coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smi_apmc_helper.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <amdblocks/smm.h>
5 #include <cpu/x86/smm.h>
6 #include <elog.h>
7 #include <smmstore.h>
8 #include <types.h>
9 
10 /* bits in smm_io_trap */
11 #define SMM_IO_TRAP_PORT_OFFSET 16
12 #define SMM_IO_TRAP_PORT_ADDRESS_MASK 0xffff
13 #define SMM_IO_TRAP_RW (1 << 0)
14 #define SMM_IO_TRAP_VALID (1 << 1)
15 
16 static inline u16 get_io_address(u32 info)
17 {
18  return ((info >> SMM_IO_TRAP_PORT_OFFSET) &
20 }
21 
22 static void *find_save_state(int cmd)
23 {
24  unsigned int core;
25  amd64_smm_state_save_area_t *state;
26  u32 smm_io_trap;
27  u8 reg_al;
28 
29  /* Check all nodes looking for the one that issued the IO */
30  for (core = 0; core < CONFIG_MAX_CPUS; core++) {
31  state = smm_get_save_state(core);
32  smm_io_trap = state->smm_io_trap_offset;
33  /* Check for Valid IO Trap Word (bit1==1) */
34  if (!(smm_io_trap & SMM_IO_TRAP_VALID))
35  continue;
36  /* Make sure it was a write (bit0==0) */
37  if (smm_io_trap & SMM_IO_TRAP_RW)
38  continue;
39  /* Check for APMC IO port */
40  if (pm_acpi_smi_cmd_port() != get_io_address(smm_io_trap))
41  continue;
42  /* Check AL against the requested command */
43  reg_al = state->rax;
44  if (reg_al == cmd)
45  return state;
46  }
47  return NULL;
48 }
49 
50 void handle_smi_gsmi(void)
51 {
52  u8 sub_command;
53  amd64_smm_state_save_area_t *io_smi;
54  u32 reg_ebx;
55 
57  if (!io_smi)
58  return;
59  /* Command and return value in EAX */
60  sub_command = (io_smi->rax >> 8) & 0xff;
61 
62  /* Parameter buffer in EBX */
63  reg_ebx = io_smi->rbx;
64 
65  /* drivers/elog/gsmi.c */
66  io_smi->rax = gsmi_exec(sub_command, &reg_ebx);
67 }
68 
69 void handle_smi_store(void)
70 {
71  u8 sub_command;
72  amd64_smm_state_save_area_t *io_smi;
73  u32 reg_ebx;
74 
76  if (!io_smi)
77  return;
78  /* Command and return value in EAX */
79  sub_command = (io_smi->rax >> 8) & 0xff;
80 
81  /* Parameter buffer in EBX */
82  reg_ebx = io_smi->rbx;
83 
84  /* drivers/smmstore/smi.c */
85  io_smi->rax = smmstore_exec(sub_command, (void *)reg_ebx);
86 }
void * smm_get_save_state(int cpu)
Definition: smihandler.c:114
static struct smmstore_params_info info
Definition: ramstage.c:12
uint32_t smmstore_exec(uint8_t command, void *param)
Definition: smi.c:144
u32 gsmi_exec(u8 command, u32 *param)
Definition: gsmi.c:46
#define APM_CNT_ELOG_GSMI
Definition: smm.h:29
uint16_t pm_acpi_smi_cmd_port(void)
Definition: smi.c:6
#define APM_CNT_SMMSTORE
Definition: smm.h:28
state
Definition: raminit.c:1787
#define SMM_IO_TRAP_RW
static u16 get_io_address(u32 info)
#define SMM_IO_TRAP_PORT_OFFSET
void handle_smi_store(void)
#define SMM_IO_TRAP_VALID
void handle_smi_gsmi(void)
static void * find_save_state(int cmd)
#define SMM_IO_TRAP_PORT_ADDRESS_MASK
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45