forked from Imagelibrary/rtems
sparc: Move _CPU_Context_switch(), etc.
Move the _CPU_Context_switch(), _CPU_Context_restore() and _CPU_Context_switch_to_first_task_smp() code since the method to obtain the processor index is BSP specific.
This commit is contained in:
@@ -41,6 +41,230 @@
|
|||||||
#endif /* defined( RTEMS_SMP ) */
|
#endif /* defined( RTEMS_SMP ) */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void _CPU_Context_switch(
|
||||||
|
* Context_Control *run,
|
||||||
|
* Context_Control *heir
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* This routine performs a normal non-FP context switch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
PUBLIC(_CPU_Context_switch)
|
||||||
|
SYM(_CPU_Context_switch):
|
||||||
|
! skip g0
|
||||||
|
st %g1, [%o0 + G1_OFFSET] ! save the global registers
|
||||||
|
std %g2, [%o0 + G2_OFFSET]
|
||||||
|
std %g4, [%o0 + G4_OFFSET]
|
||||||
|
std %g6, [%o0 + G6_OFFSET]
|
||||||
|
|
||||||
|
! load the address of the ISR stack nesting prevention flag
|
||||||
|
sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %g2
|
||||||
|
ld [%g2 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %g2
|
||||||
|
! save it a bit later so we do not waste a couple of cycles
|
||||||
|
|
||||||
|
std %l0, [%o0 + L0_OFFSET] ! save the local registers
|
||||||
|
std %l2, [%o0 + L2_OFFSET]
|
||||||
|
std %l4, [%o0 + L4_OFFSET]
|
||||||
|
std %l6, [%o0 + L6_OFFSET]
|
||||||
|
|
||||||
|
! Now actually save ISR stack nesting prevention flag
|
||||||
|
st %g2, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET]
|
||||||
|
|
||||||
|
std %i0, [%o0 + I0_OFFSET] ! save the input registers
|
||||||
|
std %i2, [%o0 + I2_OFFSET]
|
||||||
|
std %i4, [%o0 + I4_OFFSET]
|
||||||
|
std %i6, [%o0 + I6_FP_OFFSET]
|
||||||
|
|
||||||
|
std %o0, [%o0 + O0_OFFSET] ! save the output registers
|
||||||
|
std %o2, [%o0 + O2_OFFSET]
|
||||||
|
std %o4, [%o0 + O4_OFFSET]
|
||||||
|
std %o6, [%o0 + O6_SP_OFFSET]
|
||||||
|
|
||||||
|
rd %psr, %o2
|
||||||
|
st %o2, [%o0 + PSR_OFFSET] ! save status register
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is entered from _CPU_Context_restore with:
|
||||||
|
* o1 = context to restore
|
||||||
|
* o2 = psr
|
||||||
|
*/
|
||||||
|
|
||||||
|
PUBLIC(_CPU_Context_restore_heir)
|
||||||
|
SYM(_CPU_Context_restore_heir):
|
||||||
|
/*
|
||||||
|
* Flush all windows with valid contents except the current one.
|
||||||
|
* In examining the set register windows, one may logically divide
|
||||||
|
* the windows into sets (some of which may be empty) based on their
|
||||||
|
* current status:
|
||||||
|
*
|
||||||
|
* + current (i.e. in use),
|
||||||
|
* + used (i.e. a restore would not trap)
|
||||||
|
* + invalid (i.e. 1 in corresponding bit in WIM)
|
||||||
|
* + unused
|
||||||
|
*
|
||||||
|
* Either the used or unused set of windows may be empty.
|
||||||
|
*
|
||||||
|
* NOTE: We assume only one bit is set in the WIM at a time.
|
||||||
|
*
|
||||||
|
* Given a CWP of 5 and a WIM of 0x1, the registers are divided
|
||||||
|
* into sets as follows:
|
||||||
|
*
|
||||||
|
* + 0 - invalid
|
||||||
|
* + 1-4 - unused
|
||||||
|
* + 5 - current
|
||||||
|
* + 6-7 - used
|
||||||
|
*
|
||||||
|
* In this case, we only would save the used windows -- 6 and 7.
|
||||||
|
*
|
||||||
|
* Traps are disabled for the same logical period as in a
|
||||||
|
* flush all windows trap handler.
|
||||||
|
*
|
||||||
|
* Register Usage while saving the windows:
|
||||||
|
* g1 = current PSR
|
||||||
|
* g2 = current wim
|
||||||
|
* g3 = CWP
|
||||||
|
* g4 = wim scratch
|
||||||
|
* g5 = scratch
|
||||||
|
*/
|
||||||
|
|
||||||
|
ld [%o1 + PSR_OFFSET], %g1 ! g1 = saved psr
|
||||||
|
|
||||||
|
and %o2, SPARC_PSR_CWP_MASK, %g3 ! g3 = CWP
|
||||||
|
! g1 = psr w/o cwp
|
||||||
|
andn %g1, SPARC_PSR_ET_MASK | SPARC_PSR_CWP_MASK, %g1
|
||||||
|
or %g1, %g3, %g1 ! g1 = heirs psr
|
||||||
|
mov %g1, %psr ! restore status register and
|
||||||
|
! **** DISABLE TRAPS ****
|
||||||
|
mov %wim, %g2 ! g2 = wim
|
||||||
|
mov 1, %g4
|
||||||
|
sll %g4, %g3, %g4 ! g4 = WIM mask for CW invalid
|
||||||
|
|
||||||
|
save_frame_loop:
|
||||||
|
sll %g4, 1, %g5 ! rotate the "wim" left 1
|
||||||
|
srl %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4
|
||||||
|
or %g4, %g5, %g4 ! g4 = wim if we do one restore
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a restore would not underflow, then continue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
andcc %g4, %g2, %g0 ! Any windows to flush?
|
||||||
|
bnz done_flushing ! No, then continue
|
||||||
|
nop
|
||||||
|
|
||||||
|
restore ! back one window
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now save the window just as if we overflowed to it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
|
||||||
|
std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
|
||||||
|
std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
|
||||||
|
std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
|
||||||
|
|
||||||
|
std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
|
||||||
|
std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
|
||||||
|
std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
|
||||||
|
std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
|
||||||
|
|
||||||
|
ba save_frame_loop
|
||||||
|
nop
|
||||||
|
|
||||||
|
done_flushing:
|
||||||
|
|
||||||
|
add %g3, 1, %g3 ! calculate desired WIM
|
||||||
|
and %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
|
||||||
|
mov 1, %g4
|
||||||
|
sll %g4, %g3, %g4 ! g4 = new WIM
|
||||||
|
mov %g4, %wim
|
||||||
|
|
||||||
|
or %g1, SPARC_PSR_ET_MASK, %g1
|
||||||
|
mov %g1, %psr ! **** ENABLE TRAPS ****
|
||||||
|
! and restore CWP
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
! skip g0
|
||||||
|
ld [%o1 + G1_OFFSET], %g1 ! restore the global registers
|
||||||
|
ldd [%o1 + G2_OFFSET], %g2
|
||||||
|
ldd [%o1 + G4_OFFSET], %g4
|
||||||
|
ldd [%o1 + G6_OFFSET], %g6
|
||||||
|
|
||||||
|
! Load thread specific ISR dispatch prevention flag
|
||||||
|
ld [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2
|
||||||
|
sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %o3
|
||||||
|
! Store it to memory later to use the cycles
|
||||||
|
|
||||||
|
ldd [%o1 + L0_OFFSET], %l0 ! restore the local registers
|
||||||
|
ldd [%o1 + L2_OFFSET], %l2
|
||||||
|
ldd [%o1 + L4_OFFSET], %l4
|
||||||
|
ldd [%o1 + L6_OFFSET], %l6
|
||||||
|
|
||||||
|
! Now restore thread specific ISR dispatch prevention flag
|
||||||
|
st %o2,[%o3 + %lo(SYM(_CPU_ISR_Dispatch_disable))]
|
||||||
|
|
||||||
|
ldd [%o1 + I0_OFFSET], %i0 ! restore the output registers
|
||||||
|
ldd [%o1 + I2_OFFSET], %i2
|
||||||
|
ldd [%o1 + I4_OFFSET], %i4
|
||||||
|
ldd [%o1 + I6_FP_OFFSET], %i6
|
||||||
|
|
||||||
|
ldd [%o1 + O2_OFFSET], %o2 ! restore the output registers
|
||||||
|
ldd [%o1 + O4_OFFSET], %o4
|
||||||
|
ldd [%o1 + O6_SP_OFFSET], %o6
|
||||||
|
! do o0/o1 last to avoid destroying heir context pointer
|
||||||
|
ldd [%o1 + O0_OFFSET], %o0 ! overwrite heir pointer
|
||||||
|
|
||||||
|
jmp %o7 + 8 ! return
|
||||||
|
nop ! delay slot
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void _CPU_Context_restore(
|
||||||
|
* Context_Control *new_context
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* This routine is generally used only to perform restart self.
|
||||||
|
*
|
||||||
|
* NOTE: It is unnecessary to reload some registers.
|
||||||
|
*/
|
||||||
|
.align 4
|
||||||
|
PUBLIC(_CPU_Context_restore)
|
||||||
|
SYM(_CPU_Context_restore):
|
||||||
|
save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp
|
||||||
|
rd %psr, %o2
|
||||||
|
ba SYM(_CPU_Context_restore_heir)
|
||||||
|
mov %i0, %o1 ! in the delay slot
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
/*
|
||||||
|
* void _CPU_Context_switch_to_first_task_smp(
|
||||||
|
* Context_Control *new_context
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* This routine is only used to switch to the first task on a
|
||||||
|
* secondary core in an SMP configuration. We do not need to
|
||||||
|
* flush any windows and, in fact, this can be dangerous
|
||||||
|
* as they may or may not be initialized properly. So we just
|
||||||
|
* reinitialize the PSR and WIM.
|
||||||
|
*/
|
||||||
|
PUBLIC(_CPU_Context_switch_to_first_task_smp)
|
||||||
|
SYM(_CPU_Context_switch_to_first_task_smp):
|
||||||
|
mov %psr, %g1 ! Turn of traps when modifying WIM
|
||||||
|
andn %g1, SPARC_PSR_ET_MASK, %g1
|
||||||
|
mov %g1, %psr
|
||||||
|
/* WIM and PSR will be set in done_flushing, it need args:
|
||||||
|
* g1=PSR, g3=CWP, o1=Context
|
||||||
|
*/
|
||||||
|
and %g1, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
|
||||||
|
nop
|
||||||
|
mov %o0, %o1 ! in the delay slot
|
||||||
|
ba,a done_flushing
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void _ISR_Handler()
|
* void _ISR_Handler()
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -128,228 +128,4 @@ SYM(_CPU_Context_restore_fp):
|
|||||||
|
|
||||||
#endif /* SPARC_HAS_FPU */
|
#endif /* SPARC_HAS_FPU */
|
||||||
|
|
||||||
/*
|
|
||||||
* void _CPU_Context_switch(
|
|
||||||
* Context_Control *run,
|
|
||||||
* Context_Control *heir
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* This routine performs a normal non-FP context switch.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
PUBLIC(_CPU_Context_switch)
|
|
||||||
SYM(_CPU_Context_switch):
|
|
||||||
! skip g0
|
|
||||||
st %g1, [%o0 + G1_OFFSET] ! save the global registers
|
|
||||||
std %g2, [%o0 + G2_OFFSET]
|
|
||||||
std %g4, [%o0 + G4_OFFSET]
|
|
||||||
std %g6, [%o0 + G6_OFFSET]
|
|
||||||
|
|
||||||
! load the address of the ISR stack nesting prevention flag
|
|
||||||
sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %g2
|
|
||||||
ld [%g2 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %g2
|
|
||||||
! save it a bit later so we do not waste a couple of cycles
|
|
||||||
|
|
||||||
std %l0, [%o0 + L0_OFFSET] ! save the local registers
|
|
||||||
std %l2, [%o0 + L2_OFFSET]
|
|
||||||
std %l4, [%o0 + L4_OFFSET]
|
|
||||||
std %l6, [%o0 + L6_OFFSET]
|
|
||||||
|
|
||||||
! Now actually save ISR stack nesting prevention flag
|
|
||||||
st %g2, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET]
|
|
||||||
|
|
||||||
std %i0, [%o0 + I0_OFFSET] ! save the input registers
|
|
||||||
std %i2, [%o0 + I2_OFFSET]
|
|
||||||
std %i4, [%o0 + I4_OFFSET]
|
|
||||||
std %i6, [%o0 + I6_FP_OFFSET]
|
|
||||||
|
|
||||||
std %o0, [%o0 + O0_OFFSET] ! save the output registers
|
|
||||||
std %o2, [%o0 + O2_OFFSET]
|
|
||||||
std %o4, [%o0 + O4_OFFSET]
|
|
||||||
std %o6, [%o0 + O6_SP_OFFSET]
|
|
||||||
|
|
||||||
rd %psr, %o2
|
|
||||||
st %o2, [%o0 + PSR_OFFSET] ! save status register
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is entered from _CPU_Context_restore with:
|
|
||||||
* o1 = context to restore
|
|
||||||
* o2 = psr
|
|
||||||
*/
|
|
||||||
|
|
||||||
PUBLIC(_CPU_Context_restore_heir)
|
|
||||||
SYM(_CPU_Context_restore_heir):
|
|
||||||
/*
|
|
||||||
* Flush all windows with valid contents except the current one.
|
|
||||||
* In examining the set register windows, one may logically divide
|
|
||||||
* the windows into sets (some of which may be empty) based on their
|
|
||||||
* current status:
|
|
||||||
*
|
|
||||||
* + current (i.e. in use),
|
|
||||||
* + used (i.e. a restore would not trap)
|
|
||||||
* + invalid (i.e. 1 in corresponding bit in WIM)
|
|
||||||
* + unused
|
|
||||||
*
|
|
||||||
* Either the used or unused set of windows may be empty.
|
|
||||||
*
|
|
||||||
* NOTE: We assume only one bit is set in the WIM at a time.
|
|
||||||
*
|
|
||||||
* Given a CWP of 5 and a WIM of 0x1, the registers are divided
|
|
||||||
* into sets as follows:
|
|
||||||
*
|
|
||||||
* + 0 - invalid
|
|
||||||
* + 1-4 - unused
|
|
||||||
* + 5 - current
|
|
||||||
* + 6-7 - used
|
|
||||||
*
|
|
||||||
* In this case, we only would save the used windows -- 6 and 7.
|
|
||||||
*
|
|
||||||
* Traps are disabled for the same logical period as in a
|
|
||||||
* flush all windows trap handler.
|
|
||||||
*
|
|
||||||
* Register Usage while saving the windows:
|
|
||||||
* g1 = current PSR
|
|
||||||
* g2 = current wim
|
|
||||||
* g3 = CWP
|
|
||||||
* g4 = wim scratch
|
|
||||||
* g5 = scratch
|
|
||||||
*/
|
|
||||||
|
|
||||||
ld [%o1 + PSR_OFFSET], %g1 ! g1 = saved psr
|
|
||||||
|
|
||||||
and %o2, SPARC_PSR_CWP_MASK, %g3 ! g3 = CWP
|
|
||||||
! g1 = psr w/o cwp
|
|
||||||
andn %g1, SPARC_PSR_ET_MASK | SPARC_PSR_CWP_MASK, %g1
|
|
||||||
or %g1, %g3, %g1 ! g1 = heirs psr
|
|
||||||
mov %g1, %psr ! restore status register and
|
|
||||||
! **** DISABLE TRAPS ****
|
|
||||||
mov %wim, %g2 ! g2 = wim
|
|
||||||
mov 1, %g4
|
|
||||||
sll %g4, %g3, %g4 ! g4 = WIM mask for CW invalid
|
|
||||||
|
|
||||||
save_frame_loop:
|
|
||||||
sll %g4, 1, %g5 ! rotate the "wim" left 1
|
|
||||||
srl %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4
|
|
||||||
or %g4, %g5, %g4 ! g4 = wim if we do one restore
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If a restore would not underflow, then continue.
|
|
||||||
*/
|
|
||||||
|
|
||||||
andcc %g4, %g2, %g0 ! Any windows to flush?
|
|
||||||
bnz done_flushing ! No, then continue
|
|
||||||
nop
|
|
||||||
|
|
||||||
restore ! back one window
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now save the window just as if we overflowed to it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
|
|
||||||
std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
|
|
||||||
std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
|
|
||||||
std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
|
|
||||||
|
|
||||||
std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
|
|
||||||
std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
|
|
||||||
std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
|
|
||||||
std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
|
|
||||||
|
|
||||||
ba save_frame_loop
|
|
||||||
nop
|
|
||||||
|
|
||||||
done_flushing:
|
|
||||||
|
|
||||||
add %g3, 1, %g3 ! calculate desired WIM
|
|
||||||
and %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
|
|
||||||
mov 1, %g4
|
|
||||||
sll %g4, %g3, %g4 ! g4 = new WIM
|
|
||||||
mov %g4, %wim
|
|
||||||
|
|
||||||
or %g1, SPARC_PSR_ET_MASK, %g1
|
|
||||||
mov %g1, %psr ! **** ENABLE TRAPS ****
|
|
||||||
! and restore CWP
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
! skip g0
|
|
||||||
ld [%o1 + G1_OFFSET], %g1 ! restore the global registers
|
|
||||||
ldd [%o1 + G2_OFFSET], %g2
|
|
||||||
ldd [%o1 + G4_OFFSET], %g4
|
|
||||||
ldd [%o1 + G6_OFFSET], %g6
|
|
||||||
|
|
||||||
! Load thread specific ISR dispatch prevention flag
|
|
||||||
ld [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2
|
|
||||||
sethi %hi(SYM(_CPU_ISR_Dispatch_disable)), %o3
|
|
||||||
! Store it to memory later to use the cycles
|
|
||||||
|
|
||||||
ldd [%o1 + L0_OFFSET], %l0 ! restore the local registers
|
|
||||||
ldd [%o1 + L2_OFFSET], %l2
|
|
||||||
ldd [%o1 + L4_OFFSET], %l4
|
|
||||||
ldd [%o1 + L6_OFFSET], %l6
|
|
||||||
|
|
||||||
! Now restore thread specific ISR dispatch prevention flag
|
|
||||||
st %o2,[%o3 + %lo(SYM(_CPU_ISR_Dispatch_disable))]
|
|
||||||
|
|
||||||
ldd [%o1 + I0_OFFSET], %i0 ! restore the output registers
|
|
||||||
ldd [%o1 + I2_OFFSET], %i2
|
|
||||||
ldd [%o1 + I4_OFFSET], %i4
|
|
||||||
ldd [%o1 + I6_FP_OFFSET], %i6
|
|
||||||
|
|
||||||
ldd [%o1 + O2_OFFSET], %o2 ! restore the output registers
|
|
||||||
ldd [%o1 + O4_OFFSET], %o4
|
|
||||||
ldd [%o1 + O6_SP_OFFSET], %o6
|
|
||||||
! do o0/o1 last to avoid destroying heir context pointer
|
|
||||||
ldd [%o1 + O0_OFFSET], %o0 ! overwrite heir pointer
|
|
||||||
|
|
||||||
jmp %o7 + 8 ! return
|
|
||||||
nop ! delay slot
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void _CPU_Context_restore(
|
|
||||||
* Context_Control *new_context
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* This routine is generally used only to perform restart self.
|
|
||||||
*
|
|
||||||
* NOTE: It is unnecessary to reload some registers.
|
|
||||||
*/
|
|
||||||
.align 4
|
|
||||||
PUBLIC(_CPU_Context_restore)
|
|
||||||
SYM(_CPU_Context_restore):
|
|
||||||
save %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp
|
|
||||||
rd %psr, %o2
|
|
||||||
ba SYM(_CPU_Context_restore_heir)
|
|
||||||
mov %i0, %o1 ! in the delay slot
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
#if defined(RTEMS_SMP)
|
|
||||||
/*
|
|
||||||
* void _CPU_Context_switch_to_first_task_smp(
|
|
||||||
* Context_Control *new_context
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* This routine is only used to switch to the first task on a
|
|
||||||
* secondary core in an SMP configuration. We do not need to
|
|
||||||
* flush any windows and, in fact, this can be dangerous
|
|
||||||
* as they may or may not be initialized properly. So we just
|
|
||||||
* reinitialize the PSR and WIM.
|
|
||||||
*/
|
|
||||||
PUBLIC(_CPU_Context_switch_to_first_task_smp)
|
|
||||||
SYM(_CPU_Context_switch_to_first_task_smp):
|
|
||||||
mov %psr, %g1 ! Turn of traps when modifying WIM
|
|
||||||
andn %g1, SPARC_PSR_ET_MASK, %g1
|
|
||||||
mov %g1, %psr
|
|
||||||
/* WIM and PSR will be set in done_flushing, it need args:
|
|
||||||
* g1=PSR, g3=CWP, o1=Context
|
|
||||||
*/
|
|
||||||
and %g1, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
|
|
||||||
nop
|
|
||||||
mov %o0, %o1 ! in the delay slot
|
|
||||||
ba,a done_flushing
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|||||||
Reference in New Issue
Block a user