Stefan Reinauer ([email protected]) just uploaded a new patch set to 
gerrit, which you can find at http://review.coreboot.org/1309

-gerrit

commit fe5a5548bd833818ec15d2fa6ad121794dd29d62
Author: Duncan Laurie <[email protected]>
Date:   Sat Jun 23 15:22:43 2012 -0700

    SMM: Fix state save map for sandybridge and TSEG
    
    There are enough differences that it is worth defining the
    proper map for the sandybridge/ivybridge CPUs.  The state
    save map was not being addressed properly for TSEG and
    needs to use the right offset instead of pointing in ASEG.
    
    To do this properly add a required southbridge export to
    return the TSEG base and use that where appropriate.
    
    Change-Id: Idad153ed6c07d2633cb3d53eddd433a3df490834
    Signed-off-by: Duncan Laurie <[email protected]>
---
 src/cpu/x86/smm/smihandler.c               |   20 +++++--
 src/include/cpu/x86/smm.h                  |   95 ++++++++++++++++++++++++++++
 src/southbridge/intel/bd82x6x/smihandler.c |   28 +++++----
 3 files changed, 125 insertions(+), 18 deletions(-)

diff --git a/src/cpu/x86/smm/smihandler.c b/src/cpu/x86/smm/smihandler.c
index bbed0f1..83ebaf9 100644
--- a/src/cpu/x86/smm/smihandler.c
+++ b/src/cpu/x86/smm/smihandler.c
@@ -117,8 +117,14 @@ void smi_handler(u32 smm_revision)
 {
        unsigned int node;
        smm_state_save_area_t state_save;
+       u32 smm_base = 0xa8000; /* ASEG */
 
-#if !CONFIG_SMM_TSEG
+#if CONFIG_SMM_TSEG
+       /* Update global variable TSEG base */
+       if (!smi_get_tseg_base())
+               return;
+       smm_base = smi_get_tseg_base() + 0x8000;
+#else
        /* Are we ok to execute the handler? */
        if (!smi_obtain_lock()) {
                /* For security reasons we don't release the other CPUs
@@ -146,18 +152,22 @@ void smi_handler(u32 smm_revision)
        case 0x00030007:
                state_save.type = LEGACY;
                state_save.legacy_state_save = (legacy_smm_state_save_area_t *)
-                       (0xa8000 + 0x7e00 - (node * 0x400));
+                       (smm_base + 0x7e00 - (node * 0x400));
                break;
        case 0x00030100:
-       case 0x00030101: /* SandyBridge */
                state_save.type = EM64T;
                state_save.em64t_state_save = (em64t_smm_state_save_area_t *)
-                       (0xa8000 + 0x7d00 - (node * 0x400));
+                       (smm_base + 0x7d00 - (node * 0x400));
+       case 0x00030101: /* SandyBridge/IvyBridge */
+               state_save.type = EM64T101;
+               state_save.em64t101_state_save =
+                       (em64t101_smm_state_save_area_t *)
+                       (smm_base + 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));
+                       (smm_base + 0x7e00 - (node * 0x400));
                break;
        default:
                printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_revision);
diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h
index 89257e5..ccce2cb 100644
--- a/src/include/cpu/x86/smm.h
+++ b/src/include/cpu/x86/smm.h
@@ -201,6 +201,96 @@ typedef struct {
 } __attribute__((packed)) em64t_smm_state_save_area_t;
 
 
