/** @file
Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*----------------------------------------------------------------------------------------
* G L O B A L S
*----------------------------------------------------------------------------------------
*/
//
// CoreInfo table
//
STATIC ARM_CORE_INFO mAmdMpCoreInfoTable[] = {
{
// Cluster 0, Core 0
0x0, 0x0,
},
{
// Cluster 0, Core 1
0x0, 0x1,
},
{
// Cluster 1, Core 0
0x1, 0x0,
},
{
// Cluster 1, Core 1
0x1, 0x1,
},
{
// Cluster 2, Core 0
0x2, 0x0,
},
{
// Cluster 2, Core 1
0x2, 0x1,
},
{
// Cluster 3, Core 0
0x3, 0x0,
},
{
// Cluster 3, Core 1
0x3, 0x1,
}
};
//
// Core count
//
STATIC UINTN mAmdCoreCount = sizeof (mAmdMpCoreInfoTable) / sizeof (ARM_CORE_INFO);
/*----------------------------------------------------------------------------------------
* P P I L I S T
*----------------------------------------------------------------------------------------
*/
STATIC EFI_PEI_ISCP_PPI *PeiIscpPpi;
/*----------------------------------------------------------------------------------------
* P P I D E S C R I P T O R
*----------------------------------------------------------------------------------------
*/
STATIC EFI_PEI_PPI_DESCRIPTOR mPlatInitPpiDescriptor =
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gAmdStyxPlatInitPpiGuid,
NULL
};
/**
*---------------------------------------------------------------------------------------
* PlatInitPeiEntryPoint
*
* Description:
* Entry point of the PlatInit PEI module.
*
* Control flow:
* Query platform parameters via ISCP.
*
* Parameters:
* @param[in] FfsHeader EFI_PEI_FILE_HANDLE
* @param[in] **PeiServices Pointer to the PEI Services Table.
*
* @return EFI_STATUS
*
*---------------------------------------------------------------------------------------
*/
EFI_STATUS
EFIAPI
PlatInitPeiEntryPoint (
IN EFI_PEI_FILE_HANDLE FfsHeader,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
AMD_MEMORY_RANGE_DESCRIPTOR IscpMemDescriptor = {0};
ISCP_FUSE_INFO IscpFuseInfo = {0};
ISCP_CPU_RESET_INFO CpuResetInfo = {0};
ISCP_MAC_INFO MacAddrInfo = {0};
UINTN MacSize;
UINTN CpuCoreCount, CpuMap, CpuMapSize;
UINTN Index, CoreNum;
UINT32 *CpuIdReg = (UINT32 *)FixedPcdGet32 (PcdCpuIdRegister);
DEBUG ((EFI_D_ERROR, "PlatInit PEIM Loaded\n"));
// CPUID
Status = PcdSet32S (PcdSocCpuId, *CpuIdReg);
ASSERT_EFI_ERROR (Status);
DEBUG ((EFI_D_ERROR, "SocCpuId = 0x%X\n", PcdGet32 (PcdSocCpuId)));
// Update core count based on PCD option
if (mAmdCoreCount > PcdGet32 (PcdSocCoreCount)) {
mAmdCoreCount = PcdGet32 (PcdSocCoreCount);
}
Status = PeiServicesLocatePpi (&gPeiIscpPpiGuid, 0, NULL, (VOID**)&PeiIscpPpi);
ASSERT_EFI_ERROR (Status);
// Get fuse information from ISCP
Status = PeiIscpPpi->ExecuteFuseTransaction (PeiServices, &IscpFuseInfo);
ASSERT_EFI_ERROR (Status);
CpuMap = IscpFuseInfo.SocConfiguration.CpuMap;
CpuCoreCount = IscpFuseInfo.SocConfiguration.CpuCoreCount;
CpuMapSize = sizeof (IscpFuseInfo.SocConfiguration.CpuMap) * 8;
ASSERT (CpuMap != 0);
ASSERT (CpuCoreCount != 0);
ASSERT (CpuCoreCount <= CpuMapSize);
// Update core count based on fusing
if (mAmdCoreCount > CpuCoreCount) {
mAmdCoreCount = CpuCoreCount;
}
//
// Update per-core information from ISCP
// Walk CPU map to enumerate active cores
//
for (CoreNum = 0, Index = 0; CoreNum < CpuMapSize && Index < mAmdCoreCount; ++CoreNum) {
if (CpuMap & 1) {
CpuResetInfo.CoreNum = CoreNum;
Status = PeiIscpPpi->ExecuteCpuRetrieveIdTransaction (
PeiServices, &CpuResetInfo );
ASSERT_EFI_ERROR (Status);
ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_DISABLED);
ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_UNDEFINED);
mAmdMpCoreInfoTable[Index].ClusterId = CpuResetInfo.CoreStatus.ClusterId;
mAmdMpCoreInfoTable[Index].CoreId = CpuResetInfo.CoreStatus.CoreId;
DEBUG ((EFI_D_ERROR, "Core[%d]: ClusterId = %d CoreId = %d\n",
Index, mAmdMpCoreInfoTable[Index].ClusterId,
mAmdMpCoreInfoTable[Index].CoreId));
// Next core in Table
++Index;
}
// Next core in Map
CpuMap >>= 1;
}
// Update core count based on CPU map
if (mAmdCoreCount > Index) {
mAmdCoreCount = Index;
}
// Update SocCoreCount on Dynamic PCD
if (PcdGet32 (PcdSocCoreCount) != mAmdCoreCount) {
Status = PcdSet32S (PcdSocCoreCount, mAmdCoreCount);
ASSERT_EFI_ERROR (Status);
}
DEBUG ((EFI_D_ERROR, "SocCoreCount = %d\n", PcdGet32 (PcdSocCoreCount)));
// Build AmdMpCoreInfo HOB
BuildGuidDataHob (&gAmdStyxMpCoreInfoGuid, mAmdMpCoreInfoTable, sizeof (ARM_CORE_INFO) * mAmdCoreCount);
// Get SystemMemorySize from ISCP
IscpMemDescriptor.Size0 = 0;
Status = PeiIscpPpi->ExecuteMemoryTransaction (PeiServices, &IscpMemDescriptor);
ASSERT_EFI_ERROR (Status);
// Update SystemMemorySize on Dynamic PCD
if (IscpMemDescriptor.Size0) {
Status = PcdSet64S (PcdSystemMemorySize, IscpMemDescriptor.Size0);
ASSERT_EFI_ERROR (Status);
}
if (IscpMemDescriptor.Size0 == 0) {
DEBUG ((EFI_D_ERROR, "Warning: Could not get SystemMemorySize via ISCP, using default value.\n"));
}
DEBUG ((EFI_D_ERROR, "SystemMemorySize = %ld\n", PcdGet64 (PcdSystemMemorySize)));
if (FixedPcdGetBool (PcdXgbeEnable)) {
// Get MAC Address from ISCP
Status = PeiIscpPpi->ExecuteGetMacAddressTransaction (
PeiServices, &MacAddrInfo );
ASSERT_EFI_ERROR (Status);
// Check for bogus MAC addresses that have the multicast bit set. This
// includes FF:FF:FF:FF:FF:FF, which is what you get from the SCP on
// some versions of the B0 Overdrive
MacSize = sizeof(MacAddrInfo.MacAddress0);
if ((MacAddrInfo.MacAddress0[0] & 0x1) == 0x0) {
Status = PcdSetPtrS (PcdEthMacA, &MacSize, MacAddrInfo.MacAddress0);
ASSERT_EFI_ERROR (Status);
}
if ((MacAddrInfo.MacAddress1[0] & 0x1) == 0x0) {
Status = PcdSetPtrS (PcdEthMacB, &MacSize, MacAddrInfo.MacAddress1);
ASSERT_EFI_ERROR (Status);
}
DEBUG ((EFI_D_ERROR, "EthMacA = %02x:%02x:%02x:%02x:%02x:%02x\n",
((UINT8 *)PcdGetPtr (PcdEthMacA))[0], ((UINT8 *)PcdGetPtr (PcdEthMacA))[1],
((UINT8 *)PcdGetPtr (PcdEthMacA))[2], ((UINT8 *)PcdGetPtr (PcdEthMacA))[3],
((UINT8 *)PcdGetPtr (PcdEthMacA))[4], ((UINT8 *)PcdGetPtr (PcdEthMacA))[5]));
DEBUG ((EFI_D_ERROR, "EthMacB = %02x:%02x:%02x:%02x:%02x:%02x\n",
((UINT8 *)PcdGetPtr (PcdEthMacB))[0], ((UINT8 *)PcdGetPtr (PcdEthMacB))[1],
((UINT8 *)PcdGetPtr (PcdEthMacB))[2], ((UINT8 *)PcdGetPtr (PcdEthMacB))[3],
((UINT8 *)PcdGetPtr (PcdEthMacB))[4], ((UINT8 *)PcdGetPtr (PcdEthMacB))[5]));
}
// Let other PEI modules know we're done!
Status = (*PeiServices)->InstallPpi (PeiServices, &mPlatInitPpiDescriptor);
ASSERT_EFI_ERROR (Status);
return Status;
}