OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [exec/] [score/] [cpu/] [hppa1.1/] [cpu_asm.S] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * TODO:
3
 *       Context_switch needs to only save callee save registers
4
 *       I think this means can skip:    r1, r2, r19-29, r31
5
 *       Ref:     p 3-2 of Procedure Calling Conventions Manual
6
 *       This should be #ifndef DEBUG so that debugger has
7
 *       accurate visibility into all registers
8
 *
9
 *  This file contains the assembly code for the HPPA implementation
10
 *  of RTEMS.
11
 *
12
 *  COPYRIGHT (c) 1994,95 by Division Incorporated
13
 *
14
 *  The license and distribution terms for this file may be
15
 *  found in the file LICENSE in this distribution or at
16
 *  http://www.OARcorp.com/rtems/license.html.
17
 *
18
 *  $Id: cpu_asm.S,v 1.2 2001-09-27 11:59:24 chris Exp $
19
 */
20
 
21
#include 
22
#include 
23
#include 
24
#include 
25
 
26
        .SPACE $PRIVATE$
27
        .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
28
        .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
29
        .SPACE $TEXT$
30
        .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
31
        .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
32
        .SPACE $TEXT$
33
        .SUBSPA $CODE$
34
 
35
/*
36
 * Special register usage for context switch and interrupts
37
 * Stay away from %cr28 which is used for TLB misses on 72000
38
 */
39
 
40
isr_arg0           .reg    %cr24
41
isr_r9             .reg    %cr25
42
isr_r8             .reg    %cr26
43
 
44
/*
45
 * Interrupt stack frame looks like this
46
 *
47
 *  offset                                   item
48
 * -----------------------------------------------------------------
49
 *   INTEGER_CONTEXT_OFFSET             Context_Control
50
 *   FP_CONTEXT_OFFSET                  Context_Control_fp
51
 *
52
 * It is padded out to a multiple of 64
53
 */
54
 
55
 
56
/*PAGE^L
57
 *  void _Generic_ISR_Handler()
58
 *
59
 *  This routine provides the RTEMS interrupt management.
60
 *
61
 *   We jump here from the interrupt vector.
62
 *   The HPPA hardware has done some stuff for us:
63
 *       PSW saved in IPSW
64
 *       PSW set to 0
65
 *       PSW[E] set to default (0)
66
 *       PSW[M] set to 1 iff this is HPMC
67
 *
68
 *       IIA queue is frozen (since PSW[Q] is now 0)
69
 *       privilege level promoted to 0
70
 *       IIR, ISR, IOR potentially updated if PSW[Q] was 1 at trap
71
 *       registers GR  1,8,9,16,17,24,25 copied to shadow regs
72
 *                 SHR 0 1 2  3  4  5  6
73
 *
74
 *   Our vector stub (in the BSP) MUST have done the following:
75
 *
76
 *   a) Saved the original %r9 into %isr_r9 (%cr25)
77
 *   b) Placed the vector number in %r9
78
 *   c) Was allowed to also destroy $isr_r8 (%cr26),
79
 *      but the stub was NOT allowed to destroy any other registers.
80
 *
81
 *   The typical stub sequence (in the BSP) should look like this:
82
 *
83
 *   a)     mtctl   %r9,isr_r9     ; (save r9 in cr25)
84
 *   b)     ldi     vector,%r9     ; (load constant vector number in r9)
85
 *   c)     mtctl   %r8,isr_r8     ; (save r8 in cr26)
86
 *   d)     ldil    L%MY_BSP_first_level_interrupt_handler,%r8
87
 *   e)     ldo     R%MY_BSP_first_level_interrupt_handler(%r8),%r8
88
 *                                 ; (point to BSP raw handler table)
89
 *   f)     ldwx,s  %r9(%r8),%r8   ; (load value from raw handler table)
90
 *   g)     bv      0(%r8)         ; (call raw handler: _Generic_ISR_Handler)
91
 *   h)     mfctl   isr_r8,%r8     ; (restore r8 from cr26 in delay slot)
92
 *
93
 *   Optionally, steps (c) thru (h) _could_ be replaced with a single
94
 *          bl,n    _Generic_ISR_Handler,%r0
95
 *
96
 *
97
 */
98
        .EXPORT _Generic_ISR_Handler,ENTRY,PRIV_LEV=0
99
_Generic_ISR_Handler:
100
        .PROC
101
        .CALLINFO FRAME=0,NO_CALLS
102
        .ENTRY
103
 
104
        mtctl     arg0, isr_arg0
105
 
106
/*
107
 * save interrupt state
108
 */
109
        mfctl     ipsw, arg0
110
        stw       arg0, IPSW_OFFSET(sp)
111
 
112
        mfctl     iir, arg0
113
        stw       arg0, IIR_OFFSET(sp)
114
 
115
        mfctl     ior, arg0
116
        stw       arg0, IOR_OFFSET(sp)
117
 
118
        mfctl     pcoq, arg0
119
        stw       arg0, PCOQFRONT_OFFSET(sp)
120
 
121
        mtctl     %r0, pcoq
122
        mfctl     pcoq, arg0
123
        stw       arg0, PCOQBACK_OFFSET(sp)
124
 
125
        mfctl     %sar, arg0
126
        stw       arg0, SAR_OFFSET(sp)
127
 
128
/*
129
 * Build an interrupt frame to hold the contexts we will need.
130
 * We have already saved the interrupt items on the stack
131
 *
132
 * At this point the following registers are damaged wrt the interrupt
133
 *  reg    current value        saved value
134
 * ------------------------------------------------
135
 *  arg0   scratch               isr_arg0  (cr24)
136
 *  r9     vector number         isr_r9    (cr25)
137
 *
138
 * Point to beginning of integer context and
139
 * save the integer context
140
 */
141
        stw         %r1,R1_OFFSET(sp)
142
        stw         %r2,R2_OFFSET(sp)
143
        stw         %r3,R3_OFFSET(sp)
144
        stw         %r4,R4_OFFSET(sp)
145
        stw         %r5,R5_OFFSET(sp)
146
        stw         %r6,R6_OFFSET(sp)
147
        stw         %r7,R7_OFFSET(sp)
148
        stw         %r8,R8_OFFSET(sp)
149
/*
150
 * skip r9
151
 */
152
        stw         %r10,R10_OFFSET(sp)
153
        stw         %r11,R11_OFFSET(sp)
154
        stw         %r12,R12_OFFSET(sp)
155
        stw         %r13,R13_OFFSET(sp)
156
        stw         %r14,R14_OFFSET(sp)
157
        stw         %r15,R15_OFFSET(sp)
158
        stw         %r16,R16_OFFSET(sp)
159
        stw         %r17,R17_OFFSET(sp)
160
        stw         %r18,R18_OFFSET(sp)
161
        stw         %r19,R19_OFFSET(sp)
162
        stw         %r20,R20_OFFSET(sp)
163
        stw         %r21,R21_OFFSET(sp)
164
        stw         %r22,R22_OFFSET(sp)
165
        stw         %r23,R23_OFFSET(sp)
166
        stw         %r24,R24_OFFSET(sp)
167
        stw         %r25,R25_OFFSET(sp)
168
/*
169
 * skip arg0
170
 */
171
        stw         %r27,R27_OFFSET(sp)
172
        stw         %r28,R28_OFFSET(sp)
173
        stw         %r29,R29_OFFSET(sp)
174
        stw         %r30,R30_OFFSET(sp)
175
        stw         %r31,R31_OFFSET(sp)
176
 
177
/* Now most registers are available since they have been saved
178
 *
179
 * The following items are currently wrong in the integer context
180
 *  reg    current value        saved value
181
 * ------------------------------------------------
182
 *  arg0   scratch               isr_arg0  (cr24)
183
 *  r9     vector number         isr_r9    (cr25)
184
 *
185
 * Fix them
186
 */
187
 
188
         mfctl      isr_arg0,%r3
189
         stw        %r3,ARG0_OFFSET(sp)
190
 
191
         mfctl      isr_r9,%r3
192
         stw        %r3,R9_OFFSET(sp)
193
 
