diff options
author | Brian Bakke <bbakke@us.ibm.com> | 2018-05-22 11:30:26 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-06-07 13:37:46 -0400 |
commit | e364f91be1727019dd594c57d496e5ce43e8f5f0 (patch) | |
tree | 3515d4777d5ca4705fc232b02110d6c480151eff /src/usr/xscom | |
parent | 0c6d58230e615000dee1a1940bf4bc84ad5c1798 (diff) | |
download | talos-hostboot-e364f91be1727019dd594c57d496e5ce43e8f5f0.tar.gz talos-hostboot-e364f91be1727019dd594c57d496e5ce43e8f5f0.zip |
Fixes to node IPC messaging to handle non-zero base addresses
Current code has each Node calculate each Remote Node's IPC area
remote address by performing a fixed format calculation.
This change has each Node calculating its IPC area Remote address
and posting this value to a local SCOM register. A Node reads
a Remote Node's SCOM register to acquire the Remote IPC area
address.
Change-Id: I25260ce180e0d07e5e81990d4c1f99e249912491
RTC:191463
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59177
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Prachi Gupta <pragupta@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/xscom')
-rw-r--r-- | src/usr/xscom/xscom.C | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C index 18594d7cd..7c8bd607c 100644 --- a/src/usr/xscom/xscom.C +++ b/src/usr/xscom/xscom.C @@ -35,12 +35,14 @@ #include <sys/task.h> #include <sys/sync.h> #include <sys/misc.h> +#include <sys/time.h> #include <string.h> #include <devicefw/driverif.H> #include <trace/interface.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> #include <targeting/common/targetservice.H> +#include <targeting/common/utilFilter.H> #include <xscom/xscomreasoncodes.H> #include "xscom.H" #include <assert.h> @@ -818,4 +820,115 @@ uint64_t generate_mmio_addr( TARGETING::Target* i_proc, return l_returnAddr; } + +/** + * @brief Multicast Read of core XSCOM register on remote Node + */ +uint64_t readRemoteCoreScomMultiCast( uint64_t i_node, + uint64_t i_scomAddr ) +{ + // definitions of 64 bit xscom address contents that are + // useful for this function + // hi 32 bits lo 32 bits + // representation : 0x0000_0000__0000_0000 + // + // (hi 32 bits, xscom mmio control) + // + // chip field 0x0000_0400__0000_0000 + // (to be multiplied by chip ID to give field value) + // + // node/group field (0-7) 0xE000_0000__0000_0000 + // + // (lo 32 bits, scom addr) + // + // multicast 0x0000_0000__4000_0000 + // multicast op type 0x0000_0000__3800_0000 + // - read OR 00 + // - read AND 08 + // - read bitwise 10 + // - rsvd 18 + // - write compare 20 + // - write 28 + // - rsvd 30 + // - rsvd 38 + // multicast group 0x0000_0000__0700_0000 + // relative scomAddr field 0x0000_0000__00FF_FFFF + constexpr uint64_t XSCOM_MULTICAST = 0x0000000040000000; + constexpr uint64_t XSCOM_MULTICAST_OP_READ_OR = 0x0000000000000000; + constexpr uint64_t XSCOM_MULTICAST_GROUP_CORE = 0x0000000001000000; + constexpr uint64_t XSCOM_MULTICAST_REL_ADDR_MASK = 0x0000000000FFFFFF; + + // Symmetry between nodes is enforced so we know the remote + // node contains this chip + TARGETING::Target * l_MasterProcTarget = nullptr; + TARGETING::TargetService & l_tgtServ = TARGETING::targetService(); + l_tgtServ.masterProcChipTargetHandle( l_MasterProcTarget ); + uint8_t l_chipId = + l_MasterProcTarget->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>(); + + // compute xscom address & control, then map into processor space + uint64_t l_xscomBaseAddr = + computeMemoryMapOffset( MMIO_GROUP0_CHIP0_XSCOM_BASE_ADDR, + i_node, + l_chipId ); + + uint64_t l_xscomAddr = ( (i_scomAddr & XSCOM_MULTICAST_REL_ADDR_MASK) | + XSCOM_MULTICAST | + XSCOM_MULTICAST_OP_READ_OR | + XSCOM_MULTICAST_GROUP_CORE ); + + uint64_t * l_virtAddr = + static_cast<uint64_t*> + (mmio_dev_map(reinterpret_cast<void*>(l_xscomBaseAddr), + THIRTYTWO_GB)); + + // execute the SCOM op to do the multicast read + // init return value to dummy to verify read happened + uint64_t l_rv = IPC_INVALID_REMOTE_ADDR | i_node; + size_t l_rvSize = sizeof(l_rv); + HMER l_hmer; + + do + { + errlHndl_t l_err = xScomDoOp( DeviceFW::READ, + l_virtAddr, + l_xscomAddr, + &l_rv, + l_rvSize, + l_hmer ); + + // If not successful + if (l_err) + { + delete l_err; + l_err = nullptr; + + TRACFCOMP( g_trac_xscom, + ERR_MRK "readRemoteCoreScomMultiCast() Read xScom Failed: " + "XscomAddr = %.16llx, VAddr=%llx", + l_xscomAddr, l_virtAddr ); + + // re-seed return value in case changed before error detected + l_rv = IPC_INVALID_REMOTE_ADDR | i_node; + break; + } + else + { + } + + // regs not yet populated + if (l_rv == 0 ) + { + // delay to allow remote core to populate regs + nanosleep(0, (NS_PER_MSEC * 100)); + } + + // wait for remote node to populate its core scom regs + } while( l_rv == 0 ); + + mmio_dev_unmap(reinterpret_cast<void*>(l_virtAddr)); + + return l_rv; +} + } // end namespace |