summaryrefslogtreecommitdiffstats
path: root/src/lib/gpe_scom.h
blob: 3f8f26ee3a88b310a7a456bda1479bbd232b86e5 (plain)
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
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
#ifndef __GPE_SCOM_H__
#define __GPE_SCOM_H__

// $Id: gpe_scom.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/gpe_scom.h,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------

/// \file gpe_scom.h
/// \brief Generic SCOM procedures for PORE-GPE
///
/// We provide 2 generic SCOM procedures for PORE-GPE, one for P8 SCOMs and
/// another for Centaur SCOMS. The setup and control of the procedures is
/// roughly modeled after the way the simple SCOM-ing programs were described
/// and implemented by the P7 OCA unit. This facility was written primarily to
/// support SCOM-ing Centaur from OCC (which requires a complex setup),
/// however for some core applications it may also be simpler to use a generic
/// procedure rather than creating a custom GPE program to read/write P8 SCOM
/// registers.
///
/// SCOM programs are set up and controlled through a GpeScomParms
/// structure. This structure contains overall control and status information,
/// as well as a pointer to an array of scomList_t structures which decribes
/// the program. Each entry of the scomList_t describes one of several
/// operations that can be performed on a SCOM address including read, write,
/// and read-modify-write. Special control-only entries are also supported
/// including a NOP, a programmable wait delay, timestamping with the TOD and
/// special "SYNC" commands for Centaur. For more on the commands and their
/// actions please see \ref gpe_scom_commands.
///
/// Each scomList_t entry also includes a data field and a mask field. The
/// data field contains the data to write for SCOM writes and
/// read-modify-writes, holds the data returned for SCOM reads, or contains a
/// pointer to a data vector for vector commands. The mask is used in the case
/// of read-modify-write to indicate which bits of the SCOM to modify. Control
/// commands may also interpret these fields in different ways.


#ifndef __ASSEMBLER__

/// A SCOM command descriptor for gpe_scom_centaur amd gpe_scom_p8.
///
/// For an introduction to the use of this structure and the procedures that
/// use please see the commants for the file gpe_scom.h
///
/// The \a scom field is the full 32-bit SCOM address of the targeted SCOM,
/// initialized by the caller.  SCOM addresses for P8 core SCOMs can be
/// created from the chiplet-0 address using the macro
/// CORE_CHIPLET_ADDRESS(). Multicast addresses for P8 can be generated using
/// the macro MC_ADDRESS(). The notions of internal "chiplets" and "multicast"
/// are not supported for Centaur SCOM addreses, so for Centaur this is always
/// a simple SCOM address. The procedure gpe_scom_centaur() does support an
/// iterative notion of multicast however. Some special control commands do
/// not use this field at all; see \ref gpe_scom_commands.
///
/// The \a errorFlags field contains error status associated with the
/// (attempted) SCOM access.  This field is set by the procedure. For futher
/// informaton on error handling please see each individual procedure.
///
/// The \a instanceNumber field is currently only used by
/// gpe_scom_centaur(). For further details please see the documentation for
/// gpe_scom_centaur(). 
///
/// The \a commandType field is initialized by the caller. For command
/// documentation see \ref gpe_scom_commands and the individual procedures.
///
/// The \a data field is used to hold write data for SCOM write and
/// read-modify-write commands (including the "all" forms), contains the
/// returned read data for scalar SCOM read commands, and contains a pointer
/// to a data vector for vector commands. Other commands may also use the \a
/// data field for other purposes as documented with each command.
///
/// The \a mask field contains a positive bit mask used to identify the fields
/// to update for SCOM read-modify-write. Other commands may also use the \a
/// mask field for other purposes as documented with each command.
///
/// \note Because this structure is read and written by the GPE engine it is
/// strongly recommended to allocate instances of this structure in
/// non-cacheable data sections, with the caveat that data structures assigned
/// to non-default data sections must always be initialized. For example:
///
/// \code
///
/// static scomList_t S_scomList[10] 
///     SECTION_ATTRIBUTE(".noncacheable") = {0};
///
/// \endcode

typedef struct {
    union
    {
        struct {
            uint32_t scom;
            uint8_t reserved;
            uint8_t errorFlags;
            uint8_t instanceNumber;
            uint8_t commandType;
        };
        uint64_t command;
    };
    uint64_t mask;
    union
    {
        uint64_t data;
        struct {
            uint32_t unused;
            uint64_t* pData;
        };
    };
}  scomList_t;

