- Tangier ACPI table fixes
- Support getting high memory size on QEMU x86
- Show UEFI images involved in crash for x86
- EFI loader conventional memory map fix
This commit is contained in:
Tom Rini 2019-09-10 08:52:00 -04:00
commit 001c8ea94a
13 changed files with 189 additions and 51 deletions

View file

@ -12,6 +12,7 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <efi_loader.h>
#include <asm/control_regs.h> #include <asm/control_regs.h>
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/interrupt.h> #include <asm/interrupt.h>
@ -64,6 +65,18 @@ static char *exceptions[] = {
"Reserved" "Reserved"
}; };
/**
* show_efi_loaded_images() - show loaded UEFI images
*
* List all loaded UEFI images.
*
* @eip: instruction pointer
*/
static void show_efi_loaded_images(uintptr_t eip)
{
efi_print_image_infos((void *)eip);
}
static void dump_regs(struct irq_regs *regs) static void dump_regs(struct irq_regs *regs)
{ {
unsigned long cs, eip, eflags; unsigned long cs, eip, eflags;
@ -144,6 +157,7 @@ static void dump_regs(struct irq_regs *regs)
printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp)); printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp));
sp -= 4; sp -= 4;
} }
show_efi_loaded_images(eip);
} }
static void do_exception(struct irq_regs *regs) static void do_exception(struct irq_regs *regs)

View file

