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