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 d444468b27f..c052313f4dc 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();  |