smbios: Add support for showing table types 16 and 19
In some cases it is useful to find out the location of physical memory, e.g. so that the memory@ nodes can be correctly set up in the devicetree. Add support for parsing this information from the SMBIOS tables. Series-to: concept Series-cc: heinrich Series-version: 2 Cover-letter: smbios: Refactor the smbios command and parser The 'smbios' command has its own code for parsing SMBIOS tables. There in also lib/smbios-parser.c which parses tables, although only version 2. This series moved parsing to lib/ and rationalises the code a little. It also adds support for a few more tables. Finally, a hook is added so operation from coreboot can be tested on ellesmere. END Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
98
cmd/smbios.c
98
cmd/smbios.c
@@ -117,7 +117,43 @@ static const struct str_lookup_table associativity_strings[] = {
|
||||
{ SMBIOS_CACHE_ASSOC_48WAY, "48-way Set-Associative" },
|
||||
{ SMBIOS_CACHE_ASSOC_64WAY, "64-way Set-Associative" },
|
||||
{ SMBIOS_CACHE_ASSOC_20WAY, "20-way Set-Associative" },
|
||||
};
|
||||
|
||||
static const struct str_lookup_table mem_array_location_strings[] = {
|
||||
{ 0x01, "Other" },
|
||||
{ 0x02, "Unknown" },
|
||||
{ 0x03, "System board or motherboard" },
|
||||
{ 0x04, "ISA add-on card" },
|
||||
{ 0x05, "EISA add-on card" },
|
||||
{ 0x06, "PCI add-on card" },
|
||||
{ 0x07, "MCA add-on card" },
|
||||
{ 0x08, "PCMCIA add-on card" },
|
||||
{ 0x09, "Proprietary add-on card" },
|
||||
{ 0x0A, "NuBus" },
|
||||
{ 0xA0, "PC-98/C20 add-on card" },
|
||||
{ 0xA1, "PC-98/C24 add-on card" },
|
||||
{ 0xA2, "PC-98/E add-on card" },
|
||||
{ 0xA3, "PC-98/Local bus add-on card" },
|
||||
};
|
||||
|
||||
static const struct str_lookup_table mem_array_use_strings[] = {
|
||||
{ 0x01, "Other" },
|
||||
{ 0x02, "Unknown" },
|
||||
{ 0x03, "System memory" },
|
||||
{ 0x04, "Video memory" },
|
||||
{ 0x05, "Flash memory" },
|
||||
{ 0x06, "Non-volatile RAM" },
|
||||
{ 0x07, "Cache memory" },
|
||||
};
|
||||
|
||||
static const struct str_lookup_table mem_err_corr_strings[] = {
|
||||
{ 0x01, "Other" },
|
||||
{ 0x02, "Unknown" },
|
||||
{ 0x03, "None" },
|
||||
{ 0x04, "Parity" },
|
||||
{ 0x05, "Single-bit ECC" },
|
||||
{ 0x06, "Multi-bit ECC" },
|
||||
{ 0x07, "CRC" },
|
||||
};
|
||||
|
||||
static void smbios_print_generic(const struct smbios_header *table)
|
||||
@@ -369,6 +405,62 @@ static void smbios_print_type7(struct smbios_type7 *table)
|
||||
printf("\tInstalled Cache Size 2: 0x%08x\n", table->inst_size2.data);
|
||||
}
|
||||
|
||||
static void smbios_print_type16(struct smbios_type16 *table)
|
||||
{
|
||||
u64 capacity;
|
||||
|
||||
printf("Physical Memory Array\n");
|
||||
smbios_print_lookup_str(mem_array_location_strings, table->location,
|
||||
ARRAY_SIZE(mem_array_location_strings),
|
||||
"Location");
|
||||
smbios_print_lookup_str(mem_array_use_strings, table->use,
|
||||
ARRAY_SIZE(mem_array_use_strings), "Use");
|
||||
smbios_print_lookup_str(mem_err_corr_strings, table->error_correction,
|
||||
ARRAY_SIZE(mem_err_corr_strings),
|
||||
"Error Correction");
|
||||
|
||||
capacity = table->maximum_capacity;
|
||||
if (capacity == 0x7fffffff &&
|
||||
table->hdr.length >= offsetof(struct smbios_type16,
|
||||
extended_maximum_capacity)) {
|
||||
capacity = table->extended_maximum_capacity;
|
||||
printf("\tMaximum Capacity: %llu GB\n", capacity >> 30);
|
||||
} else if (capacity > 0) {
|
||||
printf("\tMaximum Capacity: %llu MB\n", capacity >> 10);
|
||||
} else {
|
||||
printf("\tMaximum Capacity: No limit\n");
|
||||
}
|
||||
|
||||
printf("\tError Information Handle: 0x%04x\n",
|
||||
table->error_information_handle);
|
||||
printf("\tNumber Of Devices: %u\n", table->number_of_memory_devices);
|
||||
}
|
||||
|
||||
static void smbios_print_type19(struct smbios_type19 *table)
|
||||
{
|
||||
u64 start_addr, end_addr;
|
||||
|
||||
printf("Memory Array Mapped Address\n");
|
||||
|
||||
/* Check if extended address fields are present (SMBIOS v2.7+) */
|
||||
if (table->hdr.length >= 0x1f) {
|
||||
start_addr = table->extended_starting_address;
|
||||
end_addr = table->extended_ending_address;
|
||||
} else {
|
||||
start_addr = table->starting_address;
|
||||
end_addr = table->ending_address;
|
||||
}
|
||||
|
||||
/* The ending address is the address of the last 1KB block */
|
||||
if (end_addr != 0xffffffff && end_addr != 0xffffffffffffffff)
|
||||
end_addr = (end_addr + 1) * 1024 - 1;
|
||||
|
||||
printf("\tStarting Address: 0x%016llx\n", start_addr);
|
||||
printf("\tEnding Address: 0x%016llx\n", end_addr);
|
||||
printf("\tMemory Array Handle: 0x%04x\n", table->memory_array_handle);
|
||||
printf("\tPartition Width: %u\n", table->partition_width);
|
||||
}
|
||||
|
||||
static void smbios_print_type127(struct smbios_type127 *table)
|
||||
{
|
||||
printf("End Of Table\n");
|
||||
@@ -424,6 +516,12 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
case SMBIOS_CACHE_INFORMATION:
|
||||
smbios_print_type7((struct smbios_type7 *)pos);
|
||||
break;
|
||||
case SMBIOS_PHYS_MEMORY_ARRAY:
|
||||
smbios_print_type16((struct smbios_type16 *)pos);
|
||||
break;
|
||||
case SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS:
|
||||
smbios_print_type19((struct smbios_type19 *)pos);
|
||||
break;
|
||||
case SMBIOS_END_OF_TABLE:
|
||||
smbios_print_type127((struct smbios_type127 *)pos);
|
||||
break;
|
||||
|
||||
@@ -281,6 +281,31 @@ struct __packed smbios_type7 {
|
||||
char eos[SMBIOS_STRUCT_EOS_BYTES];
|
||||
};
|
||||
|
||||
struct __packed smbios_type16 {
|
||||
struct smbios_header hdr;
|
||||
u8 location;
|
||||
u8 use;
|
||||
u8 error_correction;
|
||||
u32 maximum_capacity;
|
||||
u16 error_information_handle;
|
||||
u16 number_of_memory_devices;
|
||||
/* The following field is only present in SMBIOS v2.7+ */
|
||||
u64 extended_maximum_capacity;
|
||||
char eos[SMBIOS_STRUCT_EOS_BYTES];
|
||||
};
|
||||
|
||||
struct __packed smbios_type19 {
|
||||
struct smbios_header hdr;
|
||||
u32 starting_address;
|
||||
u32 ending_address;
|
||||
u16 memory_array_handle;
|
||||
u8 partition_width;
|
||||
/* The following fields are only present in SMBIOS v2.7+ */
|
||||
u64 extended_starting_address;
|
||||
u64 extended_ending_address;
|
||||
char eos[SMBIOS_STRUCT_EOS_BYTES];
|
||||
};
|
||||
|
||||
struct __packed smbios_type32 {
|
||||
u8 type;
|
||||
u8 length;
|
||||
|
||||
@@ -191,4 +191,38 @@
|
||||
#define SMBIOS_CACHE_ASSOC_64WAY 13
|
||||
#define SMBIOS_CACHE_ASSOC_20WAY 14
|
||||
|
||||
/* Physical Memory Array */
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_OTHER 0x01
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_UNKNOWN 0x02
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_SYSTEM_BOARD 0x03
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_ISA_ADDON 0x04
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_EISA_ADDON 0x05
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PCI_ADDON 0x06
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_MCA_ADDON 0x07
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PCMCIA_ADDON 0x08
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PROPRIETARY_ADDON 0x09
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_NUBUS 0x0a
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C20_ADDON 0xa0
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C24_ADDON 0xa1
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_E_ADDON 0xa2
|
||||
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_LOCAL_BUS_ADDON 0xa3
|
||||
|
||||
#define SMBIOS_MEM_ARRAY_USE_OTHER 0x01
|
||||
#define SMBIOS_MEM_ARRAY_USE_UNKNOWN 0x02
|
||||
#define SMBIOS_MEM_ARRAY_USE_SYSTEM 0x03
|
||||
#define SMBIOS_MEM_ARRAY_USE_VIDEO 0x04
|
||||
#define SMBIOS_MEM_ARRAY_USE_FLASH 0x05
|
||||
#define SMBIOS_MEM_ARRAY_USE_NON_VOLATILE_RAM 0x06
|
||||
#define SMBIOS_MEM_ARRAY_USE_CACHE 0x07
|
||||
|
||||
#define SMBIOS_MEM_ERR_CORR_OTHER 0x01
|
||||
#define SMBIOS_MEM_ERR_CORR_UNKNOWN 0x02
|
||||
#define SMBIOS_MEM_ERR_CORR_NONE 0x03
|
||||
#define SMBIOS_MEM_ERR_CORR_PARITY 0x04
|
||||
#define SMBIOS_MEM_ERR_CORR_SINGLE_BIT_ECC 0x05
|
||||
#define SMBIOS_MEM_ERR_CORR_MULTI_BIT_ECC 0x06
|
||||
#define SMBIOS_MEM_ERR_CORR_CRC 0x07
|
||||
|
||||
#define SMBIOS_MEM_CAPACITY_EXTENDED 0x80000000
|
||||
|
||||
#endif /* _SMBIOS_DEF_H_ */
|
||||
|
||||
Reference in New Issue
Block a user