diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2016-03-07 11:40:44 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-03-29 13:33:23 -0400 |
commit | 40e763ce8ad18132b6244a695ca9bc5f96a07674 (patch) | |
tree | 6dc851e3f51e357c228e2b929716e5e08baa5124 | |
parent | c66c9b42b4e2aa5abb6293c732ad7f3245e1e3e0 (diff) | |
download | talos-hostboot-40e763ce8ad18132b6244a695ca9bc5f96a07674.tar.gz talos-hostboot-40e763ce8ad18132b6244a695ca9bc5f96a07674.zip |
Additional fapi2 hw_access support
Moved function implementations into .C file
Cleaned up cfam target check
Change-Id: Ib25e6cdb336688eb23e2cfef7f3756781839753f
RTC: 143118
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/867
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/include/usr/fapi2/hw_access.H | 5 | ||||
-rw-r--r-- | src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H | 1 | ||||
-rw-r--r-- | src/include/usr/fapi2/plat_hw_access.H | 697 | ||||
-rwxr-xr-x | src/usr/fapi2/fapi2.mk | 2 | ||||
-rw-r--r-- | src/usr/fapi2/plat_hw_access.C | 672 | ||||
-rw-r--r-- | src/usr/fapi2/test/fapi2HwpTest.C | 63 | ||||
-rw-r--r-- | src/usr/fapi2/test/makefile | 1 | ||||
-rw-r--r-- | src/usr/fapi2/test/p9_hwtests.C | 192 | ||||
-rw-r--r-- | src/usr/fapi2/test/p9_hwtests.H | 67 |
9 files changed, 1030 insertions, 670 deletions
diff --git a/src/include/usr/fapi2/hw_access.H b/src/include/usr/fapi2/hw_access.H index 07ef14373..867379e95 100644 --- a/src/include/usr/fapi2/hw_access.H +++ b/src/include/usr/fapi2/hw_access.H @@ -31,11 +31,6 @@ #ifndef _FAPI2_HWACCESS_H_ #define _FAPI2_HWACCESS_H_ -// Variable_buffer isn't supported on PPE -#ifndef __PPE__ -#include <variable_buffer.H> -#endif - #include <plat_hw_access.H> #include <fapi2_hw_access.H> diff --git a/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H b/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H index f08e34014..c737ca692 100644 --- a/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H +++ b/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H @@ -47,6 +47,7 @@ namespace fapi2 MOD_FAPI2_PLAT_HWP_TEST = 0x04, MOD_FAPI2_PLAT_GET_PARENT_TEST = 0x05, MOD_FAPI2_PLAT_GET_CHILDREN_TEST = 0x06, + MOD_FAPI2_VERIFYCFAMACCESSTARGET = 0x07, }; /** diff --git a/src/include/usr/fapi2/plat_hw_access.H b/src/include/usr/fapi2/plat_hw_access.H index 8ed41a326..d5e76e55c 100644 --- a/src/include/usr/fapi2/plat_hw_access.H +++ b/src/include/usr/fapi2/plat_hw_access.H @@ -36,15 +36,11 @@ #ifndef PLATHWACCESS_H_ #define PLATHWACCESS_H_ -#include <stdint.h> -#include <errl/errlentry.H> -#include <devicefw/userif.H> #include <return_code.H> #include <buffer.H> #include <target.H> #include <target_types.H> #include <hw_access_def.H> -#include <plat_utils.H> namespace fapi2 { @@ -58,56 +54,13 @@ namespace fapi2 /// @Tparam K template parameter, passed in target. /// @param[in] i_target HW target to operate on. /// @param[in] i_address SCOM register address to read from. -/// @param[out] o_date Buffer that holds data read from HW target. +/// @param[out] o_data Buffer that holds data read from HW target. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. /// -template< TargetType K > -inline ReturnCode platGetScom(const Target<K>& i_target, - const uint64_t i_address, - buffer<uint64_t>& o_data) -{ - ReturnCode l_rc; - errlHndl_t l_err = NULL; - - FAPI_DBG(ENTER_MRK "platGetScom"); - // Note: Trace is placed here in plat code because PPE doesn't support - // trace in common fapi2_hw_access.H - bool l_traceit = platIsScanTraceEnabled(); - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); +ReturnCode platGetScom(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + buffer<uint64_t>& o_data); - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; - - // Perform SCOM read - size_t l_size = sizeof(uint64_t); - l_err = deviceRead(l_target, - &o_data(), - l_size, - DEVICE_SCOM_ADDRESS(i_address)); - if (l_err) - { - FAPI_ERR("platGetScom: deviceRead returns error!"); - FAPI_ERR("fapiGetScom failed - Target %s, Addr %.16llX", - tmpScomStr, i_address); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - } - - if (l_traceit) - { - uint64_t l_data = (uint64_t)o_data; - FAPI_SCAN("TRACE : GETSCOM : %s : %.16llX %.16llX", - tmpScomStr, - i_address, - l_data); - } - - FAPI_DBG(EXIT_MRK "platGetScom"); - return l_rc; -} /// @brief Platform-level implementation called by putScom() /// @Tparam K template parameter, passed in target. @@ -115,53 +68,10 @@ inline ReturnCode platGetScom(const Target<K>& i_target, /// @param[in] i_address SCOM register address to write to. /// @param[in] i_data Buffer that holds data to write into address. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -template< TargetType K > -inline ReturnCode platPutScom(const Target<K>& i_target, - const uint64_t i_address, - const buffer<uint64_t> i_data) -{ - ReturnCode l_rc; - errlHndl_t l_err = NULL; - - FAPI_DBG(ENTER_MRK "platPutScom"); - // Note: Trace is placed here in plat code because PPE doesn't support - // trace in common fapi2_hw_access.H - bool l_traceit = platIsScanTraceEnabled(); - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; +ReturnCode platPutScom(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data); - // Perform SCOM write - size_t l_size = sizeof(uint64_t); - uint64_t l_data = static_cast<uint64_t>(i_data); - l_err = deviceWrite(l_target, - &l_data, - l_size, - DEVICE_SCOM_ADDRESS(i_address)); - if (l_err) - { - FAPI_ERR("platPutScom: deviceRead returns error!"); - FAPI_ERR("platPutScom failed - Target %s, Addr %.16llX", - tmpScomStr, i_address); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - } - - if (l_traceit) - { - FAPI_SCAN("TRACE : PUTSCOM : %s : %.16llX %.16llX", - tmpScomStr, - i_address, - l_data); - } - - FAPI_DBG(EXIT_MRK "platPutScom"); - return l_rc; -} /// @brief Platform-level implementation called by putScomUnderMask() /// @tparam K template parameter, passed in target. @@ -170,199 +80,11 @@ inline ReturnCode platPutScom(const Target<K>& i_target, /// @param[in] i_data Buffer that holds data to write into address. /// @param[in] i_mask Buffer that holds the mask value. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -template< TargetType K > -inline ReturnCode platPutScomUnderMask(const Target<K>& i_target, - const uint64_t i_address, - const buffer<uint64_t> i_data, - const buffer<uint64_t> i_mask) -{ - ReturnCode l_rc; - errlHndl_t l_err = NULL; - - FAPI_DBG(ENTER_MRK "platPutScomUnderMask"); - // Note: Trace is placed here in plat code because PPE doesn't support - // trace in common fapi2_hw_access.H - bool l_traceit = platIsScanTraceEnabled(); - - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; - - do - { - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - // Get current value from HW - uint64_t l_data = 0; - size_t l_size = sizeof(uint64_t); - l_err = deviceRead(l_target, - &l_data, - l_size, - DEVICE_SCOM_ADDRESS(i_address)); - if (l_err) - { - FAPI_ERR("platPutScomUnderMask: deviceRead returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Calculate new value to write to reg - uint64_t l_inMaskInverted = ~i_mask; // Write mask inverted - uint64_t l_newMask = (i_data & i_mask); // Retain set data bits - - // l_data = current data set bits - l_data &= l_inMaskInverted; - - // l_data = current data set bit + set mask bits - l_data |= l_newMask; - - // Write new value - l_err = deviceWrite(l_target, - &l_data, - l_size, - DEVICE_SCOM_ADDRESS(i_address)); - if (l_err) - { - FAPI_ERR("platPutScomUnderMask: deviceWrite returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - } while (0); - - if (l_rc != fapi2::FAPI2_RC_SUCCESS) - { - FAPI_ERR("platPutScomUnderMask failed - Target %s, Addr %.16llX", - tmpScomStr, i_address); - } - - if( l_traceit ) - { - uint64_t l_data = i_data; - uint64_t l_mask = i_mask; - FAPI_SCAN( "TRACE : PUTSCOMMASK : %s : %.16llX %.16llX %.16llX", - tmpScomStr, - i_address, - l_data, - l_mask); - } - - FAPI_DBG(EXIT_MRK "platPutScomUnderMask"); - return l_rc; -} - -/// -/// @brief Platform-level implementation of modifyScom() -/// Hardware procedures writers will not call this function. -/// @Tparam K template parameter, passed in target. -/// @param[in] i_target HW target to operate on. -/// @param[in] i_address SCOM address to modify. -/// @param[out] i_data 64-bit buffer that holds data to modify. -/// @param[in] i_modifyMode The modify mode (or/and/xor). -/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template< TargetType K > -inline ReturnCode platModifyScom(const Target<K>& i_target, - const uint32_t i_address, - const buffer<uint32_t> i_data, - const fapi2::ChipOpModifyMode i_modifyMode) -{ - - // --------------- Will implement when needed -------------------- +ReturnCode platPutScomUnderMask(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data, + const buffer<uint64_t> i_mask); - FAPI_DBG(ENTER_MRK "platModifyScom"); - ReturnCode l_rc; - errlHndl_t l_err = NULL; - FAPI_ERR("platModifyScom: Error: Hostboot not yet support modifyScom function!"); - - // Add the error log pointer as data and set the ReturnCode as needed - - FAPI_DBG(EXIT_MRK "platModifyScom"); - return l_rc; -} - -/// -/// @brief Verify target of a cfam access -/// We can't access the cfam engine of the master processor. -/// Only allow access to the other processors. -/// This function will return an error if the input target is -/// the boot processor. -/// @Tparam K template parameter, passed in target. -/// @param[in] i_target HW target to operate on. -/// @param[in] i_address CFAM address to read from. -/// @return errlHndl_t -/// -template< TargetType K > -static errlHndl_t verifyCfamAccessTarget(const Target<K>& i_target, - const uint32_t i_address) -{ - errlHndl_t l_err = NULL; - - // Can't access cfam engine on the master processor - if (i_target.getType() == fapi2::TARGET_TYPE_PROC_CHIP) - { - TARGETING::Target* l_pMasterProcChip = NULL; - TARGETING::targetService(). - masterProcChipTargetHandle( l_pMasterProcChip ); - - TARGETING::Target* l_pTarget = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - if( l_pMasterProcChip == l_pTarget ) - { - FAPI_ERR("verifyCfamAccessTarget: Attempt to access CFAM register %.8X on the master processor chip", - i_address); - } - } - return l_err; -} - -/// -/// @brief Internal function that gets the chip target for cfam access -/// HW procedures may pass in non-chip targets (such as MBA or -/// MBS as a target), so we need to find the parent chip in order -/// to pass it to the device driver. -/// @param[in] i_target HW target to operate on. -/// @param[out] o_chipTarget The output chip target. -/// @return errlHndl_t -/// -static errlHndl_t getCfamChipTarget(const TARGETING::Target* i_target, - TARGETING::Target*& o_chipTarget) -{ - errlHndl_t l_err = NULL; - - // Default to input target - o_chipTarget = const_cast<TARGETING::Target*>(i_target); - - // Check to see if this is a chiplet - if (i_target->getAttr<TARGETING::ATTR_CLASS>() == TARGETING::CLASS_UNIT) - { - // Look for its chip parent - TARGETING::PredicateCTM l_chipClass(TARGETING::CLASS_CHIP); - TARGETING::TargetHandleList l_list; - TARGETING::TargetService& l_targetService = TARGETING::targetService(); - (void) l_targetService.getAssociated( - l_list, - i_target, - TARGETING::TargetService::PARENT, - TARGETING::TargetService::ALL, - &l_chipClass); - - if ( l_list.size() == 1 ) - { - o_chipTarget = l_list[0]; - } - else - { - // Something is wrong here, can't have more than one parent chip - FAPI_ERR("getCfamChipTarget: Invalid number of parent chip for this target chiplet - # parent chips %d", l_list.size()); - } - } - return l_err; -} /// /// @brief Platform-level implementation called by getCfamRegister() @@ -373,86 +95,10 @@ static errlHndl_t getCfamChipTarget(const TARGETING::Target* i_target, /// @param[out] o_data 32-bit buffer that holds data read from HW target. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. /// -template< TargetType K > -inline ReturnCode platGetCfamRegister(const Target<K>& i_target, - const uint32_t i_address, - buffer<uint32_t>& o_data) -{ - FAPI_DBG(ENTER_MRK "platGetCfamRegister"); - ReturnCode l_rc; - errlHndl_t l_err = NULL; - bool l_traceit = platIsScanTraceEnabled(); +ReturnCode platGetCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + buffer<uint32_t>& o_data); - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; - - do - { - // Can't access cfam engine on master processor - l_err = verifyCfamAccessTarget(i_target,i_address); - if (l_err) - { - FAPI_ERR("platGetCfamRegister: verifyCfamAccessTarget returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - // Get the chip target if l_target is not a chip - TARGETING::Target* l_myChipTarget = NULL; - l_err = getCfamChipTarget(l_target, l_myChipTarget); - if (l_err) - { - FAPI_ERR("platGetCfamRegister: getCfamChipTarget returns error!"); - FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X", - tmpScomStr, i_address); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Perform CFAM read via FSI - // Address needs to be multiply by 4 because register addresses are - // word offsets but the FSI addresses are byte offsets. - // However, we need to preserve the engine's offset of 0x0C00 and 0x1000 - uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); - size_t l_size = sizeof(uint32_t); - l_err = deviceRead(l_myChipTarget, - &o_data(), - l_size, - DEVICE_FSI_ADDRESS(l_addr)); - if (l_err) - { - FAPI_ERR("platGetCfamRegister: deviceRead returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - } while(0); - - if (l_rc != fapi2::FAPI2_RC_SUCCESS) - { - FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X", - tmpScomStr, i_address); - } - - if( l_traceit ) - { - uint32_t l_data = (uint32_t)o_data; - FAPI_SCAN( "TRACE : GETCFAMREG : %s : %.8X %.8X", - tmpScomStr, - i_address, - l_data); - } - - FAPI_DBG(EXIT_MRK "platGetCfamRegister"); - return l_rc; -} /// /// @brief Platform-level implementation called by putCfamRegister() @@ -463,123 +109,10 @@ inline ReturnCode platGetCfamRegister(const Target<K>& i_target, /// @param[out] i_data 32-bit buffer that holds data to write into address. /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. /// -template< TargetType K > -inline ReturnCode platPutCfamRegister(const Target<K>& i_target, - const uint32_t i_address, - const buffer<uint32_t> i_data) -{ - FAPI_DBG(ENTER_MRK "platPutCfamRegister"); - ReturnCode l_rc; - errlHndl_t l_err = NULL; - bool l_traceit = platIsScanTraceEnabled(); - - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; - - do - { - // Can't access cfam engine on master processor - l_err = verifyCfamAccessTarget(i_target,i_address); - if (l_err) - { - FAPI_ERR("platPutCfamRegister: verifyCfamAccessTarget returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - TARGETING::Target* l_myChipTarget = NULL; - // Get the chip target if l_target is not a chip - l_err = getCfamChipTarget(l_target, l_myChipTarget); - if (l_err) - { - FAPI_ERR("platPutCfamRegister: getCfamChipTarget returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Perform CFAM write via FSI - // Address needs to be multiply by 4 because register addresses are word - // offsets but the FSI addresses are byte offsets - // However, we need to preserve the engine's offset of 0x0C00 and 0x1000 - uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); - size_t l_size = sizeof(uint32_t); - uint32_t l_data = static_cast<uint32_t>(i_data); - l_err = deviceWrite(l_myChipTarget, - &l_data, - l_size, - DEVICE_FSI_ADDRESS(l_addr)); - if (l_err) - { - FAPI_ERR("platPutCfamRegister: deviceWrite returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - } while (0); +ReturnCode platPutCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + const buffer<uint32_t> i_data); - if (l_rc != fapi2::FAPI2_RC_SUCCESS) - { - FAPI_ERR("platPutCfamRegister failed - Target %s, Addr %.8X", - tmpScomStr, i_address); - } - - if( l_traceit ) - { - uint32_t l_data = i_data; - FAPI_SCAN( "TRACE : PUTCFAMREG : %s : %.8X %.8X", - tmpScomStr, - i_address, - l_data); - } - - FAPI_DBG(EXIT_MRK "platPutCfamRegister"); - return l_rc; -} - - -/// @brief Modifying input 32-bit data with the specified mode -/// This method modify 32-bit input data (io_modifiedData) by applying the -/// specified modify mode along with the input data (i_origData). -/// -/// @param[in] i_modifyMode Modification mode -/// @param[in] i_origData 32-bit data to be used for modification -/// @param[out] io_modifiedData 32-bit data to be modified -/// -/// @return void -/// -static void platProcess32BitModifyMode( - const fapi2::ChipOpModifyMode i_modifyMode, - const buffer<uint32_t> i_origDataBuf, - buffer<uint32_t>& io_modifiedData) -{ - -//@TODO RTC:143118 This should be a switch statement - - // OR operation - if (fapi2::CHIP_OP_MODIFY_MODE_OR == i_modifyMode) - { - io_modifiedData |= i_origDataBuf; - } - // AND operation - else if (fapi2::CHIP_OP_MODIFY_MODE_AND == i_modifyMode) - { - io_modifiedData &= i_origDataBuf; - } - // Must be XOR operation - else - { - io_modifiedData ^= i_origDataBuf; - } - - return; -} /// /// @brief Platform-level implementation of modifyCfamRegister() @@ -591,189 +124,29 @@ static void platProcess32BitModifyMode( /// @param[in] i_modifyMode The modify mode (or/and/xor). /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. /// -template< TargetType K > -inline ReturnCode platModifyCfamRegister(const Target<K>& i_target, - const uint32_t i_address, - const buffer<uint32_t> i_data, - const fapi2::ChipOpModifyMode i_modifyMode) -{ - FAPI_DBG(ENTER_MRK "platModifyCfamRegister"); - ReturnCode l_rc; - errlHndl_t l_err = NULL; - bool l_traceit = platIsScanTraceEnabled(); - - //TODO: RTC 124195 - Support target::toEcmdString() for SCAN trace - const char* tmpScomStr = "TargetString"; - - do - { - // Can't access cfam engine on master processor - l_err = verifyCfamAccessTarget(i_target,i_address); - if (l_err) - { - FAPI_ERR("platModifyCfamRegister: verifyCfamAccessTarget returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); - - // Get the chip target if l_target is not a chip - TARGETING::Target* l_myChipTarget = NULL; - l_err = getCfamChipTarget(l_target, l_myChipTarget); - if (l_err) - { - FAPI_ERR("platModifyCfamRegister: getCfamChipTarget returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Read current value - // Address needs to be multiply by 4 because register addresses are word - // offsets but the FSI addresses are byte offsets. - // However, we need to preserve the engine's offset of 0x0C00 and 0x1000 - uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); - buffer<uint32_t> l_data = 0; - size_t l_size = sizeof(uint32_t); - l_err = deviceRead(l_myChipTarget, - &l_data(), - l_size, - DEVICE_FSI_ADDRESS(l_addr)); - if (l_err) - { - FAPI_ERR("platModifyCfamRegister: deviceRead returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - // Applying modification - platProcess32BitModifyMode(i_modifyMode, i_data, l_data); - - // Write back - l_err = deviceWrite(l_target, - &l_data(), - l_size, - DEVICE_FSI_ADDRESS(l_addr)); - if (l_err) - { - FAPI_ERR("platModifyCfamRegister: deviceWrite returns error!"); - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - break; - } - - } while (0); - - if (l_rc != fapi2::FAPI2_RC_SUCCESS) - { - FAPI_ERR("platModifyCfamRegister failed - Target %s, Addr %.8X", - tmpScomStr, i_address); - } - - if( l_traceit ) - { - // get string representation of the modify mode - const char * l_pMode = NULL; - - if (i_modifyMode == fapi2::CHIP_OP_MODIFY_MODE_OR) - { - l_pMode = "OR"; - } - else if (i_modifyMode == fapi2::CHIP_OP_MODIFY_MODE_AND) - { - l_pMode = "AND"; - } - else if (i_modifyMode == fapi2::CHIP_OP_MODIFY_MODE_XOR) - { - l_pMode = "XOR"; - } - else - { - l_pMode = "?"; - } - - uint32_t l_data = (uint32_t)i_data; - FAPI_SCAN( "TRACE : MODCFAMREG : %s : %.8X %.8X %s", - tmpScomStr, - i_address, - l_data, - l_pMode ); - } - - FAPI_DBG(EXIT_MRK "platModifyCfamRegister"); - return l_rc; -} +ReturnCode platModifyCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + const buffer<uint32_t> i_data, + const fapi2::ChipOpModifyMode i_modifyMode); //@TODO RTC:126630 getRing is not yet supported #if 0 -/// -/// @brief Platform-level implementation called by fapiGetRing() -/// Hardware procedures writers will not call this function. -/// @Tparam K template parameter, passed in target. -/// @param[in] i_target HW target to operate on. +/// @brief Reads a ring from a chip. +/// @tparam K template parameter, passed in target. +/// @param[in] i_target Target to operate on. /// @param[in] i_address Ring address to read from. -/// @param[out] o_data Buffer that holds ring data read from HW target. +/// @param[out] o_data Buffer that holds data read from HW target. /// @param[in] i_ringMode Ring operation mode. -/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. template< TargetType K > -inline ReturnCode platGetRing(const Target<K>& i_target, - const scanRingId_t i_address, - variable_buffer& o_data, - const RingMode i_ringMode = 0) -{ - FAPI_DBG(ENTER_MRK "platGetRing"); - ReturnCode l_rc; - errlHndl_t l_err = NULL; - - // Extract the component pointer - TARGETING::Target* l_target = - reinterpret_cast<TARGETING::Target*>(i_target.get()); +inline ReturnCode getRing(const Target<K>& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode = 0); - // Output buffer must be set to ring's len by user - uint64_t l_ringLen = o_data.getBitLength(); - uint64_t l_flag = platGetDDScanMode(i_ringMode); - size_t l_size = o_data.getByteLength(); - l_err = deviceRead(l_target, - ecmdDataBufferBaseImplementationHelper::getDataPtr(&o_data), - l_size, - DEVICE_SCAN_ADDRESS(i_address, l_ringLen, l_flag)); - if (l_err) - { - // Add the error log pointer as data to the ReturnCode - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); - } - - FAPI_DBG(EXIT_MRK "platGetRing"); - return l_rc; -} - - -/// @brief Platform-level implementation called by fapiPutRing() -/// Hardware procedures writers will not call this function. -/// @tparam K template parameter, passed in target. -/// @param[in] i_target Target to operate on. -/// @param[in] i_address Ring address to write to. -/// @param[in] i_data Buffer that contains RS4 compressed ring data -/// to write into address -/// @param[in] i_ringMode Ring operation mode. -/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -template< TargetType K > -inline ReturnCode platPutRing(const Target<K>& i_target, - const scanRingId_t i_address, - variable_buffer& i_data, - const RingMode i_ringMode = 0) -{ -} - -/// @brief Platform-level implementation called by fapiModifyRing() +/// @brief Read-modify-write a ring on a chip. /// @tparam K template parameter, passed in target. /// @param[in] i_target Target to operate on. /// @param[in] i_address Ring address to modify. @@ -781,15 +154,13 @@ inline ReturnCode platPutRing(const Target<K>& i_target, /// to be modified. /// @param[in] i_modifyMode The modify mode (or/and/xor) /// @param[in] i_ringMode Ring operation mode. -/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. template< TargetType K > inline ReturnCode modifyRing(const Target<K>& i_target, const scanRingId_t i_address, - variable_buffer& i_data, + const variable_buffer& i_data, const ChipOpModifyMode i_modifyMode, - const RingMode i_ringMode = 0) -{ -} + const RingMode i_ringMode = 0); #endif // End if 0 diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk index c7837e20e..7d1bcb40e 100755 --- a/src/usr/fapi2/fapi2.mk +++ b/src/usr/fapi2/fapi2.mk @@ -39,7 +39,7 @@ OBJS += plat_attribute_service.o OBJS += plat_attr_override_sync.o OBJS += plat_hwp_invoker.o OBJS += target.o - +OBJS += plat_hw_access.o #EKB Objects (mirrored in src/import) OBJS += error_info.o diff --git a/src/usr/fapi2/plat_hw_access.C b/src/usr/fapi2/plat_hw_access.C new file mode 100644 index 000000000..f7fae4b6c --- /dev/null +++ b/src/usr/fapi2/plat_hw_access.C @@ -0,0 +1,672 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/plat_hw_access.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file plat_hw_access.C +/// +/// @brief Implements hardware-access functions for the platform layer. +/// + +#include <stdint.h> +#include <errl/errlentry.H> +#include <devicefw/userif.H> +#include <return_code.H> +#include <buffer.H> +#include <target.H> +#include <target_types.H> +#include <hw_access_def.H> +#include <plat_utils.H> +#include <hwpf_fapi2_reasoncodes.H> +#include <fapi2/plat_hw_access.H> + +//@TODO-RTC:144504-Remove when the attribute shows up +//just use an existing string type for now +#define ATTR_FAPI_NAME_type ATTR_OPAL_MODEL_type + +namespace fapi2 +{ + +//------------------------------------------------------------------------------ +// HW Communication Functions to be implemented at the platform layer. +//------------------------------------------------------------------------------ + +/// @brief Platform-level implementation called by getScom() +ReturnCode platGetScom(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + buffer<uint64_t>& o_data) +{ + ReturnCode l_rc; + errlHndl_t l_err = NULL; + + FAPI_DBG(ENTER_MRK "platGetScom"); + // Note: Trace is placed here in plat code because PPE doesn't support + // trace in common fapi2_hw_access.H + bool l_traceit = platIsScanTraceEnabled(); + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + // Perform SCOM read + size_t l_size = sizeof(uint64_t); + l_err = deviceRead(l_target, + &o_data(), + l_size, + DEVICE_SCOM_ADDRESS(i_address)); + if (l_err) + { + FAPI_ERR("platGetScom: deviceRead returns error!"); + FAPI_ERR("fapiGetScom failed - Target %s, Addr %.16llX", + l_targName, i_address); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + } + + if (l_traceit) + { + uint64_t l_data = (uint64_t)o_data; + FAPI_SCAN("TRACE : GETSCOM : %s : %.16llX %.16llX", + l_targName, + i_address, + l_data); + } + + FAPI_DBG(EXIT_MRK "platGetScom"); + return l_rc; +} + +/// @brief Platform-level implementation called by putScom() +ReturnCode platPutScom(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data) +{ + ReturnCode l_rc; + errlHndl_t l_err = NULL; + + FAPI_DBG(ENTER_MRK "platPutScom"); + // Note: Trace is placed here in plat code because PPE doesn't support + // trace in common fapi2_hw_access.H + bool l_traceit = platIsScanTraceEnabled(); + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + // Perform SCOM write + size_t l_size = sizeof(uint64_t); + uint64_t l_data = static_cast<uint64_t>(i_data); + l_err = deviceWrite(l_target, + &l_data, + l_size, + DEVICE_SCOM_ADDRESS(i_address)); + if (l_err) + { + FAPI_ERR("platPutScom: deviceRead returns error!"); + FAPI_ERR("platPutScom failed - Target %s, Addr %.16llX", + l_targName, i_address); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + } + + if (l_traceit) + { + FAPI_SCAN("TRACE : PUTSCOM : %s : %.16llX %.16llX", + l_targName, + i_address, + l_data); + } + + FAPI_DBG(EXIT_MRK "platPutScom"); + return l_rc; +} + +/// @brief Platform-level implementation called by putScomUnderMask() +ReturnCode platPutScomUnderMask(const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data, + const buffer<uint64_t> i_mask) +{ + ReturnCode l_rc; + errlHndl_t l_err = NULL; + + FAPI_DBG(ENTER_MRK "platPutScomUnderMask"); + // Note: Trace is placed here in plat code because PPE doesn't support + // trace in common fapi2_hw_access.H + bool l_traceit = platIsScanTraceEnabled(); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + do + { + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Get current value from HW + uint64_t l_data = 0; + size_t l_size = sizeof(uint64_t); + l_err = deviceRead(l_target, + &l_data, + l_size, + DEVICE_SCOM_ADDRESS(i_address)); + if (l_err) + { + FAPI_ERR("platPutScomUnderMask: deviceRead returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Calculate new value to write to reg + uint64_t l_inMaskInverted = ~i_mask; // Write mask inverted + uint64_t l_newMask = (i_data & i_mask); // Retain set data bits + + // l_data = current data set bits + l_data &= l_inMaskInverted; + + // l_data = current data set bit + set mask bits + l_data |= l_newMask; + + // Write new value + l_err = deviceWrite(l_target, + &l_data, + l_size, + DEVICE_SCOM_ADDRESS(i_address)); + if (l_err) + { + FAPI_ERR("platPutScomUnderMask: deviceWrite returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + } while (0); + + if (l_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("platPutScomUnderMask failed - Target %s, Addr %.16llX", + l_targName, i_address); + } + + if( l_traceit ) + { + uint64_t l_data = i_data; + uint64_t l_mask = i_mask; + FAPI_SCAN( "TRACE : PUTSCOMMASK : %s : %.16llX %.16llX %.16llX", + l_targName, + i_address, + l_data, + l_mask); + } + + FAPI_DBG(EXIT_MRK "platPutScomUnderMask"); + return l_rc; +} + +/// @brief Verify target of a cfam access +errlHndl_t verifyCfamAccessTarget(const TARGETING::Target* i_target, + const uint32_t i_address) +{ + errlHndl_t l_err = NULL; + + // Can't access cfam engine on the master processor + TARGETING::Target* l_pMasterProcChip = NULL; + TARGETING::targetService(). + masterProcChipTargetHandle( l_pMasterProcChip ); + + if( l_pMasterProcChip == i_target ) + { + FAPI_ERR("verifyCfamAccessTarget: Attempt to access CFAM register %.8X on the master processor chip", + i_address); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_VERIFYCFAMACCESSTARGET + * @reasoncode fapi2::RC_INVALID_TARG_TARGET + * @userdata1 CFAM Address + * @userdata2 HUID of input target + * @devdesc verifyCfamAccessTarget> Attempt to access CFAM + * on the master processor + * @custdesc Internal firmware error + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_VERIFYCFAMACCESSTARGET, + fapi2::RC_INVALID_TARG_TARGET, + i_address, + TARGETING::get_huid(i_target), + true /*SW error*/); + l_err->collectTrace(FAPI_TRACE_NAME); + } + + return l_err; +} + +/// @brief Internal function that gets the chip target for cfam access +errlHndl_t getCfamChipTarget(const TARGETING::Target* i_target, + TARGETING::Target*& o_chipTarget) +{ + errlHndl_t l_err = NULL; + + // Default to input target + o_chipTarget = const_cast<TARGETING::Target*>(i_target); + + // Check to see if this is a chiplet + if (i_target->getAttr<TARGETING::ATTR_CLASS>() == TARGETING::CLASS_UNIT) + { + // Look for its chip parent + TARGETING::PredicateCTM l_chipClass(TARGETING::CLASS_CHIP); + TARGETING::TargetHandleList l_list; + TARGETING::TargetService& l_targetService = TARGETING::targetService(); + (void) l_targetService.getAssociated( + l_list, + i_target, + TARGETING::TargetService::PARENT, + TARGETING::TargetService::ALL, + &l_chipClass); + + if ( l_list.size() == 1 ) + { + o_chipTarget = l_list[0]; + } + else + { + // Something is wrong here, can't have more than one parent chip + FAPI_ERR("getCfamChipTarget: Invalid number of parent chip for this target chiplet - # parent chips %d", l_list.size()); + } + } + return l_err; +} + +/// @brief Platform-level implementation called by getCfamRegister() +ReturnCode platGetCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + buffer<uint32_t>& o_data) +{ + FAPI_DBG(ENTER_MRK "platGetCfamRegister"); + ReturnCode l_rc; + errlHndl_t l_err = NULL; + bool l_traceit = platIsScanTraceEnabled(); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + do + { + // Extract the target pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Get the chip target if l_target is not a chip + TARGETING::Target* l_myChipTarget = NULL; + l_err = getCfamChipTarget(l_target, l_myChipTarget); + if (l_err) + { + FAPI_ERR("platGetCfamRegister: getCfamChipTarget returns error!"); + FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X", + l_targName, i_address); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Can't access cfam engine on master processor + l_err = verifyCfamAccessTarget(i_target,i_address); + if (l_err) + { + FAPI_ERR("platGetCfamRegister: verifyCfamAccessTarget returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Perform CFAM read via FSI + // Address needs to be multiply by 4 because register addresses are + // word offsets but the FSI addresses are byte offsets. + // However, we need to preserve the engine's offset in the top byte + uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); + size_t l_size = sizeof(uint32_t); + l_err = deviceRead(l_myChipTarget, + &o_data(), + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + FAPI_ERR("platGetCfamRegister: deviceRead returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + } while(0); + + if (l_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("fapiGetCfamRegister failed - Target %s, Addr %.8X", + l_targName, i_address); + } + + if( l_traceit ) + { + uint32_t l_data = (uint32_t)o_data; + FAPI_SCAN( "TRACE : GETCFAMREG : %s : %.8X %.8X", + l_targName, + i_address, + l_data); + } + + FAPI_DBG(EXIT_MRK "platGetCfamRegister"); + return l_rc; +} + +/// @brief Platform-level implementation called by putCfamRegister() +ReturnCode platPutCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + const buffer<uint32_t> i_data) +{ + FAPI_DBG(ENTER_MRK "platPutCfamRegister"); + ReturnCode l_rc; + errlHndl_t l_err = NULL; + bool l_traceit = platIsScanTraceEnabled(); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + do + { + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Get the chip target if l_target is not a chip + TARGETING::Target* l_myChipTarget = NULL; + l_err = getCfamChipTarget(l_target, l_myChipTarget); + if (l_err) + { + FAPI_ERR("platPutCfamRegister: getCfamChipTarget returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Can't access cfam engine on master processor + l_err = verifyCfamAccessTarget(i_target,i_address); + if (l_err) + { + FAPI_ERR("platPutCfamRegister: verifyCfamAccessTarget returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Perform CFAM write via FSI + // Address needs to be multiply by 4 because register addresses are word + // offsets but the FSI addresses are byte offsets + // However, we need to preserve the engine's offset in the top byte + uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); + size_t l_size = sizeof(uint32_t); + uint32_t l_data = static_cast<uint32_t>(i_data); + l_err = deviceWrite(l_myChipTarget, + &l_data, + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + FAPI_ERR("platPutCfamRegister: deviceWrite returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + } while (0); + + if (l_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("platPutCfamRegister failed - Target %s, Addr %.8X", + l_targName, i_address); + } + + if( l_traceit ) + { + uint32_t l_data = i_data; + FAPI_SCAN( "TRACE : PUTCFAMREG : %s : %.8X %.8X", + l_targName, + i_address, + l_data); + } + + FAPI_DBG(EXIT_MRK "platPutCfamRegister"); + return l_rc; +} + + +/// @brief Modifying input 32-bit data with the specified mode +void platProcess32BitModifyMode( const ChipOpModifyMode i_modifyMode, + const buffer<uint32_t> i_origDataBuf, + buffer<uint32_t>& io_modifiedData ) +{ + switch( i_modifyMode ) + { + // OR operation + case( fapi2::CHIP_OP_MODIFY_MODE_OR ): + io_modifiedData |= i_origDataBuf; + break; + // AND operation + case( fapi2::CHIP_OP_MODIFY_MODE_AND ): + io_modifiedData &= i_origDataBuf; + break; + // XOR operation + case( fapi2::CHIP_OP_MODIFY_MODE_XOR ): + io_modifiedData ^= i_origDataBuf; + break; + + // deliberately have no default case to catch new modes + // at compile time + } + return; +} + +/// @brief String translation for modify mode +const char* platModeString( const ChipOpModifyMode i_modifyMode ) +{ + const char* l_modString = "???"; + switch( i_modifyMode ) + { + // OR operation + case( fapi2::CHIP_OP_MODIFY_MODE_OR ): + l_modString = "OR"; + break; + // AND operation + case( fapi2::CHIP_OP_MODIFY_MODE_AND ): + l_modString = "AND"; + break; + // XOR operation + case( fapi2::CHIP_OP_MODIFY_MODE_XOR ): + l_modString = "XOR"; + break; + + // deliberately have no default case to catch new modes + // at compile time + } + return l_modString; +} + +/// @brief Platform-level implementation of modifyCfamRegister() +ReturnCode platModifyCfamRegister(const Target<TARGET_TYPE_ALL>& i_target, + const uint32_t i_address, + const buffer<uint32_t> i_data, + const ChipOpModifyMode i_modifyMode) +{ + FAPI_DBG(ENTER_MRK "platModifyCfamRegister"); + ReturnCode l_rc; + errlHndl_t l_err = NULL; + bool l_traceit = platIsScanTraceEnabled(); + const char* l_modeString = platModeString(i_modifyMode); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + do + { + // Can't access cfam engine on master processor + l_err = verifyCfamAccessTarget(i_target,i_address); + if (l_err) + { + FAPI_ERR("platModifyCfamRegister: verifyCfamAccessTarget returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Get the chip target if l_target is not a chip + TARGETING::Target* l_myChipTarget = NULL; + l_err = getCfamChipTarget(l_target, l_myChipTarget); + if (l_err) + { + FAPI_ERR("platModifyCfamRegister: getCfamChipTarget returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Read current value + // Address needs to be multiply by 4 because register addresses are word + // offsets but the FSI addresses are byte offsets. + // However, we need to preserve the engine's offset of 0x0C00 and 0x1000 + uint64_t l_addr = ((i_address & 0x003F) << 2) | (i_address & 0xFF00); + buffer<uint32_t> l_data = 0; + size_t l_size = sizeof(uint32_t); + l_err = deviceRead(l_myChipTarget, + &l_data(), + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + FAPI_ERR("platModifyCfamRegister: deviceRead returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + // Applying modification + platProcess32BitModifyMode(i_modifyMode, i_data, l_data); + + // Write back + l_err = deviceWrite(l_target, + &l_data(), + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + FAPI_ERR("platModifyCfamRegister: deviceWrite returns error!"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + break; + } + + } while (0); + + if (l_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("platModifyCfamRegister failed - Target %s, Addr %.8X", + l_targName, i_address); + } + + if( l_traceit ) + { + uint32_t l_data = (uint32_t)i_data; + FAPI_SCAN( "TRACE : MODCFAMREG : %s : %.8X %.8X %s", + l_targName, + i_address, + l_data, + l_modeString ); + } + + FAPI_DBG(EXIT_MRK "platModifyCfamRegister"); + return l_rc; +} + +//@TODO RTC:126630 getRing is not yet supported + +#if 0 + +/// @brief Platform-level implementation called by fapiGetRing() +ReturnCode platGetRing(const Target<TARGET_TYPE_ALL>& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode) +{ + FAPI_DBG(ENTER_MRK "platGetRing"); + ReturnCode l_rc; + errlHndl_t l_err = NULL; + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Output buffer must be set to ring's len by user + uint64_t l_ringLen = o_data.getBitLength(); + uint64_t l_flag = platGetDDScanMode(i_ringMode); + size_t l_size = o_data.getByteLength(); + l_err = deviceRead(l_target, + ecmdDataBufferBaseImplementationHelper::getDataPtr(&o_data), + l_size, + DEVICE_SCAN_ADDRESS(i_address, l_ringLen, l_flag)); + if (l_err) + { + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + } + + FAPI_DBG(EXIT_MRK "platGetRing"); + return l_rc; +} + + +/// @brief Platform-level implementation called by fapiPutRing() +inline ReturnCode platPutRing(const Target<TARGET_TYPE_ALL>& i_target, + const scanRingId_t i_address, + variable_buffer& i_data, + const RingMode i_ringMode) +{ +} + +/// @brief Platform-level implementation called by fapiModifyRing() +ReturnCode modifyRing(const Target<TARGET_TYPE_ALL>& i_target, + const scanRingId_t i_address, + variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode = 0) +{ +} + +#endif // End if 0 + +// -------------------------------------------------------------------------- +// NOTE: +// No spy access interface as HB doesn't allow spy access. +// -------------------------------------------------------------------------- + + +} // End namespace + diff --git a/src/usr/fapi2/test/fapi2HwpTest.C b/src/usr/fapi2/test/fapi2HwpTest.C index d8fb23c0c..35ce9bdc5 100644 --- a/src/usr/fapi2/test/fapi2HwpTest.C +++ b/src/usr/fapi2/test/fapi2HwpTest.C @@ -28,6 +28,7 @@ #include <fapi2.H> #include <hwpf_fapi2_reasoncodes.H> #include <fapi2TestUtils.H> +#include <p9_hwtests.H> namespace fapi2 { @@ -150,6 +151,66 @@ errlHndl_t fapi2HwpTest() TS_FAIL("Error occured in p9_sample_procedure_proc !!"); } numTests++; + FAPI_INVOKE_HWP(l_errl, p9_scomtest_getscom_fail, fapi2_procTarget); + if(l_errl != NULL) + { + delete l_errl; // delete expected error log + } + else + { + TS_FAIL("No error from p9_scomtest_getscom_fail !!"); + numFails++; + } + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_scomtest_putscom_fail, fapi2_procTarget); + if(l_errl != NULL) + { + delete l_errl; // delete expected error log + } + else + { + TS_FAIL("No error from p9_scomtest_putscom_fail !!"); + numFails++; + } + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_cfamtest_putcfam_fail, fapi2_procTarget); + if(l_errl != NULL) + { + delete l_errl; // delete expected error log + } + else + { + TS_FAIL("No error from p9_cfamtest_putcfam_fail !!"); + numFails++; + } + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_cfamtest_getcfam_fail, fapi2_procTarget); + if(l_errl != NULL) + { + delete l_errl; // delete expected error log + } + else + { + TS_FAIL("No error from p9_cfamtest_getcfam_fail !!"); + numFails++; + } + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_scomtest_getscom_pass, fapi2_procTarget); + if(l_errl) + { + TS_FAIL("Error from p9_scomtest_getscom_pass !!"); + numFails++; + } + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_scomtest_putscom_pass, fapi2_procTarget); + if(l_errl) + { + TS_FAIL("Error from p9_scomtest_putscom_pass !!"); + numFails++; + } + + + numTests++; FAPI_INVOKE_HWP(l_errl, p9_sample_procedure_eq, fapi2_eqTarget, scratchWriteValue); if(l_errl != NULL) { @@ -274,4 +335,4 @@ errlHndl_t fapi2HwpTest() return l_errl; } -}
\ No newline at end of file +} diff --git a/src/usr/fapi2/test/makefile b/src/usr/fapi2/test/makefile index ffebf05e3..5184e449e 100644 --- a/src/usr/fapi2/test/makefile +++ b/src/usr/fapi2/test/makefile @@ -37,6 +37,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/ # Procedures OBJS += p9_sample_procedure.o +OBJS += p9_hwtests.o OBJS += fapi2TestUtils.o TESTS += fapi2Test.H diff --git a/src/usr/fapi2/test/p9_hwtests.C b/src/usr/fapi2/test/p9_hwtests.C new file mode 100644 index 000000000..2f066aa4e --- /dev/null +++ b/src/usr/fapi2/test/p9_hwtests.C @@ -0,0 +1,192 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/p9_hwtests.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +//------------------------------------------------------------------------------ +/// @file p9_hwtests.C +/// +/// @brief These procedures test the fapi2 hw_access interfaces. +//----------------------------------------------------------------------------- + +#include <fapi2.H> + + +fapi2::ReturnCode p9_scomtest_getscom_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint64_t> l_scomdata = 0; + + FAPI_INF("Entering p9_scomtest_getscom_fail..."); + + FAPI_INF("Do getscom on proc target"); + FAPI_TRY(fapi2::getScom(i_target, + 0x11223344, + l_scomdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_scomtest_getscom_fail..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_scomtest_putscom_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint64_t> l_scomdata = 0; + + FAPI_INF("Entering p9_scomtest_putscom_fail..."); + + FAPI_INF("Do getscom on proc target"); + FAPI_TRY(fapi2::putScom(i_target, + 0x22334455, + l_scomdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_scomtest_putscom_fail..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_cfamtest_getcfam_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint32_t> l_cfamdata = 0; + + FAPI_INF("Entering p9_cfamtest_getcfam_fail..."); + + FAPI_INF("Do getcfam on proc target"); + FAPI_TRY(fapi2::getCfamRegister(i_target, + 0x11223344, + l_cfamdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_cfamtest_getcfam_fail..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_cfamtest_putcfam_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint32_t> l_cfamdata = 0; + + FAPI_INF("Entering p9_cfamtest_putcfam_fail..."); + + FAPI_INF("Do getcfam on proc target"); + FAPI_TRY(fapi2::putCfamRegister(i_target, + 0x22334455, + l_cfamdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_cfamtest_putcfam_fail..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_scomtest_getscom_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint64_t> l_scomdata = 0; + + FAPI_INF("Entering p9_scomtest_getscom_pass..."); + + FAPI_INF("Do getscom on proc target"); + FAPI_TRY(fapi2::getScom(i_target, + 0x02010803, //CXA FIR Mask Register + l_scomdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_scomtest_getscom_pass..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_scomtest_putscom_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint64_t> l_scomdata = 0; + + FAPI_INF("Entering p9_scomtest_putscom_pass..."); + + FAPI_INF("Do getscom on proc target"); + FAPI_TRY(fapi2::putScom(i_target, + 0x02010803, //CXA FIR Mask Register + l_scomdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_scomtest_putscom_pass..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_cfamtest_getcfam_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint32_t> l_cfamdata = 0; + + FAPI_INF("Entering p9_cfamtest_getcfam_pass..."); + + FAPI_INF("Do getcfam on proc target"); + FAPI_TRY(fapi2::getCfamRegister(i_target, + 0x1000, //DATA_0 from FSI2PIB + l_cfamdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_cfamtest_getcfam_pass..."); + + return fapi2::current_err; + +} + +fapi2::ReturnCode p9_cfamtest_putcfam_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + fapi2::buffer<uint32_t> l_cfamdata = 0; + + FAPI_INF("Entering p9_cfamtest_putcfam_pass..."); + + FAPI_INF("Do getcfam on proc target"); + FAPI_TRY(fapi2::putCfamRegister(i_target, + 0x1000, //DATA_0 from FSI2PIB + l_cfamdata)); + + fapi_try_exit: + + FAPI_INF("Exiting p9_cfamtest_putcfam_pass..."); + + return fapi2::current_err; + +} diff --git a/src/usr/fapi2/test/p9_hwtests.H b/src/usr/fapi2/test/p9_hwtests.H new file mode 100644 index 000000000..9143e2a64 --- /dev/null +++ b/src/usr/fapi2/test/p9_hwtests.H @@ -0,0 +1,67 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/p9_hwtests.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +//------------------------------------------------------------------------------ +/// @file p9_hwtests.C +/// +/// @brief These procedures test the fapi2 hw_access interfaces. +//------------------------------------------------------------------------------ +#ifndef _P9_HWTESTS_H_ +#define _P9_HWTESTS_H_ + +#include <fapi2.H> + +fapi2::ReturnCode p9_scomtest_getscom_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_scomtest_putscom_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_cfamtest_getcfam_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_cfamtest_putcfam_fail( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_scomtest_getscom_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_scomtest_putscom_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_cfamtest_getcfam_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +fapi2::ReturnCode p9_cfamtest_putcfam_pass( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + + +#endif |