diff options
Diffstat (limited to 'arch/sparc/kernel')
| -rw-r--r-- | arch/sparc/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/apc.c | 37 | ||||
| -rw-r--r-- | arch/sparc/kernel/auxio_32.c | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/btext.c | 673 | ||||
| -rw-r--r-- | arch/sparc/kernel/cpu.c | 11 | ||||
| -rw-r--r-- | arch/sparc/kernel/entry.S | 33 | ||||
| -rw-r--r-- | arch/sparc/kernel/head_32.S | 22 | ||||
| -rw-r--r-- | arch/sparc/kernel/ioport.c | 5 | ||||
| -rw-r--r-- | arch/sparc/kernel/irq_64.c | 8 | ||||
| -rw-r--r-- | arch/sparc/kernel/ldc.c | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/leon_kernel.c | 84 | ||||
| -rw-r--r-- | arch/sparc/kernel/leon_smp.c | 468 | ||||
| -rw-r--r-- | arch/sparc/kernel/pci_msi.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/perf_event.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/prom_common.c | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/setup_64.c | 6 | ||||
| -rw-r--r-- | arch/sparc/kernel/smp_32.c | 10 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc32.c | 62 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_32.S | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_64.S | 6 | ||||
| -rw-r--r-- | arch/sparc/kernel/time_32.c | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/trampoline_32.S | 69 | ||||
| -rw-r--r-- | arch/sparc/kernel/visemul.c | 2 | 
23 files changed, 1407 insertions, 110 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 5b47fab9966..c6316142db4 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -72,7 +72,7 @@ obj-y                     += dma.o  obj-$(CONFIG_SPARC32_PCI) += pcic.o  obj-$(CONFIG_SMP)         += trampoline_$(BITS).o smp_$(BITS).o -obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o +obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o  obj-$(CONFIG_SPARC64_SMP) += hvtramp.o  obj-y                     += auxio_$(BITS).o @@ -87,6 +87,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS).o  obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o  CFLAGS_REMOVE_ftrace.o := -pg +obj-$(CONFIG_EARLYFB) += btext.o  obj-$(CONFIG_STACKTRACE)     += stacktrace.o  # sparc64 PCI  obj-$(CONFIG_SPARC64_PCI)    += pci.o pci_common.o psycho_common.o diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 9c115823c4b..71ec90b9e31 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -10,7 +10,6 @@  #include <linux/errno.h>  #include <linux/init.h>  #include <linux/miscdevice.h> -#include <linux/smp_lock.h>  #include <linux/pm.h>  #include <linux/of.h>  #include <linux/of_device.h> @@ -76,7 +75,6 @@ static inline void apc_free(struct of_device *op)  static int apc_open(struct inode *inode, struct file *f)  { -	cycle_kernel_lock();  	return 0;  } @@ -87,61 +85,46 @@ static int apc_release(struct inode *inode, struct file *f)  static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)  { -	__u8 inarg, __user *arg; - -	arg = (__u8 __user *) __arg; - -	lock_kernel(); +	__u8 inarg, __user *arg = (__u8 __user *) __arg;  	switch (cmd) {  	case APCIOCGFANCTL: -		if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) { -			unlock_kernel(); +		if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))  			return -EFAULT; -		}  		break;  	case APCIOCGCPWR: -		if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) { -			unlock_kernel(); +		if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg))  			return -EFAULT; -		}  		break;  	case APCIOCGBPORT: -		if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) { -			unlock_kernel(); +		if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg))  			return -EFAULT; -		}  		break;  	case APCIOCSFANCTL: -		if (get_user(inarg, arg)) { -			unlock_kernel(); +		if (get_user(inarg, arg))  			return -EFAULT; -		}  		apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);  		break; +  	case APCIOCSCPWR: -		if (get_user(inarg, arg)) { -			unlock_kernel(); +		if (get_user(inarg, arg))  			return -EFAULT; -		}  		apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);  		break; +  	case APCIOCSBPORT: -		if (get_user(inarg, arg)) { -			unlock_kernel(); +		if (get_user(inarg, arg))  			return -EFAULT; -		}  		apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);  		break; +  	default: -		unlock_kernel();  		return -EINVAL;  	}; -	unlock_kernel();  	return 0;  } diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index 45c41232fc4..ee8d214cae1 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c @@ -28,6 +28,7 @@ void __init auxio_probe(void)  	struct resource r;  	switch (sparc_cpu_model) { +	case sparc_leon:  	case sun4d:  	case sun4:  		return; diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c new file mode 100644 index 00000000000..8cc2d56ffe9 --- /dev/null +++ b/arch/sparc/kernel/btext.c @@ -0,0 +1,673 @@ +/* + * Procedures for drawing on the screen early on in the boot process. + * + * Benjamin Herrenschmidt <benh@kernel.crashing.org> + */ +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/console.h> + +#include <asm/btext.h> +#include <asm/oplib.h> +#include <asm/io.h> + +#define NO_SCROLL + +#ifndef NO_SCROLL +static void scrollscreen(void); +#endif + +static void draw_byte(unsigned char c, long locX, long locY); +static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); +static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); +static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); + +#define __force_data __attribute__((__section__(".data"))) + +static int g_loc_X __force_data; +static int g_loc_Y __force_data; +static int g_max_loc_X __force_data; +static int g_max_loc_Y __force_data; + +static int dispDeviceRowBytes __force_data; +static int dispDeviceDepth  __force_data; +static int dispDeviceRect[4] __force_data; +static unsigned char *dispDeviceBase __force_data; + +#define cmapsz	(16*256) + +static unsigned char vga_font[cmapsz]; + +static int __init btext_initialize(unsigned int node) +{ +	unsigned int width, height, depth, pitch; +	unsigned long address = 0; +	u32 prop; + +	if (prom_getproperty(node, "width", (char *)&width, 4) < 0) +		return -EINVAL; +	if (prom_getproperty(node, "height", (char *)&height, 4) < 0) +		return -EINVAL; +	if (prom_getproperty(node, "depth", (char *)&depth, 4) < 0) +		return -EINVAL; +	pitch = width * ((depth + 7) / 8); + +	if (prom_getproperty(node, "linebytes", (char *)&prop, 4) >= 0 && +	    prop != 0xffffffffu) +		pitch = prop; + +	if (pitch == 1) +		pitch = 0x1000; + +	if (prom_getproperty(node, "address", (char *)&prop, 4) >= 0) +		address = prop; + +	/* FIXME: Add support for PCI reg properties. Right now, only +	 * reliable on macs +	 */ +	if (address == 0) +		return -EINVAL; + +	g_loc_X = 0; +	g_loc_Y = 0; +	g_max_loc_X = width / 8; +	g_max_loc_Y = height / 16; +	dispDeviceBase = (unsigned char *)address; +	dispDeviceRowBytes = pitch; +	dispDeviceDepth = depth == 15 ? 16 : depth; +	dispDeviceRect[0] = dispDeviceRect[1] = 0; +	dispDeviceRect[2] = width; +	dispDeviceRect[3] = height; + +	return 0; +} + +/* Calc the base address of a given point (x,y) */ +static unsigned char * calc_base(int x, int y) +{ +	unsigned char *base = dispDeviceBase; + +	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3); +	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes; +	return base; +} + +static void btext_clearscreen(void) +{ +	unsigned int *base	= (unsigned int *)calc_base(0, 0); +	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) * +					(dispDeviceDepth >> 3)) >> 2; +	int i,j; + +	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) +	{ +		unsigned int *ptr = base; +		for(j=width; j; --j) +			*(ptr++) = 0; +		base += (dispDeviceRowBytes >> 2); +	} +} + +#ifndef NO_SCROLL +static void scrollscreen(void) +{ +	unsigned int *src     	= (unsigned int *)calc_base(0,16); +	unsigned int *dst     	= (unsigned int *)calc_base(0,0); +	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) * +				   (dispDeviceDepth >> 3)) >> 2; +	int i,j; + +	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) +	{ +		unsigned int *src_ptr = src; +		unsigned int *dst_ptr = dst; +		for(j=width; j; --j) +			*(dst_ptr++) = *(src_ptr++); +		src += (dispDeviceRowBytes >> 2); +		dst += (dispDeviceRowBytes >> 2); +	} +	for (i=0; i<16; i++) +	{ +		unsigned int *dst_ptr = dst; +		for(j=width; j; --j) +			*(dst_ptr++) = 0; +		dst += (dispDeviceRowBytes >> 2); +	} +} +#endif /* ndef NO_SCROLL */ + +void btext_drawchar(char c) +{ +	int cline = 0; +#ifdef NO_SCROLL +	int x; +#endif +	switch (c) { +	case '\b': +		if (g_loc_X > 0) +			--g_loc_X; +		break; +	case '\t': +		g_loc_X = (g_loc_X & -8) + 8; +		break; +	case '\r': +		g_loc_X = 0; +		break; +	case '\n': +		g_loc_X = 0; +		g_loc_Y++; +		cline = 1; +		break; +	default: +		draw_byte(c, g_loc_X++, g_loc_Y); +	} +	if (g_loc_X >= g_max_loc_X) { +		g_loc_X = 0; +		g_loc_Y++; +		cline = 1; +	} +#ifndef NO_SCROLL +	while (g_loc_Y >= g_max_loc_Y) { +		scrollscreen(); +		g_loc_Y--; +	} +#else +	/* wrap around from bottom to top of screen so we don't +	   waste time scrolling each line.  -- paulus. */ +	if (g_loc_Y >= g_max_loc_Y) +		g_loc_Y = 0; +	if (cline) { +		for (x = 0; x < g_max_loc_X; ++x) +			draw_byte(' ', x, g_loc_Y); +	} +#endif +} + +static void btext_drawtext(const char *c, unsigned int len) +{ +	while (len--) +		btext_drawchar(*c++); +} + +static void draw_byte(unsigned char c, long locX, long locY) +{ +	unsigned char *base	= calc_base(locX << 3, locY << 4); +	unsigned char *font	= &vga_font[((unsigned int)c) * 16]; +	int rb			= dispDeviceRowBytes; + +	switch(dispDeviceDepth) { +	case 24: +	case 32: +		draw_byte_32(font, (unsigned int *)base, rb); +		break; +	case 15: +	case 16: +		draw_byte_16(font, (unsigned int *)base, rb); +		break; +	case 8: +		draw_byte_8(font, (unsigned int *)base, rb); +		break; +	} +} + +static unsigned int expand_bits_8[16] = { +	0x00000000, +	0x000000ff, +	0x0000ff00, +	0x0000ffff, +	0x00ff0000, +	0x00ff00ff, +	0x00ffff00, +	0x00ffffff, +	0xff000000, +	0xff0000ff, +	0xff00ff00, +	0xff00ffff, +	0xffff0000, +	0xffff00ff, +	0xffffff00, +	0xffffffff +}; + +static unsigned int expand_bits_16[4] = { +	0x00000000, +	0x0000ffff, +	0xffff0000, +	0xffffffff +}; + + +static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0xFFFFFFFFUL; +	int bg = 0x00000000UL; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (-(bits >> 7) & fg) ^ bg; +		base[1] = (-((bits >> 6) & 1) & fg) ^ bg; +		base[2] = (-((bits >> 5) & 1) & fg) ^ bg; +		base[3] = (-((bits >> 4) & 1) & fg) ^ bg; +		base[4] = (-((bits >> 3) & 1) & fg) ^ bg; +		base[5] = (-((bits >> 2) & 1) & fg) ^ bg; +		base[6] = (-((bits >> 1) & 1) & fg) ^ bg; +		base[7] = (-(bits & 1) & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static void draw_byte_16(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0xFFFFFFFFUL; +	int bg = 0x00000000UL; +	unsigned int *eb = (int *)expand_bits_16; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (eb[bits >> 6] & fg) ^ bg; +		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; +		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; +		base[3] = (eb[bits & 3] & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static void draw_byte_8(unsigned char *font, unsigned int *base, int rb) +{ +	int l, bits; +	int fg = 0x0F0F0F0FUL; +	int bg = 0x00000000UL; +	unsigned int *eb = (int *)expand_bits_8; + +	for (l = 0; l < 16; ++l) +	{ +		bits = *font++; +		base[0] = (eb[bits >> 4] & fg) ^ bg; +		base[1] = (eb[bits & 0xf] & fg) ^ bg; +		base = (unsigned int *) ((char *)base + rb); +	} +} + +static void btext_console_write(struct console *con, const char *s, +				unsigned int n) +{ +	btext_drawtext(s, n); +} + +static struct console btext_console = { +	.name	= "btext", +	.write	= btext_console_write, +	.flags	= CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME, +	.index	= 0, +}; + +int __init btext_find_display(void) +{ +	unsigned int node; +	char type[32]; +	int ret; + +	node = prom_inst2pkg(prom_stdout); +	if (prom_getproperty(node, "device_type", type, 32) < 0) +		return -ENODEV; +	if (strcmp(type, "display")) +		return -ENODEV; + +	ret = btext_initialize(node); +	if (!ret) { +		btext_clearscreen(); +		register_console(&btext_console); +	} +	return ret; +} + +static unsigned char vga_font[cmapsz] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, +0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, +0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, +0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, +0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, +0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, +0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, +0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, +0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, +0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, +0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, +0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, +0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, +0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, +0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, +0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, +0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, +0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, +0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, +0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, +0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, +0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, +0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, +0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, +0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, +0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, +0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, +0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, +0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, +0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, +0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, +0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, +0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, +0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, +0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, +0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, +0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, +0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, +0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, +0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, +0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, +0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, +0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, +0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, +0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, +0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, +0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, +0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, +0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, +0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, +0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, +0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, +0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, +0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, +0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, +0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, +0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, +0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, +0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, +0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, +0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, +0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, +0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, +0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, +0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, +0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, +0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, +0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, +0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, +0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, +0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, +0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, +0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, +0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, +0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, +0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, +0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, +0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, +0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, +0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, +0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, +0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, +0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, +0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, +0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, +0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, +0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, +0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, +0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, +0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, +}; diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 1446df90ef8..e447938d39c 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -185,6 +185,17 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {  		FPU(-1, NULL)  	}  },{ +	0xF,		/* Aeroflex Gaisler */ +	.cpu_info = { +		CPU(3, "LEON"), +		CPU(-1, NULL) +	}, +	.fpu_info = { +		FPU(2, "GRFPU"), +		FPU(3, "GRFPU-Lite"), +		FPU(-1, NULL) +	} +},{  	0x17,  	.cpu_info = {  		CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"), diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f41ecc5ac0b..ec9c7bc67d2 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -400,6 +400,39 @@ linux_trap_ipi15_sun4d:  	/* FIXME */  1:	b,a	1b +#ifdef CONFIG_SPARC_LEON + +	.globl	smpleon_ticker +	/* SMP per-cpu ticker interrupts are handled specially. */ +smpleon_ticker: +        SAVE_ALL +	or	%l0, PSR_PIL, %g2 +	wr	%g2, 0x0, %psr +	WRITE_PAUSE +	wr	%g2, PSR_ET, %psr +	WRITE_PAUSE +	call	leon_percpu_timer_interrupt +	 add	%sp, STACKFRAME_SZ, %o0 +	wr	%l0, PSR_ET, %psr +	WRITE_PAUSE +	RESTORE_ALL + +	.align	4 +	.globl	linux_trap_ipi15_leon +linux_trap_ipi15_leon: +	SAVE_ALL +	or	%l0, PSR_PIL, %l4 +	wr	%l4, 0x0, %psr +	WRITE_PAUSE +	wr	%l4, PSR_ET, %psr +	WRITE_PAUSE +	call	leon_cross_call_irq +	 nop +	b	ret_trap_lockless_ipi +	 clr	%l6 + +#endif /* CONFIG_SPARC_LEON */ +  #endif /* CONFIG_SMP */  	/* This routine handles illegal instructions and privileged diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 439d82a95ac..21bb2590d4a 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S @@ -811,9 +811,31 @@ found_version:  got_prop:  #ifdef CONFIG_SPARC_LEON  	        /* no cpu-type check is needed, it is a SPARC-LEON */ +#ifdef CONFIG_SMP +		ba leon_smp_init +		 nop + +		.global leon_smp_init +leon_smp_init: +		sethi	%hi(boot_cpu_id), %g1    ! master always 0 +		stb	%g0, [%g1 + %lo(boot_cpu_id)] +		sethi	%hi(boot_cpu_id4), %g1   ! master always 0 +		stb	%g0, [%g1 + %lo(boot_cpu_id4)] + +		rd     %asr17,%g1 +		srl    %g1,28,%g1 + +		cmp %g0,%g1 +		 beq sun4c_continue_boot         !continue with master +		nop + +		ba leon_smp_cpu_startup +		 nop +#else  		ba sun4c_continue_boot  		 nop  #endif +#endif  		set	cputypval, %o2  		ldub	[%o2 + 0x4], %l1 diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 9f61fd8cbb7..3c8c44f6a41 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -48,8 +48,13 @@  #include <asm/dma.h>  #include <asm/iommu.h>  #include <asm/io-unit.h> +#include <asm/leon.h> +#ifdef CONFIG_SPARC_LEON +#define mmu_inval_dma_area(p, l) leon_flush_dcache_all() +#else  #define mmu_inval_dma_area(p, l)	/* Anton pulled it out for 2.4.0-xx */ +#endif  static struct resource *_sparc_find_resource(struct resource *r,  					     unsigned long); diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 8ab1d4728a4..ce996f97855 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -187,7 +187,7 @@ int show_interrupts(struct seq_file *p, void *v)  		for_each_online_cpu(j)  			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));  #endif -		seq_printf(p, " %9s", irq_desc[i].chip->typename); +		seq_printf(p, " %9s", irq_desc[i].chip->name);  		seq_printf(p, "  %s", action->name);  		for (action=action->next; action; action = action->next) @@ -484,7 +484,7 @@ static void sun4v_virq_eoi(unsigned int virt_irq)  }  static struct irq_chip sun4u_irq = { -	.typename	= "sun4u", +	.name		= "sun4u",  	.enable		= sun4u_irq_enable,  	.disable	= sun4u_irq_disable,  	.eoi		= sun4u_irq_eoi, @@ -492,7 +492,7 @@ static struct irq_chip sun4u_irq = {  };  static struct irq_chip sun4v_irq = { -	.typename	= "sun4v", +	.name		= "sun4v",  	.enable		= sun4v_irq_enable,  	.disable	= sun4v_irq_disable,  	.eoi		= sun4v_irq_eoi, @@ -500,7 +500,7 @@ static struct irq_chip sun4v_irq = {  };  static struct irq_chip sun4v_virq = { -	.typename	= "vsun4v", +	.name		= "vsun4v",  	.enable		= sun4v_virq_enable,  	.disable	= sun4v_virq_disable,  	.eoi		= sun4v_virq_eoi, diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index adf5f273868..cb3c72c45aa 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)  	snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);  	err = request_irq(lp->cfg.rx_irq, ldc_rx, -			  IRQF_SAMPLE_RANDOM | IRQF_SHARED, +			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,  			  lp->rx_irq_name, lp);  	if (err)  		return err;  	err = request_irq(lp->cfg.tx_irq, ldc_tx, -			  IRQF_SAMPLE_RANDOM | IRQF_SHARED, +			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,  			  lp->tx_irq_name, lp);  	if (err) {  		free_irq(lp->cfg.rx_irq, lp); diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 54d8a5bd482..87f1760c0aa 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -12,11 +12,14 @@  #include <linux/of_platform.h>  #include <linux/interrupt.h>  #include <linux/of_device.h> +  #include <asm/oplib.h>  #include <asm/timer.h>  #include <asm/prom.h>  #include <asm/leon.h>  #include <asm/leon_amba.h> +#include <asm/traps.h> +#include <asm/cacheflush.h>  #include "prom.h"  #include "irq.h" @@ -115,6 +118,21 @@ void __init leon_init_timers(irq_handler_t counter_fn)  				      (((1000000 / 100) - 1)));  		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); +#ifdef CONFIG_SMP +		leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs; +		leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1; + +		if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & +		      (1<<LEON3_GPTIMER_SEPIRQ))) { +			prom_printf("irq timer not configured with seperate irqs \n"); +			BUG(); +		} + +		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); +		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); +		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); +# endif +  	} else {  		printk(KERN_ERR "No Timer/irqctrl found\n");  		BUG(); @@ -130,11 +148,41 @@ void __init leon_init_timers(irq_handler_t counter_fn)  		prom_halt();  	} +# ifdef CONFIG_SMP +	{ +		unsigned long flags; +		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)]; + +		/* For SMP we use the level 14 ticker, however the bootup code +		 * has copied the firmwares level 14 vector into boot cpu's +		 * trap table, we must fix this now or we get squashed. +		 */ +		local_irq_save(flags); + +		patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ + +		/* Adjust so that we jump directly to smpleon_ticker */ +		trap_table->inst_three += smpleon_ticker - real_irq_entry; + +		local_flush_cache_all(); +		local_irq_restore(flags); +	} +# endif +  	if (leon3_gptimer_regs) {  		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,  				      LEON3_GPTIMER_EN |  				      LEON3_GPTIMER_RL |  				      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); + +#ifdef CONFIG_SMP +		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, +				      LEON3_GPTIMER_EN | +				      LEON3_GPTIMER_RL | +				      LEON3_GPTIMER_LD | +				      LEON3_GPTIMER_IRQEN); +#endif +  	}  } @@ -175,6 +223,42 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)  	}  } +#ifdef CONFIG_SMP + +void leon_set_cpu_int(int cpu, int level) +{ +	unsigned long mask; +	mask = get_irqmask(level); +	LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); +} + +static void leon_clear_ipi(int cpu, int level) +{ +	unsigned long mask; +	mask = get_irqmask(level); +	LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16); +} + +static void leon_set_udt(int cpu) +{ +} + +void leon_clear_profile_irq(int cpu) +{ +} + +void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) +{ +	unsigned long mask, flags, *addr; +	mask = get_irqmask(irq_nr); +	local_irq_save(flags); +	addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]); +	LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask))); +	local_irq_restore(flags); +} + +#endif +  void __init leon_init_IRQ(void)  {  	sparc_init_timers = leon_init_timers; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c new file mode 100644 index 00000000000..05c0dadd637 --- /dev/null +++ b/arch/sparc/kernel/leon_smp.c @@ -0,0 +1,468 @@ +/* leon_smp.c: Sparc-Leon SMP support. + * + * based on sun4m_smp.c + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB + * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB + */ + +#include <asm/head.h> + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/threads.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/profile.h> +#include <linux/pm.h> +#include <linux/delay.h> + +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> + +#include <asm/ptrace.h> +#include <asm/atomic.h> +#include <asm/irq_regs.h> + +#include <asm/delay.h> +#include <asm/irq.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/oplib.h> +#include <asm/cpudata.h> +#include <asm/asi.h> +#include <asm/leon.h> +#include <asm/leon_amba.h> + +#ifdef CONFIG_SPARC_LEON + +#include "irq.h" + +extern ctxd_t *srmmu_ctx_table_phys; +static int smp_processors_ready; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; +extern unsigned char boot_cpu_id; +extern cpumask_t smp_commenced_mask; +void __init leon_configure_cache_smp(void); + +static inline unsigned long do_swap(volatile unsigned long *ptr, +				    unsigned long val) +{ +	__asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val) +			     : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) +			     : "memory"); +	return val; +} + +static void smp_setup_percpu_timer(void); + +void __cpuinit leon_callin(void) +{ +	int cpuid = hard_smpleon_processor_id(); + +	local_flush_cache_all(); +	local_flush_tlb_all(); +	leon_configure_cache_smp(); + +	/* Get our local ticker going. */ +	smp_setup_percpu_timer(); + +	calibrate_delay(); +	smp_store_cpu_info(cpuid); + +	local_flush_cache_all(); +	local_flush_tlb_all(); + +	/* +	 * Unblock the master CPU _only_ when the scheduler state +	 * of all secondary CPUs will be up-to-date, so after +	 * the SMP initialization the master will be just allowed +	 * to call the scheduler code. +	 * Allow master to continue. +	 */ +	do_swap(&cpu_callin_map[cpuid], 1); + +	local_flush_cache_all(); +	local_flush_tlb_all(); + +	cpu_probe(); + +	/* Fix idle thread fields. */ +	__asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(¤t_set[cpuid]) +			     : "memory" /* paranoid */); + +	/* Attach to the address space of init_task. */ +	atomic_inc(&init_mm.mm_count); +	current->active_mm = &init_mm; + +	while (!cpu_isset(cpuid, smp_commenced_mask)) +		mb(); + +	local_irq_enable(); +	cpu_set(cpuid, cpu_online_map); +} + +/* + *	Cycle through the processors asking the PROM to start each one. + */ + +extern struct linux_prom_registers smp_penguin_ctable; + +void __init leon_configure_cache_smp(void) +{ +	unsigned long cfg = sparc_leon3_get_dcachecfg(); +	int me = smp_processor_id(); + +	if (ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg) > 4) { +		printk(KERN_INFO "Note: SMP with snooping only works on 4k cache, found %dk(0x%x) on cpu %d, disabling caches\n", +		     (unsigned int)ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg), +		     (unsigned int)cfg, (unsigned int)me); +		sparc_leon3_disable_cache(); +	} else { +		if (cfg & ASI_LEON3_SYSCTRL_CFG_SNOOPING) { +			sparc_leon3_enable_snooping(); +		} else { +			printk(KERN_INFO "Note: You have to enable snooping in the vhdl model cpu %d, disabling caches\n", +			     me); +			sparc_leon3_disable_cache(); +		} +	} + +	local_flush_cache_all(); +	local_flush_tlb_all(); +} + +void leon_smp_setbroadcast(unsigned int mask) +{ +	int broadcast = +	    ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >> +	      LEON3_IRQMPSTATUS_BROADCAST) & 1); +	if (!broadcast) { +		prom_printf("######## !!!! The irqmp-ctrl must have broadcast enabled, smp wont work !!!!! ####### nr cpus: %d\n", +		     leon_smp_nrcpus()); +		if (leon_smp_nrcpus() > 1) { +			BUG(); +		} else { +			prom_printf("continue anyway\n"); +			return; +		} +	} +	LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask); +} + +unsigned int leon_smp_getbroadcast(void) +{ +	unsigned int mask; +	mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast)); +	return mask; +} + +int leon_smp_nrcpus(void) +{ +	int nrcpu = +	    ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >> +	      LEON3_IRQMPSTATUS_CPUNR) & 0xf) + 1; +	return nrcpu; +} + +void __init leon_boot_cpus(void) +{ +	int nrcpu = leon_smp_nrcpus(); +	int me = smp_processor_id(); + +	printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x \n", (unsigned int)me, +	       (unsigned int)nrcpu, (unsigned int)NR_CPUS, +	       (unsigned int)&(leon3_irqctrl_regs->mpstatus)); + +	leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, me); +	leon_enable_irq_cpu(LEON3_IRQ_TICKER, me); +	leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, me); + +	leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER); + +	leon_configure_cache_smp(); +	smp_setup_percpu_timer(); +	local_flush_cache_all(); + +} + +int __cpuinit leon_boot_one_cpu(int i) +{ + +	struct task_struct *p; +	int timeout; + +	/* Cook up an idler for this guy. */ +	p = fork_idle(i); + +	current_set[i] = task_thread_info(p); + +	/* See trampoline.S:leon_smp_cpu_startup for details... +	 * Initialize the contexts table +	 * Since the call to prom_startcpu() trashes the structure, +	 * we need to re-initialize it for each cpu +	 */ +	smp_penguin_ctable.which_io = 0; +	smp_penguin_ctable.phys_addr = (unsigned int)srmmu_ctx_table_phys; +	smp_penguin_ctable.reg_size = 0; + +	/* whirrr, whirrr, whirrrrrrrrr... */ +	printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i, +	       (unsigned int)&leon3_irqctrl_regs->mpstatus); +	local_flush_cache_all(); + +	LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpstatus), 1 << i); + +	/* wheee... it's going... */ +	for (timeout = 0; timeout < 10000; timeout++) { +		if (cpu_callin_map[i]) +			break; +		udelay(200); +	} +	printk(KERN_INFO "Started CPU %d \n", (unsigned int)i); + +	if (!(cpu_callin_map[i])) { +		printk(KERN_ERR "Processor %d is stuck.\n", i); +		return -ENODEV; +	} else { +		leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, i); +		leon_enable_irq_cpu(LEON3_IRQ_TICKER, i); +		leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, i); +	} + +	local_flush_cache_all(); +	return 0; +} + +void __init leon_smp_done(void) +{ + +	int i, first; +	int *prev; + +	/* setup cpu list for irq rotation */ +	first = 0; +	prev = &first; +	for (i = 0; i < NR_CPUS; i++) { +		if (cpu_online(i)) { +			*prev = i; +			prev = &cpu_data(i).next; +		} +	} +	*prev = first; +	local_flush_cache_all(); + +	/* Free unneeded trap tables */ +	if (!cpu_isset(1, cpu_present_map)) { +		ClearPageReserved(virt_to_page(trapbase_cpu1)); +		init_page_count(virt_to_page(trapbase_cpu1)); +		free_page((unsigned long)trapbase_cpu1); +		totalram_pages++; +		num_physpages++; +	} +	if (!cpu_isset(2, cpu_present_map)) { +		ClearPageReserved(virt_to_page(trapbase_cpu2)); +		init_page_count(virt_to_page(trapbase_cpu2)); +		free_page((unsigned long)trapbase_cpu2); +		totalram_pages++; +		num_physpages++; +	} +	if (!cpu_isset(3, cpu_present_map)) { +		ClearPageReserved(virt_to_page(trapbase_cpu3)); +		init_page_count(virt_to_page(trapbase_cpu3)); +		free_page((unsigned long)trapbase_cpu3); +		totalram_pages++; +		num_physpages++; +	} +	/* Ok, they are spinning and ready to go. */ +	smp_processors_ready = 1; + +} + +void leon_irq_rotate(int cpu) +{ +} + +static struct smp_funcall { +	smpfunc_t func; +	unsigned long arg1; +	unsigned long arg2; +	unsigned long arg3; +	unsigned long arg4; +	unsigned long arg5; +	unsigned long processors_in[NR_CPUS];	/* Set when ipi entered. */ +	unsigned long processors_out[NR_CPUS];	/* Set when ipi exited. */ +} ccall_info; + +static DEFINE_SPINLOCK(cross_call_lock); + +/* Cross calls must be serialized, at least currently. */ +static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, +			    unsigned long arg2, unsigned long arg3, +			    unsigned long arg4) +{ +	if (smp_processors_ready) { +		register int high = NR_CPUS - 1; +		unsigned long flags; + +		spin_lock_irqsave(&cross_call_lock, flags); + +		{ +			/* If you make changes here, make sure gcc generates proper code... */ +			register smpfunc_t f asm("i0") = func; +			register unsigned long a1 asm("i1") = arg1; +			register unsigned long a2 asm("i2") = arg2; +			register unsigned long a3 asm("i3") = arg3; +			register unsigned long a4 asm("i4") = arg4; +			register unsigned long a5 asm("i5") = 0; + +			__asm__ __volatile__("std %0, [%6]\n\t" +					     "std %2, [%6 + 8]\n\t" +					     "std %4, [%6 + 16]\n\t" : : +					     "r"(f), "r"(a1), "r"(a2), "r"(a3), +					     "r"(a4), "r"(a5), +					     "r"(&ccall_info.func)); +		} + +		/* Init receive/complete mapping, plus fire the IPI's off. */ +		{ +			register int i; + +			cpu_clear(smp_processor_id(), mask); +			cpus_and(mask, cpu_online_map, mask); +			for (i = 0; i <= high; i++) { +				if (cpu_isset(i, mask)) { +					ccall_info.processors_in[i] = 0; +					ccall_info.processors_out[i] = 0; +					set_cpu_int(i, LEON3_IRQ_CROSS_CALL); + +				} +			} +		} + +		{ +			register int i; + +			i = 0; +			do { +				if (!cpu_isset(i, mask)) +					continue; + +				while (!ccall_info.processors_in[i]) +					barrier(); +			} while (++i <= high); + +			i = 0; +			do { +				if (!cpu_isset(i, mask)) +					continue; + +				while (!ccall_info.processors_out[i]) +					barrier(); +			} while (++i <= high); +		} + +		spin_unlock_irqrestore(&cross_call_lock, flags); +	} +} + +/* Running cross calls. */ +void leon_cross_call_irq(void) +{ +	int i = smp_processor_id(); + +	ccall_info.processors_in[i] = 1; +	ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, +			ccall_info.arg4, ccall_info.arg5); +	ccall_info.processors_out[i] = 1; +} + +void leon_percpu_timer_interrupt(struct pt_regs *regs) +{ +	struct pt_regs *old_regs; +	int cpu = smp_processor_id(); + +	old_regs = set_irq_regs(regs); + +	leon_clear_profile_irq(cpu); + +	profile_tick(CPU_PROFILING); + +	if (!--prof_counter(cpu)) { +		int user = user_mode(regs); + +		irq_enter(); +		update_process_times(user); +		irq_exit(); + +		prof_counter(cpu) = prof_multiplier(cpu); +	} +	set_irq_regs(old_regs); +} + +static void __init smp_setup_percpu_timer(void) +{ +	int cpu = smp_processor_id(); + +	prof_counter(cpu) = prof_multiplier(cpu) = 1; +} + +void __init leon_blackbox_id(unsigned *addr) +{ +	int rd = *addr & 0x3e000000; +	int rs1 = rd >> 11; + +	/* patch places where ___b_hard_smp_processor_id appears */ +	addr[0] = 0x81444000 | rd;	/* rd %asr17, reg */ +	addr[1] = 0x8130201c | rd | rs1;	/* srl reg, 0x1c, reg */ +	addr[2] = 0x01000000;	/* nop */ +} + +void __init leon_blackbox_current(unsigned *addr) +{ +	int rd = *addr & 0x3e000000; +	int rs1 = rd >> 11; + +	/* patch LOAD_CURRENT macro where ___b_load_current appears */ +	addr[0] = 0x81444000 | rd;	/* rd %asr17, reg */ +	addr[2] = 0x8130201c | rd | rs1;	/* srl reg, 0x1c, reg */ +	addr[4] = 0x81282002 | rd | rs1;	/* sll reg, 0x2, reg */ + +} + +/* + * CPU idle callback function + * See .../arch/sparc/kernel/process.c + */ +void pmc_leon_idle(void) +{ +	__asm__ volatile ("mov %g0, %asr19"); +} + +void __init leon_init_smp(void) +{ +	/* Patch ipi15 trap table */ +	t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); + +	BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id); +	BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current); +	BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); +	BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id, +			BTFIXUPCALL_NORM); + +#ifndef PMC_NO_IDLE +	/* Assign power management IDLE handler */ +	pm_idle = pmc_leon_idle; +	printk(KERN_INFO "leon: power management initialized\n"); +#endif + +} + +#endif /* CONFIG_SPARC_LEON */ diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index f1be37a7b12..e1b0541feb1 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -112,7 +112,7 @@ static void free_msi(struct pci_pbm_info *pbm, int msi_num)  }  static struct irq_chip msi_irq = { -	.typename	= "PCI-MSI", +	.name		= "PCI-MSI",  	.mask		= mask_msi_irq,  	.unmask		= unmask_msi_irq,  	.enable		= unmask_msi_irq, diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 04db9274389..fa5936e1c3b 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -437,7 +437,7 @@ static const struct sparc_pmu niagara2_pmu = {  	.lower_shift	= 6,  	.event_mask	= 0xfff,  	.hv_bit		= 0x8, -	.irq_bit	= 0x03, +	.irq_bit	= 0x30,  	.upper_nop	= 0x220,  	.lower_nop	= 0x220,  }; diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 138910c6720..d80a65d9e89 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -79,6 +79,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len  	err = -ENODEV; +	mutex_lock(&of_set_property_mutex);  	write_lock(&devtree_lock);  	prevp = &dp->properties;  	while (*prevp) { @@ -88,9 +89,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len  			void *old_val = prop->value;  			int ret; -			mutex_lock(&of_set_property_mutex);  			ret = prom_setprop(dp->node, name, val, len); -			mutex_unlock(&of_set_property_mutex);  			err = -EINVAL;  			if (ret >= 0) { @@ -109,6 +108,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len  		prevp = &(*prevp)->next;  	}  	write_unlock(&devtree_lock); +	mutex_unlock(&of_set_property_mutex);  	/* XXX Upate procfs if necessary... */ diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 21180339cb0..a2a79e76344 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -46,6 +46,7 @@  #include <asm/setup.h>  #include <asm/mmu.h>  #include <asm/ns87303.h> +#include <asm/btext.h>  #ifdef CONFIG_IP_PNP  #include <net/ipconfig.h> @@ -286,7 +287,10 @@ void __init setup_arch(char **cmdline_p)  	parse_early_param();  	boot_flags_init(*cmdline_p); -	register_console(&prom_early_console); +#ifdef CONFIG_EARLYFB +	if (btext_find_display()) +#endif +		register_console(&prom_early_console);  	if (tlb_type == hypervisor)  		printk("ARCH: SUN4V\n"); diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 132d81fb261..91c10fb7085 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -32,6 +32,7 @@  #include <asm/cacheflush.h>  #include <asm/tlbflush.h>  #include <asm/cpudata.h> +#include <asm/leon.h>  #include "irq.h" @@ -96,6 +97,9 @@ void __init smp_cpus_done(unsigned int max_cpus)  	case sun4d:  		smp4d_smp_done();  		break; +	case sparc_leon: +		leon_smp_done(); +		break;  	case sun4e:  		printk("SUN4E\n");  		BUG(); @@ -306,6 +310,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus)  	case sun4d:  		smp4d_boot_cpus();  		break; +	case sparc_leon: +		leon_boot_cpus(); +		break;  	case sun4e:  		printk("SUN4E\n");  		BUG(); @@ -376,6 +383,9 @@ int __cpuinit __cpu_up(unsigned int cpu)  	case sun4d:  		ret = smp4d_boot_one_cpu(cpu);  		break; +	case sparc_leon: +		ret = leon_boot_one_cpu(cpu); +		break;  	case sun4e:  		printk("SUN4E\n");  		BUG(); diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 04e28b2671c..00abe87e5b5 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -26,11 +26,6 @@  #include <linux/nfs_fs.h>  #include <linux/quota.h>  #include <linux/module.h> -#include <linux/sunrpc/svc.h> -#include <linux/nfsd/nfsd.h> -#include <linux/nfsd/cache.h> -#include <linux/nfsd/xdr.h> -#include <linux/nfsd/syscall.h>  #include <linux/poll.h>  #include <linux/personality.h>  #include <linux/stat.h> @@ -591,63 +586,6 @@ out:  	return ret;         } -struct __sysctl_args32 { -	u32 name; -	int nlen; -	u32 oldval; -	u32 oldlenp; -	u32 newval; -	u32 newlen; -	u32 __unused[4]; -}; - -asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) -{ -#ifndef CONFIG_SYSCTL_SYSCALL -	return -ENOSYS; -#else -	struct __sysctl_args32 tmp; -	int error; -	size_t oldlen, __user *oldlenp = NULL; -	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL; - -	if (copy_from_user(&tmp, args, sizeof(tmp))) -		return -EFAULT; - -	if (tmp.oldval && tmp.oldlenp) { -		/* Duh, this is ugly and might not work if sysctl_args -		   is in read-only memory, but do_sysctl does indirectly -		   a lot of uaccess in both directions and we'd have to -		   basically copy the whole sysctl.c here, and -		   glibc's __sysctl uses rw memory for the structure -		   anyway.  */ -		if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) || -		    put_user(oldlen, (size_t __user *)addr)) -			return -EFAULT; -		oldlenp = (size_t __user *)addr; -	} - -	lock_kernel(); -	error = do_sysctl((int __user *)(unsigned long) tmp.name, -			  tmp.nlen, -			  (void __user *)(unsigned long) tmp.oldval, -			  oldlenp, -			  (void __user *)(unsigned long) tmp.newval, -			  tmp.newlen); -	unlock_kernel(); -	if (oldlenp) { -		if (!error) { -			if (get_user(oldlen, (size_t __user *)addr) || -			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp)) -				error = -EFAULT; -		} -		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) -			error = -EFAULT; -	} -	return error; -#endif -} -  long sys32_lookup_dcookie(unsigned long cookie_high,  			  unsigned long cookie_low,  			  char __user *buf, size_t len) diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 0f1658d3749..ceb1530f8aa 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -82,5 +82,5 @@ sys_call_table:  /*310*/	.long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate  /*315*/	.long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1  /*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv -/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open +/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 009825f6e73..cc8e7862e95 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -68,7 +68,7 @@ sys_call_table32:  	.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall  /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler  	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep -/*250*/	.word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl +/*250*/	.word sys32_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl  	.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep  /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun  	.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy @@ -83,7 +83,7 @@ sys_call_table32:  /*310*/	.word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate  	.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1  /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv -	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open +	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg  #endif /* CONFIG_COMPAT */ @@ -158,4 +158,4 @@ sys_call_table:  /*310*/	.word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate  	.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1  /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv -	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open +	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 614ac7b4a9d..5b2f595fe65 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -210,9 +210,6 @@ static void __init sbus_time_init(void)  	btfixup();  	sparc_init_timers(timer_interrupt); -	 -	/* Now that OBP ticker has been silenced, it is safe to enable IRQ. */ -	local_irq_enable();  }  void __init time_init(void) diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 5e235c52d66..691f484e03b 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -15,7 +15,7 @@  #include <asm/contregs.h>  #include <asm/thread_info.h> -	.globl sun4m_cpu_startup, __smp4m_processor_id +	.globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id  	.globl sun4d_cpu_startup, __smp4d_processor_id  	__CPUINIT @@ -106,6 +106,12 @@ __smp4d_processor_id:  	retl  	 mov	%g1, %o7 +__leon_processor_id: +	rd     %asr17,%g2 +        srl    %g2,28,%g2 +	retl +	 mov	%g1, %o7 +  /* CPUID in bootbus can be found at PA 0xff0140000 */  #define SUN4D_BOOTBUS_CPUID	0xf0140000 @@ -160,3 +166,64 @@ sun4d_cpu_startup:  	 nop  	b,a	smp_do_cpu_idle + +#ifdef CONFIG_SPARC_LEON + +	__CPUINIT +	.align	4 +        .global leon_smp_cpu_startup, smp_penguin_ctable + +leon_smp_cpu_startup: + +        set smp_penguin_ctable,%g1 +        ld [%g1+4],%g1 +        srl %g1,4,%g1 +        set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ +	sta %g1, [%g5] ASI_M_MMUREGS + +	/* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ +	set	(PSR_PIL | PSR_S | PSR_PS), %g1 +	wr	%g1, 0x0, %psr		! traps off though +	WRITE_PAUSE + +	/* Our %wim is one behind CWP */ +	mov	2, %g1 +	wr	%g1, 0x0, %wim +	WRITE_PAUSE + +	/* Set tbr - we use just one trap table. */ +	set	trapbase, %g1 +	wr	%g1, 0x0, %tbr +	WRITE_PAUSE + +	/* Get our CPU id */ +        rd     %asr17,%g3 + +	/* Give ourselves a stack and curptr. */ +	set	current_set, %g5 +	srl	%g3, 28, %g4 +	sll	%g4, 2, %g4 +	ld	[%g5 + %g4], %g6 + +	sethi	%hi(THREAD_SIZE - STACKFRAME_SZ), %sp +	or	%sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp +	add	%g6, %sp, %sp + +	/* Turn on traps (PSR_ET). */ +	rd	%psr, %g1 +	wr	%g1, PSR_ET, %psr	! traps on +	WRITE_PAUSE + +	/* Init our caches, etc. */ +	set	poke_srmmu, %g5 +	ld	[%g5], %g5 +	call	%g5 +	 nop + +	/* Start this processor. */ +	call	leon_callin +	 nop + +	b,a	smp_do_cpu_idle + +#endif diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index b956fd71c13..d231cbd5c52 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c @@ -617,7 +617,7 @@ static void pmul(struct pt_regs *regs, unsigned int insn, unsigned int opf)  		rs2 = fps_regval(f, RS2(insn));  		rd_val = 0; -		src2 = (rs2 >> (opf == FMUL8x16AU_OPF) ? 16 : 0); +		src2 = rs2 >> (opf == FMUL8x16AU_OPF ? 16 : 0);  		for (byte = 0; byte < 4; byte++) {  			u16 src1 = (rs1 >> (byte * 8)) & 0x00ff;  			u32 prod = src1 * src2;  |