]> rtime.felk.cvut.cz Git - arc.git/blobdiff - arch/ppc/mpc55xx/kernel/arch_krn.sx
Isr almost done
[arc.git] / arch / ppc / mpc55xx / kernel / arch_krn.sx
index f3058d2fb1b0c5b48cb4c323aef37655a039a0a1..603ef8535d967475c754a5e86083653d85513562 100644 (file)
@@ -1,74 +1,99 @@
-\r
-/*\r
- * IVOR4\r
- * 1. Save stack frames: EXC, VGPR, NVGPR and C\r
- * 2. Call Irq_Entry(void *curr_stack)\r
- * 2.1 Check for exception\r
- * 2.2 If softint, clear it.\r
- * 2.3 If PROC_ISR1, then just call the function\r
- * 2.4 If PROC_ISR2 -> it's a PCB, let the OS handle it.\r
+/* \r
+ *\r
+ *  The Irq_IsrTypeTable does not exist any more.\r
+ *  The Irq_VectorTable is now a pure function table (not mixed pcb and functions )\r
+ *  The PPC interrupt handling is a bit faster.\r
+ * \r
+ *\r
+ *   New files for arch offsets? \r
+ *   Bypassed Irq_Entry()...\r
+ *  TODO:\r
+ *    Move pre/post hooks into swap code?\r
+ *\r
+ *\r
+ * IMPLEMENTATION NOTES\r
+ *  OPT: For ISR1 (interrupts always off) the there is no need to save r13-r31 since\r
+ *  it will be saved by the C-function. \r
  */\r
-\r
-#define _ASSEMBLER_\r
-#include "asm_ppc.h"\r
-#include "asm_offset.h"\r
-#include "asm_book_e.h"\r
-.extern os_intc_pcb_tbl\r
-.extern os_intc_types_tbl\r
-.extern os_sys\r
-\r
-\r
+       \r
 /*\r
  * Small assembler school\r
- * Compare imm(32-bit)\r
- * > cmpwi rA,100\r
- * Extract bits and right adjust\r
- * > extrwi rA,rS,n,b  ( n-number of bits, b- startbit )\r
+ *  Compare imm(32-bit)\r
+ *   $ cmpwi rA,100\r
+ *  Extract bits and right adjust\r
+ *   $ extrwi rA,rS,n,b  ( n-number of bits, b- startbit )\r
+ *  Use of @ha,@h,@l. Use @ha for arithmetic instructions to compensate for sign.\r
+ *  To cause less confusion use load and logical instructions instead of arithmetic ones.\r
+ *   $ lis r3,0x8000@h    \r
+ *   $ ori r3,r3,0x08000@l\r
+ *  is the same as \r
+ *   $ addis r3,0x8000@ha    \r
+ *   $ addi r3,r3,0x08000@l\r
  *\r
  * Note!\r
- * The offset's (d or D)for SPE instructins are rediculously low.\r
+ * The offset's (d or D)for SPE instructions are ridiculously low.\r
  * Normally you have 16-bits offset, but when using spe load and store\r
  * you can use only 8-bit.\r
 */\r
 \r
-#define        LOCK()                  wrteei  0\r
-#define        UNLOCK()                wrteei  1\r
 \r
+/* ----------------------------[includes]------------------------------------*/\r
+#define _ASSEMBLER_\r
+#include "asm_ppc.h"\r
+#include "arch_offset.h"\r
+#include "asm_offset.h"\r
+#include "arch_stack.h"\r
 \r
-.extern os_proc_start_extended\r
+// #include "asm_book_e.h"\r
+.extern os_intc_pcb_tbl\r
+.extern os_intc_types_tbl\r
+.extern Os_Sys\r
+.extern Os_ArchPanic\r
 \r
-//-------------------------------------------------------------------\r
+#if defined(CFG_VLE)\r
+#define lis            e_lis\r
+#define li             se_li\r
+#define lwz        e_lwz\r
+#define stwu   e_stwu\r
+#define stw            e_stw\r
+#define b              e_b\r
+#define addi   e_addi          /* true ?*/\r
+#define subi   e_subi          /* true ?*/\r
+#endif         \r
 \r
