From c68e5d39a502d01421cbc70d25c377e9215facef Mon Sep 17 00:00:00 2001 From: David S. Miller Date: Sun, 13 May 2012 23:09:04 -0700 Subject: sparc32: Implement hard_smp_processor_id() via instruction patching. This is the last non-trivial user of btfixup. Like sparc64, use a special patch section to resolve the various implementations of how to read the current CPU's ID when we don't have current_thread_info()->cpu necessarily available. Signed-off-by: David S. Miller Tested-by: Sam Ravnborg --- arch/sparc/kernel/setup_32.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'arch/sparc/kernel/setup_32.c') diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 6f294f371d68..2f7cfb5f7569 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -192,6 +192,52 @@ extern int root_mountflags; char reboot_command[COMMAND_LINE_SIZE]; +struct cpuid_patch_entry { + unsigned int addr; + unsigned int sun4d[3]; + unsigned int leon[3]; +}; +extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; + +static void __init per_cpu_patch(void) +{ + struct cpuid_patch_entry *p; + + if (sparc_cpu_model == sun4m) { + /* Nothing to do, this is what the unpatched code + * targets. + */ + return; + } + + p = &__cpuid_patch; + while (p < &__cpuid_patch_end) { + unsigned long addr = p->addr; + unsigned int *insns; + + switch (sparc_cpu_model) { + case sun4d: + insns = &p->sun4d[0]; + break; + + case sparc_leon: + insns = &p->leon[0]; + break; + default: + prom_printf("Unknown cpu type, halting.\n"); + prom_halt(); + } + *(unsigned int *) (addr + 0) = insns[0]; + *(unsigned int *) (addr + 4) = insns[1]; + *(unsigned int *) (addr + 8) = insns[2]; + } +#ifdef CONFIG_SMP + local_ops->cache_all(); +#else + sparc32_cachetlb_ops->cache_all(); +#endif +} + enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); @@ -295,6 +341,11 @@ void __init setup_arch(char **cmdline_p) paging_init(); + /* Now that we have the cache ops hooked up, we can patch + * instructions. + */ + per_cpu_patch(); + smp_setup_cpu_possible_map(); } -- cgit v1.2.3-55-g7522