From patchwork Sun Apr 26 15:12:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238489 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:53 -0600 Subject: [PATCH v4 1/9] x86: fsp: Allow skipping init code when chain loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-2-sjg@chromium.org> It is useful to be able to boot the same x86 image on a device with or without a first-stage bootloader. For example, with chromebook_coral, it is helpful for testing to be able to boot the same U-Boot (complete with FSP) on bare metal and from coreboot. It allows checking of things like CPU speed, comparing registers, ACPI tables and the like. When U-Boot is not the first-stage bootloader much of this code is not needed and can break booting. Add checks for this to the FSP code. Rather than checking for the amount of available SDRAM, just use 1GB in this situation, which should be safe. Using 2GB may run into a memory hole on some SoCs. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: None Changes in v3: None Changes in v2: None arch/x86/lib/fsp/fsp_dram.c | 8 ++++++++ arch/x86/lib/fsp/fsp_graphics.c | 3 +++ arch/x86/lib/fsp2/fsp_dram.c | 10 ++++++++++ arch/x86/lib/fsp2/fsp_init.c | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c index 9ce0ddf0d3..15e82de2fe 100644 --- a/arch/x86/lib/fsp/fsp_dram.c +++ b/arch/x86/lib/fsp/fsp_dram.c @@ -44,6 +44,14 @@ int dram_init_banksize(void) phys_addr_t low_end; uint bank; + if (!ll_boot_init()) { + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; + + mtrr_add_request(MTRR_TYPE_WRBACK, 0, gd->ram_size); + return 0; + } + low_end = 0; for (bank = 1, hdr = gd->arch.hob_list; bank < CONFIG_NR_DRAM_BANKS && !end_of_hob(hdr); diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c index 226c7e66b3..98b762209f 100644 --- a/arch/x86/lib/fsp/fsp_graphics.c +++ b/arch/x86/lib/fsp/fsp_graphics.c @@ -78,6 +78,9 @@ static int fsp_video_probe(struct udevice *dev) struct vesa_mode_info *vesa = &mode_info.vesa; int ret; + if (!ll_boot_init()) + return 0; + printf("Video: "); /* Initialize vesa_mode_info structure */ diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c index c8f2c09b6a..3869c53c5f 100644 --- a/arch/x86/lib/fsp2/fsp_dram.c +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -12,11 +12,18 @@ #include #include #include +#include int dram_init(void) { int ret; + if (!ll_boot_init()) { + /* Use a small and safe amount of 1GB */ + gd->ram_size = SZ_1G; + + return 0; + } if (spl_phase() == PHASE_SPL) { #ifdef CONFIG_HAVE_ACPI_RESUME bool s3wake = gd->arch.prev_sleep_state == ACPI_S3; @@ -68,6 +75,9 @@ int dram_init(void) ulong board_get_usable_ram_top(ulong total_size) { + if (!ll_boot_init()) + return gd->ram_size; + #if CONFIG_IS_ENABLED(HANDOFF) struct spl_handoff *ho = gd->spl_handoff; diff --git a/arch/x86/lib/fsp2/fsp_init.c b/arch/x86/lib/fsp2/fsp_init.c index da9bd6b45c..c7dc2ea257 100644 --- a/arch/x86/lib/fsp2/fsp_init.c +++ b/arch/x86/lib/fsp2/fsp_init.c @@ -23,7 +23,7 @@ int arch_cpu_init_dm(void) int ret; /* Make sure pads are set up early in U-Boot */ - if (spl_phase() != PHASE_BOARD_F) + if (!ll_boot_init() || spl_phase() != PHASE_BOARD_F) return 0; /* Probe all pinctrl devices to set up the pads */ From patchwork Sun Apr 26 15:12:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238492 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:54 -0600 Subject: [PATCH v4 2/9] x86: apl: Skip init code when chain loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-3-sjg@chromium.org> When U-Boot is not the first-stage bootloader the FSP-S init must be skipped. Update it to add a check. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: None Changes in v3: None Changes in v2: None arch/x86/cpu/apollolake/fsp_s.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c index 17cf1682ad..7ef169b147 100644 --- a/arch/x86/cpu/apollolake/fsp_s.c +++ b/arch/x86/cpu/apollolake/fsp_s.c @@ -566,6 +566,8 @@ int arch_fsp_init_r(void) struct udevice *dev, *itss; int ret; + if (!ll_boot_init()) + return 0; /* * This must be called before any devices are probed. Put any probing * into arch_fsps_preinit() above. From patchwork Sun Apr 26 15:12:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238493 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:55 -0600 Subject: [PATCH v4 3/9] x86: cpu: Skip init code when chain loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-4-sjg@chromium.org> When U-Boot is not the first-stage bootloader the interrupt and cache init must be skipped, as well as init for various peripherals. Update the code to add checks for this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: None Changes in v3: None Changes in v2: - Drop the other check in interrupt_init() which is not needed now arch/x86/cpu/cpu.c | 4 +++- arch/x86/cpu/i386/interrupt.c | 6 ++++-- arch/x86/lib/init_helpers.c | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index cec04b481b..8526e856d7 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -239,8 +239,10 @@ int cpu_init_r(void) struct udevice *dev; int ret; - if (!ll_boot_init()) + if (!ll_boot_init()) { + uclass_first_device(UCLASS_PCI, &dev); return 0; + } ret = x86_init_cpus(); if (ret) diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c index 4c7e9ea215..e67a116ac1 100644 --- a/arch/x86/cpu/i386/interrupt.c +++ b/arch/x86/cpu/i386/interrupt.c @@ -264,6 +264,9 @@ int interrupt_init(void) struct udevice *dev; int ret; + if (!ll_boot_init()) + return 0; + /* Try to set up the interrupt router, but don't require one */ ret = irq_first_device_type(X86_IRQT_BASE, &dev); if (ret && ret != -ENODEV) @@ -295,8 +298,7 @@ int interrupt_init(void) * TODO(sjg at chromium.org): But we don't handle these correctly when * booted from EFI. */ - if (ll_boot_init()) - enable_interrupts(); + enable_interrupts(); #endif return 0; diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 5bb55e256f..d906b528b3 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -30,6 +30,9 @@ int init_cache_f_r(void) return ret; } + if (!ll_boot_init()) + return 0; + /* Initialise the CPU cache(s) */ return init_cache(); } From patchwork Sun Apr 26 15:12:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238491 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:56 -0600 Subject: [PATCH v4 4/9] pci: Avoid auto-config when chain loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426091237.v4.4.Idfdc61ea876ea7aeafb2370394ac2c922344f9b4@changeid> When U-Boot is not the first-stage bootloader we don't want to re-configure the PCI devices, since this has already been done. Add a check to avoid this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: None Changes in v3: None Changes in v2: - Drop patch 'dm: Avoid initing built-in devices when chain loading' drivers/pci/pci-uclass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index d2e10d6868..7f46e901fb 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1009,7 +1009,7 @@ static int pci_uclass_post_probe(struct udevice *bus) if (ret) return ret; - if (CONFIG_IS_ENABLED(PCI_PNP) && + if (CONFIG_IS_ENABLED(PCI_PNP) && ll_boot_init() && (!hose->skip_auto_config_until_reloc || (gd->flags & GD_FLG_RELOC))) { ret = pci_auto_config_devices(bus); @@ -1031,7 +1031,7 @@ static int pci_uclass_post_probe(struct udevice *bus) * Note we only call this 1) after U-Boot is relocated, and 2) * root bus has finished probing. */ - if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) { + if ((gd->flags & GD_FLG_RELOC) && bus->seq == 0 && ll_boot_init()) { ret = fsp_init_phase_pci(); if (ret) return ret; From patchwork Sun Apr 26 15:12:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238490 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:57 -0600 Subject: [PATCH v4 5/9] board: Add a gd flag for chain loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-5-sjg@chromium.org> When U-Boot is run from another boot loader, much of the low-level init needs to be skipped. Add a flag for this and adjust ll_boot_init() to use it. Signed-off-by: Simon Glass Reviewed-by: Peng Fan Reviewed-by: Bin Meng --- Changes in v4: - Rename flag to GD_FLG_SKIP_LL_INIT Changes in v3: - Add a new patch with a gd flag for chain loading Changes in v2: None include/asm-generic/global_data.h | 1 + include/init.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index d9e220cfe3..8c78792cc9 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -166,5 +166,6 @@ typedef struct global_data { #define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */ #define GD_FLG_LOG_READY 0x08000 /* Log system is ready for use */ #define GD_FLG_WDT_READY 0x10000 /* Watchdog is ready for use */ +#define GD_FLG_SKIP_LL_INIT 0x20000 /* Don't perform low-level init */ #endif /* __ASM_GENERIC_GBL_DATA_H */ diff --git a/include/init.h b/include/init.h index 2a33a3fd1e..f84a1fc0e0 100644 --- a/include/init.h +++ b/include/init.h @@ -20,7 +20,7 @@ struct global_data; #ifdef CONFIG_EFI_STUB #define ll_boot_init() false #else -#define ll_boot_init() true +#define ll_boot_init() (!(gd->flags & GD_FLG_SKIP_LL_INIT)) #endif /* From patchwork Sun Apr 26 15:12:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238494 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:58 -0600 Subject: [PATCH v4 6/9] x86: Move coreboot-table detection into common code In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-6-sjg@chromium.org> To support detecting booting from coreboot, move the code which locates the coreboot tables into a common place. Adjust the algorithm slightly to use a word comparison instead of string, since it is faster. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: - Add new patch to move coreboot-table detection into common code Changes in v3: None Changes in v2: None arch/x86/cpu/coreboot/tables.c | 24 +++++++++--------------- arch/x86/cpu/i386/cpu.c | 25 +++++++++++++++++++++++++ arch/x86/include/asm/coreboot_tables.h | 7 +++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c index 37e0424b5e..0f04c4f8e9 100644 --- a/arch/x86/cpu/coreboot/tables.c +++ b/arch/x86/cpu/coreboot/tables.c @@ -115,20 +115,11 @@ __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; - unsigned char *ptr = (unsigned char *)addr; int i; - for (i = 0; i < len; i += 16, ptr += 16) { - header = (struct cb_header *)ptr; - if (!strncmp((const char *)header->signature, "LBIO", 4)) - break; - } - - /* We walked the entire space and didn't find anything. */ - if (i >= len) - return -1; - + header = (struct cb_header *)ptr; if (!header->table_bytes) return 0; @@ -231,10 +222,13 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) int get_coreboot_info(struct sysinfo_t *info) { - int ret = cb_parse_header((void *)0x00000000, 0x1000, info); + long addr; + int ret; - if (ret != 1) - ret = cb_parse_header((void *)0x000f0000, 0x1000, info); + addr = locate_coreboot_table(); + if (addr < 0) + return addr; + ret = cb_parse_header((void *)addr, 0x1000, info); - return (ret == 1) ? 0 : -1; + return ret == 1 ? 0 : -ENOENT; } diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index c8da7f10e9..e52fd686d9 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -447,6 +447,31 @@ int x86_cpu_init_f(void) return 0; } +long detect_coreboot_table_at(ulong start, ulong size) +{ + u32 *ptr, *end; + + size /= 4; + for (ptr = (void *)start, end = ptr + size; ptr < end; ptr += 4) { + if (*ptr == 0x4f49424c) /* "LBIO" */ + return (long)ptr; + } + + return -ENOENT; +} + +long locate_coreboot_table(void) +{ + long addr; + + /* We look for LBIO in the first 4K of RAM and again at 60KB */ + addr = detect_coreboot_table_at(0x0, 0x1000); + if (addr < 0) + addr = detect_coreboot_table_at(0xf0000, 0x1000); + + return addr; +} + int x86_cpu_reinit_f(void) { setup_identity(); diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h index 61de0077d7..268284f43c 100644 --- a/arch/x86/include/asm/coreboot_tables.h +++ b/arch/x86/include/asm/coreboot_tables.h @@ -343,4 +343,11 @@ void *high_table_malloc(size_t bytes); */ void write_coreboot_table(u32 addr, struct memory_area *cfg_tables); +/** + * locate_coreboot_table() - Try to find coreboot tables at standard locations + * + * @return address of table that was found, or -ve error number + */ +long locate_coreboot_table(void); + #endif From patchwork Sun Apr 26 15:12:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238496 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:12:59 -0600 Subject: [PATCH v4 7/9] x86: Add a way to detect running from coreboot In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-7-sjg@chromium.org> If U-Boot is running from coreboot we need to skip low-level init. Add an way to detect this and to set the gd flag. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: - Rename flag to GD_FLG_SKIP_LL_INIT - Split this patch into two Changes in v3: - Add new patch to detect running from coreboot Changes in v2: None arch/x86/cpu/i386/cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index e52fd686d9..8a458bb5ff 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -476,6 +476,8 @@ int x86_cpu_reinit_f(void) { setup_identity(); setup_pci_ram_top(); + if (locate_coreboot_table() >= 0) + gd->flags |= GD_FLG_SKIP_LL_INIT; return 0; } From patchwork Sun Apr 26 15:13:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238497 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:13:00 -0600 Subject: [PATCH v4 8/9] x86: Use the existing stack when chain-loading In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-8-sjg@chromium.org> With chromebook_coral we normally run TPL->SPL->U-Boot. This is the 'bare metal' case. When running from coreboot we put u-boot.bin in the RW_LEGACY portion of the image, e.g. with: cbfstool image-coral.serial.bin add-flat-binary -r RW_LEGACY \ -f /tmp/b/chromebook_coral/u-boot.bin -n altfw/u-boot \ -c lzma -l 0x1110000 -e 0x1110000 In this case U-Boot is run from coreboot (actually Depthcharge, its payload) so we cannot access CAR. Use the existing stack instead. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: - Update to use locate_coreboot_table() Changes in v3: None Changes in v2: None arch/x86/cpu/start_from_spl.S | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S index 22cab2dd6c..905c825cdc 100644 --- a/arch/x86/cpu/start_from_spl.S +++ b/arch/x86/cpu/start_from_spl.S @@ -14,18 +14,30 @@ .globl _start .type _start, @function _start: - /* Set up memory using the existing stack */ + /* + * If running from coreboot, CAR is no-longer available. Use the + * existing stack, which is large enough. + */ + call locate_coreboot_table + cmp $0, %eax + jge use_existing_stack + movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE - 4), %eax #ifdef CONFIG_DCACHE_RAM_MRC_VAR_SIZE subl $CONFIG_DCACHE_RAM_MRC_VAR_SIZE, %eax #endif + jmp 2f /* - * We don't subject CONFIG_DCACHE_RAM_MRC_VAR_SIZE since memory is + * We don't subtract CONFIG_DCACHE_RAM_MRC_VAR_SIZE since memory is * already set up. This has the happy side-effect of putting gd in a * new place separate from SPL, so the memset() in * board_init_f_init_reserve() does not cause any problems (otherwise * it would zero out the gd and crash) */ + /* Set up memory using the existing stack */ +use_existing_stack: + mov %esp, %eax +2: call board_init_f_alloc_reserve mov %eax, %esp From patchwork Sun Apr 26 15:13:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 238495 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Apr 2020 09:13:01 -0600 Subject: [PATCH v4 9/9] x86: Add documentation for the chain-load feature In-Reply-To: <20200426151302.93418-1-sjg@chromium.org> References: <20200426151302.93418-1-sjg@chromium.org> Message-ID: <20200426151302.93418-9-sjg@chromium.org> Add a few notes about this feature, which is aimed for development. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v4: None Changes in v3: None Changes in v2: None doc/arch/x86.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/arch/x86.rst b/doc/arch/x86.rst index a441738ad1..c6b70ce61a 100644 --- a/doc/arch/x86.rst +++ b/doc/arch/x86.rst @@ -712,6 +712,34 @@ to load a 'u-boot-payload.efi', see below test logs on QEMU. See :doc:`../uefi/u-boot_on_efi` and :doc:`../uefi/uefi` for details of EFI support in U-Boot. +Chain-loading +------------- +U-Boot can be chain-loaded from another bootloader, such as coreboot or +Slim Bootloader. Typically this is done by building for targets 'coreboot' or +'slimbootloader'. + +For example, at present we have a 'coreboot' target but this runs very +different code from the bare-metal targets, such as coral. There is very little +in common between them. + +It is useful to be able to boot the same U-Boot on a device, with or without a +first-stage bootloader. For example, with chromebook_coral, it is helpful for +testing to be able to boot the same U-Boot (complete with FSP) on bare metal +and from coreboot. It allows checking of things like CPU speed, comparing +registers, ACPI tables and the like. + +To do this you can use ll_boot_init() in appropriate places to skip init that +has already been done by the previous stage. This works by setting a +GD_FLG_NO_LL_INIT flag when U-Boot detects that it is running from another +bootloader. + +With this feature, you can build a bare-metal target and boot it from +coreboot, for example. + +Note that this is a development feature only. It is not intended for use in +production environments. Also it is not currently part of the automated tests +so may break in the future. + TODO List --------- - Audio