#else // __ASSEMBLER__

        // scomList_t structure offsets

        .set    SCOM_LIST_COMMAND,  0x0
        .set    SCOM_LIST_MASK,     0x8
        .set    SCOM_LIST_DATA,     0x10
        .set    SIZEOF_SCOM_LIST_T, 0x18

        // PGAS macros to extract fields of the scomList_t command. The source
        // and target must be data registers, and they can be the same data
        // register.

        .macro  scom_list_get_scom, target:req, source:req
        extrdi  \target, \source, 32, 0
        .endm

        .macro  scom_list_get_instance_number, target:req, source:req
        extrdi  \target, \source, 8, 48
        .endm

        .macro  scom_list_get_command_type, target:req, source:req
        extrdi  \target, \source, 8, 56
        .endm

        // PGAS macros to update fields of the scomList_t command. The source
        // and target must be different data registers. The target is the
        // current value and is updated with the new field held
        // right-justified in the source. The source register is effectively
        // destroyed by these operations.

        .macro  scom_list_set_error_flags, target:req, source:req
        insrdi  \target, \source, 8, 40
        .endm

        .macro  scom_list_set_instance_number, target:req, source:req
        insrdi  \target, \source, 8, 48
        .endm

#endif // __ASSEMBLER__

/// \defgroup gpe_scom_commands GPE SCOM Procedure Commands
///
/// \note Command 0 is not defined on purpose to trap errors.
/// @{

/// No operation
#define GPE_SCOM_NOP 1

/// Read from SCOM, depositing read data into the \a data field of the
/// scomList_t.
#define GPE_SCOM_READ 2

/// Write to SCOM, taking write data from the \a data field of the scomList_t.
#define GPE_SCOM_WRITE 3

/// Read-Modify-Write.
///
/// This operation first reads the SCOM. Bits under the \a mask field of the
/// scomList_t are then cleared in the read data. The masked read data is then
/// ORed with the contents of the \a data field of the scomList_t and the
/// result is written back to the SCOM address.
///
/// \note This command \e does \e not apply the mask to the data from the \a
/// data field of the scomList_t. The caller should do this (if necessary)
/// when setting up the scomList_t.
///
/// \note The procedures do not provide a way to distinguish errors that may
/// have occurred on the initial read vs. those that may have occurred on the
/// subsequenct write. 
#define GPE_SCOM_RMW 4

/// For gpe_scom_centaur(), the \a data field of the scomList_t contains a
/// 32-bit pointer (cast to a uint64_t) to an array of PGP_NCENTAUR uint64_t
/// values. SCOM read data for each configured Centaur (MCS) is deposited in
/// this array.  Array entries for unconfigured Centaur are zeroed.
#define GPE_SCOM_READ_VECTOR 5

/// For gpe_scom_centaur(), write the \a data field of the scomList_t to
/// all configured Centaur. Currently unsupported for gpe_scom_p8().
#define GPE_SCOM_WRITE_ALL 6

/// For gpe_scom_centaur(), perform read-modify write for all configured
/// Centaur. Currently unsupported for gpe_scom_p8().
#define GPE_SCOM_RMW_ALL 7

/// Programmable wait delay
///
/// This command simply waits for an interval of time specified by the \a data
/// field of the scomList_t. Use the macro GPE_SCOM_WAIT_DELAY() to convert
/// SSX (OCC timebase) ticks into the correct units for this command.  For
/// example use GPE_SCOM_WAIT_DELAY(SSX_MILLISECONDS(10)) to wait 10 ms.
///
/// \note This operation blocks the GPE from completing any other work until
/// the delay is finished.
///
/// \note This time delay can not be implemented with extreme precision due to
/// the lack of a programmable wait delay in the PORE architecture, plus
/// procedure overhead, bus and bus interface contention, etc. For
/// applications requiring extremely precise timing it will be best to code
/// those by hand in PORE assembler and run them in a dedicated lab-only
/// setting.
#define GPE_SCOM_WAIT 8

/// Issue a generic Centaur SYNC
///
/// This command is only valid for gpe_scom_centaur(). This command creates
/// and issues a generic SYNC command to Centaur.  The caller is completely
/// responsible for creating the contents of the data packet sent as part of
/// the Centaur SYNC. The data packet is taken verbatim from the \a data field
/// of the scomList_t, and sent to the MCS designated as the SYNC MCS in the
/// global G_centaurConfiguration.  For further details see the comments with
/// the procedure gpe_scom_centaur() and the CentaurConfiguration structure.
#define GPE_SCOM_CENTAUR_SYNC 9

/// Issue a Centaur SYNC to all configured Centaur
///
/// This command is only valid for gpe_scom_centaur(). This command creates
/// and issues a SYNC command to all configured Centaur. The data packet is
/// taken from the \a data field of the scomList_t, and sent to the MCS
/// designated as the SYNC MCS in the global G_centaurConfiguration. The
/// caller is responsible for setting the SYNC command bits (bits 8:N); The
/// procedure will fill bits 0:7 with a mask of all configured Centaur.  For
/// further details see the comments with the procedure gpe_scom_centaur() and
/// the CentaurConfiguration structure.
#define GPE_SCOM_CENTAUR_SYNC_ALL 10

