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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [shared/] [irq/] [irq_asm.S] - Blame information for rev 562

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  This file contains the assembly code for the PowerPC
3
 *  IRQ veneers for RTEMS.
4
 *
5
 *  The license and distribution terms for this file may be
6
 *  found in found in the file LICENSE in this distribution or at
7
 *  http://www.OARcorp.com/rtems/license.html.
8
 *
9
 *  Modified to support the MCP750.
10
 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
11
 *
12
 *
13
 * $Id: irq_asm.S,v 1.2 2001-09-27 12:01:06 chris Exp $
14
 */
15
 
16
#include 
17
#include 
18
#include 
19
#include 
20
#include "asm.h"
21
 
22
 
23
#define SYNC \
24
        sync; \
25
        isync
26
 
27
        .text
28
        .p2align 5
29
 
30
        PUBLIC_VAR(decrementer_exception_vector_prolog_code)
31
 
32
SYM (decrementer_exception_vector_prolog_code):
33
        /*
34
         * let room for exception frame
35
         */
36
        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
37
        stw     r4, GPR4_OFFSET(r1)
38
        li      r4, ASM_DEC_VECTOR
39
        ba      shared_raw_irq_code_entry
40
 
41
        PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
42
 
43
        decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
44
 
45
        PUBLIC_VAR(external_exception_vector_prolog_code)
46
 
47
SYM (external_exception_vector_prolog_code):
48
        /*
49
         * let room for exception frame
50
         */
51
        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
52
        stw     r4, GPR4_OFFSET(r1)
53
        li      r4, ASM_EXT_VECTOR
54
        ba      shared_raw_irq_code_entry
55
 
56
        PUBLIC_VAR (external_exception_vector_prolog_code_size)
57
 
58
        external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
59
 
60
        PUBLIC_VAR(shared_raw_irq_code_entry)
61
        PUBLIC_VAR(C_dispatch_irq_handler)
62
 
63
        .p2align 5
64
SYM (shared_raw_irq_code_entry):
65
        /*
66
         * Entry conditions :
67
         *      Registers already saved : R1, R4
68
         *      R1  :   points to a location with enough room for the
69
         *              interrupt frame
70
         *      R4  :   vector number
71
         */
72
        /*
73
         * Save SRR0/SRR1 As soon As possible as it is the minimal needed
74
         * to reenable exception processing
75
         */
76
        stw     r0, GPR0_OFFSET(r1)
77
        stw     r2, GPR2_OFFSET(r1)
78
        stw     r3, GPR3_OFFSET(r1)
79
 
80
        mfsrr0  r0
81
        mfsrr1  r2
82
        mfmsr   r3
83
 
84
        stw     r0, SRR0_FRAME_OFFSET(r1)
85
        stw     r2, SRR1_FRAME_OFFSET(r1)
86
        /*
87
         * Enable data and instruction address translation, exception recovery
88
     *
89
     * also, on CPUs with FP, enable FP so that FP context can be
90
     * saved and restored (using FP instructions)
91
         */
92
#if (PPC_HAS_FPU == 0)
93
        ori     r3, r3, MSR_RI | MSR_IR | MSR_DR
94
#else
95
        ori     r3, r3, MSR_RI | MSR_IR | MSR_DR | MSR_FP
96
#endif
97
        mtmsr   r3
98
        SYNC
99
        /*
100
         * Push C scratch registers on the current stack. It may
101
         * actually be the thread stack or the interrupt stack.
102
         * Anyway we have to make it in order to be able to call C/C++
103
         * functions. Depending on the nesting interrupt level, we will
104
         * switch to the right stack later.
105
         */
106
        stw     r5, GPR5_OFFSET(r1)
107
        stw     r6, GPR6_OFFSET(r1)
108
        stw     r7, GPR7_OFFSET(r1)
109
        stw     r8, GPR8_OFFSET(r1)
110
        stw     r9, GPR9_OFFSET(r1)
111
        stw     r10, GPR10_OFFSET(r1)
112
        stw     r11, GPR11_OFFSET(r1)
113
        stw     r12, GPR12_OFFSET(r1)
