- Various fixes for Google chromebooks
- Various minor enhancements for coreboot
This commit is contained in:
Tom Rini 2023-05-11 08:40:33 -04:00
commit e94fbdd272
58 changed files with 380 additions and 147 deletions

View file

@ -195,6 +195,7 @@ config SANDBOX
imply PHYLIB imply PHYLIB
imply DM_MDIO imply DM_MDIO
imply DM_MDIO_MUX imply DM_MDIO_MUX
imply ACPI
imply ACPI_PMC imply ACPI_PMC
imply ACPI_PMC_SANDBOX imply ACPI_PMC_SANDBOX
imply CMD_PMC imply CMD_PMC
@ -261,6 +262,7 @@ config X86
imply PCH imply PCH
imply PHYSMEM imply PHYSMEM
imply RTC_MC146818 imply RTC_MC146818
imply ACPI
imply ACPIGEN if !QEMU && !EFI_APP imply ACPIGEN if !QEMU && !EFI_APP
imply SYSINFO if GENERATE_SMBIOS_TABLE imply SYSINFO if GENERATE_SMBIOS_TABLE
imply SYSINFO_SMBIOS if GENERATE_SMBIOS_TABLE imply SYSINFO_SMBIOS if GENERATE_SMBIOS_TABLE

View file

@ -89,7 +89,7 @@ static int imx8_init_mu(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, imx8_init_mu); EVENT_SPY(EVT_DM_POST_INIT_F, imx8_init_mu);
#if defined(CONFIG_ARCH_MISC_INIT) #if defined(CONFIG_ARCH_MISC_INIT)
int arch_misc_init(void) int arch_misc_init(void)

View file

