Root/target/linux/ubicom32/files/arch/ubicom32/include/asm/thread.h

1/*
2 * arch/ubicom32/include/asm/thread.h
3 * Ubicom32 architecture specific thread definitions.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
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.
13 *
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.
18 *
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/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28#ifndef _ASM_UBICOM32_THREAD_H
29#define _ASM_UBICOM32_THREAD_H
30
31#if !defined(__ASSEMBLY__)
32
33#include <asm/ptrace.h>
34#include <asm/ubicom32-common.h>
35
36typedef int thread_t;
37typedef unsigned char thread_type_t;
38typedef void (*thread_exec_fn_t)(void *arg);
39
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)
45
46/*
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.
49 */
50#define THREAD_ARCHITECTURAL_MAX 16
51
52/*
53 * TODO: Rename this at some point to be thread_
54 */
55extern unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
56
57
58/*
59 * thread_get_self()
60 */
61static inline thread_t thread_get_self(void)
62{
63    thread_t result;
64
65    /*
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.
68     */
69    asm (
70        "lsr.4 %0, ROSR, #2 \n\t"
71        : "=d" (result)
72        :
73        : "cc"
74    );
75
76    return result;
77}
78
79/*
80 * thread_suspend()
81 */
82static inline void thread_suspend(void)
83{
84    asm volatile (
85        "suspend\n\t"
86        :
87        :
88    );
89}
90
91/*
92 * thread_resume()
93 */
94static inline void thread_resume(thread_t thread)
95{
96    asm volatile (
97        "move.4 MT_ACTIVE_SET, %0 \n\t"
98        "pipe_flush 0 \n\t"
99        "pipe_flush 0 \n\t"
100        :
101        : "d" (1 << thread)
102    );
103}
104
105
106
107/*
108 * thread_enable_mask()
109 * Enable all threads in the mask.
110 *
111 * All writes to MT_EN must be protected by the MT_EN_LOCK bit
112 */
113static inline void thread_enable_mask(unsigned int mask)
114{
115    /*
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,
121     * are completed.
122     */
123    UBICOM32_LOCK(MT_EN_LOCK_BIT);
124    asm volatile (
125        "or.4 MT_EN, MT_EN, %0 \n\t"
126        "pipe_flush 0 \n\t"
127        "pipe_flush 0 \n\t"
128        :
129        : "d" (mask)
130        : "cc"
131    );
132    UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
133}
134
135/*
136 * thread_enable()
137 */
138static inline void thread_enable(thread_t thread)
139{
140    thread_enable_mask(1 << thread);
141}
142
143/*
144 * thread_disable_mask()
145 * Disable all threads in the mask.
146 *
147 * All writes to MT_EN must be protected by the MT_EN_LOCK bit
148 */
149static inline void thread_disable_mask(unsigned int mask)
150{
151    /*
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,
157     * are completed.
158     */
159    UBICOM32_LOCK(MT_EN_LOCK_BIT);
160    asm volatile (
161        "and.4 MT_EN, MT_EN, %0 \n\t"
162        "pipe_flush 0 \n\t"
163        "pipe_flush 0 \n\t"
164        :
165        : "d" (~mask)
166        : "cc"
167    );
168    UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
169}
170
171/*
172 * thread_disable()
173 */
174static inline void thread_disable(thread_t thread)
175{
176    thread_disable_mask(1 << thread);
177}
178
179/*
180 * thread_disable_others()
181 * Disable all other threads
182 */
183static inline void thread_disable_others(void)
184{
185    thread_t self = thread_get_self();
186    thread_disable_mask(~(1 << self));
187}
188
189/*
190 * thread_is_trapped()
191 * Is the specified tid trapped?
192 */
193static inline int thread_is_trapped(thread_t tid)
194{
195    int thread_mask = (1 << tid);
196    int trap_thread;
197
198    asm (
199        "move.4 %0, MT_TRAP \n\t"
200        : "=d" (trap_thread)
201        :
202    );
203    return (trap_thread & thread_mask);
204}
205
206/*
207 * thread_is_enabled()
208 * Is the specified tid enabled?
209 */
210static inline int thread_is_enabled(thread_t tid)
211{
212    int thread_mask = (1 << tid);
213    int enabled_threads;
214
215    asm (
216        "move.4 %0, MT_EN \n\t"
217        : "=d" (enabled_threads)
218        :
219    );
220    return (enabled_threads & thread_mask);
221}
222
223/*
224 * thread_get_instruction_count()
225 */
226static inline unsigned int thread_get_instruction_count(void)
227{
228    unsigned int result;
229    asm (
230        "move.4 %0, INST_CNT \n\t"
231        : "=r" (result)
232    );
233    return result;
234}
235
236/*
237 * thread_get_pc()
238 * pc could point to a speculative and cancelled instruction unless thread is disabled
239 */
240static inline void *thread_get_pc(thread_t thread)
241{
242    void *result;
243    asm (
244        "move.4 csr, %1 \n\t"
245        "setcsr_flush 0 \n\t"
246        "move.4 %0, pc \n\t"
247        "move.4 csr, #0 \n\t"
248        "setcsr_flush 0 \n\t"
249        : "=r" (result)
250        : "r" ((thread << 9) | (1 << 8))
251    );
252    return result;
253}
254
255/*
256 * thread_get_trap_cause()
257 * This should be called only when the thread is not running
258 */
259static inline unsigned int thread_get_trap_cause(thread_t thread)
260{
261    unsigned int result;
262    asm (
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"
268        : "=r" (result)
269        : "r" ((thread << 9) | (1 << 8))
270    );
271    return result;
272}
273
274/*
275 * THREAD_STALL macro.
276 */
277#define THREAD_STALL \
278        asm volatile ( \
279            "move.4 mt_dbg_active_clr, #-1 \n\t" \
280            "pipe_flush 0 \n\t" \
281            : \
282            : \
283        )
284
285extern unsigned int thread_get_mainline(void);
286extern void thread_set_mainline(thread_t tid);
287extern thread_t thread_alloc(void);
288extern thread_t thread_start(thread_t thread, thread_exec_fn_t exec, void *arg, unsigned int *sp_high, thread_type_t type);
289
290/*
291 * asm macros
292 */
293asm (
294/*
295 * thread_get_self
296 * Read and shift the current thread into reg
297 *
298 * Note that we don't need to mask the result as bits 6 through 31 of the
299 * ROSR are zeroes.
300 */
301".macro thread_get_self reg \n\t"
302" lsr.4 \\reg, ROSR, #2 \n\t"
303".endm \n\t"
304
305/*
306 * thread_get_self_mask
307 * Read and shift the current thread mask into reg
308 */
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 */
312".endm \n\t"
313);
314
315#else /* __ASSEMBLY__ */
316
317#include <asm/thread-asm.h>
318
319#endif /* __ASSEMBLY__ */
320#endif /* _ASM_UBICOM32_THREAD_H */
321

Archive Download this file



interactive