114
        stw     r13, GPR13_OFFSET(r1)
115
 
116
        mfcr    r5
117
        mfctr   r6
118
        mfxer   r7
119
        mflr    r8
120
 
121
        stw     r5,  EXC_CR_OFFSET(r1)
122
        stw     r6,  EXC_CTR_OFFSET(r1)
123
        stw     r7,  EXC_XER_OFFSET(r1)
124
        stw     r8,  EXC_LR_OFFSET(r1)
125
 
126
        /*
127
         * Add some non volatile registers to store information
128
         * that will be used when returning from C handler
129
         */
130
        stw     r14, GPR14_OFFSET(r1)
131
        stw     r15, GPR15_OFFSET(r1)
132
        /*
133
         * save current stack pointer location in R14
134
         */
135
        addi    r14, r1, 0
136
        /*
137
         * store part of _Thread_Dispatch_disable_level address in R15
138
         */
139
        addis r15,0, _Thread_Dispatch_disable_level@ha
140
        /*
141
         * Get current nesting level in R2
142
         */
143
        mfspr   r2, SPRG0
144
        /*
145
         * Check if stack switch is necessary
146
         */
147
        cmpwi   r2,0
148
        bne     nested
149
        mfspr   r1, SPRG1
150
 
151
nested:
152
        /*
153
         * Start Incrementing nesting level in R2
154
         */
155
        addi    r2,r2,1
156
        /*
157
         * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
158
         */
159
        lwz     r6,_Thread_Dispatch_disable_level@l(r15)
160
        /*
161
         * store new nesting level in SPRG0
162
         */
163
        mtspr   SPRG0, r2
164
 
165
        addi    r6, r6, 1
166
        mfmsr   r5
167
        /*
168
         * store new _Thread_Dispatch_disable_level value
169
         */
170
        stw     r6, _Thread_Dispatch_disable_level@l(r15)
171
        /*
172
         * We are now running on the interrupt stack. External and decrementer
173
         * exceptions are still disabled. I see no purpose trying to optimize
174
         * further assembler code.
175
         */
176
        /*
177
         * Call C exception handler for decrementer Interrupt frame is passed just
178
         * in case...
179
         */
180
        addi    r3, r14, 0x8
181
        bl      C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
182
        /*
183
         * start decrementing nesting level. Note : do not test result against 0
184
         * value as an easy exit condition because if interrupt nesting level > 1
185
         * then _Thread_Dispatch_disable_level > 1
186
         */
187
        mfspr   r2, SPRG0
188
        /*
189
         * start decrementing _Thread_Dispatch_disable_level
190
         */
191
        lwz     r3,_Thread_Dispatch_disable_level@l(r15)
192
        addi    r2, r2, -1      /* Continue decrementing nesting level */
193
        addi    r3, r3, -1      /* Continue decrementing _Thread_Dispatch_disable_level */
194
        mtspr   SPRG0, r2       /* End decrementing nesting level */
195
        stw     r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
196
        cmpwi   r3, 0
197
        /*
198
         * switch back to original stack (done here just optimize registers
199
         * contention. Could have been done before...)
200
         */
201
        addi    r1, r14, 0
202
        bne     easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
203
        /*
204
         * Here we are running again on the thread system stack.
205
         * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
206
         * Interrupt are still disabled. Time to check if scheduler request to
207
         * do something with the current thread...
208
         */
209
        addis   r4, 0, _Context_Switch_necessary@ha
210
        lwz     r5, _Context_Switch_necessary@l(r4)
211
        cmpwi   r5, 0
212
        bne     switch
213
 
214
        addis   r6, 0, _ISR_Signals_to_thread_executing@ha
215
        lwz     r7, _ISR_Signals_to_thread_executing@l(r6)
216
        cmpwi   r7, 0
217
        li      r8, 0
218
        beq     easy_exit
219
        stw     r8, _ISR_Signals_to_thread_executing@l(r6)
220
        /*
221
         * going to call _ThreadProcessSignalsFromIrq
222
         * Push a complete exception like frame...
223
         */
224
        stmw    r16, GPR16_OFFSET(r1)
