mb/hardkernel/odroid-h4: Correct number of jacks in hda_verb.c
[coreboot.git] / src / lib / smbios.c
blob9cee637b6950c4dfb101437c8612831ed98b8251
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <assert.h>
4 #include <string.h>
5 #include <smbios.h>
6 #include <console/console.h>
7 #include <version.h>
8 #include <device/device.h>
9 #include <device/pciexp.h>
10 #include <device/dram/spd.h>
11 #include <elog.h>
12 #include <endian.h>
13 #include <memory_info.h>
14 #include <spd.h>
15 #include <cbmem.h>
16 #include <commonlib/helpers.h>
17 #include <device/pci_ids.h>
18 #include <device/pci.h>
19 #include <drivers/vpd/vpd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
23 static u8 smbios_checksum(u8 *p, u32 length)
25 u8 ret = 0;
26 while (length--)
27 ret += *p++;
28 return -ret;
31 int smbios_add_string(u8 *start, const char *str)
33 int i = 1;
34 char *p = (char *)start;
37 * Return 0 as required for empty strings.
38 * See Section 6.1.3 "Text Strings" of the SMBIOS specification.
40 if (str == NULL || *str == '\0')
41 return 0;
43 for (;;) {
44 if (!*p) {
45 strcpy(p, str);
46 p += strlen(str);
47 *p++ = '\0';
48 *p++ = '\0';
49 return i;
52 if (!strcmp(p, str))
53 return i;
55 p += strlen(p)+1;
56 i++;
60 int smbios_string_table_len(u8 *start)
62 char *p = (char *)start;
63 int i, len = 0;
65 while (*p) {
66 i = strlen(p) + 1;
67 p += i;
68 len += i;
71 if (!len)
72 return 2;
74 return len + 1;
77 int smbios_full_table_len(struct smbios_header *header, u8 *str_table_start)
79 return header->length + smbios_string_table_len(str_table_start);
82 void *smbios_carve_table(unsigned long start, u8 type, u8 length, u16 handle)
84 struct smbios_header *t = (struct smbios_header *)start;
86 assert(length >= sizeof(*t));
87 memset(t, 0, length);
88 t->type = type;
89 t->length = length - 2;
90 t->handle = handle;
91 return t;
94 /* this function will fill the corresponding manufacturer */
95 void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t)
97 const char *const manufacturer = spd_manufacturer_name(mod_id);
99 if (manufacturer) {
100 t->manufacturer = smbios_add_string(t->eos, manufacturer);
101 } else {
102 char string_buffer[256];
104 snprintf(string_buffer, sizeof(string_buffer), "Unknown (%x)", mod_id);
105 t->manufacturer = smbios_add_string(t->eos, string_buffer);
109 static void trim_trailing_whitespace(char *buffer, size_t buffer_size)
111 size_t len = strnlen(buffer, buffer_size);
113 if (len == 0)
114 return;
116 for (char *p = buffer + len - 1; p >= buffer; --p) {
117 if (*p == ' ')
118 *p = 0;
119 else
120 break;
124 /** This function will fill the corresponding part number */
125 static void smbios_fill_dimm_part_number(const char *part_number, struct smbios_type17 *t)
127 int invalid;
128 size_t i, len;
129 char trimmed_part_number[DIMM_INFO_PART_NUMBER_SIZE];
131 strncpy(trimmed_part_number, part_number, sizeof(trimmed_part_number));
132 trimmed_part_number[sizeof(trimmed_part_number) - 1] = '\0';
135 * SPD mandates that unused characters be represented with a ' '.
136 * We don't want to publish the whitespace in the SMBIOS tables.
138 trim_trailing_whitespace(trimmed_part_number, sizeof(trimmed_part_number));
140 len = strlen(trimmed_part_number);
142 invalid = 0; /* assume valid */
143 for (i = 0; i < len; i++) {
144 if (trimmed_part_number[i] < ' ') {
145 invalid = 1;
146 trimmed_part_number[i] = '*';
150 if (len == 0) {
151 /* Null String in Part Number will have "None" instead. */
152 t->part_number = smbios_add_string(t->eos, "None");
153 } else if (invalid) {
154 char string_buffer[sizeof(trimmed_part_number) + 10];
156 snprintf(string_buffer, sizeof(string_buffer), "Invalid (%s)",
157 trimmed_part_number);
158 t->part_number = smbios_add_string(t->eos, string_buffer);
159 } else {
160 t->part_number = smbios_add_string(t->eos, trimmed_part_number);
164 /* Encodes the SPD serial number into hex */
165 static void smbios_fill_dimm_serial_number(const struct dimm_info *dimm,
166 struct smbios_type17 *t)
168 char serial[9];
170 snprintf(serial, sizeof(serial), "%02hhx%02hhx%02hhx%02hhx",
171 dimm->serial[0], dimm->serial[1], dimm->serial[2], dimm->serial[3]);
173 t->serial_number = smbios_add_string(t->eos, serial);
176 static const char *memory_device_type(u8 code)
178 /* SMBIOS spec 3.6 7.18.2 */
179 static const char * const type[] = {
180 "Other",
181 "Unknown",
182 "DRAM",
183 "EDRAM",
184 "VRAM",
185 "SRAM",
186 "RAM",
187 "ROM",
188 "Flash",
189 "EEPROM",
190 "FEPROM",
191 "EPROM",
192 "CDRAM",
193 "3DRAM",
194 "SDRAM",
195 "SGRAM",
196 "RDRAM",
197 "DDR",
198 "DDR2",
199 "DDR2 FB-DIMM",
200 "Reserved",
201 "Reserved",
202 "Reserved",
203 "DDR3",
204 "FBD2",
205 "DDR4", /* 0x1A */
206 "LPDDR",
207 "LPDDR2",
208 "LPDDR3",
209 "LPDDR4",
210 "Logical non-volatile device",
211 "HBM",
212 "HBM2",
213 "DDR5",
214 "LPDDR5",
215 "HBM3", /* 0x24 */
218 if (code >= MEMORY_TYPE_OTHER && code <= MEMORY_TYPE_HBM3)
219 return type[code - 1];
220 return "Unsupported";
223 static void dump_smbios_type17(struct dimm_info *dimm)
225 printk(BIOS_INFO, "memory at Channel-%d-DIMM-%d", dimm->channel_num, dimm->dimm_num);
226 printk(BIOS_INFO, " type is %s\n", memory_device_type(dimm->ddr_type));
227 printk(BIOS_INFO, "memory part number is %s\n", dimm->module_part_number);
228 if (dimm->max_speed_mts != 0)
229 printk(BIOS_INFO, "memory max speed is %d MT/s\n", dimm->max_speed_mts);
230 printk(BIOS_INFO, "memory speed is %d MT/s\n",
231 dimm->configured_speed_mts ? : dimm->ddr_frequency);
232 printk(BIOS_INFO, "memory size is %d MiB\n", dimm->dimm_size);
235 static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
236 unsigned long *current, int *handle,
237 int type16_handle)
239 struct spd_info info;
240 get_spd_info(dimm->ddr_type, dimm->mod_type, &info);
242 struct smbios_type17 *t = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE,
243 sizeof(*t), *handle);
245 t->memory_type = dimm->ddr_type;
246 if (dimm->configured_speed_mts != 0)
247 t->clock_speed = dimm->configured_speed_mts;
248 else
249 t->clock_speed = dimm->ddr_frequency;
250 if (dimm->max_speed_mts != 0)
251 t->speed = dimm->max_speed_mts;
252 else
253 t->speed = dimm->ddr_frequency;
254 if (dimm->dimm_size < 0x7fff) {
255 t->size = dimm->dimm_size;
256 } else {
257 t->size = 0x7fff;
258 t->extended_size = dimm->dimm_size & 0x7fffffff;
260 t->data_width = 8 * (1 << (dimm->bus_width & 0x7));
261 t->total_width = t->data_width + 8 * ((dimm->bus_width & 0x18) >> 3);
262 t->form_factor = info.form_factor;
264 smbios_fill_dimm_manufacturer_from_id(dimm->mod_id, t);
265 smbios_fill_dimm_serial_number(dimm, t);
266 smbios_fill_dimm_asset_tag(dimm, t);
267 smbios_fill_dimm_locator(dimm, t);
269 /* put '\0' in the end of data */
270 dimm->module_part_number[DIMM_INFO_PART_NUMBER_SIZE - 1] = '\0';
271 smbios_fill_dimm_part_number((char *)dimm->module_part_number, t);
273 /* Voltage Levels */
274 t->configured_voltage = dimm->vdd_voltage;
275 t->minimum_voltage = dimm->vdd_voltage;
276 t->maximum_voltage = dimm->vdd_voltage;
278 /* Fill in type detail */
279 t->type_detail = info.type_detail;
281 /* Synchronous = 1 */
282 t->type_detail |= MEMORY_TYPE_DETAIL_SYNCHRONOUS;
283 /* no handle for error information */
284 t->memory_error_information_handle = 0xFFFE;
285 t->attributes = dimm->rank_per_dimm;
286 t->phys_memory_array_handle = type16_handle;
288 *handle += 1;
289 return smbios_full_table_len(&t->header, t->eos);
292 static int create_smbios_type17_for_empty_slot(struct dimm_info *dimm,
293 unsigned long *current, int *handle,
294 int type16_handle)
296 struct smbios_type17 *t = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE,
297 sizeof(*t), *handle);
298 t->phys_memory_array_handle = type16_handle;
299 /* no handle for error information */
300 t->memory_error_information_handle = 0xfffe;
301 t->total_width = 0xffff; /* Unknown */
302 t->data_width = 0xffff; /* Unknown */
303 t->form_factor = 0x2; /* Unknown */
304 smbios_fill_dimm_locator(dimm, t); /* Device and Bank */
305 t->memory_type = 0x2; /* Unknown */
306 t->type_detail = 0x2; /* Unknown */
308 *handle += 1;
309 if (CONFIG(DUMP_SMBIOS_TYPE17))
310 dump_smbios_type17(dimm);
312 return smbios_full_table_len(&t->header, t->eos);
315 #define VERSION_VPD "firmware_version"
316 static const char *vpd_get_bios_version(void)
318 int size;
319 const char *s;
320 char *version;
322 s = vpd_find(VERSION_VPD, &size, VPD_RO);
323 if (!s) {
324 printk(BIOS_ERR, "Find version from VPD %s failed\n", VERSION_VPD);
325 return NULL;
328 version = malloc(size + 1);
329 if (!version) {
330 printk(BIOS_ERR, "Failed to malloc %d bytes for VPD version\n", size + 1);
331 return NULL;
333 memcpy(version, s, size);
334 version[size] = '\0';
335 printk(BIOS_DEBUG, "Firmware version %s from VPD %s\n", version, VERSION_VPD);
336 return version;
339 static const char *get_bios_version(void)
341 const char *s;
343 #define SPACES \
346 if (CONFIG(CHROMEOS))
347 return SPACES;
349 if (CONFIG(VPD_SMBIOS_VERSION)) {
350 s = vpd_get_bios_version();
351 if (s != NULL)
352 return s;
355 s = smbios_mainboard_bios_version();
356 if (s != NULL)
357 return s;
359 if (strlen(CONFIG_LOCALVERSION) != 0) {
360 printk(BIOS_DEBUG, "BIOS version set to CONFIG_LOCALVERSION: '%s'\n",
361 CONFIG_LOCALVERSION);
362 return CONFIG_LOCALVERSION;
365 printk(BIOS_DEBUG, "SMBIOS firmware version is set to coreboot_version: '%s'\n",
366 coreboot_version);
367 return coreboot_version;
370 static int smbios_write_type0(unsigned long *current, int handle)
372 struct smbios_type0 *t = smbios_carve_table(*current, SMBIOS_BIOS_INFORMATION,
373 sizeof(*t), handle);
375 t->vendor = smbios_add_string(t->eos, CONFIG_BIOS_VENDOR);
376 t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date);
378 if (CONFIG(CHROMEOS_NVS)) {
379 uintptr_t version_address = (uintptr_t)t->eos;
380 /* SMBIOS offsets start at 1 rather than 0 */
381 version_address += (u32)smbios_string_table_len(t->eos) - 1;
382 smbios_type0_bios_version(version_address);
384 t->bios_version = smbios_add_string(t->eos, get_bios_version());
385 uint32_t rom_size = CONFIG_ROM_SIZE;
386 rom_size = MIN(CONFIG_ROM_SIZE, 16 * MiB);
387 t->bios_rom_size = (rom_size / 65535) - 1;
389 if (CONFIG_ROM_SIZE >= 1 * GiB)
390 t->extended_bios_rom_size = DIV_ROUND_UP(CONFIG_ROM_SIZE, GiB) | (1 << 14);
391 else
392 t->extended_bios_rom_size = DIV_ROUND_UP(CONFIG_ROM_SIZE, MiB);
394 t->system_bios_major_release = coreboot_major_revision;
395 t->system_bios_minor_release = coreboot_minor_revision;
397 smbios_ec_revision(&t->ec_major_release, &t->ec_minor_release);
399 t->bios_characteristics =
400 BIOS_CHARACTERISTICS_PCI_SUPPORTED |
401 BIOS_CHARACTERISTICS_SELECTABLE_BOOT |
402 BIOS_CHARACTERISTICS_UPGRADEABLE;
404 if (CONFIG(CARDBUS_PLUGIN_SUPPORT))
405 t->bios_characteristics |= BIOS_CHARACTERISTICS_PC_CARD;
407 if (CONFIG(HAVE_ACPI_TABLES))
408 t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI;
410 t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET;
411 const int len = smbios_full_table_len(&t->header, t->eos);
412 *current += len;
413 return len;
416 unsigned int __weak smbios_processor_external_clock(void)
418 return 0; /* Unknown */
421 unsigned int __weak smbios_processor_characteristics(void)
423 return 0;
426 unsigned int __weak smbios_cache_error_correction_type(u8 level)
428 return SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN;
431 unsigned int __weak smbios_cache_sram_type(void)
433 return SMBIOS_CACHE_SRAM_TYPE_UNKNOWN;
436 unsigned int __weak smbios_cache_conf_operation_mode(u8 level)
438 return SMBIOS_CACHE_OP_MODE_UNKNOWN; /* Unknown */
441 /* Returns the processor voltage in 100mV units */
442 unsigned int __weak smbios_cpu_get_voltage(void)
444 return 0; /* Unknown */
447 unsigned int smbios_get_max_sockets(void)
449 if (CONFIG_MAX_SOCKET == 1)
450 return 1;
451 else
452 return smbios_soc_get_max_sockets();
455 static int smbios_write_type1(unsigned long *current, int handle)
457 struct smbios_type1 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_INFORMATION,
458 sizeof(*t), handle);
460 t->manufacturer = smbios_add_string(t->eos, smbios_system_manufacturer());
461 t->product_name = smbios_add_string(t->eos, smbios_system_product_name());
462 t->serial_number = smbios_add_string(t->eos, smbios_system_serial_number());
463 t->wakeup_type = smbios_system_wakeup_type();
464 t->sku = smbios_add_string(t->eos, smbios_system_sku());
465 t->version = smbios_add_string(t->eos, smbios_system_version());
466 #ifdef CONFIG_MAINBOARD_FAMILY
467 t->family = smbios_add_string(t->eos, CONFIG_MAINBOARD_FAMILY);
468 #endif
469 smbios_system_set_uuid(t->uuid);
470 const int len = smbios_full_table_len(&t->header, t->eos);
471 *current += len;
472 return len;
475 static int smbios_write_type2(unsigned long *current, int handle, const int chassis_handle)
477 struct smbios_type2 *t = smbios_carve_table(*current, SMBIOS_BOARD_INFORMATION,
478 sizeof(*t), handle);
480 t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer());
481 t->product_name = smbios_add_string(t->eos, smbios_mainboard_product_name());
482 t->serial_number = smbios_add_string(t->eos, smbios_mainboard_serial_number());
483 t->version = smbios_add_string(t->eos, smbios_mainboard_version());
484 t->asset_tag = smbios_add_string(t->eos, smbios_mainboard_asset_tag());
485 t->feature_flags = smbios_mainboard_feature_flags();
486 t->location_in_chassis = smbios_add_string(t->eos,
487 smbios_mainboard_location_in_chassis());
488 t->board_type = smbios_mainboard_board_type();
489 t->chassis_handle = chassis_handle;
490 const int len = smbios_full_table_len(&t->header, t->eos);
491 *current += len;
492 return len;
495 static int smbios_write_type3(unsigned long *current, int handle)
497 struct smbios_type3 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_ENCLOSURE,
498 sizeof(*t), handle);
500 t->manufacturer = smbios_add_string(t->eos, smbios_system_manufacturer());
501 t->bootup_state = SMBIOS_STATE_SAFE;
502 t->power_supply_state = SMBIOS_STATE_SAFE;
503 t->thermal_state = SMBIOS_STATE_SAFE;
504 t->_type = smbios_mainboard_enclosure_type();
505 t->security_status = SMBIOS_STATE_SAFE;
506 t->number_of_power_cords = smbios_chassis_power_cords();
507 t->asset_tag_number = smbios_add_string(t->eos, smbios_mainboard_asset_tag());
508 t->version = smbios_add_string(t->eos, smbios_chassis_version());
509 t->serial_number = smbios_add_string(t->eos, smbios_chassis_serial_number());
510 const int len = smbios_full_table_len(&t->header, t->eos);
511 *current += len;
512 return len;
516 * Write SMBIOS type 7.
517 * Fill in some fields with constant values, as gathering the information
518 * from CPUID is impossible.
520 int smbios_write_type7(unsigned long *current,
521 const int handle,
522 const u8 level,
523 const u8 sram_type,
524 const enum smbios_cache_associativity associativity,
525 const enum smbios_cache_type type,
526 const size_t max_cache_size,
527 const size_t cache_size)
529 char buf[8];
531 struct smbios_type7 *t = smbios_carve_table(*current, SMBIOS_CACHE_INFORMATION,
532 sizeof(*t), handle);
534 snprintf(buf, sizeof(buf), "CACHE%x", level);
535 t->socket_designation = smbios_add_string(t->eos, buf);
537 t->cache_configuration = SMBIOS_CACHE_CONF_LEVEL(level) |
538 SMBIOS_CACHE_CONF_LOCATION(0) | /* Internal */
539 SMBIOS_CACHE_CONF_ENABLED(1) | /* Enabled */
540 SMBIOS_CACHE_CONF_OPERATION_MODE(smbios_cache_conf_operation_mode(level));
542 if (max_cache_size < (SMBIOS_CACHE_SIZE_MASK * KiB)) {
543 t->max_cache_size = max_cache_size / KiB;
544 t->max_cache_size2 = t->max_cache_size;
546 t->max_cache_size |= SMBIOS_CACHE_SIZE_UNIT_1KB;
547 t->max_cache_size2 |= SMBIOS_CACHE_SIZE2_UNIT_1KB;
548 } else {
549 if (max_cache_size < (SMBIOS_CACHE_SIZE_MASK * 64 * KiB))
550 t->max_cache_size = max_cache_size / (64 * KiB);
551 else
552 t->max_cache_size = SMBIOS_CACHE_SIZE_OVERFLOW;
553 t->max_cache_size2 = max_cache_size / (64 * KiB);
555 t->max_cache_size |= SMBIOS_CACHE_SIZE_UNIT_64KB;
556 t->max_cache_size2 |= SMBIOS_CACHE_SIZE2_UNIT_64KB;
559 if (cache_size < (SMBIOS_CACHE_SIZE_MASK * KiB)) {
560 t->installed_size = cache_size / KiB;
561 t->installed_size2 = t->installed_size;
563 t->installed_size |= SMBIOS_CACHE_SIZE_UNIT_1KB;
564 t->installed_size2 |= SMBIOS_CACHE_SIZE2_UNIT_1KB;
565 } else {
566 if (cache_size < (SMBIOS_CACHE_SIZE_MASK * 64 * KiB))
567 t->installed_size = cache_size / (64 * KiB);
568 else
569 t->installed_size = SMBIOS_CACHE_SIZE_OVERFLOW;
570 t->installed_size2 = cache_size / (64 * KiB);
572 t->installed_size |= SMBIOS_CACHE_SIZE_UNIT_64KB;
573 t->installed_size2 |= SMBIOS_CACHE_SIZE2_UNIT_64KB;
576 t->associativity = associativity;
577 t->supported_sram_type = sram_type;
578 t->current_sram_type = sram_type;
579 t->cache_speed = 0; /* Unknown */
580 t->error_correction_type = smbios_cache_error_correction_type(level);
581 t->system_cache_type = type;
583 const int len = smbios_full_table_len(&t->header, t->eos);
584 *current += len;
585 return len;
588 /* Convert the associativity as integer to the SMBIOS enum if available */
589 enum smbios_cache_associativity smbios_cache_associativity(const u8 num)
591 switch (num) {
592 case 1:
593 return SMBIOS_CACHE_ASSOCIATIVITY_DIRECT;
594 case 2:
595 return SMBIOS_CACHE_ASSOCIATIVITY_2WAY;
596 case 4:
597 return SMBIOS_CACHE_ASSOCIATIVITY_4WAY;
598 case 8:
599 return SMBIOS_CACHE_ASSOCIATIVITY_8WAY;
600 case 12:
601 return SMBIOS_CACHE_ASSOCIATIVITY_12WAY;
602 case 16:
603 return SMBIOS_CACHE_ASSOCIATIVITY_16WAY;
604 case 20:
605 return SMBIOS_CACHE_ASSOCIATIVITY_20WAY;
606 case 24:
607 return SMBIOS_CACHE_ASSOCIATIVITY_24WAY;
608 case 32:
609 return SMBIOS_CACHE_ASSOCIATIVITY_32WAY;
610 case 48:
611 return SMBIOS_CACHE_ASSOCIATIVITY_48WAY;
612 case 64:
613 return SMBIOS_CACHE_ASSOCIATIVITY_64WAY;
614 case 0xff:
615 return SMBIOS_CACHE_ASSOCIATIVITY_FULL;
616 default:
617 return SMBIOS_CACHE_ASSOCIATIVITY_UNKNOWN;
621 int smbios_write_type8(unsigned long *current, int *handle,
622 const struct port_information *port,
623 size_t num_ports)
625 unsigned int totallen = 0, i;
627 for (i = 0; i < num_ports; i++, port++) {
628 struct smbios_type8 *t = smbios_carve_table(*current,
629 SMBIOS_PORT_CONNECTOR_INFORMATION,
630 sizeof(*t), *handle);
631 t->internal_reference_designator =
632 smbios_add_string(t->eos, port->internal_reference_designator);
633 t->internal_connector_type = port->internal_connector_type;
634 t->external_reference_designator =
635 smbios_add_string(t->eos, port->external_reference_designator);
636 t->external_connector_type = port->external_connector_type;
637 t->port_type = port->port_type;
638 *handle += 1;
639 const int len = smbios_full_table_len(&t->header, t->eos);
640 *current += len;
641 totallen += len;
643 return totallen;
646 int smbios_write_type9(unsigned long *current, int *handle,
647 const char *name, const enum misc_slot_type type,
648 const enum slot_data_bus_bandwidth bandwidth,
649 const enum misc_slot_usage usage,
650 const enum misc_slot_length length,
651 const u16 id, u8 slot_char1, u8 slot_char2,
652 u8 segment_group, u8 bus, u8 dev_func)
654 struct smbios_type9 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_SLOTS,
655 sizeof(*t), *handle);
657 t->slot_designation = smbios_add_string(t->eos, name ? name : "SLOT");
658 t->slot_type = type;
659 /* TODO add slot_id support, will be "_SUN" for ACPI devices */
660 t->slot_id = id;
661 t->slot_data_bus_width = bandwidth;
662 t->current_usage = usage;
663 t->slot_length = length;
664 t->slot_characteristics_1 = slot_char1;
665 t->slot_characteristics_2 = slot_char2;
666 t->segment_group_number = segment_group;
667 t->bus_number = bus;
668 t->device_function_number = dev_func;
669 t->data_bus_width = SlotDataBusWidthOther;
671 const int len = smbios_full_table_len(&t->header, t->eos);
672 *current += len;
673 *handle += 1;
674 return len;
677 static int smbios_write_type11(unsigned long *current, int *handle)
679 struct device *dev;
680 struct smbios_type11 *t = smbios_carve_table(*current, SMBIOS_OEM_STRINGS,
681 sizeof(*t), *handle);
683 for (dev = all_devices; dev; dev = dev->next) {
684 if (dev->ops && dev->ops->get_smbios_strings)
685 dev->ops->get_smbios_strings(dev, t);
688 if (t->count == 0) {
689 memset(t, 0, sizeof(*t));
690 return 0;
693 const int len = smbios_full_table_len(&t->header, t->eos);
694 *current += len;
695 (*handle)++;
696 return len;
699 static int smbios_write_type16(unsigned long *current, int *handle)
701 int i;
702 uint64_t max_capacity;
704 struct memory_info *meminfo;
705 meminfo = cbmem_find(CBMEM_ID_MEMINFO);
706 if (meminfo == NULL)
707 return 0; /* can't find mem info in cbmem */
709 printk(BIOS_INFO, "Create SMBIOS type 16\n");
711 if (meminfo->max_capacity_mib == 0 || meminfo->number_of_devices == 0) {
712 /* Fill in defaults if not provided */
713 meminfo->number_of_devices = 0;
714 meminfo->max_capacity_mib = 0;
715 for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
716 meminfo->max_capacity_mib += meminfo->dimm[i].dimm_size;
717 meminfo->number_of_devices += !!meminfo->dimm[i].dimm_size;
721 struct smbios_type16 *t = smbios_carve_table(*current, SMBIOS_PHYS_MEMORY_ARRAY,
722 sizeof(*t), *handle);
724 t->location = MEMORY_ARRAY_LOCATION_SYSTEM_BOARD;
725 t->use = MEMORY_ARRAY_USE_SYSTEM;
726 t->memory_error_correction = meminfo->ecc_type;
728 /* no error information handle available */
729 t->memory_error_information_handle = 0xFFFE;
730 max_capacity = meminfo->max_capacity_mib;
731 if (max_capacity * (MiB / KiB) < SMBIOS_USE_EXTENDED_MAX_CAPACITY)
732 t->maximum_capacity = max_capacity * (MiB / KiB);
733 else {
734 t->maximum_capacity = SMBIOS_USE_EXTENDED_MAX_CAPACITY;
735 t->extended_maximum_capacity = max_capacity * MiB;
737 t->number_of_memory_devices = meminfo->number_of_devices;
739 const int len = smbios_full_table_len(&t->header, t->eos);
740 *current += len;
741 (*handle)++;
742 return len;
745 static int smbios_write_type17(unsigned long *current, int *handle, int type16)
747 int totallen = 0;
748 int i;
750 struct memory_info *meminfo;
751 meminfo = cbmem_find(CBMEM_ID_MEMINFO);
752 if (meminfo == NULL)
753 return 0; /* can't find mem info in cbmem */
755 printk(BIOS_INFO, "Create SMBIOS type 17\n");
756 for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
757 struct dimm_info *d = &meminfo->dimm[i];
759 * Windows 10 GetPhysicallyInstalledSystemMemory functions reads SMBIOS tables
760 * type 16 and type 17. The type 17 tables need to point to a type 16 table.
761 * Otherwise, the physical installed memory size is guessed from the system
762 * memory map, which results in a slightly smaller value than the actual size.
764 int len;
765 if (d->dimm_size > 0)
766 len = create_smbios_type17_for_dimm(d, current, handle, type16);
767 else
768 len = create_smbios_type17_for_empty_slot(d, current, handle, type16);
770 *current += len;
771 totallen += len;
773 return totallen;
776 static int smbios_write_type19(unsigned long *current, int *handle, int type16)
778 int i;
780 struct memory_info *meminfo;
781 meminfo = cbmem_find(CBMEM_ID_MEMINFO);
782 if (meminfo == NULL)
783 return 0; /* can't find mem info in cbmem */
785 struct smbios_type19 *t = smbios_carve_table(*current,
786 SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS,
787 sizeof(*t), *handle);
789 t->memory_array_handle = type16;
791 for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
792 if (meminfo->dimm[i].dimm_size > 0) {
793 t->extended_ending_address += meminfo->dimm[i].dimm_size;
794 t->partition_width++;
797 t->extended_ending_address *= MiB;
799 /* Check if it fits into regular address */
800 if (t->extended_ending_address >= KiB &&
801 t->extended_ending_address < 0x40000000000ULL) {
803 * FIXME: The starting address is SoC specific, but SMBIOS tables are only
804 * exported on x86 where it's always 0.
807 t->starting_address = 0;
808 t->ending_address = t->extended_ending_address / KiB - 1;
809 t->extended_starting_address = ~0;
810 t->extended_ending_address = ~0;
811 } else {
812 t->starting_address = ~0;
813 t->ending_address = ~0;
814 t->extended_starting_address = 0;
815 t->extended_ending_address--;
818 const int len = smbios_full_table_len(&t->header, t->eos);
819 *current += len;
820 *handle += 1;
821 return len;
824 static int smbios_write_type20_table(unsigned long *current, int *handle, u32 addr_start,
825 u32 addr_end, int type17_handle, int type19_handle)
827 struct smbios_type20 *t = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE_MAPPED_ADDRESS,
828 sizeof(*t), *handle);
830 t->memory_device_handle = type17_handle;
831 t->memory_array_mapped_address_handle = type19_handle;
832 t->addr_start = addr_start;
833 t->addr_end = addr_end;
834 t->partition_row_pos = 0xff;
835 t->interleave_pos = 0xff;
836 t->interleave_depth = 0xff;
838 const int len = smbios_full_table_len(&t->header, t->eos);
839 *current += len;
840 *handle += 1;
841 return len;
844 static int smbios_write_type20(unsigned long *current, int *handle,
845 int type17_handle, int type19_handle)
847 u32 start_addr = 0;
848 int totallen = 0;
849 int i;
851 struct memory_info *meminfo;
852 meminfo = cbmem_find(CBMEM_ID_MEMINFO);
853 if (meminfo == NULL)
854 return 0; /* can't find mem info in cbmem */
856 printk(BIOS_INFO, "Create SMBIOS type 20\n");
857 for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
858 struct dimm_info *dimm;
859 dimm = &meminfo->dimm[i];
860 if (dimm->dimm_size == 0)
861 continue;
863 u32 end_addr = start_addr + (dimm->dimm_size << 10) - 1;
864 totallen += smbios_write_type20_table(current, handle, start_addr, end_addr,
865 type17_handle, type19_handle);
866 start_addr = end_addr + 1;
868 return totallen;
871 int smbios_write_type28(unsigned long *current, int *handle,
872 const char *name,
873 const enum smbios_temp_location location,
874 const enum smbios_temp_status status,
875 u16 max_value, u16 min_value,
876 u16 resolution, u16 tolerance,
877 u16 accuracy,
878 u32 oem,
879 u16 nominal_value)
881 struct smbios_type28 *t = smbios_carve_table(*current, SMBIOS_TEMPERATURE_PROBE,
882 sizeof(*t), *handle);
884 t->description = smbios_add_string(t->eos, name ? name : "Temperature");
885 t->location_and_status = location | (status << 5);
886 t->maximum_value = max_value;
887 t->minimum_value = min_value;
888 t->resolution = resolution;
889 t->tolerance = tolerance;
890 t->accuracy = accuracy;
891 t->oem_defined = oem;
892 t->nominal_value = nominal_value;
894 const int len = smbios_full_table_len(&t->header, t->eos);
895 *current += len;
896 *handle += 1;
897 return len;
900 static int smbios_write_type32(unsigned long *current, int handle)
902 struct smbios_type32 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_BOOT_INFORMATION,
903 sizeof(*t), handle);
905 const int len = smbios_full_table_len(&t->header, t->eos);
906 *current += len;
907 return len;
910 int smbios_write_type38(unsigned long *current, int *handle,
911 const enum smbios_bmc_interface_type interface_type,
912 const u8 ipmi_rev, const u8 i2c_addr, const u8 nv_addr,
913 const u64 base_addr, const u8 base_modifier,
914 const u8 irq)
916 struct smbios_type38 *t = smbios_carve_table(*current, SMBIOS_IPMI_DEVICE_INFORMATION,
917 sizeof(*t), *handle);
919 t->interface_type = interface_type;
920 t->ipmi_rev = ipmi_rev;
921 t->i2c_slave_addr = i2c_addr;
922 t->nv_storage_addr = nv_addr;
923 t->base_address = base_addr;
924 t->base_address_modifier = base_modifier;
925 t->irq = irq;
927 const int len = smbios_full_table_len(&t->header, t->eos);
928 *current += len;
929 *handle += 1;
930 return len;
933 int smbios_write_type39(unsigned long *current, int *handle,
934 u8 unit_group, const char *loc, const char *dev_name,
935 const char *man, const char *serial_num,
936 const char *tag_num, const char *part_num,
937 const char *rev_lvl, u16 max_pow_cap,
938 const struct power_supply_ch *ps_ch)
940 struct smbios_type39 *t = smbios_carve_table(*current,
941 SMBIOS_SYSTEM_POWER_SUPPLY,
942 sizeof(*t), *handle);
944 uint16_t val = 0;
945 uint16_t ps_type, ps_status, vol_switch, ps_unplug, ps_present, hot_rep;
947 t->power_unit_group = unit_group;
948 t->location = smbios_add_string(t->eos, loc);
949 t->device_name = smbios_add_string(t->eos, dev_name);
950 t->manufacturer = smbios_add_string(t->eos, man);
951 t->serial_number = smbios_add_string(t->eos, serial_num);
952 t->asset_tag_number = smbios_add_string(t->eos, tag_num);
953 t->model_part_number = smbios_add_string(t->eos, part_num);
954 t->revision_level = smbios_add_string(t->eos, rev_lvl);
955 t->max_power_capacity = max_pow_cap;
957 ps_type = ps_ch->power_supply_type & 0xF;
958 ps_status = ps_ch->power_supply_status & 0x7;
959 vol_switch = ps_ch->input_voltage_range_switch & 0xF;
960 ps_unplug = ps_ch->power_supply_unplugged & 0x1;
961 ps_present = ps_ch->power_supply_present & 0x1;
962 hot_rep = ps_ch->power_supply_hot_replaceble & 0x1;
964 val |= (ps_type << 10);
965 val |= (ps_status << 7);
966 val |= (vol_switch << 3);
967 val |= (ps_unplug << 2);
968 val |= (ps_present << 1);
969 val |= hot_rep;
970 t->power_supply_characteristics = val;
972 t->input_voltage_probe_handle = 0xFFFF;
973 t->cooling_device_handle = 0xFFFF;
974 t->input_current_probe_handle = 0xFFFF;
976 const int len = smbios_full_table_len(&t->header, t->eos);
977 *current += len;
978 *handle += 1;
979 return len;
982 int smbios_write_type41(unsigned long *current, int *handle,
983 const char *name, u8 instance, u16 segment_group,
984 u8 bus, u8 device, u8 function, u8 device_type)
986 struct smbios_type41 *t = smbios_carve_table(*current,
987 SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION,
988 sizeof(*t), *handle);
990 t->reference_designation = smbios_add_string(t->eos, name);
991 t->device_type = device_type;
992 t->device_status = 1;
993 t->device_type_instance = instance;
994 t->segment_group_number = segment_group;
995 t->bus_number = bus;
996 t->device_number = device;
997 t->function_number = function;
999 const int len = smbios_full_table_len(&t->header, t->eos);
1000 *current += len;
1001 *handle += 1;
1002 return len;
1005 int smbios_write_type43(unsigned long *current, int *handle, const u32 vendor_id,
1006 const u8 major_spec_ver, const u8 minor_spec_ver,
1007 const u32 fw_ver1, const u32 fw_ver2, const char *description,
1008 const u64 characteristics, const u32 oem_defined)
1010 struct smbios_type43 *t = smbios_carve_table(*current, SMBIOS_TPM_DEVICE,
1011 sizeof(*t), *handle);
1013 t->vendor_id = vendor_id;
1014 t->major_spec_ver = major_spec_ver;
1015 t->minor_spec_ver = minor_spec_ver;
1016 t->fw_ver1 = fw_ver1;
1017 t->fw_ver2 = fw_ver2;
1018 t->characteristics = characteristics;
1019 t->oem_defined = oem_defined;
1020 t->description = smbios_add_string(t->eos, description);
1022 const int len = smbios_full_table_len(&t->header, t->eos);
1023 *current += len;
1024 *handle += 1;
1025 return len;
1028 static int smbios_write_type127(unsigned long *current, int handle)
1030 struct smbios_type127 *t = smbios_carve_table(*current, SMBIOS_END_OF_TABLE,
1031 sizeof(*t), handle);
1033 const int len = smbios_full_table_len(&t->header, t->eos);
1034 *current += len;
1035 return len;
1038 /* Get the device type 41 from the dev struct */
1039 static u8 smbios_get_device_type_from_dev(struct device *dev)
1041 u16 pci_basesubclass = (dev->class >> 8) & 0xFFFF;
1043 switch (pci_basesubclass) {
1044 case PCI_CLASS_NOT_DEFINED:
1045 return SMBIOS_DEVICE_TYPE_OTHER;
1046 case PCI_CLASS_DISPLAY_VGA:
1047 case PCI_CLASS_DISPLAY_XGA:
1048 case PCI_CLASS_DISPLAY_3D:
1049 case PCI_CLASS_DISPLAY_OTHER:
1050 return SMBIOS_DEVICE_TYPE_VIDEO;
1051 case PCI_CLASS_STORAGE_SCSI:
1052 return SMBIOS_DEVICE_TYPE_SCSI;
1053 case PCI_CLASS_NETWORK_ETHERNET:
1054 return SMBIOS_DEVICE_TYPE_ETHERNET;
1055 case PCI_CLASS_NETWORK_TOKEN_RING:
1056 return SMBIOS_DEVICE_TYPE_TOKEN_RING;
1057 case PCI_CLASS_MULTIMEDIA_VIDEO:
1058 case PCI_CLASS_MULTIMEDIA_AUDIO:
1059 case PCI_CLASS_MULTIMEDIA_PHONE:
1060 case PCI_CLASS_MULTIMEDIA_OTHER:
1061 return SMBIOS_DEVICE_TYPE_SOUND;
1062 case PCI_CLASS_STORAGE_ATA:
1063 return SMBIOS_DEVICE_TYPE_PATA;
1064 case PCI_CLASS_STORAGE_SATA:
1065 return SMBIOS_DEVICE_TYPE_SATA;
1066 case PCI_CLASS_STORAGE_SAS:
1067 return SMBIOS_DEVICE_TYPE_SAS;
1068 default:
1069 return SMBIOS_DEVICE_TYPE_UNKNOWN;
1073 static bool smbios_get_type41_instance_id(struct device *dev, u8 device_type, u8 *instance_id)
1075 #if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
1076 *instance_id = dev->smbios_instance_id;
1077 return dev->smbios_instance_id_valid;
1078 #else
1079 static u8 type41_inst_cnt[SMBIOS_DEVICE_TYPE_COUNT + 1] = {};
1081 if (device_type == SMBIOS_DEVICE_TYPE_OTHER ||
1082 device_type == SMBIOS_DEVICE_TYPE_UNKNOWN)
1083 return false;
1085 if (device_type > SMBIOS_DEVICE_TYPE_COUNT)
1086 return false;
1088 *instance_id = type41_inst_cnt[device_type]++;
1089 return true;
1090 #endif
1093 static const char *smbios_get_type41_refdes(struct device *dev)
1095 #if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
1096 if (dev->smbios_refdes)
1097 return dev->smbios_refdes;
1098 #endif
1099 #if CONFIG(PCI)
1100 return get_pci_subclass_name(dev);
1101 #else
1102 return "???";
1103 #endif
1106 static int smbios_generate_type41_from_devtree(struct device *dev, int *handle,
1107 unsigned long *current)
1109 if (dev->path.type != DEVICE_PATH_PCI)
1110 return 0;
1111 if (!dev->on_mainboard)
1112 return 0;
1114 const u8 device_type = smbios_get_device_type_from_dev(dev);
1116 u8 instance_id;
1118 if (!smbios_get_type41_instance_id(dev, device_type, &instance_id))
1119 return 0;
1121 const char *name = smbios_get_type41_refdes(dev);
1123 return smbios_write_type41(current, handle,
1124 name, // name
1125 instance_id, // inst
1126 dev->upstream->segment_group, // segment group
1127 dev->upstream->secondary, //bus
1128 PCI_SLOT(dev->path.pci.devfn), // device
1129 PCI_FUNC(dev->path.pci.devfn), // func
1130 device_type);
1133 static int smbios_generate_type9_from_devtree(struct device *dev, int *handle,
1134 unsigned long *current)
1136 enum misc_slot_usage usage;
1137 enum slot_data_bus_bandwidth bandwidth;
1138 enum misc_slot_type type;
1139 enum misc_slot_length length;
1140 uint8_t characteristics_1 = 0, characteristics_2 = 0;
1142 if (dev->path.type != DEVICE_PATH_PCI)
1143 return 0;
1145 if (!dev->smbios_slot_type && !dev->smbios_slot_data_width &&
1146 !dev->smbios_slot_designation && !dev->smbios_slot_length)
1147 return 0;
1149 if (dev_is_active_bridge(dev))
1150 usage = SlotUsageInUse;
1151 else if (dev->enabled)
1152 usage = SlotUsageAvailable;
1153 else
1154 usage = SlotUsageUnknown;
1156 if (dev->smbios_slot_data_width)
1157 bandwidth = dev->smbios_slot_data_width;
1158 else
1159 bandwidth = SlotDataBusWidthUnknown;
1161 if (dev->smbios_slot_type > SlotTypeUnknown) {
1162 type = dev->smbios_slot_type;
1163 if ((type >= SlotTypePciExpress && type <= SlotTypeEDSFF_E3) ||
1164 (type >= SlotTypeAgp && type <= SlotTypeM2Socket3) ||
1165 (type == SlotTypePci)) {
1166 characteristics_1 |= SMBIOS_SLOT_3P3V;
1168 if ((type >= SlotTypeAgp && type <= SlotTypeAgp8X) ||
1169 (type == SlotTypePci))
1170 characteristics_1 |= SMBIOS_SLOT_5V;
1171 } else {
1172 characteristics_1 = SMBIOS_SLOT_UNKNOWN;
1173 type = SlotTypeUnknown;
1176 if (dev->smbios_slot_length)
1177 length = dev->smbios_slot_length;
1178 else
1179 length = SlotLengthUnknown;
1181 if (pci_has_pme_pin(dev))
1182 characteristics_2 |= SMBIOS_SLOT_PME;
1183 if (CONFIG(PCIEXP_PLUGIN_SUPPORT) && pciexp_dev_is_slot_hot_plug_cap(dev))
1184 characteristics_2 |= SMBIOS_SLOT_HOTPLUG;
1186 return smbios_write_type9(current, handle,
1187 dev->smbios_slot_designation,
1188 type,
1189 bandwidth,
1190 usage,
1191 length,
1193 characteristics_1,
1194 characteristics_2,
1195 dev->upstream->segment_group,
1196 dev->upstream->secondary,
1197 dev->path.pci.devfn);
1200 int get_smbios_data(struct device *dev, int *handle, unsigned long *current)
1202 int len = 0;
1204 len += smbios_generate_type9_from_devtree(dev, handle, current);
1205 len += smbios_generate_type41_from_devtree(dev, handle, current);
1207 return len;
1210 static int smbios_walk_device_tree(struct device *tree, int *handle, unsigned long *current)
1212 struct device *dev;
1213 int len = 0;
1215 for (dev = tree; dev; dev = dev->next) {
1216 if (!dev->enabled)
1217 continue;
1219 if (dev->ops && dev->ops->get_smbios_data) {
1220 printk(BIOS_INFO, "%s (%s)\n", dev_path(dev), dev_name(dev));
1221 len += dev->ops->get_smbios_data(dev, handle, current);
1222 } else {
1223 len += get_smbios_data(dev, handle, current);
1226 return len;
1229 unsigned long smbios_write_tables(unsigned long current)
1231 struct smbios_entry *se = NULL;
1232 struct smbios_entry30 *se3;
1233 unsigned long tables;
1234 int len = 0;
1235 int max_struct_size = 0;
1236 int handle = 0;
1238 current = ALIGN_UP(current, 16);
1239 printk(BIOS_DEBUG, "%s: %08lx\n", __func__, current);
1241 // only add a 32 bit entry point if SMBIOS table is below 4G
1242 if (current < UINT32_MAX) {
1243 se = (struct smbios_entry *)current;
1244 current += sizeof(*se);
1245 current = ALIGN_UP(current, 16);
1248 se3 = (struct smbios_entry30 *)current;
1249 current += sizeof(*se3);
1250 current = ALIGN_UP(current, 16);
1252 tables = current;
1253 update_max(len, max_struct_size, smbios_write_type0(&current, handle++));
1254 update_max(len, max_struct_size, smbios_write_type1(&current, handle++));
1256 /* The chassis handle is the next one */
1257 update_max(len, max_struct_size, smbios_write_type2(&current, handle, handle + 1));
1258 handle++;
1259 update_max(len, max_struct_size, smbios_write_type3(&current, handle++));
1261 for (unsigned int s = 0; s < smbios_get_max_sockets(); s++) {
1262 struct smbios_type4 *type4 = (struct smbios_type4 *)current;
1263 update_max(len, max_struct_size, smbios_write_type4(&current, handle++));
1264 len += smbios_write_type7_cache_parameters(&current, &handle, &max_struct_size, type4);
1266 update_max(len, max_struct_size, smbios_write_type11(&current, &handle));
1267 if (CONFIG(ELOG))
1268 update_max(len, max_struct_size,
1269 elog_smbios_write_type15(&current, handle++));
1271 const int type16 = handle;
1272 update_max(len, max_struct_size, smbios_write_type16(&current, &handle));
1273 const int type17 = handle;
1274 update_max(len, max_struct_size, smbios_write_type17(&current, &handle, type16));
1275 const int type19 = handle;
1276 update_max(len, max_struct_size, smbios_write_type19(&current, &handle, type16));
1277 update_max(len, max_struct_size,
1278 smbios_write_type20(&current, &handle, type17, type19));
1279 update_max(len, max_struct_size, smbios_write_type32(&current, handle++));
1281 update_max(len, max_struct_size, smbios_walk_device_tree(all_devices,
1282 &handle, &current));
1284 update_max(len, max_struct_size, smbios_write_type127(&current, handle++));
1286 if (se) {
1287 /* Install SMBIOS 2.1 entry point */
1288 memset(se, 0, sizeof(*se));
1289 memcpy(se->anchor, "_SM_", 4);
1290 se->length = sizeof(*se);
1291 se->major_version = 3;
1292 se->minor_version = 0;
1293 se->max_struct_size = max_struct_size;
1294 se->struct_count = handle;
1295 memcpy(se->intermediate_anchor_string, "_DMI_", 5);
1297 se->struct_table_address = (u32)tables;
1298 se->struct_table_length = len;
1300 se->intermediate_checksum = smbios_checksum((u8 *)se + 0x10, sizeof(*se) - 0x10);
1301 se->checksum = smbios_checksum((u8 *)se, sizeof(*se));
1304 /* Install SMBIOS 3.0 entry point */
1305 memset(se3, 0, sizeof(*se3));
1306 memcpy(se3->anchor, "_SM3_", 5);
1307 se3->length = sizeof(*se3);
1308 se3->major_version = 3;
1309 se3->minor_version = 0;
1311 se3->struct_table_address = (u64)tables;
1312 se3->struct_table_length = len;
1314 se3->checksum = smbios_checksum((u8 *)se3, sizeof(*se3));
1316 return current;