smp-mt.c (0bfa130e741f8f73a7bbf6a89aad4816e9094a71) | smp-mt.c (39b8d5254246ac56342b72f812255c8f7a74dca9) |
---|---|
1/* 2 * This program is free software; you can distribute it and/or modify it 3 * under the terms of the GNU General Public License (Version 2) as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope it will be useful, but WITHOUT 7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --- 22 unchanged lines hidden (view full) --- 31#include <asm/system.h> 32#include <asm/hardirq.h> 33#include <asm/mmu_context.h> 34#include <asm/time.h> 35#include <asm/mipsregs.h> 36#include <asm/mipsmtregs.h> 37#include <asm/mips_mt.h> 38 | 1/* 2 * This program is free software; you can distribute it and/or modify it 3 * under the terms of the GNU General Public License (Version 2) as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope it will be useful, but WITHOUT 7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --- 22 unchanged lines hidden (view full) --- 31#include <asm/system.h> 32#include <asm/hardirq.h> 33#include <asm/mmu_context.h> 34#include <asm/time.h> 35#include <asm/mipsregs.h> 36#include <asm/mipsmtregs.h> 37#include <asm/mips_mt.h> 38 |
39#define MIPS_CPU_IPI_RESCHED_IRQ 0 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) | 39static void __init smvp_copy_vpe_config(void) |
46{ | 40{ |
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 61static void ipi_resched_dispatch(void) 62{ 63 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); 64} 65 66static void ipi_call_dispatch(void) 67{ 68 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 69} 70 71static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 72{ 73 return IRQ_HANDLED; 74} 75 76static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) 77{ 78 smp_call_function_interrupt(); 79 80 return IRQ_HANDLED; 81} 82 83static struct irqaction irq_resched = { 84 .handler = ipi_resched_interrupt, 85 .flags = IRQF_DISABLED|IRQF_PERCPU, 86 .name = "IPI_resched" 87}; 88 89static struct irqaction irq_call = { 90 .handler = ipi_call_interrupt, 91 .flags = IRQF_DISABLED|IRQF_PERCPU, 92 .name = "IPI_call" 93}; 94 95static void __init smp_copy_vpe_config(void) 96{ | |
97 write_vpe_c0_status( 98 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 99 100 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 101 write_vpe_c0_config( read_c0_config()); 102 103 /* make sure there are no software interrupts pending */ 104 write_vpe_c0_cause(0); 105 106 /* Propagate Config7 */ 107 write_vpe_c0_config7(read_c0_config7()); 108 109 write_vpe_c0_count(read_c0_count()); 110} 111 | 41 write_vpe_c0_status( 42 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 43 44 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 45 write_vpe_c0_config( read_c0_config()); 46 47 /* make sure there are no software interrupts pending */ 48 write_vpe_c0_cause(0); 49 50 /* Propagate Config7 */ 51 write_vpe_c0_config7(read_c0_config7()); 52 53 write_vpe_c0_count(read_c0_count()); 54} 55 |
112static 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, |
113 unsigned int ncpu) 114{ 115 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) 116 return ncpu; 117 118 /* Deactivate all but VPE 0 */ 119 if (tc != 0) { 120 unsigned long tmp = read_vpe_c0_vpeconf0(); --- 9 unchanged lines hidden (view full) --- 130 __cpu_number_map[tc] = ++ncpu; 131 __cpu_logical_map[ncpu] = tc; 132 } 133 134 /* Disable multi-threading with TC's */ 135 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); 136 137 if (tc != 0) | 57 unsigned int ncpu) 58{ 59 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) 60 return ncpu; 61 62 /* Deactivate all but VPE 0 */ 63 if (tc != 0) { 64 unsigned long tmp = read_vpe_c0_vpeconf0(); --- 9 unchanged lines hidden (view full) --- 74 __cpu_number_map[tc] = ++ncpu; 75 __cpu_logical_map[ncpu] = tc; 76 } 77 78 /* Disable multi-threading with TC's */ 79 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); 80 81 if (tc != 0) |
138 smp_copy_vpe_config(); | 82 smvp_copy_vpe_config(); |
139 140 return ncpu; 141} 142 | 83 84 return ncpu; 85} 86 |
143static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) | 87static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0) |
144{ 145 unsigned long tmp; 146 147 if (!tc) 148 return; 149 150 /* bind a TC to each VPE, May as well put all excess TC's 151 on the last VPE */ --- 50 unchanged lines hidden (view full) --- 202 unsigned int i; 203 204 for_each_cpu_mask(i, mask) 205 vsmp_send_ipi_single(i, action); 206} 207 208static void __cpuinit vsmp_init_secondary(void) 209{ | 88{ 89 unsigned long tmp; 90 91 if (!tc) 92 return; 93 94 /* bind a TC to each VPE, May as well put all excess TC's 95 on the last VPE */ --- 50 unchanged lines hidden (view full) --- 146 unsigned int i; 147 148 for_each_cpu_mask(i, mask) 149 vsmp_send_ipi_single(i, action); 150} 151 152static void __cpuinit vsmp_init_secondary(void) 153{ |
210 /* Enable per-cpu interrupts */ | 154 extern int gic_present; |
211 212 /* This is Malta specific: IPI,performance and timer inetrrupts */ | 155 156 /* This is Malta specific: IPI,performance and timer inetrrupts */ |
213 write_c0_status((read_c0_status() & ~ST0_IM ) | 214 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); | 157 if (gic_present) 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); |
215} 216 217static void __cpuinit vsmp_smp_finish(void) 218{ | 163} 164 165static void __cpuinit vsmp_smp_finish(void) 166{ |
167 /* CDFIXME: remove this? */ |
|
219 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 220 221#ifdef CONFIG_MIPS_MT_FPAFF 222 /* If we have an FPU, enroll ourselves in the FPU-full mask */ 223 if (cpu_has_fpu) 224 cpu_set(smp_processor_id(), mt_fpu_cpumask); 225#endif /* CONFIG_MIPS_MT_FPAFF */ 226 --- 44 unchanged lines hidden (view full) --- 271 clear_c0_mvpcontrol(MVPCONTROL_VPC); 272 273 evpe(EVPE_ENABLE); 274} 275 276/* 277 * Common setup before any secondaries are started 278 * Make sure all CPU's are in a sensible state before we boot any of the | 168 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 169 170#ifdef CONFIG_MIPS_MT_FPAFF 171 /* If we have an FPU, enroll ourselves in the FPU-full mask */ 172 if (cpu_has_fpu) 173 cpu_set(smp_processor_id(), mt_fpu_cpumask); 174#endif /* CONFIG_MIPS_MT_FPAFF */ 175 --- 44 unchanged lines hidden (view full) --- 220 clear_c0_mvpcontrol(MVPCONTROL_VPC); 221 222 evpe(EVPE_ENABLE); 223} 224 225/* 226 * Common setup before any secondaries are started 227 * Make sure all CPU's are in a sensible state before we boot any of the |
279 * secondarys | 228 * secondaries |
280 */ 281static void __init vsmp_smp_setup(void) 282{ 283 unsigned int mvpconf0, ntc, tc, ncpu = 0; 284 unsigned int nvpe; 285 286#ifdef CONFIG_MIPS_MT_FPAFF 287 /* If we have an FPU, enroll ourselves in the FPU-full mask */ --- 16 unchanged lines hidden (view full) --- 304 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; 305 smp_num_siblings = nvpe; 306 307 /* we'll always have more TC's than VPE's, so loop setting everything 308 to a sensible state */ 309 for (tc = 0; tc <= ntc; tc++) { 310 settc(tc); 311 | 229 */ 230static void __init vsmp_smp_setup(void) 231{ 232 unsigned int mvpconf0, ntc, tc, ncpu = 0; 233 unsigned int nvpe; 234 235#ifdef CONFIG_MIPS_MT_FPAFF 236 /* If we have an FPU, enroll ourselves in the FPU-full mask */ --- 16 unchanged lines hidden (view full) --- 253 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; 254 smp_num_siblings = nvpe; 255 256 /* we'll always have more TC's than VPE's, so loop setting everything 257 to a sensible state */ 258 for (tc = 0; tc <= ntc; tc++) { 259 settc(tc); 260 |
312 smp_tc_init(tc, mvpconf0); 313 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); | 261 smvp_tc_init(tc, mvpconf0); 262 ncpu = smvp_vpe_init(tc, mvpconf0, ncpu); |
314 } 315 316 /* Release config state */ 317 clear_c0_mvpcontrol(MVPCONTROL_VPC); 318 319 /* We'll wait until starting the secondaries before starting MVPE */ 320 321 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); 322} 323 324static void __init vsmp_prepare_cpus(unsigned int max_cpus) 325{ 326 mips_mt_set_cpuoptions(); | 263 } 264 265 /* Release config state */ 266 clear_c0_mvpcontrol(MVPCONTROL_VPC); 267 268 /* We'll wait until starting the secondaries before starting MVPE */ 269 270 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); 271} 272 273static void __init vsmp_prepare_cpus(unsigned int max_cpus) 274{ 275 mips_mt_set_cpuoptions(); |
327 328 /* set up ipi interrupts */ 329 if (cpu_has_vint) { 330 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); 331 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); 332 } 333 334 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 335 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; 336 337 setup_irq(cpu_ipi_resched_irq, &irq_resched); 338 setup_irq(cpu_ipi_call_irq, &irq_call); 339 340 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); 341 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); | |
342} 343 344struct plat_smp_ops vsmp_smp_ops = { 345 .send_ipi_single = vsmp_send_ipi_single, 346 .send_ipi_mask = vsmp_send_ipi_mask, 347 .init_secondary = vsmp_init_secondary, 348 .smp_finish = vsmp_smp_finish, 349 .cpus_done = vsmp_cpus_done, 350 .boot_secondary = vsmp_boot_secondary, 351 .smp_setup = vsmp_smp_setup, 352 .prepare_cpus = vsmp_prepare_cpus, 353}; | 276} 277 278struct plat_smp_ops vsmp_smp_ops = { 279 .send_ipi_single = vsmp_send_ipi_single, 280 .send_ipi_mask = vsmp_send_ipi_mask, 281 .init_secondary = vsmp_init_secondary, 282 .smp_finish = vsmp_smp_finish, 283 .cpus_done = vsmp_cpus_done, 284 .boot_secondary = vsmp_boot_secondary, 285 .smp_setup = vsmp_smp_setup, 286 .prepare_cpus = vsmp_prepare_cpus, 287}; |