0001
0002
0003
0004
0005
0006
0007
0008 #include <asm/contregs.h>
0009 #include <asm/page.h>
0010 #include <asm/ptrace.h>
0011 #include <asm/psr.h>
0012 #include <asm/smp.h>
0013 #include <asm/asi.h>
0014 #include <asm/winmacro.h>
0015 #include <asm/asmmacro.h>
0016 #include <asm/thread_info.h>
0017
0018
0019
0020
0021 #define t_psr l0
0022 #define t_pc l1
0023 #define t_npc l2
0024 #define t_wim l3
0025
0026
0027
0028 #define twin_tmp1 l4
0029 #define twin_tmp2 l5
0030
0031 #define curptr g6
0032
0033 .text
0034 .align 4
0035
0036
0037
0038
0039
0040
0041
0042
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
0076 .globl fnwin_patch1_7win, fnwin_patch2_7win
0077 fnwin_patch1_7win: srl %t_wim, 6, %twin_tmp2
0078 fnwin_patch2_7win: and %twin_tmp1, 0x7f, %twin_tmp1
0079
0080
0081 .globl fill_window_entry, fnwin_patch1, fnwin_patch2
0082 fill_window_entry:
0083
0084
0085
0086
0087
0088 sll %t_wim, 1, %twin_tmp1
0089 fnwin_patch1: srl %t_wim, 7, %twin_tmp2
0090 or %twin_tmp1, %twin_tmp2, %twin_tmp1
0091 fnwin_patch2: and %twin_tmp1, 0xff, %twin_tmp1
0092
0093 wr %twin_tmp1, 0x0, %wim
0094
0095 andcc %t_psr, PSR_PS, %g0
0096 be fwin_from_user
0097 restore %g0, %g0, %g0
0098
0099
0100
0101
0102
0103 fwin_from_kernel:
0104
0105
0106 restore %g0, %g0, %g0
0107
0108
0109
0110 LOAD_WINDOW(sp)
0111
0112
0113 save %g0, %g0, %g0
0114 save %g0, %g0, %g0
0115
0116
0117
0118
0119
0120
0121
0122 wr %t_psr, 0x0, %psr
0123 WRITE_PAUSE
0124
0125 jmp %t_pc
0126 rett %t_npc
0127
0128 fwin_from_user:
0129
0130
0131 restore %g0, %g0, %g0
0132
0133
0134
0135
0136 b srmmu_fwin_stackchk
0137 andcc %sp, 0x7, %g0
0138
0139 #define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ)
0140
0141 fwin_user_stack_is_bolixed:
0142
0143
0144
0145
0146
0147 LOAD_CURRENT(l4, l5)
0148
0149 sethi %hi(STACK_OFFSET), %l5
0150 or %l5, %lo(STACK_OFFSET), %l5
0151 add %l4, %l5, %l5
0152
0153
0154 STORE_PT_GLOBALS(l5)
0155 STORE_PT_YREG(l5, g3)
0156
0157
0158 mov %l4, %curptr
0159
0160 save %g0, %g0, %g0
0161
0162
0163
0164 rd %psr, %g3
0165 mov %fp, %g4
0166
0167 save %g0, %g0, %g0
0168
0169
0170
0171 sethi %hi(STACK_OFFSET), %l5
0172 or %l5, %lo(STACK_OFFSET), %l5
0173 add %curptr, %l5, %sp
0174
0175
0176 STORE_PT_INS(sp)
0177 STORE_PT_PRIV(sp, t_psr, t_pc, t_npc)
0178
0179
0180 wr %t_wim, 0x0, %wim
0181
0182
0183 mov 0x1, %g5
0184 sll %g5, %g3, %g5
0185 st %g5, [%curptr + TI_UWINMASK] ! one live user window still
0186 st %g0, [%curptr + TI_W_SAVED] ! no windows in the buffer
0187
0188 wr %t_psr, PSR_ET, %psr ! enable traps
0189 nop
0190 call window_underflow_fault
0191 mov %g4, %o0
0192
0193 b ret_trap_entry
0194 clr %l6
0195
0196 fwin_user_stack_is_ok:
0197
0198
0199
0200
0201
0202 LOAD_WINDOW(sp)
0203
0204
0205 save %g0, %g0, %g0
0206 save %g0, %g0, %g0
0207
0208
0209
0210
0211 fwin_user_finish_up:
0212
0213
0214 wr %t_psr, 0x0, %psr
0215 WRITE_PAUSE
0216
0217 jmp %t_pc
0218 rett %t_npc
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 .globl srmmu_fwin_stackchk
0244 srmmu_fwin_stackchk:
0245
0246
0247
0248 bne fwin_user_stack_is_bolixed
0249 sethi %hi(PAGE_OFFSET), %l5
0250
0251
0252
0253
0254
0255 mov AC_M_SFSR, %l4
0256 cmp %l5, %sp
0257 bleu fwin_user_stack_is_bolixed
0258 LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status
0259 SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status
0260
0261
0262
0263
0264
0265
0266 LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg
0267 SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg
0268 or %l5, 0x2, %l5 ! turn on no-fault bit
0269 LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it
0270 SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it
0271
0272
0273 LOAD_WINDOW(sp)
0274
0275
0276 save %g0, %g0, %g0
0277 save %g0, %g0, %g0
0278
0279
0280
0281
0282 LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
0283 SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
0284 andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit
0285 LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it
0286 SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it
0287
0288 mov AC_M_SFAR, %twin_tmp2
0289 LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address
0290 SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address
0291
0292 mov AC_M_SFSR, %twin_tmp2
0293 LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status
0294 SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status
0295 andcc %twin_tmp2, 0x2, %g0 ! did fault occur?
0296
0297 bne 1f ! yep, cleanup
0298 nop
0299
0300 wr %t_psr, 0x0, %psr
0301 nop
0302 b fwin_user_finish_up + 0x4
0303 nop
0304
0305
0306
0307
0308
0309
0310 1:
0311 restore %g0, %g0, %g0
0312 b fwin_user_stack_is_bolixed ! oh well
0313 restore %g0, %g0, %g0