aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c')
-rw-r--r--src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c464
1 files changed, 464 insertions, 0 deletions
diff --git a/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
new file mode 100644
index 0000000000..20a359ad0e
--- /dev/null
+++ b/src/vendorcode/amd/pi/00670F00/Proc/Psp/PspBaseLib/PspBaseLib.c
@@ -0,0 +1,464 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * PSP Base Library
+ *
+ * Contains interface to the PSP library
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: PSP
+ * @e \$Revision: 309090 $ @e \$Date: 2014-12-09 12:28:05 -0600 (Tue, 09 Dec 2014) $
+ *
+ */
+ /*****************************************************************************
+ *
+ * Copyright (c) 2008 - 2015, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************************/
+
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "Filecode.h"
+#include "PspBaseLib.h"
+
+#define FILECODE PROC_PSP_PSPBASELIB_PSPBASELIB_FILECODE
+#define PSP_BAR1_TMP_BASE 0xFEA00000ul
+
+#define GET_PCI_BUS(Reg) (((UINT32) Reg >> 16) & 0xFF)
+#define GET_PCI_DEV(Reg) (((UINT32) Reg >> 11) & 0x1F)
+#define GET_PCI_FUNC(Reg) (((UINT32) Reg >> 8) & 0x7)
+#define GET_PCI_OFFSET(Reg) ((UINT32)Reg & 0xFF)
+
+#define PCI_CONFIG_SMU_INDIRECT_INDEX 0xB8 ///< Gnb Offset index for SMU mbox
+#define PCI_CONFIG_SMU_INDIRECT_DATA 0xBC ///< Gnb Offset data for SMU mbox
+
+#define SMU_CC_PSP_FUSES_STATUS 0xC0018000ul ///< offset in GNB to find PSP fusing
+#define SMU_CC_PSP_FUSES_SECURE BIT0 ///< BIT0
+#define SMU_CC_PSP_FUSES_FRA_ENABLE BIT1 ///< BIT1
+#define SMU_CC_PSP_FUSES_PROTO BIT2 ///< BIT2
+#define PLATFORM_SECURE_BOOT_EN BIT4 ///< BIT4
+
+
+#define PSP_BLANK_PART 0 ///< Blank part
+#define PSP_PROTO_PART SMU_CC_PSP_FUSES_PROTO ///< Proto Part
+#define PSP_NON_SECURE_PART (SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_PCPU_DIS) ///< Non Secure Part
+#define PSP_SECURE_PART (SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_SECURE) ///< Secure Part
+#define PSP_FRA_MODE (SMU_CC_PSP_FUSES_FRA_ENABLE + SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_SECURE) ///< FRA Part
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+UINT32
+PspLibPciReadConfig (
+ IN UINT32 Register
+ )
+{
+ UINT32 Value;
+ PCI_ADDR PciAddr;
+
+ Value = 0;
+ PciAddr.AddressValue = MAKE_SBDFO (0, GET_PCI_BUS (Register), GET_PCI_DEV (Register), GET_PCI_FUNC (Register), GET_PCI_OFFSET (Register));
+
+ LibAmdPciRead (AccessWidth32, PciAddr, &Value, NULL);
+
+ return Value;
+}
+
+VOID
+PspLibPciWriteConfig (
+ IN UINT32 Register,
+ IN UINT32 Value
+ )
+{
+ PCI_ADDR PciAddr;
+ PciAddr.AddressValue = MAKE_SBDFO (0, GET_PCI_BUS (Register), GET_PCI_DEV (Register), GET_PCI_FUNC (Register), GET_PCI_OFFSET (Register));
+
+ LibAmdPciWrite (AccessWidth32, PciAddr, &Value, NULL);
+
+}
+
+UINT32
+PspLibPciReadPspConfig (
+ IN UINT16 Offset
+ )
+{
+ return (PspLibPciReadConfig ((UINT32) (PSP_PCI_BDA + Offset)));
+}
+
+VOID
+PspLibPciWritePspConfig (
+ IN UINT16 Offset,
+ IN UINT32 Value
+ )
+{
+ PspLibPciWriteConfig ((UINT32) (PSP_PCI_BDA + Offset), Value);
+}
+
+BOOLEAN
+GetPspDirBase (
+ IN OUT UINT32 *Address
+ )
+{
+ UINTN i;
+ FIRMWARE_ENTRY_TABLE *FirmwareTableBase;
+ CONST UINT32 RomSigAddrTable[] =
+ {
+ 0xFFFA0000, // --> 512KB base
+ 0xFFF20000, // --> 1MB base
+ 0xFFE20000, // --> 2MB base
+ 0xFFC20000, // --> 4MB base
+ 0xFF820000, // --> 8MB base
+ 0xFF020000 // --> 16MB base
+ };
+
+ for (i = 0; i < sizeof (RomSigAddrTable) / sizeof (UINT32); i++) {
+ FirmwareTableBase = (FIRMWARE_ENTRY_TABLE *) (UINTN) RomSigAddrTable[i];
+ // Search flash for unique signature 0x55AA55AA
+ if (FirmwareTableBase->Signature == FIRMWARE_TABLE_SIGNATURE) {
+ *Address = FirmwareTableBase->PspDirBase;
+ return TRUE;
+ }
+ }
+
+ return (FALSE);
+}
+
+BOOLEAN
+PSPEntryInfo (
+ IN PSP_DIRECTORY_ENTRY_TYPE EntryType,
+ IN OUT UINT64 *EntryAddress,
+ IN UINT32 *EntrySize
+ )
+{
+ PSP_DIRECTORY *PspDir;
+ UINTN i;
+
+ if (GetPspDirBase ((UINT32 *)&PspDir ) != TRUE) {
+ return FALSE;
+ }
+
+ for (i = 0; i < PspDir->Header.TotalEntries; i++) {
+ if (PspDir->PspEntry[i].Type == EntryType) {
+ *EntryAddress = PspDir->PspEntry[i].Location;
+ *EntrySize = PspDir->PspEntry[i].Size;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+/**
+ Check if PSP device is present
+
+ @retval BOOLEAN 0: PSP Disabled, 1: PSP Enabled
+
+**/
+BOOLEAN
+CheckPspDevicePresent (
+ VOID
+ )
+{
+ UINT32 SecureFuseReg;
+ PspLibPciWriteConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_INDEX, (UINT32)SMU_CC_PSP_FUSES_STATUS);
+ SecureFuseReg = PspLibPciReadConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_DATA);
+
+ if (SecureFuseReg &= SMU_CC_PSP_FUSES_PROTO) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/**
+ Check PSP Platform Seucre Enable State
+ HVB & Secure S3 (Resume vector set to Dram, & core content will restore by uCode)
+ will be applied if Psp Plaform Secure is enabled
+
+ @retval BOOLEAN 0: PSP Platform Secure Disabled, 1: PSP Platform Secure Enabled
+
+**/
+BOOLEAN
+CheckPspPlatformSecureEnable (
+ VOID
+ )
+{
+ UINT32 SecureFuseReg;
+ PspLibPciWriteConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_INDEX, (UINT32)SMU_CC_PSP_FUSES_STATUS);
+ SecureFuseReg = PspLibPciReadConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_DATA);
+
+ if (SecureFuseReg &= PLATFORM_SECURE_BOOT_EN) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/**
+ Check PSP Recovery Flag
+ Target will set Recovery flag if some PSP entry point by PSP directory has been corrupted.
+
+ @retval BOOLEAN 0: Recovery Flag is cleared, 1: Recovery Flag has been set
+
+**/
+BOOLEAN
+CheckPspRecoveryFlag (
+ VOID
+ )
+{
+ MBOX_STATUS *MboxStatus;
+
+ //Init PSP MMIO
+ PspBarInitEarly ();
+
+ GetPspMboxStatus (&MboxStatus);
+
+ return (BOOLEAN) (MboxStatus->Recovery);
+}
+
+/**
+ Return the PspMbox MMIO location
+
+
+ @retval BOOLEAN FALSE: ERROR, TRUE: SUCCEED
+
+**/
+BOOLEAN
+GetPspMboxStatus (
+ IN OUT MBOX_STATUS **MboxStatus
+ )
+{
+ UINT32 PspMmio;
+
+ if (GetPspBar1Addr (&PspMmio) == FALSE) {
+ return (FALSE);
+ }
+
+ *MboxStatus = (MBOX_STATUS *)( (UINTN)PspMmio + PSP_MAILBOX_BASE + PSP_MAILBOX_STATUS_OFFSET); // PSPMbox base is at offset CP2MSG_28 ie. offset 28*4 = 0x70
+
+ return (TRUE);
+}
+
+BOOLEAN
+PspBarInitEarly (void)
+{
+ UINT32 PspMmioSize;
+ UINT32 Value32;
+
+ if (PspLibPciReadPspConfig (PSP_PCI_DEVID_REG) == 0xffffffff) {
+ return (FALSE);
+ }
+
+ //Check if PSP BAR has been assigned, if not do the PSP BAR initialation
+ if (PspLibPciReadPspConfig (PSP_PCI_BAR1_REG) == 0) {
+ /// Get PSP BAR1 Size
+ PspLibPciWritePspConfig (PSP_PCI_BAR1_REG, 0xFFFFFFFF);
+ PspMmioSize = PspLibPciReadPspConfig (PSP_PCI_BAR1_REG);
+ PspMmioSize = ~PspMmioSize + 1;
+ /// Assign BAR1 Temporary Address
+ PspLibPciWritePspConfig (PSP_PCI_BAR1_REG, PSP_BAR1_TMP_BASE);
+ PspLibPciWritePspConfig ( PSP_PCI_CMD_REG, 0x06);
+
+ /// Enable GNB redirection to this space @todo use equate & also find proper fix
+ PspLibPciWriteConfig ( ( (0x18 << 11) + (1 << 8) + 0xBC), ((PSP_BAR1_TMP_BASE + PspMmioSize -1) >> 8) & ~0xFF);
+ PspLibPciWriteConfig ( ( (0x18 << 11) + (1 << 8) + 0xB8), (PSP_BAR1_TMP_BASE >> 8) | 3);
+ /// Enable MsixBarEn, Bar1En, Bar3En
+ PspLibPciWritePspConfig ( PSP_PCI_EXTRAPCIHDR_REG, 0x34);
+ /// Capability chain update
+ Value32 = PspLibPciReadPspConfig (PSP_PCI_MIRRORCTRL1_REG);
+ Value32 &= ~D8F0x44_PmNxtPtrW_MASK;
+ Value32 |= 0xA4;
+ PspLibPciWritePspConfig (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
+**/
+BOOLEAN
+GetPspBar1Addr (
+ IN OUT UINT32 *PspMmio
+ )
+{
+ if (CheckPspDevicePresent () == FALSE) {
+ return (FALSE);
+ }
+
+ *PspMmio = PspLibPciReadPspConfig (PSP_PCI_BAR1_REG);
+
+ if ((*PspMmio) == 0xffffffff) {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/**
+ Return the PspMMIO MMIO location
+
+ @param[in] PspMmio Pointer to Psp MMIO address
+
+ @retval BOOLEAN 0: Error, 1 Success
+**/
+BOOLEAN
+GetPspBar3Addr (
+ IN OUT UINT32 *PspMmio
+ )
+{
+ if (CheckPspDevicePresent () == FALSE) {
+ return (FALSE);
+ }
+
+ *PspMmio = PspLibPciReadPspConfig (PSP_PCI_BAR3_REG);
+
+ if ((*PspMmio) == 0xffffffff) {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Returns the access width mask for the processor
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @retval Width in number of bytes
+ */
+
+
+UINT8
+PspLibAccessWidth (
+ IN ACCESS_WIDTH AccessWidth
+ )
+{
+ UINT8 Width;
+
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ Width = 1;
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ Width = 2;
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ Width = 4;
+ break;
+ case AccessWidth64:
+ case AccessS3SaveWidth64:
+ Width = 8;
+ break;
+ default:
+ Width = 0;
+ }
+ return Width;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read GNB indirect registers
+ *
+ *
+ *
+ * @param[in] Address PCI address of indirect register
+ * @param[in] IndirectAddress Offset of indirect register
+ * @param[in] Width Width
+ * @param[out] Value Pointer to value
+ */
+VOID
+PspLibPciIndirectRead (
+ IN PCI_ADDR Address,
+ IN UINT32 IndirectAddress,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value
+ )
+{
+ UINT32 IndexOffset;
+
+ IndexOffset = PspLibAccessWidth (Width);
+ LibAmdPciWrite (Width, Address, &IndirectAddress, NULL);
+ Address.AddressValue += IndexOffset;
+ LibAmdPciRead (Width, Address, Value, NULL);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write GNB indirect registers
+ *
+ *
+ *
+ * @param[in] Address PCI address of indirect register
+ * @param[in] IndirectAddress Offset of indirect register
+ * @param[in] Width Width
+ * @param[in] Value Pointer to value
+ */
+VOID
+PspLibPciIndirectWrite (
+ IN PCI_ADDR Address,
+ IN UINT32 IndirectAddress,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value
+ )
+{
+ UINT32 IndexOffset;
+
+ IndexOffset = PspLibAccessWidth (Width);
+ LibAmdPciWrite (Width, Address, &IndirectAddress, NULL);
+ Address.AddressValue += IndexOffset;
+ LibAmdPciWrite (Width, Address, Value, NULL);
+}
+
+