[PATCH v2 00/12] x86: Minor improvements mostly for image loading

This series provides a few improvements for loading of images. It also provides a way to show more detailed model information as well as an of-platdata fix noticed recently.
Changes in v2: - Add comment to .lds file - Add more notes to the commit - Fix two missing asterisks in comments
Simon Glass (12): x86: acpi_gpe: Update driver name to match devicetree x86: spl: Add a function to find the text base x86: apl: Enhance debugging in the SPL loader x86: Make sure the SPL image ends on a suitable boundary x86: spl: Make moving BSS conditional x86: Update Chromium OS GNVS names x86: zimage: Allow dumping the image from outside the module x86: zimage: Improve command-line debug handling x86: spl: Clear BSS unconditionally x86: tpl: Show next stage being booted sysinfo: Allow showing model info from sysinfo x86: coral: Show memory config and SKU ID on startup
arch/x86/cpu/acpi_gpe.c | 6 +- arch/x86/cpu/apollolake/spl.c | 12 +- arch/x86/cpu/u-boot-spl.lds | 12 ++ arch/x86/dts/chromebook_coral.dts | 11 ++ arch/x86/include/asm/intel_gnvs.h | 34 ++++- arch/x86/include/asm/zimage.h | 10 ++ arch/x86/lib/spl.c | 2 +- arch/x86/lib/tpl.c | 7 +- arch/x86/lib/zimage.c | 33 +++-- board/google/chromebook_coral/coral.c | 139 +++++++++++++++++- board/google/chromebook_coral/variant_gpio.h | 6 - common/board_info.c | 37 ++++- common/spl/spl.c | 6 + .../sysinfo/google,coral.txt | 37 +++++ include/spl.h | 10 ++ include/sysinfo.h | 4 + 16 files changed, 318 insertions(+), 48 deletions(-) create mode 100644 doc/device-tree-bindings/sysinfo/google,coral.txt

