From 0fb19ffe3056e02408c4e14940d3635bbffd7295 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:54 -0600 Subject: [PATCH 01/33] mtrr: Don't show an invalid CPU number 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 Reviewed-by: Bin Meng --- cmd/x86/mtrr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c index b213a942fd..b1691d8b65 100644 --- a/cmd/x86/mtrr.c +++ b/cmd/x86/mtrr.c @@ -148,7 +148,8 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc, 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; } From 7a187a89fd96e8f2344b47b7fd4d3a686da66f55 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:55 -0600 Subject: [PATCH 02/33] x86: Adjust search range for sysinfo table 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 Reviewed-by: Bin Meng --- 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 6fe6eaf6c8..dddd281e96 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); From d8062e950367fab0f219a889e8f2fbfade90108c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:56 -0600 Subject: [PATCH 03/33] input: Flush the keyboard buffer before resetting it 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 Reviewed-by: Bin Meng --- drivers/input/i8042.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 3563dc9883..e6070ca015 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 #include #include @@ -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; From 0992a90daa80a17f9e7e33a56fd3f9660ee84c97 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:57 -0600 Subject: [PATCH 04/33] acpi: Create a new Kconfig for ACPI 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 Reviewed-by: Bin Meng --- 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 55b9a5eb8a..c9a3359225 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -195,6 +195,7 @@ config SANDBOX imply PHYLIB imply DM_MDIO imply DM_MDIO_MUX + imply ACPI imply ACPI_PMC imply ACPI_PMC_SANDBOX imply CMD_PMC @@ -261,6 +262,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 65957da7f5..87291e2d84 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 d0fc062ef8..991b5235e2 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 0f755aa702..f0d848f45d 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 d8dac09ea8..c8b3ec1ec9 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 10aa7ac029..8d8ccc8bbc 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 956b5a0d72..12337abaec 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 From 37bf44073bf2a51f25d82856d51ae16bc8fd8f76 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:58 -0600 Subject: [PATCH 05/33] acpi: Move the table-finding functions into the libary 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 Reviewed-by: Bin Meng Tested-by: Bin Meng --- 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 991b5235e2..e70913e40b 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 4030d25c66..7ed0443c82 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 diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 12337abaec..c1c9675b5d 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 0000000000..14b15754f4 --- /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 +#include +#include +#include + +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; +} From 368fd5646604e6759c3beefdfed61c7a1bb0ab33 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:54:59 -0600 Subject: [PATCH 06/33] x86: coreboot: Collect the address of the ACPI tables 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 Reviewed-by: Bin Meng Tested-by: Bin Meng --- 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 0201ac6b03..6b266149cf 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 f131de56a4..4de137fbab 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 748fa4ee53..a11a2587f6 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 34fdaf5b1b..07570b00c9 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 65bf8df1e5..a1e1b9d640 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 From b29dbf98baa35441ad01957bb2317cb4f70f390f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:00 -0600 Subject: [PATCH 07/33] x86: Allow locating the UART from ACPI tables 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 Reviewed-by: Bin Meng --- 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 7faf678444..f4767c838f 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 de09c8681f..23066e4d05 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 #include +#include #include #include +#include #include +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; } From dd0f7bcf3b29a0b6095622b7dd83279b0a3dbfe4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:01 -0600 Subject: [PATCH 08/33] pci: coreboot: Don't read regions when booting 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 Reviewed-by: Bin Meng Fixes: f2ebaaa9f38d ("pci: Handle failed calloc in decode_regions()") Tested-by: Christian Gmeiner Tested-by: Bin Meng --- 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 9343cfc62a..8d27e40338 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__); From b21626d4cb4ed258755b64e36baedb5e040ebf20 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:02 -0600 Subject: [PATCH 09/33] x86: coreboot: Use a memory-mapped UART 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 Reviewed-by: Bin Meng Tested-by: Bin Meng --- configs/coreboot64_defconfig | 1 - configs/coreboot_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig index ec672e59e8..60a1924e9e 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 4db7289916..fb4d175110 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 From b6b33d104ddca734a0348f7e7794ccb1709f8df8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:03 -0600 Subject: [PATCH 10/33] x86: coreboot: Document how to enable the debug UART This is not obvious so add a little note about how it works. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- 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 4a5f101cad..0fe95af56d 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 From 2cbc6aa47e53b84c0c9301031bcdca581342db51 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:04 -0600 Subject: [PATCH 11/33] x86: coreboot: Scan PCI after relocation Enable this so that PCI devices can be used correctly without needing to do a manual scan. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index fb4d175110..1bbb358a02 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 From ea45ee1fc3fd3afdf242d5f141cd55df936751e3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:05 -0600 Subject: [PATCH 12/33] x86: coreboot: Log function names and line numbers 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 Reviewed-by: Bin Meng --- configs/coreboot_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 1bbb358a02..3030e5bf93 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 From 2f5210b703355ba8f8d9c441a9b4f23ce3e93133 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:06 -0600 Subject: [PATCH 13/33] x86: coreboot: Show unimplemented sysinfo tags 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 Reviewed-by: Bin Meng Tested-by: Bin Meng --- 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 6b266149cf..2c78b22d0d 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 a11a2587f6..42cc3a128d 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 07570b00c9..2b8d3b0a43 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, From 38534712cd4c4d8acdf760ee87ba219f82d738c9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:07 -0600 Subject: [PATCH 14/33] nvme: Enable PCI bus mastering U-Boot sets up devices ready for use, but coreboot does not. Enable this so that NVMe works OK from coreboot. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/nvme/nvme_pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/nvme/nvme_pci.c b/drivers/nvme/nvme_pci.c index 36bf9c5ffb..5bb43d299f 100644 --- a/drivers/nvme/nvme_pci.c +++ b/drivers/nvme/nvme_pci.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "nvme.h" @@ -30,6 +31,10 @@ 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); + + /* Turn on bus-mastering */ + dm_pci_clrset_config16(udev, PCI_COMMAND, 0, PCI_COMMAND_MASTER); + return nvme_init(udev); } From fa328446bce23ab210c5aa01249075b6a7a7e251 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:08 -0600 Subject: [PATCH 15/33] x86: nvme: coreboot: Enable NVMe 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 Reviewed-by: Bin Meng --- configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 3030e5bf93..f6ffb51804 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -59,6 +59,7 @@ CONFIG_SYS_ATA_ALT_OFFSET=0 CONFIG_ATAPI=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y +CONFIG_NVME_PCI=y # CONFIG_PCI_PNP is not set CONFIG_SOUND=y CONFIG_SOUND_I8254=y From 44dc33042f8465764bddeba4e4b362dd5372b74a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:55:09 -0600 Subject: [PATCH 16/33] coreboot: Enable ms command This is useful when looking for tables in memory. Enable it for coreboot. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- configs/coreboot_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index f6ffb51804..058caf008f 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 From 55171aedda88d12666e2a1bbc661dea1bec65337 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:45 -0600 Subject: [PATCH 17/33] dm: Emit the arch_cpu_init_dm() even only before relocation The original function was only called once, before relocation. The new one is called again after relocation. This was not the intent of the original call. Fix this by renaming and updating the calling logic. With this, chromebook_link64 makes it through SPL. Fixes: 7fe32b3442f0 ("event: Convert arch_cpu_init_dm() to use events") Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/arm/mach-imx/imx8/cpu.c | 2 +- arch/arm/mach-imx/imx8m/soc.c | 2 +- arch/arm/mach-imx/imx8ulp/soc.c | 2 +- arch/arm/mach-imx/imx9/soc.c | 2 +- arch/arm/mach-omap2/am33xx/board.c | 2 +- arch/arm/mach-omap2/hwinit-common.c | 2 +- arch/mips/mach-pic32/cpu.c | 2 +- arch/nios2/cpu/cpu.c | 2 +- arch/riscv/cpu/cpu.c | 2 +- arch/x86/cpu/baytrail/cpu.c | 2 +- arch/x86/cpu/broadwell/cpu.c | 2 +- arch/x86/cpu/ivybridge/cpu.c | 2 +- arch/x86/cpu/quark/quark.c | 2 +- arch/x86/lib/fsp2/fsp_init.c | 2 +- doc/develop/event.rst | 6 +++--- drivers/core/root.c | 4 ++-- drivers/cpu/microblaze_cpu.c | 2 +- include/event.h | 2 +- 18 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index be1f4edded..99772f68c3 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -89,7 +89,7 @@ static int imx8_init_mu(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, imx8_init_mu); +EVENT_SPY(EVT_DM_POST_INIT_F, imx8_init_mu); #if defined(CONFIG_ARCH_MISC_INIT) int arch_misc_init(void) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 4705e6c119..5a4f8358c9 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -549,7 +549,7 @@ static int imx8m_check_clock(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock); +EVENT_SPY(EVT_DM_POST_INIT_F, imx8m_check_clock); static void imx8m_setup_snvs(void) { diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index 8424332f42..81eae02b6a 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -808,7 +808,7 @@ static int imx8ulp_evt_dm_post_init(void *ctx, struct event *event) { return imx8ulp_dm_post_init(); } -EVENT_SPY(EVT_DM_POST_INIT, imx8ulp_evt_dm_post_init); +EVENT_SPY(EVT_DM_POST_INIT_F, imx8ulp_evt_dm_post_init); #if defined(CONFIG_SPL_BUILD) __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index a16e22ea6b..252663a9ee 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -262,7 +262,7 @@ int imx9_probe_mu(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, imx9_probe_mu); +EVENT_SPY(EVT_DM_POST_INIT_F, imx9_probe_mu); int timer_init(void) { diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c index a52d04d85c..ecc0a592e9 100644 --- a/arch/arm/mach-omap2/am33xx/board.c +++ b/arch/arm/mach-omap2/am33xx/board.c @@ -535,4 +535,4 @@ static int am33xx_dm_post_init(void *ctx, struct event *event) #endif return 0; } -EVENT_SPY(EVT_DM_POST_INIT, am33xx_dm_post_init); +EVENT_SPY(EVT_DM_POST_INIT_F, am33xx_dm_post_init); diff --git a/arch/arm/mach-omap2/hwinit-common.c b/arch/arm/mach-omap2/hwinit-common.c index c4a8eabc3e..771533394b 100644 --- a/arch/arm/mach-omap2/hwinit-common.c +++ b/arch/arm/mach-omap2/hwinit-common.c @@ -246,7 +246,7 @@ static int omap2_system_init(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, omap2_system_init); +EVENT_SPY(EVT_DM_POST_INIT_F, omap2_system_init); /* * Routine: wait_for_command_complete diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index de449e3c6a..ec3c250531 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -102,7 +102,7 @@ static int pic32_flash_prefetch(void *ctx, struct event *event) prefetch_init(); return 0; } -EVENT_SPY(EVT_DM_POST_INIT, pic32_flash_prefetch); +EVENT_SPY(EVT_DM_POST_INIT_F, pic32_flash_prefetch); /* Un-gate DDR2 modules (gated by default) */ static void ddr2_pmd_ungate(void) diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c index 85544503a5..da167f4b29 100644 --- a/arch/nios2/cpu/cpu.c +++ b/arch/nios2/cpu/cpu.c @@ -80,7 +80,7 @@ static int nios_cpu_setup(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, nios_cpu_setup); +EVENT_SPY(EVT_DM_POST_INIT_F, nios_cpu_setup); static int altera_nios2_get_desc(const struct udevice *dev, char *buf, int size) diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index e1ed4ec01d..ecfb1fb08c 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -145,7 +145,7 @@ int riscv_cpu_setup(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, riscv_cpu_setup); +EVENT_SPY(EVT_DM_POST_INIT_F, riscv_cpu_setup); int arch_early_init_r(void) { diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c index 4fb6a48554..4a7b4f617f 100644 --- a/arch/x86/cpu/baytrail/cpu.c +++ b/arch/x86/cpu/baytrail/cpu.c @@ -64,7 +64,7 @@ static int baytrail_uart_init(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, baytrail_uart_init); +EVENT_SPY(EVT_DM_POST_INIT_F, baytrail_uart_init); static void set_max_freq(void) { diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c index 7877961451..f30aebfe4c 100644 --- a/arch/x86/cpu/broadwell/cpu.c +++ b/arch/x86/cpu/broadwell/cpu.c @@ -40,7 +40,7 @@ static int broadwell_init_cpu(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, broadwell_init_cpu); +EVENT_SPY(EVT_DM_POST_INIT_F, broadwell_init_cpu); void set_max_freq(void) { diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index cffc5d5b1d..c988d7ff47 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -86,7 +86,7 @@ static int ivybridge_cpu_init(void *ctx, struct event *ev) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, ivybridge_cpu_init); +EVENT_SPY(EVT_DM_POST_INIT_F, ivybridge_cpu_init); #define PCH_EHCI0_TEMP_BAR0 0xe8000000 #define PCH_EHCI1_TEMP_BAR0 0xe8000400 diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 0a1fbb34d4..1be8e38cdf 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -263,7 +263,7 @@ static int quark_init_pcie(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, quark_init_pcie); +EVENT_SPY(EVT_DM_POST_INIT_F, quark_init_pcie); int checkcpu(void) { diff --git a/arch/x86/lib/fsp2/fsp_init.c b/arch/x86/lib/fsp2/fsp_init.c index b15926e824..afec7d08d6 100644 --- a/arch/x86/lib/fsp2/fsp_init.c +++ b/arch/x86/lib/fsp2/fsp_init.c @@ -42,7 +42,7 @@ int fsp_setup_pinctrl(void *ctx, struct event *event) return ret; } -EVENT_SPY(EVT_DM_POST_INIT, fsp_setup_pinctrl); +EVENT_SPY(EVT_DM_POST_INIT_F, fsp_setup_pinctrl); #if !defined(CONFIG_TPL_BUILD) binman_sym_declare(ulong, intel_fsp_m, image_pos); diff --git a/doc/develop/event.rst b/doc/develop/event.rst index e60cbf6569..1c1c9ef7f1 100644 --- a/doc/develop/event.rst +++ b/doc/develop/event.rst @@ -11,7 +11,7 @@ block device is probed. Rather than using weak functions and direct calls across subsystemss, it is often easier to use an event. -An event consists of a type (e.g. EVT_DM_POST_INIT) and some optional data, +An event consists of a type (e.g. EVT_DM_POST_INIT_F) and some optional data, in `union event_data`. An event spy can be created to watch for events of a particular type. When the event is created, it is sent to each spy in turn. @@ -26,9 +26,9 @@ To declare a spy, use something like this:: /* do something */ return 0; } - EVENT_SPY(EVT_DM_POST_INIT, snow_setup_cpus); + EVENT_SPY(EVT_DM_POST_INIT_F, snow_setup_cpus); -Your function is called when EVT_DM_POST_INIT is emitted, i.e. after driver +Your function is called when EVT_DM_POST_INIT_F is emitted, i.e. after driver model is inited (in SPL, or in U-Boot proper before and after relocation). diff --git a/drivers/core/root.c b/drivers/core/root.c index c4fb48548b..6775fb0b65 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -436,8 +436,8 @@ int dm_init_and_scan(bool pre_reloc_only) return ret; } } - if (CONFIG_IS_ENABLED(DM_EVENT)) { - ret = event_notify_null(EVT_DM_POST_INIT); + if (CONFIG_IS_ENABLED(DM_EVENT) && !(gd->flags & GD_FLG_RELOC)) { + ret = event_notify_null(EVT_DM_POST_INIT_F); if (ret) return log_msg_ret("ev", ret); } diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c index b9d0792822..c97a89fbd5 100644 --- a/drivers/cpu/microblaze_cpu.c +++ b/drivers/cpu/microblaze_cpu.c @@ -29,7 +29,7 @@ static int microblaze_cpu_probe_all(void *ctx, struct event *event) return 0; } -EVENT_SPY(EVT_DM_POST_INIT, microblaze_cpu_probe_all); +EVENT_SPY(EVT_DM_POST_INIT_F, microblaze_cpu_probe_all); static void microblaze_set_cpuinfo_pvr(struct microblaze_cpuinfo *ci) { diff --git a/include/event.h b/include/event.h index e4580b6835..fe41080fa6 100644 --- a/include/event.h +++ b/include/event.h @@ -22,7 +22,7 @@ enum event_t { EVT_TEST, /* Events related to driver model */ - EVT_DM_POST_INIT, + EVT_DM_POST_INIT_F, EVT_DM_PRE_PROBE, EVT_DM_POST_PROBE, EVT_DM_PRE_REMOVE, From f2fac8b5571b2537cf499bab9a7962e19f64e9de Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:46 -0600 Subject: [PATCH 18/33] binman: Support writing symbols for ucode etypes Allow symbol writing in these cases so that U-Boot can find the position and size of U-Boot at runtime. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- tools/binman/etype/u_boot_spl_with_ucode_ptr.py | 2 +- tools/binman/etype/u_boot_tpl_with_ucode_ptr.py | 2 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py index 72739a5eb6..18b99b00f4 100644 --- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py @@ -18,7 +18,7 @@ class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): process. """ def __init__(self, section, etype, node): - super().__init__(section, etype, node) + super().__init__(section, etype, node, auto_write_symbols=True) self.elf_fname = 'spl/u-boot-spl' def GetDefaultFilename(self): diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py index 86f9578b71..f8cc22011c 100644 --- a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py @@ -20,7 +20,7 @@ class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): process. """ def __init__(self, section, etype, node): - super().__init__(section, etype, node) + super().__init__(section, etype, node, auto_write_symbols=True) self.elf_fname = 'tpl/u-boot-tpl' def GetDefaultFilename(self): diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index 41731fd0e1..aab27ac8ee 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -28,8 +28,8 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob): microcode, to allow early x86 boot code to find it without doing anything complicated. Otherwise it is the same as the u-boot entry. """ - def __init__(self, section, etype, node): - super().__init__(section, etype, node) + def __init__(self, section, etype, node, auto_write_symbols=False): + super().__init__(section, etype, node, auto_write_symbols) self.elf_fname = 'u-boot' self.target_offset = None From 28afcb1e7f7d1b899514cbdb58fb658ee0b5c5a3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:47 -0600 Subject: [PATCH 19/33] sf: Guard against zero erasesize With tiny SPI flash the erasesize is 0 which can cause a divide-by-zero error. Check for this and return a proper error instead. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/mtd/spi/sf_probe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index e192f97efd..de6516f106 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -189,7 +189,8 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) struct mtd_info *mtd = &flash->mtd; struct erase_info instr; - if (offset % mtd->erasesize || len % mtd->erasesize) { + if (!mtd->erasesize || + (offset % mtd->erasesize || len % mtd->erasesize)) { debug("SF: Erase offset/length not multiple of erase size\n"); return -EINVAL; } From dafbfe83e04c17d304129b709ec6305acd616aac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:48 -0600 Subject: [PATCH 20/33] sf: Rename spi-nor-tiny functions The 'tiny' SPI nor functions have the same name as their big brothers, which can be confusing. Use different names so it is clear which version is in the image. Signed-off-by: Simon Glass Acked-by: Vignesh Raghavendra Reviewed-by: Bin Meng --- drivers/mtd/spi/spi-nor-tiny.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c index 68152ce3b4..7aa24e129f 100644 --- a/drivers/mtd/spi/spi-nor-tiny.c +++ b/drivers/mtd/spi/spi-nor-tiny.c @@ -361,7 +361,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor) * Erase an address range on the nor chip. The address range may extend * one or more erase sectors. Return an error is there is a problem erasing. */ -static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) +static int spi_nor_erase_tiny(struct mtd_info *mtd, struct erase_info *instr) { return -ENOTSUPP; } @@ -390,8 +390,8 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) return ERR_PTR(-EMEDIUMTYPE); } -static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int spi_nor_read_tiny(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret; @@ -426,8 +426,8 @@ read_err: * FLASH_PAGESIZE chunks. The address range may be any size provided * it is within the physical boundaries. */ -static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int spi_nor_write_tiny(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { return -ENOTSUPP; } @@ -741,9 +741,9 @@ int spi_nor_scan(struct spi_nor *nor) mtd->writesize = 1; mtd->flags = MTD_CAP_NORFLASH; mtd->size = info->sector_size * info->n_sectors; - mtd->_erase = spi_nor_erase; - mtd->_read = spi_nor_read; - mtd->_write = spi_nor_write; + mtd->_erase = spi_nor_erase_tiny; + mtd->_read = spi_nor_read_tiny; + mtd->_write = spi_nor_write_tiny; nor->size = mtd->size; From 5b465beac634d65ca5097568a8f4e9e1d61013e2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:49 -0600 Subject: [PATCH 21/33] x86: ivybridge: Ensure LPC is available for GPIO base The bd82x6x_get_gpio_base() does not work if the LPC is not set up. Probe it early to avoid this problem. In chromebook_link64 this problem shows up as an inability to read the GPIO straps for the memory type. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/ivybridge/bd82x6x.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 89312a8634..417290f559 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -31,7 +31,6 @@ DECLARE_GLOBAL_DATA_PTR; #define RCBA_AUDIO_CONFIG_HDA BIT(31) #define RCBA_AUDIO_CONFIG_MASK 0xfe -#ifndef CONFIG_HAVE_FSP static int pch_revision_id = -1; static int pch_type = -1; @@ -162,15 +161,19 @@ void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue, static int bd82x6x_probe(struct udevice *dev) { - if (!(gd->flags & GD_FLG_RELOC)) - return 0; + /* make sure the LPC is inited since it provides the gpio base */ + uclass_first_device(UCLASS_LPC, &dev); - /* Cause the SATA device to do its init */ - uclass_first_device(UCLASS_AHCI, &dev); + if (!IS_ENABLED(CONFIG_HAVE_FSP)) { + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + + /* Cause the SATA device to do its init */ + uclass_first_device(UCLASS_AHCI, &dev); + } return 0; } -#endif /* CONFIG_HAVE_FSP */ static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep) { @@ -269,8 +272,6 @@ U_BOOT_DRIVER(bd82x6x_drv) = { .name = "bd82x6x", .id = UCLASS_PCH, .of_match = bd82x6x_ids, -#ifndef CONFIG_HAVE_FSP .probe = bd82x6x_probe, -#endif .ops = &bd82x6x_pch_ops, }; From 94c11e96fd07d46238efe5e5717bc84ffc890443 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:50 -0600 Subject: [PATCH 22/33] x86: samus: Drop EFI_LOADER This adds a lot of code so that it cannot be built with the binary blobs. It is not used on this board. Drop it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- configs/chromebook_samus_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/chromebook_samus_defconfig b/configs/chromebook_samus_defconfig index b933a2352e..0d20891d2b 100644 --- a/configs/chromebook_samus_defconfig +++ b/configs/chromebook_samus_defconfig @@ -84,3 +84,4 @@ CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y CONFIG_TPM=y # CONFIG_GZIP is not set +# CONFIG_EFI_LOADER is not set From afa3d90c08242790dad21ac27a412067bcbfcb49 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:51 -0600 Subject: [PATCH 23/33] x86: Support debug UART in 64-bit mode The debug UART is already set up in SPL, so there is no need to do anything here. We must provide the (empty) function though. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/x86_64/cpu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c index 6a38761291..d1c3873dd6 100644 --- a/arch/x86/cpu/x86_64/cpu.c +++ b/arch/x86/cpu/x86_64/cpu.c @@ -50,3 +50,10 @@ int x86_cpu_init_f(void) { return 0; } + +#ifdef CONFIG_DEBUG_UART_BOARD_INIT +void board_debug_uart_init(void) +{ + /* this was already done in SPL */ +} +#endif From b194e432c3d22bbeb6045b7f294c354d03ee95d3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:52 -0600 Subject: [PATCH 24/33] x86: Tidy up availability of string functions For now, just enable the fast-but-large string functions in 32-boot U-Boot proper only. Avoid using them in SPL. We cannot use then in 64-bit builds since we only have 32-bit assembly. Reviewed-by: Bin Meng Signed-off-by: Simon Glass --- arch/x86/include/asm/string.h | 6 +++++- arch/x86/lib/Makefile | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h index c15b264a5c..5c49b0f009 100644 --- a/arch/x86/include/asm/string.h +++ b/arch/x86/include/asm/string.h @@ -14,7 +14,11 @@ extern char *strrchr(const char *s, int c); #undef __HAVE_ARCH_STRCHR extern char *strchr(const char *s, int c); -#ifdef CONFIG_X86_64 +/* + * Our assembly routines do not work on in 64-bit mode and we don't do a lot of + * copying in SPL, so code size is more important there. + */ +#if defined(CONFIG_SPL_BUILD) || !IS_ENABLED(CONFIG_X86_32BIT_INIT) #undef __HAVE_ARCH_MEMCPY extern void *memcpy(void *, const void *, __kernel_size_t); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index a6f2244147..b0612ae6dd 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -10,7 +10,9 @@ obj-y += bios.o obj-y += bios_asm.o obj-y += bios_interrupts.o endif -obj-y += string.o +endif +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_X86_32BIT_INIT) += string.o endif ifndef CONFIG_SPL_BUILD obj-$(CONFIG_CMD_BOOTM) += bootm.o From 392720b429a967a449e0c02a12193aac4b170c9c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:53 -0600 Subject: [PATCH 25/33] x86: mrc: Correct SPL debug message SPL printf() does not normally support %#x so just use %x instead. Hex is expected in U-Boot anyway. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/mrccache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 38632e513f..2f6f688000 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -303,7 +303,7 @@ static int mrccache_save_type(enum mrc_type_t type) mrc = &gd->arch.mrc[type]; if (!mrc->len) return 0; - log_debug("Saving %#x bytes of MRC output data type %d to SPI flash\n", + log_debug("Saving %x bytes of MRC output data type %d to SPI flash\n", mrc->len, type); ret = mrccache_get_region(type, &sf, &entry); if (ret) From 3d0f885a2adc9320a01a905a9deaa06d51614d92 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:54 -0600 Subject: [PATCH 26/33] x86: spl: Show debugging for BSS Show the area of memory cleared for BSS, when debugging is enabled. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/spl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index bdf57ef7b5..5e47ffa7db 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -117,6 +117,8 @@ static int x86_spl_init(void) } #ifndef CONFIG_SYS_COREBOOT + debug("BSS clear from %lx to %lx len %lx\n", (ulong)&__bss_start, + (ulong)&__bss_end, (ulong)&__bss_end - (ulong)&__bss_start); memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start); # ifndef CONFIG_TPL From 6624392d3bb633fe91b7cc4b75b6eec28f637f72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 9 May 2023 18:13:47 +0800 Subject: [PATCH 27/33] x86: sysreset: Set up LPC only after relocation Probing LPC can cause PCI enumeration to take place, which significantly increases pre-relocation memory usage. Also, LPC is somtimes enabled directly by SPL. Adjust the logic to probe the LPC only after relocation. This allows chromebook_link64 to start up without a much larger CONFIG_SYS_MALLOC_F_LEN value. Signed-off-by: Simon Glass Signed-off-by: Bin Meng Reviewed-by: Bin Meng --- drivers/sysreset/sysreset_x86.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c index 8042f3994f..4936fdb76c 100644 --- a/drivers/sysreset/sysreset_x86.c +++ b/drivers/sysreset/sysreset_x86.c @@ -129,8 +129,13 @@ static int x86_sysreset_probe(struct udevice *dev) { struct x86_sysreset_plat *plat = dev_get_plat(dev); - /* Locate the PCH if there is one. It isn't essential */ - uclass_first_device(UCLASS_PCH, &plat->pch); + /* + * Locate the PCH if there is one. It isn't essential. Avoid this before + * relocation as we shouldn't need reset then and it needs a lot of + * memory for PCI enumeration. + */ + if (gd->flags & GD_FLG_RELOC) + uclass_first_device(UCLASS_PCH, &plat->pch); return 0; } From 4e7cbf746f6ed1353244773b47aa1c7f92ed9d97 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:55 -0600 Subject: [PATCH 28/33] x86: Tidy up address for loading U-Boot from SPL Use the binman symbols for this, to avoid hard-coding the value. We could use CONFIG_X86_OFFSET_U_BOOT for the address, but it seems better to obtain the offset and size through the same mechanism. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/spl.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 5e47ffa7db..479889aec6 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -217,16 +217,9 @@ static int spl_board_load_image(struct spl_image_info *spl_image, spl_image->name = "U-Boot"; if (!IS_ENABLED(CONFIG_SYS_COREBOOT)) { - /* - * Copy U-Boot from ROM - * TODO(sjg@chromium.org): Figure out a way to get the text base - * correctly here, and in the device-tree binman definition. - * - * Also consider using FIT so we get the correct image length - * and parameters. - */ - memcpy((char *)spl_image->load_addr, (char *)0xfff00000, - 0x100000); + /* Copy U-Boot from ROM */ + memcpy((void *)spl_image->load_addr, + (void *)spl_get_image_pos(), spl_get_image_size()); } debug("Loading to %lx\n", spl_image->load_addr); From 80831b2a42cfe9bd3306059a818b8bc2b42a02d8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:57 -0600 Subject: [PATCH 29/33] x86: spl: Avoid using init_cache_f_r() from SPL This function is used by U-Boot proper. It does not set up MTRRs when SPL is enabled, but we do want this done when it is called from SPL. In fact it is confusing to use the same function from SPL, since there are quite a few conditions there. All init_cache_f_r() really does is commit the MTRRs and set up the cache. Do this in the SPL's version of this function instead. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/spl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 479889aec6..61eb026c86 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -186,7 +186,8 @@ void board_init_f(ulong flags) void board_init_f_r(void) { - init_cache_f_r(); + mtrr_commit(false); + init_cache(); gd->flags &= ~GD_FLG_SERIAL_READY; debug("cache status %d\n", dcache_status()); board_init_r(gd, 0); From 50574d42cfb9d3346e6a9a7642db67aa2b24d365 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:58 -0600 Subject: [PATCH 30/33] spl: Commit MTRRs only in board_init_f_r() We don't need to commit the SPI-flash MTRR change immediately, since it is now done in the board_init_f_r(). Also this causes chromebook_link64 to hang, presumably since we are still running from CAR (Cache-as-RAM) in SPL. Coral handles this OK, perhaps since it is running from a different memory area, but it has no effect on Coral anyway. Drop the extra mtrr_commit() in the SPL implementation. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/spl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 61eb026c86..ca1645f9d6 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -147,7 +147,6 @@ static int x86_spl_init(void) debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret); return ret; } - mtrr_commit(true); # else ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit); if (ret) From 4cb3b9f01ed8bdbd49627b977e91fc05472837cc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:50:59 -0600 Subject: [PATCH 31/33] x86: Simplify cpu_jump_to_64bit_uboot() This copies the cpu_call64() function to memory address and then jumps to it. This seems to work correctly even when called from SPL, which is running from SPI flash. Drop the copy as it is not needed. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/i386/cpu.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index c7f6c5a013..91cd5d7c9e 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -572,6 +572,7 @@ int cpu_has_64bit(void) has_long_mode(); } +/* Base address for page tables used for 64-bit mode */ #define PAGETABLE_BASE 0x80000 #define PAGETABLE_SIZE (6 * 4096) @@ -614,43 +615,20 @@ int cpu_jump_to_64bit(ulong setup_base, ulong target) } /* - * Jump from SPL to U-Boot + * cpu_jump_to_64bit_uboot() - Jump from SPL to U-Boot * - * This function is work-in-progress with many issues to resolve. - * - * It works by setting up several regions: - * ptr - a place to put the code that jumps into 64-bit mode - * gdt - a place to put the global descriptor table - * pgtable - a place to put the page tables - * - * The cpu_call64() code is copied from ROM and then manually patched so that - * it has the correct GDT address in RAM. U-Boot is copied from ROM into - * its pre-relocation address. Then we jump to the cpu_call64() code in RAM, - * which changes to 64-bit mode and starts U-Boot. + * It works by setting up page tables and calling the code to enter 64-bit long + * mode */ int cpu_jump_to_64bit_uboot(ulong target) { - typedef void (*func_t)(ulong pgtable, ulong setup_base, ulong target); uint32_t *pgtable; - func_t func; - char *ptr; pgtable = (uint32_t *)PAGETABLE_BASE; - build_pagetable(pgtable); - extern long call64_stub_size; - ptr = malloc(call64_stub_size); - if (!ptr) { - printf("Failed to allocate the cpu_call64 stub\n"); - return -ENOMEM; - } - memcpy(ptr, cpu_call64, call64_stub_size); - - func = (func_t)ptr; - /* Jump to U-Boot */ - func((ulong)pgtable, 0, (ulong)target); + cpu_call64(PAGETABLE_BASE, 0, (ulong)target); return -EFAULT; } From e2cb0468bda9458a98cee39791f7cff705da4933 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:51:00 -0600 Subject: [PATCH 32/33] x86: samus: Don't include audio and SATA in TPL These are not used in TPL so disable the drivers to save space. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/broadwell/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/cpu/broadwell/Makefile b/arch/x86/cpu/broadwell/Makefile index 52d56c65be..3e1f76d611 100644 --- a/arch/x86/cpu/broadwell/Makefile +++ b/arch/x86/cpu/broadwell/Makefile @@ -2,7 +2,6 @@ # # Copyright (c) 2016 Google, Inc -obj-y += adsp.o obj-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += cpu.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += cpu_full.o @@ -14,6 +13,8 @@ obj-y += refcode.o endif ifndef CONFIG_SPL_BUILD # obj-y += cpu_from_spl.o +obj-y += adsp.o +obj-y += sata.o endif endif @@ -29,5 +30,4 @@ obj-y += pch.o obj-y += pinctrl_broadwell.o obj-y += power_state.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += refcode.o -obj-y += sata.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += sdram.o From b982f89c583c6c03f4d1f94d29991ccf691a0f7c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 4 May 2023 16:51:01 -0600 Subject: [PATCH 33/33] x86: samus: Adjust TPL start and pre-reloc memory size Move the TPL up a little to make room for the refcode binary blob. Also increase the pre-relocation memory to make space for recent additions. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- configs/chromebook_samus_tpl_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/chromebook_samus_tpl_defconfig b/configs/chromebook_samus_tpl_defconfig index 337768b45f..4cfaf4bc5c 100644 --- a/configs/chromebook_samus_tpl_defconfig +++ b/configs/chromebook_samus_tpl_defconfig @@ -1,6 +1,6 @@ CONFIG_X86=y CONFIG_TEXT_BASE=0xffed0000 -CONFIG_SYS_MALLOC_F_LEN=0x1a00 +CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_NR_DRAM_BANKS=8 CONFIG_ENV_SIZE=0x1000 CONFIG_ENV_OFFSET=0x3F8000 @@ -8,7 +8,7 @@ CONFIG_ENV_SECT_SIZE=0x1000 CONFIG_SPL_DM_SPI=y CONFIG_DEFAULT_DEVICE_TREE="chromebook_samus" CONFIG_SPL_TEXT_BASE=0xffe70000 -CONFIG_TPL_TEXT_BASE=0xfffd8000 +CONFIG_TPL_TEXT_BASE=0xfffd8100 CONFIG_DEBUG_UART_BASE=0x3f8 CONFIG_DEBUG_UART_CLOCK=1843200 CONFIG_DEBUG_UART_BOARD_INIT=y