diff options
| author | vanlee <vanlee@us.ibm.com> | 2013-05-14 14:54:27 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-06-12 09:27:05 -0500 |
| commit | 36a701ad9bcbcb3a997d76d11fe38d7726d1c4e7 (patch) | |
| tree | 56c3c21170fe54032aa0cb4ed720f653d5e207a8 | |
| parent | d2a31c241a1a8221bc3932bdfacfc949fb6ec70c (diff) | |
| download | blackbird-hostboot-36a701ad9bcbcb3a997d76d11fe38d7726d1c4e7.tar.gz blackbird-hostboot-36a701ad9bcbcb3a997d76d11fe38d7726d1c4e7.zip | |
Add interface to do bus callout in Hostboot
Change-Id: If169d997a0aba49a81ef834d7806e1e589dc3bff
RTC: 69459
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4503
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
| -rw-r--r-- | src/include/usr/errl/errlentry.H | 15 | ||||
| -rw-r--r-- | src/include/usr/errl/errludcallout.H | 20 | ||||
| -rw-r--r-- | src/include/usr/hwas/common/hwasCallout.H | 34 | ||||
| -rw-r--r-- | src/usr/errl/errlentry.C | 50 | ||||
| -rw-r--r-- | src/usr/errl/errludcallout.C | 33 | ||||
| -rw-r--r-- | src/usr/errl/plugins/errludcallout.H | 62 | ||||
| -rw-r--r-- | src/usr/hwas/common/hwasCallout.C | 131 | ||||
| -rw-r--r-- | src/usr/hwas/hwasPlatCallout.C | 16 |
8 files changed, 306 insertions, 55 deletions
diff --git a/src/include/usr/errl/errlentry.H b/src/include/usr/errl/errlentry.H index a34633df9..96598e03a 100644 --- a/src/include/usr/errl/errlentry.H +++ b/src/include/usr/errl/errlentry.H @@ -423,6 +423,21 @@ public: void removeBackTrace(); /** + * @brief Add a bus callout + * + * @param[in] i_target1 The hardware bus endpoint target1 + * @param[in] i_target2 The hardware bus endpoint target2 + * @param[in] i_busType The hardware bus type + * @param[in] i_priority Priority of the callout + * + * @return void + */ + void addBusCallout(const TARGETING::Target *i_target1, + const TARGETING::Target *i_target2, + const HWAS::busTypeEnum i_busType, + const HWAS::callOutPriority i_priority); + + /** * @brief Add a hardware callout * * @param[in] i_target The hardware target diff --git a/src/include/usr/errl/errludcallout.H b/src/include/usr/errl/errludcallout.H index 9357baa3f..80530edd2 100644 --- a/src/include/usr/errl/errludcallout.H +++ b/src/include/usr/errl/errludcallout.H @@ -52,6 +52,26 @@ class ErrlUserDetailsCallout : public ErrlUserDetails public: /** + * @brief Construct a bus callout user detail + * + * @param[in] i_pTarget1Data The hardware target1 data + * @param[in] i_target1DataLength length of i_pTarget1Data + * @param[in] i_pTarget2Data The hardware target2 data + * @param[in] i_target2DataLength length of i_pTarget2Data + * @param[in] i_busType bus type Enum + * @param[in] i_priority Priority of the callout + * + * @return void + */ + ErrlUserDetailsCallout( + const void *i_pTarget1Data, + uint32_t i_target1DataLength, + const void *i_pTarget2Data, + uint32_t i_target2DataLength, + const HWAS::busTypeEnum i_busType, + const HWAS::callOutPriority i_priority); + + /** * @brief Construct a hardware callout user detail * * @param[in] i_pTargetData The hardware target data diff --git a/src/include/usr/hwas/common/hwasCallout.H b/src/include/usr/hwas/common/hwasCallout.H index 674dc5d34..c82e3e218 100644 --- a/src/include/usr/hwas/common/hwasCallout.H +++ b/src/include/usr/hwas/common/hwasCallout.H @@ -122,9 +122,20 @@ enum callOutPriority SRCI_PRIORITY_HIGH = 6 }; +enum busTypeEnum +{ + FSI_BUS_TYPE = 1, + DMI_BUS_TYPE = 2, + A_BUS_TYPE = 3, + X_BUS_TYPE = 4, + I2C_BUS_TYPE = 5, + PSI_BUS_TYPE = 6 +}; + // const uint8_t HW_CALLOUT = 0x01; const uint8_t PROCEDURE_CALLOUT = 0x02; +const uint8_t BUS_CALLOUT = 0x03; const uint8_t TARGET_IS_SENTINEL = 0xF0; @@ -142,6 +153,9 @@ typedef struct callout_ud struct { // callout epubProcedureID procedure; // uint32_t }; + struct { + busTypeEnum busType; + }; }; } callout_ud_t; @@ -199,6 +213,26 @@ errlHndl_t platHandleHWCallout( errlHndl_t i_errl, GARD_ErrorType i_gardErrorType); +/** + * @brief platform specific code to handle a bus callout that has been + * found in an errlog + * + * @param[in] i_pTarget1 target endpoint1 + * @param[in] i_pTarget2 target endpoint2 + * @param[in] i_busType bus type Enum + * @param[in] i_priority Enum indicating the priority of the callout + * @param[in] i_errl errlHnld for this errlog + * + * @return errlHndl_t valid errlHndl_t handle if there was an error, + * NULL if no errors; + */ +errlHndl_t platHandleBusCallout( + TARGETING::Target *i_pTarget1, + TARGETING::Target *i_pTarget2, + busTypeEnum i_busType, + callOutPriority i_priority, + errlHndl_t i_errl); + #endif // not PARSER }; // end namespace diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C index 62d47e598..fd9d76857 100644 --- a/src/usr/errl/errlentry.C +++ b/src/usr/errl/errlentry.C @@ -299,6 +299,56 @@ void ErrlEntry::removeBackTrace() //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// +void ErrlEntry::addBusCallout(const TARGETING::Target *i_target_endp1, + const TARGETING::Target *i_target_endp2, + const HWAS::busTypeEnum i_busType, + const HWAS::callOutPriority i_priority) +{ + TRACFCOMP(g_trac_errl, ENTER_MRK"addBusCallout(%p, %p, %d, 0x%x)", + i_target_endp1, i_target_endp2, i_busType, i_priority); + + TARGETING::EntityPath ep1, ep2; + const void *pData1, *pData2; + uint32_t size1, size2; + + if (i_target_endp1 == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) + { + size1 = sizeof(HWAS::TARGET_IS_SENTINEL); + pData1 = &HWAS::TARGET_IS_SENTINEL; + } + else + { // we got a non MASTER_SENTINEL target, therefore the targeting + // module is loaded, therefore we can make this call. + ep1 = i_target_endp1->getAttr<TARGETING::ATTR_PHYS_PATH>(); + size1 = TARGETING::EntityPath::MAX_PATH_ELEMENTS - ep1.size(); + size1 *= sizeof(TARGETING::EntityPath::PathElement); + size1 = sizeof(ep1) - size1; + pData1 = &ep1; + } + + if (i_target_endp2 == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) + { + size2 = sizeof(HWAS::TARGET_IS_SENTINEL); + pData2 = &HWAS::TARGET_IS_SENTINEL; + } + else + { // we got a non MASTER_SENTINEL target, therefore the targeting + // module is loaded, therefore we can make this call. + ep2 = i_target_endp2->getAttr<TARGETING::ATTR_PHYS_PATH>(); + size2 = TARGETING::EntityPath::MAX_PATH_ELEMENTS - ep2.size(); + size2 *= sizeof(TARGETING::EntityPath::PathElement); + size2 = sizeof(ep2) - size2; + pData2 = &ep2; + } + + ErrlUserDetailsCallout( pData1, size1, pData2, size2, i_busType, + i_priority).addToLog(this); + +} // addBusCallout + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// void ErrlEntry::addHwCallout(const TARGETING::Target *i_target, const HWAS::callOutPriority i_priority, const HWAS::DeconfigEnum i_deconfigState, diff --git a/src/usr/errl/errludcallout.C b/src/usr/errl/errludcallout.C index 3fa43078e..c206a628a 100644 --- a/src/usr/errl/errludcallout.C +++ b/src/usr/errl/errludcallout.C @@ -38,6 +38,39 @@ namespace ERRORLOG extern TARGETING::TARG_TD_t g_trac_errl; //------------------------------------------------------------------------------ +// Bus callout +ErrlUserDetailsCallout::ErrlUserDetailsCallout( + const void *i_pTarget1Data, + uint32_t i_target1DataLength, + const void *i_pTarget2Data, + uint32_t i_target2DataLength, + const HWAS::busTypeEnum i_busType, + const HWAS::callOutPriority i_priority) +{ + TRACDCOMP(g_trac_errl, "BusCallout entry"); + + // Set up ErrlUserDetails instance variables + iv_CompId = ERRL_COMP_ID; + iv_Version = 1; + iv_SubSection = ERRL_UDT_CALLOUT; + + uint32_t pDataLength = sizeof(HWAS::callout_ud_t) + + i_target1DataLength + i_target2DataLength; + HWAS::callout_ud_t *pData; + pData = reinterpret_cast<HWAS::callout_ud_t *> + (reallocUsrBuf(pDataLength)); + pData->type = HWAS::BUS_CALLOUT; + pData->busType = i_busType; + pData->priority = i_priority; + char * l_ptr = (char *)(++pData); + memcpy(l_ptr, i_pTarget1Data, i_target1DataLength); + memcpy(l_ptr + i_target1DataLength, i_pTarget2Data, i_target2DataLength); + + TRACDCOMP(g_trac_errl, "BusCallout exit; pDataLength %d", pDataLength); + +} // Bus callout + +//------------------------------------------------------------------------------ // Hardware callout ErrlUserDetailsCallout::ErrlUserDetailsCallout( const void *i_pTargetData, diff --git a/src/usr/errl/plugins/errludcallout.H b/src/usr/errl/plugins/errludcallout.H index a4d7590a8..6d27391a9 100644 --- a/src/usr/errl/plugins/errludcallout.H +++ b/src/usr/errl/plugins/errludcallout.H @@ -73,6 +73,37 @@ public: switch (pData->type) { + case HWAS::BUS_CALLOUT: + { + char * l_busType; + switch (ntohl(pData->busType)) + { + case HWAS::FSI_BUS_TYPE: l_busType = "FSI BUS"; + break; + case HWAS::DMI_BUS_TYPE: l_busType = "DMI BUS"; + break; + case HWAS::A_BUS_TYPE: l_busType = "A BUS"; + break; + case HWAS::X_BUS_TYPE: l_busType = "X BUS"; + break; + case HWAS::I2C_BUS_TYPE: l_busType = "I2C BUS"; + break; + case HWAS::PSI_BUS_TYPE: l_busType = "PSI BUS"; + break; + default: l_busType = "UNKNOWN BUS"; + break; + } + + i_parser.PrintString( "Callout Bus type", l_busType ); + + // what follows the pData structure is Two entity paths + // print them out + uint8_t *l_ptr = reinterpret_cast<uint8_t *>(pData+1); + printEntityPath(l_ptr, i_parser, "Target1"); + printEntityPath(l_ptr, i_parser, "Target2"); + + break; // BUS_CALLOUT + } case HWAS::HW_CALLOUT: { i_parser.PrintString( "Callout type", "Hardware Callout"); @@ -80,17 +111,7 @@ public: // what follows the pData structure is an entity path // print it first uint8_t *l_ptr = reinterpret_cast<uint8_t *>(pData+1); - if (*l_ptr == 0xF0) - { - i_parser.PrintString("Target", - "MASTER_PROCESSOR_CHIP_TARGET_SENTINEL"); - } - else - { - char outString[128]; - l_ptr = errlud_parse_entity_path(l_ptr, outString); - i_parser.PrintString("Target", outString); - } + printEntityPath(l_ptr, i_parser, "Target"); i_parser.PrintNumber( "CPU id", "0x%X", ntohl(pData->cpuid) ); @@ -209,6 +230,25 @@ private: ErrlUserDetailsParserCallout(const ErrlUserDetailsParserCallout &); ErrlUserDetailsParserCallout & operator=( const ErrlUserDetailsParserCallout &); + + void printEntityPath(uint8_t * & io_ptr, + ErrlUsrParser & i_parser, + const char * i_label) const + { + if (*io_ptr == HWAS::TARGET_IS_SENTINEL) + { + i_parser.PrintString( i_label, + "MASTER_PROCESSOR_CHIP_TARGET_SENTINEL"); + ++io_ptr; + } + else + { + char outString[128]; + io_ptr = errlud_parse_entity_path(io_ptr, outString); + i_parser.PrintString(i_label, outString); + } + } + }; } diff --git a/src/usr/hwas/common/hwasCallout.C b/src/usr/hwas/common/hwasCallout.C index 64cc7b92c..f82130a94 100644 --- a/src/usr/hwas/common/hwasCallout.C +++ b/src/usr/hwas/common/hwasCallout.C @@ -45,6 +45,56 @@ namespace HWAS using namespace HWAS::COMMON; +bool retrieveTarget(uint8_t * & io_uData, + TARGETING::Target * & o_pTarget, errlHndl_t i_errl) +{ + bool l_err = false; + + // data is either a token indicating it's the + // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL + // or it's the EntityPath - getAttr<TARGETING::ATTR_PHYS_PATH>() + if (*io_uData != TARGET_IS_SENTINEL) + { + // convert the EntityPath to a Target pointer + TARGETING::EntityPath ep, *ep_ptr; + uint32_t size; + ep_ptr = (TARGETING::EntityPath *)io_uData; + size = TARGETING::EntityPath::MAX_PATH_ELEMENTS - ep_ptr->size(); + size *= sizeof(TARGETING::EntityPath::PathElement); + size = sizeof(ep) - size; + memcpy(&ep, io_uData, size); + o_pTarget = TARGETING::targetService().toTarget(ep); + io_uData += size; + + if (unlikely(o_pTarget == NULL)) + { // only happen if we have a corrupt errlog or targeting. + HWAS_ERR("HW callout; o_pTarget was NULL!!!"); + + /*@ + * @errortype + * @moduleid HWAS::MOD_PROCESS_CALLOUT + * @reasoncode HWAS::RC_INVALID_TARGET + * @devdesc Invalid Target encountered in + * processing of HW callout + * @userdata1 callout errlog PLID + */ + errlHndl_t errl = hwasError( + ERRL_SEV_INFORMATIONAL, + HWAS::MOD_PROCESS_CALLOUT, + HWAS::RC_INVALID_TARGET, + i_errl->plid()); + errlCommit(errl, HWAS_COMP_ID); + l_err = true; + } + } + else + { // convert this to the real master processor + TARGETING::targetService().masterProcChipTargetHandle(o_pTarget); + io_uData += sizeof(HWAS::TARGET_IS_SENTINEL); + } + return l_err; +} + void processCallout(errlHndl_t i_errl, uint8_t *i_pData, uint64_t i_Size) @@ -58,55 +108,24 @@ void processCallout(errlHndl_t i_errl, { case (HW_CALLOUT): { - TARGETING::Target *pTarget; + TARGETING::Target *pTarget = NULL; + uint8_t * l_uData = (uint8_t *)(pCalloutUD + 1); + bool l_err = retrieveTarget(l_uData, pTarget, i_errl); - // data after the pCalloutUD structure is either a token - // indicating it's the MASTER_PROCESSOR_CHIP_TARGET_SENTINEL - // or it's the EntityPath - getAttr<TARGETING::ATTR_PHYS_PATH>() - if (*((uint8_t *)(pCalloutUD + 1)) != TARGET_IS_SENTINEL) + if (!l_err) { - // convert the EntityPath to a Target pointer - TARGETING::EntityPath ep; - memcpy(&ep, (pCalloutUD + 1), sizeof(ep)); - pTarget = TARGETING::targetService().toTarget(ep); - - if (unlikely(pTarget == NULL)) - { // only happen if we have a corrupt errlog or targeting. - HWAS_ERR("HW callout; pTarget was NULL!!!"); - - /*@ - * @errortype - * @moduleid HWAS::MOD_PROCESS_CALLOUT - * @reasoncode HWAS::RC_INVALID_TARGET - * @devdesc Invalid Target encountered in - * processing of HW callout - * @userdata1 callout errlog PLID - */ - errlHndl_t errl = hwasError( - ERRL_SEV_INFORMATIONAL, - HWAS::MOD_PROCESS_CALLOUT, - HWAS::RC_INVALID_TARGET, - i_errl->plid()); + errlHndl_t errl = platHandleHWCallout( + pTarget, + pCalloutUD->priority, + pCalloutUD->deconfigState, + i_errl, + pCalloutUD->gardErrorType); + if (errl) + { + HWAS_ERR("HW callout: error from platHandlHWCallout"); errlCommit(errl, HWAS_COMP_ID); - break; } } - else - { // convert this to the real master processor - TARGETING::targetService().masterProcChipTargetHandle(pTarget); - } - - errlHndl_t errl = platHandleHWCallout( - pTarget, - pCalloutUD->priority, - pCalloutUD->deconfigState, - i_errl, - pCalloutUD->gardErrorType); - if (errl) - { - HWAS_ERR("HW callout: error from platHandlHWCallout"); - errlCommit(errl, HWAS_COMP_ID); - } break; } // HW_CALLOUT case (PROCEDURE_CALLOUT): @@ -123,6 +142,30 @@ void processCallout(errlHndl_t i_errl, } break; } + case (BUS_CALLOUT): + { + TARGETING::Target *pTarget1 = NULL; + TARGETING::Target *pTarget2 = NULL; + + uint8_t * l_targetData = (uint8_t *)(pCalloutUD + 1); + bool l_err1 = retrieveTarget(l_targetData, pTarget1, i_errl); + bool l_err2 = retrieveTarget(l_targetData, pTarget2, i_errl); + + if (!l_err1 && !l_err2) + { + errlHndl_t errl = platHandleBusCallout( + pTarget1, pTarget2, + pCalloutUD->busType, + pCalloutUD->priority, + i_errl); + if (errl) + { + HWAS_ERR("HW callout: error from platHandlBusCallout"); + errlCommit(errl, HWAS_COMP_ID); + } + } + break; + } // BUS_CALLOUT default: { HWAS_ERR("bad data in Callout UD %x", pCalloutUD->type); diff --git a/src/usr/hwas/hwasPlatCallout.C b/src/usr/hwas/hwasPlatCallout.C index 10d84e877..1b91c4e5e 100644 --- a/src/usr/hwas/hwasPlatCallout.C +++ b/src/usr/hwas/hwasPlatCallout.C @@ -116,4 +116,20 @@ errlHndl_t platHandleHWCallout( return errl; } +//****************************************************************************** +// platHandleBusCallout +//****************************************************************************** +errlHndl_t platHandleBusCallout( + TARGETING::Target *i_pTarget1, + TARGETING::Target *i_pTarget2, + busTypeEnum i_busType, + callOutPriority i_priority, + errlHndl_t i_errl) +{ + errlHndl_t errl = NULL; + + // hostboot does not handle or do any action for bus callouts + return errl; +} + } // namespace HWAS |