194
/*
195
 * At this point we are done with isr_arg0, and isr_r9 control registers
196
 *
197
 * Prepare to re-enter virtual mode
198
 * We need Q in case the interrupt handler enables interrupts
199
 */
200
 
201
        ldil      L%CPU_PSW_DEFAULT, arg0
202
        ldo       R%CPU_PSW_DEFAULT(arg0), arg0
203
        mtctl     arg0, ipsw
204
 
205
/*
206
 * Now jump to "rest_of_isr_handler" with the rfi
207
 * We are assuming the space queues are all correct already
208
 */
209
 
210
        ldil      L%rest_of_isr_handler, arg0
211
        ldo       R%rest_of_isr_handler(arg0), arg0
212
        mtctl     arg0, pcoq
213
        ldo       4(arg0), arg0
214
        mtctl     arg0, pcoq
215
 
216
        rfi
217
        nop
218
 
219
/*
220
 * At this point we are back in virtual mode and all our
221
 *  normal addressing is once again ok.
222
 *
223
 *  It is now ok to take an exception or trap
224
 */
225
 
226
rest_of_isr_handler:
227
 
228
/*
229
 * Point to beginning of float context and
230
 * save the floating point context -- doing whatever patches are necessary
231
 */
232
 
233
        .call ARGW0=GR
234
        bl          _CPU_Save_float_context,%r2
235
        ldo         FP_CONTEXT_OFFSET(sp),arg0
236
 
237
/*
238
 * save the ptr to interrupt frame as an argument for the interrupt handler
239
 */
240
 
241
        copy        sp, arg1
242
 
243
/*
244
 * Advance the frame to point beyond all interrupt contexts (integer & float)
245
 * this also includes the pad to align to 64byte stack boundary
246
 */
247
        ldo         CPU_INTERRUPT_FRAME_SIZE(sp), sp
248
 
249
/*
250
 *    r3  -- &_ISR_Nest_level
251
 *    r5  -- value _ISR_Nest_level
252
 *    r4  -- &_Thread_Dispatch_disable_level
253
 *    r6  -- value _Thread_Dispatch_disable_level
254
 *    r9  -- vector number
255
 */
256
 
257
        .import   _ISR_Nest_level,data
258
        ldil      L%_ISR_Nest_level,%r3
259
        ldo       R%_ISR_Nest_level(%r3),%r3
260
        ldw       0(%r3),%r5
261
 
262
        .import   _Thread_Dispatch_disable_level,data
263
        ldil      L%_Thread_Dispatch_disable_level,%r4
264
        ldo       R%_Thread_Dispatch_disable_level(%r4),%r4
265
        ldw       0(%r4),%r6
266
 
267
/*
268
 * increment interrupt nest level counter.  If outermost interrupt
269
 * switch the stack and squirrel away the previous sp.
270
 */
271
        addi      1,%r5,%r5
272
        stw       %r5, 0(%r3)
273
 
274
/*
275
 * compute and save new stack (with frame)
276
 * just in case we are nested -- simpler this way
277
 */
278
        comibf,=  1,%r5,stack_done
279
        ldo       128(sp),%r7
280
 
281
/*
282
 * Switch to interrupt stack allocated by the interrupt manager (intr.c)
283
 */
284
        .import   _CPU_Interrupt_stack_low,data
285
        ldil      L%_CPU_Interrupt_stack_low,%r7
286
        ldw       R%_CPU_Interrupt_stack_low(%r7),%r7
287
        ldo       128(%r7),%r7
288
 
289
stack_done:
290
/*
291
 * save our current stack pointer where the "old sp" is supposed to be
292
 */
293
        stw       sp, -4(%r7)
294
/*
295
 * and switch stacks (or advance old stack in nested case)
296
 */
297
        copy      %r7, sp
298
 
299
/*
300
 * increment the dispatch disable level counter.
301
 */
302
        addi      1,%r6,%r6
303
        stw       %r6, 0(%r4)
304
 
305
/*
306
 * load address of user handler
307
 * Note:  No error checking is done, it is assumed that the
308
 *        vector table contains a valid address or a stub
309
 *        spurious handler.
310
 */
