|
|
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.