diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/build/tools/listdeps.pl | 5 | ||||
-rw-r--r-- | src/include/usr/devicefw/driverif.H | 9 | ||||
-rw-r--r-- | src/include/usr/scom/scomif.H | 11 | ||||
-rw-r--r-- | src/usr/isteps/istep13/call_mem_startclocks.C | 7 | ||||
-rw-r--r-- | src/usr/isteps/istep16/call_host_activate_slave_cores.C | 6 | ||||
-rw-r--r-- | src/usr/scom/scom.C | 79 | ||||
-rw-r--r-- | src/usr/xscom/xscom.C | 29 |
7 files changed, 133 insertions, 13 deletions
diff --git a/src/build/tools/listdeps.pl b/src/build/tools/listdeps.pl index 26e4e5a0e..7096f0a38 100755 --- a/src/build/tools/listdeps.pl +++ b/src/build/tools/listdeps.pl @@ -6,7 +6,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2016 +# Contributors Listed Below - COPYRIGHT 2013,2017 # [+] Google Inc. # [+] International Business Machines Corp. # @@ -221,7 +221,8 @@ my $resident_modules = { "libsbeio.so" => '1', "libvpd.so" => '1', "libsecureboot_trusted.so" => '1', - "libsecureboot_base.so" => '1', + "libsecureboot_base.so" => '1', + "libscom.so" => '1', }; # A list of the dependent libraries in each istep. diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index 550b90f09..df90800b3 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -93,7 +93,14 @@ namespace DeviceFW * @param[in] i_address - XSCom address to operate on. */ #define DEVICE_XSCOM_ADDRESS(i_address) \ - DeviceFW::XSCOM, static_cast<uint64_t>((i_address)) + DeviceFW::XSCOM, static_cast<uint64_t>((i_address)), 0ull + + /** Construct the device addressing parameters for XSCOM device ops + * when no error handling is required. + * @param[in] i_address - XSCom address to operate on. + */ + #define DEVICE_XSCOM_ADDRESS_NO_ERROR(i_address) \ + DeviceFW::XSCOM, static_cast<uint64_t>((i_address)), 1ull /** Construct the device addressing parameters for IBSCOM (inband scom) * device ops. diff --git a/src/include/usr/scom/scomif.H b/src/include/usr/scom/scomif.H index 4bba1112b..5df08120d 100644 --- a/src/include/usr/scom/scomif.H +++ b/src/include/usr/scom/scomif.H @@ -43,6 +43,17 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, bool & o_needsWakeup, uint64_t i_opMode = 0); +#ifndef __HOSTBOOT_RUNTIME +/** + * @brief Enable scoms to all cores for multicast workaround + */ +void enableSlaveCoreMulticast( void ); + +/** + * @brief Enable scoms to the memory chiplets for multicast workaround + */ +void enableMemChipletMulticast( void ); +#endif }; // end namespace SCOM diff --git a/src/usr/isteps/istep13/call_mem_startclocks.C b/src/usr/isteps/istep13/call_mem_startclocks.C index 0cd610194..19a84a64c 100644 --- a/src/usr/isteps/istep13/call_mem_startclocks.C +++ b/src/usr/isteps/istep13/call_mem_startclocks.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -42,6 +42,7 @@ //From Import Directory (EKB Repository) #include <p9_mem_startclocks.H> +#include <scom/scomif.H> using namespace ERRORLOG; using namespace ISTEP; @@ -100,6 +101,10 @@ void* call_mem_startclocks (void *io_pArgs) } } + // Now that the memory chiplets are turned on, we need to include them in + // multicast scom operations + SCOM::enableMemChipletMulticast(); + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mem_startclocks exit" ); diff --git a/src/usr/isteps/istep16/call_host_activate_slave_cores.C b/src/usr/isteps/istep16/call_host_activate_slave_cores.C index 8258552bc..a6bff1970 100644 --- a/src/usr/isteps/istep16/call_host_activate_slave_cores.C +++ b/src/usr/isteps/istep16/call_host_activate_slave_cores.C @@ -49,6 +49,8 @@ #include <isteps/pm/occCheckstop.H> #endif +#include <scom/scomif.H> + using namespace ERRORLOG; using namespace TARGETING; using namespace ISTEP; @@ -256,6 +258,10 @@ void* call_host_activate_slave_cores (void *io_pArgs) } #endif + // Now that the slave cores are running, we need to include them in + // multicast scom operations + SCOM::enableSlaveCoreMulticast(); + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores exit" ); diff --git a/src/usr/scom/scom.C b/src/usr/scom/scom.C index e6d1a9135..5c35dfdd2 100644 --- a/src/usr/scom/scom.C +++ b/src/usr/scom/scom.C @@ -48,7 +48,7 @@ #include <hw_access_def.H> #include <p9_scom_addr.H> #include <targeting/common/utilFilter.H> - +#include <targeting/namedtarget.H> // Trace definition @@ -58,6 +58,31 @@ TRAC_INIT(&g_trac_scom, SCOM_COMP_NAME, KILOBYTE, TRACE::BUFFER_SLOW); //1K namespace SCOM { +#ifndef __HOSTBOOT_RUNTIME +/** + * Keep track of system state to handle the multicast workaround + * more cleanly + */ +bool g_useSlaveCores = false; +bool g_useMemChiplets = false; + +/** + * @brief Enable scoms to all cores for multicast workaround + */ +void enableSlaveCoreMulticast( void ) +{ + g_useSlaveCores = true; +}; + +/** + * @brief Enable scoms to the memory chiplets for multicast workaround + */ +void enableMemChipletMulticast( void ) +{ + g_useMemChiplets = true; +}; +#endif + /** * @brief Add any additional FFDC for this specific type of scom * @@ -1187,6 +1212,16 @@ errlHndl_t doMulticastWorkaround( DeviceFW::OperationType i_opType, constexpr uint64_t MULTICAST_OP = 0x38000000; constexpr uint64_t MULTICAST_OP_BITWISE = 0x10000000; +#ifndef __HOSTBOOT_RUNTIME + // Some P9-specific chiplet values to make things more efficient + constexpr uint64_t P9_FIRST_MC = 0x07; + constexpr uint64_t P9_LAST_MC = 0x08; + constexpr uint64_t P9_FIRST_EQ = 0x10; + constexpr uint64_t P9_LAST_EQ = 0x1F; + constexpr uint64_t P9_FIRST_EC = 0x20; + constexpr uint64_t P9_LAST_EC = 0x2F; +#endif + // Skip calls to the SENTINEL since we don't have the // ability to find its children if( TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL @@ -1224,13 +1259,53 @@ errlHndl_t doMulticastWorkaround( DeviceFW::OperationType i_opType, uint64_t l_data = 0; uint64_t l_addr = (i_addr & ~CHIPLET_BYTE); uint64_t l_unit = l_chiplet->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + +#ifndef __HOSTBOOT_RUNTIME + // filter out some chiplets that aren't running yet + if( !g_useSlaveCores + && (((l_unit >= P9_FIRST_EQ) && (l_unit <= P9_LAST_EQ)) + || ((l_unit >= P9_FIRST_EC) && (l_unit <= P9_LAST_EC)) + ) + ) + { + // Only access the master ec/eq + static const TARGETING::Target* l_masterCore = + TARGETING::getMasterCore(); + uint64_t l_ecNum = + l_masterCore->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + bool l_fused = TARGETING::is_fused_mode(); + if( !((l_unit == l_ecNum) //master + || (l_fused && (l_unit == l_ecNum+1))) ) //fused-pair + { + continue; + } + auto l_eqNum = 0x10 + l_ecNum/4; + if( l_unit == l_eqNum ) + { + continue; + } + } + if( !g_useMemChiplets + && ((l_unit >= P9_FIRST_MC) && (l_unit <= P9_LAST_MC)) ) + { + // Only access the mem chiplets if we're not in async mode + // because we don't start clocks until later on in that case + auto l_syncMode = + i_target->getAttr<TARGETING::ATTR_MC_SYNC_MODE>(); + if( l_syncMode ) + { + continue; + } + } +#endif + l_addr |= (l_unit << 24); io_buflen = sizeof(uint64_t); l_err = deviceOp(i_opType, i_target, &l_data, io_buflen, - DEVICE_XSCOM_ADDRESS(l_addr)); + DEVICE_XSCOM_ADDRESS_NO_ERROR(l_addr)); // just ignore any errors, we expect they will happen if( l_err ) { diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C index 647111cfd..c9afe0273 100644 --- a/src/usr/xscom/xscom.C +++ b/src/usr/xscom/xscom.C @@ -458,7 +458,7 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, { // print a trace message.. for debug purposes // incase we are stuck in a retry loop. - TRACFCOMP(g_trac_xscom,"xscomPerformOp - RESOURCE OCCUPIED LOOP Cntr = %d: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX, HMER=%.16X", l_retryCtr, static_cast<uint64_t>(i_opType), i_xscomAddr, static_cast<uint64_t>(l_mmioAddr), io_hmer.mRegister ); + TRACFCOMP(g_trac_xscom,"xscomDoOp - RESOURCE OCCUPIED LOOP Cntr = %d: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX, HMER=%.16X", l_retryCtr, static_cast<uint64_t>(i_opType), i_xscomAddr, static_cast<uint64_t>(l_mmioAddr), io_hmer.mRegister ); // we don't want to hang forever so break out after // an obscene amount of time @@ -471,17 +471,17 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, } while (io_hmer.mXSComStatus == PIB::PIB_RESOURCE_OCCUPIED); - TRACDCOMP(g_trac_xscom,"xscomPerformOp: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX", static_cast<uint64_t>(i_opType),i_xscomAddr,static_cast<uint64_t>(l_mmioAddr)); + TRACDCOMP(g_trac_xscom,"xscomDoOp: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX", static_cast<uint64_t>(i_opType),i_xscomAddr,static_cast<uint64_t>(l_mmioAddr)); - TRACDCOMP(g_trac_xscom, "xscomPerformOp: l_offset 0x%.16llX; VirtAddr %p; i_virtAddr+l_offset %p",l_offset,i_virtAddr,i_virtAddr + l_offset); + TRACDCOMP(g_trac_xscom, "xscomDoOp: l_offset 0x%.16llX; VirtAddr %p; i_virtAddr+l_offset %p",l_offset,i_virtAddr,i_virtAddr + l_offset); if (i_opType == DeviceFW::READ) { - TRACDCOMP(g_trac_xscom, "xscomPerformOp: Read data: %.16llx", l_data); + TRACDCOMP(g_trac_xscom, "xscomDoOp: Read data: %.16llx", l_data); } else { - TRACDCOMP(g_trac_xscom, "xscomPerformOp: Write data: %.16llx", l_data); + TRACDCOMP(g_trac_xscom, "xscomDoOp: Write data: %.16llx", l_data); } do @@ -490,6 +490,7 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, if (io_hmer.mXSComStatus != PIB::PIB_NO_ERROR) { uint64_t l_hmerVal = io_hmer; + uint64_t l_fullAddr = mm_virt_to_phys(i_virtAddr + l_offset); TRACFCOMP(g_trac_xscom,ERR_MRK "XSCOM status error HMER: %.16llx ,XSComStatus = %llx, Addr=%llx",l_hmerVal,io_hmer.mXSComStatus, i_xscomAddr ); /*@ @@ -504,7 +505,7 @@ errlHndl_t xScomDoOp(DeviceFW::OperationType i_opType, XSCOM_DO_OP, XSCOM_STATUS_ERR, io_hmer, - l_mmioAddr); + l_fullAddr); //Note: Callouts are added by the caller if needed } } @@ -746,6 +747,7 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType, HMER l_hmer; mutex_t* l_XSComMutex = NULL; uint64_t l_addr = va_arg(i_args,uint64_t); + uint64_t l_noErrors = va_arg(i_args,uint64_t); do { @@ -793,7 +795,20 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType, l_hmer); // If we got a scom error. - if (l_err) + if (l_err && l_noErrors) + { + // ignoring errors because the caller doesn't care + // just return all zero data + delete l_err; + l_err = nullptr; + io_buflen = XSCOM_BUFFER_SIZE; + memset( io_buffer, 0, io_buflen ); + + // still need to reset the scomEngine. + resetScomEngine(i_target, + l_virtAddr); + } + else if (l_err) { // Call XscomCollectFFDC.. collectXscomFFDC(i_target, |