summaryrefslogtreecommitdiff
path: root/src/soc/amd/stoneyridge/smihandler.c
diff options
context:
space:
mode:
authorMarc Jones <marcj303@gmail.com>2017-05-04 21:17:45 -0600
committerMartin Roth <martinroth@google.com>2017-06-26 00:45:41 +0000
commit244848462def7075e0c812a2f71c408668cacfe4 (patch)
treefde926f45d478b36eaebfd1261886c973b803857 /src/soc/amd/stoneyridge/smihandler.c
parenta0199d8e1a96d94828b31f77e0a29a282871a76a (diff)
downloadcoreboot-244848462def7075e0c812a2f71c408668cacfe4.tar.xz
soc: Add AMD Stoney Ridge southbridge code
Copy the Hudson/Kern code from southbridge/amd/pi/hudson. This is the first of a series of patches to migrate Stoney Ridge support from cpu, northbridge, and southbridge to soc/ Changes: - add soc/amd/stoneyridge and soc/amd/common - remove all other Husdon versions - update include paths, etc - clean up Kconfig and Makefile - create chip.c to contain chip_ops Change-Id: Ib88a868e654ad127be70ecc506f6b90b784f8d1b Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/19722 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/amd/stoneyridge/smihandler.c')
-rw-r--r--src/soc/amd/stoneyridge/smihandler.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c
new file mode 100644
index 0000000000..cf95418b7c
--- /dev/null
+++ b/src/soc/amd/stoneyridge/smihandler.c
@@ -0,0 +1,136 @@
+/*
+ * SMI handler for Hudson southbridges
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+#include <soc/hudson.h>
+#include <soc/smi.h>
+
+
+
+#define SMI_0x88_ACPI_COMMAND (1 << 11)
+
+enum smi_source {
+ SMI_SOURCE_SCI = (1 << 0),
+ SMI_SOURCE_GPE = (1 << 1),
+ SMI_SOURCE_0x84 = (1 << 2),
+ SMI_SOURCE_0x88 = (1 << 3),
+ SMI_SOURCE_IRQ_TRAP = (1 << 4),
+ 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;
+ }
+
+ mainboard_smi_apmc(cmd);
+}
+
+int southbridge_io_trap_handler(int smif)
+{
+ return 0;
+}
+
+static void process_smi_sci(void)
+{
+ const uint32_t status = smi_read32(0x10);
+
+ /* Clear events to prevent re-entering SMI if event isn't handled */
+ smi_write32(0x10, status);
+}
+
+static void process_gpe_smi(void)
+{
+ const uint32_t status = smi_read32(0x80);
+ const uint32_t gevent_mask = (1 << 24) - 1;
+
+ /* Only Bits [23:0] indicate GEVENT SMIs. */
+ if (status & gevent_mask) {
+ /* A GEVENT SMI occurred */
+ mainboard_smi_gpi(status & gevent_mask);
+ }
+
+ /* Clear events to prevent re-entering SMI if event isn't handled */
+ smi_write32(0x80, status);
+}
+
+static void process_smi_0x84(void)
+{
+ const uint32_t status = smi_read32(0x84);
+
+ /* Clear events to prevent re-entering SMI if event isn't handled */
+ smi_write32(0x84, status);
+}
+
+static void process_smi_0x88(void)
+{
+ const uint32_t status = smi_read32(0x88);
+
+ if (status & SMI_0x88_ACPI_COMMAND) {
+ /* 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);
+}
+
+static void process_smi_0x8c(void)
+{
+ const uint32_t status = smi_read32(0x8c);
+
+ /* Clear events to prevent re-entering SMI if event isn't handled */
+ smi_write32(0x8c, status);
+}
+
+static void process_smi_0x90(void)
+{
+ const uint32_t status = smi_read32(0x90);
+
+ /* Clear events to prevent re-entering SMI if event isn't handled */
+ smi_write32(0x90, status);
+}
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+ const uint16_t smi_src = smi_read16(0x94);
+
+ if (smi_src & SMI_SOURCE_SCI)
+ process_smi_sci();
+ if (smi_src & SMI_SOURCE_GPE)
+ process_gpe_smi();
+ if (smi_src & SMI_SOURCE_0x84)
+ process_smi_0x84();
+ if (smi_src & SMI_SOURCE_0x88)
+ process_smi_0x88();
+ if (smi_src & SMI_SOURCE_IRQ_TRAP)
+ process_smi_0x8c();
+ if (smi_src & SMI_SOURCE_0x90)
+ process_smi_0x90();
+}
+
+void southbridge_smi_set_eos(void)
+{
+ uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
+ reg |= SMITRG0_EOS;
+ smi_write32(SMI_REG_SMITRIG0, reg);
+}