From 699c4e592b32f43d4ba2cc0d53848118a77d590a Mon Sep 17 00:00:00 2001
From: Alexey Brodkin <abrodkin@synopsys.com>
Date: Thu, 4 Aug 2016 09:21:50 +0300
Subject: [PATCH] arc: Update exception & interrupt handling for ARCv2

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  | 31 ++++++++++++++++++-------------
 arch/arc/lib/interrupts.c | 26 ++++++++++++++++++++++++++
 arch/arc/lib/ints_low.S   | 28 ++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/arch/arc/cpu/arcv2/ivt.S b/arch/arc/cpu/arcv2/ivt.S
index d110b5bba5..7924375fb1 100644
--- a/arch/arc/cpu/arcv2/ivt.S
+++ b/arch/arc/cpu/arcv2/ivt.S
@@ -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
diff --git a/arch/arc/lib/interrupts.c b/arch/arc/lib/interrupts.c
index d7cab3bb40..ee638d506b 100644
--- a/arch/arc/lib/interrupts.c
+++ b/arch/arc/lib/interrupts.c
@@ -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
diff --git a/arch/arc/lib/ints_low.S b/arch/arc/lib/ints_low.S
index 161cf37dc4..e3778847ab 100644
--- a/arch/arc/lib/ints_low.S
+++ b/arch/arc/lib/ints_low.S
@@ -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
-- 
2.39.5