1 /* 1 /* 2 * linux/arch/nios2/kernel/entry.S << 3 * << 4 * Copyright (C) 2013-2014 Altera Corporation << 5 * Copyright (C) 2009, Wind River Systems Inc << 6 * << 7 * Implemented by fredrik.markstrom@gmail.com << 8 * << 9 * Copyright (C) 1999-2002, Greg Ungerer (ger << 10 * Copyright (C) 1998 D. Jeff Dionne <jeff@li << 11 * Kenneth Albanowski <kja << 12 * Copyright (C) 2000 Lineo Inc. (www.lineo. << 13 * Copyright (C) 2004 Microtronix Datacom Lt << 14 * << 15 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 16 * License. See the file "COPYING" in the mai 3 * License. See the file "COPYING" in the main directory of this archive 17 * for more details. 4 * for more details. 18 * 5 * 19 * Linux/m68k support by Hamish Macdonald !! 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle 20 * !! 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 21 * 68060 fixes by Jesper Skov !! 8 * Copyright (C) 2001 MIPS Technologies, Inc. 22 * ColdFire support by Greg Ungerer (gerg@snap << 23 * 5307 fixes by David W. Miller << 24 * linux 2.4 support David McCullough <davidm@s << 25 */ 9 */ 26 10 27 #include <linux/sys.h> !! 11 #include <asm/asm.h> 28 #include <linux/linkage.h> !! 12 #include <asm/asmmacro.h> 29 #include <asm/asm-offsets.h> !! 13 #include <asm/compiler.h> 30 #include <asm/asm-macros.h> !! 14 #include <asm/irqflags.h> >> 15 #include <asm/regdef.h> >> 16 #include <asm/mipsregs.h> >> 17 #include <asm/stackframe.h> >> 18 #include <asm/isadep.h> 31 #include <asm/thread_info.h> 19 #include <asm/thread_info.h> 32 #include <asm/errno.h> !! 20 33 #include <asm/setup.h> !! 21 #ifndef CONFIG_PREEMPTION 34 #include <asm/entry.h> !! 22 #define resume_kernel restore_all 35 #include <asm/unistd.h> << 36 #include <asm/processor.h> << 37 << 38 .macro GET_THREAD_INFO reg << 39 .if THREAD_SIZE & 0xffff0000 << 40 andhi \reg, sp, %hi(~(THREAD_SIZE-1) << 41 .else << 42 addi \reg, r0, %lo(~(THREAD_SIZE-1) << 43 and \reg, \reg, sp << 44 .endif << 45 .endm << 46 << 47 .macro kuser_cmpxchg_check << 48 /* << 49 * Make sure our user space atomic hel << 50 * interrupted in a critical region. << 51 * ea-4 = address of interrupted insn << 52 * sp = saved regs. << 53 * cmpxchg_ldw = first critical insn, << 54 * If ea <= cmpxchg_stw and ea > cmpxc << 55 * cmpxchg_ldw + 4. << 56 */ << 57 /* et = cmpxchg_stw + 4 */ << 58 movui et, (KUSER_BASE + 4 + (cmpxchg << 59 bgtu ea, et, 1f << 60 << 61 subi et, et, (cmpxchg_stw - cmpxchg << 62 bltu ea, et, 1f << 63 stw et, PT_EA(sp) /* fix up EA * << 64 mov ea, et << 65 1: << 66 .endm << 67 << 68 .section .rodata << 69 .align 4 << 70 exception_table: << 71 .word unhandled_exception /* 0 - << 72 .word unhandled_exception /* 1 - << 73 .word external_interrupt /* 2 - << 74 .word handle_trap /* 3 - << 75 << 76 .word instruction_trap /* 4 - << 77 .word handle_illegal /* 5 - << 78 .word handle_unaligned /* 6 - << 79 .word handle_unaligned /* 7 - << 80 << 81 .word handle_diverror /* 8 - << 82 .word protection_exception_ba /* 9 - << 83 .word protection_exception_instr /* 10 << 84 .word protection_exception_ba /* 11 << 85 << 86 .word unhandled_exception /* 12 << 87 .word protection_exception_pte /* 13 << 88 .word protection_exception_pte /* 14 << 89 .word protection_exception_pte /* 15 << 90 << 91 .word unhandled_exception /* 16 << 92 << 93 trap_table: << 94 .word handle_system_call /* 0 << 95 .word handle_trap_1 /* 1 << 96 .word handle_trap_2 /* 2 << 97 .word handle_trap_3 /* 3 << 98 .word handle_trap_reserved /* 4 << 99 .word handle_trap_reserved /* 5 << 100 .word handle_trap_reserved /* 6 << 101 .word handle_trap_reserved /* 7 << 102 .word handle_trap_reserved /* 8 << 103 .word handle_trap_reserved /* 9 << 104 .word handle_trap_reserved /* 10 << 105 .word handle_trap_reserved /* 11 << 106 .word handle_trap_reserved /* 12 << 107 .word handle_trap_reserved /* 13 << 108 .word handle_trap_reserved /* 14 << 109 .word handle_trap_reserved /* 15 << 110 .word handle_trap_reserved /* 16 << 111 .word handle_trap_reserved /* 17 << 112 .word handle_trap_reserved /* 18 << 113 .word handle_trap_reserved /* 19 << 114 .word handle_trap_reserved /* 20 << 115 .word handle_trap_reserved /* 21 << 116 .word handle_trap_reserved /* 22 << 117 .word handle_trap_reserved /* 23 << 118 .word handle_trap_reserved /* 24 << 119 .word handle_trap_reserved /* 25 << 120 .word handle_trap_reserved /* 26 << 121 .word handle_trap_reserved /* 27 << 122 .word handle_trap_reserved /* 28 << 123 .word handle_trap_reserved /* 29 << 124 #ifdef CONFIG_KGDB << 125 .word handle_kgdb_breakpoint /* 30 << 126 #else 23 #else 127 .word instruction_trap !! 24 #define __ret_from_irq ret_from_exception 128 #endif 25 #endif 129 .word handle_breakpoint /* 31 << 130 << 131 .text << 132 .set noat << 133 .set nobreak << 134 << 135 ENTRY(inthandler) << 136 SAVE_ALL << 137 << 138 kuser_cmpxchg_check << 139 << 140 /* Clear EH bit before we get a new ex << 141 * and after we have saved it to the e << 142 * whether it's trap, tlb-miss or inte << 143 * estatus is not updated the next exc << 144 */ << 145 rdctl r24, status << 146 movi r9, %lo(~STATUS_EH) << 147 and r24, r24, r9 << 148 wrctl status, r24 << 149 << 150 /* Read cause and vector and branch to << 151 mov r4, sp << 152 rdctl r5, exception << 153 movia r9, exception_table << 154 add r24, r9, r5 << 155 ldw r24, 0(r24) << 156 jmp r24 << 157 << 158 << 159 /********************************************* << 160 * Handle traps << 161 ********************************************* << 162 */ << 163 ENTRY(handle_trap) << 164 ldwio r24, -4(ea) /* instruction << 165 srli r24, r24, 4 << 166 andi r24, r24, 0x7c << 167 movia r9,trap_table << 168 add r24, r24, r9 << 169 ldw r24, 0(r24) << 170 jmp r24 << 171 << 172 26 173 /********************************************* !! 27 .text 174 * Handle system calls !! 28 .align 5 175 ********************************************* !! 29 #ifndef CONFIG_PREEMPTION 176 */ !! 30 FEXPORT(ret_from_exception) 177 ENTRY(handle_system_call) !! 31 local_irq_disable # preempt stop 178 /* Enable interrupts */ !! 32 b __ret_from_irq 179 rdctl r10, status !! 33 #endif 180 ori r10, r10, STATUS_PIE !! 34 FEXPORT(ret_from_irq) 181 wrctl status, r10 !! 35 LONG_S s0, TI_REGS($28) 182 !! 36 FEXPORT(__ret_from_irq) 183 /* Reload registers destroyed by commo << 184 ldw r4, PT_R4(sp) << 185 ldw r5, PT_R5(sp) << 186 << 187 local_restart: << 188 stw r2, PT_ORIG_R2(sp) << 189 /* Check that the requested system cal << 190 movui r1, __NR_syscalls << 191 bgeu r2, r1, ret_invsyscall << 192 slli r1, r2, 2 << 193 movhi r11, %hiadj(sys_call_table) << 194 add r1, r1, r11 << 195 ldw r1, %lo(sys_call_table)(r1) << 196 << 197 /* Check if we are being traced */ << 198 GET_THREAD_INFO r11 << 199 ldw r11,TI_FLAGS(r11) << 200 BTBNZ r11,r11,TIF_SYSCALL_TRACE,trac << 201 << 202 /* Execute the system call */ << 203 callr r1 << 204 << 205 /* If the syscall returns a negative r << 206 * Set r7 to 1 to indicate error, << 207 * Negate r2 to get a positive error << 208 * If the syscall returns zero or a po << 209 * Set r7 to 0. << 210 * The sigreturn system calls will ski << 211 * adding to register ra. To avoid des << 212 */ << 213 translate_rc_and_ret: << 214 movi r1, 0 << 215 bge r2, zero, 3f << 216 ldw r1, PT_ORIG_R2(sp) << 217 addi r1, r1, 1 << 218 beq r1, zero, 3f << 219 sub r2, zero, r2 << 220 movi r1, 1 << 221 3: << 222 stw r2, PT_R2(sp) << 223 stw r1, PT_R7(sp) << 224 end_translate_rc_and_ret: << 225 << 226 ret_from_exception: << 227 ldw r1, PT_ESTATUS(sp) << 228 /* if so, skip resched, signals */ << 229 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu << 230 << 231 restore_all: << 232 rdctl r10, status << 233 andi r10, r10, %lo(~STATUS_PIE) << 234 wrctl status, r10 << 235 RESTORE_ALL << 236 eret << 237 << 238 /* If the syscall number was invalid r << 239 ret_invsyscall: << 240 movi r2, -ENOSYS << 241 br translate_rc_and_ret << 242 << 243 /* This implements the same as above, << 244 * do_syscall_trace_enter and do_sysca << 245 * syscall in order for utilities like << 246 */ << 247 traced_system_call: << 248 SAVE_SWITCH_STACK << 249 call do_syscall_trace_enter << 250 RESTORE_SWITCH_STACK << 251 << 252 /* Create system call register argumen << 253 arguments on stack are already in p << 254 of pt_regs. */ << 255 ldw r2, PT_R2(sp) << 256 ldw r4, PT_R4(sp) << 257 ldw r5, PT_R5(sp) << 258 ldw r6, PT_R6(sp) << 259 ldw r7, PT_R7(sp) << 260 << 261 /* Fetch the syscall function. */ << 262 movui r1, __NR_syscalls << 263 bgeu r2, r1, traced_invsyscall << 264 slli r1, r2, 2 << 265 movhi r11,%hiadj(sys_call_table) << 266 add r1, r1, r11 << 267 ldw r1, %lo(sys_call_table)(r1) << 268 << 269 callr r1 << 270 << 271 /* If the syscall returns a negative r << 272 * Set r7 to 1 to indicate error, << 273 * Negate r2 to get a positive error << 274 * If the syscall returns zero or a po << 275 * Set r7 to 0. << 276 * The sigreturn system calls will ski << 277 * adding to register ra. To avoid des << 278 */ << 279 translate_rc_and_ret2: << 280 movi r1, 0 << 281 bge r2, zero, 4f << 282 ldw r1, PT_ORIG_R2(sp) << 283 addi r1, r1, 1 << 284 beq r1, zero, 4f << 285 sub r2, zero, r2 << 286 movi r1, 1 << 287 4: << 288 stw r2, PT_R2(sp) << 289 stw r1, PT_R7(sp) << 290 end_translate_rc_and_ret2: << 291 SAVE_SWITCH_STACK << 292 call do_syscall_trace_exit << 293 RESTORE_SWITCH_STACK << 294 br ret_from_exception << 295 << 296 /* If the syscall number was invalid r << 297 traced_invsyscall: << 298 movi r2, -ENOSYS << 299 br translate_rc_and_ret2 << 300 << 301 Luser_return: << 302 GET_THREAD_INFO r11 << 303 ldw r10, TI_FLAGS(r11) << 304 ANDI32 r11, r10, _TIF_WORK_MASK << 305 beq r11, r0, restore_all << 306 BTBZ r1, r10, TIF_NEED_RESCHED, Lsi << 307 << 308 /* Reschedule work */ << 309 call schedule << 310 br ret_from_exception << 311 << 312 Lsignal_return: << 313 ANDI32 r1, r10, _TIF_SIGPENDING | _TI << 314 beq r1, r0, restore_all << 315 mov r4, sp /* pt_ << 316 SAVE_SWITCH_STACK << 317 call do_notify_resume << 318 beq r2, r0, no_work_pending << 319 RESTORE_SWITCH_STACK << 320 /* prepare restart syscall here withou << 321 ldw r2, PT_R2(sp) /* reload sysc << 322 ldw r4, PT_R4(sp) /* reload sysc << 323 ldw r5, PT_R5(sp) << 324 ldw r6, PT_R6(sp) << 325 ldw r7, PT_R7(sp) << 326 ldw r8, PT_R8(sp) << 327 ldw r9, PT_R9(sp) << 328 br local_restart /* restart sys << 329 << 330 no_work_pending: << 331 RESTORE_SWITCH_STACK << 332 br ret_from_exception << 333 << 334 /********************************************* << 335 * Handle external interrupts. << 336 ********************************************* << 337 */ << 338 /* 37 /* 339 * This is the generic interrupt handler (for !! 38 * We can be coming here from a syscall done in the kernel space, 340 * sources). It figures out the vector number !! 39 * e.g. a failed kernel_execve(). 341 * interrupt service routine directly. << 342 */ 40 */ 343 external_interrupt: !! 41 resume_userspace_check: 344 rdctl r12, ipending !! 42 LONG_L t0, PT_STATUS(sp) # returning to kernel mode? 345 rdctl r9, ienable !! 43 andi t0, t0, KU_USER 346 and r12, r12, r9 !! 44 beqz t0, resume_kernel 347 /* skip if no interrupt is pending */ !! 45 348 beq r12, r0, ret_from_interrupt !! 46 resume_userspace: 349 !! 47 local_irq_disable # make sure we dont miss an 350 /* !! 48 # interrupt setting need_resched 351 * Process an external hardware interr !! 49 # between sampling and return 352 */ !! 50 LONG_L a2, TI_FLAGS($28) # current->work 353 !! 51 andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) 354 addi ea, ea, -4 /* re-issue th !! 52 bnez t0, work_pending 355 stw ea, PT_EA(sp) !! 53 j restore_all 356 2: movi r4, %lo(-1) /* Start from << 357 highes << 358 /* This is the << 359 1: andi r10, r12, 1 /* Isolate bit << 360 srli r12, r12, 1 /* shift count << 361 multip << 362 addi r4, r4, 1 << 363 beq r10, r0, 1b << 364 mov r5, sp /* Setup pt_re << 365 call do_IRQ << 366 rdctl r12, ipending /* check again << 367 rdctl r9, ienable /* Isolate pos << 368 and r12, r12, r9 << 369 bne r12, r0, 2b << 370 /* br ret_from_interrupt */ /* fall << 371 << 372 ENTRY(ret_from_interrupt) << 373 ldw r1, PT_ESTATUS(sp) /* che << 374 TSTBNZ r1, r1, ESTATUS_EU, Luser_retu << 375 54 376 #ifdef CONFIG_PREEMPTION 55 #ifdef CONFIG_PREEMPTION 377 GET_THREAD_INFO r1 !! 56 resume_kernel: 378 ldw r4, TI_PREEMPT_COUNT(r1) !! 57 local_irq_disable 379 bne r4, r0, restore_all !! 58 lw t0, TI_PRE_COUNT($28) 380 ldw r4, TI_FLAGS(r1) !! 59 bnez t0, restore_all 381 BTBZ r10, r4, TIF_NEED_RESCHED, res !! 60 LONG_L t0, TI_FLAGS($28) 382 ldw r4, PT_ESTATUS(sp) /* ? I !! 61 andi t1, t0, _TIF_NEED_RESCHED 383 andi r10, r4, ESTATUS_EPIE !! 62 beqz t1, restore_all 384 beq r10, r0, restore_all !! 63 LONG_L t0, PT_STATUS(sp) # Interrupts off? 385 call preempt_schedule_irq !! 64 andi t0, 1 >> 65 beqz t0, restore_all >> 66 PTR_LA ra, restore_all >> 67 j preempt_schedule_irq 386 #endif 68 #endif 387 br restore_all << 388 69 389 /********************************************* !! 70 FEXPORT(ret_from_kernel_thread) 390 * A few syscall wrappers !! 71 jal schedule_tail # a0 = struct task_struct *prev 391 ********************************************* !! 72 move a0, s1 392 */ !! 73 jal s0 393 /* !! 74 j syscall_exit 394 * int clone(unsigned long clone_flags, unsign !! 75 395 * int __user * parent_tidptr, in !! 76 FEXPORT(ret_from_fork) 396 * int tls_val) !! 77 jal schedule_tail # a0 = struct task_struct *prev 397 */ !! 78 398 ENTRY(sys_clone) !! 79 FEXPORT(syscall_exit) 399 SAVE_SWITCH_STACK !! 80 #ifdef CONFIG_DEBUG_RSEQ 400 subi sp, sp, 4 /* make space for tl !! 81 move a0, sp 401 stw r8, 0(sp) /* pass tls pointer !! 82 jal rseq_syscall 402 call nios2_clone !! 83 #endif 403 addi sp, sp, 4 !! 84 local_irq_disable # make sure need_resched and 404 RESTORE_SWITCH_STACK !! 85 # signals dont change between 405 ret !! 86 # sampling and return 406 !! 87 LONG_L a2, TI_FLAGS($28) # current->work 407 ENTRY(sys_rt_sigreturn) !! 88 li t0, _TIF_ALLWORK_MASK 408 SAVE_SWITCH_STACK !! 89 and t0, a2, t0 409 mov r4, sp !! 90 bnez t0, syscall_exit_work 410 call do_rt_sigreturn !! 91 411 RESTORE_SWITCH_STACK !! 92 restore_all: # restore full frame 412 addi ra, ra, (end_translate_rc_and_ !! 93 .set noat 413 ret !! 94 RESTORE_TEMP 414 !! 95 RESTORE_AT 415 /********************************************* !! 96 RESTORE_STATIC 416 * A few other wrappers and stubs !! 97 restore_partial: # restore partial frame 417 ********************************************* !! 98 #ifdef CONFIG_TRACE_IRQFLAGS 418 */ !! 99 SAVE_STATIC 419 protection_exception_pte: !! 100 SAVE_AT 420 rdctl r6, pteaddr !! 101 SAVE_TEMP 421 slli r6, r6, 10 !! 102 LONG_L v0, PT_STATUS(sp) 422 call do_page_fault !! 103 #if defined(CONFIG_CPU_R3000) 423 br ret_from_exception !! 104 and v0, ST0_IEP 424 << 425 protection_exception_ba: << 426 rdctl r6, badaddr << 427 call do_page_fault << 428 br ret_from_exception << 429 << 430 protection_exception_instr: << 431 call handle_supervisor_instr << 432 br ret_from_exception << 433 << 434 handle_breakpoint: << 435 call breakpoint_c << 436 br ret_from_exception << 437 << 438 #ifdef CONFIG_NIOS2_ALIGNMENT_TRAP << 439 handle_unaligned: << 440 SAVE_SWITCH_STACK << 441 call handle_unaligned_c << 442 RESTORE_SWITCH_STACK << 443 br ret_from_exception << 444 #else 105 #else 445 handle_unaligned: !! 106 and v0, ST0_IE 446 call handle_unaligned_c << 447 br ret_from_exception << 448 #endif 107 #endif 449 !! 108 beqz v0, 1f 450 handle_illegal: !! 109 jal trace_hardirqs_on 451 call handle_illegal_c !! 110 b 2f 452 br ret_from_exception !! 111 1: jal trace_hardirqs_off 453 !! 112 2: 454 handle_diverror: !! 113 RESTORE_TEMP 455 call handle_diverror_c !! 114 RESTORE_AT 456 br ret_from_exception !! 115 RESTORE_STATIC 457 << 458 #ifdef CONFIG_KGDB << 459 handle_kgdb_breakpoint: << 460 call kgdb_breakpoint_c << 461 br ret_from_exception << 462 #endif 116 #endif >> 117 RESTORE_SOME >> 118 RESTORE_SP_AND_RET >> 119 .set at >> 120 >> 121 work_pending: >> 122 andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS >> 123 beqz t0, work_notifysig >> 124 work_resched: >> 125 TRACE_IRQS_OFF >> 126 jal schedule >> 127 >> 128 local_irq_disable # make sure need_resched and >> 129 # signals dont change between >> 130 # sampling and return >> 131 LONG_L a2, TI_FLAGS($28) >> 132 andi t0, a2, _TIF_WORK_MASK # is there any work to be done >> 133 # other than syscall tracing? >> 134 beqz t0, restore_all >> 135 andi t0, a2, _TIF_NEED_RESCHED >> 136 bnez t0, work_resched >> 137 >> 138 work_notifysig: # deal with pending signals and >> 139 # notify-resume requests >> 140 move a0, sp >> 141 li a1, 0 >> 142 jal do_notify_resume # a2 already loaded >> 143 j resume_userspace_check >> 144 >> 145 FEXPORT(syscall_exit_partial) >> 146 #ifdef CONFIG_DEBUG_RSEQ >> 147 move a0, sp >> 148 jal rseq_syscall >> 149 #endif >> 150 local_irq_disable # make sure need_resched doesn't >> 151 # change between and return >> 152 LONG_L a2, TI_FLAGS($28) # current->work >> 153 li t0, _TIF_ALLWORK_MASK >> 154 and t0, a2 >> 155 beqz t0, restore_partial >> 156 SAVE_STATIC >> 157 syscall_exit_work: >> 158 LONG_L t0, PT_STATUS(sp) # returning to kernel mode? >> 159 andi t0, t0, KU_USER >> 160 beqz t0, resume_kernel >> 161 li t0, _TIF_WORK_SYSCALL_EXIT >> 162 and t0, a2 # a2 is preloaded with TI_FLAGS >> 163 beqz t0, work_pending # trace bit set? >> 164 local_irq_enable # could let syscall_trace_leave() >> 165 # call schedule() instead >> 166 TRACE_IRQS_ON >> 167 move a0, sp >> 168 jal syscall_trace_leave >> 169 b resume_userspace 463 170 464 handle_trap_1: !! 171 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \ 465 call handle_trap_1_c !! 172 defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_MIPS_MT) 466 br ret_from_exception << 467 << 468 handle_trap_2: << 469 call handle_trap_2_c << 470 br ret_from_exception << 471 << 472 handle_trap_3: << 473 handle_trap_reserved: << 474 call handle_trap_3_c << 475 br ret_from_exception << 476 << 477 /* << 478 * Beware - when entering resume, prev (the cu << 479 * in r4, next (the new task) is in r5, don't << 480 * registers. << 481 */ << 482 ENTRY(resume) << 483 << 484 rdctl r7, status << 485 stw r7, TASK_THREAD + THREAD_KPSR( << 486 << 487 andi r7, r7, %lo(~STATUS_PIE) << 488 wrctl status, r7 << 489 << 490 SAVE_SWITCH_STACK << 491 stw sp, TASK_THREAD + THREAD_KSP(r << 492 ldw sp, TASK_THREAD + THREAD_KSP(r << 493 movia r24, _current_thread << 494 GET_THREAD_INFO r1 << 495 stw r1, 0(r24) << 496 RESTORE_SWITCH_STACK << 497 << 498 ldw r7, TASK_THREAD + THREAD_KPSR( << 499 wrctl status, r7 << 500 ret << 501 << 502 ENTRY(ret_from_fork) << 503 call schedule_tail << 504 br ret_from_exception << 505 << 506 ENTRY(ret_from_kernel_thread) << 507 call schedule_tail << 508 mov r4,r17 /* arg */ << 509 callr r16 /* function */ << 510 br ret_from_exception << 511 173 512 /* 174 /* 513 * Kernel user helpers. !! 175 * MIPS32R2 Instruction Hazard Barrier - must be called 514 * << 515 * Each segment is 64-byte aligned and will be << 516 * New segments (if ever needed) must be added << 517 * This mechanism should be used only for thin << 518 * justified, and not be abused freely. << 519 * 176 * >> 177 * For C code use the inline version named instruction_hazard(). 520 */ 178 */ >> 179 LEAF(mips_ihb) >> 180 .set MIPS_ISA_LEVEL_RAW >> 181 jr.hb ra >> 182 nop >> 183 END(mips_ihb) 521 184 522 /* Filling pads with undefined instructions. !! 185 #endif /* CONFIG_CPU_MIPSR2 - CONFIG_CPU_MIPSR6 or CONFIG_MIPS_MT */ 523 .macro kuser_pad sym size << 524 .if ((. - \sym) & 3) << 525 .rept (4 - (. - \sym) & 3) << 526 .byte 0 << 527 .endr << 528 .endif << 529 .rept ((\size - (. - \sym)) / 4) << 530 .word 0xdeadbeef << 531 .endr << 532 .endm << 533 << 534 .align 6 << 535 .globl __kuser_helper_start << 536 __kuser_helper_start: << 537 << 538 __kuser_helper_version: << 539 .word ((__kuser_helper_end - __kuser << 540 << 541 __kuser_cmpxchg: << 542 /* << 543 * r4 pointer to exchange variable << 544 * r5 old value << 545 * r6 new value << 546 */ << 547 cmpxchg_ldw: << 548 ldw r2, 0(r4) << 549 sub r2, r2, r5 << 550 bne r2, zero, cmpxchg_ret << 551 << 552 /* We had a match, store the new value << 553 cmpxchg_stw: << 554 stw r6, 0(r4) << 555 cmpxchg_ret: << 556 ret << 557 << 558 kuser_pad __kuser_cmpxchg, 64 << 559 << 560 .globl __kuser_sigtramp << 561 __kuser_sigtramp: << 562 movi r2, __NR_rt_sigreturn << 563 trap << 564 << 565 kuser_pad __kuser_sigtramp, 64 << 566 << 567 .globl __kuser_helper_end << 568 __kuser_helper_end: <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.