diff options
-rw-r--r-- | arch/mips/include/asm/mipsmtregs.h | 13 | ||||
-rw-r--r-- | arch/mips/include/asm/smtc.h | 6 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 76 |
4 files changed, 90 insertions, 9 deletions
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h index e71ff4c317f2..5b3cb8553e9a 100644 --- a/arch/mips/include/asm/mipsmtregs.h +++ b/arch/mips/include/asm/mipsmtregs.h | |||
@@ -28,6 +28,9 @@ | |||
28 | #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) | 28 | #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) |
29 | #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) | 29 | #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) |
30 | 30 | ||
31 | #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3) | ||
32 | #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val) | ||
33 | |||
31 | #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) | 34 | #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) |
32 | #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) | 35 | #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) |
33 | 36 | ||
@@ -124,6 +127,14 @@ | |||
124 | #define VPECONF0_XTC_SHIFT 21 | 127 | #define VPECONF0_XTC_SHIFT 21 |
125 | #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) | 128 | #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) |
126 | 129 | ||
130 | /* VPEConf1 fields (per VPE) */ | ||
131 | #define VPECONF1_NCP1_SHIFT 0 | ||
132 | #define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT) | ||
133 | #define VPECONF1_NCP2_SHIFT 10 | ||
134 | #define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT) | ||
135 | #define VPECONF1_NCX_SHIFT 20 | ||
136 | #define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT) | ||
137 | |||
127 | /* TCStatus fields (per TC) */ | 138 | /* TCStatus fields (per TC) */ |
128 | #define TCSTATUS_TASID (_ULCAST_(0xff)) | 139 | #define TCSTATUS_TASID (_ULCAST_(0xff)) |
129 | #define TCSTATUS_IXMT_SHIFT 10 | 140 | #define TCSTATUS_IXMT_SHIFT 10 |
@@ -350,6 +361,8 @@ do { \ | |||
350 | #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) | 361 | #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) |
351 | #define read_vpe_c0_vpeconf0() mftc0(1, 2) | 362 | #define read_vpe_c0_vpeconf0() mftc0(1, 2) |
352 | #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) | 363 | #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) |
364 | #define read_vpe_c0_vpeconf1() mftc0(1, 3) | ||
365 | #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) | ||
353 | #define read_vpe_c0_count() mftc0(9, 0) | 366 | #define read_vpe_c0_count() mftc0(9, 0) |
354 | #define write_vpe_c0_count(val) mttc0(9, 0, val) | 367 | #define write_vpe_c0_count(val) mttc0(9, 0, val) |
355 | #define read_vpe_c0_status() mftc0(12, 0) | 368 | #define read_vpe_c0_status() mftc0(12, 0) |
diff --git a/arch/mips/include/asm/smtc.h b/arch/mips/include/asm/smtc.h index c9736fc06325..8935426a56ab 100644 --- a/arch/mips/include/asm/smtc.h +++ b/arch/mips/include/asm/smtc.h | |||
@@ -33,6 +33,12 @@ typedef long asiduse; | |||
33 | #endif | 33 | #endif |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* | ||
37 | * VPE Management information | ||
38 | */ | ||
39 | |||
40 | #define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */ | ||
41 | |||
36 | extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | 42 | extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; |
37 | 43 | ||
38 | struct mm_struct; | 44 | struct mm_struct; |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1268392f1d27..31637d8c8738 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void) | |||
102 | 102 | ||
103 | #ifdef CONFIG_MIPS_MT_SMTC | 103 | #ifdef CONFIG_MIPS_MT_SMTC |
104 | /* Only do cpu_probe for first TC of CPU */ | 104 | /* Only do cpu_probe for first TC of CPU */ |
105 | if ((read_c0_tcbind() & TCBIND_CURTC) == 0) | 105 | if ((read_c0_tcbind() & TCBIND_CURTC) != 0) |
106 | __cpu_name[smp_processor_id()] = __cpu_name[0]; | ||
107 | else | ||
106 | #endif /* CONFIG_MIPS_MT_SMTC */ | 108 | #endif /* CONFIG_MIPS_MT_SMTC */ |
107 | cpu_probe(); | 109 | cpu_probe(); |
108 | cpu_report(); | 110 | cpu_report(); |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 15b5f3cfd20c..1d47843d3cc0 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS]; | |||
86 | static struct smtc_ipi_q freeIPIq; | 86 | static struct smtc_ipi_q freeIPIq; |
87 | 87 | ||
88 | 88 | ||
89 | /* | ||
90 | * Number of FPU contexts for each VPE | ||
91 | */ | ||
92 | |||
93 | static int smtc_nconf1[MAX_SMTC_VPES]; | ||
94 | |||
95 | |||
89 | /* Forward declarations */ | 96 | /* Forward declarations */ |
90 | 97 | ||
91 | void ipi_decode(struct smtc_ipi *); | 98 | void ipi_decode(struct smtc_ipi *); |
@@ -174,9 +181,9 @@ static int __init tintq(char *str) | |||
174 | 181 | ||
175 | __setup("tintq=", tintq); | 182 | __setup("tintq=", tintq); |
176 | 183 | ||
177 | static int imstuckcount[2][8]; | 184 | static int imstuckcount[MAX_SMTC_VPES][8]; |
178 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ | 185 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ |
179 | static int vpemask[2][8] = { | 186 | static int vpemask[MAX_SMTC_VPES][8] = { |
180 | {0, 0, 1, 0, 0, 0, 0, 1}, | 187 | {0, 0, 1, 0, 0, 0, 0, 1}, |
181 | {0, 0, 0, 0, 0, 0, 0, 1} | 188 | {0, 0, 0, 0, 0, 0, 0, 1} |
182 | }; | 189 | }; |
@@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot) | |||
331 | 338 | ||
332 | static void smtc_tc_setup(int vpe, int tc, int cpu) | 339 | static void smtc_tc_setup(int vpe, int tc, int cpu) |
333 | { | 340 | { |
341 | static int cp1contexts[MAX_SMTC_VPES]; | ||
342 | |||
343 | /* | ||
344 | * Make a local copy of the available FPU contexts in order | ||
345 | * to keep track of TCs that can have one. | ||
346 | */ | ||
347 | if (tc == 1) | ||
348 | { | ||
349 | /* | ||
350 | * FIXME: Multi-core SMTC hasn't been tested and the | ||
351 | * maximum number of VPEs may change. | ||
352 | */ | ||
353 | cp1contexts[0] = smtc_nconf1[0] - 1; | ||
354 | cp1contexts[1] = smtc_nconf1[1]; | ||
355 | } | ||
356 | |||
334 | settc(tc); | 357 | settc(tc); |
335 | write_tc_c0_tchalt(TCHALT_H); | 358 | write_tc_c0_tchalt(TCHALT_H); |
336 | mips_ihb(); | 359 | mips_ihb(); |
@@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
343 | * an active IPI queue. | 366 | * an active IPI queue. |
344 | */ | 367 | */ |
345 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); | 368 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); |
346 | /* Bind tc to vpe */ | 369 | |
370 | /* Bind TC to VPE. */ | ||
347 | write_tc_c0_tcbind(vpe); | 371 | write_tc_c0_tcbind(vpe); |
372 | |||
348 | /* In general, all TCs should have the same cpu_data indications. */ | 373 | /* In general, all TCs should have the same cpu_data indications. */ |
349 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | 374 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); |
350 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | 375 | |
351 | if (cpu_data[0].cputype == CPU_34K || | 376 | /* Check to see if there is a FPU context available for this TC. */ |
352 | cpu_data[0].cputype == CPU_1004K) | 377 | if (!cp1contexts[vpe]) |
353 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; | 378 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; |
379 | else | ||
380 | cp1contexts[vpe]--; | ||
381 | |||
382 | /* Store the TC and VPE into the cpu_data structure. */ | ||
354 | cpu_data[cpu].vpe_id = vpe; | 383 | cpu_data[cpu].vpe_id = vpe; |
355 | cpu_data[cpu].tc_id = tc; | 384 | cpu_data[cpu].tc_id = tc; |
356 | /* Multi-core SMTC hasn't been tested, but be prepared */ | 385 | |
386 | /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */ | ||
357 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; | 387 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; |
358 | } | 388 | } |
359 | 389 | ||
360 | /* | 390 | /* |
361 | * Tweak to get Count registes in as close a sync as possible. The | 391 | * Tweak to get Count registers synced as closely as possible. The |
362 | * value seems good for 34K-class cores. | 392 | * value seems good for 34K-class cores. |
363 | */ | 393 | */ |
364 | 394 | ||
@@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus) | |||
466 | smtc_configure_tlb(); | 496 | smtc_configure_tlb(); |
467 | 497 | ||
468 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | 498 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { |
499 | /* Get number of CP1 contexts for each VPE. */ | ||
500 | if (tc == 0) | ||
501 | { | ||
502 | /* | ||
503 | * Do not call settc() for TC0 or the FPU context | ||
504 | * value will be incorrect. Besides, we know that | ||
505 | * we are TC0 anyway. | ||
506 | */ | ||
507 | smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() & | ||
508 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
509 | if (nvpe == 2) | ||
510 | { | ||
511 | settc(1); | ||
512 | smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() & | ||
513 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
514 | settc(0); | ||
515 | } | ||
516 | } | ||
469 | if (tcpervpe[vpe] == 0) | 517 | if (tcpervpe[vpe] == 0) |
470 | continue; | 518 | continue; |
471 | if (vpe != 0) | 519 | if (vpe != 0) |
@@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus) | |||
479 | */ | 527 | */ |
480 | if (tc != 0) { | 528 | if (tc != 0) { |
481 | smtc_tc_setup(vpe, tc, cpu); | 529 | smtc_tc_setup(vpe, tc, cpu); |
530 | if (vpe != 0) { | ||
531 | /* | ||
532 | * Set MVP bit (possibly again). Do it | ||
533 | * here to catch CPUs that have no TCs | ||
534 | * bound to the VPE at reset. In that | ||
535 | * case, a TC must be bound to the VPE | ||
536 | * before we can set VPEControl[MVP] | ||
537 | */ | ||
538 | write_vpe_c0_vpeconf0( | ||
539 | read_vpe_c0_vpeconf0() | | ||
540 | VPECONF0_MVP); | ||
541 | } | ||
482 | cpu++; | 542 | cpu++; |
483 | } | 543 | } |
484 | printk(" %d", tc); | 544 | printk(" %d", tc); |