2 * M68K Schedule functions
5 #include <exec/execbase.h>
6 #include <exec/alerts.h>
7 #include <proto/exec.h>
8 #include <defines/kernel.h>
10 #include <kernel_base.h>
11 #include <kernel_debug.h>
12 #include <kernel_scheduler.h>
22 extern void cpu_Exception(void);
26 " .globl cpu_Exception\n"
28 " movem.l %d0-%d1/%a0-%a1/%a6,%sp@-\n"
30 " jsr %a6@(-1 * 6 * 11 /* Exception */)\n"
31 " movem.l %sp@+,%d0-%d1/%a0-%a1/%a6\n"
35 void cpu_Switch(regs_t
*regs
)
37 struct Task
*task
= SysBase
->ThisTask
;
38 struct AROSCPUContext
*ctx
= task
->tc_UnionETask
.tc_ETask
->et_RegFrame
;
40 /* Actually save the context */
41 CopyMem(regs
, &ctx
->cpu
, sizeof(regs_t
));
43 /* If we have an FPU, save the FPU context */
44 if (SysBase
->AttnFlags
& AFF_FPU
)
45 AROS_UFC2NR(void, FpuSaveContext
,
46 AROS_UFCA(struct FpuContext
*, &ctx
->fpu
, A0
),
47 AROS_UFCA(UWORD
, (SysBase
->AttnFlags
& AFF_68060
) ? 2 : 0, D0
));
50 task
->tc_SPReg
= (APTR
)regs
->a
[7];
55 void cpu_Dispatch(regs_t
*regs
)
58 struct AROSCPUContext
*ctx
;
61 asm volatile ("ori #0x0700, %sr\n"); // Disable CPU interrupts
63 task
= core_Dispatch();
66 D(bug("-- IDLE HALT --\n"));
69 if (SysBase
->IDNestCnt
>= 0) {
70 SysBase
->IDNestCnt
=-1;
71 asm volatile ("move.w #0xc000,0xdff09a\n");
73 asm volatile ("stop #0x2000\n"); // Wait for an interrupt
76 ctx
= task
->tc_UnionETask
.tc_ETask
->et_RegFrame
;
77 CopyMem(&ctx
->cpu
, regs
, sizeof(regs_t
));
78 regs
->a
[7] = (IPTR
)task
->tc_SPReg
;
80 /* If we have an FPU, restore the FPU context */
81 if (SysBase
->AttnFlags
& AFF_FPU
)
82 AROS_UFC2NR(void, FpuRestoreContext
,
83 AROS_UFCA(struct FpuContext
*, &ctx
->fpu
, A0
),
84 AROS_UFCA(UWORD
, (SysBase
->AttnFlags
& AFF_68060
) ? 2 : 0, D0
));
86 /* Re-enable interrupts if needed */
87 if (SysBase
->IDNestCnt
< 0) {
88 asm volatile ("move.w #0xc000,0xdff09a\n");
90 asm volatile ("move.w #0x4000,0xdff09a\n");
93 if (task
->tc_Flags
& TF_EXCEPT
) {
94 /* Exec_Exception() will Enable() */
97 /* Manipulate the current CPU context so Exec_Exception gets
98 * executed after we leave Supervisor mode.
100 task
->tc_SPReg
-= sizeof(ULONG
); /* RTS to original PC */
101 if (task
->tc_SPReg
<= task
->tc_SPLower
)
102 Alert(AT_DeadEnd
|AN_StackProbe
);
103 *(ULONG
*)(task
->tc_SPReg
) = regs
->pc
;
105 regs
->a
[7] = (IPTR
)task
->tc_SPReg
;
106 regs
->pc
= (IPTR
)cpu_Exception
;