/// Read the TOD clock
///
/// This command reads the TOD clock and deposits the value into the \a data
/// field of the scomList_t.
#define GPE_SCOM_TOD 11

/// @}


#ifndef __ASSEMBLER__

/// \defgroup centaur_sync_commands Centaur SYNC Command Bits
///
/// The Centaur SYNC command is an 8-byte word written to a specific in-band
/// address. SYNC commands are generated by the gpe_scom_centaur() procedure
/// in response to the GPE_SCOM_CENTAUR_SYNC and GPE_SCOM_CENTAUR_SYNC_ALL
/// commands (which see).
///
/// \note From the MCS Unit Workbook: Note that only the N/M Throttle sync
/// command will be used operationally in P-series, although if will be
/// possible to test all the sync commands in P-series lab testing. Z-series
/// will use all specified sync command types. ... Valid combinations of bits
/// (8:15) are: b00000000, bVVVVVV0V, and b00000010, where V = 0 or 1.
///
/// @{

#define CENTAUR_GENERATE_REFRESH_COUNTER_SYNC    0x0080000000000000ull
#define CENTAUR_RESET_CALIBRATION_COUNTER_1_SYNC 0x0040000000000000ull
#define CENTAUR_RESET_CALIBRATION_COUNTER_2_SYNC 0x0020000000000000ull
#define CENTAUR_RESET_CALIBRATION_COUNTER_3_SYNC 0x0010000000000000ull
#define CENTAUR_RESET_N_M_THROTTLE_COUNTER_SYNC  0x0008000000000000ull
#define CENTAUR_RESET_MB_TIMEBASE_SYNC           0x0004000000000000ull
#define CENTAUR_SUPER_SYNC                       0x0002000000000000ull
#define CENTAUR_MYSTERY_SYNC                     0x0001000000000000ull

/// \todo Figure out what is the "mystery sync"

/// @}


/// Convert an SsxInterval to a delay specification for gpe_scom_*()

// Yes, Virginia, the PORE engine takes 20 cycles to decrement and branch :(
#define GPE_SCOM_WAIT_DELAY(x) ((x) / 20)


/// Parameters for gpe_scom_centaur() and gpe_scom_p8().
///
/// A pointer to an initialized GpeScomParms structure is passed as the
/// parameter to the GPE procedures gpe_scom_centaur() and gpe_scom_p8.
///
/// \note Because this structure is read and written by the GPE engine it is
/// strongly recommended to allocate instances of this structure in
/// non-cacheable data sections, with the caveat that data structures assigned
/// to non-default data sections must always be initialized. For example:
///
/// \code
///
/// static GpeScomParms S_scomParms 
///     SECTION_ATTRIBUTE(".noncacheable") = {0};
///
/// \endcode

typedef struct {

    /// Input: The SCOM list
    ///
    /// This is a right-justfied pointer to an array of scomList_t structures
    /// describing the sequence of commands to execute.
    uint64_t scomList;

    /// Input: The number of entries in the scomList.
    ///
    /// \note It is considered an error if \a entries is 0, under the
    /// assumption that the caller must have neglected to initialize the
    /// structure.
    uint32_t entries;

    /// Input: Procedure options
    ///
    /// An OR-mask of option flags; See \ref gpe_scom_options;
    uint32_t options;

    /// Output: The procedure return code
    ///
    /// This field will contain 0 in the event of a successful return, and a
    /// non-zero value in the event of an error. See \ref gpe_scom_rc for
    /// documentation of the possible return codes.
    uint32_t rc;

    /// Output: The index of the entry that failed
    ///
    /// In the event that \a rc != 0, this field will contain the 0-based
    /// index of the \a scomList entry that was being processed at the time of
    /// the failure, or -1 for failures associated with the parameters or
    /// setup of the procedure.
    int32_t errorIndex;

} GpeScomParms;

#else // __ASSEMBLER__

        // Offsets into the GpeScomParms structure

        .set    GPE_SCOM_PARMS_SCOM_LIST,       0x00
        .set    GPE_SCOM_PARMS_ENTRIES_OPTIONS, 0x08
        .set    GPE_SCOM_PARMS_RC_ERROR_INDEX,  0x10

        // PGAS macros to extract fields of the GpeScomParms. The source
        // and target must be data registers, and they can be the same data
        // register.

        .macro  gpe_scom_parms_get_entries, target:req, source:req
        extrdi  \target, \source, 32, 0
        .endm

        .macro  gpe_scom_parms_get_options, target:req, source:req
        extrdi  \target, \source, 32, 32
        .endm

        .macro  gpe_scom_parms_get_rc, target:req, source:req
        extrdi  \target, \source, 32, 0
        .endm

        // PGAS macros to update fields of the GpeScomParms. The source
        // and target must be different data registers. The target is the
        // current value and is updated with the new field held
        // right-justified in the source. The source register is effectively
        // destroyed by these operations.

        .macro  gpe_scom_parms_set_rc, target:req, source:req
       insrdi   \target, \source, 32, 0
        .endm

        .macro  gpe_scom_parms_set_error_index, target:req, source:req
        insrdi  \target, \source, 32, 32
        .endm

