Merge git://git.denx.de/u-boot-x86
This commit is contained in:
commit
79c884d7e4
1
Makefile
1
Makefile
@ -1040,6 +1040,7 @@ IFDTOOL_FLAGS = -f 0:$(objtree)/u-boot.dtb
|
||||
IFDTOOL_FLAGS += -m 0x$(shell $(NM) u-boot |grep _dt_ucode_base_size |cut -d' ' -f1)
|
||||
IFDTOOL_FLAGS += -U $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot.bin
|
||||
IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin
|
||||
IFDTOOL_FLAGS += -C
|
||||
|
||||
ifneq ($(CONFIG_HAVE_INTEL_ME),)
|
||||
IFDTOOL_ME_FLAGS = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin
|
||||
|
@ -229,9 +229,16 @@ config FSP_TEMP_RAM_ADDR
|
||||
depends on HAVE_FSP
|
||||
default 0x2000000
|
||||
help
|
||||
Stack top address which is used in FspInit after DRAM is ready and
|
||||
Stack top address which is used in fsp_init() after DRAM is ready and
|
||||
CAR is disabled.
|
||||
|
||||
config FSP_SYS_MALLOC_F_LEN
|
||||
hex
|
||||
depends on HAVE_FSP
|
||||
default 0x100000
|
||||
help
|
||||
Additional size of malloc() pool before relocation.
|
||||
|
||||
config SMP
|
||||
bool "Enable Symmetric Multiprocessing"
|
||||
default n
|
||||
@ -307,10 +314,10 @@ config VGA_BIOS_ADDR
|
||||
0x90000 from the beginning of a 1MB flash device.
|
||||
|
||||
menu "System tables"
|
||||
depends on !EFI && !SYS_COREBOOT
|
||||
|
||||
config GENERATE_PIRQ_TABLE
|
||||
bool "Generate a PIRQ table"
|
||||
depends on !EFI
|
||||
default n
|
||||
help
|
||||
Generate a PIRQ routing table for this board. The PIRQ routing table
|
||||
@ -321,7 +328,6 @@ config GENERATE_PIRQ_TABLE
|
||||
|
||||
config GENERATE_SFI_TABLE
|
||||
bool "Generate a SFI (Simple Firmware Interface) table"
|
||||
depends on !EFI
|
||||
help
|
||||
The Simple Firmware Interface (SFI) provides a lightweight method
|
||||
for platform firmware to pass information to the operating system
|
||||
@ -336,7 +342,6 @@ config GENERATE_SFI_TABLE
|
||||
|
||||
config GENERATE_MP_TABLE
|
||||
bool "Generate an MP (Multi-Processor) table"
|
||||
depends on !EFI
|
||||
default n
|
||||
help
|
||||
Generate an MP (Multi-Processor) table for this board. The MP table
|
||||
@ -344,6 +349,15 @@ config GENERATE_MP_TABLE
|
||||
multiprocessing as well as symmetric I/O interrupt handling with
|
||||
the local APIC and I/O APIC.
|
||||
|
||||
config GENERATE_ACPI_TABLE
|
||||
bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
|
||||
default n
|
||||
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.
|
||||
|
||||
endmenu
|
||||
|
||||
config MAX_PIRQ_LINKS
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <pci_ids.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/fsp/fsp_support.h>
|
||||
|
||||
static struct pci_device_id mmc_supported[] = {
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO },
|
||||
@ -41,14 +40,9 @@ int arch_cpu_init(void)
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ll_boot_init())
|
||||
return 0;
|
||||
ret = pirq_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return fsp_init_phase_pci();
|
||||
return pirq_init();
|
||||
}
|
||||
#endif
|
||||
|
@ -7,14 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/init_helpers.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/zimage.h>
|
||||
#include <asm/arch/sysinfo.h>
|
||||
#include <asm/arch/tables.h>
|
||||
|
||||
@ -22,9 +15,10 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
||||
{
|
||||
unsigned num_entries;
|
||||
int i;
|
||||
|
||||
unsigned num_entries = min((unsigned)lib_sysinfo.n_memranges, max_entries);
|
||||
num_entries = min((unsigned)lib_sysinfo.n_memranges, max_entries);
|
||||
if (num_entries < lib_sysinfo.n_memranges) {
|
||||
printf("Warning: Limiting e820 map to %d entries.\n",
|
||||
num_entries);
|
||||
@ -34,8 +28,18 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
||||
|
||||
entries[i].addr = memrange->base;
|
||||
entries[i].size = memrange->size;
|
||||
entries[i].type = memrange->type;
|
||||
|
||||
/*
|
||||
* coreboot has some extensions (type 6 & 16) to the E820 types.
|
||||
* When we detect this, mark it as E820_RESERVED.
|
||||
*/
|
||||
if (memrange->type == CB_MEM_VENDOR_RSVD ||
|
||||
memrange->type == CB_MEM_TABLE)
|
||||
entries[i].type = E820_RESERVED;
|
||||
else
|
||||
entries[i].type = memrange->type;
|
||||
}
|
||||
|
||||
return num_entries;
|
||||
}
|
||||
|
||||
@ -90,15 +94,15 @@ int dram_init(void)
|
||||
struct memrange *memrange = &lib_sysinfo.memrange[i];
|
||||
unsigned long long end = memrange->base + memrange->size;
|
||||
|
||||
if (memrange->type == CB_MEM_RAM && end > ram_size &&
|
||||
memrange->base < (1ULL << 32))
|
||||
ram_size = end;
|
||||
if (memrange->type == CB_MEM_RAM && end > ram_size)
|
||||
ram_size += memrange->size;
|
||||
}
|
||||
|
||||
gd->ram_size = ram_size;
|
||||
if (ram_size == 0)
|
||||
return -1;
|
||||
|
||||
return calculate_relocation_address();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dram_init_banksize(void)
|
||||
@ -109,8 +113,7 @@ void dram_init_banksize(void)
|
||||
for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) {
|
||||
struct memrange *memrange = &lib_sysinfo.memrange[i];
|
||||
|
||||
if (memrange->type == CB_MEM_RAM &&
|
||||
memrange->base < (1ULL << 32)) {
|
||||
if (memrange->type == CB_MEM_RAM) {
|
||||
gd->bd->bi_dram[j].start = memrange->base;
|
||||
gd->bd->bi_dram[j].size = memrange->size;
|
||||
j++;
|
||||
|
@ -8,4 +8,5 @@ ifndef CONFIG_EFI_STUB
|
||||
obj-y += car.o dram.o
|
||||
endif
|
||||
obj-y += qemu.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
|
176
arch/x86/cpu/qemu/acpi.c
Normal file
176
arch/x86/cpu/qemu/acpi.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/acpi_table.h>
|
||||
#include <asm/ioapic.h>
|
||||
#include <asm/tables.h>
|
||||
|
||||
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
|
||||
void *dsdt)
|
||||
{
|
||||
acpi_header_t *header = &(fadt->header);
|
||||
u16 pmbase;
|
||||
|
||||
pci_dev_t bdf = PCI_BDF(0, 0x1f, 0);
|
||||
pci_read_config_word(bdf, 0x40, &pmbase);
|
||||
|
||||
/*
|
||||
* TODO(saket.sinha89@gmail.com): wrong value
|
||||
* of pmbase by above function. Hard-coding it to
|
||||
* correct value. Since no PCI register is
|
||||
* programmed Power Management Interface is
|
||||
* not working
|
||||
*/
|
||||
pmbase = 0x0600;
|
||||
|
||||
memset((void *)fadt, 0, sizeof(struct acpi_fadt));
|
||||
memcpy(header->signature, "FACP", 4);
|
||||
header->length = sizeof(struct acpi_fadt);
|
||||
header->revision = 3;
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
header->asl_compiler_revision = 0;
|
||||
|
||||
fadt->firmware_ctrl = (unsigned long) facs;
|
||||
fadt->dsdt = (unsigned long) dsdt;
|
||||
fadt->model = 0x00;
|
||||
fadt->preferred_pm_profile = PM_MOBILE;
|
||||
fadt->sci_int = 0x9;
|
||||
fadt->smi_cmd = 0;
|
||||
fadt->acpi_enable = 0;
|
||||
fadt->acpi_disable = 0;
|
||||
fadt->s4bios_req = 0x0;
|
||||
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;
|
||||
/*
|
||||
* Upper word is reserved and
|
||||
* Linux complains about 32 bit
|
||||
*/
|
||||
fadt->pm1_cnt_len = 2;
|
||||
fadt->pm2_cnt_len = 1;
|
||||
fadt->pm_tmr_len = 4;
|
||||
fadt->gpe0_blk_len = 16;
|
||||
fadt->gpe1_blk_len = 0;
|
||||
fadt->gpe1_base = 0;
|
||||
fadt->cst_cnt = 0;
|
||||
fadt->p_lvl2_lat = 1;
|
||||
fadt->p_lvl3_lat = 0x39;
|
||||
fadt->flush_size = 0;
|
||||
fadt->flush_stride = 0;
|
||||
fadt->duty_offset = 1;
|
||||
fadt->duty_width = 3;
|
||||
fadt->day_alrm = 0xd;
|
||||
fadt->mon_alrm = 0x00;
|
||||
fadt->century = 0x32;
|
||||
fadt->iapc_boot_arch = 0x00;
|
||||
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
|
||||
ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
|
||||
ACPI_FADT_DOCKING_SUPPORTED | 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.resv = 0;
|
||||
fadt->reset_reg.addrl = 0xcf9;
|
||||
fadt->reset_reg.addrh = 0;
|
||||
fadt->reset_value = 0x06;
|
||||
/*
|
||||
* Set X_FIRMWARE_CTRL only if FACS is
|
||||
* above 4GB. If X_FIRMWARE_CTRL is set,
|
||||
* then FIRMWARE_CTRL must be zero
|
||||
*/
|
||||
fadt->x_firmware_ctl_l = 0;
|
||||
fadt->x_firmware_ctl_h = 0;
|
||||
fadt->x_dsdt_l = (unsigned long)dsdt;
|
||||
fadt->x_dsdt_h = 0;
|
||||
fadt->x_pm1a_evt_blk.space_id = 1;
|
||||
fadt->x_pm1a_evt_blk.bit_width = 32;
|
||||
fadt->x_pm1a_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_evt_blk.resv = 0;
|
||||
fadt->x_pm1a_evt_blk.addrl = pmbase;
|
||||
fadt->x_pm1a_evt_blk.addrh = 0x0;
|
||||
fadt->x_pm1b_evt_blk.space_id = 0;
|
||||
fadt->x_pm1b_evt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_evt_blk.resv = 0;
|
||||
fadt->x_pm1b_evt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_evt_blk.addrh = 0x0;
|
||||
fadt->x_pm1a_cnt_blk.space_id = 1;
|
||||
/*
|
||||
* Upper word is reserved and
|
||||
* Linux complains about 32 bit
|
||||
*/
|
||||
fadt->x_pm1a_cnt_blk.bit_width = 16;
|
||||
fadt->x_pm1a_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_cnt_blk.resv = 0;
|
||||
fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
|
||||
fadt->x_pm1a_cnt_blk.addrh = 0x0;
|
||||
fadt->x_pm1b_cnt_blk.space_id = 0;
|
||||
fadt->x_pm1b_cnt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_cnt_blk.resv = 0;
|
||||
fadt->x_pm1b_cnt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_cnt_blk.addrh = 0x0;
|
||||
fadt->x_pm2_cnt_blk.space_id = 1;
|
||||
fadt->x_pm2_cnt_blk.bit_width = 8;
|
||||
fadt->x_pm2_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm2_cnt_blk.resv = 0;
|
||||
fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
|
||||
fadt->x_pm2_cnt_blk.addrh = 0x0;
|
||||
fadt->x_pm_tmr_blk.space_id = 1;
|
||||
fadt->x_pm_tmr_blk.bit_width = 32;
|
||||
fadt->x_pm_tmr_blk.bit_offset = 0;
|
||||
fadt->x_pm_tmr_blk.resv = 0;
|
||||
fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
|
||||
fadt->x_pm_tmr_blk.addrh = 0x0;
|
||||
fadt->x_gpe0_blk.space_id = 1;
|
||||
fadt->x_gpe0_blk.bit_width = 128;
|
||||
fadt->x_gpe0_blk.bit_offset = 0;
|
||||
fadt->x_gpe0_blk.resv = 0;
|
||||
fadt->x_gpe0_blk.addrl = pmbase + 0x20;
|
||||
fadt->x_gpe0_blk.addrh = 0x0;
|
||||
fadt->x_gpe1_blk.space_id = 0;
|
||||
fadt->x_gpe1_blk.bit_width = 0;
|
||||
fadt->x_gpe1_blk.bit_offset = 0;
|
||||
fadt->x_gpe1_blk.resv = 0;
|
||||
fadt->x_gpe1_blk.addrl = 0x0;
|
||||
fadt->x_gpe1_blk.addrh = 0x0;
|
||||
|
||||
header->checksum = table_compute_checksum((void *)fadt, header->length);
|
||||
}
|
||||
|
||||
unsigned long acpi_fill_madt(unsigned long current)
|
||||
{
|
||||
/* create all subtables for processors */
|
||||
current = acpi_create_madt_lapics(current);
|
||||
|
||||
/*
|
||||
* TODO(saket.sinha89@gmail.com): get these
|
||||
* IRQ values from device tree
|
||||
*/
|
||||
current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
|
||||
2, IO_APIC_ADDR, 0);
|
||||
current += acpi_create_madt_irqoverride(
|
||||
(struct acpi_madt_irqoverride *)current, 0, 0, 2, 0);
|
||||
current += acpi_create_madt_irqoverride(
|
||||
(struct acpi_madt_irqoverride *)current, 0, 9, 9, 0xd);
|
||||
current += acpi_create_madt_irqoverride(
|
||||
(struct acpi_madt_irqoverride *)current, 0, 0xd, 0xd, 0xd);
|
||||
acpi_create_madt_lapic_nmi(
|
||||
(struct acpi_madt_lapic_nmi *)current, 0, 0, 0);
|
||||
|
||||
return current;
|
||||
}
|
80
arch/x86/cpu/qemu/acpi/cpu-hotplug.asl
Normal file
80
arch/x86/cpu/qemu/acpi/cpu-hotplug.asl
Normal file
@ -0,0 +1,80 @@
|
||||
/* CPU hotplug */
|
||||
|
||||
Scope(\_SB) {
|
||||
/* Objects filled in by run-time generated SSDT */
|
||||
External(NTFY, MethodObj)
|
||||
External(CPON, PkgObj)
|
||||
|
||||
/* Methods called by run-time generated SSDT Processor objects */
|
||||
Method(CPMA, 1, NotSerialized) {
|
||||
/*
|
||||
* _MAT method - create an madt apic buffer
|
||||
* Arg0 = Processor ID = Local APIC ID
|
||||
* Local0 = CPON flag for this cpu
|
||||
*/
|
||||
Store(DerefOf(Index(CPON, Arg0)), Local0)
|
||||
/* Local1 = Buffer (in madt apic form) to return */
|
||||
Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
|
||||
/* Update the processor id, lapic id, and enable/disable status */
|
||||
Store(Arg0, Index(Local1, 2))
|
||||
Store(Arg0, Index(Local1, 3))
|
||||
Store(Local0, Index(Local1, 4))
|
||||
Return (Local1)
|
||||
}
|
||||
Method(CPST, 1, NotSerialized) {
|
||||
/*
|
||||
* _STA method - return ON status of cpu
|
||||
* Arg0 = Processor ID = Local APIC ID
|
||||
* Local0 = CPON flag for this cpu
|
||||
*/
|
||||
Store(DerefOf(Index(CPON, Arg0)), Local0)
|
||||
If (Local0) {
|
||||
Return (0xf)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
Method(CPEJ, 2, NotSerialized) {
|
||||
/* _EJ0 method - eject callback */
|
||||
Sleep(200)
|
||||
}
|
||||
|
||||
/* CPU hotplug notify method */
|
||||
OperationRegion(PRST, SystemIO, 0xaf00, 32)
|
||||
Field(PRST, ByteAcc, NoLock, Preserve) {
|
||||
PRS, 256
|
||||
}
|
||||
Method(PRSC, 0) {
|
||||
/* Local5 = active cpu bitmap */
|
||||
Store(PRS, Local5)
|
||||
/* Local2 = last read byte from bitmap */
|
||||
Store(Zero, Local2)
|
||||
/* Local0 = Processor ID / APIC ID iterator */
|
||||
Store(Zero, Local0)
|
||||
While (LLess(Local0, SizeOf(CPON))) {
|
||||
/* Local1 = CPON flag for this cpu */
|
||||
Store(DerefOf(Index(CPON, Local0)), Local1)
|
||||
If (And(Local0, 0x07)) {
|
||||
/* Shift down previously read bitmap byte */
|
||||
ShiftRight(Local2, 1, Local2)
|
||||
} Else {
|
||||
/* Read next byte from cpu bitmap */
|
||||
Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
|
||||
}
|
||||
/* Local3 = active state for this cpu */
|
||||
Store(And(Local2, 1), Local3)
|
||||
|
||||
If (LNotEqual(Local1, Local3)) {
|
||||
/* State change - update CPON with new state */
|
||||
Store(Local3, Index(CPON, Local0))
|
||||
/* Do CPU notify */
|
||||
If (LEqual(Local3, 1)) {
|
||||
NTFY(Local0, 1)
|
||||
} Else {
|
||||
NTFY(Local0, 3)
|
||||
}
|
||||
}
|
||||
Increment(Local0)
|
||||
}
|
||||
}
|
||||
}
|
25
arch/x86/cpu/qemu/acpi/dbug.asl
Normal file
25
arch/x86/cpu/qemu/acpi/dbug.asl
Normal file
@ -0,0 +1,25 @@
|
||||
/* Debugging */
|
||||
|
||||
Scope(\) {
|
||||
/* Debug Output */
|
||||
OperationRegion(DBG, SystemIO, 0x0402, 0x01)
|
||||
Field(DBG, ByteAcc, NoLock, Preserve) {
|
||||
DBGB, 8,
|
||||
}
|
||||
/*
|
||||
* Debug method - use this method to send output to the QEMU
|
||||
* BIOS debug port. This method handles strings, integers,
|
||||
* and buffers. For example: DBUG("abc") DBUG(0x123)
|
||||
*/
|
||||
Method(DBUG, 1) {
|
||||
ToHexString(Arg0, Local0)
|
||||
ToBuffer(Local0, Local0)
|
||||
Subtract(SizeOf(Local0), 1, Local1)
|
||||
Store(Zero, Local2)
|
||||
While (LLess(Local2, Local1)) {
|
||||
Store(DerefOf(Index(Local0, Local2)), DBGB)
|
||||
Increment(Local2)
|
||||
}
|
||||
Store(0x0a, dbgb)
|
||||
}
|
||||
}
|
31
arch/x86/cpu/qemu/acpi/hpet.asl
Normal file
31
arch/x86/cpu/qemu/acpi/hpet.asl
Normal file
@ -0,0 +1,31 @@
|
||||
/* HPET */
|
||||
|
||||
Scope(\_SB) {
|
||||
Device(HPET) {
|
||||
Name(_HID, EISAID("PNP0103"))
|
||||
Name(_UID, 0)
|
||||
OperationRegion(HPTM, SystemMemory, 0xfed00000, 0x400)
|
||||
Field(HPTM, DWordAcc, Lock, Preserve) {
|
||||
VEND, 32,
|
||||
PRD, 32,
|
||||
}
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Store(VEND, Local0)
|
||||
Store(PRD, Local1)
|
||||
ShiftRight(Local0, 16, Local0)
|
||||
If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
|
||||
Return (0x0)
|
||||
}
|
||||
If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
|
||||
Return (0x0)
|
||||
}
|
||||
Return (0x0f)
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
Memory32Fixed(ReadOnly,
|
||||
0xfed00000, /* Address Base */
|
||||
0x00000400, /* Address Length */
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
102
arch/x86/cpu/qemu/acpi/isa.asl
Normal file
102
arch/x86/cpu/qemu/acpi/isa.asl
Normal file
@ -0,0 +1,102 @@
|
||||
/* Common legacy ISA style devices. */
|
||||
Scope(\_SB.PCI0.ISA) {
|
||||
|
||||
Device(RTC) {
|
||||
Name(_HID, EisaId("PNP0B00"))
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
|
||||
IRQNoFlags() { 8 }
|
||||
IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
|
||||
})
|
||||
}
|
||||
|
||||
Device(KBD) {
|
||||
Name(_HID, EisaId("PNP0303"))
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Return (0x0f)
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
|
||||
IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
|
||||
IRQNoFlags() { 1 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(MOU) {
|
||||
Name(_HID, EisaId("PNP0F13"))
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Return (0x0f)
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IRQNoFlags() { 12 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(FDC0) {
|
||||
Name(_HID, EisaId("PNP0700"))
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Store(FDEN, Local0)
|
||||
If (LEqual(Local0, 0)) {
|
||||
Return (0x00)
|
||||
} Else {
|
||||
Return (0x0f)
|
||||
}
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x03f2, 0x03f2, 0x00, 0x04)
|
||||
IO(Decode16, 0x03f7, 0x03f7, 0x00, 0x01)
|
||||
IRQNoFlags() { 6 }
|
||||
DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(LPT) {
|
||||
Name(_HID, EisaId("PNP0400"))
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Store(LPEN, Local0)
|
||||
If (LEqual(Local0, 0)) {
|
||||
Return (0x00)
|
||||
} Else {
|
||||
Return (0x0f)
|
||||
}
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
|
||||
IRQNoFlags() { 7 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(COM1) {
|
||||
Name(_HID, EisaId("PNP0501"))
|
||||
Name(_UID, 0x01)
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Store(CAEN, Local0)
|
||||
If (LEqual(Local0, 0)) {
|
||||
Return (0x00)
|
||||
} Else {
|
||||
Return (0x0f)
|
||||
}
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x03f8, 0x03f8, 0x00, 0x08)
|
||||
IRQNoFlags() { 4 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(COM2) {
|
||||
Name(_HID, EisaId("PNP0501"))
|
||||
Name(_UID, 0x02)
|
||||
Method(_STA, 0, NotSerialized) {
|
||||
Store(CBEN, Local0)
|
||||
If (LEqual(Local0, 0)) {
|
||||
Return (0x00)
|
||||
} Else {
|
||||
Return (0x0f)
|
||||
}
|
||||
}
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, 0x02f8, 0x02f8, 0x00, 0x08)
|
||||
IRQNoFlags() { 3 }
|
||||
})
|
||||
}
|
||||
}
|
61
arch/x86/cpu/qemu/acpi/pci-crs.asl
Normal file
61
arch/x86/cpu/qemu/acpi/pci-crs.asl
Normal file
@ -0,0 +1,61 @@
|
||||
/* PCI CRS (current resources) definition. */
|
||||
Scope(\_SB.PCI0) {
|
||||
|
||||
Name(CRES, ResourceTemplate() {
|
||||
WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
|
||||
0x0000, /* Address Space Granularity */
|
||||
0x0000, /* Address Range Minimum */
|
||||
0x00ff, /* Address Range Maximum */
|
||||
0x0000, /* Address Translation Offset */
|
||||
0x0100, /* Address Length */
|
||||
,, )
|
||||
IO(Decode16,
|
||||
0x0cf8, /* Address Range Minimum */
|
||||
0x0cf8, /* Address Range Maximum */
|
||||
0x01, /* Address Alignment */
|
||||
0x08, /* Address Length */
|
||||
)
|
||||
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, /* Address Space Granularity */
|
||||
0x0000, /* Address Range Minimum */
|
||||
0x0cf7, /* Address Range Maximum */
|
||||
0x0000, /* Address Translation Offset */
|
||||
0x0cf8, /* Address Length */
|
||||
,, , TypeStatic)
|
||||
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, /* Address Space Granularity */
|
||||
0x0d00, /* Address Range Minimum */
|
||||
0xffff, /* Address Range Maximum */
|
||||
0x0000, /* Address Translation Offset */
|
||||
0xf300, /* Address Length */
|
||||
,, , TypeStatic)
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
|
||||
0x00000000, /* Address Space Granularity */
|
||||
0x000a0000, /* Address Range Minimum */
|
||||
0x000bffff, /* Address Range Maximum */
|
||||
0x00000000, /* Address Translation Offset */
|
||||
0x00020000, /* Address Length */
|
||||
,, , AddressRangeMemory, TypeStatic)
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
|
||||
0x00000000, /* Address Space Granularity */
|
||||
0xe0000000, /* Address Range Minimum */
|
||||
0xfebfffff, /* Address Range Maximum */
|
||||
0x00000000, /* Address Translation Offset */
|
||||
0x1ec00000, /* Address Length */
|
||||
,, PW32, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
|
||||
Name(CR64, ResourceTemplate() {
|
||||
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
|
||||
0x00000000, /* Address Space Granularity */
|
||||
0x80000000, /* Address Range Minimum */
|
||||
0xffffffff, /* Address Range Maximum */
|
||||
0x00000000, /* Address Translation Offset */
|
||||
0x80000000, /* Address Length */
|
||||
,, PW64, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
|
||||
Method(_CRS, 0) {
|
||||
Return (CRES)
|
||||
}
|
||||
}
|
412
arch/x86/cpu/qemu/dsdt.asl
Normal file
412
arch/x86/cpu/qemu/dsdt.asl
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* QEMU ACPI DSDT ASL definition
|
||||
*
|
||||
* Copyright (c) 2006 Fabrice Bellard
|
||||
*
|
||||
* Copyright (c) 2010 Isaku Yamahata
|
||||
* yamahata at valinux co jp
|
||||
* Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
|
||||
*/
|
||||
|
||||
DefinitionBlock (
|
||||
"dsdt.aml", /* Output Filename */
|
||||
"DSDT", /* Signature */
|
||||
0x01, /* DSDT Compliance Revision */
|
||||
"UBOO", /* OEMID */
|
||||
"UBOOT ", /* TABLE ID */
|
||||
0x2 /* OEM Revision */
|
||||
)
|
||||
{
|
||||
|
||||
#include "acpi/dbug.asl"
|
||||
|
||||
Scope(\_SB) {
|
||||
OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
|
||||
OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
|
||||
Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
|
||||
PCIB, 8,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* PCI Bus definition */
|
||||
|
||||
Scope(\_SB) {
|
||||
Device(PCI0) {
|
||||
Name(_HID, EisaId("PNP0A08"))
|
||||
Name(_CID, EisaId("PNP0A03"))
|
||||
Name(_ADR, 0x00)
|
||||
Name(_UID, 1)
|
||||
|
||||
/* _OSC: based on sample of ACPI3.0b spec */
|
||||
Name(SUPP, 0) /* PCI _OSC Support Field value */
|
||||
Name(CTRL, 0) /* PCI _OSC Control Field value */
|
||||
Method(_OSC, 4) {
|
||||
/* Create DWORD-addressable fields from Capabilities Buffer */
|
||||
CreateDWordField(Arg3, 0, CDW1)
|
||||
|
||||
/* Check for proper UUID */
|
||||
If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
|
||||
{
|
||||
/* Create DWORD-addressable fields from Capabilities Buffer */
|
||||
CreateDWordField(Arg3, 4, CDW2)
|
||||
CreateDWordField(Arg3, 8, CDW3)
|
||||
|
||||
/* Save Capabilities DWORD2 & 3 */
|
||||
Store(CDW2, SUPP)
|
||||
Store(CDW3, CTRL)
|
||||
|
||||
/*
|
||||
* Always allow native PME, AER (no dependencies)
|
||||
* Never allow SHPC (no SHPC controller in this system)
|
||||
*/
|
||||
And(CTRL, 0x1d, CTRL)
|
||||
|
||||
If (LNotEqual(Arg1, One)) {
|
||||
/* Unknown revision */
|
||||
Or(CDW1, 0x08, CDW1)
|
||||
}
|
||||
If (LNotEqual(CDW3, CTRL)) {
|
||||
/* Capabilities bits were masked */
|
||||
Or(CDW1, 0x10, CDW1)
|
||||
}
|
||||
/* Update DWORD3 in the buffer */
|
||||
Store(CTRL, CDW3)
|
||||
} Else {
|
||||
Or(CDW1, 4, CDW1) /* Unrecognized UUID */
|
||||
}
|
||||
Return (Arg3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "acpi/pci-crs.asl"
|
||||
#include "acpi/hpet.asl"
|
||||
|
||||
|
||||
/* VGA */
|
||||
|
||||
Scope(\_SB.PCI0) {
|
||||
Device(VGA) {
|
||||
Name(_ADR, 0x00010000)
|
||||
Method(_S1D, 0, NotSerialized) {
|
||||
Return (0x00)
|
||||
}
|
||||
Method(_S2D, 0, NotSerialized) {
|
||||
Return (0x00)
|
||||
}
|
||||
Method(_S3D, 0, NotSerialized) {
|
||||
Return (0x00)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* LPC ISA bridge */
|
||||
|
||||
Scope(\_SB.PCI0) {
|
||||
/* PCI D31:f0 LPC ISA bridge */
|
||||
Device(ISA) {
|
||||
/* PCI D31:f0 */
|
||||
Name(_ADR, 0x001f0000)
|
||||
|
||||
/* ICH9 PCI to ISA irq remapping */
|
||||
OperationRegion(PIRQ, PCI_Config, 0x60, 0x0c)
|
||||
|
||||
OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
|
||||
Field(LPCD, AnyAcc, NoLock, Preserve) {
|
||||
COMA, 3,
|
||||
, 1,
|
||||
COMB, 3,
|
||||
|
||||
Offset(0x01),
|
||||
LPTD, 2,
|
||||
, 2,
|
||||
FDCD, 2
|
||||
}
|
||||
OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
|
||||
Field(LPCE, AnyAcc, NoLock, Preserve) {
|
||||
CAEN, 1,
|
||||
CBEN, 1,
|
||||
LPEN, 1,
|
||||
FDEN, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "acpi/isa.asl"
|
||||
|
||||
|
||||
/* PCI IRQs */
|
||||
|
||||
/* Zero => PIC mode, One => APIC Mode */
|
||||
Name(\PICF, Zero)
|
||||
Method(\_PIC, 1, NotSerialized) {
|
||||
Store(Arg0, \PICF)
|
||||
}
|
||||
|
||||
Scope(\_SB) {
|
||||
Scope(PCI0) {
|
||||
#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3) \
|
||||
Package() { nr##ffff, 0, lnk0, 0 }, \
|
||||
Package() { nr##ffff, 1, lnk1, 0 }, \
|
||||
Package() { nr##ffff, 2, lnk2, 0 }, \
|
||||
Package() { nr##ffff, 3, lnk3, 0 }
|
||||
|
||||
#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
|
||||
#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
|
||||
#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
|
||||
#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
|
||||
|
||||
#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
|
||||
#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
|
||||
#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
|
||||
#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
|
||||
|
||||
Name(PRTP, Package() {
|
||||
prt_slot_lnkE(0x0000),
|
||||
prt_slot_lnkF(0x0001),
|
||||
prt_slot_lnkG(0x0002),
|
||||
prt_slot_lnkH(0x0003),
|
||||
prt_slot_lnkE(0x0004),
|
||||
prt_slot_lnkF(0x0005),
|
||||
prt_slot_lnkG(0x0006),
|
||||
prt_slot_lnkH(0x0007),
|
||||
prt_slot_lnkE(0x0008),
|
||||
prt_slot_lnkF(0x0009),
|
||||
prt_slot_lnkG(0x000a),
|
||||
prt_slot_lnkH(0x000b),
|
||||
prt_slot_lnkE(0x000c),
|
||||
prt_slot_lnkF(0x000d),
|
||||
prt_slot_lnkG(0x000e),
|
||||
prt_slot_lnkH(0x000f),
|
||||
prt_slot_lnkE(0x0010),
|
||||
prt_slot_lnkF(0x0011),
|
||||
prt_slot_lnkG(0x0012),
|
||||
prt_slot_lnkH(0x0013),
|
||||
prt_slot_lnkE(0x0014),
|
||||
prt_slot_lnkF(0x0015),
|
||||
prt_slot_lnkG(0x0016),
|
||||
prt_slot_lnkH(0x0017),
|
||||
prt_slot_lnkE(0x0018),
|
||||
|
||||
/* INTA -> PIRQA for slot 25 - 31
|
||||
see the default value of D<N>IR */
|
||||
prt_slot_lnkA(0x0019),
|
||||
prt_slot_lnkA(0x001a),
|
||||
prt_slot_lnkA(0x001b),
|
||||
prt_slot_lnkA(0x001c),
|
||||
prt_slot_lnkA(0x001d),
|
||||
|
||||
/* PCIe->PCI bridge. use PIRQ[E-H] */
|
||||
prt_slot_lnkE(0x001e),
|
||||
|
||||
prt_slot_lnkA(0x001f)
|
||||
})
|
||||
|
||||
#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3) \
|
||||
Package() { nr##ffff, 0, gsi0, 0 }, \
|
||||
Package() { nr##ffff, 1, gsi1, 0 }, \
|
||||
Package() { nr##ffff, 2, gsi2, 0 }, \
|
||||
Package() { nr##ffff, 3, gsi3, 0 }
|
||||
|
||||
#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
|
||||
#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
|
||||
#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
|
||||
#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
|
||||
|
||||
#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
|
||||
#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
|
||||
#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
|
||||
#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
|
||||
|
||||
Name(PRTA, Package() {
|
||||
prt_slot_gsiE(0x0000),
|
||||
prt_slot_gsiF(0x0001),
|
||||
prt_slot_gsiG(0x0002),
|
||||
prt_slot_gsiH(0x0003),
|
||||
prt_slot_gsiE(0x0004),
|
||||
prt_slot_gsiF(0x0005),
|
||||
prt_slot_gsiG(0x0006),
|
||||
prt_slot_gsiH(0x0007),
|
||||
prt_slot_gsiE(0x0008),
|
||||
prt_slot_gsiF(0x0009),
|
||||
prt_slot_gsiG(0x000a),
|
||||
prt_slot_gsiH(0x000b),
|
||||
prt_slot_gsiE(0x000c),
|
||||
prt_slot_gsiF(0x000d),
|
||||
prt_slot_gsiG(0x000e),
|
||||
prt_slot_gsiH(0x000f),
|
||||
prt_slot_gsiE(0x0010),
|
||||
prt_slot_gsiF(0x0011),
|
||||
prt_slot_gsiG(0x0012),
|
||||
prt_slot_gsiH(0x0013),
|
||||
prt_slot_gsiE(0x0014),
|
||||
prt_slot_gsiF(0x0015),
|
||||
prt_slot_gsiG(0x0016),
|
||||
prt_slot_gsiH(0x0017),
|
||||
prt_slot_gsiE(0x0018),
|
||||
|
||||
/*
|
||||
* INTA -> PIRQA for slot 25 - 31, but 30
|
||||
* see the default value of D<N>IR
|
||||
*/
|
||||
prt_slot_gsiA(0x0019),
|
||||
prt_slot_gsiA(0x001a),
|
||||
prt_slot_gsiA(0x001b),
|
||||
prt_slot_gsiA(0x001c),
|
||||
prt_slot_gsiA(0x001d),
|
||||
|
||||
/* PCIe->PCI bridge. use PIRQ[E-H] */
|
||||
prt_slot_gsiE(0x001e),
|
||||
|
||||
prt_slot_gsiA(0x001f)
|
||||
})
|
||||
|
||||
Method(_PRT, 0, NotSerialized) {
|
||||
/*
|
||||
* PCI IRQ routing table,
|
||||
* example from ACPI 2.0a
|
||||
* specification, section 6.2.8.1
|
||||
* Note: we provide the same info
|
||||
* as the PCI routing table
|
||||
* of the Bochs BIOS
|
||||
*/
|
||||
If (LEqual(\PICF, Zero)) {
|
||||
Return (PRTP)
|
||||
} Else {
|
||||
Return (PRTA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
|
||||
PRQA, 8,
|
||||
PRQB, 8,
|
||||
PRQC, 8,
|
||||
PRQD, 8,
|
||||
|
||||
Offset(0x08),
|
||||
PRQE, 8,
|
||||
PRQF, 8,
|
||||
PRQG, 8,
|
||||
PRQH, 8
|
||||
}
|
||||
|
||||
Method(IQST, 1, NotSerialized) {
|
||||
/* _STA method - get status */
|
||||
If (And(0x80, Arg0)) {
|
||||
Return (0x09)
|
||||
}
|
||||
Return (0x0b)
|
||||
}
|
||||
Method(IQCR, 1, NotSerialized) {
|
||||
/* _CRS method - get current settings */
|
||||
Name(PRR0, ResourceTemplate() {
|
||||
Interrupt(, Level, ActiveHigh, Shared) { 0 }
|
||||
})
|
||||
CreateDWordField(PRR0, 0x05, PRRI)
|
||||
Store(And(Arg0, 0x0f), PRRI)
|
||||
Return (PRR0)
|
||||
}
|
||||
|
||||
#define define_link(link, uid, reg) \
|
||||
Device(link) { \
|
||||
Name(_HID, EISAID("PNP0C0F")) \
|
||||
Name(_UID, uid) \
|
||||
Name(_PRS, ResourceTemplate() { \
|
||||
Interrupt(, Level, ActiveHigh, Shared) { \
|
||||
5, 10, 11 \
|
||||
} \
|
||||
}) \
|
||||
Method(_STA, 0, NotSerialized) { \
|
||||
Return (IQST(reg)) \
|
||||
} \
|
||||
Method(_DIS, 0, NotSerialized) { \
|
||||
Or(reg, 0x80, reg) \
|
||||
} \
|
||||
Method(_CRS, 0, NotSerialized) { \
|
||||
Return (IQCR(reg)) \
|
||||
} \
|
||||
Method(_SRS, 1, NotSerialized) { \
|
||||
CreateDWordField(Arg0, 0x05, PRRI) \
|
||||
Store(PRRI, reg) \
|
||||
} \
|
||||
}
|
||||
|
||||
define_link(LNKA, 0, PRQA)
|
||||
define_link(LNKB, 1, PRQB)
|
||||
define_link(LNKC, 2, PRQC)
|
||||
define_link(LNKD, 3, PRQD)
|
||||
define_link(LNKE, 4, PRQE)
|
||||
define_link(LNKF, 5, PRQF)
|
||||
define_link(LNKG, 6, PRQG)
|
||||
define_link(LNKH, 7, PRQH)
|
||||
|
||||
#define define_gsi_link(link, uid, gsi) \
|
||||
Device(link) { \
|
||||
Name(_HID, EISAID("PNP0C0F")) \
|
||||
Name(_UID, uid) \
|
||||
Name(_PRS, ResourceTemplate() { \
|
||||
Interrupt(, Level, ActiveHigh, Shared) { \
|
||||
gsi \
|
||||
} \
|
||||
}) \
|
||||
Name(_CRS, ResourceTemplate() { \
|
||||
Interrupt(, Level, ActiveHigh, Shared) { \
|
||||
gsi \
|
||||
} \
|
||||
}) \
|
||||
Method(_SRS, 1, NotSerialized) { \
|
||||
} \
|
||||
}
|
||||
|
||||
define_gsi_link(GSIA, 0, 0x10)
|
||||
define_gsi_link(GSIB, 0, 0x11)
|
||||
define_gsi_link(GSIC, 0, 0x12)
|
||||
define_gsi_link(GSID, 0, 0x13)
|
||||
define_gsi_link(GSIE, 0, 0x14)
|
||||
define_gsi_link(GSIF, 0, 0x15)
|
||||
define_gsi_link(GSIG, 0, 0x16)
|
||||
define_gsi_link(GSIH, 0, 0x17)
|
||||
}
|
||||
|
||||
/* General purpose events */
|
||||
|
||||
Scope(\_GPE) {
|
||||
Name(_HID, "ACPI0006")
|
||||
|
||||
Method(_L00) {
|
||||
}
|
||||
Method(_L01) {
|
||||
}
|
||||
Method(_L02) {
|
||||
}
|
||||
Method(_L03) {
|
||||
}
|
||||
Method(_L04) {
|
||||
}
|
||||
Method(_L05) {
|
||||
}
|
||||
Method(_L06) {
|
||||
}
|
||||
Method(_L07) {
|
||||
}
|
||||
Method(_L08) {
|
||||
}
|
||||
Method(_L09) {
|
||||
}
|
||||
Method(_L0A) {
|
||||
}
|
||||
Method(_L0B) {
|
||||
}
|
||||
Method(_L0C) {
|
||||
}
|
||||
Method(_L0D) {
|
||||
}
|
||||
Method(_L0E) {
|
||||
}
|
||||
Method(_L0F) {
|
||||
}
|
||||
}
|
||||
}
|
@ -36,8 +36,6 @@ int arch_cpu_init(void)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
unprotect_spi_flash();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -80,5 +78,7 @@ void cpu_irq_init(void)
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
unprotect_spi_flash();
|
||||
|
||||
return pirq_init();
|
||||
}
|
||||
|
@ -115,8 +115,10 @@ car_init_ret:
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* When we get here after car_init(), esp points to a temporary stack
|
||||
* and esi holds the HOB list address returned by the FSP.
|
||||
* U-Boot enters here twice. For the first time it comes from
|
||||
* car_init_done() with esp points to a temporary stack and esi
|
||||
* set to zero. For the second time it comes from fsp_init_done()
|
||||
* with esi holding the HOB list address returned by the FSP.
|
||||
*/
|
||||
#endif
|
||||
/* Set up global data */
|
||||
@ -141,6 +143,14 @@ car_init_ret:
|
||||
jz skip_hob
|
||||
movl %esi, GD_HOB_LIST(%edx)
|
||||
|
||||
/*
|
||||
* After fsp_init() returns, the stack has already been switched to a
|
||||
* place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR.
|
||||
* Enlarge the size of malloc() pool before relocation since we have
|
||||
* plenty of memory now.
|
||||
*/
|
||||
subl $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp
|
||||
movl %esp, GD_MALLOC_BASE(%edx)
|
||||
skip_hob:
|
||||
#else
|
||||
/* Store table pointer */
|
||||
|
@ -230,6 +230,12 @@
|
||||
update@0 {
|
||||
#include "microcode/m0230671117.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m0130673322.dtsi"
|
||||
};
|
||||
update@2 {
|
||||
#include "microcode/m0130679901.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -91,7 +91,6 @@
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "pci-x86";
|
||||
device_type = "pci";
|
||||
u-boot,dm-pre-reloc;
|
||||
ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
|
||||
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
|
||||
@ -100,14 +99,16 @@
|
||||
pcie@17,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "intel,pci";
|
||||
device_type = "pci";
|
||||
compatible = "pci-bridge";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x0000b800 0x0 0x0 0x0 0x0>;
|
||||
|
||||
topcliff@0,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "intel,pci";
|
||||
device_type = "pci";
|
||||
compatible = "pci-bridge";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00010000 0x0 0x0 0x0 0x0>;
|
||||
|
||||
pciuart0: uart@a,1 {
|
||||
compatible = "pci8086,8811.00",
|
||||
@ -115,6 +116,7 @@
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00025100 0x0 0x0 0x0 0x0
|
||||
0x01025110 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
@ -128,6 +130,7 @@
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00025200 0x0 0x0 0x0 0x0
|
||||
0x01025210 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
@ -141,6 +144,7 @@
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00025300 0x0 0x0 0x0 0x0
|
||||
0x01025310 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
@ -154,6 +158,7 @@
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00025400 0x0 0x0 0x0 0x0
|
||||
0x01025410 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
@ -168,7 +173,7 @@
|
||||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "pci";
|
||||
intel,pirq-link = <0x60 8>;
|
||||
intel,pirq-mask = <0xdee0>;
|
||||
intel,pirq-mask = <0xcee0>;
|
||||
intel,pirq-routing = <
|
||||
/* TunnelCreek PCI devices */
|
||||
PCI_BDF(0, 2, 0) INTA PIRQE
|
||||
|
3284
arch/x86/dts/microcode/m0130679901.dtsi
Normal file
3284
arch/x86/dts/microcode/m0130679901.dtsi
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,33 @@
|
||||
compatible = "intel,x86-pinctrl";
|
||||
io-base = <0x4c>;
|
||||
|
||||
/* GPIO E0 */
|
||||
soc_gpio_s5_0@0 {
|
||||
gpio-offset = <0x80 0>;
|
||||
pad-offset = <0x1d0>;
|
||||
mode-gpio;
|
||||
output-value = <0>;
|
||||
direction = <PIN_OUTPUT>;
|
||||
};
|
||||
|
||||
/* GPIO E1 */
|
||||
soc_gpio_s5_1@0 {
|
||||
gpio-offset = <0x80 1>;
|
||||
pad-offset = <0x210>;
|
||||
mode-gpio;
|
||||
output-value = <0>;
|
||||
direction = <PIN_OUTPUT>;
|
||||
};
|
||||
|
||||
/* GPIO E2 */
|
||||
soc_gpio_s5_2@0 {
|
||||
gpio-offset = <0x80 2>;
|
||||
pad-offset = <0x1e0>;
|
||||
mode-gpio;
|
||||
output-value = <0>;
|
||||
direction = <PIN_OUTPUT>;
|
||||
};
|
||||
|
||||
pin_usb_host_en0@0 {
|
||||
gpio-offset = <0x80 8>;
|
||||
pad-offset = <0x260>;
|
||||
@ -40,7 +67,7 @@
|
||||
|
||||
pin_usb_host_en1@0 {
|
||||
gpio-offset = <0x80 9>;
|
||||
pad-offset = <0x258>;
|
||||
pad-offset = <0x250>;
|
||||
mode-gpio;
|
||||
output-value = <1>;
|
||||
direction = <PIN_OUTPUT>;
|
||||
@ -256,6 +283,9 @@
|
||||
update@0 {
|
||||
#include "microcode/m0130673322.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m0130679901.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
393
arch/x86/include/asm/acpi_table.h
Normal file
393
arch/x86/include/asm/acpi_table.h
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Based on acpi.c from coreboot
|
||||
*
|
||||
* Copyright (C) 2015, Saket Sinha <saket.sinha89@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 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
|
||||
*/
|
||||
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 */
|
||||
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) */
|
||||
u8 ext_checksum; /* Checksum of the whole table */
|
||||
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 {
|
||||
char signature[4]; /* ACPI signature (4 ASCII characters) */
|
||||
u32 length; /* Table length in bytes (incl. header) */
|
||||
u8 revision; /* Table version (not ACPI version!) */
|
||||
volatile u8 checksum; /* To make sum of entire table == 0 */
|
||||
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;
|
||||
|
||||
/* A maximum number of 32 ACPI tables ought to be enough for now */
|
||||
#define MAX_ACPI_TABLES 32
|
||||
|
||||
/* RSDT (Root System Description Table) */
|
||||
struct acpi_rsdt {
|
||||
struct acpi_table_header header;
|
||||
u32 entry[MAX_ACPI_TABLES];
|
||||
};
|
||||
|
||||
/* XSDT (Extended System Description Table) */
|
||||
struct acpi_xsdt {
|
||||
struct acpi_table_header header;
|
||||
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];
|
||||
};
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
/* 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
|
||||
};
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
/* FADT (Fixed ACPI Description Table) */
|
||||
struct __packed acpi_fadt {
|
||||
struct acpi_table_header header;
|
||||
u32 firmware_ctrl;
|
||||
u32 dsdt;
|
||||
u8 model;
|
||||
u8 preferred_pm_profile;
|
||||
u16 sci_int;
|
||||
u32 smi_cmd;
|
||||
u8 acpi_enable;
|
||||
u8 acpi_disable;
|
||||
u8 s4bios_req;
|
||||
u8 pstate_cnt;
|
||||
u32 pm1a_evt_blk;
|
||||
u32 pm1b_evt_blk;
|
||||
u32 pm1a_cnt_blk;
|
||||
u32 pm1b_cnt_blk;
|
||||
u32 pm2_cnt_blk;
|
||||
u32 pm_tmr_blk;
|
||||
u32 gpe0_blk;
|
||||
u32 gpe1_blk;
|
||||
u8 pm1_evt_len;
|
||||
u8 pm1_cnt_len;
|
||||
u8 pm2_cnt_len;
|
||||
u8 pm_tmr_len;
|
||||
u8 gpe0_blk_len;
|
||||
u8 gpe1_blk_len;
|
||||
u8 gpe1_base;
|
||||
u8 cst_cnt;
|
||||
u16 p_lvl2_lat;
|
||||
u16 p_lvl3_lat;
|
||||
u16 flush_size;
|
||||
u16 flush_stride;
|
||||
u8 duty_offset;
|
||||
u8 duty_width;
|
||||
u8 day_alrm;
|
||||
u8 mon_alrm;
|
||||
u8 century;
|
||||
u16 iapc_boot_arch;
|
||||
u8 res2;
|
||||
u32 flags;
|
||||
struct acpi_gen_regaddr reset_reg;
|
||||
u8 reset_value;
|
||||
u8 res3;
|
||||
u8 res4;
|
||||
u8 res5;
|
||||
u32 x_firmware_ctl_l;
|
||||
u32 x_firmware_ctl_h;
|
||||
u32 x_dsdt_l;
|
||||
u32 x_dsdt_h;
|
||||
struct acpi_gen_regaddr x_pm1a_evt_blk;
|
||||
struct acpi_gen_regaddr x_pm1b_evt_blk;
|
||||
struct acpi_gen_regaddr x_pm1a_cnt_blk;
|
||||
struct acpi_gen_regaddr x_pm1b_cnt_blk;
|
||||
struct acpi_gen_regaddr x_pm2_cnt_blk;
|
||||
struct acpi_gen_regaddr x_pm_tmr_blk;
|
||||
struct acpi_gen_regaddr x_gpe0_blk;
|
||||
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 */
|
||||
|
||||
/* 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_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);
|
||||
unsigned long write_acpi_tables(unsigned long start);
|
@ -9,15 +9,12 @@
|
||||
#ifndef _COREBOOT_SYSINFO_H
|
||||
#define _COREBOOT_SYSINFO_H
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <libfdt.h>
|
||||
#include <asm/arch/tables.h>
|
||||
|
||||
/* Allow a maximum of 16 memory range definitions. */
|
||||
#define SYSINFO_MAX_MEM_RANGES 16
|
||||
/* Maximum number of memory range definitions */
|
||||
#define SYSINFO_MAX_MEM_RANGES 32
|
||||
/* Allow a maximum of 8 GPIOs */
|
||||
#define SYSINFO_MAX_GPIOS 8
|
||||
#define SYSINFO_MAX_GPIOS 8
|
||||
|
||||
struct sysinfo_t {
|
||||
int n_memranges;
|
||||
|
@ -24,4 +24,7 @@
|
||||
#define UART0_IRQ 4
|
||||
#define UART1_IRQ 3
|
||||
|
||||
#define KBD_IRQ 1
|
||||
#define MSE_IRQ 12
|
||||
|
||||
#endif
|
||||
|
@ -8,8 +8,6 @@
|
||||
#ifndef _INIT_HELPERS_H_
|
||||
#define _INIT_HELPERS_H_
|
||||
|
||||
int calculate_relocation_address(void);
|
||||
|
||||
int init_cache_f_r(void);
|
||||
int init_bd_struct_r(void);
|
||||
int init_func_spi(void);
|
||||
|
@ -30,6 +30,7 @@ obj-y += physmem.o
|
||||
obj-$(CONFIG_X86_RAMTEST) += ramtest.o
|
||||
obj-y += sfi.o
|
||||
obj-y += string.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
|
||||
obj-y += tables.o
|
||||
obj-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o
|
||||
obj-$(CONFIG_CMD_ZBOOT) += zimage.o
|
||||
|
436
arch/x86/lib/acpi_table.c
Normal file
436
arch/x86/lib/acpi_table.c
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Based on acpi.c from coreboot
|
||||
*
|
||||
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#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/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.
|
||||
*/
|
||||
extern const unsigned char AmlCode[];
|
||||
|
||||
/**
|
||||
* 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;
|
||||
struct acpi_rsdt *rsdt;
|
||||
struct acpi_xsdt *xsdt = NULL;
|
||||
|
||||
/* The RSDT is mandatory while the XSDT is not */
|
||||
rsdt = (struct acpi_rsdt *)rsdp->rsdt_address;
|
||||
|
||||
if (rsdp->xsdt_address)
|
||||
xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address);
|
||||
|
||||
/* This should always be MAX_ACPI_TABLES */
|
||||
entries_num = ARRAY_SIZE(rsdt->entry);
|
||||
|
||||
for (i = 0; i < entries_num; i++) {
|
||||
if (rsdt->entry[i] == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= entries_num) {
|
||||
debug("ACPI: Error: too many tables.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add table to the RSDT */
|
||||
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));
|
||||
|
||||
/* Re-calculate checksum */
|
||||
rsdt->header.checksum = 0;
|
||||
rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
|
||||
rsdt->header.length);
|
||||
|
||||
/*
|
||||
* And now the same thing for the XSDT. We use the same index as for
|
||||
* now we want the XSDT and RSDT to always be in sync in U-Boot
|
||||
*/
|
||||
if (xsdt) {
|
||||
/* Add table to the XSDT */
|
||||
xsdt->entry[i] = (u64)(u32)table;
|
||||
|
||||
/* Fix XSDT length */
|
||||
xsdt->header.length = sizeof(acpi_header_t) +
|
||||
(sizeof(u64) * (i + 1));
|
||||
|
||||
/* Re-calculate checksum */
|
||||
xsdt->header.checksum = 0;
|
||||
xsdt->header.checksum = table_compute_checksum((u8 *)xsdt,
|
||||
xsdt->header.length);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
memcpy(facs->signature, "FACS", 4);
|
||||
facs->length = sizeof(struct acpi_facs);
|
||||
facs->hardware_signature = 0;
|
||||
facs->firmware_waking_vector = 0;
|
||||
facs->global_lock = 0;
|
||||
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 */
|
||||
}
|
||||
|
||||
static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
|
||||
{
|
||||
acpi_header_t *header = &(rsdt->header);
|
||||
|
||||
/* 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));
|
||||
}
|
||||
|
||||
static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
|
||||
{
|
||||
acpi_header_t *header = &(xsdt->header);
|
||||
|
||||
/* Fill out header fields */
|
||||
fill_header(header, "XSDT", 4);
|
||||
header->length = sizeof(struct acpi_xsdt);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Calculate checksums */
|
||||
rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
|
||||
rsdp->ext_checksum = table_compute_checksum((void *)rsdp,
|
||||
sizeof(struct acpi_rsdp));
|
||||
}
|
||||
|
||||
static void acpi_create_ssdt_generator(acpi_header_t *ssdt,
|
||||
const char *oem_table_id)
|
||||
{
|
||||
unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t);
|
||||
|
||||
memset((void *)ssdt, 0, sizeof(acpi_header_t));
|
||||
|
||||
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);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
ssdt->length = current - (unsigned long)ssdt;
|
||||
ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
|
||||
}
|
||||
|
||||
unsigned long write_acpi_tables(unsigned long start)
|
||||
{
|
||||
unsigned long current;
|
||||
struct acpi_rsdp *rsdp;
|
||||
struct acpi_rsdt *rsdt;
|
||||
struct acpi_xsdt *xsdt;
|
||||
struct acpi_facs *facs;
|
||||
acpi_header_t *dsdt;
|
||||
struct acpi_fadt *fadt;
|
||||
struct acpi_mcfg *mcfg;
|
||||
struct acpi_madt *madt;
|
||||
acpi_header_t *ssdt;
|
||||
|
||||
current = start;
|
||||
|
||||
/* Align ACPI tables to 16byte */
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: Writing ACPI tables at %lx.\n", start);
|
||||
|
||||
/* We need at least an RSDP and an RSDT Table */
|
||||
rsdp = (struct acpi_rsdp *)current;
|
||||
current += sizeof(struct acpi_rsdp);
|
||||
current = ALIGN(current, 16);
|
||||
rsdt = (struct acpi_rsdt *)current;
|
||||
current += sizeof(struct acpi_rsdt);
|
||||
current = ALIGN(current, 16);
|
||||
xsdt = (struct acpi_xsdt *)current;
|
||||
current += sizeof(struct acpi_xsdt);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
/* clear all table memory */
|
||||
memset((void *)start, 0, current - start);
|
||||
|
||||
acpi_write_rsdp(rsdp, rsdt, xsdt);
|
||||
acpi_write_rsdt(rsdt);
|
||||
acpi_write_xsdt(xsdt);
|
||||
|
||||
debug("ACPI: * FACS\n");
|
||||
facs = (struct acpi_facs *)current;
|
||||
current += sizeof(struct acpi_facs);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
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);
|
||||
}
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: * FADT\n");
|
||||
fadt = (struct acpi_fadt *)current;
|
||||
current += sizeof(struct acpi_fadt);
|
||||
current = ALIGN(current, 16);
|
||||
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 = 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("current = %lx\n", current);
|
||||
|
||||
debug("ACPI: done.\n");
|
||||
|
||||
return current;
|
||||
}
|
@ -64,7 +64,7 @@ temp_ram_init_ret:
|
||||
.global fsp_init_done
|
||||
fsp_init_done:
|
||||
/*
|
||||
* We come here from FspInit with eax pointing to the HOB list.
|
||||
* We come here from fsp_continue() with eax pointing to the HOB list.
|
||||
* Save eax to esi temporarily.
|
||||
*/
|
||||
movl %eax, %esi
|
||||
|
@ -56,8 +56,22 @@ void board_final_cleanup(void)
|
||||
|
||||
int x86_fsp_init(void)
|
||||
{
|
||||
if (!gd->arch.hob_list)
|
||||
if (!gd->arch.hob_list) {
|
||||
/*
|
||||
* The first time we enter here, call fsp_init().
|
||||
* Note the execution does not return to this function,
|
||||
* instead it jumps to fsp_continue().
|
||||
*/
|
||||
fsp_init(CONFIG_FSP_TEMP_RAM_ADDR, BOOT_FULL_CONFIG, NULL);
|
||||
} else {
|
||||
/*
|
||||
* The second time we enter here, adjust the size of malloc()
|
||||
* pool before relocation. Given gd->malloc_base was adjusted
|
||||
* after the call to board_init_f_mem() in arch/x86/cpu/start.S,
|
||||
* we should fix up gd->malloc_limit here.
|
||||
*/
|
||||
gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,12 +4,10 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <spi.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -19,53 +17,6 @@ __weak ulong board_get_usable_ram_top(ulong total_size)
|
||||
return gd->ram_size;
|
||||
}
|
||||
|
||||
int calculate_relocation_address(void)
|
||||
{
|
||||
const ulong uboot_size = (uintptr_t)&__bss_end -
|
||||
(uintptr_t)&__text_start;
|
||||
ulong total_size;
|
||||
ulong dest_addr;
|
||||
ulong fdt_size = 0;
|
||||
|
||||
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
|
||||
if (gd->fdt_blob)
|
||||
fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
|
||||
#endif
|
||||
total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN +
|
||||
CONFIG_SYS_STACK_SIZE + fdt_size;
|
||||
|
||||
dest_addr = board_get_usable_ram_top(total_size);
|
||||
/*
|
||||
* NOTE: All destination address are rounded down to 16-byte
|
||||
* boundary to satisfy various worst-case alignment
|
||||
* requirements
|
||||
*/
|
||||
dest_addr &= ~15;
|
||||
|
||||
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
|
||||
/*
|
||||
* If the device tree is sitting immediate above our image then we
|
||||
* must relocate it. If it is embedded in the data section, then it
|
||||
* will be relocated with other data.
|
||||
*/
|
||||
if (gd->fdt_blob) {
|
||||
dest_addr -= fdt_size;
|
||||
gd->new_fdt = (void *)dest_addr;
|
||||
dest_addr &= ~15;
|
||||
}
|
||||
#endif
|
||||
/* U-Boot is below the FDT */
|
||||
dest_addr -= uboot_size;
|
||||
dest_addr &= ~((1 << 12) - 1);
|
||||
gd->relocaddr = dest_addr;
|
||||
gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
|
||||
|
||||
/* Stack is at the bottom, so it can grow down */
|
||||
gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_cache_f_r(void)
|
||||
{
|
||||
#if defined(CONFIG_X86_RESET_VECTOR) & !defined(CONFIG_HAVE_FSP)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <asm/sfi.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/tables.h>
|
||||
#include <asm/acpi_table.h>
|
||||
|
||||
u8 table_compute_checksum(void *v, int len)
|
||||
{
|
||||
@ -51,4 +52,8 @@ void write_tables(void)
|
||||
rom_table_end = write_mp_table(rom_table_end);
|
||||
rom_table_end = ALIGN(rom_table_end, 1024);
|
||||
#endif
|
||||
#ifdef CONFIG_GENERATE_ACPI_TABLE
|
||||
rom_table_end = write_acpi_tables(rom_table_end);
|
||||
rom_table_end = ALIGN(rom_table_end, 1024);
|
||||
#endif
|
||||
}
|
||||
|
@ -10,11 +10,12 @@
|
||||
#include <netdev.h>
|
||||
#include <smsc_lpc47m.h>
|
||||
|
||||
#define SERIAL_DEV PNP_DEV(0x2e, 4)
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
|
||||
lpc47m_enable_serial(PNP_DEV(LPC47M_IO_PORT, LPC47M_SP1),
|
||||
UART0_BASE, UART0_IRQ);
|
||||
lpc47m_enable_kbc(PNP_DEV(LPC47M_IO_PORT, LPC47M_KBC),
|
||||
KBD_IRQ, MSE_IRQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -764,9 +764,6 @@ static init_fnc_t init_sequence_f[] = {
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
fdtdec_setup,
|
||||
#endif
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
|
||||
x86_fsp_init,
|
||||
#endif
|
||||
#ifdef CONFIG_TRACE
|
||||
trace_early_init,
|
||||
#endif
|
||||
@ -774,6 +771,9 @@ static init_fnc_t init_sequence_f[] = {
|
||||
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
|
||||
/* TODO: can this go into arch_cpu_init()? */
|
||||
probecpu,
|
||||
#endif
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
|
||||
x86_fsp_init,
|
||||
#endif
|
||||
arch_cpu_init, /* basic arch cpu dependent setup */
|
||||
mark_bootstage,
|
||||
|
@ -47,23 +47,25 @@ machine. You can use devices, boot a kernel, etc.
|
||||
Build Instructions
|
||||
------------------
|
||||
First choose a board that has EFI support and obtain an EFI implementation
|
||||
for that board. It will be either 32-bit or 64-bit.
|
||||
for that board. It will be either 32-bit or 64-bit. Alternatively, you can
|
||||
opt for using QEMU [1] and the OVMF [2], as detailed below.
|
||||
|
||||
To build U-Boot as an EFI application (32-bit EFI required), enable
|
||||
CONFIG_EFI and CONFIG_EFI_APP. The efi-x86 config is set up for this.
|
||||
To build U-Boot as an EFI application (32-bit EFI required), enable CONFIG_EFI
|
||||
and CONFIG_EFI_APP. The efi-x86 config (efi-x86_defconfig) is set up for this.
|
||||
Just build U-Boot as normal, e.g.
|
||||
|
||||
To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust
|
||||
an existing config to enable CONFIG_EFI, CONFIG_EFI_STUB and either
|
||||
CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT.
|
||||
|
||||
Then build U-Boot as normal, e.g.
|
||||
|
||||
make qemu-x86_defconfig
|
||||
make menuconfig (or make xconfig if you prefer)
|
||||
# change the settings as above
|
||||
make efi-x86_defconfig
|
||||
make
|
||||
|
||||
You will end up with one of these files:
|
||||
To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust an
|
||||
existing config (like qemu-x86_defconfig) to enable CONFIG_EFI, CONFIG_EFI_STUB
|
||||
and either CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT. All of these are
|
||||
boolean Kconfig options. Then build U-Boot as normal, e.g.
|
||||
|
||||
make qemu-x86_defconfig
|
||||
make
|
||||
|
||||
You will end up with one of these files depending on what you build for:
|
||||
|
||||
u-boot-app.efi - U-Boot EFI application
|
||||
u-boot-payload.efi - U-Boot EFI payload application
|
||||
@ -71,8 +73,9 @@ You will end up with one of these files:
|
||||
|
||||
Trying it out
|
||||
-------------
|
||||
Qemu is an emulator and it can emulate an x86 machine. You can run the
|
||||
payload with something like this:
|
||||
QEMU is an emulator and it can emulate an x86 machine. Please make sure your
|
||||
QEMU version is 2.3.0 or above to test this. You can run the payload with
|
||||
something like this:
|
||||
|
||||
mkdir /tmp/efi
|
||||
cp /path/to/u-boot*.efi /tmp/efi
|
||||
@ -80,7 +83,8 @@ payload with something like this:
|
||||
|
||||
Add -nographic if you want to use the terminal for output. Once it starts
|
||||
type 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
|
||||
run the application. 'bios.bin' is the EFI 'BIOS'.
|
||||
run the application. 'bios.bin' is the EFI 'BIOS'. Check [2] to obtain a
|
||||
prebuilt EFI BIOS for QEMU or you can build one from source as well.
|
||||
|
||||
To try it on real hardware, put u-boot-app.efi on a suitable boot medium,
|
||||
such as a USB stick. Then you can type something like this to start it:
|
||||
@ -235,3 +239,6 @@ common/cmd_efi.c
|
||||
Ben Stoltz, Simon Glass
|
||||
Google, Inc
|
||||
July 2015
|
||||
|
||||
[1] http://www.qemu.org
|
||||
[2] http://www.tianocore.org/ovmf/
|
||||
|
@ -245,10 +245,10 @@ this capability yet. The command is as follows:
|
||||
|
||||
# in the coreboot root directory
|
||||
$ ./build/util/cbfstool/cbfstool build/coreboot.rom add-flat-binary \
|
||||
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110015
|
||||
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110000
|
||||
|
||||
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the
|
||||
symbol address of _start (in arch/x86/cpu/start.S).
|
||||
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE, which is the symbol address
|
||||
of _x86boot_start (in arch/x86/cpu/start.S).
|
||||
|
||||
If you want to use ELF as the coreboot payload, change U-Boot configuration to
|
||||
use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
|
||||
@ -654,13 +654,13 @@ Use the device tree for configuration where possible.
|
||||
For the microcode you can create a suitable device tree file using the
|
||||
microcode tool:
|
||||
|
||||
./tools/microcode-tool -d microcode.dat create <model>
|
||||
./tools/microcode-tool -d microcode.dat -m <model> create
|
||||
|
||||
or if you only have header files and not the full Intel microcode.dat database:
|
||||
|
||||
./tools/microcode-tool -H BAY_TRAIL_FSP_KIT/Microcode/M0130673322.h \
|
||||
-H BAY_TRAIL_FSP_KIT/Microcode/M0130679901.h \
|
||||
create all
|
||||
-m all create
|
||||
|
||||
These are written to arch/x86/dts/microcode/ by default.
|
||||
|
||||
|
@ -34,9 +34,74 @@ under that bus.
|
||||
Note that this is all done on a lazy basis, as needed, so until something is
|
||||
touched on PCI (eg: a call to pci_find_devices()) it will not be probed.
|
||||
|
||||
PCI devices can appear in the device tree. If they do this serves to specify
|
||||
the driver to use for the device. In this case they will be bound at
|
||||
start-up.
|
||||
PCI devices can appear in the flattened device tree. If they do this serves to
|
||||
specify the driver to use for the device. In this case they will be bound at
|
||||
first. Each PCI device node must have a compatible string list as well as a
|
||||
<reg> property, as defined by the IEEE Std 1275-1994 PCI bus binding document
|
||||
v2.1. Note we must describe PCI devices with the same bus hierarchy as the
|
||||
hardware, otherwise driver model cannot detect the correct parent/children
|
||||
relationship during PCI bus enumeration thus PCI devices won't be bound to
|
||||
their drivers accordingly. A working example like below:
|
||||
|
||||
pci {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "pci-x86";
|
||||
u-boot,dm-pre-reloc;
|
||||
ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
|
||||
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
|
||||
0x01000000 0x0 0x2000 0x2000 0 0xe000>;
|
||||
|
||||
pcie@17,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "pci-bridge";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x0000b800 0x0 0x0 0x0 0x0>;
|
||||
|
||||
topcliff@0,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "pci-bridge";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00010000 0x0 0x0 0x0 0x0>;
|
||||
|
||||
pciuart0: uart@a,1 {
|
||||
compatible = "pci8086,8811.00",
|
||||
"pci8086,8811",
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x00025100 0x0 0x0 0x0 0x0
|
||||
0x01025110 0x0 0x0 0x0 0x0>;
|
||||
......
|
||||
};
|
||||
|
||||
......
|
||||
};
|
||||
};
|
||||
|
||||
......
|
||||
};
|
||||
|
||||
In this example, the root PCI bus node is the "/pci" which matches "pci-x86"
|
||||
driver. It has a subnode "pcie@17,0" with driver "pci-bridge". "pcie@17,0"
|
||||
also has subnode "topcliff@0,0" which is a "pci-bridge" too. Under that bridge,
|
||||
a PCI UART device "uart@a,1" is described. This exactly reflects the hardware
|
||||
bus hierarchy: on the root PCI bus, there is a PCIe root port which connects
|
||||
to a downstream device Topcliff chipset. Inside Topcliff chipset, it has a
|
||||
PCIe-to-PCI bridge and all the chipset integrated devices like the PCI UART
|
||||
device are on the PCI bus. Like other devices in the device tree, if we want
|
||||
to bind PCI devices before relocation, "u-boot,dm-pre-reloc" must be declared
|
||||
in each of these nodes.
|
||||
|
||||
If PCI devices are not listed in the device tree, U_BOOT_PCI_DEVICE can be used
|
||||
to specify the driver to use for the device. The device tree takes precedence
|
||||
over U_BOOT_PCI_DEVICE. Plese note with U_BOOT_PCI_DEVICE, only drivers with
|
||||
DM_FLAG_PRE_RELOC will be bound before relocation. If neither device tree nor
|
||||
U_BOOT_PCI_DEVICE is provided, the built-in driver (either pci_bridge_drv or
|
||||
pci_generic_drv) will be used.
|
||||
|
||||
|
||||
Sandbox
|
||||
|
@ -226,17 +226,17 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
|
||||
drv = dev->driver;
|
||||
assert(drv);
|
||||
|
||||
/* Allocate private data if requested */
|
||||
if (drv->priv_auto_alloc_size) {
|
||||
/* Allocate private data if requested and not reentered */
|
||||
if (drv->priv_auto_alloc_size && !dev->priv) {
|
||||
dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
|
||||
if (!dev->priv) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* Allocate private data if requested */
|
||||
/* Allocate private data if requested and not reentered */
|
||||
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
|
||||
if (size) {
|
||||
if (size && !dev->uclass_priv) {
|
||||
dev->uclass_priv = calloc(1, size);
|
||||
if (!dev->uclass_priv) {
|
||||
ret = -ENOMEM;
|
||||
@ -251,7 +251,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
|
||||
size = dev->parent->uclass->uc_drv->
|
||||
per_child_auto_alloc_size;
|
||||
}
|
||||
if (size) {
|
||||
if (size && !dev->parent_priv) {
|
||||
dev->parent_priv = alloc_priv(size, drv->flags);
|
||||
if (!dev->parent_priv) {
|
||||
ret = -ENOMEM;
|
||||
@ -264,6 +264,15 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
|
||||
ret = device_probe(dev->parent);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* The device might have already been probed during
|
||||
* the call to device_probe() on its parent device
|
||||
* (e.g. PCI bridge devices). Test the flags again
|
||||
* so that we don't mess up the device.
|
||||
*/
|
||||
if (dev->flags & DM_FLAG_ACTIVATED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq = uclass_resolve_seq(dev);
|
||||
|
@ -75,7 +75,7 @@ static int gpio_ich6_get_base(unsigned long base)
|
||||
/* Is the device present? */
|
||||
tmpword = x86_pci_read_config16(pci_dev, PCI_VENDOR_ID);
|
||||
if (tmpword != PCI_VENDOR_ID_INTEL) {
|
||||
debug("%s: wrong VendorID\n", __func__);
|
||||
debug("%s: wrong VendorID %x\n", __func__, tmpword);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ static int gpio_ich6_get_base(unsigned long base)
|
||||
* at the offset that we just read. Bit 0 indicates that it's
|
||||
* an I/O address, not a memory address, so mask that off.
|
||||
*/
|
||||
return tmplong & 0xfffc;
|
||||
return tmplong & 1 ? tmplong & ~3 : tmplong & ~15;
|
||||
}
|
||||
|
||||
static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
|
||||
@ -324,7 +324,7 @@ int gpio_ich6_pinctrl_init(void)
|
||||
debug("%s: io-base offset not present\n", __func__);
|
||||
} else {
|
||||
iobase = gpio_ich6_get_base(iobase_offset);
|
||||
if (iobase < 0) {
|
||||
if (IS_ERR_VALUE(iobase)) {
|
||||
debug("%s: invalid IOBASE address (%08x)\n", __func__,
|
||||
iobase);
|
||||
return -EINVAL;
|
||||
@ -410,7 +410,7 @@ static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
struct ich6_bank_priv *bank = dev_get_priv(dev);
|
||||
|
||||
return _ich6_gpio_set_direction(inl(bank->io_sel), offset, 0);
|
||||
return _ich6_gpio_set_direction(bank->io_sel, offset, 0);
|
||||
}
|
||||
|
||||
static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
|
||||
@ -419,7 +419,7 @@ static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
|
||||
int ret;
|
||||
struct ich6_bank_priv *bank = dev_get_priv(dev);
|
||||
|
||||
ret = _ich6_gpio_set_direction(inl(bank->io_sel), offset, 1);
|
||||
ret = _ich6_gpio_set_direction(bank->io_sel, offset, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -10,49 +10,30 @@
|
||||
/* includes */
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifdef CONFIG_USE_CPCIDVI
|
||||
extern u8 gt_cpcidvi_in8(u32 offset);
|
||||
extern void gt_cpcidvi_out8(u32 offset, u8 data);
|
||||
|
||||
#define in8(a) gt_cpcidvi_in8(a)
|
||||
#define out8(a, b) gt_cpcidvi_out8(a, b)
|
||||
#endif
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <i8042.h>
|
||||
|
||||
/* defines */
|
||||
#define in8(p) inb(p)
|
||||
#define out8(p, v) outb(v, p)
|
||||
|
||||
#ifdef CONFIG_CONSOLE_CURSOR
|
||||
extern void console_cursor(int state);
|
||||
static int blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
static int blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
static int cursor_state;
|
||||
#endif
|
||||
|
||||
/* locals */
|
||||
|
||||
static int kbd_input = -1; /* no input yet */
|
||||
static int kbd_mapping = KBD_US; /* default US keyboard */
|
||||
static int kbd_flags = NORMAL; /* after reset */
|
||||
static int kbd_state; /* unshift code */
|
||||
|
||||
static void kbd_conv_char(unsigned char scan_code);
|
||||
static void kbd_led_set(void);
|
||||
static void kbd_normal(unsigned char scan_code);
|
||||
static void kbd_shift(unsigned char scan_code);
|
||||
static void kbd_ctrl(unsigned char scan_code);
|
||||
static void kbd_num(unsigned char scan_code);
|
||||
static void kbd_caps(unsigned char scan_code);
|
||||
static void kbd_scroll(unsigned char scan_code);
|
||||
static void kbd_alt(unsigned char scan_code);
|
||||
static int kbd_input_empty(void);
|
||||
static int kbd_reset(void);
|
||||
static int kbd_input = -1; /* no input yet */
|
||||
static int kbd_mapping = KBD_US; /* default US keyboard */
|
||||
static int kbd_flags = NORMAL; /* after reset */
|
||||
static int kbd_state; /* unshift code */
|
||||
|
||||
static unsigned char kbd_fct_map[144] = {
|
||||
/* kbd_fct_map table for scan code */
|
||||
0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */
|
||||
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */
|
||||
0, AS, AS, AS, AS, AS, AS, AS, /* scan 00-07 */
|
||||
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 08-0F */
|
||||
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */
|
||||
AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */
|
||||
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */
|
||||
@ -74,8 +55,8 @@ static unsigned char kbd_fct_map[144] = {
|
||||
static unsigned char kbd_key_map[2][5][144] = {
|
||||
{ /* US keyboard */
|
||||
{ /* unshift code */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
|
||||
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
|
||||
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 08-0F */
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
|
||||
'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
|
||||
@ -94,8 +75,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* shift code */
|
||||
0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */
|
||||
'&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 00-07 */
|
||||
'&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 08-0F */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */
|
||||
'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */
|
||||
@ -114,8 +95,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* control code */
|
||||
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
|
||||
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
|
||||
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
|
||||
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
|
||||
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
|
||||
0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
|
||||
0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
|
||||
@ -134,8 +115,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
|
||||
},
|
||||
{ /* non numeric code */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
|
||||
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
|
||||
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 08-0F */
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
|
||||
'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
|
||||
@ -154,30 +135,30 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* right alt mode - not used in US keyboard */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 08-0F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
|
||||
}
|
||||
},
|
||||
{ /* german keyboard */
|
||||
{ /* German keyboard */
|
||||
{ /* unshift code */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
|
||||
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
|
||||
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
|
||||
'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
|
||||
'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
|
||||
@ -196,8 +177,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* shift code */
|
||||
0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */
|
||||
'/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 00-07 */
|
||||
'/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 08-0F */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */
|
||||
'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */
|
||||
@ -216,8 +197,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* control code */
|
||||
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
|
||||
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
|
||||
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
|
||||
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
|
||||
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
|
||||
0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
|
||||
0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
|
||||
@ -236,8 +217,8 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
|
||||
},
|
||||
{ /* non numeric code */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
|
||||
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
|
||||
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
|
||||
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
|
||||
'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
|
||||
'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
|
||||
@ -255,23 +236,23 @@ static unsigned char kbd_key_map[2][5][144] = {
|
||||
'\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
|
||||
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
|
||||
},
|
||||
{ /* Right alt mode - is used in German keyboard */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
|
||||
'{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */
|
||||
'@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
|
||||
0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
|
||||
0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
|
||||
{ /* right alt mode - is used in German keyboard */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
|
||||
'{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 08-0F */
|
||||
'@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
|
||||
0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
|
||||
0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50-57 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
|
||||
}
|
||||
@ -298,167 +279,113 @@ static unsigned char ext_key_map[] = {
|
||||
0x00 /* map end */
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static int kbd_controller_present(void)
|
||||
static int kbd_input_empty(void)
|
||||
{
|
||||
return in8(I8042_STATUS_REG) != 0xff;
|
||||
int kbd_timeout = KBD_TIMEOUT * 1000;
|
||||
|
||||
while ((in8(I8042_STS_REG) & STATUS_IBF) && kbd_timeout--)
|
||||
udelay(1);
|
||||
|
||||
return kbd_timeout != -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement a weak default function for boards that optionally
|
||||
* need to skip the i8042 initialization.
|
||||
*/
|
||||
int __weak board_i8042_skip(void)
|
||||
static int kbd_output_full(void)
|
||||
{
|
||||
/* As default, don't skip */
|
||||
return 0;
|
||||
int kbd_timeout = KBD_TIMEOUT * 1000;
|
||||
|
||||
while (((in8(I8042_STS_REG) & STATUS_OBF) == 0) && kbd_timeout--)
|
||||
udelay(1);
|
||||
|
||||
return kbd_timeout != -1;
|
||||
}
|
||||
|
||||
void i8042_flush(void)
|
||||
static void kbd_led_set(void)
|
||||
{
|
||||
int timeout;
|
||||
kbd_input_empty();
|
||||
out8(I8042_DATA_REG, CMD_SET_KBD_LED);
|
||||
kbd_input_empty();
|
||||
out8(I8042_DATA_REG, (kbd_flags & 0x7));
|
||||
}
|
||||
|
||||
/*
|
||||
* The delay is to give the keyboard controller some time to fill the
|
||||
* next byte.
|
||||
*/
|
||||
while (1) {
|
||||
timeout = 100; /* wait for no longer than 100us */
|
||||
while (timeout > 0 && !(in8(I8042_STATUS_REG) & 0x01)) {
|
||||
udelay(1);
|
||||
timeout--;
|
||||
static void kbd_normal(unsigned char scan_code)
|
||||
{
|
||||
unsigned char chr;
|
||||
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
|
||||
if ((chr == 0xff) || (chr == 0x00))
|
||||
return;
|
||||
|
||||
/* if caps lock convert upper to lower */
|
||||
if (((kbd_flags & CAPS) == CAPS) &&
|
||||
(chr >= 'a' && chr <= 'z')) {
|
||||
chr -= 'a' - 'A';
|
||||
}
|
||||
|
||||
/* Try to pull next byte if not timeout. */
|
||||
if (in8(I8042_STATUS_REG) & 0x01)
|
||||
in8(I8042_DATA_REG);
|
||||
else
|
||||
break;
|
||||
kbd_input = chr;
|
||||
}
|
||||
}
|
||||
|
||||
int i8042_disable(void)
|
||||
static void kbd_shift(unsigned char scan_code)
|
||||
{
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
/* Disable keyboard */
|
||||
out8(I8042_COMMAND_REG, 0xad);
|
||||
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* i8042_kbd_init - reset keyboard and init state flags
|
||||
*/
|
||||
int i8042_kbd_init(void)
|
||||
{
|
||||
int keymap, try;
|
||||
char *penv;
|
||||
|
||||
if (!kbd_controller_present() || board_i8042_skip())
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_USE_CPCIDVI
|
||||
penv = getenv("console");
|
||||
if (penv != NULL) {
|
||||
if (strncmp(penv, "serial", 7) == 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/* Init keyboard device (default US layout) */
|
||||
keymap = KBD_US;
|
||||
penv = getenv("keymap");
|
||||
if (penv != NULL) {
|
||||
if (strncmp(penv, "de", 3) == 0)
|
||||
keymap = KBD_GER;
|
||||
}
|
||||
|
||||
for (try = 0; try < KBD_RESET_TRIES; try++) {
|
||||
if (kbd_reset() == 0) {
|
||||
kbd_mapping = keymap;
|
||||
kbd_flags = NORMAL;
|
||||
kbd_state = 0;
|
||||
kbd_led_set();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* i8042_tstc - test if keyboard input is available
|
||||
* option: cursor blinking if called in a loop
|
||||
*/
|
||||
int i8042_tstc(struct stdio_dev *dev)
|
||||
{
|
||||
unsigned char scan_code = 0;
|
||||
|
||||
#ifdef CONFIG_CONSOLE_CURSOR
|
||||
if (--blinkCount == 0) {
|
||||
cursor_state ^= 1;
|
||||
console_cursor(cursor_state);
|
||||
blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
udelay(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((in8(I8042_STATUS_REG) & 0x01) == 0) {
|
||||
return 0;
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~SHIFT);
|
||||
} else {
|
||||
scan_code = in8(I8042_DATA_REG);
|
||||
if (scan_code == 0xfa)
|
||||
return 0;
|
||||
|
||||
kbd_conv_char(scan_code);
|
||||
|
||||
if (kbd_input != -1)
|
||||
return 1;
|
||||
kbd_state = SH;
|
||||
kbd_flags |= SHIFT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* i8042_getc - wait till keyboard input is available
|
||||
* option: turn on/off cursor while waiting
|
||||
*/
|
||||
int i8042_getc(struct stdio_dev *dev)
|
||||
static void kbd_ctrl(unsigned char scan_code)
|
||||
{
|
||||
int ret_chr;
|
||||
unsigned char scan_code;
|
||||
|
||||
while (kbd_input == -1) {
|
||||
while ((in8(I8042_STATUS_REG) & 0x01) == 0) {
|
||||
#ifdef CONFIG_CONSOLE_CURSOR
|
||||
if (--blinkCount == 0) {
|
||||
cursor_state ^= 1;
|
||||
console_cursor(cursor_state);
|
||||
blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
}
|
||||
udelay(10);
|
||||
#endif
|
||||
}
|
||||
scan_code = in8(I8042_DATA_REG);
|
||||
if (scan_code != 0xfa)
|
||||
kbd_conv_char (scan_code);
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~CTRL);
|
||||
} else {
|
||||
kbd_state = CN;
|
||||
kbd_flags |= CTRL;
|
||||
}
|
||||
ret_chr = kbd_input;
|
||||
kbd_input = -1;
|
||||
return ret_chr;
|
||||
}
|
||||
|
||||
static void kbd_num(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= NUM;
|
||||
kbd_state = (kbd_flags & NUM) ? AS : NM;
|
||||
kbd_led_set();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static void kbd_alt(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~ALT);
|
||||
} else {
|
||||
kbd_state = AK;
|
||||
kbd_flags &= ALT;
|
||||
}
|
||||
}
|
||||
|
||||
static void kbd_caps(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= CAPS;
|
||||
kbd_led_set();
|
||||
}
|
||||
}
|
||||
|
||||
static void kbd_scroll(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= STP;
|
||||
kbd_led_set();
|
||||
if (kbd_flags & STP)
|
||||
kbd_input = 0x13;
|
||||
else
|
||||
kbd_input = 0x11;
|
||||
}
|
||||
}
|
||||
|
||||
static void kbd_conv_char(unsigned char scan_code)
|
||||
{
|
||||
@ -475,8 +402,8 @@ static void kbd_conv_char(unsigned char scan_code)
|
||||
|
||||
if ((scan_code == 0xe1) || (kbd_flags & E1)) {
|
||||
if (scan_code == 0xe1) {
|
||||
kbd_flags ^= BRK; /* reset the break flag */
|
||||
kbd_flags ^= E1; /* bitwise EXOR with E1 flag */
|
||||
kbd_flags ^= BRK; /* reset the break flag */
|
||||
kbd_flags ^= E1; /* bitwise EXOR with E1 flag */
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -511,203 +438,218 @@ static void kbd_conv_char(unsigned char scan_code)
|
||||
case NM:
|
||||
kbd_num(scan_code);
|
||||
break;
|
||||
case AK:
|
||||
kbd_alt(scan_code);
|
||||
break;
|
||||
case CP:
|
||||
kbd_caps(scan_code);
|
||||
break;
|
||||
case ST:
|
||||
kbd_scroll(scan_code);
|
||||
break;
|
||||
case AK:
|
||||
kbd_alt(scan_code);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_normal(unsigned char scan_code)
|
||||
{
|
||||
unsigned char chr;
|
||||
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
|
||||
if ((chr == 0xff) || (chr == 0x00))
|
||||
return;
|
||||
|
||||
/* if caps lock convert upper to lower */
|
||||
if (((kbd_flags & CAPS) == CAPS) &&
|
||||
(chr >= 'a' && chr <= 'z')) {
|
||||
chr -= 'a' - 'A';
|
||||
}
|
||||
kbd_input = chr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_shift(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~SHIFT);
|
||||
} else {
|
||||
kbd_state = SH;
|
||||
kbd_flags |= SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_ctrl(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~CTRL);
|
||||
} else {
|
||||
kbd_state = CN;
|
||||
kbd_flags |= CTRL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_caps(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= CAPS;
|
||||
kbd_led_set(); /* update keyboard LED */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_num(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= NUM;
|
||||
kbd_state = (kbd_flags & NUM) ? AS : NM;
|
||||
kbd_led_set(); /* update keyboard LED */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_scroll(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == NORMAL) {
|
||||
kbd_flags ^= STP;
|
||||
kbd_led_set(); /* update keyboard LED */
|
||||
if (kbd_flags & STP)
|
||||
kbd_input = 0x13;
|
||||
else
|
||||
kbd_input = 0x11;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_alt(unsigned char scan_code)
|
||||
{
|
||||
if ((kbd_flags & BRK) == BRK) {
|
||||
kbd_state = AS;
|
||||
kbd_flags &= (~ALT);
|
||||
} else {
|
||||
kbd_state = AK;
|
||||
kbd_flags &= ALT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void kbd_led_set(void)
|
||||
{
|
||||
kbd_input_empty();
|
||||
out8(I8042_DATA_REG, 0xed); /* SET LED command */
|
||||
kbd_input_empty();
|
||||
out8(I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static int kbd_input_empty(void)
|
||||
{
|
||||
int kbdTimeout = KBD_TIMEOUT * 1000;
|
||||
|
||||
while ((in8(I8042_STATUS_REG) & I8042_STATUS_IN_DATA) && kbdTimeout--)
|
||||
udelay(1);
|
||||
|
||||
return kbdTimeout != -1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static int wait_until_kbd_output_full(void)
|
||||
{
|
||||
int kbdTimeout = KBD_TIMEOUT * 1000;
|
||||
|
||||
while (((in8(I8042_STATUS_REG) & 0x01) == 0) && kbdTimeout--)
|
||||
udelay(1);
|
||||
|
||||
return kbdTimeout != -1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static int kbd_reset(void)
|
||||
{
|
||||
/* KB Reset */
|
||||
u8 config;
|
||||
|
||||
/* controller self test */
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
out8(I8042_DATA_REG, 0xff);
|
||||
|
||||
if (wait_until_kbd_output_full() == 0)
|
||||
return -1;
|
||||
|
||||
if (in8(I8042_DATA_REG) != 0xfa) /* ACK */
|
||||
return -1;
|
||||
|
||||
if (wait_until_kbd_output_full() == 0)
|
||||
return -1;
|
||||
|
||||
if (in8(I8042_DATA_REG) != 0xaa) /* Test Pass*/
|
||||
out8(I8042_CMD_REG, CMD_SELF_TEST);
|
||||
if (kbd_output_full() == 0)
|
||||
return -1;
|
||||
if (in8(I8042_DATA_REG) != KBC_TEST_OK)
|
||||
return -1;
|
||||
|
||||
/* keyboard reset */
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
/* Set KBC mode */
|
||||
out8(I8042_COMMAND_REG, 0x60);
|
||||
|
||||
if (kbd_input_empty() == 0)
|
||||
out8(I8042_DATA_REG, CMD_RESET_KBD);
|
||||
if (kbd_output_full() == 0)
|
||||
return -1;
|
||||
if (in8(I8042_DATA_REG) != KBD_ACK)
|
||||
return -1;
|
||||
if (kbd_output_full() == 0)
|
||||
return -1;
|
||||
if (in8(I8042_DATA_REG) != KBD_POR)
|
||||
return -1;
|
||||
|
||||
out8(I8042_DATA_REG, 0x45);
|
||||
|
||||
/* set AT translation and disable irq */
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
/* Enable Keyboard */
|
||||
out8(I8042_COMMAND_REG, 0xae);
|
||||
out8(I8042_CMD_REG, CMD_RD_CONFIG);
|
||||
if (kbd_output_full() == 0)
|
||||
return -1;
|
||||
config = in8(I8042_DATA_REG);
|
||||
config |= CONFIG_AT_TRANS;
|
||||
config &= ~(CONFIG_KIRQ_EN | CONFIG_MIRQ_EN);
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
out8(I8042_COMMAND_REG, 0x60);
|
||||
out8(I8042_CMD_REG, CMD_WR_CONFIG);
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
out8(I8042_DATA_REG, config);
|
||||
|
||||
out8(I8042_DATA_REG, 0xf4);
|
||||
/* enable keyboard */
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
out8(I8042_CMD_REG, CMD_KBD_EN);
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kbd_controller_present(void)
|
||||
{
|
||||
return in8(I8042_STS_REG) != 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement a weak default function for boards that optionally
|
||||
* need to skip the i8042 initialization.
|
||||
*/
|
||||
int __weak board_i8042_skip(void)
|
||||
{
|
||||
/* As default, don't skip */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i8042_flush(void)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
/*
|
||||
* The delay is to give the keyboard controller some time
|
||||
* to fill the next byte.
|
||||
*/
|
||||
while (1) {
|
||||
timeout = 100; /* wait for no longer than 100us */
|
||||
while (timeout > 0 && !(in8(I8042_STS_REG) & STATUS_OBF)) {
|
||||
udelay(1);
|
||||
timeout--;
|
||||
}
|
||||
|
||||
/* Try to pull next byte if not timeout */
|
||||
if (in8(I8042_STS_REG) & STATUS_OBF)
|
||||
in8(I8042_DATA_REG);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i8042_disable(void)
|
||||
{
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
/* Disable keyboard */
|
||||
out8(I8042_CMD_REG, CMD_KBD_DIS);
|
||||
|
||||
if (kbd_input_empty() == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* i8042_kbd_init - reset keyboard and init state flags */
|
||||
int i8042_kbd_init(void)
|
||||
{
|
||||
int keymap, try;
|
||||
char *penv;
|
||||
|
||||
if (!kbd_controller_present() || board_i8042_skip()) {
|
||||
debug("i8042 keyboard controller is not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init keyboard device (default US layout) */
|
||||
keymap = KBD_US;
|
||||
penv = getenv("keymap");
|
||||
if (penv != NULL) {
|
||||
if (strncmp(penv, "de", 3) == 0)
|
||||
keymap = KBD_GER;
|
||||
}
|
||||
|
||||
for (try = 0; try < KBD_RESET_TRIES; try++) {
|
||||
if (kbd_reset() == 0) {
|
||||
kbd_mapping = keymap;
|
||||
kbd_flags = NORMAL;
|
||||
kbd_state = 0;
|
||||
kbd_led_set();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* i8042_tstc - test if keyboard input is available
|
||||
*
|
||||
* option: cursor blinking if called in a loop
|
||||
*/
|
||||
int i8042_tstc(struct stdio_dev *dev)
|
||||
{
|
||||
unsigned char scan_code = 0;
|
||||
|
||||
#ifdef CONFIG_CONSOLE_CURSOR
|
||||
if (--blink_count == 0) {
|
||||
cursor_state ^= 1;
|
||||
console_cursor(cursor_state);
|
||||
blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
udelay(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
scan_code = in8(I8042_DATA_REG);
|
||||
if (scan_code == 0xfa)
|
||||
return 0;
|
||||
|
||||
kbd_conv_char(scan_code);
|
||||
|
||||
if (kbd_input != -1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* i8042_getc - wait till keyboard input is available
|
||||
*
|
||||
* option: turn on/off cursor while waiting
|
||||
*/
|
||||
int i8042_getc(struct stdio_dev *dev)
|
||||
{
|
||||
int ret_chr;
|
||||
unsigned char scan_code;
|
||||
|
||||
while (kbd_input == -1) {
|
||||
while ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
|
||||
#ifdef CONFIG_CONSOLE_CURSOR
|
||||
if (--blink_count == 0) {
|
||||
cursor_state ^= 1;
|
||||
console_cursor(cursor_state);
|
||||
blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
|
||||
}
|
||||
udelay(10);
|
||||
#endif
|
||||
}
|
||||
scan_code = in8(I8042_DATA_REG);
|
||||
if (scan_code != 0xfa)
|
||||
kbd_conv_char(scan_code);
|
||||
}
|
||||
ret_chr = kbd_input;
|
||||
kbd_input = -1;
|
||||
|
||||
return ret_chr;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ static void pnp_exit_conf_state(u16 dev)
|
||||
outb(0xaa, port);
|
||||
}
|
||||
|
||||
void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq)
|
||||
void lpc47m_enable_serial(uint dev, uint iobase, uint irq)
|
||||
{
|
||||
pnp_enter_conf_state(dev);
|
||||
pnp_set_logical_device(dev);
|
||||
@ -32,3 +32,14 @@ void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq)
|
||||
pnp_set_enable(dev, 1);
|
||||
pnp_exit_conf_state(dev);
|
||||
}
|
||||
|
||||
void lpc47m_enable_kbc(uint dev, uint irq0, uint irq1)
|
||||
{
|
||||
pnp_enter_conf_state(dev);
|
||||
pnp_set_logical_device(dev);
|
||||
pnp_set_enable(dev, 0);
|
||||
pnp_set_irq(dev, PNP_IDX_IRQ0, irq0);
|
||||
pnp_set_irq(dev, PNP_IDX_IRQ1, irq1);
|
||||
pnp_set_enable(dev, 1);
|
||||
pnp_exit_conf_state(dev);
|
||||
}
|
||||
|
@ -4978,8 +4978,8 @@ e1000_configure_tx(struct e1000_hw *hw)
|
||||
unsigned long tipg, tarc;
|
||||
uint32_t ipgr1, ipgr2;
|
||||
|
||||
E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base & 0xffffffff);
|
||||
E1000_WRITE_REG(hw, TDBAH, (unsigned long)tx_base >> 32);
|
||||
E1000_WRITE_REG(hw, TDBAL, lower_32_bits((unsigned long)tx_base));
|
||||
E1000_WRITE_REG(hw, TDBAH, upper_32_bits((unsigned long)tx_base));
|
||||
|
||||
E1000_WRITE_REG(hw, TDLEN, 128);
|
||||
|
||||
@ -5103,6 +5103,7 @@ e1000_configure_rx(struct e1000_hw *hw)
|
||||
{
|
||||
unsigned long rctl, ctrl_ext;
|
||||
rx_tail = 0;
|
||||
|
||||
/* make sure receives are disabled while setting up the descriptors */
|
||||
rctl = E1000_READ_REG(hw, RCTL);
|
||||
E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
|
||||
@ -5122,8 +5123,8 @@ e1000_configure_rx(struct e1000_hw *hw)
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
}
|
||||
/* Setup the Base and Length of the Rx Descriptor Ring */
|
||||
E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base & 0xffffffff);
|
||||
E1000_WRITE_REG(hw, RDBAH, (unsigned long)rx_base >> 32);
|
||||
E1000_WRITE_REG(hw, RDBAL, lower_32_bits((unsigned long)rx_base));
|
||||
E1000_WRITE_REG(hw, RDBAH, upper_32_bits((unsigned long)rx_base));
|
||||
|
||||
E1000_WRITE_REG(hw, RDLEN, 128);
|
||||
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
#include <dm/device-internal.h>
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
|
||||
#include <asm/fsp/fsp_support.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -461,6 +464,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
|
||||
int n_ents;
|
||||
int ret;
|
||||
char name[30], *str;
|
||||
bool bridge;
|
||||
|
||||
*devp = NULL;
|
||||
|
||||
@ -480,6 +484,17 @@ static int pci_find_and_bind_driver(struct udevice *parent,
|
||||
continue;
|
||||
|
||||
drv = entry->driver;
|
||||
|
||||
/*
|
||||
* In the pre-relocation phase, we only bind devices
|
||||
* whose driver has the DM_FLAG_PRE_RELOC set, to save
|
||||
* precious memory space as on some platforms as that
|
||||
* space is pretty limited (ie: using Cache As RAM).
|
||||
*/
|
||||
if (!(gd->flags & GD_FLG_RELOC) &&
|
||||
!(drv->flags & DM_FLAG_PRE_RELOC))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We could pass the descriptor to the driver as
|
||||
* platdata (instead of NULL) and allow its bind()
|
||||
@ -499,14 +514,23 @@ static int pci_find_and_bind_driver(struct udevice *parent,
|
||||
}
|
||||
}
|
||||
|
||||
bridge = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI;
|
||||
/*
|
||||
* In the pre-relocation phase, we only bind bridge devices to save
|
||||
* precious memory space as on some platforms as that space is pretty
|
||||
* limited (ie: using Cache As RAM).
|
||||
*/
|
||||
if (!(gd->flags & GD_FLG_RELOC) && !bridge)
|
||||
return 0;
|
||||
|
||||
/* Bind a generic driver so that the device can be used */
|
||||
sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
|
||||
PCI_FUNC(bdf));
|
||||
str = strdup(name);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
|
||||
"pci_generic_drv";
|
||||
drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
|
||||
|
||||
ret = device_bind_driver(parent, drv, str, devp);
|
||||
if (ret) {
|
||||
debug("%s: Failed to bind generic driver: %d", __func__, ret);
|
||||
@ -589,11 +613,13 @@ int pci_bind_bus_devices(struct udevice *bus)
|
||||
return ret;
|
||||
|
||||
/* Update the platform data */
|
||||
pplat = dev_get_parent_platdata(dev);
|
||||
pplat->devfn = PCI_MASK_BUS(bdf);
|
||||
pplat->vendor = vendor;
|
||||
pplat->device = device;
|
||||
pplat->class = class;
|
||||
if (dev) {
|
||||
pplat = dev_get_parent_platdata(dev);
|
||||
pplat->devfn = PCI_MASK_BUS(bdf);
|
||||
pplat->vendor = vendor;
|
||||
pplat->device = device;
|
||||
pplat->class = class;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -605,6 +631,13 @@ error:
|
||||
|
||||
static int pci_uclass_post_bind(struct udevice *bus)
|
||||
{
|
||||
/*
|
||||
* If there is no pci device listed in the device tree,
|
||||
* don't bother scanning the device tree.
|
||||
*/
|
||||
if (bus->of_offset == -1)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Scan the device tree for devices. This does not probe the PCI bus,
|
||||
* as this is not permitted while binding. It just finds devices
|
||||
@ -717,10 +750,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Don't scan buses before relocation */
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
return 0;
|
||||
|
||||
debug("%s: probing bus %d\n", __func__, bus->seq);
|
||||
ret = pci_bind_bus_devices(bus);
|
||||
if (ret)
|
||||
@ -730,6 +759,24 @@ static int pci_uclass_post_probe(struct udevice *bus)
|
||||
ret = pci_auto_config_devices(bus);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
|
||||
/*
|
||||
* Per Intel FSP specification, we should call FSP notify API to
|
||||
* inform FSP that PCI enumeration has been done so that FSP will
|
||||
* do any necessary initialization as required by the chipset's
|
||||
* BIOS Writer's Guide (BWG).
|
||||
*
|
||||
* Unfortunately we have to put this call here as with driver model,
|
||||
* the enumeration is all done on a lazy basis as needed, so until
|
||||
* something is touched on PCI it won't happen.
|
||||
*
|
||||
* Note we only call this 1) after U-Boot is relocated, and 2)
|
||||
* root bus has finished probing.
|
||||
*/
|
||||
if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0))
|
||||
ret = fsp_init_phase_pci();
|
||||
#endif
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
@ -754,8 +801,8 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
|
||||
if (ret != -ENOENT)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
/* extract the bdf from fdt_pci_addr */
|
||||
pplat->devfn = addr.phys_hi & 0xffff00;
|
||||
/* extract the devfn from fdt_pci_addr */
|
||||
pplat->devfn = addr.phys_hi & 0xff00;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -187,7 +187,7 @@ int pci_rom_load(struct pci_rom_header *rom_header,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct vbe_mode_info mode_info;
|
||||
struct vbe_mode_info mode_info;
|
||||
|
||||
int vbe_get_video_info(struct graphic_device *gdev)
|
||||
{
|
||||
@ -232,7 +232,6 @@ int vbe_get_video_info(struct graphic_device *gdev)
|
||||
|
||||
void setup_video(struct screen_info *screen_info)
|
||||
{
|
||||
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
|
||||
struct vesa_mode_info *vesa = &mode_info.vesa;
|
||||
|
||||
/* Sanity test on VESA parameters */
|
||||
@ -258,7 +257,6 @@ void setup_video(struct screen_info *screen_info)
|
||||
screen_info->blue_pos = vesa->blue_mask_pos;
|
||||
screen_info->rsvd_size = vesa->reserved_mask_size;
|
||||
screen_info->rsvd_pos = vesa->reserved_mask_pos;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
|
||||
|
@ -2247,16 +2247,17 @@ __weak int board_video_skip(void)
|
||||
|
||||
int drv_video_init(void)
|
||||
{
|
||||
int skip_dev_init;
|
||||
struct stdio_dev console_dev;
|
||||
bool have_keyboard;
|
||||
bool __maybe_unused keyboard_ok = false;
|
||||
|
||||
/* Check if video initialization should be skipped */
|
||||
if (board_video_skip())
|
||||
return 0;
|
||||
|
||||
/* Init video chip - returns with framebuffer cleared */
|
||||
skip_dev_init = (video_init() == -1);
|
||||
if (video_init() == -1)
|
||||
return 0;
|
||||
|
||||
if (board_cfb_skip())
|
||||
return 0;
|
||||
@ -2272,11 +2273,9 @@ int drv_video_init(void)
|
||||
if (have_keyboard) {
|
||||
debug("KBD: Keyboard init ...\n");
|
||||
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
|
||||
skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
|
||||
keyboard_ok = !(VIDEO_KBD_INIT_FCT == -1);
|
||||
#endif
|
||||
}
|
||||
if (skip_dev_init)
|
||||
return 0;
|
||||
|
||||
/* Init vga device */
|
||||
memset(&console_dev, 0, sizeof(console_dev));
|
||||
@ -2287,7 +2286,7 @@ int drv_video_init(void)
|
||||
console_dev.puts = video_puts; /* 'puts' function */
|
||||
|
||||
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
|
||||
if (have_keyboard) {
|
||||
if (have_keyboard && keyboard_ok) {
|
||||
/* Also init console device */
|
||||
console_dev.flags |= DEV_FLAGS_INPUT;
|
||||
console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <common.h>
|
||||
#include <asm/arch/tables.h>
|
||||
#include <asm/arch/sysinfo.h>
|
||||
#include <vbe.h>
|
||||
#include <video_fb.h>
|
||||
#include "videomodes.h"
|
||||
|
||||
@ -17,6 +18,26 @@
|
||||
*/
|
||||
GraphicDevice ctfb;
|
||||
|
||||
static void save_vesa_mode(void)
|
||||
{
|
||||
struct vesa_mode_info *vesa = &mode_info.vesa;
|
||||
struct cb_framebuffer *fb = lib_sysinfo.framebuffer;
|
||||
|
||||
vesa->x_resolution = fb->x_resolution;
|
||||
vesa->y_resolution = fb->y_resolution;
|
||||
vesa->bits_per_pixel = fb->bits_per_pixel;
|
||||
vesa->bytes_per_scanline = fb->bytes_per_line;
|
||||
vesa->phys_base_ptr = fb->physical_address;
|
||||
vesa->red_mask_size = fb->red_mask_size;
|
||||
vesa->red_mask_pos = fb->red_mask_pos;
|
||||
vesa->green_mask_size = fb->green_mask_size;
|
||||
vesa->green_mask_pos = fb->green_mask_pos;
|
||||
vesa->blue_mask_size = fb->blue_mask_size;
|
||||
vesa->blue_mask_pos = fb->blue_mask_pos;
|
||||
vesa->reserved_mask_size = fb->reserved_mask_size;
|
||||
vesa->reserved_mask_pos = fb->reserved_mask_pos;
|
||||
}
|
||||
|
||||
static int parse_coreboot_table_fb(GraphicDevice *gdev)
|
||||
{
|
||||
struct cb_framebuffer *fb = lib_sysinfo.framebuffer;
|
||||
@ -81,5 +102,8 @@ void *video_hw_init(void)
|
||||
memset((void *)gdev->pciBase, 0,
|
||||
gdev->winSizeX * gdev->winSizeY * gdev->gdfBytesPP);
|
||||
|
||||
/* Initialize vesa_mode_info structure */
|
||||
save_vesa_mode();
|
||||
|
||||
return (void *)gdev;
|
||||
}
|
||||
|
@ -256,9 +256,6 @@ struct ctfb_chips_properties {
|
||||
|
||||
static const struct ctfb_chips_properties chips[] = {
|
||||
{PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
|
||||
#ifdef CONFIG_USE_CPCIDVI
|
||||
{PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220},
|
||||
#endif
|
||||
{PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220}, /* NOT TESTED */
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0} /* Terminator */
|
||||
};
|
||||
@ -944,9 +941,6 @@ SetDrawingEngine (int bits_per_pixel)
|
||||
*/
|
||||
static struct pci_device_id supported[] = {
|
||||
{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
|
||||
#ifdef CONFIG_USE_CPCIDVI
|
||||
{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1111,22 +1105,7 @@ video_hw_init (void)
|
||||
pGD->cprBase = pci_mem_base; /* Dummy */
|
||||
/* set up Hardware */
|
||||
|
||||
#ifdef CONFIG_USE_CPCIDVI
|
||||
if (device_id == PCI_DEVICE_ID_CT_69030) {
|
||||
ctWrite (CT_MSR_W_O, 0x0b);
|
||||
ctWrite (0x3cd, 0x13);
|
||||
ctWrite_i (CT_FP_O, 0x02, 0x00);
|
||||
ctWrite_i (CT_FP_O, 0x05, 0x00);
|
||||
ctWrite_i (CT_FP_O, 0x06, 0x00);
|
||||
ctWrite (0x3c2, 0x0b);
|
||||
ctWrite_i (CT_FP_O, 0x02, 0x10);
|
||||
ctWrite_i (CT_FP_O, 0x01, 0x09);
|
||||
} else {
|
||||
ctWrite (CT_MSR_W_O, 0x01);
|
||||
}
|
||||
#else
|
||||
ctWrite (CT_MSR_W_O, 0x01);
|
||||
#endif
|
||||
|
||||
/* set the extended Registers */
|
||||
ctLoadRegs (CT_XR_O, xreg);
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
|
||||
#define CONFIG_ARCH_MISC_INIT
|
||||
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||
#define CONFIG_PCI_PNP
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
|
||||
#define CONFIG_PCI_IO_SIZE 0xe000
|
||||
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||
#define CONFIG_PCI_PNP
|
||||
|
||||
@ -54,9 +53,6 @@
|
||||
#define CONFIG_PCH_GBE
|
||||
#define CONFIG_PHYLIB
|
||||
|
||||
/* TunnelCreek IGD support */
|
||||
#define CONFIG_VGA_AS_SINGLE_DEVICE
|
||||
|
||||
/* Environment configuration */
|
||||
#define CONFIG_ENV_SECT_SIZE 0x1000
|
||||
#define CONFIG_ENV_OFFSET 0
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#define CONFIG_SMSC_LPC47M
|
||||
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||
#define CONFIG_PCI_PNP
|
||||
#define CONFIG_RTL8169
|
||||
|
@ -28,7 +28,6 @@
|
||||
#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
|
||||
#define CONFIG_PCI_IO_SIZE 0xe000
|
||||
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
#define CONFIG_PCI_PNP
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga\0" \
|
||||
|
@ -87,7 +87,9 @@
|
||||
#define CONFIG_ISO_PARTITION /* Experimental */
|
||||
|
||||
#define CONFIG_CMD_PART
|
||||
#ifdef CONFIG_SYS_COREBOOT
|
||||
#define CONFIG_CMD_CBFS
|
||||
#endif
|
||||
#define CONFIG_CMD_EXT4
|
||||
#define CONFIG_CMD_EXT4_WRITE
|
||||
#define CONFIG_PARTITION_UUIDS
|
||||
@ -190,6 +192,7 @@
|
||||
* PCI configuration
|
||||
*/
|
||||
#define CONFIG_PCI
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* USB configuration
|
||||
|
@ -10,52 +10,67 @@
|
||||
#ifndef _I8042_H_
|
||||
#define _I8042_H_
|
||||
|
||||
#ifdef __I386__
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#define in8(p) inb(p)
|
||||
#define out8(p,v) outb(v,p)
|
||||
#endif
|
||||
|
||||
/* defines */
|
||||
|
||||
#define I8042_DATA_REG (CONFIG_SYS_ISA_IO + 0x0060) /* keyboard i/o buffer */
|
||||
#define I8042_STATUS_REG (CONFIG_SYS_ISA_IO + 0x0064) /* keyboard status read */
|
||||
#define I8042_COMMAND_REG (CONFIG_SYS_ISA_IO + 0x0064) /* keyboard ctrl write */
|
||||
#define I8042_DATA_REG 0x60 /* keyboard i/o buffer */
|
||||
#define I8042_STS_REG 0x64 /* keyboard status read */
|
||||
#define I8042_CMD_REG 0x64 /* keyboard ctrl write */
|
||||
|
||||
enum {
|
||||
/* Output register (I8042_DATA_REG) has data for system */
|
||||
I8042_STATUS_OUT_DATA = 1 << 0,
|
||||
I8042_STATUS_IN_DATA = 1 << 1,
|
||||
};
|
||||
/* Status register bit defines */
|
||||
#define STATUS_OBF (1 << 0)
|
||||
#define STATUS_IBF (1 << 1)
|
||||
|
||||
#define KBD_US 0 /* default US layout */
|
||||
#define KBD_GER 1 /* german layout */
|
||||
/* Configuration byte bit defines */
|
||||
#define CONFIG_KIRQ_EN (1 << 0)
|
||||
#define CONFIG_MIRQ_EN (1 << 1)
|
||||
#define CONFIG_SET_BIST (1 << 2)
|
||||
#define CONFIG_KCLK_DIS (1 << 4)
|
||||
#define CONFIG_MCLK_DIS (1 << 5)
|
||||
#define CONFIG_AT_TRANS (1 << 6)
|
||||
|
||||
#define KBD_TIMEOUT 1000 /* 1 sec */
|
||||
#define KBD_RESET_TRIES 3
|
||||
/* i8042 commands */
|
||||
#define CMD_RD_CONFIG 0x20 /* read configuration byte */
|
||||
#define CMD_WR_CONFIG 0x60 /* write configuration byte */
|
||||
#define CMD_SELF_TEST 0xaa /* controller self-test */
|
||||
#define CMD_KBD_DIS 0xad /* keyboard disable */
|
||||
#define CMD_KBD_EN 0xae /* keyboard enable */
|
||||
#define CMD_SET_KBD_LED 0xed /* set keyboard led */
|
||||
#define CMD_RESET_KBD 0xff /* reset keyboard */
|
||||
|
||||
#define AS 0 /* normal character index */
|
||||
#define SH 1 /* shift index */
|
||||
#define CN 2 /* control index */
|
||||
#define NM 3 /* numeric lock index */
|
||||
#define AK 4 /* right alt key */
|
||||
#define CP 5 /* capslock index */
|
||||
#define ST 6 /* stop output index */
|
||||
#define EX 7 /* extended code index */
|
||||
#define ES 8 /* escape and extended code index */
|
||||
/* i8042 command result */
|
||||
#define KBC_TEST_OK 0x55
|
||||
#define KBD_ACK 0xfa
|
||||
#define KBD_POR 0xaa
|
||||
|
||||
#define NORMAL 0x0000 /* normal key */
|
||||
#define STP 0x0001 /* scroll lock stop output*/
|
||||
#define NUM 0x0002 /* numeric lock */
|
||||
#define CAPS 0x0004 /* capslock */
|
||||
#define SHIFT 0x0008 /* shift */
|
||||
#define CTRL 0x0010 /* control*/
|
||||
#define EXT 0x0020 /* extended scan code 0xe0 */
|
||||
#define ESC 0x0040 /* escape key press */
|
||||
#define E1 0x0080 /* extended scan code 0xe1 */
|
||||
#define BRK 0x0100 /* make break flag for keyboard */
|
||||
#define ALT 0x0200 /* right alt */
|
||||
/* keyboard scan codes */
|
||||
|
||||
#define KBD_US 0 /* default US layout */
|
||||
#define KBD_GER 1 /* german layout */
|
||||
|
||||
#define KBD_TIMEOUT 1000 /* 1 sec */
|
||||
#define KBD_RESET_TRIES 3
|
||||
|
||||
#define AS 0 /* normal character index */
|
||||
#define SH 1 /* shift index */
|
||||
#define CN 2 /* control index */
|
||||
#define NM 3 /* numeric lock index */
|
||||
#define AK 4 /* right alt key */
|
||||
#define CP 5 /* capslock index */
|
||||
#define ST 6 /* stop output index */
|
||||
#define EX 7 /* extended code index */
|
||||
#define ES 8 /* escape and extended code index */
|
||||
|
||||
#define NORMAL 0x0000 /* normal key */
|
||||
#define STP 0x0001 /* scroll lock stop output*/
|
||||
#define NUM 0x0002 /* numeric lock */
|
||||
#define CAPS 0x0004 /* capslock */
|
||||
#define SHIFT 0x0008 /* shift */
|
||||
#define CTRL 0x0010 /* control*/
|
||||
#define EXT 0x0020 /* extended scan code 0xe0 */
|
||||
#define ESC 0x0040 /* escape key press */
|
||||
#define E1 0x0080 /* extended scan code 0xe1 */
|
||||
#define BRK 0x0100 /* make break flag for keyboard */
|
||||
#define ALT 0x0200 /* right alt */
|
||||
|
||||
/* exports */
|
||||
|
||||
|
@ -653,6 +653,7 @@ extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
|
||||
#define pci_io_to_virt(dev, addr, len, map_flags) \
|
||||
pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
|
||||
|
||||
/* For driver model these are defined in macros in pci_compat.c */
|
||||
extern int pci_hose_read_config_byte(struct pci_controller *hose,
|
||||
pci_dev_t dev, int where, u8 *val);
|
||||
extern int pci_hose_read_config_word(struct pci_controller *hose,
|
||||
|
@ -7,14 +7,35 @@
|
||||
#ifndef _SMSC_LPC47M_H_
|
||||
#define _SMSC_LPC47M_H_
|
||||
|
||||
/* I/O address of LPC47M */
|
||||
#define LPC47M_IO_PORT 0x2e
|
||||
|
||||
/* Logical device number */
|
||||
#define LPC47M_FDC 0 /* Floppy */
|
||||
#define LPC47M_SP2 2 /* Serial Port 2 */
|
||||
#define LPC47M_PP 3 /* Parallel Port */
|
||||
#define LPC47M_SP1 4 /* Serial Port 1 */
|
||||
#define LPC47M_KBC 7 /* Keyboard & Mouse */
|
||||
#define LPC47M_PME 10 /* Power Control */
|
||||
|
||||
/**
|
||||
* Configure the base I/O port of the specified serial device and enable the
|
||||
* serial device.
|
||||
*
|
||||
* @dev: High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||
* @iobase: Processor I/O port address to assign to this serial device.
|
||||
* @irq: Processor IRQ number to assign to this serial device.
|
||||
* @dev: high 8 bits = super I/O port, low 8 bits = logical device number
|
||||
* @iobase: processor I/O port address to assign to this serial device
|
||||
* @irq: processor IRQ number to assign to this serial device
|
||||
*/
|
||||
void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq);
|
||||
void lpc47m_enable_serial(uint dev, uint iobase, uint irq);
|
||||
|
||||
/**
|
||||
* Configure the specified keyboard controller device and enable the keyboard
|
||||
* controller device.
|
||||
*
|
||||
* @dev: high 8 bits = Super I/O port, low 8 bits = logical device number
|
||||
* @irq0: processor IRQ number to assign to keyboard
|
||||
* @irq1: processor IRQ number to assign to mouse
|
||||
*/
|
||||
void lpc47m_enable_kbc(uint dev, uint irq0, uint irq1);
|
||||
|
||||
#endif /* _SMSC_LPC47M_H_ */
|
||||
|
@ -102,6 +102,8 @@ struct vbe_ddc_info {
|
||||
#define VESA_SET_MODE 0x4f02
|
||||
#define VESA_GET_CUR_MODE 0x4f03
|
||||
|
||||
extern struct vbe_mode_info mode_info;
|
||||
|
||||
struct graphic_device;
|
||||
int vbe_get_video_info(struct graphic_device *gdev);
|
||||
|
||||
|
@ -207,9 +207,8 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
|
||||
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
list += (len + 1);
|
||||
}
|
||||
list += (len + 1);
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
|
@ -297,6 +297,17 @@ $(obj)/%.dtb: $(src)/%.dts FORCE
|
||||
|
||||
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
|
||||
|
||||
# ACPI
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_acpi_c_asl= ASL $@
|
||||
cmd_acpi_c_asl= \
|
||||
$(CPP) -x assembler-with-cpp -P -o $<.tmp $<; \
|
||||
iasl -p $< -tc -va $<.tmp; \
|
||||
mv $(patsubst %.asl,%.hex,$<) $@
|
||||
|
||||
$(obj)/%.c: $(src)/%.asl
|
||||
$(call cmd,acpi_c_asl)
|
||||
|
||||
# Bzip2
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
238
tools/ifdtool.c
238
tools/ifdtool.c
@ -706,10 +706,11 @@ int inject_region(char *image, int size, int region_type, char *region_fname)
|
||||
* 0xffffffff so use an address relative to that. For an
|
||||
* 8MB ROM the start address is 0xfff80000.
|
||||
* @write_fname: Filename to add to the image
|
||||
* @offset_uboot_top: Offset of the top of U-Boot
|
||||
* @return number of bytes written if OK, -ve on error
|
||||
*/
|
||||
static int write_data(char *image, int size, unsigned int addr,
|
||||
const char *write_fname)
|
||||
const char *write_fname, int offset_uboot_top)
|
||||
{
|
||||
int write_fd, write_size;
|
||||
int offset;
|
||||
@ -719,6 +720,14 @@ static int write_data(char *image, int size, unsigned int addr,
|
||||
return write_fd;
|
||||
|
||||
offset = (uint32_t)(addr + size);
|
||||
if (offset_uboot_top && offset_uboot_top >= offset) {
|
||||
fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
|
||||
write_fname);
|
||||
fprintf(stderr,
|
||||
"U-Boot finishes at offset %x, file starts at %x\n",
|
||||
offset_uboot_top, offset);
|
||||
return -EXDEV;
|
||||
}
|
||||
debug("Writing %s to offset %#x\n", write_fname, offset);
|
||||
|
||||
if (offset < 0 || offset + write_size > size) {
|
||||
@ -737,6 +746,171 @@ static int write_data(char *image, int size, unsigned int addr,
|
||||
return write_size;
|
||||
}
|
||||
|
||||
static int scan_ucode(const void *blob, char *ucode_base, int *countp,
|
||||
const char **datap, int *data_sizep)
|
||||
{
|
||||
const char *data = NULL;
|
||||
int node, count;
|
||||
int data_size;
|
||||
char *ucode;
|
||||
|
||||
for (node = 0, count = 0, ucode = ucode_base; node >= 0; count++) {
|
||||
node = fdt_node_offset_by_compatible(blob, node,
|
||||
"intel,microcode");
|
||||
if (node < 0)
|
||||
break;
|
||||
|
||||
data = fdt_getprop(blob, node, "data", &data_size);
|
||||
if (!data) {
|
||||
debug("Missing microcode data in FDT '%s': %s\n",
|
||||
fdt_get_name(blob, node, NULL),
|
||||
fdt_strerror(data_size));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (ucode_base)
|
||||
memcpy(ucode, data, data_size);
|
||||
ucode += data_size;
|
||||
}
|
||||
|
||||
if (countp)
|
||||
*countp = count;
|
||||
if (datap)
|
||||
*datap = data;
|
||||
if (data_sizep)
|
||||
*data_sizep = data_size;
|
||||
|
||||
return ucode - ucode_base;
|
||||
}
|
||||
|
||||
static int remove_ucode(char *blob)
|
||||
{
|
||||
int node, count;
|
||||
int ret;
|
||||
|
||||
/* Keep going until we find no more microcode to remove */
|
||||
do {
|
||||
for (node = 0, count = 0; node >= 0;) {
|
||||
int ret;
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, node,
|
||||
"intel,microcode");
|
||||
if (node < 0)
|
||||
break;
|
||||
|
||||
ret = fdt_delprop(blob, node, "data");
|
||||
|
||||
/*
|
||||
* -FDT_ERR_NOTFOUND means we already removed the
|
||||
* data for this one, so we just continue.
|
||||
* 0 means we did remove it, so offsets may have
|
||||
* changed and we need to restart our scan.
|
||||
* Anything else indicates an error we should report.
|
||||
*/
|
||||
if (ret == -FDT_ERR_NOTFOUND)
|
||||
continue;
|
||||
else if (!ret)
|
||||
node = 0;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
} while (count);
|
||||
|
||||
/* Pack down to remove excees space */
|
||||
ret = fdt_pack(blob);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return fdt_totalsize(blob);
|
||||
}
|
||||
|
||||
static int write_ucode(char *image, int size, struct input_file *fdt,
|
||||
int fdt_size, unsigned int ucode_ptr,
|
||||
int collate_ucode)
|
||||
{
|
||||
const char *data = NULL;
|
||||
char *ucode_buf;
|
||||
const void *blob;
|
||||
char *ucode_base;
|
||||
uint32_t *ptr;
|
||||
int ucode_size;
|
||||
int data_size;
|
||||
int offset;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
blob = (void *)image + (uint32_t)(fdt->addr + size);
|
||||
|
||||
debug("DTB at %lx\n", (char *)blob - image);
|
||||
|
||||
/* Find out about the micrcode we have */
|
||||
ucode_size = scan_ucode(blob, NULL, &count, &data, &data_size);
|
||||
if (ucode_size < 0)
|
||||
return ucode_size;
|
||||
if (!count) {
|
||||
debug("No microcode found in FDT\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (count > 1 && !collate_ucode) {
|
||||
fprintf(stderr,
|
||||
"Cannot handle multiple microcode blocks - please use -C flag to collate them\n");
|
||||
return -EMLINK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect the microcode into a buffer, remove it from the device
|
||||
* tree and place it immediately above the (now smaller) device tree.
|
||||
*/
|
||||
if (collate_ucode && count > 1) {
|
||||
ucode_buf = malloc(ucode_size);
|
||||
if (!ucode_buf) {
|
||||
fprintf(stderr,
|
||||
"Out of memory for microcode (%d bytes)\n",
|
||||
ucode_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = scan_ucode(blob, ucode_buf, NULL, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Remove the microcode from the device tree */
|
||||
ret = remove_ucode((char *)blob);
|
||||
if (ret < 0) {
|
||||
debug("Could not remove FDT microcode: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return -EINVAL;
|
||||
}
|
||||
debug("Collated %d microcode block(s)\n", count);
|
||||
debug("Device tree reduced from %x to %x bytes\n",
|
||||
fdt_size, ret);
|
||||
fdt_size = ret;
|
||||
|
||||
/*
|
||||
* Place microcode area immediately above the FDT, aligned
|
||||
* to a 16-byte boundary.
|
||||
*/
|
||||
ucode_base = (char *)(((unsigned long)blob + fdt_size + 15) &
|
||||
~15);
|
||||
|
||||
data = ucode_base;
|
||||
data_size = ucode_size;
|
||||
memcpy(ucode_base, ucode_buf, ucode_size);
|
||||
free(ucode_buf);
|
||||
}
|
||||
|
||||
offset = (uint32_t)(ucode_ptr + size);
|
||||
ptr = (void *)image + offset;
|
||||
|
||||
ptr[0] = (data - image) - size;
|
||||
ptr[1] = data_size;
|
||||
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n", ucode_ptr,
|
||||
ptr[0], ptr[1]);
|
||||
|
||||
return (collate_ucode ? data + data_size : (char *)blob + fdt_size) -
|
||||
image;
|
||||
}
|
||||
|
||||
/**
|
||||
* write_uboot() - Write U-Boot, device tree and microcode pointer
|
||||
*
|
||||
@ -752,51 +926,28 @@ static int write_data(char *image, int size, unsigned int addr,
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
static int write_uboot(char *image, int size, struct input_file *uboot,
|
||||
struct input_file *fdt, unsigned int ucode_ptr)
|
||||
struct input_file *fdt, unsigned int ucode_ptr,
|
||||
int collate_ucode)
|
||||
{
|
||||
const void *blob;
|
||||
const char *data;
|
||||
int uboot_size;
|
||||
uint32_t *ptr;
|
||||
int data_size;
|
||||
int offset;
|
||||
int node;
|
||||
int ret;
|
||||
int uboot_size, fdt_size;
|
||||
|
||||
uboot_size = write_data(image, size, uboot->addr, uboot->fname);
|
||||
uboot_size = write_data(image, size, uboot->addr, uboot->fname, 0);
|
||||
if (uboot_size < 0)
|
||||
return uboot_size;
|
||||
fdt->addr = uboot->addr + uboot_size;
|
||||
debug("U-Boot size %#x, FDT at %#x\n", uboot_size, fdt->addr);
|
||||
ret = write_data(image, size, fdt->addr, fdt->fname);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
fdt_size = write_data(image, size, fdt->addr, fdt->fname, 0);
|
||||
if (fdt_size < 0)
|
||||
return fdt_size;
|
||||
blob = (void *)image + (uint32_t)(fdt->addr + size);
|
||||
|
||||
if (ucode_ptr) {
|
||||
blob = (void *)image + (uint32_t)(fdt->addr + size);
|
||||
debug("DTB at %lx\n", (char *)blob - image);
|
||||
node = fdt_node_offset_by_compatible(blob, 0,
|
||||
"intel,microcode");
|
||||
if (node < 0) {
|
||||
debug("No microcode found in FDT: %s\n",
|
||||
fdt_strerror(node));
|
||||
return -ENOENT;
|
||||
}
|
||||
data = fdt_getprop(blob, node, "data", &data_size);
|
||||
if (!data) {
|
||||
debug("No microcode data found in FDT: %s\n",
|
||||
fdt_strerror(data_size));
|
||||
return -ENOENT;
|
||||
}
|
||||
offset = (uint32_t)(ucode_ptr + size);
|
||||
ptr = (void *)image + offset;
|
||||
ptr[0] = (data - image) - size;
|
||||
ptr[1] = data_size;
|
||||
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n",
|
||||
ucode_ptr, ptr[0], ptr[1]);
|
||||
return write_ucode(image, size, fdt, fdt_size, ucode_ptr,
|
||||
collate_ucode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ((char *)blob + fdt_size) - image;
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
@ -860,7 +1011,7 @@ int main(int argc, char *argv[])
|
||||
int mode_dump = 0, mode_extract = 0, mode_inject = 0;
|
||||
int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0;
|
||||
int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0;
|
||||
int create = 0;
|
||||
int create = 0, collate_ucode = 0;
|
||||
char *region_type_string = NULL, *inject_fname = NULL;
|
||||
char *desc_fname = NULL, *addr_str = NULL;
|
||||
int region_type = -1, inputfreq = 0;
|
||||
@ -880,6 +1031,7 @@ int main(int argc, char *argv[])
|
||||
int ret;
|
||||
static struct option long_options[] = {
|
||||
{"create", 0, NULL, 'c'},
|
||||
{"collate-microcode", 0, NULL, 'C'},
|
||||
{"dump", 0, NULL, 'd'},
|
||||
{"descriptor", 1, NULL, 'D'},
|
||||
{"em100", 0, NULL, 'e'},
|
||||
@ -898,12 +1050,15 @@ int main(int argc, char *argv[])
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lm:r:s:uU:vw:x?",
|
||||
while ((opt = getopt_long(argc, argv, "cCdD:ef:hi:lm:r:s:uU:vw:x?",
|
||||
long_options, &option_index)) != EOF) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
create = 1;
|
||||
break;
|
||||
case 'C':
|
||||
collate_ucode = 1;
|
||||
break;
|
||||
case 'd':
|
||||
mode_dump = 1;
|
||||
break;
|
||||
@ -1113,22 +1268,25 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (mode_write_descriptor)
|
||||
ret = write_data(image, size, -size, desc_fname);
|
||||
ret = write_data(image, size, -size, desc_fname, 0);
|
||||
|
||||
if (mode_inject)
|
||||
ret = inject_region(image, size, region_type, inject_fname);
|
||||
|
||||
if (mode_write) {
|
||||
int offset_uboot_top = 0;
|
||||
|
||||
for (wr_idx = 0; wr_idx < wr_num; wr_idx++) {
|
||||
ifile = &input_file[wr_idx];
|
||||
if (ifile->type == IF_fdt) {
|
||||
continue;
|
||||
} else if (ifile->type == IF_uboot) {
|
||||
ret = write_uboot(image, size, ifile, fdt,
|
||||
ucode_ptr);
|
||||
ucode_ptr, collate_ucode);
|
||||
offset_uboot_top = ret;
|
||||
} else {
|
||||
ret = write_data(image, size, ifile->addr,
|
||||
ifile->fname);
|
||||
ifile->fname, offset_uboot_top);
|
||||
}
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
@ -264,7 +264,7 @@ def CreatePatches(start, count, series):
|
||||
"""
|
||||
if series.get('version'):
|
||||
version = '%s ' % series['version']
|
||||
cmd = ['git', 'format-patch', '-M', '--signoff']
|
||||
cmd = ['git', 'format-patch', '-D', '-M', '--signoff']
|
||||
if series.get('cover'):
|
||||
cmd.append('--cover-letter')
|
||||
prefix = series.GetPatchPrefix()
|
||||
|
Loading…
Reference in New Issue
Block a user