^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2002, 2007 Maciej W. Rozycki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/cacheops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/regdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/fpregdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/stackframe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/sync.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/war.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * General exception vector for all other CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Be careful when changing this, it has to be at most 128 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * to fit into space reserved for the exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) NESTED(except_vec3_generic, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) mfc0 k1, CP0_CAUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) andi k1, k1, 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dsll k1, k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) PTR_L k0, exception_handlers(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) jr k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) END(except_vec3_generic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * General exception handler for CPUs with virtual coherency exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Be careful when changing this, it has to be at most 256 (as a special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * exception) bytes to fit into space reserved for the exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) NESTED(except_vec3_r4000, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .set arch=r4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) mfc0 k1, CP0_CAUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) li k0, 31<<2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) andi k1, k1, 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .set nomacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) beq k1, k0, handle_vced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) li k0, 14<<2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) beq k1, k0, handle_vcei
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) dsll k1, k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) PTR_L k0, exception_handlers(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) jr k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Big shit, we now may have two dirty primary cache lines for the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * physical address. We can safely invalidate the line pointed to by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * c0_badvaddr because after return from this exception handler the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * load / store will be re-executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) handle_vced:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MFC0 k0, CP0_BADVADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) li k1, -4 # Is this ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) and k0, k1 # ... really needed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mtc0 zero, CP0_TAGLO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) cache Index_Store_Tag_D, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) cache Hit_Writeback_Inv_SD, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) PTR_LA k0, vced_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) lw k1, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) addiu k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) sw k1, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) eret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) handle_vcei:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MFC0 k0, CP0_BADVADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) cache Hit_Writeback_Inv_SD, (k0) # also cleans pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) PTR_LA k0, vcei_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) lw k1, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) addiu k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) sw k1, (k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) eret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) END(except_vec3_r4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) __FINIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .align 5 /* 32 byte rollback region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) LEAF(__r4k_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* start of rollback region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) LONG_L t0, TI_FLAGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) andi t0, _TIF_NEED_RESCHED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bnez t0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .set MIPS_ISA_ARCH_LEVEL_RAW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* end of rollback region (the region size must be power of two) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) jr ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) END(__r4k_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .macro BUILD_ROLLBACK_PROLOGUE handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) FEXPORT(rollback_\handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) MFC0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) PTR_LA k1, __r4k_wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ori k0, 0x1f /* 32 byte rollback region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) xori k0, 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bne k0, k1, \handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) MTC0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) BUILD_ROLLBACK_PROLOGUE handle_int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) NESTED(handle_int, PT_SIZE, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .cfi_signal_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #ifdef CONFIG_TRACE_IRQFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Check to see if the interrupted code has just disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * interrupts and ignore this interrupt for now if so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * local_irq_disable() disables interrupts and then calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * trace_hardirqs_off() to track the state. If an interrupt is taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * after interrupts are disabled but before the state is updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * it will appear to restore_all that it is incorrectly returning with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * interrupts disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mfc0 k0, CP0_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) and k0, ST0_IEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bnez k0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) mfc0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) j k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) and k0, ST0_IE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) bnez k0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) eret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) SAVE_ALL docfi=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) CLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) LONG_L s0, TI_REGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) LONG_S sp, TI_REGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * SAVE_ALL ensures we are using a valid kernel stack for the thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Check if we are already using the IRQ stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) move s1, sp # Preserve the sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Get IRQ stack for this CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) lui k1, %hi(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) lui k1, %highest(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) daddiu k1, %higher(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dsll k1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) daddiu k1, %hi(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dsll k1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) LONG_SRL k0, SMP_CPUID_PTRSHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) LONG_ADDU k1, k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) LONG_L t0, %lo(irq_stack)(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) # Check if already on IRQ stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) PTR_LI t1, ~(_THREAD_SIZE-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) and t1, t1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) beq t0, t1, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Switch to IRQ stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) li t1, _IRQ_STACK_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) PTR_ADD sp, t0, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Save task's sp on IRQ stack so that unwinding can follow it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) LONG_S s1, 0(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) jal plat_irq_dispatch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Restore sp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) move sp, s1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) j ret_from_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) END(handle_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) __INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * This is a dedicated interrupt exception vector which reduces the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * interrupt processing overhead. The jump instruction will be replaced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * at the initialization time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * Be careful when changing this, it has to be at most 128 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * to fit into space reserved for the exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) NESTED(except_vec4, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 1: j 1b /* Dummy, will be replaced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) END(except_vec4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * EJTAG debug exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * The EJTAG debug exception entry point is 0xbfc00480, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * normally is in the boot PROM, so the boot PROM must do an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * unconditional jump to this vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) NESTED(except_vec_ejtag_debug, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) j ejtag_debug_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) END(except_vec_ejtag_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) __FINIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Vectored interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * This prototype is copied to ebase + n*IntCtl.VS and patched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * to invoke the handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) BUILD_ROLLBACK_PROLOGUE except_vec_vi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) NESTED(except_vec_vi, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) SAVE_SOME docfi=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) SAVE_AT docfi=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) PTR_LA v1, except_vec_vi_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) FEXPORT(except_vec_vi_lui)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) lui v0, 0 /* Patched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) jr v1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) FEXPORT(except_vec_vi_ori)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ori v0, 0 /* Patched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) END(except_vec_vi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) EXPORT(except_vec_vi_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Common Vectored Interrupt code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Complete the register saves and invoke the handler which is passed in $v0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) NESTED(except_vec_vi_handler, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) SAVE_TEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) SAVE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) CLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #ifdef CONFIG_TRACE_IRQFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) move s0, v0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) move v0, s0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) LONG_L s0, TI_REGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) LONG_S sp, TI_REGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * SAVE_ALL ensures we are using a valid kernel stack for the thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * Check if we are already using the IRQ stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) move s1, sp # Preserve the sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Get IRQ stack for this CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lui k1, %hi(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) lui k1, %highest(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) daddiu k1, %higher(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dsll k1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) daddiu k1, %hi(irq_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dsll k1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) LONG_SRL k0, SMP_CPUID_PTRSHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) LONG_ADDU k1, k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) LONG_L t0, %lo(irq_stack)(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) # Check if already on IRQ stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) PTR_LI t1, ~(_THREAD_SIZE-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) and t1, t1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) beq t0, t1, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Switch to IRQ stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) li t1, _IRQ_STACK_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) PTR_ADD sp, t0, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Save task's sp on IRQ stack so that unwinding can follow it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) LONG_S s1, 0(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) jalr v0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Restore sp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) move sp, s1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) j ret_from_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) END(except_vec_vi_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * EJTAG debug exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) NESTED(ejtag_debug_handler, PT_SIZE, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) MTC0 k0, CP0_DESAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mfc0 k0, CP0_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) sll k0, k0, 30 # Check for SDBBP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) bgez k0, ejtag_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 1: PTR_LA k0, ejtag_debug_buffer_spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) __SYNC(full, loongson3_war)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 2: ll k0, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) bnez k0, 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) PTR_LA k0, ejtag_debug_buffer_spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) sc k0, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) beqz k0, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) # ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) PTR_LA k0, ejtag_debug_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) LONG_S k1, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) PTR_SRL k1, SMP_CPUID_PTRSHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) PTR_SLL k1, LONGLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) PTR_LA k0, ejtag_debug_buffer_per_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) PTR_ADDU k0, k1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) PTR_LA k1, ejtag_debug_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) LONG_L k1, 0(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) LONG_S k1, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) PTR_LA k0, ejtag_debug_buffer_spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sw zero, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) PTR_LA k0, ejtag_debug_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) LONG_S k1, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) SAVE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) jal ejtag_exception_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) RESTORE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) PTR_SRL k1, SMP_CPUID_PTRSHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) PTR_SLL k1, LONGLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) PTR_LA k0, ejtag_debug_buffer_per_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) PTR_ADDU k0, k1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) LONG_L k1, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) PTR_LA k0, ejtag_debug_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) LONG_L k1, 0(k0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ejtag_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) back_to_back_c0_hazard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) MFC0 k0, CP0_DESAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .set mips32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) deret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) END(ejtag_debug_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * This buffer is reserved for the use of the EJTAG debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) EXPORT(ejtag_debug_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .fill LONGSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) EXPORT(ejtag_debug_buffer_spinlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .fill LONGSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) EXPORT(ejtag_debug_buffer_per_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .fill LONGSIZE * NR_CPUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) __INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * NMI debug exception handler for MIPS reference boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * The NMI debug exception entry point is 0xbfc00000, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * normally is in the boot PROM, so the boot PROM must do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * unconditional jump to this vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) NESTED(except_vec_nmi, 0, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) j nmi_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) END(except_vec_nmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __FINIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) NESTED(nmi_handler, PT_SIZE, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .cfi_signal_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * Clear ERL - restore segment mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * Clear BEV - required for page fault exception handler to work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) mfc0 k0, CP0_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ori k0, k0, ST0_EXL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) li k1, ~(ST0_BEV | ST0_ERL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) and k0, k0, k1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mtc0 k0, CP0_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) _ehb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) SAVE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) jal nmi_exception_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* nmi_exception_handler never returns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) END(nmi_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .macro __build_clear_none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .macro __build_clear_sti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) STI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .macro __build_clear_cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) CLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .macro __build_clear_fpe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) CLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* gas fails to assemble cfc1 for some archs (octeon).*/ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .set mips1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) SET_HARDFLOAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) cfc1 a1, fcr31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .macro __build_clear_msa_fpe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) CLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) _cfcmsa a1, MSA_CSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .macro __build_clear_ade
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) MFC0 t0, CP0_BADVADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) PTR_S t0, PT_BVADDR(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) KMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .macro __build_clear_gsexc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * We need to specify a selector to access the CP0.Diag1 (GSCause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * register. All GSExc-equipped processors have MIPS32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .set mips32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mfc0 a1, CP0_DIAGNOSTIC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) STI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .macro __BUILD_silent exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* Gas tries to parse the ASM_PRINT argument as a string containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) string escapes and emits bogus warnings if it believes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) recognize an unknown escape code. So make the arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) start with an n and gas will believe \n is ok ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .macro __BUILD_verbose nexception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) LONG_L a1, PT_EPC(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #ifdef CONFIG_32BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ASM_PRINT("Got \nexception at %08lx\012")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ASM_PRINT("Got \nexception at %016lx\012")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .macro __BUILD_count exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) LONG_L t0,exception_count_\exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) LONG_ADDIU t0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) LONG_S t0,exception_count_\exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .comm exception_count\exception, 8, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .macro __BUILD_HANDLER exception handler clear verbose ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) NESTED(handle_\exception, PT_SIZE, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .cfi_signal_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) SAVE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) FEXPORT(handle_\exception\ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) __build_clear_\clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .set at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) __BUILD_\verbose \exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) jal do_\handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) j ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) END(handle_\exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .macro BUILD_HANDLER exception handler clear verbose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) __BUILD_HANDLER \exception \handler \clear \verbose _int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) BUILD_HANDLER adel ade ade silent /* #4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) BUILD_HANDLER ades ade ade silent /* #5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) BUILD_HANDLER ibe be cli silent /* #6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) BUILD_HANDLER dbe be cli silent /* #7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) BUILD_HANDLER bp bp sti silent /* #9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) BUILD_HANDLER ri ri sti silent /* #10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) BUILD_HANDLER cpu cpu sti silent /* #11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) BUILD_HANDLER ov ov sti silent /* #12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) BUILD_HANDLER tr tr sti silent /* #13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) #ifdef CONFIG_MIPS_FP_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) BUILD_HANDLER fpe fpe fpe silent /* #15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) BUILD_HANDLER ftlb ftlb none silent /* #16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) BUILD_HANDLER gsexc gsexc gsexc silent /* #16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) BUILD_HANDLER msa msa sti silent /* #21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) BUILD_HANDLER mdmx mdmx sti silent /* #22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef CONFIG_HARDWARE_WATCHPOINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * For watch, interrupts will be enabled after the watch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * registers are read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) BUILD_HANDLER watch watch cli silent /* #23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) BUILD_HANDLER watch watch sti verbose /* #23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) BUILD_HANDLER mcheck mcheck cli verbose /* #24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) BUILD_HANDLER mt mt sti silent /* #25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) BUILD_HANDLER dsp dsp sti silent /* #26 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) BUILD_HANDLER reserved reserved sti verbose /* others */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) LEAF(handle_ri_rdhwr_tlbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* check if TLB contains a entry for EPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) MFC0 k1, CP0_ENTRYHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) andi k1, MIPS_ENTRYHI_ASID | MIPS_ENTRYHI_ASIDX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) MFC0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) PTR_SRL k0, _PAGE_SHIFT + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) PTR_SLL k0, _PAGE_SHIFT + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) or k1, k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) MTC0 k1, CP0_ENTRYHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) mtc0_tlbw_hazard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) tlbp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) tlb_probe_hazard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mfc0 k1, CP0_INDEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) bltz k1, handle_ri /* slow path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* fall thru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) END(handle_ri_rdhwr_tlbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) LEAF(handle_ri_rdhwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* MIPS32: 0x7c03e83b: rdhwr v1,$29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* microMIPS: 0x007d6b3c: rdhwr v1,$29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) MFC0 k1, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) and k0, k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) beqz k0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) xor k1, k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) lhu k0, (k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) lhu k1, 2(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ins k1, k0, 16, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) lui k0, 0x007d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) b docheck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ori k0, 0x6b3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) lui k0, 0x7c03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) lw k1, (k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ori k0, 0xe83b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) andi k0, k1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) bnez k0, handle_ri
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) lui k0, 0x7c03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) lw k1, (k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ori k0, 0xe83b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .set reorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) docheck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) bne k0, k1, handle_ri /* if not ours */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) isrdhwr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* The insn is rdhwr. No need to check CAUSE.BD here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) get_saved_sp /* k1 := current_thread_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) MFC0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ori k1, _THREAD_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) xori k1, _THREAD_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) LONG_L v1, TI_TP_VALUE(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) LONG_ADDIU k0, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) jr k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) rfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) LONG_ADDIU k0, 4 /* stall on $k0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .set at=v1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) LONG_ADDIU k0, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) MTC0 k0, CP0_EPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* I hope three instructions between MTC0 and ERET are enough... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ori k1, _THREAD_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) xori k1, _THREAD_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) LONG_L v1, TI_TP_VALUE(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .set arch=r4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) eret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) END(handle_ri_rdhwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #ifdef CONFIG_CPU_R4X00_BUGS64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* A temporary overflow handler used by check_daddi(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) __INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) BUILD_HANDLER daddi_ov daddi_ov none silent /* #12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #endif