Contiki 2.6

mtarch.c

00001 
00002 #include <stdio.h>
00003 #include "sys/mt.h"
00004 
00005 #ifndef __WORDSIZE
00006 #define __WORDSIZE 32
00007 #endif /* __WORDSIZE */
00008 
00009 #ifndef ON_64BIT_ARCH
00010 #if __WORDSIZE == 64
00011 #define ON_64BIT_ARCH 1
00012 #else /* ON_64BIT_ARCH */
00013 #define ON_64BIT_ARCH 0
00014 #endif /* __WORDSIZE == 64 */
00015 #endif /* ON_64BIT_ARCH */
00016 
00017 struct frame {
00018   unsigned long flags;
00019 #if ON_64BIT_ARCH
00020   unsigned long rbp;
00021   unsigned long rdi;
00022   unsigned long rsi;
00023   unsigned long rdx;
00024   unsigned long rcx;
00025   unsigned long rbx;
00026   unsigned long rax;
00027 #else /* ON_64BIT_ARCH */
00028   unsigned long ebp;
00029   unsigned long edi;
00030   unsigned long esi;
00031   unsigned long edx;
00032   unsigned long ecx;
00033   unsigned long ebx;
00034   unsigned long eax;
00035 #endif /* ON_64BIT_ARCH */
00036   unsigned long retaddr;
00037   unsigned long retaddr2;
00038   unsigned long data;
00039 };
00040 /*--------------------------------------------------------------------------*/
00041 void
00042 mtarch_init(void)
00043 {
00044 }
00045 /*--------------------------------------------------------------------------*/
00046 void
00047 mtarch_start(struct mtarch_thread *t,
00048     void (*function)(void *), void *data)
00049 {
00050   struct frame *f = (struct frame *)&t->stack[MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
00051   int i;
00052 
00053   for(i = 0; i < MTARCH_STACKSIZE; ++i) {
00054     t->stack[i] = i;
00055   }
00056 
00057   memset(f, 0, sizeof(struct frame));
00058   f->retaddr = (unsigned long)function;
00059   f->data    = (unsigned long)data;
00060   t->sp      = (unsigned long)&f->flags;
00061 #if ON_64BIT_ARCH
00062   f->rbp     = (unsigned long)&f->rax;
00063 #else /* ON_64BIT_ARCH */
00064   f->ebp     = (unsigned long)&f->eax;
00065 #endif /* ON_64BIT_ARCH */
00066 }
00067 /*--------------------------------------------------------------------------*/
00068 static struct mtarch_thread *running_thread;
00069 /*--------------------------------------------------------------------------*/
00070 static void
00071 sw(void)
00072 {
00073   /* Store registers */
00074 #if ON_64BIT_ARCH
00075   __asm__ (
00076       "pushq %rax\n\t"
00077       "pushq %rbx\n\t"
00078       "pushq %rcx\n\t"
00079       "pushq %rdx\n\t"
00080       "pushq %rsi\n\t"
00081       "pushq %rdi\n\t"
00082       "pushq %rbp\n\t"
00083       "pushq %rbp\n\t");
00084 #else /* ON_64BIT_ARCH */
00085   __asm__ (
00086       "pushl %eax\n\t"
00087       "pushl %ebx\n\t"
00088       "pushl %ecx\n\t"
00089       "pushl %edx\n\t"
00090       "pushl %esi\n\t"
00091       "pushl %edi\n\t"
00092       "pushl %ebp\n\t"
00093       "pushl %ebp\n\t");
00094 #endif /* ON_64BIT_ARCH */
00095 
00096   /* Switch stack pointer */
00097 #if ON_64BIT_ARCH
00098   __asm__ ("movq %0, %%rax\n\t" : : "m" (running_thread));
00099   __asm__ (
00100       "movq (%rax), %rbx\n\t"
00101       "movq %rsp, (%rax)\n\t"
00102       "movq %rbx, %rsp\n\t"
00103   );
00104 #else /* ON_64BIT_ARCH */
00105   __asm__ ("movl %0, %%eax\n\t" : : "m" (running_thread));
00106   __asm__ (
00107       "movl (%eax), %ebx\n\t"
00108       "movl %esp, (%eax)\n\t"
00109       "movl %ebx, %esp\n\t"
00110   );
00111 #endif /* ON_64BIT_ARCH */
00112 
00113   /* Restore previous registers */
00114 #if ON_64BIT_ARCH
00115   __asm__ (
00116       "popq %rbp\n\t"
00117       "popq %rbp\n\t"
00118       "popq %rdi\n\t"
00119       "popq %rsi\n\t"
00120       "popq %rdx\n\t"
00121       "popq %rcx\n\t"
00122       "popq %rbx\n\t"
00123       "popq %rax\n\t"
00124 
00125       "leave\n\t"
00126       "ret\n\t"
00127   );
00128 #else /* ON_64BIT_ARCH */
00129   __asm__ (
00130       "popl %ebp\n\t"
00131       "popl %ebp\n\t"
00132       "popl %edi\n\t"
00133       "popl %esi\n\t"
00134       "popl %edx\n\t"
00135       "popl %ecx\n\t"
00136       "popl %ebx\n\t"
00137       "popl %eax\n\t"
00138 
00139       "leave\n\t"
00140       "ret\n\t"
00141   );
00142 #endif /* ON_64BIT_ARCH */
00143 
00144 }
00145 
00146 /*--------------------------------------------------------------------------*/
00147 void
00148 mtarch_exec(struct mtarch_thread *t)
00149 {
00150   running_thread = t;
00151   sw();
00152   running_thread = NULL;
00153 }
00154 /*--------------------------------------------------------------------------*/
00155 void
00156 mtarch_remove(void)
00157 {
00158 }
00159 /*--------------------------------------------------------------------------*/
00160 void
00161 mtarch_yield(void)
00162 {
00163   sw();
00164 }
00165 /*--------------------------------------------------------------------------*/
00166 void
00167 mtarch_pstop(void)
00168 {
00169 }
00170 /*--------------------------------------------------------------------------*/
00171 void
00172 mtarch_pstart(void)
00173 {
00174 }
00175 /*--------------------------------------------------------------------------*/
00176 int
00177 mtarch_stack_usage(struct mt_thread *t)
00178 {
00179   int i;
00180   for(i = 0; i < MTARCH_STACKSIZE; ++i) {
00181     if(t->thread.stack[i] != i) {
00182       return MTARCH_STACKSIZE - i;
00183     }
00184   }
00185   return -1;
00186 }
00187 /*--------------------------------------------------------------------------*/