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/+/83446?usp=email )
Change subject: soc/amd/common/block/psp_gen2: add get_psp_mmio_base ......................................................................
soc/amd/common/block/psp_gen2: add get_psp_mmio_base
Add get_psp_mmio_base which reads the PSP MMIO base address from the hardware registers. Since this function will not only be called in ramstage, but also in SMM, we can't just look for the specific domain resource consumer like it is done for the IOAPICs in the northbridge, but have to get this base address from the registers. In order to limit the performance impact of this, the base address gets cached in a static variable if the hardware lock bit of the corresponding base address register is already set which means the base address can't change any more before the next reset.
This is a preparation to move back to using MMIO access to the PSP registers and will also enable cases that require the use of the MMIO mapping of the PSP registers.
Signed-off-by: Felix Held felix-coreboot@felixheld.de Change-Id: I1d51e30f186508b0fe1ab5eb79c73e6d4b9d1a4a --- M src/soc/amd/common/block/psp/psp_def.h M src/soc/amd/common/block/psp/psp_gen2.c 2 files changed, 66 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/46/83446/1
diff --git a/src/soc/amd/common/block/psp/psp_def.h b/src/soc/amd/common/block/psp/psp_def.h index 9def98b..f6efa21 100644 --- a/src/soc/amd/common/block/psp/psp_def.h +++ b/src/soc/amd/common/block/psp/psp_def.h @@ -108,6 +108,8 @@ #define PSP_INIT_TIMEOUT 10000 /* 10 seconds */ #define PSP_CMD_TIMEOUT 1000 /* 1 second */
+uintptr_t get_psp_mmio_base(void); + void psp_print_cmd_status(int cmd_status, struct mbox_buffer_header *header);
/* This command needs to be implemented by the generation specific code. */ diff --git a/src/soc/amd/common/block/psp/psp_gen2.c b/src/soc/amd/common/block/psp/psp_gen2.c index f647dcd..98baf86 100644 --- a/src/soc/amd/common/block/psp/psp_gen2.c +++ b/src/soc/amd/common/block/psp/psp_gen2.c @@ -3,6 +3,7 @@ #include <timer.h> #include <types.h> #include <amdblocks/psp.h> +#include <amdblocks/root_complex.h> #include <amdblocks/smn.h> #include "psp_def.h"
@@ -10,6 +11,69 @@ #define PSP_MAILBOX_BUFFER_L_OFFSET 0x10574 /* 4 bytes */ #define PSP_MAILBOX_BUFFER_H_OFFSET 0x10578 /* 4 bytes */
+#define IOHC_MISC_PSP_MMIO_REG 0x2e0 + +static uint64_t get_psp_mmio_mask(void) +{ + const struct non_pci_mmio_reg *mmio_regs; + size_t reg_count; + mmio_regs = get_iohc_non_pci_mmio_regs(®_count); + + for (size_t i = 0; i < reg_count; i++) { + if (mmio_regs[i].iohc_misc_offset == IOHC_MISC_PSP_MMIO_REG) + return mmio_regs[i].mask; + } + + printk(BIOS_ERR, "No PSP MMIO register description found.\n"); + return 0; +} + +/* Getting the PSP MMIO base from the domain resources only works in ramstage, but not in SMM, + so we have to read this form the hardware registers */ +uintptr_t get_psp_mmio_base(void) +{ + static uintptr_t psp_mmio_base; + const struct domain_iohc_info *iohc; + size_t iohc_count; + + if (psp_mmio_base) + return psp_mmio_base; + + iohc = get_iohc_info(&iohc_count); + const uint64_t psp_mmio_mask = get_psp_mmio_mask(); + + if (!psp_mmio_mask) + return 0; + + for (size_t i = 0; i < iohc_count; i++) { + const uint64_t reg64 = + smn_read64(iohc[i].misc_smn_base | IOHC_MISC_PSP_MMIO_REG); + + if (!(reg64 & IOHC_MMIO_EN)) + continue; + + const uint64_t base = reg64 & psp_mmio_mask; + + if (ENV_X86_32 && base >= 4ull * GiB) { + printk(BIOS_WARNING, "PSP MMIO base above 4GB.\n"); + continue; + } + + /* Don't cache the PSP MMIO base if the register isn't locked */ + if (!(reg64 & BIT(8))) { + printk(BIOS_WARNING, "PSP MMIO in domain %ld isn't locked\n", i); + return base; + } else { + psp_mmio_base = base; + } + } + + if (!psp_mmio_base) + printk(BIOS_ERR, "No usable PSP MMIO found.\n"); + + return psp_mmio_base; +} + union pspv2_mbox_command { u32 val; struct pspv2_mbox_cmd_fields {