| /* | |
| * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | |
| * Copyright (C) 2007-2009 PetaLogix | |
| * Copyright (C) 2006 Atmark Techno, Inc. | |
| * | |
| * This file is subject to the terms and conditions of the GNU General Public | |
| * License. See the file "COPYING" in the main directory of this archive | |
| * for more details. | |
| */ | |
| #include <linux/linkage.h> | |
| #include <asm/thread_info.h> | |
| #include <linux/errno.h> | |
| #include <asm/entry.h> | |
| #include <asm/asm-offsets.h> | |
| #include <asm/registers.h> | |
| #include <asm/unistd.h> | |
| #include <asm/percpu.h> | |
| #include <asm/signal.h> | |
| #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | |
| .macro disable_irq | |
| msrclr r0, MSR_IE | |
| .endm | |
| .macro enable_irq | |
| msrset r0, MSR_IE | |
| .endm | |
| .macro clear_bip | |
| msrclr r0, MSR_BIP | |
| .endm | |
| #else | |
| .macro disable_irq | |
| mfs r11, rmsr | |
| andi r11, r11, ~MSR_IE | |
| mts rmsr, r11 | |
| .endm | |
| .macro enable_irq | |
| mfs r11, rmsr | |
| ori r11, r11, MSR_IE | |
| mts rmsr, r11 | |
| .endm | |
| .macro clear_bip | |
| mfs r11, rmsr | |
| andi r11, r11, ~MSR_BIP | |
| mts rmsr, r11 | |
| .endm | |
| #endif | |
| ENTRY(_interrupt) | |
| swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | |
| swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | |
| lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | |
| beqid r11, 1f | |
| nop | |
| brid 2f /* jump over */ | |
| addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */ | |
| 1: /* switch to kernel stack */ | |
| lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | |
| lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | |
| /* calculate kernel stack pointer */ | |
| addik r1, r1, THREAD_SIZE - PT_SIZE | |
| 2: | |
| swi r11, r1, PT_MODE /* store the mode */ | |
| lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | |
| swi r2, r1, PT_R2 | |
| swi r3, r1, PT_R3 | |
| swi r4, r1, PT_R4 | |
| swi r5, r1, PT_R5 | |
| swi r6, r1, PT_R6 | |
| swi r7, r1, PT_R7 | |
| swi r8, r1, PT_R8 | |
| swi r9, r1, PT_R9 | |
| swi r10, r1, PT_R10 | |
| swi r11, r1, PT_R11 | |
| swi r12, r1, PT_R12 | |
| swi r13, r1, PT_R13 | |
| swi r14, r1, PT_R14 | |
| swi r14, r1, PT_PC | |
| swi r15, r1, PT_R15 | |
| swi r16, r1, PT_R16 | |
| swi r17, r1, PT_R17 | |
| swi r18, r1, PT_R18 | |
| swi r19, r1, PT_R19 | |
| swi r20, r1, PT_R20 | |
| swi r21, r1, PT_R21 | |
| swi r22, r1, PT_R22 | |
| swi r23, r1, PT_R23 | |
| swi r24, r1, PT_R24 | |
| swi r25, r1, PT_R25 | |
| swi r26, r1, PT_R26 | |
| swi r27, r1, PT_R27 | |
| swi r28, r1, PT_R28 | |
| swi r29, r1, PT_R29 | |
| swi r30, r1, PT_R30 | |
| swi r31, r1, PT_R31 | |
| /* special purpose registers */ | |
| mfs r11, rmsr | |
| swi r11, r1, PT_MSR | |
| mfs r11, rear | |
| swi r11, r1, PT_EAR | |
| mfs r11, resr | |
| swi r11, r1, PT_ESR | |
| mfs r11, rfsr | |
| swi r11, r1, PT_FSR | |
| /* reload original stack pointer and save it */ | |
| lwi r11, r0, PER_CPU(ENTRY_SP) | |
| swi r11, r1, PT_R1 | |
| /* update mode indicator we are in kernel mode */ | |
| addik r11, r0, 1 | |
| swi r11, r0, PER_CPU(KM) | |
| /* restore r31 */ | |
| lwi r31, r0, PER_CPU(CURRENT_SAVE) | |
| /* prepare the link register, the argument and jump */ | |
| addik r15, r0, ret_from_intr - 8 | |
| addk r6, r0, r15 | |
| braid do_IRQ | |
| add r5, r0, r1 | |
| ret_from_intr: | |
| lwi r11, r1, PT_MODE | |
| bneid r11, no_intr_resched | |
| 3: | |
| lwi r6, r31, TS_THREAD_INFO /* get thread info */ | |
| lwi r19, r6, TI_FLAGS /* get flags in thread info */ | |
| /* do an extra work if any bits are set */ | |
| andi r11, r19, _TIF_NEED_RESCHED | |
| beqi r11, 1f | |
| bralid r15, schedule | |
| nop | |
| bri 3b | |
| 1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | |
| beqid r11, no_intr_resched | |
| addk r5, r1, r0 | |
| bralid r15, do_notify_resume | |
| addk r6, r0, r0 | |
| bri 3b | |
| no_intr_resched: | |
| /* Disable interrupts, we are now committed to the state restore */ | |
| disable_irq | |
| /* save mode indicator */ | |
| lwi r11, r1, PT_MODE | |
| swi r11, r0, PER_CPU(KM) | |
| /* save r31 */ | |
| swi r31, r0, PER_CPU(CURRENT_SAVE) | |
| restore_context: | |
| /* special purpose registers */ | |
| lwi r11, r1, PT_FSR | |
| mts rfsr, r11 | |
| lwi r11, r1, PT_ESR | |
| mts resr, r11 | |
| lwi r11, r1, PT_EAR | |
| mts rear, r11 | |
| lwi r11, r1, PT_MSR | |
| mts rmsr, r11 | |
| lwi r31, r1, PT_R31 | |
| lwi r30, r1, PT_R30 | |
| lwi r29, r1, PT_R29 | |
| lwi r28, r1, PT_R28 | |
| lwi r27, r1, PT_R27 | |
| lwi r26, r1, PT_R26 | |
| lwi r25, r1, PT_R25 | |
| lwi r24, r1, PT_R24 | |
| lwi r23, r1, PT_R23 | |
| lwi r22, r1, PT_R22 | |
| lwi r21, r1, PT_R21 | |
| lwi r20, r1, PT_R20 | |
| lwi r19, r1, PT_R19 | |
| lwi r18, r1, PT_R18 | |
| lwi r17, r1, PT_R17 | |
| lwi r16, r1, PT_R16 | |
| lwi r15, r1, PT_R15 | |
| lwi r14, r1, PT_PC | |
| lwi r13, r1, PT_R13 | |
| lwi r12, r1, PT_R12 | |
| lwi r11, r1, PT_R11 | |
| lwi r10, r1, PT_R10 | |
| lwi r9, r1, PT_R9 | |
| lwi r8, r1, PT_R8 | |
| lwi r7, r1, PT_R7 | |
| lwi r6, r1, PT_R6 | |
| lwi r5, r1, PT_R5 | |
| lwi r4, r1, PT_R4 | |
| lwi r3, r1, PT_R3 | |
| lwi r2, r1, PT_R2 | |
| lwi r1, r1, PT_R1 | |
| rtid r14, 0 | |
| nop | |
| ENTRY(_reset) | |
| brai 0; | |
| ENTRY(_user_exception) | |
| swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | |
| swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | |
| lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | |
| beqid r11, 1f /* Already in kernel mode? */ | |
| nop | |
| brid 2f /* jump over */ | |
| addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */ | |
| 1: /* Switch to kernel stack */ | |
| lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | |
| lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | |
| /* calculate kernel stack pointer */ | |
| addik r1, r1, THREAD_SIZE - PT_SIZE | |
| 2: | |
| swi r11, r1, PT_MODE /* store the mode */ | |
| lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | |
| /* save them on stack */ | |
| swi r2, r1, PT_R2 | |
| swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | |
| swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | |
| swi r5, r1, PT_R5 | |
| swi r6, r1, PT_R6 | |
| swi r7, r1, PT_R7 | |
| swi r8, r1, PT_R8 | |
| swi r9, r1, PT_R9 | |
| swi r10, r1, PT_R10 | |
| swi r11, r1, PT_R11 | |
| /* r12: _always_ in clobber list; see unistd.h */ | |
| swi r12, r1, PT_R12 | |
| swi r13, r1, PT_R13 | |
| /* r14: _always_ in clobber list; see unistd.h */ | |
| swi r14, r1, PT_R14 | |
| /* but we want to return to the next inst. */ | |
| addik r14, r14, 0x4 | |
| swi r14, r1, PT_PC /* increment by 4 and store in pc */ | |
| swi r15, r1, PT_R15 | |
| swi r16, r1, PT_R16 | |
| swi r17, r1, PT_R17 | |
| swi r18, r1, PT_R18 | |
| swi r19, r1, PT_R19 | |
| swi r20, r1, PT_R20 | |
| swi r21, r1, PT_R21 | |
| swi r22, r1, PT_R22 | |
| swi r23, r1, PT_R23 | |
| swi r24, r1, PT_R24 | |
| swi r25, r1, PT_R25 | |
| swi r26, r1, PT_R26 | |
| swi r27, r1, PT_R27 | |
| swi r28, r1, PT_R28 | |
| swi r29, r1, PT_R29 | |
| swi r30, r1, PT_R30 | |
| swi r31, r1, PT_R31 | |
| disable_irq | |
| nop /* make sure IE bit is in effect */ | |
| clear_bip /* once IE is in effect it is safe to clear BIP */ | |
| nop | |
| /* special purpose registers */ | |
| mfs r11, rmsr | |
| swi r11, r1, PT_MSR | |
| mfs r11, rear | |
| swi r11, r1, PT_EAR | |
| mfs r11, resr | |
| swi r11, r1, PT_ESR | |
| mfs r11, rfsr | |
| swi r11, r1, PT_FSR | |
| /* reload original stack pointer and save it */ | |
| lwi r11, r0, PER_CPU(ENTRY_SP) | |
| swi r11, r1, PT_R1 | |
| /* update mode indicator we are in kernel mode */ | |
| addik r11, r0, 1 | |
| swi r11, r0, PER_CPU(KM) | |
| /* restore r31 */ | |
| lwi r31, r0, PER_CPU(CURRENT_SAVE) | |
| /* re-enable interrupts now we are in kernel mode */ | |
| enable_irq | |
| /* See if the system call number is valid. */ | |
| addi r11, r12, -__NR_syscalls | |
| bgei r11, 1f /* return to user if not valid */ | |
| /* Figure out which function to use for this system call. */ | |
| /* Note Microblaze barrel shift is optional, so don't rely on it */ | |
| add r12, r12, r12 /* convert num -> ptr */ | |
| addik r30, r0, 1 /* restarts allowed */ | |
| add r12, r12, r12 | |
| lwi r12, r12, sys_call_table /* Get function pointer */ | |
| addik r15, r0, ret_to_user-8 /* set return address */ | |
| bra r12 /* Make the system call. */ | |
| bri 0 /* won't reach here */ | |
| 1: | |
| brid ret_to_user /* jump to syscall epilogue */ | |
| addi r3, r0, -ENOSYS /* set errno in delay slot */ | |
| /* | |
| * Debug traps are like a system call, but entered via brki r14, 0x60 | |
| * All we need to do is send the SIGTRAP signal to current, ptrace and | |
| * do_notify_resume will handle the rest | |
| */ | |
| ENTRY(_debug_exception) | |
| swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | |
| lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | |
| lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | |
| addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */ | |
| swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | |
| lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | |
| //save_context: | |
| swi r11, r1, PT_MODE /* store the mode */ | |
| lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | |
| /* save them on stack */ | |
| swi r2, r1, PT_R2 | |
| swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | |
| swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | |
| swi r5, r1, PT_R5 | |
| swi r6, r1, PT_R6 | |
| swi r7, r1, PT_R7 | |
| swi r8, r1, PT_R8 | |
| swi r9, r1, PT_R9 | |
| swi r10, r1, PT_R10 | |
| swi r11, r1, PT_R11 | |
| /* r12: _always_ in clobber list; see unistd.h */ | |
| swi r12, r1, PT_R12 | |
| swi r13, r1, PT_R13 | |
| /* r14: _always_ in clobber list; see unistd.h */ | |
| swi r14, r1, PT_R14 | |
| swi r14, r1, PT_PC /* Will return to interrupted instruction */ | |
| swi r15, r1, PT_R15 | |
| swi r16, r1, PT_R16 | |
| swi r17, r1, PT_R17 | |
| swi r18, r1, PT_R18 | |
| swi r19, r1, PT_R19 | |
| swi r20, r1, PT_R20 | |
| swi r21, r1, PT_R21 | |
| swi r22, r1, PT_R22 | |
| swi r23, r1, PT_R23 | |
| swi r24, r1, PT_R24 | |
| swi r25, r1, PT_R25 | |
| swi r26, r1, PT_R26 | |
| swi r27, r1, PT_R27 | |
| swi r28, r1, PT_R28 | |
| swi r29, r1, PT_R29 | |
| swi r30, r1, PT_R30 | |
| swi r31, r1, PT_R31 | |
| disable_irq | |
| nop /* make sure IE bit is in effect */ | |
| clear_bip /* once IE is in effect it is safe to clear BIP */ | |
| nop | |
| /* special purpose registers */ | |
| mfs r11, rmsr | |
| swi r11, r1, PT_MSR | |
| mfs r11, rear | |
| swi r11, r1, PT_EAR | |
| mfs r11, resr | |
| swi r11, r1, PT_ESR | |
| mfs r11, rfsr | |
| swi r11, r1, PT_FSR | |
| /* reload original stack pointer and save it */ | |
| lwi r11, r0, PER_CPU(ENTRY_SP) | |
| swi r11, r1, PT_R1 | |
| /* update mode indicator we are in kernel mode */ | |
| addik r11, r0, 1 | |
| swi r11, r0, PER_CPU(KM) | |
| /* restore r31 */ | |
| lwi r31, r0, PER_CPU(CURRENT_SAVE) | |
| /* re-enable interrupts now we are in kernel mode */ | |
| enable_irq | |
| addi r5, r0, SIGTRAP /* sending the trap signal */ | |
| add r6, r0, r31 /* to current */ | |
| bralid r15, send_sig | |
| add r7, r0, r0 /* 3rd param zero */ | |
| addik r30, r0, 1 /* restarts allowed ??? */ | |
| /* Restore r3/r4 to work around how ret_to_user works */ | |
| lwi r3, r1, PT_R3 | |
| lwi r4, r1, PT_R4 | |
| bri ret_to_user | |
| ENTRY(_break) | |
| bri 0 | |
| /* struct task_struct *_switch_to(struct thread_info *prev, | |
| struct thread_info *next); */ | |
| ENTRY(_switch_to) | |
| /* prepare return value */ | |
| addk r3, r0, r31 | |
| /* save registers in cpu_context */ | |
| /* use r11 and r12, volatile registers, as temp register */ | |
| addik r11, r5, TI_CPU_CONTEXT | |
| swi r1, r11, CC_R1 | |
| swi r2, r11, CC_R2 | |
| /* skip volatile registers. | |
| * they are saved on stack when we jumped to _switch_to() */ | |
| /* dedicated registers */ | |
| swi r13, r11, CC_R13 | |
| swi r14, r11, CC_R14 | |
| swi r15, r11, CC_R15 | |
| swi r16, r11, CC_R16 | |
| swi r17, r11, CC_R17 | |
| swi r18, r11, CC_R18 | |
| /* save non-volatile registers */ | |
| swi r19, r11, CC_R19 | |
| swi r20, r11, CC_R20 | |
| swi r21, r11, CC_R21 | |
| swi r22, r11, CC_R22 | |
| swi r23, r11, CC_R23 | |
| swi r24, r11, CC_R24 | |
| swi r25, r11, CC_R25 | |
| swi r26, r11, CC_R26 | |
| swi r27, r11, CC_R27 | |
| swi r28, r11, CC_R28 | |
| swi r29, r11, CC_R29 | |
| swi r30, r11, CC_R30 | |
| /* special purpose registers */ | |
| mfs r12, rmsr | |
| swi r12, r11, CC_MSR | |
| mfs r12, rear | |
| swi r12, r11, CC_EAR | |
| mfs r12, resr | |
| swi r12, r11, CC_ESR | |
| mfs r12, rfsr | |
| swi r12, r11, CC_FSR | |
| /* update r31, the current */ | |
| lwi r31, r6, TI_TASK | |
| swi r31, r0, PER_CPU(CURRENT_SAVE) | |
| /* get new process' cpu context and restore */ | |
| addik r11, r6, TI_CPU_CONTEXT | |
| /* special purpose registers */ | |
| lwi r12, r11, CC_FSR | |
| mts rfsr, r12 | |
| lwi r12, r11, CC_ESR | |
| mts resr, r12 | |
| lwi r12, r11, CC_EAR | |
| mts rear, r12 | |
| lwi r12, r11, CC_MSR | |
| mts rmsr, r12 | |
| /* non-volatile registers */ | |
| lwi r30, r11, CC_R30 | |
| lwi r29, r11, CC_R29 | |
| lwi r28, r11, CC_R28 | |
| lwi r27, r11, CC_R27 | |
| lwi r26, r11, CC_R26 | |
| lwi r25, r11, CC_R25 | |
| lwi r24, r11, CC_R24 | |
| lwi r23, r11, CC_R23 | |
| lwi r22, r11, CC_R22 | |
| lwi r21, r11, CC_R21 | |
| lwi r20, r11, CC_R20 | |
| lwi r19, r11, CC_R19 | |
| /* dedicated registers */ | |
| lwi r18, r11, CC_R18 | |
| lwi r17, r11, CC_R17 | |
| lwi r16, r11, CC_R16 | |
| lwi r15, r11, CC_R15 | |
| lwi r14, r11, CC_R14 | |
| lwi r13, r11, CC_R13 | |
| /* skip volatile registers */ | |
| lwi r2, r11, CC_R2 | |
| lwi r1, r11, CC_R1 | |
| rtsd r15, 8 | |
| nop | |
| ENTRY(ret_from_fork) | |
| addk r5, r0, r3 | |
| brlid r15, schedule_tail | |
| nop | |
| swi r31, r1, PT_R31 /* save r31 in user context. */ | |
| /* will soon be restored to r31 in ret_to_user */ | |
| addk r3, r0, r0 | |
| brid ret_to_user | |
| nop | |
| ENTRY(ret_from_kernel_thread) | |
| brlid r15, schedule_tail | |
| addk r5, r0, r3 | |
| brald r15, r20 | |
| addk r5, r0, r19 | |
| brid ret_to_user | |
| addk r3, r0, r0 | |
| work_pending: | |
| lwi r11, r1, PT_MODE | |
| bneid r11, 2f | |
| 3: | |
| enable_irq | |
| andi r11, r19, _TIF_NEED_RESCHED | |
| beqi r11, 1f | |
| bralid r15, schedule | |
| nop | |
| bri 4f | |
| 1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | |
| beqi r11, no_work_pending | |
| addk r5, r30, r0 | |
| bralid r15, do_notify_resume | |
| addik r6, r0, 1 | |
| addk r30, r0, r0 /* no restarts from now on */ | |
| 4: | |
| disable_irq | |
| lwi r6, r31, TS_THREAD_INFO /* get thread info */ | |
| lwi r19, r6, TI_FLAGS /* get flags in thread info */ | |
| bri 3b | |
| ENTRY(ret_to_user) | |
| disable_irq | |
| swi r4, r1, PT_R4 /* return val */ | |
| swi r3, r1, PT_R3 /* return val */ | |
| lwi r6, r31, TS_THREAD_INFO /* get thread info */ | |
| lwi r19, r6, TI_FLAGS /* get flags in thread info */ | |
| bnei r19, work_pending /* do an extra work if any bits are set */ | |
| no_work_pending: | |
| disable_irq | |
| 2: | |
| /* save r31 */ | |
| swi r31, r0, PER_CPU(CURRENT_SAVE) | |
| /* save mode indicator */ | |
| lwi r18, r1, PT_MODE | |
| swi r18, r0, PER_CPU(KM) | |
| //restore_context: | |
| /* special purpose registers */ | |
| lwi r18, r1, PT_FSR | |
| mts rfsr, r18 | |
| lwi r18, r1, PT_ESR | |
| mts resr, r18 | |
| lwi r18, r1, PT_EAR | |
| mts rear, r18 | |
| lwi r18, r1, PT_MSR | |
| mts rmsr, r18 | |
| lwi r31, r1, PT_R31 | |
| lwi r30, r1, PT_R30 | |
| lwi r29, r1, PT_R29 | |
| lwi r28, r1, PT_R28 | |
| lwi r27, r1, PT_R27 | |
| lwi r26, r1, PT_R26 | |
| lwi r25, r1, PT_R25 | |
| lwi r24, r1, PT_R24 | |
| lwi r23, r1, PT_R23 | |
| lwi r22, r1, PT_R22 | |
| lwi r21, r1, PT_R21 | |
| lwi r20, r1, PT_R20 | |
| lwi r19, r1, PT_R19 | |
| lwi r18, r1, PT_R18 | |
| lwi r17, r1, PT_R17 | |
| lwi r16, r1, PT_R16 | |
| lwi r15, r1, PT_R15 | |
| lwi r14, r1, PT_PC | |
| lwi r13, r1, PT_R13 | |
| lwi r12, r1, PT_R12 | |
| lwi r11, r1, PT_R11 | |
| lwi r10, r1, PT_R10 | |
| lwi r9, r1, PT_R9 | |
| lwi r8, r1, PT_R8 | |
| lwi r7, r1, PT_R7 | |
| lwi r6, r1, PT_R6 | |
| lwi r5, r1, PT_R5 | |
| lwi r4, r1, PT_R4 /* return val */ | |
| lwi r3, r1, PT_R3 /* return val */ | |
| lwi r2, r1, PT_R2 | |
| lwi r1, r1, PT_R1 | |
| rtid r14, 0 | |
| nop | |
| sys_rt_sigreturn_wrapper: | |
| addk r30, r0, r0 /* no restarts for this one */ | |
| brid sys_rt_sigreturn | |
| addk r5, r1, r0 | |
| /* Interrupt vector table */ | |
| .section .init.ivt, "ax" | |
| .org 0x0 | |
| brai _reset | |
| brai _user_exception | |
| brai _interrupt | |
| brai _break | |
| brai _hw_exception_handler | |
| .org 0x60 | |
| brai _debug_exception | |
| .section .rodata,"a" | |
| #include "syscall_table.S" | |
| syscall_table_size=(.-sys_call_table) | |
| type_SYSCALL: | |
| .ascii "SYSCALL\0" | |
| type_IRQ: | |
| .ascii "IRQ\0" | |
| type_IRQ_PREEMPT: | |
| .ascii "IRQ (PREEMPTED)\0" | |
| type_SYSCALL_PREEMPT: | |
| .ascii " SYSCALL (PREEMPTED)\0" | |
| /* | |
| * Trap decoding for stack unwinder | |
| * Tuples are (start addr, end addr, string) | |
| * If return address lies on [start addr, end addr], | |
| * unwinder displays 'string' | |
| */ | |
| .align 4 | |
| .global microblaze_trap_handlers | |
| microblaze_trap_handlers: | |
| /* Exact matches come first */ | |
| .word ret_to_user ; .word ret_to_user ; .word type_SYSCALL | |
| .word ret_from_intr; .word ret_from_intr ; .word type_IRQ | |
| /* Fuzzy matches go here */ | |
| .word ret_from_intr; .word no_intr_resched; .word type_IRQ_PREEMPT | |
| .word work_pending ; .word no_work_pending; .word type_SYSCALL_PREEMPT | |
| /* End of table */ | |
| .word 0 ; .word 0 ; .word 0 |