[444] | 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 |
---|