diff options
Diffstat (limited to 'arch/mips/kernel/smp-mt.c')
-rw-r--r-- | arch/mips/kernel/smp-mt.c | 143 |
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 | 39 | static void __init smvp_copy_vpe_config(void) |
40 | #define MIPS_CPU_IPI_CALL_IRQ 1 | ||
41 | |||
42 | static int cpu_ipi_resched_irq, cpu_ipi_call_irq; | ||
43 | |||
44 | #if 0 | ||
45 | static 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 | |||
61 | void __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 | |||
108 | static void ipi_resched_dispatch(void) | ||
109 | { | ||
110 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); | ||
111 | } | ||
112 | |||
113 | static void ipi_call_dispatch(void) | ||
114 | { | ||
115 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | ||
116 | } | ||
117 | |||
118 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
119 | { | ||
120 | return IRQ_HANDLED; | ||
121 | } | ||
122 | |||
123 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
124 | { | ||
125 | smp_call_function_interrupt(); | ||
126 | |||
127 | return IRQ_HANDLED; | ||
128 | } | ||
129 | |||
130 | static struct irqaction irq_resched = { | ||
131 | .handler = ipi_resched_interrupt, | ||
132 | .flags = IRQF_DISABLED|IRQF_PERCPU, | ||
133 | .name = "IPI_resched" | ||
134 | }; | ||
135 | |||
136 | static struct irqaction irq_call = { | ||
137 | .handler = ipi_call_interrupt, | ||
138 | .flags = IRQF_DISABLED|IRQF_PERCPU, | ||
139 | .name = "IPI_call" | ||
140 | }; | ||
141 | |||
142 | static 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 | ||
159 | static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, | 56 | static 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 | ||
190 | static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) | 87 | static 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 | ||
255 | static void __cpuinit vsmp_init_secondary(void) | 152 | static 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 | ||
264 | static void __cpuinit vsmp_smp_finish(void) | 165 | static 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 | */ |
328 | static void __init vsmp_smp_setup(void) | 230 | static 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) | |||
371 | static void __init vsmp_prepare_cpus(unsigned int max_cpus) | 273 | static 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 | ||
391 | struct plat_smp_ops vsmp_smp_ops = { | 278 | struct plat_smp_ops vsmp_smp_ops = { |