summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Baiocchi <mbaiocch@us.ibm.com>2018-04-28 00:54:00 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2018-05-24 09:28:01 -0400
commit3ad299af08fd1ed6a14c72a9d3fe4b89a5af5eec (patch)
tree510aa6aaded8f7476e5f43e7c7531908c906d222
parent2383ff8f7e7617623873c39974fb3ce6f6bffc4c (diff)
downloadtalos-hostboot-3ad299af08fd1ed6a14c72a9d3fe4b89a5af5eec.tar.gz
talos-hostboot-3ad299af08fd1ed6a14c72a9d3fe4b89a5af5eec.zip
Establish Base Support For Sending Mailbox Messages Across XBUS/ABUS
This commit establishes base support for Secure Node Communications. It creates a new device driver to operate the XBUS and ABUS Link Mailboxes and adds base support for using these device drivers to send and receive messages. It also adds a test to perform a 2-chip XBUS Link Mailbox operation. Change-Id: I19510888c0922e5bb857cffc9426399e79e113ba RTC:191008 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/58376 Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: ILYA SMIRNOV <ismirno@us.ibm.com> Reviewed-by: Marshall J. Wilks <mjwilks@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: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
-rw-r--r--src/include/usr/devicefw/userif.H23
-rw-r--r--src/include/usr/isteps/istep09list.H1
-rw-r--r--src/include/usr/secureboot/nodecommif.H76
-rw-r--r--src/include/usr/secureboot/secure_reasoncodes.H16
-rw-r--r--src/makefile1
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H14
-rw-r--r--src/usr/isteps/istep09/call_proc_smp_link_layer.C24
-rw-r--r--src/usr/secureboot/makefile3
-rw-r--r--src/usr/secureboot/node_comm/makefile38
-rw-r--r--src/usr/secureboot/node_comm/node_comm.C200
-rw-r--r--src/usr/secureboot/node_comm/node_comm.H162
-rw-r--r--src/usr/secureboot/node_comm/node_comm_dd.C596
-rw-r--r--src/usr/secureboot/node_comm/node_comm_dd.H220
-rw-r--r--src/usr/secureboot/node_comm/node_comm_test.C296
14 files changed, 1666 insertions, 4 deletions
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index 286deabb1..4df37c8a8 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -68,6 +68,7 @@ namespace DeviceFW
AHB_SIO,
DVPD, // Direct access memory VPD
MEMD_VPD,
+ NODECOMM,
LAST_ACCESS_TYPE,
};
@@ -371,6 +372,26 @@ namespace DeviceFW
static_cast<uint64_t>(( i_gpio_portAddr ))
/**
+ * Construct the device addressing parameters for the Node Comm device ops.
+ * @param[in] i_mode Either ABUS or XBUS mode - see node_comm_modes_t
+ * enum defined in nodecommif.H.
+ * @param[in] i_link_id The Link Id used for routing the message.
+ * MAX values for ABUS and XBUS mode are defined in
+ * nodecommif.H.
+ * @param[in] i_mailbox_id Tha Mailbox Id used for routing the message.
+ * NOTE: Only "0" or "1" are supported.
+ *
+ * @note This interface only supports the reading and writing of
+ * 8 bytes (64 bits) per operation. Anything else will fail.
+ */
+ #define DEVICE_NODECOMM_ADDRESS( i_mode, i_link_id, i_mailbox_id ) \
+ DeviceFW::NODECOMM,\
+ static_cast<uint64_t>(( i_mode )),\
+ static_cast<uint64_t>(( i_link_id )),\
+ static_cast<uint64_t>(( i_mailbox_id ))
+
+
+ /**
* @brief Perform a hardware read operation.
*
* @param[in] i_target Device target to operate on.
diff --git a/src/include/usr/isteps/istep09list.H b/src/include/usr/isteps/istep09list.H
index 4adcc0810..6917499af 100644
--- a/src/include/usr/isteps/istep09list.H
+++ b/src/include/usr/isteps/istep09list.H
@@ -232,6 +232,7 @@ const DepModInfo g_istep09Dependancies = {
DEP_LIB(libnestmemutils.so),
DEP_LIB(libfab_iovalid.so),
DEP_LIB(libimageprocs.so),
+ DEP_LIB(libnode_comm.so),
NULL
}
};
diff --git a/src/include/usr/secureboot/nodecommif.H b/src/include/usr/secureboot/nodecommif.H
new file mode 100644
index 000000000..6787c99ea
--- /dev/null
+++ b/src/include/usr/secureboot/nodecommif.H
@@ -0,0 +1,76 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/nodecommif.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 __NODECOMMIF_H
+#define __NODECOMMIF_H
+
+#include <initservice/mboxRegs.H>
+#include <config.h>
+#include <errl/errlentry.H>
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+/*
+ * @brief The Node Communications Device Driver can *only* support ABUS or
+ * XBUS operations. This enum will be passed in by callers and it
+ * will be verified that only the XBUS or ABUS values were passed in.
+ */
+enum node_comm_modes_t
+{
+ NCDD_MODE_XBUS = 0,
+ NCDD_MODE_ABUS = 1,
+
+ // INVALID value and will be used for checks and asserts, like:
+ // assert(mode < NCDD_MODE_INVALID)
+ NCDD_MODE_INVALID = 2,
+};
+
+enum node_comm_link_mbox_info_t
+{
+ NCDD_MAX_ABUS_LINK_ID = 7,
+ NCDD_MAX_XBUS_LINK_ID = 5,
+ NCDD_MAX_MBOX_ID = 1,
+ NCDD_INVALID_LINK_MBOX = 0xFF,
+};
+
+/**
+ * @brief Execute a single transmission from one proc to another
+ * over the XBUS Link Mailbox facility
+ *
+ * @return errHndl_t Error log handle indicating success or failure
+ * @retval nullptr Test completed successfully
+ * @retval !nullptr Error log providing failure details
+ */
+errlHndl_t nodeCommXbus2ProcTest(void);
+
+} // End NODECOMM namespace
+
+} // End SECUREBOOT namespace
+
+#endif // End __NODECOMMIF_H
+
diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H
index 5dcb4bf5a..f692d4753 100644
--- a/src/include/usr/secureboot/secure_reasoncodes.H
+++ b/src/include/usr/secureboot/secure_reasoncodes.H
@@ -48,6 +48,13 @@ namespace SECUREBOOT
MOD_SECURE_GET_ALL_SEC_REGS = 0x0E,
MOD_SECURE_LOAD_HEADER = 0x0F,
MOD_SECURE_VALIDATE_ECID_COUNT = 0x10,
+
+ // Use 0x20-0x2F range for Node Communications
+ MOD_NCDD_CHECK_FOR_ERRORS = 0x20,
+ MOD_NCDD_WAIT_FOR_CMD_COMP = 0x21,
+ MOD_NC_XBUS_TEST = 0x22,
+ MOD_NC_MAP_ATTN = 0x23,
+ MOD_NCDD_PERFORM_OP = 0x24,
};
enum SECUREReasonCode
@@ -72,6 +79,15 @@ namespace SECUREBOOT
RC_DEVICE_READ_ERR = SECURE_COMP_ID | 0x11,
RC_INVALID_BASE_HEADER = SECURE_COMP_ID | 0x12,
RC_INVALID_ECID_COUNT = SECURE_COMP_ID | 0x13,
+
+ // Use 0x20-0x2F range for Node Communications
+ RC_NCDD_HW_ERROR_FOUND = SECURE_COMP_ID | 0x20,
+ RC_NCDD_CMD_COMP_TIMEOUT = SECURE_COMP_ID | 0x21,
+ RC_NC_DATA_MISCOMPARE = SECURE_COMP_ID | 0x22,
+ RC_NC_NO_ATTN_FOUND = SECURE_COMP_ID | 0x23,
+ RC_NC_TOO_MANY_ATTNS_FOUND = SECURE_COMP_ID | 0x24,
+ RC_NCDD_INVALID_ARGS = SECURE_COMP_ID | 0x25,
+
// Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H
};
diff --git a/src/makefile b/src/makefile
index e25729575..f2b570dcc 100644
--- a/src/makefile
+++ b/src/makefile
@@ -208,6 +208,7 @@ EXTENDED_MODULES += nestmemutils
EXTENDED_MODULES += fab_iovalid
EXTENDED_MODULES += isteps_nest
EXTENDED_MODULES += isteps_io
+EXTENDED_MODULES += node_comm
#***************************************
# Working test modules
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index 49c76400a..04798d791 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -368,6 +368,18 @@ const TaskInfo g_exttaskinfolist[] = {
#endif
/**
+ * @brief Node Communications Device Driver library
+ */
+ {
+ "libnode_comm.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ }
+ },
+
+ /**
* @brief Common istep functions
*
*
diff --git a/src/usr/isteps/istep09/call_proc_smp_link_layer.C b/src/usr/isteps/istep09/call_proc_smp_link_layer.C
index 07d970636..06b7ac613 100644
--- a/src/usr/isteps/istep09/call_proc_smp_link_layer.C
+++ b/src/usr/isteps/istep09/call_proc_smp_link_layer.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,6 +51,7 @@
#include <hwas/common/hwasCommon.H>
#include <sbe/sbeif.H>
+#include <secureboot/nodecommif.H>
// targeting support
#include <targeting/common/commontargeting.H>
@@ -80,10 +81,14 @@ void* call_proc_smp_link_layer( void *io_pArgs )
{
errlHndl_t l_errl = NULL;
IStepError l_StepError;
+ bool l_run_xbus_test = true;
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_smp_link_layer entry" );
+ do
+ {
+
//
// get a list of all the procs in the system
//
@@ -111,9 +116,26 @@ void* call_proc_smp_link_layer( void *io_pArgs )
TARGETING::get_huid(l_cpu_target) );
l_StepError.addErrorDetails(l_errl);
errlCommit(l_errl, HWPF_COMP_ID);
+ l_run_xbus_test = false;
}
}
+ // Test sending messages between procs via XBUS mailbox
+ if (l_run_xbus_test)
+ {
+ l_errl = SECUREBOOT::NODECOMM::nodeCommXbus2ProcTest();
+ if(l_errl)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
+ "call_proc_smp_link_layer> "
+ "nodeCommXbus2ProcTest Failed!");
+ l_StepError.addErrorDetails(l_errl);
+ errlCommit(l_errl, HWPF_COMP_ID);
+ }
+ }
+
+ } while(0);
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_proc_smp_link_layer exit" );
diff --git a/src/usr/secureboot/makefile b/src/usr/secureboot/makefile
index 5ac61aba7..c9a6a91b8 100644
--- a/src/usr/secureboot/makefile
+++ b/src/usr/secureboot/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2016
+# Contributors Listed Below - COPYRIGHT 2013,2018
# [+] International Business Machines Corp.
#
#
@@ -28,5 +28,6 @@ SUBDIRS += base.d
SUBDIRS += ext.d
SUBDIRS += trusted.d
SUBDIRS += runtime.d
+SUBDIRS += node_comm.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/secureboot/node_comm/makefile b/src/usr/secureboot/node_comm/makefile
new file mode 100644
index 000000000..d41851e71
--- /dev/null
+++ b/src/usr/secureboot/node_comm/makefile
@@ -0,0 +1,38 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/secureboot/node_comm/makefile $
+#
+# 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
+ROOTPATH = ../../../..
+MODULE = node_comm
+include ../common/common.mk
+#SUBDIRS += test.d
+
+OBJS += node_comm_dd.o
+OBJS += node_comm_test.o
+OBJS += node_comm.o
+
+VPATH += $(ROOTPATH)/src/usr/targeting/common
+EXTRAINCDIR += $(ROOTPATH)/src/include/usr
+
+CFLAGS += -iquote ../
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/secureboot/node_comm/node_comm.C b/src/usr/secureboot/node_comm/node_comm.C
new file mode 100644
index 000000000..b47f78273
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm.C
@@ -0,0 +1,200 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm.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 node_comm.C
+ *
+ * @brief Implementation of the Secure Node Communications Functions
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/userif.H>
+#include <devicefw/driverif.H>
+#include <secureboot/secure_reasoncodes.H>
+#include <secureboot/nodecommif.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+
+#include "node_comm.H"
+
+
+using namespace TARGETING;
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+/**
+ * @brief Map Attention Bits in FIR Register to specific Link Mailbox
+ */
+errlHndl_t nodeCommMapAttn(TARGETING::Target* i_pProc,
+ const node_comm_modes_t i_mode,
+ bool & o_attn_found,
+ uint64_t & o_linkId,
+ uint64_t & o_mboxId)
+{
+ errlHndl_t err = nullptr;
+ uint64_t fir_data = 0x0;
+ uint64_t fir_data_with_mask = 0x0;
+ o_attn_found = false;
+
+ assert(i_mode < NCDD_MODE_INVALID,"nodeCommMapAttn: Invalid mode: %d",
+ i_mode);
+
+ const uint64_t fir_mask = (i_mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_FIR_ATTN_MASK
+ : NCDD_XBUS_FIR_ATTN_MASK;
+
+ const uint64_t fir_addr = (i_mode == NCDD_MODE_ABUS)
+ ? NCDD_REG_FIR + NCDD_ABUS_REG_OFFSET
+ : NCDD_REG_FIR;
+
+ const size_t expSize = sizeof(fir_data);
+
+ TRACFCOMP(g_trac_nc,ENTER_MRK
+ "nodeCommMapAttn: tgt=0x%X, mode=%s, fir_addr=0x%.16llX",
+ get_huid(i_pProc),
+ (i_mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ fir_addr);
+
+
+ do
+ {
+ // Read the FIR reg
+ auto reqSize = expSize;
+ err = DeviceFW::deviceRead(i_pProc,
+ &fir_data,
+ reqSize,
+ DEVICE_SCOM_ADDRESS(fir_addr));
+
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommMapAttn Read Fail! (%s): "
+ " tgt=0x%X, reg_addr=0x%.16llX, data=0x%.16llX "
+ TRACE_ERR_FMT,
+ (i_mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ TARGETING::get_huid(i_pProc),
+ fir_addr, fir_data,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+ assert(reqSize==expSize,"nodeCommMapAttn: SCOM deviceRead didn't return expected data size of %d (it was %d)",
+ expSize,reqSize);
+
+ // Map Attention bits in the FIR
+ fir_data_with_mask = fir_data & fir_mask;
+ const int bit_count = __builtin_popcount(fir_data_with_mask);
+ TRACUCOMP(g_trac_nc,"nodeCommMapAttn: FIR data = 0x%.16llX, "
+ "mask=0x%.16llX, data+mask=0x%.16llX, count=%d",
+ fir_data, fir_mask, fir_data_with_mask, bit_count);
+
+ if (bit_count == 0)
+ {
+ TRACFCOMP(g_trac_nc,INFO_MRK"nodeCommMapAttn: no attentions found");
+ break;
+ }
+ else if (bit_count > 1)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommMapAttn: "
+ "Too many attentions found (%d) in fir: data=0x%.16llX, "
+ "data+mask=0x%.16llX, fir_addr=0x%.16llX",
+ bit_count, fir_data, fir_data_with_mask, fir_addr);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NC_TOO_MANY_ATTNS_FOUND
+ * @moduleid MOD_NC_MAP_ATTN
+ * @userdata1 Raw FIR Data
+ * @userdata2[0:31] Number of Attentions found
+ * @userdata2[32:63] Target HUID FIR was read from
+ * @devdesc Too many attentions were found in
+ * the Node Comm FIR Register
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NC_MAP_ATTN,
+ RC_NC_TOO_MANY_ATTNS_FOUND,
+ fir_data,
+ TWO_UINT32_TO_UINT64(
+ bit_count,
+ get_huid(i_pProc)));
+
+ // Likely HB code failed to do the procedure correctly
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Or unlikely an issue with Processor or its bus
+ err->addHwCallout( i_pProc,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ err->collectTrace(SECURE_COMP_NAME);
+ err->collectTrace(NODECOMM_TRACE_NAME);
+
+ break;
+ }
+
+ int bit = 0;
+ const int possible_attn_bits = __builtin_popcount(fir_mask);
+ for ( ; bit < possible_attn_bits ; ++bit)
+ {
+ // Start at first bit and shift right to find an attention
+ if ( fir_data & (NCDD_START_OF_ATTN_BITS >> bit))
+ {
+ o_attn_found = true;
+ o_linkId = (bit / 2);
+ o_mboxId = (bit % 2);
+ break;
+ }
+ }
+
+ } while( 0 );
+
+ TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommMapAttn: tgt=0x%X: "
+ "o_attn_found=%d, o_linkId=%d, mboxId=%d, "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), o_attn_found, o_linkId, o_mboxId,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end of nodeCommMapAttn
+
+} // End NODECOMM namespace
+
+} // End SECUREBOOT namespace
+
diff --git a/src/usr/secureboot/node_comm/node_comm.H b/src/usr/secureboot/node_comm/node_comm.H
new file mode 100644
index 000000000..60a6dcae7
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm.H
@@ -0,0 +1,162 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm.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 __NODE_COMM_H
+#define __NODE_COMM_H
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <config.h>
+#include <devicefw/userif.H>
+#include <trace/interface.H>
+#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
+#include <secureboot/nodecommif.H>
+// ----------------------------------------------
+// Defines
+// ----------------------------------------------
+#define NODECOMM_TRACE_NAME "NODECOMM"
+extern trace_desc_t* g_trac_nc;
+
+// Easy macro replace for unit testing - TRACD vs TRACF
+#define TRACUCOMP(args...) TRACFCOMP(args)
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+/*****************************************************************************/
+/* Node Comm Registers Decription
+ *
+ * There is a set offset between the equivalent XBUS and ABUS registers such
+ * that in all cases ABUS Register Address = XBUS Register Address + 0x400.
+ * The offset of 0x400 will be applied if the operation is in ABUS mode.
+ */
+/*****************************************************************************/
+#define NCDD_ABUS_REG_OFFSET 0x400
+#define NCDD_ABUS_STRING "ABUS"
+#define NCDD_XBUS_STRING "XBUS"
+
+
+/*
+ * @brief Node Comm Registers - see above for description
+ */
+enum node_comm_registers_t : uint64_t
+{
+ // XBUS values are default values
+ // NCDD_ABUS_REG_OFFSET added if in ABUS mode
+ NCDD_REG_FIR = 0x5013400,
+ NCDD_REG_CTRL = 0x501342E,
+ NCDD_REG_DATA = 0x501342F,
+
+ //MailBox Registers:
+ NCDD_REG_LINK_MBOX_00 = 0x5013430, //(secure)
+
+/* These registers are calculated by getLinkMboxReg() below
+ NCDD_REG_LINK_MBOX_01 = 0x5013431,
+ NCDD_REG_LINK_MBOX_10 = 0x5013432,
+ NCDD_REG_LINK_MBOX_11 = 0x5013433,
+ NCDD_REG_LINK_MBOX_20 = 0x5013434, //(secure)
+ NCDD_REG_LINK_MBOX_21 = 0x5013435,
+ NCDD_REG_LINK_MBOX_30 = 0x5013436,
+ NCDD_REG_LINK_MBOX_31 = 0x5013437,
+ NCDD_REG_LINK_MBOX_40 = 0x5013438, //(secure)
+ NCDD_REG_LINK_MBOX_41 = 0x5013439,
+ NCDD_REG_LINK_MBOX_50 = 0x501343A,
+ NCDD_REG_LINK_MBOX_51 = 0x501343B,
+
+ ABUS-Only: (but still use theoretical XBUS value and in NCDD_ABUS_REG_OFFSET)
+ NCDD_REG_LINK_MBOX_60 = 0x501343A, //(secure)
+ NCDD_REG_LINK_MBOX_61 = 0x501343B,
+ NCDD_REG_LINK_MBOX_70 = 0x501343A,
+ NCDD_REG_LINK_MBOX_71 = 0x501343B,
+*/
+};
+
+/**
+ * @brief Calculate Link Mailbox Register Address based on mode (XBUS or ABUS)
+ *
+ * @param[in] i_reg - Register Base Address - see node_comm_registers_t
+ * @param[in] i_mode - Indicates if the address is for a ABUS or XBUS operation
+ *
+ * @return uint64_t - Calculated Link Mailbox Register Address
+ */
+inline uint64_t getLinkMboxRegAddr(uint64_t i_reg,
+ node_comm_modes_t i_mode)
+{
+ return (i_mode == NCDD_MODE_ABUS)
+ ? (i_reg + NCDD_ABUS_REG_OFFSET)
+ : i_reg;
+}
+
+/**
+ * @brief Calculate Link Mailbox Base Register based on linkId and mboxId
+ *
+ * @param[in] i_linkId - Link Id of the operation
+ * @param[in] i_mboxId - Mailbox Id of the operation
+ *
+ * @return uint64_t - Calculated Link Mailbox Register Base Address
+ * @note Returned value is Base/XBUS Address - see node_comm_registers_t
+ */
+inline uint64_t getLinkMboxReg(uint8_t i_linkId, uint8_t i_mboxId)
+{
+ return NCDD_REG_LINK_MBOX_00 + (2*i_linkId) + i_mboxId;
+}
+
+enum node_comm_fir_reg_helpers_t : uint64_t
+{
+ NCDD_ABUS_FIR_ATTN_MASK = 0x000000000FFFF000,
+ NCDD_XBUS_FIR_ATTN_MASK = 0x000000000FFF0000,
+ NCDD_START_OF_ATTN_BITS = 0x0000000008000000,
+};
+
+/**
+ * @brief Map Attention Bits in XBUS/ABUS FIR Register to specific Link Mailbox
+ *
+ * @param[in] i_pProc Processor target to look for attentions on
+ * Can't be nullptr
+ * @param[in] i_mode Indicates to look for ABUS or XBUS attentions
+ * @param[in] o_attn_found Returns true if attention was found; otherwise false
+ * @param[in] o_linkId Link Id attention was found on
+ * @param[in] o_mboxId Mbox Id attention was found on
+ * @note - o_linkId and o_mboxId are only set/valid if o_attn_found is true
+ *
+ * @return errlHndl_t Error log handle
+ * @retval nullptr Operation was successful
+ * @retval !nullptr Operation failed with valid error log
+ */
+errlHndl_t nodeCommMapAttn(TARGETING::Target* i_pProc,
+ node_comm_modes_t i_mode,
+ bool & o_attn_found,
+ uint64_t & o_linkId,
+ uint64_t & o_mboxId);
+
+} // end NODECOMM namespace
+
+} // end SECUREBOOT namespace
+
+#endif // End __NODE_COMM_H
+
diff --git a/src/usr/secureboot/node_comm/node_comm_dd.C b/src/usr/secureboot/node_comm/node_comm_dd.C
new file mode 100644
index 000000000..5029068fc
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm_dd.C
@@ -0,0 +1,596 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm_dd.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 node_comm_dd.C
+ *
+ * @brief Implementation of the Secure Node Communications device driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <sys/time.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/userif.H>
+#include <devicefw/driverif.H>
+#include <secureboot/secure_reasoncodes.H>
+#include "node_comm_dd.H"
+#include "node_comm.H"
+
+// ----------------------------------------------
+// Globals
+// ----------------------------------------------
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+trace_desc_t* g_trac_nc = nullptr;
+TRAC_INIT( & g_trac_nc, NODECOMM_TRACE_NAME, KILOBYTE );
+
+
+// ----------------------------------------------
+// Defines
+// ----------------------------------------------
+// If the link(s) are up the operation should complete right away
+// so there will only be a short polling window
+#define NODE_COMM_POLL_DELAY_NS 1 // Sleep for 1ns per poll
+#define NODE_COMM_POLL_DELAY_TOTAL_NS 10 // Total time to poll
+
+
+using namespace TARGETING;
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+// Register the generic I2C perform Op with the routing code for Procs.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::NODECOMM,
+ TARGETING::TYPE_PROC,
+ nodeCommPerformOp );
+
+errlHndl_t nodeCommPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t err = nullptr;
+ node_comm_args_t node_comm_args;
+
+ uint64_t mode = va_arg( i_args, uint64_t );
+ node_comm_args.mode = static_cast<node_comm_modes_t>(mode);
+
+ uint64_t linkId = va_arg( i_args, uint64_t );
+ node_comm_args.linkId = static_cast<uint8_t>(linkId);
+
+ uint64_t mboxId = va_arg( i_args, uint64_t );
+ node_comm_args.mboxId = static_cast<uint8_t>(mboxId);
+
+ node_comm_args.data_ptr = reinterpret_cast<uint64_t*>(io_buffer);
+ node_comm_args.tgt = i_target;
+ node_comm_args.tgt_huid = TARGETING::get_huid(i_target);
+
+ do
+ {
+
+ // Check other input parameters
+ const auto max_linkId = (mode==NCDD_MODE_ABUS)
+ ? NCDD_MAX_ABUS_LINK_ID
+ : NCDD_MAX_XBUS_LINK_ID;
+
+ if ( (node_comm_args.mode >= NCDD_MODE_INVALID)
+ || (node_comm_args.linkId > max_linkId)
+ || (node_comm_args.mboxId > NCDD_MAX_MBOX_ID)
+ || (node_comm_args.data_ptr == nullptr)
+ )
+ {
+ TRACFCOMP( g_trac_nc,ERR_MRK"nodeCommPerformOp: Invalid Input Args!"
+ " mode=%d, linkId=0x%X (max=0x%X), mboxId=0x%X, "
+ " data_ptr=%p",
+ node_comm_args.mode, node_comm_args.linkId,
+ max_linkId, node_comm_args.mboxId,
+ node_comm_args.data_ptr);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NCDD_INVALID_ARGS
+ * @moduleid MOD_NCDD_PERFORM_OP
+ * @userdata1[0:15] BUS Mode Enum Value
+ * @userdata1[16:31] LinkId Value
+ * @userdata1[32:47] MAX possile LinkId Value based on Mode
+ * @userdata1[48:63] MailboxId Value
+ * @userdata2 Input Data Pointer
+ * @devdesc Invalid Input Args for Node Comm DD call
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NCDD_PERFORM_OP,
+ RC_NCDD_INVALID_ARGS,
+ FOUR_UINT16_TO_UINT64(
+ node_comm_args.mode,
+ node_comm_args.linkId,
+ max_linkId,
+ node_comm_args.mboxId),
+ reinterpret_cast<uint64_t>(
+ node_comm_args.data_ptr),
+ true /*Add HB SW Callout*/ );
+ break;
+ }
+
+ TRACUCOMP(g_trac_nc,ENTER_MRK"nodeCommPerformOp: %s: %s: "
+ "tgt=0x%X, LinkId=%d, MboxId=%d, data=0x%.16llX",
+ (node_comm_args.mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ node_comm_args.tgt_huid, node_comm_args.linkId,
+ node_comm_args.mboxId, (*node_comm_args.data_ptr));
+
+ // Mutex Lock
+ // @TODO RTC:191008 Support mutex
+
+ /***********************************************/
+ /* Node Comm Read */
+ /***********************************************/
+ if ( i_opType == DeviceFW::READ )
+ {
+ err = ncddRead( node_comm_args );
+ }
+
+ /***********************************************/
+ /* Node Comm Write */
+ /***********************************************/
+ else if( i_opType == DeviceFW::WRITE )
+ {
+ err = ncddWrite( node_comm_args);
+ }
+
+ // Handle Error from Operation (like a reset, if necessary)
+ if( err )
+ {
+
+ ncddHandleError( err,
+ node_comm_args );
+ break;
+ }
+
+ }
+ while (0);
+
+ // Mutex Unlock
+ // @TODO RTC:191008 Support mutex
+
+ // If err, add trace and FFDC to log
+ if (err)
+ {
+ err->collectTrace(SECURE_COMP_NAME);
+ err->collectTrace(NODECOMM_TRACE_NAME);
+
+ // @TODO RTC:191008 Add FFDC - call to new UserDetails Section
+ }
+
+ TRACFCOMP (g_trac_nc, EXIT_MRK"nodeCommPerformOp: %s: %s: "
+ "tgt=0x%X, LinkId=%d, MboxId=%d, data=0x%.16llX. "
+ TRACE_ERR_FMT,
+ (node_comm_args.mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ node_comm_args.tgt_huid,
+ node_comm_args.linkId, node_comm_args.mboxId,
+ (node_comm_args.data_ptr != nullptr)
+ ? (*node_comm_args.data_ptr) : 0,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+} // end nodeCommPerformOp
+
+errlHndl_t ncddRead(node_comm_args_t & i_args)
+{
+ errlHndl_t err = nullptr;
+
+ do
+ {
+ // Determine correct Link Mailbox Register based on inputs
+ const uint64_t link_mbox_reg = getLinkMboxReg(i_args.linkId, i_args.mboxId);
+
+ // Read data from the correct LinkId/Mailbox Register
+ err = ncddRegisterOp( DeviceFW::READ,
+ i_args.data_ptr,
+ link_mbox_reg,
+ i_args );
+
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddRead: SCOM deviceRead call "
+ "failed for Target HUID 0x%08X and address 0x%016llX. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ link_mbox_reg,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ } while( 0 );
+
+ TRACUCOMP( g_trac_nc,EXIT_MRK"ncddRead: "
+ TRACE_ERR_FMT,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end ncddRead
+
+errlHndl_t ncddWrite (node_comm_args_t & i_args)
+{
+ errlHndl_t err = nullptr;
+
+ do
+ {
+ // Write data to data movement register
+ err = ncddRegisterOp( DeviceFW::WRITE,
+ i_args.data_ptr,
+ NCDD_REG_DATA,
+ i_args );
+
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddWrite: SCOM deviceWrite call "
+ "failed for Target HUID 0x%08X and address 0x%016llX. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ NCDD_REG_DATA,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+
+ // Write Control Reg to send the data
+ ctrl_reg_t ctrl_reg_cmd;
+ ctrl_reg_cmd.value = 0x0;
+
+ ctrl_reg_cmd.start_stop = 1; // to start the command
+ ctrl_reg_cmd.write_not_read = 1; // write command
+ ctrl_reg_cmd.mbox_id = i_args.mboxId;
+ ctrl_reg_cmd.link_id = i_args.linkId;
+
+
+ err = ncddRegisterOp( DeviceFW::WRITE,
+ &ctrl_reg_cmd.value,
+ NCDD_REG_CTRL,
+ i_args );
+
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddWrite: SCOM deviceWrite call "
+ "failed for Target HUID 0x%08X and address 0x%016llX. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ NCDD_REG_CTRL,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // Wait for command to be complete
+ err = ncddWaitForCmdComp(i_args);
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddWrite: Wait For Cmd Complete "
+ "failed for Target HUID 0x%08X. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // @TODO RTC 191008 - have ncddWaitForCmdComp return status to
+ // check for 'write' bit being set
+
+ } while( 0 );
+
+ TRACUCOMP( g_trac_nc,EXIT_MRK"ncddWrite: "
+ TRACE_ERR_FMT,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end ncddWrite
+
+
+errlHndl_t ncddCheckStatus (node_comm_args_t & i_args,
+ const ctrl_reg_t i_statusVal )
+{
+ errlHndl_t err = nullptr;
+ bool errorFound = false;
+
+ TRACUCOMP( g_trac_nc,
+ ENTER_MRK"ncddCheckStatus(): Tgt=0x%X: 0x%.16llX",
+ i_args.tgt_huid,
+ i_statusVal.value );
+
+ do
+ {
+ if( 1 == i_statusVal.bad_addr )
+ {
+ errorFound = true;
+ TRACFCOMP(g_trac_nc,ERR_MRK
+ "Node Comm DD: Bad Address! - status reg: 0x%016llx",
+ i_statusVal.value );
+ }
+
+ if( 1 == i_statusVal.link_down )
+ {
+ errorFound = true;
+ TRACFCOMP(g_trac_nc,ERR_MRK
+ "Node Comm DD: Link Down! - status reg: 0x%016llx",
+ i_statusVal.value );
+ }
+
+ if( 1 == i_statusVal.corrupt )
+ {
+ errorFound = true;
+ TRACFCOMP(g_trac_nc,ERR_MRK
+ "Node Comm DD: Corrupt! - status reg: 0x%016llx",
+ i_statusVal.value );
+ }
+
+ if( 1 == i_statusVal.bad_write )
+ {
+ errorFound = true;
+ TRACFCOMP(g_trac_nc,ERR_MRK
+ "Node Comm DD: Bad Write! - status reg: 0x%016llx",
+ i_statusVal.value );
+ }
+
+ // Create Error Log
+ if( errorFound )
+ {
+ TRACFCOMP( g_trac_nc,
+ ERR_MRK"ncddCheckStatus() - Error(s) found on "
+ "Target 0x%X",
+ i_args.tgt_huid );
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NCDD_HW_ERROR_FOUND
+ * @moduleid MOD_NCDD_CHECK_FOR_ERRORS
+ * @userdata1 Status Register Value
+ * @userdata2 Target HUID
+ * @devdesc Error found in Node Comm status/ctrl register
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NCDD_CHECK_FOR_ERRORS,
+ RC_NCDD_HW_ERROR_FOUND,
+ i_statusVal.value,
+ i_args.tgt_huid);
+
+ // Likely an issue with Processor or its bus
+ err->addHwCallout( i_args.tgt,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+
+ // Or HB code failed to do the procedure correctly
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+
+ // @TODO RTC 184518 - Look into bus callouts
+
+ break;
+ }
+
+
+ } while( 0 );
+
+ TRACUCOMP( g_trac_nc,EXIT_MRK"ncddCheckStatus: "
+ TRACE_ERR_FMT,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end ncddCheckStatus
+
+
+errlHndl_t ncddWaitForCmdComp (node_comm_args_t & i_args)
+{
+ errlHndl_t err = nullptr;
+ uint64_t interval_ns = NODE_COMM_POLL_DELAY_NS;
+ int timeout_ns = NODE_COMM_POLL_DELAY_TOTAL_NS;
+ ctrl_reg_t ctrl_reg_status;
+
+
+ TRACUCOMP(g_trac_nc, "ncddWaitForCmdComp(): timeout_ns=%d, "
+ "interval_ns=%d", timeout_ns, interval_ns);
+
+ do
+ {
+ do
+ {
+ // Read Control Reg to check for status
+ ctrl_reg_status.value = 0x0;
+
+ err = ncddRegisterOp( DeviceFW::READ,
+ &ctrl_reg_status.value,
+ NCDD_REG_CTRL,
+ i_args );
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddWaitForCmdComp: ncddRegisterOp "
+ "failed for Target HUID 0x%08X and address 0x%016llX. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ NCDD_REG_CTRL,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // Check For Errors
+ err = ncddCheckStatus(i_args, ctrl_reg_status);
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddWaitForCmdComp: ncddCheckStatus"
+ " failed for Target HUID 0x%08X, address 0x%016llX. "
+ TRACE_ERR_FMT,
+ i_args.tgt_huid,
+ NCDD_REG_CTRL,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // Check if we have more time to poll
+ if (timeout_ns < 0)
+ {
+ TRACFCOMP(g_trac_nc,
+ ERR_MRK"ncddWaitForCmdComp() - "
+ "Timed out waiting for Command Complete! "
+ "status=0x%016llX from reg=0x%016llX",
+ ctrl_reg_status.value, NCDD_REG_CTRL);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NCDD_CMD_COMP_TIMEOUT
+ * @moduleid MOD_NCDD_WAIT_FOR_CMD_COMP
+ * @userdata1 Status Register Value
+ * @userdata2[0:31] Status/Control Register Address
+ * @userdata2[32:63] Target HUID
+ * @devdesc Timed out waiting for command complete.
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NCDD_WAIT_FOR_CMD_COMP,
+ RC_NCDD_CMD_COMP_TIMEOUT,
+ ctrl_reg_status.value,
+ TWO_UINT32_TO_UINT64(
+ NCDD_REG_CTRL,
+ i_args.tgt_huid));
+
+ // Likely an issue with Processor or its bus
+ err->addHwCallout(i_args.tgt,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Or HB code failed to do the procedure correctly
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+
+ // @TODO RTC 184518 - Look into bus callouts
+
+ break;
+ }
+
+ // Sleep before polling again
+ nanosleep( 0, interval_ns );
+ timeout_ns -= interval_ns;
+
+ } while( 1 == ctrl_reg_status.start_stop ); /* Cmd Complete when ==0 */
+
+ if (err)
+ {
+ break;
+ }
+
+ } while (0);
+
+ TRACUCOMP( g_trac_nc,EXIT_MRK"ncddWaitForCmdComp: "
+ TRACE_ERR_FMT,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end ncddWaitForCmdComp
+
+errlHndl_t ncddRegisterOp ( DeviceFW::OperationType i_opType,
+ uint64_t * io_data_64,
+ uint64_t i_reg,
+ node_comm_args_t & i_args )
+{
+ errlHndl_t err = nullptr;
+ const size_t expSize = sizeof(i_reg);
+ uint64_t l_reg = getLinkMboxRegAddr(i_reg, i_args.mode);
+
+ TRACUCOMP(g_trac_nc,ENTER_MRK"ncddRegisterOp: %s: %s: "
+ "tgt=0x%X, reg_addr=0x%.16llX, data=0x%.16llX",
+ (i_args.mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ i_args.tgt_huid,
+ l_reg, (*io_data_64)) ;
+
+ do
+ {
+ uint64_t reqSize = expSize;
+ err = DeviceFW::deviceOp( i_opType,
+ i_args.tgt,
+ io_data_64,
+ reqSize,
+ DEVICE_SCOM_ADDRESS(l_reg));
+
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"ncddRegisterOp %s %s Fail! "
+ TRACE_ERR_FMT
+ " tgt=0x%X, reg_addr=0x%.8X, data=0x%.16X",
+ (i_args.mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ TRACE_ERR_ARGS(err),
+ i_args.tgt_huid,
+ l_reg, (*io_data_64) );
+ break;
+ }
+ assert(reqSize==expSize,"ncddRegisterOp: SCOM deviceRead didn't return expected data size of %d (it was %d)",
+ expSize,reqSize);
+
+ } while (0);
+
+ TRACUCOMP(g_trac_nc,EXIT_MRK"ncddRegisterOp: %s: %s: "
+ "tgt=0x%X, reg_addr=0x%.16llX, data=0x%.16llX. "
+ TRACE_ERR_FMT,
+ (i_args.mode == NCDD_MODE_ABUS)
+ ? NCDD_ABUS_STRING : NCDD_XBUS_STRING,
+ ( i_opType == DeviceFW::READ ) ? "read" : "write",
+ i_args.tgt_huid,
+ l_reg, (*io_data_64),
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end ncddRegisterOp
+
+
+} // end NODECOMM namespace
+
+} // end SECUREBOOT namespace
+
diff --git a/src/usr/secureboot/node_comm/node_comm_dd.H b/src/usr/secureboot/node_comm/node_comm_dd.H
new file mode 100644
index 000000000..a42ce7fd0
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm_dd.H
@@ -0,0 +1,220 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm_dd.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 __NODE_COMM_DD_H
+#define __NODE_COMM_DD_H
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <config.h>
+#include <devicefw/userif.H>
+#include <secureboot/nodecommif.H>
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+/**
+ * @brief Struct used to pass basic Node Communication operations
+ * information between functions
+ */
+struct node_comm_args_t
+{
+ TARGETING::Target* tgt;
+ uint32_t tgt_huid;
+ node_comm_modes_t mode;
+ uint8_t linkId;
+ uint8_t mboxId;
+ uint64_t* data_ptr;
+
+ node_comm_args_t():tgt(nullptr),
+ tgt_huid(0x0),
+ mode(NCDD_MODE_INVALID),
+ linkId(NCDD_INVALID_LINK_MBOX),
+ mboxId(NCDD_INVALID_LINK_MBOX),
+ data_ptr(nullptr){};
+};
+
+
+/**
+ * @brief Node Comm Contol (and Status) Register Definition
+ *
+ * @note Certain bits are used to start an operation, provide status of the
+ * operation, and flag errors in the operation.
+ */
+union ctrl_reg_t
+{
+ uint64_t value;
+ struct
+ {
+ uint64_t start_stop : 1; // set to start op; HW sets to 0 when op done
+ uint64_t write_not_read : 1;
+ uint64_t bad_addr : 1;
+ uint64_t link_down : 1;
+ uint64_t corrupt : 1;
+ uint64_t sent : 1;
+ uint64_t bad_write : 1;
+ uint64_t reset : 1;
+ uint64_t mbox_id : 1;
+ uint64_t link_id : 3;
+ uint64_t reserved : 52;
+
+ } PACKED;
+};
+
+
+/**
+*
+* @brief Perform a Node Comm operation. It follows a pre-defined
+* prototype function in order to be registered with the device
+* driver framework.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driverif.H
+*
+* @param[in] i_target - Processor Target
+* Code will fail if nullptr or not TYPE_PROC
+*
+* @param [in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target device
+* OUTPUT: Pointer to the data that was read from the target device
+*
+* @param [in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device
+* NOTE: For Both INPUT and OUTPUT this should be 8-bytes (64-bits)
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* userif.H
+*
+* @param [in] i_args - This is an argument list for the device driver
+* framework. This list of arguments is documented in userif.H.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t nodeCommPerformOp( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
+/**
+ * @brief Reads data From ABUS/XBUS Link Mailbox Register
+ *
+ * @param[in/out] io_args - Structure containing arguments needed for a command
+ * transaction and it holds the resulting data
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t ncddRead (node_comm_args_t & io_args);
+
+/**
+ * @brief Writes data to ABUS/XBUS Link Mailbox Data Movement Register and then
+ * sends data via Link Bus Mailbox capability
+ *
+ * @param[in] i_args - Structure containing arguments needed for a command
+ * transaction.
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t ncddWrite (node_comm_args_t & i_args);
+
+/**
+ * @brief Checks the status in the ABUS/XBUS Link Mailbox Control Register
+ *
+ * @param[in] i_args - Structure containing arguments needed for a command
+ * transaction.
+ *
+ * @param[in] i_statusVal - Control Register value to be checked
+ *
+ * @return errlHndl_t - nullptr if successful and the command is complete;
+ * otherwise a pointer to the error log.
+ */
+errlHndl_t ncddCheckForErrors (node_comm_args_t & i_args,
+ ctrl_reg_t i_statusVal );
+
+/**
+ * @brief Waits for the operation to complete or timeout while
+ * periodically checking the status for errors
+ *
+ * @param[in] i_args - Structure containing arguments needed for a command
+ * transaction.
+ *
+ * @return errlHndl_t - nullptr if successful and the command is complete;
+ * otherwise a pointer to the error log.
+ */
+errlHndl_t ncddWaitForCmdComp (node_comm_args_t & i_args);
+
+/**
+ * @brief Analyzes an error handle object and performs any
+ * reset activity, if necessary
+ *
+ * @param[in] i_err - The error to analyze
+ * @param[in] i_args - miscellaneous arguments
+ *
+ * @return void
+ */
+// @TODO RTC:191008 Implement simple reset functionality
+void ncddHandleError( errlHndl_t & i_err,
+ node_comm_args_t & i_args ){};
+
+
+/**
+ * @brief This function handles all Node Communications-related SCOM operations
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param [in/out] io_buffer_64
+ * INPUT: Pointer to 64 bits of data to be written to the target
+ * OUTPUT: Pointer to the 64 bits of data that was read from the target
+ *
+ * @param[in] i_reg - The SCOM register of the operation
+ *
+ * @param[in/out] i_args - Structure containing arguments needed for a command
+ * transaction and holds resulting data, if applicable
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t ncddRegisterOp ( DeviceFW::OperationType i_opType,
+ uint64_t * io_data_64,
+ uint64_t i_reg,
+ node_comm_args_t & i_args );
+
+} // end NODECOMM namespace
+
+} // end SECUREBOOT namespace
+
+#endif // End __NODE_COMM_DD_H
+
diff --git a/src/usr/secureboot/node_comm/node_comm_test.C b/src/usr/secureboot/node_comm/node_comm_test.C
new file mode 100644
index 000000000..6b034361a
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm_test.C
@@ -0,0 +1,296 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm_test.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 node_comm_test.C
+ *
+ * @brief Implementation of the Secure Node Communications Tests
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/userif.H>
+#include <devicefw/driverif.H>
+#include <secureboot/secure_reasoncodes.H>
+#include <secureboot/nodecommif.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+
+#include "node_comm.H"
+
+
+using namespace TARGETING;
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+/**
+ * @brief Execute A Single Transmission from one proc to another over Xbus
+ */
+errlHndl_t nodeCommXbus2ProcTest(void)
+{
+ errlHndl_t err = nullptr;
+ const uint64_t gold_data = 0xFEEDB0B0DEADBEEF;
+ uint64_t sent_data = gold_data;
+ uint64_t read_data = 0;
+ Target* read_tgt = nullptr;
+ node_comm_modes_t mode = NCDD_MODE_XBUS;
+ uint64_t linkId = 0;
+ uint64_t mboxId = 0;
+ bool attn_found = false;
+
+ do
+ {
+
+ // Get a list of all the procs in the system
+ TARGETING::TargetHandleList l_cpuTargetList;
+ getAllChips(l_cpuTargetList, TYPE_PROC);
+
+ // Need at least 2 procs for this test
+ if ( l_cpuTargetList.size() < 2 )
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: need at least "
+ "2 procs - only have %d",
+ l_cpuTargetList.size());
+
+ break;
+ }
+
+ TRACUCOMP(g_trac_nc,ENTER_MRK"nodeCommXbus2ProcTest: Running with %d procs",
+ l_cpuTargetList.size());
+
+ // 1) Send Data Out of First Proc Xbus Link Mailbox
+ // @TODO RTC 184516 revisit this when PEER_PATH attribute is being used
+ if ( l_cpuTargetList.size() != 4)
+ {
+ linkId = 4;
+ mboxId = 0;
+ }
+ else
+ {
+ linkId = 0;
+ mboxId = 0;
+ }
+ TARGETING::Target* proc0 = (l_cpuTargetList[0]);
+ size_t size=sizeof(sent_data);
+
+ TRACFCOMP(g_trac_nc,"nodeCommXbus2ProcTest: "
+ "Sending 0x%016llX to L%d/M%d Using proc0=0x%X",
+ sent_data, linkId, mboxId, TARGETING::get_huid(proc0));
+
+ err = DeviceFW::deviceWrite(proc0,
+ &sent_data,
+ size,
+ DEVICE_NODECOMM_ADDRESS(mode, linkId, mboxId));
+
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: Error Back From "
+ "Xbus MBox Send: Tgt=0x%X, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(proc0), linkId, mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // 2) Loop through targets to see which of them had an attention
+ for (const auto & l_cpu_target: l_cpuTargetList)
+ {
+ attn_found = false;
+ read_tgt = l_cpu_target;
+
+ err = nodeCommMapAttn(read_tgt, mode, attn_found, linkId, mboxId);
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: Error Back From "
+ "Map Attn: Tgt=0x%X, attn_found=%d, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(read_tgt), attn_found, linkId, mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+ if (attn_found == true)
+ {
+ break;
+ }
+ }
+ if(err)
+ {
+ break;
+ }
+
+ if (attn_found == false)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: "
+ "No attentions were found! (%d)",
+ attn_found);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NC_NO_ATTN_FOUND
+ * @moduleid MOD_NC_XBUS_TEST
+ * @userdata1 Data Sent
+ * @userdata2[0:15] LinkId data was sent from
+ * @userdata2[16:31] MboxId data was sent from
+ * @userdata2[32:63] Target HUID data was sent from
+ * @devdesc No Attention was found after sending data in
+ * XBUS Node Comm Test
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NC_XBUS_TEST,
+ RC_NC_NO_ATTN_FOUND,
+ sent_data,
+ TWO_UINT16_ONE_UINT32_TO_UINT64(
+ linkId,
+ mboxId,
+ get_huid(proc0)));
+
+ // Likely HB code failed to do the procedure correctly
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Or unlikely an issue with Processor or its bus
+ err->addHwCallout( proc0,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_nc,INFO_MRK"nodeCommXbus2ProcTest: "
+ "Attention was found (%d) on tgt=0x%.08X",
+ attn_found, get_huid(read_tgt));
+ }
+
+
+ // 3) Read message on proc with Link Mailbox found above
+ TRACFCOMP(g_trac_nc,"nodeCommXbus2ProcTest: Attention Found on"
+ "proc=0x%X for L%d/M%d ",
+ TARGETING::get_huid(read_tgt), linkId, mboxId);
+
+ err = DeviceFW::deviceRead(read_tgt,
+ &read_data,
+ size,
+ DEVICE_NODECOMM_ADDRESS(mode, linkId, mboxId));
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: Error Back From "
+ "Xbus MBox Read: Tgt=0x%X, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(read_tgt), linkId, mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // 4) Compare values
+ if (read_data == gold_data)
+ {
+ TRACFCOMP(g_trac_nc,INFO_MRK"nodeCommXbus2ProcTest: "
+ "DATA SUCCESSFULLY READ BACK = 0x%.16llx from "
+ "proc=0x%X's L%d/M%d Mailbox"
+ "L%d/M%d using proc=0x%X",
+ read_data, TARGETING::get_huid(read_tgt), linkId, mboxId);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommXbus2ProcTest: "
+ "DATA NOT READ BACK! Got 0x%.16llx; should be 0x%.16llX. "
+ "Read from proc=0x%X's L%d/M%d Mailbox",
+ read_data, gold_data, TARGETING::get_huid(read_tgt), linkId, mboxId);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_NC_DATA_MISCOMPARE
+ * @moduleid MOD_NC_XBUS_TEST
+ * @userdata1 Data Read Back
+ * @userdata2[0:15] LinkId data was read from
+ * @userdata2[16:31] MboxId data was read from
+ * @userdata2[32:63] Target HUID data was read from
+ * @devdesc No Attention was found after sending data in
+ * Xbus Node Comm Test
+ * @custdesc Secure Boot failure
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NC_XBUS_TEST,
+ RC_NC_DATA_MISCOMPARE,
+ read_data,
+ TWO_UINT16_ONE_UINT32_TO_UINT64(
+ linkId,
+ mboxId,
+ get_huid(read_tgt)));
+
+ // Likely HB code failed to do the procedure correctly
+ err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Or unlikely an issue with Processor or its bus
+ err->addHwCallout( read_tgt,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ }
+
+ } while( 0 );
+
+ TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommXbus2ProcTest: "
+ TRACE_ERR_FMT
+ "Tgt=0x%X, attn_found=%d, link=%d, mbox=%d",
+ TRACE_ERR_ARGS(err),
+ get_huid(read_tgt), attn_found, linkId, mboxId);
+
+ if (err)
+ {
+ err->collectTrace(SECURE_COMP_NAME);
+ err->collectTrace(NODECOMM_TRACE_NAME);
+
+ // @TODO RTC:191008 Delete for now as it will fail in simics and
+ // cause a processor deconfig.
+ delete err;
+ err = nullptr;
+ }
+
+ return err;
+
+} // end of nodeCommXbus2ProcTest
+
+} // End NODECOMM namespace
+
+} // End SECUREBOOT namespace
+
+
+
OpenPOWER on IntegriCloud