1/*
2 * Copyright (c) 2007,2008,2009,2015, ETH Zurich.
3 * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
4 * All rights reserved.
5 *
6 * This file is distributed under the terms in the attached LICENSE file.
7 * If you do not find this file, copies can be found by writing to:
8 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
9 */
10
11#ifndef KERNEL_ARMV8_EXCEPTIONS_H
12#define KERNEL_ARMV8_EXCEPTIONS_H
13
14#define AARCH64_EVECTOR_UNDEF       0x00
15#define AARCH64_EVECTOR_EL0_SYNC    0x01
16#define AARCH64_EVECTOR_EL0_IRQ     0x02
17#define AARCH64_EVECTOR_EL0_FIQ     0x03
18#define AARCH64_EVECTOR_EL0_SERROR  0x04
19#define AARCH64_EVECTOR_EL1_SYNC    0x05
20#define AARCH64_EVECTOR_EL1_IRQ     0x06
21#define AARCH64_EVECTOR_EL1_FIQ     0x07
22#define AARCH64_EVECTOR_EL1_SERROR  0x08
23#define AARCH64_EVECTOR_EL2_SYNC    0x09
24#define AARCH64_EVECTOR_EL2_IRQ     0x0a
25#define AARCH64_EVECTOR_EL2_FIQ     0x0b
26#define AARCH64_EVECTOR_EL2_SERROR  0x0c
27#define AARCH32_EVECTOR_EL0_SYNC    0x10
28#define AARCH32_EVECTOR_EL0_IRQ     0x11
29#define AARCH32_EVECTOR_EL0_FIQ     0x12
30#define AARCH32_EVECTOR_EL0_SERROR  0x13
31
32#define WAIT_FOR_INTERRUPT_MAGIC    0x1234
33
34#if !defined(__ASSEMBLER__)
35
36enum aarch64_exception_class {
37    aarch64_ec_unknown   = 0x0,
38    aarch64_ec_wfi       = 0x1,
39    aarch64_ec_mcr_cp15  = 0x3,
40    aarch64_ec_mcrr_cp15 = 0x4,
41    aarch64_ec_mcr_cp14  = 0x5,
42    aarch64_ec_ldc_cp14  = 0x6,
43    aarch64_ec_fpen      = 0x7,
44    aarch64_ec_mcr_cp10  = 0x8,
45    aarch64_ec_mcrr_cp14 = 0xc,
46    aarch64_ec_il        = 0xe,
47    aarch64_ec_svc_aa32  = 0x11,
48    aarch64_ec_hvc_aa32  = 0x12,
49    aarch64_ec_smc_aa32  = 0x13,
50    aarch64_ec_svc_aa64  = 0x15,
51    aarch64_ec_hvc_aa64  = 0x16,
52    aarch64_ec_smc_aa64  = 0x17,
53    aarch64_ec_mrs       = 0x18,
54    aarch64_ec_impl      = 0x1f,
55    aarch64_ec_iabt_low  = 0x20,
56    aarch64_ec_iabt_high = 0x21,
57    aarch64_ec_pc_align  = 0x22,
58    aarch64_ec_dabt_low  = 0x24,
59    aarch64_ec_dabt_high = 0x25,
60    aarch64_ec_sp_align  = 0x26,
61    aarch64_ec_fpu_aa32  = 0x28,
62    aarch64_ec_fpu_aa64  = 0x2c,
63    aarch64_ec_serror    = 0x2f,
64    aarch64_ec_bkpt_low  = 0x30,
65    aarch64_ec_bkpt_high = 0x31,
66    aarch64_ec_step_low  = 0x32,
67    aarch64_ec_step_high = 0x33,
68    aarch64_ec_wpt_low   = 0x34,
69    aarch64_ec_wpt_high  = 0x35,
70    aarch64_ec_bkpt_soft = 0x38,
71    aarch64_ec_bkpt_el2  = 0x3a,
72    aarch64_ec_brk       = 0x3c,
73};
74
75enum aarch64_dsfc {
76    aarch64_dsfc_size_l0     = 0x00,
77    aarch64_dsfc_size_l1     = 0x01,
78    aarch64_dsfc_size_l2     = 0x02,
79    aarch64_dsfc_size_l3     = 0x03,
80    aarch64_dsfc_trans_l0    = 0x04,
81    aarch64_dsfc_trans_l1    = 0x05,
82    aarch64_dsfc_trans_l2    = 0x06,
83    aarch64_dsfc_trans_l3    = 0x07,
84    aarch64_dsfc_flag_l1     = 0x09,
85    aarch64_dsfc_flag_l2     = 0x0a,
86    aarch64_dsfc_flag_l3     = 0x0b,
87    aarch64_dsfc_perm_l1     = 0x0d,
88    aarch64_dsfc_perm_l2     = 0x0e,
89    aarch64_dsfc_perm_l3     = 0x0f,
90    aarch64_dsfc_external    = 0x10,
91    aarch64_dsfc_external_l0 = 0x14,
92    aarch64_dsfc_external_l1 = 0x15,
93    aarch64_dsfc_external_l2 = 0x16,
94    aarch64_dsfc_external_l3 = 0x17,
95    aarch64_dsfc_parity      = 0x18,
96    aarch64_dsfc_parity_l0   = 0x1c,
97    aarch64_dsfc_parity_l1   = 0x1d,
98    aarch64_dsfc_parity_l2   = 0x1e,
99    aarch64_dsfc_parity_l3   = 0x1f,
100    aarch64_dsfc_alighment   = 0x21,
101    aarch64_dsfc_tlb_confl   = 0x30,
102    aarch64_dsfc_impl1       = 0x34,
103    aarch64_dsfc_impl2       = 0x35,
104    aarch64_dsfc_sect_dom    = 0x3d,
105    aarch64_dsfc_page_dom    = 0x3e,
106};
107
108#define CACHE_LINE_BYTES        64
109#define ETABLE_ADDR     		0xffffffffffff0000
110#define ETABLE_SECTION_OFFSET	0xf000
111#define JUMP_TABLE_OFFSET		0x100
112#define ETABLE_PHYS_BASE		0x800f0000
113
114
115/* The exception vector table. */
116extern int vectors;
117
118/**
119 * Handle page fault in user-mode process.
120 *
121 * This function should be called in SVC mode with interrupts disabled.
122 */
123 void handle_user_page_fault(lvaddr_t                fault_address,
124                             arch_registers_state_t* save_area,
125                             union registers_aarch64 *resume_area);
126
127/**
128 * Handle undefined instruction fault in user-mode process.
129 *
130 * This function should be called in SVC mode with interrupts disabled.
131 */
132 void handle_user_undef(lvaddr_t fault_address, enum aarch64_exception_class cause,
133                        arch_registers_state_t* save_area,
134                        union registers_aarch64 *resume_area);
135
136void handle_user_fault(lvaddr_t fault_address, uintptr_t cause,
137                       arch_registers_state_t* save_area)__attribute__((noreturn));
138
139/**
140 * Handle faults in occuring in a priviledged mode.
141 *
142 * This function should be called with interrupts disabled.
143 */
144void fatal_kernel_fault(lvaddr_t epc, uint64_t spsr, uint64_t esr,
145                        uint64_t vector, arch_registers_state_t* save_area)
146    __attribute__((noreturn));
147
148/**
149 * Handle IRQs without saving any state, hence it should be called when
150 * the state is properly saved and an interrupt occurs. Can happen
151 * from EL0 interrupt after we saved the state and EL1 (kernel) interrupt.
152 *
153 * This function should be called with interrupts disabled.
154 */
155void nosave_handle_irq(void) __attribute__((noreturn));
156
157/**
158 * Handle IRQs occuring in EL0. Expects a partially saved register
159 * state. Stores the arguments and FPU state in the save_area.
160 *
161 * This function should be called with interrupts disabled.
162 */
163void save_handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
164                uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
165    __attribute__((noreturn));
166
167#endif // !defined(__ASSEMBLER__)
168
169#endif // __KERNEL_ARMV8_EXCEPTIONS_H__
170