soc/mediatek/mt8196: Correct the region size for mcufw_reserved
[coreboot2.git] / src / soc / amd / common / block / psp / psp_smm.c
blob671942b0f859e6add01021fb96acf6837b6d3ec6
1 /* SPDX-License-Identifier: GPL-2.0-only */
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 <amdblocks/smi.h>
10 #include <soc/iomap.h>
11 #include <string.h>
13 #include "psp_def.h"
16 * When sending PSP mailbox commands to the PSP from the SMI handler after the boot done
17 * command was sent, the corresponding data buffer needs to be placed in this core to PSP (C2P)
18 * buffer.
20 struct {
21 uint8_t buffer[C2P_BUFFER_MAXSIZE];
22 } __aligned(32) c2p_buffer;
25 * When the PSP sends mailbox commands to the host, it will update the PSP to core (P2C) buffer
26 * and then send an SMI to the host to process the request.
28 struct {
29 uint8_t buffer[P2C_BUFFER_MAXSIZE];
30 } __aligned(32) p2c_buffer;
33 * When sending PSP mailbox commands to the PSP from the SMI handler, the SMM flag needs to be
34 * set for the PSP to accept it. Otherwise it should be cleared.
36 static uint32_t smm_flag;
38 static void set_smm_flag(void)
40 smm_flag = 1;
43 static void clear_smm_flag(void)
45 smm_flag = 0;
48 static int send_psp_command_smm(uint32_t command, void *buffer)
50 int cmd_status;
52 set_smm_flag();
53 cmd_status = send_psp_command(command, buffer);
54 clear_smm_flag();
56 return cmd_status;
60 * The MBOX_BIOS_CMD_SMM_INFO PSP mailbox command doesn't necessarily need be sent from SMM,
61 * but doing so allows the linker to sort out the addresses of c2p_buffer, p2c_buffer and
62 * smm_flag without us needing to pass this info between ramstage and smm. In the PSP gen2 case
63 * this will also make sure that the PSP MMIO base will be cached in SMM before the OS takes
64 * over so no SMN accesses will be needed during OS runtime.
66 int psp_notify_smm(void)
68 msr_t msr;
69 int cmd_status;
70 struct mbox_cmd_smm_info_buffer buffer = {
71 .header = {
72 .size = sizeof(buffer)
74 .req = {
75 .psp_smm_data_region = (uintptr_t)p2c_buffer.buffer,
76 .psp_smm_data_length = sizeof(p2c_buffer),
77 .psp_mbox_smm_buffer_address = (uintptr_t)c2p_buffer.buffer,
78 .psp_mbox_smm_flag_address = (uintptr_t)&smm_flag,
82 msr = rdmsr(SMM_ADDR_MSR);
83 buffer.req.smm_base = msr.raw;
84 msr = rdmsr(SMM_MASK_MSR);
85 msr.lo &= 0xffff0000; /* mask SMM_TSEG_VALID and reserved bits */
86 buffer.req.smm_mask = msr.raw;
88 soc_fill_smm_trig_info(&buffer.req.smm_trig_info);
89 #if (CONFIG(SOC_AMD_COMMON_BLOCK_PSP_GEN2))
90 soc_fill_smm_reg_info(&buffer.req.smm_reg_info);
91 #endif
93 if (CONFIG(SOC_AMD_COMMON_BLOCK_PSP_SMI)) {
94 configure_psp_smi();
95 enable_psp_smi();
98 printk(BIOS_DEBUG, "PSP: Notify SMM info... ");
100 cmd_status = send_psp_command_smm(MBOX_BIOS_CMD_SMM_INFO, &buffer);
102 /* buffer's status shouldn't change but report it if it does */
103 psp_print_cmd_status(cmd_status, &buffer.header);
105 return cmd_status;
108 /* Notify PSP the system is going to a sleep state. */
109 void psp_notify_sx_info(uint8_t sleep_type)
111 int cmd_status;
112 struct mbox_cmd_sx_info_buffer *buffer;
114 /* PSP verifies that this buffer is at the address specified in psp_notify_smm() */
115 buffer = (struct mbox_cmd_sx_info_buffer *)c2p_buffer.buffer;
116 memset(buffer, 0, sizeof(*buffer));
117 buffer->header.size = sizeof(*buffer);
119 if (sleep_type > MBOX_BIOS_CMD_SX_INFO_SLEEP_TYPE_MAX) {
120 printk(BIOS_ERR, "PSP: BUG: invalid sleep type 0x%x requested\n", sleep_type);
121 return;
124 printk(BIOS_DEBUG, "PSP: Prepare to enter sleep state %d... ", sleep_type);
126 buffer->sleep_type = sleep_type;
128 cmd_status = send_psp_command_smm(MBOX_BIOS_CMD_SX_INFO, buffer);
130 /* buffer's status shouldn't change but report it if it does */
131 psp_print_cmd_status(cmd_status, &buffer->header);