1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. 4 */ 5 6 #include <common.h> 7 #include <asm/arcregs.h> 8 #include <asm/ptrace.h> 9 10 /* Bit values in STATUS32 */ 11 #define E1_MASK (1 << 1) /* Level 1 interrupts enable */ 12 #define E2_MASK (1 << 2) /* Level 2 interrupts enable */ 13 14 int interrupt_init(void) 15 { 16 return 0; 17 } 18 19 /* 20 * returns true if interrupts had been enabled before we disabled them 21 */ 22 int disable_interrupts(void) 23 { 24 int status = read_aux_reg(ARC_AUX_STATUS32); 25 int state = (status & (E1_MASK | E2_MASK)) ? 1 : 0; 26 27 status &= ~(E1_MASK | E2_MASK); 28 /* STATUS32 register is updated indirectly with "FLAG" instruction */ 29 __asm__("flag %0" : : "r" (status)); 30 return state; 31 } 32 33 void enable_interrupts(void) 34 { 35 unsigned int status = read_aux_reg(ARC_AUX_STATUS32); 36 37 status |= E1_MASK | E2_MASK; 38 /* STATUS32 register is updated indirectly with "FLAG" instruction */ 39 __asm__("flag %0" : : "r" (status)); 40 } 41 42 static void print_reg_file(long *reg_rev, int start_num) 43 { 44 unsigned int i; 45 46 /* Print 3 registers per line */ 47 for (i = start_num; i < start_num + 25; i++) { 48 printf("r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev); 49 if (((i + 1) % 3) == 0) 50 printf("\n"); 51 52 /* Because pt_regs has registers reversed */ 53 reg_rev--; 54 } 55 56 /* Add new-line if none was inserted in the end of loop above */ 57 if (((i + 1) % 3) != 0) 58 printf("\n"); 59 } 60 61 void show_regs(struct pt_regs *regs) 62 { 63 printf("ECR:\t0x%08lx\n", regs->ecr); 64 printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n", 65 regs->ret, regs->blink, regs->status32); 66 printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25); 67 printf("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", regs->bta, 68 regs->sp, regs->fp); 69 printf("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start, 70 regs->lp_end, regs->lp_count); 71 72 print_reg_file(&(regs->r0), 0); 73 } 74 75 void bad_mode(struct pt_regs *regs) 76 { 77 if (regs) 78 show_regs(regs); 79 80 panic("Resetting CPU ...\n"); 81 } 82 83 void do_memory_error(unsigned long address, struct pt_regs *regs) 84 { 85 printf("Memory error exception @ 0x%lx\n", address); 86 bad_mode(regs); 87 } 88 89 void do_instruction_error(unsigned long address, struct pt_regs *regs) 90 { 91 printf("Instruction error exception @ 0x%lx\n", address); 92 bad_mode(regs); 93 } 94 95 void do_machine_check_fault(unsigned long address, struct pt_regs *regs) 96 { 97 printf("Machine check exception @ 0x%lx\n", address); 98 bad_mode(regs); 99 } 100 101 void do_interrupt_handler(void) 102 { 103 printf("Interrupt fired\n"); 104 bad_mode(0); 105 } 106 107 void do_itlb_miss(struct pt_regs *regs) 108 { 109 printf("I TLB miss exception\n"); 110 bad_mode(regs); 111 } 112 113 void do_dtlb_miss(struct pt_regs *regs) 114 { 115 printf("D TLB miss exception\n"); 116 bad_mode(regs); 117 } 118 119 void do_tlb_prot_violation(unsigned long address, struct pt_regs *regs) 120 { 121 printf("TLB protection violation or misaligned access @ 0x%lx\n", 122 address); 123 bad_mode(regs); 124 } 125 126 void do_privilege_violation(struct pt_regs *regs) 127 { 128 printf("Privilege violation exception\n"); 129 bad_mode(regs); 130 } 131 132 void do_trap(struct pt_regs *regs) 133 { 134 printf("Trap exception\n"); 135 bad_mode(regs); 136 } 137 138 void do_extension(struct pt_regs *regs) 139 { 140 printf("Extension instruction exception\n"); 141 bad_mode(regs); 142 } 143 144 #ifdef CONFIG_ISA_ARCV2 145 void do_swi(struct pt_regs *regs) 146 { 147 printf("Software Interrupt exception\n"); 148 bad_mode(regs); 149 } 150 151 void do_divzero(unsigned long address, struct pt_regs *regs) 152 { 153 printf("Division by zero exception @ 0x%lx\n", address); 154 bad_mode(regs); 155 } 156 157 void do_dcerror(struct pt_regs *regs) 158 { 159 printf("Data cache consistency error exception\n"); 160 bad_mode(regs); 161 } 162 163 void do_maligned(unsigned long address, struct pt_regs *regs) 164 { 165 printf("Misaligned data access exception @ 0x%lx\n", address); 166 bad_mode(regs); 167 } 168 #endif 169