[coreboot-gerrit] New patch to review for coreboot: ddeb5c1 intel/i82801gx: SMM: Pass the ACPI GNVS pointer via state save map

Paul Menzel (paulepanter@users.sourceforge.net) gerrit at coreboot.org
Tue Jan 6 17:19:10 CET 2015


Paul Menzel (paulepanter at users.sourceforge.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8139

-gerrit

commit ddeb5c176c558b2e27e31e7de54f73a336eba16c
Author: Paul Menzel <paulepanter at users.sourceforge.net>
Date:   Tue Jan 6 17:12:26 2015 +0100

    intel/i82801gx: SMM: Pass the ACPI GNVS pointer via state save map
    
    Currently on older Intel systems, during resume the coreboot table is
    overwritten by the code in `smm_setup_structures()` called by
    `acpi_resume()` in `src/arch/x86/boot/acpi.c`. As a result, `cbmem`
    does not work anymore.
    
    Port commit 7978e3a3 (SMM: Pass the ACPI GNVS pointer via state save
    map), applied to Intel BD82x6x and the explanation below, to the other
    Intel southbridges too.
    
    Instead of hijacking some random memory addresses to relay the GNVS
    pointer to SMM we can use EBX register during the write to APM_CNT
    register when the SMI is triggered.
    
    Change-Id: I60013cc6c441ba2696ea3623722d4b0afe2dd2cc
    Signed-off-by: Paul Menzel <paulepanter at users.sourceforge.net>
---
 src/southbridge/intel/i82801gx/smi.c        | 18 ++++++++++++++----
 src/southbridge/intel/i82801gx/smihandler.c | 11 ++++++++---
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/southbridge/intel/i82801gx/smi.c b/src/southbridge/intel/i82801gx/smi.c
index 134c232..84714af 100644
--- a/src/southbridge/intel/i82801gx/smi.c
+++ b/src/southbridge/intel/i82801gx/smi.c
@@ -383,9 +383,19 @@ void smm_lock(void)
 
 void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
 {
-	/* The GDT or coreboot table is going to live here. But a long time
-	 * after we relocated the GNVS, so this is not troublesome.
+	/*
+	 * Issue SMI to set the gnvs pointer in SMM.
+	 * tcg and smi1 are unused.
+	 *
+	 * EAX = APM_CNT_GNVS_UPDATE
+	 * EBX = gnvs pointer
+	 * EDX = APM_CNT
 	 */
-	*(u32 *)0x500 = (u32)gnvs;
-	outb(0xea, 0xb2);
+	asm volatile (
+		"outb %%al, %%dx\n\t"
+		: /* ignore result */
+		: "a" (APM_CNT_GNVS_UPDATE),
+		  "b" ((u32)gnvs),
+		  "d" (APM_CNT)
+	);
 }
diff --git a/src/southbridge/intel/i82801gx/smihandler.c b/src/southbridge/intel/i82801gx/smihandler.c
index e2505ce..e1cc220 100644
--- a/src/southbridge/intel/i82801gx/smihandler.c
+++ b/src/southbridge/intel/i82801gx/smihandler.c
@@ -365,6 +365,7 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state
 {
 	u32 pmctrl;
 	u8 reg8;
+	em64t101_smm_state_save_area_t *state;
 
 	/* Emulate B2 register as the FADT / Linux expects it */
 
@@ -404,9 +405,13 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state
 			printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
 			return;
 		}
-		gnvs = *(global_nvs_t **)0x500;
-		smm_initialized = 1;
-		printk(BIOS_DEBUG, "SMI#: Setting up structures to %p\n", gnvs);
+		state = smi_apmc_find_state_save(reg8);
+		if (state) {
+			/* EBX in the state save contains the GNVS pointer */
+			gnvs = (global_nvs_t *)((u32)state->rbx);
+			smm_initialized = 1;
+			printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
+		}
 		break;
 	default:
 		printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);



More information about the coreboot-gerrit mailing list