SMM: Extract function for finding save state node
This is currently used by the ELOG GSMI interface but is a good way to pass data to SMM so move the current searching code to a separate function and make it a bit more versatile with the checks it does to find a match so it can be used in other situations. Change-Id: I5b6f92169f77c7707448ec38684cdd53c02fe0a5 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/1763 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
committed by
Ronald G. Minnich
parent
11290c49b0
commit
d396a77b4d
@@ -419,38 +419,54 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ELOG_GSMI
|
#if CONFIG_ELOG_GSMI
|
||||||
static void southbridge_smi_gsmi(void)
|
/*
|
||||||
|
* Look for Synchronous IO SMI and use save state from that
|
||||||
|
* core in case we are not running on the same core that
|
||||||
|
* initiated the IO transaction.
|
||||||
|
*/
|
||||||
|
static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u64 cmd)
|
||||||
{
|
{
|
||||||
em64t101_smm_state_save_area_t *io_smi;
|
em64t101_smm_state_save_area_t *state;
|
||||||
u32 base = smi_get_tseg_base() + 0x8000;
|
u32 base = smi_get_tseg_base() + 0x8000 + 0x7d00;
|
||||||
u32 *ret, *param;
|
int node;
|
||||||
u8 sub_command, node;
|
|
||||||
|
|
||||||
/*
|
/* Check all nodes looking for the one that issued the IO */
|
||||||
* Check for Synchronous IO SMI and use save state from that
|
|
||||||
* core in case we are not running on the same core that
|
|
||||||
* initiated the IO transaction.
|
|
||||||
*/
|
|
||||||
for (node = 0; node < CONFIG_MAX_CPUS; node++) {
|
for (node = 0; node < CONFIG_MAX_CPUS; node++) {
|
||||||
/*
|
state = (em64t101_smm_state_save_area_t *)
|
||||||
* Look for IO Misc Info:
|
(base - (node * 0x400));
|
||||||
* Synchronous bit[0]=1
|
|
||||||
* Byte bit[3:1]=1
|
|
||||||
* Output bit[7:4]=0
|
|
||||||
* APMC port bit[31:16]=0xb2
|
|
||||||
* RAX[7:0] == 0xEF
|
|
||||||
*/
|
|
||||||
u32 io_want_info = (APM_CNT << 16) | 0x3;
|
|
||||||
io_smi = (em64t101_smm_state_save_area_t *)
|
|
||||||
(base + 0x7d00 - (node * 0x400));
|
|
||||||
|
|
||||||
if (io_smi->io_misc_info == io_want_info &&
|
/* Check for Synchronous IO (bit0==1) */
|
||||||
((u8)io_smi->rax == ELOG_GSMI_APM_CNT))
|
if (!(state->io_misc_info & (1 << 0)))
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
|
/* Make sure it was a write (bit4==0) */
|
||||||
|
if (state->io_misc_info & (1 << 4))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check for APMC IO port */
|
||||||
|
if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check AX against the requested command */
|
||||||
|
if (state->rax != cmd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did not find matching CPU Save State */
|
return NULL;
|
||||||
if (node == CONFIG_MAX_CPUS)
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ELOG_GSMI
|
||||||
|
static void southbridge_smi_gsmi(void)
|
||||||
|
{
|
||||||
|
u32 *ret, *param;
|
||||||
|
u8 sub_command;
|
||||||
|
em64t101_smm_state_save_area_t *io_smi =
|
||||||
|
smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);
|
||||||
|
|
||||||
|
if (!io_smi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Command and return value in EAX */
|
/* Command and return value in EAX */
|
||||||
|
Reference in New Issue
Block a user