@ -549,7 +549,7 @@ static int imx8m_check_clock(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock); EVENT_SPY(EVT_DM_POST_INIT_F, imx8m_check_clock);
static void imx8m_setup_snvs(void) static void imx8m_setup_snvs(void)
{ {

View file

@ -808,7 +808,7 @@ static int imx8ulp_evt_dm_post_init(void *ctx, struct event *event)
{ {
return imx8ulp_dm_post_init(); return imx8ulp_dm_post_init();
} }
EVENT_SPY(EVT_DM_POST_INIT, imx8ulp_evt_dm_post_init); EVENT_SPY(EVT_DM_POST_INIT_F, imx8ulp_evt_dm_post_init);
#if defined(CONFIG_SPL_BUILD) #if defined(CONFIG_SPL_BUILD)
__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)

View file

@ -262,7 +262,7 @@ int imx9_probe_mu(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, imx9_probe_mu); EVENT_SPY(EVT_DM_POST_INIT_F, imx9_probe_mu);
int timer_init(void) int timer_init(void)
{ {

View file

@ -535,4 +535,4 @@ static int am33xx_dm_post_init(void *ctx, struct event *event)
#endif #endif
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, am33xx_dm_post_init); EVENT_SPY(EVT_DM_POST_INIT_F, am33xx_dm_post_init);

View file

@ -246,7 +246,7 @@ static int omap2_system_init(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, omap2_system_init); EVENT_SPY(EVT_DM_POST_INIT_F, omap2_system_init);
/* /*
* Routine: wait_for_command_complete * Routine: wait_for_command_complete

View file

@ -102,7 +102,7 @@ static int pic32_flash_prefetch(void *ctx, struct event *event)
prefetch_init(); prefetch_init();
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, pic32_flash_prefetch); EVENT_SPY(EVT_DM_POST_INIT_F, pic32_flash_prefetch);
/* Un-gate DDR2 modules (gated by default) */ /* Un-gate DDR2 modules (gated by default) */
static void ddr2_pmd_ungate(void) static void ddr2_pmd_ungate(void)

View file

@ -80,7 +80,7 @@ static int nios_cpu_setup(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, nios_cpu_setup); EVENT_SPY(EVT_DM_POST_INIT_F, nios_cpu_setup);
static int altera_nios2_get_desc(const struct udevice *dev, char *buf, static int altera_nios2_get_desc(const struct udevice *dev, char *buf,
int size) int size)

View file

@ -145,7 +145,7 @@ int riscv_cpu_setup(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, riscv_cpu_setup); EVENT_SPY(EVT_DM_POST_INIT_F, riscv_cpu_setup);
int arch_early_init_r(void) int arch_early_init_r(void)
{ {

View file

@ -64,7 +64,7 @@ static int baytrail_uart_init(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, baytrail_uart_init); EVENT_SPY(EVT_DM_POST_INIT_F, baytrail_uart_init);
static void set_max_freq(void) static void set_max_freq(void)
{ {

View file

@ -2,7 +2,6 @@
# #
# Copyright (c) 2016 Google, Inc # Copyright (c) 2016 Google, Inc
obj-y += adsp.o
obj-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += cpu.o obj-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += cpu.o
obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += cpu_full.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += cpu_full.o
@ -14,6 +13,8 @@ obj-y += refcode.o
endif endif
ifndef CONFIG_SPL_BUILD ifndef CONFIG_SPL_BUILD
# obj-y += cpu_from_spl.o # obj-y += cpu_from_spl.o
obj-y += adsp.o
obj-y += sata.o
endif endif
endif endif
@ -29,5 +30,4 @@ obj-y += pch.o
obj-y += pinctrl_broadwell.o obj-y += pinctrl_broadwell.o
obj-y += power_state.o obj-y += power_state.o
obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += refcode.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += refcode.o
obj-y += sata.o
obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += sdram.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += sdram.o

View file

@ -40,7 +40,7 @@ static int broadwell_init_cpu(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, broadwell_init_cpu); EVENT_SPY(EVT_DM_POST_INIT_F, broadwell_init_cpu);
void set_max_freq(void) void set_max_freq(void)
{ {

View file

@ -351,8 +351,8 @@ long locate_coreboot_table(void)
{ {
long addr; long addr;
/* We look for LBIO in the first 4K of RAM and again at 960KB */ /* We look for LBIO from addresses 1K-4K and again at 960KB */
addr = detect_coreboot_table_at(0x0, 0x1000); addr = detect_coreboot_table_at(0x400, 0xc00);
if (addr < 0) if (addr < 0)
addr = detect_coreboot_table_at(0xf0000, 0x1000); addr = detect_coreboot_table_at(0xf0000, 0x1000);

View file

@ -572,6 +572,7 @@ int cpu_has_64bit(void)
has_long_mode(); has_long_mode();
} }
/* Base address for page tables used for 64-bit mode */
#define PAGETABLE_BASE 0x80000 #define PAGETABLE_BASE 0x80000
#define PAGETABLE_SIZE (6 * 4096) #define PAGETABLE_SIZE (6 * 4096)
@ -614,43 +615,20 @@ int cpu_jump_to_64bit(ulong setup_base, ulong target)
} }
/* /*
* Jump from SPL to U-Boot * cpu_jump_to_64bit_uboot() - Jump from SPL to U-Boot
* *
* This function is work-in-progress with many issues to resolve. * It works by setting up page tables and calling the code to enter 64-bit long
* * mode
* It works by setting up several regions:
* ptr - a place to put the code that jumps into 64-bit mode
* gdt - a place to put the global descriptor table
* pgtable - a place to put the page tables
*
* The cpu_call64() code is copied from ROM and then manually patched so that
* it has the correct GDT address in RAM. U-Boot is copied from ROM into
* its pre-relocation address. Then we jump to the cpu_call64() code in RAM,
* which changes to 64-bit mode and starts U-Boot.
*/ */
int cpu_jump_to_64bit_uboot(ulong target) int cpu_jump_to_64bit_uboot(ulong target)
{ {
typedef void (*func_t)(ulong pgtable, ulong setup_base, ulong target);
uint32_t *pgtable; uint32_t *pgtable;
func_t func;
char *ptr;
pgtable = (uint32_t *)PAGETABLE_BASE; pgtable = (uint32_t *)PAGETABLE_BASE;
build_pagetable(pgtable); build_pagetable(pgtable);
extern long call64_stub_size;
ptr = malloc(call64_stub_size);
if (!ptr) {
printf("Failed to allocate the cpu_call64 stub\n");
return -ENOMEM;
}
memcpy(ptr, cpu_call64, call64_stub_size);
func = (func_t)ptr;
/* Jump to U-Boot */ /* Jump to U-Boot */
func((ulong)pgtable, 0, (ulong)target); cpu_call64(PAGETABLE_BASE, 0, (ulong)target);
return -EFAULT; return -EFAULT;
} }

View file

@ -31,7 +31,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define RCBA_AUDIO_CONFIG_HDA BIT(31) #define RCBA_AUDIO_CONFIG_HDA BIT(31)
#define RCBA_AUDIO_CONFIG_MASK 0xfe #define RCBA_AUDIO_CONFIG_MASK 0xfe
#ifndef CONFIG_HAVE_FSP
static int pch_revision_id = -1; static int pch_revision_id = -1;
static int pch_type = -1; static int pch_type = -1;
@ -162,15 +161,19 @@ void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue,
static int bd82x6x_probe(struct udevice *dev) static int bd82x6x_probe(struct udevice *dev)
{ {
if (!(gd->flags & GD_FLG_RELOC)) /* make sure the LPC is inited since it provides the gpio base */
return 0; uclass_first_device(UCLASS_LPC, &dev);
/* Cause the SATA device to do its init */ if (!IS_ENABLED(CONFIG_HAVE_FSP)) {
uclass_first_device(UCLASS_AHCI, &dev); if (!(gd->flags & GD_FLG_RELOC))
return 0;
/* Cause the SATA device to do its init */
uclass_first_device(UCLASS_AHCI, &dev);
}
return 0; return 0;
} }
#endif /* CONFIG_HAVE_FSP */
static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep) static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep)
{ {
@ -269,8 +272,6 @@ U_BOOT_DRIVER(bd82x6x_drv) = {
.name = "bd82x6x", .name = "bd82x6x",
.id = UCLASS_PCH, .id = UCLASS_PCH,
.of_match = bd82x6x_ids, .of_match = bd82x6x_ids,
#ifndef CONFIG_HAVE_FSP
.probe = bd82x6x_probe, .probe = bd82x6x_probe,
#endif
.ops = &bd82x6x_pch_ops, .ops = &bd82x6x_pch_ops,
}; };

View file

@ -86,7 +86,7 @@ static int ivybridge_cpu_init(void *ctx, struct event *ev)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, ivybridge_cpu_init); EVENT_SPY(EVT_DM_POST_INIT_F, ivybridge_cpu_init);
#define PCH_EHCI0_TEMP_BAR0 0xe8000000 #define PCH_EHCI0_TEMP_BAR0 0xe8000000
#define PCH_EHCI1_TEMP_BAR0 0xe8000400 #define PCH_EHCI1_TEMP_BAR0 0xe8000400

View file

@ -263,7 +263,7 @@ static int quark_init_pcie(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, quark_init_pcie); EVENT_SPY(EVT_DM_POST_INIT_F, quark_init_pcie);
int checkcpu(void) int checkcpu(void)
{ {

View file

@ -50,3 +50,10 @@ int x86_cpu_init_f(void)
{ {
return 0; return 0;
} }
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
void board_debug_uart_init(void)
{
/* this was already done in SPL */
}
#endif

View file

@ -16,6 +16,8 @@
#define SYSINFO_MAX_GPIOS 8 #define SYSINFO_MAX_GPIOS 8
/* Up to 10 MAC addresses */ /* Up to 10 MAC addresses */
#define SYSINFO_MAX_MACS 10 #define SYSINFO_MAX_MACS 10
/* Track the first 32 unimplemented tags */
#define SYSINFO_MAX_UNIMPL 32
/** /**
* struct sysinfo_t - Information passed to U-Boot from coreboot * struct sysinfo_t - Information passed to U-Boot from coreboot
@ -133,6 +135,9 @@
* @mtc_size: Size of MTC region * @mtc_size: Size of MTC region
* @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning * @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning
* not used * not used
* @rsdp: Pointer to ACPI RSDP table
* @unimpl_count: Number of entries in unimpl_map[]
* @unimpl: List of unimplemented IDs (bottom 8 bits only)
*/ */
struct sysinfo_t { struct sysinfo_t {
unsigned int cpu_khz; unsigned int cpu_khz;
@ -211,6 +216,9 @@ struct sysinfo_t {
u64 mtc_start; u64 mtc_start;
u32 mtc_size; u32 mtc_size;
void *chromeos_vpd; void *chromeos_vpd;
void *rsdp;
u32 unimpl_count;
u8 unimpl[SYSINFO_MAX_UNIMPL];
}; };
extern struct sysinfo_t lib_sysinfo; extern struct sysinfo_t lib_sysinfo;

View file

@ -422,6 +422,8 @@ struct cb_tsc_info {
#define CB_TAG_SERIALNO 0x002a #define CB_TAG_SERIALNO 0x002a
#define CB_MAX_SERIALNO_LENGTH 32 #define CB_MAX_SERIALNO_LENGTH 32
#define CB_TAG_ACPI_RSDP 0x0043
#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 #define CB_TAG_CMOS_OPTION_TABLE 0x00c8
struct cb_cmos_option_table { struct cb_cmos_option_table {

View file

@ -14,7 +14,11 @@ extern char *strrchr(const char *s, int c);
#undef __HAVE_ARCH_STRCHR #undef __HAVE_ARCH_STRCHR
extern char *strchr(const char *s, int c); extern char *strchr(const char *s, int c);
#ifdef CONFIG_X86_64 /*
* Our assembly routines do not work on in 64-bit mode and we don't do a lot of
* copying in SPL, so code size is more important there.
*/
#if defined(CONFIG_SPL_BUILD) || !IS_ENABLED(CONFIG_X86_32BIT_INIT)
#undef __HAVE_ARCH_MEMCPY #undef __HAVE_ARCH_MEMCPY
extern void *memcpy(void *, const void *, __kernel_size_t); extern void *memcpy(void *, const void *, __kernel_size_t);

View file

@ -10,7 +10,9 @@ obj-y += bios.o
obj-y += bios_asm.o obj-y += bios_asm.o
obj-y += bios_interrupts.o obj-y += bios_interrupts.o
endif endif
obj-y += string.o endif
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_X86_32BIT_INIT) += string.o
endif endif
ifndef CONFIG_SPL_BUILD ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTM) += bootm.o

View file

@ -264,6 +264,13 @@ static void cb_parse_mrc_cache(void *ptr, struct sysinfo_t *info)
info->mrc_cache = map_sysmem(cbmem->cbmem_tab, 0); info->mrc_cache = map_sysmem(cbmem->cbmem_tab, 0);
} }
static void cb_parse_acpi_rsdp(void *ptr, struct sysinfo_t *info)
{
struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
info->rsdp = map_sysmem(cbmem->cbmem_tab, 0);
}
__weak void cb_parse_unhandled(u32 tag, unsigned char *ptr) __weak void cb_parse_unhandled(u32 tag, unsigned char *ptr)
{ {
} }
@ -428,7 +435,12 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
case CB_TAG_MRC_CACHE: case CB_TAG_MRC_CACHE:
cb_parse_mrc_cache(rec, info); cb_parse_mrc_cache(rec, info);
break; break;
case CB_TAG_ACPI_RSDP:
cb_parse_acpi_rsdp(rec, info);
break;
default: default:
if (info->unimpl_count < SYSINFO_MAX_UNIMPL)
info->unimpl[info->unimpl_count++] = rec->tag;
cb_parse_unhandled(rec->tag, ptr); cb_parse_unhandled(rec->tag, ptr);
break; break;
} }
@ -454,6 +466,7 @@ int get_coreboot_info(struct sysinfo_t *info)
if (!ret) if (!ret)
return -ENOENT; return -ENOENT;
gd->arch.coreboot_table = addr; gd->arch.coreboot_table = addr;
gd_set_acpi_start(map_to_sysmem(info->rsdp));
gd->flags |= GD_FLG_SKIP_LL_INIT; gd->flags |= GD_FLG_SKIP_LL_INIT;
return 0; return 0;

View file

@ -42,7 +42,7 @@ int fsp_setup_pinctrl(void *ctx, struct event *event)
return ret; return ret;
} }
EVENT_SPY(EVT_DM_POST_INIT, fsp_setup_pinctrl); EVENT_SPY(EVT_DM_POST_INIT_F, fsp_setup_pinctrl);
#if !defined(CONFIG_TPL_BUILD) #if !defined(CONFIG_TPL_BUILD)
binman_sym_declare(ulong, intel_fsp_m, image_pos); binman_sym_declare(ulong, intel_fsp_m, image_pos);

View file

@ -303,7 +303,7 @@ static int mrccache_save_type(enum mrc_type_t type)
mrc = &gd->arch.mrc[type]; mrc = &gd->arch.mrc[type];
if (!mrc->len) if (!mrc->len)
return 0; return 0;
log_debug("Saving %#x bytes of MRC output data type %d to SPI flash\n", log_debug("Saving %x bytes of MRC output data type %d to SPI flash\n",
mrc->len, type); mrc->len, type);
ret = mrccache_get_region(type, &sf, &entry); ret = mrccache_get_region(type, &sf, &entry);
if (ret) if (ret)

View file

@ -117,6 +117,8 @@ static int x86_spl_init(void)
} }
#ifndef CONFIG_SYS_COREBOOT #ifndef CONFIG_SYS_COREBOOT
debug("BSS clear from %lx to %lx len %lx\n", (ulong)&__bss_start,
(ulong)&__bss_end, (ulong)&__bss_end - (ulong)&__bss_start);
memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start); memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
# ifndef CONFIG_TPL # ifndef CONFIG_TPL
@ -145,7 +147,6 @@ static int x86_spl_init(void)
debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret); debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
return ret; return ret;
} }
mtrr_commit(true);
# else # else
ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit); ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit);
if (ret) if (ret)
@ -184,7 +185,8 @@ void board_init_f(ulong flags)
void board_init_f_r(void) void board_init_f_r(void)
{ {
init_cache_f_r(); mtrr_commit(false);
init_cache();
gd->flags &= ~GD_FLG_SERIAL_READY; gd->flags &= ~GD_FLG_SERIAL_READY;
debug("cache status %d\n", dcache_status()); debug("cache status %d\n", dcache_status());
board_init_r(gd, 0); board_init_r(gd, 0);
@ -215,16 +217,9 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
spl_image->name = "U-Boot"; spl_image->name = "U-Boot";
if (!IS_ENABLED(CONFIG_SYS_COREBOOT)) { if (!IS_ENABLED(CONFIG_SYS_COREBOOT)) {
/* /* Copy U-Boot from ROM */
* Copy U-Boot from ROM memcpy((void *)spl_image->load_addr,
* TODO(sjg@chromium.org): Figure out a way to get the text base (void *)spl_get_image_pos(), spl_get_image_size());
* correctly here, and in the device-tree binman definition.
*
* Also consider using FIT so we get the correct image length
* and parameters.
*/
memcpy((char *)spl_image->load_addr, (char *)0xfff00000,
0x100000);
} }
debug("Loading to %lx\n", spl_image->load_addr); debug("Loading to %lx\n", spl_image->load_addr);

View file

@ -109,7 +109,7 @@ menu "Info commands"
config CMD_ACPI config CMD_ACPI
bool "acpi" bool "acpi"
depends on ACPIGEN depends on ACPI
default y default y
help help
List and dump ACPI tables. ACPI (Advanced Configuration and Power List and dump ACPI tables. ACPI (Advanced Configuration and Power

View file

@ -36,49 +36,11 @@ static void dump_hdr(struct acpi_table_header *hdr)
} }
} }
/**
* find_table() - Look up an ACPI table
*
* @sig: Signature of table (4 characters, upper case)
* Return: pointer to table header, or NULL if not found
*/
struct acpi_table_header *find_table(const char *sig)
{
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
int len, i, count;
rsdp = map_sysmem(gd_acpi_start(), 0);
if (!rsdp)
return NULL;
rsdt = map_sysmem(rsdp->rsdt_address, 0);
len = rsdt->header.length - sizeof(rsdt->header);
count = len / sizeof(u32);
for (i = 0; i < count; i++) {
struct acpi_table_header *hdr;
hdr = map_sysmem(rsdt->entry[i], 0);
if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN))
return hdr;
if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) {
struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt)
return map_sysmem(fadt->dsdt, 0);
if (!memcmp(sig, "FACS", ACPI_NAME_LEN) &&
fadt->firmware_ctrl)
return map_sysmem(fadt->firmware_ctrl, 0);
}
}
return NULL;
}
static int dump_table_name(const char *sig) static int dump_table_name(const char *sig)
{ {
struct acpi_table_header *hdr; struct acpi_table_header *hdr;
hdr = find_table(sig); hdr = acpi_find_table(sig);
if (!hdr) if (!hdr)
return -ENOENT; return -ENOENT;
printf("%.*s @ %08lx\n", ACPI_NAME_LEN, hdr->signature, printf("%.*s @ %08lx\n", ACPI_NAME_LEN, hdr->signature,
@ -162,6 +124,10 @@ static int do_acpi_items(struct cmd_tbl *cmdtp, int flag, int argc,
bool dump_contents; bool dump_contents;
dump_contents = argc >= 2 && !strcmp("-d", argv[1]); dump_contents = argc >= 2 && !strcmp("-d", argv[1]);
if (!IS_ENABLED(CONFIG_ACPIGEN)) {
printf("Not supported (enable ACPIGEN)\n");
return CMD_RET_FAILURE;
}
acpi_dump_items(dump_contents ? ACPI_DUMP_CONTENTS : ACPI_DUMP_LIST); acpi_dump_items(dump_contents ? ACPI_DUMP_CONTENTS : ACPI_DUMP_LIST);
return 0; return 0;

View file

@ -363,6 +363,15 @@ static void show_table(struct sysinfo_t *info, bool verbose)
print_hex("MTC size", info->mtc_size); print_hex("MTC size", info->mtc_size);
print_ptr("Chrome OS VPD", info->chromeos_vpd); print_ptr("Chrome OS VPD", info->chromeos_vpd);
print_ptr("RSDP", info->rsdp);
printf("%-12s: ", "Unimpl.");
if (info->unimpl_count) {
for (i = 0; i < info->unimpl_count; i++)
printf("%02x ", info->unimpl[i]);
printf("\n");
} else {
printf("(none)\n");
}
} }
static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc, static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc,

View file

@ -148,7 +148,8 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
printf("CPU %d:\n", i); printf("CPU %d:\n", i);
ret = do_mtrr_list(reg_count, i); ret = do_mtrr_list(reg_count, i);
if (ret) { if (ret) {
printf("Failed to read CPU %d (err=%d)\n", i, printf("Failed to read CPU %s (err=%d)\n",
i < MP_SELECT_ALL ? simple_itoa(i) : "",
ret); ret);
return CMD_RET_FAILURE; return CMD_RET_FAILURE;
} }

View file

@ -84,3 +84,4 @@ CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
CONFIG_TPM=y CONFIG_TPM=y
# CONFIG_GZIP is not set # CONFIG_GZIP is not set
# CONFIG_EFI_LOADER is not set

View file

@ -1,6 +1,6 @@
CONFIG_X86=y CONFIG_X86=y
CONFIG_TEXT_BASE=0xffed0000 CONFIG_TEXT_BASE=0xffed0000
CONFIG_SYS_MALLOC_F_LEN=0x1a00 CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_NR_DRAM_BANKS=8 CONFIG_NR_DRAM_BANKS=8
CONFIG_ENV_SIZE=0x1000 CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x3F8000 CONFIG_ENV_OFFSET=0x3F8000
@ -8,7 +8,7 @@ CONFIG_ENV_SECT_SIZE=0x1000
CONFIG_SPL_DM_SPI=y CONFIG_SPL_DM_SPI=y
CONFIG_DEFAULT_DEVICE_TREE="chromebook_samus" CONFIG_DEFAULT_DEVICE_TREE="chromebook_samus"
CONFIG_SPL_TEXT_BASE=0xffe70000 CONFIG_SPL_TEXT_BASE=0xffe70000
CONFIG_TPL_TEXT_BASE=0xfffd8000 CONFIG_TPL_TEXT_BASE=0xfffd8100
CONFIG_DEBUG_UART_BASE=0x3f8 CONFIG_DEBUG_UART_BASE=0x3f8
CONFIG_DEBUG_UART_CLOCK=1843200 CONFIG_DEBUG_UART_CLOCK=1843200
CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART_BOARD_INIT=y

View file

@ -62,7 +62,6 @@ CONFIG_ATAPI=y
CONFIG_LBA48=y CONFIG_LBA48=y
CONFIG_SYS_64BIT_LBA=y CONFIG_SYS_64BIT_LBA=y
# CONFIG_PCI_PNP is not set # CONFIG_PCI_PNP is not set
CONFIG_SYS_NS16550_PORT_MAPPED=y
CONFIG_SOUND=y CONFIG_SOUND=y
CONFIG_SOUND_I8254=y CONFIG_SOUND_I8254=y
CONFIG_CONSOLE_SCROLL_LINES=5 CONFIG_CONSOLE_SCROLL_LINES=5

View file

@ -16,10 +16,15 @@ CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000" CONFIG_BOOTCOMMAND="ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000"
CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_LOG=y
CONFIG_LOGF_LINE=y
CONFIG_LOGF_FUNC=y
CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_LAST_STAGE_INIT=y CONFIG_LAST_STAGE_INIT=y
CONFIG_PCI_INIT_R=y
CONFIG_HUSH_PARSER=y CONFIG_HUSH_PARSER=y
CONFIG_SYS_PBSIZE=532 CONFIG_SYS_PBSIZE=532
CONFIG_CMD_MEM_SEARCH=y
CONFIG_CMD_IDE=y CONFIG_CMD_IDE=y
CONFIG_CMD_MMC=y CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y CONFIG_CMD_PART=y
@ -55,10 +60,11 @@ CONFIG_SYS_ATA_ALT_OFFSET=0
CONFIG_ATAPI=y CONFIG_ATAPI=y
CONFIG_LBA48=y CONFIG_LBA48=y
CONFIG_SYS_64BIT_LBA=y CONFIG_SYS_64BIT_LBA=y
CONFIG_NVME_PCI=y
# CONFIG_PCI_PNP is not set # CONFIG_PCI_PNP is not set
CONFIG_SYS_NS16550_PORT_MAPPED=y
CONFIG_SOUND=y CONFIG_SOUND=y
CONFIG_SOUND_I8254=y CONFIG_SOUND_I8254=y
CONFIG_CONSOLE_SCROLL_LINES=5 CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_CMD_DHRYSTONE=y
# CONFIG_GZIP is not set # CONFIG_GZIP is not set
CONFIG_SMBIOS_PARSER=y CONFIG_SMBIOS_PARSER=y

View file

@ -71,3 +71,32 @@ Memory map
(typically redirects to 7ab10030 or similar) (typically redirects to 7ab10030 or similar)
500 Location of coreboot sysinfo table, used during startup 500 Location of coreboot sysinfo table, used during startup
========== ================================================================== ========== ==================================================================
Debug UART
----------
It is possible to enable the debug UART with coreboot. To do this, use the
info from the cbsysinfo command to locate the UART base. For example::
=> cbsysinfo
...
Serial I/O port: 00000000
base : 00000000
pointer : 767b51bc
type : 2
base : fe03e000
baud : 0d115200
regwidth : 4
input_hz : 0d1843200
PCI addr : 00000010
...
Here you can see that the UART base is fe03e000, regwidth is 4 (1 << 2) and the
input clock is 1843200. So you can add the following CONFIG options::
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=fe03e000
CONFIG_DEBUG_UART_CLOCK=1843200
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_DEBUG_UART_ANNOUNCE=y

View file

@ -11,7 +11,7 @@ block device is probed.
Rather than using weak functions and direct calls across subsystemss, it is Rather than using weak functions and direct calls across subsystemss, it is
often easier to use an event. often easier to use an event.
An event consists of a type (e.g. EVT_DM_POST_INIT) and some optional data, An event consists of a type (e.g. EVT_DM_POST_INIT_F) and some optional data,
in `union event_data`. An event spy can be created to watch for events of a in `union event_data`. An event spy can be created to watch for events of a
particular type. When the event is created, it is sent to each spy in turn. particular type. When the event is created, it is sent to each spy in turn.
@ -26,9 +26,9 @@ To declare a spy, use something like this::
/* do something */ /* do something */
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, snow_setup_cpus); EVENT_SPY(EVT_DM_POST_INIT_F, snow_setup_cpus);
Your function is called when EVT_DM_POST_INIT is emitted, i.e. after driver Your function is called when EVT_DM_POST_INIT_F is emitted, i.e. after driver
model is inited (in SPL, or in U-Boot proper before and after relocation). model is inited (in SPL, or in U-Boot proper before and after relocation).

View file

@ -448,6 +448,7 @@ config OFNODE_MULTI_TREE_MAX
config ACPIGEN config ACPIGEN
bool "Support ACPI table generation in driver model" bool "Support ACPI table generation in driver model"
depends on ACPI
default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU) default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU)
select LIB_UUID select LIB_UUID
help help