Use a driver name in line with the compatible string so that of-platdata can use this driver.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/cpu/acpi_gpe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/cpu/acpi_gpe.c b/arch/x86/cpu/acpi_gpe.c index 83128c33c2c..da01e71335f 100644 --- a/arch/x86/cpu/acpi_gpe.c +++ b/arch/x86/cpu/acpi_gpe.c @@ -4,6 +4,8 @@ * Written by Simon Glass sjg@chromium.org */
+#define LOG_CATEGORY UCLASS_IRQ + #include <common.h> #include <dm.h> #include <irq.h> @@ -102,8 +104,8 @@ static const struct udevice_id acpi_gpe_ids[] = { { } };
-U_BOOT_DRIVER(acpi_gpe_drv) = { - .name = "acpi_gpe", +U_BOOT_DRIVER(intel_acpi_gpe) = { + .name = "intel_acpi_gpe", .id = UCLASS_IRQ, .of_match = acpi_gpe_ids, .ops = &acpi_gpe_ops,

It is useful to know the TEXT_BASE value for the image being loaded in TPL/SPL. Add a new spl_get_image_text_base() function to handle this.
Make use of this in the x86 SPL handler, instead of having the logic there.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
common/spl/spl.c | 6 ++++++ include/spl.h | 10 ++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/spl/spl.c b/common/spl/spl.c index d375dcbb2ed..12b00e2a407 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -144,6 +144,12 @@ ulong spl_get_image_size(void) binman_sym(ulong, u_boot_any, size); }
+ulong spl_get_image_text_base(void) +{ + return spl_phase() == PHASE_TPL ? CONFIG_SPL_TEXT_BASE : + CONFIG_SYS_TEXT_BASE; +} + /* * Weak default function for board specific cleanup/preparation before * Linux boot. Some boards/platforms might not need it, so just provide diff --git a/include/spl.h b/include/spl.h index faffeb519ac..e172500b5f8 100644 --- a/include/spl.h +++ b/include/spl.h @@ -254,6 +254,16 @@ ulong spl_get_image_pos(void); */ ulong spl_get_image_size(void);
+/** + * spl_get_image_text_base() - get the text base of the next phase + * + * This returns the address that the next stage is linked to run at, i.e. + * CONFIG_SPL_TEXT_BASE or CONFIG_SYS_TEXT_BASE + * + * @return text-base address + */ +ulong spl_get_image_text_base(void); + /** * spl_load_simple_fit_skip_processing() - Hook to allow skipping the FIT * image processing during spl_load_simple_fit().

Move to log_debug() and make use of the new SPL function to find the text base.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/cpu/apollolake/spl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c index 8991d5e648e..f2d25734c60 100644 --- a/arch/x86/cpu/apollolake/spl.c +++ b/arch/x86/cpu/apollolake/spl.c @@ -3,6 +3,8 @@ * Copyright 2019 Google LLC */
+#define LOG_CATEGORY LOGC_BOOT + #include <common.h> #include <binman_sym.h> #include <bootstage.h> @@ -33,12 +35,11 @@ static int rom_load_image(struct spl_image_info *spl_image, int ret;
spl_image->size = CONFIG_SYS_MONITOR_LEN; /* We don't know SPL size */ - spl_image->entry_point = spl_phase() == PHASE_TPL ? - CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE; + spl_image->entry_point = spl_get_image_text_base(); spl_image->load_addr = spl_image->entry_point; spl_image->os = IH_OS_U_BOOT; spl_image->name = "U-Boot"; - debug("Reading from mapped SPI %lx, size %lx", spl_pos, spl_size); + log_debug("Reading from mapped SPI %lx, size %lx\n", spl_pos, spl_size);
if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) { ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev); @@ -56,7 +57,8 @@ static int rom_load_image(struct spl_image_info *spl_image, return ret; } spl_pos += map_base & ~0xff000000; - debug(", base %lx, pos %lx\n", map_base, spl_pos); + log_debug(", base %lx, pos %lx, load %lx\n", map_base, spl_pos, + spl_image->load_addr); bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi"); memcpy((void *)spl_image->load_addr, (void *)spl_pos, spl_size); cpu_flush_l1d_to_l2(); @@ -121,7 +123,7 @@ static int spl_fast_spi_load_image(struct spl_image_info *spl_image, spl_image->os = IH_OS_U_BOOT; spl_image->name = "U-Boot"; spl_pos &= ~0xff000000; - debug("Reading from flash %lx, size %lx\n", spl_pos, spl_size); + log_debug("Reading from flash %lx, size %lx\n", spl_pos, spl_size); ret = spi_flash_read_dm(dev, spl_pos, spl_size, (void *)spl_image->load_addr); cpu_flush_l1d_to_l2();

The part of U-Boot that actually ends up in u-boot-nodtb.bin is not built with any particular alignment. It ends at the start of the BSS section. The BSS section selects its own alignment, which may larger. This means that there can be a gap of a few bytes between the image ending and BSS starting.
Since u-boot.bin is build by joining u-boot-nodtb.bin and u-boot.dtb (with perhaps some padding for BSS), the expected result is not obtained. U-Boot uses the end of BSS to find the devicetree, so this means that it cannot be found.
Add 32-byte alignment of BSS so that the image size is correct and appending the devicetree will place it at the end of BSS.
Signed-off-by: Simon Glass sjg@chromium.org ---
Example SPL output without this patch:
Sections: Idx Name Size VMA LMA File off Algn 0 .text 000142a1 fef40000 fef40000 00001000 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .u_boot_list 000014a4 fef542a8 fef542a8 000152a8 2**3 CONTENTS, ALLOC, LOAD, RELOC, DATA 2 .rodata 0000599c fef55760 fef55760 00016760 2**5 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 3 .data 00000970 fef5b100 fef5b100 0001c100 2**5 CONTENTS, ALLOC, LOAD, RELOC, DATA 4 .binman_sym_table 00000020 fef5ba70 fef5ba70 0001ca70 2**2 CONTENTS, ALLOC, LOAD, DATA 5 .bss 00000060 fef5baa0 fef5baa0 00000000 2**5 ALLOC
You can see that .bss is aligned to 2**5 (32 bytes). This is because of the mallinfo struct in dlmalloc.c:
17 .bss.current_mallinfo 00000028 00000000 00000000 000004c0 2**5 ALLOC
In this case the size of u-boot-spl-nodtb.bin is 0x1ba90. This matches up with the _image_binary_end symbol:
fef5ba90 g .binman_sym_table 00000000 _image_binary_end
But BSS starts 16 bytes later, at 0xfef5baa0, due to the 32-byte alignment. So we must align _image_binary_end to a 32-byte boundary. This forces the binary size to be 0x1baa0, i.e. ending at the start of bss, as expected.
Note that gcc reports __BIGGEST_ALIGNMENT__ of 16 on this build, even though it generates an object file with a member that requests 32-byte alignment.
The current_mallinfo struct is 40 bytes in size. Increasing the struct to 68 bytes (i.e. just above a 64-byte boundary) does not cause the alignment to go above 32 bytes. So it seems that 32 bytes is the maximum alignment at present.
Changes in v2: - Add comment to .lds file - Add more notes to the commit
arch/x86/cpu/u-boot-spl.lds | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index e6c22895b35..ead4f380e74 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -43,6 +43,16 @@ SECTIONS __binman_sym_start = .; KEEP(*(SORT(.binman_sym*))); __binman_sym_end = .; + + /* + * Force 32-byte alignment so that it lines up with the start of + * bss, which may have up to 32-byte alignment. This ensures + * that the end of the .bin file matches up with + * _image_binary_end or __bss_end - see board_fdt_blob_setup(). + * The alignment of BSS depends on what is in it, so can range + * from 4 to 32 bytes. + */ + . = ALIGN(32); }
_image_binary_end = .;

