summaryrefslogtreecommitdiffstats
path: root/firmware
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 /firmware
parent34455abfe6c93adbdc835be15cd01af8277229aa (diff)
downloadrockbox-f9c780ccc146fd883374f8f89c14c9ce5968ee51.tar.gz
rockbox-f9c780ccc146fd883374f8f89c14c9ce5968ee51.tar.bz2
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
Diffstat (limited to 'firmware')
-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)
{
if (flip != flipped) /* not the curent setting */
{
- cli(); /* avoid race condition with the button_tick() */
+ /* avoid race condition with the button_tick() */
+ int oldlevel = set_irq_level(15);
lastbtn = button_flip(lastbtn);
flipped = flip;
- sti();
+ set_irq_level(oldlevel);
}
}
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)
{
do
{
- unsigned byte;
- unsigned sda1; /* precalculated SC=low,SD=1 */
- unsigned clk0sda0; /* precalculated SC and SD low */
+ unsigned int byte;
+ unsigned int sda1; /* precalculated SC=low,SD=1 */
+ unsigned int clk0sda0; /* precalculated SC and SD low */
+ unsigned int oldlevel;
byte = *p_bytes++ << 24; /* fetch to MSB position */
- cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */
- /* (currently not the case, so this could be optimized away) */
+ /* make port modifications atomic, in case an IRQ uses PBDRL */
+ /* (currently not the case, so this could be optimized away) */
+ oldlevel = set_irq_level(15);
/* precalculate the values for later bit toggling, init data write */
asm (
@@ -285,7 +287,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
: "r0"
);
- sti();
+ set_irq_level(oldlevel);
} while (--count); /* tail loop is faster */
}
@@ -298,13 +300,15 @@ void lcd_write_data(unsigned char* p_bytes, int count)
{
unsigned byte;
unsigned sda1; /* precalculated SC=low,SD=1 */
+ unsigned int oldlevel;
/* take inverse data, so I can use the NEGC instruction below, it is
the only carry add/sub which does not destroy a source register */
byte = ~(*p_bytes++ << 24); /* fetch to MSB position */
- cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */
- /* (currently not the case, so this could be optimized away) */
+ /* make port modifications atomic, in case an IRQ uses PBDRL */
+ /* (currently not the case, so this could be optimized away) */
+ oldlevel = set_irq_level(15);
/* precalculate the values for later bit toggling, init data write */
asm (
@@ -386,7 +390,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
"r0"
);
- sti(); /* end of atomic port modifications */
+ set_irq_level(oldlevel);
} while (--count); /* tail loop is faster */
}
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;
extern void kernel_init(void);
extern void yield(void);
extern void sleep(int ticks);
-int set_irq_level(int level);
int tick_add_task(void (*f)(void));
int tick_remove_task(void (*f)(void));
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 @@
#include "sh7034.h"
#include "config.h"
+extern void system_reboot (void);
+extern void system_init(void);
+extern int set_irq_level(int level);
+
#define FREQ CPU_FREQ
#define BAUDRATE 9600
@@ -113,47 +117,34 @@ static inline int tas (volatile int *pointer)
return result;
}
-static inline void sti (void)
- {
- asm volatile ("ldc\t%0,sr" : : "r"(0<<4));
- }
-
-static inline void cli (void)
- {
- asm volatile ("ldc\t%0,sr" : : "r"(15<<4));
- }
-
/* Compare And Swap */
static inline int cas (volatile int *pointer,int requested_value,int new_value)
{
- cli();
+ unsigned int oldlevel = set_irq_level(15);
if (*pointer == requested_value)
{
*pointer = new_value;
- sti ();
+ set_irq_level(oldlevel);
return 1;
}
- sti ();
+ set_irq_level(oldlevel);
return 0;
}
static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2)
{
- cli();
+ unsigned int oldlevel = set_irq_level(15);
if (*pointer1 == requested_value1 && *pointer2 == requested_value2)
{
*pointer1 = new_value1;
*pointer2 = new_value2;
- sti ();
+ set_irq_level(oldlevel);
return 1;
}
- sti ();
+ set_irq_level(oldlevel);
return 0;
}
#endif
-extern void system_reboot (void);
-extern void system_init(void);
-
#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)
}
/****************************************************************************
- * Interrupt level setting
- ****************************************************************************/
-int set_irq_level(int level)
-{
- int i;
- /* Read the old level and set the new one */
- asm volatile ("stc sr, %0" : "=r" (i));
- asm volatile ("ldc %0, sr" : : "r" (level << 4));
- return (i >> 4) & 0x0f;
-}
-
-/****************************************************************************
* Queue handling stuff
****************************************************************************/
void 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"))) =
void system_reboot (void)
{
- cli ();
+ set_irq_level(15);
asm volatile ("ldc\t%0,vbr" : : "r"(0));
@@ -318,6 +318,18 @@ void system_reboot (void)
"r"(*(int*)0),"r"(4));
}
+/****************************************************************************
+ * Interrupt level setting
+ ****************************************************************************/
+int set_irq_level(int level)
+{
+ int i;
+ /* Read the old level and set the new one */
+ asm volatile ("stc sr, %0" : "=r" (i));
+ asm volatile ("ldc %0, sr" : : "r" (level << 4));
+ return (i >> 4) & 0x0f;
+}
+
void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
{
bool state = true;