diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 92f2f534ee0..1c215e548db 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -333,6 +334,7 @@ int fdt_chosen(void *fdt) int nodeoffset; int err; const char *str; /* used to set string properties */ + ulong smbiosaddr; /* SMBIOS table address */ err = fdt_check_header(fdt); if (err < 0) { @@ -387,6 +389,23 @@ int fdt_chosen(void *fdt) return err; } + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { + /* Inject SMBIOS address when we have a valid address. + * This is useful for systems using booti/bootm instead of bootefi. + * Failure to set this property is non-fatal, we only generate a + * warning. + */ + smbiosaddr = gd_smbios_start(); + if (smbiosaddr) { + err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint", + smbiosaddr); + if (err < 0) { + printf("WARNING: could not set smbios3-entrypoint %s.\n", + fdt_strerror(err)); + } + } + } + return fdt_fixup_stdout(fdt, nodeoffset); } diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index 4c3c6308ab4..a121b294185 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -1274,6 +1274,7 @@ static int fdt_test_chosen(struct unit_test_state *uts) char fdt[8192]; struct udevice *dev; ulong addr; + ulong smbiosaddr = gd_smbios_start(); ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr)); fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ @@ -1292,6 +1293,10 @@ static int fdt_test_chosen(struct unit_test_state *uts) ut_assert(0 < console_record_readline(uts->actual_str, sizeof(uts->actual_str))); ut_asserteq_str("chosen {", uts->actual_str); + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", + upper_32_bits(smbiosaddr), + lower_32_bits(smbiosaddr)); ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); @@ -1316,6 +1321,10 @@ static int fdt_test_chosen(struct unit_test_state *uts) lower_32_bits(0x1234 + 0x5678 - 1)); ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;", upper_32_bits(0x1234), lower_32_bits(0x1234)); + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", + upper_32_bits(smbiosaddr), + lower_32_bits(smbiosaddr)); ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c index 1f24f1d5dff..ea5a494612c 100644 --- a/test/dm/fdtdec.c +++ b/test/dm/fdtdec.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -129,3 +132,48 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) } DM_TEST(dm_test_fdtdec_add_reserved_memory, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_FLAT_TREE); + +static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts) +{ + void *blob; + ulong val; + struct smbios3_entry *entry; + int chosen, blob_sz; + const fdt64_t *prop; + + if (!CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { + return -EAGAIN; + } + + blob_sz = fdt_totalsize(gd->fdt_blob) + 4096; + blob = memalign(8, blob_sz); + ut_assertnonnull(blob); + + /* Make a writable copy of the fdt blob */ + ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz)); + + /* Mock SMBIOS table */ + entry = map_sysmem(gd->arch.smbios_start, sizeof(struct smbios3_entry)); + memcpy(entry->anchor, "_SM3_", 5); + entry->length = sizeof(struct smbios3_entry); + unmap_sysmem(entry); + + /* Force fdt_chosen to run */ + ut_assertok(fdt_chosen(blob)); + + chosen = fdt_path_offset(blob, "/chosen"); + ut_assert(chosen >= 0); + + /* Verify the property exists */ + prop = fdt_getprop(blob, chosen, "smbios3-entrypoint", NULL); + ut_assertnonnull(prop); + + /* Verify the property matches smbios_start */ + val = fdt64_to_cpu(*prop); + ut_asserteq_64(gd->arch.smbios_start, val); + + free(blob); + + return 0; +} +DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT);