[PATCH v3 00/16] x86: Various minor enhancements for coreboot

This series includes some patches generated while getting U-Boot to boot more nicely on Brya, an Adler Lake Chromebook.
This includes: - show the ACPI tables with 'acpi list' - get the UART to work even if coreboot doesn't enable it - show unimplemented sysinfo tags - fix for keyboard not working - fix for trying to set up PCI regions when the info is not available - fix for looking at inaccessible memory to find the sysinfo table
Changes in v3: - Don't enable ACPI by default except on x86 and sandbox - Avoid a build error with the ASL compiler - Disable for coreboot64 since ACPI is not available
Changes in v2: - Don't show an invalid CPU number on error - Update commit message with more detail - Update code comment to mention that addresses <1KB are ignored - Flush the buffer instead of skipping the reset - Add new patch to create a new Kconfig for ACPI - Add new patch to move acpi-table-finding functions into the library - Use tab instead of space in header file - Refactor two patches into one - Add new patch to allow locating the UART from ACPI tables - Expand commit message to explain this is for the debug UART - Update the defconfig instead - Drop patch 'usb: Quieten a debug message' since it was fixed elsewhere - Drop patch 'x86: coreboot: Use a memory-mapped UART' (not needed) - Add new patch to enable ms command - Move this patch to last in the series, so it can be dropped if needed
Simon Glass (16): mtrr: Don't show an invalid CPU number x86: Adjust search range for sysinfo table input: Flush the keyboard buffer before resetting it acpi: Create a new Kconfig for ACPI acpi: Move the table-finding functions into the libary x86: coreboot: Collect the address of the ACPI tables x86: Allow locating the UART from ACPI tables pci: coreboot: Don't read regions when booting x86: coreboot: Use a memory-mapped UART x86: coreboot: Document how to enable the debug UART x86: coreboot: Scan PCI after relocation x86: coreboot: Log function names and line numbers x86: coreboot: Show unimplemented sysinfo tags x86: nvme: coreboot: Enable NVMe coreboot: Enable ms command x86: Allow locating UARTs by device ID
arch/Kconfig | 2 + arch/x86/cpu/cpu.c | 4 +- arch/x86/dts/coreboot.dts | 4 + arch/x86/include/asm/cb_sysinfo.h | 8 ++ arch/x86/include/asm/coreboot_tables.h | 2 + arch/x86/lib/coreboot/cb_sysinfo.c | 13 +++ cmd/Kconfig | 2 +- cmd/acpi.c | 44 +------ cmd/x86/cbsysinfo.c | 9 ++ cmd/x86/mtrr.c | 6 +- configs/coreboot64_defconfig | 1 - configs/coreboot_defconfig | 10 +- doc/board/coreboot/coreboot.rst | 29 +++++ drivers/core/Kconfig | 1 + drivers/input/i8042.c | 19 +++ drivers/nvme/nvme_pci.c | 8 ++ drivers/pci/pci-uclass.c | 4 + drivers/serial/Kconfig | 10 ++ drivers/serial/serial_coreboot.c | 155 +++++++++++++++++++++++-- include/acpi/acpi_table.h | 8 ++ include/asm-generic/global_data.h | 4 +- include/pci_ids.h | 3 + lib/Kconfig | 10 +- lib/Makefile | 2 +- lib/acpi/Makefile | 6 + lib/acpi/acpi.c | 45 +++++++ 26 files changed, 351 insertions(+), 58 deletions(-) create mode 100644 lib/acpi/acpi.c

When U-Boot did not do the MP init, we don't get an actual CPU number here. Skip printing it in that case.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Don't show an invalid CPU number on error
cmd/x86/mtrr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c index b213a942fde4..ff4be6b7bf5b 100644 --- a/cmd/x86/mtrr.c +++ b/cmd/x86/mtrr.c @@ -145,10 +145,12 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc, for (; i >= 0; i = mp_next_cpu(cpu_select, i)) { if (!first) printf("\n"); - printf("CPU %d:\n", i); + if (i < MP_SELECT_ALL) + printf("CPU %d:\n", i); ret = do_mtrr_list(reg_count, i); if (ret) { - printf("Failed to read CPU %d (err=%d)\n", i, + printf("Failed to read CPU %s (err=%d)\n", + i < MP_SELECT_ALL ? simple_itoa(i) : "", ret); return CMD_RET_FAILURE; }

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
When U-Boot did not do the MP init, we don't get an actual CPU number here. Skip printing it in that case.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Don't show an invalid CPU number on error
cmd/x86/mtrr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

Avoid searching starting at 0 since this memory may not be available, e.g. if protection against NULL-pointer access is enabled. The table cannot be there anyway, since the first 1KB of memory was originally used for the interrupt table and coreboot avoids it.
Start at 0x400 instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Update commit message with more detail - Update code comment to mention that addresses <1KB are ignored
arch/x86/cpu/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 6fe6eaf6c84e..dddd281e966c 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -351,8 +351,8 @@ long locate_coreboot_table(void) { long addr;
- /* We look for LBIO in the first 4K of RAM and again at 960KB */ - addr = detect_coreboot_table_at(0x0, 0x1000); + /* We look for LBIO from addresses 1K-4K and again at 960KB */ + addr = detect_coreboot_table_at(0x400, 0xc00); if (addr < 0) addr = detect_coreboot_table_at(0xf0000, 0x1000);

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
Avoid searching starting at 0 since this memory may not be available, e.g. if protection against NULL-pointer access is enabled. The table cannot be there anyway, since the first 1KB of memory was originally used for the interrupt table and coreboot avoids it.
Start at 0x400 instead.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Update commit message with more detail
- Update code comment to mention that addresses <1KB are ignored
arch/x86/cpu/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

If U-Boot is not the first-stage bootloader the keyboard may already be set up. Make sure to flush any data before trying to reset it. This avoids a long timeout / hang.
Add some comments and a log category while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Flush the buffer instead of skipping the reset
drivers/input/i8042.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 3563dc98838f..e6070ca01529 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -6,6 +6,8 @@
/* i8042.c - Intel 8042 keyboard driver routines */
+#define LOG_CATEGORY UCLASS_KEYBOARD + #include <common.h> #include <dm.h> #include <env.h> @@ -54,6 +56,14 @@ static unsigned char ext_key_map[] = { 0x00 /* map end */ };
+/** + * kbd_input_empty() - Wait until the keyboard is ready for a command + * + * Checks the IBF flag (input buffer full), waiting for it to indicate that + * any previous command has been processed. + * + * Return: true if ready, false if it timed out + */ static int kbd_input_empty(void) { int kbd_timeout = KBD_TIMEOUT * 1000; @@ -64,6 +74,12 @@ static int kbd_input_empty(void) return kbd_timeout != -1; }
+/** + * kbd_output_full() - Wait until the keyboard has data available + * + * Checks the OBF flag (output buffer full), waiting for it to indicate that + * a response to a previous command is available + */ static int kbd_output_full(void) { int kbd_timeout = KBD_TIMEOUT * 1000; @@ -127,6 +143,9 @@ static int kbd_reset(int quirk) { int config;
+ if (!kbd_input_empty()) + goto err; + /* controller self test */ if (kbd_cmd_read(CMD_SELF_TEST) != KBC_TEST_OK) goto err;

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
If U-Boot is not the first-stage bootloader the keyboard may already be set up. Make sure to flush any data before trying to reset it. This avoids a long timeout / hang.
Add some comments and a log category while we are here.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Flush the buffer instead of skipping the reset
drivers/input/i8042.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

We have several Kconfig options for ACPI, but all relate to specific functions, such as generating tables and AML code.
Add a new option which controls including basic ACPI library code, including the lib/acpi directory. This will allow us to add functions which are available even if table generation is not supported.
Adjust the command to avoid a build error when ACPIGEN is not enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Don't enable ACPI by default except on x86 and sandbox
Changes in v2: - Add new patch to create a new Kconfig for ACPI
arch/Kconfig | 2 ++ cmd/Kconfig | 2 +- cmd/acpi.c | 4 ++++ drivers/core/Kconfig | 1 + lib/Kconfig | 10 +++++++++- lib/Makefile | 2 +- lib/acpi/Makefile | 4 ++++ 7 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index d30676ae817b..e4831aeaa075 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -194,6 +194,7 @@ config SANDBOX imply PHYLIB imply DM_MDIO imply DM_MDIO_MUX + imply ACPI imply ACPI_PMC imply ACPI_PMC_SANDBOX imply CMD_PMC @@ -260,6 +261,7 @@ config X86 imply PCH imply PHYSMEM imply RTC_MC146818 + imply ACPI imply ACPIGEN if !QEMU && !EFI_APP imply SYSINFO if GENERATE_SMBIOS_TABLE imply SYSINFO_SMBIOS if GENERATE_SMBIOS_TABLE diff --git a/cmd/Kconfig b/cmd/Kconfig index ba5ec69293fd..1bffbe2e2ba0 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -109,7 +109,7 @@ menu "Info commands"
config CMD_ACPI bool "acpi" - depends on ACPIGEN + depends on ACPI default y help List and dump ACPI tables. ACPI (Advanced Configuration and Power diff --git a/cmd/acpi.c b/cmd/acpi.c index d0fc062ef8cb..991b5235e289 100644 --- a/cmd/acpi.c +++ b/cmd/acpi.c @@ -162,6 +162,10 @@ static int do_acpi_items(struct cmd_tbl *cmdtp, int flag, int argc, bool dump_contents;
dump_contents = argc >= 2 && !strcmp("-d", argv[1]); + if (!IS_ENABLED(CONFIG_ACPIGEN)) { + printf("Not supported (enable ACPIGEN)\n"); + return CMD_RET_FAILURE; + } acpi_dump_items(dump_contents ? ACPI_DUMP_CONTENTS : ACPI_DUMP_LIST);
return 0; diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 0f755aa702ee..f0d848f45d8e 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -448,6 +448,7 @@ config OFNODE_MULTI_TREE_MAX
config ACPIGEN bool "Support ACPI table generation in driver model" + depends on ACPI default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU) select LIB_UUID help diff --git a/lib/Kconfig b/lib/Kconfig index 4278b2405546..475797d9b391 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -281,9 +281,17 @@ config SUPPORT_ACPI U-Boot can generate these tables and pass them to the Operating System.
+config ACPI + bool "Enable support for ACPI libraries" + depends on SUPPORT_ACPI + help + Provides library functions for dealing with ACPI tables. This does + not necessarily include generation of tables + (see GENERATE_ACPI_TABLE), but allows for tables to be located. + config GENERATE_ACPI_TABLE bool "Generate an ACPI (Advanced Configuration and Power Interface) table" - depends on SUPPORT_ACPI + depends on ACPI select QFW if QEMU help The Advanced Configuration and Power Interface (ACPI) specification diff --git a/lib/Makefile b/lib/Makefile index 10aa7ac02985..8d8ccc8bbc39 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -66,7 +66,7 @@ obj-$(CONFIG_$(SPL_TPL_)CRC8) += crc8.o
obj-y += crypto/
-obj-$(CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE) += acpi/ +obj-$(CONFIG_$(SPL_TPL_)ACPI) += acpi/ obj-$(CONFIG_$(SPL_)MD5) += md5.o obj-$(CONFIG_ECDSA) += ecdsa/ obj-$(CONFIG_$(SPL_)RSA) += rsa/ diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 956b5a0d7265..12337abaecfa 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0+ #
+ifdef CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE + obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o @@ -21,3 +23,5 @@ endif obj-y += facs.o obj-y += ssdt.o endif + +endif # GENERATE_ACPI_TABLE

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
We have several Kconfig options for ACPI, but all relate to specific functions, such as generating tables and AML code.
Add a new option which controls including basic ACPI library code, including the lib/acpi directory. This will allow us to add functions which are available even if table generation is not supported.
Adjust the command to avoid a build error when ACPIGEN is not enabled.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Don't enable ACPI by default except on x86 and sandbox
Changes in v2:
- Add new patch to create a new Kconfig for ACPI
arch/Kconfig | 2 ++ cmd/Kconfig | 2 +- cmd/acpi.c | 4 ++++ drivers/core/Kconfig | 1 + lib/Kconfig | 10 +++++++++- lib/Makefile | 2 +- lib/acpi/Makefile | 4 ++++ 7 files changed, 22 insertions(+), 3 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

This is useful for other features. Move the function into library code so it can be used outside just the 'acpi' command.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Avoid a build error with the ASL compiler
Changes in v2: - Add new patch to move acpi-table-finding functions into the library
cmd/acpi.c | 40 +--------------------------------- include/acpi/acpi_table.h | 8 +++++++ lib/acpi/Makefile | 2 ++ lib/acpi/acpi.c | 45 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 lib/acpi/acpi.c
diff --git a/cmd/acpi.c b/cmd/acpi.c index 991b5235e289..e70913e40bfe 100644 --- a/cmd/acpi.c +++ b/cmd/acpi.c @@ -36,49 +36,11 @@ static void dump_hdr(struct acpi_table_header *hdr) } }
-/** - * find_table() - Look up an ACPI table - * - * @sig: Signature of table (4 characters, upper case) - * Return: pointer to table header, or NULL if not found - */ -struct acpi_table_header *find_table(const char *sig) -{ - struct acpi_rsdp *rsdp; - struct acpi_rsdt *rsdt; - int len, i, count; - - rsdp = map_sysmem(gd_acpi_start(), 0); - if (!rsdp) - return NULL; - rsdt = map_sysmem(rsdp->rsdt_address, 0); - len = rsdt->header.length - sizeof(rsdt->header); - count = len / sizeof(u32); - for (i = 0; i < count; i++) { - struct acpi_table_header *hdr; - - hdr = map_sysmem(rsdt->entry[i], 0); - if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN)) - return hdr; - if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) { - struct acpi_fadt *fadt = (struct acpi_fadt *)hdr; - - if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt) - return map_sysmem(fadt->dsdt, 0); - if (!memcmp(sig, "FACS", ACPI_NAME_LEN) && - fadt->firmware_ctrl) - return map_sysmem(fadt->firmware_ctrl, 0); - } - } - - return NULL; -} - static int dump_table_name(const char *sig) { struct acpi_table_header *hdr;
- hdr = find_table(sig); + hdr = acpi_find_table(sig); if (!hdr) return -ENOENT; printf("%.*s @ %08lx\n", ACPI_NAME_LEN, hdr->signature, diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 4030d25c66a0..7ed0443c821a 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -923,6 +923,14 @@ int acpi_fill_csrt(struct acpi_ctx *ctx); */ ulong write_acpi_tables(ulong start);
+/** + * acpi_find_table() - Look up an ACPI table + * + * @sig: Signature of table (4 characters, upper case) + * Return: pointer to table header, or NULL if not found + */ +struct acpi_table_header *acpi_find_table(const char *sig); + #endif /* !__ACPI__*/
#include <asm/acpi_table.h> diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 12337abaecfa..c1c9675b5d2a 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0+ #
+obj-y += acpi.o + ifdef CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c new file mode 100644 index 000000000000..14b15754f492 --- /dev/null +++ b/lib/acpi/acpi.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Utility functions for ACPI + * + * Copyright 2023 Google LLC + */ + +#include <common.h> +#include <mapmem.h> +#include <acpi/acpi_table.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct acpi_table_header *acpi_find_table(const char *sig) +{ + struct acpi_rsdp *rsdp; + struct acpi_rsdt *rsdt; + int len, i, count; + + rsdp = map_sysmem(gd_acpi_start(), 0); + if (!rsdp) + return NULL; + rsdt = map_sysmem(rsdp->rsdt_address, 0); + len = rsdt->header.length - sizeof(rsdt->header); + count = len / sizeof(u32); + for (i = 0; i < count; i++) { + struct acpi_table_header *hdr; + + hdr = map_sysmem(rsdt->entry[i], 0); + if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN)) + return hdr; + if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) { + struct acpi_fadt *fadt = (struct acpi_fadt *)hdr; + + if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt) + return map_sysmem(fadt->dsdt, 0); + if (!memcmp(sig, "FACS", ACPI_NAME_LEN) && + fadt->firmware_ctrl) + return map_sysmem(fadt->firmware_ctrl, 0); + } + } + + return NULL; +}

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
This is useful for other features. Move the function into library code so it can be used outside just the 'acpi' command.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Avoid a build error with the ASL compiler
Changes in v2:
- Add new patch to move acpi-table-finding functions into the library
cmd/acpi.c | 40 +--------------------------------- include/acpi/acpi_table.h | 8 +++++++ lib/acpi/Makefile | 2 ++ lib/acpi/acpi.c | 45 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 lib/acpi/acpi.c
Reviewed-by: Bin Meng bmeng.cn@gmail.com

At present any ACPI tables created by prior-stage firmware are ignored. It is useful to be able to view these in U-Boot.
Pick this up from the sysinfo tables and display it with the cbsysinfo command. This allows the 'acpi list' command to work when booting from coreboot.
Adjust the global_data condition so that acpi_start is available even if table-generation is disabled.
Signed-off-by: Simon Glass sjg@chromium.org
---
(no changes since v2)
Changes in v2: - Use tab instead of space in header file - Refactor two patches into one
arch/x86/include/asm/cb_sysinfo.h | 2 ++ arch/x86/include/asm/coreboot_tables.h | 2 ++ arch/x86/lib/coreboot/cb_sysinfo.c | 11 +++++++++++ cmd/x86/cbsysinfo.c | 1 + include/asm-generic/global_data.h | 4 ++-- 5 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/cb_sysinfo.h b/arch/x86/include/asm/cb_sysinfo.h index 0201ac6b03a9..6b266149cf65 100644 --- a/arch/x86/include/asm/cb_sysinfo.h +++ b/arch/x86/include/asm/cb_sysinfo.h @@ -133,6 +133,7 @@ * @mtc_size: Size of MTC region * @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning * not used + * @rsdp: Pointer to ACPI RSDP table */ struct sysinfo_t { unsigned int cpu_khz; @@ -211,6 +212,7 @@ struct sysinfo_t { u64 mtc_start; u32 mtc_size; void *chromeos_vpd; + void *rsdp; };
extern struct sysinfo_t lib_sysinfo; diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h index f131de56a405..4de137fbab9d 100644 --- a/arch/x86/include/asm/coreboot_tables.h +++ b/arch/x86/include/asm/coreboot_tables.h @@ -422,6 +422,8 @@ struct cb_tsc_info { #define CB_TAG_SERIALNO 0x002a #define CB_MAX_SERIALNO_LENGTH 32
+#define CB_TAG_ACPI_RSDP 0x0043 + #define CB_TAG_CMOS_OPTION_TABLE 0x00c8
struct cb_cmos_option_table { diff --git a/arch/x86/lib/coreboot/cb_sysinfo.c b/arch/x86/lib/coreboot/cb_sysinfo.c index 748fa4ee53bb..a11a2587f66b 100644 --- a/arch/x86/lib/coreboot/cb_sysinfo.c +++ b/arch/x86/lib/coreboot/cb_sysinfo.c @@ -264,6 +264,13 @@ static void cb_parse_mrc_cache(void *ptr, struct sysinfo_t *info) info->mrc_cache = map_sysmem(cbmem->cbmem_tab, 0); }
+static void cb_parse_acpi_rsdp(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr; + + info->rsdp = map_sysmem(cbmem->cbmem_tab, 0); +} + __weak void cb_parse_unhandled(u32 tag, unsigned char *ptr) { } @@ -428,6 +435,9 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_MRC_CACHE: cb_parse_mrc_cache(rec, info); break; + case CB_TAG_ACPI_RSDP: + cb_parse_acpi_rsdp(rec, info); + break; default: cb_parse_unhandled(rec->tag, ptr); break; @@ -454,6 +464,7 @@ int get_coreboot_info(struct sysinfo_t *info) if (!ret) return -ENOENT; gd->arch.coreboot_table = addr; + gd_set_acpi_start(map_to_sysmem(info->rsdp)); gd->flags |= GD_FLG_SKIP_LL_INIT;
return 0; diff --git a/cmd/x86/cbsysinfo.c b/cmd/x86/cbsysinfo.c index 34fdaf5b1b1c..07570b00c9a0 100644 --- a/cmd/x86/cbsysinfo.c +++ b/cmd/x86/cbsysinfo.c @@ -363,6 +363,7 @@ static void show_table(struct sysinfo_t *info, bool verbose) print_hex("MTC size", info->mtc_size);
print_ptr("Chrome OS VPD", info->chromeos_vpd); + print_ptr("RSDP", info->rsdp); }
static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 987fb66c17a3..422e0cf4720f 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -457,7 +457,7 @@ struct global_data { */ fdt_addr_t translation_offset; #endif -#ifdef CONFIG_GENERATE_ACPI_TABLE +#ifdef CONFIG_ACPI /** * @acpi_ctx: ACPI context pointer */ @@ -536,7 +536,7 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #define gd_dm_priv_base() NULL #endif
-#ifdef CONFIG_GENERATE_ACPI_TABLE +#ifdef CONFIG_ACPI #define gd_acpi_ctx() gd->acpi_ctx #define gd_acpi_start() gd->acpi_start #define gd_set_acpi_start(addr) gd->acpi_start = addr

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
At present any ACPI tables created by prior-stage firmware are ignored. It is useful to be able to view these in U-Boot.
Pick this up from the sysinfo tables and display it with the cbsysinfo command. This allows the 'acpi list' command to work when booting from coreboot.
Adjust the global_data condition so that acpi_start is available even if table-generation is disabled.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Use tab instead of space in header file
- Refactor two patches into one
arch/x86/include/asm/cb_sysinfo.h | 2 ++ arch/x86/include/asm/coreboot_tables.h | 2 ++ arch/x86/lib/coreboot/cb_sysinfo.c | 11 +++++++++++ cmd/x86/cbsysinfo.c | 1 + include/asm-generic/global_data.h | 4 ++-- 5 files changed, 18 insertions(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

When coreboot does not pass a UART in its sysinfo struct, there is no easy way to find it out.
Since coreboot does not actually init the serial device when serial is disabled, it is not possible to make it add this information to the sysinfo table.
Add a way to obtain this information from the DBG2 ACPI table, which is normally set up by coreboot.
For now this only supports a memory-mapped 16550-style UART.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Disable for coreboot64 since ACPI is not available
Changes in v2: - Add new patch to allow locating the UART from ACPI tables
drivers/serial/Kconfig | 10 +++ drivers/serial/serial_coreboot.c | 114 ++++++++++++++++++++++++++++--- 2 files changed, 116 insertions(+), 8 deletions(-)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 10d07daf2777..08f6559c1579 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -669,6 +669,16 @@ config COREBOOT_SERIAL a serial console on any platform without needing to change the device tree, etc.
+config COREBOOT_SERIAL_FROM_DBG2 + bool "Obtain UART from ACPI tables" + depends on COREBOOT_SERIAL + default y if !SPL + help + Select this to try to find a DBG2 record in the ACPI tables, in the + event that coreboot does not provide information about the UART in the + normal sysinfo tables. This provides a useful fallback when serial + is not enabled in coreboot. + config CORTINA_UART bool "Cortina UART support" depends on DM_SERIAL diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c index de09c8681f5c..23066e4d0543 100644 --- a/drivers/serial/serial_coreboot.c +++ b/drivers/serial/serial_coreboot.c @@ -5,25 +5,123 @@ * Copyright 2019 Google LLC */
+#define LOG_CATGEGORY UCLASS_SERIAL + #include <common.h> #include <dm.h> +#include <log.h> #include <ns16550.h> #include <serial.h> +#include <acpi/acpi_table.h> #include <asm/cb_sysinfo.h>
+DECLARE_GLOBAL_DATA_PTR; + +static int read_dbg2(struct ns16550_plat *plat) +{ + struct acpi_table_header *tab; + struct acpi_dbg2_header *hdr; + struct acpi_dbg2_device *dbg; + struct acpi_gen_regaddr *addr; + u32 *addr_size; + + log_debug("Looking for DBG2 in ACPI tables\n"); + if (!gd->acpi_start) { + log_debug("No ACPI tables\n"); + return -ENOENT; + } + + tab = acpi_find_table("DBG2"); + if (!tab) { + log_debug("No DBG2 table\n"); + return -ENOENT; + } + hdr = container_of(tab, struct acpi_dbg2_header, header); + + /* We only use the first device, but check that there is at least one */ + if (!hdr->devices_count) { + log_debug("No devices\n"); + return -ENOENT; + } + if (hdr->devices_offset >= tab->length) { + log_debug("Invalid offset\n"); + return -EINVAL; + } + dbg = (void *)hdr + hdr->devices_offset; + if (dbg->revision) { + log_debug("Invalid revision %d\n", dbg->revision); + return -EINVAL; + } + if (!dbg->address_count) { + log_debug("No addresses\n"); + return -EINVAL; + } + if (dbg->port_type != ACPI_DBG2_SERIAL_PORT) { + log_debug("Not a serial port\n"); + return -EPROTOTYPE; + } + if (dbg->port_subtype != ACPI_DBG2_16550_COMPATIBLE) { + log_debug("Incompatible serial port\n"); + return -EPROTOTYPE; + } + if (dbg->base_address_offset >= dbg->length || + dbg->address_size_offset >= dbg->length) { + log_debug("Invalid base address/size offsets %d, %d\n", + dbg->base_address_offset, dbg->address_size_offset); + return -EINVAL; + } + addr_size = (void *)dbg + dbg->address_size_offset; + if (!*addr_size) { + log_debug("Zero address size\n"); + return -EINVAL; + } + addr = (void *)dbg + dbg->base_address_offset; + if (addr->space_id != ACPI_ADDRESS_SPACE_MEMORY) { + log_debug("Incompatible space %d\n", addr->space_id); + return -EPROTOTYPE; + } + + plat->base = addr->addrl; + + /* ACPI_ACCESS_SIZE_DWORD_ACCESS is 3; we want 2 */ + plat->reg_shift = addr->access_size - 1; + plat->reg_width = 4; /* coreboot sets bit_width to 0 */ + plat->clock = 1843200; + plat->fcr = UART_FCR_DEFVAL; + plat->flags = 0; + log_debug("Collected UART from ACPI DBG2 table\n"); + + return 0; +} + static int coreboot_of_to_plat(struct udevice *dev) { struct ns16550_plat *plat = dev_get_plat(dev); struct cb_serial *cb_info = lib_sysinfo.serial; + int ret = -ENOENT;
- plat->base = cb_info->baseaddr; - plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0; - plat->reg_width = cb_info->regwidth; - plat->clock = cb_info->input_hertz; - plat->fcr = UART_FCR_DEFVAL; - plat->flags = 0; - if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED) - plat->flags |= NS16550_FLAG_IO; + if (cb_info) { + plat->base = cb_info->baseaddr; + plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0; + plat->reg_width = cb_info->regwidth; + plat->clock = cb_info->input_hertz; + plat->fcr = UART_FCR_DEFVAL; + plat->flags = 0; + if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED) + plat->flags |= NS16550_FLAG_IO; + ret = 0; + } else if (IS_ENABLED(CONFIG_COREBOOT_SERIAL_FROM_DBG2)) { + ret = read_dbg2(plat); + } + + if (ret) { + /* + * Returning an error will cause U-Boot to complain that + * there is no UART, which may panic. So stay silent and + * pray that the video console will work. + */ + log_debug("Cannot detect UART\n"); + }
return 0; }

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
When coreboot does not pass a UART in its sysinfo struct, there is no easy way to find it out.
Since coreboot does not actually init the serial device when serial is disabled, it is not possible to make it add this information to the sysinfo table.
Add a way to obtain this information from the DBG2 ACPI table, which is normally set up by coreboot.
For now this only supports a memory-mapped 16550-style UART.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Disable for coreboot64 since ACPI is not available
Changes in v2:
- Add new patch to allow locating the UART from ACPI tables
drivers/serial/Kconfig | 10 +++ drivers/serial/serial_coreboot.c | 114 ++++++++++++++++++++++++++++--- 2 files changed, 116 insertions(+), 8 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

When U-Boot is the second-stage bootloader, PCI is already set up. We cannot read the regions from the device tree. There is no point anyway, since PCI devices have already been allocated according to the regions and it is not safe for U-Boot to make any changes.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
drivers/pci/pci-uclass.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 9343cfc62a96..8d27e40338cf 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -973,6 +973,10 @@ static int decode_regions(struct pci_controller *hose, ofnode parent_node, int len; int i;
+ /* handle booting from coreboot, etc. */ + if (!ll_boot_init()) + return 0; + prop = ofnode_get_property(node, "ranges", &len); if (!prop) { debug("%s: Cannot decode regions\n", __func__);

When U-Boot is the second-stage bootloader, PCI is already set up. We cannot read the regions from the device tree. There is no point anyway, since PCI devices have already been allocated according to the regions and it is not safe for U-Boot to make any changes.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested-by: Christian Gmeiner christian.gmeiner@gmail.com
This fixes a regression that got introduced with f2ebaaa9f3 ("pci: Handle failed calloc in decode_regions()")
For more details see: https://lore.kernel.org/all/20220519164830.3934669-1-ptosi@google.com/T/#m9f...

On Sun, Apr 2, 2023 at 6:52 PM Christian Gmeiner christian.gmeiner@gmail.com wrote:
When U-Boot is the second-stage bootloader, PCI is already set up. We cannot read the regions from the device tree. There is no point anyway, since PCI devices have already been allocated according to the regions and it is not safe for U-Boot to make any changes.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested-by: Christian Gmeiner christian.gmeiner@gmail.com
This fixes a regression that got introduced with f2ebaaa9f3 ("pci: Handle failed calloc in decode_regions()")
For more details see: https://lore.kernel.org/all/20220519164830.3934669-1-ptosi@google.com/T/#m9f...
Fixes: f2ebaaa9f38d ("pci: Handle failed calloc in decode_regions()")

This is much more common on modern hardware, so default to using it.
This does not affect the normal UART, but does allow the debug UART to work, since it uses serial_out_shift(), etc.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Expand commit message to explain this is for the debug UART - Update the defconfig instead
configs/coreboot64_defconfig | 1 - configs/coreboot_defconfig | 1 - 2 files changed, 2 deletions(-)
diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig index ec672e59e898..60a1924e9e53 100644 --- a/configs/coreboot64_defconfig +++ b/configs/coreboot64_defconfig @@ -62,7 +62,6 @@ CONFIG_ATAPI=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y # CONFIG_PCI_PNP is not set -CONFIG_SYS_NS16550_PORT_MAPPED=y CONFIG_SOUND=y CONFIG_SOUND_I8254=y CONFIG_CONSOLE_SCROLL_LINES=5 diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 4db728991692..fb4d1751108f 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -56,7 +56,6 @@ CONFIG_ATAPI=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y # CONFIG_PCI_PNP is not set -CONFIG_SYS_NS16550_PORT_MAPPED=y CONFIG_SOUND=y CONFIG_SOUND_I8254=y CONFIG_CONSOLE_SCROLL_LINES=5

On Mon, Mar 27, 2023 at 12:16 PM Simon Glass sjg@chromium.org wrote:
This is much more common on modern hardware, so default to using it.
This does not affect the normal UART, but does allow the debug UART to work, since it uses serial_out_shift(), etc.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Expand commit message to explain this is for the debug UART
- Update the defconfig instead
configs/coreboot64_defconfig | 1 - configs/coreboot_defconfig | 1 - 2 files changed, 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

This is not obvious so add a little note about how it works.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
doc/board/coreboot/coreboot.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/doc/board/coreboot/coreboot.rst b/doc/board/coreboot/coreboot.rst index 4a5f101cad2e..0fe95af56d2d 100644 --- a/doc/board/coreboot/coreboot.rst +++ b/doc/board/coreboot/coreboot.rst @@ -71,3 +71,32 @@ Memory map (typically redirects to 7ab10030 or similar) 500 Location of coreboot sysinfo table, used during startup ========== ================================================================== + + +Debug UART +---------- + +It is possible to enable the debug UART with coreboot. To do this, use the +info from the cbsysinfo command to locate the UART base. For example:: + + => cbsysinfo + ... + Serial I/O port: 00000000 + base : 00000000 + pointer : 767b51bc + type : 2 + base : fe03e000 + baud : 0d115200 + regwidth : 4 + input_hz : 0d1843200 + PCI addr : 00000010 + ... + +Here you can see that the UART base is fe03e000, regwidth is 4 (1 << 2) and the +input clock is 1843200. So you can add the following CONFIG options:: + + CONFIG_DEBUG_UART=y + CONFIG_DEBUG_UART_BASE=fe03e000 + CONFIG_DEBUG_UART_CLOCK=1843200 + CONFIG_DEBUG_UART_SHIFT=2 + CONFIG_DEBUG_UART_ANNOUNCE=y

Enable this so that PCI devices can be used correctly without needing to do a manual scan.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index fb4d1751108f..1bbb358a0220 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -18,6 +18,7 @@ CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_LAST_STAGE_INIT=y +CONFIG_PCI_INIT_R=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=532 CONFIG_CMD_IDE=y

Turn these options on to make it easier to debug things.
Also enable dhrystone so we can get some measure of performance.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
configs/coreboot_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 1bbb358a0220..3030e5bf93b4 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -16,6 +16,9 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000" CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_LOG=y +CONFIG_LOGF_LINE=y +CONFIG_LOGF_FUNC=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_LAST_STAGE_INIT=y CONFIG_PCI_INIT_R=y @@ -60,5 +63,6 @@ CONFIG_SYS_64BIT_LBA=y CONFIG_SOUND=y CONFIG_SOUND_I8254=y CONFIG_CONSOLE_SCROLL_LINES=5 +CONFIG_CMD_DHRYSTONE=y # CONFIG_GZIP is not set CONFIG_SMBIOS_PARSER=y

Sometimes coreboot adds new tags that U-Boot does not know about. These are silently ignored, but it is useful to at least know what we are missing.
Add a way to collect this information. For Brya it shows:
Unimpl. 38 41 37 34 42 40
These are:
LB_TAG_PLATFORM_BLOB_VERSION LB_TAG_ACPI_CNVS LB_TAG_FMAP LB_TAG_VBOOT_WORKBUF LB_TAG_TYPE_C_INFO LB_TAG_BOARD_CONFIG
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
(no changes since v1)
arch/x86/include/asm/cb_sysinfo.h | 6 ++++++ arch/x86/lib/coreboot/cb_sysinfo.c | 2 ++ cmd/x86/cbsysinfo.c | 8 ++++++++ 3 files changed, 16 insertions(+)
diff --git a/arch/x86/include/asm/cb_sysinfo.h b/arch/x86/include/asm/cb_sysinfo.h index 6b266149cf65..2c78b22d0d22 100644 --- a/arch/x86/include/asm/cb_sysinfo.h +++ b/arch/x86/include/asm/cb_sysinfo.h @@ -16,6 +16,8 @@ #define SYSINFO_MAX_GPIOS 8 /* Up to 10 MAC addresses */ #define SYSINFO_MAX_MACS 10 +/* Track the first 32 unimplemented tags */ +#define SYSINFO_MAX_UNIMPL 32
/** * struct sysinfo_t - Information passed to U-Boot from coreboot @@ -134,6 +136,8 @@ * @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning * not used * @rsdp: Pointer to ACPI RSDP table + * @unimpl_count: Number of entries in unimpl_map[] + * @unimpl: List of unimplemented IDs (bottom 8 bits only) */ struct sysinfo_t { unsigned int cpu_khz; @@ -213,6 +217,8 @@ struct sysinfo_t { u32 mtc_size; void *chromeos_vpd; void *rsdp; + u32 unimpl_count; + u8 unimpl[SYSINFO_MAX_UNIMPL]; };
extern struct sysinfo_t lib_sysinfo; diff --git a/arch/x86/lib/coreboot/cb_sysinfo.c b/arch/x86/lib/coreboot/cb_sysinfo.c index a11a2587f66b..42cc3a128d93 100644 --- a/arch/x86/lib/coreboot/cb_sysinfo.c +++ b/arch/x86/lib/coreboot/cb_sysinfo.c @@ -439,6 +439,8 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) cb_parse_acpi_rsdp(rec, info); break; default: + if (info->unimpl_count < SYSINFO_MAX_UNIMPL) + info->unimpl[info->unimpl_count++] = rec->tag; cb_parse_unhandled(rec->tag, ptr); break; } diff --git a/cmd/x86/cbsysinfo.c b/cmd/x86/cbsysinfo.c index 07570b00c9a0..2b8d3b0a4356 100644 --- a/cmd/x86/cbsysinfo.c +++ b/cmd/x86/cbsysinfo.c @@ -364,6 +364,14 @@ static void show_table(struct sysinfo_t *info, bool verbose)
print_ptr("Chrome OS VPD", info->chromeos_vpd); print_ptr("RSDP", info->rsdp); + printf("%-12s: ", "Unimpl."); + if (info->unimpl_count) { + for (i = 0; i < info->unimpl_count; i++) + printf("%02x ", info->unimpl[i]); + printf("\n"); + } else { + printf("(none)\n"); + } }
static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc,

Enable support for NVMe storage devices. Update the driver to enable the bus master bit, since coreboot does not do that automatically.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Drop patch 'usb: Quieten a debug message' since it was fixed elsewhere - Drop patch 'x86: coreboot: Use a memory-mapped UART' (not needed)
configs/coreboot_defconfig | 3 +++ drivers/nvme/nvme_pci.c | 8 ++++++++ 2 files changed, 11 insertions(+)
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 3030e5bf93b4..8bb744e6e84d 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -59,6 +59,9 @@ CONFIG_SYS_ATA_ALT_OFFSET=0 CONFIG_ATAPI=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y +CONFIG_MISC=y +CONFIG_NVMEM=y +CONFIG_NVME_PCI=y # CONFIG_PCI_PNP is not set CONFIG_SOUND=y CONFIG_SOUND_I8254=y diff --git a/drivers/nvme/nvme_pci.c b/drivers/nvme/nvme_pci.c index 36bf9c5ffb73..dff19317943c 100644 --- a/drivers/nvme/nvme_pci.c +++ b/drivers/nvme/nvme_pci.c @@ -6,6 +6,7 @@
#include <common.h> #include <dm.h> +#include <init.h> #include <pci.h> #include "nvme.h"
@@ -30,6 +31,13 @@ static int nvme_probe(struct udevice *udev) ndev->instance = trailing_strtol(udev->name); ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, PCI_REGION_MEM); + + if (!ll_boot_init()) { + /* Turn on bus-mastering */ + dm_pci_clrset_config16(udev, PCI_COMMAND, 0, + PCI_COMMAND_MASTER); + } + return nvme_init(udev); }

Hi Simon,
On Mon, Mar 27, 2023 at 12:17 PM Simon Glass sjg@chromium.org wrote:
Enable support for NVMe storage devices. Update the driver to enable the bus master bit, since coreboot does not do that automatically.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Drop patch 'usb: Quieten a debug message' since it was fixed elsewhere
- Drop patch 'x86: coreboot: Use a memory-mapped UART' (not needed)
configs/coreboot_defconfig | 3 +++ drivers/nvme/nvme_pci.c | 8 ++++++++ 2 files changed, 11 insertions(+)
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 3030e5bf93b4..8bb744e6e84d 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -59,6 +59,9 @@ CONFIG_SYS_ATA_ALT_OFFSET=0 CONFIG_ATAPI=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y +CONFIG_MISC=y +CONFIG_NVMEM=y
The above 2 options seem not necessary when enabling NVMe, no?
+CONFIG_NVME_PCI=y # CONFIG_PCI_PNP is not set CONFIG_SOUND=y CONFIG_SOUND_I8254=y diff --git a/drivers/nvme/nvme_pci.c b/drivers/nvme/nvme_pci.c index 36bf9c5ffb73..dff19317943c 100644 --- a/drivers/nvme/nvme_pci.c +++ b/drivers/nvme/nvme_pci.c @@ -6,6 +6,7 @@
#include <common.h> #include <dm.h> +#include <init.h> #include <pci.h> #include "nvme.h"
@@ -30,6 +31,13 @@ static int nvme_probe(struct udevice *udev) ndev->instance = trailing_strtol(udev->name); ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, PCI_REGION_MEM);
if (!ll_boot_init()) {
I believe we can drop the ll_boot_init() check, and enable bus-mastering unconditionally as this is done by every PCI device driver.
/* Turn on bus-mastering */
dm_pci_clrset_config16(udev, PCI_COMMAND, 0,
PCI_COMMAND_MASTER);
}
return nvme_init(udev);
}
Regards, Bin

On Thu, May 4, 2023 at 9:18 PM Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Mon, Mar 27, 2023 at 12:17 PM Simon Glass sjg@chromium.org wrote:
Enable support for NVMe storage devices. Update the driver to enable the bus master bit, since coreboot does not do that automatically.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Drop patch 'usb: Quieten a debug message' since it was fixed elsewhere
- Drop patch 'x86: coreboot: Use a memory-mapped UART' (not needed)
configs/coreboot_defconfig | 3 +++ drivers/nvme/nvme_pci.c | 8 ++++++++
The nvme_pci change should go in a separate patch
2 files changed, 11 insertions(+)
Regards, Bin

This is useful when looking for tables in memory. Enable it for coreboot.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Add new patch to enable ms command
configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 8bb744e6e84d..cf0c9590e98d 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -24,6 +24,7 @@ CONFIG_LAST_STAGE_INIT=y CONFIG_PCI_INIT_R=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=532 +CONFIG_CMD_MEM_SEARCH=y CONFIG_CMD_IDE=y CONFIG_CMD_MMC=y CONFIG_CMD_PART=y

On Mon, Mar 27, 2023 at 12:17 PM Simon Glass sjg@chromium.org wrote:
This is useful when looking for tables in memory. Enable it for coreboot.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Add new patch to enable ms command
configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

