^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2005-2017 Andes Technology Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <asm/memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/nds32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifdef CONFIG_HWZOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) .macro push_zol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) mfusr $r14, $LB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) mfusr $r15, $LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) mfusr $r16, $LC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .macro skip_save_fucop_ctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #if defined(CONFIG_FPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) skip_fucop_ctl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) smw.adm $p0, [$sp], $p0, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) j fucop_ctl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .macro save_user_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #if defined(CONFIG_FPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) sethi $p0, hi20(has_fpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) lbsi $p0, [$p0+lo12(has_fpu)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) beqz $p0, skip_fucop_ctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) mfsr $p0, $FUCOP_CTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) smw.adm $p0, [$sp], $p0, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) bclr $p0, $p0, #FUCOP_CTL_offCP0EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) mtsr $p0, $FUCOP_CTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) fucop_ctl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* move $SP to the bottom of pt_regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) addi $sp, $sp, -FUCOP_CTL_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) smw.adm $sp, [$sp], $sp, #0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* move $SP to the bottom of pt_regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) addi $sp, $sp, -OSP_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* push $r0 ~ $r25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) smw.bim $r0, [$sp], $r25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* push $fp, $gp, $lp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) smw.bim $sp, [$sp], $sp, #0xe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) mfsr $r12, $SP_USR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mfsr $r13, $IPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #ifdef CONFIG_HWZOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) push_zol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) movi $r17, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) move $r18, $r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mfsr $r19, $PSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mfsr $r20, $IPSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mfsr $r21, $P_IPSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mfsr $r22, $P_IPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mfsr $r23, $P_P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mfsr $r24, $P_P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) smw.bim $r12, [$sp], $r24, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) addi $sp, $sp, -FUCOP_CTL_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Initialize kernel space $fp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) andi $p0, $r20, #PSW_mskPOM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) movi $p1, #0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) cmovz $fp, $p1, $p0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) andi $r16, $r19, #PSW_mskINTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) slti $r17, $r16, #4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bnez $r17, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addi $r17, $r19, #-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mtsr $r17, $PSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) isb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* If it was superuser mode, we don't need to update $r25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) bnez $p0, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) la $p0, __entry_task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) lw $r25, [$p0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Exception Vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) exception_handlers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .long unhandled_exceptions !Reset/NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .long unhandled_exceptions !TLB fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .long do_page_fault !PTE not present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .long do_dispatch_tlb_misc !TLB misc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .long unhandled_exceptions !TLB VLPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .long unhandled_exceptions !Machine Error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .long do_debug_trap !Debug related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .long do_dispatch_general !General exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .long eh_syscall !Syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .long asm_do_IRQ !IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) skip_save_fucop_ctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) common_exception_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) save_user_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mfsr $p0, $ITYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) andi $p0, $p0, #ITYPE_mskVECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) srli $p0, $p0, #ITYPE_offVECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) andi $p1, $p0, #NDS32_VECTOR_mskNONEXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) bnez $p1, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) sethi $lp, hi20(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ori $lp, $lp, lo12(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) sethi $p1, hi20(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ori $p1, $p1, lo12(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) lw $p1, [$p1+$p0<<2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) move $r0, $p0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mfsr $r1, $EVA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mfsr $r2, $ITYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) move $r3, $sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mfsr $r4, $OIPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* enable gie if it is enabled in IPSW. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mfsr $r21, $PSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) andi $r20, $r20, #PSW_mskGIE /* r20 is $IPSW*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) or $r21, $r21, $r20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mtsr $r21, $PSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) jr $p1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* syscall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) addi $p1, $p0, #-NDS32_VECTOR_offEXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bnez $p1, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) sethi $lp, hi20(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ori $lp, $lp, lo12(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) sethi $p1, hi20(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ori $p1, $p1, lo12(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) lwi $p1, [$p1+#NDS32_VECTOR_offEXCEPTION<<2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) jr $p1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #ifdef CONFIG_TRACE_IRQFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) jal __trace_hardirqs_off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) move $r0, $sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) sethi $lp, hi20(ret_from_intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ori $lp, $lp, lo12(ret_from_intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) sethi $p0, hi20(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ori $p0, $p0, lo12(exception_handlers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) lwi $p0, [$p0+#NDS32_VECTOR_offINTERRUPT<<2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) jr $p0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .macro EXCEPTION_VECTOR_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mfsr $p0, $EDM_CTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) tnez $p0, SWID_RAISE_INTERRUPT_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .macro EXCEPTION_VECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) sethi $p0, hi20(common_exception_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ori $p0, $p0, lo12(common_exception_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) jral.ton $p0, $p0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .section ".text.init", #alloc, #execinstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .global exception_vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) exception_vector:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .rept 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) EXCEPTION_VECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) EXCEPTION_VECTOR_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .rept 121
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) EXCEPTION_VECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .global exception_vector_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) exception_vector_end: