Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 1 | /* |
| 2 | * ARCv2 ISA based core Low Level Intr/Traps/Exceptions(non-TLB) Handling |
| 3 | * |
| 4 | * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as |
| 8 | * published by the Free Software Foundation. |
| 9 | */ |
| 10 | |
| 11 | #include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ |
| 12 | #include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ |
| 13 | #include <asm/errno.h> |
| 14 | #include <asm/arcregs.h> |
| 15 | #include <asm/irqflags.h> |
| 16 | |
| 17 | .cpu HS |
| 18 | |
| 19 | #define VECTOR .word |
| 20 | |
| 21 | ;############################ Vector Table ################################# |
| 22 | |
| 23 | .section .vector,"a",@progbits |
| 24 | .align 4 |
| 25 | |
| 26 | # Initial 16 slots are Exception Vectors |
Vineet Gupta | 3971cdc | 2015-10-09 11:26:12 +0530 | [diff] [blame] | 27 | VECTOR res_service ; Reset Vector |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 28 | VECTOR mem_service ; Mem exception |
| 29 | VECTOR instr_service ; Instrn Error |
| 30 | VECTOR EV_MachineCheck ; Fatal Machine check |
| 31 | VECTOR EV_TLBMissI ; Intruction TLB miss |
| 32 | VECTOR EV_TLBMissD ; Data TLB miss |
| 33 | VECTOR EV_TLBProtV ; Protection Violation |
| 34 | VECTOR EV_PrivilegeV ; Privilege Violation |
| 35 | VECTOR EV_SWI ; Software Breakpoint |
| 36 | VECTOR EV_Trap ; Trap exception |
| 37 | VECTOR EV_Extension ; Extn Instruction Exception |
| 38 | VECTOR EV_DivZero ; Divide by Zero |
| 39 | VECTOR EV_DCError ; Data Cache Error |
| 40 | VECTOR EV_Misaligned ; Misaligned Data Access |
| 41 | VECTOR reserved ; Reserved slots |
| 42 | VECTOR reserved ; Reserved slots |
| 43 | |
| 44 | # Begin Interrupt Vectors |
| 45 | VECTOR handle_interrupt ; (16) Timer0 |
| 46 | VECTOR handle_interrupt ; unused (Timer1) |
| 47 | VECTOR handle_interrupt ; unused (WDT) |
Vineet Gupta | bb143f8 | 2016-02-23 11:55:16 +0530 | [diff] [blame] | 48 | VECTOR handle_interrupt ; (19) Inter core Interrupt (IPI) |
| 49 | VECTOR handle_interrupt ; (20) perf Interrupt |
| 50 | VECTOR handle_interrupt ; (21) Software Triggered Intr (Self IPI) |
| 51 | VECTOR handle_interrupt ; unused |
| 52 | VECTOR handle_interrupt ; (23) unused |
| 53 | # End of fixed IRQs |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 54 | |
| 55 | .rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8 |
| 56 | VECTOR handle_interrupt |
| 57 | .endr |
| 58 | |
| 59 | .section .text, "ax",@progbits |
| 60 | |
Vineet Gupta | 3d59265 | 2015-08-27 16:25:07 +0530 | [diff] [blame] | 61 | reserved: |
| 62 | flag 1 ; Unexpected event, halt |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 63 | |
| 64 | ;##################### Interrupt Handling ############################## |
| 65 | |
| 66 | ENTRY(handle_interrupt) |
| 67 | |
| 68 | INTERRUPT_PROLOGUE irq |
| 69 | |
| 70 | clri ; To make status32.IE agree with CPU internal state |
| 71 | |
| 72 | lr r0, [ICAUSE] |
| 73 | |
| 74 | mov blink, ret_from_exception |
| 75 | |
| 76 | b.d arch_do_IRQ |
| 77 | mov r1, sp |
| 78 | |
| 79 | END(handle_interrupt) |
| 80 | |
| 81 | ;################### Non TLB Exception Handling ############################# |
| 82 | |
| 83 | ENTRY(EV_SWI) |
| 84 | flag 1 |
| 85 | END(EV_SWI) |
| 86 | |
| 87 | ENTRY(EV_DivZero) |
| 88 | flag 1 |
| 89 | END(EV_DivZero) |
| 90 | |
| 91 | ENTRY(EV_DCError) |
| 92 | flag 1 |
| 93 | END(EV_DCError) |
| 94 | |
Vineet Gupta | 541366d | 2015-10-31 01:22:51 +0530 | [diff] [blame] | 95 | ; --------------------------------------------- |
| 96 | ; Memory Error Exception Handler |
| 97 | ; - Unlike ARCompact, handles Bus errors for both User/Kernel mode, |
| 98 | ; Instruction fetch or Data access, under a single Exception Vector |
| 99 | ; --------------------------------------------- |
| 100 | |
| 101 | ENTRY(mem_service) |
| 102 | |
| 103 | EXCEPTION_PROLOGUE |
| 104 | |
| 105 | lr r0, [efa] |
| 106 | mov r1, sp |
| 107 | |
| 108 | FAKE_RET_FROM_EXCPN |
| 109 | |
| 110 | bl do_memory_error |
| 111 | b ret_from_exception |
| 112 | END(mem_service) |
| 113 | |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 114 | ENTRY(EV_Misaligned) |
| 115 | |
| 116 | EXCEPTION_PROLOGUE |
| 117 | |
| 118 | lr r0, [efa] ; Faulting Data address |
| 119 | mov r1, sp |
| 120 | |
| 121 | FAKE_RET_FROM_EXCPN |
| 122 | |
| 123 | SAVE_CALLEE_SAVED_USER |
| 124 | mov r2, sp ; callee_regs |
| 125 | |
| 126 | bl do_misaligned_access |
| 127 | |
| 128 | ; TBD: optimize - do this only if a callee reg was involved |
| 129 | ; either a dst of emulated LD/ST or src with address-writeback |
| 130 | RESTORE_CALLEE_SAVED_USER |
| 131 | |
| 132 | b ret_from_exception |
| 133 | END(EV_Misaligned) |
| 134 | |
| 135 | ; --------------------------------------------- |
| 136 | ; Protection Violation Exception Handler |
| 137 | ; --------------------------------------------- |
| 138 | |
| 139 | ENTRY(EV_TLBProtV) |
| 140 | |
| 141 | EXCEPTION_PROLOGUE |
| 142 | |
| 143 | lr r0, [efa] ; Faulting Data address |
| 144 | mov r1, sp ; pt_regs |
| 145 | |
| 146 | FAKE_RET_FROM_EXCPN |
| 147 | |
| 148 | mov blink, ret_from_exception |
| 149 | b do_page_fault |
| 150 | |
| 151 | END(EV_TLBProtV) |
| 152 | |
| 153 | ; From Linux standpoint Slow Path I/D TLB Miss is same a ProtV as they |
| 154 | ; need to call do_page_fault(). |
| 155 | ; ECR in pt_regs provides whether access was R/W/X |
| 156 | |
| 157 | .global call_do_page_fault |
| 158 | .set call_do_page_fault, EV_TLBProtV |
| 159 | |
| 160 | ;############# Common Handlers for ARCompact and ARCv2 ############## |
| 161 | |
| 162 | #include "entry.S" |
| 163 | |
| 164 | ;############# Return from Intr/Excp/Trap (ARCv2 ISA Specifics) ############## |
| 165 | ; |
| 166 | ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap) |
| 167 | ; IRQ shd definitely not happen between now and rtie |
| 168 | ; All 2 entry points to here already disable interrupts |
| 169 | |
| 170 | .Lrestore_regs: |
| 171 | |
| 172 | ld r0, [sp, PT_status32] ; U/K mode at time of entry |
| 173 | lr r10, [AUX_IRQ_ACT] |
| 174 | |
| 175 | bmsk r11, r10, 15 ; AUX_IRQ_ACT.ACTIVE |
| 176 | breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception |
| 177 | |
| 178 | ;####### Return from Intr ####### |
| 179 | |
| 180 | debug_marker_l1: |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 181 | bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot |
| 182 | |
| 183 | .Lisr_ret_fast_path: |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 184 | ; Handle special case #1: (Entry via Exception, Return via IRQ) |
| 185 | ; |
| 186 | ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig |
| 187 | ; task now returning to U mode (riding the Intr) |
| 188 | ; AUX_IRQ_ACTIVE won't have U bit set (since intr in K mode), hence SP |
| 189 | ; won't be switched to correct U mode value (from AUX_SP) |
| 190 | ; So force AUX_IRQ_ACT.U for such a case |
| 191 | |
| 192 | btst r0, STATUS_U_BIT ; Z flag set if K (Z clear for U) |
| 193 | bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U |
| 194 | sr r11, [AUX_IRQ_ACT] |
| 195 | |
| 196 | INTERRUPT_EPILOGUE irq |
| 197 | rtie |
| 198 | |
| 199 | ;####### Return from Exception / pure kernel mode ####### |
| 200 | |
| 201 | .Lexcept_ret: ; Expects r0 has PT_status32 |
| 202 | |
| 203 | debug_marker_syscall: |
| 204 | EXCEPTION_EPILOGUE |
| 205 | rtie |
| 206 | |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 207 | ;####### Return from Intr to insn in delay slot ####### |
| 208 | |
| 209 | ; Handle special case #2: (Entry via Exception in Delay Slot, Return via IRQ) |
| 210 | ; |
| 211 | ; Intr returning to a Delay Slot (DS) insn |
| 212 | ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig |
| 213 | ; entry was via Exception in DS which got preempted in kernel). |
| 214 | ; |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 215 | ; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround |
| 216 | ; |
| 217 | ; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline |
| 218 | ; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly |
| 219 | |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 220 | .Lintr_ret_to_delay_slot: |
| 221 | debug_marker_ds: |
| 222 | |
| 223 | ld r2, [@intr_to_DE_cnt] |
| 224 | add r2, r2, 1 |
| 225 | st r2, [@intr_to_DE_cnt] |
| 226 | |
| 227 | ld r2, [sp, PT_ret] |
| 228 | ld r3, [sp, PT_status32] |
| 229 | |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 230 | ; STAT32 for Int return created from scratch |
| 231 | ; (No delay dlot, disable Further intr in trampoline) |
| 232 | |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 233 | bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK |
| 234 | st r0, [sp, PT_status32] |
| 235 | |
| 236 | mov r1, .Lintr_ret_to_delay_slot_2 |
| 237 | st r1, [sp, PT_ret] |
| 238 | |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 239 | ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 240 | st r2, [sp, 0] |
| 241 | st r3, [sp, 4] |
| 242 | |
| 243 | b .Lisr_ret_fast_path |
| 244 | |
| 245 | .Lintr_ret_to_delay_slot_2: |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 246 | ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 247 | sub sp, sp, SZ_PT_REGS |
| 248 | st r9, [sp, -4] |
| 249 | |
| 250 | ld r9, [sp, 0] |
| 251 | sr r9, [eret] |
| 252 | |
| 253 | ld r9, [sp, 4] |
| 254 | sr r9, [erstatus] |
| 255 | |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 256 | ; restore AUX_USER_SP if returning to U mode |
| 257 | bbit0 r9, STATUS_U_BIT, 1f |
| 258 | ld r9, [sp, PT_sp] |
| 259 | sr r9, [AUX_USER_SP] |
| 260 | |
| 261 | 1: |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 262 | ld r9, [sp, 8] |
| 263 | sr r9, [erbta] |
| 264 | |
| 265 | ld r9, [sp, -4] |
| 266 | add sp, sp, SZ_PT_REGS |
Vineet Gupta | cbfe74a | 2016-01-08 12:29:10 +0530 | [diff] [blame] | 267 | |
| 268 | ; return from pure kernel mode to delay slot |
Vineet Gupta | 4255b07 | 2014-09-22 16:51:47 +0530 | [diff] [blame] | 269 | rtie |
| 270 | |
Vineet Gupta | 1f6ccff | 2013-05-13 18:30:41 +0530 | [diff] [blame] | 271 | END(ret_from_exception) |