aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smp-mt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/smp-mt.c')
-rw-r--r--arch/mips/kernel/smp-mt.c143
1 files changed, 15 insertions, 128 deletions
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 89e6f6aa516..87a1816c1f4 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -36,110 +36,7 @@
36#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
37#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
38 38
39#define MIPS_CPU_IPI_RESCHED_IRQ 0 39static void __init smvp_copy_vpe_config(void)
40#define MIPS_CPU_IPI_CALL_IRQ 1
41
42static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
43
44#if 0
45static void dump_mtregisters(int vpe, int tc)
46{
47 printk("vpe %d tc %d\n", vpe, tc);
48
49 settc(tc);
50
51 printk(" c0 status 0x%lx\n", read_vpe_c0_status());
52 printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
53 printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
54 printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
55 printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
56 printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
57 printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
58}
59#endif
60
61void __init sanitize_tlb_entries(void)
62{
63 int i, tlbsiz;
64 unsigned long mvpconf0, ncpu;
65
66 if (!cpu_has_mipsmt)
67 return;
68
69 /* Enable VPC */
70 set_c0_mvpcontrol(MVPCONTROL_VPC);
71
72 back_to_back_c0_hazard();
73
74 /* Disable TLB sharing */
75 clear_c0_mvpcontrol(MVPCONTROL_STLB);
76
77 mvpconf0 = read_c0_mvpconf0();
78
79 printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
80 (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
81 (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
82
83 tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
84 ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
85
86 printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
87
88 if (tlbsiz > 0) {
89 /* share them out across the vpe's */
90 tlbsiz /= ncpu;
91
92 printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
93
94 for (i = 0; i < ncpu; i++) {
95 settc(i);
96
97 if (i == 0)
98 write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
99 else
100 write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
101 (tlbsiz << 25));
102 }
103 }
104
105 clear_c0_mvpcontrol(MVPCONTROL_VPC);
106}
107
108static void ipi_resched_dispatch(void)
109{
110 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
111}
112
113static void ipi_call_dispatch(void)
114{
115 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
116}
117
118static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
119{
120 return IRQ_HANDLED;
121}
122
123static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
124{
125 smp_call_function_interrupt();
126
127 return IRQ_HANDLED;
128}
129
130static struct irqaction irq_resched = {
131 .handler = ipi_resched_interrupt,
132 .flags = IRQF_DISABLED|IRQF_PERCPU,
133 .name = "IPI_resched"
134};
135
136static struct irqaction irq_call = {
137 .handler = ipi_call_interrupt,
138 .flags = IRQF_DISABLED|IRQF_PERCPU,
139 .name = "IPI_call"
140};
141
142static void __init smp_copy_vpe_config(void)
143{ 40{
144 write_vpe_c0_status( 41 write_vpe_c0_status(
145 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 42 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
@@ -156,7 +53,7 @@ static void __init smp_copy_vpe_config(void)
156 write_vpe_c0_count(read_c0_count()); 53 write_vpe_c0_count(read_c0_count());
157} 54}
158 55
159static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, 56static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
160 unsigned int ncpu) 57 unsigned int ncpu)
161{ 58{
162 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) 59 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
@@ -182,12 +79,12 @@ static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
182 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); 79 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
183 80
184 if (tc != 0) 81 if (tc != 0)
185 smp_copy_vpe_config(); 82 smvp_copy_vpe_config();
186 83
187 return ncpu; 84 return ncpu;
188} 85}
189 86
190static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) 87static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
191{ 88{
192 unsigned long tmp; 89 unsigned long tmp;
193 90
@@ -254,15 +151,20 @@ static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
254 151
255static void __cpuinit vsmp_init_secondary(void) 152static void __cpuinit vsmp_init_secondary(void)
256{ 153{
257 /* Enable per-cpu interrupts */ 154 extern int gic_present;
258 155
259 /* This is Malta specific: IPI,performance and timer inetrrupts */ 156 /* This is Malta specific: IPI,performance and timer inetrrupts */
260 write_c0_status((read_c0_status() & ~ST0_IM ) | 157 if (gic_present)
261 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); 158 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
159 STATUSF_IP6 | STATUSF_IP7);
160 else
161 change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
162 STATUSF_IP6 | STATUSF_IP7);
262} 163}
263 164
264static void __cpuinit vsmp_smp_finish(void) 165static void __cpuinit vsmp_smp_finish(void)
265{ 166{
167 /* CDFIXME: remove this? */
266 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 168 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
267 169
268#ifdef CONFIG_MIPS_MT_FPAFF 170#ifdef CONFIG_MIPS_MT_FPAFF
@@ -323,7 +225,7 @@ static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
323/* 225/*
324 * Common setup before any secondaries are started 226 * Common setup before any secondaries are started
325 * Make sure all CPU's are in a sensible state before we boot any of the 227 * Make sure all CPU's are in a sensible state before we boot any of the
326 * secondarys 228 * secondaries
327 */ 229 */
328static void __init vsmp_smp_setup(void) 230static void __init vsmp_smp_setup(void)
329{ 231{
@@ -356,8 +258,8 @@ static void __init vsmp_smp_setup(void)
356 for (tc = 0; tc <= ntc; tc++) { 258 for (tc = 0; tc <= ntc; tc++) {
357 settc(tc); 259 settc(tc);
358 260
359 smp_tc_init(tc, mvpconf0); 261 smvp_tc_init(tc, mvpconf0);
360 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); 262 ncpu = smvp_vpe_init(tc, mvpconf0, ncpu);
361 } 263 }
362 264
363 /* Release config state */ 265 /* Release config state */
@@ -371,21 +273,6 @@ static void __init vsmp_smp_setup(void)
371static void __init vsmp_prepare_cpus(unsigned int max_cpus) 273static void __init vsmp_prepare_cpus(unsigned int max_cpus)
372{ 274{
373 mips_mt_set_cpuoptions(); 275 mips_mt_set_cpuoptions();
374
375 /* set up ipi interrupts */
376 if (cpu_has_vint) {
377 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
378 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
379 }
380
381 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
382 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
383
384 setup_irq(cpu_ipi_resched_irq, &irq_resched);
385 setup_irq(cpu_ipi_call_irq, &irq_call);
386
387 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
388 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
389} 276}
390 277
391struct plat_smp_ops vsmp_smp_ops = { 278struct plat_smp_ops vsmp_smp_ops = {