diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2016-04-29 11:30:47 -0500 |
---|---|---|
committer | Matthew A. Ploetz <maploetz@us.ibm.com> | 2016-05-04 14:50:33 -0400 |
commit | ae304eed80b3e440f7fce5f5bafac5b357e9f7c4 (patch) | |
tree | 92b37b24a8f8d7e6c5c90f68fbf91a2eee02cc36 /src/usr/xscom/xscom.C | |
parent | 0b163c19b9950b1df51af5b128083f3a9edf071d (diff) | |
download | talos-hostboot-ae304eed80b3e440f7fce5f5bafac5b357e9f7c4.tar.gz talos-hostboot-ae304eed80b3e440f7fce5f5bafac5b357e9f7c4.zip |
Good path xscom support for multiple P9 chips
Necessary changes to handle new MMIO map for P9
Change-Id: I105114030d02c6baccb4732fe9597d67f24b263c
RTC: 128077
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23862
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-by: Matthew A. Ploetz <maploetz@us.ibm.com>
Diffstat (limited to 'src/usr/xscom/xscom.C')
-rw-r--r-- | src/usr/xscom/xscom.C | 102 |
1 files changed, 33 insertions, 69 deletions
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C index 5eaad2237..b4f4c3aa6 100644 --- a/src/usr/xscom/xscom.C +++ b/src/usr/xscom/xscom.C @@ -58,17 +58,15 @@ namespace XSCOM // Master processor virtual address uint64_t* g_masterProcVirtAddr = NULL; -// Max chip per node in this system -extern uint8_t getMaxChipsPerNode(); -static uint8_t g_xscomMaxChipsPerNode = getMaxChipsPerNode(); - // Register XSCcom access functions to DD framework DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD, DeviceFW::XSCOM, TARGETING::TYPE_PROC, xscomPerformOp); -uint64_t* getCpuIdVirtualAddress(); +// Helper function to map in the master proc's XSCOM space +uint64_t* getCpuIdVirtualAddress( XSComBase_t& o_mmioAddr ); + /** * @brief Internal routine that reset XSCOM status bits * of HMER register before an XSCOM operation @@ -187,32 +185,6 @@ errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType, } /** - * @brief Returns maximum processors chip per node - * base on system type - * - * @return uint8_t - */ -uint8_t getMaxChipsPerNode() -{ - uint8_t l_numOfChips = 0; - - ProcessorCoreType l_coreType = cpu_core_type(); - switch (l_coreType) - { - case CORE_POWER8_MURANO: - case CORE_POWER8_VENICE: - case CORE_POWER8_NAPLES: - case CORE_POWER9_NIMBUS: - case CORE_POWER9_CUMULUS: - case CORE_UNKNOWN: - default: - l_numOfChips = 8; - break; - } - return l_numOfChips; -} - -/** * @brief Get the virtual address of the input target * for an XSCOM access. * @@ -291,7 +263,8 @@ errlHndl_t getTargetVirtualAddress(TARGETING::Target* i_target, { // Note: can't call TARGETING code prior to PNOR being // brought up. - uint64_t* l_tempVirtAddr = getCpuIdVirtualAddress(); + uint64_t l_mmioAddr = 0; + uint64_t* l_tempVirtAddr = getCpuIdVirtualAddress(l_mmioAddr); if (!__sync_bool_compare_and_swap(&g_masterProcVirtAddr, NULL, l_tempVirtAddr)) { @@ -323,6 +296,14 @@ errlHndl_t getTargetVirtualAddress(TARGETING::Target* i_target, break; } } + else + { + TRACFCOMP(g_trac_xscom, + "Master Proc : pir=%.8X, mmio=0x%0.16llX, virt=0x%llX", + task_getcpuid(), + l_mmioAddr, + reinterpret_cast<uint64_t>(l_tempVirtAddr)); + } } // Set virtual address to sentinel's value @@ -343,35 +324,25 @@ errlHndl_t getTargetVirtualAddress(TARGETING::Target* i_target, // the virtual address and save it in the xscom address attribute. if (o_virtAddr == NULL) { - uint64_t xscomNodeId = 0; + uint64_t xscomGroupId = 0; uint64_t xscomChipId = 0; - // Get the target Node Id - xscomNodeId = + // Get the target Group Id + xscomGroupId = i_target->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>(); // Get the target Chip Id xscomChipId = i_target->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>(); - // Get system XSCOM base address - TARGETING::TargetService& l_targetService = - TARGETING::targetService(); - TARGETING::Target* l_pTopLevel = NULL; - (void) l_targetService.getTopLevelTarget(l_pTopLevel); - assert(l_pTopLevel != NULL); - XSComBase_t l_systemBaseAddr = - l_pTopLevel->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>(); - - // Target's XSCOM Base address - l_XSComBaseAddr = l_systemBaseAddr + - ( ( (g_xscomMaxChipsPerNode * xscomNodeId) + - xscomChipId ) * THIRTYTWO_GB); + // Get assigned XSCOM base address + l_XSComBaseAddr = + i_target->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>(); TRACFCOMP(g_trac_xscom, - "Target %.8X :: Node:%d Chip:%d :: XscomBase:0x%llX", + "Target %.8X :: Group:%d Chip:%d :: XscomBase:0x%llX", TARGETING::get_huid(i_target), - xscomNodeId, + xscomGroupId, xscomChipId, l_XSComBaseAddr); @@ -390,7 +361,7 @@ errlHndl_t getTargetVirtualAddress(TARGETING::Target* i_target, // logic. So there is possibility that this same thread is running // on another thread at the exact same time. We can use atomic // update instructions here. - // Comment for Nick: This is a good candidate for having a way + // Future note : This is a good candidate for having a way // to return a reference to the attribute instead of requiring // to call setAttr. We currently have no way to SMP-safely update // this attribute, where as if we had a reference to it we could use @@ -438,8 +409,8 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, HMER &io_hmer) { - // Build the XSCom address (relative to node 0, chip 0) - XSComP8Address l_mmioAddr(i_xscomAddr); + // Build the XSCom address (relative to group 0, chip 0) + XSComP9Address l_mmioAddr(i_xscomAddr); // Get the offset uint64_t l_offset = l_mmioAddr.offset(); @@ -488,7 +459,7 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, // an obscene amount of time if( l_retryCtr > 500000 ) { - TRACFCOMP( g_trac_xscom, "Giving up, we're still locked..." ); + TRACFCOMP( g_trac_xscom, "Giving up, we're still locked on 0x%.16llX...", l_offset ); break; } } @@ -542,32 +513,24 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, * @brief Get the Virtual Address of the XSCOM space for the processor * associated with this thread (the source chip) * + * @param[out] o_mmioAddr Physical mmio address that was mapped in * @return uint64_t* virtualAddress */ -uint64_t* getCpuIdVirtualAddress() +uint64_t* getCpuIdVirtualAddress( XSComBase_t& o_mmioAddr ) { uint64_t* o_virtAddr = 0; // Get the CPU core this thread is running on PIR_t cpuid = task_getcpuid(); - // Can change the above hardcoded values to either a macro or use - // the info below to do the masking and shifting. - // uint64_t max_threads = cpu_thread_count(); - // for the number of Chips - use g_xscomMaxChipsPerNode instead.. - // For the number of Procs.. MAX_PROCS_RSV = P8_MAX_PROCS*2 - // P8_MAX_PROCS = 8 -- space left for 2* that. - - XSComBase_t l_systemBaseAddr = MASTER_PROC_XSCOM_BASE_ADDR; - // Target's XSCOM Base address - XSComBase_t l_XSComBaseAddr = l_systemBaseAddr + - ( ( (g_xscomMaxChipsPerNode * cpuid.groupId) + - cpuid.chipId ) * THIRTYTWO_GB); + o_mmioAddr = MASTER_PROC_XSCOM_BASE_ADDR + + (MMIO_OFFSET_PER_GROUP * cpuid.groupId) + + (MMIO_OFFSET_PER_GROUP * cpuid.chipId); // Target's virtual address o_virtAddr = static_cast<uint64_t*> - (mmio_dev_map(reinterpret_cast<void*>(l_XSComBaseAddr), + (mmio_dev_map(reinterpret_cast<void*>(o_mmioAddr), THIRTYTWO_GB)); TRACDCOMP(g_trac_xscom, "getCpuIdVirtualAddress: o_Virtual Address = 0x%llX\n",o_virtAddr); @@ -611,7 +574,8 @@ void resetScomEngine(TARGETING::Target* i_target, // running on. Need to find the virtAddr for that CPU. if (XscomAddr[i].target_type == CurThreadCpu) { - l_virtAddr = getCpuIdVirtualAddress(); + XSComBase_t l_ignored = 0; + l_virtAddr = getCpuIdVirtualAddress(l_ignored); } // The rest are xscoms are to the target cpu. else |