SMM: Pass the ACPI GNVS pointer via state save map
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: I79a89512c40353d72ad058cbf2e6a23a696945da Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/1766 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
7f3d442abb
commit
7978e3a383
|
@ -398,11 +398,19 @@ void smm_lock(void)
|
||||||
|
|
||||||
void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
|
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;
|
asm volatile (
|
||||||
*(u32 *)0x504 = (u32)tcg;
|
"outb %%al, %%dx\n\t"
|
||||||
*(u32 *)0x508 = (u32)smi1;
|
: /* ignore result */
|
||||||
outb(0xea, 0xb2);
|
: "a" (APM_CNT_GNVS_UPDATE),
|
||||||
|
"b" ((u32)gnvs),
|
||||||
|
"d" (APM_CNT)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,7 +424,6 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ELOG_GSMI
|
|
||||||
/*
|
/*
|
||||||
* Look for Synchronous IO SMI and use save state from that
|
* Look for Synchronous IO SMI and use save state from that
|
||||||
* core in case we are not running on the same core that
|
* core in case we are not running on the same core that
|
||||||
|
@ -462,7 +461,6 @@ static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u64 cmd)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_ELOG_GSMI
|
#if CONFIG_ELOG_GSMI
|
||||||
static void southbridge_smi_gsmi(void)
|
static void southbridge_smi_gsmi(void)
|
||||||
|
@ -492,6 +490,7 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state
|
||||||
u32 pmctrl;
|
u32 pmctrl;
|
||||||
u8 reg8;
|
u8 reg8;
|
||||||
int (*mainboard_apmc)(u8 apmc) = mainboard_smi_apmc;
|
int (*mainboard_apmc)(u8 apmc) = mainboard_smi_apmc;
|
||||||
|
em64t101_smm_state_save_area_t *state;
|
||||||
|
|
||||||
/* Emulate B2 register as the FADT / Linux expects it */
|
/* Emulate B2 register as the FADT / Linux expects it */
|
||||||
|
|
||||||
|
@ -528,8 +527,13 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state
|
||||||
printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
|
printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gnvs = *(global_nvs_t **)0x500;
|
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;
|
smm_initialized = 1;
|
||||||
|
printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#if CONFIG_ELOG_GSMI
|
#if CONFIG_ELOG_GSMI
|
||||||
case ELOG_GSMI_APM_CNT:
|
case ELOG_GSMI_APM_CNT:
|
||||||
|
|
Loading…
Reference in New Issue