#endif // __ASSEMBLER__

        
/// \defgroup gpe_scom_rc Return Codes From GPE SCOM Procedures
///
/// @{

/// Successful completion of a GPE SCOM program
#define GPE_SCOM_SUCCESS 0

/// An error occurred during setup of the PBA for Centaur access. If this
/// error code is returned then the \a errorIndex field of the GpeScomParms
/// structure will be set to -1.
#define GPE_SCOM_SETUP_ERROR 1

/// One of the fields of the GpeScomParms structure is invalid. In the case of
/// gpe_scom_centaur(), this code may also be returned if there is a problem
/// with the global structure G_centaurConfiguration.  If this error code is
/// returned then the \a errorIndex field of the GpeScomParms structure will
/// be set to -1 if the error occurred before command processing begins. 
#define GPE_SCOM_INVALID_ARGUMENT 2

/// The procedure died. Since GPE procedures do not trap errors by default
/// they will typically die on the first hardware-detected error, and GPE
/// error recovery procedures will clean up the failed job. If this error code
/// is returned then the \a errorIndex field of the GpeScomParms structure
/// will indicate the \a scomList entry being processed at the time of the
/// failure.
#define GPE_SCOM_DIED 3

/// The \a commandType field of the scomList_t was not valid for the procedure.
/// When this error is signalled then the \a errorIndex field of the
/// GpeScomParms structure contains the index of the failing entry.
#define GPE_SCOM_INVALID_COMMAND 4

/// Signalled only by gpe_scom_centaur(), the \a instanceNumber field of the
/// scomList_t did not index a valid (configured) Centaur. This error is only
/// signalled by the GPE_SCOM_READ, GPE_SCOM_WRITE and GPE_SCOM_RMW commands
/// that require a valid Centaur to be specified. When this error is signalled
/// then the \a errorIndex field of the GpeScomParms structure contains the
/// index of the failing entry.
#define GPE_SCOM_INVALID_CENTAUR 5

/// @}


/// Execute a SCOM program for Centaur SCOMs
///
/// \param[in,out] io_parms A pointer to an initialized GpeScomParms
/// structure. Since this structure is used both for input of parameterization
/// and output of return codes it is imperitive that this structure is
/// allocated in non-cacheable memory to avoid cache-related bugs.  See the
/// documentation for the fields of GpeScomParms for more information.
///
/// gpe_scom_centaur() is a GPE program that takes a pointer to an initialized
/// GpeScomParms structure as input and executes the list of SCOMs and other
/// commands. Return codes are returned in the GpeScomParms.
///
/// The following notes relate to the fields of the scomList_t structure when
/// used by gpe_scom_centaur().
///
/// - \a instanceNumber : This field must be set to the index (0 - 7) of the
/// Centaur (MCS) to access for the commands GPE_SCOM_READ, GPE_SCOM_WRITE and
/// GPE_SCOM_RMW. This field is ignored by other commands.
///
/// - \a commandType : gpe_scom_centaur() supports the special command types
/// GPE_SCOM_CENTAUR_SYNC and GPE_CENTAUR_SYNC_ALL as documented in \ref
/// gpe_scom_commands.
///
/// - \a data : The commands GPE_SCOM_CENTAUR_SYNC and
/// GPE_SCOM_CENTAUR_SYNC_ALL require a unique format for the \a data field as
/// documented with the command.
#ifdef DOXYGEN_ONLY
void gpe_scom_centaur(GpeScomParms *io_parms);
#endif

#ifndef __ASSEMBLER__

// Procedure entry points

PoreEntryPoint gpe_scom_centaur;
PoreEntryPoint gpe_scom_p8;

// Debugging symbols

extern uint64_t G_gsc_lastSlaveControl SECTION_ATTRIBUTE(".data.pore");
extern uint64_t G_gsc_lastScomAddress  SECTION_ATTRIBUTE(".data.pore");
extern uint64_t G_gsc_lastOciAddress   SECTION_ATTRIBUTE(".data.pore");

#endif // __ASSEMBLER__

#endif // __GPE_SCOM_H__
OpenPOWER on IntegriCloud