-    .global os_exception_IVOR8\r
-    .balign 16\r
-os_exception_IVOR8:\r
-       stwu    sp,-(EXC_SIZE+VGPR_SIZE)(sp)\r
-       stw     r3,EXC_R3_OFF(r1)\r
-       stw     r4,EXC_R4_OFF(r1)\r
-       SAVE_EXC_FRAME(3,1,0,SPR_SRR0,SPR_SRR1)\r
-       SAVE_VGPR(1,EXC_SIZE);\r
-       li              r3,328\r
-       stw     r3,EXC_VECTOR_OFF(r1)\r
+/* ----------------------------[private define]------------------------------*/\r
 \r
-       rfi\r
+//#define OLD_CALL             \r
 \r
-dummy_int:\r
-               b dummy_int\r
+#define INTC_IACKR_PRC0                0xfff48010 \r
+#define INTC_EOIR_PRC0         0xfff48018\r
+#define INTC_IACKR                     0xfff48010\r
+#define INTC_EOIR                      0xfff48018\r
+#define INTC_SSCIR0                    0xfff48020\r
 \r
-/*--------------------------------------------------------------------\r
- * void os_swap_context(pcb_t *old, pcb_t *new )\r
- *\r
- * Saves a small context on current stack, pops a new one from new context\r
- *\r
- * r3 - pcb for old process\r
- * r4 - pcb for new process\r
- *\r
- *--------------------------------------------------------------------*/\r
+/* ----------------------------[private macro]-------------------------------*/\r
+\r
+#define        LOCK()                  wrteei  0\r
+#define        UNLOCK()                wrteei  1\r
+\r
+#define EXC_TABLE_CODE(_exc_nr)        \\r
+       stwu    sp,-EXC_FRM_SIZE(sp);   \\r
+       stw             r3,EXC_FRM_R3(sp);              \\r
+       li          r3,_exc_nr;                         \\r
+       b               handleException                 \r
 \r
-// TODO: this assumes that both are in user mode?.. can this happen under trusted functions?\r
-//       When I get here we're ALWAYS in kernel mode\r
+#if ISR_FRM_PATTERN!=FUNC_FRM_PATTERN\r
+#error Context pattern must be in the same place\r
+#endif\r
+\r
+/* ----------------------------[private typedef]-----------------------------*/\r
+/* ----------------------------[private function prototypes]-----------------*/\r
+/* ----------------------------[private variables]---------------------------*/\r
+/* ----------------------------[private functions]---------------------------*/\r
+/* ----------------------------[public functions]----------------------------*/\r
+\r
+.extern Os_Isr\r
 \r
-.global Os_ArchSwapContextToW\r
 .global Os_ArchSwapContextTo\r
 .global Os_ArchSwapContext\r
 .global Os_ArchSetSpAndCall\r
@@ -79,111 +104,485 @@ Os_ArchSetSpAndCall:
                mtlr r4\r
                blr\r
 \r
-Os_ArchSwapContextToW:\r
-               mr              r1,r5\r
-               b               Os_ArchSwapContextTo\r
-\r
+/**\r
+ * void Os_ArchSwapContext(pcb_t *old, pcb_t *new )\r
+ *\r
+ * Saves a function context on current stack, pops a new one from new context\r
+ *\r
+ * r3 - pcb for old task\r
+ * r4 - pcb for new task\r
+ *\r
+ */\r
 Os_ArchSwapContext:\r
