Lean Sheng Tan has submitted this change. ( https://review.coreboot.org/c/coreboot/+/71967 )
Change subject: soc/intel/xeon_sp/spr: Add ACPI support for Sapphire Rapids ......................................................................
soc/intel/xeon_sp/spr: Add ACPI support for Sapphire Rapids
Add ACPI support for Sapphire Rapids. Passes FWTS ACPI tests. The code was written from scratch because there are Xeon-SP specific implementation especially Integrated Input/Output (IIO).
Change-Id: Ic2a9be0222e122ae087b9cc8e1859d257e3411d6 Signed-off-by: Jonathan Zhang jonzhang@meta.com Signed-off-by: Johnny Lin johnny_lin@wiwynn.com Signed-off-by: Marc Jones marcj303@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/71967 Reviewed-by: Jonathan Zhang jon.zhixiong.zhang@gmail.com Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Christian Walter christian.walter@9elements.com Reviewed-by: Lean Sheng Tan sheng.tan@9elements.com --- A src/soc/intel/xeon_sp/spr/acpi/cxl_resource.asl A src/soc/intel/xeon_sp/spr/acpi/dino_resource.asl A src/soc/intel/xeon_sp/spr/acpi/iiostack.asl A src/soc/intel/xeon_sp/spr/acpi/pch.asl A src/soc/intel/xeon_sp/spr/acpi/pch_rp.asl A src/soc/intel/xeon_sp/spr/acpi/pci_resource.asl A src/soc/intel/xeon_sp/spr/acpi/ubox_resource.asl A src/soc/intel/xeon_sp/spr/acpi/uncore.asl A src/soc/intel/xeon_sp/spr/acpi/uncore_irq.asl M src/soc/intel/xeon_sp/spr/chip.h M src/soc/intel/xeon_sp/spr/chipset.cb M src/soc/intel/xeon_sp/spr/romstage.c A src/soc/intel/xeon_sp/spr/soc_acpi.c 13 files changed, 2,432 insertions(+), 48 deletions(-)
Approvals: build bot (Jenkins): Verified Lean Sheng Tan: Looks good to me, approved Jonathan Zhang: Looks good to me, but someone else must approve Christian Walter: Looks good to me, approved
diff --git a/src/soc/intel/xeon_sp/spr/acpi/cxl_resource.asl b/src/soc/intel/xeon_sp/spr/acpi/cxl_resource.asl new file mode 100644 index 0000000..299247f --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/cxl_resource.asl @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define _IIO_DEVICE_NAME(str, skt, stk) str##skt##stk +#define IIO_DEVICE_NAME(str, skt, stk) _IIO_DEVICE_NAME(str, skt, stk) +#define IIO_RESOURCE_NAME(res, str, skt, stk) res##str##skt##stk + +#define STR(s) #s +#define _IIO_DEVICE_UID(str, skt, stk) STR(str##skt##stk) +#define IIO_DEVICE_UID(str, skt, stk) _IIO_DEVICE_UID(str, skt, stk) + +Device (IIO_DEVICE_NAME(DEVPREFIX, SOCKET, STACK)) +{ + Name (_HID, "ACPI0017") /* CXL */ + Name (_CID, Package (0x02) + { + EisaId ("PNP0A08") /* PCI Express Bus */, + EisaId ("PNP0A03") /* PCI Bus */ + }) + Name (_UID, IIO_DEVICE_UID(DEVPREFIX, SOCKET, STACK)) + External (_SB.IIO_DEVICE_NAME(STPREFIX, SOCKET, STACK)) + Method (_STA, 0, NotSerialized) // _STA: Status + { + Return (_SB.IIO_DEVICE_NAME(STPREFIX, SOCKET, STACK)) + } + Method (_PRT, 0, NotSerialized) + { + Return (_SB.PRTID) + } + External (_SB.IIO_DEVICE_NAME(RESPREFIX, SOCKET, STACK)) + Method (_CRS, 0, NotSerialized) + { + Return (_SB.IIO_DEVICE_NAME(RESPREFIX, SOCKET, STACK)) + } + Name (SUPP, 0x00) // PCI _OSC Support Field Value + Name (CTRL, 0x00) // PCI _OSC Control Field Value + Name (SUPC, 0x00) // CXL _OSC Support Field Value + Name (CTRC, 0x00) // CXL _OSC Control Field Value + Name (_PXM, 0x00) /* _PXM: Device Proximity */ + Method (_OSC, 4, NotSerialized) + { + CreateDWordField (Arg3, 0x00, CDW1) + If (Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */ + || Arg0 == ToUUID ("68f2d50b-c469-4d8a-bd3d-941a103fd3fc")) + /* CXL */ + { + CreateDWordField (Arg3, 0x04, CDW2) + If (Arg2 > 0x02) + { + CreateDWordField (Arg3, 0x08, CDW3) + CreateDWordField (Arg3, 0x0C, CDW4) + CreateDWordField (Arg3, 0x10, CDW5) + } + SUPP = CDW2 + CTRL = CDW3 + SUPC = CDW4 + CTRC = CDW5 + If (SUPP & 0x16 != 0x16) + { + CTRL &= 0x1E + Sleep (0x03E8) + } + /* Never allow SHPC (no SHPC controller in system) */ + CTRL &= 0x1D + /* Disable Native PCIe AER handling from OS */ + CTRL &= 0x17 + If (Arg1 != 1) /* unknown revision */ + { + CDW1 |= 0x08 + } + If (CDW3 != CTRL) /* capabilities bits were masked */ + { + CDW1 |= 0x10 + } + CDW3 = CTRL + CDW5 = CTRC + Return (Arg3) + } + Else + { + /* indicate unrecognized UUID */ + CDW1 |= 0x04 + IO80 = 0xEE + Return (Arg3) + } + } +} diff --git a/src/soc/intel/xeon_sp/spr/acpi/dino_resource.asl b/src/soc/intel/xeon_sp/spr/acpi/dino_resource.asl new file mode 100644 index 0000000..606c074 --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/dino_resource.asl @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#undef PRTID +#define PRTID AR12 + +#undef DEVPREFIX +#define DEVPREFIX DI +#undef RESPREFIX +#define RESPREFIX DT +#include "pci_resource.asl" + +#undef DEVPREFIX +#define DEVPREFIX PM +#undef RESPREFIX +#define RESPREFIX MT +#include "pci_resource.asl" + +#undef DEVPREFIX +#define DEVPREFIX HQ +#undef RESPREFIX +#define RESPREFIX HT +#include "pci_resource.asl" + +#undef DEVPREFIX +#define DEVPREFIX PN +#undef RESPREFIX +#define RESPREFIX MU +#include "pci_resource.asl" + +#undef DEVPREFIX +#define DEVPREFIX HR +#undef RESPREFIX +#define RESPREFIX HU +#include "pci_resource.asl" diff --git a/src/soc/intel/xeon_sp/spr/acpi/iiostack.asl b/src/soc/intel/xeon_sp/spr/acpi/iiostack.asl new file mode 100644 index 0000000..bf70bbc --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/iiostack.asl @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* ***** PCI Stacks **** */ +#undef DEVPREFIX +#define DEVPREFIX PC +#undef RESPREFIX +#define RESPREFIX PT +#undef STPREFIX +#define STPREFIX ST + +#undef PRTID +#define PRTID AR00 +#undef STACK +#define STACK 0 +#include "pci_resource.asl" + +#undef PRTID +#define PRTID AR01 +#undef STACK +#define STACK 1 +#include "pci_resource.asl" + +#undef STACK +#define STACK 2 +#include "pci_resource.asl" + +#undef STACK +#define STACK 3 +#include "pci_resource.asl" + +#undef STACK +#define STACK 4 +#include "pci_resource.asl" + +#undef STACK +#define STACK 5 +#include "pci_resource.asl" + +/* ***** CXL Stacks **** */ +#undef DEVPREFIX +#define DEVPREFIX CX +#undef RESPREFIX +#define RESPREFIX CT + +#undef STACK +#define STACK 1 +#include "cxl_resource.asl" + +#undef STACK +#define STACK 2 +#include "cxl_resource.asl" + +#undef STACK +#define STACK 3 +#include "cxl_resource.asl" + +#undef STACK +#define STACK 4 +#include "cxl_resource.asl" + +#undef STACK +#define STACK 5 +#include "cxl_resource.asl" + +/* ***** DINO,CPM,HQM Stacks **** */ +#undef STACK +#define STACK 8 +#include "dino_resource.asl" + +#undef STACK +#define STACK 9 +#include "dino_resource.asl" + +#undef STACK +#define STACK A +#include "dino_resource.asl" + +#undef STACK +#define STACK B +#include "dino_resource.asl" + +/* ***** Uncore Stacks **** */ +#undef STACK +#define STACK D +#include "ubox_resource.asl" diff --git a/src/soc/intel/xeon_sp/spr/acpi/pch.asl b/src/soc/intel/xeon_sp/spr/acpi/pch.asl new file mode 100644 index 0000000..05b7d58 --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/pch.asl @@ -0,0 +1,392 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +OperationRegion (TMEM, PCI_Config, 0x00, 0x0100) +Field (TMEM, ByteAcc, NoLock, Preserve) +{ + Offset (0x40), + , 4, + BSEG, 4, + PAMS, 48, + Offset (0x52), + DIM0, 4, + DIM1, 4, + Offset (0x54), + DIM2, 4 +} + +Name (MTBL, Package (0x10) +{ + 0x00, + 0x20, + 0x20, + 0x30, + 0x40, + 0x40, + 0x60, + 0x80, + 0x80, + 0x80, + 0x80, + 0xC0, + 0x0100, + 0x0100, + 0x0100, + 0x0200 +}) +Name (ERNG, Package (0x0D) +{ + 0x000C0000, + 0x000C4000, + 0x000C8000, + 0x000CC000, + 0x000D0000, + 0x000D4000, + 0x000D8000, + 0x000DC000, + 0x000E0000, + 0x000E4000, + 0x000E8000, + 0x000EC000, + 0x000F0000 +}) +Name (PAMB, Buffer (0x07){}) + +Device (APIC) +{ + Name (_HID, EisaId ("PNP0003") /* IO-APIC Interrupt Controller */) + Name (_CRS, ResourceTemplate () + { + Memory32Fixed (ReadOnly, 0xFEC00000, 0x00100000) + }) +} + +Device (LPCB) +{ + Name (_ADR, 0x001F0000) + Name (_DDN, "LPC Bus Device") + + Device (DMAC) + { + Name (_HID, EisaId ("PNP0200") /* PC-class DMA Controller */) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0000, // Range Minimum + 0x0000, // Range Maximum + 0x00, // Alignment + 0x10, // Length + ) + IO (Decode16, + 0x0081, // Range Minimum + 0x0081, // Range Maximum + 0x00, // Alignment + 0x03, // Length + ) + IO (Decode16, + 0x0087, // Range Minimum + 0x0087, // Range Maximum + 0x00, // Alignment + 0x01, // Length + ) + IO (Decode16, + 0x0089, // Range Minimum + 0x0089, // Range Maximum + 0x00, // Alignment + 0x03, // Length + ) + IO (Decode16, + 0x008F, // Range Minimum + 0x008F, // Range Maximum + 0x00, // Alignment + 0x01, // Length + ) + IO (Decode16, + 0x00C0, // Range Minimum + 0x00C0, // Range Maximum + 0x00, // Alignment + 0x20, // Length + ) + DMA (Compatibility, NotBusMaster, Transfer8, ) + {4} + }) + } + + Device (RTC) + { + Name (_HID, EisaId ("PNP0B00") /* AT Real-Time Clock */) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0070, // Range Minimum + 0x0070, // Range Maximum + 0x01, // Alignment + 0x02, // Length + ) + IO (Decode16, + 0x0072, // Range Minimum + 0x0072, // Range Maximum + 0x01, // Alignment + 0x02, // Length + ) + IO (Decode16, + 0x0074, // Range Minimum + 0x0074, // Range Maximum + 0x01, // Alignment + 0x04, // Length + ) + IRQNoFlags () + {8} + }) + } + + Device (PIC) + { + Name (_HID, EisaId ("PNP0000") /* 8259-compatible Programmable Interrupt Controller */) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0020, // Range Minimum + 0x0020, // Range Maximum + 0x01, // Alignment + 0x1E, // Length + ) + IO (Decode16, + 0x00A0, // Range Minimum + 0x00A0, // Range Maximum + 0x01, // Alignment + 0x1E, // Length + ) + IO (Decode16, + 0x04D0, // Range Minimum + 0x04D0, // Range Maximum + 0x01, // Alignment + 0x02, // Length + ) + }) + } + + Device (FPU) + { + Name (_HID, EisaId ("PNP0C04") /* x87-compatible Floating Point Processing Unit */) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x00F0, // Range Minimum + 0x00F0, // Range Maximum + 0x01, // Alignment + 0x01, // Length + ) + IRQNoFlags () + {13} + }) + } + + Device (TMR) + { + Name (_HID, EisaId ("PNP0100")) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0040, // Range Minimum + 0x0040, // Range Maximum + 0x01, // Alignment + 0x04, // Length + ) + IO (Decode16, + 0x0050, // Range Minimum + 0x0050, // Range Maximum + 0x01, // Alignment + 0x04, // Length + ) + IRQNoFlags () + {0} + }) + } + + Device (SPKR) + { + Name (_HID, EisaId ("PNP0800")) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0061, // Range Minimum + 0x0061, // Range Maximum + 0x01, // Alignment + 0x01, // Length + ) + }) + } + + Device (XTRA) + { + Name (_HID, EisaId ("PNP0C02")) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0500, // Range Minimum + 0x0500, // Range Maximum + 0x01, // Alignment + 0xFF, // Length + ) + IO (Decode16, + 0x0400, // Range Minimum + 0x0400, // Range Maximum + 0x01, // Alignment + 0x20, // Length + ) + IO (Decode16, + 0x0010, // Range Minimum + 0x0010, // Range Maximum + 0x01, // Alignment + 0x10, // Length + ) + IO (Decode16, + 0x0080, // Range Minimum + 0x0080, // Range Maximum + 0x01, // Alignment + 0x01, // Length + ) + IO (Decode16, + 0x0084, // Range Minimum + 0x0084, // Range Maximum + 0x01, // Alignment + 0x03, // Length + ) + IO (Decode16, + 0x0088, // Range Minimum + 0x0088, // Range Maximum + 0x01, // Alignment + 0x01, // Length + ) + IO (Decode16, + 0x008C, // Range Minimum + 0x008C, // Range Maximum + 0x01, // Alignment + 0x03, // Length + ) + IO (Decode16, + 0x0090, // Range Minimum + 0x0090, // Range Maximum + 0x01, // Alignment + 0x10, // Length + ) + IO (Decode16, + 0x0600, // Range Minimum + 0x0600, // Range Maximum + 0x01, // Alignment + 0x20, // Length + ) + IO (Decode16, + 0x0CA0, // Range Minimum + 0x0CA0, // Range Maximum + 0x01, // Alignment + 0x02, // Length + ) + IO (Decode16, + 0x0CA4, // Range Minimum + 0x0CA4, // Range Maximum + 0x01, // Alignment + 0x03, // Length + ) + Memory32Fixed (ReadOnly, + 0xFF000000, // Address Base + 0x01000000, // Address Length + ) + }) + } + + Device (HPET) + { + Name (_HID, EisaId ("PNP0103") /* HPET System Timer */) + Method (_STA, 0, NotSerialized) // _STA: Status + { + Return (0x0F) + } + + Name (CRS0, ResourceTemplate () + { + Memory32Fixed (ReadWrite, + 0xFED00000, // Address Base + 0x00000400, // Address Length + ) + }) + Name (CRS1, ResourceTemplate () + { + Memory32Fixed (ReadWrite, + 0xFED01000, // Address Base + 0x00000400, // Address Length + ) + }) + Name (CRS2, ResourceTemplate () + { + Memory32Fixed (ReadWrite, + 0xFED02000, // Address Base + 0x00000400, // Address Length + ) + }) + Name (CRS3, ResourceTemplate () + { + Memory32Fixed (ReadWrite, + 0xFED03000, // Address Base + 0x00000400, // Address Length + ) + }) + Method (_CRS, 0, Serialized) + { + Return (CRS0) /* _SB_.PC00.HPET.CRS0 */ + } + } +} + +Device (HDAS) +{ + Name (_ADR, 0x001F0003) + OperationRegion (HDAR, PCI_Config, 0x00, 0x0100) + Field (HDAR, WordAcc, NoLock, Preserve) + { + VDID, 32 + } + + Name (_S0W, 0x03) // _S0W: S0 Device Wake State + Method (_DSW, 3, NotSerialized) // _DSW: Device Sleep Wake + { + } +} + +Scope (_GPE) +{ + OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0xFF) + Field (PMIO, ByteAcc, NoLock, Preserve) { + Offset(0x34), /* 0x34, SMI/SCI STS*/ + , 9, + SGCS, 1, /* SWGPE STS BIT */ + + Offset(0x40), /* 0x40, SMI/SCI_EN*/ + , 17, + SGPC, 1, /* SWGPE CTRL BIT */ + + Offset(0x6C), /* 0x6C, General Purpose Event 0 Status [127:96] */ + , 2, + SGPS, 1, /* SWGPE STATUS */ + + Offset(0x7C), /* 0x7C, General Purpose Event 0 Enable [127:96] */ + , 2, + SGPE, 1 /* SWGPE ENABLE */ + } + Device (RAS) + { + Name (_HID, EisaId ("PNP0C33")) + Name (_UID, 0) + Name (_DDN, "RAS Error Device Controller") + Printf ("Initialized RAS Device PNP0C33") + } + Method(_L62, 0) { + Printf ("SWGPE Method _L62") + SGPC = 0 // clear SWGPE enable + SGPS = 1 // clear SWGPE Status + Notify(RAS, 0x80) + } + +} + +#include "pch_rp.asl" diff --git a/src/soc/intel/xeon_sp/spr/acpi/pch_rp.asl b/src/soc/intel/xeon_sp/spr/acpi/pch_rp.asl new file mode 100644 index 0000000..c3a9104 --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/pch_rp.asl @@ -0,0 +1,705 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +Device (RP01) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00080000) + } + + Name (SLOT, 0x01) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP02) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00090000) + } + + Name (SLOT, 0x02) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP03) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000A0000) + } + + Name (SLOT, 0x03) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP04) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000B0000) + } + + Name (SLOT, 0x04) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP05) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000C0000) + } + + Name (SLOT, 0x05) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP06) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000D0000) + } + + Name (SLOT, 0x06) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP07) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000E0000) + } + + Name (SLOT, 0x07) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP08) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x000F0000) + } + + Name (SLOT, 0x08) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP09) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00100000) + } + + Name (SLOT, 0x09) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP10) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00110000) + } + + Name (SLOT, 0x0A) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP11) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00120000) + } + + Name (SLOT, 0x0B) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP12) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x00130000) + } + + Name (SLOT, 0x0C) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP13) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x001A0000) + } + + Name (SLOT, 0x0D) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP14) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x001B0000) + } + + Name (SLOT, 0x0E) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP15) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x001C0000) + } + + Name (SLOT, 0x0F) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} + +Device (RP16) +{ + Name (LTRZ, 0x00) + Name (LMSL, 0x00) + Name (LNSL, 0x00) + Method (_ADR, 0, NotSerialized) + { + Return (0x001C0000) + } + + Name (SLOT, 0x10) + + OperationRegion (PXCS, PCI_Config, 0x00, 0x0900) + Field (PXCS, AnyAcc, NoLock, Preserve) + { + VDID, 32, + Offset (0x60), + Offset (0x62), + PSPX, 1 + } + + Field (PXCS, AnyAcc, NoLock, WriteAsZeros) + { + Offset (0xCC), + Offset (0xCE), + PMSX, 1 + } + + Method (HPME, 0, Serialized) + { + If (VDID != 0xFFFFFFFF && PMSX == 0x01) + { + Notify (PXSX, 0x02) // Device Wake + PMSX = 0x01 + PSPX = 0x01 + } + } + + Device (PXSX) + { + Name (_ADR, 0x00) + } +} diff --git a/src/soc/intel/xeon_sp/spr/acpi/pci_resource.asl b/src/soc/intel/xeon_sp/spr/acpi/pci_resource.asl new file mode 100644 index 0000000..7988a16 --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/pci_resource.asl @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define _IIO_DEVICE_NAME(str, skt, stk) str##skt##stk +#define IIO_DEVICE_NAME(str, skt, stk) _IIO_DEVICE_NAME(str, skt, stk) +#define IIO_RESOURCE_NAME(res, str, skt, stk) res##str##skt##stk + +#define STR(s) #s +#define _IIO_DEVICE_UID(str, skt, stk) STR(str##skt##stk) +#define IIO_DEVICE_UID(str, skt, stk) _IIO_DEVICE_UID(str, skt, stk) + +Device (IIO_DEVICE_NAME(DEVPREFIX, SOCKET, STACK)) +{ + Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) + Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) + Name (_UID, IIO_DEVICE_UID(DEVPREFIX, SOCKET, STACK)) + External (_SB.IIO_DEVICE_NAME(STPREFIX, SOCKET, STACK)) + Method (_STA, 0, NotSerialized) + { + Return (_SB.IIO_DEVICE_NAME(STPREFIX, SOCKET, STACK)) + } + Method (_PRT, 0, NotSerialized) + { + Return (_SB.PRTID) + } + External (_SB.IIO_DEVICE_NAME(RESPREFIX, SOCKET, STACK)) + Method (_CRS, 0, NotSerialized) + { + Return (_SB.IIO_DEVICE_NAME(RESPREFIX, SOCKET, STACK)) + } + Name (SUPP, 0x00) + Name (CTRL, 0x00) + Name (_PXM, SOCKET) /* _PXM: Device Proximity */ + Method (_OSC, 4, NotSerialized) + { + CreateDWordField (Arg3, 0x00, CDW1) + If (Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */) + { + CreateDWordField (Arg3, 0x04, CDW2) + If (Arg2 > 0x02) + { + CreateDWordField (Arg3, 0x08, CDW3) + } + SUPP = CDW2 + CTRL = CDW3 + If (SUPP & 0x16 != 0x16) + { + CTRL &= 0x1E + Sleep (0x03E8) + } + /* Never allow SHPC (no SHPC controller in system) */ + CTRL &= 0x1D + /* Disable Native PCIe AER handling from OS */ + CTRL &= 0x17 + + If (Arg1 != 1) /* unknown revision */ + { + CDW1 |= 0x08 + } + If (CDW3 != CTRL) /* capabilities bits were masked */ + { + CDW1 |= 0x10 + } + CDW3 = CTRL + Return (Arg3) + } + Else + { + /* indicate unrecognized UUID */ + CDW1 |= 0x04 + IO80 = 0xEE + Return (Arg3) + } + } +} diff --git a/src/soc/intel/xeon_sp/spr/acpi/ubox_resource.asl b/src/soc/intel/xeon_sp/spr/acpi/ubox_resource.asl new file mode 100644 index 0000000..416150f --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/ubox_resource.asl @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#undef PRTID +#define PRTID AR10 + +#undef DEVPREFIX +#define DEVPREFIX UC +#undef RESPREFIX +#define RESPREFIX UT +#include "pci_resource.asl" + +#undef PRTID +#define PRTID AR11 + +#undef DEVPREFIX +#define DEVPREFIX UD +#undef RESPREFIX +#define RESPREFIX UU +#include "pci_resource.asl" diff --git a/src/soc/intel/xeon_sp/spr/acpi/uncore.asl b/src/soc/intel/xeon_sp/spr/acpi/uncore.asl new file mode 100644 index 0000000..c1b8bdc --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/uncore.asl @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/itss.h> +#include <intelblocks/pcr.h> +#include <soc/iomap.h> +#include <soc/irq.h> +#include <soc/pcr_ids.h> + +Scope (_SB) +{ + #include "uncore_irq.asl" + + #define SOCKET 0 + #include "iiostack.asl" + #undef SOCKET + + #if CONFIG(SOC_ACPI_HEST) + Method (_OSC, 4, NotSerialized) + { + CreateDWordField (Arg3, 0x00, CDW1) + CDW1 |= 0x10 /* enable apei */ + Return (Arg3) + } + #endif + + #if (CONFIG_MAX_SOCKET > 1) + #define SOCKET 1 + #include "iiostack.asl" + #undef SOCKET + #endif + + #if (CONFIG_MAX_SOCKET > 2) + #define SOCKET 2 + #include "iiostack.asl" + #undef SOCKET + #endif + + #if (CONFIG_MAX_SOCKET > 3) + #define SOCKET 3 + #include "iiostack.asl" + #undef SOCKET + #endif +} diff --git a/src/soc/intel/xeon_sp/spr/acpi/uncore_irq.asl b/src/soc/intel/xeon_sp/spr/acpi/uncore_irq.asl new file mode 100644 index 0000000..699be7e --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/acpi/uncore_irq.asl @@ -0,0 +1,381 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* IRQ mode has not been tested. */ + +Name (AR00, Package() { + // D31 + Package(){0x001FFFFF, 0, 0, 16 }, + Package(){0x001FFFFF, 1, 0, 17 }, + Package(){0x001FFFFF, 2, 0, 18 }, + Package(){0x001FFFFF, 3, 0, 19 }, + // D30 + Package(){0x001EFFFF, 0, 0, 16 }, + Package(){0x001EFFFF, 1, 0, 17 }, + Package(){0x001EFFFF, 2, 0, 18 }, + Package(){0x001EFFFF, 3, 0, 19 }, + // D29 + Package(){0x001DFFFF, 0, 0, 16 }, + Package(){0x001DFFFF, 1, 0, 17 }, + Package(){0x001DFFFF, 2, 0, 18 }, + Package(){0x001DFFFF, 3, 0, 19 }, + // D28 + Package(){0x001CFFFF, 0, 0, 16 }, + Package(){0x001CFFFF, 1, 0, 17 }, + Package(){0x001CFFFF, 2, 0, 18 }, + Package(){0x001CFFFF, 3, 0, 19 }, + // D27 + Package(){0x001BFFFF, 0, 0, 16 }, + Package(){0x001BFFFF, 1, 0, 17 }, + Package(){0x001BFFFF, 2, 0, 18 }, + Package(){0x001BFFFF, 3, 0, 19 }, + // D26 + Package(){0x001AFFFF, 0, 0, 16 }, + Package(){0x001AFFFF, 1, 0, 17 }, + Package(){0x001AFFFF, 2, 0, 18 }, + Package(){0x001AFFFF, 3, 0, 19 }, + // D25 + Package(){0x0019FFFF, 0, 0, 16 }, + Package(){0x0019FFFF, 1, 0, 17 }, + Package(){0x0019FFFF, 2, 0, 18 }, + Package(){0x0019FFFF, 3, 0, 19 }, + // D24 + Package(){0x0018FFFF, 0, 0, 16 }, + Package(){0x0018FFFF, 1, 0, 17 }, + Package(){0x0018FFFF, 2, 0, 18 }, + Package(){0x0018FFFF, 3, 0, 19 }, + // D23 + Package(){0x0017FFFF, 0, 0, 16 }, + Package(){0x0017FFFF, 1, 0, 17 }, + Package(){0x0017FFFF, 2, 0, 18 }, + Package(){0x0017FFFF, 3, 0, 19 }, + // D22 + Package(){0x0016FFFF, 0, 0, 16 }, + Package(){0x0016FFFF, 1, 0, 17 }, + Package(){0x0016FFFF, 2, 0, 18 }, + Package(){0x0016FFFF, 3, 0, 19 }, + // D21 + Package(){0x0015FFFF, 0, 0, 16 }, + Package(){0x0015FFFF, 1, 0, 17 }, + Package(){0x0015FFFF, 2, 0, 18 }, + Package(){0x0015FFFF, 3, 0, 19 }, + // D20 + Package(){0x0014FFFF, 0, 0, 16 }, + Package(){0x0014FFFF, 1, 0, 17 }, + Package(){0x0014FFFF, 2, 0, 18 }, + Package(){0x0014FFFF, 3, 0, 19 }, + // D19 + Package(){0x0013FFFF, 0, 0, 16 }, + Package(){0x0013FFFF, 1, 0, 17 }, + Package(){0x0013FFFF, 2, 0, 18 }, + Package(){0x0013FFFF, 3, 0, 19 }, + // D18 + Package(){0x0012FFFF, 0, 0, 16 }, + Package(){0x0012FFFF, 1, 0, 17 }, + Package(){0x0012FFFF, 2, 0, 18 }, + Package(){0x0012FFFF, 3, 0, 19 }, + // D17 + Package(){0x0011FFFF, 0, 0, 16 }, + Package(){0x0011FFFF, 1, 0, 17 }, + Package(){0x0011FFFF, 2, 0, 18 }, + Package(){0x0011FFFF, 3, 0, 19 }, + // D16 + Package(){0x0010FFFF, 0, 0, 16 }, + Package(){0x0010FFFF, 1, 0, 17 }, + Package(){0x0010FFFF, 2, 0, 18 }, + Package(){0x0010FFFF, 3, 0, 19 }, + // D15 + Package(){0x000FFFFF, 0, 0, 16 }, + Package(){0x000FFFFF, 1, 0, 17 }, + Package(){0x000FFFFF, 2, 0, 18 }, + Package(){0x000FFFFF, 3, 0, 19 }, + // D14 + Package(){0x000EFFFF, 0, 0, 16 }, + Package(){0x000EFFFF, 1, 0, 17 }, + Package(){0x000EFFFF, 2, 0, 18 }, + Package(){0x000EFFFF, 3, 0, 19 }, + // D13 + Package(){0x000DFFFF, 0, 0, 16 }, + Package(){0x000DFFFF, 1, 0, 17 }, + Package(){0x000DFFFF, 2, 0, 18 }, + Package(){0x000DFFFF, 3, 0, 19 }, + // D12 + Package(){0x000CFFFF, 0, 0, 16 }, + Package(){0x000CFFFF, 1, 0, 17 }, + Package(){0x000CFFFF, 2, 0, 18 }, + Package(){0x000CFFFF, 3, 0, 19 }, + // D11 + Package(){0x000BFFFF, 0, 0, 16 }, + Package(){0x000BFFFF, 1, 0, 17 }, + Package(){0x000BFFFF, 2, 0, 18 }, + Package(){0x000BFFFF, 3, 0, 19 }, + // D10 + Package(){0x000AFFFF, 0, 0, 16 }, + Package(){0x000AFFFF, 1, 0, 17 }, + Package(){0x000AFFFF, 2, 0, 18 }, + Package(){0x000AFFFF, 3, 0, 19 }, + // D9 + Package(){0x0009FFFF, 0, 0, 16 }, + Package(){0x0009FFFF, 1, 0, 17 }, + Package(){0x0009FFFF, 2, 0, 18 }, + Package(){0x0009FFFF, 3, 0, 19 }, + // D8 + Package(){0x0008FFFF, 0, 0, 16 }, + Package(){0x0008FFFF, 1, 0, 17 }, + Package(){0x0008FFFF, 2, 0, 18 }, + Package(){0x0008FFFF, 3, 0, 19 }, + + // [IIM0]: IIOMISC on PC00 + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, + // [RLK0]: Legacy PCI Express Port 0 on PC00 + Package() { 0x0003FFFF, 0, 0, 16 }, + Package() { 0x0007FFFF, 0, 0, 16 }, +}) + +Name (AR01, Package() { + // [IIM0]: IIOMISC on PCxx(non PC00) + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, + // [BRPA]: PCI Express Port A + Package() { 0x0001FFFF, 0, 0, 16 }, + Package() { 0x0001FFFF, 1, 0, 17 }, + Package() { 0x0001FFFF, 2, 0, 18 }, + Package() { 0x0001FFFF, 3, 0, 19 }, + // [BRPB]: PCI Express Port B + Package() { 0x0002FFFF, 0, 0, 16 }, + Package() { 0x0002FFFF, 1, 0, 17 }, + Package() { 0x0002FFFF, 2, 0, 18 }, + Package() { 0x0002FFFF, 3, 0, 19 }, + // [BRPC]: PCI Express Port C + Package() { 0x0003FFFF, 0, 0, 16 }, + Package() { 0x0003FFFF, 1, 0, 17 }, + Package() { 0x0003FFFF, 2, 0, 18 }, + Package() { 0x0003FFFF, 3, 0, 19 }, + // [BRPD]: PCI Express Port D + Package() { 0x0004FFFF, 0, 0, 16 }, + Package() { 0x0004FFFF, 1, 0, 17 }, + Package() { 0x0004FFFF, 2, 0, 18 }, + Package() { 0x0004FFFF, 3, 0, 19 }, + // [BRPE]: PCI Express Port E + Package() { 0x0005FFFF, 0, 0, 16 }, + Package() { 0x0005FFFF, 1, 0, 17 }, + Package() { 0x0005FFFF, 2, 0, 18 }, + Package() { 0x0005FFFF, 3, 0, 19 }, + // [BRPF]: PCI Express Port F + Package() { 0x0006FFFF, 0, 0, 16 }, + Package() { 0x0006FFFF, 1, 0, 17 }, + Package() { 0x0006FFFF, 2, 0, 18 }, + Package() { 0x0006FFFF, 3, 0, 19 }, + // [BRPG]: PCI Express Port G + Package() { 0x0007FFFF, 0, 0, 16 }, + Package() { 0x0007FFFF, 1, 0, 17 }, + Package() { 0x0007FFFF, 2, 0, 18 }, + Package() { 0x0007FFFF, 3, 0, 19 }, + // [BRPH]: PCI Express Port H + Package() { 0x0008FFFF, 0, 0, 16 }, + Package() { 0x0008FFFF, 1, 0, 17 }, + Package() { 0x0008FFFF, 2, 0, 18 }, + Package() { 0x0008FFFF, 3, 0, 19 }, + // [NTBR]: NTB IRQ routing table + Package() { 0x0009FFFF, 0, 0, 16 }, + Package() { 0x0009FFFF, 1, 0, 17 }, + Package() { 0x0009FFFF, 2, 0, 18 }, + Package() { 0x0009FFFF, 3, 0, 19 }, + // D23: SATA Port 0 + Package() { 0x0017FFFF, 0, 0, 16 }, + Package() { 0x0017FFFF, 1, 0, 17 }, + Package() { 0x0017FFFF, 2, 0, 18 }, + Package() { 0x0017FFFF, 3, 0, 19 }, + // D24: SATA Port 1 + Package() { 0x0018FFFF, 0, 0, 16 }, + Package() { 0x0018FFFF, 1, 0, 17 }, + Package() { 0x0018FFFF, 2, 0, 18 }, + Package() { 0x0018FFFF, 3, 0, 19 }, + // D25: SATA Port 2 + Package() { 0x0019FFFF, 0, 0, 16 }, + Package() { 0x0019FFFF, 1, 0, 17 }, + Package() { 0x0019FFFF, 2, 0, 18 }, + Package() { 0x0019FFFF, 3, 0, 19 }, + // D31: PCH devices + Package() { 0x001FFFFF, 0, 0, 16 }, + Package() { 0x001FFFFF, 1, 0, 17 }, + Package() { 0x001FFFFF, 2, 0, 18 }, + Package() { 0x001FFFFF, 3, 0, 19 }, +}) + +Name (AR02, Package() { + // [BRPA]: PCI Express Port A + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR03, Package() { + // [BRPB]: PCI Express Port B + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR04, Package() { + // [BRPC]: PCI Express Port C + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR05, Package() { + // [BRPD]: PCI Express Port D + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR06, Package() { + // [BRPE]: PCI Express Port E + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR07, Package() { + // [BRPF]: PCI Express Port F + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR08, Package() { + // [BRPG]: PCI Express Port G + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR09, Package() { + // [BRPH]: PCI Express Port H + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) + +Name (AR0A, Package() { + // [NTBR]: NTB IRQ routing table + Package() { 0x0009FFFF, 0, 0, 16 }, + Package() { 0x0009FFFF, 1, 0, 17 }, + Package() { 0x0009FFFF, 2, 0, 18 }, + Package() { 0x0009FFFF, 3, 0, 19 }, +}) + +Name (AR10, Package() { + // [UBX0]: Uncore 0 UBOX Device + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, + // [CSM0]: Uncore 0 CHASIS_SMBUS Devices + Package() { 0x000BFFFF, 0, 0, 16 }, + Package() { 0x000BFFFF, 1, 0, 17 }, + Package() { 0x000BFFFF, 2, 0, 18 }, + Package() { 0x000BFFFF, 3, 0, 19 }, + // [M2M0]: Uncore 0 MS2MEM_SCF_MS2MEM0 Device + Package() { 0x000CFFFF, 0, 0, 16 }, + Package() { 0x000CFFFF, 1, 0, 17 }, + Package() { 0x000CFFFF, 2, 0, 18 }, + Package() { 0x000CFFFF, 3, 0, 19 }, + // [M2M1]: Uncore 0 MS2MEM_SCF_MS2MEM1 Device + Package() { 0x000DFFFF, 0, 0, 16 }, + Package() { 0x000DFFFF, 1, 0, 17 }, + Package() { 0x000DFFFF, 2, 0, 18 }, + Package() { 0x000DFFFF, 3, 0, 19 }, + // [MCD0]: Uncore 0 MCDDR0 Device + Package() { 0x001AFFFF, 0, 0, 16 }, + Package() { 0x001AFFFF, 1, 0, 17 }, + Package() { 0x001AFFFF, 2, 0, 18 }, + Package() { 0x001AFFFF, 3, 0, 19 }, + // [MCD1]: Uncore 0 MCDDR1 Device + Package() { 0x001BFFFF, 0, 0, 16 }, + Package() { 0x001BFFFF, 1, 0, 17 }, + Package() { 0x001BFFFF, 2, 0, 18 }, + Package() { 0x001BFFFF, 3, 0, 19 }, +}) + +Name (AR11, Package() { + // [CHA1]: Uncore 1 GRP1_CHA8-10 Device + Package() { 0x0001FFFF, 0, 0, 16 }, + Package() { 0x0001FFFF, 1, 0, 17 }, + Package() { 0x0001FFFF, 2, 0, 18 }, + Package() { 0x0001FFFF, 3, 0, 19 }, + // [CHA2]: Uncore 1 GRP0_CHA0-7 Device + Package() { 0x000AFFFF, 0, 0, 16 }, + Package() { 0x000AFFFF, 1, 0, 17 }, + Package() { 0x000AFFFF, 2, 0, 18 }, + Package() { 0x000AFFFF, 3, 0, 19 }, + // [CHA3]: Uncore 1 GRP0_CHA8-10 Device + Package() { 0x00B0FFFF, 0, 0, 16 }, + Package() { 0x00B0FFFF, 1, 0, 17 }, + Package() { 0x00B0FFFF, 2, 0, 18 }, + Package() { 0x00B0FFFF, 3, 0, 19 }, + // [CA00]: Uncore 1 CHAALL0-1 Device + Package() { 0x001DFFFF, 0, 0, 16 }, + Package() { 0x001DFFFF, 1, 0, 17 }, + Package() { 0x001DFFFF, 2, 0, 18 }, + Package() { 0x001DFFFF, 3, 0, 19 }, + // [PUC0]: Uncore 1 CHASIS_PUINT0-7 Device + Package() { 0x001EFFFF, 0, 0, 16 }, + Package() { 0x001EFFFF, 1, 0, 17 }, + Package() { 0x001EFFFF, 2, 0, 18 }, + Package() { 0x001EFFFF, 3, 0, 19 }, + // [GN30]: Uncore 1 Gen3Phy Device + Package() { 0x001FFFFF, 0, 0, 16 }, + Package() { 0x001FFFFF, 1, 0, 17 }, + Package() { 0x001FFFFF, 2, 0, 18 }, + Package() { 0x001FFFFF, 3, 0, 19 }, +}) + +Name (AR12, Package() { + // [IIO]: MISC Device + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, + // [IIO]: DSA0 Device + Package() { 0x0001FFFF, 0, 0, 16 }, + Package() { 0x0001FFFF, 1, 0, 17 }, + Package() { 0x0001FFFF, 2, 0, 18 }, + Package() { 0x0001FFFF, 3, 0, 19 }, + // [IIO]: IAX0 Device + Package() { 0x0002FFFF, 0, 0, 16 }, + Package() { 0x0002FFFF, 1, 0, 17 }, + Package() { 0x0002FFFF, 2, 0, 18 }, + Package() { 0x0002FFFF, 3, 0, 19 }, + // [IIO]: MSM Device + Package() { 0x0003FFFF, 0, 0, 16 }, + Package() { 0x0003FFFF, 1, 0, 17 }, + Package() { 0x0003FFFF, 2, 0, 18 }, + Package() { 0x0003FFFF, 3, 0, 19 }, + // [IIO]: NPK0 Device + Package() { 0x0004FFFF, 0, 0, 16 }, + Package() { 0x0004FFFF, 1, 0, 17 }, + Package() { 0x0004FFFF, 2, 0, 18 }, + Package() { 0x0004FFFF, 3, 0, 19 }, +}) + +Name (AR13, Package() { + // PCH PCIE express port IRQ routing table, which need align with the definition from AR00 + Package() { 0x0000FFFF, 0, 0, 16 }, + Package() { 0x0000FFFF, 1, 0, 17 }, + Package() { 0x0000FFFF, 2, 0, 18 }, + Package() { 0x0000FFFF, 3, 0, 19 }, +}) diff --git a/src/soc/intel/xeon_sp/spr/chip.h b/src/soc/intel/xeon_sp/spr/chip.h index c0e990b..5144372 100644 --- a/src/soc/intel/xeon_sp/spr/chip.h +++ b/src/soc/intel/xeon_sp/spr/chip.h @@ -29,37 +29,6 @@ struct pch_pcie_port pch_pci_port[MAX_PCH_PCIE_PORT];
/** - * Interrupt Routing configuration - * If bit7 is 1, the interrupt is disabled. - */ - uint8_t pirqa_routing; - uint8_t pirqb_routing; - uint8_t pirqc_routing; - uint8_t pirqd_routing; - uint8_t pirqe_routing; - uint8_t pirqf_routing; - uint8_t pirqg_routing; - uint8_t pirqh_routing; - - /** - * Device Interrupt Routing configuration - * Interrupt Pin x Route. - * 0h = PIRQA# - * 1h = PIRQB# - * 2h = PIRQC# - * 3h = PIRQD# - * 4h = PIRQE# - * 5h = PIRQF# - * 6h = PIRQG# - * 7h = PIRQH# - */ - uint16_t ir00_routing; - uint16_t ir01_routing; - uint16_t ir02_routing; - uint16_t ir03_routing; - uint16_t ir04_routing; - - /** * Device Interrupt Polarity Control * ipc0 - IRQ-00-31 - 1: Active low to IOAPIC, 0: Active high to IOAPIC * ipc1 - IRQ-32-63 - 1: Active low to IOAPIC, 0: Active high to IOAPIC diff --git a/src/soc/intel/xeon_sp/spr/chipset.cb b/src/soc/intel/xeon_sp/spr/chipset.cb index 9a913d9..79a8596 100644 --- a/src/soc/intel/xeon_sp/spr/chipset.cb +++ b/src/soc/intel/xeon_sp/spr/chipset.cb @@ -1,22 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-or-later
chip soc/intel/xeon_sp/spr - register "pirqa_routing" = "PCH_IRQ11" - register "pirqb_routing" = "PCH_IRQ10" - register "pirqc_routing" = "PCH_IRQ11" - register "pirqd_routing" = "PCH_IRQ11" - register "pirqe_routing" = "PCH_IRQ11" - register "pirqf_routing" = "PCH_IRQ11" - register "pirqg_routing" = "PCH_IRQ11" - register "pirqh_routing" = "PCH_IRQ11" - - # configure device interrupt routing - register "ir00_routing" = "0x3210" # IR00, Dev31 - register "ir01_routing" = "0x3210" # IR01, Dev30 - register "ir02_routing" = "0x3210" # IR02, Dev29 - register "ir03_routing" = "0x3210" # IR03, Dev28 - register "ir04_routing" = "0x3210" # IR04, Dev27 - # configure interrupt polarity control register "ipc0" = "0x00ff4000" # IPC0, PIRQA-H (IRQ16-23) should always be ActiveLow register "ipc1" = "0x00000000" # IPC1 diff --git a/src/soc/intel/xeon_sp/spr/romstage.c b/src/soc/intel/xeon_sp/spr/romstage.c index fe98f38..f4eae9c 100644 --- a/src/soc/intel/xeon_sp/spr/romstage.c +++ b/src/soc/intel/xeon_sp/spr/romstage.c @@ -169,7 +169,7 @@
m_cfg->VtdSupport = config->vtd_support;
- m_cfg->SerialIoUartDebugIoBase = 0x3F8; + m_cfg->SerialIoUartDebugIoBase = CONFIG_TTYS0_BASE;
mupd->FspmConfig.AttemptFastBoot = 1; mupd->FspmConfig.AttemptFastBootCold = 1; diff --git a/src/soc/intel/xeon_sp/spr/soc_acpi.c b/src/soc/intel/xeon_sp/spr/soc_acpi.c new file mode 100644 index 0000000..d9d82ac --- /dev/null +++ b/src/soc/intel/xeon_sp/spr/soc_acpi.c @@ -0,0 +1,591 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpigen.h> +#include <arch/smp/mpspec.h> +#include <assert.h> +#include <cbmem.h> +#include <cpu/intel/turbo.h> +#include <device/mmio.h> +#include <device/pci.h> +#include <intelblocks/acpi.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/pmclib.h> +#include <soc/acpi.h> +#include <soc/iomap.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_util.h> +#include <soc/util.h> +#include <hob_iiouds.h> + +int soc_madt_sci_irq_polarity(int sci) +{ + if (sci >= 20) + return MP_IRQ_POLARITY_LOW; + else + return MP_IRQ_POLARITY_HIGH; +} + +uint32_t soc_read_sci_irq_select(void) +{ + /* PMC controller is hidden - hence PWRMBASE can't be accessbile using PCI cfg space */ + uintptr_t pmc_bar = PCH_PWRM_BASE_ADDRESS; + return read32((void *)pmc_bar + PMC_ACPI_CNT); +} + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + + fadt->FADT_MinorVersion = 1; + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + /* Clear flags set by common/block/acpi/acpi.c acpi_fill_fadt() */ + fadt->flags &= ~ACPI_FADT_SEALED_CASE; + + fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER; + fadt->pm2_cnt_blk = pmbase + PM2_CNT; + fadt->pm2_cnt_len = 1; + fadt->gpe0_blk = pmbase + 0x60; + fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; + fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; + fadt->duty_offset = 1; + + fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + + /* PM2 Control Registers */ + fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_UNDEFINED; + fadt->x_pm2_cnt_blk.addrl = pmbase + PM2_CNT; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + /* PM1 Timer Register */ + fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + fadt->x_gpe0_blk.addrl = fadt->gpe0_blk; + fadt->x_gpe0_blk.addrh = 0x0; + + fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + fadt->x_gpe1_blk.addrl = fadt->gpe1_blk; + fadt->x_gpe1_blk.addrh = 0x0; +} + +static void create_dsdt_iou_pci_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri) +{ + /* + Stacks 0 (TYPE_UBOX_IIO) + Scope: PC<socket><stack>, ResourceTemplate: P0RS + Stacks 1 .. 5 (TYPE_UBOX_IIO) + Scope: PC<socket><stack>, ResourceTemplate: RBRS + */ + + /* Write ResourceTemplate resource name */ + char tres[16]; + snprintf(tres, sizeof(tres), "PT%d%X", socket, stack); + acpigen_write_name(tres); + + printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n", tres, + socket, stack); + + acpigen_write_resourcetemplate_header(); + + /* + * ACPI spec requires that each bus device (stack) has a valid + * resource template. Disabled devices still need a valid _CRS + * although the values are ignored. The FWTS sanity check does + * not pass when using the HOB stack resources to generate the + * _CRS resource template for disabled stacks, so we provide a + * zeroed resource template to satisfy both the spec and FWTS. + */ + const bool stack_enabled = ri->Personality < TYPE_RESERVED; + + /* Bus Resource */ + if (stack_enabled) { + /* For stack with CXL device, the PCIe bus resource is BusBase only. */ + if (is_iio_cxl_stack_res(ri)) + acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusBase, 0x0, 1); + else + acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusLimit, 0x0, + (ri->BusLimit - ri->BusBase + 1)); + } else { + acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0); + } + + /* Additional IO resources on socket 0 bus 0 */ + if (socket == 0 && stack == 0) { + /* ACPI 6.4.2.5 I/O Port Descriptor */ + acpigen_write_io16(0xCF8, 0xCFF, 0x1, 0x8, 1); + + /* IO decode CF8-CFF */ + acpigen_resource_word(1, 0xc, 0x3, 0, 0x0000, 0x03AF, 0, 0x03B0); + acpigen_resource_word(1, 0xc, 0x3, 0, 0x03E0, 0x0CF7, 0, 0x0918); + acpigen_resource_word(1, 0xc, 0x3, 0, 0x03B0, 0x03BB, 0, 0x000C); + acpigen_resource_word(1, 0xc, 0x3, 0, 0x03C0, 0x03DF, 0, 0x0020); + } + + /* IO resource */ + if (stack_enabled) { + acpigen_resource_word(1, 0xc, 0x3, 0, ri->PciResourceIoBase, + ri->PciResourceIoLimit, 0x0, + (ri->PciResourceIoLimit - ri->PciResourceIoBase + 1)); + + /* Additional Mem32 resources on socket 0 bus 0 */ + if (socket == 0 && stack == 0) { + acpigen_resource_dword(0, 0xc, 3, 0, VGA_BASE_ADDRESS, + (VGA_BASE_ADDRESS + VGA_BASE_SIZE - 1), 0x0, + VGA_BASE_SIZE); + acpigen_resource_dword(0, 0xc, 1, 0, SPI_BASE_ADDRESS, + (SPI_BASE_ADDRESS + SPI_BASE_SIZE - 1), 0x0, + SPI_BASE_SIZE); + } + + /* Mem32 resource */ + acpigen_resource_dword( + 0, 0xc, 1, 0, ri->PciResourceMem32Base, ri->PciResourceMem32Limit, 0x0, + (ri->PciResourceMem32Limit - ri->PciResourceMem32Base + 1)); + + /* Mem64 resource */ + acpigen_resource_qword( + 0, 0xc, 1, 0, ri->PciResourceMem64Base, ri->PciResourceMem64Limit, 0x0, + (ri->PciResourceMem64Limit - ri->PciResourceMem64Base + 1)); + } else { + /* Zeroed IO resource */ + acpigen_resource_word(1, 0, 3, 0, 0, 0, 0, 0); + + /* Zeroed Mem32 resource */ + acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0); + + /* Zeroed Mem64 resource */ + acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0); + } + + acpigen_write_resourcetemplate_footer(); +} + +static void create_dsdt_iou_cxl_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri) +{ + /* + Stacks 1 .. 5 (TYPE_UBOX_IIO) + Scope: CX<socket><stack>, ResourceTemplate: RBRS + */ + /* write ResourceTemplate resource name */ + char tres[16]; + snprintf(tres, sizeof(tres), "CT%d%X", socket, stack); + acpigen_write_name(tres); + + printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n", tres, + socket, stack); + + acpigen_write_resourcetemplate_header(); + + if (ri->Personality < TYPE_RESERVED) { + /* bus resource, from (BusBase + 1) to BusLimit */ + acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase + 1, ri->BusLimit, 0x0, + (ri->BusLimit - ri->BusBase)); + + /* IO resource */ + acpigen_resource_word(1, 0xc, 0x3, 0, ri->IoBase, ri->PciResourceIoBase - 1, + 0x0, ri->PciResourceIoBase - ri->IoBase); + + /* Mem32 resource */ + acpigen_resource_dword(0, 0xc, 1, 0, ri->Mmio32Base, + ri->PciResourceMem32Base - 1, 0x0, + ri->PciResourceMem32Base - ri->Mmio32Base); + + /* Mem64 resource */ + acpigen_resource_qword(0, 0xc, 1, 0, ri->Mmio64Base, + ri->PciResourceMem64Base - 1, 0x0, + ri->PciResourceMem64Base - ri->Mmio64Base); + } else { + /* bus resource, from (BusBase + 1) to BusLimit */ + acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0); + + /* IO resource */ + acpigen_resource_word(1, 0, 3, 0, 0, 0, 0, 0); + + /* Mem32 resource */ + acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0); + + /* Mem64 resource */ + acpigen_resource_qword(0, 0, 1, 0, 0, 0, 0, 0); + } + + acpigen_write_resourcetemplate_footer(); +} + +static void create_dsdt_dino_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri) +{ + /* + Stacks 8 .. B (TYPE_DINO) + Scope: DI<socket><stack> for DINO, ResourceTemplate: DT + Scope: CP<socket><stack> for CPM (i.e., QAT), ResourceTemplate: MT + Scope: HQ<socket><stack> for HQM (i.e., DLB), ResourceTemplate: HT + */ + + enum { + DSDT_DINO = 0, + DSDT_CPM, + DSDT_HQM, + DSDT_CPM1, + DSDT_HQM1 + }; + uint8_t rlist[] = {DSDT_DINO, DSDT_CPM, DSDT_HQM, DSDT_CPM1, DSDT_HQM1}; + + for (int i = 0; i < ARRAY_SIZE(rlist); ++i) { + uint8_t bus_base, bus_limit; + uint64_t mem64_base, mem64_limit; + char tres[16]; + + /* Note, This allocates the resources in a different order than + * coreboot (DINO base is last). This causes the kernel to + * reallocate the DINO BARs. + * TODO: Use the resource settings from coreboot */ + if (rlist[i] == DSDT_DINO) { + bus_base = ri->BusBase; + bus_limit = ri->BusBase; + mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE + + CPM_MMIO_SIZE + HQM_MMIO_SIZE; + mem64_limit = ri->PciResourceMem64Limit; + snprintf(tres, sizeof(tres), "DT%d%X", socket, stack); + } else if (rlist[i] == DSDT_CPM) { + bus_base = ri->BusBase + CPM_BUS_OFFSET; + bus_limit = bus_base + CPM_RESERVED_BUS; + mem64_base = ri->PciResourceMem64Base; + mem64_limit = mem64_base + CPM_MMIO_SIZE - 1; + snprintf(tres, sizeof(tres), "MT%d%X", socket, stack); + } else if (rlist[i] == DSDT_HQM) { + bus_base = ri->BusBase + HQM_BUS_OFFSET; + bus_limit = bus_base + HQM_RESERVED_BUS; + mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE; + mem64_limit = mem64_base + HQM_MMIO_SIZE - 1; + snprintf(tres, sizeof(tres), "HT%d%X", socket, stack); + } else if (rlist[i] == DSDT_CPM1) { + bus_base = ri->BusBase + CPM1_BUS_OFFSET; + bus_limit = bus_base + CPM_RESERVED_BUS; + mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE; + mem64_limit = mem64_base + CPM_MMIO_SIZE - 1; + snprintf(tres, sizeof(tres), "MU%d%X", socket, stack); + } else { // DSDT_HQM1 + bus_base = ri->BusBase + HQM1_BUS_OFFSET; + bus_limit = bus_base + HQM_RESERVED_BUS; + mem64_base = ri->PciResourceMem64Base + CPM_MMIO_SIZE + HQM_MMIO_SIZE + + CPM_MMIO_SIZE; + mem64_limit = mem64_base + HQM_MMIO_SIZE - 1; + snprintf(tres, sizeof(tres), "HU%d%X", socket, stack); + } + + printk(BIOS_DEBUG, + "\tCreating Dino ResourceTemplate %s for socket: %d, " + "stack: %d\n bus_base:0x%x, bus_limit:0x%x\n", + tres, socket, stack, bus_base, bus_limit); + + acpigen_write_name(tres); + acpigen_write_resourcetemplate_header(); + + if (ri->Personality < TYPE_RESERVED) { + acpigen_resource_word(2, 0xc, 0, 0, bus_base, bus_limit, 0x0, + (bus_limit - bus_base + 1)); + + /* Mem32 resource */ + if (rlist[i] == DSDT_DINO) + acpigen_resource_dword(0, 0xc, 1, 0, ri->PciResourceMem32Base, + ri->PciResourceMem32Limit, 0x0, + (ri->PciResourceMem32Limit + - ri->PciResourceMem32Base + 1)); + + /* Mem64 resource */ + acpigen_resource_qword(0, 0xc, 1, 0, mem64_base, mem64_limit, 0, + (mem64_limit - mem64_base + 1)); + } else { + acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0); + + /* Mem32 resource */ + if (rlist[i] == DSDT_DINO) + acpigen_resource_dword(0, 0, 1, 0, 0, 0, 0, 0); + + /* Mem64 resource */ + acpigen_resource_qword(0, 0, 1, 0, 0, 0, 0, 0); + } + + acpigen_write_resourcetemplate_footer(); + } +} + +static void create_dsdt_ubox_resource(uint8_t socket, uint8_t stack, const STACK_RES *ri) +{ + /* + Stacks D .. E (TYPE_UBOX) + Scope: UC/UD<socket><0..1> for UBOX[1-2], ResourceTemplate: UT/UU + */ + + for (int i = 0; i < 2; ++i) { + char tres[16]; + /* write ResourceTemplate resource name */ + if (i == 0) + snprintf(tres, sizeof(tres), "UT%d%X", socket, stack); + else + snprintf(tres, sizeof(tres), "UU%d%X", socket, stack); + + printk(BIOS_DEBUG, "\tCreating ResourceTemplate %s for socket: %d, stack: %d\n", + tres, socket, stack); + + acpigen_write_name(tres); + acpigen_write_resourcetemplate_header(); + + if (ri->Personality >= TYPE_RESERVED) + acpigen_resource_word(2, 0, 0, 0, 0, 0, 0, 0); + else if (i == 0) + acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase, ri->BusBase, 0x0, 1); + else + acpigen_resource_word(2, 0xc, 0, 0, ri->BusBase + 1, ri->BusBase + 1, + 0x0, 1); + + acpigen_write_resourcetemplate_footer(); + } +} + + +/* + * Add a DSDT ACPI Name field for STACK enable setting. + * This is retrieved by the device _STA defined in iiostack.asl + */ +static void create_dsdt_stack_sta(uint8_t socket, uint8_t stack, const STACK_RES *ri) +{ + char stack_sta[16]; + snprintf(stack_sta, sizeof(stack_sta), "ST%d%X", socket, stack); + + if (ri->Personality >= TYPE_RESERVED) + acpigen_write_name_integer(stack_sta, ACPI_STATUS_DEVICE_ALL_OFF); + else + acpigen_write_name_integer(stack_sta, ACPI_STATUS_DEVICE_ALL_ON); +} + +void uncore_inject_dsdt(const struct device *device) +{ + /* Only add RTxx entries once. */ + if (device->bus->secondary != 0) + return; + + /* + Write stack scope - this needs to match RP ACPI scopes. + Stacks 0 (TYPE_UBOX_IIO) + Scope: PC<socket><stack>, ResourceTemplate: P0RS + Stacks 1 .. 5 (TYPE_UBOX_IIO) + Scope: PC<socket><stack> & CX<socket><stack>, ResourceTemplate: RBRS + Stacks 8 .. B (TYPE_DINO) + Scope: DI<socket><stack> for DINO, ResourceTemplate: RBRS + Scope: CP<socket><stack> for CPM (i.e., QAT), ResourceTemplate: RBRS + Scope: HQ<socket><stack> for HQM (i.e., DLB), ResourceTemplate: RBRS + Stacks D .. E (TYPE_UBOX) + Scope: UC<socket><0..1> for UBOX[1-2], ResourceTemplate: UNRS + */ + + printk(BIOS_DEBUG, "%s device: %s\n", __func__, dev_path(device)); + + acpigen_write_scope("\_SB"); + + /* The _CSR generation must match SPR iiostack.asl. */ + const IIO_UDS *hob = get_iio_uds(); + /* TODO: DSDT uses CONFIG_MAX_SOCKET while PlatformData.numofIIO is the actual number + of CPUs plugged in, although it doesn't cause serious errors when not all CPUs are + plugged in, they should be in sync. */ + for (uint8_t socket = 0; socket < hob->PlatformData.numofIIO; ++socket) { + for (int stack = 0; stack < MAX_LOGIC_IIO_STACK; ++stack) { + const STACK_RES *ri = + &hob->PlatformData.IIO_resource[socket].StackRes[stack]; + + printk(BIOS_DEBUG, "%s processing socket: %d, stack: %d, type: %d\n", + __func__, socket, stack, ri->Personality); + + if (stack <= IioStack5) { // TYPE_UBOX_IIO + create_dsdt_iou_pci_resource(socket, stack, ri); + create_dsdt_iou_cxl_resource(socket, stack, ri); + create_dsdt_stack_sta(socket, stack, ri); + } else if (stack >= IioStack8 && stack <= IioStack11) { // TYPE_DINO + create_dsdt_dino_resource(socket, stack, ri); + create_dsdt_stack_sta(socket, stack, ri); + } else if (stack == IioStack13) { // TYPE_UBOX + create_dsdt_ubox_resource(socket, stack, ri); + create_dsdt_stack_sta(socket, stack, ri); + } + } + } + + acpigen_pop_len(); +} + +/* TODO: See if we can use the common generate_p_state_entries */ +void soc_power_states_generation(int core, int cores_per_package) +{ + int ratio_min, ratio_max, ratio_turbo, ratio_step; + int coord_type, power_max, power_unit, num_entries; + int ratio, power, clock, clock_max; + msr_t msr; + + /* Determine P-state coordination type from MISC_PWR_MGMT[0] */ + msr = rdmsr(MSR_MISC_PWR_MGMT); + if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS) + coord_type = SW_ANY; + else + coord_type = HW_ALL; + + /* Get bus ratio limits and calculate clock speeds */ + msr = rdmsr(MSR_PLATFORM_INFO); + ratio_min = (msr.hi >> (40 - 32)) & 0xff; /* Max Efficiency Ratio */ + + /* Determine if this CPU has configurable TDP */ + if (cpu_config_tdp_levels()) { + /* Set max ratio to nominal TDP ratio */ + msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); + ratio_max = msr.lo & 0xff; + } else { + /* Max Non-Turbo Ratio */ + ratio_max = (msr.lo >> 8) & 0xff; + } + clock_max = ratio_max * CONFIG_CPU_BCLK_MHZ; + + /* Calculate CPU TDP in mW */ + msr = rdmsr(MSR_PKG_POWER_SKU_UNIT); + power_unit = 2 << ((msr.lo & 0xf) - 1); + msr = rdmsr(MSR_PKG_POWER_SKU); + power_max = ((msr.lo & 0x7fff) / power_unit) * 1000; + + /* Write _PCT indicating use of FFixedHW */ + acpigen_write_empty_PCT(); + + /* Write _PPC with no limit on supported P-state */ + acpigen_write_PPC_NVS(); + + /* Write PSD indicating configured coordination type */ + acpigen_write_PSD_package(core, 1, coord_type); + + /* Add P-state entries in _PSS table */ + acpigen_write_name("_PSS"); + + /* Determine ratio points */ + ratio_step = PSS_RATIO_STEP; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; + if (num_entries > PSS_MAX_ENTRIES) { + ratio_step += 1; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; + } + + /* P[T] is Turbo state if enabled */ + if (get_turbo_state() == TURBO_ENABLED) { + /* _PSS package count including Turbo */ + acpigen_write_package(num_entries + 2); + + msr = rdmsr(MSR_TURBO_RATIO_LIMIT); + ratio_turbo = msr.lo & 0xff; + + /* Add entry for Turbo ratio */ + acpigen_write_PSS_package(clock_max + 1, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_turbo << 8, /* control */ + ratio_turbo << 8); /* status */ + } else { + /* _PSS package count without Turbo */ + acpigen_write_package(num_entries + 1); + } + + /* First regular entry is max non-turbo ratio */ + acpigen_write_PSS_package(clock_max, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_max << 8, /* control */ + ratio_max << 8); /* status */ + + /* Generate the remaining entries */ + for (ratio = ratio_min + ((num_entries - 1) * ratio_step); ratio >= ratio_min; + ratio -= ratio_step) { + + /* Calculate power at this ratio */ + power = common_calculate_power_ratio(power_max, ratio_max, ratio); + clock = ratio * CONFIG_CPU_BCLK_MHZ; + // clock = 1; + acpigen_write_PSS_package(clock, /* MHz */ + power, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio << 8, /* control */ + ratio << 8); /* status */ + } + + /* Fix package length */ + acpigen_pop_len(); +} + +unsigned long xeonsp_acpi_create_madt_lapics(unsigned long current) +{ + struct device *cpu; + uint8_t num_cpus = 0; + + for (cpu = all_devices; cpu; cpu = cpu->next) { + if ((cpu->path.type != DEVICE_PATH_APIC) + || (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { + continue; + } + if (!cpu->enabled) + continue; + current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, num_cpus, + cpu->path.apic.apic_id); + num_cpus++; + } + + return current; +} + +unsigned long acpi_fill_cedt(unsigned long current) +{ + const IIO_UDS *hob = get_iio_uds(); + union uid { + uint32_t data; + struct { + uint8_t byte0; + uint8_t byte1; + uint8_t byte2; + uint8_t byte3; + }; + } cxl_uid; + u32 cxl_ver; + u64 base; + + cxl_uid.byte0 = 'C'; + cxl_uid.byte1 = 'X'; + /* Loop through all sockets and stacks, add CHBS for each CXL IIO stack */ + for (uint8_t s = 0; s < hob->PlatformData.numofIIO; ++s) { + for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) { + const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x]; + if (!is_iio_cxl_stack_res(ri)) + continue; + /* uid needs to match with ACPI CXL device ID, eg. acpi/iiostack.asl */ + cxl_uid.byte2 = s + '0'; + cxl_uid.byte3 = x + '0'; + cxl_ver = ACPI_CEDT_CHBS_CXL_VER_1_1; + base = ri->Mmio32Base; /* DP RCRB base */ + current += acpi_create_cedt_chbs((acpi_cedt_chbs_t *)current, + cxl_uid.data, cxl_ver, base); + } + } + + return current; +}