Contiki 2.6

cooja_mtarch.c

00001 /*
00002  * Copyright (c) 2005, Swedish Institute of Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  * @(#)$Id: cooja_mtarch.c,v 1.7 2009/03/13 14:42:06 fros4943 Exp $
00032  */
00033 
00034 #include <stddef.h>
00035 
00036 #include <limits.h>
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include "sys/cooja_mt.h"
00040 
00041 #ifndef __WORDSIZE
00042 #define __WORDSIZE 32
00043 #endif /* __WORDSIZE */
00044 
00045 #ifndef ON_64BIT_ARCH
00046 #if __WORDSIZE == 64
00047 #define ON_64BIT_ARCH 1
00048 #else /* ON_64BIT_ARCH */
00049 #define ON_64BIT_ARCH 0
00050 #endif /* __WORDSIZE == 64 */
00051 #endif /* ON_64BIT_ARCH */
00052 
00053 struct frame {
00054   unsigned long flags;
00055 #if ON_64BIT_ARCH
00056   unsigned long rbp;
00057   unsigned long rdi;
00058   unsigned long rsi;
00059   unsigned long rdx;
00060   unsigned long rcx;
00061   unsigned long rbx;
00062   unsigned long rax;
00063 #else /* ON_64BIT_ARCH */
00064   unsigned long ebp;
00065   unsigned long edi;
00066   unsigned long esi;
00067   unsigned long edx;
00068   unsigned long ecx;
00069   unsigned long ebx;
00070   unsigned long eax;
00071 #endif /* ON_64BIT_ARCH */
00072   unsigned long retaddr;
00073   unsigned long retaddr2;
00074   unsigned long data;
00075 };
00076 /*--------------------------------------------------------------------------*/
00077 void
00078 cooja_mtarch_init(void)
00079 {
00080 }
00081 /*--------------------------------------------------------------------------*/
00082 void
00083 cooja_mtarch_start(struct cooja_mtarch_thread *t,
00084     void (*function)(void *), void *data)
00085 {
00086   struct frame *f = (struct frame *)&t->stack[COOJA_MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
00087   int i;
00088 
00089   for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
00090     t->stack[i] = i;
00091   }
00092 
00093   memset(f, 0, sizeof(struct frame));
00094   f->retaddr = (unsigned long)function;
00095   f->data    = (unsigned long)data;
00096   t->sp      = (unsigned long)&f->flags;
00097 #if ON_64BIT_ARCH
00098   f->rbp     = (unsigned long)&f->rax;
00099 #else /* ON_64BIT_ARCH */
00100   f->ebp     = (unsigned long)&f->eax;
00101 #endif /* ON_64BIT_ARCH */
00102 }
00103 /*--------------------------------------------------------------------------*/
00104 static struct cooja_mtarch_thread *cooja_running_thread;
00105 /*--------------------------------------------------------------------------*/
00106 void cooja_sw(void)
00107 {
00108   /* Store registers */
00109 #if ON_64BIT_ARCH
00110   __asm__ (
00111       "pushq %rax\n\t"
00112       "pushq %rbx\n\t"
00113       "pushq %rcx\n\t"
00114       "pushq %rdx\n\t"
00115       "pushq %rsi\n\t"
00116       "pushq %rdi\n\t"
00117       "pushq %rbp\n\t"
00118       "pushq %rbp\n\t");
00119 #else /* ON_64BIT_ARCH */
00120   __asm__ (
00121       "pushl %eax\n\t"
00122       "pushl %ebx\n\t"
00123       "pushl %ecx\n\t"
00124       "pushl %edx\n\t"
00125       "pushl %esi\n\t"
00126       "pushl %edi\n\t"
00127       "pushl %ebp\n\t"
00128       "pushl %ebp\n\t");
00129 #endif /* ON_64BIT_ARCH */
00130 
00131   /* Switch stack pointer */
00132 #if ON_64BIT_ARCH
00133   __asm__ ("movq %0, %%rax\n\t" : : "m" (cooja_running_thread));
00134   __asm__ (
00135       "movq (%rax), %rbx\n\t"
00136       "movq %rsp, (%rax)\n\t"
00137       "movq %rbx, %rsp\n\t"
00138   );
00139 #else /* ON_64BIT_ARCH */
00140   __asm__ ("movl %0, %%eax\n\t" : : "m" (cooja_running_thread));
00141   __asm__ (
00142       "movl (%eax), %ebx\n\t"
00143       "movl %esp, (%eax)\n\t"
00144       "movl %ebx, %esp\n\t"
00145   );
00146 #endif /* ON_64BIT_ARCH */
00147 
00148   /* Restore previous registers */
00149 #if ON_64BIT_ARCH
00150   __asm__ (
00151       "popq %rbp\n\t"
00152       "popq %rbp\n\t"
00153       "popq %rdi\n\t"
00154       "popq %rsi\n\t"
00155       "popq %rdx\n\t"
00156       "popq %rcx\n\t"
00157       "popq %rbx\n\t"
00158       "popq %rax\n\t"
00159 
00160       "leave\n\t"
00161       "ret\n\t"
00162   );
00163 #else /* ON_64BIT_ARCH */
00164   __asm__ (
00165       "popl %ebp\n\t"
00166       "popl %ebp\n\t"
00167       "popl %edi\n\t"
00168       "popl %esi\n\t"
00169       "popl %edx\n\t"
00170       "popl %ecx\n\t"
00171       "popl %ebx\n\t"
00172       "popl %eax\n\t"
00173 
00174       "leave\n\t"
00175       "ret\n\t"
00176   );
00177 #endif /* ON_64BIT_ARCH */
00178 
00179 }
00180 
00181 /*--------------------------------------------------------------------------*/
00182 void
00183 cooja_mtarch_exec(struct cooja_mtarch_thread *t)
00184 {
00185   cooja_running_thread = t;
00186   cooja_sw();
00187   cooja_running_thread = NULL;
00188 }
00189 /*--------------------------------------------------------------------------*/
00190 void
00191 cooja_mtarch_remove(void)
00192 {
00193 }
00194 /*--------------------------------------------------------------------------*/
00195 void
00196 cooja_mtarch_yield(void)
00197 {
00198   cooja_sw();
00199 }
00200 /*--------------------------------------------------------------------------*/
00201 void
00202 cooja_mtarch_pstop(void)
00203 {
00204 }
00205 /*--------------------------------------------------------------------------*/
00206 void
00207 cooja_mtarch_pstart(void)
00208 {
00209 }
00210 /*--------------------------------------------------------------------------*/
00211 int
00212 cooja_mtarch_stack_usage(struct cooja_mt_thread *t)
00213 {
00214   int i;
00215   for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
00216     if(t->thread.stack[i] != i) {
00217       return COOJA_MTARCH_STACKSIZE - i;
00218     }
00219   }
00220   return -1;
00221 }
00222 /*--------------------------------------------------------------------------*/