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
54 /* ----------------------------[private define]------------------------------*/
\r
58 #define INTC_IACKR_PRC0 0xfff48010
\r
59 #define INTC_EOIR_PRC0 0xfff48018
\r
60 #define INTC_IACKR 0xfff48010
\r
61 #define INTC_EOIR 0xfff48018
\r
62 #define INTC_SSCIR0 0xfff48020
\r
64 /* ----------------------------[private macro]-------------------------------*/
\r
66 #define LOCK() wrteei 0
\r
67 #define UNLOCK() wrteei 1
\r
69 #define EXC_TABLE_CODE(_exc_nr) \
\r
70 stwu sp,-EXC_FRM_SIZE(sp); \
\r
71 stw r3,EXC_FRM_R3(sp); \
\r
75 #if ISR_FRM_PATTERN!=FUNC_FRM_PATTERN
\r
76 #error Context pattern must be in the same place
\r
79 /* ----------------------------[private typedef]-----------------------------*/
\r
80 /* ----------------------------[private function prototypes]-----------------*/
\r
81 /* ----------------------------[private variables]---------------------------*/
\r
82 /* ----------------------------[private functions]---------------------------*/
\r
83 /* ----------------------------[public functions]----------------------------*/
\r
87 .global Os_ArchSwapContextTo
\r
88 .global Os_ArchSwapContext
\r
89 .global Os_ArchSetSpAndCall
\r
90 #if defined(__CWCC__) && defined(CFG_VLE)
\r
91 .section .text_vle,text_vle
\r
99 Os_ArchSetSpAndCall:
\r
105 * void Os_ArchSwapContext(pcb_t *old, pcb_t *new )
\r
107 * Saves a function context on current stack, pops a new one from new context
\r
109 * r3 - pcb for old task
\r
110 * r4 - pcb for new task
\r
113 Os_ArchSwapContext:
\r
114 stwu sp,-FUNC_FRM_SIZE(sp)
\r
116 stw r0,FUNC_FRM_LR(sp)
\r
118 stw r0,FUNC_FRM_CR(sp)
\r
120 /* Save context indicator */
\r
122 stw r0,FUNC_FRM_PATTERN(sp)
\r
124 #if defined(CFG_SPE)
\r
125 stw r14, FUNC_FRM_R14(sp)
\r
126 stw r15, FUNC_FRM_R15(sp)
\r
127 stw r16, FUNC_FRM_R16(sp)
\r
128 stw r17, FUNC_FRM_R17(sp)
\r
129 stw r18, FUNC_FRM_R18(sp)
\r
130 stw r19, FUNC_FRM_R19(sp)
\r
131 stw r20, FUNC_FRM_R20(sp)
\r
132 stw r21, FUNC_FRM_R21(sp)
\r
133 stw r22, FUNC_FRM_R22(sp)
\r
134 stw r23, FUNC_FRM_R23(sp)
\r
135 stw r24, FUNC_FRM_R24(sp)
\r
136 stw r25, FUNC_FRM_R25(sp)
\r
137 stw r26, FUNC_FRM_R26(sp)
\r
138 stw r27, FUNC_FRM_R27(sp)
\r
139 stw r28, FUNC_FRM_R28(sp)
\r
140 stw r29, FUNC_FRM_R29(sp)
\r
141 stw r30, FUNC_FRM_R30(sp)
\r
142 stw r31, FUNC_FRM_R31(sp)
\r
145 /* Save registers preserved by function call */
\r
146 stw r14, FUNC_FRM_R14(sp)
\r
147 stw r15, FUNC_FRM_R15(sp)
\r
148 stw r16, FUNC_FRM_R16(sp)
\r
149 stw r17, FUNC_FRM_R17(sp)
\r
150 stw r18, FUNC_FRM_R18(sp)
\r
151 stw r19, FUNC_FRM_R19(sp)
\r
152 stw r20, FUNC_FRM_R20(sp)
\r
153 stw r21, FUNC_FRM_R21(sp)
\r
154 stw r22, FUNC_FRM_R22(sp)
\r
155 stw r23, FUNC_FRM_R23(sp)
\r
156 stw r24, FUNC_FRM_R24(sp)
\r
157 stw r25, FUNC_FRM_R25(sp)
\r
158 stw r26, FUNC_FRM_R26(sp)
\r
159 stw r27, FUNC_FRM_R27(sp)
\r
160 stw r28, FUNC_FRM_R28(sp)
\r
161 stw r29, FUNC_FRM_R29(sp)
\r
162 stw r30, FUNC_FRM_R30(sp)
\r
163 stw r31, FUNC_FRM_R31(sp)
\r
166 /* Save stack ptr... */
\r
167 stw sp,PCB_STACK_CURR_P(r3)
\r
169 /* TODO: Call Os_PretaskHook()? */
\r
174 * void Os_ArchSwapContextTo( NULL, pcb_t *new )
\r
176 * r4 - The pcb to switch to.
\r
178 Os_ArchSwapContextTo:
\r
179 /* Get stack for new task */
\r
180 lwz sp,PCB_STACK_CURR_P(r4)
\r
182 /* Set new current task */
\r
183 LOAD_ADDR_32(3,os_sys)
\r
184 stw r4,SYS_CURR_PCB_P(r3)
\r
186 /* Restore C context */
\r
187 lwz r0,FUNC_FRM_CR(sp)
\r
189 lwz r0,FUNC_FRM_LR (sp)
\r
192 /* Get the context type */
\r
193 lwz r0, FUNC_FRM_PATTERN(sp)
\r
194 cmplwi r0, FUNC_PATTERN
\r
195 beq+ restoreFuncContext
\r
196 cmplwi r0,ISR_PATTERN
\r
197 beq+ restoreIsrContext
\r
198 li r3, OS_ERR_BAD_CONTEXT
\r
201 restoreFuncContext:
\r
202 #if defined(CFG_SPE)
\r
203 evldd r14, FUNC_FRM_R14(sp)
\r
204 evldd r15, FUNC_FRM_R15(sp)
\r
205 evldd r16, FUNC_FRM_R16(sp)
\r
206 evldd r17, FUNC_FRM_R17(sp)
\r
207 evldd r18, FUNC_FRM_R18(sp)
\r
208 evldd r19, FUNC_FRM_R19(sp)
\r
209 evldd r20, FUNC_FRM_R20(sp)
\r
210 evldd r21, FUNC_FRM_R21(sp)
\r
211 evldd r22, FUNC_FRM_R22(sp)
\r
212 evldd r23, FUNC_FRM_R23(sp)
\r
213 evldd r24, FUNC_FRM_R24(sp)
\r
214 evldd r25, FUNC_FRM_R25(sp)
\r
215 evldd r26, FUNC_FRM_R26(sp)
\r
216 evldd r27, FUNC_FRM_R27(sp)
\r
217 evldd r28, FUNC_FRM_R28(sp)
\r
218 evldd r29, FUNC_FRM_R29(sp)
\r
219 evldd r30, FUNC_FRM_R30(sp)
\r
220 evldd r31, FUNC_FRM_R31(sp)
\r
221 addi sp,sp,(FUNC_FRM_SIZE)
\r
223 lwz r14, FUNC_FRM_R14(sp)
\r
224 lwz r15, FUNC_FRM_R15(sp)
\r
225 lwz r16, FUNC_FRM_R16(sp)
\r
226 lwz r17, FUNC_FRM_R17(sp)
\r
227 lwz r18, FUNC_FRM_R18(sp)
\r
228 lwz r19, FUNC_FRM_R19(sp)
\r
229 lwz r20, FUNC_FRM_R20(sp)
\r
230 lwz r21, FUNC_FRM_R21(sp)
\r
231 lwz r22, FUNC_FRM_R22(sp)
\r
232 lwz r23, FUNC_FRM_R23(sp)
\r
233 lwz r24, FUNC_FRM_R24(sp)
\r
234 lwz r25, FUNC_FRM_R25(sp)
\r
235 lwz r26, FUNC_FRM_R26(sp)
\r
236 lwz r27, FUNC_FRM_R27(sp)
\r
237 lwz r28, FUNC_FRM_R28(sp)
\r
238 lwz r29, FUNC_FRM_R29(sp)
\r
239 lwz r30, FUNC_FRM_R30(sp)
\r
240 lwz r31, FUNC_FRM_R31(sp)
\r
241 addi sp,sp,(FUNC_FRM_SIZE)
\r
243 /* TODO: Call Os_PosttaskHook()? */
\r
249 * External input exception handlers
\r
251 .global exception_IVOR4
\r
252 .global restoreIsrContext
\r
256 /* Save the exception frame */
\r
257 stwu sp,-EXC_FRM_SIZE(sp)
\r
259 stw r3,EXC_FRM_R3(sp)
\r
262 stw r3, EXC_FRM_SRR0(sp)
\r
264 stw r3, EXC_FRM_SRR1(sp)
\r
267 stw r3, EXC_FRM_CR(sp)
\r
269 stw r3, EXC_FRM_XER(sp)
\r
271 stw r3, EXC_FRM_CTR(sp)
\r
273 stw r3, EXC_FRM_LR(sp)
\r
276 stw r3, EXC_FRM_VECTOR(sp)
\r
277 #if defined(CFG_SPE)
\r
279 /* Enable SPE (exceptions turns it off) */
\r
285 /* Create the frame */
\r
286 addi sp,sp,-ISR_FRM_SIZE
\r
287 evstdd r3, ISR_FRM_R3(sp) /* Save work reg */
\r
290 mfspr r3,SPR_SPEFSCR
\r
291 clrlwi r3,r3,24 /* Mask off non-status bits */
\r
292 stw r3,ISR_FRM_SPE_FSCR(sp)
\r
295 evsubfw r3,r3,r3 /* zero r3 */
\r
296 evaddumiaaw r3,r3 /* Add r3 = r3 + acc -> r3 = acc */
\r
297 evstdd r3,ISR_FRM_SPE_ACC(r1)
\r
299 evstdd r0, ISR_FRM_R0(sp)
\r
300 evstdd r4, ISR_FRM_R4(sp)
\r
301 evstdd r5, ISR_FRM_R5(sp)
\r
302 evstdd r6, ISR_FRM_R6(sp)
\r
303 evstdd r7, ISR_FRM_R7(sp)
\r
304 evstdd r8, ISR_FRM_R8(sp)
\r
305 evstdd r9, ISR_FRM_R9(sp)
\r
306 evstdd r10, ISR_FRM_R10(sp)
\r
307 evstdd r11, ISR_FRM_R11(sp)
\r
308 evstdd r12, ISR_FRM_R12(sp)
\r
309 evstdd r14, ISR_FRM_R14(sp)
\r
310 evstdd r15, ISR_FRM_R15(sp)
\r
311 evstdd r16, ISR_FRM_R16(sp)
\r
312 evstdd r17, ISR_FRM_R17(sp)
\r
313 evstdd r18, ISR_FRM_R18(sp)
\r
314 evstdd r19, ISR_FRM_R19(sp)
\r
315 evstdd r20, ISR_FRM_R20(sp)
\r
316 evstdd r21, ISR_FRM_R21(sp)
\r
317 evstdd r22, ISR_FRM_R22(sp)
\r
318 evstdd r23, ISR_FRM_R23(sp)
\r
319 evstdd r24, ISR_FRM_R24(sp)
\r
320 evstdd r25, ISR_FRM_R25(sp)
\r
321 evstdd r26, ISR_FRM_R26(sp)
\r
322 evstdd r27, ISR_FRM_R27(sp)
\r
323 evstdd r28, ISR_FRM_R28(sp)
\r
324 evstdd r29, ISR_FRM_R29(sp)
\r
325 evstdd r30, ISR_FRM_R30(sp)
\r
327 evstdd r31, (ISR_FRM_R31-8)(sp)
\r
330 /* Save the ISR frame */
\r
331 addi sp,sp,-ISR_FRM_SIZE
\r
332 stw r0, ISR_FRM_R0(sp)
\r
333 stw r4, ISR_FRM_R4(sp)
\r
334 stw r5, ISR_FRM_R5(sp)
\r
335 stw r6, ISR_FRM_R6(sp)
\r
336 stw r7, ISR_FRM_R7(sp)
\r
337 stw r8, ISR_FRM_R8(sp)
\r
338 stw r9, ISR_FRM_R9(sp)
\r
339 stw r10, ISR_FRM_R10(sp)
\r
340 stw r11, ISR_FRM_R11(sp)
\r
341 stw r12, ISR_FRM_R12(sp)
\r
342 stw r14, ISR_FRM_R14(sp)
\r
343 stw r15, ISR_FRM_R15(sp)
\r
344 stw r16, ISR_FRM_R16(sp)
\r
345 stw r17, ISR_FRM_R17(sp)
\r
346 stw r18, ISR_FRM_R18(sp)
\r
347 stw r19, ISR_FRM_R19(sp)
\r
348 stw r20, ISR_FRM_R20(sp)
\r
349 stw r21, ISR_FRM_R21(sp)
\r
350 stw r22, ISR_FRM_R22(sp)
\r
351 stw r23, ISR_FRM_R23(sp)
\r
352 stw r24, ISR_FRM_R24(sp)
\r
353 stw r25, ISR_FRM_R25(sp)
\r
354 stw r26, ISR_FRM_R26(sp)
\r
355 stw r27, ISR_FRM_R27(sp)
\r
356 stw r28, ISR_FRM_R28(sp)
\r
357 stw r29, ISR_FRM_R29(sp)
\r
358 stw r30, ISR_FRM_R30(sp)
\r
359 stw r31, ISR_FRM_R31(sp)
\r
363 stw r3,ISR_FRM_PATTERN(sp)
\r
364 /* Save the stack so it later can be saved in the pcb */
\r
367 /* Switch to interrupt stack if at depth 0 */
\r
368 /* Load the value os_sys.int_nest_cnt */
\r
369 LOAD_IND_32(r3,os_sys+SYS_INT_NEST_CNT)
\r
373 /* Load the interrupt stack */
\r
374 LOAD_IND_32(r1,os_sys+SYS_INT_STACK)
\r
378 #if defined(CFG_MPC5516)
\r
379 lis r6, INTC_IACKR_PRC0@ha
\r
380 lwz r6, INTC_IACKR_PRC0@l(r6)
\r
381 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\r
382 lis r6, INTC_IACKR@ha
\r
383 lwz r6, INTC_IACKR@l(r6)
\r
385 /* Check for 0 entry */
\r
389 /* The entry was 0, call panic */
\r
390 li r3,OS_ERR_SPURIOUS_INTERRUPT
\r
397 /* Check for soft INT */
\r
400 /* Clear soft interrupt */
\r
402 LOAD_ADDR_32(3,INTC_SSCIR0)
\r
403 // lis r3, INTC_SSCIR0@h
\r
404 // ori r3, r3, INTC_SSCIR0@l
\r
408 LOAD_ADDR_32(3,Os_Isr)
\r
409 // lis r3, Os_Isr@h
\r
410 // ori r3, r3,Os_Isr@l
\r
412 mr r3,r4 /* "old" stack as arg1 */
\r
413 #if defined(OLD_CALL)
\r
414 lwz r4, 0x0(r6) /* Read the address from the for function/pcb entry */
\r
418 blrl /* Call the entry */
\r
421 * The OS interrupt is ACK'd in Os_Isr(). For ISR1 it needs to call Irq_EOI()
\r
424 /* Irq_Entry have returned the stack we shall use */
\r
429 #if defined(CFG_SPE)
\r
431 // Restore SPE control/status reg.
\r
432 lwz r3,ISR_FRM_SPE_FSCR(sp)
\r
435 /* Restore SPE acc */
\r
436 evldd r3,ISR_FRM_SPE_ACC(r1)
\r
440 evldd r0, ISR_FRM_R0(sp)
\r
441 evldd r3, ISR_FRM_R4(sp)
\r
442 evldd r4, ISR_FRM_R4(sp)
\r
443 evldd r5, ISR_FRM_R5(sp)
\r
444 evldd r6, ISR_FRM_R6(sp)
\r
445 evldd r7, ISR_FRM_R7(sp)
\r
446 evldd r8, ISR_FRM_R8(sp)
\r
447 evldd r9, ISR_FRM_R9(sp)
\r
448 evldd r10, ISR_FRM_R10(sp)
\r
449 evldd r11, ISR_FRM_R11(sp)
\r
450 evldd r12, ISR_FRM_R12(sp)
\r
451 evldd r14, ISR_FRM_R14(sp)
\r
452 evldd r15, ISR_FRM_R15(sp)
\r
453 evldd r16, ISR_FRM_R16(sp)
\r
454 evldd r17, ISR_FRM_R17(sp)
\r
455 evldd r18, ISR_FRM_R18(sp)
\r
456 evldd r19, ISR_FRM_R19(sp)
\r
457 evldd r20, ISR_FRM_R20(sp)
\r
458 evldd r21, ISR_FRM_R21(sp)
\r
459 evldd r22, ISR_FRM_R22(sp)
\r
460 evldd r23, ISR_FRM_R23(sp)
\r
461 evldd r24, ISR_FRM_R24(sp)
\r
462 evldd r25, ISR_FRM_R25(sp)
\r
463 evldd r26, ISR_FRM_R26(sp)
\r
464 evldd r27, ISR_FRM_R27(sp)
\r
465 evldd r28, ISR_FRM_R28(sp)
\r
466 evldd r29, ISR_FRM_R29(sp)
\r
467 evldd r30, ISR_FRM_R30(sp)
\r
469 evldd r31, (ISR_FRM_R31-8)(sp)
\r
472 lwz r0, ISR_FRM_R0(sp)
\r
473 lwz r4, ISR_FRM_R4(sp)
\r
474 lwz r5, ISR_FRM_R5(sp)
\r
475 lwz r6, ISR_FRM_R6(sp)
\r
476 lwz r7, ISR_FRM_R7(sp)
\r
477 lwz r8, ISR_FRM_R8(sp)
\r
478 lwz r9, ISR_FRM_R9(sp)
\r
479 lwz r10, ISR_FRM_R10(sp)
\r
480 lwz r11, ISR_FRM_R11(sp)
\r
481 lwz r12, ISR_FRM_R12(sp)
\r
482 lwz r14, ISR_FRM_R14(sp)
\r
483 lwz r15, ISR_FRM_R15(sp)
\r
484 lwz r16, ISR_FRM_R16(sp)
\r
485 lwz r17, ISR_FRM_R17(sp)
\r
486 lwz r18, ISR_FRM_R18(sp)
\r
487 lwz r19, ISR_FRM_R19(sp)
\r
488 lwz r20, ISR_FRM_R20(sp)
\r
489 lwz r21, ISR_FRM_R21(sp)
\r
490 lwz r22, ISR_FRM_R22(sp)
\r
491 lwz r23, ISR_FRM_R23(sp)
\r
492 lwz r24, ISR_FRM_R24(sp)
\r
493 lwz r25, ISR_FRM_R25(sp)
\r
494 lwz r26, ISR_FRM_R26(sp)
\r
495 lwz r27, ISR_FRM_R27(sp)
\r
496 lwz r28, ISR_FRM_R28(sp)
\r
497 lwz r29, ISR_FRM_R29(sp)
\r
498 lwz r30, ISR_FRM_R30(sp)
\r
499 lwz r31, ISR_FRM_R31(sp)
\r
502 /* back to the exception frame */
\r
503 addi sp,sp,ISR_FRM_SIZE
\r
505 lwz r3, EXC_FRM_LR(sp)
\r
507 lwz r3, EXC_FRM_CTR(sp)
\r
509 lwz r3, EXC_FRM_XER(sp)
\r
511 lwz r3, EXC_FRM_CR(sp)
\r
513 lwz r3, EXC_FRM_SRR0(sp)
\r
515 lwz r3, EXC_FRM_SRR1(sp)
\r
517 lwz r3, EXC_FRM_R3(sp)
\r
518 addi sp,sp,EXC_FRM_SIZE
\r
524 * Decrementer exception. It just triggers soft interrupt 7.
\r
537 lis r3, INTC_SSCIR7@ha
\r
538 stb r4, INTC_SSCIR7@l(r3)
\r
546 /* Getting here means that the exception stack is started with:
\r
548 * r3 - saved and contains the exception number
\r
553 #if defined(__GNUC__)
\r
554 .section ".exception_tbl","ax"
\r
555 #elif defined(__CWCC__)
\r
556 #if defined(CFG_VLE)
\r
557 .section .exception_tbl,text_vle
\r
559 .section .exception_tbl,4,"rw"
\r
563 .global exception_tbl
\r
583 #if defined(CFG_SPE)
\r