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
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
|
// $Id: gpe_scom.pS,v 1.2 2013/12/13 23:04:33 bcbrock Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/gpe_scom.pS,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------
/// \file gpe_scom.pS
/// \brief Generic SCOM procedures for PORE-GPE
.nolist
#include "ssx.h"
#include "pgas.h"
#include "pgp_config.h"
#include "gpe.h"
#include "gpe_pba.h"
#include "gpe_scom.h"
.list
.oci
.text.pore
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Common Routines
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gsWait
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// The wait loop is implemented as a decrement and branch guaranteed
// to hit in the I-cache. This is used both by gpe_scom_centaur() and
// gpe_scom_p8().
gsWait:
ld D0, SCOM_LIST_DATA, A1
braz D0, gsWaitDone
bra gsWaitLoop
.set PORE_INSTRUCTION_BUFFER_SIZE, 8 # Should be global?
.balign PORE_INSTRUCTION_BUFFER_SIZE
gsWaitLoop:
subs D0, D0, 1
branz D0, gsWaitLoop
gsWaitDone:
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gsTod
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gsTod:
lpcs P0, TOD_VALUE_REG
ld D0, TOD_VALUE_REG, P0
std D0, SCOM_LIST_DATA, A1
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gpe_scom_centaur
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gpe_scom_centaur() has 2 entry points: The first, gpe_scom_centaur(), is for
// the "normal" case that the job is kicked off by the async drivers. The
// second, _gpe_scom_centaur() is for use as a subroutine call.
// Implementation note: Correctness requires that gpe_scom_centaur() maintins
// strict control over the PBA slave as the command list is processed. At
// entry the slave is reset, and then set up to do the cache-inibited partial
// writes used for Centaur inband SCOM. Prior to every access the extended
// address portion of the slave control register needs to be modified as it
// contains part of the address that actually goes out on the PowerBus. For
// reads there is no issue with setting the extended address at any
// time. Since cache-inhibited partial reads are not prefetched, once a read
// completes to the GPE the extended address is no longer in play. This is
// not the case for writes. Just because a write completes on the OCI does not
// mean that the write has completed at Centaur, and it is possible that
// modifying the extended address before the write completes at Centaur can
// cause a write to be corrrupted. The means that in general we need to reset
// the slave prior to modifying the extended address to guarantee that any
// outstanding write has made it to Centaur. As a run-time optimization we
// only reset the slave after doing write operations.
// At entry (gpe_scom_centaur):
//
// ETR : Contains a pointer to the GpeScomParms structure to interpret.
//
// At entry (_gpe_scom_centaur):
//
// A0 : Contains a pointer to the GpeScomParms structure to interpret.
//
// The caller should assume that all register state is destroyed by
// calling _gpe_scom_centaur
.macro gscExit
la A0, gscCalledAsSubroutine
ld D0, 0, A0
braz D0, 4723948f
ret
4723948:
halt
.endm
.global gpe_scom_centaur
.global _gpe_scom_centaur
gpe_scom_centaur:
mr D0, ETR
ls D1, 0
bra gpe_scom_centaur_begin
_gpe_scom_centaur:
mr D0, A0
ls D1, 1
gpe_scom_centaur_begin:
la A0, gscParameters
std D0, 0, A0
la A0, gscCalledAsSubroutine
std D1, 0, A0
mr A1, D0
// Establish the "invalid argument" return code and check that the
// global centaur configuration is valid and the number of entries is
// non-zero and the pointer to the scomList is non-zero.
la A0, G_centaurConfiguration
ls D0, GPE_SCOM_INVALID_ARGUMENT
gpe_scom_parms_set_rc D1, D0
ls D0, -1
gpe_scom_parms_set_error_index D1, D0
std D1, GPE_SCOM_PARMS_RC_ERROR_INDEX, A1
ld D0, CENTAUR_CONFIGURATION_CONFIG_RC, A0
braz D0, 1f
gscExit # Configuration RC != 0 (Structure is invalid)
1:
ld D0, GPE_SCOM_PARMS_ENTRIES_OPTIONS, A1
gpe_scom_parms_get_entries D1, D0
branz D1, 1f
gscExit # entries == 0
1:
ld D0, GPE_SCOM_PARMS_SCOM_LIST, A1
branz D1, 1f
gscExit # scomList == 0
1:
// Establish the "setup error" return code and error index for the PBA
// Slave reset, then reset the slave.
//
// At entry:
//
// A0 = &G_centaurConfiguration
// A1 = &GpeScomParms
ls D0, GPE_SCOM_SETUP_ERROR
gpe_scom_parms_set_rc D1, D0
ls D0, -1
gpe_scom_parms_set_error_index D1, D0
std D1, GPE_SCOM_PARMS_RC_ERROR_INDEX, A1
adds A0, A0, CENTAUR_CONFIGURATION_SCOM_PARMS
bsr gpe_pba_reset
bsr gpe_pba_setup
// Establish the "procedure died" return code, establish variables
// used during the iteration over the scomList, then begin iteration:
//
// GpeScomParms.[rc, errorIndex]
// CTR : The number of entries left to process.
// A1 : The address of the scomList_t being processed
la A0, gscParameters
ld D0, 0, A0
mr A0, D0
ls D0, GPE_SCOM_DIED
gpe_scom_parms_set_rc D1, D0
ls D0, 0
gpe_scom_parms_set_error_index D1, D0
std D1, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
ld D0, GPE_SCOM_PARMS_SCOM_LIST, A0
mr A1, D0
ld D0, GPE_SCOM_PARMS_ENTRIES_OPTIONS, A0
gpe_scom_parms_get_entries D0, D0
mr CTR, D0
loop gscLoop # We know CTR != 0, so this is a branch to
# gscLoop w/side effect of CTR--
// Loop over the scomList, dispatching the commands.
//
// Loop invariants:
//
// GpeScomParms.entries has the number of entries processed so
// far.
//
// A1 : The address of the scomList_t being processed
//
// CTR : Counting down the entries left to process.
//
// Command dispatch invariants
//
// A1 : Holds the pointer to the scomList being processed
gscLoop:
ld D1, SCOM_LIST_COMMAND, A1
scom_list_get_command_type D0, D1
// Commands listed in rough order of expected use
cmpibraeq D0, gscReadVector, GPE_SCOM_READ_VECTOR
cmpibraeq D0, gscWriteAll, GPE_SCOM_WRITE_ALL
cmpibraeq D0, gscRMWAll, GPE_SCOM_RMW_ALL
cmpibraeq D0, gscRead, GPE_SCOM_READ
cmpibraeq D0, gscSyncAll, GPE_SCOM_CENTAUR_SYNC_ALL
cmpibraeq D0, gscWrite, GPE_SCOM_WRITE
cmpibraeq D0, gscRMW, GPE_SCOM_RMW
cmpibraeq D0, gscSync, GPE_SCOM_CENTAUR_SYNC
cmpibraeq D0, gscTod, GPE_SCOM_TOD
cmpibraeq D0, gscWait, GPE_SCOM_WAIT
cmpibraeq D0, gscContinue, GPE_SCOM_NOP
bra gscInvalidCommand
// Continue the loop. Update the index number and scomList pointer.
gscContinue:
la A0, gscParameters
ld D0, 0, A0
mr A0, D0
ld D0, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
adds D0, D0, 1 # errorIndex is in low-order word
std D0, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
adds A1, A1, SIZEOF_SCOM_LIST_T
loop gscLoop
// We completed successfully. Set the final rc to 0 and halt.
ls D0, 0
std D0, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
gscExit
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscWrite
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Do a single Centaur in-band SCOM write. The actual SCOM write is
// coded as a subroutine for use by the write-all as well.
gscWrite:
ld D0, SCOM_LIST_COMMAND, A1
scom_list_get_instance_number D0, D0
bsr gscScomSetup
branz D0, gscInvalidCentaur
bsr gscWrite1
bsr gscResetSlave
bra gscContinue
gscWrite1:
ld D0, SCOM_LIST_DATA, A1
std D0, 0, A0
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscWriteAll
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// It is simplest here to simply unroll a loop that does the SCOM
// write for all Centaur indices that pass as being valid.
gscWriteAll:
.set __CENTAUR__, 0
.rept PGP_NCENTAUR
ls D0, __CENTAUR__
bsr gscScomSetup
branz D0, 1f
bsr gscWrite1
bsr gscResetSlave
1:
.set __CENTAUR__, __CENTAUR__ + 1
.endr
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscRMW
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Do a single Centaur in-band SCOM read-modify-write. SCOM data is
// ANDed with the inverted mask, then the new data is OR-ed in and
// stored back to SCOM. The actual RMW is coded as a subroutine for
// use by the RMW-all as well.
gscRMW:
ld D0, SCOM_LIST_COMMAND, A1
scom_list_get_instance_number D0, D0
bsr gscScomSetup
branz D0, gscInvalidCentaur
bsr gscRMW1
bsr gscResetSlave
bra gscContinue
gscRMW1:
ld D0, 0, A0
ld D1, SCOM_LIST_MASK, A1
xori D1, D1, 0xffffffffffffffff
and D0, D0, D1
ld D1, SCOM_LIST_DATA, A1
or D0, D0, D1
std D0, 0, A0
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscRMWAll
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// It is simplest here to simply unroll a loop that does the SCOM
// RMW for all Centaur indices that pass as being valid.
gscRMWAll:
.set __CENTAUR__, 0
.rept PGP_NCENTAUR
ls D0, __CENTAUR__
bsr gscScomSetup
branz D0, 1f
bsr gscRMW1
bsr gscResetSlave
1:
.set __CENTAUR__, __CENTAUR__ + 1
.endr
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscRead
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Do a single Centaur in-band SCOM read
gscRead:
ld D0, SCOM_LIST_COMMAND, A1
scom_list_get_instance_number D0, D0
bsr gscScomSetup
branz D0, gscInvalidCentaur
ld D0, 0, A0
std D0, SCOM_LIST_DATA, A1
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscReadVector
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// It is simplest here to simply unroll a loop that does the SCOM
// read for all Centaur indices that pass as being valid.
gscReadVector:
.set __CENTAUR__, 0
.rept PGP_NCENTAUR
ls D0, __CENTAUR__
bsr gscScomSetup
ls D1, __CENTAUR__ * 8 # Byte offset
bsr gscReadVector1
.set __CENTAUR__, __CENTAUR__ + 1
.endr
bra gscContinue
gscReadVector1:
// At entry, A1 points to the scomList_t, and D1 has the index of the
// Centaur being processed. If D0 == 0 then the read is indicated and
// A0 contains the address to dereference to accomplish the read. If
// D0 != 0, then the Centaur is invalid and we'll zero the data.
braz D0, 1f
// No read indicated. Load the data pointer, convert to an indexed
// address and store a 0. We can scratch A0 here.
ld D0, SCOM_LIST_DATA, A1
add D0, D0, D1
mr A0, D0
ls D0, 0
std D0, 0, A0
ret
// A read is indicated. Load the data pointer and convert to an
// indexed address in D1. Then load the SCOM data into D0 and store it
// back at the indexed address.
1:
ld D0, SCOM_LIST_DATA, A1
add D1, D0, D1
ld D0, 0, A0
mr A0, D1
std D0, 0, A0
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscSync
// gscSyncAll
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// These commands only differ in whether the user fills in the mask of
// valid Centaurs or the procedure fills in the mask of valid Centaurs
// from the global configuration. The extended address needed for the
// sync is stored in the global data structure, and it is only
// necessary to update the slave and store to the base address of the
// PBA BAR to accomplish the SYNC.
gscSync:
bsr gscSyncSetup
ld D0, SCOM_LIST_DATA, A1
bra gscSyncContinue
gscSyncAll:
bsr gscSyncSetup
la A0, G_centaurConfiguration
ld D0, CENTAUR_CONFIGURATION_CONFIG, A0
left_justify_centaur_config D0
ld D1, SCOM_LIST_DATA, A1
or D0, D0, D1
bra gscSyncContinue
// To set up the SYNC we only have to update the extended address
// field (bits 35:48) of the slave control register from the slave
// control register image held in the G_centaurConfiguration. We can't
// destroy A1 so it's a little tedious as we have to load the slave
// control register address twice.
gscSyncSetup:
la A0, G_centaurConfiguration
ld D1, \
(CENTAUR_CONFIGURATION_SCOM_PARMS + \
GPEPBAPARMS_SLVCTL_ADDRESS), \
A0
mr A0, D1
ld D0, 0, A0
la A0, G_centaurConfiguration
ld D1, CENTAUR_CONFIGURATION_SYNC_SLAVE_CONTROL, A0
rldimi D0, D1, 0, 35, 48
la A0, G_centaurConfiguration
ld D1, \
(CENTAUR_CONFIGURATION_SCOM_PARMS + \
GPEPBAPARMS_SLVCTL_ADDRESS), \
A0
mr A0, D1
std D0, 0, A0
ret
// Once it's set up, simply issue a store to complete the sync. The
// caller has placed the correct data in D0.
gscSyncContinue:
la A0, (PBA_BAR_CENTAUR << 28)
std D0, 0, A0
bsr gscResetSlave
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscWait
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gscWait:
bsr gsWait
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscTod
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gscTod:
bsr gsTod
bra gscContinue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscScomSetup
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// At entry:
//
// A1 : The address of the scomList_t being processed
// D0 : The Centaur instance number to set up
//
// At exit:
//
// PBA : Programmed to do the SCOM
// A1 : The address of the scomList_t being processed
// A0 : On success, the OCI address to load/store to do the SCOM
// D0 : 0 = Success, otherwise an error code
//
// This routine checks the Centaur instance number for validity. If
// the instance number is valid then the PBA is programmed to access
// the SCOM address held in the scomList_t. This requires
// reprogramming the PBA because part of the SCOM address must be
// stored as the extended address field of the PBA slave control
// register. It is not necessary to reset the PBA slave for each SCOM
// operation. The way SCOM operations are set up they "complete
// immediately" in the PBA so there is no issue with lingering state.
//
// Note: this routine is written this way (separating setup from
// execution) to support the Centaur "multicast" and read-modify-write
// operations. The multicast loop simply tries all Centaur and ignores
// the ones that fail.
gscScomSetup:
// Check the Centaur instance number (D0) for validity.
ls D1, PGP_NCENTAUR
sub D1, D0, D1
tfbult D1, 1f
ls D0, GPE_SCOM_INVALID_ARGUMENT
ret # Centaur instance too big
1:
// Check to make sure the Centaur is configured by testing the base
// address for 0. The instance number is first multiplied by 8 to
// create an array offset.
rotldi D0, D0, 3
la D1, G_centaurConfiguration
adds D1, D1, CENTAUR_CONFIGURATION_BASE_ADDRESS
add D0, D0, D1
mr A0, D0
ld D0, 0, A0
branz D0, 1f
ls D0, GPE_SCOM_INVALID_ARGUMENT
ret # Base address is 0
1:
// We have the Centaur base address in D0, and convert it to the full
// PowerBus address for the inband SCOM. Bit 27 is set to indicate OCC
// (vs. FSP) access. Bit 28 remains 0 to indicate a SCOM (vs. sensor
// cache) access. Bits 29:60 are the SCOM address. (The SCOM address
// is shifted up by 3 bit positions). We need to save A1 to SPRG0 to
// continue from here.
ori D0, D0, 0x0000001000000000
ld D1, SCOM_LIST_COMMAND, A1
scom_list_get_scom D1, D1
rotldi D1, D1, 3
or D0, D0, D1
mr SPRG0, A1
#if 1
la A1, G_gsc_lastScomAddress # Debug
std D0, 0, A1
#endif
// The low-order 27 bits of the PowerBus address are OR-ed with the
// PBA BAR base address and go into A0 as the returned OCI address.
andi D1, D0, 0x7ffffff
ori D1, D1, (PBA_BAR_CENTAUR << 28)
mr A0, D1
// Bits 23:36 of the address go into the extended address field (35:
// 48) of the PBA slave control register by a read-modify-write
// operation. Note: We're using rldimi explicitly here - not an
// extended mnemonic - to save having to justify the data.
la A1, G_centaurConfiguration
ld D1, \
(CENTAUR_CONFIGURATION_SCOM_PARMS + \
GPEPBAPARMS_SLVCTL_ADDRESS), \
A1
mr A1, D1
ld D1, 0, A1
rldimi D1, D0, 64 - (35 - 23), 35, 48
std D1, 0, A1
#if 1
la A1, G_gsc_lastSlaveControl # Debug
std D1, 0, A1
mr D1, A0
la A1, G_gsc_lastOciAddress
std D1, 0, A1
#endif
// Restore A1 to its invariant state, clear D0 to signal success and
// we're out
mr A1, SPRG0
ls D0, 0
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscResetSlave
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Reset the PBA slave after a write. This requires saving and
// restoring A1. To avoid PORE stack overflow we have to inline
// gpe_pba_reset() here. See the file gpe_pba_pgas.pS for comments on
// why the slave reset is written like this.
gscResetSlave:
la A0, gscSaveA1
mr D0, A1
std D0, 0, A0
la A0, G_centaurConfiguration + CENTAUR_CONFIGURATION_SCOM_PARMS
bra gscGpePbaReset
.balign 128
gscGpePbaReset:
la A1, PBA_SLVRST
ld D0, GPEPBAPARMS_SLVRST, A0
std D0, 0, A1
ld D0, GPEPBAPARMS_SLVRST_IN_PROGRESS, A0
ld D1, 0, A1
and D0, D0, D1
branz D0, gscGpePbaReset
la A0, gscSaveA1
ld D0, 0, A0
mr A1, D0
ret
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gscInvalidCommand
// gscInvalidCentaur
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Set the rc field. The errorIndex has already been set.
gscInvalidCommand:
ls D1, GPE_SCOM_INVALID_COMMAND
bra 1f
gscInvalidCentaur:
ls D1, GPE_SCOM_INVALID_CENTAUR
1:
la A0, gscParameters
ld D0, 0, A0
mr A0, D0
ld D0, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
gpe_scom_parms_set_rc D0, D1
std D0, GPE_SCOM_PARMS_RC_ERROR_INDEX, A0
gscExit
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// gpe_scom_centaur Global Data
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.data.pore
// Set to 0/1 when gpe_scom_centaur() is called via
// gpe_scom_centaur (ASYNC) / _gpe_scom_centaur (Subroutine)
gscCalledAsSubroutine:
.quad 0
// Used to store the parameter block pointer
gscParameters:
.quad 0
// Used to store A1 during the inner loop when we need to reset the
// slave after a write
gscSaveA1:
.quad 0
// Debug only, the last values computed by gscScomSetup.
.global G_gsc_lastSlaveControl
G_gsc_lastSlaveControl:
.quad 0
.global G_gsc_lastScomAddress
G_gsc_lastScomAddress:
.quad 0
.global G_gsc_lastOciAddress
G_gsc_lastOciAddress:
.quad 0
|