diff options
-rw-r--r-- | src/include/usr/scom/runtime/rt_scomif.H | 49 | ||||
-rw-r--r-- | src/include/usr/scom/scomif.H | 2 | ||||
-rw-r--r-- | src/include/usr/scom/scomreasoncodes.H | 2 | ||||
-rw-r--r-- | src/usr/scom/runtime/makefile | 3 | ||||
-rw-r--r-- | src/usr/scom/runtime/rt_scom.C | 310 | ||||
-rw-r--r-- | src/usr/xscom/runtime/rt_xscom.C | 289 |
6 files changed, 382 insertions, 273 deletions
diff --git a/src/include/usr/scom/runtime/rt_scomif.H b/src/include/usr/scom/runtime/rt_scomif.H new file mode 100644 index 000000000..4039f2827 --- /dev/null +++ b/src/include/usr/scom/runtime/rt_scomif.H @@ -0,0 +1,49 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/scom/runtime/rt_scomif.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* [+] 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 */ +#ifndef __RT_SCOMIF_H +#define __RT_SCOMIF_H + +#include <devicefw/driverif.H> + +namespace SCOM +{ + +/** + * @brief This function sends the scom op to the Hypervisor + * + * @param[in] i_opType Scom operation type + * @param[in] i_target Scom target + * @param[in] i_scomAddr Scom address + * @param[in|out] io_buffer Pointer to scom data + * @return errlHndl_t + */ +errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType, + TARGETING::Target * i_target, + uint64_t i_scomAddr, + void * io_buffer); + +}; // end namespace SCOM + +#endif // end __RT_SCOMIF_H diff --git a/src/include/usr/scom/scomif.H b/src/include/usr/scom/scomif.H index 5df08120d..da7227735 100644 --- a/src/include/usr/scom/scomif.H +++ b/src/include/usr/scom/scomif.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ diff --git a/src/include/usr/scom/scomreasoncodes.H b/src/include/usr/scom/scomreasoncodes.H index 5f52f2a9e..b6fb9816b 100644 --- a/src/include/usr/scom/scomreasoncodes.H +++ b/src/include/usr/scom/scomreasoncodes.H @@ -40,6 +40,7 @@ namespace SCOM SCOM_DO_FORM_1_INDIRECT_SCOM = 0x06, SCOM_HANDLE_SPECIAL_WAKEUP = 0x07, SCOM_TRANSLATE_CENTAUR = 0x08, + SCOM_RT_SEND_SCOM_TO_HYP = 0x09, }; enum scomReasonCode @@ -64,6 +65,7 @@ namespace SCOM SCOM_RUNTIME_INTERFACE_ERR = SCOM_COMP_ID | 0x12, SCOM_SPCWKUP_COUNT_ERR = SCOM_COMP_ID | 0x13, SCOM_CEN_TRANS_INVALID_TYPE = SCOM_COMP_ID | 0x14, + SCOM_RUNTIME_HYP_ERR = SCOM_COMP_ID | 0x15, }; enum UserDetailsTypes diff --git a/src/usr/scom/runtime/makefile b/src/usr/scom/runtime/makefile index af572116b..7717b9473 100644 --- a/src/usr/scom/runtime/makefile +++ b/src/usr/scom/runtime/makefile @@ -29,7 +29,8 @@ MODULE = scom_rt #include common ojects between hostboot and runtime hostboot include ../scom.mk -#include unique object modules - currently none +#include unique object modules +OBJS += rt_scom.o SUBDIRS += test.d diff --git a/src/usr/scom/runtime/rt_scom.C b/src/usr/scom/runtime/rt_scom.C new file mode 100644 index 000000000..26bac2898 --- /dev/null +++ b/src/usr/scom/runtime/rt_scom.C @@ -0,0 +1,310 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/scom/runtime/rt_scom.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2013,2018 */ +/* [+] 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 */ + +#include <devicefw/driverif.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <scom/scomreasoncodes.H> +#include <scom/scomif.H> +#include <runtime/interface.h> +#include <runtime/rt_targeting.H> +#include <xscom/piberror.H> + +// Trace definition +extern trace_desc_t* g_trac_scom; + +namespace SCOM +{ + +struct RcPibErrMap +{ + PIB::PibError iv_Piberr; + HbrtRcPiberr_t iv_Common; + int iv_Opal; // note : opal values taken from opal-api.h +}; + + +const RcPibErrMap pibErrTbl[] = +{ + // 001 + PIB::PIB_RESOURCE_OCCUPIED, + HBRT_RC_PIBERR_001_BUSY, + -12, // OPAL_XSCOM_BUSY + + // 002 + PIB::PIB_CHIPLET_OFFLINE, + HBRT_RC_PIBERR_010_OFFLINE, + -14, // OPAL_XSCOM_CHIPLET_OFF + + // 003 + PIB::PIB_PARTIAL_GOOD, + HBRT_RC_PIBERR_011_PGOOD, + -25, // OPAL_XSCOM_PARTIAL_GOOD + + // 004 + PIB::PIB_INVALID_ADDRESS, + HBRT_RC_PIBERR_100_INVALIDADDR, + -26, // OPAL_XSCOM_ADDR_ERROR + + // 005 + PIB::PIB_CLOCK_ERROR, + HBRT_RC_PIBERR_101_CLOCKERR, + -27, // OPAL_XSCOM_CLOCK_ERROR + + // 006 + PIB::PIB_PARITY_ERROR, + HBRT_RC_PIBERR_110_PARITYERR, + -28, // OPAL_XSCOM_PARITY_ERROR + + // 007 + PIB::PIB_TIMEOUT, + HBRT_RC_PIBERR_111_TIMEOUT, + -29 // OPAL_XSCOM_TIMEOUT +}; + + +/** + * @brief Internal routine that translates a HBRT return code to a + * PIB error code + * + * @param[in] i_rc HBRT return code, + * @return PibError, PIB::PIB_NO_ERROR if not translatable + * + */ +PIB::PibError HbrtRcToPibErr( HbrtRcPiberr_t i_rc ) +{ + int l_entryCnt = sizeof(pibErrTbl) / sizeof(RcPibErrMap); + PIB::PibError l_rv = PIB::PIB_NO_ERROR; + + for // loop thru the xlate table + ( int i = 0; + i < l_entryCnt; + i++ ) + { + if // matching entry found + ( pibErrTbl[i].iv_Common == i_rc ) + { + // extract translation value + l_rv = pibErrTbl[i].iv_Piberr; + break; + } + } + + return( l_rv ); +} + + +/** + * @brief Internal routine that translates an OPAL return code to a + * PIB error code + * + * @param[in] i_rc OPAL return code + * @return PibError, PIB::PIB_NO_ERROR if not translatable + */ +PIB::PibError OpalRcToPibErr( int i_rc ) +{ + int l_entryCnt = sizeof(pibErrTbl) / sizeof(RcPibErrMap); + PIB::PibError l_rv = PIB::PIB_NO_ERROR; + + for // loop thru the xlate table + ( int i = 0; + i < l_entryCnt; + i++ ) + { + if // matching entry found + ( pibErrTbl[i].iv_Opal == i_rc ) + { + // extract translation value + l_rv = pibErrTbl[i].iv_Piberr; + break; + } + } + + return( l_rv ); +} + + +/** + * @brief Send the scom to the hypervisor + * + * @param[in] i_opType Operation type, see driverif.H + * @param[in] i_target Scom target + * @param[in] i_scomAddr Scom address + * @param[in/out] io_buffer Read: Pointer to output data storage + * Write: Pointer to input data storage + * @return errlHndl_t + */ +errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType, + TARGETING::Target * i_target, + uint64_t i_scomAddr, + void * io_buffer) +{ + errlHndl_t l_err = nullptr; + int rc = 0; + + do + { + // Convert target to something Sapphire understands + RT_TARG::rtChipId_t proc_id = 0; + l_err = RT_TARG::getRtTarget(i_target, + proc_id); + if(l_err) + { + break; + } + + if(g_hostInterfaces != nullptr && + g_hostInterfaces->scom_read != nullptr && + g_hostInterfaces->scom_write != nullptr) + { + + if(i_opType == DeviceFW::READ) + { + rc = + g_hostInterfaces->scom_read(proc_id, + i_scomAddr, + io_buffer + ); + } + else if (i_opType == DeviceFW::WRITE) + { + rc = + g_hostInterfaces->scom_write(proc_id, + i_scomAddr, + io_buffer + ); + } + + if(rc) + { + TRACFCOMP(g_trac_scom,ERR_MRK + "Hypervisor scom read/write failed. " + "rc 0x%X target 0x%llX proc_id 0x%llX addr 0x%llX r/w %d", + rc, get_huid(i_target), proc_id, i_scomAddr, i_opType); + + // convert rc to error log + /*@ + * @errortype + * @moduleid SCOM_RT_SEND_SCOM_TO_HYP + * @reasoncode SCOM_RUNTIME_HYP_ERR + * @userdata1[0:31] Hypervisor return code + * @userdata1[32:63] SCOM Op Type + * @userdata2 SCOM address + * @devdesc SCOM access error + */ + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + SCOM_RT_SEND_SCOM_TO_HYP, + SCOM_RUNTIME_HYP_ERR, + TWO_UINT32_TO_UINT64( + rc, + i_opType), + i_scomAddr); + + // attempt to translate rc into a pib error assuming + // the rc is in common format + HbrtRcPiberr_t l_commonRc = static_cast<HbrtRcPiberr_t>(rc); + PIB::PibError l_piberr = HbrtRcToPibErr( l_commonRc ); + + if // input was translated to a PIB error code + ( l_piberr != PIB::PIB_NO_ERROR ) + { + // (translation was successful) + TRACFCOMP(g_trac_scom,ERR_MRK"RC to PIB Err: PIBERR 0x%X",l_piberr); + } + + else if // input was common format, but not a PIB error + ( l_commonRc == HBRT_RC_SOMEOTHERERROR ) + { + // (already translated to PIB::PIB_NO_ERROR, + // no more translation needed) + TRACFCOMP(g_trac_scom,ERR_MRK"RC to PIB Err: PIB_NO_ERROR"); + } + + else if // legacy opal + ( TARGETING::is_sapphire_load() ) + { + // attempt to translate rc into a pib error assuming + // the rc is in old opal format + // this preserves legacy behavior to avoid co-req/pre-req + l_piberr = OpalRcToPibErr( rc ); + TRACFCOMP(g_trac_scom,ERR_MRK"RC to PIB Err: OPAL 0x%X",l_piberr); + } + + else if // legacy phyp + ( TARGETING::is_phyp_load() ) + { + // default to OFFLINE for now to trigger + // the multicast workaround in scom.C + l_piberr = PIB::PIB_CHIPLET_OFFLINE; + TRACFCOMP(g_trac_scom,ERR_MRK"RC to PIB Err: PIB_CHIPLET_OFFLINE"); + } + + else + { + // our testcases respond back with the + // pib error directly + if( rc > 0 ) + { + l_piberr = static_cast<PIB::PibError>(rc); + TRACFCOMP(g_trac_scom,ERR_MRK"RC to PIB Err: RC 0x%X",l_piberr); + } + } + + PIB::addFruCallouts(i_target, + l_piberr, + i_scomAddr, + l_err); + + // Note: no trace buffer available at runtime + } + } + else // Hypervisor interface not initialized + { + TRACFCOMP(g_trac_scom,ERR_MRK"Hypervisor scom interface not linked"); + /*@ + * @errortype + * @moduleid SCOM_RT_SEND_SCOM_TO_HYP + * @reasoncode SCOM_RUNTIME_INTERFACE_ERR + * @userdata1 SCOM Op Type + * @userdata2 SCOM address + * @devdesc SCOM runtime interface not linked. + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + SCOM_RT_SEND_SCOM_TO_HYP, + SCOM_RUNTIME_INTERFACE_ERR, + i_opType, + i_scomAddr); + + l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); + } + + } while(0); + + return l_err; +} + +}; // end namespace SCOM diff --git a/src/usr/xscom/runtime/rt_xscom.C b/src/usr/xscom/runtime/rt_xscom.C index 99ef427fc..93e011864 100644 --- a/src/usr/xscom/runtime/rt_xscom.C +++ b/src/usr/xscom/runtime/rt_xscom.C @@ -26,16 +26,9 @@ #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> -#include <errl/errludlogregister.H> -#include <runtime/interface.h> -#include <errl/errludtarget.H> -#include <runtime/rt_targeting.H> -#include <xscom/piberror.H> +#include <scom/runtime/rt_scomif.H> // Trace definition trace_desc_t* g_trac_xscom = NULL; @@ -65,114 +58,6 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD, TARGETING::TYPE_MEMBUF, xscomPerformOp); -struct RcPibErrMap -{ - PIB::PibError iv_Piberr; - HbrtRcPiberr_t iv_Common; - int iv_Opal; // note : opal values taken from opal-api.h -}; - - -const RcPibErrMap pibErrTbl[] = -{ - // 001 - PIB::PIB_RESOURCE_OCCUPIED, - HBRT_RC_PIBERR_001_BUSY, - -12, // OPAL_XSCOM_BUSY - - // 002 - PIB::PIB_CHIPLET_OFFLINE, - HBRT_RC_PIBERR_010_OFFLINE, - -14, // OPAL_XSCOM_CHIPLET_OFF - - // 003 - PIB::PIB_PARTIAL_GOOD, - HBRT_RC_PIBERR_011_PGOOD, - -25, // OPAL_XSCOM_PARTIAL_GOOD - - // 004 - PIB::PIB_INVALID_ADDRESS, - HBRT_RC_PIBERR_100_INVALIDADDR, - -26, // OPAL_XSCOM_ADDR_ERROR - - // 005 - PIB::PIB_CLOCK_ERROR, - HBRT_RC_PIBERR_101_CLOCKERR, - -27, // OPAL_XSCOM_CLOCK_ERROR - - // 006 - PIB::PIB_PARITY_ERROR, - HBRT_RC_PIBERR_110_PARITYERR, - -28, // OPAL_XSCOM_PARITY_ERROR - - // 007 - PIB::PIB_TIMEOUT, - HBRT_RC_PIBERR_111_TIMEOUT, - -29 // OPAL_XSCOM_TIMEOUT -}; - - -/** - * @brief Internal routine that translates a HBRT return code to a - * PIB error code - * - * @param[in] i_rc HBRT return code, - * @return PibError, PIB::PIB_NO_ERROR if not translatable - * - */ -PIB::PibError HbrtRcToPibErr( HbrtRcPiberr_t i_rc ) -{ - int l_entryCnt = sizeof(pibErrTbl) / sizeof(RcPibErrMap); - PIB::PibError l_rv = PIB::PIB_NO_ERROR; - - for // loop thru the xlate table - ( int i = 0; - i < l_entryCnt; - i++ ) - { - if // matching entry found - ( pibErrTbl[i].iv_Common == i_rc ) - { - // extract translation value - l_rv = pibErrTbl[i].iv_Piberr; - break; - } - } - - return( l_rv ); -} - - -/** - * @brief Internal routine that translates an OPAL return code to a - * PIB error code - * - * @param[in] i_rc OPAL return code - * @return PibError, PIB::PIB_NO_ERROR if not translatable - */ -PIB::PibError OpalRcToPibErr( int i_rc ) -{ - int l_entryCnt = sizeof(pibErrTbl) / sizeof(RcPibErrMap); - PIB::PibError l_rv = PIB::PIB_NO_ERROR; - - for // loop thru the xlate table - ( int i = 0; - i < l_entryCnt; - i++ ) - { - if // matching entry found - ( pibErrTbl[i].iv_Opal == i_rc ) - { - // extract translation value - l_rv = pibErrTbl[i].iv_Piberr; - break; - } - } - - return( l_rv ); -} - - /** * @brief Internal routine that verifies the validity of input parameters * for an XSCOM access. @@ -183,7 +68,7 @@ PIB::PibError OpalRcToPibErr( int i_rc ) * @param[in/out] i_buffer Read: Pointer to output data storage * Write: Pointer to input data storage * @param[in/out] i_buflen Input: size of io_buffer (in bytes) - * Output: + * Output: * Read: Size of output data * Write: Size of data written * @param[in] i_args This is an argument list for DD framework. @@ -195,14 +80,6 @@ errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType, const TARGETING::Target* i_target, const void* i_buffer, const size_t& i_buflen, - const va_list i_args); - - - -errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType, - const TARGETING::Target* i_target, - const void* i_buffer, - const size_t& i_buflen, const va_list i_args){ errlHndl_t l_err = NULL; @@ -256,149 +133,23 @@ errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType, return l_err; } + /** - * @brief Do the scom operation + * @brief Complete the xscom op + * + * @param[in] i_opType Operation type, see driverif.H + * @param[in] i_target XSCom target + * @param[in/out] io_buffer Read: Pointer to output data storage + * Write: Pointer to input data storage + * @param[in/out] io_buflen Input: size of io_buffer (in bytes) + * Output: Read: Size of output data + * Write: Size of data written + * @param[in] i_accessType Access type + * @param[in] i_args This is an argument list for DD framework. + * In this function, there's only one argument, + * which is the MMIO XSCom address + * @return errlHndl_t */ -errlHndl_t xScomDoOp(DeviceFW::OperationType i_ioType, - TARGETING::Target * i_target, - uint64_t i_scomAddr, - void * io_buffer) -{ - errlHndl_t l_err = NULL; - int rc = 0; - RT_TARG::rtChipId_t proc_id = 0; - - // Convert target to something Sapphire understands - l_err = RT_TARG::getRtTarget(i_target, - proc_id); - - if(l_err) - { - return l_err; - } - - if(g_hostInterfaces != NULL && - g_hostInterfaces->scom_read != NULL && - g_hostInterfaces->scom_write != NULL) - { - - if(i_ioType == DeviceFW::READ) - { - rc = - g_hostInterfaces->scom_read(proc_id, - i_scomAddr, - io_buffer - ); - } - else if (i_ioType == DeviceFW::WRITE) - { - rc = - g_hostInterfaces->scom_write(proc_id, - i_scomAddr, - io_buffer - ); - } - - if(rc) - { - TRACFCOMP(g_trac_xscom,ERR_MRK - "Hypervisor scom read/write failed. " - "rc 0x%X target 0x%llX proc_id 0x%llX addr 0x%llX r/w %d", - rc, get_huid(i_target), proc_id, i_scomAddr, i_ioType); - - // convert rc to error log - /*@ - * @errortype - * @moduleid XSCOM_RT_DO_OP - * @reasoncode XSCOM_RUNTIME_ERR - * @userdata1 Hypervisor return code - * @userdata2 SCOM address - * @devdesc XSCOM access error - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, - XSCOM_RT_DO_OP, - XSCOM_RUNTIME_ERR, - rc, - i_scomAddr); - - // attempt to translate rc into a pib error assuming - // the rc is in common format - HbrtRcPiberr_t l_commonRc = static_cast<HbrtRcPiberr_t>(rc); - PIB::PibError l_piberr = HbrtRcToPibErr( l_commonRc ); - - if // input was translated to a PIB error code - ( l_piberr != PIB::PIB_NO_ERROR ) - { - // (translation was successful) - } - - else if // input was common format, but not a PIB error - ( l_commonRc == HBRT_RC_SOMEOTHERERROR ) - { - // (already translated to PIB::PIB_NO_ERROR, - // no more translation needed) - } - - else if // legacy opal - ( TARGETING::is_sapphire_load() ) - { - // attempt to translate rc into a pib error assuming - // the rc is in old opal format - // this preserves legacy behavior to avoid co-req/pre-req - l_piberr = OpalRcToPibErr( rc ); - } - - else if // legacy phyp - ( TARGETING::is_phyp_load() ) - { - // default to OFFLINE for now to trigger - // the multicast workaround in scom.C - l_piberr = PIB::PIB_CHIPLET_OFFLINE; - } - - else - { - // our testcases respond back with the - // pib error directly - if( rc > 0 ) - { - l_piberr = static_cast<PIB::PibError>(rc); - } - } - - PIB::addFruCallouts(i_target, - l_piberr, - i_scomAddr, - l_err); - - // Note: no trace buffer available at runtime - } - } - else // Hypervisor interface not initialized - { - TRACFCOMP(g_trac_xscom,ERR_MRK"Hypervisor scom interface not linked"); - /*@ - * @errortype - * @moduleid XSCOM_RT_DO_OP - * @reasoncode XSCOM_RUNTIME_INTERFACE_ERR - * @userdata1 0 - * @userdata2 SCOM address - * @devdesc XSCOM runtime interface not linked. - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, - XSCOM_RT_DO_OP, - XSCOM_RUNTIME_INTERFACE_ERR, - 0, - i_scomAddr); - - l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, - HWAS::SRCI_PRIORITY_HIGH); - } - - return l_err; -} - - errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, @@ -418,11 +169,7 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType, if (!l_err) { - - l_err = xScomDoOp(i_opType, - i_target, - l_addr, - io_buffer); + l_err = SCOM::sendScomToHyp(i_opType, i_target, l_addr, io_buffer); } TRACDCOMP(g_trac_xscom,EXIT_MRK"xscomPerformOp"); |