[coreboot-gerrit] New patch to review for coreboot: 1359768 southbridge/hudson: Add support for ACPI enable/disable via SMI

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Wed Apr 16 01:56:43 CEST 2014


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5511

-gerrit

commit 1359768c92753747cbb4a14252cbfdf55f049b6f
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Mon Apr 14 16:35:34 2014 -0500

    southbridge/hudson: Add support for ACPI enable/disable via SMI
    
    This enables the ACPI SMI command port in the FADT table, and sets up
    the hardware accordingly. If we have SMI enabled, then we don't set
    the SCI_EN bit at boot, causing the OS to send the ACPI_ENABLE
    command, as required by the ACPI spec. This gives us a chance to hook
    into the mainboard_smi_apmc() handler.
    
    Change-Id: Ib4c63d55b3132578dcae48bfe2092d4ea35821dd
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/southbridge/amd/agesa/hudson/fadt.c       | 35 +++++++++++++++++++--------
 src/southbridge/amd/agesa/hudson/hudson.h     | 15 ++++++++++--
 src/southbridge/amd/agesa/hudson/smi.c        |  6 +++++
 src/southbridge/amd/agesa/hudson/smi.h        |  1 +
 src/southbridge/amd/agesa/hudson/smihandler.c | 27 +++++++++++++++++++++
 5 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/src/southbridge/amd/agesa/hudson/fadt.c b/src/southbridge/amd/agesa/hudson/fadt.c
index 04c5a59..fcfbb44 100644
--- a/src/southbridge/amd/agesa/hudson/fadt.c
+++ b/src/southbridge/amd/agesa/hudson/fadt.c
@@ -27,6 +27,7 @@
 #include <arch/io.h>
 #include <device/device.h>
 #include "hudson.h"
+#include "smi.h"
 
 #if CONFIG_HUDSON_LEGACY_FREE
 	#define FADT_BOOT_ARCH ACPI_FADT_LEGACY_FREE
@@ -63,26 +64,41 @@ void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
 	fadt->model = 0;		/* reserved, should be 0 ACPI 3.0 */
 	fadt->preferred_pm_profile = FADT_PM_PROFILE;
 	fadt->sci_int = 9;		/* HUDSON - IRQ 09 – ACPI SCI */
-	fadt->smi_cmd = 0;		/* disable system management mode */
-	fadt->acpi_enable = 0;	/* unused if SMI_CMD = 0 */
-	fadt->acpi_disable = 0;	/* unused if SMI_CMD = 0 */
-	fadt->s4bios_req = 0;	/* unused if SMI_CMD = 0 */
-	fadt->pstate_cnt = 0;	/* unused if SMI_CMD = 0 */
 
-	pm_write16(0x60, ACPI_PM_EVT_BLK);
+	/* We write to this port further down; configure it first */
 	pm_write16(0x62, ACPI_PM1_CNT_BLK);
+
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
+		fadt->smi_cmd = ACPI_SMI_CTL_PORT;
+		fadt->acpi_enable = ACPI_SMI_CMD_ENABLE;
+		fadt->acpi_disable = ACPI_SMI_CMD_DISABLE;
+		fadt->s4bios_req = 0;	/* Not supported */
+		fadt->pstate_cnt = 0;	/* Not supported */
+		fadt->cst_cnt = 0;	/* Not supported */
+		hudson_enable_acpi_cmd_smi();
+		outl(0x0, ACPI_PM1_CNT_BLK);	/* clear SCI_EN */
+	} else {
+		fadt->smi_cmd = 0;	/* disable system management mode */
+		fadt->acpi_enable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->acpi_disable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->s4bios_req = 0;	/* unused if SMI_CMD = 0 */
+		fadt->pstate_cnt = 0;	/* unused if SMI_CMD = 0 */
+		fadt->cst_cnt = 0x00;	/* unused if SMI_CMD = 0 */
+		outl(0x1, ACPI_PM1_CNT_BLK);	/* set SCI_EN */
+	}
+
+	pm_write16(0x60, ACPI_PM_EVT_BLK);
 	pm_write16(0x64, ACPI_PM_TMR_BLK);
 	pm_write16(0x68, ACPI_GPE0_BLK);
 	/* CpuControl is in \_PR.CPU0, 6 bytes */
 	pm_write16(0x66, ACPI_CPU_CONTROL);
-	pm_write16(0x6A, 0);	/* AcpiSmiCmd */
+	pm_write16(0x6a, fadt->smi_cmd);
 
 	pm_write8(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2); /* AcpiDecodeEnable, When set, SB uses
 					* the contents of the PM registers at
 					* index 60-6B to decode ACPI I/O address.
 					* AcpiSmiEn & SmiCmdEn*/
-	/* RTC_En_En, TMR_En_En, GBL_EN_EN */
-	outl(0x1, ACPI_PM1_CNT_BLK);			/* set SCI_EN */
+
 	fadt->pm1a_evt_blk = ACPI_PM_EVT_BLK;
 	fadt->pm1b_evt_blk = 0x0000;
 	fadt->pm1a_cnt_blk = ACPI_PM1_CNT_BLK;
@@ -100,7 +116,6 @@ void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
 	fadt->gpe1_blk_len = 0;
 	fadt->gpe1_base = 0;
 
-	fadt->cst_cnt = 0x00;	/* unused if SMI_CMD = 0 */
 	fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
 	fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
 	fadt->flush_size = 0;	/* set to 0 if WBINVD is 1 in flags */
