diff options
author | Christian Geddes <crgeddes@us.ibm.com> | 2018-11-02 16:39:35 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-11-19 12:00:17 -0600 |
commit | cd754bf0b11117790f5d926844f7a8b7f595230d (patch) | |
tree | 99fbd2be99d3974c9e5cca8ccade412ba7963647 | |
parent | a4d8ef54250c26edd4de0541b9205c8b7829620f (diff) | |
download | talos-hostboot-cd754bf0b11117790f5d926844f7a8b7f595230d.tar.gz talos-hostboot-cd754bf0b11117790f5d926844f7a8b7f595230d.zip |
Route scom operations on OCMB chips to fapi2 mmio scom interface
After we get OMI targets trained we can communicate with the OCMB
chips via MMIO. This includes reading and writing scom registers on
the OCMB chip. This commit hooks up all of the plumming so when a
HWP calls fapi2::getScom/putScom on an OCMB chip hostboot will be
able to determine what functions to call to perform the operation.
Change-Id: I3ae6f8b4ad3128f61d886b1fdfbeea82b0c6e76e
RTC: 196806
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68353
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-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 |