summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2024-07-13 02:50:03 +0200
committerFelix Held <felix-coreboot@felixheld.de>2024-07-25 22:56:37 +0000
commit331cb328c29dee5cb4053059fd21f134176ca96f (patch)
tree8939494792c2a4dcb863871949c43caa619e2169
parent645203a28052b78c524bf101df960ae59f5828b0 (diff)
soc/amd/common/psp_gen2: use MMIO access again
Now that we have a get_psp_mmio_base function that will work on all SoCs that use the psp_gen2 code, we can move back to accessing the PSP registers via their MMIO mapping. This sort-of reverts commit 198cc26e4951 ("soc/amd/common/block/psp/psp_gen2: use SMN access to PSP"). When doing SMN accesses from the SMI handler after the OS has taken over ownership of the platform, there's the possibility to cause trouble by clobbering the SMN access index register from SMM. So that should be either avoided completely or the SMI code needs to save and restore the original contents of the SMN index register. The PSP MMIO base will be set up by the FSP before the resource allocation in coreboot and be treated like a fixed resource by the allocator. The first SMI where corresponding handler calls 'get_psp_mmio_base' happens when ramstage triggers the APM_CNT_SMMINFO SMI right after mpinit which happens after the resource allocation. So the PSP MMIO base address is expected to be configured and so the 'get_psp_mmio_base' function will cache the base address and won't need to do any SMN access in subsequent calls that might happen after the OS has take over control. This isn't currently an issue, since the only PSP mailbox command from the SMI handler after coreboot is done and the OS has taken over will be during the S3/S4/S5 entry, and this will be triggered by the OS as the last step after it is done with all its preparations for suspend/ shutdown. There will however be future patches that add SMI-handlers which can send PSP mailbox commands during OS runtime, and so we have to make sure we don't clobber the SMN index register. TEST=PSP mailbox commands are still sent correctly on Mandolin. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: I25f16d575991021d65b7b578956d9f90bfd15f6c Reviewed-on: https://review.coreboot.org/c/coreboot/+/83448 Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com> Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/soc/amd/common/block/psp/psb.c18
-rw-r--r--src/soc/amd/common/block/psp/psp_gen2.c51
2 files changed, 43 insertions, 26 deletions
diff --git a/src/soc/amd/common/block/psp/psb.c b/src/soc/amd/common/block/psp/psb.c
index a537bff37b..4ac7aaf08c 100644
--- a/src/soc/amd/common/block/psp/psb.c
+++ b/src/soc/amd/common/block/psp/psb.c
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/reset.h>
-#include <amdblocks/smn.h>
#include <bootstate.h>
#include <console/console.h>
#include <device/mmio.h>
@@ -83,9 +82,16 @@ static const char *fuse_status_to_string(u32 status)
}
}
-static uint32_t get_psb_status(void)
+static enum cb_err get_psb_status(uint32_t *psb_status_value)
{
- return smn_read32(SMN_PSP_PUBLIC_BASE + PSB_STATUS_OFFSET);
+ const uintptr_t psp_mmio = get_psp_mmio_base();
+
+ if (!psp_mmio) {
+ printk(BIOS_WARNING, "PSP: PSP_ADDR_MSR uninitialized\n");
+ return CB_ERR;
+ }
+ *psb_status_value = read32p(psp_mmio | PSB_STATUS_OFFSET);
+ return CB_SUCCESS;
}
/*
@@ -102,7 +108,11 @@ static enum cb_err psb_enable(void)
}
};
- status = get_psb_status();
+ if (get_psb_status(&status) != CB_SUCCESS) {
+ printk(BIOS_ERR, "PSP: Failed to get base address.\n");
+ return CB_ERR;
+ }
+
printk(BIOS_INFO, "PSB: Status = %x\n", status);
if (status & FUSE_PLATFORM_SECURE_BOOT_EN) {
diff --git a/src/soc/amd/common/block/psp/psp_gen2.c b/src/soc/amd/common/block/psp/psp_gen2.c
index 8f0bdcf9a1..bed31c1e8e 100644
--- a/src/soc/amd/common/block/psp/psp_gen2.c
+++ b/src/soc/amd/common/block/psp/psp_gen2.c
@@ -5,11 +5,11 @@
#include <amdblocks/psp.h>
#include <amdblocks/root_complex.h>
#include <amdblocks/smn.h>
+#include <device/mmio.h>
#include "psp_def.h"
#define PSP_MAILBOX_COMMAND_OFFSET 0x10570 /* 4 bytes */
-#define PSP_MAILBOX_BUFFER_L_OFFSET 0x10574 /* 4 bytes */
-#define PSP_MAILBOX_BUFFER_H_OFFSET 0x10578 /* 4 bytes */
+#define PSP_MAILBOX_BUFFER_OFFSET 0x10574 /* 8 bytes */
#define IOHC_MISC_PSP_MMIO_REG 0x2e0
@@ -92,40 +92,37 @@ union pspv2_mbox_command {
} __packed fields;
};
-static u16 rd_mbox_sts(void)
+static u16 rd_mbox_sts(uintptr_t psp_mmio)
{
union pspv2_mbox_command tmp;
- tmp.val = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp.val = read32p(psp_mmio | PSP_MAILBOX_COMMAND_OFFSET);
return tmp.fields.mbox_status;
}
-static void wr_mbox_cmd(u8 cmd)
+static void wr_mbox_cmd(uintptr_t psp_mmio, u8 cmd)
{
union pspv2_mbox_command tmp = { .val = 0 };
/* Write entire 32-bit area to begin command execution */
tmp.fields.mbox_command = cmd;
- smn_write32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET, tmp.val);
+ write32p(psp_mmio | PSP_MAILBOX_COMMAND_OFFSET, tmp.val);
}
-static u8 rd_mbox_recovery(void)
+static u8 rd_mbox_recovery(uintptr_t psp_mmio)
{
union pspv2_mbox_command tmp;
- tmp.val = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp.val = read32p(psp_mmio | PSP_MAILBOX_COMMAND_OFFSET);
return !!tmp.fields.recovery;
}
-static void wr_mbox_buffer_ptr(void *buffer)
+static void wr_mbox_buffer_ptr(uintptr_t psp_mmio, void *buffer)
{
- const uint32_t buf_addr_h = (uint64_t)(uintptr_t)buffer >> 32;
- const uint32_t buf_addr_l = (uint64_t)(uintptr_t)buffer & 0xffffffff;
- smn_write32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_H_OFFSET, buf_addr_h);
- smn_write32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_L_OFFSET, buf_addr_l);
+ write64p(psp_mmio | PSP_MAILBOX_BUFFER_OFFSET, (uintptr_t)buffer);
}
-static int wait_command(bool wait_for_ready)
+static int wait_command(uintptr_t psp_mmio, bool wait_for_ready)
{
union pspv2_mbox_command and_mask = { .val = ~0 };
union pspv2_mbox_command expected = { .val = 0 };
@@ -143,7 +140,7 @@ static int wait_command(bool wait_for_ready)
stopwatch_init_msecs_expire(&sw, PSP_CMD_TIMEOUT);
do {
- tmp = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp = read32p(psp_mmio | PSP_MAILBOX_COMMAND_OFFSET);
tmp &= ~and_mask.val;
if (tmp == expected.val)
return 0;
@@ -154,23 +151,27 @@ static int wait_command(bool wait_for_ready)
int send_psp_command(u32 command, void *buffer)
{
- if (rd_mbox_recovery())
+ const uintptr_t psp_mmio = get_psp_mmio_base();
+ if (!psp_mmio)
+ return -PSPSTS_NOBASE;
+
+ if (rd_mbox_recovery(psp_mmio))
return -PSPSTS_RECOVERY;
- if (wait_command(true))
+ if (wait_command(psp_mmio, true))
return -PSPSTS_CMD_TIMEOUT;
/* set address of command-response buffer and write command register */
- wr_mbox_buffer_ptr(buffer);
- wr_mbox_cmd(command);
+ wr_mbox_buffer_ptr(psp_mmio, buffer);
+ wr_mbox_cmd(psp_mmio, command);
/* PSP clears command register when complete. All commands except
* SxInfo set the Ready bit. */
- if (wait_command(command != MBOX_BIOS_CMD_SX_INFO))
+ if (wait_command(psp_mmio, command != MBOX_BIOS_CMD_SX_INFO))
return -PSPSTS_CMD_TIMEOUT;
/* check delivery status */
- if (rd_mbox_sts())
+ if (rd_mbox_sts(psp_mmio))
return -PSPSTS_SEND_ERROR;
return 0;
@@ -178,6 +179,12 @@ int send_psp_command(u32 command, void *buffer)
enum cb_err soc_read_c2p38(uint32_t *msg_38_value)
{
- *msg_38_value = smn_read32(SMN_PSP_PUBLIC_BASE + CORE_2_PSP_MSG_38_OFFSET);
+ const uintptr_t psp_mmio = get_psp_mmio_base();
+
+ if (!psp_mmio) {
+ printk(BIOS_WARNING, "PSP: PSP_ADDR_MSR uninitialized\n");
+ return CB_ERR;
+ }
+ *msg_38_value = read32p(psp_mmio | CORE_2_PSP_MSG_38_OFFSET);
return CB_SUCCESS;
}