diff options
author | Mark Pizzutillo <Mark.Pizzutillo@ibm.com> | 2019-08-06 16:56:42 -0400 |
---|---|---|
committer | Christian R Geddes <crgeddes@us.ibm.com> | 2019-08-11 21:21:26 -0500 |
commit | 79c45f4da21a8de180e448ac628db4126644848d (patch) | |
tree | e07295c58bf4f5a00dcd94f42eeaee17e4dd6752 /src/import | |
parent | a690cdb01d544b27f17ee8c7dc04d584b6ef74e7 (diff) | |
download | talos-hostboot-79c45f4da21a8de180e448ac628db4126644848d.tar.gz talos-hostboot-79c45f4da21a8de180e448ac628db4126644848d.zip |
Move exp_inband to lib directory
Change-Id: If494c330ce20f6ec96ded6194d705e908198cf8b
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/81882
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: ANDRE A MARIN <aamarin@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/81886
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import')
15 files changed, 1445 insertions, 1593 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C index 7f8711c3a..8583c96b6 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C @@ -34,7 +34,7 @@ // *HWP Consumed by: FSP:HB #include <lib/shared/exp_consts.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <generic/memory/lib/utils/c_str.H> #include <generic/memory/lib/utils/mss_bad_bits.H> #include <lib/exp_draminit_utils.H> diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk index b1ba30fab..a9e488383 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk @@ -28,5 +28,4 @@ PROCEDURE=exp_draminit $(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE))) -lib$(PROCEDURE)_DEPLIBS+=exp_inband $(call BUILD_PROCEDURE) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C index 3d6878515..252148e83 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C @@ -34,7 +34,7 @@ // *HWP Consumed by: FSP:HB #include <fapi2.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <lib/shared/exp_consts.H> #include <exp_data_structs.H> #include <generic/memory/lib/utils/c_str.H> diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C deleted file mode 100644 index 98f02acfd..000000000 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C +++ /dev/null @@ -1,1020 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2018,2019 */ -/* [+] 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 exp_inband.C -/// @brief implement OpenCAPI config, scom, and MSCC MMIO operations. -// -// *HWP HWP Owner: bgass@us.ibm.com -// *HWP FW Owner: dcrowell@us.ibm.com -// *HWP Team: -// *HWP Level: 2 -// *HWP Consumed by: HB - -#include <exp_inband.H> -#include <lib/omi/crc32.H> -#include <lib/shared/exp_consts.H> - -#include <mmio_access.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/endian_utils.H> - -namespace mss -{ - -namespace exp -{ - -namespace ib -{ - -//-------------------------------------------------------------------------------- -// Write operations -//-------------------------------------------------------------------------------- - -/// @brief Writes 64 bits of data to MMIO space to the selected Explorer -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_addr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putMMIO64( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - const fapi2::buffer<uint64_t>& i_data ) -{ - uint64_t l_v = static_cast<uint64_t>(i_data); - std::vector<uint8_t> l_wd; - forceLE(l_v, l_wd); - return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 8, l_wd); -} - - - - -/// @brief Writes 32 bits of data to MMIO space to the selected Explorer -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_addr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putMMIO32( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - const fapi2::buffer<uint32_t>& i_data ) -{ - uint32_t l_v = static_cast<uint32_t>(i_data); - std::vector<uint8_t> l_wd; - forceLE(l_v, l_wd); - return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 4, l_wd); -} - - - - -/// @brief Writes 64 bits of data to SCOM MMIO space -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_scomAddr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putScom( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_scomAddr, - const fapi2::buffer<uint64_t>& i_data) -{ - // Converts from the scom address to the MMIO address by shifting left by 3 bits - uint64_t l_scomAddr = i_scomAddr << OCMB_ADDR_SHIFT; - return putMMIO64(i_target, l_scomAddr, i_data); -} - - - - -/// @brief Writes 32 bits of data to OpenCAPI config space -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_cfgAddr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putOCCfg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_cfgAddr, - const fapi2::buffer<uint32_t>& i_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - uint32_t l_v = static_cast<uint32_t>(i_data); - std::vector<uint8_t> l_wd; - fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL, - FAPI_SYSTEM, l_endian)); - - if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN) - { - forceLE(l_v, l_wd); - } - else - { - forceBE(l_v, l_wd); - } - - FAPI_TRY( fapi2::putMMIO(i_target, i_cfgAddr, 4, l_wd) ); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - - -fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_input, std::vector<uint8_t>& o_data, - uint32_t& o_crc) -{ - o_data.clear(); - FAPI_TRY(forceCrctEndian(i_input.version_number, o_data)); - FAPI_TRY(forceCrctEndian(i_input.DimmType, o_data)); - FAPI_TRY(forceCrctEndian(i_input.CsPresent, o_data)); - FAPI_TRY(forceCrctEndian(i_input.DramDataWidth, o_data)); - FAPI_TRY(forceCrctEndian(i_input.Height3DS, o_data)); - FAPI_TRY(forceCrctEndian(i_input.ActiveDBYTE, o_data)); - FAPI_TRY(forceCrctEndian(i_input.ActiveNibble, o_data)); - FAPI_TRY(forceCrctEndian(i_input.AddrMirror, o_data)); - FAPI_TRY(forceCrctEndian(i_input.ColumnAddrWidth, o_data)); - FAPI_TRY(forceCrctEndian(i_input.RowAddrWidth, o_data)); - FAPI_TRY(forceCrctEndian(i_input.SpdCLSupported, o_data)); - FAPI_TRY(forceCrctEndian(i_input.SpdtAAmin, o_data)); - FAPI_TRY(forceCrctEndian(i_input.Rank4Mode, o_data)); - FAPI_TRY(forceCrctEndian(i_input.EncodedQuadCs, o_data)); - FAPI_TRY(forceCrctEndian(i_input.DDPCompatible, o_data)); - FAPI_TRY(forceCrctEndian(i_input.TSV8HSupport, o_data)); - FAPI_TRY(forceCrctEndian(i_input.MRAMSupport, o_data)); - FAPI_TRY(forceCrctEndian(i_input.MDSSupport, o_data)); - FAPI_TRY(forceCrctEndian(i_input.NumPStates, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.Frequency, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.PhyOdtImpedance, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.PhyDrvImpedancePU, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.PhyDrvImpedancePD, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.PhySlewRate, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndian(i_input.ATxImpedance, o_data)); - FAPI_TRY(forceCrctEndian(i_input.ATxSlewRate, o_data)); - FAPI_TRY(forceCrctEndian(i_input.CKTxImpedance, o_data)); - FAPI_TRY(forceCrctEndian(i_input.CKTxSlewRate, o_data)); - FAPI_TRY(forceCrctEndian(i_input.AlertOdtImpedance, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR0, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR1, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR2, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR3, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR0, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR1, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR2, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR3, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR0, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR1, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR2, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR3, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramDic, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramWritePreamble, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.DramReadPreamble, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.PhyEqualization, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.InitVrefDQ, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.InitPhyVref, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.OdtWrMapCs, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.OdtRdMapCs, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.Geardown, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.CALatencyAdder, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.BistCALMode, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.BistCAParityLatency, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.RcdDic, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.RcdVoltageCtrl, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.RcdIBTCtrl, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.RcdDBDic, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.RcdSlewRate, MSDG_MAX_PSTATE, o_data)); - FAPI_TRY(forceCrctEndian(i_input.DFIMRL_DDRCLK, o_data)); - - for(uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate) - { - FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_A[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data)); - } - - for(uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate) - { - FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_B[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data)); - } - - o_crc = crc32_gen(o_data); - - padCommData(o_data); - FAPI_TRY(correctMMIOEndianForStruct(o_data)); - FAPI_TRY(correctMMIOword_order(o_data)); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - -/// @brief Writes user_input_msdg to the data buffer -/// -/// @param[in] i_target The Explorer chip to issue the command to -/// @param[in] i_data The user_input_msdg data to write -/// @param[out] o_crc The calculated crc of the data. -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putUserInputMsdg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const user_input_msdg& i_data, - uint32_t& o_crc) -{ - std::vector<uint8_t> l_data; - - FAPI_TRY(user_input_msdg_to_little_endian(i_data, l_data, o_crc)); - - FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, l_data)); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - -fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_struct& i_input, - std::vector<uint8_t>& o_data) -{ - uint32_t l_cmd_header_crc = 0; - FAPI_TRY(forceCrctEndian(i_input.cmd_id, o_data)); - FAPI_TRY(forceCrctEndian(i_input.cmd_flags, o_data)); - FAPI_TRY(forceCrctEndian(i_input.request_identifier, o_data)); - FAPI_TRY(forceCrctEndian(i_input.cmd_length, o_data)); - FAPI_TRY(forceCrctEndian(i_input.cmd_crc, o_data)); - FAPI_TRY(forceCrctEndian(i_input.host_work_area, o_data)); - FAPI_TRY(forceCrctEndian(i_input.cmd_work_area, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.padding, CMD_PADDING_SIZE, o_data)); - FAPI_TRY(forceCrctEndianArray(i_input.command_argument, ARGUMENT_SIZE, o_data)); - - // Generates and adds on the CRC - l_cmd_header_crc = crc32_gen(o_data); - FAPI_DBG("Command header crc: %xl", l_cmd_header_crc); - FAPI_TRY(forceCrctEndian(l_cmd_header_crc, o_data)); - padCommData(o_data); - FAPI_TRY(correctMMIOEndianForStruct(o_data)); - FAPI_TRY(correctMMIOword_order(o_data)); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - -/// @brief Writes a command to the command buffer and issues interrupt -/// -/// @param[in] i_target The Explorer chip to issue the command to -/// @param[in] i_cmd The command structure to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putCMD( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const host_fw_command_struct& i_cmd) -{ - std::vector<uint8_t> l_data; - fapi2::buffer<uint64_t> l_scom; - - FAPI_TRY(host_fw_command_struct_to_little_endian(i_cmd, l_data)); - - // Clear the doorbell - l_scom.setBit<EXPLR_MMIO_MDBELLC_MDBELL_MDBELL>(); - FAPI_DBG("Clearing the inbound doorbell..."); - FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELLC, l_scom), "Failed to clear inbound doorbell register"); - - // Clear the response doorbell, just in case the last response didn't get cleared - FAPI_TRY(clear_outbound_doorbell(i_target)); - - // Set the command - FAPI_DBG("Writing the command..."); - FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_CMD_ADDR, BUFFER_TRANSACTION_SIZE, l_data), - "Failed to write to the command buffer"); - - // Ring the doorbell - aka the bit that interrupts the microchip FW and tells it to do the thing - l_scom.flush<0>(); - l_scom.setBit<EXPLR_MMIO_MDBELL_MDBELL>(); - FAPI_DBG("Setting the inbound doorbell..."); - FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELL, l_scom), "Failed to set inbound doorbell bit"); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - -//-------------------------------------------------------------------------------- -// Read operations -//-------------------------------------------------------------------------------- - -/// @brief Reads 64 bits of data from MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_addr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getMMIO64( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - fapi2::buffer<uint64_t>& o_data) -{ - uint64_t l_rd = 0; - std::vector<uint8_t> l_data(8); - uint32_t l_idx = 0; - FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 8, l_data)); - readLE(l_data, l_idx, l_rd); - o_data = l_rd; -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - - -/// @brief Reads 32 bits of data from MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_addr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getMMIO32( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - fapi2::buffer<uint32_t>& o_data) -{ - uint32_t l_rd = 0; - std::vector<uint8_t> l_data(4); - uint32_t l_idx = 0; - FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 4, l_data)); - readLE(l_data, l_idx, l_rd); - o_data = l_rd; -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - - -/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_scomAddr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getScom( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_scomAddr, - fapi2::buffer<uint64_t>& o_data) -{ - // Converts from the scom address to the MMIO address by shifting left by 3 bits - uint64_t l_scomAddr = i_scomAddr << OCMB_ADDR_SHIFT; - return getMMIO64(i_target, l_scomAddr, o_data); -} - - - - -/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_cfgAddr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getOCCfg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_cfgAddr, - fapi2::buffer<uint32_t>& o_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - uint32_t l_rd = 0; - std::vector<uint8_t> l_data(4); - uint32_t l_idx = 0; - fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL, - FAPI_SYSTEM, l_endian)); - - FAPI_TRY(fapi2::getMMIO(i_target, i_cfgAddr, 4, l_data)); - - if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN) - { - readLE(l_data, l_idx, l_rd); - } - else - { - readBE(l_data, l_idx, l_rd); - } - - o_data = l_rd; -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - -/// -/// @brief Converts a little endian data array to a host_fw_response_struct -/// @param[in] i_data little endian data to process -/// @param[out] o_crc computed CRC -/// @param[out] o_response response structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode host_fw_response_struct_from_little_endian(std::vector<uint8_t>& i_data, - uint32_t& o_crc, - host_fw_response_struct& o_response) -{ - uint32_t l_idx = 0; - - uint8_t l_response_id = 0; - uint8_t l_response_flags = 0; - uint16_t l_request_identifier = 0; - uint32_t l_response_length = 0; - uint32_t l_response_crc = 0; - uint32_t l_host_work_area = 0; - uint32_t l_response_header_crc = 0; - - FAPI_TRY(correctMMIOEndianForStruct(i_data)); - FAPI_TRY(correctMMIOword_order(i_data)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_id)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_flags)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_request_identifier)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_length)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_crc)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_host_work_area)); - FAPI_TRY(readCrctEndianArray(i_data, RSP_PADDING_SIZE, l_idx, o_response.padding)); - FAPI_TRY(readCrctEndianArray(i_data, ARGUMENT_SIZE, l_idx, o_response.response_argument)); - - o_response.response_id = l_response_id; - o_response.response_flags = l_response_flags; - o_response.request_identifier = l_request_identifier; - o_response.response_length = l_response_length; - o_response.response_crc = l_response_crc; - o_response.host_work_area = l_host_work_area; - - o_crc = crc32_gen(i_data, l_idx); - - FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_header_crc)); - o_response.response_header_crc = l_response_header_crc; - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Converts a little endian data array to a host_fw_response_struct -/// @param[in] i_target OCMB target on which to operate -/// @param[in] i_data little endian data to process -/// @param[out] o_response response structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// @note helper function to allow for checking FFDC -/// -fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - std::vector<uint8_t>& i_data, - host_fw_response_struct& o_response) -{ - uint32_t l_crc = 0; - fapi2::current_err = host_fw_response_struct_from_little_endian(i_data, l_crc, o_response); - FAPI_ASSERT( fapi2::current_err == fapi2::FAPI2_RC_SUCCESS, - fapi2::EXP_INBAND_LE_DATA_RANGE() - .set_TARGET(i_target) - .set_FUNCTION(mss::exp::READ_HOST_FW_RESPONSE_STRUCT) - .set_DATA_SIZE(i_data.size()) - .set_MAX_INDEX(sizeof(host_fw_response_struct)), - "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u", - mss::c_str(i_target), i_data.size(), sizeof(host_fw_response_struct)); - -//TODO CQ: SW461052 Correct MMIO CRC responses -#ifndef CONFIG_AXONE_BRING_UP - FAPI_ASSERT(l_crc == o_response.response_header_crc, - fapi2::EXP_INBAND_RSP_CRC_ERR() - .set_COMPUTED(l_crc) - .set_RECEIVED(o_response.response_header_crc) - .set_OCMB_TARGET(i_target), - "%s Response CRC failed to validate computed: 0x%08x got: 0x%08x", - mss::c_str(i_target), l_crc, o_response.response_header_crc); -#endif - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Polls for response ready door bell bit -/// @param[in] i_target the OCMB target on which to operate -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) -{ - // NUM_LOOPS is based on EXP_FW_DDR_PHY_INIT command, which completes in ~10ms in HW. - // We initially delay 8ms, so we should only need to poll for ~2ms here. - // We're waiting 100us between polls, so we should only need about 20 loops here, - // but we make it 200 to be safe - constexpr uint64_t NUM_LOOPS = 200; - - // So, why aren't we using the memory team's polling API? - // This is a base function that will be utilized by the platform code - // As such, we don't want to pull in more libraries than we need to: it would cause extra dependencies - // So, we're decomposing the polling library below - bool l_doorbell_response = false; - uint64_t l_loop = 0; - fapi2::buffer<uint64_t> l_data; - - // Loop until we max our our loop count or get a doorbell response - for(; l_loop < NUM_LOOPS && !l_doorbell_response; ++l_loop) - { - FAPI_TRY(fapi2::getScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data)); - l_doorbell_response = l_data.getBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>(); - FAPI_TRY( fapi2::delay(DELAY_100US, 200) ); - } - - FAPI_DBG("%s stopped on loop%u/%u data:0x%016lx %u", - mss::c_str(i_target), l_loop, NUM_LOOPS, l_data, l_doorbell_response); - - // Error check - doorbell response should be true - FAPI_ASSERT(l_doorbell_response, - fapi2::EXP_INBAND_RSP_NO_DOORBELL() - .set_OCMB_TARGET(i_target) - .set_DATA(l_data) - .set_NUM_LOOPS(l_loop), - "%s doorbell timed out after %u loops: data 0x%016lx", - mss::c_str(i_target), l_loop, l_data); - - // Ding-dong! the doorbell is rung and the response is ready - return fapi2::FAPI2_RC_SUCCESS; -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Clears outbound (response ready) door bell bit -/// @param[in] i_target the OCMB target on which to operate -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) -{ - fapi2::buffer<uint64_t> l_data; - - // Doorbell is cleared by writing a '1' to the doorbell bit - l_data.setBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>(); - - FAPI_DBG("%s Clearing outbound doorbell...", mss::c_str(i_target)); - FAPI_TRY(fapi2::putScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data)); - -fapi_try_exit: - return fapi2::current_err; -} - -/// @brief Reads a response from the response buffer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[out] o_rsp The response data read from the buffer -/// @param[out] o_data Raw (little-endian) response data buffer portion -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getRSP( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - host_fw_response_struct& o_rsp, - std::vector<uint8_t>& o_data) -{ - std::vector<uint8_t> l_data(static_cast<int>(sizeof(o_rsp))); - - // Polls for the response to be ready first - FAPI_TRY(poll_for_response_ready(i_target)); - - FAPI_DBG("Reading the response buffer..."); - FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_RSP_ADDR, BUFFER_TRANSACTION_SIZE, l_data)); - FAPI_TRY(host_fw_response_struct_from_little_endian(i_target, l_data, o_rsp)); - - FAPI_DBG("Checking if we have response data..."); - - // If response data in buffer portion, return that too - if (o_rsp.response_length > 0) - { - // make sure expected size is a multiple of 8 - const uint32_t l_padding = ((o_rsp.response_length % 8) > 0) ? (8 - (o_rsp.response_length % 8)) : 0; - o_data.resize( o_rsp.response_length + l_padding ); - FAPI_DBG("Reading response data..."); - - FAPI_TRY( fapi2::getMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, o_data) ); - FAPI_TRY( correctMMIOEndianForStruct(o_data) ); - FAPI_TRY( correctMMIOword_order(o_data) ); - } - else - { - FAPI_DBG("No response data returned..."); - // make sure no buffer data is returned - o_data.clear(); - } - - FAPI_TRY(clear_outbound_doorbell(i_target)); - -fapi_try_exit: - FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - - -/// -/// @brief Converts a little endian data array to a sensor_cache_struct -/// @param[in] i_data little endian data to process -/// @param[out] o_data sensor cache structure -/// @return true if success false if failure -/// @note helper function - returning a bool and will have true FFDC in a separate function -/// -fapi2::ReturnCode sensor_cache_struct_from_little_endian(std::vector<uint8_t>& i_data, - sensor_cache_struct& o_data) -{ - // Local variables to avoid error in passing packed struct fields by reference - uint32_t l_idx = 0; - uint16_t l_status = 0; - uint16_t l_ocmb_dts = 0; - uint16_t l_mem_dts0 = 0; - uint16_t l_mem_dts1 = 0; - uint32_t l_mba_reads = 0; - uint32_t l_mba_writes = 0; - uint32_t l_mba_activations = 0; - uint32_t l_mba_powerups = 0; - uint8_t l_self_timed_refresh = 0; - uint32_t l_frame_count = 0; - uint32_t l_mba_arrival_histo_base = 0; - uint32_t l_mba_arrival_histo_low = 0; - uint32_t l_mba_arrival_histo_med = 0; - uint32_t l_mba_arrival_histo_high = 0; - uint8_t l_initial_packet1 = 0; - - FAPI_TRY(correctMMIOEndianForStruct(i_data)); - FAPI_TRY(correctMMIOword_order(i_data)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_status)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_ocmb_dts)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts0)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts1)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_reads)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_writes)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_activations)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_powerups)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_self_timed_refresh)); - FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_0, l_idx, o_data.reserved0)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_frame_count)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_base)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_low)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_med)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_high)); - FAPI_TRY(readCrctEndian(i_data, l_idx, l_initial_packet1)); - - o_data.frame_count = l_frame_count; - o_data.mba_arrival_histo_base = l_mba_arrival_histo_base; - o_data.mba_arrival_histo_low = l_mba_arrival_histo_low; - o_data.mba_arrival_histo_med = l_mba_arrival_histo_med; - o_data.mba_arrival_histo_high = l_mba_arrival_histo_high; - o_data.initial_packet1 = l_initial_packet1; - o_data.status = l_status; - o_data.ocmb_dts = l_ocmb_dts; - o_data.mem_dts0 = l_mem_dts0; - o_data.mem_dts1 = l_mem_dts1; - o_data.mba_reads = l_mba_reads; - o_data.mba_writes = l_mba_writes; - o_data.mba_activations = l_mba_activations; - o_data.mba_powerups = l_mba_powerups; - o_data.self_timed_refresh = l_self_timed_refresh; - - FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_1, l_idx, o_data.reserved1)); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Converts a little endian data array to a sensor_cache_struct -/// @param[in] i_target OCMB target on which to operate -/// @param[in] i_data little endian data to process -/// @param[out] o_data sensor cache structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// @note helper function to allow for checking FFDC -/// -fapi2::ReturnCode sensor_cache_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - std::vector<uint8_t>& i_data, - sensor_cache_struct& o_data) -{ - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - FAPI_TRY(sensor_cache_struct_from_little_endian(i_data, o_data)); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Reads the complete 64 byte sensor cache on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[out] o_data The data read from the buffer -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode getSensorCache( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - sensor_cache_struct& o_data) -{ - std::vector<uint8_t> l_data(static_cast<int>(sizeof(o_data))); - - // The sensor cache is accessed exclusively via 2 32-byte MMIO reads - FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_SENSOR_CACHE_ADDR, 32, l_data)); - - FAPI_TRY(sensor_cache_struct_from_little_endian(i_target, l_data, o_data)); - -fapi_try_exit: - FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - -/// -/// @brief UT helper for correctMMIOEndianForStruct -/// -/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL -/// @param[in,out] io_data value to swizzle -/// -void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl, - std::vector<uint8_t>& io_data) -{ - size_t l_loops = 0; - - if (i_endian_ctrl == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_SWAP) - { - l_loops = io_data.size() / BUFFER_TRANSACTION_SIZE; - - for (size_t l_idx = 0; l_idx < l_loops; l_idx++) - { - for (int l_bidx = BUFFER_TRANSACTION_SIZE - 1; l_bidx >= 0; l_bidx--) - { - io_data.push_back(io_data.at(l_bidx)); - } - - io_data.erase(io_data.begin(), io_data.begin() + BUFFER_TRANSACTION_SIZE); - } - } -} - -/// -/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer -/// data structures. The byte order of the 4 or 8 byte reads should be little -/// endian. In order to represent the data structure in its proper layout -/// the endianness of each 4 or 8 byte read must be corrected. -/// @param[in,out] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type l_endian_ctrl; - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL, - FAPI_SYSTEM, l_endian_ctrl)); - correctMMIOEndianForStruct_helper(l_endian_ctrl, io_data); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - -/// -/// @brief UT helper for correctMMIOword_order -/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP -/// @param[in,out] io_data value to swizzle -/// -void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap, - std::vector<uint8_t>& io_data) -{ - if (i_word_swap == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_SWAP) - { - for (size_t l_idx = 0; l_idx < io_data.size(); l_idx += BUFFER_TRANSACTION_SIZE) - { - for (size_t l_bidx = l_idx; l_bidx < l_idx + BUFFER_TRANSACTION_SIZE / 2; l_bidx++) - { - uint8_t l_temp_first_word = io_data.at(l_bidx); - uint8_t l_temp_second_word = io_data.at(l_bidx + BUFFER_TRANSACTION_SIZE / 2); - io_data[l_bidx] = l_temp_second_word; - io_data[l_bidx + BUFFER_TRANSACTION_SIZE / 2] = l_temp_first_word; - } - } - } -} - -/// -/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, -/// we might need to swap 32-bit word order -/// @param[in,out] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type l_word_swap; - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP, - FAPI_SYSTEM, l_word_swap)); - correctMMIOword_order_helper(l_word_swap, io_data); - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - -/// -/// @brief Forces native data into the correct endianness necessary for Explorer -/// buffer data structures. -/// @tparam T the data type to process -/// @param[in] i_input inputted data to process -/// @param[in,out] io_data vector to append data to -/// -template < typename T > -fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, - FAPI_SYSTEM, l_struct_endian)); - - if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) - { - forceLE(i_input, io_data); - } - else - { - forceBE(i_input, io_data); - } - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - -/// -/// @brief Forces native data into the correct endianness for an array buffer -/// data structures. -/// @tparam T the data type to process -/// @param[in] i_input inputted data to process -/// @param[in] i_size size of the array -/// @param[in,out] io_data vector to append data to -/// -template < typename T > -fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, - FAPI_SYSTEM, l_struct_endian)); - - if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) - { - forceLEArray(i_input, i_size, io_data); - } - else - { - forceBEArray(i_input, i_size, io_data); - } - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - -/// -/// @brief Converts endianness of data read from Explorer buffer data structures -// into native order. -/// @tparam T the data type to output to -/// @param[in] i_input inputted data to process -/// @param[in,out] io_idx current index -/// @param[out] o_data data that has been converted into native endianness -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template < typename T > -fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, - FAPI_SYSTEM, l_struct_endian)); - - if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) - { - FAPI_ASSERT(readLE(i_input, io_idx, o_data), - fapi2::EXP_INBAND_LE_DATA_RANGE() - .set_TARGET(FAPI_SYSTEM) - .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) - .set_DATA_SIZE(i_input.size()) - .set_MAX_INDEX(sizeof(o_data)), - "Failed to convert from LE data read, size %u expected size %u", - i_input.size(), sizeof(o_data)); - } - else - { - FAPI_ASSERT(readBE(i_input, io_idx, o_data), - fapi2::EXP_INBAND_BE_DATA_RANGE() - .set_TARGET(FAPI_SYSTEM) - .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) - .set_DATA_SIZE(i_input.size()) - .set_MAX_INDEX(sizeof(o_data)), - "Failed to convert from BE data read, size %u expected size %u", - i_input.size(), sizeof(o_data)); - } - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - - -template < typename T > -fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx, - T* o_data) -{ - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, - FAPI_SYSTEM, l_struct_endian)); - - if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) - { - FAPI_ASSERT(readLEArray(i_input, i_size, io_idx, o_data), - fapi2::EXP_INBAND_LE_DATA_RANGE() - .set_TARGET(FAPI_SYSTEM) - .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) - .set_DATA_SIZE(i_input.size()) - .set_MAX_INDEX(sizeof(o_data)), - "Failed to convert from LE array data read, size %u expected size %u", - i_input.size(), sizeof(o_data)); - } - else - { - FAPI_ASSERT(readBEArray(i_input, i_size, io_idx, o_data), - fapi2::EXP_INBAND_BE_DATA_RANGE() - .set_TARGET(FAPI_SYSTEM) - .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) - .set_DATA_SIZE(i_input.size()) - .set_MAX_INDEX(sizeof(o_data)), - "Failed to convert from BE array data read, size %u expected size %u", - i_input.size(), sizeof(o_data)); - } - -fapi_try_exit: - FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err); - return fapi2::current_err; -} - - -} // ns ib - -} // ns exp - -} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H deleted file mode 100644 index 19c015a3f..000000000 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H +++ /dev/null @@ -1,531 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2018,2019 */ -/* [+] 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 exp_inband.H -/// @brief Explorer specifics for get/putMMIO inband ops -/// -/// One Axone bar register is set per MC channel for MMIO, and another -/// is set per MC channel for config space. Each bar is shared between -/// both sub-channels each with an OCMB. The upper bit of the address -/// determined by the bar sizes is used to determine which sub-channel -/// is selected. This means that for a pair of OCMB's on a channel -/// their config space is contiguous and their MMIO space is contiguous. -/// Therefore a single OCMB's MMIO and config space cannot be contiguous. -/// However, we can still use one BAR attribute and the set_bars procedure -/// can interleave the config space and MMIO space as shown in the table -/// bellow. For example, both MMIO and config bar sizes are 2GB. The -/// 2GB bit becomes the selector for the subchannel. The 4GB bit -/// becomes the offset applied for MMIO operations. -/// -/// -/// Each OCMB is assigned one base address attribute. For example: -/// ocmb | BAR ATTRIBUTE | Type | Base reg - end addr | size | sub-ch -/// +-----+--------------------+------+-----------------------------------------+------+------- -/// ocmb0 | 0x0006030200000000 | cnfg | 0x0006030200000000 - 0x000603027FFFFFFF | 2GB | 0 -/// ocmb1 | 0x0006030280000000 | cnfg | 0x0006030280000000 - 0x00060302FFFFFFFF | 2GB | 1 -/// ocmb0 | N/A | mmio | 0x0006030300000000 - 0x000603037FFFFFFF | 2GB | 0 -/// ocmb1 | N/A | mmio | 0x0006030380000000 - 0x00060303FFFFFFFF | 2GB | 1 -/// +-----+--------------------+------+-----------------------------------------+------+------- -/// ocmb2 | 0x0006030400000000 | cnfg | 0x0006030400000000 - 0x000603047FFFFFFF | 2GB | 0 -/// ocmb3 | 0x0006030480000000 | cnfg | 0x0006030480000000 - 0x00060304FFFFFFFF | 2GB | 1 -/// ocmb2 | N/A | mmio | 0x0006030500000000 - 0x000603057FFFFFFF | 2GB | 0 -/// ocmb3 | N/A | mmio | 0x0006030580000000 - 0x00060305FFFFFFFF | 2GB | 1 -/// -/// Bit 33 of the 64 bit address in big endian order determines if -/// the MMIO operation is a SCOM to the core or a register access -/// to MSCC space. If an MSCC access falls within the range specified -/// by the MSCCRNGE core register it is an access to the MIPS SRAM. -/// Specific locations within the SRAM have been set asside for command -/// and response buffers. Once written an interrupt must be issued -/// to MIPS indicating a new command is ready. Responses will send -/// an interrupt back to the host. -/// -/// Table 4-8:- Address of various buffers -/// Buffer Type MIPS view (un-cached) Host View (OpenCapi) I2C View -/// Command Buffer 0xA103 FF40 BAR + 0x0103 FF40 0xA103 FF40 -/// Response Buffer 0xA103 FF00 BAR + 0x0103 FF00 0xA103 FF00 -/// Data Buffer 0xA102 FF00 BAR + 0x0102 FF00 0xA102 FF00 -/// - -/// @file exp_inband.H -/// @brief implement OpenCAPI config, scom, and MSCC MMIO operations. -// -// *HWP HWP Owner: bgass@us.ibm.com -// *HWP FW Owner: dcrowell@us.ibm.com -// *HWP Team: -// *HWP Level: 2 -// *HWP Consumed by: HB -// -//-------------------------------------------------------------------------------- - -#ifndef __EXP_INBAND_H_ -#define __EXP_INBAND_H_ - -#include <fapi2.H> -#include <exp_data_structs.H> -#include <explorer_scom_addresses.H> -#include <explorer_scom_addresses_fld.H> -#include <explorer_scom_addresses_fixes.H> -#include <explorer_scom_addresses_fld_fixes.H> -#include <generic/memory/lib/utils/shared/mss_generic_consts.H> - -namespace mss -{ - -namespace exp -{ - -namespace ib -{ - -static const size_t BUFFER_TRANSACTION_SIZE = 8; - -static const uint64_t EXPLR_IB_CONFIG_OFFSET = 0x0000000000000000ull; -static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB -static const uint64_t EXPLR_IB_BAR_SIZE = 0b01111111; // 4GB Depends on EXPLR_IB_MMIO_OFFSET -static const uint64_t EXPLR_IB_BAR_B_BIT = EXPLR_IB_MMIO_OFFSET >> 1; // 2GB AND with A == 0, AND with B != 0 -static const uint64_t EXPLR_IB_BAR_MASK_ZERO = (EXPLR_IB_BAR_B_BIT - 1); // AND with BAR must == 0 - -//-------------------------------------------------------------------------------- -// The MSCC RAM Range Register SCOM 0x080108e5 MSCCRNGE -// determines the address range for the MIPS SRAM -// An offset within the the 1MB range is used for the command -// -/// Table 4-8:- Address of various buffers 64K 0x1 0000 -/// Buffer Type MIPS view (un-cached) Host View (OpenCapi) I2C View -/// Command Buffer 0xA103 FF40 BAR + 0x0103 FF40 0xA103 FF40 -/// Response Buffer 0xA103 FF00 BAR + 0x0103 FF00 0xA103 FF00 -/// Data Buffer 0xA102 FF00 BAR + 0x0102 FF00 0xA102 FF00 -/// -static const uint64_t EXPLR_IB_SRAM_BASE = 0x01000000; // MSCCRNGE 01000000 020FFFFF -static const uint64_t EXPLR_IB_CMD_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF40; -static const uint64_t EXPLR_IB_RSP_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF00; -static const uint64_t EXPLR_IB_DATA_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x02FF00; - -static const uint64_t EXPLR_IB_CMD_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_CMD_SRAM_ADDR; -static const uint64_t EXPLR_IB_RSP_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_RSP_SRAM_ADDR; -static const uint64_t EXPLR_IB_DATA_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_DATA_SRAM_ADDR; - -static const uint64_t EXPLR_IB_SENSOR_CACHE_ADDR = EXPLR_IB_MMIO_OFFSET | 0x40084200; - -//-------------------------------------------------------------------------------- -// Utilities -//-------------------------------------------------------------------------------- - -/// -/// @brief Converts user_input_msdg to little endian and calculates the crc -/// @param[in] i_input user_input_msdg structure to convert -/// @param[out] o_data vector of bytes for mmio -/// @param[out] o_crc the calculated crc of the data -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_input, std::vector<uint8_t>& o_data, - uint32_t& o_crc); - -/// -/// @brief Converts host_fw_command_struct to little endian -/// @param[in] i_input user_input_msdg structure to convert -/// @param[out] o_data vector of bytes for mmio. -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_struct& i_input, - std::vector<uint8_t>& o_data); - -/// -/// @brief Converts a little endian data array to a host_fw_response_struct -/// @param[in] i_data little endian data to process -/// @param[out] o_crc computed CRC -/// @param[out] o_response response structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode host_fw_response_struct_from_little_endian(std::vector<uint8_t>& i_data, - uint32_t& o_crc, - host_fw_response_struct& o_response); - -/// -/// @brief Converts a little endian data array to a host_fw_response_struct -/// @param[in] i_target OCMB target on which to operate -/// @param[in] i_data little endian data to process -/// @param[out] o_response response structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// @note helper function to allow for checking FFDC -/// -fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - std::vector<uint8_t>& i_data, - host_fw_response_struct& o_response); - -/// -/// @brief Converts a little endian data array to a sensor_cache_struct -/// @param[in] i_data little endian data to process -/// @param[out] o_data sensor cache structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// @note helper function - returning a bool and will have true FFDC in a separate function -/// -fapi2::ReturnCode sensor_cache_struct_from_little_endian(std::vector<uint8_t>& i_data, - sensor_cache_struct& o_data); - -/// -/// @brief Converts a little endian data array to a sensor_cache_struct -/// @param[in] i_target OCMB target on which to operate -/// @param[in] i_data little endian data to process -/// @param[out] o_data sensor cache structure -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// @note helper function to allow for checking FFDC -/// -fapi2::ReturnCode sensor_cache_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - std::vector<uint8_t>& i_data, - sensor_cache_struct& o_data); - -//-------------------------------------------------------------------------------- -// Write operations -//-------------------------------------------------------------------------------- - -/// @brief Writes 64 bits of data to MMIO space to the selected Explorer -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_addr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putMMIO64( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - const fapi2::buffer<uint64_t>& i_data ) ; - - - - -/// @brief Writes 32 bits of data to MMIO space to the selected Explorer -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_addr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putMMIO32( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - const fapi2::buffer<uint32_t>& i_data ) ; - - - - -/// @brief Writes 64 bits of data to SCOM MMIO space -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_scomAddr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putScom( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_scomAddr, - const fapi2::buffer<uint64_t>& i_data) ; - - - - -/// @brief Writes 32 bits of data to OpenCAPI config space -/// -/// @param[in] i_target The Explorer chip to write -/// @param[in] i_cfgAddr The address to write -/// @param[in] i_data The data to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putOCCfg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_cfgAddr, - const fapi2::buffer<uint32_t>& i_data) ; - - - - -/// @brief Writes user_input_msdg to the data buffer -/// -/// @param[in] i_target The Explorer chip to issue the command to -/// @param[in] i_data The user_input_msdg data to write -/// @param[out] o_crc The calculated crc of the data. -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putUserInputMsdg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const user_input_msdg& i_data, - uint32_t& o_crc); - - - - -/// @brief Writes a command to the command buffer and issues interrupt -/// -/// @param[in] i_target The Explorer chip to issue the command to -/// @param[in] i_cmd The command structure to write -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode putCMD( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const host_fw_command_struct& i_cmd) ; - - - -//-------------------------------------------------------------------------------- -// Read operations -//-------------------------------------------------------------------------------- - -/// @brief Reads 64 bits of data from MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_addr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getMMIO64( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - fapi2::buffer<uint64_t>& o_data) ; - - - - -/// @brief Reads 32 bits of data from MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_addr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getMMIO32( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_addr, - fapi2::buffer<uint32_t>& o_data) ; - - - - -/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_scomAddr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getScom( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_scomAddr, - fapi2::buffer<uint64_t>& o_data) ; - - - - -/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[in] i_cfgAddr The address to read -/// @param[out] o_data The data read from the address -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getOCCfg( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - const uint64_t i_cfgAddr, - fapi2::buffer<uint32_t>& o_data) ; - -/// -/// @brief Polls for response ready door bell bit -/// @param[in] i_target the OCMB target on which to operate -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); - -/// -/// @brief Clears outbound (response ready) door bell bit -/// @param[in] i_target the OCMB target on which to operate -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); - -/// @brief Reads a response from the response buffer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[out] o_rsp The response data read from the buffer -/// @param[out] o_data Raw (little-endian) response data buffer portion -/// The size of this buffer will be a multiple of 8 -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getRSP( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - host_fw_response_struct& o_rsp, - std::vector<uint8_t>& o_data) ; - - - - -/// @brief Reads the complete 64 byte sensor cache on the selected Explorer -/// -/// @param[in] i_target The Explorer chip to read data from -/// @param[out] o_data The data read from the buffer -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode getSensorCache( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - sensor_cache_struct& o_data) ; - -//-------------------------------------------------------------------------------- -// Command/Response/Data structure Endian handling -//-------------------------------------------------------------------------------- - -/// -/// @brief UT helper for correctMMIOEndianForStruct -/// -/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL -/// @param[in,out] io_data value to swizzle -/// -void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl, - std::vector<uint8_t>& io_data); - -/// -/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer -/// data structures. The byte order of the 4 or 8 byte reads should be little -/// endian. In order to represent the data structure in its proper layout -/// the endianness of each 4 or 8 byte read must be corrected. -/// @param[in,out] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data); - -/// -/// @brief UT helper for correctMMIOword_order -/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP -/// @param[in,out] io_data value to swizzle -/// -void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap, - std::vector<uint8_t>& io_data); - -/// -/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, -/// we might need to swap 32-bit word order -/// @param[in,out] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data); - -/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer -/// data structures. The byte order of the 4 or 8 byte reads should be little -/// endian. In order to represent the data structure in its proper layout -/// the endianness of each 4 or 8 byte read must be corrected. -/// -/// @param[inout] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data); - -/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, -/// we might need to swap 32-bit word order -/// @param[in,out] io_data Either data structure in proper byte order that we -/// want to swizzle prior to writing to the buffer, or the data returned -/// from reading the buffer that we want to unsizzle. -/// -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data); - -/// @brief Ensure data is an even multiple of 8 (BUFFER_TRANSACTION_SIZE). -/// If (sizeof(buffer) % BUFFER_TRANSACTION_SIZE != 0) ; then pad -/// buffer with zeros until statement is true. -/// -/// @param[in,out] io_data Communication data , either CMD or RSP buffer -/// -/// @return void -inline void padCommData(std::vector<uint8_t>& io_data) -{ - while ((io_data.size() % BUFFER_TRANSACTION_SIZE) != 0) - { - io_data.push_back(0); - } -} - -/// -/// @brief Forces native data into the correct endianness necessary for Explorer -/// buffer data structures. -/// @tparam T the data type to process -/// @param[in] i_input inputted data to process -/// @param[in,out] io_data vector to append data to -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template < typename T > -fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data); - -/// -/// @brief Forces native data into the correct endianness for an array buffer -/// data structures. -/// @tparam T the data type to process -/// @param[in] i_input inputted data to process -/// @param[in] i_size size of the array -/// @param[in,out] io_data vector to append data to -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template < typename T > -fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data); - -/// -/// @brief Converts endianness of data read from Explorer buffer data structures -// into native order. -/// @tparam T the data type to output to -/// @param[in] i_input inputted data to process -/// @param[in,out] io_idx current index -/// @param[out] o_data data that has been converted into native endianness -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template < typename T > -fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data); - -/// -/// @brief Converts endianness of data read from Explorer buffer data structures -/// into native order. -/// @tparam T the data type to output to -/// @param[in] i_input inputted data to process -/// @param[in] i_size size of the array -/// @param[in,out] io_idx current index -/// @param[out] o_data data that has been converted into native endianness -/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. -/// -template < typename T > -fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx, - T* o_data); - -//-------------------------------------------------------------------------------- - -} // ns ib - -} // ns exp - -} // ns mss - -#endif diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk deleted file mode 100644 index 3f998fd58..000000000 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk +++ /dev/null @@ -1,32 +0,0 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk $ -# -# 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 -PROCEDURE=exp_inband -$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/nest) -$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/include) -# Explicitly calling the below to only pick up the generic constants -# We don't want to clutter this procedure w/ too many includes -$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)) -$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/procedures/hwp/memory) -$(call BUILD_PROCEDURE) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C index 60ab6e728..396a33804 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C @@ -36,7 +36,7 @@ #include <fapi2.H> #include <generic/memory/lib/utils/find.H> #include <lib/exp_mss_thermal_init_utils.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <exp_mss_thermal_init.H> extern "C" diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk index 8268acd79..270920f4f 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk @@ -28,5 +28,4 @@ PROCEDURE=exp_mss_thermal_init $(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE))) -lib$(PROCEDURE)_DEPLIBS+=exp_inband $(call BUILD_PROCEDURE) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C index 262919cff..94929c1cb 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C @@ -34,7 +34,7 @@ #include <exp_omi_init.H> #include <exp_oc_regs.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <chips/common/utils/chipids.H> #include <mss_explorer_attribute_getters.H> #include <mss_p9a_attribute_getters.H> diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk index 47ba72a6c..ff0e0a5ff 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk @@ -25,7 +25,6 @@ # Makefile for exp_omi_init HWP PROCEDURE=exp_omi_init $(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE))) -lib$(PROCEDURE)_DEPLIBS+=exp_inband $(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/include) $(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/inband) $(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/nest) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C index 6d04a2689..6ddfd5bb7 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C @@ -35,7 +35,7 @@ #include <fapi2.H> #include <lib/exp_mss_thermal_init_utils.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <lib/shared/exp_consts.H> #include <generic/memory/lib/utils/c_str.H> #include <explorer_scom_addresses.H> diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C index 2f8673f90..24c196277 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C @@ -22,3 +22,963 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// @file exp_inband.C +/// @brief implement OpenCAPI config, scom, and MSCC MMIO operations. +// +// *HWP HWP Owner: bgass@us.ibm.com +// *HWP FW Owner: dcrowell@us.ibm.com +// *HWP Team: +// *HWP Level: 2 +// *HWP Consumed by: HB + +#include <lib/inband/exp_inband.H> +#include <lib/omi/crc32.H> +#include <lib/shared/exp_consts.H> + +#include <mmio_access.H> +#include <generic/memory/lib/utils/c_str.H> +#include <generic/memory/lib/utils/endian_utils.H> + +namespace mss +{ + +namespace exp +{ + +namespace ib +{ + +//-------------------------------------------------------------------------------- +// Write operations +//-------------------------------------------------------------------------------- + +/// @brief Writes 64 bits of data to MMIO space to the selected Explorer +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_addr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putMMIO64( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + const fapi2::buffer<uint64_t>& i_data) +{ + uint64_t l_v = static_cast<uint64_t>(i_data); + std::vector<uint8_t> l_wd; + forceLE(l_v, l_wd); + return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 8, l_wd); +} + +/// @brief Writes 32 bits of data to MMIO space to the selected Explorer +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_addr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putMMIO32( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + const fapi2::buffer<uint32_t>& i_data) +{ + uint32_t l_v = static_cast<uint32_t>(i_data); + std::vector<uint8_t> l_wd; + forceLE(l_v, l_wd); + return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 4, l_wd); +} + +/// @brief Writes 64 bits of data to SCOM MMIO space +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_scomAddr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putScom( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_scomAddr, + const fapi2::buffer<uint64_t>& i_data) +{ + // Converts from the scom address to the MMIO address by shifting left by 3 bits + uint64_t l_scomAddr = i_scomAddr << OCMB_ADDR_SHIFT; + return putMMIO64(i_target, l_scomAddr, i_data); +} + +/// @brief Writes 32 bits of data to OpenCAPI config space +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_cfgAddr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putOCCfg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_cfgAddr, + const fapi2::buffer<uint32_t>& i_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + uint32_t l_v = static_cast<uint32_t>(i_data); + std::vector<uint8_t> l_wd; + fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL, + FAPI_SYSTEM, l_endian)); + + if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN) + { + forceLE(l_v, l_wd); + } + else + { + forceBE(l_v, l_wd); + } + + FAPI_TRY(fapi2::putMMIO(i_target, i_cfgAddr, 4, l_wd)); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_input, std::vector<uint8_t>& o_data, + uint32_t& o_crc) +{ + o_data.clear(); + FAPI_TRY(forceCrctEndian(i_input.version_number, o_data)); + FAPI_TRY(forceCrctEndian(i_input.DimmType, o_data)); + FAPI_TRY(forceCrctEndian(i_input.CsPresent, o_data)); + FAPI_TRY(forceCrctEndian(i_input.DramDataWidth, o_data)); + FAPI_TRY(forceCrctEndian(i_input.Height3DS, o_data)); + FAPI_TRY(forceCrctEndian(i_input.ActiveDBYTE, o_data)); + FAPI_TRY(forceCrctEndian(i_input.ActiveNibble, o_data)); + FAPI_TRY(forceCrctEndian(i_input.AddrMirror, o_data)); + FAPI_TRY(forceCrctEndian(i_input.ColumnAddrWidth, o_data)); + FAPI_TRY(forceCrctEndian(i_input.RowAddrWidth, o_data)); + FAPI_TRY(forceCrctEndian(i_input.SpdCLSupported, o_data)); + FAPI_TRY(forceCrctEndian(i_input.SpdtAAmin, o_data)); + FAPI_TRY(forceCrctEndian(i_input.Rank4Mode, o_data)); + FAPI_TRY(forceCrctEndian(i_input.EncodedQuadCs, o_data)); + FAPI_TRY(forceCrctEndian(i_input.DDPCompatible, o_data)); + FAPI_TRY(forceCrctEndian(i_input.TSV8HSupport, o_data)); + FAPI_TRY(forceCrctEndian(i_input.MRAMSupport, o_data)); + FAPI_TRY(forceCrctEndian(i_input.MDSSupport, o_data)); + FAPI_TRY(forceCrctEndian(i_input.NumPStates, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.Frequency, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.PhyOdtImpedance, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.PhyDrvImpedancePU, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.PhyDrvImpedancePD, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.PhySlewRate, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndian(i_input.ATxImpedance, o_data)); + FAPI_TRY(forceCrctEndian(i_input.ATxSlewRate, o_data)); + FAPI_TRY(forceCrctEndian(i_input.CKTxImpedance, o_data)); + FAPI_TRY(forceCrctEndian(i_input.CKTxSlewRate, o_data)); + FAPI_TRY(forceCrctEndian(i_input.AlertOdtImpedance, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR0, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR1, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR2, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttNomR3, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR0, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR1, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR2, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttWrR3, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR0, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR1, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR2, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramRttParkR3, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramDic, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramWritePreamble, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.DramReadPreamble, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.PhyEqualization, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.InitVrefDQ, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.InitPhyVref, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.OdtWrMapCs, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.OdtRdMapCs, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.Geardown, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.CALatencyAdder, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.BistCALMode, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.BistCAParityLatency, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.RcdDic, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.RcdVoltageCtrl, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.RcdIBTCtrl, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.RcdDBDic, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.RcdSlewRate, MSDG_MAX_PSTATE, o_data)); + FAPI_TRY(forceCrctEndian(i_input.DFIMRL_DDRCLK, o_data)); + + for (uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate) + { + FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_A[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data)); + } + + for (uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate) + { + FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_B[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data)); + } + + o_crc = crc32_gen(o_data); + + padCommData(o_data); + FAPI_TRY(correctMMIOEndianForStruct(o_data)); + FAPI_TRY(correctMMIOword_order(o_data)); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// @brief Writes user_input_msdg to the data buffer +/// +/// @param[in] i_target The Explorer chip to issue the command to +/// @param[in] i_data The user_input_msdg data to write +/// @param[out] o_crc The calculated crc of the data. +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putUserInputMsdg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const user_input_msdg& i_data, + uint32_t& o_crc) +{ + std::vector<uint8_t> l_data; + + FAPI_TRY(user_input_msdg_to_little_endian(i_data, l_data, o_crc)); + + FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, l_data)); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_struct& i_input, + std::vector<uint8_t>& o_data) +{ + uint32_t l_cmd_header_crc = 0; + FAPI_TRY(forceCrctEndian(i_input.cmd_id, o_data)); + FAPI_TRY(forceCrctEndian(i_input.cmd_flags, o_data)); + FAPI_TRY(forceCrctEndian(i_input.request_identifier, o_data)); + FAPI_TRY(forceCrctEndian(i_input.cmd_length, o_data)); + FAPI_TRY(forceCrctEndian(i_input.cmd_crc, o_data)); + FAPI_TRY(forceCrctEndian(i_input.host_work_area, o_data)); + FAPI_TRY(forceCrctEndian(i_input.cmd_work_area, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.padding, CMD_PADDING_SIZE, o_data)); + FAPI_TRY(forceCrctEndianArray(i_input.command_argument, ARGUMENT_SIZE, o_data)); + + // Generates and adds on the CRC + l_cmd_header_crc = crc32_gen(o_data); + FAPI_DBG("Command header crc: %xl", l_cmd_header_crc); + FAPI_TRY(forceCrctEndian(l_cmd_header_crc, o_data)); + padCommData(o_data); + FAPI_TRY(correctMMIOEndianForStruct(o_data)); + FAPI_TRY(correctMMIOword_order(o_data)); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// @brief Writes a command to the command buffer and issues interrupt +/// +/// @param[in] i_target The Explorer chip to issue the command to +/// @param[in] i_cmd The command structure to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putCMD( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const host_fw_command_struct& i_cmd) +{ + std::vector<uint8_t> l_data; + fapi2::buffer<uint64_t> l_scom; + + FAPI_TRY(host_fw_command_struct_to_little_endian(i_cmd, l_data)); + + // Clear the doorbell + l_scom.setBit<EXPLR_MMIO_MDBELLC_MDBELL_MDBELL>(); + FAPI_DBG("Clearing the inbound doorbell..."); + FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELLC, l_scom), "Failed to clear inbound doorbell register"); + + // Clear the response doorbell, just in case the last response didn't get cleared + FAPI_TRY(clear_outbound_doorbell(i_target)); + + // Set the command + FAPI_DBG("Writing the command..."); + FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_CMD_ADDR, BUFFER_TRANSACTION_SIZE, l_data), + "Failed to write to the command buffer"); + + // Ring the doorbell - aka the bit that interrupts the microchip FW and tells it to do the thing + l_scom.flush<0>(); + l_scom.setBit<EXPLR_MMIO_MDBELL_MDBELL>(); + FAPI_DBG("Setting the inbound doorbell..."); + FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELL, l_scom), "Failed to set inbound doorbell bit"); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +//-------------------------------------------------------------------------------- +// Read operations +//-------------------------------------------------------------------------------- + +/// @brief Reads 64 bits of data from MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_addr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getMMIO64( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + fapi2::buffer<uint64_t>& o_data) +{ + uint64_t l_rd = 0; + std::vector<uint8_t> l_data(8); + uint32_t l_idx = 0; + FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 8, l_data)); + readLE(l_data, l_idx, l_rd); + o_data = l_rd; +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// @brief Reads 32 bits of data from MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_addr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getMMIO32( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + fapi2::buffer<uint32_t>& o_data) +{ + uint32_t l_rd = 0; + std::vector<uint8_t> l_data(4); + uint32_t l_idx = 0; + FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 4, l_data)); + readLE(l_data, l_idx, l_rd); + o_data = l_rd; +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_scomAddr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getScom( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_scomAddr, + fapi2::buffer<uint64_t>& o_data) +{ + // Converts from the scom address to the MMIO address by shifting left by 3 bits + uint64_t l_scomAddr = i_scomAddr << OCMB_ADDR_SHIFT; + return getMMIO64(i_target, l_scomAddr, o_data); +} + +/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_cfgAddr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getOCCfg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_cfgAddr, + fapi2::buffer<uint32_t>& o_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + uint32_t l_rd = 0; + std::vector<uint8_t> l_data(4); + uint32_t l_idx = 0; + fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL, + FAPI_SYSTEM, l_endian)); + + FAPI_TRY(fapi2::getMMIO(i_target, i_cfgAddr, 4, l_data)); + + if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN) + { + readLE(l_data, l_idx, l_rd); + } + else + { + readBE(l_data, l_idx, l_rd); + } + + o_data = l_rd; +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief Converts a little endian data array to a host_fw_response_struct +/// @param[in] i_data little endian data to process +/// @param[out] o_crc computed CRC +/// @param[out] o_response response structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode host_fw_response_struct_from_little_endian(std::vector<uint8_t>& i_data, + uint32_t& o_crc, + host_fw_response_struct& o_response) +{ + uint32_t l_idx = 0; + + uint8_t l_response_id = 0; + uint8_t l_response_flags = 0; + uint16_t l_request_identifier = 0; + uint32_t l_response_length = 0; + uint32_t l_response_crc = 0; + uint32_t l_host_work_area = 0; + uint32_t l_response_header_crc = 0; + + FAPI_TRY(correctMMIOEndianForStruct(i_data)); + FAPI_TRY(correctMMIOword_order(i_data)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_id)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_flags)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_request_identifier)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_length)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_crc)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_host_work_area)); + FAPI_TRY(readCrctEndianArray(i_data, RSP_PADDING_SIZE, l_idx, o_response.padding)); + FAPI_TRY(readCrctEndianArray(i_data, ARGUMENT_SIZE, l_idx, o_response.response_argument)); + + o_response.response_id = l_response_id; + o_response.response_flags = l_response_flags; + o_response.request_identifier = l_request_identifier; + o_response.response_length = l_response_length; + o_response.response_crc = l_response_crc; + o_response.host_work_area = l_host_work_area; + + o_crc = crc32_gen(i_data, l_idx); + + FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_header_crc)); + o_response.response_header_crc = l_response_header_crc; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Converts a little endian data array to a host_fw_response_struct +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_data little endian data to process +/// @param[out] o_response response structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @note helper function to allow for checking FFDC +/// +fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& + i_target, + std::vector<uint8_t>& i_data, + host_fw_response_struct& o_response) +{ + uint32_t l_crc = 0; + fapi2::current_err = host_fw_response_struct_from_little_endian(i_data, l_crc, o_response); + FAPI_ASSERT(fapi2::current_err == fapi2::FAPI2_RC_SUCCESS, + fapi2::EXP_INBAND_LE_DATA_RANGE() + .set_TARGET(i_target) + .set_FUNCTION(mss::exp::READ_HOST_FW_RESPONSE_STRUCT) + .set_DATA_SIZE(i_data.size()) + .set_MAX_INDEX(sizeof(host_fw_response_struct)), + "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u", + mss::c_str(i_target), i_data.size(), sizeof(host_fw_response_struct)); + +//TODO CQ: SW461052 Correct MMIO CRC responses +#ifndef CONFIG_AXONE_BRING_UP + FAPI_ASSERT(l_crc == o_response.response_header_crc, + fapi2::EXP_INBAND_RSP_CRC_ERR() + .set_COMPUTED(l_crc) + .set_RECEIVED(o_response.response_header_crc) + .set_OCMB_TARGET(i_target), + "%s Response CRC failed to validate computed: 0x%08x got: 0x%08x", + mss::c_str(i_target), l_crc, o_response.response_header_crc); +#endif + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Polls for response ready door bell bit +/// @param[in] i_target the OCMB target on which to operate +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + // NUM_LOOPS is based on EXP_FW_DDR_PHY_INIT command, which completes in ~10ms in HW. + // We initially delay 8ms, so we should only need to poll for ~2ms here. + // We're waiting 100us between polls, so we should only need about 20 loops here, + // but we make it 200 to be safe + constexpr uint64_t NUM_LOOPS = 200; + + // So, why aren't we using the memory team's polling API? + // This is a base function that will be utilized by the platform code + // As such, we don't want to pull in more libraries than we need to: it would cause extra dependencies + // So, we're decomposing the polling library below + bool l_doorbell_response = false; + uint64_t l_loop = 0; + fapi2::buffer<uint64_t> l_data; + + // Loop until we max our our loop count or get a doorbell response + for (; l_loop < NUM_LOOPS && !l_doorbell_response; ++l_loop) + { + FAPI_TRY(fapi2::getScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data)); + l_doorbell_response = l_data.getBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>(); + FAPI_TRY(fapi2::delay(DELAY_100US, 200)); + } + + FAPI_DBG("%s stopped on loop%u/%u data:0x%016lx %u", + mss::c_str(i_target), l_loop, NUM_LOOPS, l_data, l_doorbell_response); + + // Error check - doorbell response should be true + FAPI_ASSERT(l_doorbell_response, + fapi2::EXP_INBAND_RSP_NO_DOORBELL() + .set_OCMB_TARGET(i_target) + .set_DATA(l_data) + .set_NUM_LOOPS(l_loop), + "%s doorbell timed out after %u loops: data 0x%016lx", + mss::c_str(i_target), l_loop, l_data); + + // Ding-dong! the doorbell is rung and the response is ready + return fapi2::FAPI2_RC_SUCCESS; +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Clears outbound (response ready) door bell bit +/// @param[in] i_target the OCMB target on which to operate +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + fapi2::buffer<uint64_t> l_data; + + // Doorbell is cleared by writing a '1' to the doorbell bit + l_data.setBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>(); + + FAPI_DBG("%s Clearing outbound doorbell...", mss::c_str(i_target)); + FAPI_TRY(fapi2::putScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// @brief Reads a response from the response buffer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[out] o_rsp The response data read from the buffer +/// @param[out] o_data Raw (little-endian) response data buffer portion +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getRSP( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + host_fw_response_struct& o_rsp, + std::vector<uint8_t>& o_data) +{ + std::vector<uint8_t> l_data(static_cast<int>(sizeof(o_rsp))); + + // Polls for the response to be ready first + FAPI_TRY(poll_for_response_ready(i_target)); + + FAPI_DBG("Reading the response buffer..."); + FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_RSP_ADDR, BUFFER_TRANSACTION_SIZE, l_data)); + FAPI_TRY(host_fw_response_struct_from_little_endian(i_target, l_data, o_rsp)); + + FAPI_DBG("Checking if we have response data..."); + + // If response data in buffer portion, return that too + if (o_rsp.response_length > 0) + { + // make sure expected size is a multiple of 8 + const uint32_t l_padding = ((o_rsp.response_length % 8) > 0) ? (8 - (o_rsp.response_length % 8)) : 0; + o_data.resize(o_rsp.response_length + l_padding); + FAPI_DBG("Reading response data..."); + + FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, o_data)); + FAPI_TRY(correctMMIOEndianForStruct(o_data)); + FAPI_TRY(correctMMIOword_order(o_data)); + } + else + { + FAPI_DBG("No response data returned..."); + // make sure no buffer data is returned + o_data.clear(); + } + + FAPI_TRY(clear_outbound_doorbell(i_target)); + +fapi_try_exit: + FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief Converts a little endian data array to a sensor_cache_struct +/// @param[in] i_data little endian data to process +/// @param[out] o_data sensor cache structure +/// @return true if success false if failure +/// @note helper function - returning a bool and will have true FFDC in a separate function +/// +fapi2::ReturnCode sensor_cache_struct_from_little_endian(std::vector<uint8_t>& i_data, + sensor_cache_struct& o_data) +{ + // Local variables to avoid error in passing packed struct fields by reference + uint32_t l_idx = 0; + uint16_t l_status = 0; + uint16_t l_ocmb_dts = 0; + uint16_t l_mem_dts0 = 0; + uint16_t l_mem_dts1 = 0; + uint32_t l_mba_reads = 0; + uint32_t l_mba_writes = 0; + uint32_t l_mba_activations = 0; + uint32_t l_mba_powerups = 0; + uint8_t l_self_timed_refresh = 0; + uint32_t l_frame_count = 0; + uint32_t l_mba_arrival_histo_base = 0; + uint32_t l_mba_arrival_histo_low = 0; + uint32_t l_mba_arrival_histo_med = 0; + uint32_t l_mba_arrival_histo_high = 0; + uint8_t l_initial_packet1 = 0; + + FAPI_TRY(correctMMIOEndianForStruct(i_data)); + FAPI_TRY(correctMMIOword_order(i_data)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_status)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_ocmb_dts)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts0)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts1)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_reads)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_writes)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_activations)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_powerups)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_self_timed_refresh)); + FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_0, l_idx, o_data.reserved0)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_frame_count)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_base)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_low)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_med)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_high)); + FAPI_TRY(readCrctEndian(i_data, l_idx, l_initial_packet1)); + + o_data.frame_count = l_frame_count; + o_data.mba_arrival_histo_base = l_mba_arrival_histo_base; + o_data.mba_arrival_histo_low = l_mba_arrival_histo_low; + o_data.mba_arrival_histo_med = l_mba_arrival_histo_med; + o_data.mba_arrival_histo_high = l_mba_arrival_histo_high; + o_data.initial_packet1 = l_initial_packet1; + o_data.status = l_status; + o_data.ocmb_dts = l_ocmb_dts; + o_data.mem_dts0 = l_mem_dts0; + o_data.mem_dts1 = l_mem_dts1; + o_data.mba_reads = l_mba_reads; + o_data.mba_writes = l_mba_writes; + o_data.mba_activations = l_mba_activations; + o_data.mba_powerups = l_mba_powerups; + o_data.self_timed_refresh = l_self_timed_refresh; + + FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_1, l_idx, o_data.reserved1)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Converts a little endian data array to a sensor_cache_struct +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_data little endian data to process +/// @param[out] o_data sensor cache structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @note helper function to allow for checking FFDC +/// +fapi2::ReturnCode sensor_cache_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& + i_target, + std::vector<uint8_t>& i_data, + sensor_cache_struct& o_data) +{ + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + FAPI_TRY(sensor_cache_struct_from_little_endian(i_data, o_data)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Reads the complete 64 byte sensor cache on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[out] o_data The data read from the buffer +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode getSensorCache( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + sensor_cache_struct& o_data) +{ + std::vector<uint8_t> l_data(static_cast<int>(sizeof(o_data))); + + // The sensor cache is accessed exclusively via 2 32-byte MMIO reads + FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_SENSOR_CACHE_ADDR, 32, l_data)); + + FAPI_TRY(sensor_cache_struct_from_little_endian(i_target, l_data, o_data)); + +fapi_try_exit: + FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief UT helper for correctMMIOEndianForStruct +/// +/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL +/// @param[in,out] io_data value to swizzle +/// +void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl, + std::vector<uint8_t>& io_data) +{ + size_t l_loops = 0; + + if (i_endian_ctrl == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_SWAP) + { + l_loops = io_data.size() / BUFFER_TRANSACTION_SIZE; + + for (size_t l_idx = 0; l_idx < l_loops; l_idx++) + { + for (int l_bidx = BUFFER_TRANSACTION_SIZE - 1; l_bidx >= 0; l_bidx--) + { + io_data.push_back(io_data.at(l_bidx)); + } + + io_data.erase(io_data.begin(), io_data.begin() + BUFFER_TRANSACTION_SIZE); + } + } +} + +/// +/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer +/// data structures. The byte order of the 4 or 8 byte reads should be little +/// endian. In order to represent the data structure in its proper layout +/// the endianness of each 4 or 8 byte read must be corrected. +/// @param[in,out] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type l_endian_ctrl; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL, + FAPI_SYSTEM, l_endian_ctrl)); + correctMMIOEndianForStruct_helper(l_endian_ctrl, io_data); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief UT helper for correctMMIOword_order +/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP +/// @param[in,out] io_data value to swizzle +/// +void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap, + std::vector<uint8_t>& io_data) +{ + if (i_word_swap == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_SWAP) + { + for (size_t l_idx = 0; l_idx < io_data.size(); l_idx += BUFFER_TRANSACTION_SIZE) + { + for (size_t l_bidx = l_idx; l_bidx < l_idx + BUFFER_TRANSACTION_SIZE / 2; l_bidx++) + { + uint8_t l_temp_first_word = io_data.at(l_bidx); + uint8_t l_temp_second_word = io_data.at(l_bidx + BUFFER_TRANSACTION_SIZE / 2); + io_data[l_bidx] = l_temp_second_word; + io_data[l_bidx + BUFFER_TRANSACTION_SIZE / 2] = l_temp_first_word; + } + } + } +} + +/// +/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, +/// we might need to swap 32-bit word order +/// @param[in,out] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type l_word_swap; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP, + FAPI_SYSTEM, l_word_swap)); + correctMMIOword_order_helper(l_word_swap, io_data); + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief Forces native data into the correct endianness necessary for Explorer +/// buffer data structures. +/// @tparam T the data type to process +/// @param[in] i_input inputted data to process +/// @param[in,out] io_data vector to append data to +/// +template <typename T> +fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, + FAPI_SYSTEM, l_struct_endian)); + + if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) + { + forceLE(i_input, io_data); + } + else + { + forceBE(i_input, io_data); + } + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief Forces native data into the correct endianness for an array buffer +/// data structures. +/// @tparam T the data type to process +/// @param[in] i_input inputted data to process +/// @param[in] i_size size of the array +/// @param[in,out] io_data vector to append data to +/// +template <typename T> +fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, + FAPI_SYSTEM, l_struct_endian)); + + if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) + { + forceLEArray(i_input, i_size, io_data); + } + else + { + forceBEArray(i_input, i_size, io_data); + } + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +/// +/// @brief Converts endianness of data read from Explorer buffer data structures +// into native order. +/// @tparam T the data type to output to +/// @param[in] i_input inputted data to process +/// @param[in,out] io_idx current index +/// @param[out] o_data data that has been converted into native endianness +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template <typename T> +fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, + FAPI_SYSTEM, l_struct_endian)); + + if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) + { + FAPI_ASSERT(readLE(i_input, io_idx, o_data), + fapi2::EXP_INBAND_LE_DATA_RANGE() + .set_TARGET(FAPI_SYSTEM) + .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) + .set_DATA_SIZE(i_input.size()) + .set_MAX_INDEX(sizeof(o_data)), + "Failed to convert from LE data read, size %u expected size %u", + i_input.size(), sizeof(o_data)); + } + else + { + FAPI_ASSERT(readBE(i_input, io_idx, o_data), + fapi2::EXP_INBAND_BE_DATA_RANGE() + .set_TARGET(FAPI_SYSTEM) + .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) + .set_DATA_SIZE(i_input.size()) + .set_MAX_INDEX(sizeof(o_data)), + "Failed to convert from BE data read, size %u expected size %u", + i_input.size(), sizeof(o_data)); + } + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +template <typename T> +fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx, + T* o_data) +{ + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN, + FAPI_SYSTEM, l_struct_endian)); + + if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN) + { + FAPI_ASSERT(readLEArray(i_input, i_size, io_idx, o_data), + fapi2::EXP_INBAND_LE_DATA_RANGE() + .set_TARGET(FAPI_SYSTEM) + .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) + .set_DATA_SIZE(i_input.size()) + .set_MAX_INDEX(sizeof(o_data)), + "Failed to convert from LE array data read, size %u expected size %u", + i_input.size(), sizeof(o_data)); + } + else + { + FAPI_ASSERT(readBEArray(i_input, i_size, io_idx, o_data), + fapi2::EXP_INBAND_BE_DATA_RANGE() + .set_TARGET(FAPI_SYSTEM) + .set_FUNCTION(mss::exp::READ_CRCT_ENDIAN) + .set_DATA_SIZE(i_input.size()) + .set_MAX_INDEX(sizeof(o_data)), + "Failed to convert from BE array data read, size %u expected size %u", + i_input.size(), sizeof(o_data)); + } + +fapi_try_exit: + FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err); + return fapi2::current_err; +} + +} // namespace ib + +} // namespace exp + +} // namespace mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H index 6164cde08..9b562ed0b 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H @@ -22,3 +22,481 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +/// +/// @file exp_inband.H +/// @brief Explorer specifics for get/putMMIO inband ops +/// +/// One Axone bar register is set per MC channel for MMIO, and another +/// is set per MC channel for config space. Each bar is shared between +/// both sub-channels each with an OCMB. The upper bit of the address +/// determined by the bar sizes is used to determine which sub-channel +/// is selected. This means that for a pair of OCMB's on a channel +/// their config space is contiguous and their MMIO space is contiguous. +/// Therefore a single OCMB's MMIO and config space cannot be contiguous. +/// However, we can still use one BAR attribute and the set_bars procedure +/// can interleave the config space and MMIO space as shown in the table +/// bellow. For example, both MMIO and config bar sizes are 2GB. The +/// 2GB bit becomes the selector for the subchannel. The 4GB bit +/// becomes the offset applied for MMIO operations. +/// +/// +/// Each OCMB is assigned one base address attribute. For example: +/// ocmb | BAR ATTRIBUTE | Type | Base reg - end addr | size | sub-ch +/// +-----+--------------------+------+-----------------------------------------+------+------- +/// ocmb0 | 0x0006030200000000 | cnfg | 0x0006030200000000 - 0x000603027FFFFFFF | 2GB | 0 +/// ocmb1 | 0x0006030280000000 | cnfg | 0x0006030280000000 - 0x00060302FFFFFFFF | 2GB | 1 +/// ocmb0 | N/A | mmio | 0x0006030300000000 - 0x000603037FFFFFFF | 2GB | 0 +/// ocmb1 | N/A | mmio | 0x0006030380000000 - 0x00060303FFFFFFFF | 2GB | 1 +/// +-----+--------------------+------+-----------------------------------------+------+------- +/// ocmb2 | 0x0006030400000000 | cnfg | 0x0006030400000000 - 0x000603047FFFFFFF | 2GB | 0 +/// ocmb3 | 0x0006030480000000 | cnfg | 0x0006030480000000 - 0x00060304FFFFFFFF | 2GB | 1 +/// ocmb2 | N/A | mmio | 0x0006030500000000 - 0x000603057FFFFFFF | 2GB | 0 +/// ocmb3 | N/A | mmio | 0x0006030580000000 - 0x00060305FFFFFFFF | 2GB | 1 +/// +/// Bit 33 of the 64 bit address in big endian order determines if +/// the MMIO operation is a SCOM to the core or a register access +/// to MSCC space. If an MSCC access falls within the range specified +/// by the MSCCRNGE core register it is an access to the MIPS SRAM. +/// Specific locations within the SRAM have been set asside for command +/// and response buffers. Once written an interrupt must be issued +/// to MIPS indicating a new command is ready. Responses will send +/// an interrupt back to the host. +/// +/// Table 4-8:- Address of various buffers +/// Buffer Type MIPS view (un-cached) Host View (OpenCapi) I2C View +/// Command Buffer 0xA103 FF40 BAR + 0x0103 FF40 0xA103 FF40 +/// Response Buffer 0xA103 FF00 BAR + 0x0103 FF00 0xA103 FF00 +/// Data Buffer 0xA102 FF00 BAR + 0x0102 FF00 0xA102 FF00 +/// + +/// @file exp_inband.H +/// @brief implement OpenCAPI config, scom, and MSCC MMIO operations. +// +// *HWP HWP Owner: bgass@us.ibm.com +// *HWP FW Owner: dcrowell@us.ibm.com +// *HWP Team: +// *HWP Level: 2 +// *HWP Consumed by: HB +// +//-------------------------------------------------------------------------------- + +#ifndef __EXP_INBAND_H_ +#define __EXP_INBAND_H_ + +#include <fapi2.H> +#include <exp_data_structs.H> +#include <explorer_scom_addresses.H> +#include <explorer_scom_addresses_fld.H> +#include <explorer_scom_addresses_fixes.H> +#include <explorer_scom_addresses_fld_fixes.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> + +namespace mss +{ + +namespace exp +{ + +namespace ib +{ + +static const size_t BUFFER_TRANSACTION_SIZE = 8; + +static const uint64_t EXPLR_IB_CONFIG_OFFSET = 0x0000000000000000ull; +static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB +static const uint64_t EXPLR_IB_BAR_SIZE = 0b01111111; // 4GB Depends on EXPLR_IB_MMIO_OFFSET +static const uint64_t EXPLR_IB_BAR_B_BIT = EXPLR_IB_MMIO_OFFSET >> 1; // 2GB AND with A == 0, AND with B != 0 +static const uint64_t EXPLR_IB_BAR_MASK_ZERO = (EXPLR_IB_BAR_B_BIT - 1); // AND with BAR must == 0 + +//-------------------------------------------------------------------------------- +// The MSCC RAM Range Register SCOM 0x080108e5 MSCCRNGE +// determines the address range for the MIPS SRAM +// An offset within the the 1MB range is used for the command +// +/// Table 4-8:- Address of various buffers 64K 0x1 0000 +/// Buffer Type MIPS view (un-cached) Host View (OpenCapi) I2C View +/// Command Buffer 0xA103 FF40 BAR + 0x0103 FF40 0xA103 FF40 +/// Response Buffer 0xA103 FF00 BAR + 0x0103 FF00 0xA103 FF00 +/// Data Buffer 0xA102 FF00 BAR + 0x0102 FF00 0xA102 FF00 +/// +static const uint64_t EXPLR_IB_SRAM_BASE = 0x01000000; // MSCCRNGE 01000000 020FFFFF +static const uint64_t EXPLR_IB_CMD_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF40; +static const uint64_t EXPLR_IB_RSP_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF00; +static const uint64_t EXPLR_IB_DATA_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x02FF00; + +static const uint64_t EXPLR_IB_CMD_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_CMD_SRAM_ADDR; +static const uint64_t EXPLR_IB_RSP_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_RSP_SRAM_ADDR; +static const uint64_t EXPLR_IB_DATA_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_DATA_SRAM_ADDR; + +static const uint64_t EXPLR_IB_SENSOR_CACHE_ADDR = EXPLR_IB_MMIO_OFFSET | 0x40084200; + +//-------------------------------------------------------------------------------- +// Utilities +//-------------------------------------------------------------------------------- + +/// +/// @brief Converts user_input_msdg to little endian and calculates the crc +/// @param[in] i_input user_input_msdg structure to convert +/// @param[out] o_data vector of bytes for mmio +/// @param[out] o_crc the calculated crc of the data +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_input, std::vector<uint8_t>& o_data, + uint32_t& o_crc); + +/// +/// @brief Converts host_fw_command_struct to little endian +/// @param[in] i_input user_input_msdg structure to convert +/// @param[out] o_data vector of bytes for mmio. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_struct& i_input, + std::vector<uint8_t>& o_data); + +/// +/// @brief Converts a little endian data array to a host_fw_response_struct +/// @param[in] i_data little endian data to process +/// @param[out] o_crc computed CRC +/// @param[out] o_response response structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode host_fw_response_struct_from_little_endian(std::vector<uint8_t>& i_data, + uint32_t& o_crc, + host_fw_response_struct& o_response); + +/// +/// @brief Converts a little endian data array to a host_fw_response_struct +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_data little endian data to process +/// @param[out] o_response response structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @note helper function to allow for checking FFDC +/// +fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& + i_target, + std::vector<uint8_t>& i_data, + host_fw_response_struct& o_response); + +/// +/// @brief Converts a little endian data array to a sensor_cache_struct +/// @param[in] i_data little endian data to process +/// @param[out] o_data sensor cache structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @note helper function - returning a bool and will have true FFDC in a separate function +/// +fapi2::ReturnCode sensor_cache_struct_from_little_endian(std::vector<uint8_t>& i_data, + sensor_cache_struct& o_data); + +/// +/// @brief Converts a little endian data array to a sensor_cache_struct +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_data little endian data to process +/// @param[out] o_data sensor cache structure +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// @note helper function to allow for checking FFDC +/// +fapi2::ReturnCode sensor_cache_struct_from_little_endian(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& + i_target, + std::vector<uint8_t>& i_data, + sensor_cache_struct& o_data); + +//-------------------------------------------------------------------------------- +// Write operations +//-------------------------------------------------------------------------------- + +/// @brief Writes 64 bits of data to MMIO space to the selected Explorer +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_addr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putMMIO64( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + const fapi2::buffer<uint64_t>& i_data); + +/// @brief Writes 32 bits of data to MMIO space to the selected Explorer +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_addr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putMMIO32( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + const fapi2::buffer<uint32_t>& i_data); + +/// @brief Writes 64 bits of data to SCOM MMIO space +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_scomAddr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putScom( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_scomAddr, + const fapi2::buffer<uint64_t>& i_data); + +/// @brief Writes 32 bits of data to OpenCAPI config space +/// +/// @param[in] i_target The Explorer chip to write +/// @param[in] i_cfgAddr The address to write +/// @param[in] i_data The data to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putOCCfg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_cfgAddr, + const fapi2::buffer<uint32_t>& i_data); + +/// @brief Writes user_input_msdg to the data buffer +/// +/// @param[in] i_target The Explorer chip to issue the command to +/// @param[in] i_data The user_input_msdg data to write +/// @param[out] o_crc The calculated crc of the data. +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putUserInputMsdg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const user_input_msdg& i_data, + uint32_t& o_crc); + +/// @brief Writes a command to the command buffer and issues interrupt +/// +/// @param[in] i_target The Explorer chip to issue the command to +/// @param[in] i_cmd The command structure to write +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode putCMD( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const host_fw_command_struct& i_cmd); + +//-------------------------------------------------------------------------------- +// Read operations +//-------------------------------------------------------------------------------- + +/// @brief Reads 64 bits of data from MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_addr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getMMIO64( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + fapi2::buffer<uint64_t>& o_data); + +/// @brief Reads 32 bits of data from MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_addr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getMMIO32( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_addr, + fapi2::buffer<uint32_t>& o_data); + +/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_scomAddr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getScom( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_scomAddr, + fapi2::buffer<uint64_t>& o_data); + +/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[in] i_cfgAddr The address to read +/// @param[out] o_data The data read from the address +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getOCCfg( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_cfgAddr, + fapi2::buffer<uint32_t>& o_data); + +/// +/// @brief Polls for response ready door bell bit +/// @param[in] i_target the OCMB target on which to operate +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +/// +/// @brief Clears outbound (response ready) door bell bit +/// @param[in] i_target the OCMB target on which to operate +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +/// @brief Reads a response from the response buffer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[out] o_rsp The response data read from the buffer +/// @param[out] o_data Raw (little-endian) response data buffer portion +/// The size of this buffer will be a multiple of 8 +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getRSP( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + host_fw_response_struct& o_rsp, + std::vector<uint8_t>& o_data); + +/// @brief Reads the complete 64 byte sensor cache on the selected Explorer +/// +/// @param[in] i_target The Explorer chip to read data from +/// @param[out] o_data The data read from the buffer +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode getSensorCache( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + sensor_cache_struct& o_data); + +//-------------------------------------------------------------------------------- +// Command/Response/Data structure Endian handling +//-------------------------------------------------------------------------------- + +/// +/// @brief UT helper for correctMMIOEndianForStruct +/// +/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL +/// @param[in,out] io_data value to swizzle +/// +void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl, + std::vector<uint8_t>& io_data); + +/// +/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer +/// data structures. The byte order of the 4 or 8 byte reads should be little +/// endian. In order to represent the data structure in its proper layout +/// the endianness of each 4 or 8 byte read must be corrected. +/// @param[in,out] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data); + +/// +/// @brief UT helper for correctMMIOword_order +/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP +/// @param[in,out] io_data value to swizzle +/// +void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap, + std::vector<uint8_t>& io_data); + +/// +/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, +/// we might need to swap 32-bit word order +/// @param[in,out] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data); + +/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer +/// data structures. The byte order of the 4 or 8 byte reads should be little +/// endian. In order to represent the data structure in its proper layout +/// the endianness of each 4 or 8 byte read must be corrected. +/// +/// @param[inout] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data); + +/// @brief Because of how the AXI bridge in Explorer breaks up the transaction, +/// we might need to swap 32-bit word order +/// @param[in,out] io_data Either data structure in proper byte order that we +/// want to swizzle prior to writing to the buffer, or the data returned +/// from reading the buffer that we want to unsizzle. +/// +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data); + +/// @brief Ensure data is an even multiple of 8 (BUFFER_TRANSACTION_SIZE). +/// If (sizeof(buffer) % BUFFER_TRANSACTION_SIZE != 0) ; then pad +/// buffer with zeros until statement is true. +/// +/// @param[in,out] io_data Communication data , either CMD or RSP buffer +/// +/// @return void +inline void padCommData(std::vector<uint8_t>& io_data) +{ + while ((io_data.size() % BUFFER_TRANSACTION_SIZE) != 0) + { + io_data.push_back(0); + } +} + +/// +/// @brief Forces native data into the correct endianness necessary for Explorer +/// buffer data structures. +/// @tparam T the data type to process +/// @param[in] i_input inputted data to process +/// @param[in,out] io_data vector to append data to +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template <typename T> +fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data); + +/// +/// @brief Forces native data into the correct endianness for an array buffer +/// data structures. +/// @tparam T the data type to process +/// @param[in] i_input inputted data to process +/// @param[in] i_size size of the array +/// @param[in,out] io_data vector to append data to +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template <typename T> +fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data); + +/// +/// @brief Converts endianness of data read from Explorer buffer data structures +// into native order. +/// @tparam T the data type to output to +/// @param[in] i_input inputted data to process +/// @param[in,out] io_idx current index +/// @param[out] o_data data that has been converted into native endianness +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template <typename T> +fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data); + +/// +/// @brief Converts endianness of data read from Explorer buffer data structures +/// into native order. +/// @tparam T the data type to output to +/// @param[in] i_input inputted data to process +/// @param[in] i_size size of the array +/// @param[in,out] io_idx current index +/// @param[out] o_data data that has been converted into native endianness +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template <typename T> +fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx, + T* o_data); + +//-------------------------------------------------------------------------------- + +} // namespace ib + +} // namespace exp + +} // namespace mss + +#endif diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C index 035c9f3a5..c89ff177b 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C @@ -51,7 +51,7 @@ #include <map> #include <lib/shared/mss_const.H> #include <generic/memory/lib/utils/memory_size.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> ///---------------------------------------------------------------------------- /// Constant definitions diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C index 9271a4097..9801e8f30 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C @@ -45,7 +45,7 @@ #include <p9_mc_scom_addresses.H> #include <p9a_misc_scom_addresses.H> #include <p9a_misc_scom_addresses_fld.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> //----------------------------------------------------------------------------------- // Function definitions |