summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Derksen <mderkse1@us.ibm.com>2018-09-12 10:54:15 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-11-09 13:27:20 -0600
commit1e1b50096bb42d57f06af3016cd1e7c6977d0021 (patch)
tree349d0c3199a2010686b1b9c6f056668a61031a19
parent8351efdb3b65ed4fc5472e78efd5db315663e42f (diff)
downloadtalos-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.H90
-rw-r--r--src/include/usr/fapi2/plat_mmio_access.H77
-rwxr-xr-xsrc/usr/fapi2/fapi2.mk2
-rw-r--r--src/usr/fapi2/plat_mmio_access.C208
-rw-r--r--src/usr/fapi2/test/fapi2MmioAccessTest.H221
-rw-r--r--src/usr/fapi2/test/fapi2Test.mk2
-rw-r--r--src/usr/fapi2/test/p9_mmiotests.C299
-rw-r--r--src/usr/fapi2/test/p9_mmiotests.H71
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
OpenPOWER on IntegriCloud