summaryrefslogtreecommitdiff
path: root/src/soc/amd/common
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2022-04-29 19:25:19 +0200
committerFelix Held <felix-coreboot@felixheld.de>2022-05-04 16:08:16 +0000
commit198cc26e4951b3dbca588286706b7df562c45d42 (patch)
treecce7c5e4419dca39828364b025f29212f2c54570 /src/soc/amd/common
parentc48ec7b2bf3d09bd8be8fb3b9e3aac66f3dbf5dc (diff)
soc/amd/common/block/psp/psp_gen2: use SMN access to PSP
Since we can't rely on the MMIO base address in the PSP_ADDR_MSR MSR to access the PSP mailbox registers, switch to using the SMN mapping of the PSP mailbox registers. The PSP SMN base address is taken from the amdgpu driver in the Linux kernel. BUG=b:229779018 TEST=Mandolin still boots successfully and there are no errors/warnings about possibly PSP-related things. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: I9d17e523e9ae8d8e14ecedc37131a81f82351487 Reviewed-on: https://review.coreboot.org/c/coreboot/+/64034 Reviewed-by: Raul Rangel <rrangel@chromium.org> Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/amd/common')
-rw-r--r--src/soc/amd/common/block/psp/Kconfig1
-rw-r--r--src/soc/amd/common/block/psp/psp_gen2.c65
2 files changed, 26 insertions, 40 deletions
diff --git a/src/soc/amd/common/block/psp/Kconfig b/src/soc/amd/common/block/psp/Kconfig
index 3249174adb..22ebb6803b 100644
--- a/src/soc/amd/common/block/psp/Kconfig
+++ b/src/soc/amd/common/block/psp/Kconfig
@@ -14,6 +14,7 @@ config SOC_AMD_COMMON_BLOCK_PSP_GEN1
config SOC_AMD_COMMON_BLOCK_PSP_GEN2
bool
select SOC_AMD_COMMON_BLOCK_PSP
+ select SOC_AMD_COMMON_BLOCK_SMN
help
Used by the PSP in AMD family 17h, 19h and possibly newer CPUs.
diff --git a/src/soc/amd/common/block/psp/psp_gen2.c b/src/soc/amd/common/block/psp/psp_gen2.c
index 80650cb8fd..820d44d4c9 100644
--- a/src/soc/amd/common/block/psp/psp_gen2.c
+++ b/src/soc/amd/common/block/psp/psp_gen2.c
@@ -2,16 +2,16 @@
#include <bootstate.h>
#include <console/console.h>
-#include <cpu/amd/msr.h>
-#include <cpu/x86/msr.h>
-#include <device/mmio.h>
#include <timer.h>
#include <amdblocks/psp.h>
-#include <soc/iomap.h>
+#include <amdblocks/smn.h>
#include "psp_def.h"
+#define SMN_PSP_PUBLIC_BASE 0x3800000
+
#define PSP_MAILBOX_COMMAND_OFFSET 0x10570 /* 4 bytes */
-#define PSP_MAILBOX_BUFFER_OFFSET 0x10574 /* 8 bytes */
+#define PSP_MAILBOX_BUFFER_L_OFFSET 0x10574 /* 4 bytes */
+#define PSP_MAILBOX_BUFFER_H_OFFSET 0x10578 /* 4 bytes */
#define CORE_2_PSP_MSG_38_OFFSET 0x10998 /* 4 byte */
#define CORE_2_PSP_MSG_38_FUSE_SPL BIT(12)
@@ -27,45 +27,40 @@ union pspv2_mbox_command {
} __packed fields;
};
-static uintptr_t soc_get_psp_base_address(void)
-{
- uintptr_t psp_mmio = rdmsr(PSP_ADDR_MSR).lo;
- if (!psp_mmio)
- printk(BIOS_ERR, "PSP: PSP_ADDR_MSR uninitialized\n");
- return psp_mmio;
-}
-
-static u16 rd_mbox_sts(uintptr_t psp_mmio)
+static u16 rd_mbox_sts(void)
{
union pspv2_mbox_command tmp;
- tmp.val = read32p(psp_mmio + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp.val = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
return tmp.fields.mbox_status;
}
-static void wr_mbox_cmd(uintptr_t psp_mmio, u8 cmd)
+static void wr_mbox_cmd(u8 cmd)
{
union pspv2_mbox_command tmp = { .val = 0 };
/* Write entire 32-bit area to begin command execution */
tmp.fields.mbox_command = cmd;
- write32p(psp_mmio + PSP_MAILBOX_COMMAND_OFFSET, tmp.val);
+ smn_write32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET, tmp.val);
}
-static u8 rd_mbox_recovery(uintptr_t psp_mmio)
+static u8 rd_mbox_recovery(void)
{
union pspv2_mbox_command tmp;
- tmp.val = read32p(psp_mmio + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp.val = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
return !!tmp.fields.recovery;
}
-static void wr_mbox_buffer_ptr(uintptr_t psp_mmio, void *buffer)
+static void wr_mbox_buffer_ptr(void *buffer)
{
- write64p(psp_mmio + PSP_MAILBOX_BUFFER_OFFSET, (uintptr_t)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);
}
-static int wait_command(uintptr_t psp_mmio, bool wait_for_ready)
+static int wait_command(bool wait_for_ready)
{
union pspv2_mbox_command and_mask = { .val = ~0 };
union pspv2_mbox_command expected = { .val = 0 };
@@ -83,7 +78,7 @@ static int wait_command(uintptr_t psp_mmio, bool wait_for_ready)
stopwatch_init_msecs_expire(&sw, PSP_CMD_TIMEOUT);
do {
- tmp = read32p(psp_mmio + PSP_MAILBOX_COMMAND_OFFSET);
+ tmp = smn_read32(SMN_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET);
tmp &= ~and_mask.val;
if (tmp == expected.val)
return 0;
@@ -94,27 +89,23 @@ static int wait_command(uintptr_t psp_mmio, bool wait_for_ready)
int send_psp_command(u32 command, void *buffer)
{
- uintptr_t psp_mmio = soc_get_psp_base_address();
- if (!psp_mmio)
- return -PSPSTS_NOBASE;
-
- if (rd_mbox_recovery(psp_mmio))
+ if (rd_mbox_recovery())
return -PSPSTS_RECOVERY;
- if (wait_command(psp_mmio, true))
+ if (wait_command(true))
return -PSPSTS_CMD_TIMEOUT;
/* set address of command-response buffer and write command register */
- wr_mbox_buffer_ptr(psp_mmio, buffer);
- wr_mbox_cmd(psp_mmio, command);
+ wr_mbox_buffer_ptr(buffer);
+ wr_mbox_cmd(command);
/* PSP clears command register when complete. All commands except
* SxInfo set the Ready bit. */
- if (wait_command(psp_mmio, command != MBOX_BIOS_CMD_SX_INFO))
+ if (wait_command(command != MBOX_BIOS_CMD_SX_INFO))
return -PSPSTS_CMD_TIMEOUT;
/* check delivery status */
- if (rd_mbox_sts(psp_mmio))
+ if (rd_mbox_sts())
return -PSPSTS_SEND_ERROR;
return 0;
@@ -122,13 +113,7 @@ int send_psp_command(u32 command, void *buffer)
enum cb_err soc_read_c2p38(uint32_t *msg_38_value)
{
- uintptr_t psp_mmio = soc_get_psp_base_address();
-
- 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);
+ *msg_38_value = smn_read32(SMN_PSP_PUBLIC_BASE + CORE_2_PSP_MSG_38_OFFSET);
return CB_SUCCESS;
}