diff options
-rw-r--r-- | src/include/usr/expscom/expscom_reasoncodes.H | 4 | ||||
-rw-r--r-- | src/usr/expscom/README.md | 118 | ||||
-rw-r--r-- | src/usr/expscom/expscom_trace.C (renamed from src/usr/expscom/expscomtrace.C) | 6 | ||||
-rw-r--r-- | src/usr/expscom/expscom_trace.H (renamed from src/usr/expscom/expscomtrace.H) | 8 | ||||
-rw-r--r-- | src/usr/expscom/expscom_utils.C | 223 | ||||
-rw-r--r-- | src/usr/expscom/expscom_utils.H | 61 | ||||
-rw-r--r-- | src/usr/expscom/i2cscomdd.C | 220 | ||||
-rw-r--r-- | src/usr/expscom/i2cscomdd.H | 4 | ||||
-rw-r--r-- | src/usr/expscom/makefile | 10 | ||||
-rw-r--r-- | src/usr/expscom/mmioscomdd.C | 158 | ||||
-rw-r--r-- | src/usr/expscom/mmioscomdd.H | 67 |
11 files changed, 656 insertions, 223 deletions
diff --git a/src/include/usr/expscom/expscom_reasoncodes.H b/src/include/usr/expscom/expscom_reasoncodes.H index 62713531c..9eb7ebc29 100644 --- a/src/include/usr/expscom/expscom_reasoncodes.H +++ b/src/include/usr/expscom/expscom_reasoncodes.H @@ -31,8 +31,8 @@ namespace EXPSCOM { enum EXPSCOMModuleId { - MOD_OCMBSCOM_INVALID = 0x00, // Zero is an invalid module id - MOD_I2CSCOM_PERFORM_OP = 0x01, // i2cscom.C : i2cScomPerformOp + MOD_OCMBSCOM_INVALID = 0x00, // Zero is an invalid module id + MOD_OCMB_UTILS = 0x01, // expscom_utils.C }; enum EXPSCOMReasonCode diff --git a/src/usr/expscom/README.md b/src/usr/expscom/README.md index d6d7a8284..fd7e351e5 100644 --- a/src/usr/expscom/README.md +++ b/src/usr/expscom/README.md @@ -138,4 +138,120 @@ the device op route for I2C address on the OCMB's master I2c device (which will l_myOCMBTargeti2cInfo->engine, l_myOCMBTargeti2cInfo->devAddr, sizeof(l_cmd_vector), - l_cmd_vector) );
\ No newline at end of file + l_cmd_vector) ); + +### Explorer MMIO SCOM + +When the useIbScom field is set in SCOM_SWITCHES this is how the fapi2::putScom API for OCMB +targets will be processed (lets say for now this is IBM scom address): + +* Generic FAPI2 getScom API + + + fapi2::getScom(myOcmbTarget, scomAddr, io_buffer); + +* Platform Specifc FAPI2 getScom API + + + fapi2::platGetScom(myOcmbTarget, scomAddr, io_buffer); + +* Platform Specifc FAPI2 getScom API resolves to calling into our device framework to whatever +function is registered to read OCMB target for DeviceFW::SCOM operations + + + DeviceFW::deviceRead(myOcmbTarget, io_buffer, + sizeof(uint64_t), DeviceFW::SCOM, + scomAddr, READ) + +* scomPeformOp is what is defined to handle DeviceFW::SCOM operations to the OCMB chip targets + + + SCOM::scomPerformOp(READ, myOCMBTarget, io_buffer, + sizeof(uint64_t), DeviceFW::SCOM, + scomAddr) + +* scomPeformOp is basically a wrapper for checkIndirectAndDoScom. There are no indirect scoms +for OCMB target scoms so we will end up calling doScomOp + + + checkIndirectAndDoScom(READ, myOCMBTarget, io_buffer, + sizeof(uint64_t), DeviceFW::SCOM, + scomAddr) + +* doScomOp looks at the SCOM_SWITCHES attribute and decides which type of scom to do for the given target. + + + doScomOp(READ, myOCMBTarget, io_buffer, + sizeof(uint64_t), DeviceFW::SCOM, + scomAddr) + +* If the useIbScom field is set to 1 then we will call the function that is registered to inband scoms for OCMB targets + + + deviceOp(READ, myOCMBTarget, io_buffer, + sizeof(uint64_t), DeviceFW::IBSCOM, + scomAddr) + +* mmioScomPerformOp is the function that is registered to IBSCOM operations to OCMB chips + + + mmioScomPerformOp(READ, myOCMBTarget, io_buffer, + sizeof(uint64_t), DeviceFW::IBSCOM, + scomAddr) + +* mmioScomPerformOp will call the hwp mss::exp::ib::getScom which is a in-band scom driver for the OCMB explorer chip + + + FAPI_EXEC_HWP(l_rc , mss::exp::ib::getScom, myOCMBTarget, scomAddr, io_buffer); + +* mss::exp::ib::getScom will translate the scomAddress into a mmio address and perform a getMMIO64 operation + + + getMMIO64(myOCMBTarget, (scomAddr << 3), io_buffer); + +* getMMIO64 will add the IB_MMIO offset and perform a 64 bit mmio read using the fapi2::getMMIO interface + + + fapi2::getMMIO(myOCMBTarget, EXPLR_IB_MMIO_OFFSET | scomAddr, 8, io_buffer) + +* fapi2::getMMIO is defined by the platform + + + ReturnCode platGetMMIO( myOCMBTarget, + EXPLR_IB_MMIO_OFFSET | (scomAddr << 3), + 8, // bytes + io_buffer ) + +* platGetMMIO will use the device framework to look up the correct routine for MMIO addresses on OCMB targets + + + DeviceFW::deviceRead(myOCMBTarget, + io_buffer, + 8, // bytes + DEVICE_MMIO_ADDRESS(EXPLR_IB_MMIO_OFFSET | (scomAddr << 3), 8)); + + +* the device framework will route the deviceRead call to mmioPerformOp + + + mmioPerformOp(READ, + myOCMBTarget, + io_buffer, + 8, // bytes + DeviceFW::MMIO, + address, readLimit); + +* mmioPerformOp resolves to doing a memcpy on the address requested + + + if (i_opType == DeviceFW::READ) + { + memcpy(io_ptr + i, mm_ptr + i, l_accessLimit); + } + else if (i_opType == DeviceFW::WRITE) + { + memcpy(mm_ptr + i, io_ptr + i, l_accessLimit); + + // XXX Need to check a processor SCOM here to determine if the + // write succeeded or failed. + } diff --git a/src/usr/expscom/expscomtrace.C b/src/usr/expscom/expscom_trace.C index 1b8fb554c..14b48c086 100644 --- a/src/usr/expscom/expscomtrace.C +++ b/src/usr/expscom/expscom_trace.C @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/expscom/expscomtrace.C $ */ +/* $Source: src/usr/expscom/expscom_trace.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -23,13 +23,13 @@ /* */ /* IBM_PROLOG_END_TAG */ /// -/// @file expscomtrace.C +/// @file expscom_trace.C /// /// @brief Initialized trace descriptor for expscom /// -#include "expscomtrace.H" +#include "expscom_trace.H" #include <limits.h> #include <hbotcompid.H> diff --git a/src/usr/expscom/expscomtrace.H b/src/usr/expscom/expscom_trace.H index 61e1fde78..8335a4b3c 100644 --- a/src/usr/expscom/expscomtrace.H +++ b/src/usr/expscom/expscom_trace.H @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/expscom/expscomtrace.H $ */ +/* $Source: src/usr/expscom/expscom_trace.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -23,12 +23,12 @@ /* */ /* IBM_PROLOG_END_TAG */ /// -/// @file expscomtrace.H +/// @file expscom_trace.H /// @brief Defines the extern expscom trace /// -#ifndef expscom_TRACE_H_ -#define expscom_TRACE_H_ +#ifndef EXPSCOM_TRACE_H_ +#define EXPSCOM_TRACE_H_ #include <trace/interface.H> //****************************************************************************** diff --git a/src/usr/expscom/expscom_utils.C b/src/usr/expscom/expscom_utils.C new file mode 100644 index 000000000..a631f74e0 --- /dev/null +++ b/src/usr/expscom/expscom_utils.C @@ -0,0 +1,223 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expscom/expscom_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ +/** + * @file expscom_utls.C + * + * @brief Provides the common utility functions for i2c and mmio + * Explorer OCMB scom drivers + */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <errl/errlmanager.H> // errlCommit +#include <errl/errludtarget.H> // ErrlUserDetailsTarget +#include <devicefw/driverif.H> // OperationType +#include <expscom/expscom_reasoncodes.H> +#include "expscom_trace.H" +#include "expscom_utils.H" + +namespace EXPSCOM +{ + +constexpr uint64_t FIRST_4_BYTES = 0xFFFFFFFF00000000; + +/////////////////////////////////////////////////////////////////////////////// +// See above for doxygen documentation +/////////////////////////////////////////////////////////////////////////////// +errlHndl_t validateInputs(DeviceFW::OperationType i_opType, + const TARGETING::Target* i_target, + size_t i_buflen, + uint64_t i_scomAddr) +{ + errlHndl_t l_err = nullptr; + uint32_t l_commonPlid = 0; // If there are multiple issues found link logs with first + + TARGETING::ATTR_MODEL_type l_targetModel = + i_target->getAttr<TARGETING::ATTR_MODEL>(); + + // Only target we can perform ocmb scoms on are explorer OCMB chip targets + if( l_targetModel != TARGETING::MODEL_EXPLORER ) + { + TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid target type : l_targetModel=%d", l_targetModel ); + /*@ + * @errortype + * @moduleid EXPSCOM::MOD_OCMB_UTILS + * @reasoncode EXPSCOM::RC_INVALID_MODEL_TYPE + * @userdata1 SCOM Address + * @userdata2 Model Type + * @devdesc validateInputs> Invalid target type (!= OCMB_CHP) + * @custdesc A problem occurred during the IPL of the system: + * Invalid target type for a SCOM operation. + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EXPSCOM::MOD_OCMB_UTILS, + EXPSCOM::RC_INVALID_MODEL_TYPE, + i_scomAddr, + l_targetModel, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + l_err->collectTrace(EXPSCOM_COMP_NAME); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); + l_commonPlid = l_err->plid(); + } + + // The address passed to the OCMB scom functions is really only 32 bits + // just to be safe make sure that first 4 bytes are 0s + if( i_scomAddr & FIRST_4_BYTES ) + { + TRACFCOMP( g_trac_expscom, + ERR_MRK "validateInputs> Invalid address : i_scomAddr=0x%lx , first 32 bits should be 0's", + i_scomAddr ); + + // If there is already an error from prev checks, then commit it + if(l_err) + { + errlCommit(l_err, EXPSCOM_COMP_ID); + } + + /*@ + * @errortype + * @moduleid EXPSCOM::MOD_OCMB_UTILS + * @reasoncode EXPSCOM::RC_INVALID_ADDRESS + * @userdata1 SCOM Address + * @userdata2 Target HUID + * @devdesc validateInputs> Invalid scom address, first 4 + * bytes should be 0's + * @custdesc A problem occurred during the IPL of the system: + * Invalid address for a SCOM operation. + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EXPSCOM::MOD_OCMB_UTILS, + EXPSCOM::RC_INVALID_ADDRESS, + i_scomAddr, + TARGETING::get_huid(i_target), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + l_err->collectTrace(EXPSCOM_COMP_NAME); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); + + if(l_commonPlid == 0) + { + l_commonPlid = l_err->plid(); + } + else + { + l_err->plid(l_commonPlid); + } + } + + // The buffer passed into validateInputs should ALWAYS be 8 bytes. + // If it is an IBM scom then all 8 bytes are used. If its microchip scom + // then only the last 4 bytes are used. + if (i_buflen != sizeof(uint64_t)) + { + TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid data length : io_buflen=%d ," + " expected sizeof(uint64_t)", i_buflen ); + + // If there is already an error from prev checks, then commit it + if(l_err) + { + errlCommit(l_err, EXPSCOM_COMP_ID); + } + + /*@ + * @errortype + * @moduleid EXPSCOM::MOD_OCMB_UTILS + * @reasoncode EXPSCOM::RC_INVALID_LENGTH + * @userdata1 SCOM Address + * @userdata2 Data Length + * @devdesc validateInputs> Invalid data length (!= 8 bytes) + * @custdesc A problem occurred during the IPL of the system: + * Invalid data length for a SCOM operation. + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EXPSCOM::MOD_OCMB_UTILS, + EXPSCOM::RC_INVALID_LENGTH, + i_scomAddr, + TO_UINT64(i_buflen), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + l_err->collectTrace(EXPSCOM_COMP_NAME); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); + + if(l_commonPlid == 0) + { + l_commonPlid = l_err->plid(); + } + else + { + l_err->plid(l_commonPlid); + } + } + + // The only valid operations are READ and WRITE if anything else comes in we need to error out + if (i_opType != DeviceFW::READ && i_opType != DeviceFW::WRITE ) + { + TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid operation type : i_opType=%d", i_opType ); + + if(l_err) + { + errlCommit(l_err, EXPSCOM_COMP_ID); + } + + /*@ + * @errortype + * @moduleid EXPSCOM::MOD_OCMB_UTILS + * @reasoncode EXPSCOM::RC_INVALID_OPTYPE + * @userdata1 SCOM Address + * @userdata2 Access Type + * @devdesc validateInputs> Invalid OP type (!= READ or WRITE) + * @custdesc A problem occurred during the IPL of the system: + * Invalid operation type for a SCOM operation. + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EXPSCOM::MOD_OCMB_UTILS, + EXPSCOM::RC_INVALID_OPTYPE, + i_scomAddr, + i_opType, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + l_err->collectTrace(EXPSCOM_COMP_NAME); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); + + if(l_commonPlid == 0) + { + l_commonPlid = l_err->plid(); + } + else + { + l_err->plid(l_commonPlid); + } + } + + return l_err; +} + +} // End namespace EXPSCOM diff --git a/src/usr/expscom/expscom_utils.H b/src/usr/expscom/expscom_utils.H new file mode 100644 index 000000000..0a9aa0dd3 --- /dev/null +++ b/src/usr/expscom/expscom_utils.H @@ -0,0 +1,61 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expscom/expscom_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 __EXPSCOM_UTILS_H +#define __EXPSCOM_UTILS_H + +/** @file expscom_utils.H + * @brief Provides the common utility functions for i2c and mmio + * Explorer OCMB scom drivers + */ +#include <stdint.h> + + +namespace EXPSCOM +{ + +/** +* @brief Performs validation of params passed to i2cScomPerformOp and +* mmioScomPerformOp functions. This function checks that the target +* model, the buffer lengt, addr format, and the op type are all valid. +* A unique error will be created for each violation. If multiple error +* are found the last error will be returned and all previous errors found +* will be committed as new errors are found (see function). +* +* @param[in] i_opType Operation type, see DeviceFW::OperationType +* in driverif.H +* @param[in] i_target TARGETING::Target passed to mmioscomPerformOp +* @param[in] i_buflen size of buffer passed to mmioscomPerformOp +* @param[in] i_scomAddr Scom address operation will be performed on + +* @return errlHndl_t +*/ +errlHndl_t validateInputs(DeviceFW::OperationType i_opType, + const TARGETING::Target* i_target, + size_t i_buflen, + uint64_t i_scomAddr); + +} + +#endif
\ No newline at end of file diff --git a/src/usr/expscom/i2cscomdd.C b/src/usr/expscom/i2cscomdd.C index 1cbff6083..596e293ec 100644 --- a/src/usr/expscom/i2cscomdd.C +++ b/src/usr/expscom/i2cscomdd.C @@ -37,33 +37,16 @@ #include <hwpf/fapi2/include/fapi2_hwp_executor.H> // FAPI_EXEC_HWP #include <expscom/expscom_reasoncodes.H> // EXPSCOM::MOD_I2CSCOM_PERFORM_OP #include "i2cscomdd.H" //i2cScomPerformOp -#include "expscomtrace.H" //g_trac_expscom +#include "expscom_trace.H" //g_trac_expscom +#include "expscom_utils.H" //validateInputs namespace I2CSCOMDD { -constexpr uint64_t FIRST_4_BYTES = 0xFFFFFFFF00000000; - -/** - * @brief Performs validation of params passed into i2cScomPerformOp function - * This function checks that the target type, the address format, the buffer length - * and the op type are all valid. A unique error will be created for each violation. - * If multiple error are found the last error will be returned and all previous errors - * found will be committed as new errors are found (see function). - * - * @param[in] i_opType Operation type, see DeviceFW::OperationType - * in driverif.H - * @param[in] i_target TARGETING::Target passed to i2cScomPerformOp - * @param[in] i_buflen size of buffer passed to i2cScomPerformOp - * (i_buflen is expected to be 8 bytes) - * @param[in] i_scomAddr Scom address operation will be performed on - - * @return errlHndl_t nullptr on success, non-null ptr on error - */ -errlHndl_t validateInputs(DeviceFW::OperationType i_opType, - const TARGETING::Target* i_target, - size_t i_buflen, - uint64_t i_scomAddr); +DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD, + DeviceFW::I2CSCOM, + TARGETING::TYPE_OCMB_CHIP, + i2cScomPerformOp); /////////////////////////////////////////////////////////////////////////////// // See header for doxygen documentation @@ -89,10 +72,14 @@ errlHndl_t i2cScomPerformOp(DeviceFW::OperationType i_opType, do { // First make sure the inputs are valid - l_err = validateInputs ( i_opType, i_target, l_scomAddr, io_buflen); + l_err = EXPSCOM::validateInputs ( i_opType, i_target, l_scomAddr, io_buflen); if(l_err) { + // Write a trace out to the buffer and then collect it on the log + // this way we can know if the fail was in i2cScomPerformOp or mmioScomPerformOp + TRACFCOMP( g_trac_expscom, ERR_MRK "i2cScomPerformOp> Validation of inputs failed see error logs for details "); + l_err->collectTrace(EXPSCOM_COMP_NAME); break; } @@ -181,189 +168,4 @@ errlHndl_t i2cScomPerformOp(DeviceFW::OperationType i_opType, } while (0); return l_err; } - -/////////////////////////////////////////////////////////////////////////////// -// See above for doxygen documentation -/////////////////////////////////////////////////////////////////////////////// -errlHndl_t validateInputs(DeviceFW::OperationType i_opType, - const TARGETING::Target* i_target, - size_t i_buflen, - uint64_t i_scomAddr) -{ - errlHndl_t l_err = nullptr; - uint32_t l_commonPlid = 0; // If there are multiple issues found link logs with first - - TARGETING::ATTR_MODEL_type l_targetModel = - i_target->getAttr<TARGETING::ATTR_MODEL>(); - - // Only target we can perform i2c scoms on like this are explorer OCMB chip targets - if( l_targetModel != TARGETING::MODEL_EXPLORER ) - { - TRACFCOMP( g_trac_expscom, ERR_MRK "i2cScomPerformOp> Invalid model type : l_targetModel=%d", l_targetModel ); - /*@ - * @errortype - * @moduleid EXPSCOM::MOD_I2CSCOM_PERFORM_OP - * @reasoncode EXPSCOM::RC_INVALID_MODEL_TYPE - * @userdata1 SCOM Address - * @userdata2[0:31] Model Type - * @userdata2[32:63] Target Huid - * @devdesc i2cScomPerformOp> Invalid target type (!= OCMB_CHP) - * @custdesc A problem occurred during the IPL of the system: - * Invalid target type for a SCOM operation. - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EXPSCOM::MOD_I2CSCOM_PERFORM_OP, - EXPSCOM::RC_INVALID_MODEL_TYPE, - i_scomAddr, - TWO_UINT32_TO_UINT64(l_targetModel, - TARGETING::get_huid(i_target)), - ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); - - l_err->collectTrace(EXPSCOM_COMP_NAME); - ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). - addToLog(l_err); - l_commonPlid = l_err->plid(); - } - // The address is really only 32 bits, we will cast it to 32 bits before passing to - // the fapi2 i2c_get_scom function but just to be safe make sure that first 4 bytes are 0s - if( i_scomAddr & FIRST_4_BYTES ) - { - TRACFCOMP( g_trac_expscom, - ERR_MRK "i2cScomPerformOp> Invalid address : i_scomAddr=0x%lx , first 32 bits should be 0's", - i_scomAddr ); - - // If there is already an error from prev checks, then commit it - if(l_err) - { - errlCommit(l_err, EXPSCOM_COMP_ID); - } - - /*@ - * @errortype - * @moduleid EXPSCOM::MOD_I2CSCOM_PERFORM_OP - * @reasoncode EXPSCOM::RC_INVALID_ADDRESS - * @userdata1 SCOM Address - * @userdata2 Target HUID - * @devdesc i2cScomPerformOp> Invalid scom address, first 4 - * bytes should be 0's - * @custdesc A problem occurred during the IPL of the system: - * Invalid address for a SCOM operation. - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EXPSCOM::MOD_I2CSCOM_PERFORM_OP, - EXPSCOM::RC_INVALID_ADDRESS, - i_scomAddr, - TARGETING::get_huid(i_target), - ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); - - l_err->collectTrace(EXPSCOM_COMP_NAME); - ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). - addToLog(l_err); - - if(l_commonPlid == 0) - { - l_commonPlid = l_err->plid(); - } - else - { - l_err->plid(l_commonPlid); - } - } - - // The buffer passed into i2cScomPerformOp should ALWAYS be 8 bytes. - // If it is an IBM scom then all 8 bytes are used. If its microchip scom - // then only the last 4 bytes are used. - if (i_buflen != sizeof(uint64_t)) - { - TRACFCOMP( g_trac_expscom, ERR_MRK "i2cScomPerformOp> Invalid data length : io_buflen=%d ," - " expected sizeof(uint64_t)", i_buflen ); - - // If there is already an error from prev checks, then commit it - if(l_err) - { - errlCommit(l_err, EXPSCOM_COMP_ID); - } - - /*@ - * @errortype - * @moduleid EXPSCOM::MOD_I2CSCOM_PERFORM_OP - * @reasoncode EXPSCOM::RC_INVALID_LENGTH - * @userdata1 SCOM Address - * @userdata2 Data Length - * @devdesc i2cScomPerformOp> Invalid data length (!= 8 bytes) - * @custdesc A problem occurred during the IPL of the system: - * Invalid data length for a SCOM operation. - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EXPSCOM::MOD_I2CSCOM_PERFORM_OP, - EXPSCOM::RC_INVALID_LENGTH, - i_scomAddr, - TO_UINT64(i_buflen), - ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); - - l_err->collectTrace(EXPSCOM_COMP_NAME); - ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). - addToLog(l_err); - - if(l_commonPlid == 0) - { - l_commonPlid = l_err->plid(); - } - else - { - l_err->plid(l_commonPlid); - } - } - - // The only valid operations are READ and WRITE if anything else comes in we need to error out - if (i_opType != DeviceFW::READ && i_opType != DeviceFW::WRITE ) - { - TRACFCOMP( g_trac_expscom, ERR_MRK "i2cScomPerformOp> Invalid operation type : i_opType=%d", i_opType ); - - if(l_err) - { - errlCommit(l_err, EXPSCOM_COMP_ID); - } - - /*@ - * @errortype - * @moduleid EXPSCOM::MOD_I2CSCOM_PERFORM_OP - * @reasoncode EXPSCOM::RC_INVALID_OPTYPE - * @userdata1 SCOM Address - * @userdata2 Op Type - * @devdesc i2cScomPerformOp> Invalid operation type (!= READ or WRITE) - * @custdesc A problem occurred during the IPL of the system: - * Invalid SCOM operation. - */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EXPSCOM::MOD_I2CSCOM_PERFORM_OP, - EXPSCOM::RC_INVALID_OPTYPE, - i_scomAddr, - i_opType, - ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); - - l_err->collectTrace(EXPSCOM_COMP_NAME); - ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). - addToLog(l_err); - - if(l_commonPlid == 0) - { - l_commonPlid = l_err->plid(); - } - else - { - l_err->plid(l_commonPlid); - } - } - - return l_err; -} - - -DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD, - DeviceFW::I2CSCOM, - TARGETING::TYPE_OCMB_CHIP, - i2cScomPerformOp); - - }
\ No newline at end of file diff --git a/src/usr/expscom/i2cscomdd.H b/src/usr/expscom/i2cscomdd.H index 07c025037..a65f847ca 100644 --- a/src/usr/expscom/i2cscomdd.H +++ b/src/usr/expscom/i2cscomdd.H @@ -26,7 +26,7 @@ #define __I2CSCOMDD_H /** @file i2cscomdd.H - * @brief Provides the interfaces to perform I2cscom + * @brief Provides the interfaces to perform I2Cscom */ #include <stdint.h> @@ -55,7 +55,7 @@ namespace I2CSCOMDD * which is the IBM scom address * @return errlHndl_t nullptr on success, non-null ptr on error */ -errlHndl_t i2cscomPerformOp(DeviceFW::OperationType i_opType, +errlHndl_t i2cScomPerformOp(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, size_t& io_buflen, diff --git a/src/usr/expscom/makefile b/src/usr/expscom/makefile index f8569d329..4399d993b 100644 --- a/src/usr/expscom/makefile +++ b/src/usr/expscom/makefile @@ -26,17 +26,23 @@ ROOTPATH = ../../.. MODULE = expscom EXTRAINCDIR += ${ROOTPATH}/src/import +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 +# Need to build exp_indband to use EKB's getMMIO/putMMIO +OBJS += exp_inband.o -OBJS += expscomtrace.o +OBJS += expscom_trace.o +OBJS += expscom_utils.o OBJS += i2cscomdd.o -# OBJS += mmioscom.o +OBJS += mmioscomdd.o # TODO RTC:196806 ADD TESTs #SUBDIRS += test.d +VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/ + include ${ROOTPATH}/config.mk
\ No newline at end of file diff --git a/src/usr/expscom/mmioscomdd.C b/src/usr/expscom/mmioscomdd.C new file mode 100644 index 000000000..6d2ca3e5d --- /dev/null +++ b/src/usr/expscom/mmioscomdd.C @@ -0,0 +1,158 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expscom/mmioscomdd.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,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 */ + +/** + * @file mmioscomdd.C + * + * @brief Implementation of MMIO SCOM operations to OCMB chip */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <exp_inband.H> // mmio_get_scom +#include <lib/shared/exp_consts.H> // IBM_SCOM_INDICATOR +#include <hwpf/fapi2/include/fapi2_hwp_executor.H>// FAPI_EXEC_HWP +#include "mmioscomdd.H" //mmioScomPerformOp +#include "expscom_trace.H" //g_trac_expscom +#include "expscom_utils.H" //validateInputs + +namespace MMIOSCOMDD +{ + +DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD, + DeviceFW::IBSCOM, + TARGETING::TYPE_OCMB_CHIP, + mmioScomPerformOp); + +/////////////////////////////////////////////////////////////////////////////// +// See header for doxygen documentation +/////////////////////////////////////////////////////////////////////////////// +errlHndl_t mmioScomPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args) +{ + errlHndl_t l_err = nullptr; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + // The only extra arg should be the scomAddress + uint64_t l_expAddr = va_arg(i_args,uint64_t); + + // The fapi2 put/get mmioScom interfaces require a fapi2::buffer so convert + // to a uint64_t buffer (for IBM scom) and uint32_t buffer (for Microchip scoms) + fapi2::buffer<uint64_t> l_fapi2Buffer64(*reinterpret_cast<uint64_t *>(io_buffer)); + fapi2::buffer<uint32_t> l_fapi2Buffer32; + l_fapi2Buffer64.extractToRight<32,32>(l_fapi2Buffer32); + + do + { + // First make sure the inputs are valid + l_err = EXPSCOM::validateInputs ( i_opType, i_target, l_expAddr, io_buflen); + + if(l_err) + { + // Write a trace out to the buffer and then collect it on the log + // this way we can know if the fail was in i2cScomPerformOp or mmioScomPerformOp + TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> Validation of inputs failed see error logs for details "); + l_err->collectTrace(EXPSCOM_COMP_NAME); + break; + } + + // Check if this is a IBM_SCOM address by &ing the address with IBM_SCOM_INDICATOR + // If the indicator is not set, then we will assume this is a microChip address + if( (l_expAddr & mss::exp::i2c::IBM_SCOM_INDICATOR) == mss::exp::i2c::IBM_SCOM_INDICATOR) + { + // READ and WRITE equates to mss::exp::ib::getScom and mss::exp::ib::putScom respectively. + // any other OP is invalid. i/o data is expected to be 8 bytes for IBM scoms + if(i_opType == DeviceFW::READ) + { + FAPI_EXEC_HWP(l_rc , mss::exp::ib::getScom, i_target, l_expAddr, l_fapi2Buffer64); + l_err = fapi2::rcToErrl(l_rc); + if(l_err) + { + l_err->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_err->collectTrace(FAPI_TRACE_NAME,384); + TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> mss::exp::ib::getScom failed for HUID 0x%x Address 0x%lx ", + TARGETING::get_huid(i_target), l_expAddr ); + } + else + { + // Copy contents of what we read to io_buffer + memcpy(io_buffer, reinterpret_cast<uint8_t *>(l_fapi2Buffer64.pointer()), sizeof(uint64_t)); + } + } + else + { + FAPI_EXEC_HWP(l_rc , mss::exp::ib::putScom, i_target, l_expAddr, l_fapi2Buffer64); + l_err = fapi2::rcToErrl(l_rc); + if(l_err) + { + l_err->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_err->collectTrace(FAPI_TRACE_NAME,384); + TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> mss::exp::ib::putScom failed for HUID 0x%x Address 0x%lx ", + TARGETING::get_huid(i_target), l_expAddr ); + } + } + } + else + { + // READ and WRITE equates to mss::exp::ib::gettMMIO32 and mss::exp::ib::putMMIO32 respectively. + // any other OP is invalid. + if(i_opType == DeviceFW::READ) + { + FAPI_EXEC_HWP(l_rc , mss::exp::ib::getMMIO32, i_target, l_expAddr, l_fapi2Buffer32); + l_err = fapi2::rcToErrl(l_rc); + if(l_err) + { + TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> getMMIO32 failed for HUID 0x%x Address 0x%lx ", + TARGETING::get_huid(i_target), l_expAddr ); + } + else + { + // Put the contexts of the 32 bit buffer right justified into the 64 bit buffer + l_fapi2Buffer64.flush<0>(); + l_fapi2Buffer64.insertFromRight<32,32>(l_fapi2Buffer32); + // Copy contents of 64 bit buffer to io_buffer + memcpy(io_buffer, reinterpret_cast<uint8_t *>(l_fapi2Buffer64.pointer()), sizeof(uint64_t)); + } + } + else + { + FAPI_EXEC_HWP(l_rc , mss::exp::ib::putMMIO32, i_target, l_expAddr, l_fapi2Buffer32); + l_err = fapi2::rcToErrl(l_rc); + if(l_err) + { + TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> putMMIO32 failed for HUID 0x%x Address 0x%lx ", + TARGETING::get_huid(i_target), l_expAddr ); + } + } + + } + + } while (0); + return l_err; +} +}
\ No newline at end of file diff --git a/src/usr/expscom/mmioscomdd.H b/src/usr/expscom/mmioscomdd.H new file mode 100644 index 000000000..bef9013b9 --- /dev/null +++ b/src/usr/expscom/mmioscomdd.H @@ -0,0 +1,67 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expscom/mmioscomdd.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,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 __MMIOSCOMDD_H +#define __MMIOSCOMDD_H + +/** @file mmioscomdd.H + * @brief Provides the interfaces to perform mmioscom to OCMB chip + */ +#include <stdint.h> + + +namespace MMIOSCOMDD +{ + +/** + * @brief Performs an MMIOSCOM access operation + * This function performs an MMIOSCOM access operation. It follows a pre-defined + * prototype functions in order to be registered with the device-driver + * framework. + * + * @param[in] i_opType Operation type, see DeviceFW::OperationType + * in driverif.H + * @param[in] i_target MMIOSCOM Explorer Chip 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 DeviceFW::AccessType enum (usrif.H) + * @param[in] i_args This is an argument list for DD framework. + * In this function, there's only one argument, + * which is the IBM scom address + * @return errlHndl_t + */ +errlHndl_t mmioScomPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args); + +} + +#endif // __MMIOSCOMDD_H
\ No newline at end of file |