1 | /* |
---|
2 | * Copyright (c) 2011 Aeroflex Gaisler |
---|
3 | * |
---|
4 | * BSD license: |
---|
5 | * |
---|
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
7 | * of this software and associated documentation files (the "Software"), to deal |
---|
8 | * in the Software without restriction, including without limitation the rights |
---|
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
10 | * copies of the Software, and to permit persons to whom the Software is |
---|
11 | * furnished to do so, subject to the following conditions: |
---|
12 | * |
---|
13 | * The above copyright notice and this permission notice shall be included in |
---|
14 | * all copies or substantial portions of the Software. |
---|
15 | * |
---|
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
---|
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
22 | * THE SOFTWARE. |
---|
23 | */ |
---|
24 | |
---|
25 | |
---|
26 | #ifndef __LEONBARE_KERNEL_H__ |
---|
27 | #define __LEONBARE_KERNEL_H__ |
---|
28 | |
---|
29 | #include <asm-leon/contextswitch.h> |
---|
30 | #include <asm-leon/leonbare_debug.h> |
---|
31 | #include <asm-leon/leon.h> |
---|
32 | #ifndef __ASSEMBLER__ |
---|
33 | #include <asm-leon/leonbare_kernel_queue.h> |
---|
34 | #include <reent.h> |
---|
35 | #endif |
---|
36 | #include "irq.h" |
---|
37 | |
---|
38 | #define LEONBARE_RUNQ_READY_NR (2) /* queue 0-1 for ready */ |
---|
39 | #define LEONBARE_RUNQ_SUSPENDED_IDX (2) /* queue 2 for suspended */ |
---|
40 | #define LEONBARE_RUNQ_PREPARE_IDX (3) /* LEONBARE_RUNQ_READY_NR times queues */ |
---|
41 | #define LEONBARE_RUNQ_KILLED_IDX (LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR) /* queue 2 for killed threads */ |
---|
42 | #define LEONBARE_RUNQ_NR (LEONBARE_RUNQ_KILLED_IDX+1) |
---|
43 | |
---|
44 | #define LEONBARE_RUNQ_ISREADY(idx) ((idx) >= 0 && (idx) < LEONBARE_RUNQ_READY_NR) |
---|
45 | #define LEONBARE_RUNQ_ISPREPARE(idx) ((idx) >= LEONBARE_RUNQ_PREPARE_IDX && (idx) < LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR) |
---|
46 | #define LEONBARE_RUNQ_ISSUSPEND(idx) ((idx) == LEONBARE_RUNQ_SUSPENDED_IDX) |
---|
47 | #define LEONBARE_RUNQ_ISKILLED(idx) ((idx) == LEONBARE_RUNQ_KILLED_IDX) |
---|
48 | |
---|
49 | #ifndef __ASSEMBLER__ |
---|
50 | |
---|
51 | #ifndef NULL |
---|
52 | #define NULL ((void *)0) |
---|
53 | #endif |
---|
54 | |
---|
55 | #define MACRO_BEGIN do { |
---|
56 | #define MACRO_END } while (0) |
---|
57 | |
---|
58 | #define optbarrier() __asm__ __volatile__("": : :"memory") |
---|
59 | |
---|
60 | typedef struct leonbare_thread_ctx |
---|
61 | { |
---|
62 | unsigned long sf_locals[8]; |
---|
63 | unsigned long sf_ins[8]; |
---|
64 | unsigned long outs[8]; |
---|
65 | unsigned long globals[8]; |
---|
66 | unsigned long psr; |
---|
67 | unsigned long wim; |
---|
68 | unsigned long magic; |
---|
69 | unsigned long fpu; |
---|
70 | /* size aligned to 8 */ |
---|
71 | } leonbare_thread_ctx_t; |
---|
72 | #define LEONBARE_THREAD_CTX_SZ sizeof(struct leonbare_thread_ctx) |
---|
73 | |
---|
74 | typedef |
---|
75 | LBTAILQ_HEAD (leonbare_mutex_queue, leonbare_mutex) * |
---|
76 | leonbare_mutex_queue_t; |
---|
77 | |
---|
78 | #endif |
---|
79 | #define LEONBARE_THREAD_OFFSET_CTX 0 |
---|
80 | #ifndef __ASSEMBLER__ |
---|
81 | |
---|
82 | struct leonbare_thread_protect |
---|
83 | { |
---|
84 | unsigned int runq; |
---|
85 | unsigned int krp_runq_depth; |
---|
86 | unsigned int krp_k_depth; |
---|
87 | struct leonbare_mutex *krp_m; |
---|
88 | unsigned int krp_m_depth; |
---|
89 | unsigned int krp_flags;; |
---|
90 | unsigned int krp_flags_depth; |
---|
91 | }; |
---|
92 | |
---|
93 | #define LEONBARE_INT_DISABLE_DECL unsigned long _irq_flags = leonbare_disable_traps(); |
---|
94 | #define LEONBARE_INT_ENABLE_DECL leonbare_enable_traps(_irq_flags); |
---|
95 | |
---|
96 | #define leonbare_setu32p(a,v) leonbare_leon23_storenocache(a,v) |
---|
97 | #define leonbare_setu32(a,v) leonbare_leon23_storenocache(a,v) |
---|
98 | #define leonbare_getu32(a) leonbare_leon23_loadnocache(a) |
---|
99 | |
---|
100 | #define LEONBARE_KERNEL_UNCACHED |
---|
101 | #ifndef LEONBARE_KERNEL_UNCACHED |
---|
102 | #define LEONBARE_KERNEL_SETU32P(a,v) (a=v) |
---|
103 | #define LEONBARE_KERNEL_SETU32(a,v) (a=v) /* uncached version should return v */ |
---|
104 | #define LEONBARE_KERNEL_GETU32(a) (a) |
---|
105 | #define LEONBARE_KERNEL_GETU32P(a) (a) |
---|
106 | #define LEONBARE_KERNEL_GETI32(a) (a) |
---|
107 | #define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(a)) |
---|
108 | #define LEONBARE_KERNEL_GETU32P_BARE(a) (*(a)) /* uncached: no & */ |
---|
109 | #define LEONBARE_KERNEL_SETU32P_BARE(a,v) (*(a) = v) /* uncached: no & */ |
---|
110 | #else |
---|
111 | #define LEONBARE_KERNEL_SETU32P(a,v) (leonbare_setu32p(&a,v)) |
---|
112 | #define LEONBARE_KERNEL_SETU32(a,v) (leonbare_setu32p(&a,v)) /* uncached version should return v */ |
---|
113 | #define LEONBARE_KERNEL_GETU32(a) (leonbare_getu32(&a)) |
---|
114 | #define LEONBARE_KERNEL_GETU32P(a) ((void *)leonbare_getu32(&a)) |
---|
115 | #define LEONBARE_KERNEL_GETI32(a) (leonbare_getu32(&a)) |
---|
116 | #define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(LEONBARE_KERNEL_GETU32P(a))) |
---|
117 | #define LEONBARE_KERNEL_GETU32P_BARE(a) ((void *)leonbare_getu32(a)) /* uncached: no & */ |
---|
118 | #define LEONBARE_KERNEL_SETU32P_BARE(a,v) (leonbare_setu32p(a,v)) /* uncached: no & */ |
---|
119 | #endif |
---|
120 | |
---|
121 | |
---|
122 | #define LEONBARE_SMP_SPINLOCK_AQUIRE(l) |
---|
123 | #define LEONBARE_SMP_SPINLOCK_RELEASE(l) |
---|
124 | |
---|
125 | #define LEONBARE_ISQ_ISDISABLED ((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK) |
---|
126 | |
---|
127 | #define _LEONBARE_PROTECT_IRQ_START \ |
---|
128 | if (LEONBARE_KR_CURRENT->th_prot.krp_flags_depth++) { \ |
---|
129 | LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \ |
---|
130 | } else { \ |
---|
131 | LEONBARE_KR_CURRENT->th_prot.krp_flags = leonbare_disable_traps(); \ |
---|
132 | } |
---|
133 | |
---|
134 | #define _LEONBARE_PROTECT_IRQ_END \ |
---|
135 | if (--LEONBARE_KR_CURRENT->th_prot.krp_flags_depth) { \ |
---|
136 | LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \ |
---|
137 | } else { \ |
---|
138 | leonbare_enable_traps(LEONBARE_KR_CURRENT->th_prot.krp_flags); \ |
---|
139 | } |
---|
140 | |
---|
141 | #define _LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \ |
---|
142 | if (LEONBARE_KR_CURRENT->th_prot.krp_m_depth++) { \ |
---|
143 | LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \ |
---|
144 | } else { \ |
---|
145 | LEONBARE_SMP_SPINLOCK_AQUIRE(m->smp_lock); \ |
---|
146 | LEONBARE_KR_CURRENT->th_prot.krp_m = m; \ |
---|
147 | } |
---|
148 | |
---|
149 | #define _LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ |
---|
150 | LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \ |
---|
151 | if ((--LEONBARE_KR_CURRENT->th_prot.krp_m_depth) == 0) { \ |
---|
152 | LEONBARE_SMP_SPINLOCK_RELEASE(m->smp_lock); \ |
---|
153 | } |
---|
154 | |
---|
155 | #define _LEONBARE_PROTECT_KERNEL_START \ |
---|
156 | if (LEONBARE_KR_CURRENT->th_prot.krp_k_depth++ == 0) { \ |
---|
157 | LEONBARE_SMP_SPINLOCK_AQUIRE(LEONBARE_KR_LOCK); \ |
---|
158 | } |
---|
159 | |
---|
160 | #define _LEONBARE_PROTECT_KERNEL_END \ |
---|
161 | if ((--LEONBARE_KR_CURRENT->th_prot.krp_k_depth) == 0) { \ |
---|
162 | LEONBARE_SMP_SPINLOCK_RELEASE(LEONBARE_KR_LOCK); \ |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | #define LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \ |
---|
167 | _LEONBARE_PROTECT_IRQ_START; \ |
---|
168 | _LEONBARE_PROTECT_MUTEXSTRUCT_START(m) |
---|
169 | |
---|
170 | #define LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ |
---|
171 | _LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ |
---|
172 | _LEONBARE_PROTECT_IRQ_END; |
---|
173 | |
---|
174 | |
---|
175 | #define LEONBARE_PROTECT_KERNEL_START() \ |
---|
176 | _LEONBARE_PROTECT_IRQ_START; \ |
---|
177 | _LEONBARE_PROTECT_KERNEL_START; |
---|
178 | |
---|
179 | #define LEONBARE_PROTECT_KERNEL_END() \ |
---|
180 | _LEONBARE_PROTECT_KERNEL_END; \ |
---|
181 | _LEONBARE_PROTECT_IRQ_END; |
---|
182 | |
---|
183 | typedef struct leonbare_thread |
---|
184 | { |
---|
185 | struct leonbare_thread_ctx th_ctx; |
---|
186 | unsigned int th_flags; |
---|
187 | |
---|
188 | int th_account; /* how many ticks the thread stays in the readyqueue for one round */ |
---|
189 | int th_caccount; /* current value of th_account, updated on reinsertion */ |
---|
190 | unsigned int th_pri_idx; /* ready queue index */ |
---|
191 | unsigned int th_runq_idx; /* ready queue index index */ |
---|
192 | unsigned int th_runq_which; /* 0: ready queue, 1: ready prepare queue */ |
---|
193 | |
---|
194 | char *th_name; |
---|
195 | int th_result; |
---|
196 | int (*th_func) (void *); |
---|
197 | void *th_arg; |
---|
198 | char *th_stack_base; |
---|
199 | unsigned int th_stack_size; |
---|
200 | struct _reent th_reent; /* reentrant structure for newlib */ |
---|
201 | struct _reent *th_reentp; /* pointer to eather pt_reent or global reent */ |
---|
202 | |
---|
203 | struct leonbare_thread_protect th_prot; |
---|
204 | |
---|
205 | LBTAILQ_ENTRY (leonbare_thread) th_runq; |
---|
206 | LBTAILQ_ENTRY (leonbare_thread) th_allq; |
---|
207 | LBTAILQ_ENTRY (leonbare_thread) th_mutex; |
---|
208 | struct leonbare_mutex_queue th_mutex_locked; |
---|
209 | |
---|
210 | } *leonbare_thread_t __attribute__ ((aligned (8))); |
---|
211 | |
---|
212 | #define LEONBARE_TH_FLAGS_get(c) LEONBARE_KERNEL_GETU32((c)->th_flags) |
---|
213 | #define LEONBARE_TH_ACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_account) |
---|
214 | #define LEONBARE_TH_CACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_caccount) |
---|
215 | |
---|
216 | #define LEONBARE_TH_PRI_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_pri_idx) |
---|
217 | #define LEONBARE_TH_RUNQ_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_idx) |
---|
218 | #define LEONBARE_TH_RUNQ_WHICH_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_which) |
---|
219 | |
---|
220 | #define LEONBARE_TH_NAME_get(c) LEONBARE_KERNEL_GETU32P((c)->th_name) |
---|
221 | #define LEONBARE_TH_RESULT_get(c) LEONBARE_KERNEL_GETI32((c)->th_result) |
---|
222 | #define LEONBARE_TH_FUNC_get(c) LEONBARE_KERNEL_GETU32((c)->th_func) |
---|
223 | #define LEONBARE_TH_ARG_get(c) LEONBARE_KERNEL_GETU32((c)->th_arg) |
---|
224 | #define LEONBARE_TH_STACK_BASE_get(c) LEONBARE_KERNEL_GETU32P((c)->th_stack_base) |
---|
225 | #define LEONBARE_TH_STACK_SIZE_get(c) LEONBARE_KERNEL_GETU32((c)->th_stack_size) |
---|
226 | #define LEONBARE_TH_REENTP_get(c) LEONBARE_KERNEL_GETU32P((c)->th_reentp) |
---|
227 | |
---|
228 | |
---|
229 | |
---|
230 | |
---|
231 | #define LEONBARE_TH_NAME(c) (c->th_name) |
---|
232 | #define LEONBARE_TH_NAME_DBG(c) (LEONBARE_TH_NAME(c) ? LEONBARE_TH_NAME(c) : "<unknown>") |
---|
233 | |
---|
234 | #define LEONBARE_REENT_SET(p) ((_impure_ptr=(p)->th_reentp)==_impure_ptr) |
---|
235 | |
---|
236 | #define LEONBARE_TH_READY (1<<0) |
---|
237 | #define LEONBARE_TH_SUSPENDED (1<<1) |
---|
238 | #define LEONBARE_TH_TERMINATED (1<<2) |
---|
239 | #define LEONBARE_TH_FINISHED (1<<3) |
---|
240 | |
---|
241 | #define LEONBARE_TH_SATEMASK (LEONBARE_TH_READY | \ |
---|
242 | LEONBARE_TH_SUSPENDED | \ |
---|
243 | LEONBARE_TH_TERMINATED | \ |
---|
244 | LEONBARE_TH_FINISHED) |
---|
245 | |
---|
246 | #define LEONBARE_TH_SETSTATE(c,f) c->th_flags = ((c->th_flags & ~LEONBARE_TH_SATEMASK) | (f & LEONBARE_TH_SATEMASK)) |
---|
247 | #define LEONBARE_TH_ORSTATE(c,f) c->th_flags |= (f & LEONBARE_TH_SATEMASK) |
---|
248 | |
---|
249 | typedef LBTAILQ_HEAD (leonbare_thread_queue, |
---|
250 | leonbare_thread) * leonbare_thread_queue_t; |
---|
251 | |
---|
252 | extern struct leonbare_kernel leonbare_kernel; |
---|
253 | #define KERNEL_GLOBAL leonbare_kernel |
---|
254 | typedef struct leonbare_kernel |
---|
255 | { |
---|
256 | leonbare_thread_t kr_cur, kr_next; |
---|
257 | struct leonbare_thread_queue kr_runq[LEONBARE_RUNQ_NR]; |
---|
258 | struct leonbare_thread_queue kr_allq; |
---|
259 | struct leonbare_mutex_queue kr_allm; |
---|
260 | int kr_is_inkernel, kr_need_schedule, kr_is_preemption, kr_runq_which; |
---|
261 | int kr_protect_flags; |
---|
262 | } leonbare_kernel_t __attribute__ ((aligned (8))); |
---|
263 | #define LEONBARE_KR_CURRENT (KERNEL_GLOBAL.kr_cur) |
---|
264 | #define LEONBARE_KR_NEXT (KERNEL_GLOBAL.kr_next) |
---|
265 | #define LEONBARE_KR_RUNQ(i) (&(KERNEL_GLOBAL.kr_runq[i])) |
---|
266 | #define LEONBARE_KR_RUNQ_WHICH (KERNEL_GLOBAL.kr_runq_which) |
---|
267 | #define LEONBARE_KR_ALLQ (&(KERNEL_GLOBAL.kr_allq)) |
---|
268 | #define LEONBARE_KR_ALLM (&(KERNEL_GLOBAL.kr_allm)) |
---|
269 | #define LEONBARE_KR_IS_IN_KERNEL (KERNEL_GLOBAL.kr_is_inkernel) |
---|
270 | #define LEONBARE_KR_IS_PREEMPTION (KERNEL_GLOBAL.kr_is_preemption) |
---|
271 | |
---|
272 | #define LEONBARE_KR_NEED_SCHEDULE (LEONBARE_KR_CURRENT != LEONBARE_KR_NEXT) |
---|
273 | |
---|
274 | #define LEONBARE_STACKALIGN(sp) ((((unsigned int)sp) + 7) & ~7) |
---|
275 | |
---|
276 | /* context switching macros, implemented via setjmp/longjmp plus saving errno */ |
---|
277 | #define SAVE_CONTEXT(t) ( _leonbare_kernel_savecontext((t), 0) ) |
---|
278 | #define RESTORE_CONTEXT(t) _leonbare_kernel_switchto((t), 1) |
---|
279 | |
---|
280 | #define KERNEL_SCHEDULE(f,retval) \ |
---|
281 | MACRO_BEGIN \ |
---|
282 | LEONBARE_KR_IS_IN_KERNEL--; \ |
---|
283 | if (LEONBARE_KR_IS_IN_KERNEL == 0 && LEONBARE_KR_NEED_SCHEDULE) { \ |
---|
284 | LEONBARE_KR_IS_IN_KERNEL++; \ |
---|
285 | if ((f) && (SAVE_CONTEXT(LEONBARE_KR_CURRENT) == 0)) { \ |
---|
286 | leonbare_sched(); \ |
---|
287 | } \ |
---|
288 | optbarrier(); \ |
---|
289 | LEONBARE_KR_IS_IN_KERNEL--; \ |
---|
290 | } \ |
---|
291 | MACRO_END |
---|
292 | |
---|
293 | #define KERNEL_ENTER LEONBARE_KR_IS_IN_KERNEL++; |
---|
294 | #define KERNEL_EXIT(f,ret) KERNEL_SCHEDULE(f,ret) |
---|
295 | |
---|
296 | int leonbare_thread_init (); |
---|
297 | int leonbare_thread_create (struct leonbare_thread *thread, char *stack, |
---|
298 | int stacksize); |
---|
299 | int leonbare_sched_update (); |
---|
300 | leonbare_thread_t leonbare_sched_paytime (); |
---|
301 | void leonbare_sched_insert (struct leonbare_thread *thread, int head, |
---|
302 | int prepare); |
---|
303 | unsigned int leonbare_sched (); |
---|
304 | unsigned int reschedule (); |
---|
305 | unsigned int _leonbare_kernel_switchto (struct leonbare_thread *old, |
---|
306 | struct leonbare_thread *new); |
---|
307 | |
---|
308 | #define LEONBARE_STACK_DEFINE(n,size) unsigned char n[size] __attribute__((aligned(8))); |
---|
309 | #define LEONBARE_STACK_SIZE_DEFAULT 1024*20 |
---|
310 | |
---|
311 | typedef struct leonbare_mutex |
---|
312 | { |
---|
313 | unsigned int mx_owner_cnt; |
---|
314 | leonbare_thread_t mx_owner; |
---|
315 | struct leonbare_thread_queue mx_threads; |
---|
316 | LBTAILQ_ENTRY (leonbare_mutex) mx_allm; |
---|
317 | LBTAILQ_ENTRY (leonbare_mutex) mx_locked; |
---|
318 | |
---|
319 | } *leonbare_mutex_t; |
---|
320 | |
---|
321 | #define LEONBARE_MUTEX_OWNER_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner) |
---|
322 | #define LEONBARE_MUTEX_OWNER_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner,o) |
---|
323 | #define LEONBARE_MUTEX_OWNER_CNT_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner_cnt) |
---|
324 | #define LEONBARE_MUTEX_OWNER_CNT_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner_cnt,o) |
---|
325 | |
---|
326 | #define LEONBARE_MUTEX_LOCK_TIMEOUT -1 |
---|
327 | #define LEONBARE_MUTEX_LOCK_OK 0 |
---|
328 | #define LEONBARE_MUTEX_LOCK_ERROR 1 |
---|
329 | |
---|
330 | #define LEONBARE_MUTEX_UNLOCK_OK 0 |
---|
331 | #define LEONBARE_MUTEX_UNLOCK_ERROR 1 |
---|
332 | |
---|
333 | |
---|
334 | #define LEONBARE_PROTECT_DECL(flags) unsigned long flags; |
---|
335 | #define LEONBARE_PROTECT_KERNEL(flags) flags = leonbare_disable_traps(); |
---|
336 | #define LEONBARE_UNPROTECT_KERNEL(flags) leonbare_enable_traps(flags); |
---|
337 | |
---|
338 | #define LEONBARE_PROTECT_MUTEX(flags,m) flags = leonbare_disable_traps(); |
---|
339 | #define LEONBARE_UNPROTECT_MUTEX(flags,m) leonbare_enable_traps(flags); |
---|
340 | |
---|
341 | #else |
---|
342 | |
---|
343 | #define LEONBARE_THREAD_CTX_STORE_LOCALS(base_reg) \ |
---|
344 | std %l0, [%base_reg + LEONBARE_THREAD_CTX_STACK_L0]; \ |
---|
345 | std %l2, [%base_reg + LEONBARE_THREAD_CTX_STACK_L2]; \ |
---|
346 | std %l4, [%base_reg + LEONBARE_THREAD_CTX_STACK_L4]; \ |
---|
347 | std %l6, [%base_reg + LEONBARE_THREAD_CTX_STACK_L6]; |
---|
348 | |
---|
349 | #define LEONBARE_THREAD_CTX_STORE_INS(base_reg) \ |
---|
350 | std %i0, [%base_reg + LEONBARE_THREAD_CTX_STACK_I0]; \ |
---|
351 | std %i2, [%base_reg + LEONBARE_THREAD_CTX_STACK_I2]; \ |
---|
352 | std %i4, [%base_reg + LEONBARE_THREAD_CTX_STACK_I4]; \ |
---|
353 | std %i6, [%base_reg + LEONBARE_THREAD_CTX_STACK_I6]; |
---|
354 | |
---|
355 | #define LEONBARE_THREAD_CTX_STORE_OUTS(base_reg) \ |
---|
356 | std %o0, [%base_reg + LEONBARE_THREAD_CTX_STACK_O0]; \ |
---|
357 | std %o2, [%base_reg + LEONBARE_THREAD_CTX_STACK_O2]; \ |
---|
358 | std %o4, [%base_reg + LEONBARE_THREAD_CTX_STACK_O4]; \ |
---|
359 | std %o6, [%base_reg + LEONBARE_THREAD_CTX_STACK_O6]; |
---|
360 | |
---|
361 | #define LEONBARE_THREAD_CTX_STORE_GLOBALS(base_reg) \ |
---|
362 | st %g1, [%base_reg + LEONBARE_THREAD_CTX_STACK_G1]; \ |
---|
363 | std %g2, [%base_reg + LEONBARE_THREAD_CTX_STACK_G2]; \ |
---|
364 | std %g4, [%base_reg + LEONBARE_THREAD_CTX_STACK_G4]; \ |
---|
365 | std %g6, [%base_reg + LEONBARE_THREAD_CTX_STACK_G6]; |
---|
366 | |
---|
367 | |
---|
368 | #define LEONBARE_THREAD_CTX_LOAD_LOCALS(base_reg) \ |
---|
369 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L0], %l0; \ |
---|
370 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L2], %l2; \ |
---|
371 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L4], %l4; \ |
---|
372 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L6], %l6; |
---|
373 | |
---|
374 | #define LEONBARE_THREAD_CTX_LOAD_INS(base_reg) \ |
---|
375 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I0], %i0; \ |
---|
376 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I2], %i2; \ |
---|
377 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I4], %i4; \ |
---|
378 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I6], %i6; |
---|
379 | |
---|
380 | #define LEONBARE_THREAD_CTX_LOAD_OUTS(base_reg) \ |
---|
381 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O0], %o0; \ |
---|
382 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O2], %o2; \ |
---|
383 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O4], %o4; \ |
---|
384 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O6], %o6; |
---|
385 | |
---|
386 | #define LEONBARE_THREAD_CTX_LOAD_GLOBALS(base_reg) \ |
---|
387 | ld [%base_reg + LEONBARE_THREAD_CTX_STACK_G1], %g1; \ |
---|
388 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G2], %g2; \ |
---|
389 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G4], %g4; \ |
---|
390 | ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G6], %g6; |
---|
391 | |
---|
392 | |
---|
393 | #define LEONBARE_THREAD_CTX_STACK_L0 (0*8*4) |
---|
394 | #define LEONBARE_THREAD_CTX_STACK_L2 (LEONBARE_THREAD_CTX_STACK_L0+(2*4)) |
---|
395 | #define LEONBARE_THREAD_CTX_STACK_L4 (LEONBARE_THREAD_CTX_STACK_L0+(4*4)) |
---|
396 | #define LEONBARE_THREAD_CTX_STACK_L6 (LEONBARE_THREAD_CTX_STACK_L0+(6*4)) |
---|
397 | |
---|
398 | #define LEONBARE_THREAD_CTX_STACK_I0 (1*8*4) |
---|
399 | #define LEONBARE_THREAD_CTX_STACK_I2 (LEONBARE_THREAD_CTX_STACK_I0+(2*4)) |
---|
400 | #define LEONBARE_THREAD_CTX_STACK_I4 (LEONBARE_THREAD_CTX_STACK_I0+(4*4)) |
---|
401 | #define LEONBARE_THREAD_CTX_STACK_I6 (LEONBARE_THREAD_CTX_STACK_I0+(6*4)) |
---|
402 | |
---|
403 | #define LEONBARE_THREAD_CTX_STACK_O0 (2*8*4) |
---|
404 | #define LEONBARE_THREAD_CTX_STACK_O2 (LEONBARE_THREAD_CTX_STACK_O0+(2*4)) |
---|
405 | #define LEONBARE_THREAD_CTX_STACK_O4 (LEONBARE_THREAD_CTX_STACK_O0+(4*4)) |
---|
406 | #define LEONBARE_THREAD_CTX_STACK_O6 (LEONBARE_THREAD_CTX_STACK_O0+(6*4)) |
---|
407 | |
---|
408 | #define LEONBARE_THREAD_CTX_STACK_G0 (3*8*4) |
---|
409 | #define LEONBARE_THREAD_CTX_STACK_G1 (LEONBARE_THREAD_CTX_STACK_G0+(1*4)) |
---|
410 | #define LEONBARE_THREAD_CTX_STACK_G2 (LEONBARE_THREAD_CTX_STACK_G0+(2*4)) |
---|
411 | #define LEONBARE_THREAD_CTX_STACK_G4 (LEONBARE_THREAD_CTX_STACK_G0+(4*4)) |
---|
412 | #define LEONBARE_THREAD_CTX_STACK_G6 (LEONBARE_THREAD_CTX_STACK_G0+(6*4)) |
---|
413 | |
---|
414 | #define LEONBARE_THREAD_CTX_STACK_PSR (4*8*4) |
---|
415 | #define LEONBARE_THREAD_CTX_STACK_WIM (LEONBARE_THREAD_CTX_STACK_PSR+4) |
---|
416 | #define LEONBARE_THREAD_CTX_STACK_MAGIC (LEONBARE_THREAD_CTX_STACK_PSR+8) |
---|
417 | #define LEONBARE_THREAD_CTX_STACK_FPU (LEONBARE_THREAD_CTX_STACK_PSR+12) |
---|
418 | |
---|
419 | #define LEONBARE_THREAD_CTX_SZ (LEONBARE_THREAD_CTX_STACK_PSR+16) |
---|
420 | |
---|
421 | #endif /* __ASSEMBLER__ */ |
---|
422 | |
---|
423 | # define LEONBARE_STOPALL \ |
---|
424 | LBDEBUG_HEADER_PRINTF(LBDEBUG_ALWAYS_NR,"Stopped at %s(%d), possibly not implemented yet\n",__FUNCTION__,__LINE__); \ |
---|
425 | _leonbare_Stop(); |
---|
426 | |
---|
427 | #define LEONBARE_THREAD_CTX_MAGIC 0x1234 |
---|
428 | |
---|
429 | #ifdef LBDEBUG_DO_ASSERT |
---|
430 | #define LEONBARE_VERIFYIRQDISABLED() LBPASSERT(((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK),"Irq must be disabled (pil==0xf)\n",0) |
---|
431 | #define LEONBARE_VERIFYSCHED() leonbare_sched_verify() |
---|
432 | #else |
---|
433 | #define LEONBARE_VERIFYIRQDISABLED() |
---|
434 | #define LEONBARE_VERIFYSCHED() |
---|
435 | #endif |
---|
436 | #define LEONBARE_PRINTQUEUES() if (PDEBUG_FLAGS_CHECK(LBDEBUG_QUEUE_NR)) { leonbare_sched_printqueue(); } |
---|
437 | |
---|
438 | #endif |
---|