diff options
author | Matt Derksen <mderkse1@us.ibm.com> | 2018-09-12 10:54:15 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-11-09 13:27:20 -0600 |
commit | 1e1b50096bb42d57f06af3016cd1e7c6977d0021 (patch) | |
tree | 349d0c3199a2010686b1b9c6f056668a61031a19 | |
parent | 8351efdb3b65ed4fc5472e78efd5db315663e42f (diff) | |
download | talos-hostboot-1e1b50096bb42d57f06af3016cd1e7c6977d0021.tar.gz talos-hostboot-1e1b50096bb42d57f06af3016cd1e7c6977d0021.zip |
Support fapi2 MMIO functions
There will be a new set of interfaces in fapi2 to perform mmio
(aka inband) operations directly. This is needed for OCMB access
in the memory HWPs, specifically as part of the command/response
protocol.
Change-Id: If473e8e53fa6f76a05ad897e150b58075c769902
RTC:191344
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66045
Reviewed-by: Richard Ward <rward15@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/include/usr/fapi2/mmio_access.H | 90 | ||||
-rw-r--r-- | src/include/usr/fapi2/plat_mmio_access.H | 77 | ||||
-rwxr-xr-x | src/usr/fapi2/fapi2.mk | 2 | ||||
-rw-r--r-- | src/usr/fapi2/plat_mmio_access.C | 208 | ||||
-rw-r--r-- | src/usr/fapi2/test/fapi2MmioAccessTest.H | 221 | ||||
-rw-r--r-- | src/usr/fapi2/test/fapi2Test.mk | 2 | ||||
-rw-r--r-- | src/usr/fapi2/test/p9_mmiotests.C | 299 | ||||
-rw-r--r-- | src/usr/fapi2/test/p9_mmiotests.H | 71 |
8 files changed, 970 insertions, 0 deletions
diff --git a/src/include/usr/fapi2/mmio_access.H b/src/include/usr/fapi2/mmio_access.H new file mode 100644 index 000000000..baa574207 --- /dev/null +++ b/src/include/usr/fapi2/mmio_access.H @@ -0,0 +1,90 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/fapi2/mmio_access.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file mmio_access.H +/// +/// @brief Hardware access functions that needs to be specialized for +/// platform implementation. +/// + +#ifndef _FAPI2_MMIO_ACCESS_H_ +#define _FAPI2_MMIO_ACCESS_H_ + +#include <fapi2_mmio_access.H> +#include <plat_mmio_access.H> + +namespace fapi2 +{ + //---------------------------------------------------------------------------- + // HW Communication Functions to be implemented at the platform layer. + //---------------------------------------------------------------------------- + /** + * @brief Calls platform-level implementation of getMMIO() + * + * @param[in] i_target HW target to operate on. + * @param[in] i_mmioAddr Address to read, relative to this Target's system + * MMIO address. + * @param[in] i_transSize Number of bytes to read in a single transaction. + * @param[out] o_data Buffer that holds data read from HW target. + * The size of the buffer determines the number of + * bytes that are read. + * + * @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + */ + template< TargetType K > + inline ReturnCode getMMIO(const Target<K>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + std::vector<uint8_t>& o_data) + { + return platGetMMIO(i_target, i_mmioAddr, i_transSize, o_data); + } + + /** + * @brief Calls platform-level implementation of putMMIO() + * + * @param[in] i_target HW target to operate on. + * @param[in] i_mmioAddr Address for write, relative to this Target's + * system MMIO address. + * @param[in] i_transSize Size of a single transaction, not the total amount + * of data to be transferred. For example, there is + * a requirement that we access the AXI regs with a + * 4-byte load and the SCOM regs with a 8-byte load. + * @param[in] i_data Buffer that holds data to write to the HW target. + * The size of the buffer determines the number of + * bytes to be written. + * @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + */ + template< TargetType K > + inline ReturnCode putMMIO(const Target<K>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + const std::vector<uint8_t>& i_data) + { + return platPutMMIO(i_target, i_mmioAddr, i_transSize, i_data); + } + +}; // fapi2 namespace + +#endif // _FAPI2_MMIO_ACCESS_H_ diff --git a/src/include/usr/fapi2/plat_mmio_access.H b/src/include/usr/fapi2/plat_mmio_access.H new file mode 100644 index 000000000..739c991c3 --- /dev/null +++ b/src/include/usr/fapi2/plat_mmio_access.H @@ -0,0 +1,77 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/fapi2/plat_mmio_access.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file plat_mmio_access.H +/// +/// @brief Platform mmio-access definitions +/// + +#ifndef _FAPI2_PLAT_MMIOACCESS_H_ +#define _FAPI2_PLAT_MMIOACCESS_H_ + +namespace fapi2 +{ + + /** + * @brief Platform-level implementation of getMMIO() + * Reads data via MMIO from the target + * + * @param[in] i_target FAPI HW target to operate on. + * @param[in] i_mmioAddr Address to read, relative to this Target's system + * MMIO address. + * @param[in] i_transSize Number of bytes to read in a single transaction. + * @param[out] o_data Buffer that holds data read from HW target. + * The size of the buffer determines the number of + * bytes that are read. + * + * @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + */ + ReturnCode platGetMMIO( const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + std::vector<uint8_t>& o_data ); + + /** + * @brief Platform-level implementation of putMMIO() + * Writes data via MMIO to the target + * + * @param[in] i_target FAPI HW target to operate on. + * @param[in] i_mmioAddr Address for write, relative to this Target's + * system MMIO address. + * @param[in] i_transSize Size of a single transaction, not the total amount + * of data to be transferred. For example, there is + * a requirement that we access the AXI regs with a + * 4-byte load and the SCOM regs with a 8-byte load. + * @param[in] i_data Buffer that holds data to write to the HW target. + * The size of the buffer determines the number of + * bytes to be written. + * @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + */ + ReturnCode platPutMMIO( const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + const std::vector<uint8_t>& i_data ); + +}; +#endif // _FAPI2_PLAT_MMIOACCESS_H_ diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk index d55521a02..9e2032470 100755 --- a/src/usr/fapi2/fapi2.mk +++ b/src/usr/fapi2/fapi2.mk @@ -81,6 +81,8 @@ OBJS += plat_wof_access.o OBJS += dimmBadDqBitmapFuncs.o OBJS += rowRepairsFuncs.o OBJS += plat_i2c_access.o +OBJS += plat_mmio_access.o + #Required include before all the procedure.mk are included include ${ROOTPATH}/procedure.rules.mk diff --git a/src/usr/fapi2/plat_mmio_access.C b/src/usr/fapi2/plat_mmio_access.C new file mode 100644 index 000000000..60526761b --- /dev/null +++ b/src/usr/fapi2/plat_mmio_access.C @@ -0,0 +1,208 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/plat_mmio_access.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_mmio_access.C + * + * @brief Implements FAPI mmio functions at the platform layer. + */ + +#include <stdint.h> +#include <errl/errlentry.H> +#include <devicefw/userif.H> +#include <return_code.H> +#include <target.H> +#include <target_types.H> +#include <plat_utils.H> +#include <attribute_service.H> +#include <hwpf_fapi2_reasoncodes.H> +#include <fapi2/plat_mmio_access.H> + + +namespace fapi2 +{ +//------------------------------------------------------------------------------ +// HW Communication Functions to be implemented at the platform layer. +//------------------------------------------------------------------------------ + +/// @brief Platform-level implementation of getMMIO() +/// Reads data via MMIO from the target +ReturnCode platGetMMIO( const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + std::vector<uint8_t>& o_data ) +{ + ReturnCode l_rc; + errlHndl_t l_err = nullptr; + + FAPI_DBG(ENTER_MRK "platGetMMIO"); + + // Note: Trace is placed here in plat code because PPE doesn't support + // trace in common fapi2_mmio_access.H + bool l_traceit = platIsScanTraceEnabled(); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + size_t l_get_size = o_data.size(); + + // create a temporary buffer for read data + uint8_t * l_data_read = new uint8_t[ l_get_size ]; + + do + { + // Extract the component pointer + TARGETING::Target * l_target = nullptr; + l_err = fapi2::platAttrSvc::getTargetingTarget(i_target, l_target); + if ( l_err ) + { + FAPI_ERR( "platGetMMIO: Error from getTargetingTarget on %s", + l_targName ); + break; //return with error + } + + // call MMIO driver + l_err = DeviceFW::deviceRead(l_target, + l_data_read, + l_get_size, + DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize)); + + if (l_traceit) + { + // Only trace the first 8 bytes of data read + // (don't want to overflow trace buffer) + uint64_t l_traceDataRead = 0; + if (l_get_size >= sizeof(l_traceDataRead)) + { + memcpy(&l_traceDataRead, l_data_read, sizeof(l_traceDataRead)); + } + else if (l_get_size > 0) + { + memcpy(&l_traceDataRead, l_data_read, l_get_size); + } + FAPI_SCAN("TRACE : getMMIO : %s %d - %d %.16llX", + l_targName, + o_data.size(), + l_get_size, + l_traceDataRead); + } + + } while(0); + + if (l_err) + { + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + } + else + { + // read was successful so copy data into o_data + o_data.clear(); + o_data.insert( o_data.end(), + &l_data_read[0], + &l_data_read[l_get_size] ); + } + delete [] l_data_read; + + FAPI_DBG(EXIT_MRK "platGetMMIO"); + return l_rc; +} + + +/// @brief Platform-level implementation of putMMIO() +/// Writes data via MMIO to the target +ReturnCode platPutMMIO( const Target<TARGET_TYPE_ALL>& i_target, + const uint64_t i_mmioAddr, + const size_t i_transSize, + const std::vector<uint8_t>& i_data ) +{ + ReturnCode l_rc; + errlHndl_t l_err = nullptr; + uint8_t * l_writeDataPtr; + + FAPI_DBG(ENTER_MRK "platPutMMIO"); + + // Note: Trace is placed here in plat code because PPE doesn't support + // trace in common fapi2_mmio_access.H + bool l_traceit = platIsScanTraceEnabled(); + + // Grab the name of the target + TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; + fapi2::toString(i_target, l_targName, sizeof(l_targName)); + + do { + // Extract the component pointer + TARGETING::Target * l_target = nullptr; + l_err = fapi2::platAttrSvc::getTargetingTarget(i_target, l_target); + if (l_err) + { + FAPI_ERR( "platPutMMIO: Error from getTargetingTarget on %s", + l_targName ); + break; //return with error + } + + //copy data from const vector to data ptr + l_writeDataPtr = new uint8_t[ i_data.size() ]; + std::copy(i_data.begin(), i_data.end(), l_writeDataPtr); + size_t l_dataSize = i_data.size(); + + // call MMIO driver + l_err = DeviceFW::deviceWrite(l_target, + l_writeDataPtr, + l_dataSize, + DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize)); + if (l_traceit) + { + // trace the first 8 bytes of written data + // (avoid trace buffer overflow) + uint64_t traceWriteData = 0; + if (l_dataSize > sizeof(traceWriteData)) + { + // copy what will fit into traceWriteData variable + memcpy(&traceWriteData, l_writeDataPtr, sizeof(traceWriteData)); + } + else + { + memcpy(&traceWriteData, l_writeDataPtr, l_dataSize); + } + FAPI_SCAN( "TRACE : putMMIO : %s : %d %.16llX", + l_targName, + l_dataSize, + traceWriteData ); + } + + delete [] l_writeDataPtr; + + } while (0); + + if (l_err) + { + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); + } + + FAPI_DBG(EXIT_MRK "platPutMMIO"); + return l_rc; +} + +} // End namespace diff --git a/src/usr/fapi2/test/fapi2MmioAccessTest.H b/src/usr/fapi2/test/fapi2MmioAccessTest.H new file mode 100644 index 000000000..dca8421a0 --- /dev/null +++ b/src/usr/fapi2/test/fapi2MmioAccessTest.H @@ -0,0 +1,221 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/fapi2MmioAccessTest.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __FAPI2_MMIOACCESSTEST_H +#define __FAPI2_MMIOACCESSTEST_H + +/** + * @file src/usr/fapi2/test/fapi2MmioAccessTest.H + * + * @brief Test various types of MMIO access with FAPI2 Macros + */ + +#include <cxxtest/TestSuite.H> +#include <errl/errlmanager.H> +#include <errl/errlentry.H> +#include <fapi2.H> +#include <fapi2TestUtils.H> +#include <p9_mmiotests.H> +#include <plat_hwp_invoker.H> + +using namespace fapi2; + +class Fapi2MmioAccessTest : public CxxTest::TestSuite +{ +public: +//****************************************************************************** +// test_fapi2MmioInvalidTarget +// Try calling mmio operation on invalid targets +//****************************************************************************** +void test_fapi2MmioInvalidTarget() +{ + errlHndl_t l_errl = nullptr; + int numTests = 0; + int numFails = 0; + + // Create a vector of TARGETING::Target pointers + TARGETING::TargetHandleList l_procTargetList; + + // Get a list of all of the proc chips + TARGETING::getAllChips(l_procTargetList, TARGETING::TYPE_PROC, true); + + for (auto & l_proc: l_procTargetList) + { + Target<fapi2::TARGET_TYPE_PROC_CHIP> fapi2_procTarget( l_proc ); + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_getmmio_invalid_target, fapi2_procTarget); + if(l_errl != nullptr) + { + delete l_errl; // delete expected error log + l_errl = nullptr; + } + else + { + TS_FAIL("No error from p9_mmiotest_getmmio_invalid_target !!"); + numFails++; + } + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_putmmio_invalid_target, fapi2_procTarget); + if(l_errl != nullptr) + { + delete l_errl; // delete expected error log + l_errl = nullptr; + } + else + { + TS_FAIL("No error from p9_mmiotest_putmmio_invalid_target !!"); + numFails++; + } + } + FAPI_INF("test_fapi2MmioInvalidTarget Test Complete. %d/%d fails", numFails, numTests); +} + +//****************************************************************************** +// test_fapi2MmioInvalidSizes +// Try calling mmio operation with invalid input sizes +//****************************************************************************** +void test_fapi2MmioInvalidSizes() +{ + errlHndl_t l_errl = nullptr; + int numTests = 0; + int numFails = 0; + + // Create a vector of TARGETING::Target pointers + TARGETING::TargetHandleList l_ocmbTargetList; + + // Get a list of all of the OCMB chips + TARGETING::getAllChips(l_ocmbTargetList, TARGETING::TYPE_OCMB_CHIP, true); + + for (auto & l_ocmb: l_ocmbTargetList) + { + Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget( l_ocmb ); + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_indivisible_by_section_size, fapi2_ocmbTarget); + if(l_errl != nullptr) + { + delete l_errl; // delete expected error log + l_errl = nullptr; + } + else + { + TS_FAIL("No error from p9_mmiotest_indivisible_by_section_size !!"); + numFails++; + } + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_invalid_section_size, fapi2_ocmbTarget); + if(l_errl != nullptr) + { + delete l_errl; // delete expected error log + l_errl = nullptr; + } + else + { + TS_FAIL("No error from p9_mmiotest_invalid_section_size !!"); + numFails++; + } + } + + FAPI_INF("test_fapi2MmioInvalidSizes Test Complete. %d/%d fails", numFails, numTests); +} + +//****************************************************************************** +// test_fapi2MmioAccess +//****************************************************************************** +void test_fapi2MmioAccess() +{ + int numTests = 0; + int numFails = 0; + + errlHndl_t l_errl = nullptr; + + // Create a vector of TARGETING::Target pointers + TARGETING::TargetHandleList l_chipList; + + // Get a list of all of the OCMB chips + TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true); + + for (auto & l_ocmb: l_chipList) + { + Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi2_target( l_ocmb ); + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_getmmio_pass, l_fapi2_target); + if(l_errl) + { + TS_FAIL("Error from p9_mmiotest_getmmio_pass !!"); + numFails++; + errlCommit(l_errl,FAPI2_COMP_ID); + delete l_errl; // delete unexpected error log so we dont get + // a false negative on the next case + l_errl = nullptr; + } + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_putmmio_pass, l_fapi2_target); + if(l_errl) + { + TS_FAIL("Error from p9_mmiotest_putmmio_pass !!"); + numFails++; + errlCommit(l_errl,FAPI2_COMP_ID); + delete l_errl; // delete unexpected error log so we dont get + // a false negative on the next case + l_errl = nullptr; + } + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_double_read_pass, l_fapi2_target); + if(l_errl) + { + TS_FAIL("Error from p9_mmiotest_double_read_pass !!"); + numFails++; + errlCommit(l_errl,FAPI2_COMP_ID); + delete l_errl; // delete unexpected error log so we dont get + // a false negative on the next case + l_errl = nullptr; + } + + numTests++; + FAPI_INVOKE_HWP(l_errl, p9_mmiotest_write_read_pass, l_fapi2_target); + if(l_errl) + { + TS_FAIL("Error from p9_mmiotest_write_read_pass !!"); + numFails++; + errlCommit(l_errl,FAPI2_COMP_ID); + delete l_errl; // delete unexpected error log so we dont get + // a false negative on the next case + l_errl = nullptr; + } + } + + FAPI_INF("fapi2MmioAccessTest Test Complete. %d/%d fails", numFails, numTests); +} + + +}; + +#endif // End __FAPI2_MMIOACCESSTEST_H diff --git a/src/usr/fapi2/test/fapi2Test.mk b/src/usr/fapi2/test/fapi2Test.mk index 6c3619a32..16c779b6e 100644 --- a/src/usr/fapi2/test/fapi2Test.mk +++ b/src/usr/fapi2/test/fapi2Test.mk @@ -57,6 +57,7 @@ ifeq (${HOSTBOOT_RUNTIME},1) ## Remove non-runtime tests (grep -v testname.H) TESTS += ${shell ls ${ROOTPATH}/src/usr/fapi2/test/*Test.H | \ grep -v fapi2I2cAccessTest.H | \ + grep -v fapi2MmioAccessTest.H | \ sort | xargs} ################################################################################ @@ -68,6 +69,7 @@ else TESTS += ${shell ls ${ROOTPATH}/src/usr/fapi2/test/*Test.H | \ sort | xargs} OBJS += p9_i2ctests.o +OBJS += p9_mmiotests.o ################################################################################ endif diff --git a/src/usr/fapi2/test/p9_mmiotests.C b/src/usr/fapi2/test/p9_mmiotests.C new file mode 100644 index 000000000..264e88117 --- /dev/null +++ b/src/usr/fapi2/test/p9_mmiotests.C @@ -0,0 +1,299 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/p9_mmiotests.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +//------------------------------------------------------------------------------ +/// @file p9_mmiotests.C +/// +/// @brief These procedures test the fapi2 mmio_access interfaces. +//----------------------------------------------------------------------------- +#include <sys/time.h> + +#include <cxxtest/TestSuite.H> +#include <fapi2.H> +#include <mmio_access.H> +#include <errl/errlentry.H> +#include <plat_hwp_invoker.H> +#include <sbe/sbe_common.H> + + +fapi2::ReturnCode p9_mmiotest_getmmio_invalid_target( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + // This will fail because PROC_CHIP not supported type + FAPI_INF("Entering p9_mmiotest_getmmio_invalid_target..."); + + std::vector<uint8_t> l_mmiodata; + l_mmiodata.resize(8); + + FAPI_INF("Do getMMIO on a proc target for 8 bytes"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, // mmio address relative to target + 8, // mmio transaction size + l_mmiodata)); + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_getmmio_invalid_target..."); + + return fapi2::current_err; + +} + + +fapi2::ReturnCode p9_mmiotest_putmmio_invalid_target( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) +{ + // This will fail because PROC_CHIP not supported type + FAPI_INF("Entering p9_mmiotest_putmmio_invalid_target..."); + + std::vector<uint8_t> l_mmiodata; + l_mmiodata.push_back(1); + l_mmiodata.push_back(2); + l_mmiodata.push_back(3); + l_mmiodata.push_back(4); + + + FAPI_INF( "Do putMMIO on proc target" ); + FAPI_TRY(fapi2::putMMIO(i_target, + 0x1000, + 4, + l_mmiodata)); + + fapi_try_exit: + + FAPI_INF( "Exiting p9_mmiotest_putmmio_invalid_target... rc = 0x%.8X", + (uint64_t)fapi2::current_err ); + + return fapi2::current_err; + +} + + +fapi2::ReturnCode p9_mmiotest_indivisible_by_section_size( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + // This will fail because data can not be divided evenly among multiple section size transfers + FAPI_INF("Entering p9_mmiotest_indivisible_by_section_size..."); + + std::vector<uint8_t> l_mmiodata; + l_mmiodata.resize(10); + + FAPI_INF("Do getMMIO on a target for 10 bytes"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, // mmio address relative to target + 8, // mmio transaction size + l_mmiodata)); + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_indivisible_by_section_size..."); + + return fapi2::current_err; + +} + + +fapi2::ReturnCode p9_mmiotest_invalid_section_size( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + // This will fail because an invalid section transfer size is being requested + FAPI_INF("Entering p9_mmiotest_invalid_section_size..."); + + std::vector<uint8_t> l_mmiodata; + l_mmiodata.resize(12); + + FAPI_INF("Do getMMIO on a target for 12 bytes"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, // mmio address relative to target + 12, // mmio transaction size + l_mmiodata)); + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_invalid_section_size..."); + + return fapi2::current_err; + +} + +//////////////////////////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////////////////////////// +fapi2::ReturnCode p9_mmiotest_getmmio_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + std::vector<uint8_t> l_mmiodata; + + FAPI_INF("Entering p9_mmiotest_getmmio_pass..."); + + const size_t l_mmiodataSize = 4; + l_mmiodata.resize(l_mmiodataSize); // do a single mmio transaction + + FAPI_INF("Do single-read transaction getMMIO on an OCMB target"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, + l_mmiodataSize, + l_mmiodata) ); + + + l_mmiodata.resize(l_mmiodataSize*2); // do a double mmio transaction + FAPI_INF("Do double-read transaction getMMIO on an OCMB target"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, + l_mmiodataSize, + l_mmiodata) ); + + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_getmmio_pass..."); + + return fapi2::current_err; + +} + + +fapi2::ReturnCode p9_mmiotest_double_read_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + std::vector<uint8_t> l_1st_read; + std::vector<uint8_t> l_2nd_read; + + FAPI_INF("Entering p9_mmiotest_double_read_pass..."); + + const size_t l_mmioTransactionSize = 4; + l_1st_read.resize(4); + + FAPI_INF("Do first getMMIO on an ocmb target"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, + l_mmioTransactionSize, + l_1st_read) ); + + // Initialize to some bad data + l_2nd_read.push_back('T'); + l_2nd_read.push_back('e'); + l_2nd_read.push_back('s'); + l_2nd_read.push_back('t'); + + FAPI_INF("Do second getMMIO on an ocmb target"); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, + l_mmioTransactionSize, + l_2nd_read) ); + + // read data should match + if (l_2nd_read != l_1st_read) + { + TS_FAIL("1st read data (%d) does NOT match 2nd read data (%d)", + l_1st_read.size(), l_2nd_read.size()); + TRACFBIN(g_fapiTd, "1st data", l_1st_read.data(), l_1st_read.size()); + TRACFBIN(g_fapiTd, "2nd data", l_2nd_read.data(), l_2nd_read.size()); + } + + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_double_read_pass..."); + + return fapi2::current_err; +} + + +fapi2::ReturnCode p9_mmiotest_putmmio_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + FAPI_INF("Entering p9_mmiotest_putmmio_pass..."); + + std::vector<uint8_t> l_mmiodata; + l_mmiodata.push_back('P'); + l_mmiodata.push_back('U'); + l_mmiodata.push_back('T'); + l_mmiodata.push_back('M'); + l_mmiodata.push_back('M'); + l_mmiodata.push_back('I'); + l_mmiodata.push_back('O'); + l_mmiodata.push_back('-'); + l_mmiodata.push_back('P'); + l_mmiodata.push_back('A'); + l_mmiodata.push_back('S'); + l_mmiodata.push_back('S'); + + FAPI_INF("Do putMMIO on OCMB target"); + FAPI_TRY(fapi2::putMMIO(i_target, + 0x1000, + 4, + l_mmiodata)); + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_putmmio_pass..."); + + return fapi2::current_err; +} + + +fapi2::ReturnCode p9_mmiotest_write_read_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + FAPI_INF("Entering p9_mmiotest_write_read_pass..."); + + const size_t l_mmioTransactionSize = 4; + std::vector<uint8_t> l_mmio_data; + std::vector<uint8_t> l_read_mmio_data; + + const uint8_t l_data[] = {'p','9','_','m', 'm','i','o','t', + 'e','s','t','_', 'w','r','i','t', + 'e','_','r','e', 'a','d','_','p', + 'a','s','s','!'}; + const size_t l_data_size = sizeof(l_data); + l_mmio_data.insert( l_mmio_data.end(), &l_data[0], &l_data[l_data_size] ); + + // Write out a known value (name of this test) + FAPI_INF("Calling putMMIO on the target (size: %d)", l_data_size); + FAPI_TRY(fapi2::putMMIO(i_target, 0x1000, + l_mmioTransactionSize, l_mmio_data)); + + // now read it out and verify it was written correctly + FAPI_INF("Now read the just written data"); + l_read_mmio_data.resize(l_data_size); + FAPI_TRY(fapi2::getMMIO(i_target, + 0x1000, + l_mmioTransactionSize, + l_read_mmio_data)); + + if (l_mmio_data == l_read_mmio_data) + { + FAPI_INF("Data found matches what was written"); + } + else + { + TS_FAIL( "Data found (%d) does NOT match written values (%d)", + l_read_mmio_data.size(), l_mmio_data.size() ); + TRACFBIN(g_fapiTd, "getMMIO returned", + l_read_mmio_data.data(), l_read_mmio_data.size()); + TRACFBIN(g_fapiTd, "putMMIO wrote", l_mmio_data.data(), + l_mmio_data.size()); + } + + fapi_try_exit: + + FAPI_INF("Exiting p9_mmiotest_write_read_pass..."); + + return fapi2::current_err; +} diff --git a/src/usr/fapi2/test/p9_mmiotests.H b/src/usr/fapi2/test/p9_mmiotests.H new file mode 100644 index 000000000..bfcaebf33 --- /dev/null +++ b/src/usr/fapi2/test/p9_mmiotests.H @@ -0,0 +1,71 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/p9_mmiotests.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +//------------------------------------------------------------------------------ +/// @file p9_mmiotests.C +/// +/// @brief These procedures test the fapi2 mmio_access interfaces. +//------------------------------------------------------------------------------ +#ifndef _P9_MMIOTESTS_H_ +#define _P9_MMIOTESTS_H_ + +#include <fapi2.H> + +//----------------------------------------------------------------------- +// FAILURE TESTCASES +//----------------------------------------------------------------------- +// Unsupported target +fapi2::ReturnCode p9_mmiotest_getmmio_invalid_target( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + +fapi2::ReturnCode p9_mmiotest_putmmio_invalid_target( + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + +// Expected size cannot be broken evenly into section sizes +fapi2::ReturnCode p9_mmiotest_indivisible_by_section_size( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +// Try unsupported section size +fapi2::ReturnCode p9_mmiotest_invalid_section_size( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +//----------------------------------------------------------------------- +// GOOD-CASE TESTCASES +//----------------------------------------------------------------------- +// Simple getMMIO, try with two get sizes +fapi2::ReturnCode p9_mmiotest_getmmio_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +// Simple putMMIO, try with two put sizes +fapi2::ReturnCode p9_mmiotest_putmmio_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +// Verify same read of the same thing twice matches +fapi2::ReturnCode p9_mmiotest_double_read_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +// Verify we read exactly what we wrote +fapi2::ReturnCode p9_mmiotest_write_read_pass( + fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); +#endif |