311
        .import   _ISR_Vector_table,data
312
        ldil      L%_ISR_Vector_table,%r8
313
        ldo       R%_ISR_Vector_table(%r8),%r8
314
        ldwx,s    %r9(%r8),%r8
315
 
316
/*
317
 * invoke user interrupt handler
318
 * Interrupts are currently disabled, as per RTEMS convention
319
 * The handler has the option of re-enabling interrupts
320
 * NOTE:  can not use 'bl' since it uses "pc-relative" addressing
321
 *    and we are using a hard coded address from a table
322
 *  So... we fudge r2 ourselves (ala dynacall)
323
 *  arg0 = vector number, arg1 = ptr to rtems_interrupt_frame
324
 */
325
        copy      %r9, %r26
326
        .call  ARGW0=GR, ARGW1=GR
327
        blr       %r0, rp
328
        bv,n      0(%r8)
329
 
330
post_user_interrupt_handler:
331
 
332
/*
333
 * Back from user handler(s)
334
 * Disable external interrupts (since the interrupt handler could
335
 * have turned them on) and return to the interrupted task stack (assuming
336
 * (_ISR_Nest_level == 0)
337
 */
338
 
339
        rsm        HPPA_PSW_I + HPPA_PSW_R, %r0
340
        ldw        -4(sp), sp
341
 
342
/*
343
 *    r3  -- (most of) &_ISR_Nest_level
344
 *    r5  -- value _ISR_Nest_level
345
 *    r4  -- (most of) &_Thread_Dispatch_disable_level
346
 *    r6  -- value _Thread_Dispatch_disable_level
347
 *    r7  -- (most of) &_ISR_Signals_to_thread_executing
348
 *    r8  -- value _ISR_Signals_to_thread_executing
349
 */
350
 
351
        .import   _ISR_Nest_level,data
352
        ldil      L%_ISR_Nest_level,%r3
353
        ldw       R%_ISR_Nest_level(%r3),%r5
354
 
355
        .import   _Thread_Dispatch_disable_level,data
356
        ldil      L%_Thread_Dispatch_disable_level,%r4
357
        ldw       R%_Thread_Dispatch_disable_level(%r4),%r6
358
 
359
        .import    _ISR_Signals_to_thread_executing,data
360
        ldil       L%_ISR_Signals_to_thread_executing,%r7
361
 
362
/*
363
 * decrement isr nest level
364
 */
365
        addi      -1, %r5, %r5
366
        stw       %r5, R%_ISR_Nest_level(%r3)
367
 
368
/*
369
 * decrement dispatch disable level counter and, if not 0, go on
370
 */
371
        addi       -1,%r6,%r6
372
        comibf,=   0,%r6,isr_restore
373
        stw        %r6, R%_Thread_Dispatch_disable_level(%r4)
374
 
375
/*
376
 * check whether or not a context switch is necessary
377
 */
378
        .import    _Context_Switch_necessary,data
379
        ldil       L%_Context_Switch_necessary,%r8
380
        ldw        R%_Context_Switch_necessary(%r8),%r8
381
        comibf,=,n 0,%r8,ISR_dispatch
382
 
383
/*
384
 * check whether or not a context switch is necessary because an ISR
385
 *    sent signals to the interrupted task
386
 */
387
        ldw        R%_ISR_Signals_to_thread_executing(%r7),%r8
388
        comibt,=,n 0,%r8,isr_restore
389
 
390
 
391
/*
392
 * OK, something happened while in ISR and we need to switch to a task
393
 * other than the one which was interrupted or the
394
 *    ISR_Signals_to_thread_executing case
395
 * We also turn on interrupts, since the interrupted task had them
396
 *   on (obviously :-) and Thread_Dispatch is happy to leave ints on.
397
 */
398
 
399
ISR_dispatch:
400
        stw        %r0, R%_ISR_Signals_to_thread_executing(%r7)
401
 
402
        ssm        HPPA_PSW_I, %r0
403
 
404
        .import    _Thread_Dispatch,code
405
        .call
406
        bl         _Thread_Dispatch,%r2
407
        ldo        128(sp),sp
408
 
409
        ldo        -128(sp),sp
