Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/40000 )
Change subject: soc/amd/common/psp: Move early init to soc ......................................................................
soc/amd/common/psp: Move early init to soc
The initialization code in common//psp is very specific to Family 15h. Move this to the stoneyridge directory.
BUG=b:130660285 TEST: Verify PSP functionality on google/grunt
Change-Id: Ice3d06d6437f59a529c26fc2359565c940d39482 Signed-off-by: Marshall Dawson marshalldawson3rd@gmail.com Reviewed-on: https://chromium-review.googlesource.com/2020365 Reviewed-by: Eric Peers epeers@google.com Signed-off-by: Felix Held felix-coreboot@felixheld.de Reviewed-on: https://review.coreboot.org/c/coreboot/+/40000 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Angel Pons th3fanbus@gmail.com Reviewed-by: Raul Rangel rrangel@chromium.org Reviewed-by: Paul Menzel paulepanter@users.sourceforge.net --- M src/soc/amd/common/block/include/amdblocks/psp.h M src/soc/amd/common/block/psp/Makefile.inc M src/soc/amd/common/block/psp/psp.c M src/soc/amd/stoneyridge/Makefile.inc M src/soc/amd/stoneyridge/include/soc/southbridge.h A src/soc/amd/stoneyridge/psp.c M src/soc/amd/stoneyridge/romstage.c 7 files changed, 75 insertions(+), 126 deletions(-)
Approvals: build bot (Jenkins): Verified Paul Menzel: Looks good to me, but someone else must approve Marshall Dawson: Looks good to me, but someone else must approve Raul Rangel: Looks good to me, approved Angel Pons: Looks good to me, approved
diff --git a/src/soc/amd/common/block/include/amdblocks/psp.h b/src/soc/amd/common/block/include/amdblocks/psp.h index 494f174..42c802d 100644 --- a/src/soc/amd/common/block/include/amdblocks/psp.h +++ b/src/soc/amd/common/block/include/amdblocks/psp.h @@ -15,24 +15,8 @@ #ifndef __AMD_PSP_H__ #define __AMD_PSP_H__
-#include <amdblocks/agesawrapper.h> -#include <soc/pci_devs.h> -#include <types.h> - -/* Extra, Special Purpose Registers in the PSP PCI Config Space */ - -/* PSP Mirror Features Capabilities and Control Register */ -#define PSP_PCI_MIRRORCTRL1_REG 0x44 /* PSP Mirror Ctrl Reg */ -#define PMNXTPTRW_MASK 0xff /* PCI AFCR pointer mask */ -#define PMNXTPTRW_EXPOSE 0xa4 /* Pointer to expose the AFCR */ - -#define PSP_PCI_EXT_HDR_CTRL 0x48 /* Extra PCI Header Ctrl */ -#define MAGIC_ENABLES 0x34 /* Extra PCI HDR Ctl Enables */ - -#define PSP_MAILBOX_BASE 0x70 /* Mailbox offset from PCIe BAR */ - -#define MSR_CU_CBBCFG 0xc00110a2 /* PSP Pvt Blk Base Addr */ -#define BAR3HIDE BIT(12) /* Bit to hide BAR3 addr */ +/* Get the mailbox base address - specific to family of device. */ +struct psp_mbox *soc_get_mbox_address(void);
/* x86 to PSP commands */ #define MBOX_BIOS_CMD_DRAM_INFO 0x01 diff --git a/src/soc/amd/common/block/psp/Makefile.inc b/src/soc/amd/common/block/psp/Makefile.inc index d5f9386..2f5de1d 100644 --- a/src/soc/amd/common/block/psp/Makefile.inc +++ b/src/soc/amd/common/block/psp/Makefile.inc @@ -1,3 +1,4 @@ bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c +smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c index 9c053c2..7ec8d7b 100644 --- a/src/soc/amd/common/block/psp/psp.c +++ b/src/soc/amd/common/block/psp/psp.c @@ -33,73 +33,6 @@ static const char *psp_status_cmd_timeout = "error: PSP command timeout"; static const char *psp_status_noerror = "";
-static void psp_bar_init_early(void) -{ - u32 psp_mmio_size; - u32 value32; - u32 base, limit; - - /* Check for presence of the PSP */ - if (pci_read_config32(SOC_PSP_DEV, PCI_VENDOR_ID) == 0xffffffff) { - printk(BIOS_WARNING, "PSP: SOC_PSP_DEV device not found at D%xF%x\n", - PSP_DEV, PSP_FUNC); - return; - } - - /* Check if PSP BAR has been assigned, and if so, just return */ - if (pci_read_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4) & - ~PCI_BASE_ADDRESS_MEM_ATTR_MASK) - return; - - /* Otherwise, do an early init of the BAR */ - pci_write_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4, 0xffffffff); - psp_mmio_size = ~pci_read_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4) + 1; - printk(BIOS_SPEW, "PSP: BAR size is 0x%x\n", psp_mmio_size); - /* Assign BAR to an initial temporarily defined region */ - pci_write_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4, - PSP_MAILBOX_BAR3_BASE); - - /* Route MMIO through the northbridge */ - pci_write_config32(SOC_PSP_DEV, PCI_COMMAND, - (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); - limit = ((PSP_MAILBOX_BAR3_BASE + psp_mmio_size - 1) >> 8) & ~0xff; - pci_write_config32(SOC_ADDR_DEV, NB_MMIO_LIMIT_LO(7), limit); - base = (PSP_MAILBOX_BAR3_BASE >> 8) | MMIO_WE | MMIO_RE; - pci_write_config32(SOC_ADDR_DEV, NB_MMIO_BASE_LO(7), base); - pci_write_config32(SOC_PSP_DEV, PSP_PCI_EXT_HDR_CTRL, MAGIC_ENABLES); - - /* Update the capability chain */ - value32 = pci_read_config32(SOC_PSP_DEV, PSP_PCI_MIRRORCTRL1_REG); - value32 &= ~PMNXTPTRW_MASK; - value32 |= PMNXTPTRW_EXPOSE; - pci_write_config32(SOC_PSP_DEV, PSP_PCI_MIRRORCTRL1_REG, value32); -} - -static uintptr_t get_psp_bar3_addr(void) -{ - uintptr_t psp_mmio; - - /* Check for presence of the PSP */ - if (pci_read_config32(SOC_PSP_DEV, PCI_VENDOR_ID) == 0xffffffff) { - printk(BIOS_WARNING, "PSP: No SOC_PSP_DEV found at D%xF%x\n", - PSP_DEV, PSP_FUNC); - return 0; - } - - /* D8F0x48[12] is the Bar3Hide flag, check it */ - if (pci_read_config32(SOC_PSP_DEV, PSP_PCI_EXT_HDR_CTRL) & BAR3HIDE) { - psp_mmio = rdmsr(MSR_CU_CBBCFG).lo; - if (psp_mmio == 0xffffffff) { - printk(BIOS_WARNING, "PSP: BAR hidden, MSR val uninitialized\n"); - return 0; - } - return psp_mmio; - } else { - return pci_read_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4) & - ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; - } -} - static const char *status_to_string(int err) { switch (err) { @@ -120,23 +53,6 @@ } }
-static struct psp_mbox *get_mbox_address(void) -{ - uintptr_t baseptr; - - baseptr = get_psp_bar3_addr(); - if (baseptr == 0) { - psp_bar_init_early(); - baseptr = get_psp_bar3_addr(); - if (baseptr == 0) { - printk(BIOS_WARNING, "PSP: %s(), psp_bar_init_early() failed...\n", - __func__); - return NULL; - } - } - return (struct psp_mbox *)(baseptr + PSP_MAILBOX_BASE); -} - static u32 rd_mbox_sts(struct psp_mbox *mbox) { return read32(&mbox->mbox_status); @@ -192,7 +108,7 @@
static int send_psp_command(u32 command, void *buffer) { - struct psp_mbox *mbox = get_mbox_address(); + struct psp_mbox *mbox = soc_get_mbox_address(); if (!mbox) return -PSPSTS_NOBASE;
diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc index 96b8303..50e53c4 100644 --- a/src/soc/amd/stoneyridge/Makefile.inc +++ b/src/soc/amd/stoneyridge/Makefile.inc @@ -59,6 +59,7 @@ romstage-y += tsc_freq.c romstage-y += southbridge.c romstage-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c +romstage-y += psp.c
verstage-y += gpio.c verstage-y += i2c.c @@ -93,6 +94,7 @@ ramstage-y += usb.c ramstage-y += tsc_freq.c ramstage-y += finalize.c +ramstage-y += psp.c
all-y += reset.c
@@ -102,6 +104,7 @@ smm-y += tsc_freq.c smm-$(CONFIG_DEBUG_SMI) += uart.c smm-y += gpio.c +smm-y += psp.c
CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/include diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 45bad1f..7384951 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -290,10 +290,17 @@ #define SPI_RD4DW_EN_HOST BIT(15)
/* Platform Security Processor D8F0 */ +void soc_enable_psp_early(void); + #define PSP_MAILBOX_BAR PCI_BASE_ADDRESS_4 /* BKDG: "BAR3" */ +#define PSP_MAILBOX_OFFSET 0x70 /* offset from BAR3 value */ + #define PSP_BAR_ENABLES 0x48 #define PSP_MAILBOX_BAR_EN 0x10
+#define MSR_CU_CBBCFG 0xc00110a2 /* PSP Pvt Blk Base Addr */ +#define BAR3HIDE BIT(12) /* Bit to hide BAR3 addr */ + /* IO 0xcf9 - Reset control port*/ #define FULL_RST BIT(3) #define RST_CMD BIT(2) diff --git a/src/soc/amd/stoneyridge/psp.c b/src/soc/amd/stoneyridge/psp.c new file mode 100644 index 0000000..bc2d725 --- /dev/null +++ b/src/soc/amd/stoneyridge/psp.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* This file is part of the coreboot project. */ + +#include <console/console.h> +#include <device/pci_ops.h> +#include <device/pci_def.h> +#include <cpu/x86/msr.h> +#include <soc/pci_devs.h> +#include <soc/northbridge.h> +#include <soc/southbridge.h> +#include <amdblocks/psp.h> + +void soc_enable_psp_early(void) +{ + u32 base, limit, cmd; + + /* Open a posted hole from 0x80000000 : 0xfed00000-1 */ + base = (0x80000000 >> 8) | MMIO_WE | MMIO_RE; + limit = (ALIGN_DOWN(HPET_BASE_ADDRESS - 1, 64 * KiB) >> 8); + pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_LIMIT0_LO, limit); + pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_BASE0_LO, base); + + /* Preload a value into BAR and enable it */ + pci_write_config32(SOC_PSP_DEV, PSP_MAILBOX_BAR, PSP_MAILBOX_BAR3_BASE); + pci_write_config32(SOC_PSP_DEV, PSP_BAR_ENABLES, PSP_MAILBOX_BAR_EN); + + /* Enable memory access and master */ + cmd = pci_read_config32(SOC_PSP_DEV, PCI_COMMAND); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config32(SOC_PSP_DEV, PCI_COMMAND, cmd); +}; + +struct psp_mbox *soc_get_mbox_address(void) +{ + uintptr_t psp_mmio; + + /* Check for presence of the PSP */ + if (pci_read_config32(SOC_PSP_DEV, PCI_VENDOR_ID) == 0xffffffff) { + printk(BIOS_WARNING, "PSP: No SOC_PSP_DEV found at D%xF%x\n", + PSP_DEV, PSP_FUNC); + return 0; + } + + /* Determine if Bar3Hide has been set, and if hidden get the base from + * the MSR instead. */ + if (pci_read_config32(SOC_PSP_DEV, PSP_BAR_ENABLES) & BAR3HIDE) { + psp_mmio = rdmsr(MSR_CU_CBBCFG).lo; + if (psp_mmio == 0xffffffff) { + printk(BIOS_WARNING, "PSP: BAR hidden, MSR val uninitialized\n"); + return 0; + } + } else { + psp_mmio = pci_read_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4) & + ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; + } + + return (struct psp_mbox *)(psp_mmio + PSP_MAILBOX_OFFSET); +} diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c index efe75b7..fab9a83 100644 --- a/src/soc/amd/stoneyridge/romstage.c +++ b/src/soc/amd/stoneyridge/romstage.c @@ -31,6 +31,7 @@ #include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper_call.h> #include <soc/northbridge.h> +#include <soc/pci_devs.h> #include <soc/romstage.h> #include <soc/southbridge.h> #include <amdblocks/psp.h> @@ -42,28 +43,6 @@ /* By default, don't do anything */ }
-static void load_smu_fw1(void) -{ - u32 base, limit, cmd; - - /* Open a posted hole from 0x80000000 : 0xfed00000-1 */ - base = (0x80000000 >> 8) | MMIO_WE | MMIO_RE; - limit = (ALIGN_DOWN(HPET_BASE_ADDRESS - 1, 64 * KiB) >> 8); - pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_LIMIT0_LO, limit); - pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_BASE0_LO, base); - - /* Preload a value into "BAR3" and enable it */ - pci_write_config32(SOC_PSP_DEV, PSP_MAILBOX_BAR, PSP_MAILBOX_BAR3_BASE); - pci_write_config32(SOC_PSP_DEV, PSP_BAR_ENABLES, PSP_MAILBOX_BAR_EN); - - /* Enable memory access and master */ - cmd = pci_read_config32(SOC_PSP_DEV, PCI_COMMAND); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config32(SOC_PSP_DEV, PCI_COMMAND, cmd); - - psp_load_named_blob(BLOB_SMU_FW, "smu_fw"); -} - static void agesa_call(void) { post_code(0x37); @@ -92,8 +71,9 @@
console_init();
+ soc_enable_psp_early(); if (CONFIG(SOC_AMD_PSP_SELECTABLE_SMU_FW)) - load_smu_fw1(); + psp_load_named_blob(BLOB_SMU_FW, "smu_fw");
mainboard_romstage_entry_s3(s3_resume); elog_boot_notify(s3_resume);