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