1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
/* 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 <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>
// ----------------------------------------------
// 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...) TRACDCOMP(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_FIR_WOX_AND = 0x5013401,
NCDD_REG_FIR_WOX_OR = 0x5013402,
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 Convert 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;
}
/**
* @brief Calculate Secure LinkId and MailboxId based on OBUS Instance
*
* @param[out] i_obusInstance - OBUS Instance of the operation
* @param[out] o_linkId - Link Id of the OBUS instance
* @param[out] o_mboxId - Mailbox Id of the OBUS instance
*
* @return void
*/
inline void getSecureLinkMboxFromObus(uint8_t i_obusInstance,
uint8_t & o_linkId,
uint8_t & o_mboxId)
{
// For each OBUS instance there are 2 links and 2 mailboxes
// and the Secure Link and Mailbox is always the relative 'L0M0'
// of these 4 possibilities
o_linkId = (2*i_obusInstance);
o_mboxId = 0;
return;
}
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 Calculate Link Mailbox FIR Register Attention Bit Mask
* 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 FIR Register Attention Bit Mask
*/
inline uint64_t getLinkMboxFirAttnBit(uint8_t i_linkId, uint8_t i_mboxId)
{
return (NCDD_START_OF_ATTN_BITS >> ((2*i_linkId) + i_mboxId));
}
/**
* @brief This function waits for the processor to receive a message over
* ABUS from a processor on another node.
*
* @param[in] i_pProc - Processor target to look for attentions on
* Can't be nullptr
* @param[out] o_data - Data received
* @param[out] o_linkId - Link Id that received the message
* @param[out] o_mboxId - Mailbox Id that received the message
*
* @return errlHndl_t Error log handle
* @retval nullptr Operation was successful
* @retval !nullptr Operation failed with valid error log
*/
errlHndl_t nodeCommAbusRecvMessage(TARGETING::Target* i_pProc,
uint64_t & o_data,
uint8_t & o_linkId,
uint8_t & o_mboxId);
/**
* @brief This function sends a message over the ABUS from the processor of
* the current node to a processor on another node.
*
* @param[in] i_pProc - Processor target to look for attentions on
* Can't be nullptr
* @param[in] i_data - Data to be sent
* @param[in] i_linkId - Link Id Message is sent from
* @param[in] i_mboxId - Mailbox Id Message is sent from
*
* @return errlHndl_t Error log handle
* @retval nullptr Operation was successful
* @retval !nullptr Operation failed with valid error log
*/
errlHndl_t nodeCommAbusSendMessage(TARGETING::Target* i_pProc,
const uint64_t & i_data,
const uint8_t & i_linkId,
const uint8_t & i_mboxId);
/**
* @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,
uint8_t & o_linkId,
uint8_t & o_mboxId);
/**
* @brief Add FFDC for the target to an error log
*
* @param[in] i_mode Specifies XBUS or ABUS mode
* @param[in] i_pProc Proc Chip Target used to collect info from
* @param[in,out] io_log Error Log to add FFDC to
*
* @return void
*/
void getNodeCommFFDC(node_comm_modes_t i_mode,
TARGETING::Target* i_pProc,
errlHndl_t & io_log);
/**
* @brief Adds a bus callout to the error log by determining the bus and the two
* targets associated with it
*
* @param[in] i_mode Specifies XBUS or ABUS mode
* @param[in] i_pProc Proc Chip Target used to collect info from
* Can't be nullptr
* @param[in] i_linkId Link ID associated with i_pProc
* @param[in,out] io_log Error Log to add FFDC to
* @param[in] i_priority Optional: Callout Priority (defaulted to HIGH)
*
* @return void
*/
void addNodeCommBusCallout(
node_comm_modes_t i_mode,
TARGETING::Target* i_pProc,
uint8_t & i_linkId,
errlHndl_t & io_log,
HWAS::callOutPriority i_priority = HWAS::SRCI_PRIORITY_HIGH);
} // end NODECOMM namespace
} // end SECUREBOOT namespace
#endif // End __NODE_COMM_H
|