410
 
411
isr_restore:
412
 
413
/*
414
 * enable interrupts during most of restore
415
 */
416
        ssm        HPPA_PSW_I, %r0
417
 
418
/*
419
 * Get a pointer to beginning of our stack frame
420
 */
421
        ldo        -CPU_INTERRUPT_FRAME_SIZE(sp), %arg1
422
 
423
/*
424
 * restore float
425
 */
426
        .call ARGW0=GR
427
        bl         _CPU_Restore_float_context,%r2
428
        ldo        FP_CONTEXT_OFFSET(%arg1), arg0
429
 
430
        copy       %arg1, %arg0
431
 
432
/*
433
 *   ********** FALL THRU **********
434
 */
435
 
436
/*
437
 * Jump here from bottom of Context_Switch
438
 * Also called directly by _CPU_Context_Restart_self via _Thread_Restart_self
439
 * restore interrupt state
440
 */
441
 
442
        .EXPORT _CPU_Context_restore
443
_CPU_Context_restore:
444
 
445
/*
446
 * restore integer state
447
 */
448
        ldw         R1_OFFSET(arg0),%r1
449
        ldw         R2_OFFSET(arg0),%r2
450
        ldw         R3_OFFSET(arg0),%r3
451
        ldw         R4_OFFSET(arg0),%r4
452
        ldw         R5_OFFSET(arg0),%r5
453
        ldw         R6_OFFSET(arg0),%r6
454
        ldw         R7_OFFSET(arg0),%r7
455
        ldw         R8_OFFSET(arg0),%r8
456
        ldw         R9_OFFSET(arg0),%r9
457
        ldw         R10_OFFSET(arg0),%r10
458
        ldw         R11_OFFSET(arg0),%r11
459
        ldw         R12_OFFSET(arg0),%r12
460
        ldw         R13_OFFSET(arg0),%r13
461
        ldw         R14_OFFSET(arg0),%r14
462
        ldw         R15_OFFSET(arg0),%r15
463
        ldw         R16_OFFSET(arg0),%r16
464
        ldw         R17_OFFSET(arg0),%r17
465
        ldw         R18_OFFSET(arg0),%r18
466
        ldw         R19_OFFSET(arg0),%r19
467
        ldw         R20_OFFSET(arg0),%r20
468
        ldw         R21_OFFSET(arg0),%r21
469
        ldw         R22_OFFSET(arg0),%r22
470
        ldw         R23_OFFSET(arg0),%r23
471
        ldw         R24_OFFSET(arg0),%r24
472
/*
473
 * skipping r25; used as scratch register below
474
 * skipping r26 (arg0) until we are done with it
475
 */
476
        ldw         R27_OFFSET(arg0),%r27
477
        ldw         R28_OFFSET(arg0),%r28
478
        ldw         R29_OFFSET(arg0),%r29
479
/*
480
 * skipping r30 (sp) until we turn off interrupts
481
 */
482
        ldw         R31_OFFSET(arg0),%r31
483
 
484
/*
485
 * Turn off Q & R & I so we can write r30 and interrupt control registers
486
 */
487
        rsm        HPPA_PSW_Q + HPPA_PSW_R + HPPA_PSW_I, %r0
488
 
489
/*
490
 * now safe to restore r30
491
 */
492
        ldw         R30_OFFSET(arg0),%r30
493
 
494
        ldw        IPSW_OFFSET(arg0), %r25
495
        mtctl      %r25, ipsw
496
 
497
        ldw        SAR_OFFSET(arg0), %r25
498
        mtctl      %r25, sar
499
 
500
        ldw        PCOQFRONT_OFFSET(arg0), %r25
501
        mtctl      %r25, pcoq
502
 
503
        ldw        PCOQBACK_OFFSET(arg0), %r25
504
        mtctl      %r25, pcoq
505
 
506
/*
507
 * Load r25 with interrupts off
508
 */
509
        ldw         R25_OFFSET(arg0),%r25
510
/*
511
 * Must load r26 (arg0) last
512
 */
513
        ldw         R26_OFFSET(arg0),%r26
514
 
515
isr_exit:
516
        rfi