-               // allocate space for context+nvgpr\r
-               // (no need for proper stack-frame here)\r
-               stwu    r1,-(C_SIZE+NVGPR_SIZE)(r1)\r
-               // save lr and cr */\r
-               mflr    r0\r
-               stw             r0,C_LR_OFF(sp)\r
-               mfcr    r0\r
-               stw             r0,C_CR_OFF(sp)\r
-               // Save small-context pattern\r
-               li              r0,SC_PATTERN\r
-               stw             r0,C_CONTEXT_OFF(sp)\r
-               // Save registers preserved by function call\r
-               SAVE_NVGPR(sp,(C_SIZE-14*GPR_SIZE))\r
-// Save stack ptr...\r
-               stw             sp,PCB_STACK_CURR_P(r3)\r
-\r
-// Stack frame here\r
-// --------- bottom( high address )\r
-//  SC_xxx\r
-//  C_xxx\r
-// --------- <- stack.curr\r
-//\r
-// --------- top( low address )\r
-\r
-\r
-// TODO: If we change application we must change mmu setup\r
+       stwu    sp,-FUNC_FRM_SIZE(sp)\r
+       mflr    r0\r
+       stw             r0,FUNC_FRM_LR(sp)\r
+       mfcr    r0\r
+       stw             r0,FUNC_FRM_CR(sp)\r
+       \r
+       /* Save context indicator */\r
+       li              r0,FUNC_PATTERN\r
+       stw             r0,FUNC_FRM_PATTERN(sp)\r
+\r
+#if defined(CFG_SPE)\r
+       stw             r14, FUNC_FRM_R14(sp)\r
+       stw             r15, FUNC_FRM_R15(sp)\r
+       stw             r16, FUNC_FRM_R16(sp)\r
+       stw             r17, FUNC_FRM_R17(sp)\r
+       stw             r18, FUNC_FRM_R18(sp)\r
+       stw             r19, FUNC_FRM_R19(sp)\r
+       stw             r20, FUNC_FRM_R20(sp)\r
+       stw             r21, FUNC_FRM_R21(sp)\r
+       stw             r22, FUNC_FRM_R22(sp)\r
+       stw             r23, FUNC_FRM_R23(sp)\r
+       stw             r24, FUNC_FRM_R24(sp)\r
+       stw             r25, FUNC_FRM_R25(sp)\r
+       stw             r26, FUNC_FRM_R26(sp)\r
+       stw             r27, FUNC_FRM_R27(sp)\r
+       stw             r28, FUNC_FRM_R28(sp)\r
+       stw             r29, FUNC_FRM_R29(sp)\r
+       stw             r30, FUNC_FRM_R30(sp)\r
+       stw             r31, FUNC_FRM_R31(sp)\r
+\r
+#else\r
+       /* Save registers preserved by function call */\r
+       stw             r14, FUNC_FRM_R14(sp)\r
+       stw             r15, FUNC_FRM_R15(sp)\r
+       stw             r16, FUNC_FRM_R16(sp)\r
+       stw             r17, FUNC_FRM_R17(sp)\r
+       stw             r18, FUNC_FRM_R18(sp)\r
+       stw             r19, FUNC_FRM_R19(sp)\r
+       stw             r20, FUNC_FRM_R20(sp)\r
+       stw             r21, FUNC_FRM_R21(sp)\r
+       stw             r22, FUNC_FRM_R22(sp)\r
+       stw             r23, FUNC_FRM_R23(sp)\r
+       stw             r24, FUNC_FRM_R24(sp)\r
+       stw             r25, FUNC_FRM_R25(sp)\r
+       stw             r26, FUNC_FRM_R26(sp)\r
+       stw             r27, FUNC_FRM_R27(sp)\r
+       stw             r28, FUNC_FRM_R28(sp)\r
+       stw             r29, FUNC_FRM_R29(sp)\r
+       stw             r30, FUNC_FRM_R30(sp)\r
+       stw             r31, FUNC_FRM_R31(sp)\r
+#endif\r
+\r
+       /* Save stack ptr... */\r
+       stw             sp,PCB_STACK_CURR_P(r3)\r
+\r
+       /* TODO: Call Os_PretaskHook()? */ \r
+       \r
+       /*      Flow down  */\r
+       \r
+/**\r
+ * void Os_ArchSwapContextTo( NULL, pcb_t *new )\r
+ * r3 - always NULL\r
+ * r4 - The pcb to switch to.\r
+ */    \r
 Os_ArchSwapContextTo:\r
