binman support for expanding entries, connections

misc fixes and improvements to sandbox, etc.
 x86 CBFS improvements
 x86 coreboot improvements
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmBfg1YRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIreZQnQf/UtTgrFdmvY86v4Y3sCvbdAlDHso15voU
 zEwhjKoPbnchHDA0UMFn/SmP0zRZNQbIhIsASoC4OBVl8nmtAQ7nDP8SmwtV95Zo
 wqPVUlCjkHID3XOFIDbqx3L6fCL1mDe33hhfdYDzeLmhcDyxofY9yTjMasxk4tcu
 oMRMiFYpL6IkM7Jtey/kRzOuEykh1J/iXJ0rAHnzgHR8vzLJEo5DjLsbd971896I
 87LUmZ//3b499KgTCj7MYTEFoDA36MCPQKWqIhbFv4zh3STLGCT5fri6jHWqjHYG
 UU35bdgLvsE3Dv/VFg/C+YoIzbxGRYK5WCIJX4akoE/GPCgba0C9YQ==
 =5gak
 -----END PGP SIGNATURE-----

Merge tag 'dm-pull-28mar21' of git://git.denx.de/u-boot-dm into next

binman support for expanding entries, connections
misc fixes and improvements to sandbox, etc.
x86 CBFS improvements
x86 coreboot improvements
This commit is contained in:
Tom Rini 2021-03-28 20:29:39 -04:00
commit 4906238191
126 changed files with 3132 additions and 811 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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)

View file

@ -44,6 +44,13 @@ SECTIONS
{
*(.__efi_runtime_rel_stop)
}
.dynsym :
{
__dyn_sym_start = .;
*(.dynsym)
__dyn_sym_end = .;
}
}
INSERT BEFORE .data;

View file

@ -200,6 +200,10 @@
compatible = "sandbox,reset";
};
rng {
compatible = "sandbox,sandbox-rng";
};
sound {
compatible = "sandbox,sound";
cpu {

View file

@ -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

View file

@ -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,

View file

@ -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();
}

View file

@ -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;

View file

@ -20,5 +20,4 @@ else
obj-y += sdram.o
endif
obj-y += coreboot.o
obj-y += tables.o
obj-y += timestamp.o

View file

@ -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;

View file

@ -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);
}
/*

View file

@ -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;
}

View file

@ -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)

View file

@ -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

View file

@ -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";
};

View file

@ -6,6 +6,7 @@
#ifndef _ASM_ARCH_UART_H
#define _ASM_ARCH_UART_H
#include <dt-structs.h>
#include <ns16550.h>
/**

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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_CBMEM_ENTRY 0x0031
#define CBMEM_ID_SMBIOS 0x534d4254
#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
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;

View file

@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright 2021 Google LLC
#
obj-y += cb_sysinfo.o
obj-y += cb_support.o

View file

@ -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;
}

View file

@ -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;
}

View file

@ -87,7 +87,7 @@ static int fsp_video_probe(struct udevice *dev)
int ret;
if (!ll_boot_init())
return 0;
return -ENODEV;
printf("Video: ");

View file

@ -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) {

View file

@ -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;

View file

@ -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();
}

View file

@ -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__);

View file

@ -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;

View file

@ -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>

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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),

View file

@ -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),

View file

@ -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"

View file

@ -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;

View file

@ -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

394
cmd/x86/cbsysinfo.c Normal file
View file

@ -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"
);

View file

@ -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;
model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
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);
}
if (model)
printf("Model: %s\n", model);
#endif
/* 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);
}
return checkboard();
}

View file

@ -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);

View file

@ -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 */

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

14
doc/chromium/index.rst Normal file
View file

@ -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

74
doc/chromium/overview.rst Normal file
View file

@ -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>`_

View file

@ -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

View file

@ -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>;
*/
};

View file

@ -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
==================

View file

@ -21,6 +21,7 @@ Shell commands
booti
bootmenu
button
x86/cbsysinfo
conitrace
echo
exception

View file

@ -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

View file

@ -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/

View file

@ -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");

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -7,7 +7,6 @@
*/
#define LOG_CATEGORY UCLASS_MISC
#define LOG_DEBUG
#include <common.h>
#include <axi.h>

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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[] = {

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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)
{

View file

@ -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>

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
};
/**
@ -110,6 +162,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.
*
@ -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. */

View file

@ -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 */

View file

@ -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"

View file

@ -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;
};
/**

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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_ */

View file

@ -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 */
@ -76,6 +89,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
*
@ -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)

View file

@ -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,
};

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more