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