summaryrefslogtreecommitdiff
path: root/firmware/target/arm/system-arm.h
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-03-26 01:50:41 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-03-26 01:50:41 +0000
commitaf395f4db6ad7b83f9d9afefb1c0ceeedd140a45 (patch)
treeb631289b4a3b28d3c65b10d272d50298f377c69f /firmware/target/arm/system-arm.h
parent74d678fdbcbc427c057e7682ba0a0566e49a8b97 (diff)
downloadrockbox-af395f4db6ad7b83f9d9afefb1c0ceeedd140a45.tar.gz
rockbox-af395f4db6ad7b83f9d9afefb1c0ceeedd140a45.zip
Do core interrupt masking in a less general fashion and save some instructions to decrease size and speed things up a little bit. Small fix to a few places where interrupts would get enabled again where they shouldn't have been (context switching calls when disabled).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16811 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/system-arm.h')
-rw-r--r--firmware/target/arm/system-arm.h97
1 files changed, 72 insertions, 25 deletions
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index 774cdbcff4..3f1dfb16c8 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -74,27 +74,7 @@ static inline uint32_t swap_odd_even32(uint32_t value)
74 return value; 74 return value;
75} 75}
76 76
77static inline void enable_fiq(void) 77/* Core-level interrupt masking */
78{
79 /* Clear FIQ disable bit */
80 asm volatile (
81 "mrs r0, cpsr \n"\
82 "bic r0, r0, #0x40 \n"\
83 "msr cpsr_c, r0 "
84 : : : "r0"
85 );
86}
87
88static inline void disable_fiq(void)
89{
90 /* Set FIQ disable bit */
91 asm volatile (
92 "mrs r0, cpsr \n"\
93 "orr r0, r0, #0x40 \n"\
94 "msr cpsr_c, r0 "
95 : : : "r0"
96 );
97}
98 78
99/* This one returns the old status */ 79/* This one returns the old status */
100#define IRQ_ENABLED 0x00 80#define IRQ_ENABLED 0x00
@@ -108,8 +88,10 @@ static inline void disable_fiq(void)
108#define IRQ_FIQ_STATUS 0xc0 88#define IRQ_FIQ_STATUS 0xc0
109#define HIGHEST_IRQ_LEVEL IRQ_DISABLED 89#define HIGHEST_IRQ_LEVEL IRQ_DISABLED
110 90
111#define set_irq_level(status) set_interrupt_status((status), IRQ_STATUS) 91#define set_irq_level(status) \
112#define set_fiq_status(status) set_interrupt_status((status), FIQ_STATUS) 92 set_interrupt_status((status), IRQ_STATUS)
93#define set_fiq_status(status) \
94 set_interrupt_status((status), FIQ_STATUS)
113 95
114static inline int set_interrupt_status(int status, int mask) 96static inline int set_interrupt_status(int status, int mask)
115{ 97{
@@ -122,10 +104,75 @@ static inline int set_interrupt_status(int status, int mask)
122 "orr %0, %0, %2 \n" 104 "orr %0, %0, %2 \n"
123 "msr cpsr_c, %0 \n" 105 "msr cpsr_c, %0 \n"
124 : "=&r,r"(cpsr), "=&r,r"(oldstatus) 106 : "=&r,r"(cpsr), "=&r,r"(oldstatus)
125 : "r,i"(status & mask), [mask]"i,i"(mask) 107 : "r,i"(status & mask), [mask]"i,i"(mask));
126 );
127 108
128 return oldstatus; 109 return oldstatus;
129} 110}
130 111
112static inline void enable_interrupt(int mask)
113{
114 /* Clear I and/or F disable bit */
115 int tmp;
116 asm volatile (
117 "mrs %0, cpsr \n"
118 "bic %0, %0, %1 \n"
119 "msr cpsr_c, %0 \n"
120 : "=&r"(tmp) : "i"(mask));
121}
122
123static inline void disable_interrupt(int mask)
124{
125 /* Set I and/or F disable bit */
126 int tmp;
127 asm volatile (
128 "mrs %0, cpsr \n"
129 "orr %0, %0, %1 \n"
130 "msr cpsr_c, %0 \n"
131 : "=&r"(tmp) : "i"(mask));
132}
133
134#define disable_irq(void) \
135 disable_interrupt(IRQ_STATUS)
136
137#define enable_irq(void) \
138 enable_interrupt(IRQ_STATUS)
139
140#define disable_fiq(void) \
141 disable_interrupt(FIQ_STATUS)
142
143#define enable_fiq(void) \
144 enable_interrupt(FIQ_STATUS)
145
146static inline int disable_interrupt_save(int mask)
147{
148 /* Set I and/or F disable bit and return old cpsr value */
149 int cpsr, tmp;
150 asm volatile (
151 "mrs %1, cpsr \n"
152 "orr %0, %1, %2 \n"
153 "msr cpsr_c, %0 \n"
154 : "=&r"(tmp), "=&r"(cpsr)
155 : "i"(mask));
156 return cpsr;
157}
158
159#define disable_irq_save() \
160 disable_interrupt_save(IRQ_STATUS)
161
162#define disable_fiq_save() \
163 disable_interrupt_save(FIQ_STATUS)
164
165static inline void restore_interrupt(int cpsr)
166{
167 /* Set cpsr_c from value returned by disable_interrupt_save
168 * or set_interrupt_status */
169 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr));
170}
171
172#define restore_irq(cpsr) \
173 restore_interrupt(cpsr)
174
175#define restore_fiq(cpsr) \
176 restore_interrupt(cpsr)
177
131#endif /* SYSTEM_ARM_H */ 178#endif /* SYSTEM_ARM_H */