Hello Charles Marslett,
I'd like you to do a code review. Please visit
https://review.coreboot.org/27619
to review the following change.
Change subject: Add header file: psp.h, and modify code in psp.c to use internal functions rather than functions from PspBaseLib. ......................................................................
Add header file: psp.h, and modify code in psp.c to use internal functions rather than functions from PspBaseLib.
Change-Id: I2740ceb945736c6e413f7d0bd0c41a19e19c7d5a Signed-off-by: Charles Marslett charles.marslett@silverbackltd.com --- M src/soc/amd/common/block/psp/psp.c A src/soc/amd/common/block/psp/psp.h 2 files changed, 175 insertions(+), 13 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/27619/1
diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c index a1a0e5b..dbb0267 100644 --- a/src/soc/amd/common/block/psp/psp.c +++ b/src/soc/amd/common/block/psp/psp.c @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */
@@ -20,7 +20,11 @@ #include <device/pci_def.h> #include <bootstate.h> #include <console/console.h> +#include <device/pci_ops.h> #include <amdblocks/psp.h> +#include <soc/iomap.h> +#include "psp.h" +
static const char *psp_status_nobase = "error: PSP BAR3 not assigned"; static const char *psp_status_halted = "error: PSP in halted state"; @@ -30,6 +34,124 @@ static const char *psp_status_cmd_timeout = "error: PSP command timeout"; static const char *psp_status_noerror = "";
+static BOOLEAN psp_bar_init_early(VOID); + + +/** + Attempt to perform a very early initialization of the PSP device + BAR3 register. + + @retval BOOLEAN 0: Error, 1 Success +**/ +static BOOLEAN +psp_bar_init_early(VOID) +{ + u32 PspMmioSize; + u32 Value32; + PCI_ADDR PciAddr; + + printk(BIOS_DEBUG, "PSP: %s() called...\n", __func__); + + Value32 = pci_read_config32(SOC_PSP_DEV, PSP_PCI_DEVID_REG); + if (Value32 == 0xffffffff) { + printk(BIOS_DEBUG, "PSP: No device at PSP Seg/Bus/Dev/FUNC...\n"); + return FALSE; + } + + // Check if PSP BAR has been assigned, + // if not do the PSP BAR initialization + Value32 = pci_read_config32(SOC_PSP_DEV, PSP_PCI_BAR3_REG); + if ((Value32 & ~0x0F) == 0) { + printk(BIOS_DEBUG, "PSP: BAR3 value is zero...\n"); + /// Get PSP BAR3 Size + pci_write_config32(SOC_PSP_DEV, PSP_PCI_BAR3_REG, + (u32)0xFFFFFFFF); + PspMmioSize = ~pci_read_config32(SOC_PSP_DEV, PSP_PCI_BAR3_REG) + + 1; + printk(BIOS_DEBUG, "PSP: BAR3 size is 0x%x...\n", PspMmioSize); + /// Assign BAR3 Temporary Address + pci_write_config32(SOC_PSP_DEV, PSP_PCI_BAR3_REG, + PSP_MAILBOX_BAR3_BASE); + /// Enable Access + pci_write_config32(SOC_PSP_DEV, PSP_PCI_CMD_REG, 0x06); + printk(BIOS_DEBUG, "PSP: BAR3 set to 0x%x, CMD=0x%x zero...\n", + (unsigned int)pci_read_config32(SOC_PSP_DEV, + PSP_PCI_BAR3_REG), + (unsigned int)pci_read_config32(SOC_PSP_DEV, + PSP_PCI_CMD_REG)); + + /// Enable GNB redirection to this space + /// @todo use equate & also find proper fix + PciAddr.AddressValue = MAKE_SBDFO(0, 0, 0x18, 1, 0xBC); + Value32 = ((PSP_MAILBOX_BAR3_BASE + PspMmioSize - 1) >> 8) + & ~0xFF; + LibAmdPciWrite(AccessWidth32, PciAddr, &Value32, NULL); + + PciAddr.AddressValue = MAKE_SBDFO(0, 0, 0x18, 1, 0xB8); + Value32 = (PSP_MAILBOX_BAR3_BASE >> 8) | 3; + LibAmdPciWrite(AccessWidth32, PciAddr, &Value32, NULL); + + /// Enable MsixBarEn, Bar1En, Bar3En + pci_write_config32(SOC_PSP_DEV, PSP_PCI_EXTRAPCIHDR_REG, + 0x34); + + /// Capability chain update + Value32 = pci_read_config32(SOC_PSP_DEV, + PSP_PCI_MIRRORCTRL1_REG); + Value32 &= ~D8F0x44_PmNxtPtrW_MASK; + Value32 |= 0xA4; + pci_write_config32(SOC_PSP_DEV, PSP_PCI_MIRRORCTRL1_REG, + Value32); + } + return TRUE; +} + + +/** + Return the PspMMIO MMIO location + + @param[in] PspMmio Pointer to Psp MMIO address + + @retval BOOLEAN 0: Error, 1 Success +**/ +static BOOLEAN +get_psp_bar3_addr( + IN OUT u32 *PspMmio + ) +{ + u32 Value; + + pci_write_config32(SOC_PSP_DEV, PCI_CONFIG_SMU_INDIRECT_INDEX, + SMU_CC_PSP_FUSES_STATUS); + Value = pci_read_config32(SOC_PSP_DEV, PCI_CONFIG_SMU_INDIRECT_DATA); + if ((Value & SMU_CC_PSP_FUSES_PROTO) != 0) { + printk(BIOS_DEBUG, "PSP: %s(): SMU_CC_PSP_FUSES_PROTO = 0 - FALSE...\n", + __func__); + return FALSE; + } + + // D8F0x48[12] Bar3Hide + if (pci_read_config32(SOC_PSP_DEV, PSP_PCI_EXTRAPCIHDR_REG) & BIT12) { + printk(BIOS_DEBUG, "PSP: %s(): D8F0x48[12]/Bar3Hidden...\n", + __func__); + *PspMmio = (u32)__readmsr(MSR_CU_CBBCFG)) == 0xFFFFFFFF; + if (*PspMmio) { + printk(BIOS_DEBUG, "PSP: %s(): Msr PspMmio = 0xFFFFFFFF - FALSE...\n", + __func__); + return FALSE; + } + printk(BIOS_DEBUG, "PSP: %s(): BAR3 = 0x%x ...\n", + __func__, *PspMmio); + } else { + *PspMmio = pci_read_config32(SOC_PSP_DEV, PSP_PCI_BAR3_REG) & + 0xFFF00000; + printk(BIOS_DEBUG, "PSP: %s(): Read BAR3 = 0x%x ...\n", + __func__, *PspMmio); + } + return TRUE; +} + + static const char *status_to_string(int err) { switch (err) { @@ -52,20 +174,25 @@
static struct psp_mbox *get_mbox_address(void) { - UINT32 base; /* UINT32 for compatibility with PspBaseLib */ - BOOLEAN bar3_status; + u32 base; /* u32 for compatibility with PspBaseLib */ uintptr_t baseptr;
- bar3_status = GetPspBar3Addr(&base); - if (!bar3_status) { - PspBarInitEarly(); - bar3_status = GetPspBar3Addr(&base); + if (!get_psp_bar3_addr(&base)) { + printk(BIOS_DEBUG, + "PSP: %s(), get_psp_bar3_addr() returned FALSE, base=0x%x...\n", + __func__, base); + psp_bar_init_early(); + if (!get_psp_bar3_addr(&base)) { + printk(BIOS_DEBUG, + "PSP: %s(), get_psp_bar3_addr returned FALSE, base=0x%x...\n", + __func__, base); + return NULL; + } } - if (!bar3_status) - return NULL; - - baseptr = base; - return (struct psp_mbox *)(baseptr + PSP_MAILBOX_BASE); + baseptr = (uintptr_t)base + PSP_MAILBOX_BASE; + printk(BIOS_DEBUG, "PSP: %s() = 0x%p...\n", + __func__, (struct psp_mbox *)baseptr); + return ((struct psp_mbox *)baseptr); }
static u32 rd_mbox_sts(struct psp_mbox *mbox) @@ -157,7 +284,7 @@ }
/* - * Notify the PSP that DRAM is present. Upon receiving this command, the PSP + * Notify the PSP that DRAM is present. Upon receiving this command, the PSP * will load its OS into fenced DRAM that is not accessible to the x86 cores. */ int psp_notify_dram(void) diff --git a/src/soc/amd/common/block/psp/psp.h b/src/soc/amd/common/block/psp/psp.h new file mode 100644 index 0000000..dd6159b --- /dev/null +++ b/src/soc/amd/common/block/psp/psp.h @@ -0,0 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// Registers in the PSP PCI Config Space + +#define PSP_PCI_DEVID_REG 0x00 ///< Standard Pci Device ID +#define PSP_PCI_CMD_REG 0x04 ///< CmdReg +#define PSP_PCI_BAR3_REG 0x20 ///< Pci Bar3 +#define PSP_PCI_MIRRORCTRL1_REG 0x44 ///< PSP Mirror Reg Ctrl +#define PSP_PCI_EXTRAPCIHDR_REG 0x48 ///< Extra PCI Header Ctr +#define PCI_CONFIG_SMU_INDIRECT_INDEX 0xB8 ///< Gnb index for SMU mbox +#define PCI_CONFIG_SMU_INDIRECT_DATA 0xBC ///< Gnb data for SMU mbox + +// GNB related offsets and bit specifications + +#define SMU_CC_PSP_FUSES_STATUS 0xC0018000ul ///< GNB offset to find PSP fusing +#define SMU_CC_PSP_FUSES_PROTO BIT2 ///< BIT2 + +// PSP Mailbox definitions +#define PSP_MAILBOX_BASE 0x70 ///< Mailbox offset from PCIe BAR + +#define MSR_CU_CBBCFG 0xC00110A2ul ///< PSP Private Blk Base Addr +