diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/amd/common/block/cpu/smm/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/smm/smi_apmc_helper.c | 86 | ||||
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/smm.h | 2 | ||||
-rw-r--r-- | src/soc/amd/picasso/smihandler.c | 84 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/smihandler.c | 84 |
5 files changed, 93 insertions, 164 deletions
diff --git a/src/soc/amd/common/block/cpu/smm/Makefile.inc b/src/soc/amd/common/block/cpu/smm/Makefile.inc index 4c18d12b1d..80d06a70a5 100644 --- a/src/soc/amd/common/block/cpu/smm/Makefile.inc +++ b/src/soc/amd/common/block/cpu/smm/Makefile.inc @@ -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 diff --git a/src/soc/amd/common/block/cpu/smm/smi_apmc_helper.c b/src/soc/amd/common/block/cpu/smm/smi_apmc_helper.c new file mode 100644 index 0000000000..576c9180c8 --- /dev/null +++ b/src/soc/amd/common/block/cpu/smm/smi_apmc_helper.c @@ -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); +} diff --git a/src/soc/amd/common/block/include/amdblocks/smm.h b/src/soc/amd/common/block/include/amdblocks/smm.h index 5f14b1e850..187eddf691 100644 --- a/src/soc/amd/common/block/include/amdblocks/smm.h +++ b/src/soc/amd/common/block/include/amdblocks/smm.h @@ -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); diff --git a/src/soc/amd/picasso/smihandler.c b/src/soc/amd/picasso/smihandler.c index d478aad142..79e45fadbb 100644 --- a/src/soc/amd/picasso/smihandler.c +++ b/src/soc/amd/picasso/smihandler.c @@ -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, ®_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(); diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c index 23951b2a58..2b0c85b60d 100644 --- a/src/soc/amd/stoneyridge/smihandler.c +++ b/src/soc/amd/stoneyridge/smihandler.c @@ -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, ®_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; } |