517
        .EXIT
518
        .PROCEND
519
 
520
/*
521
 *  This section is used to context switch floating point registers.
522
 *  Ref:  6-35 of Architecture 1.1
523
 *
524
 *  NOTE:    since integer multiply uses the floating point unit,
525
 *           we have to save/restore fp on every trap.  We cannot
526
 *           just try to keep track of fp usage.
527
 */
528
 
529
        .align 32
530
        .EXPORT _CPU_Save_float_context,ENTRY,PRIV_LEV=0
531
_CPU_Save_float_context:
532
        .PROC
533
        .CALLINFO FRAME=0,NO_CALLS
534
        .ENTRY
535
        fstds,ma    %fr0,8(%arg0)
536
        fstds,ma    %fr1,8(%arg0)
537
        fstds,ma    %fr2,8(%arg0)
538
        fstds,ma    %fr3,8(%arg0)
539
        fstds,ma    %fr4,8(%arg0)
540
        fstds,ma    %fr5,8(%arg0)
541
        fstds,ma    %fr6,8(%arg0)
542
        fstds,ma    %fr7,8(%arg0)
543
        fstds,ma    %fr8,8(%arg0)
544
        fstds,ma    %fr9,8(%arg0)
545
        fstds,ma    %fr10,8(%arg0)
546
        fstds,ma    %fr11,8(%arg0)
547
        fstds,ma    %fr12,8(%arg0)
548
        fstds,ma    %fr13,8(%arg0)
549
        fstds,ma    %fr14,8(%arg0)
550
        fstds,ma    %fr15,8(%arg0)
551
        fstds,ma    %fr16,8(%arg0)
552
        fstds,ma    %fr17,8(%arg0)
553
        fstds,ma    %fr18,8(%arg0)
554
        fstds,ma    %fr19,8(%arg0)
555
        fstds,ma    %fr20,8(%arg0)
556
        fstds,ma    %fr21,8(%arg0)
557
        fstds,ma    %fr22,8(%arg0)
558
        fstds,ma    %fr23,8(%arg0)
559
        fstds,ma    %fr24,8(%arg0)
560
        fstds,ma    %fr25,8(%arg0)
561
        fstds,ma    %fr26,8(%arg0)
562
        fstds,ma    %fr27,8(%arg0)
563
        fstds,ma    %fr28,8(%arg0)
564
        fstds,ma    %fr29,8(%arg0)
565
        fstds,ma    %fr30,8(%arg0)
566
        fstds       %fr31,0(%arg0)
567
        bv          0(%r2)
568
        addi        -(31*8), %arg0, %arg0        ; restore arg0 just for fun
569
        .EXIT
570
        .PROCEND
571
 
572
        .align 32
573
        .EXPORT _CPU_Restore_float_context,ENTRY,PRIV_LEV=0
574
_CPU_Restore_float_context:
575
        .PROC
576
        .CALLINFO FRAME=0,NO_CALLS
577
        .ENTRY
578
        addi        (31*8), %arg0, %arg0         ; point at last double
579
        fldds       0(%arg0),%fr31
580
        fldds,mb    -8(%arg0),%fr30
581
        fldds,mb    -8(%arg0),%fr29
582
        fldds,mb    -8(%arg0),%fr28
583
        fldds,mb    -8(%arg0),%fr27
584
        fldds,mb    -8(%arg0),%fr26
585
        fldds,mb    -8(%arg0),%fr25
586
        fldds,mb    -8(%arg0),%fr24
587
        fldds,mb    -8(%arg0),%fr23
588
        fldds,mb    -8(%arg0),%fr22
589
        fldds,mb    -8(%arg0),%fr21
590
        fldds,mb    -8(%arg0),%fr20
591
        fldds,mb    -8(%arg0),%fr19
592
        fldds,mb    -8(%arg0),%fr18
593
        fldds,mb    -8(%arg0),%fr17
594
        fldds,mb    -8(%arg0),%fr16
595
        fldds,mb    -8(%arg0),%fr15
596
        fldds,mb    -8(%arg0),%fr14
597
        fldds,mb    -8(%arg0),%fr13
