1 /* $Id: winmacro.h,v 1.22 2000/05/09 17:40:15 davem Exp $ 2 * winmacro.h: Window loading-unloading macros. 3 * 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5 */ 6 7 #ifndef _SPARC_WINMACRO_H 8 #define _SPARC_WINMACRO_H 9 10 #include <linux/config.h> 11 #include <asm/ptrace.h> 12 #include <asm/psr.h> 13 14 /* Store the register window onto the 8-byte aligned area starting 15 * at %reg. It might be %sp, it might not, we don't care. 16 */ 17 #define STORE_WINDOW(reg) \ 18 std %l0, [%reg + RW_L0]; \ 19 std %l2, [%reg + RW_L2]; \ 20 std %l4, [%reg + RW_L4]; \ 21 std %l6, [%reg + RW_L6]; \ 22 std %i0, [%reg + RW_I0]; \ 23 std %i2, [%reg + RW_I2]; \ 24 std %i4, [%reg + RW_I4]; \ 25 std %i6, [%reg + RW_I6]; 26 27 /* Load a register window from the area beginning at %reg. */ 28 #define LOAD_WINDOW(reg) \ 29 ldd [%reg + RW_L0], %l0; \ 30 ldd [%reg + RW_L2], %l2; \ 31 ldd [%reg + RW_L4], %l4; \ 32 ldd [%reg + RW_L6], %l6; \ 33 ldd [%reg + RW_I0], %i0; \ 34 ldd [%reg + RW_I2], %i2; \ 35 ldd [%reg + RW_I4], %i4; \ 36 ldd [%reg + RW_I6], %i6; 37 38 /* Loading and storing struct pt_reg trap frames. */ 39 #define LOAD_PT_INS(base_reg) \ 40 ldd [%base_reg + STACKFRAME_SZ + PT_I0], %i0; \ 41 ldd [%base_reg + STACKFRAME_SZ + PT_I2], %i2; \ 42 ldd [%base_reg + STACKFRAME_SZ + PT_I4], %i4; \ 43 ldd [%base_reg + STACKFRAME_SZ + PT_I6], %i6; 44 45 #define LOAD_PT_GLOBALS(base_reg) \ 46 ld [%base_reg + STACKFRAME_SZ + PT_G1], %g1; \ 47 ldd [%base_reg + STACKFRAME_SZ + PT_G2], %g2; \ 48 ldd [%base_reg + STACKFRAME_SZ + PT_G4], %g4; \ 49 ldd [%base_reg + STACKFRAME_SZ + PT_G6], %g6; 50 51 #define LOAD_PT_YREG(base_reg, scratch) \ 52 ld [%base_reg + STACKFRAME_SZ + PT_Y], %scratch; \ 53 wr %scratch, 0x0, %y; 54 55 #define LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ 56 ld [%base_reg + STACKFRAME_SZ + PT_PSR], %pt_psr; \ 57 ld [%base_reg + STACKFRAME_SZ + PT_PC], %pt_pc; \ 58 ld [%base_reg + STACKFRAME_SZ + PT_NPC], %pt_npc; 59 60 #define LOAD_PT_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ 61 LOAD_PT_YREG(base_reg, scratch) \ 62 LOAD_PT_INS(base_reg) \ 63 LOAD_PT_GLOBALS(base_reg) \ 64 LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) 65 66 #define STORE_PT_INS(base_reg) \ 67 std %i0, [%base_reg + STACKFRAME_SZ + PT_I0]; \ 68 std %i2, [%base_reg + STACKFRAME_SZ + PT_I2]; \ 69 std %i4, [%base_reg + STACKFRAME_SZ + PT_I4]; \ 70 std %i6, [%base_reg + STACKFRAME_SZ + PT_I6]; 71 72 #define STORE_PT_GLOBALS(base_reg) \ 73 st %g1, [%base_reg + STACKFRAME_SZ + PT_G1]; \ 74 std %g2, [%base_reg + STACKFRAME_SZ + PT_G2]; \ 75 std %g4, [%base_reg + STACKFRAME_SZ + PT_G4]; \ 76 std %g6, [%base_reg + STACKFRAME_SZ + PT_G6]; 77 78 #define STORE_PT_YREG(base_reg, scratch) \ 79 rd %y, %scratch; \ 80 st %scratch, [%base_reg + STACKFRAME_SZ + PT_Y]; 81 82 #define STORE_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ 83 st %pt_psr, [%base_reg + STACKFRAME_SZ + PT_PSR]; \ 84 st %pt_pc, [%base_reg + STACKFRAME_SZ + PT_PC]; \ 85 st %pt_npc, [%base_reg + STACKFRAME_SZ + PT_NPC]; 86 87 #define STORE_PT_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ 88 STORE_PT_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ 89 STORE_PT_GLOBALS(base_reg) \ 90 STORE_PT_YREG(base_reg, g_scratch) \ 91 STORE_PT_INS(base_reg) 92 93 #define SAVE_BOLIXED_USER_STACK(cur_reg, scratch) \ 94 ld [%cur_reg + AOFF_task_thread + AOFF_thread_w_saved], %scratch; \ 95 sll %scratch, 2, %scratch; \ 96 add %scratch, %cur_reg, %scratch; \ 97 st %sp, [%scratch + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]; \ 98 sub %scratch, %cur_reg, %scratch; \ 99 sll %scratch, 4, %scratch; \ 100 add %scratch, %cur_reg, %scratch; \ 101 STORE_WINDOW(scratch + AOFF_task_thread + AOFF_thread_reg_window); \ 102 sub %scratch, %cur_reg, %scratch; \ 103 srl %scratch, 6, %scratch; \ 104 add %scratch, 1, %scratch; \ 105 st %scratch, [%cur_reg + AOFF_task_thread + AOFF_thread_w_saved]; 106 107 #ifdef CONFIG_SMP 108 #define LOAD_CURRENT4M(dest_reg, idreg) \ 109 rd %tbr, %idreg; \ 110 sethi %hi(C_LABEL(current_set)), %dest_reg; \ 111 srl %idreg, 10, %idreg; \ 112 or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ 113 and %idreg, 0xc, %idreg; \ 114 ld [%idreg + %dest_reg], %dest_reg; 115 116 #define LOAD_CURRENT4D(dest_reg, idreg) \ 117 lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ 118 sethi %hi(C_LABEL(current_set)), %dest_reg; \ 119 sll %idreg, 2, %idreg; \ 120 or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ 121 ld [%idreg + %dest_reg], %dest_reg; 122 123 /* Blackbox - take care with this... - check smp4m and smp4d before changing this. */ 124 #define LOAD_CURRENT(dest_reg, idreg) \ 125 sethi %hi(___b_load_current), %idreg; \ 126 sethi %hi(C_LABEL(current_set)), %dest_reg; \ 127 sethi %hi(C_LABEL(boot_cpu_id4)), %idreg; \ 128 or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ 129 ldub [%idreg + %lo(C_LABEL(boot_cpu_id4))], %idreg; \ 130 ld [%idreg + %dest_reg], %dest_reg; 131 #else 132 #define LOAD_CURRENT(dest_reg, idreg) \ 133 sethi %hi(C_LABEL(current_set)), %idreg; \ 134 ld [%idreg + %lo(C_LABEL(current_set))], %dest_reg; 135 #endif 136 137 #endif /* !(_SPARC_WINMACRO_H) */ 138