arc: Update exception & interrupt handling for ARCv2
authorAlexey Brodkin <abrodkin@synopsys.com>
Thu, 4 Aug 2016 06:21:50 +0000 (09:21 +0300)
committerAlexey Brodkin <abrodkin@synopsys.com>
Fri, 5 Aug 2016 09:50:25 +0000 (12:50 +0300)
Initially IVT for ARCv2 was simply copypasted from ARCompact
with some selected fixes so basic stuff works.

Now we update it with more ARCv2 specific vectors like
 * Software Interrupt
 * Division by zero
 * Data cache consistency error
 * Misaligned access

Also normal interrupts are now implemented properly and extened to
all possible 240 items.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
arch/arc/cpu/arcv2/ivt.S
arch/arc/lib/interrupts.c
arch/arc/lib/ints_low.S

index d110b5bba53648b7e06b4dea39f600d34259ff98..7924375fb1d3212ea5836654f41ade2e19aa410b 100644 (file)
@@ -7,21 +7,26 @@
 .section .ivt, "a",@progbits
 .align 4
        /* Critical system events */
-.word  _start                  /* 0 - 0x000 */
-.word  memory_error            /* 1 - 0x008 */
-.word  instruction_error       /* 2 - 0x010 */
+.word  _start                  /* 0x00 - Reset */
+.word  memory_error            /* 0x01 - Memory Error */
+.word  instruction_error       /* 0x02 - Instruction Error */
 
        /* Exceptions */
-.word  EV_MachineCheck         /* 0x100, Fatal Machine check  (0x20) */
-.word  EV_TLBMissI             /* 0x108, Intruction TLB miss  (0x21) */
-.word  EV_TLBMissD             /* 0x110, Data TLB miss        (0x22) */
-.word  EV_TLBProtV             /* 0x118, Protection Violation (0x23)
-                                                       or Misaligned Access  */
-.word  EV_PrivilegeV           /* 0x120, Privilege Violation  (0x24) */
-.word  EV_Trap                 /* 0x128, Trap exception       (0x25) */
-.word  EV_Extension            /* 0x130, Extn Intruction Excp (0x26) */
+.word  EV_MachineCheck         /* 0x03 - Fatal Machine check */
+.word  EV_TLBMissI             /* 0x04 - Intruction TLB miss */
+.word  EV_TLBMissD             /* 0x05 - Data TLB miss */
+.word  EV_TLBProtV             /* 0x06 - Protection Violation or Misaligned Access */
+.word  EV_PrivilegeV           /* 0x07 - Privilege Violation */
+.word  EV_SWI                  /* 0x08 - Software Interrupt */
+.word  EV_Trap                 /* 0x09 - Trap */
+.word  EV_Extension            /* 0x0A - Extension Intruction Exception */
+.word  EV_DivZero              /* 0x0B - Division by Zero */
+.word  EV_DCError              /* 0x0C - Data cache consistency error */
+.word  EV_Maligned             /* 0x0D - Misaligned data access */
+.word  0                       /* 0x0E - Unused */
+.word  0                       /* 0x0F - Unused */
 
        /* Device interrupts */
-.rept  29
-       j       interrupt_handler       /* 3:31 - 0x018:0xF8 */
+.rept  240
+.word  interrupt_handler       /* 0x10 - 0xFF */
 .endr
index d7cab3bb409d4727123eba4afb23b9ecb93fb0cf..ee638d506bebe063b819d32246ce7305ec9fc38c 100644 (file)
@@ -141,3 +141,29 @@ void do_extension(struct pt_regs *regs)
        printf("Extension instruction exception\n");
        bad_mode(regs);
 }
+
+#ifdef CONFIG_ISA_ARCV2
+void do_swi(struct pt_regs *regs)
+{
+       printf("Software Interrupt exception\n");
+       bad_mode(regs);
+}
+
+void do_divzero(unsigned long address, struct pt_regs *regs)
+{
+       printf("Division by zero exception @ 0x%lx\n", address);
+       bad_mode(regs);
+}
+
+void do_dcerror(struct pt_regs *regs)
+{
+       printf("Data cache consistency error exception\n");
+       bad_mode(regs);
+}
+
+void do_maligned(unsigned long address, struct pt_regs *regs)
+{
+       printf("Misaligned data access exception @ 0x%lx\n", address);
+       bad_mode(regs);
+}
+#endif
index 161cf37dc48ac569fe6eafa85799a184147039af..e3778847aba1503a9931f30a0b251396a8ce21db 100644 (file)
@@ -149,3 +149,31 @@ ENTRY(EV_Extension)
        mov     %r0, %sp
        j       do_extension
 ENDPROC(EV_Extension)
+
+#ifdef CONFIG_ISA_ARCV2
+ENTRY(EV_SWI)
+       SAVE_ALL_SYS
+       mov     %r0, %sp
+       j       do_swi
+ENDPROC(EV_SWI)
+
+ENTRY(EV_DivZero)
+       SAVE_ALL_SYS
+       SAVE_EXCEPTION_SOURCE
+       mov     %r1, %sp
+       j       do_divzero
+ENDPROC(EV_DivZero)
+
+ENTRY(EV_DCError)
+       SAVE_ALL_SYS
+       mov     %r0, %sp
+       j       do_dcerror
+ENDPROC(EV_DCError)
+
+ENTRY(EV_Maligned)
+       SAVE_ALL_SYS
+       SAVE_EXCEPTION_SOURCE
+       mov     %r1, %sp
+       j       do_maligned
+ENDPROC(EV_Maligned)
+#endif