598
        fldds,mb    -8(%arg0),%fr12
599
        fldds,mb    -8(%arg0),%fr11
600
        fldds,mb    -8(%arg0),%fr10
601
        fldds,mb    -8(%arg0),%fr9
602
        fldds,mb    -8(%arg0),%fr8
603
        fldds,mb    -8(%arg0),%fr7
604
        fldds,mb    -8(%arg0),%fr6
605
        fldds,mb    -8(%arg0),%fr5
606
        fldds,mb    -8(%arg0),%fr4
607
        fldds,mb    -8(%arg0),%fr3
608
        fldds,mb    -8(%arg0),%fr2
609
        fldds,mb    -8(%arg0),%fr1
610
        bv          0(%r2)
611
        fldds,mb    -8(%arg0),%fr0
612
        .EXIT
613
        .PROCEND
614
 
615
/*
616
 * These 2 small routines are unused right now.
617
 * Normally we just go thru _CPU_Save_float_context (and Restore)
618
 *
619
 * Here we just deref the ptr and jump up, letting _CPU_Save_float_context
620
 *  do the return for us.
621
 */
622
 
623
        .EXPORT _CPU_Context_save_fp,ENTRY,PRIV_LEV=0
624
_CPU_Context_save_fp:
625
        .PROC
626
        .CALLINFO FRAME=0,NO_CALLS
627
        .ENTRY
628
        bl          _CPU_Save_float_context, %r0
629
        ldw         0(%arg0), %arg0
630
        .EXIT
631
        .PROCEND
632
 
633
        .EXPORT _CPU_Context_restore_fp,ENTRY,PRIV_LEV=0
634
_CPU_Context_restore_fp:
635
        .PROC
636
        .CALLINFO FRAME=0,NO_CALLS
637
        .ENTRY
638
        bl          _CPU_Restore_float_context, %r0
639
        ldw         0(%arg0), %arg0
640
        .EXIT
641
        .PROCEND
642
 
643
 
644
/*
645
 *  void _CPU_Context_switch( run_context, heir_context )
646
 *
647
 *  This routine performs a normal non-FP context switch.
648
 */
649
 
650
        .align 32
651
        .EXPORT _CPU_Context_switch,ENTRY,PRIV_LEV=0,ARGW0=GR,ARGW1=GR
652
_CPU_Context_switch:
653
        .PROC
654
        .CALLINFO FRAME=64
655
        .ENTRY
656
 
657
/*
658
 * Save the integer context
659
 */
660
        stw         %r1,R1_OFFSET(arg0)
661
        stw         %r2,R2_OFFSET(arg0)
662
        stw         %r3,R3_OFFSET(arg0)
663
        stw         %r4,R4_OFFSET(arg0)
664
        stw         %r5,R5_OFFSET(arg0)
665
        stw         %r6,R6_OFFSET(arg0)
666
        stw         %r7,R7_OFFSET(arg0)
667
        stw         %r8,R8_OFFSET(arg0)
668
        stw         %r9,R9_OFFSET(arg0)
669
        stw         %r10,R10_OFFSET(arg0)
670
        stw         %r11,R11_OFFSET(arg0)
671
        stw         %r12,R12_OFFSET(arg0)
672
        stw         %r13,R13_OFFSET(arg0)
673
        stw         %r14,R14_OFFSET(arg0)
674
        stw         %r15,R15_OFFSET(arg0)
675
        stw         %r16,R16_OFFSET(arg0)
676
        stw         %r17,R17_OFFSET(arg0)
677
        stw         %r18,R18_OFFSET(arg0)
678
        stw         %r19,R19_OFFSET(arg0)
679
        stw         %r20,R20_OFFSET(arg0)
680
        stw         %r21,R21_OFFSET(arg0)
681
        stw         %r22,R22_OFFSET(arg0)
682
        stw         %r23,R23_OFFSET(arg0)
683
        stw         %r24,R24_OFFSET(arg0)
684
        stw         %r25,R25_OFFSET(arg0)
685
        stw         %r26,R26_OFFSET(arg0)
686
        stw         %r27,R27_OFFSET(arg0)
