diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-11-08 13:02:29 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-11-15 18:21:49 -0500 |
commit | f6771dbb27c704ce837ba3bb1dcaa53f48f76ea8 (patch) | |
tree | efec5eacc34a9e412a193a79d575cbf3b90acf23 | |
parent | efb9ca08b5a2374b29938cdcab417ce4feb14b54 (diff) |
[MIPS] Fix shadow register support.
Shadow register support would not possibly have worked on multicore
systems. The support code for it was also depending not on MIPS R2 but
VSMP or SMTC kernels even though it makes perfect sense with UP kernels.
SR sets are a scarce resource and the expected usage pattern is that
users actually hardcode the register set numbers in their code. So fix
the allocator by ditching it. Move the remaining CPU probe bits into
the generic CPU probe.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/Kconfig | 9 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/proc.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 68 | ||||
-rw-r--r-- | include/asm-mips/cpu-info.h | 1 |
5 files changed, 11 insertions, 74 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4b07b18e5196..2f2ce0c28bc0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1409,7 +1409,6 @@ config MIPS_MT_SMP | |||
1409 | depends on SYS_SUPPORTS_MULTITHREADING | 1409 | depends on SYS_SUPPORTS_MULTITHREADING |
1410 | select CPU_MIPSR2_IRQ_VI | 1410 | select CPU_MIPSR2_IRQ_VI |
1411 | select CPU_MIPSR2_IRQ_EI | 1411 | select CPU_MIPSR2_IRQ_EI |
1412 | select CPU_MIPSR2_SRS | ||
1413 | select MIPS_MT | 1412 | select MIPS_MT |
1414 | select NR_CPUS_DEFAULT_2 | 1413 | select NR_CPUS_DEFAULT_2 |
1415 | select SMP | 1414 | select SMP |
@@ -1426,7 +1425,6 @@ config MIPS_MT_SMTC | |||
1426 | select GENERIC_CLOCKEVENTS_BROADCAST | 1425 | select GENERIC_CLOCKEVENTS_BROADCAST |
1427 | select CPU_MIPSR2_IRQ_VI | 1426 | select CPU_MIPSR2_IRQ_VI |
1428 | select CPU_MIPSR2_IRQ_EI | 1427 | select CPU_MIPSR2_IRQ_EI |
1429 | select CPU_MIPSR2_SRS | ||
1430 | select MIPS_MT | 1428 | select MIPS_MT |
1431 | select NR_CPUS_DEFAULT_8 | 1429 | select NR_CPUS_DEFAULT_8 |
1432 | select SMP | 1430 | select SMP |
@@ -1453,7 +1451,6 @@ config MIPS_VPE_LOADER | |||
1453 | depends on SYS_SUPPORTS_MULTITHREADING | 1451 | depends on SYS_SUPPORTS_MULTITHREADING |
1454 | select CPU_MIPSR2_IRQ_VI | 1452 | select CPU_MIPSR2_IRQ_VI |
1455 | select CPU_MIPSR2_IRQ_EI | 1453 | select CPU_MIPSR2_IRQ_EI |
1456 | select CPU_MIPSR2_SRS | ||
1457 | select MIPS_MT | 1454 | select MIPS_MT |
1458 | help | 1455 | help |
1459 | Includes a loader for loading an elf relocatable object | 1456 | Includes a loader for loading an elf relocatable object |
@@ -1582,12 +1579,6 @@ config CPU_MIPSR2_IRQ_VI | |||
1582 | config CPU_MIPSR2_IRQ_EI | 1579 | config CPU_MIPSR2_IRQ_EI |
1583 | bool | 1580 | bool |
1584 | 1581 | ||
1585 | # | ||
1586 | # Shadow registers are an R2 feature | ||
1587 | # | ||
1588 | config CPU_MIPSR2_SRS | ||
1589 | bool | ||
1590 | |||
1591 | config CPU_HAS_SYNC | 1582 | config CPU_HAS_SYNC |
1592 | bool | 1583 | bool |
1593 | depends on !CPU_R3000 | 1584 | depends on !CPU_R3000 |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index c8c47a2d1972..5c2794391bf5 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -943,6 +943,11 @@ __init void cpu_probe(void) | |||
943 | } | 943 | } |
944 | 944 | ||
945 | __cpu_name[cpu] = cpu_to_name(c); | 945 | __cpu_name[cpu] = cpu_to_name(c); |
946 | |||
947 | if (cpu_has_mips_r2) | ||
948 | c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | ||
949 | else | ||
950 | c->srsets = 1; | ||
946 | } | 951 | } |
947 | 952 | ||
948 | __init void cpu_report(void) | 953 | __init void cpu_report(void) |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index efd2d1314123..6e6e947cce1e 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -60,6 +60,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
60 | cpu_has_dsp ? " dsp" : "", | 60 | cpu_has_dsp ? " dsp" : "", |
61 | cpu_has_mipsmt ? " mt" : "" | 61 | cpu_has_mipsmt ? " mt" : "" |
62 | ); | 62 | ); |
63 | seq_printf(m, "shadow register sets\t: %d\n", | ||
64 | cpu_data[n].srsets); | ||
63 | 65 | ||
64 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", | 66 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
65 | cpu_has_vce ? "%u" : "not available"); | 67 | cpu_has_vce ? "%u" : "not available"); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index fa500787152d..23e73d0650a3 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1100,59 +1100,6 @@ void *set_except_vector(int n, void *addr) | |||
1100 | return (void *)old_handler; | 1100 | return (void *)old_handler; |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | #ifdef CONFIG_CPU_MIPSR2_SRS | ||
1104 | /* | ||
1105 | * MIPSR2 shadow register set allocation | ||
1106 | * FIXME: SMP... | ||
1107 | */ | ||
1108 | |||
1109 | static struct shadow_registers { | ||
1110 | /* | ||
1111 | * Number of shadow register sets supported | ||
1112 | */ | ||
1113 | unsigned long sr_supported; | ||
1114 | /* | ||
1115 | * Bitmap of allocated shadow registers | ||
1116 | */ | ||
1117 | unsigned long sr_allocated; | ||
1118 | } shadow_registers; | ||
1119 | |||
1120 | static void mips_srs_init(void) | ||
1121 | { | ||
1122 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | ||
1123 | printk(KERN_INFO "%ld MIPSR2 register sets available\n", | ||
1124 | shadow_registers.sr_supported); | ||
1125 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ | ||
1126 | } | ||
1127 | |||
1128 | int mips_srs_max(void) | ||
1129 | { | ||
1130 | return shadow_registers.sr_supported; | ||
1131 | } | ||
1132 | |||
1133 | int mips_srs_alloc(void) | ||
1134 | { | ||
1135 | struct shadow_registers *sr = &shadow_registers; | ||
1136 | int set; | ||
1137 | |||
1138 | again: | ||
1139 | set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported); | ||
1140 | if (set >= sr->sr_supported) | ||
1141 | return -1; | ||
1142 | |||
1143 | if (test_and_set_bit(set, &sr->sr_allocated)) | ||
1144 | goto again; | ||
1145 | |||
1146 | return set; | ||
1147 | } | ||
1148 | |||
1149 | void mips_srs_free(int set) | ||
1150 | { | ||
1151 | struct shadow_registers *sr = &shadow_registers; | ||
1152 | |||
1153 | clear_bit(set, &sr->sr_allocated); | ||
1154 | } | ||
1155 | |||
1156 | static asmlinkage void do_default_vi(void) | 1103 | static asmlinkage void do_default_vi(void) |
1157 | { | 1104 | { |
1158 | show_regs(get_irq_regs()); | 1105 | show_regs(get_irq_regs()); |
@@ -1163,6 +1110,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1163 | { | 1110 | { |
1164 | unsigned long handler; | 1111 | unsigned long handler; |
1165 | unsigned long old_handler = vi_handlers[n]; | 1112 | unsigned long old_handler = vi_handlers[n]; |
1113 | int srssets = current_cpu_data.srsets; | ||
1166 | u32 *w; | 1114 | u32 *w; |
1167 | unsigned char *b; | 1115 | unsigned char *b; |
1168 | 1116 | ||
@@ -1178,7 +1126,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1178 | 1126 | ||
1179 | b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); | 1127 | b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); |
1180 | 1128 | ||
1181 | if (srs >= mips_srs_max()) | 1129 | if (srs >= srssets) |
1182 | panic("Shadow register set %d not supported", srs); | 1130 | panic("Shadow register set %d not supported", srs); |
1183 | 1131 | ||
1184 | if (cpu_has_veic) { | 1132 | if (cpu_has_veic) { |
@@ -1186,7 +1134,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1186 | board_bind_eic_interrupt(n, srs); | 1134 | board_bind_eic_interrupt(n, srs); |
1187 | } else if (cpu_has_vint) { | 1135 | } else if (cpu_has_vint) { |
1188 | /* SRSMap is only defined if shadow sets are implemented */ | 1136 | /* SRSMap is only defined if shadow sets are implemented */ |
1189 | if (mips_srs_max() > 1) | 1137 | if (srssets > 1) |
1190 | change_c0_srsmap(0xf << n*4, srs << n*4); | 1138 | change_c0_srsmap(0xf << n*4, srs << n*4); |
1191 | } | 1139 | } |
1192 | 1140 | ||
@@ -1253,14 +1201,6 @@ void *set_vi_handler(int n, vi_handler_t addr) | |||
1253 | return set_vi_srs_handler(n, addr, 0); | 1201 | return set_vi_srs_handler(n, addr, 0); |
1254 | } | 1202 | } |
1255 | 1203 | ||
1256 | #else | ||
1257 | |||
1258 | static inline void mips_srs_init(void) | ||
1259 | { | ||
1260 | } | ||
1261 | |||
1262 | #endif /* CONFIG_CPU_MIPSR2_SRS */ | ||
1263 | |||
1264 | /* | 1204 | /* |
1265 | * This is used by native signal handling | 1205 | * This is used by native signal handling |
1266 | */ | 1206 | */ |
@@ -1503,8 +1443,6 @@ void __init trap_init(void) | |||
1503 | else | 1443 | else |
1504 | ebase = CAC_BASE; | 1444 | ebase = CAC_BASE; |
1505 | 1445 | ||
1506 | mips_srs_init(); | ||
1507 | |||
1508 | per_cpu_trap_init(); | 1446 | per_cpu_trap_init(); |
1509 | 1447 | ||
1510 | /* | 1448 | /* |
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h index 94f1c8172360..ed5c02c6afbb 100644 --- a/include/asm-mips/cpu-info.h +++ b/include/asm-mips/cpu-info.h | |||
@@ -54,6 +54,7 @@ struct cpuinfo_mips { | |||
54 | struct cache_desc dcache; /* Primary D or combined I/D cache */ | 54 | struct cache_desc dcache; /* Primary D or combined I/D cache */ |
55 | struct cache_desc scache; /* Secondary cache */ | 55 | struct cache_desc scache; /* Secondary cache */ |
56 | struct cache_desc tcache; /* Tertiary/split secondary cache */ | 56 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
57 | int srsets; /* Shadow register sets */ | ||
57 | #if defined(CONFIG_MIPS_MT_SMTC) | 58 | #if defined(CONFIG_MIPS_MT_SMTC) |
58 | /* | 59 | /* |
59 | * In the MIPS MT "SMTC" model, each TC is considered | 60 | * In the MIPS MT "SMTC" model, each TC is considered |