When coreboot does not pass a UART in its sysinfo struct, there is no easy way to find it out. Add a way to specify known UARTs so we can find them without needing help from coreboot.
Since coreboot does not actually init the serial device when serial is disabled, it is not possible to make it add this information to the sysinfo table.
Also, we cannot use the class information, since we don't know which UART is being used. For example, with Alder Lake there are two:
00.16.00 0x8086 0x51e0 Simple comm. controller 0x80 00.1e.00 0x8086 0x51a8 Simple comm. controller 0x80
In our case the second one is the right one, but thre is no way to distinguish it from the first one without using the device ID.
If we have Adler Lake hardware which uses a different UART, we could perhaps look at the ACPI tables, or the machine information passed in the SMBIOS tables.
This was discussed previously before: [1]
[1] https://patchwork.ozlabs.org/project/uboot/patch/20210407163159.3.I967ea8c85...
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v2)
Changes in v2: - Move this patch to last in the series, so it can be dropped if needed
arch/x86/dts/coreboot.dts | 4 ++++ drivers/serial/serial_coreboot.c | 41 ++++++++++++++++++++++++++++++++ include/pci_ids.h | 3 +++ 3 files changed, 48 insertions(+)
diff --git a/arch/x86/dts/coreboot.dts b/arch/x86/dts/coreboot.dts index f9ff5346a79b..1abd3fddd15c 100644 --- a/arch/x86/dts/coreboot.dts +++ b/arch/x86/dts/coreboot.dts @@ -14,6 +14,8 @@ /include/ "rtc.dtsi"
#include "tsc_timer.dtsi" +#include <dt-bindings/pci/pci.h> +#include <pci_ids.h>
/ { model = "coreboot x86 payload"; @@ -34,6 +36,8 @@ pci { compatible = "pci-x86"; bootph-all; + u-boot,pci-pre-reloc = < + PCI_VENDEV(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADP_P_UART0) >; };
serial: serial { diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c index 23066e4d0543..bb3a5362dfaf 100644 --- a/drivers/serial/serial_coreboot.c +++ b/drivers/serial/serial_coreboot.c @@ -17,6 +17,12 @@
DECLARE_GLOBAL_DATA_PTR;
+static const struct pci_device_id ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL_UART2) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADP_P_UART0) }, + {}, +}; + static int read_dbg2(struct ns16550_plat *plat) { struct acpi_table_header *tab; @@ -94,6 +100,39 @@ static int read_dbg2(struct ns16550_plat *plat) return 0; }
+/* + * Coreboot only sets up the UART if it uses it and doesn't bother to put the + * details in sysinfo if it doesn't. Try to guess in that case, using devices + * we know about + * + * @plat: Platform data to fill in + * @return 0 if found, -ve if no UART was found + */ +static int guess_uart(struct ns16550_plat *plat) +{ + struct udevice *bus, *dev; + ulong addr; + int index; + int ret; + + ret = uclass_first_device_err(UCLASS_PCI, &bus); + if (ret) + return ret; + index = 0; + ret = pci_bus_find_devices(bus, ids, &index, &dev); + if (ret) + return ret; + addr = dm_pci_read_bar32(dev, 0); + plat->base = addr; + plat->reg_shift = 2; + plat->reg_width = 4; + plat->clock = 1843200; + plat->fcr = UART_FCR_DEFVAL; + plat->flags = 0; + + return 0; +} + static int coreboot_of_to_plat(struct udevice *dev) { struct ns16550_plat *plat = dev_get_plat(dev); @@ -113,6 +152,8 @@ static int coreboot_of_to_plat(struct udevice *dev) } else if (IS_ENABLED(CONFIG_COREBOOT_SERIAL_FROM_DBG2)) { ret = read_dbg2(plat); } + if (ret && CONFIG_IS_ENABLED(PCI)) + ret = guess_uart(plat);
if (ret) { /* diff --git a/include/pci_ids.h b/include/pci_ids.h index 88b0a6404585..5ae1b9b7fb6e 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2992,6 +2992,9 @@ #define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45 #define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f +#define PCI_DEVICE_ID_INTEL_ADP_P_UART0 0x51a8 +#define PCI_DEVICE_ID_INTEL_ADP_P_UART1 0x51a9 +#define PCI_DEVICE_ID_INTEL_APL_UART2 0x5ac0 #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_19 0x65f3 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5

Hi Simon,
On Mon, Mar 27, 2023 at 12:17 PM Simon Glass sjg@chromium.org wrote:
When coreboot does not pass a UART in its sysinfo struct, there is no easy way to find it out. Add a way to specify known UARTs so we can find them without needing help from coreboot.
Since coreboot does not actually init the serial device when serial is disabled, it is not possible to make it add this information to the sysinfo table.
Also, we cannot use the class information, since we don't know which UART is being used. For example, with Alder Lake there are two:
00.16.00 0x8086 0x51e0 Simple comm. controller 0x80 00.1e.00 0x8086 0x51a8 Simple comm. controller 0x80
In our case the second one is the right one, but thre is no way to distinguish it from the first one without using the device ID.
If we have Adler Lake hardware which uses a different UART, we could perhaps look at the ACPI tables, or the machine information passed in the SMBIOS tables.
This was discussed previously before: [1]
[1] https://patchwork.ozlabs.org/project/uboot/patch/20210407163159.3.I967ea8c85...
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v2)
Changes in v2:
- Move this patch to last in the series, so it can be dropped if needed
Since now we can parse the DBG2 ACPI table to get the UART info, I'd rather not apply this patch.
arch/x86/dts/coreboot.dts | 4 ++++ drivers/serial/serial_coreboot.c | 41 ++++++++++++++++++++++++++++++++ include/pci_ids.h | 3 +++ 3 files changed, 48 insertions(+)
Regards, Bin

Hi Bin,
On Sun, 26 Mar 2023 at 22:16, Simon Glass sjg@chromium.org wrote:
This series includes some patches generated while getting U-Boot to boot more nicely on Brya, an Adler Lake Chromebook.
This includes:
- show the ACPI tables with 'acpi list'
- get the UART to work even if coreboot doesn't enable it
- show unimplemented sysinfo tags
- fix for keyboard not working
- fix for trying to set up PCI regions when the info is not available
- fix for looking at inaccessible memory to find the sysinfo table
Changes in v3:
- Don't enable ACPI by default except on x86 and sandbox
- Avoid a build error with the ASL compiler
- Disable for coreboot64 since ACPI is not available
Changes in v2:
- Don't show an invalid CPU number on error
- Update commit message with more detail
- Update code comment to mention that addresses <1KB are ignored
- Flush the buffer instead of skipping the reset
- Add new patch to create a new Kconfig for ACPI
- Add new patch to move acpi-table-finding functions into the library
- Use tab instead of space in header file
- Refactor two patches into one
- Add new patch to allow locating the UART from ACPI tables
- Expand commit message to explain this is for the debug UART
- Update the defconfig instead
- Drop patch 'usb: Quieten a debug message' since it was fixed elsewhere
- Drop patch 'x86: coreboot: Use a memory-mapped UART' (not needed)
- Add new patch to enable ms command
- Move this patch to last in the series, so it can be dropped if needed
Simon Glass (16): mtrr: Don't show an invalid CPU number x86: Adjust search range for sysinfo table input: Flush the keyboard buffer before resetting it acpi: Create a new Kconfig for ACPI acpi: Move the table-finding functions into the libary x86: coreboot: Collect the address of the ACPI tables x86: Allow locating the UART from ACPI tables pci: coreboot: Don't read regions when booting x86: coreboot: Use a memory-mapped UART x86: coreboot: Document how to enable the debug UART x86: coreboot: Scan PCI after relocation x86: coreboot: Log function names and line numbers x86: coreboot: Show unimplemented sysinfo tags x86: nvme: coreboot: Enable NVMe coreboot: Enable ms command x86: Allow locating UARTs by device ID
arch/Kconfig | 2 + arch/x86/cpu/cpu.c | 4 +- arch/x86/dts/coreboot.dts | 4 + arch/x86/include/asm/cb_sysinfo.h | 8 ++ arch/x86/include/asm/coreboot_tables.h | 2 + arch/x86/lib/coreboot/cb_sysinfo.c | 13 +++ cmd/Kconfig | 2 +- cmd/acpi.c | 44 +------ cmd/x86/cbsysinfo.c | 9 ++ cmd/x86/mtrr.c | 6 +- configs/coreboot64_defconfig | 1 - configs/coreboot_defconfig | 10 +- doc/board/coreboot/coreboot.rst | 29 +++++ drivers/core/Kconfig | 1 + drivers/input/i8042.c | 19 +++ drivers/nvme/nvme_pci.c | 8 ++ drivers/pci/pci-uclass.c | 4 + drivers/serial/Kconfig | 10 ++ drivers/serial/serial_coreboot.c | 155 +++++++++++++++++++++++-- include/acpi/acpi_table.h | 8 ++ include/asm-generic/global_data.h | 4 +- include/pci_ids.h | 3 + lib/Kconfig | 10 +- lib/Makefile | 2 +- lib/acpi/Makefile | 6 + lib/acpi/acpi.c | 45 +++++++ 26 files changed, 351 insertions(+), 58 deletions(-) create mode 100644 lib/acpi/acpi.c
-- 2.40.0.348.gf938b09366-goog
Any thoughts on this series, please?
Regards, Simon
participants (3)
-
Bin Meng
-
Christian Gmeiner
-
Simon Glass