diff options
author | Iru Cai <mytbk920423@gmail.com> | 2019-10-30 14:21:52 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2019-10-30 14:48:38 +0800 |
commit | ae51f41d14f548d494ac41e0d21137c5a4c3f59c (patch) | |
tree | 6ddb9d1aaa7bd5bad5bbf8497edc2e08ff208d79 /arch/x86 | |
download | uext4-ae51f41d14f548d494ac41e0d21137c5a4c3f59c.tar.xz |
import the U-Boot code and make it compile
Diffstat (limited to 'arch/x86')
153 files changed, 14908 insertions, 0 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h new file mode 100644 index 0000000..4475d04 --- /dev/null +++ b/arch/x86/include/asm/acpi.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __ASM_ACPI_H__ +#define __ASM_ACPI_H__ + +struct acpi_fadt; + +/** + * acpi_find_fadt() - find ACPI FADT table in the system memory + * + * This routine parses the ACPI table to locate the ACPI FADT table. + * + * @return: a pointer to the ACPI FADT table in the system memory + */ +struct acpi_fadt *acpi_find_fadt(void); + +/** + * acpi_find_wakeup_vector() - find OS installed wake up vector address + * + * This routine parses the ACPI table to locate the wake up vector installed + * by the OS previously. + * + * @fadt: a pointer to the ACPI FADT table in the system memory + * @return: wake up vector address installed by the OS + */ +void *acpi_find_wakeup_vector(struct acpi_fadt *fadt); + +/** + * enter_acpi_mode() - enter into ACPI mode + * + * This programs the ACPI-defined PM1_CNT register to enable SCI interrupt + * so that the whole system swiches to ACPI mode. + * + * @pm1_cnt: PM1_CNT register I/O address + */ +void enter_acpi_mode(int pm1_cnt); + +#endif /* __ASM_ACPI_H__ */ diff --git a/arch/x86/include/asm/acpi/debug.asl b/arch/x86/include/asm/acpi/debug.asl new file mode 100644 index 0000000..6025507 --- /dev/null +++ b/arch/x86/include/asm/acpi/debug.asl @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/arch/x86/acpi/debug.asl + */ + +/* POST register region */ +OperationRegion(X80, SystemIO, 0x80, 1) +Field(X80, ByteAcc, NoLock, Preserve) +{ + P80, 8 +} + +/* Legacy serial port register region */ +OperationRegion(CREG, SystemIO, 0x3F8, 8) +Field(CREG, ByteAcc, NoLock, Preserve) +{ + CDAT, 8, + CDLM, 8, + , 8, + CLCR, 8, + CMCR, 8, + CLSR, 8 +} + +/* DINI - Initialize the serial port to 115200 8-N-1 */ +Method(DINI) +{ + Store(0x83, CLCR) + Store(0x01, CDAT) /* 115200 baud (low) */ + Store(0x00, CDLM) /* 115200 baud (high) */ + Store(0x03, CLCR) /* word=8 stop=1 parity=none */ + Store(0x03, CMCR) /* DTR=1 RTS=1 out1/2=Off loop=Off */ + Store(0x00, CDLM) /* turn off interrupts */ +} + +/* THRE - Wait for serial port transmitter holding register to go empty */ +Method(THRE) +{ + And(CLSR, 0x20, Local0) + While (LEqual(Local0, Zero)) { + And(CLSR, 0x20, Local0) + } +} + +/* OUTX - Send a single raw character */ +Method(OUTX, 1) +{ + THRE() + Store(Arg0, CDAT) +} + +/* OUTC - Send a single character, expanding LF into CR/LF */ +Method(OUTC, 1) +{ + If (LEqual(Arg0, 0x0a)) { + OUTX(0x0d) + } + OUTX(Arg0) +} + +/* DBGN - Send a single hex nibble */ +Method(DBGN, 1) +{ + And(Arg0, 0x0f, Local0) + If (LLess(Local0, 10)) { + Add(Local0, 0x30, Local0) + } Else { + Add(Local0, 0x37, Local0) + } + OUTC(Local0) +} + +/* DBGB - Send a hex byte */ +Method(DBGB, 1) +{ + ShiftRight(Arg0, 4, Local0) + DBGN(Local0) + DBGN(Arg0) +} + +/* DBGW - Send a hex word */ +Method(DBGW, 1) +{ + ShiftRight(Arg0, 8, Local0) + DBGB(Local0) + DBGB(Arg0) +} + +/* DBGD - Send a hex dword */ +Method(DBGD, 1) +{ + ShiftRight(Arg0, 16, Local0) + DBGW(Local0) + DBGW(Arg0) +} + +/* Get a char from a string */ +Method(GETC, 2) +{ + CreateByteField(Arg0, Arg1, DBGC) + Return (DBGC) +} + +/* DBGO - Send either a string or an integer */ +Method(DBGO, 1, Serialized) +{ + If (LEqual(ObjectType(Arg0), 1)) { + If (LGreater(Arg0, 0xffff)) { + DBGD(Arg0) + } Else { + If (LGreater(Arg0, 0xff)) { + DBGW(Arg0) + } Else { + DBGB(Arg0) + } + } + } Else { + Name(BDBG, Buffer(80) {}) + Store(Arg0, BDBG) + Store(0, Local1) + While (One) { + Store(GETC(BDBG, Local1), Local0) + If (LEqual(Local0, 0)) { + Return (Zero) + } + OUTC(Local0) + Increment(Local1) + } + } + + Return (Zero) +} diff --git a/arch/x86/include/asm/acpi/global_nvs.h b/arch/x86/include/asm/acpi/global_nvs.h new file mode 100644 index 0000000..d56d35c --- /dev/null +++ b/arch/x86/include/asm/acpi/global_nvs.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ACPI_GNVS_H_ +#define _ACPI_GNVS_H_ + +/* + * This file provides two ACPI global NVS macros: ACPI_GNVS_ADDR and + * ACPI_GNVS_SIZE. They are to be used in platform's global_nvs.asl file + * to declare the GNVS OperationRegion, as well as write_acpi_tables() + * for the GNVS address runtime fix up. + */ +#define ACPI_GNVS_ADDR 0xdeadbeef +#define ACPI_GNVS_SIZE 0x100 + +#endif /* _ACPI_GNVS_H_ */ diff --git a/arch/x86/include/asm/acpi/globutil.asl b/arch/x86/include/asm/acpi/globutil.asl new file mode 100644 index 0000000..5d50ef3 --- /dev/null +++ b/arch/x86/include/asm/acpi/globutil.asl @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/arch/x86/acpi/globutil.asl + */ + +Method(MIN, 2) +{ + If (LLess(Arg0, Arg1)) { + Return (Arg0) + } Else { + Return (Arg1) + } +} + +Method(SLEN, 1) +{ + Store(Arg0, Local0) + Return (Sizeof(Local0)) +} + +Method(S2BF, 1, Serialized) +{ + Add(SLEN(Arg0), One, Local0) + Name(BUFF, Buffer(Local0) {}) + Store(Arg0, BUFF) + Return (BUFF) +} + +/* + * SCMP - Strong string compare + * + * Checks both length and content + */ +Method(SCMP, 2) +{ + Store(S2BF(Arg0), Local0) + Store(S2BF(Arg1), Local1) + Store(Zero, Local4) + Store(SLEN(Arg0), Local5) + Store(SLEN(Arg1), Local6) + Store(MIN(Local5, Local6), Local7) + + While (LLess(Local4, Local7)) { + Store(Derefof(Index(Local0, Local4)), Local2) + Store(Derefof(Index(Local1, Local4)), Local3) + If (LGreater(Local2, Local3)) { + Return (One) + } Else { + If (LLess(Local2, Local3)) { + Return (Ones) + } + } + Increment(Local4) + } + + If (LLess(Local4, Local5)) { + Return (One) + } Else { + If (LLess(Local4, Local6)) { + Return (Ones) + } Else { + Return (Zero) + } + } +} + +/* + * WCMP - Weak string compare + * + * Checks to find Arg1 at beginning of Arg0. + * Fails if length(Arg0) < length(Arg1). + * Returns 0 on fail, 1 on pass. + */ +Method(WCMP, 2) +{ + Store(S2BF(Arg0), Local0) + Store(S2BF(Arg1), Local1) + If (LLess(SLEN(Arg0), SLEN(Arg1))) { + Return (Zero) + } + Store(Zero, Local2) + Store(SLEN(Arg1), Local3) + + While (LLess(Local2, Local3)) { + If (LNotEqual(Derefof(Index(Local0, Local2)), + Derefof(Index(Local1, Local2)))) { + Return (Zero) + } + Increment(Local2) + } + + Return (One) +} + +/* + * I2BM - Returns Bit Map + * + * Arg0 = IRQ Number (0-15) + */ +Method(I2BM, 1) +{ + Store(0, Local0) + If (LNotEqual(Arg0, 0)) { + Store(1, Local1) + ShiftLeft(Local1, Arg0, Local0) + } + + Return (Local0) +} diff --git a/arch/x86/include/asm/acpi/irq_helper.h b/arch/x86/include/asm/acpi/irq_helper.h new file mode 100644 index 0000000..6e404f4 --- /dev/null +++ b/arch/x86/include/asm/acpi/irq_helper.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 Sage Electronics Engineering, LLC. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/include/soc/irq_helper.h + */ + +/* + * This file intentionally gets included multiple times, to set pic and apic + * modes, so should not have guard statements added. + */ + +/* + * This file will use irqroute.asl and irqroute.h to generate the ACPI IRQ + * routing for the platform being compiled. + * + * This method uses #defines in irqroute.h along with the macros contained + * in this file to generate an IRQ routing for each PCI device in the system. + */ + +#undef PCI_DEV_PIRQ_ROUTES +#undef PCI_DEV_PIRQ_ROUTE +#undef ACPI_DEV_IRQ +#undef PCIE_BRIDGE_DEV +#undef RP_IRQ_ROUTES +#undef ROOTPORT_METHODS +#undef ROOTPORT_IRQ_ROUTES +#undef RP_METHOD + +#if defined(PIC_MODE) + +#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \ + Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 } + +#define RP_IRQ_ROUTES(prefix_, func_, a_, b_, c_, d_) \ +Name(prefix_ ## func_ ## P, Package() \ +{ \ + ACPI_DEV_IRQ(0x0000, 0, a_), \ + ACPI_DEV_IRQ(0x0000, 1, b_), \ + ACPI_DEV_IRQ(0x0000, 2, c_), \ + ACPI_DEV_IRQ(0x0000, 3, d_), \ +}) + +/* define as blank so ROOTPORT_METHODS only gets inserted once */ +#define ROOTPORT_METHODS(prefix_, dev_) + +#else /* defined(PIC_MODE) */ + +#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \ + Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ } + +#define RP_IRQ_ROUTES(prefix_, func_, a_, b_, c_, d_) \ +Name(prefix_ ## func_ ## A, Package() \ +{ \ + ACPI_DEV_IRQ(0x0000, 0, a_), \ + ACPI_DEV_IRQ(0x0000, 1, b_), \ + ACPI_DEV_IRQ(0x0000, 2, c_), \ + ACPI_DEV_IRQ(0x0000, 3, d_), \ +}) + +#define ROOTPORT_METHODS(prefix_, dev_) \ + RP_METHOD(prefix_, dev_, 0) \ + RP_METHOD(prefix_, dev_, 1) \ + RP_METHOD(prefix_, dev_, 2) \ + RP_METHOD(prefix_, dev_, 3) \ + RP_METHOD(prefix_, dev_, 4) \ + RP_METHOD(prefix_, dev_, 5) \ + RP_METHOD(prefix_, dev_, 6) \ + RP_METHOD(prefix_, dev_, 7) + +#endif /* defined(PIC_MODE) */ + +#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \ + ACPI_DEV_IRQ(dev_, 0, a_), \ + ACPI_DEV_IRQ(dev_, 1, b_), \ + ACPI_DEV_IRQ(dev_, 2, c_), \ + ACPI_DEV_IRQ(dev_, 3, d_) + +#define PCIE_BRIDGE_DEV(prefix_, dev_, a_, b_, c_, d_) \ + ROOTPORT_IRQ_ROUTES(prefix_, a_, b_, c_, d_) \ + ROOTPORT_METHODS(prefix_, dev_) + +#define ROOTPORT_IRQ_ROUTES(prefix_, a_, b_, c_, d_) \ + RP_IRQ_ROUTES(prefix_, 0, a_, b_, c_, d_) \ + RP_IRQ_ROUTES(prefix_, 1, b_, c_, d_, a_) \ + RP_IRQ_ROUTES(prefix_, 2, c_, d_, a_, b_) \ + RP_IRQ_ROUTES(prefix_, 3, d_, a_, b_, c_) \ + RP_IRQ_ROUTES(prefix_, 4, a_, b_, c_, d_) \ + RP_IRQ_ROUTES(prefix_, 5, b_, c_, d_, a_) \ + RP_IRQ_ROUTES(prefix_, 6, c_, d_, a_, b_) \ + RP_IRQ_ROUTES(prefix_, 7, d_, a_, b_, c_) + +#define RP_METHOD(prefix_, dev_, func_)\ +Device (prefix_ ## 0 ## func_) \ +{ \ + Name(_ADR, dev_ ## 000 ## func_) \ + Name(_PRW, Package() { 0, 0 }) \ + Method(_PRT) { \ + If (PICM) { \ + Return (prefix_ ## func_ ## A) \ + } Else { \ + Return (prefix_ ## func_ ## P) \ + } \ + } \ +} + +/* SoC specific PIRQ route configuration */ +#include <asm/arch/acpi/irqroute.h> diff --git a/arch/x86/include/asm/acpi/irqlinks.asl b/arch/x86/include/asm/acpi/irqlinks.asl new file mode 100644 index 0000000..9fc83a5 --- /dev/null +++ b/arch/x86/include/asm/acpi/irqlinks.asl @@ -0,0 +1,485 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/irqlinks.asl + */ + +/* + * Intel chipset PIRQ routing control ASL description + * + * The programming interface is common to most Intel chipsets. But the PRTx + * registers may be mapped to different blocks. Some chipsets map them to LPC + * device (00:1f:00) PCI configuration space (like TunnelCreek, Quark), while + * some newer Atom SoCs (like BayTrail, Braswell) map them to Intel Legacy + * Block (ILB) memory space. + * + * This file defines 8 PCI IRQ link devices which corresponds to 8 PIRQ lines + * PIRQ A/B/C/D/E/F/G/H. To incorperate this file, the PRTx registers must be + * defined somewhere else in the platform's ASL files. + */ + +Device (LNKA) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 1) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTA) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLA, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLA, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTA */ + ShiftLeft(1, And(PRTA, 0x0f), IRQ0) + + Return (RTLA) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTA) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTA, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKB) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 2) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTB) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLB, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLB, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTB */ + ShiftLeft(1, And(PRTB, 0x0f), IRQ0) + + Return (RTLB) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTB) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTB, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKC) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 3) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTC) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLC, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLC, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTC */ + ShiftLeft(1, And(PRTC, 0x0f), IRQ0) + + Return (RTLC) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTC) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTC, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKD) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 4) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTD) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLD, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLD, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTD */ + ShiftLeft(1, And(PRTD, 0x0f), IRQ0) + + Return (RTLD) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTD) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTD, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKE) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 5) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTE) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLE, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLE, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTE */ + ShiftLeft(1, And(PRTE, 0x0f), IRQ0) + + Return (RTLE) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTE) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTE, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKF) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 6) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTF) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLF, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLF, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTF */ + ShiftLeft(1, And(PRTF, 0x0f), IRQ0) + + Return (RTLF) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTF) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTF, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKG) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 7) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTG) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLG, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLG, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTG */ + ShiftLeft(1, And(PRTG, 0x0f), IRQ0) + + Return (RTLG) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTG) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTG, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} + +Device (LNKH) +{ + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 8) + + /* Disable method */ + Method(_DIS, 0, Serialized) + { + Store(0x80, PRTH) + } + + /* Possible Resource Settings for this Link */ + Name(_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) { 5, 6, 7, 10, 11, 12, 14, 15 } + }) + + /* Current Resource Settings for this link */ + Method(_CRS, 0, Serialized) + { + Name(RTLH, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLH, 1, IRQ0) + + /* Clear the WordField */ + Store(Zero, IRQ0) + + /* Set the bit from PRTH */ + ShiftLeft(1, And(PRTH, 0x0f), IRQ0) + + Return (RTLH) + } + + /* Set Resource Setting for this IRQ link */ + Method(_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + /* Which bit is set? */ + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTH) + } + + /* Status */ + Method(_STA, 0, Serialized) + { + If (And(PRTH, 0x80)) { + Return (STA_DISABLED) + } Else { + Return (STA_INVISIBLE) + } + } +} diff --git a/arch/x86/include/asm/acpi/irqroute.asl b/arch/x86/include/asm/acpi/irqroute.asl new file mode 100644 index 0000000..0ed7efd --- /dev/null +++ b/arch/x86/include/asm/acpi/irqroute.asl @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/irqroute.asl + */ + +Name(\PICM, 0) + +/* + * The _PIC method is called by the OS to choose between interrupt + * routing via the i8259 interrupt controller or the APIC. + * + * _PIC is called with a parameter of 0 for i8259 configuration and + * with a parameter of 1 for Local APIC/IOAPIC configuration. + */ +Method(\_PIC, 1) +{ + /* Remember the OS' IRQ routing choice */ + Store(Arg0, PICM) +} + +/* PCI interrupt routing */ +Method(_PRT) { + If (PICM) { + Return (Package() { + #undef PIC_MODE + #include "irq_helper.h" + PCI_DEV_PIRQ_ROUTES + }) + } Else { + Return (Package() { + #define PIC_MODE + #include "irq_helper.h" + PCI_DEV_PIRQ_ROUTES + }) + } + +} + +/* PCIe downstream ports interrupt routing */ +PCIE_BRIDGE_IRQ_ROUTES +#undef PIC_MODE +#include "irq_helper.h" +PCIE_BRIDGE_IRQ_ROUTES diff --git a/arch/x86/include/asm/acpi/sleepstates.asl b/arch/x86/include/asm/acpi/sleepstates.asl new file mode 100644 index 0000000..32e16a2 --- /dev/null +++ b/arch/x86/include/asm/acpi/sleepstates.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/sleepstates.asl + */ + +Name(\_S0, Package() {0x0, 0x0, 0x0, 0x0}) +#ifdef CONFIG_HAVE_ACPI_RESUME +Name(\_S3, Package() {0x5, 0x0, 0x0, 0x0}) +#endif +Name(\_S4, Package() {0x6, 0x0, 0x0, 0x0}) +Name(\_S5, Package() {0x7, 0x0, 0x0, 0x0}) diff --git a/arch/x86/include/asm/acpi/statdef.asl b/arch/x86/include/asm/acpi/statdef.asl new file mode 100644 index 0000000..6697bc4 --- /dev/null +++ b/arch/x86/include/asm/acpi/statdef.asl @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/arch/x86/acpi/statdef.asl + */ + +/* Status and notification definitions */ + +#define STA_MISSING 0x00 +#define STA_PRESENT 0x01 +#define STA_ENABLED 0x03 +#define STA_DISABLED 0x09 +#define STA_INVISIBLE 0x0b +#define STA_UNAVAILABLE 0x0d +#define STA_VISIBLE 0x0f + +/* SMBus status codes */ +#define SMB_OK 0x00 +#define SMB_UNKNOWN_FAIL 0x07 +#define SMB_DEV_ADDR_NAK 0x10 +#define SMB_DEVICE_ERROR 0x11 +#define SMB_DEV_CMD_DENIED 0x12 +#define SMB_UNKNOWN_ERR 0x13 +#define SMB_DEV_ACC_DENIED 0x17 +#define SMB_TIMEOUT 0x18 +#define SMB_HST_UNSUPP_PROTOCOL 0x19 +#define SMB_BUSY 0x1a +#define SMB_PKT_CHK_ERROR 0x1f + +/* Device Object Notification Values */ +#define NOTIFY_BUS_CHECK 0x00 +#define NOTIFY_DEVICE_CHECK 0x01 +#define NOTIFY_DEVICE_WAKE 0x02 +#define NOTIFY_EJECT_REQUEST 0x03 +#define NOTIFY_DEVICE_CHECK_JR 0x04 +#define NOTIFY_FREQUENCY_ERROR 0x05 +#define NOTIFY_BUS_MODE 0x06 +#define NOTIFY_POWER_FAULT 0x07 +#define NOTIFY_CAPABILITIES 0x08 +#define NOTIFY_PLD_CHECK 0x09 +#define NOTIFY_SLIT_UPDATE 0x0b +#define NOTIFY_SRA_UPDATE 0x0d + +/* Battery Device Notification Values */ +#define NOTIFY_BAT_STATUSCHG 0x80 +#define NOTIFY_BAT_INFOCHG 0x81 +#define NOTIFY_BAT_MAINTDATA 0x82 + +/* Power Source Object Notification Values */ +#define NOTIFY_PWR_STATUSCHG 0x80 +#define NOTIFY_PWR_INFOCHG 0x81 + +/* Thermal Zone Object Notification Values */ +#define NOTIFY_TZ_STATUSCHG 0x80 +#define NOTIFY_TZ_TRIPPTCHG 0x81 +#define NOTIFY_TZ_DEVLISTCHG 0x82 +#define NOTIFY_TZ_RELTBLCHG 0x83 + +/* Power Button Notification Values */ +#define NOTIFY_POWER_BUTTON 0x80 + +/* Sleep Button Notification Values */ +#define NOTIFY_SLEEP_BUTTON 0x80 + +/* Lid Notification Values */ +#define NOTIFY_LID_STATUSCHG 0x80 + +/* Processor Device Notification Values */ +#define NOTIFY_CPU_PPCCHG 0x80 +#define NOTIFY_CPU_CSTATECHG 0x81 +#define NOTIFY_CPU_THROTLCHG 0x82 + +/* User Presence Device Notification Values */ +#define NOTIFY_USR_PRESNCECHG 0x80 + +/* Ambient Light Sensor Notification Values */ +#define NOTIFY_ALS_ILLUMCHG 0x80 +#define NOTIFY_ALS_COLORTMPCHG 0x81 +#define NOTIFY_ALS_RESPCHG 0x82 diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h new file mode 100644 index 0000000..7588913 --- /dev/null +++ b/arch/x86/include/asm/acpi_table.h @@ -0,0 +1,417 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Based on acpi.c from coreboot + * + * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com> + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +#define RSDP_SIG "RSD PTR " /* RSDP pointer signature */ +#define OEM_ID "U-BOOT" /* U-Boot */ +#define OEM_TABLE_ID "U-BOOTBL" /* U-Boot Table */ +#define ASLC_ID "INTL" /* Intel ASL Compiler */ + +#define ACPI_RSDP_REV_ACPI_1_0 0 +#define ACPI_RSDP_REV_ACPI_2_0 2 + +/* + * 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, others 2 */ + u32 rsdt_address; /* Physical address of RSDT (32 bits) */ + u32 length; /* Total RSDP length (incl. extended part) */ + u64 xsdt_address; /* Physical address of XSDT (64 bits) */ + u8 ext_checksum; /* Checksum of the whole table */ + u8 reserved[3]; +}; + +/* Generic ACPI header, provided by (almost) all tables */ +struct __packed acpi_table_header { + char signature[4]; /* ACPI signature (4 ASCII characters) */ + u32 length; /* Table length in bytes (incl. header) */ + u8 revision; /* Table version (not ACPI version!) */ + 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 aslc_id[4]; /* ASL compiler vendor ID */ + u32 aslc_revision; /* ASL compiler revision number */ +}; + +/* A maximum number of 32 ACPI tables ought to be enough for now */ +#define MAX_ACPI_TABLES 32 + +/* 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]; +}; + +/* FADT Preferred Power Management Profile */ +enum acpi_pm_profile { + ACPI_PM_UNSPECIFIED = 0, + ACPI_PM_DESKTOP, + ACPI_PM_MOBILE, + ACPI_PM_WORKSTATION, + ACPI_PM_ENTERPRISE_SERVER, + ACPI_PM_SOHO_SERVER, + ACPI_PM_APPLIANCE_PC, + ACPI_PM_PERFORMANCE_SERVER, + ACPI_PM_TABLET +}; + +/* FADT flags for p_lvl2_lat and p_lvl3_lat */ +#define ACPI_FADT_C2_NOT_SUPPORTED 101 +#define ACPI_FADT_C3_NOT_SUPPORTED 1001 + +/* FADT Boot Architecture Flags */ +#define ACPI_FADT_LEGACY_FREE 0x00 +#define ACPI_FADT_LEGACY_DEVICES (1 << 0) +#define ACPI_FADT_8042 (1 << 1) +#define ACPI_FADT_VGA_NOT_PRESENT (1 << 2) +#define ACPI_FADT_MSI_NOT_SUPPORTED (1 << 3) +#define ACPI_FADT_NO_PCIE_ASPM_CONTROL (1 << 4) + +/* FADT Feature Flags */ +#define ACPI_FADT_WBINVD (1 << 0) +#define ACPI_FADT_WBINVD_FLUSH (1 << 1) +#define ACPI_FADT_C1_SUPPORTED (1 << 2) +#define ACPI_FADT_C2_MP_SUPPORTED (1 << 3) +#define ACPI_FADT_POWER_BUTTON (1 << 4) +#define ACPI_FADT_SLEEP_BUTTON (1 << 5) +#define ACPI_FADT_FIXED_RTC (1 << 6) +#define ACPI_FADT_S4_RTC_WAKE (1 << 7) +#define ACPI_FADT_32BIT_TIMER (1 << 8) +#define ACPI_FADT_DOCKING_SUPPORTED (1 << 9) +#define ACPI_FADT_RESET_REGISTER (1 << 10) +#define ACPI_FADT_SEALED_CASE (1 << 11) +#define ACPI_FADT_HEADLESS (1 << 12) +#define ACPI_FADT_SLEEP_TYPE (1 << 13) +#define ACPI_FADT_PCI_EXPRESS_WAKE (1 << 14) +#define ACPI_FADT_PLATFORM_CLOCK (1 << 15) +#define ACPI_FADT_S4_RTC_VALID (1 << 16) +#define ACPI_FADT_REMOTE_POWER_ON (1 << 17) +#define ACPI_FADT_APIC_CLUSTER (1 << 18) +#define ACPI_FADT_APIC_PHYSICAL (1 << 19) +#define ACPI_FADT_HW_REDUCED_ACPI (1 << 20) +#define ACPI_FADT_LOW_PWR_IDLE_S0 (1 << 21) + +enum acpi_address_space_type { + ACPI_ADDRESS_SPACE_MEMORY = 0, /* System memory */ + ACPI_ADDRESS_SPACE_IO, /* System I/O */ + ACPI_ADDRESS_SPACE_PCI, /* PCI config space */ + ACPI_ADDRESS_SPACE_EC, /* Embedded controller */ + ACPI_ADDRESS_SPACE_SMBUS, /* SMBus */ + ACPI_ADDRESS_SPACE_PCC = 0x0a, /* Platform Comm. Channel */ + ACPI_ADDRESS_SPACE_FIXED = 0x7f /* Functional fixed hardware */ +}; + +enum acpi_address_space_size { + ACPI_ACCESS_SIZE_UNDEFINED = 0, + ACPI_ACCESS_SIZE_BYTE_ACCESS, + ACPI_ACCESS_SIZE_WORD_ACCESS, + ACPI_ACCESS_SIZE_DWORD_ACCESS, + ACPI_ACCESS_SIZE_QWORD_ACCESS +}; + +struct acpi_gen_regaddr { + u8 space_id; /* Address space ID */ + u8 bit_width; /* Register size in bits */ + u8 bit_offset; /* Register bit offset */ + u8 access_size; /* Access size */ + u32 addrl; /* Register address, low 32 bits */ + u32 addrh; /* Register address, high 32 bits */ +}; + +/* FADT (Fixed ACPI Description Table) */ +struct __packed acpi_fadt { + struct acpi_table_header header; + u32 firmware_ctrl; + u32 dsdt; + u8 res1; + 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; + u16 arm_boot_arch; + u8 minor_revision; + 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; +}; + +/* FACS flags */ +#define ACPI_FACS_S4BIOS_F (1 << 0) +#define ACPI_FACS_64BIT_WAKE_F (1 << 1) + +/* FACS (Firmware ACPI Control Structure) */ +struct acpi_facs { + char signature[4]; /* "FACS" */ + u32 length; /* Length in bytes (>= 64) */ + u32 hardware_signature; /* Hardware signature */ + u32 firmware_waking_vector; /* Firmware waking vector */ + u32 global_lock; /* Global lock */ + u32 flags; /* FACS flags */ + u32 x_firmware_waking_vector_l; /* X FW waking vector, low */ + u32 x_firmware_waking_vector_h; /* X FW waking vector, high */ + u8 version; /* Version 2 */ + u8 res1[3]; + u32 ospm_flags; /* OSPM enabled flags */ + u8 res2[24]; +}; + +/* MADT flags */ +#define ACPI_MADT_PCAT_COMPAT (1 << 0) + +/* MADT (Multiple APIC Description Table) */ +struct acpi_madt { + struct acpi_table_header header; + u32 lapic_addr; /* Local APIC address */ + u32 flags; /* Multiple APIC flags */ +}; + +/* MADT: APIC Structure Type*/ +enum acpi_apic_types { + ACPI_APIC_LAPIC = 0, /* Processor local APIC */ + ACPI_APIC_IOAPIC, /* I/O APIC */ + ACPI_APIC_IRQ_SRC_OVERRIDE, /* Interrupt source override */ + ACPI_APIC_NMI_SRC, /* NMI source */ + ACPI_APIC_LAPIC_NMI, /* Local APIC NMI */ + ACPI_APIC_LAPIC_ADDR_OVERRIDE, /* Local APIC address override */ + ACPI_APIC_IOSAPIC, /* I/O SAPIC */ + ACPI_APIC_LSAPIC, /* Local SAPIC */ + ACPI_APIC_PLATFORM_IRQ_SRC, /* Platform interrupt sources */ + ACPI_APIC_LX2APIC, /* Processor local x2APIC */ + ACPI_APIC_LX2APIC_NMI, /* Local x2APIC NMI */ +}; + +/* MADT: Processor Local APIC Structure */ + +#define LOCAL_APIC_FLAG_ENABLED (1 << 0) + +struct acpi_madt_lapic { + u8 type; /* Type (0) */ + u8 length; /* Length in bytes (8) */ + u8 processor_id; /* ACPI processor ID */ + u8 apic_id; /* Local APIC ID */ + u32 flags; /* Local APIC flags */ +}; + +/* MADT: I/O APIC Structure */ +struct acpi_madt_ioapic { + u8 type; /* Type (1) */ + u8 length; /* Length in bytes (12) */ + u8 ioapic_id; /* I/O APIC ID */ + u8 reserved; + u32 ioapic_addr; /* I/O APIC address */ + u32 gsi_base; /* Global system interrupt base */ +}; + +/* MADT: Interrupt Source Override Structure */ +struct __packed acpi_madt_irqoverride { + u8 type; /* Type (2) */ + u8 length; /* Length in bytes (10) */ + u8 bus; /* ISA (0) */ + u8 source; /* Bus-relative int. source (IRQ) */ + u32 gsirq; /* Global system interrupt */ + u16 flags; /* MPS INTI flags */ +}; + +/* MADT: Local APIC NMI Structure */ +struct __packed acpi_madt_lapic_nmi { + u8 type; /* Type (4) */ + u8 length; /* Length in bytes (6) */ + u8 processor_id; /* ACPI processor ID */ + u16 flags; /* MPS INTI flags */ + u8 lint; /* Local APIC LINT# */ +}; + +/* MCFG (PCI Express MMIO config space BAR description table) */ +struct acpi_mcfg { + struct acpi_table_header header; + u8 reserved[8]; +}; + +struct acpi_mcfg_mmconfig { + u32 base_address_l; + u32 base_address_h; + u16 pci_segment_group_number; + u8 start_bus_number; + u8 end_bus_number; + u8 reserved[4]; +}; + +/* PM1_CNT bit defines */ +#define PM1_CNT_SCI_EN (1 << 0) + +/* ACPI global NVS structure */ +struct acpi_global_nvs; + +/* CSRT (Core System Resource Table) */ +struct acpi_csrt { + struct acpi_table_header header; +}; + +struct acpi_csrt_group { + u32 length; + u32 vendor_id; + u32 subvendor_id; + u16 device_id; + u16 subdevice_id; + u16 revision; + u16 reserved; + u32 shared_info_length; +}; + +struct acpi_csrt_shared_info { + u16 major_version; + u16 minor_version; + u32 mmio_base_low; + u32 mmio_base_high; + u32 gsi_interrupt; + u8 interrupt_polarity; + u8 interrupt_mode; + u8 num_channels; + u8 dma_address_width; + u16 base_request_line; + u16 num_handshake_signals; + u32 max_block_size; +}; + +/* DBG2 definitions are partially used for SPCR interface_type */ + +/* Types for port_type field */ + +#define ACPI_DBG2_SERIAL_PORT 0x8000 +#define ACPI_DBG2_1394_PORT 0x8001 +#define ACPI_DBG2_USB_PORT 0x8002 +#define ACPI_DBG2_NET_PORT 0x8003 + +/* Subtypes for port_subtype field */ + +#define ACPI_DBG2_16550_COMPATIBLE 0x0000 +#define ACPI_DBG2_16550_SUBSET 0x0001 +#define ACPI_DBG2_ARM_PL011 0x0003 +#define ACPI_DBG2_ARM_SBSA_32BIT 0x000D +#define ACPI_DBG2_ARM_SBSA_GENERIC 0x000E +#define ACPI_DBG2_ARM_DCC 0x000F +#define ACPI_DBG2_BCM2835 0x0010 + +#define ACPI_DBG2_1394_STANDARD 0x0000 + +#define ACPI_DBG2_USB_XHCI 0x0000 +#define ACPI_DBG2_USB_EHCI 0x0001 + +#define ACPI_DBG2_UNKNOWN 0x00FF + +/* SPCR (Serial Port Console Redirection table) */ +struct __packed acpi_spcr { + struct acpi_table_header header; + u8 interface_type; + u8 reserved[3]; + struct acpi_gen_regaddr serial_port; + u8 interrupt_type; + u8 pc_interrupt; + u32 interrupt; /* Global system interrupt */ + u8 baud_rate; + u8 parity; + u8 stop_bits; + u8 flow_control; + u8 terminal_type; + u8 reserved1; + u16 pci_device_id; /* Must be 0xffff if not PCI device */ + u16 pci_vendor_id; /* Must be 0xffff if not PCI device */ + u8 pci_bus; + u8 pci_device; + u8 pci_function; + u32 pci_flags; + u8 pci_segment; + u32 reserved2; +}; + +/* These can be used by the target port */ + +void acpi_fill_header(struct acpi_table_header *header, char *signature); +void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, + void *dsdt); +int acpi_create_madt_lapics(u32 current); +int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, + u32 addr, u32 gsi_base); +int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, + u8 bus, u8 source, u32 gsirq, u16 flags); +int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, + u8 cpu, u16 flags, u8 lint); +u32 acpi_fill_madt(u32 current); +int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, + u16 seg_nr, u8 start, u8 end); +u32 acpi_fill_mcfg(u32 current); +u32 acpi_fill_csrt(u32 current); +void acpi_create_gnvs(struct acpi_global_nvs *gnvs); +ulong write_acpi_tables(ulong start); + +/** + * acpi_get_rsdp_addr() - get ACPI RSDP table address + * + * This routine returns the ACPI RSDP table address in the system memory. + * + * @return: ACPI RSDP table address + */ +ulong acpi_get_rsdp_addr(void); + +#endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl new file mode 100644 index 0000000..aaf87f4 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/acpi/global_nvs.h> + +OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE) +Field(GNVS, ByteAcc, NoLock, Preserve) +{ + PCNT, 8, /* processor count */ + IURE, 8, /* internal UART enabled */ +} diff --git a/arch/x86/include/asm/arch-baytrail/acpi/gpio.asl b/arch/x86/include/asm/arch-baytrail/acpi/gpio.asl new file mode 100644 index 0000000..abe3756 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/gpio.asl @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/gpio.asl + */ + +/* SouthCluster GPIO */ +Device (GPSC) +{ + Name(_HID, "INT33FC") + Name(_CID, "INT33FC") + Name(_UID, 1) + + Name(RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0, 0x1000, RMEM) + Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,) + { + GPIO_SC_IRQ + } + }) + + Method(_CRS) + { + CreateDwordField(^RBUF, ^RMEM._BAS, RBAS) + Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSCORE, RBAS) + Return (^RBUF) + } + + Method(_STA) + { + Return (STA_VISIBLE) + } +} + +/* NorthCluster GPIO */ +Device (GPNC) +{ + Name(_HID, "INT33FC") + Name(_CID, "INT33FC") + Name(_UID, 2) + + Name(RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0, 0x1000, RMEM) + Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,) + { + GPIO_NC_IRQ + } + }) + + Method(_CRS) + { + CreateDwordField(^RBUF, ^RMEM._BAS, RBAS) + Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPNCORE, RBAS) + Return (^RBUF) + } + + Method(_STA) + { + Return (STA_VISIBLE) + } +} + +/* SUS GPIO */ +Device (GPSS) +{ + Name(_HID, "INT33FC") + Name(_CID, "INT33FC") + Name(_UID, 3) + + Name(RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0, 0x1000, RMEM) + Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , ,) + { + GPIO_SUS_IRQ + } + }) + + Method(_CRS) + { + CreateDwordField(^RBUF, ^RMEM._BAS, RBAS) + Add(IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSSUS, RBAS) + Return (^RBUF) + } + + Method(_STA) + { + Return (STA_VISIBLE) + } +} diff --git a/arch/x86/include/asm/arch-baytrail/acpi/irqroute.h b/arch/x86/include/asm/arch-baytrail/acpi/irqroute.h new file mode 100644 index 0000000..57921f2 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/irqroute.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/arch/device.h> + +#define PCI_DEV_PIRQ_ROUTES \ + PCI_DEV_PIRQ_ROUTE(GFX_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(EMMC_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SDIO_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SD_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SATA_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(XHCI_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(LPE_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(MMC45_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SIO1_DEV, A, B, C, D), \ + PCI_DEV_PIRQ_ROUTE(TXE_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(HDA_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(PCIE_DEV, A, B, C, D), \ + PCI_DEV_PIRQ_ROUTE(EHCI_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SIO2_DEV, A, B, C, D), \ + PCI_DEV_PIRQ_ROUTE(PCU_DEV, A, B, C, D) + +#define PCIE_BRIDGE_IRQ_ROUTES \ + PCIE_BRIDGE_DEV(RP, PCIE_DEV, A, B, C, D) diff --git a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl new file mode 100644 index 0000000..08b2f53 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/lpc.asl + */ + +/* Intel LPC Bus Device - 0:1f.0 */ + +Scope (\) +{ + /* Intel Legacy Block */ + OperationRegion(ILBS, SystemMemory, ILB_BASE_ADDRESS, ILB_BASE_SIZE) + Field(ILBS, AnyAcc, NoLock, Preserve) { + Offset (0x8), + PRTA, 8, + PRTB, 8, + PRTC, 8, + PRTD, 8, + PRTE, 8, + PRTF, 8, + PRTG, 8, + PRTH, 8, + Offset (0x88), + , 3, + UI3E, 1, + UI4E, 1 + } +} + +Device (LPCB) +{ + Name(_ADR, 0x001f0000) + + OperationRegion(LPC0, PCI_Config, 0x00, 0x100) + Field(LPC0, AnyAcc, NoLock, Preserve) { + Offset(0x08), + SRID, 8, + Offset(0x80), + C1EN, 1, + Offset(0x84) + } + + #include <asm/acpi/irqlinks.asl> + + /* Firmware Hub */ + Device (FWH) + { + Name(_HID, EISAID("INT0800")) + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, 0xff000000, 0x01000000) + }) + } + + /* 8259 Interrupt Controller */ + Device (PIC) + { + Name(_HID, EISAID("PNP0000")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x20, 0x20, 0x01, 0x02) + IO(Decode16, 0x24, 0x24, 0x01, 0x02) + IO(Decode16, 0x28, 0x28, 0x01, 0x02) + IO(Decode16, 0x2c, 0x2c, 0x01, 0x02) + IO(Decode16, 0x30, 0x30, 0x01, 0x02) + IO(Decode16, 0x34, 0x34, 0x01, 0x02) + IO(Decode16, 0x38, 0x38, 0x01, 0x02) + IO(Decode16, 0x3c, 0x3c, 0x01, 0x02) + IO(Decode16, 0xa0, 0xa0, 0x01, 0x02) + IO(Decode16, 0xa4, 0xa4, 0x01, 0x02) + IO(Decode16, 0xa8, 0xa8, 0x01, 0x02) + IO(Decode16, 0xac, 0xac, 0x01, 0x02) + IO(Decode16, 0xb0, 0xb0, 0x01, 0x02) + IO(Decode16, 0xb4, 0xb4, 0x01, 0x02) + IO(Decode16, 0xb8, 0xb8, 0x01, 0x02) + IO(Decode16, 0xbc, 0xbc, 0x01, 0x02) + IO(Decode16, 0x4d0, 0x4d0, 0x01, 0x02) + IRQNoFlags () { 2 } + }) + } + + /* 8254 timer */ + Device (TIMR) + { + Name(_HID, EISAID("PNP0100")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x40, 0x40, 0x01, 0x04) + IO(Decode16, 0x50, 0x50, 0x10, 0x04) + IRQNoFlags() { 0 } + }) + } + + /* HPET */ + Device (HPET) + { + Name(_HID, EISAID("PNP0103")) + Name(_CID, 0x010CD041) + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, HPET_BASE_ADDRESS, HPET_BASE_SIZE) + }) + + Method(_STA) + { + Return (STA_VISIBLE) + } + } + + /* Internal UART */ + Device (IURT) + { + Name(_HID, EISAID("PNP0501")) + Name(_UID, 1) + + Method(_STA, 0, Serialized) + { + If (LEqual(IURE, 1)) { + Store(1, UI3E) + Store(1, UI4E) + Store(1, C1EN) + Return (STA_VISIBLE) + } Else { + Return (STA_MISSING) + } + + } + + Method(_DIS, 0, Serialized) + { + Store(0, UI3E) + Store(0, UI4E) + Store(0, C1EN) + } + + Method(_CRS, 0, Serialized) + { + Name(BUF0, ResourceTemplate() + { + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 3 } + }) + + Name(BUF1, ResourceTemplate() + { + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 4 } + }) + + If (LLessEqual(SRID, 0x04)) { + Return (BUF0) + } Else { + Return (BUF1) + } + } + } + + /* Real Time Clock */ + Device (RTC) + { + Name(_HID, EISAID("PNP0B00")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x70, 0x70, 1, 8) + /* + * Disable as Windows doesn't like it, and systems + * don't seem to use it + */ + /* IRQNoFlags() { 8 } */ + }) + } + + /* LPC device: Resource consumption */ + Device (LDRC) + { + Name(_HID, EISAID("PNP0C02")) + Name(_UID, 2) + + Name(RBUF, ResourceTemplate() + { + IO(Decode16, 0x61, 0x61, 0x1, 0x01) /* NMI Status */ + IO(Decode16, 0x63, 0x63, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x65, 0x65, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x67, 0x67, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x80, 0x80, 0x1, 0x01) /* Port 80 Post */ + IO(Decode16, 0x92, 0x92, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0xb2, 0xb2, 0x1, 0x02) /* SWSMI */ + }) + + Method(_CRS, 0, NotSerialized) + { + Return (RBUF) + } + } +} diff --git a/arch/x86/include/asm/arch-baytrail/acpi/platform.asl b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl new file mode 100644 index 0000000..5186fe0 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/acpi/statdef.asl> +#include <asm/arch/iomap.h> +#include <asm/arch/irq.h> + +/* + * The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0. + */ +Method(_PTS, 1) +{ +} + +/* The _WAK method is called on system wakeup */ +Method(_WAK, 1) +{ + Return (Package() {0, 0}) +} + +/* ACPI global NVS */ +#include "global_nvs.asl" + +/* TODO: add CPU ASL support */ + +Scope (\_SB) +{ + #include "southcluster.asl" + + /* ACPI devices */ + #include "gpio.asl" +} + +/* Chipset specific sleep states */ +#include <asm/acpi/sleepstates.asl> diff --git a/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl new file mode 100644 index 0000000..2a1c31c --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/southcluster.asl + */ + +Device (PCI0) +{ + Name(_HID, EISAID("PNP0A08")) /* PCIe */ + Name(_CID, EISAID("PNP0A03")) /* PCI */ + + Name(_ADR, 0) + Name(_BBN, 0) + + Name(MCRS, ResourceTemplate() + { + /* Bus Numbers */ + WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100, , , PB00) + + /* IO Region 0 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8, , , PI00) + + /* PCI Config Space */ + IO(Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008) + + /* IO Region 1 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300, , , PI01) + + /* VGA memory (0xa0000-0xbffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000a0000, 0x000bffff, 0x00000000, + 0x00020000, , , ASEG) + + /* OPROM reserved (0xc0000-0xc3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c0000, 0x000c3fff, 0x00000000, + 0x00004000, , , OPR0) + + /* OPROM reserved (0xc4000-0xc7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c4000, 0x000c7fff, 0x00000000, + 0x00004000, , , OPR1) + + /* OPROM reserved (0xc8000-0xcbfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c8000, 0x000cbfff, 0x00000000, + 0x00004000, , , OPR2) + + /* OPROM reserved (0xcc000-0xcffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000cc000, 0x000cffff, 0x00000000, + 0x00004000, , , OPR3) + + /* OPROM reserved (0xd0000-0xd3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000, + 0x00004000, , , OPR4) + + /* OPROM reserved (0xd4000-0xd7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000, + 0x00004000, , , OPR5) + + /* OPROM reserved (0xd8000-0xdbfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000, + 0x00004000, , , OPR6) + + /* OPROM reserved (0xdc000-0xdffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000dc000, 0x000dffff, 0x00000000, + 0x00004000, , , OPR7) + + /* BIOS Extension (0xe0000-0xe3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000, + 0x00004000, , , ESG0) + + /* BIOS Extension (0xe4000-0xe7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000, + 0x00004000, , , ESG1) + + /* BIOS Extension (0xe8000-0xebfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000, + 0x00004000, , , ESG2) + + /* BIOS Extension (0xec000-0xeffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000ec000, 0x000effff, 0x00000000, + 0x00004000, , , ESG3) + + /* System BIOS (0xf0000-0xfffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000f0000, 0x000fffff, 0x00000000, + 0x00010000, , , FSEG) + + /* PCI Memory Region (TOLM-CONFIG_MMCONF_BASE_ADDRESS) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, , , PMEM) + + /* High PCI Memory Region */ + QwordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, , , UMEM) + }) + + Method(_CRS, 0, Serialized) + { + /* Update PCI resource area */ + CreateDwordField(MCRS, ^PMEM._MIN, PMIN) + CreateDwordField(MCRS, ^PMEM._MAX, PMAX) + CreateDwordField(MCRS, ^PMEM._LEN, PLEN) + + /* + * Hardcode TOLM to 2GB for now as BayTrail FSP uses this value. + * + * TODO: for generic usage, read TOLM value from register, or + * from global NVS (not implemented by U-Boot yet). + */ + Store(0x80000000, PMIN) + Store(Subtract(MCFG_BASE_ADDRESS, 1), PMAX) + Add(Subtract(PMAX, PMIN), 1, PLEN) + + /* Update High PCI resource area */ + CreateQwordField(MCRS, ^UMEM._MIN, UMIN) + CreateQwordField(MCRS, ^UMEM._MAX, UMAX) + CreateQwordField(MCRS, ^UMEM._LEN, ULEN) + + /* Set base address to 16GB and allocate 48GB for PCI space */ + Store(0x400000000, UMIN) + Store(0xc00000000, ULEN) + Add(UMIN, Subtract(ULEN, 1), UMAX) + + Return (MCRS) + } + + /* Device Resource Consumption */ + Device (PDRC) + { + Name(_HID, EISAID("PNP0C02")) + Name(_UID, 1) + + Name(PDRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE) + Memory32Fixed(ReadWrite, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE) + Memory32Fixed(ReadWrite, SPI_BASE_ADDRESS, SPI_BASE_SIZE) + Memory32Fixed(ReadWrite, PMC_BASE_ADDRESS, PMC_BASE_SIZE) + Memory32Fixed(ReadWrite, PUNIT_BASE_ADDRESS, PUNIT_BASE_SIZE) + Memory32Fixed(ReadWrite, ILB_BASE_ADDRESS, ILB_BASE_SIZE) + Memory32Fixed(ReadWrite, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE) + Memory32Fixed(ReadWrite, MPHY_BASE_ADDRESS, MPHY_BASE_SIZE) + }) + + /* Current Resource Settings */ + Method(_CRS, 0, Serialized) + { + Return (PDRS) + } + } + + Method(_OSC, 4) + { + /* Check for proper GUID */ + If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) { + /* Let OS control everything */ + Return (Arg3) + } Else { + /* Unrecognized UUID */ + CreateDWordField(Arg3, 0, CDW1) + Or(CDW1, 4, CDW1) + Return (Arg3) + } + } + + /* LPC Bridge 0:1f.0 */ + #include "lpc.asl" + + /* USB EHCI 0:1d.0 */ + #include "usb.asl" + + /* USB XHCI 0:14.0 */ + #include "xhci.asl" + + /* IRQ routing for each PCI device */ + #include <asm/acpi/irqroute.asl> +} diff --git a/arch/x86/include/asm/arch-baytrail/acpi/usb.asl b/arch/x86/include/asm/arch-baytrail/acpi/usb.asl new file mode 100644 index 0000000..78a7952 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/usb.asl @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/usb.asl + */ + +/* EHCI Controller 0:1d.0 */ + +Device (EHC1) +{ + Name(_ADR, 0x001d0000) + + /* Power Resources for Wake */ + Name(_PRW, Package() { 13, 4 }) + + /* Highest D state in S3 state */ + Name(_S3D, 2) + + /* Highest D state in S4 state */ + Name(_S4D, 2) + + Device (HUB7) + { + Name(_ADR, 0x00000000) + + Device(PRT1) { Name(_ADR, 1) } /* USB Port 0 */ + Device(PRT2) { Name(_ADR, 2) } /* USB Port 1 */ + Device(PRT3) { Name(_ADR, 3) } /* USB Port 2 */ + Device(PRT4) { Name(_ADR, 4) } /* USB Port 3 */ + } +} diff --git a/arch/x86/include/asm/arch-baytrail/acpi/xhci.asl b/arch/x86/include/asm/arch-baytrail/acpi/xhci.asl new file mode 100644 index 0000000..13cb429 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/acpi/xhci.asl @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/acpi/xhci.asl + */ + +/* XHCI Controller 0:14.0 */ + +Device (XHCI) +{ + Name(_ADR, 0x00140000) + + /* Power Resources for Wake */ + Name(_PRW, Package() { 13, 3 }) + + /* Highest D state in S3 state */ + Name(_S3D, 3) + + Device (RHUB) + { + Name(_ADR, 0x00000000) + + Device (PRT1) { Name(_ADR, 1) } /* USB Port 0 */ + Device (PRT2) { Name(_ADR, 2) } /* USB Port 1 */ + Device (PRT3) { Name(_ADR, 3) } /* USB Port 2 */ + Device (PRT4) { Name(_ADR, 4) } /* USB Port 3 */ + } +} diff --git a/arch/x86/include/asm/arch-baytrail/device.h b/arch/x86/include/asm/arch-baytrail/device.h new file mode 100644 index 0000000..a3872cf --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/device.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/include/soc/pci_devs.h + */ + +#ifndef _DEVICE_H_ +#define _DEVICE_H_ + +/* + * Internal PCI device numbers within the SoC. + * + * Note it must start with 0x_ prefix, as the device number macro will be + * included in the ACPI ASL files (see irq_helper.h and irq_route.h). + */ + +/* SoC transaction router */ +#define SOC_DEV 0x00 + +/* Graphics and Display */ +#define GFX_DEV 0x02 + +/* MIPI */ +#define MIPI_DEV 0x03 + +/* EMMC Port */ +#define EMMC_DEV 0x10 + +/* SDIO Port */ +#define SDIO_DEV 0x11 + +/* SD Port */ +#define SD_DEV 0x12 + +/* SATA */ +#define SATA_DEV 0x13 + +/* xHCI */ +#define XHCI_DEV 0x14 + +/* LPE Audio */ +#define LPE_DEV 0x15 + +/* OTG */ +#define OTG_DEV 0x16 + +/* MMC45 Port */ +#define MMC45_DEV 0x17 + +/* Serial IO 1 */ +#define SIO1_DEV 0x18 + +/* Trusted Execution Engine */ +#define TXE_DEV 0x1a + +/* HD Audio */ +#define HDA_DEV 0x1b + +/* PCIe Ports */ +#define PCIE_DEV 0x1c + +/* EHCI */ +#define EHCI_DEV 0x1d + +/* Serial IO 2 */ +#define SIO2_DEV 0x1e + +/* Platform Controller Unit */ +#define PCU_DEV 0x1f + +#endif /* _DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h b/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h new file mode 100644 index 0000000..cd48705 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_CONFIGS_H__ +#define __FSP_CONFIGS_H__ + +#ifndef __ASSEMBLY__ +struct fsp_config_data { + struct fsp_cfg_common common; + struct upd_region fsp_upd; +}; + +struct fspinit_rtbuf { + struct common_buf common; /* FSP common runtime data structure */ +}; +#endif + +/* FSP user configuration settings */ + +#define MRC_INIT_TSEG_SIZE_1MB 1 +#define MRC_INIT_TSEG_SIZE_2MB 2 +#define MRC_INIT_TSEG_SIZE_4MB 4 +#define MRC_INIT_TSEG_SIZE_8MB 8 + +#define MRC_INIT_MMIO_SIZE_1024MB 0x400 +#define MRC_INIT_MMIO_SIZE_1536MB 0x600 +#define MRC_INIT_MMIO_SIZE_2048MB 0x800 + +#define EMMC_BOOT_MODE_DISABLED 0 +#define EMMC_BOOT_MODE_AUTO 1 +#define EMMC_BOOT_MODE_EMMC41 2 +#define EMMC_BOOT_MODE_EMCC45 3 + +#define SATA_MODE_IDE 0 +#define SATA_MODE_AHCI 1 + +#define IGD_DVMT50_PRE_ALLOC_32MB 0x01 +#define IGD_DVMT50_PRE_ALLOC_64MB 0x02 +#define IGD_DVMT50_PRE_ALLOC_96MB 0x03 +#define IGD_DVMT50_PRE_ALLOC_128MB 0x04 +#define IGD_DVMT50_PRE_ALLOC_160MB 0x05 +#define IGD_DVMT50_PRE_ALLOC_192MB 0x06 +#define IGD_DVMT50_PRE_ALLOC_224MB 0x07 +#define IGD_DVMT50_PRE_ALLOC_256MB 0x08 +#define IGD_DVMT50_PRE_ALLOC_288MB 0x09 +#define IGD_DVMT50_PRE_ALLOC_320MB 0x0a +#define IGD_DVMT50_PRE_ALLOC_352MB 0x0b +#define IGD_DVMT50_PRE_ALLOC_384MB 0x0c +#define IGD_DVMT50_PRE_ALLOC_416MB 0x0d +#define IGD_DVMT50_PRE_ALLOC_448MB 0x0e +#define IGD_DVMT50_PRE_ALLOC_480MB 0x0f +#define IGD_DVMT50_PRE_ALLOC_512MB 0x10 + +#define APERTURE_SIZE_128MB 1 +#define APERTURE_SIZE_256MB 2 +#define APERTURE_SIZE_512MB 3 + +#define GTT_SIZE_1MB 1 +#define GTT_SIZE_2MB 2 + +#define OS_SELECTION_ANDROID 1 +#define OS_SELECTION_LINUX 4 + +#define DRAM_SPEED_800MTS 0 +#define DRAM_SPEED_1066MTS 1 +#define DRAM_SPEED_1333MTS 2 +#define DRAM_SPEED_1600MTS 3 + +#define DRAM_TYPE_DDR3 0 +#define DRAM_TYPE_DDR3L 1 +#define DRAM_TYPE_DDR3ECC 2 +#define DRAM_TYPE_LPDDR2 4 +#define DRAM_TYPE_LPDDR3 5 +#define DRAM_TYPE_DDR4 6 + +#define DIMM_WIDTH_X8 0 +#define DIMM_WIDTH_X16 1 +#define DIMM_WIDTH_X32 2 + +#define DIMM_DENSITY_1GBIT 0 +#define DIMM_DENSITY_2GBIT 1 +#define DIMM_DENSITY_4GBIT 2 +#define DIMM_DENSITY_8GBIT 3 + +#define DIMM_BUS_WIDTH_8BITS 0 +#define DIMM_BUS_WIDTH_16BITS 1 +#define DIMM_BUS_WIDTH_32BITS 2 +#define DIMM_BUS_WIDTH_64BITS 3 + +#define DIMM_SIDES_1RANKS 0 +#define DIMM_SIDES_2RANKS 1 + +#define LPE_MODE_DISABLED 0 +#define LPE_MODE_PCI 1 +#define LPE_MODE_ACPI 2 + +#define LPSS_SIO_MODE_ACPI 0 +#define LPSS_SIO_MODE_PCI 1 + +#define SCC_MODE_ACPI 0 +#define SCC_MODE_PCI 1 + +#endif /* __FSP_CONFIGS_H__ */ diff --git a/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h new file mode 100644 index 0000000..c6544ea --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015 Google, Inc + */ + +#ifndef __FSP_VPD_H +#define __FSP_VPD_H + +struct memory_down_data { + uint8_t enable_memory_down; + uint8_t dram_speed; + uint8_t dram_type; + uint8_t dimm_0_enable; + uint8_t dimm_1_enable; + uint8_t dimm_width; + uint8_t dimm_density; + uint8_t dimm_bus_width; + uint8_t dimm_sides; /* Ranks Per dimm_ */ + uint8_t dimm_tcl; /* tCL */ + /* tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc. */ + uint8_t dimm_trpt_rcd; + uint8_t dimm_twr; /* tWR in DRAM clk */ + uint8_t dimm_twtr; /* tWTR in DRAM clk */ + uint8_t dimm_trrd; /* tRRD in DRAM clk */ + uint8_t dimm_trtp; /* tRTP in DRAM clk */ + uint8_t dimm_tfaw; /* tFAW in DRAM clk */ +}; + +struct __packed upd_region { + uint64_t signature; /* Offset 0x0000 */ + uint8_t reserved0[24]; /* Offset 0x0008 */ + uint16_t mrc_init_tseg_size; /* Offset 0x0020 */ + uint16_t mrc_init_mmio_size; /* Offset 0x0022 */ + uint8_t mrc_init_spd_addr1; /* Offset 0x0024 */ + uint8_t mrc_init_spd_addr2; /* Offset 0x0025 */ + uint8_t emmc_boot_mode; /* Offset 0x0026 */ + uint8_t enable_sdio; /* Offset 0x0027 */ + uint8_t enable_sdcard; /* Offset 0x0028 */ + uint8_t enable_hsuart0; /* Offset 0x0029 */ + uint8_t enable_hsuart1; /* Offset 0x002a */ + uint8_t enable_spi; /* Offset 0x002b */ + uint8_t reserved1; /* Offset 0x002c */ + uint8_t enable_sata; /* Offset 0x002d */ + uint8_t sata_mode; /* Offset 0x002e */ + uint8_t enable_azalia; /* Offset 0x002f */ + struct azalia_config *azalia_cfg_ptr; /* Offset 0x0030 */ + uint8_t enable_xhci; /* Offset 0x0034 */ + uint8_t lpe_mode; /* Offset 0x0035 */ + uint8_t lpss_sio_mode; /* Offset 0x0036 */ + uint8_t enable_dma0; /* Offset 0x0037 */ + uint8_t enable_dma1; /* Offset 0x0038 */ + uint8_t enable_i2_c0; /* Offset 0x0039 */ + uint8_t enable_i2_c1; /* Offset 0x003a */ + uint8_t enable_i2_c2; /* Offset 0x003b */ + uint8_t enable_i2_c3; /* Offset 0x003c */ + uint8_t enable_i2_c4; /* Offset 0x003d */ + uint8_t enable_i2_c5; /* Offset 0x003e */ + uint8_t enable_i2_c6; /* Offset 0x003f */ + uint8_t enable_pwm0; /* Offset 0x0040 */ + uint8_t enable_pwm1; /* Offset 0x0041 */ + uint8_t enable_hsi; /* Offset 0x0042 */ + uint8_t igd_dvmt50_pre_alloc; /* Offset 0x0043 */ + uint8_t aperture_size; /* Offset 0x0044 */ + uint8_t gtt_size; /* Offset 0x0045 */ + uint8_t reserved2[5]; /* Offset 0x0046 */ + uint8_t mrc_debug_msg; /* Offset 0x004b */ + uint8_t isp_enable; /* Offset 0x004c */ + uint8_t scc_mode; /* Offset 0x004d */ + uint8_t igd_render_standby; /* Offset 0x004e */ + uint8_t txe_uma_enable; /* Offset 0x004f */ + uint8_t os_selection; /* Offset 0x0050 */ + uint8_t emmc45_ddr50_enabled; /* Offset 0x0051 */ + uint8_t emmc45_hs200_enabled; /* Offset 0x0052 */ + uint8_t emmc45_retune_timer_value; /* Offset 0x0053 */ + uint8_t enable_igd; /* Offset 0x0054 */ + uint8_t unused_upd_space1[155]; /* Offset 0x0055 */ + struct memory_down_data memory_params; /* Offset 0x00f0 */ + uint16_t terminator; /* Offset 0x0100 */ +}; + +#define VPD_IMAGE_ID 0x3157454956594C56 /* 'VLYVIEW1' */ + +struct __packed vpd_region { + uint64_t sign; /* Offset 0x0000 */ + uint32_t img_rev; /* Offset 0x0008 */ + uint32_t upd_offset; /* Offset 0x000c */ + uint8_t unused[16]; /* Offset 0x0010 */ + uint32_t fsp_res_memlen; /* Offset 0x0020 */ + uint8_t platform_type; /* Offset 0x0024 */ + uint8_t enable_secure_boot; /* Offset 0x0025 */ +}; +#endif diff --git a/arch/x86/include/asm/arch-baytrail/global_nvs.h b/arch/x86/include/asm/arch-baytrail/global_nvs.h new file mode 100644 index 0000000..1072e3d --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/global_nvs.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _GLOBAL_NVS_H_ +#define _GLOBAL_NVS_H_ + +struct __packed acpi_global_nvs { + u8 pcnt; /* processor count */ + u8 iuart_en; /* internal UART enabled */ + + /* + * Add padding so sizeof(struct acpi_global_nvs) == 0x100. + * This must match the size defined in the global_nvs.asl. + */ + u8 rsvd[254]; +}; + +#endif /* _GLOBAL_NVS_H_ */ diff --git a/arch/x86/include/asm/arch-baytrail/iomap.h b/arch/x86/include/asm/arch-baytrail/iomap.h new file mode 100644 index 0000000..752dae0 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/iomap.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/include/soc/iomap.h + */ + +#ifndef _BAYTRAIL_IOMAP_H_ +#define _BAYTRAIL_IOMAP_H_ + +/* Memory Mapped IO bases */ + +/* PCI Configuration Space */ +#define MCFG_BASE_ADDRESS CONFIG_PCIE_ECAM_BASE +#define MCFG_BASE_SIZE 0x10000000 + +/* Temporary Base Address */ +#define TEMP_BASE_ADDRESS 0xfd000000 + +/* Transactions in this range will abort */ +#define ABORT_BASE_ADDRESS 0xfeb00000 +#define ABORT_BASE_SIZE 0x00100000 + +/* High Performance Event Timer */ +#define HPET_BASE_ADDRESS 0xfed00000 +#define HPET_BASE_SIZE 0x400 + +/* SPI Bus */ +#define SPI_BASE_ADDRESS 0xfed01000 +#define SPI_BASE_SIZE 0x400 + +/* Power Management Controller */ +#define PMC_BASE_ADDRESS 0xfed03000 +#define PMC_BASE_SIZE 0x400 + +#define GEN_PMCON1 0x20 +#define UART_EN (1 << 24) +#define DISB (1 << 23) +#define MEM_SR (1 << 21) +#define SRS (1 << 20) +#define CTS (1 << 19) +#define MS4V (1 << 18) +#define PWR_FLR (1 << 16) +#define PME_B0_S5_DIS (1 << 15) +#define SUS_PWR_FLR (1 << 14) +#define WOL_EN_OVRD (1 << 13) +#define DIS_SLP_X_STRCH_SUS_UP (1 << 12) +#define GEN_RST_STS (1 << 9) +#define RPS (1 << 2) +#define AFTERG3_EN (1 << 0) +#define GEN_PMCON2 0x24 +#define SLPSX_STR_POL_LOCK (1 << 18) +#define BIOS_PCI_EXP_EN (1 << 10) +#define PWRBTN_LVL (1 << 9) +#define SMI_LOCK (1 << 4) + +/* Power Management Unit */ +#define PUNIT_BASE_ADDRESS 0xfed05000 +#define PUNIT_BASE_SIZE 0x800 + +/* Intel Legacy Block */ +#define ILB_BASE_ADDRESS 0xfed08000 +#define ILB_BASE_SIZE 0x400 + +/* IO Memory */ +#define IO_BASE_ADDRESS 0xfed0c000 +#define IO_BASE_OFFSET_GPSCORE 0x0000 +#define IO_BASE_OFFSET_GPNCORE 0x1000 +#define IO_BASE_OFFSET_GPSSUS 0x2000 +#define IO_BASE_SIZE 0x4000 + +/* Root Complex Base Address */ +#define RCBA_BASE_ADDRESS 0xfed1c000 +#define RCBA_BASE_SIZE 0x400 + +/* MODPHY */ +#define MPHY_BASE_ADDRESS 0xfef00000 +#define MPHY_BASE_SIZE 0x100000 + +/* IO Port bases */ +#define ACPI_BASE_ADDRESS 0x0400 +#define ACPI_BASE_SIZE 0x80 + +#define PM1_STS 0x00 +#define PM1_CNT 0x04 + +#define GPIO_BASE_ADDRESS 0x0500 +#define GPIO_BASE_SIZE 0x100 + +#define SMBUS_BASE_ADDRESS 0xefa0 + +#endif /* _BAYTRAIL_IOMAP_H_ */ diff --git a/arch/x86/include/asm/arch-baytrail/irq.h b/arch/x86/include/asm/arch-baytrail/irq.h new file mode 100644 index 0000000..fda3f59 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/irq.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + * + * Modified from coreboot src/soc/intel/baytrail/include/soc/irq.h + */ + +#ifndef _BAYTRAIL_IRQ_H_ +#define _BAYTRAIL_IRQ_H_ + +#define PIRQA_APIC_IRQ 16 +#define PIRQB_APIC_IRQ 17 +#define PIRQC_APIC_IRQ 18 +#define PIRQD_APIC_IRQ 19 +#define PIRQE_APIC_IRQ 20 +#define PIRQF_APIC_IRQ 21 +#define PIRQG_APIC_IRQ 22 +#define PIRQH_APIC_IRQ 23 + +/* The below IRQs are for when devices are in ACPI mode */ +#define LPE_DMA0_IRQ 24 +#define LPE_DMA1_IRQ 25 +#define LPE_SSP0_IRQ 26 +#define LPE_SSP1_IRQ 27 +#define LPE_SSP2_IRQ 28 +#define LPE_IPC2HOST_IRQ 29 +#define LPSS_I2C1_IRQ 32 +#define LPSS_I2C2_IRQ 33 +#define LPSS_I2C3_IRQ 34 +#define LPSS_I2C4_IRQ 35 +#define LPSS_I2C5_IRQ 36 +#define LPSS_I2C6_IRQ 37 +#define LPSS_I2C7_IRQ 38 +#define LPSS_HSUART1_IRQ 39 +#define LPSS_HSUART2_IRQ 40 +#define LPSS_SPI_IRQ 41 +#define LPSS_DMA1_IRQ 42 +#define LPSS_DMA2_IRQ 43 +#define SCC_EMMC_IRQ 44 +#define SCC_SDIO_IRQ 46 +#define SCC_SD_IRQ 47 +#define GPIO_NC_IRQ 48 +#define GPIO_SC_IRQ 49 +#define GPIO_SUS_IRQ 50 +/* GPIO direct / dedicated IRQs */ +#define GPIO_S0_DED_IRQ_0 51 +#define GPIO_S0_DED_IRQ_1 52 +#define GPIO_S0_DED_IRQ_2 53 +#define GPIO_S0_DED_IRQ_3 54 +#define GPIO_S0_DED_IRQ_4 55 +#define GPIO_S0_DED_IRQ_5 56 +#define GPIO_S0_DED_IRQ_6 57 +#define GPIO_S0_DED_IRQ_7 58 +#define GPIO_S0_DED_IRQ_8 59 +#define GPIO_S0_DED_IRQ_9 60 +#define GPIO_S0_DED_IRQ_10 61 +#define GPIO_S0_DED_IRQ_11 62 +#define GPIO_S0_DED_IRQ_12 63 +#define GPIO_S0_DED_IRQ_13 64 +#define GPIO_S0_DED_IRQ_14 65 +#define GPIO_S0_DED_IRQ_15 66 +#define GPIO_S5_DED_IRQ_0 67 +#define GPIO_S5_DED_IRQ_1 68 +#define GPIO_S5_DED_IRQ_2 69 +#define GPIO_S5_DED_IRQ_3 70 +#define GPIO_S5_DED_IRQ_4 71 +#define GPIO_S5_DED_IRQ_5 72 +#define GPIO_S5_DED_IRQ_6 73 +#define GPIO_S5_DED_IRQ_7 74 +#define GPIO_S5_DED_IRQ_8 75 +#define GPIO_S5_DED_IRQ_9 76 +#define GPIO_S5_DED_IRQ_10 77 +#define GPIO_S5_DED_IRQ_11 78 +#define GPIO_S5_DED_IRQ_12 79 +#define GPIO_S5_DED_IRQ_13 80 +#define GPIO_S5_DED_IRQ_14 81 +#define GPIO_S5_DED_IRQ_15 82 +/* DIRQs - Two levels of expansion to evaluate to numeric constants for ASL */ +#define _GPIO_S0_DED_IRQ(slot) GPIO_S0_DED_IRQ_##slot +#define _GPIO_S5_DED_IRQ(slot) GPIO_S5_DED_IRQ_##slot +#define GPIO_S0_DED_IRQ(slot) _GPIO_S0_DED_IRQ(slot) +#define GPIO_S5_DED_IRQ(slot) _GPIO_S5_DED_IRQ(slot) + +#endif /* _BAYTRAIL_IRQ_H_ */ diff --git a/arch/x86/include/asm/arch-braswell/fsp/fsp_configs.h b/arch/x86/include/asm/arch-braswell/fsp/fsp_configs.h new file mode 100644 index 0000000..4425dcb --- /dev/null +++ b/arch/x86/include/asm/arch-braswell/fsp/fsp_configs.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_CONFIGS_H__ +#define __FSP_CONFIGS_H__ + +#ifndef __ASSEMBLY__ +struct fsp_config_data { + struct fsp_cfg_common common; + struct upd_region fsp_upd; +}; + +struct fspinit_rtbuf { + struct common_buf common; /* FSP common runtime data structure */ +}; +#endif + +/* FSP user configuration settings */ + +#define MRC_INIT_TSEG_SIZE_1MB 1 +#define MRC_INIT_TSEG_SIZE_2MB 2 +#define MRC_INIT_TSEG_SIZE_4MB 4 +#define MRC_INIT_TSEG_SIZE_8MB 8 + +#define MRC_INIT_MMIO_SIZE_1024MB 0x400 +#define MRC_INIT_MMIO_SIZE_1536MB 0x600 +#define MRC_INIT_MMIO_SIZE_2048MB 0x800 + +#define IGD_DVMT50_PRE_ALLOC_32MB 0x01 +#define IGD_DVMT50_PRE_ALLOC_64MB 0x02 +#define IGD_DVMT50_PRE_ALLOC_96MB 0x03 +#define IGD_DVMT50_PRE_ALLOC_128MB 0x04 +#define IGD_DVMT50_PRE_ALLOC_160MB 0x05 +#define IGD_DVMT50_PRE_ALLOC_192MB 0x06 +#define IGD_DVMT50_PRE_ALLOC_224MB 0x07 +#define IGD_DVMT50_PRE_ALLOC_256MB 0x08 +#define IGD_DVMT50_PRE_ALLOC_288MB 0x09 +#define IGD_DVMT50_PRE_ALLOC_320MB 0x0a +#define IGD_DVMT50_PRE_ALLOC_352MB 0x0b +#define IGD_DVMT50_PRE_ALLOC_384MB 0x0c +#define IGD_DVMT50_PRE_ALLOC_416MB 0x0d +#define IGD_DVMT50_PRE_ALLOC_448MB 0x0e +#define IGD_DVMT50_PRE_ALLOC_480MB 0x0f +#define IGD_DVMT50_PRE_ALLOC_512MB 0x10 + +#define APERTURE_SIZE_128MB 1 +#define APERTURE_SIZE_256MB 2 +#define APERTURE_SIZE_512MB 3 + +#define GTT_SIZE_1MB 1 +#define GTT_SIZE_2MB 2 + +#define DRAM_TYPE_DDR3 0 +#define DRAM_TYPE_LPDDR3 1 + +#define SDCARD_MODE_DISABLED 0 +#define SDCARD_MODE_PCI 1 +#define SDCARD_MODE_ACPI 2 + +#define LPE_MODE_DISABLED 0 +#define LPE_MODE_PCI 1 +#define LPE_MODE_ACPI 2 + +#define CHV_SVID_CONFIG_0 0 +#define CHV_SVID_CONFIG_1 1 +#define CHV_SVID_CONFIG_2 2 +#define CHV_SVID_CONFIG_3 3 + +#define EMMC_MODE_DISABLED 0 +#define EMMC_MODE_PCI 1 +#define EMMC_MODE_ACPI 2 + +#define SATA_SPEED_GEN1 1 +#define SATA_SPEED_GEN2 2 +#define SATA_SPEED_GEN3 3 + +#define ISP_PCI_DEV_CONFIG_1 1 +#define ISP_PCI_DEV_CONFIG_2 2 +#define ISP_PCI_DEV_CONFIG_3 3 + +#define PNP_SETTING_DISABLED 0 +#define PNP_SETTING_POWER 1 +#define PNP_SETTING_PERF 2 +#define PNP_SETTING_POWER_AND_PERF 3 + +#endif /* __FSP_CONFIGS_H__ */ diff --git a/arch/x86/include/asm/arch-braswell/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-braswell/fsp/fsp_vpd.h new file mode 100644 index 0000000..a3bde3d --- /dev/null +++ b/arch/x86/include/asm/arch-braswell/fsp/fsp_vpd.h @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2015, Intel Corporation + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_VPD_H__ +#define __FSP_VPD_H__ + +struct __packed memory_upd { + u64 signature; /* Offset 0x0020 */ + u8 revision; /* Offset 0x0028 */ + u8 unused2[7]; /* Offset 0x0029 */ + u16 mrc_init_tseg_size; /* Offset 0x0030 */ + u16 mrc_init_mmio_size; /* Offset 0x0032 */ + u8 mrc_init_spd_addr1; /* Offset 0x0034 */ + u8 mrc_init_spd_addr2; /* Offset 0x0035 */ + u8 mem_ch0_config; /* Offset 0x0036 */ + u8 mem_ch1_config; /* Offset 0x0037 */ + u32 memory_spd_ptr; /* Offset 0x0038 */ + u8 igd_dvmt50_pre_alloc; /* Offset 0x003c */ + u8 aperture_size; /* Offset 0x003d */ + u8 gtt_size; /* Offset 0x003e */ + u8 legacy_seg_decode; /* Offset 0x003f */ + u8 enable_dvfs; /* Offset 0x0040 */ + u8 memory_type; /* Offset 0x0041 */ + u8 enable_ca_mirror; /* Offset 0x0042 */ + u8 reserved[189]; /* Offset 0x0043 */ +}; + +struct gpio_family { + u32 confg; + u32 confg_changes; + u32 misc; + u32 mmio_addr; + wchar_t *name; +}; + +struct gpio_pad { + u32 confg0; + u32 confg0_changes; + u32 confg1; + u32 confg1_changes; + u32 community; + u32 mmio_addr; + wchar_t *name; + u32 misc; +}; + +struct __packed silicon_upd { + u64 signature; /* Offset 0x0100 */ + u8 revision; /* Offset 0x0108 */ + u8 unused3[7]; /* Offset 0x0109 */ + u8 sdcard_mode; /* Offset 0x0110 */ + u8 enable_hsuart0; /* Offset 0x0111 */ + u8 enable_hsuart1; /* Offset 0x0112 */ + u8 enable_azalia; /* Offset 0x0113 */ + struct azalia_config *azalia_cfg_ptr; /* Offset 0x0114 */ + u8 enable_sata; /* Offset 0x0118 */ + u8 enable_xhci; /* Offset 0x0119 */ + u8 lpe_mode; /* Offset 0x011a */ + u8 enable_dma0; /* Offset 0x011b */ + u8 enable_dma1; /* Offset 0x011c */ + u8 enable_i2c0; /* Offset 0x011d */ + u8 enable_i2c1; /* Offset 0x011e */ + u8 enable_i2c2; /* Offset 0x011f */ + u8 enable_i2c3; /* Offset 0x0120 */ + u8 enable_i2c4; /* Offset 0x0121 */ + u8 enable_i2c5; /* Offset 0x0122 */ + u8 enable_i2c6; /* Offset 0x0123 */ + u32 graphics_config_ptr; /* Offset 0x0124 */ + struct gpio_family *gpio_familiy_ptr; /* Offset 0x0128 */ + struct gpio_pad *gpio_pad_ptr; /* Offset 0x012c */ + u8 disable_punit_pwr_config; /* Offset 0x0130 */ + u8 chv_svid_config; /* Offset 0x0131 */ + u8 disable_dptf; /* Offset 0x0132 */ + u8 emmc_mode; /* Offset 0x0133 */ + u8 usb3_clk_ssc; /* Offset 0x0134 */ + u8 disp_clk_ssc; /* Offset 0x0135 */ + u8 sata_clk_ssc; /* Offset 0x0136 */ + u8 usb2_port0_pe_txi_set; /* Offset 0x0137 */ + u8 usb2_port0_txi_set; /* Offset 0x0138 */ + u8 usb2_port0_tx_emphasis_en; /* Offset 0x0139 */ + u8 usb2_port0_tx_pe_half; /* Offset 0x013a */ + u8 usb2_port1_pe_txi_set; /* Offset 0x013b */ + u8 usb2_port1_txi_set; /* Offset 0x013c */ + u8 usb2_port1_tx_emphasis_en; /* Offset 0x013d */ + u8 usb2_port1_tx_pe_half; /* Offset 0x013e */ + u8 usb2_port2_pe_txi_set; /* Offset 0x013f */ + u8 usb2_port2_txi_set; /* Offset 0x0140 */ + u8 usb2_port2_tx_emphasis_en; /* Offset 0x0141 */ + u8 usb2_port2_tx_pe_half; /* Offset 0x0142 */ + u8 usb2_port3_pe_txi_set; /* Offset 0x0143 */ + u8 usb2_port3_txi_set; /* Offset 0x0144 */ + u8 usb2_port3_tx_emphasis_en; /* Offset 0x0145 */ + u8 usb2_port3_tx_pe_half; /* Offset 0x0146 */ + u8 usb2_port4_pe_txi_set; /* Offset 0x0147 */ + u8 usb2_port4_txi_set; /* Offset 0x0148 */ + u8 usb2_port4_tx_emphasis_en; /* Offset 0x0149 */ + u8 usb2_port4_tx_pe_half; /* Offset 0x014a */ + u8 usb3_lane0_ow2tap_gen2_deemph3p5; /* Offset 0x014b */ + u8 usb3_lane1_ow2tap_gen2_deemph3p5; /* Offset 0x014c */ + u8 usb3_lane2_ow2tap_gen2_deemph3p5; /* Offset 0x014d */ + u8 usb3_lane3_ow2tap_gen2_deemph3p5; /* Offset 0x014e */ + u8 sata_speed; /* Offset 0x014f */ + u8 usb_ssic_port; /* Offset 0x0150 */ + u8 usb_hsic_port; /* Offset 0x0151 */ + u8 pcie_rootport_speed; /* Offset 0x0152 */ + u8 enable_ssic; /* Offset 0x0153 */ + u32 logo_ptr; /* Offset 0x0154 */ + u32 logo_size; /* Offset 0x0158 */ + u8 rtc_lock; /* Offset 0x015c */ + u8 pmic_i2c_bus; /* Offset 0x015d */ + u8 enable_isp; /* Offset 0x015e */ + u8 isp_pci_dev_config; /* Offset 0x015f */ + u8 turbo_mode; /* Offset 0x0160 */ + u8 pnp_settings; /* Offset 0x0161 */ + u8 sd_detect_chk; /* Offset 0x0162 */ + u8 reserved[411]; /* Offset 0x0163 */ +}; + +#define MEMORY_UPD_ID 0x244450554d454d24 /* '$MEMUPD$' */ +#define SILICON_UPD_ID 0x244450555f495324 /* '$SI_UPD$' */ + +struct __packed upd_region { + u64 signature; /* Offset 0x0000 */ + u8 revision; /* Offset 0x0008 */ + u8 unused0[7]; /* Offset 0x0009 */ + u32 memory_upd_offset; /* Offset 0x0010 */ + u32 silicon_upd_offset; /* Offset 0x0014 */ + u64 unused1; /* Offset 0x0018 */ + struct memory_upd memory_upd; /* Offset 0x0020 */ + struct silicon_upd silicon_upd; /* Offset 0x0100 */ + u16 terminator; /* Offset 0x02fe */ +}; + +#define VPD_IMAGE_ID 0x2450534657534224 /* '$BSWFSP$' */ + +struct __packed vpd_region { + u64 sign; /* Offset 0x0000 */ + u32 img_rev; /* Offset 0x0008 */ + u32 upd_offset; /* Offset 0x000c */ +}; + +#endif /* __FSP_VPD_H__ */ diff --git a/arch/x86/include/asm/arch-braswell/gpio.h b/arch/x86/include/asm/arch-braswell/gpio.h new file mode 100644 index 0000000..e8389e5 --- /dev/null +++ b/arch/x86/include/asm/arch-braswell/gpio.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + * + * From coreboot src/soc/intel/braswell/include/soc/gpio.h + */ + +#ifndef _BRASWELL_GPIO_H_ +#define _BRASWELL_GPIO_H_ + +#include <asm/arch/iomap.h> + +enum mode_list { + M0, + M1, + M2, + M3, + M4, + M5, + M6, + M7, + M8, + M9, + M10, + M11, + M12, + M13, +}; + +enum int_select { + L0, + L1, + L2, + L3, + L4, + L5, + L6, + L7, + L8, + L9, + L10, + L11, + L12, + L13, + L14, + L15, +}; + +enum gpio_en { + NATIVE = 0xff, + GPIO = 0, /* Native, no need to set PAD_VALUE */ + GPO = 1, /* GPO, output only in PAD_VALUE */ + GPI = 2, /* GPI, input only in PAD_VALUE */ + HI_Z = 3, + NA_GPO = 0, +}; + +enum gpio_state { + LOW, + HIGH, +}; + +enum en_dis { + DISABLE, /* Disable */ + ENABLE, /* Enable */ +}; + +enum int_type { + INT_DIS, + TRIG_EDGE_LOW, + TRIG_EDGE_HIGH, + TRIG_EDGE_BOTH, + TRIG_LEVEL, +}; + +enum mask { + MASKABLE, + NON_MASKABLE, +}; + +enum glitch_cfg { + GLITCH_DISABLE, + EN_EDGE_DETECT, + EN_RX_DATA, + EN_EDGE_RX_DATA, +}; + +enum inv_rx_tx { + NO_INVERSION = 0, + INV_RX_ENABLE = 1, + INV_TX_ENABLE = 2, + INV_RX_TX_ENABLE = 3, + INV_RX_DATA = 4, + INV_TX_DATA = 8, +}; + +enum voltage { + VOLT_3_3, /* Working on 3.3 Volts */ + VOLT_1_8, /* Working on 1.8 Volts */ +}; + +enum hs_mode { + DISABLE_HS, /* Disable high speed mode */ + ENABLE_HS, /* Enable high speed mode */ +}; + +enum odt_up_dn { + PULL_UP, /* On Die Termination Up */ + PULL_DOWN, /* On Die Termination Down */ +}; + +enum odt_en { + DISABLE_OD, /* On Die Termination Disable */ + ENABLE_OD, /* On Die Termination Enable */ +}; + +enum pull_type { + P_NONE = 0, /* Pull None */ + P_20K_L = 1, /* Pull Down 20K */ + P_5K_L = 2, /* Pull Down 5K */ + P_1K_L = 4, /* Pull Down 1K */ + P_20K_H = 9, /* Pull Up 20K */ + P_5K_H = 10, /* Pull Up 5K */ + P_1K_H = 12 /* Pull Up 1K */ +}; + +enum bit { + ONE_BIT = 1, + TWO_BIT = 3, + THREE_BIT = 7, + FOUR_BIT = 15, + FIVE_BIT = 31, + SIX_BIT = 63, + SEVEN_BIT = 127, + EIGHT_BIT = 255 +}; + +enum gpe_config { + GPE, + SMI, + SCI, +}; + +enum community { + SOUTHWEST = 0x0000, + NORTH = 0x8000, + EAST = 0x10000, + SOUTHEAST = 0x18000, + VIRTUAL = 0x20000, +}; + +#define NA 0xff +#define TERMINATOR 0xffffffff + +#define GPIO_FAMILY_CONF(family_name, park_mode, hysctl, vp18_mode, hs_mode, \ + odt_up_dn, odt_en, curr_src_str, rcomp, family_no, community_offset) { \ + .confg = ((((park_mode) != NA) ? park_mode << 26 : 0) | \ + (((hysctl) != NA) ? hysctl << 24 : 0) | \ + (((vp18_mode) != NA) ? vp18_mode << 21 : 0) | \ + (((hs_mode) != NA) ? hs_mode << 19 : 0) | \ + (((odt_up_dn) != NA) ? odt_up_dn << 18 : 0) | \ + (((odt_en) != NA) ? odt_en << 17 : 0) | \ + (curr_src_str)), \ + .confg_changes = ((((park_mode) != NA) ? ONE_BIT << 26 : 0) | \ + (((hysctl) != NA) ? TWO_BIT << 24 : 0) | \ + (((vp18_mode) != NA) ? ONE_BIT << 21 : 0) | \ + (((hs_mode) != NA) ? ONE_BIT << 19 : 0) | \ + (((odt_up_dn) != NA) ? ONE_BIT << 18 : 0) | \ + (((odt_en) != NA) ? ONE_BIT << 17 : 0) | \ + (THREE_BIT)), \ + .misc = ((rcomp == ENABLE) ? 1 : 0) , \ + .mmio_addr = (community_offset == TERMINATOR) ? TERMINATOR : \ + ((family_no != NA) ? (IO_BASE_ADDRESS + community_offset +\ + (0x80 * family_no) + 0x1080) : 0) , \ + .name = 0 \ +} + +#define GPIO_PAD_CONF(pad_name, mode_select, mode, gpio_config, gpio_state, \ + gpio_light_mode, int_type, int_sel, term, open_drain, current_source,\ + int_mask, glitch, inv_rx_tx, wake_mask, wake_mask_bit, gpe, \ + mmio_offset, community_offset) { \ + .confg0 = ((((int_sel) != NA) ? (int_sel << 28) : 0) | \ + (((glitch) != NA) ? (glitch << 26) : 0) | \ + (((term) != NA) ? (term << 20) : 0) | \ + (((mode_select) == GPIO) ? ((mode << 16) | (1 << 15)) : \ + ((mode << 16))) | \ + (((gpio_config) != NA) ? (gpio_config << 8) : 0) | \ + (((gpio_light_mode) != NA) ? (gpio_light_mode << 7) : 0) | \ + (((gpio_state) == HIGH) ? 2 : 0)), \ + .confg0_changes = ((((int_sel) != NA) ? (FOUR_BIT << 28) : 0) | \ + (((glitch) != NA) ? (TWO_BIT << 26) : 0) | \ + (((term) != NA) ? (FOUR_BIT << 20) : 0) | \ + (FIVE_BIT << 15) | \ + (((gpio_config) != NA) ? (THREE_BIT << 8) : 0) | \ + (((gpio_light_mode) != NA) ? (ONE_BIT << 7) : 0) | \ + (((gpio_state) != NA) ? ONE_BIT << 1 : 0)), \ + .confg1 = ((((current_source) != NA) ? (current_source << 27) : 0) | \ + (((inv_rx_tx) != NA) ? inv_rx_tx << 4 : 0) | \ + (((open_drain) != NA) ? open_drain << 3 : 0) | \ + (((int_type) != NA) ? int_type : 0)), \ + .confg1_changes = ((((current_source) != NA) ? (ONE_BIT << 27) : 0) | \ + (((inv_rx_tx) != NA) ? FOUR_BIT << 4 : 0) | \ + (((open_drain) != NA) ? ONE_BIT << 3 : 0) | \ + (((int_type) != NA) ? THREE_BIT : 0)), \ + .community = community_offset, \ + .mmio_addr = (community_offset == TERMINATOR) ? TERMINATOR : \ + ((mmio_offset != NA) ? (IO_BASE_ADDRESS + \ + community_offset + mmio_offset) : 0), \ + .name = 0, \ + .misc = ((((gpe) != NA) ? (gpe << 0) : 0) | \ + (((wake_mask) != NA) ? (wake_mask << 2) : 0) | \ + (((int_mask) != NA) ? (int_mask << 3) : 0)) | \ + (((wake_mask_bit) != NA) ? (wake_mask_bit << 4) : (NA << 4)) \ +} + +#endif /* _BRASWELL_GPIO_H_ */ diff --git a/arch/x86/include/asm/arch-braswell/iomap.h b/arch/x86/include/asm/arch-braswell/iomap.h new file mode 100644 index 0000000..873d331 --- /dev/null +++ b/arch/x86/include/asm/arch-braswell/iomap.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _BRASWELL_IOMAP_H_ +#define _BRASWELL_IOMAP_H_ + +/* Memory Mapped IO bases */ + +/* Power Management Controller */ +#define PMC_BASE_ADDRESS 0xfed03000 +#define PMC_BASE_SIZE 0x400 + +/* Power Management Unit */ +#define PUNIT_BASE_ADDRESS 0xfed05000 +#define PUNIT_BASE_SIZE 0x800 + +/* Intel Legacy Block */ +#define ILB_BASE_ADDRESS 0xfed08000 +#define ILB_BASE_SIZE 0x400 + +/* SPI Bus */ +#define SPI_BASE_ADDRESS 0xfed01000 +#define SPI_BASE_SIZE 0x400 + +/* Root Complex Base Address */ +#define RCBA_BASE_ADDRESS 0xfed1c000 +#define RCBA_BASE_SIZE 0x400 + +/* IO Memory */ +#define IO_BASE_ADDRESS 0xfed80000 +#define IO_BASE_SIZE 0x4000 + +/* MODPHY */ +#define MPHY_BASE_ADDRESS 0xfef00000 +#define MPHY_BASE_SIZE 0x100000 + +/* IO Port bases */ + +#define ACPI_BASE_ADDRESS 0x400 +#define ACPI_BASE_SIZE 0x80 + +#define GPIO_BASE_ADDRESS 0x500 +#define GPIO_BASE_SIZE 0x100 + +#define SMBUS_BASE_ADDRESS 0xefa0 + +#endif /* _BRASWELL_IOMAP_H_ */ diff --git a/arch/x86/include/asm/arch-broadwell/adsp.h b/arch/x86/include/asm/arch-broadwell/adsp.h new file mode 100644 index 0000000..eb825ce --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/adsp.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for Intel Application Digital Signal Processor + * + * Copyright 2019 Google LLC + * + * Modified from coreboot file of the same name + */ + +#ifndef __ASM_ARCH_BROADWELL_ADSP_H +#define __ASM_ARCH_BROADWELL_ADSP_H + +#define ADSP_PCI_IRQ 23 +#define ADSP_ACPI_IRQ 3 +#define ADSP_ACPI_IRQEN BIT(3) + +#define ADSP_SHIM_BASE_LPT 0xe7000 +#define ADSP_SHIM_BASE_WPT 0xfb000 +#define ADSP_SHIM_LTRC 0xe0 +#define ADSP_SHIM_LTRC_VALUE 0x3003 +#define ADSP_SHIM_IMC 0x28 +#define ADSP_SHIM_IPCD 0x40 + +#define ADSP_PCI_VDRTCTL0 0xa0 +#define ADSP_VDRTCTL0_D3PGD_LPT BIT(1) +#define ADSP_VDRTCTL0_D3PGD_WPT BIT(0) +#define ADSP_VDRTCTL0_D3SRAMPGD_LPT BIT(2) +#define ADSP_VDRTCTL0_D3SRAMPGD_WPT BIT(1) +#define ADSP_PCI_VDRTCTL1 0xa4 +#define ADSP_PCI_VDRTCTL2 0xa8 +#define ADSP_VDRTCTL2_VALUE 0x00000fff + +#define ADSP_IOBP_VDLDAT1 0xd7000624 +#define ADSP_VDLDAT1_VALUE 0x00040100 +#define ADSP_IOBP_VDLDAT2 0xd7000628 +#define ADSP_IOBP_ACPI_IRQ3 0xd9d8 +#define ADSP_IOBP_ACPI_IRQ3I 0xd8d9 +#define ADSP_IOBP_ACPI_IRQ4 0xdbda +#define ADSP_IOBP_PMCTL 0xd70001e0 +#define ADSP_PMCTL_VALUE 0x3f +#define ADSP_IOBP_PCICFGCTL 0xd7000500 +#define ADSP_PCICFGCTL_PCICD BIT(0) +#define ADSP_PCICFGCTL_ACPIIE BIT(1) +#define ADSP_PCICFGCTL_SPCBAD BIT(7) + +#endif /* __ASM_ARCH_BROADWELL_ADSP_H */ diff --git a/arch/x86/include/asm/arch-broadwell/cpu.h b/arch/x86/include/asm/arch-broadwell/cpu.h new file mode 100644 index 0000000..3bc3bd6 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/cpu.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __asm_arch_cpu_h +#define __asm_arch_cpu_h + +/* CPU types */ +#define HASWELL_FAMILY_ULT 0x40650 +#define BROADWELL_FAMILY_ULT 0x306d0 + +/* Supported CPUIDs */ +#define CPUID_HASWELL_A0 0x306c1 +#define CPUID_HASWELL_B0 0x306c2 +#define CPUID_HASWELL_C0 0x306c3 +#define CPUID_HASWELL_ULT_B0 0x40650 +#define CPUID_HASWELL_ULT 0x40651 +#define CPUID_HASWELL_HALO 0x40661 +#define CPUID_BROADWELL_C0 0x306d2 +#define CPUID_BROADWELL_D0 0x306d3 +#define CPUID_BROADWELL_E0 0x306d4 + +#define BROADWELL_FAMILY_ULT 0x306d0 + +#define CORE_THREAD_COUNT_MSR 0x35 + +#define MSR_VR_CURRENT_CONFIG 0x601 +#define MSR_VR_MISC_CONFIG 0x603 +#define MSR_PKG_POWER_SKU 0x614 +#define MSR_DDR_RAPL_LIMIT 0x618 +#define MSR_VR_MISC_CONFIG2 0x636 + +/* Latency times in units of 1024ns. */ +#define C_STATE_LATENCY_CONTROL_0_LIMIT 0x42 +#define C_STATE_LATENCY_CONTROL_1_LIMIT 0x73 +#define C_STATE_LATENCY_CONTROL_2_LIMIT 0x91 +#define C_STATE_LATENCY_CONTROL_3_LIMIT 0xe4 +#define C_STATE_LATENCY_CONTROL_4_LIMIT 0x145 +#define C_STATE_LATENCY_CONTROL_5_LIMIT 0x1ef + +void cpu_set_power_limits(int power_limit_1_time); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/gpio.h b/arch/x86/include/asm/arch-broadwell/gpio.h new file mode 100644 index 0000000..a32e2db --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/gpio.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + * + * From Coreboot src/soc/intel/broadwell/include/soc/gpio.h + */ + +#ifndef __ASM_ARCH_GPIO +#define __ASM_ARCH_GPIO + +#define GPIO_PER_BANK 32 +#define GPIO_BANKS 3 + +struct broadwell_bank_platdata { + uint16_t base_addr; + const char *bank_name; + int bank; +}; + +/* PCH-LP GPIOBASE Registers */ +struct pch_lp_gpio_regs { + u32 own[GPIO_BANKS]; + u32 reserved0; + + u16 pirq_to_ioxapic; + u16 reserved1[3]; + u32 blink; + u32 ser_blink; + + u32 ser_blink_cmdsts; + u32 ser_blink_data; + u16 gpi_nmi_en; + u16 gpi_nmi_sts; + u32 reserved2; + + u32 gpi_route[GPIO_BANKS]; + u32 reserved3; + + u32 reserved4[4]; + + u32 alt_gpi_smi_sts; + u32 alt_gpi_smi_en; + u32 reserved5[2]; + + u32 rst_sel[GPIO_BANKS]; + u32 reserved6; + + u32 reserved9[3]; + u32 gpio_gc; + + u32 gpi_is[GPIO_BANKS]; + u32 reserved10; + + u32 gpi_ie[GPIO_BANKS]; + u32 reserved11; + + u32 reserved12[24]; + + struct { + u32 conf_a; + u32 conf_b; + } config[GPIO_BANKS * GPIO_PER_BANK]; +}; +check_member(pch_lp_gpio_regs, gpi_ie[0], 0x90); +check_member(pch_lp_gpio_regs, config[0], 0x100); + +enum { + CONFA_MODE_SHIFT = 0, + CONFA_MODE_GPIO = 1 << CONFA_MODE_SHIFT, + + CONFA_DIR_SHIFT = 2, + CONFA_DIR_INPUT = 1 << CONFA_DIR_SHIFT, + + CONFA_INVERT_SHIFT = 3, + CONFA_INVERT = 1 << CONFA_INVERT_SHIFT, + + CONFA_TRIGGER_SHIFT = 4, + CONFA_TRIGGER_LEVEL = 1 << CONFA_TRIGGER_SHIFT, + + CONFA_LEVEL_SHIFT = 30, + CONFA_LEVEL_HIGH = 1UL << CONFA_LEVEL_SHIFT, + + CONFA_OUTPUT_SHIFT = 31, + CONFA_OUTPUT_HIGH = 1UL << CONFA_OUTPUT_SHIFT, + + CONFB_SENSE_SHIFT = 2, + CONFB_SENSE_DISABLE = 1 << CONFB_SENSE_SHIFT, +}; + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/iomap.h b/arch/x86/include/asm/arch-broadwell/iomap.h new file mode 100644 index 0000000..de7f6e5 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/iomap.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * From Coreboot soc/intel/broadwell/include/soc/iomap.h + * + * Copyright (C) 2016 Google Inc. + */ + +#ifndef __asm_arch_iomap_h +#define __asm_arch_iomap_h + +#define MCFG_BASE_ADDRESS 0xf0000000 +#define MCFG_BASE_SIZE 0x4000000 + +#define HPET_BASE_ADDRESS 0xfed00000 + +#define MCH_BASE_ADDRESS 0xfed10000 +#define MCH_BASE_SIZE 0x8000 + +#define DMI_BASE_ADDRESS 0xfed18000 +#define DMI_BASE_SIZE 0x1000 + +#define EP_BASE_ADDRESS 0xfed19000 +#define EP_BASE_SIZE 0x1000 + +#define EDRAM_BASE_ADDRESS 0xfed80000 +#define EDRAM_BASE_SIZE 0x4000 + +#define GDXC_BASE_ADDRESS 0xfed84000 +#define GDXC_BASE_SIZE 0x1000 + +#define RCBA_BASE_ADDRESS 0xfed1c000 +#define RCBA_BASE_SIZE 0x4000 + +#define HPET_BASE_ADDRESS 0xfed00000 + +#define ACPI_BASE_ADDRESS 0x1000 +#define ACPI_BASE_SIZE 0x100 + +#define GPIO_BASE_ADDRESS 0x1400 +#define GPIO_BASE_SIZE 0x400 + +#define SMBUS_BASE_ADDRESS 0x0400 +#define SMBUS_BASE_SIZE 0x10 + +/* Temporary addresses used before relocation */ +#define EARLY_GTT_BAR 0xe0000000 +#define EARLY_XHCI_BAR 0xd7000000 +#define EARLY_EHCI_BAR 0xd8000000 +#define EARLY_UART_BAR 0x3f8 +#define EARLY_TEMP_MMIO 0xfed08000 + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/lpc.h b/arch/x86/include/asm/arch-broadwell/lpc.h new file mode 100644 index 0000000..98f928a --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/lpc.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot soc/intel/broadwell/include/soc/lpc.h + * + * Copyright (C) 2016 Google Inc. + */ + +#ifndef _ASM_ARCH_LPC_H +#define _ASM_ARCH_LPC_H + +#define GEN_PMCON_1 0xa0 +#define SMI_LOCK (1 << 4) +#define GEN_PMCON_2 0xa2 +#define SYSTEM_RESET_STS (1 << 4) +#define THERMTRIP_STS (1 << 3) +#define SYSPWR_FLR (1 << 1) +#define PWROK_FLR (1 << 0) +#define GEN_PMCON_3 0xa4 +#define SUS_PWR_FLR (1 << 14) +#define GEN_RST_STS (1 << 9) +#define RTC_BATTERY_DEAD (1 << 2) +#define PWR_FLR (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define GEN_PMCON_LOCK 0xa6 +#define SLP_STR_POL_LOCK (1 << 2) +#define ACPI_BASE_LOCK (1 << 1) +#define PMIR 0xac +#define PMIR_CF9LOCK (1 << 31) +#define PMIR_CF9GR (1 << 20) + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/me.h b/arch/x86/include/asm/arch-broadwell/me.h new file mode 100644 index 0000000..58f16ba --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/me.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot soc/intel/broadwell/include/soc/me.h + * + * Copyright (C) 2014 Google Inc. + */ + +#ifndef _asm_arch_me_h +#define _asm_arch_me_h + +#include <asm/me_common.h> + +#define ME_INIT_STATUS_SUCCESS_OTHER 3 /* SEE ME9 BWG */ + +#define ME_HSIO_MESSAGE (7 << 28) +#define ME_HSIO_CMD_GETHSIOVER 1 +#define ME_HSIO_CMD_CLOSE 0 + +/* + * Apparently the GMES register is renamed to HFS2 (or HFSTS2 according + * to ME9 BWG). Sadly the PCH EDS and the ME BWG do not match on nomenclature. + */ +#define PCI_ME_HFS2 0x48 +/* Infrastructure Progress Values */ +#define ME_HFS2_PHASE_ROM 0 +#define ME_HFS2_PHASE_BUP 1 +#define ME_HFS2_PHASE_UKERNEL 2 +#define ME_HFS2_PHASE_POLICY 3 +#define ME_HFS2_PHASE_MODULE_LOAD 4 +#define ME_HFS2_PHASE_UNKNOWN 5 +#define ME_HFS2_PHASE_HOST_COMM 6 +/* Current State - Based on Infra Progress values. */ +/* ROM State */ +#define ME_HFS2_STATE_ROM_BEGIN 0 +#define ME_HFS2_STATE_ROM_DISABLE 6 +/* BUP State */ +#define ME_HFS2_STATE_BUP_INIT 0 +#define ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1 +#define ME_HFS2_STATE_BUP_FLOW_DET 4 +#define ME_HFS2_STATE_BUP_VSCC_ERR 8 +#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa +#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb +#define ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd +#define ME_HFS2_STATE_BUP_M3 0x11 +#define ME_HFS2_STATE_BUP_M0 0x12 +#define ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13 +#define ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15 +#define ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17 +#define ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18 +#define ME_HFS2_STATE_BUP_T32_MISSING 0x1c +#define ME_HFS2_STATE_BUP_WAIT_DID 0x1f +#define ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20 +#define ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21 +#define ME_HFS2_STATE_BUP_ENABLE_UMA 0x22 +#define ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25 +#define ME_HFS2_STATE_BUP_M0_CLK 0x26 +#define ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27 +#define ME_HFS2_STATE_BUP_TEMP_DIS 0x28 +#define ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32 +/* Policy Module State */ +#define ME_HFS2_STATE_POLICY_ENTRY 0 +#define ME_HFS2_STATE_POLICY_RCVD_S3 3 +#define ME_HFS2_STATE_POLICY_RCVD_S4 4 +#define ME_HFS2_STATE_POLICY_RCVD_S5 5 +#define ME_HFS2_STATE_POLICY_RCVD_UPD 6 +#define ME_HFS2_STATE_POLICY_RCVD_PCR 7 +#define ME_HFS2_STATE_POLICY_RCVD_NPCR 8 +#define ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9 +#define ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa +#define ME_HFS2_STATE_POLICY_RCVD_DID 0xb +#define ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc +#define ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd +#define ME_HFS2_STATE_POLICY_FPB_ERR 0xe +#define ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf +#define ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10 +/* Current PM Event Values */ +#define ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0 +#define ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3 +#define ME_HFS2_PMEVENT_CLEAN_ME_RESET 4 +#define ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5 +#define ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6 +#define ME_HFS2_PMEVENT_S0MO_SXM3 7 +#define ME_HFS2_PMEVENT_SXM3_S0M0 8 +#define ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9 +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb +#define ME_HFS2_PMEVENT_SXMX_SXMOFF 0xc + +struct me_hfs2 { + u32 bist_in_progress:1; + u32 reserved1:2; + u32 invoke_mebx:1; + u32 cpu_replaced_sts:1; + u32 mbp_rdy:1; + u32 mfs_failure:1; + u32 warm_reset_request:1; + u32 cpu_replaced_valid:1; + u32 reserved2:4; + u32 mbp_cleared:1; + u32 reserved3:2; + u32 current_state:8; + u32 current_pmevent:4; + u32 progress_code:4; +} __packed; + +#define PCI_ME_HFS5 0x68 + +#define PCI_ME_H_GS2 0x70 +#define PCI_ME_MBP_GIVE_UP 0x01 + +/* ICC Messages */ +#define ICC_SET_CLOCK_ENABLES 0x3 +#define ICC_API_VERSION_LYNXPOINT 0x00030000 + +struct icc_header { + u32 api_version; + u32 icc_command; + u32 icc_status; + u32 length; + u32 reserved; +} __packed; + +struct icc_clock_enables_msg { + u32 clock_enables; + u32 clock_mask; + u32 no_response:1; + u32 reserved:31; +} __packed; + +/* + * ME to BIOS Payload Datastructures and definitions. The ordering of the + * structures follows the ordering in the ME9 BWG. + */ + +#define MBP_APPID_KERNEL 1 +#define MBP_APPID_INTEL_AT 3 +#define MBP_APPID_HWA 4 +#define MBP_APPID_ICC 5 +#define MBP_APPID_NFC 6 +/* Kernel items: */ +#define MBP_KERNEL_FW_VER_ITEM 1 +#define MBP_KERNEL_FW_CAP_ITEM 2 +#define MBP_KERNEL_ROM_BIST_ITEM 3 +#define MBP_KERNEL_PLAT_KEY_ITEM 4 +#define MBP_KERNEL_FW_TYPE_ITEM 5 +#define MBP_KERNEL_MFS_FAILURE_ITEM 6 +#define MBP_KERNEL_PLAT_TIME_ITEM 7 +/* Intel AT items: */ +#define MBP_INTEL_AT_STATE_ITEM 1 +/* ICC Items: */ +#define MBP_ICC_PROFILE_ITEM 1 +/* HWA Items: */ +#define MBP_HWA_REQUEST_ITEM 1 +/* NFC Items: */ +#define MBP_NFC_SUPPORT_DATA_ITEM 1 + +#define MBP_MAKE_IDENT(appid, item) ((appid << 8) | item) +#define MBP_IDENT(appid, item) \ + MBP_MAKE_IDENT(MBP_APPID_##appid, MBP_##appid##_##item##_ITEM) + +struct mbp_fw_version_name { + u32 major_version:16; + u32 minor_version:16; + u32 hotfix_version:16; + u32 build_version:16; +} __packed; + +struct icc_address_mask { + u16 icc_start_address; + u16 mask; +} __packed; + +struct mbp_icc_profile { + u8 num_icc_profiles; + u8 icc_profile_soft_strap; + u8 icc_profile_index; + u8 reserved; + u32 icc_reg_bundles; + struct icc_address_mask icc_address_mask[0]; +} __packed; + +struct me_bios_payload { + struct mbp_fw_version_name *fw_version_name; + struct mbp_mefwcaps *fw_capabilities; + struct mbp_rom_bist_data *rom_bist_data; + struct mbp_platform_key *platform_key; + struct mbp_plat_type *fw_plat_type; + struct mbp_icc_profile *icc_profile; + struct mbp_at_state *at_state; + u32 *mfsintegrity; + struct mbp_plat_time *plat_time; + struct mbp_nfc_data *nfc_data; +}; + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pch.h b/arch/x86/include/asm/arch-broadwell/pch.h new file mode 100644 index 0000000..ecdf6d1 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pch.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ASM_ARCH_PCH_H +#define __ASM_ARCH_PCH_H + +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 +#define ACPI_EN (1 << 7) + +#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ +#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ +#define GPIO_EN (1 << 4) + +#define PCIEXBAR 0x60 + +#define PCH_DEV_LPC PCI_BDF(0, 0x1f, 0) + +/* RCB registers */ +#define OIC 0x31fe /* 16bit */ +#define HPTC 0x3404 /* 32bit */ +#define FD 0x3418 /* 32bit */ + +/* Function Disable 1 RCBA 0x3418 */ +#define PCH_DISABLE_ALWAYS (1 << 0) + +/* PM registers */ +#define TCO1_CNT 0x60 +#define TCO_TMR_HLT (1 << 11) + + +/* Device 0:0.0 PCI configuration space */ + +#define EPBAR 0x40 +#define MCHBAR 0x48 +#define PCIEXBAR 0x60 +#define DMIBAR 0x68 +#define GGC 0x50 /* GMCH Graphics Control */ +#define DEVEN 0x54 /* Device Enable */ +#define DEVEN_D7EN (1 << 14) +#define DEVEN_D4EN (1 << 7) +#define DEVEN_D3EN (1 << 5) +#define DEVEN_D2EN (1 << 4) +#define DEVEN_D1F0EN (1 << 3) +#define DEVEN_D1F1EN (1 << 2) +#define DEVEN_D1F2EN (1 << 1) +#define DEVEN_D0EN (1 << 0) +#define DPR 0x5c +#define DPR_EPM (1 << 2) +#define DPR_PRS (1 << 1) +#define DPR_SIZE_MASK 0xff0 + +#define MCHBAR_PEI_VERSION 0x5034 +#define BIOS_RESET_CPL 0x5da8 +#define EDRAMBAR 0x5408 +#define MCH_PAIR 0x5418 +#define GDXCBAR 0x5420 + +#define PAM0 0x80 +#define PAM1 0x81 +#define PAM2 0x82 +#define PAM3 0x83 +#define PAM4 0x84 +#define PAM5 0x85 +#define PAM6 0x86 + +/* PCODE MMIO communications live in the MCHBAR. */ +#define BIOS_MAILBOX_INTERFACE 0x5da4 +#define MAILBOX_RUN_BUSY (1 << 31) +#define MAILBOX_BIOS_CMD_READ_PCS 1 +#define MAILBOX_BIOS_CMD_WRITE_PCS 2 +#define MAILBOX_BIOS_CMD_READ_CALIBRATION 0x509 +#define MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL 0x909 +#define MAILBOX_BIOS_CMD_READ_PCH_POWER 0xa +#define MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT 0xb +#define MAILBOX_BIOS_CMD_READ_C9C10_VOLTAGE 0x26 +#define MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE 0x27 +/* Errors are returned back in bits 7:0. */ +#define MAILBOX_BIOS_ERROR_NONE 0 +#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1 +#define MAILBOX_BIOS_ERROR_TIMEOUT 2 +#define MAILBOX_BIOS_ERROR_ILLEGAL_DATA 3 +#define MAILBOX_BIOS_ERROR_RESERVED 4 +#define MAILBOX_BIOS_ERROR_ILLEGAL_VR_ID 5 +#define MAILBOX_BIOS_ERROR_VR_INTERFACE_LOCKED 6 +#define MAILBOX_BIOS_ERROR_VR_ERROR 7 +/* Data is passed through bits 31:0 of the data register. */ +#define BIOS_MAILBOX_DATA 0x5da0 + +/* SATA IOBP Registers */ +#define SATA_IOBP_SP0_SECRT88 0xea002688 +#define SATA_IOBP_SP1_SECRT88 0xea002488 + +#define SATA_SECRT88_VADJ_MASK 0xff +#define SATA_SECRT88_VADJ_SHIFT 16 + +#define SATA_IOBP_SP0DTLE_DATA 0xea002550 +#define SATA_IOBP_SP0DTLE_EDGE 0xea002554 +#define SATA_IOBP_SP1DTLE_DATA 0xea002750 +#define SATA_IOBP_SP1DTLE_EDGE 0xea002754 + +#define SATA_DTLE_MASK 0xF +#define SATA_DTLE_DATA_SHIFT 24 +#define SATA_DTLE_EDGE_SHIFT 16 + +/* Power Management */ +#define PCH_PCS 0x84 +#define PCH_PCS_PS_D3HOT 3 + +#define GEN_PMCON_1 0xa0 +#define SMI_LOCK (1 << 4) +#define GEN_PMCON_2 0xa2 +#define SYSTEM_RESET_STS (1 << 4) +#define THERMTRIP_STS (1 << 3) +#define SYSPWR_FLR (1 << 1) +#define PWROK_FLR (1 << 0) +#define GEN_PMCON_3 0xa4 +#define SUS_PWR_FLR (1 << 14) +#define GEN_RST_STS (1 << 9) +#define RTC_BATTERY_DEAD (1 << 2) +#define PWR_FLR (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define GEN_PMCON_LOCK 0xa6 +#define SLP_STR_POL_LOCK (1 << 2) +#define ACPI_BASE_LOCK (1 << 1) +#define PMIR 0xac +#define PMIR_CF9LOCK (1 << 31) +#define PMIR_CF9GR (1 << 20) + +/* Broadwell PCH (Wildcat Point) */ +#define PCH_WPT_HSW_U_SAMPLE 0x9cc1 +#define PCH_WPT_BDW_U_SAMPLE 0x9cc2 +#define PCH_WPT_BDW_U_PREMIUM 0x9cc3 +#define PCH_WPT_BDW_U_BASE 0x9cc5 +#define PCH_WPT_BDW_Y_SAMPLE 0x9cc6 +#define PCH_WPT_BDW_Y_PREMIUM 0x9cc7 +#define PCH_WPT_BDW_Y_BASE 0x9cc9 +#define PCH_WPT_BDW_H 0x9ccb + +#define SA_IGD_OPROM_VENDEV 0x80860406 + +/* Dynamically determine if the part is ULT */ +bool cpu_is_ult(void); + +u32 pch_iobp_read(u32 address); +int pch_iobp_write(u32 address, u32 data); +int pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); +int pch_iobp_exec(u32 addr, u16 op_dcode, u8 route_id, u32 *data, u8 *resp); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pei_data.h b/arch/x86/include/asm/arch-broadwell/pei_data.h new file mode 100644 index 0000000..4442bea --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pei_data.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * From Coreboot soc/intel/broadwell/include/soc/pei_data.h + * + * Copyright (C) 2014 Google Inc. + */ + +#ifndef ASM_ARCH_PEI_DATA_H +#define ASM_ARCH_PEI_DATA_H + +#include <linux/linkage.h> + +#define PEI_VERSION 22 + +typedef void asmlinkage (*tx_byte_func)(unsigned char byte); + +enum board_type { + BOARD_TYPE_CRB_MOBILE = 0, /* CRB Mobile */ + BOARD_TYPE_CRB_DESKTOP, /* CRB Desktop */ + BOARD_TYPE_USER1, /* SV mobile */ + BOARD_TYPE_USER2, /* SV desktop */ + BOARD_TYPE_USER3, /* SV server */ + BOARD_TYPE_ULT, /* ULT */ + BOARD_TYPE_CRB_EMBDEDDED, /* CRB Embedded */ + BOARD_TYPE_UNKNOWN, +}; + +#define MAX_USB2_PORTS 14 +#define MAX_USB3_PORTS 6 +#define USB_OC_PIN_SKIP 8 + +enum usb2_port_location { + USB_PORT_BACK_PANEL = 0, + USB_PORT_FRONT_PANEL, + USB_PORT_DOCK, + USB_PORT_MINI_PCIE, + USB_PORT_FLEX, + USB_PORT_INTERNAL, + USB_PORT_SKIP, + USB_PORT_NGFF_DEVICE_DOWN, +}; + +struct usb2_port_setting { + /* + * Usb Port Length: + * [16:4] = length in inches in octal format + * [3:0] = decimal point + */ + uint16_t length; + uint8_t enable; + uint8_t oc_pin; + uint8_t location; +} __packed; + +struct usb3_port_setting { + uint8_t enable; + uint8_t oc_pin; + /* + * Set to 0 if trace length is > 5 inches + * Set to 1 if trace length is <= 5 inches + */ + uint8_t fixed_eq; +} __packed; + + +struct pei_data { + uint32_t pei_version; + + enum board_type board_type; + int boot_mode; + int ec_present; + int usbdebug; + + /* Base addresses */ + uint32_t pciexbar; + uint16_t smbusbar; + uint32_t xhcibar; + uint32_t ehcibar; + uint32_t gttbar; + uint32_t rcba; + uint32_t pmbase; + uint32_t gpiobase; + uint32_t temp_mmio_base; + uint32_t tseg_size; + + /* + * 0 = leave channel enabled + * 1 = disable dimm 0 on channel + * 2 = disable dimm 1 on channel + * 3 = disable dimm 0+1 on channel + */ + int dimm_channel0_disabled; + int dimm_channel1_disabled; + /* Set to 0 for memory down */ + uint8_t spd_addresses[4]; + /* Enable 2x Refresh Mode */ + int ddr_refresh_2x; + /* DQ pins are interleaved on board */ + int dq_pins_interleaved; + /* Limit DDR3 frequency */ + int max_ddr3_freq; + /* Disable self refresh */ + int disable_self_refresh; + /* Disable cmd power/CKEPD */ + int disable_cmd_pwr; + + /* USB port configuration */ + struct usb2_port_setting usb2_ports[MAX_USB2_PORTS]; + struct usb3_port_setting usb3_ports[MAX_USB3_PORTS]; + + /* + * USB3 board specific PHY tuning + */ + + /* Valid range: 0x69 - 0x80 */ + uint8_t usb3_txout_volt_dn_amp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x80 - 0x9c */ + uint8_t usb3_txout_imp_sc_volt_amp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x39 - 0x80 */ + uint8_t usb3_txout_de_emp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x3d - 0x4a */ + uint8_t usb3_txout_imp_adj_volt_amp[MAX_USB3_PORTS]; + + /* Console output function */ + tx_byte_func tx_byte; + + /* + * DIMM SPD data for memory down configurations + * [CHANNEL][SLOT][SPD] + */ + uint8_t spd_data[2][2][512]; + + /* + * LPDDR3 DQ byte map + * [CHANNEL][ITERATION][2] + * + * Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side) + * DQByteMap[0] - ClkDQByteMap: + * - If clock is per rank, program to [0xFF, 0xFF] + * - If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF] + * - If clock is shared by 2 ranks but does not go to all bytes, + * Entry[i] defines which DQ bytes Group i services + * DQByteMap[1] - CmdNDQByteMap: [0] is CmdN/CAA and [1] is CmdN/CAB + * DQByteMap[2] - CmdSDQByteMap: [0] is CmdS/CAA and [1] is CmdS/CAB + * DQByteMap[3] - CkeDQByteMap : [0] is CKE /CAA and [1] is CKE /CAB + * For DDR, DQByteMap[3:1] = [0xFF, 0] + * DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] + * since we have 1 CTL / rank + * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] + * since we have 1 CA Vref + */ + uint8_t dq_map[2][6][2]; + + /* + * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins + * [CHANNEL][MAX_BYTES] + */ + uint8_t dqs_map[2][8]; + + /* Data read from flash and passed into MRC */ + const void *saved_data; + int saved_data_size; + + /* Disable use of saved data (can be set by mainboard) */ + int disable_saved_data; + + /* Data from MRC that should be saved to flash */ + void *data_to_save; + int data_to_save_size; + struct pei_memory_info meminfo; +} __packed; + +void mainboard_fill_pei_data(struct pei_data *pei_data); +void broadwell_fill_pei_data(struct pei_data *pei_data); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pm.h b/arch/x86/include/asm/arch-broadwell/pm.h new file mode 100644 index 0000000..df35080 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pm.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot src/soc/intel/broadwell/include/soc/pm.h + * + * Copyright (C) 2016 Google, Inc. + */ + +#ifndef __ASM_ARCH_PM_H +#define __ASM_ARCH_PM_H + +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PCIEXPWAK_STS (1 << 14) +#define PRBTNOR_STS (1 << 11) +#define RTC_STS (1 << 10) +#define PWRBTN_STS (1 << 8) +#define GBL_STS (1 << 5) +#define BM_STS (1 << 4) +#define TMROF_STS (1 << 0) +#define PM1_EN 0x02 +#define PCIEXPWAK_DIS (1 << 14) +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) +#define PM1_CNT 0x04 +#define SLP_EN (1 << 13) +#define SLP_TYP (7 << 10) +#define SLP_TYP_SHIFT 10 +#define SLP_TYP_S0 0 +#define SLP_TYP_S1 1 +#define SLP_TYP_S3 5 +#define SLP_TYP_S4 6 +#define SLP_TYP_S5 7 +#define GBL_RLS (1 << 2) +#define BM_RLD (1 << 1) +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define XHCI_SMI_EN (1 << 31) +#define ME_SMI_EN (1 << 30) +#define GPIO_UNLOCK_SMI_EN (1 << 27) +#define INTEL_USB2_EN (1 << 18) +#define LEGACY_USB2_EN (1 << 17) +#define PERIODIC_EN (1 << 14) +#define TCO_EN (1 << 13) +#define MCSMI_EN (1 << 11) +#define BIOS_RLS (1 << 7) +#define SWSMI_TMR_EN (1 << 6) +#define APMC_EN (1 << 5) +#define SLP_SMI_EN (1 << 4) +#define LEGACY_USB_EN (1 << 3) +#define BIOS_EN (1 << 2) +#define EOS (1 << 1) +#define GBL_SMI_EN (1 << 0) +#define SMI_STS 0x34 +#define UPWRC 0x3c +#define UPWRC_WS (1 << 8) +#define UPWRC_WE (1 << 1) +#define UPWRC_SMI (1 << 0) +#define GPE_CNTL 0x42 +#define SWGPE_CTRL (1 << 1) +#define DEVACT_STS 0x44 +#define PM2_CNT 0x50 +#define TCO1_CNT 0x60 +#define TCO_TMR_HLT (1 << 11) +#define TCO1_STS 0x64 +#define DMISCI_STS (1 << 9) +#define TCO2_STS 0x66 +#define TCO2_STS_SECOND_TO (1 << 1) + +#define GPE0_REG_MAX 4 +#define GPE0_REG_SIZE 32 +#define GPE0_STS(x) (0x80 + (x * 4)) +#define GPE_31_0 0 /* 0x80/0x90 = GPE[31:0] */ +#define GPE_63_32 1 /* 0x84/0x94 = GPE[63:32] */ +#define GPE_94_64 2 /* 0x88/0x98 = GPE[94:64] */ +#define GPE_STD 3 /* 0x8c/0x9c = Standard GPE */ +#define WADT_STS (1 << 18) +#define GP27_STS (1 << 16) +#define PME_B0_STS (1 << 13) +#define ME_SCI_STS (1 << 12) +#define PME_STS (1 << 11) +#define BATLOW_STS (1 << 10) +#define PCI_EXP_STS (1 << 9) +#define SMB_WAK_STS (1 << 7) +#define TCOSCI_STS (1 << 6) +#define SWGPE_STS (1 << 2) +#define HOT_PLUG_STS (1 << 1) +#define GPE0_EN(x) (0x90 + (x * 4)) +#define WADT_en (1 << 18) +#define GP27_EN (1 << 16) +#define PME_B0_EN (1 << 13) +#define ME_SCI_EN (1 << 12) +#define PME_EN (1 << 11) +#define BATLOW_EN (1 << 10) +#define PCI_EXP_EN (1 << 9) +#define TCOSCI_EN (1 << 6) +#define SWGPE_EN (1 << 2) +#define HOT_PLUG_EN (1 << 1) + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 +#define MAINBOARD_POWER_KEEP 2 + +#define SLEEP_STATE_S0 0 +#define SLEEP_STATE_S3 3 +#define SLEEP_STATE_S5 5 + +struct chipset_power_state { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t pm1_cnt; + uint16_t tco1_sts; + uint16_t tco2_sts; + uint32_t gpe0_sts[4]; + uint32_t gpe0_en[4]; + uint16_t gen_pmcon1; + uint16_t gen_pmcon2; + uint16_t gen_pmcon3; + int prev_sleep_state; + uint16_t hsio_version; + uint16_t hsio_checksum; +}; + +void power_state_get(struct udevice *pch_dev, struct chipset_power_state *ps); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/rcb.h b/arch/x86/include/asm/arch-broadwell/rcb.h new file mode 100644 index 0000000..b7ce874 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/rcb.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __asm_arch_rcba_h +#define __asm_arch_rcba_h + +#define ACPIIRQEN 0x31e0 /* 32bit */ + +#define PMSYNC_CONFIG 0x33c4 /* 32bit */ +#define PMSYNC_CONFIG2 0x33cc /* 32bit */ + +#define DEEP_S3_POL 0x3328 /* 32bit */ +#define DEEP_S3_EN_AC (1 << 0) +#define DEEP_S3_EN_DC (1 << 1) +#define DEEP_S5_POL 0x3330 /* 32bit */ +#define DEEP_S5_EN_AC (1 << 14) +#define DEEP_S5_EN_DC (1 << 15) +#define DEEP_SX_CONFIG 0x3334 /* 32bit */ +#define DEEP_SX_WAKE_PIN_EN (1 << 2) +#define DEEP_SX_ACPRESENT_PD (1 << 1) +#define DEEP_SX_GP27_PIN_EN (1 << 0) +#define PMSYNC_CONFIG 0x33c4 /* 32bit */ +#define PMSYNC_CONFIG2 0x33cc /* 32bit */ + +#define RC 0x3400 /* 32bit */ +#define HPTC 0x3404 /* 32bit */ +#define GCS 0x3410 /* 32bit */ +#define BUC 0x3414 /* 32bit */ +#define PCH_DISABLE_GBE (1 << 5) +#define FD 0x3418 /* 32bit */ +#define FDSW 0x3420 /* 8bit */ +#define DISPBDF 0x3424 /* 16bit */ +#define FD2 0x3428 /* 32bit */ +#define CG 0x341c /* 32bit */ + +/* Function Disable 1 RCBA 0x3418 */ +#define PCH_DISABLE_ALWAYS (1 << 0) +#define PCH_DISABLE_ADSPD (1 << 1) +#define PCH_DISABLE_SATA1 (1 << 2) +#define PCH_DISABLE_SMBUS (1 << 3) +#define PCH_DISABLE_HD_AUDIO (1 << 4) +#define PCH_DISABLE_EHCI2 (1 << 13) +#define PCH_DISABLE_LPC (1 << 14) +#define PCH_DISABLE_EHCI1 (1 << 15) +#define PCH_DISABLE_PCIE(x) (1 << (16 + x)) +#define PCH_DISABLE_THERMAL (1 << 24) +#define PCH_DISABLE_SATA2 (1 << 25) +#define PCH_DISABLE_XHCI (1 << 27) + +/* Function Disable 2 RCBA 0x3428 */ +#define PCH_DISABLE_KT (1 << 4) +#define PCH_DISABLE_IDER (1 << 3) +#define PCH_DISABLE_MEI2 (1 << 2) +#define PCH_DISABLE_MEI1 (1 << 1) +#define PCH_ENABLE_DBDF (1 << 0) + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/serialio.h b/arch/x86/include/asm/arch-broadwell/serialio.h new file mode 100644 index 0000000..5e98eaf --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/serialio.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Serial IO defintiions (taken from coreboot file of same name) + * + * Copyright 2019 Google LLC + */ + +#ifndef __ARCH_BROADWELL_SERIALIO_H_ +#define __ARCH_BROADWELL_SERIALIO_H_ + +/* Serial IO IOBP Registers */ +#define SIO_IOBP_PORTCTRL0 0xcb000000 /* SDIO D23:F0 */ +#define SIO_IOBP_PORTCTRL0_ACPI_IRQ_EN BIT(5) +#define SIO_IOBP_PORTCTRL0_PCI_CONF_DIS BIT(4) +#define SIO_IOBP_PORTCTRL1 0xcb000014 /* SDIO D23:F0 */ +#define SIO_IOBP_PORTCTRL1_SNOOP_SELECT(x) (((x) & 3) << 13) +#define SIO_IOBP_GPIODF 0xcb000154 +#define SIO_IOBP_GPIODF_SDIO_IDLE_DET_EN BIT(4) +#define SIO_IOBP_GPIODF_DMA_IDLE_DET_EN BIT(3) +#define SIO_IOBP_GPIODF_UART_IDLE_DET_EN BIT(2) +#define SIO_IOBP_GPIODF_I2C_IDLE_DET_EN BIT(1) +#define SIO_IOBP_GPIODF_SPI_IDLE_DET_EN BIT(0) +#define SIO_IOBP_GPIODF_UART0_BYTE_ACCESS BIT(10) +#define SIO_IOBP_GPIODF_UART1_BYTE_ACCESS BIT(11) +#define SIO_IOBP_PORTCTRL2 0xcb000240 /* DMA D21:F0 */ +#define SIO_IOBP_PORTCTRL3 0xcb000248 /* I2C0 D21:F1 */ +#define SIO_IOBP_PORTCTRL4 0xcb000250 /* I2C1 D21:F2 */ +#define SIO_IOBP_PORTCTRL5 0xcb000258 /* SPI0 D21:F3 */ +#define SIO_IOBP_PORTCTRL6 0xcb000260 /* SPI1 D21:F4 */ +#define SIO_IOBP_PORTCTRL7 0xcb000268 /* UART0 D21:F5 */ +#define SIO_IOBP_PORTCTRL8 0xcb000270 /* UART1 D21:F6 */ +#define SIO_IOBP_PORTCTRLX(x) (0xcb000240 + ((x) * 8)) +/* PORTCTRL 2-8 have the same layout */ +#define SIO_IOBP_PORTCTRL_ACPI_IRQ_EN BIT(21) +#define SIO_IOBP_PORTCTRL_PCI_CONF_DIS BIT(20) +#define SIO_IOBP_PORTCTRL_SNOOP_SELECT(x) (((x) & 3) << 18) +#define SIO_IOBP_PORTCTRL_INT_PIN(x) (((x) & 0xf) << 2) +#define SIO_IOBP_PORTCTRL_PM_CAP_PRSNT BIT(1) +#define SIO_IOBP_FUNCDIS0 0xce00aa07 /* DMA D21:F0 */ +#define SIO_IOBP_FUNCDIS1 0xce00aa47 /* I2C0 D21:F1 */ +#define SIO_IOBP_FUNCDIS2 0xce00aa87 /* I2C1 D21:F2 */ +#define SIO_IOBP_FUNCDIS3 0xce00aac7 /* SPI0 D21:F3 */ +#define SIO_IOBP_FUNCDIS4 0xce00ab07 /* SPI1 D21:F4 */ +#define SIO_IOBP_FUNCDIS5 0xce00ab47 /* UART0 D21:F5 */ +#define SIO_IOBP_FUNCDIS6 0xce00ab87 /* UART1 D21:F6 */ +#define SIO_IOBP_FUNCDIS7 0xce00ae07 /* SDIO D23:F0 */ +#define SIO_IOBP_FUNCDIS_DIS BIT(8) + +/* Serial IO Devices */ +#define SIO_ID_SDMA 0 /* D21:F0 */ +#define SIO_ID_I2C0 1 /* D21:F1 */ +#define SIO_ID_I2C1 2 /* D21:F2 */ +#define SIO_ID_SPI0 3 /* D21:F3 */ +#define SIO_ID_SPI1 4 /* D21:F4 */ +#define SIO_ID_UART0 5 /* D21:F5 */ +#define SIO_ID_UART1 6 /* D21:F6 */ +#define SIO_ID_SDIO 7 /* D23:F0 */ + +#define SIO_REG_PPR_CLOCK 0x800 +#define SIO_REG_PPR_CLOCK_EN BIT(0) +#define SIO_REG_PPR_CLOCK_UPDATE BIT(31) +#define SIO_REG_PPR_CLOCK_M_DIV 0x25a +#define SIO_REG_PPR_CLOCK_N_DIV 0x7fff +#define SIO_REG_PPR_RST 0x804 +#define SIO_REG_PPR_RST_ASSERT 0x3 +#define SIO_REG_PPR_GEN 0x808 +#define SIO_REG_PPR_GEN_LTR_MODE_MASK BIT(2) +#define SIO_REG_PPR_GEN_VOLTAGE_MASK BIT(3) +#define SIO_REG_PPR_GEN_VOLTAGE(x) ((x & 1) << 3) +#define SIO_REG_AUTO_LTR 0x814 + +#define SIO_REG_SDIO_PPR_GEN 0x1008 +#define SIO_REG_SDIO_PPR_SW_LTR 0x1010 +#define SIO_REG_SDIO_PPR_CMD12 0x3c +#define SIO_REG_SDIO_PPR_CMD12_B30 BIT(30) + +#define SIO_PIN_INTA 1 /* IRQ5 in ACPI mode */ +#define SIO_PIN_INTB 2 /* IRQ6 in ACPI mode */ +#define SIO_PIN_INTC 3 /* IRQ7 in ACPI mode */ +#define SIO_PIN_INTD 4 /* IRQ13 in ACPI mode */ + +#endif /* __ARCH_BROADWELL_SERIALIO_H_ */ diff --git a/arch/x86/include/asm/arch-broadwell/spi.h b/arch/x86/include/asm/arch-broadwell/spi.h new file mode 100644 index 0000000..7820998 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/spi.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2014 Google Inc. + * + * This file is from coreboot soc/intel/broadwell/include/soc/spi.h + */ + +#ifndef _BROADWELL_SPI_H_ +#define _BROADWELL_SPI_H_ + +/* + * SPI Opcode Menu setup for SPIBAR lockdown + * should support most common flash chips. + */ + +#define SPIBAR_OFFSET 0x3800 +#define SPI_REG(x) (RCB_REG(SPIBAR_OFFSET + (x))) + +/* Reigsters within the SPIBAR */ +#define SPIBAR_SSFC 0x91 +#define SPIBAR_FDOC 0xb0 +#define SPIBAR_FDOD 0xb4 + +#define SPIBAR_PREOP 0x94 +#define SPIBAR_OPTYPE 0x96 +#define SPIBAR_OPMENU_LOWER 0x98 +#define SPIBAR_OPMENU_UPPER 0x9c + +#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */ +#define SPI_OPTYPE_0 0x01 /* Write, no address */ + +#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */ +#define SPI_OPTYPE_1 0x03 /* Write, address required */ + +#define SPI_OPMENU_2 0x03 /* READ: Read Data */ +#define SPI_OPTYPE_2 0x02 /* Read, address required */ + +#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */ +#define SPI_OPTYPE_3 0x00 /* Read, no address */ + +#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */ +#define SPI_OPTYPE_4 0x03 /* Write, address required */ + +#define SPI_OPMENU_5 0x9f /* RDID: Read ID */ +#define SPI_OPTYPE_5 0x00 /* Read, no address */ + +#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */ +#define SPI_OPTYPE_6 0x03 /* Write, address required */ + +#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */ +#define SPI_OPTYPE_7 0x02 /* Read, address required */ + +#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \ + (SPI_OPMENU_5 << 8) | SPI_OPMENU_4) +#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \ + (SPI_OPMENU_1 << 8) | SPI_OPMENU_0) + +#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \ + (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \ + (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \ + (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0)) + +#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */ + +#define SPIBAR_HSFS 0x04 /* SPI hardware sequence status */ +#define SPIBAR_HSFS_FLOCKDN (1 << 15)/* Flash Configuration Lock-Down */ +#define SPIBAR_HSFS_SCIP (1 << 5) /* SPI Cycle In Progress */ +#define SPIBAR_HSFS_AEL (1 << 2) /* SPI Access Error Log */ +#define SPIBAR_HSFS_FCERR (1 << 1) /* SPI Flash Cycle Error */ +#define SPIBAR_HSFS_FDONE (1 << 0) /* SPI Flash Cycle Done */ +#define SPIBAR_HSFC 0x06 /* SPI hardware sequence control */ +#define SPIBAR_HSFC_BYTE_COUNT(c) (((c - 1) & 0x3f) << 8) +#define SPIBAR_HSFC_CYCLE_READ (0 << 1) /* Read cycle */ +#define SPIBAR_HSFC_CYCLE_WRITE (2 << 1) /* Write cycle */ +#define SPIBAR_HSFC_CYCLE_ERASE (3 << 1) /* Erase cycle */ +#define SPIBAR_HSFC_GO (1 << 0) /* GO: start SPI transaction */ +#define SPIBAR_FADDR 0x08 /* SPI flash address */ +#define SPIBAR_FDATA(n) (0x10 + (4 * n)) /* SPI flash data */ +#define SPIBAR_SSFS 0x90 +#define SPIBAR_SSFS_ERROR (1 << 3) +#define SPIBAR_SSFS_DONE (1 << 2) +#define SPIBAR_SSFC 0x91 +#define SPIBAR_SSFC_DATA (1 << 14) +#define SPIBAR_SSFC_GO (1 << 1) + +#endif diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h new file mode 100644 index 0000000..dd8d1cb --- /dev/null +++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + */ + +#ifndef _COREBOOT_SYSINFO_H +#define _COREBOOT_SYSINFO_H + +#include <asm/coreboot_tables.h> + +/* Maximum number of memory range definitions */ +#define SYSINFO_MAX_MEM_RANGES 32 +/* Allow a maximum of 8 GPIOs */ +#define SYSINFO_MAX_GPIOS 8 + +struct sysinfo_t { + int n_memranges; + struct memrange { + unsigned long long base; + unsigned long long size; + unsigned int type; + } memrange[SYSINFO_MAX_MEM_RANGES]; + + u32 cmos_range_start; + u32 cmos_range_end; + u32 cmos_checksum_location; + u32 vbnv_start; + u32 vbnv_size; + + char *version; + char *extra_version; + char *build; + char *compile_time; + char *compile_by; + char *compile_host; + char *compile_domain; + char *compiler; + char *linker; + char *assembler; + + struct cb_framebuffer *framebuffer; + + int num_gpios; + struct cb_gpio gpios[SYSINFO_MAX_GPIOS]; + + void *vdat_addr; + u32 vdat_size; + void *tstamp_table; + void *cbmem_cons; + + struct cb_serial *serial; +}; + +extern struct sysinfo_t lib_sysinfo; + +int get_coreboot_info(struct sysinfo_t *info); + +#endif diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h new file mode 100644 index 0000000..9320afb --- /dev/null +++ b/arch/x86/include/asm/arch-coreboot/timestamp.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + */ + +#ifndef __COREBOOT_TIMESTAMP_H__ +#define __COREBOOT_TIMESTAMP_H__ + +enum timestamp_id { + /* coreboot specific timestamp IDs */ + TS_START_ROMSTAGE = 1, + TS_BEFORE_INITRAM = 2, + TS_AFTER_INITRAM = 3, + TS_END_ROMSTAGE = 4, + TS_START_COPYRAM = 8, + TS_END_COPYRAM = 9, + TS_START_RAMSTAGE = 10, + TS_DEVICE_ENUMERATE = 30, + TS_DEVICE_CONFIGURE = 40, + TS_DEVICE_ENABLE = 50, + TS_DEVICE_INITIALIZE = 60, + TS_DEVICE_DONE = 70, + TS_CBMEM_POST = 75, + TS_WRITE_TABLES = 80, + TS_LOAD_PAYLOAD = 90, + TS_ACPI_WAKE_JUMP = 98, + TS_SELFBOOT_JUMP = 99, + + /* U-Boot entry IDs start at 1000 */ + TS_U_BOOT_INITTED = 1000, /* This is where u-boot starts */ + TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel. */ +}; + +void timestamp_init(void); +void timestamp_add(enum timestamp_id id, uint64_t ts_time); +void timestamp_add_now(enum timestamp_id id); + +/** + * timestamp_add_to_bootstage - Add important coreboot timestamps to bootstage + * + * @return 0 if ok, -1 if no timestamps were found + */ +int timestamp_add_to_bootstage(void); + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/fsp/fsp_configs.h b/arch/x86/include/asm/arch-ivybridge/fsp/fsp_configs.h new file mode 100644 index 0000000..ae9105b --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/fsp/fsp_configs.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_CONFIGS_H__ +#define __FSP_CONFIGS_H__ + +struct platform_config { + u8 enable_ht; + u8 enable_turbo; + u8 enable_memory_down; + u8 enable_fast_boot; +}; + +/* + * Dummy structure for now as currently only SPD is verified in U-Boot. + * + * We can add the missing parameters when adding support on a board with + * memory down configuration. + */ +struct memory_config { + u8 dummy; +}; + +struct fsp_config_data { + struct fsp_cfg_common common; + struct platform_config plat_config; + struct memory_config mem_config; +}; + +struct fspinit_rtbuf { + u32 stack_top; + u32 boot_mode; + struct platform_config *plat_config; + struct memory_config *mem_config; +}; + +#endif /* __FSP_CONFIGS_H__ */ diff --git a/arch/x86/include/asm/arch-ivybridge/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-ivybridge/fsp/fsp_vpd.h new file mode 100644 index 0000000..4b0f23a --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/fsp/fsp_vpd.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_VPD_H__ +#define __FSP_VPD_H__ + +/* IvyBridge FSP does not support VPD/UPD */ + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/me.h b/arch/x86/include/asm/arch-ivybridge/me.h new file mode 100644 index 0000000..518c308 --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/me.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From Coreboot src/southbridge/intel/bd82x6x/me.h + * + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + */ + +#ifndef _ASM_INTEL_ME_H +#define _ASM_INTEL_ME_H + +#include <asm/me_common.h> + +struct __packed mbp_fw_version_name { + u32 major_version:16; + u32 minor_version:16; + u32 hotfix_version:16; + u32 build_version:16; +}; + +struct __packed mbp_icc_profile { + u8 num_icc_profiles; + u8 icc_profile_soft_strap; + u8 icc_profile_index; + u8 reserved; + u32 register_lock_mask[3]; +}; + +struct __packed platform_type_rule_data { + u32 platform_target_usage_type:4; + u32 platform_target_market_type:2; + u32 super_sku:1; + u32 reserved:1; + u32 intel_me_fw_image_type:4; + u32 platform_brand:4; + u32 reserved_1:16; +}; + +struct __packed mbp_fw_caps { + struct mefwcaps_sku fw_capabilities; + u8 available; +}; + +struct __packed mbp_plat_type { + struct platform_type_rule_data rule_data; + u8 available; +}; + +struct __packed me_bios_payload { + struct mbp_fw_version_name fw_version_name; + struct mbp_fw_caps fw_caps_sku; + struct mbp_rom_bist_data rom_bist_data; + struct mbp_platform_key platform_key; + struct mbp_plat_type fw_plat_type; + struct mbp_icc_profile icc_profile; + struct tdt_state_info at_state; + u32 mfsintegrity; +}; + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h new file mode 100644 index 0000000..4839ebc --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From Coreboot file of the same name + * + * Copyright (C) 2011 The ChromiumOS Authors. + */ + +#ifndef _ASM_ARCH_MODEL_206AX_H +#define _ASM_ARCH_MODEL_206AX_H + +#define CPUID_VMX (1 << 5) +#define CPUID_SMX (1 << 6) +#define MSR_FEATURE_CONFIG 0x13c +#define IA32_PLATFORM_DCA_CAP 0x1f8 +#define IA32_MISC_ENABLE 0x1a0 +#define MSR_TEMPERATURE_TARGET 0x1a2 +#define IA32_THERM_INTERRUPT 0x19b +#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 +#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2 +#define MSR_LT_LOCK_MEMORY 0x2e7 +#define IA32_MC0_STATUS 0x401 + +#define MSR_MISC_PWR_MGMT 0x1aa +#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) + +#define MSR_PKGC3_IRTL 0x60a +#define MSR_PKGC6_IRTL 0x60b +#define MSR_PKGC7_IRTL 0x60c +#define IRTL_VALID (1 << 15) +#define IRTL_1_NS (0 << 10) +#define IRTL_32_NS (1 << 10) +#define IRTL_1024_NS (2 << 10) +#define IRTL_32768_NS (3 << 10) +#define IRTL_1048576_NS (4 << 10) +#define IRTL_33554432_NS (5 << 10) +#define IRTL_RESPONSE_MASK (0x3ff) + +#define MSR_PP0_CURRENT_CONFIG 0x601 +#define PP0_CURRENT_LIMIT (112 << 3) /* 112 A */ +#define MSR_PP1_CURRENT_CONFIG 0x602 +#define PP1_CURRENT_LIMIT_SNB (35 << 3) /* 35 A */ +#define PP1_CURRENT_LIMIT_IVB (50 << 3) /* 50 A */ +#define MSR_PKG_POWER_SKU 0x614 + +#define IVB_CONFIG_TDP_MIN_CPUID 0x306a2 +#define MSR_CONFIG_TDP_LEVEL1 0x649 +#define MSR_CONFIG_TDP_LEVEL2 0x64a +#define MSR_CONFIG_TDP_CONTROL 0x64b + +/* P-state configuration */ +#define PSS_MAX_ENTRIES 8 +#define PSS_RATIO_STEP 2 +#define PSS_LATENCY_TRANSITION 10 +#define PSS_LATENCY_BUSMASTER 10 + +/* Configure power limits for turbo mode */ +void set_power_limits(u8 power_limit_1_time); +bool cpu_ivybridge_config_tdp_levels(void); + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h b/arch/x86/include/asm/arch-ivybridge/pch.h new file mode 100644 index 0000000..8018bc0 --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/pch.h @@ -0,0 +1,398 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014 Google, Inc + * + * From Coreboot src/southbridge/intel/bd82x6x/pch.h + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2012 The Chromium OS Authors. All rights reserved. + */ + +#ifndef _ASM_ARCH_PCH_H +#define _ASM_ARCH_PCH_H + +#include <pci.h> + +/* PCH types */ +#define PCH_TYPE_CPT 0x1c /* CougarPoint */ +#define PCH_TYPE_PPT 0x1e /* IvyBridge */ + +/* PCH stepping values for LPC device */ +#define PCH_STEP_A0 0 +#define PCH_STEP_A1 1 +#define PCH_STEP_B0 2 +#define PCH_STEP_B1 3 +#define PCH_STEP_B2 4 +#define PCH_STEP_B3 5 +#define DEFAULT_GPIOBASE 0x0480 +#define DEFAULT_PMBASE 0x0500 + +#define SMBUS_IO_BASE 0x0400 + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 +#define MAINBOARD_POWER_KEEP 2 + +/* PCI Configuration Space (D30:F0): PCI2PCI */ +#define PSTS 0x06 +#define SMLT 0x1b +#define SECSTS 0x1e +#define INTR 0x3c +#define BCTRL 0x3e +#define SBR (1 << 6) +#define SEE (1 << 1) +#define PERE (1 << 0) + +#define PCH_EHCI1_DEV PCI_BDF(0, 0x1d, 0) +#define PCH_EHCI2_DEV PCI_BDF(0, 0x1a, 0) +#define PCH_XHCI_DEV PCI_BDF(0, 0x14, 0) +#define PCH_ME_DEV PCI_BDF(0, 0x16, 0) +#define PCH_PCIE_DEV_SLOT 28 + +#define PCH_DEV PCI_BDF(0, 0, 0) +#define PCH_VIDEO_DEV PCI_BDF(0, 2, 0) + +/* PCI Configuration Space (D31:F0): LPC */ +#define PCH_LPC_DEV PCI_BDF(0, 0x1f, 0) +#define SERIRQ_CNTL 0x64 + +#define GEN_PMCON_1 0xa0 +#define GEN_PMCON_2 0xa2 +#define GEN_PMCON_3 0xa4 +#define ETR3 0xac +#define ETR3_CWORWRE (1 << 18) +#define ETR3_CF9GR (1 << 20) + +/* GEN_PMCON_3 bits */ +#define RTC_BATTERY_DEAD (1 << 2) +#define RTC_POWER_FAILED (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) + +#define BIOS_CNTL 0xDC +#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ +#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ +#define GPIO_ROUT 0xb8 + +#define PIRQA_ROUT 0x60 +#define PIRQB_ROUT 0x61 +#define PIRQC_ROUT 0x62 +#define PIRQD_ROUT 0x63 +#define PIRQE_ROUT 0x68 +#define PIRQF_ROUT 0x69 +#define PIRQG_ROUT 0x6A +#define PIRQH_ROUT 0x6B + +#define GEN_PMCON_1 0xa0 +#define GEN_PMCON_2 0xa2 +#define GEN_PMCON_3 0xa4 +#define ETR3 0xac +#define ETR3_CWORWRE (1 << 18) +#define ETR3_CF9GR (1 << 20) + +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 +#define BIOS_CNTL 0xDC +#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ +#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ +#define GPIO_ROUT 0xb8 + +/* PCI Configuration Space (D31:F1): IDE */ +#define PCH_IDE_DEV PCI_BDF(0, 0x1f, 1) +#define PCH_SATA_DEV PCI_BDF(0, 0x1f, 2) +#define PCH_SATA2_DEV PCI_BDF(0, 0x1f, 5) + +#define IDE_SDMA_CNT 0x48 /* Synchronous DMA control */ +#define IDE_SSDE1 (1 << 3) +#define IDE_SSDE0 (1 << 2) +#define IDE_PSDE1 (1 << 1) +#define IDE_PSDE0 (1 << 0) + +#define IDE_SDMA_TIM 0x4a + +#define IDE_CONFIG 0x54 /* IDE I/O Configuration Register */ +#define SIG_MODE_SEC_NORMAL (0 << 18) +#define SIG_MODE_SEC_TRISTATE (1 << 18) +#define SIG_MODE_SEC_DRIVELOW (2 << 18) +#define SIG_MODE_PRI_NORMAL (0 << 16) +#define SIG_MODE_PRI_TRISTATE (1 << 16) +#define SIG_MODE_PRI_DRIVELOW (2 << 16) +#define FAST_SCB1 (1 << 15) +#define FAST_SCB0 (1 << 14) +#define FAST_PCB1 (1 << 13) +#define FAST_PCB0 (1 << 12) +#define SCB1 (1 << 3) +#define SCB0 (1 << 2) +#define PCB1 (1 << 1) +#define PCB0 (1 << 0) + +#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */ +#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */ +#define SATA_SP 0xd0 /* Scratchpad */ + +/* SATA IOBP Registers */ +#define SATA_IOBP_SP0G3IR 0xea000151 +#define SATA_IOBP_SP1G3IR 0xea000051 + +#define VCH 0x0000 /* 32bit */ +#define VCAP1 0x0004 /* 32bit */ +#define VCAP2 0x0008 /* 32bit */ +#define PVC 0x000c /* 16bit */ +#define PVS 0x000e /* 16bit */ + +#define V0CAP 0x0010 /* 32bit */ +#define V0CTL 0x0014 /* 32bit */ +#define V0STS 0x001a /* 16bit */ + +#define V1CAP 0x001c /* 32bit */ +#define V1CTL 0x0020 /* 32bit */ +#define V1STS 0x0026 /* 16bit */ + +#define RCTCL 0x0100 /* 32bit */ +#define ESD 0x0104 /* 32bit */ +#define ULD 0x0110 /* 32bit */ +#define ULBA 0x0118 /* 64bit */ + +#define RP1D 0x0120 /* 32bit */ +#define RP1BA 0x0128 /* 64bit */ +#define RP2D 0x0130 /* 32bit */ +#define RP2BA 0x0138 /* 64bit */ +#define RP3D 0x0140 /* 32bit */ +#define RP3BA 0x0148 /* 64bit */ +#define RP4D 0x0150 /* 32bit */ +#define RP4BA 0x0158 /* 64bit */ +#define HDD 0x0160 /* 32bit */ +#define HDBA 0x0168 /* 64bit */ +#define RP5D 0x0170 /* 32bit */ +#define RP5BA 0x0178 /* 64bit */ +#define RP6D 0x0180 /* 32bit */ +#define RP6BA 0x0188 /* 64bit */ + +#define RPC 0x0400 /* 32bit */ +#define RPFN 0x0404 /* 32bit */ + +#define TRSR 0x1e00 /* 8bit */ +#define TRCR 0x1e10 /* 64bit */ +#define TWDR 0x1e18 /* 64bit */ + +#define IOTR0 0x1e80 /* 64bit */ +#define IOTR1 0x1e88 /* 64bit */ +#define IOTR2 0x1e90 /* 64bit */ +#define IOTR3 0x1e98 /* 64bit */ + +#define TCTL 0x3000 /* 8bit */ + +#define NOINT 0 +#define INTA 1 +#define INTB 2 +#define INTC 3 +#define INTD 4 + +#define DIR_IDR 12 /* Interrupt D Pin Offset */ +#define DIR_ICR 8 /* Interrupt C Pin Offset */ +#define DIR_IBR 4 /* Interrupt B Pin Offset */ +#define DIR_IAR 0 /* Interrupt A Pin Offset */ + +#define PIRQA 0 +#define PIRQB 1 +#define PIRQC 2 +#define PIRQD 3 +#define PIRQE 4 +#define PIRQF 5 +#define PIRQG 6 +#define PIRQH 7 + +/* IO Buffer Programming */ +#define IOBPIRI 0x2330 +#define IOBPD 0x2334 +#define IOBPS 0x2338 +#define IOBPS_RW_BX ((1 << 9)|(1 << 10)) +#define IOBPS_WRITE_AX ((1 << 9)|(1 << 10)) +#define IOBPS_READ_AX ((1 << 8)|(1 << 9)|(1 << 10)) + +#define D31IP 0x3100 /* 32bit */ +#define D31IP_TTIP 24 /* Thermal Throttle Pin */ +#define D31IP_SIP2 20 /* SATA Pin 2 */ +#define D31IP_SMIP 12 /* SMBUS Pin */ +#define D31IP_SIP 8 /* SATA Pin */ +#define D30IP 0x3104 /* 32bit */ +#define D30IP_PIP 0 /* PCI Bridge Pin */ +#define D29IP 0x3108 /* 32bit */ +#define D29IP_E1P 0 /* EHCI #1 Pin */ +#define D28IP 0x310c /* 32bit */ +#define D28IP_P8IP 28 /* PCI Express Port 8 */ +#define D28IP_P7IP 24 /* PCI Express Port 7 */ +#define D28IP_P6IP 20 /* PCI Express Port 6 */ +#define D28IP_P5IP 16 /* PCI Express Port 5 */ +#define D28IP_P4IP 12 /* PCI Express Port 4 */ +#define D28IP_P3IP 8 /* PCI Express Port 3 */ +#define D28IP_P2IP 4 /* PCI Express Port 2 */ +#define D28IP_P1IP 0 /* PCI Express Port 1 */ +#define D27IP 0x3110 /* 32bit */ +#define D27IP_ZIP 0 /* HD Audio Pin */ +#define D26IP 0x3114 /* 32bit */ +#define D26IP_E2P 0 /* EHCI #2 Pin */ +#define D25IP 0x3118 /* 32bit */ +#define D25IP_LIP 0 /* GbE LAN Pin */ +#define D22IP 0x3124 /* 32bit */ +#define D22IP_KTIP 12 /* KT Pin */ +#define D22IP_IDERIP 8 /* IDE-R Pin */ +#define D22IP_MEI2IP 4 /* MEI #2 Pin */ +#define D22IP_MEI1IP 0 /* MEI #1 Pin */ +#define D20IP 0x3128 /* 32bit */ +#define D20IP_XHCIIP 0 +#define D31IR 0x3140 /* 16bit */ +#define D30IR 0x3142 /* 16bit */ +#define D29IR 0x3144 /* 16bit */ +#define D28IR 0x3146 /* 16bit */ +#define D27IR 0x3148 /* 16bit */ +#define D26IR 0x314c /* 16bit */ +#define D25IR 0x3150 /* 16bit */ +#define D22IR 0x315c /* 16bit */ +#define D20IR 0x3160 /* 16bit */ +#define OIC 0x31fe /* 16bit */ + +#define SPI_FREQ_SWSEQ 0x3893 +#define SPI_DESC_COMP0 0x38b0 +#define SPI_FREQ_WR_ERA 0x38b4 + +#define DIR_ROUTE(a, b, c, d) \ + (((d) << DIR_IDR) | ((c) << DIR_ICR) | \ + ((b) << DIR_IBR) | ((a) << DIR_IAR)) + +#define HPTC 0x3404 /* 32bit */ +#define BUC 0x3414 /* 32bit */ +#define PCH_DISABLE_GBE (1 << 5) +#define FD 0x3418 /* 32bit */ +#define DISPBDF 0x3424 /* 16bit */ +#define FD2 0x3428 /* 32bit */ +#define CG 0x341c /* 32bit */ + +/* Function Disable 1 RCBA 0x3418 */ +#define PCH_DISABLE_ALWAYS ((1 << 0)|(1 << 26)) +#define PCH_DISABLE_P2P (1 << 1) +#define PCH_DISABLE_SATA1 (1 << 2) +#define PCH_DISABLE_SMBUS (1 << 3) +#define PCH_DISABLE_HD_AUDIO (1 << 4) +#define PCH_DISABLE_EHCI2 (1 << 13) +#define PCH_DISABLE_LPC (1 << 14) +#define PCH_DISABLE_EHCI1 (1 << 15) +#define PCH_DISABLE_PCIE(x) (1 << (16 + x)) +#define PCH_DISABLE_THERMAL (1 << 24) +#define PCH_DISABLE_SATA2 (1 << 25) +#define PCH_DISABLE_XHCI (1 << 27) + +/* Function Disable 2 RCBA 0x3428 */ +#define PCH_DISABLE_KT (1 << 4) +#define PCH_DISABLE_IDER (1 << 3) +#define PCH_DISABLE_MEI2 (1 << 2) +#define PCH_DISABLE_MEI1 (1 << 1) +#define PCH_ENABLE_DBDF (1 << 0) + +/* ICH7 GPIOBASE */ +#define GPIO_USE_SEL 0x00 +#define GP_IO_SEL 0x04 +#define GP_LVL 0x0c +#define GPO_BLINK 0x18 +#define GPI_INV 0x2c +#define GPIO_USE_SEL2 0x30 +#define GP_IO_SEL2 0x34 +#define GP_LVL2 0x38 +#define GPIO_USE_SEL3 0x40 +#define GP_IO_SEL3 0x44 +#define GP_LVL3 0x48 +#define GP_RST_SEL1 0x60 +#define GP_RST_SEL2 0x64 +#define GP_RST_SEL3 0x68 + +/* ICH7 PMBASE */ +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PCIEXPWAK_STS (1 << 14) +#define PRBTNOR_STS (1 << 11) +#define RTC_STS (1 << 10) +#define PWRBTN_STS (1 << 8) +#define GBL_STS (1 << 5) +#define BM_STS (1 << 4) +#define TMROF_STS (1 << 0) +#define PM1_EN 0x02 +#define PCIEXPWAK_DIS (1 << 14) +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) +#define PM1_CNT 0x04 +#define SLP_EN (1 << 13) +#define SLP_TYP (7 << 10) +#define SLP_TYP_S0 0 +#define SLP_TYP_S1 1 +#define SLP_TYP_S3 5 +#define SLP_TYP_S4 6 +#define SLP_TYP_S5 7 +#define GBL_RLS (1 << 2) +#define BM_RLD (1 << 1) +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define PROC_CNT 0x10 +#define LV2 0x14 +#define LV3 0x15 +#define LV4 0x16 +#define PM2_CNT 0x50 /* mobile only */ +#define GPE0_STS 0x20 +#define PME_B0_STS (1 << 13) +#define PME_STS (1 << 11) +#define BATLOW_STS (1 << 10) +#define PCI_EXP_STS (1 << 9) +#define RI_STS (1 << 8) +#define SMB_WAK_STS (1 << 7) +#define TCOSCI_STS (1 << 6) +#define SWGPE_STS (1 << 2) +#define HOT_PLUG_STS (1 << 1) +#define GPE0_EN 0x28 +#define PME_B0_EN (1 << 13) +#define PME_EN (1 << 11) +#define TCOSCI_EN (1 << 6) +#define SMI_EN 0x30 +#define INTEL_USB2_EN (1 << 18) /* Intel-Specific USB2 SMI logic */ +#define LEGACY_USB2_EN (1 << 17) /* Legacy USB2 SMI logic */ +#define PERIODIC_EN (1 << 14) /* SMI on PERIODIC_STS in SMI_STS */ +#define TCO_EN (1 << 13) /* Enable TCO Logic (BIOSWE et al) */ +#define MCSMI_EN (1 << 11) /* Trap microcontroller range access */ +#define BIOS_RLS (1 << 7) /* asserts SCI on bit set */ +#define SWSMI_TMR_EN (1 << 6) /* start software smi timer on bit set */ +#define APMC_EN (1 << 5) /* Writes to APM_CNT cause SMI# */ +#define SLP_SMI_EN (1 << 4) /* Write SLP_EN in PM1_CNT asserts SMI# */ +#define LEGACY_USB_EN (1 << 3) /* Legacy USB circuit SMI logic */ +#define BIOS_EN (1 << 2) /* Assert SMI# on setting GBL_RLS bit */ +#define EOS (1 << 1) /* End of SMI (deassert SMI#) */ +#define GBL_SMI_EN (1 << 0) /* SMI# generation at all? */ +#define SMI_STS 0x34 +#define ALT_GP_SMI_EN 0x38 +#define ALT_GP_SMI_STS 0x3a +#define GPE_CNTL 0x42 +#define DEVACT_STS 0x44 +#define SS_CNT 0x50 +#define C3_RES 0x54 +#define TCO1_STS 0x64 +#define DMISCI_STS (1 << 9) +#define TCO2_STS 0x66 + +/** + * pch_silicon_revision() - Read silicon device ID from the PCH + * + * @dev: PCH device + * @return silicon device ID + */ +int pch_silicon_type(struct udevice *dev); + +/** + * pch_pch_iobp_update() - Update a pch register + * + * @dev: PCH device + * @address: Address to update + * @andvalue: Value to AND with existing value + * @orvalue: Value to OR with existing value + */ +void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue, + u32 orvalue); + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/pei_data.h b/arch/x86/include/asm/arch-ivybridge/pei_data.h new file mode 100644 index 0000000..b8da21b --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/pei_data.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011, Google Inc. + */ + +#ifndef ASM_ARCH_PEI_DATA_H +#define ASM_ARCH_PEI_DATA_H + +#include <linux/linkage.h> + +struct pch_usb3_controller_settings { + /* 0: Disable, 1: Enable, 2: Auto, 3: Smart Auto */ + uint16_t mode; + /* 4 bit mask, 1: switchable, 0: not switchable */ + uint16_t hs_port_switch_mask; + /* 0: No xHCI preOS driver, 1: xHCI preOS driver */ + uint16_t preboot_support; + /* 0: Disable, 1: Enable */ + uint16_t xhci_streams; +}; + +typedef asmlinkage void (*tx_byte_func)(unsigned char byte); + +#define PEI_VERSION 6 + +struct __packed pei_data { + uint32_t pei_version; + uint32_t mchbar; + uint32_t dmibar; + uint32_t epbar; + uint32_t pciexbar; + uint16_t smbusbar; + uint32_t wdbbar; + uint32_t wdbsize; + uint32_t hpet_address; + uint32_t rcba; + uint32_t pmbase; + uint32_t gpiobase; + uint32_t thermalbase; + uint32_t system_type; /* 0 Mobile, 1 Desktop/Server */ + uint32_t tseg_size; + uint8_t spd_addresses[4]; + uint8_t ts_addresses[4]; + int boot_mode; + int ec_present; + int gbe_enable; + /* + * 0 = leave channel enabled + * 1 = disable dimm 0 on channel + * 2 = disable dimm 1 on channel + * 3 = disable dimm 0+1 on channel + */ + int dimm_channel0_disabled; + int dimm_channel1_disabled; + /* Seed values saved in CMOS */ + uint32_t scrambler_seed; + uint32_t scrambler_seed_s3; + /* Data read from flash and passed into MRC */ + unsigned char *mrc_input; + unsigned int mrc_input_len; + /* Data from MRC that should be saved to flash */ + unsigned char *mrc_output; + unsigned int mrc_output_len; + /* + * Max frequency DDR3 could be ran at. Could be one of four values: + * 800, 1067, 1333, 1600 + */ + uint32_t max_ddr3_freq; + /* + * USB Port Configuration: + * [0] = enable + * [1] = overcurrent pin + * [2] = length + * + * Ports 0-7 can be mapped to OC0-OC3 + * Ports 8-13 can be mapped to OC4-OC7 + * + * Port Length + * MOBILE: + * < 0x050 = Setting 1 (back panel, 1-5in, lowest tx amplitude) + * < 0x140 = Setting 2 (back panel, 5-14in, highest tx amplitude) + * DESKTOP: + * < 0x080 = Setting 1 (front/back panel, <8in, lowest tx amplitude) + * < 0x130 = Setting 2 (back panel, 8-13in, higher tx amplitude) + * < 0x150 = Setting 3 (back panel, 13-15in, higest tx amplitude) + */ + uint16_t usb_port_config[16][3]; + /* See the usb3 struct above for details */ + struct pch_usb3_controller_settings usb3; + /* + * SPD data array for onboard RAM. Specify address 0xf0, + * 0xf1, 0xf2, 0xf3 to index one of the 4 slots in + * spd_address for a given "DIMM". + */ + uint8_t spd_data[4][256]; + tx_byte_func tx_byte; + int ddr3lv_support; + /* + * pcie_init needs to be set to 1 to have the system agent initialise + * PCIe. Note: This should only be required if your system has Gen3 + * devices and it will increase your boot time by at least 100ms. + */ + int pcie_init; + /* + * N mode functionality. Leave this setting at 0. + * 0 Auto + * 1 1N + * 2 2N + */ + int nmode; + /* + * DDR refresh rate config. JEDEC Standard No.21-C Annex K allows + * for DIMM SPD data to specify whether double-rate is required for + * extended operating temperature range. + * 0 Enable double rate based upon temperature thresholds + * 1 Normal rate + * 2 Always enable double rate + */ + int ddr_refresh_rate_config; +}; + +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h new file mode 100644 index 0000000..a3a507f --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014 Google, Inc + * + * From Coreboot file of the same name + * + * Copyright (C) 2007-2008 coresystems GmbH + * Copyright (C) 2011 Google Inc. + */ + +#ifndef _ACH_ASM_SANDYBRIDGE_H +#define _ACH_ASM_SANDYBRIDGE_H + +/* Chipset types */ +#define SANDYBRIDGE_MOBILE 0 +#define SANDYBRIDGE_DESKTOP 1 +#define SANDYBRIDGE_SERVER 2 + +/* Device ID for SandyBridge and IvyBridge */ +#define BASE_REV_SNB 0x00 +#define BASE_REV_IVB 0x50 +#define BASE_REV_MASK 0x50 + +/* SandyBridge CPU stepping */ +#define SNB_STEP_D0 (BASE_REV_SNB + 5) /* Also J0 */ +#define SNB_STEP_D1 (BASE_REV_SNB + 6) +#define SNB_STEP_D2 (BASE_REV_SNB + 7) /* Also J1/Q0 */ + +/* IvyBridge CPU stepping */ +#define IVB_STEP_A0 (BASE_REV_IVB + 0) +#define IVB_STEP_B0 (BASE_REV_IVB + 2) +#define IVB_STEP_C0 (BASE_REV_IVB + 4) +#define IVB_STEP_K0 (BASE_REV_IVB + 5) +#define IVB_STEP_D0 (BASE_REV_IVB + 6) + +/* Intel Enhanced Debug region must be 4MB */ +#define IED_SIZE 0x400000 + +/* Northbridge BARs */ +#define DEFAULT_DMIBAR 0xfed18000 /* 4 KB */ +#define DEFAULT_EPBAR 0xfed19000 /* 4 KB */ +#define DEFAULT_RCBABASE 0xfed1c000 +/* 4 KB per PCIe device */ +#define DEFAULT_PCIEXBAR CONFIG_PCIE_ECAM_BASE + +#define IOMMU_BASE1 0xfed90000ULL +#define IOMMU_BASE2 0xfed91000ULL + +/* Device 0:0.0 PCI configuration space (Host Bridge) */ +#define EPBAR 0x40 +#define MCHBAR 0x48 +#define PCIEXBAR 0x60 +#define DMIBAR 0x68 +#define X60BAR 0x60 + +#define GGC 0x50 /* GMCH Graphics Control */ + +#define DEVEN 0x54 /* Device Enable */ +#define DEVEN_PEG60 (1 << 13) +#define DEVEN_IGD (1 << 4) +#define DEVEN_PEG10 (1 << 3) +#define DEVEN_PEG11 (1 << 2) +#define DEVEN_PEG12 (1 << 1) +#define DEVEN_HOST (1 << 0) + +#define PAM0 0x80 +#define PAM1 0x81 +#define PAM2 0x82 +#define PAM3 0x83 +#define PAM4 0x84 +#define PAM5 0x85 +#define PAM6 0x86 + +#define LAC 0x87 /* Legacy Access Control */ +#define SMRAM 0x88 /* System Management RAM Control */ +#define D_OPEN (1 << 6) +#define D_CLS (1 << 5) +#define D_LCK (1 << 4) +#define G_SMRAME (1 << 3) +#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) + +#define TOM 0xa0 +#define TOUUD 0xa8 /* Top of Upper Usable DRAM */ +#define TSEG 0xb8 /* TSEG base */ +#define TOLUD 0xbc /* Top of Low Used Memory */ + +#define SKPAD 0xdc /* Scratchpad Data */ + +/* Device 0:1.0 PCI configuration space (PCI Express) */ +#define BCTRL1 0x3e /* 16bit */ + +/* Device 0:2.0 PCI configuration space (Graphics Device) */ + +#define MSAC 0x62 /* Multi Size Aperture Control */ +#define SWSCI 0xe8 /* SWSCI enable */ +#define ASLS 0xfc /* OpRegion Base */ + +/* + * MCHBAR + */ +#define SSKPD 0x5d14 /* 16bit (scratchpad) */ +#define BIOS_RESET_CPL 0x5da8 /* 8bit */ + +/* + * DMIBAR + */ + +#define DMIBAR_REG(x) (DEFAULT_DMIBAR + x) + +/** + * bridge_silicon_revision() - Get the Northbridge revision + * + * @dev: Northbridge device + * @return revision ID (bits 3:0) and bridge ID (bits 7:4) + */ +int bridge_silicon_revision(struct udevice *dev); + +#endif diff --git a/arch/x86/include/asm/arch-qemu/device.h b/arch/x86/include/asm/arch-qemu/device.h new file mode 100644 index 0000000..daafd5d --- /dev/null +++ b/arch/x86/include/asm/arch-qemu/device.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QEMU_DEVICE_H_ +#define _QEMU_DEVICE_H_ + +#include <pci.h> + +#define QEMU_I440FX PCI_BDF(0, 0, 0) +#define PIIX_ISA PCI_BDF(0, 1, 0) +#define PIIX_IDE PCI_BDF(0, 1, 1) +#define PIIX_USB PCI_BDF(0, 1, 2) +#define PIIX_PM PCI_BDF(0, 1, 3) +#define ICH9_PM PCI_BDF(0, 0x1f, 0) +#define I440FX_VGA PCI_BDF(0, 2, 0) + +#define QEMU_Q35 PCI_BDF(0, 0, 0) +#define Q35_VGA PCI_BDF(0, 1, 0) + +#endif /* _QEMU_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-qemu/qemu.h b/arch/x86/include/asm/arch-qemu/qemu.h new file mode 100644 index 0000000..061735b --- /dev/null +++ b/arch/x86/include/asm/arch-qemu/qemu.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ARCH_QEMU_H_ +#define _ARCH_QEMU_H_ + +/* Programmable Attribute Map (PAM) Registers */ +#define I440FX_PAM 0x59 +#define Q35_PAM 0x90 +#define PAM_NUM 7 +#define PAM_RW 0x33 + +/* X-Bus Chip Select Register */ +#define XBCS 0x4e +#define APIC_EN (1 << 8) + +/* IDE Timing Register */ +#define IDE0_TIM 0x40 +#define IDE1_TIM 0x42 +#define IDE_DECODE_EN (1 << 15) + +/* PCIe ECAM Base Address Register */ +#define PCIEX_BAR 0x60 +#define BAR_EN (1 << 0) + +/* I/O Ports */ +#define CMOS_ADDR_PORT 0x70 +#define CMOS_DATA_PORT 0x71 + +#define LOW_RAM_ADDR 0x34 +#define HIGH_RAM_ADDR 0x35 + +#define LOW_HIGHRAM_ADDR 0x5b +#define MID_HIGHRAM_ADDR 0x5c +#define HIGH_HIGHRAM_ADDR 0x5d + +/* PM registers */ +#define PMBA 0x40 +#define PMREGMISC 0x80 +#define PMIOSE (1 << 0) + +/** + * qemu_get_low_memory_size() - Get low memory size + * + * @return: size of memory below 4GiB + */ +u32 qemu_get_low_memory_size(void); + +/** + * qemu_get_high_memory_size() - Get high memory size + * + * @return: size of memory above 4GiB + */ +u64 qemu_get_high_memory_size(void); + +#endif /* _ARCH_QEMU_H_ */ diff --git a/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl new file mode 100644 index 0000000..6160217 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/acpi/global_nvs.h> + +OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE) +Field(GNVS, ByteAcc, NoLock, Preserve) +{ + PCNT, 8, /* processor count */ +} diff --git a/arch/x86/include/asm/arch-quark/acpi/irqroute.h b/arch/x86/include/asm/arch-quark/acpi/irqroute.h new file mode 100644 index 0000000..879b67d --- /dev/null +++ b/arch/x86/include/asm/arch-quark/acpi/irqroute.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/arch/device.h> + +#define PCI_DEV_PIRQ_ROUTES \ + PCI_DEV_PIRQ_ROUTE(QUARK_DEV_20, E, F, G, H), \ + PCI_DEV_PIRQ_ROUTE(QUARK_DEV_21, E, F, G, H), \ + PCI_DEV_PIRQ_ROUTE(QUARK_DEV_23, A, B, C, D) + +#define PCIE_BRIDGE_IRQ_ROUTES \ + PCIE_BRIDGE_DEV(RP, QUARK_DEV_23, A, B, C, D) diff --git a/arch/x86/include/asm/arch-quark/acpi/lpc.asl b/arch/x86/include/asm/arch-quark/acpi/lpc.asl new file mode 100644 index 0000000..fc30e0a --- /dev/null +++ b/arch/x86/include/asm/arch-quark/acpi/lpc.asl @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +/* Intel LPC Bus Device - 0:1f.0 */ + +Device (LPCB) +{ + Name(_ADR, 0x001f0000) + + OperationRegion(PRTX, PCI_Config, 0x60, 8) + Field(PRTX, AnyAcc, NoLock, Preserve) { + PRTA, 8, + PRTB, 8, + PRTC, 8, + PRTD, 8, + PRTE, 8, + PRTF, 8, + PRTG, 8, + PRTH, 8, + } + + #include <asm/acpi/irqlinks.asl> + + /* Firmware Hub */ + Device (FWH) + { + Name(_HID, EISAID("INT0800")) + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, 0xff000000, 0x01000000) + }) + } + + /* 8259 Interrupt Controller */ + Device (PIC) + { + Name(_HID, EISAID("PNP0000")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x20, 0x20, 0x01, 0x02) + IO(Decode16, 0x24, 0x24, 0x01, 0x02) + IO(Decode16, 0x28, 0x28, 0x01, 0x02) + IO(Decode16, 0x2c, 0x2c, 0x01, 0x02) + IO(Decode16, 0x30, 0x30, 0x01, 0x02) + IO(Decode16, 0x34, 0x34, 0x01, 0x02) + IO(Decode16, 0x38, 0x38, 0x01, 0x02) + IO(Decode16, 0x3c, 0x3c, 0x01, 0x02) + IO(Decode16, 0xa0, 0xa0, 0x01, 0x02) + IO(Decode16, 0xa4, 0xa4, 0x01, 0x02) + IO(Decode16, 0xa8, 0xa8, 0x01, 0x02) + IO(Decode16, 0xac, 0xac, 0x01, 0x02) + IO(Decode16, 0xb0, 0xb0, 0x01, 0x02) + IO(Decode16, 0xb4, 0xb4, 0x01, 0x02) + IO(Decode16, 0xb8, 0xb8, 0x01, 0x02) + IO(Decode16, 0xbc, 0xbc, 0x01, 0x02) + IO(Decode16, 0x4d0, 0x4d0, 0x01, 0x02) + IRQNoFlags () { 2 } + }) + } + + /* 8254 timer */ + Device (TIMR) + { + Name(_HID, EISAID("PNP0100")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x40, 0x40, 0x01, 0x04) + IO(Decode16, 0x50, 0x50, 0x10, 0x04) + IRQNoFlags() { 0 } + }) + } + + /* HPET */ + Device (HPET) + { + Name(_HID, EISAID("PNP0103")) + Name(_CID, 0x010CD041) + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, HPET_BASE_ADDRESS, HPET_BASE_SIZE) + }) + + Method(_STA) + { + Return (STA_VISIBLE) + } + } + + /* Real Time Clock */ + Device (RTC) + { + Name(_HID, EISAID("PNP0B00")) + Name(_CRS, ResourceTemplate() + { + IO(Decode16, 0x70, 0x70, 1, 8) + IRQNoFlags() { 8 } + }) + } + + /* LPC device: Resource consumption */ + Device (LDRC) + { + Name(_HID, EISAID("PNP0C02")) + Name(_UID, 2) + + Name(RBUF, ResourceTemplate() + { + IO(Decode16, 0x61, 0x61, 0x1, 0x01) /* NMI Status */ + IO(Decode16, 0x63, 0x63, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x65, 0x65, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x67, 0x67, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0x80, 0x80, 0x1, 0x01) /* Port 80 Post */ + IO(Decode16, 0x92, 0x92, 0x1, 0x01) /* CPU Reserved */ + IO(Decode16, 0xb2, 0xb2, 0x1, 0x02) /* SWSMI */ + }) + + Method(_CRS, 0, NotSerialized) + { + Return (RBUF) + } + } +} diff --git a/arch/x86/include/asm/arch-quark/acpi/platform.asl b/arch/x86/include/asm/arch-quark/acpi/platform.asl new file mode 100644 index 0000000..5b3e4a5 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/acpi/platform.asl @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <asm/acpi/statdef.asl> +#include <asm/arch/iomap.h> +#include <asm/arch/irq.h> + +/* + * The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0. + */ +Method(_PTS, 1) +{ +} + +/* The _WAK method is called on system wakeup */ +Method(_WAK, 1) +{ + Return (Package() {0, 0}) +} + +/* ACPI global NVS */ +#include "global_nvs.asl" + +/* TODO: add CPU ASL support */ + +Scope (\_SB) +{ + #include "southcluster.asl" +} + +/* Chipset specific sleep states */ +#include <asm/acpi/sleepstates.asl> diff --git a/arch/x86/include/asm/arch-quark/acpi/southcluster.asl b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl new file mode 100644 index 0000000..fe9edc1 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +Device (PCI0) +{ + Name(_HID, EISAID("PNP0A08")) /* PCIe */ + Name(_CID, EISAID("PNP0A03")) /* PCI */ + + Name(_ADR, 0) + Name(_BBN, 0) + + Name(MCRS, ResourceTemplate() + { + /* Bus Numbers */ + WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100, , , PB00) + + /* IO Region 0 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8, , , PI00) + + /* PCI Config Space */ + IO(Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008) + + /* IO Region 1 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300, , , PI01) + + /* VGA memory (0xa0000-0xbffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000a0000, 0x000bffff, 0x00000000, + 0x00020000, , , ASEG) + + /* OPROM reserved (0xc0000-0xc3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c0000, 0x000c3fff, 0x00000000, + 0x00004000, , , OPR0) + + /* OPROM reserved (0xc4000-0xc7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c4000, 0x000c7fff, 0x00000000, + 0x00004000, , , OPR1) + + /* OPROM reserved (0xc8000-0xcbfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c8000, 0x000cbfff, 0x00000000, + 0x00004000, , , OPR2) + + /* OPROM reserved (0xcc000-0xcffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000cc000, 0x000cffff, 0x00000000, + 0x00004000, , , OPR3) + + /* OPROM reserved (0xd0000-0xd3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000, + 0x00004000, , , OPR4) + + /* OPROM reserved (0xd4000-0xd7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000, + 0x00004000, , , OPR5) + + /* OPROM reserved (0xd8000-0xdbfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000, + 0x00004000, , , OPR6) + + /* OPROM reserved (0xdc000-0xdffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000dc000, 0x000dffff, 0x00000000, + 0x00004000, , , OPR7) + + /* BIOS Extension (0xe0000-0xe3fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000, + 0x00004000, , , ESG0) + + /* BIOS Extension (0xe4000-0xe7fff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000, + 0x00004000, , , ESG1) + + /* BIOS Extension (0xe8000-0xebfff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000, + 0x00004000, , , ESG2) + + /* BIOS Extension (0xec000-0xeffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000ec000, 0x000effff, 0x00000000, + 0x00004000, , , ESG3) + + /* System BIOS (0xf0000-0xfffff) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000f0000, 0x000fffff, 0x00000000, + 0x00010000, , , FSEG) + + /* PCI Memory Region (TOLM-CONFIG_MMCONF_BASE_ADDRESS) */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, , , PMEM) + }) + + Method(_CRS, 0, Serialized) + { + /* Update PCI resource area */ + CreateDwordField(MCRS, ^PMEM._MIN, PMIN) + CreateDwordField(MCRS, ^PMEM._MAX, PMAX) + CreateDwordField(MCRS, ^PMEM._LEN, PLEN) + + /* + * Hardcode TOLM to 2GB for now (see DRAM_MAX_SIZE in quark.h) + * + * TODO: for generic usage, read TOLM value from register, or + * from global NVS (not implemented by U-Boot yet). + */ + Store(0x80000000, PMIN) + Store(Subtract(MCFG_BASE_ADDRESS, 1), PMAX) + Add(Subtract(PMAX, PMIN), 1, PLEN) + + Return (MCRS) + } + + /* Device Resource Consumption */ + Device (PDRC) + { + Name(_HID, EISAID("PNP0C02")) + Name(_UID, 1) + + Name(PDRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, CONFIG_ESRAM_BASE, 0x80000) + Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE) + Memory32Fixed(ReadWrite, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE) + IO(Decode16, SPI_DMA_BASE_ADDRESS, SPI_DMA_BASE_ADDRESS, 0x0010, SPI_DMA_BASE_SIZE) + IO(Decode16, GPIO_BASE_ADDRESS, GPIO_BASE_ADDRESS, 0x0080, GPIO_BASE_SIZE) + IO(Decode16, WDT_BASE_ADDRESS, WDT_BASE_ADDRESS, 0x0040, WDT_BASE_SIZE) + }) + + /* Current Resource Settings */ + Method(_CRS, 0, Serialized) + { + Return (PDRS) + } + } + + Method(_OSC, 4) + { + /* Check for proper GUID */ + If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) { + /* Let OS control everything */ + Return (Arg3) + } Else { + /* Unrecognized UUID */ + CreateDWordField(Arg3, 0, CDW1) + Or(CDW1, 4, CDW1) + Return (Arg3) + } + } + + /* LPC Bridge 0:1f.0 */ + #include "lpc.asl" + + /* IRQ routing for each PCI device */ + #include <asm/acpi/irqroute.asl> +} diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000..0c43916 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_ + +/* + * Internal PCI device numbers within the SoC. + * + * Note it must start with 0x_ prefix, as the device number macro will be + * included in the ACPI ASL files (see irq_helper.h and irq_route.h). + */ + +#define QUARK_HOST_BRIDGE_DEV 0x00 +#define QUARK_HOST_BRIDGE_FUNC 0 + +#define QUARK_DEV_20 0x14 +#define QUARK_MMC_SDIO_FUNC 0 +#define QUARK_UART0_FUNC 1 +#define QUARK_USB_DEVICE_FUNC 2 +#define QUARK_USB_EHCI_FUNC 3 +#define QUARK_USB_OHCI_FUNC 4 +#define QUARK_UART1_FUNC 5 +#define QUARK_EMAC0_FUNC 6 +#define QUARK_EMAC1_FUNC 7 + +#define QUARK_DEV_21 0x15 +#define QUARK_SPI0_FUNC 0 +#define QUARK_SPI1_FUNC 1 +#define QUARK_I2C_GPIO_FUNC 2 + +#define QUARK_DEV_23 0x17 +#define QUARK_PCIE0_FUNC 0 +#define QUARK_PCIE1_FUNC 1 + +#define QUARK_LGC_BRIDGE_DEV 0x1f +#define QUARK_LGC_BRIDGE_FUNC 0 + +#ifndef __ASSEMBLY__ +#include <pci.h> + +#define QUARK_HOST_BRIDGE \ + PCI_BDF(0, QUARK_HOST_BRIDGE_DEV, QUARK_HOST_BRIDGE_FUNC) +#define QUARK_MMC_SDIO \ + PCI_BDF(0, QUARK_DEV_20, QUARK_MMC_SDIO_FUNC) +#define QUARK_UART0 \ + PCI_BDF(0, QUARK_DEV_20, QUARK_UART0_FUNC) +#define QUARK_USB_DEVICE \ + PCI_BDF(0, QUARK_DEV_20, QUARK_USB_DEVICE_FUNC) +#define QUARK_USB_EHCI \ + PCI_BDF(0, QUARK_DEV_20, QUARK_USB_EHCI_FUNC) +#define QUARK_USB_OHCI \ + PCI_BDF(0, QUARK_DEV_20, QUARK_USB_OHCI_FUNC) +#define QUARK_UART1 \ + PCI_BDF(0, QUARK_DEV_20, QUARK_UART1_FUNC) +#define QUARK_EMAC0 \ + PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC0_FUNC) +#define QUARK_EMAC1 \ + PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC1_FUNC) +#define QUARK_SPI0 \ + PCI_BDF(0, QUARK_DEV_21, QUARK_SPI0_FUNC) +#define QUARK_SPI1 \ + PCI_BDF(0, QUARK_DEV_21, QUARK_SPI1_FUNC) +#define QUARK_I2C_GPIO \ + PCI_BDF(0, QUARK_DEV_21, QUARK_I2C_GPIO_FUNC) +#define QUARK_PCIE0 \ + PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE0_FUNC) +#define QUARK_PCIE1 \ + PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE1_FUNC) +#define QUARK_LEGACY_BRIDGE \ + PCI_BDF(0, QUARK_LGC_BRIDGE_DEV, QUARK_LGC_BRIDGE_FUNC) +#endif /* __ASSEMBLY__ */ + +#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/global_nvs.h b/arch/x86/include/asm/arch-quark/global_nvs.h new file mode 100644 index 0000000..6e99e67 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/global_nvs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _GLOBAL_NVS_H_ +#define _GLOBAL_NVS_H_ + +struct __packed acpi_global_nvs { + u8 pcnt; /* processor count */ + + /* + * Add padding so sizeof(struct acpi_global_nvs) == 0x100. + * This must match the size defined in the global_nvs.asl. + */ + u8 rsvd[255]; +}; + +#endif /* _GLOBAL_NVS_H_ */ diff --git a/arch/x86/include/asm/arch-quark/iomap.h b/arch/x86/include/asm/arch-quark/iomap.h new file mode 100644 index 0000000..e233252 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/iomap.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUARK_IOMAP_H_ +#define _QUARK_IOMAP_H_ + +/* Memory Mapped IO bases */ + +/* ESRAM */ +#define ESRAM_BASE_ADDRESS CONFIG_ESRAM_BASE +#define ESRAM_BASE_SIZE ESRAM_SIZE + +/* PCI Configuration Space */ +#define MCFG_BASE_ADDRESS CONFIG_PCIE_ECAM_BASE +#define MCFG_BASE_SIZE 0x10000000 + +/* High Performance Event Timer */ +#define HPET_BASE_ADDRESS 0xfed00000 +#define HPET_BASE_SIZE 0x400 + +/* Root Complex Base Address */ +#define RCBA_BASE_ADDRESS CONFIG_RCBA_BASE +#define RCBA_BASE_SIZE 0x4000 + +/* IO Port bases */ +#define ACPI_PM1_BASE_ADDRESS CONFIG_ACPI_PM1_BASE +#define ACPI_PM1_BASE_SIZE 0x10 + +#define ACPI_PBLK_BASE_ADDRESS CONFIG_ACPI_PBLK_BASE +#define ACPI_PBLK_BASE_SIZE 0x10 + +#define SPI_DMA_BASE_ADDRESS CONFIG_SPI_DMA_BASE +#define SPI_DMA_BASE_SIZE 0x10 + +#define GPIO_BASE_ADDRESS CONFIG_GPIO_BASE +#define GPIO_BASE_SIZE 0x80 + +#define ACPI_GPE0_BASE_ADDRESS CONFIG_ACPI_GPE0_BASE +#define ACPI_GPE0_BASE_SIZE 0x40 + +#define WDT_BASE_ADDRESS CONFIG_WDT_BASE +#define WDT_BASE_SIZE 0x40 + +#endif /* _QUARK_IOMAP_H_ */ diff --git a/arch/x86/include/asm/arch-quark/irq.h b/arch/x86/include/asm/arch-quark/irq.h new file mode 100644 index 0000000..2aaa728 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/irq.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUARK_IRQ_H_ +#define _QUARK_IRQ_H_ + +#define PIRQA_APIC_IRQ 16 +#define PIRQB_APIC_IRQ 17 +#define PIRQC_APIC_IRQ 18 +#define PIRQD_APIC_IRQ 19 +#define PIRQE_APIC_IRQ 20 +#define PIRQF_APIC_IRQ 21 +#define PIRQG_APIC_IRQ 22 +#define PIRQH_APIC_IRQ 23 + +#endif /* _QUARK_IRQ_H_ */ diff --git a/arch/x86/include/asm/arch-quark/mrc.h b/arch/x86/include/asm/arch-quark/mrc.h new file mode 100644 index 0000000..2353426 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/mrc.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + */ + +#ifndef _MRC_H_ +#define _MRC_H_ + +#define MRC_VERSION 0x0111 + +/* architectural definitions */ +#define NUM_CHANNELS 1 /* number of channels */ +#define NUM_RANKS 2 /* number of ranks per channel */ +#define NUM_BYTE_LANES 4 /* number of byte lanes per channel */ + +/* software limitations */ +#define MAX_CHANNELS 1 +#define MAX_RANKS 2 +#define MAX_BYTE_LANES 4 + +#define MAX_SOCKETS 1 +#define MAX_SIDES 1 +#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS) + +/* Specify DRAM and channel width */ +enum { + X8, /* DRAM width */ + X16, /* DRAM width & Channel Width */ + X32 /* Channel Width */ +}; + +/* Specify DRAM speed */ +enum { + DDRFREQ_800, + DDRFREQ_1066 +}; + +/* Specify DRAM type */ +enum { + DDR3, + DDR3L +}; + +/* + * density: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb + * cl: DRAM CAS Latency in clocks + * ras: ACT to PRE command period + * wtr: Delay from start of internal write transaction to internal read command + * rrd: ACT to ACT command period (JESD79 specific to page size 1K/2K) + * faw: Four activate window (JESD79 specific to page size 1K/2K) + * + * ras/wtr/rrd/faw timings are in picoseconds + * + * Refer to JEDEC spec (or DRAM datasheet) when changing these values. + */ +struct dram_params { + uint8_t density; + uint8_t cl; + uint32_t ras; + uint32_t wtr; + uint32_t rrd; + uint32_t faw; +}; + +/* + * Delay configuration for individual signals + * Vref setting + * Scrambler seed + */ +struct mrc_timings { + uint32_t rcvn[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t rdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t wdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t wdq[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t vref[NUM_CHANNELS][NUM_BYTE_LANES]; + uint32_t wctl[NUM_CHANNELS][NUM_RANKS]; + uint32_t wcmd[NUM_CHANNELS]; + uint32_t scrambler_seed; + /* need to save for the case of frequency change */ + uint8_t ddr_speed; +}; + +/* Boot mode defined as bit mask (1<<n) */ +enum { + BM_UNKNOWN, + BM_COLD = 1, /* full training */ + BM_FAST = 2, /* restore timing parameters */ + BM_S3 = 4, /* resume from S3 */ + BM_WARM = 8 +}; + +/* MRC execution status */ +#define MRC_SUCCESS 0 /* initialization ok */ +#define MRC_E_MEMTEST 1 /* memtest failed */ + +/* + * Memory Reference Code parameters + * + * It includes 3 parts: + * - input parameters like boot mode and DRAM parameters + * - context parameters for MRC internal state + * - output parameters like initialization result and memory size + */ +struct mrc_params { + /* Input parameters */ + uint32_t boot_mode; /* BM_COLD, BM_FAST, BM_WARM, BM_S3 */ + /* DRAM parameters */ + uint8_t dram_width; /* x8, x16 */ + uint8_t ddr_speed; /* DDRFREQ_800, DDRFREQ_1066 */ + uint8_t ddr_type; /* DDR3, DDR3L */ + uint8_t ecc_enables; /* 0, 1 (memory size reduced to 7/8) */ + uint8_t scrambling_enables; /* 0, 1 */ + /* 1, 3 (1'st rank has to be populated if 2'nd rank present) */ + uint32_t rank_enables; + uint32_t channel_enables; /* 1 only */ + uint32_t channel_width; /* x16 only */ + /* 0, 1, 2 (mode 2 forced if ecc enabled) */ + uint32_t address_mode; + /* REFRESH_RATE: 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED */ + uint8_t refresh_rate; + /* SR_TEMP_RANGE: 0=normal, 1=extended, others=RESERVED */ + uint8_t sr_temp_range; + /* + * RON_VALUE: 0=34ohm, 1=40ohm, others=RESERVED + * (select MRS1.DIC driver impedance control) + */ + uint8_t ron_value; + /* RTT_NOM_VALUE: 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED */ + uint8_t rtt_nom_value; + /* RD_ODT_VALUE: 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED */ + uint8_t rd_odt_value; + struct dram_params params; + /* Internally used context parameters */ + uint32_t board_id; /* board layout (use x8 or x16 memory) */ + uint32_t hte_setup; /* when set hte reconfiguration requested */ + uint32_t menu_after_mrc; + uint32_t power_down_disable; + uint32_t tune_rcvn; + uint32_t channel_size[NUM_CHANNELS]; + uint32_t column_bits[NUM_CHANNELS]; + uint32_t row_bits[NUM_CHANNELS]; + uint32_t mrs1; /* register content saved during training */ + uint8_t first_run; + /* Output parameters */ + /* initialization result (non zero specifies error code) */ + uint32_t status; + /* total memory size in bytes (excludes ECC banks) */ + uint32_t mem_size; + /* training results (also used on input) */ + struct mrc_timings timings; +}; + +/* + * MRC memory initialization structure + * + * post_code: a 16-bit post code of a specific initialization routine + * boot_path: bitwise or of BM_COLD, BM_FAST, BM_WARM and BM_S3 + * init_fn: real memory initialization routine + */ +struct mem_init { + uint16_t post_code; + uint16_t boot_path; + void (*init_fn)(struct mrc_params *mrc_params); +}; + +/* MRC platform data flags */ +#define MRC_FLAG_ECC_EN 0x00000001 +#define MRC_FLAG_SCRAMBLE_EN 0x00000002 +#define MRC_FLAG_MEMTEST_EN 0x00000004 +/* 0b DDR "fly-by" topology else 1b DDR "tree" topology */ +#define MRC_FLAG_TOP_TREE_EN 0x00000008 +/* If set ODR signal is asserted to DRAM devices on writes */ +#define MRC_FLAG_WR_ODT_EN 0x00000010 + +/** + * mrc_init - Memory Reference Code initialization entry routine + * + * @mrc_params: parameters for MRC + */ +void mrc_init(struct mrc_params *mrc_params); + +#endif /* _MRC_H_ */ diff --git a/arch/x86/include/asm/arch-quark/msg_port.h b/arch/x86/include/asm/arch-quark/msg_port.h new file mode 100644 index 0000000..9527fda --- /dev/null +++ b/arch/x86/include/asm/arch-quark/msg_port.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUARK_MSG_PORT_H_ +#define _QUARK_MSG_PORT_H_ + +/* + * In the Quark SoC, some chipset commands are accomplished by utilizing + * the internal message network within the host bridge (D0:F0). Accesses + * to this network are accomplished by populating the message control + * register (MCR), Message Control Register eXtension (MCRX) and the + * message data register (MDR). + */ +#define MSG_CTRL_REG 0xd0 /* Message Control Register */ +#define MSG_DATA_REG 0xd4 /* Message Data Register */ +#define MSG_CTRL_EXT_REG 0xd8 /* Message Control Register EXT */ + +/* Normal Read/Write OpCodes */ +#define MSG_OP_READ 0x10 +#define MSG_OP_WRITE 0x11 + +/* Alternative Read/Write OpCodes */ +#define MSG_OP_ALT_READ 0x06 +#define MSG_OP_ALT_WRITE 0x07 + +/* IO Read/Write OpCodes */ +#define MSG_OP_IO_READ 0x02 +#define MSG_OP_IO_WRITE 0x03 + +/* All byte enables */ +#define MSG_BYTE_ENABLE 0xf0 + +#ifndef __ASSEMBLY__ + +/** + * msg_port_setup - set up the message port control register + * + * @op: message bus access opcode + * @port: port number on the message bus + * @reg: register number within a port + */ +void msg_port_setup(int op, int port, int reg); + +/** + * msg_port_read - read a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_read(u8 port, u32 reg); + +/** + * msg_port_write - write a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_alt_read - read a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_alt_read(u8 port, u32 reg); + +/** + * msg_port_alt_write - write a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_alt_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_io_read - read a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_io_read(u8 port, u32 reg); + +/** + * msg_port_io_write - write a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_io_write(u8 port, u32 reg, u32 value); + +/* clrbits, setbits, clrsetbits macros for message port access */ + +#define msg_port_normal_read msg_port_read +#define msg_port_normal_write msg_port_write + +#define msg_port_generic_clrsetbits(type, port, reg, clr, set) \ + msg_port_##type##_write(port, reg, \ + (msg_port_##type##_read(port, reg) \ + & ~(clr)) | (set)) + +#define msg_port_clrbits(port, reg, clr) \ + msg_port_generic_clrsetbits(normal, port, reg, clr, 0) +#define msg_port_setbits(port, reg, set) \ + msg_port_generic_clrsetbits(normal, port, reg, 0, set) +#define msg_port_clrsetbits(port, reg, clr, set) \ + msg_port_generic_clrsetbits(normal, port, reg, clr, set) + +#define msg_port_alt_clrbits(port, reg, clr) \ + msg_port_generic_clrsetbits(alt, port, reg, clr, 0) +#define msg_port_alt_setbits(port, reg, set) \ + msg_port_generic_clrsetbits(alt, port, reg, 0, set) +#define msg_port_alt_clrsetbits(port, reg, clr, set) \ + msg_port_generic_clrsetbits(alt, port, reg, clr, set) + +#define msg_port_io_clrbits(port, reg, clr) \ + msg_port_generic_clrsetbits(io, port, reg, clr, 0) +#define msg_port_io_setbits(port, reg, set) \ + msg_port_generic_clrsetbits(io, port, reg, 0, set) +#define msg_port_io_clrsetbits(port, reg, clr, set) \ + msg_port_generic_clrsetbits(io, port, reg, clr, set) + +#endif /* __ASSEMBLY__ */ + +#endif /* _QUARK_MSG_PORT_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000..feca198 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUARK_H_ +#define _QUARK_H_ + +/* Message Bus Ports */ +#define MSG_PORT_MEM_ARBITER 0x00 +#define MSG_PORT_HOST_BRIDGE 0x03 +#define MSG_PORT_RMU 0x04 +#define MSG_PORT_MEM_MGR 0x05 +#define MSG_PORT_USB_AFE 0x14 +#define MSG_PORT_PCIE_AFE 0x16 +#define MSG_PORT_SOC_UNIT 0x31 + +/* Port 0x00: Memory Arbiter Message Port Registers */ + +/* Enhanced Configuration Space */ +#define AEC_CTRL 0x00 + +/* Port 0x03: Host Bridge Message Port Registers */ + +/* Host Miscellaneous Controls 2 */ +#define HMISC2 0x03 + +#define HMISC2_SEGE 0x00000002 +#define HMISC2_SEGF 0x00000004 +#define HMISC2_SEGAB 0x00000010 + +/* Host Memory I/O Boundary */ +#define HM_BOUND 0x08 +#define HM_BOUND_LOCK 0x00000001 + +/* Extended Configuration Space */ +#define HEC_REG 0x09 + +/* MTRR Registers */ +#define MTRR_CAP 0x40 +#define MTRR_DEF_TYPE 0x41 + +#define MTRR_FIX_64K_00000 0x42 +#define MTRR_FIX_64K_40000 0x43 +#define MTRR_FIX_16K_80000 0x44 +#define MTRR_FIX_16K_90000 0x45 +#define MTRR_FIX_16K_A0000 0x46 +#define MTRR_FIX_16K_B0000 0x47 +#define MTRR_FIX_4K_C0000 0x48 +#define MTRR_FIX_4K_C4000 0x49 +#define MTRR_FIX_4K_C8000 0x4a +#define MTRR_FIX_4K_CC000 0x4b +#define MTRR_FIX_4K_D0000 0x4c +#define MTRR_FIX_4K_D4000 0x4d +#define MTRR_FIX_4K_D8000 0x4e +#define MTRR_FIX_4K_DC000 0x4f +#define MTRR_FIX_4K_E0000 0x50 +#define MTRR_FIX_4K_E4000 0x51 +#define MTRR_FIX_4K_E8000 0x52 +#define MTRR_FIX_4K_EC000 0x53 +#define MTRR_FIX_4K_F0000 0x54 +#define MTRR_FIX_4K_F4000 0x55 +#define MTRR_FIX_4K_F8000 0x56 +#define MTRR_FIX_4K_FC000 0x57 + +#define MTRR_SMRR_PHYBASE 0x58 +#define MTRR_SMRR_PHYMASK 0x59 + +#define MTRR_VAR_PHYBASE(n) (0x5a + 2 * (n)) +#define MTRR_VAR_PHYMASK(n) (0x5b + 2 * (n)) + +#ifndef __ASSEMBLY__ + +/* variable range MTRR usage */ +enum { + MTRR_VAR_ROM, + MTRR_VAR_ESRAM, + MTRR_VAR_RAM +}; + +#endif /* __ASSEMBLY__ */ + +/* Port 0x04: Remote Management Unit Message Port Registers */ + +/* ACPI PBLK Base Address Register */ +#define PBLK_BA 0x70 + +/* Control Register */ +#define RMU_CTRL 0x71 + +/* SPI DMA Base Address Register */ +#define SPI_DMA_BA 0x7a + +/* Thermal Sensor Register */ +#define TS_MODE 0xb0 +#define TS_TEMP 0xb1 +#define TS_TRIP 0xb2 + +/* Port 0x05: Memory Manager Message Port Registers */ + +/* eSRAM Block Page Control */ +#define ESRAM_BLK_CTRL 0x82 +#define ESRAM_BLOCK_MODE 0x10000000 + +/* Port 0x14: USB2 AFE Unit Port Registers */ + +#define USB2_GLOBAL_PORT 0x4001 +#define USB2_PLL1 0x7f02 +#define USB2_PLL2 0x7f03 +#define USB2_COMPBG 0x7f04 + +/* Port 0x16: PCIe AFE Unit Port Registers */ + +#define PCIE_RXPICTRL0_L0 0x2080 +#define PCIE_RXPICTRL0_L1 0x2180 + +/* Port 0x31: SoC Unit Port Registers */ + +/* Thermal Sensor Config */ +#define TS_CFG1 0x31 +#define TS_CFG2 0x32 +#define TS_CFG3 0x33 +#define TS_CFG4 0x34 + +/* PCIe Controller Config */ +#define PCIE_CFG 0x36 +#define PCIE_CTLR_PRI_RST 0x00010000 +#define PCIE_PHY_SB_RST 0x00020000 +#define PCIE_CTLR_SB_RST 0x00040000 +#define PCIE_PHY_LANE_RST 0x00090000 +#define PCIE_CTLR_MAIN_RST 0x00100000 + +/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000 + +/* eSRAM */ +#define ESRAM_SIZE 0x80000 + +/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001 + +/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000 + +/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000 + +/* PCIe Root Port Configuration Registers */ + +#define PCIE_RP_CCFG 0xd0 +#define CCFG_UPRS (1 << 14) +#define CCFG_UNRS (1 << 15) +#define CCFG_UNSD (1 << 23) +#define CCFG_UPSD (1 << 24) + +#define PCIE_RP_MPC2 0xd4 +#define MPC2_IPF (1 << 11) + +#define PCIE_RP_MBC 0xf4 +#define MBC_SBIC (3 << 16) + +/* Legacy Bridge PCI Configuration Registers */ +#define LB_GBA 0x44 +#define LB_PM1BLK 0x48 +#define LB_GPE0BLK 0x4c +#define LB_ACTL 0x58 +#define LB_PABCDRC 0x60 +#define LB_PEFGHRC 0x64 +#define LB_WDTBA 0x84 +#define LB_BCE 0xd4 +#define LB_BC 0xd8 +#define LB_RCBA 0xf0 + +/* USB EHCI memory-mapped registers */ +#define EHCI_INSNREG01 0x94 + +/* USB device memory-mapped registers */ +#define USBD_INT_MASK 0x410 +#define USBD_EP_INT_STS 0x414 +#define USBD_EP_INT_MASK 0x418 + +#ifndef __ASSEMBLY__ + +/* Root Complex Register Block */ +struct quark_rcba { + u32 rctl; + u32 esd; + u32 rsvd1[3150]; + u16 rmu_ir; + u16 d23_ir; + u16 core_ir; + u16 d20d21_ir; +}; + +#include <asm/io.h> +#include <asm/pci.h> + +/** + * qrk_pci_read_config_dword() - Read a configuration value + * + * @dev: PCI device address: bus, device and function + * @offset: Dword offset within the device's configuration space + * @valuep: Place to put the returned value + * + * Note: This routine is inlined to provide better performance on Quark + */ +static inline void qrk_pci_read_config_dword(pci_dev_t dev, int offset, + u32 *valuep) +{ + outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR); + *valuep = inl(PCI_REG_DATA); +} + +/** + * qrk_pci_write_config_dword() - Write a PCI configuration value + * + * @dev: PCI device address: bus, device and function + * @offset: Dword offset within the device's configuration space + * @value: Value to write + * + * Note: This routine is inlined to provide better performance on Quark + */ +static inline void qrk_pci_write_config_dword(pci_dev_t dev, int offset, + u32 value) +{ + outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR); + outl(value, PCI_REG_DATA); +} + +/** + * board_assert_perst() - Assert the PERST# pin + * + * The CPU interface to the PERST# signal on Quark is platform dependent. + * Board-specific codes need supply this routine to assert PCIe slot reset. + * + * The tricky part in this routine is that any APIs that may trigger PCI + * enumeration process are strictly forbidden, as any access to PCIe root + * port's configuration registers will cause system hang while it is held + * in reset. + */ +void board_assert_perst(void); + +/** + * board_deassert_perst() - De-assert the PERST# pin + * + * The CPU interface to the PERST# signal on Quark is platform dependent. + * Board-specific codes need supply this routine to de-assert PCIe slot reset. + * + * The tricky part in this routine is that any APIs that may trigger PCI + * enumeration process are strictly forbidden, as any access to PCIe root + * port's configuration registers will cause system hang while it is held + * in reset. + */ +void board_deassert_perst(void); + +#endif /* __ASSEMBLY__ */ + +#endif /* _QUARK_H_ */ diff --git a/arch/x86/include/asm/arch-queensbay/device.h b/arch/x86/include/asm/arch-queensbay/device.h new file mode 100644 index 0000000..15857bf --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/device.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _QUEENSBAY_DEVICE_H_ +#define _QUEENSBAY_DEVICE_H_ + +#include <pci.h> + +/* TunnelCreek PCI Devices */ +#define TNC_HOST_BRIDGE_DEV 0 +#define TNC_HOST_BRIDGE_FUNC 0 +#define TNC_IGD_DEV 2 +#define TNC_IGD_FUNC 0 +#define TNC_SDVO_DEV 3 +#define TNC_SDVO_FUNC 0 +#define TNC_PCIE0_DEV 23 +#define TNC_PCIE0_FUNC 0 +#define TNC_PCIE1_DEV 24 +#define TNC_PCIE1_FUNC 0 +#define TNC_PCIE2_DEV 25 +#define TNC_PCIE2_FUNC 0 +#define TNC_PCIE3_DEV 26 +#define TNC_PCIE3_FUNC 0 +#define TNC_HDA_DEV 27 +#define TNC_HDA_FUNC 0 +#define TNC_LPC_DEV 31 +#define TNC_LPC_FUNC 0 + +#define TNC_HOST_BRIDGE \ + PCI_BDF(0, TNC_HOST_BRIDGE_DEV, TNC_HOST_BRIDGE_FUNC) +#define TNC_IGD \ + PCI_BDF(0, TNC_IGD_DEV, TNC_IGD_FUNC) +#define TNC_SDVO \ + PCI_BDF(0, TNC_SDVO_DEV, TNC_SDVO_FUNC) +#define TNC_PCIE0 \ + PCI_BDF(0, TNC_PCIE0_DEV, TNC_PCIE0_FUNC) +#define TNC_PCIE1 \ + PCI_BDF(0, TNC_PCIE1_DEV, TNC_PCIE1_FUNC) +#define TNC_PCIE2 \ + PCI_BDF(0, TNC_PCIE2_DEV, TNC_PCIE2_FUNC) +#define TNC_PCIE3 \ + PCI_BDF(0, TNC_PCIE3_DEV, TNC_PCIE3_FUNC) +#define TNC_HDA \ + PCI_BDF(0, TNC_HDA_DEV, TNC_HDA_FUNC) +#define TNC_LPC \ + PCI_BDF(0, TNC_LPC_DEV, TNC_LPC_FUNC) + +/* Topcliff IOH PCI Devices */ +#define TCF_PCIE_PORT_DEV 0 +#define TCF_PCIE_PORT_FUNC 0 + +#define TCF_DEV_0 0 +#define TCF_PKT_HUB_FUNC 0 +#define TCF_GBE_FUNC 1 +#define TCF_GPIO_FUNC 2 + +#define TCF_DEV_2 2 +#define TCF_USB1_OHCI0_FUNC 0 +#define TCF_USB1_OHCI1_FUNC 1 +#define TCF_USB1_OHCI2_FUNC 2 +#define TCF_USB1_EHCI_FUNC 3 +#define TCF_USB_DEVICE_FUNC 4 + +#define TCF_DEV_4 4 +#define TCF_SDIO0_FUNC 0 +#define TCF_SDIO1_FUNC 1 + +#define TCF_DEV_6 6 +#define TCF_SATA_FUNC 0 + +#define TCF_DEV_8 8 +#define TCF_USB2_OHCI0_FUNC 0 +#define TCF_USB2_OHCI1_FUNC 1 +#define TCF_USB2_OHCI2_FUNC 2 +#define TCF_USB2_EHCI_FUNC 3 + +#define TCF_DEV_10 10 +#define TCF_DMA1_FUNC 0 +#define TCF_UART0_FUNC 1 +#define TCF_UART1_FUNC 2 +#define TCF_UART2_FUNC 3 +#define TCF_UART3_FUNC 4 + +#define TCF_DEV_12 12 +#define TCF_DMA2_FUNC 0 +#define TCF_SPI_FUNC 1 +#define TCF_I2C_FUNC 2 +#define TCF_CAN_FUNC 3 +#define TCF_1588_FUNC 4 + +#endif /* _QUEENSBAY_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_configs.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_configs.h new file mode 100644 index 0000000..979121c --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_configs.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_CONFIGS_H__ +#define __FSP_CONFIGS_H__ + +struct fsp_config_data { + struct fsp_cfg_common common; + struct upd_region fsp_upd; +}; + +struct fspinit_rtbuf { + struct common_buf common; /* FSP common runtime data structure */ +}; + +#endif /* __FSP_CONFIGS_H__ */ diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h new file mode 100644 index 0000000..7572fc7 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + * + * This file is automatically generated. Please do NOT modify !!! + */ + +#ifndef __VPDHEADER_H__ +#define __VPDHEADER_H__ + +struct __packed upd_region { + u64 sign; /* Offset 0x0000 */ + u64 reserved; /* Offset 0x0008 */ + u8 dummy[240]; /* Offset 0x0010 */ + u8 hda_verb_header[12]; /* Offset 0x0100 */ + u32 hda_verb_length; /* Offset 0x010C */ + u8 hda_verb_data0[16]; /* Offset 0x0110 */ + u8 hda_verb_data1[16]; /* Offset 0x0120 */ + u8 hda_verb_data2[16]; /* Offset 0x0130 */ + u8 hda_verb_data3[16]; /* Offset 0x0140 */ + u8 hda_verb_data4[16]; /* Offset 0x0150 */ + u8 hda_verb_data5[16]; /* Offset 0x0160 */ + u8 hda_verb_data6[16]; /* Offset 0x0170 */ + u8 hda_verb_data7[16]; /* Offset 0x0180 */ + u8 hda_verb_data8[16]; /* Offset 0x0190 */ + u8 hda_verb_data9[16]; /* Offset 0x01A0 */ + u8 hda_verb_data10[16]; /* Offset 0x01B0 */ + u8 hda_verb_data11[16]; /* Offset 0x01C0 */ + u8 hda_verb_data12[16]; /* Offset 0x01D0 */ + u8 hda_verb_data13[16]; /* Offset 0x01E0 */ + u8 hda_verb_pad[47]; /* Offset 0x01F0 */ + u16 terminator; /* Offset 0x021F */ +}; + +#define VPD_IMAGE_ID 0x445056574F4E4E4D /* 'MNNOWVPD' */ + +struct __packed vpd_region { + u64 sign; /* Offset 0x0000 */ + u32 img_rev; /* Offset 0x0008 */ + u32 upd_offset; /* Offset 0x000C */ + u8 unused[16]; /* Offset 0x0010 */ + u32 fsp_res_memlen; /* Offset 0x0020 */ + u8 disable_pcie1; /* Offset 0x0024 */ + u8 disable_pcie2; /* Offset 0x0025 */ + u8 disable_pcie3; /* Offset 0x0026 */ + u8 enable_azalia; /* Offset 0x0027 */ + u8 legacy_seg_decode; /* Offset 0x0028 */ + u8 pcie_port_ioh; /* Offset 0x0029 */ +}; + +#endif diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h new file mode 100644 index 0000000..8d15150 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _X86_ARCH_TNC_H_ +#define _X86_ARCH_TNC_H_ + +/* IGD Function Disable Register */ +#define IGD_FD 0xc4 +#define FUNC_DISABLE 0x00000001 + +/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001 + +/* LPC PCI Configuration Registers */ +#define LPC_RCBA 0xf0 + +/* Root Complex Register Block */ +struct tnc_rcba { + u32 rctl; + u32 esd; + u32 rsvd1[2]; + u32 hdd; + u32 rsvd2; + u32 hdba; + u32 rsvd3[3129]; + u32 d31ip; + u32 rsvd4[3]; + u32 d27ip; + u32 rsvd5; + u32 d02ip; + u32 rsvd6; + u32 d26ip; + u32 d25ip; + u32 d24ip; + u32 d23ip; + u32 d03ip; + u32 rsvd7[3]; + u16 d31ir; + u16 rsvd8[3]; + u16 d27ir; + u16 d26ir; + u16 d25ir; + u16 d24ir; + u16 d23ir; + u16 rsvd9[7]; + u16 d02ir; + u16 d03ir; +}; + +#endif /* _X86_ARCH_TNC_H_ */ diff --git a/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h b/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h new file mode 100644 index 0000000..05dd1b2 --- /dev/null +++ b/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#ifndef __SLIMBOOTLOADER_ARCH_H__ +#define __SLIMBOOTLOADER_ARCH_H__ + +#include <common.h> +#include <asm/hob.h> + +/** + * A GUID to get MemoryMap info hob which is provided by Slim Bootloader + */ +#define SBL_MEMORY_MAP_INFO_GUID \ + EFI_GUID(0xa1ff7424, 0x7a1a, 0x478e, \ + 0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32) + +/** + * A GUID to get SerialPort info hob which is provided by Slim Bootloader + */ +#define SBL_SERIAL_PORT_INFO_GUID \ + EFI_GUID(0x6c6872fe, 0x56a9, 0x4403, \ + 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1) + +/** + * A GUID to get boot performance info hob which is provided by Slim Bootloader + */ +#define SBL_PERFORMANCE_INFO_GUID \ + EFI_GUID(0x868204be, 0x23d0, 0x4ff9, \ + 0xac, 0x34, 0xb9, 0x95, 0xac, 0x04, 0xb1, 0xb9) + +/** + * A single entry of memory map information + * + * @addr: start address of a memory map entry + * @size: size of a memory map entry + * @type: usable:1, reserved:2, acpi:3, nvs:4, unusable:5 + * @flag: only used in Slim Bootloader + * @rsvd: padding for alignment + */ +struct sbl_memory_map_entry { + u64 addr; + u64 size; + u8 type; + u8 flag; + u8 rsvd[6]; +}; + +/** + * This includes all memory map entries which is sorted based on physical start + * address, from low to high, and carved out reserved, acpi nvs, acpi reclaim + * and usable memory. + * + * @rev : revision of memory_map_info structure. currently 1. + * @rsvd : padding for alignment + * @count: the number of memory map entries + * @entry: array of all memory map entries + */ +struct sbl_memory_map_info { + u8 rev; + u8 rsvd[3]; + u32 count; + struct sbl_memory_map_entry entry[0]; +}; + +/** + * This includes serial port info which has already been initialized in previous + * Slim Bootloader stage. + * The Slim Bootloader initializes serial port regardless of debug/release build + * modes, and it passes the information to a payload thru hob. So, a payload can + * re-use the serial information without re-initializing serial port. + * + * @rev : revision of serial_port_info structure. currently 1. + * @rsvd : padding for alignment + * @type : port io: 1, mmio: 2 + * @base : io base address. ex) 0x3f8, 0x80001000 + * @baud : uart baud rate + * @stride: register stride in Bytes + * @clk : uart frequency in Hz + * @rsvd1 : reserved + */ +struct sbl_serial_port_info { + u8 rev; + u8 rsvd[3]; + u32 type; + u32 base; + u32 baud; + u32 stride; + u32 clk; + u32 rsvd1; +}; + +/** + * This includes timestamp data which has been collected in Slim Bootloader + * stages from the reset vector. In addition, this has TSC frequency in KHz to + * calculate each timestamp. + * + * @rev : revision of performance_info structure. currently 1. + * @rsvd : padding for alignment + * @count : the number of collected timestamp data + * @flags : only used in Slim Bootloader + * @frequency: tsc frequency in KHz + * @timestamp: the array of timestamp data which has 64-bit tsc value + */ +struct sbl_performance_info { + u8 rev; + u8 rsvd[3]; + u16 count; + u16 flags; + u32 frequency; + u64 timestamp[0]; +}; + +#endif /* __SLIMBOOTLOADER_ARCH_H__ */ diff --git a/arch/x86/include/asm/arch-tangier/acpi/global_nvs.asl b/arch/x86/include/asm/arch-tangier/acpi/global_nvs.asl new file mode 100644 index 0000000..895b807 --- /dev/null +++ b/arch/x86/include/asm/arch-tangier/acpi/global_nvs.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + * + * Partially based on global_nvs.asl for other x86 platforms + */ + +#include <asm/acpi/global_nvs.h> + +OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE) +Field(GNVS, ByteAcc, NoLock, Preserve) +{ + PCNT, 8, /* processor count */ +} diff --git a/arch/x86/include/asm/arch-tangier/acpi/platform.asl b/arch/x86/include/asm/arch-tangier/acpi/platform.asl new file mode 100644 index 0000000..cf75ca7 --- /dev/null +++ b/arch/x86/include/asm/arch-tangier/acpi/platform.asl @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + * + * Partially based on platform.asl for other x86 platforms + */ + +#include <asm/acpi/statdef.asl> +#include <asm/arch/iomap.h> + +/* + * The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0. + */ +Method(_PTS, 1) +{ +} + +/* The _WAK method is called on system wakeup */ +Method(_WAK, 1) +{ + Return (Package() { Zero, Zero }) +} + +Scope (_SB) +{ + /* Real Time Clock */ + Device (RTC0) + { + Name (_HID, EisaId ("PNP0B00")) + Name (_CRS, ResourceTemplate() + { + IO(Decode16, 0x70, 0x70, 0x01, 0x08) + }) + } +} + +/* ACPI global NVS */ +#include "global_nvs.asl" + +Scope (\_SB) +{ + #include "southcluster.asl" +} diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl new file mode 100644 index 0000000..c622783 --- /dev/null +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -0,0 +1,491 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + * + * Partially based on southcluster.asl for other x86 platforms + */ + +Device (PCI0) +{ + Name (_HID, EISAID("PNP0A08")) /* PCIe */ + Name (_CID, EISAID("PNP0A03")) /* PCI */ + + Name (_ADR, Zero) + Name (_BBN, Zero) + + Name (MCRS, ResourceTemplate() + { + /* Bus Numbers */ + WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100, , , PB00) + + /* IO Region 0 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8, , , PI00) + + /* PCI Config Space */ + IO(Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008) + + /* IO Region 1 */ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300, , , PI01) + + /* GPIO Low Memory Region */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000ddcc0, 0x000ddccf, 0x00000000, + 0x00000010, , , GP00) + + /* PSH Memory Region 0 */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x04819000, 0x04898fff, 0x00000000, + 0x00080000, , , PSH0) + + /* PSH Memory Region 1 */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x04919000, 0x04920fff, 0x00000000, + 0x00008000, , , PSH1) + + /* SST Memory Region */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x05e00000, 0x05ffffff, 0x00000000, + 0x00200000, , , SST0) + + /* PCI Memory Region */ + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x80000000, 0xffffffff, 0x00000000, + 0x80000000, , , PMEM) + }) + + Method (_CRS, 0, Serialized) + { + Return (MCRS) + } + + /* Device Resource Consumption */ + Device (PDRC) + { + Name (_HID, EISAID("PNP0C02")) + Name (_UID, One) + + Name (PDRS, ResourceTemplate() + { + Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE) + }) + + Method (_CRS, 0, Serialized) + { + Return (PDRS) + } + } + + Method (_OSC, 4) + { + /* Check for proper GUID */ + If (LEqual(Arg0, ToUUID("33db4d5b-1ff7-401c-9657-7441c03dd766"))) { + /* Let OS control everything */ + Return (Arg3) + } Else { + /* Unrecognized UUID */ + CreateDWordField(Arg3, 0, CDW1) + Or(CDW1, 4, CDW1) + Return (Arg3) + } + } + + Device (SDHC) + { + Name (_ADR, 0x00010003) + Name (_DEP, Package (0x01) + { + GPIO + }) + Name (PSTS, Zero) + + Method (_STA) + { + Return (STA_VISIBLE) + } + + Method (_PS3, 0, NotSerialized) + { + } + + Method (_PS0, 0, NotSerialized) + { + If (PSTS == Zero) + { + If (^^GPIO.AVBL == One) + { + ^^GPIO.WFD3 = One + PSTS = One + } + } + } + + /* BCM43340 */ + Device (BRC1) + { + Name (_ADR, 0x01) + Name (_DEP, Package (0x01) + { + GPIO + }) + + Method (_STA) + { + Return (STA_VISIBLE) + } + + Method (_RMV, 0, NotSerialized) + { + Return (Zero) + } + + Method (_PS3, 0, NotSerialized) + { + If (^^^GPIO.AVBL == One) + { + ^^^GPIO.WFD3 = Zero + PSTS = Zero + } + } + + Method (_PS0, 0, NotSerialized) + { + If (PSTS == Zero) + { + If (^^^GPIO.AVBL == One) + { + ^^^GPIO.WFD3 = One + PSTS = One + } + } + } + } + + Device (BRC2) + { + Name (_ADR, 0x02) + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Method (_RMV, 0, NotSerialized) + { + Return (Zero) + } + } + } + + Device (SPI5) + { + Name (_ADR, 0x00070001) + Name (RBUF, ResourceTemplate() + { + GpioIo(Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 110 } + GpioIo(Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 111 } + GpioIo(Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 112 } + GpioIo(Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 113 } + + FixedDMA(0x000d, 0x0002, Width32bit, ) + FixedDMA(0x000c, 0x0003, Width32bit, ) + }) + + Method (_CRS, 0, NotSerialized) + { + Return (RBUF) + } + + /* + * See + * http://www.kernel.org/doc/Documentation/acpi/gpio-properties.txt + * for more information about GPIO bindings. + */ + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { + "cs-gpios", Package () { + ^SPI5, 0, 0, 0, + ^SPI5, 1, 0, 0, + ^SPI5, 2, 0, 0, + ^SPI5, 3, 0, 0, + }, + }, + } + }) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + } + + Device (I2C1) + { + Name (_ADR, 0x00080000) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Name (RBUF, ResourceTemplate() + { + FixedDMA(0x0009, 0x0000, Width32bit, ) + FixedDMA(0x0008, 0x0001, Width32bit, ) + }) + + Method (_CRS, 0, NotSerialized) + { + Return (RBUF) + } + } + + Device (I2C6) + { + Name (_ADR, 0x00090001) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + } + + Device (GPIO) + { + Name (_ADR, 0x000c0000) + + Method (_STA) + { + Return (STA_VISIBLE) + } + + Name (AVBL, Zero) + Method (_REG, 2, NotSerialized) + { + If (Arg0 == 0x08) + { + AVBL = Arg1 + } + } + + OperationRegion (GPOP, GeneralPurposeIo, 0, 1) + Field (GPOP, ByteAcc, NoLock, Preserve) + { + Connection ( + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 96 } + ), + WFD3, 1, + } + } + + Device (PWM0) + { + Name (_ADR, 0x00170000) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + } + + Device (HSU0) + { + Name (_ADR, 0x00040001) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Device (BTH0) + { + Name (_HID, "BCM2E95") + Name (_DEP, Package () + { + GPIO, + HSU0 + }) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Method (_CRS, 0, Serialized) + { + Name (RBUF, ResourceTemplate() + { + UartSerialBus(0x0001C200, DataBitsEight, StopBitsOne, + 0xFC, LittleEndian, ParityTypeNone, FlowControlHardware, + 0x20, 0x20, "\\_SB.PCI0.HSU0", 0, ResourceConsumer, , ) + GpioInt(Level, ActiveHigh, Exclusive, PullNone, 0, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 185 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 184 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 71 } + }) + Return (RBUF) + } + + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "host-wakeup-gpios", Package () { ^BTH0, 0, 0, 0 } }, + Package () { "device-wakeup-gpios", Package () { ^BTH0, 1, 0, 0 } }, + Package () { "shutdown-gpios", Package () { ^BTH0, 2, 0, 0 } }, + } + }) + } + } + + Device (IPC1) + { + Name (_ADR, 0x00130000) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Device (PMIC) + { + Name (_ADR, Zero) + Name (_HID, "INTC100E") + Name (_CID, "INTC100E") + Name (_DDN, "Basin Cove PMIC") + Name (_DEP, Package () + { + IPC1 + }) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Method (_CRS, 0, Serialized) + { + Name (RBUF, ResourceTemplate() + { + /* + * Shadow registers in SRAM for PMIC: + * SRAM PMIC register + * -------------------- + * 0x00- Unknown + * 0x03 THRMIRQ (0x04) + * 0x04 BCUIRQ (0x05) + * 0x05 ADCIRQ (0x06) + * 0x06 CHGRIRQ0 (0x07) + * 0x07 CHGRIRQ1 (0x08) + * 0x08- Unknown + * 0x0a PBSTATUS (0x27) + * 0x0b- Unknown + */ + Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 52 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 51 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 50 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 27 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 49 } + }) + Return (RBUF) + } + + OperationRegion (PMOP, 0x8D, Zero, 0x0100) + Field (PMOP, DWordAcc, NoLock, Preserve) + { + SEL1, 32, + SEL2, 32, + VCCL, 32, + VNNL, 32, + AONL, 32, + CNTC, 32, + CNTN, 32, + AONN, 32, + CNT1, 32, + CNT2, 32, + CNT3, 32, + FLEX, 32, + PRG1, 32, + PRG2, 32, + PRG3, 32, + VLDO, 32, + } + + Name (AVBL, Zero) + Method (_REG, 2, NotSerialized) + { + If ((Arg0 == 0x8D)) + { + AVBL = Arg1 + } + } + } + } + + Device (GDMA) + { + Name (_ADR, 0x00150000) + Name (_HID, "808611A2") + Name (_UID, Zero) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Method (_CRS, 0, Serialized) + { + Name (RBUF, ResourceTemplate () + { + Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } + }) + Return (RBUF) + } + } +} + +Device (FLIS) +{ + Name (_HID, "INTC1002") + Name (_DDN, "Intel Merrifield Family-Level Interface Shim") + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0xFF0C0000, 0x00008000) + PinGroup("spi5", ResourceProducer, ) { 90, 91, 92, 93, 94, 95, 96 } + PinGroup("uart0", ResourceProducer, ) { 115, 116, 117, 118 } + PinGroup("uart1", ResourceProducer, ) { 119, 120, 121, 122 } + PinGroup("uart2", ResourceProducer, ) { 123, 124, 125, 126 } + PinGroup("pwm0", ResourceProducer, ) { 144 } + PinGroup("pwm1", ResourceProducer, ) { 145 } + PinGroup("pwm2", ResourceProducer, ) { 132 } + PinGroup("pwm3", ResourceProducer, ) { 133 } + }) + + Method (_CRS, 0, NotSerialized) + { + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } +} diff --git a/arch/x86/include/asm/arch-tangier/global_nvs.h b/arch/x86/include/asm/arch-tangier/global_nvs.h new file mode 100644 index 0000000..a7811a3 --- /dev/null +++ b/arch/x86/include/asm/arch-tangier/global_nvs.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + * + * Partially based on global_nvs.h for other x86 platforms + */ + +#ifndef _GLOBAL_NVS_H_ +#define _GLOBAL_NVS_H_ + +struct __packed acpi_global_nvs { + u8 pcnt; /* processor count */ + + /* + * Add padding so sizeof(struct acpi_global_nvs) == 0x100. + * This must match the size defined in the global_nvs.asl. + */ + u8 rsvd[255]; +}; + +#endif /* _GLOBAL_NVS_H_ */ diff --git a/arch/x86/include/asm/arch-tangier/iomap.h b/arch/x86/include/asm/arch-tangier/iomap.h new file mode 100644 index 0000000..b0fc03e --- /dev/null +++ b/arch/x86/include/asm/arch-tangier/iomap.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2019 Intel Corporation */ + +#ifndef _TANGIER_IOMAP_H +#define _TANGIER_IOMAP_H + +#define MCFG_BASE_ADDRESS 0x3f500000 +#define MCFG_BASE_SIZE 0x00100000 + +#endif /* _TANGIER_IOMAP_H */ diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h new file mode 100644 index 0000000..806f787 --- /dev/null +++ b/arch/x86/include/asm/atomic.h @@ -0,0 +1,115 @@ +#ifndef _ASM_X86_ATOMIC_H +#define _ASM_X86_ATOMIC_H + +#include <linux/compiler.h> +#include <linux/types.h> +#include <asm/processor.h> + +typedef struct { volatile int counter; } atomic_t; + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#define ATOMIC_INIT(i) { (i) } + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. + */ +static inline int atomic_read(const atomic_t *v) +{ + return ACCESS_ONCE((v)->counter); +} + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. + */ +static inline void atomic_set(atomic_t *v, int i) +{ + v->counter = i; +} + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. + */ +static inline void atomic_add(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "addl %1,%0" + : "+m" (v->counter) + : "ir" (i)); +} + +/** + * atomic_sub - subtract integer from atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v. + */ +static inline void atomic_sub(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "subl %1,%0" + : "+m" (v->counter) + : "ir" (i)); +} + +/** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. + */ +static inline void atomic_inc(atomic_t *v) +{ + asm volatile(LOCK_PREFIX "incl %0" + : "+m" (v->counter)); +} + +/** + * atomic_dec - decrement atomic variable + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. + */ +static inline void atomic_dec(atomic_t *v) +{ + asm volatile(LOCK_PREFIX "decl %0" + : "+m" (v->counter)); +} + +/** + * atomic_inc_short - increment of a short integer + * @v: pointer to type int + * + * Atomically adds 1 to @v + * Returns the new value of @u + */ +static inline short int atomic_inc_short(short int *v) +{ + asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v)); + return *v; +} + +/* These are x86-specific, used by some header files */ +#define atomic_clear_mask(mask, addr) \ + asm volatile(LOCK_PREFIX "andl %0,%1" \ + : : "r" (~(mask)), "m" (*(addr)) : "memory") + +#define atomic_set_mask(mask, addr) \ + asm volatile(LOCK_PREFIX "orl %0,%1" \ + : : "r" ((unsigned)(mask)), "m" (*(addr)) \ + : "memory") + +#endif /* _ASM_X86_ATOMIC_H */ diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h new file mode 100644 index 0000000..196fcf9 --- /dev/null +++ b/arch/x86/include/asm/bitops.h @@ -0,0 +1,410 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#include <asm-generic/bitops/fls.h> +#include <asm-generic/bitops/__fls.h> +#include <asm-generic/bitops/fls64.h> + +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +#define ADDR (*(volatile long *) addr) + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +#define PLATFORM__SET_BIT + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its new value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile void * addr); +#endif + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#ifdef __KERNEL__ + +/** + * __ffs - find first set bit in word + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static inline unsigned long __ffs(unsigned long word) +{ + __asm__("rep; bsf %1,%0" + : "=r" (word) + : "rm" (word)); + return word; +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "rm" (x)); + + return r+1; +} +#define PLATFORM_FFS + +static inline int __ilog2(unsigned int x) +{ + return generic_fls(x) - 1; +} + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +#define ext2_set_bit __test_and_set_bit +#define ext2_clear_bit __test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) __set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _I386_BITOPS_H */ diff --git a/arch/x86/include/asm/bootm.h b/arch/x86/include/asm/bootm.h new file mode 100644 index 0000000..bd8ce55 --- /dev/null +++ b/arch/x86/include/asm/bootm.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013, Google Inc. + */ + +#ifndef ARM_BOOTM_H +#define ARM_BOOTM_H + +void bootm_announce_and_cleanup(void); + +/** + * boot_linux_kernel() - boot a linux kernel + * + * This boots a kernel image, either 32-bit or 64-bit. It will also work with + * a self-extracting kernel, if you set @image_64bit to false. + * + * @setup_base: Pointer to the setup.bin information for the kernel + * @load_address: Pointer to the start of the kernel image + * @image_64bit: true if the image is a raw 64-bit kernel, false if it + * is raw 32-bit or any type of self-extracting kernel + * such as a bzImage. + * @return -ve error code. This function does not return if the kernel was + * booted successfully. + */ +int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit); + +#endif diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h new file mode 100644 index 0000000..d961ddd --- /dev/null +++ b/arch/x86/include/asm/bootparam.h @@ -0,0 +1,128 @@ +#ifndef _ASM_X86_BOOTPARAM_H +#define _ASM_X86_BOOTPARAM_H + +#include <linux/types.h> +#include <linux/screen_info.h> +#include <linux/apm_bios.h> +#include <linux/edd.h> +#include <asm/e820.h> +#include <asm/ist.h> +#include <asm/video/edid.h> + +/* setup data types */ +enum { + SETUP_NONE = 0, + SETUP_E820_EXT, + SETUP_DTB, +}; + +/* extensible setup data list node */ +struct setup_data { + __u64 next; + __u32 type; + __u32 len; + __u8 data[0]; +}; + +struct setup_header { + __u8 setup_sects; + __u16 root_flags; + __u32 syssize; + __u16 ram_size; +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + __u16 vid_mode; + __u16 root_dev; + __u16 boot_flag; + __u16 jump; + __u32 header; + __u16 version; + __u32 realmode_swtch; + __u16 start_sys; + __u16 kernel_version; + __u8 type_of_loader; + __u8 loadflags; +#define LOADED_HIGH (1<<0) +#define QUIET_FLAG (1<<5) +#define KEEP_SEGMENTS (1<<6) +#define CAN_USE_HEAP (1<<7) + __u16 setup_move_size; + __u32 code32_start; + __u32 ramdisk_image; + __u32 ramdisk_size; + __u32 bootsect_kludge; + __u16 heap_end_ptr; + __u8 ext_loader_ver; + __u8 ext_loader_type; + __u32 cmd_line_ptr; + __u32 initrd_addr_max; + __u32 kernel_alignment; + __u8 relocatable_kernel; + __u8 _pad2[3]; + __u32 cmdline_size; + __u32 hardware_subarch; + __u64 hardware_subarch_data; + __u32 payload_offset; + __u32 payload_length; + __u64 setup_data; + __u64 pref_address; + __u32 init_size; + __u32 handover_offset; +} __attribute__((packed)); + +struct sys_desc_table { + __u16 length; + __u8 table[14]; +}; + +struct efi_info { + __u32 efi_loader_signature; + __u32 efi_systab; + __u32 efi_memdesc_size; + __u32 efi_memdesc_version; + __u32 efi_memmap; + __u32 efi_memmap_size; + __u32 efi_systab_hi; + __u32 efi_memmap_hi; +}; + +/* The so-called "zeropage" */ +struct boot_params { + struct screen_info screen_info; /* 0x000 */ + struct apm_bios_info apm_bios_info; /* 0x040 */ + __u8 _pad2[4]; /* 0x054 */ + __u64 tboot_addr; /* 0x058 */ + struct ist_info ist_info; /* 0x060 */ + __u64 acpi_rsdp_addr; /* 0x070 */ + __u8 _pad3[8]; /* 0x078 */ + __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */ + __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ + struct sys_desc_table sys_desc_table; /* 0x0a0 */ + __u8 _pad4[144]; /* 0x0b0 */ + struct edid_info edid_info; /* 0x140 */ + struct efi_info efi_info; /* 0x1c0 */ + __u32 alt_mem_k; /* 0x1e0 */ + __u32 scratch; /* Scratch field! */ /* 0x1e4 */ + __u8 e820_entries; /* 0x1e8 */ + __u8 eddbuf_entries; /* 0x1e9 */ + __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ + __u8 _pad6[6]; /* 0x1eb */ + struct setup_header hdr; /* setup header */ /* 0x1f1 */ + __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; + __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ + struct e820_entry e820_map[E820MAX]; /* 0x2d0 */ + __u8 _pad8[48]; /* 0xcd0 */ + struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */ + __u8 _pad9[276]; /* 0xeec */ +} __attribute__((packed)); + +enum { + X86_SUBARCH_PC = 0, + X86_SUBARCH_LGUEST, + X86_SUBARCH_XEN, + X86_SUBARCH_INTEL_MID, + X86_SUBARCH_CE4100, + X86_NR_SUBARCHS, +}; +#endif /* _ASM_X86_BOOTPARAM_H */ diff --git a/arch/x86/include/asm/byteorder.h b/arch/x86/include/asm/byteorder.h new file mode 100644 index 0000000..a2d1fd8 --- /dev/null +++ b/arch/x86/include/asm/byteorder.h @@ -0,0 +1,44 @@ +#ifndef _I386_BYTEORDER_H +#define _I386_BYTEORDER_H + +#include <asm/types.h> + +#ifdef __GNUC__ + + +static __inline__ __u32 ___arch__swab32(__u32 x) +{ + __asm__("bswap %0" : "=r" (x) : "0" (x)); + + return x; +} + +#define _constant_swab16(x) ((__u16)( \ + (((__u16)(x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(x) & (__u16)0xff00U) >> 8))) + +static __inline__ __u16 ___arch__swab16(__u16 x) +{ +#if CONFIG_IS_ENABLED(X86_64) + return _constant_swab16(x); +#else + __asm__("xchgb %b0,%h0" /* swap bytes */ \ + : "=q" (x) \ + : "0" (x)); \ + return x; +#endif +} + +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#endif /* __GNUC__ */ + +#include <linux/byteorder/little_endian.h> + +#endif /* _I386_BYTEORDER_H */ diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h new file mode 100644 index 0000000..145b878 --- /dev/null +++ b/arch/x86/include/asm/cache.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#ifndef __X86_CACHE_H__ +#define __X86_CACHE_H__ + +/* + * If CONFIG_SYS_CACHELINE_SIZE is defined use it for DMA alignment. Otherwise + * use 64-bytes, a safe default for x86. + */ +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 64 +#endif + +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE + +static inline void wbinvd(void) +{ + asm volatile ("wbinvd" : : : "memory"); +} + +static inline void invd(void) +{ + asm volatile("invd" : : : "memory"); +} + +/* Enable caches and write buffer */ +void enable_caches(void); + +/* Disable caches and write buffer */ +void disable_caches(void); + +#endif /* __X86_CACHE_H__ */ diff --git a/arch/x86/include/asm/cmos_layout.h b/arch/x86/include/asm/cmos_layout.h new file mode 100644 index 0000000..e2f6d18 --- /dev/null +++ b/arch/x86/include/asm/cmos_layout.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __CMOS_LAYOUT_H +#define __CMOS_LAYOUT_H + +/* + * The RTC internal registers and RAM is organized as two banks of 128 bytes + * each, called the standard and extended banks. The first 14 bytes of the + * standard bank contain the RTC time and date information along with four + * registers, A - D, that are used for configuration of the RTC. The extended + * bank contains a full 128 bytes of battery backed SRAM. + * + * For simplicity in U-Boot we only support CMOS in the standard bank, and + * its base address starts from offset 0x10, which leaves us 112 bytes space. + */ +#define CMOS_BASE 0x10 + +/* + * The file records all offsets off CMOS_BASE that is currently used by + * U-Boot for various reasons. It is put in such a unified place in order + * to be consistent across platforms. + */ + +/* stack address for S3 boot in a FSP configuration, 4 bytes */ +#define CMOS_FSP_STACK_ADDR CMOS_BASE + +#endif /* __CMOS_LAYOUT_H */ diff --git a/arch/x86/include/asm/config.h b/arch/x86/include/asm/config.h new file mode 100644 index 0000000..7ea4436 --- /dev/null +++ b/arch/x86/include/asm/config.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2009 Freescale Semiconductor, Inc. + */ + +#ifndef _ASM_CONFIG_H_ +#define _ASM_CONFIG_H_ + +#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH + +#endif diff --git a/arch/x86/include/asm/control_regs.h b/arch/x86/include/asm/control_regs.h new file mode 100644 index 0000000..44b8ba2 --- /dev/null +++ b/arch/x86/include/asm/control_regs.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * Portions of this file are derived from the Linux kernel source + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#ifndef __X86_CONTROL_REGS_H +#define __X86_CONTROL_REGS_H + +/* + * The memory clobber prevents the GCC from reordering the read/write order + * of CR0 +*/ +static inline unsigned long read_cr0(void) +{ + unsigned long val; + + asm volatile ("movl %%cr0, %0" : "=r" (val) : : "memory"); + return val; +} + +static inline void write_cr0(unsigned long val) +{ + asm volatile ("movl %0, %%cr0" : : "r" (val) : "memory"); +} + +static inline unsigned long read_cr2(void) +{ + unsigned long val; + + asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long read_cr3(void) +{ + unsigned long val; + + asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long read_cr4(void) +{ + unsigned long val; + + asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("mov %%db0, %0" : "=r" (val)); + break; + case 1: + asm("mov %%db1, %0" : "=r" (val)); + break; + case 2: + asm("mov %%db2, %0" : "=r" (val)); + break; + case 3: + asm("mov %%db3, %0" : "=r" (val)); + break; + case 6: + asm("mov %%db6, %0" : "=r" (val)); + break; + case 7: + asm("mov %%db7, %0" : "=r" (val)); + break; + default: + val = 0; + } + return val; +} + +#endif diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h new file mode 100644 index 0000000..2c54e24 --- /dev/null +++ b/arch/x86/include/asm/coreboot_tables.h @@ -0,0 +1,327 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + */ + +#ifndef _COREBOOT_TABLES_H +#define _COREBOOT_TABLES_H + +struct memory_area; + +struct cbuint64 { + u32 lo; + u32 hi; +}; + +struct cb_header { + u8 signature[4]; + u32 header_bytes; + u32 header_checksum; + u32 table_bytes; + u32 table_checksum; + u32 table_entries; +}; + +struct cb_record { + u32 tag; + u32 size; +}; + +#define CB_TAG_UNUSED 0x0000 +#define CB_TAG_MEMORY 0x0001 + +struct cb_memory_range { + struct cbuint64 start; + struct cbuint64 size; + u32 type; +}; + +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 + +struct cb_memory { + u32 tag; + u32 size; + struct cb_memory_range map[0]; +}; + +#define CB_TAG_HWRPB 0x0002 + +struct cb_hwrpb { + u32 tag; + u32 size; + u64 hwrpb; +}; + +#define CB_TAG_MAINBOARD 0x0003 + +struct cb_mainboard { + u32 tag; + u32 size; + u8 vendor_idx; + u8 part_number_idx; + u8 strings[0]; +}; + +#define CB_TAG_VERSION 0x0004 +#define CB_TAG_EXTRA_VERSION 0x0005 +#define CB_TAG_BUILD 0x0006 +#define CB_TAG_COMPILE_TIME 0x0007 +#define CB_TAG_COMPILE_BY 0x0008 +#define CB_TAG_COMPILE_HOST 0x0009 +#define CB_TAG_COMPILE_DOMAIN 0x000a +#define CB_TAG_COMPILER 0x000b +#define CB_TAG_LINKER 0x000c +#define CB_TAG_ASSEMBLER 0x000d + +struct cb_string { + u32 tag; + u32 size; + u8 string[0]; +}; + +#define CB_TAG_SERIAL 0x000f + +struct cb_serial { + u32 tag; + u32 size; +#define CB_SERIAL_TYPE_IO_MAPPED 1 +#define CB_SERIAL_TYPE_MEMORY_MAPPED 2 + u32 type; + u32 baseaddr; + u32 baud; +}; + +#define CB_TAG_CONSOLE 0x0010 + +struct cb_console { + u32 tag; + u32 size; + u16 type; +}; + +#define CB_TAG_CONSOLE_SERIAL8250 0 +#define CB_TAG_CONSOLE_VGA 1 /* OBSOLETE */ +#define CB_TAG_CONSOLE_BTEXT 2 /* OBSOLETE */ +#define CB_TAG_CONSOLE_LOGBUF 3 +#define CB_TAG_CONSOLE_SROM 4 /* OBSOLETE */ +#define CB_TAG_CONSOLE_EHCI 5 + +#define CB_TAG_FORWARD 0x0011 + +struct cb_forward { + u32 tag; + u32 size; + u64 forward; +}; + +#define CB_TAG_FRAMEBUFFER 0x0012 + +struct cb_framebuffer { + u32 tag; + u32 size; + u64 physical_address; + u32 x_resolution; + u32 y_resolution; + u32 bytes_per_line; + u8 bits_per_pixel; + u8 red_mask_pos; + u8 red_mask_size; + u8 green_mask_pos; + u8 green_mask_size; + u8 blue_mask_pos; + u8 blue_mask_size; + u8 reserved_mask_pos; + u8 reserved_mask_size; +}; + +#define CB_TAG_GPIO 0x0013 +#define GPIO_MAX_NAME_LENGTH 16 + +struct cb_gpio { + u32 port; + u32 polarity; + u32 value; + u8 name[GPIO_MAX_NAME_LENGTH]; +}; + +struct cb_gpios { + u32 tag; + u32 size; + u32 count; + struct cb_gpio gpios[0]; +}; + +#define CB_TAG_FDT 0x0014 + +struct cb_fdt { + uint32_t tag; + uint32_t size; /* size of the entire entry */ + /* the actual FDT gets placed here */ +}; + +#define CB_TAG_VDAT 0x0015 + +struct cb_vdat { + uint32_t tag; + uint32_t size; /* size of the entire entry */ + void *vdat_addr; + uint32_t vdat_size; +}; + +#define CB_TAG_TIMESTAMPS 0x0016 +#define CB_TAG_CBMEM_CONSOLE 0x0017 +#define CB_TAG_MRC_CACHE 0x0018 + +struct cb_cbmem_tab { + uint32_t tag; + uint32_t size; + void *cbmem_tab; +}; + +#define CB_TAG_VBNV 0x0019 + +struct cb_vbnv { + uint32_t tag; + uint32_t size; + uint32_t vbnv_start; + uint32_t vbnv_size; +}; + +#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 + +struct cb_cmos_option_table { + u32 tag; + u32 size; + u32 header_length; +}; + +#define CB_TAG_OPTION 0x00c9 + +#define CMOS_MAX_NAME_LENGTH 32 + +struct cb_cmos_entries { + u32 tag; + u32 size; + u32 bit; + u32 length; + u32 config; + u32 config_id; + u8 name[CMOS_MAX_NAME_LENGTH]; +}; + +#define CB_TAG_OPTION_ENUM 0x00ca +#define CMOS_MAX_TEXT_LENGTH 32 + +struct cb_cmos_enums { + u32 tag; + u32 size; + u32 config_id; + u32 value; + u8 text[CMOS_MAX_TEXT_LENGTH]; +}; + +#define CB_TAG_OPTION_DEFAULTS 0x00cb +#define CMOS_IMAGE_BUFFER_SIZE 128 + +struct cb_cmos_defaults { + u32 tag; + u32 size; + u32 name_length; + u8 name[CMOS_MAX_NAME_LENGTH]; + u8 default_set[CMOS_IMAGE_BUFFER_SIZE]; +}; + +#define CB_TAG_OPTION_CHECKSUM 0x00cc +#define CHECKSUM_NONE 0 +#define CHECKSUM_PCBIOS 1 + +struct cb_cmos_checksum { + u32 tag; + u32 size; + u32 range_start; + u32 range_end; + u32 location; + u32 type; +}; + +/* Helpful macros */ + +#define MEM_RANGE_COUNT(_rec) \ + (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0])) + +#define MEM_RANGE_PTR(_rec, _idx) \ + (((u8 *) (_rec)) + sizeof(*(_rec)) \ + + (sizeof((_rec)->map[0]) * (_idx))) + +#define MB_VENDOR_STRING(_mb) \ + (((unsigned char *) ((_mb)->strings)) + (_mb)->vendor_idx) + +#define MB_PART_STRING(_mb) \ + (((unsigned char *) ((_mb)->strings)) + (_mb)->part_number_idx) + +#define UNPACK_CB64(_in) \ + ((((u64) _in.hi) << 32) | _in.lo) + +#define CBMEM_TOC_RESERVED 512 +#define MAX_CBMEM_ENTRIES 16 +#define CBMEM_MAGIC 0x434f5245 + +struct cbmem_entry { + u32 magic; + u32 id; + u64 base; + u64 size; +} __packed; + +#define CBMEM_ID_FREESPACE 0x46524545 +#define CBMEM_ID_GDT 0x4c474454 +#define CBMEM_ID_ACPI 0x41435049 +#define CBMEM_ID_CBTABLE 0x43425442 +#define CBMEM_ID_PIRQ 0x49525154 +#define CBMEM_ID_MPTABLE 0x534d5054 +#define CBMEM_ID_RESUME 0x5245534d +#define CBMEM_ID_RESUME_SCRATCH 0x52455343 +#define CBMEM_ID_SMBIOS 0x534d4254 +#define CBMEM_ID_TIMESTAMP 0x54494d45 +#define CBMEM_ID_MRCDATA 0x4d524344 +#define CBMEM_ID_CONSOLE 0x434f4e53 +#define CBMEM_ID_NONE 0x00000000 + +/** + * high_table_reserve() - reserve configuration table in high memory + * + * This reserves configuration table in high memory. + * + * @return: always 0 + */ +int high_table_reserve(void); + +/** + * high_table_malloc() - allocate configuration table in high memory + * + * This allocates configuration table in high memory. + * + * @bytes: size of configuration table to be allocated + * @return: pointer to configuration table in high memory + */ +void *high_table_malloc(size_t bytes); + +/** + * write_coreboot_table() - write coreboot table + * + * This writes coreboot table at a given address. + * + * @addr: start address to write coreboot table + * @cfg_tables: pointer to configuration table memory area + */ +void write_coreboot_table(u32 addr, struct memory_area *cfg_tables); + +#endif diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h new file mode 100644 index 0000000..feee0f9 --- /dev/null +++ b/arch/x86/include/asm/cpu.h @@ -0,0 +1,290 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2014 The Chromium OS Authors. + * + * Part of this file is adapted from coreboot + * src/arch/x86/include/arch/cpu.h and + * src/arch/x86/lib/cpu.c + */ + +#ifndef _ASM_CPU_H +#define _ASM_CPU_H + +enum { + X86_VENDOR_INVALID = 0, + X86_VENDOR_INTEL, + X86_VENDOR_CYRIX, + X86_VENDOR_AMD, + X86_VENDOR_UMC, + X86_VENDOR_NEXGEN, + X86_VENDOR_CENTAUR, + X86_VENDOR_RISE, + X86_VENDOR_TRANSMETA, + X86_VENDOR_NSC, + X86_VENDOR_SIS, + X86_VENDOR_ANY = 0xfe, + X86_VENDOR_UNKNOWN = 0xff +}; + +/* Global descriptor table (GDT) bits */ +enum { + GDT_4KB = 1ULL << 55, + GDT_32BIT = 1ULL << 54, + GDT_LONG = 1ULL << 53, + GDT_PRESENT = 1ULL << 47, + GDT_NOTSYS = 1ULL << 44, + GDT_CODE = 1ULL << 43, + GDT_LIMIT_LOW_SHIFT = 0, + GDT_LIMIT_LOW_MASK = 0xffff, + GDT_LIMIT_HIGH_SHIFT = 48, + GDT_LIMIT_HIGH_MASK = 0xf, + GDT_BASE_LOW_SHIFT = 16, + GDT_BASE_LOW_MASK = 0xffff, + GDT_BASE_HIGH_SHIFT = 56, + GDT_BASE_HIGH_MASK = 0xf, +}; + +/* + * System controllers in an x86 system. We mostly need to just find these and + * use them on PCI. At some point these might have their own uclass (e.g. + * UCLASS_VIDEO for the GMA device). + */ +enum { + X86_NONE, + X86_SYSCON_ME, /* Intel Management Engine */ + X86_SYSCON_PINCONF, /* Intel x86 pin configuration */ + X86_SYSCON_PMU, /* Power Management Unit */ + X86_SYSCON_SCU, /* System Controller Unit */ +}; + +struct cpuid_result { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +}; + +/* + * Generic CPUID function + */ +static inline struct cpuid_result cpuid(int op) +{ + struct cpuid_result result; + asm volatile( + "mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (result.eax), + "=S" (result.ebx), + "=c" (result.ecx), + "=d" (result.edx) + : "0" (op) + : "edi"); + return result; +} + +/* + * Generic Extended CPUID function + */ +static inline struct cpuid_result cpuid_ext(int op, unsigned ecx) +{ + struct cpuid_result result; + asm volatile( + "mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (result.eax), + "=S" (result.ebx), + "=c" (result.ecx), + "=d" (result.edx) + : "0" (op), "2" (ecx) + : "edi"); + return result; +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax) + : "0" (op) + : "ecx", "edx", "edi"); + return eax; +} + +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=S" (ebx) + : "0" (op) + : "ecx", "edx", "edi"); + return ebx; +} + +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ecx; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "edx", "edi"); + return ecx; +} + +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, edx; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=d" (edx) + : "0" (op) + : "ecx", "edi"); + return edx; +} + +#if !CONFIG_IS_ENABLED(X86_64) + +/* Standard macro to see if a specific flag is changeable */ +static inline int flag_is_changeable_p(uint32_t flag) +{ + uint32_t f1, f2; + + asm( + "pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl %2,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl\n\t" + : "=&r" (f1), "=&r" (f2) + : "ir" (flag)); + return ((f1^f2) & flag) != 0; +} +#endif + +static inline void mfence(void) +{ + __asm__ __volatile__("mfence" : : : "memory"); +} + +/** + * cpu_enable_paging_pae() - Enable PAE-paging + * + * @cr3: Value to set in cr3 (PDPT or PML4T) + */ +void cpu_enable_paging_pae(ulong cr3); + +/** + * cpu_disable_paging_pae() - Disable paging and PAE + */ +void cpu_disable_paging_pae(void); + +/** + * cpu_has_64bit() - Check if the CPU has 64-bit support + * + * @return 1 if this CPU supports long mode (64-bit), 0 if not + */ +int cpu_has_64bit(void); + +/** + * cpu_vendor_name() - Get CPU vendor name + * + * @vendor: CPU vendor enumeration number + * + * @return: Address to hold the CPU vendor name string + */ +const char *cpu_vendor_name(int vendor); + +#define CPU_MAX_NAME_LEN 49 + +/** + * cpu_get_name() - Get the name of the current cpu + * + * @name: Place to put name, which must be CPU_MAX_NAME_LEN bytes including + * @return pointer to name, which will likely be a few bytes after the start + * of @name + * \0 terminator + */ +char *cpu_get_name(char *name); + +/** + * cpu_call64() - Jump to a 64-bit Linux kernel (internal function) + * + * The kernel is uncompressed and the 64-bit entry point is expected to be + * at @target. + * + * This function is used internally - see cpu_jump_to_64bit() for a more + * useful function. + * + * @pgtable: Address of 24KB area containing the page table + * @setup_base: Pointer to the setup.bin information for the kernel + * @target: Pointer to the start of the kernel image + */ +void cpu_call64(ulong pgtable, ulong setup_base, ulong target); + +/** + * cpu_call32() - Jump to a 32-bit entry point + * + * @code_seg32: 32-bit code segment to use (GDT offset, e.g. 0x20) + * @target: Pointer to the start of the 32-bit U-Boot image/entry point + * @table: Pointer to start of info table to pass to U-Boot + */ +void cpu_call32(ulong code_seg32, ulong target, ulong table); + +/** + * cpu_jump_to_64bit() - Jump to a 64-bit Linux kernel + * + * The kernel is uncompressed and the 64-bit entry point is expected to be + * at @target. + * + * @setup_base: Pointer to the setup.bin information for the kernel + * @target: Pointer to the start of the kernel image + */ +int cpu_jump_to_64bit(ulong setup_base, ulong target); + +/** + * cpu_jump_to_64bit_uboot() - special function to jump from SPL to U-Boot + * + * This handles calling from 32-bit SPL to 64-bit U-Boot. + * + * @target: Address of U-Boot in RAM + */ +int cpu_jump_to_64bit_uboot(ulong target); + +/** + * cpu_get_family_model() - Get the family and model for the CPU + * + * @return the CPU ID masked with 0x0fff0ff0 + */ +u32 cpu_get_family_model(void); + +/** + * cpu_get_stepping() - Get the stepping value for the CPU + * + * @return the CPU ID masked with 0xf + */ +u32 cpu_get_stepping(void); + +#endif diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h new file mode 100644 index 0000000..cdd99a9 --- /dev/null +++ b/arch/x86/include/asm/cpu_common.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Common code for Intel CPUs + * + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ASM_CPU_COMMON_H +#define __ASM_CPU_COMMON_H + +/* Standard Intel bus clock is fixed at 100MHz */ +enum { + INTEL_BCLK_MHZ = 100 +}; + +struct cpu_info; + +/** + * cpu_common_init() - Set up common CPU init + * + * This reports BIST failure, enables the LAPIC, updates microcode, enables + * the upper 128-bytes of CROM RAM, probes the northbridge, PCH, LPC and SATA. + * + * @return 0 if OK, -ve on error + */ +int cpu_common_init(void); + +/** + * cpu_set_flex_ratio_to_tdp_nominal() - Set up the maximum non-turbo rate + * + * If a change is needed, this function will do a soft reset so it takes + * effect. + * + * Some details are available here: + * http://forum.hwbot.org/showthread.php?t=76092 + * + * @return 0 if OK, -ve on error + */ +int cpu_set_flex_ratio_to_tdp_nominal(void); + +/** + * cpu_intel_get_info() - Obtain CPU info for Intel CPUs + * + * Most Intel CPUs use the same MSR to obtain the clock speed, and use the same + * features. This function fills in these values, given the value of the base + * clock in MHz (typically this should be set to 100). + * + * @info: cpu_info struct to fill in + * @bclk_mz: the base clock in MHz + * + * @return 0 always + */ +int cpu_intel_get_info(struct cpu_info *info, int bclk_mz); + +/** + * cpu_configure_thermal_target() - Set the thermal target for a CPU + * + * This looks up the tcc-offset property and uses it to set the + * MSR_TEMPERATURE_TARGET value. + * + * @dev: CPU device + * @return 0 if OK, -ENOENT if no target is given in device tree + */ +int cpu_configure_thermal_target(struct udevice *dev); + +/** + * cpu_set_perf_control() - Set the nominal CPU clock speed + * + * This sets the clock speed as a multiplier of BCLK + * + * @clk_ratio: Ratio to use + */ +void cpu_set_perf_control(uint clk_ratio); + +/** + * cpu_config_tdp_levels() - Check for configurable TDP option + * + * @return true if the CPU has configurable TDP (Thermal-design power) + */ +bool cpu_config_tdp_levels(void); + +/** enum burst_mode_t - Burst-mode states */ +enum burst_mode_t { + BURST_MODE_UNKNOWN, + BURST_MODE_UNAVAILABLE, + BURST_MODE_DISABLED, + BURST_MODE_ENABLED +}; + +/* + * cpu_get_burst_mode_state() - Get the Burst/Turbo Mode State + * + * This reads MSR IA32_MISC_ENABLE 0x1A0 + * Bit 38 - TURBO_MODE_DISABLE Bit to get state ENABLED / DISABLED. + * Also checks cpuid 0x6 to see whether burst mode is supported. + * + * @return current burst mode status + */ +enum burst_mode_t cpu_get_burst_mode_state(void); + +/** + * cpu_set_burst_mode() - Set CPU burst mode + * + * @burst_mode: true to enable burst mode, false to disable + */ +void cpu_set_burst_mode(bool burst_mode); + +/** + * cpu_set_eist() - Enable Enhanced Intel Speed Step Technology + * + * @eist_status: true to enable EIST, false to disable + */ +void cpu_set_eist(bool eist_status); + +/** + * cpu_set_p_state_to_turbo_ratio() - Set turbo ratio + * + * TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the + * factory configured values for of 1-core, 2-core, 3-core + * and 4-core turbo ratio limits for all processors. + * + * 7:0 - MAX_TURBO_1_CORE + * 15:8 - MAX_TURBO_2_CORES + * 23:16 - MAX_TURBO_3_CORES + * 31:24 - MAX_TURBO_4_CORES + * + * Set PERF_CTL MSR (0x199) P_Req with that value. + */ +void cpu_set_p_state_to_turbo_ratio(void); + +#endif diff --git a/arch/x86/include/asm/cpu_x86.h b/arch/x86/include/asm/cpu_x86.h new file mode 100644 index 0000000..19223f2 --- /dev/null +++ b/arch/x86/include/asm/cpu_x86.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ASM_CPU_X86_H +#define _ASM_CPU_X86_H + +/** + * cpu_x86_bind() - Bind an x86 CPU with the driver + * + * This updates cpu device's platform data with information from device tree, + * like the processor local apic id. + * + * @dev: Device to check (UCLASS_CPU) + * @return 0 always + */ +int cpu_x86_bind(struct udevice *dev); + +/** + * cpu_x86_get_desc() - Get a description string for an x86 CPU + * + * This uses cpu_get_name() and is suitable to use as the get_desc() method for + * the CPU uclass. + * + * @dev: Device to check (UCLASS_CPU) + * @buf: Buffer to place string + * @size: Size of string space + * @return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int cpu_x86_get_desc(struct udevice *dev, char *buf, int size); + +/** + * cpu_x86_get_vendor() - Get a vendor string for an x86 CPU + * + * This uses cpu_vendor_name() and is suitable to use as the get_vendor() + * method for the CPU uclass. + * + * @dev: Device to check (UCLASS_CPU) + * @buf: Buffer to place string + * @size: Size of string space + * @return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int cpu_x86_get_vendor(struct udevice *dev, char *buf, int size); + +#endif /* _ASM_CPU_X86_H */ diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h new file mode 100644 index 0000000..b353ff0 --- /dev/null +++ b/arch/x86/include/asm/dma-mapping.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2007 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + */ +#ifndef __ASM_X86_DMA_MAPPING_H +#define __ASM_X86_DMA_MAPPING_H + +#include <linux/dma-direction.h> + +#define dma_mapping_error(x, y) 0 + +static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) +{ + *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len); + return (void *)*handle; +} + +static inline void dma_free_coherent(void *addr) +{ + free(addr); +} + +static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, + enum dma_data_direction dir) +{ + return (unsigned long)vaddr; +} + +static inline void dma_unmap_single(volatile void *vaddr, size_t len, + unsigned long paddr) +{ +} + +#endif /* __ASM_X86_DMA_MAPPING_H */ diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h new file mode 100644 index 0000000..9d29f82 --- /dev/null +++ b/arch/x86/include/asm/e820.h @@ -0,0 +1,30 @@ +#ifndef _ASM_X86_E820_H +#define _ASM_X86_E820_H + +#define E820MAX 128 /* number of entries in E820MAP */ + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + +struct e820_entry { + __u64 addr; /* start of memory segment */ + __u64 size; /* size of memory segment */ + __u32 type; /* type of memory segment */ +} __attribute__((packed)); + +#define ISA_START_ADDRESS 0xa0000 +#define ISA_END_ADDRESS 0x100000 + +#endif /* __ASSEMBLY__ */ + +/* Implementation defined function to install an e820 map */ +unsigned int install_e820_map(unsigned int max_entries, + struct e820_entry *); + +#endif /* _ASM_X86_E820_H */ diff --git a/arch/x86/include/asm/early_cmos.h b/arch/x86/include/asm/early_cmos.h new file mode 100644 index 0000000..543a9e6 --- /dev/null +++ b/arch/x86/include/asm/early_cmos.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __EARLY_CMOS_H +#define __EARLY_CMOS_H + +/* CMOS actually resides in the RTC SRAM */ +#define CMOS_IO_PORT 0x70 + +/** + * cmos_read8() - Get 8-bit data stored at the given address + * + * This reads from CMOS for the 8-bit data stored at the given address. + * + * @addr: RTC SRAM address + * @return: 8-bit data stored at the given address + */ +u8 cmos_read8(u8 addr); + +/** + * cmos_read16() - Get 16-bit data stored at the given address + * + * This reads from CMOS for the 16-bit data stored at the given address. + * + * @addr: RTC SRAM address + * @return: 16-bit data stored at the given address + */ +u16 cmos_read16(u8 addr); + +/** + * cmos_read32() - Get 32-bit data stored at the given address + * + * This reads from CMOS for the 32-bit data stored at the given address. + * + * @addr: RTC SRAM address + * @return: 32-bit data stored at the given address + */ +u32 cmos_read32(u8 addr); + +#endif /* __EARLY_CMOS_H */ diff --git a/arch/x86/include/asm/fsp/fsp_azalia.h b/arch/x86/include/asm/fsp/fsp_azalia.h new file mode 100644 index 0000000..e59180b --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_azalia.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Google, Inc + */ + +#ifndef _FSP_AZALIA_H_ +#define _FSP_AZALIA_H_ + +struct __packed azalia_verb_table_header { + u32 vendor_device_id; + u16 sub_system_id; + u8 revision_id; /* 0xff applies to all steppings */ + u8 front_panel_support; + u16 number_of_rear_jacks; + u16 number_of_front_jacks; +}; + +struct __packed azalia_verb_table { + struct azalia_verb_table_header header; + const u32 *data; +}; + +struct __packed azalia_config { + u8 pme_enable:1; + u8 docking_supported:1; + u8 docking_attached:1; + u8 hdmi_codec_enable:1; + u8 azalia_v_ci_enable:1; + u8 rsvdbits:3; + /* number of verb tables provided by platform */ + u8 verb_table_num; + const struct azalia_verb_table *verb_table; + /* delay timer after azalia reset */ + u16 reset_wait_timer_ms; +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_bootmode.h b/arch/x86/include/asm/fsp/fsp_bootmode.h new file mode 100644 index 0000000..bc96ec3 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_bootmode.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_BOOT_MODE_H__ +#define __FSP_BOOT_MODE_H__ + +/* 0x21 - 0xf..f are reserved */ +#define BOOT_FULL_CONFIG 0x00 +#define BOOT_MINIMAL_CONFIG 0x01 +#define BOOT_NO_CONFIG_CHANGES 0x02 +#define BOOT_FULL_CONFIG_PLUS_DIAG 0x03 +#define BOOT_DEFAULT_SETTINGS 0x04 +#define BOOT_ON_S4_RESUME 0x05 +#define BOOT_ON_S5_RESUME 0x06 +#define BOOT_ON_S2_RESUME 0x10 +#define BOOT_ON_S3_RESUME 0x11 +#define BOOT_ON_FLASH_UPDATE 0x12 +#define BOOT_IN_RECOVERY_MODE 0x20 + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_fv.h b/arch/x86/include/asm/fsp/fsp_fv.h new file mode 100644 index 0000000..511dfb7 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_fv.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_FV___ +#define __FSP_FV___ + +/* Value of EFI_FV_FILE_ATTRIBUTES */ +#define EFI_FV_FILE_ATTR_ALIGNMENT 0x0000001F +#define EFI_FV_FILE_ATTR_FIXED 0x00000100 +#define EFI_FV_FILE_ATTR_MEMORY_MAPPED 0x00000200 + +/* Attributes bit definitions */ +#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB2_READ_STATUS 0x00000004 +#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB2_WRITE_STATUS 0x00000020 +#define EFI_FVB2_LOCK_CAP 0x00000040 +#define EFI_FVB2_LOCK_STATUS 0x00000080 +#define EFI_FVB2_STICKY_WRITE 0x00000200 +#define EFI_FVB2_MEMORY_MAPPED 0x00000400 +#define EFI_FVB2_ERASE_POLARITY 0x00000800 +#define EFI_FVB2_READ_LOCK_CAP 0x00001000 +#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 +#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 +#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 +#define EFI_FVB2_ALIGNMENT 0x001F0000 +#define EFI_FVB2_ALIGNMENT_1 0x00000000 +#define EFI_FVB2_ALIGNMENT_2 0x00010000 +#define EFI_FVB2_ALIGNMENT_4 0x00020000 +#define EFI_FVB2_ALIGNMENT_8 0x00030000 +#define EFI_FVB2_ALIGNMENT_16 0x00040000 +#define EFI_FVB2_ALIGNMENT_32 0x00050000 +#define EFI_FVB2_ALIGNMENT_64 0x00060000 +#define EFI_FVB2_ALIGNMENT_128 0x00070000 +#define EFI_FVB2_ALIGNMENT_256 0x00080000 +#define EFI_FVB2_ALIGNMENT_512 0x00090000 +#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 +#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 +#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 +#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 +#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 +#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 +#define EFI_FVB2_ALIGNMENT_64K 0x00100000 +#define EFI_FVB2_ALIGNMENT_128K 0x00110000 +#define EFI_FVB2_ALIGNMENT_256K 0x00120000 +#define EFI_FVB2_ALIGNMENT_512K 0x00130000 +#define EFI_FVB2_ALIGNMENT_1M 0x00140000 +#define EFI_FVB2_ALIGNMENT_2M 0x00150000 +#define EFI_FVB2_ALIGNMENT_4M 0x00160000 +#define EFI_FVB2_ALIGNMENT_8M 0x00170000 +#define EFI_FVB2_ALIGNMENT_16M 0x00180000 +#define EFI_FVB2_ALIGNMENT_32M 0x00190000 +#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 +#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 +#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 +#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 +#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 +#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 + +struct fv_blkmap_entry { + /* The number of sequential blocks which are of the same size */ + u32 num_blocks; + /* The size of the blocks */ + u32 length; +}; + +/* Describes the features and layout of the firmware volume */ +struct fv_header { + /* + * The first 16 bytes are reserved to allow for the reset vector of + * processors whose reset vector is at address 0. + */ + u8 zero_vec[16]; + /* + * Declares the file system with which the firmware volume + * is formatted. + */ + efi_guid_t fs_guid; + /* + * Length in bytes of the complete firmware volume, including + * the header. + */ + u64 fv_len; + /* Set to EFI_FVH_SIGNATURE */ + u32 sign; + /* + * Declares capabilities and power-on defaults for the firmware + * volume. + */ + u32 attr; + /* Length in bytes of the complete firmware volume header */ + u16 hdr_len; + /* + * A 16-bit checksum of the firmware volume header. + * A valid header sums to zero. + */ + u16 checksum; + /* + * Offset, relative to the start of the header, of the extended + * header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is + * no extended header. + */ + u16 ext_hdr_off; + /* This field must always be set to zero */ + u8 reserved[1]; + /* + * Set to 2. Future versions of this specification may define new + * header fields and will increment the Revision field accordingly. + */ + u8 rev; + /* + * An array of run-length encoded FvBlockMapEntry structures. + * The array is terminated with an entry of {0,0}. + */ + struct fv_blkmap_entry block_map[1]; +}; + +#define EFI_FVH_SIGNATURE SIGNATURE_32('_', 'F', 'V', 'H') + +/* Firmware Volume Header Revision definition */ +#define EFI_FVH_REVISION 0x02 + +/* Extension header pointed by ExtHeaderOffset of volume header */ +struct fv_ext_header { + /* firmware volume name */ + efi_guid_t fv_name; + /* Size of the rest of the extension header including this structure */ + u32 ext_hdr_size; +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_hob.h b/arch/x86/include/asm/fsp/fsp_hob.h new file mode 100644 index 0000000..d248520 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_hob.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_HOB_H__ +#define __FSP_HOB_H__ + +#include <asm/hob.h> + +enum pixel_format { + pixel_rgbx_8bpc, /* RGB 8 bit per color */ + pixel_bgrx_8bpc, /* BGR 8 bit per color */ + pixel_bitmask, +}; + +struct __packed hob_graphics_info { + phys_addr_t fb_base; /* framebuffer base address */ + u32 fb_size; /* framebuffer size */ + u32 version; + u32 width; + u32 height; + enum pixel_format pixel_format; + u32 red_mask; + u32 green_mask; + u32 blue_mask; + u32 reserved_mask; + u32 pixels_per_scanline; +}; + +/* FSP specific GUID HOB definitions */ +#define FSP_GUID_DATA1 0x912740be +#define FSP_GUID_DATA2 0x2284 +#define FSP_GUID_DATA3 0x4734 +#define FSP_GUID_DATA4_0 0xb9 +#define FSP_GUID_DATA4_1 0x71 +#define FSP_GUID_DATA4_2 0x84 +#define FSP_GUID_DATA4_3 0xb0 +#define FSP_GUID_DATA4_4 0x27 +#define FSP_GUID_DATA4_5 0x35 +#define FSP_GUID_DATA4_6 0x3f +#define FSP_GUID_DATA4_7 0x0c + +#define FSP_GUID_BYTE0 0xbe +#define FSP_GUID_BYTE1 0x40 +#define FSP_GUID_BYTE2 0x27 +#define FSP_GUID_BYTE3 0x91 +#define FSP_GUID_BYTE4 0x84 +#define FSP_GUID_BYTE5 0x22 +#define FSP_GUID_BYTE6 0x34 +#define FSP_GUID_BYTE7 0x47 +#define FSP_GUID_BYTE8 FSP_GUID_DATA4_0 +#define FSP_GUID_BYTE9 FSP_GUID_DATA4_1 +#define FSP_GUID_BYTE10 FSP_GUID_DATA4_2 +#define FSP_GUID_BYTE11 FSP_GUID_DATA4_3 +#define FSP_GUID_BYTE12 FSP_GUID_DATA4_4 +#define FSP_GUID_BYTE13 FSP_GUID_DATA4_5 +#define FSP_GUID_BYTE14 FSP_GUID_DATA4_6 +#define FSP_GUID_BYTE15 FSP_GUID_DATA4_7 + +#define FSP_HEADER_GUID \ + EFI_GUID(FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \ + FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \ + FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \ + FSP_GUID_DATA4_6, FSP_GUID_DATA4_7) + +#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ + EFI_GUID(0x721acf02, 0x4d77, 0x4c2a, \ + 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0) + +#define FSP_VARIABLE_NV_DATA_HOB_GUID \ + EFI_GUID(0xa034147d, 0x690c, 0x4154, \ + 0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42) + +#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \ + EFI_GUID(0xbbcff46c, 0xc8d3, 0x4113, \ + 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e) + +#define FSP_HOB_RESOURCE_OWNER_FSP_GUID \ + EFI_GUID(0x69a79759, 0x1373, 0x4367, \ + 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e) + +#define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \ + EFI_GUID(0xd038747c, 0xd00c, 0x4980, \ + 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55) + +#define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \ + EFI_GUID(0x9c7c3aa7, 0x5332, 0x4917, \ + 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07) + +/* The following GUIDs are newly introduced in FSP spec 1.1 */ + +#define FSP_HOB_RESOURCE_OWNER_BOOTLOADER_TOLUM_GUID \ + EFI_GUID(0x73ff4f56, 0xaa8e, 0x4451, \ + 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44) + +#define FSP_GRAPHICS_INFO_HOB_GUID \ + EFI_GUID(0x39f62cce, 0x6825, 0x4669, \ + 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07) + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_infoheader.h b/arch/x86/include/asm/fsp/fsp_infoheader.h new file mode 100644 index 0000000..e72c052 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_infoheader.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _FSP_HEADER_H_ +#define _FSP_HEADER_H_ + +#define FSP_HEADER_OFF 0x94 /* Fixed FSP header offset in the FSP image */ + +struct __packed fsp_header { + u32 sign; /* 'FSPH' */ + u32 hdr_len; /* header length */ + u8 reserved1[3]; + u8 hdr_rev; /* header rev */ + u32 img_rev; /* image rev */ + char img_id[8]; /* signature string */ + u32 img_size; /* image size */ + u32 img_base; /* image base */ + u32 img_attr; /* image attribute */ + u32 cfg_region_off; /* configuration region offset */ + u32 cfg_region_size; /* configuration region size */ + u32 api_num; /* number of API entries */ + u32 fsp_tempram_init; /* tempram_init offset */ + u32 fsp_init; /* fsp_init offset */ + u32 fsp_notify; /* fsp_notify offset */ + u32 fsp_mem_init; /* fsp_mem_init offset */ + u32 fsp_tempram_exit; /* fsp_tempram_exit offset */ + u32 fsp_silicon_init; /* fsp_silicon_init offset */ +}; + +#define FSP_HEADER_REVISION_1 1 +#define FSP_HEADER_REVISION_2 2 + +enum fsp_type { + FSP_ATTR_COMP_TYPE_FSP_T = 1, + FSP_ATTR_COMP_TYPE_FSP_M = 2, + FSP_ATTR_COMP_TYPE_FSP_S = 3, +}; + +enum { + FSP_ATTR_GRAPHICS_SUPPORT = 1 << 0, + FSP_ATTR_COMP_TYPE_SHIFT = 28, + FSP_ATTR_COMP_TYPE_MASK = 0xfU << FSP_ATTR_COMP_TYPE_SHIFT, + +}; + +#define EFI_FSPH_SIGNATURE SIGNATURE_32('F', 'S', 'P', 'H') + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h new file mode 100644 index 0000000..4ac27d2 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_SUPPORT_H__ +#define __FSP_SUPPORT_H__ + +#include <asm/fsp/fsp_bootmode.h> +#include <asm/fsp/fsp_fv.h> +#include <asm/fsp/fsp_hob.h> +#include <asm/fsp/fsp_infoheader.h> +#include <asm/fsp/fsp_types.h> +#include <asm/fsp_arch.h> +#include <asm/fsp/fsp_azalia.h> + +#define FSP_LOWMEM_BASE 0x100000UL +#define FSP_HIGHMEM_BASE 0x100000000ULL +#define UPD_TERMINATOR 0x55AA + +/** + * fsp_find_header() - Find FSP header offset in FSP image + * + * @return the offset of FSP header. If signature is invalid, returns 0. + */ +struct fsp_header *fsp_find_header(void); + +/** + * fsp_notify() - FSP notification wrapper function + * + * @fsp_hdr: Pointer to FSP information header + * @phase: FSP initialization phase defined in enum fsp_phase + * + * @return compatible status code with EFI_STATUS defined in PI spec + */ +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase); + +/** + * fsp_get_usable_lowmem_top() - retrieves the top of usable low memory + * + * @hob_list: A HOB list pointer. + * + * @return Usable low memory top. + */ +u32 fsp_get_usable_lowmem_top(const void *hob_list); + +/** + * fsp_get_usable_highmem_top() - retrieves the top of usable high memory + * + * @hob_list: A HOB list pointer. + * + * @return Usable high memory top. + */ +u64 fsp_get_usable_highmem_top(const void *hob_list); + +/** + * fsp_get_reserved_mem_from_guid() - retrieves a special reserved memory region + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid: A pointer to the owner guild. + * + * @return Reserved region start address. + * 0 if this region does not exist. + */ +u64 fsp_get_reserved_mem_from_guid(const void *hob_list, + u64 *len, const efi_guid_t *guid); + +/** + * fsp_get_fsp_reserved_mem() - retrieves the FSP reserved normal memory + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the FSP reserved memory length buffer. + * If the GUID HOB is located, the length will be updated. + * @return FSP reserved memory base + * 0 if this region does not exist. + */ +u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len); + +/** + * fsp_get_tseg_reserved_mem() - retrieves the TSEG reserved normal memory + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the TSEG reserved memory length buffer. + * If the GUID HOB is located, the length will be updated. + * + * @return NULL: Failed to find the TSEG reserved memory. + * @return others: TSEG reserved memory base. + */ +u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len); + +/** + * fsp_get_nvs_data() - retrieves FSP Non-volatile Storage HOB buffer and size + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the NVS data buffer length. + * If the HOB is located, the length will be updated. + * + * @return NULL: Failed to find the NVS HOB. + * @return others: FSP NVS data buffer pointer. + */ +void *fsp_get_nvs_data(const void *hob_list, u32 *len); + +/** + * fsp_get_var_nvs_data() - get FSP variable Non-volatile Storage HOB buffer + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the NVS data buffer length. + * If the HOB is located, the length will be updated. + * + * @return NULL: Failed to find the NVS HOB. + * @return others: FSP NVS data buffer pointer. + */ +void *fsp_get_var_nvs_data(const void *hob_list, u32 *len); + +/** + * fsp_get_graphics_info() - retrieves graphics information. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the graphics info HOB length. + * If the HOB is located, the length will be updated. + * + * @return NULL: Failed to find the graphics info HOB. + * @return others: A pointer to struct hob_graphics_info. + */ +void *fsp_get_graphics_info(const void *hob_list, u32 *len); + +/** + * fsp_init_phase_pci() - Tell the FSP that we have completed PCI init + * + * @return 0 if OK, -EPERM if the FSP gave an error. + */ +int fsp_init_phase_pci(void); + +/** + * fsp_scan_for_ram_size() - Scan the HOB list to find the RAM size + * + * This sets gd->ram_size based on what it finds. + * + * @return 0 if OK, -ve on error + */ +int fsp_scan_for_ram_size(void); + +/** + * fsp_prepare_mrc_cache() - Find the DRAM training data from the MRC cache + * + * @return pointer to data, or NULL if no cache or no data found in the cache + */ +void *fsp_prepare_mrc_cache(void); + +/** + * fsp_notify() - FSP notification wrapper function + * + * @fsp_hdr: Pointer to FSP information header + * @phase: FSP initialization phase defined in enum fsp_phase + * + * @return compatible status code with EFI_STATUS defined in PI spec + */ +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase); + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_types.h b/arch/x86/include/asm/fsp/fsp_types.h new file mode 100644 index 0000000..3d5b17e --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_types.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_TYPES_H__ +#define __FSP_TYPES_H__ + +/** + * Returns a 16-bit signature built from 2 ASCII characters. + * + * This macro returns a 16-bit value built from the two ASCII characters + * specified by A and B. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * + * @return: A 16-bit value built from the two ASCII characters specified by + * A and B. + */ +#define SIGNATURE_16(A, B) ((A) | (B << 8)) + +/** + * Returns a 32-bit signature built from 4 ASCII characters. + * + * This macro returns a 32-bit value built from the four ASCII characters + * specified by A, B, C, and D. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * + * @return: A 32-bit value built from the two ASCII characters specified by + * A, B, C and D. + */ +#define SIGNATURE_32(A, B, C, D) \ + (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) + +/** + * Returns a 64-bit signature built from 8 ASCII characters. + * + * This macro returns a 64-bit value built from the eight ASCII characters + * specified by A, B, C, D, E, F, G,and H. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * @E: The fifth ASCII character. + * @F: The sixth ASCII character. + * @G: The seventh ASCII character. + * @H: The eighth ASCII character. + * + * @return: A 64-bit value built from the two ASCII characters specified by + * A, B, C, D, E, F, G and H. + */ +#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) + +#endif diff --git a/arch/x86/include/asm/fsp1/fsp_api.h b/arch/x86/include/asm/fsp1/fsp_api.h new file mode 100644 index 0000000..f2d7079 --- /dev/null +++ b/arch/x86/include/asm/fsp1/fsp_api.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_API_H__ +#define __FSP_API_H__ + +#include <linux/linkage.h> + +/* + * FSP common configuration structure. + * This needs to be included in the platform-specific struct fsp_config_data. + */ +struct fsp_cfg_common { + struct fsp_header *fsp_hdr; + u32 stack_top; + u32 boot_mode; +}; + +/* + * FspInit continuation function prototype. + * Control will be returned to this callback function after FspInit API call. + */ +typedef void (*fsp_continuation_f)(u32 status, void *hob_list); + +struct fsp_init_params { + /* Non-volatile storage buffer pointer */ + void *nvs_buf; + /* Runtime buffer pointer */ + void *rt_buf; + /* Continuation function address */ + fsp_continuation_f continuation; +}; + +struct common_buf { + /* + * Stack top pointer used by the bootloader. The new stack frame will be + * set up at this location after FspInit API call. + */ + u32 stack_top; + u32 boot_mode; /* Current system boot mode */ + void *upd_data; /* User platform configuraiton data region */ + u32 tolum_size; /* Top of low usable memory size (FSP 1.1) */ + u32 reserved[6]; /* Reserved */ +}; + +enum fsp_phase { + /* Notification code for post PCI enuermation */ + INIT_PHASE_PCI = 0x20, + /* Notification code before transfering control to the payload */ + INIT_PHASE_BOOT = 0x40 +}; + +struct fsp_notify_params { + /* Notification phase used for NotifyPhase API */ + enum fsp_phase phase; +}; + +/* FspInit API function prototype */ +typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params); + +/* FspNotify API function prototype */ +typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params); + +#endif diff --git a/arch/x86/include/asm/fsp1/fsp_ffs.h b/arch/x86/include/asm/fsp1/fsp_ffs.h new file mode 100644 index 0000000..b7558e5 --- /dev/null +++ b/arch/x86/include/asm/fsp1/fsp_ffs.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP_FFS_H__ +#define __FSP_FFS_H__ + +/* Used to verify the integrity of the file */ +union __packed ffs_integrity { + struct { + /* + * The IntegrityCheck.checksum.header field is an 8-bit + * checksum of the file header. The State and + * IntegrityCheck.checksum.file fields are assumed to be zero + * and the checksum is calculated such that the entire header + * sums to zero. + */ + u8 header; + /* + * If the FFS_ATTRIB_CHECKSUM (see definition below) bit of + * the Attributes field is set to one, the + * IntegrityCheck.checksum.file field is an 8-bit checksum of + * the file data. If the FFS_ATTRIB_CHECKSUM bit of the + * Attributes field is cleared to zero, the + * IntegrityCheck.checksum.file field must be initialized with + * a value of 0xAA. The IntegrityCheck.checksum.file field is + * valid any time the EFI_FILE_DATA_VALID bit is set in the + * State field. + */ + u8 file; + } checksum; + + /* This is the full 16 bits of the IntegrityCheck field */ + u16 checksum16; +}; + +/* + * Each file begins with the header that describe the + * contents and state of the files. + */ +struct __packed ffs_file_header { + /* + * This GUID is the file name. + * It is used to uniquely identify the file. + */ + efi_guid_t name; + /* Used to verify the integrity of the file */ + union ffs_integrity integrity; + /* Identifies the type of file */ + u8 type; + /* Declares various file attribute bits */ + u8 attr; + /* The length of the file in bytes, including the FFS header */ + u8 size[3]; + /* + * Used to track the state of the file throughout the life of + * the file from creation to deletion. + */ + u8 state; +}; + +struct __packed ffs_file_header2 { + /* + * This GUID is the file name. It is used to uniquely identify the file. + * There may be only one instance of a file with the file name GUID of + * Name in any given firmware volume, except if the file type is + * EFI_FV_FILE_TYPE_FFS_PAD. + */ + efi_guid_t name; + /* Used to verify the integrity of the file */ + union ffs_integrity integrity; + /* Identifies the type of file */ + u8 type; + /* Declares various file attribute bits */ + u8 attr; + /* + * The length of the file in bytes, including the FFS header. + * The length of the file data is either + * (size - sizeof(struct ffs_file_header)). This calculation means a + * zero-length file has a size of 24 bytes, which is + * sizeof(struct ffs_file_header). Size is not required to be a + * multiple of 8 bytes. Given a file F, the next file header is located + * at the next 8-byte aligned firmware volume offset following the last + * byte of the file F. + */ + u8 size[3]; + /* + * Used to track the state of the file throughout the life of + * the file from creation to deletion. + */ + u8 state; + /* + * If FFS_ATTRIB_LARGE_FILE is set in attr, then ext_size exists + * and size must be set to zero. + * If FFS_ATTRIB_LARGE_FILE is not set then + * struct ffs_file_header is used. + */ + u32 ext_size; +}; + +/* + * Pseudo type. It is used as a wild card when retrieving sections. + * The section type EFI_SECTION_ALL matches all section types. + */ +#define EFI_SECTION_ALL 0x00 + +/* Encapsulation section Type values */ +#define EFI_SECTION_COMPRESSION 0x01 +#define EFI_SECTION_GUID_DEFINED 0x02 +#define EFI_SECTION_DISPOSABLE 0x03 + +/* Leaf section Type values */ +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B +#define EFI_SECTION_SMM_DEPEX 0x1C + +/* Common section header */ +struct __packed raw_section { + /* + * A 24-bit unsigned integer that contains the total size of + * the section in bytes, including the EFI_COMMON_SECTION_HEADER. + */ + u8 size[3]; + u8 type; +}; + +struct __packed raw_section2 { + /* + * A 24-bit unsigned integer that contains the total size of + * the section in bytes, including the EFI_COMMON_SECTION_HEADER. + */ + u8 size[3]; + u8 type; + /* + * If size is 0xFFFFFF, then ext_size contains the size of + * the section. If size is not equal to 0xFFFFFF, then this + * field does not exist. + */ + u32 ext_size; +}; + +#endif diff --git a/arch/x86/include/asm/fsp1/fsp_support.h b/arch/x86/include/asm/fsp1/fsp_support.h new file mode 100644 index 0000000..a44a550 --- /dev/null +++ b/arch/x86/include/asm/fsp1/fsp_support.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __FSP1_SUPPORT_H__ +#define __FSP1_SUPPORT_H__ + +#include <asm/fsp/fsp_support.h> +#include "fsp_ffs.h" + +/** + * fsp_asm_continuation() - FSP Continuation assembly helper routine + * + * This routine jumps to the C version of FSP continuation function + */ +void fsp_asm_continuation(void); + +/** + * fsp_init_done() - FSP initialization complete + * + * This is the function that indicates FSP initialization is complete and jumps + * back to the bootloader with HOB list pointer as the parameter. + * + * @hob_list: HOB list pointer + */ +void fsp_init_done(void *hob_list); + +/** + * fsp_continue() - FSP Continuation function + * + * @status: Always 0 + * @hob_list: HOB list pointer + * + * @return Never returns + */ +void fsp_continue(u32 status, void *hob_list); + +/** + * fsp_init() - FSP initialization wrapper function + * + * @stack_top: bootloader stack top address + * @boot_mode: boot mode defined in fsp_bootmode.h + * @nvs_buf: Non-volatile memory buffer pointer + */ +void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf); + +/** + * fsp_get_bootloader_tmp_mem() - retrieves temporary stack buffer and size + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the bootloader temporary stack length. + * If the HOB is located, the length will be updated. + * + * @return NULL: Failed to find the bootloader temporary stack HOB. + * @return others: Bootloader temporary stackbuffer pointer. + */ +void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len); + +/** + * fsp_update_configs() - overrides the default configurations of FSP + * + * @config: A pointer to the FSP configuration data structure + * @rt_buf: A pointer to the FSP runtime buffer data structure + * + * @return None + */ +void fsp_update_configs(struct fsp_config_data *config, + struct fspinit_rtbuf *rt_buf); + +#endif diff --git a/arch/x86/include/asm/fsp_arch.h b/arch/x86/include/asm/fsp_arch.h new file mode 100644 index 0000000..3b2077b --- /dev/null +++ b/arch/x86/include/asm/fsp_arch.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + * + * Architecture-specific definitions (FSP config and VPD/UPD) + */ + +#ifndef __FSP_ARCH_H__ +#define __FSP_ARCH_H__ + +/* + * Note: use #ifndef __ASSEMBLY__ around any struct definitions or other C code + * since this file can be included from assembly. + */ + +#include <asm/fsp1/fsp_api.h> +#include <asm/fsp1/fsp_ffs.h> +#include <asm/arch/fsp/fsp_vpd.h> +#include <asm/arch/fsp/fsp_configs.h> + +#endif diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h new file mode 100644 index 0000000..17a4d34 --- /dev/null +++ b/arch/x86/include/asm/global_data.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +#ifndef __ASSEMBLY__ + +#include <asm/processor.h> + +enum pei_boot_mode_t { + PEI_BOOT_NONE = 0, + PEI_BOOT_SOFT_RESET, + PEI_BOOT_RESUME, + +}; + +struct dimm_info { + uint32_t dimm_size; + uint16_t ddr_type; + uint16_t ddr_frequency; + uint8_t rank_per_dimm; + uint8_t channel_num; + uint8_t dimm_num; + uint8_t bank_locator; + /* The 5th byte is '\0' for the end of string */ + uint8_t serial[5]; + /* The 19th byte is '\0' for the end of string */ + uint8_t module_part_number[19]; + uint16_t mod_id; + uint8_t mod_type; + uint8_t bus_width; +} __packed; + +struct pei_memory_info { + uint8_t dimm_cnt; + /* Maximum num of dimm is 8 */ + struct dimm_info dimm[8]; +} __packed; + +struct memory_area { + uint64_t start; + uint64_t size; +}; + +struct memory_info { + int num_areas; + uint64_t total_memory; + uint64_t total_32bit_memory; + struct memory_area area[CONFIG_NR_DRAM_BANKS]; +}; + +#define MAX_MTRR_REQUESTS 8 + +/** + * A request for a memory region to be set up in a particular way. These + * requests are processed before board_init_r() is called. They are generally + * optional and can be ignored with some performance impact. + */ +struct mtrr_request { + int type; /* MTRR_TYPE_... */ + uint64_t start; + uint64_t size; +}; + +/* Architecture-specific global data */ +struct arch_global_data { + u64 gdt[X86_GDT_NUM_ENTRIES] __aligned(16); + struct global_data *gd_addr; /* Location of Global Data */ + uint8_t x86; /* CPU family */ + uint8_t x86_vendor; /* CPU vendor */ + uint8_t x86_model; + uint8_t x86_mask; + uint32_t x86_device; + uint64_t tsc_base; /* Initial value returned by rdtsc() */ + unsigned long clock_rate; /* Clock rate of timer in Hz */ + void *new_fdt; /* Relocated FDT */ + uint32_t bist; /* Built-in self test value */ + enum pei_boot_mode_t pei_boot_mode; + const struct pch_gpio_map *gpio_map; /* board GPIO map */ + struct memory_info meminfo; /* Memory information */ + struct pei_memory_info pei_meminfo; /* PEI memory information */ +#ifdef CONFIG_USE_HOB + void *hob_list; /* FSP HOB list */ +#endif + struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; + int mtrr_req_count; + int has_mtrr; + /* MRC training data to save for the next boot */ + char *mrc_output; + unsigned int mrc_output_len; + ulong table; /* Table pointer from previous loader */ + int turbo_state; /* Current turbo state */ + struct irq_routing_table *pirq_routing_table; +#ifdef CONFIG_SEABIOS + u32 high_table_ptr; + u32 high_table_limit; +#endif +#ifdef CONFIG_HAVE_ACPI_RESUME + int prev_sleep_state; /* Previous sleep state ACPI_S0/1../5 */ + ulong backup_mem; /* Backup memory address for S3 */ +#endif +}; + +#endif + +#include <asm-generic/global_data.h> + +#ifndef __ASSEMBLY__ +# if defined(CONFIG_EFI_APP) || CONFIG_IS_ENABLED(X86_64) + +/* TODO(sjg@chromium.org): Consider using a fixed register for gd on x86_64 */ +#define gd global_data_ptr + +#define DECLARE_GLOBAL_DATA_PTR extern struct global_data *global_data_ptr +# else +static inline __attribute__((no_instrument_function)) gd_t *get_fs_gd_ptr(void) +{ + gd_t *gd_ptr; + +#if CONFIG_IS_ENABLED(X86_64) + asm volatile("fs mov 0, %0\n" : "=r" (gd_ptr)); +#else + asm volatile("fs movl 0, %0\n" : "=r" (gd_ptr)); +#endif + + return gd_ptr; +} + +#define gd get_fs_gd_ptr() + +#define DECLARE_GLOBAL_DATA_PTR +# endif + +#endif + +#endif /* __ASM_GBL_DATA_H */ diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h new file mode 100644 index 0000000..58e4d7b --- /dev/null +++ b/arch/x86/include/asm/gpio.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012, Google Inc. All rights reserved. + */ + +#ifndef _X86_GPIO_H_ +#define _X86_GPIO_H_ + +#include <asm-generic/gpio.h> + +struct ich6_bank_platdata { + uint16_t base_addr; + const char *bank_name; + int offset; +}; + +#endif /* _X86_GPIO_H_ */ diff --git a/arch/x86/include/asm/handoff.h b/arch/x86/include/asm/handoff.h new file mode 100644 index 0000000..aec49b9 --- /dev/null +++ b/arch/x86/include/asm/handoff.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Architecture-specific SPL handoff information for x86 + * + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __x86_asm_handoff_h +#define __x86_asm_handoff_h + +/** + * struct arch_spl_handoff - architecture-specific handoff info + * + * @usable_ram_top: Value returned by board_get_usable_ram_top() in SPL + * @hob_list: Start of FSP hand-off blocks (HOBs) + */ +struct arch_spl_handoff { + ulong usable_ram_top; + void *hob_list; +}; + +#endif diff --git a/arch/x86/include/asm/hob.h b/arch/x86/include/asm/hob.h new file mode 100644 index 0000000..56e11db --- /dev/null +++ b/arch/x86/include/asm/hob.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __HOB_H__ +#define __HOB_H__ + +#include <efi.h> +#include <efi_loader.h> + +/* Type of HOB Header */ +#define HOB_TYPE_MEM_ALLOC 0x0002 +#define HOB_TYPE_RES_DESC 0x0003 +#define HOB_TYPE_GUID_EXT 0x0004 +#define HOB_TYPE_UNUSED 0xFFFE +#define HOB_TYPE_EOH 0xFFFF + +/* Value of ResourceType in HOB_RES_DESC */ +#define RES_SYS_MEM 0x00000000 +#define RES_MMAP_IO 0x00000001 +#define RES_IO 0x00000002 +#define RES_FW_DEVICE 0x00000003 +#define RES_MMAP_IO_PORT 0x00000004 +#define RES_MEM_RESERVED 0x00000005 +#define RES_IO_RESERVED 0x00000006 +#define RES_MAX_MEM_TYPE 0x00000007 + +/* + * These types can be ORed together as needed. + * + * The first three enumerations describe settings + * The rest of the settings describe capabilities + */ +#define RES_ATTR_PRESENT 0x00000001 +#define RES_ATTR_INITIALIZED 0x00000002 +#define RES_ATTR_TESTED 0x00000004 +#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 +#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 +#define RES_ATTR_ECC_RESERVED_1 0x00000020 +#define RES_ATTR_ECC_RESERVED_2 0x00000040 +#define RES_ATTR_READ_PROTECTED 0x00000080 +#define RES_ATTR_WRITE_PROTECTED 0x00000100 +#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 +#define RES_ATTR_UNCACHEABLE 0x00000400 +#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 +#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 +#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 +#define RES_ATTR_16_BIT_IO 0x00004000 +#define RES_ATTR_32_BIT_IO 0x00008000 +#define RES_ATTR_64_BIT_IO 0x00010000 +#define RES_ATTR_UNCACHED_EXPORTED 0x00020000 + +/* + * Describes the format and size of the data inside the HOB. + * All HOBs must contain this generic HOB header. + */ +struct hob_header { + u16 type; /* HOB type */ + u16 len; /* HOB length */ + u32 reserved; /* always zero */ +}; + +/* + * Describes all memory ranges used during the HOB producer phase that + * exist outside the HOB list. This HOB type describes how memory is used, + * not the physical attributes of memory. + */ +struct hob_mem_alloc { + struct hob_header hdr; + /* + * A GUID that defines the memory allocation region's type and purpose, + * as well as other fields within the memory allocation HOB. This GUID + * is used to define the additional data within the HOB that may be + * present for the memory allocation HOB. Type efi_guid_t is defined in + * InstallProtocolInterface() in the UEFI 2.0 specification. + */ + efi_guid_t name; + /* + * The base address of memory allocated by this HOB. + * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + phys_addr_t mem_base; + /* The length in bytes of memory allocated by this HOB */ + phys_size_t mem_len; + /* + * Defines the type of memory allocated by this HOB. + * The memory type definition follows the EFI_MEMORY_TYPE definition. + * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + enum efi_mem_type mem_type; + /* padding */ + u8 reserved[4]; +}; + +/* + * Describes the resource properties of all fixed, nonrelocatable resource + * ranges found on the processor host bus during the HOB producer phase. + */ +struct hob_res_desc { + struct hob_header hdr; + /* + * A GUID representing the owner of the resource. This GUID is + * used by HOB consumer phase components to correlate device + * ownership of a resource. + */ + efi_guid_t owner; + u32 type; + u32 attr; + /* The physical start address of the resource region */ + phys_addr_t phys_start; + /* The number of bytes of the resource region */ + phys_size_t len; +}; + +/* + * Allows writers of executable content in the HOB producer phase to + * maintain and manage HOBs with specific GUID. + */ +struct hob_guid { + struct hob_header hdr; + /* A GUID that defines the contents of this HOB */ + efi_guid_t name; + /* GUID specific data goes here */ +}; + +/** + * get_next_hob() - return a pointer to the next HOB in the HOB list + * + * This macro returns a pointer to HOB that follows the HOB specified by hob + * in the HOB List. + * + * @hdr: A pointer to a HOB. + * + * @return A pointer to the next HOB in the HOB list. + */ +static inline const struct hob_header *get_next_hob(const struct hob_header + *hdr) +{ + return (const struct hob_header *)((uintptr_t)hdr + hdr->len); +} + +/** + * end_of_hob() - determine if a HOB is the last HOB in the HOB list + * + * This macro determine if the HOB specified by hob is the last HOB in the + * HOB list. If hob is last HOB in the HOB list, then true is returned. + * Otherwise, false is returned. + * + * @hdr: A pointer to a HOB. + * + * @return true: The HOB specified by hdr is the last HOB in the HOB list. + * @return false: The HOB specified by hdr is not the last HOB in the HOB list. + */ +static inline bool end_of_hob(const struct hob_header *hdr) +{ + return hdr->type == HOB_TYPE_EOH; +} + +/** + * get_guid_hob_data() - return a pointer to data buffer from a HOB of + * type HOB_TYPE_GUID_EXT + * + * This macro returns a pointer to the data buffer in a HOB specified by hob. + * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return A pointer to the data buffer in a HOB. + */ +static inline void *get_guid_hob_data(const struct hob_header *hdr) +{ + return (void *)((uintptr_t)hdr + sizeof(struct hob_guid)); +} + +/** + * get_guid_hob_data_size() - return the size of the data buffer from a HOB + * of type HOB_TYPE_GUID_EXT + * + * This macro returns the size, in bytes, of the data buffer in a HOB + * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return The size of the data buffer. + */ +static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) +{ + return hdr->len - sizeof(struct hob_guid); +} + +/** + * Returns the next instance of a HOB type from the starting HOB. + * + * @type: HOB type to search + * @hob_list: A pointer to the HOB list + * + * @return A HOB object with matching type; Otherwise NULL. + */ +const struct hob_header *hob_get_next_hob(uint type, const void *hob_list); + +/** + * Returns the next instance of the matched GUID HOB from the starting HOB. + * + * @guid: GUID to search + * @hob_list: A pointer to the HOB list + * + * @return A HOB object with matching GUID; Otherwise NULL. + */ +const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid, + const void *hob_list); + +/** + * This function retrieves a GUID HOB data buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid A pointer to HOB GUID. + * + * @return NULL: Failed to find the GUID HOB. + * @return others: GUID HOB data buffer pointer. + */ +void *hob_get_guid_hob_data(const void *hob_list, u32 *len, + const efi_guid_t *guid); + +#endif /* __HOB_H__ */ diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h new file mode 100644 index 0000000..d769daf --- /dev/null +++ b/arch/x86/include/asm/i8254.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + */ + +/* i8254.h Intel 8254 PIT registers */ + +#ifndef _ASMI386_I8254_H_ +#define _ASMI386_I8954_H_ + +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ + +/* PIT Command Register Bit Definitions */ + +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ + +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ + +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0a /* Select mode 5 */ + +/* The clock frequency of the i8253/i8254 PIT */ +#define PIT_TICK_RATE 1193182 + +/** + * i8254_enable_beep() - Start a beep using the PCAT timer + * + * This starts beeping using the legacy i8254 timer. The beep may be silenced + * after a delay with i8254_disable_beep(). + * + * @frequency_hz: Frequency of beep in Hz + * @return 0 if OK, -EINVAL if frequency_hz is 0 + */ +int i8254_enable_beep(uint frequency_hz); + +/** + * i8254_disable_beep() - Disable the bepper + * + * This stops any existing beep + */ +void i8254_disable_beep(void); + +#endif /* _ASMI386_I8954_H_ */ diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h new file mode 100644 index 0000000..b73052a --- /dev/null +++ b/arch/x86/include/asm/i8259.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + */ + +/* i8259.h i8259 PIC Registers */ + +#ifndef _ASMI386_I8259_H_ +#define _ASMI386_I8959_H_ + +/* PIC I/O mapped registers */ +#define IRR 0x0 /* Interrupt Request Register */ +#define ISR 0x0 /* In-Service Register */ +#define ICW1 0x0 /* Initialization Control Word 1 */ +#define OCW2 0x0 /* Operation Control Word 2 */ +#define OCW3 0x0 /* Operation Control Word 3 */ +#define ICW2 0x1 /* Initialization Control Word 2 */ +#define ICW3 0x1 /* Initialization Control Word 3 */ +#define ICW4 0x1 /* Initialization Control Word 4 */ +#define IMR 0x1 /* Interrupt Mask Register */ + +/* IRR, IMR, ISR and ICW3 bits */ +#define IR7 0x80 /* IR7 */ +#define IR6 0x40 /* IR6 */ +#define IR5 0x20 /* IR5 */ +#define IR4 0x10 /* IR4 */ +#define IR3 0x08 /* IR3 */ +#define IR2 0x04 /* IR2 */ +#define IR1 0x02 /* IR1 */ +#define IR0 0x01 /* IR0 */ + +/* SEOI bits */ +#define SEOI_IR7 0x07 /* IR7 */ +#define SEOI_IR6 0x06 /* IR6 */ +#define SEOI_IR5 0x05 /* IR5 */ +#define SEOI_IR4 0x04 /* IR4 */ +#define SEOI_IR3 0x03 /* IR3 */ +#define SEOI_IR2 0x02 /* IR2 */ +#define SEOI_IR1 0x01 /* IR1 */ +#define SEOI_IR0 0x00 /* IR0 */ + +/* OCW2 bits */ +#define OCW2_RCLR 0x00 /* Rotate/clear */ +#define OCW2_NEOI 0x20 /* Non specific EOI */ +#define OCW2_NOP 0x40 /* NOP */ +#define OCW2_SEOI 0x60 /* Specific EOI */ +#define OCW2_RSET 0x80 /* Rotate/set */ +#define OCW2_REOI 0xa0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xc0 /* Priority Set Command */ +#define OCW2_RSEOI 0xe0 /* Rotate on specific EOI */ + +/* ICW1 bits */ +#define ICW1_SEL 0x10 /* Select ICW1 */ +#define ICW1_LTIM 0x08 /* Level-Triggered Interrupt Mode */ +#define ICW1_ADI 0x04 /* Address Interval */ +#define ICW1_SNGL 0x02 /* Single PIC */ +#define ICW1_EICW4 0x01 /* Expect initilization ICW4 */ + +/* + * ICW2 is the starting vector number + * + * ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device + */ + +/* ICW4 bits */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_PM 0x01 /* Microprocessor Mode */ + +#define ELCR1 0x4d0 +#define ELCR2 0x4d1 + +int i8259_init(void); + +#endif /* _ASMI386_I8959_H_ */ diff --git a/arch/x86/include/asm/ibmpc.h b/arch/x86/include/asm/ibmpc.h new file mode 100644 index 0000000..4368b6e --- /dev/null +++ b/arch/x86/include/asm/ibmpc.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + */ + +#ifndef __ASM_IBMPC_H_ +#define __ASM_IBMPC_H_ 1 + +/* misc ports in an ibm compatible pc */ + +#define MASTER_PIC 0x20 +#define PIT_BASE 0x40 +#define KBDDATA 0x60 +#define SYSCTLB 0x62 +#define KBDCMD 0x64 +#define SYSCTLA 0x92 +#define SLAVE_PIC 0xa0 + +#define UART0_BASE 0x3f8 +#define UART1_BASE 0x2f8 + +#define UART0_IRQ 4 +#define UART1_IRQ 3 + +#define KBD_IRQ 1 +#define MSE_IRQ 12 + +#endif diff --git a/arch/x86/include/asm/intel_regs.h b/arch/x86/include/asm/intel_regs.h new file mode 100644 index 0000000..4e01722 --- /dev/null +++ b/arch/x86/include/asm/intel_regs.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ASM_INTEL_REGS_H +#define __ASM_INTEL_REGS_H + +/* Access the memory-controller hub */ +#define MCH_BASE_ADDRESS 0xfed10000 +#define MCH_BASE_SIZE 0x8000 +#define MCHBAR_REG(reg) (MCH_BASE_ADDRESS + (reg)) + +#define MCHBAR_PEI_VERSION 0x5034 +#define MCH_PKG_POWER_LIMIT_LO 0x59a0 +#define MCH_PKG_POWER_LIMIT_HI 0x59a4 +#define MCH_DDR_POWER_LIMIT_LO 0x58e0 +#define MCH_DDR_POWER_LIMIT_HI 0x58e4 + +/* Access the Root Complex Register Block */ +#define RCB_BASE_ADDRESS 0xfed1c000 +#define RCB_REG(reg) (RCB_BASE_ADDRESS + (reg)) + +#define SOFT_RESET_CTRL 0x38f4 +#define SOFT_RESET_DATA 0x38f8 + +#endif diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h new file mode 100644 index 0000000..fdeb857 --- /dev/null +++ b/arch/x86/include/asm/interrupt.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2009 + * Graeme Russ, graeme.russ@gmail.com + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + */ + +#ifndef __ASM_INTERRUPT_H_ +#define __ASM_INTERRUPT_H_ 1 + +#include <asm/types.h> + +#define SYS_NUM_IRQS 16 + +/* Architecture defined exceptions */ +enum x86_exception { + EXC_DE = 0, + EXC_DB, + EXC_NMI, + EXC_BP, + EXC_OF, + EXC_BR, + EXC_UD, + EXC_NM, + EXC_DF, + EXC_CSO, + EXC_TS, + EXC_NP, + EXC_SS, + EXC_GP, + EXC_PF, + EXC_MF = 16, + EXC_AC, + EXC_MC, + EXC_XM, + EXC_VE +}; + +/* arch/x86/cpu/interrupts.c */ +void set_vector(u8 intnum, void *routine); + +/* Architecture specific functions */ +void mask_irq(int irq); +void unmask_irq(int irq); +void specific_eoi(int irq); + +extern char exception_stack[]; + +/** + * configure_irq_trigger() - Configure IRQ triggering + * + * Switch the given interrupt to be level / edge triggered + * + * @param int_num legacy interrupt number (3-7, 9-15) + * @param is_level_triggered true for level triggered interrupt, false for + * edge triggered interrupt + */ +void configure_irq_trigger(int int_num, bool is_level_triggered); + +void *x86_get_idt(void); + +#endif diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h new file mode 100644 index 0000000..cf6c33c --- /dev/null +++ b/arch/x86/include/asm/io.h @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include <linux/compiler.h> + +/* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + + /* + * Bit simplified and optimized by Jan Hubicka + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + * + * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, + * isa_read[wl] and isa_write[wl] fixed + * - Arnaldo Carvalho de Melo <acme@conectiva.com.br> + */ + +#define IO_SPACE_LIMIT 0xffff + +#include <asm/types.h> + + +#ifdef __KERNEL__ + + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile u8 *)(uintptr_t)(addr)) +#define readw(addr) (*(volatile u16 *)(uintptr_t)(addr)) +#define readl(addr) (*(volatile u32 *)(uintptr_t)(addr)) +#define readq(addr) (*(volatile u64 *)(uintptr_t)(addr)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_readq readq + +#define writeb(b, addr) (*(volatile u8 *)(addr) = (b)) +#define writew(b, addr) (*(volatile u16 *)(addr) = (b)) +#define writel(b, addr) (*(volatile u32 *)(addr) = (b)) +#define writeq(b, addr) (*(volatile u64 *)(addr) = (b)) +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel +#define __raw_writeq writeq + +#define memset_io(a,b,c) memset((a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(b),(c)) +#define memcpy_toio(a,b,c) memcpy((a),(b),(c)) + +#define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a) +#define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le64(a, v) out_arch(q, le64, a, v) +#define out_le32(a, v) out_arch(l, le32, a, v) +#define out_le16(a, v) out_arch(w, le16, a, v) + +#define in_le64(a) in_arch(q, le64, a) +#define in_le32(a) in_arch(l, le32, a) +#define in_le16(a) in_arch(w, le16, a) + +#define out_be32(a, v) out_arch(l, be32, a, v) +#define out_be16(a, v) out_arch(w, be16, a, v) + +#define in_be32(a) in_arch(l, be32, a) +#define in_be16(a) in_arch(w, be16, a) + +#define out_8(a, v) __raw_writeb(v, a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + +#endif /* __KERNEL__ */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#define __SLOW_DOWN_IO "\noutb %%al,$0xed" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + + +/* + * Talk about misusing macros.. + */ +#define __OUT1(s,x) \ +static inline void _out##s(unsigned x value, unsigned short port) { + +#define __OUT2(s,s1,s2) \ +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" + + +#define __OUT(s,s1,x) \ +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} + +#define __IN1(s) \ +static inline RETURN_TYPE _in##s(unsigned short port) { RETURN_TYPE _v; + +#define __IN2(s,s1,s2) \ +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } + +#define __INS(s) \ +static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; ins" #s \ +: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define __OUTS(s) \ +static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; outs" #s \ +: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define RETURN_TYPE unsigned char +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int +__IN(l,"") +#undef RETURN_TYPE + +#define inb(port) _inb((uintptr_t)(port)) +#define inw(port) _inw((uintptr_t)(port)) +#define inl(port) _inl((uintptr_t)(port)) + +__OUT(b,"b",char) +__OUT(w,"w",short) +__OUT(l,,int) + +#define outb(val, port) _outb(val, (uintptr_t)(port)) +#define outw(val, port) _outw(val, (uintptr_t)(port)) +#define outl(val, port) _outl(val, (uintptr_t)(port)) + +__INS(b) +__INS(w) +__INS(l) + +__OUTS(b) +__OUTS(w) +__OUTS(l) + +/* IO space accessors */ +#define clrio(type, addr, clear) \ + out##type(in##type(addr) & ~(clear), (addr)) + +#define setio(type, addr, set) \ + out##type(in##type(addr) | (set), (addr)) + +#define clrsetio(type, addr, clear, set) \ + out##type((in##type(addr) & ~(clear)) | (set), (addr)) + +#define clrio_32(addr, clear) clrio(l, addr, clear) +#define clrio_16(addr, clear) clrio(w, addr, clear) +#define clrio_8(addr, clear) clrio(b, addr, clear) + +#define setio_32(addr, set) setio(l, addr, set) +#define setio_16(addr, set) setio(w, addr, set) +#define setio_8(addr, set) setio(b, addr, set) + +#define clrsetio_32(addr, clear, set) clrsetio(l, addr, clear, set) +#define clrsetio_16(addr, clear, set) clrsetio(w, addr, clear, set) +#define clrsetio_8(addr, clear, set) clrsetio(b, addr, clear, set) + +static inline void sync(void) +{ +} + +/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + +/* + * Read/write from/to an (offsettable) iomem cookie. It might be a PIO + * access or a MMIO access, these functions don't care. The info is + * encoded in the hardware mapping set up by the mapping functions + * (or the cookie itself, depending on implementation and hw). + * + * The generic routines don't assume any hardware mappings, and just + * encode the PIO/MMIO as part of the cookie. They coldly assume that + * the MMIO IO mappings are not in the low address range. + * + * Architectures for which this is not true can't use this generic + * implementation and should do their own copy. + */ + +/* + * We assume that all the low physical PIO addresses (0-0xffff) always + * PIO. That means we can do some sanity checks on the low bits, and + * don't need to just take things for granted. + */ +#define PIO_RESERVED 0x10000UL + +/* + * Ugly macros are a way of life. + */ +#define IO_COND(addr, is_pio, is_mmio) do { \ + unsigned long port = (unsigned long __force)addr; \ + if (port >= PIO_RESERVED) { \ + is_mmio; \ + } else { \ + is_pio; \ + } \ +} while (0) + +static inline u8 ioread8(const volatile void __iomem *addr) +{ + IO_COND(addr, return inb(port), return readb(addr)); + return 0xff; +} + +static inline u16 ioread16(const volatile void __iomem *addr) +{ + IO_COND(addr, return inw(port), return readw(addr)); + return 0xffff; +} + +static inline u32 ioread32(const volatile void __iomem *addr) +{ + IO_COND(addr, return inl(port), return readl(addr)); + return 0xffffffff; +} + +static inline void iowrite8(u8 value, volatile void __iomem *addr) +{ + IO_COND(addr, outb(value, port), writeb(value, addr)); +} + +static inline void iowrite16(u16 value, volatile void __iomem *addr) +{ + IO_COND(addr, outw(value, port), writew(value, addr)); +} + +static inline void iowrite32(u32 value, volatile void __iomem *addr) +{ + IO_COND(addr, outl(value, port), writel(value, addr)); +} + +#include <asm-generic/io.h> + +#endif /* _ASM_IO_H */ diff --git a/arch/x86/include/asm/ioapic.h b/arch/x86/include/asm/ioapic.h new file mode 100644 index 0000000..9e004e9 --- /dev/null +++ b/arch/x86/include/asm/ioapic.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot file of the same name + * + * Copyright (C) 2010 coresystems GmbH + */ + +#ifndef __ASM_IOAPIC_H +#define __ASM_IOAPIC_H + +#define IO_APIC_ADDR 0xfec00000 + +/* Direct addressed register */ +#define IO_APIC_INDEX (IO_APIC_ADDR + 0x00) +#define IO_APIC_DATA (IO_APIC_ADDR + 0x10) + +/* Indirect addressed register offset */ +#define IO_APIC_ID 0x00 +#define IO_APIC_VER 0x01 + +/** + * io_apic_read() - Read I/O APIC register + * + * This routine reads I/O APIC indirect addressed register. + * + * @reg: address of indirect addressed register + * @return: register value to read + */ +u32 io_apic_read(u32 reg); + +/** + * io_apic_write() - Write I/O APIC register + * + * This routine writes I/O APIC indirect addressed register. + * + * @reg: address of indirect addressed register + * @val: register value to write + */ +void io_apic_write(u32 reg, u32 val); + +void io_apic_set_id(int ioapic_id); + +#endif diff --git a/arch/x86/include/asm/ioctl.h b/arch/x86/include/asm/ioctl.h new file mode 100644 index 0000000..b279fe0 --- /dev/null +++ b/arch/x86/include/asm/ioctl.h @@ -0,0 +1 @@ +#include <asm-generic/ioctl.h> diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h new file mode 100644 index 0000000..e5c9160 --- /dev/null +++ b/arch/x86/include/asm/irq.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ARCH_IRQ_H_ +#define _ARCH_IRQ_H_ + +#include <dt-bindings/interrupt-router/intel-irq.h> + +/** + * Intel interrupt router configuration mechanism + * + * There are two known ways of Intel interrupt router configuration mechanism + * so far. On most cases, the IRQ routing configuraiton is controlled by PCI + * configuraiton registers on the legacy bridge, normally PCI BDF(0, 31, 0). + * On some newer platforms like BayTrail and Braswell, the IRQ routing is now + * in the IBASE register block where IBASE is memory-mapped. + */ +enum pirq_config { + PIRQ_VIA_PCI, + PIRQ_VIA_IBASE +}; + +struct pirq_regmap { + int link; + int offset; +}; + +/** + * Intel interrupt router control block + * + * Its members' value will be filled in based on device tree's input. + * + * @config: PIRQ_VIA_PCI or PIRQ_VIA_IBASE + * @link_base: link value base number + * @link_num: number of PIRQ links supported + * @has_regmap: has mapping table between PIRQ link and routing register offset + * @irq_mask: IRQ mask reprenting the 16 IRQs in 8259, bit N is 1 means + * IRQ N is available to be routed + * @lb_bdf: irq router's PCI bus/device/function number encoding + * @ibase: IBASE register block base address + * @actl_8bit: ACTL register width is 8-bit (for ICH series chipset) + * @actl_addr: ACTL register offset + */ +struct irq_router { + int config; + u32 link_base; + int link_num; + bool has_regmap; + struct pirq_regmap *regmap; + u16 irq_mask; + u32 bdf; + u32 ibase; + bool actl_8bit; + int actl_addr; +}; + +struct pirq_routing { + int bdf; + int pin; + int pirq; +}; + +#define PIRQ_BITMAP 0xdef8 + +#endif /* _ARCH_IRQ_H_ */ diff --git a/arch/x86/include/asm/ist.h b/arch/x86/include/asm/ist.h new file mode 100644 index 0000000..80b8597 --- /dev/null +++ b/arch/x86/include/asm/ist.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef _ASM_X86_IST_H +#define _ASM_X86_IST_H + +/* + * Include file for the interface to IST BIOS + * Copyright 2002 Andy Grover <andrew.grover@intel.com> + */ + + +#include <linux/types.h> + +struct ist_info { + __u32 signature; + __u32 command; + __u32 event; + __u32 perf_level; +}; + +#ifdef __KERNEL__ + +extern struct ist_info ist_info; + +#endif /* __KERNEL__ */ +#endif /* _ASM_X86_IST_H */ diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h new file mode 100644 index 0000000..78eef6a --- /dev/null +++ b/arch/x86/include/asm/lapic.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot file of same name + * + * Copyright (C) 2014 Google, Inc + */ + +#ifndef _ARCH_ASM_LAPIC_H +#define _ARCH_ASM_LAPIC_H + +#define LAPIC_DEFAULT_BASE 0xfee00000 + +#define LAPIC_ID 0x020 +#define LAPIC_LVR 0x030 + +#define LAPIC_TASKPRI 0x080 +#define LAPIC_TPRI_MASK 0xff + +#define LAPIC_RRR 0x0c0 + +#define LAPIC_SPIV 0x0f0 +#define LAPIC_SPIV_ENABLE 0x100 + +#define LAPIC_ICR 0x300 +#define LAPIC_DEST_SELF 0x40000 +#define LAPIC_DEST_ALLINC 0x80000 +#define LAPIC_DEST_ALLBUT 0xc0000 +#define LAPIC_ICR_RR_MASK 0x30000 +#define LAPIC_ICR_RR_INVALID 0x00000 +#define LAPIC_ICR_RR_INPROG 0x10000 +#define LAPIC_ICR_RR_VALID 0x20000 +#define LAPIC_INT_LEVELTRIG 0x08000 +#define LAPIC_INT_ASSERT 0x04000 +#define LAPIC_ICR_BUSY 0x01000 +#define LAPIC_DEST_LOGICAL 0x00800 +#define LAPIC_DM_FIXED 0x00000 +#define LAPIC_DM_LOWEST 0x00100 +#define LAPIC_DM_SMI 0x00200 +#define LAPIC_DM_REMRD 0x00300 +#define LAPIC_DM_NMI 0x00400 +#define LAPIC_DM_INIT 0x00500 +#define LAPIC_DM_STARTUP 0x00600 +#define LAPIC_DM_EXTINT 0x00700 +#define LAPIC_VECTOR_MASK 0x000ff + +#define LAPIC_ICR2 0x310 +#define GET_LAPIC_DEST_FIELD(x) (((x) >> 24) & 0xff) +#define SET_LAPIC_DEST_FIELD(x) ((x) << 24) + +#define LAPIC_LVT0 0x350 +#define LAPIC_LVT1 0x360 +#define LAPIC_LVT_MASKED (1 << 16) +#define LAPIC_LVT_LEVEL_TRIGGER (1 << 15) +#define LAPIC_LVT_REMOTE_IRR (1 << 14) +#define LAPIC_INPUT_POLARITY (1 << 13) +#define LAPIC_SEND_PENDING (1 << 12) +#define LAPIC_LVT_RESERVED_1 (1 << 11) +#define LAPIC_DELIVERY_MODE_MASK (7 << 8) +#define LAPIC_DELIVERY_MODE_FIXED (0 << 8) +#define LAPIC_DELIVERY_MODE_NMI (4 << 8) +#define LAPIC_DELIVERY_MODE_EXTINT (7 << 8) + +unsigned long lapic_read(unsigned long reg); + +void lapic_write(unsigned long reg, unsigned long v); + +void enable_lapic(void); + +void disable_lapic(void); + +unsigned long lapicid(void); + +int lapic_remote_read(int apicid, int reg, unsigned long *pvalue); + +void lapic_setup(void); + +#endif diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h new file mode 100644 index 0000000..bdca72e --- /dev/null +++ b/arch/x86/include/asm/linkage.h @@ -0,0 +1,6 @@ +#ifndef _ASM_X86_LINKAGE_H +#define _ASM_X86_LINKAGE_H + +#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) + +#endif /* _ASM_X86_LINKAGE_H */ diff --git a/arch/x86/include/asm/lpc_common.h b/arch/x86/include/asm/lpc_common.h new file mode 100644 index 0000000..d462c2e --- /dev/null +++ b/arch/x86/include/asm/lpc_common.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ASM_LPC_COMMON_H +#define __ASM_LPC_COMMON_H + +#define PCH_RCBA_BASE 0xf0 + +#define RC 0x3400 /* 32bit */ +#define GCS 0x3410 /* 32bit */ + +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 + +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */ +#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */ +#define LPC_EN 0x82 /* LPC IF Enables Register */ +#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ +#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ +#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ +#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ +#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ +#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ +#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ +#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ +#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ +#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[3:2] */ +#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ +#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ +#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ +#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ +#define LPC_GENX_DEC(x) (0x84 + 4 * (x)) +#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */ +#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */ +#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */ +#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */ +#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */ +#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */ +#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */ +#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */ + +/** + * lpc_common_early_init() - Set up common LPC init + * + * This sets up the legacy decode areas, GEN_DEC, SPI prefetch and Port80. It + * also puts the RCB in the correct place so that RCB_REG() works. + * + * @dev: LPC device (a child of the PCH) + * @return 0 on success, -ve on error + */ +int lpc_common_early_init(struct udevice *dev); + +int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect); + +#endif diff --git a/arch/x86/include/asm/me_common.h b/arch/x86/include/asm/me_common.h new file mode 100644 index 0000000..49d8862 --- /dev/null +++ b/arch/x86/include/asm/me_common.h @@ -0,0 +1,372 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From Coreboot src/southbridge/intel/bd82x6x/me.h + * + * Coreboot copies lots of code around. Here we are trying to keep the common + * code in a separate file to reduce code duplication and hopefully make it + * easier to add new platform. + * + * Copyright (C) 2016 Google, Inc + */ + +#ifndef __ASM_ME_COMMON_H +#define __ASM_ME_COMMON_H + +#include <linux/compiler.h> +#include <linux/types.h> +#include <pci.h> + +#define MCHBAR_PEI_VERSION 0x5034 + +#define ME_RETRY 100000 /* 1 second */ +#define ME_DELAY 10 /* 10 us */ + +/* + * Management Engine PCI registers + */ + +#define PCI_CPU_MEBASE_L 0x70 /* Set by MRC */ +#define PCI_CPU_MEBASE_H 0x74 /* Set by MRC */ + +#define PCI_ME_HFS 0x40 +#define ME_HFS_CWS_RESET 0 +#define ME_HFS_CWS_INIT 1 +#define ME_HFS_CWS_REC 2 +#define ME_HFS_CWS_NORMAL 5 +#define ME_HFS_CWS_WAIT 6 +#define ME_HFS_CWS_TRANS 7 +#define ME_HFS_CWS_INVALID 8 +#define ME_HFS_STATE_PREBOOT 0 +#define ME_HFS_STATE_M0_UMA 1 +#define ME_HFS_STATE_M3 4 +#define ME_HFS_STATE_M0 5 +#define ME_HFS_STATE_BRINGUP 6 +#define ME_HFS_STATE_ERROR 7 +#define ME_HFS_ERROR_NONE 0 +#define ME_HFS_ERROR_UNCAT 1 +#define ME_HFS_ERROR_IMAGE 3 +#define ME_HFS_ERROR_DEBUG 4 +#define ME_HFS_MODE_NORMAL 0 +#define ME_HFS_MODE_DEBUG 2 +#define ME_HFS_MODE_DIS 3 +#define ME_HFS_MODE_OVER_JMPR 4 +#define ME_HFS_MODE_OVER_MEI 5 +#define ME_HFS_BIOS_DRAM_ACK 1 +#define ME_HFS_ACK_NO_DID 0 +#define ME_HFS_ACK_RESET 1 +#define ME_HFS_ACK_PWR_CYCLE 2 +#define ME_HFS_ACK_S3 3 +#define ME_HFS_ACK_S4 4 +#define ME_HFS_ACK_S5 5 +#define ME_HFS_ACK_GBL_RESET 6 +#define ME_HFS_ACK_CONTINUE 7 + +struct me_hfs { + u32 working_state:4; + u32 mfg_mode:1; + u32 fpt_bad:1; + u32 operation_state:3; + u32 fw_init_complete:1; + u32 ft_bup_ld_flr:1; + u32 update_in_progress:1; + u32 error_code:4; + u32 operation_mode:4; + u32 reserved:4; + u32 boot_options_present:1; + u32 ack_data:3; + u32 bios_msg_ack:4; +} __packed; + +#define PCI_ME_UMA 0x44 + +struct me_uma { + u32 size:6; + u32 reserved_1:10; + u32 valid:1; + u32 reserved_0:14; + u32 set_to_one:1; +} __packed; + +#define PCI_ME_H_GS 0x4c +#define ME_INIT_DONE 1 +#define ME_INIT_STATUS_SUCCESS 0 +#define ME_INIT_STATUS_NOMEM 1 +#define ME_INIT_STATUS_ERROR 2 + +struct me_did { + u32 uma_base:16; + u32 reserved:7; + u32 rapid_start:1; /* Broadwell only */ + u32 status:4; + u32 init_done:4; +} __packed; + +#define PCI_ME_GMES 0x48 +#define ME_GMES_PHASE_ROM 0 +#define ME_GMES_PHASE_BUP 1 +#define ME_GMES_PHASE_UKERNEL 2 +#define ME_GMES_PHASE_POLICY 3 +#define ME_GMES_PHASE_MODULE 4 +#define ME_GMES_PHASE_UNKNOWN 5 +#define ME_GMES_PHASE_HOST 6 + +struct me_gmes { + u32 bist_in_prog:1; + u32 icc_prog_sts:2; + u32 invoke_mebx:1; + u32 cpu_replaced_sts:1; + u32 mbp_rdy:1; + u32 mfs_failure:1; + u32 warm_rst_req_for_df:1; + u32 cpu_replaced_valid:1; + u32 reserved_1:2; + u32 fw_upd_ipu:1; + u32 reserved_2:4; + u32 current_state:8; + u32 current_pmevent:4; + u32 progress_code:4; +} __packed; + +#define PCI_ME_HERES 0xbc +#define PCI_ME_EXT_SHA1 0x00 +#define PCI_ME_EXT_SHA256 0x02 +#define PCI_ME_HER(x) (0xc0+(4*(x))) + +struct me_heres { + u32 extend_reg_algorithm:4; + u32 reserved:26; + u32 extend_feature_present:1; + u32 extend_reg_valid:1; +} __packed; + +/* + * Management Engine MEI registers + */ + +#define MEI_H_CB_WW 0x00 +#define MEI_H_CSR 0x04 +#define MEI_ME_CB_RW 0x08 +#define MEI_ME_CSR_HA 0x0c + +struct mei_csr { + u32 interrupt_enable:1; + u32 interrupt_status:1; + u32 interrupt_generate:1; + u32 ready:1; + u32 reset:1; + u32 reserved:3; + u32 buffer_read_ptr:8; + u32 buffer_write_ptr:8; + u32 buffer_depth:8; +} __packed; + +#define MEI_ADDRESS_CORE 0x01 +#define MEI_ADDRESS_AMT 0x02 +#define MEI_ADDRESS_RESERVED 0x03 +#define MEI_ADDRESS_WDT 0x04 +#define MEI_ADDRESS_MKHI 0x07 +#define MEI_ADDRESS_ICC 0x08 +#define MEI_ADDRESS_THERMAL 0x09 + +#define MEI_HOST_ADDRESS 0 + +struct mei_header { + u32 client_address:8; + u32 host_address:8; + u32 length:9; + u32 reserved:6; + u32 is_complete:1; +} __packed; + +#define MKHI_GROUP_ID_CBM 0x00 +#define MKHI_GROUP_ID_FWCAPS 0x03 +#define MKHI_GROUP_ID_MDES 0x08 +#define MKHI_GROUP_ID_GEN 0xff + +#define MKHI_GET_FW_VERSION 0x02 +#define MKHI_END_OF_POST 0x0c +#define MKHI_FEATURE_OVERRIDE 0x14 + +/* Ivybridge only: */ +#define MKHI_GLOBAL_RESET 0x0b +#define MKHI_FWCAPS_GET_RULE 0x02 +#define MKHI_MDES_ENABLE 0x09 + +/* Broadwell only: */ +#define MKHI_GLOBAL_RESET 0x0b +#define MKHI_FWCAPS_GET_RULE 0x02 +#define MKHI_GROUP_ID_HMRFPO 0x05 +#define MKHI_HMRFPO_LOCK 0x02 +#define MKHI_HMRFPO_LOCK_NOACK 0x05 +#define MKHI_MDES_ENABLE 0x09 +#define MKHI_END_OF_POST_NOACK 0x1a + +struct mkhi_header { + u32 group_id:8; + u32 command:7; + u32 is_response:1; + u32 reserved:8; + u32 result:8; +} __packed; + +struct me_fw_version { + u16 code_minor; + u16 code_major; + u16 code_build_number; + u16 code_hot_fix; + u16 recovery_minor; + u16 recovery_major; + u16 recovery_build_number; + u16 recovery_hot_fix; +} __packed; + + +#define HECI_EOP_STATUS_SUCCESS 0x0 +#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1 + +#define CBM_RR_GLOBAL_RESET 0x01 + +#define GLOBAL_RESET_BIOS_MRC 0x01 +#define GLOBAL_RESET_BIOS_POST 0x02 +#define GLOBAL_RESET_MEBX 0x03 + +struct me_global_reset { + u8 request_origin; + u8 reset_type; +} __packed; + +enum me_bios_path { + ME_NORMAL_BIOS_PATH, + ME_S3WAKE_BIOS_PATH, + ME_ERROR_BIOS_PATH, + ME_RECOVERY_BIOS_PATH, + ME_DISABLE_BIOS_PATH, + ME_FIRMWARE_UPDATE_BIOS_PATH, +}; + +struct __packed mefwcaps_sku { + u32 full_net:1; + u32 std_net:1; + u32 manageability:1; + u32 small_business:1; + u32 l3manageability:1; + u32 intel_at:1; + u32 intel_cls:1; + u32 reserved:3; + u32 intel_mpc:1; + u32 icc_over_clocking:1; + u32 pavp:1; + u32 reserved_1:4; + u32 ipv6:1; + u32 kvm:1; + u32 och:1; + u32 vlan:1; + u32 tls:1; + u32 reserved_4:1; + u32 wlan:1; + u32 reserved_5:8; +}; + +struct __packed tdt_state_flag { + u16 lock_state:1; + u16 authenticate_module:1; + u16 s3authentication:1; + u16 flash_wear_out:1; + u16 flash_variable_security:1; + u16 wwan3gpresent:1; /* ivybridge only */ + u16 wwan3goob:1; /* ivybridge only */ + u16 reserved:9; +}; + +struct __packed tdt_state_info { + u8 state; + u8 last_theft_trigger; + struct tdt_state_flag flags; +}; + +struct __packed mbp_rom_bist_data { + u16 device_id; + u16 fuse_test_flags; + u32 umchid[4]; +}; + +struct __packed mbp_platform_key { + u32 key[8]; +}; + +struct __packed mbp_header { + u32 mbp_size:8; + u32 num_entries:8; + u32 rsvd:16; +}; + +struct __packed mbp_item_header { + u32 app_id:8; + u32 item_id:8; + u32 length:8; + u32 rsvd:8; +}; + +struct __packed me_fwcaps { + u32 id; + u8 length; + struct mefwcaps_sku caps_sku; + u8 reserved[3]; +}; + +/** + * intel_me_status() - Check Intel Management Engine status + * + * @me_dev: Management engine PCI device + */ +void intel_me_status(struct udevice *me_dev); + +/** + * intel_early_me_init() - Early Intel Management Engine init + * + * @me_dev: Management engine PCI device + * @return 0 if OK, -ve on error + */ +int intel_early_me_init(struct udevice *me_dev); + +/** + * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine + * + * @me_dev: Management engine PCI device + * @return UMA size if OK, -EINVAL on error + */ +int intel_early_me_uma_size(struct udevice *me_dev); + +/** + * intel_early_me_init_done() - Complete Intel Management Engine init + * + * @dev: Northbridge device + * @me_dev: Management engine PCI device + * @status: Status result (ME_INIT_...) + * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT + * if ME did not respond + */ +int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, + uint status); + +int intel_me_hsio_version(struct udevice *dev, uint16_t *version, + uint16_t *checksum); + +static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) +{ + u32 dword; + + dm_pci_read_config32(me_dev, offset, &dword); + memcpy(ptr, &dword, sizeof(dword)); +} + +static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) +{ + u32 dword = 0; + + memcpy(&dword, ptr, sizeof(dword)); + dm_pci_write_config32(me_dev, offset, dword); +} +#endif diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h new file mode 100644 index 0000000..4ab7504 --- /dev/null +++ b/arch/x86/include/asm/microcode.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2015 Google, Inc + */ + +#ifndef __ASM_ARCH_MICROCODE_H +#define __ASM_ARCH_MICROCODE_H + +#ifndef __ASSEMBLY__ + +/* This is a declaration for ucode_base in start.S */ +extern u32 ucode_base; +extern u32 ucode_size; + +/** + * microcode_update_intel() - Apply microcode updates + * + * Applies any microcode updates in the device tree. + * + * @return 0 if OK, -EEXIST if the updates were already applied, -ENOENT if + * not updates were found, -EINVAL if an update was invalid + */ +int microcode_update_intel(void); + +/** + * microcode_read_rev() - Read the microcode version + * + * This reads the microcode version of the currently running CPU + * + * @return microcode version number + */ +int microcode_read_rev(void); +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h new file mode 100644 index 0000000..fb59e2f --- /dev/null +++ b/arch/x86/include/asm/mp.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015 Google, Inc + * + * Taken from coreboot file of the same name + */ + +#ifndef _X86_MP_H_ +#define _X86_MP_H_ + +#include <asm/atomic.h> + +typedef int (*mp_callback_t)(struct udevice *cpu, void *arg); + +/* + * A mp_flight_record details a sequence of calls for the APs to perform + * along with the BSP to coordinate sequencing. Each flight record either + * provides a barrier for each AP before calling the callback or the APs + * are allowed to perform the callback without waiting. Regardless, each + * record has the cpus_entered field incremented for each record. When + * the BSP observes that the cpus_entered matches the number of APs + * the bsp_call is called with bsp_arg and upon returning releases the + * barrier allowing the APs to make further progress. + * + * Note that ap_call() and bsp_call() can be NULL. In the NULL case the + * callback will just not be called. + */ +struct mp_flight_record { + atomic_t barrier; + atomic_t cpus_entered; + mp_callback_t ap_call; + void *ap_arg; + mp_callback_t bsp_call; + void *bsp_arg; +} __attribute__((aligned(ARCH_DMA_MINALIGN))); + +#define MP_FLIGHT_RECORD(barrier_, ap_func_, ap_arg_, bsp_func_, bsp_arg_) \ + { \ + .barrier = ATOMIC_INIT(barrier_), \ + .cpus_entered = ATOMIC_INIT(0), \ + .ap_call = ap_func_, \ + .ap_arg = ap_arg_, \ + .bsp_call = bsp_func_, \ + .bsp_arg = bsp_arg_, \ + } + +#define MP_FR_BLOCK_APS(ap_func, ap_arg, bsp_func, bsp_arg) \ + MP_FLIGHT_RECORD(0, ap_func, ap_arg, bsp_func, bsp_arg) + +#define MP_FR_NOBLOCK_APS(ap_func, ap_arg, bsp_func, bsp_arg) \ + MP_FLIGHT_RECORD(1, ap_func, ap_arg, bsp_func, bsp_arg) + +/* + * The mp_params structure provides the arguments to the mp subsystem + * for bringing up APs. + * + * At present this is overkill for U-Boot, but it may make it easier to add + * SMM support. + */ +struct mp_params { + int parallel_microcode_load; + const void *microcode_pointer; + /* Flight plan for APs and BSP */ + struct mp_flight_record *flight_plan; + int num_records; +}; + +/* + * mp_init() will set up the SIPI vector and bring up the APs according to + * mp_params. Each flight record will be executed according to the plan. Note + * that the MP infrastructure uses SMM default area without saving it. It's + * up to the chipset or mainboard to either e820 reserve this area or save this + * region prior to calling mp_init() and restoring it after mp_init returns. + * + * At the time mp_init() is called the MTRR MSRs are mirrored into APs then + * caching is enabled before running the flight plan. + * + * The MP init has the following properties: + * 1. APs are brought up in parallel. + * 2. The ordering of cpu number and APIC ids is not deterministic. + * Therefore, one cannot rely on this property or the order of devices in + * the device tree unless the chipset or mainboard know the APIC ids + * a priori. + * + * mp_init() returns < 0 on error, 0 on success. + */ +int mp_init(struct mp_params *params); + +/* Probes the CPU device */ +int mp_init_cpu(struct udevice *cpu, void *unused); + +/* Set up additional CPUs */ +int x86_mp_init(void); + +#endif /* _X86_MP_H_ */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h new file mode 100644 index 0000000..a25f8f0 --- /dev/null +++ b/arch/x86/include/asm/mpspec.h @@ -0,0 +1,460 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * Adapted from coreboot src/arch/x86/include/arch/smp/mpspec.h + */ + +#ifndef __ASM_MPSPEC_H +#define __ASM_MPSPEC_H + +/* + * Structure definitions for SMP machines following the + * Intel MultiProcessor Specification 1.4 + */ + +#define MPSPEC_V14 4 + +#define MPF_SIGNATURE "_MP_" + +struct mp_floating_table { + char mpf_signature[4]; /* "_MP_" */ + u32 mpf_physptr; /* Configuration table address */ + u8 mpf_length; /* Our length (paragraphs) */ + u8 mpf_spec; /* Specification version */ + u8 mpf_checksum; /* Checksum (makes sum 0) */ + u8 mpf_feature1; /* Predefined or Unique configuration? */ + u8 mpf_feature2; /* Bit7 set for IMCR/PIC */ + u8 mpf_feature3; /* Unused (0) */ + u8 mpf_feature4; /* Unused (0) */ + u8 mpf_feature5; /* Unused (0) */ +}; + +#define MPC_SIGNATURE "PCMP" + +struct mp_config_table { + char mpc_signature[4]; /* "PCMP" */ + u16 mpc_length; /* Size of table */ + u8 mpc_spec; /* Specification version */ + u8 mpc_checksum; /* Checksum (makes sum 0) */ + char mpc_oem[8]; /* OEM ID */ + char mpc_product[12]; /* Product ID */ + u32 mpc_oemptr; /* OEM table address */ + u16 mpc_oemsize; /* OEM table size */ + u16 mpc_entry_count; /* Number of entries in the table */ + u32 mpc_lapic; /* Local APIC address */ + u16 mpe_length; /* Extended table size */ + u8 mpe_checksum; /* Extended table checksum */ + u8 reserved; +}; + +/* Base MP configuration table entry types */ + +enum mp_base_config_entry_type { + MP_PROCESSOR, + MP_BUS, + MP_IOAPIC, + MP_INTSRC, + MP_LINTSRC +}; + +#define MPC_CPU_EN (1 << 0) +#define MPC_CPU_BP (1 << 1) + +struct mpc_config_processor { + u8 mpc_type; + u8 mpc_apicid; + u8 mpc_apicver; + u8 mpc_cpuflag; + u32 mpc_cpusignature; + u32 mpc_cpufeature; + u32 mpc_reserved[2]; +}; + +#define BUSTYPE_CBUS "CBUS " +#define BUSTYPE_CBUSII "CBUSII" +#define BUSTYPE_EISA "EISA " +#define BUSTYPE_FUTURE "FUTURE" +#define BUSTYPE_INTERN "INTERN" +#define BUSTYPE_ISA "ISA " +#define BUSTYPE_MBI "MBI " +#define BUSTYPE_MBII "MBII " +#define BUSTYPE_MCA "MCA " +#define BUSTYPE_MPI "MPI " +#define BUSTYPE_MPSA "MPSA " +#define BUSTYPE_NUBUS "NUBUS " +#define BUSTYPE_PCI "PCI " +#define BUSTYPE_PCMCIA "PCMCIA" +#define BUSTYPE_TC "TC " +#define BUSTYPE_VL "VL " +#define BUSTYPE_VME "VME " +#define BUSTYPE_XPRESS "XPRESS" + +struct mpc_config_bus { + u8 mpc_type; + u8 mpc_busid; + u8 mpc_bustype[6]; +}; + +#define MPC_APIC_USABLE (1 << 0) + +struct mpc_config_ioapic { + u8 mpc_type; + u8 mpc_apicid; + u8 mpc_apicver; + u8 mpc_flags; + u32 mpc_apicaddr; +}; + +enum mp_irq_source_types { + MP_INT, + MP_NMI, + MP_SMI, + MP_EXTINT +}; + +#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 + +#define MP_APIC_ALL 0xff + +struct mpc_config_intsrc { + u8 mpc_type; + u8 mpc_irqtype; + u16 mpc_irqflag; + u8 mpc_srcbus; + u8 mpc_srcbusirq; + u8 mpc_dstapic; + u8 mpc_dstirq; +}; + +struct mpc_config_lintsrc { + u8 mpc_type; + u8 mpc_irqtype; + u16 mpc_irqflag; + u8 mpc_srcbusid; + u8 mpc_srcbusirq; + u8 mpc_destapic; + u8 mpc_destlint; +}; + +/* Extended MP configuration table entry types */ + +enum mp_ext_config_entry_type { + MPE_SYSTEM_ADDRESS_SPACE = 128, + MPE_BUS_HIERARCHY, + MPE_COMPAT_ADDRESS_SPACE +}; + +struct mp_ext_config { + u8 mpe_type; + u8 mpe_length; +}; + +#define ADDRESS_TYPE_IO 0 +#define ADDRESS_TYPE_MEM 1 +#define ADDRESS_TYPE_PREFETCH 2 + +struct mp_ext_system_address_space { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_addr_type; + u32 mpe_addr_base_low; + u32 mpe_addr_base_high; + u32 mpe_addr_length_low; + u32 mpe_addr_length_high; +}; + +#define BUS_SUBTRACTIVE_DECODE (1 << 0) + +struct mp_ext_bus_hierarchy { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_bus_info; + u8 mpe_parent_busid; + u8 reserved[3]; +}; + +#define ADDRESS_RANGE_ADD 0 +#define ADDRESS_RANGE_SUBTRACT 1 + +/* + * X100 - X3FF + * X500 - X7FF + * X900 - XBFF + * XD00 - XFFF + */ +#define RANGE_LIST_IO_ISA 0 +/* + * X3B0 - X3BB + * X3C0 - X3DF + * X7B0 - X7BB + * X7C0 - X7DF + * XBB0 - XBBB + * XBC0 - XBDF + * XFB0 - XFBB + * XFC0 - XCDF + */ +#define RANGE_LIST_IO_VGA 1 + +struct mp_ext_compat_address_space { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_addr_modifier; + u32 mpe_range_list; +}; + +/** + * mp_next_mpc_entry() - Compute MP configuration table end to be used as + * next base table entry start address + * + * This computes the end address of current MP configuration table, without + * counting any extended configuration table entry. + * + * @mc: configuration table header address + * @return: configuration table end address + */ +static inline ulong mp_next_mpc_entry(struct mp_config_table *mc) +{ + return (ulong)mc + mc->mpc_length; +} + +/** + * mp_add_mpc_entry() - Add a base MP configuration table entry + * + * This adds the base MP configuration table entry size with + * added base table entry length and increases entry count by 1. + * + * @mc: configuration table header address + * @length: length of the added table entry + */ +static inline void mp_add_mpc_entry(struct mp_config_table *mc, uint length) +{ + mc->mpc_length += length; + mc->mpc_entry_count++; +} + +/** + * mp_next_mpe_entry() - Compute MP configuration table end to be used as + * next extended table entry start address + * + * This computes the end address of current MP configuration table, + * including any extended configuration table entry. + * + * @mc: configuration table header address + * @return: configuration table end address + */ +static inline ulong mp_next_mpe_entry(struct mp_config_table *mc) +{ + return (ulong)mc + mc->mpc_length + mc->mpe_length; +} + +/** + * mp_add_mpe_entry() - Add an extended MP configuration table entry + * + * This adds the extended MP configuration table entry size with + * added extended table entry length. + * + * @mc: configuration table header address + * @mpe: extended table entry base address + */ +static inline void mp_add_mpe_entry(struct mp_config_table *mc, + struct mp_ext_config *mpe) +{ + mc->mpe_length += mpe->mpe_length; +} + +/** + * mp_write_floating_table() - Write the MP floating table + * + * This writes the MP floating table, and points MP configuration table + * to its end address so that MP configuration table follows immediately + * after the floating table. + * + * @mf: MP floating table base address + * @return: MP configuration table header address + */ +struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf); + +/** + * mp_config_table_init() - Initialize the MP configuration table header + * + * This populates the MP configuration table header with valid bits. + * + * @mc: MP configuration table header address + */ +void mp_config_table_init(struct mp_config_table *mc); + +/** + * mp_write_processor() - Write a processor entry + * + * This writes a processor entry to the configuration table. + * + * @mc: MP configuration table header address + */ +void mp_write_processor(struct mp_config_table *mc); + +/** + * mp_write_bus() - Write a bus entry + * + * This writes a bus entry to the configuration table. + * + * @mc: MP configuration table header address + * @id: bus id + * @bustype: bus type name + */ +void mp_write_bus(struct mp_config_table *mc, int id, const char *bustype); + +/** + * mp_write_ioapic() - Write an I/O APIC entry + * + * This writes an I/O APIC entry to the configuration table. + * + * @mc: MP configuration table header address + * @id: I/O APIC id + * @ver: I/O APIC version + * @apicaddr: I/O APIC address + */ +void mp_write_ioapic(struct mp_config_table *mc, int id, int ver, u32 apicaddr); + +/** + * mp_write_intsrc() - Write an I/O interrupt assignment entry + * + * This writes an I/O interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @irqflag: IRQ flag (level/trigger) + * @srcbus: source bus id where the interrupt comes from + * @srcbusirq: IRQ number mapped on the source bus + * @dstapic: destination I/O APIC id where the interrupt goes to + * @dstirq: destination I/O APIC pin where the interrupt goes to + */ +void mp_write_intsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int dstapic, int dstirq); + +/** + * mp_write_pci_intsrc() - Write a PCI interrupt assignment entry + * + * This writes a PCI interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @srcbus: PCI bus number where the interrupt comes from + * @dev: device number on the PCI bus + * @pin: PCI interrupt pin (INT A/B/C/D) + * @dstapic: destination I/O APIC id where the interrupt goes to + * @dstirq: destination I/O APIC pin where the interrupt goes to + */ +void mp_write_pci_intsrc(struct mp_config_table *mc, int irqtype, + int srcbus, int dev, int pin, int dstapic, int dstirq); + +/** + * mp_write_lintsrc() - Write a local interrupt assignment entry + * + * This writes a local interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @irqflag: IRQ flag (level/trigger) + * @srcbus: PCI bus number where the interrupt comes from + * @srcbusirq: IRQ number mapped on the source bus + * @dstapic: destination local APIC id where the interrupt goes to + * @destlint: destination local APIC pin where the interrupt goes to + */ +void mp_write_lintsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int destapic, int destlint); + + +/** + * mp_write_address_space() - Write a system address space entry + * + * This writes a system address space entry to the configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id for the bus where system address space is mapped + * @addr_type: system address type + * @addr_base_low: starting address low + * @addr_base_high: starting address high + * @addr_length_low: address length low + * @addr_length_high: address length high + */ +void mp_write_address_space(struct mp_config_table *mc, + int busid, int addr_type, + u32 addr_base_low, u32 addr_base_high, + u32 addr_length_low, u32 addr_length_high); + +/** + * mp_write_bus_hierarchy() - Write a bus hierarchy descriptor entry + * + * This writes a bus hierarchy descriptor entry to the configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id + * @bus_info: bit0 indicates if the bus is a subtractive decode bus + * @parent_busid: parent bus id + */ +void mp_write_bus_hierarchy(struct mp_config_table *mc, + int busid, int bus_info, int parent_busid); + +/** + * mp_write_compat_address_space() - Write a compat bus address space entry + * + * This writes a compatibility bus address space modifier entry to the + * configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id + * @addr_modifier: add or subtract to predefined address range list + * @range_list: list of predefined address space ranges + */ +void mp_write_compat_address_space(struct mp_config_table *mc, int busid, + int addr_modifier, u32 range_list); + +/** + * mptable_finalize() - Finalize the MP table + * + * This finalizes the MP table by calculating required checksums. + * + * @mc: MP configuration table header address + * @return: MP table end address + */ +u32 mptable_finalize(struct mp_config_table *mc); + +/** + * mp_determine_pci_dstirq() - Determine PCI device's int pin on the I/O APIC + * + * This determines a PCI device's interrupt pin number on the I/O APIC. + * + * This can be implemented by platform codes to handle specifal cases, which + * do not conform to the normal chipset/board design where PIRQ[A-H] are mapped + * directly to I/O APIC INTPIN#16-23. + * + * @bus: bus number of the pci device + * @dev: device number of the pci device + * @func: function number of the pci device + * @pirq: PIRQ number the PCI device's interrupt pin is routed to + * @return: interrupt pin number on the I/O APIC + */ +int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq); + +/** + * write_mp_table() - Write MP table + * + * This writes MP table at a given address. + * + * @addr: start address to write MP table + * @return: end address of MP table + */ +ulong write_mp_table(ulong addr); + +#endif /* __ASM_MPSPEC_H */ diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h new file mode 100644 index 0000000..d4e56bf --- /dev/null +++ b/arch/x86/include/asm/mrc_common.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ASM_MRC_COMMON_H +#define __ASM_MRC_COMMON_H + +#include <linux/linkage.h> + +/** + * mrc_common_init() - Set up SDRAM + * + * This calls the memory reference code (MRC) to set up SDRAM + * + * @dev: Northbridge device + * @pei_data: Platform-specific data required by the MRC + * @use_asm_linkage: true if the call to MRC requires asmlinkage, false if it + * uses normal U-Boot calling + * @return 0 if OK, -ve on error + */ +int mrc_common_init(struct udevice *dev, void *pei_data, bool use_asm_linkage); + +asmlinkage void sdram_console_tx_byte(unsigned char byte); + +int mrc_locate_spd(struct udevice *dev, int size, const void **spd_datap); + +void report_memory_config(void); + +/** + * mrc_add_memory_area() - Add a new usable memory area to our list + * + * Note: @start and @end must not span the first 4GB boundary + * + * @info: Place to store memory info + * @start: Start of this memory area + * @end: End of this memory area + 1 + */ +int mrc_add_memory_area(struct memory_info *info, uint64_t start, + uint64_t end); + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong mrc_common_board_get_usable_ram_top(ulong total_size); + +void mrc_common_dram_init_banksize(void); + +#endif diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h new file mode 100644 index 0000000..40fda85 --- /dev/null +++ b/arch/x86/include/asm/mrccache.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014 Google, Inc + * Copyright (C) 2015 Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ASM_MRCCACHE_H +#define _ASM_MRCCACHE_H + +#define MRC_DATA_ALIGN 0x1000 +#define MRC_DATA_SIGNATURE (('M' << 0) | ('R' << 8) | \ + ('C' << 16) | ('D'<<24)) + +#define MRC_DATA_HEADER_SIZE 32 + +struct __packed mrc_data_container { + u32 signature; /* "MRCD" */ + u32 data_size; /* Size of the 'data' field */ + u32 checksum; /* IP style checksum */ + u32 reserved; /* For header alignment */ + u8 data[0]; /* Variable size, platform/run time dependent */ +}; + +struct mrc_region { + u32 base; + u32 offset; + u32 length; +}; + +struct udevice; + +/** + * mrccache_find_current() - find the latest MRC cache record + * + * This searches the MRC cache region looking for the latest record to use + * for setting up SDRAM + * + * @entry: Position and size of MRC cache in SPI flash + * @return pointer to latest record, or NULL if none + */ +struct mrc_data_container *mrccache_find_current(struct mrc_region *entry); + +/** + * mrccache_update() - update the MRC cache with a new record + * + * This writes a new record to the end of the MRC cache region. If the new + * record is the same as the latest record then the write is skipped + * + * @sf: SPI flash to write to + * @entry: Position and size of MRC cache in SPI flash + * @cur: Record to write + * @return 0 if updated, -EEXIST if the record is the same as the latest + * record, -EINVAL if the record is not valid, other error if SPI write failed + */ +int mrccache_update(struct udevice *sf, struct mrc_region *entry, + struct mrc_data_container *cur); + +/** + * mrccache_reserve() - reserve MRC data on the stack + * + * This copies MRC data pointed by gd->arch.mrc_output to a new place on the + * stack with length gd->arch.mrc_output_len, and updates gd->arch.mrc_output + * to point to the new place once the migration is done. + * + * This routine should be called by reserve_arch() before U-Boot is relocated + * when MRC cache is enabled. + * + * @return 0 always + */ +int mrccache_reserve(void); + +/** + * mrccache_get_region() - get MRC region on the SPI flash + * + * This gets MRC region whose offset and size are described in the device tree + * as a subnode to the SPI flash. If a non-NULL device pointer is supplied, + * this also probes the SPI flash device and returns its device pointer for + * the caller to use later. + * + * Be careful when calling this routine with a non-NULL device pointer: + * - driver model initialization must be complete + * - calling in the pre-relocation phase may bring some side effects during + * the SPI flash device probe (eg: for SPI controllers on a PCI bus, it + * triggers PCI bus enumeration during which insufficient memory issue + * might be exposed and it causes subsequent SPI flash probe fails). + * + * @devp: Returns pointer to the SPI flash device + * @entry: Position and size of MRC cache in SPI flash + * @return 0 if success, -ENOENT if SPI flash node does not exist in the + * device tree, -EPERM if MRC region subnode does not exist in the device + * tree, -EINVAL if MRC region properties format is incorrect, other error + * if SPI flash probe failed. + */ +int mrccache_get_region(struct udevice **devp, struct mrc_region *entry); + +/** + * mrccache_save() - save MRC data to the SPI flash + * + * This saves MRC data stored previously by gd->arch.mrc_output to a proper + * place within the MRC region on the SPI flash. + * + * @return 0 if saved to SPI flash successfully, other error if failed + */ +int mrccache_save(void); + +/** + * mrccache_spl_save() - Save to the MRC region from SPL + * + * When SPL is used to set up the memory controller we want to save the MRC + * data in SPL to avoid needing to pass it up to U-Boot proper to save. This + * function handles that. + * + * @return 0 if saved to SPI flash successfully, other error if failed + */ +int mrccache_spl_save(void); + +#endif /* _ASM_MRCCACHE_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h new file mode 100644 index 0000000..5bc8b6c --- /dev/null +++ b/arch/x86/include/asm/msr-index.h @@ -0,0 +1,621 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Taken from the linux kernel file of the same name + * + * (C) Copyright 2012 + * Graeme Russ, <graeme.russ@gmail.com> + */ + +#ifndef _ASM_X86_MSR_INDEX_H +#define _ASM_X86_MSR_INDEX_H + +/* CPU model specific register (MSR) numbers */ + +/* x86-64 specific MSRs */ +#define MSR_EFER 0xc0000080 /* extended feature register */ +#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */ +#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ +#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */ +#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ +#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ +#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */ +#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */ + +/* EFER bits: */ +#define _EFER_SCE 0 /* SYSCALL/SYSRET */ +#define _EFER_LME 8 /* Long mode enable */ +#define _EFER_LMA 10 /* Long mode active (read-only) */ +#define _EFER_NX 11 /* No execute enable */ +#define _EFER_SVME 12 /* Enable virtualization */ +#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */ +#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */ + +#define EFER_SCE (1<<_EFER_SCE) +#define EFER_LME (1<<_EFER_LME) +#define EFER_LMA (1<<_EFER_LMA) +#define EFER_NX (1<<_EFER_NX) +#define EFER_SVME (1<<_EFER_SVME) +#define EFER_LMSLE (1<<_EFER_LMSLE) +#define EFER_FFXSR (1<<_EFER_FFXSR) + +/* Intel MSRs. Some also available on other CPUs */ +#define MSR_PIC_MSG_CONTROL 0x2e +#define PLATFORM_INFO_SET_TDP (1 << 29) + +#define MSR_MTRR_CAP_MSR 0x0fe +#define MSR_MTRR_CAP_SMRR (1 << 11) +#define MSR_MTRR_CAP_WC (1 << 10) +#define MSR_MTRR_CAP_FIX (1 << 8) +#define MSR_MTRR_CAP_VCNT 0xff + +#define MSR_IA32_PERFCTR0 0x000000c1 +#define MSR_IA32_PERFCTR1 0x000000c2 +#define MSR_FSB_FREQ 0x000000cd +#define MSR_NHM_PLATFORM_INFO 0x000000ce + +#define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 +#define NHM_C3_AUTO_DEMOTE (1UL << 25) +#define NHM_C1_AUTO_DEMOTE (1UL << 26) +#define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) +#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) +#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) + +#define MSR_BSEL_CR_OVERCLOCK_CONTROL 0x000000cd +#define MSR_PLATFORM_INFO 0x000000ce +#define MSR_PMG_CST_CONFIG_CONTROL 0x000000e2 +#define SINGLE_PCTL (1 << 11) + +#define MSR_MTRRcap 0x000000fe +#define MSR_IA32_BBL_CR_CTL 0x00000119 +#define MSR_IA32_BBL_CR_CTL3 0x0000011e +#define MSR_POWER_MISC 0x00000120 +#define ENABLE_ULFM_AUTOCM_MASK (1 << 2) +#define ENABLE_INDP_AUTOCM_MASK (1 << 3) + +#define MSR_EMULATE_PM_TIMER 0x121 +#define EMULATE_DELAY_OFFSET_VALUE 20 +#define EMULATE_PM_TMR_EN (1 << 16) +#define EMULATE_DELAY_VALUE 0x13 + +#define MSR_IA32_SYSENTER_CS 0x00000174 +#define MSR_IA32_SYSENTER_ESP 0x00000175 +#define MSR_IA32_SYSENTER_EIP 0x00000176 + +#define MSR_IA32_MCG_CAP 0x00000179 +#define MSR_IA32_MCG_STATUS 0x0000017a +#define MSR_IA32_MCG_CTL 0x0000017b + +#define MSR_FLEX_RATIO 0x194 +#define FLEX_RATIO_LOCK (1 << 20) +#define FLEX_RATIO_EN (1 << 16) +/* This is burst mode BIT 38 in IA32_MISC_ENABLE MSR at offset 1A0h */ +#define BURST_MODE_DISABLE (1 << 6) + +#define MSR_IA32_MISC_ENABLE 0x000001a0 + +/* MISC_ENABLE bits: architectural */ +#define MISC_ENABLE_FAST_STRING BIT_ULL(0) +#define MISC_ENABLE_TCC BIT_ULL(1) +#define MISC_DISABLE_TURBO BIT_ULL(6) +#define MISC_ENABLE_EMON BIT_ULL(7) +#define MISC_ENABLE_BTS_UNAVAIL BIT_ULL(11) +#define MISC_ENABLE_PEBS_UNAVAIL BIT_ULL(12) +#define MISC_ENABLE_ENHANCED_SPEEDSTEP BIT_ULL(16) +#define MISC_ENABLE_MWAIT BIT_ULL(18) +#define MISC_ENABLE_LIMIT_CPUID BIT_ULL(22) +#define MISC_ENABLE_XTPR_DISABLE BIT_ULL(23) +#define MISC_ENABLE_XD_DISABLE BIT_ULL(34) + +/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ +#define MISC_ENABLE_X87_COMPAT BIT_ULL(2) +#define MISC_ENABLE_TM1 BIT_ULL(3) +#define MISC_ENABLE_SPLIT_LOCK_DISABLE BIT_ULL(4) +#define MISC_ENABLE_L3CACHE_DISABLE BIT_ULL(6) +#define MISC_ENABLE_SUPPRESS_LOCK BIT_ULL(8) +#define MISC_ENABLE_PREFETCH_DISABLE BIT_ULL(9) +#define MISC_ENABLE_FERR BIT_ULL(10) +#define MISC_ENABLE_FERR_MULTIPLEX BIT_ULL(10) +#define MISC_ENABLE_TM2 BIT_ULL(13) +#define MISC_ENABLE_ADJ_PREF_DISABLE BIT_ULL(19) +#define MISC_ENABLE_SPEEDSTEP_LOCK BIT_ULL(20) +#define MISC_ENABLE_L1D_CONTEXT BIT_ULL(24) +#define MISC_ENABLE_DCU_PREF_DISABLE BIT_ULL(37) +#define MISC_ENABLE_TURBO_DISABLE BIT_ULL(38) +#define MISC_ENABLE_IP_PREF_DISABLE BIT_ULL(39) + +#define MSR_TEMPERATURE_TARGET 0x1a2 +#define MSR_PREFETCH_CTL 0x1a4 +#define PREFETCH_L1_DISABLE (1 << 0) +#define PREFETCH_L2_DISABLE (1 << 2) +#define MSR_OFFCORE_RSP_0 0x000001a6 +#define MSR_OFFCORE_RSP_1 0x000001a7 +#define MSR_MISC_PWR_MGMT 0x1aa +#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) +#define MSR_TURBO_RATIO_LIMIT 0x000001ad + +#define MSR_IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 + +#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 + +#define PACKAGE_THERM_STATUS_PROCHOT BIT(0) +#define PACKAGE_THERM_STATUS_POWER_LIMIT BIT(10) + +#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2 + +#define PACKAGE_THERM_INT_HIGH_ENABLE BIT(0) +#define PACKAGE_THERM_INT_LOW_ENABLE BIT(1) +#define PACKAGE_THERM_INT_PLN_ENABLE BIT(24) + +#define MSR_LBR_SELECT 0x000001c8 +#define MSR_LBR_TOS 0x000001c9 +#define MSR_IA32_PLATFORM_DCA_CAP 0x1f8 +#define MSR_POWER_CTL 0x000001fc +#define MSR_LBR_NHM_FROM 0x00000680 +#define MSR_LBR_NHM_TO 0x000006c0 +#define MSR_LBR_CORE_FROM 0x00000040 +#define MSR_LBR_CORE_TO 0x00000060 + +#define MSR_IA32_PEBS_ENABLE 0x000003f1 +#define MSR_IA32_DS_AREA 0x00000600 +#define MSR_IA32_PERF_CAPABILITIES 0x00000345 +#define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6 + +#define MSR_MTRRfix64K_00000 0x00000250 +#define MSR_MTRRfix16K_80000 0x00000258 +#define MSR_MTRRfix16K_A0000 0x00000259 +#define MSR_MTRRfix4K_C0000 0x00000268 +#define MSR_MTRRfix4K_C8000 0x00000269 +#define MSR_MTRRfix4K_D0000 0x0000026a +#define MSR_MTRRfix4K_D8000 0x0000026b +#define MSR_MTRRfix4K_E0000 0x0000026c +#define MSR_MTRRfix4K_E8000 0x0000026d +#define MSR_MTRRfix4K_F0000 0x0000026e +#define MSR_MTRRfix4K_F8000 0x0000026f +#define MSR_MTRRdefType 0x000002ff + +#define MSR_IA32_CR_PAT 0x00000277 + +#define MSR_IA32_DEBUGCTLMSR 0x000001d9 +#define MSR_IA32_LASTBRANCHFROMIP 0x000001db +#define MSR_IA32_LASTBRANCHTOIP 0x000001dc +#define MSR_IA32_LASTINTFROMIP 0x000001dd +#define MSR_IA32_LASTINTTOIP 0x000001de + +/* DEBUGCTLMSR bits (others vary by model): */ +#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ +/* single-step on branches */ +#define DEBUGCTLMSR_BTF (1UL << 1) +#define DEBUGCTLMSR_TR (1UL << 6) +#define DEBUGCTLMSR_BTS (1UL << 7) +#define DEBUGCTLMSR_BTINT (1UL << 8) +#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9) +#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) +#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) + +#define MSR_IA32_POWER_CTL 0x000001fc + +#define MSR_IA32_MC0_CTL 0x00000400 +#define MSR_IA32_MC0_STATUS 0x00000401 +#define MSR_IA32_MC0_ADDR 0x00000402 +#define MSR_IA32_MC0_MISC 0x00000403 + +/* C-state Residency Counters */ +#define MSR_PKG_C3_RESIDENCY 0x000003f8 +#define MSR_PKG_C6_RESIDENCY 0x000003f9 +#define MSR_PKG_C7_RESIDENCY 0x000003fa +#define MSR_CORE_C3_RESIDENCY 0x000003fc +#define MSR_CORE_C6_RESIDENCY 0x000003fd +#define MSR_CORE_C7_RESIDENCY 0x000003fe +#define MSR_PKG_C2_RESIDENCY 0x0000060d +#define MSR_PKG_C8_RESIDENCY 0x00000630 +#define MSR_PKG_C9_RESIDENCY 0x00000631 +#define MSR_PKG_C10_RESIDENCY 0x00000632 + +/* Run Time Average Power Limiting (RAPL) Interface */ + +#define MSR_PKG_POWER_SKU_UNIT 0x00000606 + +#define MSR_C_STATE_LATENCY_CONTROL_0 0x60a +#define MSR_C_STATE_LATENCY_CONTROL_1 0x60b +#define MSR_C_STATE_LATENCY_CONTROL_2 0x60c +#define MSR_C_STATE_LATENCY_CONTROL_3 0x633 +#define MSR_C_STATE_LATENCY_CONTROL_4 0x634 +#define MSR_C_STATE_LATENCY_CONTROL_5 0x635 +#define IRTL_VALID (1 << 15) +#define IRTL_1_NS (0 << 10) +#define IRTL_32_NS (1 << 10) +#define IRTL_1024_NS (2 << 10) +#define IRTL_32768_NS (3 << 10) +#define IRTL_1048576_NS (4 << 10) +#define IRTL_33554432_NS (5 << 10) +#define IRTL_RESPONSE_MASK (0x3ff) + +#define MSR_PKG_POWER_LIMIT 0x00000610 +/* long duration in low dword, short duration in high dword */ +#define PKG_POWER_LIMIT_MASK 0x7fff +#define PKG_POWER_LIMIT_EN (1 << 15) +#define PKG_POWER_LIMIT_CLAMP (1 << 16) +#define PKG_POWER_LIMIT_TIME_SHIFT 17 +#define PKG_POWER_LIMIT_TIME_MASK 0x7f + +#define MSR_PKG_ENERGY_STATUS 0x00000611 +#define MSR_PKG_PERF_STATUS 0x00000613 +#define MSR_PKG_POWER_INFO 0x00000614 + +#define MSR_DRAM_POWER_LIMIT 0x00000618 +#define MSR_DRAM_ENERGY_STATUS 0x00000619 +#define MSR_DRAM_PERF_STATUS 0x0000061b +#define MSR_DRAM_POWER_INFO 0x0000061c + +#define MSR_PP0_POWER_LIMIT 0x00000638 +#define MSR_PP0_ENERGY_STATUS 0x00000639 +#define MSR_PP0_POLICY 0x0000063a +#define MSR_PP0_PERF_STATUS 0x0000063b + +#define MSR_PP1_POWER_LIMIT 0x00000640 +#define MSR_PP1_ENERGY_STATUS 0x00000641 +#define MSR_PP1_POLICY 0x00000642 +#define MSR_CONFIG_TDP_NOMINAL 0x00000648 +#define MSR_TURBO_ACTIVATION_RATIO 0x0000064c +#define MSR_CORE_C1_RES 0x00000660 +#define MSR_IACORE_RATIOS 0x0000066a +#define MSR_IACORE_TURBO_RATIOS 0x0000066c +#define MSR_IACORE_VIDS 0x0000066b +#define MSR_IACORE_TURBO_VIDS 0x0000066d +#define MSR_PKG_TURBO_CFG1 0x00000670 +#define MSR_CPU_TURBO_WKLD_CFG1 0x00000671 +#define MSR_CPU_TURBO_WKLD_CFG2 0x00000672 +#define MSR_CPU_THERM_CFG1 0x00000673 +#define MSR_CPU_THERM_CFG2 0x00000674 +#define MSR_CPU_THERM_SENS_CFG 0x00000675 + +#define MSR_AMD64_MC0_MASK 0xc0010044 + +#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) +#define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x)) +#define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x)) +#define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x)) + +#define MSR_AMD64_MCx_MASK(x) (MSR_AMD64_MC0_MASK + (x)) + +/* These are consecutive and not in the normal 4er MCE bank block */ +#define MSR_IA32_MC0_CTL2 0x00000280 +#define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x)) + +#define MSR_P6_PERFCTR0 0x000000c1 +#define MSR_P6_PERFCTR1 0x000000c2 +#define MSR_P6_EVNTSEL0 0x00000186 +#define MSR_P6_EVNTSEL1 0x00000187 + +#define MSR_KNC_PERFCTR0 0x00000020 +#define MSR_KNC_PERFCTR1 0x00000021 +#define MSR_KNC_EVNTSEL0 0x00000028 +#define MSR_KNC_EVNTSEL1 0x00000029 + +/* Alternative perfctr range with full access. */ +#define MSR_IA32_PMC0 0x000004c1 + +/* AMD64 MSRs. Not complete. See the architecture manual for a more + complete list. */ + +#define MSR_AMD64_PATCH_LEVEL 0x0000008b +#define MSR_AMD64_TSC_RATIO 0xc0000104 +#define MSR_AMD64_NB_CFG 0xc001001f +#define MSR_AMD64_PATCH_LOADER 0xc0010020 +#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 +#define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_LS_CFG 0xc0011020 +#define MSR_AMD64_DC_CFG 0xc0011022 +#define MSR_AMD64_BU_CFG2 0xc001102a +#define MSR_AMD64_IBSFETCHCTL 0xc0011030 +#define MSR_AMD64_IBSFETCHLINAD 0xc0011031 +#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 +#define MSR_AMD64_IBSFETCH_REG_COUNT 3 +#define MSR_AMD64_IBSFETCH_REG_MASK ((1UL<<MSR_AMD64_IBSFETCH_REG_COUNT)-1) +#define MSR_AMD64_IBSOPCTL 0xc0011033 +#define MSR_AMD64_IBSOPRIP 0xc0011034 +#define MSR_AMD64_IBSOPDATA 0xc0011035 +#define MSR_AMD64_IBSOPDATA2 0xc0011036 +#define MSR_AMD64_IBSOPDATA3 0xc0011037 +#define MSR_AMD64_IBSDCLINAD 0xc0011038 +#define MSR_AMD64_IBSDCPHYSAD 0xc0011039 +#define MSR_AMD64_IBSOP_REG_COUNT 7 +#define MSR_AMD64_IBSOP_REG_MASK ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1) +#define MSR_AMD64_IBSCTL 0xc001103a +#define MSR_AMD64_IBSBRTARGET 0xc001103b +#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ + +/* Fam 16h MSRs */ +#define MSR_F16H_L2I_PERF_CTL 0xc0010230 +#define MSR_F16H_L2I_PERF_CTR 0xc0010231 + +/* Fam 15h MSRs */ +#define MSR_F15H_PERF_CTL 0xc0010200 +#define MSR_F15H_PERF_CTR 0xc0010201 +#define MSR_F15H_NB_PERF_CTL 0xc0010240 +#define MSR_F15H_NB_PERF_CTR 0xc0010241 + +/* Fam 10h MSRs */ +#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 +#define FAM10H_MMIO_CONF_ENABLE (1<<0) +#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf +#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 +#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL +#define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c + +/* K8 MSRs */ +#define MSR_K8_TOP_MEM1 0xc001001a +#define MSR_K8_TOP_MEM2 0xc001001d +#define MSR_K8_SYSCFG 0xc0010010 +#define MSR_K8_INT_PENDING_MSG 0xc0010055 +/* C1E active bits in int pending message */ +#define K8_INTP_C1E_ACTIVE_MASK 0x18000000 +#define MSR_K8_TSEG_ADDR 0xc0010112 +#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ +#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ +#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ + +/* K7 MSRs */ +#define MSR_K7_EVNTSEL0 0xc0010000 +#define MSR_K7_PERFCTR0 0xc0010004 +#define MSR_K7_EVNTSEL1 0xc0010001 +#define MSR_K7_PERFCTR1 0xc0010005 +#define MSR_K7_EVNTSEL2 0xc0010002 +#define MSR_K7_PERFCTR2 0xc0010006 +#define MSR_K7_EVNTSEL3 0xc0010003 +#define MSR_K7_PERFCTR3 0xc0010007 +#define MSR_K7_CLK_CTL 0xc001001b +#define MSR_K7_HWCR 0xc0010015 +#define MSR_K7_FID_VID_CTL 0xc0010041 +#define MSR_K7_FID_VID_STATUS 0xc0010042 + +/* K6 MSRs */ +#define MSR_K6_WHCR 0xc0000082 +#define MSR_K6_UWCCR 0xc0000085 +#define MSR_K6_EPMR 0xc0000086 +#define MSR_K6_PSOR 0xc0000087 +#define MSR_K6_PFIR 0xc0000088 + +/* Centaur-Hauls/IDT defined MSRs. */ +#define MSR_IDT_FCR1 0x00000107 +#define MSR_IDT_FCR2 0x00000108 +#define MSR_IDT_FCR3 0x00000109 +#define MSR_IDT_FCR4 0x0000010a + +#define MSR_IDT_MCR0 0x00000110 +#define MSR_IDT_MCR1 0x00000111 +#define MSR_IDT_MCR2 0x00000112 +#define MSR_IDT_MCR3 0x00000113 +#define MSR_IDT_MCR4 0x00000114 +#define MSR_IDT_MCR5 0x00000115 +#define MSR_IDT_MCR6 0x00000116 +#define MSR_IDT_MCR7 0x00000117 +#define MSR_IDT_MCR_CTRL 0x00000120 + +/* VIA Cyrix defined MSRs*/ +#define MSR_VIA_FCR 0x00001107 +#define MSR_VIA_LONGHAUL 0x0000110a +#define MSR_VIA_RNG 0x0000110b +#define MSR_VIA_BCR2 0x00001147 + +/* Transmeta defined MSRs */ +#define MSR_TMTA_LONGRUN_CTRL 0x80868010 +#define MSR_TMTA_LONGRUN_FLAGS 0x80868011 +#define MSR_TMTA_LRTI_READOUT 0x80868018 +#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a + +/* Intel defined MSRs. */ +#define MSR_IA32_P5_MC_ADDR 0x00000000 +#define MSR_IA32_P5_MC_TYPE 0x00000001 +#define MSR_IA32_TSC 0x00000010 +#define MSR_IA32_PLATFORM_ID 0x00000017 +#define MSR_IA32_EBL_CR_POWERON 0x0000002a +#define MSR_EBC_FREQUENCY_ID 0x0000002c +#define MSR_SMI_COUNT 0x00000034 +#define MSR_IA32_FEATURE_CONTROL 0x0000003a +#define MSR_IA32_TSC_ADJUST 0x0000003b + +#define FEATURE_CONTROL_LOCKED (1<<0) +#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) +#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) + +#define MSR_IA32_APICBASE 0x0000001b +#define MSR_IA32_APICBASE_BSP (1<<8) +#define MSR_IA32_APICBASE_ENABLE (1<<11) +#define MSR_IA32_APICBASE_BASE (0xfffff<<12) + +#define MSR_IA32_TSCDEADLINE 0x000006e0 + +#define MSR_IA32_UCODE_WRITE 0x00000079 +#define MSR_IA32_UCODE_REV 0x0000008b + +#define MSR_IA32_PERF_STATUS 0x00000198 +#define MSR_IA32_PERF_CTL 0x00000199 +#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 +#define MSR_AMD_PERF_STATUS 0xc0010063 +#define MSR_AMD_PERF_CTL 0xc0010062 + +#define MSR_PMG_CST_CONFIG_CTL 0x000000e2 +#define MSR_PMG_IO_CAPTURE_ADR 0x000000e4 +#define MSR_IA32_MPERF 0x000000e7 +#define MSR_IA32_APERF 0x000000e8 + +#define MSR_IA32_THERM_CONTROL 0x0000019a +#define MSR_IA32_THERM_INTERRUPT 0x0000019b + +#define THERM_INT_HIGH_ENABLE (1 << 0) +#define THERM_INT_LOW_ENABLE (1 << 1) +#define THERM_INT_PLN_ENABLE (1 << 24) + +#define MSR_IA32_THERM_STATUS 0x0000019c + +#define THERM_STATUS_PROCHOT (1 << 0) +#define THERM_STATUS_POWER_LIMIT (1 << 10) + +#define MSR_THERM2_CTL 0x0000019d + +#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16) + +#define MSR_IA32_TSC_DEADLINE 0x000006E0 + +/* P4/Xeon+ specific */ +#define MSR_IA32_MCG_EAX 0x00000180 +#define MSR_IA32_MCG_EBX 0x00000181 +#define MSR_IA32_MCG_ECX 0x00000182 +#define MSR_IA32_MCG_EDX 0x00000183 +#define MSR_IA32_MCG_ESI 0x00000184 +#define MSR_IA32_MCG_EDI 0x00000185 +#define MSR_IA32_MCG_EBP 0x00000186 +#define MSR_IA32_MCG_ESP 0x00000187 +#define MSR_IA32_MCG_EFLAGS 0x00000188 +#define MSR_IA32_MCG_EIP 0x00000189 +#define MSR_IA32_MCG_RESERVED 0x0000018a + +/* Pentium IV performance counter MSRs */ +#define MSR_P4_BPU_PERFCTR0 0x00000300 +#define MSR_P4_BPU_PERFCTR1 0x00000301 +#define MSR_P4_BPU_PERFCTR2 0x00000302 +#define MSR_P4_BPU_PERFCTR3 0x00000303 +#define MSR_P4_MS_PERFCTR0 0x00000304 +#define MSR_P4_MS_PERFCTR1 0x00000305 +#define MSR_P4_MS_PERFCTR2 0x00000306 +#define MSR_P4_MS_PERFCTR3 0x00000307 +#define MSR_P4_FLAME_PERFCTR0 0x00000308 +#define MSR_P4_FLAME_PERFCTR1 0x00000309 +#define MSR_P4_FLAME_PERFCTR2 0x0000030a +#define MSR_P4_FLAME_PERFCTR3 0x0000030b +#define MSR_P4_IQ_PERFCTR0 0x0000030c +#define MSR_P4_IQ_PERFCTR1 0x0000030d +#define MSR_P4_IQ_PERFCTR2 0x0000030e +#define MSR_P4_IQ_PERFCTR3 0x0000030f +#define MSR_P4_IQ_PERFCTR4 0x00000310 +#define MSR_P4_IQ_PERFCTR5 0x00000311 +#define MSR_P4_BPU_CCCR0 0x00000360 +#define MSR_P4_BPU_CCCR1 0x00000361 +#define MSR_P4_BPU_CCCR2 0x00000362 +#define MSR_P4_BPU_CCCR3 0x00000363 +#define MSR_P4_MS_CCCR0 0x00000364 +#define MSR_P4_MS_CCCR1 0x00000365 +#define MSR_P4_MS_CCCR2 0x00000366 +#define MSR_P4_MS_CCCR3 0x00000367 +#define MSR_P4_FLAME_CCCR0 0x00000368 +#define MSR_P4_FLAME_CCCR1 0x00000369 +#define MSR_P4_FLAME_CCCR2 0x0000036a +#define MSR_P4_FLAME_CCCR3 0x0000036b +#define MSR_P4_IQ_CCCR0 0x0000036c +#define MSR_P4_IQ_CCCR1 0x0000036d +#define MSR_P4_IQ_CCCR2 0x0000036e +#define MSR_P4_IQ_CCCR3 0x0000036f +#define MSR_P4_IQ_CCCR4 0x00000370 +#define MSR_P4_IQ_CCCR5 0x00000371 +#define MSR_P4_ALF_ESCR0 0x000003ca +#define MSR_P4_ALF_ESCR1 0x000003cb +#define MSR_P4_BPU_ESCR0 0x000003b2 +#define MSR_P4_BPU_ESCR1 0x000003b3 +#define MSR_P4_BSU_ESCR0 0x000003a0 +#define MSR_P4_BSU_ESCR1 0x000003a1 +#define MSR_P4_CRU_ESCR0 0x000003b8 +#define MSR_P4_CRU_ESCR1 0x000003b9 +#define MSR_P4_CRU_ESCR2 0x000003cc +#define MSR_P4_CRU_ESCR3 0x000003cd +#define MSR_P4_CRU_ESCR4 0x000003e0 +#define MSR_P4_CRU_ESCR5 0x000003e1 +#define MSR_P4_DAC_ESCR0 0x000003a8 +#define MSR_P4_DAC_ESCR1 0x000003a9 +#define MSR_P4_FIRM_ESCR0 0x000003a4 +#define MSR_P4_FIRM_ESCR1 0x000003a5 +#define MSR_P4_FLAME_ESCR0 0x000003a6 +#define MSR_P4_FLAME_ESCR1 0x000003a7 +#define MSR_P4_FSB_ESCR0 0x000003a2 +#define MSR_P4_FSB_ESCR1 0x000003a3 +#define MSR_P4_IQ_ESCR0 0x000003ba +#define MSR_P4_IQ_ESCR1 0x000003bb +#define MSR_P4_IS_ESCR0 0x000003b4 +#define MSR_P4_IS_ESCR1 0x000003b5 +#define MSR_P4_ITLB_ESCR0 0x000003b6 +#define MSR_P4_ITLB_ESCR1 0x000003b7 +#define MSR_P4_IX_ESCR0 0x000003c8 +#define MSR_P4_IX_ESCR1 0x000003c9 +#define MSR_P4_MOB_ESCR0 0x000003aa +#define MSR_P4_MOB_ESCR1 0x000003ab +#define MSR_P4_MS_ESCR0 0x000003c0 +#define MSR_P4_MS_ESCR1 0x000003c1 +#define MSR_P4_PMH_ESCR0 0x000003ac +#define MSR_P4_PMH_ESCR1 0x000003ad +#define MSR_P4_RAT_ESCR0 0x000003bc +#define MSR_P4_RAT_ESCR1 0x000003bd +#define MSR_P4_SAAT_ESCR0 0x000003ae +#define MSR_P4_SAAT_ESCR1 0x000003af +#define MSR_P4_SSU_ESCR0 0x000003be +#define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */ + +#define MSR_P4_TBPU_ESCR0 0x000003c2 +#define MSR_P4_TBPU_ESCR1 0x000003c3 +#define MSR_P4_TC_ESCR0 0x000003c4 +#define MSR_P4_TC_ESCR1 0x000003c5 +#define MSR_P4_U2L_ESCR0 0x000003b0 +#define MSR_P4_U2L_ESCR1 0x000003b1 + +#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2 + +/* Intel Core-based CPU performance counters */ +#define MSR_CORE_PERF_FIXED_CTR0 0x00000309 +#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a +#define MSR_CORE_PERF_FIXED_CTR2 0x0000030b +#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d +#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e +#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f +#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 + +/* Geode defined MSRs */ +#define MSR_GEODE_BUSCONT_CONF0 0x00001900 + +/* Intel VT MSRs */ +#define MSR_IA32_VMX_BASIC 0x00000480 +#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 +#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 +#define MSR_IA32_VMX_EXIT_CTLS 0x00000483 +#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 +#define MSR_IA32_VMX_MISC 0x00000485 +#define MSR_IA32_VMX_CR0_FIXED0 0x00000486 +#define MSR_IA32_VMX_CR0_FIXED1 0x00000487 +#define MSR_IA32_VMX_CR4_FIXED0 0x00000488 +#define MSR_IA32_VMX_CR4_FIXED1 0x00000489 +#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a +#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b +#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c +#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048d +#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e +#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048f +#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 +#define MSR_IA32_VMX_VMFUNC 0x00000491 + +#define MSR_IA32_PQR_ASSOC 0xc8f +/* MSR bits 33:32 encode slot number 0-3 */ +#define MSR_IA32_PQR_ASSOC_MASK (1 << 0 | 1 << 1) + +#define MSR_L2_QOS_MASK(reg) (0xd10 + (reg)) + +/* VMX_BASIC bits and bitmasks */ +#define VMX_BASIC_VMCS_SIZE_SHIFT 32 +#define VMX_BASIC_64 0x0001000000000000LLU +#define VMX_BASIC_MEM_TYPE_SHIFT 50 +#define VMX_BASIC_MEM_TYPE_MASK 0x003c000000000000LLU +#define VMX_BASIC_MEM_TYPE_WB 6LLU +#define VMX_BASIC_INOUT 0x0040000000000000LLU + +/* MSR_IA32_VMX_MISC bits */ +#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29) +#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F +/* AMD-V MSRs */ + +#define MSR_VM_CR 0xc0010114 +#define MSR_VM_IGNNE 0xc0010115 +#define MSR_VM_HSAVE_PA 0xc0010117 + +#endif /* _ASM_X86_MSR_INDEX_H */ diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h new file mode 100644 index 0000000..3e613de --- /dev/null +++ b/arch/x86/include/asm/msr.h @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Taken from the linux kernel file of the same name + * + * (C) Copyright 2012 + * Graeme Russ, <graeme.russ@gmail.com> + */ + +#ifndef _ASM_X86_MSR_H +#define _ASM_X86_MSR_H + +#include <asm/msr-index.h> + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8]) +#define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8]) + +#ifdef __KERNEL__ + +#include <linux/errno.h> + +struct msr { + union { + struct { + u32 l; + u32 h; + }; + u64 q; + }; +}; + +struct msr_info { + u32 msr_no; + struct msr reg; + struct msr *msrs; + int err; +}; + +struct msr_regs_info { + u32 *regs; + int err; +}; + +static inline unsigned long long native_read_tscp(unsigned int *aux) +{ + unsigned long low, high; + asm volatile(".byte 0x0f,0x01,0xf9" + : "=a" (low), "=d" (high), "=c" (*aux)); + return low | ((u64)high << 32); +} + +/* + * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A" + * constraint has different meanings. For i386, "A" means exactly + * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead, + * it means rax *or* rdx. + */ +#ifdef CONFIG_X86_64 +#define DECLARE_ARGS(val, low, high) unsigned low, high +#define EAX_EDX_VAL(val, low, high) ((low) | ((u64)(high) << 32)) +#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_ARGS(val, low, high) "A" (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +static inline __attribute__((no_instrument_function)) + unsigned long long native_read_msr(unsigned int msr) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr)); + return EAX_EDX_VAL(val, low, high); +} + +static inline void native_write_msr(unsigned int msr, + unsigned low, unsigned high) +{ + asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory"); +} + +extern unsigned long long native_read_tsc(void); + +extern int native_rdmsr_safe_regs(u32 regs[8]); +extern int native_wrmsr_safe_regs(u32 regs[8]); + +static inline unsigned long long native_read_pmc(int counter) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter)); + return EAX_EDX_VAL(val, low, high); +} + +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt.h> +#else +#include <errno.h> +/* + * Access to machine-specific registers (available on 586 and better only) + * Note: the rd* operations modify the parameters directly (without using + * pointer indirection), this allows gcc to optimize better + */ + +#define rdmsr(msr, val1, val2) \ +do { \ + u64 __val = native_read_msr((msr)); \ + (void)((val1) = (u32)__val); \ + (void)((val2) = (u32)(__val >> 32)); \ +} while (0) + +static inline void wrmsr(unsigned msr, unsigned low, unsigned high) +{ + native_write_msr(msr, low, high); +} + +#define rdmsrl(msr, val) \ + ((val) = native_read_msr((msr))) + +#define wrmsrl(msr, val) \ + native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32)) + +static inline void msr_clrsetbits_64(unsigned msr, u64 clear, u64 set) +{ + u64 val; + + val = native_read_msr(msr); + val &= ~clear; + val |= set; + wrmsrl(msr, val); +} + +static inline void msr_setbits_64(unsigned msr, u64 set) +{ + u64 val; + + val = native_read_msr(msr); + val |= set; + wrmsrl(msr, val); +} + +static inline void msr_clrbits_64(unsigned msr, u64 clear) +{ + u64 val; + + val = native_read_msr(msr); + val &= ~clear; + wrmsrl(msr, val); +} + +/* rdmsr with exception handling */ +#define rdmsr_safe(msr, p1, p2) \ +({ \ + int __err; \ + u64 __val = native_read_msr_safe((msr), &__err); \ + (*p1) = (u32)__val; \ + (*p2) = (u32)(__val >> 32); \ + __err; \ +}) + +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = native_rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return native_wrmsr_safe_regs(gprs); +} + +static inline int rdmsr_safe_regs(u32 regs[8]) +{ + return native_rdmsr_safe_regs(regs); +} + +static inline int wrmsr_safe_regs(u32 regs[8]) +{ + return native_wrmsr_safe_regs(regs); +} + +typedef struct msr_t { + uint32_t lo; + uint32_t hi; +} msr_t; + +static inline struct msr_t msr_read(unsigned msr_num) +{ + struct msr_t msr; + + rdmsr(msr_num, msr.lo, msr.hi); + + return msr; +} + +static inline void msr_write(unsigned msr_num, msr_t msr) +{ + wrmsr(msr_num, msr.lo, msr.hi); +} + +#define rdtscl(low) \ + ((low) = (u32)__native_read_tsc()) + +#define rdtscll(val) \ + ((val) = __native_read_tsc()) + +#define rdpmc(counter, low, high) \ +do { \ + u64 _l = native_read_pmc((counter)); \ + (low) = (u32)_l; \ + (high) = (u32)(_l >> 32); \ +} while (0) + +#define rdtscp(low, high, aux) \ +do { \ + unsigned long long _val = native_read_tscp(&(aux)); \ + (low) = (u32)_val; \ + (high) = (u32)(_val >> 32); \ +} while (0) + +#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) + +#endif /* !CONFIG_PARAVIRT */ + + +#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ + (u32)((val) >> 32)) + +#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) + +#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0) + +struct msr *msrs_alloc(void); +void msrs_free(struct msr *msrs); + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_X86_MSR_H */ diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h new file mode 100644 index 0000000..6726172 --- /dev/null +++ b/arch/x86/include/asm/mtrr.h @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2014 Google, Inc + * + * From Coreboot file of the same name + */ + +#ifndef _ASM_MTRR_H +#define _ASM_MTRR_H + +/* MTRR region types */ +#define MTRR_TYPE_UNCACHEABLE 0 +#define MTRR_TYPE_WRCOMB 1 +#define MTRR_TYPE_WRTHROUGH 4 +#define MTRR_TYPE_WRPROT 5 +#define MTRR_TYPE_WRBACK 6 + +#define MTRR_TYPE_COUNT 7 + +#define MTRR_CAP_MSR 0x0fe +#define MTRR_DEF_TYPE_MSR 0x2ff + +#define MTRR_CAP_SMRR (1 << 11) +#define MTRR_CAP_WC (1 << 10) +#define MTRR_CAP_FIX (1 << 8) +#define MTRR_CAP_VCNT_MASK 0xff + +#define MTRR_DEF_TYPE_MASK 0xff +#define MTRR_DEF_TYPE_EN (1 << 11) +#define MTRR_DEF_TYPE_FIX_EN (1 << 10) + +#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg)) +#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1) + +#define MTRR_PHYS_MASK_VALID (1 << 11) + +#define MTRR_BASE_TYPE_MASK 0x7 + +/* Number of MTRRs supported */ +#define MTRR_COUNT 8 + +#define NUM_FIXED_MTRRS 11 +#define RANGES_PER_FIXED_MTRR 8 +#define NUM_FIXED_RANGES (NUM_FIXED_MTRRS * RANGES_PER_FIXED_MTRR) + +#define MTRR_FIX_64K_00000_MSR 0x250 +#define MTRR_FIX_16K_80000_MSR 0x258 +#define MTRR_FIX_16K_A0000_MSR 0x259 +#define MTRR_FIX_4K_C0000_MSR 0x268 +#define MTRR_FIX_4K_C8000_MSR 0x269 +#define MTRR_FIX_4K_D0000_MSR 0x26a +#define MTRR_FIX_4K_D8000_MSR 0x26b +#define MTRR_FIX_4K_E0000_MSR 0x26c +#define MTRR_FIX_4K_E8000_MSR 0x26d +#define MTRR_FIX_4K_F0000_MSR 0x26e +#define MTRR_FIX_4K_F8000_MSR 0x26f + +#define MTRR_FIX_TYPE(t) ((t << 24) | (t << 16) | (t << 8) | t) + +#if !defined(__ASSEMBLER__) + +/** + * Information about the previous MTRR state, set up by mtrr_open() + * + * @deftype: Previous value of MTRR_DEF_TYPE_MSR + * @enable_cache: true if cache was enabled + */ +struct mtrr_state { + uint64_t deftype; + bool enable_cache; +}; + +/** + * mtrr_open() - Prepare to adjust MTRRs + * + * Use mtrr_open() passing in a structure - this function will init it. Then + * when done, pass the same structure to mtrr_close() to re-enable MTRRs and + * possibly the cache. + * + * @state: Empty structure to pass in to hold settings + * @do_caches: true to disable caches before opening + */ +void mtrr_open(struct mtrr_state *state, bool do_caches); + +/** + * mtrr_open() - Clean up after adjusting MTRRs, and enable them + * + * This uses the structure containing information returned from mtrr_open(). + * + * @state: Structure from mtrr_open() + * @state: true to restore cache state to that before mtrr_open() + */ +void mtrr_close(struct mtrr_state *state, bool do_caches); + +/** + * mtrr_add_request() - Add a new MTRR request + * + * This adds a request for a memory region to be set up in a particular way. + * + * @type: Requested type (MTRR_TYPE_) + * @start: Start address + * @size: Size + * + * @return: 0 on success, non-zero on failure + */ +int mtrr_add_request(int type, uint64_t start, uint64_t size); + +/** + * mtrr_commit() - set up the MTRR registers based on current requests + * + * This sets up MTRRs for the available DRAM and the requests received so far. + * It must be called with caches disabled. + * + * @do_caches: true if caches are currently on + * + * @return: 0 on success, non-zero on failure + */ +int mtrr_commit(bool do_caches); + +/** + * mtrr_set_next_var() - set up a variable MTRR + * + * This finds the first free variable MTRR and sets to the given area + * + * @type: Requested type (MTRR_TYPE_) + * @start: Start address + * @size: Size + * @return 0 on success, -ENOSPC if there are no more MTRRs + */ +int mtrr_set_next_var(uint type, uint64_t base, uint64_t size); + +#endif + +#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0) +# error "CONFIG_XIP_ROM_SIZE is not a power of 2" +#endif + +#if ((CONFIG_CACHE_ROM_SIZE & (CONFIG_CACHE_ROM_SIZE - 1)) != 0) +# error "CONFIG_CACHE_ROM_SIZE is not a power of 2" +#endif + +#define CACHE_ROM_BASE (((1 << 20) - (CONFIG_CACHE_ROM_SIZE >> 12)) << 12) + +#endif diff --git a/arch/x86/include/asm/pch_common.h b/arch/x86/include/asm/pch_common.h new file mode 100644 index 0000000..c4614d3 --- /dev/null +++ b/arch/x86/include/asm/pch_common.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __asm_pch_common_h +#define __asm_pch_common_h + +/* Common Intel SATA registers */ +#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */ +#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */ +#define SATA_SP 0xd0 /* Scratchpad */ + +#define INTR_LN 0x3c +#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ +#define IDE_DECODE_ENABLE (1 << 15) +#define IDE_SITRE (1 << 14) +#define IDE_ISP_5_CLOCKS (0 << 12) +#define IDE_ISP_4_CLOCKS (1 << 12) +#define IDE_ISP_3_CLOCKS (2 << 12) +#define IDE_RCT_4_CLOCKS (0 << 8) +#define IDE_RCT_3_CLOCKS (1 << 8) +#define IDE_RCT_2_CLOCKS (2 << 8) +#define IDE_RCT_1_CLOCKS (3 << 8) +#define IDE_DTE1 (1 << 7) +#define IDE_PPE1 (1 << 6) +#define IDE_IE1 (1 << 5) +#define IDE_TIME1 (1 << 4) +#define IDE_DTE0 (1 << 3) +#define IDE_PPE0 (1 << 2) +#define IDE_IE0 (1 << 1) +#define IDE_TIME0 (1 << 0) +#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ + +#define SERIRQ_CNTL 0x64 + +/** + * pch_common_sir_read() - Read from a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to read + * @return value read from register + */ +u32 pch_common_sir_read(struct udevice *dev, int idx); + +/** + * pch_common_sir_write() - Write to a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to write + * @value: Value to write + */ +void pch_common_sir_write(struct udevice *dev, int idx, u32 value); + +#endif diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h new file mode 100644 index 0000000..2a72073 --- /dev/null +++ b/arch/x86/include/asm/pci.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + */ + +#ifndef _PCI_I386_H_ +#define _PCI_I386_H_ + +#include <pci.h> + +/* bus mapping constants (used for PCI core initialization) */ +#define PCI_REG_ADDR 0xcf8 +#define PCI_REG_DATA 0xcfc + +#define PCI_CFG_EN 0x80000000 + +#ifndef __ASSEMBLY__ + +/** + * pci_x86_read_config() - Read a configuration value from a device + * + * This function can be called before PCI is set up in driver model. + * + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @offset: Register offset to read + * @valuep: Place to put the returned value + * @size: Access size + * @return 0 if OK, -ve on error + */ +int pci_x86_read_config(pci_dev_t bdf, uint offset, ulong *valuep, + enum pci_size_t size); + +/** + * pci_bus_write_config() - Write a configuration value to a device + * + * This function can be called before PCI is set up in driver model. + * + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @offset: Register offset to write + * @value: Value to write + * @size: Access size + * @return 0 if OK, -ve on error + */ +int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value, + enum pci_size_t size); + +/** + * pci_bus_clrset_config32() - Update a configuration value for a device + * + * The register at @offset is updated to (oldvalue & ~clr) | set. This function + * can be called before PCI is set up in driver model. + * + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @offset: Register offset to update + * @clr: Bits to clear + * @set: Bits to set + * @return 0 if OK, -ve on error + */ +int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set, + enum pci_size_t size); + +/** + * Assign IRQ number to a PCI device + * + * This function assigns IRQ for a PCI device. If the device does not exist + * or does not require interrupts then this function has no effect. + * + * @bus: PCI bus number + * @device: PCI device number + * @irq: An array of IRQ numbers that are assigned to INTA through + * INTD of this PCI device. + */ +void pci_assign_irqs(int bus, int device, u8 irq[4]); + +#endif /* __ASSEMBLY__ */ + +#endif /* _PCI_I386_H_ */ diff --git a/arch/x86/include/asm/pirq_routing.h b/arch/x86/include/asm/pirq_routing.h new file mode 100644 index 0000000..67e5c44 --- /dev/null +++ b/arch/x86/include/asm/pirq_routing.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * Ported from coreboot src/arch/x86/include/arch/pirq_routing.h + */ + +#ifndef _PIRQ_ROUTING_H_ +#define _PIRQ_ROUTING_H_ + +/* + * This is the maximum number on interrupt entries that a PCI device may have. + * This is NOT the number of slots or devices in the system + * This is NOT the number of entries in the PIRQ table + * + * This tells us that in the PIRQ table, we are going to have 4 link-bitmap + * entries per PCI device which is fixed at 4: INTA, INTB, INTC, and INTD. + * + * CAUTION: If you change this, PIRQ routing will not work correctly. + */ +#define MAX_INTX_ENTRIES 4 + +#define PIRQ_SIGNATURE \ + (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) +#define PIRQ_VERSION 0x0100 + +struct __packed irq_info { + u8 bus; /* Bus number */ + u8 devfn; /* Device and function number */ + struct __packed { + u8 link; /* IRQ line ID, 0=not routed */ + u16 bitmap; /* Available IRQs */ + } irq[MAX_INTX_ENTRIES]; + u8 slot; /* Slot number, 0=onboard */ + u8 rfu; +}; + +struct __packed irq_routing_table { + u32 signature; /* PIRQ_SIGNATURE */ + u16 version; /* PIRQ_VERSION */ + u16 size; /* Table size in bytes */ + u8 rtr_bus; /* busno of the interrupt router */ + u8 rtr_devfn; /* devfn of the interrupt router */ + u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ + u16 rtr_vendor; /* Vendor ID of the interrupt router */ + u16 rtr_device; /* Device ID of the interrupt router */ + u32 miniport_data; + u8 rfu[11]; + u8 checksum; /* Modulo 256 checksum must give zero */ + struct irq_info slots[CONFIG_IRQ_SLOT_COUNT]; +}; + +/** + * get_irq_slot_count() - Get the number of entries in the irq_info table + * + * This calculates the number of entries for the irq_info table. + * + * @rt: pointer to the base address of the struct irq_info + * @return: number of entries + */ +static inline int get_irq_slot_count(struct irq_routing_table *rt) +{ + return (rt->size - 32) / sizeof(struct irq_info); +} + +/** + * pirq_check_irq_routed() - Check whether an IRQ is routed to 8259 PIC + * + * This function checks whether an IRQ is routed to 8259 PIC for a given link. + * + * Note: this function should be provided by the platform codes, as the + * implementation of interrupt router may be different. + * + * @dev: irq router's udevice + * @link: link number which represents a PIRQ + * @irq: the 8259 IRQ number + * @return: true if the irq is already routed to 8259 for a given link, + * false elsewise + */ +bool pirq_check_irq_routed(struct udevice *dev, int link, u8 irq); + +/** + * pirq_translate_link() - Translate a link value + * + * This function translates a platform-specific link value to a link number. + * On Intel platforms, the link value is normally a offset into the PCI + * configuration space into the legacy bridge. + * + * Note: this function should be provided by the platform codes, as the + * implementation of interrupt router may be different. + * + * @dev: irq router's udevice + * @link: platform-specific link value + * @return: link number which represents a PIRQ + */ +int pirq_translate_link(struct udevice *dev, int link); + +/** + * pirq_assign_irq() - Assign an IRQ to a PIRQ link + * + * This function assigns the IRQ to a PIRQ link so that the PIRQ is routed to + * the 8259 PIC. + * + * Note: this function should be provided by the platform codes, as the + * implementation of interrupt router may be different. + * + * @dev: irq router's udevice + * @link: link number which represents a PIRQ + * @irq: IRQ to which the PIRQ is routed + */ +void pirq_assign_irq(struct udevice *dev, int link, u8 irq); + +/** + * pirq_route_irqs() - Route PIRQs to 8259 PIC + * + * This function configures all PCI devices' interrupt pins and maps them to + * PIRQs and finally 8259 PIC. The routed irq number is written to interrupt + * line register in the configuration space of the PCI device for OS to use. + * The configuration source is taken from a struct irq_info table, the format + * of which is defined in PIRQ routing table spec and PCI BIOS spec. + * + * @dev: irq router's udevice + * @irq: pointer to the base address of the struct irq_info + * @num: number of entries in the struct irq_info + */ +void pirq_route_irqs(struct udevice *dev, struct irq_info *irq, int num); + +/** + * copy_pirq_routing_table() - Copy a PIRQ routing table + * + * This helper function copies the given PIRQ routing table to a given address. + * Before copying, it does several sanity tests against the PIRQ routing table. + * It also fixes up the table checksum and align the given address to a 16 byte + * boundary to meet the PIRQ routing table spec requirements. + * + * @addr: address to store the copied PIRQ routing table + * @rt: pointer to the PIRQ routing table to copy from + * @return: end address of the copied PIRQ routing table + */ +u32 copy_pirq_routing_table(u32 addr, struct irq_routing_table *rt); + +#endif /* _PIRQ_ROUTING_H_ */ diff --git a/arch/x86/include/asm/pmu.h b/arch/x86/include/asm/pmu.h new file mode 100644 index 0000000..b76bdf6 --- /dev/null +++ b/arch/x86/include/asm/pmu.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + */ +#ifndef _X86_ASM_PMU_IPC_H_ +#define _X86_ASM_PMU_IPC_H_ + +int pmu_turn_power(unsigned int lss, bool on); + +#endif /* _X86_ASM_PMU_IPC_H_ */ diff --git a/arch/x86/include/asm/pnp_def.h b/arch/x86/include/asm/pnp_def.h new file mode 100644 index 0000000..0345d19 --- /dev/null +++ b/arch/x86/include/asm/pnp_def.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + * + * Adapted from coreboot src/include/device/pnp_def.h + * and arch/x86/include/arch/io.h + */ + +#ifndef _ASM_PNP_DEF_H_ +#define _ASM_PNP_DEF_H_ + +#include <asm/io.h> + +#define PNP_IDX_EN 0x30 +#define PNP_IDX_IO0 0x60 +#define PNP_IDX_IO1 0x62 +#define PNP_IDX_IO2 0x64 +#define PNP_IDX_IO3 0x66 +#define PNP_IDX_IRQ0 0x70 +#define PNP_IDX_IRQ1 0x72 +#define PNP_IDX_DRQ0 0x74 +#define PNP_IDX_DRQ1 0x75 +#define PNP_IDX_MSC0 0xf0 +#define PNP_IDX_MSC1 0xf1 + +/* Generic functions for pnp devices */ + +/* + * pnp device is a 16-bit integer composed of its i/o port address at high byte + * and logic function number at low byte. + */ +#define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC)) + +static inline void pnp_write_config(uint16_t dev, uint8_t reg, uint8_t value) +{ + uint8_t port = dev >> 8; + + outb(reg, port); + outb(value, port + 1); +} + +static inline uint8_t pnp_read_config(uint16_t dev, uint8_t reg) +{ + uint8_t port = dev >> 8; + + outb(reg, port); + return inb(port + 1); +} + +static inline void pnp_set_logical_device(uint16_t dev) +{ + uint8_t device = dev & 0xff; + + pnp_write_config(dev, 0x07, device); +} + +static inline void pnp_set_enable(uint16_t dev, int enable) +{ + pnp_write_config(dev, PNP_IDX_EN, enable ? 1 : 0); +} + +static inline int pnp_read_enable(uint16_t dev) +{ + return !!pnp_read_config(dev, PNP_IDX_EN); +} + +static inline void pnp_set_iobase(uint16_t dev, uint8_t index, uint16_t iobase) +{ + pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff); + pnp_write_config(dev, index + 1, iobase & 0xff); +} + +static inline uint16_t pnp_read_iobase(uint16_t dev, uint8_t index) +{ + return ((uint16_t)(pnp_read_config(dev, index)) << 8) | + pnp_read_config(dev, index + 1); +} + +static inline void pnp_set_irq(uint16_t dev, uint8_t index, unsigned irq) +{ + pnp_write_config(dev, index, irq); +} + +static inline void pnp_set_drq(uint16_t dev, uint8_t index, unsigned drq) +{ + pnp_write_config(dev, index, drq & 0xff); +} + +#endif /* _ASM_PNP_DEF_H_ */ diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h new file mode 100644 index 0000000..dbcea7f --- /dev/null +++ b/arch/x86/include/asm/posix_types.h @@ -0,0 +1,86 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +/* checking against __x86_64__ covers both 64-bit EFI stub and 64-bit U-Boot */ +#if defined(__x86_64__) +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +#else +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +#endif +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h new file mode 100644 index 0000000..939b6fa --- /dev/null +++ b/arch/x86/include/asm/post.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2014 Google, Inc + */ + +#ifndef _post_h +#define _post_h + +/* port to use for post codes */ +#define POST_PORT 0x80 + +/* post codes which represent various stages of init */ +#define POST_START 0x1e +#define POST_CAR_START 0x1f +#define POST_CAR_SIPI 0x20 +#define POST_CAR_MTRR 0x21 +#define POST_CAR_UNCACHEABLE 0x22 +#define POST_CAR_BASE_ADDRESS 0x23 +#define POST_CAR_MASK 0x24 +#define POST_CAR_FILL 0x25 +#define POST_CAR_ROM_CACHE 0x26 +#define POST_CAR_MRC_CACHE 0x27 +#define POST_CAR_CPU_CACHE 0x28 +#define POST_START_STACK 0x29 +#define POST_START_DONE 0x2a +#define POST_CPU_INIT 0x2b +#define POST_EARLY_INIT 0x2c +#define POST_CPU_INFO 0x2d +#define POST_PRE_MRC 0x2e +#define POST_MRC 0x2f +#define POST_DRAM 0x30 +#define POST_LAPIC 0x31 +#define POST_OS_RESUME 0x40 + +#define POST_RAM_FAILURE 0xea +#define POST_BIST_FAILURE 0xeb +#define POST_CAR_FAILURE 0xec +#define POST_RESUME_FAILURE 0xed + +/* Output a post code using al - value must be 0 to 0xff */ +#ifdef __ASSEMBLY__ +#define post_code(value) \ + movb $value, %al; \ + outb %al, $POST_PORT +#else +#include <asm/io.h> + +static inline void post_code(int code) +{ + outb(code, POST_PORT); +} +#endif + +#endif diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h new file mode 100644 index 0000000..7a3e836 --- /dev/null +++ b/arch/x86/include/asm/processor-flags.h @@ -0,0 +1,100 @@ +#ifndef _ASM_X86_PROCESSOR_FLAGS_H +#define _ASM_X86_PROCESSOR_FLAGS_H +/* Various flags defined: can be included from assembler. */ + +/* + * EFLAGS bits + */ +#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ +#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ +#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ +#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ +#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ +#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ +#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ +#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ +#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ +#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ +#define X86_EFLAGS_NT 0x00004000 /* Nested Task */ +#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ +#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ +#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ +#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ +#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ +#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ + +/* + * Basic CPU control in CR0 + */ +#define X86_CR0_PE 0x00000001 /* Protection Enable */ +#define X86_CR0_MP 0x00000002 /* Monitor Coprocessor */ +#define X86_CR0_EM 0x00000004 /* Emulation */ +#define X86_CR0_TS 0x00000008 /* Task Switched */ +#define X86_CR0_ET 0x00000010 /* Extension Type */ +#define X86_CR0_NE 0x00000020 /* Numeric Error */ +#define X86_CR0_WP 0x00010000 /* Write Protect */ +#define X86_CR0_AM 0x00040000 /* Alignment Mask */ +#define X86_CR0_NW 0x20000000 /* Not Write-through */ +#define X86_CR0_CD 0x40000000 /* Cache Disable */ +#define X86_CR0_PG 0x80000000 /* Paging */ + +/* + * Paging options in CR3 + */ +#define X86_CR3_PWT 0x00000008 /* Page Write Through */ +#define X86_CR3_PCD 0x00000010 /* Page Cache Disable */ + +/* + * Intel CPU features in CR4 + */ +#define X86_CR4_VME 0x00000001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x00000002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x00000004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x00000008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x00000010 /* enable page size extensions */ +#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x00000040 /* Machine check enable */ +#define X86_CR4_PGE 0x00000080 /* enable global pages */ +#define X86_CR4_PCE 0x00000100 /* enable performance counters at ipl 3 */ +#define X86_CR4_OSFXSR 0x00000200 /* enable fast FPU save and restore */ +#define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ +#define X86_CR4_VMXE 0x00002000 /* enable VMX virtualization */ +#define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ + +/* + * x86-64 Task Priority Register, CR8 + */ +#define X86_CR8_TPR 0x0000000F /* task priority register */ + +/* + * AMD and Transmeta use MSRs for configuration; see <asm/msr-index.h> + */ + +/* + * NSC/Cyrix CPU configuration register indexes + */ +#define CX86_PCR0 0x20 +#define CX86_GCR 0xb8 +#define CX86_CCR0 0xc0 +#define CX86_CCR1 0xc1 +#define CX86_CCR2 0xc2 +#define CX86_CCR3 0xc3 +#define CX86_CCR4 0xe8 +#define CX86_CCR5 0xe9 +#define CX86_CCR6 0xea +#define CX86_CCR7 0xeb +#define CX86_PCR1 0xf0 +#define CX86_DIR0 0xfe +#define CX86_DIR1 0xff +#define CX86_ARR_BASE 0xc4 +#define CX86_RCR_BASE 0xdc + +#ifdef __KERNEL__ +#ifdef CONFIG_VM86 +#define X86_VM_MASK X86_EFLAGS_VM +#else +#define X86_VM_MASK 0 /* No VM86 support */ +#endif +#endif + +#endif /* _ASM_X86_PROCESSOR_FLAGS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h new file mode 100644 index 0000000..f1d9977 --- /dev/null +++ b/arch/x86/include/asm/processor.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + */ + +#ifndef __ASM_PROCESSOR_H_ +#define __ASM_PROCESSOR_H_ 1 + +#define X86_GDT_ENTRY_SIZE 8 + +#define X86_GDT_ENTRY_NULL 0 +#define X86_GDT_ENTRY_UNUSED 1 +#define X86_GDT_ENTRY_32BIT_CS 2 +#define X86_GDT_ENTRY_32BIT_DS 3 +#define X86_GDT_ENTRY_32BIT_FS 4 +#define X86_GDT_ENTRY_16BIT_CS 5 +#define X86_GDT_ENTRY_16BIT_DS 6 +#define X86_GDT_ENTRY_16BIT_FLAT_CS 7 +#define X86_GDT_ENTRY_16BIT_FLAT_DS 8 +#define X86_GDT_NUM_ENTRIES 9 + +#define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE) + +/* Length of the public header on Intel microcode blobs */ +#define UCODE_HEADER_LEN 0x30 + +#ifndef __ASSEMBLY__ + +/* + * This register is documented in (for example) the Intel Atom Processor E3800 + * Product Family Datasheet in "PCU - Power Management Controller (PMC)". + * + * RST_CNT: Reset Control Register (RST_CNT) Offset cf9. + * + * The naming follows Intel's naming. + */ +#define IO_PORT_RESET 0xcf9 + +enum { + SYS_RST = 1 << 1, /* 0 for soft reset, 1 for hard reset */ + RST_CPU = 1 << 2, /* initiate reset */ + FULL_RST = 1 << 3, /* full power cycle */ +}; + +static inline __attribute__((always_inline)) void cpu_hlt(void) +{ + asm("hlt"); +} + +static inline ulong cpu_get_sp(void) +{ + ulong result; + + asm volatile( + "mov %%esp, %%eax" + : "=a" (result)); + return result; +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h new file mode 100644 index 0000000..3849bc0 --- /dev/null +++ b/arch/x86/include/asm/ptrace.h @@ -0,0 +1,100 @@ +#ifndef _I386_PTRACE_H +#define _I386_PTRACE_H + +#include <asm/types.h> + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 +#define FRAME_SIZE 17 + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + int xds; + int xes; + int xfs; + int xgs; + long orig_eax; + long eip; + int xcs; + long eflags; + long esp; + int xss; +} __attribute__ ((packed)); + +struct irq_regs { + /* Pushed by irq_common_entry */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long esp; + long eax; + long xds; + long xes; + long xfs; + long xgs; + long xss; + /* Pushed by vector handler (irq_<num>) */ + long irq_id; + /* Pushed by cpu in response to interrupt */ + union { + struct { + long eip; + long xcs; + long eflags; + } ctx1; + struct { + long err; + long eip; + long xcs; + long eflags; + } ctx2; + } context; +} __attribute__ ((packed)); + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_GETFPXREGS 18 +#define PTRACE_SETFPXREGS 19 + +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + +#ifdef __KERNEL__ +#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) +#define instruction_pointer(regs) ((regs)->eip) +extern void show_regs(struct pt_regs *); +#endif + +#endif diff --git a/arch/x86/include/asm/report_platform.h b/arch/x86/include/asm/report_platform.h new file mode 100644 index 0000000..26e70f1 --- /dev/null +++ b/arch/x86/include/asm/report_platform.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016 Google, Inc + */ + +#ifndef __ARCH_REPORT_PLATFORM_H +#define __ARCH_REPORT_PLATFORM_H + +/** + * report_platform_info() - Report platform information + * + * This reports information about the CPU and chipset. + * + * @dev: Northbridge device + */ +void report_platform_info(struct udevice *dev); + +#endif diff --git a/arch/x86/include/asm/scu.h b/arch/x86/include/asm/scu.h new file mode 100644 index 0000000..f5ec5a1 --- /dev/null +++ b/arch/x86/include/asm/scu.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2017 Intel Corporation + */ +#ifndef _X86_ASM_SCU_IPC_H_ +#define _X86_ASM_SCU_IPC_H_ + +/* IPC defines the following message types */ +#define IPCMSG_INDIRECT_READ 0x02 +#define IPCMSG_INDIRECT_WRITE 0x05 +#define IPCMSG_WARM_RESET 0xf0 +#define IPCMSG_COLD_RESET 0xf1 +#define IPCMSG_SOFT_RESET 0xf2 +#define IPCMSG_COLD_BOOT 0xf3 +#define IPCMSG_GET_FW_REVISION 0xf4 +#define IPCMSG_WATCHDOG_TIMER 0xf8 /* Set Kernel Watchdog Threshold */ + +struct ipc_ifwi_version { + u16 minor; + u8 major; + u8 hardware_id; + u32 reserved[3]; +}; + +/* Issue commands to the SCU with or without data */ +int scu_ipc_simple_command(u32 cmd, u32 sub); +int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen); +int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, + int outlen, u32 dptr, u32 sptr); + +#endif /* _X86_ASM_SCU_IPC_H_ */ diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h new file mode 100644 index 0000000..a6be360 --- /dev/null +++ b/arch/x86/include/asm/sections.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2012 The Chromium OS Authors. + */ + +#ifndef __ASM_X86_SECTIONS_H +#define __ASM_X86_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h new file mode 100644 index 0000000..49c36c1 --- /dev/null +++ b/arch/x86/include/asm/setjmp.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Written by H. Peter Anvin <hpa@zytor.com> + * Brought in from Linux v4.4 and modified for U-Boot + * From Linux arch/um/sys-i386/setjmp.S + */ + +#ifndef __setjmp_h +#define __setjmp_h + +#ifdef CONFIG_X86_64 + +struct jmp_buf_data { + unsigned long __rip; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __rbx; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; +}; + +#else + +struct jmp_buf_data { + unsigned int __ebx; + unsigned int __esp; + unsigned int __ebp; + unsigned int __esi; + unsigned int __edi; + unsigned int __eip; +}; + +#endif + +int setjmp(struct jmp_buf_data *jmp_buf); +void longjmp(struct jmp_buf_data *jmp_buf, int val); + +#endif diff --git a/arch/x86/include/asm/sfi.h b/arch/x86/include/asm/sfi.h new file mode 100644 index 0000000..09d4700 --- /dev/null +++ b/arch/x86/include/asm/sfi.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright(c) 2009 Intel Corporation. All rights reserved. + */ + +#ifndef _LINUX_SFI_H +#define _LINUX_SFI_H + +#include <errno.h> +#include <linux/types.h> + +/* Table signatures reserved by the SFI specification */ +#define SFI_SIG_SYST "SYST" +#define SFI_SIG_FREQ "FREQ" +#define SFI_SIG_CPUS "CPUS" +#define SFI_SIG_MTMR "MTMR" +#define SFI_SIG_MRTC "MRTC" +#define SFI_SIG_MMAP "MMAP" +#define SFI_SIG_APIC "APIC" +#define SFI_SIG_XSDT "XSDT" +#define SFI_SIG_WAKE "WAKE" +#define SFI_SIG_DEVS "DEVS" +#define SFI_SIG_GPIO "GPIO" + +#define SFI_SIGNATURE_SIZE 4 +#define SFI_OEM_ID_SIZE 6 +#define SFI_OEM_TABLE_ID_SIZE 8 + +#define SFI_NAME_LEN 16 +#define SFI_TABLE_MAX_ENTRIES 16 + +#define SFI_GET_NUM_ENTRIES(ptable, entry_type) \ + ((ptable->header.len - sizeof(struct sfi_table_header)) / \ + (sizeof(entry_type))) +/* + * Table structures must be byte-packed to match the SFI specification, + * as they are provided by the BIOS. + */ +struct __packed sfi_table_header { + char sig[SFI_SIGNATURE_SIZE]; + u32 len; + u8 rev; + u8 csum; + char oem_id[SFI_OEM_ID_SIZE]; + char oem_table_id[SFI_OEM_TABLE_ID_SIZE]; +}; + +struct __packed sfi_table_simple { + struct sfi_table_header header; + u64 pentry[1]; +}; + +/* Comply with UEFI spec 2.1 */ +struct __packed sfi_mem_entry { + u32 type; + u64 phys_start; + u64 virt_start; + u64 pages; + u64 attrib; +}; + +/* Memory type definitions */ +enum sfi_mem_type { + SFI_MEM_RESERVED, + SFI_LOADER_CODE, + SFI_LOADER_DATA, + SFI_BOOT_SERVICE_CODE, + SFI_BOOT_SERVICE_DATA, + SFI_RUNTIME_SERVICE_CODE, + SFI_RUNTIME_SERVICE_DATA, + SFI_MEM_CONV, + SFI_MEM_UNUSABLE, + SFI_ACPI_RECLAIM, + SFI_ACPI_NVS, + SFI_MEM_MMIO, + SFI_MEM_IOPORT, + SFI_PAL_CODE, + SFI_MEM_TYPEMAX, +}; + +struct __packed sfi_cpu_table_entry { + u32 apic_id; +}; + +struct __packed sfi_cstate_table_entry { + u32 hint; /* MWAIT hint */ + u32 latency; /* latency in ms */ +}; + +struct __packed sfi_apic_table_entry { + u64 phys_addr; /* phy base addr for APIC reg */ +}; + +struct __packed sfi_freq_table_entry { + u32 freq_mhz; /* in MHZ */ + u32 latency; /* transition latency in ms */ + u32 ctrl_val; /* value to write to PERF_CTL */ +}; + +struct __packed sfi_wake_table_entry { + u64 phys_addr; /* pointer to where the wake vector locates */ +}; + +struct __packed sfi_timer_table_entry { + u64 phys_addr; /* phy base addr for the timer */ + u32 freq_hz; /* in HZ */ + u32 irq; +}; + +struct __packed sfi_rtc_table_entry { + u64 phys_addr; /* phy base addr for the RTC */ + u32 irq; +}; + +struct __packed sfi_device_table_entry { + u8 type; /* bus type, I2C, SPI or ...*/ + u8 host_num; /* attached to host 0, 1...*/ + u16 addr; + u8 irq; + u32 max_freq; + char name[SFI_NAME_LEN]; +}; + +enum { + SFI_DEV_TYPE_SPI = 0, + SFI_DEV_TYPE_I2C, + SFI_DEV_TYPE_UART, + SFI_DEV_TYPE_HSI, + SFI_DEV_TYPE_IPC, + SFI_DEV_TYPE_SD, +}; + +struct __packed sfi_gpio_table_entry { + char controller_name[SFI_NAME_LEN]; + u16 pin_no; + char pin_name[SFI_NAME_LEN]; +}; + +struct sfi_xsdt_header { + uint32_t oem_revision; + uint32_t creator_id; + uint32_t creator_revision; +}; + +typedef int (*sfi_table_handler) (struct sfi_table_header *table); + +/** + * write_sfi_table() - Write Simple Firmware Interface tables + * + * @base: Address to write table to + * @return address to use for the next table + */ +ulong write_sfi_table(ulong base); + +#endif /*_LINUX_SFI_H */ diff --git a/arch/x86/include/asm/sipi.h b/arch/x86/include/asm/sipi.h new file mode 100644 index 0000000..1ab6c28 --- /dev/null +++ b/arch/x86/include/asm/sipi.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2015 Gooogle, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef _ASM_SIPI_H +#define _ASM_SIPI_H + +#define AP_DEFAULT_BASE 0x30000 +#define AP_DEFAULT_SIZE 0x10000 + +#ifndef __ASSEMBLER__ + +/** + * struct sipi_params_16bit - 16-bit SIPI entry-point parameters + * + * These are set up in the same space as the SIPI 16-bit code so that each AP + * can access the parameters when it boots. + * + * Each of these must be set up for the AP to boot, except @segment which is + * set in the assembly code. + * + * @ap_start: 32-bit SIPI entry point for U-Boot + * @segment: Code segment for U-Boot + * @pad: Padding (not used) + * @gdt_limit: U-Boot GDT limit (X86_GDT_SIZE - 1) + * @gdt: U-Boot GDT (gd->arch.gdt) + * @unused: Not used + */ +struct __packed sipi_params_16bit { + u32 ap_start; + u16 segment; + u16 pad; + u16 gdt_limit; + u32 gdt; + u16 unused; +}; + +/** + * struct sipi_params - 32-bit SIP entry-point parameters + * + * These are used by the AP init code and must be set up before the APs start. + * The members must match with the sipi_params layout in sipi_vector.S. + * + * The stack area extends down from @stack_top, with @stack_size allocated + * for each AP. + * + * @idt_ptr: Interrupt descriptor table pointer + * @stack_top: Top of the AP stack area + * @stack_size: Size of each AP's stack + * @microcode_lock: Used to ensure only one AP loads microcode at once + * 0xffffffff enables parallel loading. + * @microcode_ptr: Pointer to microcode, or 0 if none + * @msr_table_ptr: Pointer to saved MSRs, a list of struct saved_msr + * @msr_count: Number of saved MSRs + * @c_handler: C function to call once early init is complete + * @ap_count: Shared atomic value to allocate CPU indexes + */ +struct sipi_params { + u32 idt_ptr; + u32 stack_top; + u32 stack_size; + u32 microcode_lock; + u32 microcode_ptr; + u32 msr_table_ptr; + u32 msr_count; + u32 c_handler; + atomic_t ap_count; +}; + +/* 16-bit AP entry point */ +void ap_start16(void); + +/* end of 16-bit code/data, marks the region to be copied to SIP vector */ +void ap_start16_code_end(void); + +/* 32-bit AP entry point */ +void ap_start(void); + +extern char sipi_params_16bit[]; +extern char sipi_params[]; + +#endif /* __ASSEMBLER__ */ + +#endif diff --git a/arch/x86/include/asm/speedstep.h b/arch/x86/include/asm/speedstep.h new file mode 100644 index 0000000..43bfabf --- /dev/null +++ b/arch/x86/include/asm/speedstep.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From Coreboot file of same name + * + * Copyright (C) 2007-2009 coresystems GmbH + * 2012 secunet Security Networks AG + */ + +#ifndef _ASM_SPEEDSTEP_H +#define _ASM_SPEEDSTEP_H + +/* Magic value used to locate speedstep configuration in the device tree */ +#define SPEEDSTEP_APIC_MAGIC 0xACAC + +/* MWAIT coordination I/O base address. This must match + * the \_PR_.CPU0 PM base address. + */ +#define PMB0_BASE 0x510 + +/* PMB1: I/O port that triggers SMI once cores are in the same state. + * See CSM Trigger, at PMG_CST_CONFIG_CONTROL[6:4] + */ +#define PMB1_BASE 0x800 + +struct sst_state { + uint8_t dynfsb:1; /* whether this is SLFM */ + uint8_t nonint:1; /* add .5 to ratio */ + uint8_t ratio:6; + uint8_t vid; + uint8_t is_turbo; + uint8_t is_slfm; + uint32_t power; +}; +#define SPEEDSTEP_RATIO_SHIFT 8 +#define SPEEDSTEP_RATIO_DYNFSB_SHIFT (7 + SPEEDSTEP_RATIO_SHIFT) +#define SPEEDSTEP_RATIO_DYNFSB (1 << SPEEDSTEP_RATIO_DYNFSB_SHIFT) +#define SPEEDSTEP_RATIO_NONINT_SHIFT (6 + SPEEDSTEP_RATIO_SHIFT) +#define SPEEDSTEP_RATIO_NONINT (1 << SPEEDSTEP_RATIO_NONINT_SHIFT) +#define SPEEDSTEP_RATIO_VALUE_MASK (0x1f << SPEEDSTEP_RATIO_SHIFT) +#define SPEEDSTEP_VID_MASK 0x3f +#define SPEEDSTEP_STATE_FROM_MSR(val, mask) ((struct sst_state){ \ + 0, /* dynfsb won't be read. */ \ + ((val & mask) & SPEEDSTEP_RATIO_NONINT) ? 1 : 0, \ + (((val & mask) & SPEEDSTEP_RATIO_VALUE_MASK) \ + >> SPEEDSTEP_RATIO_SHIFT), \ + (val & mask) & SPEEDSTEP_VID_MASK, \ + 0, /* not turbo by default */ \ + 0, /* not slfm by default */ \ + 0 /* power is hardcoded in software. */ \ + }) +#define SPEEDSTEP_ENCODE_STATE(state) ( \ + ((uint16_t)(state).dynfsb << SPEEDSTEP_RATIO_DYNFSB_SHIFT) | \ + ((uint16_t)(state).nonint << SPEEDSTEP_RATIO_NONINT_SHIFT) | \ + ((uint16_t)(state).ratio << SPEEDSTEP_RATIO_SHIFT) | \ + ((uint16_t)(state).vid & SPEEDSTEP_VID_MASK)) +#define SPEEDSTEP_DOUBLE_RATIO(state) ( \ + ((uint8_t)(state).ratio * 2) + (state).nonint) + +struct sst_params { + struct sst_state slfm; + struct sst_state min; + struct sst_state max; + struct sst_state turbo; +}; + +/* Looking at core2's spec, the highest normal bus ratio for an eist enabled + processor is 14, the lowest is always 6. This makes 5 states with the + minimal step width of 2. With turbo mode and super LFM we have at most 7. */ +#define SPEEDSTEP_MAX_NORMAL_STATES 5 +#define SPEEDSTEP_MAX_STATES (SPEEDSTEP_MAX_NORMAL_STATES + 2) +struct sst_table { + /* Table of p-states for EMTTM and ACPI by decreasing performance. */ + struct sst_state states[SPEEDSTEP_MAX_STATES]; + int num_states; +}; + +void speedstep_gen_pstates(struct sst_table *); + +#define SPEEDSTEP_MAX_POWER_YONAH 31000 +#define SPEEDSTEP_MIN_POWER_YONAH 13100 +#define SPEEDSTEP_MAX_POWER_MEROM 35000 +#define SPEEDSTEP_MIN_POWER_MEROM 25000 +#define SPEEDSTEP_SLFM_POWER_MEROM 12000 +#define SPEEDSTEP_MAX_POWER_PENRYN 35000 +#define SPEEDSTEP_MIN_POWER_PENRYN 15000 +#define SPEEDSTEP_SLFM_POWER_PENRYN 12000 + +#endif diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h new file mode 100644 index 0000000..1bef487 --- /dev/null +++ b/arch/x86/include/asm/spl.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __asm_spl_h +#define __asm_spl_h + +#define CONFIG_SPL_BOARD_LOAD_IMAGE + +enum { + BOOT_DEVICE_SPI_MMAP = 10, + BOOT_DEVICE_CROS_VBOOT, +}; + +void jump_to_spl(ulong entry); + +#endif diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h new file mode 100644 index 0000000..c15b264 --- /dev/null +++ b/arch/x86/include/asm/string.h @@ -0,0 +1,47 @@ +#ifndef __ASM_I386_STRING_H +#define __ASM_I386_STRING_H + +/* + * We don't do inline string functions, since the + * optimised inline asm versions are not small. + */ +#undef __HAVE_ARCH_STRNCPY +extern char *strncpy(char *__dest, __const__ char *__src, __kernel_size_t __n); + +#undef __HAVE_ARCH_STRRCHR +extern char *strrchr(const char *s, int c); + +#undef __HAVE_ARCH_STRCHR +extern char *strchr(const char *s, int c); + +#ifdef CONFIG_X86_64 + +#undef __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); + +#else + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); + +#endif /* CONFIG_X86_64 */ + +#undef __HAVE_ARCH_MEMCHR +extern void *memchr(const void *, int, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, __kernel_size_t n); + +#endif diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h new file mode 100644 index 0000000..f7c72ed --- /dev/null +++ b/arch/x86/include/asm/tables.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _X86_TABLES_H_ +#define _X86_TABLES_H_ + +#include <tables_csum.h> + +#define ROM_TABLE_ADDR CONFIG_ROM_TABLE_ADDR +#define ROM_TABLE_END (CONFIG_ROM_TABLE_ADDR + CONFIG_ROM_TABLE_SIZE - 1) + +#define ROM_TABLE_ALIGN 1024 + +/* SeaBIOS expects coreboot tables at address range 0x0000-0x1000 */ +#define CB_TABLE_ADDR 0x800 + +/** + * table_compute_checksum() - Compute a table checksum + * + * This computes an 8-bit checksum for the configuration table. + * All bytes in the configuration table, including checksum itself and + * reserved bytes must add up to zero. + * + * @v: configuration table base address + * @len: configuration table size + * @return: the 8-bit checksum + */ +u8 table_compute_checksum(void *v, int len); + +/** + * table_fill_string() - Fill a string with pad in the configuration table + * + * This fills a string in the configuration table. It copies number of bytes + * from the source string, and if source string length is shorter than the + * required size to copy, pad the table string with the given pad character. + * + * @dest: where to fill a string + * @src: where to copy from + * @n: number of bytes to copy + * @pad: character to pad the remaining bytes + */ +void table_fill_string(char *dest, const char *src, size_t n, char pad); + +/** + * write_tables() - Write x86 configuration tables + * + * This writes x86 configuration tables, including PIRQ routing table, + * Multi-Processor table and ACPI table. Whether a specific type of + * configuration table is written is controlled by a Kconfig option. + */ +void write_tables(void); + +/** + * write_pirq_routing_table() - Write PIRQ routing table + * + * This writes PIRQ routing table at a given address. + * + * @start: start address to write PIRQ routing table + * @return: end address of PIRQ routing table + */ +ulong write_pirq_routing_table(ulong start); + +#endif /* _X86_TABLES_H_ */ diff --git a/arch/x86/include/asm/turbo.h b/arch/x86/include/asm/turbo.h new file mode 100644 index 0000000..94a6353 --- /dev/null +++ b/arch/x86/include/asm/turbo.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * From coreboot file of the same name + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + */ + +#ifndef _ASM_TURBO_H +#define _ASM_TURBO_H + +#define CPUID_LEAF_PM 6 +#define PM_CAP_TURBO_MODE (1 << 1) + +enum { + TURBO_UNKNOWN, + TURBO_UNAVAILABLE, + TURBO_DISABLED, + TURBO_ENABLED, +}; + +/* Return current turbo state */ +int turbo_get_state(void); + +/* Enable turbo */ +void turbo_enable(void); + +#endif diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h new file mode 100644 index 0000000..ba50001 --- /dev/null +++ b/arch/x86/include/asm/types.h @@ -0,0 +1,28 @@ +#ifndef __ASM_I386_TYPES_H +#define __ASM_I386_TYPES_H + +#include <asm-generic/int-ll64.h> + +typedef unsigned short umode_t; + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#if CONFIG_IS_ENABLED(X86_64) +#define BITS_PER_LONG 64 +#else +#define BITS_PER_LONG 32 +#endif + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +typedef unsigned long long phys_addr_t; +typedef unsigned long long phys_size_t; + +#endif /* __KERNEL__ */ + +#endif diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h new file mode 100644 index 0000000..2466ad2 --- /dev/null +++ b/arch/x86/include/asm/u-boot-x86.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + */ + +#ifndef _U_BOOT_I386_H_ +#define _U_BOOT_I386_H_ 1 + +struct global_data; + +extern char gdt_rom[]; + +/* cpu/.../cpu.c */ +int arch_cpu_init(void); + +/** + * x86_cpu_init_f() - Set up basic features of the x86 CPU + * + * 0 on success, -ve on error + */ +int x86_cpu_init_f(void); + +/** + * x86_cpu_reinit_f() - Set up the CPU a second time + * + * Once cpu_init_f() has been called (e.g. in SPL) we should not call it + * again (e.g. in U-Boot proper) since it sets up the state from scratch. + * Call this function in later phases of U-Boot instead. It reads the CPU + * identify so that CPU functions can be used correctly, but does not change + * anything. + * + * @return 0 (indicating success, to mimic cpu_init_f()) + */ +int x86_cpu_reinit_f(void); + +int cpu_init_f(void); +void setup_gdt(struct global_data *id, u64 *gdt_addr); +/* + * Setup FSP execution environment GDT to use the one we used in + * arch/x86/cpu/start16.S and reload the segment registers. + */ +void setup_fsp_gdt(void); +int init_cache(void); +int cleanup_before_linux(void); + +/* cpu/.../timer.c */ +void timer_isr(void *); +typedef void (timer_fnc_t) (void); +int register_timer_isr (timer_fnc_t *isr_func); +unsigned long get_tbclk_mhz(void); +void timer_set_base(uint64_t base); +int i8254_init(void); + +/* cpu/.../interrupts.c */ +int cpu_init_interrupts(void); + +int cleanup_before_linux(void); +int x86_cleanup_before_linux(void); +void x86_enable_caches(void); +void x86_disable_caches(void); +int x86_init_cache(void); +ulong board_get_usable_ram_top(ulong total_size); +int default_print_cpuinfo(void); + +/* Set up a UART which can be used with printch(), printhex8(), etc. */ +int setup_internal_uart(int enable); + +void setup_pcat_compatibility(void); + +void isa_unmap_rom(u32 addr); +u32 isa_map_rom(u32 bus_addr, int size); + +/* arch/x86/lib/... */ +int video_bios_init(void); + +/* arch/x86/lib/fsp1,2/... */ + +/** + * fsp_save_s3_stack() - save stack address to CMOS for next S3 boot + * + * At the end of pre-relocation phase, save the new stack address + * to CMOS and use it as the stack on next S3 boot for fsp_init() + * continuation function. + * + * @return: 0 if OK, -ve on error + */ +int fsp_save_s3_stack(void); + +void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn)); +void board_init_f_r(void) __attribute__ ((noreturn)); + +int arch_misc_init(void); + +/* Read the time stamp counter */ +static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void) +{ + uint32_t high, low; + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)); + return (((uint64_t)high) << 32) | low; +} + +/* board/... */ +void timer_set_tsc_base(uint64_t new_base); +uint64_t timer_get_tsc(void); + +void quick_ram_check(void); + +#define PCI_VGA_RAM_IMAGE_START 0xc0000 + +#endif /* _U_BOOT_I386_H_ */ diff --git a/arch/x86/include/asm/u-boot.h b/arch/x86/include/asm/u-boot.h new file mode 100644 index 0000000..432eb35 --- /dev/null +++ b/arch/x86/include/asm/u-boot.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> +#include <asm/u-boot-x86.h> + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_I386 + +#endif /* _U_BOOT_H_ */ diff --git a/arch/x86/include/asm/unaligned.h b/arch/x86/include/asm/unaligned.h new file mode 100644 index 0000000..6cecbbb --- /dev/null +++ b/arch/x86/include/asm/unaligned.h @@ -0,0 +1 @@ +#include <asm-generic/unaligned.h> diff --git a/arch/x86/include/asm/video/edid.h b/arch/x86/include/asm/video/edid.h new file mode 100644 index 0000000..928c342 --- /dev/null +++ b/arch/x86/include/asm/video/edid.h @@ -0,0 +1,16 @@ +#ifndef __linux_video_edid_h__ +#define __linux_video_edid_h__ + +#if !defined(__KERNEL__) || defined(CONFIG_X86) + +struct edid_info { + unsigned char dummy[128]; +}; + +#ifdef __KERNEL__ +extern struct edid_info edid_info; +#endif /* __KERNEL__ */ + +#endif + +#endif /* __linux_video_edid_h__ */ diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h new file mode 100644 index 0000000..80e128c --- /dev/null +++ b/arch/x86/include/asm/zimage.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + */ + +#ifndef _ASM_ZIMAGE_H_ +#define _ASM_ZIMAGE_H_ + +#include <asm/bootparam.h> +#include <asm/e820.h> + +/* linux i386 zImage/bzImage header. Offsets relative to + * the start of the image */ + +#define HEAP_FLAG 0x80 +#define BIG_KERNEL_FLAG 0x01 + +/* magic numbers */ +#define KERNEL_MAGIC 0xaa55 +#define KERNEL_V2_MAGIC 0x53726448 +#define COMMAND_LINE_MAGIC 0xA33F + +/* limits */ +#define BZIMAGE_MAX_SIZE 15*1024*1024 /* 15MB */ +#define ZIMAGE_MAX_SIZE 512*1024 /* 512k */ +#define SETUP_MAX_SIZE 32768 + +#define SETUP_START_OFFSET 0x200 +#define BZIMAGE_LOAD_ADDR 0x100000 +#define ZIMAGE_LOAD_ADDR 0x10000 + +struct boot_params *load_zimage(char *image, unsigned long kernel_size, + ulong *load_addressp); +int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, + unsigned long initrd_addr, unsigned long initrd_size); +void setup_video(struct screen_info *screen_info); +void setup_efi_info(struct efi_info *efi_info); + +#endif |