aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-04-04 10:09:06 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-04-18 22:14:22 -0400
commit193dd2ce2a4a1c5b2e7814544572424d497069db (patch)
treecca42417c505a8f68e2d2accc83d392fb7221432 /arch/mips/kernel/traps.c
parent62a442155ea58a17497b487324b27ec2f2dc5c5c (diff)
[MIPS] R2: Implement shadow register allocation without spinlock.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 61efc61c45e2..081e6ed5bb62 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -961,15 +961,19 @@ void *set_except_vector(int n, void *addr)
961 961
962#ifdef CONFIG_CPU_MIPSR2 962#ifdef CONFIG_CPU_MIPSR2
963/* 963/*
964 * Shadow register allocation 964 * MIPSR2 shadow register set allocation
965 * FIXME: SMP... 965 * FIXME: SMP...
966 */ 966 */
967 967
968/* MIPSR2 shadow register sets */ 968static struct shadow_registers {
969struct shadow_registers { 969 /*
970 spinlock_t sr_lock; /* */ 970 * Number of shadow register sets supported
971 int sr_supported; /* Number of shadow register sets supported */ 971 */
972 int sr_allocated; /* Bitmap of allocated shadow registers */ 972 unsigned long sr_supported;
973 /*
974 * Bitmap of allocated shadow registers
975 */
976 unsigned long sr_allocated;
973} shadow_registers; 977} shadow_registers;
974 978
975void mips_srs_init(void) 979void mips_srs_init(void)
@@ -980,7 +984,6 @@ void mips_srs_init(void)
980 shadow_registers.sr_supported); 984 shadow_registers.sr_supported);
981#endif 985#endif
982 shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ 986 shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
983 spin_lock_init(&shadow_registers.sr_lock);
984} 987}
985 988
986int mips_srs_max(void) 989int mips_srs_max(void)
@@ -991,32 +994,24 @@ int mips_srs_max(void)
991int mips_srs_alloc(void) 994int mips_srs_alloc(void)
992{ 995{
993 struct shadow_registers *sr = &shadow_registers; 996 struct shadow_registers *sr = &shadow_registers;
994 unsigned long flags;
995 int set; 997 int set;
996 998
997 spin_lock_irqsave(&sr->sr_lock, flags); 999again:
1000 set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
1001 if (set >= sr->sr_supported)
1002 return -1;
998 1003
999 for (set = 0; set < sr->sr_supported; set++) { 1004 if (test_and_set_bit(set, &sr->sr_allocated))
1000 if ((sr->sr_allocated & (1 << set)) == 0) { 1005 goto again;
1001 sr->sr_allocated |= 1 << set;
1002 spin_unlock_irqrestore(&sr->sr_lock, flags);
1003 return set;
1004 }
1005 }
1006 1006
1007 /* None available */ 1007 return set;
1008 spin_unlock_irqrestore(&sr->sr_lock, flags);
1009 return -1;
1010} 1008}
1011 1009
1012void mips_srs_free (int set) 1010void mips_srs_free (int set)
1013{ 1011{
1014 struct shadow_registers *sr = &shadow_registers; 1012 struct shadow_registers *sr = &shadow_registers;
1015 unsigned long flags;
1016 1013
1017 spin_lock_irqsave(&sr->sr_lock, flags); 1014 clear_bit(set, &sr->sr_allocated);
1018 sr->sr_allocated &= ~(1 << set);
1019 spin_unlock_irqrestore(&sr->sr_lock, flags);
1020} 1015}
1021 1016
1022static void *set_vi_srs_handler(int n, void *addr, int srs) 1017static void *set_vi_srs_handler(int n, void *addr, int srs)