aboutsummaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block/psp
diff options
context:
space:
mode:
authorMarshall Dawson <marshall.dawson@amd.corp-partner.google.com>2020-03-16 19:20:20 -0600
committerFelix Held <felix-coreboot@felixheld.de>2020-04-16 23:15:09 +0000
commite8ffa9ffd3cf5cb9fcade12e1f1e0dea5fc3fcf2 (patch)
tree7599bd33ad59b015afe080744905af2b97b42c78 /src/soc/amd/common/block/psp
parente26da8ba16d4b87669524871b85a211a75f0eec4 (diff)
soc/amd/psp: Add SmmInfo command
Implement the MboxBiosCmdSmmInfo function to inform the PSP of the SoC's SMM configuration. Once the BootDone command is sent, the PSP only responds to commands where the buffer is in SMM memory. Set aside a region for the core-to-PSP command buffer and the PSP-to-core mailbox. Also add an SMM flag, which the PSP expects to read as non-zero during an SMI. Add calls to soc functions for the soc to populate the trigger info and register info (v2 only). Add functions to set up the structures needed for the SmmInfo function in Picasso support. Issue a SW SMI, and add a new handler to call the new PSP function. BUG=b:153677737 Change-Id: I10088a53e786db788740e4b388650641339dae75 Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40295 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
Diffstat (limited to 'src/soc/amd/common/block/psp')
-rw-r--r--src/soc/amd/common/block/psp/Makefile.inc1
-rw-r--r--src/soc/amd/common/block/psp/psp_def.h19
-rw-r--r--src/soc/amd/common/block/psp/psp_smm.c78
3 files changed, 98 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/psp/Makefile.inc b/src/soc/amd/common/block/psp/Makefile.inc
index dc9a385e39..c2a33354ad 100644
--- a/src/soc/amd/common/block/psp/Makefile.inc
+++ b/src/soc/amd/common/block/psp/Makefile.inc
@@ -11,5 +11,6 @@ ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP_GEN1) += psp_gen1.c
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP_GEN2) += psp_gen2.c
smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c
+smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp_smm.c
smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP_GEN1) += psp_gen1.c
smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP_GEN2) += psp_gen2.c
diff --git a/src/soc/amd/common/block/psp/psp_def.h b/src/soc/amd/common/block/psp/psp_def.h
index f3ac5c2181..63ca3abb0a 100644
--- a/src/soc/amd/common/block/psp/psp_def.h
+++ b/src/soc/amd/common/block/psp/psp_def.h
@@ -6,6 +6,7 @@
#include <types.h>
#include <commonlib/helpers.h>
+#include <amdblocks/psp.h>
/* x86 to PSP commands */
#define MBOX_BIOS_CMD_DRAM_INFO 0x01
@@ -81,6 +82,24 @@ struct mbox_default_buffer { /* command-response buffer unused by command */
struct mbox_buffer_header header;
} __attribute__((packed, aligned(32)));
+struct smm_req_buffer {
+ uint64_t smm_base; /* TSEG base */
+ uint64_t smm_mask; /* TSEG mask */
+ uint64_t psp_smm_data_region; /* PSP region in SMM space */
+ uint64_t psp_smm_data_length; /* PSP region length in SMM space */
+ struct smm_trigger_info smm_trig_info;
+#if CONFIG(SOC_AMD_COMMON_BLOCK_PSP_GEN2)
+ struct smm_register_info smm_reg_info;
+#endif
+ uint64_t psp_mbox_smm_buffer_address;
+ uint64_t psp_mbox_smm_flag_address;
+} __packed;
+
+struct mbox_cmd_smm_info_buffer {
+ struct mbox_buffer_header header;
+ struct smm_req_buffer req;
+} __attribute__((packed, aligned(32)));
+
struct mbox_cmd_sx_info_buffer {
struct mbox_buffer_header header;
u8 sleep_type;
diff --git a/src/soc/amd/common/block/psp/psp_smm.c b/src/soc/amd/common/block/psp/psp_smm.c
new file mode 100644
index 0000000000..cc15738881
--- /dev/null
+++ b/src/soc/amd/common/block/psp/psp_smm.c
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* This file is part of the coreboot project. */
+
+#include <device/mmio.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <cbfs.h>
+#include <region_file.h>
+#include <timer.h>
+#include <bootstate.h>
+#include <rules.h>
+#include <console/console.h>
+#include <amdblocks/psp.h>
+#include <soc/iomap.h>
+#include <soc/northbridge.h>
+#include "psp_def.h"
+
+#define C2P_BUFFER_MAXSIZE 0xc00 /* Core-to-PSP buffer */
+#define P2C_BUFFER_MAXSIZE 0xc00 /* PSP-to-core buffer */
+
+struct {
+ u8 buffer[C2P_BUFFER_MAXSIZE];
+} __attribute__((aligned(32))) c2p_buffer;
+
+struct {
+ u8 buffer[P2C_BUFFER_MAXSIZE];
+} __attribute__((aligned(32))) p2c_buffer;
+
+static uint32_t smm_flag; /* Non-zero for SMM, clear when not */
+
+static void set_smm_flag(void)
+{
+ smm_flag = 1;
+}
+
+static void clear_smm_flag(void)
+{
+ smm_flag = 0;
+}
+
+int psp_notify_smm(void)
+{
+ msr_t msr;
+ int cmd_status;
+ struct mbox_cmd_smm_info_buffer buffer = {
+ .header = {
+ .size = sizeof(buffer)
+ },
+ .req = {
+ .psp_smm_data_region = (uintptr_t)p2c_buffer.buffer,
+ .psp_smm_data_length = sizeof(p2c_buffer),
+ .psp_mbox_smm_buffer_address = (uintptr_t)c2p_buffer.buffer,
+ .psp_mbox_smm_flag_address = (uintptr_t)&smm_flag,
+ }
+ };
+
+ msr = rdmsr(SMM_ADDR_MSR);
+ buffer.req.smm_base = ((uint64_t)msr.hi << 32) | msr.lo;
+ msr = rdmsr(SMM_MASK_MSR);
+ msr.lo &= 0xffff0000; /* mask SMM_LOCK and SMM_TSEG_VALID and reserved bits */
+ buffer.req.smm_mask = ((uint64_t)msr.hi << 32) | msr.lo;
+
+ soc_fill_smm_trig_info(&buffer.req.smm_trig_info);
+#if (CONFIG(SOC_AMD_COMMON_BLOCK_PSP_GEN2))
+ soc_fill_smm_reg_info(&buffer.req.smm_reg_info);
+#endif
+
+ printk(BIOS_DEBUG, "PSP: Notify SMM info... ");
+
+ set_smm_flag();
+ cmd_status = send_psp_command(MBOX_BIOS_CMD_SMM_INFO, &buffer);
+ clear_smm_flag();
+
+ /* buffer's status shouldn't change but report it if it does */
+ psp_print_cmd_status(cmd_status, (struct mbox_default_buffer *)&buffer);
+
+ return cmd_status;
+}