diff options
author | Andres Lugo-Reyes <aalugore@us.ibm.com> | 2016-10-24 18:02:08 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-12-20 00:22:27 -0500 |
commit | bdf8d5b8b6ab68f1882d18b1fad721f465b8aa74 (patch) | |
tree | b8b5eb683ec2c66ae89443516cc57a2d5a5fb8d5 /src/usr/isteps | |
parent | c4692b79f73b6867c76d22e608c4a831d69bdb03 (diff) | |
download | talos-hostboot-bdf8d5b8b6ab68f1882d18b1fad721f465b8aa74.tar.gz talos-hostboot-bdf8d5b8b6ab68f1882d18b1fad721f465b8aa74.zip |
P9 Updates for occ communication code
This commit contains updates for p9 OCC communication
code to no longer use the deprecated
ecmdDataBufferBase class.
Change-Id: I96b6be564a6edee1f66099583f030d3b519acb60
Depends-on: I6182163e569ac97f06e3ddfbb69deab90e849de3
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31876
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/isteps')
-rw-r--r-- | src/usr/isteps/pm/occAccess.C | 329 | ||||
-rw-r--r-- | src/usr/isteps/pm/pm.mk | 1 |
2 files changed, 330 insertions, 0 deletions
diff --git a/src/usr/isteps/pm/occAccess.C b/src/usr/isteps/pm/occAccess.C new file mode 100644 index 000000000..d6cda63ae --- /dev/null +++ b/src/usr/isteps/pm/occAccess.C @@ -0,0 +1,329 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/pm/occAccess.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <stdint.h> + +#include <errl/errlentry.H> +#include <occ/occAccess.H> +#include <targeting/common/utilFilter.H> + +// Fapi +#include <fapi2.H> +#include <fapi2/plat_hwp_invoker.H> +#include <isteps/hwpf_reasoncodes.H> + +// Procedures +#include <p9_pm_ocb_init.H> +#include <p9_pm_ocb_indir_setup_linear.H> +#include <p9_pm_ocb_indir_access.H> + +// Easy macro replace for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) + +#define CIRCULAR_OCB_DATA_SIZE 8 + + + +namespace HBOCC +{ + +// Passed target should be either a PROC or an OCC target +// If passed an OCC, then use it's parent PROC +// If passed a PROC, then use it +errlHndl_t getChipTarget(const TARGETING::Target* i_target, + TARGETING::Target* & o_pChipTarget) +{ + errlHndl_t l_errl = nullptr; + TARGETING::TYPE l_type = TARGETING::TYPE_NA; + bool l_found = false; //error if no chip target found + uint32_t l_huid = 0xFFFFFFFF; //read for error FFDC + + do + { + if(nullptr == i_target) //unexpected error + { + TRACFCOMP( g_fapiTd, ERR_MRK"getChipTarget: null target passed"); + break; // log and return error + } + + l_type = i_target->getAttr<TARGETING::ATTR_TYPE> (); + if (TARGETING::TYPE_OCC == l_type) // if OCC, use parent PROC + { + const TARGETING::Target * l_pChipTarget = getParentChip( + const_cast<TARGETING::Target *>(i_target)); + o_pChipTarget = const_cast<TARGETING::Target *>(l_pChipTarget); + if (nullptr == o_pChipTarget) + { + l_huid = i_target->getAttr<TARGETING::ATTR_HUID>(); + TRACFCOMP( g_fapiTd, ERR_MRK"getChipTarget:" + " Error OCC target has no parent" + " Target type: 0x%X huid:0x%X", + l_type, l_huid); + break; // log and return error + } + l_found = true; + } + else if (TARGETING::TYPE_PROC == l_type) //use passed PROC target + { + o_pChipTarget = const_cast<TARGETING::Target *>(i_target); + l_found = true; + } + else // unexpected target type + { + l_huid = i_target->getAttr<TARGETING::ATTR_HUID>(); + TRACFCOMP( g_fapiTd, ERR_MRK"getChipTarget:" + " Error Unexpected target type. Not PROC or" + " OCC. Target is of type: 0x%X huid:0x%X", + l_type, l_huid); + break; // log and return error + } + + } + while (0); + + if (!l_found) + { + /*@ + * @errortype + * @moduleid fapi::MOD_GET_OCC_CHIP_TARGET + * @reasoncode fapi::RC_TARGET_UNSUPPORTED + * @userdata1 Target Type + * @userdata2 Target HUID + * @devdesc PROC or OCC expected + * @custdesc A problem occurred during the IPL + * of the system. + */ + const bool hbSwError = true; + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_GET_OCC_CHIP_TARGET, + fapi::RC_TARGET_UNSUPPORTED, + l_type, + l_huid, + hbSwError); + } + + return l_errl; +} + +// common wrapper to p8_ocb_indir_access to access an OCB indirect channel +enum accessOCBIndirectCmd +{ + ACCESS_OCB_READ_LINEAR, + ACCESS_OCB_WRITE_LINEAR, + ACCESS_OCB_WRITE_CIRCULAR, +}; + +/* + * @brief Interface for communicating with the OCC via OCB channels + * + * @param[in] i_cmd - OCB Command type + * @param[in] i_pTarget - The OCC Target + * @param[in] i_addr - The address to read from/write to + * @param[in/out] io_dataBuf - The input/output buffer + * @param[in] i_dataLen - The length of the buffer in bytes + * + * @return - nullptr on success, error log handle on failure + */ +errlHndl_t accessOCBIndirectChannel(accessOCBIndirectCmd i_cmd, + const TARGETING::Target * i_pTarget, + const uint32_t i_addr, + uint64_t * io_dataBuf, + size_t i_dataLen ) +{ + errlHndl_t l_errl = nullptr; + uint32_t l_len = 0; + TARGETING::Target* l_pChipTarget = nullptr; + + p9ocb::PM_OCB_CHAN_NUM l_channel = p9ocb::OCB_CHAN0; // OCB channel (0,1,2,3) + p9ocb::PM_OCB_ACCESS_OP l_operation = p9ocb::OCB_GET; // Operation(Get, Put) + bool l_ociAddrValid = true; // use oci_address + bool l_setup=true; // set up linear + + TRACUCOMP( g_fapiTd, ENTER_MRK"accessOCBIndirectChannel cmd=%d",i_cmd); + + switch (i_cmd) + { + case (ACCESS_OCB_READ_LINEAR): + break; // use defaults + case (ACCESS_OCB_WRITE_LINEAR): + l_operation = p9ocb::OCB_PUT; + break; + case (ACCESS_OCB_WRITE_CIRCULAR): + l_channel = p9ocb::OCB_CHAN1; + l_operation = p9ocb::OCB_PUT; + l_ociAddrValid = false; + l_setup = false; + break; + } + + TRACUCOMP( g_fapiTd, INFO_MRK"accessOCBIndirectChannel" + " channel=%d operation=%d addrValid=%d", + l_channel,l_operation,l_ociAddrValid); + do + { + l_errl = getChipTarget(i_pTarget,l_pChipTarget); + if (l_errl) + { + break; //exit with error + } + TRACUCOMP( g_fapiTd, INFO_MRK"accessOCBIndirectChannel:" + " target=%.8x type=%d", + get_huid(l_pChipTarget), + l_pChipTarget->getAttr<TARGETING::ATTR_TYPE>()); + + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapiTarget( l_pChipTarget ); + + // buffer must be multiple of 8 bytes + if( i_dataLen%8 != 0) + { + + TRACFCOMP( g_fapiImpTd, ERR_MRK"accessOCBIndirectChannel:" + " Error Improper data size:%d(in bytes),size of data" + " requested to be read is not aligned in size of 8 Bytes", + i_dataLen ); + + /*@ + * @errortype + * @moduleid fapi::MOD_ACCESS_OCB_INDIRECT_CHANNEL + * @reasoncode fapi::RC_INVALID_DATA_BUFFER_LENGTH + * @userdata1 Length of requested buffer size(in Bytes) to + * perform read operation. + * @userdata2 OCI address + * @devdesc Improper data size, data is not 8 byte aligned. + * @custdesc A problem occurred during the IPL + * of the system. + */ + const bool hbSwError = true; + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_ACCESS_OCB_INDIRECT_CHANNEL, + fapi::RC_INVALID_DATA_BUFFER_LENGTH, + i_dataLen, + i_addr, + hbSwError); + break; // return with error + } + + // TODO RTC: 116027 To be consistent with FSP code hwcoOCC.C, + // p8_ocb_indir_setup_linear is always called for read and write + // linear and not called for write circular. + // a) linear read and write set up may only be needed once + // b) circular write may need to be set up once + if (l_setup) + { + + FAPI_INVOKE_HWP( l_errl, + p9_pm_ocb_indir_setup_linear, + l_fapiTarget, + p9ocb::OCB_CHAN0, + p9ocb::OCB_TYPE_LINSTR, + i_addr ); + + + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"accessOCBIndirectChannel:" + " Error [0x%X] in call to " + " FAPI_INVOKE_HWP(p8_ocb_indir_setup_linear)", + l_errl->reasonCode()); + break; // return with error + } + } + + // perform operation + FAPI_INVOKE_HWP( l_errl, + p9_pm_ocb_indir_access, + l_fapiTarget, + l_channel, + l_operation, + i_dataLen/8, // Number of 8-byte blocks + l_ociAddrValid, + i_addr, + l_len, + io_dataBuf ); + + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"accessOCBIndirectChannel:" + " Error [0x%X] in call to" + " FAPI_INVOKE_HWP(p8_ocb_indir_access)", + l_errl->reasonCode()); + break; // return with error + } + + } + while (0); + + TRACUCOMP( g_fapiTd, EXIT_MRK"accessOCBIndirectChannel"); + + return l_errl; +} + +// Read OCC SRAM +errlHndl_t readSRAM(const TARGETING::Target * i_pTarget, + const uint32_t i_addr, + uint64_t * io_dataBuf, + size_t i_dataLen ) +{ + errlHndl_t l_errl = nullptr; + l_errl = accessOCBIndirectChannel(ACCESS_OCB_READ_LINEAR, + i_pTarget, + i_addr, + io_dataBuf, + i_dataLen ); + return l_errl; +} + +// Write OCC SRAM +errlHndl_t writeSRAM(const TARGETING::Target * i_pTarget, + const uint32_t i_addr, + uint64_t * i_dataBuf, + size_t i_dataLen) +{ + errlHndl_t l_errl = nullptr; + l_errl = accessOCBIndirectChannel(ACCESS_OCB_WRITE_LINEAR, + i_pTarget, + i_addr, + i_dataBuf, + i_dataLen ); + return l_errl; +} + +// Write OCC Circular Buffer +errlHndl_t writeCircularBuffer(const TARGETING::Target * i_pTarget, + uint64_t * i_dataBuf) +{ + errlHndl_t l_errl = nullptr; + l_errl = accessOCBIndirectChannel(ACCESS_OCB_WRITE_CIRCULAR, + i_pTarget, + 0, + i_dataBuf, + CIRCULAR_OCB_DATA_SIZE); + return l_errl; +} + +} //end OCC namespace diff --git a/src/usr/isteps/pm/pm.mk b/src/usr/isteps/pm/pm.mk index 782725a8c..86bb5cca0 100644 --- a/src/usr/isteps/pm/pm.mk +++ b/src/usr/isteps/pm/pm.mk @@ -53,6 +53,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/ #common PM Complex functions between ipl and runtime OBJS += pm_common.o +OBJS += occAccess.o ## NOTE: add a new directory onto the vpaths when you add a new HWP VPATH += ${HWP_PM_PATH} ${HWP_CUST_PATH} ${HWP_ACC_PATH} |