soc/amd/stoneyridge: Add ELOG to SMM
1. Add ELOG entries to smihandler.c 2. Add save_state utilities that are needed by southbridge_smi_gsmi BUG=b:65485690 Change-Id: I458babe1694f042215dd0e1c3277856e340de86f Signed-off-by: John E. Kabat Jr <john.kabat@scarletltd.com> Reviewed-on: https://review.coreboot.org/21728 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
0e022038fc
commit
7057a27a44
|
@ -24,6 +24,66 @@
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <soc/smi.h>
|
#include <soc/smi.h>
|
||||||
#include <soc/southbridge.h>
|
#include <soc/southbridge.h>
|
||||||
|
#include <elog.h>
|
||||||
|
|
||||||
|
/* bits in smm_io_trap */
|
||||||
|
#define SMM_IO_TRAP_PORT_OFFSET 16
|
||||||
|
#define SMM_IO_TRAP_PORT_ADDRESS_MASK 0xffff
|
||||||
|
#define SMM_IO_TRAP_RW (1 << 0)
|
||||||
|
#define SMM_IO_TRAP_VALID (1 << 1)
|
||||||
|
|
||||||
|
static inline u16 get_io_address(u32 info)
|
||||||
|
{
|
||||||
|
return ((info >> SMM_IO_TRAP_PORT_OFFSET) &
|
||||||
|
SMM_IO_TRAP_PORT_ADDRESS_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *find_save_state(int cmd)
|
||||||
|
{
|
||||||
|
int core;
|
||||||
|
amd64_smm_state_save_area_t *state;
|
||||||
|
u32 smm_io_trap;
|
||||||
|
u8 reg_al;
|
||||||
|
|
||||||
|
/* Check all nodes looking for the one that issued the IO */
|
||||||
|
for (core = 0; core < CONFIG_MAX_CPUS; core++) {
|
||||||
|
state = smm_get_save_state(core);
|
||||||
|
smm_io_trap = state->smm_io_trap_offset;
|
||||||
|
/* Check for Valid IO Trap Word (bit1==1) */
|
||||||
|
if (!(smm_io_trap & SMM_IO_TRAP_VALID))
|
||||||
|
continue;
|
||||||
|
/* Make sure it was a write (bit0==0) */
|
||||||
|
if (smm_io_trap & SMM_IO_TRAP_RW)
|
||||||
|
continue;
|
||||||
|
/* Check for APMC IO port */
|
||||||
|
if (pm_acpi_smi_cmd_port() != get_io_address(smm_io_trap))
|
||||||
|
continue;
|
||||||
|
/* Check AL against the requested command */
|
||||||
|
reg_al = state->rax;
|
||||||
|
if (reg_al == cmd)
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void southbridge_smi_gsmi(void)
|
||||||
|
{
|
||||||
|
u8 sub_command;
|
||||||
|
amd64_smm_state_save_area_t *io_smi;
|
||||||
|
u32 reg_ebx;
|
||||||
|
|
||||||
|
io_smi = find_save_state(ELOG_GSMI_APM_CNT);
|
||||||
|
if (!io_smi)
|
||||||
|
return;
|
||||||
|
/* Command and return value in EAX */
|
||||||
|
sub_command = (io_smi->rax >> 8) & 0xff;
|
||||||
|
|
||||||
|
/* Parameter buffer in EBX */
|
||||||
|
reg_ebx = io_smi->rbx;
|
||||||
|
|
||||||
|
/* drivers/elog/gsmi.c */
|
||||||
|
io_smi->rax = gsmi_exec(sub_command, ®_ebx);
|
||||||
|
}
|
||||||
|
|
||||||
static void sb_apmc_smi_handler(void)
|
static void sb_apmc_smi_handler(void)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +101,10 @@ static void sb_apmc_smi_handler(void)
|
||||||
reg32 &= ~(1 << 0); /* clear SCI_EN */
|
reg32 &= ~(1 << 0); /* clear SCI_EN */
|
||||||
outl(ACPI_PM1_CNT_BLK, reg32);
|
outl(ACPI_PM1_CNT_BLK, reg32);
|
||||||
break;
|
break;
|
||||||
|
case ELOG_GSMI_APM_CNT:
|
||||||
|
if (IS_ENABLED(CONFIG_ELOG_GSMI))
|
||||||
|
southbridge_smi_gsmi();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainboard_smi_apmc(cmd);
|
mainboard_smi_apmc(cmd);
|
||||||
|
@ -88,6 +152,10 @@ static void sb_slp_typ_handler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slp_typ >= ACPI_S3) {
|
if (slp_typ >= ACPI_S3) {
|
||||||
|
/* Sleep Type Elog S3, S4, and S5 entry */
|
||||||
|
if (IS_ENABLED(CONFIG_ELOG_GSMI))
|
||||||
|
elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
|
||||||
|
|
||||||
wbinvd();
|
wbinvd();
|
||||||
|
|
||||||
disable_all_smi_status();
|
disable_all_smi_status();
|
||||||
|
|
Loading…
Reference in New Issue