diff options
Diffstat (limited to 'src/usr/expaccess')
-rw-r--r-- | src/usr/expaccess/errlud_expscom.C | 216 | ||||
-rw-r--r-- | src/usr/expaccess/errlud_expscom.H | 160 | ||||
-rw-r--r-- | src/usr/expaccess/expaccess.mk | 10 | ||||
-rw-r--r-- | src/usr/expaccess/expscom_utils.C | 15 | ||||
-rw-r--r-- | src/usr/expaccess/mmioscomdd.C | 2 | ||||
-rw-r--r-- | src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C | 32 | ||||
-rw-r--r-- | src/usr/expaccess/plugins/errludP_expscom.H | 168 | ||||
-rw-r--r-- | src/usr/expaccess/plugins/expscomUdParserFactory.H | 58 | ||||
-rw-r--r-- | src/usr/expaccess/runtime/makefile | 5 | ||||
-rw-r--r-- | src/usr/expaccess/runtime/test/makefile | 3 | ||||
-rw-r--r-- | src/usr/expaccess/test/expErrlTest.C | 158 | ||||
-rw-r--r-- | src/usr/expaccess/test/expErrlTest.H | 129 | ||||
-rw-r--r-- | src/usr/expaccess/test/expscomtest.H | 1077 | ||||
-rw-r--r-- | src/usr/expaccess/test/exptest_utils.C | 136 | ||||
-rw-r--r-- | src/usr/expaccess/test/exptest_utils.H | 64 | ||||
-rw-r--r-- | src/usr/expaccess/test/makefile | 5 | ||||
-rw-r--r-- | src/usr/expaccess/test/ocmbcommtest.H | 289 | ||||
-rw-r--r-- | src/usr/expaccess/test/rcExpLog.C | 55 | ||||
-rw-r--r-- | src/usr/expaccess/test/rcExpLog.H | 49 | ||||
-rw-r--r-- | src/usr/expaccess/test/test.mk | 23 |
20 files changed, 2099 insertions, 555 deletions
diff --git a/src/usr/expaccess/errlud_expscom.C b/src/usr/expaccess/errlud_expscom.C new file mode 100644 index 000000000..7480b9887 --- /dev/null +++ b/src/usr/expaccess/errlud_expscom.C @@ -0,0 +1,216 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/errlud_expscom.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 errlud_expscom.C + * @brief Utility to add Explorer logs to your hostboot error + */ +#include "errlud_expscom.H" +#include "expscom_trace.H" +#include <errl/hberrltypes.H> // pelSectionHeader_t +#include <exp_fw_log_data.H> // explorer log gathering tools +#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP +#include <expscom/expscom_reasoncodes.H> // user-detail subsections +#include <errl/errlmanager.H> // errlCommit + +using namespace EXPSCOM; + +// Main function to add Explorer logs to a HB error log +bool EXPSCOM::expAddLog( const exp_log_type i_type, + TARGETING::Target * i_ocmb, + errlHndl_t & io_errl ) +{ + bool l_logsAdded = false; + explog_section_header_t l_header; // use 0 defaults + + // Meta data included with each section + const uint32_t META_SECTION_SIZE = sizeof(l_header) + + sizeof(ERRORLOG::pelSectionHeader_t); + + // @todo RTC 214628 + // Hopefully create a way to tell how much room is left in io_errl + uint32_t l_bytesAvailableInLog = 4 * KILOBYTE; + + if (l_bytesAvailableInLog > META_SECTION_SIZE) + { + errlHndl_t l_errl = nullptr; + std::vector<uint8_t>l_error_log_data; // explorer error entry data + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(i_ocmb); + + // Make HWP call to grab explorer error log data + if (i_type == EXPSCOM::ACTIVE_LOG) + { + TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_active_error_log"); + FAPI_INVOKE_HWP( l_errl, exp_active_log, + l_fapi_ocmb_target, l_error_log_data ); + } + else + { + TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_saved_error_log"); + FAPI_INVOKE_HWP( l_errl, exp_saved_log, + l_fapi_ocmb_target, l_error_log_data ); + } + + if (l_errl) + { + // Unable to grab explorer error log data + TRACFCOMP( g_trac_expscom, ERR_MRK "Unable to grab explorer error log data"); + l_errl->collectTrace(EXPSCOM_COMP_NAME); + + // This error is not a system critical failure, should be just noted + l_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); + + // Associate this error with the original explorer failure log + l_errl->plid(io_errl->plid()); + errlCommit(l_errl, EXPSCOM_COMP_ID); + } + else + { + // Cycle through data and add sections to io_errl + // Most recent error log entries are at the end of the data returned + // so need to work backwards from the end + l_header.error_data_size = FIRST_EXPLORER_DATA_SECTION_SIZE; + uint32_t l_explorer_bytes_left = l_error_log_data.size(); + uint8_t * l_end_ptr = l_error_log_data.data() + l_explorer_bytes_left; + + // while explorer data to append + while (l_explorer_bytes_left && l_bytesAvailableInLog) + { + // Can we add a full packet size of error data? + if (l_bytesAvailableInLog > (l_header.error_data_size + META_SECTION_SIZE)) + { + // Check if we don't have full packet of explorer error data + if (l_explorer_bytes_left < l_header.error_data_size) + { + // Reduce the packet size to include the last of explorer error data + l_header.error_data_size = l_explorer_bytes_left; + } + } + else if ( l_bytesAvailableInLog > META_SECTION_SIZE ) // Any room left for another section? + { + // Is there enough explorer error data for room available? + if ( l_explorer_bytes_left >= + (l_bytesAvailableInLog - META_SECTION_SIZE) ) + { + // Not enough room is available for all the remaining explorer error data + // Use up the rest of the space available + l_header.error_data_size = l_bytesAvailableInLog - META_SECTION_SIZE; + } + else + { + // Room is available but not enough explorer data for full packet size + // Reduce the packet size to include the last of explorer error data + l_header.error_data_size = l_explorer_bytes_left; + } + } + else + { + // No more space available in hostboot error log + break; + } + + // Offset into explorer error log data returned + l_header.offset_exp_log = l_explorer_bytes_left - + l_header.error_data_size; + + // Add the section entry to the HWP error log + if ( i_type == EXPSCOM::ACTIVE_LOG ) + { + ExpscomActiveLogUD(l_header, (l_end_ptr - l_header.error_data_size)). + addToLog(io_errl); + } + else + { + ExpscomSavedLogUD(l_header, (l_end_ptr - l_header.error_data_size)). + addToLog(io_errl); + } + l_logsAdded = true; + + // Update to next packet of Explorer error log data + l_end_ptr -= l_header.error_data_size; // update to always be the tail of data to add + l_header.packet_num++; + l_explorer_bytes_left -= l_header.error_data_size; + l_bytesAvailableInLog -= (META_SECTION_SIZE + l_header.error_data_size); + l_header.error_data_size = FOLLOWING_EXPLORER_DATA_SECTION_SIZE; + } + } + } + else + { + TRACFCOMP( g_trac_expscom, INFO_MRK + "expAddErrorLog: Unable to add any %d type error logs," + " only have %d bytes available in log", i_type, l_bytesAvailableInLog ); + } + return l_logsAdded; +} + +//------------------------------------------------------------------------------ +// Expscom Active Log User Details +//------------------------------------------------------------------------------ +ExpscomActiveLogUD::ExpscomActiveLogUD( + const explog_section_header_t & i_header_info, + const uint8_t * i_data_portion ) +{ + // Set up Ud instance variables + iv_CompId = EXPSCOM_COMP_ID; + iv_Version = 1; + iv_SubSection = EXPSCOM_UDT_ACTIVE_LOG; + + uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) + + i_header_info.error_data_size ); + + memcpy(l_pBuf, &i_header_info, sizeof(i_header_info)); + l_pBuf += sizeof(i_header_info); + memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size); + l_pBuf += i_header_info.error_data_size; +} + +ExpscomActiveLogUD::~ExpscomActiveLogUD() +{ +} + +//------------------------------------------------------------------------------ +// Expscom Saved Log User Details +//------------------------------------------------------------------------------ +ExpscomSavedLogUD::ExpscomSavedLogUD( + const explog_section_header_t & i_header_info, + const uint8_t * i_data_portion ) +{ + // Set up Ud instance variables + iv_CompId = EXPSCOM_COMP_ID; + iv_Version = 1; + iv_SubSection = EXPSCOM_UDT_SAVED_LOG; + + uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) + + i_header_info.error_data_size ); + + memcpy(l_pBuf, &i_header_info, sizeof(i_header_info)); + l_pBuf += sizeof(i_header_info); + memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size); + l_pBuf += i_header_info.error_data_size; +} + +ExpscomSavedLogUD::~ExpscomSavedLogUD() +{ +} diff --git a/src/usr/expaccess/errlud_expscom.H b/src/usr/expaccess/errlud_expscom.H new file mode 100644 index 000000000..acb17bc2c --- /dev/null +++ b/src/usr/expaccess/errlud_expscom.H @@ -0,0 +1,160 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/errlud_expscom.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ + +#ifndef __ERRLUD_EXPSCOM_H +#define __ERRLUD_EXPSCOM_H + +/** + * @file errlud_expscom.H + * @brief Utility functions to add Explorer logs to your hostboot error + */ +#include <stdint.h> + +#include <errl/errluserdetails.H> + +// targeting support +#include <targeting/common/commontargeting.H> +#include <targeting/common/utilFilter.H> + +namespace EXPSCOM +{ +/** + * @brief Enum for what kind of Explorer log + */ +enum exp_log_type : uint8_t +{ + ACTIVE_LOG = 1, // RAM error section + SAVED_LOG = 2 // SPI flash error section +}; + +/** + * @brief Adds Explorer log data to platform log + * Grabs explorer error log based on type and then breaks that data + * into smaller user-data sections adding them to the platform log. + * Note: First section will be the smallest and contain the most recent + * trace data. Probably contains most relevent traces, so try to make + * always fit in the error log. + * @param i_type - what kind of explorer error log to add + * @param i_ocmb - Explorer target + * @param io_errl - Platform error log to add logs into + * @return true if explorer error data added, else false + */ +bool expAddLog( const exp_log_type i_type, + TARGETING::Target * i_ocmb, + errlHndl_t & io_errl ); + + + +/** + * @brief Header data of every explorer error log user-data section + */ +struct explog_section_header_t +{ + uint16_t packet_num; // ordering byte (0 = first packet) + uint32_t offset_exp_log; // offset where data portion started in full explorer log + uint16_t error_data_size; // size of data portion following header + + explog_section_header_t() + : packet_num(0), + offset_exp_log(0), + error_data_size(0) + {} +} __attribute__((__packed__)); + +// Break large explorer log data into smaller error sections +// to avoid dropping important debug data. +// Make most important first section smaller so this won't get dropped +const uint16_t FIRST_EXPLORER_DATA_SECTION_SIZE = 0x0100; +const uint16_t FOLLOWING_EXPLORER_DATA_SECTION_SIZE = 0x0200; + + +/** + * @class ExpscomActiveLogUD + * + * Adds Explorer Active log information to an error log as user detail + * Data is from Explorer RAM + * + */ +class ExpscomActiveLogUD : public ERRORLOG::ErrlUserDetails +{ + public: + /** + * @brief Constructor + * + * @param i_header_info Meta information added to beginning of section + * @param i_data_portion Pointer to portion of Active log data + * + */ + ExpscomActiveLogUD( const explog_section_header_t & i_header_info, + const uint8_t * i_data_portion ); + + /** + * @brief Destructor + */ + virtual ~ExpscomActiveLogUD(); + + // Disabled + ExpscomActiveLogUD() = delete; + ExpscomActiveLogUD(ExpscomActiveLogUD &) = delete; + ExpscomActiveLogUD & operator=(ExpscomActiveLogUD &) = delete; +}; + + + + +/** + * @class ExpscomSavedLogUD + * + * Adds Explorer Saved log information to an error log as user detail + * Data is from Explorer SPI flash + * + */ +class ExpscomSavedLogUD : public ERRORLOG::ErrlUserDetails +{ + public: + /** + * @brief Constructor + * + * @param i_header_info Meta information added to beginning of section + * @param i_data_portion Pointer to portion of Saved error data + * + */ + ExpscomSavedLogUD( const explog_section_header_t & i_header_info, + const uint8_t * i_data_portion ); + + /** + * @brief Destructor + */ + virtual ~ExpscomSavedLogUD(); + + // Disabled + ExpscomSavedLogUD() = delete; + ExpscomSavedLogUD(ExpscomSavedLogUD &) = delete; + ExpscomSavedLogUD & operator=(ExpscomSavedLogUD &) = delete; +}; + +} + +#endif diff --git a/src/usr/expaccess/expaccess.mk b/src/usr/expaccess/expaccess.mk index 84835c522..d4431e0cd 100644 --- a/src/usr/expaccess/expaccess.mk +++ b/src/usr/expaccess/expaccess.mk @@ -25,14 +25,20 @@ EXTRAINCDIR += ${ROOTPATH}/src/import EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 -# Need to build exp_indband to use EKB's getMMIO/putMMIO/getCMD/getRSP +VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/ + +# Need to build exp_inband to use EKB's getMMIO/putMMIO/getCMD/getRSP OBJS += exp_inband.o OBJS += expscom_trace.o OBJS += expscom_utils.o OBJS += i2cscomdd.o -OBJS += mmioscomdd.o
\ No newline at end of file +OBJS += mmioscomdd.o +OBJS += exp_fw_log.o +OBJS += exp_fw_log_data.o +OBJS += errlud_expscom.o diff --git a/src/usr/expaccess/expscom_utils.C b/src/usr/expaccess/expscom_utils.C index 5ea7eeeb2..c4818379c 100644 --- a/src/usr/expaccess/expscom_utils.C +++ b/src/usr/expaccess/expscom_utils.C @@ -55,20 +55,21 @@ errlHndl_t validateInputs(DeviceFW::OperationType i_opType, errlHndl_t l_err = nullptr; uint32_t l_commonPlid = 0; // If there are multiple issues found link logs with first - TARGETING::ATTR_MODEL_type l_targetModel = - i_target->getAttr<TARGETING::ATTR_MODEL>(); + // Verify that the target is of type OCMB_CHIP + TARGETING::ATTR_TYPE_type l_targetType = + i_target->getAttr<TARGETING::ATTR_TYPE>(); - // Only target we can perform ocmb scoms on are explorer OCMB chip targets - if( l_targetModel != TARGETING::MODEL_EXPLORER ) + // Only target we can perform ocmb scoms on are OCMB chip targets + if( l_targetType != TARGETING::TYPE_OCMB_CHIP ) { - TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid target type : l_targetModel=%d", l_targetModel ); + TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid target type : l_targetType=0x%X", l_targetType ); /*@ * @errortype * @moduleid EXPSCOM::MOD_OCMB_UTILS * @reasoncode EXPSCOM::RC_INVALID_MODEL_TYPE * @userdata1 SCOM Address * @userdata2 Model Type - * @devdesc validateInputs> Invalid target type (!= OCMB_CHP) + * @devdesc validateInputs> Invalid target type (!= OCMB_CHIP) * @custdesc A problem occurred during the IPL of the system: * Invalid target type for a SCOM operation. */ @@ -76,7 +77,7 @@ errlHndl_t validateInputs(DeviceFW::OperationType i_opType, EXPSCOM::MOD_OCMB_UTILS, EXPSCOM::RC_INVALID_MODEL_TYPE, i_scomAddr, - l_targetModel, + l_targetType, ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); l_err->collectTrace(EXPSCOM_COMP_NAME); diff --git a/src/usr/expaccess/mmioscomdd.C b/src/usr/expaccess/mmioscomdd.C index bf4513158..00feb38d4 100644 --- a/src/usr/expaccess/mmioscomdd.C +++ b/src/usr/expaccess/mmioscomdd.C @@ -31,7 +31,7 @@ /*****************************************************************************/ // I n c l u d e s /*****************************************************************************/ -#include <exp_inband.H> // mmio_get_scom +#include <lib/inband/exp_inband.H> // mmio_get_scom #include <lib/shared/exp_consts.H> // IBM_SCOM_INDICATOR #include <hwpf/fapi2/include/fapi2_hwp_executor.H>// FAPI_EXEC_HWP #include "mmioscomdd.H" //mmioScomPerformOp diff --git a/src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C b/src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C new file mode 100644 index 000000000..54bf595b6 --- /dev/null +++ b/src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C @@ -0,0 +1,32 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 EXPSCOM_COMP_ID_Parse.C + * @brief Build the Explorer User Details parser factory + */ +#include "errludparser.H" +#include "expscomUdParserFactory.H" + +ERRL_MAKE_UD_PARSER(EXPSCOM::UserDetailsParserFactory, hbfw::EXPSCOM_COMP_ID) diff --git a/src/usr/expaccess/plugins/errludP_expscom.H b/src/usr/expaccess/plugins/errludP_expscom.H new file mode 100644 index 000000000..73d449ba4 --- /dev/null +++ b/src/usr/expaccess/plugins/errludP_expscom.H @@ -0,0 +1,168 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/plugins/errludP_expscom.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ +#ifndef ERRL_UDP_EXPSCOM_H +#define ERRL_UDP_EXPSCOM_H + +/** + * @file errludP_expscom.H + * Defines the ErrlUserDetailsParser classes that parse EXPSCOM FFDC + */ + +#include "errluserdetails.H" +#include <string.h> + +#define TO_UINT16(ptr) (ntohs(*(reinterpret_cast<uint16_t*>(ptr)))) +#define TO_UINT32(ptr) (ntohl(*(reinterpret_cast<uint32_t*>(ptr)))) + +namespace EXPSCOM +{ + +/** + * @brief Header data of every explorer error log section + */ +typedef struct __attribute__((packed)) +{ + uint16_t packet_num; // ordering byte (0 = first packet) + uint32_t offset_exp_log; // offset where data portion started in full explorer log + uint16_t error_data_size; // size of data portion following header +} explog_section_header_t; + +/** + * @class UdParserExpActiveErrorLog + * + * Parses user-data sections for Explorer's Active logs + */ +class UdParserExpActiveLog : public ERRORLOG::ErrlUserDetailsParser +{ +public: + /** + * @brief Constructor + */ + UdParserExpActiveLog() {} + + /** + * @brief Destructor + */ + virtual ~UdParserExpActiveLog() {} + + /** + * @brief Parses string user detail data from an error log + * + * @param i_version Version of the data + * @param i_parse ErrlUsrParser object for outputting information + * @param i_pBuffer Pointer to buffer containing detail data + * @param i_buflen Length of the buffer + */ + virtual void parse(errlver_t i_version, + ErrlUsrParser & i_parser, + void * i_pBuffer, + const uint32_t i_buflen) const + { + explog_section_header_t * pHeader = reinterpret_cast<explog_section_header_t *>(i_pBuffer); + i_parser.PrintHeading("Explorer Active (RAM) Log Data"); + i_parser.PrintNumber("Order packet", "%d", TO_UINT16(&(pHeader->packet_num))); + i_parser.PrintNumber("Data starting offset", "0x%.8lX", TO_UINT32(&(pHeader->offset_exp_log))); + i_parser.PrintNumber("Size of data section", "0x%.4lX", TO_UINT16(&(pHeader->error_data_size))); + i_parser.PrintBlank(); + uint16_t errorDataSize = TO_UINT16(&(pHeader->error_data_size)); + if (errorDataSize <= (i_buflen - sizeof(explog_section_header_t))) + { + char * l_trace_error_data = static_cast<char*>(i_pBuffer) + sizeof(explog_section_header_t); + i_parser.PrintHexDump(l_trace_error_data, errorDataSize); + } + else + { + i_parser.PrintHeading("ERROR DATA MISSING -- printing entire section in hex"); + i_parser.PrintNumber("Expected data size", "0x%.4lX", i_buflen - sizeof(explog_section_header_t)); + i_parser.PrintHexDump(i_pBuffer, i_buflen); + } + + } + + // Disabled + UdParserExpActiveLog(const UdParserExpActiveLog&) = delete; + UdParserExpActiveLog & operator=(const UdParserExpActiveLog&) = delete; +}; + +/** + * @class UdParserExpSavedErrorLog + * + * Parses user-data sections for Explorer's Saved logs + */ +class UdParserExpSavedLog : public ERRORLOG::ErrlUserDetailsParser +{ +public: + /** + * @brief Constructor + */ + UdParserExpSavedLog() {} + + /** + * @brief Destructor + */ + virtual ~UdParserExpSavedLog() {} + + /** + * @brief Parses string user detail data from an error log + * + * @param i_version Version of the data + * @param i_parse ErrlUsrParser object for outputting information + * @param i_pBuffer Pointer to buffer containing detail data + * @param i_buflen Length of the buffer + */ + virtual void parse(errlver_t i_version, + ErrlUsrParser & i_parser, + void * i_pBuffer, + const uint32_t i_buflen) const + { + explog_section_header_t * pHeader = reinterpret_cast<explog_section_header_t *>(i_pBuffer); + i_parser.PrintHeading("Explorer Saved (SPI flash) Log Data"); + i_parser.PrintNumber("Order packet", "%d", TO_UINT16(&(pHeader->packet_num))); + i_parser.PrintNumber("Data starting offset", "0x%.8lX", TO_UINT32(&(pHeader->offset_exp_log))); + i_parser.PrintNumber("Size of data section", "0x%.4lX", TO_UINT16(&(pHeader->error_data_size))); + i_parser.PrintBlank(); + uint16_t errorDataSize = TO_UINT16(&pHeader->error_data_size); + if (errorDataSize <= (i_buflen - sizeof(explog_section_header_t))) + { + char * l_trace_error_data = static_cast<char*>(i_pBuffer) + sizeof(explog_section_header_t); + i_parser.PrintHexDump(l_trace_error_data, errorDataSize); + } + else + { + i_parser.PrintHeading("ERROR DATA MISSING -- printing entire section in hex"); + i_parser.PrintNumber("Expected data size", "0x%.4lX", i_buflen - sizeof(explog_section_header_t)); + i_parser.PrintHexDump(i_pBuffer, i_buflen); + } + + } + + // Disabled + UdParserExpSavedLog(const UdParserExpSavedLog&) = delete; + UdParserExpSavedLog & operator=(const UdParserExpSavedLog&) = delete; +}; + +} // end EXPSCOM namespace + +#endif diff --git a/src/usr/expaccess/plugins/expscomUdParserFactory.H b/src/usr/expaccess/plugins/expscomUdParserFactory.H new file mode 100644 index 000000000..6a006e308 --- /dev/null +++ b/src/usr/expaccess/plugins/expscomUdParserFactory.H @@ -0,0 +1,58 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/plugins/expscomUdParserFactory.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 expscomUdParserFactory.H + * @brief Registers Explorer User Detail parsers + */ +#if !defined(_EXPSCOMUDPARSERFACTORY_H) +#define _EXPSCOMUDPARSERFACTORY_H + +#include "errludparserfactory.H" +#include "errludP_expscom.H" + +namespace EXPSCOM +{ + class UserDetailsParserFactory + : public ERRORLOG::ErrlUserDetailsParserFactory + { + public: + UserDetailsParserFactory() + { + registerParser<UdParserExpActiveLog> + (EXPSCOM_UDT_ACTIVE_LOG); + + registerParser<UdParserExpSavedLog> + (EXPSCOM_UDT_SAVED_LOG); + } + + private: + + UserDetailsParserFactory(const UserDetailsParserFactory &); + UserDetailsParserFactory & operator= + (const UserDetailsParserFactory &); + }; +}; + +#endif diff --git a/src/usr/expaccess/runtime/makefile b/src/usr/expaccess/runtime/makefile index ed744eab2..722d966e6 100644 --- a/src/usr/expaccess/runtime/makefile +++ b/src/usr/expaccess/runtime/makefile @@ -22,6 +22,7 @@ # permissions and limitations under the License. # # IBM_PROLOG_END_TAG +HOSTBOOT_RUNTIME = 1 ROOTPATH = ../../../.. MODULE = expaccess_rt @@ -30,7 +31,9 @@ SUBDIRS += test.d include ../expaccess.mk +EXTRAINCDIR += ../ + VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/ VPATH += ${ROOTPATH}/src/usr/expaccess/ -include ${ROOTPATH}/config.mk
\ No newline at end of file +include ${ROOTPATH}/config.mk diff --git a/src/usr/expaccess/runtime/test/makefile b/src/usr/expaccess/runtime/test/makefile index 442fc0953..3359dc760 100644 --- a/src/usr/expaccess/runtime/test/makefile +++ b/src/usr/expaccess/runtime/test/makefile @@ -30,9 +30,6 @@ MODULE = testexpaccess_rt include ../../test/test.mk -#TODO RTC:196806 re-enable mmio communication tests when mmio works TESTS = ../../test/expscomtest.H include ${ROOTPATH}/config.mk - - diff --git a/src/usr/expaccess/test/expErrlTest.C b/src/usr/expaccess/test/expErrlTest.C new file mode 100644 index 000000000..10f3b1189 --- /dev/null +++ b/src/usr/expaccess/test/expErrlTest.C @@ -0,0 +1,158 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/expErrlTest.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 expErrlTest.C + * @brief Tests the various ways to grab/add explorer error log data + */ +#include <rcExpLog.H> // RC error log side +#include <fapi2.H> +#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP +#include <errl/errlmanager.H> +#include "../errlud_expscom.H" // HB error log side + + +fapi2::ReturnCode get_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const uint64_t i_address, + fapi2::buffer<uint64_t>& o_data) +{ + return fapi2::getScom(i_target,i_address,o_data); +} + +uint32_t expErrorLogHb() +{ + uint32_t numTests = 0; + uint32_t numFails = 0; + errlHndl_t l_err = nullptr; + + // Create a vector of TARGETING::Target pointers + TARGETING::TargetHandleList l_chipList; + + // Get a list of all of the functioning ocmb chips + TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true); + + //Verify at least one ocmb found, some systems do not have ocmb chips + if(l_chipList.size() == 0 ) + { + FAPI_INF("expErrorLogHb: No OCMB targets found, skipping test"); + } + + // create an error for each OCMB and grab the trace data + for ( auto & l_ocmb : l_chipList ) + { + // Get a scom error with bad address + FAPI_INF("expErrorLogHb - Get a scom error with bad address for ocmb 0x%.8X", + TARGETING::get_huid(l_ocmb)); + numTests++; + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget(l_ocmb); + fapi2::buffer<uint64_t> l_scom_buffer; + FAPI_INVOKE_HWP( l_err, get_scom, fapi2_ocmbTarget, + 0xFFFFFFFF, l_scom_buffer ); + if (l_err) + { + FAPI_INF("expErrorLogHb - created error log 0x%04X, now adding explorer errors", l_err->plid()); + + // Add explorer error logs to this and commit + bool logAdded = false; + numTests++; + logAdded = EXPSCOM::expAddLog(EXPSCOM::ACTIVE_LOG, l_ocmb, l_err); + if (!logAdded) + { + TS_FAIL("expErrorLogHb: No ACTIVE explorer logs added to 0x%04X", l_err->plid()); + numFails++; + } + + numTests++; + logAdded = EXPSCOM::expAddLog(EXPSCOM::SAVED_LOG, l_ocmb, l_err); + if (!logAdded) + { + TS_FAIL("expErrorLogHb: No SAVED explorer logs added to 0x%04X", l_err->plid()); + numFails++; + } + errlCommit(l_err, CXXTEST_COMP_ID); + } + else + { + TS_FAIL("expErrorLogHb: getScom(0xFFFFFFFF) worked on 0x%.8X", + TARGETING::get_huid(l_ocmb)); + numFails++; + } + } + + FAPI_INF("expErrorLogHb Test Complete. %d/%d fails", numFails, numTests); + + return numFails; +} + +uint32_t expErrorLogRc() +{ + uint32_t numTests = 0; + uint32_t numFails = 0; + errlHndl_t l_errl = nullptr; + FAPI_INF("expErrorLogRc() running"); + do + { + // Create a vector of TARGETING::Target pointers + TARGETING::TargetHandleList l_chipList; + + // Get a list of all of the functioning ocmb chips + TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true); + TARGETING::Target * l_ocmb = nullptr; + + //Take the first ocmb and use it + if (l_chipList.size() > 0) + { + l_ocmb = l_chipList[0]; + } + else + { + FAPI_INF("expErrorLogRc: No OCMB targets found, skipping test"); + break; + } + + numTests++; + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget(l_ocmb); + // This procedure creates an RC error and then adds Explorer log data + // to that error + // (0x500 bytes of ACTIVE log data, 0x450 bytes of SAVED log data) + FAPI_INVOKE_HWP(l_errl, exp_error_rc, fapi2_ocmbTarget, 0x500, 0x450); + if(l_errl != nullptr) + { + // Commit this error log so it can be examined for Explorer log data + FAPI_INF("exp_errorFfdc_fail returned expected errl"); + errlCommit(l_errl,CXXTEST_COMP_ID); + l_errl = nullptr; + } + else + { + TS_FAIL("expErrorLogRc: No error from exp_errorFfdc_fail !!"); + numFails++; + } + } while (0); + + FAPI_INF("expErrorLogRc Test Complete. %d/%d fails", + numFails , numTests); + + return numFails; +} diff --git a/src/usr/expaccess/test/expErrlTest.H b/src/usr/expaccess/test/expErrlTest.H new file mode 100644 index 000000000..77b44452d --- /dev/null +++ b/src/usr/expaccess/test/expErrlTest.H @@ -0,0 +1,129 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/expErrlTest.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ +#ifndef __expErrlTest_H +#define __expErrlTest_H + +/** + * @file ExpErrorLogTest.H + * + * @brief Test case for explorer error log grabbing/adding +*/ + +#include <cxxtest/TestSuite.H> +#include <fapi2.H> +#include "expErrlTest.C" +#include <exptest_utils.H> + +using namespace fapi2; + +class test_expErrorLog: public CxxTest::TestSuite +{ +public: + + /** + * @brief Test adding Explorer error logs via RC + */ + void testExpErrorLogRc(void) + { + // @todo RTC 214629 - disabled until simics implements exp_error_log + return; + + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup, unable to continue"); + } + else + { + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + uint32_t l_res = expErrorLogRc(); + if (l_res != 0) + { + TS_FAIL("rcTestExpErrorLogRc. Fail l_res=%d", l_res); + } + // atomic section << + mutex_unlock(iv_serializeTestMutex); + } + } + + /** + * @brief Test hostboot side of adding Explorer error log to errl + */ + void testExpErrorLogHb(void) + { + // @todo RTC 214629 - disabled until simics implements exp_error_log + return; + + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup, unable to continue"); + } + else + { + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + uint32_t l_res = expErrorLogHb(); + + if (l_res != 0) + { + TS_FAIL("testExpErrorLogHb. Fail l_res=%d", l_res); + } + // atomic section << + mutex_unlock(iv_serializeTestMutex); + } + } + + /** + * @brief Constructor + */ + test_expErrorLog() : CxxTest::TestSuite() + { + // All modules are loaded by runtime, + // so testcase loading of modules is not required +#ifndef __HOSTBOOT_RUNTIME + errlHndl_t err = nullptr; + + // For testing, just load the library needed and don't bother with + // unloading to avoid pulling the rug from under other tests that need + // the loaded library + err = exptest::loadModule(exptest::MSS_LIBRARY_NAME); + if(err) + { + TS_FAIL("OCMBCommTest() - Constuctor: failed to load MSS module"); + errlCommit( err, TARG_COMP_ID ); + } +#endif + iv_serializeTestMutex = exptest::getTestMutex(); + }; + + private: + // This is used for tests that need to not run operations at the same time + TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex; + +}; + +#endif diff --git a/src/usr/expaccess/test/expscomtest.H b/src/usr/expaccess/test/expscomtest.H index c943ca7ba..5f5583287 100644 --- a/src/usr/expaccess/test/expscomtest.H +++ b/src/usr/expaccess/test/expscomtest.H @@ -41,8 +41,9 @@ #include <fapi2_hwp_executor.H> #include <fapi2/hw_access.H> #include <lib/shared/exp_consts.H> +#include "exptest_utils.H" +#include "../expscom_trace.H" -extern trace_desc_t* g_trac_expscom; using namespace TARGETING; using namespace ERRORLOG; @@ -57,10 +58,11 @@ struct testExpscomAddrData // Test table values const testExpscomAddrData g_expscomAddrTable[] = { - {0x501C, 0x00000000DEADBEEF}, - {0x209004, 0x00000000C0DEDEAD}, - {0x8010002, 0xDEADC0DEC0DEBEEF} + {0x501C, 0x00000000DEADBEEF}, // UART scratch register + {0x209004, 0x00000000C0DEDEAD}, // PVT_CTRL - TM_SCRATCH register + {0x8010002, 0xDEADC0DEC0DEBEEF} // PSCOM_ERROR_MASK register }; + const uint32_t g_expscomAddrTableSz = sizeof(g_expscomAddrTable)/sizeof(testExpscomAddrData); @@ -80,7 +82,7 @@ TS_FAIL(STRING , \ l_testEntry.addr, \ get_huid(TARGET)); \ l_err = fapi2::rcToErrl(l_rc); \ -errlCommit(l_err, 0x10); +errlCommit(l_err, CXXTEST_COMP_ID); #define FAIL_TEST_ERRL(TARGET, STRING) \ l_fails++; \ @@ -88,7 +90,7 @@ TS_FAIL(STRING , \ l_testEntry.data, \ l_testEntry.addr, \ get_huid(TARGET)); \ -errlCommit(l_err, 0x10); +errlCommit(l_err, CXXTEST_COMP_ID); class expscomTest: public CxxTest::TestSuite { @@ -107,14 +109,33 @@ private: return fapi2::getScom(i_target,i_address,o_data); } + fapi2::ReturnCode put_scom(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, + const uint64_t i_address, + const fapi2::buffer<uint64_t> i_data) + { + return fapi2::putScom(i_target,i_address,i_data); + } + + fapi2::ReturnCode get_scom(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, + const uint64_t i_address, + fapi2::buffer<uint64_t>& o_data) + { + return fapi2::getScom(i_target,i_address,o_data); + } + + // This is used for tests that need to not run operations at the same time + HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex; + public: /** - * @brief EXPSCOM test I2C Path + * @brief EXPSCOM test I2C Path of FAPI HWP interfaces * Write value and read back to verify i2c scoms to OCMBs */ void testExpscomI2c(void) { +// Only MMIO supported at runtime +#ifndef __HOSTBOOT_RUNTIME TRACFCOMP( g_trac_expscom, ">> Enter testExpscomI2c"); // Keep trace of pass/fails uint32_t l_tests = 0; @@ -125,15 +146,16 @@ public: // will be used to hold error from fapi calls fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; fapi2::buffer<uint64_t> l_scom_buffer; - TargetHandleList l_explorerList; do{ -// Causing a data storage exception in c_str... -#ifdef CONFIG_AXONE_BRING_UP -TRACFCOMP( g_trac_expscom,"skipping testExpscomI2c"); -break; -#endif + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup"); + break; + } + // Get the system's OCMB chips, we will use these as test targets + TargetHandleList l_explorerList; getAllChips( l_explorerList, TYPE_OCMB_CHIP, true ); // true: return functional OCMBs @@ -144,23 +166,44 @@ break; break; } + // Get the system's MEM_PORT units, we will use these as test targets + TargetHandleList l_memportList; + getAllChiplets( l_memportList, + TYPE_MEM_PORT, + true ); // true: return functional OCMBs + + if(l_explorerList.size() != l_memportList.size() ) + { + TS_FAIL( "Wrong number of MEM_PORTs (%d) compared to OCMB_CHIPs (%d)", l_memportList.size(), l_explorerList.size() ); + break; + } // We will use the first and last targets for these scom tests auto l_firstExpChip = l_explorerList.front(); auto l_lastExpChip = l_explorerList.back(); + auto l_firstMemPort = l_memportList.front(); + auto l_lastMemPort = l_memportList.back(); // Cast the TARGETING::Targets into fapi2::Targets fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip); fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip); + fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> l_firstMemPort_fapi(l_firstMemPort); + fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> l_lastMemPort_fapi(l_lastMemPort); // Save away original scom switch info so we can restore it at the end of the test - auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); - auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); + auto first_ocmb_info = + l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + auto last_ocmb_info = + l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>(); - // This goal of this tests is to make sure I2C scom to OCMB is working so force - // scom to go over I2C path for these targets - l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); - l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + + // The goal of these tests is to make sure I2C scom to OCMB is + // working so force scom to go over I2C path for these targets + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); // Loop through table for first and last OCMB targets for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) @@ -216,7 +259,7 @@ break; if(l_err) { FAIL_TEST_ERRL(l_firstExpChip, - "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") + "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); } l_tests++; @@ -241,7 +284,7 @@ break; if(l_err) { FAIL_TEST_ERRL(l_lastExpChip, - "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") + "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); } l_tests++; @@ -253,20 +296,118 @@ break; l_scom_buffer(), get_huid(l_lastExpChip)); } + + /// Repeat everything on the MEM_PORT targets + + // Read the test entry info from the global table at the top of this file + l_testEntry = g_expscomAddrTable[l_num]; + + if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) + { + // If this is an IBM address then we expect 64 bits of data + l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); + } + else + { + // Otherwise we know this is a native OCMB address and it is only 32 bits + l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data); + } + + FAPI_INVOKE_HWP(l_err, put_scom, + l_firstMemPort_fapi, + l_testEntry.addr, + l_scom_buffer ); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstMemPort, + "testExpscomI2c>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); + + } + + // putScom to last MEM_PORT over i2c + FAPI_INVOKE_HWP(l_err, put_scom, + l_lastMemPort_fapi, + l_testEntry.addr, + l_scom_buffer ); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_lastMemPort, + "testExpscomI2c>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); + } + + + // Flush scom buffers so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to first MEM_PORT over i2c + FAPI_INVOKE_HWP(l_err, get_scom, + l_firstMemPort_fapi, + l_testEntry.addr, + l_scom_buffer ); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstMemPort, + "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomI2c>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_firstMemPort)); + } + + // Flush scom buffers so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to last MEM_PORT over i2c + FAPI_INVOKE_HWP(l_err, get_scom, + l_lastMemPort_fapi, + l_testEntry.addr, + l_scom_buffer ); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_lastMemPort, + "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomI2c>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_lastMemPort)); + } } // Set ATTR_SCOM_SWITCHES back to their original values - l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info); - l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info); - }while(0); + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info); + // << atomic section + mutex_unlock(iv_serializeTestMutex); + }while(0); TRACFCOMP( g_trac_expscom, "<< Exit testExpscomI2c"); +#endif return; } + /** + * @brief Test platform level interfaces over I2C + */ void testExpscomI2cPlatform(void) { - +// Only mmio supported at runtime +#ifndef __HOSTBOOT_RUNTIME TRACFCOMP( g_trac_expscom, ">> Enter testExpscomI2cPlatform"); // Keep trace of pass/fails uint32_t l_tests = 0; @@ -283,12 +424,11 @@ break; TargetHandleList l_explorerList; do{ -// Causing a data storage exception in c_str... -#ifdef CONFIG_AXONE_BRING_UP -TRACFCOMP( g_trac_expscom,"skipping testExpscomI2cPlatformPlatform"); -break; -#endif - + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup"); + break; + } getAllChips( l_explorerList, TYPE_OCMB_CHIP, true ); // true: return functional OCMBs @@ -296,7 +436,7 @@ break; if(l_explorerList.size() == 0 ) { - TRACFCOMP( g_trac_expscom, "No OCMB targets found, skipping testExpscomI2cPlatformPlatform"); + TRACFCOMP( g_trac_expscom, "No OCMB targets found, skipping testExpscomI2cPlatform"); break; } @@ -305,412 +445,517 @@ break; auto l_lastExpChip = l_explorerList.back(); // Save away original scom switch info so we can restore it at the end of the test - auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); - auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); + auto first_ocmb_info = + l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + auto last_ocmb_info = + l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); // This goal of this tests is to make sure I2C scom to OCMB is working so force // scom to go over I2C path for these targets - l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); - l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); // Loop through table for first and last OCMB targets for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) { - // Read the test entry info from the global table at the top of this file - testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; - - if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) - { - // If this is an IBM address then we expect 64 bits of data - l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); - } - else - { - // Otherwise we know this is a native OCMB address and it is only 32 bits - l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data); - } - l_err = deviceWrite(l_firstExpChip, - &l_scom_buffer, - l_scomSize, - DEVICE_SCOM_ADDRESS( l_testEntry.addr)); - l_tests++; - if(l_err) - { - FAIL_TEST_ERRL(l_firstExpChip, + // Read the test entry info from the global table at the top of this file + testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; + + if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) + { + // If this is an IBM address then we expect 64 bits of data + l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); + } + else + { + // Otherwise we know this is a native OCMB address and it is only 32 bits + l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data); + } + l_err = deviceWrite(l_firstExpChip, + &l_scom_buffer, + l_scomSize, + DEVICE_SCOM_ADDRESS( l_testEntry.addr)); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstExpChip, + "testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); + + } + + l_err = deviceWrite(l_lastExpChip, + &l_scom_buffer, + l_scomSize, + DEVICE_SCOM_ADDRESS( l_testEntry.addr)); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstExpChip, "testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); - } - - l_err = deviceWrite(l_lastExpChip, - &l_scom_buffer, - l_scomSize, - DEVICE_SCOM_ADDRESS( l_testEntry.addr)); - l_tests++; - if(l_err) - { - FAIL_TEST_ERRL(l_firstExpChip, - "testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X"); - - } - // Flush scom buffers so it doesnt mess up next test - l_scom_buffer.flush<0>(); - - // getScom to first OCMB over i2c - l_err = deviceRead(l_firstExpChip, - &l_scom_buffer(), - l_scomSize, - DEVICE_SCOM_ADDRESS( l_testEntry.addr)); - l_tests++; - if(l_err) - { - FAIL_TEST_ERRL(l_firstExpChip, - "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") - } - - l_tests++; - if(l_scom_buffer() != l_testEntry.data) - { - l_fails++; - TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", - l_testEntry.data, - l_scom_buffer(), - get_huid(l_firstExpChip)); - } - - - // Flush scom buffers so it doesnt mess up next test - l_scom_buffer.flush<0>(); - - // getScom to last OCMB over i2c - l_err = deviceRead(l_lastExpChip, - &l_scom_buffer(), - l_scomSize, - DEVICE_SCOM_ADDRESS( l_testEntry.addr)); - l_tests++; - if(l_err) - { - FAIL_TEST_ERRL(l_firstExpChip, - "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") - } - - l_tests++; - if(l_scom_buffer() != l_testEntry.data) - { - l_fails++; - TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", - l_testEntry.data, - l_scom_buffer(), - get_huid(l_firstExpChip)); - } + } + // Flush scom buffers so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to first OCMB over i2c + l_err = deviceRead(l_firstExpChip, + &l_scom_buffer(), + l_scomSize, + DEVICE_SCOM_ADDRESS( l_testEntry.addr)); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstExpChip, + "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_firstExpChip)); + } + + + // Flush scom buffers so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to last OCMB over i2c + l_err = deviceRead(l_lastExpChip, + &l_scom_buffer(), + l_scomSize, + DEVICE_SCOM_ADDRESS( l_testEntry.addr)); + l_tests++; + if(l_err) + { + FAIL_TEST_ERRL(l_firstExpChip, + "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X") + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_firstExpChip)); + } } // Set ATTR_SCOM_SWITCHES back to their original values - l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info); - l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info); + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info); + + // << atomic section + mutex_unlock(iv_serializeTestMutex); + }while(0); TRACFCOMP( g_trac_expscom, "<< Exit testExpscomI2cPlatform"); +#endif return; } -// TODO RTC: 189447 Enable MMIO tests when MMIO drivers avail - /** + /** * @brief EXPSCOM test MMIO * Write value and read back to verify MMIO scoms to OCMBs + * using fapi HWPs. */ -// void testExpscomMmio(void) -// { -// TargetHandleList l_explorerList; -// uint32_t l_tests = 0; -// uint32_t l_fails = 0; -// errlHndl_t l_err = nullptr; -// fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; -// fapi2::buffer<uint64_t> l_scom_buffer; -// -// // Get the system's procs -// getAllChips( l_explorerList, -// TYPE_OCMB_CHIP, -// true ); // true: return functional OCMBs -// -// auto l_firstExpChip = l_explorerList.front(); -// auto l_lastExpChip = l_explorerList.back(); -// -// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip); -// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip); -// -// auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); -// auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); -// -// -// // Loop through table for first and last OCMB, perform i2c write, then -// // mmio read, and mmio write followed by i2c read. -// for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) -// { -// testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; -// if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) -// { -// l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); -// } -// else -// { -// l_scom_buffer.insert<0,32,0,uint32_t>(l_testEntry.data); -// } -// -// // putScom to first OCMB over mmio -// l_rc = put_scom(l_firstExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_firstExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// -// // putScom to last OCMB over mmio -// l_rc = put_scom(l_lastExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_lastExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// -// // Flush scom buffer so it doesnt mess up next test -// l_scom_buffer.flush<0>(); -// -// -// // getScom to first OCMB over mmio -// l_rc = get_scom(l_firstExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_firstExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// -// l_tests++; -// if(l_scom_buffer() != l_testEntry.data) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_scom_buffer(), -// get_huid(l_firstExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// -// // Flush scom buffer so it doesnt mess up next test -// l_scom_buffer.flush<0>(); -// -// // getScom to last OCMB over mmio -// l_rc = get_scom(l_lastExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_lastExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// -// l_tests++; -// if(l_scom_buffer() != l_testEntry.data) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_scom_buffer(), -// get_huid(l_lastExpChip)); -// l_err = fapi2::rcToErrl(l_rc); -// errlCommit(l_err, 0x10); -// } -// } -// // Set ATTR_SCOM_SWITCHES back to their original values -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info); -// return; -// } - - /** - * @brief EXPSCOM test MMIO - * Write value and read back to verify MMIO - */ -// void testExpscomCombined(void) -// { -// TargetHandleList l_explorerList; -// uint32_t l_tests = 0; -// uint32_t l_fails = 0; -// fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; -// fapi2::buffer<uint64_t> l_scom_buffer; -// -// // Get the system's procs -// getAllChips( l_explorerList, -// TYPE_OCMB_CHIP, -// true ); // true: return functional OCMBs -// -// auto l_firstExpChip = l_explorerList.front(); -// auto l_lastExpChip = l_explorerList.back(); -// -// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip); -// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip); -// -// auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); -// auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); -// -// // Loop through table for first and last OCMB -// for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) -// { -// testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; -// -// if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) -// { -// l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); -// } -// else -// { -// l_scom_buffer.insert<0,32,0,uint32_t>(l_testEntry.data); -// } -// -// // ODD tests : first target writes MMIO, last target writes I2C -// // EVEN tests : first target writes I2C, last target writes MMIO -// if(l_num % 2) -// { -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); -// } -// else -// { -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom); -// } -// -// // putScom to first OCMB over mmio -// l_rc = put_scom(l_firstExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_firstExpChip)); -// } -// -// // putScom to last OCMB over mmio -// l_rc = put_scom(l_lastExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_lastExpChip)); -// } -// -// // Flush scom buffer so it doesnt mess up next test -// l_scom_buffer.flush<0>(); -// -// // getScom to first OCMB over mmio -// l_rc = get_scom(l_firstExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_firstExpChip)); -// } -// -// l_tests++; -// if(l_scom_buffer() != l_testEntry.data) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_scom_buffer(), -// get_huid(l_firstExpChip)); -// } -// -// // ODD tests : first target reads I2C, last target reads MMIO -// // EVEN tests : first target reads MMIO, last target reads I2C -// if(l_num % 2) -// { -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom); -// } -// else -// { -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom); -// } -// -// // Flush scom buffer so it doesnt mess up next test -// l_scom_buffer.flush<0>(); -// -// // getScom to last OCMB over mmio -// l_rc = get_scom(l_lastExpChip_fapi, -// l_testEntry.addr, -// l_scom_buffer); -// l_tests++; -// if(l_rc) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_testEntry.addr, -// get_huid(l_lastExpChip)); -// } -// -// l_tests++; -// if(l_scom_buffer() != l_testEntry.data) -// { -// l_fails++; -// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", -// l_testEntry.data, -// l_scom_buffer(), -// get_huid(l_lastExpChip)); -// } -// } -// // Set ATTR_SCOM_SWITCHES back to their original values -// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info); -// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info); -// return; -// } + void testExpscomMmio(void) + { + TargetHandleList l_explorerList; + uint32_t l_tests = 0; + uint32_t l_fails = 0; + errlHndl_t l_err = nullptr; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + fapi2::buffer<uint64_t> l_scom_buffer; + + TRACFCOMP(g_trac_expscom, ">> Enter testExpscomMmio"); + + do{ + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup"); + break; + } + + // Get the system's procs + getAllChips( l_explorerList, + TYPE_OCMB_CHIP, + true ); // true: return functional OCMBs + + if(l_explorerList.size() == 0 ) + { + TRACFCOMP(g_trac_expscom, "No OCMB targets found, skipping testExpscomMmio"); + break; + } + + auto l_firstExpChip = l_explorerList.front(); + auto l_lastExpChip = l_explorerList.back(); + + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> + l_firstExpChip_fapi(l_firstExpChip); + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> + l_lastExpChip_fapi(l_lastExpChip); + + auto first_ocmb_info = + l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + auto last_ocmb_info = + l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + + // Force use of MMIO + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + + // Loop through table for first and last OCMB, perform i2c write, + // then read it back + for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) + { + testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; + if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) + { + l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); + } + else + { + l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data); + } + + // putScom to first OCMB over mmio + l_rc = put_scom(l_firstExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_firstExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + // putScom to last OCMB over mmio + l_rc = put_scom(l_lastExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_lastExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + // Flush scom buffer so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to first OCMB over mmio + l_rc = get_scom(l_firstExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_firstExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_firstExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + // Flush scom buffer so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to last OCMB over mmio + l_rc = get_scom(l_lastExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_lastExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_lastExpChip)); + l_err = fapi2::rcToErrl(l_rc); + errlCommit(l_err, CXXTEST_COMP_ID); + } + } + // Set ATTR_SCOM_SWITCHES back to their original values + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info); + + // << atomic section + mutex_unlock(iv_serializeTestMutex); + }while(0); + + + TRACFCOMP(g_trac_expscom, "<< Exit testExpscomMmio"); + return; + } + + /** + * @brief EXPSCOM test MMIO + * Combine I2C and MMIO reads/writes to verify that we + * get consistent results using FAPI HWPs. + */ + void testExpscomCombined(void) + { +// Only MMIO scoms supported at runtime, i2c not supported +#ifndef __HOSTBOOT_RUNTIME + TargetHandleList l_explorerList; + uint32_t l_tests = 0; + uint32_t l_fails = 0; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + fapi2::buffer<uint64_t> l_scom_buffer; + + TRACFCOMP(g_trac_expscom, ">> Enter testExpscomCombined"); + + do{ + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup"); + break; + } + + // Get the system's procs + getAllChips( l_explorerList, + TYPE_OCMB_CHIP, + true ); // true: return functional OCMBs + + if(l_explorerList.size() == 0 ) + { + TRACFCOMP(g_trac_expscom, "No OCMB targets found, skipping testExpscomCombined"); + break; + } + + auto l_firstExpChip = l_explorerList.front(); + auto l_lastExpChip = l_explorerList.back(); + + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> + l_firstExpChip_fapi(l_firstExpChip); + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> + l_lastExpChip_fapi(l_lastExpChip); + + auto first_ocmb_info = + l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + auto last_ocmb_info = + l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>(); + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + + // Loop through table for first and last OCMB, perform i2c write, + // then mmio read, and mmio write followed by i2c read. + for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++) + { + testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num]; + + if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR) + { + l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data); + } + else + { + l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data); + } + + // ODD tests : first target writes MMIO, last target writes I2C + // EVEN tests : first target writes I2C, last target writes MMIO + if(l_num % 2) + { + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + } + else + { + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + } + + // putScom to first OCMB + l_rc = put_scom(l_firstExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_firstExpChip)); + } + + // putScom to last OCMB + l_rc = put_scom(l_lastExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_lastExpChip)); + } + + // Flush scom buffer so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to first OCMB + l_rc = get_scom(l_firstExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_firstExpChip)); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_firstExpChip)); + } + + // ODD tests : first target reads I2C, last target reads MMIO + // EVEN tests : first target reads MMIO, last target reads I2C + if(l_num % 2) + { + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + } + else + { + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom); + } + + // Flush scom buffer so it doesnt mess up next test + l_scom_buffer.flush<0>(); + + // getScom to last OCMB + l_rc = get_scom(l_lastExpChip_fapi, + l_testEntry.addr, + l_scom_buffer); + l_tests++; + if(l_rc) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X", + l_testEntry.data, + l_testEntry.addr, + get_huid(l_lastExpChip)); + } + + l_tests++; + if(l_scom_buffer() != l_testEntry.data) + { + l_fails++; + TS_FAIL("testExpscomCombined>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X", + l_testEntry.data, + l_scom_buffer(), + get_huid(l_lastExpChip)); + } + } + + // Set ATTR_SCOM_SWITCHES back to their original values + l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info); + l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info); + + // << atomic section + mutex_unlock(iv_serializeTestMutex); + }while(0); + + TRACFCOMP(g_trac_expscom, "<< Exit testExpscomCombined"); +#endif + return; + } + + /** + * @brief Constructor + */ + expscomTest() : CxxTest::TestSuite() + { + // All modules are loaded by runtime, + // so testcase loading of modules is not required +#ifndef __HOSTBOOT_RUNTIME + errlHndl_t err = nullptr; + + err = exptest::loadModule(exptest::MSS_LIBRARY_NAME); + if(err) + { + TS_FAIL("expscomTest() - Constuctor: failed to load MSS module"); + errlCommit( err, CXXTEST_COMP_ID ); + } +#endif + iv_serializeTestMutex = exptest::getTestMutex(); + }; + + + /** + * @brief Destructor + */ + ~expscomTest() + { + }; }; diff --git a/src/usr/expaccess/test/exptest_utils.C b/src/usr/expaccess/test/exptest_utils.C new file mode 100644 index 000000000..01096716f --- /dev/null +++ b/src/usr/expaccess/test/exptest_utils.C @@ -0,0 +1,136 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/exptest_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ +#include <fapi2.H> +#include <cxxtest/TestSuite.H> +#include "exptest_utils.H" + +namespace exptest +{ + errlHndl_t loadModule(const char * i_modName) + { + errlHndl_t err = NULL; + + // VFS functions only compilable in non-runtime environment + #ifndef __HOSTBOOT_RUNTIME + if(!VFS::module_is_loaded(i_modName)) + { + err = VFS::module_load(i_modName); + if(err) + { + TS_FAIL("loadModule() - %s load failed", i_modName ); + } + else + { + FAPI_INF("loadModule: %s loaded", i_modName); + } + } + #endif + return err; + } + + TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR getTestMutex(void) + { + TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR pMutex = nullptr; + + // Get a reference to the target service + TARGETING::TargetService& l_targetService = TARGETING::targetService(); + + // Get the system target containing the test mutex + TARGETING::Target* l_pTarget = NULL; + (void) l_targetService.getTopLevelTarget(l_pTarget); + if (l_pTarget == nullptr) + { + TS_INFO("getTestMutex: Top level target handle is NULL"); + } + else + { + // use the chip-specific mutex attribute + pMutex = l_pTarget->getHbMutexAttr + <TARGETING::ATTR_HB_MUTEX_SERIALIZE_TEST_LOCK>(); + } + return pMutex; + } + + void enableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget) + { + mutex_t* l_mutex = nullptr; + + assert((i_ocmbTarget != nullptr), + "enableInbandScomsOcmb: target is NULL!"); + + // Verify that the target is of type OCMB_CHIP + TARGETING::ATTR_TYPE_type l_targetType = + i_ocmbTarget->getAttr<TARGETING::ATTR_TYPE>(); + assert((l_targetType == TARGETING::TYPE_OCMB_CHIP), + "enableInbandScomsOcmb: target is not an OCMB chip!"); + + TS_INFO("enableInbandScomsOcmb: switching to use MMIO on OCMB 0x%08x", + TARGETING::get_huid(i_ocmbTarget)); + + //don't mess with attributes without the mutex (just to be safe) + l_mutex = i_ocmbTarget->getHbMutexAttr<TARGETING::ATTR_IBSCOM_MUTEX>(); + mutex_lock(l_mutex); + + TARGETING::ScomSwitches l_switches = + i_ocmbTarget->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); + l_switches.useInbandScom = 1; + l_switches.useI2cScom = 0; + + // Modify attribute + i_ocmbTarget->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(l_switches); + mutex_unlock(l_mutex); + }; + + void disableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget) + { + mutex_t* l_mutex = nullptr; + + assert((i_ocmbTarget != nullptr), + "disableInbandScomsOcmb: target is NULL!"); + + // Verify that the target is of type OCMB_CHIP + TARGETING::ATTR_TYPE_type l_targetType = + i_ocmbTarget->getAttr<TARGETING::ATTR_TYPE>(); + assert((l_targetType == TARGETING::TYPE_OCMB_CHIP), + "disableInbandScomsOcmb: target is not an OCMB chip!"); + + TS_INFO("disableInbandScomsOcmb: switching to use i2c on OCMB 0x%08x", + TARGETING::get_huid(i_ocmbTarget)); + + //don't mess with attributes without the mutex (just to be safe) + l_mutex = i_ocmbTarget->getHbMutexAttr<TARGETING::ATTR_IBSCOM_MUTEX>(); + mutex_lock(l_mutex); + + TARGETING::ScomSwitches l_switches = + i_ocmbTarget->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); + l_switches.useInbandScom = 0; + l_switches.useI2cScom = 1; + + // Modify attribute + i_ocmbTarget->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(l_switches); + mutex_unlock(l_mutex); + }; + +} diff --git a/src/usr/expaccess/test/exptest_utils.H b/src/usr/expaccess/test/exptest_utils.H new file mode 100644 index 000000000..babba0fcf --- /dev/null +++ b/src/usr/expaccess/test/exptest_utils.H @@ -0,0 +1,64 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/exptest_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ +#ifndef EXPTEST_UTILS_H_ +#define EXPTEST_UTILS_H_ + +#ifndef __HOSTBOOT_RUNTIME +#include <vfs/vfs.H> // module_is_loaded & module_load +#endif + +namespace exptest +{ + +// Need this module for mss::c_str call in HWP failure path traces +const char MSS_LIBRARY_NAME[17] = "libisteps_mss.so"; + +/** + * @brief Generic function to load a module + * @param i_modName - module name to load + * @return error handle if module_load call fails + */ +errlHndl_t loadModule(const char * i_modName); + +/** + * @brief Get the mutex pointer for syncronizing tests + * @return pointer to mutex, nullptr if not found + */ +TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR getTestMutex(void); + +/** + * @brief Enable inband scoms on an OCMB target + * @param[in] i_ocmbTarget The target OCMB chip + */ +void enableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget); + +/** + * @brief Disable inband scoms on an OCMB target (use i2c instead) + * @param[in] i_ocmbTarget The target OCMB chip + */ +void disableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget); +} + +#endif diff --git a/src/usr/expaccess/test/makefile b/src/usr/expaccess/test/makefile index 461a908c8..0e4f0e2e5 100644 --- a/src/usr/expaccess/test/makefile +++ b/src/usr/expaccess/test/makefile @@ -28,7 +28,6 @@ MODULE = testexpaccess include test.mk -#TODO RTC:196806 re-enable mmio communication tests when mmio works -TESTS = expscomtest.H +TESTS = *.H -include ${ROOTPATH}/config.mk
\ No newline at end of file +include ${ROOTPATH}/config.mk diff --git a/src/usr/expaccess/test/ocmbcommtest.H b/src/usr/expaccess/test/ocmbcommtest.H index 94d298032..3c5486a1b 100644 --- a/src/usr/expaccess/test/ocmbcommtest.H +++ b/src/usr/expaccess/test/ocmbcommtest.H @@ -33,13 +33,13 @@ #include <errl/errlmanager.H> #include <errl/errlentry.H> #include <fapi2.H> -#ifndef __HOSTBOOT_RUNTIME -#include <vfs/vfs.H> // module_is_loaded & module_load -#endif + #include <plat_hwp_invoker.H> -#include <exp_inband.H> +#include <lib/inband/exp_inband.H> #include <exp_data_structs.H> #include <generic/memory/lib/utils/endian_utils.H> +#include "exptest_utils.H" + // EXP_FW_ADAPTER_PROPERTIES_GET data response format #define FW_ADAPTER_MAX_FW_IMAGE 4 @@ -67,64 +67,6 @@ typedef struct } FW_ADAPTER_PROPERTIES_type; -// Need this module for mss::c_str call in HWP failure path traces -const char MSS_LIBRARY_NAME[17] = "libisteps_mss.so"; - -/** - * @brief Generic function to load a module - * @param o_module_loaded - returns true if module is loaded by this function - * @param i_modName - module name to load - * @return error handle if module_load call fails - */ -errlHndl_t loadModule(bool & o_module_loaded, const char * i_modName) -{ - errlHndl_t err = NULL; - o_module_loaded = false; - -// VFS functions only compilable in non-runtime environment -#ifndef __HOSTBOOT_RUNTIME - if(!VFS::module_is_loaded(i_modName)) - { - err = VFS::module_load(i_modName); - if(err) - { - TS_FAIL("loadModule() - %s load failed", i_modName ); - } - else - { - o_module_loaded = true; - FAPI_INF("loadModule: %s loaded", i_modName); - } - } -#endif - return err; -} - -/** - * @brief Generic function to unload a module - * @param i_modName - module name to load - * @return error handle if module_unload call fails - */ -errlHndl_t unloadModule(const char * i_modName) -{ - errlHndl_t err = NULL; - -// VFS function only compilable in non-runtime environment -#ifndef __HOSTBOOT_RUNTIME - err = VFS::module_unload(i_modName); - if(err) - { - TS_FAIL("unloadExplorerModule() - %s unload failed", i_modName ); - } - else - { - FAPI_INF("unloadModule: %s unloaded", i_modName); - } -#endif - return err; -} - - class OCMBCommTest: public CxxTest::TestSuite { public: @@ -189,11 +131,13 @@ class OCMBCommTest: public CxxTest::TestSuite } /** - * @brief Test the Explorer inband command/response path + * @brief Send and check get_properties Explorer inband command + * @return Number of failures */ - void testOcmbInbandCmdRsp( void ) + int sendOcmbInbandCmdRsp(bool setScomI2c) { errlHndl_t l_errl = nullptr; + uint8_t failures = 0; // Create a vector of TARGETING::Target pointers TARGETING::TargetHandleList l_chipList; @@ -210,102 +154,217 @@ class OCMBCommTest: public CxxTest::TestSuite for (auto & l_ocmb: l_chipList) { - FAPI_INF("testOcmbInbandCmdRsp: testing 0x%.8X OCMB", TARGETING::get_huid(l_ocmb)); - - fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target( l_ocmb ); + do + { + if (setScomI2c) + { + FAPI_INF("sendOcmbInbandCmdRsp: testing 0x%.8X OCMB using I2C", TARGETING::get_huid(l_ocmb)); + // disable inband and use i2c when possible + exptest::disableInbandScomsOcmb(l_ocmb); + } + else + { + FAPI_INF("sendOcmbInbandCmdRsp: testing 0x%.8X OCMB using MMIO", TARGETING::get_huid(l_ocmb)); + // just incase some other test disabled inband scoms + exptest::enableInbandScomsOcmb(l_ocmb); + } + + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target( l_ocmb ); + + TRACFBIN(g_trac_expscom, "l_cmd: ", &l_cmd, sizeof(host_fw_command_struct)); + + // send the command + FAPI_INVOKE_HWP(l_errl, mss::exp::ib::putCMD, l_fapi2_target, + l_cmd); + if (l_errl) + { + TS_FAIL("Error from putCMD for 0x%.8X target", + TARGETING::get_huid(l_ocmb)); + failures++; + break; + } + + FAPI_INF("sendOcmbInbandCmdRsp: reading response"); + + // grab the response + FAPI_INVOKE_HWP(l_errl, mss::exp::ib::getRSP, l_fapi2_target, + l_rsp, l_rsp_data); + if (l_errl) + { + TS_FAIL("Error from getRSP for 0x%.8X target, plid=0x%X rc=0x%X", + TARGETING::get_huid(l_ocmb), + ERRL_GETPLID_SAFE(l_errl), ERRL_GETRC_SAFE(l_errl)); + failures++; + break; + } + + TRACFBIN(g_trac_expscom, "l_rsp: ", &l_rsp, sizeof(host_fw_response_struct)); + TRACFBIN(g_trac_expscom, "l_rsp_data: ", l_rsp_data.data(), l_rsp_data.size()); + + // Check for a valid data response length + if (l_rsp.response_length != sizeof(FW_ADAPTER_PROPERTIES_type)) + { + TS_FAIL("Unexpected response length 0x%.8X (expected 0x%.8X)", + l_rsp.response_length, sizeof(FW_ADAPTER_PROPERTIES_type)); + failures++; + break; + } + + // Now convert the little endian response data into big endian + FW_ADAPTER_PROPERTIES_type l_fw_adapter_data; + fw_adapter_properties_struct_from_little_endian(l_fw_adapter_data, + l_rsp_data); + + // Check for some expected response values + // Simics should return 0x88 as the first byte of chip_version + if (l_fw_adapter_data.chip_version[0] != 0x88 ) + { + TS_FAIL("Expected chip_version to start with 0x88, found 0x%02X", + l_fw_adapter_data.chip_version[0]); + failures++; + } + } while (0); - // send the command - FAPI_INVOKE_HWP(l_errl, mss::exp::ib::putCMD, l_fapi2_target, - l_cmd); if (l_errl) { - TS_FAIL("Error from putCMD for 0x%.8X target", - TARGETING::get_huid(l_ocmb)); - break; + // Commit the error as this is NOT expected and + // needs to be investigated + errlCommit( l_errl, TARG_COMP_ID ); } - // grab the response - FAPI_INVOKE_HWP(l_errl, mss::exp::ib::getRSP, l_fapi2_target, - l_rsp, l_rsp_data); - if (l_errl) + if (setScomI2c) { - TS_FAIL("Error from getRSP for 0x%.8X target", - TARGETING::get_huid(l_ocmb)); - break; + // Default the ocmb back to inband communication + exptest::enableInbandScomsOcmb(l_ocmb); } + } + + FAPI_INF("sendOcmbInbandCmdRsp: exiting"); + return failures; + }; + + /** + * @brief Test the Explorer inband command/response path over MMIO + */ + void testOcmbInbandCmdRspOverMMIO( void ) + { + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup, unable to continue"); + } + else + { + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); - // Check for a valid data response length - if (l_rsp.response_length != sizeof(FW_ADAPTER_PROPERTIES_type)) + int failures = sendOcmbInbandCmdRsp(false); + if (failures) { - TS_FAIL("Unexpected response length 0x%.8X (expected 0x%.8X)", - l_rsp.response_length, sizeof(FW_ADAPTER_PROPERTIES_type)); - break; + TS_FAIL("testOcmbInbandCmdRspOverMMIO() failed: %d", failures); } + mutex_unlock(iv_serializeTestMutex); + } + } + + /** + * @brief Test the Explorer inband command/response path over I2C + * using ATTR_FORCE_SRAM_MMIO_OVER_I2C + */ + void testOcmbInbandCmdRspOverI2c_via_force( void ) + { + FAPI_INF("testOcmbInbandCmdRspOverI2c_via_force: entering"); + if (!iv_serializeTestMutex) + { + TS_FAIL("iv_serializedTestMutex is not setup, unable to continue"); + } + else + { + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + + // Set FORCE_SRAM_MMIO_OVER_I2C to change to use I2C instead of MMIO + TARGETING::Target * l_sys = nullptr; + TARGETING::targetService().getTopLevelTarget(l_sys); + crit_assert(l_sys != nullptr); - // Now convert the little endian response data into big endian - FW_ADAPTER_PROPERTIES_type l_fw_adapter_data; - fw_adapter_properties_struct_from_little_endian(l_fw_adapter_data, - l_rsp_data); + l_sys->setAttr<TARGETING::ATTR_FORCE_SRAM_MMIO_OVER_I2C>(0x01); - // Check for some expected response values - // Simics should return 0x10 as the first byte of chip_version - if (l_fw_adapter_data.chip_version[0] != 0x10 ) + int failures = sendOcmbInbandCmdRsp(false); + if (failures) { - TS_FAIL("Expected chip_version to start with 0x10, found 0x%02X", - l_fw_adapter_data.chip_version[0]); + TS_FAIL("testOcmbInbandCmdRspOverI2c_via_force() failed: %d", failures); } + + // Restore using MMIO instead of I2C + l_sys->setAttr<TARGETING::ATTR_FORCE_SRAM_MMIO_OVER_I2C>(0x00); + + mutex_unlock(iv_serializeTestMutex); } + FAPI_INF("testOcmbInbandCmdRspOverI2c_via_force: exiting"); + } - if (l_errl) + /** + * @brief Test the Explorer inband command/response path over I2C + * using scom setting to i2c + */ + void testOcmbInbandCmdRspOverI2c_via_scom_switch( void ) + { + FAPI_INF("testOcmbInbandCmdRspOverI2c_via_scom_switch: entering"); + if (!iv_serializeTestMutex) { - errlCommit( l_errl, TARG_COMP_ID ); + TS_FAIL("iv_serializedTestMutex is not setup, unable to continue"); } - FAPI_INF("testOcmbInbandCmdRsp: exiting"); - }; + else + { + // Inband operations can't be run at the same time + // atomic section >> + mutex_lock(iv_serializeTestMutex); + + // Set SCOM_SWITCHES to use i2c instead of MMMIO when + // running the inband cmd/rsp operations + int failures = sendOcmbInbandCmdRsp(true); + if (failures) + { + TS_FAIL("testOcmbInbandCmdRspOverI2c_via_scom_switch() failed: %d", failures); + } + + mutex_unlock(iv_serializeTestMutex); + } + FAPI_INF("testOcmbInbandCmdRspOverI2c_via_scom_switch: exiting"); + } /** * @brief Constructor */ OCMBCommTest() : CxxTest::TestSuite() { - mss_module_loaded = false; - // All modules are loaded by runtime, // so testcase loading of modules is not required #ifndef __HOSTBOOT_RUNTIME errlHndl_t err = nullptr; - err = loadModule(mss_module_loaded, MSS_LIBRARY_NAME); + err = exptest::loadModule(exptest::MSS_LIBRARY_NAME); if(err) { TS_FAIL("OCMBCommTest() - Constuctor: failed to load MSS module"); errlCommit( err, TARG_COMP_ID ); } #endif + iv_serializeTestMutex = exptest::getTestMutex(); }; - /** * @brief Destructor */ ~OCMBCommTest() { - errlHndl_t err = nullptr; - if (mss_module_loaded) - { - err = unloadModule(MSS_LIBRARY_NAME); - if(err) - { - TS_FAIL("~OCMBCommTest() - Destructor: failed to unload MSS module"); - errlCommit( err, TARG_COMP_ID ); - } - } }; private: - // use this to keep track of if we need to unload any - // modules loaded by this testcase - bool mss_module_loaded; + // This is used for tests that need to not run operations at the same time + TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex; }; diff --git a/src/usr/expaccess/test/rcExpLog.C b/src/usr/expaccess/test/rcExpLog.C new file mode 100644 index 000000000..53e61cd5d --- /dev/null +++ b/src/usr/expaccess/test/rcExpLog.C @@ -0,0 +1,55 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/rcExpLog.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 rcExpLog.C + * @brief Call fapi2::ReturnCode functions for explorer logs + */ +#include <cxxtest/TestSuite.H> +#include <fapi2.H> +#include <plat_hwp_invoker.H> +#include <hwp_error_info.H> +#include <hwp_ffdc_classes.H> + +#include <rcExpLog.H> + +fapi2::ReturnCode exp_error_rc( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target, + const uint32_t i_active_log_size, + const uint32_t i_saved_log_size) +{ + FAPI_INF("Enter exp_error_rc (active %d, saved %d)...", + i_active_log_size, i_saved_log_size); + + FAPI_ASSERT(0, fapi2::COLLECT_EXPLORER_ERROR() + .set_OCMB_CHIP_TARGET(i_ocmb_target) + .set_EXP_ACTIVE_LOG_SIZE(i_active_log_size) + .set_EXP_SAVED_LOG_SIZE(i_saved_log_size), + "Testcase exp_error_rc assert"); + +fapi_try_exit: + + FAPI_INF("Exiting exp_error_rc..."); + return fapi2::current_err; +} diff --git a/src/usr/expaccess/test/rcExpLog.H b/src/usr/expaccess/test/rcExpLog.H new file mode 100644 index 000000000..c3193bef9 --- /dev/null +++ b/src/usr/expaccess/test/rcExpLog.H @@ -0,0 +1,49 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/expaccess/test/rcExpLog.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 rcExpLog.H + * + * @brief These procedures provide fapi2 return codes with desired data to + * support testing from expErrlTest + */ +#ifndef _RC_EXPLOG_H_ +#define _RC_EXPLOG_H_ + +#include <fapi2.H> + + +/** + * @brief Creates a test RC with added Explorer log trace data + * @param i_ocmb_target - Explorer target + * @param i_active_log_size - maximum size of active (RAM) data to add + * @param i_saved_log_size - maximum size of saved (SPI flash) data to add + * @return ReturnCode with added error log data + */ +fapi2::ReturnCode exp_error_rc( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target, + const uint32_t i_active_log_size, + const uint32_t i_saved_log_size ); + +#endif diff --git a/src/usr/expaccess/test/test.mk b/src/usr/expaccess/test/test.mk index 059efe27d..9dd8237df 100644 --- a/src/usr/expaccess/test/test.mk +++ b/src/usr/expaccess/test/test.mk @@ -22,14 +22,23 @@ # permissions and limitations under the License. # # IBM_PROLOG_END_TAG -EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 -EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/ +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/ -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include -EXTRAINCDIR += ${ROOTPATH}/src/import +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/ +EXTRAINCDIR += ${ROOTPATH}/src/import/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/test/ +VPATH += ${ROOTPATH}/src/usr/expaccess/test/ +VPATH += ${ROOTPATH}/src/usr/expaccess/ +VPATH += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ + +OBJS += exptest_utils.o +OBJS += exp_collect_explorer_log.o +OBJS += rcExpLog.o include ${ROOTPATH}/config.mk |