"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

boot/bootfdt: Add smbios3-entrypoint to FDT for non-EFI boots

The Linux kernel can discover SMBIOS tables through two primary methods:
1. Via EFI tables, when using EFI boot;
2. Via the 'smbios3-entrypoint' property in the /chosen node of the
device tree.

When U-Boot boots a Linux kernel using a non-EFI command ("bootm",
"bootz", or "booti"), the kernel relies on the device tree to detect
the hardware. If SMBIOS tables are available in U-Boot, they should
be passed to the kernel via this device tree property.

This patch modifies boot_fdt_prepare(), to inject the SMBIOSv3 table
address into the device tree if there is a table generated by U-boot.
The "board_fdt_chosen_smbios" is weak in order to leave the possibilty
for specific boards to select custom SMBIOS addresses.

The changes in this patch are added in the context of supporting this
device tree property in linux kernel:
https://lkml.org/lkml/2025/10/24/1393

Device tree schema was updated to include the "smbios3-entrypoint" node
in pull request: https://github.com/devicetree-org/dt-schema/pull/177

Signed-off-by: Adriana Nicolae <adriana@arista.com>

authored by

Adriana Nicolae and committed by
Tom Rini
209bbc4e d4a81248

+76
+19
boot/fdt_support.c
··· 27 27 #include <fdtdec.h> 28 28 #include <version.h> 29 29 #include <video.h> 30 + #include <smbios.h> 30 31 31 32 DECLARE_GLOBAL_DATA_PTR; 32 33 ··· 333 334 int nodeoffset; 334 335 int err; 335 336 const char *str; /* used to set string properties */ 337 + ulong smbiosaddr; /* SMBIOS table address */ 336 338 337 339 err = fdt_check_header(fdt); 338 340 if (err < 0) { ··· 385 387 printf("WARNING: could not set u-boot,version %s.\n", 386 388 fdt_strerror(err)); 387 389 return err; 390 + } 391 + 392 + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { 393 + /* Inject SMBIOS address when we have a valid address. 394 + * This is useful for systems using booti/bootm instead of bootefi. 395 + * Failure to set this property is non-fatal, we only generate a 396 + * warning. 397 + */ 398 + smbiosaddr = gd_smbios_start(); 399 + if (smbiosaddr) { 400 + err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint", 401 + smbiosaddr); 402 + if (err < 0) { 403 + printf("WARNING: could not set smbios3-entrypoint %s.\n", 404 + fdt_strerror(err)); 405 + } 406 + } 388 407 } 389 408 390 409 return fdt_fixup_stdout(fdt, nodeoffset);
+9
test/cmd/fdt.c
··· 1274 1274 char fdt[8192]; 1275 1275 struct udevice *dev; 1276 1276 ulong addr; 1277 + ulong smbiosaddr = gd_smbios_start(); 1277 1278 1278 1279 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr)); 1279 1280 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ ··· 1292 1293 ut_assert(0 < console_record_readline(uts->actual_str, 1293 1294 sizeof(uts->actual_str))); 1294 1295 ut_asserteq_str("chosen {", uts->actual_str); 1296 + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) 1297 + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", 1298 + upper_32_bits(smbiosaddr), 1299 + lower_32_bits(smbiosaddr)); 1295 1300 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ 1296 1301 if (env_bootargs) 1297 1302 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); ··· 1316 1321 lower_32_bits(0x1234 + 0x5678 - 1)); 1317 1322 ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;", 1318 1323 upper_32_bits(0x1234), lower_32_bits(0x1234)); 1324 + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) 1325 + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", 1326 + upper_32_bits(smbiosaddr), 1327 + lower_32_bits(smbiosaddr)); 1319 1328 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ 1320 1329 if (env_bootargs) 1321 1330 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
+48
test/dm/fdtdec.c
··· 7 7 #include <asm/global_data.h> 8 8 #include <dm/of_extra.h> 9 9 #include <dm/test.h> 10 + #include <fdt_support.h> 11 + #include <mapmem.h> 12 + #include <smbios.h> 10 13 #include <test/ut.h> 11 14 12 15 DECLARE_GLOBAL_DATA_PTR; ··· 129 132 } 130 133 DM_TEST(dm_test_fdtdec_add_reserved_memory, 131 134 UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_FLAT_TREE); 135 + 136 + static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts) 137 + { 138 + void *blob; 139 + ulong val; 140 + struct smbios3_entry *entry; 141 + int chosen, blob_sz; 142 + const fdt64_t *prop; 143 + 144 + if (!CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { 145 + return -EAGAIN; 146 + } 147 + 148 + blob_sz = fdt_totalsize(gd->fdt_blob) + 4096; 149 + blob = memalign(8, blob_sz); 150 + ut_assertnonnull(blob); 151 + 152 + /* Make a writable copy of the fdt blob */ 153 + ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz)); 154 + 155 + /* Mock SMBIOS table */ 156 + entry = map_sysmem(gd->arch.smbios_start, sizeof(struct smbios3_entry)); 157 + memcpy(entry->anchor, "_SM3_", 5); 158 + entry->length = sizeof(struct smbios3_entry); 159 + unmap_sysmem(entry); 160 + 161 + /* Force fdt_chosen to run */ 162 + ut_assertok(fdt_chosen(blob)); 163 + 164 + chosen = fdt_path_offset(blob, "/chosen"); 165 + ut_assert(chosen >= 0); 166 + 167 + /* Verify the property exists */ 168 + prop = fdt_getprop(blob, chosen, "smbios3-entrypoint", NULL); 169 + ut_assertnonnull(prop); 170 + 171 + /* Verify the property matches smbios_start */ 172 + val = fdt64_to_cpu(*prop); 173 + ut_asserteq_64(gd->arch.smbios_start, val); 174 + 175 + free(blob); 176 + 177 + return 0; 178 + } 179 + DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT);