Contiki 3.x
cooja_mtarch.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 #include <stddef.h>
34 
35 #include <limits.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include "sys/cooja_mt.h"
39 
40 #ifndef __WORDSIZE
41 #define __WORDSIZE 32
42 #endif /* __WORDSIZE */
43 
44 #ifndef ON_64BIT_ARCH
45 #if __WORDSIZE == 64
46 #define ON_64BIT_ARCH 1
47 #else /* ON_64BIT_ARCH */
48 #define ON_64BIT_ARCH 0
49 #endif /* __WORDSIZE == 64 */
50 #endif /* ON_64BIT_ARCH */
51 
52 struct frame {
53  unsigned long flags;
54 #if ON_64BIT_ARCH
55  unsigned long rbp;
56  unsigned long rdi;
57  unsigned long rsi;
58  unsigned long rdx;
59  unsigned long rcx;
60  unsigned long rbx;
61  unsigned long rax;
62 #else /* ON_64BIT_ARCH */
63  unsigned long ebp;
64  unsigned long edi;
65  unsigned long esi;
66  unsigned long edx;
67  unsigned long ecx;
68  unsigned long ebx;
69  unsigned long eax;
70 #endif /* ON_64BIT_ARCH */
71  unsigned long retaddr;
72  unsigned long retaddr2;
73  unsigned long data;
74 };
75 /*--------------------------------------------------------------------------*/
76 void
77 cooja_mtarch_init(void)
78 {
79 }
80 /*--------------------------------------------------------------------------*/
81 void
82 cooja_mtarch_start(struct cooja_mtarch_thread *t,
83  void (*function)(void *), void *data)
84 {
85  struct frame *f = (struct frame *)&t->stack[COOJA_MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
86  int i;
87 
88  for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
89  t->stack[i] = i;
90  }
91 
92  memset(f, 0, sizeof(struct frame));
93  f->retaddr = (unsigned long)function;
94  f->data = (unsigned long)data;
95  t->sp = (unsigned long)&f->flags;
96 #if ON_64BIT_ARCH
97  f->rbp = (unsigned long)&f->rax;
98 #else /* ON_64BIT_ARCH */
99  f->ebp = (unsigned long)&f->eax;
100 #endif /* ON_64BIT_ARCH */
101 }
102 /*--------------------------------------------------------------------------*/
103 static struct cooja_mtarch_thread *cooja_running_thread;
104 /*--------------------------------------------------------------------------*/
105 void cooja_sw(void)
106 {
107  /* Store registers */
108 #if ON_64BIT_ARCH
109  __asm__ (
110  "pushq %rax\n\t"
111  "pushq %rbx\n\t"
112  "pushq %rcx\n\t"
113  "pushq %rdx\n\t"
114  "pushq %rsi\n\t"
115  "pushq %rdi\n\t"
116  "pushq %rbp\n\t"
117  "pushq %rbp\n\t");
118 #else /* ON_64BIT_ARCH */
119  __asm__ (
120  "pushl %eax\n\t"
121  "pushl %ebx\n\t"
122  "pushl %ecx\n\t"
123  "pushl %edx\n\t"
124  "pushl %esi\n\t"
125  "pushl %edi\n\t"
126  "pushl %ebp\n\t"
127  "pushl %ebp\n\t");
128 #endif /* ON_64BIT_ARCH */
129 
130  /* Switch stack pointer */
131 #if ON_64BIT_ARCH
132  __asm__ ("movq %0, %%rax\n\t" : : "m" (cooja_running_thread));
133  __asm__ (
134  "movq (%rax), %rbx\n\t"
135  "movq %rsp, (%rax)\n\t"
136  "movq %rbx, %rsp\n\t"
137  );
138 #else /* ON_64BIT_ARCH */
139  __asm__ ("movl %0, %%eax\n\t" : : "m" (cooja_running_thread));
140  __asm__ (
141  "movl (%eax), %ebx\n\t"
142  "movl %esp, (%eax)\n\t"
143  "movl %ebx, %esp\n\t"
144  );
145 #endif /* ON_64BIT_ARCH */
146 
147  /* Restore previous registers */
148 #if ON_64BIT_ARCH
149  __asm__ (
150  "popq %rbp\n\t"
151  "popq %rbp\n\t"
152  "popq %rdi\n\t"
153  "popq %rsi\n\t"
154  "popq %rdx\n\t"
155  "popq %rcx\n\t"
156  "popq %rbx\n\t"
157  "popq %rax\n\t"
158 
159  "leave\n\t"
160  "ret\n\t"
161  );
162 #else /* ON_64BIT_ARCH */
163  __asm__ (
164  "popl %ebp\n\t"
165  "popl %ebp\n\t"
166  "popl %edi\n\t"
167  "popl %esi\n\t"
168  "popl %edx\n\t"
169  "popl %ecx\n\t"
170  "popl %ebx\n\t"
171  "popl %eax\n\t"
172 
173  "leave\n\t"
174  "ret\n\t"
175  );
176 #endif /* ON_64BIT_ARCH */
177 
178 }
179 
180 /*--------------------------------------------------------------------------*/
181 void
182 cooja_mtarch_exec(struct cooja_mtarch_thread *t)
183 {
184  cooja_running_thread = t;
185  cooja_sw();
186  cooja_running_thread = NULL;
187 }
188 /*--------------------------------------------------------------------------*/
189 void
190 cooja_mtarch_remove(void)
191 {
192 }
193 /*--------------------------------------------------------------------------*/
194 void
195 cooja_mtarch_yield(void)
196 {
197  cooja_sw();
198 }
199 /*--------------------------------------------------------------------------*/
200 void
201 cooja_mtarch_pstop(void)
202 {
203 }
204 /*--------------------------------------------------------------------------*/
205 void
206 cooja_mtarch_pstart(void)
207 {
208 }
209 /*--------------------------------------------------------------------------*/
210 int
211 cooja_mtarch_stack_usage(struct cooja_mt_thread *t)
212 {
213  int i;
214  for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
215  if(t->thread.stack[i] != i) {
216  return COOJA_MTARCH_STACKSIZE - i;
217  }
218  }
219  return -1;
220 }
221 /*--------------------------------------------------------------------------*/
#define NULL
The null pointer.