687
        stw         %r28,R28_OFFSET(arg0)
688
        stw         %r29,R29_OFFSET(arg0)
689
        stw         %r30,R30_OFFSET(arg0)
690
        stw         %r31,R31_OFFSET(arg0)
691
 
692
/*
693
 * fill in interrupt context section
694
 */
695
        stw         %r2, PCOQFRONT_OFFSET(%arg0)
696
        ldo         4(%r2), %r2
697
        stw         %r2, PCOQBACK_OFFSET(%arg0)
698
 
699
/*
700
 * Generate a suitable IPSW by using the system default psw
701
 *  with the current low bits added in.
702
 */
703
 
704
        ldil        L%CPU_PSW_DEFAULT, %r2
705
        ldo         R%CPU_PSW_DEFAULT(%r2), %r2
706
        ssm         0, %arg2
707
        dep         %arg2, 31, 8, %r2
708
        stw         %r2, IPSW_OFFSET(%arg0)
709
 
710
/*
711
 * at this point, the running task context is completely saved
712
 * Now jump to the bottom of the interrupt handler to load the
713
 * heirs context
714
 */
715
 
716
        b           _CPU_Context_restore
717
        copy        %arg1, %arg0
718
 
719
        .EXIT
720
        .PROCEND
721
 
722
 
723
/*
724
 * Find first bit
725
 * NOTE:
726
 *   This is used (and written) only for the ready chain code and
727
 *   priority bit maps.
728
 *   Any other use constitutes fraud.
729
 *   Returns first bit from the least significant side.
730
 *   Eg:  if input is 0x8001
731
 *        output will indicate the '1' bit and return 0.
732
 *   This is counter to HPPA bit numbering which calls this
733
 *   bit 31.  This way simplifies the macros _CPU_Priority_Mask
734
 *   and _CPU_Priority_Bits_index.
735
 *
736
 *   NOTE:
737
 *       We just use 16 bit version
738
 *       does not handle zero case
739
 *
740
 *  Based on the UTAH Mach libc version of ffs.
741
 */
742
 
743
        .align 32
744
        .EXPORT hppa_rtems_ffs,ENTRY,PRIV_LEV=0,ARGW0=GR
745
hppa_rtems_ffs:
746
        .PROC
747
        .CALLINFO FRAME=0,NO_CALLS
748
        .ENTRY
749
 
750
#ifdef RETURN_ERROR_ON_ZERO
751
        comb,=  %arg0,%r0,ffsdone       ; If arg0 is 0
752
        ldi     -1,%ret0                ;   return -1
753
#endif
754
 
755
#if BITFIELD_SIZE == 32
756
        ldi     31,%ret0                ; Set return to high bit
757
        extru,= %arg0,31,16,%r0         ; If low 16 bits are non-zero
758
        addi,tr -16,%ret0,%ret0         ;   subtract 16 from bitpos
759
        shd     %r0,%arg0,16,%arg0      ; else shift right 16 bits
760
#else
761
        ldi     15,%ret0                ; Set return to high bit
762
#endif
763
        extru,= %arg0,31,8,%r0          ; If low 8 bits are non-zero
764
        addi,tr -8,%ret0,%ret0          ;   subtract 8 from bitpos
765
        shd     %r0,%arg0,8,%arg0       ; else shift right 8 bits
766
        extru,= %arg0,31,4,%r0          ; If low 4 bits are non-zero
767
        addi,tr -4,%ret0,%ret0          ;   subtract 4 from bitpos
768
        shd     %r0,%arg0,4,%arg0       ; else shift right 4 bits
769
        extru,= %arg0,31,2,%r0          ; If low 2 bits are non-zero
770
        addi,tr -2,%ret0,%ret0          ;   subtract 2 from bitpos
771
        shd     %r0,%arg0,2,%arg0       ; else shift right 2 bits
772
        extru,= %arg0,31,1,%r0          ; If low bit is non-zero
773
        addi    -1,%ret0,%ret0          ;   subtract 1 from bitpos
774
ffsdone:
775
        bv,n    0(%r2)
776
        nop
777
        .EXIT
778
        .PROCEND

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.