cooja_mtarch.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
00044
00045 #ifndef ON_64BIT_ARCH
00046 #if __WORDSIZE == 64
00047 #define ON_64BIT_ARCH 1
00048 #else
00049 #define ON_64BIT_ARCH 0
00050 #endif
00051 #endif
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
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
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
00100 f->ebp = (unsigned long)&f->eax;
00101 #endif
00102 }
00103
00104 static struct cooja_mtarch_thread *cooja_running_thread;
00105
00106 void cooja_sw(void)
00107 {
00108
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
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
00130
00131
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
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
00147
00148
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
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
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