coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
psp_smm.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <cpu/x86/msr.h>
5 #include <cpu/amd/msr.h>
6 #include <region_file.h>
7 #include <console/console.h>
8 #include <amdblocks/psp.h>
9 #include <soc/iomap.h>
10 #include <string.h>
11 
12 #include "psp_def.h"
13 
14 #define C2P_BUFFER_MAXSIZE 0xc00 /* Core-to-PSP buffer */
15 #define P2C_BUFFER_MAXSIZE 0xc00 /* PSP-to-core buffer */
16 
17 struct {
19 } __attribute__((aligned(32))) c2p_buffer;
20 
21 struct {
23 } __attribute__((aligned(32))) p2c_buffer;
24 
25 static uint32_t smm_flag; /* Non-zero for SMM, clear when not */
26 
27 static void set_smm_flag(void)
28 {
29  smm_flag = 1;
30 }
31 
32 static void clear_smm_flag(void)
33 {
34  smm_flag = 0;
35 }
36 
37 int psp_notify_smm(void)
38 {
39  msr_t msr;
40  int cmd_status;
42  .header = {
43  .size = sizeof(buffer)
44  },
45  .req = {
46  .psp_smm_data_region = (uintptr_t)p2c_buffer.buffer,
47  .psp_smm_data_length = sizeof(p2c_buffer),
48  .psp_mbox_smm_buffer_address = (uintptr_t)c2p_buffer.buffer,
49  .psp_mbox_smm_flag_address = (uintptr_t)&smm_flag,
50  }
51  };
52 
53  msr = rdmsr(SMM_ADDR_MSR);
54  buffer.req.smm_base = ((uint64_t)msr.hi << 32) | msr.lo;
55  msr = rdmsr(SMM_MASK_MSR);
56  msr.lo &= 0xffff0000; /* mask SMM_TSEG_VALID and reserved bits */
57  buffer.req.smm_mask = ((uint64_t)msr.hi << 32) | msr.lo;
58 
59  soc_fill_smm_trig_info(&buffer.req.smm_trig_info);
60 #if (CONFIG(SOC_AMD_COMMON_BLOCK_PSP_GEN2))
61  soc_fill_smm_reg_info(&buffer.req.smm_reg_info);
62 #endif
63 
64  printk(BIOS_DEBUG, "PSP: Notify SMM info... ");
65 
66  set_smm_flag();
69 
70  /* buffer's status shouldn't change but report it if it does */
71  psp_print_cmd_status(cmd_status, &buffer.header);
72 
73  return cmd_status;
74 }
75 
76 /* Notify PSP the system is going to a sleep state. */
77 void psp_notify_sx_info(u8 sleep_type)
78 {
79  int cmd_status;
81 
82  /* PSP verifies that this buffer is at the address specified in psp_notify_smm() */
83  buffer = (struct mbox_cmd_sx_info_buffer *)c2p_buffer.buffer;
84  memset(buffer, 0, sizeof(*buffer));
85  buffer->header.size = sizeof(*buffer);
86 
88  printk(BIOS_ERR, "PSP: BUG: invalid sleep type 0x%x requested\n", sleep_type);
89  return;
90  }
91 
92  printk(BIOS_DEBUG, "PSP: Prepare to enter sleep state %d... ", sleep_type);
93 
94  buffer->sleep_type = sleep_type;
95 
96  set_smm_flag();
99 
100  /* buffer's status shouldn't change but report it if it does */
101  psp_print_cmd_status(cmd_status, &buffer->header);
102 }
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
void psp_print_cmd_status(int cmd_status, struct mbox_buffer_header *header)
Definition: psp.c:47
#define printk(level,...)
Definition: stdlib.h:16
#define SMM_ADDR_MSR
Definition: msr.h:60
#define SMM_MASK_MSR
Definition: msr.h:61
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
void soc_fill_smm_trig_info(struct smm_trigger_info *trig)
Definition: psp_smm_gen2.c:8
void soc_fill_smm_reg_info(struct smm_register_info *reg)
Definition: psp_smm_gen2.c:20
int send_psp_command(u32 command, void *buffer)
Definition: psp_gen1.c:115
#define MBOX_BIOS_CMD_SX_INFO_SLEEP_TYPE_MAX
Definition: psp_def.h:13
#define MBOX_BIOS_CMD_SMM_INFO
Definition: psp_def.h:11
#define MBOX_BIOS_CMD_SX_INFO
Definition: psp_def.h:12
static uint32_t smm_flag
Definition: psp_smm.c:25
static void set_smm_flag(void)
Definition: psp_smm.c:27
#define C2P_BUFFER_MAXSIZE
Definition: psp_smm.c:14
#define P2C_BUFFER_MAXSIZE
Definition: psp_smm.c:15
static void clear_smm_flag(void)
Definition: psp_smm.c:32
int psp_notify_smm(void)
Definition: psp_smm.c:37
struct @412 p2c_buffer
struct @411 c2p_buffer
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
void psp_notify_sx_info(u8 sleep_type)
Definition: psp_smm.c:77
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
uint8_t u8
Definition: stdint.h:45
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111