diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-03-26 01:50:41 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-03-26 01:50:41 +0000 |
commit | af395f4db6ad7b83f9d9afefb1c0ceeedd140a45 (patch) | |
tree | b631289b4a3b28d3c65b10d272d50298f377c69f /firmware/target/arm/system-arm.h | |
parent | 74d678fdbcbc427c057e7682ba0a0566e49a8b97 (diff) | |
download | rockbox-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.h | 97 |
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 | ||
77 | static 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 | |||
88 | static 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 | ||
114 | static inline int set_interrupt_status(int status, int mask) | 96 | static 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 | ||
112 | static 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 | |||
123 | static 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 | |||
146 | static 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 | |||
165 | static 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 */ |