1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 21f6ccfffSVineet Gupta/* 31f6ccfffSVineet Gupta * ARCv2 ISA based core Low Level Intr/Traps/Exceptions(non-TLB) Handling 41f6ccfffSVineet Gupta * 51f6ccfffSVineet Gupta * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) 61f6ccfffSVineet Gupta */ 71f6ccfffSVineet Gupta 81f6ccfffSVineet Gupta#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ 91f6ccfffSVineet Gupta#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ 101f6ccfffSVineet Gupta#include <asm/errno.h> 111f6ccfffSVineet Gupta#include <asm/arcregs.h> 121f6ccfffSVineet Gupta#include <asm/irqflags.h> 131f6ccfffSVineet Gupta 14f33b8cddSYuriy Kolerov; A maximum number of supported interrupts in the core interrupt controller. 15f33b8cddSYuriy Kolerov; This number is not equal to the maximum interrupt number (256) because 16f33b8cddSYuriy Kolerov; first 16 lines are reserved for exceptions and are not configurable. 17f33b8cddSYuriy Kolerov#define NR_CPU_IRQS 240 18f33b8cddSYuriy Kolerov 191f6ccfffSVineet Gupta .cpu HS 201f6ccfffSVineet Gupta 211f6ccfffSVineet Gupta#define VECTOR .word 221f6ccfffSVineet Gupta 231f6ccfffSVineet Gupta;############################ Vector Table ################################# 241f6ccfffSVineet Gupta 251f6ccfffSVineet Gupta .section .vector,"a",@progbits 261f6ccfffSVineet Gupta .align 4 271f6ccfffSVineet Gupta 281f6ccfffSVineet Gupta# Initial 16 slots are Exception Vectors 293971cdc2SVineet GuptaVECTOR res_service ; Reset Vector 301f6ccfffSVineet GuptaVECTOR mem_service ; Mem exception 311f6ccfffSVineet GuptaVECTOR instr_service ; Instrn Error 321f6ccfffSVineet GuptaVECTOR EV_MachineCheck ; Fatal Machine check 331f6ccfffSVineet GuptaVECTOR EV_TLBMissI ; Intruction TLB miss 341f6ccfffSVineet GuptaVECTOR EV_TLBMissD ; Data TLB miss 351f6ccfffSVineet GuptaVECTOR EV_TLBProtV ; Protection Violation 361f6ccfffSVineet GuptaVECTOR EV_PrivilegeV ; Privilege Violation 371f6ccfffSVineet GuptaVECTOR EV_SWI ; Software Breakpoint 381f6ccfffSVineet GuptaVECTOR EV_Trap ; Trap exception 391f6ccfffSVineet GuptaVECTOR EV_Extension ; Extn Instruction Exception 401f6ccfffSVineet GuptaVECTOR EV_DivZero ; Divide by Zero 411f6ccfffSVineet GuptaVECTOR EV_DCError ; Data Cache Error 421f6ccfffSVineet GuptaVECTOR EV_Misaligned ; Misaligned Data Access 431f6ccfffSVineet GuptaVECTOR reserved ; Reserved slots 441f6ccfffSVineet GuptaVECTOR reserved ; Reserved slots 451f6ccfffSVineet Gupta 461f6ccfffSVineet Gupta# Begin Interrupt Vectors 471f6ccfffSVineet GuptaVECTOR handle_interrupt ; (16) Timer0 481f6ccfffSVineet GuptaVECTOR handle_interrupt ; unused (Timer1) 491f6ccfffSVineet GuptaVECTOR handle_interrupt ; unused (WDT) 50bb143f81SVineet GuptaVECTOR handle_interrupt ; (19) Inter core Interrupt (IPI) 51bb143f81SVineet GuptaVECTOR handle_interrupt ; (20) perf Interrupt 52bb143f81SVineet GuptaVECTOR handle_interrupt ; (21) Software Triggered Intr (Self IPI) 53bb143f81SVineet GuptaVECTOR handle_interrupt ; unused 54bb143f81SVineet GuptaVECTOR handle_interrupt ; (23) unused 55bb143f81SVineet Gupta# End of fixed IRQs 561f6ccfffSVineet Gupta 57f33b8cddSYuriy Kolerov.rept NR_CPU_IRQS - 8 581f6ccfffSVineet Gupta VECTOR handle_interrupt 591f6ccfffSVineet Gupta.endr 601f6ccfffSVineet Gupta 611f6ccfffSVineet Gupta .section .text, "ax",@progbits 621f6ccfffSVineet Gupta 633d592659SVineet Guptareserved: 643d592659SVineet Gupta flag 1 ; Unexpected event, halt 651f6ccfffSVineet Gupta 661f6ccfffSVineet Gupta;##################### Interrupt Handling ############################## 671f6ccfffSVineet Gupta 681f6ccfffSVineet GuptaENTRY(handle_interrupt) 691f6ccfffSVineet Gupta 701f6ccfffSVineet Gupta INTERRUPT_PROLOGUE irq 711f6ccfffSVineet Gupta 7278833e79SVineet Gupta # irq control APIs local_irq_save/restore/disable/enable fiddle with 7378833e79SVineet Gupta # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio) 7478833e79SVineet Gupta # However a taken interrupt doesn't clear these bits. Thus irqs_disabled() 7578833e79SVineet Gupta # query in hard ISR path would return false (since .IE is set) which would 7678833e79SVineet Gupta # trips genirq interrupt handling asserts. 7778833e79SVineet Gupta # 7878833e79SVineet Gupta # So do a "soft" disable of interrutps here. 7978833e79SVineet Gupta # 8078833e79SVineet Gupta # Note this disable is only for consistent book-keeping as further interrupts 8178833e79SVineet Gupta # will be disabled anyways even w/o this. Hardware tracks active interrupts 8278833e79SVineet Gupta # seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts 8378833e79SVineet Gupta # unless this one returns (or higher prio becomes pending in 2-prio scheme) 841f6ccfffSVineet Gupta 8578833e79SVineet Gupta IRQ_DISABLE 861f6ccfffSVineet Gupta 8778833e79SVineet Gupta ; icause is banked: one per priority level 8878833e79SVineet Gupta ; so a higher prio interrupt taken here won't clobber prev prio icause 89d9676fa1SEvgeny Voevodin lr r0, [ICAUSE] 901f6ccfffSVineet Gupta mov blink, ret_from_exception 911f6ccfffSVineet Gupta 921f6ccfffSVineet Gupta b.d arch_do_IRQ 931f6ccfffSVineet Gupta mov r1, sp 941f6ccfffSVineet Gupta 951f6ccfffSVineet GuptaEND(handle_interrupt) 961f6ccfffSVineet Gupta 971f6ccfffSVineet Gupta;################### Non TLB Exception Handling ############################# 981f6ccfffSVineet Gupta 991f6ccfffSVineet GuptaENTRY(EV_SWI) 100814a5850SVineet Gupta ; TODO: implement this 101814a5850SVineet Gupta EXCEPTION_PROLOGUE 102814a5850SVineet Gupta b ret_from_exception 1031f6ccfffSVineet GuptaEND(EV_SWI) 1041f6ccfffSVineet Gupta 1051f6ccfffSVineet GuptaENTRY(EV_DivZero) 106814a5850SVineet Gupta ; TODO: implement this 107814a5850SVineet Gupta EXCEPTION_PROLOGUE 108814a5850SVineet Gupta b ret_from_exception 1091f6ccfffSVineet GuptaEND(EV_DivZero) 1101f6ccfffSVineet Gupta 1111f6ccfffSVineet GuptaENTRY(EV_DCError) 112814a5850SVineet Gupta ; TODO: implement this 113814a5850SVineet Gupta EXCEPTION_PROLOGUE 114814a5850SVineet Gupta b ret_from_exception 1151f6ccfffSVineet GuptaEND(EV_DCError) 1161f6ccfffSVineet Gupta 117541366daSVineet Gupta; --------------------------------------------- 118541366daSVineet Gupta; Memory Error Exception Handler 119541366daSVineet Gupta; - Unlike ARCompact, handles Bus errors for both User/Kernel mode, 120541366daSVineet Gupta; Instruction fetch or Data access, under a single Exception Vector 121541366daSVineet Gupta; --------------------------------------------- 122541366daSVineet Gupta 123541366daSVineet GuptaENTRY(mem_service) 124541366daSVineet Gupta 125541366daSVineet Gupta EXCEPTION_PROLOGUE 126541366daSVineet Gupta 127541366daSVineet Gupta lr r0, [efa] 128541366daSVineet Gupta mov r1, sp 129541366daSVineet Gupta 130541366daSVineet Gupta FAKE_RET_FROM_EXCPN 131541366daSVineet Gupta 132541366daSVineet Gupta bl do_memory_error 133541366daSVineet Gupta b ret_from_exception 134541366daSVineet GuptaEND(mem_service) 135541366daSVineet Gupta 1361f6ccfffSVineet GuptaENTRY(EV_Misaligned) 1371f6ccfffSVineet Gupta 1381f6ccfffSVineet Gupta EXCEPTION_PROLOGUE 1391f6ccfffSVineet Gupta 1401f6ccfffSVineet Gupta lr r0, [efa] ; Faulting Data address 1411f6ccfffSVineet Gupta mov r1, sp 1421f6ccfffSVineet Gupta 1431f6ccfffSVineet Gupta FAKE_RET_FROM_EXCPN 1441f6ccfffSVineet Gupta 1451f6ccfffSVineet Gupta SAVE_CALLEE_SAVED_USER 1461f6ccfffSVineet Gupta mov r2, sp ; callee_regs 1471f6ccfffSVineet Gupta 1481f6ccfffSVineet Gupta bl do_misaligned_access 1491f6ccfffSVineet Gupta 1501f6ccfffSVineet Gupta ; TBD: optimize - do this only if a callee reg was involved 1511f6ccfffSVineet Gupta ; either a dst of emulated LD/ST or src with address-writeback 1521f6ccfffSVineet Gupta RESTORE_CALLEE_SAVED_USER 1531f6ccfffSVineet Gupta 1541f6ccfffSVineet Gupta b ret_from_exception 1551f6ccfffSVineet GuptaEND(EV_Misaligned) 1561f6ccfffSVineet Gupta 1571f6ccfffSVineet Gupta; --------------------------------------------- 1581f6ccfffSVineet Gupta; Protection Violation Exception Handler 1591f6ccfffSVineet Gupta; --------------------------------------------- 1601f6ccfffSVineet Gupta 1611f6ccfffSVineet GuptaENTRY(EV_TLBProtV) 1621f6ccfffSVineet Gupta 1631f6ccfffSVineet Gupta EXCEPTION_PROLOGUE 1641f6ccfffSVineet Gupta 1651f6ccfffSVineet Gupta lr r0, [efa] ; Faulting Data address 1661f6ccfffSVineet Gupta mov r1, sp ; pt_regs 1671f6ccfffSVineet Gupta 1681f6ccfffSVineet Gupta FAKE_RET_FROM_EXCPN 1691f6ccfffSVineet Gupta 1701f6ccfffSVineet Gupta mov blink, ret_from_exception 1711f6ccfffSVineet Gupta b do_page_fault 1721f6ccfffSVineet Gupta 1731f6ccfffSVineet GuptaEND(EV_TLBProtV) 1741f6ccfffSVineet Gupta 1751f6ccfffSVineet Gupta; From Linux standpoint Slow Path I/D TLB Miss is same a ProtV as they 1761f6ccfffSVineet Gupta; need to call do_page_fault(). 1771f6ccfffSVineet Gupta; ECR in pt_regs provides whether access was R/W/X 1781f6ccfffSVineet Gupta 1791f6ccfffSVineet Gupta.global call_do_page_fault 1801f6ccfffSVineet Gupta.set call_do_page_fault, EV_TLBProtV 1811f6ccfffSVineet Gupta 1821f6ccfffSVineet Gupta;############# Common Handlers for ARCompact and ARCv2 ############## 1831f6ccfffSVineet Gupta 1841f6ccfffSVineet Gupta#include "entry.S" 1851f6ccfffSVineet Gupta 1861f6ccfffSVineet Gupta;############# Return from Intr/Excp/Trap (ARCv2 ISA Specifics) ############## 1871f6ccfffSVineet Gupta; 1881f6ccfffSVineet Gupta; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap) 1891f6ccfffSVineet Gupta; IRQ shd definitely not happen between now and rtie 1901f6ccfffSVineet Gupta; All 2 entry points to here already disable interrupts 1911f6ccfffSVineet Gupta 1921f6ccfffSVineet Gupta.Lrestore_regs: 19378833e79SVineet Guptarestore_regs: 1941f6ccfffSVineet Gupta 195d9676fa1SEvgeny Voevodin # Interrpts are actually disabled from this point on, but will get 196d9676fa1SEvgeny Voevodin # reenabled after we return from interrupt/exception. 197d9676fa1SEvgeny Voevodin # But irq tracer needs to be told now... 198d9676fa1SEvgeny Voevodin TRACE_ASM_IRQ_ENABLE 199d9676fa1SEvgeny Voevodin 2001f6ccfffSVineet Gupta ld r0, [sp, PT_status32] ; U/K mode at time of entry 2011f6ccfffSVineet Gupta lr r10, [AUX_IRQ_ACT] 2021f6ccfffSVineet Gupta 2031f6ccfffSVineet Gupta bmsk r11, r10, 15 ; AUX_IRQ_ACT.ACTIVE 2041f6ccfffSVineet Gupta breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception 2051f6ccfffSVineet Gupta 2061f6ccfffSVineet Gupta;####### Return from Intr ####### 2071f6ccfffSVineet Gupta 2081f6ccfffSVineet Guptadebug_marker_l1: 209e494239aSVineet Gupta ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot 210e494239aSVineet Gupta btst r0, STATUS_DE_BIT ; Z flag set if bit clear 211e494239aSVineet Gupta bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set 2124255b07fSVineet Gupta 2134255b07fSVineet Gupta.Lisr_ret_fast_path: 2141f6ccfffSVineet Gupta ; Handle special case #1: (Entry via Exception, Return via IRQ) 2151f6ccfffSVineet Gupta ; 2161f6ccfffSVineet Gupta ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig 2171f6ccfffSVineet Gupta ; task now returning to U mode (riding the Intr) 2181f6ccfffSVineet Gupta ; AUX_IRQ_ACTIVE won't have U bit set (since intr in K mode), hence SP 2191f6ccfffSVineet Gupta ; won't be switched to correct U mode value (from AUX_SP) 2201f6ccfffSVineet Gupta ; So force AUX_IRQ_ACT.U for such a case 2211f6ccfffSVineet Gupta 2221f6ccfffSVineet Gupta btst r0, STATUS_U_BIT ; Z flag set if K (Z clear for U) 2231f6ccfffSVineet Gupta bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U 2241f6ccfffSVineet Gupta sr r11, [AUX_IRQ_ACT] 2251f6ccfffSVineet Gupta 2261f6ccfffSVineet Gupta INTERRUPT_EPILOGUE irq 2271f6ccfffSVineet Gupta rtie 2281f6ccfffSVineet Gupta 2291f6ccfffSVineet Gupta;####### Return from Exception / pure kernel mode ####### 2301f6ccfffSVineet Gupta 2311f6ccfffSVineet Gupta.Lexcept_ret: ; Expects r0 has PT_status32 2321f6ccfffSVineet Gupta 2331f6ccfffSVineet Guptadebug_marker_syscall: 2341f6ccfffSVineet Gupta EXCEPTION_EPILOGUE 2351f6ccfffSVineet Gupta rtie 2361f6ccfffSVineet Gupta 2374255b07fSVineet Gupta;####### Return from Intr to insn in delay slot ####### 2384255b07fSVineet Gupta 2394255b07fSVineet Gupta; Handle special case #2: (Entry via Exception in Delay Slot, Return via IRQ) 2404255b07fSVineet Gupta; 2414255b07fSVineet Gupta; Intr returning to a Delay Slot (DS) insn 2424255b07fSVineet Gupta; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig 2434255b07fSVineet Gupta; entry was via Exception in DS which got preempted in kernel). 2444255b07fSVineet Gupta; 245cbfe74a7SVineet Gupta; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround 246cbfe74a7SVineet Gupta; 247cbfe74a7SVineet Gupta; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline 248cbfe74a7SVineet Gupta; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly 249cbfe74a7SVineet Gupta 2504255b07fSVineet Gupta.Lintr_ret_to_delay_slot: 2514255b07fSVineet Guptadebug_marker_ds: 2524255b07fSVineet Gupta 2534255b07fSVineet Gupta ld r2, [@intr_to_DE_cnt] 2544255b07fSVineet Gupta add r2, r2, 1 2554255b07fSVineet Gupta st r2, [@intr_to_DE_cnt] 2564255b07fSVineet Gupta 2574255b07fSVineet Gupta ld r2, [sp, PT_ret] 2584255b07fSVineet Gupta ld r3, [sp, PT_status32] 2594255b07fSVineet Gupta 260cbfe74a7SVineet Gupta ; STAT32 for Int return created from scratch 261cbfe74a7SVineet Gupta ; (No delay dlot, disable Further intr in trampoline) 262cbfe74a7SVineet Gupta 2634255b07fSVineet Gupta bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK 2644255b07fSVineet Gupta st r0, [sp, PT_status32] 2654255b07fSVineet Gupta 2664255b07fSVineet Gupta mov r1, .Lintr_ret_to_delay_slot_2 2674255b07fSVineet Gupta st r1, [sp, PT_ret] 2684255b07fSVineet Gupta 269cbfe74a7SVineet Gupta ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots 2704255b07fSVineet Gupta st r2, [sp, 0] 2714255b07fSVineet Gupta st r3, [sp, 4] 2724255b07fSVineet Gupta 2734255b07fSVineet Gupta b .Lisr_ret_fast_path 2744255b07fSVineet Gupta 2754255b07fSVineet Gupta.Lintr_ret_to_delay_slot_2: 276cbfe74a7SVineet Gupta ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP 2774255b07fSVineet Gupta sub sp, sp, SZ_PT_REGS 2784255b07fSVineet Gupta st r9, [sp, -4] 2794255b07fSVineet Gupta 2804255b07fSVineet Gupta ld r9, [sp, 0] 2814255b07fSVineet Gupta sr r9, [eret] 2824255b07fSVineet Gupta 2834255b07fSVineet Gupta ld r9, [sp, 4] 2844255b07fSVineet Gupta sr r9, [erstatus] 2854255b07fSVineet Gupta 286cbfe74a7SVineet Gupta ; restore AUX_USER_SP if returning to U mode 287cbfe74a7SVineet Gupta bbit0 r9, STATUS_U_BIT, 1f 288cbfe74a7SVineet Gupta ld r9, [sp, PT_sp] 289cbfe74a7SVineet Gupta sr r9, [AUX_USER_SP] 290cbfe74a7SVineet Gupta 291cbfe74a7SVineet Gupta1: 2924255b07fSVineet Gupta ld r9, [sp, 8] 2934255b07fSVineet Gupta sr r9, [erbta] 2944255b07fSVineet Gupta 2954255b07fSVineet Gupta ld r9, [sp, -4] 2964255b07fSVineet Gupta add sp, sp, SZ_PT_REGS 297cbfe74a7SVineet Gupta 298cbfe74a7SVineet Gupta ; return from pure kernel mode to delay slot 2994255b07fSVineet Gupta rtie 3004255b07fSVineet Gupta 3011f6ccfffSVineet GuptaEND(ret_from_exception) 302