1d670bd4fSSam Ravnborg/* 2d670bd4fSSam Ravnborg * rtrap.S: Return from Sparc trap low-level code. 3d670bd4fSSam Ravnborg * 4d670bd4fSSam Ravnborg * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5d670bd4fSSam Ravnborg */ 6d670bd4fSSam Ravnborg 7d670bd4fSSam Ravnborg#include <asm/page.h> 8d670bd4fSSam Ravnborg#include <asm/ptrace.h> 9d670bd4fSSam Ravnborg#include <asm/psr.h> 10d670bd4fSSam Ravnborg#include <asm/asi.h> 11d670bd4fSSam Ravnborg#include <asm/smp.h> 12d670bd4fSSam Ravnborg#include <asm/contregs.h> 13d670bd4fSSam Ravnborg#include <asm/winmacro.h> 14d670bd4fSSam Ravnborg#include <asm/asmmacro.h> 15d670bd4fSSam Ravnborg#include <asm/thread_info.h> 16d670bd4fSSam Ravnborg 17d670bd4fSSam Ravnborg#define t_psr l0 18d670bd4fSSam Ravnborg#define t_pc l1 19d670bd4fSSam Ravnborg#define t_npc l2 20d670bd4fSSam Ravnborg#define t_wim l3 21d670bd4fSSam Ravnborg#define twin_tmp1 l4 22d670bd4fSSam Ravnborg#define glob_tmp g4 23d670bd4fSSam Ravnborg#define curptr g6 24d670bd4fSSam Ravnborg 25d670bd4fSSam Ravnborg /* 7 WINDOW SPARC PATCH INSTRUCTIONS */ 26d670bd4fSSam Ravnborg .globl rtrap_7win_patch1, rtrap_7win_patch2, rtrap_7win_patch3 27d670bd4fSSam Ravnborg .globl rtrap_7win_patch4, rtrap_7win_patch5 28d670bd4fSSam Ravnborgrtrap_7win_patch1: srl %t_wim, 0x6, %glob_tmp 29d670bd4fSSam Ravnborgrtrap_7win_patch2: and %glob_tmp, 0x7f, %glob_tmp 30d670bd4fSSam Ravnborgrtrap_7win_patch3: srl %g1, 7, %g2 31d670bd4fSSam Ravnborgrtrap_7win_patch4: srl %g2, 6, %g2 32d670bd4fSSam Ravnborgrtrap_7win_patch5: and %g1, 0x7f, %g1 33d670bd4fSSam Ravnborg /* END OF PATCH INSTRUCTIONS */ 34d670bd4fSSam Ravnborg 35d670bd4fSSam Ravnborg /* We need to check for a few things which are: 36d670bd4fSSam Ravnborg * 1) The need to call schedule() because this 37d670bd4fSSam Ravnborg * processes quantum is up. 38d670bd4fSSam Ravnborg * 2) Pending signals for this process, if any 39d670bd4fSSam Ravnborg * exist we need to call do_signal() to do 40d670bd4fSSam Ravnborg * the needy. 41d670bd4fSSam Ravnborg * 42d670bd4fSSam Ravnborg * Else we just check if the rett would land us 43d670bd4fSSam Ravnborg * in an invalid window, if so we need to grab 44d670bd4fSSam Ravnborg * it off the user/kernel stack first. 45d670bd4fSSam Ravnborg */ 46d670bd4fSSam Ravnborg 47d670bd4fSSam Ravnborg .globl ret_trap_entry, rtrap_patch1, rtrap_patch2 48d670bd4fSSam Ravnborg .globl rtrap_patch3, rtrap_patch4, rtrap_patch5 49d670bd4fSSam Ravnborg .globl ret_trap_lockless_ipi 50d670bd4fSSam Ravnborgret_trap_entry: 51d670bd4fSSam Ravnborgret_trap_lockless_ipi: 52d670bd4fSSam Ravnborg andcc %t_psr, PSR_PS, %g0 53d670bd4fSSam Ravnborg sethi %hi(PSR_SYSCALL), %g1 54d670bd4fSSam Ravnborg be 1f 55d670bd4fSSam Ravnborg andn %t_psr, %g1, %t_psr 56d670bd4fSSam Ravnborg 57d670bd4fSSam Ravnborg wr %t_psr, 0x0, %psr 58d670bd4fSSam Ravnborg b ret_trap_kernel 59d670bd4fSSam Ravnborg nop 60d670bd4fSSam Ravnborg 61d670bd4fSSam Ravnborg1: 62d670bd4fSSam Ravnborg ld [%curptr + TI_FLAGS], %g2 63d670bd4fSSam Ravnborg andcc %g2, (_TIF_NEED_RESCHED), %g0 64d670bd4fSSam Ravnborg be signal_p 65d670bd4fSSam Ravnborg nop 66d670bd4fSSam Ravnborg 67d670bd4fSSam Ravnborg call schedule 68d670bd4fSSam Ravnborg nop 69d670bd4fSSam Ravnborg 70d670bd4fSSam Ravnborg ld [%curptr + TI_FLAGS], %g2 71d670bd4fSSam Ravnborgsignal_p: 72d670bd4fSSam Ravnborg andcc %g2, _TIF_DO_NOTIFY_RESUME_MASK, %g0 73d670bd4fSSam Ravnborg bz,a ret_trap_continue 74d670bd4fSSam Ravnborg ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 75d670bd4fSSam Ravnborg 76d670bd4fSSam Ravnborg mov %g2, %o2 77d670bd4fSSam Ravnborg mov %l5, %o1 78d670bd4fSSam Ravnborg call do_notify_resume 79d670bd4fSSam Ravnborg add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr 80d670bd4fSSam Ravnborg 81caebf910SAl Viro b signal_p 82caebf910SAl Viro ld [%curptr + TI_FLAGS], %g2 83caebf910SAl Viro 84d670bd4fSSam Ravnborgret_trap_continue: 85d670bd4fSSam Ravnborg sethi %hi(PSR_SYSCALL), %g1 86d670bd4fSSam Ravnborg andn %t_psr, %g1, %t_psr 87d670bd4fSSam Ravnborg wr %t_psr, 0x0, %psr 88d670bd4fSSam Ravnborg WRITE_PAUSE 89d670bd4fSSam Ravnborg 90d670bd4fSSam Ravnborg ld [%curptr + TI_W_SAVED], %twin_tmp1 91d670bd4fSSam Ravnborg orcc %g0, %twin_tmp1, %g0 92d670bd4fSSam Ravnborg be ret_trap_nobufwins 93d670bd4fSSam Ravnborg nop 94d670bd4fSSam Ravnborg 95d670bd4fSSam Ravnborg wr %t_psr, PSR_ET, %psr 96d670bd4fSSam Ravnborg WRITE_PAUSE 97d670bd4fSSam Ravnborg 98d670bd4fSSam Ravnborg mov 1, %o1 99d670bd4fSSam Ravnborg call try_to_clear_window_buffer 100d670bd4fSSam Ravnborg add %sp, STACKFRAME_SZ, %o0 101d670bd4fSSam Ravnborg 102d670bd4fSSam Ravnborg b signal_p 103d670bd4fSSam Ravnborg ld [%curptr + TI_FLAGS], %g2 104d670bd4fSSam Ravnborg 105d670bd4fSSam Ravnborgret_trap_nobufwins: 106d670bd4fSSam Ravnborg /* Load up the user's out registers so we can pull 107d670bd4fSSam Ravnborg * a window from the stack, if necessary. 108d670bd4fSSam Ravnborg */ 109d670bd4fSSam Ravnborg LOAD_PT_INS(sp) 110d670bd4fSSam Ravnborg 111d670bd4fSSam Ravnborg /* If there are already live user windows in the 112d670bd4fSSam Ravnborg * set we can return from trap safely. 113d670bd4fSSam Ravnborg */ 114d670bd4fSSam Ravnborg ld [%curptr + TI_UWINMASK], %twin_tmp1 115d670bd4fSSam Ravnborg orcc %g0, %twin_tmp1, %g0 116d670bd4fSSam Ravnborg bne ret_trap_userwins_ok 117d670bd4fSSam Ravnborg nop 118d670bd4fSSam Ravnborg 119d670bd4fSSam Ravnborg /* Calculate new %wim, we have to pull a register 120d670bd4fSSam Ravnborg * window from the users stack. 121d670bd4fSSam Ravnborg */ 122d670bd4fSSam Ravnborgret_trap_pull_one_window: 123d670bd4fSSam Ravnborg rd %wim, %t_wim 124d670bd4fSSam Ravnborg sll %t_wim, 0x1, %twin_tmp1 125d670bd4fSSam Ravnborgrtrap_patch1: srl %t_wim, 0x7, %glob_tmp 126d670bd4fSSam Ravnborg or %glob_tmp, %twin_tmp1, %glob_tmp 127d670bd4fSSam Ravnborgrtrap_patch2: and %glob_tmp, 0xff, %glob_tmp 128d670bd4fSSam Ravnborg 129d670bd4fSSam Ravnborg wr %glob_tmp, 0x0, %wim 130d670bd4fSSam Ravnborg 131d670bd4fSSam Ravnborg /* Here comes the architecture specific 132d670bd4fSSam Ravnborg * branch to the user stack checking routine 133d670bd4fSSam Ravnborg * for return from traps. 134d670bd4fSSam Ravnborg */ 135ef136bc9SSam Ravnborg b srmmu_rett_stackchk 136d670bd4fSSam Ravnborg andcc %fp, 0x7, %g0 137d670bd4fSSam Ravnborg 138d670bd4fSSam Ravnborgret_trap_userwins_ok: 139d670bd4fSSam Ravnborg LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) 140d670bd4fSSam Ravnborg or %t_pc, %t_npc, %g2 141d670bd4fSSam Ravnborg andcc %g2, 0x3, %g0 142d670bd4fSSam Ravnborg sethi %hi(PSR_SYSCALL), %g2 143d670bd4fSSam Ravnborg be 1f 144d670bd4fSSam Ravnborg andn %t_psr, %g2, %t_psr 145d670bd4fSSam Ravnborg 146d670bd4fSSam Ravnborg b ret_trap_unaligned_pc 147d670bd4fSSam Ravnborg add %sp, STACKFRAME_SZ, %o0 148d670bd4fSSam Ravnborg 149d670bd4fSSam Ravnborg1: 150d670bd4fSSam Ravnborg LOAD_PT_YREG(sp, g1) 151d670bd4fSSam Ravnborg LOAD_PT_GLOBALS(sp) 152d670bd4fSSam Ravnborg 153d670bd4fSSam Ravnborg wr %t_psr, 0x0, %psr 154d670bd4fSSam Ravnborg WRITE_PAUSE 155d670bd4fSSam Ravnborg 156d670bd4fSSam Ravnborg jmp %t_pc 157d670bd4fSSam Ravnborg rett %t_npc 158d670bd4fSSam Ravnborg 159d670bd4fSSam Ravnborgret_trap_unaligned_pc: 160d670bd4fSSam Ravnborg ld [%sp + STACKFRAME_SZ + PT_PC], %o1 161d670bd4fSSam Ravnborg ld [%sp + STACKFRAME_SZ + PT_NPC], %o2 162d670bd4fSSam Ravnborg ld [%sp + STACKFRAME_SZ + PT_PSR], %o3 163d670bd4fSSam Ravnborg 164d670bd4fSSam Ravnborg wr %t_wim, 0x0, %wim ! or else... 165d670bd4fSSam Ravnborg 166d670bd4fSSam Ravnborg wr %t_psr, PSR_ET, %psr 167d670bd4fSSam Ravnborg WRITE_PAUSE 168d670bd4fSSam Ravnborg 169d670bd4fSSam Ravnborg call do_memaccess_unaligned 170d670bd4fSSam Ravnborg nop 171d670bd4fSSam Ravnborg 172d670bd4fSSam Ravnborg b signal_p 173d670bd4fSSam Ravnborg ld [%curptr + TI_FLAGS], %g2 174d670bd4fSSam Ravnborg 175d670bd4fSSam Ravnborgret_trap_kernel: 176d670bd4fSSam Ravnborg /* Will the rett land us in the invalid window? */ 177d670bd4fSSam Ravnborg mov 2, %g1 178d670bd4fSSam Ravnborg sll %g1, %t_psr, %g1 179d670bd4fSSam Ravnborgrtrap_patch3: srl %g1, 8, %g2 180d670bd4fSSam Ravnborg or %g1, %g2, %g1 181d670bd4fSSam Ravnborg rd %wim, %g2 182d670bd4fSSam Ravnborg andcc %g2, %g1, %g0 183d670bd4fSSam Ravnborg be 1f ! Nope, just return from the trap 184d670bd4fSSam Ravnborg sll %g2, 0x1, %g1 185d670bd4fSSam Ravnborg 186d670bd4fSSam Ravnborg /* We have to grab a window before returning. */ 187d670bd4fSSam Ravnborgrtrap_patch4: srl %g2, 7, %g2 188d670bd4fSSam Ravnborg or %g1, %g2, %g1 189d670bd4fSSam Ravnborgrtrap_patch5: and %g1, 0xff, %g1 190d670bd4fSSam Ravnborg 191d670bd4fSSam Ravnborg wr %g1, 0x0, %wim 192d670bd4fSSam Ravnborg 193d670bd4fSSam Ravnborg /* Grrr, make sure we load from the right %sp... */ 194d670bd4fSSam Ravnborg LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1) 195d670bd4fSSam Ravnborg 196d670bd4fSSam Ravnborg restore %g0, %g0, %g0 197d670bd4fSSam Ravnborg LOAD_WINDOW(sp) 198d670bd4fSSam Ravnborg b 2f 199d670bd4fSSam Ravnborg save %g0, %g0, %g0 200d670bd4fSSam Ravnborg 201d670bd4fSSam Ravnborg /* Reload the entire frame in case this is from a 202d670bd4fSSam Ravnborg * kernel system call or whatever... 203d670bd4fSSam Ravnborg */ 204d670bd4fSSam Ravnborg1: 205d670bd4fSSam Ravnborg LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1) 206d670bd4fSSam Ravnborg2: 207d670bd4fSSam Ravnborg sethi %hi(PSR_SYSCALL), %twin_tmp1 208d670bd4fSSam Ravnborg andn %t_psr, %twin_tmp1, %t_psr 209d670bd4fSSam Ravnborg wr %t_psr, 0x0, %psr 210d670bd4fSSam Ravnborg WRITE_PAUSE 211d670bd4fSSam Ravnborg 212d670bd4fSSam Ravnborg jmp %t_pc 213d670bd4fSSam Ravnborg rett %t_npc 214d670bd4fSSam Ravnborg 215d670bd4fSSam Ravnborgret_trap_user_stack_is_bolixed: 216d670bd4fSSam Ravnborg wr %t_wim, 0x0, %wim 217d670bd4fSSam Ravnborg 218d670bd4fSSam Ravnborg wr %t_psr, PSR_ET, %psr 219d670bd4fSSam Ravnborg WRITE_PAUSE 220d670bd4fSSam Ravnborg 221d670bd4fSSam Ravnborg call window_ret_fault 222d670bd4fSSam Ravnborg add %sp, STACKFRAME_SZ, %o0 223d670bd4fSSam Ravnborg 224d670bd4fSSam Ravnborg b signal_p 225d670bd4fSSam Ravnborg ld [%curptr + TI_FLAGS], %g2 226d670bd4fSSam Ravnborg 227d670bd4fSSam Ravnborg .globl srmmu_rett_stackchk 228d670bd4fSSam Ravnborgsrmmu_rett_stackchk: 229d670bd4fSSam Ravnborg bne ret_trap_user_stack_is_bolixed 230d670bd4fSSam Ravnborg sethi %hi(PAGE_OFFSET), %g1 231d670bd4fSSam Ravnborg cmp %g1, %fp 232d670bd4fSSam Ravnborg bleu ret_trap_user_stack_is_bolixed 233d670bd4fSSam Ravnborg mov AC_M_SFSR, %g1 2341ec8cf62SSam RavnborgLEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0) 2351ec8cf62SSam RavnborgSUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0) 236d670bd4fSSam Ravnborg 2371ec8cf62SSam RavnborgLEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1) 2381ec8cf62SSam RavnborgSUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1) 239d670bd4fSSam Ravnborg or %g1, 0x2, %g1 2401ec8cf62SSam RavnborgLEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) 2411ec8cf62SSam RavnborgSUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) 242d670bd4fSSam Ravnborg 243d670bd4fSSam Ravnborg restore %g0, %g0, %g0 244d670bd4fSSam Ravnborg 245d670bd4fSSam Ravnborg LOAD_WINDOW(sp) 246d670bd4fSSam Ravnborg 247d670bd4fSSam Ravnborg save %g0, %g0, %g0 248d670bd4fSSam Ravnborg 249d670bd4fSSam Ravnborg andn %g1, 0x2, %g1 2501ec8cf62SSam RavnborgLEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) 2511ec8cf62SSam RavnborgSUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) 252d670bd4fSSam Ravnborg 253d670bd4fSSam Ravnborg mov AC_M_SFAR, %g2 2541ec8cf62SSam RavnborgLEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2) 2551ec8cf62SSam RavnborgSUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2) 256d670bd4fSSam Ravnborg 257d670bd4fSSam Ravnborg mov AC_M_SFSR, %g1 2581ec8cf62SSam RavnborgLEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1) 2591ec8cf62SSam RavnborgSUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1) 260d670bd4fSSam Ravnborg andcc %g1, 0x2, %g0 261d670bd4fSSam Ravnborg be ret_trap_userwins_ok 262d670bd4fSSam Ravnborg nop 263d670bd4fSSam Ravnborg 264d670bd4fSSam Ravnborg b,a ret_trap_user_stack_is_bolixed 265