Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 67 additions & 19 deletions arch/m68k-all/exec/dispatch.S
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
/*
Copyright © 2012, The AROS Development Team. All rights reserved.
$Id$

Desc: Dispatch()
Lang: english

These routines are the core of the m68k scheduling system
*/
/* Restore an m68k task context directly from its saved user-stack frame. */

#include "aros/m68k/asm.h"

Expand All @@ -17,15 +9,71 @@

.func AROS_SLIB_ENTRY(Dispatch,Exec,10)
AROS_SLIB_ENTRY(Dispatch,Exec,10):
lea.l %sp@(-4*(8+8)),%sp /* %sp = regs_t */
move.l %sp,%sp@- /* Push regs_t * onto stack */
__Dispatch_this:
jsr cpu_Dispatch /* Call cpu_Dispatch */
addq.l #4,%sp
movem.l %sp@+,%d0-%d7/%a0-%a5 /* Load task state */
move.l %sp@(4),%a6
move.l %a6,%usp /* Restore user stack pointer */
move.l %sp@,%a6 /* Restore A6 */
addq.l #8,%sp
rte /* SR, PC, etc are on the stack */
/* A6 may still contain the caller's library base here. */
move.l 4,%a6
ori.w #0x0700,%sr

/* Fast path for the ordinary head-of-ready-list dispatch. */
lea.l TaskReady(%a6),%a0
move.l %a0@,%a3
move.l %a3@,%d0
beq.s 1f
cmp.b #TS_READY,tc_State(%a3)
bne.s 1f
move.b tc_Flags(%a3),%d1
and.b #TF_DISPATCH_SPECIAL,%d1
bne.s 1f
move.w AttnFlags(%a6),%d1
and.w #AFF_FPU,%d1
bne.s 1f

move.l %d0,%a0@
move.l %d0,%a1
move.l %a0,ln_Pred(%a1)
addq.l #1,DispCount(%a6)
move.l %a3,ThisTask(%a6)
move.w Quantum(%a6),Elapsed(%a6)
/* SFF_QuantumOver is bit 14 of SysFlags: bit 6 of its first byte */
bclr.b #6,SysFlags(%a6)
move.b #TS_RUN,tc_State(%a3)
move.b tc_IDNestCnt(%a3),IDNestCnt(%a6)
move.l tc_SPReg(%a3),%a5
bra.s 2f

1:
jsr m68k_DispatchFrame
move.l %d0,%a5
move.l ThisTask(%a6),%a3

