Contiki 2.5
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  * @(#)$Id: cooja_mtarch.c,v 1.7 2009/03/13 14:42:06 fros4943 Exp $
32  */
33 
34 #include <stddef.h>
35 
36 #include <limits.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include "sys/cooja_mt.h"
40 
41 #ifndef __WORDSIZE
42 #define __WORDSIZE 32
43 #endif /* __WORDSIZE */
44 
45 #ifndef ON_64BIT_ARCH
46 #if __WORDSIZE == 64
47 #define ON_64BIT_ARCH 1
48 #else /* ON_64BIT_ARCH */
49 #define ON_64BIT_ARCH 0
50 #endif /* __WORDSIZE == 64 */
51 #endif /* ON_64BIT_ARCH */
52 
53 struct frame {
54  unsigned long flags;
55 #if ON_64BIT_ARCH
56  unsigned long rbp;
57  unsigned long rdi;
58  unsigned long rsi;
59  unsigned long rdx;
60  unsigned long rcx;
61  unsigned long rbx;
62  unsigned long rax;
63 #else /* ON_64BIT_ARCH */
64  unsigned long ebp;
65  unsigned long edi;
66  unsigned long esi;
67  unsigned long edx;
68  unsigned long ecx;
69  unsigned long ebx;
70  unsigned long eax;
71 #endif /* ON_64BIT_ARCH */
72  unsigned long retaddr;
73  unsigned long retaddr2;
74  unsigned long data;
75 };
76 /*--------------------------------------------------------------------------*/
77 void
78 cooja_mtarch_init(void)
79 {
80 }
81 /*--------------------------------------------------------------------------*/
82 void
83 cooja_mtarch_start(struct cooja_mtarch_thread *t,
84  void (*function)(void *), void *data)
85 {
86  struct frame *f = (struct frame *)&t->stack[COOJA_MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)];
87  int i;
88 
89  for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
90  t->stack[i] = i;
91  }
92 
93  memset(f, 0, sizeof(struct frame));
94  f->retaddr = (unsigned long)function;
95  f->data = (unsigned long)data;
96  t->sp = (unsigned long)&f->flags;
97 #if ON_64BIT_ARCH
98  f->rbp = (unsigned long)&f->rax;
99 #else /* ON_64BIT_ARCH */
100  f->ebp = (unsigned long)&f->eax;
101 #endif /* ON_64BIT_ARCH */
102 }
103 /*--------------------------------------------------------------------------*/
104 static struct cooja_mtarch_thread *cooja_running_thread;
105 /*--------------------------------------------------------------------------*/
106 void cooja_sw(void)
107 {
108  /* Store registers */
109 #if ON_64BIT_ARCH
110  __asm__ (
111  "pushq %rax\n\t"
112  "pushq %rbx\n\t"
113  "pushq %rcx\n\t"
114  "pushq %rdx\n\t"
115  "pushq %rsi\n\t"
116  "pushq %rdi\n\t"
117  "pushq %rbp\n\t"
118  "pushq %rbp\n\t");
119 #else /* ON_64BIT_ARCH */
120  __asm__ (
121  "pushl %eax\n\t"
122  "pushl %ebx\n\t"
123  "pushl %ecx\n\t"
124  "pushl %edx\n\t"
125  "pushl %esi\n\t"
126  "pushl %edi\n\t"
127  "pushl %ebp\n\t"
128  "pushl %ebp\n\t");
129 #endif /* ON_64BIT_ARCH */
130 
131  /* Switch stack pointer */
132 #if ON_64BIT_ARCH
133  __asm__ ("movq %0, %%rax\n\t" : : "m" (cooja_running_thread));
134  __asm__ (
135  "movq (%rax), %rbx\n\t"
136  "movq %rsp, (%rax)\n\t"
137  "movq %rbx, %rsp\n\t"
138  );
139 #else /* ON_64BIT_ARCH */
140  __asm__ ("movl %0, %%eax\n\t" : : "m" (cooja_running_thread));
141  __asm__ (
142  "movl (%eax), %ebx\n\t"
143  "movl %esp, (%eax)\n\t"
144  "movl %ebx, %esp\n\t"
145  );
146 #endif /* ON_64BIT_ARCH */
147 
148  /* Restore previous registers */
149 #if ON_64BIT_ARCH
150  __asm__ (
151  "popq %rbp\n\t"
152  "popq %rbp\n\t"
153  "popq %rdi\n\t"
154  "popq %rsi\n\t"
155  "popq %rdx\n\t"
156  "popq %rcx\n\t"
157  "popq %rbx\n\t"
158  "popq %rax\n\t"
159 
160  "leave\n\t"
161  "ret\n\t"
162  );
163 #else /* ON_64BIT_ARCH */
164  __asm__ (
165  "popl %ebp\n\t"
166  "popl %ebp\n\t"
167  "popl %edi\n\t"
168  "popl %esi\n\t"
169  "popl %edx\n\t"
170  "popl %ecx\n\t"
171  "popl %ebx\n\t"
172  "popl %eax\n\t"
173 
174  "leave\n\t"
175  "ret\n\t"
176  );
177 #endif /* ON_64BIT_ARCH */
178 
179 }
180 
181 /*--------------------------------------------------------------------------*/
182 void
183 cooja_mtarch_exec(struct cooja_mtarch_thread *t)
184 {
185  cooja_running_thread = t;
186  cooja_sw();
187  cooja_running_thread = NULL;
188 }
189 /*--------------------------------------------------------------------------*/
190 void
191 cooja_mtarch_remove(void)
192 {
193 }
194 /*--------------------------------------------------------------------------*/
195 void
196 cooja_mtarch_yield(void)
197 {
198  cooja_sw();
199 }
200 /*--------------------------------------------------------------------------*/
201 void
202 cooja_mtarch_pstop(void)
203 {
204 }
205 /*--------------------------------------------------------------------------*/
206 void
207 cooja_mtarch_pstart(void)
208 {
209 }
210 /*--------------------------------------------------------------------------*/
211 int
212 cooja_mtarch_stack_usage(struct cooja_mt_thread *t)
213 {
214  int i;
215  for(i = 0; i < COOJA_MTARCH_STACKSIZE; ++i) {
216  if(t->thread.stack[i] != i) {
217  return COOJA_MTARCH_STACKSIZE - i;
218  }
219  }
220  return -1;
221 }
222 /*--------------------------------------------------------------------------*/