Contiki 2.5
mtarch.c
1 
2 #include <stdio.h>
3 #include "sys/mt.h"
4 
5 #ifndef __WORDSIZE
6 #define __WORDSIZE 32
7 #endif /* __WORDSIZE */
8 
9 #ifndef ON_64BIT_ARCH
10 #if __WORDSIZE == 64
11 #define ON_64BIT_ARCH 1
12 #else /* ON_64BIT_ARCH */
13 #define ON_64BIT_ARCH 0
14 #endif /* __WORDSIZE == 64 */
15 #endif /* ON_64BIT_ARCH */
16 
17 struct frame {
18  unsigned long flags;
19 #if ON_64BIT_ARCH
20  unsigned long rbp;
21  unsigned long rdi;
22  unsigned long rsi;
23  unsigned long rdx;
24  unsigned long rcx;
25  unsigned long rbx;
26  unsigned long rax;
27 #else /* ON_64BIT_ARCH */
28  unsigned long ebp;
29  unsigned long edi;
30  unsigned long esi;
31  unsigned long edx;
32  unsigned long ecx;
33  unsigned long ebx;
34  unsigned long eax;
35 #endif /* ON_64BIT_ARCH */
36  unsigned long retaddr;
37  unsigned long retaddr2;
38  unsigned long data;
39 };
40 /*--------------------------------------------------------------------------*/
41 void
43 {
44 }
45 /*--------------------------------------------------------------------------*/
46 void
47 mtarch_start(struct mtarch_thread *t,
48  void (*function)(void *), void *data)
49 {
50  struct frame *f = (struct frame *)&t->stack[MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
51  int i;
52 
53  for(i = 0; i < MTARCH_STACKSIZE; ++i) {
54  t->stack[i] = i;
55  }
56 
57  memset(f, 0, sizeof(struct frame));
58  f->retaddr = (unsigned long)function;
59  f->data = (unsigned long)data;
60  t->sp = (unsigned long)&f->flags;
61 #if ON_64BIT_ARCH
62  f->rbp = (unsigned long)&f->rax;
63 #else /* ON_64BIT_ARCH */
64  f->ebp = (unsigned long)&f->eax;
65 #endif /* ON_64BIT_ARCH */
66 }
67 /*--------------------------------------------------------------------------*/
68 static struct mtarch_thread *running_thread;
69 /*--------------------------------------------------------------------------*/
70 static void
71 sw(void)
72 {
73  /* Store registers */
74 #if ON_64BIT_ARCH
75  __asm__ (
76  "pushq %rax\n\t"
77  "pushq %rbx\n\t"
78  "pushq %rcx\n\t"
79  "pushq %rdx\n\t"
80  "pushq %rsi\n\t"
81  "pushq %rdi\n\t"
82  "pushq %rbp\n\t"
83  "pushq %rbp\n\t");
84 #else /* ON_64BIT_ARCH */
85  __asm__ (
86  "pushl %eax\n\t"
87  "pushl %ebx\n\t"
88  "pushl %ecx\n\t"
89  "pushl %edx\n\t"
90  "pushl %esi\n\t"
91  "pushl %edi\n\t"
92  "pushl %ebp\n\t"
93  "pushl %ebp\n\t");
94 #endif /* ON_64BIT_ARCH */
95 
96  /* Switch stack pointer */
97 #if ON_64BIT_ARCH
98  __asm__ ("movq %0, %%rax\n\t" : : "m" (running_thread));
99  __asm__ (
100  "movq (%rax), %rbx\n\t"
101  "movq %rsp, (%rax)\n\t"
102  "movq %rbx, %rsp\n\t"
103  );
104 #else /* ON_64BIT_ARCH */
105  __asm__ ("movl %0, %%eax\n\t" : : "m" (running_thread));
106  __asm__ (
107  "movl (%eax), %ebx\n\t"
108  "movl %esp, (%eax)\n\t"
109  "movl %ebx, %esp\n\t"
110  );
111 #endif /* ON_64BIT_ARCH */
112 
113  /* Restore previous registers */
114 #if ON_64BIT_ARCH
115  __asm__ (
116  "popq %rbp\n\t"
117  "popq %rbp\n\t"
118  "popq %rdi\n\t"
119  "popq %rsi\n\t"
120  "popq %rdx\n\t"
121  "popq %rcx\n\t"
122  "popq %rbx\n\t"
123  "popq %rax\n\t"
124 
125  "leave\n\t"
126  "ret\n\t"
127  );
128 #else /* ON_64BIT_ARCH */
129  __asm__ (
130  "popl %ebp\n\t"
131  "popl %ebp\n\t"
132  "popl %edi\n\t"
133  "popl %esi\n\t"
134  "popl %edx\n\t"
135  "popl %ecx\n\t"
136  "popl %ebx\n\t"
137  "popl %eax\n\t"
138 
139  "leave\n\t"
140  "ret\n\t"
141  );
142 #endif /* ON_64BIT_ARCH */
143 
144 }
145 
146 /*--------------------------------------------------------------------------*/
147 void
148 mtarch_exec(struct mtarch_thread *t)
149 {
150  running_thread = t;
151  sw();
152  running_thread = NULL;
153 }
154 /*--------------------------------------------------------------------------*/
155 void
157 {
158 }
159 /*--------------------------------------------------------------------------*/
160 void
162 {
163  sw();
164 }
165 /*--------------------------------------------------------------------------*/
166 void
167 mtarch_pstop(void)
168 {
169 }
170 /*--------------------------------------------------------------------------*/
171 void
172 mtarch_pstart(void)
173 {
174 }
175 /*--------------------------------------------------------------------------*/
176 int
177 mtarch_stack_usage(struct mt_thread *t)
178 {
179  int i;
180  for(i = 0; i < MTARCH_STACKSIZE; ++i) {
181  if(t->thread.stack[i] != i) {
182  return MTARCH_STACKSIZE - i;
183  }
184  }
185  return -1;
186 }
187 /*--------------------------------------------------------------------------*/