1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Linus Nielsen Feltzing 2004-02-25 13:00:36 +00:00
parent 34455abfe6
commit f9c780ccc1
6 changed files with 39 additions and 44 deletions

View file

@ -258,10 +258,11 @@ void button_set_flip(bool flip)
{ {
if (flip != flipped) /* not the curent setting */ 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); lastbtn = button_flip(lastbtn);
flipped = flip; flipped = flip;
sti(); set_irq_level(oldlevel);
} }
} }

View file

@ -188,14 +188,16 @@ void lcd_write_data(unsigned char* p_bytes, int count)
{ {
do do
{ {
unsigned byte; unsigned int byte;
unsigned sda1; /* precalculated SC=low,SD=1 */ unsigned int sda1; /* precalculated SC=low,SD=1 */
unsigned clk0sda0; /* precalculated SC and SD low */ unsigned int clk0sda0; /* precalculated SC and SD low */
unsigned int oldlevel;
byte = *p_bytes++ << 24; /* fetch to MSB position */ byte = *p_bytes++ << 24; /* fetch to MSB position */
cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ /* make port modifications atomic, in case an IRQ uses PBDRL */
/* (currently not the case, so this could be optimized away) */ /* (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 */ /* precalculate the values for later bit toggling, init data write */
asm ( asm (
@ -285,7 +287,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
: "r0" : "r0"
); );
sti(); set_irq_level(oldlevel);
} while (--count); /* tail loop is faster */ } while (--count); /* tail loop is faster */
} }
@ -298,13 +300,15 @@ void lcd_write_data(unsigned char* p_bytes, int count)
{ {
unsigned byte; unsigned byte;
unsigned sda1; /* precalculated SC=low,SD=1 */ unsigned sda1; /* precalculated SC=low,SD=1 */
unsigned int oldlevel;
/* take inverse data, so I can use the NEGC instruction below, it is /* 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 */ the only carry add/sub which does not destroy a source register */
byte = ~(*p_bytes++ << 24); /* fetch to MSB position */ byte = ~(*p_bytes++ << 24); /* fetch to MSB position */
cli(); /* make port modifications atomic, in case an IRQ uses PBDRL */ /* make port modifications atomic, in case an IRQ uses PBDRL */
/* (currently not the case, so this could be optimized away) */ /* (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 */ /* precalculate the values for later bit toggling, init data write */
asm ( asm (
@ -386,7 +390,7 @@ void lcd_write_data(unsigned char* p_bytes, int count)
"r0" "r0"
); );
sti(); /* end of atomic port modifications */ set_irq_level(oldlevel);
} while (--count); /* tail loop is faster */ } while (--count); /* tail loop is faster */
} }

View file

@ -64,7 +64,6 @@ extern long current_tick;
extern void kernel_init(void); extern void kernel_init(void);
extern void yield(void); extern void yield(void);
extern void sleep(int ticks); extern void sleep(int ticks);
int set_irq_level(int level);
int tick_add_task(void (*f)(void)); int tick_add_task(void (*f)(void));
int tick_remove_task(void (*f)(void)); int tick_remove_task(void (*f)(void));

View file

@ -23,6 +23,10 @@
#include "sh7034.h" #include "sh7034.h"
#include "config.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 FREQ CPU_FREQ
#define BAUDRATE 9600 #define BAUDRATE 9600
@ -113,47 +117,34 @@ static inline int tas (volatile int *pointer)
return result; 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 */ /* Compare And Swap */
static inline int cas (volatile int *pointer,int requested_value,int new_value) 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) if (*pointer == requested_value)
{ {
*pointer = new_value; *pointer = new_value;
sti (); set_irq_level(oldlevel);
return 1; return 1;
} }
sti (); set_irq_level(oldlevel);
return 0; return 0;
} }
static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int requested_value1,int requested_value2,int new_value1,int new_value2) 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) if (*pointer1 == requested_value1 && *pointer2 == requested_value2)
{ {
*pointer1 = new_value1; *pointer1 = new_value1;
*pointer2 = new_value2; *pointer2 = new_value2;
sti (); set_irq_level(oldlevel);
return 1; return 1;
} }
sti (); set_irq_level(oldlevel);
return 0; return 0;
} }
#endif #endif
extern void system_reboot (void);
extern void system_init(void);
#endif #endif

View file

@ -70,18 +70,6 @@ void yield(void)
wake_up_thread(); wake_up_thread();
} }
/****************************************************************************
* 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 * Queue handling stuff
****************************************************************************/ ****************************************************************************/

View file

@ -302,7 +302,7 @@ void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
void system_reboot (void) void system_reboot (void)
{ {
cli (); set_irq_level(15);
asm volatile ("ldc\t%0,vbr" : : "r"(0)); asm volatile ("ldc\t%0,vbr" : : "r"(0));
@ -318,6 +318,18 @@ void system_reboot (void)
"r"(*(int*)0),"r"(4)); "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 */ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
{ {
bool state = true; bool state = true;