summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/node_comm/node_comm_transfer.C
diff options
context:
space:
mode:
authorMike Baiocchi <mbaiocch@us.ibm.com>2019-02-04 14:53:39 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-02-13 14:37:30 -0600
commitc47875eb8c65cbdf29032377c9dc584d081ef35b (patch)
treed347dc14fa612e2924acaf92ecb06e72b0bddeef /src/usr/secureboot/node_comm/node_comm_transfer.C
parent2206846076da737cb4f4a7e8ae66bf57d5d37bc3 (diff)
downloadblackbird-hostboot-c47875eb8c65cbdf29032377c9dc584d081ef35b.tar.gz
blackbird-hostboot-c47875eb8c65cbdf29032377c9dc584d081ef35b.zip
Add Node Communications Transfer Protocol
This commit adds a more flexible Node-to-Node Transfer Protocol that will be used for the secureboot/trustedboot algorithm in multi-node configurations. The original message transfer has been updated to use this new transfer protocol. Change-Id: I12704e8d71d8c0aac52c286160322f9b845a5026 RTC:203641 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71317 Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@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: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot/node_comm/node_comm_transfer.C')
-rw-r--r--src/usr/secureboot/node_comm/node_comm_transfer.C378
1 files changed, 378 insertions, 0 deletions
diff --git a/src/usr/secureboot/node_comm/node_comm_transfer.C b/src/usr/secureboot/node_comm/node_comm_transfer.C
new file mode 100644
index 000000000..daa6b6cbb
--- /dev/null
+++ b/src/usr/secureboot/node_comm/node_comm_transfer.C
@@ -0,0 +1,378 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/node_comm/node_comm_transfer.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] 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 */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <config.h>
+#include <time.h>
+#include <devicefw/userif.H>
+#include <trace/interface.H>
+#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
+#include <secureboot/nodecommif.H>
+#include "node_comm.H"
+#include "node_comm_transfer.H"
+
+// ----------------------------------------------
+// Defines
+// ----------------------------------------------
+
+
+namespace SECUREBOOT
+{
+
+namespace NODECOMM
+{
+
+
+errlHndl_t nodeCommTransferSend(TARGETING::Target* i_pProc,
+ const uint8_t i_linkId,
+ const uint8_t i_mboxId,
+ node_comm_transfer_types_t i_transferType,
+ const uint8_t * i_data,
+ const size_t i_dataSize)
+{
+ errlHndl_t err = nullptr;
+
+ // Determine how many messages need to be sent:
+ // msg sequence 0: Initiation Message
+ // msg sequence 1..N: 8-byte data messages
+ size_t msg_seq = 0;
+ size_t total_data_msgs = (i_dataSize + (sizeof(uint64_t)-1))
+ /sizeof(uint64_t);
+
+ TRACFCOMP(g_trac_nc,ENTER_MRK"nodeCommTransferSend: iProc=0x%.08X "
+ "to send %d bytes of data through linkId=%d mboxId=%d over "
+ "%d data messages",
+ get_huid(i_pProc), i_dataSize, i_linkId, i_mboxId, total_data_msgs);
+
+ do
+ {
+ // Keep track of data sent
+ size_t bytes_sent = 0;
+ size_t bytes_left = i_dataSize;
+
+ // Loop of sending messages (initiation and data) and receiving ACKs
+ for ( ; msg_seq <= total_data_msgs; ++msg_seq)
+ {
+ TRACUCOMP(g_trac_nc,INFO_MRK"nodeCommTransferSend: loop start: "
+ "seq = %d (msg %d of %d)",
+ msg_seq, msg_seq+1, total_data_msgs);
+
+ uint64_t data = 0;
+
+ if (msg_seq==0)
+ {
+ // Send Initiaion Message
+ node_comm_msg_format_t send_msg;
+ send_msg.value = 0; // Clear out the data
+
+ // @TODO RTC 203642 Fix sendingNode and recving Node
+ send_msg.sendingNode = 0;
+ send_msg.recvingNode = 1;
+
+ send_msg.msgType = i_transferType;
+ send_msg.msgSeqNum = msg_seq;
+ send_msg.totalDataMsgs = total_data_msgs;
+ send_msg.totalDataSize = i_dataSize;
+
+ data = send_msg.value;
+ }
+ else
+ {
+ // Send Data
+ // Write a max of 8 bytes at a time
+ size_t loop_data_length =
+ (bytes_left > sizeof(uint64_t)) ?
+ sizeof(uint64_t) :
+ bytes_left;
+
+ data=0;
+ memcpy(&data,
+ i_data + bytes_sent,
+ loop_data_length);
+
+ // Update amount of data left to be written
+ bytes_sent += loop_data_length;
+ bytes_left -= loop_data_length;
+ }
+ TRACDCOMP(g_trac_nc,INFO_MRK"nodeCommTransferSend: "
+ "msg %d: sending data=0x%.16llX (bytes_sent=%d, "
+ "bytes_left=%d)",
+ msg_seq, data, bytes_sent, bytes_left);
+
+ err = nodeCommAbusSendMessage(i_pProc,
+ data,
+ i_linkId,
+ i_mboxId);
+
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferSend: "
+ "nodeCommAbusSendMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), data, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+ // Get ACK
+ uint64_t data_recv = 0;
+ err = nodeCommAbusRecvMessage(i_pProc,
+ i_linkId,
+ i_mboxId,
+ data_recv);
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferSend: "
+ "nodeCommAbusRecvMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), data, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+
+ break;
+ }
+ TRACDCOMP(g_trac_nc,INFO_MRK"nodeCommTransferSend: "
+ "msg %d: receiving ACK = 0x%.16llX",
+ msg_seq, data_recv);
+
+
+
+ // @TODO RTC 203642 Check that ACK is
+ // -- from the right node
+ // -- from right linkId/mboxId
+ // -- the right type of ACK
+
+ } // end of for-loop of messages
+
+ if (err)
+ {
+ break;
+ }
+
+ } while( 0 );
+
+ TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommTransferSend: "
+ TRACE_ERR_FMT,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end of nodeCommTransferSend
+
+
+
+errlHndl_t nodeCommTransferRecv(TARGETING::Target* i_pProc,
+ const uint8_t i_linkId,
+ const uint8_t i_mboxId,
+ node_comm_transfer_types_t i_transferType,
+ uint8_t*& o_data,
+ size_t & o_dataSize)
+{
+ errlHndl_t err = nullptr;
+
+ TRACFCOMP(g_trac_nc,ENTER_MRK"nodeCommTransferRecv: i_pProc=0x%.08X "
+ "expecting messages of type 0x%.02x from linkId=%d mboxId=%d",
+ get_huid(i_pProc), i_transferType, i_linkId, i_mboxId);
+
+ // Clear the output variables to be safe
+ o_data = nullptr;
+ o_dataSize = 0;
+
+ do
+ {
+
+ // Wait for Message
+ uint64_t data_recv = 0;
+ err = nodeCommAbusRecvMessage(i_pProc,
+ i_linkId,
+ i_mboxId,
+ data_recv);
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferRecv: "
+ "nodeCommAbusRecvMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), data_recv, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+
+ break;
+ }
+ node_comm_msg_format_t init_msg = {.value = data_recv};
+ TRACFCOMP(g_trac_nc,INFO_MRK"nodeCommTransferRecv: "
+ "Initiation Message 0x%.16llX: sN=%d, rN=%d, msgType=0x%X, "
+ "msgSeqNum=%d, totalDataMsgs=%d.totalDataSize=%d",
+ init_msg.value, init_msg.sendingNode, init_msg.recvingNode,
+ init_msg.msgType, init_msg.msgSeqNum, init_msg.totalDataMsgs,
+ init_msg.totalDataSize);
+
+ // @TODO RTC 203642 Add the following checks:
+ // - check nodes
+ // - init_msg.msgSeqNum should be 0 for initiation message
+ // - check that expected transfer type is received
+
+
+ // Reply with ACK:
+ node_comm_msg_format_t ack_msg = {.value = 0};
+ ack_msg.value = 0;
+
+ // @TODO RTC 203642 Fix sending node Ids
+ // Always set these for ACK of Initiation:
+ ack_msg.msgSeqNum = 0;
+ ack_msg.msgType = NCT_ACK_OF_INTIATION;
+
+ // ACK total number of expected data messages
+ ack_msg.totalDataMsgs = init_msg.totalDataMsgs;
+
+ // Send ACK message
+ err = nodeCommAbusSendMessage(i_pProc,
+ ack_msg.value,
+ i_linkId,
+ i_mboxId);
+
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferRecv: "
+ "nodeCommAbusSendMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), ack_msg.value, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+
+
+ // msg sequence 0: Initiation Message
+ // msg sequence 1..N: 8-byte data messages
+ size_t msg_seq = 1;
+ size_t total_data_msgs = init_msg.totalDataMsgs;
+
+ // Keep track of data read
+ size_t bytes_read = 0;
+ size_t bytes_left = init_msg.totalDataSize;
+
+ // Create output buffer to store the data
+ uint8_t * data_buffer = reinterpret_cast<uint8_t*>
+ (malloc(init_msg.totalDataSize));
+
+
+ // Loop of receiving data messages and sending ACKs
+ for ( ; msg_seq <= total_data_msgs; ++msg_seq)
+ {
+ // Wait for Data Message
+ data_recv = 0;
+ err = nodeCommAbusRecvMessage(i_pProc,
+ i_linkId,
+ i_mboxId,
+ data_recv);
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferRecv: "
+ "nodeCommAbusRecvMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), data_recv, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+
+ break;
+ }
+ TRACDCOMP(g_trac_nc,INFO_MRK"nodeCommTransferRecv: "
+ "Data Msg Recvd: %d: 0x%.16llX",
+ msg_seq, data_recv);
+
+ size_t loop_bytes_read = (bytes_left > sizeof(uint64_t)) ?
+ sizeof(uint64_t) :
+ bytes_left;
+
+ memcpy(data_buffer+bytes_read,
+ &data_recv,
+ loop_bytes_read);
+
+ data_recv=0; // clear for next loop
+
+ bytes_read += loop_bytes_read;
+ bytes_left -= loop_bytes_read;
+
+ // Send Data ACK
+ ack_msg.msgType = NCT_ACK_OF_DATA;
+ ack_msg.msgSeqNum = msg_seq;
+ ack_msg.totalDataSize = bytes_read;
+
+ TRACDCOMP(g_trac_nc,INFO_MRK"nodeCommTransferRecv: "
+ "Data Msg ACK: %d: 0x%.16llX (bytes_read=%d, "
+ "bytes_left=%d)",
+ msg_seq, ack_msg.value, bytes_read, bytes_left);
+
+ err = nodeCommAbusSendMessage(i_pProc,
+ ack_msg.value,
+ i_linkId,
+ i_mboxId);
+
+ if (err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommTransferRecv: "
+ "nodeCommAbusSendMessage returned an error: "
+ "Tgt=0x%.08X, data=0x%.16llX, link=%d, mbox=%d: "
+ TRACE_ERR_FMT,
+ get_huid(i_pProc), ack_msg.value, i_linkId, i_mboxId,
+ TRACE_ERR_ARGS(err));
+ break;
+ }
+ } // end of for-loop for receiving data messages
+
+ if (err)
+ {
+ free(data_buffer);
+ o_data=nullptr;
+ o_dataSize=0;
+ break;
+ }
+ else
+ {
+ o_data = data_buffer;
+ o_dataSize = init_msg.totalDataSize;
+ }
+
+
+ } while( 0 );
+
+ TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommTransferRecv: "
+ "o_data=%p, o_dataSize=%d. "
+ TRACE_ERR_FMT,
+ o_data, o_dataSize,
+ TRACE_ERR_ARGS(err));
+
+ return err;
+
+} // end of nodeCommTransferRecv
+
+} // end NODECOMM namespace
+
+} // end SECUREBOOT namespace
+
+
OpenPOWER on IntegriCloud