/* * 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. * * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2002, 2007 Maciej W. Rozycki * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. */#include <linux/init.h> #include <asm/asm.h>#include <asm/asmmacro.h>#include <asm/cacheops.h>#include <asm/irqflags.h>#include <asm/regdef.h>#include <asm/fpregdef.h>#include <asm/mipsregs.h>#include <asm/stackframe.h>#include <asm/sync.h>#include <asm/thread_info.h> __INIT /* * General exception vector for all other CPUs. * * Be careful when changing this, it has to be at most 128 bytes * to fit into space reserved for the exception handler. */NESTED(except_vec3_generic, 0, sp) .set push .set noat mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c#ifdef CONFIG_64BIT dsll k1, k1, 1#endif PTR_L k0, exception_handlers(k1) jr k0 .set pop END(except_vec3_generic) /* * General exception handler for CPUs with virtual coherency exception. * * Be careful when changing this, it has to be at most 256 (as a special * exception) bytes to fit into space reserved for the exception handler. */NESTED(except_vec3_r4000, 0, sp) .set push .set arch=r4000 .set noat mfc0 k1, CP0_CAUSE li k0, 31<<2 andi k1, k1, 0x7c .set push .set noreorder .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei#ifdef CONFIG_64BIT dsll k1, k1, 1#endif .set pop PTR_L k0, exception_handlers(k1) jr k0 /* * Big shit, we now may have two dirty primary cache lines for the same * physical address. We can safely invalidate the line pointed to by * c0_badvaddr because after return from this exception handler the * load / store will be re-executed. */handle_vced: MFC0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D, (k0) cache Hit_Writeback_Inv_SD, (k0)#ifdef CONFIG_PROC_FS PTR_LA k0, vced_count lw k1, (k0) addiu k1, 1 sw k1, (k0)#endif eret handle_vcei: MFC0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD, (k0) # also cleans pi#ifdef CONFIG_PROC_FS PTR_LA k0, vcei_count lw k1, (k0) addiu k1, 1 sw k1, (k0)#endif eret .set pop END(except_vec3_r4000) __FINIT .section .cpuidle.text,"ax" /* Align to 32 bytes for the maximum idle interrupt region size. */ .align 5LEAF(r4k_wait) /* Keep the ISA bit clear for calculations on local labels here. */0: .fill 0 /* Start of idle interrupt region. */ local_irq_enable /* * If an interrupt lands here, before going idle on the next * instruction, we must *NOT* go idle since the interrupt could * have set TIF_NEED_RESCHED or caused a timer to need resched. * Fall through -- see skipover_handler below -- and have the * idle loop take care of things. */1: .fill 0 /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */ .if 1b - 0b > 32 .error "overlong idle interrupt region" .elseif 1b - 0b > 8 .align 4 .endif2: .fill 0 .equ r4k_wait_idle_size, 2b - 0b /* End of idle interrupt region; size has to be a power of 2. */ .set MIPS_ISA_ARCH_LEVEL_RAWr4k_wait_insn: waitr4k_wait_exit: .set mips0 local_irq_disable jr ra END(r4k_wait) .previous .macro BUILD_SKIPOVER_PROLOGUE handler FEXPORT(skipover_\handler) .set push .set noat MFC0 k0, CP0_EPC /* Subtract/add 2 to let the ISA bit propagate through the mask. */ PTR_LA k1, r4k_wait_insn - 2 ori k0, r4k_wait_idle_size - 2 .set noreorder bne k0, k1, \handler PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 .set reorder MTC0 k0, CP0_EPC .set pop .endm .align 5BUILD_SKIPOVER_PROLOGUE handle_intNESTED(handle_int, PT_SIZE, sp) .cfi_signal_frame#ifdef CONFIG_TRACE_IRQFLAGS /* * Check to see if the interrupted code has just disabled * interrupts and ignore this interrupt for now if so. * * local_irq_disable() disables interrupts and then calls * trace_hardirqs_off() to track the state. If an interrupt is taken * after interrupts are disabled but before the state is updated * it will appear to restore_all that it is incorrectly returning with * interrupts disabled */ .set push .set noat mfc0 k0, CP0_STATUS#if defined(CONFIG_CPU_R3000) and k0, ST0_IEP bnez k0, 1f mfc0 k0, CP0_EPC .set noreorder j k0 rfe#else and k0, ST0_IE bnez k0, 1f eret#endif1: .set pop#endif SAVE_ALL docfi=1 CLI TRACE_IRQS_OFF LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) /* * SAVE_ALL ensures we are using a valid kernel stack for the thread. * Check if we are already using the IRQ stack. */ move s1, sp # Preserve the sp /* Get IRQ stack for this CPU */ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(irq_stack)#else lui k1, %highest(irq_stack) daddiu k1, %higher(irq_stack) dsll k1, 16 daddiu k1, %hi(irq_stack) dsll k1, 16#endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 LONG_L t0, %lo(irq_stack)(k1) # Check if already on IRQ stack PTR_LI t1, ~(_THREAD_SIZE-1) and t1, t1, sp beq t0, t1, 2f /* Switch to IRQ stack */ li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 /* Save task's sp on IRQ stack so that unwinding can follow it */ LONG_S s1, 0(sp)2: jal plat_irq_dispatch /* Restore sp */ move sp, s1 j ret_from_irq#ifdef CONFIG_CPU_MICROMIPS nop#endif END(handle_int) __INIT /* * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. * This is a dedicated interrupt exception vector which reduces the * interrupt processing overhead. The jump instruction will be replaced * at the initialization time. * * Be careful when changing this, it has to be at most 128 bytes * to fit into space reserved for the exception handler. */NESTED(except_vec4, 0, sp)1: j 1b /* Dummy, will be replaced */ END(except_vec4) /* * EJTAG debug exception handler. * The EJTAG debug exception entry point is 0xbfc00480, which * normally is in the boot PROM, so the boot PROM must do an * unconditional jump to this vector. */NESTED(except_vec_ejtag_debug, 0, sp) j ejtag_debug_handler#ifdef CONFIG_CPU_MICROMIPS nop#endif END(except_vec_ejtag_debug) __FINIT /* * Vectored interrupt handler. * This prototype is copied to ebase + n*IntCtl.VS and patched * to invoke the handler */BUILD_SKIPOVER_PROLOGUE except_vec_viNESTED(except_vec_vi, 0, sp) SAVE_SOME docfi=1 SAVE_AT docfi=1 .set push .set noreorder PTR_LA v1, except_vec_vi_handler jr v1FEXPORT(except_vec_vi_ori) ori v0, zero, 0 /* Offset in vi_handlers[] */ .set pop END(except_vec_vi)EXPORT(except_vec_vi_end) /* * Common Vectored Interrupt code * Complete the register saves and invoke the handler, $v0 holds * offset into vi_handlers[] */NESTED(except_vec_vi_handler, 0, sp) SAVE_TEMP SAVE_STATIC CLI#ifdef CONFIG_TRACE_IRQFLAGS move s0, v0 TRACE_IRQS_OFF move v0, s0#endif LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) /* * SAVE_ALL ensures we are using a valid kernel stack for the thread. * Check if we are already using the IRQ stack. */ move s1, sp # Preserve the sp /* Get IRQ stack for this CPU */ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(irq_stack)#else lui k1, %highest(irq_stack) daddiu k1, %higher(irq_stack) dsll k1, 16 daddiu k1, %hi(irq_stack) dsll k1, 16#endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 LONG_L t0, %lo(irq_stack)(k1) # Check if already on IRQ stack PTR_LI t1, ~(_THREAD_SIZE-1) and t1, t1, sp beq t0, t1, 2f /* Switch to IRQ stack */ li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 /* Save task's sp on IRQ stack so that unwinding can follow it */ LONG_S s1, 0(sp)2: PTR_L v0, vi_handlers(v0) jalr v0 /* Restore sp */ move sp, s1 j ret_from_irq END(except_vec_vi_handler) /* * EJTAG debug exception handler. */NESTED(ejtag_debug_handler, PT_SIZE, sp) .set push .set noat MTC0 k0, CP0_DESAVE mfc0 k0, CP0_DEBUG andi k0, k0, MIPS_DEBUG_DBP # Check for SDBBP. beqz k0, ejtag_return #ifdef CONFIG_SMP1: PTR_LA k0, ejtag_debug_buffer_spinlock __SYNC(full, loongson3_war)2: ll k0, 0(k0) bnez k0, 2b PTR_LA k0, ejtag_debug_buffer_spinlock sc k0, 0(k0) beqz k0, 1b# ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC sync# endif PTR_LA k0, ejtag_debug_buffer LONG_S k1, 0(k0) ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG PTR_SRL k1, SMP_CPUID_PTRSHIFT PTR_SLL k1, LONGLOG PTR_LA k0, ejtag_debug_buffer_per_cpu PTR_ADDU k0, k1 PTR_LA k1, ejtag_debug_buffer LONG_L k1, 0(k1) LONG_S k1, 0(k0) PTR_LA k0, ejtag_debug_buffer_spinlock sw zero, 0(k0)#else PTR_LA k0, ejtag_debug_buffer LONG_S k1, 0(k0)#endif SAVE_ALL move a0, sp jal ejtag_exception_handler RESTORE_ALL #ifdef CONFIG_SMP ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG PTR_SRL k1, SMP_CPUID_PTRSHIFT PTR_SLL k1, LONGLOG PTR_LA k0, ejtag_debug_buffer_per_cpu PTR_ADDU k0, k1 LONG_L k1, 0(k0)#else PTR_LA k0, ejtag_debug_buffer LONG_L k1, 0(k0)#endif ejtag_return: back_to_back_c0_hazard MFC0 k0, CP0_DESAVE .set mips32 deret .set pop END(ejtag_debug_handler) /* * This buffer is reserved for the use of the EJTAG debug * handler. */ .dataEXPORT(ejtag_debug_buffer) .fill LONGSIZE#ifdef CONFIG_SMPEXPORT(ejtag_debug_buffer_spinlock) .fill LONGSIZEEXPORT(ejtag_debug_buffer_per_cpu) .fill LONGSIZE * NR_CPUS#endif .previous __INIT /* * NMI debug exception handler for MIPS reference boards. * The NMI debug exception entry point is 0xbfc00000, which * normally is in the boot PROM, so the boot PROM must do a * unconditional jump to this vector. */NESTED(except_vec_nmi, 0, sp) j nmi_handler#ifdef CONFIG_CPU_MICROMIPS nop#endif END(except_vec_nmi) __FINIT NESTED(nmi_handler, PT_SIZE, sp) .cfi_signal_frame .set push .set noat /* * Clear ERL - restore segment mapping * Clear BEV - required for page fault exception handler to work */ mfc0 k0, CP0_STATUS ori k0, k0, ST0_EXL li k1, ~(ST0_BEV | ST0_ERL) and k0, k0, k1 mtc0 k0, CP0_STATUS _ehb SAVE_ALL move a0, sp jal nmi_exception_handler /* nmi_exception_handler never returns */ .set pop END(nmi_handler) .macro __build_clear_none .endm .macro __build_clear_sti TRACE_IRQS_ON STI .endm .macro __build_clear_cli CLI TRACE_IRQS_OFF .endm .macro __build_clear_fpe CLI TRACE_IRQS_OFF .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 .set hardfloat cfc1 a1, fcr31 .set pop .endm .macro __build_clear_msa_fpe CLILines 1–500 of 692. Load more
/* * 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. * * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2002, 2007 Maciej W. Rozycki * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. */ #include <linux/init.h> #include <asm/asm.h> #include <asm/asmmacro.h> #include <asm/cacheops.h> #include <asm/irqflags.h> #include <asm/regdef.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/stackframe.h> #include <asm/sync.h> #include <asm/thread_info.h> __INIT /* * General exception vector for all other CPUs. * * Be careful when changing this, it has to be at most 128 bytes * to fit into space reserved for the exception handler. */ NESTED(except_vec3_generic, 0, sp) .set push .set noat mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c #ifdef CONFIG_64BIT dsll k1, k1, 1 #endif PTR_L k0, exception_handlers(k1) jr k0 .set pop END(except_vec3_generic) /* * General exception handler for CPUs with virtual coherency exception. * * Be careful when changing this, it has to be at most 256 (as a special * exception) bytes to fit into space reserved for the exception handler. */ NESTED(except_vec3_r4000, 0, sp) .set push .set arch=r4000 .set noat mfc0 k1, CP0_CAUSE li k0, 31<<2 andi k1, k1, 0x7c .set push .set noreorder .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei #ifdef CONFIG_64BIT dsll k1, k1, 1 #endif .set pop PTR_L k0, exception_handlers(k1) jr k0 /* * Big shit, we now may have two dirty primary cache lines for the same * physical address. We can safely invalidate the line pointed to by * c0_badvaddr because after return from this exception handler the * load / store will be re-executed. */ handle_vced: MFC0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D, (k0) cache Hit_Writeback_Inv_SD, (k0) #ifdef CONFIG_PROC_FS PTR_LA k0, vced_count lw k1, (k0) addiu k1, 1 sw k1, (k0) #endif eret handle_vcei: MFC0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD, (k0) # also cleans pi #ifdef CONFIG_PROC_FS PTR_LA k0, vcei_count lw k1, (k0) addiu k1, 1 sw k1, (k0) #endif eret .set pop END(except_vec3_r4000) __FINIT .section .cpuidle.text,"ax" /* Align to 32 bytes for the maximum idle interrupt region size. */ .align 5 LEAF(r4k_wait) /* Keep the ISA bit clear for calculations on local labels here. */ 0: .fill 0 /* Start of idle interrupt region. */ local_irq_enable /* * If an interrupt lands here, before going idle on the next * instruction, we must *NOT* go idle since the interrupt could * have set TIF_NEED_RESCHED or caused a timer to need resched. * Fall through -- see skipover_handler below -- and have the * idle loop take care of things. */ 1: .fill 0 /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */ .if 1b - 0b > 32 .error "overlong idle interrupt region" .elseif 1b - 0b > 8 .align 4 .endif 2: .fill 0 .equ r4k_wait_idle_size, 2b - 0b /* End of idle interrupt region; size has to be a power of 2. */ .set MIPS_ISA_ARCH_LEVEL_RAW r4k_wait_insn: wait r4k_wait_exit: .set mips0 local_irq_disable jr ra END(r4k_wait) .previous .macro BUILD_SKIPOVER_PROLOGUE handler FEXPORT(skipover_\handler) .set push .set noat MFC0 k0, CP0_EPC /* Subtract/add 2 to let the ISA bit propagate through the mask. */ PTR_LA k1, r4k_wait_insn - 2 ori k0, r4k_wait_idle_size - 2 .set noreorder bne k0, k1, \handler PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 .set reorder MTC0 k0, CP0_EPC .set pop .endm .align 5 BUILD_SKIPOVER_PROLOGUE handle_int NESTED(handle_int, PT_SIZE, sp) .cfi_signal_frame #ifdef CONFIG_TRACE_IRQFLAGS /* * Check to see if the interrupted code has just disabled * interrupts and ignore this interrupt for now if so. * * local_irq_disable() disables interrupts and then calls * trace_hardirqs_off() to track the state. If an interrupt is taken * after interrupts are disabled but before the state is updated * it will appear to restore_all that it is incorrectly returning with * interrupts disabled */ .set push .set noat mfc0 k0, CP0_STATUS #if defined(CONFIG_CPU_R3000) and k0, ST0_IEP bnez k0, 1f mfc0 k0, CP0_EPC .set noreorder j k0 rfe #else and k0, ST0_IE bnez k0, 1f eret #endif 1: .set pop #endif SAVE_ALL docfi=1 CLI TRACE_IRQS_OFF LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) /* * SAVE_ALL ensures we are using a valid kernel stack for the thread. * Check if we are already using the IRQ stack. */ move s1, sp # Preserve the sp /* Get IRQ stack for this CPU */ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(irq_stack) #else lui k1, %highest(irq_stack) daddiu k1, %higher(irq_stack) dsll k1, 16 daddiu k1, %hi(irq_stack) dsll k1, 16 #endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 LONG_L t0, %lo(irq_stack)(k1) # Check if already on IRQ stack PTR_LI t1, ~(_THREAD_SIZE-1) and t1, t1, sp beq t0, t1, 2f /* Switch to IRQ stack */ li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 /* Save task's sp on IRQ stack so that unwinding can follow it */ LONG_S s1, 0(sp) 2: jal plat_irq_dispatch /* Restore sp */ move sp, s1 j ret_from_irq #ifdef CONFIG_CPU_MICROMIPS nop #endif END(handle_int) __INIT /* * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. * This is a dedicated interrupt exception vector which reduces the * interrupt processing overhead. The jump instruction will be replaced * at the initialization time. * * Be careful when changing this, it has to be at most 128 bytes * to fit into space reserved for the exception handler. */ NESTED(except_vec4, 0, sp) 1: j 1b /* Dummy, will be replaced */ END(except_vec4) /* * EJTAG debug exception handler. * The EJTAG debug exception entry point is 0xbfc00480, which * normally is in the boot PROM, so the boot PROM must do an * unconditional jump to this vector. */ NESTED(except_vec_ejtag_debug, 0, sp) j ejtag_debug_handler #ifdef CONFIG_CPU_MICROMIPS nop #endif END(except_vec_ejtag_debug) __FINIT /* * Vectored interrupt handler. * This prototype is copied to ebase + n*IntCtl.VS and patched * to invoke the handler */ BUILD_SKIPOVER_PROLOGUE except_vec_vi NESTED(except_vec_vi, 0, sp) SAVE_SOME docfi=1 SAVE_AT docfi=1 .set push .set noreorder PTR_LA v1, except_vec_vi_handler jr v1 FEXPORT(except_vec_vi_ori) ori v0, zero, 0 /* Offset in vi_handlers[] */ .set pop END(except_vec_vi) EXPORT(except_vec_vi_end) /* * Common Vectored Interrupt code * Complete the register saves and invoke the handler, $v0 holds * offset into vi_handlers[] */ NESTED(except_vec_vi_handler, 0, sp) SAVE_TEMP SAVE_STATIC CLI #ifdef CONFIG_TRACE_IRQFLAGS move s0, v0 TRACE_IRQS_OFF move v0, s0 #endif LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) /* * SAVE_ALL ensures we are using a valid kernel stack for the thread. * Check if we are already using the IRQ stack. */ move s1, sp # Preserve the sp /* Get IRQ stack for this CPU */ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(irq_stack) #else lui k1, %highest(irq_stack) daddiu k1, %higher(irq_stack) dsll k1, 16 daddiu k1, %hi(irq_stack) dsll k1, 16 #endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 LONG_L t0, %lo(irq_stack)(k1) # Check if already on IRQ stack PTR_LI t1, ~(_THREAD_SIZE-1) and t1, t1, sp beq t0, t1, 2f /* Switch to IRQ stack */ li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 /* Save task's sp on IRQ stack so that unwinding can follow it */ LONG_S s1, 0(sp) 2: PTR_L v0, vi_handlers(v0) jalr v0 /* Restore sp */ move sp, s1 j ret_from_irq END(except_vec_vi_handler) /* * EJTAG debug exception handler. */ NESTED(ejtag_debug_handler, PT_SIZE, sp) .set push .set noat MTC0 k0, CP0_DESAVE mfc0 k0, CP0_DEBUG andi k0, k0, MIPS_DEBUG_DBP # Check for SDBBP. beqz k0, ejtag_return #ifdef CONFIG_SMP 1: PTR_LA k0, ejtag_debug_buffer_spinlock __SYNC(full, loongson3_war) 2: ll k0, 0(k0) bnez k0, 2b PTR_LA k0, ejtag_debug_buffer_spinlock sc k0, 0(k0) beqz k0, 1b # ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC sync # endif PTR_LA k0, ejtag_debug_buffer LONG_S k1, 0(k0) ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG PTR_SRL k1, SMP_CPUID_PTRSHIFT PTR_SLL k1, LONGLOG PTR_LA k0, ejtag_debug_buffer_per_cpu PTR_ADDU k0, k1 PTR_LA k1, ejtag_debug_buffer LONG_L k1, 0(k1) LONG_S k1, 0(k0) PTR_LA k0, ejtag_debug_buffer_spinlock sw zero, 0(k0) #else PTR_LA k0, ejtag_debug_buffer LONG_S k1, 0(k0) #endif SAVE_ALL move a0, sp jal ejtag_exception_handler RESTORE_ALL #ifdef CONFIG_SMP ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG PTR_SRL k1, SMP_CPUID_PTRSHIFT PTR_SLL k1, LONGLOG PTR_LA k0, ejtag_debug_buffer_per_cpu PTR_ADDU k0, k1 LONG_L k1, 0(k0) #else PTR_LA k0, ejtag_debug_buffer LONG_L k1, 0(k0) #endif ejtag_return: back_to_back_c0_hazard MFC0 k0, CP0_DESAVE .set mips32 deret .set pop END(ejtag_debug_handler) /* * This buffer is reserved for the use of the EJTAG debug * handler. */ .data EXPORT(ejtag_debug_buffer) .fill LONGSIZE #ifdef CONFIG_SMP EXPORT(ejtag_debug_buffer_spinlock) .fill LONGSIZE EXPORT(ejtag_debug_buffer_per_cpu) .fill LONGSIZE * NR_CPUS #endif .previous __INIT /* * NMI debug exception handler for MIPS reference boards. * The NMI debug exception entry point is 0xbfc00000, which * normally is in the boot PROM, so the boot PROM must do a * unconditional jump to this vector. */ NESTED(except_vec_nmi, 0, sp) j nmi_handler #ifdef CONFIG_CPU_MICROMIPS nop #endif END(except_vec_nmi) __FINIT NESTED(nmi_handler, PT_SIZE, sp) .cfi_signal_frame .set push .set noat /* * Clear ERL - restore segment mapping * Clear BEV - required for page fault exception handler to work */ mfc0 k0, CP0_STATUS ori k0, k0, ST0_EXL li k1, ~(ST0_BEV | ST0_ERL) and k0, k0, k1 mtc0 k0, CP0_STATUS _ehb SAVE_ALL move a0, sp jal nmi_exception_handler /* nmi_exception_handler never returns */ .set pop END(nmi_handler) .macro __build_clear_none .endm .macro __build_clear_sti TRACE_IRQS_ON STI .endm .macro __build_clear_cli CLI TRACE_IRQS_OFF .endm .macro __build_clear_fpe CLI TRACE_IRQS_OFF .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 .set hardfloat cfc1 a1, fcr31 .set pop .endm .macro __build_clear_msa_fpe CLI