soc/amd/*/smihandler: factor out ELOG and SMMSTORE handler
This also replaces the southbridge_ prefix of the handler functions with a handle_ prefix. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: Ib6ea1f4e2700c508a8bf72c488043e276ba4a062 Reviewed-on: https://review.coreboot.org/c/coreboot/+/51354 Reviewed-by: Raul Rangel <rrangel@chromium.org> Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
4324bc60d5
commit
90bcdb436a
|
@ -7,6 +7,7 @@ postcar-y += smm_helper.c
|
||||||
ramstage-y += finalize.c
|
ramstage-y += finalize.c
|
||||||
ramstage-y += smm_relocate.c
|
ramstage-y += smm_relocate.c
|
||||||
ramstage-y += smm_helper.c
|
ramstage-y += smm_helper.c
|
||||||
|
smm-y += smi_apmc_helper.c
|
||||||
smm-y += smi_handler.c
|
smm-y += smi_handler.c
|
||||||
|
|
||||||
endif # CONFIG_SOC_AMD_COMMON_BLOCK_SMM
|
endif # CONFIG_SOC_AMD_COMMON_BLOCK_SMM
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <amdblocks/smm.h>
|
||||||
|
#include <cpu/amd/amd64_save_state.h>
|
||||||
|
#include <cpu/x86/smm.h>
|
||||||
|
#include <elog.h>
|
||||||
|
#include <smmstore.h>
|
||||||
|
#include <types.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)
|
||||||
|
{
|
||||||
|
unsigned 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_smi_gsmi(void)
|
||||||
|
{
|
||||||
|
u8 sub_command;
|
||||||
|
amd64_smm_state_save_area_t *io_smi;
|
||||||
|
u32 reg_ebx;
|
||||||
|
|
||||||
|
io_smi = find_save_state(APM_CNT_ELOG_GSMI);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_smi_store(void)
|
||||||
|
{
|
||||||
|
u8 sub_command;
|
||||||
|
amd64_smm_state_save_area_t *io_smi;
|
||||||
|
u32 reg_ebx;
|
||||||
|
|
||||||
|
io_smi = find_save_state(APM_CNT_SMMSTORE);
|
||||||
|
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/smmstore/smi.c */
|
||||||
|
io_smi->rax = smmstore_exec(sub_command, (void *)reg_ebx);
|
||||||
|
}
|
|
@ -11,4 +11,6 @@ struct smm_relocation_params {
|
||||||
void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size);
|
void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size);
|
||||||
void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase);
|
void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase);
|
||||||
void *get_smi_source_handler(int source);
|
void *get_smi_source_handler(int source);
|
||||||
|
void handle_smi_gsmi(void);
|
||||||
|
void handle_smi_store(void);
|
||||||
void clear_tvalid(void);
|
void clear_tvalid(void);
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <cpu/x86/cache.h>
|
#include <cpu/x86/cache.h>
|
||||||
#include <cpu/amd/amd64_save_state.h>
|
|
||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
#include <arch/hlt.h>
|
#include <arch/hlt.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <smmstore.h>
|
|
||||||
#include <soc/smi.h>
|
#include <soc/smi.h>
|
||||||
#include <soc/southbridge.h>
|
#include <soc/southbridge.h>
|
||||||
#include <amdblocks/acpimmio.h>
|
#include <amdblocks/acpimmio.h>
|
||||||
|
@ -20,84 +18,6 @@
|
||||||
#include <soc/smu.h>
|
#include <soc/smu.h>
|
||||||
#include <types.h>
|
#include <types.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)
|
|
||||||
{
|
|
||||||
unsigned 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(APM_CNT_ELOG_GSMI);
|
|
||||||
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 southbridge_smi_store(void)
|
|
||||||
{
|
|
||||||
u8 sub_command;
|
|
||||||
amd64_smm_state_save_area_t *io_smi;
|
|
||||||
u32 reg_ebx;
|
|
||||||
|
|
||||||
io_smi = find_save_state(APM_CNT_SMMSTORE);
|
|
||||||
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/smmstore/smi.c */
|
|
||||||
io_smi->rax = smmstore_exec(sub_command, (void *)reg_ebx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fch_apmc_smi_handler(void)
|
static void fch_apmc_smi_handler(void)
|
||||||
{
|
{
|
||||||
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
|
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
|
||||||
|
@ -111,11 +31,11 @@ static void fch_apmc_smi_handler(void)
|
||||||
break;
|
break;
|
||||||
case APM_CNT_ELOG_GSMI:
|
case APM_CNT_ELOG_GSMI:
|
||||||
if (CONFIG(ELOG_GSMI))
|
if (CONFIG(ELOG_GSMI))
|
||||||
southbridge_smi_gsmi();
|
handle_smi_gsmi();
|
||||||
break;
|
break;
|
||||||
case APM_CNT_SMMSTORE:
|
case APM_CNT_SMMSTORE:
|
||||||
if (CONFIG(SMMSTORE))
|
if (CONFIG(SMMSTORE))
|
||||||
southbridge_smi_store();
|
handle_smi_store();
|
||||||
break;
|
break;
|
||||||
case APM_CNT_SMMINFO:
|
case APM_CNT_SMMINFO:
|
||||||
psp_notify_smm();
|
psp_notify_smm();
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <cpu/x86/cache.h>
|
#include <cpu/x86/cache.h>
|
||||||
#include <cpu/amd/amd64_save_state.h>
|
|
||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
#include <arch/hlt.h>
|
#include <arch/hlt.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <smmstore.h>
|
|
||||||
#include <soc/smi.h>
|
#include <soc/smi.h>
|
||||||
#include <soc/southbridge.h>
|
#include <soc/southbridge.h>
|
||||||
#include <amdblocks/acpimmio.h>
|
#include <amdblocks/acpimmio.h>
|
||||||
|
@ -18,84 +16,6 @@
|
||||||
#include <elog.h>
|
#include <elog.h>
|
||||||
#include <types.h>
|
#include <types.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)
|
|
||||||
{
|
|
||||||
unsigned 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(APM_CNT_ELOG_GSMI);
|
|
||||||
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 southbridge_smi_store(void)
|
|
||||||
{
|
|
||||||
u8 sub_command;
|
|
||||||
amd64_smm_state_save_area_t *io_smi;
|
|
||||||
u32 reg_ebx;
|
|
||||||
|
|
||||||
io_smi = find_save_state(APM_CNT_SMMSTORE);
|
|
||||||
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/smmstore/smi.c */
|
|
||||||
io_smi->rax = smmstore_exec(sub_command, (void *)reg_ebx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fch_apmc_smi_handler(void)
|
static void fch_apmc_smi_handler(void)
|
||||||
{
|
{
|
||||||
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
|
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
|
||||||
|
@ -109,11 +29,11 @@ static void fch_apmc_smi_handler(void)
|
||||||
break;
|
break;
|
||||||
case APM_CNT_ELOG_GSMI:
|
case APM_CNT_ELOG_GSMI:
|
||||||
if (CONFIG(ELOG_GSMI))
|
if (CONFIG(ELOG_GSMI))
|
||||||
southbridge_smi_gsmi();
|
handle_smi_gsmi();
|
||||||
break;
|
break;
|
||||||
case APM_CNT_SMMSTORE:
|
case APM_CNT_SMMSTORE:
|
||||||
if (CONFIG(SMMSTORE))
|
if (CONFIG(SMMSTORE))
|
||||||
southbridge_smi_store();
|
handle_smi_store();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue