aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/smtc.c')
-rw-r--r--arch/mips/kernel/smtc.c65
1 files changed, 42 insertions, 23 deletions
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 802febed7df5..6a857bf030b0 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/cpumask.h> 5#include <linux/cpumask.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/module.h>
7 8
8#include <asm/cpu.h> 9#include <asm/cpu.h>
9#include <asm/processor.h> 10#include <asm/processor.h>
@@ -261,6 +262,7 @@ void smtc_configure_tlb(void)
261 } 262 }
262 } 263 }
263 write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); 264 write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB);
265 ehb();
264 266
265 /* 267 /*
266 * Setup kernel data structures to use software total, 268 * Setup kernel data structures to use software total,
@@ -269,9 +271,12 @@ void smtc_configure_tlb(void)
269 * of their initialization in smtc_cpu_setup(). 271 * of their initialization in smtc_cpu_setup().
270 */ 272 */
271 273
272 tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */ 274 /* MIPS32 limits TLB indices to 64 */
273 cpu_data[0].tlbsize = tlbsiz; 275 if (tlbsiz > 64)
276 tlbsiz = 64;
277 cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz;
274 smtc_status |= SMTC_TLB_SHARED; 278 smtc_status |= SMTC_TLB_SHARED;
279 local_flush_tlb_all();
275 280
276 printk("TLB of %d entry pairs shared by %d VPEs\n", 281 printk("TLB of %d entry pairs shared by %d VPEs\n",
277 tlbsiz, vpes); 282 tlbsiz, vpes);
@@ -1016,6 +1021,35 @@ void setup_cross_vpe_interrupts(void)
1016 * SMTC-specific hacks invoked from elsewhere in the kernel. 1021 * SMTC-specific hacks invoked from elsewhere in the kernel.
1017 */ 1022 */
1018 1023
1024void smtc_ipi_replay(void)
1025{
1026 /*
1027 * To the extent that we've ever turned interrupts off,
1028 * we may have accumulated deferred IPIs. This is subtle.
1029 * If we use the smtc_ipi_qdepth() macro, we'll get an
1030 * exact number - but we'll also disable interrupts
1031 * and create a window of failure where a new IPI gets
1032 * queued after we test the depth but before we re-enable
1033 * interrupts. So long as IXMT never gets set, however,
1034 * we should be OK: If we pick up something and dispatch
1035 * it here, that's great. If we see nothing, but concurrent
1036 * with this operation, another TC sends us an IPI, IXMT
1037 * is clear, and we'll handle it as a real pseudo-interrupt
1038 * and not a pseudo-pseudo interrupt.
1039 */
1040 if (IPIQ[smp_processor_id()].depth > 0) {
1041 struct smtc_ipi *pipi;
1042 extern void self_ipi(struct smtc_ipi *);
1043
1044 while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
1045 self_ipi(pipi);
1046 smtc_cpu_stats[smp_processor_id()].selfipis++;
1047 }
1048 }
1049}
1050
1051EXPORT_SYMBOL(smtc_ipi_replay);
1052
1019void smtc_idle_loop_hook(void) 1053void smtc_idle_loop_hook(void)
1020{ 1054{
1021#ifdef SMTC_IDLE_HOOK_DEBUG 1055#ifdef SMTC_IDLE_HOOK_DEBUG
@@ -1112,29 +1146,14 @@ void smtc_idle_loop_hook(void)
1112 if (pdb_msg != &id_ho_db_msg[0]) 1146 if (pdb_msg != &id_ho_db_msg[0])
1113 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); 1147 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1114#endif /* SMTC_IDLE_HOOK_DEBUG */ 1148#endif /* SMTC_IDLE_HOOK_DEBUG */
1149
1115 /* 1150 /*
1116 * To the extent that we've ever turned interrupts off, 1151 * Replay any accumulated deferred IPIs. If "Instant Replay"
1117 * we may have accumulated deferred IPIs. This is subtle. 1152 * is in use, there should never be any.
1118 * If we use the smtc_ipi_qdepth() macro, we'll get an
1119 * exact number - but we'll also disable interrupts
1120 * and create a window of failure where a new IPI gets
1121 * queued after we test the depth but before we re-enable
1122 * interrupts. So long as IXMT never gets set, however,
1123 * we should be OK: If we pick up something and dispatch
1124 * it here, that's great. If we see nothing, but concurrent
1125 * with this operation, another TC sends us an IPI, IXMT
1126 * is clear, and we'll handle it as a real pseudo-interrupt
1127 * and not a pseudo-pseudo interrupt.
1128 */ 1153 */
1129 if (IPIQ[smp_processor_id()].depth > 0) { 1154#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
1130 struct smtc_ipi *pipi; 1155 smtc_ipi_replay();
1131 extern void self_ipi(struct smtc_ipi *); 1156#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
1132
1133 if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) {
1134 self_ipi(pipi);
1135 smtc_cpu_stats[smp_processor_id()].selfipis++;
1136 }
1137 }
1138} 1157}
1139 1158
1140void smtc_soft_dump(void) 1159void smtc_soft_dump(void)