summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/ibscom/ibscomif.H46
-rw-r--r--src/include/usr/scom/scomif.H20
-rw-r--r--src/include/usr/scom/scomreasoncodes.H3
-rw-r--r--src/makefile1
-rw-r--r--src/usr/ibscom/ibscom.C221
-rw-r--r--src/usr/ibscom/ibscom.mk27
-rw-r--r--src/usr/ibscom/ibscom_multicast.C149
-rw-r--r--src/usr/ibscom/makefile8
-rw-r--r--src/usr/ibscom/runtime/makefile38
-rw-r--r--src/usr/ibscom/runtime/rt_ibscom.C114
-rw-r--r--src/usr/scom/preopchecks.C150
-rw-r--r--src/usr/scom/scom.mk1
-rw-r--r--src/usr/xscom/runtime/rt_xscom.C101
-rw-r--r--src/usr/xscom/xscom.C83
14 files changed, 578 insertions, 384 deletions
diff --git a/src/include/usr/ibscom/ibscomif.H b/src/include/usr/ibscom/ibscomif.H
index f539caf90..41e9f0cdd 100644
--- a/src/include/usr/ibscom/ibscomif.H
+++ b/src/include/usr/ibscom/ibscomif.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,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. */
@@ -26,6 +28,7 @@
#include <stdint.h>
#include <builtins.h>
#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
namespace IBSCOM
{
@@ -40,6 +43,45 @@ namespace IBSCOM
*/
void enableInbandScoms( bool i_disable = IBSCOM_ENABLE );
-}
+/**
+ * @brief Multicast this ibscom address
+ *
+ * @param[in] i_opType read/write
+ * @param[in] i_target target membuf
+ * @param[inout] io_buffer return data
+ * @param[inout] io_buflen return data length
+ * @param[in] i_addr inband scom address
+ * @param[out] o_didWorkaround return indicator
+ *
+ * @return error log on fail
+ */
+errlHndl_t doIBScomMulticast( DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ uint64_t i_addr,
+ bool& o_didWorkaround );
+
+#ifndef __HOSTBOOT_RUNTIME
+/**
+ * @brief Perform ibscom
+ *
+ * @param[in] i_opType read/write
+ * @param[in] i_target target membuf
+ * @param[inout] io_buffer return data
+ * @param[inout] io_buflen return data length
+ * @param[in] i_addr inband scom address
+ * @param[in] i_errDataPath generate SUE error
+ *
+ * @return error log on fail
+ */
+errlHndl_t doIBScom(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ uint64_t i_addr,
+ bool i_errDataPath);
+#endif
+} // end namespace IBSCOM
#endif
diff --git a/src/include/usr/scom/scomif.H b/src/include/usr/scom/scomif.H
index da7227735..d86bd6358 100644
--- a/src/include/usr/scom/scomif.H
+++ b/src/include/usr/scom/scomif.H
@@ -25,6 +25,8 @@
#ifndef __SCOMIF_H
#define __SCOMIF_H
+#include <devicefw/driverif.H>
+
namespace SCOM
{
@@ -43,6 +45,24 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target,
bool & o_needsWakeup,
uint64_t i_opMode = 0);
+/**
+ * @brief Common routine that verifies input parameters for *scom accesses.
+ *
+ * @param[in] i_opType Operation type, see driverif.H
+ * @param[in] i_target Scom target
+ * @param[in] i_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in] i_buflen Input: size of io_buffer (in bytes)
+ * @param[in] i_addr Address being accessed (Used for FFDC)
+ * @return errlHndl_t
+ */
+errlHndl_t scomOpSanityCheck(const DeviceFW::OperationType i_opType,
+ const TARGETING::Target* i_target,
+ const void* i_buffer,
+ const size_t i_buflen,
+ const uint64_t i_addr,
+ const size_t i_minbufsize);
+
#ifndef __HOSTBOOT_RUNTIME
/**
* @brief Enable scoms to all cores for multicast workaround
diff --git a/src/include/usr/scom/scomreasoncodes.H b/src/include/usr/scom/scomreasoncodes.H
index b6fb9816b..c4db021c8 100644
--- a/src/include/usr/scom/scomreasoncodes.H
+++ b/src/include/usr/scom/scomreasoncodes.H
@@ -41,6 +41,7 @@ namespace SCOM
SCOM_HANDLE_SPECIAL_WAKEUP = 0x07,
SCOM_TRANSLATE_CENTAUR = 0x08,
SCOM_RT_SEND_SCOM_TO_HYP = 0x09,
+ SCOM_OP_SANITY_CHECK = 0x0A,
};
enum scomReasonCode
@@ -66,6 +67,8 @@ namespace SCOM
SCOM_SPCWKUP_COUNT_ERR = SCOM_COMP_ID | 0x13,
SCOM_CEN_TRANS_INVALID_TYPE = SCOM_COMP_ID | 0x14,
SCOM_RUNTIME_HYP_ERR = SCOM_COMP_ID | 0x15,
+ SCOM_INVALID_DATA_BUFFER = SCOM_COMP_ID | 0x16,
+ SCOM_INVALID_OP_TYPE = SCOM_COMP_ID | 0x17,
};
enum UserDetailsTypes
diff --git a/src/makefile b/src/makefile
index 4a718dd6f..83fe2511c 100644
--- a/src/makefile
+++ b/src/makefile
@@ -275,6 +275,7 @@ RUNTIME_MODULES += targeting_rt
RUNTIME_MODULES += util_rt
RUNTIME_MODULES += devicefw_rt
RUNTIME_MODULES += xscom_rt
+RUNTIME_MODULES += ibscom_rt
RUNTIME_MODULES += scom_rt
RUNTIME_MODULES += vpd_rt
RUNTIME_MODULES += i2c_rt
diff --git a/src/usr/ibscom/ibscom.C b/src/usr/ibscom/ibscom.C
index 8d0671072..fd1918e34 100644
--- a/src/usr/ibscom/ibscom.C
+++ b/src/usr/ibscom/ibscom.C
@@ -45,6 +45,7 @@
#include <errl/errludtarget.H>
#include <xscom/piberror.H>
#include <diag/attn/attn.H>
+#include <scom/scomif.H>
#include <ibscom/ibscomif.H>
#include <targeting/common/utilFilter.H>
#include <arch/memorymap.H>
@@ -74,112 +75,6 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
TYPE_MEMBUF,
ibscomPerformOp);
-/**
- * @brief Internal routine that verifies the validity of input parameters
- * for an inband scom access.
- *
- * @param[in] i_opType Operation type, see DeviceFW::OperationType
- * in driverif.H
- * @param[in] i_target inband scom target
- * @param[in] i_buffer Read: Pointer to output data storage
- * Write: Pointer to input data storage
- * @param[in] i_buflen Input: size of io_buffer (in bytes)
- * @param[in] i_addr Address being accessed (Used for FFDC)
- * @return errlHndl_t
- */
-errlHndl_t ibscomOpSanityCheck(const DeviceFW::OperationType i_opType,
- const Target* i_target,
- const void* i_buffer,
- const size_t& i_buflen,
- const uint64_t i_addr)
-{
- errlHndl_t l_err = NULL;
- TRACDCOMP(g_trac_ibscom, INFO_MRK
- ">>ibscomOpSanityCheck: Entering Function");
-
- do
- {
- // Verify address is somewhat valid (not over 32-bits long)
- if(0 != (i_addr & 0xFFFFFFFF00000000))
- {
- TRACFCOMP(g_trac_ibscom, ERR_MRK"ibscomOpSanityCheck: Impossible address. i_addr=0x%.16X",
- i_buflen);
- /*@
- * @errortype
- * @moduleid IBSCOM_SANITY_CHECK
- * @reasoncode IBSCOM_INVALID_ADDRESS
- * @userdata1 Inband Scom address
- * @userdata2 <none>
- * @devdesc The provided address is over 32 bits long
- * which makes it invalid.
- */
- l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- IBSCOM_SANITY_CHECK,
- IBSCOM_INVALID_ADDRESS,
- i_addr,
- 0);
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
- break;
- }
-
- // Verify data buffer
- if ( (i_buflen < IBSCOM_BUFFER_SIZE) ||
- (i_buffer == NULL) )
- {
- TRACFCOMP(g_trac_ibscom, ERR_MRK
- "ibscomOpSanityCheck: Invalid buffer. i_buflen=0x%X",
- i_buflen);
- /*@
- * @errortype
- * @moduleid IBSCOM_SANITY_CHECK
- * @reasoncode IBSCOM_INVALID_DATA_BUFFER
- * @userdata1 Buffer size
- * @userdata2 Inband Scom address
- * @devdesc Inband buffer size < 8 bytes or NULL
- * data buffer
- */
- l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- IBSCOM_SANITY_CHECK,
- IBSCOM_INVALID_DATA_BUFFER,
- i_buflen,
- i_addr);
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
- break;
- }
-
- // Verify OP type
- if ( (i_opType != DeviceFW::READ) &&
- (i_opType != DeviceFW::WRITE) )
- {
- TRACFCOMP(g_trac_ibscom, ERR_MRK
- "ibscomOpSanityCheck: Invalid opType. i_opType=0x%X",
- i_opType);
- /*@
- * @errortype
- * @moduleid IBSCOM_SANITY_CHECK
- * @reasoncode IBSCOM_INVALID_OP_TYPE
- * @userdata1 Operation type
- * @userdata2 inband scom address
- * @devdesc inband scom invalid operation type
- */
- l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- IBSCOM_SANITY_CHECK,
- IBSCOM_INVALID_OP_TYPE,
- i_opType,
- i_addr);
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
- break;
- }
-
-
- } while(0);
-
- return l_err;
-}
-
/**
* @brief Return the parent DMI target for the input membuf target
@@ -520,10 +415,12 @@ errlHndl_t doIBScom(DeviceFW::OperationType i_opType,
i_addr);
// inband scom operation sanity check
- l_err = ibscomOpSanityCheck(i_opType, i_target, io_buffer,
- io_buflen, i_addr);
+ l_err = SCOM::scomOpSanityCheck(i_opType, i_target, io_buffer,
+ io_buflen, i_addr, IBSCOM_BUFFER_SIZE);
if (l_err)
{
+ // Trace here - sanity check does not know scom type
+ TRACFCOMP(g_trac_ibscom,"IBScom sanity check failed");
break;
}
// Set to buffer len to 0 until successfully access
@@ -955,114 +852,6 @@ errlHndl_t doIBScom(DeviceFW::OperationType i_opType,
return l_err;
}
-/**
- * @brief Multicast this ibscom address
- *
- * @param[in] i_opType read/write
- * @param[in] i_target target membuf
- * @param[inout] io_buffer return data
- * @param[inout] io_buflen return data length
- * @param[in] i_addr inband scom address
- * @param[out] o_didWorkaround return indicator
- *
- * @return error log on fail
- */
-errlHndl_t doIBScomMulticast( DeviceFW::OperationType i_opType,
- Target* i_target,
- void* io_buffer,
- size_t& io_buflen,
- uint64_t i_addr,
- bool& o_didWorkaround )
-{
- errlHndl_t l_err = nullptr;
- uint64_t* l_summaryReg = reinterpret_cast<uint64_t*>(io_buffer);
-
- // Chiplet byte info masks
- constexpr uint64_t IS_MULTICAST = 0x40000000;
- constexpr uint64_t MULTICAST_GROUP = 0x07000000;
- constexpr uint64_t MULTICAST_OP = 0x38000000;
- constexpr uint64_t MULTICAST_OP_BITWISE = 0x10000000;
- constexpr uint64_t CHIPLET_BYTE = 0xFF000000;
-
- // Valid groups
- constexpr uint64_t GROUP_0 = 0x00000000;
- constexpr uint64_t GROUP_3 = 0x03000000;
-
- uint64_t l_group = MULTICAST_GROUP & i_addr;
-
- // Only perform this workaround for:
- // - reads
- // - multicast registers
- // - multicast read option 'bit-wise'
- // - multicast group 0 or 3
- if( !((DeviceFW::READ == i_opType)
- && ((IS_MULTICAST & i_addr) == IS_MULTICAST)
- && ((MULTICAST_OP & i_addr) == MULTICAST_OP_BITWISE)
- && ((GROUP_0 == l_group) || (GROUP_3 == l_group)) ) )
- {
- o_didWorkaround = false;
- return nullptr;
- }
-
- TRACFCOMP( g_trac_ibscom, "doIBScomMulticast on %.8X for %.8X", TARGETING::get_huid(i_target), i_addr );
-
- // Chiplet numbers
- constexpr uint64_t CHIPLET_PRV = 1;
- constexpr uint64_t CHIPLET_NST = 2;
- constexpr uint64_t CHIPLET_MEM = 3;
-
- // Start chiplet depends on group, end chiplet is always MEM
- // - Multicast group 0: PRV NST MEM, chiplets 1 2 3
- // - Multicast group 3: NST MEM, chiplets 2 3
- uint64_t l_start_chplt = 0;
- uint64_t l_end_chplt = CHIPLET_MEM;
- if( GROUP_0 == l_group )
- {
- l_start_chplt = CHIPLET_PRV;
- }
- else // Must be group 3
- {
- l_start_chplt = CHIPLET_NST;
- }
-
- // Do the ibscom for each chiplet and return the combined value
- for( uint64_t l_chplt = l_start_chplt; l_chplt <= l_end_chplt; l_chplt++ )
- {
- // Remove the chiplet byte info from the address
- uint64_t l_addr = (i_addr & ~CHIPLET_BYTE);
- uint64_t l_data = 0;
-
- // Add the chiplet to the address
- l_addr |= (l_chplt << 24);
- io_buflen = sizeof(uint64_t);
-
- l_err = doIBScom(i_opType,
- i_target,
- &l_data,
- io_buflen,
- l_addr,
- false);
- if( l_err )
- {
- break;
- }
- // If any bits are set, set this unit's bit in summary reg
- // note: just check the first bit,
- // this is good enough for the use-case we have now
- // but a better implementation would be to actually
- // check the select regs as well so we know which bit(s)
- // are the trigger
- if( l_data & 0x8000000000000000 )
- {
- *l_summaryReg |= (0x8000000000000000 >> l_chplt);
- }
-
- }
-
- o_didWorkaround = true;
-
- return l_err;
-}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/usr/ibscom/ibscom.mk b/src/usr/ibscom/ibscom.mk
new file mode 100644
index 000000000..ac8802ca7
--- /dev/null
+++ b/src/usr/ibscom/ibscom.mk
@@ -0,0 +1,27 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/ibscom/ibscom.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2012,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
+
+OBJS += ibscom_multicast.o
+
diff --git a/src/usr/ibscom/ibscom_multicast.C b/src/usr/ibscom/ibscom_multicast.C
new file mode 100644
index 000000000..fb2513d12
--- /dev/null
+++ b/src/usr/ibscom/ibscom_multicast.C
@@ -0,0 +1,149 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/ibscom/ibscom_multicast.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,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 */
+#include <ibscom/ibscomif.H>
+#include <trace/interface.H>
+#include <errl/errlmanager.H>
+#include <scom/runtime/rt_scomif.H>
+
+// Trace definition
+extern trace_desc_t* g_trac_ibscom;
+
+namespace IBSCOM
+{
+
+/**
+ * @brief Multicast this ibscom address
+ *
+ * @param[in] i_opType read/write
+ * @param[in] i_target target membuf
+ * @param[inout] io_buffer return data
+ * @param[inout] io_buflen return data length
+ * @param[in] i_addr inband scom address
+ * @param[out] o_didWorkaround return indicator
+ *
+ * @return error log on fail
+ */
+errlHndl_t doIBScomMulticast( DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ uint64_t i_addr,
+ bool& o_didWorkaround )
+{
+ errlHndl_t l_err = nullptr;
+ uint64_t* l_summaryReg = reinterpret_cast<uint64_t*>(io_buffer);
+
+ // Chiplet byte info masks
+ constexpr uint64_t IS_MULTICAST = 0x40000000;
+ constexpr uint64_t MULTICAST_GROUP = 0x07000000;
+ constexpr uint64_t MULTICAST_OP = 0x38000000;
+ constexpr uint64_t MULTICAST_OP_BITWISE = 0x10000000;
+ constexpr uint64_t CHIPLET_BYTE = 0xFF000000;
+
+ // Valid groups
+ constexpr uint64_t GROUP_0 = 0x00000000;
+ constexpr uint64_t GROUP_3 = 0x03000000;
+
+ uint64_t l_group = MULTICAST_GROUP & i_addr;
+
+ // Only perform this workaround for:
+ // - reads
+ // - multicast registers
+ // - multicast read option 'bit-wise'
+ // - multicast group 0 or 3
+ if( !((DeviceFW::READ == i_opType)
+ && ((IS_MULTICAST & i_addr) == IS_MULTICAST)
+ && ((MULTICAST_OP & i_addr) == MULTICAST_OP_BITWISE)
+ && ((GROUP_0 == l_group) || (GROUP_3 == l_group)) ) )
+ {
+ o_didWorkaround = false;
+ return nullptr;
+ }
+
+ TRACFCOMP( g_trac_ibscom, "doIBScomMulticast on %.8X for %.8X", TARGETING::get_huid(i_target), i_addr );
+
+ // Chiplet numbers
+ constexpr uint64_t CHIPLET_PRV = 1;
+ constexpr uint64_t CHIPLET_NST = 2;
+ constexpr uint64_t CHIPLET_MEM = 3;
+
+ // Start chiplet depends on group, end chiplet is always MEM
+ // - Multicast group 0: PRV NST MEM, chiplets 1 2 3
+ // - Multicast group 3: NST MEM, chiplets 2 3
+ uint64_t l_start_chplt = 0;
+ uint64_t l_end_chplt = CHIPLET_MEM;
+ if( GROUP_0 == l_group )
+ {
+ l_start_chplt = CHIPLET_PRV;
+ }
+ else // Must be group 3
+ {
+ l_start_chplt = CHIPLET_NST;
+ }
+
+ // Do the ibscom for each chiplet and return the combined value
+ for( uint64_t l_chplt = l_start_chplt; l_chplt <= l_end_chplt; l_chplt++ )
+ {
+ // Remove the chiplet byte info from the address
+ uint64_t l_addr = (i_addr & ~CHIPLET_BYTE);
+ uint64_t l_data = 0;
+
+ // Add the chiplet to the address
+ l_addr |= (l_chplt << 24);
+ io_buflen = sizeof(uint64_t);
+
+#ifdef __HOSTBOOT_RUNTIME
+ l_err = SCOM::sendScomToHyp(i_opType, i_target, l_addr, &l_data);
+#else
+ l_err = doIBScom(i_opType,
+ i_target,
+ &l_data,
+ io_buflen,
+ l_addr,
+ false);
+#endif
+ if( l_err )
+ {
+ break;
+ }
+ // If any bits are set, set this unit's bit in summary reg
+ // note: just check the first bit,
+ // this is good enough for the use-case we have now
+ // but a better implementation would be to actually
+ // check the select regs as well so we know which bit(s)
+ // are the trigger
+ if( l_data & 0x8000000000000000 )
+ {
+ *l_summaryReg |= (0x8000000000000000 >> l_chplt);
+ }
+
+ }
+
+ o_didWorkaround = true;
+
+ return l_err;
+}
+
+} // end namespace IBSCOM
diff --git a/src/usr/ibscom/makefile b/src/usr/ibscom/makefile
index 8e34154e0..69403562f 100644
--- a/src/usr/ibscom/makefile
+++ b/src/usr/ibscom/makefile
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2012,2014
+# Contributors Listed Below - COPYRIGHT 2012,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.
@@ -23,8 +25,12 @@
ROOTPATH = ../../..
MODULE = ibscom
+#include common ojects between hostboot and runtime hostboot
+include ibscom.mk
+
OBJS += ibscom.o
SUBDIRS += test.d
+SUBDIRS += runtime.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/ibscom/runtime/makefile b/src/usr/ibscom/runtime/makefile
new file mode 100644
index 000000000..ba45c1b5e
--- /dev/null
+++ b/src/usr/ibscom/runtime/makefile
@@ -0,0 +1,38 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/ibscom/runtime/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2013,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
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = ibscom_rt
+
+#include common ojects between hostboot and runtime hostboot
+include ../ibscom.mk
+
+#include unique object modules
+OBJS += rt_ibscom.o
+
+#SUBDIRS += test.d
+
+VPATH += ..
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/ibscom/runtime/rt_ibscom.C b/src/usr/ibscom/runtime/rt_ibscom.C
new file mode 100644
index 000000000..d731f1acc
--- /dev/null
+++ b/src/usr/ibscom/runtime/rt_ibscom.C
@@ -0,0 +1,114 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/ibscom/runtime/rt_ibscom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,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 */
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <ibscom/ibscomreasoncodes.H>
+#include "../ibscom.H"
+#include <scom/scomif.H>
+#include <scom/runtime/rt_scomif.H>
+#include <ibscom/ibscomif.H>
+
+// Trace definition
+trace_desc_t* g_trac_ibscom = NULL;
+TRAC_INIT(&g_trac_ibscom, "IBSCOM", 2*KILOBYTE, TRACE::BUFFER_SLOW);
+
+namespace IBSCOM
+{
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::IBSCOM,
+ TARGETING::TYPE_MEMBUF,
+ ibscomPerformOp);
+
+
+/**
+ * @brief Complete the ibscom op
+ *
+ * @param[in] i_opType Operation type, see driverif.H
+ * @param[in] i_target IBSCom target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes)
+ * Output: Read: Size of output data
+ * Write: Size of data written
+ * @param[in] i_accessType Access type
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there's only one argument,
+ * which is the MMIO IBSCom address
+ * @return errlHndl_t
+ */
+errlHndl_t ibscomPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ TRACDCOMP(g_trac_ibscom,ENTER_MRK"ibscomPerformOp");
+ errlHndl_t l_err = NULL;
+ uint64_t l_addr = va_arg(i_args,uint64_t);
+
+ do
+ {
+ l_err = SCOM::scomOpSanityCheck(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ l_addr,
+ IBSCOM_BUFFER_SIZE);
+ if( l_err )
+ {
+ // Trace here - sanity check does not know scom type
+ TRACFCOMP(g_trac_ibscom,"Runtime IBScom sanity check failed");
+ break;
+ }
+
+ // Multicast is not handled correctly by inband scom
+ // Call workaround to complete manually
+ bool l_didWorkaround = false;
+ l_err = doIBScomMulticast(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ l_addr,
+ l_didWorkaround);
+ if( l_err || l_didWorkaround )
+ {
+ break;
+ }
+
+ l_err = SCOM::sendScomToHyp(i_opType, i_target, l_addr, io_buffer);
+
+ } while(0);
+
+ TRACDCOMP(g_trac_ibscom,EXIT_MRK"ibscomPerformOp");
+
+ return l_err;
+}
+
+}; // end namespace IBSCOM
+
diff --git a/src/usr/scom/preopchecks.C b/src/usr/scom/preopchecks.C
new file mode 100644
index 000000000..f5bc9f4a5
--- /dev/null
+++ b/src/usr/scom/preopchecks.C
@@ -0,0 +1,150 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/scom/preopchecks.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,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 */
+#include <devicefw/driverif.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <scom/scomreasoncodes.H>
+#include <scom/scomif.H>
+
+// Trace definition
+extern trace_desc_t* g_trac_scom;
+
+namespace SCOM
+{
+
+/**
+ * @brief Common routine that verifies input parameters for *scom accesses.
+ *
+ * @param[in] i_opType Operation type, see driverif.H
+ * @param[in] i_target Scom target
+ * @param[in] i_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in] i_buflen Input: size of io_buffer (in bytes)
+ * @param[in] i_addr Address being accessed (Used for FFDC)
+ * @return errlHndl_t
+ */
+errlHndl_t scomOpSanityCheck(const DeviceFW::OperationType i_opType,
+ const TARGETING::Target* i_target,
+ const void* i_buffer,
+ const size_t i_buflen,
+ const uint64_t i_addr,
+ const size_t i_minbufsize)
+{
+ errlHndl_t l_err = NULL;
+ TRACDCOMP(g_trac_scom, INFO_MRK
+ ">>scomOpSanityCheck: Entering Function");
+
+ do
+ {
+ // Verify address is not over 32-bits long
+ if(0 != (i_addr & 0xFFFFFFFF00000000))
+ {
+ TRACFCOMP(g_trac_scom, ERR_MRK
+ "scomOpSanityCheck: Impossible address. i_addr=0x%.16X",
+ i_addr);
+
+ /*@
+ * @errortype
+ * @moduleid SCOM_OP_SANITY_CHECK
+ * @reasoncode SCOM_INVALID_ADDR
+ * @userdata1 Scom address
+ * @userdata2 Scom target
+ * @devdesc The provided address is over 32 bits long
+ * which makes it invalid.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_OP_SANITY_CHECK,
+ SCOM_INVALID_ADDR,
+ i_addr,
+ get_huid(i_target));
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ break;
+ }
+
+ // Verify data buffer
+ if ( (i_buflen < i_minbufsize) ||
+ (i_buffer == NULL) )
+ {
+ TRACFCOMP(g_trac_scom, ERR_MRK
+ "scomOpSanityCheck: Invalid buffer. i_buflen=0x%X",
+ i_buflen);
+ /*@
+ * @errortype
+ * @moduleid SCOM_OP_SANITY_CHECK
+ * @reasoncode SCOM_INVALID_DATA_BUFFER
+ * @userdata1[0:31] Buffer size
+ * @userdata1[32:63] Minimum allowed buffer size
+ * @userdata2 Scom address
+ * @devdesc Buffer size is less than allowed
+ * or NULL data buffer
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_OP_SANITY_CHECK,
+ SCOM_INVALID_DATA_BUFFER,
+ TWO_UINT32_TO_UINT64(
+ i_buflen,
+ i_minbufsize),
+ i_addr);
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ break;
+ }
+
+ // Verify OP type
+ if ( (i_opType != DeviceFW::READ) &&
+ (i_opType != DeviceFW::WRITE) )
+ {
+ TRACFCOMP(g_trac_scom, ERR_MRK
+ "scomOpSanityCheck: Invalid opType. i_opType=0x%X",
+ i_opType);
+ /*@
+ * @errortype
+ * @moduleid SCOM_OP_SANITY_CHECK
+ * @reasoncode SCOM_INVALID_OP_TYPE
+ * @userdata1 Operation type
+ * @userdata2 Scom address
+ * @devdesc Scom invalid operation type
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SCOM_OP_SANITY_CHECK,
+ SCOM_INVALID_OP_TYPE,
+ i_opType,
+ i_addr);
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ break;
+ }
+
+
+ } while(0);
+
+ return l_err;
+}
+
+} // end namespace SCOM
diff --git a/src/usr/scom/scom.mk b/src/usr/scom/scom.mk
index 890b106d7..d382b6176 100644
--- a/src/usr/scom/scom.mk
+++ b/src/usr/scom/scom.mk
@@ -42,6 +42,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
OBJS += scom.o
OBJS += scomtrans.o
OBJS += errlud_pib.o
+OBJS += preopchecks.o
OBJS += postopchecks.o
OBJS += DmiScomWorkaround.o
OBJS += ibscom_retry.o
diff --git a/src/usr/xscom/runtime/rt_xscom.C b/src/usr/xscom/runtime/rt_xscom.C
index 93e011864..cf7d40052 100644
--- a/src/usr/xscom/runtime/rt_xscom.C
+++ b/src/usr/xscom/runtime/rt_xscom.C
@@ -28,6 +28,7 @@
#include <errl/errlmanager.H>
#include <xscom/xscomreasoncodes.H>
#include "../xscom.H"
+#include <scom/scomif.H>
#include <scom/runtime/rt_scomif.H>
// Trace definition
@@ -42,7 +43,7 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
TARGETING::TYPE_PROC,
xscomPerformOp);
-// Direct all scom calls though this interface at runtime
+// Also direct fsi scom calls though this interface at runtime
DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
DeviceFW::FSISCOM,
TARGETING::TYPE_PROC,
@@ -53,86 +54,6 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
TARGETING::TYPE_MEMBUF,
xscomPerformOp);
-DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
- DeviceFW::IBSCOM,
- TARGETING::TYPE_MEMBUF,
- xscomPerformOp);
-
-/**
- * @brief Internal routine that verifies the validity of input parameters
- * for an XSCOM access.
- *
- * @param[in] i_opType Operation type, see DeviceFW::OperationType
- * in driverif.H
- * @param[in] i_target XSCom target
- * @param[in/out] i_buffer Read: Pointer to output data storage
- * Write: Pointer to input data storage
- * @param[in/out] i_buflen Input: size of io_buffer (in bytes)
- * Output:
- * Read: Size of output data
- * Write: Size of data written
- * @param[in] i_args This is an argument list for DD framework.
- * In this function, there's only one argument,
- * which is the MMIO XSCom address
- * @return errlHndl_t
- */
-errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType,
- const TARGETING::Target* i_target,
- const void* i_buffer,
- const size_t& i_buflen,
- const va_list i_args){
- errlHndl_t l_err = NULL;
-
- do
- {
- // Verify data buffer
- if ( (i_buflen < XSCOM_BUFFER_SIZE) ||
- (i_buffer == NULL) )
- {
- /*@
- * @errortype
- * @moduleid XSCOM_RT_SANITY_CHECK
- * @reasoncode XSCOM_INVALID_DATA_BUFFER
- * @userdata1 Buffer size
- * @userdata2 XSCom address
- * @devdesc XSCOM buffer size < 8 bytes or NULL data buff
- */
- l_err =
- new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- XSCOM_RT_SANITY_CHECK,
- XSCOM_INVALID_DATA_BUFFER,
- i_buflen,
- va_arg(i_args,uint64_t));
- break;
- }
-
- // Verify OP type
- if ( (i_opType != DeviceFW::READ) &&
- (i_opType != DeviceFW::WRITE) )
- {
- /*@
- * @errortype
- * @moduleid XSCOM_RT_SANITY_CHECK
- * @reasoncode XSCOM_INVALID_OP_TYPE
- * @userdata1 Operation type
- * @userdata2 XSCom address
- * @devdesc XSCOM invalid operation type
- */
- l_err =
- new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- XSCOM_RT_SANITY_CHECK,
- XSCOM_INVALID_OP_TYPE,
- i_opType,
- va_arg(i_args,uint64_t));
- break;
- }
-
-
- } while(0);
-
- return l_err;
-}
-
/**
* @brief Complete the xscom op
@@ -161,13 +82,19 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
errlHndl_t l_err = NULL;
uint64_t l_addr = va_arg(i_args,uint64_t);
- l_err = xscomOpSanityCheck(i_opType,
- i_target,
- io_buffer,
- io_buflen,
- i_args);
+ l_err = SCOM::scomOpSanityCheck(i_opType,
+ i_target,
+ io_buffer,
+ io_buflen,
+ l_addr,
+ XSCOM_BUFFER_SIZE);
- if (!l_err)
+ if (l_err)
+ {
+ // Trace here - sanity check does not know scom type
+ TRACFCOMP(g_trac_xscom,"Runtime XScom sanity check failed");
+ }
+ else
{
l_err = SCOM::sendScomToHyp(i_opType, i_target, l_addr, io_buffer);
}
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C
index a28897f8b..18594d7cd 100644
--- a/src/usr/xscom/xscom.C
+++ b/src/usr/xscom/xscom.C
@@ -46,6 +46,7 @@
#include <assert.h>
#include <errl/errludlogregister.H>
#include <xscom/piberror.H>
+#include <scom/scomif.H>
#include <arch/pirformat.H>
#include <lpc/lpcif.H>
#include <sys/mm.h>
@@ -113,82 +114,6 @@ HMER waitForHMERStatus()
/**
- * @brief Internal routine that verifies the validity of input parameters
- * for an XSCOM access.
- *
- * @param[in] i_opType Operation type, see DeviceFW::OperationType
- * in driverif.H
- * @param[in] i_target XSCom target
- * @param[in/out] i_buffer Read: Pointer to output data storage
- * Write: Pointer to input data storage
- * @param[in/out] i_buflen Input: size of io_buffer (in bytes)
- * Output:
- * Read: Size of output data
- * Write: Size of data written
- * @param[in] i_args This is an argument list for DD framework.
- * In this function, there's only one argument,
- * which is the MMIO XSCom address
- * @return errlHndl_t
- */
-errlHndl_t xscomOpSanityCheck(const DeviceFW::OperationType i_opType,
- const TARGETING::Target* i_target,
- const void* i_buffer,
- const size_t& i_buflen,
- const va_list i_args)
-{
- errlHndl_t l_err = NULL;
-
- do
- {
- // Verify data buffer
- if ( (i_buflen < XSCOM_BUFFER_SIZE) ||
- (i_buffer == NULL) )
- {
- /*@
- * @errortype
- * @moduleid XSCOM_SANITY_CHECK
- * @reasoncode XSCOM_INVALID_DATA_BUFFER
- * @userdata1 Buffer size
- * @userdata2 XSCom address
- * @devdesc XSCOM buffer size < 8 bytes or NULL data buffer
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- XSCOM_SANITY_CHECK,
- XSCOM_INVALID_DATA_BUFFER,
- i_buflen,
- va_arg(i_args,uint64_t),
- true /*Add HB Software Callout*/);
- break;
- }
-
- // Verify OP type
- if ( (i_opType != DeviceFW::READ) &&
- (i_opType != DeviceFW::WRITE) )
- {
- /*@
- * @errortype
- * @moduleid XSCOM_SANITY_CHECK
- * @reasoncode XSCOM_INVALID_OP_TYPE
- * @userdata1 Operation type
- * @userdata2 XSCom address
- * @devdesc XSCOM invalid operation type
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- XSCOM_SANITY_CHECK,
- XSCOM_INVALID_OP_TYPE,
- i_opType,
- va_arg(i_args,uint64_t),
- true /*Add HB Software Callout*/);
- break;
- }
-
-
- } while(0);
-
- return l_err;
-}
-
-/**
* @brief Get the virtual address of the input target
* for an XSCOM access.
*
@@ -752,10 +677,12 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
do
{
// XSCOM operation sanity check
- l_err = xscomOpSanityCheck(i_opType, i_target, io_buffer,
- io_buflen, i_args);
+ l_err = SCOM::scomOpSanityCheck(i_opType, i_target, io_buffer,
+ io_buflen, l_addr, XSCOM_BUFFER_SIZE);
if (l_err)
{
+ // Trace here - sanity check does not know scom type
+ TRACFCOMP(g_trac_xscom,"XScom sanity check failed");
break;
}
OpenPOWER on IntegriCloud