2 * Window fill (underflow) trap, based on code from Sparclinux.
4 * Copyright (C) 1995 David S. Miller
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 /* Reg_window offsets */
42 /* Load a register window from the area beginning at %reg. */
43 #define LOAD_WINDOW(reg) \
44 ldd [%reg + RW_L0], %l0; \
45 ldd [%reg + RW_L2], %l2; \
46 ldd [%reg + RW_L4], %l4; \
47 ldd [%reg + RW_L6], %l6; \
48 ldd [%reg + RW_I0], %i0; \
49 ldd [%reg + RW_I2], %i2; \
50 ldd [%reg + RW_I4], %i4; \
51 ldd [%reg + RW_I6], %i6;
53 #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
55 /* Just like the overflow handler we define macros for registers
56 * with fixed meanings in this routine.
62 /* Don't touch the above registers or else you die horribly... */
64 /* Now macros for the available scratch registers in this routine. */
71 /* The trap entry point has executed the following:
76 * andcc %l0, PSR_PS, %g0
79 /* To get an idea of what has just happened to cause this
80 * trap take a look at this diagram:
82 * 1 2 3 4 <-- Window number
84 * T O W I <-- Symbolic name
86 * O == the window that execution was in when
87 * the restore was attempted
89 * T == the trap itself has save'd us into this
92 * W == this window is the one which is now invalid
93 * and must be made valid plus loaded from the
96 * I == this window will be the invalid one when we
97 * are done and return from trap if successful
100 /* BEGINNING OF PATCH INSTRUCTIONS */
102 /* On 7-window Sparc the boot code patches fnwin_patch1
103 * with the following instruction.
105 .globl fnwin_patch1_7win, fnwin_patch2_7win
106 fnwin_patch1_7win: srl %t_wim, 6, %twin_tmp2
107 fnwin_patch2_7win: and %twin_tmp1, 0x7f, %twin_tmp1
108 /* END OF PATCH INSTRUCTIONS */
111 .globl fill_window_entry, fnwin_patch1, fnwin_patch2
113 /* LOCATION: Window 'T' */
115 /* Compute what the new %wim is going to be if we retrieve
116 * the proper window off of the stack.
118 sll %t_wim, 1, %twin_tmp1
119 fnwin_patch1: srl %t_wim, 7, %twin_tmp2
120 or %twin_tmp1, %twin_tmp2, %twin_tmp1
121 fnwin_patch2: and %twin_tmp1, 0xff, %twin_tmp1
123 wr %twin_tmp1, 0x0, %wim /* Make window 'I' invalid */
125 restore %g0, %g0, %g0 /* Restore to window 'O' */
127 /* Trapped from kernel, we trust that the kernel does not
128 * 'over restore' sorta speak and just grab the window
129 * from the stack and return. Easy enough.
131 /* LOCATION: Window 'O' */
133 restore %g0, %g0, %g0
136 /* LOCATION: Window 'W' */
138 LOAD_WINDOW(sp) /* Load it up */
140 /* Spin the wheel... */
143 /* I'd like to buy a vowel please... */
145 /* LOCATION: Window 'T' */
147 /* Now preserve the condition codes in %psr, pause, and
148 * return from trap. This is the simplest case of all.