View file

@ -436,8 +436,8 @@ int dm_init_and_scan(bool pre_reloc_only)
return ret; return ret;
} }
} }
if (CONFIG_IS_ENABLED(DM_EVENT)) { if (CONFIG_IS_ENABLED(DM_EVENT) && !(gd->flags & GD_FLG_RELOC)) {
ret = event_notify_null(EVT_DM_POST_INIT); ret = event_notify_null(EVT_DM_POST_INIT_F);
if (ret) if (ret)
return log_msg_ret("ev", ret); return log_msg_ret("ev", ret);
} }

View file

@ -29,7 +29,7 @@ static int microblaze_cpu_probe_all(void *ctx, struct event *event)
return 0; return 0;
} }
EVENT_SPY(EVT_DM_POST_INIT, microblaze_cpu_probe_all); EVENT_SPY(EVT_DM_POST_INIT_F, microblaze_cpu_probe_all);
static void microblaze_set_cpuinfo_pvr(struct microblaze_cpuinfo *ci) static void microblaze_set_cpuinfo_pvr(struct microblaze_cpuinfo *ci)
{ {

View file

@ -6,6 +6,8 @@
/* i8042.c - Intel 8042 keyboard driver routines */ /* i8042.c - Intel 8042 keyboard driver routines */
#define LOG_CATEGORY UCLASS_KEYBOARD
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <env.h> #include <env.h>
@ -54,6 +56,14 @@ static unsigned char ext_key_map[] = {
0x00 /* map end */ 0x00 /* map end */
}; };
/**
* kbd_input_empty() - Wait until the keyboard is ready for a command
*
* Checks the IBF flag (input buffer full), waiting for it to indicate that
* any previous command has been processed.
*
* Return: true if ready, false if it timed out
*/
static int kbd_input_empty(void) static int kbd_input_empty(void)
{ {
int kbd_timeout = KBD_TIMEOUT * 1000; int kbd_timeout = KBD_TIMEOUT * 1000;
@ -64,6 +74,12 @@ static int kbd_input_empty(void)
return kbd_timeout != -1; return kbd_timeout != -1;
} }
/**
* kbd_output_full() - Wait until the keyboard has data available
*
* Checks the OBF flag (output buffer full), waiting for it to indicate that
* a response to a previous command is available
*/
static int kbd_output_full(void) static int kbd_output_full(void)
{ {
int kbd_timeout = KBD_TIMEOUT * 1000; int kbd_timeout = KBD_TIMEOUT * 1000;
@ -127,6 +143,9 @@ static int kbd_reset(int quirk)
{ {
int config; int config;
if (!kbd_input_empty())
goto err;
/* controller self test */ /* controller self test */
if (kbd_cmd_read(CMD_SELF_TEST) != KBC_TEST_OK) if (kbd_cmd_read(CMD_SELF_TEST) != KBC_TEST_OK)
goto err; goto err;

View file

@ -189,7 +189,8 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
struct mtd_info *mtd = &flash->mtd; struct mtd_info *mtd = &flash->mtd;
struct erase_info instr; struct erase_info instr;
if (offset % mtd->erasesize || len % mtd->erasesize) { if (!mtd->erasesize ||
(offset % mtd->erasesize || len % mtd->erasesize)) {
debug("SF: Erase offset/length not multiple of erase size\n"); debug("SF: Erase offset/length not multiple of erase size\n");
return -EINVAL; return -EINVAL;
} }

View file

@ -361,7 +361,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
* Erase an address range on the nor chip. The address range may extend * Erase an address range on the nor chip. The address range may extend
* one or more erase sectors. Return an error is there is a problem erasing. * one or more erase sectors. Return an error is there is a problem erasing.
*/ */
static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) static int spi_nor_erase_tiny(struct mtd_info *mtd, struct erase_info *instr)
{ {
return -ENOTSUPP; return -ENOTSUPP;
} }
@ -390,8 +390,8 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
return ERR_PTR(-EMEDIUMTYPE); return ERR_PTR(-EMEDIUMTYPE);
} }
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, static int spi_nor_read_tiny(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
struct spi_nor *nor = mtd_to_spi_nor(mtd); struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret; int ret;
@ -426,8 +426,8 @@ read_err:
* FLASH_PAGESIZE chunks. The address range may be any size provided * FLASH_PAGESIZE chunks. The address range may be any size provided
* it is within the physical boundaries. * it is within the physical boundaries.
*/ */
static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, static int spi_nor_write_tiny(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf) size_t *retlen, const u_char *buf)
{ {
return -ENOTSUPP; return -ENOTSUPP;
} }
@ -741,9 +741,9 @@ int spi_nor_scan(struct spi_nor *nor)
mtd->writesize = 1; mtd->writesize = 1;
mtd->flags = MTD_CAP_NORFLASH; mtd->flags = MTD_CAP_NORFLASH;
mtd->size = info->sector_size * info->n_sectors; mtd->size = info->sector_size * info->n_sectors;
mtd->_erase = spi_nor_erase; mtd->_erase = spi_nor_erase_tiny;
mtd->_read = spi_nor_read; mtd->_read = spi_nor_read_tiny;
mtd->_write = spi_nor_write; mtd->_write = spi_nor_write_tiny;
nor->size = mtd->size; nor->size = mtd->size;

View file

@ -6,6 +6,7 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <init.h>
#include <pci.h> #include <pci.h>
#include "nvme.h" #include "nvme.h"
@ -30,6 +31,10 @@ static int nvme_probe(struct udevice *udev)
ndev->instance = trailing_strtol(udev->name); ndev->instance = trailing_strtol(udev->name);
ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0, ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0,
PCI_REGION_TYPE, PCI_REGION_MEM); PCI_REGION_TYPE, PCI_REGION_MEM);
/* Turn on bus-mastering */
dm_pci_clrset_config16(udev, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
return nvme_init(udev); return nvme_init(udev);
} }

