From 8d3496194f3df97948da92c8b7074641597a7519 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sat, 21 Apr 2007 22:15:45 +0000 Subject: [PATCH] Added Multithreading support to the cc65 targets based on the Contiki 1.x C64 implementation with the following changes: - Added support for the function parameter. - Removed support for preemption because: - No other current implementation does so. - Preemption support would make the code at least target-dependent or it wouldn't work at all (as on plain Apple2 machines without timer interrupt). --- cpu/6502/Makefile.6502 | 5 +- cpu/6502/mtarch-asm.S | 214 +++++++++++++++++++++++++++++++++++++++++ cpu/6502/mtarch.c | 123 +++++++++++++++++++++++ cpu/6502/mtarch.h | 16 ++- 4 files changed, 353 insertions(+), 5 deletions(-) create mode 100644 cpu/6502/mtarch-asm.S create mode 100644 cpu/6502/mtarch.c diff --git a/cpu/6502/Makefile.6502 b/cpu/6502/Makefile.6502 index e42135af3..8d430bcd8 100644 --- a/cpu/6502/Makefile.6502 +++ b/cpu/6502/Makefile.6502 @@ -1,3 +1,4 @@ +# # Copyright (c) 2007, Adam Dunkels. # All rights reserved. # @@ -29,7 +30,7 @@ # # Author: Oliver Schmidt # -# $Id: Makefile.6502,v 1.6 2007/04/21 15:04:23 oliverschmidt Exp $ +# $Id: Makefile.6502,v 1.7 2007/04/21 22:15:45 oliverschmidt Exp $ # ifndef CONTIKI @@ -53,7 +54,7 @@ CONTIKI_CPU_DIRS = . net sys CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} CONTIKI_TARGET_SOURCEFILES = contiki-main.c -CONTIKI_CPU_SOURCEFILES = lc-asm.S uip_arch.c +CONTIKI_CPU_SOURCEFILES = mtarch.c mtarch-asm.S lc-asm.S uip_arch.c CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(CONTIKI_TARGET_SOURCEFILES) diff --git a/cpu/6502/mtarch-asm.S b/cpu/6502/mtarch-asm.S new file mode 100644 index 000000000..a90ed1495 --- /dev/null +++ b/cpu/6502/mtarch-asm.S @@ -0,0 +1,214 @@ +; +; Copyright (c) 2004, Adam Dunkels. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; 3. Neither the name of the Institute nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. +; +; This file is part of the Contiki operating system. +; +; Author: Adam Dunkels +; +; $Id: mtarch-asm.S,v 1.1 2007/04/21 22:15:45 oliverschmidt Exp $ +; +;--------------------------------------------------------------------- + .importzp ptr1 + .importzp sp + .import __ZP_START__ + + .import _mtarch_asm_threadspreg + .import _mtarch_asm_threadsp + .import _mtarch_asm_threadzp + .import _mtarch_asm_threadstack + + .export _mtarch_asm_start + .export _mtarch_asm_yield + .export _mtarch_asm_exec + +;--------------------------------------------------------------------- +.bss +kernelsp: .res 2 +kernelspreg: .res 1 + +zpsize = 32 + +;--------------------------------------------------------------------- +.code +; Switch to thread defined by threadsp, threadstack and threadspreg. +; The kernel stack is swapped onto the threadstack, and the +; sp and spreg are saved to the local variables "kernelsp" and +; "kernelspreg". Also, the zeropage variables are saved. +_mtarch_asm_exec: + sei + ; Save current stack pointer + lda sp + sta kernelsp + lda sp+1 + sta kernelsp+1 + + tsx + stx kernelspreg + + lda _mtarch_asm_threadzp + sta ptr1 + lda _mtarch_asm_threadzp+1 + sta ptr1+1 + + ldy #0 +: lda <__ZP_START__,y + tax + lda (ptr1),y + sta <__ZP_START__,y + txa + sta (ptr1),y + iny + cpy #zpsize + bne :- + + lda _mtarch_asm_threadstack + sta ptr1 + lda _mtarch_asm_threadstack+1 + sta ptr1+1 + + ldy kernelspreg ; Determine the smallest of the two stack pointers, + cpy _mtarch_asm_threadspreg ; as we only need to swap the used part of the stack. + bcc :+ + ldy _mtarch_asm_threadspreg + +: lda $0100,y + tax + lda (ptr1),y + sta $0100,y + txa + sta (ptr1),y + iny + bne :- + + lda _mtarch_asm_threadsp + sta sp + lda _mtarch_asm_threadsp+1 + sta sp+1 + + ldx _mtarch_asm_threadspreg + txs + + pla + tay + pla + tax + pla + rti + +;--------------------------------------------------------------------- +; Switch from thread defined by threadsp, threadstack and threadspreg. +; The kernel stack is swapped back from the threadstack, and the +; sp and spreg are restored from the local variables "kernelsp" and +; "kernelspreg". +_mtarch_asm_yield: + php + pha + txa + pha + tya + pha + + sei + tsx ; The rts adds 1 to the PC + ; saved on the stack. We want + lda $0105,x ; the stack to look like is would + clc ; do inside of an interrupt + adc #1 ; (this is what the 'rts' does, + sta $0105,x ; but not the 'rti'). + lda $0106,x + adc #0 + sta $0106,x + + lda sp + sta _mtarch_asm_threadsp + lda sp+1 + sta _mtarch_asm_threadsp+1 + + tsx + stx _mtarch_asm_threadspreg + + lda _mtarch_asm_threadzp + sta ptr1 + lda _mtarch_asm_threadzp+1 + sta ptr1+1 + + ldy kernelspreg ; Determine the smallest of the two stack pointers, + cpy _mtarch_asm_threadspreg ; as we only need to swap the used part of the stack. + bcc :+ + ldy _mtarch_asm_threadspreg + +: lda <__ZP_START__,y + tax + lda (ptr1),y + sta <__ZP_START__,y + txa + sta (ptr1),y + iny + cpy #zpsize + bne :- + + lda _mtarch_asm_threadstack + sta ptr1 + lda _mtarch_asm_threadstack+1 + sta ptr1+1 + + ldy #0 +: lda $0100,y + tax + lda (ptr1),y + sta $0100,y + txa + sta (ptr1),y + iny + bne :- + + lda kernelsp + sta sp + lda kernelsp+1 + sta sp+1 + + ldx kernelspreg + txs + + cli + rts +;--------------------------------------------------------------------- +_mtarch_asm_start: + lda _mtarch_asm_threadzp + sta ptr1 + lda _mtarch_asm_threadzp+1 + sta ptr1+1 + + ldy #0 +: lda <__ZP_START__,y + sta (ptr1),y + iny + cpy #zpsize + bne :- + rts +;--------------------------------------------------------------------- diff --git a/cpu/6502/mtarch.c b/cpu/6502/mtarch.c new file mode 100644 index 000000000..bd0306c28 --- /dev/null +++ b/cpu/6502/mtarch.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: mtarch.c,v 1.1 2007/04/21 22:15:45 oliverschmidt Exp $ + */ + +#include + +#include "mtarch.h" + +unsigned char mtarch_asm_threadspreg; +unsigned char *mtarch_asm_threadsp; +unsigned char *mtarch_asm_threadzp; +unsigned char *mtarch_asm_threadstack; + +void mtarch_asm_start(void); +void mtarch_asm_yield(void); +void mtarch_asm_exec(void); + +/*--------------------------------------------------------------------------*/ +void +mtarch_init(void) +{ +} +/*--------------------------------------------------------------------------*/ +void +mtarch_remove(void) +{ +} +/*--------------------------------------------------------------------------*/ +void +mtarch_start(struct mtarch_thread *thread, + void (* function)(void *data), + void *data) +{ + memset(thread->cpustack, 0, sizeof(thread->cpustack)); + memset(thread->cstack, 0, sizeof(thread->cstack)); + + /* Create a CPU stack frame with the appropriate values. */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 2] = ((unsigned short)function) / 0x100; /* high byte of return address */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 3] = ((unsigned short)function) % 0x100; /* low byte of return address */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 4] = 0x21; /* processor flags */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 5] = /* a register */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 6] = /* x register */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 7] = 0x00; /* y register */ + thread->spreg = MTARCH_CPUSTACKSIZE - 8; + + /* Setup the C stack with the data pointer. */ + thread->cstack[MTARCH_CPUSTACKSIZE - 2] = ((unsigned short)data) / 0x100; /* high byte of data pointer */ + thread->cstack[MTARCH_CPUSTACKSIZE - 3] = ((unsigned short)data) % 0x100; /* low byte of data pointer */ + thread->sp = &thread->cstack[MTARCH_CSTACKSIZE - 3]; + + mtarch_asm_threadzp = &(thread->zp); + mtarch_asm_start(); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_yield(void) +{ + mtarch_asm_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_exec(struct mtarch_thread *thread) +{ + /* Switch processor stack. The call to mtarch_asm_switch() will not + return until the process that we switch to calls yield(). */ + mtarch_asm_threadspreg = thread->spreg; + mtarch_asm_threadsp = thread->sp; + + mtarch_asm_threadstack = &(thread->cpustack[0]); + mtarch_asm_threadzp = &(thread->zp[0]); + + mtarch_asm_exec(); + + thread->sp = mtarch_asm_threadsp; + thread->spreg = mtarch_asm_threadspreg; +} +/*--------------------------------------------------------------------------*/ +void +mtarch_stop(struct mtarch_thread *thread) +{ +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstart(void) +{ +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstop(void) +{ +} +/*--------------------------------------------------------------------------*/ diff --git a/cpu/6502/mtarch.h b/cpu/6502/mtarch.h index 37e58923f..939db50a8 100644 --- a/cpu/6502/mtarch.h +++ b/cpu/6502/mtarch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2004, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,14 +28,24 @@ * * This file is part of the Contiki operating system. * - * $Id: mtarch.h,v 1.1 2007/04/18 21:38:55 oliverschmidt Exp $ + * Author: Adam Dunkels + * + * $Id: mtarch.h,v 1.2 2007/04/21 22:15:45 oliverschmidt Exp $ */ #ifndef __MTARCH_H__ #define __MTARCH_H__ +#define MTARCH_CPUSTACKSIZE 256 +#define MTARCH_CSTACKSIZE 256 +#define MTARCH_ZPSIZE 32 + struct mtarch_thread { - unsigned char dummy; + unsigned char spreg; + unsigned char *sp; + unsigned char cpustack[MTARCH_CPUSTACKSIZE]; + unsigned char cstack [MTARCH_CSTACKSIZE]; + unsigned char zp [MTARCH_ZPSIZE]; }; #endif /* __MTARCH_H__ */