diff options
-rw-r--r-- | firmware/kernel.c | 14 | ||||
-rw-r--r-- | firmware/target/arm/as3525/fmradio-i2c-as3525.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c | 34 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 6 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 6 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-as3525.c | 52 | ||||
-rw-r--r-- | firmware/target/arm/crt0.S | 29 | ||||
-rw-r--r-- | firmware/target/arm/system-arm.h | 10 |
8 files changed, 105 insertions, 48 deletions
diff --git a/firmware/kernel.c b/firmware/kernel.c index 155205749f..0b39e29126 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -1195,9 +1195,7 @@ int semaphore_wait(struct semaphore *s, int timeout) | |||
1195 | * in 'semaphore_init'. */ | 1195 | * in 'semaphore_init'. */ |
1196 | void semaphore_release(struct semaphore *s) | 1196 | void semaphore_release(struct semaphore *s) |
1197 | { | 1197 | { |
1198 | #if defined(HAVE_PRIORITY_SCHEDULING) && defined(irq_enabled_checkval) | ||
1199 | unsigned int result = THREAD_NONE; | 1198 | unsigned int result = THREAD_NONE; |
1200 | #endif | ||
1201 | int oldlevel; | 1199 | int oldlevel; |
1202 | 1200 | ||
1203 | oldlevel = disable_irq_save(); | 1201 | oldlevel = disable_irq_save(); |
@@ -1209,11 +1207,7 @@ void semaphore_release(struct semaphore *s) | |||
1209 | KERNEL_ASSERT(s->count == 0, | 1207 | KERNEL_ASSERT(s->count == 0, |
1210 | "semaphore_release->threads queued but count=%d!\n", s->count); | 1208 | "semaphore_release->threads queued but count=%d!\n", s->count); |
1211 | s->queue->retval = OBJ_WAIT_SUCCEEDED; /* indicate explicit wake */ | 1209 | s->queue->retval = OBJ_WAIT_SUCCEEDED; /* indicate explicit wake */ |
1212 | #if defined(HAVE_PRIORITY_SCHEDULING) && defined(irq_enabled_checkval) | ||
1213 | result = wakeup_thread(&s->queue); | 1210 | result = wakeup_thread(&s->queue); |
1214 | #else | ||
1215 | wakeup_thread(&s->queue); | ||
1216 | #endif | ||
1217 | } | 1211 | } |
1218 | else | 1212 | else |
1219 | { | 1213 | { |
@@ -1228,11 +1222,11 @@ void semaphore_release(struct semaphore *s) | |||
1228 | corelock_unlock(&s->cl); | 1222 | corelock_unlock(&s->cl); |
1229 | restore_irq(oldlevel); | 1223 | restore_irq(oldlevel); |
1230 | 1224 | ||
1231 | #if defined(HAVE_PRIORITY_SCHEDULING) && defined(irq_enabled_checkval) | 1225 | #if defined(HAVE_PRIORITY_SCHEDULING) && defined(is_thread_context) |
1232 | /* No thread switch if IRQ disabled - it's probably called via ISR. | 1226 | /* No thread switch if not thread context */ |
1233 | * switch_thread would as well enable them anyway. */ | 1227 | if((result & THREAD_SWITCH) && is_thread_context()) |
1234 | if((result & THREAD_SWITCH) && irq_enabled_checkval(oldlevel)) | ||
1235 | switch_thread(); | 1228 | switch_thread(); |
1236 | #endif | 1229 | #endif |
1230 | (void)result; | ||
1237 | } | 1231 | } |
1238 | #endif /* HAVE_SEMAPHORE_OBJECTS */ | 1232 | #endif /* HAVE_SEMAPHORE_OBJECTS */ |
diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c index 3da42e31b2..5d05956799 100644 --- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c +++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c | |||
@@ -195,8 +195,8 @@ void tuner_isr(void) | |||
195 | /* read and clear the interrupt */ | 195 | /* read and clear the interrupt */ |
196 | if (GPIOA_MIS & (1<<4)) { | 196 | if (GPIOA_MIS & (1<<4)) { |
197 | semaphore_release(&rds_sema); | 197 | semaphore_release(&rds_sema); |
198 | GPIOA_IC = (1<<4); | ||
198 | } | 199 | } |
199 | GPIOA_IC = (1<<4); | ||
200 | } | 200 | } |
201 | 201 | ||
202 | /* Captures RDS data and processes it */ | 202 | /* Captures RDS data and processes it */ |
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c index 7f82b692c7..8244c475fa 100644 --- a/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c +++ b/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c | |||
@@ -30,6 +30,7 @@ static bool hold_button = false; | |||
30 | 30 | ||
31 | #ifdef HAVE_SCROLLWHEEL | 31 | #ifdef HAVE_SCROLLWHEEL |
32 | #define SCROLLWHEEL_BITS (1<<7|1<<6) | 32 | #define SCROLLWHEEL_BITS (1<<7|1<<6) |
33 | #define SCROLLWHEEL_BITS_POS 6 | ||
33 | /* TIMER units */ | 34 | /* TIMER units */ |
34 | #define TIMER_TICK (KERNEL_TIMER_FREQ/HZ)/* how long a tick lasts */ | 35 | #define TIMER_TICK (KERNEL_TIMER_FREQ/HZ)/* how long a tick lasts */ |
35 | #define TIMER_MS (TIMER_TICK/(1000/HZ))/* how long a ms lasts */ | 36 | #define TIMER_MS (TIMER_TICK/(1000/HZ))/* how long a ms lasts */ |
@@ -78,10 +79,17 @@ static void scrollwheel(unsigned int wheel_value) | |||
78 | 79 | ||
79 | unsigned int btn = BUTTON_NONE; | 80 | unsigned int btn = BUTTON_NONE; |
80 | 81 | ||
81 | if (old_wheel_value == wheel_tbl[0][wheel_value]) | 82 | if (hold_button) |
83 | { | ||
84 | } | ||
85 | else if (old_wheel_value == wheel_tbl[0][wheel_value]) | ||
86 | { | ||
82 | btn = BUTTON_SCROLL_FWD; | 87 | btn = BUTTON_SCROLL_FWD; |
88 | } | ||
83 | else if (old_wheel_value == wheel_tbl[1][wheel_value]) | 89 | else if (old_wheel_value == wheel_tbl[1][wheel_value]) |
90 | { | ||
84 | btn = BUTTON_SCROLL_BACK; | 91 | btn = BUTTON_SCROLL_BACK; |
92 | } | ||
85 | 93 | ||
86 | if (btn == BUTTON_NONE) | 94 | if (btn == BUTTON_NONE) |
87 | { | 95 | { |
@@ -200,11 +208,13 @@ void button_gpioa_isr(void) | |||
200 | { | 208 | { |
201 | #if defined(HAVE_SCROLLWHEEL) | 209 | #if defined(HAVE_SCROLLWHEEL) |
202 | /* scroll wheel handling */ | 210 | /* scroll wheel handling */ |
203 | if (GPIOA_MIS & SCROLLWHEEL_BITS) | 211 | unsigned long bits = GPIOA_MIS & SCROLLWHEEL_BITS; |
204 | scrollwheel(GPIOA_PIN_MASK(0xc0) >> 6); | ||
205 | 212 | ||
206 | /* ack interrupt */ | 213 | if (bits) |
207 | GPIOA_IC = SCROLLWHEEL_BITS; | 214 | { |
215 | scrollwheel(GPIOA_PIN_MASK(SCROLLWHEEL_BITS) >> SCROLLWHEEL_BITS_POS); | ||
216 | GPIOA_IC = bits; /* ack interrupt */ | ||
217 | } | ||
208 | #endif | 218 | #endif |
209 | } | 219 | } |
210 | 220 | ||
@@ -225,8 +235,10 @@ int button_read_device(void) | |||
225 | int delay = 30; | 235 | int delay = 30; |
226 | while(delay--) nop; | 236 | while(delay--) nop; |
227 | 237 | ||
238 | disable_irq(); | ||
239 | |||
228 | bool ccu_io_bit12 = CCU_IO & (1<<12); | 240 | bool ccu_io_bit12 = CCU_IO & (1<<12); |
229 | bitclr32(&CCU_IO, 1<<12); | 241 | CCU_IO &= ~(1<<12); |
230 | 242 | ||
231 | /* B1 is shared with FM i2c */ | 243 | /* B1 is shared with FM i2c */ |
232 | bool gpiob_pin0_dir = GPIOB_DIR & (1<<1); | 244 | bool gpiob_pin0_dir = GPIOB_DIR & (1<<1); |
@@ -256,7 +268,9 @@ int button_read_device(void) | |||
256 | GPIOB_DIR |= 1<<1; | 268 | GPIOB_DIR |= 1<<1; |
257 | 269 | ||
258 | if(ccu_io_bit12) | 270 | if(ccu_io_bit12) |
259 | bitset32(&CCU_IO, 1<<12); | 271 | CCU_IO |= (1<<12); |
272 | |||
273 | enable_irq(); | ||
260 | 274 | ||
261 | #ifdef HAS_BUTTON_HOLD | 275 | #ifdef HAS_BUTTON_HOLD |
262 | #ifndef BOOTLOADER | 276 | #ifndef BOOTLOADER |
@@ -265,12 +279,6 @@ int button_read_device(void) | |||
265 | { | 279 | { |
266 | hold_button = hold; | 280 | hold_button = hold; |
267 | backlight_hold_changed(hold); | 281 | backlight_hold_changed(hold); |
268 | /* mask scrollwheel irq so we don't need to check for | ||
269 | * the hold button in the isr */ | ||
270 | if (hold) | ||
271 | GPIOA_IE &= ~SCROLLWHEEL_BITS; | ||
272 | else | ||
273 | GPIOA_IE |= SCROLLWHEEL_BITS; | ||
274 | } | 282 | } |
275 | #else | 283 | #else |
276 | hold_button = hold; | 284 | hold_button = hold; |
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 17f1bfa11d..5bed36e51e 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c | |||
@@ -178,10 +178,12 @@ static int sd1_oneshot_callback(struct timeout *tmo) | |||
178 | void sd_gpioa_isr(void) | 178 | void sd_gpioa_isr(void) |
179 | { | 179 | { |
180 | static struct timeout sd1_oneshot; | 180 | static struct timeout sd1_oneshot; |
181 | |||
181 | if (GPIOA_MIS & EXT_SD_BITS) | 182 | if (GPIOA_MIS & EXT_SD_BITS) |
183 | { | ||
182 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); | 184 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); |
183 | /* acknowledge interrupt */ | 185 | GPIOA_IC = EXT_SD_BITS; /* acknowledge interrupt */ |
184 | GPIOA_IC = EXT_SD_BITS; | 186 | } |
185 | } | 187 | } |
186 | #endif /* HAVE_HOTSWAP */ | 188 | #endif /* HAVE_HOTSWAP */ |
187 | 189 | ||
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 717d5dd744..9edc598edf 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c | |||
@@ -1041,10 +1041,12 @@ static int sd1_oneshot_callback(struct timeout *tmo) | |||
1041 | void sd_gpioa_isr(void) | 1041 | void sd_gpioa_isr(void) |
1042 | { | 1042 | { |
1043 | static struct timeout sd1_oneshot; | 1043 | static struct timeout sd1_oneshot; |
1044 | |||
1044 | if (GPIOA_MIS & EXT_SD_BITS) | 1045 | if (GPIOA_MIS & EXT_SD_BITS) |
1046 | { | ||
1045 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); | 1047 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); |
1046 | /* acknowledge interrupt */ | 1048 | GPIOA_IC = EXT_SD_BITS; /* acknowledge interrupt */ |
1047 | GPIOA_IC = EXT_SD_BITS; | 1049 | } |
1048 | } | 1050 | } |
1049 | #endif /* HAVE_HOTSWAP */ | 1051 | #endif /* HAVE_HOTSWAP */ |
1050 | 1052 | ||
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 01aaeaccbe..f0ed75d2bd 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c | |||
@@ -51,7 +51,7 @@ | |||
51 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | 51 | extern __attribute__((weak,alias("UIRQ"))) void name (void) |
52 | 52 | ||
53 | static void UIRQ (void) __attribute__((interrupt ("IRQ"))); | 53 | static void UIRQ (void) __attribute__((interrupt ("IRQ"))); |
54 | void irq_handler(void) __attribute__((interrupt ("IRQ"))); | 54 | void irq_handler(void) __attribute__((naked, interrupt ("IRQ"))); |
55 | void fiq_handler(void) __attribute__((interrupt ("FIQ"))); | 55 | void fiq_handler(void) __attribute__((interrupt ("FIQ"))); |
56 | 56 | ||
57 | default_interrupt(INT_WATCHDOG); | 57 | default_interrupt(INT_WATCHDOG); |
@@ -121,6 +121,11 @@ static void UIRQ(void) | |||
121 | static const struct { int source; void (*isr) (void); } vec_int_srcs[] = | 121 | static const struct { int source; void (*isr) (void); } vec_int_srcs[] = |
122 | { | 122 | { |
123 | /* Highest priority at the top of the list */ | 123 | /* Highest priority at the top of the list */ |
124 | #if defined(HAVE_HOTSWAP) || defined(HAVE_RDS_CAP) || \ | ||
125 | (defined(SANSA_FUZEV2) && !INCREASED_SCROLLWHEEL_POLLING) | ||
126 | /* If GPIOA ISR is interrupted, things seem to go wonky ?? */ | ||
127 | { INT_SRC_GPIOA, INT_GPIOA }, | ||
128 | #endif | ||
124 | #ifdef HAVE_RECORDING | 129 | #ifdef HAVE_RECORDING |
125 | { INT_SRC_I2SIN, INT_I2SIN }, /* For recording */ | 130 | { INT_SRC_I2SIN, INT_I2SIN }, /* For recording */ |
126 | #endif | 131 | #endif |
@@ -134,29 +139,26 @@ static const struct { int source; void (*isr) (void); } vec_int_srcs[] = | |||
134 | { INT_SRC_TIMER2, INT_TIMER2 }, | 139 | { INT_SRC_TIMER2, INT_TIMER2 }, |
135 | { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, | 140 | { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, |
136 | { INT_SRC_AUDIO, INT_AUDIO }, | 141 | { INT_SRC_AUDIO, INT_AUDIO }, |
137 | #if defined(HAVE_HOTSWAP) || \ | ||
138 | (defined(SANSA_FUZEV2) && !INCREASED_SCROLLWHEEL_POLLING) | ||
139 | { INT_SRC_GPIOA, INT_GPIOA, }, | ||
140 | #endif | ||
141 | /* Lowest priority at the end of the list */ | 142 | /* Lowest priority at the end of the list */ |
142 | }; | 143 | }; |
143 | 144 | ||
144 | static void setup_vic(void) | 145 | static void setup_vic(void) |
145 | { | 146 | { |
146 | const unsigned int n = sizeof(vec_int_srcs)/sizeof(vec_int_srcs[0]); | ||
147 | unsigned int i; | ||
148 | |||
149 | CGU_PERI |= CGU_VIC_CLOCK_ENABLE; /* enable VIC */ | 147 | CGU_PERI |= CGU_VIC_CLOCK_ENABLE; /* enable VIC */ |
150 | VIC_INT_EN_CLEAR = 0xffffffff; /* disable all interrupt lines */ | 148 | VIC_INT_EN_CLEAR = 0xffffffff; /* disable all interrupt lines */ |
151 | VIC_INT_SELECT = 0; /* only IRQ, no FIQ */ | 149 | VIC_INT_SELECT = 0; /* only IRQ, no FIQ */ |
152 | 150 | ||
153 | *VIC_DEF_VECT_ADDR = UIRQ; | 151 | *VIC_DEF_VECT_ADDR = UIRQ; |
154 | 152 | ||
155 | for(i = 0; i < n; i++) | 153 | for(unsigned int i = 0; i < ARRAYLEN(vec_int_srcs); i++) |
156 | { | 154 | { |
157 | VIC_VECT_ADDRS[i] = vec_int_srcs[i].isr; | 155 | VIC_VECT_ADDRS[i] = vec_int_srcs[i].isr; |
158 | VIC_VECT_CNTLS[i] = (1<<5) | vec_int_srcs[i].source; | 156 | VIC_VECT_CNTLS[i] = (1<<5) | vec_int_srcs[i].source; |
159 | } | 157 | } |
158 | |||
159 | /* Reset priority hardware */ | ||
160 | for(unsigned int i = 0; i < 32; i++) | ||
161 | *VIC_VECT_ADDR = 0; | ||
160 | } | 162 | } |
161 | 163 | ||
162 | void INT_GPIOA(void) | 164 | void INT_GPIOA(void) |
@@ -177,8 +179,36 @@ void INT_GPIOA(void) | |||
177 | 179 | ||
178 | void irq_handler(void) | 180 | void irq_handler(void) |
179 | { | 181 | { |
180 | (*VIC_VECT_ADDR)(); /* call the isr */ | 182 | /* Worst-case IRQ stack usage with 10 vectors: |
181 | *VIC_VECT_ADDR = (void*)VIC_VECT_ADDR; /* any write will ack the irq */ | 183 | * 10*4*10 = 400 bytes (100 words) |
184 | * | ||
185 | * No SVC stack is used by pro/epi-logue code | ||
186 | */ | ||
187 | asm volatile ( | ||
188 | "sub lr, lr, #4 \n" /* Create return address */ | ||
189 | "stmfd sp!, { r0-r5, r12, lr } \n" /* Save what gets clobbered */ | ||
190 | "ldr r0, =0xc6010030 \n" /* Obtain VIC address (before SPSR read!) */ | ||
191 | "ldr r12, [r0] \n" /* Load Vector */ | ||
192 | "mrs r1, spsr \n" /* Save SPSR_irq */ | ||
193 | "stmfd sp!, { r0-r1 } \n" /* Must have something bet. mrs and msr */ | ||
194 | "msr cpsr_c, #0x13 \n" /* Switch to SVC mode, enable IRQ */ | ||
195 | "and r4, sp, #4 \n" /* Align SVC stack to 8 bytes, save */ | ||
196 | "sub sp, sp, r4 \n" | ||
197 | "mov r5, lr \n" /* Save lr_SVC */ | ||
198 | #if ARM_ARCH >= 5 | ||
199 | "blx r12 \n" /* Call handler */ | ||
200 | #else | ||
201 | "mov lr, pc \n" | ||
202 | "bx r12 \n" | ||
203 | #endif | ||
204 | "add sp, sp, r4 \n" /* Undo alignment fudge */ | ||
205 | "mov lr, r5 \n" /* Restore lr_SVC */ | ||
206 | "msr cpsr_c, #0x92 \n" /* Mask IRQ, return to IRQ mode */ | ||
207 | "ldmfd sp!, { r0-r1 } \n" /* Pop VIC address, SPSR_irq */ | ||
208 | "str r0, [r0] \n" /* Ack end of ISR to VIC */ | ||
209 | "msr spsr_cxsf, r1 \n" /* Restore SPSR_irq */ | ||
210 | "ldmfd sp!, { r0-r5, r12, pc }^ \n" /* Restore regs, and RFE */ | ||
211 | ); | ||
182 | } | 212 | } |
183 | 213 | ||
184 | void fiq_handler(void) | 214 | void fiq_handler(void) |
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index f75f37006d..7befecb593 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S | |||
@@ -100,17 +100,23 @@ newstart: | |||
100 | strhi r4, [r2], #4 | 100 | strhi r4, [r2], #4 |
101 | bhi 1b | 101 | bhi 1b |
102 | 102 | ||
103 | /* Set up stack for IRQ mode */ | 103 | /* Set up stack for IRQ mode */ |
104 | msr cpsr_c, #0xd2 | 104 | msr cpsr_c, #0xd2 |
105 | ldr sp, =irq_stack | 105 | ldr sp, =irq_stack |
106 | 106 | ||
107 | /* Set up stack for FIQ mode */ | ||
108 | msr cpsr_c, #0xd1 | ||
109 | ldr sp, =fiq_stack | ||
110 | |||
111 | /* Let svc, abort and undefined modes use irq stack */ | ||
112 | msr cpsr_c, #0xd3 | 107 | msr cpsr_c, #0xd3 |
108 | #if CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2 | ||
109 | /* Let abort and undefined modes use irq stack */ | ||
110 | /* svc stack is for interrupt processing */ | ||
111 | ldr sp, =svc_stack | ||
112 | #else | ||
113 | /* Let svc, abort and undefined modes use irq stack */ | ||
113 | ldr sp, =irq_stack | 114 | ldr sp, =irq_stack |
115 | |||
116 | /* Set up stack for FIQ mode */ | ||
117 | msr cpsr_c, #0xd1 | ||
118 | ldr sp, =fiq_stack | ||
119 | #endif | ||
114 | msr cpsr_c, #0xd7 | 120 | msr cpsr_c, #0xd7 |
115 | ldr sp, =irq_stack | 121 | ldr sp, =irq_stack |
116 | msr cpsr_c, #0xdb | 122 | msr cpsr_c, #0xdb |
@@ -159,15 +165,20 @@ prefetch_abort_handler: | |||
159 | b UIE | 165 | b UIE |
160 | 166 | ||
161 | data_abort_handler: | 167 | data_abort_handler: |
162 | sub r0, lr, #8 | 168 | sub r0, lr, #8 |
163 | mov r1, #2 | 169 | mov r1, #2 |
164 | b UIE | 170 | b UIE |
165 | 171 | ||
172 | /* Cache-align interrupt stacks */ | ||
173 | .balign 32 | ||
174 | |||
166 | /* 256 words of IRQ stack */ | 175 | /* 256 words of IRQ stack */ |
167 | .space 256*4 | 176 | .space 256*4 |
168 | irq_stack: | 177 | irq_stack: |
169 | 178 | ||
170 | /* 256 words of FIQ stack */ | 179 | /* 256 words of FIQ/SVC stack */ |
171 | .space 256*4 | 180 | .space 256*4 |
172 | fiq_stack: | 181 | fiq_stack: |
173 | end: | 182 | svc_stack: |
183 | |||
184 | end: \ No newline at end of file | ||
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h index b3630a8473..ffce77a176 100644 --- a/firmware/target/arm/system-arm.h +++ b/firmware/target/arm/system-arm.h | |||
@@ -76,6 +76,9 @@ void __div0(void); | |||
76 | #define ints_enabled_checkval(val) \ | 76 | #define ints_enabled_checkval(val) \ |
77 | (((val) & IRQ_FIQ_STATUS) == 0) | 77 | (((val) & IRQ_FIQ_STATUS) == 0) |
78 | 78 | ||
79 | /* We run in SYS mode */ | ||
80 | #define is_thread_context() \ | ||
81 | (get_processor_mode() == 0x1f) | ||
79 | 82 | ||
80 | /* Core-level interrupt masking */ | 83 | /* Core-level interrupt masking */ |
81 | 84 | ||
@@ -109,6 +112,13 @@ static inline bool interrupt_enabled(int status) | |||
109 | return (cpsr & status) == 0; | 112 | return (cpsr & status) == 0; |
110 | } | 113 | } |
111 | 114 | ||
115 | static inline unsigned long get_processor_mode(void) | ||
116 | { | ||
117 | unsigned long cpsr; | ||
118 | asm ("mrs %0, cpsr" : "=r"(cpsr)); | ||
119 | return cpsr & 0x1f; | ||
120 | } | ||
121 | |||
112 | /* ARM_ARCH version section for architecture*/ | 122 | /* ARM_ARCH version section for architecture*/ |
113 | 123 | ||
114 | #if ARM_ARCH >= 6 | 124 | #if ARM_ARCH >= 6 |