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:
Felix Held 2021-03-08 23:54:18 +01:00
parent 4324bc60d5
commit 90bcdb436a
5 changed files with 93 additions and 164 deletions

View File

@ -7,6 +7,7 @@ postcar-y += smm_helper.c
ramstage-y += finalize.c
ramstage-y += smm_relocate.c
ramstage-y += smm_helper.c
smm-y += smi_apmc_helper.c
smm-y += smi_handler.c
endif # CONFIG_SOC_AMD_COMMON_BLOCK_SMM

View File

@ -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, &reg_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);
}

View File

@ -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 smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase);
void *get_smi_source_handler(int source);
void handle_smi_gsmi(void);
void handle_smi_store(void);
void clear_tvalid(void);

View File

@ -4,11 +4,9 @@
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <cpu/x86/cache.h>
#include <cpu/amd/amd64_save_state.h>
#include <acpi/acpi.h>
#include <arch/hlt.h>
#include <device/pci_def.h>
#include <smmstore.h>
#include <soc/smi.h>
#include <soc/southbridge.h>
#include <amdblocks/acpimmio.h>
@ -20,84 +18,6 @@
#include <soc/smu.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, &reg_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)
{
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
@ -111,11 +31,11 @@ static void fch_apmc_smi_handler(void)
break;
case APM_CNT_ELOG_GSMI:
if (CONFIG(ELOG_GSMI))
southbridge_smi_gsmi();
handle_smi_gsmi();
break;
case APM_CNT_SMMSTORE:
if (CONFIG(SMMSTORE))
southbridge_smi_store();
handle_smi_store();
break;
case APM_CNT_SMMINFO:
psp_notify_smm();

View File

@ -4,11 +4,9 @@
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <cpu/x86/cache.h>
#include <cpu/amd/amd64_save_state.h>
#include <acpi/acpi.h>
#include <arch/hlt.h>
#include <device/pci_def.h>
#include <smmstore.h>
#include <soc/smi.h>
#include <soc/southbridge.h>
#include <amdblocks/acpimmio.h>
@ -18,84 +16,6 @@
#include <elog.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, &reg_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)
{
const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
@ -109,11 +29,11 @@ static void fch_apmc_smi_handler(void)
break;
case APM_CNT_ELOG_GSMI:
if (CONFIG(ELOG_GSMI))
southbridge_smi_gsmi();
handle_smi_gsmi();
break;
case APM_CNT_SMMSTORE:
if (CONFIG(SMMSTORE))
southbridge_smi_store();
handle_smi_store();
break;
}