From 599d668cdd8438820d9ca8f54826163662b2a6f0 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Thu, 17 Apr 2014 23:33:50 -0500 Subject: southbridge/hudson: Compile refactored SMI setup utilities in SMM Refactor hudson_enable_gevent_smi() to allow configuring the interrupt mode and trigger level. Move the utilities which are useful in SMM to a separate file that is included in both ramstage and SMM. This is useful for SMI handlers which need to enable or disable GEVENT SMIs on-the-fly. A follow-up patch makes use of this infrastructure. Change-Id: Ifa4c300c00c178b18d7280690cfc4b8367c669b8 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://review.coreboot.org/170 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/southbridge/amd/agesa/hudson/smi_util.c | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/southbridge/amd/agesa/hudson/smi_util.c (limited to 'src/southbridge/amd/agesa/hudson/smi_util.c') diff --git a/src/southbridge/amd/agesa/hudson/smi_util.c b/src/southbridge/amd/agesa/hudson/smi_util.c new file mode 100644 index 0000000000..6076cd43b3 --- /dev/null +++ b/src/southbridge/amd/agesa/hudson/smi_util.c @@ -0,0 +1,79 @@ +/* + * SMM utilities used in both SMM and normal mode + * + * Copyright (C) 2014 Alexandru Gagniuc + * Subject to the GNU GPL v2, or (at your option) any later version. + */ + +#include "smi.h" + +#include + +#define HUDSON_SMI_ACPI_COMMAND 75 + +static void configure_smi(uint8_t smi_num, uint8_t mode) +{ + uint8_t reg32_offset, bit_offset; + uint32_t reg32; + + /* SMI sources range from [0:149] */ + if (smi_num > 149) { + printk(BIOS_WARNING, "BUG: Invalid SMI: %u\n", smi_num); + return; + } + + /* 16 sources per register, 2 bits per source; registers are 4 bytes */ + reg32_offset = (smi_num / 16) * 4; + bit_offset = (smi_num % 16) * 2; + + reg32 = smi_read32(SMI_REG_CONTROL0 + reg32_offset); + reg32 &= ~(0x3 << (bit_offset)); + reg32 |= (mode & 0x3) << bit_offset; + smi_write32(SMI_REG_CONTROL0 + reg32_offset, reg32); +} + +/** + * Configure generation of interrupts for given GEVENT pin + * + * @param gevent The GEVENT pin number. Valid values are 0 thru 23 + * @param mode The type of event this pin should generate. Note that only + * SMI_MODE_SMI generates an SMI. SMI_MODE_DISABLE disables events. + * @param level SMI_LVL_LOW or SMI_LVL_HIGH + */ +void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level) +{ + uint32_t reg32; + /* GEVENT pins range from [0:23] */ + if (gevent > 23) { + printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent); + return; + } + + /* SMI0 source is GEVENT0 and so on */ + configure_smi(gevent, mode); + + /* And set set the trigger level */ + reg32 = smi_read32(SMI_REG_SMITRIG0); + reg32 &= ~(1 << gevent); + reg32 |= (level & 0x1) << gevent; + smi_write32(SMI_REG_SMITRIG0, reg32); +} + +/** Disable events from given GEVENT pin */ +void hudson_disable_gevent_smi(uint8_t gevent) +{ + /* GEVENT pins range from [0:23] */ + if (gevent > 23) { + printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent); + return; + } + + /* SMI0 source is GEVENT0 and so on */ + configure_smi(gevent, SMI_MODE_DISABLE); +} + +/** Enable SMIs on writes to ACPI SMI command port */ +void hudson_enable_acpi_cmd_smi(void) +{ + configure_smi(HUDSON_SMI_ACPI_COMMAND, SMI_MODE_SMI); +} -- cgit v1.2.3