Attention is currently required from: Fred Reitberger, Jason Glenesk, Matt DeVillier.
Felix Held has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/83448?usp=email )
Change subject: soc/amd/common/psp_gen2: use MMIO access again ......................................................................
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").
Since the fist get_psp_mmio_base call in SMM will be done in ramstage when coreboot triggers the APM_CNT_SMMINFO SMI which results in psp_notify_smm being called, the PSP MMIO base address will already be saved to the static variable inside get_psp_mmio_base, so we don't have to worry about get_psp_mmio_base potentially clobbering the SMN index register during OS runtime. Right now, this doesn't matter, 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 which will be triggered by the OS as last step after is done with all its preparations for suspend/shutdown. There will however be future patches that add SMI- handlers that can send PSP mailbox commands during OS runtime where we have to make sure to not 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 --- M src/soc/amd/common/block/psp/psb.c M src/soc/amd/common/block/psp/psp_gen2.c 2 files changed, 43 insertions(+), 26 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/48/83448/1
diff --git a/src/soc/amd/common/block/psp/psb.c b/src/soc/amd/common/block/psp/psb.c index a537bff..4ac7aaf 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 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 @@ } };
- 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 98136d1..dd3e7d3 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
@@ -85,40 +85,37 @@ } __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 }; @@ -136,7 +133,7 @@ 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; @@ -147,23 +144,27 @@
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; @@ -171,6 +172,12 @@
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; } \ No newline at end of file