2 * arch/ubicom32/include/asm/thread.h
3 * Ubicom32 architecture specific thread definitions.
5 * (C) Copyright 2009, Ubicom, Inc.
7 * This file is part of the Ubicom32 Linux Kernel Port.
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
23 * Ubicom32 implementation derived from (with many thanks):
28 #ifndef _ASM_UBICOM32_THREAD_H
29 #define _ASM_UBICOM32_THREAD_H
31 #if !defined(__ASSEMBLY__)
33 #include <asm/ptrace.h>
34 #include <asm/ubicom32-common.h>
37 typedef unsigned char thread_type_t
;
38 typedef void (*thread_exec_fn_t
)(void *arg
);
40 #define THREAD_NULL 0x40
41 #define THREAD_TYPE_HRT (1 << 0)
42 #define THREAD_TYPE_SPECIAL 0
43 #define THREAD_TYPE_NORMAL 0
44 #define THREAD_TYPE_BACKGROUND (1 << 1)
47 * This is the upper bound on the maximum hardware threads that one will find
48 * on a Ubicom processor. It is used to size per hardware thread data structures.
50 #define THREAD_ARCHITECTURAL_MAX 16
53 * TODO: Rename this at some point to be thread_
55 extern unsigned int sw_ksp
[THREAD_ARCHITECTURAL_MAX
];
61 static inline thread_t
thread_get_self(void)
66 * Note that ROSR has zeroes in bits 6 through 31 and so we don't need
67 * to do any additional bit masking here.
70 "lsr.4 %0, ROSR, #2 \n\t"
82 static inline void thread_suspend(void)
94 static inline void thread_resume(thread_t thread
)
97 "move.4 MT_ACTIVE_SET, %0 \n\t"
108 * thread_enable_mask()
109 * Enable all threads in the mask.
111 * All writes to MT_EN must be protected by the MT_EN_LOCK bit
113 static inline void thread_enable_mask(unsigned int mask
)
116 * must flush the pipeline twice.
117 * first pipe_flush is to ensure write to MT_EN is completed
118 * second one is to ensure any new instructions from
119 * the targeted thread (the one being disabled), that
120 * are issued while the write to MT_EN is being executed,
123 UBICOM32_LOCK(MT_EN_LOCK_BIT
);
125 "or.4 MT_EN, MT_EN, %0 \n\t"
132 UBICOM32_UNLOCK(MT_EN_LOCK_BIT
);
138 static inline void thread_enable(thread_t thread
)
140 thread_enable_mask(1 << thread
);
144 * thread_disable_mask()
145 * Disable all threads in the mask.
147 * All writes to MT_EN must be protected by the MT_EN_LOCK bit
149 static inline void thread_disable_mask(unsigned int mask
)
152 * must flush the pipeline twice.
153 * first pipe_flush is to ensure write to MT_EN is completed
154 * second one is to ensure any new instructions from
155 * the targeted thread (the one being disabled), that
156 * are issued while the write to MT_EN is being executed,
159 UBICOM32_LOCK(MT_EN_LOCK_BIT
);
161 "and.4 MT_EN, MT_EN, %0 \n\t"
168 UBICOM32_UNLOCK(MT_EN_LOCK_BIT
);
174 static inline void thread_disable(thread_t thread
)
176 thread_disable_mask(1 << thread
);
180 * thread_disable_others()
181 * Disable all other threads
183 static inline void thread_disable_others(void)
185 thread_t self
= thread_get_self();
186 thread_disable_mask(~(1 << self
));
190 * thread_is_trapped()
191 * Is the specified tid trapped?
193 static inline int thread_is_trapped(thread_t tid
)
195 int thread_mask
= (1 << tid
);
199 "move.4 %0, MT_TRAP \n\t"
203 return (trap_thread
& thread_mask
);
207 * thread_is_enabled()
208 * Is the specified tid enabled?
210 static inline int thread_is_enabled(thread_t tid
)
212 int thread_mask
= (1 << tid
);
216 "move.4 %0, MT_EN \n\t"
217 : "=d" (enabled_threads
)
220 return (enabled_threads
& thread_mask
);
224 * thread_get_instruction_count()
226 static inline unsigned int thread_get_instruction_count(void)
230 "move.4 %0, INST_CNT \n\t"
238 * pc could point to a speculative and cancelled instruction unless thread is disabled
240 static inline void *thread_get_pc(thread_t thread
)
244 "move.4 csr, %1 \n\t"
245 "setcsr_flush 0 \n\t"
247 "move.4 csr, #0 \n\t"
248 "setcsr_flush 0 \n\t"
250 : "r" ((thread
<< 9) | (1 << 8))
256 * thread_get_trap_cause()
257 * This should be called only when the thread is not running
259 static inline unsigned int thread_get_trap_cause(thread_t thread
)
263 "move.4 csr, %1 \n\t"
264 "setcsr_flush 0 \n\t"
265 "move.4 %0, trap_cause \n\t"
266 "move.4 csr, #0 \n\t"
267 "setcsr_flush 0 \n\t"
269 : "r" ((thread
<< 9) | (1 << 8))
275 * THREAD_STALL macro.
277 #define THREAD_STALL \
279 "move.4 mt_dbg_active_clr, #-1 \n\t" \
280 "pipe_flush 0 \n\t" \
285 extern unsigned int thread_get_mainline(void);
286 extern void thread_set_mainline(thread_t tid
);
287 extern thread_t
thread_alloc(void);
288 extern thread_t
thread_start(thread_t thread
, thread_exec_fn_t exec
, void *arg
, unsigned int *sp_high
, thread_type_t type
);
296 * Read and shift the current thread into reg
298 * Note that we don't need to mask the result as bits 6 through 31 of the
301 ".macro thread_get_self reg \n\t"
302 " lsr.4 \\reg, ROSR, #2 \n\t"
306 * thread_get_self_mask
307 * Read and shift the current thread mask into reg
309 ".macro thread_get_self_mask reg \n\t"
310 " lsr.4 \\reg, ROSR, #2 \n\t"
311 " lsl.4 \\reg, #1, \\reg \n\t" /* Thread bit */
315 #else /* __ASSEMBLY__ */
317 #include <asm/thread-asm.h>
319 #endif /* __ASSEMBLY__ */
320 #endif /* _ASM_UBICOM32_THREAD_H */