mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-18 06:58:54 +00:00
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:
commit
4906238191
126 changed files with 3132 additions and 811 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -44,6 +44,13 @@ SECTIONS
|
|||
{
|
||||
*(.__efi_runtime_rel_stop)
|
||||
}
|
||||
|
||||
.dynsym :
|
||||
{
|
||||
__dyn_sym_start = .;
|
||||
*(.dynsym)
|
||||
__dyn_sym_end = .;
|
||||
}
|
||||
}
|
||||
|
||||
INSERT BEFORE .data;
|
||||
|
|
|
@ -200,6 +200,10 @@
|
|||
compatible = "sandbox,reset";
|
||||
};
|
||||
|
||||
rng {
|
||||
compatible = "sandbox,sandbox-rng";
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "sandbox,sound";
|
||||
cpu {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,5 +20,4 @@ else
|
|||
obj-y += sdram.o
|
||||
endif
|
||||
obj-y += coreboot.o
|
||||
obj-y += tables.o
|
||||
obj-y += timestamp.o
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef _ASM_ARCH_UART_H
|
||||
#define _ASM_ARCH_UART_H
|
||||
|
||||
#include <dt-structs.h>
|
||||
#include <ns16550.h>
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
220
arch/x86/include/asm/cb_sysinfo.h
Normal file
220
arch/x86/include/asm/cb_sysinfo.h
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
7
arch/x86/lib/coreboot/Makefile
Normal file
7
arch/x86/lib/coreboot/Makefile
Normal 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
|
41
arch/x86/lib/coreboot/cb_support.c
Normal file
41
arch/x86/lib/coreboot/cb_support.c
Normal 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;
|
||||
}
|
468
arch/x86/lib/coreboot/cb_sysinfo.c
Normal file
468
arch/x86/lib/coreboot/cb_sysinfo.c
Normal 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;
|
||||
}
|
|
@ -87,7 +87,7 @@ static int fsp_video_probe(struct udevice *dev)
|
|||
int ret;
|
||||
|
||||
if (!ll_boot_init())
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
|
||||
printf("Video: ");
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
35
cmd/host.c
35
cmd/host.c
|
@ -41,17 +41,35 @@ static int do_host_save(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
if (argc < 2 || argc > 3)
|
||||
return CMD_RET_USAGE;
|
||||
bool removable = false;
|
||||
const char *dev_str;
|
||||
char *file;
|
||||
char *ep;
|
||||
char *dev_str = argv[1];
|
||||
char *file = argc >= 3 ? argv[2] : NULL;
|
||||
int dev = simple_strtoul(dev_str, &ep, 16);
|
||||
int dev;
|
||||
|
||||
/* Skip 'bind' */
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (!strcmp(argv[0], "-r")) {
|
||||
removable = true;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc > 2)
|
||||
return CMD_RET_USAGE;
|
||||
dev_str = argv[0];
|
||||
dev = simple_strtoul(dev_str, &ep, 16);
|
||||
if (*ep) {
|
||||
printf("** Bad device specification %s **\n", dev_str);
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
return !!host_dev_bind(dev, file);
|
||||
file = argc > 1 ? argv[1] : NULL;
|
||||
|
||||
return !!host_dev_bind(dev, file, removable);
|
||||
}
|
||||
|
||||
static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
@ -146,7 +164,7 @@ static struct cmd_tbl cmd_host_sub[] = {
|
|||
U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
|
||||
U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
|
||||
U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
|
||||
U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""),
|
||||
U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
|
||||
U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
|
||||
U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
|
||||
};
|
||||
|
@ -178,7 +196,8 @@ U_BOOT_CMD(
|
|||
"host save hostfs - <addr> <filename> <bytes> [<offset>] - "
|
||||
"save a file to host\n"
|
||||
"host size hostfs - <filename> - determine size of file on host\n"
|
||||
"host bind <dev> [<filename>] - bind \"host\" device to file\n"
|
||||
"host bind [-r] <dev> [<filename>] - bind \"host\" device to file\n"
|
||||
" -r = mark as removable\n"
|
||||
"host info [<dev>] - show device binding & info\n"
|
||||
"host dev [<dev>] - Set or retrieve the current host device\n"
|
||||
"host commands use the \"hostfs\" device. The \"host\" device is used\n"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
394
cmd/x86/cbsysinfo.c
Normal 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"
|
||||
);
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
14
doc/chromium/index.rst
Normal 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
74
doc/chromium/overview.rst
Normal 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>`_
|
|
@ -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
|
37
doc/device-tree-bindings/sysinfo/google,coral.txt
Normal file
37
doc/device-tree-bindings/sysinfo/google,coral.txt
Normal 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>;
|
||||
*/
|
||||
};
|
|
@ -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
|
||||
==================
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Shell commands
|
|||
booti
|
||||
bootmenu
|
||||
button
|
||||
x86/cbsysinfo
|
||||
conitrace
|
||||
echo
|
||||
exception
|
||||
|
|
25
doc/usage/x86/cbsysinfo.rst
Normal file
25
doc/usage/x86/cbsysinfo.rst
Normal 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
|
|
@ -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/
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_MISC
|
||||
#define LOG_DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#include <axi.h>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
122
fs/cbfs/cbfs.c
122
fs/cbfs/cbfs.c
|
@ -79,6 +79,57 @@ static void swap_file_header(struct cbfs_fileheader *dest,
|
|||
dest->offset = be32_to_cpu(src->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* fill_node() - Fill a node struct with information from the CBFS
|
||||
*
|
||||
* @node: Node to fill
|
||||
* @start: Pointer to the start of the CBFS file in memory
|
||||
* @header: Pointer to the header information (in our enddianess)
|
||||
* @return 0 if OK, -EBADF if the header is too small
|
||||
*/
|
||||
static int fill_node(struct cbfs_cachenode *node, void *start,
|
||||
struct cbfs_fileheader *header)
|
||||
{
|
||||
uint name_len;
|
||||
uint offset;
|
||||
|
||||
/* Check the header is large enough */
|
||||
if (header->offset < sizeof(struct cbfs_fileheader))
|
||||
return -EBADF;
|
||||
|
||||
node->next = NULL;
|
||||
node->type = header->type;
|
||||
node->data = start + header->offset;
|
||||
node->data_length = header->len;
|
||||
name_len = header->offset - sizeof(struct cbfs_fileheader);
|
||||
node->name = start + sizeof(struct cbfs_fileheader);
|
||||
node->name_length = name_len;
|
||||
node->attr_offset = header->attributes_offset;
|
||||
node->comp_algo = CBFS_COMPRESS_NONE;
|
||||
node->decomp_size = 0;
|
||||
|
||||
for (offset = node->attr_offset; offset < header->offset;) {
|
||||
const struct cbfs_file_attribute *attr;
|
||||
uint tag, len;
|
||||
|
||||
attr = start + offset;
|
||||
tag = be32_to_cpu(attr->tag);
|
||||
len = be32_to_cpu(attr->len);
|
||||
if (tag == CBFS_FILE_ATTR_TAG_COMPRESSION) {
|
||||
struct cbfs_file_attr_compression *comp;
|
||||
|
||||
comp = start + offset;
|
||||
node->comp_algo = be32_to_cpu(comp->compression);
|
||||
node->decomp_size =
|
||||
be32_to_cpu(comp->decompressed_size);
|
||||
}
|
||||
|
||||
offset += len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a starting position in memory, scan forward, bounded by a size, and
|
||||
* find the next valid CBFS file. No memory is allocated by this function. The
|
||||
|
@ -87,7 +138,7 @@ static void swap_file_header(struct cbfs_fileheader *dest,
|
|||
* @param start The location in memory to start from.
|
||||
* @param size The size of the memory region to search.
|
||||
* @param align The alignment boundaries to check on.
|
||||
* @param new_node A pointer to the file structure to load.
|
||||
* @param node A pointer to the file structure to load.
|
||||
* @param used A pointer to the count of of bytes scanned through,
|
||||
* including the file if one is found.
|
||||
*
|
||||
|
@ -95,7 +146,7 @@ static void swap_file_header(struct cbfs_fileheader *dest,
|
|||
* is found.
|
||||
*/
|
||||
static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
|
||||
int align, struct cbfs_cachenode *new_node,
|
||||
int align, struct cbfs_cachenode *node,
|
||||
int *used)
|
||||
{
|
||||
struct cbfs_fileheader header;
|
||||
|
@ -104,8 +155,7 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
|
|||
|
||||
while (size >= align) {
|
||||
const struct cbfs_fileheader *file_header = start;
|
||||
u32 name_len;
|
||||
u32 step;
|
||||
int ret;
|
||||
|
||||
/* Check if there's a file here. */
|
||||
if (memcmp(good_file_magic, &file_header->magic,
|
||||
|
@ -117,25 +167,13 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
|
|||
}
|
||||
|
||||
swap_file_header(&header, file_header);
|
||||
if (header.offset < sizeof(struct cbfs_fileheader)) {
|
||||
ret = fill_node(node, start, &header);
|
||||
if (ret) {
|
||||
priv->result = CBFS_BAD_FILE;
|
||||
return -EBADF;
|
||||
return log_msg_ret("fill", ret);
|
||||
}
|
||||
new_node->next = NULL;
|
||||
new_node->type = header.type;
|
||||
new_node->data = start + header.offset;
|
||||
new_node->data_length = header.len;
|
||||
name_len = header.offset - sizeof(struct cbfs_fileheader);
|
||||
new_node->name = (char *)file_header +
|
||||
sizeof(struct cbfs_fileheader);
|
||||
new_node->name_length = name_len;
|
||||
new_node->attributes_offset = header.attributes_offset;
|
||||
|
||||
step = header.len;
|
||||
if (step % align)
|
||||
step = step + align - step % align;
|
||||
|
||||
*used += step;
|
||||
*used += ALIGN(header.len, align);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -146,7 +184,7 @@ static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
|
|||
static int file_cbfs_fill_cache(struct cbfs_priv *priv, int size, int align)
|
||||
{
|
||||
struct cbfs_cachenode *cache_node;
|
||||
struct cbfs_cachenode *new_node;
|
||||
struct cbfs_cachenode *node;
|
||||
struct cbfs_cachenode **cache_tail = &priv->file_cache;
|
||||
void *start;
|
||||
|
||||
|
@ -164,21 +202,20 @@ static int file_cbfs_fill_cache(struct cbfs_priv *priv, int size, int align)
|
|||
int used;
|
||||
int ret;
|
||||
|
||||
new_node = (struct cbfs_cachenode *)
|
||||
malloc(sizeof(struct cbfs_cachenode));
|
||||
if (!new_node)
|
||||
node = malloc(sizeof(struct cbfs_cachenode));
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
ret = file_cbfs_next_file(priv, start, size, align, new_node,
|
||||
ret = file_cbfs_next_file(priv, start, size, align, node,
|
||||
&used);
|
||||
|
||||
if (ret < 0) {
|
||||
free(new_node);
|
||||
free(node);
|
||||
if (ret == -ENOENT)
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
*cache_tail = new_node;
|
||||
cache_tail = &new_node->next;
|
||||
*cache_tail = node;
|
||||
cache_tail = &node->next;
|
||||
|
||||
size -= used;
|
||||
start += used;
|
||||
|
@ -276,18 +313,26 @@ int file_cbfs_init(ulong end_of_rom)
|
|||
return cbfs_init(&cbfs_s, end_of_rom);
|
||||
}
|
||||
|
||||
int cbfs_init_mem(ulong base, struct cbfs_priv **privp)
|
||||
int cbfs_init_mem(ulong base, ulong size, bool require_hdr,
|
||||
struct cbfs_priv **privp)
|
||||
{
|
||||
struct cbfs_priv priv_s, *priv = &priv_s;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Use a local variable to start with until we know that the CBFS is
|
||||
* valid.
|
||||
* Use a local variable to start with until we know that the * CBFS is
|
||||
* valid. Note that size is detected from the header, if present,
|
||||
* meaning the parameter is ignored.
|
||||
*/
|
||||
ret = cbfs_load_header_ptr(priv, base);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
if (require_hdr || size == CBFS_SIZE_UNKNOWN)
|
||||
return ret;
|
||||
memset(priv, '\0', sizeof(struct cbfs_priv));
|
||||
priv->header.rom_size = size;
|
||||
priv->header.align = CBFS_ALIGN_SIZE;
|
||||
priv->start = (void *)base;
|
||||
}
|
||||
|
||||
ret = file_cbfs_fill_cache(priv, priv->header.rom_size,
|
||||
priv->header.align);
|
||||
|
@ -317,6 +362,17 @@ const struct cbfs_header *file_cbfs_get_header(void)
|
|||
}
|
||||
}
|
||||
|
||||
const struct cbfs_cachenode *cbfs_get_first(const struct cbfs_priv *priv)
|
||||
{
|
||||
return priv->file_cache;
|
||||
}
|
||||
|
||||
void cbfs_get_next(const struct cbfs_cachenode **filep)
|
||||
{
|
||||
if (*filep)
|
||||
*filep = (*filep)->next;
|
||||
}
|
||||
|
||||
const struct cbfs_cachenode *file_cbfs_get_first(void)
|
||||
{
|
||||
struct cbfs_priv *priv = &cbfs_s;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue