2 * Proll takes this from Sparclinux kernel, ruthlessly truncated
3 * because we have no user windows.
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License V2
22 * as published by the Free Software Foundation
25 // #include <asm/winmacro.h>
26 // #include <asm/asmmacro.h>
28 /* Reg_window offsets */
46 /* Store the register window onto the 8-byte aligned area starting
47 * at %reg. It might be %sp, it might not, we don't care.
49 #define STORE_WINDOW(reg) \
50 std %l0, [%reg + RW_L0]; \
51 std %l2, [%reg + RW_L2]; \
52 std %l4, [%reg + RW_L4]; \
53 std %l6, [%reg + RW_L6]; \
54 std %i0, [%reg + RW_I0]; \
55 std %i2, [%reg + RW_I2]; \
56 std %i4, [%reg + RW_I4]; \
57 std %i6, [%reg + RW_I6];
59 /* We define macro's for registers which have a fixed
60 * meaning throughout this entire routine. The 'T' in
61 * the comments mean that the register can only be
62 * accessed when in the 'trap' window, 'G' means
63 * accessible in any window. Do not change these registers
64 * after they have been set, until you are ready to return
67 #define t_psr l0 /* %psr at trap time T */
68 #define t_pc l1 /* PC for trap return T */
69 #define t_npc l2 /* NPC for trap return T */
70 #define t_wim l3 /* %wim at trap time T */
71 #define saved_g5 l5 /* Global save register T */
72 #define saved_g6 l6 /* Global save register T */
74 /* Now registers whose values can change within the handler. */
75 #define twin_tmp l4 /* Temp reg, only usable in trap window T */
76 #define glob_tmp g5 /* Global temporary reg, usable anywhere G */
81 /* BEGINNING OF PATCH INSTRUCTIONS */
82 /* On a 7-window Sparc the boot code patches spnwin_*
83 * instructions with the following ones.
85 .globl spnwin_patch1_7win, spnwin_patch2_7win, spnwin_patch3_7win
86 spnwin_patch1_7win: sll %t_wim, 6, %glob_tmp
87 spnwin_patch2_7win: and %glob_tmp, 0x7f, %glob_tmp
88 spnwin_patch3_7win: and %twin_tmp, 0x7f, %twin_tmp
89 /* END OF PATCH INSTRUCTIONS */
91 /* The trap entry point has done the following:
95 * b spill_window_entry
99 .globl spill_window_entry
100 .globl spnwin_patch1, spnwin_patch2
102 /* LOCATION: Trap Window */
104 mov %g5, %saved_g5 ! save away global temp register
105 mov %g6, %saved_g6 ! save away 'current' ptr register
107 /* Compute what the new %wim will be if we save the
108 * window properly in this trap handler.
110 * newwim = ((%wim>>1) | (%wim<<(nwindows - 1)));
112 srl %t_wim, 0x1, %twin_tmp
113 spnwin_patch1: sll %t_wim, 7, %glob_tmp
114 or %glob_tmp, %twin_tmp, %glob_tmp
115 spnwin_patch2: and %glob_tmp, 0xff, %glob_tmp
117 /* Save into the window which must be saved and do it.
119 save %g0, %g0, %g0 ! save into the window to stash away
120 wr %glob_tmp, 0x0, %wim ! set new %wim, this is safe now
122 /* LOCATION: Window to be saved */
124 STORE_WINDOW(sp) ! stash the window
125 restore %g0, %g0, %g0 ! go back into trap window
127 /* LOCATION: Trap window */
128 mov %saved_g5, %g5 ! restore %glob_tmp
129 mov %saved_g6, %g6 ! restore %curptr
130 wr %t_psr, 0x0, %psr ! restore condition codes in %psr
131 nop; nop; nop ! waste some time
132 jmp %t_pc ! Return from trap
133 rett %t_npc ! we are done