On Mon, Jan 25, 2021 at 1:06 AM Simon Glass sjg@chromium.org wrote:
The part of U-Boot that actually ends up in u-boot-nodtb.bin is not built with any particular alignment. It ends at the start of the BSS section. The BSS section selects its own alignment, which may larger.
may be
This means that there can be a gap of a few bytes between the image ending and BSS starting.
Since u-boot.bin is build by joining u-boot-nodtb.bin and u-boot.dtb (with perhaps some padding for BSS), the expected result is not obtained. U-Boot uses the end of BSS to find the devicetree, so this means that it cannot be found.
Add 32-byte alignment of BSS so that the image size is correct and appending the devicetree will place it at the end of BSS.
Signed-off-by: Simon Glass sjg@chromium.org
Example SPL output without this patch:
Sections: Idx Name Size VMA LMA File off Algn 0 .text 000142a1 fef40000 fef40000 00001000 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .u_boot_list 000014a4 fef542a8 fef542a8 000152a8 2**3 CONTENTS, ALLOC, LOAD, RELOC, DATA 2 .rodata 0000599c fef55760 fef55760 00016760 2**5 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 3 .data 00000970 fef5b100 fef5b100 0001c100 2**5 CONTENTS, ALLOC, LOAD, RELOC, DATA 4 .binman_sym_table 00000020 fef5ba70 fef5ba70 0001ca70 2**2 CONTENTS, ALLOC, LOAD, DATA 5 .bss 00000060 fef5baa0 fef5baa0 00000000 2**5 ALLOC
You can see that .bss is aligned to 2**5 (32 bytes). This is because of the mallinfo struct in dlmalloc.c:
17 .bss.current_mallinfo 00000028 00000000 00000000 000004c0 2**5 ALLOC
In this case the size of u-boot-spl-nodtb.bin is 0x1ba90. This matches up with the _image_binary_end symbol:
fef5ba90 g .binman_sym_table 00000000 _image_binary_end
But BSS starts 16 bytes later, at 0xfef5baa0, due to the 32-byte alignment. So we must align _image_binary_end to a 32-byte boundary. This forces the binary size to be 0x1baa0, i.e. ending at the start of bss, as expected.
Note that gcc reports __BIGGEST_ALIGNMENT__ of 16 on this build, even though it generates an object file with a member that requests 32-byte alignment.
The current_mallinfo struct is 40 bytes in size. Increasing the struct to 68 bytes (i.e. just above a 64-byte boundary) does not cause the alignment to go above 32 bytes. So it seems that 32 bytes is the maximum alignment at present.
The above information is very useful for people to understand such tricky changes.
I can put such in the commit message when applying.
Changes in v2:
- Add comment to .lds file
- Add more notes to the commit
arch/x86/cpu/u-boot-spl.lds | 10 ++++++++++ 1 file changed, 10 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

