File indexing completed on 2025-05-11 08:24:24
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
0029
0030
0031
0032
0033
0034 #ifdef HAVE_CONFIG_H
0035 #include "config.h"
0036 #endif
0037
0038 #include <rtems/asm.h>
0039 #include <rtems/score/percpu.h>
0040
0041
0042
0043
0044
0045
0046 .align 4
0047 .global SYM (_CPU_Context_switch)
0048
0049 .set RUNCONTEXT_ARG, 4 | save context argument
0050 .set HEIRCONTEXT_ARG, 8 | restore context argument
0051
0052 SYM (_CPU_Context_switch):
0053 moval a7@(RUNCONTEXT_ARG),a0| a0 = running thread context
0054 movw sr,d1 | d1 = status register
0055 movml d1-d7/a2-a7,a0@ | save context
0056
0057 moval a7@(HEIRCONTEXT_ARG),a0| a0 = heir thread context
0058
0059 #if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 )
0060 moveb a0@(13*4),d0 | get context specific DF bit info in d0
0061 btstb #4,d0 | test context specific DF bit info
0062 beq fpu_on | branch if FPU needs to be switched on
0063
0064 fpu_off: movl _CPU_cacr_shadow,d0 | get content of _CPU_cacr_shadow in d0
0065 btstl #4,d0 | test DF bit info in d0
0066 bne restore | branch if FPU is already switched off
0067 bsetl #4,d0 | set DF bit in d0
0068 bra cacr_set | branch to set the new FPU setting in cacr and _CPU_cacr_shadow
0069
0070 fpu_on: movl _CPU_cacr_shadow,d0 | get content of _CPU_cacr_shadow in d1
0071 btstl #4,d0 | test context specific DF bit info
0072 beq restore | branch if FPU is already switched on
0073 bclrl #4,d0 | clear DF bit info in d0
0074
0075 cacr_set: movew sr,d1 | get content of sr in d1
0076 oril #0x00000700,d1 | mask d1
0077 movew d1,sr | disable all interrupts
0078 movl d0,_CPU_cacr_shadow | move _CPU_cacr_shadow to d1
0079 movec d0,cacr | enable FPU in cacr
0080 #endif
0081
0082
0083 restore: movml a0@,d1-d7/a2-a7 | restore context
0084 movw d1,sr | restore status register
0085 rts
0086
0087 .global SYM (_CPU_Context_Restart_self)
0088 .set CONTEXT_ARG, 4 | context arg
0089
0090 #if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 )
0091
0092
0093
0094 #warning "_CPU_Context_Restart_self restoring FPU context not implemented"
0095 #endif
0096 SYM(_CPU_Context_Restart_self):
0097 moval a7@(CONTEXT_ARG),a0
0098 bra restore
0099
0100
0101
0102
0103
0104
0105
0106
0107 #if ( CPU_HARDWARE_FP == TRUE )
0108
0109 .set FPCONTEXT_ARG, 4 | save FP context argument
0110
0111 .align 4
0112 .global SYM (_CPU_Context_save_fp)
0113 SYM (_CPU_Context_save_fp):
0114
0115
0116 moval a7@(FPCONTEXT_ARG), a1
0117 moval a1@, a0
0118
0119 #if defined( __mcoldfire__ )
0120
0121 movel macsr, d0
0122 clrl d1
0123 movl d1, macsr
0124
0125
0126 movl acc0, d1
0127 moveml d0-d1, a0@(0)
0128
0129
0130 movl acc1, d0
0131 movl acc2, d1
0132 moveml d0-d1, a0@(8)
0133
0134
0135 movl acc3, d0
0136 movl accext01, d1
0137 moveml d0-d1, a0@(16)
0138
0139
0140 movl accext23, d0
0141 movl mask, d1
0142 moveml d0-d1, a0@(24)
0143
0144 #if ( M68K_HAS_FPU == 1 )
0145
0146 fsave a0@(32)
0147
0148
0149 fmovel fpi, a0@(48)
0150
0151
0152 fmovem fp0-fp7, a0@(52)
0153 #endif
0154 #else
0155 #if defined( __mc68060__ )
0156 lea a0@(-M68K_FP_STATE_SIZE), a0
0157 fsave a0@ | save 68060 state frame
0158 #else
0159 fsave a0@- | save 68881/68882 state frame
0160 #endif
0161 tstb a0@ | check for a null frame
0162 beq.b nosv | Yes, skip save of user model
0163 fmovem fp0-fp7, a0@- | save data registers (fp0-fp7)
0164 fmovem fpc/fps/fpi, a0@- | and save control registers
0165 movl #-1, a0@- | place not-null flag on stack
0166 nosv:
0167 movl a0, a1@ | save pointer to saved context
0168 #endif
0169
0170
0171 rts
0172
0173 .align 4
0174 .global SYM (_CPU_Context_restore_fp)
0175 SYM (_CPU_Context_restore_fp):
0176
0177
0178 moval a7@(FPCONTEXT_ARG), a1
0179 moval a1@, a0
0180
0181 #if defined( __mcoldfire__ )
0182 #if ( M68K_HAS_FPU == 1 )
0183
0184 fmovem a0@(52), fp0-fp7
0185
0186
0187 fmovel a0@(48), fpi
0188
0189
0190 frestore a0@(32)
0191 #endif
0192
0193
0194 clrl d0
0195 movl d0, macsr
0196
0197
0198 moveml a0@(24), d0-d1
0199 movl d0, mask
0200 movl d1, accext23
0201
0202
0203 moveml a0@(16), d0-d1
0204 movl d0, accext01
0205 movl d1, acc3
0206
0207
0208 moveml a0@(8), d0-d1
0209 movl d0, acc2
0210 movl d1, acc1
0211
0212
0213 moveml a0@(0), d0-d1
0214 movl d0, acc0
0215 movl d1, macsr
0216 #else
0217 tstb a0@ | Null context frame?
0218 beq.b norst | Yes, skip fp restore
0219 addql #4, a0 | throwaway non-null flag
0220 fmovem a0@+, fpc/fps/fpi | restore control registers
0221 fmovem a0@+, fp0-fp7 | restore data regs (fp0-fp7)
0222 norst:
0223 #if defined( __mc68060__ )
0224 frestore a0@ | restore 68060 state frame
0225 lea a0@(M68K_FP_STATE_SIZE), a0
0226 #else
0227 frestore a0@+ | restore 68881/68882 state frame
0228 #endif
0229 movl a0, a1@ | save pointer to saved context
0230 #endif
0231
0232
0233 rts
0234 #endif
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 #if ( defined(__mcoldfire__) )
0250 .set SR_OFFSET, 2 | Status register offset
0251 .set PC_OFFSET, 4 | Program Counter offset
0252 .set FVO_OFFSET, 0 | Format/vector offset
0253 #elif ( M68K_HAS_VBR == 1)
0254 .set SR_OFFSET, 0 | Status register offset
0255 .set PC_OFFSET, 2 | Program Counter offset
0256 .set FVO_OFFSET, 6 | Format/vector offset
0257 #else
0258 .set SR_OFFSET, 2 | Status register offset
0259 .set PC_OFFSET, 4 | Program Counter offset
0260 .set FVO_OFFSET, 0 | Format/vector offset placed in the stack
0261 #endif
0262
0263 .set SAVED, 16 | space for saved registers
0264
0265 .align 4
0266 .global SYM (_ISR_Handler)
0267
0268 SYM (_ISR_Handler):
0269 | disable multitasking
0270 addql #1,THREAD_DISPATCH_DISABLE_LEVEL
0271 #if ( !defined(__mcoldfire__) )
0272 moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
0273 #else
0274 lea a7@(-SAVED),a7
0275 movm.l d0-d1/a0-a1,a7@ | save d0-d1,a0-a1
0276 #endif
0277 movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
0278 andl #0x03fc,d0 | d0 = vector offset in vbr
0279
0280
0281 #if ( M68K_HAS_SEPARATE_STACKS == 0 )
0282 | Make a0 point just above interrupt stack
0283 movel INTERRUPT_STACK_HIGH,a0
0284 cmpl INTERRUPT_STACK_LOW,a7 | stack below interrupt stack?
0285 bcs.b 1f | yes, switch to interrupt stack
0286 cmpl a0,a7 | stack above interrupt stack?
0287 bcs.b 2f | no, do not switch stacks
0288 1:
0289 movel a7,a1 | copy task stack pointer
0290 movel a0,a7 | switch to interrupt stack
0291 movel a1,a7@- | store task stack pointer
0292 | on interrupt stack
0293 2:
0294 #endif
0295
0296 addql #1,ISR_NEST_LEVEL | one nest level deeper
0297
0298 lea SYM(_ISR_Vector_table),a0
0299 movel (a0,d0),a0 | a0 = address of user routine
0300
0301 lsrl #2,d0 | d0 = vector number
0302 movel d0,a7@- | push vector number
0303 jbsr a0@ | invoke the user ISR
0304 addql #4,a7 | remove vector number
0305 subql #1,ISR_NEST_LEVEL | Reduce interrupt-nesting count
0306
0307 #if ( M68K_HAS_SEPARATE_STACKS == 0 )
0308 movel INTERRUPT_STACK_HIGH,a0
0309 subql #4,a0
0310 cmpl a0,a7 | At top of interrupt stack?
0311 bne.b 1f | No, do not restore task stack pointer
0312 movel (a7),a7 | Restore task stack pointer
0313 1:
0314 #endif
0315 subql #1,THREAD_DISPATCH_DISABLE_LEVEL
0316 | unnest multitasking
0317 bne.b exit | If dispatch disabled, exit
0318
0319 #if ( M68K_HAS_SEPARATE_STACKS == 1 )
0320 movew #0xf000,d0 | isolate format nibble
0321 andw a7@(SAVED+FVO_OFFSET),d0 | get F/VO
0322 cmpiw #0x1000,d0 | is it a throwaway isf?
0323 bne.b exit | NOT outer level, so branch
0324 #else
0325
0326
0327
0328
0329
0330
0331
0332 #if ( !defined(__mcoldfire__) && !__mc68060__ )
0333 cmpl #_ISR_Handler,a7@(SAVED+PC_OFFSET)
0334 beq.b exit
0335 #endif
0336 #endif
0337 tstb DISPATCH_NEEDED
0338 | Is thread switch necessary?
0339 beq.b exit | No, then exit
0340
0341 bframe:
0342 | If sent, will be processed
0343 #if ( M68K_HAS_SEPARATE_STACKS == 1 )
0344 movec msp,a0 | a0 = master stack pointer
0345 movew #0,a0@- | push format word
0346 movel #thread_dispatch,a0@- | push return addr
0347 movew a0@(6),a0@- | push saved sr
0348 movec a0,msp | set master stack pointer
0349 #else
0350 jsr SYM (_Thread_Dispatch) | Perform context switch
0351 #endif
0352
0353 #if ( !defined(__mcoldfire__) )
0354 exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
0355 #else
0356 exit: moveml a7@,d0-d1/a0-a1 | restore d0-d1,a0-a1
0357 lea a7@(SAVED),a7
0358 #endif
0359
0360 #if ( M68K_HAS_VBR == 0 )
0361 addql #2,a7 | pop format/id
0362 #endif
0363 rte | return to thread
0364 | OR _Isr_dispatch
0365
0366 #if ( M68K_HAS_SEPARATE_STACKS == 1 )
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 thread_dispatch:
0380 #if ( !defined(__mcoldfire__) )
0381 movml d0-d1/a0-a1,a7@-
0382 jsr SYM (_Thread_Dispatch)
0383 movml a7@+,d0-d1/a0-a1
0384 #else
0385 lea a7@(-SAVED),a7
0386 movml d0-d1/a0-a1,a7@
0387 jsr SYM (_Thread_Dispatch)
0388 movml a7@,d0-d1/a0-a1
0389 lea a7@(SAVED),a7
0390 #endif
0391
0392 #if ( M68K_HAS_VBR == 0 )
0393 addql #2,a7 | pop format/id
0394 #endif
0395 rte
0396 #endif