From 79aaf64fcf7ffa61b8adbeef270d572542e73dc3 Mon Sep 17 00:00:00 2001 From: jmcmullan Date: Fri, 20 Jul 2012 04:52:32 +0000 Subject: [PATCH] arch/m68k-amiga: Vastly reduce interrupt latency Signed-off-by: Jason S. McMullan git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@45269 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/m68k-all/exec/dispatch.S | 31 ++++++ arch/m68k-all/exec/exec_platform.c | 28 +++++ arch/m68k-all/exec/exitintr.S | 42 ++++++++ arch/m68k-all/exec/mmakefile.src | 3 +- arch/m68k-all/exec/schedule.S | 27 +++++ arch/m68k-all/exec/stackswap.S | 23 ---- arch/m68k-all/exec/supervisor.S | 9 -- arch/m68k-all/exec/switch.S | 25 +++++ arch/m68k-all/include/aros/cpucontext.h | 5 +- arch/m68k-all/kernel/dispatch.c | 53 ++++++++++ arch/m68k-all/kernel/kernel_cpu.h | 70 ++++--------- arch/m68k-all/kernel/kernel_intr.c | 44 ++++++++ arch/m68k-all/kernel/m68k_exception.c | 180 ++++++++++++-------------------- arch/m68k-all/kernel/m68k_exception.h | 4 +- arch/m68k-all/kernel/mmakefile.src | 3 +- arch/m68k-all/kernel/schedule.c | 52 +++++++++ arch/m68k-all/kernel/switch.c | 54 ++++++++++ arch/m68k-amiga/exec/mmakefile.src | 2 +- arch/m68k-amiga/exec/reschedule.c | 84 +++++++++++++++ arch/m68k-amiga/kernel/amiga_irq.c | 104 ++++++++---------- arch/m68k-amiga/kernel/cause.c | 54 ++++++++++ arch/m68k-amiga/kernel/dispatch.c | 52 +++++++++ arch/m68k-amiga/kernel/mmakefile.src | 2 +- rom/exec/dispatch.c | 59 +++++++++++ rom/exec/exec.conf | 12 ++- rom/exec/exitintr.c | 59 +++++++++++ rom/exec/mmakefile.src | 9 +- rom/exec/schedule.c | 59 +++++++++++ rom/exec/switch.c | 59 +++++++++++ rom/exec/traphandler.c | 6 +- 30 files changed, 936 insertions(+), 278 deletions(-) create mode 100644 arch/m68k-all/exec/dispatch.S create mode 100644 arch/m68k-all/exec/exec_platform.c create mode 100644 arch/m68k-all/exec/exitintr.S create mode 100644 arch/m68k-all/exec/schedule.S create mode 100644 arch/m68k-all/exec/switch.S create mode 100644 arch/m68k-all/kernel/dispatch.c rewrite arch/m68k-all/kernel/kernel_cpu.h (61%) create mode 100644 arch/m68k-all/kernel/kernel_intr.c create mode 100644 arch/m68k-all/kernel/schedule.c create mode 100644 arch/m68k-all/kernel/switch.c create mode 100644 arch/m68k-amiga/exec/reschedule.c create mode 100644 arch/m68k-amiga/kernel/cause.c create mode 100644 arch/m68k-amiga/kernel/dispatch.c create mode 100644 rom/exec/dispatch.c create mode 100644 rom/exec/exitintr.c create mode 100644 rom/exec/schedule.c create mode 100644 rom/exec/switch.c diff --git a/arch/m68k-all/exec/dispatch.S b/arch/m68k-all/exec/dispatch.S new file mode 100644 index 0000000000..c33929839c --- /dev/null +++ b/arch/m68k-all/exec/dispatch.S @@ -0,0 +1,31 @@ +/* + Copyright © 2012, The AROS Development Team. All rights reserved. + $Id$ + + Desc: Dispatch() + Lang: english + + These routines are the core of the m68k scheduling system +*/ + +#include "aros/m68k/asm.h" + + .text + .balign 4 + .globl AROS_SLIB_ENTRY(Dispatch,Exec,10) + .globl __Dispatch_this + + .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 */ + .endfunc diff --git a/arch/m68k-all/exec/exec_platform.c b/arch/m68k-all/exec/exec_platform.c new file mode 100644 index 0000000000..85807a576e --- /dev/null +++ b/arch/m68k-all/exec/exec_platform.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011, The AROS Development Team. All rights reserved. + * Author: Jason S. McMullan + * + * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 + * + */ + +#include +#include +#include + +extern VOID AROS_SLIB_ENTRY(ExitIntr, Exec, 6)(VOID); +extern VOID AROS_SLIB_ENTRY(Schedule, Exec, 7)(VOID); +extern VOID AROS_SLIB_ENTRY(Switch, Exec, 9)(VOID); +extern VOID AROS_SLIB_ENTRY(Dispatch, Exec, 10)(VOID); + +static int Exec_init_platform(struct ExecBase *lh) +{ + __AROS_SETVECADDR(lh, 6, AROS_SLIB_ENTRY(ExitIntr, Exec, 6)); + __AROS_SETVECADDR(lh, 7, AROS_SLIB_ENTRY(Schedule, Exec, 7)); + __AROS_SETVECADDR(lh, 9, AROS_SLIB_ENTRY(Switch, Exec, 9)); + __AROS_SETVECADDR(lh,10, AROS_SLIB_ENTRY(Dispatch, Exec,10)); + + return TRUE; +} + +ADD2INITLIB(Exec_init_platform,0) diff --git a/arch/m68k-all/exec/exitintr.S b/arch/m68k-all/exec/exitintr.S new file mode 100644 index 0000000000..d46e6c9403 --- /dev/null +++ b/arch/m68k-all/exec/exitintr.S @@ -0,0 +1,42 @@ +/* + Copyright © 2012, The AROS Development Team. All rights reserved. + $Id$ + + Desc: ExitIntr() + Lang: english + + These routines are the core of the m68k scheduling system +*/ + +#include "aros/m68k/asm.h" + + .text + .balign 4 + .globl AROS_SLIB_ENTRY(ExitIntr,Exec,6) + + .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 + */ + + /* If we are returning to supervisor mode, just do it. + * %sp@(4*6) is the SR from the RTE. + * We want to test bit 12 (0x2000) of the SR. + * But BTST only tests a byte. Therefore, we + * only need to test bit 5 (0x20) of the upper + * byte of SR, which is at %sp@(4*6) + */ + btst.b #5,%sp@(4*6) + bne 0f + + /* + * Determine whether we need to call the Scheduler + */ + jsr core_ExitIntr + tst.w %d0 + bne __Schedule_this +0: + movem.l %sp@+,%d0-%d1/%a0-%a1/%a5-%a6 + rte + .endfunc diff --git a/arch/m68k-all/exec/mmakefile.src b/arch/m68k-all/exec/mmakefile.src index 28957c7cae..f0da4c1dc6 100644 --- a/arch/m68k-all/exec/mmakefile.src +++ b/arch/m68k-all/exec/mmakefile.src @@ -6,6 +6,7 @@ FILES=offsets getcc preparecontext \ cachecontrol setfunction copymem alert_cpu AFILES=newstackswap stackswap \ + exitintr schedule switch dispatch \ supervisor superstate userstate \ forbid \ cacheclearu_ cachecleare_ cachepostdma_ cachepredma_ \ @@ -14,7 +15,7 @@ AFILES=newstackswap stackswap \ copymem_ copymemquick USER_CFLAGS := $(PRIV_EXEC_INCLUDES) -USER_AFLAGS := -I$(GENINCDIR) -DDoRegisterCalls -m68060 +USER_AFLAGS := -I$(GENINCDIR) -m68060 %build_archspecific \ mainmmake=kernel-exec maindir=rom/exec \ diff --git a/arch/m68k-all/exec/schedule.S b/arch/m68k-all/exec/schedule.S new file mode 100644 index 0000000000..8b5d2d0b03 --- /dev/null +++ b/arch/m68k-all/exec/schedule.S @@ -0,0 +1,27 @@ +/* + Copyright © 2012, The AROS Development Team. All rights reserved. + $Id$ + + Desc: Schedule() + Lang: english + + These routines are the core of the m68k scheduling system +*/ + +#include "aros/m68k/asm.h" + + .text + .balign 4 + .globl AROS_SLIB_ENTRY(Schedule,Exec,7) + .globl __Schedule_this + + .func AROS_SLIB_ENTRY(Schedule,Exec,7) +AROS_SLIB_ENTRY(Schedule,Exec,7): + movem.l %d0-%d1/%a0-%a1/%a5-%a6,%sp@- /* Save D0-D1/A0-A1 */ +__Schedule_this: + jsr core_Schedule + tst.w %d0 /* Something to do? */ + movem.l %sp@+,%d0-%d1/%a0-%a1/%a5-%a6 /* Restore regs */ + bne AROS_SLIB_ENTRY(Switch,Exec,9) + rte + .endfunc diff --git a/arch/m68k-all/exec/stackswap.S b/arch/m68k-all/exec/stackswap.S index b3e5adf58d..5764e25d1d 100644 --- a/arch/m68k-all/exec/stackswap.S +++ b/arch/m68k-all/exec/stackswap.S @@ -49,15 +49,9 @@ AROS_SLIB_ENTRY(StackSwap,Exec,122): // Here's how the stack looks right now // 0(%sp) : Return Address -#ifndef DoRegisterCalls - // 4(%sp) : pointer to StackSwap structure -#endif /* Preserve returnaddress and fix sp */ move.l (%sp)+,%d1 // d1 contains return address -#ifndef DoRegisterCalls - move.l (%sp)+,%a0 // a0 holds param to this function -#endif // now the stack is 'clean' move.l %a6,%sp@- // save contents of %a6 @@ -72,14 +66,8 @@ AROS_SLIB_ENTRY(StackSwap,Exec,122): movem.l %d0/%a0/%a1,%sp@- // d0: save return address on stack // a0: param to this function onto stack // a1: address of task to stack -#ifndef DoRegisterCalls - move.l %a6,-(%sp) // a6: Execbase onto stack -#endif /* Just to be sure interrupts always find a good stackframe */ jsr Disable(%a6) // disable interrupts -#ifndef DoRegisterCalls - move.l %sp@+,%a6 // a6: Execbase from stack -#endif movem.l %sp@+,%d0/%a0/%a1 // a1 holds address of task // a0 holds param to this function // d0 holds return address @@ -108,20 +96,9 @@ AROS_SLIB_ENTRY(StackSwap,Exec,122): /* Reenable interrupts. */ move.l 0x4,%a6 // get ExecBase -#ifndef DoRegisterCalls - move.l %a6,%sp@- // ExecBase onto stack -#endif jsr Enable(%a6) // Enable interrupts -#ifndef DoRegisterCalls - move.l %sp@+,%a6 // dummy -#endif movem.l %sp@+,%d0/%a6 // restore orig. content of %a6 register // restore return address to d0 - -#ifndef DoRegisterCalls - move.l #0,%sp@- // write fake parameter to this function - // onto stack -#endif /* Restore returnaddress and return */ move.l %d0,%sp@- // return address onto stack diff --git a/arch/m68k-all/exec/supervisor.S b/arch/m68k-all/exec/supervisor.S index b9b5ac542b..b5d6edfd9e 100644 --- a/arch/m68k-all/exec/supervisor.S +++ b/arch/m68k-all/exec/supervisor.S @@ -45,12 +45,10 @@ Kernel Effect ------------------------------------------------------------------- - i386 (under emulation) None m68k (native) Runs the process in supervisor mode. The process must end with an RTE instruction. It should save any registers which is uses. - m68k (under emulation) EXAMPLE @@ -81,10 +79,6 @@ .globl AROS_SLIB_ENTRY(Supervisor,Exec,5) .type AROS_SLIB_ENTRY(Supervisor,Exec,5),@function AROS_SLIB_ENTRY(Supervisor,Exec,5): -#ifndef DoRegisterCalls - move.l %a5,%sp@- - move.l %sp@(-8),%a5 -#endif /* CRITICAL SECTION - DO NOT USE THE STACK */ Exec_Supervisor_Entry: or.w #0x2000, %sr // Caused exception on 68000 @@ -101,9 +95,6 @@ Exec_Supervisor_Entry: jmp (%a5) Exec_Supervisor_Exit: /* END CRITICAL SECTION - CALLER'S STACK */ -#ifndef DoRegisterCalls - move.l %sp@+,%a5 -#endif rts /* 68000 privilege violation stack frame: diff --git a/arch/m68k-all/exec/switch.S b/arch/m68k-all/exec/switch.S new file mode 100644 index 0000000000..37d4fe82bb --- /dev/null +++ b/arch/m68k-all/exec/switch.S @@ -0,0 +1,25 @@ +/* + Copyright © 2012, The AROS Development Team. All rights reserved. + $Id$ + + Desc: Switch() + Lang: english + + These routines are the core of the m68k scheduling system +*/ + +#include "aros/m68k/asm.h" + + .text + .balign 4 + .globl AROS_SLIB_ENTRY(Switch,Exec,9) + + .func AROS_SLIB_ENTRY(Switch,Exec,9) +AROS_SLIB_ENTRY(Switch,Exec,9): + movem.l %d0-%d7/%a0-%a7,%sp@- + move.l %usp,%a0 + move.l %a0,%sp@(4*15) /* Fix up %a7 */ + move.l %sp,%sp@- /* Push regs_t * onto stack */ + jsr cpu_Switch /* Call cpu_Switch */ + bra __Dispatch_this /* Skip ahead */ + .endfunc diff --git a/arch/m68k-all/include/aros/cpucontext.h b/arch/m68k-all/include/aros/cpucontext.h index 64f139babd..e510c2e788 100644 --- a/arch/m68k-all/include/aros/cpucontext.h +++ b/arch/m68k-all/include/aros/cpucontext.h @@ -5,15 +5,12 @@ * We don't need ULONG Flags in this context, since the * SysBase->AttnFlags provides the CPU type information. */ - struct ExceptionContext { ULONG d[8]; IPTR a[8]; - IPTR trapcode; - ULONG traparg; UWORD sr; IPTR pc; -}; +} __attribute__((__packed__)); #endif diff --git a/arch/m68k-all/kernel/dispatch.c b/arch/m68k-all/kernel/dispatch.c new file mode 100644 index 0000000000..5cb1841438 --- /dev/null +++ b/arch/m68k-all/kernel/dispatch.c @@ -0,0 +1,53 @@ +#include + +#include +#include + +/***************************************************************************** + + NAME */ +#include + +AROS_LH0(void, KrnDispatch, + +/* SYNOPSIS */ + +/* LOCATION */ + struct KernelBase *, KernelBase, 4, Kernel) + +/* FUNCTION + Run the next available task + + INPUTS + None + + RESULT + None + + NOTES + This entry point directly calls task dispatch routine in supervisor mode. + It neither performs any checks of caller status nor obeys interrupt enable + state. After calling this function, caller's task will be replaced by + another one, and caller's state will be lost. + + This function is safe to call only from within user mode. + This function is considered internal, and not meant to be called + by user's software. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + /* The real implementation is in Exec/Dispatch */ + Supervisor(__AROS_GETVECADDR(SysBase,10)); + + AROS_LIBFUNC_EXIT +} diff --git a/arch/m68k-all/kernel/kernel_cpu.h b/arch/m68k-all/kernel/kernel_cpu.h dissimilarity index 61% index 1b313db470..4d008bda1e 100644 --- a/arch/m68k-all/kernel/kernel_cpu.h +++ b/arch/m68k-all/kernel/kernel_cpu.h @@ -1,47 +1,23 @@ -/* - * M68K CPU-specific definitions. - * - */ - -#ifndef KERNEL_CPU_H_ -#define KERNEL_CPU_H_ - -#include - -#include "cpu_m68k.h" - -/* User/supervisor mode switching */ -#define cpumode_t __unused int - -/* Only used on protected memory systems. On the - * m68k-amiga, these are unneeded. - */ -#define goSuper() (0) -#define goUser() do { } while (0) -#define goBack(mode) do { } while (0) - - -/* Syscalls use the F-line emulation trap, - * via instruction 'F405' (AROS), with - * %a0 set to 0x41524f53 ("AROS") - * %d0 is the syscall function to call - * %d1-%d7,%a1-%a6 are available for - * arguments. All registers *except* for - * %d0 are preserved. - * - * I would like to use 0xA405, but UAE stole - * all the A-Line instructions! - * - * I used to use 0xF405, but that is a valid - * instruction on the 68030. - */ -#define KRN_SYSCALL_INST 0xFF05 -#define KRN_SYSCALL_MAGIC 0x41524F53 -#define krnSysCall(x) asm volatile ( \ - "move.l %0,%%d0\n" \ - "move.l %2,%%a0\n" \ - ".word %c1\n" \ - : : "g" (x), "i" (KRN_SYSCALL_INST), "i" (KRN_SYSCALL_MAGIC) \ - : "%d0", "%a0"); - -#endif /* _KERNEL_CPU_H */ +/* + * M68K CPU-specific definitions. + * + */ + +#ifndef KERNEL_CPU_H_ +#define KERNEL_CPU_H_ + +#include + +#include "cpu_m68k.h" + +/* User/supervisor mode switching */ +#define cpumode_t __unused int + +/* Only used on protected memory systems. On the + * m68k-amiga, these are unneeded. + */ +#define goSuper() (0) +#define goUser() do { } while (0) +#define goBack(mode) do { } while (0) + +#endif /* _KERNEL_CPU_H */ diff --git a/arch/m68k-all/kernel/kernel_intr.c b/arch/m68k-all/kernel/kernel_intr.c new file mode 100644 index 0000000000..fb6deff4e8 --- /dev/null +++ b/arch/m68k-all/kernel/kernel_intr.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012, The AROS Development Team + * All right reserved. + * Author: Jason S. McMullan + * + * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 + */ + +#include +#include +#include + +#include +#include +#include +#include + +/* Called on leaveing the interrupt. + * This function returns TRUE if the task scheduler is needed. + */ +BOOL core_ExitIntr(VOID) +{ + /* Soft interrupt requested? It's high time to do it */ + if (SysBase->SysFlags & SFF_SoftInt) + core_Cause(INTB_SOFTINT, 1L << INTB_SOFTINT); + + /* If task switching is disabled, do nothing */ + if (SysBase->TDNestCnt < 0) + { + /* + * Do not disturb task if it's not necessary. + * Reschedule only if switch pending flag is set. Exit otherwise. + */ + if (SysBase->AttnResched & ARF_AttnSwitch) + { + /* Run task scheduling sequence */ + return TRUE; + } + } + + return FALSE; +} + + diff --git a/arch/m68k-all/kernel/m68k_exception.c b/arch/m68k-all/kernel/m68k_exception.c index b39671fd83..3dbdc288f6 100644 --- a/arch/m68k-all/kernel/m68k_exception.c +++ b/arch/m68k-all/kernel/m68k_exception.c @@ -9,6 +9,8 @@ #define DEBUG 0 #include #include +#include + #include #include #include @@ -215,62 +217,71 @@ static void M68KExceptionInit_10(struct ExecBase *SysBase) * When we call M68KExceptionAction: * Return PC (4) * Return SR (2) - * D0-D7/A0-A7 (16 * 4) <= NO TOUCHING! - * SysBase (4) A6 - * SP (4) D1 - * Exception Vector (4) D0 + * TrapArg (4) + * TrapCode (4) + * D0-D1/A0-A1 (4 * 4) <= NO TOUCHING! + * Pointer to trapcode/arg (4) + * Exception Vector (4) * * When we come back: - * Drop SysBase, SP, and Exception args - * Restore D0-D1/A0-A1/A6 - * Drop the Exception # word + * Restore D0-D1/A0-A1 + * Either execute the trap, or just return. * RTE */ extern void M68KExceptionHelper(void); asm ( - " .text\n" - " .globl M68KExceptionHelper\n" - "M68KExceptionHelper:\n" - " lea.l %sp@(-12),%sp\n" // Fix stack to below regs.a[6] - " move.l %a6,%sp@(0)\n" // Save A6 in regs.a[6] - " move.l %sp@(12),%a6\n" // Get Exception Id into A6 - " clr.l %sp@(12)\n" // Clear TrapCode arg - " move.l #0f,%sp@(8)\n" // Save default TrapCode - " move.l %a6,%sp@(4)\n" // Save Exception ID to regs.a[7] - " movem.l %d0-%d7/%a0-%a5,%sp@-\n"// Push everything - SP is now 'regs_t' - " move.l %sp@(15*4),%d1\n" // Exception Id (regs.a[7]) - " move.l %usp,%a0\n" - " move.l %a0,%sp@(4*15)\n" // Fix up SP in regs as USP - " move.l %sp,%d0\n" // regs_t - " move.l 4, %a6\n" // Global SysBase - " move.l %a6, %sp@-\n" // Push SysBase - " move.l %d1, %sp@-\n" // Push Exception Id - " move.l %d0, %sp@-\n" // Push regs_t * - " jsr M68KExceptionAction\n" - " lea %sp@(12),%sp\n" // Drop all stack args - " movem.l %sp@+,%d0-%d7/%a0-%a5\n" // Restore all but a6 - " move.l %sp@(4),%a6\n" // Get USP from regs_t - " move.l %a6,%usp\n" // Set USP - " move.l %sp@+,%a6\n" // Restore A6 - " addq.l #4,%sp\n" // Pop off A7 - " tst.l %sp@\n" // New tasks have a NULL trapcode - " beq.s 1f\n" - " rts\n" // Execute tc_TrapCode - "1:\n" - " addq.l #4,%sp\n" - "0:\n" - " addq.l #4,%sp\n" // Drop TrapCode parameter - " rte\n" // And return + " .text\n" + " .globl M68KExceptionHelper\n" + "M68KExceptionHelper:\n" + " clr.l %sp@-\n" // Save space for tc + " movem.l %d0-%d1/%a0-%a1,%sp@-\n"// Save regs + " lea.l %sp@(4*(4)),%a0\n" // Get location of tc/ta + " move.l %sp@(4*(4+1)),%d0\n" // Get exception vector + " jsr M68KExceptionAction\n" // Call action routine + " movem.l %sp@+,%d0-%d1/%a0-%a1\n"// Restore regs + " tst.l %sp@\n" // NULL trapcode? Just return + " beq.s 1f\n" + " rts\n" // Execute tc_TrapCode + "1:\n" + " addq.l #4,%sp\n" + "0:\n" + " addq.l #4,%sp\n" // Drop TrapCode parameter + " rte\n" // And return ); /* Default handler */ extern void Exec_MagicResetCode(void); -void M68KExceptionHandler(regs_t *regs, int id, struct ExecBase *SysBase) +extern struct ExecBase *AbsExecBase; + +struct M68KTrapCode { + APTR trapcode; + ULONG traparg; +}; + +AROS_UFH2(VOID, M68KExceptionAction, + AROS_UFHA(ULONG, vector, D0), + AROS_UFHA(struct M68KTrapCode *, tc, A0)) { - VOID (*trapHandler)(ULONG, void *); + AROS_USERFUNC_INIT + + ULONG Id; + VOID (*Handler)(ULONG id); + + if (vector & 1) { + /* vector is really a pointer to a M68KException table entry */ + struct M68KException *Exception; + + Exception = (APTR)(vector & ~1); - if (SysBase == NULL || - KernelBase == NULL) { + Id = Exception->Id; + Handler = Exception->Handler; + } else { + Id = vector >> 2; + Handler = NULL; + } + +#if DEBUG + if (SysBase == NULL || KernelBase == NULL) { volatile LONG *LastAlert = (volatile LONG *)(64 * sizeof(LONG)); /* SysBase has been corrupted! Mark the alert, * and reboot. @@ -288,81 +299,18 @@ void M68KExceptionHandler(regs_t *regs, int id, struct ExecBase *SysBase) Exec_MagicResetCode(); return; } - - trapHandler = FindTask(NULL)->tc_TrapCode; - /* Call an AmigaOS trap handler, in supervisor - * mode, that *may* alter almost any of our - * registers, by abusing the stack frame - * via 'regs_t'. Whee! - */ - regs->trapcode = (IPTR)trapHandler; - regs->traparg = (ULONG)id; -} - -void M68KExceptionAction(regs_t *regs, ULONG vector, struct ExecBase *SysBase) -{ - int Id; - BOOL (*Handler)(regs_t *regs, int id, struct ExecBase *SysBase); - - if (vector & 1) { - /* vector is really a pointer to a M68KException table entry */ - struct M68KException *Exception; - - Exception = (APTR)(vector & ~1); - - Id = Exception->Id; - Handler = Exception->Handler; - } else { - Id = vector >> 2; - Handler = NULL; - } - -#ifdef AROS_DEBUG_STACK - if (KernelBase != NULL) { // Prevents early failure - if (regs->sr & 0x2000) { - if ((APTR)regs < (SysBase->SysStkLower+0x10) || (((APTR)regs)-1) > SysBase->SysStkUpper) { - D(bug("Supervisor: iStack overflow %p (%p-%p)\n", (APTR)regs, SysBase->SysStkLower, SysBase->SysStkUpper)); - D(bug("Exception: %d\n", Id)); - D(PRINT_CPU_CONTEXT(regs)); - Alert(AT_DeadEnd | AN_StackProbe); - } - } else { -#if 0 /* can't do this, in old times if was popular to reallocate new stacks manually.. */ - struct Task *t = SysBase->ThisTask; - if ((APTR)regs->a[7] < (t->tc_SPLower+0x10) || (APTR)(regs->a[7]-1) > t->tc_SPUpper) { - D(bug("[%s]: iStack overflow %p (%p-%p)\n", t->tc_Node.ln_Name, (APTR)regs->a[7], t->tc_SPLower, t->tc_SPUpper)); - D(bug("Exception: %d\n", Id)); - D(PRINT_CPU_CONTEXT(regs)); - Alert(AT_DeadEnd | AN_StackProbe); - } -#endif - } - } #endif - if (Handler == NULL || !Handler(regs, Id, SysBase)) - M68KExceptionHandler(regs, Id, SysBase); - -#ifdef AROS_DEBUG_STACK - if (KernelBase != NULL) { - if (regs->sr & 0x2000) { - if ((APTR)regs < (SysBase->SysStkLower+0x10) || (((APTR)regs)-1) > SysBase->SysStkUpper) { - D(bug("Supervisor: Stack overflow %p (%p-%p)\n", (APTR)regs, SysBase->SysStkLower, SysBase->SysStkUpper)); - D(bug("Exception: %d\n", Id)); - D(PRINT_CPU_CONTEXT(regs)); - Alert(AT_DeadEnd | AN_StackProbe); - } - } else { - struct Task *t = SysBase->ThisTask; - if ((APTR)regs->a[7] < (t->tc_SPLower+0x10) || (APTR)(regs->a[7]-1) > t->tc_SPUpper) { - D(bug("[%s]: Stack overflow %p (%p-%p)\n", t->tc_Node.ln_Name, (APTR)regs->a[7], t->tc_SPLower, t->tc_SPUpper)); - D(bug("Exception: %d\n", Id)); - D(PRINT_CPU_CONTEXT(regs)); - Alert(AT_DeadEnd | AN_StackProbe); - } - } + tc->traparg = Id; + if (!Handler) { + Handler = FindTask(NULL)->tc_TrapCode; + if (!Handler) { + Handler = SysBase->TaskTrapCode; + } } -#endif + tc->trapcode = Handler; + + AROS_USERFUNC_EXIT } /* We assume that the caller has already set up diff --git a/arch/m68k-all/kernel/m68k_exception.h b/arch/m68k-all/kernel/m68k_exception.h index ceaa4eaa69..d0dd83e9a4 100644 --- a/arch/m68k-all/kernel/m68k_exception.h +++ b/arch/m68k-all/kernel/m68k_exception.h @@ -54,8 +54,8 @@ */ struct M68KException { UWORD Id; - /* Returns TRUE if handled, FALSE if it didn't */ - BOOL (*Handler)(regs_t *regs, int id, struct ExecBase *SysBase); + /* tc_TrapCode style handler - MUST PRESERVE ALL REGISTERS! */ + void (*Handler)(ULONG id); }; void M68KExceptionInit(const struct M68KException *Table, struct ExecBase *SysBase); diff --git a/arch/m68k-all/kernel/mmakefile.src b/arch/m68k-all/kernel/mmakefile.src index d1f0e94651..cf53f972ef 100644 --- a/arch/m68k-all/kernel/mmakefile.src +++ b/arch/m68k-all/kernel/mmakefile.src @@ -1,7 +1,8 @@ # $Id$ include $(TOP)/config/make.cfg -FILES=m68k_exception kernel_cpu platform_init setprotection mapglobal mmu #kernel_gdb +FILES=dispatch schedule switch m68k_exception kernel_cpu kernel_intr \ + platform_init setprotection mapglobal mmu #kernel_gdb AFILES=issuper fpusavecontext fpurestorecontext buserror diff --git a/arch/m68k-all/kernel/schedule.c b/arch/m68k-all/kernel/schedule.c new file mode 100644 index 0000000000..18e2577344 --- /dev/null +++ b/arch/m68k-all/kernel/schedule.c @@ -0,0 +1,52 @@ +#include + +#include +#include + +/***************************************************************************** + + NAME */ +#include + +AROS_LH0(void, KrnSchedule, + +/* SYNOPSIS */ + +/* LOCATION */ + struct KernelBase *, KernelBase, 6, Kernel) + +/* FUNCTION + Run task scheduling sequence + + INPUTS + None + + RESULT + None + + NOTES + This entry point directly calls task scheduling routine + in supervisor mode. It neither performs any checks of caller status + nor obeys interrupt enable state. + + This function is safe to call only from within user mode. + This function is considered internal, and not meant to be called + by user's software. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + /* The real implementation is in Exec/Schedule */ + Supervisor(__AROS_GETVECADDR(SysBase,7)); + + AROS_LIBFUNC_EXIT +} diff --git a/arch/m68k-all/kernel/switch.c b/arch/m68k-all/kernel/switch.c new file mode 100644 index 0000000000..e21e86600f --- /dev/null +++ b/arch/m68k-all/kernel/switch.c @@ -0,0 +1,54 @@ +#include + +#include +#include + +/***************************************************************************** + + NAME */ +#include + +AROS_LH0(void, KrnSwitch, + +/* SYNOPSIS */ + +/* LOCATION */ + struct KernelBase *, KernelBase, 5, Kernel) + +/* FUNCTION + Save context of caller's task and dispatch the next available task + + INPUTS + None + + RESULT + None + + NOTES + This entry point directly calls task switch routine + in supervisor mode. It neither performs any checks of caller status + nor obeys interrupt enable state. After calling this function, caller's + task will be replaced by another one, and it's caller's responsibility + to do anything to prevent task loss. + + This function is safe to call only from within user mode. + This function is considered internal, and not meant to be called + by user's software. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + /* The real implementation is in Exec/Switch */ + Supervisor(__AROS_GETVECADDR(SysBase,9)); + + AROS_LIBFUNC_EXIT +} diff --git a/arch/m68k-amiga/exec/mmakefile.src b/arch/m68k-amiga/exec/mmakefile.src index 3215f5e982..0c1fc0649a 100644 --- a/arch/m68k-amiga/exec/mmakefile.src +++ b/arch/m68k-amiga/exec/mmakefile.src @@ -1,7 +1,7 @@ # $Id$ include $(TOP)/config/make.cfg -CFILES := coldreboot moveexecbase shutdowna exec_globals +CFILES := coldreboot moveexecbase shutdowna exec_globals reschedule AFILES := enable disable readgayle #MM kernel-exec : kernel-exec-amiga-m68k diff --git a/arch/m68k-amiga/exec/reschedule.c b/arch/m68k-amiga/exec/reschedule.c new file mode 100644 index 0000000000..89e147819a --- /dev/null +++ b/arch/m68k-amiga/exec/reschedule.c @@ -0,0 +1,84 @@ +/* + Copyright © 1995-2011, The AROS Development Team. All rights reserved. + $Id$ + + Desc: + Lang: english +*/ + +#include +#include +#include +#include +#include + +#include + +#include "exec_intern.h" + +/* Amiga(tm) custom chips MMIO area */ +#define _CUSTOM 0xDFF000 + +extern VOID AROS_SLIB_ENTRY(Schedule, Exec, 7)(VOID); + +/***************************************************************************** + + NAME */ +#include + + AROS_LH0(void, Reschedule, + +/* SYNOPSIS */ + +/* LOCATION */ + struct ExecBase *, SysBase, 8, Exec) + +/* FUNCTION + Give up the CPU time to other tasks (if there are any). + + INPUTS + None + + RESULT + None + + NOTES + This function was private in AmigaOS(tm) up to v3.1. There's no guarantee + that it will continue to exist in other systems. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + + HISTORY + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + BOOL oldAttnSwitch = (SysBase->AttnResched & ARF_AttnSwitch) ? TRUE : FALSE; + + AROS_ATOMIC_OR(SysBase->AttnResched, ARF_AttnSwitch); /* Set scheduling attention */ + + if (SysBase->TDNestCnt < 0) /* If task switching enabled */ + { + if (SysBase->IDNestCnt < 0) /* And interrupts enabled */ + { + D(bug("[Reschedule] Calling scheduler, KernelBase 0x%p\n", KernelBase)); + Supervisor(AROS_SLIB_ENTRY(Schedule,Exec,7)); /* Call scheduler */ + } + + /* If we set the attention flag, tag the software interrupt*/ + if (!oldAttnSwitch) { + struct Custom *custom = (APTR)_CUSTOM; + + custom->intreq = 0x8004; + } + } + + AROS_LIBFUNC_EXIT +} /* Reschedule */ diff --git a/arch/m68k-amiga/kernel/amiga_irq.c b/arch/m68k-amiga/kernel/amiga_irq.c index 3b0befd11f..4f2d3312fe 100644 --- a/arch/m68k-amiga/kernel/amiga_irq.c +++ b/arch/m68k-amiga/kernel/amiga_irq.c @@ -123,47 +123,6 @@ static inline UWORD custom_r(ULONG reg) * .. * 255 User 191 */ -static BOOL LineF_Decode(regs_t *regs, int id, struct ExecBase *SysBase) -{ - if (*((UWORD *)regs->pc) == KRN_SYSCALL_INST - && regs->a[0] == KRN_SYSCALL_MAGIC -/* COMPATIBILTY HACK! - * Do not check supervisor state, allows some badly coded programs to work. - */ -#if 0 - && (regs->sr & 0x2000) == 0 -#endif - ) { - /* Move past the instruction */ - regs->pc += 2; - - /* AROS syscall */ - core_SysCall(regs->d[0], regs); - return TRUE; - } - - return FALSE; -} - -/* Wrapper to work around GCC frame pointer bugs - */ -static inline BOOL Amiga_Paula_IRQ(int irq, UWORD mask, struct ExecBase *SysBase) -{ - /* If we don't have handler, ignore it */ - if (SysBase->IntVects[irq].iv_Code == NULL) { - bug("SPURIOUS IRQ: %d mask=0x%04x\n", irq, mask); - return FALSE; - } - - AROS_UFC5(void, SysBase->IntVects[irq].iv_Code, \ - AROS_UFCA(ULONG, mask, D1), \ - AROS_UFCA(ULONG, 0xDFF000, A0), \ - AROS_UFCA(APTR, SysBase->IntVects[irq].iv_Data, A1),\ - AROS_UFCA(APTR, SysBase->IntVects[irq].iv_Code, A5),\ - AROS_UFCA(struct ExecBase *, SysBase, A6)); - - return TRUE; -} #define PAULA_IRQ_CHECK(valid_mask) \ const UWORD irq_mask = valid_mask; \ @@ -184,16 +143,41 @@ static inline BOOL Amiga_Paula_IRQ(int irq, UWORD mask, struct ExecBase *SysBase #define PAULA_IRQ_EXIT() \ /* mask = custom_r(INTENAR) & custom_r(INTREQR) & (irq_mask); */ \ } while (0); \ - /* If the caller was not nested, call core_ExitInterrupt */ \ - if (!(regs->sr & 0x2000)) \ - core_ExitInterrupt(regs); \ + /* Call Exec/ExitIntr */ \ return TRUE; +#define DECLARE_TrapCode(handler) \ + BOOL handler(VOID); \ + VOID handler##_TrapCode(ULONG Id); \ + asm ( \ + " .global " #handler "_TrapCode\n" \ + " .func " #handler "_TrapCode\n" \ + #handler "_TrapCode:\n" \ + " addq.l #4,%sp\n" /* Drop the ID */ \ + " movem.l %d0/%d1/%a0/%a1/%a5/%a6,%sp@-\n" \ + " jsr " #handler "\n" \ + " tst.w %d0\n" \ + " beq 0f\n" \ + " jmp Exec_6_ExitIntr\n" \ + "0:\n" \ + " movem.l %sp@+,%d0/%d1/%a0/%a1/%a5/%a6\n" \ + " rte\n" \ + " .endfunc\n" \ + ); \ + /* AOS interrupt handlers will clear INTREQ before executing interrupt code, * servers will clear INTREQ after whole server chain has been executed. */ -static BOOL Amiga_Level_1(regs_t *regs, int id, struct ExecBase *SysBase) +DECLARE_TrapCode(Amiga_Level_1); +DECLARE_TrapCode(Amiga_Level_2); +DECLARE_TrapCode(Amiga_Level_3); +DECLARE_TrapCode(Amiga_Level_4); +DECLARE_TrapCode(Amiga_Level_5); +DECLARE_TrapCode(Amiga_Level_6); +DECLARE_TrapCode(Amiga_Level_7); + +BOOL Amiga_Level_1(VOID) { /* Paula IRQs 0 - Serial port TX done * 1 - Disk DMA finished @@ -214,7 +198,7 @@ static BOOL Amiga_Level_1(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_2(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_2(VOID) { /* Paula IRQs 3 - CIA-A */ @@ -227,7 +211,7 @@ static BOOL Amiga_Level_2(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_3(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_3(VOID) { /* Paula IRQs 4 - Copper * 5 - Vert Blank @@ -245,7 +229,7 @@ static BOOL Amiga_Level_3(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_4(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_4(VOID) { /* Paula IRQs 7 - Audio 0 * 8 - Audio 1 @@ -264,7 +248,7 @@ static BOOL Amiga_Level_4(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_5(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_5(VOID) { /* Paula IRQs 11 - Serial RX * 12 - Disk Sync @@ -279,7 +263,7 @@ static BOOL Amiga_Level_5(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_6(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_6(VOID) { /* Paula IRQ 13 - CIA-B & IRQ6 * 14 - INTEN (manually setting INTEN bit in INTREQ triggers it) @@ -294,7 +278,7 @@ static BOOL Amiga_Level_6(regs_t *regs, int id, struct ExecBase *SysBase) PAULA_IRQ_EXIT(); } -static BOOL Amiga_Level_7(regs_t *regs, int id, struct ExecBase *SysBase) +BOOL Amiga_Level_7(VOID) { /* NMI - no way around it. */ @@ -305,19 +289,17 @@ static BOOL Amiga_Level_7(regs_t *regs, int id, struct ExecBase *SysBase) /* Don't reschedule on the way out - so don't * call PAULA_IRQ_EXIT() */ - - return TRUE; + return FALSE; } const struct M68KException AmigaExceptionTable[] = { - { .Id = 11, .Handler = LineF_Decode }, - { .Id = 25, .Handler = Amiga_Level_1 }, - { .Id = 26, .Handler = Amiga_Level_2 }, - { .Id = 27, .Handler = Amiga_Level_3 }, - { .Id = 28, .Handler = Amiga_Level_4 }, - { .Id = 29, .Handler = Amiga_Level_5 }, - { .Id = 30, .Handler = Amiga_Level_6 }, - { .Id = 31, .Handler = Amiga_Level_7 }, + { .Id = 25, .Handler = Amiga_Level_1_TrapCode }, + { .Id = 26, .Handler = Amiga_Level_2_TrapCode }, + { .Id = 27, .Handler = Amiga_Level_3_TrapCode }, + { .Id = 28, .Handler = Amiga_Level_4_TrapCode }, + { .Id = 29, .Handler = Amiga_Level_5_TrapCode }, + { .Id = 30, .Handler = Amiga_Level_6_TrapCode }, + { .Id = 31, .Handler = Amiga_Level_7_TrapCode }, { .Id = 0, } }; diff --git a/arch/m68k-amiga/kernel/cause.c b/arch/m68k-amiga/kernel/cause.c new file mode 100644 index 0000000000..188095ea78 --- /dev/null +++ b/arch/m68k-amiga/kernel/cause.c @@ -0,0 +1,54 @@ +#include + +#include +#include + +/***************************************************************************** + + NAME */ +#include + +AROS_LH0I(void, KrnCause, + +/* SYNOPSIS */ + +/* LOCATION */ + struct KernelBase *, KernelBase, 3, Kernel) + +/* FUNCTION + Run software interrupt processing sequence + + INPUTS + None + + RESULT + None + + NOTES + This entry point directly calls interrupt processing routine + in supervisor mode. It neither performs any checks of caller status + nor obeys interrupt enable state. + + This function is safe to call only from within user mode. + This function is considered internal, and not meant to be called + by user's software. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + /* Stub function - this is not needed, since the caller + * (exec/Cause) does not call KrnCause() on the amiga-m68k + * platform + */ + + AROS_LIBFUNC_EXIT +} diff --git a/arch/m68k-amiga/kernel/dispatch.c b/arch/m68k-amiga/kernel/dispatch.c new file mode 100644 index 0000000000..188a2dbf97 --- /dev/null +++ b/arch/m68k-amiga/kernel/dispatch.c @@ -0,0 +1,52 @@ +#include + +#include +#include + +/***************************************************************************** + + NAME */ +#include + +AROS_LH0(void, KrnDispatch, + +/* SYNOPSIS */ + +/* LOCATION */ + struct KernelBase *, KernelBase, 4, Kernel) + +/* FUNCTION + Run the next available task + + INPUTS + None + + RESULT + None + + NOTES + This entry point directly calls task dispatch routine in supervisor mode. + It neither performs any checks of caller status nor obeys interrupt enable + state. After calling this function, caller's task will be replaced by + another one, and caller's state will be lost. + + This function is safe to call only from within user mode. + This function is considered internal, and not meant to be called + by user's software. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + Supervisor(Dispatch_wapper); + + AROS_LIBFUNC_EXIT +} diff --git a/arch/m68k-amiga/kernel/mmakefile.src b/arch/m68k-amiga/kernel/mmakefile.src index 600f10f6e7..1b6b0be57b 100644 --- a/arch/m68k-amiga/kernel/mmakefile.src +++ b/arch/m68k-amiga/kernel/mmakefile.src @@ -1,7 +1,7 @@ # $Id$ include $(TOP)/config/make.cfg -FILES=cli sti kernel_debug kernel_timer maygetchar amiga_irq \ +FILES=cause cli sti kernel_debug kernel_timer maygetchar amiga_irq \ getbootinfo kernel_globals AFILES= diff --git a/rom/exec/dispatch.c b/rom/exec/dispatch.c new file mode 100644 index 0000000000..6545a34110 --- /dev/null +++ b/rom/exec/dispatch.c @@ -0,0 +1,59 @@ +/* + Copyright © 1995-2011, The AROS Development Team. All rights reserved. + $Id$ + + Desc: + Lang: english +*/ + +#include +#include +#include +#include +#include + +#include "exec_intern.h" + +/***************************************************************************** + + NAME */ +#include + + AROS_LH0(void, Dispatch, + +/* SYNOPSIS */ + +/* LOCATION */ + struct ExecBase *, SysBase, 10, Exec) + +/* FUNCTION + PRIVATE function to dispatch next available task + + INPUTS + None + + RESULT + None + + NOTES + This function was private in AmigaOS(tm) up to v3.1. + There's no guarantee that it will continue to exist in other systems. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + + HISTORY + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + AROS_FUNCTION_NOT_IMPLEMENTED("Exec"); + + AROS_LIBFUNC_EXIT +} /* Dispatch */ diff --git a/rom/exec/exec.conf b/rom/exec/exec.conf index 7c01723dd9..fd854d29d8 100644 --- a/rom/exec/exec.conf +++ b/rom/exec/exec.conf @@ -71,11 +71,15 @@ BPTR close() () .private .skip 2 IPTR Supervisor(void *userFunction) (A5) -.skip 1 # AmigaOS(tm) private ExitIntr() hook -.skip 1 # AmigaOS(tm) private Schedule() hook +VOID ExitIntr() () +.private +VOID Schedule() () +.private void Reschedule() () -.skip 1 # AmigaOS(tm) private Switch() hook -.skip 1 # AmigaOS(tm) private Dispatch() hook +VOID Switch() () +.private +VOID Dispatch() () +.private void Exception() () void InitCode(ULONG startClass, ULONG version) (D0, D1) void InitStruct(CONST_APTR initTable, APTR memory, ULONG size) (A1, A2, D0) diff --git a/rom/exec/exitintr.c b/rom/exec/exitintr.c new file mode 100644 index 0000000000..19943915f3 --- /dev/null +++ b/rom/exec/exitintr.c @@ -0,0 +1,59 @@ +/* + Copyright © 1995-2011, The AROS Development Team. All rights reserved. + $Id$ + + Desc: + Lang: english +*/ + +#include +#include +#include +#include +#include + +#include "exec_intern.h" + +/***************************************************************************** + + NAME */ +#include + + AROS_LH0(void, ExitIntr, + +/* SYNOPSIS */ + +/* LOCATION */ + struct ExecBase *, SysBase, 6, Exec) + +/* FUNCTION + PRIVATE architecture specific routine for exiting interrupts. + + INPUTS + None + + RESULT + None + + NOTES + This function was private in AmigaOS(tm) up to v3.1. + There's no guarantee that it will exist in other systems. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + + HISTORY + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + AROS_FUNCTION_NOT_IMPLEMENTED("Exec"); + + AROS_LIBFUNC_EXIT +} /* ExitIntr */ diff --git a/rom/exec/mmakefile.src b/rom/exec/mmakefile.src index b775607ac4..d85e119a06 100644 --- a/rom/exec/mmakefile.src +++ b/rom/exec/mmakefile.src @@ -15,8 +15,9 @@ ALL_FUNCTIONS := \ checkio childfree childorphan childstatus childwait closedevice \ closelibrary coldreboot copymem copymemquick createiorequest \ createmsgport createpool deallocate debug deleteiorequest \ - deletemsgport deletepool disable doio enable enqueue \ - exception findname findport findresident findsemaphore findtask findtaskbypid \ + deletemsgport deletepool disable dispatch doio \ + enable enqueue exception exitintr \ + findname findport findresident findsemaphore findtask findtaskbypid \ forbid freeentry freemem freepooled freesignal freetrap freevec getcc \ getmsg initcode initresident initsemaphore initstruct insert \ makefunctions makelibrary obtainquickvector obtainsemaphore \ @@ -25,9 +26,9 @@ ALL_FUNCTIONS := \ rawioinit rawmaygetchar rawputchar readgayle releasesemaphore \ releasesemaphorelist remdevice remhead remintserver remlibrary \ remmemhandler remove remport remresource remsemaphore remtail remtask \ - replymsg reschedule sendio setexcept setfunction setintvector \ + replymsg reschedule schedule sendio setexcept setfunction setintvector \ setsignal setsr settaskpri signal stackswap sumkickdata sumlibrary \ - superstate supervisor taggedopenlibrary typeofmem userstate \ + superstate supervisor switch taggedopenlibrary typeofmem userstate \ vacate wait waitio waitport allocvecpooled freevecpooled newallocentry \ newaddtask newminlist avl vnewrawdofmt shutdowna useralert \ addresetcallback remresetcallback doresetcallbacks newcreatetaska \ diff --git a/rom/exec/schedule.c b/rom/exec/schedule.c new file mode 100644 index 0000000000..e2efc9f7be --- /dev/null +++ b/rom/exec/schedule.c @@ -0,0 +1,59 @@ +/* + Copyright © 1995-2011, The AROS Development Team. All rights reserved. + $Id$ + + Desc: + Lang: english +*/ + +#include +#include +#include +#include +#include + +#include "exec_intern.h" + +/***************************************************************************** + + NAME */ +#include + + AROS_LH0(void, Schedule, + +/* SYNOPSIS */ + +/* LOCATION */ + struct ExecBase *, SysBase, 7, Exec) + +/* FUNCTION + PRIVATE architecture specific routine for relinquishing CPU time + + INPUTS + None + + RESULT + None + + NOTES + This function was private in AmigaOS(tm) up to v3.1. There's no guarantee + that it will continue to exist in other systems. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + + HISTORY + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + AROS_FUNCTION_NOT_IMPLEMENTED("Exec"); + + AROS_LIBFUNC_EXIT +} /* Schedule */ diff --git a/rom/exec/switch.c b/rom/exec/switch.c new file mode 100644 index 0000000000..48820a533c --- /dev/null +++ b/rom/exec/switch.c @@ -0,0 +1,59 @@ +/* + Copyright © 1995-2011, The AROS Development Team. All rights reserved. + $Id$ + + Desc: + Lang: english +*/ + +#include +#include +#include +#include +#include + +#include "exec_intern.h" + +/***************************************************************************** + + NAME */ +#include + + AROS_LH0(void, Switch, + +/* SYNOPSIS */ + +/* LOCATION */ + struct ExecBase *, SysBase, 9, Exec) + +/* FUNCTION + PRIVATE function to force a task switch to the next runnable task + + INPUTS + None + + RESULT + None + + NOTES + This function was private in AmigaOS(tm) up to v3.1. + There's no guarantee that it will continue to exist in other systems. + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + + HISTORY + +******************************************************************************/ +{ + AROS_LIBFUNC_INIT + + AROS_FUNCTION_NOT_IMPLEMENTED("Exec"); + + AROS_LIBFUNC_EXIT +} /* Switch */ diff --git a/rom/exec/traphandler.c b/rom/exec/traphandler.c index 24678752b4..e7e1f5363d 100644 --- a/rom/exec/traphandler.c +++ b/rom/exec/traphandler.c @@ -47,11 +47,10 @@ asm ( " .balign 2\n" " .global Exec_TrapHandler\n" "Exec_TrapHandler:\n" - " move.l #0,%sp@-\n" /* Push on a NULL trapcode */ - " movem.l %d0-%d7/%a0-%a7,%sp@-\n" /* Save regs */ + " movem.l %d0-%d7/%a0-%a6,%sp@-\n" /* Save regs */ + " move.l %sp@(15*4),%d0\n" /* Get trap code */ " move.l %usp,%a0\n" /* Get USP */ " move.l %a0,%sp@(15*4)\n" /* Fix up A7 to be USP */ - " move.l %sp@(17*4),%d0\n" /* Get the trap number */ " move.l %sp,%sp@-\n" /* Push on pointer to exception ctx */ " move.l %d0,%sp@-\n" /* Push on trap number */ " jsr Exec__TrapHandler\n" /* Call C routine */ @@ -61,7 +60,6 @@ asm ( " move.l %a6,%usp\n" /* Restore USP */ " move.l %sp@+,%a6\n" /* Restore A6 */ " addq.l #4,%sp\n" /* Skip past A7 */ - " addq.l #8,%sp\n" /* Skip past trapcode and traparg */ " rte\n" /* Return from trap */ ); void Exec__TrapHandler(ULONG trapNum, struct ExceptionContext *ctx) -- 2.11.4.GIT