2:
tst.b IDNestCnt(%a6)
bmi.s 3f
move.w #0x4000,0xdff09a
bra.s 4f
3:
move.w #0xc000,0xdff09a
4:
/*
* Enter the task through ex_LaunchPoint, as Kickstart's Dispatch()
* does: A3 is the task, A5 its saved frame and A6 SysBase. Programs
* hook the field to see each task being launched and chain to the
* address they found there, so the first dispatch publishes the
* default launch code below.
*/
move.l LaunchPoint(%a6),%d0
bne.s 5f
lea.l %pc@(6f),%a4
move.l %a4,LaunchPoint(%a6)
bra.s 6f
5:
move.l %d0,%a4
jmp (%a4)
6:
lea.l %a5@(66),%a2
move.l %a2,%usp
move.l %a5@+,%sp@-
move.w %a5@+,%sp@-
movem.l %a5@,%d0-%d7/%a0-%a6
rte
.endfunc
10 changes: 5 additions & 5 deletions arch/m68k-all/exec/exec_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ struct Exec_PlatformData
#define TDNESTCOUNT_DEC SysBase->TDNestCnt--
#define FLAG_SCHEDQUANTUM_CLEAR SysBase->SysFlags &= ~SFF_QuantumOver
#define FLAG_SCHEDQUANTUM_SET SysBase->SysFlags |= SFF_QuantumOver
#define FLAG_SCHEDSWITCH_CLEAR SysBase->AttnResched &= ~ARF_AttnSwitch
#define FLAG_SCHEDSWITCH_SET SysBase->AttnResched |= ARF_AttnSwitch
#define FLAG_SCHEDSWITCH_CLEAR SysBase->SysFlags &= ~SFF_AttnSwitch
#define FLAG_SCHEDSWITCH_SET SysBase->SysFlags |= SFF_AttnSwitch
#define FLAG_SCHEDDISPATCH_CLEAR SysBase->AttnResched &= ~ARF_AttnDispatch
#define FLAG_SCHEDDISPATCH_SET SysBase->AttnResched |= ARF_AttnDispatch
#else
Expand All @@ -33,8 +33,8 @@ struct Exec_PlatformData
#define TDNESTCOUNT_DEC AROS_ATOMIC_DEC(SysBase->TDNestCnt)
#define FLAG_SCHEDQUANTUM_CLEAR AROS_ATOMIC_AND(SysBase->SysFlags, ~SFF_QuantumOver)
#define FLAG_SCHEDQUANTUM_SET AROS_ATOMIC_OR(SysBase->SysFlags, SFF_QuantumOver)
#define FLAG_SCHEDSWITCH_CLEAR AROS_ATOMIC_AND(SysBase->AttnResched, ~ARF_AttnSwitch)
#define FLAG_SCHEDSWITCH_SET AROS_ATOMIC_OR(SysBase->AttnResched, ARF_AttnSwitch)
#define FLAG_SCHEDSWITCH_CLEAR AROS_ATOMIC_AND(SysBase->SysFlags, ~SFF_AttnSwitch)
#define FLAG_SCHEDSWITCH_SET AROS_ATOMIC_OR(SysBase->SysFlags, SFF_AttnSwitch)
#define FLAG_SCHEDDISPATCH_CLEAR AROS_ATOMIC_AND(SysBase->AttnResched, ~ARF_AttnDispatch)
#define FLAG_SCHEDDISPATCH_SET AROS_ATOMIC_OR(SysBase->AttnResched, ARF_AttnDispatch)
#endif
Expand All @@ -47,7 +47,7 @@ struct Exec_PlatformData
#define TDNESTCOUNT_GET (SysBase->TDNestCnt)
#define TDNESTCOUNT_SET(val) (SysBase->TDNestCnt=(val))
#define FLAG_SCHEDQUANTUM_ISSET (SysBase->SysFlags & SFF_QuantumOver)
#define FLAG_SCHEDSWITCH_ISSET (SysBase->AttnResched & ARF_AttnSwitch)
#define FLAG_SCHEDSWITCH_ISSET (SysBase->SysFlags & SFF_AttnSwitch)
#define FLAG_SCHEDDISPATCH_ISSET (SysBase->AttnResched & ARF_AttnDispatch)

#define GET_THIS_TASK (SysBase->ThisTask)
Expand Down
9 changes: 6 additions & 3 deletions arch/m68k-all/exec/exitintr.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright © 2012, The AROS Development Team. All rights reserved.
Copyright © 2012-2026, The AROS Development Team. All rights reserved.
$Id$

Desc: ExitIntr()
Expand All @@ -16,9 +16,12 @@

.func AROS_SLIB_ENTRY(ExitIntr,Exec,6)
AROS_SLIB_ENTRY(ExitIntr,Exec,6):
/* At this point, %d0-%d1/%a0-%a1/%a5-%a6 are on
* the stack, followed by SR, PC, and an exception frame
/* Kickstart's entry contract: the interrupt handler jumped here
* through the library vector with SysBase pushed on the stack.
* Below it are %d0-%d1/%a0-%a1/%a5-%a6, followed by SR, PC, and
* an exception frame.
*/
move.l %sp@+,%a6

/* If we are returning to supervisor mode, just do it.
* %sp@(4*6) is the SR from the RTE.
Expand Down
109 changes: 45 additions & 64 deletions arch/m68k-all/exec/preparecontext.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
/*
Copyright � 1995-2011, The AROS Development Team. All rights reserved.
$Id$

Desc: PrepareContext() - Prepare a task context for dispatch, m68k version
Lang: english
*/
/* Prepare the initial task frame in the format used by Switch/Dispatch. */

#include <exec/execbase.h>
#include <exec/memory.h>
#include <utility/tagitem.h>
#include <aros/m68k/cpucontext.h>
#include <proto/kernel.h>
#include <string.h>

#include "exec_intern.h"
#include "exec_util.h"

#define _PUSH(sp, val) *--sp = (IPTR)val
#define _PUSH(sp, val) *--sp = (IPTR)(val)
#define M68K_TASK_FRAME_SIZE 66

