1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Alan Korr
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 /* Common to all ARM_ARCH */
30 #define IRQ_ENABLED 0x00
31 #define IRQ_DISABLED 0x80
32 #define IRQ_STATUS 0x80
33 #define FIQ_ENABLED 0x00
34 #define FIQ_DISABLED 0x40
35 #define FIQ_STATUS 0x40
36 #define IRQ_FIQ_ENABLED 0x00
37 #define IRQ_FIQ_DISABLED 0xc0
38 #define IRQ_FIQ_STATUS 0xc0
39 #define HIGHEST_IRQ_LEVEL IRQ_DISABLED
41 #define set_irq_level(status) \
42 set_interrupt_status((status), IRQ_STATUS)
43 #define set_fiq_status(status) \
44 set_interrupt_status((status), FIQ_STATUS)
46 #define disable_irq_save() \
47 disable_interrupt_save(IRQ_STATUS)
48 #define disable_fiq_save() \
49 disable_interrupt_save(FIQ_STATUS)
51 #define restore_irq(cpsr) \
52 restore_interrupt(cpsr)
53 #define restore_fiq(cpsr) \
54 restore_interrupt(cpsr)
56 #define disable_irq() \
57 disable_interrupt(IRQ_STATUS)
58 #define enable_irq() \
59 enable_interrupt(IRQ_STATUS)
60 #define disable_fiq() \
61 disable_interrupt(FIQ_STATUS)
62 #define enable_fiq() \
63 enable_interrupt(FIQ_STATUS)
65 /* Core-level interrupt masking */
67 static inline int set_interrupt_status(int status
, int mask
)
71 /* Read the old levels and set the new ones */
74 "bic %0, %1, %[mask] \n"
77 : "=&r,r"(cpsr
), "=&r,r"(oldstatus
)
78 : "r,i"(status
& mask
), [mask
]"i,i"(mask
));
83 static inline void restore_interrupt(int cpsr
)
85 /* Set cpsr_c from value returned by disable_interrupt_save
86 * or set_interrupt_status */
87 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr
));
90 /* ARM_ARCH version section for architecture*/
93 static inline uint16_t swap16(uint16_t value
)
95 result[15..8] = value[ 7..0];
96 result[ 7..0] = value[15..8];
100 asm volatile ("revsh %0, %1" /* xxAB */
101 : "=r"(retval
) : "r"((uint32_t)value
)); /* xxBA */
105 static inline uint32_t swap32(uint32_t value
)
107 result[31..24] = value[ 7.. 0];
108 result[23..16] = value[15.. 8];
109 result[15.. 8] = value[23..16];
110 result[ 7.. 0] = value[31..24];
114 asm volatile ("rev %0, %1" /* ABCD */
115 : "=r"(retval
) : "r"(value
)); /* DCBA */
119 static inline uint32_t swap_odd_even32(uint32_t value
)
122 result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
123 result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
126 asm volatile ("rev16 %0, %1" /* ABCD */
127 : "=r"(retval
) : "r"(value
)); /* BADC */
131 static inline void enable_interrupt(int mask
)
133 /* Clear I and/or F disable bit */
134 /* mask is expected to be constant and so only relevent branch
136 switch (mask
& IRQ_FIQ_STATUS
)
139 asm volatile ("cpsie i");
142 asm volatile ("cpsie f");
145 asm volatile ("cpsie if");
150 static inline void disable_interrupt(int mask
)
152 /* Set I and/or F disable bit */
153 /* mask is expected to be constant and so only relevent branch
155 switch (mask
& IRQ_FIQ_STATUS
)
158 asm volatile ("cpsid i");
161 asm volatile ("cpsid f");
164 asm volatile ("cpsid if");
169 static inline int disable_interrupt_save(int mask
)
171 /* Set I and/or F disable bit and return old cpsr value */
173 /* mask is expected to be constant and so only relevent branch
175 asm volatile("mrs %0, cpsr" : "=r"(cpsr
));
176 switch (mask
& IRQ_FIQ_STATUS
)
179 asm volatile ("cpsid i");
182 asm volatile ("cpsid f");
185 asm volatile ("cpsid if");
191 #else /* ARM_ARCH < 6 */
193 static inline uint16_t swap16(uint16_t value
)
195 result[15..8] = value[ 7..0];
196 result[ 7..0] = value[15..8];
199 return (value
>> 8) | (value
<< 8);
202 static inline uint32_t swap32(uint32_t value
)
204 result[31..24] = value[ 7.. 0];
205 result[23..16] = value[15.. 8];
206 result[15.. 8] = value[23..16];
207 result[ 7.. 0] = value[31..24];
212 "eor %1, %0, %0, ror #16 \n\t"
213 "bic %1, %1, #0xff0000 \n\t"
214 "mov %0, %0, ror #8 \n\t"
215 "eor %0, %0, %1, lsr #8 \n\t"
216 : "+r" (value
), "=r" (tmp
)
221 static inline uint32_t swap_odd_even32(uint32_t value
)
224 result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
225 result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
228 asm volatile ( /* ABCD */
229 "bic %1, %0, #0x00ff00 \n\t" /* AB.D */
230 "bic %0, %0, #0xff0000 \n\t" /* A.CD */
231 "mov %0, %0, lsr #8 \n\t" /* .A.C */
232 "orr %0, %0, %1, lsl #8 \n\t" /* B.D.|.A.C */
233 : "+r" (value
), "=r" (tmp
) /* BADC */
238 static inline void enable_interrupt(int mask
)
240 /* Clear I and/or F disable bit */
246 : "=&r"(tmp
) : "i"(mask
));
249 static inline void disable_interrupt(int mask
)
251 /* Set I and/or F disable bit */
257 : "=&r"(tmp
) : "i"(mask
));
260 static inline int disable_interrupt_save(int mask
)
262 /* Set I and/or F disable bit and return old cpsr value */
268 : "=&r"(tmp
), "=&r"(cpsr
)
273 #endif /* ARM_ARCH */
275 #endif /* SYSTEM_ARM_H */