John E. Kabat Jr. has uploaded this change for review. ( https://review.coreboot.org/21728
Change subject: soc/amd/stoneyridge: Add ELOG to SMM (WIP) ......................................................................
soc/amd/stoneyridge: Add ELOG to SMM (WIP)
Add ELOG entries to smihandler.c Use latest southbridge.h Change ACPI_SMI_CMD_ENABLE from 0xEF to 0xE1 to fix conflict with ELOG_GSMI_APM_CNT in elog. Correct errors on debug statement in eloc.g. Add required file uart.c to the makefile for elog Test code included - will be removed later. BUG=b:65485690 Blocked by issue 65587605 SMM mode SPI driver
Change-Id: I458babe1694f042215dd0e1c3277856e340de86f Signed-off-by: John E. Kabat Jr john.kabat@scarletltd.com --- M src/drivers/elog/Makefile.inc M src/drivers/elog/elog.c M src/soc/amd/stoneyridge/Makefile.inc M src/soc/amd/stoneyridge/include/soc/smi.h M src/soc/amd/stoneyridge/include/soc/southbridge.h M src/soc/amd/stoneyridge/smihandler.c 6 files changed, 275 insertions(+), 54 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/28/21728/1
diff --git a/src/drivers/elog/Makefile.inc b/src/drivers/elog/Makefile.inc index 79a7cc0..437e5dd 100644 --- a/src/drivers/elog/Makefile.inc +++ b/src/drivers/elog/Makefile.inc @@ -1,6 +1,7 @@ ramstage-$(CONFIG_ELOG) += elog.c
smm-$(CONFIG_ELOG_GSMI) += elog.c gsmi.c +smm-$(CONFIG_ELOG_DEBUG) += ../../lib/hexdump.c
romstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c ramstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c index 1c17561..d174419 100644 --- a/src/drivers/elog/elog.c +++ b/src/drivers/elog/elog.c @@ -324,8 +324,8 @@
address = rdev_mmap(rdev, offset, size);
- elog_debug("%s(address=0x%p offset=0x%08x size=%u)\n", __func__, - address, offset, size); + printk(BIOS_DEBUG, "%s(address=0x%p offset=0x%08zx size=%zu)\n", + __func__, address, offset, size);
if (address == NULL) return; diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc index 5524a29..f783a9f 100644 --- a/src/soc/amd/stoneyridge/Makefile.inc +++ b/src/soc/amd/stoneyridge/Makefile.inc @@ -85,10 +85,10 @@ ramstage-$(CONFIG_STONEYRIDGE_UART) += uart.c ramstage-y += usb.c ramstage-y += tsc_freq.c - smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c +smm-$(CONFIG_STONEYRIDGE_UART) += uart.c
CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/include diff --git a/src/soc/amd/stoneyridge/include/soc/smi.h b/src/soc/amd/stoneyridge/include/soc/smi.h index 6f7cadb..aa11afa 100644 --- a/src/soc/amd/stoneyridge/include/soc/smi.h +++ b/src/soc/amd/stoneyridge/include/soc/smi.h @@ -54,27 +54,33 @@ #define SMISTAT1_FAKESMI_0 (1 << 1) #define SMISTAT1_FAKESMI_1 (1 << 2) #define SMISTAT1_FAKESMI_2 (1 << 3) -#define SMISTAT1_FAKESMI_EVTS (0b111 << 1) -#define SMISTAT1_FAKE_SMI_EVTS (SMISTAT1_FAKESMI_0 | SMISTAT1_FAKESMI_1 | SMISTAT1_FAKESMI_2) -#define SMISTAT1_ECGE0_EVTS (1 << 8) -#define SMISTAT1_TWARN_EVTS (1 << 16)) -#define SMISTAT1_PWRBTN_EVTS (1 << 19) -#define SMISTAT1_PROCHOT_EVTS (1 << 20) +#define SMISTAT1_FAKE_SMI_EVTS (0x07 << 1) +#define SMISTAT1_FAKESMI_EVTS (SMISTAT1_FAKESMI_0 | \ + SMISTAT1_FAKESMI_1 | \ + SMISTAT1_FAKESMI_2) +#define SMISTAT1_ECGE0 (1 << 8) +#define SMISTAT1_TWARN (1 << 16) +#define SMISTAT1_PWRBTN (1 << 19) +#define SMISTAT1_PROCHOT (1 << 20) #define SMI_REG_SMISTAT2 0x88 -#define SMISTAT2_SLPTYP_EVTS (1 << 1) -#define SMISTAT2_PWRBTN_EVTS (1 << 10) -#define SMISTAT2_ACPI_CMD_EVTS (1 << 11) -#define SMISTAT2_ECSMI0_EVTS (1 << 15) -#define SMISTAT2_PROCHOT_EVTS (1 << 19) +#define SMISTAT2_SLPTYP (1 << 1) +#define SMISTAT2_PWRBTN (1 << 10) +#define SMISTAT2_ACPI_CMD (1 << 11) +#define SMISTAT2_ECSMI0 (1 << 15) +#define SMISTAT2_PROCHOT (1 << 19) #define SMI_REG_SMISTAT3 0x8c #define SMI_REG_SMISTAT4 0x90 -#define SMISTAT4_FAKESMI_EVTS (0b111 << 10) #define SMISTAT4_FAKESMI_0 (1 << 10) #define SMISTAT4_FAKESMI_1 (1 << 11) #define SMISTAT4_FAKESMI_2 (1 << 12) -#define SMISTAT4_MEMTRAP_EVT (1 << 24) +#define SMISTAT4_FAKE_SMI_EVTS (0x07 << 10) +#define SMISTAT4_FAKESMI_EVTS (SMISTAT4_FAKESMI_0 | \ + SMISTAT4_FAKESMI_1 | \ + SMISTAT4_FAKESMI_2) +#define SMISTAT4_MEMTRAP (1 << 24)
-#define SMI_REG_SMI_TIMERT 0x94 +#define SMI_REG_SMI_POINTER 0x94 +#define SMI_REG_SMI_TIMERT 0x96
#define SMI_REG_SMITRIG0 0x98 #define SMITRG0_SMIENB (1 << 31) @@ -85,19 +91,13 @@
#define SMI_REG_SMITRIG1 0x9c
-/* Bit settings for SMI_CTL */ -#define SMI_CTL_SET_DISABLE (0b00) -#define SMI_CTL_SET_SMI (0b01) -#define SMI_CTL_SET_NMI (0b10) -#define SMI_CTL_SET_IRQ13 (0b11) - #define SMI_REG_CONTROL0 0xa0 #define SMI_REG_CONTROL1 0xa4
#define SMI_REG_SMICTRL2 0xa8 /* SMIs reported in SMIx84 */ -#define SMICTRL2_FAKE2_SMI_EN (SMI_CTL_SET_SMI << 6) -#define SMICTRL2_FAKE1_SMI_EN (SMI_CTL_SET_SMI << 4) -#define SMICTRL2_FAKE0_SMI_EN (SMI_CTL_SET_SMI << 2) +#define SMICTRL2_FAKE2_SMI_EN (SMI_MODE_SMI << 6) +#define SMICTRL2_FAKE1_SMI_EN (SMI_MODE_SMI << 4) +#define SMICTRL2_FAKE0_SMI_EN (SMI_MODE_SMI << 2)
#define SMI_REG_CONTROL3 0xac #define SMI_REG_CONTROL4 0xb0 @@ -106,13 +106,14 @@ #define SMI_REG_CONTROL7 0xbc
#define SMI_REG_SMICTRL8 0xc0 /* SMIs reported in SMIx90 */ -#define SMICTRL8_FAKE2_SMI_EN (SMI_CTL_SET_SMI << 24) -#define SMICTRL8_FAKE1_SMI_EN (SMI_CTL_SET_SMI << 22) -#define SMICTRL8_FAKE0_SMI_EN (SMI_CTL_SET_SMI << 20) +#define SMICTRL8_FAKE2_SMI_EN (SMI_MODE_SMI << 24) +#define SMICTRL8_FAKE1_SMI_EN (SMI_MODE_SMI << 22) +#define SMICTRL8_FAKE0_SMI_EN (SMI_MODE_SMI << 20)
#define SMI_REG_SMICTRL9 0xc4 /* SMIs reported in SMIx90 */ -#define SMICTRL9_MTRAP_EN (SMI_CTL_SET_SMI << 16) /* Enable memory trap SMI */ +#define SMICTRL9_MTRAP_EN (SMI_MODE_SMI << 16) /* Enable memory trap */ #define SMICTRL9_MTRAP_MASK (0x03 << 16) /* Memory trap field mask */ + #define SMI_REG_IO_TRAP0 0xc8 #define SMI_REG_MEM_TRAP0 0xd0 #define SMI_REG_MEM_RD_OVR_DATA 0xd4 diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 20edf5f..8604206 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -23,6 +23,109 @@ #include <device/device.h> #include "chip.h"
+/* Some older include files such as fch.h use predefined bits values + * instead of using BIT(x) macro. As they are used in early_setup.c, + * they need to be defined, and southbridge.h needs to be included + * before the ofending file. + */ + +#ifndef BIT0 +#define BIT0 BIT(0) +#endif +#ifndef BIT1 +#define BIT1 BIT(1) +#endif +#ifndef BIT2 +#define BIT2 BIT(2) +#endif +#ifndef BIT3 +#define BIT3 BIT(3) +#endif +#ifndef BIT4 +#define BIT4 BIT(4) +#endif +#ifndef BIT5 +#define BIT5 BIT(5) +#endif +#ifndef BIT6 +#define BIT6 BIT(6) +#endif +#ifndef BIT7 +#define BIT7 BIT(7) +#endif +#ifndef BIT8 +#define BIT8 BIT(8) +#endif +#ifndef BIT9 +#define BIT9 BIT(9) +#endif +#ifndef BIT10 +#define BIT10 BIT(10) +#endif +#ifndef BIT11 +#define BIT11 BIT(11) +#endif +#ifndef BIT12 +#define BIT12 BIT(12) +#endif +#ifndef BIT13 +#define BIT13 BIT(13) +#endif +#ifndef BIT14 +#define BIT14 BIT(14) +#endif +#ifndef BIT15 +#define BIT15 BIT(15) +#endif +#ifndef BIT16 +#define BIT16 BIT(16) +#endif +#ifndef BIT17 +#define BIT17 BIT(17) +#endif +#ifndef BIT18 +#define BIT18 BIT(18) +#endif +#ifndef BIT19 +#define BIT19 BIT(19) +#endif +#ifndef BIT20 +#define BIT20 BIT(20) +#endif +#ifndef BIT21 +#define BIT21 BIT(21) +#endif +#ifndef BIT22 +#define BIT22 BIT(22) +#endif +#ifndef BIT23 +#define BIT23 BIT(23) +#endif +#ifndef BIT24 +#define BIT24 BIT(24) +#endif +#ifndef BIT25 +#define BIT25 BIT(25) +#endif +#ifndef BIT26 +#define BIT26 BIT(26) +#endif +#ifndef BIT27 +#define BIT27 BIT(27) +#endif +#ifndef BIT28 +#define BIT28 BIT(28) +#endif +#ifndef BIT29 +#define BIT29 BIT(29) +#endif +#ifndef BIT30 +#define BIT30 BIT(30) +#endif +#ifndef BIT31 +#define BIT31 BIT(31) +#endif + #define IO_APIC2_ADDR 0xfec20000
/* Offsets from ACPI_MMIO_BASE @@ -44,6 +147,17 @@
#define PM_ACPI_MMIO_EN 0x24 #define PM_SERIRQ_CONF 0x54 +#define PM_SERIRQ_NUM_BITS_17 0x0000 +#define PM_SERIRQ_NUM_BITS_18 0x0004 +#define PM_SERIRQ_NUM_BITS_19 0x0008 +#define PM_SERIRQ_NUM_BITS_20 0x000c +#define PM_SERIRQ_NUM_BITS_21 0x0010 +#define PM_SERIRQ_NUM_BITS_22 0x0014 +#define PM_SERIRQ_NUM_BITS_23 0x0018 +#define PM_SERIRQ_NUM_BITS_24 0x001c +#define PM_SERIRQ_MODE BIT(6) +#define PM_SERIRQ_ENABLE BIT(7) + #define PM_EVT_BLK 0x60 #define PM1_CNT_BLK 0x62 #define PM_TMR_BLK 0x64 @@ -56,6 +170,10 @@ #define PM_HUD_SD_FLASH_CTRL 0xe7 #define PM_YANG_SD_FLASH_CTRL 0xe8 #define PM_PCIB_CFG 0xea +#define PM_LPC_GATING 0xec +#define PM_LPC_AB_NO_BYPASS_EN BIT(2) +#define PM_LPC_A20_EN BIT(1) +#define PM_LPC_ENABLE BIT(0)
#define SYS_RESET 0xcf9
@@ -70,16 +188,22 @@ #define ACPI_SMI_CMD_CST_CONTROL 0xde #define ACPI_SMI_CMD_PST_CONTROL 0xad #define ACPI_SMI_CMD_DISABLE 0xbe -#define ACPI_SMI_CMD_ENABLE 0xef +#define ACPI_SMI_CMD_ENABLE 0xe1 #define ACPI_SMI_CMD_S4_REQ 0xc0
-#define REV_STONEYRIDGE_A11 0x11 -#define REV_STONEYRIDGE_A12 0x12 +#define REV_STONEYRIDGE_A11 0x11 +#define REV_STONEYRIDGE_A12 0x12
#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 #define ROUTE_TPM_2_SPI BIT(3) -#define SPI_ROM_ENABLE 0x02 +#define SPI_ABORT_ENABLE BIT(2) +#define SPI_ROM_ENABLE BIT(1) +#define SPI_ROM_ALT_ENABLE BIT(0) +#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) #define SPI_BASE_ADDRESS 0xfec10000 + +#define LPC_PCI_CONTROL 0x40 +#define LEGACY_DMA_EN BIT(2)
#define LPC_IO_PORT_DECODE_ENABLE 0x44 #define DECODE_ENABLE_PARALLEL_PORT0 BIT(0) @@ -118,16 +242,55 @@ #define LPC_IO_OR_MEM_DECODE_ENABLE 0x48 #define LPC_WIDEIO2_ENABLE BIT(25) #define LPC_WIDEIO1_ENABLE BIT(24) +#define DECODE_IO_PORT_ENABLE6 BIT(23) +#define DECODE_IO_PORT_ENABLE5 BIT(22) +#define DECODE_IO_PORT_ENABLE4 BIT(21) +#define DECODE_IO_PORT_ENABLE3 BIT(19) +#define DECODE_IO_PORT_ENABLE2 BIT(18) +#define DECODE_IO_PORT_ENABLE1 BIT(17) +#define DECODE_IO_PORT_ENABLE0 BIT(16) +#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT(7) #define LPC_WIDEIO0_ENABLE BIT(2) +/* Assuming word access to higher word (register 0x4a) */ +#define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a +#define LPC_WIDEIO2_ENABLE_H BIT(9) +#define LPC_WIDEIO1_ENABLE_H BIT(8) +#define DECODE_IO_PORT_ENABLE6_H BIT(7) +#define DECODE_IO_PORT_ENABLE5_H BIT(6) +#define DECODE_IO_PORT_ENABLE4_H BIT(5) +#define DECODE_IO_PORT_ENABLE3_H BIT(3) +#define DECODE_IO_PORT_ENABLE2_H BIT(2) +#define DECODE_IO_PORT_ENABLE1_H BIT(1) +#define DECODE_IO_PORT_ENABLE0_H BIT(0)
+/* Register 0x64 is 32-bit, composed by two 16-bit sub-registers. + * For ease of access, each sub-register is declared separetely. + */ #define LPC_WIDEIO_GENERIC_PORT 0x64 +#define LPC_WIDEIO1_GENERIC_PORT 0x66 +#define ROM_ADDRESS_RANGE1_START 0x68 +#define ROM_ADDRESS_RANGE1_END 0x6a +#define ROM_ADDRESS_RANGE2_START 0x6c +#define ROM_ADDRESS_RANGE2_END 0x6e
#define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74 #define LPC_ALT_WIDEIO2_ENABLE BIT(3) #define LPC_ALT_WIDEIO1_ENABLE BIT(2) #define LPC_ALT_WIDEIO0_ENABLE BIT(0)
+#define LPC_MISC_CONTROL_BITS 0x78 +#define LPC_NOHOG BIT(0) + #define LPC_WIDEIO2_GENERIC_PORT 0x90 + +/* LPC register 0xb8 is DWORD, here there are definition for byte + * access. For example, bits 31-24 are accessed through byte access + * at register 0xbb (). + */ +#define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8 + +#define LPC_HOST_CONTROL 0xbb +#define SPI_FROM_HOST_PREFETCH_EN BIT(0)
#define SPI_CNTRL0 0x00 #define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18)) @@ -165,6 +328,10 @@ #define SPI100_HOST_PREF_CONFIG 0x2c #define SPI_RD4DW_EN_HOST BIT(15)
+#define FCH_MISC_REG40_OSCOUT1_EN BIT(2) + +#define FLASH_BASE_ADDR ((0xffffffff - CONFIG_ROM_SIZE) + 1) + static inline int sb_sata_enable(void) { /* True if IDE or AHCI. */ diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c index 9865191..f0dfd77 100644 --- a/src/soc/amd/stoneyridge/smihandler.c +++ b/src/soc/amd/stoneyridge/smihandler.c @@ -12,9 +12,8 @@ #include <amdblocks/psp_smm.h> #include <soc/smi.h> #include <soc/southbridge.h> - - -#define SMI_0x88_ACPI_COMMAND (1 << 11) +#include <elog.h> +#include <arch/acpi.h>
enum smi_source { SMI_SOURCE_SCI = (1 << 0), @@ -24,6 +23,28 @@ SMI_SOURCE_IRQ_TRAP = (1 << 4), SMI_SOURCE_0x90 = (1 << 5) }; + + +#if IS_ENABLED(CONFIG_ELOG_GSMI) +static void southbridge_smi_gsmi(void) +{ + amd64_smm_state_save_area_t *state_save = + (amd64_smm_state_save_area_t *)SMM_AMD64_SAVE_STATE_OFFSET; + u32 *ret, *param; + uint8_t sub_command; + + /* Command and return value in EAX */ + ret = (u32 *)&state_save->rax; + sub_command = (uint8_t)(*ret >> 8); + + /* Parameter buffer in EBX */ + param = (u32 *)&state_save->rbx; + + /* drivers/elog/gsmi.c */ + *ret = gsmi_exec(sub_command, param); +} +#endif +
static void sb_apmc_smi_handler(void) { @@ -41,8 +62,12 @@ reg32 &= ~(1 << 0); /* clear SCI_EN */ outl(ACPI_PM1_CNT_BLK, reg32); break; +#if IS_ENABLED(CONFIG_ELOG_GSMI) + case ELOG_GSMI_APM_CNT: + southbridge_smi_gsmi(); + break; +#endif } - mainboard_smi_apmc(cmd); }
@@ -53,15 +78,15 @@
static void process_smi_sci(void) { - const uint32_t status = smi_read32(0x10); + const uint32_t status = smi_read32(SMI_REG_SCI_STATUS);
/* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x10, status); + smi_write32(SMI_REG_SCI_STATUS, status); }
static void process_gpe_smi(void) { - const uint32_t status = smi_read32(0x80); + const uint32_t status = smi_read32(SMI_REG_SMISTAT0); const uint32_t gevent_mask = (1 << 24) - 1;
/* Only Bits [23:0] indicate GEVENT SMIs. */ @@ -71,52 +96,79 @@ }
/* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x80, status); + smi_write32(SMI_REG_SMISTAT0, status); }
static void process_smi_0x84(void) { - const uint32_t status = smi_read32(0x84); + const uint32_t status = smi_read32(SMI_REG_SMISTAT1);
/* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x84, status); + smi_write32(SMI_REG_SMISTAT1, status); } + +#if IS_ENABLED(CONFIG_ELOG_GSMI) +static u8 smi_get_slp_typ(void) +{ + u32 reg32; + + reg32 = inl(ACPI_PM1_CNT_BLK); + return (reg32 >> 10) & 0x03; +} +#endif
static void process_smi_0x88(void) { - const uint32_t status = smi_read32(0x88); + const uint32_t status = smi_read32(SMI_REG_SMISTAT2);
- if (status & SMI_0x88_ACPI_COMMAND) { + if (status & SMISTAT2_ACPI_CMD) { /* Command received via ACPI SMI command port */ sb_apmc_smi_handler(); } + + if (status & SMISTAT2_PWRBTN) { + /* Power Button pressed */ +#if IS_ENABLED(CONFIG_ELOG_GSMI) + elog_add_event(ELOG_TYPE_POWER_BUTTON); +#endif + } + + if (status & SMISTAT2_SLPTYP) { + /* Sleep Type */ +#if IS_ENABLED(CONFIG_ELOG_GSMI) + /* Log S3, S4, and S5 entry */ + u8 slp_typ = smi_get_slp_typ(); + if (slp_typ >= ACPI_S3) + elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ); +#endif + } + /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x88, status); + smi_write32(SMI_REG_SMISTAT2, status); }
static void process_smi_0x8c(void) { - const uint32_t status = smi_read32(0x8c); + const uint32_t status = smi_read32(SMI_REG_SMISTAT3);
/* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x8c, status); + smi_write32(SMI_REG_SMISTAT3, status); }
static void process_smi_0x90(void) { - const uint32_t status = smi_read32(0x90); + const uint32_t status = smi_read32(SMI_REG_SMISTAT4);
/* Check for PSP mailbox initialization */ - if (status & SMISTAT4_MEMTRAP_EVT) { + if (status & SMISTAT4_MEMTRAP) psp_smm_init(status); - }
/* Check for PSP mailbox event */ if (status & SMISTAT4_FAKESMI_0) psp_p2cmbox_event(status);
/* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x90, status); + smi_write32(SMI_REG_SMISTAT4, status); }
void smm_southbridge_clear_state(void) @@ -139,7 +191,7 @@
void southbridge_smi_handler(void) { - const uint16_t smi_src = smi_read16(0x94); + const uint16_t smi_src = smi_read16(SMI_REG_SMI_POINTER);
if (smi_src & SMI_SOURCE_SCI) process_smi_sci();