2 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
4 * Adapted from coreboot src/arch/x86/smbios.c
6 * SPDX-License-Identifier: GPL-2.0+
11 #include <tables_csum.h>
15 DECLARE_GLOBAL_DATA_PTR
;
18 * smbios_add_string() - add a string to the string area
20 * This adds a string to the string area which is appended directly after
21 * the formatted portion of an SMBIOS structure.
23 * @start: string area start address
25 * @return: string number in the string area
27 static int smbios_add_string(char *start
, const char *str
)
51 * smbios_string_table_len() - compute the string area size
53 * This computes the size of the string area including the string terminator.
55 * @start: string area start address
56 * @return: string area size
58 static int smbios_string_table_len(char *start
)
72 static int smbios_write_type0(uintptr_t *current
, int handle
)
74 struct smbios_type0
*t
= (struct smbios_type0
*)*current
;
75 int len
= sizeof(struct smbios_type0
);
77 memset(t
, 0, sizeof(struct smbios_type0
));
78 fill_smbios_header(t
, SMBIOS_BIOS_INFORMATION
, len
, handle
);
79 t
->vendor
= smbios_add_string(t
->eos
, "U-Boot");
80 t
->bios_ver
= smbios_add_string(t
->eos
, PLAIN_VERSION
);
81 t
->bios_release_date
= smbios_add_string(t
->eos
, U_BOOT_DMI_DATE
);
82 t
->bios_rom_size
= (CONFIG_ROM_SIZE
/ 65536) - 1;
83 t
->bios_characteristics
= BIOS_CHARACTERISTICS_PCI_SUPPORTED
|
84 BIOS_CHARACTERISTICS_SELECTABLE_BOOT
|
85 BIOS_CHARACTERISTICS_UPGRADEABLE
;
86 #ifdef CONFIG_GENERATE_ACPI_TABLE
87 t
->bios_characteristics_ext1
= BIOS_CHARACTERISTICS_EXT1_ACPI
;
89 t
->bios_characteristics_ext2
= BIOS_CHARACTERISTICS_EXT2_TARGET
;
90 t
->bios_major_release
= 0xff;
91 t
->bios_minor_release
= 0xff;
92 t
->ec_major_release
= 0xff;
93 t
->ec_minor_release
= 0xff;
95 len
= t
->length
+ smbios_string_table_len(t
->eos
);
101 static int smbios_write_type1(uintptr_t *current
, int handle
)
103 struct smbios_type1
*t
= (struct smbios_type1
*)*current
;
104 int len
= sizeof(struct smbios_type1
);
106 memset(t
, 0, sizeof(struct smbios_type1
));
107 fill_smbios_header(t
, SMBIOS_SYSTEM_INFORMATION
, len
, handle
);
108 t
->manufacturer
= smbios_add_string(t
->eos
, CONFIG_SMBIOS_MANUFACTURER
);
109 t
->product_name
= smbios_add_string(t
->eos
, CONFIG_SMBIOS_PRODUCT_NAME
);
111 len
= t
->length
+ smbios_string_table_len(t
->eos
);
117 static int smbios_write_type2(uintptr_t *current
, int handle
)
119 struct smbios_type2
*t
= (struct smbios_type2
*)*current
;
120 int len
= sizeof(struct smbios_type2
);
122 memset(t
, 0, sizeof(struct smbios_type2
));
123 fill_smbios_header(t
, SMBIOS_BOARD_INFORMATION
, len
, handle
);
124 t
->manufacturer
= smbios_add_string(t
->eos
, CONFIG_SMBIOS_MANUFACTURER
);
125 t
->product_name
= smbios_add_string(t
->eos
, CONFIG_SMBIOS_PRODUCT_NAME
);
126 t
->feature_flags
= SMBIOS_BOARD_FEATURE_HOSTING
;
127 t
->board_type
= SMBIOS_BOARD_MOTHERBOARD
;
129 len
= t
->length
+ smbios_string_table_len(t
->eos
);
135 static int smbios_write_type3(uintptr_t *current
, int handle
)
137 struct smbios_type3
*t
= (struct smbios_type3
*)*current
;
138 int len
= sizeof(struct smbios_type3
);
140 memset(t
, 0, sizeof(struct smbios_type3
));
141 fill_smbios_header(t
, SMBIOS_SYSTEM_ENCLOSURE
, len
, handle
);
142 t
->manufacturer
= smbios_add_string(t
->eos
, CONFIG_SMBIOS_MANUFACTURER
);
143 t
->chassis_type
= SMBIOS_ENCLOSURE_DESKTOP
;
144 t
->bootup_state
= SMBIOS_STATE_SAFE
;
145 t
->power_supply_state
= SMBIOS_STATE_SAFE
;
146 t
->thermal_state
= SMBIOS_STATE_SAFE
;
147 t
->security_status
= SMBIOS_SECURITY_NONE
;
149 len
= t
->length
+ smbios_string_table_len(t
->eos
);
155 static int smbios_write_type4(uintptr_t *current
, int handle
)
157 struct smbios_type4
*t
= (struct smbios_type4
*)*current
;
158 int len
= sizeof(struct smbios_type4
);
161 char processor_name
[CPU_MAX_NAME_LEN
];
162 struct cpuid_result res
;
164 memset(t
, 0, sizeof(struct smbios_type4
));
165 fill_smbios_header(t
, SMBIOS_PROCESSOR_INFORMATION
, len
, handle
);
166 t
->processor_type
= SMBIOS_PROCESSOR_TYPE_CENTRAL
;
167 t
->processor_family
= gd
->arch
.x86
;
168 vendor
= cpu_vendor_name(gd
->arch
.x86_vendor
);
169 t
->processor_manufacturer
= smbios_add_string(t
->eos
, vendor
);
171 t
->processor_id
[0] = res
.eax
;
172 t
->processor_id
[1] = res
.edx
;
173 name
= cpu_get_name(processor_name
);
174 t
->processor_version
= smbios_add_string(t
->eos
, name
);
175 t
->status
= SMBIOS_PROCESSOR_STATUS_ENABLED
;
176 t
->processor_upgrade
= SMBIOS_PROCESSOR_UPGRADE_NONE
;
177 t
->l1_cache_handle
= 0xffff;
178 t
->l2_cache_handle
= 0xffff;
179 t
->l3_cache_handle
= 0xffff;
180 t
->processor_family2
= t
->processor_family
;
182 len
= t
->length
+ smbios_string_table_len(t
->eos
);
188 static int smbios_write_type32(uintptr_t *current
, int handle
)
190 struct smbios_type32
*t
= (struct smbios_type32
*)*current
;
191 int len
= sizeof(struct smbios_type32
);
193 memset(t
, 0, sizeof(struct smbios_type32
));
194 fill_smbios_header(t
, SMBIOS_SYSTEM_BOOT_INFORMATION
, len
, handle
);
201 static int smbios_write_type127(uintptr_t *current
, int handle
)
203 struct smbios_type127
*t
= (struct smbios_type127
*)*current
;
204 int len
= sizeof(struct smbios_type127
);
206 memset(t
, 0, sizeof(struct smbios_type127
));
207 fill_smbios_header(t
, SMBIOS_END_OF_TABLE
, len
, handle
);
214 static smbios_write_type smbios_write_funcs
[] = {
224 uintptr_t write_smbios_table(uintptr_t addr
)
226 struct smbios_entry
*se
;
229 int max_struct_size
= 0;
235 /* 16 byte align the table address */
236 addr
= ALIGN(addr
, 16);
238 se
= (struct smbios_entry
*)addr
;
239 memset(se
, 0, sizeof(struct smbios_entry
));
241 addr
+= sizeof(struct smbios_entry
);
242 addr
= ALIGN(addr
, 16);
245 /* populate minimum required tables */
246 for (i
= 0; i
< ARRAY_SIZE(smbios_write_funcs
); i
++) {
247 int tmp
= smbios_write_funcs
[i
](&addr
, handle
++);
248 max_struct_size
= max(max_struct_size
, tmp
);
252 memcpy(se
->anchor
, "_SM_", 4);
253 se
->length
= sizeof(struct smbios_entry
);
254 se
->major_ver
= SMBIOS_MAJOR_VER
;
255 se
->minor_ver
= SMBIOS_MINOR_VER
;
256 se
->max_struct_size
= max_struct_size
;
257 memcpy(se
->intermediate_anchor
, "_DMI_", 5);
258 se
->struct_table_length
= len
;
259 se
->struct_table_address
= tables
;
260 se
->struct_count
= handle
;
262 /* calculate checksums */
263 istart
= (char *)se
+ SMBIOS_INTERMEDIATE_OFFSET
;
264 isize
= sizeof(struct smbios_entry
) - SMBIOS_INTERMEDIATE_OFFSET
;
265 se
->intermediate_checksum
= table_compute_checksum(istart
, isize
);
266 se
->checksum
= table_compute_checksum(se
, sizeof(struct smbios_entry
));