-// Get stack for new task\r
-               lwz             sp,PCB_STACK_CURR_P(r4)\r
-\r
-// Set new current process\r
-               LOAD_ADDR_32(3,os_sys)\r
-               stw             r4,SYS_CURR_PCB_P(r3)\r
-\r
-// Restore C context\r
-        lwz     r0,C_CR_OFF(sp)\r
-        mtcr    r0\r
-        lwz     r0,C_LR_OFF (sp)\r
-        mtlr    r0\r
-\r
-// Get the context type\r
-               lwz             r0,C_CONTEXT_OFF(sp)\r
-               cmpli   0,r0,SC_PATTERN\r
-               beq+    os_sc_restore\r
-               cmpli   0,r0,LC_PATTERN\r
-               beq+    os_lc_restore\r
-               b               os_bad_bad\r
-\r
-\r
-// SC_xxx\r
-// C_xxxx <- We point here\r
-\r
-os_sc_restore:\r
-               RESTORE_NVGPR(sp,(C_SIZE-14*GPR_SIZE))\r
-               addi    sp,sp,(C_SIZE+NVGPR_SIZE)\r
-               // TODO: The blr will not do the trick if swapping to a user land task.\r
-               blr\r
-\r
-os_lc_restore:\r
-       addi    r1,r1,C_SIZE\r
-       RESTORE_NVGPR(1,0)\r
-       addi    r1,r1,-C_SIZE\r
-       RESTORE_VGPR(1,C_SIZE)\r
-\r
-       RESTORE_WORK_AND_MORE\r
+       /* Get stack for new task */\r
+       lwz             sp,PCB_STACK_CURR_P(r4)\r
+\r
+       /* Set new current task */\r
+       LOAD_ADDR_32(3,Os_Sys)\r
+       stw             r4,SYS_CURR_PCB_P(r3)\r
+\r
+       /* Restore C context */\r
+       lwz     r0,FUNC_FRM_CR(sp)\r
+    mtcr    r0\r
+    lwz     r0,FUNC_FRM_LR (sp)\r
+    mtlr    r0\r
+\r
+       /* Get the context type */\r
+       lwz             r0, FUNC_FRM_PATTERN(sp)\r
+       cmpli   0, r0, FUNC_PATTERN\r
+       beq+    restoreFuncContext\r
+       cmpli   0, r0,ISR_PATTERN\r
+       beq+    restoreIsrContext\r
+       li              r3, OS_ERR_BAD_CONTEXT\r
+       b               Os_ArchPanic\r
+\r
+restoreFuncContext:\r
+#if defined(CFG_SPE)\r
+       evldd   r14, FUNC_FRM_R14(sp)\r
+       evldd   r15, FUNC_FRM_R15(sp)\r
+       evldd   r16, FUNC_FRM_R16(sp)\r
+       evldd   r17, FUNC_FRM_R17(sp)\r
+       evldd   r18, FUNC_FRM_R18(sp)\r
+       evldd   r19, FUNC_FRM_R19(sp)\r
+       evldd   r20, FUNC_FRM_R20(sp)\r
+       evldd   r21, FUNC_FRM_R21(sp)\r
+       evldd   r22, FUNC_FRM_R22(sp)\r
+       evldd   r23, FUNC_FRM_R23(sp)\r
+       evldd   r24, FUNC_FRM_R24(sp)\r
+       evldd   r25, FUNC_FRM_R25(sp)\r
+       evldd   r26, FUNC_FRM_R26(sp)\r
+       evldd   r27, FUNC_FRM_R27(sp)\r
+       evldd   r28, FUNC_FRM_R28(sp)\r
+       evldd   r29, FUNC_FRM_R29(sp)\r
+       evldd   r30, FUNC_FRM_R30(sp)\r
+       evldd   r31, FUNC_FRM_R31(sp)\r
+       addi    sp,sp,(FUNC_FRM_SIZE)\r
+#else \r
+       lwz             r14, FUNC_FRM_R14(sp)\r
+       lwz             r15, FUNC_FRM_R15(sp)\r
+       lwz             r16, FUNC_FRM_R16(sp)\r
+       lwz             r17, FUNC_FRM_R17(sp)\r
+       lwz             r18, FUNC_FRM_R18(sp)\r
+       lwz             r19, FUNC_FRM_R19(sp)\r
+       lwz             r20, FUNC_FRM_R20(sp)\r
+       lwz             r21, FUNC_FRM_R21(sp)\r
+       lwz             r22, FUNC_FRM_R22(sp)\r
+       lwz             r23, FUNC_FRM_R23(sp)\r
+       lwz             r24, FUNC_FRM_R24(sp)\r
+       lwz             r25, FUNC_FRM_R25(sp)\r
+       lwz             r26, FUNC_FRM_R26(sp)\r
+       lwz             r27, FUNC_FRM_R27(sp)\r
+       lwz             r28, FUNC_FRM_R28(sp)\r
+       lwz             r29, FUNC_FRM_R29(sp)\r
+       lwz             r30, FUNC_FRM_R30(sp)\r
+       lwz             r31, FUNC_FRM_R31(sp)\r
+       addi    sp,sp,(FUNC_FRM_SIZE)\r
+#endif \r
+       /* TODO: Call Os_PosttaskHook()? */\r
+       \r
+       blr\r
+\r
+\r
+/**\r
+ * External input exception handlers \r
+ */ \r
+               .global exception_IVOR4\r
+               .global restoreIsrContext\r
+               .balign 16\r
+exception_IVOR4:\r
+\r
+       /* Save the exception frame */\r
+       stwu    sp,-EXC_FRM_SIZE(sp)\r
+\r
+       stw     r3,EXC_FRM_R3(sp)\r
+\r
+       mfsrr0  r3\r
+       stw     r3, EXC_FRM_SRR0(sp)\r
+       mfsrr1  r3\r
+       stw     r3, EXC_FRM_SRR1(sp)\r
+\r
+       mfcr    r3\r
+       stw     r3, EXC_FRM_CR(sp)      \r
+       mfxer   r3 \r
+       stw     r3, EXC_FRM_XER(sp)\r
+       mfctr   r3\r
+       stw     r3, EXC_FRM_CTR(sp)\r
+       mflr    r3\r
+       stw     r3, EXC_FRM_LR(sp)      \r
+       \r
+       li              r3,4\r
+       stw     r3, EXC_FRM_VECTOR(sp)\r
+#if defined(CFG_SPE)   \r
+\r
+       /* Enable SPE (exceptions turns it off) */\r
+       mfmsr           r3\r
+    oris               r3,r3,0x0200\r
+       mtmsr           r3\r
+       isync\r
+\r
+       /* Create the frame */\r
+       addi    sp,sp,-ISR_FRM_SIZE\r
+       evstdd          r3, ISR_FRM_R3(sp)              /* Save work reg */     \r
+       \r
+       /* SPEFSCR      */\r
+       mfspr           r3,SPR_SPEFSCR\r
+       clrlwi          r3,r3,24                                /* Mask off non-status bits */\r
+       stw                     r3,ISR_FRM_SPE_FSCR(sp)\r
+\r
+       /* Save SPE acc  */\r
+       evsubfw         r3,r3,r3                                /* zero r3 */\r
+       evaddumiaaw r3,r3                                       /* Add r3 = r3 + acc -> r3 = acc */\r
+       evstdd          r3,ISR_FRM_SPE_ACC(r1)\r
+       \r
+       evstdd          r0, ISR_FRM_R0(sp)\r
+       evstdd          r4, ISR_FRM_R4(sp)\r
+       evstdd          r5, ISR_FRM_R5(sp)\r
+       evstdd          r6, ISR_FRM_R6(sp)\r
+       evstdd          r7, ISR_FRM_R7(sp)\r
+       evstdd          r8, ISR_FRM_R8(sp)\r
+       evstdd          r9, ISR_FRM_R9(sp)\r
+       evstdd          r10, ISR_FRM_R10(sp)\r
+       evstdd          r11, ISR_FRM_R11(sp)\r
+       evstdd          r12, ISR_FRM_R12(sp)\r
+       evstdd          r14, ISR_FRM_R14(sp)\r
+       evstdd          r15, ISR_FRM_R15(sp)\r
+       evstdd          r16, ISR_FRM_R16(sp)\r
+       evstdd          r17, ISR_FRM_R17(sp)\r
+       evstdd          r18, ISR_FRM_R18(sp)\r
+       evstdd          r19, ISR_FRM_R19(sp)\r
+       evstdd          r20, ISR_FRM_R20(sp)\r
+       evstdd          r21, ISR_FRM_R21(sp)\r
+       evstdd          r22, ISR_FRM_R22(sp)\r
+       evstdd          r23, ISR_FRM_R23(sp)\r
+       evstdd          r24, ISR_FRM_R24(sp)\r
+       evstdd          r25, ISR_FRM_R25(sp)\r
+       evstdd          r26, ISR_FRM_R26(sp)\r
+       evstdd          r27, ISR_FRM_R27(sp)\r
+       evstdd          r28, ISR_FRM_R28(sp)\r
+       evstdd          r29, ISR_FRM_R29(sp)\r
+       evstdd          r30, ISR_FRM_R30(sp)\r
+       addi            sp,sp,8\r
+       evstdd          r31, (ISR_FRM_R31-8)(sp)\r
+       addi            sp,sp,-8\r
+#else\r
+       /* Save the ISR frame */\r
+       addi    sp,sp,-ISR_FRM_SIZE\r
+       stw             r0, ISR_FRM_R0(sp)\r
+       stw             r4, ISR_FRM_R4(sp)\r
+       stw             r5, ISR_FRM_R5(sp)\r
+       stw             r6, ISR_FRM_R6(sp)\r
+       stw             r7, ISR_FRM_R7(sp)\r
+       stw             r8, ISR_FRM_R8(sp)\r
+       stw             r9, ISR_FRM_R9(sp)\r
+       stw             r10, ISR_FRM_R10(sp)\r
+       stw             r11, ISR_FRM_R11(sp)\r
+       stw             r12, ISR_FRM_R12(sp)\r
+       stw             r14, ISR_FRM_R14(sp)\r
+       stw             r15, ISR_FRM_R15(sp)\r
+       stw             r16, ISR_FRM_R16(sp)\r
+       stw             r17, ISR_FRM_R17(sp)\r
+       stw             r18, ISR_FRM_R18(sp)\r
+       stw             r19, ISR_FRM_R19(sp)\r
+       stw             r20, ISR_FRM_R20(sp)\r
+       stw             r21, ISR_FRM_R21(sp)\r
+       stw             r22, ISR_FRM_R22(sp)\r
+       stw             r23, ISR_FRM_R23(sp)\r
+       stw             r24, ISR_FRM_R24(sp)\r
+       stw             r25, ISR_FRM_R25(sp)\r
+       stw             r26, ISR_FRM_R26(sp)\r
+       stw             r27, ISR_FRM_R27(sp)\r
+       stw             r28, ISR_FRM_R28(sp)\r
+       stw             r29, ISR_FRM_R29(sp)\r
+       stw             r30, ISR_FRM_R30(sp)\r
+       stw             r31, ISR_FRM_R31(sp)\r
+#endif\r
+       \r
+       li              r3,ISR_PATTERN\r
+       stw             r3,ISR_FRM_PATTERN(sp)\r
+       /* Save the stack so it later can be saved in the pcb */        \r
+       mr              r4,sp                   \r
+       \r
+       /* Switch to interrupt stack if at depth 0 */\r
+       /* Load the value Os_Sys.int_nest_cnt */\r
+       LOAD_IND_32(r3,Os_Sys+SYS_INT_NEST_CNT)\r
+       cmpli   0,r3,0\r
+       bne-    on_int_stack\r
+\r
+       /* Load the interrupt stack */\r
+       LOAD_IND_32(r1,Os_Sys+SYS_INT_STACK)\r
+\r
+on_int_stack:\r
+\r
+#if defined(CFG_MPC5516)\r
+       lis r6, INTC_IACKR_PRC0@ha\r
+       lwz r6, INTC_IACKR_PRC0@l(r6)\r
+#elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
+       lis r6, INTC_IACKR@ha \r
+       lwz r6, INTC_IACKR@l(r6)\r
+#endif\r
+       /* Check for 0 entry */\r
+       mr              r5,r6\r
+       cmpli   0,r5,0\r
+       bne+    vectorOk\r
+       /* The entry was 0, call panic */\r
+       li              r3,OS_ERR_SPURIOUS_INTERRUPT\r
+       li              r4, 0\r
+       mr              r5,r1\r
+       b               Os_ArchPanic\r
+       \r
+vectorOk:\r
+       extrwi  r5,r5,9,21\r
+       /* Check for soft INT */\r
+       cmpli   0,r5,7\r
+       bgt             noSoftInt\r
+       /* Clear soft interrupt */\r
+       li              r0,1    \r
+       lis             r3, INTC_SSCIR0@h\r
+       ori             r3, r3, INTC_SSCIR0@l\r
+       stbx    r0,r5,r3                        \r
+       \r
+noSoftInt:     \r
+\r
+       lis   r3, Os_Isr@h\r
+    ori   r3, r3,Os_Isr@l\r
+    mtlr  r3\r
+       mr    r3,r4             /* "old" stack as arg1 */\r
+#if defined(OLD_CALL)  \r
+    lwz   r4, 0x0(r6)  /* Read the address from the for function/pcb entry */\r
+#else\r
+       mr       r4,r5\r
+#endif    \r
+    blrl                               /* Call the entry */\r
+\r
+       /* Notes!\r
+        * The OS interrupt is ACK'd in Os_Isr(). For ISR1 it needs to call Irq_EOI()\r
+        */\r
+        \r
+       /* Irq_Entry have returned the stack we shall use */\r
+       mr              sp,r3\r
+\r
+       /* Restore */\r
+restoreIsrContext:\r
+#if defined(CFG_SPE) \r
+\r
+       // Restore SPE control/status reg.\r
+       lwz             r3,ISR_FRM_SPE_FSCR(sp)\r
+       mtspr   SPR_CSRR0,r3\r
+\r
+       /* Restore SPE acc */\r
+       evldd r3,ISR_FRM_SPE_ACC(r1)\r
+       evmra r3,r3\r
+       \r
+\r
+       evldd   r0, ISR_FRM_R0(sp)\r
+       evldd   r3, ISR_FRM_R4(sp)\r
+       evldd   r4, ISR_FRM_R4(sp)\r
+       evldd   r5, ISR_FRM_R5(sp)\r
+       evldd   r6, ISR_FRM_R6(sp)\r
+       evldd   r7, ISR_FRM_R7(sp)\r
+       evldd   r8, ISR_FRM_R8(sp)\r
+       evldd   r9, ISR_FRM_R9(sp)\r
+       evldd   r10, ISR_FRM_R10(sp)\r
+       evldd   r11, ISR_FRM_R11(sp)\r
+       evldd   r12, ISR_FRM_R12(sp)\r
+       evldd   r14, ISR_FRM_R14(sp)\r
+       evldd   r15, ISR_FRM_R15(sp)\r
+       evldd   r16, ISR_FRM_R16(sp)\r
+       evldd   r17, ISR_FRM_R17(sp)\r
+       evldd   r18, ISR_FRM_R18(sp)\r
+       evldd   r19, ISR_FRM_R19(sp)\r
+       evldd   r20, ISR_FRM_R20(sp)\r
+       evldd   r21, ISR_FRM_R21(sp)\r
+       evldd   r22, ISR_FRM_R22(sp)\r
+       evldd   r23, ISR_FRM_R23(sp)\r
+       evldd   r24, ISR_FRM_R24(sp)\r
+       evldd   r25, ISR_FRM_R25(sp)\r
+       evldd   r26, ISR_FRM_R26(sp)\r
+       evldd   r27, ISR_FRM_R27(sp)\r
+       evldd   r28, ISR_FRM_R28(sp)\r
+       evldd   r29, ISR_FRM_R29(sp)\r
+       evldd   r30, ISR_FRM_R30(sp)\r
+       addi    sp,sp,8\r
+       evldd   r31, (ISR_FRM_R31-8)(sp)\r
+       addi    sp,sp,-8\r
+#else\r
+       lwz             r0, ISR_FRM_R0(sp)\r
+       lwz             r4, ISR_FRM_R4(sp)\r
+       lwz             r5, ISR_FRM_R5(sp)\r
+       lwz             r6, ISR_FRM_R6(sp)\r
+       lwz             r7, ISR_FRM_R7(sp)\r
+       lwz             r8, ISR_FRM_R8(sp)\r
+       lwz             r9, ISR_FRM_R9(sp)\r
+       lwz             r10, ISR_FRM_R10(sp)\r
+       lwz             r11, ISR_FRM_R11(sp)\r
+       lwz             r12, ISR_FRM_R12(sp)\r
+       lwz             r14, ISR_FRM_R14(sp)\r
+       lwz             r15, ISR_FRM_R15(sp)\r
+       lwz             r16, ISR_FRM_R16(sp)\r
+       lwz             r17, ISR_FRM_R17(sp)\r
+       lwz             r18, ISR_FRM_R18(sp)\r
+       lwz             r19, ISR_FRM_R19(sp)\r
+       lwz             r20, ISR_FRM_R20(sp)\r
+       lwz             r21, ISR_FRM_R21(sp)\r
+       lwz             r22, ISR_FRM_R22(sp)\r
+       lwz             r23, ISR_FRM_R23(sp)\r
+       lwz             r24, ISR_FRM_R24(sp)\r
+       lwz             r25, ISR_FRM_R25(sp)\r
+       lwz             r26, ISR_FRM_R26(sp)\r
+       lwz             r27, ISR_FRM_R27(sp)\r
+       lwz             r28, ISR_FRM_R28(sp)\r
+       lwz             r29, ISR_FRM_R29(sp)\r
+       lwz             r30, ISR_FRM_R30(sp)\r
+       lwz             r31, ISR_FRM_R31(sp)\r
+#endif \r
+       \r
+       /* back to the exception frame */\r
+       addi    sp,sp,ISR_FRM_SIZE\r
+       \r
+       lwz     r3, EXC_FRM_LR(sp)\r
+       mtlr    r3\r
+       lwz             r3, EXC_FRM_CTR(sp)\r
+       mtctr   r3\r
+       lwz     r3, EXC_FRM_XER(sp)\r
+       mtxer   r3\r
+       lwz     r3, EXC_FRM_CR(sp)\r
+       mtcr    r3\r
+       lwz     r3, EXC_FRM_SRR0(sp)\r
+       mtsrr0  r3\r
+       lwz     r3, EXC_FRM_SRR1(sp)\r
+       mtsrr1  r3\r
+       lwz     r3, EXC_FRM_R3(sp)\r
+       addi    sp,sp,EXC_FRM_SIZE\r
        rfi\r
 \r
