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

1/*
2 * arch/ubicom32/include/asm/ldsr.h
3 * Ubicom32 LDSR interface 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_LDSR_H
29#define _ASM_UBICOM32_LDSR_H
30
31#include <asm/ubicom32-common.h>
32#include <asm/types.h>
33#include <asm/thread.h>
34
35extern unsigned int ldsr_soft_irq_mask;
36
37/*
38 * ldsr_local_irq_is_disabled()
39 * Test if interrupts are disabled for this thread?
40 */
41static inline int ldsr_local_irq_is_disabled(void)
42{
43    int ret;
44    thread_t self = thread_get_self();
45    unsigned int mask = (1 << self);
46
47    asm volatile (
48    " and.4 %0, scratchpad1, %1 \n\t"
49        : "=r" (ret)
50        : "d" (mask)
51        : "cc"
52    );
53
54    /*
55     * We return a simple 1 == disabled, 0 == enabled
56     * losing which tid this is for, because Linux
57     * can restore interrupts on a different thread.
58     */
59    return ret >> self;
60}
61
62/*
63 * ldsr_local_irq_save()
64 * Get the current interrupt state and disable interrupts.
65 */
66static inline unsigned int ldsr_local_irq_save(void)
67{
68    int ret;
69    thread_t self = thread_get_self();
70    unsigned int mask = (1 << self);
71
72    /*
73     * Ensure the compiler can not optimize out the code
74     * (volatile) and that it does not "cache" values around
75     * the interrupt state change (memory). This ensures
76     * that interrupt changes are treated as a critical
77     * section.
78     */
79    asm volatile (
80    " and.4 %0, scratchpad1, %1 \n\t"
81    " or.4 scratchpad1, scratchpad1, %1 \n\t"
82        : "=&r" (ret)
83        : "d" (mask)
84        : "cc", "memory"
85    );
86
87    /*
88     * We return a simple 1 == disabled, 0 == enabled
89     * losing which tid this is for, because Linux
90     * can restore interrupts on a different thread.
91     */
92    return ret >> self;
93}
94
95/*
96 * ldsr_local_irq_restore()
97 * Restore this cpu's interrupt enable/disable state.
98 *
99 * Note: flags is either 0 or 1.
100 */
101static inline void ldsr_local_irq_restore(unsigned int flags)
102{
103    unsigned int temp;
104    thread_t self = thread_get_self();
105    unsigned int mask = (1 << self);
106    flags = (flags << self);
107
108    /*
109     * Ensure the compiler can not optimize out the code
110     * (volatile) and that it does not "cache" values around
111     * the interrupt state change (memory). This ensures
112     * that interrupt changes are treated as a critical
113     * section.
114     *
115     * Atomic change to our bit in scratchpad1 without
116     * causing any temporary glitch in the value and
117     * without effecting other values. Also this uses
118     * no branches so no penalties.
119     */
120    asm volatile (
121    " xor.4 %0, scratchpad1, %1 \n\t"
122    " and.4 %0, %2, %0 \n\t"
123    " xor.4 scratchpad1, scratchpad1, %0 \n\t"
124    " move.4 int_set0, %3 \n\t"
125        : "=&d"(temp)
126        : "d"(flags), "r"(mask), "r"(ldsr_soft_irq_mask)
127        : "cc", "memory"
128    );
129}
130
131/*
132 * ldsr_local_irq_disable_interrupt()
133 * Disable ints for this thread.
134 */
135static inline void ldsr_local_irq_disable(void)
136{
137    unsigned int mask = (1 << thread_get_self());
138
139    /*
140     * Ensure the compiler can not optimize out the code
141     * (volatile) and that it does not "cache" values around
142     * the interrupt state change (memory). This ensures
143     * that interrupt changes are treated as a critical
144     * section.
145     */
146    asm volatile (
147    " or.4 scratchpad1, scratchpad1, %0 \n\t"
148        :
149        : "d" (mask)
150        : "cc", "memory"
151    );
152}
153
154/*
155 * ldsr_local_irq_enable_interrupt
156 * Enable ints for this thread.
157 */
158static inline void ldsr_local_irq_enable(void)
159{
160    unsigned int mask = (1 << thread_get_self());
161
162    /*
163     * Ensure the compiler can not optimize out the code
164     * (volatile) and that it does not "cache" values around
165     * the interrupt state change (memory). This ensures
166     * that interrupt changes are treated as a critical
167     * section.
168     */
169    asm volatile (
170    " and.4 scratchpad1, scratchpad1, %0 \n\t"
171    " move.4 int_set0, %1 \n\t"
172        :
173        : "d" (~mask), "r" (ldsr_soft_irq_mask)
174        : "cc", "memory"
175    );
176}
177
178extern void ldsr_init(void);
179extern void ldsr_set_trap_irq(unsigned int irq);
180extern void ldsr_mask_vector(unsigned int vector);
181extern void ldsr_unmask_vector(unsigned int vector);
182extern void ldsr_enable_vector(unsigned int vector);
183extern void ldsr_disable_vector(unsigned int vector);
184extern thread_t ldsr_get_threadid(void);
185
186#endif /* _ASM_UBICOM32_LDSR_H */
187

Archive Download this file



interactive