/** @file
Copyright (c) 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include "CpuPciAccess.h"
#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD)
#include
#endif
#ifndef IA32
#include "Library/IoLib.h"
#include
#include
static EFI_IIO_UDS_PROTOCOL *mIioUds;
IIO_UDS *mIioUdsDataPtr;
CPU_CSR_ACCESS_VAR *PCpuCsrAccessVarGlobal = NULL;
#endif
#ifndef IA32
CPU_CSR_ACCESS_VAR CpuCsrAccessVarGlobal;
#endif
//
// Disable warning for unsued input parameters
//
#ifdef _MSC_VER
#pragma warning(disable : 4100)
#pragma warning(disable : 4013)
#pragma warning(disable : 4306)
#endif
//
// PCI function translation table; note that this table doesn't capture the function
// information for all instances of a box. It only captures for the first instance.
// It has to be translated for other instances after the look up is done.
//
STATIC UINT8 FunTbl[MAX_CPU_TYPES][MAX_BOX_TYPES][8] = {
{
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // CHA MISC 0
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // CHA PMA 1
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // CHA CMS 2
{0, 1, 2, 3, 0xFF, 0xFF, 0xFF, 0xFF}, // CHABC 3
{0, 1, 2, 3, 4, 5, 6, 7 }, // PCU 4
{0, 1, 2, 3, 4, 5, 6, 7 }, // VCU 5
{0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // M2MEM 6
{0, 4, 0, 0, 4, 0, 0xFF, 0xFF}, // MC 7 //SKX:Should be {0, 1, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
{0, 2, 4, 0, 2, 4, 0xFF, 0xFF}, // MCIO DDRIO 8 //SKX:should be {0, 1, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF}
{0, 1, 2, 3, 0xFF, 0xFF, 0xFF, 0xFF}, // KTI 9
{0, 1, 2, 3, 0xFF, 0xFF, 0xFF, 0xFF}, // M3KTI 10
{2, 6, 2, 2, 6, 2, 0xFF, 0xFF}, // MCDDC 11 //SKX:SHould be {2, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // MCDDC These entries all seem wrong but work
{0, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // M2UPCIE 12
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // IIO DMI 13
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // IIO PCIE 14
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // IIO PCIENTB 15
{0, 1, 2, 3, 4, 5, 6, 7 }, // IIOCB 16
{0, 1, 2, 4, 5, 6, 0xFF, 0xFF}, // IIO VTD 17
{0, 0, 7, 7, 4, 4, 0xFF, 0xFF}, // IIO_RTO 18
{0, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // UBOX 19
}, // SKX
};
STATIC UINT8 m2pcieDevTable[MAX_SKX_M2PCIE] = { 22, 21, 22, 23, 21};
/**
Populate CpuCsrAccessVar structure.
@param host - pointer to the system host root structure
@param CpuCsrAccessVar - pointer to CpuCsrAccessVar structure to be populated
@retval None
**/
VOID
GetCpuCsrAccessVar_RC (
PSYSHOST host,
CPU_CSR_ACCESS_VAR *CpuCsrAccessVar
)
{
#ifndef IA32
EFI_STATUS Status;
#endif
if (host != NULL) {
CpuDeadLoop ();
}
#ifndef IA32
if (host == NULL) {
if(PCpuCsrAccessVarGlobal == NULL){ //check if 1st time, if yes, then need to update
// Locate the IIO Protocol Interface
Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, &mIioUds);
mIioUdsDataPtr = (IIO_UDS *)mIioUds->IioUdsPtr;
//ASSERT_EFI_ERROR (Status);
PCpuCsrAccessVarGlobal = &CpuCsrAccessVarGlobal;
for (socket = 0; socket < MAX_SOCKET; socket++) {
CpuCsrAccessVarGlobal.stackPresentBitmap[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].stackPresentBitmap;
CpuCsrAccessVarGlobal.SocketFirstBus[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].SocketFirstBus;
CpuCsrAccessVarGlobal.SocketLastBus[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].SocketLastBus;
CpuCsrAccessVarGlobal.segmentSocket[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].segmentSocket;
for (ctr = 0; ctr < MAX_IIO_STACK; ctr++) {
CpuCsrAccessVarGlobal.StackBus[socket][ctr] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].StackBus[ctr];
}
}
CpuCsrAccessVarGlobal.cpuType = mIioUdsDataPtr->SystemStatus.cpuType;
CpuCsrAccessVarGlobal.stepping = mIioUdsDataPtr->SystemStatus.MinimumCpuStepping;
CpuCsrAccessVarGlobal.socketPresentBitMap = mIioUdsDataPtr->SystemStatus.socketPresentBitMap;
CpuCsrAccessVarGlobal.FpgaPresentBitMap = mIioUdsDataPtr->SystemStatus.FpgaPresentBitMap;
CpuCsrAccessVarGlobal.mmCfgBase = (UINT32)mIioUdsDataPtr->PlatformData.PciExpressBase;
CpuCsrAccessVarGlobal.numChPerMC = mIioUdsDataPtr->SystemStatus.numChPerMC;
CpuCsrAccessVarGlobal.maxCh = mIioUdsDataPtr->SystemStatus.maxCh;
CpuCsrAccessVarGlobal.maxIMC = mIioUdsDataPtr->SystemStatus.maxIMC;
}
if ((PCpuCsrAccessVarGlobal != NULL) && (CpuCsrAccessVarGlobal.socketPresentBitMap != mIioUdsDataPtr->SystemStatus.socketPresentBitMap)) {
for (socket = 0; socket < MAX_SOCKET; socket++) {
CpuCsrAccessVarGlobal.stackPresentBitmap[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].stackPresentBitmap;
CpuCsrAccessVarGlobal.SocketFirstBus[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].SocketFirstBus;
CpuCsrAccessVarGlobal.SocketLastBus[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].SocketLastBus;
CpuCsrAccessVarGlobal.segmentSocket[socket] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].segmentSocket;
for (ctr = 0; ctr < MAX_IIO_STACK; ctr++) {
CpuCsrAccessVarGlobal.StackBus[socket][ctr] = mIioUdsDataPtr->PlatformData.CpuQpiInfo[socket].StackBus[ctr];
}
}
CpuCsrAccessVarGlobal.cpuType = mIioUdsDataPtr->SystemStatus.cpuType;
CpuCsrAccessVarGlobal.stepping = mIioUdsDataPtr->SystemStatus.MinimumCpuStepping;
CpuCsrAccessVarGlobal.socketPresentBitMap = mIioUdsDataPtr->SystemStatus.socketPresentBitMap;
CpuCsrAccessVarGlobal.FpgaPresentBitMap = mIioUdsDataPtr->SystemStatus.FpgaPresentBitMap;
CpuCsrAccessVarGlobal.mmCfgBase = (UINT32)mIioUdsDataPtr->PlatformData.PciExpressBase;
CpuCsrAccessVarGlobal.numChPerMC = mIioUdsDataPtr->SystemStatus.numChPerMC;
CpuCsrAccessVarGlobal.maxCh = mIioUdsDataPtr->SystemStatus.maxCh;
CpuCsrAccessVarGlobal.maxIMC = mIioUdsDataPtr->SystemStatus.maxIMC;
}
for (socket = 0; socket < MAX_SOCKET; socket++) {
CpuCsrAccessVar->stackPresentBitmap[socket] = CpuCsrAccessVarGlobal.stackPresentBitmap[socket];
CopyMem (&CpuCsrAccessVar->StackBus[socket], &CpuCsrAccessVarGlobal.StackBus[socket], MAX_IIO_STACK);
}
CpuCsrAccessVar->cpuType = CpuCsrAccessVarGlobal.cpuType;
//CpuCsrAccessVar->stepping = CpuCsrAccessVarGlobal.stepping;
CpuCsrAccessVar->socketPresentBitMap = CpuCsrAccessVarGlobal.socketPresentBitMap;
CpuCsrAccessVar->FpgaPresentBitMap = CpuCsrAccessVarGlobal.FpgaPresentBitMap;
//CpuCsrAccessVar->mmCfgBase = CpuCsrAccessVarGlobal.mmCfgBase;
CpuCsrAccessVar->numChPerMC = CpuCsrAccessVarGlobal.numChPerMC;
CpuCsrAccessVar->maxCh = CpuCsrAccessVarGlobal.maxCh;
//CpuCsrAccessVar->maxIMC = CpuCsrAccessVarGlobal.maxIMC;
}
#endif
}
/**
Stall execution after internal assertion fails
@param haltOnError - 1 stalls in infinite loop; 0 returns to caller
@retval None
**/
VOID RcDeadLoop (
UINT8 haltOnError
)
{
//
// Prevent from optimizing out
//
while (*(volatile UINT8 *) &haltOnError);
}
/**
CsrAccess specific print to serial output
@param host - Pointer to the system host (root) structure
@param Format - string format
@retval N/A
**/
VOID
CpuCsrAccessError (
PSYSHOST host,
char* Format,
...
)
{
UINT8 haltOnError;
#ifdef SERIAL_DBG_MSG
#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD)
UINT32 *pData32;
#endif
va_list Marker;
va_start (Marker, Format);
#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD)
if (host != NULL) {
pData32 = (UINT32 *)Marker;
if( (*pData32 & 0xFFFFFF00) == 0xFFFFFF00){ // check if input is one byte only
*pData32 = *pData32 & 0x000000FF;
} if( (*pData32 & 0xFFFF0000) == 0xFFFF0000){ // check if input is word only
*pData32 = *pData32 & 0x0000FFFF;
}
DEBUG ((
DEBUG_ERROR, Format, *pData32
));
}
#else
if (host != NULL) {
rcVprintf (host, Format, Marker);
}
#endif
va_end (Marker);
#endif
haltOnError = 1;
RcDeadLoop (haltOnError);
return;
}
/**
Returns the CPU Index for MC func tbl lookup based on CPU type and CPU sub type.
This index will be used for MC box instance -> function mapping look-up
@param host - Pointer to the system host (root) structure
@retval Index for CPU type
**/
STATIC
UINT8
GetCpuIndex (
PSYSHOST host
)
{
UINT8 cpuIndex = 0xFF;
cpuIndex = 0;
return cpuIndex;
}
/**
Indetifies the bus number for given SocId & BoxType
@param host - Pointer to the system host (root) structure
@param SocId - CPU Socket Node number (Socket ID)
@param BoxType - Box Type; values come from CpuPciAccess.h
@retval PCI bus number
**/
UINT32
GetBusNumber (
PSYSHOST host,
UINT8 SocId,
UINT8 BoxType,
UINT8 BoxInst,
UINT8 FuncBlk,
CPU_CSR_ACCESS_VAR *CpuCsrAccessVar
)
{
UINT32 Bus = 0;
UINT8 TempStack = 0;
// Make sure SocId or Fpga is valid
if ((!((CpuCsrAccessVar->socketPresentBitMap & (1 << SocId)) && (BoxType != BOX_FPGA)))) {
if ((!((CpuCsrAccessVar->FpgaPresentBitMap & (1 << SocId)) && (BoxType == BOX_FPGA)))) {
CpuCsrAccessError (host, "\nInvalid Socket Id %d. \n", SocId);
}
}
//
// Each socket is assigned multiple buses
// Check the box type and return the appropriate bus number.
//
if ((BoxType == BOX_MC) ||
(BoxType == BOX_MCDDC) ||
(BoxType == BOX_MCIO) ||
(BoxType == BOX_M2MEM)) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_PSTACK1];
} else if (BoxType == BOX_UBOX) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else if ((BoxType == BOX_IIO_PCIE_DMI) ||
(BoxType == BOX_IIO_CB)) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else if (BoxType == BOX_IIO_PCIE) {
//
// IIO_PCIE is used to access all pcie ports in all stacks
//
if (BoxInst == 0) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else {
TempStack = IIO_PSTACK0 + ((BoxInst-1) / 4);
if (TempStack < MAX_IIO_STACK) {
Bus = CpuCsrAccessVar->StackBus[SocId][TempStack];
} else {
CpuCsrAccessError (host, "\nInvalid IIO_PCIE BoxInstance %d. \n", BoxInst);
}
}
} else if (BoxType == BOX_IIO_VTD) {
TempStack = IIO_CSTACK + BoxInst;
if (TempStack < MAX_IIO_STACK) {
Bus = CpuCsrAccessVar->StackBus[SocId][TempStack];
} else {
CpuCsrAccessError (host, "\nInvalid BOX_IIO_VTD BoxInstance %d. \n", BoxInst);
}
} else if (BoxType == BOX_IIO_PCIE_NTB) {
if (BoxInst > 0) {
TempStack = IIO_PSTACK0 + ((BoxInst-1) / 4);
if (TempStack < MAX_IIO_STACK) {
Bus = CpuCsrAccessVar->StackBus[SocId][TempStack];
} else {
CpuCsrAccessError (host, "\nInvalid BOX_IIO_PCIE_NTB BoxInstance %d. \n", BoxInst);
}
} else {
CpuCsrAccessError (host, "\nInvalid BOX_IIO_PCIE_NTB BoxInstance %d. \n", BoxInst);
}
} else if (BoxType == BOX_IIO_RTO) {
if (FuncBlk == IIO_RTO) {
//
// IIO_RTO is used to access all pcie ports in all stacks same as iio_pcie
//
if (BoxInst == 0) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else {
TempStack = IIO_PSTACK0 + ((BoxInst-1) / 4);
if (TempStack < MAX_IIO_STACK) {
Bus = CpuCsrAccessVar->StackBus[SocId][TempStack];
} else {
CpuCsrAccessError (host, "\nInvalid IIO_PCIE BoxInstance %d. \n", BoxInst);
}
}
} else if ((FuncBlk == IIO_RTO_GLOBAL) || (FuncBlk == IIO_RTO_VTD)) {
//
// IIO_RTO_GLOBAL and IIO_RTO_VTD maps 1 instance per c/p/m stack
//
if ((IIO_CSTACK + BoxInst) < MAX_IIO_STACK) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK + BoxInst];
}
} else if ((FuncBlk == IIO_RTO_VTD_DMI) ||
(FuncBlk == IIO_RTO_DMI) ||
(FuncBlk == IIO_RTO_GLOBAL_DMI)) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else {
CpuCsrAccessError (host, "\nInvalid BoxType %d, Functional block %d. \n", BoxType, FuncBlk);
}
} else if ((BoxType == BOX_CHA_MISC) ||
(BoxType == BOX_CHA_PMA) ||
(BoxType == BOX_CHA_CMS) ||
(BoxType == BOX_CHABC) ||
(BoxType == BOX_PCU) ||
(BoxType == BOX_VCU)) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_PSTACK0];
} else if ((BoxType == BOX_M2UPCIE) ||
(BoxType == BOX_KTI) ||
(BoxType == BOX_M3KTI)) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_PSTACK2];
} else if (BoxType == BOX_FPGA) {
Bus = CpuCsrAccessVar->StackBus[SocId][IIO_CSTACK];
} else {
// Error
CpuCsrAccessError (host, "\nInvalid BoxType %d. \n", BoxType);
}
return Bus;
}
/**
Indetifies the device number for given Box Type & Box Instance
@param host - Pointer to the system host (root) structure
@param BoxType - Box Type; values come from CpuPciAccess.h
@param BoxInst - Box Instance, 0 based
@param FuncBlk - Functional Block; values come from CpuPciAccess.h
@retval PCI Device number
**/
UINT32
GetDeviceNumber (
PSYSHOST host,
UINT8 BoxType,
UINT8 BoxInst,
UINT8 FuncBlk,
CPU_CSR_ACCESS_VAR *CpuCsrAccessVar
)
{
UINT32 Dev = 0;
UINT8 CpuType, NumChPerMC;
CpuType = CpuCsrAccessVar->cpuType;
NumChPerMC = CpuCsrAccessVar->numChPerMC;
//
// Translate the Box Type & Instance into PCI Device number.
//
switch (BoxType) {
case BOX_MC:
case BOX_MCDDC:
if (CpuType == CPU_SKX) {
switch (BoxInst) {
case 0:
case 1:
Dev = 10;
break;
case 2:
Dev = 11;
break;
case 3:
case 4:
Dev = 12;
break;
case 5:
Dev = 13;
break;
}
} else {
CpuCsrAccessError (host, "\nInvalid Cpu type.\n");
}
break;
case BOX_MCIO:
if (CpuType == CPU_SKX) {
Dev = 22 + (BoxInst / NumChPerMC);
} else {
CpuCsrAccessError (host, "\nInvalid Cpu type.\n");
}
break;
case BOX_M2MEM:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_SKX_M2MEM)) {
Dev = 8 + BoxInst;
} else {
CpuCsrAccessError (host, "\nInvalid M2MEM Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_CHA_MISC:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_SKX_CHA)) {
if (BoxInst < 8) {
Dev = 8;
} else if (BoxInst < 16) {
Dev = 9;
} else if (BoxInst < 24) {
Dev = 10;
} else if (BoxInst < 28) {
Dev = 11;
}
} else {
CpuCsrAccessError (host, "\nInvalid CHA Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_CHA_PMA:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_SKX_CHA)) {
if (BoxInst < 8) {
Dev = 14;
} else if (BoxInst < 16) {
Dev = 15;
} else if (BoxInst < 24) {
Dev = 16;
} else if (BoxInst < 28) {
Dev = 17;
}
} else {
CpuCsrAccessError (host, "\nInvalid CHA Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_CHA_CMS:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_SKX_CHA)) {
if (BoxInst < 8) {
Dev = 20;
} else if (BoxInst < 16) {
Dev = 21;
} else if (BoxInst < 24) {
Dev = 22;
} else if (BoxInst < 28) {
Dev = 23;
}
} else {
CpuCsrAccessError (host, "\nInvalid CHA Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_CHABC:
if ((CpuType == CPU_SKX) && (BoxInst == 0)) {
Dev = 29;
} else {
CpuCsrAccessError (host, "\nInvalid CHABC Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_PCU:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_PCU)) {
Dev = 30;
} else {
CpuCsrAccessError (host, "\nInvalid PCU Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_VCU:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_VCU)) {
Dev = 31;
} else {
CpuCsrAccessError (host, "\nInvalid VCU Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_KTI:
/*
Dev # KTI(phy,logic)#
14 0 0
15 1 1
16 2 2
*/
if (CpuType == CPU_SKX) {
if (BoxInst < MAX_SKX_KTIAGENT ) {
Dev = 14 + BoxInst;
} else {
CpuCsrAccessError (host, "\nInvalid KTI Box Instance Number %d. \n", BoxInst);
}
} else {
CpuCsrAccessError (host, "\nInvalid Cpu type.\n");
}
break;
case BOX_M3KTI:
/*
Logical M3KTI # Dev # Fun #
KTI01 0 18 0
KTI23 1 18 4
*/
if (CpuType == CPU_SKX) {
if (BoxInst < 2 ) {
Dev = 18;
} else {
CpuCsrAccessError (host, "\nInvalid Box instance.\n");
}
} else {
CpuCsrAccessError (host, "\nInvalid Cpu type.\n");
}
break;
case BOX_M2UPCIE:
if (CpuType == CPU_SKX) {
if (BoxInst < MAX_SKX_M2PCIE) {
Dev = m2pcieDevTable[BoxInst];
} else {
CpuCsrAccessError (host, "\nInvalid KTI Box Instance Number %d. \n", BoxInst);
}
} else {
CpuCsrAccessError (host, "\nInvalid Cpu type.\n");
}
break;
case BOX_IIO_PCIE_DMI:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_IIO)) {
Dev = 0;
} else {
CpuCsrAccessError (host, "\nInvalid IIO PCIE DMI Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_IIO_PCIE:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_IIO_PCIE)) {
if (BoxInst == 0) {
// Cstack
Dev = 0;
} else {
// M/Pstacks
Dev = 0 + ((BoxInst-1) % 4);
}
} else {
CpuCsrAccessError (host, "\nInvalid IIO PCIE Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_IIO_PCIE_NTB:
if ((CpuType == CPU_SKX)) {
Dev = 0;
} else {
CpuCsrAccessError (host, "\nInvalid IIO PCIE Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_IIO_CB:
if ((CpuType == CPU_SKX)) {
Dev = 4;
} else {
CpuCsrAccessError (host, "\nInvalid IIO CB Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_IIO_VTD:
if ((CpuType == CPU_SKX)) {
Dev = 5;
} else {
CpuCsrAccessError (host, "\nInvalid IIO VTD Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_IIO_RTO:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_IIO_RTO)) {
Dev = 7;
} else {
CpuCsrAccessError (host, "\nInvalid IIO RTO Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_UBOX:
if ((CpuType == CPU_SKX) && (BoxInst < MAX_ALL_UBOX)) {
Dev = 8;
} else {
CpuCsrAccessError (host, "\nInvalid Ubox Instance Number %d. \n", BoxInst);
//Note: the fatal error function writes to UBOX CSR and recurses forever (until stack is gone).
}
break;
case BOX_FPGA:
if ((CpuType == CPU_SKX) && (BoxInst == 0)) {
Dev = 16;
} else {
CpuCsrAccessError (host, "\nInvalid FPGA Instance number %d. \n", BoxInst);
}
break;
default:
CpuCsrAccessError (host, "\nInvalid Box Type %d. \n", BoxType);
}
if (Dev > 31) {
CpuCsrAccessError (host, "\nInvalid Device %d accessed for Box Type %d and Box Instance %d. \n", Dev, BoxType, BoxInst);
}
return Dev;
}
/**
Indetifies the function number for given BoxType, BoxInst & Functional Block
@param host - Pointer to the system host (root) structure
@param BoxType - Box Type; values come from CpuPciAccess.h
@param BoxInst - Box Instance, 0 based
@param FuncBlk - Functional Block; values come from CpuPciAccess.h
@retval PCI Function number
**/
UINT32
GetFunctionNumber (
PSYSHOST host,
UINT8 BoxType,
UINT8 BoxInst,
UINT8 FuncBlk,
CPU_CSR_ACCESS_VAR *CpuCsrAccessVar
)
{
UINT32 Fun = 0;
UINT8 CpuIndex, CpuType, NumChPerMC;
CpuType = CpuCsrAccessVar->cpuType;
NumChPerMC = CpuCsrAccessVar->numChPerMC;
// Get the CPU type, sub type
CpuIndex = GetCpuIndex(host);
//
// Translate the Box Type & Functional Block into PCI function number. Note that the box type & instance number
// passed to this routine are assumed to be valid; here we only need to validate if the function number is correct
// after the look up is done.
//
switch (BoxType) {
case BOX_MC:
if (FuncBlk == 0 || FuncBlk == 1) {
Fun = FunTbl[CpuType][BoxType][BoxInst % NumChPerMC] + FuncBlk;
} else {
Fun = 4;
}
break;
case BOX_MCDDC:
Fun = FunTbl[CpuType][BoxType][BoxInst % NumChPerMC] + FuncBlk;
break;
case BOX_MCIO:
if (FuncBlk == 2) {
Fun = FunTbl[CpuType][BoxType][BoxInst % NumChPerMC] + 3;
} else {
Fun = FunTbl[CpuType][BoxType][BoxInst % NumChPerMC] + FuncBlk;
}
break;
case BOX_CHA_MISC:
case BOX_CHA_PMA:
case BOX_CHA_CMS:
//
// For Cha, no table look up is needed; the function number can be obtained from instance number.
//
if ((CpuType == CPU_SKX) && (BoxInst < MAX_SKX_CHA)) {
Fun = (BoxInst % 8);
}
break;
case BOX_M3KTI:
/*
Logical M3KTI # Dev # Fun #
KTI01 0 18 0
KTI23 1 18 4
*/
Fun = FunTbl[CpuType][BoxType][FuncBlk];
if (BoxInst == 1) {
Fun = Fun + 4;
}
break;
case BOX_M2MEM:
case BOX_CHABC:
case BOX_PCU:
case BOX_VCU:
case BOX_IIO_PCIE_DMI:
case BOX_IIO_PCIE:
case BOX_IIO_PCIE_NTB:
case BOX_IIO_CB:
case BOX_IIO_VTD:
case BOX_UBOX:
Fun = FunTbl[CpuType][BoxType][FuncBlk];
break;
case BOX_M2UPCIE:
Fun = FunTbl[CpuType][BoxType][FuncBlk];
if (BoxInst == 2 || BoxInst == 4) { // M2PCIE2 & M2MCP1
Fun = Fun + 4;
}
break;
case BOX_KTI:
Fun = FunTbl[CpuType][BoxType][FuncBlk];
if (BoxInst >=9 ) {
Fun = Fun + 4;
}
break;
case BOX_IIO_RTO:
if ((BoxInst < MAX_ALL_IIO_RTO) && (FunTbl[CpuType][BoxType][FuncBlk] != 0xFF)) {
if (FuncBlk == IIO_RTO) {
if (BoxInst == 0) {
// Cstack
Fun = 0;
} else {
// M/Pstacks
Fun = 0 + ((BoxInst-1) % 4);
}
} else {
Fun = FunTbl[CpuType][BoxType][FuncBlk];
}
} else {
CpuCsrAccessError (host, "\nInvalid IIO RTO Box Instance Number %d. \n", BoxInst);
}
break;
case BOX_FPGA:
if (BoxInst == 0) {
Fun = 0;
} else {
CpuCsrAccessError (host, "\nInvalid FPGA Box Instance Number %d. \n", BoxInst);
}
break;
default:
CpuCsrAccessError (host, "\nInvalid Box Type %d. \n", BoxType);
}
if (Fun > 7) {
CpuCsrAccessError (host, "\nInvalid Functional Block %d accessed for CPUType %d CPUIndex %d Box Type %d and Box Instance %d. \n",
FuncBlk, CpuType, CpuIndex, BoxType, BoxInst);
}
return Fun;
}