- 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 <dm.h>
#include <efi_loader.h>
#include <asm/control_regs.h>
#include <asm/i8259.h>
#include <asm/interrupt.h>
@ -64,6 +65,18 @@ static char *exceptions[] = {
"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)
{
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));
sp -= 4;
}
show_efi_loaded_images(eip);
}
static void do_exception(struct irq_regs *regs)

View file

@ -9,7 +9,7 @@
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
u32 qemu_get_low_memory_size(void)
{
u32 ram;
@ -19,7 +19,27 @@ int dram_init(void)
ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
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);
return 0;
@ -27,8 +47,16 @@ int dram_init(void)
int dram_init_banksize(void)
{
u64 high_mem_size;
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;
}
@ -43,5 +71,5 @@ int dram_init_banksize(void)
*/
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+
/*
* QEMU x86 specific E820 table generation
*
* (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
* (C) Copyright 2019 Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <env_internal.h>
#include <asm/e820.h>
#include <asm/arch/qemu.h>
DECLARE_GLOBAL_DATA_PTR;
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
entries[0].addr = 0;
entries[0].size = ISA_START_ADDRESS;
entries[0].type = E820_RAM;
u64 high_mem_size;
int n = 0;
entries[1].addr = ISA_START_ADDRESS;
entries[1].size = ISA_END_ADDRESS - ISA_START_ADDRESS;
entries[1].type = E820_RESERVED;
entries[n].addr = 0;
entries[n].size = ISA_START_ADDRESS;
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
* storing ACPI tables, we need to reserve them in e820 tables,
* otherwise kernel will reclaim them and data will be corrupted
*/
entries[2].addr = ISA_END_ADDRESS;
entries[2].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS;
entries[2].type = E820_RAM;
entries[n].addr = ISA_END_ADDRESS;
entries[n].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS;
entries[n].type = E820_RAM;
n++;
/* for simplicity, reserve entire malloc space */
entries[3].addr = gd->relocaddr - TOTAL_MALLOC_LEN;
entries[3].size = TOTAL_MALLOC_LEN;
entries[3].type = E820_RESERVED;
entries[n].addr = gd->relocaddr - TOTAL_MALLOC_LEN;
entries[n].size = TOTAL_MALLOC_LEN;
entries[n].type = E820_RESERVED;
n++;
entries[4].addr = gd->relocaddr;
entries[4].size = gd->ram_size - gd->relocaddr;
entries[4].type = E820_RESERVED;
entries[n].addr = gd->relocaddr;
entries[n].size = qemu_get_low_memory_size() - gd->relocaddr;
entries[n].type = E820_RESERVED;
n++;
entries[5].addr = CONFIG_PCIE_ECAM_BASE;
entries[5].size = CONFIG_PCIE_ECAM_SIZE;
entries[5].type = E820_RESERVED;
entries[n].addr = CONFIG_PCIE_ECAM_BASE;
entries[n].size = CONFIG_PCIE_ECAM_SIZE;
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/tables.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 *dsdt)
@ -63,7 +64,7 @@ u32 acpi_fill_mcfg(u32 current)
/* TODO: Derive parameters from SFI MCFG table */
current += acpi_create_mcfg_mmconfig
((struct acpi_mcfg_mmconfig *)current,
0x3f500000, 0x0, 0x0, 0x0);
MCFG_BASE_ADDRESS, 0x0, 0x0, 0x0);
return current;
}
@ -94,7 +95,7 @@ static u32 acpi_fill_csrt_dma(struct acpi_csrt_group *grp)
si->dma_address_width = 32;
si->base_request_line = 0;
si->num_handshake_signals = 16;
si->max_block_size = 0x20000;
si->max_block_size = 0x1ffff;
return grp->length;
}

View file

@ -34,7 +34,7 @@ struct acpi_rsdp {
};
/* 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) */
u32 length; /* Table length in bytes (incl. header) */
u8 revision; /* Table version (not ACPI version!) */

View file

@ -32,9 +32,27 @@
#define LOW_RAM_ADDR 0x34
#define HIGH_RAM_ADDR 0x35
#define LOW_HIGHRAM_ADDR 0x5b
#define MID_HIGHRAM_ADDR 0x5c
#define HIGH_HIGHRAM_ADDR 0x5d
/* PM registers */
#define PMBA 0x40
#define PMREGMISC 0x80
#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_ */

View file

@ -6,6 +6,7 @@
*/
#include <asm/acpi/statdef.asl>
#include <asm/arch/iomap.h>
/*
* 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 */
Method(_WAK, 1)
{
Return (Package() {0, 0})
Return (Package() { Zero, Zero })
}
Scope (_SB)

View file

@ -10,8 +10,8 @@ Device (PCI0)
Name (_HID, EISAID("PNP0A08")) /* PCIe */
Name (_CID, EISAID("PNP0A03")) /* PCI */
Name (_ADR, 0)
Name (_BBN, 0)
Name (_ADR, Zero)
Name (_BBN, Zero)
Name (MCRS, ResourceTemplate()
{
@ -66,6 +66,23 @@ Device (PCI0)
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)
{
/* Check for proper GUID */
@ -365,19 +382,19 @@ Device (PCI0)
Name (RBUF, ResourceTemplate()
{
/*
* Shadow registers in SRAM for PMIC:
* SRAM PMIC register
* --------------------
* 0x00- Unknown
* 0x03 THRMIRQ (0x04)
* 0x04 BCUIRQ (0x05)
* 0x05 ADCIRQ (0x06)
* 0x06 CHGRIRQ0 (0x07)
* 0x07 CHGRIRQ1 (0x08)
* 0x08- Unknown
* 0x0a PBSTATUS (0x27)
* 0x0b- Unknown
*/
* Shadow registers in SRAM for PMIC:
* SRAM PMIC register
* --------------------
* 0x00- Unknown
* 0x03 THRMIRQ (0x04)
* 0x04 BCUIRQ (0x05)
* 0x05 ADCIRQ (0x06)
* 0x06 CHGRIRQ0 (0x07)
* 0x07 CHGRIRQ1 (0x08)
* 0x08- Unknown
* 0x0a PBSTATUS (0x27)
* 0x0b- Unknown
*/
Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 }
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];
unsigned int i, num;
u64 start, pages;
u64 start, pages, ram_top;
int type;
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) {
start = e820[i].addr;
pages = ALIGN(e820[i].size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
switch (e820[i].type) {
case E820_RAM:
@ -69,7 +72,15 @@ void efi_add_known_memory(void)
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) */

View file

@ -10,12 +10,6 @@
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)
{
#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
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
---------------------------------------------------------------

1
tools/.gitignore vendored
View file

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