-// When something really bad happens we end up here for the moment\r
-os_bad_bad:\r
-               b       os_bad_bad\r
-\r
-\r
 \r
 \r
-// ------------------------------------------------------------------\r
-\r
-/*\r
- * Trap interface !!!! See article http://www.linuxjournal.com/article/6516\r
- * http://www.osweekly.com/index.php?option=com_content&task=view&id=2229\r
+/**\r
+ * Decrementer exception. It just triggers soft interrupt 7.\r
+ *\r
  */\r
+exception_IVOR10:\r
+    stwu       r3,-8(sp)\r
+    stw        r4,4(sp)\r
 \r
-/* The T32 instruction sim can't handle trap's so we have to make something\r
- * - write SRR0, SRR1, MSR\r
- * - jump to there routines\r
- */\r
+    /* ack dec int */\r
+    lis        r3,0x0800\r
+    mtspr   SPR_TSR,r3\r
 \r
-// ------------------------------------------------------------------\r
+    /* Set soft int */\r
+    li         r4,2\r
+    lis     r3, INTC_SSCIR7@ha\r
+    stb     r4, INTC_SSCIR7@l(r3)\r
 \r
+    lwz     r3,0(sp)\r
+    lwz     r4,4(sp)\r
+    addi       sp,sp,8\r
+    rfi\r
 \r
