Move c/h files implementing/defining standard library stuff into a new libc directory...
[kugel-rb.git] / firmware / target / arm / system-arm.h
blob0608f50a02b8e43f321c682b5e49e4dac625e2e6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #ifndef SYSTEM_ARM_H
22 #define SYSTEM_ARM_H
24 /* Common to all ARM_ARCH */
25 #define nop \
26 asm volatile ("nop")
28 void __div0(void);
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)
69 unsigned long cpsr;
70 int oldstatus;
71 /* Read the old levels and set the new ones */
72 asm volatile (
73 "mrs %1, cpsr \n"
74 "bic %0, %1, %[mask] \n"
75 "orr %0, %0, %2 \n"
76 "msr cpsr_c, %0 \n"
77 : "=&r,r"(cpsr), "=&r,r"(oldstatus)
78 : "r,i"(status & mask), [mask]"i,i"(mask));
80 return oldstatus;
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*/
92 #if ARM_ARCH >= 6
93 static inline uint16_t swap16(uint16_t value)
95 result[15..8] = value[ 7..0];
96 result[ 7..0] = value[15..8];
99 uint32_t retval;
100 asm volatile ("revsh %0, %1" /* xxAB */
101 : "=r"(retval) : "r"((uint32_t)value)); /* xxBA */
102 return retval;
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];
113 uint32_t retval;
114 asm volatile ("rev %0, %1" /* ABCD */
115 : "=r"(retval) : "r"(value)); /* DCBA */
116 return retval;
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]
125 uint32_t retval;
126 asm volatile ("rev16 %0, %1" /* ABCD */
127 : "=r"(retval) : "r"(value)); /* BADC */
128 return retval;
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
135 * is preserved */
136 switch (mask & IRQ_FIQ_STATUS)
138 case IRQ_STATUS:
139 asm volatile ("cpsie i");
140 break;
141 case FIQ_STATUS:
142 asm volatile ("cpsie f");
143 break;
144 case IRQ_FIQ_STATUS:
145 asm volatile ("cpsie if");
146 break;
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
154 * is preserved */
155 switch (mask & IRQ_FIQ_STATUS)
157 case IRQ_STATUS:
158 asm volatile ("cpsid i");
159 break;
160 case FIQ_STATUS:
161 asm volatile ("cpsid f");
162 break;
163 case IRQ_FIQ_STATUS:
164 asm volatile ("cpsid if");
165 break;
169 static inline int disable_interrupt_save(int mask)
171 /* Set I and/or F disable bit and return old cpsr value */
172 int cpsr;
173 /* mask is expected to be constant and so only relevent branch
174 * is preserved */
175 asm volatile("mrs %0, cpsr" : "=r"(cpsr));
176 switch (mask & IRQ_FIQ_STATUS)
178 case IRQ_STATUS:
179 asm volatile ("cpsid i");
180 break;
181 case FIQ_STATUS:
182 asm volatile ("cpsid f");
183 break;
184 case IRQ_FIQ_STATUS:
185 asm volatile ("cpsid if");
186 break;
188 return cpsr;
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];
210 uint32_t tmp;
211 asm volatile (
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)
218 return value;
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]
227 uint32_t tmp;
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 */
235 return value;
238 static inline void enable_interrupt(int mask)
240 /* Clear I and/or F disable bit */
241 int tmp;
242 asm volatile (
243 "mrs %0, cpsr \n"
244 "bic %0, %0, %1 \n"
245 "msr cpsr_c, %0 \n"
246 : "=&r"(tmp) : "i"(mask));
249 static inline void disable_interrupt(int mask)
251 /* Set I and/or F disable bit */
252 int tmp;
253 asm volatile (
254 "mrs %0, cpsr \n"
255 "orr %0, %0, %1 \n"
256 "msr cpsr_c, %0 \n"
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 */
263 int cpsr, tmp;
264 asm volatile (
265 "mrs %1, cpsr \n"
266 "orr %0, %1, %2 \n"
267 "msr cpsr_c, %0 \n"
268 : "=&r"(tmp), "=&r"(cpsr)
269 : "i"(mask));
270 return cpsr;
273 #endif /* ARM_ARCH */
275 #endif /* SYSTEM_ARM_H */