3 * Copyright 2014 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <exception.h>
30 #include <libpayload.h>
33 u64 exception_stack
[2*KiB
] __attribute__((aligned(16)));
34 u64
*exception_stack_end
= exception_stack
+ ARRAY_SIZE(exception_stack
);
36 struct exception_handler_info
41 static exception_hook hook
;
42 struct exception_state exception_state
;
44 static struct exception_handler_info exceptions
[EXC_COUNT
] = {
45 [EXC_SYNC_SP0
] = { "_sync_sp_el0" },
46 [EXC_IRQ_SP0
] = { "_irq_sp_el0" },
47 [EXC_FIQ_SP0
] = { "_fiq_sp_el0" },
48 [EXC_SERROR_SP0
] = {"_serror_sp_el0"},
49 [EXC_SYNC_SPX
] = { "_sync_spx" },
50 [EXC_IRQ_SPX
] = { "_irq_spx" },
51 [EXC_FIQ_SPX
] = { "_fiq_spx" },
52 [EXC_SERROR_SPX
] = {"_serror_spx"},
53 [EXC_SYNC_ELX_64
] = { "_sync_elx_64" },
54 [EXC_IRQ_ELX_64
] = { "_irq_elx_64" },
55 [EXC_FIQ_ELX_64
] = { "_fiq_elx_64" },
56 [EXC_SERROR_ELX_64
] = {"_serror_elx_64"},
57 [EXC_SYNC_ELX_32
] = { "_sync_elx_32" },
58 [EXC_IRQ_ELX_32
] = { "_irq_elx_32" },
59 [EXC_FIQ_ELX_32
] = { "_fiq_elx_32" },
60 [EXC_SERROR_ELX_32
] = {"_serror_elx_32"},
63 static void dump_stack(uintptr_t addr
, size_t bytes
)
66 const int words_per_line
= 8;
67 uint64_t *ptr
= (void *)ALIGN_DOWN(addr
, words_per_line
* sizeof(*ptr
));
69 printf("Dumping stack:\n");
70 for (i
= bytes
/ sizeof(*ptr
); i
>= 0; i
-= words_per_line
) {
71 printf("%p: ", ptr
+ i
);
72 for (j
= i
; j
< i
+ words_per_line
; j
++)
73 printf("%016llx ", *(ptr
+ j
));
78 static void print_regs(struct exception_state
*state
)
82 printf("ELR = 0x%016llx ESR = 0x%08llx\n",
83 state
->elr
, state
->esr
);
84 printf("FAR = 0x%016llx SPSR = 0x%08llx\n",
85 raw_read_far_el2(), raw_read_spsr_el2());
86 for (i
= 0; i
< 30; i
+= 2) {
87 printf("X%02d = 0x%016llx X%02d = 0x%016llx\n",
88 i
, state
->regs
[i
], i
+ 1, state
->regs
[i
+ 1]);
90 printf("X30 = 0x%016llx SP = 0x%016llx\n",
91 state
->regs
[30], state
->sp
);
94 void exception_dispatch(struct exception_state
*state
, int idx
);
95 void exception_dispatch(struct exception_state
*state
, int idx
)
97 if (idx
>= EXC_COUNT
) {
98 printf("Bad exception index %d.\n", idx
);
100 struct exception_handler_info
*info
= &exceptions
[idx
];
101 if (hook
&& hook(idx
))
105 printf("exception %s\n", info
->name
);
107 printf("exception _not_used.\n");
110 /* Few words below SP in case we need state from a returned function. */
111 dump_stack(state
->sp
- 32, 512);
116 void exception_init(void)
118 extern uint64_t exception_table
[];
119 raw_write_vbar_el2((uintptr_t)exception_table
);
120 exception_set_state_ptr(&exception_state
);
123 void exception_install_hook(exception_hook h
)
125 die_if(hook
, "Implement support for a list of hooks if you need it.");