^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/arch/nios2/kernel/entry.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2013-2014 Altera Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009, Wind River Systems Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Kenneth Albanowski <kjahds@kjahds.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2004 Microtronix Datacom Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Linux/m68k support by Hamish Macdonald
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 68060 fixes by Jesper Skov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * ColdFire support by Greg Ungerer (gerg@snapgear.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 5307 fixes by David W. Miller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * linux 2.4 support David McCullough <davidm@snapgear.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/sys.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/asm-macros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/entry.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .macro GET_THREAD_INFO reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .if THREAD_SIZE & 0xffff0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) andhi \reg, sp, %hi(~(THREAD_SIZE-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) addi \reg, r0, %lo(~(THREAD_SIZE-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) and \reg, \reg, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .macro kuser_cmpxchg_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Make sure our user space atomic helper is restarted if it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * interrupted in a critical region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * ea-4 = address of interrupted insn (ea must be preserved).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * sp = saved regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * cmpxchg_ldw = first critical insn, cmpxchg_stw = last critical insn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * If ea <= cmpxchg_stw and ea > cmpxchg_ldw then saved EA is set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * cmpxchg_ldw + 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* et = cmpxchg_stw + 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) movui et, (KUSER_BASE + 4 + (cmpxchg_stw - __kuser_helper_start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bgtu ea, et, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) subi et, et, (cmpxchg_stw - cmpxchg_ldw) /* et = cmpxchg_ldw + 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) bltu ea, et, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) stw et, PT_EA(sp) /* fix up EA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mov ea, et
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .section .rodata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) exception_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .word unhandled_exception /* 0 - Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .word unhandled_exception /* 1 - Processor-only Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .word external_interrupt /* 2 - Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .word handle_trap /* 3 - Trap Instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .word instruction_trap /* 4 - Unimplemented instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .word handle_illegal /* 5 - Illegal instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .word handle_unaligned /* 6 - Misaligned data access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .word handle_unaligned /* 7 - Misaligned destination address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .word handle_diverror /* 8 - Division error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .word protection_exception_ba /* 9 - Supervisor-only instr. address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .word protection_exception_instr /* 10 - Supervisor only instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .word protection_exception_ba /* 11 - Supervisor only data address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .word unhandled_exception /* 12 - Double TLB miss (data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .word protection_exception_pte /* 13 - TLB permission violation (x) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .word protection_exception_pte /* 14 - TLB permission violation (r) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .word protection_exception_pte /* 15 - TLB permission violation (w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .word unhandled_exception /* 16 - MPU region violation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) trap_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .word handle_system_call /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .word handle_trap_1 /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .word handle_trap_2 /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .word handle_trap_3 /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .word handle_trap_reserved /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .word handle_trap_reserved /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .word handle_trap_reserved /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .word handle_trap_reserved /* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .word handle_trap_reserved /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .word handle_trap_reserved /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .word handle_trap_reserved /* 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .word handle_trap_reserved /* 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .word handle_trap_reserved /* 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .word handle_trap_reserved /* 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .word handle_trap_reserved /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .word handle_trap_reserved /* 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .word handle_trap_reserved /* 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .word handle_trap_reserved /* 17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .word handle_trap_reserved /* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .word handle_trap_reserved /* 19 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .word handle_trap_reserved /* 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .word handle_trap_reserved /* 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .word handle_trap_reserved /* 22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .word handle_trap_reserved /* 23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .word handle_trap_reserved /* 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .word handle_trap_reserved /* 25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .word handle_trap_reserved /* 26 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .word handle_trap_reserved /* 27 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .word handle_trap_reserved /* 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .word handle_trap_reserved /* 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #ifdef CONFIG_KGDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .word instruction_trap /* 30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .word handle_breakpoint /* 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .set nobreak
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ENTRY(inthandler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) SAVE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) kuser_cmpxchg_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Clear EH bit before we get a new excpetion in the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * and after we have saved it to the exception frame. This is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * whether it's trap, tlb-miss or interrupt. If we don't do this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * estatus is not updated the next exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rdctl r24, status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) movi r9, %lo(~STATUS_EH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) and r24, r24, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) wrctl status, r24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Read cause and vector and branch to the associated handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mov r4, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rdctl r5, exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) movia r9, exception_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) add r24, r9, r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ldw r24, 0(r24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) jmp r24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Handle traps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ENTRY(handle_trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ldwio r24, -4(ea) /* instruction that caused the exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) srli r24, r24, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) andi r24, r24, 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) movia r9,trap_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) add r24, r24, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ldw r24, 0(r24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) jmp r24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Handle system calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ENTRY(handle_system_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) rdctl r10, status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ori r10, r10, STATUS_PIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) wrctl status, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Reload registers destroyed by common code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ldw r4, PT_R4(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ldw r5, PT_R5(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) local_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Check that the requested system call is within limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) movui r1, __NR_syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bgeu r2, r1, ret_invsyscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) slli r1, r2, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) movhi r11, %hiadj(sys_call_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) add r1, r1, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ldw r1, %lo(sys_call_table)(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) beq r1, r0, ret_invsyscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Check if we are being traced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) GET_THREAD_INFO r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ldw r11,TI_FLAGS(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) BTBNZ r11,r11,TIF_SYSCALL_TRACE,traced_system_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Execute the system call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) callr r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* If the syscall returns a negative result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Set r7 to 1 to indicate error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Negate r2 to get a positive error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * If the syscall returns zero or a positive value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * Set r7 to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * The sigreturn system calls will skip the code below by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * adding to register ra. To avoid destroying registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) translate_rc_and_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) movi r1, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) bge r2, zero, 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) sub r2, zero, r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) movi r1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) stw r2, PT_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) stw r1, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) end_translate_rc_and_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret_from_exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ldw r1, PT_ESTATUS(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* if so, skip resched, signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) TSTBNZ r1, r1, ESTATUS_EU, Luser_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) restore_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rdctl r10, status /* disable intrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) andi r10, r10, %lo(~STATUS_PIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) wrctl status, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) RESTORE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) eret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* If the syscall number was invalid return ENOSYS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret_invsyscall:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) movi r2, -ENOSYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) br translate_rc_and_ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* This implements the same as above, except it calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * do_syscall_trace_enter and do_syscall_trace_exit before and after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * syscall in order for utilities like strace and gdb to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) traced_system_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) call do_syscall_trace_enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Create system call register arguments. The 5th and 6th
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) arguments on stack are already in place at the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) of pt_regs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ldw r2, PT_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ldw r4, PT_R4(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ldw r5, PT_R5(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ldw r6, PT_R6(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ldw r7, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Fetch the syscall function, we don't need to check the boundaries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * since this is already done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) slli r1, r2, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) movhi r11,%hiadj(sys_call_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) add r1, r1, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ldw r1, %lo(sys_call_table)(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) callr r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* If the syscall returns a negative result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Set r7 to 1 to indicate error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * Negate r2 to get a positive error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * If the syscall returns zero or a positive value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Set r7 to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * The sigreturn system calls will skip the code below by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * adding to register ra. To avoid destroying registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) translate_rc_and_ret2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) movi r1, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) bge r2, zero, 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) sub r2, zero, r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) movi r1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) stw r2, PT_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) stw r1, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) end_translate_rc_and_ret2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) call do_syscall_trace_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) Luser_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) GET_THREAD_INFO r11 /* get thread_info pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ANDI32 r11, r10, _TIF_WORK_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) beq r11, r0, restore_all /* Nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) BTBZ r1, r10, TIF_NEED_RESCHED, Lsignal_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* Reschedule work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) call schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) Lsignal_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ANDI32 r1, r10, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) beq r1, r0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) mov r4, sp /* pt_regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) call do_notify_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) beq r2, r0, no_work_pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* prepare restart syscall here without leaving kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ldw r2, PT_R2(sp) /* reload syscall number in r2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ldw r4, PT_R4(sp) /* reload syscall arguments r4-r9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ldw r5, PT_R5(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ldw r6, PT_R6(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ldw r7, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ldw r8, PT_R8(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ldw r9, PT_R9(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) br local_restart /* restart syscall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) no_work_pending:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Handle external interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * This is the generic interrupt handler (for all hardware interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * sources). It figures out the vector number and calls the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * interrupt service routine directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) external_interrupt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) rdctl r12, ipending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) rdctl r9, ienable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) and r12, r12, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* skip if no interrupt is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) beq r12, r0, ret_from_interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) movi r24, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) stw r24, PT_ORIG_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Process an external hardware interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) addi ea, ea, -4 /* re-issue the interrupted instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) stw ea, PT_EA(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 2: movi r4, %lo(-1) /* Start from bit position 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) highest priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* This is the IRQ # for handler call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 1: andi r10, r12, 1 /* Isolate bit we are interested in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) srli r12, r12, 1 /* shift count is costly without hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) multiplier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) addi r4, r4, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) beq r10, r0, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mov r5, sp /* Setup pt_regs pointer for handler call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) call do_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) rdctl r12, ipending /* check again if irq still pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) rdctl r9, ienable /* Isolate possible interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) and r12, r12, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bne r12, r0, 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* br ret_from_interrupt */ /* fall through to ret_from_interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ENTRY(ret_from_interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ldw r1, PT_ESTATUS(sp) /* check if returning to kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) TSTBNZ r1, r1, ESTATUS_EU, Luser_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #ifdef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) GET_THREAD_INFO r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ldw r4, TI_PREEMPT_COUNT(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) bne r4, r0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ldw r4, TI_FLAGS(r1) /* ? Need resched set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) BTBZ r10, r4, TIF_NEED_RESCHED, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ldw r4, PT_ESTATUS(sp) /* ? Interrupts off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) andi r10, r4, ESTATUS_EPIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) beq r10, r0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) call preempt_schedule_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) br restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * A few syscall wrappers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * int clone(unsigned long clone_flags, unsigned long newsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * int __user * parent_tidptr, int __user * child_tidptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * int tls_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ENTRY(sys_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) subi sp, sp, 4 /* make space for tls pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) stw r8, 0(sp) /* pass tls pointer (r8) via stack (5th argument) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) call nios2_clone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) addi sp, sp, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ENTRY(sys_rt_sigreturn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) mov r4, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) call do_rt_sigreturn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) addi ra, ra, (end_translate_rc_and_ret - translate_rc_and_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * A few other wrappers and stubs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) protection_exception_pte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) rdctl r6, pteaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) slli r6, r6, 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) call do_page_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) protection_exception_ba:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) rdctl r6, badaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) call do_page_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) protection_exception_instr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) call handle_supervisor_instr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) handle_breakpoint:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) call breakpoint_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #ifdef CONFIG_NIOS2_ALIGNMENT_TRAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) handle_unaligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) call handle_unaligned_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) handle_unaligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) call handle_unaligned_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) handle_illegal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) call handle_illegal_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) handle_diverror:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) call handle_diverror_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #ifdef CONFIG_KGDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) handle_kgdb_breakpoint:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) call kgdb_breakpoint_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) handle_trap_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) call handle_trap_1_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) handle_trap_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) call handle_trap_2_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) handle_trap_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) handle_trap_reserved:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) call handle_trap_3_c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Beware - when entering resume, prev (the current task) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * in r4, next (the new task) is in r5, don't change these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ENTRY(resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) rdctl r7, status /* save thread status reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) stw r7, TASK_THREAD + THREAD_KPSR(r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) andi r7, r7, %lo(~STATUS_PIE) /* disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) wrctl status, r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) stw sp, TASK_THREAD + THREAD_KSP(r4)/* save kernel stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ldw sp, TASK_THREAD + THREAD_KSP(r5)/* restore new thread stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) movia r24, _current_thread /* save thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) GET_THREAD_INFO r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) stw r1, 0(r24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ldw r7, TASK_THREAD + THREAD_KPSR(r5)/* restore thread status reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) wrctl status, r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ENTRY(ret_from_fork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) call schedule_tail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ENTRY(ret_from_kernel_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) call schedule_tail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) mov r4,r17 /* arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) callr r16 /* function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) br ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * Kernel user helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * Each segment is 64-byte aligned and will be mapped to the <User space>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * New segments (if ever needed) must be added after the existing ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * This mechanism should be used only for things that are really small and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * justified, and not be abused freely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* Filling pads with undefined instructions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .macro kuser_pad sym size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .if ((. - \sym) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .rept (4 - (. - \sym) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .byte 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .rept ((\size - (. - \sym)) / 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .word 0xdeadbeef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .align 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .globl __kuser_helper_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) __kuser_helper_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) __kuser_helper_version: /* @ 0x1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .word ((__kuser_helper_end - __kuser_helper_start) >> 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) __kuser_cmpxchg: /* @ 0x1004 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * r4 pointer to exchange variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * r5 old value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * r6 new value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) cmpxchg_ldw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ldw r2, 0(r4) /* load current value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sub r2, r2, r5 /* compare with old value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) bne r2, zero, cmpxchg_ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* We had a match, store the new value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) cmpxchg_stw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) stw r6, 0(r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) cmpxchg_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) kuser_pad __kuser_cmpxchg, 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .globl __kuser_sigtramp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) __kuser_sigtramp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) movi r2, __NR_rt_sigreturn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) kuser_pad __kuser_sigtramp, 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .globl __kuser_helper_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) __kuser_helper_end: