diff options
Diffstat (limited to 'arch/sparc64/kernel/setup.c')
-rw-r--r-- | arch/sparc64/kernel/setup.c | 56 |
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 | ||
493 | static 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 | |||
493 | void __init setup_arch(char **cmdline_p) | 545 | void __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 | ||