/** @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; }