Commit 92704a1c authored by David S. Miller's avatar David S. Miller Committed by David S. Miller
Browse files

[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: default avatarDavid S. Miller <davem@davemloft.net>
parent f4e841da
Loading
Loading
Loading
Loading
+5 −79
Original line number Diff line number Diff line
@@ -1628,84 +1628,10 @@ __flushw_user:
2:	retl
	 nop

	/* Read cpu ID from hardware, return in %g6.
	 * (callers_pc - 4) is in %g1.  Patched at boot time.
	 *
	 * Default is spitfire implementation.
	 *
	 * The instruction sequence needs to be 5 instructions
	 * in order to fit the longest implementation, which is
	 * currently starfire.
	 */
	.align		32
	.globl		__get_cpu_id
__get_cpu_id:
	ldxa		[%g0] ASI_UPA_CONFIG, %g6
	srlx		%g6, 17, %g6
	jmpl		%g1 + 0x4, %g0
	 and		%g6, 0x1f, %g6
	nop

__get_cpu_id_cheetah_safari:
	ldxa		[%g0] ASI_SAFARI_CONFIG, %g6
	srlx		%g6, 17, %g6
	jmpl		%g1 + 0x4, %g0
	 and		%g6, 0x3ff, %g6
	nop

__get_cpu_id_cheetah_jbus:
	ldxa		[%g0] ASI_JBUS_CONFIG, %g6
	srlx		%g6, 17, %g6
	jmpl		%g1 + 0x4, %g0
	 and		%g6, 0x1f, %g6
	nop

__get_cpu_id_starfire:
	sethi		%hi(0x1fff40000d0 >> 9), %g6
	sllx		%g6, 9, %g6
	or		%g6, 0xd0, %g6
	jmpl		%g1 + 0x4, %g0
	 lduwa		[%g6] ASI_PHYS_BYPASS_EC_E, %g6

	.globl		per_cpu_patch
per_cpu_patch:
	sethi		%hi(this_is_starfire), %o0
	lduw		[%o0 + %lo(this_is_starfire)], %o1
	sethi		%hi(__get_cpu_id_starfire), %o0
	brnz,pn		%o1, 10f
	 or		%o0, %lo(__get_cpu_id_starfire), %o0
	sethi		%hi(tlb_type), %o0
	lduw		[%o0 + %lo(tlb_type)], %o1
	brz,pt		%o1, 11f
	 nop
	rdpr		%ver, %o0
	srlx		%o0, 32, %o0
	sethi		%hi(0x003e0016), %o1
	or		%o1, %lo(0x003e0016), %o1
	cmp		%o0, %o1
	sethi		%hi(__get_cpu_id_cheetah_jbus), %o0
	be,pn		%icc, 10f
	 or		%o0, %lo(__get_cpu_id_cheetah_jbus), %o0
	sethi		%hi(__get_cpu_id_cheetah_safari), %o0
	or		%o0, %lo(__get_cpu_id_cheetah_safari), %o0
10:
	sethi		%hi(__get_cpu_id), %o1
	or		%o1, %lo(__get_cpu_id), %o1
	lduw		[%o0 + 0x00], %o2
	stw		%o2, [%o1 + 0x00]
	flush		%o1 + 0x00
	lduw		[%o0 + 0x04], %o2
	stw		%o2, [%o1 + 0x04]
	flush		%o1 + 0x04
	lduw		[%o0 + 0x08], %o2
	stw		%o2, [%o1 + 0x08]
	flush		%o1 + 0x08
	lduw		[%o0 + 0x0c], %o2
	stw		%o2, [%o1 + 0x0c]
	flush		%o1 + 0x0c
	lduw		[%o0 + 0x10], %o2
	stw		%o2, [%o1 + 0x10]
	flush		%o1 + 0x10
11:
#ifdef CONFIG_SMP
	.globl		hard_smp_processor_id
hard_smp_processor_id:
	__GET_CPUID(%o0)
	retl
	 nop
#endif
+3 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <asm/cache.h>
#include <asm/cpudata.h>
#include <asm/auxio.h>
#include <asm/head.h>

#ifdef CONFIG_SMP
static void distribute_irqs(void);
@@ -153,7 +154,8 @@ void enable_irq(unsigned int irq)
		unsigned long ver;

		__asm__ ("rdpr %%ver, %0" : "=r" (ver));
		if ((ver >> 32) == 0x003e0016) {
		if ((ver >> 32) == __JALAPENO_ID ||
		    (ver >> 32) == __SERRANO_ID) {
			/* We set it to our JBUS ID. */
			__asm__ __volatile__("ldxa [%%g0] %1, %0"
					     : "=r" (tid)
+54 −2
Original line number Diff line number Diff line
@@ -490,6 +490,58 @@ void register_prom_callbacks(void)
		   "' linux-.soft2 to .soft2");
}

static void __init per_cpu_patch(void)
{
#ifdef CONFIG_SMP
	struct cpuid_patch_entry *p;
	unsigned long ver;
	int is_jbus;

	if (tlb_type == spitfire && !this_is_starfire)
		return;

	__asm__ ("rdpr %%ver, %0" : "=r" (ver));
	is_jbus = ((ver >> 32) == __JALAPENO_ID ||
		   (ver >> 32) == __SERRANO_ID);

	p = &__cpuid_patch;
	while (p < &__cpuid_patch_end) {
		unsigned long addr = p->addr;
		unsigned int *insns;

		switch (tlb_type) {
		case spitfire:
			insns = &p->starfire[0];
			break;
		case cheetah:
		case cheetah_plus:
			if (is_jbus)
				insns = &p->cheetah_jbus[0];
			else
				insns = &p->cheetah_safari[0];
			break;
		default:
			prom_printf("Unknown cpu type, halting.\n");
			prom_halt();
		};

		*(unsigned int *) (addr +  0) = insns[0];
		__asm__ __volatile__("flush	%0" : : "r" (addr +  0));

		*(unsigned int *) (addr +  4) = insns[1];
		__asm__ __volatile__("flush	%0" : : "r" (addr +  4));

		*(unsigned int *) (addr +  8) = insns[2];
		__asm__ __volatile__("flush	%0" : : "r" (addr +  8));

		*(unsigned int *) (addr + 12) = insns[3];
		__asm__ __volatile__("flush	%0" : : "r" (addr + 12));

		p++;
	}
#endif
}

void __init setup_arch(char **cmdline_p)
{
	/* Initialize PROM console and command line. */
@@ -507,8 +559,8 @@ void __init setup_arch(char **cmdline_p)
	/* Work out if we are starfire early on */
	check_if_starfire();

	/* Now we know enough to patch the __get_cpu_id()
	 * trampoline used by trap code.
	/* Now we know enough to patch the get_cpuid sequences
	 * used by trap code.
	 */
	per_cpu_patch();

+5 −4
Original line number Diff line number Diff line
@@ -424,7 +424,7 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c
static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
{
	u64 pstate, ver;
	int nack_busy_id, is_jalapeno;
	int nack_busy_id, is_jbus;

	if (cpus_empty(mask))
		return;
@@ -434,7 +434,8 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
	 * derivative processor.
	 */
	__asm__ ("rdpr %%ver, %0" : "=r" (ver));
	is_jalapeno = ((ver >> 32) == 0x003e0016);
	is_jbus = ((ver >> 32) == __JALAPENO_ID ||
		   (ver >> 32) == __SERRANO_ID);

	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));

@@ -459,7 +460,7 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
		for_each_cpu_mask(i, mask) {
			u64 target = (i << 14) | 0x70;

			if (!is_jalapeno)
			if (!is_jbus)
				target |= (nack_busy_id << 24);
			__asm__ __volatile__(
				"stxa	%%g0, [%0] %1\n\t"
@@ -512,7 +513,7 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
			for_each_cpu_mask(i, mask) {
				u64 check_mask;

				if (is_jalapeno)
				if (is_jbus)
					check_mask = (0x2UL << (2*i));
				else
					check_mask = (0x2UL <<
+3 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <asm/processor.h>
#include <asm/timer.h>
#include <asm/kdebug.h>
#include <asm/head.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
@@ -788,7 +789,8 @@ void __init cheetah_ecache_flush_init(void)
		cheetah_error_log[i].afsr = CHAFSR_INVALID;

	__asm__ ("rdpr %%ver, %0" : "=r" (ver));
	if ((ver >> 32) == 0x003e0016) {
	if ((ver >> 32) == __JALAPENO_ID ||
	    (ver >> 32) == __SERRANO_ID) {
		cheetah_error_table = &__jalapeno_error_table[0];
		cheetah_afsr_errors = JPAFSR_ERRORS;
	} else if ((ver >> 32) == 0x003e0015) {
Loading