summaryrefslogtreecommitdiff
path: root/arch/arc/cpu/arc700/interrupts.c
diff options
context:
space:
mode:
authorAlexey Brodkin <Alexey.Brodkin@synopsys.com>2014-02-04 12:56:14 +0400
committerTom Rini <trini@ti.com>2014-02-07 08:14:32 -0500
commit2f16ac9df4d898ab7266f768f125a638c7c5add8 (patch)
treef45e5d608b684b8024e15ac5d0cef37e344d10ab /arch/arc/cpu/arc700/interrupts.c
parent288aaacf2de5507f33c0bb26eb063f2f69033dd6 (diff)
arc: add cpu files
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> Cc: Vineet Gupta <vgupta@synopsys.com> Cc: Francois Bedard <fbedard@synopsys.com> Cc: Wolfgang Denk <wd@denx.de> Cc: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'arch/arc/cpu/arc700/interrupts.c')
-rw-r--r--arch/arc/cpu/arc700/interrupts.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/arch/arc/cpu/arc700/interrupts.c b/arch/arc/cpu/arc700/interrupts.c
new file mode 100644
index 0000000000..d93a6eb547
--- /dev/null
+++ b/arch/arc/cpu/arc700/interrupts.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arcregs.h>
+#include <asm/ptrace.h>
+
+/* Bit values in STATUS32 */
+#define E1_MASK (1 << 1) /* Level 1 interrupts enable */
+#define E2_MASK (1 << 2) /* Level 2 interrupts enable */
+
+int interrupt_init(void)
+{
+ return 0;
+}
+
+/*
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts(void)
+{
+ int status = read_aux_reg(ARC_AUX_STATUS32);
+ int state = (status | E1_MASK | E2_MASK) ? 1 : 0;
+
+ status &= ~(E1_MASK | E2_MASK);
+ /* STATUS32 register is updated indirectly with "FLAG" instruction */
+ __asm__("flag %0" : : "r" (status));
+ return state;
+}
+
+void enable_interrupts(void)
+{
+ unsigned int status = read_aux_reg(ARC_AUX_STATUS32);
+
+ status |= E1_MASK | E2_MASK;
+ /* STATUS32 register is updated indirectly with "FLAG" instruction */
+ __asm__("flag %0" : : "r" (status));
+}
+
+static void print_reg_file(long *reg_rev, int start_num)
+{
+ unsigned int i;
+
+ /* Print 3 registers per line */
+ for (i = start_num; i < start_num + 25; i++) {
+ printf("r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev);
+ if (((i + 1) % 3) == 0)
+ printf("\n");
+
+ /* Because pt_regs has registers reversed */
+ reg_rev--;
+ }
+
+ /* Add new-line if none was inserted in the end of loop above */
+ if (((i + 1) % 3) != 0)
+ printf("\n");
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n",
+ regs->ret, regs->blink, regs->status32);
+ printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25);
+ printf("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", regs->bta,
+ regs->sp, regs->fp);
+ printf("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start,
+ regs->lp_end, regs->lp_count);
+
+ print_reg_file(&(regs->r0), 0);
+}
+
+void bad_mode(struct pt_regs *regs)
+{
+ if (regs)
+ show_regs(regs);
+
+ panic("Resetting CPU ...\n");
+}
+
+void do_memory_error(unsigned long address, struct pt_regs *regs)
+{
+ printf("Memory error exception @ 0x%lx\n", address);
+ bad_mode(regs);
+}
+
+void do_instruction_error(unsigned long address, struct pt_regs *regs)
+{
+ printf("Instruction error exception @ 0x%lx\n", address);
+ bad_mode(regs);
+}
+
+void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
+{
+ printf("Machine check exception @ 0x%lx\n", address);
+ bad_mode(regs);
+}
+
+void do_interrupt_handler(void)
+{
+ printf("Interrupt fired\n");
+ bad_mode(0);
+}
+
+void do_itlb_miss(struct pt_regs *regs)
+{
+ printf("I TLB miss exception\n");
+ bad_mode(regs);
+}
+
+void do_dtlb_miss(struct pt_regs *regs)
+{
+ printf("D TLB miss exception\n");
+ bad_mode(regs);
+}
+
+void do_tlb_prot_violation(unsigned long address, struct pt_regs *regs)
+{
+ printf("TLB protection violation or misaligned access @ 0x%lx\n",
+ address);
+ bad_mode(regs);
+}
+
+void do_privilege_violation(struct pt_regs *regs)
+{
+ printf("Privilege violation exception\n");
+ bad_mode(regs);
+}
+
+void do_trap(struct pt_regs *regs)
+{
+ printf("Trap exception\n");
+ bad_mode(regs);
+}
+
+void do_extension(struct pt_regs *regs)
+{
+ printf("Extension instruction exception\n");
+ bad_mode(regs);
+}