Home | History | Annotate | Download | only in lib
      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