At present BSS is always placed in SDRAM. If a separate BSS is not in use this means that BSS doesn't work as expected. Make the setting conditional on the SEPARATE_BSS option.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/cpu/u-boot-spl.lds | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index ead4f380e74..b82e53ab124 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -57,7 +57,9 @@ SECTIONS
_image_binary_end = .;
+#if CONFIG_IS_ENABLED(SEPARATE_BSS) . = 0x120000; +#endif .bss (OVERLAY) : { __bss_start = .; *(.bss*)

The Global Non-Volatile Storage struct has some fields with particular meanings. Rename these to make things easier to follow. Also add a few more boot flags.
GNVS should not be confused with GNVQ (Going Nowhere Very Quickly).
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/include/asm/intel_gnvs.h | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/intel_gnvs.h b/arch/x86/include/asm/intel_gnvs.h index 7f9f101371c..69a20812e5e 100644 --- a/arch/x86/include/asm/intel_gnvs.h +++ b/arch/x86/include/asm/intel_gnvs.h @@ -9,6 +9,7 @@ #ifndef _INTEL_GNVS_H_ #define _INTEL_GNVS_H_
+#include <linux/bitops.h> /* * The chromeos_acpi portion of ACPI GNVS is assumed to live from offset * 0x100 - 0x1000. When defining acpi_global_nvs, use check_member @@ -18,6 +19,11 @@ */ #define GNVS_CHROMEOS_ACPI_OFFSET 0x100
+enum { + BOOT_REASON_OTHER = 0, + BOOT_REASON_S3DIAG = 9 +}; + enum { CHSW_RECOVERY_X86 = BIT(1), CHSW_RECOVERY_EC = BIT(2), @@ -25,6 +31,22 @@ enum { CHSW_FIRMWARE_WP = BIT(9), };
+enum { + RECOVERY_REASON_NONE = 0, + RECOVERY_REASON_ME = 1 +}; + +enum { + ACTIVE_ECFW_RO = 0, + ACTIVE_ECFW_RW = 1 +}; + +enum { + BINF_RECOVERY = 0, + BINF_RW_A = 1, + BINF_RW_B = 2 +}; + enum { FIRMWARE_TYPE_AUTO_DETECT = -1, FIRMWARE_TYPE_RECOVERY = 0, @@ -40,14 +62,14 @@ struct __packed chromeos_acpi_gnvs { u32 active_main_fw; /* 04 (0=recovery, 1=A, 2=B) */ u32 activeec_fw; /* 08 (0=RO, 1=RW) */ u16 switches; /* 0c CHSW */ - u8 vbt4[256]; /* 0e HWID */ - u8 vbt5[64]; /* 10e FWID */ - u8 vbt6[64]; /* 14e FRID - 275 */ + u8 hwid[256]; /* 0e HWID */ + u8 fwid[64]; /* 10e FWID */ + u8 frid[64]; /* 14e FRID - 275 */ u32 main_fw_type; /* 18e (2 = developer mode) */ - u32 vbt8; /* 192 recovery reason */ - u32 vbt9; /* 196 fmap base address */ + u32 recovery_reason; /* 192 recovery reason */ + u32 fmap_base; /* 196 fmap base address */ u8 vdat[3072]; /* 19a VDAT space filled by verified boot */ - u32 vbt10; /* d9a smbios bios version */ + u32 fwid_ptr; /* d9a smbios bios version */ u32 mehh[8]; /* d9e management engine hash */ u32 ramoops_base; /* dbe ramoops base address */ u32 ramoops_len; /* dc2 ramoops length */

At present it is possible to dump an image within the zimage command, but it is also useful to be able to dump it from elsewhere, for example in a loader that has special handling for the different zimage stages.
Export this feature as a new function.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/include/asm/zimage.h | 10 ++++++++++ arch/x86/lib/zimage.c | 23 +++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h index 64c0e6e857b..6679767d16b 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -62,6 +62,16 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, ulong initrd_addr, ulong initrd_size, ulong cmdline_force);
+/** + * zimage_dump() - Dump the metadata of a zimage + * + * This shows all available information in a zimage that has been loaded. + * + * @base_ptr: Pointer to the boot parameters, typically at address + * DEFAULT_SETUP_BASE + */ +void zimage_dump(struct boot_params *base_ptr); + void setup_video(struct screen_info *screen_info); void setup_efi_info(struct efi_info *efi_info);
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 708025b2071..3e9ee12400f 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -600,19 +600,12 @@ static void show_loader(struct setup_header *hdr) printf("\n"); }
-int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +void zimage_dump(struct boot_params *base_ptr) { - struct boot_params *base_ptr = state.base_ptr; struct setup_header *hdr; const char *version; int i;
- if (argc > 1) - base_ptr = (void *)simple_strtoul(argv[1], NULL, 16); - if (!base_ptr) { - printf("No zboot setup_base\n"); - return CMD_RET_FAILURE; - } printf("Setup located at %p:\n\n", base_ptr); print_num64("ACPI RSDP addr", base_ptr->acpi_rsdp_addr);
@@ -688,6 +681,20 @@ int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) print_num("Handover offset", hdr->handover_offset); if (get_boot_protocol(hdr, false) >= 0x215) print_num("Kernel info offset", hdr->kernel_info_offset); +} + +static int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct boot_params *base_ptr = state.base_ptr; + + if (argc > 1) + base_ptr = (void *)simple_strtoul(argv[1], NULL, 16); + if (!base_ptr) { + printf("No zboot setup_base\n"); + return CMD_RET_FAILURE; + } + zimage_dump(base_ptr);
return 0; }