BOOL PrepareContext(struct Task *task, APTR entryPoint, APTR fallBack,
const struct TagItem *tagList, struct ExecBase *SysBase)
Expand All @@ -24,74 +20,59 @@ BOOL PrepareContext(struct Task *task, APTR entryPoint, APTR fallBack,
WORD numargs = 0;
IPTR *sp = task->tc_SPReg;
struct ExceptionContext *ctx;
UBYTE *frame;

if (!(task->tc_Flags & TF_ETASK))
return FALSE;

ctx = KrnCreateContext();
task->tc_UnionETask.tc_ETask->et_RegFrame = ctx;
if (!ctx)
return FALSE;

while(tagList)
{
switch(tagList->ti_Tag)
{
case TAG_MORE:
tagList = (const struct TagItem *)tagList->ti_Data;
continue;

case TAG_SKIP:
tagList += tagList->ti_Data;
break;

case TAG_DONE:
tagList = NULL;
break;

#define HANDLEARG(x) \
case TASKTAG_ARG ## x: \
args[x - 1] = (IPTR)tagList->ti_Data; \
if (x > numargs) numargs = x; \
break;

HANDLEARG(1)
HANDLEARG(2)
HANDLEARG(3)
HANDLEARG(4)
HANDLEARG(5)
HANDLEARG(6)
HANDLEARG(7)
HANDLEARG(8)
while (tagList) {
switch (tagList->ti_Tag) {
case TAG_MORE:
tagList = (const struct TagItem *)tagList->ti_Data;
continue;
case TAG_SKIP:
tagList += tagList->ti_Data;
break;
case TAG_DONE:
tagList = NULL;
break;
#define HANDLEARG(x) \
case TASKTAG_ARG ## x: \
args[x - 1] = (IPTR)tagList->ti_Data; \
if (x > numargs) numargs = x; \
break;
HANDLEARG(1)
HANDLEARG(2)
HANDLEARG(3)
HANDLEARG(4)
HANDLEARG(5)
HANDLEARG(6)
HANDLEARG(7)
HANDLEARG(8)
}

if (tagList) tagList++;
if (tagList)
tagList++;
}

/*
There is not much to do here, or at least that is how it
appears. Most of the work is done in the kernel_cpu.h macros.
*/

if (numargs)
{
/* On m68k C function gets all param on stack */
while(numargs--)
{
_PUSH(sp, args[numargs]);
}
}

/* First we push the return address */
while (numargs--)
_PUSH(sp, args[numargs]);
_PUSH(sp, fallBack);

/* Then set up the frame to be used by Dispatch() */
ctx->pc = (IPTR)entryPoint;
ctx->a[7] = (IPTR)sp;
ctx->sr = 0x0000;

/* We return the new stack pointer back to the caller. */
task->tc_SPReg = sp;
frame = (UBYTE *)sp - M68K_TASK_FRAME_SIZE;
memset(frame, 0, M68K_TASK_FRAME_SIZE);
*(IPTR *)(frame + 0) = (IPTR)entryPoint;
*(UWORD *)(frame + 4) = 0;

/* Retain a conventional context for FPU/AMMX storage and diagnostics. */
ctx->pc = (IPTR)entryPoint;
ctx->a[7] = (IPTR)sp;
ctx->sr = 0;

task->tc_SPReg = frame;
return TRUE;
} /* PrepareContext() */
}
9 changes: 8 additions & 1 deletion arch/m68k-all/exec/schedule.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright © 2012, The AROS Development Team. All rights reserved.
Copyright © 2012-2026, The AROS Development Team. All rights reserved.
$Id$

Desc: Schedule()
Expand All @@ -19,6 +19,13 @@
AROS_SLIB_ENTRY(Schedule,Exec,7):
movem.l %d0-%d1/%a0-%a1/%a5-%a6,%sp@- /* Save D0-D1/A0-A1 */
__Schedule_this:
/*
* Decide with interrupts masked, as Kickstart's Schedule() does:
* core_Schedule() clears SFF_AttnSwitch and looks at TaskReady, and
* an interrupt in between could set the flag or queue a task. Switch
* lowers the level again; otherwise the RTE restores it.
*/
or.w #0x0700,%sr
jsr core_Schedule
tst.w %d0 /* Something to do? */
movem.l %sp@+,%d0-%d1/%a0-%a1/%a5-%a6 /* Restore regs */
Expand Down
Loading