|
|
1.1 root 1: /*
2: * Proll takes this from Sparclinux kernel, ruthlessly truncated
3: * because we have no user windows.
4: *
5: * Copyright (C) 1995 David S. Miller ([email protected])
6: *
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.
10: *
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.
15: *
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,
19: * MA 02110-1301, USA.
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
23: */
24:
25: // #include <asm/winmacro.h>
26: // #include <asm/asmmacro.h>
27:
28: /* Reg_window offsets */
29: #define RW_L0 0x00
30: #define RW_L1 0x04
31: #define RW_L2 0x08
32: #define RW_L3 0x0c
33: #define RW_L4 0x10
34: #define RW_L5 0x14
35: #define RW_L6 0x18
36: #define RW_L7 0x1c
37: #define RW_I0 0x20
38: #define RW_I1 0x24
39: #define RW_I2 0x28
40: #define RW_I3 0x2c
41: #define RW_I4 0x30
42: #define RW_I5 0x34
43: #define RW_I6 0x38
44: #define RW_I7 0x3c
45:
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.
48: */
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];
58:
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
65: * from the trap.
66: */
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 */
73:
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 */
77:
78: .text
79: .align 4
80:
81: /* BEGINNING OF PATCH INSTRUCTIONS */
82: /* On a 7-window Sparc the boot code patches spnwin_*
83: * instructions with the following ones.
84: */
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 */
90:
91: /* The trap entry point has done the following:
92: *
93: * rd %psr, %l0
94: * rd %wim, %l3
95: * b spill_window_entry
96: * nop
97: */
98:
99: .globl spill_window_entry
100: .globl spnwin_patch1, spnwin_patch2
101: spill_window_entry:
102: /* LOCATION: Trap Window */
103:
104: mov %g5, %saved_g5 ! save away global temp register
105: mov %g6, %saved_g6 ! save away 'current' ptr register
106:
107: /* Compute what the new %wim will be if we save the
108: * window properly in this trap handler.
109: *
110: * newwim = ((%wim>>1) | (%wim<<(nwindows - 1)));
111: */
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
116:
117: /* Save into the window which must be saved and do it.
118: */
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
121:
122: /* LOCATION: Window to be saved */
123:
124: STORE_WINDOW(sp) ! stash the window
125: restore %g0, %g0, %g0 ! go back into trap window
126:
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.