0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <asm/head.h>
0010 #include <asm/asi.h>
0011 #include <asm/contregs.h>
0012 #include <asm/page.h>
0013 #include <asm/psr.h>
0014 #include <asm/ptrace.h>
0015 #include <asm/winmacro.h>
0016 #include <asm/asmmacro.h>
0017 #include <asm/thread_info.h>
0018
0019
0020 #define t_psr l0
0021 #define t_pc l1
0022 #define t_npc l2
0023 #define t_wim l3
0024 #define t_twinmask l4
0025 #define t_kstack l5
0026 #define t_retpc l6
0027 #define t_systable l7
0028 #define curptr g6
0029
0030 .text
0031 .align 4
0032
0033
0034 .globl tsetup_7win_patch1, tsetup_7win_patch2
0035 .globl tsetup_7win_patch3, tsetup_7win_patch4
0036 .globl tsetup_7win_patch5, tsetup_7win_patch6
0037 tsetup_7win_patch1: sll %t_wim, 0x6, %t_wim
0038 tsetup_7win_patch2: and %g2, 0x7f, %g2
0039 tsetup_7win_patch3: and %g2, 0x7f, %g2
0040 tsetup_7win_patch4: and %g1, 0x7f, %g1
0041 tsetup_7win_patch5: sll %t_wim, 0x6, %t_wim
0042 tsetup_7win_patch6: and %g2, 0x7f, %g2
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 .globl trap_setup, tsetup_patch1, tsetup_patch2
0076 .globl tsetup_patch3, tsetup_patch4
0077 .globl tsetup_patch5, tsetup_patch6
0078 trap_setup:
0079
0080
0081
0082 mov 1, %t_twinmask
0083 andcc %t_psr, PSR_PS, %g0 ! fromsupv_p = (psr & PSR_PS)
0084 be trap_setup_from_user ! nope, from user mode
0085 sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
0086
0087
0088
0089
0090 sub %fp, (STACKFRAME_SZ + TRACEREG_SZ), %t_kstack
0091 STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
0092
0093
0094 andcc %t_twinmask, %t_wim, %g0
0095 bne trap_setup_kernel_spill ! in trap window, clean up
0096 nop
0097
0098
0099
0100
0101 jmpl %t_retpc + 0x8, %g0 ! return to caller
0102 mov %t_kstack, %sp ! jump onto new stack
0103
0104 trap_setup_kernel_spill:
0105 ld [%curptr + TI_UWINMASK], %g1
0106 orcc %g0, %g1, %g0
0107 bne trap_setup_user_spill ! there are some user windows, yuck
0108
0109
0110
0111 srl %t_wim, 0x1, %g2 ! begin computation of new %wim
0112 tsetup_patch1:
0113 sll %t_wim, 0x7, %t_wim ! patched on 7 window Sparcs
0114 or %t_wim, %g2, %g2
0115 tsetup_patch2:
0116 and %g2, 0xff, %g2 ! patched on 7 window Sparcs
0117
0118 save %g0, %g0, %g0
0119
0120
0121 wr %g2, 0x0, %wim
0122
0123
0124 STORE_WINDOW(sp)
0125
0126 restore %g0, %g0, %g0
0127
0128 jmpl %t_retpc + 0x8, %g0 ! return to caller
0129 mov %t_kstack, %sp ! and onto new kernel stack
0130
0131 #define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ)
0132
0133 trap_setup_from_user:
0134
0135 LOAD_CURRENT(t_kstack, t_twinmask)
0136
0137 sethi %hi(STACK_OFFSET), %t_twinmask
0138 or %t_twinmask, %lo(STACK_OFFSET), %t_twinmask
0139 add %t_kstack, %t_twinmask, %t_kstack
0140
0141 mov 1, %t_twinmask
0142 sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
0143
0144
0145 STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
0146
0147 #if 0
0148
0149
0150 sethi %hi(STACK_OFFSET), %curptr
0151 or %curptr, %lo(STACK_OFFSET), %curptr
0152 sub %t_kstack, %curptr, %curptr
0153 #else
0154 sethi %hi(~(THREAD_SIZE - 1)), %curptr
0155 and %t_kstack, %curptr, %curptr
0156 #endif
0157
0158
0159 st %g0, [%curptr + TI_W_SAVED]
0160
0161
0162 andcc %t_twinmask, %t_wim, %g0
0163 bne trap_setup_user_spill ! yep we are
0164 orn %g0, %t_twinmask, %g1 ! negate trap win mask into %g1
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 subcc %t_wim, %t_twinmask, %g2
0184 bneg,a 1f
0185 sub %g2, 0x1, %g2
0186 1:
0187 andn %g2, %t_twinmask, %g2
0188 tsetup_patch3:
0189 and %g2, 0xff, %g2 ! patched on 7win Sparcs
0190 st %g2, [%curptr + TI_UWINMASK] ! store new umask
0191
0192 jmpl %t_retpc + 0x8, %g0 ! return to caller
0193 mov %t_kstack, %sp ! and onto kernel stack
0194
0195 trap_setup_user_spill:
0196
0197
0198
0199
0200
0201
0202 tsetup_patch4:
0203 and %g1, 0xff, %g1 ! patched on 7win Sparcs, mask
0204 srl %t_wim, 0x1, %g2 ! compute new %wim
0205 tsetup_patch5:
0206 sll %t_wim, 0x7, %t_wim ! patched on 7win Sparcs
0207 or %t_wim, %g2, %g2 ! %g2 is new %wim
0208 tsetup_patch6:
0209 and %g2, 0xff, %g2 ! patched on 7win Sparcs
0210 andn %g1, %g2, %g1 ! clear this bit in %g1
0211 st %g1, [%curptr + TI_UWINMASK]
0212
0213 save %g0, %g0, %g0
0214
0215 wr %g2, 0x0, %wim
0216
0217
0218
0219
0220 b tsetup_srmmu_stackchk
0221 andcc %sp, 0x7, %g0
0222
0223
0224
0225
0226
0227
0228 #define glob_tmp g1
0229
0230 .globl tsetup_srmmu_stackchk
0231 tsetup_srmmu_stackchk:
0232
0233 bne trap_setup_user_stack_is_bolixed
0234 sethi %hi(PAGE_OFFSET), %glob_tmp
0235
0236 cmp %glob_tmp, %sp
0237 bleu,a 1f
0238 LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
0239 SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
0240
0241 trap_setup_user_stack_is_bolixed:
0242
0243
0244
0245 SAVE_BOLIXED_USER_STACK(curptr, g3)
0246 restore %g0, %g0, %g0
0247
0248 jmpl %t_retpc + 0x8, %g0
0249 mov %t_kstack, %sp
0250
0251 1:
0252
0253 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
0254 LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
0255 SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
0256
0257
0258 STORE_WINDOW(sp)
0259
0260
0261 andn %glob_tmp, 0x2, %glob_tmp
0262 LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
0263 SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
0264
0265 mov AC_M_SFAR, %glob_tmp
0266 LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
0267 SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
0268
0269 mov AC_M_SFSR, %glob_tmp
0270 LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
0271 SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore
0272
0273 andcc %glob_tmp, 0x2, %g0 ! did we fault?
0274 bne trap_setup_user_stack_is_bolixed ! failure
0275 nop
0276
0277 restore %g0, %g0, %g0
0278
0279 jmpl %t_retpc + 0x8, %g0
0280 mov %t_kstack, %sp
0281