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
34 * The offset's (d or D)for SPE instructions are ridiculously low.
\r
35 * Normally you have 16-bits offset, but when using spe load and store
\r
36 * you can use only 8-bit.
\r
40 /* ----------------------------[includes]------------------------------------*/
\r
42 #include "asm_ppc.h"
\r
43 #include "arch_offset.h"
\r
44 #include "asm_offset.h"
\r
45 #include "arch_stack.h"
\r
47 // #include "asm_book_e.h"
\r
48 .extern os_intc_pcb_tbl
\r
49 .extern os_intc_types_tbl
\r
51 .extern Os_ArchPanic
\r
53 #if defined(CFG_VLE)
\r
60 #define addi e_addi /* true ?*/
\r
61 #define subi e_subi /* true ?*/
\r
64 /* ----------------------------[private define]------------------------------*/
\r
66 #define INTC_IACKR_PRC0 0xfff48010
\r
67 #define INTC_EOIR_PRC0 0xfff48018
\r
68 #define INTC_IACKR 0xfff48010
\r
69 #define INTC_EOIR 0xfff48018
\r
70 #define INTC_SSCIR0 0xfff48020
\r
72 /* ----------------------------[private macro]-------------------------------*/
\r
74 #define LOCK() wrteei 0
\r
75 #define UNLOCK() wrteei 1
\r
77 #define EXC_TABLE_CODE(_exc_nr) \
\r
78 stwu sp,-EXC_FRM_SIZE(sp); \
\r
79 stw r3,EXC_FRM_R3(sp); \
\r
83 #if ISR_FRM_PATTERN!=FUNC_FRM_PATTERN
\r
84 #error Context pattern must be in the same place
\r
87 /* ----------------------------[private typedef]-----------------------------*/
\r
88 /* ----------------------------[private function prototypes]-----------------*/
\r
89 /* ----------------------------[private variables]---------------------------*/
\r
90 /* ----------------------------[private functions]---------------------------*/
\r
91 /* ----------------------------[public functions]----------------------------*/
\r
95 .global Os_ArchSwapContextTo
\r
96 .global Os_ArchSwapContext
\r
97 .global Os_ArchSetSpAndCall
\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 cmpli 0, r0, FUNC_PATTERN
\r
196 beq+ restoreFuncContext
\r
197 cmpli 0, 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(r3,os_sys+SYS_INT_STACK)
\r
379 #if defined(CFG_MPC5516)
\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)
\r
383 lis r6, INTC_IACKR@ha
\r
384 lwz r6, INTC_IACKR@l(r6)
\r
386 /* Check for 0 entry */
\r
390 /* The entry was 0, call panic */
\r
391 li r3,OS_ERR_SPURIOUS_INTERRUPT
\r
398 /* Check for soft INT */
\r
401 /* Clear soft interrupt */
\r
403 lis r3, INTC_SSCIR0@h
\r
404 ori r3, r3, INTC_SSCIR0@l
\r
410 ori r3, r3,Os_Isr@l
\r
412 mr r3,r4 /* "old" stack as arg1 */
\r
413 lwz r4, 0x0(r6) /* Read the address from the for function/pcb entry */
\r
414 blrl /* Call the entry */
\r
417 * The OS interrupt is ACK'd in Os_Isr(). For ISR1 it needs to call Irq_EOI()
\r
420 /* Irq_Entry have returned the stack we shall use */
\r
425 #if defined(CFG_SPE)
\r
427 // Restore SPE control/status reg.
\r
428 lwz r3,ISR_FRM_SPE_FSCR(sp)
\r
431 /* Restore SPE acc */
\r
432 evldd r3,ISR_FRM_SPE_ACC(r1)
\r
436 evldd r0, ISR_FRM_R0(sp)
\r
437 evldd r3, ISR_FRM_R4(sp)
\r
438 evldd r4, ISR_FRM_R4(sp)
\r
439 evldd r5, ISR_FRM_R5(sp)
\r
440 evldd r6, ISR_FRM_R6(sp)
\r
441 evldd r7, ISR_FRM_R7(sp)
\r
442 evldd r8, ISR_FRM_R8(sp)
\r
443 evldd r9, ISR_FRM_R9(sp)
\r
444 evldd r10, ISR_FRM_R10(sp)
\r
445 evldd r11, ISR_FRM_R11(sp)
\r
446 evldd r12, ISR_FRM_R12(sp)
\r
447 evldd r14, ISR_FRM_R14(sp)
\r
448 evldd r15, ISR_FRM_R15(sp)
\r
449 evldd r16, ISR_FRM_R16(sp)
\r
450 evldd r17, ISR_FRM_R17(sp)
\r
451 evldd r18, ISR_FRM_R18(sp)
\r
452 evldd r19, ISR_FRM_R19(sp)
\r
453 evldd r20, ISR_FRM_R20(sp)
\r
454 evldd r21, ISR_FRM_R21(sp)
\r
455 evldd r22, ISR_FRM_R22(sp)
\r
456 evldd r23, ISR_FRM_R23(sp)
\r
457 evldd r24, ISR_FRM_R24(sp)
\r
458 evldd r25, ISR_FRM_R25(sp)
\r
459 evldd r26, ISR_FRM_R26(sp)
\r
460 evldd r27, ISR_FRM_R27(sp)
\r
461 evldd r28, ISR_FRM_R28(sp)
\r
462 evldd r29, ISR_FRM_R29(sp)
\r
463 evldd r30, ISR_FRM_R30(sp)
\r
465 evldd r31, (ISR_FRM_R31-8)(sp)
\r
468 lwz r0, ISR_FRM_R0(sp)
\r
469 lwz r4, ISR_FRM_R4(sp)
\r
470 lwz r5, ISR_FRM_R5(sp)
\r
471 lwz r6, ISR_FRM_R6(sp)
\r
472 lwz r7, ISR_FRM_R7(sp)
\r
473 lwz r8, ISR_FRM_R8(sp)
\r
474 lwz r9, ISR_FRM_R9(sp)
\r
475 lwz r10, ISR_FRM_R10(sp)
\r
476 lwz r11, ISR_FRM_R11(sp)
\r
477 lwz r12, ISR_FRM_R12(sp)
\r
478 lwz r14, ISR_FRM_R14(sp)
\r
479 lwz r15, ISR_FRM_R15(sp)
\r
480 lwz r16, ISR_FRM_R16(sp)
\r
481 lwz r17, ISR_FRM_R17(sp)
\r
482 lwz r18, ISR_FRM_R18(sp)
\r
483 lwz r19, ISR_FRM_R19(sp)
\r
484 lwz r20, ISR_FRM_R20(sp)
\r
485 lwz r21, ISR_FRM_R21(sp)
\r
486 lwz r22, ISR_FRM_R22(sp)
\r
487 lwz r23, ISR_FRM_R23(sp)
\r
488 lwz r24, ISR_FRM_R24(sp)
\r
489 lwz r25, ISR_FRM_R25(sp)
\r
490 lwz r26, ISR_FRM_R26(sp)
\r
491 lwz r27, ISR_FRM_R27(sp)
\r
492 lwz r28, ISR_FRM_R28(sp)
\r
493 lwz r29, ISR_FRM_R29(sp)
\r
494 lwz r30, ISR_FRM_R30(sp)
\r
495 lwz r31, ISR_FRM_R31(sp)
\r
498 /* back to the exception frame */
\r
499 addi sp,sp,ISR_FRM_SIZE
\r
501 lwz r3, EXC_FRM_LR(sp)
\r
503 lwz r3, EXC_FRM_CTR(sp)
\r
505 lwz r3, EXC_FRM_XER(sp)
\r
507 lwz r3, EXC_FRM_CR(sp)
\r
509 lwz r3, EXC_FRM_SRR0(sp)
\r
511 lwz r3, EXC_FRM_SRR1(sp)
\r
513 lwz r3, EXC_FRM_R3(sp)
\r
514 addi sp,sp,EXC_FRM_SIZE
\r
520 * Decrementer exception. It just triggers soft interrupt 7.
\r
533 lis r3, INTC_SSCIR7@ha
\r
534 stb r4, INTC_SSCIR7@l(r3)
\r
542 /* Getting here means that the exception stack is started with:
\r
544 * r3 - saved and contains the exception number
\r
549 #if defined(__GNUC__)
\r
550 .section ".exception_tbl","ax"
\r
551 #elif defined(__CWCC__)
\r
552 .section .exception_tbl,4,"rw"
\r
555 .global exception_tbl
\r
575 #if defined(CFG_SPE)
\r