diff --git a/src/southbridge/amd/agesa/hudson/hudson.h b/src/southbridge/amd/agesa/hudson/hudson.h
index 73e7bd4..86b4238 100644
--- a/src/southbridge/amd/agesa/hudson/hudson.h
+++ b/src/southbridge/amd/agesa/hudson/hudson.h
@@ -29,6 +29,8 @@
 #define BIOSRAM_DATA	0xcd5
 #define PM_INDEX	0xcd6
 #define PM_DATA		0xcd7
+#define PM2_INDEX	0xcd0
+#define PM2_DATA	0xcd1
 
 #define HUDSON_ACPI_IO_BASE 0x800
 
@@ -46,9 +48,17 @@
 #define PM1_TMR_BLK_ADDRESS                     0x808                           //      AcpiPmTmrBlkAddr;
 #define CPU_CNT_BLK_ADDRESS                     0x810                           //      CpuControlBlkAddr;
 #define GPE0_BLK_ADDRESS                        0x820                           //  AcpiGpe0BlkAddr;
-#define SMI_CMD_PORT                            0xB0                            //      SmiCmdPortAddr;
 #define SPIROM_BASE_ADDRESS_REGISTER    0xA0
 
+#define ACPI_SMI_CTL_PORT		0xb2
+#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_S4_REQ		0xc0
+
+#ifndef __SMM__
+
 void pm_write8(u8 reg, u8 value);
 u8 pm_read8(u8 reg);
 void pm_write16(u8 reg, u16 value);
@@ -70,6 +80,7 @@ void hudson_enable(device_t dev);
 void __attribute__((weak)) hudson_setup_sata_phys(struct device *dev);
 void s3_resume_init_data(void *FchParams);
 
-#endif
+#endif /* __PRE_RAM__ */
+#endif /* __SMM__ */
 
 #endif /* HUDSON_H */
diff --git a/src/southbridge/amd/agesa/hudson/smi.c b/src/southbridge/amd/agesa/hudson/smi.c
index f95d713..39d7c19 100644
--- a/src/southbridge/amd/agesa/hudson/smi.c
+++ b/src/southbridge/amd/agesa/hudson/smi.c
@@ -59,3 +59,9 @@ void hudson_enable_gevent_smi(uint8_t gevent)
 	/* SMI0 source is GEVENT0 and so on */
 	enable_smi(gevent);
 }
+
+/** Enable SMIs on writes to ACPI SMI command port */
+void hudson_enable_acpi_cmd_smi(void)
+{
+	enable_smi(75);
+}
diff --git a/src/southbridge/amd/agesa/hudson/smi.h b/src/southbridge/amd/agesa/hudson/smi.h
index 3702b66..2d6ab4c 100644
--- a/src/southbridge/amd/agesa/hudson/smi.h
+++ b/src/southbridge/amd/agesa/hudson/smi.h
@@ -39,6 +39,7 @@ static inline void smi_write16(uint8_t offset, uint16_t value)
 #ifndef __SMM__
 void hudson_enable_smi_generation(void);
 void hudson_enable_gevent_smi(uint8_t gevent);
+void hudson_enable_acpi_cmd_smi(void);
 #endif
 
 #endif /* _SOUTHBRIDGE_AMD_AGESA_HUDSON_SMI_H */
diff --git a/src/southbridge/amd/agesa/hudson/smihandler.c b/src/southbridge/amd/agesa/hudson/smihandler.c
index b8bfaee..b535227 100644
--- a/src/southbridge/amd/agesa/hudson/smihandler.c
+++ b/src/southbridge/amd/agesa/hudson/smihandler.c
@@ -5,6 +5,7 @@
  * Subject to the GNU GPL v2, or (at your option) any later version.
  */
 
+#include "hudson.h"
 #include "smi.h"
 
 #include <console/console.h>
@@ -21,6 +22,28 @@ enum smi_source {
 	SMI_SOURCE_0x90 = (1 << 5)
 };
 
+static void hudson_apmc_smi_handler(void)
+{
+	u32 reg32;
+	const uint8_t cmd = inb(ACPI_SMI_CTL_PORT);
+
+	switch (cmd) {
+	case ACPI_SMI_CMD_ENABLE:
+		reg32 = inl(ACPI_PM1_CNT_BLK);
+		reg32 |= (1 << 0);	/* SCI_EN */
+		outl(reg32, ACPI_PM1_CNT_BLK);
+		break;
+	case ACPI_SMI_CMD_DISABLE:
+		reg32 = inl(ACPI_PM1_CNT_BLK);
+		reg32 &= ~(1 << 0);	/* clear SCI_EN */
+		outl(ACPI_PM1_CNT_BLK, reg32);
+		break;
+	}
+
+	if (mainboard_smi_apmc)
+		mainboard_smi_apmc(cmd);
+}
+
 int southbridge_io_trap_handler(int smif)
 {
 	return 0;
@@ -62,6 +85,10 @@ static void process_smi_0x88(void)
 {
 	const uint32_t status = smi_read32(0x88);
 
+	if (status & (1 << 11)) {
+		/* Command received via ACPI SMI command port */
+		hudson_apmc_smi_handler();
+	}
 	/* Clear events to prevent re-entering SMI if event isn't handled */
 	smi_write32(0x88, status);
 }



More information about the coreboot-gerrit mailing list