aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
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
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')
-rw-r--r--arch/sparc64/kernel/entry.S84
-rw-r--r--arch/sparc64/kernel/irq.c4
-rw-r--r--arch/sparc64/kernel/setup.c56
-rw-r--r--arch/sparc64/kernel/smp.c9
-rw-r--r--arch/sparc64/kernel/traps.c4
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S3
6 files changed, 73 insertions, 87 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 563fa4ec33f8..b3511ff5d04a 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1628,84 +1628,10 @@ __flushw_user:
16282: retl 16282: retl
1629 nop 1629 nop
1630 1630
1631 /* Read cpu ID from hardware, return in %g6. 1631#ifdef CONFIG_SMP
1632 * (callers_pc - 4) is in %g1. Patched at boot time. 1632 .globl hard_smp_processor_id
1633 * 1633hard_smp_processor_id:
1634 * Default is spitfire implementation. 1634 __GET_CPUID(%o0)
1635 *
1636 * The instruction sequence needs to be 5 instructions
1637 * in order to fit the longest implementation, which is
1638 * currently starfire.
1639 */
1640 .align 32
1641 .globl __get_cpu_id
1642__get_cpu_id:
1643 ldxa [%g0] ASI_UPA_CONFIG, %g6
1644 srlx %g6, 17, %g6
1645 jmpl %g1 + 0x4, %g0
1646 and %g6, 0x1f, %g6
1647 nop
1648
1649__get_cpu_id_cheetah_safari:
1650 ldxa [%g0] ASI_SAFARI_CONFIG, %g6
1651 srlx %g6, 17, %g6
1652 jmpl %g1 + 0x4, %g0
1653 and %g6, 0x3ff, %g6
1654 nop
1655
1656__get_cpu_id_cheetah_jbus:
1657 ldxa [%g0] ASI_JBUS_CONFIG, %g6
1658 srlx %g6, 17, %g6
1659 jmpl %g1 + 0x4, %g0
1660 and %g6, 0x1f, %g6
1661 nop
1662
1663__get_cpu_id_starfire:
1664 sethi %hi(0x1fff40000d0 >> 9), %g6
1665 sllx %g6, 9, %g6
1666 or %g6, 0xd0, %g6
1667 jmpl %g1 + 0x4, %g0
1668 lduwa [%g6] ASI_PHYS_BYPASS_EC_E, %g6
1669
1670 .globl per_cpu_patch
1671per_cpu_patch:
1672 sethi %hi(this_is_starfire), %o0
1673 lduw [%o0 + %lo(this_is_starfire)], %o1
1674 sethi %hi(__get_cpu_id_starfire), %o0
1675 brnz,pn %o1, 10f
1676 or %o0, %lo(__get_cpu_id_starfire), %o0
1677 sethi %hi(tlb_type), %o0
1678 lduw [%o0 + %lo(tlb_type)], %o1
1679 brz,pt %o1, 11f
1680 nop
1681 rdpr %ver, %o0
1682 srlx %o0, 32, %o0
1683 sethi %hi(0x003e0016), %o1
1684 or %o1, %lo(0x003e0016), %o1
1685 cmp %o0, %o1
1686 sethi %hi(__get_cpu_id_cheetah_jbus), %o0
1687 be,pn %icc, 10f
1688 or %o0, %lo(__get_cpu_id_cheetah_jbus), %o0
1689 sethi %hi(__get_cpu_id_cheetah_safari), %o0
1690 or %o0, %lo(__get_cpu_id_cheetah_safari), %o0
169110:
1692 sethi %hi(__get_cpu_id), %o1
1693 or %o1, %lo(__get_cpu_id), %o1
1694 lduw [%o0 + 0x00], %o2
1695 stw %o2, [%o1 + 0x00]
1696 flush %o1 + 0x00
1697 lduw [%o0 + 0x04], %o2
1698 stw %o2, [%o1 + 0x04]
1699 flush %o1 + 0x04
1700 lduw [%o0 + 0x08], %o2
1701 stw %o2, [%o1 + 0x08]
1702 flush %o1 + 0x08
1703 lduw [%o0 + 0x0c], %o2
1704 stw %o2, [%o1 + 0x0c]
1705 flush %o1 + 0x0c
1706 lduw [%o0 + 0x10], %o2
1707 stw %o2, [%o1 + 0x10]
1708 flush %o1 + 0x10
170911:
1710 retl 1635 retl
1711 nop 1636 nop
1637#endif
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 3e48af2769d4..d069a6feb535 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -39,6 +39,7 @@
39#include <asm/cache.h> 39#include <asm/cache.h>
40#include <asm/cpudata.h> 40#include <asm/cpudata.h>
41#include <asm/auxio.h> 41#include <asm/auxio.h>
42#include <asm/head.h>
42 43
43#ifdef CONFIG_SMP 44#ifdef CONFIG_SMP
44static void distribute_irqs(void); 45static void distribute_irqs(void);
@@ -153,7 +154,8 @@ void enable_irq(unsigned int irq)
153 unsigned long ver; 154 unsigned long ver;
154 155
155 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 156 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
156 if ((ver >> 32) == 0x003e0016) { 157 if ((ver >> 32) == __JALAPENO_ID ||
158 (ver >> 32) == __SERRANO_ID) {
157 /* We set it to our JBUS ID. */ 159 /* We set it to our JBUS ID. */
158 __asm__ __volatile__("ldxa [%%g0] %1, %0" 160 __asm__ __volatile__("ldxa [%%g0] %1, %0"
159 : "=r" (tid) 161 : "=r" (tid)
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
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 0e7552546d36..16b8eca9754e 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -424,7 +424,7 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c
424static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) 424static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
425{ 425{
426 u64 pstate, ver; 426 u64 pstate, ver;
427 int nack_busy_id, is_jalapeno; 427 int nack_busy_id, is_jbus;
428 428
429 if (cpus_empty(mask)) 429 if (cpus_empty(mask))
430 return; 430 return;
@@ -434,7 +434,8 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
434 * derivative processor. 434 * derivative processor.
435 */ 435 */
436 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 436 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
437 is_jalapeno = ((ver >> 32) == 0x003e0016); 437 is_jbus = ((ver >> 32) == __JALAPENO_ID ||
438 (ver >> 32) == __SERRANO_ID);
438 439
439 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); 440 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
440 441
@@ -459,7 +460,7 @@ retry:
459 for_each_cpu_mask(i, mask) { 460 for_each_cpu_mask(i, mask) {
460 u64 target = (i << 14) | 0x70; 461 u64 target = (i << 14) | 0x70;
461 462
462 if (!is_jalapeno) 463 if (!is_jbus)
463 target |= (nack_busy_id << 24); 464 target |= (nack_busy_id << 24);
464 __asm__ __volatile__( 465 __asm__ __volatile__(
465 "stxa %%g0, [%0] %1\n\t" 466 "stxa %%g0, [%0] %1\n\t"
@@ -512,7 +513,7 @@ retry:
512 for_each_cpu_mask(i, mask) { 513 for_each_cpu_mask(i, mask) {
513 u64 check_mask; 514 u64 check_mask;
514 515
515 if (is_jalapeno) 516 if (is_jbus)
516 check_mask = (0x2UL << (2*i)); 517 check_mask = (0x2UL << (2*i));
517 else 518 else
518 check_mask = (0x2UL << 519 check_mask = (0x2UL <<
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 7e52e8972668..1c4744c047ab 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -38,6 +38,7 @@
38#include <asm/processor.h> 38#include <asm/processor.h>
39#include <asm/timer.h> 39#include <asm/timer.h>
40#include <asm/kdebug.h> 40#include <asm/kdebug.h>
41#include <asm/head.h>
41#ifdef CONFIG_KMOD 42#ifdef CONFIG_KMOD
42#include <linux/kmod.h> 43#include <linux/kmod.h>
43#endif 44#endif
@@ -788,7 +789,8 @@ void __init cheetah_ecache_flush_init(void)
788 cheetah_error_log[i].afsr = CHAFSR_INVALID; 789 cheetah_error_log[i].afsr = CHAFSR_INVALID;
789 790
790 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 791 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
791 if ((ver >> 32) == 0x003e0016) { 792 if ((ver >> 32) == __JALAPENO_ID ||
793 (ver >> 32) == __SERRANO_ID) {
792 cheetah_error_table = &__jalapeno_error_table[0]; 794 cheetah_error_table = &__jalapeno_error_table[0];
793 cheetah_afsr_errors = JPAFSR_ERRORS; 795 cheetah_afsr_errors = JPAFSR_ERRORS;
794 } else if ((ver >> 32) == 0x003e0015) { 796 } else if ((ver >> 32) == 0x003e0015) {
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 71b943f1c9b1..1639d9c935c3 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -74,6 +74,9 @@ SECTIONS
74 __tsb_phys_patch = .; 74 __tsb_phys_patch = .;
75 .tsb_phys_patch : { *(.tsb_phys_patch) } 75 .tsb_phys_patch : { *(.tsb_phys_patch) }
76 __tsb_phys_patch_end = .; 76 __tsb_phys_patch_end = .;
77 __cpuid_patch = .;
78 .cpuid_patch : { *(.cpuid_patch) }
79 __cpuid_patch_end = .;
77 . = ALIGN(8192); 80 . = ALIGN(8192);
78 __initramfs_start = .; 81 __initramfs_start = .;
79 .init.ramfs : { *(.init.ramfs) } 82 .init.ramfs : { *(.init.ramfs) }