File indexing completed on 2025-05-11 08:24:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <rtems/asm.h>
0033 #include <rtems/score/cpuimpl.h>
0034 #include <rtems/score/percpu.h>
0035
0036 #define FRAME_OFFSET_BUFFER_0 (SPARC_MINIMUM_STACK_FRAME_SIZE)
0037 #define FRAME_OFFSET_BUFFER_1 (FRAME_OFFSET_BUFFER_0 + 0x04)
0038 #define FRAME_OFFSET_BUFFER_2 (FRAME_OFFSET_BUFFER_1 + 0x04)
0039 #define FRAME_OFFSET_L0 (FRAME_OFFSET_BUFFER_2 + 0x04)
0040 #define FRAME_OFFSET_L1 (FRAME_OFFSET_L0 + 0x04)
0041 #define FRAME_OFFSET_L2 (FRAME_OFFSET_L1 + 0x04)
0042 #define FRAME_OFFSET_L3 (FRAME_OFFSET_L2 + 0x04)
0043 #define FRAME_OFFSET_L4 (FRAME_OFFSET_L3 + 0x04)
0044 #define FRAME_OFFSET_L5 (FRAME_OFFSET_L4 + 0x04)
0045 #define FRAME_OFFSET_L6 (FRAME_OFFSET_L5 + 0x04)
0046 #define FRAME_OFFSET_L7 (FRAME_OFFSET_L6 + 0x04)
0047 #define FRAME_OFFSET_I0 (FRAME_OFFSET_L7 + 0x04)
0048 #define FRAME_OFFSET_I1 (FRAME_OFFSET_I0 + 0x04)
0049 #define FRAME_OFFSET_I2 (FRAME_OFFSET_I1 + 0x04)
0050 #define FRAME_OFFSET_I3 (FRAME_OFFSET_I2 + 0x04)
0051 #define FRAME_OFFSET_I4 (FRAME_OFFSET_I3 + 0x04)
0052 #define FRAME_OFFSET_I5 (FRAME_OFFSET_I4 + 0x04)
0053 #define FRAME_OFFSET_I6 (FRAME_OFFSET_I5 + 0x04)
0054 #define FRAME_OFFSET_I7 (FRAME_OFFSET_I6 + 0x04)
0055 #define FRAME_END (FRAME_OFFSET_I7 + 0x04)
0056 #define FRAME_SIZE \
0057 ((FRAME_END + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
0058
0059
0060
0061
0062
0063
0064 #define FSR_PATTERN_MASK 0xcf800fe0
0065
0066 .macro check_register reg
0067 sub %g1, 1, %g1
0068 cmp %g1, \reg
0069 bne restore_registers
0070 nop
0071 .endm
0072
0073 .macro check_float_register reg
0074 sub %g1, 1, %g1
0075 st \reg, [%sp + FRAME_OFFSET_BUFFER_0]
0076 cmp %g0, %sp
0077 fmovs \reg, \reg
0078 be restore_registers
0079 nop
0080 cmp %g0, %g0
0081 fmovs \reg, \reg
0082 bne restore_registers
0083 nop
0084 ld [%sp + FRAME_OFFSET_BUFFER_0], %o1
0085 cmp %g1, %o1
0086 bne restore_registers
0087 nop
0088 .endm
0089
0090 .macro write_register reg
0091 add %g1, 1, %g1
0092 mov %g1, \reg
0093 .endm
0094
0095 .macro write_float_register reg
0096 add %g1, 1, %g1
0097 st %g1, [%sp + FRAME_OFFSET_BUFFER_0]
0098 ld [%sp + FRAME_OFFSET_BUFFER_0], \reg
0099 .endm
0100
0101 .align 4
0102 PUBLIC(_CPU_Context_validate)
0103 SYM(_CPU_Context_validate):
0104
0105
0106 #if defined(SPARC_USE_LAZY_FP_SWITCH)
0107 ld [%g6 + PER_CPU_OFFSET_EXECUTING], %g2
0108 ld [%g2 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %g2
0109 #else
0110 mov %psr, %g2
0111 sethi %hi(SPARC_PSR_EF_MASK), %g3
0112 and %g2, %g3, %g2
0113 #endif
0114
0115
0116 mov %o0, %g1
0117
0118
0119 clr %g4
0120
0121 add %sp, -FRAME_SIZE, %sp
0122
0123 st %l0, [%sp + FRAME_OFFSET_L0]
0124 st %l1, [%sp + FRAME_OFFSET_L1]
0125 st %l2, [%sp + FRAME_OFFSET_L2]
0126 st %l3, [%sp + FRAME_OFFSET_L3]
0127 st %l4, [%sp + FRAME_OFFSET_L4]
0128 st %l5, [%sp + FRAME_OFFSET_L5]
0129 st %l6, [%sp + FRAME_OFFSET_L6]
0130 st %l7, [%sp + FRAME_OFFSET_L7]
0131 st %i0, [%sp + FRAME_OFFSET_I0]
0132 st %i1, [%sp + FRAME_OFFSET_I1]
0133 st %i2, [%sp + FRAME_OFFSET_I2]
0134 st %i3, [%sp + FRAME_OFFSET_I3]
0135 st %i4, [%sp + FRAME_OFFSET_I4]
0136 st %i5, [%sp + FRAME_OFFSET_I5]
0137 st %i6, [%sp + FRAME_OFFSET_I6]
0138 st %i7, [%sp + FRAME_OFFSET_I7]
0139
0140 cmp %g4, 0
0141 bne write_locals_and_outputs
0142 nop
0143 be check_for_fp
0144 nop
0145
0146 new_check_cycle:
0147 clr %g4
0148 add %g4, 1, %g4
0149 ld [%sp + FRAME_OFFSET_BUFFER_1], %g1
0150 b switch_to_next_window
0151 nop
0152
0153
0154 check_for_fp:
0155 cmp %g2, 0
0156 be write_y
0157 nop
0158
0159
0160 st %fsr, [%sp + FRAME_OFFSET_BUFFER_0]
0161 ld [%sp + FRAME_OFFSET_BUFFER_0], %o1
0162 add %g1, 1, %g1
0163 sethi %hi(FSR_PATTERN_MASK), %g3
0164 or %g3, %lo(FSR_PATTERN_MASK), %g3
0165 and %g1, %g3, %g3
0166 or %o1, %g3, %g3
0167 st %g3, [%sp + FRAME_OFFSET_BUFFER_0]
0168 ld [%sp + FRAME_OFFSET_BUFFER_0], %fsr
0169
0170 write_float_register %f0
0171 write_float_register %f1
0172 write_float_register %f2
0173 write_float_register %f3
0174 write_float_register %f4
0175 write_float_register %f5
0176 write_float_register %f6
0177 write_float_register %f7
0178 write_float_register %f8
0179 write_float_register %f9
0180 write_float_register %f10
0181 write_float_register %f11
0182 write_float_register %f12
0183 write_float_register %f13
0184 write_float_register %f14
0185 write_float_register %f15
0186 write_float_register %f16
0187 write_float_register %f17
0188 write_float_register %f18
0189 write_float_register %f19
0190 write_float_register %f20
0191 write_float_register %f21
0192 write_float_register %f22
0193 write_float_register %f23
0194 write_float_register %f24
0195 write_float_register %f25
0196 write_float_register %f26
0197 write_float_register %f27
0198 write_float_register %f28
0199 write_float_register %f29
0200 write_float_register %f30
0201 write_float_register %f31
0202
0203 write_y:
0204 write_register %y
0205
0206 write_register %i0
0207 write_register %i1
0208 write_register %i2
0209 write_register %i3
0210 write_register %i4
0211 write_register %i5
0212
0213
0214 b write_locals_and_outputs
0215 nop
0216
0217 switch_to_next_window:
0218 save %sp, -FRAME_SIZE, %sp
0219
0220 write_locals_and_outputs:
0221
0222 write_register %l1
0223 write_register %l2
0224 write_register %l3
0225 write_register %l4
0226 write_register %l5
0227 write_register %l6
0228 write_register %l7
0229 write_register %o1
0230 write_register %o2
0231 write_register %o3
0232 write_register %o4
0233 write_register %o5
0234
0235
0236
0237 add %g4, 1, %g4
0238 cmp %g4, 1
0239 bne no_store
0240 nop
0241 st %g1, [%sp + FRAME_OFFSET_BUFFER_1]
0242
0243 no_store:
0244 cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
0245 bne switch_to_next_window
0246 nop
0247
0248
0249 add %g1, 1, %g1
0250 clr %g4
0251
0252
0253 window_checking:
0254 cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
0255 be y_checking
0256 nop
0257
0258 further_checking:
0259 cmp %g4, 0
0260 bne goto_local_registers
0261 nop
0262
0263
0264 check_register %o5
0265 check_register %o4
0266 check_register %o3
0267 check_register %o2
0268 check_register %o1
0269
0270 goto_local_registers:
0271 check_register %l7
0272 check_register %l6
0273 check_register %l5
0274 check_register %l4
0275 check_register %l3
0276 check_register %l2
0277 check_register %l1
0278
0279 check_register %i5
0280 check_register %i4
0281 check_register %i3
0282 check_register %i2
0283 check_register %i1
0284
0285
0286
0287
0288 add %g4, 1, %g4
0289 cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
0290 bne dont_check_i0
0291 nop
0292 check_register %i0
0293 b y_checking
0294 nop
0295
0296 dont_check_i0:
0297 restore
0298
0299 ba window_checking
0300 nop
0301
0302
0303 y_checking:
0304 st %o1, [%sp + FRAME_OFFSET_BUFFER_2]
0305 mov %y, %o1
0306 check_register %o1
0307 ld [%sp + FRAME_OFFSET_BUFFER_2], %o1
0308 cmp %g2, 0
0309 be new_check_cycle
0310 nop
0311
0312 st %o1, [%sp + FRAME_OFFSET_BUFFER_2]
0313 SPARC_LEON3FT_B2BST_NOP
0314
0315 check_float_register %f31
0316 check_float_register %f30
0317 check_float_register %f29
0318 check_float_register %f28
0319 check_float_register %f27
0320 check_float_register %f26
0321 check_float_register %f25
0322 check_float_register %f24
0323 check_float_register %f23
0324 check_float_register %f22
0325 check_float_register %f21
0326 check_float_register %f20
0327 check_float_register %f19
0328 check_float_register %f18
0329 check_float_register %f17
0330 check_float_register %f16
0331 check_float_register %f15
0332 check_float_register %f14
0333 check_float_register %f13
0334 check_float_register %f12
0335 check_float_register %f11
0336 check_float_register %f10
0337 check_float_register %f9
0338 check_float_register %f8
0339 check_float_register %f7
0340 check_float_register %f6
0341 check_float_register %f5
0342 check_float_register %f4
0343 check_float_register %f3
0344 check_float_register %f2
0345 check_float_register %f1
0346 check_float_register %f0
0347
0348 st %fsr, [%sp + FRAME_OFFSET_BUFFER_0]
0349 ld [%sp + FRAME_OFFSET_BUFFER_0], %o1
0350 sub %g1, 1, %g1
0351 clr %g3
0352 sethi %hi(FSR_PATTERN_MASK), %g3
0353 or %g3, %lo(FSR_PATTERN_MASK), %g3
0354 and %g1, %g3, %g3
0355 and %o1, %g3, %o1
0356 cmp %o1, %g3
0357 bne restore_registers
0358 ld [%sp + FRAME_OFFSET_BUFFER_2], %o1
0359
0360 b new_check_cycle
0361 nop
0362
0363
0364
0365
0366
0367 restore_registers:
0368 and %g4, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %g4
0369 cmp %g4, 0
0370 be real_restore
0371 nop
0372 restore
0373 sub %g4, 1, %g4
0374 bne restore_registers
0375 nop
0376
0377 real_restore:
0378 ld [%sp + FRAME_OFFSET_L0], %l0
0379 ld [%sp + FRAME_OFFSET_L1], %l1
0380 ld [%sp + FRAME_OFFSET_L2], %l2
0381 ld [%sp + FRAME_OFFSET_L3], %l3
0382 ld [%sp + FRAME_OFFSET_L4], %l4
0383 ld [%sp + FRAME_OFFSET_L5], %l5
0384 ld [%sp + FRAME_OFFSET_L6], %l6
0385 ld [%sp + FRAME_OFFSET_L7], %l7
0386 ld [%sp + FRAME_OFFSET_I0], %i0
0387 ld [%sp + FRAME_OFFSET_I1], %i1
0388 ld [%sp + FRAME_OFFSET_I2], %i2
0389 ld [%sp + FRAME_OFFSET_I3], %i3
0390 ld [%sp + FRAME_OFFSET_I4], %i4
0391 ld [%sp + FRAME_OFFSET_I5], %i5
0392 ld [%sp + FRAME_OFFSET_I6], %i6
0393 ld [%sp + FRAME_OFFSET_I7], %i7
0394
0395 sub %sp, -FRAME_SIZE, %sp
0396
0397 return_value:
0398
0399 jmp %o7 + 8
0400 add %sp, FRAME_SIZE, %sp