From 269563a423f9291e84b5a93859a3e17767cf27a0 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Mon, 19 Jan 2009 21:20:22 +0000 Subject: [PATCH] First shot at factoring SMM code into generic parts and southbridge specific parts. This should help to reduce the code duplication for Rudolf's K8/VIA SMM implementation... Signed-off-by: Stefan Reinauer Acked-by: Joseph Smith git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3870 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/cpu/amd/model_10xxx/Config.lb | 1 + src/cpu/amd/model_fxx/Config.lb | 1 + src/cpu/amd/model_gx1/Config.lb | 1 + src/cpu/amd/model_gx2/Config.lb | 3 +- src/cpu/amd/model_lx/Config.lb | 3 +- src/cpu/intel/ep80579/Config.lb | 1 + src/cpu/intel/model_69x/Config.lb | 1 + src/cpu/intel/model_6dx/Config.lb | 1 + src/cpu/intel/model_6ex/Config.lb | 1 + src/cpu/intel/model_6fx/Config.lb | 1 + src/cpu/intel/model_6xx/Config.lb | 1 + src/cpu/intel/model_f0x/Config.lb | 1 + src/cpu/intel/model_f1x/Config.lb | 1 + src/cpu/intel/model_f2x/Config.lb | 1 + src/cpu/intel/model_f3x/Config.lb | 1 + src/cpu/intel/model_f4x/Config.lb | 1 + src/cpu/via/model_c3/Config.lb | 1 + src/cpu/via/model_c7/Config.lb | 1 + src/cpu/x86/smm/Config.lb | 47 ++++ src/cpu/x86/smm/smihandler.c | 203 ++++++++++++++++++ .../intel/i82801gx => cpu/x86/smm}/smm.ld | 0 .../i82801gx => cpu/x86/smm}/smmhandler.S | 0 .../i82801gx => cpu/x86/smm}/smmrelocate.S | 0 src/southbridge/intel/i82801gx/Config.lb | 35 +-- src/southbridge/intel/i82801gx/i82801gx_lpc.c | 5 + .../{smihandler.c => i82801gx_smihandler.c} | 153 +------------ util/newconfig/config.g | 49 +++++ 27 files changed, 336 insertions(+), 178 deletions(-) create mode 100644 src/cpu/x86/smm/Config.lb create mode 100644 src/cpu/x86/smm/smihandler.c rename src/{southbridge/intel/i82801gx => cpu/x86/smm}/smm.ld (100%) rename src/{southbridge/intel/i82801gx => cpu/x86/smm}/smmhandler.S (100%) rename src/{southbridge/intel/i82801gx => cpu/x86/smm}/smmrelocate.S (100%) rename src/southbridge/intel/i82801gx/{smihandler.c => i82801gx_smihandler.c} (79%) diff --git a/src/cpu/amd/model_10xxx/Config.lb b/src/cpu/amd/model_10xxx/Config.lb index 94aa01afa..47303be0e 100644 --- a/src/cpu/amd/model_10xxx/Config.lb +++ b/src/cpu/amd/model_10xxx/Config.lb @@ -31,6 +31,7 @@ dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache dir /cpu/x86/pae +dir /cpu/x86/smm dir /cpu/amd/mtrr dir /cpu/amd/quadcore dir /cpu/amd/microcode diff --git a/src/cpu/amd/model_fxx/Config.lb b/src/cpu/amd/model_fxx/Config.lb index 0adfa28d0..60463e3e6 100644 --- a/src/cpu/amd/model_fxx/Config.lb +++ b/src/cpu/amd/model_fxx/Config.lb @@ -12,6 +12,7 @@ dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache dir /cpu/x86/pae +dir /cpu/x86/smm dir /cpu/amd/mtrr dir /cpu/amd/dualcore dir /cpu/amd/microcode diff --git a/src/cpu/amd/model_gx1/Config.lb b/src/cpu/amd/model_gx1/Config.lb index bf76bd97f..4a79a3052 100644 --- a/src/cpu/amd/model_gx1/Config.lb +++ b/src/cpu/amd/model_gx1/Config.lb @@ -3,4 +3,5 @@ dir /cpu/x86/fpu dir /cpu/x86/mmx dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm driver model_gx1_init.o diff --git a/src/cpu/amd/model_gx2/Config.lb b/src/cpu/amd/model_gx2/Config.lb index e05141c5d..8294c4521 100644 --- a/src/cpu/amd/model_gx2/Config.lb +++ b/src/cpu/amd/model_gx2/Config.lb @@ -3,6 +3,7 @@ dir /cpu/x86/fpu dir /cpu/x86/mmx dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm driver model_gx2_init.o object cpubug.o -object vsmsetup.o \ No newline at end of file +object vsmsetup.o diff --git a/src/cpu/amd/model_lx/Config.lb b/src/cpu/amd/model_lx/Config.lb index 43c625406..42e90e436 100644 --- a/src/cpu/amd/model_lx/Config.lb +++ b/src/cpu/amd/model_lx/Config.lb @@ -3,6 +3,7 @@ dir /cpu/x86/fpu dir /cpu/x86/mmx dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm driver model_lx_init.o object cpubug.o -object vsmsetup.o \ No newline at end of file +object vsmsetup.o diff --git a/src/cpu/intel/ep80579/Config.lb b/src/cpu/intel/ep80579/Config.lb index 4bf4ee392..626af76dc 100644 --- a/src/cpu/intel/ep80579/Config.lb +++ b/src/cpu/intel/ep80579/Config.lb @@ -26,5 +26,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver ep80579_init.o diff --git a/src/cpu/intel/model_69x/Config.lb b/src/cpu/intel/model_69x/Config.lb index 03a4fd70f..46909d27f 100644 --- a/src/cpu/intel/model_69x/Config.lb +++ b/src/cpu/intel/model_69x/Config.lb @@ -5,5 +5,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_69x_init.o diff --git a/src/cpu/intel/model_6dx/Config.lb b/src/cpu/intel/model_6dx/Config.lb index 46656a005..15746148e 100644 --- a/src/cpu/intel/model_6dx/Config.lb +++ b/src/cpu/intel/model_6dx/Config.lb @@ -5,5 +5,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_6dx_init.o diff --git a/src/cpu/intel/model_6ex/Config.lb b/src/cpu/intel/model_6ex/Config.lb index f45d70f9e..a9c453737 100644 --- a/src/cpu/intel/model_6ex/Config.lb +++ b/src/cpu/intel/model_6ex/Config.lb @@ -8,6 +8,7 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode dir /cpu/intel/hyperthreading driver model_6ex_init.o diff --git a/src/cpu/intel/model_6fx/Config.lb b/src/cpu/intel/model_6fx/Config.lb index 549022d99..74f8be616 100644 --- a/src/cpu/intel/model_6fx/Config.lb +++ b/src/cpu/intel/model_6fx/Config.lb @@ -8,6 +8,7 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode dir /cpu/intel/hyperthreading driver model_6fx_init.o diff --git a/src/cpu/intel/model_6xx/Config.lb b/src/cpu/intel/model_6xx/Config.lb index 5b1fde1ba..de33edd64 100644 --- a/src/cpu/intel/model_6xx/Config.lb +++ b/src/cpu/intel/model_6xx/Config.lb @@ -5,5 +5,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_6xx_init.o diff --git a/src/cpu/intel/model_f0x/Config.lb b/src/cpu/intel/model_f0x/Config.lb index 2458c81c1..6afad2ad4 100644 --- a/src/cpu/intel/model_f0x/Config.lb +++ b/src/cpu/intel/model_f0x/Config.lb @@ -7,5 +7,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_f0x_init.o diff --git a/src/cpu/intel/model_f1x/Config.lb b/src/cpu/intel/model_f1x/Config.lb index 5387d455f..b6ae5085e 100644 --- a/src/cpu/intel/model_f1x/Config.lb +++ b/src/cpu/intel/model_f1x/Config.lb @@ -7,5 +7,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_f1x_init.o diff --git a/src/cpu/intel/model_f2x/Config.lb b/src/cpu/intel/model_f2x/Config.lb index 3cf506293..314205f71 100644 --- a/src/cpu/intel/model_f2x/Config.lb +++ b/src/cpu/intel/model_f2x/Config.lb @@ -7,6 +7,7 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode dir /cpu/intel/hyperthreading driver model_f2x_init.o diff --git a/src/cpu/intel/model_f3x/Config.lb b/src/cpu/intel/model_f3x/Config.lb index 175ff5891..0f80cd853 100644 --- a/src/cpu/intel/model_f3x/Config.lb +++ b/src/cpu/intel/model_f3x/Config.lb @@ -7,6 +7,7 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode dir /cpu/intel/hyperthreading driver model_f3x_init.o diff --git a/src/cpu/intel/model_f4x/Config.lb b/src/cpu/intel/model_f4x/Config.lb index 66f6ceb00..cef79889e 100644 --- a/src/cpu/intel/model_f4x/Config.lb +++ b/src/cpu/intel/model_f4x/Config.lb @@ -7,6 +7,7 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode dir /cpu/intel/hyperthreading driver model_f4x_init.o diff --git a/src/cpu/via/model_c3/Config.lb b/src/cpu/via/model_c3/Config.lb index 174d3ccc1..de7d9142a 100644 --- a/src/cpu/via/model_c3/Config.lb +++ b/src/cpu/via/model_c3/Config.lb @@ -26,5 +26,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_c3_init.o diff --git a/src/cpu/via/model_c7/Config.lb b/src/cpu/via/model_c7/Config.lb index 6bc600190..d95683216 100644 --- a/src/cpu/via/model_c7/Config.lb +++ b/src/cpu/via/model_c7/Config.lb @@ -26,5 +26,6 @@ dir /cpu/x86/mmx dir /cpu/x86/sse dir /cpu/x86/lapic dir /cpu/x86/cache +dir /cpu/x86/smm dir /cpu/intel/microcode driver model_c7_init.o diff --git a/src/cpu/x86/smm/Config.lb b/src/cpu/x86/smm/Config.lb new file mode 100644 index 000000000..8edbabdf3 --- /dev/null +++ b/src/cpu/x86/smm/Config.lb @@ -0,0 +1,47 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2008 coresystems GmbH +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +uses HAVE_SMI_HANDLER + +if HAVE_SMI_HANDLER + object smmrelocate.S + + smmobject smmhandler.S + smmobject smihandler.o + + makerule smm.o + depends "$(SMM-OBJECTS) printk.o vtxprintf.o $(LIBGCC_FILE_NAME)" + action "$(CC) $(DISTRO_LFLAGS) -nostdlib -r -o $@ $(SMM-OBJECTS) printk.o vtxprintf.o $(LIBGCC_FILE_NAME)" + end + + makerule smm + depends "smm.o $(TOP)/src/cpu/x86/smm/smm.ld ldoptions" + action "$(CC) $(DISTRO_LFLAGS) -nostdlib -nostartfiles -static -o smm.elf -T $(TOP)/src/cpu/x86/smm/smm.ld smm.o" + action "$(CROSS_COMPILE)nm -n smm.elf | sort > smm.map" + action "$(OBJCOPY) -O binary smm.elf smm" + end + + makerule smm_bin.c + depends "smm" + action "(echo 'unsigned char smm[] = {'; od -vtx1 smm | sed -e 's,^[0-9]* *,,' -e 's:[0-9a-f][0-9a-f] :0x&,:g' -e 's:[0-9a-f][0-9a-f]$$:0x&,:'; echo '}; unsigned int smm_len = '; wc -c smm |awk '{print $$1;}' ; echo ';') > smm_bin.c" + end + + object ./smm_bin.o +end diff --git a/src/cpu/x86/smm/smihandler.c b/src/cpu/x86/smm/smihandler.c new file mode 100644 index 000000000..0dc892665 --- /dev/null +++ b/src/cpu/x86/smm/smihandler.c @@ -0,0 +1,203 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +void southbridge_smi_set_eos(void); + +#define DEBUG_SMI + +typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore; + +/* SMI multiprocessing semaphore */ +static volatile smi_semaphore smi_handler_status = SMI_UNLOCKED; + +static int smi_obtain_lock(void) +{ + u8 ret = SMI_LOCKED; + + asm volatile ( + "movb %2, %%al\n" + "xchgb %%al, %1\n" + "movb %%al, %0\n" + : "=g" (ret), "=m" (smi_handler_status) + : "g" (SMI_LOCKED) + : "eax" + ); + + return (ret == SMI_UNLOCKED); +} + +static void smi_release_lock(void) +{ + asm volatile ( + "movb %1, %%al\n" + "xchgb %%al, %0\n" + : "=m" (smi_handler_status) + : "g" (SMI_UNLOCKED) + : "eax" + ); +} + +#define LAPIC_ID 0xfee00020 +static inline __attribute__((always_inline)) unsigned long nodeid(void) +{ + return (*((volatile unsigned long *)(LAPIC_ID)) >> 24); +} + +/* ********************* smi_util ************************* */ + +/* Data */ +#define UART_RBR 0x00 +#define UART_TBR 0x00 + +/* Control */ +#define UART_IER 0x01 +#define UART_IIR 0x02 +#define UART_FCR 0x02 +#define UART_LCR 0x03 +#define UART_MCR 0x04 +#define UART_DLL 0x00 +#define UART_DLM 0x01 + +/* Status */ +#define UART_LSR 0x05 +#define UART_MSR 0x06 +#define UART_SCR 0x07 + +static int uart_can_tx_byte(void) +{ + return inb(TTYS0_BASE + UART_LSR) & 0x20; +} + +static void uart_wait_to_tx_byte(void) +{ + while(!uart_can_tx_byte()) + ; +} + +static void uart_wait_until_sent(void) +{ + while(!(inb(TTYS0_BASE + UART_LSR) & 0x40)) + ; +} + +static void uart_tx_byte(unsigned char data) +{ + uart_wait_to_tx_byte(); + outb(data, TTYS0_BASE + UART_TBR); + /* Make certain the data clears the fifos */ + uart_wait_until_sent(); +} + +void console_tx_flush(void) +{ + uart_wait_to_tx_byte(); +} + +void console_tx_byte(unsigned char byte) +{ + if (byte == '\n') + uart_tx_byte('\r'); + uart_tx_byte(byte); +} + +/* ********************* smi_util ************************* */ + + +void io_trap_handler(int smif) +{ + southbridge_io_trap_handler(smif); +} + +/** + * @brief Set the EOS bit + */ +static void smi_set_eos(void) +{ + southbridge_smi_set_eos(); +} + +/** + * @brief Interrupt handler for SMI# + * + * @param smm_revision revision of the smm state save map + */ + +void smi_handler(u32 smm_revision) +{ + u8 reg8; + u16 pmctrl; + u16 pm1_sts; + u32 smi_sts, gpe0_sts, tco_sts; + unsigned int node; + smm_state_save_area_t state_save; + + /* Are we ok to execute the handler? */ + if (!smi_obtain_lock()) + return; + + node=nodeid(); + +#ifdef DEBUG_SMI + console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; +#else + console_loglevel = 1; +#endif + + printk_debug("\nSMI# #%d\n", node); + + switch (smm_revision) { + case 0x00030007: + state_save.type = LEGACY; + state_save.legacy_state_save = (legacy_smm_state_save_area_t *) + (0xa8000 + 0x7e00 - (node * 0x400)); + break; + case 0x00030100: + state_save.type = EM64T; + state_save.em64t_state_save = (em64t_smm_state_save_area_t *) + (0xa8000 + 0x7d00 - (node * 0x400)); + break; + case 0x00030064: + state_save.type = AMD64; + state_save.amd64_state_save = (amd64_smm_state_save_area_t *) + (0xa8000 + 0x7e00 - (node * 0x400)); + break; + default: + printk_debug("smm_revision: 0x%08x\n", smm_revision); + printk_debug("SMI# not supported on your CPU\n"); + /* Don't release lock, so no further SMI will happen, + * if we don't handle it anyways. + */ + return; + } + + southbridge_smi_handler(node, &state_save); + + smi_release_lock(); + + /* De-assert SMI# signal to allow another SMI */ + smi_set_eos(); +} diff --git a/src/southbridge/intel/i82801gx/smm.ld b/src/cpu/x86/smm/smm.ld similarity index 100% rename from src/southbridge/intel/i82801gx/smm.ld rename to src/cpu/x86/smm/smm.ld diff --git a/src/southbridge/intel/i82801gx/smmhandler.S b/src/cpu/x86/smm/smmhandler.S similarity index 100% rename from src/southbridge/intel/i82801gx/smmhandler.S rename to src/cpu/x86/smm/smmhandler.S diff --git a/src/southbridge/intel/i82801gx/smmrelocate.S b/src/cpu/x86/smm/smmrelocate.S similarity index 100% rename from src/southbridge/intel/i82801gx/smmrelocate.S rename to src/cpu/x86/smm/smmrelocate.S diff --git a/src/southbridge/intel/i82801gx/Config.lb b/src/southbridge/intel/i82801gx/Config.lb index 3117ad202..0ef93e89f 100644 --- a/src/southbridge/intel/i82801gx/Config.lb +++ b/src/southbridge/intel/i82801gx/Config.lb @@ -18,6 +18,8 @@ ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ## +uses HAVE_SMI_HANDLER + config chip.h driver i82801gx.o driver i82801gx_ac97.o @@ -33,34 +35,7 @@ driver i82801gx_usb_ehci.o object i82801gx_reset.o object i82801gx_watchdog.o -object i82801gx_smi.o -object smmrelocate.S - -makerule smmhandler.o - depends "$(TOP)/src/southbridge/intel/i82801gx/smmhandler.S" - action "@$(CC) -c $(CPU_OPT) $(CPPFLAGS) $(CFLAGS) -o $@ $<" -end - -makerule smihandler.o - depends "$(TOP)/src/southbridge/intel/i82801gx/smihandler.c" - action "@$(CC) -c $(CPU_OPT) $(CPPFLAGS) $(CFLAGS) -o $@ $<" -end - -makerule smm.o - depends "smmhandler.o smihandler.o printk.o vtxprintf.o $(LIBGCC_FILE_NAME)" - action "$(CC) $(DISTRO_LFLAGS) -nostdlib -r -o $@ smmhandler.o smihandler.o printk.o vtxprintf.o $(LIBGCC_FILE_NAME)" +if HAVE_SMI_HANDLER + object i82801gx_smi.o + smmobject i82801gx_smihandler.o end - -makerule smm - depends "smm.o $(TOP)/src/southbridge/intel/i82801gx/smm.ld ldoptions" - action "$(CC) $(DISTRO_LFLAGS) -nostdlib -nostartfiles -static -o smm.elf -T $(TOP)/src/southbridge/intel/i82801gx/smm.ld smm.o" - action "$(CROSS_COMPILE)nm -n smm.elf | sort > smm.map" - action "$(OBJCOPY) -O binary smm.elf smm" -end - -makerule smm_bin.c - depends "smm" - action "(echo 'unsigned char smm[] = {'; od -vtx1 smm | sed -e 's,^[0-9]* *,,' -e 's:[0-9a-f][0-9a-f] :0x&,:g' -e 's:[0-9a-f][0-9a-f]$$:0x&,:'; echo '}; unsigned int smm_len = '; wc -c smm |awk '{print $$1;}' ; echo ';') > smm_bin.c" -end - -object ./smm_bin.o diff --git a/src/southbridge/intel/i82801gx/i82801gx_lpc.c b/src/southbridge/intel/i82801gx/i82801gx_lpc.c index 13eb9e0ed..cb1f42c51 100644 --- a/src/southbridge/intel/i82801gx/i82801gx_lpc.c +++ b/src/southbridge/intel/i82801gx/i82801gx_lpc.c @@ -197,6 +197,8 @@ static void enable_hpet(struct device *dev) /* TODO */ } + +#if HAVE_SMI_HANDLER static void i82801gx_lock_smm(struct device *dev) { void smm_lock(void); @@ -243,6 +245,7 @@ static void i82801gx_lock_smm(struct device *dev) printk_debug("Done.\n"); #endif } +#endif static void lpc_init(struct device *dev) { @@ -276,7 +279,9 @@ static void lpc_init(struct device *dev) setup_i8259(); +#if HAVE_SMI_HANDLER i82801gx_lock_smm(dev); +#endif } static void i82801gx_lpc_read_resources(device_t dev) diff --git a/src/southbridge/intel/i82801gx/smihandler.c b/src/southbridge/intel/i82801gx/i82801gx_smihandler.c similarity index 79% rename from src/southbridge/intel/i82801gx/smihandler.c rename to src/southbridge/intel/i82801gx/i82801gx_smihandler.c index 8e5569ad2..e15dcad53 100644 --- a/src/southbridge/intel/i82801gx/smihandler.c +++ b/src/southbridge/intel/i82801gx/i82801gx_smihandler.c @@ -24,7 +24,7 @@ #include #include #include -#include "chip.h" +//#include "chip.h" // Future TODO: Move to i82801gx directory #include "../../../northbridge/intel/i945/ich7.h" @@ -34,6 +34,7 @@ #define ACPI_DISABLE 0x1e #define ACPI_ENABLE 0xe1 + /* I945 */ #define SMRAM 0x9d #define D_OPEN (1 << 6) @@ -84,45 +85,6 @@ */ static u16 pmbase = DEFAULT_PMBASE; -typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore; - -/* SMI multiprocessing semaphore */ -static volatile smi_semaphore smi_handler_status = SMI_UNLOCKED; - -static int smi_obtain_lock(void) -{ - u8 ret = SMI_LOCKED; - - asm volatile ( - "movb %2, %%al\n" - "xchgb %%al, %1\n" - "movb %%al, %0\n" - : "=g" (ret), "=m" (smi_handler_status) - : "g" (SMI_LOCKED) - : "eax" - ); - - return (ret == SMI_UNLOCKED); -} - -static void smi_release_lock(void) -{ - asm volatile ( - "movb %1, %%al\n" - "xchgb %%al, %0\n" - : "=m" (smi_handler_status) - : "g" (SMI_UNLOCKED) - : "eax" - ); -} - -#define LAPIC_ID 0xfee00020 -static inline __attribute__((always_inline)) unsigned long nodeid(void) -{ - return (*((volatile unsigned long *)(LAPIC_ID)) >> 24); -} - - /** * @brief read and clear PM1_STS * @return PM1_STS register @@ -273,73 +235,13 @@ static void dump_tco_status(u32 tco_sts) } -/* ********************* smi_util ************************* */ - -/* Data */ -#define UART_RBR 0x00 -#define UART_TBR 0x00 - -/* Control */ -#define UART_IER 0x01 -#define UART_IIR 0x02 -#define UART_FCR 0x02 -#define UART_LCR 0x03 -#define UART_MCR 0x04 -#define UART_DLL 0x00 -#define UART_DLM 0x01 - -/* Status */ -#define UART_LSR 0x05 -#define UART_MSR 0x06 -#define UART_SCR 0x07 - -static int uart_can_tx_byte(void) -{ - return inb(TTYS0_BASE + UART_LSR) & 0x20; -} - -static void uart_wait_to_tx_byte(void) -{ - while(!uart_can_tx_byte()) - ; -} - -static void uart_wait_until_sent(void) -{ - while(!(inb(TTYS0_BASE + UART_LSR) & 0x40)) - ; -} - -static void uart_tx_byte(unsigned char data) -{ - uart_wait_to_tx_byte(); - outb(data, TTYS0_BASE + UART_TBR); - /* Make certain the data clears the fifos */ - uart_wait_until_sent(); -} - -void console_tx_flush(void) -{ - uart_wait_to_tx_byte(); -} - -void console_tx_byte(unsigned char byte) -{ - if (byte == '\n') - uart_tx_byte('\r'); - uart_tx_byte(byte); -} - /* We are using PCIe accesses for now * 1. the chipset can do it * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind */ #include "../../../northbridge/intel/i945/pcie_config.c" -/* ********************* smi_util ************************* */ - - -void io_trap_handler(int smif) +void southbridge_io_trap_handler(int smif) { u8 reg8; global_nvs_t *gnvs = (global_nvs_t *)0xc00; @@ -374,10 +276,10 @@ void io_trap_handler(int smif) /** * @brief Set the EOS bit */ -static void smi_set_eos(void) +void southbridge_smi_set_eos(void) { u8 reg8; - + reg8 = inb(pmbase + SMI_EN); reg8 |= EOS; outb(reg8, pmbase + SMI_EN); @@ -389,52 +291,16 @@ static void smi_set_eos(void) * @param smm_revision revision of the smm state save map */ -void smi_handler(u32 smm_revision) +void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save) { u8 reg8; u16 pmctrl; u16 pm1_sts; u32 smi_sts, gpe0_sts, tco_sts; - unsigned int node; - smm_state_save_area_t state_save; - - /* Are we ok to execute the handler? */ - if (!smi_obtain_lock()) - return; - - node=nodeid(); - -#ifdef DEBUG_SMI - console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; -#else - console_loglevel = 1; -#endif - - printk_debug("\nSMI# #%d\n", node); - - switch (smm_revision) { - case 0x00030007: - state_save.type = LEGACY; - state_save.legacy_state_save = (legacy_smm_state_save_area_t *) - (0xa8000 + 0x7e00 - (node * 0x400)); - break; - case 0x00030100: - state_save.type = EM64T; - state_save.em64t_state_save = (em64t_smm_state_save_area_t *) - (0xa8000 + 0x7d00 - (node * 0x400)); - break; - default: - printk_debug("smm_revision: 0x%08x\n", smm_revision); - printk_debug("SMI# not supported on your CPU\n"); - /* Don't release lock, so no further SMI will happen, - * if we don't handle it anyways. - */ - return; - } pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc; printk_spew("SMI#: pmbase = 0x%04x\n", pmbase); - + /* We need to clear the SMI status registers, or we won't see what's * happening in the following calls. */ @@ -543,9 +409,4 @@ void smi_handler(u32 smm_revision) printk_debug("....\n"); } - - smi_release_lock(); - - /* De-assert SMI# signal to allow another SMI */ - smi_set_eos(); } diff --git a/util/newconfig/config.g b/util/newconfig/config.g index 93e36bbde..294d40721 100644 --- a/util/newconfig/config.g +++ b/util/newconfig/config.g @@ -226,6 +226,9 @@ class romimage: # driver files added by 'driver' directive self.driverrules = {} + # smm object files added by 'smmobject' directive + self.smmobjectrules = {} + # loader scripts added by 'ldscript' directive self.ldscripts = [] @@ -344,6 +347,9 @@ class romimage: def adddriverrule(self, name): self.addobjectdriver(self.driverrules, name) + def addsmmobjectrule(self, name): + self.addobjectdriver(self.smmobjectrules, name) + def getinitobjectrules(self): return self.initobjectrules @@ -371,6 +377,15 @@ class romimage: return o fatal("No such driver rule \"%s\"" % name) + def getsmmobjectrules(self): + return self.smmobjectrules + + def getsmmobjectrule(self, name): + o = getdict(self.smmobjectrules, name) + if (o): + return o + fatal("No such smm object rule \"%s\"" % name) + def addldscript(self, path): self.ldscripts.append(path) @@ -1370,6 +1385,10 @@ def adddriver(driver_name): global curimage curimage.adddriverrule(driver_name) +def addsmmobject(object_name): + global curimage + curimage.addsmmobjectrule(object_name) + def target(name): global target_dir, target_name print "Configuring TARGET %s" % name @@ -1593,6 +1612,7 @@ parser Config: token PRINT: 'print' token REGISTER: 'register' token ROMIMAGE: 'romimage' + token SMMOBJECT: 'smmobject' token SOUTHBRIDGE: 'southbridge' token SUPERIO: 'superio' token TARGET: 'target' @@ -1693,6 +1713,10 @@ parser Config: rule driver<>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}} + rule smmobject<>: + SMMOBJECT DIRPATH {{ if (C): addsmmobject(DIRPATH)}} + + rule dir<>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }} rule default<>: DEFAULT ID EQ value {{ if (C): setdefault(ID, value, 0) }} @@ -1826,6 +1850,7 @@ parser Config: | prtstmt<> {{ return prtstmt }} | register<> {{ return register }} | device<> {{ return device }} + | smmobject<> {{ return smmobject }} # ENTRY for parsing Config.lb file rule cfgfile: (uses<<1>>)* @@ -2028,6 +2053,13 @@ def writeimagemakefile(image): file.write("OBJECTS += %s\n" % (obj_name)) file.write("SOURCES += %s\n" % (obj_source)) + for srule, smm in image.getsmmobjectrules().items(): + s_name = smm[0] + s_source = smm[1] + file.write("SMM-OBJECTS += %s\n" % (s_name)) + file.write("SOURCES += %s\n" % (s_source)) + + # for chip_target.c file.write("OBJECTS += static.o\n") file.write("SOURCES += static.c\n") @@ -2104,6 +2136,23 @@ def writeimagemakefile(image): file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") #file.write("%s\n" % objrule[2]) + file.write("\n# smmobjectrules:\n") + for irule, smm in image.getsmmobjectrules().items(): + source = topify(smm[1]) + type = smm[2] + if (type == 'S'): + # for .S, .o depends on .s + file.write("%s: %s.s\n" % (smm[0], smm[3])) + file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n") + # and .s depends on .S + file.write("%s.s: %s\n" % (smm[3], source)) + # Note: next 2 lines are ONE output line! + file.write("\t$(CPP) $(CPPFLAGS) $< ") + file.write(">$@.new && mv $@.new $@\n") + else: + file.write("%s: %s\n" % (smm[0], source)) + file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") + # special rule for chip_target.c file.write("static.o: static.c\n") file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") -- 2.25.1