At present if the command line is very long it is truncated by the printf() statement, which works within a limited buffer. Use puts() instead. Also show better debugging with the command-line setup fails.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/lib/zimage.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 3e9ee12400f..602788e016d 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -109,8 +109,11 @@ static void build_command_line(char *command_line, int auto_boot)
if (env_command_line) strcat(command_line, env_command_line); - - printf("Kernel command line: "%s"\n", command_line); +#ifdef DEBUG + printf("Kernel command line:"); + puts(command_line); + printf("\n"); +#endif }
static int kernel_magic_ok(struct setup_header *hdr) @@ -354,7 +357,8 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, build_command_line(cmd_line, auto_boot); ret = bootm_process_cmdline(cmd_line, max_size, BOOTM_CL_ALL); if (ret) { - printf("Cmdline setup failed (err=%d)\n", ret); + printf("Cmdline setup failed (max_size=%x, bootproto=%x, err=%d)\n", + max_size, bootproto, ret); return ret; } printf("Kernel command line: "");

This should be done even if not using TPL, since BSS may be in use or boards that only use SPL. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/lib/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index cf22fa2d7b5..6699de49c63 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -115,8 +115,8 @@ static int x86_spl_init(void) }
#ifndef CONFIG_SYS_COREBOOT -# ifndef CONFIG_TPL memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start); +# ifndef CONFIG_TPL
/* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */ ret = interrupt_init();

