This repository has been archived by the owner on Jun 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
gi_impl.h
351 lines (314 loc) · 13.5 KB
/
gi_impl.h
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
/* begin_generated_IBM_copyright_prolog */
/* */
/* This is an automatically generated copyright prolog. */
/* After initializing, DO NOT MODIFY OR MOVE */
/* ================================================================ */
/* */
/* Licensed Materials - Property of IBM */
/* */
/* Blue Gene/Q */
/* */
/* (C) Copyright IBM Corp. 2010, 2012 */
/* */
/* US Government Users Restricted Rights - */
/* Use, duplication or disclosure restricted */
/* by GSA ADP Schedule Contract with IBM Corp. */
/* */
/* This software is available to you under the */
/* Eclipse Public License (EPL). */
/* */
/* ================================================================ */
/* */
/* end_generated_IBM_copyright_prolog */
#ifndef _KERNEL_CL_GI_IMPL_H_
#define _KERNEL_CL_GI_IMPL_H_
// CL-specific includes
#include "cl_debug.h"
#include "cl_mu.h" // CL-specific support code for interfacing MUFS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
static int open_gi_cr_file(uint32_t id, int flags)
{
char filename[25];
memset(filename, 0, sizeof(filename));
snprintf(filename, sizeof(filename), "/mu/classroute/gi_%02u", id);
return open(filename, flags);
}
/**
* \file CL gi_impl.h
*
* \brief C Header File containing implementation of the Global
* Interrupt SPIs in CL
*
*/
#include <hwi/include/common/compiler_support.h>
#include <hwi/include/bqc/MU_Macros.h>
#include <hwi/include/bqc/nd_500_dcr.h>
#include <spi/include/mu/Util.h>
#ifndef _KERNEL_GI_CLASS_ROUTE_A_E_IO_BITS
#define _KERNEL_GI_CLASS_ROUTE_A_E_IO_BITS ( BGQ_CLASS_LINK_AM | \
BGQ_CLASS_LINK_AP | \
BGQ_CLASS_LINK_BM | \
BGQ_CLASS_LINK_BP | \
BGQ_CLASS_LINK_CM | \
BGQ_CLASS_LINK_CP | \
BGQ_CLASS_LINK_DM | \
BGQ_CLASS_LINK_DP | \
BGQ_CLASS_LINK_EM | \
BGQ_CLASS_LINK_EP | \
BGQ_CLASS_LINK_IO );
#endif
/**
* \brief Query the Global Interrupt Class Routes that are Free to be Allocated
*
* Returns the Ids of the global interrupt class routes that are "free" to be
* allocated.
*
* The caller of this function is responsible for ensuring that this is an
* atomic operation that does not conflict with allocations and deallocations
* of global interrupt class routes. This can be done by obtaining a node-scoped
* lock, if necessary.
*
* \param[out] nClassRoutes Pointer to a single uint32_t where the number of free
* global interrupt class routes is returned
* (0 through BGQ_GI_CLASS_MAX_CLASSROUTES).
*
* \param[out] classRouteIds Pointer to BGQ_GI_CLASS_MAX_CLASSROUTES uint32_t's
* where the free global interrupt class route Ids are
* returned. Each returned Id has a value 0 through
* BGQ_GI_CLASS_MAX_CLASSROUTES-1.
*
* \param[in] sizeOfClassRouteIds The number of bytes pointed to by classRouteIds.
* This is used to verify that there is enough
* storage pointed to by classRouteIds to hold all
* of the global interrupt class route Ids that are
* free. If there is not enough storage, as many
* free Ids as possible are returned.
*
* \retval 0 Successful. nClassRoutes global interrupt class route Ids are
* returned in classRouteIds.
* \retval errno Unsuccessful.
*
*/
__INLINE__
int32_t Kernel_QueryGlobalInterruptClassRoutes ( uint32_t * nClassRoutes,
uint32_t * classRouteIds,
size_t sizeOfClassRouteIds )
{
int32_t rc=0;
int query_fd;
query_fd = open("/mu/classroute/gi_query", O_RDONLY);
if(query_fd == -1) {
CL_ERROR("error %d opening gi_query file %s\n", errno, strerror(errno));
return EIO;
}
rc = read(query_fd, classRouteIds, sizeOfClassRouteIds);
if(rc == -1) {
CL_ERROR("error %d reading gi_query file: %s.\n", errno, strerror(errno));
return EIO;
}
// read delivers all unallocated class route ids -> number of bytes read
// indicates the number of unallocated class routes
*nClassRoutes = rc / sizeof(uint32_t);
return 0;
}
/**
* \brief Allocate a Global Interrupt Class Route Id
*
* The specified global interrupt class route Id is allocated (reserved) for
* use, if it is not already allocated.
*
* The caller of this function is responsible for ensuring that this is an
* atomic operation that does not conflict with allocations and deallocations
* of global interrupt class routes. This can be done by obtaining a node-scoped
* lock, if necessary.
*
* \param [in] id The identifier of the global interrupt class route
* (0 through BGQ_GI_CLASS_MAX_CLASSROUTES-1).
*
* \param [in] attributes Pointer to a structure containing attributes
* for the global interrupt class route being
* allocated. If the default attributes are
* desired (refer to the structure definition
* for the default values), a NULL pointer may be
* specified.
*
* \retval 0 Successful. Global Interrupt class route was successfully
* allocated.
* \retval errno Unsuccessful. The ID is already allocated.
*
*/
__INLINE__
int32_t Kernel_AllocateGlobalInterruptClassRoute (
uint32_t id,
Kernel_GlobalInterruptClassRouteAttributes_t *attributes )
{
int fd;
// check parameters
if(id >= BGQ_GI_CLASS_MAX_CLASSROUTES)
return EINVAL;
// open file
fd = open_gi_cr_file(id, O_RDWR);
// save fd if != -1
if(fd == -1) {
return errno;
} else {
set_gi_cr_fd( id, fd );
return 0;
}
}
/**
* \brief Set a Global Interrupt Class Route Configuration
*
* There are 32 bits in a global interrupt class route configuration. This
* interface sets those bits for a specified global interrupt class route Id.
*
* The caller of this function is responsible for ensuring that this is an
* atomic operation that does not conflict with setting global interrupt
* class routes on the same node in another thread or process. This can be
* done by obtaining a node-scoped lock, if necessary.
*
* The following consistency checks are performed:
* 1. The class route output must have at most one bit set.
* 2. The class route output local bit must be 0.
* 3. If a class route output bit is 1, the corresponding input bit cannot be 1.
* This is further explained as follows:
* - Let v_in(i) and v_out(i) be the 11 bits corresponding to A-,..., E+,IO in
* the class route input and output. Ignore the local bit.
* - If (v_in(i) & v_out(i)) !=0 then input and output share a link, which is
* invalid.
* 4. Class route i and class route i+8 cannot share any links.
* This is further explained as follows:
* - Let v_in(i) and v_out(i) be the 11 bits corresponding to A-,..., E+,IO in
* the class route input and output. Ignore the local bit.
* - if ( ( v_in(i) | v_out(i) ) & (v_in(i+8) | v_out(i+8)) != 0 then
* class routes i and i+8 share links, which is invalid.
*
* \param [in] id The identifier of the global interrupt class route
* (0 through BGQ_GI_CLASS_MAX_CLASSROUTES-1).
*
* \param [in] cr Pointer to the class route structure containing the
* global interrupt class route configuration to be set.
*
* \retval 0 Successful. Collective class route was successfully configured.
* \retval 1 Unsuccessful. The class route output has more than 1 bit set.
* \retval 2 Unsuccessful. The class route output local bit must be 0.
* \retval 3 Unsuccessful. The same bit is set in both input and output.
* \retval 4 Unsuccessful. Class routes i and i+8 share links.
*
*/
__INLINE__
int32_t Kernel_SetGlobalInterruptClassRoute ( int32_t id,
ClassRoute_t *cr )
{
int rc;
if( ! have_gi_cr_fd(id) )
return EINVAL;
rc = write(get_gi_cr_fd(id), cr, sizeof(*cr));
if(rc != sizeof(*cr))
return errno;
else
return 0;
}
/**
* \brief De-allocate a Global Interrupt Class Route Id
*
* The specified global interrupt class route Id is de-allocated, such that it
* is available to be allocated again.
*
* \param [in] id The identifier of the global interrupt class route
* (0 through BGQ_GI_CLASS_MAX_CLASSROUTES-1).
*
* \retval 0 Successful. Global Interrupt class route was successfully
* de-allocated.
* \retval errno Unsuccessful.
*
*/
__INLINE__
int32_t Kernel_DeallocateGlobalInterruptClassRoute ( int32_t id )
{
int rc;
if(!have_gi_cr_fd(id))
return EINVAL;
rc = close( get_gi_cr_fd(id) );
set_gi_cr_fd(id, -1);
return rc;
}
/**
* \brief Configure Interrupts for a Global Interrupt Class Route
*
* For each global interrupt class route, there are three global interrupts
* that can be individually enabled to cause an interrupt.
*
* The caller of this function is responsible for ensuring that this is an
* atomic operation that does not conflict with configuring global interrupts
* for other class routes. This can be done by obtaining a node-scoped
* lock, if necessary.
*
* \param [in] id The identifier of the global interrupt class route
* (0 through BGQ_GI_CLASS_MAX_CLASSROUTES-1).
*
* \param [in] giId Global Interrupt Id. Within each class route, there can
* be three individual global interrupts. This specifies
* which global interrupt is to have its interrupt
* enabled (0 ... BGQ_GI_CLASS_MAX_GI_PER_CLASSROUTE-1).
*
* \param [in] interruptFlag Indicator of whether the interrupt should be
* enabled (KERNEL_GI_INTERRUPT_FLAG_ENABLE) or
* disabled (KERNEL_GI_INTERRUPT_FLAG_DISABLE).
*
* \retval 0 Successful. Global Interrupt class route was successfully
* configured for interrupts.
* \retval errno Unsuccessful.
*/
#if !(defined __FUSEDOS__) // FUSEDOS
__INLINE__
int32_t Kernel_ConfigureGIInterrupts (
uint32_t id,
uint32_t giId,
Kernel_GIInterruptFlag_t interruptFlag )
{
return ENOSYS;
}
#endif // FUSEDOS
/**
* \brief Get Global Barrier User Class Route Id
*
* Get the class route Id associated with a global barrier. This class route...
* - Is a global interrupt class route.
* - Is a "user" class route for use by user mode applications.
* - Includes all of the nodes in the job.
* - Has an initialized global interrupt barrier associated with it. This
* initialization takes place before the user mode application receives
* control.
*
* Usage Notes:
* - Common usage is for a "master process" on each node to call this function
* to obtain this class route Id.
* - The master process calls MUSPI_GIBarrierInit() to initialize software
* structures to use the barrier associated with that class route. The
* kernel has previously called MUSPI_GIBarrierInitMU() to initialize the
* MU for the barrier.
* - When processes on the node need to use the GIBarrier, they perform a
* local barrier first, then the master process enters the GIBarrier and polls
* for its completion, and finally, all processes perform the local barrier
* again.
*
* \param [out] classRouteId Pointer to a uint32_t where the Id of the user
* global interrupt class route that includes all
* nodes in the job is returned.
*
* \retval 0 Successful.
* \retval errno Error.
*/
#if !(defined __FUSEDOS__) // FUSEDOS
__INLINE__
int32_t Kernel_GetGlobalBarrierUserClassRouteId ( uint32_t *classRouteId )
{
return ENOSYS; /* Firmware does not initialize this class route. Only the
* kernels do. */
}
#endif // FUSEDOS
#endif /* _KERNEL_FIRMWARE_GI_IMPL_H_ */