summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/amd/common/block/cpu/smm/Makefile.inc1
-rw-r--r--src/soc/amd/common/block/cpu/smm/smi_apmc_helper.c86
-rw-r--r--src/soc/amd/common/block/include/amdblocks/smm.h2
-rw-r--r--src/soc/amd/picasso/smihandler.c84
-rw-r--r--src/soc/amd/stoneyridge/smihandler.c84
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, &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);
+}
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, &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();
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, &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;
}