mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-x86
This commit is contained in:
commit
6d54868eeb
93 changed files with 9949 additions and 7620 deletions
1
Makefile
1
Makefile
|
@ -1452,6 +1452,7 @@ clean: $(clean-dirs)
|
|||
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
|
||||
-o -name '*.symtypes' -o -name 'modules.order' \
|
||||
-o -name modules.builtin -o -name '.tmp_*.o.*' \
|
||||
-o -name 'dsdt.aml' -o -name 'dsdt.asl.tmp' -o -name 'dsdt.c' \
|
||||
-o -name '*.gcno' \) -type f -print | xargs rm -f
|
||||
|
||||
# mrproper - Delete all generated files, including .config
|
||||
|
|
|
@ -274,6 +274,13 @@ config ENABLE_MRC_CACHE
|
|||
to be used for speeding up boot time on future reboots and/or
|
||||
power cycles.
|
||||
|
||||
For platforms that use Intel FSP for the memory initialization,
|
||||
please check FSP output HOB via U-Boot command 'fsp hob' to see
|
||||
if there is FSP_NON_VOLATILE_STORAGE_HOB_GUID (asm/fsp/fsp_hob.h).
|
||||
If such GUID does not exist, MRC cache is not avaiable on such
|
||||
platform (eg: Intel Queensbay), which means selecting this option
|
||||
here does not make any difference.
|
||||
|
||||
config HAVE_MRC
|
||||
bool "Add a System Agent binary"
|
||||
depends on !HAVE_FSP
|
||||
|
@ -439,21 +446,13 @@ config GENERATE_MP_TABLE
|
|||
config GENERATE_ACPI_TABLE
|
||||
bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
|
||||
default n
|
||||
select QFW if QEMU
|
||||
help
|
||||
The Advanced Configuration and Power Interface (ACPI) specification
|
||||
provides an open standard for device configuration and management
|
||||
by the operating system. It defines platform-independent interfaces
|
||||
for configuration and power management monitoring.
|
||||
|
||||
config QEMU_ACPI_TABLE
|
||||
bool "Load ACPI table from QEMU fw_cfg interface"
|
||||
depends on GENERATE_ACPI_TABLE && QEMU
|
||||
default y
|
||||
help
|
||||
By default, U-Boot generates its own ACPI tables. This option, if
|
||||
enabled, disables U-Boot's version and loads ACPI tables generated
|
||||
by QEMU.
|
||||
|
||||
config GENERATE_SMBIOS_TABLE
|
||||
bool "Generate an SMBIOS (System Management BIOS) table"
|
||||
default y
|
||||
|
@ -465,6 +464,22 @@ config GENERATE_SMBIOS_TABLE
|
|||
|
||||
Check http://www.dmtf.org/standards/smbios for details.
|
||||
|
||||
config SMBIOS_MANUFACTURER
|
||||
string "SMBIOS Manufacturer"
|
||||
depends on GENERATE_SMBIOS_TABLE
|
||||
default SYS_VENDOR
|
||||
help
|
||||
The board manufacturer to store in SMBIOS structures.
|
||||
Change this to override the default one (CONFIG_SYS_VENDOR).
|
||||
|
||||
config SMBIOS_PRODUCT_NAME
|
||||
string "SMBIOS Product Name"
|
||||
depends on GENERATE_SMBIOS_TABLE
|
||||
default SYS_BOARD
|
||||
help
|
||||
The product name to store in SMBIOS structures.
|
||||
Change this to override the default one (CONFIG_SYS_BOARD).
|
||||
|
||||
endmenu
|
||||
|
||||
config MAX_PIRQ_LINKS
|
||||
|
@ -539,6 +554,20 @@ config SEABIOS
|
|||
|
||||
Check http://www.seabios.org/SeaBIOS for details.
|
||||
|
||||
config HIGH_TABLE_SIZE
|
||||
hex "Size of configuration tables which reside in high memory"
|
||||
default 0x10000
|
||||
depends on SEABIOS
|
||||
help
|
||||
SeaBIOS itself resides in E seg and F seg, where U-Boot puts all
|
||||
configuration tables like PIRQ/MP/ACPI. To avoid conflicts, U-Boot
|
||||
puts a copy of configuration tables in high memory region which
|
||||
is reserved on the stack before relocation. The region size is
|
||||
determined by this option.
|
||||
|
||||
Increse it if the default size does not fit the board's needs.
|
||||
This is most likely due to a large ACPI DSDT table is used.
|
||||
|
||||
source "arch/x86/lib/efi/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -8,3 +8,4 @@ obj-y += cpu.o
|
|||
obj-y += early_uart.o
|
||||
obj-y += fsp_configs.o
|
||||
obj-y += valleyview.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
|
||||
|
|
163
arch/x86/cpu/baytrail/acpi.c
Normal file
163
arch/x86/cpu/baytrail/acpi.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/acpi_table.h>
|
||||
#include <asm/ioapic.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/tables.h>
|
||||
#include <asm/arch/iomap.h>
|
||||
|
||||
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
|
||||
void *dsdt)
|
||||
{
|
||||
struct acpi_table_header *header = &(fadt->header);
|
||||
u16 pmbase = ACPI_BASE_ADDRESS;
|
||||
|
||||
memset((void *)fadt, 0, sizeof(struct acpi_fadt));
|
||||
|
||||
acpi_fill_header(header, "FACP");
|
||||
header->length = sizeof(struct acpi_fadt);
|
||||
header->revision = 4;
|
||||
|
||||
fadt->firmware_ctrl = (u32)facs;
|
||||
fadt->dsdt = (u32)dsdt;
|
||||
fadt->preferred_pm_profile = ACPI_PM_MOBILE;
|
||||
fadt->sci_int = 9;
|
||||
fadt->smi_cmd = 0;
|
||||
fadt->acpi_enable = 0;
|
||||
fadt->acpi_disable = 0;
|
||||
fadt->s4bios_req = 0;
|
||||
fadt->pstate_cnt = 0;
|
||||
fadt->pm1a_evt_blk = pmbase;
|
||||
fadt->pm1b_evt_blk = 0x0;
|
||||
fadt->pm1a_cnt_blk = pmbase + 0x4;
|
||||
fadt->pm1b_cnt_blk = 0x0;
|
||||
fadt->pm2_cnt_blk = pmbase + 0x50;
|
||||
fadt->pm_tmr_blk = pmbase + 0x8;
|
||||
fadt->gpe0_blk = pmbase + 0x20;
|
||||
fadt->gpe1_blk = 0;
|
||||
fadt->pm1_evt_len = 4;
|
||||
fadt->pm1_cnt_len = 2;
|
||||
fadt->pm2_cnt_len = 1;
|
||||
fadt->pm_tmr_len = 4;
|
||||
fadt->gpe0_blk_len = 8;
|
||||
fadt->gpe1_blk_len = 0;
|
||||
fadt->gpe1_base = 0;
|
||||
fadt->cst_cnt = 0;
|
||||
fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
|
||||
fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
|
||||
fadt->flush_size = 0;
|
||||
fadt->flush_stride = 0;
|
||||
fadt->duty_offset = 1;
|
||||
fadt->duty_width = 0;
|
||||
fadt->day_alrm = 0x0d;
|
||||
fadt->mon_alrm = 0x00;
|
||||
fadt->century = 0x00;
|
||||
fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
|
||||
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
|
||||
ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
|
||||
ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_RESET_REGISTER |
|
||||
ACPI_FADT_PLATFORM_CLOCK;
|
||||
|
||||
fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->reset_reg.bit_width = 8;
|
||||
fadt->reset_reg.bit_offset = 0;
|
||||
fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
|
||||
fadt->reset_reg.addrl = IO_PORT_RESET;
|
||||
fadt->reset_reg.addrh = 0;
|
||||
fadt->reset_value = SYS_RST | RST_CPU;
|
||||
|
||||
fadt->x_firmware_ctl_l = (u32)facs;
|
||||
fadt->x_firmware_ctl_h = 0;
|
||||
fadt->x_dsdt_l = (u32)dsdt;
|
||||
fadt->x_dsdt_h = 0;
|
||||
|
||||
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
|
||||
fadt->x_pm1a_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
|
||||
fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
|
||||
fadt->x_pm1a_evt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm1b_evt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_evt_blk.access_size = 0;
|
||||
fadt->x_pm1b_evt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_evt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
|
||||
fadt->x_pm1a_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
|
||||
fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
|
||||
fadt->x_pm1a_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm1b_cnt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_cnt_blk.access_size = 0;
|
||||
fadt->x_pm1b_cnt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
|
||||
fadt->x_pm2_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
|
||||
fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
|
||||
fadt->x_pm2_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
|
||||
fadt->x_pm_tmr_blk.bit_offset = 0;
|
||||
fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
|
||||
fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
|
||||
fadt->x_pm_tmr_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
|
||||
fadt->x_gpe0_blk.bit_offset = 0;
|
||||
fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
|
||||
fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
|
||||
fadt->x_gpe0_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_gpe1_blk.bit_width = 0;
|
||||
fadt->x_gpe1_blk.bit_offset = 0;
|
||||
fadt->x_gpe1_blk.access_size = 0;
|
||||
fadt->x_gpe1_blk.addrl = 0x0;
|
||||
fadt->x_gpe1_blk.addrh = 0x0;
|
||||
|
||||
header->checksum = table_compute_checksum(fadt, header->length);
|
||||
}
|
||||
|
||||
static int acpi_create_madt_irq_overrides(u32 current)
|
||||
{
|
||||
struct acpi_madt_irqoverride *irqovr;
|
||||
u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
|
||||
int length = 0;
|
||||
|
||||
irqovr = (void *)current;
|
||||
length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
|
||||
|
||||
irqovr = (void *)(current + length);
|
||||
length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
u32 acpi_fill_madt(u32 current)
|
||||
{
|
||||
current += acpi_create_madt_lapics(current);
|
||||
|
||||
current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
|
||||
2, IO_APIC_ADDR, 0);
|
||||
|
||||
current += acpi_create_madt_irq_overrides(current);
|
||||
|
||||
return current;
|
||||
}
|
|
@ -53,14 +53,6 @@ int arch_misc_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int reserve_arch(void)
|
||||
{
|
||||
#ifdef CONFIG_ENABLE_MRC_CACHE
|
||||
return mrccache_reserve();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
|
|
|
@ -109,7 +109,8 @@ static void pch_enable_ioapic(void)
|
|||
{
|
||||
u32 reg32;
|
||||
|
||||
io_apic_set_id(0x02);
|
||||
/* Make sure this is a unique ID within system */
|
||||
io_apic_set_id(0x04);
|
||||
|
||||
/* affirm full set of redirection table entries ("write once") */
|
||||
reg32 = io_apic_read(0x01);
|
||||
|
|
|
@ -190,11 +190,6 @@ static int prepare_mrc_cache(struct pei_data *pei_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int reserve_arch(void)
|
||||
{
|
||||
return mrccache_reserve();
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
struct pei_data _pei_data __aligned(8);
|
||||
|
|
|
@ -39,15 +39,7 @@ int print_cpuinfo(void)
|
|||
return default_print_cpuinfo();
|
||||
}
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
if (gd->flags & GD_FLG_COLD_BOOT)
|
||||
timestamp_add_to_bootstage();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_final_cleanup(void)
|
||||
static void board_final_cleanup(void)
|
||||
{
|
||||
/*
|
||||
* Un-cache the ROM so the kernel has one
|
||||
|
@ -79,6 +71,16 @@ void board_final_cleanup(void)
|
|||
}
|
||||
}
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
if (gd->flags & GD_FLG_COLD_BOOT)
|
||||
timestamp_add_to_bootstage();
|
||||
|
||||
board_final_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -25,10 +25,12 @@
|
|||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/control_regs.h>
|
||||
#include <asm/coreboot_tables.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/mp.h>
|
||||
#include <asm/mrccache.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/post.h>
|
||||
|
@ -661,10 +663,20 @@ void show_boot_progress(int val)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_SYS_COREBOOT
|
||||
/*
|
||||
* Implement a weak default function for boards that optionally
|
||||
* need to clean up the system before jumping to the kernel.
|
||||
*/
|
||||
__weak void board_final_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
write_tables();
|
||||
|
||||
board_final_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -741,3 +753,18 @@ int cpu_init_r(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_EFI_STUB
|
||||
int reserve_arch(void)
|
||||
{
|
||||
#ifdef CONFIG_ENABLE_MRC_CACHE
|
||||
mrccache_reserve();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SEABIOS
|
||||
high_table_reserve();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
#include <dm.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/control_regs.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/interrupt.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/i8259.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -266,6 +266,8 @@ int interrupt_init(void)
|
|||
i8259_init();
|
||||
#endif
|
||||
|
||||
lapic_setup();
|
||||
|
||||
/* Initialize core interrupt and exception functionality of CPU */
|
||||
cpu_init_interrupts();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/pci.h>
|
||||
#include <asm/pirq_routing.h>
|
||||
#include <asm/tables.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -121,6 +122,11 @@ static int create_pirq_routing_table(struct udevice *dev)
|
|||
priv->irq_mask = fdtdec_get_int(blob, node,
|
||||
"intel,pirq-mask", PIRQ_BITMAP);
|
||||
|
||||
if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
|
||||
/* Reserve IRQ9 for SCI */
|
||||
priv->irq_mask &= ~(1 << 9);
|
||||
}
|
||||
|
||||
if (priv->config == PIRQ_VIA_IBASE) {
|
||||
int ibase_off;
|
||||
|
||||
|
@ -142,6 +148,9 @@ static int create_pirq_routing_table(struct udevice *dev)
|
|||
priv->ibase &= ~0xf;
|
||||
}
|
||||
|
||||
priv->actl_8bit = fdtdec_get_bool(blob, node, "intel,actl-8bit");
|
||||
priv->actl_addr = fdtdec_get_int(blob, node, "intel,actl-addr", 0);
|
||||
|
||||
cell = fdt_getprop(blob, node, "intel,pirq-routing", &len);
|
||||
if (!cell || len % sizeof(struct pirq_routing))
|
||||
return -EINVAL;
|
||||
|
@ -206,11 +215,30 @@ static int create_pirq_routing_table(struct udevice *dev)
|
|||
|
||||
rt->size = irq_entries * sizeof(struct irq_info) + 32;
|
||||
|
||||
/* Fix up the table checksum */
|
||||
rt->checksum = table_compute_checksum(rt, rt->size);
|
||||
|
||||
pirq_routing_table = rt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void irq_enable_sci(struct udevice *dev)
|
||||
{
|
||||
struct irq_router *priv = dev_get_priv(dev);
|
||||
|
||||
if (priv->actl_8bit) {
|
||||
/* Bit7 must be turned on to enable ACPI */
|
||||
dm_pci_write_config8(dev->parent, priv->actl_addr, 0x80);
|
||||
} else {
|
||||
/* Write 0 to enable SCI on IRQ9 */
|
||||
if (priv->config == PIRQ_VIA_PCI)
|
||||
dm_pci_write_config32(dev->parent, priv->actl_addr, 0);
|
||||
else
|
||||
writel(0, priv->ibase + priv->actl_addr);
|
||||
}
|
||||
}
|
||||
|
||||
int irq_router_common_init(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
@ -224,6 +252,9 @@ int irq_router_common_init(struct udevice *dev)
|
|||
pirq_route_irqs(dev, pirq_routing_table->slots,
|
||||
get_irq_slot_count(pirq_routing_table));
|
||||
|
||||
if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE))
|
||||
irq_enable_sci(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <fdtdec.h>
|
||||
#include <rtc.h>
|
||||
#include <pci.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/interrupt.h>
|
||||
#include <asm/io.h>
|
||||
|
|
|
@ -12,10 +12,8 @@
|
|||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu_x86.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/mtrr.h>
|
||||
|
@ -419,7 +417,6 @@ static int model_206ax_init(struct udevice *dev)
|
|||
|
||||
/* Enable the local cpu apics */
|
||||
enable_lapic_tpr();
|
||||
lapic_setup();
|
||||
|
||||
/* Enable virtualization if enabled in CMOS */
|
||||
enable_vmx();
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/io.h>
|
||||
|
|
|
@ -201,11 +201,6 @@ static int recovery_mode_enabled(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
int reserve_arch(void)
|
||||
{
|
||||
return mrccache_reserve();
|
||||
}
|
||||
|
||||
static int copy_spd(struct udevice *dev, struct pei_data *peid)
|
||||
{
|
||||
const void *data;
|
||||
|
|
|
@ -65,23 +65,27 @@ void lapic_write(unsigned long reg, unsigned long v)
|
|||
|
||||
void enable_lapic(void)
|
||||
{
|
||||
msr_t msr;
|
||||
if (!IS_ENABLED(CONFIG_INTEL_QUARK)) {
|
||||
msr_t msr;
|
||||
|
||||
msr = msr_read(MSR_IA32_APICBASE);
|
||||
msr.hi &= 0xffffff00;
|
||||
msr.lo |= MSR_IA32_APICBASE_ENABLE;
|
||||
msr.lo &= ~MSR_IA32_APICBASE_BASE;
|
||||
msr.lo |= LAPIC_DEFAULT_BASE;
|
||||
msr_write(MSR_IA32_APICBASE, msr);
|
||||
msr = msr_read(MSR_IA32_APICBASE);
|
||||
msr.hi &= 0xffffff00;
|
||||
msr.lo |= MSR_IA32_APICBASE_ENABLE;
|
||||
msr.lo &= ~MSR_IA32_APICBASE_BASE;
|
||||
msr.lo |= LAPIC_DEFAULT_BASE;
|
||||
msr_write(MSR_IA32_APICBASE, msr);
|
||||
}
|
||||
}
|
||||
|
||||
void disable_lapic(void)
|
||||
{
|
||||
msr_t msr;
|
||||
if (!IS_ENABLED(CONFIG_INTEL_QUARK)) {
|
||||
msr_t msr;
|
||||
|
||||
msr = msr_read(MSR_IA32_APICBASE);
|
||||
msr.lo &= ~MSR_IA32_APICBASE_ENABLE;
|
||||
msr_write(MSR_IA32_APICBASE, msr);
|
||||
msr = msr_read(MSR_IA32_APICBASE);
|
||||
msr.lo &= ~MSR_IA32_APICBASE_ENABLE;
|
||||
msr_write(MSR_IA32_APICBASE, msr);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long lapicid(void)
|
||||
|
@ -120,7 +124,6 @@ int lapic_remote_read(int apicid, int reg, unsigned long *pvalue)
|
|||
|
||||
void lapic_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/* Only Pentium Pro and later have those MSR stuff */
|
||||
debug("Setting up local apic: ");
|
||||
|
||||
|
@ -150,11 +153,7 @@ void lapic_setup(void)
|
|||
LAPIC_DELIVERY_MODE_NMI));
|
||||
|
||||
debug("apic_id: 0x%02lx, ", lapicid());
|
||||
#else /* !CONFIG_SMP */
|
||||
/* Only Pentium Pro and later have those MSR stuff */
|
||||
debug("Disabling local apic: ");
|
||||
disable_lapic();
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
debug("done.\n");
|
||||
post_code(POST_LAPIC);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <qfw.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/interrupt.h>
|
||||
|
@ -21,7 +22,6 @@
|
|||
#include <asm/mtrr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sipi.h>
|
||||
#include <asm/fw_cfg.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/lists.h>
|
||||
|
@ -408,8 +408,6 @@ static int init_bsp(struct udevice **devp)
|
|||
cpu_get_name(processor_name);
|
||||
debug("CPU: %s\n", processor_name);
|
||||
|
||||
lapic_setup();
|
||||
|
||||
apic_id = lapicid();
|
||||
ret = find_cpu_by_apic_id(apic_id, devp);
|
||||
if (ret) {
|
||||
|
@ -420,7 +418,7 @@ static int init_bsp(struct udevice **devp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QEMU
|
||||
#ifdef CONFIG_QFW
|
||||
static int qemu_cpu_fixup(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -496,7 +494,7 @@ int mp_init(struct mp_params *p)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_QEMU
|
||||
#ifdef CONFIG_QFW
|
||||
ret = qemu_cpu_fixup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
ifndef CONFIG_EFI_STUB
|
||||
obj-y += car.o dram.o
|
||||
endif
|
||||
obj-y += cpu.o fw_cfg.o qemu.o
|
||||
obj-y += qemu.o
|
||||
obj-$(CONFIG_QFW) += cpu.o e820.o
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#include <cpu.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <qfw.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/fw_cfg.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
|
43
arch/x86/cpu/qemu/e820.c
Normal file
43
arch/x86/cpu/qemu/e820.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
||||
{
|
||||
entries[0].addr = 0;
|
||||
entries[0].size = ISA_START_ADDRESS;
|
||||
entries[0].type = E820_RAM;
|
||||
|
||||
entries[1].addr = ISA_START_ADDRESS;
|
||||
entries[1].size = ISA_END_ADDRESS - ISA_START_ADDRESS;
|
||||
entries[1].type = E820_RESERVED;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* 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[4].addr = gd->relocaddr;
|
||||
entries[4].size = gd->ram_size - gd->relocaddr;
|
||||
entries[4].type = E820_RESERVED;
|
||||
|
||||
entries[5].addr = CONFIG_PCIE_ECAM_BASE;
|
||||
entries[5].size = CONFIG_PCIE_ECAM_SIZE;
|
||||
entries[5].type = E820_RESERVED;
|
||||
|
||||
return 6;
|
||||
}
|
|
@ -6,15 +6,59 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
#include <qfw.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/device.h>
|
||||
#include <asm/arch/qemu.h>
|
||||
#include <asm/fw_cfg.h>
|
||||
|
||||
static bool i440fx;
|
||||
|
||||
#ifdef CONFIG_QFW
|
||||
|
||||
/* on x86, the qfw registers are all IO ports */
|
||||
#define FW_CONTROL_PORT 0x510
|
||||
#define FW_DATA_PORT 0x511
|
||||
#define FW_DMA_PORT_LOW 0x514
|
||||
#define FW_DMA_PORT_HIGH 0x518
|
||||
|
||||
static void qemu_x86_fwcfg_read_entry_pio(uint16_t entry,
|
||||
uint32_t size, void *address)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint8_t *data = address;
|
||||
|
||||
/*
|
||||
* writting FW_CFG_INVALID will cause read operation to resume at
|
||||
* last offset, otherwise read will start at offset 0
|
||||
*
|
||||
* Note: on platform where the control register is IO port, the
|
||||
* endianness is little endian.
|
||||
*/
|
||||
if (entry != FW_CFG_INVALID)
|
||||
outw(cpu_to_le16(entry), FW_CONTROL_PORT);
|
||||
|
||||
/* the endianness of data register is string-preserving */
|
||||
while (size--)
|
||||
data[i++] = inb(FW_DATA_PORT);
|
||||
}
|
||||
|
||||
static void qemu_x86_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma)
|
||||
{
|
||||
/* the DMA address register is big endian */
|
||||
outl(cpu_to_be32((uint32_t)dma), FW_DMA_PORT_HIGH);
|
||||
|
||||
while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR)
|
||||
__asm__ __volatile__ ("pause");
|
||||
}
|
||||
|
||||
static struct fw_cfg_arch_ops fwcfg_x86_ops = {
|
||||
.arch_read_pio = qemu_x86_fwcfg_read_entry_pio,
|
||||
.arch_read_dma = qemu_x86_fwcfg_read_entry_dma
|
||||
};
|
||||
#endif
|
||||
|
||||
static void enable_pm_piix(void)
|
||||
{
|
||||
u8 en;
|
||||
|
@ -88,7 +132,9 @@ static void qemu_chipset_init(void)
|
|||
enable_pm_ich9();
|
||||
}
|
||||
|
||||
qemu_fwcfg_init();
|
||||
#ifdef CONFIG_QFW
|
||||
qemu_fwcfg_init(&fwcfg_x86_ops);
|
||||
#endif
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <common.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ioapic.h>
|
||||
#include <asm/mrccache.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/pci.h>
|
||||
|
@ -338,6 +339,9 @@ int arch_misc_init(void)
|
|||
mrccache_save();
|
||||
#endif
|
||||
|
||||
/* Assign a unique I/O APIC ID */
|
||||
io_apic_set_id(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -360,12 +364,3 @@ void board_final_cleanup(void)
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
int reserve_arch(void)
|
||||
{
|
||||
#ifdef CONFIG_ENABLE_MRC_CACHE
|
||||
return mrccache_reserve();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "ibase";
|
||||
intel,ibase-offset = <0x50>;
|
||||
intel,actl-addr = <0>;
|
||||
intel,pirq-link = <8 8>;
|
||||
intel,pirq-mask = <0xdee0>;
|
||||
intel,pirq-routing = <
|
||||
|
@ -249,10 +250,10 @@
|
|||
#include "microcode/m0230671117.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m0130673322.dtsi"
|
||||
#include "microcode/m0130673325.dtsi"
|
||||
};
|
||||
update@2 {
|
||||
#include "microcode/m0130679901.dtsi"
|
||||
#include "microcode/m0130679907.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "ibase";
|
||||
intel,ibase-offset = <0x50>;
|
||||
intel,actl-addr = <0>;
|
||||
intel,pirq-link = <8 8>;
|
||||
intel,pirq-mask = <0xdee0>;
|
||||
intel,pirq-routing = <
|
||||
|
@ -269,10 +270,10 @@
|
|||
|
||||
microcode {
|
||||
update@0 {
|
||||
#include "microcode/m0130673322.dtsi"
|
||||
#include "microcode/m0130673325.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m0130679901.dtsi"
|
||||
#include "microcode/m0130679907.dtsi"
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -154,6 +154,7 @@
|
|||
irq-router {
|
||||
compatible = "intel,queensbay-irq-router";
|
||||
intel,pirq-config = "pci";
|
||||
intel,actl-addr = <0x58>;
|
||||
intel,pirq-link = <0x60 8>;
|
||||
intel,pirq-mask = <0xcee0>;
|
||||
intel,pirq-routing = <
|
||||
|
|
|
@ -29,6 +29,18 @@
|
|||
stdout-path = &pciuart0;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "cpu-x86";
|
||||
reg = <0>;
|
||||
intel,apic-id = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
tsc-timer {
|
||||
clock-frequency = <400000000>;
|
||||
};
|
||||
|
@ -88,6 +100,7 @@
|
|||
irq-router {
|
||||
compatible = "intel,quark-irq-router";
|
||||
intel,pirq-config = "pci";
|
||||
intel,actl-addr = <0x58>;
|
||||
intel,pirq-link = <0x60 8>;
|
||||
intel,pirq-mask = <0xdef8>;
|
||||
intel,pirq-routing = <
|
||||
|
|
File diff suppressed because it is too large
Load diff
3284
arch/x86/dts/microcode/m0130673325.dtsi
Normal file
3284
arch/x86/dts/microcode/m0130673325.dtsi
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
3284
arch/x86/dts/microcode/m0130679907.dtsi
Normal file
3284
arch/x86/dts/microcode/m0130679907.dtsi
Normal file
File diff suppressed because it is too large
Load diff
|
@ -117,6 +117,7 @@
|
|||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "ibase";
|
||||
intel,ibase-offset = <0x50>;
|
||||
intel,actl-addr = <0>;
|
||||
intel,pirq-link = <8 8>;
|
||||
intel,pirq-mask = <0xdee0>;
|
||||
intel,pirq-routing = <
|
||||
|
@ -297,10 +298,10 @@
|
|||
|
||||
microcode {
|
||||
update@0 {
|
||||
#include "microcode/m0130673322.dtsi"
|
||||
#include "microcode/m0130673325.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m0130679901.dtsi"
|
||||
#include "microcode/m0130679907.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
irq-router {
|
||||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "pci";
|
||||
intel,actl-8bit;
|
||||
intel,actl-addr = <0x44>;
|
||||
intel,pirq-link = <0x60 8>;
|
||||
intel,pirq-mask = <0x0e40>;
|
||||
intel,pirq-routing = <
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* From coreboot
|
||||
*
|
||||
* Copyright (C) 2004 SUSE LINUX AG
|
||||
* Copyright (C) 2004 Nick Barker
|
||||
* Copyright (C) 2008-2009 coresystems GmbH
|
||||
* (Written by Stefan Reinauer <stepan@coresystems.de>)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ACPI_H
|
||||
#define __ASM_ACPI_H
|
||||
|
||||
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
|
||||
#define ACPI_TABLE_CREATOR "U-BootAC" /* Must be exactly 8 bytes long! */
|
||||
#define OEM_ID "U-Boot" /* Must be exactly 6 bytes long! */
|
||||
#define ASLC "U-Bo" /* Must be exactly 4 bytes long! */
|
||||
|
||||
/* 0 = S0, 1 = S1 ...*/
|
||||
int acpi_get_slp_type(void);
|
||||
void apci_set_slp_type(int type);
|
||||
|
||||
#endif
|
136
arch/x86/include/asm/acpi/debug.asl
Normal file
136
arch/x86/include/asm/acpi/debug.asl
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/arch/x86/acpi/debug.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* POST register region */
|
||||
OperationRegion(X80, SystemIO, 0x80, 1)
|
||||
Field(X80, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
P80, 8
|
||||
}
|
||||
|
||||
/* Legacy serial port register region */
|
||||
OperationRegion(CREG, SystemIO, 0x3F8, 8)
|
||||
Field(CREG, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
CDAT, 8,
|
||||
CDLM, 8,
|
||||
, 8,
|
||||
CLCR, 8,
|
||||
CMCR, 8,
|
||||
CLSR, 8
|
||||
}
|
||||
|
||||
/* DINI - Initialize the serial port to 115200 8-N-1 */
|
||||
Method(DINI)
|
||||
{
|
||||
Store(0x83, CLCR)
|
||||
Store(0x01, CDAT) /* 115200 baud (low) */
|
||||
Store(0x00, CDLM) /* 115200 baud (high) */
|
||||
Store(0x03, CLCR) /* word=8 stop=1 parity=none */
|
||||
Store(0x03, CMCR) /* DTR=1 RTS=1 out1/2=Off loop=Off */
|
||||
Store(0x00, CDLM) /* turn off interrupts */
|
||||
}
|
||||
|
||||
/* THRE - Wait for serial port transmitter holding register to go empty */
|
||||
Method(THRE)
|
||||
{
|
||||
And(CLSR, 0x20, Local0)
|
||||
While (LEqual(Local0, Zero)) {
|
||||
And(CLSR, 0x20, Local0)
|
||||
}
|
||||
}
|
||||
|
||||
/* OUTX - Send a single raw character */
|
||||
Method(OUTX, 1)
|
||||
{
|
||||
THRE()
|
||||
Store(Arg0, CDAT)
|
||||
}
|
||||
|
||||
/* OUTC - Send a single character, expanding LF into CR/LF */
|
||||
Method(OUTC, 1)
|
||||
{
|
||||
If (LEqual(Arg0, 0x0a)) {
|
||||
OUTX(0x0d)
|
||||
}
|
||||
OUTX(Arg0)
|
||||
}
|
||||
|
||||
/* DBGN - Send a single hex nibble */
|
||||
Method(DBGN, 1)
|
||||
{
|
||||
And(Arg0, 0x0f, Local0)
|
||||
If (LLess(Local0, 10)) {
|
||||
Add(Local0, 0x30, Local0)
|
||||
} Else {
|
||||
Add(Local0, 0x37, Local0)
|
||||
}
|
||||
OUTC(Local0)
|
||||
}
|
||||
|
||||
/* DBGB - Send a hex byte */
|
||||
Method(DBGB, 1)
|
||||
{
|
||||
ShiftRight(Arg0, 4, Local0)
|
||||
DBGN(Local0)
|
||||
DBGN(Arg0)
|
||||
}
|
||||
|
||||
/* DBGW - Send a hex word */
|
||||
Method(DBGW, 1)
|
||||
{
|
||||
ShiftRight(Arg0, 8, Local0)
|
||||
DBGB(Local0)
|
||||
DBGB(Arg0)
|
||||
}
|
||||
|
||||
/* DBGD - Send a hex dword */
|
||||
Method(DBGD, 1)
|
||||
{
|
||||
ShiftRight(Arg0, 16, Local0)
|
||||
DBGW(Local0)
|
||||
DBGW(Arg0)
|
||||
}
|
||||
|
||||
/* Get a char from a string */
|
||||
Method(GETC, 2)
|
||||
{
|
||||
CreateByteField(Arg0, Arg1, DBGC)
|
||||
Return (DBGC)
|
||||
}
|
||||
|
||||
/* DBGO - Send either a string or an integer */
|
||||
Method(DBGO, 1, Serialized)
|
||||
{
|
||||
If (LEqual(ObjectType(Arg0), 1)) {
|
||||
If (LGreater(Arg0, 0xffff)) {
|
||||
DBGD(Arg0)
|
||||
} Else {
|
||||
If (LGreater(Arg0, 0xff)) {
|
||||
DBGW(Arg0)
|
||||
} Else {
|
||||
DBGB(Arg0)
|
||||
}
|
||||
}
|
||||
} Else {
|
||||
Name(BDBG, Buffer(80) {})
|
||||
Store(Arg0, BDBG)
|
||||
Store(0, Local1)
|
||||
While (One) {
|
||||
Store(GETC(BDBG, Local1), Local0)
|
||||
If (LEqual(Local0, 0)) {
|
||||
Return (Zero)
|
||||
}
|
||||
OUTC(Local0)
|
||||
Increment(Local1)
|
||||
}
|
||||
}
|
||||
|
||||
Return (Zero)
|
||||
}
|
113
arch/x86/include/asm/acpi/globutil.asl
Normal file
113
arch/x86/include/asm/acpi/globutil.asl
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/arch/x86/acpi/globutil.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
Method(MIN, 2)
|
||||
{
|
||||
If (LLess(Arg0, Arg1)) {
|
||||
Return (Arg0)
|
||||
} Else {
|
||||
Return (Arg1)
|
||||
}
|
||||
}
|
||||
|
||||
Method(SLEN, 1)
|
||||
{
|
||||
Store(Arg0, Local0)
|
||||
Return (Sizeof(Local0))
|
||||
}
|
||||
|
||||
Method(S2BF, 1, Serialized)
|
||||
{
|
||||
Add(SLEN(Arg0), One, Local0)
|
||||
Name(BUFF, Buffer(Local0) {})
|
||||
Store(Arg0, BUFF)
|
||||
Return (BUFF)
|
||||
}
|
||||
|
||||
/*
|
||||
* SCMP - Strong string compare
|
||||
*
|
||||
* Checks both length and content
|
||||
*/
|
||||
Method(SCMP, 2)
|
||||
{
|
||||
Store(S2BF(Arg0), Local0)
|
||||
Store(S2BF(Arg1), Local1)
|
||||
Store(Zero, Local4)
|
||||
Store(SLEN(Arg0), Local5)
|
||||
Store(SLEN(Arg1), Local6)
|
||||
Store(MIN(Local5, Local6), Local7)
|
||||
|
||||
While (LLess(Local4, Local7)) {
|
||||
Store(Derefof(Index(Local0, Local4)), Local2)
|
||||
Store(Derefof(Index(Local1, Local4)), Local3)
|
||||
If (LGreater(Local2, Local3)) {
|
||||
Return (One)
|
||||
} Else {
|
||||
If (LLess(Local2, Local3)) {
|
||||
Return (Ones)
|
||||
}
|
||||
}
|
||||
Increment(Local4)
|
||||
}
|
||||
|
||||
If (LLess(Local4, Local5)) {
|
||||
Return (One)
|
||||
} Else {
|
||||
If (LLess(Local4, Local6)) {
|
||||
Return (Ones)
|
||||
} Else {
|
||||
Return (Zero)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* WCMP - Weak string compare
|
||||
*
|
||||
* Checks to find Arg1 at beginning of Arg0.
|
||||
* Fails if length(Arg0) < length(Arg1).
|
||||
* Returns 0 on fail, 1 on pass.
|
||||
*/
|
||||
Method(WCMP, 2)
|
||||
{
|
||||
Store(S2BF(Arg0), Local0)
|
||||
Store(S2BF(Arg1), Local1)
|
||||
If (LLess(SLEN(Arg0), SLEN(Arg1))) {
|
||||
Return (Zero)
|
||||
}
|
||||
Store(Zero, Local2)
|
||||
Store(SLEN(Arg1), Local3)
|
||||
|
||||
While (LLess(Local2, Local3)) {
|
||||
If (LNotEqual(Derefof(Index(Local0, Local2)),
|
||||
Derefof(Index(Local1, Local2)))) {
|
||||
Return (Zero)
|
||||
}
|
||||
Increment(Local2)
|
||||
}
|
||||
|
||||
Return (One)
|
||||
}
|
||||
|
||||
/*
|
||||
* I2BM - Returns Bit Map
|
||||
*
|
||||
* Arg0 = IRQ Number (0-15)
|
||||
*/
|
||||
Method(I2BM, 1)
|
||||
{
|
||||
Store(0, Local0)
|
||||
If (LNotEqual(Arg0, 0)) {
|
||||
Store(1, Local1)
|
||||
ShiftLeft(Local1, Arg0, Local0)
|
||||
}
|
||||
|
||||
Return (Local0)
|
||||
}
|
82
arch/x86/include/asm/acpi/statdef.asl
Normal file
82
arch/x86/include/asm/acpi/statdef.asl
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/arch/x86/acpi/statdef.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* Status and notification definitions */
|
||||
|
||||
#define STA_MISSING 0x00
|
||||
#define STA_PRESENT 0x01
|
||||
#define STA_ENABLED 0x03
|
||||
#define STA_DISABLED 0x09
|
||||
#define STA_INVISIBLE 0x0b
|
||||
#define STA_UNAVAILABLE 0x0d
|
||||
#define STA_VISIBLE 0x0f
|
||||
|
||||
/* SMBus status codes */
|
||||
#define SMB_OK 0x00
|
||||
#define SMB_UNKNOWN_FAIL 0x07
|
||||
#define SMB_DEV_ADDR_NAK 0x10
|
||||
#define SMB_DEVICE_ERROR 0x11
|
||||
#define SMB_DEV_CMD_DENIED 0x12
|
||||
#define SMB_UNKNOWN_ERR 0x13
|
||||
#define SMB_DEV_ACC_DENIED 0x17
|
||||
#define SMB_TIMEOUT 0x18
|
||||
#define SMB_HST_UNSUPP_PROTOCOL 0x19
|
||||
#define SMB_BUSY 0x1a
|
||||
#define SMB_PKT_CHK_ERROR 0x1f
|
||||
|
||||
/* Device Object Notification Values */
|
||||
#define NOTIFY_BUS_CHECK 0x00
|
||||
#define NOTIFY_DEVICE_CHECK 0x01
|
||||
#define NOTIFY_DEVICE_WAKE 0x02
|
||||
#define NOTIFY_EJECT_REQUEST 0x03
|
||||
#define NOTIFY_DEVICE_CHECK_JR 0x04
|
||||
#define NOTIFY_FREQUENCY_ERROR 0x05
|
||||
#define NOTIFY_BUS_MODE 0x06
|
||||
#define NOTIFY_POWER_FAULT 0x07
|
||||
#define NOTIFY_CAPABILITIES 0x08
|
||||
#define NOTIFY_PLD_CHECK 0x09
|
||||
#define NOTIFY_SLIT_UPDATE 0x0b
|
||||
#define NOTIFY_SRA_UPDATE 0x0d
|
||||
|
||||
/* Battery Device Notification Values */
|
||||
#define NOTIFY_BAT_STATUSCHG 0x80
|
||||
#define NOTIFY_BAT_INFOCHG 0x81
|
||||
#define NOTIFY_BAT_MAINTDATA 0x82
|
||||
|
||||
/* Power Source Object Notification Values */
|
||||
#define NOTIFY_PWR_STATUSCHG 0x80
|
||||
#define NOTIFY_PWR_INFOCHG 0x81
|
||||
|
||||
/* Thermal Zone Object Notification Values */
|
||||
#define NOTIFY_TZ_STATUSCHG 0x80
|
||||
#define NOTIFY_TZ_TRIPPTCHG 0x81
|
||||
#define NOTIFY_TZ_DEVLISTCHG 0x82
|
||||
#define NOTIFY_TZ_RELTBLCHG 0x83
|
||||
|
||||
/* Power Button Notification Values */
|
||||
#define NOTIFY_POWER_BUTTON 0x80
|
||||
|
||||
/* Sleep Button Notification Values */
|
||||
#define NOTIFY_SLEEP_BUTTON 0x80
|
||||
|
||||
/* Lid Notification Values */
|
||||
#define NOTIFY_LID_STATUSCHG 0x80
|
||||
|
||||
/* Processor Device Notification Values */
|
||||
#define NOTIFY_CPU_PPCCHG 0x80
|
||||
#define NOTIFY_CPU_CSTATECHG 0x81
|
||||
#define NOTIFY_CPU_THROTLCHG 0x82
|
||||
|
||||
/* User Presence Device Notification Values */
|
||||
#define NOTIFY_USR_PRESNCECHG 0x80
|
||||
|
||||
/* Ambient Light Sensor Notification Values */
|
||||
#define NOTIFY_ALS_ILLUMCHG 0x80
|
||||
#define NOTIFY_ALS_COLORTMPCHG 0x81
|
||||
#define NOTIFY_ALS_RESPCHG 0x82
|
|
@ -2,83 +2,19 @@
|
|||
* Based on acpi.c from coreboot
|
||||
*
|
||||
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/post.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
|
||||
#define ACPI_TABLE_CREATOR "UBOOT " /* Must be 8 bytes long! */
|
||||
#define OEM_ID "UBOOT " /* Must be 6 bytes long! */
|
||||
#define ASLC "INTL" /* Must be 4 bytes long! */
|
||||
|
||||
#define OEM_REVISION 42
|
||||
#define ASL_COMPILER_REVISION 42
|
||||
|
||||
/* IO ports to generate SMIs */
|
||||
#define APM_CNT 0xb2
|
||||
#define APM_CNT_CST_CONTROL 0x85
|
||||
#define APM_CNT_PST_CONTROL 0x80
|
||||
#define APM_CNT_ACPI_DISABLE 0x1e
|
||||
#define APM_CNT_ACPI_ENABLE 0xe1
|
||||
#define APM_CNT_MBI_UPDATE 0xeb
|
||||
#define APM_CNT_GNVS_UPDATE 0xea
|
||||
#define APM_CNT_FINALIZE 0xcb
|
||||
#define APM_CNT_LEGACY 0xcc
|
||||
#define APM_ST 0xb3
|
||||
|
||||
/* Multiple Processor Interrupts */
|
||||
#define MP_IRQ_POLARITY_DEFAULT 0x0
|
||||
#define MP_IRQ_POLARITY_HIGH 0x1
|
||||
#define MP_IRQ_POLARITY_LOW 0x3
|
||||
#define MP_IRQ_POLARITY_MASK 0x3
|
||||
#define MP_IRQ_TRIGGER_DEFAULT 0x0
|
||||
#define MP_IRQ_TRIGGER_EDGE 0x4
|
||||
#define MP_IRQ_TRIGGER_LEVEL 0xc
|
||||
#define MP_IRQ_TRIGGER_MASK 0xc
|
||||
|
||||
/*
|
||||
* Interrupt assigned for SCI in order to
|
||||
* create the ACPI MADT IRQ override entry
|
||||
*/
|
||||
#define ACTL 0x00
|
||||
#define SCIS_MASK 0x07
|
||||
#define SCIS_IRQ9 0x00
|
||||
#define SCIS_IRQ10 0x01
|
||||
#define SCIS_IRQ11 0x02
|
||||
#define SCIS_IRQ20 0x04
|
||||
#define SCIS_IRQ21 0x05
|
||||
#define SCIS_IRQ22 0x06
|
||||
#define SCIS_IRQ23 0x07
|
||||
|
||||
#define ACPI_REV_ACPI_1_0 1
|
||||
#define ACPI_REV_ACPI_2_0 1
|
||||
#define ACPI_REV_ACPI_3_0 2
|
||||
#define ACPI_REV_ACPI_4_0 3
|
||||
#define ACPI_REV_ACPI_5_0 5
|
||||
#define RSDP_SIG "RSD PTR " /* RSDP pointer signature */
|
||||
#define OEM_ID "U-BOOT" /* U-Boot */
|
||||
#define OEM_TABLE_ID "U-BOOTBL" /* U-Boot Table */
|
||||
#define ASLC_ID "INTL" /* Intel ASL Compiler */
|
||||
|
||||
#define ACPI_RSDP_REV_ACPI_1_0 0
|
||||
#define ACPI_RSDP_REV_ACPI_2_0 2
|
||||
|
||||
typedef struct acpi_gen_regaddr {
|
||||
u8 space_id; /* Address space ID */
|
||||
u8 bit_width; /* Register size in bits */
|
||||
u8 bit_offset; /* Register bit offset */
|
||||
union {
|
||||
/* Reserved in ACPI 2.0 - 2.0b */
|
||||
u8 resv;
|
||||
/* Access size in ACPI 2.0c/3.0/4.0/5.0 */
|
||||
u8 access_size;
|
||||
};
|
||||
u32 addrl; /* Register address, low 32 bits */
|
||||
u32 addrh; /* Register address, high 32 bits */
|
||||
} acpi_addr_t;
|
||||
|
||||
|
||||
/*
|
||||
* RSDP (Root System Description Pointer)
|
||||
* Note: ACPI 1.0 didn't have length, xsdt_address, and ext_checksum
|
||||
|
@ -87,7 +23,7 @@ struct acpi_rsdp {
|
|||
char signature[8]; /* RSDP signature */
|
||||
u8 checksum; /* Checksum of the first 20 bytes */
|
||||
char oem_id[6]; /* OEM ID */
|
||||
u8 revision; /* 0 for ACPI 1.0, 2 for ACPI 2.0/3.0/4.0 */
|
||||
u8 revision; /* 0 for ACPI 1.0, others 2 */
|
||||
u32 rsdt_address; /* Physical address of RSDT (32 bits) */
|
||||
u32 length; /* Total RSDP length (incl. extended part) */
|
||||
u64 xsdt_address; /* Physical address of XSDT (64 bits) */
|
||||
|
@ -95,35 +31,8 @@ struct acpi_rsdp {
|
|||
u8 reserved[3];
|
||||
};
|
||||
|
||||
enum acpi_address_space_type {
|
||||
ACPI_ADDRESS_SPACE_MEMORY = 0, /* System memory */
|
||||
ACPI_ADDRESS_SPACE_IO, /* System I/O */
|
||||
ACPI_ADDRESS_SPACE_PCI, /* PCI config space */
|
||||
ACPI_ADDRESS_SPACE_EC, /* Embedded controller */
|
||||
ACPI_ADDRESS_SPACE_SMBUS, /* SMBus */
|
||||
ACPI_ADDRESS_SPACE_PCC = 0x0a, /* Platform Comm. Channel */
|
||||
ACPI_ADDRESS_SPACE_FIXED = 0x7f /* Functional fixed hardware */
|
||||
};
|
||||
|
||||
/* functional fixed hardware */
|
||||
#define ACPI_FFIXEDHW_VENDOR_INTEL 1 /* Intel */
|
||||
#define ACPI_FFIXEDHW_CLASS_HLT 0 /* C1 Halt */
|
||||
#define ACPI_FFIXEDHW_CLASS_IO_HLT 1 /* C1 I/O then Halt */
|
||||
#define ACPI_FFIXEDHW_CLASS_MWAIT 2 /* MWAIT Native C-state */
|
||||
#define ACPI_FFIXEDHW_FLAG_HW_COORD 1 /* Hardware Coordination bit */
|
||||
#define ACPI_FFIXEDHW_FLAG_BM_STS 2 /* BM_STS avoidance bit */
|
||||
|
||||
/* Access size definitions for Generic address structure */
|
||||
enum acpi_address_space_size {
|
||||
ACPI_ACCESS_SIZE_UNDEFINED = 0, /* Undefined (legacy reasons) */
|
||||
ACPI_ACCESS_SIZE_BYTE_ACCESS = 1,
|
||||
ACPI_ACCESS_SIZE_WORD_ACCESS = 2,
|
||||
ACPI_ACCESS_SIZE_DWORD_ACCESS = 3,
|
||||
ACPI_ACCESS_SIZE_QWORD_ACCESS = 4
|
||||
};
|
||||
|
||||
/* Generic ACPI header, provided by (almost) all tables */
|
||||
typedef struct acpi_table_header {
|
||||
struct 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!) */
|
||||
|
@ -131,12 +40,12 @@ typedef struct acpi_table_header {
|
|||
char oem_id[6]; /* OEM identification */
|
||||
char oem_table_id[8]; /* OEM table identification */
|
||||
u32 oem_revision; /* OEM revision number */
|
||||
char asl_compiler_id[4]; /* ASL compiler vendor ID */
|
||||
u32 asl_compiler_revision; /* ASL compiler revision number */
|
||||
} acpi_header_t;
|
||||
char aslc_id[4]; /* ASL compiler vendor ID */
|
||||
u32 aslc_revision; /* ASL compiler revision number */
|
||||
};
|
||||
|
||||
/* A maximum number of 32 ACPI tables ought to be enough for now */
|
||||
#define MAX_ACPI_TABLES 32
|
||||
#define MAX_ACPI_TABLES 32
|
||||
|
||||
/* RSDT (Root System Description Table) */
|
||||
struct acpi_rsdt {
|
||||
|
@ -150,103 +59,80 @@ struct acpi_xsdt {
|
|||
u64 entry[MAX_ACPI_TABLES];
|
||||
};
|
||||
|
||||
/* MCFG (PCI Express MMIO config space BAR description table) */
|
||||
struct acpi_mcfg {
|
||||
struct acpi_table_header header;
|
||||
u8 reserved[8];
|
||||
/* FADT Preferred Power Management Profile */
|
||||
enum acpi_pm_profile {
|
||||
ACPI_PM_UNSPECIFIED = 0,
|
||||
ACPI_PM_DESKTOP,
|
||||
ACPI_PM_MOBILE,
|
||||
ACPI_PM_WORKSTATION,
|
||||
ACPI_PM_ENTERPRISE_SERVER,
|
||||
ACPI_PM_SOHO_SERVER,
|
||||
ACPI_PM_APPLIANCE_PC,
|
||||
ACPI_PM_PERFORMANCE_SERVER,
|
||||
ACPI_PM_TABLET
|
||||
};
|
||||
|
||||
struct acpi_mcfg_mmconfig {
|
||||
u32 base_address;
|
||||
u32 base_reserved;
|
||||
u16 pci_segment_group_number;
|
||||
u8 start_bus_number;
|
||||
u8 end_bus_number;
|
||||
u8 reserved[4];
|
||||
/* FADT flags for p_lvl2_lat and p_lvl3_lat */
|
||||
#define ACPI_FADT_C2_NOT_SUPPORTED 101
|
||||
#define ACPI_FADT_C3_NOT_SUPPORTED 1001
|
||||
|
||||
/* FADT Boot Architecture Flags */
|
||||
#define ACPI_FADT_LEGACY_FREE 0x00
|
||||
#define ACPI_FADT_LEGACY_DEVICES (1 << 0)
|
||||
#define ACPI_FADT_8042 (1 << 1)
|
||||
#define ACPI_FADT_VGA_NOT_PRESENT (1 << 2)
|
||||
#define ACPI_FADT_MSI_NOT_SUPPORTED (1 << 3)
|
||||
#define ACPI_FADT_NO_PCIE_ASPM_CONTROL (1 << 4)
|
||||
|
||||
/* FADT Feature Flags */
|
||||
#define ACPI_FADT_WBINVD (1 << 0)
|
||||
#define ACPI_FADT_WBINVD_FLUSH (1 << 1)
|
||||
#define ACPI_FADT_C1_SUPPORTED (1 << 2)
|
||||
#define ACPI_FADT_C2_MP_SUPPORTED (1 << 3)
|
||||
#define ACPI_FADT_POWER_BUTTON (1 << 4)
|
||||
#define ACPI_FADT_SLEEP_BUTTON (1 << 5)
|
||||
#define ACPI_FADT_FIXED_RTC (1 << 6)
|
||||
#define ACPI_FADT_S4_RTC_WAKE (1 << 7)
|
||||
#define ACPI_FADT_32BIT_TIMER (1 << 8)
|
||||
#define ACPI_FADT_DOCKING_SUPPORTED (1 << 9)
|
||||
#define ACPI_FADT_RESET_REGISTER (1 << 10)
|
||||
#define ACPI_FADT_SEALED_CASE (1 << 11)
|
||||
#define ACPI_FADT_HEADLESS (1 << 12)
|
||||
#define ACPI_FADT_SLEEP_TYPE (1 << 13)
|
||||
#define ACPI_FADT_PCI_EXPRESS_WAKE (1 << 14)
|
||||
#define ACPI_FADT_PLATFORM_CLOCK (1 << 15)
|
||||
#define ACPI_FADT_S4_RTC_VALID (1 << 16)
|
||||
#define ACPI_FADT_REMOTE_POWER_ON (1 << 17)
|
||||
#define ACPI_FADT_APIC_CLUSTER (1 << 18)
|
||||
#define ACPI_FADT_APIC_PHYSICAL (1 << 19)
|
||||
#define ACPI_FADT_HW_REDUCED_ACPI (1 << 20)
|
||||
#define ACPI_FADT_LOW_PWR_IDLE_S0 (1 << 21)
|
||||
|
||||
enum acpi_address_space_type {
|
||||
ACPI_ADDRESS_SPACE_MEMORY = 0, /* System memory */
|
||||
ACPI_ADDRESS_SPACE_IO, /* System I/O */
|
||||
ACPI_ADDRESS_SPACE_PCI, /* PCI config space */
|
||||
ACPI_ADDRESS_SPACE_EC, /* Embedded controller */
|
||||
ACPI_ADDRESS_SPACE_SMBUS, /* SMBus */
|
||||
ACPI_ADDRESS_SPACE_PCC = 0x0a, /* Platform Comm. Channel */
|
||||
ACPI_ADDRESS_SPACE_FIXED = 0x7f /* Functional fixed hardware */
|
||||
};
|
||||
|
||||
/* MADT (Multiple APIC Description Table) */
|
||||
struct acpi_madt {
|
||||
struct acpi_table_header header;
|
||||
u32 lapic_addr; /* Local APIC address */
|
||||
u32 flags; /* Multiple APIC flags */
|
||||
} acpi_madt_t;
|
||||
|
||||
enum dev_scope_type {
|
||||
SCOPE_PCI_ENDPOINT = 1,
|
||||
SCOPE_PCI_SUB = 2,
|
||||
SCOPE_IOAPIC = 3,
|
||||
SCOPE_MSI_HPET = 4
|
||||
enum acpi_address_space_size {
|
||||
ACPI_ACCESS_SIZE_UNDEFINED = 0,
|
||||
ACPI_ACCESS_SIZE_BYTE_ACCESS,
|
||||
ACPI_ACCESS_SIZE_WORD_ACCESS,
|
||||
ACPI_ACCESS_SIZE_DWORD_ACCESS,
|
||||
ACPI_ACCESS_SIZE_QWORD_ACCESS
|
||||
};
|
||||
|
||||
typedef struct dev_scope {
|
||||
u8 type;
|
||||
u8 length;
|
||||
u8 reserved[2];
|
||||
u8 enumeration;
|
||||
u8 start_bus;
|
||||
struct {
|
||||
u8 dev;
|
||||
u8 fn;
|
||||
} path[0];
|
||||
} __packed dev_scope_t;
|
||||
|
||||
/* MADT: APIC Structure Type*/
|
||||
enum acpi_apic_types {
|
||||
LOCALAPIC = 0, /* Processor local APIC */
|
||||
IOAPIC, /* I/O APIC */
|
||||
IRQSOURCEOVERRIDE, /* Interrupt source override */
|
||||
NMITYPE, /* NMI source */
|
||||
LOCALNMITYPE, /* Local APIC NMI */
|
||||
LAPICADDRESSOVERRIDE, /* Local APIC address override */
|
||||
IOSAPIC, /* I/O SAPIC */
|
||||
LOCALSAPIC, /* Local SAPIC */
|
||||
PLATFORMIRQSOURCES, /* Platform interrupt sources */
|
||||
LOCALX2SAPIC, /* Processor local x2APIC */
|
||||
LOCALX2APICNMI, /* Local x2APIC NMI */
|
||||
};
|
||||
|
||||
/* MADT: Processor Local APIC Structure */
|
||||
struct acpi_madt_lapic {
|
||||
u8 type; /* Type (0) */
|
||||
u8 length; /* Length in bytes (8) */
|
||||
u8 processor_id; /* ACPI processor ID */
|
||||
u8 apic_id; /* Local APIC ID */
|
||||
u32 flags; /* Local APIC flags */
|
||||
};
|
||||
|
||||
#define LOCAL_APIC_FLAG_ENABLED (1 << 0)
|
||||
/* bits 1-31: reserved */
|
||||
#define PCAT_COMPAT (1 << 0)
|
||||
/* bits 1-31: reserved */
|
||||
|
||||
/* MADT: Local APIC NMI Structure */
|
||||
struct acpi_madt_lapic_nmi {
|
||||
u8 type; /* Type (4) */
|
||||
u8 length; /* Length in bytes (6) */
|
||||
u8 processor_id; /* ACPI processor ID */
|
||||
u16 flags; /* MPS INTI flags */
|
||||
u8 lint; /* Local APIC LINT# */
|
||||
};
|
||||
|
||||
/* MADT: I/O APIC Structure */
|
||||
struct acpi_madt_ioapic {
|
||||
u8 type; /* Type (1) */
|
||||
u8 length; /* Length in bytes (12) */
|
||||
u8 ioapic_id; /* I/O APIC ID */
|
||||
u8 reserved;
|
||||
u32 ioapic_addr; /* I/O APIC address */
|
||||
u32 gsi_base; /* Global system interrupt base */
|
||||
};
|
||||
|
||||
/* MADT: Interrupt Source Override Structure */
|
||||
struct acpi_madt_irqoverride {
|
||||
u8 type; /* Type (2) */
|
||||
u8 length; /* Length in bytes (10) */
|
||||
u8 bus; /* ISA (0) */
|
||||
u8 source; /* Bus-relative int. source (IRQ) */
|
||||
u32 gsirq; /* Global system interrupt */
|
||||
u16 flags; /* MPS INTI flags */
|
||||
struct acpi_gen_regaddr {
|
||||
u8 space_id; /* Address space ID */
|
||||
u8 bit_width; /* Register size in bits */
|
||||
u8 bit_offset; /* Register bit offset */
|
||||
u8 access_size; /* Access size */
|
||||
u32 addrl; /* Register address, low 32 bits */
|
||||
u32 addrh; /* Register address, high 32 bits */
|
||||
};
|
||||
|
||||
/* FADT (Fixed ACPI Description Table) */
|
||||
|
@ -254,7 +140,7 @@ struct __packed acpi_fadt {
|
|||
struct acpi_table_header header;
|
||||
u32 firmware_ctrl;
|
||||
u32 dsdt;
|
||||
u8 model;
|
||||
u8 res1;
|
||||
u8 preferred_pm_profile;
|
||||
u16 sci_int;
|
||||
u32 smi_cmd;
|
||||
|
@ -309,85 +195,121 @@ struct __packed acpi_fadt {
|
|||
struct acpi_gen_regaddr x_gpe1_blk;
|
||||
};
|
||||
|
||||
/* Flags for p_lvl2_lat and p_lvl3_lat */
|
||||
#define ACPI_FADT_C2_NOT_SUPPORTED 101
|
||||
#define ACPI_FADT_C3_NOT_SUPPORTED 1001
|
||||
|
||||
/* FADT Feature Flags */
|
||||
#define ACPI_FADT_WBINVD (1 << 0)
|
||||
#define ACPI_FADT_WBINVD_FLUSH (1 << 1)
|
||||
#define ACPI_FADT_C1_SUPPORTED (1 << 2)
|
||||
#define ACPI_FADT_C2_MP_SUPPORTED (1 << 3)
|
||||
#define ACPI_FADT_POWER_BUTTON (1 << 4)
|
||||
#define ACPI_FADT_SLEEP_BUTTON (1 << 5)
|
||||
#define ACPI_FADT_FIXED_RTC (1 << 6)
|
||||
#define ACPI_FADT_S4_RTC_WAKE (1 << 7)
|
||||
#define ACPI_FADT_32BIT_TIMER (1 << 8)
|
||||
#define ACPI_FADT_DOCKING_SUPPORTED (1 << 9)
|
||||
#define ACPI_FADT_RESET_REGISTER (1 << 10)
|
||||
#define ACPI_FADT_SEALED_CASE (1 << 11)
|
||||
#define ACPI_FADT_HEADLESS (1 << 12)
|
||||
#define ACPI_FADT_SLEEP_TYPE (1 << 13)
|
||||
#define ACPI_FADT_PCI_EXPRESS_WAKE (1 << 14)
|
||||
#define ACPI_FADT_PLATFORM_CLOCK (1 << 15)
|
||||
#define ACPI_FADT_S4_RTC_VALID (1 << 16)
|
||||
#define ACPI_FADT_REMOTE_POWER_ON (1 << 17)
|
||||
#define ACPI_FADT_APIC_CLUSTER (1 << 18)
|
||||
#define ACPI_FADT_APIC_PHYSICAL (1 << 19)
|
||||
/* Bits 20-31: reserved ACPI 3.0 & 4.0 */
|
||||
#define ACPI_FADT_HW_REDUCED_ACPI (1 << 20)
|
||||
#define ACPI_FADT_LOW_PWR_IDLE_S0 (1 << 21)
|
||||
/* bits 22-31: reserved ACPI 5.0 */
|
||||
|
||||
/* FADT Boot Architecture Flags */
|
||||
#define ACPI_FADT_LEGACY_DEVICES (1 << 0)
|
||||
#define ACPI_FADT_8042 (1 << 1)
|
||||
#define ACPI_FADT_VGA_NOT_PRESENT (1 << 2)
|
||||
#define ACPI_FADT_MSI_NOT_SUPPORTED (1 << 3)
|
||||
#define ACPI_FADT_NO_PCIE_ASPM_CONTROL (1 << 4)
|
||||
/* No legacy devices (including 8042) */
|
||||
#define ACPI_FADT_LEGACY_FREE 0x00
|
||||
|
||||
/* FADT Preferred Power Management Profile */
|
||||
#define PM_UNSPECIFIED 0
|
||||
#define PM_DESKTOP 1
|
||||
#define PM_MOBILE 2
|
||||
#define PM_WORKSTATION 3
|
||||
#define PM_ENTERPRISE_SERVER 4
|
||||
#define PM_SOHO_SERVER 5
|
||||
#define PM_APPLIANCE_PC 6
|
||||
#define PM_PERFORMANCE_SERVER 7
|
||||
#define PM_TABLET 8 /* ACPI 5.0 */
|
||||
|
||||
/* FACS (Firmware ACPI Control Structure) */
|
||||
struct acpi_facs {
|
||||
char signature[4]; /* "FACS" */
|
||||
u32 length; /* Length in bytes (>= 64) */
|
||||
u32 hardware_signature; /* Hardware signature */
|
||||
u32 firmware_waking_vector; /* Firmware waking vector */
|
||||
u32 global_lock; /* Global lock */
|
||||
u32 flags; /* FACS flags */
|
||||
u32 x_firmware_waking_vector_l; /* X FW waking vector, low */
|
||||
u32 x_firmware_waking_vector_h; /* X FW waking vector, high */
|
||||
u8 version; /* ACPI 4.0: 2 */
|
||||
u8 resv[31]; /* FIXME: 4.0: ospm_flags */
|
||||
};
|
||||
|
||||
/* FACS flags */
|
||||
#define ACPI_FACS_S4BIOS_F (1 << 0)
|
||||
#define ACPI_FACS_64BIT_WAKE_F (1 << 1)
|
||||
/* Bits 31..2: reserved */
|
||||
|
||||
/* FACS (Firmware ACPI Control Structure) */
|
||||
struct acpi_facs {
|
||||
char signature[4]; /* "FACS" */
|
||||
u32 length; /* Length in bytes (>= 64) */
|
||||
u32 hardware_signature; /* Hardware signature */
|
||||
u32 firmware_waking_vector; /* Firmware waking vector */
|
||||
u32 global_lock; /* Global lock */
|
||||
u32 flags; /* FACS flags */
|
||||
u32 x_firmware_waking_vector_l; /* X FW waking vector, low */
|
||||
u32 x_firmware_waking_vector_h; /* X FW waking vector, high */
|
||||
u8 version; /* Version 2 */
|
||||
u8 res1[3];
|
||||
u32 ospm_flags; /* OSPM enabled flags */
|
||||
u8 res2[24];
|
||||
};
|
||||
|
||||
/* MADT flags */
|
||||
#define ACPI_MADT_PCAT_COMPAT (1 << 0)
|
||||
|
||||
/* MADT (Multiple APIC Description Table) */
|
||||
struct acpi_madt {
|
||||
struct acpi_table_header header;
|
||||
u32 lapic_addr; /* Local APIC address */
|
||||
u32 flags; /* Multiple APIC flags */
|
||||
};
|
||||
|
||||
/* MADT: APIC Structure Type*/
|
||||
enum acpi_apic_types {
|
||||
ACPI_APIC_LAPIC = 0, /* Processor local APIC */
|
||||
ACPI_APIC_IOAPIC, /* I/O APIC */
|
||||
ACPI_APIC_IRQ_SRC_OVERRIDE, /* Interrupt source override */
|
||||
ACPI_APIC_NMI_SRC, /* NMI source */
|
||||
ACPI_APIC_LAPIC_NMI, /* Local APIC NMI */
|
||||
ACPI_APIC_LAPIC_ADDR_OVERRIDE, /* Local APIC address override */
|
||||
ACPI_APIC_IOSAPIC, /* I/O SAPIC */
|
||||
ACPI_APIC_LSAPIC, /* Local SAPIC */
|
||||
ACPI_APIC_PLATFORM_IRQ_SRC, /* Platform interrupt sources */
|
||||
ACPI_APIC_LX2APIC, /* Processor local x2APIC */
|
||||
ACPI_APIC_LX2APIC_NMI, /* Local x2APIC NMI */
|
||||
};
|
||||
|
||||
/* MADT: Processor Local APIC Structure */
|
||||
|
||||
#define LOCAL_APIC_FLAG_ENABLED (1 << 0)
|
||||
|
||||
struct acpi_madt_lapic {
|
||||
u8 type; /* Type (0) */
|
||||
u8 length; /* Length in bytes (8) */
|
||||
u8 processor_id; /* ACPI processor ID */
|
||||
u8 apic_id; /* Local APIC ID */
|
||||
u32 flags; /* Local APIC flags */
|
||||
};
|
||||
|
||||
/* MADT: I/O APIC Structure */
|
||||
struct acpi_madt_ioapic {
|
||||
u8 type; /* Type (1) */
|
||||
u8 length; /* Length in bytes (12) */
|
||||
u8 ioapic_id; /* I/O APIC ID */
|
||||
u8 reserved;
|
||||
u32 ioapic_addr; /* I/O APIC address */
|
||||
u32 gsi_base; /* Global system interrupt base */
|
||||
};
|
||||
|
||||
/* MADT: Interrupt Source Override Structure */
|
||||
struct __packed acpi_madt_irqoverride {
|
||||
u8 type; /* Type (2) */
|
||||
u8 length; /* Length in bytes (10) */
|
||||
u8 bus; /* ISA (0) */
|
||||
u8 source; /* Bus-relative int. source (IRQ) */
|
||||
u32 gsirq; /* Global system interrupt */
|
||||
u16 flags; /* MPS INTI flags */
|
||||
};
|
||||
|
||||
/* MADT: Local APIC NMI Structure */
|
||||
struct __packed acpi_madt_lapic_nmi {
|
||||
u8 type; /* Type (4) */
|
||||
u8 length; /* Length in bytes (6) */
|
||||
u8 processor_id; /* ACPI processor ID */
|
||||
u16 flags; /* MPS INTI flags */
|
||||
u8 lint; /* Local APIC LINT# */
|
||||
};
|
||||
|
||||
/* MCFG (PCI Express MMIO config space BAR description table) */
|
||||
struct acpi_mcfg {
|
||||
struct acpi_table_header header;
|
||||
u8 reserved[8];
|
||||
};
|
||||
|
||||
struct acpi_mcfg_mmconfig {
|
||||
u32 base_address_l;
|
||||
u32 base_address_h;
|
||||
u16 pci_segment_group_number;
|
||||
u8 start_bus_number;
|
||||
u8 end_bus_number;
|
||||
u8 reserved[4];
|
||||
};
|
||||
|
||||
/* PM1_CNT bit defines */
|
||||
#define PM1_CNT_SCI_EN (1 << 0)
|
||||
|
||||
/* These can be used by the target port */
|
||||
|
||||
unsigned long acpi_create_madt_lapics(unsigned long current);
|
||||
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr,
|
||||
u32 gsi_base);
|
||||
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
|
||||
u8 bus, u8 source, u32 gsirq, u16 flags);
|
||||
unsigned long acpi_fill_madt(unsigned long current);
|
||||
void acpi_fill_header(struct acpi_table_header *header, char *signature);
|
||||
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
|
||||
void *dsdt);
|
||||
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, u8 cpu,
|
||||
u16 flags, u8 lint);
|
||||
void *dsdt);
|
||||
int acpi_create_madt_lapics(u32 current);
|
||||
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
|
||||
u32 addr, u32 gsi_base);
|
||||
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
|
||||
u8 bus, u8 source, u32 gsirq, u16 flags);
|
||||
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
|
||||
u8 cpu, u16 flags, u8 lint);
|
||||
u32 acpi_fill_madt(u32 current);
|
||||
u32 write_acpi_tables(u32 start);
|
||||
|
|
95
arch/x86/include/asm/arch-baytrail/acpi/gpio.asl
Normal file
95
arch/x86/include/asm/arch-baytrail/acpi/gpio.asl
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/gpio.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* SouthCluster GPIO */
|
||||
Device (GPSC)
|
||||
{
|
||||
Name(_HID, "INT33FC")
|
||||
Name(_CID, "INT33FC")
|
||||
Name(_UID, 1)
|
||||
|
||||
Name(RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,)
|
||||
{
|
||||
GPIO_SC_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method(_CRS)
|
||||
{
|
||||
CreateDwordField(^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSCORE, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method(_STA)
|
||||
{
|
||||
Return (STA_VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
/* NorthCluster GPIO */
|
||||
Device (GPNC)
|
||||
{
|
||||
Name(_HID, "INT33FC")
|
||||
Name(_CID, "INT33FC")
|
||||
Name(_UID, 2)
|
||||
|
||||
Name(RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,)
|
||||
{
|
||||
GPIO_NC_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method(_CRS)
|
||||
{
|
||||
CreateDwordField(^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPNCORE, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method(_STA)
|
||||
{
|
||||
Return (STA_VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
/* SUS GPIO */
|
||||
Device (GPSS)
|
||||
{
|
||||
Name(_HID, "INT33FC")
|
||||
Name(_CID, "INT33FC")
|
||||
Name(_UID, 3)
|
||||
|
||||
Name(RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,)
|
||||
{
|
||||
GPIO_SUS_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method(_CRS)
|
||||
{
|
||||
CreateDwordField(^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSSUS, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method(_STA)
|
||||
{
|
||||
Return (STA_VISIBLE)
|
||||
}
|
||||
}
|
111
arch/x86/include/asm/arch-baytrail/acpi/irq_helper.h
Normal file
111
arch/x86/include/asm/arch-baytrail/acpi/irq_helper.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2014 Sage Electronics Engineering, LLC.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/include/soc/irq_helper.h
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file intentionally gets included multiple times, to set pic and apic
|
||||
* modes, so should not have guard statements added.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file will use irqroute.asl and irqroute.h to generate the ACPI IRQ
|
||||
* routing for the platform being compiled.
|
||||
*
|
||||
* This method uses #defines in irqroute.h along with the macros contained
|
||||
* in this file to generate an IRQ routing for each PCI device in the system.
|
||||
*/
|
||||
|
||||
#undef PCI_DEV_PIRQ_ROUTES
|
||||
#undef PCI_DEV_PIRQ_ROUTE
|
||||
#undef ACPI_DEV_IRQ
|
||||
#undef PCIE_BRIDGE_DEV
|
||||
#undef RP_IRQ_ROUTES
|
||||
#undef ROOTPORT_METHODS
|
||||
#undef ROOTPORT_IRQ_ROUTES
|
||||
#undef RP_METHOD
|
||||
|
||||
#if defined(PIC_MODE)
|
||||
|
||||
#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
|
||||
Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 }
|
||||
|
||||
#define RP_IRQ_ROUTES(prefix_, func_, a_, b_, c_, d_) \
|
||||
Name(prefix_ ## func_ ## P, Package() \
|
||||
{ \
|
||||
ACPI_DEV_IRQ(0x0000, 0, a_), \
|
||||
ACPI_DEV_IRQ(0x0000, 1, b_), \
|
||||
ACPI_DEV_IRQ(0x0000, 2, c_), \
|
||||
ACPI_DEV_IRQ(0x0000, 3, d_), \
|
||||
})
|
||||
|
||||
/* define as blank so ROOTPORT_METHODS only gets inserted once */
|
||||
#define ROOTPORT_METHODS(prefix_, dev_)
|
||||
|
||||
#else /* defined(PIC_MODE) */
|
||||
|
||||
#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
|
||||
Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ }
|
||||
|
||||
#define RP_IRQ_ROUTES(prefix_, func_, a_, b_, c_, d_) \
|
||||
Name(prefix_ ## func_ ## A, Package() \
|
||||
{ \
|
||||
ACPI_DEV_IRQ(0x0000, 0, a_), \
|
||||
ACPI_DEV_IRQ(0x0000, 1, b_), \
|
||||
ACPI_DEV_IRQ(0x0000, 2, c_), \
|
||||
ACPI_DEV_IRQ(0x0000, 3, d_), \
|
||||
})
|
||||
|
||||
#define ROOTPORT_METHODS(prefix_, dev_) \
|
||||
RP_METHOD(prefix_, dev_, 0) \
|
||||
RP_METHOD(prefix_, dev_, 1) \
|
||||
RP_METHOD(prefix_, dev_, 2) \
|
||||
RP_METHOD(prefix_, dev_, 3) \
|
||||
RP_METHOD(prefix_, dev_, 4) \
|
||||
RP_METHOD(prefix_, dev_, 5) \
|
||||
RP_METHOD(prefix_, dev_, 6) \
|
||||
RP_METHOD(prefix_, dev_, 7)
|
||||
|
||||
#endif /* defined(PIC_MODE) */
|
||||
|
||||
#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
|
||||
ACPI_DEV_IRQ(dev_, 0, a_), \
|
||||
ACPI_DEV_IRQ(dev_, 1, b_), \
|
||||
ACPI_DEV_IRQ(dev_, 2, c_), \
|
||||
ACPI_DEV_IRQ(dev_, 3, d_)
|
||||
|
||||
#define PCIE_BRIDGE_DEV(prefix_, dev_, a_, b_, c_, d_) \
|
||||
ROOTPORT_IRQ_ROUTES(prefix_, a_, b_, c_, d_) \
|
||||
ROOTPORT_METHODS(prefix_, dev_)
|
||||
|
||||
#define ROOTPORT_IRQ_ROUTES(prefix_, a_, b_, c_, d_) \
|
||||
RP_IRQ_ROUTES(prefix_, 0, a_, b_, c_, d_) \
|
||||
RP_IRQ_ROUTES(prefix_, 1, b_, c_, d_, a_) \
|
||||
RP_IRQ_ROUTES(prefix_, 2, c_, d_, a_, b_) \
|
||||
RP_IRQ_ROUTES(prefix_, 3, d_, a_, b_, c_) \
|
||||
RP_IRQ_ROUTES(prefix_, 4, a_, b_, c_, d_) \
|
||||
RP_IRQ_ROUTES(prefix_, 5, b_, c_, d_, a_) \
|
||||
RP_IRQ_ROUTES(prefix_, 6, c_, d_, a_, b_) \
|
||||
RP_IRQ_ROUTES(prefix_, 7, d_, a_, b_, c_)
|
||||
|
||||
#define RP_METHOD(prefix_, dev_, func_)\
|
||||
Device (prefix_ ## 0 ## func_) \
|
||||
{ \
|
||||
Name(_ADR, dev_ ## 000 ## func_) \
|
||||
Name(_PRW, Package() { 0, 0 }) \
|
||||
Method(_PRT) { \
|
||||
If (PICM) { \
|
||||
Return (prefix_ ## func_ ## A) \
|
||||
} Else { \
|
||||
Return (prefix_ ## func_ ## P) \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* SoC specific PIRQ route configuration */
|
||||
#include "irqroute.h"
|
493
arch/x86/include/asm/arch-baytrail/acpi/irqlinks.asl
Normal file
493
arch/x86/include/asm/arch-baytrail/acpi/irqlinks.asl
Normal file
|
@ -0,0 +1,493 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/irqlinks.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
Scope (\)
|
||||
{
|
||||
/* Intel Legacy Block */
|
||||
OperationRegion(ILBS, SystemMemory, ILB_BASE_ADDRESS, ILB_BASE_SIZE)
|
||||
Field(ILBS, AnyAcc, NoLock, Preserve) {
|
||||
Offset (0x8),
|
||||
PRTA, 8,
|
||||
PRTB, 8,
|
||||
PRTC, 8,
|
||||
PRTD, 8,
|
||||
PRTE, 8,
|
||||
PRTF, 8,
|
||||
PRTG, 8,
|
||||
PRTH, 8,
|
||||
Offset (0x88),
|
||||
, 3,
|
||||
UI3E, 1,
|
||||
UI4E, 1
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKA)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 1)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTA)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLA, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLA, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTA */
|
||||
ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLA)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTA)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTA, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKB)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 2)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTB)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLB, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLB, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTB */
|
||||
ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLB)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTB)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTB, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKC)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 3)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTC)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLC, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLC, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTC */
|
||||
ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLC)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTC)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTC, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKD)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 4)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTD)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLD, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLD, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTD */
|
||||
ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLD)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTD)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTD, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKE)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 5)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTE)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLE, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLE, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTE */
|
||||
ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLE)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTE)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTE, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKF)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 6)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTF)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLF, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLF, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTF */
|
||||
ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLF)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTF)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTF, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKG)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 7)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTG)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLG, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLG, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTG */
|
||||
ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLG)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTG)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTG, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKH)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0F"))
|
||||
Name(_UID, 8)
|
||||
|
||||
/* Disable method */
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0x80, PRTH)
|
||||
}
|
||||
|
||||
/* Possible Resource Settings for this Link */
|
||||
Name(_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
/* Current Resource Settings for this link */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(RTLH, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLH, 1, IRQ0)
|
||||
|
||||
/* Clear the WordField */
|
||||
Store(Zero, IRQ0)
|
||||
|
||||
/* Set the bit from PRTH */
|
||||
ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLH)
|
||||
}
|
||||
|
||||
/* Set Resource Setting for this IRQ link */
|
||||
Method(_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
/* Which bit is set? */
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTH)
|
||||
}
|
||||
|
||||
/* Status */
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
If (And(PRTH, 0x80)) {
|
||||
Return (STA_DISABLED)
|
||||
} Else {
|
||||
Return (STA_INVISIBLE)
|
||||
}
|
||||
}
|
||||
}
|
48
arch/x86/include/asm/arch-baytrail/acpi/irqroute.asl
Normal file
48
arch/x86/include/asm/arch-baytrail/acpi/irqroute.asl
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/irqroute.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
Name(\PICM, 0)
|
||||
|
||||
/*
|
||||
* The _PIC method is called by the OS to choose between interrupt
|
||||
* routing via the i8259 interrupt controller or the APIC.
|
||||
*
|
||||
* _PIC is called with a parameter of 0 for i8259 configuration and
|
||||
* with a parameter of 1 for Local APIC/IOAPIC configuration.
|
||||
*/
|
||||
Method(\_PIC, 1)
|
||||
{
|
||||
/* Remember the OS' IRQ routing choice */
|
||||
Store(Arg0, PICM)
|
||||
}
|
||||
|
||||
/* PCI interrupt routing */
|
||||
Method(_PRT) {
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include "irq_helper.h"
|
||||
PCI_DEV_PIRQ_ROUTES
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include "irq_helper.h"
|
||||
PCI_DEV_PIRQ_ROUTES
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* PCIe downstream ports interrupt routing */
|
||||
PCIE_BRIDGE_IRQ_ROUTES
|
||||
#undef PIC_MODE
|
||||
#include "irq_helper.h"
|
||||
PCIE_BRIDGE_IRQ_ROUTES
|
27
arch/x86/include/asm/arch-baytrail/acpi/irqroute.h
Normal file
27
arch/x86/include/asm/arch-baytrail/acpi/irqroute.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <asm/arch/device.h>
|
||||
|
||||
#define PCI_DEV_PIRQ_ROUTES \
|
||||
PCI_DEV_PIRQ_ROUTE(GFX_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(EMMC_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(SDIO_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(SD_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(SATA_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(XHCI_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(LPE_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(MMC45_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(SIO1_DEV, A, B, C, D), \
|
||||
PCI_DEV_PIRQ_ROUTE(TXE_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(HDA_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(PCIE_DEV, A, B, C, D), \
|
||||
PCI_DEV_PIRQ_ROUTE(EHCI_DEV, A, A, A, A), \
|
||||
PCI_DEV_PIRQ_ROUTE(SIO2_DEV, A, B, C, D), \
|
||||
PCI_DEV_PIRQ_ROUTE(PCU_DEV, A, B, C, D)
|
||||
|
||||
#define PCIE_BRIDGE_IRQ_ROUTES \
|
||||
PCIE_BRIDGE_DEV(RP, PCIE_DEV, A, B, C, D)
|
181
arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
Normal file
181
arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/lpc.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* Intel LPC Bus Device - 0:1f.0 */
|
||||
|
||||
Device (LPCB)
|
||||
{
|
||||
Name(_ADR, 0x001f0000)
|
||||
|
||||
OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
|
||||
Field(LPC0, AnyAcc, NoLock, Preserve) {
|
||||
Offset(0x08),
|
||||
SRID, 8,
|
||||
Offset(0x80),
|
||||
C1EN, 1,
|
||||
Offset(0x84)
|
||||
}
|
||||
|
||||
#include "irqlinks.asl"
|
||||
|
||||
/* Firmware Hub */
|
||||
Device (FWH)
|
||||
{
|
||||
Name(_HID, EISAID("INT0800"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
|
||||
})
|
||||
}
|
||||
|
||||
/* 8259 Interrupt Controller */
|
||||
Device (PIC)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0000"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x20, 0x20, 0x01, 0x02)
|
||||
IO(Decode16, 0x24, 0x24, 0x01, 0x02)
|
||||
IO(Decode16, 0x28, 0x28, 0x01, 0x02)
|
||||
IO(Decode16, 0x2c, 0x2c, 0x01, 0x02)
|
||||
IO(Decode16, 0x30, 0x30, 0x01, 0x02)
|
||||
IO(Decode16, 0x34, 0x34, 0x01, 0x02)
|
||||
IO(Decode16, 0x38, 0x38, 0x01, 0x02)
|
||||
IO(Decode16, 0x3c, 0x3c, 0x01, 0x02)
|
||||
IO(Decode16, 0xa0, 0xa0, 0x01, 0x02)
|
||||
IO(Decode16, 0xa4, 0xa4, 0x01, 0x02)
|
||||
IO(Decode16, 0xa8, 0xa8, 0x01, 0x02)
|
||||
IO(Decode16, 0xac, 0xac, 0x01, 0x02)
|
||||
IO(Decode16, 0xb0, 0xb0, 0x01, 0x02)
|
||||
IO(Decode16, 0xb4, 0xb4, 0x01, 0x02)
|
||||
IO(Decode16, 0xb8, 0xb8, 0x01, 0x02)
|
||||
IO(Decode16, 0xbc, 0xbc, 0x01, 0x02)
|
||||
IO(Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
|
||||
IRQNoFlags () { 2 }
|
||||
})
|
||||
}
|
||||
|
||||
/* 8254 timer */
|
||||
Device (TIMR)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0100"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x40, 0x40, 0x01, 0x04)
|
||||
IO(Decode16, 0x50, 0x50, 0x10, 0x04)
|
||||
IRQNoFlags() { 0 }
|
||||
})
|
||||
}
|
||||
|
||||
/* HPET */
|
||||
Device (HPET)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0103"))
|
||||
Name(_CID, 0x010CD041)
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadOnly, HPET_BASE_ADDRESS, HPET_BASE_SIZE)
|
||||
})
|
||||
|
||||
Method(_STA)
|
||||
{
|
||||
Return (STA_VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal UART */
|
||||
Device (IURT)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0501"))
|
||||
Name(_UID, 1)
|
||||
|
||||
Method(_STA, 0, Serialized)
|
||||
{
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Need to hide the internal UART depending on whether
|
||||
* internal UART is enabled or not so that external
|
||||
* SuperIO UART can be exposed to system.
|
||||
*/
|
||||
Store(1, UI3E)
|
||||
Store(1, UI4E)
|
||||
Store(1, C1EN)
|
||||
Return (STA_VISIBLE)
|
||||
|
||||
}
|
||||
|
||||
Method(_DIS, 0, Serialized)
|
||||
{
|
||||
Store(0, UI3E)
|
||||
Store(0, UI4E)
|
||||
Store(0, C1EN)
|
||||
}
|
||||
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Name(BUF0, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08)
|
||||
IRQNoFlags() { 3 }
|
||||
})
|
||||
|
||||
Name(BUF1, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08)
|
||||
IRQNoFlags() { 4 }
|
||||
})
|
||||
|
||||
If (LLessEqual(SRID, 0x04)) {
|
||||
Return (BUF0)
|
||||
} Else {
|
||||
Return (BUF1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Real Time Clock */
|
||||
Device (RTC)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0B00"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x70, 0x70, 1, 8)
|
||||
/*
|
||||
* Disable as Windows doesn't like it, and systems
|
||||
* don't seem to use it
|
||||
*/
|
||||
/* IRQNoFlags() { 8 } */
|
||||
})
|
||||
}
|
||||
|
||||
/* LPC device: Resource consumption */
|
||||
Device (LDRC)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C02"))
|
||||
Name(_UID, 2)
|
||||
|
||||
Name(RBUF, ResourceTemplate()
|
||||
{
|
||||
IO(Decode16, 0x61, 0x61, 0x1, 0x01) /* NMI Status */
|
||||
IO(Decode16, 0x63, 0x63, 0x1, 0x01) /* CPU Reserved */
|
||||
IO(Decode16, 0x65, 0x65, 0x1, 0x01) /* CPU Reserved */
|
||||
IO(Decode16, 0x67, 0x67, 0x1, 0x01) /* CPU Reserved */
|
||||
IO(Decode16, 0x80, 0x80, 0x1, 0x01) /* Port 80 Post */
|
||||
IO(Decode16, 0x92, 0x92, 0x1, 0x01) /* CPU Reserved */
|
||||
IO(Decode16, 0xb2, 0xb2, 0x1, 0x02) /* SWSMI */
|
||||
})
|
||||
|
||||
Method(_CRS, 0, NotSerialized)
|
||||
{
|
||||
Return (RBUF)
|
||||
}
|
||||
}
|
||||
}
|
36
arch/x86/include/asm/arch-baytrail/acpi/platform.asl
Normal file
36
arch/x86/include/asm/arch-baytrail/acpi/platform.asl
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <asm/acpi/statdef.asl>
|
||||
#include <asm/arch/iomap.h>
|
||||
#include <asm/arch/irq.h>
|
||||
|
||||
/*
|
||||
* The _PTS method (Prepare To Sleep) is called before the OS is
|
||||
* entering a sleep state. The sleep state number is passed in Arg0.
|
||||
*/
|
||||
Method(_PTS, 1)
|
||||
{
|
||||
}
|
||||
|
||||
/* The _WAK method is called on system wakeup */
|
||||
Method(_WAK, 1)
|
||||
{
|
||||
Return (Package() {0, 0})
|
||||
}
|
||||
|
||||
/* TODO: add CPU ASL support */
|
||||
|
||||
Scope (\_SB)
|
||||
{
|
||||
#include "southcluster.asl"
|
||||
|
||||
/* ACPI devices */
|
||||
#include "gpio.asl"
|
||||
}
|
||||
|
||||
/* Chipset specific sleep states */
|
||||
#include "sleepstates.asl"
|
13
arch/x86/include/asm/arch-baytrail/acpi/sleepstates.asl
Normal file
13
arch/x86/include/asm/arch-baytrail/acpi/sleepstates.asl
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/sleepstates.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
Name(\_S0, Package() {0x0, 0x0, 0x0, 0x0})
|
||||
Name(\_S3, Package() {0x5, 0x0, 0x0, 0x0})
|
||||
Name(\_S4, Package() {0x6, 0x0, 0x0, 0x0})
|
||||
Name(\_S5, Package() {0x7, 0x0, 0x0, 0x0})
|
211
arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl
Normal file
211
arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/southcluster.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
Device (PCI0)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0A08")) /* PCIe */
|
||||
Name(_CID, EISAID("PNP0A03")) /* PCI */
|
||||
|
||||
Name(_ADR, 0)
|
||||
Name(_BBN, 0)
|
||||
|
||||
Name(MCRS, ResourceTemplate()
|
||||
{
|
||||
/* Bus Numbers */
|
||||
WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
|
||||
0x0000, 0x0000, 0x00ff, 0x0000, 0x0100, , , PB00)
|
||||
|
||||
/* IO Region 0 */
|
||||
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8, , , PI00)
|
||||
|
||||
/* PCI Config Space */
|
||||
IO(Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
|
||||
|
||||
/* IO Region 1 */
|
||||
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, 0x0d00, 0xffff, 0x0000, 0xf300, , , PI01)
|
||||
|
||||
/* VGA memory (0xa0000-0xbffff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
|
||||
0x00020000, , , ASEG)
|
||||
|
||||
/* OPROM reserved (0xc0000-0xc3fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
|
||||
0x00004000, , , OPR0)
|
||||
|
||||
/* OPROM reserved (0xc4000-0xc7fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
|
||||
0x00004000, , , OPR1)
|
||||
|
||||
/* OPROM reserved (0xc8000-0xcbfff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
|
||||
0x00004000, , , OPR2)
|
||||
|
||||
/* OPROM reserved (0xcc000-0xcffff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
|
||||
0x00004000, , , OPR3)
|
||||
|
||||
/* OPROM reserved (0xd0000-0xd3fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
|
||||
0x00004000, , , OPR4)
|
||||
|
||||
/* OPROM reserved (0xd4000-0xd7fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
|
||||
0x00004000, , , OPR5)
|
||||
|
||||
/* OPROM reserved (0xd8000-0xdbfff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
|
||||
0x00004000, , , OPR6)
|
||||
|
||||
/* OPROM reserved (0xdc000-0xdffff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
|
||||
0x00004000, , , OPR7)
|
||||
|
||||
/* BIOS Extension (0xe0000-0xe3fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
|
||||
0x00004000, , , ESG0)
|
||||
|
||||
/* BIOS Extension (0xe4000-0xe7fff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
|
||||
0x00004000, , , ESG1)
|
||||
|
||||
/* BIOS Extension (0xe8000-0xebfff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
|
||||
0x00004000, , , ESG2)
|
||||
|
||||
/* BIOS Extension (0xec000-0xeffff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000ec000, 0x000effff, 0x00000000,
|
||||
0x00004000, , , ESG3)
|
||||
|
||||
/* System BIOS (0xf0000-0xfffff) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
|
||||
0x00010000, , , FSEG)
|
||||
|
||||
/* PCI Memory Region (TOLM-CONFIG_MMCONF_BASE_ADDRESS) */
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, , , PMEM)
|
||||
|
||||
/* High PCI Memory Region */
|
||||
QwordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, , , UMEM)
|
||||
})
|
||||
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
/* Update PCI resource area */
|
||||
CreateDwordField(MCRS, ^PMEM._MIN, PMIN)
|
||||
CreateDwordField(MCRS, ^PMEM._MAX, PMAX)
|
||||
CreateDwordField(MCRS, ^PMEM._LEN, PLEN)
|
||||
|
||||
/*
|
||||
* Hardcode TOLM to 2GB for now as BayTrail FSP uses this value.
|
||||
*
|
||||
* TODO: for generic usage, read TOLM value from register, or
|
||||
* from global NVS (not implemented by U-Boot yet).
|
||||
*/
|
||||
Store(0x80000000, PMIN)
|
||||
Store(Subtract(MCFG_BASE_ADDRESS, 1), PMAX)
|
||||
Add(Subtract(PMAX, PMIN), 1, PLEN)
|
||||
|
||||
/* Update High PCI resource area */
|
||||
CreateQwordField(MCRS, ^UMEM._MIN, UMIN)
|
||||
CreateQwordField(MCRS, ^UMEM._MAX, UMAX)
|
||||
CreateQwordField(MCRS, ^UMEM._LEN, ULEN)
|
||||
|
||||
/* Set base address to 48GB and allocate 16GB for PCI space */
|
||||
Store(0xc00000000, UMIN)
|
||||
Store(0x400000000, ULEN)
|
||||
Add(UMIN, Subtract(ULEN, 1), UMAX)
|
||||
|
||||
Return (MCRS)
|
||||
}
|
||||
|
||||
/* Device Resource Consumption */
|
||||
Device (PDRC)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C02"))
|
||||
Name(_UID, 1)
|
||||
|
||||
Name(PDRS, ResourceTemplate() {
|
||||
Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, SPI_BASE_ADDRESS, SPI_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, PMC_BASE_ADDRESS, PMC_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, PUNIT_BASE_ADDRESS, PUNIT_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, ILB_BASE_ADDRESS, ILB_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, MPHY_BASE_ADDRESS, MPHY_BASE_SIZE)
|
||||
})
|
||||
|
||||
/* Current Resource Settings */
|
||||
Method(_CRS, 0, Serialized)
|
||||
{
|
||||
Return (PDRS)
|
||||
}
|
||||
}
|
||||
|
||||
Method(_OSC, 4)
|
||||
{
|
||||
/* Check for proper GUID */
|
||||
If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
|
||||
/* Let OS control everything */
|
||||
Return (Arg3)
|
||||
} Else {
|
||||
/* Unrecognized UUID */
|
||||
CreateDWordField(Arg3, 0, CDW1)
|
||||
Or(CDW1, 4, CDW1)
|
||||
Return (Arg3)
|
||||
}
|
||||
}
|
||||
|
||||
/* LPC Bridge 0:1f.0 */
|
||||
#include "lpc.asl"
|
||||
|
||||
/* USB EHCI 0:1d.0 */
|
||||
#include "usb.asl"
|
||||
|
||||
/* USB XHCI 0:14.0 */
|
||||
#include "xhci.asl"
|
||||
|
||||
/* IRQ routing for each PCI device */
|
||||
#include "irqroute.asl"
|
||||
}
|
34
arch/x86/include/asm/arch-baytrail/acpi/usb.asl
Normal file
34
arch/x86/include/asm/arch-baytrail/acpi/usb.asl
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/usb.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* EHCI Controller 0:1d.0 */
|
||||
|
||||
Device (EHC1)
|
||||
{
|
||||
Name(_ADR, 0x001d0000)
|
||||
|
||||
/* Power Resources for Wake */
|
||||
Name(_PRW, Package() { 13, 4 })
|
||||
|
||||
/* Highest D state in S3 state */
|
||||
Name(_S3D, 2)
|
||||
|
||||
/* Highest D state in S4 state */
|
||||
Name(_S4D, 2)
|
||||
|
||||
Device (HUB7)
|
||||
{
|
||||
Name(_ADR, 0x00000000)
|
||||
|
||||
Device(PRT1) { Name(_ADR, 1) } /* USB Port 0 */
|
||||
Device(PRT2) { Name(_ADR, 2) } /* USB Port 1 */
|
||||
Device(PRT3) { Name(_ADR, 3) } /* USB Port 2 */
|
||||
Device(PRT4) { Name(_ADR, 4) } /* USB Port 3 */
|
||||
}
|
||||
}
|
31
arch/x86/include/asm/arch-baytrail/acpi/xhci.asl
Normal file
31
arch/x86/include/asm/arch-baytrail/acpi/xhci.asl
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/acpi/xhci.asl
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* XHCI Controller 0:14.0 */
|
||||
|
||||
Device (XHCI)
|
||||
{
|
||||
Name(_ADR, 0x00140000)
|
||||
|
||||
/* Power Resources for Wake */
|
||||
Name(_PRW, Package() { 13, 3 })
|
||||
|
||||
/* Highest D state in S3 state */
|
||||
Name(_S3D, 3)
|
||||
|
||||
Device (RHUB)
|
||||
{
|
||||
Name(_ADR, 0x00000000)
|
||||
|
||||
Device (PRT1) { Name(_ADR, 1) } /* USB Port 0 */
|
||||
Device (PRT2) { Name(_ADR, 2) } /* USB Port 1 */
|
||||
Device (PRT3) { Name(_ADR, 3) } /* USB Port 2 */
|
||||
Device (PRT4) { Name(_ADR, 4) } /* USB Port 3 */
|
||||
}
|
||||
}
|
74
arch/x86/include/asm/arch-baytrail/device.h
Normal file
74
arch/x86/include/asm/arch-baytrail/device.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/include/soc/pci_devs.h
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _DEVICE_H_
|
||||
#define _DEVICE_H_
|
||||
|
||||
/*
|
||||
* Internal PCI device numbers within the SoC.
|
||||
*
|
||||
* Note it must start with 0x_ prefix, as the device number macro will be
|
||||
* included in the ACPI ASL files (see irq_helper.h and irq_route.h).
|
||||
*/
|
||||
|
||||
/* SoC transaction router */
|
||||
#define SOC_DEV 0x00
|
||||
|
||||
/* Graphics and Display */
|
||||
#define GFX_DEV 0x02
|
||||
|
||||
/* MIPI */
|
||||
#define MIPI_DEV 0x03
|
||||
|
||||
/* EMMC Port */
|
||||
#define EMMC_DEV 0x10
|
||||
|
||||
/* SDIO Port */
|
||||
#define SDIO_DEV 0x11
|
||||
|
||||
/* SD Port */
|
||||
#define SD_DEV 0x12
|
||||
|
||||
/* SATA */
|
||||
#define SATA_DEV 0x13
|
||||
|
||||
/* xHCI */
|
||||
#define XHCI_DEV 0x14
|
||||
|
||||
/* LPE Audio */
|
||||
#define LPE_DEV 0x15
|
||||
|
||||
/* OTG */
|
||||
#define OTG_DEV 0x16
|
||||
|
||||
/* MMC45 Port */
|
||||
#define MMC45_DEV 0x17
|
||||
|
||||
/* Serial IO 1 */
|
||||
#define SIO1_DEV 0x18
|
||||
|
||||
/* Trusted Execution Engine */
|
||||
#define TXE_DEV 0x1a
|
||||
|
||||
/* HD Audio */
|
||||
#define HDA_DEV 0x1b
|
||||
|
||||
/* PCIe Ports */
|
||||
#define PCIE_DEV 0x1c
|
||||
|
||||
/* EHCI */
|
||||
#define EHCI_DEV 0x1d
|
||||
|
||||
/* Serial IO 2 */
|
||||
#define SIO2_DEV 0x1e
|
||||
|
||||
/* Platform Controller Unit */
|
||||
#define PCU_DEV 0x1f
|
||||
|
||||
#endif /* _DEVICE_H_ */
|
70
arch/x86/include/asm/arch-baytrail/iomap.h
Normal file
70
arch/x86/include/asm/arch-baytrail/iomap.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/include/soc/iomap.h
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _BAYTRAIL_IOMAP_H_
|
||||
#define _BAYTRAIL_IOMAP_H_
|
||||
|
||||
/* Memory Mapped IO bases */
|
||||
|
||||
/* PCI Configuration Space */
|
||||
#define MCFG_BASE_ADDRESS CONFIG_PCIE_ECAM_BASE
|
||||
#define MCFG_BASE_SIZE 0x10000000
|
||||
|
||||
/* Temporary Base Address */
|
||||
#define TEMP_BASE_ADDRESS 0xfd000000
|
||||
|
||||
/* Transactions in this range will abort */
|
||||
#define ABORT_BASE_ADDRESS 0xfeb00000
|
||||
#define ABORT_BASE_SIZE 0x00100000
|
||||
|
||||
/* High Performance Event Timer */
|
||||
#define HPET_BASE_ADDRESS 0xfed00000
|
||||
#define HPET_BASE_SIZE 0x400
|
||||
|
||||
/* SPI Bus */
|
||||
#define SPI_BASE_ADDRESS 0xfed01000
|
||||
#define SPI_BASE_SIZE 0x400
|
||||
|
||||
/* Power Management Controller */
|
||||
#define PMC_BASE_ADDRESS 0xfed03000
|
||||
#define PMC_BASE_SIZE 0x400
|
||||
|
||||
/* Power Management Unit */
|
||||
#define PUNIT_BASE_ADDRESS 0xfed05000
|
||||
#define PUNIT_BASE_SIZE 0x800
|
||||
|
||||
/* Intel Legacy Block */
|
||||
#define ILB_BASE_ADDRESS 0xfed08000
|
||||
#define ILB_BASE_SIZE 0x400
|
||||
|
||||
/* IO Memory */
|
||||
#define IO_BASE_ADDRESS 0xfed0c000
|
||||
#define IO_BASE_OFFSET_GPSCORE 0x0000
|
||||
#define IO_BASE_OFFSET_GPNCORE 0x1000
|
||||
#define IO_BASE_OFFSET_GPSSUS 0x2000
|
||||
#define IO_BASE_SIZE 0x4000
|
||||
|
||||
/* Root Complex Base Address */
|
||||
#define RCBA_BASE_ADDRESS 0xfed1c000
|
||||
#define RCBA_BASE_SIZE 0x400
|
||||
|
||||
/* MODPHY */
|
||||
#define MPHY_BASE_ADDRESS 0xfef00000
|
||||
#define MPHY_BASE_SIZE 0x100000
|
||||
|
||||
/* IO Port bases */
|
||||
#define ACPI_BASE_ADDRESS 0x0400
|
||||
#define ACPI_BASE_SIZE 0x80
|
||||
|
||||
#define GPIO_BASE_ADDRESS 0x0500
|
||||
#define GPIO_BASE_SIZE 0x100
|
||||
|
||||
#define SMBUS_BASE_ADDRESS 0xefa0
|
||||
|
||||
#endif /* _BAYTRAIL_IOMAP_H_ */
|
86
arch/x86/include/asm/arch-baytrail/irq.h
Normal file
86
arch/x86/include/asm/arch-baytrail/irq.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
* Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* Modified from coreboot src/soc/intel/baytrail/include/soc/irq.h
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _BAYTRAIL_IRQ_H_
|
||||
#define _BAYTRAIL_IRQ_H_
|
||||
|
||||
#define PIRQA_APIC_IRQ 16
|
||||
#define PIRQB_APIC_IRQ 17
|
||||
#define PIRQC_APIC_IRQ 18
|
||||
#define PIRQD_APIC_IRQ 19
|
||||
#define PIRQE_APIC_IRQ 20
|
||||
#define PIRQF_APIC_IRQ 21
|
||||
#define PIRQG_APIC_IRQ 22
|
||||
#define PIRQH_APIC_IRQ 23
|
||||
|
||||
/* The below IRQs are for when devices are in ACPI mode */
|
||||
#define LPE_DMA0_IRQ 24
|
||||
#define LPE_DMA1_IRQ 25
|
||||
#define LPE_SSP0_IRQ 26
|
||||
#define LPE_SSP1_IRQ 27
|
||||
#define LPE_SSP2_IRQ 28
|
||||
#define LPE_IPC2HOST_IRQ 29
|
||||
#define LPSS_I2C1_IRQ 32
|
||||
#define LPSS_I2C2_IRQ 33
|
||||
#define LPSS_I2C3_IRQ 34
|
||||
#define LPSS_I2C4_IRQ 35
|
||||
#define LPSS_I2C5_IRQ 36
|
||||
#define LPSS_I2C6_IRQ 37
|
||||
#define LPSS_I2C7_IRQ 38
|
||||
#define LPSS_HSUART1_IRQ 39
|
||||
#define LPSS_HSUART2_IRQ 40
|
||||
#define LPSS_SPI_IRQ 41
|
||||
#define LPSS_DMA1_IRQ 42
|
||||
#define LPSS_DMA2_IRQ 43
|
||||
#define SCC_EMMC_IRQ 44
|
||||
#define SCC_SDIO_IRQ 46
|
||||
#define SCC_SD_IRQ 47
|
||||
#define GPIO_NC_IRQ 48
|
||||
#define GPIO_SC_IRQ 49
|
||||
#define GPIO_SUS_IRQ 50
|
||||
/* GPIO direct / dedicated IRQs */
|
||||
#define GPIO_S0_DED_IRQ_0 51
|
||||
#define GPIO_S0_DED_IRQ_1 52
|
||||
#define GPIO_S0_DED_IRQ_2 53
|
||||
#define GPIO_S0_DED_IRQ_3 54
|
||||
#define GPIO_S0_DED_IRQ_4 55
|
||||
#define GPIO_S0_DED_IRQ_5 56
|
||||
#define GPIO_S0_DED_IRQ_6 57
|
||||
#define GPIO_S0_DED_IRQ_7 58
|
||||
#define GPIO_S0_DED_IRQ_8 59
|
||||
#define GPIO_S0_DED_IRQ_9 60
|
||||
#define GPIO_S0_DED_IRQ_10 61
|
||||
#define GPIO_S0_DED_IRQ_11 62
|
||||
#define GPIO_S0_DED_IRQ_12 63
|
||||
#define GPIO_S0_DED_IRQ_13 64
|
||||
#define GPIO_S0_DED_IRQ_14 65
|
||||
#define GPIO_S0_DED_IRQ_15 66
|
||||
#define GPIO_S5_DED_IRQ_0 67
|
||||
#define GPIO_S5_DED_IRQ_1 68
|
||||
#define GPIO_S5_DED_IRQ_2 69
|
||||
#define GPIO_S5_DED_IRQ_3 70
|
||||
#define GPIO_S5_DED_IRQ_4 71
|
||||
#define GPIO_S5_DED_IRQ_5 72
|
||||
#define GPIO_S5_DED_IRQ_6 73
|
||||
#define GPIO_S5_DED_IRQ_7 74
|
||||
#define GPIO_S5_DED_IRQ_8 75
|
||||
#define GPIO_S5_DED_IRQ_9 76
|
||||
#define GPIO_S5_DED_IRQ_10 77
|
||||
#define GPIO_S5_DED_IRQ_11 78
|
||||
#define GPIO_S5_DED_IRQ_12 79
|
||||
#define GPIO_S5_DED_IRQ_13 80
|
||||
#define GPIO_S5_DED_IRQ_14 81
|
||||
#define GPIO_S5_DED_IRQ_15 82
|
||||
/* DIRQs - Two levels of expansion to evaluate to numeric constants for ASL */
|
||||
#define _GPIO_S0_DED_IRQ(slot) GPIO_S0_DED_IRQ_##slot
|
||||
#define _GPIO_S5_DED_IRQ(slot) GPIO_S5_DED_IRQ_##slot
|
||||
#define GPIO_S0_DED_IRQ(slot) _GPIO_S0_DED_IRQ(slot)
|
||||
#define GPIO_S5_DED_IRQ(slot) _GPIO_S5_DED_IRQ(slot)
|
||||
|
||||
#endif /* _BAYTRAIL_IRQ_H_ */
|
|
@ -294,6 +294,25 @@ struct cbmem_entry {
|
|||
#define CBMEM_ID_CONSOLE 0x434f4e53
|
||||
#define CBMEM_ID_NONE 0x00000000
|
||||
|
||||
/**
|
||||
* high_table_reserve() - reserve configuration table in high memory
|
||||
*
|
||||
* This reserves configuration table in high memory.
|
||||
*
|
||||
* @return: always 0
|
||||
*/
|
||||
int high_table_reserve(void);
|
||||
|
||||
/**
|
||||
* high_table_malloc() - allocate configuration table in high memory
|
||||
*
|
||||
* This allocates configuration table in high memory.
|
||||
*
|
||||
* @bytes: size of configuration table to be allocated
|
||||
* @return: pointer to configuration table in high memory
|
||||
*/
|
||||
void *high_table_malloc(size_t bytes);
|
||||
|
||||
/**
|
||||
* write_coreboot_table() - write coreboot table
|
||||
*
|
||||
|
|
|
@ -93,6 +93,10 @@ struct arch_global_data {
|
|||
char *mrc_output;
|
||||
unsigned int mrc_output_len;
|
||||
ulong table; /* Table pointer from previous loader */
|
||||
#ifdef CONFIG_SEABIOS
|
||||
u32 high_table_ptr;
|
||||
u32 high_table_limit;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,8 @@ enum pirq_config {
|
|||
* IRQ N is available to be routed
|
||||
* @lb_bdf: irq router's PCI bus/device/function number encoding
|
||||
* @ibase: IBASE register block base address
|
||||
* @actl_8bit: ACTL register width is 8-bit (for ICH series chipset)
|
||||
* @actl_addr: ACTL register offset
|
||||
*/
|
||||
struct irq_router {
|
||||
int config;
|
||||
|
@ -41,6 +43,8 @@ struct irq_router {
|
|||
u16 irq_mask;
|
||||
u32 bdf;
|
||||
u32 ibase;
|
||||
bool actl_8bit;
|
||||
int actl_addr;
|
||||
};
|
||||
|
||||
struct pirq_routing {
|
||||
|
|
|
@ -10,7 +10,7 @@ obj-y += bios_asm.o
|
|||
obj-y += bios_interrupts.o
|
||||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||
obj-y += cmd_boot.o
|
||||
obj-y += coreboot_table.o
|
||||
obj-$(CONFIG_SEABIOS) += coreboot_table.o
|
||||
obj-$(CONFIG_EFI) += efi/
|
||||
obj-y += e820.o
|
||||
obj-y += gcc.o
|
||||
|
@ -31,7 +31,7 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
|
|||
obj-y += sfi.o
|
||||
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
|
||||
obj-y += string.o
|
||||
ifndef CONFIG_QEMU_ACPI_TABLE
|
||||
ifndef CONFIG_QEMU
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
|
||||
endif
|
||||
obj-y += tables.o
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Based on acpi.c from coreboot
|
||||
*
|
||||
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
@ -10,25 +11,92 @@
|
|||
#include <cpu.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <asm/acpi_table.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/ioapic.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/tables.h>
|
||||
#include <asm/pci.h>
|
||||
|
||||
/*
|
||||
* IASL compiles the dsdt entries and
|
||||
* writes the hex values to AmlCode array.
|
||||
* CamelCase cannot be handled here.
|
||||
* IASL compiles the dsdt entries and writes the hex values
|
||||
* to a C array AmlCode[] (see dsdt.c).
|
||||
*/
|
||||
extern const unsigned char AmlCode[];
|
||||
|
||||
static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
|
||||
struct acpi_xsdt *xsdt)
|
||||
{
|
||||
memset(rsdp, 0, sizeof(struct acpi_rsdp));
|
||||
|
||||
memcpy(rsdp->signature, RSDP_SIG, 8);
|
||||
memcpy(rsdp->oem_id, OEM_ID, 6);
|
||||
|
||||
rsdp->length = sizeof(struct acpi_rsdp);
|
||||
rsdp->rsdt_address = (u32)rsdt;
|
||||
|
||||
/*
|
||||
* Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2
|
||||
*
|
||||
* Some OSes expect an XSDT to be present for RSD PTR revisions >= 2.
|
||||
* If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR
|
||||
* revision 0)
|
||||
*/
|
||||
if (xsdt == NULL) {
|
||||
rsdp->revision = ACPI_RSDP_REV_ACPI_1_0;
|
||||
} else {
|
||||
rsdp->xsdt_address = (u64)(u32)xsdt;
|
||||
rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
|
||||
}
|
||||
|
||||
/* Calculate checksums */
|
||||
rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
|
||||
rsdp->ext_checksum = table_compute_checksum((void *)rsdp,
|
||||
sizeof(struct acpi_rsdp));
|
||||
}
|
||||
|
||||
void acpi_fill_header(struct acpi_table_header *header, char *signature)
|
||||
{
|
||||
memcpy(header->signature, signature, 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, OEM_TABLE_ID, 8);
|
||||
memcpy(header->aslc_id, ASLC_ID, 4);
|
||||
}
|
||||
|
||||
static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
|
||||
{
|
||||
struct acpi_table_header *header = &(rsdt->header);
|
||||
|
||||
/* Fill out header fields */
|
||||
acpi_fill_header(header, "RSDT");
|
||||
header->length = sizeof(struct acpi_rsdt);
|
||||
header->revision = 1;
|
||||
|
||||
/* Entries are filled in later, we come with an empty set */
|
||||
|
||||
/* Fix checksum */
|
||||
header->checksum = table_compute_checksum((void *)rsdt,
|
||||
sizeof(struct acpi_rsdt));
|
||||
}
|
||||
|
||||
static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
|
||||
{
|
||||
struct acpi_table_header *header = &(xsdt->header);
|
||||
|
||||
/* Fill out header fields */
|
||||
acpi_fill_header(header, "XSDT");
|
||||
header->length = sizeof(struct acpi_xsdt);
|
||||
header->revision = 1;
|
||||
|
||||
/* Entries are filled in later, we come with an empty set */
|
||||
|
||||
/* Fix checksum */
|
||||
header->checksum = table_compute_checksum((void *)xsdt,
|
||||
sizeof(struct acpi_xsdt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
|
||||
* and checksum.
|
||||
*/
|
||||
* Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
|
||||
* and checksum.
|
||||
*/
|
||||
static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
|
||||
{
|
||||
int i, entries_num;
|
||||
|
@ -50,7 +118,7 @@ static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
|
|||
}
|
||||
|
||||
if (i >= entries_num) {
|
||||
debug("ACPI: Error: too many tables.\n");
|
||||
debug("ACPI: Error: too many tables\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,12 +126,13 @@ static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
|
|||
rsdt->entry[i] = (u32)table;
|
||||
|
||||
/* Fix RSDT length or the kernel will assume invalid entries */
|
||||
rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i + 1));
|
||||
rsdt->header.length = sizeof(struct acpi_table_header) +
|
||||
(sizeof(u32) * (i + 1));
|
||||
|
||||
/* Re-calculate checksum */
|
||||
rsdt->header.checksum = 0;
|
||||
rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
|
||||
rsdt->header.length);
|
||||
rsdt->header.length);
|
||||
|
||||
/*
|
||||
* And now the same thing for the XSDT. We use the same index as for
|
||||
|
@ -74,8 +143,8 @@ static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
|
|||
xsdt->entry[i] = (u64)(u32)table;
|
||||
|
||||
/* Fix XSDT length */
|
||||
xsdt->header.length = sizeof(acpi_header_t) +
|
||||
(sizeof(u64) * (i + 1));
|
||||
xsdt->header.length = sizeof(struct acpi_table_header) +
|
||||
(sizeof(u64) * (i + 1));
|
||||
|
||||
/* Re-calculate checksum */
|
||||
xsdt->header.checksum = 0;
|
||||
|
@ -84,149 +153,6 @@ static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
|
|||
}
|
||||
}
|
||||
|
||||
static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
|
||||
u8 cpu, u8 apic)
|
||||
{
|
||||
lapic->type = LOCALAPIC; /* Local APIC structure */
|
||||
lapic->length = sizeof(struct acpi_madt_lapic);
|
||||
lapic->flags = LOCAL_APIC_FLAG_ENABLED; /* Processor/LAPIC enabled */
|
||||
lapic->processor_id = cpu;
|
||||
lapic->apic_id = apic;
|
||||
|
||||
return lapic->length;
|
||||
}
|
||||
|
||||
unsigned long acpi_create_madt_lapics(unsigned long current)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
for (uclass_find_first_device(UCLASS_CPU, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
struct cpu_platdata *plat = dev_get_parent_platdata(dev);
|
||||
|
||||
current += acpi_create_madt_lapic(
|
||||
(struct acpi_madt_lapic *)current,
|
||||
plat->cpu_id, plat->cpu_id);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr,
|
||||
u32 gsi_base)
|
||||
{
|
||||
ioapic->type = IOAPIC;
|
||||
ioapic->length = sizeof(struct acpi_madt_ioapic);
|
||||
ioapic->reserved = 0x00;
|
||||
ioapic->gsi_base = gsi_base;
|
||||
ioapic->ioapic_id = id;
|
||||
ioapic->ioapic_addr = addr;
|
||||
|
||||
return ioapic->length;
|
||||
}
|
||||
|
||||
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
|
||||
u8 bus, u8 source, u32 gsirq, u16 flags)
|
||||
{
|
||||
irqoverride->type = IRQSOURCEOVERRIDE;
|
||||
irqoverride->length = sizeof(struct acpi_madt_irqoverride);
|
||||
irqoverride->bus = bus;
|
||||
irqoverride->source = source;
|
||||
irqoverride->gsirq = gsirq;
|
||||
irqoverride->flags = flags;
|
||||
|
||||
return irqoverride->length;
|
||||
}
|
||||
|
||||
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
|
||||
u8 cpu, u16 flags, u8 lint)
|
||||
{
|
||||
lapic_nmi->type = LOCALNMITYPE;
|
||||
lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
|
||||
lapic_nmi->flags = flags;
|
||||
lapic_nmi->processor_id = cpu;
|
||||
lapic_nmi->lint = lint;
|
||||
|
||||
return lapic_nmi->length;
|
||||
}
|
||||
|
||||
static void fill_header(acpi_header_t *header, char *signature, int length)
|
||||
{
|
||||
memcpy(header->signature, signature, length);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
}
|
||||
|
||||
static void acpi_create_madt(struct acpi_madt *madt)
|
||||
{
|
||||
acpi_header_t *header = &(madt->header);
|
||||
unsigned long current = (unsigned long)madt + sizeof(struct acpi_madt);
|
||||
|
||||
memset((void *)madt, 0, sizeof(struct acpi_madt));
|
||||
|
||||
/* Fill out header fields */
|
||||
fill_header(header, "APIC", 4);
|
||||
header->length = sizeof(struct acpi_madt);
|
||||
|
||||
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
||||
header->revision = ACPI_REV_ACPI_2_0;
|
||||
|
||||
madt->lapic_addr = LAPIC_DEFAULT_BASE;
|
||||
madt->flags = PCAT_COMPAT;
|
||||
|
||||
current = acpi_fill_madt(current);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
header->length = current - (unsigned long)madt;
|
||||
|
||||
header->checksum = table_compute_checksum((void *)madt, header->length);
|
||||
}
|
||||
|
||||
static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig,
|
||||
u32 base, u16 seg_nr, u8 start, u8 end)
|
||||
{
|
||||
memset(mmconfig, 0, sizeof(*mmconfig));
|
||||
mmconfig->base_address = base;
|
||||
mmconfig->base_reserved = 0;
|
||||
mmconfig->pci_segment_group_number = seg_nr;
|
||||
mmconfig->start_bus_number = start;
|
||||
mmconfig->end_bus_number = end;
|
||||
|
||||
return sizeof(struct acpi_mcfg_mmconfig);
|
||||
}
|
||||
|
||||
static unsigned long acpi_fill_mcfg(unsigned long current)
|
||||
{
|
||||
current += acpi_create_mcfg_mmconfig
|
||||
((struct acpi_mcfg_mmconfig *)current,
|
||||
CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/* MCFG is defined in the PCI Firmware Specification 3.0 */
|
||||
static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
|
||||
{
|
||||
acpi_header_t *header = &(mcfg->header);
|
||||
unsigned long current = (unsigned long)mcfg + sizeof(struct acpi_mcfg);
|
||||
|
||||
memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
|
||||
|
||||
/* Fill out header fields */
|
||||
fill_header(header, "MCFG", 4);
|
||||
header->length = sizeof(struct acpi_mcfg);
|
||||
|
||||
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
||||
header->revision = ACPI_REV_ACPI_2_0;
|
||||
|
||||
current = acpi_fill_mcfg(current);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
header->length = current - (unsigned long)mcfg;
|
||||
header->checksum = table_compute_checksum((void *)mcfg, header->length);
|
||||
}
|
||||
|
||||
static void acpi_create_facs(struct acpi_facs *facs)
|
||||
{
|
||||
memset((void *)facs, 0, sizeof(struct acpi_facs));
|
||||
|
@ -239,101 +165,165 @@ static void acpi_create_facs(struct acpi_facs *facs)
|
|||
facs->flags = 0;
|
||||
facs->x_firmware_waking_vector_l = 0;
|
||||
facs->x_firmware_waking_vector_h = 0;
|
||||
facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */
|
||||
facs->version = 1;
|
||||
}
|
||||
|
||||
static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
|
||||
static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
|
||||
u8 cpu, u8 apic)
|
||||
{
|
||||
acpi_header_t *header = &(rsdt->header);
|
||||
lapic->type = ACPI_APIC_LAPIC;
|
||||
lapic->length = sizeof(struct acpi_madt_lapic);
|
||||
lapic->flags = LOCAL_APIC_FLAG_ENABLED;
|
||||
lapic->processor_id = cpu;
|
||||
lapic->apic_id = apic;
|
||||
|
||||
/* Fill out header fields */
|
||||
fill_header(header, "RSDT", 4);
|
||||
header->length = sizeof(struct acpi_rsdt);
|
||||
|
||||
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
||||
header->revision = ACPI_REV_ACPI_2_0;
|
||||
|
||||
/* Entries are filled in later, we come with an empty set */
|
||||
|
||||
/* Fix checksum */
|
||||
header->checksum = table_compute_checksum((void *)rsdt,
|
||||
sizeof(struct acpi_rsdt));
|
||||
return lapic->length;
|
||||
}
|
||||
|
||||
static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
|
||||
int acpi_create_madt_lapics(u32 current)
|
||||
{
|
||||
acpi_header_t *header = &(xsdt->header);
|
||||
struct udevice *dev;
|
||||
int length = 0;
|
||||
|
||||
/* Fill out header fields */
|
||||
fill_header(header, "XSDT", 4);
|
||||
header->length = sizeof(struct acpi_xsdt);
|
||||
for (uclass_find_first_device(UCLASS_CPU, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
struct cpu_platdata *plat = dev_get_parent_platdata(dev);
|
||||
|
||||
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
|
||||
header->revision = ACPI_REV_ACPI_2_0;
|
||||
|
||||
/* Entries are filled in later, we come with an empty set */
|
||||
|
||||
/* Fix checksum */
|
||||
header->checksum = table_compute_checksum((void *)xsdt,
|
||||
sizeof(struct acpi_xsdt));
|
||||
}
|
||||
|
||||
static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
|
||||
struct acpi_xsdt *xsdt)
|
||||
{
|
||||
memset(rsdp, 0, sizeof(struct acpi_rsdp));
|
||||
|
||||
memcpy(rsdp->signature, RSDP_SIG, 8);
|
||||
memcpy(rsdp->oem_id, OEM_ID, 6);
|
||||
|
||||
rsdp->length = sizeof(struct acpi_rsdp);
|
||||
rsdp->rsdt_address = (u32)rsdt;
|
||||
|
||||
/*
|
||||
* Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2
|
||||
*
|
||||
* Some OSes expect an XSDT to be present for RSD PTR revisions >= 2.
|
||||
* If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR
|
||||
* revision 0)
|
||||
*/
|
||||
if (xsdt == NULL) {
|
||||
rsdp->revision = ACPI_RSDP_REV_ACPI_1_0;
|
||||
} else {
|
||||
rsdp->xsdt_address = (u64)(u32)xsdt;
|
||||
rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
|
||||
length += acpi_create_madt_lapic(
|
||||
(struct acpi_madt_lapic *)current,
|
||||
plat->cpu_id, plat->cpu_id);
|
||||
current += length;
|
||||
}
|
||||
|
||||
/* Calculate checksums */
|
||||
rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
|
||||
rsdp->ext_checksum = table_compute_checksum((void *)rsdp,
|
||||
sizeof(struct acpi_rsdp));
|
||||
return length;
|
||||
}
|
||||
|
||||
static void acpi_create_ssdt_generator(acpi_header_t *ssdt,
|
||||
const char *oem_table_id)
|
||||
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
|
||||
u32 addr, u32 gsi_base)
|
||||
{
|
||||
unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t);
|
||||
ioapic->type = ACPI_APIC_IOAPIC;
|
||||
ioapic->length = sizeof(struct acpi_madt_ioapic);
|
||||
ioapic->reserved = 0x00;
|
||||
ioapic->gsi_base = gsi_base;
|
||||
ioapic->ioapic_id = id;
|
||||
ioapic->ioapic_addr = addr;
|
||||
|
||||
memset((void *)ssdt, 0, sizeof(acpi_header_t));
|
||||
return ioapic->length;
|
||||
}
|
||||
|
||||
memcpy(&ssdt->signature, "SSDT", 4);
|
||||
/* Access size in ACPI 2.0c/3.0/4.0/5.0 */
|
||||
ssdt->revision = ACPI_REV_ACPI_3_0;
|
||||
memcpy(&ssdt->oem_id, OEM_ID, 6);
|
||||
memcpy(&ssdt->oem_table_id, oem_table_id, 8);
|
||||
ssdt->oem_revision = OEM_REVISION;
|
||||
memcpy(&ssdt->asl_compiler_id, ASLC, 4);
|
||||
ssdt->asl_compiler_revision = ASL_COMPILER_REVISION;
|
||||
ssdt->length = sizeof(acpi_header_t);
|
||||
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
|
||||
u8 bus, u8 source, u32 gsirq, u16 flags)
|
||||
{
|
||||
irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
|
||||
irqoverride->length = sizeof(struct acpi_madt_irqoverride);
|
||||
irqoverride->bus = bus;
|
||||
irqoverride->source = source;
|
||||
irqoverride->gsirq = gsirq;
|
||||
irqoverride->flags = flags;
|
||||
|
||||
return irqoverride->length;
|
||||
}
|
||||
|
||||
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
|
||||
u8 cpu, u16 flags, u8 lint)
|
||||
{
|
||||
lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
|
||||
lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
|
||||
lapic_nmi->flags = flags;
|
||||
lapic_nmi->processor_id = cpu;
|
||||
lapic_nmi->lint = lint;
|
||||
|
||||
return lapic_nmi->length;
|
||||
}
|
||||
|
||||
static void acpi_create_madt(struct acpi_madt *madt)
|
||||
{
|
||||
struct acpi_table_header *header = &(madt->header);
|
||||
u32 current = (u32)madt + sizeof(struct acpi_madt);
|
||||
|
||||
memset((void *)madt, 0, sizeof(struct acpi_madt));
|
||||
|
||||
/* Fill out header fields */
|
||||
acpi_fill_header(header, "APIC");
|
||||
header->length = sizeof(struct acpi_madt);
|
||||
header->revision = 4;
|
||||
|
||||
madt->lapic_addr = LAPIC_DEFAULT_BASE;
|
||||
madt->flags = ACPI_MADT_PCAT_COMPAT;
|
||||
|
||||
current = acpi_fill_madt(current);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
ssdt->length = current - (unsigned long)ssdt;
|
||||
ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
|
||||
header->length = current - (u32)madt;
|
||||
|
||||
header->checksum = table_compute_checksum((void *)madt, header->length);
|
||||
}
|
||||
|
||||
static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig,
|
||||
u32 base, u16 seg_nr, u8 start, u8 end)
|
||||
{
|
||||
memset(mmconfig, 0, sizeof(*mmconfig));
|
||||
mmconfig->base_address_l = base;
|
||||
mmconfig->base_address_h = 0;
|
||||
mmconfig->pci_segment_group_number = seg_nr;
|
||||
mmconfig->start_bus_number = start;
|
||||
mmconfig->end_bus_number = end;
|
||||
|
||||
return sizeof(struct acpi_mcfg_mmconfig);
|
||||
}
|
||||
|
||||
static u32 acpi_fill_mcfg(u32 current)
|
||||
{
|
||||
current += acpi_create_mcfg_mmconfig
|
||||
((struct acpi_mcfg_mmconfig *)current,
|
||||
CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/* MCFG is defined in the PCI Firmware Specification 3.0 */
|
||||
static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
|
||||
{
|
||||
struct acpi_table_header *header = &(mcfg->header);
|
||||
u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
|
||||
|
||||
memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
|
||||
|
||||
/* Fill out header fields */
|
||||
acpi_fill_header(header, "MCFG");
|
||||
header->length = sizeof(struct acpi_mcfg);
|
||||
header->revision = 1;
|
||||
|
||||
current = acpi_fill_mcfg(current);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
header->length = current - (u32)mcfg;
|
||||
header->checksum = table_compute_checksum((void *)mcfg, header->length);
|
||||
}
|
||||
|
||||
static void enter_acpi_mode(int pm1_cnt)
|
||||
{
|
||||
/*
|
||||
* PM1_CNT register bit0 selects the power management event to be
|
||||
* either an SCI or SMI interrupt. When this bit is set, then power
|
||||
* management events will generate an SCI interrupt. When this bit
|
||||
* is reset power management events will generate an SMI interrupt.
|
||||
*
|
||||
* Per ACPI spec, it is the responsibility of the hardware to set
|
||||
* or reset this bit. OSPM always preserves this bit position.
|
||||
*
|
||||
* U-Boot does not support SMI. And we don't have plan to support
|
||||
* anything running in SMM within U-Boot. To create a legacy-free
|
||||
* system, and expose ourselves to OSPM as working under ACPI mode
|
||||
* already, turn this bit on.
|
||||
*/
|
||||
outw(PM1_CNT_SCI_EN, pm1_cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* QEMU's version of write_acpi_tables is defined in
|
||||
* arch/x86/cpu/qemu/fw_cfg.c
|
||||
* arch/x86/cpu/qemu/acpi_table.c
|
||||
*/
|
||||
u32 write_acpi_tables(u32 start)
|
||||
{
|
||||
|
@ -342,18 +332,17 @@ u32 write_acpi_tables(u32 start)
|
|||
struct acpi_rsdt *rsdt;
|
||||
struct acpi_xsdt *xsdt;
|
||||
struct acpi_facs *facs;
|
||||
acpi_header_t *dsdt;
|
||||
struct acpi_table_header *dsdt;
|
||||
struct acpi_fadt *fadt;
|
||||
struct acpi_mcfg *mcfg;
|
||||
struct acpi_madt *madt;
|
||||
acpi_header_t *ssdt;
|
||||
|
||||
current = start;
|
||||
|
||||
/* Align ACPI tables to 16byte */
|
||||
/* Align ACPI tables to 16 byte */
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: Writing ACPI tables at %lx.\n", start);
|
||||
debug("ACPI: Writing ACPI tables at %x\n", start);
|
||||
|
||||
/* We need at least an RSDP and an RSDT Table */
|
||||
rsdp = (struct acpi_rsdp *)current;
|
||||
|
@ -364,7 +353,11 @@ u32 write_acpi_tables(u32 start)
|
|||
current = ALIGN(current, 16);
|
||||
xsdt = (struct acpi_xsdt *)current;
|
||||
current += sizeof(struct acpi_xsdt);
|
||||
current = ALIGN(current, 16);
|
||||
/*
|
||||
* Per ACPI spec, the FACS table address must be aligned to a 64 byte
|
||||
* boundary (Windows checks this, but Linux does not).
|
||||
*/
|
||||
current = ALIGN(current, 64);
|
||||
|
||||
/* clear all table memory */
|
||||
memset((void *)start, 0, current - start);
|
||||
|
@ -381,21 +374,13 @@ u32 write_acpi_tables(u32 start)
|
|||
acpi_create_facs(facs);
|
||||
|
||||
debug("ACPI: * DSDT\n");
|
||||
dsdt = (acpi_header_t *)current;
|
||||
memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
|
||||
if (dsdt->length >= sizeof(acpi_header_t)) {
|
||||
current += sizeof(acpi_header_t);
|
||||
memcpy((char *)current,
|
||||
(char *)&AmlCode + sizeof(acpi_header_t),
|
||||
dsdt->length - sizeof(acpi_header_t));
|
||||
current += dsdt->length - sizeof(acpi_header_t);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
dsdt->length = current - (unsigned long)dsdt;
|
||||
dsdt->checksum = 0;
|
||||
dsdt->checksum = table_compute_checksum((void *)dsdt,
|
||||
dsdt->length);
|
||||
}
|
||||
dsdt = (struct acpi_table_header *)current;
|
||||
memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
|
||||
current += sizeof(struct acpi_table_header);
|
||||
memcpy((char *)current,
|
||||
(char *)&AmlCode + sizeof(struct acpi_table_header),
|
||||
dsdt->length - sizeof(struct acpi_table_header));
|
||||
current += dsdt->length - sizeof(struct acpi_table_header);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: * FADT\n");
|
||||
|
@ -405,36 +390,29 @@ u32 write_acpi_tables(u32 start)
|
|||
acpi_create_fadt(fadt, facs, dsdt);
|
||||
acpi_add_table(rsdp, fadt);
|
||||
|
||||
debug("ACPI: * MCFG\n");
|
||||
mcfg = (struct acpi_mcfg *)current;
|
||||
acpi_create_mcfg(mcfg);
|
||||
if (mcfg->header.length > sizeof(struct acpi_mcfg)) {
|
||||
current += mcfg->header.length;
|
||||
current = ALIGN(current, 16);
|
||||
acpi_add_table(rsdp, mcfg);
|
||||
}
|
||||
|
||||
debug("ACPI: * MADT\n");
|
||||
madt = (struct acpi_madt *)current;
|
||||
acpi_create_madt(madt);
|
||||
if (madt->header.length > sizeof(struct acpi_madt)) {
|
||||
current += madt->header.length;
|
||||
acpi_add_table(rsdp, madt);
|
||||
}
|
||||
current += madt->header.length;
|
||||
acpi_add_table(rsdp, madt);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: * SSDT\n");
|
||||
ssdt = (acpi_header_t *)current;
|
||||
acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
|
||||
if (ssdt->length > sizeof(acpi_header_t)) {
|
||||
current += ssdt->length;
|
||||
acpi_add_table(rsdp, ssdt);
|
||||
current = ALIGN(current, 16);
|
||||
}
|
||||
debug("ACPI: * MCFG\n");
|
||||
mcfg = (struct acpi_mcfg *)current;
|
||||
acpi_create_mcfg(mcfg);
|
||||
current += mcfg->header.length;
|
||||
acpi_add_table(rsdp, mcfg);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("current = %lx\n", current);
|
||||
debug("current = %x\n", current);
|
||||
|
||||
debug("ACPI: done.\n");
|
||||
debug("ACPI: done\n");
|
||||
|
||||
/*
|
||||
* Other than waiting for OSPM to request us to switch to ACPI mode,
|
||||
* do it by ourselves, since SMI will not be triggered.
|
||||
*/
|
||||
enter_acpi_mode(fadt->pm1a_cnt_blk);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,6 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define COMMAND_LINE_OFFSET 0x9000
|
||||
|
||||
/*
|
||||
* Implement a weak default function for boards that optionally
|
||||
* need to clean up the system before jumping to the kernel.
|
||||
*/
|
||||
__weak void board_final_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void bootm_announce_and_cleanup(void)
|
||||
{
|
||||
printf("\nStarting kernel ...\n\n");
|
||||
|
@ -45,7 +37,6 @@ void bootm_announce_and_cleanup(void)
|
|||
#ifdef CONFIG_BOOTSTAGE_REPORT
|
||||
bootstage_report();
|
||||
#endif
|
||||
board_final_cleanup();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT) && !defined(CONFIG_OF_NO_KERNEL)
|
||||
|
|
|
@ -9,6 +9,37 @@
|
|||
#include <asm/coreboot_tables.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int high_table_reserve(void)
|
||||
{
|
||||
/* adjust stack pointer to reserve space for configuration tables */
|
||||
gd->arch.high_table_limit = gd->start_addr_sp;
|
||||
gd->start_addr_sp -= CONFIG_HIGH_TABLE_SIZE;
|
||||
gd->arch.high_table_ptr = gd->start_addr_sp;
|
||||
|
||||
/* clear the memory */
|
||||
memset((void *)gd->arch.high_table_ptr, 0, CONFIG_HIGH_TABLE_SIZE);
|
||||
|
||||
gd->start_addr_sp &= ~0xf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *high_table_malloc(size_t bytes)
|
||||
{
|
||||
u32 new_ptr;
|
||||
void *ptr;
|
||||
|
||||
new_ptr = gd->arch.high_table_ptr + bytes;
|
||||
if (new_ptr >= gd->arch.high_table_limit)
|
||||
return NULL;
|
||||
ptr = (void *)gd->arch.high_table_ptr;
|
||||
gd->arch.high_table_ptr = new_ptr;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* cb_table_init() - initialize a coreboot table header
|
||||
*
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <pci.h>
|
||||
#include <asm/pci.h>
|
||||
#include <asm/pirq_routing.h>
|
||||
#include <asm/tables.h>
|
||||
|
||||
static bool irq_already_routed[16];
|
||||
|
||||
|
@ -111,9 +110,6 @@ u32 copy_pirq_routing_table(u32 addr, struct irq_routing_table *rt)
|
|||
{
|
||||
struct irq_routing_table *rom_rt;
|
||||
|
||||
/* Fix up the table checksum */
|
||||
rt->checksum = table_compute_checksum(rt, rt->size);
|
||||
|
||||
/* Align the table to be 16 byte aligned */
|
||||
addr = ALIGN(addr, 16);
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ static int smbios_write_type1(u32 *current, int handle)
|
|||
|
||||
memset(t, 0, sizeof(struct smbios_type1));
|
||||
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SYS_VENDOR);
|
||||
t->product_name = smbios_add_string(t->eos, CONFIG_SYS_BOARD);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||
t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME);
|
||||
|
||||
len = t->length + smbios_string_table_len(t->eos);
|
||||
*current += len;
|
||||
|
@ -121,8 +121,8 @@ static int smbios_write_type2(u32 *current, int handle)
|
|||
|
||||
memset(t, 0, sizeof(struct smbios_type2));
|
||||
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SYS_VENDOR);
|
||||
t->product_name = smbios_add_string(t->eos, CONFIG_SYS_BOARD);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||
t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME);
|
||||
t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING;
|
||||
t->board_type = SMBIOS_BOARD_MOTHERBOARD;
|
||||
|
||||
|
@ -139,7 +139,7 @@ static int smbios_write_type3(u32 *current, int handle)
|
|||
|
||||
memset(t, 0, sizeof(struct smbios_type3));
|
||||
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SYS_VENDOR);
|
||||
t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
|
||||
t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP;
|
||||
t->bootup_state = SMBIOS_STATE_SAFE;
|
||||
t->power_supply_state = SMBIOS_STATE_SAFE;
|
||||
|
|
|
@ -80,9 +80,8 @@ void write_tables(void)
|
|||
|
||||
#ifdef CONFIG_SEABIOS
|
||||
table_size = rom_table_end - rom_table_start;
|
||||
high_table = (u32)memalign(ROM_TABLE_ALIGN, table_size);
|
||||
high_table = (u32)high_table_malloc(table_size);
|
||||
if (high_table) {
|
||||
memset((void *)high_table, 0, table_size);
|
||||
table_write_funcs[i](high_table);
|
||||
|
||||
cfg_tables[i].start = high_table;
|
||||
|
|
3
board/congatec/conga-qeval20-qa3-e3845/.gitignore
vendored
Normal file
3
board/congatec/conga-qeval20-qa3-e3845/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
dsdt.aml
|
||||
dsdt.asl.tmp
|
||||
dsdt.c
|
|
@ -5,3 +5,4 @@
|
|||
#
|
||||
|
||||
obj-y += conga-qeval20-qa3.o start.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
|
||||
|
|
13
board/congatec/conga-qeval20-qa3-e3845/acpi/mainboard.asl
Normal file
13
board/congatec/conga-qeval20-qa3-e3845/acpi/mainboard.asl
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* Power Button */
|
||||
Device (PWRB)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0C"))
|
||||
}
|
||||
|
||||
/* TODO: Need add Winbond SuperIO chipset W83627 ASL codes */
|
14
board/congatec/conga-qeval20-qa3-e3845/dsdt.asl
Normal file
14
board/congatec/conga-qeval20-qa3-e3845/dsdt.asl
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
DefinitionBlock("dsdt.aml", "DSDT", 2, "U-BOOT", "U-BOOTBL", 0x00010000)
|
||||
{
|
||||
/* platform specific */
|
||||
#include <asm/arch/acpi/platform.asl>
|
||||
|
||||
/* board specific */
|
||||
#include "acpi/mainboard.asl"
|
||||
}
|
3
board/intel/bayleybay/.gitignore
vendored
Normal file
3
board/intel/bayleybay/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
dsdt.aml
|
||||
dsdt.asl.tmp
|
||||
dsdt.c
|
|
@ -5,3 +5,4 @@
|
|||
#
|
||||
|
||||
obj-y += bayleybay.o start.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
|
||||
|
|
11
board/intel/bayleybay/acpi/mainboard.asl
Normal file
11
board/intel/bayleybay/acpi/mainboard.asl
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* Power Button */
|
||||
Device (PWRB)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0C"))
|
||||
}
|
14
board/intel/bayleybay/dsdt.asl
Normal file
14
board/intel/bayleybay/dsdt.asl
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
DefinitionBlock("dsdt.aml", "DSDT", 2, "U-BOOT", "U-BOOTBL", 0x00010000)
|
||||
{
|
||||
/* platform specific */
|
||||
#include <asm/arch/acpi/platform.asl>
|
||||
|
||||
/* board specific */
|
||||
#include "acpi/mainboard.asl"
|
||||
}
|
|
@ -21,4 +21,15 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
|||
select INTEL_QUARK
|
||||
select BOARD_ROMSIZE_KB_1024
|
||||
|
||||
config SMBIOS_PRODUCT_NAME
|
||||
default "GalileoGen2"
|
||||
help
|
||||
Override the default product name U-Boot reports in the SMBIOS
|
||||
table, to be compatible with the Intel provided UEFI BIOS, as
|
||||
Linux kernel drivers (drivers/mfd/intel_quark_i2c_gpio.c and
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c) make use of
|
||||
it to do different board level configuration.
|
||||
|
||||
This can be "Galileo" for GEN1 Galileo board.
|
||||
|
||||
endif
|
||||
|
|
3
board/intel/minnowmax/.gitignore
vendored
Normal file
3
board/intel/minnowmax/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
dsdt.aml
|
||||
dsdt.asl.tmp
|
||||
dsdt.c
|
|
@ -5,3 +5,4 @@
|
|||
#
|
||||
|
||||
obj-y += minnowmax.o start.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
|
||||
|
|
11
board/intel/minnowmax/acpi/mainboard.asl
Normal file
11
board/intel/minnowmax/acpi/mainboard.asl
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/* Power Button */
|
||||
Device (PWRB)
|
||||
{
|
||||
Name(_HID, EISAID("PNP0C0C"))
|
||||
}
|
14
board/intel/minnowmax/dsdt.asl
Normal file
14
board/intel/minnowmax/dsdt.asl
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
DefinitionBlock("dsdt.aml", "DSDT", 2, "U-BOOT", "U-BOOTBL", 0x00010000)
|
||||
{
|
||||
/* platform specific */
|
||||
#include <asm/arch/acpi/platform.asl>
|
||||
|
||||
/* board specific */
|
||||
#include "acpi/mainboard.asl"
|
||||
}
|
|
@ -593,6 +593,13 @@ config CMD_SOUND
|
|||
sound init - set up sound system
|
||||
sound play - play a sound
|
||||
|
||||
config CMD_QFW
|
||||
bool "qfw"
|
||||
select QFW
|
||||
help
|
||||
This provides access to the QEMU firmware interface. The main
|
||||
feature is to allow easy loading of files passed to qemu-system
|
||||
via -kernel / -initrd
|
||||
endmenu
|
||||
|
||||
config CMD_BOOTSTAGE
|
||||
|
|
|
@ -105,6 +105,7 @@ endif
|
|||
obj-y += pcmcia.o
|
||||
obj-$(CONFIG_CMD_PORTIO) += portio.o
|
||||
obj-$(CONFIG_CMD_PXE) += pxe.o
|
||||
obj-$(CONFIG_CMD_QFW) += qfw.o
|
||||
obj-$(CONFIG_CMD_READ) += read.o
|
||||
obj-$(CONFIG_CMD_REGINFO) += reginfo.o
|
||||
obj-$(CONFIG_CMD_REISER) += reiser.o
|
||||
|
|
194
cmd/qfw.c
Normal file
194
cmd/qfw.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <qfw.h>
|
||||
|
||||
/*
|
||||
* This function prepares kernel for zboot. It loads kernel data
|
||||
* to 'load_addr', initrd to 'initrd_addr' and kernel command
|
||||
* line using qemu fw_cfg interface.
|
||||
*/
|
||||
static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
|
||||
{
|
||||
char *data_addr;
|
||||
uint32_t setup_size, kernel_size, cmdline_size, initrd_size;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_SETUP_SIZE, 4, &setup_size);
|
||||
qemu_fwcfg_read_entry(FW_CFG_KERNEL_SIZE, 4, &kernel_size);
|
||||
|
||||
if (setup_size == 0 || kernel_size == 0) {
|
||||
printf("warning: no kernel available\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_addr = load_addr;
|
||||
qemu_fwcfg_read_entry(FW_CFG_SETUP_DATA,
|
||||
le32_to_cpu(setup_size), data_addr);
|
||||
data_addr += le32_to_cpu(setup_size);
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_KERNEL_DATA,
|
||||
le32_to_cpu(kernel_size), data_addr);
|
||||
data_addr += le32_to_cpu(kernel_size);
|
||||
|
||||
data_addr = initrd_addr;
|
||||
qemu_fwcfg_read_entry(FW_CFG_INITRD_SIZE, 4, &initrd_size);
|
||||
if (initrd_size == 0) {
|
||||
printf("warning: no initrd available\n");
|
||||
} else {
|
||||
qemu_fwcfg_read_entry(FW_CFG_INITRD_DATA,
|
||||
le32_to_cpu(initrd_size), data_addr);
|
||||
data_addr += le32_to_cpu(initrd_size);
|
||||
}
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
|
||||
if (cmdline_size) {
|
||||
qemu_fwcfg_read_entry(FW_CFG_CMDLINE_DATA,
|
||||
le32_to_cpu(cmdline_size), data_addr);
|
||||
/*
|
||||
* if kernel cmdline only contains '\0', (e.g. no -append
|
||||
* when invoking qemu), do not update bootargs
|
||||
*/
|
||||
if (*data_addr != '\0') {
|
||||
if (setenv("bootargs", data_addr) < 0)
|
||||
printf("warning: unable to change bootargs\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("loading kernel to address %p size %x", load_addr,
|
||||
le32_to_cpu(kernel_size));
|
||||
if (initrd_size)
|
||||
printf(" initrd %p size %x\n",
|
||||
initrd_addr,
|
||||
le32_to_cpu(initrd_size));
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_list_firmware(void)
|
||||
{
|
||||
int ret;
|
||||
struct fw_cfg_file_iter iter;
|
||||
struct fw_file *file;
|
||||
|
||||
/* make sure fw_list is loaded */
|
||||
ret = qemu_fwcfg_read_firmware_list();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
for (file = qemu_fwcfg_file_iter_init(&iter);
|
||||
!qemu_fwcfg_file_iter_end(&iter);
|
||||
file = qemu_fwcfg_file_iter_next(&iter)) {
|
||||
printf("%-56s\n", file->cfg.name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_list(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
if (qemu_fwcfg_list_firmware() < 0)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_cpus(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
int ret = qemu_fwcfg_online_cpus();
|
||||
if (ret < 0) {
|
||||
printf("QEMU fw_cfg interface not found\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_load(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
char *env;
|
||||
void *load_addr;
|
||||
void *initrd_addr;
|
||||
|
||||
env = getenv("loadaddr");
|
||||
load_addr = env ?
|
||||
(void *)simple_strtoul(env, NULL, 16) :
|
||||
#ifdef CONFIG_LOADADDR
|
||||
(void *)CONFIG_LOADADDR;
|
||||
#else
|
||||
NULL;
|
||||
#endif
|
||||
|
||||
env = getenv("ramdiskaddr");
|
||||
initrd_addr = env ?
|
||||
(void *)simple_strtoul(env, NULL, 16) :
|
||||
#ifdef CONFIG_RAMDISK_ADDR
|
||||
(void *)CONFIG_RAMDISK_ADDR;
|
||||
#else
|
||||
NULL;
|
||||
#endif
|
||||
|
||||
if (argc == 2) {
|
||||
load_addr = (void *)simple_strtoul(argv[0], NULL, 16);
|
||||
initrd_addr = (void *)simple_strtoul(argv[1], NULL, 16);
|
||||
} else if (argc == 1) {
|
||||
load_addr = (void *)simple_strtoul(argv[0], NULL, 16);
|
||||
}
|
||||
|
||||
if (!load_addr || !initrd_addr) {
|
||||
printf("missing load or initrd address\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return qemu_fwcfg_setup_kernel(load_addr, initrd_addr);
|
||||
}
|
||||
|
||||
static cmd_tbl_t fwcfg_commands[] = {
|
||||
U_BOOT_CMD_MKENT(list, 0, 1, qemu_fwcfg_do_list, "", ""),
|
||||
U_BOOT_CMD_MKENT(cpus, 0, 1, qemu_fwcfg_do_cpus, "", ""),
|
||||
U_BOOT_CMD_MKENT(load, 2, 1, qemu_fwcfg_do_load, "", ""),
|
||||
};
|
||||
|
||||
static int do_qemu_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int ret;
|
||||
cmd_tbl_t *fwcfg_cmd;
|
||||
|
||||
if (!qemu_fwcfg_present()) {
|
||||
printf("QEMU fw_cfg interface not found\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
fwcfg_cmd = find_cmd_tbl(argv[1], fwcfg_commands,
|
||||
ARRAY_SIZE(fwcfg_commands));
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if (!fwcfg_cmd || argc > fwcfg_cmd->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ret = fwcfg_cmd->cmd(fwcfg_cmd, flag, argc, argv);
|
||||
|
||||
return cmd_process_error(fwcfg_cmd, ret);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
qfw, 4, 1, do_qemu_fw,
|
||||
"QEMU firmware interface",
|
||||
"<command>\n"
|
||||
" - list : print firmware(s) currently loaded\n"
|
||||
" - cpus : print online cpu number\n"
|
||||
" - load <kernel addr> <initrd addr> : load kernel and initrd (if any), and setup for zboot\n"
|
||||
)
|
|
@ -9,6 +9,8 @@ CONFIG_HAVE_VGA_BIOS=y
|
|||
CONFIG_VGA_BIOS_ADDR=0xfffa0000
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_SEABIOS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
CONFIG_BOOTSTAGE_REPORT=y
|
||||
|
|
|
@ -8,6 +8,8 @@ CONFIG_SMP=y
|
|||
CONFIG_HAVE_VGA_BIOS=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_SEABIOS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
|
|
|
@ -8,8 +8,6 @@ CONFIG_HAVE_VGA_BIOS=y
|
|||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
CONFIG_BOOTSTAGE_REPORT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_CMD_CPU=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
|
@ -24,7 +22,6 @@ CONFIG_CMD_DHCP=y
|
|||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
|
|
|
@ -4,10 +4,12 @@ CONFIG_DEFAULT_DEVICE_TREE="galileo"
|
|||
CONFIG_TARGET_GALILEO=y
|
||||
CONFIG_ENABLE_MRC_CACHE=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
CONFIG_BOOTSTAGE_REPORT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_CMD_CPU=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
|
@ -30,6 +32,7 @@ CONFIG_OF_CONTROL=y
|
|||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
CONFIG_CPU=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
|
|
|
@ -8,6 +8,8 @@ CONFIG_SMP=y
|
|||
CONFIG_HAVE_VGA_BIOS=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_SEABIOS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
|
|
|
@ -20,6 +20,7 @@ CONFIG_CMD_DHCP=y
|
|||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_QFW=y
|
||||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
|
|
|
@ -48,6 +48,7 @@ CONFIG_CMD_LINK_LOCAL=y
|
|||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_TIMER=y
|
||||
CONFIG_CMD_SOUND=y
|
||||
CONFIG_CMD_QFW=y
|
||||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
|
|
121
doc/README.x86
121
doc/README.x86
|
@ -23,7 +23,8 @@ In this case, known as bare mode, from the fact that it runs on the
|
|||
'bare metal', U-Boot acts like a BIOS replacement. The following platforms
|
||||
are supported:
|
||||
|
||||
- Bayley Bay
|
||||
- Bayley Bay CRB
|
||||
- Congatec QEVAL 2.0 & conga-QA3/E3845
|
||||
- Cougar Canyon 2 CRB
|
||||
- Crown Bay CRB
|
||||
- Galileo
|
||||
|
@ -303,12 +304,12 @@ Offset Description Controlling config
|
|||
000000 descriptor.bin Hard-coded to 0 in ifdtool
|
||||
001000 me.bin Set by the descriptor
|
||||
500000 <spare>
|
||||
6ef000 Environment CONFIG_ENV_OFFSET
|
||||
6f0000 MRC cache CONFIG_ENABLE_MRC_CACHE
|
||||
700000 u-boot-dtb.bin CONFIG_SYS_TEXT_BASE
|
||||
790000 vga.bin CONFIG_VGA_BIOS_ADDR
|
||||
7c0000 fsp.bin CONFIG_FSP_ADDR
|
||||
7f8000 <spare> (depends on size of fsp.bin)
|
||||
7fe000 Environment CONFIG_ENV_OFFSET
|
||||
7ff800 U-Boot 16-bit boot CONFIG_SYS_X86_START16
|
||||
|
||||
Overall ROM image size is controlled by CONFIG_ROM_SIZE.
|
||||
|
@ -412,18 +413,19 @@ If you want to check both consoles, use '-serial stdio'.
|
|||
Multicore is also supported by QEMU via '-smp n' where n is the number of cores
|
||||
to instantiate. Note, the maximum supported CPU number in QEMU is 255.
|
||||
|
||||
The fw_cfg interface in QEMU also provides information about kernel data, initrd,
|
||||
command-line arguments and more. U-Boot supports directly accessing these informtion
|
||||
from fw_cfg interface, this saves the time of loading them from hard disk or
|
||||
network again, through emulated devices. To use it , simply providing them in
|
||||
QEMU command line:
|
||||
The fw_cfg interface in QEMU also provides information about kernel data,
|
||||
initrd, command-line arguments and more. U-Boot supports directly accessing
|
||||
these informtion from fw_cfg interface, which saves the time of loading them
|
||||
from hard disk or network again, through emulated devices. To use it , simply
|
||||
providing them in QEMU command line:
|
||||
|
||||
$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024 -kernel /path/to/bzImage
|
||||
-append 'root=/dev/ram console=ttyS0' -initrd /path/to/initrd -smp 8
|
||||
|
||||
Note: -initrd and -smp are both optional
|
||||
|
||||
Then start QEMU, in U-Boot command line use the following U-Boot command to setup kernel:
|
||||
Then start QEMU, in U-Boot command line use the following U-Boot command to
|
||||
setup kernel:
|
||||
|
||||
=> qfw
|
||||
qfw - QEMU firmware interface
|
||||
|
@ -437,8 +439,8 @@ qfw <command>
|
|||
=> qfw load
|
||||
loading kernel to address 01000000 size 5d9d30 initrd 04000000 size 1b1ab50
|
||||
|
||||
Here the kernel (bzImage) is loaded to 01000000 and initrd is to 04000000. Then, 'zboot'
|
||||
can be used to boot the kernel:
|
||||
Here the kernel (bzImage) is loaded to 01000000 and initrd is to 04000000. Then,
|
||||
'zboot' can be used to boot the kernel:
|
||||
|
||||
=> zboot 02000000 - 04000000 1b1ab50
|
||||
|
||||
|
@ -490,8 +492,8 @@ Booting Ubuntu
|
|||
--------------
|
||||
As an example of how to set up your boot flow with U-Boot, here are
|
||||
instructions for starting Ubuntu from U-Boot. These instructions have been
|
||||
tested on Minnowboard MAX with a SATA driver but are equally applicable on
|
||||
other platforms and other media. There are really only four steps and its a
|
||||
tested on Minnowboard MAX with a SATA drive but are equally applicable on
|
||||
other platforms and other media. There are really only four steps and it's a
|
||||
very simple script, but a more detailed explanation is provided here for
|
||||
completeness.
|
||||
|
||||
|
@ -499,7 +501,7 @@ Note: It is possible to set up U-Boot to boot automatically using syslinux.
|
|||
It could also use the grub.cfg file (/efi/ubuntu/grub.cfg) to obtain the
|
||||
GUID. If you figure these out, please post patches to this README.
|
||||
|
||||
Firstly, you will need Ubunutu installed on an available disk. It should be
|
||||
Firstly, you will need Ubuntu installed on an available disk. It should be
|
||||
possible to make U-Boot start a USB start-up disk but for now let's assume
|
||||
that you used another boot loader to install Ubuntu.
|
||||
|
||||
|
@ -659,7 +661,7 @@ U-Boot:
|
|||
Loading bzImage at address 100000 (5805728 bytes)
|
||||
Magic signature found
|
||||
Initial RAM disk at linear address 0x04000000, size 19215259 bytes
|
||||
Kernel command line: "console=ttyS0,115200 root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro"
|
||||
Kernel command line: "root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro"
|
||||
|
||||
Starting kernel ...
|
||||
|
||||
|
@ -679,13 +681,14 @@ above commands into a script since then it will be faster.
|
|||
240,329 ahci
|
||||
1,422,704 vesa display
|
||||
|
||||
Now the kernel actually starts:
|
||||
Now the kernel actually starts: (if you want to examine kernel boot up message
|
||||
on the serial console, append "console=ttyS0,115200" to the kernel command line)
|
||||
|
||||
[ 0.000000] Initializing cgroup subsys cpuset
|
||||
[ 0.000000] Initializing cgroup subsys cpu
|
||||
[ 0.000000] Initializing cgroup subsys cpuacct
|
||||
[ 0.000000] Linux version 3.13.0-58-generic (buildd@allspice) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #97-Ubuntu SMP Wed Jul 8 02:56:15 UTC 2015 (Ubuntu 3.13.0-58.97-generic 3.13.11-ckt22)
|
||||
[ 0.000000] Command line: console=ttyS0,115200 root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro
|
||||
[ 0.000000] Command line: root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro console=ttyS0,115200
|
||||
|
||||
It continues for a long time. Along the way you will see it pick up your
|
||||
ramdisk:
|
||||
|
@ -736,14 +739,6 @@ If you want to put this in a script you can use something like this:
|
|||
The \ is to tell the shell not to evaluate ${filesize} as part of the setenv
|
||||
command.
|
||||
|
||||
You will also need to add this to your board configuration file, e.g.
|
||||
include/configs/minnowmax.h:
|
||||
|
||||
#define CONFIG_BOOTDELAY 2
|
||||
|
||||
Now when you reset your board it wait a few seconds (in case you want to
|
||||
interrupt) and then should boot straight into Ubuntu.
|
||||
|
||||
You can also bake this behaviour into your build by hard-coding the
|
||||
environment variables if you add this to minnowmax.h:
|
||||
|
||||
|
@ -812,6 +807,30 @@ to install/boot a Windows XP OS (below for example command to install Windows).
|
|||
This is also tested on Intel Crown Bay board with a PCIe graphics card, booting
|
||||
SeaBIOS then chain-loading a GRUB on a USB drive, then Linux kernel finally.
|
||||
|
||||
If you are using Intel Integrated Graphics Device (IGD) as the primary display
|
||||
device on your board, SeaBIOS needs to be patched manually to get its VGA ROM
|
||||
loaded and run by SeaBIOS. SeaBIOS locates VGA ROM via the PCI expansion ROM
|
||||
register, but IGD device does not have its VGA ROM mapped by this register.
|
||||
Its VGA ROM is packaged as part of u-boot.rom at a configurable flash address
|
||||
which is unknown to SeaBIOS. An example patch is needed for SeaBIOS below:
|
||||
|
||||
diff --git a/src/optionroms.c b/src/optionroms.c
|
||||
index 65f7fe0..c7b6f5e 100644
|
||||
--- a/src/optionroms.c
|
||||
+++ b/src/optionroms.c
|
||||
@@ -324,6 +324,8 @@ init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
|
||||
rom = deploy_romfile(file);
|
||||
else if (RunPCIroms > 1 || (RunPCIroms == 1 && isvga))
|
||||
rom = map_pcirom(pci);
|
||||
+ if (pci->bdf == pci_to_bdf(0, 2, 0))
|
||||
+ rom = (struct rom_header *)0xfff90000;
|
||||
if (! rom)
|
||||
// No ROM present.
|
||||
return;
|
||||
|
||||
Note: the patch above expects IGD device is at PCI b.d.f 0.2.0 and its VGA ROM
|
||||
is at 0xfff90000 which corresponds to CONFIG_VGA_BIOS_ADDR on Minnowboard MAX.
|
||||
Change these two accordingly if this is not the case on your board.
|
||||
|
||||
Development Flow
|
||||
----------------
|
||||
|
@ -963,12 +982,62 @@ transformations. Remember to add attribution to coreboot for new files added
|
|||
to U-Boot. This should go at the top of each file and list the coreboot
|
||||
filename where the code originated.
|
||||
|
||||
Debugging ACPI issues with Windows:
|
||||
|
||||
Windows might cache system information and only detect ACPI changes if you
|
||||
modify the ACPI table versions. So tweak them liberally when debugging ACPI
|
||||
issues with Windows.
|
||||
|
||||
ACPI Support Status
|
||||
-------------------
|
||||
Advanced Configuration and Power Interface (ACPI) [16] aims to establish
|
||||
industry-standard interfaces enabling OS-directed configuration, power
|
||||
management, and thermal management of mobile, desktop, and server platforms.
|
||||
|
||||
Linux can boot without ACPI with "acpi=off" command line parameter, but
|
||||
with ACPI the kernel gains the capabilities to handle power management.
|
||||
For Windows, ACPI is a must-have firmware feature since Windows Vista.
|
||||
CONFIG_GENERATE_ACPI_TABLE is the config option to turn on ACPI support in
|
||||
U-Boot. This requires Intel ACPI compiler to be installed on your host to
|
||||
compile ACPI DSDT table written in ASL format to AML format. You can get
|
||||
the compiler via "apt-get install iasl" if you are on Ubuntu or download
|
||||
the source from [17] to compile one by yourself.
|
||||
|
||||
Current ACPI support in U-Boot is not complete. More features will be added
|
||||
in the future. The status as of today is:
|
||||
|
||||
* Support generating RSDT, XSDT, FACS, FADT, MADT, MCFG tables.
|
||||
* Support one static DSDT table only, compiled by Intel ACPI compiler.
|
||||
* Support S0/S5, reboot and shutdown from OS.
|
||||
* Support booting a pre-installed Ubuntu distribution via 'zboot' command.
|
||||
* Support installing and booting Ubuntu 14.04 (or above) from U-Boot with
|
||||
the help of SeaBIOS using legacy interface (non-UEFI mode).
|
||||
* Support installing and booting Windows 8.1/10 from U-Boot with the help
|
||||
of SeaBIOS using legacy interface (non-UEFI mode).
|
||||
* Support ACPI interrupts with SCI only.
|
||||
|
||||
Features not supported so far (to make it a complete ACPI solution):
|
||||
* S3 (Suspend to RAM), S4 (Suspend to Disk).
|
||||
|
||||
Features that are optional:
|
||||
* ACPI global NVS support. We may need it to simplify ASL code logic if
|
||||
utilizing NVS variables. Most likely we will need this sooner or later.
|
||||
* Dynamic AML bytecodes insertion at run-time. We may need this to support
|
||||
SSDT table generation and DSDT fix up.
|
||||
* SMI support. Since U-Boot is a modern bootloader, we don't want to bring
|
||||
those legacy stuff into U-Boot. ACPI spec allows a system that does not
|
||||
support SMI (a legacy-free system).
|
||||
|
||||
So far ACPI is enabled on BayTrail based boards. Testing was done by booting
|
||||
a pre-installed Ubuntu 14.04 from a SATA drive. Installing Ubuntu 14.04 and
|
||||
Windows 8.1/10 to a SATA drive and booting from there is also tested. Most
|
||||
devices seem to work correctly and the board can respond a reboot/shutdown
|
||||
command from the OS.
|
||||
|
||||
TODO List
|
||||
---------
|
||||
- Audio
|
||||
- Chrome OS verified boot
|
||||
- SMI and ACPI support, to provide platform info and facilities to Linux
|
||||
|
||||
References
|
||||
----------
|
||||
|
@ -987,3 +1056,5 @@ References
|
|||
[13] http://events.linuxfoundation.org/sites/events/files/slides/elce-2014.pdf
|
||||
[14] http://www.seabios.org/SeaBIOS
|
||||
[15] doc/device-tree-bindings/misc/intel,irq-router.txt
|
||||
[16] http://www.acpi.info
|
||||
[17] https://www.acpica.org/downloads
|
||||
|
|
|
@ -14,6 +14,11 @@ Required properties :
|
|||
"ibase": IRQ routing is in the memory-mapped IBASE register block
|
||||
- intel,ibase-offset : IBASE register offset in the interrupt router's PCI
|
||||
configuration space, required only if intel,pirq-config = "ibase".
|
||||
- intel,actl-8bit : If ACTL (ACPI control) register width is 8-bit, this must
|
||||
be specified. The 8-bit ACTL register is seen on ICH series chipset, like
|
||||
ICH9/Panther Point/etc. On Atom chipset it is a 32-bit register.
|
||||
- intel,actl-addr : ACTL (ACPI control) register offset. ACTL can be either
|
||||
in the interrupt router's PCI configuration space, or IBASE.
|
||||
- intel,pirq-link : Specifies the PIRQ link information with two cells. The
|
||||
first cell is the register offset that controls the first PIRQ link routing.
|
||||
The second cell is the total number of PIRQ links the router supports.
|
||||
|
|
|
@ -138,4 +138,10 @@ config WINBOND_W83627
|
|||
legacy UART or other devices in the Winbond Super IO chips
|
||||
on X86 platforms.
|
||||
|
||||
config QFW
|
||||
bool
|
||||
help
|
||||
Hidden option to enable QEMU fw_cfg interface. This will be selected by
|
||||
either CONFIG_CMD_QFW or CONFIG_GENERATE_ACPI_TABLE.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -43,3 +43,4 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
|
|||
obj-$(CONFIG_RESET) += reset-uclass.o
|
||||
obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
|
||||
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
|
||||
obj-$(CONFIG_QFW) += qfw.o
|
||||
|
|
|
@ -8,220 +8,20 @@
|
|||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <qfw.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/fw_cfg.h>
|
||||
#ifdef CONFIG_GENERATE_ACPI_TABLE
|
||||
#include <asm/tables.h>
|
||||
#include <asm/e820.h>
|
||||
#endif
|
||||
#include <linux/list.h>
|
||||
#include <memalign.h>
|
||||
|
||||
static bool fwcfg_present;
|
||||
static bool fwcfg_dma_present;
|
||||
static struct fw_cfg_arch_ops *fwcfg_arch_ops;
|
||||
|
||||
static LIST_HEAD(fw_list);
|
||||
|
||||
/* Read configuration item using fw_cfg PIO interface */
|
||||
static void qemu_fwcfg_read_entry_pio(uint16_t entry,
|
||||
uint32_t size, void *address)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint8_t *data = address;
|
||||
|
||||
/*
|
||||
* writting FW_CFG_INVALID will cause read operation to resume at
|
||||
* last offset, otherwise read will start at offset 0
|
||||
*/
|
||||
if (entry != FW_CFG_INVALID)
|
||||
outw(entry, FW_CONTROL_PORT);
|
||||
while (size--)
|
||||
data[i++] = inb(FW_DATA_PORT);
|
||||
}
|
||||
|
||||
/* Read configuration item using fw_cfg DMA interface */
|
||||
static void qemu_fwcfg_read_entry_dma(uint16_t entry,
|
||||
uint32_t size, void *address)
|
||||
{
|
||||
struct fw_cfg_dma_access dma;
|
||||
|
||||
dma.length = cpu_to_be32(size);
|
||||
dma.address = cpu_to_be64((uintptr_t)address);
|
||||
dma.control = cpu_to_be32(FW_CFG_DMA_READ);
|
||||
|
||||
/*
|
||||
* writting FW_CFG_INVALID will cause read operation to resume at
|
||||
* last offset, otherwise read will start at offset 0
|
||||
*/
|
||||
if (entry != FW_CFG_INVALID)
|
||||
dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
|
||||
|
||||
barrier();
|
||||
|
||||
debug("qemu_fwcfg_dma_read_entry: addr %p, length %u control 0x%x\n",
|
||||
address, size, be32_to_cpu(dma.control));
|
||||
|
||||
outl(cpu_to_be32((uint32_t)&dma), FW_DMA_PORT_HIGH);
|
||||
|
||||
while (be32_to_cpu(dma.control) & ~FW_CFG_DMA_ERROR)
|
||||
__asm__ __volatile__ ("pause");
|
||||
}
|
||||
|
||||
static bool qemu_fwcfg_present(void)
|
||||
{
|
||||
uint32_t qemu;
|
||||
|
||||
qemu_fwcfg_read_entry_pio(FW_CFG_SIGNATURE, 4, &qemu);
|
||||
return be32_to_cpu(qemu) == QEMU_FW_CFG_SIGNATURE;
|
||||
}
|
||||
|
||||
static bool qemu_fwcfg_dma_present(void)
|
||||
{
|
||||
uint8_t dma_enabled;
|
||||
|
||||
qemu_fwcfg_read_entry_pio(FW_CFG_ID, 1, &dma_enabled);
|
||||
if (dma_enabled & FW_CFG_DMA_ENABLED)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void qemu_fwcfg_read_entry(uint16_t entry,
|
||||
uint32_t length, void *address)
|
||||
{
|
||||
if (fwcfg_dma_present)
|
||||
qemu_fwcfg_read_entry_dma(entry, length, address);
|
||||
else
|
||||
qemu_fwcfg_read_entry_pio(entry, length, address);
|
||||
}
|
||||
|
||||
int qemu_fwcfg_online_cpus(void)
|
||||
{
|
||||
uint16_t nb_cpus;
|
||||
|
||||
if (!fwcfg_present)
|
||||
return -ENODEV;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus);
|
||||
|
||||
return le16_to_cpu(nb_cpus);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares kernel for zboot. It loads kernel data
|
||||
* to 'load_addr', initrd to 'initrd_addr' and kernel command
|
||||
* line using qemu fw_cfg interface.
|
||||
*/
|
||||
static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
|
||||
{
|
||||
char *data_addr;
|
||||
uint32_t setup_size, kernel_size, cmdline_size, initrd_size;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_SETUP_SIZE, 4, &setup_size);
|
||||
qemu_fwcfg_read_entry(FW_CFG_KERNEL_SIZE, 4, &kernel_size);
|
||||
|
||||
if (setup_size == 0 || kernel_size == 0) {
|
||||
printf("warning: no kernel available\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_addr = load_addr;
|
||||
qemu_fwcfg_read_entry(FW_CFG_SETUP_DATA,
|
||||
le32_to_cpu(setup_size), data_addr);
|
||||
data_addr += le32_to_cpu(setup_size);
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_KERNEL_DATA,
|
||||
le32_to_cpu(kernel_size), data_addr);
|
||||
data_addr += le32_to_cpu(kernel_size);
|
||||
|
||||
data_addr = initrd_addr;
|
||||
qemu_fwcfg_read_entry(FW_CFG_INITRD_SIZE, 4, &initrd_size);
|
||||
if (initrd_size == 0) {
|
||||
printf("warning: no initrd available\n");
|
||||
} else {
|
||||
qemu_fwcfg_read_entry(FW_CFG_INITRD_DATA,
|
||||
le32_to_cpu(initrd_size), data_addr);
|
||||
data_addr += le32_to_cpu(initrd_size);
|
||||
}
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
|
||||
if (cmdline_size) {
|
||||
qemu_fwcfg_read_entry(FW_CFG_CMDLINE_DATA,
|
||||
le32_to_cpu(cmdline_size), data_addr);
|
||||
/*
|
||||
* if kernel cmdline only contains '\0', (e.g. no -append
|
||||
* when invoking qemu), do not update bootargs
|
||||
*/
|
||||
if (*data_addr != '\0') {
|
||||
if (setenv("bootargs", data_addr) < 0)
|
||||
printf("warning: unable to change bootargs\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("loading kernel to address %p size %x", load_addr,
|
||||
le32_to_cpu(kernel_size));
|
||||
if (initrd_size)
|
||||
printf(" initrd %p size %x\n",
|
||||
initrd_addr,
|
||||
le32_to_cpu(initrd_size));
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_read_firmware_list(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t count;
|
||||
struct fw_file *file;
|
||||
struct list_head *entry;
|
||||
|
||||
/* don't read it twice */
|
||||
if (!list_empty(&fw_list))
|
||||
return 0;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count);
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
count = be32_to_cpu(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
file = malloc(sizeof(*file));
|
||||
if (!file) {
|
||||
printf("error: allocating resource\n");
|
||||
goto err;
|
||||
}
|
||||
qemu_fwcfg_read_entry(FW_CFG_INVALID,
|
||||
sizeof(struct fw_cfg_file), &file->cfg);
|
||||
file->addr = 0;
|
||||
list_add_tail(&file->list, &fw_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
list_for_each(entry, &fw_list) {
|
||||
file = list_entry(entry, struct fw_file, list);
|
||||
free(file);
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QEMU_ACPI_TABLE
|
||||
static struct fw_file *qemu_fwcfg_find_file(const char *name)
|
||||
{
|
||||
struct list_head *entry;
|
||||
struct fw_file *file;
|
||||
|
||||
list_for_each(entry, &fw_list) {
|
||||
file = list_entry(entry, struct fw_file, list);
|
||||
if (!strcmp(file->cfg.name, name))
|
||||
return file;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERATE_ACPI_TABLE
|
||||
/*
|
||||
* This function allocates memory for ACPI tables
|
||||
*
|
||||
|
@ -346,41 +146,6 @@ static int bios_linker_add_checksum(struct bios_linker_entry *entry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
||||
{
|
||||
entries[0].addr = 0;
|
||||
entries[0].size = ISA_START_ADDRESS;
|
||||
entries[0].type = E820_RAM;
|
||||
|
||||
entries[1].addr = ISA_START_ADDRESS;
|
||||
entries[1].size = ISA_END_ADDRESS - ISA_START_ADDRESS;
|
||||
entries[1].type = E820_RESERVED;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* 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[4].addr = gd->relocaddr;
|
||||
entries[4].size = gd->ram_size - gd->relocaddr;
|
||||
entries[4].type = E820_RESERVED;
|
||||
|
||||
entries[5].addr = CONFIG_PCIE_ECAM_BASE;
|
||||
entries[5].size = CONFIG_PCIE_ECAM_SIZE;
|
||||
entries[5].type = E820_RESERVED;
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
/* This function loads and patches ACPI tables provided by QEMU */
|
||||
u32 write_acpi_tables(u32 addr)
|
||||
{
|
||||
|
@ -389,7 +154,6 @@ u32 write_acpi_tables(u32 addr)
|
|||
struct bios_linker_entry *table_loader;
|
||||
struct bios_linker_entry *entry;
|
||||
uint32_t size;
|
||||
struct list_head *list;
|
||||
|
||||
/* make sure fw_list is loaded */
|
||||
ret = qemu_fwcfg_read_firmware_list();
|
||||
|
@ -444,10 +208,14 @@ u32 write_acpi_tables(u32 addr)
|
|||
|
||||
out:
|
||||
if (ret) {
|
||||
list_for_each(list, &fw_list) {
|
||||
file = list_entry(list, struct fw_file, list);
|
||||
if (file->addr)
|
||||
struct fw_cfg_file_iter iter;
|
||||
for (file = qemu_fwcfg_file_iter_init(&iter);
|
||||
!qemu_fwcfg_file_iter_end(&iter);
|
||||
file = qemu_fwcfg_file_iter_next(&iter)) {
|
||||
if (file->addr) {
|
||||
free((void *)file->addr);
|
||||
file->addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,115 +224,163 @@ out:
|
|||
}
|
||||
#endif
|
||||
|
||||
static int qemu_fwcfg_list_firmware(void)
|
||||
/* Read configuration item using fw_cfg PIO interface */
|
||||
static void qemu_fwcfg_read_entry_pio(uint16_t entry,
|
||||
uint32_t size, void *address)
|
||||
{
|
||||
debug("qemu_fwcfg_read_entry_pio: entry 0x%x, size %u address %p\n",
|
||||
entry, size, address);
|
||||
|
||||
return fwcfg_arch_ops->arch_read_pio(entry, size, address);
|
||||
}
|
||||
|
||||
/* Read configuration item using fw_cfg DMA interface */
|
||||
static void qemu_fwcfg_read_entry_dma(uint16_t entry,
|
||||
uint32_t size, void *address)
|
||||
{
|
||||
struct fw_cfg_dma_access dma;
|
||||
|
||||
dma.length = cpu_to_be32(size);
|
||||
dma.address = cpu_to_be64((uintptr_t)address);
|
||||
dma.control = cpu_to_be32(FW_CFG_DMA_READ);
|
||||
|
||||
/*
|
||||
* writting FW_CFG_INVALID will cause read operation to resume at
|
||||
* last offset, otherwise read will start at offset 0
|
||||
*/
|
||||
if (entry != FW_CFG_INVALID)
|
||||
dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
|
||||
|
||||
barrier();
|
||||
|
||||
debug("qemu_fwcfg_read_entry_dma: entry 0x%x, size %u address %p, control 0x%x\n",
|
||||
entry, size, address, be32_to_cpu(dma.control));
|
||||
|
||||
fwcfg_arch_ops->arch_read_dma(&dma);
|
||||
}
|
||||
|
||||
bool qemu_fwcfg_present(void)
|
||||
{
|
||||
return fwcfg_present;
|
||||
}
|
||||
|
||||
bool qemu_fwcfg_dma_present(void)
|
||||
{
|
||||
return fwcfg_dma_present;
|
||||
}
|
||||
|
||||
void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address)
|
||||
{
|
||||
if (fwcfg_dma_present)
|
||||
qemu_fwcfg_read_entry_dma(entry, length, address);
|
||||
else
|
||||
qemu_fwcfg_read_entry_pio(entry, length, address);
|
||||
}
|
||||
|
||||
int qemu_fwcfg_online_cpus(void)
|
||||
{
|
||||
uint16_t nb_cpus;
|
||||
|
||||
if (!fwcfg_present)
|
||||
return -ENODEV;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus);
|
||||
|
||||
return le16_to_cpu(nb_cpus);
|
||||
}
|
||||
|
||||
int qemu_fwcfg_read_firmware_list(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t count;
|
||||
struct fw_file *file;
|
||||
struct list_head *entry;
|
||||
|
||||
/* don't read it twice */
|
||||
if (!list_empty(&fw_list))
|
||||
return 0;
|
||||
|
||||
qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count);
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
count = be32_to_cpu(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
file = malloc(sizeof(*file));
|
||||
if (!file) {
|
||||
printf("error: allocating resource\n");
|
||||
goto err;
|
||||
}
|
||||
qemu_fwcfg_read_entry(FW_CFG_INVALID,
|
||||
sizeof(struct fw_cfg_file), &file->cfg);
|
||||
file->addr = 0;
|
||||
list_add_tail(&file->list, &fw_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
list_for_each(entry, &fw_list) {
|
||||
file = list_entry(entry, struct fw_file, list);
|
||||
free(file);
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
struct fw_file *qemu_fwcfg_find_file(const char *name)
|
||||
{
|
||||
int ret;
|
||||
struct list_head *entry;
|
||||
struct fw_file *file;
|
||||
|
||||
/* make sure fw_list is loaded */
|
||||
ret = qemu_fwcfg_read_firmware_list();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each(entry, &fw_list) {
|
||||
file = list_entry(entry, struct fw_file, list);
|
||||
printf("%-56s\n", file->cfg.name);
|
||||
if (!strcmp(file->cfg.name, name))
|
||||
return file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void qemu_fwcfg_init(void)
|
||||
struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter)
|
||||
{
|
||||
fwcfg_present = qemu_fwcfg_present();
|
||||
if (fwcfg_present)
|
||||
fwcfg_dma_present = qemu_fwcfg_dma_present();
|
||||
iter->entry = fw_list.next;
|
||||
return list_entry((struct list_head *)iter->entry,
|
||||
struct fw_file, list);
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_list(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter)
|
||||
{
|
||||
if (qemu_fwcfg_list_firmware() < 0)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
return 0;
|
||||
iter->entry = ((struct list_head *)iter->entry)->next;
|
||||
return list_entry((struct list_head *)iter->entry,
|
||||
struct fw_file, list);
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_cpus(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter)
|
||||
{
|
||||
int ret = qemu_fwcfg_online_cpus();
|
||||
if (ret < 0) {
|
||||
printf("QEMU fw_cfg interface not found\n");
|
||||
return CMD_RET_FAILURE;
|
||||
return iter->entry == &fw_list;
|
||||
}
|
||||
|
||||
void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops)
|
||||
{
|
||||
uint32_t qemu;
|
||||
uint32_t dma_enabled;
|
||||
|
||||
fwcfg_present = false;
|
||||
fwcfg_dma_present = false;
|
||||
fwcfg_arch_ops = NULL;
|
||||
|
||||
if (!ops || !ops->arch_read_pio || !ops->arch_read_dma)
|
||||
return;
|
||||
fwcfg_arch_ops = ops;
|
||||
|
||||
qemu_fwcfg_read_entry_pio(FW_CFG_SIGNATURE, 4, &qemu);
|
||||
if (be32_to_cpu(qemu) == QEMU_FW_CFG_SIGNATURE)
|
||||
fwcfg_present = true;
|
||||
|
||||
if (fwcfg_present) {
|
||||
qemu_fwcfg_read_entry_pio(FW_CFG_ID, 1, &dma_enabled);
|
||||
if (dma_enabled & FW_CFG_DMA_ENABLED)
|
||||
fwcfg_dma_present = true;
|
||||
}
|
||||
|
||||
printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_fwcfg_do_load(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
char *env;
|
||||
void *load_addr;
|
||||
void *initrd_addr;
|
||||
|
||||
env = getenv("loadaddr");
|
||||
load_addr = env ?
|
||||
(void *)simple_strtoul(env, NULL, 16) :
|
||||
(void *)CONFIG_LOADADDR;
|
||||
|
||||
env = getenv("ramdiskaddr");
|
||||
initrd_addr = env ?
|
||||
(void *)simple_strtoul(env, NULL, 16) :
|
||||
(void *)CONFIG_RAMDISK_ADDR;
|
||||
|
||||
if (argc == 2) {
|
||||
load_addr = (void *)simple_strtoul(argv[0], NULL, 16);
|
||||
initrd_addr = (void *)simple_strtoul(argv[1], NULL, 16);
|
||||
} else if (argc == 1) {
|
||||
load_addr = (void *)simple_strtoul(argv[0], NULL, 16);
|
||||
}
|
||||
|
||||
return qemu_fwcfg_setup_kernel(load_addr, initrd_addr);
|
||||
}
|
||||
|
||||
static cmd_tbl_t fwcfg_commands[] = {
|
||||
U_BOOT_CMD_MKENT(list, 0, 1, qemu_fwcfg_do_list, "", ""),
|
||||
U_BOOT_CMD_MKENT(cpus, 0, 1, qemu_fwcfg_do_cpus, "", ""),
|
||||
U_BOOT_CMD_MKENT(load, 2, 1, qemu_fwcfg_do_load, "", ""),
|
||||
};
|
||||
|
||||
static int do_qemu_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int ret;
|
||||
cmd_tbl_t *fwcfg_cmd;
|
||||
|
||||
if (!fwcfg_present) {
|
||||
printf("QEMU fw_cfg interface not found\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
fwcfg_cmd = find_cmd_tbl(argv[1], fwcfg_commands,
|
||||
ARRAY_SIZE(fwcfg_commands));
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if (!fwcfg_cmd || argc > fwcfg_cmd->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ret = fwcfg_cmd->cmd(fwcfg_cmd, flag, argc, argv);
|
||||
|
||||
return cmd_process_error(fwcfg_cmd, ret);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
qfw, 4, 1, do_qemu_fw,
|
||||
"QEMU firmware interface",
|
||||
"<command>\n"
|
||||
" - list : print firmware(s) currently loaded\n"
|
||||
" - cpus : print online cpu number\n"
|
||||
" - load <kernel addr> <initrd addr> : load kernel and initrd (if any), and setup for zboot\n"
|
||||
)
|
|
@ -40,6 +40,6 @@
|
|||
#define CONFIG_X86EMU_RAW_IO
|
||||
|
||||
#define CONFIG_ENV_SECT_SIZE 0x1000
|
||||
#define CONFIG_ENV_OFFSET 0x007fe000
|
||||
#define CONFIG_ENV_OFFSET 0x006ef000
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
|
|
@ -193,14 +193,19 @@
|
|||
#define CONFIG_HOSTNAME x86
|
||||
#define CONFIG_BOOTFILE "bzImage"
|
||||
#define CONFIG_LOADADDR 0x1000000
|
||||
#define CONFIG_RAMDISK_ADDR 0x4000000
|
||||
#define CONFIG_RAMDISK_ADDR 0x4000000
|
||||
#ifdef CONFIG_GENERATE_ACPI_TABLE
|
||||
#define CONFIG_OTHBOOTARGS "othbootargs=\0"
|
||||
#else
|
||||
#define CONFIG_OTHBOOTARGS "othbootargs=acpi=off\0"
|
||||
#endif
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
CONFIG_STD_DEVICES_SETTINGS \
|
||||
"pciconfighost=1\0" \
|
||||
"netdev=eth0\0" \
|
||||
"consoledev=ttyS0\0" \
|
||||
"othbootargs=acpi=off\0" \
|
||||
CONFIG_OTHBOOTARGS \
|
||||
"ramdiskaddr=0x4000000\0" \
|
||||
"ramdiskfile=initramfs.gz\0"
|
||||
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
#ifndef __FW_CFG__
|
||||
#define __FW_CFG__
|
||||
|
||||
#define FW_CONTROL_PORT 0x510
|
||||
#define FW_DATA_PORT 0x511
|
||||
#define FW_DMA_PORT_LOW 0x514
|
||||
#define FW_DMA_PORT_HIGH 0x518
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
enum qemu_fwcfg_items {
|
||||
|
@ -87,12 +82,22 @@ struct fw_file {
|
|||
struct list_head list; /* list node to link to fw_list */
|
||||
};
|
||||
|
||||
struct fw_cfg_file_iter {
|
||||
struct list_head *entry; /* structure to iterate file list */
|
||||
};
|
||||
|
||||
struct fw_cfg_dma_access {
|
||||
__be32 control;
|
||||
__be32 length;
|
||||
__be64 address;
|
||||
};
|
||||
|
||||
struct fw_cfg_arch_ops {
|
||||
void (*arch_read_pio)(uint16_t selector, uint32_t size,
|
||||
void *address);
|
||||
void (*arch_read_dma)(struct fw_cfg_dma_access *dma);
|
||||
};
|
||||
|
||||
struct bios_linker_entry {
|
||||
__le32 command;
|
||||
union {
|
||||
|
@ -144,8 +149,14 @@ struct bios_linker_entry {
|
|||
|
||||
/**
|
||||
* Initialize QEMU fw_cfg interface
|
||||
*
|
||||
* @ops: arch specific read operations
|
||||
*/
|
||||
void qemu_fwcfg_init(void);
|
||||
void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops);
|
||||
|
||||
void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address);
|
||||
int qemu_fwcfg_read_firmware_list(void);
|
||||
struct fw_file *qemu_fwcfg_find_file(const char *name);
|
||||
|
||||
/**
|
||||
* Get system cpu number
|
||||
|
@ -154,4 +165,12 @@ void qemu_fwcfg_init(void);
|
|||
*/
|
||||
int qemu_fwcfg_online_cpus(void);
|
||||
|
||||
/* helper functions to iterate firmware file list */
|
||||
struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter);
|
||||
struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter);
|
||||
bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter);
|
||||
|
||||
bool qemu_fwcfg_present(void);
|
||||
bool qemu_fwcfg_dma_present(void);
|
||||
|
||||
#endif
|
|
@ -323,13 +323,13 @@ $(obj)/%.S: $(src)/%.ttf
|
|||
|
||||
# ACPI
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_acpi_c_asl= ASL $@
|
||||
quiet_cmd_acpi_c_asl= ASL $<
|
||||
cmd_acpi_c_asl= \
|
||||
$(CPP) -x assembler-with-cpp -P -o $<.tmp $<; \
|
||||
iasl -p $< -tc -va $<.tmp; \
|
||||
$(CPP) -x assembler-with-cpp -P $(UBOOTINCLUDE) -o $<.tmp $<; \
|
||||
iasl -p $< -tc $<.tmp $(if $(KBUILD_VERBOSE:1=), >/dev/null); \
|
||||
mv $(patsubst %.asl,%.hex,$<) $@
|
||||
|
||||
$(obj)/%.c: $(src)/%.asl
|
||||
$(obj)/dsdt.c: $(src)/dsdt.asl
|
||||
$(call cmd,acpi_c_asl)
|
||||
|
||||
# Bzip2
|
||||
|
|
Loading…
Reference in a new issue