^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * etrap.S: Sparc trap window preparation for entry into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linux kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/asi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/contregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/psr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/winmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Registers to not touch at all. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define t_psr l0 /* Set by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define t_pc l1 /* Set by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define t_npc l2 /* Set by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define t_wim l3 /* Set by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define t_twinmask l4 /* Set at beginning of this entry routine. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define t_kstack l5 /* Set right before pt_regs frame is built */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define t_retpc l6 /* If you change this, change winmacro.h header file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define t_systable l7 /* Never touch this, could be the syscall table ptr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define curptr g6 /* Set after pt_regs frame is built */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* SEVEN WINDOW PATCH INSTRUCTIONS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .globl tsetup_7win_patch1, tsetup_7win_patch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .globl tsetup_7win_patch3, tsetup_7win_patch4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .globl tsetup_7win_patch5, tsetup_7win_patch6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) tsetup_7win_patch1: sll %t_wim, 0x6, %t_wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) tsetup_7win_patch2: and %g2, 0x7f, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) tsetup_7win_patch3: and %g2, 0x7f, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) tsetup_7win_patch4: and %g1, 0x7f, %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) tsetup_7win_patch5: sll %t_wim, 0x6, %t_wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) tsetup_7win_patch6: and %g2, 0x7f, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* END OF PATCH INSTRUCTIONS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* At trap time, interrupts and all generic traps do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * rd %psr, %l0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * b some_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * rd %wim, %l3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Then 'some_handler' if it needs a trap frame (ie. it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * to call c-code and the trap cannot be handled in-window)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * then it does the SAVE_ALL macro in entry.S which does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * sethi %hi(trap_setup), %l4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * jmpl %l4 + %lo(trap_setup), %l6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* 2 3 4 window number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * O T S mnemonic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * O == Current window before trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * T == Window entered when trap occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * S == Window we will need to save if (1<<T) == %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Before execution gets here, it must be guaranteed that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * %l0 contains trap time %psr, %l1 and %l2 contain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * trap pc and npc, and %l3 contains the trap time %wim.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .globl trap_setup, tsetup_patch1, tsetup_patch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .globl tsetup_patch3, tsetup_patch4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .globl tsetup_patch5, tsetup_patch6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) trap_setup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Calculate mask of trap window. See if from user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * or kernel and branch conditionally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mov 1, %t_twinmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) andcc %t_psr, PSR_PS, %g0 ! fromsupv_p = (psr & PSR_PS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) be trap_setup_from_user ! nope, from user mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* From kernel, allocate more kernel stack and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * build a pt_regs trap frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sub %fp, (STACKFRAME_SZ + TRACEREG_SZ), %t_kstack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* See if we are in the trap window. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) andcc %t_twinmask, %t_wim, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) bne trap_setup_kernel_spill ! in trap window, clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Trap from kernel with a window available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Just do it...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) jmpl %t_retpc + 0x8, %g0 ! return to caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mov %t_kstack, %sp ! jump onto new stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) trap_setup_kernel_spill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ld [%curptr + TI_UWINMASK], %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) orcc %g0, %g1, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) bne trap_setup_user_spill ! there are some user windows, yuck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Spill from kernel, but only kernel windows, adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * %wim and go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) srl %t_wim, 0x1, %g2 ! begin computation of new %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) tsetup_patch1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) sll %t_wim, 0x7, %t_wim ! patched on 7 window Sparcs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) or %t_wim, %g2, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) tsetup_patch2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) and %g2, 0xff, %g2 ! patched on 7 window Sparcs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) save %g0, %g0, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Set new %wim value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) wr %g2, 0x0, %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Save the kernel window onto the corresponding stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) STORE_WINDOW(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) restore %g0, %g0, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) jmpl %t_retpc + 0x8, %g0 ! return to caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mov %t_kstack, %sp ! and onto new kernel stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) trap_setup_from_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* We can't use %curptr yet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) LOAD_CURRENT(t_kstack, t_twinmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) sethi %hi(STACK_OFFSET), %t_twinmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) or %t_twinmask, %lo(STACK_OFFSET), %t_twinmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) add %t_kstack, %t_twinmask, %t_kstack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mov 1, %t_twinmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Build pt_regs frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* If we're sure every task_struct is THREAD_SIZE aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) we can speed this up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) sethi %hi(STACK_OFFSET), %curptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) or %curptr, %lo(STACK_OFFSET), %curptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) sub %t_kstack, %curptr, %curptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) sethi %hi(~(THREAD_SIZE - 1)), %curptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) and %t_kstack, %curptr, %curptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Clear current_thread_info->w_saved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) st %g0, [%curptr + TI_W_SAVED]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* See if we are in the trap window. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) andcc %t_twinmask, %t_wim, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) bne trap_setup_user_spill ! yep we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) orn %g0, %t_twinmask, %g1 ! negate trap win mask into %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Trap from user, but not into the invalid window.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Calculate new umask. The way this works is,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * any window from the %wim at trap time until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * the window right before the one we are in now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * is a user window. A diagram:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * 7 6 5 4 3 2 1 0 window number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * I L T mnemonic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Window 'I' is the invalid window in our example,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * window 'L' is the window the user was in when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * the trap occurred, window T is the trap window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * we are in now. So therefore, windows 5, 4 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * 3 are user windows. The following sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * computes the user winmask to represent this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) subcc %t_wim, %t_twinmask, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) bneg,a 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) sub %g2, 0x1, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) andn %g2, %t_twinmask, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) tsetup_patch3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) and %g2, 0xff, %g2 ! patched on 7win Sparcs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) st %g2, [%curptr + TI_UWINMASK] ! store new umask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) jmpl %t_retpc + 0x8, %g0 ! return to caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mov %t_kstack, %sp ! and onto kernel stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) trap_setup_user_spill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* A spill occurred from either kernel or user mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * and there exist some user windows to deal with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * A mask of the currently valid user windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * is in %g1 upon entry to here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) tsetup_patch4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) and %g1, 0xff, %g1 ! patched on 7win Sparcs, mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) srl %t_wim, 0x1, %g2 ! compute new %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tsetup_patch5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) sll %t_wim, 0x7, %t_wim ! patched on 7win Sparcs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) or %t_wim, %g2, %g2 ! %g2 is new %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) tsetup_patch6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) and %g2, 0xff, %g2 ! patched on 7win Sparcs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) andn %g1, %g2, %g1 ! clear this bit in %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) st %g1, [%curptr + TI_UWINMASK]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) save %g0, %g0, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) wr %g2, 0x0, %wim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Call MMU-architecture dependent stack checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) b tsetup_srmmu_stackchk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) andcc %sp, 0x7, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Architecture specific stack checking routines. When either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * of these routines are called, the globals are free to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * as they have been safely stashed on the new kernel stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * pointer. Thus the definition below for simplicity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define glob_tmp g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .globl tsetup_srmmu_stackchk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) tsetup_srmmu_stackchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Check results of callers andcc %sp, 0x7, %g0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bne trap_setup_user_stack_is_bolixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) sethi %hi(PAGE_OFFSET), %glob_tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) cmp %glob_tmp, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bleu,a 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) trap_setup_user_stack_is_bolixed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* From user/kernel into invalid window w/bad user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * stack. Save bad user stack, and return to caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) SAVE_BOLIXED_USER_STACK(curptr, g3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) restore %g0, %g0, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) jmpl %t_retpc + 0x8, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mov %t_kstack, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Clear the fault status and turn on the no_fault bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Dump the registers and cross fingers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) STORE_WINDOW(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Clear the no_fault bit and check the status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) andn %glob_tmp, 0x2, %glob_tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mov AC_M_SFAR, %glob_tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mov AC_M_SFSR, %glob_tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) andcc %glob_tmp, 0x2, %g0 ! did we fault?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) bne trap_setup_user_stack_is_bolixed ! failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) restore %g0, %g0, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) jmpl %t_retpc + 0x8, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mov %t_kstack, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)