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
67 stwu sp,-EXC_FRM_SIZE(sp); \
\r
68 stw r3,EXC_FRM_R3(sp); \
\r
72 #if ISR_FRM_PATTERN!=FUNC_FRM_PATTERN
\r
73 #error Context pattern must be in the same place
\r
76 /* ----------------------------[private typedef]-----------------------------*/
\r
77 /* ----------------------------[private function prototypes]-----------------*/
\r
78 /* ----------------------------[private variables]---------------------------*/
\r
79 /* ----------------------------[private functions]---------------------------*/
\r
80 /* ----------------------------[public functions]----------------------------*/
\r
84 .global Os_ArchSwapContextTo
\r
85 .global Os_ArchSwapContext
\r
86 .global Os_ArchSetSpAndCall
\r
87 .global Os_Test_And_Set
\r
88 #if defined(__CWCC__) && defined(CFG_VLE)
\r
89 .section .text_vle,text_vle
\r
90 #elif defined(__DCC__)
\r
91 // Must be indented (diab)
\r
92 .section .text_vle,x
\r
93 #elif defined(__GNUC__)
\r
100 Os_ArchSetSpAndCall:
\r
106 * void Os_ArchSwapContext(pcb_t *old, pcb_t *new )
\r
108 * Saves a function context on current stack, pops a new one from new context
\r
110 * r3 - pcb for old task
\r
111 * r4 - pcb for new task
\r
114 Os_ArchSwapContext:
\r
115 stwu sp,-FUNC_FRM_SIZE(sp)
\r
117 stw r0,FUNC_FRM_LR(sp)
\r
119 stw r0,FUNC_FRM_CR(sp)
\r
121 /* Save context indicator */
\r
123 stw r0,FUNC_FRM_PATTERN(sp)
\r
125 #if defined(CFG_SPE)
\r
126 stw r14, FUNC_FRM_R14(sp)
\r
127 stw r15, FUNC_FRM_R15(sp)
\r
128 stw r16, FUNC_FRM_R16(sp)
\r
129 stw r17, FUNC_FRM_R17(sp)
\r
130 stw r18, FUNC_FRM_R18(sp)
\r
131 stw r19, FUNC_FRM_R19(sp)
\r
132 stw r20, FUNC_FRM_R20(sp)
\r
133 stw r21, FUNC_FRM_R21(sp)
\r
134 stw r22, FUNC_FRM_R22(sp)
\r
135 stw r23, FUNC_FRM_R23(sp)
\r
136 stw r24, FUNC_FRM_R24(sp)
\r
137 stw r25, FUNC_FRM_R25(sp)
\r
138 stw r26, FUNC_FRM_R26(sp)
\r
139 stw r27, FUNC_FRM_R27(sp)
\r
140 stw r28, FUNC_FRM_R28(sp)
\r
141 stw r29, FUNC_FRM_R29(sp)
\r
142 stw r30, FUNC_FRM_R30(sp)
\r
143 stw r31, FUNC_FRM_R31(sp)
\r
146 /* Save registers preserved by function call */
\r
147 stw r14, FUNC_FRM_R14(sp)
\r
148 stw r15, FUNC_FRM_R15(sp)
\r
149 stw r16, FUNC_FRM_R16(sp)
\r
150 stw r17, FUNC_FRM_R17(sp)
\r
151 stw r18, FUNC_FRM_R18(sp)
\r
152 stw r19, FUNC_FRM_R19(sp)
\r
153 stw r20, FUNC_FRM_R20(sp)
\r
154 stw r21, FUNC_FRM_R21(sp)
\r
155 stw r22, FUNC_FRM_R22(sp)
\r
156 stw r23, FUNC_FRM_R23(sp)
\r
157 stw r24, FUNC_FRM_R24(sp)
\r
158 stw r25, FUNC_FRM_R25(sp)
\r
159 stw r26, FUNC_FRM_R26(sp)
\r
160 stw r27, FUNC_FRM_R27(sp)
\r
161 stw r28, FUNC_FRM_R28(sp)
\r
162 stw r29, FUNC_FRM_R29(sp)
\r
163 stw r30, FUNC_FRM_R30(sp)
\r
164 stw r31, FUNC_FRM_R31(sp)
\r
167 /* Save stack ptr... */
\r
168 stw sp,PCB_STACK_CURR_P(r3)
\r
170 /* TODO: Call Os_PretaskHook()? */
\r
175 * void Os_ArchSwapContextTo( NULL, pcb_t *new )
\r
177 * r4 - The pcb to switch to.
\r
179 Os_ArchSwapContextTo:
\r
180 /* Get stack for new task */
\r
181 lwz sp,PCB_STACK_CURR_P(r4)
\r
183 /* Set new current task */
\r
184 LOAD_ADDR_32(3,Os_Sys)
\r
185 stw r4,SYS_CURR_PCB_P(r3)
\r
187 /* Restore C context */
\r
188 lwz r0,FUNC_FRM_CR(sp)
\r
190 lwz r0,FUNC_FRM_LR (sp)
\r
193 /* Get the context type */
\r
194 lwz r0, FUNC_FRM_PATTERN(sp)
\r
195 cmplwi r0, FUNC_PATTERN
\r
196 beq+ restoreFuncContext
\r
197 cmplwi r0,ISR_PATTERN
\r
198 beq+ restoreIsrContext
\r
199 li r3, OS_ERR_BAD_CONTEXT
\r
202 restoreFuncContext:
\r
203 #if defined(CFG_SPE)
\r
204 evldd r14, FUNC_FRM_R14(sp)
\r
205 evldd r15, FUNC_FRM_R15(sp)
\r
206 evldd r16, FUNC_FRM_R16(sp)
\r
207 evldd r17, FUNC_FRM_R17(sp)
\r
208 evldd r18, FUNC_FRM_R18(sp)
\r
209 evldd r19, FUNC_FRM_R19(sp)
\r
210 evldd r20, FUNC_FRM_R20(sp)
\r
211 evldd r21, FUNC_FRM_R21(sp)
\r
212 evldd r22, FUNC_FRM_R22(sp)
\r
213 evldd r23, FUNC_FRM_R23(sp)
\r
214 evldd r24, FUNC_FRM_R24(sp)
\r
215 evldd r25, FUNC_FRM_R25(sp)
\r
216 evldd r26, FUNC_FRM_R26(sp)
\r
217 evldd r27, FUNC_FRM_R27(sp)
\r
218 evldd r28, FUNC_FRM_R28(sp)
\r
219 evldd r29, FUNC_FRM_R29(sp)
\r
220 evldd r30, FUNC_FRM_R30(sp)
\r
221 evldd r31, FUNC_FRM_R31(sp)
\r
222 addi sp,sp,(FUNC_FRM_SIZE)
\r
224 lwz r14, FUNC_FRM_R14(sp)
\r
225 lwz r15, FUNC_FRM_R15(sp)
\r
226 lwz r16, FUNC_FRM_R16(sp)
\r
227 lwz r17, FUNC_FRM_R17(sp)
\r
228 lwz r18, FUNC_FRM_R18(sp)
\r
229 lwz r19, FUNC_FRM_R19(sp)
\r
230 lwz r20, FUNC_FRM_R20(sp)
\r
231 lwz r21, FUNC_FRM_R21(sp)
\r
232 lwz r22, FUNC_FRM_R22(sp)
\r
233 lwz r23, FUNC_FRM_R23(sp)
\r
234 lwz r24, FUNC_FRM_R24(sp)
\r
235 lwz r25, FUNC_FRM_R25(sp)
\r
236 lwz r26, FUNC_FRM_R26(sp)
\r
237 lwz r27, FUNC_FRM_R27(sp)
\r
238 lwz r28, FUNC_FRM_R28(sp)
\r
239 lwz r29, FUNC_FRM_R29(sp)
\r
240 lwz r30, FUNC_FRM_R30(sp)
\r
241 lwz r31, FUNC_FRM_R31(sp)
\r
242 addi sp,sp,(FUNC_FRM_SIZE)
\r
244 /* TODO: Call Os_PosttaskHook()? */
\r
250 * External input exception handlers
\r
252 .global exception_IVOR4
\r
253 .global restoreIsrContext
\r
257 /* Save the exception frame */
\r
258 stwu sp,-EXC_FRM_SIZE(sp)
\r
260 stw r3,EXC_FRM_R3(sp)
\r
263 stw r3, EXC_FRM_SRR0(sp)
\r
265 stw r3, EXC_FRM_SRR1(sp)
\r
268 stw r3, EXC_FRM_CR(sp)
\r
270 stw r3, EXC_FRM_XER(sp)
\r
272 stw r3, EXC_FRM_CTR(sp)
\r
274 stw r3, EXC_FRM_LR(sp)
\r
277 stw r3, EXC_FRM_VECTOR(sp)
\r
278 #if defined(CFG_SPE)
\r
280 /* Enable SPE (exceptions turns it off) */
\r
286 /* Create the frame */
\r
287 addi sp,sp,-ISR_FRM_SIZE
\r
288 evstdd r3, ISR_FRM_R3(sp) /* Save work reg */
\r
291 mfspr r3,SPR_SPEFSCR
\r
292 clrlwi r3,r3,24 /* Mask off non-status bits */
\r
293 stw r3,ISR_FRM_SPE_FSCR(sp)
\r
296 evsubfw r3,r3,r3 /* zero r3 */
\r
297 evaddumiaaw r3,r3 /* Add r3 = r3 + acc -> r3 = acc */
\r
298 evstdd r3,ISR_FRM_SPE_ACC(r1)
\r
300 evstdd r0, ISR_FRM_R0(sp)
\r
301 evstdd r4, ISR_FRM_R4(sp)
\r
302 evstdd r5, ISR_FRM_R5(sp)
\r
303 evstdd r6, ISR_FRM_R6(sp)
\r
304 evstdd r7, ISR_FRM_R7(sp)
\r
305 evstdd r8, ISR_FRM_R8(sp)
\r
306 evstdd r9, ISR_FRM_R9(sp)
\r
307 evstdd r10, ISR_FRM_R10(sp)
\r
308 evstdd r11, ISR_FRM_R11(sp)
\r
309 evstdd r12, ISR_FRM_R12(sp)
\r
310 evstdd r14, ISR_FRM_R14(sp)
\r
311 evstdd r15, ISR_FRM_R15(sp)
\r
312 evstdd r16, ISR_FRM_R16(sp)
\r
313 evstdd r17, ISR_FRM_R17(sp)
\r
314 evstdd r18, ISR_FRM_R18(sp)
\r
315 evstdd r19, ISR_FRM_R19(sp)
\r
316 evstdd r20, ISR_FRM_R20(sp)
\r
317 evstdd r21, ISR_FRM_R21(sp)
\r
318 evstdd r22, ISR_FRM_R22(sp)
\r
319 evstdd r23, ISR_FRM_R23(sp)
\r
320 evstdd r24, ISR_FRM_R24(sp)
\r
321 evstdd r25, ISR_FRM_R25(sp)
\r
322 evstdd r26, ISR_FRM_R26(sp)
\r
323 evstdd r27, ISR_FRM_R27(sp)
\r
324 evstdd r28, ISR_FRM_R28(sp)
\r
325 evstdd r29, ISR_FRM_R29(sp)
\r
326 evstdd r30, ISR_FRM_R30(sp)
\r
328 evstdd r31, (ISR_FRM_R31-8)(sp)
\r
331 /* Save the ISR frame */
\r
332 addi sp,sp,-ISR_FRM_SIZE
\r
333 stw r0, ISR_FRM_R0(sp)
\r
334 stw r4, ISR_FRM_R4(sp)
\r
335 stw r5, ISR_FRM_R5(sp)
\r
336 stw r6, ISR_FRM_R6(sp)
\r
337 stw r7, ISR_FRM_R7(sp)
\r
338 stw r8, ISR_FRM_R8(sp)
\r
339 stw r9, ISR_FRM_R9(sp)
\r
340 stw r10, ISR_FRM_R10(sp)
\r
341 stw r11, ISR_FRM_R11(sp)
\r
342 stw r12, ISR_FRM_R12(sp)
\r
343 stw r14, ISR_FRM_R14(sp)
\r
344 stw r15, ISR_FRM_R15(sp)
\r
345 stw r16, ISR_FRM_R16(sp)
\r
346 stw r17, ISR_FRM_R17(sp)
\r
347 stw r18, ISR_FRM_R18(sp)
\r
348 stw r19, ISR_FRM_R19(sp)
\r
349 stw r20, ISR_FRM_R20(sp)
\r
350 stw r21, ISR_FRM_R21(sp)
\r
351 stw r22, ISR_FRM_R22(sp)
\r
352 stw r23, ISR_FRM_R23(sp)
\r
353 stw r24, ISR_FRM_R24(sp)
\r
354 stw r25, ISR_FRM_R25(sp)
\r
355 stw r26, ISR_FRM_R26(sp)
\r
356 stw r27, ISR_FRM_R27(sp)
\r
357 stw r28, ISR_FRM_R28(sp)
\r
358 stw r29, ISR_FRM_R29(sp)
\r
359 stw r30, ISR_FRM_R30(sp)
\r
360 stw r31, ISR_FRM_R31(sp)
\r
364 stw r3,ISR_FRM_PATTERN(sp)
\r
365 /* Save the stack so it later can be saved in the pcb */
\r
368 /* Switch to interrupt stack if at depth 0 */
\r
369 /* Load the value Os_Sys.int_nest_cnt */
\r
370 LOAD_IND_32(r3,(Os_Sys+SYS_INT_NEST_CNT))
\r
374 /* Load the interrupt stack */
\r
375 LOAD_IND_32(r1,(Os_Sys+SYS_INT_STACK))
\r
379 #if defined(CFG_MPC5516)|| defined(CFG_MPC5668)
\r
380 lis r6, INTC_IACKR_PRC0@ha
\r
381 lwz r6, INTC_IACKR_PRC0@l(r6)
\r
382 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567) || defined(CFG_MPC5606S)
\r
383 lis r6, INTC_IACKR@ha
\r
384 lwz r6, INTC_IACKR@l(r6)
\r
386 #error No CPU selected
\r
388 /* Check for 0 entry */
\r
393 /* The entry was 0, call panic */
\r
394 li r3,OS_ERR_SPURIOUS_INTERRUPT
\r
401 /* extract vector */
\r
403 /* Check for soft INT */
\r
406 /* Clear soft interrupt */
\r
408 LOAD_ADDR_32(3,INTC_SSCIR0)
\r
412 LOAD_ADDR_32(3,Os_Isr)
\r
414 mr r3,r4 /* "old" stack as arg1 */
\r
415 mr r4,r5 /* Vector as arg2 */
\r
416 blrl /* Call the entry */
\r
419 * The OS interrupt is ACK'd in Os_Isr(). For ISR1 it needs to call Irq_EOI()
\r
422 /* Irq_Entry have returned the stack we shall use */
\r
427 #if defined(CFG_SPE)
\r
429 // Restore SPE control/status reg.
\r
430 lwz r3,ISR_FRM_SPE_FSCR(sp)
\r
433 /* Restore SPE acc */
\r
434 evldd r3,ISR_FRM_SPE_ACC(r1)
\r
438 evldd r0, ISR_FRM_R0(sp)
\r
439 evldd r3, ISR_FRM_R4(sp)
\r
440 evldd r4, ISR_FRM_R4(sp)
\r
441 evldd r5, ISR_FRM_R5(sp)
\r
442 evldd r6, ISR_FRM_R6(sp)
\r
443 evldd r7, ISR_FRM_R7(sp)
\r
444 evldd r8, ISR_FRM_R8(sp)
\r
445 evldd r9, ISR_FRM_R9(sp)
\r
446 evldd r10, ISR_FRM_R10(sp)
\r
447 evldd r11, ISR_FRM_R11(sp)
\r
448 evldd r12, ISR_FRM_R12(sp)
\r
449 evldd r14, ISR_FRM_R14(sp)
\r
450 evldd r15, ISR_FRM_R15(sp)
\r
451 evldd r16, ISR_FRM_R16(sp)
\r
452 evldd r17, ISR_FRM_R17(sp)
\r
453 evldd r18, ISR_FRM_R18(sp)
\r
454 evldd r19, ISR_FRM_R19(sp)
\r
455 evldd r20, ISR_FRM_R20(sp)
\r
456 evldd r21, ISR_FRM_R21(sp)
\r
457 evldd r22, ISR_FRM_R22(sp)
\r
458 evldd r23, ISR_FRM_R23(sp)
\r
459 evldd r24, ISR_FRM_R24(sp)
\r
460 evldd r25, ISR_FRM_R25(sp)
\r
461 evldd r26, ISR_FRM_R26(sp)
\r
462 evldd r27, ISR_FRM_R27(sp)
\r
463 evldd r28, ISR_FRM_R28(sp)
\r
464 evldd r29, ISR_FRM_R29(sp)
\r
465 evldd r30, ISR_FRM_R30(sp)
\r
467 evldd r31, (ISR_FRM_R31-8)(sp)
\r
470 lwz r0, ISR_FRM_R0(sp)
\r
471 lwz r4, ISR_FRM_R4(sp)
\r
472 lwz r5, ISR_FRM_R5(sp)
\r
473 lwz r6, ISR_FRM_R6(sp)
\r
474 lwz r7, ISR_FRM_R7(sp)
\r
475 lwz r8, ISR_FRM_R8(sp)
\r
476 lwz r9, ISR_FRM_R9(sp)
\r
477 lwz r10, ISR_FRM_R10(sp)
\r
478 lwz r11, ISR_FRM_R11(sp)
\r
479 lwz r12, ISR_FRM_R12(sp)
\r
480 lwz r14, ISR_FRM_R14(sp)
\r
481 lwz r15, ISR_FRM_R15(sp)
\r
482 lwz r16, ISR_FRM_R16(sp)
\r
483 lwz r17, ISR_FRM_R17(sp)
\r
484 lwz r18, ISR_FRM_R18(sp)
\r
485 lwz r19, ISR_FRM_R19(sp)
\r
486 lwz r20, ISR_FRM_R20(sp)
\r
487 lwz r21, ISR_FRM_R21(sp)
\r
488 lwz r22, ISR_FRM_R22(sp)
\r
489 lwz r23, ISR_FRM_R23(sp)
\r
490 lwz r24, ISR_FRM_R24(sp)
\r
491 lwz r25, ISR_FRM_R25(sp)
\r
492 lwz r26, ISR_FRM_R26(sp)
\r
493 lwz r27, ISR_FRM_R27(sp)
\r
494 lwz r28, ISR_FRM_R28(sp)
\r
495 lwz r29, ISR_FRM_R29(sp)
\r
496 lwz r30, ISR_FRM_R30(sp)
\r
497 lwz r31, ISR_FRM_R31(sp)
\r
500 /* back to the exception frame */
\r
501 addi sp,sp,ISR_FRM_SIZE
\r
503 lwz r3, EXC_FRM_LR(sp)
\r
505 lwz r3, EXC_FRM_CTR(sp)
\r
507 lwz r3, EXC_FRM_XER(sp)
\r
509 lwz r3, EXC_FRM_CR(sp)
\r
511 lwz r3, EXC_FRM_SRR0(sp)
\r
513 lwz r3, EXC_FRM_SRR1(sp)
\r
515 lwz r3, EXC_FRM_R3(sp)
\r
516 addi sp,sp,EXC_FRM_SIZE
\r
522 * Decrementer exception. It just triggers soft interrupt 7.
\r
535 lis r3, INTC_SSCIR7@ha
\r
536 stb r4, INTC_SSCIR7@l(r3)
\r
544 /* Getting here means that the exception stack is started with:
\r
546 * r3 - saved and contains the exception number
\r
551 #if defined(__GNUC__)
\r
552 .section ".exception_tbl","ax"
\r
553 #elif defined(__CWCC__)
\r
554 #if defined(CFG_VLE)
\r
555 .section .exception_tbl,text_vle
\r
557 .section .exception_tbl,4,"rw"
\r
559 #elif defined(__DCC__)
\r
560 // Must be indented (diab)
\r
561 .section .text_vle,x
\r
565 .global exception_tbl
\r
579 #if defined(CFG_MPC5606S)
\r
589 #if defined(CFG_SPE)
\r