From da3854fc9f80c0240ba7cadd2aebf036683ff21b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 24 Jun 2008 22:15:58 +0100 Subject: DM9000: Fixup blackfin after removing 2 resource usage The dm9000 driver accepts either 2 or 3 resources to describe the platform devices. The 2 resources case abuses the ioresource mechanism by passing ioremap()ed memory through the platform device resources. This patch removes converts boards that were using it to the 3 resources scheme. CC: Bryan Wu Signed-off-by: Ben Dooks Signed-off-by: Laurent Pinchart Signed-off-by: Jeff Garzik --- arch/blackfin/mach-bf527/boards/ezkit.c | 7 ++++++- arch/blackfin/mach-bf533/boards/H8606.c | 7 ++++++- arch/blackfin/mach-bf537/boards/generic_board.c | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 5958eecefcf..689b69c98ee 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -323,10 +323,15 @@ static struct platform_device smc91x_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x203FB800, - .end = 0x203FB800 + 8, + .end = 0x203FB800 + 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = 0x203FB800 + 4, + .end = 0x203FB800 + 5, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_PF9, .end = IRQ_PF9, .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 7cc4864f6aa..4103a97c1a7 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -65,10 +65,15 @@ static struct platform_device rtc_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x20300000, - .end = 0x20300000 + 8, + .end = 0x20300000 + 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = 0x20300000 + 4, + .end = 0x20300000 + 5, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_PF10, .end = IRQ_PF10, .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 7d250828dad..01b63e2ec18 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -166,10 +166,15 @@ static struct platform_device smc91x_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x203FB800, - .end = 0x203FB800 + 8, + .end = 0x203FB800 + 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = 0x203FB800 + 4, + .end = 0x203FB800 + 5, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_PF9, .end = IRQ_PF9, .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), -- cgit v1.2.3 From 3aa30df3d0d78f568cff9d6a98ae01ae55494f10 Mon Sep 17 00:00:00 2001 From: Hinko Kocevar Date: Fri, 6 Jun 2008 14:12:26 +0200 Subject: cris: compile fixes for 2.6.26-rc5 Add dummy ops for serial debug port. Add setting of c_ispeed/c_ospeed as suggested by Alan Cox. Signed-off-by: Hinko Kocevar Acked-by: Alan Cox Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/kernel/debugport.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 04d5eee2c90..162730eb887 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c @@ -426,12 +426,18 @@ static int dummy_write(struct tty_struct * tty, return count; } -static int -dummy_write_room(struct tty_struct *tty) +static int dummy_write_room(struct tty_struct *tty) { return 8192; } +static const struct tty_operations dummy_ops = { + .open = dummy_open, + .close = dummy_close, + .write = dummy_write, + .write_room = dummy_write_room, +}; + void __init init_dummy_console(void) { @@ -444,14 +450,14 @@ init_dummy_console(void) dummy_driver.type = TTY_DRIVER_TYPE_SERIAL; dummy_driver.subtype = SERIAL_TYPE_NORMAL; dummy_driver.init_termios = tty_std_termios; + /* Normally B9600 default... */ dummy_driver.init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ + B115200 | CS8 | CREAD | HUPCL | CLOCAL; dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + dummy_driver.init_termios.c_ispeed = 115200; + dummy_driver.init_termios.c_ospeed = 115200; - dummy_driver.open = dummy_open; - dummy_driver.close = dummy_close; - dummy_driver.write = dummy_write; - dummy_driver.write_room = dummy_write_room; + dummy_driver.ops = &dummy_ops; if (tty_register_driver(&dummy_driver)) panic("Couldn't register dummy serial driver\n"); } -- cgit v1.2.3 From 9be48a94b8ae8c944dc918ad65f2f27e9df3ed00 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 29 Jun 2008 22:50:56 +0200 Subject: It looks at least odd to apply spin_unlock to a mutex. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @def@ declarer DEFINE_MUTEX; identifier m; @@ DEFINE_MUTEX(m); @@ identifier def.m; @@ ( - spin_lock(&m) + mutex_lock(&m) | - spin_unlock(&m) + mutex_unlock(&m) ) // Signed-off-by: Julia Lawall Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/drivers/pcf8563.c | 2 +- arch/cris/arch-v32/drivers/pcf8563.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index 52103d16dc6..8769dc91407 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c @@ -233,7 +233,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { - spin_unlock(&rtc_lock); + mutex_unlock(&rtc_lock); return -EFAULT; } diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c index 53db3870ba0..f263ab57122 100644 --- a/arch/cris/arch-v32/drivers/pcf8563.c +++ b/arch/cris/arch-v32/drivers/pcf8563.c @@ -229,7 +229,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { - spin_unlock(&rtc_lock); + mutex_unlock(&rtc_lock); return -EFAULT; } -- cgit v1.2.3 From bdb144b67a7660ce5d044ae9a2fd1a8030f12523 Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Sun, 29 Jun 2008 23:15:19 +0200 Subject: [CRIS] Build fixes for compressed and rescue images for v10 and v32: - Use the normal cross gcc instead of using an elf specific cris toolchain. This removes the dependency of this second toolchain. - Use the normal cross objcopy instead of overriding it to use elf-toolchain. This allows compiling using "CROSS_COMPILE=$CRIS_GCC/cris-axis-linux-gnu-" instead of just "CROSS_COMPILE=$CRIS_GCC/cris-axis-linux-gnu/bin/" - Remove redundant rules for compiling, the implicit rules are sufficient. - Convert the arch/cris/arch-v10/boot/compressed/head.S to format accepted by the cris-axis-linux-gnu-gcc (registers must be prefixed with '$', remove explicit underscore on exported symbols) - Remove a number of unused (and duplicated) prototypes from arch/cris/arch-v10/boot/compressed/misc.c. - Correct memcpy and memset return values (actually return them!) Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/boot/Makefile | 1 - arch/cris/arch-v10/boot/compressed/Makefile | 12 +-- arch/cris/arch-v10/boot/compressed/decompress.ld | 3 +- arch/cris/arch-v10/boot/compressed/head.S | 98 ++++++++++++------------ arch/cris/arch-v10/boot/compressed/misc.c | 23 +++--- arch/cris/arch-v10/boot/rescue/Makefile | 7 +- arch/cris/arch-v32/boot/Makefile | 1 - arch/cris/arch-v32/boot/compressed/Makefile | 4 - arch/cris/arch-v32/boot/rescue/Makefile | 1 - 9 files changed, 65 insertions(+), 85 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile index 20c83a53caf..21720301443 100644 --- a/arch/cris/arch-v10/boot/Makefile +++ b/arch/cris/arch-v10/boot/Makefile @@ -2,7 +2,6 @@ # arch/cris/arch-v10/boot/Makefile # -OBJCOPY = objcopy-cris OBJCOPYFLAGS = -O binary --remove-section=.bss subdir- := compressed rescue diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile index 4a031cb27eb..9ec5f87d515 100644 --- a/arch/cris/arch-v10/boot/compressed/Makefile +++ b/arch/cris/arch-v10/boot/compressed/Makefile @@ -2,12 +2,10 @@ # arch/cris/arch-v10/boot/compressed/Makefile # -CC = gcc-cris -melf $(LINUXINCLUDE) -ccflags-y += -O2 -LD = ld-cris +asflags-y += $(LINUXINCLUDE) +ccflags-y += -O2 $(LINUXINCLUDE) ldflags-y += -T $(obj)/decompress.ld OBJECTS = $(obj)/head.o $(obj)/misc.o -OBJCOPY = objcopy-cris OBJCOPYFLAGS = -O binary --remove-section=.bss quiet_cmd_image = BUILD $@ @@ -21,12 +19,6 @@ $(obj)/decompress.o: $(OBJECTS) FORCE $(obj)/decompress.bin: $(obj)/decompress.o FORCE $(call if_changed,objcopy) -$(obj)/head.o: $(obj)/head.S .config - @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@ - -$(obj)/misc.o: $(obj)/misc.c .config - @$(CC) -D__KERNEL__ -c $< -o $@ - $(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE $(call if_changed,image) diff --git a/arch/cris/arch-v10/boot/compressed/decompress.ld b/arch/cris/arch-v10/boot/compressed/decompress.ld index 0b0a14fe617..e80f4594d54 100644 --- a/arch/cris/arch-v10/boot/compressed/decompress.ld +++ b/arch/cris/arch-v10/boot/compressed/decompress.ld @@ -1,4 +1,5 @@ -OUTPUT_FORMAT(elf32-us-cris) +/* OUTPUT_FORMAT(elf32-us-cris) */ +OUTPUT_FORMAT(elf32-cris) MEMORY { diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/arch-v10/boot/compressed/head.S index 610bdb23755..981fbae8495 100644 --- a/arch/cris/arch-v10/boot/compressed/head.S +++ b/arch/cris/arch-v10/boot/compressed/head.S @@ -15,77 +15,77 @@ #define COMMAND_LINE_MAGIC 0x87109563 ;; Exported symbols - - .globl _input_data - + .globl input_data + + .text nop di ;; We need to initialze DRAM registers before we start using the DRAM - - cmp.d RAM_INIT_MAGIC, r8 ; Already initialized? + + cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? beq dram_init_finished nop - + #include "../../lib/dram_init.S" - -dram_init_finished: - + +dram_init_finished: + ;; Initiate the PA and PB ports - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0 - move.b r0, [R_PORT_PA_DATA] + move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 + move.b $r0, [R_PORT_PA_DATA] - move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0 - move.b r0, [R_PORT_PA_DIR] + move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 + move.b $r0, [R_PORT_PA_DIR] - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0 - move.b r0, [R_PORT_PB_DATA] + move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 + move.b $r0, [R_PORT_PB_DATA] - move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0 - move.b r0, [R_PORT_PB_DIR] + move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 + move.b $r0, [R_PORT_PB_DIR] ;; Setup the stack to a suitably high address. ;; We assume 8 MB is the minimum DRAM in an eLinux ;; product and put the sp at the top for now. - move.d 0x40800000, sp + move.d 0x40800000, $sp ;; Figure out where the compressed piggyback image is ;; in the flash (since we wont try to copy it to DRAM ;; before unpacking). It is at _edata, but in flash. ;; Use (_edata - basse) as offset to the current PC. - -basse: move.d pc, r5 - and.d 0x7fffffff, r5 ; strip any non-cache bit - subq 2, r5 ; compensate for the move.d pc instr - move.d r5, r0 ; save for later - flash address of 'basse' - add.d _edata, r5 - sub.d basse, r5 ; r5 = flash address of '_edata' - + +basse: move.d $pc, $r5 + and.d 0x7fffffff, $r5 ; strip any non-cache bit + subq 2, $r5 ; compensate for the move.d $pc instr + move.d $r5, $r0 ; save for later - flash address of 'basse' + add.d _edata, $r5 + sub.d basse, $r5 ; $r5 = flash address of '_edata' + ;; Copy text+data to DRAM - - move.d basse, r1 ; destination - move.d _edata, r2 ; end destination -1: move.w [r0+], r3 - move.w r3, [r1+] - cmp.d r2, r1 + + move.d basse, $r1 ; destination + move.d _edata, $r2 ; end destination +1: move.w [$r0+], $r3 + move.w $r3, [$r1+] + cmp.d $r2, $r1 bcs 1b nop - move.d r5, [_input_data] ; for the decompressor + move.d $r5, [input_data] ; for the decompressor ;; Clear the decompressors BSS (between _edata and _end) - - moveq 0, r0 - move.d _edata, r1 - move.d _end, r2 -1: move.w r0, [r1+] - cmp.d r2, r1 + + moveq 0, $r0 + move.d _edata, $r1 + move.d _end, $r2 +1: move.w $r0, [$r1+] + cmp.d $r2, $r1 bcs 1b nop @@ -94,16 +94,16 @@ basse: move.d pc, r5 move.d $r10, [$r12] move.d _cmd_line_addr, $r12 move.d $r11, [$r12] - - ;; Do the decompression and save compressed size in _inptr - jsr _decompress_kernel - - ;; Put start address of root partition in r9 so the kernel can use it + ;; Do the decompression and save compressed size in inptr + + jsr decompress_kernel + + ;; Put start address of root partition in $r9 so the kernel can use it ;; when mounting from flash - move.d [_input_data], r9 ; flash address of compressed kernel - add.d [_inptr], r9 ; size of compressed kernel + move.d [input_data], $r9 ; flash address of compressed kernel + add.d [inptr], $r9 ; size of compressed kernel ;; Restore command line magic and address. move.d _cmd_line_magic, $r10 @@ -112,12 +112,12 @@ basse: move.d pc, r5 move.d [$r11], $r11 ;; Enter the decompressed kernel - move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized + move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized jump 0x40004000 ; kernel is linked to this address - + .data -_input_data: +input_data: .dword 0 ; used by the decompressor _cmd_line_magic: .dword 0 diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c index 9a43ab19391..59961f20fab 100644 --- a/arch/cris/arch-v10/boot/compressed/misc.c +++ b/arch/cris/arch-v10/boot/compressed/misc.c @@ -30,8 +30,7 @@ #define STATIC static void* memset(void* s, int c, size_t n); -void* memcpy(void* __dest, __const void* __src, - size_t __n); +void* memcpy(void* __dest, __const void* __src, size_t __n); #define memzero(s, n) memset ((s), 0, (n)) @@ -81,11 +80,8 @@ static unsigned outcnt = 0; /* bytes in output buffer */ # define Tracecv(c,x) #endif -static int fill_inbuf(void); static void flush_window(void); static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); extern char *input_data; /* lives in head.S */ @@ -95,7 +91,6 @@ static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); -static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); @@ -103,8 +98,8 @@ static void puts(const char *); /* the "heap" is put directly after the BSS ends, at end */ -extern int end; -static long free_mem_ptr = (long)&end; +extern int _end; +static long free_mem_ptr = (long)&_end; #include "../../../../../lib/inflate.c" @@ -170,6 +165,8 @@ memset(void* s, int c, size_t n) char *ss = (char*)s; for (i=0;i Date: Mon, 30 Jun 2008 20:38:06 +0200 Subject: [CRIS] Correct image makefiles to allow using a separate OBJ-directory. Make compile succeed when building with O= (srctree != objtree). Signed-off-by: Hinko Kocevar Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/boot/compressed/Makefile | 2 +- arch/cris/arch-v10/boot/rescue/Makefile | 2 +- arch/cris/arch-v32/boot/compressed/Makefile | 2 +- arch/cris/arch-v32/boot/rescue/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile index 9ec5f87d515..08d943ce4be 100644 --- a/arch/cris/arch-v10/boot/compressed/Makefile +++ b/arch/cris/arch-v10/boot/compressed/Makefile @@ -4,7 +4,7 @@ asflags-y += $(LINUXINCLUDE) ccflags-y += -O2 $(LINUXINCLUDE) -ldflags-y += -T $(obj)/decompress.ld +ldflags-y += -T $(srctree)/$(obj)/decompress.ld OBJECTS = $(obj)/head.o $(obj)/misc.o OBJCOPYFLAGS = -O binary --remove-section=.bss diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile index bea8b9c2a7c..07688da9270 100644 --- a/arch/cris/arch-v10/boot/rescue/Makefile +++ b/arch/cris/arch-v10/boot/rescue/Makefile @@ -4,7 +4,7 @@ ccflags-y += -O2 $(LINUXINCLUDE) asflags-y += $(LINUXINCLUDE) -ldflags-y += -T $(obj)/rescue.ld +ldflags-y += -T $(srctree)/$(obj)/rescue.ld OBJCOPYFLAGS = -O binary --remove-section=.bss obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o OBJECT := $(obj)/head.o diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile index 9138938eec3..d6335f26083 100644 --- a/arch/cris/arch-v32/boot/compressed/Makefile +++ b/arch/cris/arch-v32/boot/compressed/Makefile @@ -4,7 +4,7 @@ asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch -ldflags-y += -T $(obj)/decompress.ld +ldflags-y += -T $(srctree)/$(obj)/decompress.ld OBJECTS = $(obj)/head.o $(obj)/misc.o OBJCOPYFLAGS = -O binary --remove-section=.bss diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile index b548bde185d..44ae0ad61f9 100644 --- a/arch/cris/arch-v32/boot/rescue/Makefile +++ b/arch/cris/arch-v32/boot/rescue/Makefile @@ -7,7 +7,7 @@ ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \ -I $(srctree)/include/asm/arch asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch LD = gcc-cris -mlinux -march=v32 -nostdlib -ldflags-y += -T $(obj)/rescue.ld +ldflags-y += -T $(srctree)/$(obj)/rescue.ld LDPOSTFLAGS = -lgcc OBJCOPYFLAGS = -O binary --remove-section=.bss obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o -- cgit v1.2.3 From bd451d5ed206cda4ed0e03fac4e5dece2fd7767f Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 30 Jun 2008 23:22:51 +0200 Subject: [CRISv10] Correct whitespace damage. The previous patch was whitespace damaged, correct to indent using tabs. Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/kernel/debugport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 162730eb887..3dc6e91ba39 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c @@ -432,10 +432,10 @@ static int dummy_write_room(struct tty_struct *tty) } static const struct tty_operations dummy_ops = { - .open = dummy_open, - .close = dummy_close, - .write = dummy_write, - .write_room = dummy_write_room, + .open = dummy_open, + .close = dummy_close, + .write = dummy_write, + .write_room = dummy_write_room, }; void __init -- cgit v1.2.3 From f3c4b53d5ec6bd2ae0f284c1e6371bff545f0f80 Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 30 Jun 2008 21:20:23 +0200 Subject: [CRISv10] Clean up compressed/misc.c Many minor fixes in whitespace and formatting. Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/boot/compressed/misc.c | 127 ++++++++++++++++-------------- 1 file changed, 70 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c index 59961f20fab..18e13bce140 100644 --- a/arch/cris/arch-v10/boot/compressed/misc.c +++ b/arch/cris/arch-v10/boot/compressed/misc.c @@ -29,11 +29,10 @@ #define OF(args) args #define STATIC static -void* memset(void* s, int c, size_t n); -void* memcpy(void* __dest, __const void* __src, size_t __n); - -#define memzero(s, n) memset ((s), 0, (n)) +void *memset(void *s, int c, size_t n); +void *memcpy(void *__dest, __const void *__src, size_t __n); +#define memzero(s, n) memset((s), 0, (n)) typedef unsigned char uch; typedef unsigned short ush; @@ -61,23 +60,38 @@ static unsigned outcnt = 0; /* bytes in output buffer */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ -#define get_byte() inbuf[inptr++] - +#define get_byte() (inbuf[inptr++]) + /* Diagnostic functions */ #ifdef DEBUG -# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Assert(cond, msg) do { \ + if (!(cond)) \ + error(msg); \ + } while (0) # define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +# define Tracev(x) do { \ + if (verbose) \ + fprintf x; \ + } while (0) +# define Tracevv(x) do { \ + if (verbose > 1) \ + fprintf x; \ + } while (0) +# define Tracec(c, x) do { \ + if (verbose && (c)) \ + fprintf x; \ + } while (0) +# define Tracecv(c, x) do { \ + if (verbose > 1 && (c)) \ + fprintf x; \ + } while (0) #else -# define Assert(cond,msg) +# define Assert(cond, msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) +# define Tracec(c, x) +# define Tracecv(c, x) #endif static void flush_window(void); @@ -88,26 +102,27 @@ extern char *input_data; /* lives in head.S */ static long bytes_out = 0; static uch *output_data; static unsigned long output_ptr = 0; - + static void *malloc(int size); static void free(void *where); static void gzip_mark(void **); static void gzip_release(void **); - + static void puts(const char *); /* the "heap" is put directly after the BSS ends, at end */ - + extern int _end; static long free_mem_ptr = (long)&_end; - + #include "../../../../../lib/inflate.c" static void *malloc(int size) { void *p; - if (size <0) error("Malloc error"); + if (size < 0) + error("Malloc error"); free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ @@ -137,48 +152,47 @@ static void puts(const char *s) { #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL - while(*s) { + while (*s) { #ifdef CONFIG_ETRAX_DEBUG_PORT0 - while(!(*R_SERIAL0_STATUS & (1 << 5))) ; + while (!(*R_SERIAL0_STATUS & (1 << 5))) ; *R_SERIAL0_TR_DATA = *s++; #endif #ifdef CONFIG_ETRAX_DEBUG_PORT1 - while(!(*R_SERIAL1_STATUS & (1 << 5))) ; + while (!(*R_SERIAL1_STATUS & (1 << 5))) ; *R_SERIAL1_TR_DATA = *s++; #endif #ifdef CONFIG_ETRAX_DEBUG_PORT2 - while(!(*R_SERIAL2_STATUS & (1 << 5))) ; + while (!(*R_SERIAL2_STATUS & (1 << 5))) ; *R_SERIAL2_TR_DATA = *s++; #endif #ifdef CONFIG_ETRAX_DEBUG_PORT3 - while(!(*R_SERIAL3_STATUS & (1 << 5))) ; + while (!(*R_SERIAL3_STATUS & (1 << 5))) ; *R_SERIAL3_TR_DATA = *s++; #endif } #endif } -void* -memset(void* s, int c, size_t n) +void *memset(void *s, int c, size_t n) { int i; - char *ss = (char*)s; + char *ss = (char *)s; - for (i=0;i> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out = *in; + out++; + in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; } -static void -error(char *x) +static void error(char *x) { puts("\n\n"); puts(x); puts("\n\n -- System halted\n"); - while(1); /* Halt */ + while (1); /* Halt */ } void setup_normal_output_buffer(void) @@ -223,7 +237,7 @@ void setup_normal_output_buffer(void) void decompress_kernel(void) { char revision; - + /* input_data is set in head.S */ inbuf = input_data; @@ -255,10 +269,9 @@ void decompress_kernel(void) makecrc(); __asm__ volatile ("move $vr,%0" : "=rm" (revision)); - if (revision < 10) - { + if (revision < 10) { puts("You need an ETRAX 100LX to run linux 2.6\n"); - while(1); + while (1); } puts("Uncompressing Linux...\n"); -- cgit v1.2.3 From 8b2cf73cc11cf29a21c51c453a3205f23d888915 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 27 Apr 2008 12:14:13 -0700 Subject: KVM: add statics were possible, function definition in lapic.h Noticed by sparse: arch/x86/kvm/vmx.c:1583:6: warning: symbol 'vmx_disable_intercept_for_msr' was not declared. Should it be static? arch/x86/kvm/x86.c:3406:5: warning: symbol 'kvm_task_switch_16' was not declared. Should it be static? arch/x86/kvm/x86.c:3429:5: warning: symbol 'kvm_task_switch_32' was not declared. Should it be static? arch/x86/kvm/mmu.c:1968:6: warning: symbol 'kvm_mmu_remove_one_alloc_mmu_page' was not declared. Should it be static? arch/x86/kvm/mmu.c:2014:6: warning: symbol 'mmu_destroy_caches' was not declared. Should it be static? arch/x86/kvm/lapic.c:862:5: warning: symbol 'kvm_lapic_get_base' was not declared. Should it be static? arch/x86/kvm/i8254.c:94:5: warning: symbol 'pit_get_gate' was not declared. Should it be static? arch/x86/kvm/i8254.c:196:5: warning: symbol '__pit_timer_fn' was not declared. Should it be static? arch/x86/kvm/i8254.c:561:6: warning: symbol '__inject_pit_timer_intr' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Avi Kivity --- arch/x86/kvm/i8254.c | 6 +++--- arch/x86/kvm/lapic.h | 1 + arch/x86/kvm/mmu.c | 2 +- arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 3829aa7b663..735ec9a0b36 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -91,7 +91,7 @@ static void pit_set_gate(struct kvm *kvm, int channel, u32 val) c->gate = val; } -int pit_get_gate(struct kvm *kvm, int channel) +static int pit_get_gate(struct kvm *kvm, int channel) { WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock)); @@ -193,7 +193,7 @@ static void pit_latch_status(struct kvm *kvm, int channel) } } -int __pit_timer_fn(struct kvm_kpit_state *ps) +static int __pit_timer_fn(struct kvm_kpit_state *ps) { struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0]; struct kvm_kpit_timer *pt = &ps->pit_timer; @@ -575,7 +575,7 @@ void kvm_free_pit(struct kvm *kvm) } } -void __inject_pit_timer_intr(struct kvm *kvm) +static void __inject_pit_timer_intr(struct kvm *kvm) { mutex_lock(&kvm->lock); kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1); diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 676c396c9ce..81858881287 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -31,6 +31,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu); u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); +u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 7e7c3969f7a..8e449dbcc59 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1948,7 +1948,7 @@ void kvm_mmu_zap_all(struct kvm *kvm) kvm_flush_remote_tlbs(kvm); } -void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm) +static void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm) { struct kvm_mmu_page *page; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 10ce6ee4c49..39739305980 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1821,7 +1821,7 @@ static void allocate_vpid(struct vcpu_vmx *vmx) spin_unlock(&vmx_vpid_lock); } -void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr) +static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr) { void *va; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0faa2546b1c..45dc2b6a9c8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3449,7 +3449,7 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu, return 0; } -int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, +static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, struct desc_struct *cseg_desc, struct desc_struct *nseg_desc) { @@ -3472,7 +3472,7 @@ out: return ret; } -int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, +static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, struct desc_struct *cseg_desc, struct desc_struct *nseg_desc) { -- cgit v1.2.3 From c7bf23babc959b186335d2640959a1b8633588de Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:55:59 +0200 Subject: KVM: VMX: move APIC_ACCESS trace entry to generic code This patch moves the trace entry for APIC accesses from the VMX code to the generic lapic code. This way APIC accesses from SVM will also be traced. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/lapic.c | 4 ++++ arch/x86/kvm/vmx.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ebc03f5ae16..f9201fbc61d 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -572,6 +572,8 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) { u32 val = 0; + KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); + if (offset >= LAPIC_MMIO_LENGTH) return 0; @@ -695,6 +697,8 @@ static void apic_mmio_write(struct kvm_io_device *this, offset &= 0xff0; + KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); + switch (offset) { case APIC_ID: /* Local APIC ID */ apic_set_reg(apic, APIC_ID, val); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 39739305980..8c951d3eab3 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2554,8 +2554,6 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) exit_qualification = vmcs_read64(EXIT_QUALIFICATION); offset = exit_qualification & 0xffful; - KVMTRACE_1D(APIC_ACCESS, vcpu, (u32)offset, handler); - er = emulate_instruction(vcpu, kvm_run, 0, 0, 0); if (er != EMULATE_DONE) { -- cgit v1.2.3 From c47f098d69ed2bd7343e54095ff4aa2533253bee Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:56:00 +0200 Subject: KVM: SVM: implement dedicated NMI exit handler With an exit handler for NMI intercepts its possible to account them using kvmtrace. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 6b0d5fa5bab..8a2118b09fd 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1081,6 +1081,11 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port); } +static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + return 1; +} + static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { return 1; @@ -1365,7 +1370,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, [SVM_EXIT_INTR] = nop_on_interception, - [SVM_EXIT_NMI] = nop_on_interception, + [SVM_EXIT_NMI] = nmi_interception, [SVM_EXIT_SMI] = nop_on_interception, [SVM_EXIT_INIT] = nop_on_interception, [SVM_EXIT_VINTR] = interrupt_window_interception, -- cgit v1.2.3 From a069805579a390f0fa91694f6963bcc4b2cecc6b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:56:01 +0200 Subject: KVM: SVM: implement dedicated INTR exit handler With an exit handler for INTR intercepts its possible to account them using kvmtrace. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8a2118b09fd..0eac1a5060a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1086,6 +1086,12 @@ static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) return 1; } +static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + ++svm->vcpu.stat.irq_exits; + return 1; +} + static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { return 1; @@ -1369,7 +1375,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, - [SVM_EXIT_INTR] = nop_on_interception, + [SVM_EXIT_INTR] = intr_interception, [SVM_EXIT_NMI] = nmi_interception, [SVM_EXIT_SMI] = nop_on_interception, [SVM_EXIT_INIT] = nop_on_interception, -- cgit v1.2.3 From 54e445ca8411ec892f986d9f8c11b8c1806ecde4 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:56:02 +0200 Subject: KVM: add missing kvmtrace bits This patch adds some kvmtrace bits to the generic x86 code where it is instrumented from SVM. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 45dc2b6a9c8..59084a3981c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2020,6 +2020,7 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) int emulate_clts(struct kvm_vcpu *vcpu) { + KVMTRACE_0D(CLTS, vcpu, handler); kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS); return X86EMUL_CONTINUE; } @@ -2600,27 +2601,41 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) { + unsigned long value; + kvm_x86_ops->decache_cr4_guest_bits(vcpu); switch (cr) { case 0: - return vcpu->arch.cr0; + value = vcpu->arch.cr0; + break; case 2: - return vcpu->arch.cr2; + value = vcpu->arch.cr2; + break; case 3: - return vcpu->arch.cr3; + value = vcpu->arch.cr3; + break; case 4: - return vcpu->arch.cr4; + value = vcpu->arch.cr4; + break; case 8: - return kvm_get_cr8(vcpu); + value = kvm_get_cr8(vcpu); + break; default: vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); return 0; } + KVMTRACE_3D(CR_READ, vcpu, (u32)cr, (u32)value, + (u32)((u64)value >> 32), handler); + + return value; } void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, unsigned long *rflags) { + KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)val, + (u32)((u64)val >> 32), handler); + switch (cr) { case 0: kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val)); -- cgit v1.2.3 From af9ca2d703f4cefbf6441bfe127c4191092ad394 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:56:03 +0200 Subject: KVM: SVM: add missing kvmtrace markers This patch adds the missing kvmtrace markers to the svm module of kvm. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 0eac1a5060a..8953292acfd 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -949,7 +949,9 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data) static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr) { - return to_svm(vcpu)->db_regs[dr]; + unsigned long val = to_svm(vcpu)->db_regs[dr]; + KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler); + return val; } static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value, @@ -1004,6 +1006,12 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) fault_address = svm->vmcb->control.exit_info_2; error_code = svm->vmcb->control.exit_info_1; + + if (!npt_enabled) + KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code, + (u32)fault_address, (u32)(fault_address >> 32), + handler); + return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); } @@ -1083,12 +1091,14 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { + KVMTRACE_0D(NMI, &svm->vcpu, handler); return 1; } static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { ++svm->vcpu.stat.irq_exits; + KVMTRACE_0D(INTR, &svm->vcpu, handler); return 1; } @@ -1230,6 +1240,9 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) if (svm_get_msr(&svm->vcpu, ecx, &data)) kvm_inject_gp(&svm->vcpu, 0); else { + KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data, + (u32)(data >> 32), handler); + svm->vmcb->save.rax = data & 0xffffffff; svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; svm->next_rip = svm->vmcb->save.rip + 2; @@ -1315,6 +1328,10 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; u64 data = (svm->vmcb->save.rax & -1u) | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); + + KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32), + handler); + svm->next_rip = svm->vmcb->save.rip + 2; if (svm_set_msr(&svm->vcpu, ecx, data)) kvm_inject_gp(&svm->vcpu, 0); @@ -1334,6 +1351,8 @@ static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) static int interrupt_window_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { + KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler); + svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR); svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; /* @@ -1408,6 +1427,9 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) struct vcpu_svm *svm = to_svm(vcpu); u32 exit_code = svm->vmcb->control.exit_code; + KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip, + (u32)((u64)svm->vmcb->save.rip >> 32), entryexit); + if (npt_enabled) { int mmu_reload = 0; if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { @@ -1481,6 +1503,8 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) { struct vmcb_control_area *control; + KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler); + control = &svm->vmcb->control; control->int_vector = irq; control->int_ctl &= ~V_INTR_PRIO_MASK; -- cgit v1.2.3 From d2ebb4103ff349af6dac14955bf93e57487a6694 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 30 Apr 2008 17:56:04 +0200 Subject: KVM: SVM: add tracing support for TDP page faults To distinguish between real page faults and nested page faults they should be traced as different events. This is implemented by this patch. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8953292acfd..218949cce1a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1011,6 +1011,10 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code, (u32)fault_address, (u32)(fault_address >> 32), handler); + else + KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code, + (u32)fault_address, (u32)(fault_address >> 32), + handler); return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); } -- cgit v1.2.3 From f697554515b06e8d7264f316b25e6da943407142 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Fri, 2 May 2008 17:02:23 +0200 Subject: KVM: PIT: support mode 3 The in-kernel PIT emulation ignores pending timers if operating under mode 3, which for example Hurd uses. This mode should output a square wave, high for (N+1)/2 counts and low for (N-1)/2 counts. As we only care about the resulting interrupts, the period is N, and mode 3 is the same as mode 2 with regard to interrupts. Signed-off-by: Aurelien Jarno Signed-off-by: Avi Kivity --- arch/x86/kvm/i8254.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 735ec9a0b36..60074dc66bd 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -308,6 +308,7 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) create_pit_timer(&ps->pit_timer, val, 0); break; case 2: + case 3: create_pit_timer(&ps->pit_timer, val, 1); break; default: -- cgit v1.2.3 From 14ae51b6c068ef7ab52dc2d53fe226e6189f2ab2 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Mon, 5 May 2008 13:05:16 -0400 Subject: KVM: SVM: Fake MSR_K7 performance counters Attached is a patch that fixes a guest crash when booting older Linux kernels. The problem stems from the fact that we are currently emulating MSR_K7_EVNTSEL[0-3], but not emulating MSR_K7_PERFCTR[0-3]. Because of this, setup_k7_watchdog() in the Linux kernel receives a GPF when it attempts to write into MSR_K7_PERFCTR, which causes an OOPs. The patch fixes it by just "fake" emulating the appropriate MSRs, throwing away the data in the process. This causes the NMI watchdog to not actually work, but it's not such a big deal in a virtualized environment. When we get a write to one of these counters, we printk_ratelimit() a warning. I decided to print it out for all writes, even if the data is 0; it doesn't seem to make sense to me to special case when data == 0. Tested by myself on a RHEL-4 guest, and Joerg Roedel on a Windows XP 64-bit guest. Signed-off-by: Chris Lalancette Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 218949cce1a..992ab711587 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1312,16 +1312,19 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) case MSR_K7_EVNTSEL1: case MSR_K7_EVNTSEL2: case MSR_K7_EVNTSEL3: + case MSR_K7_PERFCTR0: + case MSR_K7_PERFCTR1: + case MSR_K7_PERFCTR2: + case MSR_K7_PERFCTR3: /* - * only support writing 0 to the performance counters for now - * to make Windows happy. Should be replaced by a real - * performance counter emulation later. + * Just discard all writes to the performance counters; this + * should keep both older linux and windows 64-bit guests + * happy */ - if (data != 0) - goto unhandled; + pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data); + break; default: - unhandled: return kvm_set_msr_common(vcpu, ecx, data); } return 0; -- cgit v1.2.3 From 7682f2d0dd3ff5bd2756eac018a5b4e7e30ef16c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 12 May 2008 19:25:43 +0300 Subject: KVM: VMX: Trivial vmcs_write64() code simplification Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 8c951d3eab3..fff8e23433d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -431,10 +431,8 @@ static void vmcs_write32(unsigned long field, u32 value) static void vmcs_write64(unsigned long field, u64 value) { -#ifdef CONFIG_X86_64 - vmcs_writel(field, value); -#else vmcs_writel(field, value); +#ifndef CONFIG_X86_64 asm volatile (""); vmcs_writel(field+1, value >> 32); #endif -- cgit v1.2.3 From 1b7fcd3263e5f12dba43d27b64e1578bec070c28 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 15 May 2008 13:51:35 +0300 Subject: KVM: MMU: Fix false flooding when a pte points to page table The KVM MMU tries to detect when a speculative pte update is not actually used by demand fault, by checking the accessed bit of the shadow pte. If the shadow pte has not been accessed, we deem that page table flooded and remove the shadow page table, allowing further pte updates to proceed without emulation. However, if the pte itself points at a page table and only used for write operations, the accessed bit will never be set since all access will happen through the emulator. This is exactly what happens with kscand on old (2.4.x) HIGHMEM kernels. The kernel points a kmap_atomic() pte at a page table, and then proceeds with read-modify-write operations to look at the dirty and accessed bits. We get a false flood trigger on the kmap ptes, which results in the mmu spending all its time setting up and tearing down shadows. Fix by setting the shadow accessed bit on emulated accesses. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 17 ++++++++++++++++- arch/x86/kvm/mmu.h | 3 ++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 8e449dbcc59..53f1ed852ca 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1122,8 +1122,10 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, else kvm_release_pfn_clean(pfn); } - if (!ptwrite || !*ptwrite) + if (speculative) { vcpu->arch.last_pte_updated = shadow_pte; + vcpu->arch.last_pte_gfn = gfn; + } } static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) @@ -1671,6 +1673,18 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, vcpu->arch.update_pte.pfn = pfn; } +static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn) +{ + u64 *spte = vcpu->arch.last_pte_updated; + + if (spte + && vcpu->arch.last_pte_gfn == gfn + && shadow_accessed_mask + && !(*spte & shadow_accessed_mask) + && is_shadow_present_pte(*spte)) + set_bit(PT_ACCESSED_SHIFT, (unsigned long *)spte); +} + void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, int bytes) { @@ -1694,6 +1708,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_access_page(vcpu, gfn); kvm_mmu_free_some_pages(vcpu); ++vcpu->kvm->stat.mmu_pte_write; kvm_mmu_audit(vcpu, "pre pte write"); diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 1730757bbc7..258e5d56298 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -15,7 +15,8 @@ #define PT_USER_MASK (1ULL << 2) #define PT_PWT_MASK (1ULL << 3) #define PT_PCD_MASK (1ULL << 4) -#define PT_ACCESSED_MASK (1ULL << 5) +#define PT_ACCESSED_SHIFT 5 +#define PT_ACCESSED_MASK (1ULL << PT_ACCESSED_SHIFT) #define PT_DIRTY_MASK (1ULL << 6) #define PT_PAGE_SIZE_MASK (1ULL << 7) #define PT_PAT_MASK (1ULL << 7) -- cgit v1.2.3 From 4ecac3fd6dc2629ad76a658a486f081c44aef10e Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 13 May 2008 13:23:38 +0300 Subject: KVM: Handle virtualization instruction #UD faults during reboot KVM turns off hardware virtualization extensions during reboot, in order to disassociate the memory used by the virtualization extensions from the processor, and in order to have the system in a consistent state. Unfortunately virtual machines may still be running while this goes on, and once virtualization extensions are turned off, any virtulization instruction will #UD on execution. Fix by adding an exception handler to virtualization instructions; if we get an exception during reboot, we simply spin waiting for the reset to complete. If it's a true exception, BUG() so we can have our stack trace. Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 20 +++++++++++--------- arch/x86/kvm/vmx.c | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 992ab711587..9390a31c06f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -27,6 +27,8 @@ #include +#define __ex(x) __kvm_handle_fault_on_reboot(x) + MODULE_AUTHOR("Qumranet"); MODULE_LICENSE("GPL"); @@ -129,17 +131,17 @@ static inline void push_irq(struct kvm_vcpu *vcpu, u8 irq) static inline void clgi(void) { - asm volatile (SVM_CLGI); + asm volatile (__ex(SVM_CLGI)); } static inline void stgi(void) { - asm volatile (SVM_STGI); + asm volatile (__ex(SVM_STGI)); } static inline void invlpga(unsigned long addr, u32 asid) { - asm volatile (SVM_INVLPGA :: "a"(addr), "c"(asid)); + asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); } static inline unsigned long kvm_read_cr2(void) @@ -1758,17 +1760,17 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) /* Enter guest mode */ "push %%rax \n\t" "mov %c[vmcb](%[svm]), %%rax \n\t" - SVM_VMLOAD "\n\t" - SVM_VMRUN "\n\t" - SVM_VMSAVE "\n\t" + __ex(SVM_VMLOAD) "\n\t" + __ex(SVM_VMRUN) "\n\t" + __ex(SVM_VMSAVE) "\n\t" "pop %%rax \n\t" #else /* Enter guest mode */ "push %%eax \n\t" "mov %c[vmcb](%[svm]), %%eax \n\t" - SVM_VMLOAD "\n\t" - SVM_VMRUN "\n\t" - SVM_VMSAVE "\n\t" + __ex(SVM_VMLOAD) "\n\t" + __ex(SVM_VMRUN) "\n\t" + __ex(SVM_VMSAVE) "\n\t" "pop %%eax \n\t" #endif diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fff8e23433d..b80b4d14163 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -30,6 +30,8 @@ #include #include +#define __ex(x) __kvm_handle_fault_on_reboot(x) + MODULE_AUTHOR("Qumranet"); MODULE_LICENSE("GPL"); @@ -278,7 +280,7 @@ static inline void __invvpid(int ext, u16 vpid, gva_t gva) u64 gva; } operand = { vpid, 0, gva }; - asm volatile (ASM_VMX_INVVPID + asm volatile (__ex(ASM_VMX_INVVPID) /* CF==1 or ZF==1 --> rc = -1 */ "; ja 1f ; ud2 ; 1:" : : "a"(&operand), "c"(ext) : "cc", "memory"); @@ -290,7 +292,7 @@ static inline void __invept(int ext, u64 eptp, gpa_t gpa) u64 eptp, gpa; } operand = {eptp, gpa}; - asm volatile (ASM_VMX_INVEPT + asm volatile (__ex(ASM_VMX_INVEPT) /* CF==1 or ZF==1 --> rc = -1 */ "; ja 1f ; ud2 ; 1:\n" : : "a" (&operand), "c" (ext) : "cc", "memory"); @@ -311,7 +313,7 @@ static void vmcs_clear(struct vmcs *vmcs) u64 phys_addr = __pa(vmcs); u8 error; - asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0" + asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0" : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) : "cc", "memory"); if (error) @@ -378,7 +380,7 @@ static unsigned long vmcs_readl(unsigned long field) { unsigned long value; - asm volatile (ASM_VMX_VMREAD_RDX_RAX + asm volatile (__ex(ASM_VMX_VMREAD_RDX_RAX) : "=a"(value) : "d"(field) : "cc"); return value; } @@ -413,7 +415,7 @@ static void vmcs_writel(unsigned long field, unsigned long value) { u8 error; - asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0" + asm volatile (__ex(ASM_VMX_VMWRITE_RAX_RDX) "; setna %0" : "=q"(error) : "a"(value), "d"(field) : "cc"); if (unlikely(error)) vmwrite_error(field, value); @@ -621,7 +623,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) u8 error; per_cpu(current_vmcs, cpu) = vmx->vmcs; - asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0" + asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0" : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) : "cc"); if (error) @@ -1030,13 +1032,14 @@ static void hardware_enable(void *garbage) MSR_IA32_FEATURE_CONTROL_LOCKED | MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED); write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ - asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) + asm volatile (ASM_VMX_VMXON_RAX + : : "a"(&phys_addr), "m"(phys_addr) : "memory", "cc"); } static void hardware_disable(void *garbage) { - asm volatile (ASM_VMX_VMXOFF : : : "cc"); + asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc"); write_cr4(read_cr4() & ~X86_CR4_VMXE); } @@ -2834,7 +2837,7 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) "push %%edx; push %%ebp;" "push %%ecx \n\t" #endif - ASM_VMX_VMWRITE_RSP_RDX "\n\t" + __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t" /* Check if vmlaunch of vmresume is needed */ "cmpl $0, %c[launched](%0) \n\t" /* Load guest registers. Don't clobber flags. */ @@ -2869,9 +2872,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) #endif /* Enter guest mode */ "jne .Llaunched \n\t" - ASM_VMX_VMLAUNCH "\n\t" + __ex(ASM_VMX_VMLAUNCH) "\n\t" "jmp .Lkvm_vmx_return \n\t" - ".Llaunched: " ASM_VMX_VMRESUME "\n\t" + ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" ".Lkvm_vmx_return: " /* Save guest registers, load host registers, keep flags */ #ifdef CONFIG_X86_64 -- cgit v1.2.3 From 543e42436643d68ad007d0bae2f485caac9c8a02 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 13 May 2008 16:22:47 +0300 Subject: KVM: VMX: Add list of potentially locally cached vcpus VMX hardware can cache the contents of a vcpu's vmcs. This cache needs to be flushed when migrating a vcpu to another cpu, or (which is the case that interests us here) when disabling hardware virtualization on a cpu. The current implementation of decaching iterates over the list of all vcpus, picks the ones that are potentially cached on the cpu that is being offlined, and flushes the cache. The problem is that it uses mutex_trylock() to gain exclusive access to the vcpu, which fires off a (benign) warning about using the mutex in an interrupt context. To avoid this, and to make things generally nicer, add a new per-cpu list of potentially cached vcus. This makes the decaching code much simpler. The list is vmx-specific since other hardware doesn't have this issue. [andrea: fix crash on suspend/resume] Signed-off-by: Andrea Arcangeli Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 24 ++++++++++++++++++++++-- arch/x86/kvm/x86.c | 27 --------------------------- 2 files changed, 22 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b80b4d14163..4d179d10637 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -55,6 +55,7 @@ struct vmcs { struct vcpu_vmx { struct kvm_vcpu vcpu; + struct list_head local_vcpus_link; int launched; u8 fail; u32 idt_vectoring_info; @@ -93,6 +94,7 @@ static int init_rmode(struct kvm *kvm); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); +static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); static struct page *vmx_io_bitmap_a; static struct page *vmx_io_bitmap_b; @@ -331,6 +333,9 @@ static void __vcpu_clear(void *arg) if (per_cpu(current_vmcs, cpu) == vmx->vmcs) per_cpu(current_vmcs, cpu) = NULL; rdtscll(vmx->vcpu.arch.host_tsc); + list_del(&vmx->local_vcpus_link); + vmx->vcpu.cpu = -1; + vmx->launched = 0; } static void vcpu_clear(struct vcpu_vmx *vmx) @@ -338,7 +343,6 @@ static void vcpu_clear(struct vcpu_vmx *vmx) if (vmx->vcpu.cpu == -1) return; smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 1); - vmx->launched = 0; } static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx) @@ -617,6 +621,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vcpu_clear(vmx); kvm_migrate_timers(vcpu); vpid_sync_vcpu_all(vmx); + local_irq_disable(); + list_add(&vmx->local_vcpus_link, + &per_cpu(vcpus_on_cpu, cpu)); + local_irq_enable(); } if (per_cpu(current_vmcs, cpu) != vmx->vmcs) { @@ -1022,6 +1030,7 @@ static void hardware_enable(void *garbage) u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); u64 old; + INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); rdmsrl(MSR_IA32_FEATURE_CONTROL, old); if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED | MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED)) @@ -1037,8 +1046,19 @@ static void hardware_enable(void *garbage) : "memory", "cc"); } +static void vmclear_local_vcpus(void) +{ + int cpu = raw_smp_processor_id(); + struct vcpu_vmx *vmx, *n; + + list_for_each_entry_safe(vmx, n, &per_cpu(vcpus_on_cpu, cpu), + local_vcpus_link) + __vcpu_clear(vmx); +} + static void hardware_disable(void *garbage) { + vmclear_local_vcpus(); asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc"); write_cr4(read_cr4() & ~X86_CR4_VMXE); } @@ -2967,7 +2987,7 @@ static void vmx_free_vmcs(struct kvm_vcpu *vcpu) struct vcpu_vmx *vmx = to_vmx(vcpu); if (vmx->vmcs) { - on_each_cpu(__vcpu_clear, vmx, 1); + vcpu_clear(vmx); free_vmcs(vmx->vmcs); vmx->vmcs = NULL; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 59084a3981c..8c14ddcaba7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -823,33 +823,6 @@ out: */ void decache_vcpus_on_cpu(int cpu) { - struct kvm *vm; - struct kvm_vcpu *vcpu; - int i; - - spin_lock(&kvm_lock); - list_for_each_entry(vm, &vm_list, vm_list) - for (i = 0; i < KVM_MAX_VCPUS; ++i) { - vcpu = vm->vcpus[i]; - if (!vcpu) - continue; - /* - * If the vcpu is locked, then it is running on some - * other cpu and therefore it is not cached on the - * cpu in question. - * - * If it's not locked, check the last cpu it executed - * on. - */ - if (mutex_trylock(&vcpu->mutex)) { - if (vcpu->cpu == cpu) { - kvm_x86_ops->vcpu_decache(vcpu); - vcpu->cpu = -1; - } - mutex_unlock(&vcpu->mutex); - } - } - spin_unlock(&kvm_lock); } int kvm_dev_ioctl_check_extension(long ext) -- cgit v1.2.3 From 7cc8883074b040aa8c1ebd3a17463b0ea3a9ef16 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 13 May 2008 16:29:20 +0300 Subject: KVM: Remove decache_vcpus_on_cpu() and related callbacks Obsoleted by the vmx-specific per-cpu list. Signed-off-by: Avi Kivity --- arch/ia64/kvm/kvm-ia64.c | 8 -------- arch/powerpc/kvm/powerpc.c | 4 ---- arch/s390/kvm/kvm-s390.c | 4 ---- arch/x86/kvm/svm.c | 5 ----- arch/x86/kvm/vmx.c | 6 ------ arch/x86/kvm/x86.c | 8 -------- 6 files changed, 35 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 68c978be9a5..7c504be5797 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1035,14 +1035,6 @@ static void kvm_free_vmm_area(void) } } -/* - * Make sure that a cpu that is being hot-unplugged does not have any vcpus - * cached on it. Leave it as blank for IA64. - */ -void decache_vcpus_on_cpu(int cpu) -{ -} - static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 777e0f34e0e..0513b359851 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -240,10 +240,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { } -void decache_vcpus_on_cpu(int cpu) -{ -} - int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) { diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 6558b09ff57..4585c8ac2b0 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -79,10 +79,6 @@ void kvm_arch_hardware_disable(void *garbage) { } -void decache_vcpus_on_cpu(int cpu) -{ -} - int kvm_arch_hardware_setup(void) { return 0; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 9390a31c06f..238e8f3afaf 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -709,10 +709,6 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) rdtscll(vcpu->arch.host_tsc); } -static void svm_vcpu_decache(struct kvm_vcpu *vcpu) -{ -} - static void svm_cache_regs(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1933,7 +1929,6 @@ static struct kvm_x86_ops svm_x86_ops = { .prepare_guest_switch = svm_prepare_guest_switch, .vcpu_load = svm_vcpu_load, .vcpu_put = svm_vcpu_put, - .vcpu_decache = svm_vcpu_decache, .set_guest_debug = svm_guest_debug, .get_msr = svm_get_msr, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 4d179d10637..b99bb37e5de 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -692,11 +692,6 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) update_exception_bitmap(vcpu); } -static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) -{ - vcpu_clear(to_vmx(vcpu)); -} - static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) { return vmcs_readl(GUEST_RFLAGS); @@ -3114,7 +3109,6 @@ static struct kvm_x86_ops vmx_x86_ops = { .prepare_guest_switch = vmx_save_host_state, .vcpu_load = vmx_vcpu_load, .vcpu_put = vmx_vcpu_put, - .vcpu_decache = vmx_vcpu_decache, .set_guest_debug = set_guest_debug, .guest_debug_pre = kvm_guest_debug_pre, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8c14ddcaba7..fd03b4465bc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -817,14 +817,6 @@ out: return r; } -/* - * Make sure that a cpu that is being hot-unplugged does not have any vcpus - * cached on it. - */ -void decache_vcpus_on_cpu(int cpu) -{ -} - int kvm_dev_ioctl_check_extension(long ext) { int r; -- cgit v1.2.3 From 50d40d7fb9b09e68a657c68837fcfa067b70cc42 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 25 May 2008 14:38:15 +0300 Subject: KVM: Remove unnecessary ->decache_regs() call Since we aren't modifying any register, there's no need to decache the register state. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fd03b4465bc..5f00c60f0af 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2297,7 +2297,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, kvm_x86_ops->cache_regs(vcpu); memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4); - kvm_x86_ops->decache_regs(vcpu); kvm_x86_ops->skip_emulated_instruction(vcpu); -- cgit v1.2.3 From 3419ffc8e45a5344abc87684cbca6cdc5c9c8a01 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 15 May 2008 09:52:48 +0800 Subject: KVM: IOAPIC/LAPIC: Enable NMI support [avi: fix ia64 build breakage] Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/lapic.c | 3 ++- arch/x86/kvm/x86.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index f9201fbc61d..e48d1939403 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -356,8 +356,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, case APIC_DM_SMI: printk(KERN_DEBUG "Ignoring guest SMI\n"); break; + case APIC_DM_NMI: - printk(KERN_DEBUG "Ignoring guest NMI\n"); + kvm_inject_nmi(vcpu); break; case APIC_DM_INIT: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5f00c60f0af..19974dde656 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -173,6 +173,12 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); } +void kvm_inject_nmi(struct kvm_vcpu *vcpu) +{ + vcpu->arch.nmi_pending = 1; +} +EXPORT_SYMBOL_GPL(kvm_inject_nmi); + void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { WARN_ON(vcpu->arch.exception.pending); -- cgit v1.2.3 From f08864b42a45581a64558aa5b6b673c77b97ee5d Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 15 May 2008 18:23:25 +0800 Subject: KVM: VMX: Enable NMI with in-kernel irqchip Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 124 +++++++++++++++++++++++++++++++++++++++++++++-------- arch/x86/kvm/vmx.h | 12 +++++- arch/x86/kvm/x86.c | 1 + 3 files changed, 118 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b99bb37e5de..1bb99465720 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -264,6 +264,11 @@ static inline int cpu_has_vmx_vpid(void) SECONDARY_EXEC_ENABLE_VPID); } +static inline int cpu_has_virtual_nmis(void) +{ + return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS; +} + static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr) { int i; @@ -1088,7 +1093,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) u32 _vmentry_control = 0; min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; - opt = 0; + opt = PIN_BASED_VIRTUAL_NMIS; if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS, &_pin_based_exec_control) < 0) return -EIO; @@ -2130,6 +2135,13 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq) irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); } +static void vmx_inject_nmi(struct kvm_vcpu *vcpu) +{ + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, + INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR); + vcpu->arch.nmi_pending = 0; +} + static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) { int word_index = __ffs(vcpu->arch.irq_summary); @@ -2653,6 +2665,19 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; } +static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + u32 cpu_based_vm_exec_control; + + /* clear pending NMI */ + cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); + cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING; + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); + ++vcpu->stat.nmi_window_exits; + + return 1; +} + /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs @@ -2663,6 +2688,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_EXCEPTION_NMI] = handle_exception, [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, [EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault, + [EXIT_REASON_NMI_WINDOW] = handle_nmi_window, [EXIT_REASON_IO_INSTRUCTION] = handle_io, [EXIT_REASON_CR_ACCESS] = handle_cr, [EXIT_REASON_DR_ACCESS] = handle_dr, @@ -2750,17 +2776,52 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); } +static void enable_nmi_window(struct kvm_vcpu *vcpu) +{ + u32 cpu_based_vm_exec_control; + + if (!cpu_has_virtual_nmis()) + return; + + cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); + cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); +} + +static int vmx_nmi_enabled(struct kvm_vcpu *vcpu) +{ + u32 guest_intr = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); + return !(guest_intr & (GUEST_INTR_STATE_NMI | + GUEST_INTR_STATE_MOV_SS | + GUEST_INTR_STATE_STI)); +} + +static int vmx_irq_enabled(struct kvm_vcpu *vcpu) +{ + u32 guest_intr = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); + return (!(guest_intr & (GUEST_INTR_STATE_MOV_SS | + GUEST_INTR_STATE_STI)) && + (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF)); +} + +static void enable_intr_window(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.nmi_pending) + enable_nmi_window(vcpu); + else if (kvm_cpu_has_interrupt(vcpu)) + enable_irq_window(vcpu); +} + static void vmx_intr_assist(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - u32 idtv_info_field, intr_info_field; - int has_ext_irq, interrupt_window_open; + u32 idtv_info_field, intr_info_field, exit_intr_info_field; int vector; update_tpr_threshold(vcpu); - has_ext_irq = kvm_cpu_has_interrupt(vcpu); intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD); + exit_intr_info_field = vmcs_read32(VM_EXIT_INTR_INFO); idtv_info_field = vmx->idt_vectoring_info; if (intr_info_field & INTR_INFO_VALID_MASK) { if (idtv_info_field & INTR_INFO_VALID_MASK) { @@ -2768,8 +2829,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) if (printk_ratelimit()) printk(KERN_ERR "Fault when IDT_Vectoring\n"); } - if (has_ext_irq) - enable_irq_window(vcpu); + enable_intr_window(vcpu); return; } if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) { @@ -2779,30 +2839,56 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK; vmx_inject_irq(vcpu, vect); - if (unlikely(has_ext_irq)) - enable_irq_window(vcpu); + enable_intr_window(vcpu); return; } KVMTRACE_1D(REDELIVER_EVT, vcpu, idtv_info_field, handler); - vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field); + /* + * SDM 3: 25.7.1.2 + * Clear bit "block by NMI" before VM entry if a NMI delivery + * faulted. + */ + if ((idtv_info_field & VECTORING_INFO_TYPE_MASK) + == INTR_TYPE_NMI_INTR && cpu_has_virtual_nmis()) + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, + vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & + ~GUEST_INTR_STATE_NMI); + + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field + & ~INTR_INFO_RESVD_BITS_MASK); vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); if (unlikely(idtv_info_field & INTR_INFO_DELIVER_CODE_MASK)) vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, vmcs_read32(IDT_VECTORING_ERROR_CODE)); - if (unlikely(has_ext_irq)) - enable_irq_window(vcpu); + enable_intr_window(vcpu); return; } - if (!has_ext_irq) + if (cpu_has_virtual_nmis()) { + /* + * SDM 3: 25.7.1.2 + * Re-set bit "block by NMI" before VM entry if vmexit caused by + * a guest IRET fault. + */ + if ((exit_intr_info_field & INTR_INFO_UNBLOCK_NMI) && + (exit_intr_info_field & INTR_INFO_VECTOR_MASK) != 8) + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, + vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) | + GUEST_INTR_STATE_NMI); + else if (vcpu->arch.nmi_pending) { + if (vmx_nmi_enabled(vcpu)) + vmx_inject_nmi(vcpu); + enable_intr_window(vcpu); + return; + } + + } + if (!kvm_cpu_has_interrupt(vcpu)) return; - interrupt_window_open = - ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) && - (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0); - if (interrupt_window_open) { + if (vmx_irq_enabled(vcpu)) { vector = kvm_cpu_get_interrupt(vcpu); vmx_inject_irq(vcpu, vector); kvm_timer_intr_post(vcpu, vector); @@ -2963,7 +3049,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) fixup_rmode_irq(vmx); vcpu->arch.interrupt_window_open = - (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & + (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0; asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); vmx->launched = 1; @@ -2971,7 +3058,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) intr_info = vmcs_read32(VM_EXIT_INTR_INFO); /* We need to handle NMIs before interrupts are enabled */ - if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */ + if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200 && + (intr_info & INTR_INFO_VALID_MASK)) { KVMTRACE_0D(NMI, vcpu, handler); asm("int $2"); } diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h index 79d94c610df..425a13436b3 100644 --- a/arch/x86/kvm/vmx.h +++ b/arch/x86/kvm/vmx.h @@ -40,6 +40,7 @@ #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 #define CPU_BASED_CR8_STORE_EXITING 0x00100000 #define CPU_BASED_TPR_SHADOW 0x00200000 +#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_USE_IO_BITMAPS 0x02000000 @@ -216,7 +217,7 @@ enum vmcs_field { #define EXIT_REASON_TRIPLE_FAULT 2 #define EXIT_REASON_PENDING_INTERRUPT 7 - +#define EXIT_REASON_NMI_WINDOW 8 #define EXIT_REASON_TASK_SWITCH 9 #define EXIT_REASON_CPUID 10 #define EXIT_REASON_HLT 12 @@ -251,7 +252,9 @@ enum vmcs_field { #define INTR_INFO_VECTOR_MASK 0xff /* 7:0 */ #define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ #define INTR_INFO_DELIVER_CODE_MASK 0x800 /* 11 */ +#define INTR_INFO_UNBLOCK_NMI 0x1000 /* 12 */ #define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ +#define INTR_INFO_RESVD_BITS_MASK 0x7ffff000 #define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK #define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK @@ -259,9 +262,16 @@ enum vmcs_field { #define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK #define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */ +#define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */ #define INTR_TYPE_EXCEPTION (3 << 8) /* processor exception */ #define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */ +/* GUEST_INTERRUPTIBILITY_INFO flags. */ +#define GUEST_INTR_STATE_STI 0x00000001 +#define GUEST_INTR_STATE_MOV_SS 0x00000002 +#define GUEST_INTR_STATE_SMI 0x00000004 +#define GUEST_INTR_STATE_NMI 0x00000008 + /* * Exit Qualifications for MOV for Control Register Access */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19974dde656..05b54976c89 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -72,6 +72,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "mmio_exits", VCPU_STAT(mmio_exits) }, { "signal_exits", VCPU_STAT(signal_exits) }, { "irq_window", VCPU_STAT(irq_window_exits) }, + { "nmi_window", VCPU_STAT(nmi_window_exits) }, { "halt_exits", VCPU_STAT(halt_exits) }, { "halt_wakeup", VCPU_STAT(halt_wakeup) }, { "hypercalls", VCPU_STAT(hypercalls) }, -- cgit v1.2.3 From 9ba075a664dff836fd6fb93f90fcc827f7683d91 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 26 May 2008 20:06:35 +0300 Subject: KVM: MTRR support Add emulation for the memory type range registers, needed by VMware esx 3.5, and by pci device assignment. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 05b54976c89..5f67a7c54e8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -611,6 +611,38 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT); } +static bool msr_mtrr_valid(unsigned msr) +{ + switch (msr) { + case 0x200 ... 0x200 + 2 * KVM_NR_VAR_MTRR - 1: + case MSR_MTRRfix64K_00000: + case MSR_MTRRfix16K_80000: + case MSR_MTRRfix16K_A0000: + case MSR_MTRRfix4K_C0000: + case MSR_MTRRfix4K_C8000: + case MSR_MTRRfix4K_D0000: + case MSR_MTRRfix4K_D8000: + case MSR_MTRRfix4K_E0000: + case MSR_MTRRfix4K_E8000: + case MSR_MTRRfix4K_F0000: + case MSR_MTRRfix4K_F8000: + case MSR_MTRRdefType: + case MSR_IA32_CR_PAT: + return true; + case 0x2f8: + return true; + } + return false; +} + +static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data) +{ + if (!msr_mtrr_valid(msr)) + return 1; + + vcpu->arch.mtrr[msr - 0x200] = data; + return 0; +} int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { @@ -632,8 +664,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) break; case MSR_IA32_UCODE_REV: case MSR_IA32_UCODE_WRITE: - case 0x200 ... 0x2ff: /* MTRRs */ break; + case 0x200 ... 0x2ff: + return set_msr_mtrr(vcpu, msr, data); case MSR_IA32_APICBASE: kvm_set_apic_base(vcpu, data); break; @@ -691,6 +724,15 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) return kvm_x86_ops->get_msr(vcpu, msr_index, pdata); } +static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) +{ + if (!msr_mtrr_valid(msr)) + return 1; + + *pdata = vcpu->arch.mtrr[msr - 0x200]; + return 0; +} + int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) { u64 data; @@ -712,11 +754,13 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_MC0_MISC+16: case MSR_IA32_UCODE_REV: case MSR_IA32_EBL_CR_POWERON: - /* MTRR registers */ - case 0xfe: - case 0x200 ... 0x2ff: data = 0; break; + case MSR_MTRRcap: + data = 0x500 | KVM_NR_VAR_MTRR; + break; + case 0x200 ... 0x2ff: + return get_msr_mtrr(vcpu, msr, pdata); case 0xcd: /* fsb frequency */ data = 3; break; -- cgit v1.2.3 From 3e6e0aab1ba1e8b354ce01f5659336f9aee69437 Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 10:18:46 +0200 Subject: KVM: Prefixes segment functions that will be exported with "kvm_" Prefixes functions that will be exported with kvm_. We also prefixed set_segment() even if it still static to be coherent. signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 78 +++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5f67a7c54e8..4c94fad7f01 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3100,8 +3100,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) return 0; } -static void get_segment(struct kvm_vcpu *vcpu, - struct kvm_segment *var, int seg) +void kvm_get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) { kvm_x86_ops->get_segment(vcpu, var, seg); } @@ -3110,7 +3110,7 @@ void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) { struct kvm_segment cs; - get_segment(vcpu, &cs, VCPU_SREG_CS); + kvm_get_segment(vcpu, &cs, VCPU_SREG_CS); *db = cs.db; *l = cs.l; } @@ -3124,15 +3124,15 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, vcpu_load(vcpu); - get_segment(vcpu, &sregs->cs, VCPU_SREG_CS); - get_segment(vcpu, &sregs->ds, VCPU_SREG_DS); - get_segment(vcpu, &sregs->es, VCPU_SREG_ES); - get_segment(vcpu, &sregs->fs, VCPU_SREG_FS); - get_segment(vcpu, &sregs->gs, VCPU_SREG_GS); - get_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + kvm_get_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + kvm_get_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + kvm_get_segment(vcpu, &sregs->es, VCPU_SREG_ES); + kvm_get_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + kvm_get_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + kvm_get_segment(vcpu, &sregs->ss, VCPU_SREG_SS); - get_segment(vcpu, &sregs->tr, VCPU_SREG_TR); - get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + kvm_get_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); kvm_x86_ops->get_idt(vcpu, &dt); sregs->idt.limit = dt.limit; @@ -3184,7 +3184,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return 0; } -static void set_segment(struct kvm_vcpu *vcpu, +static void kvm_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { kvm_x86_ops->set_segment(vcpu, var, seg); @@ -3221,7 +3221,7 @@ static void get_segment_descritptor_dtable(struct kvm_vcpu *vcpu, if (selector & 1 << 2) { struct kvm_segment kvm_seg; - get_segment(vcpu, &kvm_seg, VCPU_SREG_LDTR); + kvm_get_segment(vcpu, &kvm_seg, VCPU_SREG_LDTR); if (kvm_seg.unusable) dtable->limit = 0; @@ -3327,7 +3327,7 @@ static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) { struct kvm_segment kvm_seg; - get_segment(vcpu, &kvm_seg, seg); + kvm_get_segment(vcpu, &kvm_seg, seg); return kvm_seg.selector; } @@ -3343,8 +3343,8 @@ static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu, return 0; } -static int load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, - int type_bits, int seg) +int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, + int type_bits, int seg) { struct kvm_segment kvm_seg; @@ -3357,7 +3357,7 @@ static int load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, if (!kvm_seg.s) kvm_seg.unusable = 1; - set_segment(vcpu, &kvm_seg, seg); + kvm_set_segment(vcpu, &kvm_seg, seg); return 0; } @@ -3403,25 +3403,25 @@ static int load_state_from_tss32(struct kvm_vcpu *vcpu, vcpu->arch.regs[VCPU_REGS_RSI] = tss->esi; vcpu->arch.regs[VCPU_REGS_RDI] = tss->edi; - if (load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR)) + if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR)) return 1; - if (load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) + if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) return 1; - if (load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) + if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) return 1; - if (load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) + if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) return 1; - if (load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) + if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) return 1; - if (load_segment_descriptor(vcpu, tss->fs, 1, VCPU_SREG_FS)) + if (kvm_load_segment_descriptor(vcpu, tss->fs, 1, VCPU_SREG_FS)) return 1; - if (load_segment_descriptor(vcpu, tss->gs, 1, VCPU_SREG_GS)) + if (kvm_load_segment_descriptor(vcpu, tss->gs, 1, VCPU_SREG_GS)) return 1; return 0; } @@ -3462,19 +3462,19 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu, vcpu->arch.regs[VCPU_REGS_RSI] = tss->si; vcpu->arch.regs[VCPU_REGS_RDI] = tss->di; - if (load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR)) + if (kvm_load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR)) return 1; - if (load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) + if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) return 1; - if (load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) + if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) return 1; - if (load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) + if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) return 1; - if (load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) + if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) return 1; return 0; } @@ -3532,7 +3532,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) struct desc_struct nseg_desc; int ret = 0; - get_segment(vcpu, &tr_seg, VCPU_SREG_TR); + kvm_get_segment(vcpu, &tr_seg, VCPU_SREG_TR); if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) goto out; @@ -3591,7 +3591,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 | X86_CR0_TS); seg_desct_to_kvm_desct(&nseg_desc, tss_selector, &tr_seg); tr_seg.type = 11; - set_segment(vcpu, &tr_seg, VCPU_SREG_TR); + kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR); out: kvm_x86_ops->decache_regs(vcpu); return ret; @@ -3658,15 +3658,15 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, } } - set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); - set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); - set_segment(vcpu, &sregs->es, VCPU_SREG_ES); - set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); - set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); - set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES); + kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + kvm_set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + kvm_set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); - set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); - set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); vcpu_put(vcpu); -- cgit v1.2.3 From 89c696383d6eb493351a89d450d8ad7a55cbe1da Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 10:22:20 +0200 Subject: KVM: x86 emulator: Update c->dst.bytes in decode instruction Update c->dst.bytes in decode instruction instead of instruction itself. It's needed because if c->dst.bytes is equal to 0, the instruction is not emulated. Signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 932f216d890..a928aa6cdad 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -1049,6 +1049,7 @@ done_prefixes: break; case DstMem: if ((c->d & ModRM) && c->modrm_mod == 3) { + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.type = OP_REG; c->dst.val = c->dst.orig_val = c->modrm_val; c->dst.ptr = c->modrm_ptr; -- cgit v1.2.3 From 954cd36f7613ac6d084abe33114dd45a8e0dbe92 Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 10:19:08 +0200 Subject: KVM: x86 emulator: add support for jmp far 0xea Add support for jmp far (opcode 0xea) instruction. Signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index a928aa6cdad..48b62cc3bd0 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -168,7 +168,8 @@ static u16 opcode_table[256] = { /* 0xE0 - 0xE7 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE8 - 0xEF */ - ImplicitOps | Stack, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, + ImplicitOps | Stack, SrcImm | ImplicitOps, + ImplicitOps, SrcImmByte | ImplicitOps, 0, 0, 0, 0, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, @@ -1661,7 +1662,33 @@ special_insn: break; } case 0xe9: /* jmp rel */ - case 0xeb: /* jmp rel short */ + goto jmp; + case 0xea: /* jmp far */ { + uint32_t eip; + uint16_t sel; + + switch (c->op_bytes) { + case 2: + eip = insn_fetch(u16, 2, c->eip); + break; + case 4: + eip = insn_fetch(u32, 4, c->eip); + break; + default: + DPRINTF("jmp far: Invalid op_bytes\n"); + goto cannot_emulate; + } + sel = insn_fetch(u16, 2, c->eip); + if (kvm_load_segment_descriptor(ctxt->vcpu, sel, 9, VCPU_SREG_CS) < 0) { + DPRINTF("jmp far: Failed to load CS descriptor\n"); + goto cannot_emulate; + } + + c->eip = eip; + break; + } + case 0xeb: + jmp: /* jmp rel short */ jmp_rel(c, c->src.val); c->dst.type = OP_NONE; /* Disable writeback. */ break; -- cgit v1.2.3 From 615ac125618dc7b40ecb418e8b353d31ccf0e518 Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 10:19:16 +0200 Subject: KVM: x86 emulator: adds support to mov r,imm (opcode 0xb8) instruction Add support to mov r, imm (0xb8) instruction. Signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 48b62cc3bd0..21d7ff6a8ec 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -152,7 +152,8 @@ static u16 opcode_table[256] = { ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, ByteOp | ImplicitOps | String, ImplicitOps | String, /* 0xB0 - 0xBF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + DstReg | SrcImm | Mov, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xC7 */ ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM, 0, ImplicitOps | Stack, 0, 0, @@ -1624,6 +1625,8 @@ special_insn: case 0xae ... 0xaf: /* scas */ DPRINTF("Urk! I don't handle SCAS.\n"); goto cannot_emulate; + case 0xb8: /* mov r, imm */ + goto mov; case 0xc0 ... 0xc1: emulate_grp2(ctxt); break; -- cgit v1.2.3 From 4257198ae2c36e030a0947fef661c8de973778be Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 14:49:15 +0200 Subject: KVM: x86 emulator: Add support for mov seg, r (0x8e) instruction Add support for mov r, sreg (0x8c) instruction. [avi: drop the sreg decoding table in favor of 1:1 encoding] Signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 21d7ff6a8ec..b049b6bf9a7 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -138,7 +138,8 @@ static u16 opcode_table[256] = { /* 0x88 - 0x8F */ ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, - 0, ModRM | DstReg, 0, Group | Group1A, + 0, ModRM | DstReg, + DstReg | SrcMem | ModRM | Mov, Group | Group1A, /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, @@ -1520,6 +1521,28 @@ special_insn: case 0x8d: /* lea r16/r32, m */ c->dst.val = c->modrm_ea; break; + case 0x8e: { /* mov seg, r/m16 */ + uint16_t sel; + int type_bits; + int err; + + sel = c->src.val; + if (c->modrm_reg <= 5) { + type_bits = (c->modrm_reg == 1) ? 9 : 1; + err = kvm_load_segment_descriptor(ctxt->vcpu, sel, + type_bits, c->modrm_reg); + } else { + printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n", + c->modrm); + goto cannot_emulate; + } + + if (err < 0) + goto cannot_emulate; + + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + } case 0x8f: /* pop (sole member of Grp1a) */ rc = emulate_grp1a(ctxt, ops); if (rc != 0) -- cgit v1.2.3 From 38d5bc6d50a4368be08b39b02efb9cbbe1dd60d0 Mon Sep 17 00:00:00 2001 From: Guillaume Thouvenin Date: Tue, 27 May 2008 15:13:28 +0200 Subject: KVM: x86 emulator: Add support for mov r, sreg (0x8c) instruction Add support for mov r, sreg (0x8c) instruction Signed-off-by: Guillaume Thouvenin Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index b049b6bf9a7..2a9db4d90ba 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -138,7 +138,7 @@ static u16 opcode_table[256] = { /* 0x88 - 0x8F */ ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, - 0, ModRM | DstReg, + DstMem | SrcReg | ModRM | Mov, ModRM | DstReg, DstReg | SrcMem | ModRM | Mov, Group | Group1A, /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -1518,6 +1518,19 @@ special_insn: break; case 0x88 ... 0x8b: /* mov */ goto mov; + case 0x8c: { /* mov r/m, sreg */ + struct kvm_segment segreg; + + if (c->modrm_reg <= 5) + kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg); + else { + printk(KERN_INFO "0x8c: Invalid segreg in modrm byte 0x%02x\n", + c->modrm); + goto cannot_emulate; + } + c->dst.val = segreg.selector; + break; + } case 0x8d: /* lea r16/r32, m */ c->dst.val = c->modrm_ea; break; -- cgit v1.2.3 From eab9f71feb1851b5b700ca12ae614b6a0a441021 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 29 May 2008 14:20:16 +0300 Subject: KVM: MMU: Optimize prefetch_page() Instead of reading each pte individually, read 256 bytes worth of ptes and batch process them. Signed-off-by: Avi Kivity --- arch/x86/kvm/paging_tmpl.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 934c7b61939..4d918220bae 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -460,8 +460,9 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) { - int i, offset = 0, r = 0; - pt_element_t pt; + int i, j, offset, r; + pt_element_t pt[256 / sizeof(pt_element_t)]; + gpa_t pte_gpa; if (sp->role.metaphysical || (PTTYPE == 32 && sp->role.level > PT_PAGE_TABLE_LEVEL)) { @@ -469,19 +470,20 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu, return; } - if (PTTYPE == 32) + pte_gpa = gfn_to_gpa(sp->gfn); + if (PTTYPE == 32) { offset = sp->role.quadrant << PT64_LEVEL_BITS; + pte_gpa += offset * sizeof(pt_element_t); + } - for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { - gpa_t pte_gpa = gfn_to_gpa(sp->gfn); - pte_gpa += (i+offset) * sizeof(pt_element_t); - - r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &pt, - sizeof(pt_element_t)); - if (r || is_present_pte(pt)) - sp->spt[i] = shadow_trap_nonpresent_pte; - else - sp->spt[i] = shadow_notrap_nonpresent_pte; + for (i = 0; i < PT64_ENT_PER_PAGE; i += ARRAY_SIZE(pt)) { + r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt); + pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t); + for (j = 0; j < ARRAY_SIZE(pt); ++j) + if (r || is_present_pte(pt[j])) + sp->spt[i+j] = shadow_trap_nonpresent_pte; + else + sp->spt[i+j] = shadow_notrap_nonpresent_pte; } } -- cgit v1.2.3 From 19e43636b5af1c8b9cc8406af674835284abab0c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 29 May 2008 14:26:29 +0300 Subject: KVM: x86 emulator: simplify push imm8 emulation Instead of fetching the data explicitly, use SrcImmByte. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 2a9db4d90ba..4e037ea8fe6 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -121,7 +121,7 @@ static u16 opcode_table[256] = { 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , 0, 0, 0, 0, /* 0x68 - 0x6F */ - 0, 0, ImplicitOps | Mov | Stack, 0, + 0, 0, SrcImmByte | Mov | Stack, 0, SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ /* 0x70 - 0x77 */ @@ -1425,8 +1425,6 @@ special_insn: c->dst.val = (s32) c->src.val; break; case 0x6a: /* push imm8 */ - c->src.val = 0L; - c->src.val = insn_fetch(s8, 1, c->eip); emulate_push(ctxt); break; case 0x6c: /* insb */ -- cgit v1.2.3 From 91ed7a0e15c6f6ff57f5cf70feabdba56a999863 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 29 May 2008 14:38:38 +0300 Subject: KVM: x86 emulator: implement 'push imm' (opcode 0x68) Encountered in FC6 boot sequence, now that we don't force ss.rpl = 0 during the protected mode transition. Not really necessary, but nice to have. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 4e037ea8fe6..b90857c7656 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -121,7 +121,7 @@ static u16 opcode_table[256] = { 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , 0, 0, 0, 0, /* 0x68 - 0x6F */ - 0, 0, SrcImmByte | Mov | Stack, 0, + SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ /* 0x70 - 0x77 */ @@ -1424,6 +1424,7 @@ special_insn: goto cannot_emulate; c->dst.val = (s32) c->src.val; break; + case 0x68: /* push imm */ case 0x6a: /* push imm8 */ emulate_push(ctxt); break; -- cgit v1.2.3 From d761a501cf9cd4fa08ff35d252ff08b8c31ce677 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 29 May 2008 14:55:03 +0300 Subject: KVM: MMU: Move nonpaging_prefetch_page() In preparation for next patch. No code change. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 53f1ed852ca..62741b7c422 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -776,6 +776,15 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp, BUG(); } +static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp) +{ + int i; + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) + sp->spt[i] = shadow_trap_nonpresent_pte; +} + static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) { unsigned index; @@ -1213,15 +1222,6 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) } -static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, - struct kvm_mmu_page *sp) -{ - int i; - - for (i = 0; i < PT64_ENT_PER_PAGE; ++i) - sp->spt[i] = shadow_trap_nonpresent_pte; -} - static void mmu_free_roots(struct kvm_vcpu *vcpu) { int i; -- cgit v1.2.3 From 131d82791b628d4aeafd94ddc74a9b68f3d15a83 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 29 May 2008 14:56:28 +0300 Subject: KVM: MMU: Avoid page prefetch on SVM SVM cannot benefit from page prefetching since guest page fault bypass cannot by made to work there. Avoid accessing the guest page table in this case. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 62741b7c422..5ebb2788bd7 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -850,7 +850,10 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, hlist_add_head(&sp->hash_link, bucket); if (!metaphysical) rmap_write_protect(vcpu->kvm, gfn); - vcpu->arch.mmu.prefetch_page(vcpu, sp); + if (shadow_trap_nonpresent_pte != shadow_notrap_nonpresent_pte) + vcpu->arch.mmu.prefetch_page(vcpu, sp); + else + nonpaging_prefetch_page(vcpu, sp); return sp; } -- cgit v1.2.3 From 92760499d01ef91518119908eb9b8798b6c9bd3f Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 30 May 2008 16:05:53 +0200 Subject: KVM: kvm_io_device: extend in_range() to manage len and write attribute Modify member in_range() of structure kvm_io_device to pass length and the type of the I/O (write or read). This modification allows to use kvm_io_device with coalesced MMIO. Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/ia64/kvm/kvm-ia64.c | 6 +++--- arch/x86/kvm/i8254.c | 6 ++++-- arch/x86/kvm/i8259.c | 3 ++- arch/x86/kvm/lapic.c | 3 ++- arch/x86/kvm/x86.c | 28 +++++++++++++++++----------- 5 files changed, 28 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 7c504be5797..bb58df7cc41 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -195,11 +195,11 @@ int kvm_dev_ioctl_check_extension(long ext) } static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, - gpa_t addr) + gpa_t addr, int len, int is_write) { struct kvm_io_device *dev; - dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); + dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write); return dev; } @@ -231,7 +231,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) kvm_run->exit_reason = KVM_EXIT_MMIO; return 0; mmio: - mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr); + mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir); if (mmio_dev) { if (!p->dir) kvm_iodevice_write(mmio_dev, p->addr, p->size, diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 60074dc66bd..9e3391e9a1b 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -460,7 +460,8 @@ static void pit_ioport_read(struct kvm_io_device *this, mutex_unlock(&pit_state->lock); } -static int pit_in_range(struct kvm_io_device *this, gpa_t addr) +static int pit_in_range(struct kvm_io_device *this, gpa_t addr, + int len, int is_write) { return ((addr >= KVM_PIT_BASE_ADDRESS) && (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); @@ -501,7 +502,8 @@ static void speaker_ioport_read(struct kvm_io_device *this, mutex_unlock(&pit_state->lock); } -static int speaker_in_range(struct kvm_io_device *this, gpa_t addr) +static int speaker_in_range(struct kvm_io_device *this, gpa_t addr, + int len, int is_write) { return (addr == KVM_SPEAKER_BASE_ADDRESS); } diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index ab29cf2def4..5857f59ad4a 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -346,7 +346,8 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1) return s->elcr; } -static int picdev_in_range(struct kvm_io_device *this, gpa_t addr) +static int picdev_in_range(struct kvm_io_device *this, gpa_t addr, + int len, int is_write) { switch (addr) { case 0x20: diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e48d1939403..180ba7316da 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -785,7 +785,8 @@ static void apic_mmio_write(struct kvm_io_device *this, } -static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr) +static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr, + int len, int size) { struct kvm_lapic *apic = (struct kvm_lapic *)this->private; int ret = 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4c94fad7f01..ab3f5552d69 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1797,13 +1797,14 @@ static void kvm_init_msr_list(void) * Only apic need an MMIO device hook, so shortcut now.. */ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, - gpa_t addr) + gpa_t addr, int len, + int is_write) { struct kvm_io_device *dev; if (vcpu->arch.apic) { dev = &vcpu->arch.apic->dev; - if (dev->in_range(dev, addr)) + if (dev->in_range(dev, addr, len, is_write)) return dev; } return NULL; @@ -1811,13 +1812,15 @@ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, - gpa_t addr) + gpa_t addr, int len, + int is_write) { struct kvm_io_device *dev; - dev = vcpu_find_pervcpu_dev(vcpu, addr); + dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write); if (dev == NULL) - dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); + dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, + is_write); return dev; } @@ -1885,7 +1888,7 @@ mmio: * Is this MMIO handled locally? */ mutex_lock(&vcpu->kvm->lock); - mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); + mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0); if (mmio_dev) { kvm_iodevice_read(mmio_dev, gpa, bytes, val); mutex_unlock(&vcpu->kvm->lock); @@ -1940,7 +1943,7 @@ mmio: * Is this MMIO handled locally? */ mutex_lock(&vcpu->kvm->lock); - mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); + mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1); if (mmio_dev) { kvm_iodevice_write(mmio_dev, gpa, bytes, val); mutex_unlock(&vcpu->kvm->lock); @@ -2317,9 +2320,10 @@ static void pio_string_write(struct kvm_io_device *pio_dev, } static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, - gpa_t addr) + gpa_t addr, int len, + int is_write) { - return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr); + return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write); } int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, @@ -2351,7 +2355,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, kvm_x86_ops->skip_emulated_instruction(vcpu); - pio_dev = vcpu_find_pio_dev(vcpu, port); + pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in); if (pio_dev) { kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data); complete_pio(vcpu); @@ -2433,7 +2437,9 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, } } - pio_dev = vcpu_find_pio_dev(vcpu, port); + pio_dev = vcpu_find_pio_dev(vcpu, port, + vcpu->arch.pio.cur_count, + !vcpu->arch.pio.in); if (!vcpu->arch.pio.in) { /* string PIO write */ ret = pio_copy_data(vcpu); -- cgit v1.2.3 From 542472b53ea9e0add0ba23976018210191d84754 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 30 May 2008 16:05:55 +0200 Subject: KVM: Add coalesced MMIO support (x86 part) This patch enables coalesced MMIO for x86 architecture. It defines KVM_MMIO_PAGE_OFFSET and KVM_CAP_COALESCED_MMIO. It enables the compilation of coalesced_mmio.c. Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/x86/kvm/Makefile | 3 ++- arch/x86/kvm/x86.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index c97d35c218d..d0e940bb6f4 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -2,7 +2,8 @@ # Makefile for Kernel-based Virtual Machine module # -common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o) +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ + coalesced_mmio.o) ifeq ($(CONFIG_KVM_TRACE),y) common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) endif diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ab3f5552d69..d731d4fff1a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -885,6 +885,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MP_STATE: r = 1; break; + case KVM_CAP_COALESCED_MMIO: + r = KVM_COALESCED_MMIO_PAGE_OFFSET; + break; case KVM_CAP_VAPIC: r = !kvm_x86_ops->cpu_has_accelerated_tpr(); break; -- cgit v1.2.3 From 588968b6b7d34e6a88f538d1db9aca47b203623e Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 30 May 2008 16:05:56 +0200 Subject: KVM: Add coalesced MMIO support (powerpc part) This patch enables coalesced MMIO for powerpc architecture. It defines KVM_MMIO_PAGE_OFFSET and KVM_CAP_COALESCED_MMIO. It enables the compilation of coalesced_mmio.c. Signed-off-by: Laurent Vivier Signed-off-by: Avi Kivity --- arch/powerpc/kvm/Makefile | 2 +- arch/powerpc/kvm/powerpc.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index d0d358d367e..04e3449e1f4 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -4,7 +4,7 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm -common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o) +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) kvm-objs := $(common-objs) powerpc.o emulate.o booke_guest.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0513b359851..b850d249702 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -145,6 +145,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_USER_MEMORY: r = 1; break; + case KVM_CAP_COALESCED_MMIO: + r = KVM_COALESCED_MMIO_PAGE_OFFSET; + break; default: r = 0; break; -- cgit v1.2.3 From 7f39f8ac177db258200053074aa7a3d98656b1cf Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 30 May 2008 16:05:57 +0200 Subject: KVM: Add coalesced MMIO support (ia64 part) This patch enables coalesced MMIO for ia64 architecture. It defines KVM_MMIO_PAGE_OFFSET and KVM_CAP_COALESCED_MMIO. It enables the compilation of coalesced_mmio.c. [akpm: fix compile error on ia64] Signed-off-by: Laurent Vivier Signed-off-by: Andrew Morton Signed-off-by: Avi Kivity --- arch/ia64/kvm/Makefile | 3 ++- arch/ia64/kvm/kvm-ia64.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index 112791dd254..bf22fb9e6dc 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -43,7 +43,8 @@ $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/ EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/ -common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o) +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ + coalesced_mmio.o) kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index bb58df7cc41..9408b30576d 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -187,6 +187,9 @@ int kvm_dev_ioctl_check_extension(long ext) r = 1; break; + case KVM_CAP_COALESCED_MMIO: + r = KVM_COALESCED_MMIO_PAGE_OFFSET; + break; default: r = 0; } -- cgit v1.2.3 From 622395a9e63bf87a16faecf555ed02375cbae5b7 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Wed, 11 Jun 2008 19:52:53 -0300 Subject: KVM: only abort guest entry if timer count goes from 0->1 Only abort guest entry if the timer count went from 0->1, since for 1->2 or larger the bit will either be set already or a timer irq will have been injected. Using atomic_inc_and_test() for it also introduces an SMP barrier to the LAPIC version (thought it was unecessary because of timer migration, but guest can be scheduled to a different pCPU between exit and kvm_vcpu_block(), so there is the possibility for a race). Noticed by Avi. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/i8254.c | 11 ++++------- arch/x86/kvm/lapic.c | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 9e3391e9a1b..c0f7872a912 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -198,14 +198,11 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps) struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0]; struct kvm_kpit_timer *pt = &ps->pit_timer; - atomic_inc(&pt->pending); - smp_mb__after_atomic_inc(); - if (vcpu0) { + if (!atomic_inc_and_test(&pt->pending)) set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests); - if (waitqueue_active(&vcpu0->wq)) { - vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; - wake_up_interruptible(&vcpu0->wq); - } + if (vcpu0 && waitqueue_active(&vcpu0->wq)) { + vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; + wake_up_interruptible(&vcpu0->wq); } pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 180ba7316da..73f43de69f6 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -945,8 +945,8 @@ static int __apic_timer_fn(struct kvm_lapic *apic) int result = 0; wait_queue_head_t *q = &apic->vcpu->wq; - atomic_inc(&apic->timer.pending); - set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests); + if(!atomic_inc_and_test(&apic->timer.pending)) + set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests); if (waitqueue_active(q)) { apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; wake_up_interruptible(q); -- cgit v1.2.3 From 25be46080f1a446cb2bda3daadbd22a5682b955e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 10 Jun 2008 10:46:53 -0300 Subject: KVM: Do not calculate linear rip in emulation failure report If we're not gonna do anything (case in which failure is already reported), we do not need to even bother with calculating the linear rip. Signed-off-by: Glauber Costa Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d731d4fff1a..5d21bb69d88 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2081,11 +2081,11 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) unsigned long rip = vcpu->arch.rip; unsigned long rip_linear; - rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); - if (reported) return; + rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); + emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu); printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", -- cgit v1.2.3 From f76c710d759250a43976bcfcab6af6ebb94b7dc2 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 13 Jun 2008 22:45:42 +0300 Subject: KVM: Use printk_rlimit() instead of reporting emulation failures just once Emulation failure reports are useful, so allow more than one per the lifetime of the module. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5d21bb69d88..d1db5aa5c7f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2076,12 +2076,11 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) { - static int reported; u8 opcodes[4]; unsigned long rip = vcpu->arch.rip; unsigned long rip_linear; - if (reported) + if (!printk_ratelimit()) return; rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); @@ -2090,7 +2089,6 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); - reported = 1; } EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); -- cgit v1.2.3 From b13354f8f092884fa8d79472404de4907b25d579 Mon Sep 17 00:00:00 2001 From: Mohammed Gamal Date: Sun, 15 Jun 2008 19:37:38 +0300 Subject: KVM: x86 emulator: emulate nop and xchg reg, acc (opcodes 0x90 - 0x97) Signed-off-by: Mohammed Gamal Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index b90857c7656..28082913919 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -140,8 +140,9 @@ static u16 opcode_table[256] = { ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ModRM | DstReg, DstReg | SrcMem | ModRM | Mov, Group | Group1A, - /* 0x90 - 0x9F */ - 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x90 - 0x97 */ + DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, + /* 0x98 - 0x9F */ 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, /* 0xA0 - 0xA7 */ ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, @@ -1493,6 +1494,7 @@ special_insn: emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); break; case 0x86 ... 0x87: /* xchg */ + xchg: /* Write back the register source. */ switch (c->dst.bytes) { case 1: @@ -1560,6 +1562,17 @@ special_insn: if (rc != 0) goto done; break; + case 0x90: /* nop / xchg r8,rax */ + if (!(c->rex_prefix & 1)) { /* nop */ + c->dst.type = OP_NONE; + break; + } + case 0x91 ... 0x97: /* xchg reg,rax */ + c->src.type = c->dst.type = OP_REG; + c->src.bytes = c->dst.bytes = c->op_bytes; + c->src.ptr = (unsigned long *) &c->regs[VCPU_REGS_RAX]; + c->src.val = *(c->src.ptr); + goto xchg; case 0x9c: /* pushf */ c->src.val = (unsigned long) ctxt->eflags; emulate_push(ctxt); -- cgit v1.2.3 From 8684c0af0b2bab770c257e2a04e1546eed35fa56 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Jun 2008 21:13:41 -0700 Subject: KVM: x86 emulator: handle undecoded rex.b with r/m = 5 in certain cases x86_64 does not decode rex.b in certain cases, where the r/m field = 5. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 28082913919..3721cfddc97 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -750,6 +750,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, switch (base_reg) { case 5: + case 13: if (c->modrm_mod != 0) c->modrm_ea += c->regs[base_reg]; else @@ -767,6 +768,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, } break; case 5: + case 13: if (c->modrm_mod != 0) c->modrm_ea += c->regs[c->modrm_rm]; else if (ctxt->mode == X86EMUL_MODE_PROT64) -- cgit v1.2.3 From dc71d0f1620790ec8e54101ca37e7b31e31208a8 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Jun 2008 21:23:17 -0700 Subject: KVM: x86 emulator: simplify sib decoding Instead of using sparse switches, use simpler if/else sequences. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 3721cfddc97..ca7ab2469a4 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -748,24 +748,12 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, base_reg |= sib & 7; scale = sib >> 6; - switch (base_reg) { - case 5: - case 13: - if (c->modrm_mod != 0) - c->modrm_ea += c->regs[base_reg]; - else - c->modrm_ea += - insn_fetch(s32, 4, c->eip); - break; - default: + if ((base_reg & 7) == 5 && c->modrm_mod == 0) + c->modrm_ea += insn_fetch(s32, 4, c->eip); + else c->modrm_ea += c->regs[base_reg]; - } - switch (index_reg) { - case 4: - break; - default: + if (index_reg != 4) c->modrm_ea += c->regs[index_reg] << scale; - } break; case 5: case 13: -- cgit v1.2.3 From 84411d85dacdb6665578608c6a70fc8b819761a8 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Jun 2008 21:53:26 -0700 Subject: KVM: x86 emulator: simplify r/m decoding Consolidate the duplicated code when not in any special case. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index ca7ab2469a4..c3a823174f3 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -740,9 +740,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, c->modrm_ea = (u16)c->modrm_ea; } else { /* 32/64-bit ModR/M decode. */ - switch (c->modrm_rm) { - case 4: - case 12: + if ((c->modrm_rm & 7) == 4) { sib = insn_fetch(u8, 1, c->eip); index_reg |= (sib >> 3) & 7; base_reg |= sib & 7; @@ -754,18 +752,11 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, c->modrm_ea += c->regs[base_reg]; if (index_reg != 4) c->modrm_ea += c->regs[index_reg] << scale; - break; - case 5: - case 13: - if (c->modrm_mod != 0) - c->modrm_ea += c->regs[c->modrm_rm]; - else if (ctxt->mode == X86EMUL_MODE_PROT64) + } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) { + if (ctxt->mode == X86EMUL_MODE_PROT64) rip_relative = 1; - break; - default: + } else c->modrm_ea += c->regs[c->modrm_rm]; - break; - } switch (c->modrm_mod) { case 0: if (c->modrm_rm == 5) -- cgit v1.2.3 From f5b4edcd52e78556800f90d08bfc9126416ac82f Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Jun 2008 22:09:11 -0700 Subject: KVM: x86 emulator: simplify rip relative decoding rip relative decoding is relative to the instruction pointer of the next instruction; by moving address adjustment until after decoding is complete, we remove the need to determine the instruction size. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index c3a823174f3..20b604489c3 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -664,7 +664,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, { struct decode_cache *c = &ctxt->decode; u8 sib; - int index_reg = 0, base_reg = 0, scale, rip_relative = 0; + int index_reg = 0, base_reg = 0, scale; int rc = 0; if (c->rex_prefix) { @@ -754,7 +754,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, c->modrm_ea += c->regs[index_reg] << scale; } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) { if (ctxt->mode == X86EMUL_MODE_PROT64) - rip_relative = 1; + c->rip_relative = 1; } else c->modrm_ea += c->regs[c->modrm_rm]; switch (c->modrm_mod) { @@ -770,22 +770,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, break; } } - if (rip_relative) { - c->modrm_ea += c->eip; - switch (c->d & SrcMask) { - case SrcImmByte: - c->modrm_ea += 1; - break; - case SrcImm: - if (c->d & ByteOp) - c->modrm_ea += 1; - else - if (c->op_bytes == 8) - c->modrm_ea += 4; - else - c->modrm_ea += c->op_bytes; - } - } done: return rc; } @@ -1044,6 +1028,9 @@ done_prefixes: break; } + if (c->rip_relative) + c->modrm_ea += c->eip; + done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } -- cgit v1.2.3 From 0adc8675d645940139d12477e5e05b8a0a7a1117 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Jun 2008 22:45:54 -0700 Subject: KVM: x86 emulator: avoid segment base adjust for lea Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 20b604489c3..38926b7da64 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -940,7 +940,7 @@ done_prefixes: c->override_base != &ctxt->gs_base) c->override_base = NULL; - if (c->override_base) + if (c->override_base && !(!c->twobyte && c->b == 0x8d)) c->modrm_ea += *c->override_base; if (c->ad_bytes != 8) -- cgit v1.2.3 From 7a5b56dfd3a682a51fc84682290d5147872a8e99 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 22 Jun 2008 16:22:51 +0300 Subject: KVM: x86 emulator: lazily evaluate segment registers Instead of prefetching all segment bases before emulation, read them at the last moment. Since most of them are unneeded, we save some cycles on Intel machines where this is a bit expensive. Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 21 ---------- arch/x86/kvm/x86_emulate.c | 96 +++++++++++++++++++++++++++------------------- 2 files changed, 57 insertions(+), 60 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d1db5aa5c7f..f726ba79fd3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2126,27 +2126,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu, ? X86EMUL_MODE_PROT64 : cs_db ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; - if (vcpu->arch.emulate_ctxt.mode == X86EMUL_MODE_PROT64) { - vcpu->arch.emulate_ctxt.cs_base = 0; - vcpu->arch.emulate_ctxt.ds_base = 0; - vcpu->arch.emulate_ctxt.es_base = 0; - vcpu->arch.emulate_ctxt.ss_base = 0; - } else { - vcpu->arch.emulate_ctxt.cs_base = - get_segment_base(vcpu, VCPU_SREG_CS); - vcpu->arch.emulate_ctxt.ds_base = - get_segment_base(vcpu, VCPU_SREG_DS); - vcpu->arch.emulate_ctxt.es_base = - get_segment_base(vcpu, VCPU_SREG_ES); - vcpu->arch.emulate_ctxt.ss_base = - get_segment_base(vcpu, VCPU_SREG_SS); - } - - vcpu->arch.emulate_ctxt.gs_base = - get_segment_base(vcpu, VCPU_SREG_GS); - vcpu->arch.emulate_ctxt.fs_base = - get_segment_base(vcpu, VCPU_SREG_FS); - r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); /* Reject the instructions other than VMCALL/VMMCALL when diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 38926b7da64..18ca25c2d4a 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -522,6 +522,39 @@ static inline void jmp_rel(struct decode_cache *c, int rel) register_address_increment(c, &c->eip, rel); } +static void set_seg_override(struct decode_cache *c, int seg) +{ + c->has_seg_override = true; + c->seg_override = seg; +} + +static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg) +{ + if (ctxt->mode == X86EMUL_MODE_PROT64 && seg < VCPU_SREG_FS) + return 0; + + return kvm_x86_ops->get_segment_base(ctxt->vcpu, seg); +} + +static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt, + struct decode_cache *c) +{ + if (!c->has_seg_override) + return 0; + + return seg_base(ctxt, c->seg_override); +} + +static unsigned long es_base(struct x86_emulate_ctxt *ctxt) +{ + return seg_base(ctxt, VCPU_SREG_ES); +} + +static unsigned long ss_base(struct x86_emulate_ctxt *ctxt) +{ + return seg_base(ctxt, VCPU_SREG_SS); +} + static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, unsigned long linear, u8 *dest) @@ -735,8 +768,8 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, } if (c->modrm_rm == 2 || c->modrm_rm == 3 || (c->modrm_rm == 6 && c->modrm_mod != 0)) - if (!c->override_base) - c->override_base = &ctxt->ss_base; + if (!c->has_seg_override) + set_seg_override(c, VCPU_SREG_SS); c->modrm_ea = (u16)c->modrm_ea; } else { /* 32/64-bit ModR/M decode. */ @@ -807,6 +840,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) memset(c, 0, sizeof(struct decode_cache)); c->eip = ctxt->vcpu->arch.rip; + ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); switch (mode) { @@ -845,23 +879,15 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) /* switch between 2/4 bytes */ c->ad_bytes = def_ad_bytes ^ 6; break; + case 0x26: /* ES override */ case 0x2e: /* CS override */ - c->override_base = &ctxt->cs_base; - break; + case 0x36: /* SS override */ case 0x3e: /* DS override */ - c->override_base = &ctxt->ds_base; - break; - case 0x26: /* ES override */ - c->override_base = &ctxt->es_base; + set_seg_override(c, (c->b >> 3) & 3); break; case 0x64: /* FS override */ - c->override_base = &ctxt->fs_base; - break; case 0x65: /* GS override */ - c->override_base = &ctxt->gs_base; - break; - case 0x36: /* SS override */ - c->override_base = &ctxt->ss_base; + set_seg_override(c, c->b & 7); break; case 0x40 ... 0x4f: /* REX */ if (mode != X86EMUL_MODE_PROT64) @@ -933,15 +959,11 @@ done_prefixes: if (rc) goto done; - if (!c->override_base) - c->override_base = &ctxt->ds_base; - if (mode == X86EMUL_MODE_PROT64 && - c->override_base != &ctxt->fs_base && - c->override_base != &ctxt->gs_base) - c->override_base = NULL; + if (!c->has_seg_override) + set_seg_override(c, VCPU_SREG_DS); - if (c->override_base && !(!c->twobyte && c->b == 0x8d)) - c->modrm_ea += *c->override_base; + if (!(!c->twobyte && c->b == 0x8d)) + c->modrm_ea += seg_override_base(ctxt, c); if (c->ad_bytes != 8) c->modrm_ea = (u32)c->modrm_ea; @@ -1043,7 +1065,7 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt) c->dst.bytes = c->op_bytes; c->dst.val = c->src.val; register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); - c->dst.ptr = (void *) register_address(c, ctxt->ss_base, + c->dst.ptr = (void *) register_address(c, ss_base(ctxt), c->regs[VCPU_REGS_RSP]); } @@ -1053,7 +1075,7 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, struct decode_cache *c = &ctxt->decode; int rc; - rc = ops->read_std(register_address(c, ctxt->ss_base, + rc = ops->read_std(register_address(c, ss_base(ctxt), c->regs[VCPU_REGS_RSP]), &c->dst.val, c->dst.bytes, ctxt->vcpu); if (rc != 0) @@ -1375,11 +1397,11 @@ special_insn: register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); c->dst.ptr = (void *) register_address( - c, ctxt->ss_base, c->regs[VCPU_REGS_RSP]); + c, ss_base(ctxt), c->regs[VCPU_REGS_RSP]); break; case 0x58 ... 0x5f: /* pop reg */ pop_instruction: - if ((rc = ops->read_std(register_address(c, ctxt->ss_base, + if ((rc = ops->read_std(register_address(c, ss_base(ctxt), c->regs[VCPU_REGS_RSP]), c->dst.ptr, c->op_bytes, ctxt->vcpu)) != 0) goto done; @@ -1405,7 +1427,7 @@ special_insn: c->rep_prefix ? address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, (ctxt->eflags & EFLG_DF), - register_address(c, ctxt->es_base, + register_address(c, es_base(ctxt), c->regs[VCPU_REGS_RDI]), c->rep_prefix, c->regs[VCPU_REGS_RDX]) == 0) { @@ -1421,9 +1443,8 @@ special_insn: c->rep_prefix ? address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, (ctxt->eflags & EFLG_DF), - register_address(c, c->override_base ? - *c->override_base : - ctxt->ds_base, + register_address(c, + seg_override_base(ctxt, c), c->regs[VCPU_REGS_RSI]), c->rep_prefix, c->regs[VCPU_REGS_RDX]) == 0) { @@ -1559,11 +1580,10 @@ special_insn: c->dst.type = OP_MEM; c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.ptr = (unsigned long *)register_address(c, - ctxt->es_base, + es_base(ctxt), c->regs[VCPU_REGS_RDI]); if ((rc = ops->read_emulated(register_address(c, - c->override_base ? *c->override_base : - ctxt->ds_base, + seg_override_base(ctxt, c), c->regs[VCPU_REGS_RSI]), &c->dst.val, c->dst.bytes, ctxt->vcpu)) != 0) @@ -1579,8 +1599,7 @@ special_insn: c->src.type = OP_NONE; /* Disable writeback. */ c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->src.ptr = (unsigned long *)register_address(c, - c->override_base ? *c->override_base : - ctxt->ds_base, + seg_override_base(ctxt, c), c->regs[VCPU_REGS_RSI]); if ((rc = ops->read_emulated((unsigned long)c->src.ptr, &c->src.val, @@ -1591,7 +1610,7 @@ special_insn: c->dst.type = OP_NONE; /* Disable writeback. */ c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.ptr = (unsigned long *)register_address(c, - ctxt->es_base, + es_base(ctxt), c->regs[VCPU_REGS_RDI]); if ((rc = ops->read_emulated((unsigned long)c->dst.ptr, &c->dst.val, @@ -1615,7 +1634,7 @@ special_insn: c->dst.type = OP_MEM; c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.ptr = (unsigned long *)register_address(c, - ctxt->es_base, + es_base(ctxt), c->regs[VCPU_REGS_RDI]); c->dst.val = c->regs[VCPU_REGS_RAX]; register_address_increment(c, &c->regs[VCPU_REGS_RDI], @@ -1627,8 +1646,7 @@ special_insn: c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; if ((rc = ops->read_emulated(register_address(c, - c->override_base ? *c->override_base : - ctxt->ds_base, + seg_override_base(ctxt, c), c->regs[VCPU_REGS_RSI]), &c->dst.val, c->dst.bytes, -- cgit v1.2.3 From 6ada8cca79cb971f5da7d1756f4f9292e3ef1e03 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 22 Jun 2008 16:45:24 +0300 Subject: KVM: MMU: When debug is enabled, make it a run-time parameter Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 5ebb2788bd7..5994645dcee 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -66,7 +66,8 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {} #endif #if defined(MMU_DEBUG) || defined(AUDIT) -static int dbg = 1; +static int dbg = 0; +module_param(dbg, bool, 0644); #endif #ifndef MMU_DEBUG -- cgit v1.2.3 From db475c39eca0f2e44953d96e768d7ce808ab85bd Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 22 Jun 2008 16:46:22 +0300 Subject: KVM: MMU: Fix printk format Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 5994645dcee..1fd8e3b58cc 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1116,7 +1116,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, mark_page_dirty(vcpu->kvm, gfn); pgprintk("%s: setting spte %llx\n", __func__, spte); - pgprintk("instantiating %s PTE (%s) at %d (%llx) addr %llx\n", + pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n", (spte&PT_PAGE_SIZE_MASK)? "2MB" : "4kB", (spte&PT_WRITABLE_MASK)?"RW":"R", gfn, spte, shadow_pte); set_shadow_pte(shadow_pte, spte); -- cgit v1.2.3 From 65267ea1b3e768dc54b63cd7fad520d89c27d350 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 18 Jun 2008 14:43:38 +0800 Subject: KVM: VMX: Fix a wrong usage of vmcs_config The function ept_update_paging_mode_cr0() write to CPU_BASED_VM_EXEC_CONTROL based on vmcs_config.cpu_based_exec_ctrl. That's wrong because the variable may not consistent with the content in the CPU_BASE_VM_EXEC_CONTROL MSR. Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1bb99465720..6a3a4038f3b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1441,7 +1441,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, if (!(cr0 & X86_CR0_PG)) { /* From paging/starting to nonpaging */ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, - vmcs_config.cpu_based_exec_ctrl | + vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) | (CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING)); vcpu->arch.cr0 = cr0; @@ -1451,7 +1451,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, } else if (!is_paging(vcpu)) { /* From nonpaging to paging */ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, - vmcs_config.cpu_based_exec_ctrl & + vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) & ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING)); vcpu->arch.cr0 = cr0; -- cgit v1.2.3 From efa67e0d1f51842393606034051d805ab9948abd Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Fri, 20 Jun 2008 09:51:30 +0200 Subject: KVM: VMX: Fake emulate Intel perfctr MSRs Older linux guests (in this case, 2.6.9) can attempt to access the performance counter MSRs without a fixup section, and injecting a GPF kills the guest. Work around by allowing the guest to write those MSRs. Tested by me on RHEL-4 i386 and x86_64 guests, as well as F-9 guests. Signed-off-by: Chris Lalancette Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 6a3a4038f3b..d493a97e788 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -920,6 +920,18 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) break; case MSR_IA32_TIME_STAMP_COUNTER: guest_write_tsc(data); + break; + case MSR_P6_PERFCTR0: + case MSR_P6_PERFCTR1: + case MSR_P6_EVNTSEL0: + case MSR_P6_EVNTSEL1: + /* + * Just discard all writes to the performance counters; this + * should keep both older linux and windows 64-bit guests + * happy + */ + pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", msr_index, data); + break; default: vmx_load_host_state(vmx); -- cgit v1.2.3 From f8b78fa3d406f3a2dc038e2b47749013a9295994 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 23 Jun 2008 12:04:25 -0300 Subject: KVM: move slots_lock acquision down to vapic_exit There is no need to grab slots_lock if the vapic_page will not be touched. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f726ba79fd3..55906e4c467 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2787,8 +2787,10 @@ static void vapic_exit(struct kvm_vcpu *vcpu) if (!apic || !apic->vapic_addr) return; + down_read(&vcpu->kvm->slots_lock); kvm_release_page_dirty(apic->vapic_page); mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); + up_read(&vcpu->kvm->slots_lock); } static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -2944,9 +2946,7 @@ out: post_kvm_run_save(vcpu, kvm_run); - down_read(&vcpu->kvm->slots_lock); vapic_exit(vcpu); - up_read(&vcpu->kvm->slots_lock); return r; } -- cgit v1.2.3 From dfdded7c41e5b68c79a9f8a942d41f56bc265ba4 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Fri, 27 Jun 2008 15:05:34 +0200 Subject: KVM: Fix memory leak on guest exit This patch fixes a memory leak, we want to free the physmem when destroying the vm. Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- arch/s390/kvm/kvm-s390.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 4585c8ac2b0..b802ce6f675 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -194,6 +194,7 @@ out_nokvm: void kvm_arch_destroy_vm(struct kvm *kvm) { debug_unregister(kvm->arch.dbf); + kvm_free_physmem(kvm); free_page((unsigned long)(kvm->arch.sca)); kfree(kvm); module_put(THIS_MODULE); -- cgit v1.2.3 From 4da29e909ea8087de09e27476f91f51a070cabe8 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 27 Jun 2008 15:05:38 +0200 Subject: KVM: s390: Set guest storage limit and offset to sane values Some machines do not accept 16EB as guest storage limit. Lets change the default for the guest storage limit to a sane value. We also should set the guest_origin to what userspace thinks it is. This allows guests starting at an address != 0. Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- arch/s390/kvm/kvm-s390.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index b802ce6f675..cdab57c5bc7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -247,11 +247,16 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gbea = 1; } +/* The current code can have up to 256 pages for virtio */ +#define VIRTIODESCSPACE (256ul * 4096ul) + int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH); - vcpu->arch.sie_block->gmslm = 0xffffffffffUL; - vcpu->arch.sie_block->gmsor = 0x000000000000; + vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize + + vcpu->kvm->arch.guest_origin + + VIRTIODESCSPACE - 1ul; + vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; vcpu->arch.sie_block->ecb = 2; vcpu->arch.sie_block->eca = 0xC1002001U; setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup, -- cgit v1.2.3 From 180c12fb22bd17c7187ae1bce023d24a42b2980c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 27 Jun 2008 15:05:40 +0200 Subject: KVM: s390: rename private structures While doing some tests with our lcrash implementation I have seen a naming conflict with prefix_info in kvm_host.h vs. addrconf.h To avoid future conflicts lets rename private definitions in asm/kvm_host.h by adding the kvm_s390 prefix. Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- arch/s390/kvm/interrupt.c | 32 ++++++++++++++++---------------- arch/s390/kvm/kvm-s390.c | 3 ++- arch/s390/kvm/priv.c | 2 +- arch/s390/kvm/sigp.c | 20 ++++++++++---------- 4 files changed, 29 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 84a7fed4cd4..11230b0db95 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -31,7 +31,7 @@ static int psw_interrupts_disabled(struct kvm_vcpu *vcpu) } static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu, - struct interrupt_info *inti) + struct kvm_s390_interrupt_info *inti) { switch (inti->type) { case KVM_S390_INT_EMERGENCY: @@ -91,7 +91,7 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag) } static void __set_intercept_indicator(struct kvm_vcpu *vcpu, - struct interrupt_info *inti) + struct kvm_s390_interrupt_info *inti) { switch (inti->type) { case KVM_S390_INT_EMERGENCY: @@ -111,7 +111,7 @@ static void __set_intercept_indicator(struct kvm_vcpu *vcpu, } static void __do_deliver_interrupt(struct kvm_vcpu *vcpu, - struct interrupt_info *inti) + struct kvm_s390_interrupt_info *inti) { const unsigned short table[] = { 2, 4, 4, 6 }; int rc, exception = 0; @@ -290,9 +290,9 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu) int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) { - struct local_interrupt *li = &vcpu->arch.local_int; - struct float_interrupt *fi = vcpu->arch.local_int.float_int; - struct interrupt_info *inti; + struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; + struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; + struct kvm_s390_interrupt_info *inti; int rc = 0; if (atomic_read(&li->active)) { @@ -408,9 +408,9 @@ void kvm_s390_idle_wakeup(unsigned long data) void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) { - struct local_interrupt *li = &vcpu->arch.local_int; - struct float_interrupt *fi = vcpu->arch.local_int.float_int; - struct interrupt_info *n, *inti = NULL; + struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; + struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; + struct kvm_s390_interrupt_info *n, *inti = NULL; int deliver; __reset_intercept_indicators(vcpu); @@ -465,8 +465,8 @@ void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code) { - struct local_interrupt *li = &vcpu->arch.local_int; - struct interrupt_info *inti; + struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; + struct kvm_s390_interrupt_info *inti; inti = kzalloc(sizeof(*inti), GFP_KERNEL); if (!inti) @@ -487,9 +487,9 @@ int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code) int kvm_s390_inject_vm(struct kvm *kvm, struct kvm_s390_interrupt *s390int) { - struct local_interrupt *li; - struct float_interrupt *fi; - struct interrupt_info *inti; + struct kvm_s390_local_interrupt *li; + struct kvm_s390_float_interrupt *fi; + struct kvm_s390_interrupt_info *inti; int sigcpu; inti = kzalloc(sizeof(*inti), GFP_KERNEL); @@ -544,8 +544,8 @@ int kvm_s390_inject_vm(struct kvm *kvm, int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_interrupt *s390int) { - struct local_interrupt *li; - struct interrupt_info *inti; + struct kvm_s390_local_interrupt *li; + struct kvm_s390_interrupt_info *inti; inti = kzalloc(sizeof(*inti), GFP_KERNEL); if (!inti) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index cdab57c5bc7..399acf3f64d 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -275,7 +275,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, if (!vcpu) goto out_nomem; - vcpu->arch.sie_block = (struct sie_block *) get_zeroed_page(GFP_KERNEL); + vcpu->arch.sie_block = (struct kvm_s390_sie_block *) + get_zeroed_page(GFP_KERNEL); if (!vcpu->arch.sie_block) goto out_free_cpu; diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index c02286c6a93..2e2d2ffb6a0 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -199,7 +199,7 @@ out: static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem) { - struct float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; int cpus = 0; int n; diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 0a236acfb5f..5a556114eaa 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -45,7 +45,7 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg) { - struct float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; int rc; if (cpu_addr >= KVM_MAX_VCPUS) @@ -71,9 +71,9 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg) static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) { - struct float_interrupt *fi = &vcpu->kvm->arch.float_int; - struct local_interrupt *li; - struct interrupt_info *inti; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_local_interrupt *li; + struct kvm_s390_interrupt_info *inti; int rc; if (cpu_addr >= KVM_MAX_VCPUS) @@ -108,9 +108,9 @@ unlock: static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store) { - struct float_interrupt *fi = &vcpu->kvm->arch.float_int; - struct local_interrupt *li; - struct interrupt_info *inti; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_local_interrupt *li; + struct kvm_s390_interrupt_info *inti; int rc; if (cpu_addr >= KVM_MAX_VCPUS) @@ -169,9 +169,9 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, u64 *reg) { - struct float_interrupt *fi = &vcpu->kvm->arch.float_int; - struct local_interrupt *li; - struct interrupt_info *inti; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_local_interrupt *li; + struct kvm_s390_interrupt_info *inti; int rc; u8 tmp; -- cgit v1.2.3 From 0da1db75a2feca54564add30828bab658982481c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 2 Jul 2008 16:02:11 +0200 Subject: KVM: SVM: fix suspend/resume support On suspend the svm_hardware_disable function is called which frees all svm_data variables. On resume they are not re-allocated. This patch removes the deallocation of svm_data from the hardware_disable function to the hardware_unsetup function which is not called on suspend. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 238e8f3afaf..858e2970223 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -272,19 +272,11 @@ static int has_svm(void) static void svm_hardware_disable(void *garbage) { - struct svm_cpu_data *svm_data - = per_cpu(svm_data, raw_smp_processor_id()); - - if (svm_data) { - uint64_t efer; + uint64_t efer; - wrmsrl(MSR_VM_HSAVE_PA, 0); - rdmsrl(MSR_EFER, efer); - wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); - per_cpu(svm_data, raw_smp_processor_id()) = NULL; - __free_page(svm_data->save_area); - kfree(svm_data); - } + wrmsrl(MSR_VM_HSAVE_PA, 0); + rdmsrl(MSR_EFER, efer); + wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); } static void svm_hardware_enable(void *garbage) @@ -323,6 +315,19 @@ static void svm_hardware_enable(void *garbage) page_to_pfn(svm_data->save_area) << PAGE_SHIFT); } +static void svm_cpu_uninit(int cpu) +{ + struct svm_cpu_data *svm_data + = per_cpu(svm_data, raw_smp_processor_id()); + + if (!svm_data) + return; + + per_cpu(svm_data, raw_smp_processor_id()) = NULL; + __free_page(svm_data->save_area); + kfree(svm_data); +} + static int svm_cpu_init(int cpu) { struct svm_cpu_data *svm_data; @@ -460,6 +465,11 @@ err: static __exit void svm_hardware_unsetup(void) { + int cpu; + + for_each_online_cpu(cpu) + svm_cpu_uninit(cpu); + __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); iopm_base = 0; } -- cgit v1.2.3 From 7e37c2998a5a0b00134f6227167694b710f57ac0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 1 Jul 2008 01:19:19 +0300 Subject: x86: KVM guest: make kvm_smp_prepare_boot_cpu() static This patch makes the needlessly global kvm_smp_prepare_boot_cpu() static. Signed-off-by: Adrian Bunk Signed-off-by: Avi Kivity --- arch/x86/kernel/kvmclock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 87edf1ceb1d..d02def06ca9 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -113,7 +113,7 @@ static void kvm_setup_secondary_clock(void) #endif #ifdef CONFIG_SMP -void __init kvm_smp_prepare_boot_cpu(void) +static void __init kvm_smp_prepare_boot_cpu(void) { WARN_ON(kvm_register_clock("primary cpu clock")); native_smp_prepare_boot_cpu(); -- cgit v1.2.3 From 5a4c92880493945678315a6df810f7a21f55b985 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 3 Jul 2008 18:33:02 -0300 Subject: KVM: mmu_shrink: kvm_mmu_zap_page requires slots_lock to be held kvm_mmu_zap_page() needs slots lock held (rmap_remove->gfn_to_memslot, for example). Since kvm_lock spinlock is held in mmu_shrink(), do a non-blocking down_read_trylock(). Untested. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1fd8e3b58cc..ff7cf632175 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1987,6 +1987,8 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) list_for_each_entry(kvm, &vm_list, vm_list) { int npages; + if (!down_read_trylock(&kvm->slots_lock)) + continue; spin_lock(&kvm->mmu_lock); npages = kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages; @@ -1999,6 +2001,7 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) nr_to_scan--; spin_unlock(&kvm->mmu_lock); + up_read(&kvm->slots_lock); } if (kvm_freed) list_move_tail(&kvm_freed->vm_list, &vm_list); -- cgit v1.2.3 From 4e1096d27f3d095735c1c69c7b0a26a06a0d454e Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Sun, 6 Jul 2008 19:16:51 +0800 Subject: KVM: VMX: Add ept_sync_context in flush_tlb Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table. Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d493a97e788..fff3b490976 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -91,6 +91,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) } static int init_rmode(struct kvm *kvm); +static u64 construct_eptp(unsigned long root_hpa); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); @@ -1422,6 +1423,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu) static void vmx_flush_tlb(struct kvm_vcpu *vcpu) { vpid_sync_vcpu_all(to_vmx(vcpu)); + if (vm_need_ept()) + ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa)); } static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) -- cgit v1.2.3 From ac9f6dc0db0b5582ebf8bb720d7c41c3d2159013 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 6 Jul 2008 15:48:31 +0300 Subject: KVM: Apply the kernel sigmask to vcpus blocked due to being uninitialized Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 55906e4c467..89fc8565ede 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2958,15 +2958,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu_load(vcpu); + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); + if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { kvm_vcpu_block(vcpu); - vcpu_put(vcpu); - return -EAGAIN; + r = -EAGAIN; + goto out; } - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); - /* re-sync apic's tpr */ if (!irqchip_in_kernel(vcpu->kvm)) kvm_set_cr8(vcpu, kvm_run->cr8); -- cgit v1.2.3 From 19fdfa0d133ae216e9d1c69a8333fe63fcf8e584 Mon Sep 17 00:00:00 2001 From: Mohammed Gamal Date: Sun, 6 Jul 2008 16:51:26 +0300 Subject: KVM: x86 emulator: Fix HLT instruction This patch fixes issue encountered with HLT instruction under FreeDOS's HIMEM XMS Driver. The HLT instruction jumped directly to the done label and skips updating the EIP value, therefore causing the guest to spin endlessly on the same instruction. The patch changes the instruction so that it writes back the updated EIP value. Signed-off-by: Mohammed Gamal Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 18ca25c2d4a..8bc63f62fbb 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -1731,7 +1731,7 @@ special_insn: break; case 0xf4: /* hlt */ ctxt->vcpu->arch.halt_request = 1; - goto done; + break; case 0xf5: /* cmc */ /* complement carry flag from eflags reg */ ctxt->eflags ^= EFLG_CF; -- cgit v1.2.3 From c65bbfa1d693d375da51f9c8aa9fb26f09fa19ed Mon Sep 17 00:00:00 2001 From: Ben-Ami Yassour Date: Sun, 6 Jul 2008 17:15:07 +0300 Subject: KVM: check injected pic irq within valid pic irqs Check that an injected pic irq is between 0 and 15. Signed-off-by: Ben-Ami Yassour Signed-off-by: Avi Kivity --- arch/x86/kvm/i8259.c | 6 ++++-- arch/x86/kvm/irq.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 5857f59ad4a..c31164e8aa4 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -130,8 +130,10 @@ void kvm_pic_set_irq(void *opaque, int irq, int level) { struct kvm_pic *s = opaque; - pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); - pic_update_irq(s); + if (irq >= 0 && irq < PIC_NUM_PINS) { + pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); + pic_update_irq(s); + } } /* diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 2a15be2275c..7ca47cbb48b 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h @@ -30,6 +30,8 @@ #include "ioapic.h" #include "lapic.h" +#define PIC_NUM_PINS 16 + struct kvm; struct kvm_vcpu; -- cgit v1.2.3 From d6e88aec07aa8f6c7e4024f5734ec659fd7c5a40 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 10 Jul 2008 16:53:33 +0300 Subject: KVM: Prefix some x86 low level function with kvm_, to avoid namespace issues Fixes compilation with CONFIG_VMI enabled. Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 12 ++++++------ arch/x86/kvm/vmx.c | 24 ++++++++++++------------ arch/x86/kvm/x86.c | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 858e2970223..b756e876dce 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1710,9 +1710,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) sync_lapic_to_cr8(vcpu); save_host_msrs(vcpu); - fs_selector = read_fs(); - gs_selector = read_gs(); - ldt_selector = read_ldt(); + fs_selector = kvm_read_fs(); + gs_selector = kvm_read_gs(); + ldt_selector = kvm_read_ldt(); svm->host_cr2 = kvm_read_cr2(); svm->host_dr6 = read_dr6(); svm->host_dr7 = read_dr7(); @@ -1845,9 +1845,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) write_dr7(svm->host_dr7); kvm_write_cr2(svm->host_cr2); - load_fs(fs_selector); - load_gs(gs_selector); - load_ldt(ldt_selector); + kvm_load_fs(fs_selector); + kvm_load_gs(gs_selector); + kvm_load_ldt(ldt_selector); load_host_msrs(vcpu); reload_tss(vcpu); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fff3b490976..0cac6370171 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -484,7 +484,7 @@ static void reload_tss(void) struct descriptor_table gdt; struct desc_struct *descs; - get_gdt(&gdt); + kvm_get_gdt(&gdt); descs = (void *)gdt.base; descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ load_TR_desc(); @@ -540,9 +540,9 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) * Set host fs and gs selectors. Unfortunately, 22.2.3 does not * allow segment selectors with cpl > 0 or ti == 1. */ - vmx->host_state.ldt_sel = read_ldt(); + vmx->host_state.ldt_sel = kvm_read_ldt(); vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; - vmx->host_state.fs_sel = read_fs(); + vmx->host_state.fs_sel = kvm_read_fs(); if (!(vmx->host_state.fs_sel & 7)) { vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); vmx->host_state.fs_reload_needed = 0; @@ -550,7 +550,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) vmcs_write16(HOST_FS_SELECTOR, 0); vmx->host_state.fs_reload_needed = 1; } - vmx->host_state.gs_sel = read_gs(); + vmx->host_state.gs_sel = kvm_read_gs(); if (!(vmx->host_state.gs_sel & 7)) vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); else { @@ -586,15 +586,15 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) ++vmx->vcpu.stat.host_state_reload; vmx->host_state.loaded = 0; if (vmx->host_state.fs_reload_needed) - load_fs(vmx->host_state.fs_sel); + kvm_load_fs(vmx->host_state.fs_sel); if (vmx->host_state.gs_ldt_reload_needed) { - load_ldt(vmx->host_state.ldt_sel); + kvm_load_ldt(vmx->host_state.ldt_sel); /* * If we have to reload gs, we must take care to * preserve our gs base. */ local_irq_save(flags); - load_gs(vmx->host_state.gs_sel); + kvm_load_gs(vmx->host_state.gs_sel); #ifdef CONFIG_X86_64 wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); #endif @@ -654,8 +654,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) * Linux uses per-cpu TSS and GDT, so set these when switching * processors. */ - vmcs_writel(HOST_TR_BASE, read_tr_base()); /* 22.2.4 */ - get_gdt(&dt); + vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ + kvm_get_gdt(&dt); vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */ rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); @@ -1943,8 +1943,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ - vmcs_write16(HOST_FS_SELECTOR, read_fs()); /* 22.2.4 */ - vmcs_write16(HOST_GS_SELECTOR, read_gs()); /* 22.2.4 */ + vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */ + vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */ vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ #ifdef CONFIG_X86_64 rdmsrl(MSR_FS_BASE, a); @@ -1958,7 +1958,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ - get_idt(&dt); + kvm_get_idt(&dt); vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 89fc8565ede..b131f3c0cf6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3767,14 +3767,14 @@ void fx_init(struct kvm_vcpu *vcpu) * allocate ram with GFP_KERNEL. */ if (!used_math()) - fx_save(&vcpu->arch.host_fx_image); + kvm_fx_save(&vcpu->arch.host_fx_image); /* Initialize guest FPU by resetting ours and saving into guest's */ preempt_disable(); - fx_save(&vcpu->arch.host_fx_image); - fx_finit(); - fx_save(&vcpu->arch.guest_fx_image); - fx_restore(&vcpu->arch.host_fx_image); + kvm_fx_save(&vcpu->arch.host_fx_image); + kvm_fx_finit(); + kvm_fx_save(&vcpu->arch.guest_fx_image); + kvm_fx_restore(&vcpu->arch.host_fx_image); preempt_enable(); vcpu->arch.cr0 |= X86_CR0_ET; @@ -3791,8 +3791,8 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) return; vcpu->guest_fpu_loaded = 1; - fx_save(&vcpu->arch.host_fx_image); - fx_restore(&vcpu->arch.guest_fx_image); + kvm_fx_save(&vcpu->arch.host_fx_image); + kvm_fx_restore(&vcpu->arch.guest_fx_image); } EXPORT_SYMBOL_GPL(kvm_load_guest_fpu); @@ -3802,8 +3802,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) return; vcpu->guest_fpu_loaded = 0; - fx_save(&vcpu->arch.guest_fx_image); - fx_restore(&vcpu->arch.host_fx_image); + kvm_fx_save(&vcpu->arch.guest_fx_image); + kvm_fx_restore(&vcpu->arch.host_fx_image); ++vcpu->stat.fpu_reload; } EXPORT_SYMBOL_GPL(kvm_put_guest_fpu); -- cgit v1.2.3 From 34d4cb8fca1f2a31be152b74797e6cd160ec9de6 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 10 Jul 2008 20:49:31 -0300 Subject: KVM: MMU: nuke shadowed pgtable pages and ptes on memslot destruction Flush the shadow mmu before removing regions to avoid stale entries. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/ia64/kvm/kvm-ia64.c | 3 +++ arch/powerpc/kvm/powerpc.c | 4 ++++ arch/s390/kvm/kvm-s390.c | 4 ++++ arch/x86/kvm/x86.c | 5 +++++ 4 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 9408b30576d..2672f4d278a 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1455,6 +1455,9 @@ int kvm_arch_set_memory_region(struct kvm *kvm, return 0; } +void kvm_arch_flush_shadow(struct kvm *kvm) +{ +} long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index b850d249702..53826a5f6c0 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -170,6 +170,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm, return 0; } +void kvm_arch_flush_shadow(struct kvm *kvm) +{ +} + struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvm_vcpu *vcpu; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 399acf3f64d..1782cbcd282 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -675,6 +675,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm, return 0; } +void kvm_arch_flush_shadow(struct kvm *kvm) +{ +} + gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) { return gfn; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b131f3c0cf6..9f1cdb011cf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4032,6 +4032,11 @@ int kvm_arch_set_memory_region(struct kvm *kvm, return 0; } +void kvm_arch_flush_shadow(struct kvm *kvm) +{ + kvm_mmu_zap_all(kvm); +} + int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) { return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE -- cgit v1.2.3 From 376c53c2b30d4a1955240f59f4ecd959aa118f92 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 10 Jul 2008 20:54:29 -0300 Subject: KVM: MMU: improve invalid shadow root page handling Harden kvm_mmu_zap_page() against invalid root pages that had been shadowed from memslots that are gone. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ff7cf632175..7f57da66382 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -930,14 +930,17 @@ static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) } kvm_mmu_page_unlink_children(kvm, sp); if (!sp->root_count) { - if (!sp->role.metaphysical) + if (!sp->role.metaphysical && !sp->role.invalid) unaccount_shadowed(kvm, sp->gfn); hlist_del(&sp->hash_link); kvm_mmu_free_page(kvm, sp); } else { + int invalid = sp->role.invalid; list_move(&sp->link, &kvm->arch.active_mmu_pages); sp->role.invalid = 1; kvm_reload_remote_mmus(kvm); + if (!sp->role.metaphysical && !invalid) + unaccount_shadowed(kvm, sp->gfn); } kvm_mmu_reset_last_pte_updated(kvm); } -- cgit v1.2.3 From 2a7c5b8b550b1fb1db9eb490420132e637f5dcb4 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 10 Jul 2008 17:08:15 -0300 Subject: KVM: x86 emulator: emulate clflush If the guest issues a clflush in a mmio address, the instruction can trap into the hypervisor. Currently, we do not decode clflush properly, causing the guest to hang. This patch fixes this emulating clflush (opcode 0f ae). Signed-off-by: Glauber Costa Signed-off-by: Avi Kivity --- arch/x86/kvm/x86_emulate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 8bc63f62fbb..f2f90468f8b 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -219,7 +219,7 @@ static u16 twobyte_table[256] = { /* 0xA0 - 0xA7 */ 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, /* 0xA8 - 0xAF */ - 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, ModRM, 0, /* 0xB0 - 0xB7 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, DstMem | SrcReg | ModRM | BitOp, @@ -1947,6 +1947,8 @@ twobyte_insn: c->src.val &= (c->dst.bytes << 3) - 1; emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); break; + case 0xae: /* clflush */ + break; case 0xb0 ... 0xb1: /* cmpxchg */ /* * Save real source value, then compare EAX against -- cgit v1.2.3 From 722c05f2192070bac0208b2c16ce13929b32d92f Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 13 Jul 2008 11:33:54 +0300 Subject: KVM: MMU: Fix potential race setting upper shadow ptes on nonpae hosts The direct mapped shadow code (used for real mode and two dimensional paging) sets upper-level ptes using direct assignment rather than calling set_shadow_pte(). A nonpae host will split this into two writes, which opens up a race if another vcpu accesses the same memory area. Fix by calling set_shadow_pte() instead of assigning directly. Noticed by Izik Eidus. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 7f57da66382..b0e4ddca6c1 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1189,9 +1189,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, return -ENOMEM; } - table[index] = __pa(new_table->spt) - | PT_PRESENT_MASK | PT_WRITABLE_MASK - | shadow_user_mask | shadow_x_mask; + set_shadow_pte(&table[index], + __pa(new_table->spt) + | PT_PRESENT_MASK | PT_WRITABLE_MASK + | shadow_user_mask | shadow_x_mask); } table_addr = table[index] & PT64_BASE_ADDR_MASK; } -- cgit v1.2.3 From 3450004a8cec8bab246372a1cabb9c2483b1e6c3 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 15 Jul 2008 19:57:30 +0300 Subject: [MIPS] PCI: Make the pcibios_max_latency variable static The pcibios_max_latency variable is needlessly defined global, and this patch makes it static. Build-tested using malta_defconfig. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle --- arch/mips/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index d7d6cb063d2..77bd5b68dc4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -204,7 +204,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. */ -unsigned int pcibios_max_latency = 255; +static unsigned int pcibios_max_latency = 255; void pcibios_set_master(struct pci_dev *dev) { -- cgit v1.2.3 From f028b8605613ade67fda554e30d367911d6c7222 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 15 Jul 2008 19:57:31 +0300 Subject: [MIPS] Fix missing prototypes in asm/fpu.h While building the Malta defconfig, sparse spat the following warnings: >>>>>>>>>>>>>>>>>> arch/mips/math-emu/kernel_linkage.c:31:6: warning: symbol 'fpu_emulator_init_fpu' was not declared. Should it be static? arch/mips/math-emu/kernel_linkage.c:54:5: warning: symbol 'fpu_emulator_save_context' was not declared. Should it be static? arch/mips/math-emu/kernel_linkage.c:68:5: warning: symbol 'fpu_emulator_restore_context' was not declared. Should it be static? >>>>>>>>>>>>>>>>>> This patch fixes these errors by adding the proper prototypes to the include/asm-mips/fpu.h header, and actually using this header in the sparse-spotted source file. Build-tested with Malta defconfig. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle --- arch/mips/math-emu/kernel_linkage.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c index ed49ef01ac5..52e6c58c8de 100644 --- a/arch/mips/math-emu/kernel_linkage.c +++ b/arch/mips/math-emu/kernel_linkage.c @@ -24,6 +24,7 @@ #include #include +#include #include #define SIGNALLING_NAN 0x7ff800007ff80000LL -- cgit v1.2.3 From 36e5c21de51e83bfa17c1e7334050edd2eda3d47 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 16 Jul 2008 14:06:15 +0200 Subject: [MIPS] IP22, IP28: Fix merge bug Instead of one SGI_HAS_HAL2 for IP22 and one for IP28, IP28 got two of them... Let's give IP22 some ALSA sound, too. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle [MIPS] IP22, IP28: Fix merge bug Instead of one SGI_HAS_HAL2 for IP22 and one for IP28, IP28 got two of them... Let's give IP22 some ALSA sound, too. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d21df5f1b1f..30edc395dce 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -330,6 +330,7 @@ config SGI_IP22 select SGI_HAS_DS1286 select SGI_HAS_I8042 select SGI_HAS_INDYDOG + select SGI_HAS_HAL2 select SGI_HAS_SEEQ select SGI_HAS_WD93 select SGI_HAS_ZILOG @@ -386,7 +387,6 @@ config SGI_IP28 select SGI_HAS_I8042 select SGI_HAS_INDYDOG select SGI_HAS_HAL2 - select SGI_HAS_HAL2 select SGI_HAS_SEEQ select SGI_HAS_WD93 select SGI_HAS_ZILOG -- cgit v1.2.3 From 5a334fa9240411121f5dda9605fc7fd98429e8c5 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 16 Jul 2008 15:18:54 +0200 Subject: [MIPS] IP22: Use common SGI button driver Use the Indy/O2 button driver. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip22/ip22-platform.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index fc6df96305e..60141235ec4 100644 --- a/arch/mips/sgi-ip22/ip22-platform.c +++ b/arch/mips/sgi-ip22/ip22-platform.c @@ -188,8 +188,7 @@ static int __init sgi_button_devinit(void) if (ip22_is_fullhouse()) return 0; /* full house has no volume buttons */ - return IS_ERR(platform_device_register_simple("sgiindybtns", - -1, NULL, 0)); + return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0)); } device_initcall(sgi_button_devinit); -- cgit v1.2.3 From 36a0a3cd45b49ceff78ac28efef1cbeec413d8c2 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 16 Jul 2008 15:18:58 +0200 Subject: [MIPS] IP32: Use common SGI button driver Use the Indy/O2 button driver. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip32/ip32-platform.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 2ee401ba0b2..3d63721e0e8 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -85,18 +85,7 @@ device_initcall(sgio2audio_devinit); static __init int sgio2btns_devinit(void) { - struct platform_device *pd; - int ret; - - pd = platform_device_alloc("sgio2btns", -1); - if (!pd) - return -ENOMEM; - - ret = platform_device_add(pd); - if (ret) - platform_device_put(pd); - - return ret; + return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0)); } device_initcall(sgio2btns_devinit); -- cgit v1.2.3 From 73b4390fb23456964201abda79f1210fe337d01a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 16 Jul 2008 16:12:25 +0100 Subject: [MIPS] Routerboard 532: Support for base system Signed-off-by: Phil Sutter Signed-off-by: Florian Fainelli Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 20 +- arch/mips/Makefile | 7 + arch/mips/configs/rb532_defconfig | 1314 +++++++++++++++++++++++++++++++++++++ arch/mips/pci/Makefile | 1 + arch/mips/pci/fixup-rc32434.c | 69 ++ arch/mips/pci/ops-rc32434.c | 207 ++++++ arch/mips/pci/pci-rc32434.c | 221 +++++++ arch/mips/rb532/Makefile | 7 + arch/mips/rb532/devices.c | 331 ++++++++++ arch/mips/rb532/gpio.c | 220 +++++++ arch/mips/rb532/irq.c | 209 ++++++ arch/mips/rb532/prom.c | 158 +++++ arch/mips/rb532/serial.c | 53 ++ arch/mips/rb532/setup.c | 79 +++ arch/mips/rb532/time.c | 67 ++ 15 files changed, 2962 insertions(+), 1 deletion(-) create mode 100644 arch/mips/configs/rb532_defconfig create mode 100644 arch/mips/pci/fixup-rc32434.c create mode 100644 arch/mips/pci/ops-rc32434.c create mode 100644 arch/mips/pci/pci-rc32434.c create mode 100644 arch/mips/rb532/Makefile create mode 100644 arch/mips/rb532/devices.c create mode 100644 arch/mips/rb532/gpio.c create mode 100644 arch/mips/rb532/irq.c create mode 100644 arch/mips/rb532/prom.c create mode 100644 arch/mips/rb532/serial.c create mode 100644 arch/mips/rb532/setup.c create mode 100644 arch/mips/rb532/time.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 30edc395dce..b9c754f4070 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -558,6 +558,24 @@ config MACH_TX39XX config MACH_TX49XX bool "Toshiba TX49 series based machines" +config MIKROTIK_RB532 + bool "Mikrotik RB532 boards" + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select GENERIC_HARDIRQS_NO__DO_IRQ + select HW_HAS_PCI + select IRQ_CPU + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SWAP_IO_SPACE + select BOOT_RAW + select GENERIC_GPIO + help + Support the Mikrotik(tm) RouterBoard 532 series, + based on the IDT RC32434 SoC. + config WR_PPMC bool "Wind River PPMC board" select CEVT_R4K @@ -899,7 +917,7 @@ config BOOT_ELF32 config MIPS_L1_CACHE_SHIFT int - default "4" if MACH_DECSTATION + default "4" if MACH_DECSTATION || MIKROTIK_RB532 default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM default "4" if PMC_MSP4200_EVAL default "5" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 356453322b4..9aab51caf16 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -559,6 +559,13 @@ load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000 # core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/ +# +# Routerboard 532 board +# +core-$(CONFIG_MIKROTIK_RB532) += arch/mips/rb532/ +cflags-$(CONFIG_MIKROTIK_RB532) += -Iinclude/asm-mips/mach-rc32434 +load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000 + # # Toshiba RBTX4927 board or # Toshiba RBTX4937 board diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig new file mode 100644 index 00000000000..f28dc32974e --- /dev/null +++ b/arch/mips/configs/rb532_defconfig @@ -0,0 +1,1314 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.25 +# Mon Apr 28 12:24:17 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +CONFIG_MIKROTIK_RB532=y +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_BOOT_RAW=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_L1_CACHE_SHIFT=4 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +CONFIG_HZ_100=y +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=100 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_CLASSIC_RCU=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_VEGAS=y +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="vegas" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_BRIDGE_NETFILTER is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +CONFIG_NF_CONNTRACK_IRC=m +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=m +# CONFIG_NF_CT_NETLINK is not set +CONFIG_NETFILTER_XTABLES=y +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +# CONFIG_IP_NF_TARGET_REDIRECT is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_NF_NAT_SNMP_BASIC is not set +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +# CONFIG_NF_NAT_SIP is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +# CONFIG_DECNET is not set +CONFIG_LLC=y +CONFIG_LLC2=m +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RR=m +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_INGRESS is not set + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=y +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +# CONFIG_NET_ACT_NAT is not set +CONFIG_NET_ACT_PEDIT=m +# CONFIG_NET_ACT_SIMP is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +# CONFIG_AX25 is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLOCK2MTD=y + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RB532=y +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_IFB=m +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_KORINA=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_TC35815 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +CONFIG_VIA_RHINE=y +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_RHINE_NAPI=y +# CONFIG_SC92031 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_HERMES is not set +CONFIG_ATMEL=m +# CONFIG_PCI_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_HOSTAP is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPP_MPPE is not set +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +# CONFIG_HID is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_GPIO is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=m +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_HW is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 57e34cafa49..15e01aec37f 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -49,3 +49,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o +obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o diff --git a/arch/mips/pci/fixup-rc32434.c b/arch/mips/pci/fixup-rc32434.c new file mode 100644 index 00000000000..75b90dcb7a0 --- /dev/null +++ b/arch/mips/pci/fixup-rc32434.c @@ -0,0 +1,69 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include + +static int __devinitdata irq_map[2][12] = { + {0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1}, + {0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3} +}; + +int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = 0; + + if (dev->bus->number < 2 && PCI_SLOT(dev->devfn) < 12) + irq = irq_map[dev->bus->number][PCI_SLOT(dev->devfn)]; + + return irq + GROUP4_IRQ_BASE + 4; +} + +static void rc32434_pci_early_fixup(struct pci_dev *dev) +{ + if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) { + /* disable prefetched memory range */ + pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0); + pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10); + + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + } +} + +/* + * The fixup applies to both the IDT and VIA devices present on the board + */ +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, rc32434_pci_early_fixup); + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c new file mode 100644 index 00000000000..d1f8fa210ca --- /dev/null +++ b/arch/mips/pci/ops-rc32434.c @@ -0,0 +1,207 @@ +/* + * BRIEF MODULE DESCRIPTION + * pci_ops for IDT EB434 board + * + * Copyright 2004 IDT Inc. (rischelp@idt.com) + * Copyright 2006 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + + +#define PCI_CFG_SET(bus, slot, func, off) \ + (rc32434_pci->pcicfga = (0x80000000 | \ + ((bus) << 16) | ((slot)<<11) | \ + ((func)<<8) | (off))) + +static inline int config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, + unsigned char where, u32 *data) +{ + unsigned int slot = PCI_SLOT(devfn); + u8 func = PCI_FUNC(devfn); + + /* Setup address */ + PCI_CFG_SET(bus->number, slot, func, where); + rc32434_sync(); + + if (access_type == PCI_ACCESS_WRITE) + rc32434_pci->pcicfgd = *data; + else + *data = rc32434_pci->pcicfgd; + + rc32434_sync(); + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int read_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 *val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); + *val = (data >> ((where & 3) << 3)) & 0xff; + return ret; +} + +static int read_config_word(struct pci_bus *bus, unsigned int devfn, + int where, u16 *val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); + *val = (data >> ((where & 3) << 3)) & 0xffff; + return ret; +} + +static int read_config_dword(struct pci_bus *bus, unsigned int devfn, + int where, u32 *val) +{ + int ret; + int delay = 1; + + /* + * Don't scan too far, else there will be errors with plugged in + * daughterboard (rb564). + */ + if (bus->number == 0 && PCI_SLOT(devfn) > 21) + return 0; + +retry: + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); + + /* + * Certain devices react delayed at device scan time, this + * gives them time to settle + */ + if (where == PCI_VENDOR_ID) { + if (ret == 0xffffffff || ret == 0x00000000 || + ret == 0x0000ffff || ret == 0xffff0000) { + if (delay > 4) + return 0; + delay *= 2; + msleep(delay); + goto retry; + } + } + + return ret; +} + +static int +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, + u8 val) +{ + u32 data = 0; + + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + + +static int +write_config_word(struct pci_bus *bus, unsigned int devfn, int where, + u16 val) +{ + u32 data = 0; + + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + + +static int +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, + u32 val) +{ + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + switch (size) { + case 1: + return read_config_byte(bus, devfn, where, (u8 *) val); + case 2: + return read_config_word(bus, devfn, where, (u16 *) val); + default: + return read_config_dword(bus, devfn, where, val); + } +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + switch (size) { + case 1: + return write_config_byte(bus, devfn, where, (u8) val); + case 2: + return write_config_word(bus, devfn, where, (u16) val); + default: + return write_config_dword(bus, devfn, where, val); + } +} + +struct pci_ops rc32434_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c new file mode 100644 index 00000000000..1c2821e2f49 --- /dev/null +++ b/arch/mips/pci/pci-rc32434.c @@ -0,0 +1,221 @@ +/* + * BRIEF MODULE DESCRIPTION + * PCI initialization for IDT EB434 board + * + * Copyright 2004 IDT Inc. (rischelp@idt.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* define an unsigned array for the PCI registers */ +static unsigned int korina_cnfg_regs[25] = { + KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4, + KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8, + KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12, + KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16, + KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20, + KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24 +}; +static struct resource rc32434_res_pci_mem1; +static struct resource rc32434_res_pci_mem2; + +static struct resource rc32434_res_pci_mem1 = { + .name = "PCI MEM1", + .start = 0x50000000, + .end = 0x5FFFFFFF, + .flags = IORESOURCE_MEM, + .parent = &rc32434_res_pci_mem1, + .sibling = NULL, + .child = &rc32434_res_pci_mem2 +}; + +static struct resource rc32434_res_pci_mem2 = { + .name = "PCI Mem2", + .start = 0x60000000, + .end = 0x6FFFFFFF, + .flags = IORESOURCE_MEM, + .parent = &rc32434_res_pci_mem1, + .sibling = NULL, + .child = NULL +}; + +static struct resource rc32434_res_pci_io1 = { + .name = "PCI I/O1", + .start = 0x18800000, + .end = 0x188FFFFF, + .flags = IORESOURCE_IO, +}; + +extern struct pci_ops rc32434_pci_ops; + +#define PCI_MEM1_START PCI_ADDR_START +#define PCI_MEM1_END (PCI_ADDR_START + CPUTOPCI_MEM_WIN - 1) +#define PCI_MEM2_START (PCI_ADDR_START + CPUTOPCI_MEM_WIN) +#define PCI_MEM2_END (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) - 1) +#define PCI_IO1_START (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN)) +#define PCI_IO1_END \ + (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN - 1) +#define PCI_IO2_START \ + (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN) +#define PCI_IO2_END \ + (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + (2 * CPUTOPCI_IO_WIN) - 1) + +struct pci_controller rc32434_controller2; + +struct pci_controller rc32434_controller = { + .pci_ops = &rc32434_pci_ops, + .mem_resource = &rc32434_res_pci_mem1, + .io_resource = &rc32434_res_pci_io1, + .mem_offset = 0, + .io_offset = 0, + +}; + +#ifdef __MIPSEB__ +#define PCI_ENDIAN_FLAG PCILBAC_sb_m +#else +#define PCI_ENDIAN_FLAG 0 +#endif + +static int __init rc32434_pcibridge_init(void) +{ + unsigned int pcicvalue, pcicdata = 0; + unsigned int dummyread, pcicntlval; + int loopCount; + unsigned int pci_config_addr; + + pcicvalue = rc32434_pci->pcic; + pcicvalue = (pcicvalue >> PCIM_SHFT) & PCIM_BIT_LEN; + if (!((pcicvalue == PCIM_H_EA) || + (pcicvalue == PCIM_H_IA_FIX) || + (pcicvalue == PCIM_H_IA_RR))) { + pr_err(KERN_ERR "PCI init error!!!\n"); + /* Not in Host Mode, return ERROR */ + return -1; + } + /* Enables the Idle Grant mode, Arbiter Parking */ + pcicdata |= (PCI_CTL_IGM | PCI_CTL_EAP | PCI_CTL_EN); + rc32434_pci->pcic = pcicdata; /* Enable the PCI bus Interface */ + /* Zero out the PCI status & PCI Status Mask */ + for (;;) { + pcicdata = rc32434_pci->pcis; + if (!(pcicdata & PCI_STAT_RIP)) + break; + } + + rc32434_pci->pcis = 0; + rc32434_pci->pcism = 0xFFFFFFFF; + /* Zero out the PCI decoupled registers */ + rc32434_pci->pcidac = 0; /* + * disable PCI decoupled accesses at + * initialization + */ + rc32434_pci->pcidas = 0; /* clear the status */ + rc32434_pci->pcidasm = 0x0000007F; /* Mask all the interrupts */ + /* Mask PCI Messaging Interrupts */ + rc32434_pci_msg->pciiic = 0; + rc32434_pci_msg->pciiim = 0xFFFFFFFF; + rc32434_pci_msg->pciioic = 0; + rc32434_pci_msg->pciioim = 0; + + + /* Setup PCILB0 as Memory Window */ + rc32434_pci->pcilba[0].address = (unsigned int) (PCI_ADDR_START); + + /* setup the PCI map address as same as the local address */ + + rc32434_pci->pcilba[0].mapping = (unsigned int) (PCI_ADDR_START); + + + /* Setup PCILBA1 as MEM */ + rc32434_pci->pcilba[0].control = + (((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG); + dummyread = rc32434_pci->pcilba[0].control; /* flush the CPU write Buffers */ + rc32434_pci->pcilba[1].address = 0x60000000; + rc32434_pci->pcilba[1].mapping = 0x60000000; + + /* setup PCILBA2 as IO Window */ + rc32434_pci->pcilba[1].control = + (((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG); + dummyread = rc32434_pci->pcilba[1].control; /* flush the CPU write Buffers */ + rc32434_pci->pcilba[2].address = 0x18C00000; + rc32434_pci->pcilba[2].mapping = 0x18FFFFFF; + + /* setup PCILBA2 as IO Window */ + rc32434_pci->pcilba[2].control = + (((SIZE_4MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG); + dummyread = rc32434_pci->pcilba[2].control; /* flush the CPU write Buffers */ + + /* Setup PCILBA3 as IO Window */ + rc32434_pci->pcilba[3].address = 0x18800000; + rc32434_pci->pcilba[3].mapping = 0x18800000; + rc32434_pci->pcilba[3].control = + ((((SIZE_1MB & 0x1ff) << PCI_LBAC_SIZE_BIT) | PCI_LBAC_MSI) | + PCI_ENDIAN_FLAG); + dummyread = rc32434_pci->pcilba[3].control; /* flush the CPU write Buffers */ + + pci_config_addr = (unsigned int) (0x80000004); + for (loopCount = 0; loopCount < 24; loopCount++) { + rc32434_pci->pcicfga = pci_config_addr; + dummyread = rc32434_pci->pcicfga; + rc32434_pci->pcicfgd = korina_cnfg_regs[loopCount]; + dummyread = rc32434_pci->pcicfgd; + pci_config_addr += 4; + } + rc32434_pci->pcitc = + (unsigned int) ((PCITC_RTIMER_VAL & 0xff) << PCI_TC_RTIMER_BIT) | + ((PCITC_DTIMER_VAL & 0xff) << PCI_TC_DTIMER_BIT); + + pcicntlval = rc32434_pci->pcic; + pcicntlval &= ~PCI_CTL_TNR; + rc32434_pci->pcic = pcicntlval; + pcicntlval = rc32434_pci->pcic; + + return 0; +} + +static int __init rc32434_pci_init(void) +{ + pr_info("PCI: Initializing PCI\n"); + + ioport_resource.start = rc32434_res_pci_io1.start; + ioport_resource.end = rc32434_res_pci_io1.end; + + rc32434_pcibridge_init(); + + register_pci_controller(&rc32434_controller); + rc32434_sync(); + + return 0; +} + +arch_initcall(rc32434_pci_init); diff --git a/arch/mips/rb532/Makefile b/arch/mips/rb532/Makefile new file mode 100644 index 00000000000..8f0b6b6a162 --- /dev/null +++ b/arch/mips/rb532/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the RB532 board specific parts of the kernel +# + +obj-y += irq.o time.o setup.o serial.o prom.o gpio.o devices.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c new file mode 100644 index 00000000000..44fb0a62877 --- /dev/null +++ b/arch/mips/rb532/devices.c @@ -0,0 +1,331 @@ +/* + * RouterBoard 500 Platform devices + * + * Copyright (C) 2006 Felix Fietkau + * Copyright (C) 2007 Florian Fainelli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ETH0_DMA_RX_IRQ (GROUP1_IRQ_BASE + 0) +#define ETH0_DMA_TX_IRQ (GROUP1_IRQ_BASE + 1) +#define ETH0_RX_OVR_IRQ (GROUP3_IRQ_BASE + 9) +#define ETH0_TX_UND_IRQ (GROUP3_IRQ_BASE + 10) + +#define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET) +#define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET) + +/* NAND definitions */ +#define GPIO_RDY (1 << 0x08) +#define GPIO_WPX (1 << 0x09) +#define GPIO_ALE (1 << 0x0a) +#define GPIO_CLE (1 << 0x0b) + +extern char *board_type; + +static struct resource korina_dev0_res[] = { + { + .name = "korina_regs", + .start = ETH0_BASE_ADDR, + .end = ETH0_BASE_ADDR + sizeof(struct eth_regs), + .flags = IORESOURCE_MEM, + }, { + .name = "korina_rx", + .start = ETH0_DMA_RX_IRQ, + .end = ETH0_DMA_RX_IRQ, + .flags = IORESOURCE_IRQ + }, { + .name = "korina_tx", + .start = ETH0_DMA_TX_IRQ, + .end = ETH0_DMA_TX_IRQ, + .flags = IORESOURCE_IRQ + }, { + .name = "korina_ovr", + .start = ETH0_RX_OVR_IRQ, + .end = ETH0_RX_OVR_IRQ, + .flags = IORESOURCE_IRQ + }, { + .name = "korina_und", + .start = ETH0_TX_UND_IRQ, + .end = ETH0_TX_UND_IRQ, + .flags = IORESOURCE_IRQ + }, { + .name = "korina_dma_rx", + .start = ETH0_RX_DMA_ADDR, + .end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1, + .flags = IORESOURCE_MEM, + }, { + .name = "korina_dma_tx", + .start = ETH0_TX_DMA_ADDR, + .end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct korina_device korina_dev0_data = { + .name = "korina0", + .mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee} +}; + +static struct platform_device korina_dev0 = { + .id = 0, + .name = "korina", + .dev.platform_data = &korina_dev0_data, + .resource = korina_dev0_res, + .num_resources = ARRAY_SIZE(korina_dev0_res), +}; + +#define CF_GPIO_NUM 13 + +static struct resource cf_slot0_res[] = { + { + .name = "cf_membase", + .flags = IORESOURCE_MEM + }, { + .name = "cf_irq", + .start = (8 + 4 * 32 + CF_GPIO_NUM), /* 149 */ + .end = (8 + 4 * 32 + CF_GPIO_NUM), + .flags = IORESOURCE_IRQ + } +}; + +static struct cf_device cf_slot0_data = { + .gpio_pin = 13 +}; + +static struct platform_device cf_slot0 = { + .id = 0, + .name = "pata-rb532-cf", + .dev.platform_data = &cf_slot0_data, + .resource = cf_slot0_res, + .num_resources = ARRAY_SIZE(cf_slot0_res), +}; + +/* Resources and device for NAND */ +static int rb532_dev_ready(struct mtd_info *mtd) +{ + return readl(IDT434_REG_BASE + GPIOD) & GPIO_RDY; +} + +static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *chip = mtd->priv; + unsigned char orbits, nandbits; + + if (ctrl & NAND_CTRL_CHANGE) { + orbits = (ctrl & NAND_CLE) << 1; + orbits |= (ctrl & NAND_ALE) >> 1; + + nandbits = (~ctrl & NAND_CLE) << 1; + nandbits |= (~ctrl & NAND_ALE) >> 1; + + set_latch_u5(orbits, nandbits); + } + if (cmd != NAND_CMD_NONE) + writeb(cmd, chip->IO_ADDR_W); +} + +static struct resource nand_slot0_res[] = { + [0] = { + .name = "nand_membase", + .flags = IORESOURCE_MEM + } +}; + +static struct platform_nand_data rb532_nand_data = { + .ctrl.dev_ready = rb532_dev_ready, + .ctrl.cmd_ctrl = rb532_cmd_ctrl, +}; + +static struct platform_device nand_slot0 = { + .name = "gen_nand", + .id = -1, + .resource = nand_slot0_res, + .num_resources = ARRAY_SIZE(nand_slot0_res), + .dev.platform_data = &rb532_nand_data, +}; + +static struct mtd_partition rb532_partition_info[] = { + { + .name = "Routerboard NAND boot", + .offset = 0, + .size = 4 * 1024 * 1024, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct platform_device rb532_led = { + .name = "rb532-led", + .id = 0, +}; + +static struct gpio_keys_button rb532_gpio_btn[] = { + { + .gpio = 1, + .code = BTN_0, + .desc = "S1", + .active_low = 1, + } +}; + +static struct gpio_keys_platform_data rb532_gpio_btn_data = { + .buttons = rb532_gpio_btn, + .nbuttons = ARRAY_SIZE(rb532_gpio_btn), +}; + +static struct platform_device rb532_button = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &rb532_gpio_btn_data, + } +}; + +static struct resource rb532_wdt_res[] = { + { + .name = "rb532_wdt_res", + .start = INTEG0_BASE_ADDR, + .end = INTEG0_BASE_ADDR + sizeof(struct integ), + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device rb532_wdt = { + .name = "rc32434_wdt", + .id = -1, + .resource = rb532_wdt_res, + .num_resources = ARRAY_SIZE(rb532_wdt_res), +}; + +static struct platform_device *rb532_devs[] = { + &korina_dev0, + &nand_slot0, + &cf_slot0, + &rb532_led, + &rb532_button, + &rb532_wdt +}; + +static void __init parse_mac_addr(char *macstr) +{ + int i, j; + unsigned char result, value; + + for (i = 0; i < 6; i++) { + result = 0; + + if (i != 5 && *(macstr + 2) != ':') + return; + + for (j = 0; j < 2; j++) { + if (isxdigit(*macstr) + && (value = + isdigit(*macstr) ? *macstr - + '0' : toupper(*macstr) - 'A' + 10) < 16) { + result = result * 16 + value; + macstr++; + } else + return; + } + + macstr++; + korina_dev0_data.mac[i] = result; + } +} + + +/* DEVICE CONTROLLER 1 */ +#define CFG_DC_DEV1 ((void *)0xb8010010) +#define CFG_DC_DEV2 ((void *)0xb8010020) +#define CFG_DC_DEVBASE 0x0 +#define CFG_DC_DEVMASK 0x4 +#define CFG_DC_DEVC 0x8 +#define CFG_DC_DEVTC 0xC + +/* NAND definitions */ +#define NAND_CHIP_DELAY 25 + +static void __init rb532_nand_setup(void) +{ + switch (mips_machtype) { + case MACH_MIKROTIK_RB532A: + set_latch_u5(LO_FOFF | LO_CEX, + LO_ULED | LO_ALE | LO_CLE | LO_WPX); + break; + default: + set_latch_u5(LO_WPX | LO_FOFF | LO_CEX, + LO_ULED | LO_ALE | LO_CLE); + break; + } + + /* Setup NAND specific settings */ + rb532_nand_data.chip.nr_chips = 1; + rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info); + rb532_nand_data.chip.partitions = rb532_partition_info; + rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY; + rb532_nand_data.chip.options = NAND_NO_AUTOINCR; +} + + +static int __init plat_setup_devices(void) +{ + /* Look for the CF card reader */ + if (!readl(CFG_DC_DEV1 + CFG_DC_DEVMASK)) + rb532_devs[1] = NULL; + else { + cf_slot0_res[0].start = + readl(CFG_DC_DEV1 + CFG_DC_DEVBASE); + cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000; + } + + /* Read the NAND resources from the device controller */ + nand_slot0_res[0].start = readl(CFG_DC_DEV2 + CFG_DC_DEVBASE); + nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000; + + /* Initialise the NAND device */ + rb532_nand_setup(); + + return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs)); +} + +static int __init setup_kmac(char *s) +{ + printk(KERN_INFO "korina mac = %s\n", s); + parse_mac_addr(s); + return 0; +} + +__setup("kmac=", setup_kmac); + +arch_initcall(plat_setup_devices); diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c new file mode 100644 index 00000000000..b2fe82dba0a --- /dev/null +++ b/arch/mips/rb532/gpio.c @@ -0,0 +1,220 @@ +/* + * Miscellaneous functions for IDT EB434 board + * + * Copyright 2004 IDT Inc. (rischelp@idt.com) + * Copyright 2006 Phil Sutter + * Copyright 2007 Florian Fainelli + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +struct rb532_gpio_reg __iomem *rb532_gpio_reg0; +EXPORT_SYMBOL(rb532_gpio_reg0); + +struct mpmc_device dev3; + +static struct resource rb532_gpio_reg0_res[] = { + { + .name = "gpio_reg0", + .start = (u32)(IDT434_REG_BASE + GPIOBASE), + .end = (u32)(IDT434_REG_BASE + GPIOBASE + sizeof(struct rb532_gpio_reg)), + .flags = IORESOURCE_MEM, + } +}; + +static struct resource rb532_dev3_ctl_res[] = { + { + .name = "dev3_ctl", + .start = (u32)(IDT434_REG_BASE + DEV3BASE), + .end = (u32)(IDT434_REG_BASE + DEV3BASE + sizeof(struct dev_reg)), + .flags = IORESOURCE_MEM, + } +}; + +void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val) +{ + unsigned flags, data; + unsigned i = 0; + + spin_lock_irqsave(&dev3.lock, flags); + + data = *(volatile unsigned *) (IDT434_REG_BASE + reg_offs); + for (i = 0; i != len; ++i) { + if (val & (1 << i)) + data |= (1 << (i + bit)); + else + data &= ~(1 << (i + bit)); + } + writel(data, (IDT434_REG_BASE + reg_offs)); + + spin_unlock_irqrestore(&dev3.lock, flags); +} +EXPORT_SYMBOL(set_434_reg); + +unsigned get_434_reg(unsigned reg_offs) +{ + return readl(IDT434_REG_BASE + reg_offs); +} +EXPORT_SYMBOL(get_434_reg); + +void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) +{ + unsigned flags; + + spin_lock_irqsave(&dev3.lock, flags); + + dev3.state = (dev3.state | or_mask) & ~nand_mask; + writel(dev3.state, &dev3.base); + + spin_unlock_irqrestore(&dev3.lock, flags); +} +EXPORT_SYMBOL(set_latch_u5); + +unsigned char get_latch_u5(void) +{ + return dev3.state; +} +EXPORT_SYMBOL(get_latch_u5); + +int rb532_gpio_get_value(unsigned gpio) +{ + return readl(&rb532_gpio_reg0->gpiod) & (1 << gpio); +} +EXPORT_SYMBOL(rb532_gpio_get_value); + +void rb532_gpio_set_value(unsigned gpio, int value) +{ + unsigned tmp; + + tmp = readl(&rb532_gpio_reg0->gpiod) & ~(1 << gpio); + if (value) + tmp |= 1 << gpio; + + writel(tmp, (void *)&rb532_gpio_reg0->gpiod); +} +EXPORT_SYMBOL(rb532_gpio_set_value); + +int rb532_gpio_direction_input(unsigned gpio) +{ + writel(readl(&rb532_gpio_reg0->gpiocfg) & ~(1 << gpio), + (void *)&rb532_gpio_reg0->gpiocfg); + + return 0; +} +EXPORT_SYMBOL(rb532_gpio_direction_input); + +int rb532_gpio_direction_output(unsigned gpio, int value) +{ + gpio_set_value(gpio, value); + writel(readl(&rb532_gpio_reg0->gpiocfg) | (1 << gpio), + (void *)&rb532_gpio_reg0->gpiocfg); + + return 0; +} +EXPORT_SYMBOL(rb532_gpio_direction_output); + +void rb532_gpio_set_int_level(unsigned gpio, int value) +{ + unsigned tmp; + + tmp = readl(&rb532_gpio_reg0->gpioilevel) & ~(1 << gpio); + if (value) + tmp |= 1 << gpio; + writel(tmp, (void *)&rb532_gpio_reg0->gpioilevel); +} +EXPORT_SYMBOL(rb532_gpio_set_int_level); + +int rb532_gpio_get_int_level(unsigned gpio) +{ + return readl(&rb532_gpio_reg0->gpioilevel) & (1 << gpio); +} +EXPORT_SYMBOL(rb532_gpio_get_int_level); + +void rb532_gpio_set_int_status(unsigned gpio, int value) +{ + unsigned tmp; + + tmp = readl(&rb532_gpio_reg0->gpioistat); + if (value) + tmp |= 1 << gpio; + writel(tmp, (void *)&rb532_gpio_reg0->gpioistat); +} +EXPORT_SYMBOL(rb532_gpio_set_int_status); + +int rb532_gpio_get_int_status(unsigned gpio) +{ + return readl(&rb532_gpio_reg0->gpioistat) & (1 << gpio); +} +EXPORT_SYMBOL(rb532_gpio_get_int_status); + +void rb532_gpio_set_func(unsigned gpio, int value) +{ + unsigned tmp; + + tmp = readl(&rb532_gpio_reg0->gpiofunc); + if (value) + tmp |= 1 << gpio; + writel(tmp, (void *)&rb532_gpio_reg0->gpiofunc); +} +EXPORT_SYMBOL(rb532_gpio_set_func); + +int rb532_gpio_get_func(unsigned gpio) +{ + return readl(&rb532_gpio_reg0->gpiofunc) & (1 << gpio); +} +EXPORT_SYMBOL(rb532_gpio_get_func); + +int __init rb532_gpio_init(void) +{ + rb532_gpio_reg0 = ioremap_nocache(rb532_gpio_reg0_res[0].start, + rb532_gpio_reg0_res[0].end - + rb532_gpio_reg0_res[0].start); + + if (!rb532_gpio_reg0) { + printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); + return -ENXIO; + } + + dev3.base = ioremap_nocache(rb532_dev3_ctl_res[0].start, + rb532_dev3_ctl_res[0].end - + rb532_dev3_ctl_res[0].start); + + if (!dev3.base) { + printk(KERN_ERR "rb532: cannot remap device controller 3\n"); + return -ENXIO; + } + + return 0; +} +arch_initcall(rb532_gpio_init); diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c new file mode 100644 index 00000000000..c0d0f950caf --- /dev/null +++ b/arch/mips/rb532/irq.c @@ -0,0 +1,209 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +struct intr_group { + u32 mask; /* mask of valid bits in pending/mask registers */ + volatile u32 *base_addr; +}; + +#define RC32434_NR_IRQS (GROUP4_IRQ_BASE + 32) + +#if (NR_IRQS < RC32434_NR_IRQS) +#error Too little irqs defined. Did you override ? +#endif + +static const struct intr_group intr_group[NUM_INTR_GROUPS] = { + { + .mask = 0x0000efff, + .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)}, + { + .mask = 0x00001fff, + .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)}, + { + .mask = 0x00000007, + .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)}, + { + .mask = 0x0003ffff, + .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)}, + { + .mask = 0xffffffff, + .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)} +}; + +#define READ_PEND(base) (*(base)) +#define READ_MASK(base) (*(base + 2)) +#define WRITE_MASK(base, val) (*(base + 2) = (val)) + +static inline int irq_to_group(unsigned int irq_nr) +{ + return (irq_nr - GROUP0_IRQ_BASE) >> 5; +} + +static inline int group_to_ip(unsigned int group) +{ + return group + 2; +} + +static inline void enable_local_irq(unsigned int ip) +{ + int ipnum = 0x100 << ip; + + set_c0_status(ipnum); +} + +static inline void disable_local_irq(unsigned int ip) +{ + int ipnum = 0x100 << ip; + + clear_c0_status(ipnum); +} + +static inline void ack_local_irq(unsigned int ip) +{ + int ipnum = 0x100 << ip; + + clear_c0_cause(ipnum); +} + +static void rb532_enable_irq(unsigned int irq_nr) +{ + int ip = irq_nr - GROUP0_IRQ_BASE; + unsigned int group, intr_bit; + volatile unsigned int *addr; + + if (ip < 0) + enable_local_irq(irq_nr); + else { + group = ip >> 5; + + ip &= (1 << 5) - 1; + intr_bit = 1 << ip; + + enable_local_irq(group_to_ip(group)); + + addr = intr_group[group].base_addr; + WRITE_MASK(addr, READ_MASK(addr) & ~intr_bit); + } +} + +static void rb532_disable_irq(unsigned int irq_nr) +{ + int ip = irq_nr - GROUP0_IRQ_BASE; + unsigned int group, intr_bit, mask; + volatile unsigned int *addr; + + if (ip < 0) { + disable_local_irq(irq_nr); + } else { + group = ip >> 5; + + ip &= (1 << 5) - 1; + intr_bit = 1 << ip; + addr = intr_group[group].base_addr; + mask = READ_MASK(addr); + mask |= intr_bit; + WRITE_MASK(addr, mask); + + /* + * if there are no more interrupts enabled in this + * group, disable corresponding IP + */ + if (mask == intr_group[group].mask) + disable_local_irq(group_to_ip(group)); + } +} + +static void rb532_mask_and_ack_irq(unsigned int irq_nr) +{ + rb532_disable_irq(irq_nr); + ack_local_irq(group_to_ip(irq_to_group(irq_nr))); +} + +static struct irq_chip rc32434_irq_type = { + .name = "RB532", + .ack = rb532_disable_irq, + .mask = rb532_disable_irq, + .mask_ack = rb532_mask_and_ack_irq, + .unmask = rb532_enable_irq, +}; + +void __init arch_init_irq(void) +{ + int i; + + pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS); + + for (i = 0; i < RC32434_NR_IRQS; i++) + set_irq_chip_and_handler(i, &rc32434_irq_type, + handle_level_irq); +} + +/* Main Interrupt dispatcher */ +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int ip, pend, group; + volatile unsigned int *addr; + unsigned int cp0_cause = read_c0_cause() & read_c0_status(); + + if (cp0_cause & CAUSEF_IP7) { + do_IRQ(7); + } else { + ip = (cp0_cause & 0x7c00); + if (ip) { + group = 21 + (fls(ip) - 32); + + addr = intr_group[group].base_addr; + + pend = READ_PEND(addr); + pend &= ~READ_MASK(addr); /* only unmasked interrupts */ + pend = 39 + (fls(pend) - 32); + do_IRQ((group << 5) + pend); + } + } +} diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c new file mode 100644 index 00000000000..1bc0af8febf --- /dev/null +++ b/arch/mips/rb532/prom.c @@ -0,0 +1,158 @@ +/* + * RouterBoard 500 specific prom routines + * + * Copyright (C) 2003, Peter Sadik + * Copyright (C) 2005-2006, P.Christeas + * Copyright (C) 2007, Gabor Juhos + * Felix Fietkau + * Florian Fainelli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern void __init setup_serial_port(void); + +unsigned int idt_cpu_freq = 132000000; +EXPORT_SYMBOL(idt_cpu_freq); +unsigned int gpio_bootup_state; +EXPORT_SYMBOL(gpio_bootup_state); + +static struct resource ddr_reg[] = { + { + .name = "ddr-reg", + .start = DDR0_PHYS_ADDR, + .end = DDR0_PHYS_ADDR + sizeof(struct ddr_ram), + .flags = IORESOURCE_MEM, + } +}; + +void __init prom_free_prom_memory(void) +{ + /* No prom memory to free */ +} + +static inline int match_tag(char *arg, const char *tag) +{ + return strncmp(arg, tag, strlen(tag)) == 0; +} + +static inline unsigned long tag2ul(char *arg, const char *tag) +{ + char *num; + + num = arg + strlen(tag); + return simple_strtoul(num, 0, 10); +} + +void __init prom_setup_cmdline(void) +{ + char cmd_line[CL_SIZE]; + char *cp, *board; + int prom_argc; + char **prom_argv, **prom_envp; + int i; + + prom_argc = fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + cp = cmd_line; + /* Note: it is common that parameters start + * at argv[1] and not argv[0], + * however, our elf loader starts at [0] */ + for (i = 0; i < prom_argc; i++) { + if (match_tag(prom_argv[i], FREQ_TAG)) { + idt_cpu_freq = tag2ul(prom_argv[i], FREQ_TAG); + continue; + } +#ifdef IGNORE_CMDLINE_MEM + /* parses out the "mem=xx" arg */ + if (match_tag(prom_argv[i], MEM_TAG)) + continue; +#endif + if (i > 0) + *(cp++) = ' '; + if (match_tag(prom_argv[i], BOARD_TAG)) { + board = prom_argv[i] + strlen(BOARD_TAG); + + if (match_tag(board, BOARD_RB532A)) + mips_machtype = MACH_MIKROTIK_RB532A; + else + mips_machtype = MACH_MIKROTIK_RB532; + } + + if (match_tag(prom_argv[i], GPIO_TAG)) + gpio_bootup_state = tag2ul(prom_argv[i], GPIO_TAG); + + strcpy(cp, prom_argv[i]); + cp += strlen(prom_argv[i]); + } + *(cp++) = ' '; + + i = strlen(arcs_cmdline); + if (i > 0) { + *(cp++) = ' '; + strcpy(cp, arcs_cmdline); + cp += strlen(arcs_cmdline); + } + if (gpio_bootup_state & 0x02) + strcpy(cp, GPIO_INIT_NOBUTTON); + else + strcpy(cp, GPIO_INIT_BUTTON); + + cmd_line[CL_SIZE-1] = '\0'; + + strcpy(arcs_cmdline, cmd_line); +} + +void __init prom_init(void) +{ + struct ddr_ram __iomem *ddr; + phys_t memsize; + phys_t ddrbase; + + ddr = ioremap_nocache(ddr_reg[0].start, + ddr_reg[0].end - ddr_reg[0].start); + + if (!ddr) { + printk(KERN_ERR "Unable to remap DDR register\n"); + return; + } + + ddrbase = (phys_t)&ddr->ddrbase; + memsize = (phys_t)&ddr->ddrmask; + memsize = 0 - memsize; + + prom_setup_cmdline(); + + /* give all RAM to boot allocator, + * except for the first 0x400 and the last 0x200 bytes */ + add_memory_region(ddrbase + 0x400, memsize - 0x600, BOOT_MEM_RAM); +} diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c new file mode 100644 index 00000000000..1a05b5ddee0 --- /dev/null +++ b/arch/mips/rb532/serial.c @@ -0,0 +1,53 @@ +/* + * BRIEF MODULE DESCRIPTION + * Serial port initialisation. + * + * Copyright 2004 IDT Inc. (rischelp@idt.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +extern unsigned int idt_cpu_freq; + +static struct uart_port rb532_uart = { + .type = PORT_16550A, + .line = 0, + .irq = RC32434_UART0_IRQ, + .iotype = UPIO_MEM, + .membase = (char *)KSEG1ADDR(RC32434_UART0_BASE), + .regshift = 2 +}; + +int __init setup_serial_port(void) +{ + rb532_uart.uartclk = idt_cpu_freq; + + return early_serial_setup(&rb532_uart); +} +arch_initcall(setup_serial_port); diff --git a/arch/mips/rb532/setup.c b/arch/mips/rb532/setup.c new file mode 100644 index 00000000000..7aafa95ac20 --- /dev/null +++ b/arch/mips/rb532/setup.c @@ -0,0 +1,79 @@ +/* + * setup.c - boot time setup code + */ + +#include + +#include +#include +#include +#include + +#include +#include + +struct pci_reg __iomem *pci_reg; +EXPORT_SYMBOL(pci_reg); + +static struct resource pci0_res[] = { + { + .name = "pci_reg0", + .start = PCI0_BASE_ADDR, + .end = PCI0_BASE_ADDR + sizeof(struct pci_reg), + .flags = IORESOURCE_MEM, + } +}; + +static void rb_machine_restart(char *command) +{ + /* just jump to the reset vector */ + writel(0x80000001, (void *)KSEG1ADDR(RC32434_REG_BASE + RC32434_RST)); + ((void (*)(void)) KSEG1ADDR(0x1FC00000u))(); +} + +static void rb_machine_halt(void) +{ + for (;;) + continue; +} + +void __init plat_mem_setup(void) +{ + u32 val; + + _machine_restart = rb_machine_restart; + _machine_halt = rb_machine_halt; + pm_power_off = rb_machine_halt; + + set_io_port_base(KSEG1); + + pci_reg = ioremap_nocache(pci0_res[0].start, + pci0_res[0].end - pci0_res[0].start); + if (!pci_reg) { + printk(KERN_ERR "Could not remap PCI registers\n"); + return; + } + + val = __raw_readl(&pci_reg->pcic); + val &= 0xFFFFFF7; + __raw_writel(val, (void *)&pci_reg->pcic); + +#ifdef CONFIG_PCI + /* Enable PCI interrupts in EPLD Mask register */ + *epld_mask = 0x0; + *(epld_mask + 1) = 0x0; +#endif + write_c0_wired(0); +} + +const char *get_system_type(void) +{ + switch (mips_machtype) { + case MACH_MIKROTIK_RB532A: + return "Mikrotik RB532A"; + break; + default: + return "Mikrotik RB532"; + break; + } +} diff --git a/arch/mips/rb532/time.c b/arch/mips/rb532/time.c new file mode 100644 index 00000000000..db74edf8cef --- /dev/null +++ b/arch/mips/rb532/time.c @@ -0,0 +1,67 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Setting up the clock on the MIPS boards. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern unsigned int idt_cpu_freq; + +/* + * Figure out the r4k offset, the amount to increment the compare + * register for each time tick. There is no RTC available. + * + * The RC32434 counts at half the CPU *core* speed. + */ +static unsigned long __init cal_r4koff(void) +{ + mips_hpt_frequency = idt_cpu_freq * IDT_CLOCK_MULT / 2; + + return mips_hpt_frequency / HZ; +} + +void __init plat_time_init(void) +{ + unsigned int est_freq, flags; + unsigned long r4k_offset; + + local_irq_save(flags); + + printk(KERN_INFO "calculating r4koff... "); + r4k_offset = cal_r4koff(); + printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + + est_freq = 2 * r4k_offset * HZ; + est_freq += 5000; /* round */ + est_freq -= est_freq % 10000; + printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, + (est_freq % 1000000) * 100 / 1000000); + local_irq_restore(flags); +} -- cgit v1.2.3 From 8d795f2a5cf73338a467ac82bdeb73225e987c45 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 18 Jul 2008 00:43:48 +0900 Subject: [MIPS] TXx9: Miscellaneous build fixes * Fix build if only RBTX4927 or RBTX4938 was selected. * Move gpio helpers to generic part. * Select SOC_TX4938 for RBTX4927/37 board. * Fix parent of rbtx4938_fpga_resource. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/Kconfig | 2 ++ arch/mips/txx9/generic/setup.c | 20 ++++++++++++++++++++ arch/mips/txx9/rbtx4938/setup.c | 14 +------------- 3 files changed, 23 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index b92a134ef12..6de4c5aa92b 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -7,6 +7,8 @@ config TOSHIBA_RBTX4927 bool "Toshiba RBTX49[23]7 board" depends on MACH_TX49XX select SOC_TX4927 + # TX4937 is subset of TX4938 + select SOC_TX4938 help This Toshiba board is based on the TX4927 processor. Say Y here to support this machine type diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 5afc5d5cab0..8caef07701b 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -94,6 +94,22 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL(clk_put); +/* GPIO support */ + +#ifdef CONFIG_GENERIC_GPIO +int gpio_to_irq(unsigned gpio) +{ + return -EINVAL; +} +EXPORT_SYMBOL(gpio_to_irq); + +int irq_to_gpio(unsigned irq) +{ + return -EINVAL; +} +EXPORT_SYMBOL(irq_to_gpio); +#endif + extern struct txx9_board_vec jmr3927_vec; extern struct txx9_board_vec rbtx4927_vec; extern struct txx9_board_vec rbtx4937_vec; @@ -126,15 +142,19 @@ void __init prom_init(void) #endif #ifdef CONFIG_CPU_TX49XX switch (TX4938_REV_PCODE()) { +#ifdef CONFIG_TOSHIBA_RBTX4927 case 0x4927: txx9_board_vec = &rbtx4927_vec; break; case 0x4937: txx9_board_vec = &rbtx4937_vec; break; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4938 case 0x4938: txx9_board_vec = &rbtx4938_vec; break; +#endif } #endif diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index aaa987ae0f8..c2da92396b7 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -457,7 +457,7 @@ static void __init rbtx4938_mem_setup(void) rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; - if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) + if (request_resource(&txx9_ce_res[2], &rbtx4938_fpga_resource)) printk("request resource for fpga failed\n"); _machine_restart = rbtx4938_machine_restart; @@ -488,18 +488,6 @@ static int __init rbtx4938_ne_init(void) return IS_ERR(dev) ? PTR_ERR(dev) : 0; } -/* GPIO support */ - -int gpio_to_irq(unsigned gpio) -{ - return -EINVAL; -} - -int irq_to_gpio(unsigned irq) -{ - return -EINVAL; -} - static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, -- cgit v1.2.3 From fc22c3571c86cc36f4eb29336ce40c04a666ee98 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 19:25:40 +0300 Subject: [MIPS] mips/sgi-ip22/ip28-berr.c: fix the build Commit 3e6ea3b0d7a93550a93a265e732413d3a5aaf0d2 (linux-mips.org) / 52f4f6bbcff5510f662a002ec1219660ea25af62 (kernel.org) ([MIPS] Use kernel-supplied ARRAY_SIZE() macro.) causes the following compile error: <-- snip --> ... CC arch/mips/sgi-ip22/ip28-berr.o /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c: In function 'ip28_be_interrupt': /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:415: error: subscripted value is neither array nor pointer /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:415: error: subscripted value is neither array nor pointer /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:415: warning: type defaults to 'int' in declaration of 'type name' /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:424: error: subscripted value is neither array nor pointer /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:424: error: subscripted value is neither array nor pointer /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/mips/sgi-ip22/ip28-berr.c:424: warning: type defaults to 'int' in declaration of 'type name' make[2]: *** [arch/mips/sgi-ip22/ip28-berr.o] Error 1 <-- snip --> Using ARRAY_SIZE in these places in arch/mips/sgi-ip22/ip28-berr.c was bogus, and therefore gets reverted by this patch. Signed-off-by: Adrian Bunk Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip22/ip28-berr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index fee7a2e0e53..30e12e2ec4b 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c @@ -412,7 +412,7 @@ static int ip28_be_interrupt(const struct pt_regs *regs) * Now we have an asynchronous bus error, speculatively or DMA caused. * Need to search all DMA descriptors for the error address. */ - for (i = 0; i < ARRAY_SIZE(hpc3); ++i) { + for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) { struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; if ((cpu_err_stat & CPU_ERRMASK) && (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp)) @@ -421,7 +421,7 @@ static int ip28_be_interrupt(const struct pt_regs *regs) (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp)) break; } - if (i < ARRAY_SIZE(hpc3)) { + if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) { struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:" " ctl %08x, ndp %08x, cbp %08x\n", -- cgit v1.2.3 From b5d5accc7a2eb41f43ef346f3b258ba2f6342a1c Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 18 Jul 2008 23:03:15 +0900 Subject: [MIPS] Cobalt: Fix I/O port resource range LCD and buttons don't use I/O port space. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/cobalt/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index dd23beb8604..b5164422724 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -81,8 +81,8 @@ void __init plat_mem_setup(void) set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE)); - /* I/O port resource must include LCD/buttons */ - ioport_resource.end = 0x0fffffff; + /* I/O port resource */ + ioport_resource.end = 0x01ffffff; /* These resources have been reserved by VIA SuperI/O chip. */ for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++) -- cgit v1.2.3 From 255033a9bb900a06c9a7798908ce12557d24fb66 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 19 Jul 2008 01:51:41 +0900 Subject: [MIPS] TXx9: Cleanups for 64-bit support * Unify (and fix) mem_tx4938.c and mem_tx4927.c * Simplify prom_init * Kill volatiles and unused definitions for tx4927.h and tx4938.h Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/Makefile | 2 +- arch/mips/txx9/generic/mem_tx4927.c | 94 +++++---------------------- arch/mips/txx9/generic/mem_tx4938.c | 124 ------------------------------------ arch/mips/txx9/rbtx4927/prom.c | 6 +- arch/mips/txx9/rbtx4938/prom.c | 6 +- arch/mips/txx9/rbtx4938/setup.c | 11 ++-- 6 files changed, 24 insertions(+), 219 deletions(-) delete mode 100644 arch/mips/txx9/generic/mem_tx4938.c (limited to 'arch') diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 668fdaad644..ab274ede9a7 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -5,7 +5,7 @@ obj-y += setup.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o irq_tx4927.o -obj-$(CONFIG_SOC_TX4938) += mem_tx4938.o irq_tx4938.o +obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o obj-$(CONFIG_KGDB) += dbgio.o diff --git a/arch/mips/txx9/generic/mem_tx4927.c b/arch/mips/txx9/generic/mem_tx4927.c index 12dfc377bf2..ef6ea6e9787 100644 --- a/arch/mips/txx9/generic/mem_tx4927.c +++ b/arch/mips/txx9/generic/mem_tx4927.c @@ -1,5 +1,5 @@ /* - * linux/arch/mips/tx4927/common/tx4927_prom.c + * linux/arch/mips/txx9/generic/mem_tx4927.c * * common tx4927 memory interface * @@ -32,8 +32,9 @@ #include #include #include +#include -static unsigned int __init tx4927_process_sdccr(unsigned long addr) +static unsigned int __init tx4927_process_sdccr(u64 __iomem *addr) { u64 val; unsigned int sdccr_ce; @@ -45,97 +46,32 @@ static unsigned int __init tx4927_process_sdccr(unsigned long addr) unsigned int rs = 0; unsigned int cs = 0; unsigned int mw = 0; - unsigned int msize = 0; - val = __raw_readq((void __iomem *)addr); + val = __raw_readq(addr); /* MVMCP -- need #defs for these bits masks */ sdccr_ce = ((val & (1 << 10)) >> 10); sdccr_bs = ((val & (1 << 8)) >> 8); sdccr_rs = ((val & (3 << 5)) >> 5); - sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_cs = ((val & (7 << 2)) >> 2); sdccr_mw = ((val & (1 << 0)) >> 0); if (sdccr_ce) { - switch (sdccr_bs) { - case 0:{ - bs = 2; - break; - } - case 1:{ - bs = 4; - break; - } - } - switch (sdccr_rs) { - case 0:{ - rs = 2048; - break; - } - case 1:{ - rs = 4096; - break; - } - case 2:{ - rs = 8192; - break; - } - case 3:{ - rs = 0; - break; - } - } - switch (sdccr_cs) { - case 0:{ - cs = 256; - break; - } - case 1:{ - cs = 512; - break; - } - case 2:{ - cs = 1024; - break; - } - case 3:{ - cs = 2048; - break; - } - } - switch (sdccr_mw) { - case 0:{ - mw = 8; - break; - } /* 8 bytes = 64 bits */ - case 1:{ - mw = 4; - break; - } /* 4 bytes = 32 bits */ - } + bs = 2 << sdccr_bs; + rs = 2048 << sdccr_rs; + cs = 256 << sdccr_cs; + mw = 8 >> sdccr_mw; } - /* bytes per chip MB per chip num chips */ - msize = (((rs * cs * mw) / (1024 * 1024)) * bs); - - return (msize); + return rs * cs * mw * bs; } - unsigned int __init tx4927_get_mem_size(void) { - unsigned int c0; - unsigned int c1; - unsigned int c2; - unsigned int c3; - unsigned int total; - - /* MVMCP -- need #defs for these registers */ - c0 = tx4927_process_sdccr(0xff1f8000); - c1 = tx4927_process_sdccr(0xff1f8008); - c2 = tx4927_process_sdccr(0xff1f8010); - c3 = tx4927_process_sdccr(0xff1f8018); - total = c0 + c1 + c2 + c3; + unsigned int total = 0; + int i; - return (total); + for (i = 0; i < ARRAY_SIZE(tx4927_sdramcptr->cr); i++) + total += tx4927_process_sdccr(&tx4927_sdramcptr->cr[i]); + return total; } diff --git a/arch/mips/txx9/generic/mem_tx4938.c b/arch/mips/txx9/generic/mem_tx4938.c deleted file mode 100644 index 20baeaeba4c..00000000000 --- a/arch/mips/txx9/generic/mem_tx4938.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * linux/arch/mips/tx4938/common/prom.c - * - * common tx4938 memory interface - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ - -#include -#include -#include - -static unsigned int __init -tx4938_process_sdccr(u64 * addr) -{ - u64 val; - unsigned int sdccr_ce; - unsigned int sdccr_rs; - unsigned int sdccr_cs; - unsigned int sdccr_mw; - unsigned int rs = 0; - unsigned int cs = 0; - unsigned int mw = 0; - unsigned int bc = 4; - unsigned int msize = 0; - - val = ____raw_readq((void __iomem *)addr); - - /* MVMCP -- need #defs for these bits masks */ - sdccr_ce = ((val & (1 << 10)) >> 10); - sdccr_rs = ((val & (3 << 5)) >> 5); - sdccr_cs = ((val & (7 << 2)) >> 2); - sdccr_mw = ((val & (1 << 0)) >> 0); - - if (sdccr_ce) { - switch (sdccr_rs) { - case 0:{ - rs = 2048; - break; - } - case 1:{ - rs = 4096; - break; - } - case 2:{ - rs = 8192; - break; - } - default:{ - rs = 0; - break; - } - } - switch (sdccr_cs) { - case 0:{ - cs = 256; - break; - } - case 1:{ - cs = 512; - break; - } - case 2:{ - cs = 1024; - break; - } - case 3:{ - cs = 2048; - break; - } - case 4:{ - cs = 4096; - break; - } - default:{ - cs = 0; - break; - } - } - switch (sdccr_mw) { - case 0:{ - mw = 8; - break; - } /* 8 bytes = 64 bits */ - case 1:{ - mw = 4; - break; - } /* 4 bytes = 32 bits */ - } - } - - /* bytes per chip MB per chip bank count */ - msize = (((rs * cs * mw) / (1024 * 1024)) * (bc)); - - /* MVMCP -- bc hard coded to 4 from table 9.3.1 */ - /* boad supports bc=2 but no way to detect */ - - return (msize); -} - -unsigned int __init -tx4938_get_mem_size(void) -{ - unsigned int c0; - unsigned int c1; - unsigned int c2; - unsigned int c3; - unsigned int total; - - /* MVMCP -- need #defs for these registers */ - c0 = tx4938_process_sdccr((u64 *) 0xff1f8000); - c1 = tx4938_process_sdccr((u64 *) 0xff1f8008); - c2 = tx4938_process_sdccr((u64 *) 0xff1f8010); - c3 = tx4938_process_sdccr((u64 *) 0xff1f8018); - total = c0 + c1 + c2 + c3; - - return (total); -} diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c index 942e627d2dc..5c0de54ebdd 100644 --- a/arch/mips/txx9/rbtx4927/prom.c +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -36,10 +36,6 @@ void __init rbtx4927_prom_init(void) { - extern int tx4927_get_mem_size(void); - int msize; - prom_init_cmdline(); - msize = tx4927_get_mem_size(); - add_memory_region(0, msize << 20, BOOT_MEM_RAM); + add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM); } diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c index fbb37458ddb..ee189519ce5 100644 --- a/arch/mips/txx9/rbtx4938/prom.c +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -18,12 +18,8 @@ void __init rbtx4938_prom_init(void) { - extern int tx4938_get_mem_size(void); - int msize; #ifndef CONFIG_TX4938_NAND_BOOT prom_init_cmdline(); #endif - - msize = tx4938_get_mem_size(); - add_memory_region(0, msize << 20, BOOT_MEM_RAM); + add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM); } diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index c2da92396b7..c1e076c7b2d 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -310,7 +310,7 @@ void __init tx4938_board_setup(void) printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); for (i = 0; i < 4; i++) { - unsigned long long cr = tx4938_sdramcptr->cr[i]; + u64 cr = TX4938_SDRAMC_CR(i); unsigned long ram_base, ram_size; if (!((unsigned long)cr & 0x00000400)) continue; /* disabled */ @@ -318,20 +318,21 @@ void __init tx4938_board_setup(void) ram_size = ((unsigned long)(cr >> 33) + 1) << 21; if (ram_base >= 0x20000000) continue; /* high memory (ignore) */ - printk(" CR%d:%016Lx", i, cr); + printk(KERN_CONT " CR%d:%016llx", i, cr); tx4938_sdram_resource[i].name = "SDRAM"; tx4938_sdram_resource[i].start = ram_base; tx4938_sdram_resource[i].end = ram_base + ram_size - 1; tx4938_sdram_resource[i].flags = IORESOURCE_MEM; request_resource(&iomem_resource, &tx4938_sdram_resource[i]); } - printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); + printk(KERN_CONT " TR:%09llx\n", ____raw_readq(&tx4938_sdramcptr->tr)); /* SRAM */ - if (tx4938_sramcptr->cr & 1) { + if (____raw_readq(&tx4938_sramcptr->cr) & 1) { unsigned int size = 0x800; unsigned long base = - (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); + (____raw_readq(&tx4938_sramcptr->cr) >> (39-11)) + & ~(size - 1); tx4938_sram_resource.name = "SRAM"; tx4938_sram_resource.start = base; tx4938_sram_resource.end = base + size - 1; -- cgit v1.2.3 From 94a4c32939dede9328c6e4face335eb8441fc18d Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 19 Jul 2008 01:51:47 +0900 Subject: [MIPS] TXx9: Add 64-bit support SYS_SUPPORTS_64BIT_KERNEL is enabled for RBTX4927/RBTX4938, but actually it was broken for long time (or from the beginning). Now it should work. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/Makefile | 4 +- arch/mips/txx9/generic/irq_tx4927.c | 2 +- arch/mips/txx9/generic/irq_tx4938.c | 2 +- arch/mips/txx9/generic/setup.c | 16 ++- arch/mips/txx9/generic/setup_tx4927.c | 194 +++++++++++++++++++++++++ arch/mips/txx9/generic/setup_tx4938.c | 259 ++++++++++++++++++++++++++++++++++ arch/mips/txx9/jmr3927/setup.c | 8 -- arch/mips/txx9/rbtx4927/irq.c | 12 +- arch/mips/txx9/rbtx4927/setup.c | 89 ++++-------- arch/mips/txx9/rbtx4938/setup.c | 218 ++-------------------------- 10 files changed, 510 insertions(+), 294 deletions(-) create mode 100644 arch/mips/txx9/generic/setup_tx4927.c create mode 100644 arch/mips/txx9/generic/setup_tx4938.c (limited to 'arch') diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index ab274ede9a7..9c120771e65 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -4,8 +4,8 @@ obj-y += setup.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o irq_tx4927.o -obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o irq_tx4938.o +obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o +obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o obj-$(CONFIG_KGDB) += dbgio.o diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c index 6377bd8a905..cbea1fdde82 100644 --- a/arch/mips/txx9/generic/irq_tx4927.c +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -31,7 +31,7 @@ void __init tx4927_irq_init(void) { mips_cpu_irq_init(); - txx9_irq_init(TX4927_IRC_REG); + txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL); set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, handle_simple_irq); } diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c index 5fc86c9c9d2..6eac684bf19 100644 --- a/arch/mips/txx9/generic/irq_tx4938.c +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -19,7 +19,7 @@ void __init tx4938_irq_init(void) { mips_cpu_irq_init(); - txx9_irq_init(TX4938_IRC_REG); + txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL); set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, handle_simple_irq); } diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 8caef07701b..3715a8f5ea4 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -30,6 +30,7 @@ struct resource txx9_ce_res[8]; static char txx9_ce_res_name[8][4]; /* "CEn" */ /* pcode, internal register */ +unsigned int txx9_pcode; char txx9_pcode_str[8]; static struct resource txx9_reg_res = { .name = txx9_pcode_str, @@ -59,15 +60,16 @@ unsigned int txx9_master_clock; unsigned int txx9_cpu_clock; unsigned int txx9_gbus_clock; +int txx9_ccfg_toeon __initdata = 1; /* Minimum CLK support */ struct clk *clk_get(struct device *dev, const char *id) { if (!strcmp(id, "spi-baseclk")) - return (struct clk *)(txx9_gbus_clock / 2 / 4); + return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 4); if (!strcmp(id, "imbus_clk")) - return (struct clk *)(txx9_gbus_clock / 2); + return (struct clk *)((unsigned long)txx9_gbus_clock / 2); return ERR_PTR(-ENOENT); } EXPORT_SYMBOL(clk_get); @@ -123,6 +125,12 @@ void __init prom_init_cmdline(void) int argc = (int)fw_arg0; char **argv = (char **)fw_arg1; int i; /* Always ignore the "-c" at argv[0] */ +#ifdef CONFIG_64BIT + char *fixed_argv[32]; + for (i = 0; i < argc; i++) + fixed_argv[i] = (char *)(long)(*((__s32 *)argv + i)); + argv = fixed_argv; +#endif /* ignore all built-in args if any f/w args given */ if (argc > 1) @@ -180,6 +188,10 @@ char * __init prom_getcmdline(void) /* wrappers */ void __init plat_mem_setup(void) { + ioport_resource.start = 0; + ioport_resource.end = ~0UL; /* no limit */ + iomem_resource.start = 0; + iomem_resource.end = ~0UL; /* no limit */ txx9_board_vec->mem_setup(); } diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c new file mode 100644 index 00000000000..89d6e28add9 --- /dev/null +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -0,0 +1,194 @@ +/* + * TX4927 setup routines + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * 2003-2005 (c) MontaVista Software, Inc. + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void __init tx4927_wdr_init(void) +{ + /* clear WatchDogReset (W1C) */ + tx4927_ccfg_set(TX4927_CCFG_WDRST); + /* do reset on watchdog */ + tx4927_ccfg_set(TX4927_CCFG_WR); +} + +static struct resource tx4927_sdram_resource[4]; + +void __init tx4927_setup(void) +{ + int i; + __u32 divmode; + int cpuclk = 0; + u64 ccfg; + + txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE, + TX4927_REG_SIZE); + + /* SDRAMC,EBUSC are configured by PROM */ + for (i = 0; i < 8; i++) { + if (!(TX4927_EBUSC_CR(i) & 0x8)) + continue; /* disabled */ + txx9_ce_res[i].start = (unsigned long)TX4927_EBUSC_BA(i); + txx9_ce_res[i].end = + txx9_ce_res[i].start + TX4927_EBUSC_SIZE(i) - 1; + request_resource(&iomem_resource, &txx9_ce_res[i]); + } + + /* clocks */ + ccfg = ____raw_readq(&tx4927_ccfgptr->ccfg); + if (txx9_master_clock) { + /* calculate gbus_clock and cpu_clock from master_clock */ + divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4927_CCFG_DIVMODE_8: + case TX4927_CCFG_DIVMODE_10: + case TX4927_CCFG_DIVMODE_12: + case TX4927_CCFG_DIVMODE_16: + txx9_gbus_clock = txx9_master_clock * 4; break; + default: + txx9_gbus_clock = txx9_master_clock; + } + switch (divmode) { + case TX4927_CCFG_DIVMODE_2: + case TX4927_CCFG_DIVMODE_8: + cpuclk = txx9_gbus_clock * 2; break; + case TX4927_CCFG_DIVMODE_2_5: + case TX4927_CCFG_DIVMODE_10: + cpuclk = txx9_gbus_clock * 5 / 2; break; + case TX4927_CCFG_DIVMODE_3: + case TX4927_CCFG_DIVMODE_12: + cpuclk = txx9_gbus_clock * 3; break; + case TX4927_CCFG_DIVMODE_4: + case TX4927_CCFG_DIVMODE_16: + cpuclk = txx9_gbus_clock * 4; break; + } + txx9_cpu_clock = cpuclk; + } else { + if (txx9_cpu_clock == 0) + txx9_cpu_clock = 200000000; /* 200MHz */ + /* calculate gbus_clock and master_clock from cpu_clock */ + cpuclk = txx9_cpu_clock; + divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4927_CCFG_DIVMODE_2: + case TX4927_CCFG_DIVMODE_8: + txx9_gbus_clock = cpuclk / 2; break; + case TX4927_CCFG_DIVMODE_2_5: + case TX4927_CCFG_DIVMODE_10: + txx9_gbus_clock = cpuclk * 2 / 5; break; + case TX4927_CCFG_DIVMODE_3: + case TX4927_CCFG_DIVMODE_12: + txx9_gbus_clock = cpuclk / 3; break; + case TX4927_CCFG_DIVMODE_4: + case TX4927_CCFG_DIVMODE_16: + txx9_gbus_clock = cpuclk / 4; break; + } + switch (divmode) { + case TX4927_CCFG_DIVMODE_8: + case TX4927_CCFG_DIVMODE_10: + case TX4927_CCFG_DIVMODE_12: + case TX4927_CCFG_DIVMODE_16: + txx9_master_clock = txx9_gbus_clock / 4; break; + default: + txx9_master_clock = txx9_gbus_clock; + } + } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + + /* CCFG */ + tx4927_wdr_init(); + /* clear BusErrorOnWrite flag (W1C) */ + tx4927_ccfg_set(TX4927_CCFG_BEOW); + /* enable Timeout BusError */ + if (txx9_ccfg_toeon) + tx4927_ccfg_set(TX4927_CCFG_TOE); + + /* DMA selection */ + txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_DMASEL_ALL); + + /* Use external clock for external arbiter */ + if (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB)) + txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_PCICLKEN_ALL); + + printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", + txx9_pcode_str, + (cpuclk + 500000) / 1000000, + (txx9_master_clock + 500000) / 1000000, + (__u32)____raw_readq(&tx4927_ccfgptr->crir), + (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4927_ccfgptr->pcfg)); + + printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); + for (i = 0; i < 4; i++) { + __u64 cr = TX4927_SDRAMC_CR(i); + unsigned long base, size; + if (!((__u32)cr & 0x00000400)) + continue; /* disabled */ + base = (unsigned long)(cr >> 49) << 21; + size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21; + printk(" CR%d:%016llx", i, (unsigned long long)cr); + tx4927_sdram_resource[i].name = "SDRAM"; + tx4927_sdram_resource[i].start = base; + tx4927_sdram_resource[i].end = base + size - 1; + tx4927_sdram_resource[i].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4927_sdram_resource[i]); + } + printk(" TR:%09llx\n", + (unsigned long long)____raw_readq(&tx4927_sdramcptr->tr)); + + /* TMR */ + /* disable all timers */ + for (i = 0; i < TX4927_NR_TMR; i++) + txx9_tmr_init(TX4927_TMR_REG(i) & 0xfffffffffULL); + + /* PIO */ + txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); + __raw_writel(0, &tx4927_pioptr->maskcpu); + __raw_writel(0, &tx4927_pioptr->maskext); +} + +void __init tx4927_time_init(unsigned int tmrnr) +{ + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) + txx9_clockevent_init(TX4927_TMR_REG(tmrnr) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4927_IR_TMR(tmrnr), + TXX9_IMCLK); +} + +void __init tx4927_setup_serial(void) +{ +#ifdef CONFIG_SERIAL_TXX9 + int i; + struct uart_port req; + + for (i = 0; i < 2; i++) { + memset(&req, 0, sizeof(req)); + req.line = i; + req.iotype = UPIO_MEM; + req.membase = (unsigned char __iomem *)TX4927_SIO_REG(i); + req.mapbase = TX4927_SIO_REG(i) & 0xfffffffffULL; + req.irq = TXX9_IRQ_BASE + TX4927_IR_SIO(i); + req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; + req.uartclk = TXX9_IMCLK; + early_serial_txx9_setup(&req); + } +#endif /* CONFIG_SERIAL_TXX9 */ +} diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c new file mode 100644 index 00000000000..317378d8579 --- /dev/null +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -0,0 +1,259 @@ +/* + * TX4938/4937 setup routines + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * 2003-2005 (c) MontaVista Software, Inc. + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void __init tx4938_wdr_init(void) +{ + /* clear WatchDogReset (W1C) */ + tx4938_ccfg_set(TX4938_CCFG_WDRST); + /* do reset on watchdog */ + tx4938_ccfg_set(TX4938_CCFG_WR); +} + +static struct resource tx4938_sdram_resource[4]; +static struct resource tx4938_sram_resource; + +#define TX4938_SRAM_SIZE 0x800 + +void __init tx4938_setup(void) +{ + int i; + __u32 divmode; + int cpuclk = 0; + u64 ccfg; + + txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, + TX4938_REG_SIZE); + + /* SDRAMC,EBUSC are configured by PROM */ + for (i = 0; i < 8; i++) { + if (!(TX4938_EBUSC_CR(i) & 0x8)) + continue; /* disabled */ + txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); + txx9_ce_res[i].end = + txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; + request_resource(&iomem_resource, &txx9_ce_res[i]); + } + + /* clocks */ + ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); + if (txx9_master_clock) { + /* calculate gbus_clock and cpu_clock from master_clock */ + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4938_CCFG_DIVMODE_8: + case TX4938_CCFG_DIVMODE_10: + case TX4938_CCFG_DIVMODE_12: + case TX4938_CCFG_DIVMODE_16: + case TX4938_CCFG_DIVMODE_18: + txx9_gbus_clock = txx9_master_clock * 4; break; + default: + txx9_gbus_clock = txx9_master_clock; + } + switch (divmode) { + case TX4938_CCFG_DIVMODE_2: + case TX4938_CCFG_DIVMODE_8: + cpuclk = txx9_gbus_clock * 2; break; + case TX4938_CCFG_DIVMODE_2_5: + case TX4938_CCFG_DIVMODE_10: + cpuclk = txx9_gbus_clock * 5 / 2; break; + case TX4938_CCFG_DIVMODE_3: + case TX4938_CCFG_DIVMODE_12: + cpuclk = txx9_gbus_clock * 3; break; + case TX4938_CCFG_DIVMODE_4: + case TX4938_CCFG_DIVMODE_16: + cpuclk = txx9_gbus_clock * 4; break; + case TX4938_CCFG_DIVMODE_4_5: + case TX4938_CCFG_DIVMODE_18: + cpuclk = txx9_gbus_clock * 9 / 2; break; + } + txx9_cpu_clock = cpuclk; + } else { + if (txx9_cpu_clock == 0) + txx9_cpu_clock = 300000000; /* 300MHz */ + /* calculate gbus_clock and master_clock from cpu_clock */ + cpuclk = txx9_cpu_clock; + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4938_CCFG_DIVMODE_2: + case TX4938_CCFG_DIVMODE_8: + txx9_gbus_clock = cpuclk / 2; break; + case TX4938_CCFG_DIVMODE_2_5: + case TX4938_CCFG_DIVMODE_10: + txx9_gbus_clock = cpuclk * 2 / 5; break; + case TX4938_CCFG_DIVMODE_3: + case TX4938_CCFG_DIVMODE_12: + txx9_gbus_clock = cpuclk / 3; break; + case TX4938_CCFG_DIVMODE_4: + case TX4938_CCFG_DIVMODE_16: + txx9_gbus_clock = cpuclk / 4; break; + case TX4938_CCFG_DIVMODE_4_5: + case TX4938_CCFG_DIVMODE_18: + txx9_gbus_clock = cpuclk * 2 / 9; break; + } + switch (divmode) { + case TX4938_CCFG_DIVMODE_8: + case TX4938_CCFG_DIVMODE_10: + case TX4938_CCFG_DIVMODE_12: + case TX4938_CCFG_DIVMODE_16: + case TX4938_CCFG_DIVMODE_18: + txx9_master_clock = txx9_gbus_clock / 4; break; + default: + txx9_master_clock = txx9_gbus_clock; + } + } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + + /* CCFG */ + tx4938_wdr_init(); + /* clear BusErrorOnWrite flag (W1C) */ + tx4938_ccfg_set(TX4938_CCFG_BEOW); + /* enable Timeout BusError */ + if (txx9_ccfg_toeon) + tx4938_ccfg_set(TX4938_CCFG_TOE); + + /* DMA selection */ + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); + + /* Use external clock for external arbiter */ + if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); + + printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", + txx9_pcode_str, + (cpuclk + 500000) / 1000000, + (txx9_master_clock + 500000) / 1000000, + (__u32)____raw_readq(&tx4938_ccfgptr->crir), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); + + printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); + for (i = 0; i < 4; i++) { + __u64 cr = TX4938_SDRAMC_CR(i); + unsigned long base, size; + if (!((__u32)cr & 0x00000400)) + continue; /* disabled */ + base = (unsigned long)(cr >> 49) << 21; + size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21; + printk(" CR%d:%016llx", i, (unsigned long long)cr); + tx4938_sdram_resource[i].name = "SDRAM"; + tx4938_sdram_resource[i].start = base; + tx4938_sdram_resource[i].end = base + size - 1; + tx4938_sdram_resource[i].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sdram_resource[i]); + } + printk(" TR:%09llx\n", + (unsigned long long)____raw_readq(&tx4938_sdramcptr->tr)); + + /* SRAM */ + if (txx9_pcode == 0x4938 && ____raw_readq(&tx4938_sramcptr->cr) & 1) { + unsigned int size = TX4938_SRAM_SIZE; + tx4938_sram_resource.name = "SRAM"; + tx4938_sram_resource.start = + (____raw_readq(&tx4938_sramcptr->cr) >> (39-11)) + & ~(size - 1); + tx4938_sram_resource.end = + tx4938_sram_resource.start + TX4938_SRAM_SIZE - 1; + tx4938_sram_resource.flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sram_resource); + } + + /* TMR */ + /* disable all timers */ + for (i = 0; i < TX4938_NR_TMR; i++) + txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); + + /* DMA */ + for (i = 0; i < 2; i++) + ____raw_writeq(TX4938_DMA_MCR_MSTEN, + (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); + + /* PIO */ + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); + __raw_writel(0, &tx4938_pioptr->maskcpu); + __raw_writel(0, &tx4938_pioptr->maskext); + + if (txx9_pcode == 0x4938) { + __u64 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); + /* set PCIC1 reset */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); + if (pcfg & (TX4938_PCFG_ETH0_SEL | TX4938_PCFG_ETH1_SEL)) { + mdelay(1); /* at least 128 cpu clock */ + /* clear PCIC1 reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_PCIC1RST); + } else { + printk(KERN_INFO "%s: stop PCIC1\n", txx9_pcode_str); + /* stop PCIC1 */ + txx9_set64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_PCIC1CKD); + } + if (!(pcfg & TX4938_PCFG_ETH0_SEL)) { + printk(KERN_INFO "%s: stop ETH0\n", txx9_pcode_str); + txx9_set64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_ETH0RST); + txx9_set64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_ETH0CKD); + } + if (!(pcfg & TX4938_PCFG_ETH1_SEL)) { + printk(KERN_INFO "%s: stop ETH1\n", txx9_pcode_str); + txx9_set64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_ETH1RST); + txx9_set64(&tx4938_ccfgptr->clkctr, + TX4938_CLKCTR_ETH1CKD); + } + } +} + +void __init tx4938_time_init(unsigned int tmrnr) +{ + if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) + txx9_clockevent_init(TX4938_TMR_REG(tmrnr) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4938_IR_TMR(tmrnr), + TXX9_IMCLK); +} + +void __init tx4938_setup_serial(void) +{ +#ifdef CONFIG_SERIAL_TXX9 + int i; + struct uart_port req; + unsigned int ch_mask = 0; + + if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_ETH0_SEL) + ch_mask |= 1 << 1; /* disable SIO1 by PCFG setting */ + for (i = 0; i < 2; i++) { + if ((1 << i) & ch_mask) + continue; + memset(&req, 0, sizeof(req)); + req.line = i; + req.iotype = UPIO_MEM; + req.membase = (unsigned char __iomem *)TX4938_SIO_REG(i); + req.mapbase = TX4938_SIO_REG(i) & 0xfffffffffULL; + req.irq = TXX9_IRQ_BASE + TX4938_IR_SIO(i); + req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; + req.uartclk = TXX9_IMCLK; + early_serial_txx9_setup(&req); + } +#endif /* CONFIG_SERIAL_TXX9 */ +} diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 5e35ef73c5a..03647ebe413 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -105,14 +105,6 @@ static void __init jmr3927_mem_setup(void) _machine_halt = jmr3927_machine_halt; pm_power_off = jmr3927_machine_power_off; - /* - * IO/MEM resources. - */ - ioport_resource.start = 0; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0; - iomem_resource.end = 0xffffffff; - /* Reboot on panic */ panic_timeout = 180; diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index 70f13211bc2..cd748a93032 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -126,14 +126,12 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { .mask_ack = toshiba_rbtx4927_irq_ioc_disable, .unmask = toshiba_rbtx4927_irq_ioc_enable, }; -#define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL -#define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL static int toshiba_rbtx4927_irq_nested(int sw_irq) { u8 level3; - level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + level3 = readb(rbtx4927_imstat_addr) & 0x1f; if (level3) sw_irq = RBTX4927_IRQ_IOC + fls(level3) - 1; return (sw_irq); @@ -154,18 +152,18 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) { unsigned char v; - v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v = readb(rbtx4927_imask_addr); v |= (1 << (irq - RBTX4927_IRQ_IOC)); - writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); + writeb(v, rbtx4927_imask_addr); } static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) { unsigned char v; - v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v = readb(rbtx4927_imask_addr); v &= ~(1 << (irq - RBTX4927_IRQ_IOC)); - writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); + writeb(v, rbtx4927_imask_addr); mmiowb(); } diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 1657fd935da..3da20ea3e55 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -53,17 +53,10 @@ #include #include #include -#include -#include #include #include #include #include /* for TX4937 */ -#ifdef CONFIG_SERIAL_TXX9 -#include -#endif - -static int tx4927_ccfg_toeon = 1; #ifdef CONFIG_PCI static void __init tx4927_pci_setup(void) @@ -184,14 +177,14 @@ static void toshiba_rbtx4927_restart(char *command) printk(KERN_NOTICE "System Rebooting...\n"); /* enable the s/w reset register */ - writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE); + writeb(1, rbtx4927_softresetlock_addr); /* wait for enable to be seen */ - while ((readb(RBTX4927_SW_RESET_ENABLE) & - RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + while (!(readb(rbtx4927_softresetlock_addr) & 1)) + ; /* do a s/w reset */ - writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO); + writeb(1, rbtx4927_softreset_addr); /* do something passive while waiting for reset */ local_irq_disable(); @@ -213,9 +206,11 @@ static void toshiba_rbtx4927_power_off(void) /* no return */ } +static void __init rbtx4927_clock_init(void); +static void __init rbtx4937_clock_init(void); + static void __init rbtx4927_mem_setup(void) { - int i; u32 cp0_config; char *argptr; @@ -227,16 +222,18 @@ static void __init rbtx4927_mem_setup(void) cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); write_c0_config(cp0_config); - ioport_resource.end = 0xffffffff; - iomem_resource.end = 0xffffffff; + if (TX4927_REV_PCODE() == 0x4927) { + rbtx4927_clock_init(); + tx4927_setup(); + } else { + rbtx4937_clock_init(); + tx4938_setup(); + } _machine_restart = toshiba_rbtx4927_restart; _machine_halt = toshiba_rbtx4927_halt; pm_power_off = toshiba_rbtx4927_power_off; - for (i = 0; i < TX4927_NR_TMR; i++) - txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); - #ifdef CONFIG_PCI txx9_alloc_pci_controller(&txx9_primary_pcic, RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE, @@ -245,36 +242,13 @@ static void __init rbtx4927_mem_setup(void) set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); #endif - /* CCFG */ - /* do reset on watchdog */ - tx4927_ccfg_set(TX4927_CCFG_WR); - /* enable Timeout BusError */ - if (tx4927_ccfg_toeon) - tx4927_ccfg_set(TX4927_CCFG_TOE); - -#ifdef CONFIG_SERIAL_TXX9 - { - extern int early_serial_txx9_setup(struct uart_port *port); - struct uart_port req; - for(i = 0; i < 2; i++) { - memset(&req, 0, sizeof(req)); - req.line = i; - req.iotype = UPIO_MEM; - req.membase = (char *)(0xff1ff300 + i * 0x100); - req.mapbase = 0xff1ff300 + i * 0x100; - req.irq = TXX9_IRQ_BASE + TX4927_IR_SIO(i); - req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; - req.uartclk = 50000000; - early_serial_txx9_setup(&req); - } - } + tx4927_setup_serial(); #ifdef CONFIG_SERIAL_TXX9_CONSOLE argptr = prom_getcmdline(); if (strstr(argptr, "console=") == NULL) { strcat(argptr, " console=ttyS0,38400"); } #endif -#endif #ifdef CONFIG_ROOT_NFS argptr = prom_getcmdline(); @@ -291,19 +265,7 @@ static void __init rbtx4927_mem_setup(void) #endif } -static void __init rbtx49x7_common_time_init(void) -{ - /* change default value to udelay/mdelay take reasonable time */ - loops_per_jiffy = txx9_cpu_clock / HZ / 2; - - mips_hpt_frequency = txx9_cpu_clock / 2; - if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) - txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, - TXX9_IRQ_BASE + 17, - 50000000); -} - -static void __init rbtx4927_time_init(void) +static void __init rbtx4927_clock_init(void) { /* * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. @@ -325,11 +287,9 @@ static void __init rbtx4927_time_init(void) default: txx9_cpu_clock = 200000000; /* 200MHz */ } - - rbtx49x7_common_time_init(); } -static void __init rbtx4937_time_init(void) +static void __init rbtx4937_clock_init(void) { /* * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. @@ -357,15 +317,18 @@ static void __init rbtx4937_time_init(void) default: txx9_cpu_clock = 333333333; /* 333MHz */ } +} - rbtx49x7_common_time_init(); +static void __init rbtx4927_time_init(void) +{ + tx4927_time_init(0); } static int __init toshiba_rbtx4927_rtc_init(void) { - static struct resource __initdata res = { - .start = 0x1c010000, - .end = 0x1c010000 + 0x800 - 1, + struct resource res = { + .start = RBTX4927_BRAMRTC_BASE - IO_BASE, + .end = RBTX4927_BRAMRTC_BASE - IO_BASE + 0x800 - 1, .flags = IORESOURCE_MEM, }; struct platform_device *dev = @@ -375,7 +338,7 @@ static int __init toshiba_rbtx4927_rtc_init(void) static int __init rbtx4927_ne_init(void) { - static struct resource __initdata res[] = { + struct resource res[] = { { .start = RBTX4927_RTL_8019_BASE, .end = RBTX4927_RTL_8019_BASE + 0x20 - 1, @@ -434,7 +397,7 @@ struct txx9_board_vec rbtx4937_vec __initdata = { .prom_init = rbtx4927_prom_init, .mem_setup = rbtx4927_mem_setup, .irq_setup = rbtx4927_irq_setup, - .time_init = rbtx4937_time_init, + .time_init = rbtx4927_time_init, .device_init = rbtx4927_device_init, .arch_init = rbtx4937_arch_init, #ifdef CONFIG_PCI diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index c1e076c7b2d..6c2b99bb8af 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -20,21 +20,14 @@ #include #include -#include -#include #include #include #include #include -#ifdef CONFIG_SERIAL_TXX9 -#include -#endif #include #include #include -static int tx4938_ccfg_toeon = 1; - static void rbtx4938_machine_halt(void) { printk(KERN_NOTICE "System Halted\n"); @@ -182,189 +175,10 @@ static void __init rbtx4938_spi_setup(void) } static struct resource rbtx4938_fpga_resource; -static struct resource tx4938_sdram_resource[4]; -static struct resource tx4938_sram_resource; - -void __init tx4938_board_setup(void) -{ - int i; - unsigned long divmode; - int cpuclk = 0; - unsigned long pcode = TX4938_REV_PCODE(); - - ioport_resource.start = 0; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0; - iomem_resource.end = 0xffffffff; /* expand to 4GB */ - - txx9_reg_res_init(pcode, TX4938_REG_BASE, - TX4938_REG_SIZE); - /* SDRAMC,EBUSC are configured by PROM */ - for (i = 0; i < 8; i++) { - if (!(TX4938_EBUSC_CR(i) & 0x8)) - continue; /* disabled */ - txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); - txx9_ce_res[i].end = - txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; - request_resource(&iomem_resource, &txx9_ce_res[i]); - } - - /* clocks */ - if (txx9_master_clock) { - u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); - /* calculate gbus_clock and cpu_clock_freq from master_clock */ - divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; - switch (divmode) { - case TX4938_CCFG_DIVMODE_8: - case TX4938_CCFG_DIVMODE_10: - case TX4938_CCFG_DIVMODE_12: - case TX4938_CCFG_DIVMODE_16: - case TX4938_CCFG_DIVMODE_18: - txx9_gbus_clock = txx9_master_clock * 4; break; - default: - txx9_gbus_clock = txx9_master_clock; - } - switch (divmode) { - case TX4938_CCFG_DIVMODE_2: - case TX4938_CCFG_DIVMODE_8: - cpuclk = txx9_gbus_clock * 2; break; - case TX4938_CCFG_DIVMODE_2_5: - case TX4938_CCFG_DIVMODE_10: - cpuclk = txx9_gbus_clock * 5 / 2; break; - case TX4938_CCFG_DIVMODE_3: - case TX4938_CCFG_DIVMODE_12: - cpuclk = txx9_gbus_clock * 3; break; - case TX4938_CCFG_DIVMODE_4: - case TX4938_CCFG_DIVMODE_16: - cpuclk = txx9_gbus_clock * 4; break; - case TX4938_CCFG_DIVMODE_4_5: - case TX4938_CCFG_DIVMODE_18: - cpuclk = txx9_gbus_clock * 9 / 2; break; - } - txx9_cpu_clock = cpuclk; - } else { - u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); - if (txx9_cpu_clock == 0) { - txx9_cpu_clock = 300000000; /* 300MHz */ - } - /* calculate gbus_clock and master_clock from cpu_clock_freq */ - cpuclk = txx9_cpu_clock; - divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; - switch (divmode) { - case TX4938_CCFG_DIVMODE_2: - case TX4938_CCFG_DIVMODE_8: - txx9_gbus_clock = cpuclk / 2; break; - case TX4938_CCFG_DIVMODE_2_5: - case TX4938_CCFG_DIVMODE_10: - txx9_gbus_clock = cpuclk * 2 / 5; break; - case TX4938_CCFG_DIVMODE_3: - case TX4938_CCFG_DIVMODE_12: - txx9_gbus_clock = cpuclk / 3; break; - case TX4938_CCFG_DIVMODE_4: - case TX4938_CCFG_DIVMODE_16: - txx9_gbus_clock = cpuclk / 4; break; - case TX4938_CCFG_DIVMODE_4_5: - case TX4938_CCFG_DIVMODE_18: - txx9_gbus_clock = cpuclk * 2 / 9; break; - } - switch (divmode) { - case TX4938_CCFG_DIVMODE_8: - case TX4938_CCFG_DIVMODE_10: - case TX4938_CCFG_DIVMODE_12: - case TX4938_CCFG_DIVMODE_16: - case TX4938_CCFG_DIVMODE_18: - txx9_master_clock = txx9_gbus_clock / 4; break; - default: - txx9_master_clock = txx9_gbus_clock; - } - } - /* change default value to udelay/mdelay take reasonable time */ - loops_per_jiffy = txx9_cpu_clock / HZ / 2; - - /* CCFG */ - /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ - tx4938_ccfg_set(TX4938_CCFG_WDRST | TX4938_CCFG_BEOW); - /* do reset on watchdog */ - tx4938_ccfg_set(TX4938_CCFG_WR); - /* clear PCIC1 reset */ - txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); - - /* enable Timeout BusError */ - if (tx4938_ccfg_toeon) - tx4938_ccfg_set(TX4938_CCFG_TOE); - - /* DMA selection */ - txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); - - /* Use external clock for external arbiter */ - if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) - txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); - - printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", - txx9_pcode_str, - (cpuclk + 500000) / 1000000, - (txx9_master_clock + 500000) / 1000000, - (__u32)____raw_readq(&tx4938_ccfgptr->crir), - (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), - (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); - - printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); - for (i = 0; i < 4; i++) { - u64 cr = TX4938_SDRAMC_CR(i); - unsigned long ram_base, ram_size; - if (!((unsigned long)cr & 0x00000400)) - continue; /* disabled */ - ram_base = (unsigned long)(cr >> 49) << 21; - ram_size = ((unsigned long)(cr >> 33) + 1) << 21; - if (ram_base >= 0x20000000) - continue; /* high memory (ignore) */ - printk(KERN_CONT " CR%d:%016llx", i, cr); - tx4938_sdram_resource[i].name = "SDRAM"; - tx4938_sdram_resource[i].start = ram_base; - tx4938_sdram_resource[i].end = ram_base + ram_size - 1; - tx4938_sdram_resource[i].flags = IORESOURCE_MEM; - request_resource(&iomem_resource, &tx4938_sdram_resource[i]); - } - printk(KERN_CONT " TR:%09llx\n", ____raw_readq(&tx4938_sdramcptr->tr)); - - /* SRAM */ - if (____raw_readq(&tx4938_sramcptr->cr) & 1) { - unsigned int size = 0x800; - unsigned long base = - (____raw_readq(&tx4938_sramcptr->cr) >> (39-11)) - & ~(size - 1); - tx4938_sram_resource.name = "SRAM"; - tx4938_sram_resource.start = base; - tx4938_sram_resource.end = base + size - 1; - tx4938_sram_resource.flags = IORESOURCE_MEM; - request_resource(&iomem_resource, &tx4938_sram_resource); - } - - /* TMR */ - for (i = 0; i < TX4938_NR_TMR; i++) - txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); - - /* enable DMA */ - for (i = 0; i < 2; i++) - ____raw_writeq(TX4938_DMA_MCR_MSTEN, - (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); - - /* PIO */ - __raw_writel(0, &tx4938_pioptr->maskcpu); - __raw_writel(0, &tx4938_pioptr->maskext); - -#ifdef CONFIG_PCI - txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); -#endif -} static void __init rbtx4938_time_init(void) { - mips_hpt_frequency = txx9_cpu_clock / 2; - if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) - txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, - TXX9_IRQ_BASE + TX4938_IR_TMR(0), - txx9_gbus_clock / 2); + tx4938_time_init(0); } static void __init rbtx4938_mem_setup(void) @@ -372,39 +186,24 @@ static void __init rbtx4938_mem_setup(void) unsigned long long pcfg; char *argptr; - iomem_resource.end = 0xffffffff; /* 4GB */ - if (txx9_master_clock == 0) txx9_master_clock = 25000000; /* 25MHz */ - tx4938_board_setup(); -#ifndef CONFIG_PCI + + tx4938_setup(); + +#ifdef CONFIG_PCI + txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); +#else set_io_port_base(RBTX4938_ETHER_BASE); #endif -#ifdef CONFIG_SERIAL_TXX9 - { - extern int early_serial_txx9_setup(struct uart_port *port); - int i; - struct uart_port req; - for(i = 0; i < 2; i++) { - memset(&req, 0, sizeof(req)); - req.line = i; - req.iotype = UPIO_MEM; - req.membase = (char *)(0xff1ff300 + i * 0x100); - req.mapbase = 0xff1ff300 + i * 0x100; - req.irq = RBTX4938_IRQ_IRC_SIO(i); - req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; - req.uartclk = 50000000; - early_serial_txx9_setup(&req); - } - } + tx4938_setup_serial(); #ifdef CONFIG_SERIAL_TXX9_CONSOLE argptr = prom_getcmdline(); if (strstr(argptr, "console=") == NULL) { strcat(argptr, " console=ttyS0,38400"); } #endif -#endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 printk("PIOSEL: disabling both ata and nand selection\n"); @@ -568,7 +367,6 @@ static int __init rbtx4938_spi_init(void) static void __init rbtx4938_arch_init(void) { - txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); gpiochip_add(&rbtx4938_spi_gpio_chip); rbtx4938_pci_setup(); rbtx4938_spi_init(); -- cgit v1.2.3 From e0eb730757665d7e8ec0e79d9042a9311f3edb7e Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 19 Jul 2008 01:51:52 +0900 Subject: [MIPS] TXx9: Fix some sparse warnings Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 3715a8f5ea4..8c60c78b9a9 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #ifdef CONFIG_CPU_TX49XX #include -- cgit v1.2.3 From 4914ad4a9f2d484a68422700ba8493db73c7c411 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 20 Jul 2008 11:34:39 +0100 Subject: [MIPS] 32-bit compat: Delete unused sys_truncate64 and sys_ftruncate64. Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 65af3cc90ab..c266211ed65 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -129,23 +129,6 @@ out: return error; } - -asmlinkage int sys_truncate64(const char __user *path, unsigned int high, - unsigned int low) -{ - if ((int)high < 0) - return -EINVAL; - return sys_truncate(path, ((long) high << 32) | low); -} - -asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high, - unsigned int low) -{ - if ((int)high < 0) - return -EINVAL; - return sys_ftruncate(fd, ((long) high << 32) | low); -} - /* * sys_execve() executes a new program. */ -- cgit v1.2.3 From 8213bbf9c1c0009872a3278aa7a83ec8f3508195 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 20 Jul 2008 13:16:46 +0100 Subject: [MIPS] Rename MIPS sys_pipe syscall entry point to something MIPS-specific. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 2 +- arch/mips/kernel/scall64-64.S | 2 +- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- arch/mips/kernel/syscall.c | 9 ++++++++- 5 files changed, 12 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index c058c0b61a2..fc4fd4d705e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -354,7 +354,7 @@ einval: li v0, -EINVAL sys sys_mkdir 2 sys sys_rmdir 1 /* 4040 */ sys sys_dup 1 - sys sys_pipe 0 + sys sysm_pipe 0 sys sys_times 1 sys sys_ni_syscall 0 sys sys_brk 1 /* 4045 */ diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index dc597b600c6..2b73fd1e452 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -219,7 +219,7 @@ sys_call_table: PTR sys_readv PTR sys_writev PTR sys_access /* 5020 */ - PTR sys_pipe + PTR sysm_pipe PTR sys_select PTR sys_sched_yield PTR sys_mremap diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 12940eca789..2654e75d2fe 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -141,7 +141,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_readv PTR compat_sys_writev PTR sys_access /* 6020 */ - PTR sys_pipe + PTR sysm_pipe PTR compat_sys_select PTR sys_sched_yield PTR sys_mremap diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 9a275efb4f0..76167bea5a7 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -247,7 +247,7 @@ sys_call_table: PTR sys_mkdir PTR sys_rmdir /* 4040 */ PTR sys_dup - PTR sys_pipe + PTR sysm_pipe PTR compat_sys_times PTR sys_ni_syscall PTR sys_brk /* 4045 */ diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index af1bdc89748..3523c8d12ed 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -40,7 +40,14 @@ #include #include -asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs) +/* + * For historic reasons the pipe(2) syscall on MIPS has an unusual calling + * convention. It returns results in registers $v0 / $v1 which means there + * is no need for it to do verify the validity of a userspace pointer + * argument. Historically that used to be expensive in Linux. These days + * the performance advantage is negligible. + */ +asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs) { int fd[2]; int error, res; -- cgit v1.2.3 From 15648f154a8faea97cbe931e189cf0a57fd066f4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 16 Jul 2008 21:52:25 +0100 Subject: simserial: Fix up for ldisc changes Noted by Tony Luck although I've done the patches differently and also removed some other bogus oddments. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- arch/ia64/hp/sim/simserial.c | 46 +++----------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 23cafc80d2a..24b1ad5334c 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -193,18 +193,6 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) * ------------------------------------------------------------------- */ -#if 0 -/* - * not really used in our situation so keep them commented out for now - */ -static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); - printk(KERN_ERR "do_serial_bh: called\n"); -} -#endif - static void do_softint(struct work_struct *private_) { printk(KERN_ERR "simserial: do_softint called\n"); @@ -351,11 +339,7 @@ static void rs_flush_buffer(struct tty_struct *tty) info->xmit.head = info->xmit.tail = 0; local_irq_restore(flags); - wake_up_interruptible(&tty->write_wait); - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); + tty_wakeup(tty); } /* @@ -404,12 +388,6 @@ static void rs_unthrottle(struct tty_struct * tty) printk(KERN_INFO "simrs_unthrottle called\n"); } -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ -} static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) @@ -422,14 +400,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, } switch (cmd) { - case TIOCMGET: - printk(KERN_INFO "rs_ioctl: TIOCMGET called\n"); - return -EINVAL; - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n"); - return -EINVAL; case TIOCGSERIAL: printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); return 0; @@ -488,14 +458,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { @@ -623,9 +585,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp) * the line discipline to only process XON/XOFF characters. */ shutdown(info); - if (tty->ops->flush_buffer) - tty->ops->flush_buffer(tty); - if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); + rs_flush_buffer(tty); + tty_ldisc_flush(tty); info->event = 0; info->tty = NULL; if (info->blocked_open) { @@ -955,7 +916,6 @@ static const struct tty_operations hp_ops = { .stop = rs_stop, .start = rs_start, .hangup = rs_hangup, - .break_ctl = rs_break, .wait_until_sent = rs_wait_until_sent, .read_proc = rs_read_proc, }; -- cgit v1.2.3 From 34492b5834ede63d896c93ccba9a4657a8435dc2 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 16 Jul 2008 21:54:01 +0100 Subject: MN10300: Fix MN10300's serial port driver to get at its tty_struct Fix MN10300's serial port driver to get at its tty_struct as this moved from struct uart_info into struct tty_port in patch: Signed-off-by: David Howells Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/mn10300-serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index b9c268c6b2f..8b054e7a8ae 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -392,7 +392,7 @@ static int mask_test_and_clear(volatile u8 *ptr, u8 mask) static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) { struct uart_icount *icount = &port->uart.icount; - struct tty_struct *tty = port->uart.info->tty; + struct tty_struct *tty = port->uart.info->port.tty; unsigned ix; int count; u8 st, ch, push, status, overrun; -- cgit v1.2.3 From f30828a6745281edda735f642b5f814e1123ecd3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:08 +0200 Subject: m68k: remove CVS keywords This patch removes CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/sun3/idprom.c | 2 +- arch/m68k/sun3/prom/Makefile | 1 - arch/m68k/sun3/prom/console.c | 2 +- arch/m68k/sun3/prom/init.c | 2 +- arch/m68k/sun3/prom/misc.c | 2 +- arch/m68k/sun3/prom/printf.c | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c index dca6ab6a4ed..6c5336d62fa 100644 --- a/arch/m68k/sun3/idprom.c +++ b/arch/m68k/sun3/idprom.c @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.22 1996/11/13 05:09:25 davem Exp $ +/* * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * diff --git a/arch/m68k/sun3/prom/Makefile b/arch/m68k/sun3/prom/Makefile index 6e48ae2a717..da7eac06bca 100644 --- a/arch/m68k/sun3/prom/Makefile +++ b/arch/m68k/sun3/prom/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.5 1995/11/25 00:59:48 davem Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # diff --git a/arch/m68k/sun3/prom/console.c b/arch/m68k/sun3/prom/console.c index 52c1427863d..5812560b70f 100644 --- a/arch/m68k/sun3/prom/console.c +++ b/arch/m68k/sun3/prom/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.10 1996/12/18 06:46:54 tridge Exp $ +/* * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * diff --git a/arch/m68k/sun3/prom/init.c b/arch/m68k/sun3/prom/init.c index 202adfcc316..5f85681af5a 100644 --- a/arch/m68k/sun3/prom/init.c +++ b/arch/m68k/sun3/prom/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.9 1996/12/18 06:46:55 tridge Exp $ +/* * init.c: Initialize internal variables used by the PROM * library functions. * diff --git a/arch/m68k/sun3/prom/misc.c b/arch/m68k/sun3/prom/misc.c index b88716f2c68..3d60e1337f7 100644 --- a/arch/m68k/sun3/prom/misc.c +++ b/arch/m68k/sun3/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.15 1997/05/14 20:45:00 davem Exp $ +/* * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * diff --git a/arch/m68k/sun3/prom/printf.c b/arch/m68k/sun3/prom/printf.c index e7bfde377b5..c8cf98d97f2 100644 --- a/arch/m68k/sun3/prom/printf.c +++ b/arch/m68k/sun3/prom/printf.c @@ -1,4 +1,4 @@ -/* $Id: printf.c,v 1.5 1996/04/04 16:31:07 tridge Exp $ +/* * printf.c: Internal prom library printf facility. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) -- cgit v1.2.3 From 97d26e73d729c8d967bc5eb9086321956c444dd4 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 17 Jul 2008 21:16:11 +0200 Subject: m68k: vmlinux-std/sun3.lds.S cleanup - use PAGE_SIZE macro This patch includes page.h header into linker script that allow us to use PAGE_SIZE macro instead of numeric constant Signed-off-by: Cyrill Gorcunov Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/vmlinux-std.lds | 3 ++- arch/m68k/kernel/vmlinux-sun3.lds | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 7537cc5e615..99b0784c055 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds @@ -1,6 +1,7 @@ /* ld script to make m68k Linux kernel */ #include +#include OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") OUTPUT_ARCH(m68k) @@ -41,7 +42,7 @@ SECTIONS _edata = .; /* End of data section */ /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; .init.text : { _sinittext = .; diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index cdc313e7c29..8a4919e4d36 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -1,6 +1,7 @@ /* ld script to make m68k Linux kernel */ #include +#include OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") OUTPUT_ARCH(m68k) @@ -34,7 +35,7 @@ SECTIONS _edata = .; /* will be freed after init */ - . = ALIGN(8192); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; .init.text : { _sinittext = .; @@ -61,12 +62,12 @@ __init_begin = .; } SECURITY_INIT #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(8192); + . = ALIGN(PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(8192); + . = ALIGN(PAGE_SIZE); __init_end = .; .data.init.task : { *(.data.init_task) } -- cgit v1.2.3 From edfd92f67eec1bdd905dd7841416eaf945a5b92f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 17 Jul 2008 21:16:12 +0200 Subject: m68k: Allow no CPU/platform type for allnoconfig Allow no CPU/platform type for allnoconfig - Provide a dummy value for FPSTATESIZE if no CPU type was selected - Provide a dummy value for NR_IRQS if no platform type was selected - Warn the user if no CPU or platform type was selected Note: you still cannot build an allnoconfig kernel, as CONFIG_SWAP=n doesn't build and we cannot easily fix that (http://groups.google.com/group/linux.kernel/browse_thread/thread/d430c78b07e1827b) Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/setup.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index a9fb83a8c18..b1f39e4cedb 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,11 @@ #include #endif +#if !FPSTATESIZE || !NR_IRQS +#warning No CPU/platform type selected, your kernel will not work! +#warning Are you building an allnoconfig kernel? +#endif + unsigned long m68k_machtype; EXPORT_SYMBOL(m68k_machtype); unsigned long m68k_cputype; -- cgit v1.2.3 From a0c14d28df8fcf939a8efd9332ace164e9f931fb Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 17 Jul 2008 21:16:13 +0200 Subject: Stringify support commas > This is a no-no for those archs that still use -traditional. > > I dunno if this is a problem for you at the moment and the > > right fix is anyway to nuke -traditional. > > > > Sam Signed-off-by: Mathieu Desnoyers Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/fpsp040/Makefile | 1 - arch/m68k/ifpsp060/Makefile | 1 - arch/m68k/kernel/Makefile | 2 -- arch/m68k/lib/Makefile | 2 -- arch/m68k/math-emu/Makefile | 2 -- 5 files changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/m68k/fpsp040/Makefile b/arch/m68k/fpsp040/Makefile index 0214d2f6f8b..9506d883ace 100644 --- a/arch/m68k/fpsp040/Makefile +++ b/arch/m68k/fpsp040/Makefile @@ -10,7 +10,6 @@ obj-y := bindec.o binstr.o decbin.o do_func.o gen_except.o get_op.o \ x_bsun.o x_fline.o x_operr.o x_ovfl.o x_snan.o x_store.o \ x_unfl.o x_unimp.o x_unsupp.o bugfix.o skeleton.o -EXTRA_AFLAGS := -traditional EXTRA_LDFLAGS := -x $(OS_OBJS): fpsp.h diff --git a/arch/m68k/ifpsp060/Makefile b/arch/m68k/ifpsp060/Makefile index 2fe8472cb5e..43b43504945 100644 --- a/arch/m68k/ifpsp060/Makefile +++ b/arch/m68k/ifpsp060/Makefile @@ -6,5 +6,4 @@ obj-y := fskeleton.o iskeleton.o os.o -EXTRA_AFLAGS := -traditional EXTRA_LDFLAGS := -x diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 7a62a718143..3a7f6222550 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -16,5 +16,3 @@ devres-y = ../../../kernel/irq/devres.o obj-$(CONFIG_PCI) += bios32.o obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo - -EXTRA_AFLAGS := -traditional diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index a18af095cd7..af9abf8d9d9 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -2,7 +2,5 @@ # Makefile for m68k-specific library files.. # -EXTRA_AFLAGS := -traditional - lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ checksum.o string.o uaccess.o diff --git a/arch/m68k/math-emu/Makefile b/arch/m68k/math-emu/Makefile index 53994040181..a0935bf9836 100644 --- a/arch/m68k/math-emu/Makefile +++ b/arch/m68k/math-emu/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -EXTRA_AFLAGS := -traditional - #EXTRA_AFLAGS += -DFPU_EMU_DEBUG #EXTRA_CFLAGS += -DFPU_EMU_DEBUG -- cgit v1.2.3 From b739912efc02f80cc4dc5eaef07e5bc7eafee1b0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:14 +0200 Subject: m68k: make multi_defconfig the default defconfig It seems to match the intention behind multi_defconfig to make it the default defconfig. Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index b15173f28a2..8133dbc4496 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -13,7 +13,7 @@ # Copyright (C) 1994 by Hamish Macdonald # -KBUILD_DEFCONFIG := amiga_defconfig +KBUILD_DEFCONFIG := multi_defconfig # override top level makefile AS += -m68020 -- cgit v1.2.3 From d33b4432e634246eef00ef4d425939c253f70dd6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:15 +0200 Subject: m68k: remove AP1000 code Unless I miss something that's code for a sparc machine even the sparc code no longer supports that got copied to m68k when these files were copied. Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/sun3/prom/console.c | 4 ---- arch/m68k/sun3/prom/init.c | 9 --------- arch/m68k/sun3/prom/printf.c | 5 ----- 3 files changed, 18 deletions(-) (limited to 'arch') diff --git a/arch/m68k/sun3/prom/console.c b/arch/m68k/sun3/prom/console.c index 5812560b70f..2bcb6e4bfe5 100644 --- a/arch/m68k/sun3/prom/console.c +++ b/arch/m68k/sun3/prom/console.c @@ -104,8 +104,6 @@ prom_query_input_device() return PROMDEV_ITTYB; } return PROMDEV_I_UNK; - case PROM_AP1000: - return PROMDEV_I_UNK; }; } #endif @@ -166,8 +164,6 @@ prom_query_output_device() }; } break; - case PROM_AP1000: - return PROMDEV_I_UNK; }; return PROMDEV_O_UNK; } diff --git a/arch/m68k/sun3/prom/init.c b/arch/m68k/sun3/prom/init.c index 5f85681af5a..d8e6349336b 100644 --- a/arch/m68k/sun3/prom/init.c +++ b/arch/m68k/sun3/prom/init.c @@ -31,11 +31,6 @@ extern void prom_ranges_init(void); void __init prom_init(struct linux_romvec *rp) { -#ifdef CONFIG_AP1000 - extern struct linux_romvec *ap_prom_init(void); - rp = ap_prom_init(); -#endif - romvec = rp; #ifndef CONFIG_SUN3 switch(romvec->pv_romvers) { @@ -53,10 +48,6 @@ void __init prom_init(struct linux_romvec *rp) prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n"); prom_halt(); break; - case 42: /* why not :-) */ - prom_vers = PROM_AP1000; - break; - default: prom_printf("PROMLIB: Bad PROM version %d\n", romvec->pv_romvers); diff --git a/arch/m68k/sun3/prom/printf.c b/arch/m68k/sun3/prom/printf.c index c8cf98d97f2..df85018f487 100644 --- a/arch/m68k/sun3/prom/printf.c +++ b/arch/m68k/sun3/prom/printf.c @@ -37,10 +37,6 @@ prom_printf(char *fmt, ...) bptr = ppbuf; -#ifdef CONFIG_AP1000 - ap_write(1,bptr,strlen(bptr)); -#else - #ifdef CONFIG_KGDB if (kgdb_initialized) { printk("kgdb_initialized = %d\n", kgdb_initialized); @@ -53,7 +49,6 @@ prom_printf(char *fmt, ...) prom_putchar(ch); } -#endif #endif va_end(args); return; -- cgit v1.2.3 From 8468afc039f03837066132be14cdd9e5fa726f0b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:21 +0200 Subject: export amiga_vblank This patch fixes the following build error: <-- snip --> .. Building modules, stage 2. MODPOST 1203 modules ERROR: "amiga_vblank" [drivers/video/amifb.ko] undefined! .. make[2]: *** [__modpost] Error 1 <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/amiga/config.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 50f5daab46b..dd0734e54bb 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -51,6 +51,8 @@ unsigned long amiga_chipset; EXPORT_SYMBOL(amiga_chipset); unsigned char amiga_vblank; +EXPORT_SYMBOL(amiga_vblank); + unsigned char amiga_psfreq; struct amiga_hw_present amiga_hw_present; -- cgit v1.2.3 From 0795dbcc4c4c93a929463957993c04cf5fec346c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:23 +0200 Subject: m68k/amiga/: possible cleanups This patch contains the following possible cleanups: - amiints.c: add a proper prototype for amiga_init_IRQ() in include/asm-m68k/amigaints.h - make the following needlessly global code static: - config.c: amiga_model - config.c: amiga_psfreq - config.c: amiga_serial_console_write() - #if 0 the following unused functions: - config.c: amiga_serial_puts() - config.c: amiga_serial_console_wait_key() - config.c: amiga_serial_gets() - remove the following unused variable: - config.c: amiga_masterclock Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/amiga/config.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index dd0734e54bb..df679d96b1c 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -36,14 +36,11 @@ #include #include -unsigned long amiga_model; -EXPORT_SYMBOL(amiga_model); +static unsigned long amiga_model; unsigned long amiga_eclock; EXPORT_SYMBOL(amiga_eclock); -unsigned long amiga_masterclock; - unsigned long amiga_colorclock; EXPORT_SYMBOL(amiga_colorclock); @@ -53,7 +50,7 @@ EXPORT_SYMBOL(amiga_chipset); unsigned char amiga_vblank; EXPORT_SYMBOL(amiga_vblank); -unsigned char amiga_psfreq; +static unsigned char amiga_psfreq; struct amiga_hw_present amiga_hw_present; EXPORT_SYMBOL(amiga_hw_present); @@ -94,8 +91,6 @@ static char *amiga_models[] __initdata = { static char amiga_model_name[13] = "Amiga "; static void amiga_sched_init(irq_handler_t handler); -/* amiga specific irq functions */ -extern void amiga_init_IRQ(void); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); /* amiga specific timer functions */ @@ -109,8 +104,6 @@ static void amiga_reset(void); extern void amiga_init_sound(void); static void amiga_mem_console_write(struct console *co, const char *b, unsigned int count); -void amiga_serial_console_write(struct console *co, const char *s, - unsigned int count); #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on); #endif @@ -420,8 +413,7 @@ void __init config_amiga(void) mach_heartbeat = amiga_heartbeat; #endif - /* Fill in the clock values (based on the 700 kHz E-Clock) */ - amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ + /* Fill in the clock value (based on the 700 kHz E-Clock) */ amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ /* clear all DMA bits */ @@ -819,8 +811,8 @@ static void amiga_serial_putc(char c) ; } -void amiga_serial_console_write(struct console *co, const char *s, - unsigned int count) +static void amiga_serial_console_write(struct console *co, const char *s, + unsigned int count) { while (count--) { if (*s == '\n') @@ -829,7 +821,7 @@ void amiga_serial_console_write(struct console *co, const char *s, } } -#ifdef CONFIG_SERIAL_CONSOLE +#if 0 void amiga_serial_puts(const char *s) { amiga_serial_console_write(NULL, s, strlen(s)); -- cgit v1.2.3 From 5575d0a3c9676b2886adad67dd4b2ac126a49f1f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:24 +0200 Subject: m68k/atari/debug.c: possible cleanups This patch contains the following possible cleanups: - make the following needlessly global functions (always) static: - atari_mfp_console_write() - atari_scc_console_write() - atari_midi_console_write() - atari_init_mfp_port() - atari_init_scc_port() - atari_init_midi_port() - #if 0 the following unused functions: - atari_mfp_console_wait_key() - atari_scc_console_wait_key() - atari_midi_console_wait_key() - remove the following unused variables: - atari_MFP_init_done - atari_SCC_init_done Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/atari/debug.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index 043ddbc61c7..702b15ccfab 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -20,14 +20,6 @@ #include #include -/* Flag that Modem1 port is already initialized and used */ -int atari_MFP_init_done; -EXPORT_SYMBOL(atari_MFP_init_done); - -/* Flag that Modem1 port is already initialized and used */ -int atari_SCC_init_done; -EXPORT_SYMBOL(atari_SCC_init_done); - /* Can be set somewhere, if a SCC master reset has already be done and should * not be repeated; used by kgdb */ int atari_SCC_reset_done; @@ -47,8 +39,8 @@ static inline void ata_mfp_out(char c) mfp.usart_dta = c; } -void atari_mfp_console_write(struct console *co, const char *str, - unsigned int count) +static void atari_mfp_console_write(struct console *co, const char *str, + unsigned int count) { while (count--) { if (*str == '\n') @@ -66,8 +58,8 @@ static inline void ata_scc_out(char c) scc.cha_b_data = c; } -void atari_scc_console_write(struct console *co, const char *str, - unsigned int count) +static void atari_scc_console_write(struct console *co, const char *str, + unsigned int count) { while (count--) { if (*str == '\n') @@ -83,8 +75,8 @@ static inline void ata_midi_out(char c) acia.mid_data = c; } -void atari_midi_console_write(struct console *co, const char *str, - unsigned int count) +static void atari_midi_console_write(struct console *co, const char *str, + unsigned int count) { while (count--) { if (*str == '\n') @@ -136,7 +128,7 @@ static void atari_par_console_write(struct console *co, const char *str, } } -#ifdef CONFIG_SERIAL_CONSOLE +#if 0 int atari_mfp_console_wait_key(struct console *co) { while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ @@ -166,11 +158,7 @@ int atari_midi_console_wait_key(struct console *co) * SCC serial ports. They're used by the debugging interface, kgdb, and the * serial console code. */ -#ifndef CONFIG_SERIAL_CONSOLE static void __init atari_init_mfp_port(int cflag) -#else -void atari_init_mfp_port(int cflag) -#endif { /* * timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 @@ -193,8 +181,6 @@ void atari_init_mfp_port(int cflag) mfp.tim_dt_d = baud_table[baud]; mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ mfp.trn_stat |= 0x01; /* enable TX */ - - atari_MFP_init_done = 1; } #define SCC_WRITE(reg, val) \ @@ -214,11 +200,7 @@ void atari_init_mfp_port(int cflag) MFPDELAY(); \ } while (0) -#ifndef CONFIG_SERIAL_CONSOLE static void __init atari_init_scc_port(int cflag) -#else -void atari_init_scc_port(int cflag) -#endif { extern int atari_SCC_reset_done; static int clksrc_table[9] = @@ -277,14 +259,9 @@ void atari_init_scc_port(int cflag) SCC_WRITE(5, reg5 | 8); atari_SCC_reset_done = 1; - atari_SCC_init_done = 1; } -#ifndef CONFIG_SERIAL_CONSOLE static void __init atari_init_midi_port(int cflag) -#else -void atari_init_midi_port(int cflag) -#endif { int baud = cflag & CBAUD; int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; -- cgit v1.2.3 From 8dfbdf4abad6e5a7bbd097bf7e2c0ec41e0c54b4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:25 +0200 Subject: m68k/mac/: possible cleanups This patch contains the following possible cleanups: - make the following needlessly global code (always) static: - baboon.c: struct baboon - baboon.c: baboon_irq() - config.c: mac_orig_videoaddr - config.c: mac_identify() - config.c: mac_report_hardware() - config.c: mac_debug_console_write() - config.c: mac_sccb_console_write() - config.c: mac_scca_console_write() - config.c: mac_init_scc_port() - oss.c: oss_irq() - oss.c: oss_nubus_irq() - psc.c: psc_debug_dump() - psc.c: psc_dma_die_die_die() - via.c: rbv_clear - remove the unused bootparse.c - #if 0 the following unused functions: - config.c: mac_debugging_short() - config.c: mac_debugging_long() - remove the following unused code: - config.c: mac_bisize - config.c: mac_env - config.c: mac_SCC_init_done - config.c: mac_SCC_reset_done - config.c: mac_init_scca_port() - config.c: mac_init_sccb_port() Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mac/Makefile | 2 +- arch/m68k/mac/baboon.c | 26 +++++----- arch/m68k/mac/bootparse.c | 122 ---------------------------------------------- arch/m68k/mac/config.c | 11 ++--- arch/m68k/mac/debug.c | 41 ++++------------ arch/m68k/mac/oss.c | 8 +-- arch/m68k/mac/psc.c | 4 +- arch/m68k/mac/via.c | 2 +- 8 files changed, 35 insertions(+), 181 deletions(-) delete mode 100644 arch/m68k/mac/bootparse.c (limited to 'arch') diff --git a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile index 1d265ba365a..daebd80bdef 100644 --- a/arch/m68k/mac/Makefile +++ b/arch/m68k/mac/Makefile @@ -2,5 +2,5 @@ # Makefile for Linux arch/m68k/mac source directory # -obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \ +obj-y := config.o macints.o iop.o via.o oss.o psc.o \ baboon.o macboing.o debug.o misc.o diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 673a1085984..dae9c982aa8 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -23,9 +23,7 @@ /* #define DEBUG_IRQS */ int baboon_present; -volatile struct baboon *baboon; - -irqreturn_t baboon_irq(int, void *); +static volatile struct baboon *baboon; #if 0 extern int macide_ack_intr(struct ata_channel *); @@ -49,21 +47,11 @@ void __init baboon_init(void) printk("Baboon detected at %p\n", baboon); } -/* - * Register the Baboon interrupt dispatcher on nubus slot $C. - */ - -void __init baboon_register_interrupts(void) -{ - request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "baboon", (void *) baboon); -} - /* * Baboon interrupt handler. This works a lot like a VIA. */ -irqreturn_t baboon_irq(int irq, void *dev_id) +static irqreturn_t baboon_irq(int irq, void *dev_id) { int irq_bit, irq_num; unsigned char events; @@ -95,6 +83,16 @@ irqreturn_t baboon_irq(int irq, void *dev_id) return IRQ_HANDLED; } +/* + * Register the Baboon interrupt dispatcher on nubus slot $C. + */ + +void __init baboon_register_interrupts(void) +{ + request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, + "baboon", (void *) baboon); +} + void baboon_irq_enable(int irq) { #ifdef DEBUG_IRQUSE printk("baboon_irq_enable(%d)\n", irq); diff --git a/arch/m68k/mac/bootparse.c b/arch/m68k/mac/bootparse.c deleted file mode 100644 index 36d22360982..00000000000 --- a/arch/m68k/mac/bootparse.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -/* - * Booter vars - */ - -int boothowto; -int _boothowto; - -/* - * Called early to parse the environment (passed to us from the booter) - * into a bootinfo struct. Will die as soon as we have our own booter - */ - -#define atol(x) simple_strtoul(x,NULL,0) - -void parse_booter(char *env) -{ - char *name; - char *value; -#if 0 - while(0 && *env) -#else - while(*env) -#endif - { - name=env; - value=name; - while(*value!='='&&*value) - value++; - if(*value=='=') - *value++=0; - env=value; - while(*env) - env++; - env++; -#if 0 - if(strcmp(name,"VIDEO_ADDR")==0) - mac_mch.videoaddr=atol(value); - if(strcmp(name,"ROW_BYTES")==0) - mac_mch.videorow=atol(value); - if(strcmp(name,"SCREEN_DEPTH")==0) - mac_mch.videodepth=atol(value); - if(strcmp(name,"DIMENSIONS")==0) - mac_mch.dimensions=atol(value); -#endif - if(strcmp(name,"BOOTTIME")==0) - mac_bi_data.boottime=atol(value); - if(strcmp(name,"GMTBIAS")==0) - mac_bi_data.gmtbias=atol(value); - if(strcmp(name,"BOOTERVER")==0) - mac_bi_data.bootver=atol(value); - if(strcmp(name,"MACOS_VIDEO")==0) - mac_bi_data.videological=atol(value); - if(strcmp(name,"MACOS_SCC")==0) - mac_bi_data.sccbase=atol(value); - if(strcmp(name,"MACHINEID")==0) - mac_bi_data.id=atol(value); - if(strcmp(name,"MEMSIZE")==0) - mac_bi_data.memsize=atol(value); - if(strcmp(name,"SERIAL_MODEM_FLAGS")==0) - mac_bi_data.serialmf=atol(value); - if(strcmp(name,"SERIAL_MODEM_HSKICLK")==0) - mac_bi_data.serialhsk=atol(value); - if(strcmp(name,"SERIAL_MODEM_GPICLK")==0) - mac_bi_data.serialgpi=atol(value); - if(strcmp(name,"SERIAL_PRINT_FLAGS")==0) - mac_bi_data.printmf=atol(value); - if(strcmp(name,"SERIAL_PRINT_HSKICLK")==0) - mac_bi_data.printhsk=atol(value); - if(strcmp(name,"SERIAL_PRINT_GPICLK")==0) - mac_bi_data.printgpi=atol(value); - if(strcmp(name,"PROCESSOR")==0) - mac_bi_data.cpuid=atol(value); - if(strcmp(name,"ROMBASE")==0) - mac_bi_data.rombase=atol(value); - if(strcmp(name,"TIMEDBRA")==0) - mac_bi_data.timedbra=atol(value); - if(strcmp(name,"ADBDELAY")==0) - mac_bi_data.adbdelay=atol(value); - } -#if 0 /* XXX: TODO with m68k_mach_* */ - /* Fill in the base stuff */ - boot_info.machtype=MACH_MAC; - /* Read this from the macinfo we got ! */ -/* boot_info.cputype=CPU_68020|FPUB_68881;*/ -/* boot_info.memory[0].addr=0;*/ -/* boot_info.memory[0].size=((mac_bi_data.id>>7)&31)<<20;*/ - boot_info.num_memory=1; /* On a MacII */ - boot_info.ramdisk_size=0; /* For now */ - *boot_info.command_line=0; -#endif - } - - -void print_booter(char *env) -{ - char *name; - char *value; - while(*env) - { - name=env; - value=name; - while(*value!='='&&*value) - value++; - if(*value=='=') - *value++=0; - env=value; - while(*env) - env++; - env++; - printk("%s=%s\n", name,value); - } - } - - diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index ad3e3bacae3..c45e18449f3 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -46,7 +46,6 @@ /* Mac bootinfo struct */ struct mac_booter_data mac_bi_data; -int mac_bisize = sizeof mac_bi_data; /* New m68k bootinfo stuff and videobase */ @@ -55,10 +54,8 @@ extern struct mem_info m68k_memory[NUM_MEMINFO]; extern struct mem_info m68k_ramdisk; -void *mac_env; /* Loaded by the boot asm */ - /* The phys. video addr. - might be bogus on some machines */ -unsigned long mac_orig_videoaddr; +static unsigned long mac_orig_videoaddr; /* Mac specific timer functions */ extern unsigned long mac_gettimeoffset(void); @@ -79,6 +76,8 @@ extern void mac_mksound(unsigned int, unsigned int); extern void nubus_sweep_video(void); static void mac_get_model(char *str); +static void mac_identify(void); +static void mac_report_hardware(void); static void __init mac_sched_init(irq_handler_t vector) { @@ -765,7 +764,7 @@ static struct mac_model mac_data_table[] = { } }; -void __init mac_identify(void) +static void __init mac_identify(void) { struct mac_model *m; @@ -821,7 +820,7 @@ void __init mac_identify(void) baboon_init(); } -void __init mac_report_hardware(void) +static void __init mac_report_hardware(void) { printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name); } diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index e8a57138b4a..2165740786a 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -51,6 +51,8 @@ extern void mac_serial_print(const char *); static int peng, line; #endif +#if 0 + void mac_debugging_short(int pos, short num) { #ifdef DEBUG_SCREEN @@ -125,6 +127,8 @@ void mac_debugging_long(int pos, long addr) #endif } +#endif /* 0 */ + #ifdef DEBUG_SERIAL /* * TODO: serial debug code @@ -142,12 +146,6 @@ struct mac_SCC { # define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) -/* Flag that serial port is already initialized and used */ -int mac_SCC_init_done; -/* Can be set somewhere, if a SCC master reset has already be done and should - * not be repeated; used by kgdb */ -int mac_SCC_reset_done; - static int scc_port = -1; static struct console mac_console_driver = { @@ -171,8 +169,8 @@ static struct console mac_console_driver = { * this driver if Mac. */ -void mac_debug_console_write(struct console *co, const char *str, - unsigned int count) +static void mac_debug_console_write(struct console *co, const char *str, + unsigned int count) { mac_serial_print(str); } @@ -209,8 +207,8 @@ static inline void mac_scca_out(char c) scc.cha_a_data = c; } -void mac_sccb_console_write(struct console *co, const char *str, - unsigned int count) +static void mac_sccb_console_write(struct console *co, const char *str, + unsigned int count) { while (count--) { if (*str == '\n') @@ -219,8 +217,8 @@ void mac_sccb_console_write(struct console *co, const char *str, } } -void mac_scca_console_write(struct console *co, const char *str, - unsigned int count) +static void mac_scca_console_write(struct console *co, const char *str, + unsigned int count) { while (count--) { if (*str == '\n') @@ -265,14 +263,8 @@ void mac_scca_console_write(struct console *co, const char *str, barrier(); \ } while(0) -#ifndef CONFIG_SERIAL_CONSOLE static void __init mac_init_scc_port(int cflag, int port) -#else -void mac_init_scc_port(int cflag, int port) -#endif { - extern int mac_SCC_reset_done; - /* * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k */ @@ -340,22 +332,9 @@ void mac_init_scc_port(int cflag, int port) SCCA_WRITE(3, reg3 | 1); SCCA_WRITE(5, reg5 | 8); } - - mac_SCC_reset_done = 1; - mac_SCC_init_done = 1; } #endif /* DEBUG_SERIAL */ -void mac_init_scca_port(int cflag) -{ - mac_init_scc_port(cflag, 0); -} - -void mac_init_sccb_port(int cflag) -{ - mac_init_scc_port(cflag, 1); -} - static int __init mac_debug_setup(char *arg) { if (!MACH_IS_MAC) diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 3c943d2ec57..43d83e054b8 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -30,8 +30,8 @@ int oss_present; volatile struct mac_oss *oss; -irqreturn_t oss_irq(int, void *); -irqreturn_t oss_nubus_irq(int, void *); +static irqreturn_t oss_irq(int, void *); +static irqreturn_t oss_nubus_irq(int, void *); extern irqreturn_t via1_irq(int, void *); extern irqreturn_t mac_scc_dispatch(int, void *); @@ -92,7 +92,7 @@ void __init oss_nubus_init(void) * and SCSI; everything else is routed to its own autovector IRQ. */ -irqreturn_t oss_irq(int irq, void *dev_id) +static irqreturn_t oss_irq(int irq, void *dev_id) { int events; @@ -126,7 +126,7 @@ irqreturn_t oss_irq(int irq, void *dev_id) * Unlike the VIA/RBV this is on its own autovector interrupt level. */ -irqreturn_t oss_nubus_irq(int irq, void *dev_id) +static irqreturn_t oss_nubus_irq(int irq, void *dev_id) { int events, irq_bit, i; diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index d66f723b17c..f84a4dd64f9 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -36,7 +36,7 @@ irqreturn_t psc_irq(int, void *); * Debugging dump, used in various places to see what's going on. */ -void psc_debug_dump(void) +static void psc_debug_dump(void) { int i; @@ -55,7 +55,7 @@ void psc_debug_dump(void) * expanded to cover what I think are the other 7 channels. */ -void psc_dma_die_die_die(void) +static void psc_dma_die_die_die(void) { int i; diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index fa485df4160..f3b27d04a31 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -45,7 +45,7 @@ volatile long *via_memory_bogon=(long *)&via_memory_bogon; int rbv_present; int via_alt_mapping; EXPORT_SYMBOL(via_alt_mapping); -__u8 rbv_clear; +static __u8 rbv_clear; /* * Globals for accessing the VIA chip registers without having to -- cgit v1.2.3 From 22deb527ce5d13e07652f81a53032aa0214ea8c3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:26 +0200 Subject: m68k/q40/config.c: make functions static This patch makes the following needlessly global functions static: - q40_reset() - q40_halt() - q40_disable_irqs() - q40_gettimeoffset() - q40_hwclk() - q40_get_ss() - q40_set_clock_mmss() Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/q40/config.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 476e18eca75..be9de2f3dc4 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -41,14 +41,12 @@ static void q40_get_model(char *model); static int q40_get_hardware_list(char *buffer); extern void q40_sched_init(irq_handler_t handler); -extern unsigned long q40_gettimeoffset(void); -extern int q40_hwclk(int, struct rtc_time *); -extern unsigned int q40_get_ss(void); -extern int q40_set_clock_mmss(unsigned long); +static unsigned long q40_gettimeoffset(void); +static int q40_hwclk(int, struct rtc_time *); +static unsigned int q40_get_ss(void); +static int q40_set_clock_mmss(unsigned long); static int q40_get_rtc_pll(struct rtc_pll_info *pll); static int q40_set_rtc_pll(struct rtc_pll_info *pll); -extern void q40_reset(void); -void q40_halt(void); extern void q40_waitbut(void); void q40_set_vectors(void); @@ -127,7 +125,7 @@ static void q40_heartbeat(int on) } #endif -void q40_reset(void) +static void q40_reset(void) { halted = 1; printk("\n\n*******************************************\n" @@ -137,7 +135,8 @@ void q40_reset(void) while (1) ; } -void q40_halt(void) + +static void q40_halt(void) { halted = 1; printk("\n\n*******************\n" @@ -165,7 +164,8 @@ static unsigned int serports[] = { 0x3f8,0x2f8,0x3e8,0x2e8,0 }; -void q40_disable_irqs(void) + +static void q40_disable_irqs(void) { unsigned i, j; @@ -227,7 +227,7 @@ static inline unsigned char bin2bcd(unsigned char b) } -unsigned long q40_gettimeoffset(void) +static unsigned long q40_gettimeoffset(void) { return 5000 * (ql_ticks != 0); } @@ -248,7 +248,7 @@ unsigned long q40_gettimeoffset(void) * }; */ -int q40_hwclk(int op, struct rtc_time *t) +static int q40_hwclk(int op, struct rtc_time *t) { if (op) { /* Write.... */ @@ -285,7 +285,7 @@ int q40_hwclk(int op, struct rtc_time *t) return 0; } -unsigned int q40_get_ss(void) +static unsigned int q40_get_ss(void) { return bcd2bin(Q40_RTC_SECS); } @@ -295,7 +295,7 @@ unsigned int q40_get_ss(void) * clock is out by > 30 minutes. Logic lifted from atari code. */ -int q40_set_clock_mmss(unsigned long nowtime) +static int q40_set_clock_mmss(unsigned long nowtime) { int retval = 0; short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; -- cgit v1.2.3 From 07b8125949de66b6552966de8d4280c3a8620359 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:27 +0200 Subject: m68k/sun3/: possible cleanups This patch contains the following possible cleanups: - make the following needlessly global code static: - config.c: sun3_bootmem_alloc() - config.c: sun3_sched_init() - dvma.c: dvma_page() - idprom.c: struct Sun_Machines[] - mmu_emu.c: struct ctx_alloc[] - sun3dvma.c: iommu_use[] - sun3ints.c: led_pattern[] - remove the unused sbus.c Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/sun3/Makefile | 2 +- arch/m68k/sun3/config.c | 7 ++++--- arch/m68k/sun3/dvma.c | 2 +- arch/m68k/sun3/idprom.c | 2 +- arch/m68k/sun3/mmu_emu.c | 2 +- arch/m68k/sun3/sbus.c | 27 --------------------------- arch/m68k/sun3/sun3dvma.c | 2 +- arch/m68k/sun3/sun3ints.c | 2 +- 8 files changed, 10 insertions(+), 36 deletions(-) delete mode 100644 arch/m68k/sun3/sbus.c (limited to 'arch') diff --git a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile index be1a8470d63..38ba0e0ceda 100644 --- a/arch/m68k/sun3/Makefile +++ b/arch/m68k/sun3/Makefile @@ -2,6 +2,6 @@ # Makefile for Linux arch/m68k/sun3 source directory # -obj-y := sun3ints.o sun3dvma.o sbus.o idprom.o +obj-y := sun3ints.o sun3dvma.o idprom.o obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c index c0fbd278fbb..732087d0735 100644 --- a/arch/m68k/sun3/config.c +++ b/arch/m68k/sun3/config.c @@ -36,7 +36,7 @@ extern char _text, _end; char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; extern unsigned long sun3_gettimeoffset(void); -extern void sun3_sched_init(irq_handler_t handler); +static void sun3_sched_init(irq_handler_t handler); extern void sun3_get_model (char* model); extern void idprom_init (void); extern int sun3_hwclk(int set, struct rtc_time *t); @@ -114,7 +114,8 @@ static void sun3_halt (void) /* sun3 bootmem allocation */ -void __init sun3_bootmem_alloc(unsigned long memory_start, unsigned long memory_end) +static void __init sun3_bootmem_alloc(unsigned long memory_start, + unsigned long memory_end) { unsigned long start_page; @@ -164,7 +165,7 @@ void __init config_sun3(void) sun3_bootmem_alloc(memory_start, memory_end); } -void __init sun3_sched_init(irq_handler_t timer_routine) +static void __init sun3_sched_init(irq_handler_t timer_routine) { sun3_disable_interrupts(); intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE); diff --git a/arch/m68k/sun3/dvma.c b/arch/m68k/sun3/dvma.c index d2b3093f240..d522eaab455 100644 --- a/arch/m68k/sun3/dvma.c +++ b/arch/m68k/sun3/dvma.c @@ -19,7 +19,7 @@ static unsigned long ptelist[120]; -inline unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr) +static unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr) { unsigned long pte; unsigned long j; diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c index 6c5336d62fa..c86ac37d198 100644 --- a/arch/m68k/sun3/idprom.c +++ b/arch/m68k/sun3/idprom.c @@ -25,7 +25,7 @@ static struct idprom idprom_buffer; * of the Sparc CPU and have a meaningful IDPROM machtype value that we * know about. See asm-sparc/machines.h for empirical constants. */ -struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { +static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { /* First, Sun3's */ { .name = "Sun 3/160 Series", .id_machtype = (SM_SUN3 | SM_3_160) }, { .name = "Sun 3/50", .id_machtype = (SM_SUN3 | SM_3_50) }, diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c index fb0f6a20cc3..60f9d4500d7 100644 --- a/arch/m68k/sun3/mmu_emu.c +++ b/arch/m68k/sun3/mmu_emu.c @@ -55,7 +55,7 @@ unsigned char pmeg_ctx[PMEGS_NUM]; /* pointers to the mm structs for each task in each context. 0xffffffff is a marker for kernel context */ -struct mm_struct *ctx_alloc[CONTEXTS_NUM] = { +static struct mm_struct *ctx_alloc[CONTEXTS_NUM] = { [0] = (struct mm_struct *)0xffffffff }; diff --git a/arch/m68k/sun3/sbus.c b/arch/m68k/sun3/sbus.c deleted file mode 100644 index babdbfa3cda..00000000000 --- a/arch/m68k/sun3/sbus.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SBus helper functions - * - * Sun3 don't have a sbus, but many of the used devices are also - * used on Sparc machines with sbus. To avoid having a lot of - * duplicate code, we provide necessary glue stuff to make using - * of the sbus driver code possible. - * - * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de) - */ - -#include -#include -#include - -int __init sbus_init(void) -{ - return 0; -} - -void *sparc_alloc_io (u32 address, void *virtual, int len, char *name, - u32 bus_type, int rdonly) -{ - return (void *)address; -} - -subsys_initcall(sbus_init); diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c index 8709677fa02..f9277e8b415 100644 --- a/arch/m68k/sun3/sun3dvma.c +++ b/arch/m68k/sun3/sun3dvma.c @@ -29,7 +29,7 @@ static inline void dvma_unmap_iommu(unsigned long a, int b) extern void sun3_dvma_init(void); #endif -unsigned long iommu_use[IOMMU_TOTAL_ENTRIES]; +static unsigned long iommu_use[IOMMU_TOTAL_ENTRIES]; #define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT) diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index cf93481adb1..7364cd67455 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -30,7 +30,7 @@ void sun3_enable_interrupts(void) sun3_enable_irq(0); } -int led_pattern[8] = { +static int led_pattern[8] = { ~(0x80), ~(0x01), ~(0x40), ~(0x02), ~(0x20), ~(0x04), -- cgit v1.2.3 From 635c0a217425f6f37422b85bcc88a7af9efc457c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 17 Jul 2008 21:16:29 +0200 Subject: m68k/apollo: Add missing call to apollo_parse_bootinfo() Add the missing call to apollo_parse_bootinfo(), which had been lost from a big Apollo support patch by Peter De Schrijver in 1999. Thanks to Adrian Bunk for noticing! Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index b1f39e4cedb..ea1e44da19b 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -122,6 +122,7 @@ extern int bvme6000_parse_bootinfo(const struct bi_record *); extern int mvme16x_parse_bootinfo(const struct bi_record *); extern int mvme147_parse_bootinfo(const struct bi_record *); extern int hp300_parse_bootinfo(const struct bi_record *); +extern int apollo_parse_bootinfo(const struct bi_record *); extern void config_amiga(void); extern void config_atari(void); @@ -189,6 +190,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) unknown = mvme147_parse_bootinfo(record); else if (MACH_IS_HP300) unknown = hp300_parse_bootinfo(record); + else if (MACH_IS_APOLLO) + unknown = apollo_parse_bootinfo(record); else unknown = 1; } -- cgit v1.2.3 From 62bc654e794feb5242c31a59dcc36bab64f7d917 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:30 +0200 Subject: m68k/Mac: remove the unused ADB_KEYBOARD option When the driver was removed back in 2002 the option was forgotten. Reported-by: Robert P. J. Day Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/Kconfig | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 55ea52fe6ac..8012ff7d751 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -578,18 +578,6 @@ config MAC_HID depends on INPUT_ADBHID default y -config ADB_KEYBOARD - bool "Support for ADB keyboard (old driver)" - depends on MAC && !INPUT_ADBHID - help - This option allows you to use an ADB keyboard attached to your - machine. Note that this disables any other (ie. PS/2) keyboard - support, even if your machine is physically capable of using both at - the same time. - - If you use an ADB keyboard (4 pin connector), say Y here. - If you use a PS/2 keyboard (6 pin connector), say N here. - config HPDCA tristate "HP DCA serial support" depends on DIO && SERIAL_8250 -- cgit v1.2.3 From 7ccaee5cadd7a771773bbb878e139697511ebdde Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 21:16:31 +0200 Subject: m68k/Atari: remove the dead ATARI_SCC{,_DMA} options It seems the driver was removed back in kernel 2.3 but the options were forgotten. Reported-by: Robert P. J. Day Signed-off-by: Adrian Bunk Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/Kconfig | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 8012ff7d751..8c5e1de68fc 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -490,28 +490,6 @@ config ATARI_MFPSER Note for Falcon users: You also have an MFP port, it's just not wired to the outside... But you could use the port under Linux. -config ATARI_SCC - tristate "Atari SCC serial support" - depends on ATARI - ---help--- - If you have serial ports based on a Zilog SCC chip (Modem2, Serial2, - LAN) and like to use them under Linux, say Y. All built-in SCC's are - supported (TT, MegaSTE, Falcon), and also the ST-ESCC. If you have - two connectors for channel A (Serial2 and LAN), they are visible as - two separate devices. - - To compile this driver as a module, choose M here. - -config ATARI_SCC_DMA - bool "Atari SCC serial DMA support" - depends on ATARI_SCC - help - This enables DMA support for receiving data on channel A of the SCC. - If you have a TT you may say Y here and read - drivers/char/atari_SCC.README. All other users should say N here, - because only the TT has SCC-DMA, even if your machine keeps claiming - so at boot time. - config ATARI_MIDI tristate "Atari MIDI serial support" depends on ATARI @@ -628,7 +606,7 @@ config DN_SERIAL config SERIAL_CONSOLE bool "Support for serial port console" - depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_SCC=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) + depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) ---help--- If you say Y here, it will be possible to use a serial port as the system console (the system console is the device which receives all -- cgit v1.2.3 From 7b6b948fc0d60a704c15b1cd72345a98e759dd62 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 17 Jul 2008 21:16:33 +0200 Subject: arch/m68k/mm/motorola.c: Eliminate NULL test and memset after alloc_bootmem As noted by Akinobu Mita in patch b1fceac2b9e04d278316b2faddf276015fc06e3b, alloc_bootmem and related functions never return NULL and always return a zeroed region of memory. Thus a NULL test or memset after calls to these functions is unnecessary. This was fixed using the following semantic patch. (http://www.emn.fr/x-info/coccinelle/) // @@ expression E; statement S; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) .. when != E ( - BUG_ON (E == NULL); | - if (E == NULL) S ) @@ expression E,E1; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) .. when != E - memset(E,0,E1); // Signed-off-by: Julia Lawall Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mm/motorola.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 30d34f28502..226795bdf35 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -285,7 +285,6 @@ void __init paging_init(void) * to a couple of allocated pages */ empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); - memset(empty_zero_page, 0, PAGE_SIZE); /* * Set up SFC/DFC registers -- cgit v1.2.3 From 93026e217b46b70f9719caf69e716fa3bbe1d20c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 17 Jul 2008 21:16:34 +0200 Subject: arch/m68k/mm/sun3mmu.c: Eliminate NULL test and memset after alloc_bootmem As noted by Akinobu Mita in patch b1fceac2b9e04d278316b2faddf276015fc06e3b, alloc_bootmem and related functions never return NULL and always return a zeroed region of memory. Thus a NULL test or memset after calls to these functions is unnecessary. This was fixed using the following semantic patch. (http://www.emn.fr/x-info/coccinelle/) // @@ expression E; statement S; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) .. when != E ( - BUG_ON (E == NULL); | - if (E == NULL) S ) @@ expression E,E1; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) .. when != E - memset(E,0,E1); // Signed-off-by: Julia Lawall Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mm/sun3mmu.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c index 6a6513aa1ce..edceefc1887 100644 --- a/arch/m68k/mm/sun3mmu.c +++ b/arch/m68k/mm/sun3mmu.c @@ -53,7 +53,6 @@ void __init paging_init(void) wp_works_ok = 0; #endif empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); - memset(empty_zero_page, 0, PAGE_SIZE); address = PAGE_OFFSET; pg_dir = swapper_pg_dir; -- cgit v1.2.3