[MIPS] R2: Implement shadow register allocation without spinlock.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
@@ -961,15 +961,19 @@ void *set_except_vector(int n, void *addr)
|
|||||||
|
|
||||||
#ifdef CONFIG_CPU_MIPSR2
|
#ifdef CONFIG_CPU_MIPSR2
|
||||||
/*
|
/*
|
||||||
* Shadow register allocation
|
* MIPSR2 shadow register set allocation
|
||||||
* FIXME: SMP...
|
* FIXME: SMP...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* MIPSR2 shadow register sets */
|
static struct shadow_registers {
|
||||||
struct shadow_registers {
|
/*
|
||||||
spinlock_t sr_lock; /* */
|
* Number of shadow register sets supported
|
||||||
int sr_supported; /* Number of shadow register sets supported */
|
*/
|
||||||
int sr_allocated; /* Bitmap of allocated shadow registers */
|
unsigned long sr_supported;
|
||||||
|
/*
|
||||||
|
* Bitmap of allocated shadow registers
|
||||||
|
*/
|
||||||
|
unsigned long sr_allocated;
|
||||||
} shadow_registers;
|
} shadow_registers;
|
||||||
|
|
||||||
void mips_srs_init(void)
|
void mips_srs_init(void)
|
||||||
@@ -980,7 +984,6 @@ void mips_srs_init(void)
|
|||||||
shadow_registers.sr_supported);
|
shadow_registers.sr_supported);
|
||||||
#endif
|
#endif
|
||||||
shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
|
shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
|
||||||
spin_lock_init(&shadow_registers.sr_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mips_srs_max(void)
|
int mips_srs_max(void)
|
||||||
@@ -991,32 +994,24 @@ int mips_srs_max(void)
|
|||||||
int mips_srs_alloc(void)
|
int mips_srs_alloc(void)
|
||||||
{
|
{
|
||||||
struct shadow_registers *sr = &shadow_registers;
|
struct shadow_registers *sr = &shadow_registers;
|
||||||
unsigned long flags;
|
|
||||||
int set;
|
int set;
|
||||||
|
|
||||||
spin_lock_irqsave(&sr->sr_lock, flags);
|
again:
|
||||||
|
set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
|
||||||
|
if (set >= sr->sr_supported)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (set = 0; set < sr->sr_supported; set++) {
|
if (test_and_set_bit(set, &sr->sr_allocated))
|
||||||
if ((sr->sr_allocated & (1 << set)) == 0) {
|
goto again;
|
||||||
sr->sr_allocated |= 1 << set;
|
|
||||||
spin_unlock_irqrestore(&sr->sr_lock, flags);
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* None available */
|
return set;
|
||||||
spin_unlock_irqrestore(&sr->sr_lock, flags);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mips_srs_free (int set)
|
void mips_srs_free (int set)
|
||||||
{
|
{
|
||||||
struct shadow_registers *sr = &shadow_registers;
|
struct shadow_registers *sr = &shadow_registers;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&sr->sr_lock, flags);
|
clear_bit(set, &sr->sr_allocated);
|
||||||
sr->sr_allocated &= ~(1 << set);
|
|
||||||
spin_unlock_irqrestore(&sr->sr_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *set_vi_srs_handler(int n, void *addr, int srs)
|
static void *set_vi_srs_handler(int n, void *addr, int srs)
|
||||||
|
Reference in New Issue
Block a user