-// System call, use this for trusted function ???\r
-// TODO: The example in autosar is not neccesary.. sc here here instead??\r
-//\r
-// NOTE!!!!!\r
-// Since the sc is a sync call, it should be enough to save NV regs(14->)\r
-// If I don't use the NV regs here I shouldn't need to save them\r
-// TODO: Inform compiler in SC_CALL() that I clobber volatile regs( r0, r3->\r
-//      (since the compiler does not know it's a function call)\r
-// TODO: Could probably do this shorter....only NV regs that I use need saving\r
-//       ( only cr2->cr4 according to e500 ABI )\r
 \r
+/* Getting here means that the exception stack is started with:\r
+ * sp - saved\r
+ * r3 - saved and contains the exception number \r
+ */\r
+handleException:\r
+       b  handleException              \r
+       \r
+#if defined(__GNUC__)  \r
+.section ".exception_tbl","ax"\r
+#elif defined(__CWCC__)\r
+.section .exception_tbl,4,"rw"\r
+#endif\r
+.balign 0x1000\r
+.global exception_tbl\r
+\r
+exception_tbl:\r
+       EXC_TABLE_CODE(0)\r
+       EXC_TABLE_CODE(1)\r
+       EXC_TABLE_CODE(2)\r
+       EXC_TABLE_CODE(3)\r
+    b      exception_IVOR4\r
+    .skip   +0xc\r
+       EXC_TABLE_CODE(5)\r
+       EXC_TABLE_CODE(6)\r
+       EXC_TABLE_CODE(7)\r
+       EXC_TABLE_CODE(8)\r
+       EXC_TABLE_CODE(9)\r
+    b     exception_IVOR10\r
+    .skip   +0xc\r
+       EXC_TABLE_CODE(11)\r
+       EXC_TABLE_CODE(12)\r
+       EXC_TABLE_CODE(13)\r
+       EXC_TABLE_CODE(14)\r
+#if defined(CFG_SPE)\r
+       EXC_TABLE_CODE(32)\r
+       EXC_TABLE_CODE(33)\r
+       EXC_TABLE_CODE(34)\r
+#endif\r
 \r
 \r
 \r