/** @file Copyright (c) 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #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; }