3 * The Irq_IsrTypeTable does not exist any more.
\r
4 * The Irq_VectorTable is now a pure function table (not mixed pcb and functions )
\r
5 * The PPC interrupt handling is a bit faster.
\r
8 * New files for arch offsets?
\r
9 * Bypassed Irq_Entry()...
\r
11 * Move pre/post hooks into swap code?
\r
14 * IMPLEMENTATION NOTES
\r
15 * OPT: For ISR1 (interrupts always off) the there is no need to save r13-r31 since
\r
16 * it will be saved by the C-function.
\r
20 * Small assembler school
\r
21 * Compare imm(32-bit)
\r
23 * Extract bits and right adjust
\r
24 * $ extrwi rA,rS,n,b ( n-number of bits, b- startbit )
\r
25 * Use of @ha,@h,@l. Use @ha for arithmetic instructions to compensate for sign.
\r
26 * To cause less confusion use load and logical instructions instead of arithmetic ones.
\r
27 * $ lis r3,0x8000@h
\r
28 * $ ori r3,r3,0x08000@l
\r
30 * $ addis r3,0x8000@ha
\r
31 * $ addi r3,r3,0x08000@l
\r
37 /* ----------------------------[includes]------------------------------------*/
\r
39 #include "asm_ppc.h"
\r
40 #include "arch_offset.h"
\r
41 #include "asm_offset.h"
\r
42 #include "arch_stack.h"
\r
44 // #include "asm_book_e.h"
\r
45 .extern os_intc_pcb_tbl
\r
46 .extern os_intc_types_tbl
\r
48 .extern Os_ArchPanic
\r
51 /* ----------------------------[private define]------------------------------*/
\r
54 #define INTC_IACKR_PRC0 0xfff48010
\r
55 #define INTC_EOIR_PRC0 0xfff48018
\r
56 #define INTC_IACKR 0xfff48010
\r
57 #define INTC_EOIR 0xfff48018
\r
58 #define INTC_SSCIR0 0xfff48020
\r
60 /* ----------------------------[private macro]-------------------------------*/
\r
62 #define LOCK() wrteei 0
\r
63 #define UNLOCK() wrteei 1
\r
65 #define EXC_TABLE_CODE(_exc_nr) \
\r
66 stwu sp,-EXC_FRM_SIZE(sp); \
\r
67 stw r3,EXC_FRM_R3(sp); \
\r
71 #if ISR_FRM_PATTERN!=FUNC_FRM_PATTERN
\r
72 #error Context pattern must be in the same place
\r
75 /* ----------------------------[private typedef]-----------------------------*/
\r
76 /* ----------------------------[private function prototypes]-----------------*/
\r
77 /* ----------------------------[private variables]---------------------------*/
\r
78 /* ----------------------------[private functions]---------------------------*/
\r
79 /* ----------------------------[public functions]----------------------------*/
\r
83 .global Os_ArchSwapContextTo
\r
84 .global Os_ArchSwapContext
\r
85 .global Os_ArchSetSpAndCall
\r
86 .global Os_Test_And_Set
\r
87 #if defined(__CWCC__) && defined(CFG_VLE)
\r
88 .section .text_vle,text_vle
\r
96 Os_ArchSetSpAndCall:
\r
102 * void Os_ArchSwapContext(pcb_t *old, pcb_t *new )
\r
104 * Saves a function context on current stack, pops a new one from new context
\r
106 * r3 - pcb for old task
\r
107 * r4 - pcb for new task
\r
110 Os_ArchSwapContext:
\r
111 stwu sp,-FUNC_FRM_SIZE(sp)
\r
113 stw r0,FUNC_FRM_LR(sp)
\r
115 stw r0,FUNC_FRM_CR(sp)
\r
117 /* Save context indicator */
\r
119 stw r0,FUNC_FRM_PATTERN(sp)
\r
121 #if defined(CFG_SPE)
\r
122 stw r14, FUNC_FRM_R14(sp)
\r
123 stw r15, FUNC_FRM_R15(sp)
\r
124 stw r16, FUNC_FRM_R16(sp)
\r
125 stw r17, FUNC_FRM_R17(sp)
\r
126 stw r18, FUNC_FRM_R18(sp)
\r
127 stw r19, FUNC_FRM_R19(sp)
\r
128 stw r20, FUNC_FRM_R20(sp)
\r
129 stw r21, FUNC_FRM_R21(sp)
\r
130 stw r22, FUNC_FRM_R22(sp)
\r
131 stw r23, FUNC_FRM_R23(sp)
\r
132 stw r24, FUNC_FRM_R24(sp)
\r
133 stw r25, FUNC_FRM_R25(sp)
\r
134 stw r26, FUNC_FRM_R26(sp)
\r
135 stw r27, FUNC_FRM_R27(sp)
\r
136 stw r28, FUNC_FRM_R28(sp)
\r
137 stw r29, FUNC_FRM_R29(sp)
\r
138 stw r30, FUNC_FRM_R30(sp)
\r
139 stw r31, FUNC_FRM_R31(sp)
\r
142 /* Save registers preserved by function call */
\r
143 stw r14, FUNC_FRM_R14(sp)
\r
144 stw r15, FUNC_FRM_R15(sp)
\r
145 stw r16, FUNC_FRM_R16(sp)
\r
146 stw r17, FUNC_FRM_R17(sp)
\r
147 stw r18, FUNC_FRM_R18(sp)
\r
148 stw r19, FUNC_FRM_R19(sp)
\r
149 stw r20, FUNC_FRM_R20(sp)
\r
150 stw r21, FUNC_FRM_R21(sp)
\r
151 stw r22, FUNC_FRM_R22(sp)
\r
152 stw r23, FUNC_FRM_R23(sp)
\r
153 stw r24, FUNC_FRM_R24(sp)
\r
154 stw r25, FUNC_FRM_R25(sp)
\r
155 stw r26, FUNC_FRM_R26(sp)
\r
156 stw r27, FUNC_FRM_R27(sp)
\r
157 stw r28, FUNC_FRM_R28(sp)
\r
158 stw r29, FUNC_FRM_R29(sp)
\r
159 stw r30, FUNC_FRM_R30(sp)
\r
160 stw r31, FUNC_FRM_R31(sp)
\r
163 /* Save stack ptr... */
\r
164 stw sp,PCB_STACK_CURR_P(r3)
\r
166 /* TODO: Call Os_PretaskHook()? */
\r
171 * void Os_ArchSwapContextTo( NULL, pcb_t *new )
\r
173 * r4 - The pcb to switch to.
\r
175 Os_ArchSwapContextTo:
\r
176 /* Get stack for new task */
\r
177 lwz sp,PCB_STACK_CURR_P(r4)
\r
179 /* Set new current task */
\r
180 LOAD_ADDR_32(3,Os_Sys)
\r
181 stw r4,SYS_CURR_PCB_P(r3)
\r
183 /* Restore C context */
\r
184 lwz r0,FUNC_FRM_CR(sp)
\r
186 lwz r0,FUNC_FRM_LR (sp)
\r
189 /* Get the context type */
\r
190 lwz r0, FUNC_FRM_PATTERN(sp)
\r
191 cmplwi r0, FUNC_PATTERN
\r
192 beq+ restoreFuncContext
\r
193 cmplwi r0,ISR_PATTERN
\r
194 beq+ restoreIsrContext
\r
195 li r3, OS_ERR_BAD_CONTEXT
\r
198 restoreFuncContext:
\r
199 #if defined(CFG_SPE)
\r
200 evldd r14, FUNC_FRM_R14(sp)
\r
201 evldd r15, FUNC_FRM_R15(sp)
\r
202 evldd r16, FUNC_FRM_R16(sp)
\r
203 evldd r17, FUNC_FRM_R17(sp)
\r
204 evldd r18, FUNC_FRM_R18(sp)
\r
205 evldd r19, FUNC_FRM_R19(sp)
\r
206 evldd r20, FUNC_FRM_R20(sp)
\r
207 evldd r21, FUNC_FRM_R21(sp)
\r
208 evldd r22, FUNC_FRM_R22(sp)
\r
209 evldd r23, FUNC_FRM_R23(sp)
\r
210 evldd r24, FUNC_FRM_R24(sp)
\r
211 evldd r25, FUNC_FRM_R25(sp)
\r
212 evldd r26, FUNC_FRM_R26(sp)
\r
213 evldd r27, FUNC_FRM_R27(sp)
\r
214 evldd r28, FUNC_FRM_R28(sp)
\r
215 evldd r29, FUNC_FRM_R29(sp)
\r
216 evldd r30, FUNC_FRM_R30(sp)
\r
217 evldd r31, FUNC_FRM_R31(sp)
\r
218 addi sp,sp,(FUNC_FRM_SIZE)
\r
220 lwz r14, FUNC_FRM_R14(sp)
\r
221 lwz r15, FUNC_FRM_R15(sp)
\r
222 lwz r16, FUNC_FRM_R16(sp)
\r
223 lwz r17, FUNC_FRM_R17(sp)
\r
224 lwz r18, FUNC_FRM_R18(sp)
\r
225 lwz r19, FUNC_FRM_R19(sp)
\r
226 lwz r20, FUNC_FRM_R20(sp)
\r
227 lwz r21, FUNC_FRM_R21(sp)
\r
228 lwz r22, FUNC_FRM_R22(sp)
\r
229 lwz r23, FUNC_FRM_R23(sp)
\r
230 lwz r24, FUNC_FRM_R24(sp)
\r
231 lwz r25, FUNC_FRM_R25(sp)
\r
232 lwz r26, FUNC_FRM_R26(sp)
\r
233 lwz r27, FUNC_FRM_R27(sp)
\r
234 lwz r28, FUNC_FRM_R28(sp)
\r
235 lwz r29, FUNC_FRM_R29(sp)
\r
236 lwz r30, FUNC_FRM_R30(sp)
\r
237 lwz r31, FUNC_FRM_R31(sp)
\r
238 addi sp,sp,(FUNC_FRM_SIZE)
\r
240 /* TODO: Call Os_PosttaskHook()? */
\r
246 * External input exception handlers
\r
248 .global exception_IVOR4
\r
249 .global restoreIsrContext
\r
253 /* Save the exception frame */
\r
254 stwu sp,-EXC_FRM_SIZE(sp)
\r
256 stw r3,EXC_FRM_R3(sp)
\r
259 stw r3, EXC_FRM_SRR0(sp)
\r
261 stw r3, EXC_FRM_SRR1(sp)
\r
264 stw r3, EXC_FRM_CR(sp)
\r
266 stw r3, EXC_FRM_XER(sp)
\r
268 stw r3, EXC_FRM_CTR(sp)
\r
270 stw r3, EXC_FRM_LR(sp)
\r
273 stw r3, EXC_FRM_VECTOR(sp)
\r
274 #if defined(CFG_SPE)
\r
276 /* Enable SPE (exceptions turns it off) */
\r
282 /* Create the frame */
\r
283 addi sp,sp,-ISR_FRM_SIZE
\r
284 evstdd r3, ISR_FRM_R3(sp) /* Save work reg */
\r
287 mfspr r3,SPR_SPEFSCR
\r
288 clrlwi r3,r3,24 /* Mask off non-status bits */
\r
289 stw r3,ISR_FRM_SPE_FSCR(sp)
\r
292 evsubfw r3,r3,r3 /* zero r3 */
\r
293 evaddumiaaw r3,r3 /* Add r3 = r3 + acc -> r3 = acc */
\r
294 evstdd r3,ISR_FRM_SPE_ACC(r1)
\r
296 evstdd r0, ISR_FRM_R0(sp)
\r
297 evstdd r4, ISR_FRM_R4(sp)
\r
298 evstdd r5, ISR_FRM_R5(sp)
\r
299 evstdd r6, ISR_FRM_R6(sp)
\r
300 evstdd r7, ISR_FRM_R7(sp)
\r
301 evstdd r8, ISR_FRM_R8(sp)
\r
302 evstdd r9, ISR_FRM_R9(sp)
\r
303 evstdd r10, ISR_FRM_R10(sp)
\r
304 evstdd r11, ISR_FRM_R11(sp)
\r
305 evstdd r12, ISR_FRM_R12(sp)
\r
306 evstdd r14, ISR_FRM_R14(sp)
\r
307 evstdd r15, ISR_FRM_R15(sp)
\r
308 evstdd r16, ISR_FRM_R16(sp)
\r
309 evstdd r17, ISR_FRM_R17(sp)
\r
310 evstdd r18, ISR_FRM_R18(sp)
\r
311 evstdd r19, ISR_FRM_R19(sp)
\r
312 evstdd r20, ISR_FRM_R20(sp)
\r
313 evstdd r21, ISR_FRM_R21(sp)
\r
314 evstdd r22, ISR_FRM_R22(sp)
\r
315 evstdd r23, ISR_FRM_R23(sp)
\r
316 evstdd r24, ISR_FRM_R24(sp)
\r
317 evstdd r25, ISR_FRM_R25(sp)
\r
318 evstdd r26, ISR_FRM_R26(sp)
\r
319 evstdd r27, ISR_FRM_R27(sp)
\r
320 evstdd r28, ISR_FRM_R28(sp)
\r
321 evstdd r29, ISR_FRM_R29(sp)
\r
322 evstdd r30, ISR_FRM_R30(sp)
\r
324 evstdd r31, (ISR_FRM_R31-8)(sp)
\r
327 /* Save the ISR frame */
\r
328 addi sp,sp,-ISR_FRM_SIZE
\r
329 stw r0, ISR_FRM_R0(sp)
\r
330 stw r4, ISR_FRM_R4(sp)
\r
331 stw r5, ISR_FRM_R5(sp)
\r
332 stw r6, ISR_FRM_R6(sp)
\r
333 stw r7, ISR_FRM_R7(sp)
\r
334 stw r8, ISR_FRM_R8(sp)
\r
335 stw r9, ISR_FRM_R9(sp)
\r
336 stw r10, ISR_FRM_R10(sp)
\r
337 stw r11, ISR_FRM_R11(sp)
\r
338 stw r12, ISR_FRM_R12(sp)
\r
339 stw r14, ISR_FRM_R14(sp)
\r
340 stw r15, ISR_FRM_R15(sp)
\r
341 stw r16, ISR_FRM_R16(sp)
\r
342 stw r17, ISR_FRM_R17(sp)
\r
343 stw r18, ISR_FRM_R18(sp)
\r
344 stw r19, ISR_FRM_R19(sp)
\r
345 stw r20, ISR_FRM_R20(sp)
\r
346 stw r21, ISR_FRM_R21(sp)
\r
347 stw r22, ISR_FRM_R22(sp)
\r
348 stw r23, ISR_FRM_R23(sp)
\r
349 stw r24, ISR_FRM_R24(sp)
\r
350 stw r25, ISR_FRM_R25(sp)
\r
351 stw r26, ISR_FRM_R26(sp)
\r
352 stw r27, ISR_FRM_R27(sp)
\r
353 stw r28, ISR_FRM_R28(sp)
\r
354 stw r29, ISR_FRM_R29(sp)
\r
355 stw r30, ISR_FRM_R30(sp)
\r
356 stw r31, ISR_FRM_R31(sp)
\r
360 stw r3,ISR_FRM_PATTERN(sp)
\r
361 /* Save the stack so it later can be saved in the pcb */
\r
364 /* Switch to interrupt stack if at depth 0 */
\r
365 /* Load the value Os_Sys.int_nest_cnt */
\r
366 LOAD_IND_32(r3,Os_Sys+SYS_INT_NEST_CNT)
\r
370 /* Load the interrupt stack */
\r
371 LOAD_IND_32(r1,Os_Sys+SYS_INT_STACK)
\r
375 #if defined(CFG_MPC5516)
\r
376 lis r6, INTC_IACKR_PRC0@ha
\r
377 lwz r6, INTC_IACKR_PRC0@l(r6)
\r
378 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
379 lis r6, INTC_IACKR@ha
\r
380 lwz r6, INTC_IACKR@l(r6)
\r
382 /* Check for 0 entry */
\r
387 /* The entry was 0, call panic */
\r
388 li r3,OS_ERR_SPURIOUS_INTERRUPT
\r
395 /* extract vector */
\r
397 /* Check for soft INT */
\r
400 /* Clear soft interrupt */
\r
402 LOAD_ADDR_32(3,INTC_SSCIR0)
\r
406 LOAD_ADDR_32(3,Os_Isr)
\r
408 mr r3,r4 /* "old" stack as arg1 */
\r
409 mr r4,r5 /* Vector as arg2 */
\r
410 blrl /* Call the entry */
\r
413 * The OS interrupt is ACK'd in Os_Isr(). For ISR1 it needs to call Irq_EOI()
\r
416 /* Irq_Entry have returned the stack we shall use */
\r
421 #if defined(CFG_SPE)
\r
423 // Restore SPE control/status reg.
\r
424 lwz r3,ISR_FRM_SPE_FSCR(sp)
\r
427 /* Restore SPE acc */
\r
428 evldd r3,ISR_FRM_SPE_ACC(r1)
\r
432 evldd r0, ISR_FRM_R0(sp)
\r
433 evldd r3, ISR_FRM_R4(sp)
\r
434 evldd r4, ISR_FRM_R4(sp)
\r
435 evldd r5, ISR_FRM_R5(sp)
\r
436 evldd r6, ISR_FRM_R6(sp)
\r
437 evldd r7, ISR_FRM_R7(sp)
\r
438 evldd r8, ISR_FRM_R8(sp)
\r
439 evldd r9, ISR_FRM_R9(sp)
\r
440 evldd r10, ISR_FRM_R10(sp)
\r
441 evldd r11, ISR_FRM_R11(sp)
\r
442 evldd r12, ISR_FRM_R12(sp)
\r
443 evldd r14, ISR_FRM_R14(sp)
\r
444 evldd r15, ISR_FRM_R15(sp)
\r
445 evldd r16, ISR_FRM_R16(sp)
\r
446 evldd r17, ISR_FRM_R17(sp)
\r
447 evldd r18, ISR_FRM_R18(sp)
\r
448 evldd r19, ISR_FRM_R19(sp)
\r
449 evldd r20, ISR_FRM_R20(sp)
\r
450 evldd r21, ISR_FRM_R21(sp)
\r
451 evldd r22, ISR_FRM_R22(sp)
\r
452 evldd r23, ISR_FRM_R23(sp)
\r
453 evldd r24, ISR_FRM_R24(sp)
\r
454 evldd r25, ISR_FRM_R25(sp)
\r
455 evldd r26, ISR_FRM_R26(sp)
\r
456 evldd r27, ISR_FRM_R27(sp)
\r
457 evldd r28, ISR_FRM_R28(sp)
\r
458 evldd r29, ISR_FRM_R29(sp)
\r
459 evldd r30, ISR_FRM_R30(sp)
\r
461 evldd r31, (ISR_FRM_R31-8)(sp)
\r
464 lwz r0, ISR_FRM_R0(sp)
\r
465 lwz r4, ISR_FRM_R4(sp)
\r
466 lwz r5, ISR_FRM_R5(sp)
\r
467 lwz r6, ISR_FRM_R6(sp)
\r
468 lwz r7, ISR_FRM_R7(sp)
\r
469 lwz r8, ISR_FRM_R8(sp)
\r
470 lwz r9, ISR_FRM_R9(sp)
\r
471 lwz r10, ISR_FRM_R10(sp)
\r
472 lwz r11, ISR_FRM_R11(sp)
\r
473 lwz r12, ISR_FRM_R12(sp)
\r
474 lwz r14, ISR_FRM_R14(sp)
\r
475 lwz r15, ISR_FRM_R15(sp)
\r
476 lwz r16, ISR_FRM_R16(sp)
\r
477 lwz r17, ISR_FRM_R17(sp)
\r
478 lwz r18, ISR_FRM_R18(sp)
\r
479 lwz r19, ISR_FRM_R19(sp)
\r
480 lwz r20, ISR_FRM_R20(sp)
\r
481 lwz r21, ISR_FRM_R21(sp)
\r
482 lwz r22, ISR_FRM_R22(sp)
\r
483 lwz r23, ISR_FRM_R23(sp)
\r
484 lwz r24, ISR_FRM_R24(sp)
\r
485 lwz r25, ISR_FRM_R25(sp)
\r
486 lwz r26, ISR_FRM_R26(sp)
\r
487 lwz r27, ISR_FRM_R27(sp)
\r
488 lwz r28, ISR_FRM_R28(sp)
\r
489 lwz r29, ISR_FRM_R29(sp)
\r
490 lwz r30, ISR_FRM_R30(sp)
\r
491 lwz r31, ISR_FRM_R31(sp)
\r
494 /* back to the exception frame */
\r
495 addi sp,sp,ISR_FRM_SIZE
\r
497 lwz r3, EXC_FRM_LR(sp)
\r
499 lwz r3, EXC_FRM_CTR(sp)
\r
501 lwz r3, EXC_FRM_XER(sp)
\r
503 lwz r3, EXC_FRM_CR(sp)
\r
505 lwz r3, EXC_FRM_SRR0(sp)
\r
507 lwz r3, EXC_FRM_SRR1(sp)
\r
509 lwz r3, EXC_FRM_R3(sp)
\r
510 addi sp,sp,EXC_FRM_SIZE
\r
516 * Decrementer exception. It just triggers soft interrupt 7.
\r
529 lis r3, INTC_SSCIR7@ha
\r
530 stb r4, INTC_SSCIR7@l(r3)
\r
538 /* Getting here means that the exception stack is started with:
\r
540 * r3 - saved and contains the exception number
\r
545 #if defined(__GNUC__)
\r
546 .section ".exception_tbl","ax"
\r
547 #elif defined(__CWCC__)
\r
548 #if defined(CFG_VLE)
\r
549 .section .exception_tbl,text_vle
\r
551 .section .exception_tbl,4,"rw"
\r
555 .global exception_tbl
\r
575 #if defined(CFG_SPE)
\r