aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/setup.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-02-27 02:27:19 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:35 -0500
commit92704a1c63c3b481870d02636d0b5a70c7e21cd1 (patch)
tree098f96da6ab50a1d878425e2b91a9cf22f78ac80 /arch/sparc64/kernel/setup.c
parentf4e841da30b4bcbb8f1cc20a01157a788ff58b21 (diff)
[SPARC64]: Refine code sequences to get the cpu id.
On uniprocessor, it's always zero for optimize that. On SMP, the jmpl to the stub kills the return address stack in the cpu branch prediction logic, so expand the code sequence inline and use a code patching section to fix things up. This also always better and explicit register selection, which will be taken advantage of in a future changeset. The hard_smp_processor_id() function is big, so do not inline it. Fix up tests for Jalapeno to also test for Serrano chips too. These tests want "jbus Ultra-IIIi" cases to match, so that is what we should test for. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/setup.c')
-rw-r--r--arch/sparc64/kernel/setup.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 59a70301a6cf..f751d11926bc 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -490,6 +490,58 @@ void register_prom_callbacks(void)
490 "' linux-.soft2 to .soft2"); 490 "' linux-.soft2 to .soft2");
491} 491}
492 492
493static void __init per_cpu_patch(void)
494{
495#ifdef CONFIG_SMP
496 struct cpuid_patch_entry *p;
497 unsigned long ver;
498 int is_jbus;
499
500 if (tlb_type == spitfire && !this_is_starfire)
501 return;
502
503 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
504 is_jbus = ((ver >> 32) == __JALAPENO_ID ||
505 (ver >> 32) == __SERRANO_ID);
506
507 p = &__cpuid_patch;
508 while (p < &__cpuid_patch_end) {
509 unsigned long addr = p->addr;
510 unsigned int *insns;
511
512 switch (tlb_type) {
513 case spitfire:
514 insns = &p->starfire[0];
515 break;
516 case cheetah:
517 case cheetah_plus:
518 if (is_jbus)
519 insns = &p->cheetah_jbus[0];
520 else
521 insns = &p->cheetah_safari[0];
522 break;
523 default:
524 prom_printf("Unknown cpu type, halting.\n");
525 prom_halt();
526 };
527
528 *(unsigned int *) (addr + 0) = insns[0];
529 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
530
531 *(unsigned int *) (addr + 4) = insns[1];
532 __asm__ __volatile__("flush %0" : : "r" (addr + 4));
533
534 *(unsigned int *) (addr + 8) = insns[2];
535 __asm__ __volatile__("flush %0" : : "r" (addr + 8));
536
537 *(unsigned int *) (addr + 12) = insns[3];
538 __asm__ __volatile__("flush %0" : : "r" (addr + 12));
539
540 p++;
541 }
542#endif
543}
544
493void __init setup_arch(char **cmdline_p) 545void __init setup_arch(char **cmdline_p)
494{ 546{
495 /* Initialize PROM console and command line. */ 547 /* Initialize PROM console and command line. */
@@ -507,8 +559,8 @@ void __init setup_arch(char **cmdline_p)
507 /* Work out if we are starfire early on */ 559 /* Work out if we are starfire early on */
508 check_if_starfire(); 560 check_if_starfire();
509 561
510 /* Now we know enough to patch the __get_cpu_id() 562 /* Now we know enough to patch the get_cpuid sequences
511 * trampoline used by trap code. 563 * used by trap code.
512 */ 564 */
513 per_cpu_patch(); 565 per_cpu_patch();
514 566