Enhance the debugging to show the next stage being booted as well as a dump of the start of the image.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/lib/tpl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index 04ff32277fd..c84a0c9bc7d 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -111,7 +111,12 @@ int spl_spi_load_image(void)
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { - debug("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point); + debug("Jumping to %s at %lx\n", spl_phase_name(spl_next_phase()), + (ulong)spl_image->entry_point); +#ifdef DEBUG + print_buffer(spl_image->entry_point, (void *)spl_image->entry_point, 1, + 0x20, 0); +#endif jump_to_spl(spl_image->entry_point); hang(); }

Some boards may want to show the SKU ID or other information obtained at runtime. Allow this to come from sysinfo. The board can then provide a sysinfo driver to provide it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
common/board_info.c | 37 +++++++++++++++++++++++++++++-------- include/sysinfo.h | 4 ++++ 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/common/board_info.c b/common/board_info.c index a6db087f960..20a2dea1f35 100644 --- a/common/board_info.c +++ b/common/board_info.c @@ -1,30 +1,51 @@ // SPDX-License-Identifier: GPL-2.0+
#include <common.h> +#include <dm.h> #include <init.h> +#include <sysinfo.h> #include <linux/libfdt.h> #include <linux/compiler.h>
+DECLARE_GLOBAL_DATA_PTR; + int __weak checkboard(void) { return 0; }
/* - * If the root node of the DTB has a "model" property, show it. + * Check sysinfo for board information. Failing that if the root node of the DTB + * has a "model" property, show it. + * * Then call checkboard(). */ int __weak show_board_info(void) { -#ifdef CONFIG_OF_CONTROL - DECLARE_GLOBAL_DATA_PTR; - const char *model; + if (IS_ENABLED(CONFIG_OF_CONTROL)) { + struct udevice *dev; + const char *model; + char str[80]; + int ret = -ENOSYS; + + if (IS_ENABLED(CONFIG_SYSINFO)) { + /* This might provide more detail */ + ret = uclass_first_device_err(UCLASS_SYSINFO, &dev); + if (!ret) + ret = sysinfo_get_str(dev, + SYSINFO_ID_BOARD_MODEL, + sizeof(str), str); + }
- model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + /* Fail back to the main 'model' if available */ + if (ret) + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + else + model = str;
- if (model) - printf("Model: %s\n", model); -#endif + if (model) + printf("Model: %s\n", model); + }
return checkboard(); } diff --git a/include/sysinfo.h b/include/sysinfo.h index 743f3554659..f4ffb1a3503 100644 --- a/include/sysinfo.h +++ b/include/sysinfo.h @@ -35,9 +35,13 @@ enum sysinfo_id { SYSINFO_ID_NONE,
+ /* For SMBIOS tables */ SYSINFO_ID_SMBIOS_SYSTEM_VERSION, SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
+ /* For show_board_info() */ + SYSINFO_ID_BOARD_MODEL, + /* First value available for downstream/board used */ SYSINFO_ID_USER = 0x1000, };

Provide the model information through sysinfo so that it shows up on boot. For memconfig 4 pins are provided, for 16 combinations. For SKU ID there are two options:
- two pins provided in a ternary arrangement, for 9 combinations. - reading from the EC
Add a binding doc and drop the unused #defines as well.
Example:
U-Boot 2021.01-rc5
CPU: Intel(R) Celeron(R) CPU N3450 @ 1.10GHz DRAM: 3.9 GiB MMC: sdmmc@1b,0: 1, emmc@1c,0: 2 Video: 1024x768x32 @ b0000000 Model: Google Coral (memconfig 5, SKU 3)
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: - Fix two missing asterisks in comments
arch/x86/dts/chromebook_coral.dts | 11 ++ board/google/chromebook_coral/coral.c | 139 +++++++++++++++++- board/google/chromebook_coral/variant_gpio.h | 6 - .../sysinfo/google,coral.txt | 37 +++++ 4 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 doc/device-tree-bindings/sysinfo/google,coral.txt
diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts index bfbdd517d1f..8ed7c02db91 100644 --- a/arch/x86/dts/chromebook_coral.dts +++ b/arch/x86/dts/chromebook_coral.dts @@ -54,6 +54,17 @@ recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>; write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>; phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>; + memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH + &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH + &gpio_n GPIO_38 GPIO_ACTIVE_HIGH + &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>; + + /* + * This is used for reef only: + * + * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH + * &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>; + */ smbios { /* Type 1 table */ system { diff --git a/board/google/chromebook_coral/coral.c b/board/google/chromebook_coral/coral.c index f9fb3f163f0..77a6cca4497 100644 --- a/board/google/chromebook_coral/coral.c +++ b/board/google/chromebook_coral/coral.c @@ -3,9 +3,12 @@ * Copyright 2019 Google LLC */
+#define LOG_CATEGORY UCLASS_SYSINFO + #include <common.h> #include <bloblist.h> #include <command.h> +#include <cros_ec.h> #include <dm.h> #include <log.h> #include <sysinfo.h> @@ -15,6 +18,7 @@ #include <asm/intel_gnvs.h> #include <asm/intel_pinctrl.h> #include <dm/acpi.h> +#include <linux/delay.h> #include "variant_gpio.h"
struct cros_gpio_info { @@ -29,10 +33,125 @@ int arch_misc_init(void) return 0; }
-/* This function is needed if CONFIG_CMDLINE is not enabled */ -int board_run_command(const char *cmdline) +static int get_memconfig(struct udevice *dev) { - printf("No command line\n"); + struct gpio_desc gpios[4]; + int cfg; + int ret; + + ret = gpio_request_list_by_name(dev, "memconfig-gpios", gpios, + ARRAY_SIZE(gpios), + GPIOD_IS_IN | GPIOD_PULL_UP); + if (ret < 0) { + log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret); + return ret; + } + + /* Give the lines time to settle */ + udelay(10); + + ret = dm_gpio_get_values_as_int(gpios, ARRAY_SIZE(gpios)); + if (ret < 0) + return log_msg_ret("get", ret); + cfg = ret; + + ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios)); + if (ret) + return log_msg_ret("free", ret); + + return cfg; +} + +/** + * get_skuconfig() - Get the SKU number either from pins or the EC + * + * Two options are supported: + * skuconfig-gpios - two pins in the device tree (tried first) + * EC - reading from the EC (backup) + * + * @dev: sysinfo device to use + * @return SKU ID, or -ve error if not found + */ +static int get_skuconfig(struct udevice *dev) +{ + struct gpio_desc gpios[2]; + int cfg; + int ret; + + ret = gpio_request_list_by_name(dev, "skuconfig-gpios", gpios, + ARRAY_SIZE(gpios), + GPIOD_IS_IN); + if (ret != ARRAY_SIZE(gpios)) { + struct udevice *cros_ec; + + log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret); + + /* Try the EC */ + ret = uclass_first_device_err(UCLASS_CROS_EC, &cros_ec); + if (ret < 0) { + log_err("Cannot find EC for SKU details\n"); + return log_msg_ret("sku", ret); + } + ret = cros_ec_get_sku_id(cros_ec); + if (ret < 0) { + log_err("Cannot read SKU details\n"); + return log_msg_ret("sku", ret); + } + + return ret; + } + + ret = dm_gpio_get_values_as_int_base3(gpios, ARRAY_SIZE(gpios)); + if (ret < 0) + return log_msg_ret("get", ret); + cfg = ret; + + ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios)); + if (ret) + return log_msg_ret("free", ret); + + return cfg; +} + +static int coral_get_str(struct udevice *dev, int id, size_t size, char *val) +{ + int ret; + + if (IS_ENABLED(CONFIG_SPL_BUILD)) + return -ENOSYS; + + switch (id) { + case SYSINFO_ID_SMBIOS_SYSTEM_VERSION: + case SYSINFO_ID_SMBIOS_BASEBOARD_VERSION: { + ret = get_skuconfig(dev); + + if (ret < 0) + return ret; + if (size < 15) + return -ENOSPC; + sprintf(val, "rev%d", ret); + break; + } + case SYSINFO_ID_BOARD_MODEL: { + int mem_config, sku_config; + const char *model; + + ret = get_memconfig(dev); + if (ret < 0) + log_warning("Unable to read memconfig (err=%d)\n", ret); + mem_config = ret; + ret = get_skuconfig(dev); + if (ret < 0) + log_warning("Unable to read skuconfig (err=%d)\n", ret); + sku_config = ret; + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + snprintf(val, size, "%s (memconfig %d, SKU %d)", model, + mem_config, sku_config); + break; + } + default: + return -ENOENT; + }
return 0; } @@ -45,12 +164,15 @@ int chromeos_get_gpio(const struct udevice *dev, const char *prop, int ret;
ret = gpio_request_by_name((struct udevice *)dev, prop, 0, &desc, 0); - if (ret == -ENOTBLK) + if (ret == -ENOTBLK) { info->gpio_num = CROS_GPIO_VIRTUAL; - else if (ret) + log_debug("GPIO '%s' is virtual\n", prop); + } else if (ret) { return log_msg_ret("gpio", ret); - else + } else { info->gpio_num = desc.offset; + dm_gpio_free((struct udevice *)dev, &desc); + } info->linux_name = dev_read_string(desc.dev, "linux-name"); if (!info->linux_name) return log_msg_ret("linux-name", -ENOENT); @@ -81,11 +203,11 @@ static int chromeos_acpi_gpio_generate(const struct udevice *dev, ret = chromeos_get_gpio(dev, "write-protect-gpios", CROS_GPIO_WP, &info[1]); if (ret) - return log_msg_ret("rec", ret); + return log_msg_ret("wp", ret); ret = chromeos_get_gpio(dev, "phase-enforce-gpios", CROS_GPIO_PE, &info[2]); if (ret) - return log_msg_ret("rec", ret); + return log_msg_ret("phase", ret); acpigen_write_scope(ctx, "\"); acpigen_write_name(ctx, "OIPG"); acpigen_write_package(ctx, count); @@ -145,6 +267,7 @@ struct acpi_ops coral_acpi_ops = { };
struct sysinfo_ops coral_sysinfo_ops = { + .get_str = coral_get_str, };
#if !CONFIG_IS_ENABLED(OF_PLATDATA) diff --git a/board/google/chromebook_coral/variant_gpio.h b/board/google/chromebook_coral/variant_gpio.h index f516d88be5c..403e2419a71 100644 --- a/board/google/chromebook_coral/variant_gpio.h +++ b/board/google/chromebook_coral/variant_gpio.h @@ -34,12 +34,6 @@ /* Determine if board is in final shipping mode. */ #define GPIO_SHIP_MODE GPIO_10
-/* Memory SKU GPIOs. */ -#define MEM_CONFIG3 GPIO_45 -#define MEM_CONFIG2 GPIO_38 -#define MEM_CONFIG1 GPIO_102 -#define MEM_CONFIG0 GPIO_101 - /* DMIC_CONFIG_PIN: High for 1-DMIC and low for 4-DMIC's */ #define DMIC_CONFIG_PIN GPIO_17
diff --git a/doc/device-tree-bindings/sysinfo/google,coral.txt b/doc/device-tree-bindings/sysinfo/google,coral.txt new file mode 100644 index 00000000000..d8a1a79687e --- /dev/null +++ b/doc/device-tree-bindings/sysinfo/google,coral.txt @@ -0,0 +1,37 @@ +Google Coral sysinfo information +================================ + +This binding allows information about the board to be described. It includes +the SMBIOS binding as well. + +Required properties: + + - compatible: "google,coral" + - recovery-gpios: GPIO to use for recovery button (-1 if none) + - wite-protect-gpios: GPIO to use for write-protect screw + - phase-enforce-gpios: GPIO to indicate the board is in final ship mode + - memconfig-gpios: 4 GPIOs to use to read memory config (as base2 int) + +Optional properties: + - skuconfig-gpios: 2 GPIOs to use to read SKU ID. If not present, the + Chromium OS EC SKU_ID is used instead + +Example: + +board: board { + compatible = "google,coral"; + recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>; + write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>; + phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>; + memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH + &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH + &gpio_n GPIO_38 GPIO_ACTIVE_HIGH + &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>; + + /* + * This is used for reef only: + * + * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH + * &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>; + */ + };

Hi Simon,
On Mon, Jan 25, 2021 at 1:06 AM Simon Glass sjg@chromium.org wrote:
This series provides a few improvements for loading of images. It also provides a way to show more detailed model information as well as an of-platdata fix noticed recently.
Changes in v2:
- Add comment to .lds file
- Add more notes to the commit
- Fix two missing asterisks in comments
Simon Glass (12): x86: acpi_gpe: Update driver name to match devicetree x86: spl: Add a function to find the text base x86: apl: Enhance debugging in the SPL loader x86: Make sure the SPL image ends on a suitable boundary x86: spl: Make moving BSS conditional x86: Update Chromium OS GNVS names x86: zimage: Allow dumping the image from outside the module x86: zimage: Improve command-line debug handling x86: spl: Clear BSS unconditionally x86: tpl: Show next stage being booted sysinfo: Allow showing model info from sysinfo x86: coral: Show memory config and SKU ID on startup
Patch 1-10 was applied to u-boot-x86. Patch 11-12 do not apply. Please rebase. Thanks!
Regards, Bin
participants (2)
-
Bin Meng
-
Simon Glass