summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-03-28 20:29:39 -0400
committerTom Rini <trini@konsulko.com>2021-03-28 20:29:39 -0400
commit4906238191b90be7aec2269ba8cd6aeb161cd312 (patch)
tree1bab411fe047542ab69342a90fba6110f4dbe124
parent9c7335e4e68355a96bd5a411b2a5f85866823c58 (diff)
parente5021221db3faf7e90a295d6eb045fbf5c6a908b (diff)
downloadu-boot-WIP/28Mar2021-next.tar.gz
Merge tag 'dm-pull-28mar21' of git://git.denx.de/u-boot-dm into nextWIP/28Mar2021-next
binman support for expanding entries, connections misc fixes and improvements to sandbox, etc. x86 CBFS improvements x86 coreboot improvements
-rw-r--r--arch/riscv/cpu/ax25/Kconfig2
-rw-r--r--arch/riscv/cpu/fu540/Kconfig2
-rw-r--r--arch/riscv/cpu/generic/Kconfig2
-rw-r--r--arch/sandbox/cpu/cpu.c6
-rw-r--r--arch/sandbox/cpu/os.c24
-rw-r--r--arch/sandbox/cpu/u-boot.lds7
-rw-r--r--arch/sandbox/dts/sandbox.dtsi4
-rw-r--r--arch/x86/Kconfig21
-rw-r--r--arch/x86/cpu/apollolake/cpu.c14
-rw-r--r--arch/x86/cpu/apollolake/cpu_common.c60
-rw-r--r--arch/x86/cpu/apollolake/cpu_spl.c58
-rw-r--r--arch/x86/cpu/coreboot/Makefile1
-rw-r--r--arch/x86/cpu/coreboot/coreboot.c2
-rw-r--r--arch/x86/cpu/coreboot/sdram.c29
-rw-r--r--arch/x86/cpu/coreboot/tables.c255
-rw-r--r--arch/x86/cpu/coreboot/timestamp.c14
-rw-r--r--arch/x86/cpu/start_from_spl.S4
-rw-r--r--arch/x86/dts/chromebook_coral.dts19
-rw-r--r--arch/x86/include/asm/arch-apollolake/uart.h1
-rw-r--r--arch/x86/include/asm/arch-coreboot/sysinfo.h62
-rw-r--r--arch/x86/include/asm/arch-coreboot/timestamp.h25
-rw-r--r--arch/x86/include/asm/cb_sysinfo.h220
-rw-r--r--arch/x86/include/asm/coreboot_tables.h261
-rw-r--r--arch/x86/include/asm/e820.h16
-rw-r--r--arch/x86/lib/Makefile1
-rw-r--r--arch/x86/lib/bootm.c2
-rw-r--r--arch/x86/lib/coreboot/Makefile7
-rw-r--r--arch/x86/lib/coreboot/cb_support.c41
-rw-r--r--arch/x86/lib/coreboot/cb_sysinfo.c468
-rw-r--r--arch/x86/lib/fsp/fsp_graphics.c2
-rw-r--r--arch/x86/lib/fsp2/fsp_init.c3
-rw-r--r--arch/x86/lib/fsp2/fsp_support.c4
-rw-r--r--arch/x86/lib/init_helpers.c6
-rw-r--r--arch/x86/lib/spl.c2
-rw-r--r--arch/x86/lib/zimage.c13
-rw-r--r--board/coreboot/coreboot/coreboot.c2
-rw-r--r--board/google/chromebook_coral/coral.c141
-rw-r--r--board/google/chromebook_coral/variant_gpio.h6
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/acpi.c2
-rw-r--r--cmd/bloblist.c2
-rw-r--r--cmd/host.c35
-rw-r--r--cmd/version.c2
-rw-r--r--cmd/x86/Makefile1
-rw-r--r--cmd/x86/cbsysinfo.c394
-rw-r--r--common/board_info.c37
-rw-r--r--common/bootm.c3
-rw-r--r--common/bootstage.c18
-rw-r--r--common/image-fit.c4
-rw-r--r--common/spl/Kconfig2
-rw-r--r--common/spl/spl.c23
-rw-r--r--configs/chromebook_coral_defconfig2
-rw-r--r--configs/chromebook_link64_defconfig2
-rw-r--r--configs/qemu-x86_64_defconfig2
-rw-r--r--doc/arch/sandbox.rst2
-rw-r--r--doc/board/google/chromebook_coral.rst234
-rw-r--r--doc/chromium/chainload.rst (renamed from doc/README.chromium-chainload)80
-rw-r--r--doc/chromium/files/chromebook_jerry.its (renamed from doc/chromium/chromebook_jerry.its)0
-rw-r--r--doc/chromium/files/devkeys/kernel.keyblock (renamed from doc/chromium/devkeys/kernel.keyblock)bin1208 -> 1208 bytes
-rw-r--r--doc/chromium/files/devkeys/kernel_data_key.vbprivk (renamed from doc/chromium/devkeys/kernel_data_key.vbprivk)bin1199 -> 1199 bytes
-rw-r--r--doc/chromium/files/nyan-big.its (renamed from doc/chromium/nyan-big.its)0
-rw-r--r--doc/chromium/index.rst14
-rw-r--r--doc/chromium/overview.rst74
-rw-r--r--doc/chromium/run_vboot.rst (renamed from doc/README.chromium)90
-rw-r--r--doc/device-tree-bindings/sysinfo/google,coral.txt37
-rw-r--r--doc/index.rst8
-rw-r--r--doc/usage/index.rst1
-rw-r--r--doc/usage/x86/cbsysinfo.rst25
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/block/sandbox.c8
-rw-r--r--drivers/gpio/intel_gpio.c14
-rw-r--r--drivers/misc/cbmem_console.c2
-rw-r--r--drivers/misc/cros_ec_sandbox.c4
-rw-r--r--drivers/misc/p2sb_emul.c1
-rw-r--r--drivers/mmc/pci_mmc.c6
-rw-r--r--drivers/mtd/spi/sf-uclass.c14
-rw-r--r--drivers/mtd/spi/sf_internal.h4
-rw-r--r--drivers/mtd/spi/sf_probe.c8
-rw-r--r--drivers/mtd/spi/spi-nor-core.c11
-rw-r--r--drivers/mtd/spi/spi-nor-tiny.c6
-rw-r--r--drivers/pci/pci_rom.c7
-rw-r--r--drivers/serial/serial_coreboot.c2
-rw-r--r--drivers/sound/tegra_i2s.c1
-rw-r--r--drivers/spi/spi-uclass.c11
-rw-r--r--drivers/timer/sandbox_timer.c3
-rw-r--r--drivers/timer/timer-uclass.c6
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/coreboot.c18
-rw-r--r--fs/cbfs/cbfs.c124
-rw-r--r--include/cbfs.h77
-rw-r--r--include/command.h10
-rw-r--r--include/configs/chromebook_coral.h6
-rw-r--r--include/dm/of_extra.h8
-rw-r--r--include/image.h5
-rw-r--r--include/malloc.h3
-rw-r--r--include/sandboxblockdev.h9
-rw-r--r--include/smbios.h20
-rw-r--r--include/spi_flash.h31
-rw-r--r--include/sysinfo.h4
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/binman.c4
-rw-r--r--lib/smbios-parser.c38
-rw-r--r--lib/smbios.c4
-rw-r--r--test/cmd/test_echo.c3
-rw-r--r--test/dm/sf.c10
-rw-r--r--test/lib/test_print.c8
-rw-r--r--tools/binman/binman.rst14
-rw-r--r--tools/binman/entries.rst21
-rw-r--r--tools/binman/entry.py16
-rw-r--r--tools/binman/etype/cbfs.py1
-rw-r--r--tools/binman/etype/collection.py67
-rw-r--r--tools/binman/etype/mkimage.py1
-rw-r--r--tools/binman/etype/section.py36
-rw-r--r--tools/binman/etype/u_boot.py2
-rw-r--r--tools/binman/etype/u_boot_spl.py2
-rw-r--r--tools/binman/etype/u_boot_tpl.py2
-rw-r--r--tools/binman/etype/vblock.py36
-rw-r--r--tools/binman/ftest.py57
-rw-r--r--tools/binman/test/196_symbols_nodtb.dts (renamed from tools/binman/test/192_symbols_nodtb.dts)0
-rw-r--r--tools/binman/test/197_symbols_expand.dts23
-rw-r--r--tools/binman/test/198_collection.dts27
-rw-r--r--tools/binman/test/199_collection_section.dts32
-rw-r--r--tools/binman/test/200_align_default.dts30
-rw-r--r--tools/dtoc/fdt.py92
-rw-r--r--tools/dtoc/test/dtoc_test_simple.dts4
-rwxr-xr-xtools/dtoc/test_fdt.py76
126 files changed, 3133 insertions, 812 deletions
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
index 327b74e20a..941d963ece 100644
--- a/arch/riscv/cpu/ax25/Kconfig
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -6,7 +6,7 @@ config RISCV_NDS
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
imply ANDES_PLMT_TIMER if (RISCV_MMODE || SPL_RISCV_MMODE)
- imply SPL_CPU_SUPPORT
+ imply SPL_CPU
imply SPL_OPENSBI
imply SPL_LOAD_FIT
help
diff --git a/arch/riscv/cpu/fu540/Kconfig b/arch/riscv/cpu/fu540/Kconfig
index 61bd5c426e..616b25650f 100644
--- a/arch/riscv/cpu/fu540/Kconfig
+++ b/arch/riscv/cpu/fu540/Kconfig
@@ -13,7 +13,7 @@ config SIFIVE_FU540
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply CMD_CPU
- imply SPL_CPU_SUPPORT
+ imply SPL_CPU
imply SPL_OPENSBI
imply SPL_LOAD_FIT
imply SMP
diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig
index f4c2e2643c..198e36e969 100644
--- a/arch/riscv/cpu/generic/Kconfig
+++ b/arch/riscv/cpu/generic/Kconfig
@@ -10,6 +10,6 @@ config GENERIC_RISCV
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply CMD_CPU
- imply SPL_CPU_SUPPORT
+ imply SPL_CPU
imply SPL_OPENSBI
imply SPL_LOAD_FIT
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index edd48e2c1b..48636ab639 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -6,7 +6,6 @@
#include <common.h>
#include <bootstage.h>
#include <cpu_func.h>
-#include <dm.h>
#include <errno.h>
#include <log.h>
#include <asm/global_data.h>
@@ -17,7 +16,6 @@
#include <asm/malloc.h>
#include <asm/setjmp.h>
#include <asm/state.h>
-#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -34,10 +32,8 @@ void sandbox_exit(void)
{
/* Do this here while it still has an effect */
os_fd_restore();
- if (state_uninit())
- os_exit(2);
- if (dm_uninit())
+ if (state_uninit())
os_exit(2);
/* This is considered normal termination for now */
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 68825d28d6..b9ad341861 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -711,7 +711,7 @@ static int add_args(char ***argvp, char *add_args[], int count)
* @fname: Filename to exec
* @return does not return on success, any return value is an error
*/
-static int os_jump_to_file(const char *fname)
+static int os_jump_to_file(const char *fname, bool delete_it)
{
struct sandbox_state *state = state_get_current();
char mem_fname[30];
@@ -734,11 +734,13 @@ static int os_jump_to_file(const char *fname)
os_fd_restore();
- extra_args[0] = "-j";
- extra_args[1] = (char *)fname;
- extra_args[2] = "-m";
- extra_args[3] = mem_fname;
- argc = 4;
+ argc = 0;
+ if (delete_it) {
+ extra_args[argc++] = "-j";
+ extra_args[argc++] = (char *)fname;
+ }
+ extra_args[argc++] = "-m";
+ extra_args[argc++] = mem_fname;
if (state->ram_buf_rm)
extra_args[argc++] = "--rm_memory";
err = add_args(&argv, extra_args, argc);
@@ -762,7 +764,10 @@ static int os_jump_to_file(const char *fname)
return err;
}
- return unlink(fname);
+ if (delete_it)
+ return unlink(fname);
+
+ return -EFAULT;
}
int os_jump_to_image(const void *dest, int size)
@@ -774,7 +779,7 @@ int os_jump_to_image(const void *dest, int size)
if (err)
return err;
- return os_jump_to_file(fname);
+ return os_jump_to_file(fname, true);
}
int os_find_u_boot(char *fname, int maxlen, bool use_img)
@@ -847,7 +852,8 @@ int os_spl_to_uboot(const char *fname)
/* U-Boot will delete ram buffer after read: "--rm_memory"*/
state->ram_buf_rm = true;
- return os_jump_to_file(fname);
+
+ return os_jump_to_file(fname, false);
}
long os_get_time_offset(void)
diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds
index 936da5e140..a1f509c9ab 100644
--- a/arch/sandbox/cpu/u-boot.lds
+++ b/arch/sandbox/cpu/u-boot.lds
@@ -44,6 +44,13 @@ SECTIONS
{
*(.__efi_runtime_rel_stop)
}
+
+ .dynsym :
+ {
+ __dyn_sym_start = .;
+ *(.dynsym)
+ __dyn_sym_end = .;
+ }
}
INSERT BEFORE .data;
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 69d7d3019e..31db50db35 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -200,6 +200,10 @@
compatible = "sandbox,reset";
};
+ rng {
+ compatible = "sandbox,sandbox-rng";
+ };
+
sound {
compatible = "sandbox,sound";
cpu {
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5b089af699..970bdff37f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1047,4 +1047,25 @@ config INTEL_GMA_SWSMISCI
endif # INTEL_SOC
+config COREBOOT_SYSINFO
+ bool "Support reading coreboot sysinfo"
+ default y if SYS_COREBOOT
+ help
+ Select this option to read the coreboot sysinfo table on start-up,
+ if present. This is written by coreboot before it exits and provides
+ various pieces of information about the running system, including
+ display, memory and build information. It is stored in
+ struct sysinfo_t after parsing by get_coreboot_info().
+
+config SPL_COREBOOT_SYSINFO
+ bool "Support reading coreboot sysinfo"
+ depends on SPL
+ default y if COREBOOT_SYSINFO
+ help
+ Select this option to read the coreboot sysinfo table in SPL,
+ if present. This is written by coreboot before it exits and provides
+ various pieces of information about the running system, including
+ display, memory and build information. It is stored in
+ struct sysinfo_t after parsing by get_coreboot_info().
+
endmenu
diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
index fbc016d0e0..647c9df6a7 100644
--- a/arch/x86/cpu/apollolake/cpu.c
+++ b/arch/x86/cpu/apollolake/cpu.c
@@ -19,6 +19,7 @@
#include <asm/arch/iomap.h>
#include <dm/acpi.h>
+#ifdef CONFIG_ACPIGEN
#define CSTATE_RES(address_space, width, offset, address) \
{ \
.space_id = address_space, \
@@ -57,11 +58,6 @@ static struct acpi_cstate cstate_map[] = {
},
};
-static int apl_get_info(const struct udevice *dev, struct cpu_info *info)
-{
- return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
-}
-
static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
{
uint core_id = dev_seq(dev);
@@ -89,6 +85,12 @@ static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
return 0;
}
+#endif /* CONFIG_ACPIGEN */
+
+static int apl_get_info(const struct udevice *dev, struct cpu_info *info)
+{
+ return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
+}
static void update_fixed_mtrrs(void)
{
@@ -170,9 +172,11 @@ static int cpu_apl_probe(struct udevice *dev)
return 0;
}
+#ifdef CONFIG_ACPIGEN
struct acpi_ops apl_cpu_acpi_ops = {
.fill_ssdt = acpi_cpu_fill_ssdt,
};
+#endif
static const struct cpu_ops cpu_x86_apl_ops = {
.get_desc = cpu_x86_get_desc,
diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c
index 63f6999b02..5d7d26b140 100644
--- a/arch/x86/cpu/apollolake/cpu_common.c
+++ b/arch/x86/cpu/apollolake/cpu_common.c
@@ -7,11 +7,17 @@
#include <dm.h>
#include <log.h>
#include <asm/cpu_common.h>
+#include <asm/io.h>
#include <asm/msr.h>
+#include <asm/pci.h>
#include <asm/arch/cpu.h>
#include <asm/arch/iomap.h>
+#include <asm/arch/uart.h>
#include <power/acpi_pmc.h>
+/* Define this here to avoid referencing any drivers for the debug UART 1 */
+#define PCH_DEV_P2SB PCI_BDF(0, 0x0d, 0)
+
void cpu_flush_l1d_to_l2(void)
{
struct msr_t msr;
@@ -40,3 +46,57 @@ void enable_pm_timer_emulation(const struct udevice *pmc)
debug("PM timer %x %x\n", msr.hi, msr.lo);
msr_write(MSR_EMULATE_PM_TIMER, msr);
}
+
+static void pch_uart_init(void)
+{
+ /*
+ * Set up the pinmux so that the UART rx/tx signals are connected
+ * outside the SoC.
+ *
+ * There are about 500 lines of code required to program the GPIO
+ * configuration for the UARTs. But it boils down to four writes, and
+ * for the debug UART we want the minimum possible amount of code before
+ * the UART is running. So just add the magic writes here. See
+ * apl_hostbridge_early_init_pinctrl() for the full horror.
+ */
+ if (PCI_FUNC(PCH_DEV_UART) == 1) {
+ writel(0x40000402, 0xd0c50650);
+ writel(0x3c47, 0xd0c50654);
+ writel(0x40000400, 0xd0c50658);
+ writel(0x3c48, 0xd0c5065c);
+ } else { /* UART2 */
+ writel(0x40000402, 0xd0c50670);
+ writel(0x3c4b, 0xd0c50674);
+ writel(0x40000400, 0xd0c50678);
+ writel(0x3c4c, 0xd0c5067c);
+ }
+
+#ifdef CONFIG_DEBUG_UART
+ apl_uart_init(PCH_DEV_UART, CONFIG_DEBUG_UART_BASE);
+#endif
+}
+
+static void p2sb_enable_bar(ulong bar)
+{
+ /* Enable PCR Base address in PCH */
+ pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, bar,
+ PCI_SIZE_32);
+ pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
+
+ /* Enable P2SB MSE */
+ pci_x86_write_config(PCH_DEV_P2SB, PCI_COMMAND,
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY,
+ PCI_SIZE_8);
+}
+
+/*
+ * board_debug_uart_init() - Init the debug UART ready for use
+ *
+ * This is the minimum init needed to get the UART running. It avoids any
+ * drivers or complex code, so that the UART is running as soon as possible.
+ */
+void board_debug_uart_init(void)
+{
+ p2sb_enable_bar(IOMAP_P2SB_BAR);
+ pch_uart_init();
+}
diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
index 9a18476b22..8f48457ee2 100644
--- a/arch/x86/cpu/apollolake/cpu_spl.c
+++ b/arch/x86/cpu/apollolake/cpu_spl.c
@@ -31,68 +31,10 @@
#include <asm/arch/lpc.h>
#include <asm/arch/pch.h>
#include <asm/arch/systemagent.h>
-#include <asm/arch/uart.h>
#include <asm/fsp2/fsp_api.h>
#include <linux/sizes.h>
#include <power/acpi_pmc.h>
-/* Define this here to avoid referencing any drivers for the debug UART 1 */
-#define PCH_DEV_P2SB PCI_BDF(0, 0x0d, 0)
-
-static void pch_uart_init(void)
-{
- /*
- * Set up the pinmux so that the UART rx/tx signals are connected
- * outside the SoC.
- *
- * There are about 500 lines of code required to program the GPIO
- * configuration for the UARTs. But it boils down to four writes, and
- * for the debug UART we want the minimum possible amount of code before
- * the UART is running. So just add the magic writes here. See
- * apl_hostbridge_early_init_pinctrl() for the full horror.
- */
- if (PCI_FUNC(PCH_DEV_UART) == 1) {
- writel(0x40000402, 0xd0c50650);
- writel(0x3c47, 0xd0c50654);
- writel(0x40000400, 0xd0c50658);
- writel(0x3c48, 0xd0c5065c);
- } else { /* UART2 */
- writel(0x40000402, 0xd0c50670);
- writel(0x3c4b, 0xd0c50674);
- writel(0x40000400, 0xd0c50678);
- writel(0x3c4c, 0xd0c5067c);
- }
-
-#ifdef CONFIG_DEBUG_UART
- apl_uart_init(PCH_DEV_UART, CONFIG_DEBUG_UART_BASE);
-#endif
-}
-
-static void p2sb_enable_bar(ulong bar)
-{
- /* Enable PCR Base address in PCH */
- pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, bar,
- PCI_SIZE_32);
- pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
-
- /* Enable P2SB MSE */
- pci_x86_write_config(PCH_DEV_P2SB, PCI_COMMAND,
- PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY,
- PCI_SIZE_8);
-}
-
-/*
- * board_debug_uart_init() - Init the debug UART ready for use
- *
- * This is the minimum init needed to get the UART running. It avoids any
- * drivers or complex code, so that the UART is running as soon as possible.
- */
-void board_debug_uart_init(void)
-{
- p2sb_enable_bar(IOMAP_P2SB_BAR);
- pch_uart_init();
-}
-
static int fast_spi_cache_bios_region(void)
{
uint map_size, offset;
diff --git a/arch/x86/cpu/coreboot/Makefile b/arch/x86/cpu/coreboot/Makefile
index 605f90304e..a6cdb9a148 100644
--- a/arch/x86/cpu/coreboot/Makefile
+++ b/arch/x86/cpu/coreboot/Makefile
@@ -20,5 +20,4 @@ else
obj-y += sdram.o
endif
obj-y += coreboot.o
-obj-y += tables.o
obj-y += timestamp.o
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 15c3ad879a..69cf8f417c 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -14,7 +14,7 @@
#include <asm/io.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
#include <asm/arch/timestamp.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index a2e47d196a..4a256bad44 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -8,7 +8,7 @@
#include <common.h>
#include <init.h>
#include <asm/e820.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -16,32 +16,7 @@ DECLARE_GLOBAL_DATA_PTR;
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
- unsigned int num_entries;
- int i;
-
- num_entries = min((unsigned int)lib_sysinfo.n_memranges, max_entries);
- if (num_entries < lib_sysinfo.n_memranges) {
- printf("Warning: Limiting e820 map to %d entries.\n",
- num_entries);
- }
- for (i = 0; i < num_entries; i++) {
- struct memrange *memrange = &lib_sysinfo.memrange[i];
-
- entries[i].addr = memrange->base;
- entries[i].size = memrange->size;
-
- /*
- * coreboot has some extensions (type 6 & 16) to the E820 types.
- * When we detect this, mark it as E820_RESERVED.
- */
- if (memrange->type == CB_MEM_VENDOR_RSVD ||
- memrange->type == CB_MEM_TABLE)
- entries[i].type = E820_RESERVED;
- else
- entries[i].type = memrange->type;
- }
-
- return num_entries;
+ return cb_install_e820_map(max_entries, entries);
}
/*
diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c
deleted file mode 100644
index c52741ac9d..0000000000
--- a/arch/x86/cpu/coreboot/tables.c
+++ /dev/null
@@ -1,255 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * This file is part of the libpayload project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2009 coresystems GmbH
- */
-
-#include <common.h>
-#include <net.h>
-#include <asm/arch/sysinfo.h>
-#include <asm/global_data.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/*
- * This needs to be in the .data section so that it's copied over during
- * relocation. By default it's put in the .bss section which is simply filled
- * with zeroes when transitioning from "ROM", which is really RAM, to other
- * RAM.
- */
-struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
-
-/*
- * Some of this is x86 specific, and the rest of it is generic. Right now,
- * since we only support x86, we'll avoid trying to make lots of infrastructure
- * we don't need. If in the future, we want to use coreboot on some other
- * architecture, then take out the generic parsing code and move it elsewhere.
- */
-
-/* === Parsing code === */
-/* This is the generic parsing code. */
-
-static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
-{
- struct cb_memory *mem = (struct cb_memory *)ptr;
- int count = MEM_RANGE_COUNT(mem);
- int i;
-
- if (count > SYSINFO_MAX_MEM_RANGES)
- count = SYSINFO_MAX_MEM_RANGES;
-
- info->n_memranges = 0;
-
- for (i = 0; i < count; i++) {
- struct cb_memory_range *range =
- (struct cb_memory_range *)MEM_RANGE_PTR(mem, i);
-
- info->memrange[info->n_memranges].base =
- UNPACK_CB64(range->start);
-
- info->memrange[info->n_memranges].size =
- UNPACK_CB64(range->size);
-
- info->memrange[info->n_memranges].type = range->type;
-
- info->n_memranges++;
- }
-}
-
-static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
-{
- struct cb_serial *ser = (struct cb_serial *)ptr;
- info->serial = ser;
-}
-
-static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
-{
- struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr;
-
- info->vbnv_start = vbnv->vbnv_start;
- info->vbnv_size = vbnv->vbnv_size;
-}
-
-static void cb_parse_cbmem_entry(unsigned char *ptr, struct sysinfo_t *info)
-{
- struct cb_cbmem_entry *entry = (struct cb_cbmem_entry *)ptr;
-
- if (entry->id != CBMEM_ID_SMBIOS)
- return;
-
- info->smbios_start = entry->address;
- info->smbios_size = entry->entry_size;
-}
-
-static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
-{
- int i;
- struct cb_gpios *gpios = (struct cb_gpios *)ptr;
-
- info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
- (gpios->count) : SYSINFO_MAX_GPIOS;
-
- for (i = 0; i < info->num_gpios; i++)
- info->gpios[i] = gpios->gpios[i];
-}
-
-static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
-{
- struct cb_vdat *vdat = (struct cb_vdat *) ptr;
-
- info->vdat_addr = vdat->vdat_addr;
- info->vdat_size = vdat->vdat_size;
-}
-
-static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info)
-{
- info->tstamp_table = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
-}
-
-static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)
-{
- info->cbmem_cons = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
-}
-
-static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
-{
- info->framebuffer = (struct cb_framebuffer *)ptr;
-}
-
-static void cb_parse_string(unsigned char *ptr, char **info)
-{
- *info = (char *)((struct cb_string *)ptr)->string;
-}
-
-__weak void cb_parse_unhandled(u32 tag, unsigned char *ptr)
-{
-}
-
-static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
-{
- unsigned char *ptr = addr;
- struct cb_header *header;
- int i;
-
- header = (struct cb_header *)ptr;
- if (!header->table_bytes)
- return 0;
-
- /* Make sure the checksums match. */
- if (!ip_checksum_ok(header, sizeof(*header)))
- return -1;
-
- if (compute_ip_checksum(ptr + sizeof(*header), header->table_bytes) !=
- header->table_checksum)
- return -1;
-
- /* Now, walk the tables. */
- ptr += header->header_bytes;
-
- /* Inintialize some fields to sentinel values. */
- info->vbnv_start = info->vbnv_size = (uint32_t)(-1);
-
- for (i = 0; i < header->table_entries; i++) {
- struct cb_record *rec = (struct cb_record *)ptr;
-
- /* We only care about a few tags here (maybe more later). */
- switch (rec->tag) {
- case CB_TAG_FORWARD:
- return cb_parse_header(
- (void *)(unsigned long)
- ((struct cb_forward *)rec)->forward,
- len, info);
- continue;
- case CB_TAG_MEMORY:
- cb_parse_memory(ptr, info);
- break;
- case CB_TAG_SERIAL:
- cb_parse_serial(ptr, info);
- break;
- case CB_TAG_VERSION:
- cb_parse_string(ptr, &info->version);
- break;
- case CB_TAG_EXTRA_VERSION:
- cb_parse_string(ptr, &info->extra_version);
- break;
- case CB_TAG_BUILD:
- cb_parse_string(ptr, &info->build);
- break;
- case CB_TAG_COMPILE_TIME:
- cb_parse_string(ptr, &info->compile_time);
- break;
- case CB_TAG_COMPILE_BY:
- cb_parse_string(ptr, &info->compile_by);
- break;
- case CB_TAG_COMPILE_HOST:
- cb_parse_string(ptr, &info->compile_host);
- break;
- case CB_TAG_COMPILE_DOMAIN:
- cb_parse_string(ptr, &info->compile_domain);
- break;
- case CB_TAG_COMPILER:
- cb_parse_string(ptr, &info->compiler);
- break;
- case CB_TAG_LINKER:
- cb_parse_string(ptr, &info->linker);
- break;
- case CB_TAG_ASSEMBLER:
- cb_parse_string(ptr, &info->assembler);
- break;
- /*
- * FIXME we should warn on serial if coreboot set up a
- * framebuffer buf the payload does not know about it.
- */
- case CB_TAG_FRAMEBUFFER:
- cb_parse_framebuffer(ptr, info);
- break;
- case CB_TAG_GPIO:
- cb_parse_gpios(ptr, info);
- break;
- case CB_TAG_VDAT:
- cb_parse_vdat(ptr, info);
- break;
- case CB_TAG_TIMESTAMPS:
- cb_parse_tstamp(ptr, info);
- break;
- case CB_TAG_CBMEM_CONSOLE:
- cb_parse_cbmem_cons(ptr, info);
- break;
- case CB_TAG_VBNV:
- cb_parse_vbnv(ptr, info);
- break;
- case CB_TAG_CBMEM_ENTRY:
- cb_parse_cbmem_entry(ptr, info);
- break;
- default:
- cb_parse_unhandled(rec->tag, ptr);
- break;
- }
-
- ptr += rec->size;
- }
-
- return 1;
-}
-
-/* == Architecture specific == */
-/* This is the x86 specific stuff. */
-
-int get_coreboot_info(struct sysinfo_t *info)
-{
- long addr;
- int ret;
-
- addr = locate_coreboot_table();
- if (addr < 0)
- return addr;
- ret = cb_parse_header((void *)addr, 0x1000, info);
- if (!ret)
- return -ENOENT;
- gd->arch.coreboot_table = addr;
- gd->flags |= GD_FLG_SKIP_LL_INIT;
-
- return 0;
-}
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
index 0162597809..7f133cefae 100644
--- a/arch/x86/cpu/coreboot/timestamp.c
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -8,21 +8,9 @@
#include <common.h>
#include <bootstage.h>
#include <asm/arch/timestamp.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
#include <linux/compiler.h>
-struct timestamp_entry {
- uint32_t entry_id;
- uint64_t entry_stamp;
-} __packed;
-
-struct timestamp_table {
- uint64_t base_time;
- uint32_t max_entries;
- uint32_t num_entries;
- struct timestamp_entry entries[0]; /* Variable number of entries */
-} __packed;
-
static struct timestamp_table *ts_table __attribute__((section(".data")));
void timestamp_init(void)
diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S
index 905c825cdc..abfd4abb62 100644
--- a/arch/x86/cpu/start_from_spl.S
+++ b/arch/x86/cpu/start_from_spl.S
@@ -43,6 +43,10 @@ use_existing_stack:
call board_init_f_init_reserve
+#ifdef CONFIG_DEBUG_UART
+ call debug_uart_init
+#endif
+
call x86_cpu_reinit_f
xorl %eax, %eax
call board_init_f
diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
index d109a38759..c8cb4e21c6 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -47,6 +47,7 @@
i2c5 = &i2c_5;
i2c6 = &i2c_6;
i2c7 = &i2c_7;
+ mmc0 = &emmc;
mmc1 = &sdmmc;
};
@@ -55,6 +56,17 @@
recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>;
write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>;
phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>;
+ memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH
+ &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH
+ &gpio_n GPIO_38 GPIO_ACTIVE_HIGH
+ &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>;
+
+ /*
+ * This is used for reef only:
+ *
+ * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH
+ * &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>;
+ */
smbios {
/* Type 1 table */
system {
@@ -148,6 +160,11 @@
#interrupt-cells = <2>;
};
+ coreboot-video {
+ /* This will only activate when booted from coreboot */
+ compatible = "coreboot-fb";
+ };
+
keyboard {
intel,duplicate-por;
};
@@ -571,7 +588,7 @@
sdmmc: sdmmc@1b,0 {
reg = <0x0000d800 0 0 0 0>;
compatible = "intel,apl-sd";
- cd-gpios = <&gpio_n GPIO_177 GPIO_ACTIVE_LOW>;
+ cd-gpios = <&gpio_sw GPIO_177 GPIO_ACTIVE_LOW>;
acpi,name = "SDCD";
};
diff --git a/arch/x86/include/asm/arch-apollolake/uart.h b/arch/x86/include/asm/arch-apollolake/uart.h
index 38335b0490..c3ca171b83 100644
--- a/arch/x86/include/asm/arch-apollolake/uart.h
+++ b/arch/x86/include/asm/arch-apollolake/uart.h
@@ -6,6 +6,7 @@
#ifndef _ASM_ARCH_UART_H
#define _ASM_ARCH_UART_H
+#include <dt-structs.h>
#include <ns16550.h>
/**
diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h
deleted file mode 100644
index 419ec52933..0000000000
--- a/arch/x86/include/asm/arch-coreboot/sysinfo.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * This file is part of the libpayload project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- */
-
-#ifndef _COREBOOT_SYSINFO_H
-#define _COREBOOT_SYSINFO_H
-
-#include <asm/coreboot_tables.h>
-
-/* Maximum number of memory range definitions */
-#define SYSINFO_MAX_MEM_RANGES 32
-/* Allow a maximum of 8 GPIOs */
-#define SYSINFO_MAX_GPIOS 8
-
-struct sysinfo_t {
- int n_memranges;
- struct memrange {
- unsigned long long base;
- unsigned long long size;
- unsigned int type;
- } memrange[SYSINFO_MAX_MEM_RANGES];
-
- u32 cmos_range_start;
- u32 cmos_range_end;
- u32 cmos_checksum_location;
- u32 vbnv_start;
- u32 vbnv_size;
-
- char *version;
- char *extra_version;
- char *build;
- char *compile_time;
- char *compile_by;
- char *compile_host;
- char *compile_domain;
- char *compiler;
- char *linker;
- char *assembler;
-
- struct cb_framebuffer *framebuffer;
-
- int num_gpios;
- struct cb_gpio gpios[SYSINFO_MAX_GPIOS];
-
- void *vdat_addr;
- u32 vdat_size;
- void *tstamp_table;
- void *cbmem_cons;
- u64 smbios_start;
- u32 smbios_size;
-
- struct cb_serial *serial;
-};
-
-extern struct sysinfo_t lib_sysinfo;
-
-int get_coreboot_info(struct sysinfo_t *info);
-
-#endif
diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h
index 85d42c02c4..531526b314 100644
--- a/arch/x86/include/asm/arch-coreboot/timestamp.h
+++ b/arch/x86/include/asm/arch-coreboot/timestamp.h
@@ -8,30 +8,7 @@
#ifndef __COREBOOT_TIMESTAMP_H__
#define __COREBOOT_TIMESTAMP_H__
-enum timestamp_id {
- /* coreboot specific timestamp IDs */
- TS_START_ROMSTAGE = 1,
- TS_BEFORE_INITRAM = 2,
- TS_AFTER_INITRAM = 3,
- TS_END_ROMSTAGE = 4,
- TS_START_COPYRAM = 8,
- TS_END_COPYRAM = 9,
- TS_START_RAMSTAGE = 10,
- TS_DEVICE_ENUMERATE = 30,
- TS_DEVICE_CONFIGURE = 40,
- TS_DEVICE_ENABLE = 50,
- TS_DEVICE_INITIALIZE = 60,
- TS_DEVICE_DONE = 70,
- TS_CBMEM_POST = 75,
- TS_WRITE_TABLES = 80,
- TS_LOAD_PAYLOAD = 90,
- TS_ACPI_WAKE_JUMP = 98,
- TS_SELFBOOT_JUMP = 99,
-
- /* U-Boot entry IDs start at 1000 */
- TS_U_BOOT_INITTED = 1000, /* This is where u-boot starts */
- TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel. */
-};
+#include <asm/cb_sysinfo.h>
void timestamp_init(void);
void timestamp_add(enum timestamp_id id, uint64_t ts_time);
diff --git a/arch/x86/include/asm/cb_sysinfo.h b/arch/x86/include/asm/cb_sysinfo.h
new file mode 100644
index 0000000000..675eef6f2c
--- /dev/null
+++ b/arch/x86/include/asm/cb_sysinfo.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _COREBOOT_SYSINFO_H
+#define _COREBOOT_SYSINFO_H
+
+#include <asm/coreboot_tables.h>
+
+/* Maximum number of memory range definitions */
+#define SYSINFO_MAX_MEM_RANGES 32
+/* Allow a maximum of 8 GPIOs */
+#define SYSINFO_MAX_GPIOS 8
+/* Up to 10 MAC addresses */
+#define SYSINFO_MAX_MACS 10
+
+/**
+ * struct sysinfo_t - Information passed to U-Boot from coreboot
+ *
+ * Coreboot passes on a lot of information using a list of individual data
+ * structures identified by a numeric tag. These are parsed in U-Boot to produce
+ * this struct. Some of the pointers here point back to the tagged data
+ * structure, since it is assumed to remain around while U-Boot is running.
+ *
+ * The 'cbsysinfo' command can display this information.
+ *
+ * @cpu_khz: CPU frequence in KHz (e.g. 1100000)
+ * @serial: Pointer to the serial information, NULL if none
+ * @ser_ioport: Not actually provided by a tag and not used on modern hardware,
+ * which typicaally uses a memory-mapped port
+ * @ser_base: Not used at all, but present to match up with the coreboot data
+ * structure
+ * @n_memranges: Number of memory ranges
+ * @memrange: List of memory ranges:
+ * @base: Base address of range
+ * @size: Size of range in bytes
+ * @type: Type of range (CB_MEM_RAM, etc.)
+ * @option_table: Provides a pointer to the CMOS RAM options table, which
+ * indicates which options are available. The header is followed by a list
+ * of struct cb_cmos_entries records, so that an option can be found from
+ * its name. This is not used in U-Boot. NULL if not present
+ * @cmos_range_start: Start bit of the CMOS checksum range (in fact this must
+ * be a multiple of 8)
+ * @cmos_range_end: End bit of the CMOS checksum range (multiple of 8). This is
+ * the inclusive end.
+ * @cmos_checksum_location: Location of checksum, multiplied by 8. This is the
+ * byte offset into the CMOS RAM of the first checksum byte. The second one
+ * follows immediately. The checksum is a simple 16-bit sum of all the
+ * bytes from offset cmos_range_start / 8 to cmos_range_end / 8, inclusive,
+ * in big-endian format (so sum >> 8 is stored in the first byte).
+ * @vbnv_start: Start offset of CMOS RAM used for Chromium OS verified boot
+ * (typically 0x34)
+ * @vbnv_size: Number of bytes used by Chromium OS verified boot (typically
+ * 0x10)
+ * @extra_version: Extra version information, typically ""
+ * @build: Build date, e.g. "Wed Nov 18 02:51:58 UTC 2020"
+ * @compile_time: Compilation time, e.g. "02:51:58"
+ * @compile_by: Who compiled coreboot (never set?)
+ * @compile_host: Name of the machine that compiled coreboot (never set?)
+ * @compile_domain: Domain name of the machine that compiled coreboot (never
+ * set?)
+ * @compiler: Name of the compiler used to build coreboot (never set?)
+ * @linker: Name of the linker used to build coreboot (never set?)
+ * @assembler: Name of the assembler used to build coreboot (never set?)
+ * @cb_version: Coreboot version string, e.g. v1.9308_26_0.0.22-2599-g232f22c75d
+ * @framebuffer: Address of framebuffer tag, or NULL if none. See
+ * struct cb_framebuffer for the definition
+ * @num_gpios: Number of verified-boot GPIOs
+ * @gpios: List of GPIOs:
+ * @port: GPIO number, or 0xffffffff if not a GPIO
+ * @polarity: CB_GPIO_ACTIVE_LOW or CB_GPIO_ACTIVE_HIGH
+ * @value: Value of GPIO (0 or 1)
+ * @name: Name of GPIO
+ *
+ * A typical list is:
+ * id: port polarity val name
+ * 0: - active-high 1 write protect
+ * 1: - active-high 0 recovery
+ * 2: - active-high 1 lid
+ * 3: - active-high 0 power
+ * 4: - active-high 0 oprom
+ * 5: 29 active-high 0 EC in RW
+ *
+ * @num_macs: Number of MAC addresses
+ * @macs: List of MAC addresses
+ * @serialno: Serial number, or NULL (never set?)
+ * @mbtable: Address of the multiboot table, or NULL. This is a
+ * struct multiboot_header, not used in U-Boot
+ * @header: Address of header, if there is a CB_TAG_FORWARD, else NULL
+ * @mainboard: Pointer to mainboard info or NULL. Typically the vendor is
+ * "Google" and the part number is ""
+ * @vboot_handoff: Pointer to Chromium OS verified boot hand-off information.
+ * This is struct vboot_handoff, providing access to internal information
+ * generated by coreboot when this is being used
+ * @vboot_handoff_size: Size of hand-off information (typically 0xc0c)
+ * @vdat_addr: Pointer to Chromium OS verified boot data, which uses
+ * struct chromeos_acpi. It sits in the Intel Global NVS struct, after the
+ * first 0x100 bytes
+ * @vdat_size: Size of this data, typically 0xf00
+ * @smbios_start: Address of SMBIOS tables
+ * @smbios_size: Size of SMBIOS tables (e.g. 0x800)
+ * @x86_rom_var_mtrr_index: MTRR number used for ROM caching. Not used in U-Boot
+ * @tstamp_table: Pointer to timestamp_table, struct timestamp_table
+ * @cbmem_cons: Pointer to the console dump, struct cbmem_console. This provides
+ * access to the console output generated by coreboot, typically about 64KB
+ * and mostly PCI enumeration info
+ * @mrc_cache: Pointer to memory-reference-code cache, typically NULL
+ * acpi_gnvs: @Pointer to Intel Global NVS struct, see struct acpi_global_nvs
+ * @board_id: Board ID indicating the board variant, typically 0xffffffff
+ * @ram_code: RAM code indicating the SDRAM type, typically 0xffffffff
+ * @wifi_calibration: WiFi calibration info, NULL if none
+ * @ramoops_buffer: Address of kernel Ramoops buffer
+ * @ramoops_buffer_size: Sizeof of Ramoops buffer, typically 1MB
+ * @spi_flash: Information about SPI flash:
+ * @size: Size in bytes, e.g. 16MB
+ * @sector_size; Sector size of flash device, e.g. 4KB
+ * @erase_cmd: Command used to erase flash, or 0 if not used
+ * @fmap_offset: SPI-flash offset of the flash map (FMAP) table. This has a
+ * __FMAP__ header. It provides information about the different top-level
+ * sections in the SPI flash, e.g. 0x204000
+ * @cbfs_offset: SPI-flash offset of the Coreboot Filesystem (CBFS) used for
+ * read-only data, e.g. 0x205000. This is typically called 'COREBOOT' in
+ * the flash map. It holds various coreboot binaries as well as
+ * video-configuration files and graphics data for the Chromium OS
+ * verified boot user interface.
+ * @cbfs_size: Size of CBFS, e.g. 0x17b000
+ * @boot_media_size; Size of boot media (i.e. SPI flash), e.g. 16MB
+ * @mtc_start; Start of MTC region (Nvidia private data), 0 if not used. See
+ * https://chromium.googlesource.com/chromiumos/third_party/coreboot/+/chromeos-2013.04/src/soc/nvidia/tegra210/mtc.c
+ * @mtc_size: Size of MTC region
+ * @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning
+ * not used
+ */
+struct sysinfo_t {
+ unsigned int cpu_khz;
+ struct cb_serial *serial;
+ unsigned short ser_ioport;
+ unsigned long ser_base; // for mmapped serial
+
+ int n_memranges;
+
+ struct memrange {
+ unsigned long long base;
+ unsigned long long size;
+ unsigned int type;
+ } memrange[SYSINFO_MAX_MEM_RANGES];
+
+ struct cb_cmos_option_table *option_table;
+ u32 cmos_range_start;
+ u32 cmos_range_end;
+ u32 cmos_checksum_location;
+ u32 vbnv_start;
+ u32 vbnv_size;
+
+ char *version;
+ char *extra_version;
+ char *build;
+ char *compile_time;
+ char *compile_by;
+ char *compile_host;
+ char *compile_domain;
+ char *compiler;
+ char *linker;
+ char *assembler;
+
+ char *cb_version;
+
+ struct cb_framebuffer *framebuffer;
+
+ int num_gpios;
+ struct cb_gpio gpios[SYSINFO_MAX_GPIOS];
+ int num_macs;
+ struct mac_address macs[SYSINFO_MAX_MACS];
+ char *serialno;
+
+ unsigned long *mbtable; /** Pointer to the multiboot table */
+
+ struct cb_header *header;
+ struct cb_mainboard *mainboard;
+
+ void *vboot_handoff;
+ u32 vboot_handoff_size;
+ void *vdat_addr;
+ u32 vdat_size;
+ u64 smbios_start;
+ u32 smbios_size;
+
+ int x86_rom_var_mtrr_index;
+
+ void *tstamp_table;
+ void *cbmem_cons;
+ void *mrc_cache;
+ void *acpi_gnvs;
+ u32 board_id;
+ u32 ram_code;
+ void *wifi_calibration;
+ u64 ramoops_buffer;
+ u32 ramoops_buffer_size;
+ struct {
+ u32 size;
+ u32 sector_size;
+ u32 erase_cmd;
+ } spi_flash;
+ u64 fmap_offset;
+ u64 cbfs_offset;
+ u64 cbfs_size;
+ u64 boot_media_size;
+ u64 mtc_start;
+ u32 mtc_size;
+ void *chromeos_vpd;
+};
+
+extern struct sysinfo_t lib_sysinfo;
+
+int get_coreboot_info(struct sysinfo_t *info);
+
+#endif
diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h
index 7e1576768b..a74654bbe3 100644
--- a/arch/x86/include/asm/coreboot_tables.h
+++ b/arch/x86/include/asm/coreboot_tables.h
@@ -8,6 +8,106 @@
#ifndef _COREBOOT_TABLES_H
#define _COREBOOT_TABLES_H
+struct timestamp_entry {
+ u32 entry_id;
+ u64 entry_stamp;
+} __packed;
+
+struct timestamp_table {
+ u64 base_time;
+ u16 max_entries;
+ u16 tick_freq_mhz;
+ u32 num_entries;
+ struct timestamp_entry entries[0]; /* Variable number of entries */
+} __packed;
+
+enum timestamp_id {
+ /* coreboot-specific timestamp IDs */
+ TS_START_ROMSTAGE = 1,
+ TS_BEFORE_INITRAM = 2,
+ TS_AFTER_INITRAM = 3,
+ TS_END_ROMSTAGE = 4,
+ TS_START_VBOOT = 5,
+ TS_END_VBOOT = 6,
+ TS_START_COPYRAM = 8,
+ TS_END_COPYRAM = 9,
+ TS_START_RAMSTAGE = 10,
+ TS_START_BOOTBLOCK = 11,
+ TS_END_BOOTBLOCK = 12,
+ TS_START_COPYROM = 13,
+ TS_END_COPYROM = 14,
+ TS_START_ULZMA = 15,
+ TS_END_ULZMA = 16,
+ TS_START_ULZ4F = 17,
+ TS_END_ULZ4F = 18,
+ TS_DEVICE_ENUMERATE = 30,
+ TS_DEVICE_CONFIGURE = 40,
+ TS_DEVICE_ENABLE = 50,
+ TS_DEVICE_INITIALIZE = 60,
+ TS_DEVICE_DONE = 70,
+ TS_CBMEM_POST = 75,
+ TS_WRITE_TABLES = 80,
+ TS_FINALIZE_CHIPS = 85,
+ TS_LOAD_PAYLOAD = 90,
+ TS_ACPI_WAKE_JUMP = 98,
+ TS_SELFBOOT_JUMP = 99,
+
+ /* 500+ reserved for vendorcode extensions (500-600: google/chromeos) */
+ TS_START_COPYVER = 501,
+ TS_END_COPYVER = 502,
+ TS_START_TPMINIT = 503,
+ TS_END_TPMINIT = 504,
+ TS_START_VERIFY_SLOT = 505,
+ TS_END_VERIFY_SLOT = 506,
+ TS_START_HASH_BODY = 507,
+ TS_DONE_LOADING = 508,
+ TS_DONE_HASHING = 509,
+ TS_END_HASH_BODY = 510,
+ TS_START_COPYVPD = 550,
+ TS_END_COPYVPD_RO = 551,
+ TS_END_COPYVPD_RW = 552,
+
+ /* 940-950 reserved for vendorcode extensions (940-950: Intel ME) */
+ TS_ME_INFORM_DRAM_WAIT = 940,
+ TS_ME_INFORM_DRAM_DONE = 941,
+
+ /* 950+ reserved for vendorcode extensions (950-999: intel/fsp) */
+ TS_FSP_MEMORY_INIT_START = 950,
+ TS_FSP_MEMORY_INIT_END = 951,
+ TS_FSP_TEMP_RAM_EXIT_START = 952,
+ TS_FSP_TEMP_RAM_EXIT_END = 953,
+ TS_FSP_SILICON_INIT_START = 954,
+ TS_FSP_SILICON_INIT_END = 955,
+ TS_FSP_BEFORE_ENUMERATE = 956,
+ TS_FSP_AFTER_ENUMERATE = 957,
+ TS_FSP_BEFORE_FINALIZE = 958,
+ TS_FSP_AFTER_FINALIZE = 959,
+ TS_FSP_BEFORE_END_OF_FIRMWARE = 960,
+ TS_FSP_AFTER_END_OF_FIRMWARE = 961,
+
+ /* 1000+ reserved for payloads (1000-1200: ChromeOS depthcharge) */
+
+ /* U-Boot entry IDs start at 1000 */
+ TS_U_BOOT_INITTED = 1000, /* This is where U-Boot starts */
+
+ TS_RO_PARAMS_INIT = 1001,
+ TS_RO_VB_INIT = 1002,
+ TS_RO_VB_SELECT_FIRMWARE = 1003,
+ TS_RO_VB_SELECT_AND_LOAD_KERNEL = 1004,
+
+ TS_RW_VB_SELECT_AND_LOAD_KERNEL = 1010,
+
+ TS_VB_SELECT_AND_LOAD_KERNEL = 1020,
+ TS_VB_EC_VBOOT_DONE = 1030,
+ TS_VB_STORAGE_INIT_DONE = 1040,
+ TS_VB_READ_KERNEL_DONE = 1050,
+ TS_VB_VBOOT_DONE = 1100,
+
+ TS_START_KERNEL = 1101,
+ TS_KERNEL_DECOMPRESSION = 1102,
+ TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel */
+};
+
struct memory_area;
struct cbuint64 {
@@ -162,13 +262,14 @@ struct cb_framebuffer {
};
#define CB_TAG_GPIO 0x0013
-#define GPIO_MAX_NAME_LENGTH 16
-
+#define CB_GPIO_ACTIVE_LOW 0
+#define CB_GPIO_ACTIVE_HIGH 1
+#define CB_GPIO_MAX_NAME_LENGTH 16
struct cb_gpio {
u32 port;
u32 polarity;
u32 value;
- u8 name[GPIO_MAX_NAME_LENGTH];
+ u8 name[CB_GPIO_MAX_NAME_LENGTH];
};
struct cb_gpios {
@@ -181,61 +282,158 @@ struct cb_gpios {
#define CB_TAG_FDT 0x0014
struct cb_fdt {
- uint32_t tag;
- uint32_t size; /* size of the entire entry */
+ u32 tag;
+ u32 size; /* size of the entire entry */
/* the actual FDT gets placed here */
};
#define CB_TAG_VDAT 0x0015
struct cb_vdat {
- uint32_t tag;
- uint32_t size; /* size of the entire entry */
+ u32 tag;
+ u32 size; /* size of the entire entry */
void *vdat_addr;
- uint32_t vdat_size;
+ u32 vdat_size;
};
#define CB_TAG_TIMESTAMPS 0x0016
#define CB_TAG_CBMEM_CONSOLE 0x0017
+
+struct cbmem_console {
+ u32 size;
+ u32 cursor;
+ char body[0];
+} __packed;
+
#define CB_TAG_MRC_CACHE 0x0018
struct cb_cbmem_tab {
- uint32_t tag;
- uint32_t size;
- void *cbmem_tab;
+ u32 tag;
+ u32 size;
+ u64 cbmem_tab;
};
#define CB_TAG_VBNV 0x0019
struct cb_vbnv {
- uint32_t tag;
- uint32_t size;
- uint32_t vbnv_start;
- uint32_t vbnv_size;
+ u32 tag;
+ u32 size;
+ u32 vbnv_start;
+ u32 vbnv_size;
+};
+
+#define CB_TAG_VBOOT_HANDOFF 0x0020
+
+#define CB_TAG_X86_ROM_MTRR 0x0021
+struct cb_x86_rom_mtrr {
+ u32 tag;
+ u32 size;
+ /*
+ * The variable range MTRR index covering the ROM. If one wants to
+ * enable caching the ROM, the variable MTRR needs to be set to
+ * write-protect. To disable the caching after enabling set the
+ * type to uncacheable
+ */
+ u32 index;
+};
+
+#define CB_TAG_DMA 0x0022
+#define CB_TAG_RAM_OOPS 0x0023
+#define CB_TAG_ACPI_GNVS 0x0024
+
+#define CB_TAG_BOARD_ID 0x0025
+struct cb_board_id {
+ u32 tag;
+ u32 size;
+ /* Board ID as retrieved from the board revision GPIOs. */
+ u32 board_id;
+};
+
+#define CB_TAG_MAC_ADDRS 0x0026
+struct mac_address {
+ u8 mac_addr[6];
+ u8 pad[2]; /* Pad it to 8 bytes to keep it simple. */
+};
+
+struct cb_macs {
+ u32 tag;
+ u32 size;
+ u32 count;
+ struct mac_address mac_addrs[0];
+};
+
+#define CB_TAG_WIFI_CALIBRATION 0x0027
+
+#define CB_TAG_RAM_CODE 0x0028
+struct cb_ram_code {
+ u32 tag;
+ u32 size;
+ u32 ram_code;
+};
+
+#define CB_TAG_SPI_FLASH 0x0029
+struct cb_spi_flash {
+ u32 tag;
+ u32 size;
+ u32 flash_size;
+ u32 sector_size;
+ u32 erase_cmd;
+};
+
+#define CB_TAG_MTC 0x002b
+#define CB_TAG_VPD 0x002c
+struct lb_range {
+ u32 tag;
+ u32 size;
+ u64 range_start;
+ u32 range_size;
+};
+
+#define CB_TAG_BOOT_MEDIA_PARAMS 0x0030
+struct cb_boot_media_params {
+ u32 tag;
+ u32 size;
+ /* offsets are relative to start of boot media */
+ u64 fmap_offset;
+ u64 cbfs_offset;
+ u64 cbfs_size;
+ u64 boot_media_size;
};
-#define CB_TAG_CBMEM_ENTRY 0x0031
-#define CBMEM_ID_SMBIOS 0x534d4254
+#define CB_TAG_CBMEM_ENTRY 0x0031
+#define CBMEM_ID_SMBIOS 0x534d4254
struct cb_cbmem_entry {
- uint32_t tag;
- uint32_t size;
- uint64_t address;
- uint32_t entry_size;
- uint32_t id;
+ u32 tag;
+ u32 size;
+ u64 address;
+ u32 entry_size;
+ u32 id;
+};
+
+#define CB_TAG_TSC_INFO 0x0032
+struct cb_tsc_info {
+ u32 tag;
+ u32 size;
+
+ u32 freq_khz;
};
+#define CB_TAG_SERIALNO 0x002a
+#define CB_MAX_SERIALNO_LENGTH 32
+
#define CB_TAG_CMOS_OPTION_TABLE 0x00c8
struct cb_cmos_option_table {
u32 tag;
u32 size;
u32 header_length;
+ /* entries follow after this header */
};
#define CB_TAG_OPTION 0x00c9
-#define CMOS_MAX_NAME_LENGTH 32
+#define CB_CMOS_MAX_NAME_LENGTH 32
struct cb_cmos_entries {
u32 tag;
@@ -244,34 +442,33 @@ struct cb_cmos_entries {
u32 length;
u32 config;
u32 config_id;
- u8 name[CMOS_MAX_NAME_LENGTH];
+ u8 name[CB_CMOS_MAX_NAME_LENGTH];
};
#define CB_TAG_OPTION_ENUM 0x00ca
-#define CMOS_MAX_TEXT_LENGTH 32
-
+#define CB_CMOS_MAX_TEXT_LENGTH 32
struct cb_cmos_enums {
u32 tag;
u32 size;
u32 config_id;
u32 value;
- u8 text[CMOS_MAX_TEXT_LENGTH];
+ u8 text[CB_CMOS_MAX_TEXT_LENGTH];
};
#define CB_TAG_OPTION_DEFAULTS 0x00cb
-#define CMOS_IMAGE_BUFFER_SIZE 128
+#define CB_CMOS_IMAGE_BUFFER_SIZE 128
struct cb_cmos_defaults {
u32 tag;
u32 size;
u32 name_length;
- u8 name[CMOS_MAX_NAME_LENGTH];
- u8 default_set[CMOS_IMAGE_BUFFER_SIZE];
+ u8 name[CB_CMOS_MAX_NAME_LENGTH];
+ u8 default_set[CB_CMOS_IMAGE_BUFFER_SIZE];
};
#define CB_TAG_OPTION_CHECKSUM 0x00cc
-#define CHECKSUM_NONE 0
-#define CHECKSUM_PCBIOS 1
+#define CB_CHECKSUM_NONE 0
+#define CB_CHECKSUM_PCBIOS 1
struct cb_cmos_checksum {
u32 tag;
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index a66c0d2489..850a0a7a89 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -22,9 +22,23 @@ struct e820_entry {
#define ISA_START_ADDRESS 0xa0000
#define ISA_END_ADDRESS 0x100000
-/* Implementation defined function to install an e820 map */
+/* Implementation-defined function to install an e820 map */
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *);
+
+/**
+ * cb_install_e820_map() - Install e820 map provided by coreboot sysinfo
+ *
+ * This should be used when booting from coreboot, since in that case the
+ * memory areas are provided by coreboot in its sysinfo.
+ *
+ * @max_entries: Maximum number of entries to write
+ * @entries: Place to put entires
+ * @return number of entries written
+ */
+unsigned int cb_install_e820_map(unsigned int max_entries,
+ struct e820_entry *entries);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_E820_H */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 1bcbb49a61..65d9b3bd6a 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -15,6 +15,7 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_BOOTM) += bootm.o
endif
obj-y += cmd_boot.o
+obj-$(CONFIG_$(SPL_)COREBOOT_SYSINFO) += coreboot/
obj-$(CONFIG_SEABIOS) += coreboot_table.o
obj-y += early_cmos.o
obj-y += e820.o
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index aa5f0bf6b7..733dd71257 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -36,7 +36,7 @@ void bootm_announce_and_cleanup(void)
printf("\nStarting kernel ...\n\n");
#ifdef CONFIG_SYS_COREBOOT
- timestamp_add_now(TS_U_BOOT_START_KERNEL);
+ timestamp_add_now(TS_START_KERNEL);
#endif
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
#if CONFIG_IS_ENABLED(BOOTSTAGE_REPORT)
diff --git a/arch/x86/lib/coreboot/Makefile b/arch/x86/lib/coreboot/Makefile
new file mode 100644
index 0000000000..cb0ae1d017
--- /dev/null
+++ b/arch/x86/lib/coreboot/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2021 Google LLC
+#
+
+obj-y += cb_sysinfo.o
+obj-y += cb_support.o
diff --git a/arch/x86/lib/coreboot/cb_support.c b/arch/x86/lib/coreboot/cb_support.c
new file mode 100644
index 0000000000..ebb45cdfb5
--- /dev/null
+++ b/arch/x86/lib/coreboot/cb_support.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Support for booting from coreboot
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <asm/cb_sysinfo.h>
+#include <asm/e820.h>
+
+unsigned int cb_install_e820_map(unsigned int max_entries,
+ struct e820_entry *entries)
+{
+ unsigned int num_entries;
+ int i;
+
+ num_entries = min((unsigned int)lib_sysinfo.n_memranges, max_entries);
+ if (num_entries < lib_sysinfo.n_memranges) {
+ printf("Warning: Limiting e820 map to %d entries\n",
+ num_entries);
+ }
+ for (i = 0; i < num_entries; i++) {
+ struct memrange *memrange = &lib_sysinfo.memrange[i];
+
+ entries[i].addr = memrange->base;
+ entries[i].size = memrange->size;
+
+ /*
+ * coreboot has some extensions (type 6 & 16) to the E820 types.
+ * When we detect this, mark it as E820_RESERVED.
+ */
+ if (memrange->type == CB_MEM_VENDOR_RSVD ||
+ memrange->type == CB_MEM_TABLE)
+ entries[i].type = E820_RESERVED;
+ else
+ entries[i].type = memrange->type;
+ }
+
+ return num_entries;
+}
diff --git a/arch/x86/lib/coreboot/cb_sysinfo.c b/arch/x86/lib/coreboot/cb_sysinfo.c
new file mode 100644
index 0000000000..e2c65bfb1e
--- /dev/null
+++ b/arch/x86/lib/coreboot/cb_sysinfo.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 coresystems GmbH
+ */
+
+#include <common.h>
+#include <asm/cb_sysinfo.h>
+#include <init.h>
+#include <mapmem.h>
+#include <net.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This needs to be in the .data section so that it's copied over during
+ * relocation. By default it's put in the .bss section which is simply filled
+ * with zeroes when transitioning from "ROM", which is really RAM, to other
+ * RAM.
+ */
+struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
+
+/*
+ * Some of this is x86 specific, and the rest of it is generic. Right now,
+ * since we only support x86, we'll avoid trying to make lots of infrastructure
+ * we don't need. If in the future, we want to use coreboot on some other
+ * architecture, then take out the generic parsing code and move it elsewhere.
+ */
+
+/* === Parsing code === */
+/* This is the generic parsing code */
+
+static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_memory *mem = (struct cb_memory *)ptr;
+ int count = MEM_RANGE_COUNT(mem);
+ int i;
+
+ if (count > SYSINFO_MAX_MEM_RANGES)
+ count = SYSINFO_MAX_MEM_RANGES;
+
+ info->n_memranges = 0;
+
+ for (i = 0; i < count; i++) {
+ struct cb_memory_range *range =
+ (struct cb_memory_range *)MEM_RANGE_PTR(mem, i);
+
+ info->memrange[info->n_memranges].base =
+ UNPACK_CB64(range->start);
+
+ info->memrange[info->n_memranges].size =
+ UNPACK_CB64(range->size);
+
+ info->memrange[info->n_memranges].type = range->type;
+
+ info->n_memranges++;
+ }
+}
+
+static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_serial *ser = (struct cb_serial *)ptr;
+
+ info->serial = ser;
+}
+
+static void cb_parse_vboot_handoff(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct lb_range *vbho = (struct lb_range *)ptr;
+
+ info->vboot_handoff = (void *)(uintptr_t)vbho->range_start;
+ info->vboot_handoff_size = vbho->range_size;
+}
+
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct lb_range *vbnv = (struct lb_range *)ptr;
+
+ info->vbnv_start = vbnv->range_start;
+ info->vbnv_size = vbnv->range_size;
+}
+
+static void cb_parse_cbmem_entry(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_entry *entry = (struct cb_cbmem_entry *)ptr;
+
+ if (entry->id != CBMEM_ID_SMBIOS)
+ return;
+
+ info->smbios_start = entry->address;
+ info->smbios_size = entry->entry_size;
+}
+
+static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
+{
+ int i;
+ struct cb_gpios *gpios = (struct cb_gpios *)ptr;
+
+ info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
+ (gpios->count) : SYSINFO_MAX_GPIOS;
+
+ for (i = 0; i < info->num_gpios; i++)
+ info->gpios[i] = gpios->gpios[i];
+}
+
+static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct lb_range *vdat = (struct lb_range *)ptr;
+
+ info->vdat_addr = map_sysmem(vdat->range_start, vdat->range_size);
+ info->vdat_size = vdat->range_size;
+}
+
+static void cb_parse_mac_addresses(unsigned char *ptr,
+ struct sysinfo_t *info)
+{
+ struct cb_macs *macs = (struct cb_macs *)ptr;
+ int i;
+
+ info->num_macs = (macs->count < ARRAY_SIZE(info->macs)) ?
+ macs->count : ARRAY_SIZE(info->macs);
+
+ for (i = 0; i < info->num_macs; i++)
+ info->macs[i] = macs->mac_addrs[i];
+}
+
+static void cb_parse_tstamp(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = ptr;
+
+ info->tstamp_table = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+static void cb_parse_cbmem_cons(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = ptr;
+
+ info->cbmem_cons = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+static void cb_parse_acpi_gnvs(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+
+ info->acpi_gnvs = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+static void cb_parse_board_id(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_board_id *const cbbid = (struct cb_board_id *)ptr;
+
+ info->board_id = cbbid->board_id;
+}
+
+static void cb_parse_ram_code(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_ram_code *const ram_code = (struct cb_ram_code *)ptr;
+
+ info->ram_code = ram_code->ram_code;
+}
+
+static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info)
+{
+ /* ptr points to a coreboot table entry and is already virtual */
+ info->option_table = ptr;
+}
+
+static void cb_parse_checksum(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cmos_checksum *cmos_cksum = ptr;
+
+ info->cmos_range_start = cmos_cksum->range_start;
+ info->cmos_range_end = cmos_cksum->range_end;
+ info->cmos_checksum_location = cmos_cksum->location;
+}
+
+static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
+{
+ /* ptr points to a coreboot table entry and is already virtual */
+ info->framebuffer = ptr;
+}
+
+static void cb_parse_string(unsigned char *ptr, char **info)
+{
+ *info = (char *)((struct cb_string *)ptr)->string;
+}
+
+static void cb_parse_wifi_calibration(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+
+ info->wifi_calibration = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+static void cb_parse_ramoops(void *ptr, struct sysinfo_t *info)
+{
+ struct lb_range *ramoops = (struct lb_range *)ptr;
+
+ info->ramoops_buffer = ramoops->range_start;
+ info->ramoops_buffer_size = ramoops->range_size;
+}
+
+static void cb_parse_mtc(void *ptr, struct sysinfo_t *info)
+{
+ struct lb_range *mtc = (struct lb_range *)ptr;
+
+ info->mtc_start = mtc->range_start;
+ info->mtc_size = mtc->range_size;
+}
+
+static void cb_parse_spi_flash(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_spi_flash *flash = (struct cb_spi_flash *)ptr;
+
+ info->spi_flash.size = flash->flash_size;
+ info->spi_flash.sector_size = flash->sector_size;
+ info->spi_flash.erase_cmd = flash->erase_cmd;
+}
+
+static void cb_parse_boot_media_params(unsigned char *ptr,
+ struct sysinfo_t *info)
+{
+ struct cb_boot_media_params *const bmp =
+ (struct cb_boot_media_params *)ptr;
+
+ info->fmap_offset = bmp->fmap_offset;
+ info->cbfs_offset = bmp->cbfs_offset;
+ info->cbfs_size = bmp->cbfs_size;
+ info->boot_media_size = bmp->boot_media_size;
+}
+
+static void cb_parse_vpd(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+
+ info->chromeos_vpd = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+static void cb_parse_tsc_info(void *ptr, struct sysinfo_t *info)
+{
+ const struct cb_tsc_info *tsc_info = ptr;
+
+ if (tsc_info->freq_khz == 0)
+ return;
+
+ /* Honor the TSC frequency passed to the payload */
+ info->cpu_khz = tsc_info->freq_khz;
+}
+
+static void cb_parse_x86_rom_var_mtrr(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_x86_rom_mtrr *rom_mtrr = ptr;
+
+ info->x86_rom_var_mtrr_index = rom_mtrr->index;
+}
+
+static void cb_parse_mrc_cache(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+
+ info->mrc_cache = map_sysmem(cbmem->cbmem_tab, 0);
+}
+
+__weak void cb_parse_unhandled(u32 tag, unsigned char *ptr)
+{
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+ unsigned char *ptr = addr;
+ struct cb_header *header;
+ int i;
+
+ header = (struct cb_header *)ptr;
+ if (!header->table_bytes)
+ return 0;
+
+ /* Make sure the checksums match */
+ if (!ip_checksum_ok(header, sizeof(*header)))
+ return -1;
+
+ if (compute_ip_checksum(ptr + sizeof(*header), header->table_bytes) !=
+ header->table_checksum)
+ return -1;
+
+ info->header = header;
+
+ /*
+ * Board straps represented by numerical values are small numbers.
+ * Preset them to an invalid value in case the firmware does not
+ * supply the info.
+ */
+ info->board_id = ~0;
+ info->ram_code = ~0;
+
+ /* Now, walk the tables */
+ ptr += header->header_bytes;
+
+ /* Inintialize some fields to sentinel values */
+ info->vbnv_start = info->vbnv_size = (uint32_t)(-1);
+
+ for (i = 0; i < header->table_entries; i++) {
+ struct cb_record *rec = (struct cb_record *)ptr;
+
+ /* We only care about a few tags here (maybe more later) */
+ switch (rec->tag) {
+ case CB_TAG_FORWARD:
+ return cb_parse_header(
+ (void *)(unsigned long)
+ ((struct cb_forward *)rec)->forward,
+ len, info);
+ continue;
+ case CB_TAG_MEMORY:
+ cb_parse_memory(ptr, info);
+ break;
+ case CB_TAG_SERIAL:
+ cb_parse_serial(ptr, info);
+ break;
+ case CB_TAG_VERSION:
+ cb_parse_string(ptr, &info->cb_version);
+ break;
+ case CB_TAG_EXTRA_VERSION:
+ cb_parse_string(ptr, &info->extra_version);
+ break;
+ case CB_TAG_BUILD:
+ cb_parse_string(ptr, &info->build);
+ break;
+ case CB_TAG_COMPILE_TIME:
+ cb_parse_string(ptr, &info->compile_time);
+ break;
+ case CB_TAG_COMPILE_BY:
+ cb_parse_string(ptr, &info->compile_by);
+ break;
+ case CB_TAG_COMPILE_HOST:
+ cb_parse_string(ptr, &info->compile_host);
+ break;
+ case CB_TAG_COMPILE_DOMAIN:
+ cb_parse_string(ptr, &info->compile_domain);
+ break;
+ case CB_TAG_COMPILER:
+ cb_parse_string(ptr, &info->compiler);
+ break;
+ case CB_TAG_LINKER:
+ cb_parse_string(ptr, &info->linker);
+ break;
+ case CB_TAG_ASSEMBLER:
+ cb_parse_string(ptr, &info->assembler);
+ break;
+ case CB_TAG_CMOS_OPTION_TABLE:
+ cb_parse_optiontable(ptr, info);
+ break;
+ case CB_TAG_OPTION_CHECKSUM:
+ cb_parse_checksum(ptr, info);
+ break;
+ /*
+ * FIXME we should warn on serial if coreboot set up a
+ * framebuffer buf the payload does not know about it.
+ */
+ case CB_TAG_FRAMEBUFFER:
+ cb_parse_framebuffer(ptr, info);
+ break;
+ case CB_TAG_MAINBOARD:
+ info->mainboard = (struct cb_mainboard *)ptr;
+ break;
+ case CB_TAG_GPIO:
+ cb_parse_gpios(ptr, info);
+ break;
+ case CB_TAG_VDAT:
+ cb_parse_vdat(ptr, info);
+ break;
+ case CB_TAG_VBNV:
+ cb_parse_vbnv(ptr, info);
+ break;
+ case CB_TAG_VBOOT_HANDOFF:
+ cb_parse_vboot_handoff(ptr, info);
+ break;
+ case CB_TAG_MAC_ADDRS:
+ cb_parse_mac_addresses(ptr, info);
+ break;
+ case CB_TAG_SERIALNO:
+ cb_parse_string(ptr, &info->serialno);
+ break;
+ case CB_TAG_TIMESTAMPS:
+ cb_parse_tstamp(ptr, info);
+ break;
+ case CB_TAG_CBMEM_CONSOLE:
+ cb_parse_cbmem_cons(ptr, info);
+ break;
+ case CB_TAG_ACPI_GNVS:
+ cb_parse_acpi_gnvs(ptr, info);
+ break;
+ case CB_TAG_CBMEM_ENTRY:
+ cb_parse_cbmem_entry(ptr, info);
+ break;
+ case CB_TAG_BOARD_ID:
+ cb_parse_board_id(ptr, info);
+ break;
+ case CB_TAG_RAM_CODE:
+ cb_parse_ram_code(ptr, info);
+ break;
+ case CB_TAG_WIFI_CALIBRATION:
+ cb_parse_wifi_calibration(ptr, info);
+ break;
+ case CB_TAG_RAM_OOPS:
+ cb_parse_ramoops(ptr, info);
+ break;
+ case CB_TAG_SPI_FLASH:
+ cb_parse_spi_flash(ptr, info);
+ break;
+ case CB_TAG_MTC:
+ cb_parse_mtc(ptr, info);
+ break;
+ case CB_TAG_BOOT_MEDIA_PARAMS:
+ cb_parse_boot_media_params(ptr, info);
+ break;
+ case CB_TAG_TSC_INFO:
+ cb_parse_tsc_info(ptr, info);
+ break;
+ case CB_TAG_VPD:
+ cb_parse_vpd(ptr, info);
+ break;
+ case CB_TAG_X86_ROM_MTRR:
+ cb_parse_x86_rom_var_mtrr(rec, info);
+ break;
+ case CB_TAG_MRC_CACHE:
+ cb_parse_mrc_cache(rec, info);
+ break;
+ default:
+ cb_parse_unhandled(rec->tag, ptr);
+ break;
+ }
+
+ ptr += rec->size;
+ }
+
+ return 1;
+}
+
+/* == Architecture specific == */
+/* This is the x86 specific stuff */
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ long addr;
+ int ret;
+
+ addr = locate_coreboot_table();
+ if (addr < 0)
+ return addr;
+ ret = cb_parse_header((void *)addr, 0x1000, info);
+ if (!ret)
+ return -ENOENT;
+ gd->arch.coreboot_table = addr;
+ gd->flags |= GD_FLG_SKIP_LL_INIT;
+
+ return 0;
+}
+
+const struct sysinfo_t *cb_get_sysinfo(void)
+{
+ if (!ll_boot_init())
+ return &lib_sysinfo;
+
+ return NULL;
+}
diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index cc909e0e16..02fd05c9fa 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -87,7 +87,7 @@ static int fsp_video_probe(struct udevice *dev)
int ret;
if (!ll_boot_init())
- return 0;
+ return -ENODEV;
printf("Video: ");
diff --git a/arch/x86/lib/fsp2/fsp_init.c b/arch/x86/lib/fsp2/fsp_init.c
index 85cae54a0c..5afdce1e0d 100644
--- a/arch/x86/lib/fsp2/fsp_init.c
+++ b/arch/x86/lib/fsp2/fsp_init.c
@@ -84,7 +84,8 @@ static int get_cbfs_fsp(enum fsp_type_t type, ulong map_base,
struct cbfs_priv *cbfs;
int ret;
- ret = cbfs_init_mem(map_base + cbfs_base, &cbfs);
+ ret = cbfs_init_mem(map_base + cbfs_base, CBFS_SIZE_UNKNOWN, true,
+ &cbfs);
if (ret)
return ret;
if (!ret) {
diff --git a/arch/x86/lib/fsp2/fsp_support.c b/arch/x86/lib/fsp2/fsp_support.c
index 503f97d5f3..b2c7658245 100644
--- a/arch/x86/lib/fsp2/fsp_support.c
+++ b/arch/x86/lib/fsp2/fsp_support.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
+#include <init.h>
#include <log.h>
#include <spi_flash.h>
#include <asm/fsp/fsp_support.h>
@@ -114,6 +115,9 @@ u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
struct fsp_notify_params *params_ptr;
u32 status;
+ if (!ll_boot_init())
+ return 0;
+
if (!fsp_hdr)
fsp_hdr = gd->arch.fsp_s_hdr;
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 066dc404a2..67401b9ba7 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -18,6 +18,9 @@ int init_cache_f_r(void)
IS_ENABLED(CONFIG_FSP_VERSION2);
int ret;
+ if (!ll_boot_init())
+ return 0;
+
do_mtrr &= !IS_ENABLED(CONFIG_FSP_VERSION1) &&
!IS_ENABLED(CONFIG_SYS_SLIMBOOTLOADER);
@@ -31,9 +34,6 @@ int init_cache_f_r(void)
return ret;
}
- if (!ll_boot_init())
- return 0;
-
/* Initialise the CPU cache(s) */
return init_cache();
}
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index 1bae1f4f32..b18c1cd609 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -96,7 +96,7 @@ static int x86_spl_init(void)
}
#endif
preloader_console_init();
-#ifndef CONFIG_TPL
+#if !defined(CONFIG_TPL) && !CONFIG_IS_ENABLED(CPU)
ret = print_cpuinfo();
if (ret) {
debug("%s: print_cpuinfo() failed\n", __func__);
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 602788e016..90fc8a466d 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -18,6 +18,7 @@
#include <bootm.h>
#include <command.h>
#include <env.h>
+#include <init.h>
#include <irq_func.h>
#include <log.h>
#include <malloc.h>
@@ -28,6 +29,7 @@
#include <asm/byteorder.h>
#include <asm/bootm.h>
#include <asm/bootparam.h>
+#include <asm/global_data.h>
#ifdef CONFIG_SYS_COREBOOT
#include <asm/arch/timestamp.h>
#endif
@@ -35,6 +37,8 @@
#include <linux/ctype.h>
#include <linux/libfdt.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/*
* Memory lay-out:
*
@@ -309,8 +313,13 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
int bootproto = get_boot_protocol(hdr, false);
log_debug("Setup E820 entries\n");
- setup_base->e820_entries = install_e820_map(
- ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
+ if (ll_boot_init()) {
+ setup_base->e820_entries = install_e820_map(
+ ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
+ } else if (IS_ENABLED(CONFIG_COREBOOT_SYSINFO)) {
+ setup_base->e820_entries = cb_install_e820_map(
+ ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
+ }
if (bootproto == 0x0100) {
setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
diff --git a/board/coreboot/coreboot/coreboot.c b/board/coreboot/coreboot/coreboot.c
index 9aafb8920c..175d3ce691 100644
--- a/board/coreboot/coreboot/coreboot.c
+++ b/board/coreboot/coreboot/coreboot.c
@@ -4,7 +4,7 @@
*/
#include <common.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
#include <asm/global_data.h>
#include <init.h>
#include <smbios.h>
diff --git a/board/google/chromebook_coral/coral.c b/board/google/chromebook_coral/coral.c
index f9fb3f163f..3f9235c903 100644
--- a/board/google/chromebook_coral/coral.c
+++ b/board/google/chromebook_coral/coral.c
@@ -3,9 +3,12 @@
* Copyright 2019 Google LLC
*/
+#define LOG_CATEGORY UCLASS_SYSINFO
+
#include <common.h>
#include <bloblist.h>
#include <command.h>
+#include <cros_ec.h>
#include <dm.h>
#include <log.h>
#include <sysinfo.h>
@@ -15,6 +18,7 @@
#include <asm/intel_gnvs.h>
#include <asm/intel_pinctrl.h>
#include <dm/acpi.h>
+#include <linux/delay.h>
#include "variant_gpio.h"
struct cros_gpio_info {
@@ -29,10 +33,125 @@ int arch_misc_init(void)
return 0;
}
-/* This function is needed if CONFIG_CMDLINE is not enabled */
-int board_run_command(const char *cmdline)
+static int get_memconfig(struct udevice *dev)
{
- printf("No command line\n");
+ struct gpio_desc gpios[4];
+ int cfg;
+ int ret;
+
+ ret = gpio_request_list_by_name(dev, "memconfig-gpios", gpios,
+ ARRAY_SIZE(gpios),
+ GPIOD_IS_IN | GPIOD_PULL_UP);
+ if (ret < 0) {
+ log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret);
+ return ret;
+ }
+
+ /* Give the lines time to settle */
+ udelay(10);
+
+ ret = dm_gpio_get_values_as_int(gpios, ARRAY_SIZE(gpios));
+ if (ret < 0)
+ return log_msg_ret("get", ret);
+ cfg = ret;
+
+ ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios));
+ if (ret)
+ return log_msg_ret("free", ret);
+
+ return cfg;
+}
+
+/**
+ * get_skuconfig() - Get the SKU number either from pins or the EC
+ *
+ * Two options are supported:
+ * skuconfig-gpios - two pins in the device tree (tried first)
+ * EC - reading from the EC (backup)
+ *
+ * @dev: sysinfo device to use
+ * @return SKU ID, or -ve error if not found
+ */
+static int get_skuconfig(struct udevice *dev)
+{
+ struct gpio_desc gpios[2];
+ int cfg;
+ int ret;
+
+ ret = gpio_request_list_by_name(dev, "skuconfig-gpios", gpios,
+ ARRAY_SIZE(gpios),
+ GPIOD_IS_IN);
+ if (ret != ARRAY_SIZE(gpios)) {
+ struct udevice *cros_ec;
+
+ log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret);
+
+ /* Try the EC */
+ ret = uclass_first_device_err(UCLASS_CROS_EC, &cros_ec);
+ if (ret < 0) {
+ log_err("Cannot find EC for SKU details\n");
+ return log_msg_ret("sku", ret);
+ }
+ ret = cros_ec_get_sku_id(cros_ec);
+ if (ret < 0) {
+ log_err("Cannot read SKU details\n");
+ return log_msg_ret("sku", ret);
+ }
+
+ return ret;
+ }
+
+ ret = dm_gpio_get_values_as_int_base3(gpios, ARRAY_SIZE(gpios));
+ if (ret < 0)
+ return log_msg_ret("get", ret);
+ cfg = ret;
+
+ ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios));
+ if (ret)
+ return log_msg_ret("free", ret);
+
+ return cfg;
+}
+
+static int coral_get_str(struct udevice *dev, int id, size_t size, char *val)
+{
+ int ret;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD))
+ return -ENOSYS;
+
+ switch (id) {
+ case SYSINFO_ID_SMBIOS_SYSTEM_VERSION:
+ case SYSINFO_ID_SMBIOS_BASEBOARD_VERSION: {
+ ret = get_skuconfig(dev);
+
+ if (ret < 0)
+ return ret;
+ if (size < 15)
+ return -ENOSPC;
+ sprintf(val, "rev%d", ret);
+ break;
+ }
+ case SYSINFO_ID_BOARD_MODEL: {
+ int mem_config, sku_config;
+ const char *model;
+
+ ret = get_memconfig(dev);
+ if (ret < 0)
+ log_warning("Unable to read memconfig (err=%d)\n", ret);
+ mem_config = ret;
+ ret = get_skuconfig(dev);
+ if (ret < 0)
+ log_warning("Unable to read skuconfig (err=%d)\n", ret);
+ sku_config = ret;
+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ snprintf(val, size, "%s (memconfig %d, SKU %d)", model,
+ mem_config, sku_config);
+ break;
+ }
+ default:
+ return -ENOENT;
+ }
return 0;
}
@@ -45,12 +164,15 @@ int chromeos_get_gpio(const struct udevice *dev, const char *prop,
int ret;
ret = gpio_request_by_name((struct udevice *)dev, prop, 0, &desc, 0);
- if (ret == -ENOTBLK)
+ if (ret == -ENOTBLK) {
info->gpio_num = CROS_GPIO_VIRTUAL;
- else if (ret)
+ log_debug("GPIO '%s' is virtual\n", prop);
+ } else if (ret) {
return log_msg_ret("gpio", ret);
- else
+ } else {
info->gpio_num = desc.offset;
+ dm_gpio_free((struct udevice *)dev, &desc);
+ }
info->linux_name = dev_read_string(desc.dev, "linux-name");
if (!info->linux_name)
return log_msg_ret("linux-name", -ENOENT);
@@ -63,6 +185,8 @@ int chromeos_get_gpio(const struct udevice *dev, const char *prop,
}
info->flags = desc.flags & GPIOD_ACTIVE_LOW ? CROS_GPIO_ACTIVE_LOW :
CROS_GPIO_ACTIVE_HIGH;
+ if (!ret)
+ dm_gpio_free(desc.dev, &desc);
return 0;
}
@@ -81,11 +205,11 @@ static int chromeos_acpi_gpio_generate(const struct udevice *dev,
ret = chromeos_get_gpio(dev, "write-protect-gpios", CROS_GPIO_WP,
&info[1]);
if (ret)
- return log_msg_ret("rec", ret);
+ return log_msg_ret("wp", ret);
ret = chromeos_get_gpio(dev, "phase-enforce-gpios", CROS_GPIO_PE,
&info[2]);
if (ret)
- return log_msg_ret("rec", ret);
+ return log_msg_ret("phase", ret);
acpigen_write_scope(ctx, "\\");
acpigen_write_name(ctx, "OIPG");
acpigen_write_package(ctx, count);
@@ -145,6 +269,7 @@ struct acpi_ops coral_acpi_ops = {
};
struct sysinfo_ops coral_sysinfo_ops = {
+ .get_str = coral_get_str,
};
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
diff --git a/board/google/chromebook_coral/variant_gpio.h b/board/google/chromebook_coral/variant_gpio.h
index f516d88be5..403e2419a7 100644
--- a/board/google/chromebook_coral/variant_gpio.h
+++ b/board/google/chromebook_coral/variant_gpio.h
@@ -34,12 +34,6 @@
/* Determine if board is in final shipping mode. */
#define GPIO_SHIP_MODE GPIO_10
-/* Memory SKU GPIOs. */
-#define MEM_CONFIG3 GPIO_45
-#define MEM_CONFIG2 GPIO_38
-#define MEM_CONFIG1 GPIO_102
-#define MEM_CONFIG0 GPIO_101
-
/* DMIC_CONFIG_PIN: High for 1-DMIC and low for 4-DMIC's */
#define DMIC_CONFIG_PIN GPIO_17
diff --git a/cmd/Kconfig b/cmd/Kconfig
index e4bb1d4c4a..8ab34f3798 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2251,6 +2251,15 @@ config CMD_BEDBUG
for some PowerPC processors. For details please see the
documentation in doc/README.bedbug.
+config CMD_CBSYSINFO
+ bool "cbsysinfo"
+ depends on X86
+ default y if SYS_COREBOOT
+ help
+ This provides information about the coreboot sysinfo table stored in
+ memory by coreboot before jumping to U-Boot. It can be useful for
+ debugging the beaaviour of coreboot or U-Boot.
+
config CMD_DIAG
bool "diag - Board diagnostics"
help
diff --git a/cmd/acpi.c b/cmd/acpi.c
index 157261bffb..e5b9a1752b 100644
--- a/cmd/acpi.c
+++ b/cmd/acpi.c
@@ -187,10 +187,12 @@ static int do_acpi_dump(struct cmd_tbl *cmdtp, int flag, int argc,
return 0;
}
+#ifdef CONFIG_SYS_LONGHELP
static char acpi_help_text[] =
"list - list ACPI tables\n"
"acpi items [-d] - List/dump each piece of ACPI data from devices\n"
"acpi dump <name> - Dump ACPI table";
+#endif
U_BOOT_CMD_WITH_SUBCMDS(acpi, "ACPI tables", acpi_help_text,
U_BOOT_SUBCMD_MKENT(list, 1, 1, do_acpi_list),
diff --git a/cmd/bloblist.c b/cmd/bloblist.c
index 97b5734161..21e7ff67af 100644
--- a/cmd/bloblist.c
+++ b/cmd/bloblist.c
@@ -29,9 +29,11 @@ static int do_bloblist_list(struct cmd_tbl *cmdtp, int flag, int argc,
return 0;
}
+#ifdef CONFIG_SYS_LONGHELP
static char bloblist_help_text[] =
"info - show information about the bloblist\n"
"bloblist list - list blobs in the bloblist";
+#endif
U_BOOT_CMD_WITH_SUBCMDS(bloblist, "Bloblists", bloblist_help_text,
U_BOOT_SUBCMD_MKENT(info, 1, 1, do_bloblist_info),
diff --git a/cmd/host.c b/cmd/host.c
index 1d21f796ac..6aa3d9167a 100644
--- a/cmd/host.c
+++ b/cmd/host.c
@@ -41,17 +41,35 @@ static int do_host_save(struct cmd_tbl *cmdtp, int flag, int argc,
static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- if (argc < 2 || argc > 3)
- return CMD_RET_USAGE;
+ bool removable = false;
+ const char *dev_str;
+ char *file;
char *ep;
- char *dev_str = argv[1];
- char *file = argc >= 3 ? argv[2] : NULL;
- int dev = simple_strtoul(dev_str, &ep, 16);
+ int dev;
+
+ /* Skip 'bind' */
+ argc--;
+ argv++;
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[0], "-r")) {
+ removable = true;
+ argc--;
+ argv++;
+ }
+
+ if (argc > 2)
+ return CMD_RET_USAGE;
+ dev_str = argv[0];
+ dev = simple_strtoul(dev_str, &ep, 16);
if (*ep) {
printf("** Bad device specification %s **\n", dev_str);
return CMD_RET_USAGE;
}
- return !!host_dev_bind(dev, file);
+ file = argc > 1 ? argv[1] : NULL;
+
+ return !!host_dev_bind(dev, file, removable);
}
static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -146,7 +164,7 @@ static struct cmd_tbl cmd_host_sub[] = {
U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
- U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""),
+ U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
};
@@ -178,7 +196,8 @@ U_BOOT_CMD(
"host save hostfs - <addr> <filename> <bytes> [<offset>] - "
"save a file to host\n"
"host size hostfs - <filename> - determine size of file on host\n"
- "host bind <dev> [<filename>] - bind \"host\" device to file\n"
+ "host bind [-r] <dev> [<filename>] - bind \"host\" device to file\n"
+ " -r = mark as removable\n"
"host info [<dev>] - show device binding & info\n"
"host dev [<dev>] - Set or retrieve the current host device\n"
"host commands use the \"hostfs\" device. The \"host\" device is used\n"
diff --git a/cmd/version.c b/cmd/version.c
index 3686b87332..685b458ce2 100644
--- a/cmd/version.c
+++ b/cmd/version.c
@@ -9,7 +9,7 @@
#include <version.h>
#include <linux/compiler.h>
#ifdef CONFIG_SYS_COREBOOT
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
#endif
const char __weak version_string[] = U_BOOT_VERSION_STRING;
diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile
index 144b1cf5ab..5f82204c87 100644
--- a/cmd/x86/Makefile
+++ b/cmd/x86/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_CMD_CBSYSINFO) += cbsysinfo.o
obj-y += mtrr.o
obj-$(CONFIG_CMD_EXCEPTION) += exception.o
obj-$(CONFIG_USE_HOB) += hob.o
diff --git a/cmd/x86/cbsysinfo.c b/cmd/x86/cbsysinfo.c
new file mode 100644
index 0000000000..a0db0ad364
--- /dev/null
+++ b/cmd/x86/cbsysinfo.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <asm/cb_sysinfo.h>
+#include <command.h>
+#include <console.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void cbprompt(const char *name)
+{
+ for (; *name == '>'; name++)
+ puts(" ");
+ printf("%-12s: ", name);
+}
+
+static void print_dec(const char *name, int value)
+{
+ cbprompt(name);
+ printf(value > 9 ? "0d%d\n" : "%d\n", value);
+}
+
+static void print_hex(const char *name, int value)
+{
+ cbprompt(name);
+ printf("%x\n", value);
+}
+
+static void print_addr(const char *name, ulong value)
+{
+ cbprompt(name);
+ printf("%08lx\n", value);
+}
+
+static void print_addr64(const char *name, u64 value)
+{
+ cbprompt(name);
+ printf("%16llx\n", value);
+}
+
+static void print_ptr(const char *name, const void *value)
+{
+ cbprompt(name);
+ printf("%p\n", value);
+}
+
+static void print_str(const char *name, const char *value)
+{
+ if (value) {
+ cbprompt(name);
+ printf("%s\n", value);
+ }
+}
+
+static void print_idx(const char *name, uint idx, const u8 *strings)
+{
+ const char *ptr;
+
+ cbprompt(name);
+ ptr = (char *)strings + idx;
+ printf("%d: %s\n", idx, ptr ? ptr : "(unknown)");
+}
+
+static const char *const cb_mem_name[] = {
+ NULL,
+ "ram",
+ "reserved",
+ "acpi",
+ "nvs",
+ "unusable",
+ "vendor",
+};
+
+static const char *get_mem_name(int tag)
+{
+ if (tag >= CB_MEM_RAM && tag <= CB_MEM_VENDOR_RSVD)
+ return cb_mem_name[tag];
+
+ if (tag == CB_MEM_TABLE)
+ return "table";
+
+ return "(unknown)";
+}
+
+static const struct timestamp_id_to_name {
+ uint id;
+ const char *name;
+} timestamp_ids[] = {
+ /* Marker to report base_time */
+ { 0, "1st timestamp" },
+ { TS_START_ROMSTAGE, "start of romstage" },
+ { TS_BEFORE_INITRAM, "before ram initialization" },
+ { TS_AFTER_INITRAM, "after ram initialization" },
+ { TS_END_ROMSTAGE, "end of romstage" },
+ { TS_START_VBOOT, "start of verified boot" },
+ { TS_END_VBOOT, "end of verified boot" },
+ { TS_START_COPYRAM, "starting to load ramstage" },
+ { TS_END_COPYRAM, "finished loading ramstage" },
+ { TS_START_RAMSTAGE, "start of ramstage" },
+ { TS_START_BOOTBLOCK, "start of bootblock" },
+ { TS_END_BOOTBLOCK, "end of bootblock" },
+ { TS_START_COPYROM, "starting to load romstage" },
+ { TS_END_COPYROM, "finished loading romstage" },
+ { TS_START_ULZMA, "starting LZMA decompress (ignore for x86)" },
+ { TS_END_ULZMA, "finished LZMA decompress (ignore for x86)" },
+ { TS_START_ULZ4F, "starting LZ4 decompress (ignore for x86)" },
+ { TS_END_ULZ4F, "finished LZ4 decompress (ignore for x86)" },
+ { TS_DEVICE_ENUMERATE, "device enumeration" },
+ { TS_DEVICE_CONFIGURE, "device configuration" },
+ { TS_DEVICE_ENABLE, "device enable" },
+ { TS_DEVICE_INITIALIZE, "device initialization" },
+ { TS_DEVICE_DONE, "device setup done" },
+ { TS_CBMEM_POST, "cbmem post" },
+ { TS_WRITE_TABLES, "write tables" },
+ { TS_FINALIZE_CHIPS, "finalize chips" },
+ { TS_LOAD_PAYLOAD, "load payload" },
+ { TS_ACPI_WAKE_JUMP, "ACPI wake jump" },
+ { TS_SELFBOOT_JUMP, "selfboot jump" },
+
+ { TS_START_COPYVER, "starting to load verstage" },
+ { TS_END_COPYVER, "finished loading verstage" },
+ { TS_START_TPMINIT, "starting to initialize TPM" },
+ { TS_END_TPMINIT, "finished TPM initialization" },
+ { TS_START_VERIFY_SLOT, "starting to verify keyblock/preamble (RSA)" },
+ { TS_END_VERIFY_SLOT, "finished verifying keyblock/preamble (RSA)" },
+ { TS_START_HASH_BODY, "starting to verify body (load+SHA2+RSA) " },
+ { TS_DONE_LOADING, "finished loading body (ignore for x86)" },
+ { TS_DONE_HASHING, "finished calculating body hash (SHA2)" },
+ { TS_END_HASH_BODY, "finished verifying body signature (RSA)" },
+
+ { TS_START_COPYVPD, "starting to load Chrome OS VPD" },
+ { TS_END_COPYVPD_RO, "finished loading Chrome OS VPD (RO)" },
+ { TS_END_COPYVPD_RW, "finished loading Chrome OS VPD (RW)" },
+
+ { TS_U_BOOT_INITTED, "U-Boot start" },
+ { TS_RO_PARAMS_INIT, "RO parameter init" },
+ { TS_RO_VB_INIT, "RO vboot init" },
+ { TS_RO_VB_SELECT_FIRMWARE, "RO vboot select firmware" },
+ { TS_RO_VB_SELECT_AND_LOAD_KERNEL, "RO vboot select&load kernel" },
+ { TS_RW_VB_SELECT_AND_LOAD_KERNEL, "RW vboot select&load kernel" },
+ { TS_VB_SELECT_AND_LOAD_KERNEL, "vboot select&load kernel" },
+ { TS_VB_EC_VBOOT_DONE, "finished EC verification" },
+ { TS_VB_STORAGE_INIT_DONE, "finished storage device initialization" },
+ { TS_VB_READ_KERNEL_DONE, "finished reading kernel from disk" },
+ { TS_VB_VBOOT_DONE, "finished vboot kernel verification" },
+ { TS_KERNEL_DECOMPRESSION, "starting kernel decompression/relocation" },
+ { TS_START_KERNEL, "jumping to kernel" },
+ { TS_U_BOOT_START_KERNEL, "just before jump to kernel" },
+
+ /* Intel ME-related timestamps */
+ { TS_ME_INFORM_DRAM_WAIT, "waiting for ME acknowledgment of raminit"},
+ { TS_ME_INFORM_DRAM_DONE, "finished waiting for ME response"},
+
+ /* FSP-related timestamps */
+ { TS_FSP_MEMORY_INIT_START, "calling FspMemoryInit" },
+ { TS_FSP_MEMORY_INIT_END, "returning from FspMemoryInit" },
+ { TS_FSP_TEMP_RAM_EXIT_START, "calling FspTempRamExit" },
+ { TS_FSP_TEMP_RAM_EXIT_END, "returning from FspTempRamExit" },
+ { TS_FSP_SILICON_INIT_START, "calling FspSiliconInit" },
+ { TS_FSP_SILICON_INIT_END, "returning from FspSiliconInit" },
+ { TS_FSP_BEFORE_ENUMERATE, "calling FspNotify(AfterPciEnumeration)" },
+ { TS_FSP_AFTER_ENUMERATE,
+ "returning from FspNotify(AfterPciEnumeration)" },
+ { TS_FSP_BEFORE_FINALIZE, "calling FspNotify(ReadyToBoot)" },
+ { TS_FSP_AFTER_FINALIZE, "returning from FspNotify(ReadyToBoot)" },
+ { TS_FSP_BEFORE_END_OF_FIRMWARE, "calling FspNotify(EndOfFirmware)" },
+ { TS_FSP_AFTER_END_OF_FIRMWARE,
+ "returning from FspNotify(EndOfFirmware)" },
+};
+
+static const char *timestamp_name(uint32_t id)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(timestamp_ids); i++) {
+ if (timestamp_ids[i].id == id)
+ return timestamp_ids[i].name;
+ }
+
+ return "<unknown>";
+}
+
+static void show_table(struct sysinfo_t *info, bool verbose)
+{
+ struct cb_serial *ser = info->serial;
+ int i;
+
+ printf("Coreboot table at %lx, decoded to %p",
+ gd->arch.coreboot_table, info);
+ if (info->header)
+ printf(", forwarded to %p\n", info->header);
+ printf("\n");
+
+ print_dec("CPU KHz", info->cpu_khz);
+
+ print_addr("Serial I/O port", info->ser_ioport);
+ print_addr(">base", info->ser_base);
+ print_ptr(">pointer", ser);
+ if (ser) {
+ print_hex(">type", ser->type);
+ print_addr(">base", ser->baseaddr);
+ print_dec(">baud", ser->baud);
+ print_hex(">baud", ser->regwidth);
+ print_dec(">input_hz", ser->input_hertz);
+ print_addr(">PCI addr", ser->uart_pci_addr);
+ }
+
+ print_dec("Mem ranges", info->n_memranges);
+ printf("%12s: %-11s || base || size\n", "id", "type");
+ for (i = 0; i < info->n_memranges; i++) {
+ const struct memrange *mr = &info->memrange[i];
+
+ printf("%12d: %02x:%-8s %016llx %016llx\n", i, mr->type,
+ get_mem_name(mr->type), mr->base, mr->size);
+ }
+ print_ptr("option_table", info->option_table);
+
+ print_hex("CMOS start", info->cmos_range_start);
+ if (info->cmos_range_start) {
+ print_hex(">CMOS end", info->cmos_range_end);
+ print_hex(">CMOS csum loc", info->cmos_checksum_location);
+ }
+
+ print_hex("VBNV start", info->vbnv_start);
+ print_hex("VBNV size", info->vbnv_size);
+
+ print_str("CB version", info->cb_version);
+ print_str(">Extra", info->extra_version);
+ print_str(">Build", info->build);
+ print_str(">Time", info->compile_time);
+ print_str(">By", info->compile_by);
+ print_str(">Host", info->compile_host);
+ print_str(">Domain", info->compile_domain);
+ print_str(">Compiler", info->compiler);
+ print_str(">Linker", info->linker);
+ print_str(">Assembler", info->assembler);
+
+ print_ptr("Framebuffer", info->framebuffer);
+ if (info->framebuffer) {
+ struct cb_framebuffer *fb = info->framebuffer;
+
+ print_addr64(">Phys addr", fb->physical_address);
+ print_dec(">X res", fb->x_resolution);
+ print_dec(">X res", fb->y_resolution);
+ print_hex(">Bytes / line", fb->bytes_per_line);
+ print_dec(">Bpp", fb->bits_per_pixel);
+ printf(" %-12s red %d/%d, green %d/%d, blue %d/%d, reserved %d/%d\n",
+ "pos/size", fb->red_mask_pos, fb->red_mask_size,
+ fb->green_mask_pos, fb->green_mask_size,
+ fb->blue_mask_pos, fb->blue_mask_size,
+ fb->reserved_mask_pos, fb->reserved_mask_size);
+ }
+
+ print_dec("GPIOs", info->num_gpios);
+ printf("%12s: %4s %12s %3s %s\n", "id", "port", "polarity", "val",
+ "name");
+ for (i = 0; i < info->num_gpios; i++) {
+ const struct cb_gpio *gpio = &info->gpios[i];
+ char portstr[4];
+
+ if (gpio->port == 0xffffffff)
+ strcpy(portstr, "-");
+ else
+ sprintf(portstr, "%x", gpio->port);
+ printf("%12d: %4s %12s %3d %s\n", i, portstr,
+ gpio->polarity == CB_GPIO_ACTIVE_LOW ? "active-low" :
+ "active-high", gpio->value, gpio->name);
+ }
+ print_dec("MACs", info->num_macs);
+ for (i = 0; i < info->num_macs; i++) {
+ const struct mac_address *mac = &info->macs[i];
+ int j;
+
+ printf("%12d: ", i);
+ for (j = 0; j < sizeof(mac->mac_addr); j++)
+ printf("%s%02x", j ? ":" : "", mac->mac_addr[j]);
+ printf("\n");
+ }
+ print_str(">Serial #", info->serialno);
+ print_ptr("Multiboot tab", info->mbtable);
+ print_ptr("CB header", info->header);
+ print_ptr("CB mainboard", info->mainboard);
+ if (info->mainboard) {
+ struct cb_mainboard *mb = info->mainboard;
+
+ print_idx(">vendor", mb->vendor_idx, mb->strings);
+ print_idx(">part_number", mb->part_number_idx, mb->strings);
+ }
+ print_ptr("vboot handoff", info->vboot_handoff);
+ print_hex(">size", info->vboot_handoff_size);
+ print_ptr(">vdat addr", info->vdat_addr);
+ print_hex(">size", info->vdat_size);
+
+ print_addr64("SMBIOS", info->smbios_start);
+ print_hex(">size", info->smbios_size);
+ print_hex("ROM MTRR", info->x86_rom_var_mtrr_index);
+
+ print_ptr("Tstamp table", info->tstamp_table);
+ if (verbose && info->tstamp_table) {
+ struct timestamp_table *ts = info->tstamp_table;
+
+ printf("%-12s", "Base_time");
+ print_grouped_ull(ts->base_time, 12);
+ printf("\n");
+ print_dec("Tick MHz", ts->tick_freq_mhz);
+ for (i = 0; i < ts->num_entries; i++) {
+ const struct timestamp_entry *tse;
+
+ tse = &ts->entries[i];
+ printf(" ");
+ print_grouped_ull(tse->entry_stamp, 12);
+ printf(" %s\n", timestamp_name(tse->entry_id));
+ }
+ }
+
+ print_ptr("CBmem cons", info->cbmem_cons);
+ if (info->cbmem_cons) {
+ struct cbmem_console *cons = info->cbmem_cons;
+ int i;
+
+ print_hex("Size", cons->size);
+ print_hex("Cursor", cons->cursor);
+ if (verbose) {
+ for (i = 0; i < cons->cursor; i++) {
+ int ch = cons->body[i];
+
+ putc(ch);
+
+ if (ch == '\n') {
+ /* check for ctrl-c to abort... */
+ if (ctrlc()) {
+ puts("Abort\n");
+ return;
+ }
+ printf(" ");
+ }
+ }
+ printf("\n");
+ }
+ }
+
+ print_ptr("MRC cache", info->mrc_cache);
+ print_ptr("ACPI GNVS", info->acpi_gnvs);
+ print_hex("Board ID", info->board_id);
+ print_hex("RAM code", info->ram_code);
+ print_ptr("WiFi calib", info->wifi_calibration);
+ print_addr64("Ramoops buff", info->ramoops_buffer);
+ print_hex(">size", info->ramoops_buffer_size);
+ print_hex("SF size", info->spi_flash.size);
+ print_hex("SF sector", info->spi_flash.sector_size);
+ print_hex("SF erase cmd", info->spi_flash.erase_cmd);
+
+ print_addr64("FMAP offset", info->fmap_offset);
+ print_addr64("CBFS offset", info->cbfs_offset);
+ print_addr64("CBFS size", info->cbfs_size);
+ print_addr64("Boot media size", info->boot_media_size);
+ print_addr64("MTC start", info->mtc_start);
+ print_hex("MTC size", info->mtc_size);
+
+ print_ptr("Chrome OS VPD", info->chromeos_vpd);
+}
+
+static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ bool verbose = false;
+
+ if (argc > 1) {
+ if (!strcmp("-v", argv[1]))
+ verbose = true;
+ else
+ return CMD_RET_USAGE;
+ }
+
+ if (!gd->arch.coreboot_table) {
+ printf("No coreboot sysinfo table found\n");
+ return CMD_RET_FAILURE;
+ }
+ show_table(&lib_sysinfo, verbose);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ cbsysinfo, 2, 1, do_cbsysinfo,
+ "Show coreboot sysinfo table",
+ "[-v] Dumps out the contents of the sysinfo table. This only\n"
+ "works if U-Boot is booted from coreboot"
+);
diff --git a/common/board_info.c b/common/board_info.c
index b54aa30a94..1cfe34f706 100644
--- a/common/board_info.c
+++ b/common/board_info.c
@@ -1,31 +1,52 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
+#include <dm.h>
#include <init.h>
+#include <sysinfo.h>
#include <asm/global_data.h>
#include <linux/libfdt.h>
#include <linux/compiler.h>
+DECLARE_GLOBAL_DATA_PTR;
+
int __weak checkboard(void)
{
return 0;
}
/*
- * If the root node of the DTB has a "model" property, show it.
+ * Check sysinfo for board information. Failing that if the root node of the DTB
+ * has a "model" property, show it.
+ *
* Then call checkboard().
*/
int __weak show_board_info(void)
{
-#ifdef CONFIG_OF_CONTROL
- DECLARE_GLOBAL_DATA_PTR;
- const char *model;
+ if (IS_ENABLED(CONFIG_OF_CONTROL)) {
+ struct udevice *dev;
+ const char *model;
+ char str[80];
+ int ret = -ENOSYS;
+
+ if (IS_ENABLED(CONFIG_SYSINFO)) {
+ /* This might provide more detail */
+ ret = uclass_first_device_err(UCLASS_SYSINFO, &dev);
+ if (!ret)
+ ret = sysinfo_get_str(dev,
+ SYSINFO_ID_BOARD_MODEL,
+ sizeof(str), str);
+ }
- model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ /* Fail back to the main 'model' if available */
+ if (ret)
+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ else
+ model = str;
- if (model)
- printf("Model: %s\n", model);
-#endif
+ if (model)
+ printf("Model: %s\n", model);
+ }
return checkboard();
}
diff --git a/common/bootm.c b/common/bootm.c
index dab7c3619f..ea71522d0c 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -583,7 +583,8 @@ int bootm_process_cmdline(char *buf, int maxlen, int flags)
if (ret)
return log_msg_ret("silent", ret);
}
- if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && (flags & BOOTM_CL_SUBST)) {
+ if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
+ (flags & BOOTM_CL_SUBST)) {
ret = process_subst(buf, maxlen);
if (ret)
return log_msg_ret("subst", ret);
diff --git a/common/bootstage.c b/common/bootstage.c
index 2c0110c263..4621105682 100644
--- a/common/bootstage.c
+++ b/common/bootstage.c
@@ -9,6 +9,8 @@
* permits accurate timestamping of each.
*/
+#define LOG_CATEGORY LOGC_BOOT
+
#include <common.h>
#include <bootstage.h>
#include <hang.h>
@@ -127,12 +129,16 @@ ulong bootstage_add_record(enum bootstage_id id, const char *name,
/* Only record the first event for each */
rec = find_id(data, id);
- if (!rec && data->rec_count < RECORD_COUNT) {
- rec = &data->record[data->rec_count++];
- rec->time_us = mark;
- rec->name = name;
- rec->flags = flags;
- rec->id = id;
+ if (!rec) {
+ if (data->rec_count < RECORD_COUNT) {
+ rec = &data->record[data->rec_count++];
+ rec->time_us = mark;
+ rec->name = name;
+ rec->flags = flags;
+ rec->id = id;
+ } else {
+ log_warning("Bootstage space exhasuted\n");
+ }
}
/* Tell the board about this progress */
diff --git a/common/image-fit.c b/common/image-fit.c
index 28b3d2b191..2d0ece6181 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1512,6 +1512,10 @@ int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
uint8_t image_arch;
int aarch32_support = 0;
+ /* Let's assume that sandbox can load any architecture */
+ if (IS_ENABLED(CONFIG_SANDBOX))
+ return true;
+
if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
aarch32_support = 1;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 584f8483e2..0711cbf951 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -500,7 +500,7 @@ config SPL_CACHE_SUPPORT
future requests for that data can be served faster. Enable this option
to build the drivers in drivers/cache as part of an SPL build.
-config SPL_CPU_SUPPORT
+config SPL_CPU
bool "Support CPU drivers"
help
Enable this to support CPU drivers in SPL. These drivers can set
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 5f51098a88..556a91ab53 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -387,6 +387,22 @@ static inline int write_spl_handoff(void) { return 0; }
#endif /* HANDOFF */
+/**
+ * get_bootstage_id() - Get the bootstage ID to emit
+ *
+ * @start: true if this is for starting SPL, false for ending it
+ * @return bootstage ID to use
+ */
+static enum bootstage_id get_bootstage_id(bool start)
+{
+ enum u_boot_phase phase = spl_phase();
+
+ if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
+ return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
+ else
+ return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
+}
+
static int spl_common_init(bool setup_malloc)
{
int ret;
@@ -417,8 +433,8 @@ static int spl_common_init(bool setup_malloc)
__func__, ret);
}
#endif /* CONFIG_BOOTSTAGE_STASH */
- bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_START_TPL :
- BOOTSTAGE_ID_START_SPL, SPL_TPL_NAME);
+ bootstage_mark_name(get_bootstage_id(true),
+ spl_phase_name(spl_phase()));
#if CONFIG_IS_ENABLED(LOG)
ret = log_init();
if (ret) {
@@ -733,8 +749,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr,
gd->malloc_ptr / 1024);
#endif
- bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_END_TPL :
- BOOTSTAGE_ID_END_SPL, "end " SPL_TPL_NAME);
+ bootstage_mark_name(get_bootstage_id(false), "end phase");
#ifdef CONFIG_BOOTSTAGE_STASH
ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig
index e3756cf79c..48239138c7 100644
--- a/configs/chromebook_coral_defconfig
+++ b/configs/chromebook_coral_defconfig
@@ -43,7 +43,7 @@ CONFIG_BLOBLIST_ADDR=0x100000
CONFIG_HANDOFF=y
CONFIG_TPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_SEPARATE_BSS=y
-CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_CPU=y
CONFIG_SPL_DM_SPI_FLASH=y
CONFIG_SPL_PCI=y
# CONFIG_SPL_SPI_FLASH_TINY is not set
diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig
index 8f56ee3476..872e33d757 100644
--- a/configs/chromebook_link64_defconfig
+++ b/configs/chromebook_link64_defconfig
@@ -31,7 +31,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_MISC_INIT_R=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_CPU=y
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_DM_SPI_FLASH=y
diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig
index 99a489cab4..4815d8af4e 100644
--- a/configs/qemu-x86_64_defconfig
+++ b/configs/qemu-x86_64_defconfig
@@ -31,7 +31,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_PCI_INIT_R=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_CPU=y
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_DM_SPI_FLASH=y
CONFIG_SPL_NET_SUPPORT=y
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 8b18a22117..e052b6bdb0 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -389,6 +389,8 @@ the contents of the root directory on the second partion of the image
=>host bind 0 ./disk.raw
=>ls host 0:2
+The device can be marked removeable with 'host bind -r'.
+
A disk image can be created using the following commands::
$> truncate -s 1200M ./disk.raw
diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst
index c39f1e310c..4b585678dc 100644
--- a/doc/board/google/chromebook_coral.rst
+++ b/doc/board/google/chromebook_coral.rst
@@ -16,6 +16,169 @@ Note that booting U-Boot on APL is already supported by coreboot and
Slim Bootloader. This documentation refers to a 'bare metal' port.
+Building
+--------
+
+First, you need the following binary blobs:
+
+ * descriptor.bin - Intel flash descriptor
+ * fitimage.bin - Base flash image structure
+ * fsp_m.bin - FSP-M, for setting up SDRAM
+ * fsp_s.bin - FSP-S, for setting up Silicon
+ * vbt.bin - for setting up display
+
+These binaries do not seem to be available publicly. If you have a ROM image,
+such as santa.bin then you can do this::
+
+ cbfstool santa.bin extract -n fspm.bin -f fsp-m.bin
+ cbfstool santa.bin extract -n fsps.bin -f fsp-s.bin
+ cbfstool santa.bin extract -n vbt-santa.bin -f vbt.bin
+ mkdir tmp
+ cd tmp
+ dump_fmap -x ../santa.bin
+ mv SI_DESC ../descriptor.bin
+ mv IFWI ../fitimage.bin
+
+Put all of these files in `board/google/chromebook_coral` so they can be found
+by the build.
+
+To build::
+
+ make O=/tmp/b/chromebook_coral chromebook_coral_defconfig
+ make O=/tmp/b/chromebook_coral -s -j30 all
+
+That should produce `/tmp/b/chrombook_coral/u-boot.rom` which you can use with
+a Dediprog em100::
+
+ em100 -s -c w25q128fw -d /tmp/b/chromebook_coral/u-boot.rom -r
+
+or you can use flashrom to write it to the board. If you do that, make sure you
+have a way to restore the old ROM without booting the board. Otherwise you may
+brick it. Having said that, you may find these instructions useful if you want
+to unbrick your device:
+
+ https://chromium.googlesource.com/chromiumos/platform/ec/+/cr50_stab/docs/case_closed_debugging.md
+
+You can buy Suzy-Q from Sparkfun:
+
+ https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/main/docs/ccd.md#suzyq-suzyqable
+
+Note that it will hang at the SPL prompt for 21 seconds. When booting into
+Chrome OS it will always select developer mode, so will wipe anything you have
+on the device if you let it proceed. You have two seconds in U-Boot to stop the
+auto-boot prompt and several seconds at the 'developer wipe' screen to stop it
+wiping the disk.
+
+Here is the console output::
+
+ U-Boot TPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
+ Trying to boot from Mapped SPI
+
+ U-Boot SPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
+ Trying to boot from Mapped SPI
+
+
+ U-Boot 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
+
+ CPU: Intel(R) Celeron(R) CPU N3450 @ 1.10GHz
+ DRAM: 3.9 GiB
+ MMC: sdmmc@1b,0: 1, emmc@1c,0: 2
+ Video: 1024x768x32 @ b0000000
+ Model: Google Coral
+ Net: No ethernet found.
+ SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+ Hit any key to stop autoboot: 0
+ cmdline=console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=${uuid}/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=${uuid} add_efi_memmap boot=local noresume noswap i915.modeset=1 Kernel command line: "console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=35c775e7-3735-d745-93e5-d9e0238f7ed0/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=35c775e7-3735-d745-93e5-d9e0238f7ed0 add_efi_memmap boot=local noresume noswap i915.modeset=1 tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic disablevmx=off "
+ Setup located at 00090000:
+
+ ACPI RSDP addr : 7991f000
+ E820: 14 entries
+ Addr Size Type
+ d0000000 1000000 <NULL>
+ 0 a0000 RAM
+ a0000 60000 Reserved
+ 7b000000 800000 Reserved
+ 7b800000 4800000 Reserved
+ 7ac00000 400000 Reserved
+ 100000 ff00000 RAM
+ 10000000 2151000 Reserved
+ 12151000 68aaf000 RAM
+ 100000000 80000000 RAM
+ e0000000 10000000 Reserved
+ 7991bfd0 12e4030 Reserved
+ d0000000 10000000 Reserved
+ fed10000 8000 Reserved
+ Setup sectors : 1e
+ Root flags : 1
+ Sys size : 63420
+ RAM size : 0
+ Video mode : ffff
+ Root dev : 0
+ Boot flag : 0
+ Jump : 66eb
+ Header : 53726448
+ Kernel V2
+ Version : 20d
+ Real mode switch : 0
+ Start sys : 1000
+ Kernel version : 38cc
+ @00003acc:
+ Type of loader : 80
+ U-Boot, version 0
+ Load flags : 81
+ : loaded-high can-use-heap
+ Setup move size : 8000
+ Code32 start : 100000
+ Ramdisk image : 0
+ Ramdisk size : 0
+ Bootsect kludge : 0
+ Heap end ptr : 8e00
+ Ext loader ver : 0
+ Ext loader type : 0
+ Command line ptr : 99000
+ console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=35c775e7-3735-d745-93e5-d9e0238f7ed0/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=35c775e7-3735-d745-93e5-d9e0238f7ed0 add_efi_memmap boot=local noresume noswap i915.modeset=1 tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic disablevmx=off
+ Initrd addr max : 7fffffff
+ Kernel alignment : 200000
+ Relocatable kernel : 1
+ Min alignment : 15
+ : 200000
+ Xload flags : 3
+ : 64-bit-entry can-load-above-4gb
+ Cmdline size : 7ff
+ Hardware subarch : 0
+ HW subarch data : 0
+ Payload offset : 26e
+ Payload length : 612045
+ Setup data : 0
+ Pref address : 1000000
+ Init size : 1383000
+ Handover offset : 0
+
+ Starting kernel ...
+
+ Timer summary in microseconds (17 records):
+ Mark Elapsed Stage
+ 0 0 reset
+ 155,279 155,279 TPL
+ 237,088 81,809 end phase
+ 237,533 445 SPL
+ 816,456 578,923 end phase
+ 817,357 901 board_init_f
+ 1,061,751 244,394 board_init_r
+ 1,402,435 340,684 id=64
+ 1,430,071 27,636 main_loop
+ 5,532,057 4,101,986 start_kernel
+
+ Accumulated time:
+ 685 dm_r
+ 2,817 fast_spi
+ 33,095 dm_spl
+ 52,468 dm_f
+ 208,242 fsp-m
+ 242,221 fsp-s
+ 332,710 mmap_spi
+
+
Boot flow - TPL
---------------
@@ -181,7 +344,7 @@ Partial memory map
ff000000 Bottom of ROM
fefc0000 Top of CAR region
fef96000 Stack for FSP-M
- fef40000 59000 FSP-M
+ fef40000 59000 FSP-M (also VPL loads here)
fef11000 SPL loaded here
fef10000 CONFIG_BLOBLIST_ADDR
fef10000 Stack top in TPL, SPL and U-Boot before relocation
@@ -195,35 +358,72 @@ Partial memory map
1110000 CONFIG_SYS_TEXT_BASE
+Speeding up SPL for development
+-------------------------------
+
+The 21-second wait for memory training is annoying during development, since
+every new image incurs this cost when booting. There is no cache to fall back on
+since that area of the image is empty on start-up.
+
+You can add suitable cache contents to the image to fix this, for development
+purposes only, like this::
+
+ # Read the image back after booting through SPL
+ em100 -s -c w25q128fw -u image.bin
+
+ # Extract the two cache regions
+ binman extract -i image.bin extra *cache
+
+ # Move them into the source directory
+ mv *cache board/google/chromebook_coral
+
+Then add something like this to the devicetree::
+
+ #if IS_ENABLED(CONFIG_HAVE_MRC) || IS_ENABLED(CONFIG_FSP_VERSION2)
+ /* Provide initial contents of the MRC data for faster development */
+ rw-mrc-cache {
+ type = "blob";
+ /* Mirror the offset in spi-flash@0 */
+ offset = <0xff8e0000>;
+ size = <0x10000>;
+ filename = "board/google/chromebook_coral/rw-mrc-cache";
+ };
+ rw-var-mrc-cache {
+ type = "blob";
+ size = <0x1000>;
+ filename = "board/google/chromebook_coral/rw-var-mrc-cache";
+ };
+ #endif
+
+This tells binman to put the cache contents in the same place as the
+`rw-mrc-cache` and `rw-var-mrc-cache` regions defined by the SPI-flash driver.
+
+
Supported peripherals
---------------------
-- UART
-- SPI flash
-- Video
-- MMC (dev 0) and micro-SD (dev 1)
-- Chrome OS EC
-- Keyboard
-- USB
+The following have U-Boot drivers:
+
+ - UART
+ - SPI flash
+ - Video
+ - MMC (dev 0) and micro-SD (dev 1)
+ - Chrome OS EC
+ - Cr50 (security chip)
+ - Keyboard
+ - USB
To do
-----
- Finish peripherals
- - left-side USB
- - USB-C
- - Cr50 (security chip: a basic driver is running but not included here)
- Sound (Intel I2S support exists, but need da7219 driver)
- - Various minor features supported by LPC, etc.
-- Booting Chrome OS, e.g. with verified boot
-- Integrate with Chrome OS vboot
-- Improvements to booting from coreboot (i.e. as a coreboot target)
- Use FSP-T binary instead of our own CAR implementation
- Use the official FSP package instead of the coreboot one
-- Enable all CPU cores
- Suspend / resume
-- ACPI
+- Fix MMC which seems to try to read even though the card is empty
+- Fix USB3 crash "WARN halted endpoint, queueing URB anyway."
Credits
diff --git a/doc/README.chromium-chainload b/doc/chromium/chainload.rst
index 45eaeced2d..7b6bb10d36 100644
--- a/doc/README.chromium-chainload
+++ b/doc/chromium/chainload.rst
@@ -1,3 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2020 Google LLC
+
Running U-Boot from coreboot on Chromebooks
===========================================
@@ -15,7 +18,7 @@ replace the ROM unless you have a servo board and cable to restore it with.
For all of these the standard U-Boot build instructions apply. For example on
-ARM:
+ARM::
sudo apt install gcc-arm-linux-gnueabi
mkdir b
@@ -37,14 +40,17 @@ https://www.chromium.org/chromium-os/firmware-porting-guide/using-nv-u-boot-on-t
Nyan-big
--------
-Compiled based on information here:
-https://lists.denx.de/pipermail/u-boot/2015-March/209530.html
-https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big
-https://lists.denx.de/pipermail/u-boot/2017-May/289491.html
-https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card
+Compiled based on information here::
+
+ https://lists.denx.de/pipermail/u-boot/2015-March/209530.html
+ https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big
+ https://lists.denx.de/pipermail/u-boot/2017-May/289491.html
+ https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card
1. Build U-Boot
+Steps::
+
mkdir b
make -j8 O=b/nyan-big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all
@@ -61,16 +67,21 @@ kernel, and crashes if it is not present.
3. Build and sign an image
- ./b/nyan-big/tools/mkimage -f doc/chromium/nyan-big.its u-boot-chromium.fit
+Steps::
+
+ ./b/nyan-big/tools/mkimage -f doc/chromium/files/nyan-big.its u-boot-chromium.fit
echo test >dummy.txt
- vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
- --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
- --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
- --bootloader dummy.txt --pack u-boot.kpart
+ vbutil_kernel --arch arm \
+ --keyblock doc/chromium/files/devkeys/kernel.keyblock \
+ --signprivate doc/chromium/files/devkeys/kernel_data_key.vbprivk \
+ --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
+ --bootloader dummy.txt --pack u-boot.kpart
4. Prepare an SD card
+Steps::
+
DISK=/dev/sdc # Replace with your actual SD card device
sudo cgpt create $DISK
sudo cgpt add -b 34 -s 32768 -P 1 -S 1 -t kernel $DISK
@@ -80,6 +91,8 @@ kernel, and crashes if it is not present.
5. Write U-Boot to the SD card
+Steps::
+
sudo dd if=u-boot.kpart of=/dev/sdc1; sync
@@ -90,7 +103,7 @@ do this, login as root (via Ctrl-Alt-forward_arrow) and type
'enable_dev_usb_boot'. You only need to do this once.
Reboot the device with the SD card inserted. Press Clrl-U at the developer
-mode screen. It should show something like the following on the display:
+mode screen. It should show something like the following on the display::
U-Boot 2017.07-00637-g242eb42-dirty (May 22 2017 - 06:14:21 -0600)
@@ -104,9 +117,9 @@ mode screen. It should show something like the following on the display:
7. Known problems
-On the serial console the word MMC is chopped at the start of the line:
+On the serial console the word MMC is chopped at the start of the line::
-C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0
+ C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0
This is likely due to some problem with change-over of the serial driver
during relocation (or perhaps updating the clock setup in board_init()).
@@ -116,7 +129,7 @@ during relocation (or perhaps updating the clock setup in board_init()).
To check that you copied the u-boot.its file correctly, use these commands.
You should see that the data at 0x100 in u-boot-chromium.fit is the first few
-bytes of U-Boot:
+bytes of U-Boot::
hd u-boot-chromium.fit |head -20
...
@@ -141,34 +154,39 @@ The instruction are similar to those for Nyan with changes as noted below:
Open include/configs/rk3288_common.h
-Change:
+Change::
-#define CONFIG_SYS_TEXT_BASE 0x00100000
+ #define CONFIG_SYS_TEXT_BASE 0x00100000
-to:
+to::
-#define CONFIG_SYS_TEXT_BASE 0x02000100
+ #define CONFIG_SYS_TEXT_BASE 0x02000100
2. Build U-Boot
+Steps::
+
mkdir b
make -j8 O=b/chromebook_jerry CROSS_COMPILE=arm-linux-gnueabi- \
- chromebook_jerry_defconfig all
+ chromebook_jerry_defconfig all
3. See above
4. Build and sign an image
+Steps::
+
./b/chromebook_jerry/tools/mkimage -f doc/chromium/chromebook_jerry.its \
- u-boot-chromium.fit
+ u-boot-chromium.fit
echo test >dummy.txt
- vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
- --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
- --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
- --bootloader dummy.txt --pack u-boot.kpart
+ vbutil_kernel --arch arm \
+ --keyblock doc/chromium/files/devkeys/kernel.keyblock \
+ --signprivate doc/chromium/files/devkeys/kernel_data_key.vbprivk \
+ --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
+ --bootloader dummy.txt --pack u-boot.kpart
5. See above
@@ -182,7 +200,7 @@ do this, login as root (via Ctrl-Alt-forward_arrow) and type
'enable_dev_usb_boot'. You only need to do this once.
Reboot the device with the SD card inserted. Press Clrl-U at the developer
-mode screen. It should show something like the following on the display:
+mode screen. It should show something like the following on the display::
U-Boot 2017.05-00649-g72acdbf-dirty (May 29 2017 - 14:57:05 -0600)
@@ -203,18 +221,18 @@ None as yet.
Other notes
-===========
+-----------
flashrom
---------
+~~~~~~~~
- Used to make a backup of your firmware, or to replace it.
+Used to make a backup of your firmware, or to replace it.
- See: https://www.chromium.org/chromium-os/packages/cros-flashrom
+See: https://www.chromium.org/chromium-os/packages/cros-flashrom
coreboot
---------
+~~~~~~~~
Coreboot itself is not designed to actually boot an OS. Instead, a program
called Depthcharge is used. This originally came out of U-Boot and was then
diff --git a/doc/chromium/chromebook_jerry.its b/doc/chromium/files/chromebook_jerry.its
index 7505a20535..7505a20535 100644
--- a/doc/chromium/chromebook_jerry.its
+++ b/doc/chromium/files/chromebook_jerry.its
diff --git a/doc/chromium/devkeys/kernel.keyblock b/doc/chromium/files/devkeys/kernel.keyblock
index 9740be4e60..9740be4e60 100644
--- a/doc/chromium/devkeys/kernel.keyblock
+++ b/doc/chromium/files/devkeys/kernel.keyblock
Binary files differ
diff --git a/doc/chromium/devkeys/kernel_data_key.vbprivk b/doc/chromium/files/devkeys/kernel_data_key.vbprivk
index 8d392fb294..8d392fb294 100644
--- a/doc/chromium/devkeys/kernel_data_key.vbprivk
+++ b/doc/chromium/files/devkeys/kernel_data_key.vbprivk
Binary files differ
diff --git a/doc/chromium/nyan-big.its b/doc/chromium/files/nyan-big.its
index bd412915e9..bd412915e9 100644
--- a/doc/chromium/nyan-big.its
+++ b/doc/chromium/files/nyan-big.its
diff --git a/doc/chromium/index.rst b/doc/chromium/index.rst
new file mode 100644
index 0000000000..0722c25003
--- /dev/null
+++ b/doc/chromium/index.rst
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2020 Google LLC
+
+Chromium OS-specific doc
+========================
+
+This provides some information about Chromium OS and U-Boot.
+
+.. toctree::
+ :maxdepth: 2
+
+ overview
+ run_vboot
+ chainload
diff --git a/doc/chromium/overview.rst b/doc/chromium/overview.rst
new file mode 100644
index 0000000000..5498ed9c16
--- /dev/null
+++ b/doc/chromium/overview.rst
@@ -0,0 +1,74 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2020 Google LLC
+
+Chromium OS Support in U-Boot
+=============================
+
+Introduction
+------------
+
+This describes how to use U-Boot with Chromium OS. Several options are
+available:
+
+ - Running U-Boot from the 'altfw' feature, which is available on selected
+ Chromebooks from 2019 onwards (initially Grunt). Press '1' from the
+ developer-mode screen to get into U-Boot. See here for details:
+ https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_mode.md
+
+ - Running U-Boot from the disk partition. This involves signing U-Boot and
+ placing it on the disk, for booting as a 'kernel'. See
+ :doc:`chainload` for information on this. This is the only
+ option on non-U-Boot Chromebooks from 2013 to 2018 and is somewhat
+ more involved.
+
+ - Running U-Boot with Chromium OS verified boot. This allows U-Boot to be
+ used instead of either or both of depthcharge (a bootloader which forked
+ from U-Boot in 2013) and coreboot. See :doc:`run_vboot` for more
+ information on this.
+
+ - Running U-Boot from coreboot. This allows U-Boot to run on more devices
+ since many of them only support coreboot as the bootloader and have
+ no bare-metal support in U-Boot. For this, use the 'coreboot' target.
+
+ - Running U-Boot and booting into a Chrome OS image, but without verified
+ boot. This can be useful for testing.
+
+
+Talks and documents
+-------------------
+
+Here is some material relevant to Chromium OS verified boot with U-Boot:
+
+ - "U-Boot with Chrome OS and firmware packaging"
+
+ - Author: Simon Glass
+ - Presented at Open Source Firmware Conference 2018, Erlangen
+ - Describes the work in progress as at the end of 2018
+ - Slides at `OSFC <https://2018.osfc.io/uploads/talk/paper/26/U-Boot_with_Chrome_OS_and_firmware_packaging.pdf>`_
+ - Video on `Youtube <https://www.youtube.com/watch?v=1jknxUvmwpo>`_
+
+ - "Verified Boot in Chrome OS and how to make it work for you"
+
+ - Author: Simon Glass
+ - Presented at ELCE 2013, Edinburgh
+ - Describes the original 2013 implementation as shipped on snow (first
+ `ARM Chromebook was a Samsung Chromebook <https://www.cnet.com/products/samsung-series-3-chromebook-xe303c12-11-6-exynos-5250-2-gb-ram-16-gb-ssd-bilingual-english-french/>`_
+ with Samsung Exynos5250 `review <https://www.cnet.com/reviews/samsung-chromebook-series-3-review/>`_),
+ spring (`HP Chromebook 11 <https://www.cnet.com/products/hp-chromebook-11-g2-11-6-exynos-5250-4-gb-ram-16-gb-emmc/>`_)
+ and pit/pi (`Samsung Chromebook 2 <https://www.cnet.com/products/samsung-chromebook-2-xe503c12-11-6-exynos-5-octa-4-gb-ram-16-gb-ssd/>`_
+ with Exynos 5 Octa 5420 in 2014).
+ - Slides at `Google research <https://research.google/pubs/pub42038/>`_
+ - Video at `Youtube <https://www.youtube.com/watch?v=kdpZC9jFzZA>`_
+
+ - "Chrome University 2018: Chrome OS Firmware and Verified Boot 201"
+
+ - Author: Duncan Laurie
+ - Describes Chrome OS firmware as of 2018 and includes a wide range of
+ topics. This has no U-Boot information, but does cover coreboot and also
+ talks about the Chrome OS EC and Security chip. This is probably the
+ best introduction talk.
+ - Video at `YouTube <https://www.youtube.com/watch?v=WY2sWpuda2g>`_
+
+ - `Chromium OS U-Boot <https://www.chromium.org/developers/u-boot>`_
+
+ - `Firmware porting Guide <https://www.chromium.org/chromium-os/firmware-porting-guide>`_
diff --git a/doc/README.chromium b/doc/chromium/run_vboot.rst
index 75f2f24042..41b4f63183 100644
--- a/doc/README.chromium
+++ b/doc/chromium/run_vboot.rst
@@ -1,42 +1,14 @@
-Chromium OS Support in U-Boot
-=============================
-
-Introduction
-------------
-
-This describes how to use U-Boot with Chromium OS. Several options are
-available:
-
- - Running U-Boot from the 'altfw' feature, which is available on selected
- Chromebooks from 2019 onwards (initially Grunt). Press '1' from the
- developer-mode screen to get into U-Boot. See here for details:
- https://sites.google.com/a/chromium.org/dev/chromium-os/poking-around-your-chrome-os-device?pli=1
-
- - Running U-Boot from the disk partition. This involves signing U-Boot and
- placing it on the disk, for booting as a 'kernel'. See
- README.chromium-chainload for information on this. This is the only
- option on non-U-Boot Chromebooks from 2013 to 2018 and is somewhat
- more involved.
-
- - Running U-Boot with Chromium OS verified boot. This allows U-Boot to be
- used instead of either or both of depthcharge (a bootloader which forked
- from U-Boot in 2013) and coreboot. See below for more information on
- this.
-
- - Running U-Boot from coreboot. This allows U-Boot to run on more devices
- since many of them only support coreboot as the bootloader and have
- no bare-metal support in U-Boot. For this, use the 'coreboot' target.
-
- - Running U-Boot and booting into a Chrome OS image, but without verified
- boot. This can be useful for testing.
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2020 Google LLC
+.. sectionauthor:: Simon Glass <sjg@chromium.org>
-U-Boot with Chromium OS verified boot
--------------------------------------
+Running U-Boot with Chromium OS verified boot
+=============================================
-To obtain:
+To obtain::
- git clone https://github.com/sglass68/u-boot.git
+ git clone https://github.com/sjg20/u-boot.git
cd u-boot
git checkout cros-master
@@ -46,28 +18,35 @@ To obtain:
git checkout 45964294
# futility: updater: Correct output version for Snow
-To build for sandbox:
+To build for sandbox::
UB=/tmp/b/chromeos_sandbox # U-Boot build directory
cd u-boot
make O=$UB chromeos_sandbox_defconfig
make O=$UB -j20 -s VBOOT_SOURCE=/path/to/vboot_reference \
- MAKEFLAGS_VBOOT=DEBUG=1 QUIET=1
+ MAKEFLAGS_VBOOT=DEBUG=1 QUIET=1
Replace sandbox with another supported target.
This produces $UB/image.bin which contains the firmware binaries in a SPI
flash image.
-To run on sandbox:
+To run on sandbox::
+ CROS=~/cosarm
+ IMG=$CROS/src/build/images/coral/latest/chromiumos_image.bin
$UB/tpl/u-boot-tpl -d $UB/u-boot.dtb.out \
- -L6 -c "host bind 0 $CROS/src/build/images/cheza/latest/chromiumos_image.bin; vboot go auto" \
- -l -w -s state.dtb -r
+ -L6 -c "host bind 0 $IMG; vboot go auto" \
+ -l -w -s state.dtb -r -n -m $UB/ram
+
+ $UB/tpl/u-boot-tpl -d $UB/u-boot.dtb.out -L6 -l \
+ -c "host bind 0 $IMG; vboot go auto" -w -s $UB/state.dtb -r -n -m $UB/mem
+
To run on other boards:
- Install image.bin in the SPI flash of your device
- Boot your system
+
+ - Install image.bin in the SPI flash of your device
+ - Boot your system
Sandbox
@@ -83,7 +62,7 @@ a device tree and binding a Chromium OS disk image for use to find kernels
phases into state.dtb and will automatically ensure that memory is shared
between all phases. TPL will jump to SPL and then on to U-Boot proper.
-It is possible to run with debugging on, e.g.
+It is possible to run with debugging on, e.g.::
gdb --args $UB/tpl/u-boot-tpl -d ....
@@ -95,7 +74,7 @@ Samus
-----
Basic support is available for samus, using the chromeos_samus target. If you
-have an em100, use:
+have an em100, use::
sudo em100 -s -c W25Q128FW -d $UB/image.bin -t -r
@@ -119,11 +98,20 @@ New uclasses
Several uclasses are provided in cros/:
- UCLASS_CROS_AUX_FW Chrome OS auxiliary firmware
- UCLASS_CROS_FWSTORE Chrome OS firmware storage
- UCLASS_CROS_NVDATA Chrome OS non-volatile data device
- UCLASS_CROS_VBOOT_EC Chrome OS vboot EC operations
- UCLASS_CROS_VBOOT_FLAG Chrome OS verified boot flag
+UCLASS_CROS_AUX_FW
+ Chrome OS auxiliary firmware
+
+UCLASS_CROS_FWSTORE
+ Chrome OS firmware storage
+
+UCLASS_CROS_NVDATA
+ Chrome OS non-volatile data device
+
+UCLASS_CROS_VBOOT_EC
+ Chrome OS vboot EC operations
+
+UCLASS_CROS_VBOOT_FLAG
+ Chrome OS verified boot flag
The existing UCLASS_CROS_EC is also used.
@@ -181,7 +169,7 @@ detect problems that affect the flow or particular vboot features.
U-Boot without Chromium OS verified boot
----------------------------------------
-The following script can be used to boot a Chrome OS image on coral:
+The following script can be used to boot a Chrome OS image on coral::
# Read the image header and obtain the address of the kernel
# The offset 4f0 is defined by verified boot and may change for other
@@ -213,6 +201,4 @@ TO DO
Get the full ACPI tables working with Coral
-Simon Glass
-sjg@chromium.org
7 October 2018
diff --git a/doc/device-tree-bindings/sysinfo/google,coral.txt b/doc/device-tree-bindings/sysinfo/google,coral.txt
new file mode 100644
index 0000000000..d8a1a79687
--- /dev/null
+++ b/doc/device-tree-bindings/sysinfo/google,coral.txt
@@ -0,0 +1,37 @@
+Google Coral sysinfo information
+================================
+
+This binding allows information about the board to be described. It includes
+the SMBIOS binding as well.
+
+Required properties:
+
+ - compatible: "google,coral"
+ - recovery-gpios: GPIO to use for recovery button (-1 if none)
+ - wite-protect-gpios: GPIO to use for write-protect screw
+ - phase-enforce-gpios: GPIO to indicate the board is in final ship mode
+ - memconfig-gpios: 4 GPIOs to use to read memory config (as base2 int)
+
+Optional properties:
+ - skuconfig-gpios: 2 GPIOs to use to read SKU ID. If not present, the
+ Chromium OS EC SKU_ID is used instead
+
+Example:
+
+board: board {
+ compatible = "google,coral";
+ recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>;
+ write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>;
+ phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>;
+ memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH
+ &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH
+ &gpio_n GPIO_38 GPIO_ACTIVE_HIGH
+ &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>;
+
+ /*
+ * This is used for reef only:
+ *
+ * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH
+ * &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>;
+ */
+ };
diff --git a/doc/index.rst b/doc/index.rst
index f7aada966b..02de1d4684 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -87,6 +87,14 @@ Android-specific features available in U-Boot.
android/index
+Chromium OS-specific doc
+------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ chromium/index
+
Indices and tables
==================
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 35c515f8b5..fb834349ca 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -21,6 +21,7 @@ Shell commands
booti
bootmenu
button
+ x86/cbsysinfo
conitrace
echo
exception
diff --git a/doc/usage/x86/cbsysinfo.rst b/doc/usage/x86/cbsysinfo.rst
new file mode 100644
index 0000000000..8c03a85169
--- /dev/null
+++ b/doc/usage/x86/cbsysinfo.rst
@@ -0,0 +1,25 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+cbsysinfo
+=========
+
+Synopis
+-------
+
+::
+
+ cbsysinfo
+
+
+Description
+-----------
+
+This displays information obtained from the coreboot sysinfo table. It is only
+useful when booting U-Boot from coreboot.
+
+Example
+-------
+
+::
+
+ => cbsysinfo
diff --git a/drivers/Makefile b/drivers/Makefile
index c562a719f7..3510daba29 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -38,7 +38,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_BOOTCOUNT_LIMIT) += bootcount/
obj-$(CONFIG_SPL_CACHE_SUPPORT) += cache/
-obj-$(CONFIG_SPL_CPU_SUPPORT) += cpu/
+obj-$(CONFIG_SPL_CPU) += cpu/
obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
obj-$(CONFIG_ARMADA_38X) += ddr/marvell/a38x/
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index e2f229b15d..1c2c3b4f88 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -89,7 +89,7 @@ static unsigned long host_block_write(struct blk_desc *block_dev,
}
#ifdef CONFIG_BLK
-int host_dev_bind(int devnum, char *filename)
+int host_dev_bind(int devnum, char *filename, bool removable)
{
struct host_block_dev *host_dev;
struct udevice *dev;
@@ -146,7 +146,7 @@ int host_dev_bind(int devnum, char *filename)
}
desc = blk_get_devnum_by_type(IF_TYPE_HOST, devnum);
- desc->removable = 1;
+ desc->removable = removable;
snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
snprintf(desc->revision, BLK_REV_SIZE, "1.0");
@@ -160,7 +160,7 @@ err:
return ret;
}
#else
-int host_dev_bind(int dev, char *filename)
+int host_dev_bind(int dev, char *filename, bool removable)
{
struct host_block_dev *host_dev = find_host_device(dev);
@@ -195,7 +195,7 @@ int host_dev_bind(int dev, char *filename)
blk_dev->block_write = host_block_write;
blk_dev->devnum = dev;
blk_dev->part_type = PART_TYPE_UNKNOWN;
- blk_dev->removable = 1;
+ blk_dev->removable = removable;
snprintf(blk_dev->vendor, BLK_VEN_SIZE, "U-Boot");
snprintf(blk_dev->product, BLK_PRD_SIZE, "hostfile");
snprintf(blk_dev->revision, BLK_REV_SIZE, "1.0");
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index ab46a94dbc..f15ce7b59e 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -23,6 +23,7 @@
#include <asm/pci.h>
#include <asm/arch/gpio.h>
#include <dm/acpi.h>
+#include <dm/device-internal.h>
#include <dt-bindings/gpio/x86-gpio.h>
static int intel_gpio_get_value(struct udevice *dev, uint offset)
@@ -85,7 +86,7 @@ static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
/*
* GPIO numbers are global in the device tree so it doesn't matter
- * which one is used
+ * which @orig_dev is used
*/
gpio = args->args[0];
ret = intel_pinctrl_get_pad(gpio, &pinctrl, &desc->offset);
@@ -97,6 +98,17 @@ static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
desc->dev = dev;
+ /*
+ * Handle the case where the wrong GPIO device was provided, since this
+ * will not have been probed by the GPIO uclass before calling here
+ * (see gpio_request_tail()).
+ */
+ if (orig_dev != dev) {
+ ret = device_probe(dev);
+ if (ret)
+ return log_msg_ret("probe", ret);
+ }
+
return 0;
}
diff --git a/drivers/misc/cbmem_console.c b/drivers/misc/cbmem_console.c
index 5ba0a54206..8bbe33d414 100644
--- a/drivers/misc/cbmem_console.c
+++ b/drivers/misc/cbmem_console.c
@@ -9,7 +9,7 @@
#error This driver requires coreboot
#endif
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
struct cbmem_console {
u32 buffer_size;
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index cb8adc4495..bc01df0904 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -153,10 +153,14 @@ static int cros_ec_write_state(void *blob, int node)
{
struct ec_state *ec = g_state;
+ if (!g_state)
+ return 0;
+
/* We are guaranteed enough space to write basic properties */
fdt_setprop_u32(blob, node, "current-image", ec->current_image);
fdt_setprop(blob, node, "vbnv-context", ec->vbnv_context,
sizeof(ec->vbnv_context));
+
return state_setprop(node, "flash-data", ec->flash_data,
ec->ec_config.flash.length);
}
diff --git a/drivers/misc/p2sb_emul.c b/drivers/misc/p2sb_emul.c
index 973d02d678..51f87161d5 100644
--- a/drivers/misc/p2sb_emul.c
+++ b/drivers/misc/p2sb_emul.c
@@ -7,7 +7,6 @@
*/
#define LOG_CATEGORY UCLASS_MISC
-#define LOG_DEBUG
#include <common.h>
#include <axi.h>
diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c
index fd5dd229b5..b9ab064b60 100644
--- a/drivers/mmc/pci_mmc.c
+++ b/drivers/mmc/pci_mmc.c
@@ -53,6 +53,7 @@ static int pci_mmc_probe(struct udevice *dev)
host->ioaddr = (void *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
PCI_REGION_MEM);
host->name = dev->name;
+ host->cd_gpio = priv->cd_gpio;
host->mmc = &plat->mmc;
host->mmc->dev = dev;
ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
@@ -68,8 +69,11 @@ static int pci_mmc_of_to_plat(struct udevice *dev)
{
if (CONFIG_IS_ENABLED(DM_GPIO)) {
struct pci_mmc_priv *priv = dev_get_priv(dev);
+ int ret;
- gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN);
+ ret = gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
+ GPIOD_IS_IN);
+ log_debug("cd-gpio %s done, ret=%d\n", dev->name, ret);
}
return 0;
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 12d132152d..cfce00ef54 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -31,6 +31,15 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
}
+int spl_flash_get_sw_write_prot(struct udevice *dev)
+{
+ struct dm_spi_flash_ops *ops = sf_get_ops(dev);
+
+ if (!ops->get_sw_write_prot)
+ return -ENOSYS;
+ return log_ret(ops->get_sw_write_prot(dev));
+}
+
/*
* TODO(sjg@chromium.org): This is an old-style function. We should remove
* it when all SPI flash drivers use dm
@@ -46,11 +55,6 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
return dev_get_uclass_priv(dev);
}
-void spi_flash_free(struct spi_flash *flash)
-{
- device_remove(flash->spi->dev, DM_REMOVE_NORMAL);
-}
-
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode,
struct udevice **devp)
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 9ceff0e7c1..786301ba4a 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -75,6 +75,10 @@ extern const struct flash_info spi_nor_ids[];
#define JEDEC_MFR(info) ((info)->id[0])
#define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2]))
+/* Get software write-protect value (BP bits) */
+int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash);
+
+
#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
int spi_flash_mtd_register(struct spi_flash *flash);
void spi_flash_mtd_unregister(void);
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 6c87434867..3befbe91ca 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -130,6 +130,13 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
return mtd->_erase(mtd, &instr);
}
+static int spi_flash_std_get_sw_write_prot(struct udevice *dev)
+{
+ struct spi_flash *flash = dev_get_uclass_priv(dev);
+
+ return spi_flash_cmd_get_sw_write_prot(flash);
+}
+
int spi_flash_std_probe(struct udevice *dev)
{
struct spi_slave *slave = dev_get_parent_priv(dev);
@@ -153,6 +160,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
.read = spi_flash_std_read,
.write = spi_flash_std_write,
.erase = spi_flash_std_erase,
+ .get_sw_write_prot = spi_flash_std_get_sw_write_prot,
};
static const struct udevice_id spi_flash_std_ids[] = {
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index e0efebc355..a6625535a7 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2647,3 +2647,14 @@ int spi_nor_scan(struct spi_nor *nor)
return 0;
}
+
+/* U-Boot specific functions, need to extend MTD to support these */
+int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor)
+{
+ int sr = read_sr(nor);
+
+ if (sr < 0)
+ return sr;
+
+ return (sr >> 2) & 7;
+}
diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c
index 07c8c7b82b..1d5861d55c 100644
--- a/drivers/mtd/spi/spi-nor-tiny.c
+++ b/drivers/mtd/spi/spi-nor-tiny.c
@@ -809,3 +809,9 @@ int spi_nor_scan(struct spi_nor *nor)
return 0;
}
+
+/* U-Boot specific functions, need to extend MTD to support these */
+int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor)
+{
+ return -ENOTSUPP;
+}
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index a14a4db3c2..7bad4c82c0 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -349,13 +349,10 @@ int vbe_setup_video_priv(struct vesa_mode_info *vesa,
}
/* Use double buffering if enabled */
- if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
- if (!plat->base)
- return log_msg_ret("copy", -ENFILE);
+ if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->base)
plat->copy_base = vesa->phys_base_ptr;
- } else {
+ else
plat->base = vesa->phys_base_ptr;
- }
log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
index 88c8209c5d..de09c8681f 100644
--- a/drivers/serial/serial_coreboot.c
+++ b/drivers/serial/serial_coreboot.c
@@ -9,7 +9,7 @@
#include <dm.h>
#include <ns16550.h>
#include <serial.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
static int coreboot_of_to_plat(struct udevice *dev)
{
diff --git a/drivers/sound/tegra_i2s.c b/drivers/sound/tegra_i2s.c
index 5cf82250da..932f737900 100644
--- a/drivers/sound/tegra_i2s.c
+++ b/drivers/sound/tegra_i2s.c
@@ -4,7 +4,6 @@
* Written by Simon Glass <sjg@chromium.org>
*/
#define LOG_CATEGORY UCLASS_I2S
-#define LOG_DEBUG
#include <common.h>
#include <dm.h>
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 7155d4aebd..ee30110b56 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -11,6 +11,7 @@
#include <log.h>
#include <malloc.h>
#include <spi.h>
+#include <spi-mem.h>
#include <dm/device_compat.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
@@ -199,6 +200,16 @@ static int spi_post_probe(struct udevice *bus)
ops->set_mode += gd->reloc_off;
if (ops->cs_info)
ops->cs_info += gd->reloc_off;
+ if (ops->mem_ops) {
+ struct spi_controller_mem_ops *mem_ops =
+ (struct spi_controller_mem_ops *)ops->mem_ops;
+ if (mem_ops->adjust_op_size)
+ mem_ops->adjust_op_size += gd->reloc_off;
+ if (mem_ops->supports_op)
+ mem_ops->supports_op += gd->reloc_off;
+ if (mem_ops->exec_op)
+ mem_ops->exec_op += gd->reloc_off;
+ }
reloc_done++;
}
#endif
diff --git a/drivers/timer/sandbox_timer.c b/drivers/timer/sandbox_timer.c
index 2075cd4edd..c846bfb9f1 100644
--- a/drivers/timer/sandbox_timer.c
+++ b/drivers/timer/sandbox_timer.c
@@ -38,7 +38,8 @@ static int sandbox_timer_probe(struct udevice *dev)
{
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- if (dev_read_bool(dev, "sandbox,timebase-frequency-fallback"))
+ if (CONFIG_IS_ENABLED(CPU) &&
+ dev_read_bool(dev, "sandbox,timebase-frequency-fallback"))
return timer_timebase_fallback(dev);
else if (!uc_priv->clock_rate)
uc_priv->clock_rate = SANDBOX_TIMER_RATE;
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 6f00a5d0db..73b4a5cd27 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -83,11 +83,7 @@ static int timer_post_probe(struct udevice *dev)
return 0;
}
-/*
- * TODO: should be CONFIG_IS_ENABLED(CPU), but the SPL config has _SUPPORT on
- * the end...
- */
-#if defined(CONFIG_CPU) || defined(CONFIG_SPL_CPU_SUPPORT)
+#if CONFIG_IS_ENABLED(CPU)
int timer_timebase_fallback(struct udevice *dev)
{
struct udevice *cpu;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 667157c2e9..63ae2ba43c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -241,7 +241,7 @@ config VIDCONSOLE_AS_NAME
config VIDEO_COREBOOT
bool "Enable coreboot framebuffer driver support"
- depends on X86 && SYS_COREBOOT
+ depends on X86
help
Turn on this option to enable a framebuffer driver when U-Boot is
loaded by coreboot where the graphics device is configured by
diff --git a/drivers/video/coreboot.c b/drivers/video/coreboot.c
index 0a5fb08dc8..7237542c07 100644
--- a/drivers/video/coreboot.c
+++ b/drivers/video/coreboot.c
@@ -5,9 +5,10 @@
#include <common.h>
#include <dm.h>
+#include <init.h>
#include <vbe.h>
#include <video.h>
-#include <asm/arch/sysinfo.h>
+#include <asm/cb_sysinfo.h>
static int save_vesa_mode(struct cb_framebuffer *fb,
struct vesa_mode_info *vesa)
@@ -17,7 +18,7 @@ static int save_vesa_mode(struct cb_framebuffer *fb,
* running on the serial console.
*/
if (!fb)
- return -ENXIO;
+ return log_msg_ret("save", -ENXIO);
vesa->x_resolution = fb->x_resolution;
vesa->y_resolution = fb->y_resolution;
@@ -44,16 +45,23 @@ static int coreboot_video_probe(struct udevice *dev)
struct vesa_mode_info *vesa = &mode_info.vesa;
int ret;
+ if (ll_boot_init())
+ return log_msg_ret("ll", -ENODEV);
+
printf("Video: ");
/* Initialize vesa_mode_info structure */
ret = save_vesa_mode(fb, vesa);
- if (ret)
+ if (ret) {
+ ret = log_msg_ret("save", ret);
goto err;
+ }
ret = vbe_setup_video_priv(vesa, uc_priv, plat);
- if (ret)
+ if (ret) {
+ ret = log_msg_ret("setup", ret);
goto err;
+ }
printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
vesa->bits_per_pixel);
@@ -61,7 +69,7 @@ static int coreboot_video_probe(struct udevice *dev)
return 0;
err:
- printf("No video mode configured in coreboot!\n");
+ printf("No video mode configured in coreboot (err=%d)\n", ret);
return ret;
}
diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c
index 9007aa7d15..415ea28b87 100644
--- a/fs/cbfs/cbfs.c
+++ b/fs/cbfs/cbfs.c
@@ -79,6 +79,57 @@ static void swap_file_header(struct cbfs_fileheader *dest,
dest->offset = be32_to_cpu(src->offset);
}
+/**
+ * fill_node() - Fill a node struct with information from the CBFS
+ *
+ * @node: Node to fill
+ * @start: Pointer to the start of the CBFS file in memory
+ * @header: Pointer to the header information (in our enddianess)
+ * @return 0 if OK, -EBADF if the header is too small
+ */
+static int fill_node(struct cbfs_cachenode *node, void *start,
+ struct cbfs_fileheader *header)
+{
+ uint name_len;
+ uint offset;
+
+ /* Check the header is large enough */
+ if (header->offset < sizeof(struct cbfs_fileheader))
+ return -EBADF;
+
+ node->next = NULL;
+ node->type = header->type;
+ node->data = start + header->offset;
+ node->data_length = header->len;
+ name_len = header->offset - sizeof(struct cbfs_fileheader);
+ node->name = start + sizeof(struct cbfs_fileheader);
+ node->name_length = name_len;
+ node->attr_offset = header->attributes_offset;
+ node->comp_algo = CBFS_COMPRESS_NONE;
+ node->decomp_size = 0;
+
+ for (offset = node->attr_offset; offset < header->offset;) {
+ const struct cbfs_file_attribute *attr;
+ uint tag, len;
+
+ attr = start + offset;
+ tag = be32_to_cpu(attr->tag);
+ len = be32_to_cpu(attr->len);
+ if (tag == CBFS_FILE_ATTR_TAG_COMPRESSION) {
+ struct cbfs_file_attr_compression *comp;
+
+ comp = start + offset;
+ node->comp_algo = be32_to_cpu(comp->compression);
+ node->decomp_size =
+ be32_to_cpu(comp->decompressed_size);
+ }
+
+ offset += len;
+ }
+
+ return 0;
+}
+
/*
* Given a starting position in memory, scan forward, bounded by a size, and
* find the next valid CBFS file. No memory is allocated by this function. The
@@ -87,7 +138,7 @@ static void swap_file_header(struct cbfs_fileheader *dest,
* @param start The location in memory to start from.
* @param size The size of the memory region to search.
* @param align The alignment boundaries to check on.
- * @param new_node A pointer to the file structure to load.
+ * @param node A pointer to the file structure to load.
* @param used A pointer to the count of of bytes scanned through,
* including the file if one is found.
*
@@ -95,7 +146,7 @@ static void swap_file_header(struct cbfs_fileheader *dest,
* is found.
*/
static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
- int align, struct cbfs_cachenode *new_node,
+ int align, struct cbfs_cachenode *node,
int *used)
{
struct cbfs_fileheader header;
@@ -104,8 +155,7 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
while (size >= align) {
const struct cbfs_fileheader *file_header = start;
- u32 name_len;
- u32 step;
+ int ret;
/* Check if there's a file here. */
if (memcmp(good_file_magic, &file_header->magic,
@@ -117,25 +167,13 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
}
swap_file_header(&header, file_header);
- if (header.offset < sizeof(struct cbfs_fileheader)) {
+ ret = fill_node(node, start, &header);
+ if (ret) {
priv->result = CBFS_BAD_FILE;
- return -EBADF;
+ return log_msg_ret("fill", ret);
}
- new_node->next = NULL;
- new_node->type = header.type;
- new_node->data = start + header.offset;
- new_node->data_length = header.len;
- name_len = header.offset - sizeof(struct cbfs_fileheader);
- new_node->name = (char *)file_header +
- sizeof(struct cbfs_fileheader);
- new_node->name_length = name_len;
- new_node->attributes_offset = header.attributes_offset;
-
- step = header.len;
- if (step % align)
- step = step + align - step % align;
-
- *used += step;
+
+ *used += ALIGN(header.len, align);
return 0;
}
@@ -146,7 +184,7 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
static int file_cbfs_fill_cache(struct cbfs_priv *priv, int size, int align)
{
struct cbfs_cachenode *cache_node;
- struct cbfs_cachenode *new_node;
+ struct cbfs_cachenode *node;
struct cbfs_cachenode **cache_tail = &priv->file_cache;
void *start;
@@ -164,21 +202,20 @@ static int file_cbfs_fill_cache(struct cbfs_priv *priv, int size, int align)
int used;
int ret;
- new_node = (struct cbfs_cachenode *)
- malloc(sizeof(struct cbfs_cachenode));
- if (!new_node)
+ node = malloc(sizeof(struct cbfs_cachenode));
+ if (!node)
return -ENOMEM;
- ret = file_cbfs_next_file(priv, start, size, align, new_node,
+ ret = file_cbfs_next_file(priv, start, size, align, node,
&used);
if (ret < 0) {
- free(new_node);
+ free(node);
if (ret == -ENOENT)
break;
return ret;
}
- *cache_tail = new_node;
- cache_tail = &new_node->next;
+ *cache_tail = node;
+ cache_tail = &node->next;
size -= used;
start += used;
@@ -276,18 +313,26 @@ int file_cbfs_init(ulong end_of_rom)
return cbfs_init(&cbfs_s, end_of_rom);
}
-int cbfs_init_mem(ulong base, struct cbfs_priv **privp)
+int cbfs_init_mem(ulong base, ulong size, bool require_hdr,
+ struct cbfs_priv **privp)
{
struct cbfs_priv priv_s, *priv = &priv_s;
int ret;
/*
- * Use a local variable to start with until we know that the CBFS is
- * valid.
+ * Use a local variable to start with until we know that the * CBFS is
+ * valid. Note that size is detected from the header, if present,
+ * meaning the parameter is ignored.
*/
ret = cbfs_load_header_ptr(priv, base);
- if (ret)
- return ret;
+ if (ret) {
+ if (require_hdr || size == CBFS_SIZE_UNKNOWN)
+ return ret;
+ memset(priv, '\0', sizeof(struct cbfs_priv));
+ priv->header.rom_size = size;
+ priv->header.align = CBFS_ALIGN_SIZE;
+ priv->start = (void *)base;
+ }
ret = file_cbfs_fill_cache(priv, priv->header.rom_size,
priv->header.align);
@@ -317,6 +362,17 @@ const struct cbfs_header *file_cbfs_get_header(void)
}
}
+const struct cbfs_cachenode *cbfs_get_first(const struct cbfs_priv *priv)
+{
+ return priv->file_cache;
+}
+
+void cbfs_get_next(const struct cbfs_cachenode **filep)
+{
+ if (*filep)
+ *filep = (*filep)->next;
+}
+
const struct cbfs_cachenode *file_cbfs_get_first(void)
{
struct cbfs_priv *priv = &cbfs_s;
diff --git a/include/cbfs.h b/include/cbfs.h
index 5f296d6a37..ae94f1dcdf 100644
--- a/include/cbfs.h
+++ b/include/cbfs.h
@@ -9,6 +9,8 @@
#include <compiler.h>
#include <linux/compiler.h>
+struct cbfs_priv;
+
enum cbfs_result {
CBFS_SUCCESS = 0,
CBFS_NOT_INITIALIZED,
@@ -42,6 +44,8 @@ enum cbfs_filetype {
enum {
CBFS_HEADER_MAGIC = 0x4f524243,
+ CBFS_SIZE_UNKNOWN = 0xffffffff,
+ CBFS_ALIGN_SIZE = 0x40,
};
/**
@@ -68,6 +72,52 @@ struct cbfs_fileheader {
/* offset to struct cbfs_file_attribute or 0 */
u32 attributes_offset;
u32 offset;
+ char filename[];
+} __packed;
+
+/**
+ * These are standard values for the known compression alogrithms that coreboot
+ * knows about for stages and payloads. Of course, other CBFS users can use
+ * whatever values they want, as long as they understand them.
+ */
+#define CBFS_COMPRESS_NONE 0
+#define CBFS_COMPRESS_LZMA 1
+#define CBFS_COMPRESS_LZ4 2
+
+/*
+ * Depending on how the header was initialized, it may be backed with 0x00 or
+ * 0xff, so support both
+ */
+#define CBFS_FILE_ATTR_TAG_UNUSED 0
+#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff
+#define CBFS_FILE_ATTR_TAG_COMPRESSION 0x42435a4c
+#define CBFS_FILE_ATTR_TAG_HASH 0x68736148
+
+/*
+ * The common fields of extended cbfs file attributes. Attributes are expected
+ * to start with tag/len, then append their specific fields
+ */
+struct cbfs_file_attribute {
+ u32 tag;
+ /* len covers the whole structure, incl. tag and len */
+ u32 len;
+ u8 data[0];
+} __packed;
+
+struct cbfs_file_attr_compression {
+ u32 tag;
+ u32 len;
+ /* whole file compression format. 0 if no compression. */
+ u32 compression;
+ u32 decompressed_size;
+} __packed;
+
+struct cbfs_file_attr_hash {
+ u32 tag;
+ u32 len;
+ u32 hash_type;
+ /* hash_data is len - sizeof(struct) bytes */
+ u8 hash_data[];
} __packed;
struct cbfs_cachenode {
@@ -77,7 +127,9 @@ struct cbfs_cachenode {
u32 type;
u32 data_length;
u32 name_length;
- u32 attributes_offset;
+ u32 attr_offset;
+ u32 comp_algo;
+ u32 decomp_size;
};
/**
@@ -111,6 +163,21 @@ int file_cbfs_init(ulong end_of_rom);
const struct cbfs_header *file_cbfs_get_header(void);
/**
+ * cbfs_get_first() - Get the first file in a CBFS
+ *
+ * @return pointer to first file, or NULL if it is empty
+ */
+const struct cbfs_cachenode *cbfs_get_first(const struct cbfs_priv *priv);
+
+/**
+ * cbfs_get_next() - Get the next file in a CBFS
+ *
+ * @filep: Pointer to current file; updated to point to the next file, if any,
+ * else NULL
+ */
+void cbfs_get_next(const struct cbfs_cachenode **filep);
+
+/**
* file_cbfs_get_first() - Get a handle for the first file in CBFS.
*
* @return A handle for the first file in CBFS, NULL on error.
@@ -133,8 +200,6 @@ void file_cbfs_get_next(const struct cbfs_cachenode **file);
*/
const struct cbfs_cachenode *file_cbfs_find(const char *name);
-struct cbfs_priv;
-
/**
* cbfs_find_file() - Find a file in a given CBFS
*
@@ -149,11 +214,13 @@ const struct cbfs_cachenode *cbfs_find_file(struct cbfs_priv *cbfs,
* cbfs_init_mem() - Set up a new CBFS
*
* @base: Base address of CBFS
+ * @size: Size of CBFS if known, else CBFS_SIZE_UNKNOWN
+ * @require_header: true to read a header at the start, false to not require one
* @cbfsp: Returns a pointer to CBFS on success
* @return 0 if OK, -ve on error
*/
-int cbfs_init_mem(ulong base, struct cbfs_priv **privp);
-
+int cbfs_init_mem(ulong base, ulong size, bool require_hdr,
+ struct cbfs_priv **privp);
/***************************************************************************/
/* All of the functions below can be used without first initializing CBFS. */
diff --git a/include/command.h b/include/command.h
index 747f8f8095..137cfbc323 100644
--- a/include/command.h
+++ b/include/command.h
@@ -389,6 +389,14 @@ int run_command_list(const char *cmd, int len, int flag);
return 0; \
}
+#define _CMD_REMOVE_REP(_name, _cmd) \
+ int __remove_ ## _name(void) \
+ { \
+ if (0) \
+ _cmd(NULL, 0, 0, NULL, NULL); \
+ return 0; \
+ }
+
#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
_usage, _help, _comp) \
{ #_name, _maxargs, 0 ? _cmd_rep : NULL, NULL, _usage, \
@@ -405,7 +413,7 @@ int run_command_list(const char *cmd, int len, int flag);
#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \
_help, _comp) \
- _CMD_REMOVE(sub_ ## _name, _cmd_rep)
+ _CMD_REMOVE_REP(sub_ ## _name, _cmd_rep)
#endif /* CONFIG_CMDLINE */
diff --git a/include/configs/chromebook_coral.h b/include/configs/chromebook_coral.h
index 6e8e8ec170..00760b8a30 100644
--- a/include/configs/chromebook_coral.h
+++ b/include/configs/chromebook_coral.h
@@ -12,13 +12,13 @@
#define CONFIG_BOOTCOMMAND \
"tpm init; tpm startup TPM2_SU_CLEAR; " \
- "read mmc 2:2 100000 0 80; setexpr loader *001004f0; " \
+ "read mmc 0:2 100000 0 80; setexpr loader *001004f0; " \
"setexpr size *00100518; setexpr blocks $size / 200; " \
- "read mmc 2:2 100000 80 $blocks; setexpr setup $loader - 1000; " \
+ "read mmc 0:2 100000 80 $blocks; setexpr setup $loader - 1000; " \
"setexpr cmdline_ptr $loader - 2000; " \
"setexpr.s cmdline *$cmdline_ptr; " \
"setexpr cmdline gsub %U \\\\${uuid}; " \
- "if part uuid mmc 2:2 uuid; then " \
+ "if part uuid mmc 0:2 uuid; then " \
"zboot start 100000 0 0 0 $setup cmdline; " \
"zboot load; zboot setup; zboot dump; zboot go;" \
"fi"
diff --git a/include/dm/of_extra.h b/include/dm/of_extra.h
index ca15df21b0..fc4f974319 100644
--- a/include/dm/of_extra.h
+++ b/include/dm/of_extra.h
@@ -11,7 +11,11 @@
enum fmap_compress_t {
FMAP_COMPRESS_NONE,
+ FMAP_COMPRESS_LZMA,
FMAP_COMPRESS_LZ4,
+
+ FMAP_COMPRESS_COUNT,
+ FMAP_COMPRESS_UNKNOWN,
};
enum fmap_hash_t {
@@ -30,6 +34,10 @@ struct fmap_entry {
enum fmap_hash_t hash_algo; /* Hash algorithm */
const uint8_t *hash; /* Hash value */
int hash_size; /* Hash size */
+ /* Node pointer if CBFS, else NULL */
+ const struct cbfs_cachenode *cbfs_node;
+ /* Hash node pointer if CBFS, else NULL */
+ const struct cbfs_cachenode *cbfs_hash_node;
};
/**
diff --git a/include/image.h b/include/image.h
index 138c83dd28..bcd126d262 100644
--- a/include/image.h
+++ b/include/image.h
@@ -886,6 +886,11 @@ static inline int image_check_type(const image_header_t *hdr, uint8_t type)
}
static inline int image_check_arch(const image_header_t *hdr, uint8_t arch)
{
+#ifndef USE_HOSTCC
+ /* Let's assume that sandbox can load any architecture */
+ if (IS_ENABLED(CONFIG_SANDBOX))
+ return true;
+#endif
return (image_get_arch(hdr) == arch) ||
(image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64);
}
diff --git a/include/malloc.h b/include/malloc.h
index e15e528a2e..024b18be00 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -880,6 +880,8 @@ extern Void_t* sbrk();
#else
+void malloc_simple_info(void);
+
#if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE)
#define malloc malloc_simple
#define realloc realloc_simple
@@ -887,7 +889,6 @@ extern Void_t* sbrk();
static inline void free(void *ptr) {}
void *calloc(size_t nmemb, size_t size);
void *realloc_simple(void *ptr, size_t size);
-void malloc_simple_info(void);
#else
# ifdef USE_DL_PREFIX
diff --git a/include/sandboxblockdev.h b/include/sandboxblockdev.h
index c1f0afb337..4006e942a0 100644
--- a/include/sandboxblockdev.h
+++ b/include/sandboxblockdev.h
@@ -14,6 +14,13 @@ struct host_block_dev {
int fd;
};
-int host_dev_bind(int dev, char *filename);
+/**
+ * host_dev_bind() - Bind or unbind a device
+ *
+ * @dev: Device number (0=first slot)
+ * @filename: Host filename to use, or NULL to unbind
+ * @removable: true if the block device should mark itself as removable
+ */
+int host_dev_bind(int dev, char *filename, bool removable);
#endif
diff --git a/include/smbios.h b/include/smbios.h
index ecc4fd1de3..ffeefb4737 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -14,6 +14,10 @@
#define SMBIOS_MAJOR_VER 3
#define SMBIOS_MINOR_VER 0
+enum {
+ SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
+};
+
/* SMBIOS structure types */
enum {
SMBIOS_BIOS_INFORMATION = 0,
@@ -269,4 +273,20 @@ const char *smbios_string(const struct smbios_header *header, int index);
*/
int smbios_update_version(const char *version);
+/**
+ * smbios_update_version_full() - Update the version string
+ *
+ * This can be called after the SMBIOS tables are written (e.g. after the U-Boot
+ * main loop has started) to update the BIOS version string (SMBIOS table 0).
+ * It scans for the correct place to put the version, so does not need U-Boot
+ * to have actually written the tables itself (e.g. if a previous bootloader
+ * did it).
+ *
+ * @smbios_tab: Start of SMBIOS tables
+ * @version: New version string to use
+ * @return 0 if OK, -ENOENT if no version string was previously written,
+ * -ENOSPC if the new string is too large to fit
+ */
+int smbios_update_version_full(void *smbios_tab, const char *version);
+
#endif /* _SMBIOS_H_ */
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 85cae32cc7..3d747c925b 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -35,6 +35,19 @@ struct dm_spi_flash_ops {
int (*write)(struct udevice *dev, u32 offset, size_t len,
const void *buf);
int (*erase)(struct udevice *dev, u32 offset, size_t len);
+ /**
+ * get_sw_write_prot() - Check state of software write-protect feature
+ *
+ * SPI flash chips can lock a region of the flash defined by a
+ * 'protected area'. This function checks if this protected area is
+ * defined.
+ *
+ * @dev: SPI flash device
+ * @return 0 if no region is write-protected, 1 if a region is
+ * write-protected, -ENOSYS if the driver does not implement this,
+ * other -ve value on error
+ */
+ int (*get_sw_write_prot)(struct udevice *dev);
};
/* Access the serial operations for a device */
@@ -77,6 +90,20 @@ int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
/**
+ * spl_flash_get_sw_write_prot() - Check state of software write-protect feature
+ *
+ * SPI flash chips can lock a region of the flash defined by a
+ * 'protected area'. This function checks if this protected area is
+ * defined.
+ *
+ * @dev: SPI flash device
+ * @return 0 if no region is write-protected, 1 if a region is
+ * write-protected, -ENOSYS if the driver does not implement this,
+ * other -ve value on error
+ */
+int spl_flash_get_sw_write_prot(struct udevice *dev);
+
+/**
* spi_flash_std_probe() - Probe a SPI flash device
*
* This is the standard internal method for probing a SPI flash device to
@@ -97,7 +124,9 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode);
/* Compatibility function - this is the old U-Boot API */
-void spi_flash_free(struct spi_flash *flash);
+static inline void spi_flash_free(struct spi_flash *flash)
+{
+}
static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
size_t len, void *buf)
diff --git a/include/sysinfo.h b/include/sysinfo.h
index 270ac1b377..68fad25a06 100644
--- a/include/sysinfo.h
+++ b/include/sysinfo.h
@@ -37,9 +37,13 @@ struct udevice;
enum sysinfo_id {
SYSINFO_ID_NONE,
+ /* For SMBIOS tables */
SYSINFO_ID_SMBIOS_SYSTEM_VERSION,
SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
+ /* For show_board_info() */
+ SYSINFO_ID_BOARD_MODEL,
+
/* First value available for downstream/board used */
SYSINFO_ID_USER = 0x1000,
};
diff --git a/lib/Kconfig b/lib/Kconfig
index 7288340614..80ff2443cb 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -642,7 +642,7 @@ menu "System tables"
config BLOBLIST_TABLES
bool "Put tables in a bloblist"
- depends on X86
+ depends on X86 && BLOBLIST
help
Normally tables are placed at address 0xf0000 and can be up to 64KB
long. With this option, tables are instead placed in the bloblist
diff --git a/lib/binman.c b/lib/binman.c
index 6040ec8924..530df6a4b4 100644
--- a/lib/binman.c
+++ b/lib/binman.c
@@ -128,8 +128,8 @@ int binman_select_subnode(const char *name)
if (!ofnode_valid(node))
return log_msg_ret("node", -ENOENT);
binman->image = node;
- log_debug("binman: Selected image subnode '%s'\n",
- ofnode_get_name(binman->image));
+ log_info("binman: Selected image subnode '%s'\n",
+ ofnode_get_name(binman->image));
return 0;
}
diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c
index b89f988ef9..34203f952c 100644
--- a/lib/smbios-parser.c
+++ b/lib/smbios-parser.c
@@ -3,6 +3,8 @@
* Copyright (C) 2020, Bachmann electronic GmbH
*/
+#define LOG_CATEGORY LOGC_BOOT
+
#include <common.h>
#include <smbios.h>
@@ -94,3 +96,39 @@ const char *smbios_string(const struct smbios_header *header, int index)
return string_from_smbios_table(header, index);
}
+
+int smbios_update_version_full(void *smbios_tab, const char *version)
+{
+ const struct smbios_header *hdr;
+ struct smbios_type0 *bios;
+ uint old_len, len;
+ char *ptr;
+
+ log_info("Updating SMBIOS table at %p\n", smbios_tab);
+ hdr = smbios_header(smbios_tab, SMBIOS_BIOS_INFORMATION);
+ if (!hdr)
+ return log_msg_ret("tab", -ENOENT);
+ bios = (struct smbios_type0 *)hdr;
+ ptr = (char *)smbios_string(hdr, bios->bios_ver);
+ if (!ptr)
+ return log_msg_ret("str", -ENOMEDIUM);
+
+ /*
+ * This string is supposed to have at least enough bytes and is
+ * padded with spaces. Update it, taking care not to move the
+ * \0 terminator, so that other strings in the string table
+ * are not disturbed. See smbios_add_string()
+ */
+ old_len = strnlen(ptr, SMBIOS_STR_MAX);
+ len = strnlen(version, SMBIOS_STR_MAX);
+ if (len > old_len)
+ return log_ret(-ENOSPC);
+
+ log_debug("Replacing SMBIOS type 0 version string '%s'\n", ptr);
+ memcpy(ptr, version, len);
+#ifdef LOG_DEBUG
+ print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0);
+#endif
+
+ return 0;
+}
diff --git a/lib/smbios.c b/lib/smbios.c
index 7d463c84a9..9eb226ec9f 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -20,10 +20,6 @@
DECLARE_GLOBAL_DATA_PTR;
-enum {
- SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
-};
-
/**
* struct smbios_ctx - context for writing SMBIOS tables
*
diff --git a/test/cmd/test_echo.c b/test/cmd/test_echo.c
index aa5cebc4e7..9d60d7d1a0 100644
--- a/test/cmd/test_echo.c
+++ b/test/cmd/test_echo.c
@@ -44,9 +44,10 @@ static int lib_test_hush_echo(struct unit_test_state *uts)
int i;
for (i = 0; i < ARRAY_SIZE(echo_data); ++i) {
+ ut_silence_console(uts);
console_record_reset_enable();
ut_assertok(run_command(echo_data[i].cmd, 0));
- gd->flags &= ~GD_FLG_RECORD;
+ ut_unsilence_console(uts);
console_record_readline(uts->actual_str,
sizeof(uts->actual_str));
ut_asserteq_str(echo_data[i].expected, uts->actual_str);
diff --git a/test/dm/sf.c b/test/dm/sf.c
index cc1fc4d69a..17d43fef3b 100644
--- a/test/dm/sf.c
+++ b/test/dm/sf.c
@@ -21,7 +21,7 @@
/* Simple test of sandbox SPI flash */
static int dm_test_spi_flash(struct unit_test_state *uts)
{
- struct udevice *dev;
+ struct udevice *dev, *emul;
int full_size = 0x200000;
int size = 0x10000;
u8 *src, *dst;
@@ -51,6 +51,14 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
ut_assertok(spi_flash_read_dm(dev, 0, size, dst));
ut_asserteq_mem(src, dst, size);
+ /* Try the write-protect stuff */
+ ut_assertok(uclass_first_device_err(UCLASS_SPI_EMUL, &emul));
+ ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+ sandbox_sf_set_block_protect(emul, 1);
+ ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
+ sandbox_sf_set_block_protect(emul, 0);
+ ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+
/* Check mapping */
ut_assertok(dm_spi_get_mmap(dev, &map_base, &map_size, &offset));
ut_asserteq(0x1000, map_base);
diff --git a/test/lib/test_print.c b/test/lib/test_print.c
index 12972f1bcd..a60a5a51f1 100644
--- a/test/lib/test_print.c
+++ b/test/lib/test_print.c
@@ -18,12 +18,14 @@ DECLARE_GLOBAL_DATA_PTR;
static int test_print_freq(struct unit_test_state *uts,
uint64_t freq, char *expected)
{
+ ut_silence_console(uts);
console_record_reset_enable();
print_freq(freq, ";\n");
- gd->flags &= ~GD_FLG_RECORD;
+ ut_unsilence_console(uts);
console_record_readline(uts->actual_str, sizeof(uts->actual_str));
ut_asserteq_str(expected, uts->actual_str);
ut_assertok(ut_check_console_end(uts));
+
return 0;
}
@@ -46,12 +48,14 @@ LIB_TEST(lib_test_print_freq, 0);
static int test_print_size(struct unit_test_state *uts,
uint64_t freq, char *expected)
{
+ ut_silence_console(uts);
console_record_reset_enable();
print_size(freq, ";\n");
- gd->flags &= ~GD_FLG_RECORD;
+ ut_unsilence_console(uts);
console_record_readline(uts->actual_str, sizeof(uts->actual_str));
ut_asserteq_str(expected, uts->actual_str);
ut_assertok(ut_check_console_end(uts));
+
return 0;
}
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 15314d1958..1aa2459d50 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -472,6 +472,13 @@ missing-msg:
information about what needs to be fixed. See missing-blob-help for the
message for each tag.
+no-expanded:
+ By default binman substitutes entries with expanded versions if available,
+ so that a `u-boot` entry type turns into `u-boot-expanded`, for example. The
+ `--no-expanded` command-line option disables this globally. The
+ `no-expanded` property disables this just for a single entry. Put the
+ `no-expanded` boolean property in the node to select this behaviour.
+
The attributes supported for images and sections are described below. Several
are similar to those for entries.
@@ -555,6 +562,13 @@ skip-at-start:
'end-at-4gb' property is not applicable where CONFIG_SYS_TEXT_BASE +
Image size != 4gb.
+align-default:
+ Specifies the default alignment for entries in this section, if they do
+ not specify an alignment. Note that this only applies to top-level entries
+ in the section (direct subentries), not any subentries of those entries.
+ This means that each section must specify its own default alignment, if
+ required.
+
Examples of the above options can be found in the tests. See the
tools/binman/test directory.
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index f6faa15562..a91211e93e 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -248,6 +248,19 @@ both of size 1MB.
+Entry: collection: An entry which contains a collection of other entries
+------------------------------------------------------------------------
+
+Properties / Entry arguments:
+ - content: List of phandles to entries to include
+
+This allows reusing the contents of other entries. The contents of the
+listed entries are combined to form this entry. This serves as a useful
+base class for entry types which need to process data from elsewhere in
+the image, not necessarily child entries.
+
+
+
Entry: cros-ec-rw: A blob entry which contains a Chromium OS read-write EC image
--------------------------------------------------------------------------------
@@ -783,6 +796,8 @@ Properties / Entry arguments: (see binman README for more information):
file, since the first 16 bytes are skipped when writing.
name-prefix: Adds a prefix to the name of every entry in the section
when writing out the map
+ align_default: Default alignment for this section, if no alignment is
+ given in the entry
Properties:
allow_missing: True if this section permits external blobs to be
@@ -863,7 +878,7 @@ U-Boot can access binman symbols at runtime. See:
in the binman README for more information.
Note that this entry is automatically replaced with u-boot-expanded unless
---no-expanded is used.
+--no-expanded is used or the node has a 'no-expanded' property.
@@ -984,7 +999,7 @@ The ELF file 'spl/u-boot-spl' must also be available for this to work, since
binman uses that to look up symbols to write into the SPL binary.
Note that this entry is automatically replaced with u-boot-spl-expanded
-unless --no-expanded is used.
+unless --no-expanded is used or the node has a 'no-expanded' property.
@@ -1113,7 +1128,7 @@ The ELF file 'tpl/u-boot-tpl' must also be available for this to work, since
binman uses that to look up symbols to write into the TPL binary.
Note that this entry is automatically replaced with u-boot-tpl-expanded
-unless --no-expanded is used.
+unless --no-expanded is used or the node has a 'no-expanded' property.
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 1cfa024a9f..70222718ea 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -164,7 +164,8 @@ class Entry(object):
if obj and expanded:
# Check whether to use the expanded entry
new_etype = etype + '-expanded'
- if obj.UseExpanded(node, etype, new_etype):
+ can_expand = not fdt_util.GetBool(node, 'no-expanded')
+ if can_expand and obj.UseExpanded(node, etype, new_etype):
etype = new_etype
else:
obj = None
@@ -200,6 +201,8 @@ class Entry(object):
if tools.NotPowerOfTwo(self.align):
raise ValueError("Node '%s': Alignment %s must be a power of two" %
(self._node.path, self.align))
+ if self.section and self.align is None:
+ self.align = self.section.align_default
self.pad_before = fdt_util.GetInt(self._node, 'pad-before', 0)
self.pad_after = fdt_util.GetInt(self._node, 'pad-after', 0)
self.align_size = fdt_util.GetInt(self._node, 'align-size')
@@ -437,6 +440,11 @@ class Entry(object):
"""Convenience function to raise an error referencing a node"""
raise ValueError("Node '%s': %s" % (self._node.path, msg))
+ def Info(self, msg):
+ """Convenience function to log info referencing a node"""
+ tag = "Info '%s'" % self._node.path
+ tout.Detail('%30s: %s' % (tag, msg))
+
def Detail(self, msg):
"""Convenience function to log detail referencing a node"""
tag = "Node '%s'" % self._node.path
@@ -476,9 +484,13 @@ class Entry(object):
"""
return self._node.path
- def GetData(self):
+ def GetData(self, required=True):
"""Get the contents of an entry
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
Returns:
bytes content of the entry, excluding any padding. If the entry is
compressed, the compressed data is returned
diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py
index 1daddeb822..44db7b9bb2 100644
--- a/tools/binman/etype/cbfs.py
+++ b/tools/binman/etype/cbfs.py
@@ -169,6 +169,7 @@ class Entry_cbfs(Entry):
super().__init__(section, etype, node)
self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86')
+ self.align_default = None
self._cbfs_entries = OrderedDict()
self._ReadSubnodes()
self.reader = None
diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
new file mode 100644
index 0000000000..1625575fe9
--- /dev/null
+++ b/tools/binman/etype/collection.py
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2021 Google LLC
+# Written by Simon Glass <sjg@chromium.org>
+#
+
+# Support for a collection of entries from other parts of an image
+
+from collections import OrderedDict
+import os
+
+from binman.entry import Entry
+from dtoc import fdt_util
+
+class Entry_collection(Entry):
+ """An entry which contains a collection of other entries
+
+ Properties / Entry arguments:
+ - content: List of phandles to entries to include
+
+ This allows reusing the contents of other entries. The contents of the
+ listed entries are combined to form this entry. This serves as a useful
+ base class for entry types which need to process data from elsewhere in
+ the image, not necessarily child entries.
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.content = fdt_util.GetPhandleList(self._node, 'content')
+ if not self.content:
+ self.Raise("Collection must have a 'content' property")
+
+ def GetContents(self, required):
+ """Get the contents of this entry
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry
+ """
+ # Join up all the data
+ self.Info('Getting contents, required=%s' % required)
+ data = b''
+ for entry_phandle in self.content:
+ entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
+ required)
+ if not required and entry_data is None:
+ self.Info('Contents not available yet')
+ # Data not available yet
+ return None
+ data += entry_data
+
+ self.Info('Returning contents size %x' % len(data))
+
+ return data
+
+ def ObtainContents(self):
+ data = self.GetContents(False)
+ if data is None:
+ return False
+ self.SetContents(data)
+ return True
+
+ def ProcessContents(self):
+ # The blob may have changed due to WriteSymbols()
+ data = self.GetContents(True)
+ return self.ProcessContentsUpdate(data)
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index e9f82729ab..e49977522e 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -36,6 +36,7 @@ class Entry_mkimage(Entry):
super().__init__(section, etype, node)
self._args = fdt_util.GetString(self._node, 'args').split(' ')
self._mkimage_entries = OrderedDict()
+ self.align_default = None
self._ReadSubnodes()
def ObtainContents(self):
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index cce1500b4e..c3bac026c1 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -36,6 +36,8 @@ class Entry_section(Entry):
file, since the first 16 bytes are skipped when writing.
name-prefix: Adds a prefix to the name of every entry in the section
when writing out the map
+ align_default: Default alignment for this section, if no alignment is
+ given in the entry
Properties:
allow_missing: True if this section permits external blobs to be
@@ -76,6 +78,7 @@ class Entry_section(Entry):
if self._skip_at_start is None:
self._skip_at_start = 0
self._name_prefix = fdt_util.GetString(self._node, 'name-prefix')
+ self.align_default = fdt_util.GetInt(self._node, 'align-default', 0)
filename = fdt_util.GetString(self._node, 'filename')
if filename:
self._filename = filename
@@ -180,7 +183,7 @@ class Entry_section(Entry):
return data
- def _BuildSectionData(self):
+ def _BuildSectionData(self, required):
"""Build the contents of a section
This places all entries at the right place, dealing with padding before
@@ -188,13 +191,20 @@ class Entry_section(Entry):
pad-before and pad-after properties in the section items) since that is
handled by the parent section.
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
Returns:
Contents of the section (bytes)
"""
section_data = b''
for entry in self._entries.values():
- data = self.GetPaddedDataForEntry(entry, entry.GetData())
+ entry_data = entry.GetData(required)
+ if not required and entry_data is None:
+ return None
+ data = self.GetPaddedDataForEntry(entry, entry_data)
# Handle empty space before the entry
pad = (entry.offset or 0) - self._skip_at_start - len(section_data)
if pad > 0:
@@ -226,18 +236,24 @@ class Entry_section(Entry):
data = self.GetData()
return section.GetPaddedDataForEntry(self, data)
- def GetData(self):
+ def GetData(self, required=True):
"""Get the contents of an entry
This builds the contents of the section, stores this as the contents of
the section and returns it
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
Returns:
bytes content of the section, made up for all all of its subentries.
This excludes any padding. If the section is compressed, the
compressed data is returned
"""
- data = self._BuildSectionData()
+ data = self._BuildSectionData(required)
+ if data is None:
+ return None
self.SetContents(data)
return data
@@ -263,7 +279,7 @@ class Entry_section(Entry):
self._SortEntries()
self._ExpandEntries()
- data = self._BuildSectionData()
+ data = self._BuildSectionData(True)
self.SetContents(data)
self.CheckSize()
@@ -360,16 +376,20 @@ class Entry_section(Entry):
def GetEntries(self):
return self._entries
- def GetContentsByPhandle(self, phandle, source_entry):
+ def GetContentsByPhandle(self, phandle, source_entry, required):
"""Get the data contents of an entry specified by a phandle
This uses a phandle to look up a node and and find the entry
- associated with it. Then it returnst he contents of that entry.
+ associated with it. Then it returns the contents of that entry.
+
+ The node must be a direct subnode of this section.
Args:
phandle: Phandle to look up (integer)
source_entry: Entry containing that phandle (used for error
reporting)
+ required: True if the data must be present, False if it is OK to
+ return None
Returns:
data from associated entry (as a string), or None if not found
@@ -379,7 +399,7 @@ class Entry_section(Entry):
source_entry.Raise("Cannot find node for phandle %d" % phandle)
for entry in self._entries.values():
if entry._node == node:
- return entry.GetData()
+ return entry.GetData(required)
source_entry.Raise("Cannot find entry for node '%s'" % node.name)
def LookupSymbol(self, sym_name, optional, msg, base_addr, entries=None):
diff --git a/tools/binman/etype/u_boot.py b/tools/binman/etype/u_boot.py
index d2eaba6d4a..e8d180a46d 100644
--- a/tools/binman/etype/u_boot.py
+++ b/tools/binman/etype/u_boot.py
@@ -25,7 +25,7 @@ class Entry_u_boot(Entry_blob):
in the binman README for more information.
Note that this entry is automatically replaced with u-boot-expanded unless
- --no-expanded is used.
+ --no-expanded is used or the node has a 'no-expanded' property.
"""
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
diff --git a/tools/binman/etype/u_boot_spl.py b/tools/binman/etype/u_boot_spl.py
index 1c39f98251..6f79bf59f9 100644
--- a/tools/binman/etype/u_boot_spl.py
+++ b/tools/binman/etype/u_boot_spl.py
@@ -32,7 +32,7 @@ class Entry_u_boot_spl(Entry_blob):
binman uses that to look up symbols to write into the SPL binary.
Note that this entry is automatically replaced with u-boot-spl-expanded
- unless --no-expanded is used.
+ unless --no-expanded is used or the node has a 'no-expanded' property.
"""
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
diff --git a/tools/binman/etype/u_boot_tpl.py b/tools/binman/etype/u_boot_tpl.py
index 95d9bd6b20..0c575df8cd 100644
--- a/tools/binman/etype/u_boot_tpl.py
+++ b/tools/binman/etype/u_boot_tpl.py
@@ -32,7 +32,7 @@ class Entry_u_boot_tpl(Entry_blob):
binman uses that to look up symbols to write into the TPL binary.
Note that this entry is automatically replaced with u-boot-tpl-expanded
- unless --no-expanded is used.
+ unless --no-expanded is used or the node has a 'no-expanded' property.
"""
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py
index eba5351dd5..c0a6a28c94 100644
--- a/tools/binman/etype/vblock.py
+++ b/tools/binman/etype/vblock.py
@@ -9,12 +9,13 @@
from collections import OrderedDict
import os
-from binman.entry import Entry, EntryArg
+from binman.entry import EntryArg
+from binman.etype.collection import Entry_collection
from dtoc import fdt_util
from patman import tools
-class Entry_vblock(Entry):
+class Entry_vblock(Entry_collection):
"""An entry which contains a Chromium OS verified boot block
Properties / Entry arguments:
@@ -37,9 +38,6 @@ class Entry_vblock(Entry):
"""
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
- self.content = fdt_util.GetPhandleList(self._node, 'content')
- if not self.content:
- self.Raise("Vblock must have a 'content' property")
(self.keydir, self.keyblock, self.signprivate, self.version,
self.kernelkey, self.preamble_flags) = self.GetEntryArgsOrProps([
EntryArg('keydir', str),
@@ -49,15 +47,21 @@ class Entry_vblock(Entry):
EntryArg('kernelkey', str),
EntryArg('preamble-flags', int)])
- def GetVblock(self):
+ def GetVblock(self, required):
+ """Get the contents of this entry
+
+ Args:
+ required: True if the data must be present, False if it is OK to
+ return None
+
+ Returns:
+ bytes content of the entry, which is the signed vblock for the
+ provided data
+ """
# Join up the data files to be signed
- input_data = b''
- for entry_phandle in self.content:
- data = self.section.GetContentsByPhandle(entry_phandle, self)
- if data is None:
- # Data not available yet
- return False
- input_data += data
+ input_data = self.GetContents(required)
+ if input_data is None:
+ return None
uniq = self.GetUniqueName()
output_fname = tools.GetOutputFilename('vblock.%s' % uniq)
@@ -79,13 +83,13 @@ class Entry_vblock(Entry):
return tools.ReadFile(output_fname)
def ObtainContents(self):
- data = self.GetVblock()
- if data is False:
+ data = self.GetVblock(False)
+ if data is None:
return False
self.SetContents(data)
return True
def ProcessContents(self):
# The blob may have changed due to WriteSymbols()
- data = self.GetVblock()
+ data = self.GetVblock(True)
return self.ProcessContentsUpdate(data)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 81c213a908..89fe6612e1 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -1344,13 +1344,19 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('052_u_boot_spl_nodtb.dts')
self.assertEqual(U_BOOT_SPL_NODTB_DATA, data[:len(U_BOOT_SPL_NODTB_DATA)])
- def checkSymbols(self, dts, base_data, u_boot_offset):
+ def checkSymbols(self, dts, base_data, u_boot_offset, entry_args=None,
+ use_expanded=False):
"""Check the image contains the expected symbol values
Args:
dts: Device tree file to use for test
base_data: Data before and after 'u-boot' section
u_boot_offset: Offset of 'u-boot' section in image
+ entry_args: Dict of entry args to supply to binman
+ key: arg name
+ value: value of that arg
+ use_expanded: True to use expanded entries where available, e.g.
+ 'u-boot-expanded' instead of 'u-boot'
"""
elf_fname = self.ElfTestFile('u_boot_binman_syms')
syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
@@ -1359,7 +1365,8 @@ class TestFunctional(unittest.TestCase):
addr)
self._SetupSplElf('u_boot_binman_syms')
- data = self._DoReadFile(dts)
+ data = self._DoReadFileDtb(dts, entry_args=entry_args,
+ use_expanded=use_expanded)[0]
# The image should contain the symbols from u_boot_binman_syms.c
# Note that image_pos is adjusted by the base address of the image,
# which is 0x10 in our test image
@@ -1377,7 +1384,7 @@ class TestFunctional(unittest.TestCase):
def testSymbolsNoDtb(self):
"""Test binman can assign symbols embedded in U-Boot SPL"""
- self.checkSymbols('192_symbols_nodtb.dts',
+ self.checkSymbols('196_symbols_nodtb.dts',
U_BOOT_SPL_NODTB_DATA + U_BOOT_SPL_DTB_DATA,
0x38)
@@ -1711,7 +1718,7 @@ class TestFunctional(unittest.TestCase):
"""Test we detect a vblock which has no content to sign"""
with self.assertRaises(ValueError) as e:
self._DoReadFile('075_vblock_no_content.dts')
- self.assertIn("Node '/binman/vblock': Vblock must have a 'content' "
+ self.assertIn("Node '/binman/vblock': Collection must have a 'content' "
'property', str(e.exception))
def testVblockBadPhandle(self):
@@ -4460,5 +4467,47 @@ class TestFunctional(unittest.TestCase):
start += fdt_size + len(U_BOOT_TPL_DATA)
self.assertEqual(len(data), start)
+ def testSymbolsExpanded(self):
+ """Test binman can assign symbols in expanded entries"""
+ entry_args = {
+ 'spl-dtb': '1',
+ }
+ self.checkSymbols('197_symbols_expand.dts', U_BOOT_SPL_NODTB_DATA +
+ U_BOOT_SPL_DTB_DATA, 0x38,
+ entry_args=entry_args, use_expanded=True)
+
+ def testCollection(self):
+ """Test a collection"""
+ data = self._DoReadFile('198_collection.dts')
+ self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA +
+ tools.GetBytes(0xff, 2) + U_BOOT_NODTB_DATA +
+ tools.GetBytes(0xfe, 3) + U_BOOT_DTB_DATA,
+ data)
+
+ def testCollectionSection(self):
+ """Test a collection where a section must be built first"""
+ # Sections never have their contents when GetData() is called, but when
+ # _BuildSectionData() is called with required=True, a section will force
+ # building the contents, producing an error is anything is still
+ # missing.
+ data = self._DoReadFile('199_collection_section.dts')
+ section = U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA
+ self.assertEqual(section + U_BOOT_DATA + tools.GetBytes(0xff, 2) +
+ section + tools.GetBytes(0xfe, 3) + U_BOOT_DATA,
+ data)
+
+ def testAlignDefault(self):
+ """Test that default alignment works on sections"""
+ data = self._DoReadFile('200_align_default.dts')
+ expected = (U_BOOT_DATA + tools.GetBytes(0, 8 - len(U_BOOT_DATA)) +
+ U_BOOT_DATA)
+ # Special alignment for section
+ expected += tools.GetBytes(0, 32 - len(expected))
+ # No alignment within the nested section
+ expected += U_BOOT_DATA + U_BOOT_NODTB_DATA;
+ # Now the final piece, which should be default-aligned
+ expected += tools.GetBytes(0, 88 - len(expected)) + U_BOOT_NODTB_DATA
+ self.assertEqual(expected, data)
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/192_symbols_nodtb.dts b/tools/binman/test/196_symbols_nodtb.dts
index 5c900d6070..5c900d6070 100644
--- a/tools/binman/test/192_symbols_nodtb.dts
+++ b/tools/binman/test/196_symbols_nodtb.dts
diff --git a/tools/binman/test/197_symbols_expand.dts b/tools/binman/test/197_symbols_expand.dts
new file mode 100644
index 0000000000..8aee76dc75
--- /dev/null
+++ b/tools/binman/test/197_symbols_expand.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ pad-byte = <0xff>;
+ u-boot-spl {
+ };
+
+ u-boot {
+ offset = <0x38>;
+ no-expanded;
+ };
+
+ u-boot-spl2 {
+ type = "u-boot-spl";
+ };
+ };
+};
diff --git a/tools/binman/test/198_collection.dts b/tools/binman/test/198_collection.dts
new file mode 100644
index 0000000000..484a1b0050
--- /dev/null
+++ b/tools/binman/test/198_collection.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ collection {
+ content = <&u_boot_nodtb &dtb>;
+ };
+ fill {
+ size = <2>;
+ fill-byte = [ff];
+ };
+ u_boot_nodtb: u-boot-nodtb {
+ };
+ fill2 {
+ type = "fill";
+ size = <3>;
+ fill-byte = [fe];
+ };
+ dtb: u-boot-dtb {
+ };
+ };
+};
diff --git a/tools/binman/test/199_collection_section.dts b/tools/binman/test/199_collection_section.dts
new file mode 100644
index 0000000000..03a73194c3
--- /dev/null
+++ b/tools/binman/test/199_collection_section.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ collection {
+ content = <&section &u_boot>;
+ };
+ fill {
+ size = <2>;
+ fill-byte = [ff];
+ };
+ section: section {
+ u-boot-nodtb {
+ };
+ u-boot-dtb {
+ };
+ };
+ fill2 {
+ type = "fill";
+ size = <3>;
+ fill-byte = [fe];
+ };
+ u_boot: u-boot {
+ no-expanded;
+ };
+ };
+};
diff --git a/tools/binman/test/200_align_default.dts b/tools/binman/test/200_align_default.dts
new file mode 100644
index 0000000000..1b155770d4
--- /dev/null
+++ b/tools/binman/test/200_align_default.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ align-default = <8>;
+ u-boot {
+ };
+
+ u-boot-align {
+ type = "u-boot";
+ };
+
+ section {
+ align = <32>;
+ u-boot {
+ };
+
+ u-boot-nodtb {
+ };
+ };
+
+ u-boot-nodtb {
+ };
+ };
+};
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 25ce5136eb..3996971e39 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -103,6 +103,8 @@ class Prop:
"""A device tree property
Properties:
+ node: Node containing this property
+ offset: Offset of the property (None if still to be synced)
name: Property name (as per the device tree)
value: Property value as a string of bytes, or a list of strings of
bytes
@@ -114,7 +116,7 @@ class Prop:
self.name = name
self.value = None
self.bytes = bytes(data)
- self.dirty = False
+ self.dirty = offset is None
if not data:
self.type = Type.BOOL
self.value = True
@@ -228,9 +230,14 @@ class Prop:
Raises:
FdtException if auto_resize is False and there is not enough space
"""
- if self._offset is None or self.dirty:
+ if self.dirty:
node = self._node
fdt_obj = node._fdt._fdt_obj
+ node_name = fdt_obj.get_name(node._offset)
+ if node_name and node_name != node.name:
+ raise ValueError("Internal error, node '%s' name mismatch '%s'" %
+ (node.path, node_name))
+
if auto_resize:
while fdt_obj.setprop(node.Offset(), self.name, self.bytes,
(libfdt.NOSPACE,)) == -libfdt.NOSPACE:
@@ -239,13 +246,15 @@ class Prop:
fdt_obj.setprop(node.Offset(), self.name, self.bytes)
else:
fdt_obj.setprop(node.Offset(), self.name, self.bytes)
+ self.dirty = False
class Node:
"""A device tree node
Properties:
- offset: Integer offset in the device tree
+ parent: Parent Node
+ offset: Integer offset in the device tree (None if to be synced)
name: Device tree node tname
path: Full path to node, along with the node name itself
_fdt: Device tree object
@@ -324,6 +333,11 @@ class Node:
fdt_obj = self._fdt._fdt_obj
if self._offset != my_offset:
self._offset = my_offset
+ name = fdt_obj.get_name(self._offset)
+ if name and self.name != name:
+ raise ValueError("Internal error, node '%s' name mismatch '%s'" %
+ (self.path, name))
+
offset = fdt_obj.first_subnode(self._offset, QUIET_NOTFOUND)
for subnode in self.subnodes:
if subnode.name != fdt_obj.get_name(offset):
@@ -339,8 +353,8 @@ class Node:
p = fdt_obj.get_property_by_offset(poffset)
prop = self.props.get(p.name)
if not prop:
- raise ValueError("Internal error, property '%s' missing, "
- 'offset %d' % (p.name, poffset))
+ raise ValueError("Internal error, node '%s' property '%s' missing, "
+ 'offset %d' % (self.path, p.name, poffset))
prop.RefreshOffset(poffset)
poffset = fdt_obj.next_property_offset(poffset, QUIET_NOTFOUND)
@@ -447,8 +461,13 @@ class Node:
Args:
prop_name: Name of property to add
val: Bytes value of property
+
+ Returns:
+ Prop added
"""
- self.props[prop_name] = Prop(self, None, prop_name, val)
+ prop = Prop(self, None, prop_name, val)
+ self.props[prop_name] = prop
+ return prop
def AddString(self, prop_name, val):
"""Add a new string property to a node
@@ -459,9 +478,12 @@ class Node:
Args:
prop_name: Name of property to add
val: String value of property
+
+ Returns:
+ Prop added
"""
val = bytes(val, 'utf-8')
- self.AddData(prop_name, val + b'\0')
+ return self.AddData(prop_name, val + b'\0')
def AddInt(self, prop_name, val):
"""Add a new integer property to a node
@@ -472,8 +494,11 @@ class Node:
Args:
prop_name: Name of property to add
val: Integer value of property
+
+ Returns:
+ Prop added
"""
- self.AddData(prop_name, struct.pack('>I', val))
+ return self.AddData(prop_name, struct.pack('>I', val))
def AddSubnode(self, name):
"""Add a new subnode to the node
@@ -499,9 +524,13 @@ class Node:
auto_resize: Resize the device tree automatically if it does not
have enough space for the update
+ Returns:
+ True if the node had to be added, False if it already existed
+
Raises:
FdtException if auto_resize is False and there is not enough space
"""
+ added = False
if self._offset is None:
# The subnode doesn't exist yet, so add it
fdt_obj = self._fdt._fdt_obj
@@ -515,23 +544,45 @@ class Node:
else:
offset = fdt_obj.add_subnode(self.parent._offset, self.name)
self._offset = offset
+ added = True
- # Sync subnodes in reverse so that we don't disturb node offsets for
- # nodes that are earlier in the DT. This avoids an O(n^2) rescan of
- # node offsets.
+ # Sync the existing subnodes first, so that we can rely on the offsets
+ # being correct. As soon as we add new subnodes, it pushes all the
+ # existing subnodes up.
for node in reversed(self.subnodes):
- node.Sync(auto_resize)
+ if node._offset is not None:
+ node.Sync(auto_resize)
- # Sync properties now, whose offsets should not have been disturbed.
- # We do this after subnodes, since this disturbs the offsets of these
- # properties. Note that new properties will have an offset of None here,
- # which Python 3 cannot sort against int. So use a large value instead
- # to ensure that the new properties are added first.
+ # Sync subnodes in reverse so that we get the expected order. Each
+ # new node goes at the start of the subnode list. This avoids an O(n^2)
+ # rescan of node offsets.
+ num_added = 0
+ for node in reversed(self.subnodes):
+ if node.Sync(auto_resize):
+ num_added += 1
+ if num_added:
+ # Reorder our list of nodes to put the new ones first, since that's
+ # what libfdt does
+ old_count = len(self.subnodes) - num_added
+ subnodes = self.subnodes[old_count:] + self.subnodes[:old_count]
+ self.subnodes = subnodes
+
+ # Sync properties now, whose offsets should not have been disturbed,
+ # since properties come before subnodes. This is done after all the
+ # subnode processing above, since updating properties can disturb the
+ # offsets of those subnodes.
+ # Properties are synced in reverse order, with new properties added
+ # before existing properties are synced. This ensures that the offsets
+ # of earlier properties are not disturbed.
+ # Note that new properties will have an offset of None here, which
+ # Python cannot sort against int. So use a large value instead so that
+ # new properties are added first.
prop_list = sorted(self.props.values(),
key=lambda prop: prop._offset or 1 << 31,
reverse=True)
for prop in prop_list:
prop.Sync(auto_resize)
+ return added
class Fdt:
@@ -642,8 +693,9 @@ class Fdt:
Raises:
FdtException if auto_resize is False and there is not enough space
"""
+ self.CheckCache()
self._root.Sync(auto_resize)
- self.Invalidate()
+ self.Refresh()
def Pack(self):
"""Pack the device tree down to its minimum size
@@ -652,7 +704,7 @@ class Fdt:
build up in the device tree binary.
"""
CheckErr(self._fdt_obj.pack(), 'pack')
- self.Invalidate()
+ self.Refresh()
def GetContents(self):
"""Get the contents of the FDT
@@ -704,11 +756,11 @@ class Fdt:
if self._cached_offsets:
return
self.Refresh()
- self._cached_offsets = True
def Refresh(self):
"""Refresh the offset cache"""
self._root.Refresh(0)
+ self._cached_offsets = True
def GetStructOffset(self, offset):
"""Get the file offset of a given struct offset
diff --git a/tools/dtoc/test/dtoc_test_simple.dts b/tools/dtoc/test/dtoc_test_simple.dts
index d8ab8613ee..b5c1274bb7 100644
--- a/tools/dtoc/test/dtoc_test_simple.dts
+++ b/tools/dtoc/test/dtoc_test_simple.dts
@@ -56,4 +56,8 @@
low-power;
};
};
+
+ orig-node {
+ orig = <1 23 4>;
+ };
};
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index 1c3a8a2ab1..856392b1bd 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -154,6 +154,7 @@ class TestNode(unittest.TestCase):
def setUp(self):
self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
self.node = self.dtb.GetNode('/spl-test')
+ self.fdt = self.dtb.GetFdtObj()
def testOffset(self):
"""Tests that we can obtain the offset of a node"""
@@ -197,7 +198,7 @@ class TestNode(unittest.TestCase):
def testRefreshExtraNode(self):
"""Test refreshing offsets when an expected node is missing"""
# Delete it from the device tre, not our tables
- self.dtb.GetFdtObj().del_node(self.node.Offset())
+ self.fdt.del_node(self.node.Offset())
with self.assertRaises(ValueError) as e:
self.dtb.Refresh()
self.assertIn('Internal error, node name mismatch '
@@ -209,7 +210,7 @@ class TestNode(unittest.TestCase):
del self.node.props['notstring']
with self.assertRaises(ValueError) as e:
self.dtb.Refresh()
- self.assertIn("Internal error, property 'notstring' missing, offset ",
+ self.assertIn("Internal error, node '/spl-test' property 'notstring' missing, offset ",
str(e.exception))
def testLookupPhandle(self):
@@ -220,6 +221,66 @@ class TestNode(unittest.TestCase):
target = dtb.GetNode('/phandle-target')
self.assertEqual(target, dtb.LookupPhandle(fdt32_to_cpu(prop.value)))
+ def testAddNodeSpace(self):
+ """Test adding a single node when out of space"""
+ self.fdt.pack()
+ self.node.AddSubnode('subnode')
+ with self.assertRaises(libfdt.FdtException) as e:
+ self.dtb.Sync(auto_resize=False)
+ self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
+
+ self.dtb.Sync(auto_resize=True)
+ offset = self.fdt.path_offset('/spl-test/subnode')
+ self.assertTrue(offset > 0)
+
+ def testAddNodes(self):
+ """Test adding various subnode and properies"""
+ node = self.dtb.GetNode('/i2c@0')
+
+ # Add one more node next to the pmic one
+ sn1 = node.AddSubnode('node-one')
+ sn1.AddInt('integer-a', 12)
+ sn1.AddInt('integer-b', 23)
+
+ # Sync so that everything is clean
+ self.dtb.Sync(auto_resize=True)
+
+ # Add two subnodes next to pmic and node-one
+ sn2 = node.AddSubnode('node-two')
+ sn2.AddInt('integer-2a', 34)
+ sn2.AddInt('integer-2b', 45)
+
+ sn3 = node.AddSubnode('node-three')
+ sn3.AddInt('integer-3', 123)
+
+ # Add a property to the node after i2c@0 to check that this is not
+ # disturbed by adding a subnode to i2c@0
+ orig_node = self.dtb.GetNode('/orig-node')
+ orig_node.AddInt('integer-4', 456)
+
+ # Add a property to the pmic node to check that pmic properties are not
+ # disturbed
+ pmic = self.dtb.GetNode('/i2c@0/pmic@9')
+ pmic.AddInt('integer-5', 567)
+
+ self.dtb.Sync(auto_resize=True)
+
+ def testRefreshNameMismatch(self):
+ """Test name mismatch when syncing nodes and properties"""
+ prop = self.node.AddInt('integer-a', 12)
+
+ wrong_offset = self.dtb.GetNode('/i2c@0')._offset
+ self.node._offset = wrong_offset
+ with self.assertRaises(ValueError) as e:
+ self.dtb.Sync()
+ self.assertIn("Internal error, node '/spl-test' name mismatch 'i2c@0'",
+ str(e.exception))
+
+ with self.assertRaises(ValueError) as e:
+ self.node.Refresh(wrong_offset)
+ self.assertIn("Internal error, node '/spl-test' name mismatch 'i2c@0'",
+ str(e.exception))
+
class TestProp(unittest.TestCase):
"""Test operation of the Prop class"""
@@ -385,17 +446,6 @@ class TestProp(unittest.TestCase):
self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
self.dtb.Sync(auto_resize=True)
- def testAddNode(self):
- self.fdt.pack()
- self.node.AddSubnode('subnode')
- with self.assertRaises(libfdt.FdtException) as e:
- self.dtb.Sync(auto_resize=False)
- self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
-
- self.dtb.Sync(auto_resize=True)
- offset = self.fdt.path_offset('/spl-test/subnode')
- self.assertTrue(offset > 0)
-
def testAddMore(self):
"""Test various other methods for adding and setting properties"""
self.node.AddZeroProp('one')