diff --git a/platform/cooja/sys/cooja_mtarch.c b/platform/cooja/sys/cooja_mtarch.c index 38755b470..1e23c0449 100644 --- a/platform/cooja/sys/cooja_mtarch.c +++ b/platform/cooja/sys/cooja_mtarch.c @@ -28,15 +28,39 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: cooja_mtarch.c,v 1.5 2007/04/02 08:47:28 fros4943 Exp $ + * @(#)$Id: cooja_mtarch.c,v 1.6 2008/11/28 16:41:26 fros4943 Exp $ */ +#include + +#include #include #include #include "sys/cooja_mt.h" +#ifndef __WORDSIZE +#define __WORDSIZE 32 +#endif /* __WORDSIZE */ + +#ifndef ON_64BIT_ARCH +#if __WORDSIZE == 64 +#define ON_64BIT_ARCH 1 +#else /* ON_64BIT_ARCH */ +#define ON_64BIT_ARCH 0 +#endif /* __WORDSIZE == 64 */ +#endif /* ON_64BIT_ARCH */ + struct frame { unsigned long flags; +#if ON_64BIT_ARCH + unsigned long rbp; + unsigned long rdi; + unsigned long rsi; + unsigned long rdx; + unsigned long rcx; + unsigned long rbx; + unsigned long rax; +#else /* ON_64BIT_ARCH */ unsigned long ebp; unsigned long edi; unsigned long esi; @@ -44,6 +68,7 @@ struct frame { unsigned long ecx; unsigned long ebx; unsigned long eax; +#endif /* ON_64BIT_ARCH */ unsigned long retaddr; unsigned long retaddr2; unsigned long data; @@ -56,20 +81,24 @@ cooja_mtarch_init(void) /*--------------------------------------------------------------------------*/ void cooja_mtarch_start(struct cooja_mtarch_thread *t, - void (*function)(void *), void *data) + void (*function)(void *), void *data) { struct frame *f = (struct frame *)&t->stack[COOJA_MTARCH_STACKSIZE - sizeof(struct frame)/4]; int i; - + for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) { t->stack[i] = i; } - + memset(f, 0, sizeof(struct frame)); f->retaddr = (unsigned long)function; f->data = (unsigned long)data; t->sp = (unsigned long)&f->flags; +#if ON_64BIT_ARCH + f->rbp = (unsigned long)&f->rax; +#else /* ON_64BIT_ARCH */ f->ebp = (unsigned long)&f->eax; +#endif /* ON_64BIT_ARCH */ } /*--------------------------------------------------------------------------*/ static struct cooja_mtarch_thread *cooja_running_thread; @@ -77,39 +106,78 @@ static struct cooja_mtarch_thread *cooja_running_thread; void cooja_sw(void) { /* Store registers */ +#if ON_64BIT_ARCH __asm__ ( - "pushl %eax\n\t" - "pushl %ebx\n\t" - "pushl %ecx\n\t" - "pushl %edx\n\t" - "pushl %esi\n\t" - "pushl %edi\n\t" - "pushl %ebp\n\t" - "pushl %ebp\n\t"); - + "pushq %rax\n\t" + "pushq %rbx\n\t" + "pushq %rcx\n\t" + "pushq %rdx\n\t" + "pushq %rsi\n\t" + "pushq %rdi\n\t" + "pushq %rbp\n\t" + "pushq %rbp\n\t"); +#else /* ON_64BIT_ARCH */ + __asm__ ( + "pushl %eax\n\t" + "pushl %ebx\n\t" + "pushl %ecx\n\t" + "pushl %edx\n\t" + "pushl %esi\n\t" + "pushl %edi\n\t" + "pushl %ebp\n\t" + "pushl %ebp\n\t"); +#endif /* ON_64BIT_ARCH */ + /* Switch stack pointer */ +#if ON_64BIT_ARCH + __asm__ ("movq %0, %%rax\n\t" : : "m" (cooja_running_thread)); + __asm__ ( + "movq 0(%rax), %rbx\n\t" + "movq %rsp, 0(%rax)\n\t" + "movq %rbx, %rsp\n\t" + ); +#else /* ON_64BIT_ARCH */ __asm__ ("movl %0, %%eax\n\t" : : "m" (cooja_running_thread)); __asm__ ( - "movl 0(%eax), %ebx\n\t" - "movl %esp, 0(%eax)\n\t" - "movl %ebx, %esp\n\t" - ); - - /* Restore stored registers and return "our" way */ + "movl 0(%eax), %ebx\n\t" + "movl %esp, 0(%eax)\n\t" + "movl %ebx, %esp\n\t" + ); +#endif /* ON_64BIT_ARCH */ + + /* Restore previous registers */ +#if ON_64BIT_ARCH __asm__ ( - "popl %ebp\n\t" - "popl %ebp\n\t" - "popl %edi\n\t" - "popl %esi\n\t" - "popl %edx\n\t" - "popl %ecx\n\t" - "popl %ebx\n\t" - "popl %eax\n\t" - - "leave\n\t" - "ret\n\t" - ); + "popq %rbp\n\t" + "popq %rbp\n\t" + "popq %rdi\n\t" + "popq %rsi\n\t" + "popq %rdx\n\t" + "popq %rcx\n\t" + "popq %rbx\n\t" + "popq %rax\n\t" + + "leave\n\t" + "ret\n\t" + ); +#else /* ON_64BIT_ARCH */ + __asm__ ( + "popl %ebp\n\t" + "popl %ebp\n\t" + "popl %edi\n\t" + "popl %esi\n\t" + "popl %edx\n\t" + "popl %ecx\n\t" + "popl %ebx\n\t" + "popl %eax\n\t" + + "leave\n\t" + "ret\n\t" + ); +#endif /* ON_64BIT_ARCH */ + } + /*--------------------------------------------------------------------------*/ void cooja_mtarch_exec(struct cooja_mtarch_thread *t)