[coreboot] New patch to review for coreboot: 9b73f5f smm: Update rev 0x30101 SMM revision save state

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Feb 26 01:23:07 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2515

-gerrit

commit 9b73f5f1a4e5d92b1f0833a07f075dbe74538aa9
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Nov 7 12:27:29 2012 -0600

    smm: Update rev 0x30101 SMM revision save state
    
    According to both Haswell and the SandyBridge/Ivybridge
    BWGs the save state area actually starts at 0x7c00 offset
    from 0x8000. Update the em64t101_smm_state_save_area_t
    structure and introduce a define for the offset.
    
    Note: I have no idea what eptp is. It's just listed in the
    haswell BWG. The offsets should not be changed.
    
    Change-Id: I38d1d1469e30628a83f10b188ab2fe53d5a50e5a
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/cpu/x86/smm/smihandler.c               | 29 +++++++++++++----------
 src/include/cpu/x86/smm.h                  | 37 ++++++++++++++++++++----------
 src/southbridge/intel/bd82x6x/smihandler.c |  2 +-
 3 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/src/cpu/x86/smm/smihandler.c b/src/cpu/x86/smm/smihandler.c
index 10f38f9..b4b7f36 100644
--- a/src/cpu/x86/smm/smihandler.c
+++ b/src/cpu/x86/smm/smihandler.c
@@ -107,6 +107,12 @@ static void smi_restore_pci_address(void)
 	outl(pci_orig, 0xcf8);
 }
 
+static inline void *smm_save_state(u32 base, int arch_offset, int node)
+{
+	base += SMM_SAVE_STATE_BEGIN(arch_offset) - (node * 0x400);
+	return (void *)base;
+}
+
 /**
  * @brief Interrupt handler for SMI#
  *
@@ -117,13 +123,13 @@ void smi_handler(u32 smm_revision)
 {
 	unsigned int node;
 	smm_state_save_area_t state_save;
-	u32 smm_base = 0xa8000; /* ASEG */
+	u32 smm_base = 0xa0000; /* ASEG */
 
 #if CONFIG_SMM_TSEG
 	/* Update global variable TSEG base */
 	if (!smi_get_tseg_base())
 		return;
-	smm_base = smi_get_tseg_base() + 0x8000;
+	smm_base = smi_get_tseg_base();
 #else
 	/* Are we ok to execute the handler? */
 	if (!smi_obtain_lock()) {
@@ -151,24 +157,23 @@ void smi_handler(u32 smm_revision)
 	case 0x00030002:
 	case 0x00030007:
 		state_save.type = LEGACY;
-		state_save.legacy_state_save = (legacy_smm_state_save_area_t *)
-			(smm_base + 0x7e00 - (node * 0x400));
+		state_save.legacy_state_save =
+			smm_save_state(smm_base, 0x7e00, node);
 		break;
 	case 0x00030100:
 		state_save.type = EM64T;
-		state_save.em64t_state_save = (em64t_smm_state_save_area_t *)
-			(smm_base + 0x7d00 - (node * 0x400));
-		break;
-	case 0x00030101: /* SandyBridge/IvyBridge */
+		state_save.em64t_state_save =
+			smm_save_state(smm_base, 0x7d00, node);
+	case 0x00030101: /* SandyBridge, IvyBridge, and Haswell */
 		state_save.type = EM64T101;
 		state_save.em64t101_state_save =
-			(em64t101_smm_state_save_area_t *)
-			(smm_base + 0x7d00 - (node * 0x400));
+			smm_save_state(smm_base,
+			               SMM_EM64T101_ARCH_OFFSET, node);
 		break;
 	case 0x00030064:
 		state_save.type = AMD64;
-		state_save.amd64_state_save = (amd64_smm_state_save_area_t *)
-			(smm_base + 0x7e00 - (node * 0x400));
+		state_save.amd64_state_save =
+			smm_save_state(smm_base, 0x7e00, node);
 		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 b52a315..3ffebf4 100644
--- a/src/include/cpu/x86/smm.h
+++ b/src/include/cpu/x86/smm.h
@@ -27,6 +27,9 @@
 /* used only by C programs so far */
 #define SMM_BASE 0xa0000
 
+#define SMM_ENTRY_OFFSET 0x8000
+#define SMM_SAVE_STATE_BEGIN(x) (SMM_ENTRY_OFFSET + (x))
+
 #include <types.h>
 typedef struct {
 	u16	es_selector;
@@ -202,11 +205,17 @@ typedef struct {
 
 
 /* Intel Revision 30101 SMM State-Save Area
- * Used in SandyBridge/IvyBridge architecture
- * starts @ 0x7d00
+ * The following processor architectures use this:
+ * - SandyBridge
+ * - IvyBridge
+ * - Haswell
  */
+#define SMM_EM64T101_ARCH_OFFSET 0x7c00
+#define SMM_EM64T101_SAVE_STATE_OFFSET \
+	SMM_SAVE_STATE_BEGIN(SMM_EM64T101_ARCH_OFFSET)
 typedef struct {
-	u8	reserved0[208];
+	u8	reserved0[256];
+	u8	reserved1[208];
 
 	u32	gdtr_upper_base;
 	u32	ldtr_upper_base;
@@ -219,25 +228,29 @@ typedef struct {
 	u64	io_rcx;
 	u64	io_rsi;
 
-	u8	reserved1[52];
+	u8	reserved2[52];
 	u32	shutdown_auto_restart;
-	u8	reserved2[8];
+	u8	reserved3[8];
 	u32	cr4;
 
-	u8	reserved3[72];
+	u8	reserved4[72];
 
 	u32	gdtr_base;
-	u8	reserved4[4];
-	u32	idtr_base;
 	u8	reserved5[4];
+	u32	idtr_base;
+	u8	reserved6[4];
 	u32	ldtr_base;
 
-	u8	reserved6[68];
+	u8	reserved7[56];
+	/* EPTP fields are only on Haswell according to BWGs, but Intel was
+	 * wise and reused the same revision number. */
+	u64	eptp;
+	u32	eptp_en;
 	u32	cs_base;
-	u8	reserved7[4];
+	u8	reserved8[4];
 	u32	iedbase;
 
-	u8	reserved8[8];
+	u8	reserved9[8];
 
 	u32	smbase;
 	u32	smm_revision;
@@ -245,7 +258,7 @@ typedef struct {
 	u16	io_restart;
 	u16	autohalt_restart;
 
-	u8	reserved9[24];
+	u8	reserved10[24];
 
 	u64	r15;
 	u64	r14;
diff --git a/src/southbridge/intel/bd82x6x/smihandler.c b/src/southbridge/intel/bd82x6x/smihandler.c
index 804607c..420c5db 100644
--- a/src/southbridge/intel/bd82x6x/smihandler.c
+++ b/src/southbridge/intel/bd82x6x/smihandler.c
@@ -432,7 +432,7 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
 static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
 {
 	em64t101_smm_state_save_area_t *state;
-	u32 base = smi_get_tseg_base() + 0x8000 + 0x7d00;
+	u32 base = smi_get_tseg_base() + SMM_EM64T101_SAVE_STATE_OFFSET;
 	int node;
 
 	/* Check all nodes looking for the one that issued the IO */



More information about the coreboot mailing list