View file

@ -973,6 +973,10 @@ static int decode_regions(struct pci_controller *hose, ofnode parent_node,
int len; int len;
int i; int i;
/* handle booting from coreboot, etc. */
if (!ll_boot_init())
return 0;
prop = ofnode_get_property(node, "ranges", &len); prop = ofnode_get_property(node, "ranges", &len);
if (!prop) { if (!prop) {
debug("%s: Cannot decode regions\n", __func__); debug("%s: Cannot decode regions\n", __func__);

View file

@ -669,6 +669,16 @@ config COREBOOT_SERIAL
a serial console on any platform without needing to change the a serial console on any platform without needing to change the
device tree, etc. device tree, etc.
config COREBOOT_SERIAL_FROM_DBG2
bool "Obtain UART from ACPI tables"
depends on COREBOOT_SERIAL
default y if !SPL
help
Select this to try to find a DBG2 record in the ACPI tables, in the
event that coreboot does not provide information about the UART in the
normal sysinfo tables. This provides a useful fallback when serial
is not enabled in coreboot.
config CORTINA_UART config CORTINA_UART
bool "Cortina UART support" bool "Cortina UART support"
depends on DM_SERIAL depends on DM_SERIAL

View file

@ -5,25 +5,123 @@
* Copyright 2019 Google LLC * Copyright 2019 Google LLC
*/ */
#define LOG_CATGEGORY UCLASS_SERIAL
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <log.h>
#include <ns16550.h> #include <ns16550.h>
#include <serial.h> #include <serial.h>
#include <acpi/acpi_table.h>
#include <asm/cb_sysinfo.h> #include <asm/cb_sysinfo.h>
DECLARE_GLOBAL_DATA_PTR;
static int read_dbg2(struct ns16550_plat *plat)
{
struct acpi_table_header *tab;
struct acpi_dbg2_header *hdr;
struct acpi_dbg2_device *dbg;
struct acpi_gen_regaddr *addr;
u32 *addr_size;
log_debug("Looking for DBG2 in ACPI tables\n");
if (!gd->acpi_start) {
log_debug("No ACPI tables\n");
return -ENOENT;
}
tab = acpi_find_table("DBG2");
if (!tab) {
log_debug("No DBG2 table\n");
return -ENOENT;
}
hdr = container_of(tab, struct acpi_dbg2_header, header);
/* We only use the first device, but check that there is at least one */
if (!hdr->devices_count) {
log_debug("No devices\n");
return -ENOENT;
}
if (hdr->devices_offset >= tab->length) {
log_debug("Invalid offset\n");
return -EINVAL;
}
dbg = (void *)hdr + hdr->devices_offset;
if (dbg->revision) {
log_debug("Invalid revision %d\n", dbg->revision);
return -EINVAL;
}
if (!dbg->address_count) {
log_debug("No addresses\n");
return -EINVAL;
}
if (dbg->port_type != ACPI_DBG2_SERIAL_PORT) {
log_debug("Not a serial port\n");
return -EPROTOTYPE;
}
if (dbg->port_subtype != ACPI_DBG2_16550_COMPATIBLE) {
log_debug("Incompatible serial port\n");
return -EPROTOTYPE;
}
if (dbg->base_address_offset >= dbg->length ||
dbg->address_size_offset >= dbg->length) {
log_debug("Invalid base address/size offsets %d, %d\n",
dbg->base_address_offset, dbg->address_size_offset);
return -EINVAL;
}
addr_size = (void *)dbg + dbg->address_size_offset;
if (!*addr_size) {
log_debug("Zero address size\n");
return -EINVAL;
}
addr = (void *)dbg + dbg->base_address_offset;
if (addr->space_id != ACPI_ADDRESS_SPACE_MEMORY) {
log_debug("Incompatible space %d\n", addr->space_id);
return -EPROTOTYPE;
}
plat->base = addr->addrl;
/* ACPI_ACCESS_SIZE_DWORD_ACCESS is 3; we want 2 */
plat->reg_shift = addr->access_size - 1;
plat->reg_width = 4; /* coreboot sets bit_width to 0 */
plat->clock = 1843200;
plat->fcr = UART_FCR_DEFVAL;
plat->flags = 0;
log_debug("Collected UART from ACPI DBG2 table\n");
return 0;
}
static int coreboot_of_to_plat(struct udevice *dev) static int coreboot_of_to_plat(struct udevice *dev)
{ {
struct ns16550_plat *plat = dev_get_plat(dev); struct ns16550_plat *plat = dev_get_plat(dev);
struct cb_serial *cb_info = lib_sysinfo.serial; struct cb_serial *cb_info = lib_sysinfo.serial;
int ret = -ENOENT;
plat->base = cb_info->baseaddr; if (cb_info) {
plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0; plat->base = cb_info->baseaddr;
plat->reg_width = cb_info->regwidth; plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0;
plat->clock = cb_info->input_hertz; plat->reg_width = cb_info->regwidth;
plat->fcr = UART_FCR_DEFVAL; plat->clock = cb_info->input_hertz;
plat->flags = 0; plat->fcr = UART_FCR_DEFVAL;
if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED) plat->flags = 0;
plat->flags |= NS16550_FLAG_IO; if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED)
plat->flags |= NS16550_FLAG_IO;
ret = 0;
} else if (IS_ENABLED(CONFIG_COREBOOT_SERIAL_FROM_DBG2)) {
ret = read_dbg2(plat);
}
if (ret) {
/*
* Returning an error will cause U-Boot to complain that
* there is no UART, which may panic. So stay silent and
* pray that the video console will work.
*/
log_debug("Cannot detect UART\n");
}
return 0; return 0;
} }

View file

@ -129,8 +129,13 @@ static int x86_sysreset_probe(struct udevice *dev)
{ {
struct x86_sysreset_plat *plat = dev_get_plat(dev); struct x86_sysreset_plat *plat = dev_get_plat(dev);
/* Locate the PCH if there is one. It isn't essential */ /*
uclass_first_device(UCLASS_PCH, &plat->pch); * Locate the PCH if there is one. It isn't essential. Avoid this before
* relocation as we shouldn't need reset then and it needs a lot of
* memory for PCI enumeration.
*/
if (gd->flags & GD_FLG_RELOC)
uclass_first_device(UCLASS_PCH, &plat->pch);
return 0; return 0;
} }

View file

@ -923,6 +923,14 @@ int acpi_fill_csrt(struct acpi_ctx *ctx);
*/ */
ulong write_acpi_tables(ulong start); ulong write_acpi_tables(ulong start);
/**
* acpi_find_table() - Look up an ACPI table
*
* @sig: Signature of table (4 characters, upper case)
* Return: pointer to table header, or NULL if not found
*/
struct acpi_table_header *acpi_find_table(const char *sig);
#endif /* !__ACPI__*/ #endif /* !__ACPI__*/
#include <asm/acpi_table.h> #include <asm/acpi_table.h>

View file

@ -457,7 +457,7 @@ struct global_data {
*/ */
fdt_addr_t translation_offset; fdt_addr_t translation_offset;
#endif #endif
#ifdef CONFIG_GENERATE_ACPI_TABLE #ifdef CONFIG_ACPI
/** /**
* @acpi_ctx: ACPI context pointer * @acpi_ctx: ACPI context pointer
*/ */
@ -536,7 +536,7 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
#define gd_dm_priv_base() NULL #define gd_dm_priv_base() NULL
#endif #endif
#ifdef CONFIG_GENERATE_ACPI_TABLE #ifdef CONFIG_ACPI
#define gd_acpi_ctx() gd->acpi_ctx #define gd_acpi_ctx() gd->acpi_ctx
#define gd_acpi_start() gd->acpi_start #define gd_acpi_start() gd->acpi_start
#define gd_set_acpi_start(addr) gd->acpi_start = addr #define gd_set_acpi_start(addr) gd->acpi_start = addr

View file

@ -22,7 +22,7 @@ enum event_t {
EVT_TEST, EVT_TEST,
/* Events related to driver model */ /* Events related to driver model */
EVT_DM_POST_INIT, EVT_DM_POST_INIT_F,
EVT_DM_PRE_PROBE, EVT_DM_PRE_PROBE,
EVT_DM_POST_PROBE, EVT_DM_POST_PROBE,
EVT_DM_PRE_REMOVE, EVT_DM_PRE_REMOVE,

View file

@ -281,9 +281,17 @@ config SUPPORT_ACPI
U-Boot can generate these tables and pass them to the Operating U-Boot can generate these tables and pass them to the Operating
System. System.
config ACPI
bool "Enable support for ACPI libraries"
depends on SUPPORT_ACPI
help
Provides library functions for dealing with ACPI tables. This does
not necessarily include generation of tables
(see GENERATE_ACPI_TABLE), but allows for tables to be located.
config GENERATE_ACPI_TABLE config GENERATE_ACPI_TABLE
bool "Generate an ACPI (Advanced Configuration and Power Interface) table" bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
depends on SUPPORT_ACPI depends on ACPI
select QFW if QEMU select QFW if QEMU
help help
The Advanced Configuration and Power Interface (ACPI) specification The Advanced Configuration and Power Interface (ACPI) specification

View file

@ -66,7 +66,7 @@ obj-$(CONFIG_$(SPL_TPL_)CRC8) += crc8.o
obj-y += crypto/ obj-y += crypto/
obj-$(CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE) += acpi/ obj-$(CONFIG_$(SPL_TPL_)ACPI) += acpi/
obj-$(CONFIG_$(SPL_)MD5) += md5.o obj-$(CONFIG_$(SPL_)MD5) += md5.o
obj-$(CONFIG_ECDSA) += ecdsa/ obj-$(CONFIG_ECDSA) += ecdsa/
obj-$(CONFIG_$(SPL_)RSA) += rsa/ obj-$(CONFIG_$(SPL_)RSA) += rsa/

View file

@ -1,6 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+ # SPDX-License-Identifier: GPL-2.0+
# #
obj-y += acpi.o
ifdef CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o
@ -21,3 +25,5 @@ endif
obj-y += facs.o obj-y += facs.o
obj-y += ssdt.o obj-y += ssdt.o
endif endif
endif # GENERATE_ACPI_TABLE

45
lib/acpi/acpi.c Normal file
View file

@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Utility functions for ACPI
*
* Copyright 2023 Google LLC
*/
#include <common.h>
#include <mapmem.h>
#include <acpi/acpi_table.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
struct acpi_table_header *acpi_find_table(const char *sig)
{
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
int len, i, count;
rsdp = map_sysmem(gd_acpi_start(), 0);
if (!rsdp)
return NULL;
rsdt = map_sysmem(rsdp->rsdt_address, 0);
len = rsdt->header.length - sizeof(rsdt->header);
count = len / sizeof(u32);
for (i = 0; i < count; i++) {
struct acpi_table_header *hdr;
hdr = map_sysmem(rsdt->entry[i], 0);
if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN))
return hdr;
if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) {
struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt)
return map_sysmem(fadt->dsdt, 0);
if (!memcmp(sig, "FACS", ACPI_NAME_LEN) &&
fadt->firmware_ctrl)
return map_sysmem(fadt->firmware_ctrl, 0);
}
}
return NULL;
}

View file

@ -18,7 +18,7 @@ class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr):
process. process.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node):
super().__init__(section, etype, node) super().__init__(section, etype, node, auto_write_symbols=True)
self.elf_fname = 'spl/u-boot-spl' self.elf_fname = 'spl/u-boot-spl'
def GetDefaultFilename(self): def GetDefaultFilename(self):

View file

@ -20,7 +20,7 @@ class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr):
process. process.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node):
super().__init__(section, etype, node) super().__init__(section, etype, node, auto_write_symbols=True)
self.elf_fname = 'tpl/u-boot-tpl' self.elf_fname = 'tpl/u-boot-tpl'
def GetDefaultFilename(self): def GetDefaultFilename(self):

View file

@ -28,8 +28,8 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob):
microcode, to allow early x86 boot code to find it without doing anything microcode, to allow early x86 boot code to find it without doing anything
complicated. Otherwise it is the same as the u-boot entry. complicated. Otherwise it is the same as the u-boot entry.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node, auto_write_symbols=False):
super().__init__(section, etype, node) super().__init__(section, etype, node, auto_write_symbols)
self.elf_fname = 'u-boot' self.elf_fname = 'u-boot'
self.target_offset = None self.target_offset = None