21 #include <linux/kernel.h>
22 #include <linux/sched.h>
27 #include <linux/module.h>
29 #include <linux/slab.h>
32 #include <asm/processor.h>
34 #include <asm/hardirq.h>
37 #include <asm/mmu_context.h>
39 #include <asm/cacheflush.h>
41 #include <asm/addrspace.h>
52 #define LOCK_MT_PRA() \
53 local_irq_save(flags); \
56 #define UNLOCK_MT_PRA() \
58 local_irq_restore(flags)
60 #define LOCK_CORE_PRA() \
61 local_irq_save(flags); \
64 #define UNLOCK_CORE_PRA() \
66 local_irq_restore(flags)
83 #define IPIBUF_PER_CPU 4
99 static void post_direct_ipi(
int cpu,
struct smtc_ipi *pipi);
100 static void setup_cross_vpe_interrupts(
unsigned int nvpe);
109 static int vpe0limit;
110 static int ipibuffers;
128 static int __init stlb_disable(
char *
s)
134 static int __init asidmask_set(
char *
str)
149 printk(
"ILLEGAL ASID mask 0x%x from command line\n", asidmask);
156 __setup(
"nostlb", stlb_disable);
157 __setup(
"asidmask=", asidmask_set);
159 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
161 static int hang_trig;
163 static int __init hangtrig_enable(
char *
s)
170 __setup(
"hangtrig", hangtrig_enable);
172 #define DEFAULT_BLOCKED_IPI_LIMIT 32
174 static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT;
176 static int __init tintq(
char *str)
187 {0, 0, 1, 0, 0, 0, 0, 1},
188 {0, 0, 0, 0, 0, 0, 0, 1}
192 static int clock_hang_reported[
NR_CPUS];
200 static void smtc_configure_tlb(
void)
203 unsigned long mvpconf0;
204 unsigned long config1val;
237 for (i=0; i < vpes; i++) {
252 tlbsiz += ((config1val >> 25) & 0x3f) + 1;
278 printk(
"TLB of %d entry pairs shared by %d VPEs\n",
281 printk(
"WARNING: TLB Not Sharable on SMTC Boot!\n");
314 for (i=start_cpu_slot; i<
NR_CPUS && i<ntcs; i++) {
319 #ifdef CONFIG_MIPS_MT_FPAFF
325 printk(
"%i available secondary CPU TC(s)\n", i - 1);
339 static void smtc_tc_setup(
int vpe,
int tc,
int cpu)
353 cp1contexts[0] = smtc_nconf1[0] - 1;
354 cp1contexts[1] = smtc_nconf1[1];
377 if (!cp1contexts[vpe])
421 IPIQ[
i].resched_flag = 0;
438 printk(
"Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n");
441 printk(
"ASID mask value override to 0x%x\n", asidmask);
444 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
446 printk(
"Logic Analyser Trigger on suspected TC hang\n");
462 for (i = 0; i < nvpe; i++) {
463 tcpervpe[
i] = ntc / nvpe;
465 if((slop - i) > 0) tcpervpe[i]++;
469 if (vpe0limit > ntc) vpe0limit = ntc;
472 if (vpe0limit < tcpervpe[0]) {
474 slop = tcpervpe[0] - vpe0limit;
475 slopslop = slop % (nvpe - 1);
476 tcpervpe[0] = vpe0limit;
477 for (i = 1; i < nvpe; i++) {
478 tcpervpe[
i] += slop / (nvpe - 1);
479 if(slopslop && ((slopslop - (i - 1) > 0)))
482 }
else if (vpe0limit > tcpervpe[0]) {
484 slop = vpe0limit - tcpervpe[0];
485 slopslop = slop % (nvpe - 1);
486 tcpervpe[0] = vpe0limit;
487 for (i = 1; i < nvpe; i++) {
488 tcpervpe[
i] -= slop / (nvpe - 1);
489 if(slopslop && ((slopslop - (i - 1) > 0)))
496 smtc_configure_tlb();
498 for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) {
517 if (tcpervpe[vpe] == 0)
521 printk(
"VPE %d: TC", vpe);
522 for (i = 0; i < tcpervpe[vpe]; i++) {
529 smtc_tc_setup(vpe, tc, cpu);
601 #ifdef CONFIG_MIPS_MT_FPAFF
602 for (tc = 0; tc < ntc; tc++) {
612 setup_cross_vpe_interrupts(nvpe);
621 panic(
"kmalloc of IPI message buffers failed");
623 printk(
"IPI buffer pool of %d buffers\n", nipi);
624 for (i = 0; i < nipi; i++) {
625 smtc_ipi_nq(&freeIPIq, pipi);
695 printk(
"TC %d going on-line as CPU %d\n",
714 unsigned long hwmask)
716 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
726 #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
740 void smtc_forward_irq(
struct irq_data *
d)
742 unsigned int irq = d->
irq;
756 target = cpumask_first(d->
affinity);
772 do_IRQ_no_affinity(irq);
802 static void smtc_ipi_qdump(
void)
807 for (i = 0; i <
NR_CPUS ;i++) {
808 pr_info(
"IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
816 #ifdef SMTC_IPI_DEBUG
817 pr_debug(
"%u %lu\n", temp->sender, temp->stamp);
834 static inline int atomic_postincrement(
atomic_t *
v)
846 :
"=&r" (result),
"=&r" (temp),
"=m" (v->
counter)
859 unsigned long tcrestart;
865 printk(
"Cannot Send IPI to self!\n");
868 if (set_resched_flag &&
IPIQ[cpu].resched_flag != 0)
872 pipi = smtc_ipi_dq(&freeIPIq);
876 panic(
"IPI Msg. Buffers Depleted");
879 pipi->
arg = (
void *)action;
883 IPIQ[
cpu].resched_flag |= set_resched_flag;
884 smtc_ipi_nq(&
IPIQ[cpu], pipi);
917 && tcrestart < (
unsigned long)__pastwait) {
919 tcstatus &= ~TCSTATUS_IXMT;
930 IPIQ[
cpu].resched_flag |= set_resched_flag;
931 smtc_ipi_nq(&
IPIQ[cpu], pipi);
934 post_direct_ipi(cpu, pipi);
944 static void post_direct_ipi(
int cpu,
struct smtc_ipi *pipi)
947 unsigned long tcstatus;
948 unsigned long tcrestart;
950 extern void __smtc_ipi_vector(
void);
957 if ((tcrestart & 0x80000000)
958 && ((*(
unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) {
971 kstack = ((
struct pt_regs *)kernelsp[cpu]) - 1;
976 kstack->cp0_tcstatus = tcstatus;
978 kstack->
pad0[4] = (
unsigned long)pipi;
990 static void ipi_resched_interrupt(
void)
995 static void ipi_call_interrupt(
void)
1003 static void __irq_entry smtc_clock_tick_interrupt(
void)
1006 struct clock_event_device *
cd;
1011 cd = &
per_cpu(mips_clockevent_device, cpu);
1012 cd->event_handler(cd);
1018 void *arg_copy = pipi->
arg;
1019 int type_copy = pipi->
type;
1021 smtc_ipi_nq(&freeIPIq, pipi);
1023 switch (type_copy) {
1025 smtc_clock_tick_interrupt();
1029 switch ((
int)arg_copy) {
1031 ipi_resched_interrupt();
1034 ipi_call_interrupt();
1037 printk(
"Impossible SMTC IPI Argument %p\n", arg_copy);
1041 #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
1047 do_IRQ_no_affinity((
int)arg_copy);
1051 printk(
"Impossible SMTC IPI Type 0x%x\n", type_copy);
1078 unsigned long flags;
1085 spin_lock(&q->
lock);
1086 pipi = __smtc_ipi_dq(q);
1087 spin_unlock(&q->
lock);
1113 static irqreturn_t ipi_interrupt(
int irq,
void *dev_idm)
1119 unsigned long tcstatus;
1121 unsigned long flags;
1122 unsigned int mtflags;
1123 unsigned int vpflags;
1133 clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ);
1134 set_c0_status(0x100 << MIPS_CPU_IPI_IRQ);
1135 irq_enable_hazard();
1150 pipi = smtc_ipi_dq(&
IPIQ[cpu]);
1152 if (
cpu_data[cpu].tc_id != my_tc) {
1160 post_direct_ipi(cpu, pipi);
1166 smtc_ipi_req(&
IPIQ[cpu], pipi);
1186 static void ipi_irq_dispatch(
void)
1192 .handler = ipi_interrupt,
1197 static void setup_cross_vpe_interrupts(
unsigned int nvpe)
1203 panic(
"SMTC Kernel requires Vectored Interrupt support");
1207 setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ));
1238 unsigned long flags;
1246 spin_lock(&q->
lock);
1247 pipi = __smtc_ipi_dq(q);
1248 spin_unlock(&q->
lock);
1265 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
1278 char id_ho_db_msg[768];
1286 if (hook_ntcs > NR_CPUS)
1288 for (tc = 0; tc < hook_ntcs; tc++) {
1290 clock_hang_reported[
tc] = 0;
1292 for (vpe = 0; vpe < 2; vpe++)
1293 for (im = 0; im < 8; im++)
1294 imstuckcount[vpe][im] = 0;
1295 printk(
"Idle loop test hook initialized for %d TCs\n", hook_ntcs);
1299 while (
atomic_read(&idle_hook_initialized) < 1000)
1308 printk(
"Dangling IXMT in cpu_idle()\n");
1312 #define IM_LIMIT 2000
1315 pdb_msg = &id_ho_db_msg[0];
1318 for (bit = 0; bit < 8; bit++) {
1323 if (vpemask[vpe][bit]) {
1324 if (!(im & (0x100 << bit)))
1325 imstuckcount[vpe][
bit]++;
1327 imstuckcount[vpe][
bit] = 0;
1328 if (imstuckcount[vpe][bit] > IM_LIMIT) {
1329 set_c0_status(0x100 << bit);
1331 imstuckcount[vpe][
bit] = 0;
1333 "Dangling IM %d fixed for VPE %d\n", bit,
1341 if (pdb_msg != &id_ho_db_msg[0])
1352 printk(
"Counter Interrupts taken per CPU (TC)\n");
1356 printk(
"Self-IPI invocations:\n");
1361 printk(
"%d Recoveries of \"stolen\" FPU\n",
1372 unsigned long flags, mtflags, tcstat, prevhalt,
asid;
1472 tlb_write_indexed();
1484 static int halt_state_save[
NR_CPUS];