diff options
Diffstat (limited to 'arch/sparc/kernel/setup_32.c')
-rw-r--r-- | arch/sparc/kernel/setup_32.c | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index d444468..c052313 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -42,7 +42,6 @@ #include <asm/vaddrs.h> #include <asm/mbus.h> #include <asm/idprom.h> -#include <asm/machines.h> #include <asm/cpudata.h> #include <asm/setup.h> #include <asm/cacheflush.h> @@ -106,7 +105,6 @@ unsigned long cmdline_memory_size __initdata = 0; /* which CPU booted us (0xff = not set) */ unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */ -unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */ static void prom_console_write(struct console *con, const char *s, unsigned n) @@ -182,13 +180,6 @@ static void __init boot_flags_init(char *commands) } } -/* This routine will in the future do all the nasty prom stuff - * to probe for the mmu type and its parameters, etc. This will - * also be where SMP things happen. - */ - -extern void sun4c_probe_vac(void); - extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; @@ -200,6 +191,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]; + flushi(addr + 0); + *(unsigned int *) (addr + 4) = insns[1]; + flushi(addr + 4); + *(unsigned int *) (addr + 8) = insns[2]; + flushi(addr + 8); + + p++; + } +} + enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); @@ -225,10 +262,6 @@ void __init setup_arch(char **cmdline_p) /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; - if (!strcmp(&cputypval[0], "sun4 ")) - sparc_cpu_model = sun4; - if (!strcmp(&cputypval[0], "sun4c")) - sparc_cpu_model = sun4c; if (!strcmp(&cputypval[0], "sun4m")) sparc_cpu_model = sun4m; if (!strcmp(&cputypval[0], "sun4s")) @@ -244,12 +277,6 @@ void __init setup_arch(char **cmdline_p) printk("ARCH: "); switch(sparc_cpu_model) { - case sun4: - printk("SUN4\n"); - break; - case sun4c: - printk("SUN4C\n"); - break; case sun4m: printk("SUN4M\n"); break; @@ -275,8 +302,6 @@ void __init setup_arch(char **cmdline_p) #endif idprom_init(); - if (ARCH_SUN4C) - sun4c_probe_vac(); load_mmu(); phys_base = 0xffffffffUL; @@ -313,6 +338,9 @@ void __init setup_arch(char **cmdline_p) init_mm.context = (unsigned long) NO_CONTEXT; init_task.thread.kregs = &fake_swapper_regs; + /* Run-time patch instructions to match the cpu model */ + per_cpu_patch(); + paging_init(); smp_setup_cpu_possible_map(); |