+/* Intel Revision 30101 SMM State-Save Area
+ * Used in SandyBridge/IvyBridge architecture
+ * starts @ 0x7d00
+ */
+typedef struct {
+       u8      reserved0[208];
+
+       u32     gdtr_upper_base;
+       u32     ldtr_upper_base;
+       u32     idtr_upper_base;
+
+       u32     io_cf8;
+
+       u64     io_rdi;
+       u64     io_rip;
+       u64     io_rcx;
+       u64     io_rsi;
+
+       u8      reserved1[52];
+       u32     shutdown_auto_restart;
+       u8      reserved2[8];
+       u32     cr4;
+
+       u8      reserved3[72];
+
+       u32     gdtr_base;
+       u8      reserved4[4];
+       u32     idtr_base;
+       u8      reserved5[4];
+       u32     ldtr_base;
+
+       u8      reserved6[68];
+       u32     cs_base;
+       u8      reserved7[4];
+       u32     iedbase;
+
+       u8      reserved8[8];
+
+       u32     smbase;
+       u32     smm_revision;
+
+       u16     io_restart;
+       u16     autohalt_restart;
+
+       u8      reserved9[24];
+
+       u64     r15;
+       u64     r14;
+       u64     r13;
+       u64     r12;
+       u64     r11;
+       u64     r10;
+       u64     r9;
+       u64     r8;
+
+       u64     rax;
+       u64     rcx;
+       u64     rdx;
+       u64     rbx;
+
+       u64     rsp;
+       u64     rbp;
+       u64     rsi;
+       u64     rdi;
+
+
+       u64     io_mem_addr;
+       u32     io_misc_info;
+
+       u32     es_sel;
+       u32     cs_sel;
+       u32     ss_sel;
+       u32     ds_sel;
+       u32     fs_sel;
+       u32     gs_sel;
+
+       u32     ldtr_sel;
+       u32     tr_sel;
+
+       u64     dr7;
+       u64     dr6;
+       u64     rip;
+       u64     efer;
+       u64     rflags;
+
+       u64     cr3;
+       u64     cr0;
+} __attribute__((packed)) em64t101_smm_state_save_area_t;
+
+
 /* Legacy x86 SMM State-Save Area
  * starts @ 0x7e00
  */
@@ -243,6 +333,7 @@ typedef struct {
 typedef enum {
        AMD64,
        EM64T,
+       EM64T101,
        LEGACY
 } save_state_type_t;
 
@@ -252,6 +343,7 @@ typedef struct {
        union {
        amd64_smm_state_save_area_t *amd64_state_save;
        em64t_smm_state_save_area_t *em64t_state_save;
+       em64t101_smm_state_save_area_t *em64t101_state_save;
        legacy_smm_state_save_area_t *legacy_state_save;
        };
 } smm_state_save_area_t;
@@ -284,6 +376,9 @@ void __attribute__((weak)) mainboard_smi_sleep(u8 slp_typ);
 
 #if !CONFIG_SMM_TSEG
 void smi_release_lock(void);
+#else
+/* Return address of TSEG base */
+u32 smi_get_tseg_base(void);
 #endif
 
 #endif
diff --git a/src/southbridge/intel/bd82x6x/smihandler.c 
b/src/southbridge/intel/bd82x6x/smihandler.c
index d7690ba..f5780cd 100644
--- a/src/southbridge/intel/bd82x6x/smihandler.c
+++ b/src/southbridge/intel/bd82x6x/smihandler.c
@@ -32,6 +32,13 @@
 
 #include "nvs.h"
 
+/* 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/sandybridge/sandybridge.h>
+#include <northbridge/intel/sandybridge/pcie_config.c>
+
 /* While we read PMBASE dynamically in case it changed, let's
  * initialize it with a sane value
  */
@@ -47,6 +54,12 @@ void *smi1 = (void *)0x0;
 
 #if CONFIG_SMM_TSEG
 static u32 tseg_base = 0;
+u32 smi_get_tseg_base(void)
+{
+       if (!tseg_base)
+               tseg_base = pcie_read_config32(PCI_DEV(0, 0, 0), TSEG) & ~1;
+       return tseg_base;
+}
 static inline void tseg_fixup(void **ptr)
 {
        /* Adjust pointer with TSEG base */
@@ -208,13 +221,6 @@ static void dump_tco_status(u32 tco_sts)
        printk(BIOS_DEBUG, "\n");
 }
 
-/* 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/sandybridge/sandybridge.h>
-#include <northbridge/intel/sandybridge/pcie_config.c>
-
 int southbridge_io_trap_handler(int smif)
 {
        switch (smif) {
@@ -672,11 +678,6 @@ void southbridge_smi_handler(unsigned int node, 
smm_state_save_area_t *state_sav
        /* Update global variable pmbase */
        pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
 
-#if CONFIG_SMM_TSEG
-       /* Update global variable TSEG base */
-       tseg_base = pcie_read_config32(PCI_DEV(0, 0, 0), TSEG) & ~1;
-#endif
-
        /* We need to clear the SMI status registers, or we won't see what's
         * happening in the following calls.
         */
@@ -688,7 +689,8 @@ void southbridge_smi_handler(unsigned int node, 
smm_state_save_area_t *state_sav
                        if (southbridge_smi[i]) {
 #if CONFIG_SMM_TSEG
                                smi_handler_t handler = (smi_handler_t)
-                                       ((u8*)southbridge_smi[i] + tseg_base);
+                                       ((u8*)southbridge_smi[i] +
+                                        smi_get_tseg_base());
                                if (handler)
                                        handler(node, state_save);
 #else

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to