summaryrefslogtreecommitdiffstats
path: root/src/ssx/ppc405/ppc405_context.h
blob: 30193584361260e6c78722d0212611658e0d77b7 (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
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
#ifndef __PPC405_CONTEXT_H__
#define __PPC405_CONTEXT_H__

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

/// \file ppc405_context.h
/// \brief PPC405 Machine and Thread context for SSX

/// \page ppc405_machine_context PPC405 Assembler Macros for SSX Machine
/// Context (Critical Sections)
///
/// \section _ssx_enter_critical \b _ssx_critical_section_enter/exit
///
/// These macro encapsulates the instruction sequences required to enter and
/// exit critical sections, along with the machine context save for later
/// exiting the critical section.
///
/// \arg \c priority Either \c SSX_CRITICAL, \c SSX_NON_CRITICAL or
/// SSX_SUPERCRITICAL (for \c ssx_critical_section_enter). 
///
/// \arg \c ctxreg A register that will hold (holds) the machine context (MSR)
/// prior to entering the critical section (to be restored) for \c
/// _ssx_critical_section_enter (\c _ssx_critical_section_exit).
///
/// \arg \c scrreg A scratch register required for the computation of
/// \c _ssx_critical_section_enter. 
///
/// Forms:
/// 
/// \b _ssx_critical_section_enter \a priority, \a ctxreg, \a scrreg - Enter a
/// critical section \n
/// \b _ssx_critical_section_exit \a ctxreg - Exit a critical section

#ifdef __ASSEMBLER__

        .set    _msr_ee_bit, MSR_EE_BIT
        .set    _msr_ce_bit, MSR_CE_BIT

        .macro  _ssx_critical_section_enter priority, ctxreg, scrreg
        mfmsr   \ctxreg
        .if     ((\priority) == SSX_CRITICAL)
        _clrbit \scrreg, \ctxreg, _msr_ee_bit
        _clrbit \scrreg, \scrreg, _msr_ce_bit
        mtmsr   \scrreg
        .elseif ((\priority) == SSX_SUPERCRITICAL)
        _liwa   \scrreg, (MSR_APE | MSR_WE | MSR_CE | MSR_EE | MSR_ME | MSR_DWE | MSR_DE)
        andc    \scrreg, \ctxreg, \scrreg
        mtmsr   \scrreg
        .elseif ((\priority) == SSX_NONCRITICAL)
        wrteei  0
        .else
        .error  "'priority' was not one of SSX_CRITICAL, SSX_NONCRITICAL or SSX_SUPERCRITICAL"
        .endif
        isync
        .endm

        .macro  _ssx_critical_section_exit ctxreg
        mtmsr   \ctxreg
        isync
        .endm
        
// ****************************************************************************
// SSX context save/restore macros for 32-bit Embedded PowerPC
// ****************************************************************************

// All stack frames are 8-byte aligned in conformance with the EABI.  SSX
// never saves or restores GPR2 or GPR13.  GPR13 is constant in (E)ABI
// applications - the base of the read-write small data area.  GPR2 is
// system-reserved in ABI applications, and is the base for read-only small data
// in EABI applications.

// A fair amount of complexity is involved in handling the non-critical and
// critical interrupt levels, and the emphasis on performance of fast-mode
// interrupt handlers. Several different approaches and philosophies could
// have been implemented - this is only one.  In this implementation
// critical/non-critical interrupt levels are treated more or less the same,
// and the interrupt priority is just that - a kind of preemption priority.
// Critical interrupt handling does have a little less overhead because it
// does not have a thread scheduling step at the end.

// A full context save takes place in 3 or 4 steps.  Thread switches always do
// steps 1, 2 and 3.
// 1. The fast context that is always saved in response to every interrupt;
// 1a. The optional save/update of the kernel context for interrupts. 
// 2. The (volatile - fast) context that is saved if an interrupt handler
//    switches from fast-mode to full-mode.
// 3. The non-volatile context that is saved when a thread is switched out.

// USPRG0 holds the __SsxKernelContext structure (defined in ppc405.h) that
// represents the current kernel context.  The layout is as follows:
//
// Bits   Meaning
// ==============
// 0:7   The critical interrupt count
// 8:15  The non-critical interrupt count
// 16:23 The IRQ currently being processed
// 24    The 'thread_mode' flag
// 25:31 The thread priority of the running thread
//
// When SSX is initialized USPRG0 is initialized to 0.  When thread-mode is
// entered (by ssx_start_threads()) bit 24 is set to 1.  In order to support
// PgP/OCC firmware, once initialized (with ssx_initialize()) SSX can simply
// handle interrupts, reverting back to the non-thread-mode idle loop when
// there's nothing to do.
//      
// Note that it would require a serious error for the interrupt counts to ever
// equal or exceed 2**8 as this would imply runaway reentrancy and stack
// overflow. In fact it is most likely an error if an interrupt handler is
// ever re-entered while active.

// Registers SRR2 and SRR3 are always saved in IRQ context because
// __ssx_irq_fast2full must save the (volatile - fast) context to provide
// working registers before it can look at USPRG0 to determine critical
// vs. non-critical context.  However, when restoring a non-critical interrupt
// or thread these registers need not be restored. SRR2 and SRR3 are never
// saved or restored for thread context switches, because threads always
// operate at noncritical level.

// When MMU protection is enabled, relocation/protection is re-established
// immediately upon entry to the interrupt handler, before any memory
// operations (load/store) take place.  This requires using SPRG0 and SPGR4
// for temporary storage for noncritical/critical handlers respectively in
// accordance with the SSX conventions for SPRGn usage by fast-mode
// interrupts. 

        ## ------------------------------------------------------------
        ## Unused registers for embedded PowerPC
        ## ------------------------------------------------------------

        ## Registers GPR2 and GPR13 are never saved or restored.  In ABI and 
        ## EABI applications these registers are constant.

        .set    UNUSED_GPR2,  0x2 # Dedicated; EABI read-only small data area
        .set    UNUSED_GPR13, 0xd # Dedicated; (E)ABI read-write small data area

        ## ------------------------------------------------------------
        ## Flags for context push/pop
        ## ------------------------------------------------------------

        .set    SSX_THREAD_CONTEXT, 0
        .set    SSX_IRQ_CONTEXT, 1

        ## ------------------------------------------------------------
        ## The SSX fast context layout for Embedded PowerPC
        ## ------------------------------------------------------------

        .set    SSX_FAST_CTX_GPR1,       0x00 # Dedicated; Stack pointer
        .set    SSX_FAST_CTX_HANDLER_LR, 0x04 # Slot for handler to store LR 
        .set    SSX_FAST_CTX_GPR3,       0x08 # Volatile;  Parameter; Return Value
        .set    SSX_FAST_CTX_GPR4,       0x0c # Volatile;  Parameter
        .set    SSX_FAST_CTX_GPR5,       0x10 # Volatile;  Parameter
        .set    SSX_FAST_CTX_GPR6,       0x14 # Volatile;  Parameter
        .set    SSX_FAST_CTX_GPR7,       0x18 # Volatile; Parameter
        .set    SSX_FAST_CTX_CR,         0x1c # Condition register 
        .set    SSX_FAST_CTX_LR,         0x20 # Link register      SPRN 0x008 
        .set    SSX_FAST_CTX_KERNEL_CTX, 0x24 # Saved __SsxKernelContext for IRQ

        .set    SSX_FAST_CTX_SIZE,  0x28  # Must be 8-byte aligned

        ## ------------------------------------------------------------
        ## The SSX (volatile - fast) context layout for Embedded PowerPC
        ## ------------------------------------------------------------

        .set    SSX_VOL_FAST_CTX_GPR1,       0x00 # Dedicated; Stack pointer
        .set    SSX_VOL_FAST_CTX_HANDLER_LR, 0x04 # Slot for handler to store LR
        .set    SSX_VOL_FAST_CTX_GPR0,       0x08 # Volatile;  Language specific
        .set    SSX_VOL_FAST_CTX_GPR8,       0x0c # Volatile;  Parameter
        .set    SSX_VOL_FAST_CTX_GPR9,       0x10 # Volatile;  Parameter
        .set    SSX_VOL_FAST_CTX_GPR10,      0x14 # Volatile;  Parameter
        .set    SSX_VOL_FAST_CTX_GPR11,      0x18 # Volatile
        .set    SSX_VOL_FAST_CTX_GPR12,      0x1c # Volatile
        .set    SSX_VOL_FAST_CTX_XER,        0x20 # Fixed-point exception register  SPRN 0x001
        .set    SSX_VOL_FAST_CTX_CTR,        0x24 # Count register                  SPRN 0x009
        .set    SSX_VOL_FAST_CTX_SRR0,       0x28 # Save/restore register 0         SPRN 0x01a
        .set    SSX_VOL_FAST_CTX_SRR1,       0x2c # Save/restore register 1         SPRN 0x01b
        .set    SSX_VOL_FAST_CTX_SRR2,       0x30 # Save/restore register 2         SPRN 0x3de
        .set    SSX_VOL_FAST_CTX_SRR3,       0x34 # Save/restore register 3         SPRN 0x3df

        .set    SSX_VOL_FAST_CTX_SIZE,  0x38  # Must be 8-byte aligned

        ## ------------------------------------------------------------
        ## The SSX non-volatile context layout for Embedded PowerPC
        ## ------------------------------------------------------------

        ## The 'preferred form' for stmw is for the LSB of R31 to fall into the
        ## end of a 16-byte aligned block.

        .set    SSX_NON_VOL_CTX_GPR1,       0x0   # Dedicated; Stack Pointer
        .set    SSX_NON_VOL_CTX_HANDLER_LR, 0x4   # Slot for handler to store LR
        .set    SSX_NON_VOL_CTX_GPR14,      0x8   # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR15,      0xc   # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR16,      0x10  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR17,      0x14  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR18,      0x18  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR19,      0x1c  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR20,      0x20  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR21,      0x24  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR22,      0x28  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR23,      0x2c  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR24,      0x30  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR25,      0x34  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR26,      0x38  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR27,      0x3c  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR28,      0x40  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR29,      0x44  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR30,      0x48  # Non-volatile
        .set    SSX_NON_VOL_CTX_GPR31,      0x4c  # Non-volatile

        .set    SSX_NON_VOL_CTX_SIZE,  0x50 # Must be 8-byte aligned

        ## ------------------------------------------------------------
        ## Save/restore the fast context
        ## 
        ## 11 Instructions, 8 Loads/Stores : If MMU is disabled
        ## 17 Instructions, 8 Loads/Stores : If MMU is enabled
        ## ------------------------------------------------------------
        ##
        ## Without MMU support, an EIEIO is always executed at the entry point
        ## to gauarantee that all memory operations (especially MMIO
        ## operations) have completed prior to execution of the interrupt
        ## handler.
        ##
        ## If MMU support is enabled, address translation is re-established
        ## immediately at the entry of each interrupt, prior to performing any
        ## loads or stores. SSX currently only supports using the MMU for
        ## protection, not for address translation.  Therfore it is 'legal'
        ## to change translation modes a with an MTMSR followed by an
        ## ISYNC. This is much simpler then the complex instruction sequence
        ## that would be required if we had to set up RFI/RFCI sequences to
        ## change the execution context at this point.
        ##
        ## Note that since we are not really doing address translation, it
        ## would also be in keeping with the 'fast interrupt' idea to defer
        ## reenabling translation (protection) until the fast-to-full sequence
        ## was executed for full-mode interrupts, and run fast-mode interrupts
        ## unprotected. However here we chose to run all interrupts with MMU
        ## protection. 
        ##
        ## Unfortunately the simple MTMSR;ISYNC sequence exposes a serious bug
        ## in the 405-S core that causes the stack-pointer store instruction
        ## to generate a seemingly random, *real-mode* address in certain cases
        ## when this instruction in a noncritical interrupt prologue is
        ## interrupted by a critical interrupt. This bug is described in
        ## HW239446. The workaround is to follow the ISYNC sith a SYNC - which
        ## eliminates the problem for reasons still unknown. On the bright side
        ## this SYNC might also serve the same purpose as the EIEIO in the
        ## non-MMU case, guaranteeing that all MMIO has completed prior to the
        ## interrupt handler. However without the initial EIEIO we still
        ## experience failures, so this seemingly redundant instruction also
        ## remains in place. This requirement is assumed to be related to the
        ## HW239446 issue.       

        .macro  _ssx_fast_ctx_push, critical

        .if     !PPC405_MMU_SUPPORT

                eieio

        .elseif \critical

                eieio           # HW239446?
                mtsprg4 %r3
                mfmsr   %r3
                ori     %r3, %r3, PPC405_RELOCATION_MODE
                mtmsr   %r3
                isync
#ifndef ALLOW_HW239446
                sync            # HW239446!
#endif
                mfsprg4 %r3

        .else

                eieio           # HW239446?
                mtsprg0 %r3
                mfmsr   %r3
                ori     %r3, %r3, PPC405_RELOCATION_MODE
                mtmsr   %r3
                isync
#ifndef ALLOW_HW239446
                sync            # HW239446!
#endif
                mfsprg0 %r3
        
        .endif                             

        stwu    %r1, -SSX_FAST_CTX_SIZE(%r1) # May be corrupted w/o HW239446

        stw     %r3,  SSX_FAST_CTX_GPR3(%r1)
        stw     %r4,  SSX_FAST_CTX_GPR4(%r1)
        stw     %r5,  SSX_FAST_CTX_GPR5(%r1)
        stw     %r6,  SSX_FAST_CTX_GPR6(%r1)
        stw     %r7,  SSX_FAST_CTX_GPR7(%r1)

        mfcr    %r3
        mflr    %r4

        stw     %r3,  SSX_FAST_CTX_CR(%r1)
        stw     %r4,  SSX_FAST_CTX_LR(%r1)

        .endm


        .macro  _ssx_fast_ctx_pop
                
        lwz     %r3, SSX_FAST_CTX_CR(%r1)
        lwz     %r4, SSX_FAST_CTX_LR(%r1)

        mtcr    %r3
        mtlr    %r4

        lwz     %r3,  SSX_FAST_CTX_GPR3(%r1)
        lwz     %r4,  SSX_FAST_CTX_GPR4(%r1)
        lwz     %r5,  SSX_FAST_CTX_GPR5(%r1)
        lwz     %r6,  SSX_FAST_CTX_GPR6(%r1)
        lwz     %r7,  SSX_FAST_CTX_GPR7(%r1)

        lwz     %r1, 0(%r1)

        .endm

        ## ------------------------------------------------------------
        ## Save/update the kernel context in response to an interrupt.  This is
        ## not part of the fast context save because for external interupts the
        ## IRQ is not determined until later.
        ## ------------------------------------------------------------

        ## The kernel context is saved, then updated with the currently active
        ## IRQ in bits 16:23.  The correct interrupt count is incremented and
        ## the context is returned to USPRG0.

        .macro  _save_update_kernel_context critical, irqreg, ctxreg

        .if     \critical
        SSX_TRACE_CRITICAL_IRQ_ENTRY \irqreg, \ctxreg
        .else
        SSX_TRACE_NONCRITICAL_IRQ_ENTRY \irqreg, \ctxreg
        .endif          

        mfusprg0 \ctxreg
        stw     \ctxreg, SSX_FAST_CTX_KERNEL_CTX(%r1)
        rlwimi  \ctxreg, \irqreg, 8, 16, 23
        .if     \critical
        addis   \ctxreg, \ctxreg, 0x0100
        .else
        addis   \ctxreg, \ctxreg, 0x0001
        .endif
        mtusprg0 \ctxreg

        .endm

        ## ------------------------------------------------------------
        ## Fast-mode context pop and RF(C)I.  This is only used by
        ## interrupt handlers - the thread context switch has its own
        ## code to handle updating USPRG0 for thread mode.
        ## ------------------------------------------------------------

        .macro  _ssx_fast_ctx_pop_exit critical

        .if     SSX_KERNEL_TRACE_ENABLE
        .if     \critical
        bl      __ssx_trace_critical_irq_exit
        .else
        bl      __ssx_trace_noncritical_irq_exit
        .endif
        .endif

        lwz     %r3, SSX_FAST_CTX_KERNEL_CTX(%r1)
        mtusprg0 %r3
        _ssx_fast_ctx_pop
        .if     \critical
        rfci
        .else
        rfi
        .endif

        .endm

        ## ------------------------------------------------------------
        ## Save/restore the (volatile - fast) context
        ## 
        ## Thread - 15     Instructions, 11 Loads/Stores
        ## IRQ    - 19(15) Instructions, 13(11) Loads/Stores
        ## ------------------------------------------------------------

        .macro  _ssx_vol_fast_ctx_push, irq_context, critical=1

        stwu    %r1, -SSX_VOL_FAST_CTX_SIZE(%r1)

        stw     %r0,  SSX_VOL_FAST_CTX_GPR0(%r1)
        stw     %r8,  SSX_VOL_FAST_CTX_GPR8(%r1)
        stw     %r9,  SSX_VOL_FAST_CTX_GPR9(%r1)
        stw     %r10, SSX_VOL_FAST_CTX_GPR10(%r1)
        stw     %r11, SSX_VOL_FAST_CTX_GPR11(%r1)
        stw     %r12, SSX_VOL_FAST_CTX_GPR12(%r1)

        mfxer   %r8
        mfctr   %r9
        mfsrr0  %r10
        mfsrr1  %r11

        stw     %r8,  SSX_VOL_FAST_CTX_XER(%r1)
        stw     %r9,  SSX_VOL_FAST_CTX_CTR(%r1)
        stw     %r10, SSX_VOL_FAST_CTX_SRR0(%r1)
        stw     %r11, SSX_VOL_FAST_CTX_SRR1(%r1)

        .if     (\irq_context & \critical)
        mfsrr2  %r8
        mfsrr3  %r9

        stw     %r8, SSX_VOL_FAST_CTX_SRR2(%r1)
        stw     %r9, SSX_VOL_FAST_CTX_SRR3(%r1)
        .endif

        .endm


        .macro  _ssx_vol_fast_ctx_pop, irq_context, critical

        .if     (\irq_context & \critical)
        lwz     %r8, SSX_VOL_FAST_CTX_SRR2(%r1)
        lwz     %r9, SSX_VOL_FAST_CTX_SRR3(%r1)

        mtsrr2  %r8
        mtsrr3  %r9
        .endif  

        lwz     %r8,  SSX_VOL_FAST_CTX_XER(%r1)
        lwz     %r9,  SSX_VOL_FAST_CTX_CTR(%r1)
        lwz     %r10, SSX_VOL_FAST_CTX_SRR0(%r1)
        lwz     %r11, SSX_VOL_FAST_CTX_SRR1(%r1)

        mtxer   %r8
        mtctr   %r9
        mtsrr0  %r10
        mtsrr1  %r11

        lwz     %r0,  SSX_VOL_FAST_CTX_GPR0(%r1)
        lwz     %r8,  SSX_VOL_FAST_CTX_GPR8(%r1)
        lwz     %r9,  SSX_VOL_FAST_CTX_GPR9(%r1)
        lwz     %r10, SSX_VOL_FAST_CTX_GPR10(%r1)
        lwz     %r11, SSX_VOL_FAST_CTX_GPR11(%r1)
        lwz     %r12, SSX_VOL_FAST_CTX_GPR12(%r1)

        lwz     %r1, 0(%r1)

        .endm

        ## ------------------------------------------------------------
        ## Save/restore the non-volatile context on the stack
        ##
        ## 2 Instructions, 19 Loads/Stores
        ## ------------------------------------------------------------

        .macro  _ssx_non_vol_ctx_push

        stwu    %r1, -SSX_NON_VOL_CTX_SIZE(%r1)
        stmw    %r14, SSX_NON_VOL_CTX_GPR14(%r1)
        
        .endm


        .macro  _ssx_non_vol_ctx_pop

        lmw     %r14, SSX_NON_VOL_CTX_GPR14(%r1)
        lwz     %r1, 0(%r1)

        .endm

#else /* __ASSEMBLER__ */

/// SSX thread context layout as a C structure.
///
/// This is the structure of the stack area pointed to by
/// thread->saved_stack_pointer when a thread is fully context-switched out.

typedef struct {

    uint32_t r1_nv;
    uint32_t link_nv;
    uint32_t r14;
    uint32_t r15;
    uint32_t r16;
    uint32_t r17;
    uint32_t r18;
    uint32_t r19;
    uint32_t r20;
    uint32_t r21;
    uint32_t r22;
    uint32_t r23;
    uint32_t r24;
    uint32_t r25;
    uint32_t r26;
    uint32_t r27;
    uint32_t r28;
    uint32_t r29;
    uint32_t r30;
    uint32_t r31;
    uint32_t r1_vf;
    uint32_t link_vf;
    uint32_t r0;
    uint32_t r8;
    uint32_t r9;
    uint32_t r10;
    uint32_t r11;
    uint32_t r12;
    uint32_t xer;
    uint32_t ctr;
    uint32_t srr0;
    uint32_t srr1;
    uint32_t srr2;
    uint32_t srr3;
    uint32_t r1;
    uint32_t link_fast;
    uint32_t r3;
    uint32_t r4;
    uint32_t r5;
    uint32_t r6;
    uint32_t r7;
    uint32_t cr;
    uint32_t lr;
    uint32_t usprg0;

} SsxThreadContext;


/// SSX thread context of an interrupted thread (full-mode handler)
///
/// When a thread is interrupted by a full-mode interrupt handler, this is the
/// layout of the stack area pointed to by either __ssx_saved_sp_noncritical
/// or __ssx_saved_sp_critical.

typedef struct {

    uint32_t r1_vf;
    uint32_t link_vf;
    uint32_t r0;
    uint32_t r8;
    uint32_t r9;
    uint32_t r10;
    uint32_t r11;
    uint32_t r12;
    uint32_t xer;
    uint32_t ctr;
    uint32_t srr0;
    uint32_t srr1;
    uint32_t srr2;
    uint32_t srr3;
    uint32_t r1;
    uint32_t link_fast;
    uint32_t r3;
    uint32_t r4;
    uint32_t r5;
    uint32_t r6;
    uint32_t r7;
    uint32_t cr;
    uint32_t lr;
    uint32_t usprg0;

} SsxThreadContextFullIrq;


/// SSX thread context of an interrupted thread (fast-mode handler)
///
/// When a thread is interrupted by a fast-mode interrupt handler, this is the
/// layout of the stack area pointed to by R1 - unless the fast-mode interrupt
/// handler extends the stack.

typedef struct {

    uint32_t r1;
    uint32_t link_fast;
    uint32_t r3;
    uint32_t r4;
    uint32_t r5;
    uint32_t r6;
    uint32_t r7;
    uint32_t cr;
    uint32_t lr;
    uint32_t usprg0;

} SsxThreadContextFastIrq;

#endif /* __ASSEMBLER__ */

#endif /* __PPC405_CONTEXT_H__ */


OpenPOWER on IntegriCloud