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>
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)
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.
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)
43 static void clear_smm_flag(void)
48 static int send_psp_command_smm(uint32_t command
, void *buffer
)
53 cmd_status
= send_psp_command(command
, buffer
);
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)
70 struct mbox_cmd_smm_info_buffer buffer
= {
72 .size
= sizeof(buffer
)
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
);
93 if (CONFIG(SOC_AMD_COMMON_BLOCK_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
);
108 /* Notify PSP the system is going to a sleep state. */
109 void psp_notify_sx_info(uint8_t sleep_type
)
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
);
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
);