|
|
1.1 root 1: /*
2: * Window fill (underflow) trap, based on code from Sparclinux.
3: *
4: * Copyright (C) 1995 David S. Miller
5: *
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.
9: *
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.
14: *
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,
18: * MA 02110-1301, USA.
19: */
20:
21: // #include <psr.h>
22: // #include <asi.h>
23:
24: /* Reg_window offsets */
25: #define RW_L0 0x00
26: #define RW_L1 0x04
27: #define RW_L2 0x08
28: #define RW_L3 0x0c
29: #define RW_L4 0x10
30: #define RW_L5 0x14
31: #define RW_L6 0x18
32: #define RW_L7 0x1c
33: #define RW_I0 0x20
34: #define RW_I1 0x24
35: #define RW_I2 0x28
36: #define RW_I3 0x2c
37: #define RW_I4 0x30
38: #define RW_I5 0x34
39: #define RW_I6 0x38
40: #define RW_I7 0x3c
41:
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;
52:
53: #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
54:
55: /* Just like the overflow handler we define macros for registers
56: * with fixed meanings in this routine.
57: */
58: #define t_psr l0
59: #define t_pc l1
60: #define t_npc l2
61: #define t_wim l3
62: /* Don't touch the above registers or else you die horribly... */
63:
64: /* Now macros for the available scratch registers in this routine. */
65: #define twin_tmp1 l4
66: #define twin_tmp2 l5
67:
68: .text
69: .align 4
70:
71: /* The trap entry point has executed the following:
72: *
73: * rd %psr, %l0
74: * rd %wim, %l3
75: * b fill_window_entry
76: * andcc %l0, PSR_PS, %g0
77: */
78:
79: /* To get an idea of what has just happened to cause this
80: * trap take a look at this diagram:
81: *
82: * 1 2 3 4 <-- Window number
83: * ----------
84: * T O W I <-- Symbolic name
85: *
86: * O == the window that execution was in when
87: * the restore was attempted
88: *
89: * T == the trap itself has save'd us into this
90: * window
91: *
92: * W == this window is the one which is now invalid
93: * and must be made valid plus loaded from the
94: * stack
95: *
96: * I == this window will be the invalid one when we
97: * are done and return from trap if successful
98: */
99:
100: /* BEGINNING OF PATCH INSTRUCTIONS */
101:
102: /* On 7-window Sparc the boot code patches fnwin_patch1
103: * with the following instruction.
104: */
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 */
109:
110:
111: .globl fill_window_entry, fnwin_patch1, fnwin_patch2
112: fill_window_entry:
113: /* LOCATION: Window 'T' */
114:
115: /* Compute what the new %wim is going to be if we retrieve
116: * the proper window off of the stack.
117: */
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
122:
123: wr %twin_tmp1, 0x0, %wim /* Make window 'I' invalid */
124:
125: restore %g0, %g0, %g0 /* Restore to window 'O' */
126:
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.
130: */
131: /* LOCATION: Window 'O' */
132:
133: restore %g0, %g0, %g0
134:
135: /* LOCATION: Window 'W' */
136:
137: LOAD_WINDOW(sp) /* Load it up */
138:
139: /* Spin the wheel... */
140: save %g0, %g0, %g0
141: save %g0, %g0, %g0
142: /* I'd like to buy a vowel please... */
143:
144: /* LOCATION: Window 'T' */
145:
146: /* Now preserve the condition codes in %psr, pause, and
147: * return from trap. This is the simplest case of all.
148: */
149: wr %t_psr, 0x0, %psr
150: WRITE_PAUSE
151:
152: jmp %t_pc
153: rett %t_npc
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.