@ -9,7 +9,7 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) u32 qemu_get_low_memory_size(void)
{ {
u32 ram; u32 ram;
@ -19,7 +19,27 @@ int dram_init(void)
ram |= ((u32)inb(CMOS_DATA_PORT)) << 6; ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
ram += 16 * 1024; ram += 16 * 1024;
gd->ram_size = ram * 1024; return ram * 1024;
}
u64 qemu_get_high_memory_size(void)
{
u64 ram;
outb(HIGH_HIGHRAM_ADDR, CMOS_ADDR_PORT);
ram = ((u64)inb(CMOS_DATA_PORT)) << 22;
outb(MID_HIGHRAM_ADDR, CMOS_ADDR_PORT);
ram |= ((u64)inb(CMOS_DATA_PORT)) << 14;
outb(LOW_HIGHRAM_ADDR, CMOS_ADDR_PORT);
ram |= ((u64)inb(CMOS_DATA_PORT)) << 6;
return ram * 1024;
}
int dram_init(void)
{
gd->ram_size = qemu_get_low_memory_size();
gd->ram_size += qemu_get_high_memory_size();
post_code(POST_DRAM); post_code(POST_DRAM);
return 0; return 0;
@ -27,8 +47,16 @@ int dram_init(void)
int dram_init_banksize(void) int dram_init_banksize(void)
{ {
u64 high_mem_size;
gd->bd->bi_dram[0].start = 0; gd->bd->bi_dram[0].start = 0;
gd->bd->bi_dram[0].size = gd->ram_size; gd->bd->bi_dram[0].size = qemu_get_low_memory_size();
high_mem_size = qemu_get_high_memory_size();
if (high_mem_size) {
gd->bd->bi_dram[1].start = SZ_4G;
gd->bd->bi_dram[1].size = high_mem_size;
}
return 0; return 0;
} }
@ -43,5 +71,5 @@ int dram_init_banksize(void)
*/ */
ulong board_get_usable_ram_top(ulong total_size) ulong board_get_usable_ram_top(ulong total_size)
{ {
return gd->ram_size; return qemu_get_low_memory_size();
} }

View file

@ -1,46 +1,67 @@
// SPDX-License-Identifier: GPL-2.0+ // SPDX-License-Identifier: GPL-2.0+
/* /*
* QEMU x86 specific E820 table generation
*
* (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
* (C) Copyright 2019 Bin Meng <bmeng.cn@gmail.com>
*/ */
#include <common.h> #include <common.h>
#include <env_internal.h> #include <env_internal.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/arch/qemu.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
unsigned int install_e820_map(unsigned int max_entries, unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries) struct e820_entry *entries)
{ {
entries[0].addr = 0; u64 high_mem_size;
entries[0].size = ISA_START_ADDRESS; int n = 0;
entries[0].type = E820_RAM;
entries[1].addr = ISA_START_ADDRESS; entries[n].addr = 0;
entries[1].size = ISA_END_ADDRESS - ISA_START_ADDRESS; entries[n].size = ISA_START_ADDRESS;
entries[1].type = E820_RESERVED; entries[n].type = E820_RAM;
n++;
entries[n].addr = ISA_START_ADDRESS;
entries[n].size = ISA_END_ADDRESS - ISA_START_ADDRESS;
entries[n].type = E820_RESERVED;
n++;
/* /*
* since we use memalign(malloc) to allocate high memory for * since we use memalign(malloc) to allocate high memory for
* storing ACPI tables, we need to reserve them in e820 tables, * storing ACPI tables, we need to reserve them in e820 tables,
* otherwise kernel will reclaim them and data will be corrupted * otherwise kernel will reclaim them and data will be corrupted
*/ */
entries[2].addr = ISA_END_ADDRESS; entries[n].addr = ISA_END_ADDRESS;
entries[2].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS; entries[n].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS;
entries[2].type = E820_RAM; entries[n].type = E820_RAM;
n++;
/* for simplicity, reserve entire malloc space */ /* for simplicity, reserve entire malloc space */
entries[3].addr = gd->relocaddr - TOTAL_MALLOC_LEN; entries[n].addr = gd->relocaddr - TOTAL_MALLOC_LEN;
entries[3].size = TOTAL_MALLOC_LEN; entries[n].size = TOTAL_MALLOC_LEN;
entries[3].type = E820_RESERVED; entries[n].type = E820_RESERVED;
n++;
entries[4].addr = gd->relocaddr; entries[n].addr = gd->relocaddr;
entries[4].size = gd->ram_size - gd->relocaddr; entries[n].size = qemu_get_low_memory_size() - gd->relocaddr;
entries[4].type = E820_RESERVED; entries[n].type = E820_RESERVED;
n++;
entries[5].addr = CONFIG_PCIE_ECAM_BASE; entries[n].addr = CONFIG_PCIE_ECAM_BASE;
entries[5].size = CONFIG_PCIE_ECAM_SIZE; entries[n].size = CONFIG_PCIE_ECAM_SIZE;
entries[5].type = E820_RESERVED; entries[n].type = E820_RESERVED;
n++;
return 6; high_mem_size = qemu_get_high_memory_size();
if (high_mem_size) {
entries[n].addr = SZ_4G;
entries[n].size = high_mem_size;
entries[n].type = E820_RAM;
n++;
}
return n;
} }

View file

@ -14,6 +14,7 @@
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/tables.h> #include <asm/tables.h>
#include <asm/arch/global_nvs.h> #include <asm/arch/global_nvs.h>
#include <asm/arch/iomap.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
void *dsdt) void *dsdt)
@ -63,7 +64,7 @@ u32 acpi_fill_mcfg(u32 current)
/* TODO: Derive parameters from SFI MCFG table */ /* TODO: Derive parameters from SFI MCFG table */
current += acpi_create_mcfg_mmconfig current += acpi_create_mcfg_mmconfig
((struct acpi_mcfg_mmconfig *)current, ((struct acpi_mcfg_mmconfig *)current,
0x3f500000, 0x0, 0x0, 0x0); MCFG_BASE_ADDRESS, 0x0, 0x0, 0x0);
return current; return current;
} }
@ -94,7 +95,7 @@ static u32 acpi_fill_csrt_dma(struct acpi_csrt_group *grp)
si->dma_address_width = 32; si->dma_address_width = 32;
si->base_request_line = 0; si->base_request_line = 0;
si->num_handshake_signals = 16; si->num_handshake_signals = 16;
si->max_block_size = 0x20000; si->max_block_size = 0x1ffff;
return grp->length; return grp->length;
} }

View file

@ -34,7 +34,7 @@ struct acpi_rsdp {
}; };
/* Generic ACPI header, provided by (almost) all tables */ /* Generic ACPI header, provided by (almost) all tables */
struct acpi_table_header { struct __packed acpi_table_header {
char signature[4]; /* ACPI signature (4 ASCII characters) */ char signature[4]; /* ACPI signature (4 ASCII characters) */
u32 length; /* Table length in bytes (incl. header) */ u32 length; /* Table length in bytes (incl. header) */
u8 revision; /* Table version (not ACPI version!) */ u8 revision; /* Table version (not ACPI version!) */

View file

@ -32,9 +32,27 @@
#define LOW_RAM_ADDR 0x34 #define LOW_RAM_ADDR 0x34
#define HIGH_RAM_ADDR 0x35 #define HIGH_RAM_ADDR 0x35
#define LOW_HIGHRAM_ADDR 0x5b
#define MID_HIGHRAM_ADDR 0x5c
#define HIGH_HIGHRAM_ADDR 0x5d
/* PM registers */ /* PM registers */
#define PMBA 0x40 #define PMBA 0x40
#define PMREGMISC 0x80 #define PMREGMISC 0x80
#define PMIOSE (1 << 0) #define PMIOSE (1 << 0)
/**
* qemu_get_low_memory_size() - Get low memory size
*
* @return: size of memory below 4GiB
*/
u32 qemu_get_low_memory_size(void);
/**
* qemu_get_high_memory_size() - Get high memory size
*
* @return: size of memory above 4GiB
*/
u64 qemu_get_high_memory_size(void);
#endif /* _ARCH_QEMU_H_ */ #endif /* _ARCH_QEMU_H_ */

View file

@ -6,6 +6,7 @@
*/ */
#include <asm/acpi/statdef.asl> #include <asm/acpi/statdef.asl>
#include <asm/arch/iomap.h>
/* /*
* The _PTS method (Prepare To Sleep) is called before the OS is * The _PTS method (Prepare To Sleep) is called before the OS is
@ -18,7 +19,7 @@ Method(_PTS, 1)
/* The _WAK method is called on system wakeup */ /* The _WAK method is called on system wakeup */
Method(_WAK, 1) Method(_WAK, 1)
{ {
Return (Package() {0, 0}) Return (Package() { Zero, Zero })
} }
Scope (_SB) Scope (_SB)

View file

@ -10,8 +10,8 @@ Device (PCI0)
Name (_HID, EISAID("PNP0A08")) /* PCIe */ Name (_HID, EISAID("PNP0A08")) /* PCIe */
Name (_CID, EISAID("PNP0A03")) /* PCI */ Name (_CID, EISAID("PNP0A03")) /* PCI */
Name (_ADR, 0) Name (_ADR, Zero)
Name (_BBN, 0) Name (_BBN, Zero)
Name (MCRS, ResourceTemplate() Name (MCRS, ResourceTemplate()
{ {
@ -66,6 +66,23 @@ Device (PCI0)
Return (MCRS) Return (MCRS)
} }
/* Device Resource Consumption */
Device (PDRC)
{
Name (_HID, EISAID("PNP0C02"))
Name (_UID, One)
Name (PDRS, ResourceTemplate()
{
Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE)
})
Method (_CRS, 0, Serialized)
{
Return (PDRS)
}
}
Method (_OSC, 4) Method (_OSC, 4)
{ {
/* Check for proper GUID */ /* Check for proper GUID */
@ -365,19 +382,19 @@ Device (PCI0)
Name (RBUF, ResourceTemplate() Name (RBUF, ResourceTemplate()
{ {
/* /*
* Shadow registers in SRAM for PMIC: * Shadow registers in SRAM for PMIC:
* SRAM PMIC register * SRAM PMIC register
* -------------------- * --------------------
* 0x00- Unknown * 0x00- Unknown
* 0x03 THRMIRQ (0x04) * 0x03 THRMIRQ (0x04)
* 0x04 BCUIRQ (0x05) * 0x04 BCUIRQ (0x05)
* 0x05 ADCIRQ (0x06) * 0x05 ADCIRQ (0x06)
* 0x06 CHGRIRQ0 (0x07) * 0x06 CHGRIRQ0 (0x07)
* 0x07 CHGRIRQ1 (0x08) * 0x07 CHGRIRQ1 (0x08)
* 0x08- Unknown * 0x08- Unknown
* 0x0a PBSTATUS (0x27) * 0x0a PBSTATUS (0x27)
* 0x0b- Unknown * 0x0b- Unknown
*/ */
Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 }
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 }

View file

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2019 Intel Corporation */
#ifndef _TANGIER_IOMAP_H
#define _TANGIER_IOMAP_H
#define MCFG_BASE_ADDRESS 0x3f500000
#define MCFG_BASE_SIZE 0x00100000
#endif /* _TANGIER_IOMAP_H */

View file

@ -41,14 +41,17 @@ void efi_add_known_memory(void)
{ {
struct e820_entry e820[E820MAX]; struct e820_entry e820[E820MAX];
unsigned int i, num; unsigned int i, num;
u64 start, pages; u64 start, pages, ram_top;
int type; int type;
num = install_e820_map(ARRAY_SIZE(e820), e820); num = install_e820_map(ARRAY_SIZE(e820), e820);
ram_top = (u64)gd->ram_top & ~EFI_PAGE_MASK;
if (!ram_top)
ram_top = 0x100000000ULL;
for (i = 0; i < num; ++i) { for (i = 0; i < num; ++i) {
start = e820[i].addr; start = e820[i].addr;
pages = ALIGN(e820[i].size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
switch (e820[i].type) { switch (e820[i].type) {
case E820_RAM: case E820_RAM:
@ -69,7 +72,15 @@ void efi_add_known_memory(void)
break; break;
} }
efi_add_memory_map(start, pages, type, false); if (type == EFI_CONVENTIONAL_MEMORY) {
efi_add_conventional_memory_map(start,
start + e820[i].size,
ram_top);
} else {
pages = ALIGN(e820[i].size, EFI_PAGE_SIZE)
>> EFI_PAGE_SHIFT;
efi_add_memory_map(start, pages, type, false);
}
} }
} }
#endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */

View file

@ -10,12 +10,6 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
/* Get the top of usable RAM */
__weak ulong board_get_usable_ram_top(ulong total_size)
{
return gd->ram_size;
}
int init_cache_f_r(void) int init_cache_f_r(void)
{ {
#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \ #if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \

View file

@ -86,6 +86,28 @@ The PayloadId can be any 4 Bytes value.
$ qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Outputs/qemu/SlimBootloader.bin $ qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Outputs/qemu/SlimBootloader.bin
Test Linux booting on QEMU target
---------------------------------
Let's use LeafHill (APL) Yocto image for testing.
Download it from http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/machines/leafhill/.
1. Prepare Yocto hard disk image::
$ wget http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/machines/leafhill/leafhill-4.0-jethro-2.0.tar.bz2
$ tar -xvf leafhill-4.0-jethro-2.0.tar.bz2
$ ls -l leafhill-4.0-jethro-2.0/binary/core-image-sato-intel-corei7-64.hddimg
2. Launch Slim Bootloader on QEMU with disk image::
$ qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Outputs/qemu/SlimBootloader.bin -drive id=mydrive,if=none,file=/path/to/core-image-sato-intel-corei7-64.hddimg,format=raw -device ide-hd,drive=mydrive
3. Update boot environment values on shell::
=> setenv bootfile vmlinuz
=> setenv bootdev scsi
=> boot
Build Instruction for Slim Bootloader for LeafHill (APL) target Build Instruction for Slim Bootloader for LeafHill (APL) target
--------------------------------------------------------------- ---------------------------------------------------------------

1
tools/.gitignore vendored
View file

@ -14,6 +14,7 @@
/gen_eth_addr /gen_eth_addr
/gen_ethaddr_crc /gen_ethaddr_crc
/ifdtool /ifdtool
/ifwitool
/img2srec /img2srec
/kwboot /kwboot
/lib/ /lib/