summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2004-02-25 13:00:36 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2004-02-25 13:00:36 +0000
commitf9c780ccc146fd883374f8f89c14c9ce5968ee51 (patch)
tree7f09a228e34adeed9c626c9f6e91ded8003e678c
parent34455abfe6c93adbdc835be15cd01af8277229aa (diff)
downloadrockbox-f9c780ccc146fd883374f8f89c14c9ce5968ee51.tar.gz
rockbox-f9c780ccc146fd883374f8f89c14c9ce5968ee51.zip
The cli()/sti() functions are not safe. We should have removed them long ago.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4314 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/button.c5
-rw-r--r--firmware/drivers/lcd.c22
-rw-r--r--firmware/export/kernel.h1
-rw-r--r--firmware/export/system.h29
-rw-r--r--firmware/kernel.c12
-rw-r--r--firmware/system.c14
6 files changed, 39 insertions, 44 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 06c24e0e45..66c7e978fb 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -258,10 +258,11 @@ void button_set_flip(bool flip)
258{ 258{
259 if (flip != flipped) /* not the curent setting */ 259 if (flip != flipped) /* not the curent setting */
260 { 260 {
261 cli(); /* avoid race condition with the button_tick() */ 261 /* avoid race condition with the button_tick() */
262 int oldlevel = set_irq_level(15);
262 lastbtn = button_flip(lastbtn); 263 lastbtn = button_flip(lastbtn);
263 flipped = flip; 264 flipped = flip;
264 sti(); 265 set_irq_level(oldlevel);
265 } 266 }
266} 267}
267 268
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c
index 5c2c514f10..950f8b5057 100644
--- a/firmware/drivers/lcd.c
+++ b/firmware/drivers/lcd.c
@@ -188,14 +188,16 @@ void lcd_write_data(unsigned char* p_bytes, int count)
188{ 188{
189 do 189 do
190 { 190 {
191 unsigned byte; 191 unsigned int byte;
192 unsigned sda1; /* precalculated SC=low,SD=1 */ 192 unsigned int sda1; /* precalculated SC=low,SD=1 */
193 unsigned clk0sda0; /* precalculated SC and SD low */ 193 unsigned int clk0sda0; /* precalculated SC and SD low */
194 unsigned int oldlevel;
194 195
195 byte = *p_bytes++ << 24; /* fetch to MSB position */ 196 byte = *p_bytes++ << 24; /* fetch to MSB position */
196 197
197 cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ 198 /* make port modifications atomic, in case an IRQ uses PBDRL */
198 /* (currently not the case, so this could be optimized away) */ 199 /* (currently not the case, so this could be optimized away) */
200 oldlevel = set_irq_level(15);
199 201
200 /* precalculate the values for later bit toggling, init data write */ 202 /* precalculate the values for later bit toggling, init data write */
201 asm ( 203 asm (
@@ -285,7 +287,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
285 : "r0" 287 : "r0"
286 ); 288 );
287 289
288 sti(); 290 set_irq_level(oldlevel);
289 291
290 } while (--count); /* tail loop is faster */ 292 } while (--count); /* tail loop is faster */
291} 293}
@@ -298,13 +300,15 @@ void lcd_write_data(unsigned char* p_bytes, int count)
298 { 300 {
299 unsigned byte; 301 unsigned byte;
300 unsigned sda1; /* precalculated SC=low,SD=1 */ 302 unsigned sda1; /* precalculated SC=low,SD=1 */
303 unsigned int oldlevel;
301 304
302 /* take inverse data, so I can use the NEGC instruction below, it is 305 /* take inverse data, so I can use the NEGC instruction below, it is
303 the only carry add/sub which does not destroy a source register */ 306 the only carry add/sub which does not destroy a source register */
304 byte = ~(*p_bytes++ << 24); /* fetch to MSB position */ 307 byte = ~(*p_bytes++ << 24); /* fetch to MSB position */
305 308
306 cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ 309 /* make port modifications atomic, in case an IRQ uses PBDRL */
307 /* (currently not the case, so this could be optimized away) */ 310 /* (currently not the case, so this could be optimized away) */
311 oldlevel = set_irq_level(15);
308 312
309 /* precalculate the values for later bit toggling, init data write */ 313 /* precalculate the values for later bit toggling, init data write */
310 asm ( 314 asm (
@@ -386,7 +390,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
386 "r0" 390 "r0"
387 ); 391 );
388 392
389 sti(); /* end of atomic port modifications */ 393 set_irq_level(oldlevel);
390 394
391 } while (--count); /* tail loop is faster */ 395 } while (--count); /* tail loop is faster */
392} 396}
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 0f69f43ec0..6e11baedf6 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -64,7 +64,6 @@ extern long current_tick;
64extern void kernel_init(void); 64extern void kernel_init(void);
65extern void yield(void); 65extern void yield(void);
66extern void sleep(int ticks); 66extern void sleep(int ticks);
67int set_irq_level(int level);
68int tick_add_task(void (*f)(void)); 67int tick_add_task(void (*f)(void));
69int tick_remove_task(void (*f)(void)); 68int tick_remove_task(void (*f)(void));
70 69
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 01d2f130d3..5886145d7b 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -23,6 +23,10 @@
23#include "sh7034.h" 23#include "sh7034.h"
24#include "config.h" 24#include "config.h"
25 25
26extern void system_reboot (void);
27extern void system_init(void);
28extern int set_irq_level(int level);
29
26#define FREQ CPU_FREQ 30#define FREQ CPU_FREQ
27#define BAUDRATE 9600 31#define BAUDRATE 9600
28 32
@@ -113,47 +117,34 @@ static inline int tas (volatile int *pointer)
113 return result; 117 return result;
114 } 118 }
115 119
116static inline void sti (void)
117 {
118 asm volatile ("ldc\t%0,sr" : : "r"(0<<4));
119 }
120
121static inline void cli (void)
122 {
123 asm volatile ("ldc\t%0,sr" : : "r"(15<<4));
124 }
125
126/* Compare And Swap */ 120/* Compare And Swap */
127static inline int cas (volatile int *pointer,int requested_value,int new_value) 121static inline int cas (volatile int *pointer,int requested_value,int new_value)
128 { 122 {
129 cli(); 123 unsigned int oldlevel = set_irq_level(15);
130 if (*pointer == requested_value) 124 if (*pointer == requested_value)
131 { 125 {
132 *pointer = new_value; 126 *pointer = new_value;
133 sti (); 127 set_irq_level(oldlevel);
134 return 1; 128 return 1;
135 } 129 }
136 sti (); 130 set_irq_level(oldlevel);
137 return 0; 131 return 0;
138 } 132 }
139 133
140static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2) 134static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2)
141 { 135 {
142 cli(); 136 unsigned int oldlevel = set_irq_level(15);
143 if (*pointer1 == requested_value1 && *pointer2 == requested_value2) 137 if (*pointer1 == requested_value1 && *pointer2 == requested_value2)
144 { 138 {
145 *pointer1 = new_value1; 139 *pointer1 = new_value1;
146 *pointer2 = new_value2; 140 *pointer2 = new_value2;
147 sti (); 141 set_irq_level(oldlevel);
148 return 1; 142 return 1;
149 } 143 }
150 sti (); 144 set_irq_level(oldlevel);
151 return 0; 145 return 0;
152 } 146 }
153 147
154#endif 148#endif
155 149
156extern void system_reboot (void);
157extern void system_init(void);
158
159#endif 150#endif
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 3255ba0b20..1c37f004a4 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -71,18 +71,6 @@ void yield(void)
71} 71}
72 72
73/**************************************************************************** 73/****************************************************************************
74 * Interrupt level setting
75 ****************************************************************************/
76int set_irq_level(int level)
77{
78 int i;
79 /* Read the old level and set the new one */
80 asm volatile ("stc sr, %0" : "=r" (i));
81 asm volatile ("ldc %0, sr" : : "r" (level << 4));
82 return (i >> 4) & 0x0f;
83}
84
85/****************************************************************************
86 * Queue handling stuff 74 * Queue handling stuff
87 ****************************************************************************/ 75 ****************************************************************************/
88void queue_init(struct event_queue *q) 76void queue_init(struct event_queue *q)
diff --git a/firmware/system.c b/firmware/system.c
index 87d3b9dc7d..3ec56f7c15 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -302,7 +302,7 @@ void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
302 302
303void system_reboot (void) 303void system_reboot (void)
304{ 304{
305 cli (); 305 set_irq_level(15);
306 306
307 asm volatile ("ldc\t%0,vbr" : : "r"(0)); 307 asm volatile ("ldc\t%0,vbr" : : "r"(0));
308 308
@@ -318,6 +318,18 @@ void system_reboot (void)
318 "r"(*(int*)0),"r"(4)); 318 "r"(*(int*)0),"r"(4));
319} 319}
320 320
321/****************************************************************************
322 * Interrupt level setting
323 ****************************************************************************/
324int set_irq_level(int level)
325{
326 int i;
327 /* Read the old level and set the new one */
328 asm volatile ("stc sr, %0" : "=r" (i));
329 asm volatile ("ldc %0, sr" : : "r" (level << 4));
330 return (i >> 4) & 0x0f;
331}
332
321void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ 333void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
322{ 334{
323 bool state = true; 335 bool state = true;