blob: 3ff211d047e5a7ac4de1c263f19d9c02116adc8c [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2014 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <stdio.h>
24#include <debug.h>
25#include <arch/arch_ops.h>
26#include <arch/arm64.h>
27
28#define SHUTDOWN_ON_FATAL 1
29
30struct fault_handler_table_entry {
31 uint64_t pc;
32 uint64_t fault_handler;
33};
34
35extern struct fault_handler_table_entry __fault_handler_table_start[];
36extern struct fault_handler_table_entry __fault_handler_table_end[];
37
38static void dump_iframe(const struct arm64_iframe_long *iframe)
39{
40 printf("iframe %p:\n", iframe);
41 printf("x0 0x%16llx x1 0x%16llx x2 0x%16llx x3 0x%16llx\n", iframe->r[0], iframe->r[1], iframe->r[2], iframe->r[3]);
42 printf("x4 0x%16llx x5 0x%16llx x6 0x%16llx x7 0x%16llx\n", iframe->r[4], iframe->r[5], iframe->r[6], iframe->r[7]);
43 printf("x8 0x%16llx x9 0x%16llx x10 0x%16llx x11 0x%16llx\n", iframe->r[8], iframe->r[9], iframe->r[10], iframe->r[11]);
44 printf("x12 0x%16llx x13 0x%16llx x14 0x%16llx x15 0x%16llx\n", iframe->r[12], iframe->r[13], iframe->r[14], iframe->r[15]);
45 printf("x16 0x%16llx x17 0x%16llx x18 0x%16llx x19 0x%16llx\n", iframe->r[16], iframe->r[17], iframe->r[18], iframe->r[19]);
46 printf("x20 0x%16llx x21 0x%16llx x22 0x%16llx x23 0x%16llx\n", iframe->r[20], iframe->r[21], iframe->r[22], iframe->r[23]);
47 printf("x24 0x%16llx x25 0x%16llx x26 0x%16llx x27 0x%16llx\n", iframe->r[24], iframe->r[25], iframe->r[26], iframe->r[27]);
48 printf("x28 0x%16llx x29 0x%16llx lr 0x%16llx sp 0x%16llx\n", iframe->r[28], iframe->r[29], iframe->r[30], iframe->r[31]);
49 printf("elr 0x%16llx\n", iframe->elr);
50 printf("spsr 0x%16llx\n", iframe->spsr);
51}
52
53void arm64_sync_exception(struct arm64_iframe_long *iframe)
54{
55 struct fault_handler_table_entry *fault_handler;
56 uint32_t esr = ARM64_READ_SYSREG(esr_el1);
57 uint32_t ec = esr >> 26;
58 uint32_t il = (esr >> 25) & 0x1;
59 uint32_t iss = esr & ((1<<24) - 1);
60
61#ifdef WITH_LIB_SYSCALL
62 if (ec == 0x15 || ec == 0x11) { // syscall 64/32
63 void arm64_syscall(struct arm64_iframe_long *iframe);
64 arch_enable_fiqs();
65 arm64_syscall(iframe);
66 arch_disable_fiqs();
67 return;
68 }
69#endif
70
71 /* floating point */
72 if (ec == 0x07) {
73 arm64_fpu_exception(iframe);
74 return;
75 }
76
77 for (fault_handler = __fault_handler_table_start; fault_handler < __fault_handler_table_end; fault_handler++) {
78 if (fault_handler->pc == iframe->elr) {
79 iframe->elr = fault_handler->fault_handler;
80 return;
81 }
82 }
83
84 printf("sync_exception\n");
85 dump_iframe(iframe);
86
87 printf("ESR 0x%x: ec 0x%x, il 0x%x, iss 0x%x\n", esr, ec, il, iss);
88
89 if (ec == 0x15) { // syscall
90 printf("syscall\n");
91 return;
92 }
93
94 panic("die\n");
95}
96
97void arm64_invalid_exception(struct arm64_iframe_long *iframe, unsigned int which)
98{
99 printf("invalid exception, which 0x%x\n", which);
100 dump_iframe(iframe);
101
102 panic("die\n");
103}
104
105
106