Commit 697ec431 authored by Bin Meng's avatar Bin Meng

x86: qemu: Drop our own ACPI implementation

Our own ACPI implementation (when CONFIG_QEMU_ACPI_TABLE is not set)
does not build anymore after x86 has been fully converted to DM PCI.
Instead of trying to fix the build errors, given we now have the ACPI
support via QEMU's fw_cfg interface, which is a more reliable way to
generate correct ACPI tables than by ourselves, hence drop our own
ACPI implementation.
Signed-off-by: 's avatarBin Meng <bmeng.cn@gmail.com>
Reviewed-by: 's avatarSimon Glass <sjg@chromium.org>
parent ee8b25fa
......@@ -8,6 +8,3 @@ ifndef CONFIG_EFI_STUB
obj-y += car.o dram.o
endif
obj-y += cpu.o fw_cfg.o qemu.o
ifndef CONFIG_QEMU_ACPI_TABLE
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
endif
/*
* 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;
}
/* 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)
}
}
}
/* 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)
}
}
/* 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 */
)
})
}
}
/* 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 }
})
}
}
/* 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)
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment