From 3ad299af08fd1ed6a14c72a9d3fe4b89a5af5eec Mon Sep 17 00:00:00 2001 From: Mike Baiocchi Date: Sat, 28 Apr 2018 00:54:00 -0500 Subject: 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 Reviewed-by: ILYA SMIRNOV Reviewed-by: Marshall J. Wilks Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: William G. Hoffa --- src/usr/secureboot/node_comm/makefile | 38 ++ src/usr/secureboot/node_comm/node_comm.C | 200 +++++++++ src/usr/secureboot/node_comm/node_comm.H | 162 +++++++ src/usr/secureboot/node_comm/node_comm_dd.C | 596 ++++++++++++++++++++++++++ src/usr/secureboot/node_comm/node_comm_dd.H | 220 ++++++++++ src/usr/secureboot/node_comm/node_comm_test.C | 296 +++++++++++++ 6 files changed, 1512 insertions(+) create mode 100644 src/usr/secureboot/node_comm/makefile create mode 100644 src/usr/secureboot/node_comm/node_comm.C create mode 100644 src/usr/secureboot/node_comm/node_comm.H create mode 100644 src/usr/secureboot/node_comm/node_comm_dd.C create mode 100644 src/usr/secureboot/node_comm/node_comm_dd.H create mode 100644 src/usr/secureboot/node_comm/node_comm_test.C (limited to 'src/usr/secureboot/node_comm') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include // for TRACE_ERR_FMT, TRACE_ERR_ARGS +#include +// ---------------------------------------------- +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(mode); + + uint64_t linkId = va_arg( i_args, uint64_t ); + node_comm_args.linkId = static_cast(linkId); + + uint64_t mboxId = va_arg( i_args, uint64_t ); + node_comm_args.mboxId = static_cast(mboxId); + + node_comm_args.data_ptr = reinterpret_cast(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( + 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 +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + + + -- cgit v1.2.1