225
        addi    r3, r1, 0x8
226
        /*
227
         * compute SP at exception entry
228
         */
229
        addi    r2, r1, EXCEPTION_FRAME_END
230
        /*
231
         * store it at the right place
232
         */
233
        stw     r2, GPR1_OFFSET(r1)
234
        /*
235
         * Call High Level signal handling code
236
         */
237
        bl      _ThreadProcessSignalsFromIrq
238
        /*
239
         * start restoring exception like frame
240
         */
241
        lwz     r31,  EXC_CTR_OFFSET(r1)
242
        lwz     r30,  EXC_XER_OFFSET(r1)
243
        lwz     r29,  EXC_CR_OFFSET(r1)
244
        lwz     r28,  EXC_LR_OFFSET(r1)
245
 
246
        mtctr   r31
247
        mtxer   r30
248
        mtcr    r29
249
        mtlr    r28
250
 
251
        lmw     r4, GPR4_OFFSET(r1)
252
        lwz     r2, GPR2_OFFSET(r1)
253
        lwz     r0, GPR0_OFFSET(r1)
254
 
255
        /*
256
         * Disable data and instruction translation. Make path non recoverable...
257
         */
258
        mfmsr   r3
259
        xori    r3, r3, MSR_RI | MSR_IR | MSR_DR
260
        mtmsr   r3
261
        SYNC
262
        /*
263
         * Restore rfi related settings
264
         */
265
 
266
        lwz     r3, SRR1_FRAME_OFFSET(r1)
267
        mtsrr1  r3
268
        lwz     r3, SRR0_FRAME_OFFSET(r1)
269
        mtsrr0  r3
270
 
271
        lwz     r3, GPR3_OFFSET(r1)
272
        addi    r1,r1, EXCEPTION_FRAME_END
273
        SYNC
274
        rfi
275
 
276
switch:
277
        bl      SYM (_Thread_Dispatch)
278
 
279
easy_exit:
280
        /*
281
         * start restoring interrupt frame
282
         */
283
        lwz     r3,  EXC_CTR_OFFSET(r1)
284
        lwz     r4,  EXC_XER_OFFSET(r1)
285
        lwz     r5,  EXC_CR_OFFSET(r1)
286
        lwz     r6,  EXC_LR_OFFSET(r1)
287
 
288
        mtctr   r3
289
        mtxer   r4
290
        mtcr    r5
291
        mtlr    r6
292
 
293
        lwz     r15, GPR15_OFFSET(r1)
294
        lwz     r14, GPR14_OFFSET(r1)
295
        lwz     r13, GPR13_OFFSET(r1)
296
        lwz     r12, GPR12_OFFSET(r1)
297
        lwz     r11, GPR11_OFFSET(r1)
298
        lwz     r10, GPR10_OFFSET(r1)
299
        lwz     r9, GPR9_OFFSET(r1)
300
        lwz     r8, GPR8_OFFSET(r1)
301
        lwz     r7, GPR7_OFFSET(r1)
302
        lwz     r6, GPR6_OFFSET(r1)
303
        lwz     r5, GPR5_OFFSET(r1)
304
 
305
        /*
306
         * Disable nested exception processing, data and instruction
307
         * translation.
308
         */
309
        mfmsr   r3
310
        xori    r3, r3, MSR_RI | MSR_IR | MSR_DR
311
        mtmsr   r3
312
        SYNC
313
        /*
314
         * Restore rfi related settings
315
         */
316
 
317
        lwz     r4, SRR1_FRAME_OFFSET(r1)
318
        lwz     r2, SRR0_FRAME_OFFSET(r1)
319
        lwz     r3, GPR3_OFFSET(r1)
320
        lwz     r0, GPR0_OFFSET(r1)
321
 
322
        mtsrr1  r4
323
        mtsrr0  r2
324
        lwz     r4, GPR4_OFFSET(r1)
325
        lwz     r2, GPR2_OFFSET(r1)
326
        addi    r1,r1, EXCEPTION_FRAME_END
327
        SYNC
328
        rfi
329
 

powered by: WebSVN 2.1.0

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