blob: 2112e868f631bef04eb9b809b93274ff8781e3bd [file] [log] [blame]
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -06001/* SPDX-License-Identifier: GPL-2.0-only */
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -06002
3#include <device/mmio.h>
4#include <cpu/x86/msr.h>
5#include <cpu/amd/msr.h>
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -06006#include <region_file.h>
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -06007#include <console/console.h>
8#include <amdblocks/psp.h>
9#include <soc/iomap.h>
Elyes HAOUAS722e6102020-06-13 12:52:24 +020010#include <string.h>
11
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060012#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
17struct {
18 u8 buffer[C2P_BUFFER_MAXSIZE];
Elyes Haouas2dc5c6e2023-09-07 19:40:56 +020019} __aligned(32) c2p_buffer;
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060020
21struct {
22 u8 buffer[P2C_BUFFER_MAXSIZE];
Elyes Haouas2dc5c6e2023-09-07 19:40:56 +020023} __aligned(32) p2c_buffer;
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060024
25static uint32_t smm_flag; /* Non-zero for SMM, clear when not */
26
27static void set_smm_flag(void)
28{
29 smm_flag = 1;
30}
31
32static void clear_smm_flag(void)
33{
34 smm_flag = 0;
35}
36
37int psp_notify_smm(void)
38{
39 msr_t msr;
40 int cmd_status;
41 struct mbox_cmd_smm_info_buffer buffer = {
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);
Felix Held65c4b862023-03-09 19:29:16 +010054 buffer.req.smm_base = msr.raw;
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060055 msr = rdmsr(SMM_MASK_MSR);
Felix Held357cc652020-07-09 00:04:22 +020056 msr.lo &= 0xffff0000; /* mask SMM_TSEG_VALID and reserved bits */
Felix Held65c4b862023-03-09 19:29:16 +010057 buffer.req.smm_mask = msr.raw;
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060058
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();
67 cmd_status = send_psp_command(MBOX_BIOS_CMD_SMM_INFO, &buffer);
68 clear_smm_flag();
69
70 /* buffer's status shouldn't change but report it if it does */
Felix Held7d304182020-04-15 17:05:38 +020071 psp_print_cmd_status(cmd_status, &buffer.header);
Marshall Dawsone8ffa9f2020-03-16 19:20:20 -060072
73 return cmd_status;
74}
Felix Held43126ed2020-04-01 22:06:39 +020075
76/* Notify PSP the system is going to a sleep state. */
77void psp_notify_sx_info(u8 sleep_type)
78{
79 int cmd_status;
80 struct mbox_cmd_sx_info_buffer *buffer;
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
87 if (sleep_type > MBOX_BIOS_CMD_SX_INFO_SLEEP_TYPE_MAX) {
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();
97 cmd_status = send_psp_command(MBOX_BIOS_CMD_SX_INFO, buffer);
98 clear_smm_flag();
99
100 /* buffer's status shouldn't change but report it if it does */
Felix Held7d304182020-04-15 17:05:38 +0200101 psp_print_cmd_status(cmd_status, &buffer->header);
Felix Held43126ed2020-04-01 22:06:39 +0200102}