xref: /aosp_15_r20/external/coreboot/src/arch/arm/armv7/exception.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
3 #include <types.h>
4 #include <arch/cache.h>
5 #include <arch/exception.h>
6 #include <console/console.h>
7 
8 uint8_t exception_stack[0x100] __aligned(8);
9 extern void *exception_stack_end;
10 
11 void exception_undefined_instruction(uint32_t *regs);
12 void exception_software_interrupt(uint32_t *regs);
13 void exception_prefetch_abort(uint32_t *regs);
14 void exception_data_abort(uint32_t *regs);
15 void exception_not_used(uint32_t *regs);
16 void exception_irq(uint32_t *regs);
17 void exception_fiq(uint32_t *regs);
18 
dump_stack(uintptr_t addr,size_t bytes)19 static void dump_stack(uintptr_t addr, size_t bytes)
20 {
21 	int i, j;
22 	const int line = 8;
23 	uint32_t *ptr = (uint32_t *)(addr & ~(line * sizeof(*ptr) - 1));
24 
25 	printk(BIOS_ERR, "Dumping stack:\n");
26 	for (i = bytes / sizeof(*ptr); i >= 0; i -= line) {
27 		printk(BIOS_ERR, "%p: ", ptr + i);
28 		for (j = i; j < i + line; j++)
29 			printk(BIOS_ERR, "%08x ", *(ptr + j));
30 		printk(BIOS_ERR, "\n");
31 	}
32 }
33 
print_regs(uint32_t * regs)34 static void print_regs(uint32_t *regs)
35 {
36 	int i;
37 
38 	for (i = 0; i < 16; i++) {
39 		if (i == 15)
40 			printk(BIOS_ERR, "PC");
41 		else if (i == 14)
42 			printk(BIOS_ERR, "LR");
43 		else if (i == 13)
44 			printk(BIOS_ERR, "SP");
45 		else if (i == 12)
46 			printk(BIOS_ERR, "IP");
47 		else
48 			printk(BIOS_ERR, "R%d", i);
49 		printk(BIOS_ERR, " = 0x%08x\n", regs[i]);
50 	}
51 }
52 
exception_undefined_instruction(uint32_t * regs)53 void exception_undefined_instruction(uint32_t *regs)
54 {
55 	printk(BIOS_ERR, "exception _undefined_instruction\n");
56 	regs[15] -= 2;	/* CAREFUL: specific to thumb mode (otherwise 4)! */
57 	print_regs(regs);
58 	dump_stack(regs[13], 512);
59 	die("exception");
60 }
61 
exception_software_interrupt(uint32_t * regs)62 void exception_software_interrupt(uint32_t *regs)
63 {
64 	printk(BIOS_ERR, "exception _software_interrupt\n");
65 	print_regs(regs);
66 	dump_stack(regs[13], 512);
67 	die("exception");
68 }
69 
exception_prefetch_abort(uint32_t * regs)70 void exception_prefetch_abort(uint32_t *regs)
71 {
72 	printk(BIOS_ERR, "exception _prefetch_abort\n");
73 	regs[15] -= 4;
74 	print_regs(regs);
75 	printk(BIOS_ERR, "IFAR = %#.8x\n", read_ifar());
76 	printk(BIOS_ERR, "IFSR = %#.8x\n", read_ifsr());
77 	printk(BIOS_ERR, "AIFSR = %#.8x\n", read_aifsr());
78 	dump_stack(regs[13], 512);
79 	die("exception");
80 }
81 
exception_data_abort(uint32_t * regs)82 void exception_data_abort(uint32_t *regs)
83 {
84 	printk(BIOS_ERR, "exception _data_abort\n");
85 	regs[15] -= 8;
86 	print_regs(regs);
87 	printk(BIOS_ERR, "DFAR = %#.8x\n", read_dfar());
88 	printk(BIOS_ERR, "DFSR = %#.8x\n", read_dfsr());
89 	printk(BIOS_ERR, "ADFSR = %#.8x\n", read_adfsr());
90 	dump_stack(regs[13], 512);
91 	die("exception");
92 }
93 
exception_not_used(uint32_t * regs)94 void exception_not_used(uint32_t *regs)
95 {
96 	printk(BIOS_ERR, "exception _not_used\n");
97 	print_regs(regs);
98 	dump_stack(regs[13], 512);
99 	die("exception");
100 }
101 
exception_irq(uint32_t * regs)102 void exception_irq(uint32_t *regs)
103 {
104 	printk(BIOS_ERR, "exception _irq\n");
105 	regs[15] -= 4;
106 	print_regs(regs);
107 	dump_stack(regs[13], 512);
108 	die("exception");
109 }
110 
exception_fiq(uint32_t * regs)111 void exception_fiq(uint32_t *regs)
112 {
113 	printk(BIOS_ERR, "exception _fiq\n");
114 	regs[15] -= 4;
115 	print_regs(regs);
116 	dump_stack(regs[13], 512);
117 	die("exception");
118 }
119 
exception_init(void)120 void exception_init(void)
121 {
122 	uint32_t sctlr = read_sctlr();
123 	/* Handle exceptions in ARM mode. */
124 	sctlr &= ~SCTLR_TE;
125 	/* Set V=0 in SCTLR so VBAR points to the exception vector table. */
126 	sctlr &= ~SCTLR_V;
127 	/* Enforce alignment temporarily. */
128 	write_sctlr(sctlr);
129 
130 	extern uint32_t exception_table[];
131 	set_vbar((uintptr_t)exception_table);
132 	exception_stack_end = exception_stack + sizeof(exception_stack);
133 
134 	printk(BIOS_DEBUG, "Exception handlers installed.\n");
135 }
136