diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-08-28 22:00:09 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-08-28 22:00:09 +0000 |
commit | 1a1d77dd589de5a567fa95e36aa6999c704ceca4 (patch) | |
tree | 141e31f89f18b9fe0831f31852e0435ceaccafc5 /arch | |
parent | fb9c690a18b3d66925a65b17441c37fa14d4370b (diff) |
Merge with 2.4.0-test7.
Diffstat (limited to 'arch')
154 files changed, 4020 insertions, 1583 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in index ed44cb67c..6485df4af 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -302,9 +302,10 @@ endmenu source drivers/char/Config.in - #source drivers/misc/Config.in +source drivers/media/Config.in + source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then @@ -334,6 +335,7 @@ fi endmenu source drivers/usb/Config.in +source drivers/input/Config.in mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index ac80051ed..7dda5b566 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -1160,3 +1160,4 @@ sys_call_table: .quad sys_pivot_root .quad sys_mincore /* 375 */ .quad sys_pciconfig_iobase + .quad sys_getdents64 diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 6102f2213..4d574b824 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -104,7 +104,8 @@ struct osf_dirent_callback { int error; }; -static int osf_filldir(void *__buf, const char *name, int namlen, off_t offset, ino_t ino) +static int osf_filldir(void *__buf, const char *name, int namlen, off_t offset, + ino_t ino, unsigned int d_type) { struct osf_dirent *dirent; struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index d4ad98651..00120e251 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -1,7 +1,7 @@ /* * linux/arch/alpha/kernel/time.c * - * Copyright (C) 1991, 1992, 1995, 1999 Linus Torvalds + * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds * * This file contains the PC-specific time handling details: * reading the RTC at bootup, etc.. @@ -21,6 +21,9 @@ * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net) * fixed algorithm in do_gettimeofday() for calculating the precise time * from processor cycle counter (now taking lost_ticks into account) + * 2000-08-13 Jan-Benedict Glaw <jbglaw@lug-owl.de> + * Fixed time_init to be aware of epoches != 1900. This prevents + * booting up in 2048 for me;) Code is stolen from rtc.c. */ #include <linux/config.h> #include <linux/errno.h> @@ -200,7 +203,7 @@ common_init_rtc(void) void time_init(void) { - unsigned int year, mon, day, hour, min, sec, cc1, cc2; + unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; unsigned long cycle_freq, one_percent; long diff; @@ -263,16 +266,24 @@ time_init(void) BCD_TO_BIN(mon); BCD_TO_BIN(year); } -#ifdef ALPHA_PRE_V1_2_SRM_CONSOLE - /* - * The meaning of life, the universe, and everything. Plus - * this makes the year come out right on SRM consoles earlier - * than v1.2. - */ - year -= 42; -#endif - if ((year += 1900) < 1970) + + /* PC-like is standard; used for year <= 20 || year >= 100 */ + epoch = 1900; + if (year > 20 && year < 48) + /* ARC console, used on some not so old boards */ + epoch = 1980; + else if (year >= 48 && year < 70) + /* Digital UNIX, used on older boards (eg. AXPpxi33) */ + epoch = 1952; + else if (year >= 70 && year < 100) + /* Digital DECstations, very old... */ + epoch = 1928; + + printk(KERN_INFO "Using epoch = %d\n", epoch); + + if ((year += epoch) < 1970) year += 100; + xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 5bd7af915..81b78feb9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -48,7 +48,7 @@ NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then ech # ifeq ($(NEW_GCC),y) CFLAGS += -mshort-load-bytes -CFLAGS_PROC_CPU_26 := -mcpu=arm3 -Os +CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os CFLAGS_PROC_CPU_32v3 := -march=armv3 CFLAGS_PROC_CPU_32v4 := -march=armv4 CFLAGS_ARM6 := -mtune=arm6 @@ -166,10 +166,9 @@ endif HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ arch/arm/kernel/init_task.o SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib \ - arch/arm/special arch/arm/nwfpe + arch/arm/nwfpe CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) LIBS := arch/arm/lib/lib.o arch/arm/lib/lib.a $(LIBS) $(LIBGCC) -DRIVERS += arch/arm/special/special.a ifeq ($(CONFIG_NWFPE),y) LIBS := arch/arm/nwfpe/math-emu.o $(LIBS) @@ -193,7 +192,14 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot # The following is a hack to get 'constants.h' up # to date before starting compilation -$(patsubst %, _dir_%, $(SUBDIRS)) : constants +$(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \ + constants \ + include/asm-arm/mach-types.h + +include/asm-arm/mach-types.h: \ + arch/arm/tools/mach-types \ + arch/arm/tools/gen-mach-types + @awk -f arch/arm/tools/gen-mach-types arch/arm/tools/mach-types > $@ constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy @$(MAKE) -C arch/arm/lib constants.h @@ -218,16 +224,16 @@ arch/arm/mm: dummy arch/arm/lib: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib -zImage zinstall Image install: vmlinux +bzImage zImage zinstall Image bootpImage install: vmlinux @$(MAKEBOOT) $@ archmrproper: - @$(MAKE) -C arch/$(ARCH)/special mrproper $(RM) include/asm-arm/arch include/asm-arm/proc archclean: @$(MAKEBOOT) clean $(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds + $(RM) include/asm-arm/mach-types.h archdep: symlinks @$(MAKEBOOT) dep @@ -241,46 +247,25 @@ zi:; @$(MAKEBOOT) zinstall # # Configuration targets. Use these to select a # configuration for your architecture -# -a5k_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/a5k arch/arm/defconfig - -ebsa110_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/ebsa110 arch/arm/defconfig - -footbridge_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/footbridge arch/arm/defconfig - -rpc_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/rpc arch/arm/defconfig - -brutus_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/brutus arch/arm/defconfig - -victor_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/victor arch/arm/defconfig - -empeg_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/empeg arch/arm/defconfig - -thinclient_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/thinclient arch/arm/defconfig - -assabet_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/assabet arch/arm/defconfig - -lart_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/lart arch/arm/defconfig +CFGS= a5k_config ebsa110_config \ + footbridge_config rpc_config \ + brutus_config victor_config \ + empeg_config thinclient_config \ + assabet_config lart_config \ + cerf_config + +$(CFGS): + @( \ + CFG=$(@:_config=); \ + if [ -f arch/arm/def-configs/$$CFG ]; then \ + $(RM) arch/arm/defconfig; \ + cp arch/arm/def-configs/$$CFG arch/arm/defconfig; \ + echo "*** Default configuration for $$CFG installed"; \ + echo "*** Next, you may run 'make oldconfig'"; \ + else \ + echo "$$CFG does not exist"; \ + fi; \ + ) l7200_config: $(RM) arch/arm/defconfig diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index d210b92c2..2811e80ef 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -5,20 +5,105 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1995, 1996 Russell King +# Copyright (C) 1995-2000 Russell King # SYSTEM =$(TOPDIR)/vmlinux +ifeq ($(CONFIG_CPU_26),y) +ZTEXTADDR = 0x02080000 +PARAMS_PHYS = 0x0207c000 +INITRD_PHYS = 0x02180000 +INITRD_VIRT = 0x02180000 +endif + +ifeq ($(CONFIG_ARCH_RPC),y) +ZTEXTADDR = 0x10008000 +PARAMS_PHYS = 0x10000100 +INITRD_PHYS = 0x18000000 +INITRD_VIRT = 0xc8000000 +endif + +ifeq ($(CONFIG_ARCH_CLPS7500),y) +ZTEXTADDR = 0x10008000 +endif + +ifeq ($(CONFIG_ARCH_EBSA110),y) +ZTEXTADDR = 0x00008000 +PARAMS_PHYS = 0x00000400 +INITRD_PHYS = 0x00800000 +INITRD_VIRT = 0xc0800000 +endif + +ifeq ($(CONFIG_FOOTBRIDGE),y) +ZTEXTADDR = 0x00008000 +PARAMS = 0x00000100 +INITRD_PHYS = 0x00800000 +INITRD_VIRT = 0xc0800000 +endif + +ifeq ($(CONFIG_ARCH_NEXUSPCI),y) +ZTEXTADDR = 0x40200000 +ZRELADDR = 0x40008000 +endif + +ifeq ($(CONFIG_ARCH_L7200),y) +# RAM based kernel +#ZTEXTADDR = 0xf0400000 +#ZRELADDR = 0xf0008000 + +# FLASH based kernel +ZTEXTADDR = 0x00010000 +ZRELADDR = 0xf0008000 +ZBSSADDR = 0xf03e0000 +endif + +ifeq ($(CONFIG_ARCH_SA1100),y) +ZTEXTADDR = 0xc0008000 +ZRELADDR = 0xc0008000 +ifeq ($(CONFIG_SA1100_VICTOR),y) + ZTEXTADDR = 0x00002000 + ZBSSADDR = 0xc0100000 +endif +ifeq ($(CONFIG_SA1100_THINCLIENT),y) + ZTEXTADDR = 0xC0200000 +endif +ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y) + ZTEXTADDR = 0xC0200000 +endif +endif + +# +# If you don't define ZRELADDR above, +# then it defaults to ZTEXTADDR +# +ifeq ($(ZRELADDR),) +ZRELADDR = $(ZTEXTADDR) +endif + +export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS + Image: $(CONFIGURE) $(SYSTEM) $(OBJCOPY) $(SYSTEM) $@ +bzImage: zImage + zImage: $(CONFIGURE) compressed/vmlinux $(OBJCOPY) compressed/vmlinux $@ +bootpImage: bootp/bootp + $(OBJCOPY) bootp/bootp $@ + compressed/vmlinux: $(TOPDIR)/vmlinux dep @$(MAKE) -C compressed vmlinux +bootp/bootp: zImage initrd + @$(MAKE) -C bootp bootp + +initrd: + @test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1) + @test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1) + install: $(CONFIGURE) Image sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" @@ -26,7 +111,8 @@ zinstall: $(CONFIGURE) zImage sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" clean: - rm -f Image zImage + $(RM) Image zImage bootpImage @$(MAKE) -C compressed clean + @$(MAKE) -C bootp clean dep: diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile new file mode 100644 index 000000000..c513c8ad3 --- /dev/null +++ b/arch/arm/boot/bootp/Makefile @@ -0,0 +1,26 @@ +# +# linux/arch/arm/boot/bootp/Makefile +# + +ZSYSTEM =$(TOPDIR)/arch/arm/boot/zImage +INITRD =$(ZSYSTEM) +ZLDFLAGS =-p -X -T bootp.lds \ + --defsym initrd_addr=$(INITRD_PHYS) \ + --defsym initrd_virt=$(INITRD_VIRT) \ + --defsym params=$(PARAMS_PHYS) + +all: bootp + +# Note that bootp.lds picks up kernel.o and initrd.o +bootp: init.o kernel.o initrd.o bootp.lds + $(LD) $(ZLDFLAGS) -o $@ init.o + +kernel.o: $(ZSYSTEM) + $(LD) -r -s -o $@ -b binary $(ZSYSTEM) + +initrd.o: $(INITRD) + $(LD) -r -s -o $@ -b binary $(INITRD) + +.PHONY: $(INITRD) $(ZSYSTEM) + +clean:; $(RM) bootp bootp.lds diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S new file mode 100644 index 000000000..c5682212f --- /dev/null +++ b/arch/arm/boot/bootp/init.S @@ -0,0 +1,57 @@ +/* + * Header file for splitting kernel + initrd. Note that we pass + * r0 through to r3 straight through. + */ + .section .start,#alloc,#execinstr + .type _entry, #function +_entry: +kernel_addr: adr r10, initdata + ldmia r10, {r11, r12} + sub r11, r10, r11 @ work out exec offset + add r12, r12, r11 @ correct "splitify" + mov pc, r12 @ jump to splitify + .size _entry,. - _entry + + .type initdata, #object +initdata: .word initdata @ compiled address of this + .word splitify + .size initdata,. - initdata + + .text +splitify: adr r13, data + ldmia r13!, {r4-r6} @ move the kernel + add r4, r4, r11 @ correction + mov r12, r5 + bl move + + ldmia r13!, {r4-r6} @ then the initrd + add r4, r4, r11 @ correction + bl move + + ldmib r13, {r5,r6,r7} @ get size and addr of initrd + add r7, r7, #16*4 @ offset of initrd_start in param_struct + stmia r7, {r5,r6} @ save in param_struct + mov pc, r12 @ call kernel + +move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time + stmia r5!, {r7 - r10} + ldmia r4!, {r7 - r10} + stmia r5!, {r7 - r10} + subs r6, r6, #8 * 4 + bcs move + mov pc, lr + +data: .word kernel_start + .word kernel_addr + .word kernel_len + + .word initrd_start + .word initrd_addr + .word initrd_len + + .word initrd_virt + .word initrd_len + .word params + + .type kernel_start,#object + .type initrd_start,#object diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index f3c45c553..2a0108021 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -2,10 +2,13 @@ # linux/arch/arm/boot/compressed/Makefile # # create a compressed vmlinuz image from the original vmlinux +# +# Note! SYSTEM, ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported +# from arch/arm/boot/Makefile +# HEAD = head.o OBJS = misc.o -SYSTEM = $(TOPDIR)/vmlinux CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_PROC) FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c ZLDFLAGS = -p -X -T vmlinux.lds @@ -17,60 +20,25 @@ ifeq ($(CONFIG_ARCH_ACORN),y) OBJS += ll_char_wr.o font.o endif -ifeq ($(CONFIG_CPU_26),y) -ZTEXTADDR = 0x02080000 -endif - -ifeq ($(CONFIG_ARCH_RPC),y) -ZTEXTADDR = 0x10008000 -endif - -ifeq ($(CONFIG_ARCH_CLPS7500),y) -ZTEXTADDR = 0x10008000 -endif - -ifeq ($(CONFIG_ARCH_EBSA110),y) -ZTEXTADDR = 0x00008000 -endif - -ifeq ($(CONFIG_FOOTBRIDGE),y) -ZTEXTADDR = 0x00008000 -endif - ifeq ($(CONFIG_ARCH_NETWINDER),y) OBJS += head-netwinder.o endif ifeq ($(CONFIG_ARCH_NEXUSPCI),y) HEAD = head-nexuspci.o -ZTEXTADDR = 0x40200000 -ZRELADDR = 0x40008000 +endif + +ifeq ($(CONFIG_ARCH_L7200),y) +OBJS += head-l7200.o endif ifeq ($(CONFIG_ARCH_SA1100),y) OBJS += head-sa1100.o setup-sa1100.o -ZTEXTADDR = 0xc0008000 -ZRELADDR = 0xc0008000 -ifeq ($(CONFIG_SA1100_VICTOR),y) - ZTEXTADDR = 0x00002000 - ZBSSADDR = 0xc0100000 -endif -ifeq ($(CONFIG_SA1100_THINCLIENT),y) - ZTEXTADDR = 0xC0200000 -endif -ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y) - ZTEXTADDR = 0xC0200000 +ifeq ($(CONFIG_SA1100_NANOENGINE),y) + OBJS += hw-bse.o endif endif -# -# If you don't define ZRELADDR above, -# then it defaults to ZTEXTADDR -# -ifeq ($(ZRELADDR),) -ZRELADDR = $(ZTEXTADDR) -endif - SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/; ifneq ($(ZBSSADDR),) @@ -104,3 +72,6 @@ clean:; rm -f vmlinux core piggy* vmlinux.lds .PHONY: vmlinux.lds clean misc.o: misc.c $(TOPDIR)/include/asm/arch/uncompress.h $(TOPDIR)/lib/inflate.c + +%.o: %.S + $(CC) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) -c -o $@ $< diff --git a/arch/arm/boot/compressed/head-l7200.S b/arch/arm/boot/compressed/head-l7200.S new file mode 100644 index 000000000..ecf4d6881 --- /dev/null +++ b/arch/arm/boot/compressed/head-l7200.S @@ -0,0 +1,30 @@ +/* + * linux/arch/arm/boot/compressed/head-l7200.S + * + * Copyright (C) 2000 Steve Hill <sjhill@cotw.com> + * + * Some code borrowed from Nicola Pitre's 'head-sa1100.S' file. This + * is merged with head.S by the linker. + */ + +#include <linux/config.h> + +#ifndef CONFIG_ARCH_L7200 +#error What am I doing here... +#endif + + .section ".start", #alloc, #execinstr + +__L7200_start: + + mov r0, #0x00100000 @ FLASH address of initrd + mov r2, #0xf1000000 @ RAM address of initrd + add r1, r2, #0x00700000 @ Size of initrd +1: + ldmia r0!, {r3, r4, r5, r6} + stmia r2!, {r3, r4, r5, r6} + cmp r2, r1 + ble 1b + + mov r8, #0 @ Zero it out + mov r7, #19 @ Set architecture ID diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S index 489bb4d96..eca1d773d 100644 --- a/arch/arm/boot/compressed/head-netwinder.S +++ b/arch/arm/boot/compressed/head-netwinder.S @@ -1,15 +1,24 @@ +#define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) + .section ".start", #alloc, #execinstr + /* + * check to see if we are running from the correct address. + * If not, we move ourselves in a two stage process. Firstly, + * we copy the start of the kernel (which includes this code) + * to 0x8000, and then jump to this code to continue with the + * rest (since this code will get overwritten). + */ adr r2, 1f - ldmdb r2, {r7, r8} + ldmdb r2, {r9, r10} and r3, r2, #0xc000 - teq r3, #0x8000 - beq 2f + teq r3, #0x8000 @ correctly located? + beq 2f @ skip this code bic r3, r2, #0xc000 orr r3, r3, #0x8000 - mov r0, r3 - mov r4, #64 - sub r5, r8, r7 + mov r0, r3 @ new address if '1' + mov r4, #64 @ number of bytes to copy + sub r5, r10, r9 @ total number of bytes to copy b 1f .word _start @@ -17,15 +26,16 @@ 1: .rept 4 - ldmia r2!, {r6, r7, r8, r9} - stmia r3!, {r6, r7, r8, r9} + ldmia r2!, {r6, r9, r10, r11} + stmia r3!, {r6, r9, r10, r11} .endr subs r4, r4, #64 bcs 1b - movs r4, r5 - mov r5, #0 - mov r1, #5 @ only here to fix NeTTroms which dont set r1 - movne pc, r0 - - mov r0, #0 + movs r4, r5 @ remaining length + mov r5, #0 @ no more to copy + movne pc, r0 @ jump back to 1 (in the newly copied + @ code) + mov r7, #5 @ only here to fix NeTTroms which dont + mov r8, #2 << 24 @ scheduled for removal in 2.5.xx + orr r8, r8, #5 << 12 2: diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S index 6b0d4624d..73cef4bd8 100644 --- a/arch/arm/boot/compressed/head-sa1100.S +++ b/arch/arm/boot/compressed/head-sa1100.S @@ -9,6 +9,7 @@ #include <linux/config.h> #include <linux/linkage.h> +#include <asm/mach-types.h> #ifndef CONFIG_ARCH_SA1100 #error What am I doing here... @@ -18,27 +19,10 @@ __SA1100_start: - @ Preserve r0/r1 i.e. kernel entry values - mov r8, r0 - mov r9, r1 - -#if defined( CONFIG_SA1100_ASSABET ) || \ - defined( CONFIG_SA1100_BRUTUS ) || \ - defined( CONFIG_SA1100_THINCLIENT ) -@ Booting from Angel -- need to enter SVC mode -#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */ -#define angel_SWI_ARM (0x123456) - mov r0, #angel_SWIreason_EnterSVC - swi #angel_SWI_ARM - - @ turn off interrupts to prevent the angel from running - mrs r0, cpsr - orr r0, r0, #0xc0 - msr cpsr_c, r0 -#endif + @ Preserve r8/r7 i.e. kernel entry values #ifdef CONFIG_SA1100_VICTOR - teq r9, #26 @ MACH_TYPE_VICTOR + teq r7, #MACH_TYPE_VICTOR bne 10f @ Copy cmdline to 0xc0000000 @@ -74,10 +58,6 @@ __SA1100_start: * Pause for a short time so that we give enough time * for the host to start a terminal up. */ - mov r0, #0x02000000 + mov r0, #0x00200000 1: subs r0, r0, #1 bne 1b - - @ Restore initial r0/r1 - mov r0, r8 - mov r1, r9 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 10c2290a0..ef9090f72 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -3,9 +3,9 @@ * * Copyright (C) 1996-1999 Russell King */ +#include <linux/config.h> #include <linux/linkage.h> - /* * Debugging stuff */ @@ -84,18 +84,31 @@ start: b 1f .word 0x016f2818 @ Magic numbers to help the loader .word start -1: +1: mov r7, r1 @ save architecture ID + mov r8, r0 @ save r0 +#ifdef CONFIG_ANGELBOOT + /* + * Booting from Angel - need to enter SVC mode and disable + * FIQs/IRQs (numeric definitions from angel arm.h source) + */ + mov r0, #0x17 @ angel_SWIreason_EnterSVC + swi 0x123456 @ angel_SWI_ARM + mrs r0, cpsr @ turn off interrupts to + orr r0, r0, #0xc0 @ prevent angel from running + msr cpsr_c, r0 + + /* + * Note that some cache flushing and other stuff may + * be needed here - is there an Angel SWI call for this? + */ +#endif /* * some architecture specific code can be inserted - * by the linker here, but it should preserve r0, r1 - * and r8. + * by the linker here, but it should preserve r7 and r8. */ .text -1: teq r0, #0 - bne 1b - mov r7, r1 @ save architecture ID - mrc p15, 0, r6, c0, c0 @ get processor ID +1: mrc p15, 0, r6, c0, c0 @ get processor ID adr r2, LC0 ldmia r2, {r2, r3, r4, r5, sp} diff --git a/arch/arm/boot/compressed/hw-bse.c b/arch/arm/boot/compressed/hw-bse.c new file mode 100644 index 000000000..3e8f07f8e --- /dev/null +++ b/arch/arm/boot/compressed/hw-bse.c @@ -0,0 +1,74 @@ +/* + * Bright Star Engineering Inc. + * + * code for readng parameters from the + * parameter blocks of the boot block + * flash memory + * + */ + +static int strcmp(const char *s1, const char *s2) +{ + while (*s1 != '\0' && *s1 == *s2) + { + s1++; + s2++; + } + + return (*(unsigned char *) s1) - (*(unsigned char *) s2); +} + +struct pblk_t { + char type; + unsigned short size; +}; + +static char *bse_getflashparam(char *name) { + unsigned int esize; + char *q,*r; + unsigned char *p,*e; + struct pblk_t *thepb = (struct pblk_t *) 0x00004000; + struct pblk_t *altpb = (struct pblk_t *) 0x00006000; + if (thepb->type&1) { + if (altpb->type&1) { + /* no valid param block */ + return (char*)0; + } else { + /* altpb is valid */ + struct pblk_t *tmp; + tmp = thepb; + thepb = altpb; + altpb = tmp; + } + } + p = (char*)thepb + sizeof(struct pblk_t); + e = p + thepb->size; + while (p < e) { + q = p; + esize = *p; + if (esize == 0xFF) break; + if (esize == 0) break; + if (esize > 127) { + esize = (esize&0x7F)<<8 | p[1]; + q++; + } + q++; + r=q; + if (*r && ((name == 0) || (!strcmp(name,r)))) { + while (*q++) ; + return q; + } + p+=esize; + } + return (char*)0; +} + +void bse_setup(void) { + /* extract the linux cmdline from flash */ + char *name=bse_getflashparam("linuxboot"); + char *x = (char *)0xc0000100; + if (name) { + while (*name) *x++=*name++; + } + *x=0; +} diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S index 6fd5b84e6..f7657773b 100644 --- a/arch/arm/boot/compressed/setup-sa1100.S +++ b/arch/arm/boot/compressed/setup-sa1100.S @@ -9,8 +9,9 @@ * Runtime test for Neponset added. */ -#define __ASSEMBLY__ #include <linux/linkage.h> +#include <linux/config.h> +#include <asm/mach-types.h> .text @@ -44,6 +45,12 @@ SCR_loc: .long SYMBOL_NAME(SCR_value) #define GPIO_2_9 0x3fc +/* + * void sa1100_setup( int arch_id ); + * + * This is called from decompress_kernel() with the arch_decomp_setup() macro. + */ + ENTRY(sa1100_setup) mov r3, r0 @ keep machine type in r3 @@ -51,7 +58,7 @@ ENTRY(sa1100_setup) @ (taken from "Intel StrongARM SA-1110 Microprocessor Development Board @ User's Guide," p.4-9) - teq r3, #25 @ MACH_TYPE_ASSABET + teq r3, #MACH_TYPE_ASSABET bne skip_SCR ldr r0, GPIO_BASE @@ -80,8 +87,8 @@ ENTRY(sa1100_setup) skip_SCR: @ Initialize UART (if bootloader has not done it yet)... - teq r3, #16 @ MACH_TYPE_BRUTUS - teqne r3, #25 @ MACH_TYPE_ASSABET + teq r3, #MACH_TYPE_BRUTUS + teqne r3, #MACH_TYPE_ASSABET bne skip_uart @ UART3 if Assabet is used with Neponset @@ -92,7 +99,7 @@ skip_SCR: @ At least for Brutus, the UART1 is used through @ the alternate GPIO function... - teq r3, #16 @ MACH_TYPE_BRUTUS + teq r3, #MACH_TYPE_BRUTUS bne uart1 alt_GPIO_uart: ldr r0, GPIO_BASE @@ -126,5 +133,14 @@ uart_init: ldr r1, [r0, #UTSR1] mov r1, #0xff @ flush status reg str r1, [r0, #UTSR0] skip_uart: + + @ Extra specific setup calls + @ The machine type is passed in r0 + mov r0, r3 +#ifdef CONFIG_SA1100_NANOENGINE + teq r0, #32 @ MACH_TYPE_NANOENGINE + beq SYMBOL_NAME(bse_setup) +#endif + out: mov pc, lr diff --git a/arch/arm/config.in b/arch/arm/config.in index 95c94d666..c45998677 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -29,6 +29,7 @@ comment 'System Type' choice 'ARM system type' \ "Archimedes/A5000 CONFIG_ARCH_ARCA5K \ + Cirrus-CL-PS7500FE CONFIG_ARCH_CLPS7500 \ Co-EBSA285 CONFIG_ARCH_CO285 \ EBSA-110 CONFIG_ARCH_EBSA110 \ FootBridge CONFIG_ARCH_FOOTBRIDGE \ @@ -62,6 +63,7 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET fi bool ' Include support for Brutus' CONFIG_SA1100_BRUTUS + bool ' Include support for CerfBoard' CONFIG_SA1100_CERF bool ' Include support for Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY # bool ' Include support for Empeg' CONFIG_SA1100_EMPEG # bool ' Include support for Itsy' CONFIG_SA1100_ITSY @@ -69,9 +71,52 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then # bool ' Include support for PLEB' CONFIG_SA1100_PLEB bool ' Include support for ThinClient' CONFIG_SA1100_THINCLIENT bool ' Include support for GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT + bool ' Include support for nanoEngine' CONFIG_SA1100_NANOENGINE bool ' Include support for Victor' CONFIG_SA1100_VICTOR # bool ' Include support for Tifon' CONFIG_SA1100_TIFON -# bool ' Include support for XP860' CONFIG_SA1100_XP860 + bool ' Include support for XP860' CONFIG_SA1100_XP860 + + bool ' Load kernel using Angel Debug Monitor' CONFIG_ANGELBOOT + + # Determine if SA1111 support is required + if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \ + "$CONFIG_SA1100_XP860" = "y" ]; then + define_bool CONFIG_SA1111 y + fi +fi + +# Definitions to make life easier +if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \ + "$CONFIG_ARCH_RPC" = "y" ]; then + define_bool CONFIG_ARCH_ACORN y +else + define_bool CONFIG_ARCH_ACORN n +fi + +# see Documentation/arm/ConfigVars for a description of these +if [ "$CONFIG_ARCH_CO285" = "y" -o \ + "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then + define_bool CONFIG_FOOTBRIDGE y +else + define_bool CONFIG_FOOTBRIDGE n +fi +if [ "$CONFIG_ARCH_CATS" = "y" -o \ + "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \ + "$CONFIG_ARCH_NETWINDER" = "y" -o \ + "$CONFIG_ARCH_PERSONAL_SERVER" = "y" ]; then + define_bool CONFIG_FOOTBRIDGE_HOST y +else + define_bool CONFIG_FOOTBRIDGE_HOST n +fi +if [ "$CONFIG_ARCH_CO285" = "y" -o \ + "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then + define_bool CONFIG_FOOTBRIDGE_ADDIN y +else + define_bool CONFIG_FOOTBRIDGE_ADDIN n +fi +if [ "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \ + "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then + define_bool CONFIG_ARCH_EBSA285 y fi # Figure out whether this system uses 26-bit or 32-bit CPUs. @@ -113,38 +158,6 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then fi # Select various configuration options depending on the machine type -if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \ - "$CONFIG_ARCH_RPC" = "y" ]; then - define_bool CONFIG_ARCH_ACORN y -else - define_bool CONFIG_ARCH_ACORN n -fi - -if [ "$CONFIG_ARCH_CO285" = "y" -o \ - "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then - define_bool CONFIG_FOOTBRIDGE y -else - define_bool CONFIG_FOOTBRIDGE n -fi -if [ "$CONFIG_ARCH_CATS" = "y" -o \ - "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \ - "$CONFIG_ARCH_NETWINDER" = "y" -o \ - "$CONFIG_ARCH_PERSONAL_SERVER" = "y" ]; then - define_bool CONFIG_FOOTBRIDGE_HOST y -else - define_bool CONFIG_FOOTBRIDGE_HOST n -fi -if [ "$CONFIG_ARCH_CO285" = "y" -o \ - "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then - define_bool CONFIG_FOOTBRIDGE_ADDIN y -else - define_bool CONFIG_FOOTBRIDGE_ADDIN n -fi -if [ "$CONFIG_ARCH_EBSA285_HOST" = "y" -o \ - "$CONFIG_ARCH_EBSA285_ADDIN" = "y" ]; then - define_bool CONFIG_ARCH_EBSA285 y -fi - if [ "$CONFIG_ARCH_SA1100" = "y" ]; then define_bool CONFIG_DISCONTIGMEM y else @@ -167,6 +180,15 @@ else define_bool CONFIG_ISA n define_bool CONFIG_ISA_DMA n fi + +# Do we have a PC-type keyboard in this architecture? +if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_PC_KEYMAP y +fi +if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then + define_bool CONFIG_PC_KEYMAP y +fi endmenu mainmenu_option next_comment @@ -199,6 +221,7 @@ if [ "$CONFIG_CPU_32" = "y" ]; then fi if [ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_CLPS7500" = "y" -o \ "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \ "$CONFIG_ARCH_CATS" = "y" ]; then string 'Default kernel command string' CONFIG_CMDLINE "" @@ -301,6 +324,8 @@ fi #source drivers/misc/Config.in +source drivers/media/Config.in + source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then @@ -329,6 +354,7 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \ fi source drivers/usb/Config.in +source drivers/input/Config.in mainmenu_option next_comment diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 62c0ca60e..9fa2e8e86 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -5,9 +5,14 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). +USE_STANDARD_AS_RULE := true + HEAD_OBJ = head-$(PROCESSOR).o ENTRY_OBJ = entry-$(PROCESSOR).o +AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional +AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional + O_OBJS_arc = dma-arc.o oldlatches.o O_OBJS_rpc = dma-rpc.o O_OBJS_footbridge = dma-footbridge.o hw-footbridge.o isa.o @@ -54,14 +59,8 @@ MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) all: kernel.o $(HEAD_OBJ) init_task.o -$(HEAD_OBJ): $(HEAD_OBJ:.o=.S) - $(CC) $(AFLAGS) -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ - include $(TOPDIR)/Rules.make -.S.o: - $(CC) $(AFLAGS) $(AFLAGS_$@) -c -o $*.o $< - # Spell out some dependencies that `make dep' doesn't spot entry-armv.o: calls.S ../lib/constants.h entry-armo.o: calls.S ../lib/constants.h diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c index 0ce6d9d21..e25331e03 100644 --- a/arch/arm/kernel/arch.c +++ b/arch/arm/kernel/arch.c @@ -15,7 +15,7 @@ #include <asm/dec21285.h> #include <asm/elf.h> #include <asm/setup.h> -#include <asm/system.h> +#include <asm/mach-types.h> #include "arch.h" @@ -219,6 +219,17 @@ static void victor_power_off(void) while (1); } + +static void xp860_power_off(void) +{ + GPDR |= GPIO_GPIO20; + GPSR = GPIO_GPIO20; + mdelay(1000); + GPCR = GPIO_GPIO20; + while(1); +} + + extern void select_sa1100_io_desc(void); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ @@ -273,6 +284,18 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params, setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 ); } + else if (machine_is_cerf()) { + // 16Meg Ram. + SET_BANK( 0, 0xc0000000, 8*1024*1024 ); + SET_BANK( 1, 0xc8000000, 8*1024*1024 ); // comment this out for 8MB Cerfs + mi->nr_banks = 2; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk(1, 0, 0, 8192); + // Save 2Meg for RAMDisk + setup_initrd(0xc0500000, 3*1024*1024); + } + else if (machine_is_empeg()) { SET_BANK( 0, 0xc0000000, 4*1024*1024 ); SET_BANK( 1, 0xc8000000, 4*1024*1024 ); @@ -309,6 +332,18 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params, setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); } + else if (machine_is_nanoengine()) { + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); + + /* Get command line parameters passed from the loader (if any) */ + if( *((char*)0xc0000100) ) + *cmdline = ((char *)0xc0000100); + } else if (machine_is_tifon()) { SET_BANK( 0, 0xc0000000, 16*1024*1024 ); SET_BANK( 1, 0xc8000000, 16*1024*1024 ); @@ -335,6 +370,12 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params, pm_power_off = victor_power_off; } + else if (machine_is_xp860()) { + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + pm_power_off = xp860_power_off; + } } #ifdef CONFIG_SA1100_ASSABET @@ -356,6 +397,13 @@ MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)") FIXUP(fixup_sa1100) MACHINE_END #endif +#ifdef CONFIG_SA1100_CERF +MACHINE_START(CERF, "Intrinsyc CerfBoard") + MAINTAINER("Pieter Truter") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END +#endif #ifdef CONFIG_SA1100_EMPEG MACHINE_START(EMPEG, "empeg MP3 Car Audio Player") BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) @@ -381,6 +429,12 @@ MACHINE_START(LART, "LART") FIXUP(fixup_sa1100) MACHINE_END #endif +#ifdef CONFIG_SA1100_NANOENGINE +MACHINE_START(NANOENGINE, "BSE nanoEngine") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END +#endif #ifdef CONFIG_SA1100_PLEB MACHINE_START(PLEB, "PLEB") BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index fc14d6c45..8dafc4db9 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -23,6 +23,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/checksum.h> +#include <asm/mach-types.h> extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(struct pt_regs *, struct user_fp_struct *); @@ -187,10 +188,6 @@ EXPORT_SYMBOL(__arch_copy_from_user); EXPORT_SYMBOL(__arch_copy_to_user); EXPORT_SYMBOL(__arch_clear_user); EXPORT_SYMBOL(__arch_strnlen_user); -#elif defined(CONFIG_CPU_26) -EXPORT_SYMBOL(uaccess_kernel); -EXPORT_SYMBOL(uaccess_user); -#endif /* consistent area handling */ EXPORT_SYMBOL(pci_alloc_consistent); @@ -198,6 +195,11 @@ EXPORT_SYMBOL(consistent_alloc); EXPORT_SYMBOL(consistent_free); EXPORT_SYMBOL(consistent_sync); +#elif defined(CONFIG_CPU_26) +EXPORT_SYMBOL(uaccess_kernel); +EXPORT_SYMBOL(uaccess_user); +#endif + /* gcc lib functions */ EXPORT_SYMBOL_NOVERS(__gcc_bcmp); EXPORT_SYMBOL_NOVERS(__ashldi3); diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index b2c644198..0b519e9c3 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -11,7 +11,7 @@ #include <linux/init.h> #include <asm/irq.h> -#include <asm/system.h> +#include <asm/mach-types.h> #include "bios32.h" @@ -198,20 +198,35 @@ void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { - unsigned long where, size; - u32 reg; + u32 val, check; + int reg; if (debug_pci) printk("PCI: Assigning %3s %08lx to %s\n", res->flags & IORESOURCE_IO ? "IO" : "MEM", res->start, dev->name); - where = PCI_BASE_ADDRESS_0 + resource * 4; - size = res->end - res->start; - - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); + val = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + val |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a + * non-standard resource. + */ + return; + } + pci_write_config_dword(dev, reg, val); + pci_read_config_dword(dev, reg, &check); + if ((val ^ check) & ((val & PCI_BASE_ADDRESS_SPACE_IO) ? + PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, + resource, val, check); + } } void __init pcibios_update_irq(struct pci_dev *dev, int irq) diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 0db6d0fde..eee31eeae 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -226,8 +226,9 @@ .long SYMBOL_NAME(sys_setgid) /* 215 */ .long SYMBOL_NAME(sys_setfsuid) .long SYMBOL_NAME(sys_setfsgid) + .long SYMBOL_NAME(sys_getdents64) - .rept NR_syscalls-216 + .rept NR_syscalls-217 .long SYMBOL_NAME(sys_ni_syscall) .endr #endif diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S index da81b3b05..e0b916438 100644 --- a/arch/arm/kernel/debug-armv.S +++ b/arch/arm/kernel/debug-armv.S @@ -162,12 +162,14 @@ #elif defined(CONFIG_ARCH_L7200) - .macro addruart,rx + .equ io_virt, IO_BASE + .equ io_phys, IO_START + .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? - moveq \rx, #0x80000000 @ physical base address - movne \rx, #0xd0000000 @ virtual address + moveq \rx, #io_phys @ physical base address + movne \rx, #io_virt @ virtual address add \rx, \rx, #0x00044000 @ Ser1 @ add \rx, \rx, #0x00045000 @ Ser2 .endm diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c index 7fb43c68a..3238b3a3c 100644 --- a/arch/arm/kernel/dec21285.c +++ b/arch/arm/kernel/dec21285.c @@ -274,7 +274,7 @@ void __init dc21285_init(void) cfn_mode = __footbridge_cfn_mode(); - printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX in " + printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX, in " "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ? "central function" : "addin"); diff --git a/arch/arm/kernel/dma-arc.c b/arch/arm/kernel/dma-arc.c index 5a2f93b67..25fbcccd8 100644 --- a/arch/arm/kernel/dma-arc.c +++ b/arch/arm/kernel/dma-arc.c @@ -13,6 +13,7 @@ #include <asm/fiq.h> #include <asm/io.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include "dma.h" diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c index 35e3c35a3..c7eecfe42 100644 --- a/arch/arm/kernel/dma-rpc.c +++ b/arch/arm/kernel/dma-rpc.c @@ -315,7 +315,7 @@ static struct dma_ops floppy_dma_ops = { /* * This is virtual DMA - we don't need anything here. */ -static int sound_enable_disable_dma(dmach_t channel, dma_t *dma) +static void sound_enable_disable_dma(dmach_t channel, dma_t *dma) { } diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 7ed4c28ca..6fe844db4 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -248,24 +248,23 @@ int request_dma(dmach_t channel, const char *device_id) return -EINVAL; } -static int no_dma(void) +int get_dma_residue(dmach_t channel) { return 0; } #define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a) -GLOBAL_ALIAS(disable_dma, no_dma); -GLOBAL_ALIAS(enable_dma, no_dma); -GLOBAL_ALIAS(free_dma, no_dma); -GLOBAL_ALIAS(get_dma_residue, no_dma); -GLOBAL_ALIAS(get_dma_list, no_dma); -GLOBAL_ALIAS(set_dma_mode, no_dma); -GLOBAL_ALIAS(set_dma_page, no_dma); -GLOBAL_ALIAS(set_dma_count, no_dma); -GLOBAL_ALIAS(set_dma_addr, no_dma); -GLOBAL_ALIAS(set_dma_sg, no_dma); -GLOBAL_ALIAS(set_dma_speed, no_dma); -GLOBAL_ALIAS(init_dma, no_dma); +GLOBAL_ALIAS(disable_dma, get_dma_residue); +GLOBAL_ALIAS(enable_dma, get_dma_residue); +GLOBAL_ALIAS(free_dma, get_dma_residue); +GLOBAL_ALIAS(get_dma_list, get_dma_residue); +GLOBAL_ALIAS(set_dma_mode, get_dma_residue); +GLOBAL_ALIAS(set_dma_page, get_dma_residue); +GLOBAL_ALIAS(set_dma_count, get_dma_residue); +GLOBAL_ALIAS(set_dma_addr, get_dma_residue); +GLOBAL_ALIAS(set_dma_sg, get_dma_residue); +GLOBAL_ALIAS(set_dma_speed, get_dma_residue); +GLOBAL_ALIAS(init_dma, get_dma_residue); #endif diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 5acfd9f24..6d9b425ea 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -265,8 +265,7 @@ static int exec_mmap(void) * Set up the expansion card * daemon's environment. */ -static void -ecard_init_task(void) +static void ecard_init_task(int force) { /* We want to set up the page tables for the following mapping: * Virtual Physical @@ -282,7 +281,8 @@ ecard_init_task(void) pgd_t *src_pgd, *dst_pgd; unsigned int dst_addr = IO_START; - exec_mmap(); + if (!force) + exec_mmap(); src_pgd = pgd_offset(current->mm, IO_BASE); dst_pgd = pgd_offset(current->mm, dst_addr); @@ -309,21 +309,24 @@ ecard_init_task(void) static int ecard_task(void * unused) { - current->session = 1; - current->pgrp = 1; + struct task_struct *tsk = current; + + tsk->session = 1; + tsk->pgrp = 1; /* * We don't want /any/ signals, not even SIGKILL */ - sigfillset(¤t->blocked); - sigemptyset(¤t->signal); + sigfillset(&tsk->blocked); + sigemptyset(&tsk->signal); + recalc_sigpending(tsk); - strcpy(current->comm, "kecardd"); + strcpy(tsk->comm, "kecardd"); /* * Set up the environment */ - ecard_init_task(); + ecard_init_task(0); while (1) { struct ecard_request *req; @@ -332,7 +335,7 @@ ecard_task(void * unused) req = xchg(&ecard_req, NULL); if (req == NULL) { - sigemptyset(¤t->signal); + sigemptyset(&tsk->signal); interruptible_sleep_on(&ecard_wait); } } while (req == NULL); @@ -368,7 +371,7 @@ ecard_call(struct ecard_request *req) */ if ((current == &init_task || in_interrupt()) && req->req == req_reset && req->ec == NULL) { - ecard_init_task(); + ecard_init_task(1); ecard_task_reset(req); } else { if (ecard_pid <= 0) diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S index d6fa94867..ab0f4e69e 100644 --- a/arch/arm/kernel/entry-armo.S +++ b/arch/arm/kernel/entry-armo.S @@ -38,17 +38,6 @@ .text -@ Offsets into task structure -@ --------------------------- -@ -#define STATE 0 -#define COUNTER 4 -#define PRIORITY 8 -#define FLAGS 12 -#define SIGPENDING 16 - -#define PF_TRACESYS 0x20 - @ Bad Abort numbers @ ----------------- @ @@ -58,12 +47,6 @@ #define BAD_IRQ 3 #define BAD_UNDEFINSTR 4 -@ OS version number used in SWIs -@ RISC OS is 0 -@ RISC iX is 8 -@ -#define OS_NUMBER 9 - @ @ Stack format (ensured by USER_* and SVC_*) @ @@ -456,6 +439,7 @@ vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case... orr lr, lr, #0x08000003 @ Force SVC bne do_IRQ mov r4, #0 + get_current_task r5 b ret_with_reschedule irq_prio_table diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 5d4f216b6..002c39933 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -32,8 +32,6 @@ .text -#define PT_TRACESYS 0x00000002 - @ Bad Abort numbers @ ----------------- @ @@ -43,12 +41,6 @@ #define BAD_IRQ 3 #define BAD_UNDEFINSTR 4 -@ OS version number used in SWIs -@ RISC OS is 0 -@ RISC iX is 8 -@ -#define OS_NUMBER 9 - @ @ Stack format (ensured by USER_* and SVC_*) @ @@ -426,12 +418,15 @@ ENTRY(soft_irq_mask) .endm #elif defined(CONFIG_ARCH_L7200) -/* Don't use fast interrupts */ + + .equ irq_base_addr, IO_BASE_2 + .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base - ldr r4, =0xe0001000 @ Virt addr status reg + mov r4, #irq_base_addr @ Virt addr IRQ regs + add r4, r4, #0x00001000 @ Status reg ldr \irqstat, [r4] @ get interrupts mov \irqnr, #0 1001: tst \irqstat, #1 @@ -727,6 +722,7 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE @ bne do_IRQ mov r4, #0 + get_current_task r5 b ret_with_reschedule .align 5 diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index c260b8e19..b22720cd5 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -1,4 +1,13 @@ #include <linux/config.h> + +#define PT_TRACESYS 0x00000002 + +@ OS version number used in SWIs +@ RISC OS is 0 +@ RISC iX is 8 +@ +#define OS_NUMBER 9 + /*============================================================================ * All exits to user mode from the kernel go through this code. */ @@ -22,25 +31,23 @@ slow_syscall_return: add sp, sp, #S_OFF ret_from_sys_call: @ external entry get_softirq r0 + get_current_task r5 ldmia r0, {r0, r1} @ softirq_active, softirq_mask mov r4, #1 @ flag this as being syscall return tst r0, r1 blne SYMBOL_NAME(do_softirq) -ret_with_reschedule: @ external entry (__irq_usr) - get_current_task r5 +ret_with_reschedule: @ external entry (r5 must be set) (__irq_usr) ldr r0, [r5, #TSK_NEED_RESCHED] ldr r1, [r5, #TSK_SIGPENDING] teq r0, #0 bne ret_reschedule teq r1, #0 @ check for signals - bne ret_signal - + blne ret_signal ret_from_all: restore_user_regs @ internal ret_signal: mov r1, sp @ internal - adrsvc al, lr, ret_from_all mov r2, r4 - b SYMBOL_NAME(do_signal) + b SYMBOL_NAME(do_signal) @ note the bl above sets lr ret_reschedule: adrsvc al, lr, ret_with_reschedule @ internal b SYMBOL_NAME(schedule) @@ -48,12 +55,13 @@ ret_reschedule: adrsvc al, lr, ret_with_reschedule @ internal .globl ret_from_exception ret_from_exception: @ external entry get_softirq r0 + get_current_task r5 ldmia r0, {r0, r1} @ softirq_active, softirq_mask mov r4, #0 tst r0, r1 + ldr r6, [sp, #S_PSR] blne SYMBOL_NAME(do_softirq) - ldr r0, [sp, #S_PSR] - tst r0, #3 @ returning to user mode? + tst r6, #3 @ returning to user mode? beq ret_with_reschedule b ret_from_all diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 6597de184..b74d7550f 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -83,8 +83,11 @@ int fiq_def_op(void *ref, int relinquish) return 0; } -static struct fiq_handler default_owner = - { NULL, "default", fiq_def_op, NULL }; +static struct fiq_handler default_owner = { + name: "default", + fiq_op: fiq_def_op, +}; + static struct fiq_handler *current_fiq = &default_owner; int get_fiq_list(char *buf) diff --git a/arch/arm/kernel/head-armo.S b/arch/arm/kernel/head-armo.S index df5b02ae8..f0360a3d9 100644 --- a/arch/arm/kernel/head-armo.S +++ b/arch/arm/kernel/head-armo.S @@ -1,11 +1,13 @@ /* * linux/arch/arm/kernel/head-armo.S * - * Copyright (C) 1994, 1995, 1996, 1997 Russell King + * Copyright (C) 1994-2000 Russell King * * 26-bit kernel startup code */ +#include <linux/config.h> #include <linux/linkage.h> +#include <asm/mach-types.h> .globl SYMBOL_NAME(swapper_pg_dir) .equ SYMBOL_NAME(swapper_pg_dir), 0x0207d000 @@ -17,46 +19,69 @@ ENTRY(stext) ENTRY(_stext) __entry: cmp pc, #0x02000000 - ldrlt pc, LC1 @ if 0x01800000, call at 0x02080000 + ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000 teq r0, #0 @ Check for old calling method - blne Loldparams @ Move page if old - adr r5, LC0 - ldmia r5, {r5, r6, sl, sp} @ Setup stack - mov r4, #0 -1: cmp r5, sl @ Clear BSS - strcc r4, [r5], #4 + blne oldparams @ Move page if old + adr r0, LC0 + ldmib r0, {r2-r5, sp} @ Setup stack + mov r0, #0 +1: cmp r2, r3 @ Clear BSS + strcc r0, [r2], #4 bcc 1b - mov r0, #0xea000000 @ Point undef instr to continuation - adr r5, Lcontinue - 12 - orr r5, r0, r5, lsr #2 - str r5, [r4, #4] - mov r2, r4 - ldr r5, Larm2_id - swp r0, r0, [r2] @ check for swp (ARM2 can't) - ldr r5, Larm250_id - mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't) - mov r5, r0 @ Use processor ID if we do have CP#15 -Lcontinue: str r5, [r6] - mov r5, #0xeb000000 @ Point undef instr vector to itself - sub r5, r5, #2 - str r5, [r4, #4] + + bl detect_proc_type + str r0, [r4] + bl detect_arch_type + str r0, [r5] + mov fp, #0 b SYMBOL_NAME(start_kernel) -LC1: .word SYMBOL_NAME(_stext) -LC0: .word SYMBOL_NAME(__bss_start) - .word SYMBOL_NAME(processor_id) - .word SYMBOL_NAME(_end) - .word SYMBOL_NAME(init_task_union)+8192 -Larm2_id: .long 0x41560200 -Larm250_id: .long 0x41560250 +LC0: .word SYMBOL_NAME(_stext) + .word SYMBOL_NAME(__bss_start) @ r2 + .word SYMBOL_NAME(_end) @ r3 + .word SYMBOL_NAME(processor_id) @ r4 + .word SYMBOL_NAME(__machine_arch_type) @ r5 + .word SYMBOL_NAME(init_task_union)+8192 @ sp +arm2_id: .long 0x41560200 +arm250_id: .long 0x41560250 .align -Loldparams: mov r4, #0x02000000 +oldparams: mov r4, #0x02000000 add r3, r4, #0x00080000 add r4, r4, #0x0007c000 1: ldmia r0!, {r5 - r12} stmia r4!, {r5 - r12} cmp r4, r3 blt 1b - movs pc, lr + mov pc, lr + +/* + * We need some way to automatically detect the difference between + * these two machines. Unfortunately, it is not possible to detect + * the presence of the SuperIO chip, because that will hang the old + * Archimedes machines solid. + */ +/* DAG: Outdated, these have been combined !!!!!!! */ +detect_arch_type: +#if defined(CONFIG_ARCH_ARC) + mov r0, #MACH_TYPE_ARCHIMEDES +#elif defined(CONFIG_ARCH_A5K) + mov r0, #MACH_TYPE_A5K +#endif + mov pc, lr + +detect_proc_type: + mov r2, #0xea000000 @ Point undef instr to continuation + adr r0, continue - 12 + orr r0, r2, r0, lsr #2 + mov r1, #0 + str r0, [r1, #4] + ldr r0, arm2_id + swp r2, r2, [r1] @ check for swp (ARM2 can't) + ldr r0, arm250_id + mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't) +continue: mov r2, #0xeb000000 @ Make undef vector loop + sub r2, r2, #2 + str r2, [r1, #4] + mov pc, lr diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S index 38bfc8760..e253c7efa 100644 --- a/arch/arm/kernel/head-armv.S +++ b/arch/arm/kernel/head-armv.S @@ -19,6 +19,7 @@ #endif #define SWAPPER_PGDIR_OFFSET 0x4000 +#define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) .globl SYMBOL_NAME(swapper_pg_dir) .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET @@ -27,7 +28,28 @@ .type stext, #function ENTRY(stext) ENTRY(_stext) - +/* + * Entry point. The general rules are: + * should be called with r0 == 0 + * r1 contains the unique architecture number + * with MMU is off, I-cache may be on or off, D-cache should be off. + * See linux/arch/arm/kernel/arch.c and linux/include/asm-arm/system.h + * for the complete list of numbers for r1. If you require a new number, + * please follow the instructions given towards the end of + * linux/Documentation/arm/README. + */ + mov r12, r0 +/* + * NOTE! Any code which is placed here should be done for one of + * the following reasons: + * + * 1. Compatability with old production boot firmware (ie, users + * actually have and are booting the kernel with the old firmware) + * and therefore will be eventually removed. + * 2. Cover the case when there is no boot firmware. This is not + * ideal, but in this case, it should ONLY set r0 and r1 to the + * appropriate value. + */ #ifdef CONFIG_ARCH_NETWINDER /* * Compatability cruft for old NetWinder NeTTroms. This @@ -63,28 +85,18 @@ ENTRY(_stext) mov r5, #0 movne pc, r0 - mov r0, #0 @ catch old NeTTroms mov r1, #5 @ (will go in 2.5) + mov r12, #2 << 24 @ scheduled for removal in 2.5.xx + orr r12, r12, #5 << 12 #endif #ifdef CONFIG_ARCH_L7200 /* * FIXME - No bootloader, so manually set 'r1' with our architecture number. */ - mov r0, #0 mov r1, #19 #endif -/* - * Entry point. Entry *must* be called with r0 == 0, with the MMU off. - * r1 contains the unique architecture number. See - * linux/arch/arm/kernel/arch.c and linux/include/asm-arm/system.h for - * the complete list. If you require a new number, please follow the - * instructions given towards the end of Documentation/arm/README. - */ -__entry: teq r0, #0 @ wrong register vals? - movne r0, #'i' @ yes, error 'i' - bne __error - bl __lookup_processor_type +__entry: bl __lookup_processor_type teq r10, #0 @ invalid processor? moveq r0, #'p' @ yes, error 'p' beq __error @@ -98,6 +110,7 @@ __entry: teq r0, #0 @ wrong register vals? @ (return control reg) __switch_data: .long __mmap_switched + .long SYMBOL_NAME(compat) .long SYMBOL_NAME(__bss_start) .long SYMBOL_NAME(_end) .long SYMBOL_NAME(processor_id) @@ -123,8 +136,9 @@ __ret: ldr lr, __switch_data .align 5 __mmap_switched: adr r3, __switch_data + 4 - ldmia r3, {r4, r5, r6, r7, r8, sp} @ r4 = __bss_start + ldmia r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat @ sp = stack pointer + str r12, [r2] mov fp, #0 @ Clear BSS 1: cmp r4, r5 diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c index b56b944e7..41ff450a5 100644 --- a/arch/arm/kernel/hw-footbridge.c +++ b/arch/arm/kernel/hw-footbridge.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <asm/leds.h> -#include <asm/system.h> +#include <asm/mach-types.h> #define IRDA_IO_BASE 0x180 #define GP1_IO_BASE 0x338 diff --git a/arch/arm/kernel/hw-sa1100.c b/arch/arm/kernel/hw-sa1100.c index 27786cdd2..5acfab1e2 100644 --- a/arch/arm/kernel/hw-sa1100.c +++ b/arch/arm/kernel/hw-sa1100.c @@ -17,7 +17,7 @@ #include <asm/delay.h> #include <asm/hardware.h> - +#include <asm/mach-types.h> /* * SA1100 GPIO edge detection for IRQs: @@ -130,12 +130,40 @@ void __init sa1111_init(void){ * any other SA-1111 functional blocks must be enabled separately * using the SKPCR. */ + + { + /* + * SA1111 DMA bus master setup + */ + int cas; + + /* SA1111 side */ + switch ( (MDCNFG>>12) & 0x03 ) { + case 0x02: + cas = 0; break; + case 0x03: + cas = 1; break; + default: + cas = 1; break; + } + SMCR = 1 /* 1: memory is SDRAM */ + | ( 1 << 1 ) /* 1:MBGNT is enable */ + | ( ((MDCNFG >> 4) & 0x07) << 2 ) /* row address lines */ + | ( cas << 5 ); /* CAS latency */ + + /* SA1110 side */ + GPDR |= 1<<21; + GPDR &= ~(1<<22); + GAFR |= ( (1<<21) | (1<<22) ); + + TUCR |= (1<<10); + } } #endif -static void __init hw_sa1100_init(void) +static int __init hw_sa1100_init(void) { if( machine_is_assabet() ){ if(machine_has_neponset()){ @@ -147,7 +175,10 @@ static void __init hw_sa1100_init(void) "hasn't been configured in the kernel\n" ); #endif } + } else if (machine_is_xp860()) { + sa1111_init(); } + return 0; } module_init(hw_sa1100_init); diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 8af0c3b3f..69b72624d 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -31,18 +31,12 @@ #include <asm/io.h> #include <asm/system.h> -#ifndef cliIF -#define cliIF() -#endif - /* - * Maximum IRQ count. Currently, this is arbitary. - * However, it should not be set too low to prevent - * false triggering. Conversely, if it is set too - * high, then you could miss a stuck IRQ. + * Maximum IRQ count. Currently, this is arbitary. However, it should + * not be set too low to prevent false triggering. Conversely, if it + * is set too high, then you could miss a stuck IRQ. * - * Maybe we ought to set a timer and re-enable the - * IRQ at a later time? + * Maybe we ought to set a timer and re-enable the IRQ at a later time? */ #define MAX_IRQ_CNT 100000 @@ -94,7 +88,6 @@ void disable_irq(unsigned int irq) unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - cliIF(); irq_desc[irq].enabled = 0; irq_desc[irq].mask(irq); spin_unlock_irqrestore(&irq_controller_lock, flags); @@ -105,7 +98,6 @@ void enable_irq(unsigned int irq) unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - cliIF(); irq_desc[irq].probing = 0; irq_desc[irq].triggered = 0; irq_desc[irq].enabled = 1; diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/kernel/leds-footbridge.c index b309c2ea3..3de4c96f9 100644 --- a/arch/arm/kernel/leds-footbridge.c +++ b/arch/arm/kernel/leds-footbridge.c @@ -25,6 +25,7 @@ #include <asm/hardware.h> #include <asm/leds.h> +#include <asm/mach-types.h> #include <asm/system.h> #define LED_STATE_ENABLED 1 @@ -35,7 +36,7 @@ static char hw_led_state; static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; extern spinlock_t gpio_lock; -#ifdef CONFIG_FOOTBRIDGE +#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285) static void ebsa285_leds_event(led_event_t evt) { @@ -76,15 +77,20 @@ static void ebsa285_leds_event(led_event_t evt) #ifdef CONFIG_LEDS_CPU case led_idle_start: if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state |= XBUS_LED_RED; + hw_led_state |= XBUS_LED_AMBER; break; case led_idle_end: if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state &= ~XBUS_LED_RED; + hw_led_state &= ~XBUS_LED_AMBER; break; #endif + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~XBUS_LED_RED; + break; + case led_green_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~XBUS_LED_GREEN; @@ -174,6 +180,11 @@ static void netwinder_leds_event(led_event_t evt) break; #endif + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; + case led_green_on: if (led_state & LED_STATE_CLAIMED) hw_led_state |= GPIO_GREEN_LED; @@ -229,7 +240,7 @@ EXPORT_SYMBOL(leds_event); static int __init leds_init(void) { -#ifdef CONFIG_FOOTBRIDGE +#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285) if (machine_is_ebsa285() || machine_is_co285()) leds_event = ebsa285_leds_event; #endif diff --git a/arch/arm/kernel/leds-sa1100.c b/arch/arm/kernel/leds-sa1100.c index f2f0325c3..fc4662c2a 100644 --- a/arch/arm/kernel/leds-sa1100.c +++ b/arch/arm/kernel/leds-sa1100.c @@ -36,6 +36,7 @@ #include <asm/hardware.h> #include <asm/leds.h> +#include <asm/mach-types.h> #include <asm/system.h> @@ -95,6 +96,9 @@ static void assabet_leds_event(led_event_t evt) break; #endif + case led_halted: + break; + case led_green_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~BCR_LED_GREEN; @@ -302,6 +306,100 @@ static void lart_leds_event(led_event_t evt) #endif /* CONFIG_SA1100_LART */ +#ifdef CONFIG_SA1100_CERF +#define LED_D0 GPIO_GPIO(0) +#define LED_D1 GPIO_GPIO(1) +#define LED_D2 GPIO_GPIO(2) +#define LED_D3 GPIO_GPIO(3) +#define LED_MASK (LED_D0|LED_D1|LED_D2|LED_D3) + +static void cerf_leds_event(led_event_t evt) +{ + unsigned long flags; + + save_flags_cli(flags); + + switch (evt) { + case led_start: + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_D0; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D1; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D1; + break; +#endif + case led_green_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D2; + break; + + case led_green_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D2; + break; + + case led_amber_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D3; + break; + + case led_amber_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D3; + break; + + case led_red_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D1; + break; + + case led_red_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D1; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + restore_flags(flags); +} + +#endif /* CONFIG_SA1100_CERF */ + static void dummy_leds_event(led_event_t evt) { } @@ -325,7 +423,13 @@ sa1100_leds_init(void) if (machine_is_lart()) leds_event = lart_leds_event; #endif - +#ifdef CONFIG_SA1100_CERF + if (machine_is_cerf()) + { + //GPDR |= 0x0000000F; + leds_event = cerf_leds_event; + } +#endif leds_event(led_start); return 0; } diff --git a/arch/arm/kernel/oldlatches.c b/arch/arm/kernel/oldlatches.c index 3d6758ff4..91b9e5d62 100644 --- a/arch/arm/kernel/oldlatches.c +++ b/arch/arm/kernel/oldlatches.c @@ -1,14 +1,17 @@ /* Support for the latches on the old Archimedes which control the floppy, * hard disc and printer * - * (c) David Alan Gilbert 1995/1996 + * (c) David Alan Gilbert 1995/1996,2000 */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/sched.h> #include <asm/io.h> #include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/arch/oldlatches.h> static unsigned char latch_a_copy; static unsigned char latch_b_copy; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3ef5bc59d..478810936 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -22,6 +22,7 @@ #include <asm/system.h> #include <asm/io.h> +#include <asm/leds.h> #include <asm/uaccess.h> /* @@ -32,7 +33,7 @@ #define IDLE_CLOCK_SLOW 2 #define IDLE_CLOCK_FAST 3 -extern char *processor_modes[]; +extern const char *processor_modes[]; extern void setup_mm_for_reboot(char mode); asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); @@ -109,10 +110,12 @@ __setup("reboot=", reboot_setup); void machine_halt(void) { + leds_event(led_halted); } void machine_power_off(void) { + leds_event(led_halted); if (pm_power_off) pm_power_off(); } diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index 8118b6a68..d29f8cf1f 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c @@ -7,6 +7,7 @@ * * Modified for ARM by Russell King */ +#include <linux/config.h> #include <linux/sched.h> #include <asm/semaphore.h> @@ -53,8 +54,8 @@ void __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; - add_wait_queue(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); sem->sleepers++; @@ -67,28 +68,28 @@ void __down(struct semaphore * sem) */ if (!atomic_add_negative(sleepers - 1, &sem->count)) { sem->sleepers = 0; - wake_up(&sem->wait); break; } sem->sleepers = 1; /* us - see -1 above */ spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_UNINTERRUPTIBLE; + tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + wake_up(&sem->wait); } int __down_interruptible(struct semaphore * sem) { - int retval; + int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; - add_wait_queue(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); sem->sleepers ++; @@ -102,12 +103,10 @@ int __down_interruptible(struct semaphore * sem) * it has contention. Just correct the count * and exit. */ - retval = -EINTR; if (signal_pending(current)) { + retval = -EINTR; sem->sleepers = 0; - if (atomic_add_negative(sleepers, &sem->count)) - break; - wake_up(&sem->wait); + atomic_add(sleepers, &sem->count); break; } @@ -118,8 +117,6 @@ int __down_interruptible(struct semaphore * sem) * the lock. */ if (!atomic_add_negative(sleepers - 1, &sem->count)) { - wake_up(&sem->wait); - retval = 0; sem->sleepers = 0; break; } @@ -127,12 +124,13 @@ int __down_interruptible(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_INTERRUPTIBLE; + tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); tsk->state = TASK_RUNNING; remove_wait_queue(&sem->wait, &wait); + wake_up(&sem->wait); return retval; } @@ -147,8 +145,9 @@ int __down_interruptible(struct semaphore * sem) int __down_trylock(struct semaphore * sem) { int sleepers; + unsigned long flags; - spin_lock_irq(&semaphore_lock); + spin_lock_irqsave(&semaphore_lock, flags); sleepers = sem->sleepers + 1; sem->sleepers = 0; @@ -159,7 +158,7 @@ int __down_trylock(struct semaphore * sem) if (!atomic_add_negative(sleepers, &sem->count)) wake_up(&sem->wait); - spin_unlock_irq(&semaphore_lock); + spin_unlock_irqrestore(&semaphore_lock, flags); return 1; } @@ -254,7 +253,8 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ schedule(); + break; /* we must attempt to aquire or bias the lock */ + schedule(); } remove_wait_queue(&sem->wait, &wait); @@ -293,6 +293,102 @@ struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem) * registers (r0 to r3 and lr), but not ip, as we use it as a return * value in some cases.. */ +#ifdef CONFIG_CPU_26 +asm(" .section .text.lock, \"ax\" + .align 5 + .globl __down_failed +__down_failed: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bl __down + ldmfd sp!, {r0 - r3, pc}^ + + .align 5 + .globl __down_interruptible_failed +__down_interruptible_failed: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bl __down_interruptible + mov ip, r0 + ldmfd sp!, {r0 - r3, pc}^ + + .align 5 + .globl __down_trylock_failed +__down_trylock_failed: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bl __down_trylock + mov ip, r0 + ldmfd sp!, {r0 - r3, pc}^ + + .align 5 + .globl __up_wakeup +__up_wakeup: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bl __up + ldmfd sp!, {r0 - r3, pc}^ + + .align 5 + .globl __down_read_failed +__down_read_failed: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bcc 1f +1: bl down_read_failed_biased + ldmfd sp!, {r0 - r3, pc}^ +2: bl down_read_failed + mov r1, pc + orr r2, r1, # + teqp r2, #0 + + ldr r3, [r0] + subs r3, r3, #1 + str r3, [r0] + ldmplfd sp!, {r0 - r3, pc}^ + orrcs r1, r1, #0x20000000 @ Set carry + teqp r1, #0 + bcc 2b + b 1b + + .align 5 + .globl __down_write_failed +__down_write_failed: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + bcc 1f +1: bl down_write_failed_biased + ldmfd sp!, {r0 - r3, pc}^ +2: bl down_write_failed + mov r1, pc + orr r2, r1, #128 + teqp r2, #0 + + ldr r3, [r0] + subs r3, r3, #"RW_LOCK_BIAS_STR" + str r3, [r0] + ldmeqfd sp!, {r0 - r3, pc}^ + orrcs r1, r1, #0x20000000 @ Set carry + teqp r1, #0 + bcc 2b + b 1b + + .align 5 + .globl __rwsem_wake +__rwsem_wake: + stmfd sp!, {r0 - r3, lr} + mov r0, ip + beq 1f + bl rwsem_wake_readers + ldmfd sp!, {r0 - r3, pc}^ +1: bl rwsem_wake_writer + ldmfd sp!, {r0 - r3, pc}^ + + .previous + "); + +#else +/* 32 bit version */ asm(" .section .text.lock, \"ax\" .align 5 .globl __down_failed @@ -382,3 +478,4 @@ __rwsem_wake: .previous "); +#endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c6010476a..c20ffab21 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -19,7 +19,7 @@ #include <asm/io.h> #include <asm/procinfo.h> #include <asm/setup.h> -#include <asm/system.h> +#include <asm/mach-types.h> #include "arch.h" @@ -40,6 +40,7 @@ extern int root_mountflags; extern int _stext, _text, _etext, _edata, _end; unsigned int processor_id; +unsigned int compat; unsigned int __machine_arch_type; unsigned int system_rev; unsigned int system_serial_low; @@ -161,6 +162,11 @@ static struct machine_desc * __init setup_architecture(unsigned int nr) } printk("Architecture: %s\n", list->name); + if (compat) + printk(KERN_WARNING "Using compatability code " + "scheduled for removal in v%d.%d.%d\n", + compat >> 24, (compat >> 12) & 0x3ff, + compat & 0x3ff); return list; } @@ -305,12 +311,6 @@ void __init setup_arch(char **cmdline_p) memset(&meminfo, 0, sizeof(meminfo)); -#if defined(CONFIG_ARCH_ARC) - __machine_arch_type = MACH_TYPE_ARCHIMEDES; -#elif defined(CONFIG_ARCH_A5K) - __machine_arch_type = MACH_TYPE_A5K; -#endif - setup_processor(); ROOT_DEV = MKDEV(0, 255); diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 4d489bcf3..5c2e240b7 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -35,37 +35,38 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { + int err = -EFAULT;; + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; + goto out; + if (from->si_code < 0) return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + /* First 32bits of unions are always present. */ + err |= __put_user(from->si_pid, &to->si_pid); + switch (from->si_code >> 16) { + case __SI_FAULT >> 16: + break; + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_uid, &to->si_uid); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ } +out: + return err; } /* @@ -175,24 +176,24 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { int err = 0; - err |= __get_user(regs->ARM_r0, &sc->arm_r0); - err |= __get_user(regs->ARM_r1, &sc->arm_r1); - err |= __get_user(regs->ARM_r2, &sc->arm_r2); - err |= __get_user(regs->ARM_r3, &sc->arm_r3); - err |= __get_user(regs->ARM_r4, &sc->arm_r4); - err |= __get_user(regs->ARM_r5, &sc->arm_r5); - err |= __get_user(regs->ARM_r6, &sc->arm_r6); - err |= __get_user(regs->ARM_r7, &sc->arm_r7); - err |= __get_user(regs->ARM_r8, &sc->arm_r8); - err |= __get_user(regs->ARM_r9, &sc->arm_r9); - err |= __get_user(regs->ARM_r10, &sc->arm_r10); - err |= __get_user(regs->ARM_fp, &sc->arm_fp); - err |= __get_user(regs->ARM_ip, &sc->arm_ip); - err |= __get_user(regs->ARM_sp, &sc->arm_sp); - err |= __get_user(regs->ARM_lr, &sc->arm_lr); - err |= __get_user(regs->ARM_pc, &sc->arm_pc); + __get_user_error(regs->ARM_r0, &sc->arm_r0, err); + __get_user_error(regs->ARM_r1, &sc->arm_r1, err); + __get_user_error(regs->ARM_r2, &sc->arm_r2, err); + __get_user_error(regs->ARM_r3, &sc->arm_r3, err); + __get_user_error(regs->ARM_r4, &sc->arm_r4, err); + __get_user_error(regs->ARM_r5, &sc->arm_r5, err); + __get_user_error(regs->ARM_r6, &sc->arm_r6, err); + __get_user_error(regs->ARM_r7, &sc->arm_r7, err); + __get_user_error(regs->ARM_r8, &sc->arm_r8, err); + __get_user_error(regs->ARM_r9, &sc->arm_r9, err); + __get_user_error(regs->ARM_r10, &sc->arm_r10, err); + __get_user_error(regs->ARM_fp, &sc->arm_fp, err); + __get_user_error(regs->ARM_ip, &sc->arm_ip, err); + __get_user_error(regs->ARM_sp, &sc->arm_sp, err); + __get_user_error(regs->ARM_lr, &sc->arm_lr, err); + __get_user_error(regs->ARM_pc, &sc->arm_pc, err); #ifdef CONFIG_CPU_32 - err |= __get_user(regs->ARM_cpsr, &sc->arm_cpsr); + __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); #endif err |= !valid_user_regs(regs); @@ -289,30 +290,30 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/ { int err = 0; - err |= __put_user (regs->ARM_r0, &sc->arm_r0); - err |= __put_user (regs->ARM_r1, &sc->arm_r1); - err |= __put_user (regs->ARM_r2, &sc->arm_r2); - err |= __put_user (regs->ARM_r3, &sc->arm_r3); - err |= __put_user (regs->ARM_r4, &sc->arm_r4); - err |= __put_user (regs->ARM_r5, &sc->arm_r5); - err |= __put_user (regs->ARM_r6, &sc->arm_r6); - err |= __put_user (regs->ARM_r7, &sc->arm_r7); - err |= __put_user (regs->ARM_r8, &sc->arm_r8); - err |= __put_user (regs->ARM_r9, &sc->arm_r9); - err |= __put_user (regs->ARM_r10, &sc->arm_r10); - err |= __put_user (regs->ARM_fp, &sc->arm_fp); - err |= __put_user (regs->ARM_ip, &sc->arm_ip); - err |= __put_user (regs->ARM_sp, &sc->arm_sp); - err |= __put_user (regs->ARM_lr, &sc->arm_lr); - err |= __put_user (regs->ARM_pc, &sc->arm_pc); + __put_user_error(regs->ARM_r0, &sc->arm_r0, err); + __put_user_error(regs->ARM_r1, &sc->arm_r1, err); + __put_user_error(regs->ARM_r2, &sc->arm_r2, err); + __put_user_error(regs->ARM_r3, &sc->arm_r3, err); + __put_user_error(regs->ARM_r4, &sc->arm_r4, err); + __put_user_error(regs->ARM_r5, &sc->arm_r5, err); + __put_user_error(regs->ARM_r6, &sc->arm_r6, err); + __put_user_error(regs->ARM_r7, &sc->arm_r7, err); + __put_user_error(regs->ARM_r8, &sc->arm_r8, err); + __put_user_error(regs->ARM_r9, &sc->arm_r9, err); + __put_user_error(regs->ARM_r10, &sc->arm_r10, err); + __put_user_error(regs->ARM_fp, &sc->arm_fp, err); + __put_user_error(regs->ARM_ip, &sc->arm_ip, err); + __put_user_error(regs->ARM_sp, &sc->arm_sp, err); + __put_user_error(regs->ARM_lr, &sc->arm_lr, err); + __put_user_error(regs->ARM_pc, &sc->arm_pc, err); #ifdef CONFIG_CPU_32 - err |= __put_user (regs->ARM_cpsr, &sc->arm_cpsr); + __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); #endif - err |= __put_user (current->thread.trap_no, &sc->trap_no); - err |= __put_user (current->thread.error_code, &sc->error_code); - err |= __put_user (current->thread.address, &sc->fault_address); - err |= __put_user (mask, &sc->oldmask); + __put_user_error(current->thread.trap_no, &sc->trap_no, err); + __put_user_error(current->thread.error_code, &sc->error_code, err); + __put_user_error(current->thread.address, &sc->fault_address, err); + __put_user_error(mask, &sc->oldmask, err); return err; } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index c76a95736..197107138 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -30,7 +30,7 @@ extern void c_backtrace (unsigned long fp, int pmode); -char *processor_modes[]= +const char *processor_modes[]= { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , @@ -414,7 +414,7 @@ void __bug(const char *file, int line, void *data) if (data) printk(KERN_CRIT" - extra data = %p", data); printk("\n"); - BUG(); + *(int *)0 = 0; } void __readwrite_bug(const char *fn) diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 991b4a3c8..cfa371d5e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -4,6 +4,8 @@ # Copyright (C) 1995-1999 Russell King # +USE_STANDARD_AS_RULE := true + L_TARGET := lib.a L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \ csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \ @@ -36,9 +38,6 @@ L_OBJS += $(L_OBJS_$(MACHINE)) include $(TOPDIR)/Rules.make -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< - constants.h: getconsdata.o extractconstants.pl $(PERL) extractconstants.pl $(OBJDUMP) > $@ diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index e95160e38..f2ea3231d 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S @@ -76,20 +76,20 @@ USER( strt r3, [r0], #4) @ May fault blt .c2u_0rem8lp .c2u_0cpy8lp: ldmia r1!, {r3 - r6} - stmia r0!, {r3 - r6} @ Shouldn't fault + stmia r0!, {r3 - r6} @ Shouldnt fault ldmia r1!, {r3 - r6} - stmia r0!, {r3 - r6} @ Shouldn't fault + stmia r0!, {r3 - r6} @ Shouldnt fault subs ip, ip, #32 bpl .c2u_0cpy8lp .c2u_0rem8lp: cmn ip, #16 ldmgeia r1!, {r3 - r6} - stmgeia r0!, {r3 - r6} @ Shouldn't fault + stmgeia r0!, {r3 - r6} @ Shouldnt fault tst ip, #8 ldmneia r1!, {r3 - r4} - stmneia r0!, {r3 - r4} @ Shouldn't fault + stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 ldrne r3, [r1], #4 - strnet r3, [r0], #4 @ Shouldn't fault + strnet r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .c2u_0fupi .c2u_0nowords: teq ip, #0 @@ -141,7 +141,7 @@ USER( strt r3, [r0], #4) @ May fault orr r5, r5, r6, lsl #24 mov r6, r6, lsr #8 orr r6, r6, r7, lsl #24 - stmia r0!, {r3 - r6} @ Shouldn't fault + stmia r0!, {r3 - r6} @ Shouldnt fault subs ip, ip, #16 bpl .c2u_1cpy8lp .c2u_1rem8lp: tst ip, #8 @@ -150,12 +150,12 @@ USER( strt r3, [r0], #4) @ May fault orrne r3, r3, r4, lsl #24 movne r4, r4, lsr #8 orrne r4, r4, r7, lsl #24 - stmneia r0!, {r3 - r4} @ Shouldn't fault + stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 movne r3, r7, lsr #8 ldrne r7, [r1], #4 orrne r3, r3, r7, lsl #24 - strnet r3, [r0], #4 @ Shouldn't fault + strnet r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .c2u_1fupi .c2u_1nowords: mov r3, r7, lsr #8 @@ -195,7 +195,7 @@ USER( strt r3, [r0], #4) @ May fault orr r5, r5, r6, lsl #16 mov r6, r6, lsr #16 orr r6, r6, r7, lsl #16 - stmia r0!, {r3 - r6} @ Shouldn't fault + stmia r0!, {r3 - r6} @ Shouldnt fault subs ip, ip, #16 bpl .c2u_2cpy8lp .c2u_2rem8lp: tst ip, #8 @@ -204,12 +204,12 @@ USER( strt r3, [r0], #4) @ May fault orrne r3, r3, r4, lsl #16 movne r4, r4, lsr #16 orrne r4, r4, r7, lsl #16 - stmneia r0!, {r3 - r4} @ Shouldn't fault + stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 movne r3, r7, lsr #16 ldrne r7, [r1], #4 orrne r3, r3, r7, lsl #16 - strnet r3, [r0], #4 @ Shouldn't fault + strnet r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .c2u_2fupi .c2u_2nowords: mov r3, r7, lsr #16 @@ -249,7 +249,7 @@ USER( strt r3, [r0], #4) @ May fault orr r5, r5, r6, lsl #8 mov r6, r6, lsr #24 orr r6, r6, r7, lsl #8 - stmia r0!, {r3 - r6} @ Shouldn't fault + stmia r0!, {r3 - r6} @ Shouldnt fault subs ip, ip, #16 bpl .c2u_3cpy8lp .c2u_3rem8lp: tst ip, #8 @@ -258,12 +258,12 @@ USER( strt r3, [r0], #4) @ May fault orrne r3, r3, r4, lsl #8 movne r4, r4, lsr #24 orrne r4, r4, r7, lsl #8 - stmneia r0!, {r3 - r4} @ Shouldn't fault + stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 movne r3, r7, lsr #24 ldrne r7, [r1], #4 orrne r3, r3, r7, lsl #8 - strnet r3, [r0], #4 @ Shouldn't fault + strnet r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .c2u_3fupi .c2u_3nowords: mov r3, r7, lsr #24 @@ -333,20 +333,20 @@ USER( ldrt r3, [r1], #4) subs ip, ip, #32 blt .cfu_0rem8lp -.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldn't fault +.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault stmia r0!, {r3 - r6} - ldmia r1!, {r3 - r6} @ Shouldn't fault + ldmia r1!, {r3 - r6} @ Shouldnt fault stmia r0!, {r3 - r6} subs ip, ip, #32 bpl .cfu_0cpy8lp .cfu_0rem8lp: cmn ip, #16 - ldmgeia r1!, {r3 - r6} @ Shouldn't fault + ldmgeia r1!, {r3 - r6} @ Shouldnt fault stmgeia r0!, {r3 - r6} tst ip, #8 - ldmneia r1!, {r3 - r4} @ Shouldn't fault + ldmneia r1!, {r3 - r4} @ Shouldnt fault stmneia r0!, {r3 - r4} tst ip, #4 - ldrnet r3, [r1], #4 @ Shouldn't fault + ldrnet r3, [r1], #4 @ Shouldnt fault strne r3, [r0], #4 ands ip, ip, #3 beq .cfu_0fupi @@ -392,7 +392,7 @@ USER( ldrt r7, [r1], #4) @ May fault blt .cfu_1rem8lp .cfu_1cpy8lp: mov r3, r7, lsr #8 - ldmia r1!, {r4 - r7} @ Shouldn't fault + ldmia r1!, {r4 - r7} @ Shouldnt fault orr r3, r3, r4, lsl #24 mov r4, r4, lsr #8 orr r4, r4, r5, lsl #24 @@ -405,7 +405,7 @@ USER( ldrt r7, [r1], #4) @ May fault bpl .cfu_1cpy8lp .cfu_1rem8lp: tst ip, #8 movne r3, r7, lsr #8 - ldmneia r1!, {r4, r7} @ Shouldn't fault + ldmneia r1!, {r4, r7} @ Shouldnt fault orrne r3, r3, r4, lsl #24 movne r4, r4, lsr #8 orrne r4, r4, r7, lsl #24 @@ -446,7 +446,7 @@ USER( ldrt r7, [r1], #4) @ May fault blt .cfu_2rem8lp .cfu_2cpy8lp: mov r3, r7, lsr #16 - ldmia r1!, {r4 - r7} @ Shouldn't fault + ldmia r1!, {r4 - r7} @ Shouldnt fault orr r3, r3, r4, lsl #16 mov r4, r4, lsr #16 orr r4, r4, r5, lsl #16 @@ -459,7 +459,7 @@ USER( ldrt r7, [r1], #4) @ May fault bpl .cfu_2cpy8lp .cfu_2rem8lp: tst ip, #8 movne r3, r7, lsr #16 - ldmneia r1!, {r4, r7} @ Shouldn't fault + ldmneia r1!, {r4, r7} @ Shouldnt fault orrne r3, r3, r4, lsl #16 movne r4, r4, lsr #16 orrne r4, r4, r7, lsl #16 @@ -500,7 +500,7 @@ USER( ldrt r7, [r1], #4) @ May fault blt .cfu_3rem8lp .cfu_3cpy8lp: mov r3, r7, lsr #24 - ldmia r1!, {r4 - r7} @ Shouldn't fault + ldmia r1!, {r4 - r7} @ Shouldnt fault orr r3, r3, r4, lsl #8 mov r4, r4, lsr #24 orr r4, r4, r5, lsl #8 @@ -513,7 +513,7 @@ USER( ldrt r7, [r1], #4) @ May fault bpl .cfu_3cpy8lp .cfu_3rem8lp: tst ip, #8 movne r3, r7, lsr #24 - ldmneia r1!, {r4, r7} @ Shouldn't fault + ldmneia r1!, {r4, r7} @ Shouldnt fault orrne r3, r3, r4, lsl #8 movne r4, r4, lsr #24 orrne r4, r4, r7, lsl #8 @@ -597,7 +597,7 @@ USER( strnebt r2, [r0], #1) * or zero on exception, or n + 1 if too long */ ENTRY(__arch_strnlen_user) - stmfd sp!, {lr} + str lr, [sp, #-4]! mov r2, r0 1: USER( ldrbt r3, [r0], #1) @@ -623,7 +623,7 @@ USER( ldrbt r3, [r0], #1) * Returns : number of characters copied */ ENTRY(__arch_strncpy_from_user) - stmfd sp!, {lr} + str lr, [sp, #-4]! add ip, r1, #1 1: subs r2, r2, #1 bmi 2f diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index faedecd2d..075193467 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -7,8 +7,10 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +USE_STANDARD_AS_RULE := true + O_TARGET := mm.o -O_OBJS := consistent.o extable.o fault-$(PROCESSOR).o init.o \ +O_OBJS := extable.o fault-$(PROCESSOR).o init.o \ mm-$(PROCESSOR).o small_page.o ifeq ($(CONFIG_CPU_26),y) @@ -31,14 +33,11 @@ ifeq ($(CONFIG_CPU_32),y) ifeq ($(CONFIG_CPU_SA1100),y) P_OBJS += proc-sa110.o endif - O_OBJS += mm-$(MACHINE).o ioremap.o $(sort $(P_OBJS)) + O_OBJS += mm-$(MACHINE).o consistent.o ioremap.o $(sort $(P_OBJS)) endif include $(TOPDIR)/Rules.make -.S.o: - $(CC) $(AFLAGS) $(AFLAGS_$@) -traditional -c -o $*.o $< - # Special dependencies fault-armv.o: fault-common.c fault-armo.o: fault-common.c diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 72eaa2e47..ba58e8bad 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -18,12 +18,10 @@ #include <linux/smp.h> #include <linux/init.h> #include <linux/bootmem.h> -#ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> -#endif -#include <asm/system.h> #include <asm/segment.h> +#include <asm/mach-types.h> #include <asm/pgalloc.h> #include <asm/dma.h> #include <asm/hardware.h> @@ -151,11 +149,18 @@ void show_mem(void) end = page + NODE_DATA(node)->node_size; do { - if (PageSkip(page)) { - page = page->next_hash; - if (page == NULL) - break; - } +/* This is currently broken + * PG_skip is used on sparc/sparc64 architectures to "skip" certain + * parts of the address space. + * + * #define PG_skip 10 + * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags)) + * if (PageSkip(page)) { + * page = page->next_hash; + * if (page == NULL) + * break; + * } + */ total++; if (PageReserved(page)) reserved++; @@ -554,7 +559,7 @@ void __init mem_init(void) initpages = &__init_end - &__init_begin; high_memory = (void *)__va(meminfo.end); - max_mapnr = MAP_NR(high_memory); + max_mapnr = virt_to_page(high_memory) - mem_map; /* * We may have non-contiguous memory. @@ -598,9 +603,9 @@ void __init mem_init(void) static inline void free_area(unsigned long addr, unsigned long end, char *s) { unsigned int size = (end - addr) >> 10; - struct page *page = virt_to_page(addr); - for (; addr < end; addr += PAGE_SIZE, page ++) { + for (; addr < end; addr += PAGE_SIZE) { + struct page *page = virt_to_page(addr); ClearPageReserved(page); set_page_count(page, 1); free_page(addr); @@ -608,18 +613,14 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) } if (size) - printk(" %dk %s", size, s); + printk("Freeing %s memory: %dK\n", s, size); } void free_initmem(void) { - printk("Freeing unused kernel memory:"); - free_area((unsigned long)(&__init_begin), (unsigned long)(&__init_end), "init"); - - printk("\n"); } #ifdef CONFIG_BLK_DEV_INITRD @@ -628,17 +629,8 @@ static int keep_initrd; void free_initrd_mem(unsigned long start, unsigned long end) { - unsigned long addr; - - if (!keep_initrd) { - for (addr = start; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - set_page_count(virt_to_page(addr), 1); - free_page(addr); - totalram_pages++; - } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); - } + if (!keep_initrd) + free_area(start, end, "initrd"); } static int __init keepinitrd_setup(char *__unused) diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c index b11d55a1b..2c555f46d 100644 --- a/arch/arm/mm/mm-footbridge.c +++ b/arch/arm/mm/mm-footbridge.c @@ -48,6 +48,28 @@ #else /* + * The mapping when the footbridge is in add-in mode. + */ +#define MAPPING \ + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ + { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ + { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ + { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ + { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 } + +#endif + +struct map_desc io_desc[] __initdata = { + MAPPING +}; + +unsigned int __initdata io_desc_size = SIZE(io_desc); + + +#ifdef CONFIG_FOOTBRIDGE_ADDIN + +/* * These two functions convert virtual addresses to PCI addresses * and PCI addresses to virtual addresses. Note that it is only * legal to use these on memory obtained via get_free_page or @@ -78,22 +100,4 @@ unsigned long __bus_to_virt(unsigned long res) return res; } -/* - * The mapping when the footbridge is in add-in mode. - */ -#define MAPPING \ - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 } - #endif - -struct map_desc io_desc[] __initdata = { - MAPPING -}; - -unsigned int __initdata io_desc_size = SIZE(io_desc); - diff --git a/arch/arm/mm/mm-l7200.c b/arch/arm/mm/mm-l7200.c index 14dc5c6e4..8a252d684 100644 --- a/arch/arm/mm/mm-l7200.c +++ b/arch/arm/mm/mm-l7200.c @@ -1,9 +1,9 @@ /* * arch/arm/mm/mm-lusl7200.c * - * Extra MM routines for LUSL7200 architecture + * Extra MM routines for L7200 architecture * - * Copyright (C) 2000 Steven J. Hill + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) */ #include <linux/init.h> diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index c1ecf3fb1..aaf28f880 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -23,6 +23,7 @@ #include <asm/hardware.h> #include <asm/pgtable.h> #include <asm/page.h> +#include <asm/mach-types.h> #include "map.h" @@ -53,6 +54,15 @@ static struct map_desc assabet_io_desc[] __initdata = { #endif }; +static struct map_desc nanoengine_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_NANOENGINE + { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ + { 0xdc000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */ + SA1100_STD_IO_MAPPING +#endif +}; + static struct map_desc bitsy_io_desc[] __initdata = { #ifdef CONFIG_SA1100_BITSY { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ @@ -61,6 +71,14 @@ static struct map_desc bitsy_io_desc[] __initdata = { #endif }; +static struct map_desc cerf_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_CERF + { 0xd8000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */ + { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + SA1100_STD_IO_MAPPING +#endif +}; + static struct map_desc empeg_io_desc[] __initdata = { #ifdef CONFIG_SA1100_EMPEG { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ @@ -77,6 +95,14 @@ static struct map_desc graphicsclient_io_desc[] __initdata = { #endif }; +static struct map_desc lart_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_LART + { 0xd0000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */ + { 0xd8000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */ + SA1100_STD_IO_MAPPING +#endif +}; + static struct map_desc thinclient_io_desc[] __initdata = { #ifdef CONFIG_SA1100_THINCLIENT #if 0 @@ -104,6 +130,14 @@ static struct map_desc victor_io_desc[] __initdata = { #endif }; +static struct map_desc xp860_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_XP860 + { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ + { 0xda000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */ + { 0xdc000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */ + SA1100_STD_IO_MAPPING +#endif +}; static struct map_desc default_io_desc[] __initdata = { SA1100_STD_IO_MAPPING @@ -122,15 +156,24 @@ void __init select_sa1100_io_desc(void) if( machine_is_assabet() ) { memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) ); io_desc_size = SIZE(assabet_io_desc); + } else if( machine_is_nanoengine() ) { + memcpy( io_desc, nanoengine_io_desc, sizeof(nanoengine_io_desc) ); + io_desc_size = SIZE(nanoengine_io_desc); } else if( machine_is_bitsy() ) { memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) ); io_desc_size = SIZE(bitsy_io_desc); + } else if( machine_is_cerf() ) { + memcpy( io_desc, cerf_io_desc, sizeof(cerf_io_desc) ); + io_desc_size = SIZE(cerf_io_desc); } else if( machine_is_empeg() ) { memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) ); io_desc_size = SIZE(empeg_io_desc); } else if( machine_is_graphicsclient() ) { memcpy( io_desc, graphicsclient_io_desc, sizeof(graphicsclient_io_desc) ); io_desc_size = SIZE(graphicsclient_io_desc); + } else if( machine_is_lart() ) { + memcpy( io_desc, lart_io_desc, sizeof(lart_io_desc) ); + io_desc_size = SIZE(lart_io_desc); } else if( machine_is_thinclient() ) { memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) ); io_desc_size = SIZE(thinclient_io_desc); @@ -140,6 +183,9 @@ void __init select_sa1100_io_desc(void) } else if( machine_is_victor() ) { memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) ); io_desc_size = SIZE(victor_io_desc); + } else if( machine_is_xp860() ) { + memcpy( io_desc, xp860_io_desc, sizeof(xp860_io_desc) ); + io_desc_size = SIZE(xp860_io_desc); } else { memcpy( io_desc, default_io_desc, sizeof(default_io_desc) ); io_desc_size = SIZE(default_io_desc); diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index d49196625..262a4fd8b 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -10,11 +10,13 @@ * Changelog: * 05-09-2000 SJH Created by moving 720 specific functions * out of 'proc-arm6,7.S' per RSK discussion + * 07-25-2000 SJH Added idle function. */ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/procinfo.h> #include <asm/errno.h> +#include <asm/hardware.h> #include "../lib/constants.h" /* @@ -127,8 +129,8 @@ ENTRY(cpu_arm720_data_abort) add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine movs pc, lr - b Ldata_unknown - b Ldata_unknown + b Ldata_lateldrhpost @ ldrh rd, [rn], #m/rm + b Ldata_lateldrhpre @ ldrh rd, [rn, #m/rm] b Ldata_unknown b Ldata_unknown b Ldata_lateldrpostconst @ ldr rd, [rn], #m @@ -142,6 +144,7 @@ ENTRY(cpu_arm720_data_abort) b Ldata_simple @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m b Ldata_simple @ ldc rd, [rn, #m] b Ldata_unknown + Ldata_unknown: @ Part of jumptable mov r0, r2 mov r1, r4 @@ -149,6 +152,33 @@ Ldata_unknown: @ Part of jumptable bl baddataabort b ret_from_sys_call +Ldata_lateldrhpre: + tst r4, #1 << 21 @ check writeback bit + beq Ldata_simple +Ldata_lateldrhpost: + tst r4, #1 << 22 @ check if register or immediate offset + beq Ldata_lateldrhpostreg +Ldata_lateldrhpostconst: + and r2, r4, #0xf @ load and clear low nibble of const offset + and r5, r4, #0xf00 @ load and clear high nibble of const offset + orrs r2, r2, r5, lsr #4 @ create offset + beq Ldata_simple @ don't have to do anything if zero + and r5, r4, #0xf << 16 @ get Rn + ldr r0, [sp, r5, lsr #14] + tst r4, #1 << 23 @ U bit + subne r7, r0, r2, lsr #20 + addeq r7, r0, r2, lsr #20 + b Ldata_saver7 +Ldata_lateldrhpostreg: + and r5, r4, #0xf + ldr r2, [sp, r5, lsl #2] @ get Rm + and r5, r4, #0xf << 16 + ldr r0, [sp, r5, lsr #14] @ get Rn + tst r4, #1 << 23 + subne r7, r0, r2 + addeq r7, r0, r2 + b Ldata_saver7 + Ldata_lateldrpreconst: tst r4, #1 << 21 @ check writeback bit beq Ldata_simple @@ -219,7 +249,6 @@ Ldata_lateldrpostreg: * Function: arm720_check_bugs (void) * : arm720_proc_init (void) * : arm720_proc_fin (void) - * : arm720_proc_do_idle (void) * * Notes : This processor does not require these */ @@ -240,8 +269,22 @@ ENTRY(cpu_arm720_proc_fin) mcr p15, 0, r0, c1, c0, 0 @ disable caches mov pc, lr +/* + * Function: arm720_proc_do_idle (void) + * + * Params : r0 = call type: + * 0 = slow idle + * 1 = fast idle + * 2 = switch to slow processor clock + * 3 = switch to fast processor clock + * + * Purpose : put the processer in proper idle mode + */ ENTRY(cpu_arm720_do_idle) - mov r0, #-EINVAL + ldr r2, =IO_BASE @ Virt addr of IO + add r2, r2, #0x00050000 @ Start of PMU regs + mov r1, #0x01 @ Idle mode + str r1, [r2, #4] mov pc, lr /* diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 8c7a6b749..bf75c97a2 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -313,8 +313,8 @@ ENTRY(cpu_sa1100_data_abort) ldr r1, [r0] @ read instruction causing problem mrc p15, 0, r0, c6, c0, 0 @ get FAR mov r1, r1, lsr #19 @ b1 = L - and r1, r1, #2 mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r1, r1, #2 and r3, r3, #255 mov pc, lr diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile index a14371e5d..a7f69d405 100644 --- a/arch/arm/nwfpe/Makefile +++ b/arch/arm/nwfpe/Makefile @@ -4,6 +4,8 @@ # Copyright (C) 1998, 1999 Philip Blundell # +USE_STANDARD_AS_RULE := true + NWFPE_OBJS := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \ fpmodule.o fpopcode.o softfloat.o \ single_cpdo.o double_cpdo.o extended_cpdo.o diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types new file mode 100644 index 000000000..2f9c9b5dd --- /dev/null +++ b/arch/arm/tools/gen-mach-types @@ -0,0 +1,73 @@ +#!/bin/awk +# +# Awk script to generate include/asm-arm/mach-types.h +# +BEGIN { nr = 0 } +/^#/ { next } +/^[ ]*$/ { next } + +NF == 4 { + machine_is[nr] = "machine_is_"$1; + config[nr] = "CONFIG_"$2; + mach_type[nr] = "MACH_TYPE_"$3; + num[nr] = $4; nr++ + } + +NF == 3 { + machine_is[nr] = "machine_is_"$1; + config[nr] = "CONFIG_"$2; + mach_type[nr] = "MACH_TYPE_"$3; + num[nr] = ""; nr++ + } + + +END { + printf("/*\n"); + printf(" * This was automagically generated from %s!\n", FILENAME); + printf(" * Do NOT edit\n"); + printf(" */\n\n"); + printf("#ifndef __ASM_ARM_MACH_TYPE_H\n"); + printf("#define __ASM_ARM_MACH_TYPE_H\n\n"); + printf("#include <linux/config.h>\n\n"); + printf("#ifndef __ASSEMBLY__\n"); + printf("/* The type of machine we're running on */\n"); + printf("extern unsigned int __machine_arch_type;\n"); + printf("#endif\n\n"); + + printf("/* see arch/arm/kernel/arch.c for a description of these */\n"); + for (i = 0; i < nr; i++) + if (num[i] ~ /..*/) + printf("#define %-30s %d\n", mach_type[i], num[i]); + + printf("\n"); + + for (i = 0; i < nr; i++) + if (num[i] ~ /..*/) { + printf("#ifdef %s\n", config[i]); + printf("# ifdef machine_arch_type\n"); + printf("# undef machine_arch_type\n"); + printf("# define machine_arch_type\t__machine_arch_type\n"); + printf("# else\n"); + printf("# define machine_arch_type\t%s\n", mach_type[i]); + printf("# endif\n"); + printf("# define %s()\t(machine_arch_type == %s)\n", machine_is[i], mach_type[i]); + printf("#else\n"); + printf("# define %s()\t(0)\n", machine_is[i]); + printf("#endif\n\n"); + } + + printf("/*\n * These have not yet been registered\n */\n"); + for (i = 0; i < nr; i++) + if (num[i] !~ /..*/) + printf("/* #define %-30s <<not registered>> */\n", mach_type[i]); + + for (i = 0; i < nr; i++) + if (num[i] !~ /..*/) { + printf("#define %s()\t(0)\n", machine_is[i]); + } + + printf("\n#ifndef machine_arch_type\n"); + printf("#define machine_arch_type\t__machine_arch_type\n"); + printf("#endif\n\n"); + printf("#endif\n"); + } diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types new file mode 100644 index 000000000..b922786e3 --- /dev/null +++ b/arch/arm/tools/mach-types @@ -0,0 +1,44 @@ +# Database of machine macros and numbers +# +# To add an entry into this database, please see +# Documentation/arm/README +# +# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number +# +ebsa110 ARCH_EBSA110 EBSA110 0 +riscpc ARCH_RPC RISCPC 1 +nexuspci ARCH_NEXUSPCI NEXUSPCI 3 +ebsa285 ARCH_EBSA285 EBSA285 4 +netwinder ARCH_NETWINDER NETWINDER 5 +cats ARCH_CATS CATS 6 +tbox ARCH_TBOX TBOX 7 +co285 ARCH_CO285 CO285 8 +clps7110 ARCH_CLPS7110 CLPS7110 9 +arc ARCH_ARC ARCHIMEDES 10 +a5k ARCH_A5K A5K 11 +etoile ARCH_ETOILE ETOILE 12 +lacie_nas ARCH_LACIE_NAS LACIE_NAS 13 +clps7500 ARCH_CLPS7500 CLPS7500 14 +shark ARCH_SHARK SHARK 15 +brutus SA1100_BRUTUS BRUTUS 16 +personal_server ARCH_PERSONAL_SERVER PERSONAL_SERVER 17 +itsy SA1100_ITSY ITSY 18 +l7200 ARCH_L7200 L7200 19 +pleb SA1100_PLEB PLEB 20 +integrator ARCH_INTEGRATOR INTEGRATOR 21 +bitsy SA1100_BITSY BITSY 22 +ixp1200 ARCH_IXP1200 IXP1200 23 +thinclient SA1100_THINCLIENT THINCLIENT 24 +assabet SA1100_ASSABET ASSABET 25 +victor SA1100_VICTOR VICTOR 26 +lart SA1100_LART LART 27 +ranger ARCH_RANGER RANGER 28 +graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 +xp860 SA1100_XP860 XP860 30 +cerf SA1100_CERF CERF 31 +nanoengine SA1100_NANOENGINE NANOENGINE 32 + +# The following are unallocated +empeg SA1100_EMPEG EMPEG +tifon SA1100_TIFON TIFON +penny SA1100_PENNY PENNY diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 4087e089b..7735399cb 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -45,6 +45,10 @@ ifdef CONFIG_M586TSC CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) endif +ifdef CONFIG_M586MMX +CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) +endif + ifdef CONFIG_M686 CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) endif diff --git a/arch/i386/config.in b/arch/i386/config.in index d9fcd91db..4f41a46f7 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -30,7 +30,8 @@ choice 'Processor family' \ "386 CONFIG_M386 \ 486 CONFIG_M486 \ 586/K5/5x86/6x86/6x86MX CONFIG_M586 \ - Pentium-Classic/Pentium-MMX CONFIG_M586TSC \ + Pentium-Classic CONFIG_M586TSC \ + Pentium-MMX CONFIG_M586MMX \ Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ Pentium-III CONFIG_M686FXSR \ K6/K6-II/K6-III CONFIG_MK6 \ @@ -68,6 +69,13 @@ if [ "$CONFIG_M586TSC" = "y" ]; then define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y fi +if [ "$CONFIG_M586MMX" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_bool CONFIG_X86_USE_STRING_486 y + define_bool CONFIG_X86_ALIGNMENT_16 y + define_bool CONFIG_X86_TSC y + define_bool CONFIG_X86_GOOD_APIC y +fi if [ "$CONFIG_M686" = "y" ]; then define_int CONFIG_X86_L1_CACHE_BYTES 32 define_bool CONFIG_X86_TSC y @@ -310,11 +318,16 @@ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then fi endmenu +# +# input before char - char/joystick depends on it. As does USB. +# +source drivers/input/Config.in source drivers/char/Config.in - #source drivers/misc/Config.in +source drivers/media/Config.in + source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 38dd1d251..ce51570da 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -25,6 +25,7 @@ CONFIG_KMOD=y # CONFIG_M486 is not set # CONFIG_M586 is not set # CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set CONFIG_M686=y # CONFIG_M686FXSR is not set # CONFIG_MK6 is not set @@ -136,10 +137,8 @@ CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set @@ -332,6 +331,7 @@ CONFIG_NETDEVICES=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -353,6 +353,7 @@ CONFIG_NET_PCI=y # CONFIG_TULIP is not set # CONFIG_DGRS is not set CONFIG_EEPRO100=y +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set @@ -427,6 +428,11 @@ CONFIG_PCMCIA_NETCARD=y # CONFIG_CD_NO_IDESCSI is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Character devices # CONFIG_VT=y @@ -456,6 +462,10 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -465,11 +475,6 @@ CONFIG_PSMOUSE=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -494,6 +499,15 @@ CONFIG_PCMCIA_SERIAL=y # CONFIG_PCMCIA_SERIAL_CB is not set # +# Multimedia devices +# + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index a839790f8..aed275365 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -7,7 +7,8 @@ * Maciej W. Rozycki : Bits for genuine 82489DX APICs; * thanks to Eric Gilmore * and Rolf G. Tews - * for testing these extensively + * for testing these extensively. + * Maciej W. Rozycki : Various updates and fixes. */ #include <linux/config.h> @@ -127,6 +128,67 @@ void disable_local_APIC(void) apic_write_around(APIC_SPIV, value); } +/* + * This is to verify that we're looking at a real local APIC. + * Check these against your board if the CPUs aren't getting + * started for no apparent reason. + */ +int __init verify_local_APIC(void) +{ + unsigned int reg0, reg1; + + /* + * The version register is read-only in a real APIC. + */ + reg0 = apic_read(APIC_LVR); + Dprintk("Getting VERSION: %x\n", reg0); + apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK); + reg1 = apic_read(APIC_LVR); + Dprintk("Getting VERSION: %x\n", reg1); + + /* + * The two version reads above should print the same + * numbers. If the second one is different, then we + * poke at a non-APIC. + */ + if (reg1 != reg0) + return 0; + + /* + * Check if the version looks reasonably. + */ + reg1 = GET_APIC_VERSION(reg0); + if (reg1 == 0x00 || reg1 == 0xff) + return 0; + reg1 = get_maxlvt(); + if (reg1 < 0x02 || reg1 == 0xff) + return 0; + + /* + * The ID register is read/write in a real APIC. + */ + reg0 = apic_read(APIC_ID); + Dprintk("Getting ID: %x\n", reg0); + apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); + reg1 = apic_read(APIC_ID); + Dprintk("Getting ID: %x\n", reg1); + apic_write(APIC_ID, reg0); + if (reg1 != (reg0 ^ APIC_ID_MASK)) + return 0; + + /* + * The next two are just to see if we have sane values. + * They're only really relevant if we're in Virtual Wire + * compatibility mode, but most boxes are anymore. + */ + reg0 = apic_read(APIC_LVT0); + Dprintk("Getting LVT0: %x\n", reg0); + reg1 = apic_read(APIC_LVT1); + Dprintk("Getting LVT1: %x\n", reg1); + + return 1; +} + void __init sync_Arb_IDs(void) { /* @@ -682,46 +744,28 @@ asmlinkage void smp_spurious_interrupt(void) * This interrupt should never happen with our APIC/SMP architecture */ -static spinlock_t err_lock = SPIN_LOCK_UNLOCKED; - asmlinkage void smp_error_interrupt(void) { - unsigned long v; - - spin_lock(&err_lock); + unsigned long v, v1; + /* First tickle the hardware, only then report what went on. -- REW */ v = apic_read(APIC_ESR); - printk(KERN_INFO "APIC error interrupt on CPU#%d, should never happen.\n", - smp_processor_id()); - printk(KERN_INFO "... APIC ESR0: %08lx\n", v); - apic_write(APIC_ESR, 0); - v |= apic_read(APIC_ESR); - printk(KERN_INFO "... APIC ESR1: %08lx\n", v); - /* - * Be a bit more verbose. (multiple bits can be set) - */ - if (v & 0x01) - printk(KERN_INFO "... bit 0: APIC Send CS Error (hw problem).\n"); - if (v & 0x02) - printk(KERN_INFO "... bit 1: APIC Receive CS Error (hw problem).\n"); - if (v & 0x04) - printk(KERN_INFO "... bit 2: APIC Send Accept Error.\n"); - if (v & 0x08) - printk(KERN_INFO "... bit 3: APIC Receive Accept Error.\n"); - if (v & 0x10) - printk(KERN_INFO "... bit 4: Reserved!.\n"); - if (v & 0x20) - printk(KERN_INFO "... bit 5: Send Illegal Vector (kernel bug).\n"); - if (v & 0x40) - printk(KERN_INFO "... bit 6: Received Illegal Vector.\n"); - if (v & 0x80) - printk(KERN_INFO "... bit 7: Illegal Register Address.\n"); - + v1 = apic_read(APIC_ESR); ack_APIC_irq(); - irq_err_count++; - spin_unlock(&err_lock); + /* Here is what the APIC error bits mean: + 0: Send CS error + 1: Receive CS error + 2: Send accept error + 3: Receive accept error + 4: Reserved + 5: Send illegal vector + 6: Received illegal vector + 7: Illegal register address + */ + printk (KERN_ERR "APIC error on CPU%d: %02lx(%02lx)\n", + smp_processor_id(), v , v1); } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 337879b63..fb9b7b2ea 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -641,7 +641,8 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_pivot_root) .long SYMBOL_NAME(sys_mincore) .long SYMBOL_NAME(sys_madvise) - + .long SYMBOL_NAME(sys_getdents64) /* 220 */ + .long SYMBOL_NAME(sys_fcntl64) /* * NOTE!! This doesn't have to be exact - we just have @@ -649,6 +650,6 @@ ENTRY(sys_call_table) * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-219 + .rept NR_syscalls-221 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 525f78624..e1b00a702 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -688,7 +688,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) void __init UNEXPECTED_IO_APIC(void) { printk(KERN_WARNING " WARNING: unexpected IO-APIC, please mail\n"); - printk(KERN_WARNING " to linux-smp@vger.rutgers.edu\n"); + printk(KERN_WARNING " to linux-smp@vger.kernel.org\n"); } void __init print_IO_APIC(void) diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c index 6c6053bf7..e9c8377cd 100644 --- a/arch/i386/kernel/mca.c +++ b/arch/i386/kernel/mca.c @@ -15,7 +15,7 @@ * * Chris Beauregard August 9th, 1996 * - Rewrote /proc/mca - * + * * Chris Beauregard January 7th, 1997 * - Added basic NMI-processing * - Added more information to mca_info structure @@ -30,8 +30,11 @@ * - Fixed the output of 'Driver Installed' in /proc/mca/pos * - Made the Integrated Video & SCSI show up even if they have id 0000 * - * AV November 9th, 1999 - * - switched to regular procfs methods. + * Alexander Viro November 9th, 1999 + * - Switched to regular procfs methods + * + * Alfred Arnold & David Weinehall August 23rd, 2000 + * - Added support for Planar POS-registers */ #include <linux/module.h> @@ -50,9 +53,10 @@ #include <asm/uaccess.h> #include <linux/init.h> -/* This structure holds MCA information. Each (plug-in) adapter has +/* This structure holds MCA information. Each (plug-in) adapter has * eight POS registers. Then the machine may have integrated video and * SCSI subsystems, which also have eight POS registers. + * Finally, the motherboard (planar) has got POS-registers. * Other miscellaneous information follows. */ @@ -92,7 +96,7 @@ struct MCA_info { /* The mca_info structure pointer. If MCA bus is present, the function * mca_probe() is invoked. The function puts motherboard, then all * adapters into setup mode, allocates and fills an MCA_info structure, - * and points this pointer to the structure. Otherwise the pointer + * and points this pointer to the structure. Otherwise the pointer * is set to zero. */ @@ -194,7 +198,7 @@ void __init mca_init(void) */ /* Make sure the MCA bus is present */ - + if(!MCA_bus) return; printk("Micro Channel bus detected.\n"); @@ -216,7 +220,16 @@ void __init mca_init(void) outb_p(0, MCA_ADAPTER_SETUP_REG); - /* Put motherboard into video setup mode, read integrated video + /* Read motherboard POS registers */ + + outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG); + mca_info->slot[MCA_MOTHERBOARD].name[0] = 0; + for(j=0; j<8; j++) { + mca_info->slot[MCA_MOTHERBOARD].pos[j] = inb_p(MCA_POS_REG(j)); + } + mca_configure_adapter_status(MCA_MOTHERBOARD); + + /* Put motherboard into video setup mode, read integrated video * POS registers, and turn motherboard setup off. */ @@ -242,7 +255,7 @@ void __init mca_init(void) outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG); mca_info->slot[MCA_INTEGSCSI].name[0] = 0; for(j=0; j<8; j++) { - if((mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff) + if((mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff) { /* 0xff all across means no device. 0x00 means * something's broken, but a device is probably there. @@ -256,17 +269,17 @@ void __init mca_init(void) mca_info->which_scsi = 0xf7; } } - if(!mca_info->which_scsi) { + if(!mca_info->which_scsi) { /* Didn't find it at 0xf7, try somewhere else... */ mca_info->which_scsi = 0xfd; outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG); - for(j=0; j<8; j++) + for(j=0; j<8; j++) mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j)); } mca_configure_adapter_status(MCA_INTEGSCSI); - + /* Turn off motherboard setup */ outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); @@ -311,6 +324,9 @@ static void mca_handle_nmi_slot(int slot, int check_flag) } else if(slot == MCA_INTEGVIDEO) { printk("NMI: caused by MCA integrated video adapter (%s)\n", mca_info->slot[slot].name); + } else if(slot == MCA_MOTHERBOARD) { + printk("NMI: caused by motherboard (%s)\n", + mca_info->slot[slot].name); } /* More info available in POS 6 and 7? */ @@ -375,7 +391,7 @@ void mca_handle_nmi(void) * * Disabled adapters are not reported. */ - + int mca_find_adapter(int id, int start) { if(mca_info == NULL || id == 0xffff) { @@ -423,7 +439,7 @@ EXPORT_SYMBOL(mca_find_adapter); * to scan for further cards when some may already be driven. */ -int mca_find_unused_adapter(int id, int start) +int mca_find_unused_adapter(int id, int start) { if(mca_info == NULL || id == 0xffff) { return MCA_NOTFOUND; @@ -450,7 +466,7 @@ int mca_find_unused_adapter(int id, int start) } return MCA_NOTFOUND; -} /* mca_find_unused_adapter() */ +} /* mca_find_unused_adapter() */ EXPORT_SYMBOL(mca_find_unused_adapter); @@ -465,8 +481,8 @@ EXPORT_SYMBOL(mca_find_unused_adapter); * when it scanned the MCA space. The register value is returned. * Missing or invalid registers report 0. */ - -unsigned char mca_read_stored_pos(int slot, int reg) + +unsigned char mca_read_stored_pos(int slot, int reg) { if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0; if(reg < 0 || reg >= 8) return 0; @@ -487,9 +503,8 @@ EXPORT_SYMBOL(mca_read_stored_pos); * may not be invoked from interrupt context. It handles the * deep magic required for onboard devices transparently. */ - -unsigned char mca_read_pos(int slot, int reg) +unsigned char mca_read_pos(int slot, int reg) { unsigned int byte = 0; unsigned long flags; @@ -524,6 +539,14 @@ unsigned char mca_read_pos(int slot, int reg) byte = inb_p(MCA_POS_REG(reg)); outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); + } else if(slot == MCA_MOTHERBOARD) { + + /* Disable adapter setup, enable motherboard setup */ + outb_p(0, MCA_ADAPTER_SETUP_REG); + outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG); + + byte = inb_p(MCA_POS_REG(reg)); + outp_b(0xff, MCA_MOTHERBOARD_SETUP_REG); } else if(slot < MCA_MAX_SLOT_NR) { /* Make sure motherboard setup is off */ @@ -556,7 +579,7 @@ EXPORT_SYMBOL(mca_read_pos); * @reg: register to read from * @byte: byte to write to the POS registers * - * Store a POS value directly from the hardware. You should not + * Store a POS value directly from the hardware. You should not * normally need to use this function and should have a very good * knowledge of MCA bus before you do so. Doing this wrongly can * damage the hardware. @@ -574,7 +597,7 @@ EXPORT_SYMBOL(mca_read_pos); * screws up. */ -void mca_write_pos(int slot, int reg, unsigned char byte) +void mca_write_pos(int slot, int reg, unsigned char byte) { unsigned long flags; @@ -615,11 +638,11 @@ EXPORT_SYMBOL(mca_write_pos); * @name: text string for the namen * * This function sets the name reported via /proc for this - * adapter slot. This is for user information only. Setting a + * adapter slot. This is for user information only. Setting a * name deletes any previous name. */ - -void mca_set_adapter_name(int slot, char* name) + +void mca_set_adapter_name(int slot, char* name) { if(mca_info == NULL) return; @@ -640,7 +663,7 @@ EXPORT_SYMBOL(mca_set_adapter_name); /** * mca_set_adapter_procfn - Set the /proc callback * @slot: slot to configure - * @procfn: callback function to call for /proc + * @procfn: callback function to call for /proc * @dev: device information passed to the callback * * This sets up an information callback for /proc/mca/slot?. The @@ -648,7 +671,7 @@ EXPORT_SYMBOL(mca_set_adapter_name); * some equally informative context information, or nothing, if you * prefer), and is expected to put useful information into the * buffer. The adapter name, ID, and POS registers get printed - * before this is called though, so don't do it again. + * before this is called though, so don't do it again. * * This should be called with a %NULL @procfn when a module * unregisters, thus preventing kernel crashes and other such @@ -722,8 +745,8 @@ EXPORT_SYMBOL(mca_mark_as_unused); * Return the adapter description if set. If it has not been * set or the slot is out range then return NULL. */ - -char *mca_get_adapter_name(int slot) + +char *mca_get_adapter_name(int slot) { if(mca_info == NULL) return 0; @@ -789,14 +812,12 @@ int get_mca_info(char *page, char **start, off_t off, { int i, j, len = 0; - if(MCA_bus && mca_info != NULL) - { + if(MCA_bus && mca_info != NULL) { /* Format POS registers of eight MCA slots */ - for(i=0; i<MCA_MAX_SLOT_NR; i++) - { + for(i=0; i<MCA_MAX_SLOT_NR; i++) { len += sprintf(page+len, "Slot %d: ", i+1); - for(j=0; j<8; j++) + for(j=0; j<8; j++) len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]); len += sprintf(page+len, " %s\n", mca_info->slot[i].name); } @@ -804,19 +825,26 @@ int get_mca_info(char *page, char **start, off_t off, /* Format POS registers of integrated video subsystem */ len += sprintf(page+len, "Video : "); - for(j=0; j<8; j++) + for(j=0; j<8; j++) len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]); len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name); /* Format POS registers of integrated SCSI subsystem */ - + len += sprintf(page+len, "SCSI : "); for(j=0; j<8; j++) len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]); len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name); + + /* Format POS registers of motherboard */ + + len += sprintf(page+len, "Planar: "); + for(j=0; j<8; j++) + len += sprintf(page+len, "%02x ", mca_info->slot[MCA_MOTHERBOARD].pos[j]); + len += sprintf(page+len, " %s\n", mca_info->slot[MCA_MOTHERBOARD].name); } else { /* Leave it empty if MCA not detected - this should *never* - * happen! + * happen! */ } @@ -843,6 +871,8 @@ static int mca_default_procfn(char* buf, struct MCA_adapter *p) len += sprintf(buf+len, "Integrated SCSI Adapter\n"); } else if(slot == MCA_INTEGVIDEO) { len += sprintf(buf+len, "Integrated Video Adapter\n"); + } else if(slot == MCA_MOTHERBOARD) { + len += sprintf(buf+len, "Motherboard\n"); } if(p->name[0]) { @@ -932,6 +962,7 @@ void __init mca_do_proc_init(void) if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1); else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video"); else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi"); + else if(i == MCA_MOTHERBOARD) sprintf(p->procname,"planar"); if(!mca_isadapter(i)) continue; diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 64db873a9..1d5b7b3c8 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -67,7 +67,7 @@ static int do_microcode_update(void); static void do_update_one(void *); /* read()/write()/ioctl() are serialized on this */ -DECLARE_RWSEM(microcode_rwsem); +static DECLARE_RWSEM(microcode_rwsem); static struct microcode *microcode; /* array of 2048byte microcode blocks */ static unsigned int microcode_num; /* number of chunks in microcode */ diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 9455d2e3a..746bea030 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -170,7 +170,7 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; } else { printk("Unknown bustype %s\n", str); - panic("cannot handle bus - mail to linux-smp@vger.rutgers.edu"); + panic("cannot handle bus - mail to linux-smp@vger.kernel.org"); } } @@ -565,7 +565,7 @@ void __init find_intel_smp (void) address <<= 4; smp_scan_config(address, 0x1000); if (smp_found_config) - printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n"); + printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n"); } #else diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 24ea5e641..e79572f90 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -16,7 +16,7 @@ * Intel Mobile Pentium II detection fix. Sean Gilley, June 1999. * * IDT Winchip tweaks, misc clean ups. - * Dave Jones <dave@powertweak.com>, August 1999 + * Dave Jones <davej@suse.de>, August 1999 * * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 * @@ -27,7 +27,7 @@ * David Parsons <orc@pell.chi.il.us>, July-August 1999 * * Cleaned up cache-detection code - * Dave Jones <dave@powertweak.com>, October 1999 + * Dave Jones <davej@suse.de>, October 1999 * * Added proper L2 cache detection for Coppermine * Dragan Stancevic <visitor@valinux.com>, October 1999 @@ -38,7 +38,7 @@ * * Detection for Celeron coppermine, identify_cpu() overhauled, * and a few other clean ups. - * Dave Jones <dave@powertweak.com>, April 2000 + * Dave Jones <davej@suse.de>, April 2000 * * Pentium III FXSR, SSE support * General FPU state handling cleanups @@ -48,6 +48,9 @@ * and 8-way type cache happy bunch from Intel:^) * Dragan Stancevic <visitor@valinux.com>, May 2000 * + * Forward port AMD Duron errata T13 from 2.2.17pre + * Dave Jones <davej@suse.de>, August 2000 + * */ /* @@ -380,8 +383,8 @@ static void __init probe_roms(void) } } -void __init add_memory_region(unsigned long start, - unsigned long size, int type) +void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) { int x = e820.nr_map; @@ -398,12 +401,12 @@ void __init add_memory_region(unsigned long start, #define E820_DEBUG 1 -static void __init print_e820_map(void) +static void __init print_memory_map(char *who) { int i; for (i = 0; i < e820.nr_map; i++) { - printk(" e820: %016Lx @ %016Lx ", + printk(" %s: %016Lx @ %016Lx ", who, e820.map[i].size, e820.map[i].addr); switch (e820.map[i].type) { case E820_RAM: printk("(usable)\n"); @@ -449,7 +452,7 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) unsigned long long start = biosmap->addr; unsigned long long size = biosmap->size; unsigned long long end = start + size; - long type = biosmap->type; + unsigned long type = biosmap->type; /* Overflow in 64 bits? Ignore the memory map. */ if (start > end) @@ -460,12 +463,12 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) * Not right. Fix it up. */ if (type == E820_RAM) { - if (start < 0x100000 && end > 0xA0000) { - if (start < 0xA0000) - add_memory_region(start, 0xA0000-start, type); - if (end < 0x100000) + if (start < 0x100000ULL && end > 0xA0000ULL) { + if (start < 0xA0000ULL) + add_memory_region(start, 0xA0000ULL-start, type); + if (end < 0x100000ULL) continue; - start = 0x100000; + start = 0x100000ULL; size = end - start; } } @@ -482,6 +485,8 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) void __init setup_memory_region(void) { + char *who = "BIOS-e820"; + /* * Try to copy the BIOS-supplied E820-map. * @@ -491,14 +496,21 @@ void __init setup_memory_region(void) if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { unsigned long mem_size; - mem_size = (ALT_MEM_K < EXT_MEM_K) ? EXT_MEM_K : ALT_MEM_K; + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } e820.nr_map = 0; add_memory_region(0, LOWMEMSIZE(), E820_RAM); add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } printk("BIOS-provided physical RAM map:\n"); - print_e820_map(); + print_memory_map(who); } /* setup_memory_region */ @@ -568,7 +580,7 @@ static inline void parse_mem_cmdline (char ** cmdline_p) *cmdline_p = command_line; if (usermem) { printk("user-defined physical RAM map:\n"); - print_e820_map(); + print_memory_map("user"); } } @@ -925,7 +937,7 @@ static int __init amd_model(struct cpuinfo_x86 *c) break; } break; - case 6: /* An Athlon. We can trust the BIOS probably */ + case 6: /* An Athlon/Duron. We can trust the BIOS probably */ break; } @@ -936,10 +948,19 @@ static int __init amd_model(struct cpuinfo_x86 *c) edx>>24, ecx>>24, edx&0xFF); c->x86_cache_size=(ecx>>24)+(edx>>24); } - if (n >= 0x80000006) { - cpuid(0x80000006, &dummy, &dummy, &ecx, &edx); - printk("CPU: L2 Cache: %dK\n", ecx>>16); - c->x86_cache_size=(ecx>>16); + + /* AMD errata T13 (order #21922) */ + if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 3 && + boot_cpu_data.x86_mask == 0) + { + c->x86_cache_size = 64; + printk("CPU: L2 Cache: 64K\n"); + } else { + if (n >= 0x80000006) { + cpuid(0x80000006, &dummy, &dummy, &ecx, &edx); + printk("CPU: L2 Cache: %dK\n", ecx>>16); + c->x86_cache_size=(ecx>>16); + } } return r; @@ -1538,7 +1559,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) if(c->x86_vendor == X86_VENDOR_NEXGEN) c->x86_cache_size = 256; /* A few had 1Mb.. */ - + for (i = 0; i < sizeof(cpu_models)/sizeof(struct cpu_model_info); i++) { if (cpu_models[i].vendor == c->x86_vendor && cpu_models[i].x86 == c->x86) { @@ -1570,8 +1591,8 @@ void __init dodgy_tsc(void) cyrix_model(&boot_cpu_data); } - - + + static char *cpu_vendor_names[] __initdata = { "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" }; diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 084e3b963..7629bb3d2 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -883,39 +883,18 @@ void __init smp_boot_cpus(void) phys_cpu_present_map |= (1 << hard_smp_processor_id()); } - { - int reg; - - /* - * This is to verify that we're looking at - * a real local APIC. Check these against - * your board if the CPUs aren't getting - * started for no apparent reason. - */ - - reg = apic_read(APIC_LVR); - Dprintk("Getting VERSION: %x\n", reg); - - apic_write(APIC_LVR, 0); - reg = apic_read(APIC_LVR); - Dprintk("Getting VERSION: %x\n", reg); - - /* - * The two version reads above should print the same - * NON-ZERO!!! numbers. If the second one is zero, - * there is a problem with the APIC write/read - * definitions. - * - * The next two are just to see if we have sane values. - * They're only really relevant if we're in Virtual Wire - * compatibility mode, but most boxes are anymore. - */ - - reg = apic_read(APIC_LVT0); - Dprintk("Getting LVT0: %x\n", reg); - - reg = apic_read(APIC_LVT1); - Dprintk("Getting LVT1: %x\n", reg); + /* + * If we couldn't find a local APIC, then get out of here now! + */ + if (!verify_local_APIC()) { + printk(KERN_ERR "BIOS bug, local APIC at 0x%lX not detected!...\n", mp_lapic_addr); + printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); +#ifndef CONFIG_VISWS + io_apic_irqs = 0; +#endif + cpu_online_map = phys_cpu_present_map = 1; + smp_num_cpus = 1; + goto smp_done; } /* diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 8b8dd761c..0fdf86c19 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -18,15 +18,16 @@ mainmenu_option next_comment comment 'General setup' define_bool CONFIG_IA64 y +define_bool CONFIG_SWIOTLB y # for now... define_bool CONFIG_ISA n define_bool CONFIG_SBUS n choice 'IA-64 system type' \ - "Generic CONFIG_IA64_GENERIC \ + "generic CONFIG_IA64_GENERIC \ + DIG-compliant CONFIG_IA64_DIG \ HP-simulator CONFIG_IA64_HP_SIM \ - SN1-simulator CONFIG_IA64_SGI_SN1_SIM \ - DIG-compliant CONFIG_IA64_DIG" Generic + SN1-simulator CONFIG_IA64_SGI_SN1_SIM" generic choice 'Kernel page size' \ "4KB CONFIG_IA64_PAGE_SIZE_4KB \ @@ -38,16 +39,18 @@ if [ "$CONFIG_IA64_DIG" = "y" ]; then define_bool CONFIG_ITANIUM y define_bool CONFIG_IA64_BRL_EMU y bool ' Enable Itanium A-step specific code' CONFIG_ITANIUM_ASTEP_SPECIFIC - bool ' Enable Itanium A1-step specific code' CONFIG_ITANIUM_A1_SPECIFIC + if [ "$CONFIG_ITANIUM_ASTEP_SPECIFIC" = "y" ]; then + bool ' Enable Itanium A1-step specific code' CONFIG_ITANIUM_A1_SPECIFIC + fi + bool ' Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC + if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then + bool ' Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC + fi + bool ' Force interrupt redirection' CONFIG_IA64_HAVE_IRQREDIR bool ' Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG bool ' Enable SoftSDV hacks' CONFIG_IA64_SOFTSDV_HACKS bool ' Enable AzusA hacks' CONFIG_IA64_AZUSA_HACKS - bool ' Emulate PAL/SAL/EFI firmware' CONFIG_IA64_FW_EMU - bool ' Enable IA64 Machine Check Abort' CONFIG_IA64_MCA -fi - -if [ "$CONFIG_IA64_GENERIC" = "y" ]; then - define_bool CONFIG_IA64_SOFTSDV_HACKS y + bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA fi if [ "$CONFIG_IA64_SGI_SN1_SIM" = "y" ]; then @@ -59,7 +62,7 @@ define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. bool 'SMP support' CONFIG_SMP bool 'Performance monitor support' CONFIG_PERFMON -bool '/proc/palinfo support' CONFIG_IA64_PALINFO +bool '/proc/pal support' CONFIG_IA64_PALINFO bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC @@ -161,9 +164,9 @@ source drivers/char/Config.in #source drivers/misc/Config.in -source fs/Config.in +source drivers/media/Config.in -source fs/nls/Config.in +source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then mainmenu_option next_comment @@ -188,6 +191,7 @@ fi endmenu source drivers/usb/Config.in +source drivers/input/Config.in fi # !HP_SIM diff --git a/arch/ia64/dig/iosapic.c b/arch/ia64/dig/iosapic.c index 2426a0193..7d9a084fd 100644 --- a/arch/ia64/dig/iosapic.c +++ b/arch/ia64/dig/iosapic.c @@ -22,12 +22,14 @@ #include <linux/string.h> #include <linux/irq.h> +#include <asm/acpi-ext.h> +#include <asm/delay.h> #include <asm/io.h> #include <asm/iosapic.h> +#include <asm/machvec.h> +#include <asm/processor.h> #include <asm/ptrace.h> #include <asm/system.h> -#include <asm/delay.h> -#include <asm/processor.h> #undef DEBUG_IRQ_ROUTING @@ -315,10 +317,6 @@ dig_irq_init (void) */ outb(0xff, 0xA1); outb(0xff, 0x21); - -#ifndef CONFIG_IA64_DIG - iosapic_init(IO_SAPIC_DEFAULT_ADDR); -#endif } void @@ -337,15 +335,23 @@ dig_pci_fixup (void) if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ struct pci_dev * bridge = dev->bus->self; - /* do the bridge swizzle... */ - pin = (pin + PCI_SLOT(dev->devfn)) % 4; - irq = iosapic_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); + /* allow for multiple bridges on an adapter */ + do { + /* do the bridge swizzle... */ + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + irq = iosapic_get_PCI_irq_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); + } while (irq < 0 && (bridge = bridge->bus->self)); if (irq >= 0) printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %02x\n", bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); + else + printk(KERN_WARNING + "PCI: Couldn't map irq for B%d,I%d,P%d\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), + pin); } if (irq >= 0) { printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %02x\n", @@ -361,3 +367,34 @@ dig_pci_fixup (void) dev->irq = 15; /* Spurious interrupts */ } } + +/* + * Register an IOSAPIC discovered via ACPI. + */ +void __init +dig_register_iosapic (acpi_entry_iosapic_t *iosapic) +{ + unsigned int ver, v; + int l, max_pin; + + ver = iosapic_version(iosapic->address); + max_pin = (ver >> 16) & 0xff; + + printk("IOSAPIC Version %x.%x: address 0x%lx IRQs 0x%x - 0x%x\n", + (ver & 0xf0) >> 4, (ver & 0x0f), iosapic->address, + iosapic->irq_base, iosapic->irq_base + max_pin); + + for (l = 0; l <= max_pin; l++) { + v = iosapic->irq_base + l; + if (v < 16) + v = isa_irq_to_vector(v); + if (v > IA64_MAX_VECTORED_IRQ) { + printk(" !!! bad IOSAPIC interrupt vector: %u\n", v); + continue; + } + /* XXX Check for IOSAPIC collisions */ + iosapic_addr(v) = (unsigned long) ioremap(iosapic->address, 0); + iosapic_baseirq(v) = iosapic->irq_base; + } + iosapic_init(iosapic->address, iosapic->irq_base); +} diff --git a/arch/ia64/dig/machvec.c b/arch/ia64/dig/machvec.c index 640412d7e..4d2452745 100644 --- a/arch/ia64/dig/machvec.c +++ b/arch/ia64/dig/machvec.c @@ -1,4 +1,2 @@ +#define MACHVEC_PLATFORM_NAME dig #include <asm/machvec_init.h> -#include <asm/machvec_dig.h> - -MACHVEC_DEFINE(dig) diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c index 45c1f96f5..fa48254cc 100644 --- a/arch/ia64/dig/setup.c +++ b/arch/ia64/dig/setup.c @@ -24,10 +24,6 @@ #include <asm/machvec.h> #include <asm/system.h> -#ifdef CONFIG_IA64_FW_EMU -# include "../../kernel/fw-emu.c" -#endif - /* * This is here so we can use the CMOS detection in ide-probe.c to * determine what drives are present. In theory, we don't need this diff --git a/arch/ia64/hp/hpsim_machvec.c b/arch/ia64/hp/hpsim_machvec.c index 7d78f4961..76af3b4e2 100644 --- a/arch/ia64/hp/hpsim_machvec.c +++ b/arch/ia64/hp/hpsim_machvec.c @@ -1,4 +1,2 @@ +#define MACHVEC_PLATFORM_NAME hpsim #include <asm/machvec_init.h> -#include <asm/machvec_hpsim.h> - -MACHVEC_DEFINE(hpsim) diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index a9dc378cf..ad963b92f 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -73,7 +73,7 @@ GLOBAL_ENTRY(ia32_trace_syscall) END(ia32_trace_syscall) GLOBAL_ENTRY(sys32_vfork) - alloc r16=ar.pfs,2,2,3,0;; + alloc r16=ar.pfs,2,2,4,0;; mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags br.cond.sptk.few .fork1 // do the work END(sys32_vfork) @@ -105,7 +105,7 @@ END(sys32_fork) .align 8 .globl ia32_syscall_table ia32_syscall_table: - data8 sys_ni_syscall /* 0 - old "setup(" system call*/ + data8 sys32_ni_syscall /* 0 - old "setup(" system call*/ data8 sys_exit data8 sys32_fork data8 sys_read @@ -122,25 +122,25 @@ ia32_syscall_table: data8 sys_mknod data8 sys_chmod /* 15 */ data8 sys_lchown - data8 sys_ni_syscall /* old break syscall holder */ - data8 sys_ni_syscall + data8 sys32_ni_syscall /* old break syscall holder */ + data8 sys32_ni_syscall data8 sys_lseek data8 sys_getpid /* 20 */ data8 sys_mount data8 sys_oldumount data8 sys_setuid data8 sys_getuid - data8 sys_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */ + data8 sys32_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */ data8 sys32_ptrace data8 sys32_alarm - data8 sys_ni_syscall - data8 sys_ni_syscall + data8 sys32_ni_syscall + data8 sys32_ni_syscall data8 ia32_utime /* 30 */ - data8 sys_ni_syscall /* old stty syscall holder */ - data8 sys_ni_syscall /* old gtty syscall holder */ + data8 sys32_ni_syscall /* old stty syscall holder */ + data8 sys32_ni_syscall /* old gtty syscall holder */ data8 sys_access data8 sys_nice - data8 sys_ni_syscall /* 35 */ /* old ftime syscall holder */ + data8 sys32_ni_syscall /* 35 */ /* old ftime syscall holder */ data8 sys_sync data8 sys_kill data8 sys_rename @@ -149,22 +149,22 @@ ia32_syscall_table: data8 sys_dup data8 sys32_pipe data8 sys32_times - data8 sys_ni_syscall /* old prof syscall holder */ + data8 sys32_ni_syscall /* old prof syscall holder */ data8 sys_brk /* 45 */ data8 sys_setgid data8 sys_getgid - data8 sys_ni_syscall + data8 sys32_ni_syscall data8 sys_geteuid data8 sys_getegid /* 50 */ data8 sys_acct data8 sys_umount /* recycled never used phys( */ - data8 sys_ni_syscall /* old lock syscall holder */ + data8 sys32_ni_syscall /* old lock syscall holder */ data8 ia32_ioctl - data8 sys_fcntl /* 55 */ - data8 sys_ni_syscall /* old mpx syscall holder */ + data8 sys32_fcntl /* 55 */ + data8 sys32_ni_syscall /* old mpx syscall holder */ data8 sys_setpgid - data8 sys_ni_syscall /* old ulimit syscall holder */ - data8 sys_ni_syscall + data8 sys32_ni_syscall /* old ulimit syscall holder */ + data8 sys32_ni_syscall data8 sys_umask /* 60 */ data8 sys_chroot data8 sys_ustat @@ -172,12 +172,12 @@ ia32_syscall_table: data8 sys_getppid data8 sys_getpgrp /* 65 */ data8 sys_setsid - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall + data8 sys32_sigaction + data8 sys32_ni_syscall + data8 sys32_ni_syscall data8 sys_setreuid /* 70 */ data8 sys_setregid - data8 sys_ni_syscall + data8 sys32_ni_syscall data8 sys_sigpending data8 sys_sethostname data8 sys32_setrlimit /* 75 */ @@ -189,7 +189,7 @@ ia32_syscall_table: data8 sys_setgroups data8 old_select data8 sys_symlink - data8 sys_ni_syscall + data8 sys32_ni_syscall data8 sys_readlink /* 85 */ data8 sys_uselib data8 sys_swapon @@ -203,7 +203,7 @@ ia32_syscall_table: data8 sys_fchown /* 95 */ data8 sys_getpriority data8 sys_setpriority - data8 sys_ni_syscall /* old profil syscall holder */ + data8 sys32_ni_syscall /* old profil syscall holder */ data8 sys32_statfs data8 sys32_fstatfs /* 100 */ data8 sys_ioperm @@ -214,11 +214,11 @@ ia32_syscall_table: data8 sys32_newstat data8 sys32_newlstat data8 sys32_newfstat - data8 sys_ni_syscall + data8 sys32_ni_syscall data8 sys_iopl /* 110 */ data8 sys_vhangup - data8 sys_ni_syscall // used to be sys_idle - data8 sys_ni_syscall + data8 sys32_ni_syscall // used to be sys_idle + data8 sys32_ni_syscall data8 sys32_wait4 data8 sys_swapoff /* 115 */ data8 sys_sysinfo @@ -242,7 +242,7 @@ ia32_syscall_table: data8 sys_bdflush data8 sys_sysfs /* 135 */ data8 sys_personality - data8 sys_ni_syscall /* for afs_syscall */ + data8 sys32_ni_syscall /* for afs_syscall */ data8 sys_setfsuid data8 sys_setfsgid data8 sys_llseek /* 140 */ @@ -293,8 +293,8 @@ ia32_syscall_table: data8 sys_capset /* 185 */ data8 sys_sigaltstack data8 sys_sendfile - data8 sys_ni_syscall /* streams1 */ - data8 sys_ni_syscall /* streams2 */ + data8 sys32_ni_syscall /* streams1 */ + data8 sys32_ni_syscall /* streams2 */ data8 sys32_vfork /* 190 */ /* * CAUTION: If any system calls are added beyond this point diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index cbec84f2b..a6bf4a8d8 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -74,10 +74,14 @@ nargs(unsigned int arg, char **ap) n = 0; do { - if ((err = get_user(addr, (int *)A(arg))) != 0) - return(err); - if (ap) - *ap++ = (char *)A(addr); + err = get_user(addr, (int *)A(arg)); + if (IS_ERR(err)) + return err; + if (ap) { /* no access_ok needed, we allocated */ + err = __put_user((char *)A(addr), ap++); + if (IS_ERR(err)) + return err; + } arg += sizeof(unsigned int); n++; } while (addr); @@ -101,7 +105,11 @@ int stack) int na, ne, r, len; na = nargs(argv, NULL); + if (IS_ERR(na)) + return(na); ne = nargs(envp, NULL); + if (IS_ERR(ne)) + return(ne); len = (na + ne + 2) * sizeof(*av); /* * kmalloc won't work because the `sys_exec' code will attempt @@ -121,12 +129,21 @@ int stack) if (IS_ERR(av)) return (long)av; ae = av + na + 1; - av[na] = (char *)0; - ae[ne] = (char *)0; - (void)nargs(argv, av); - (void)nargs(envp, ae); + r = __put_user(0, (av + na)); + if (IS_ERR(r)) + goto out; + r = __put_user(0, (ae + ne)); + if (IS_ERR(r)) + goto out; + r = nargs(argv, av); + if (IS_ERR(r)) + goto out; + r = nargs(envp, ae); + if (IS_ERR(r)) + goto out; r = sys_execve(filename, av, ae, regs); if (IS_ERR(r)) +out: sys_munmap((unsigned long) av, len); return(r); } @@ -711,7 +728,8 @@ struct readdir32_callback { }; static int -filldir32 (void *__buf, const char *name, int namlen, off_t offset, ino_t ino) +filldir32 (void *__buf, const char *name, int namlen, off_t offset, ino_t ino, + unsigned int d_type) { struct linux32_dirent * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; @@ -959,150 +977,85 @@ sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp) } struct iovec32 { unsigned int iov_base; int iov_len; }; +asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long); +asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long); -typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *); - -static long -do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, - u32 count) +static struct iovec * +get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type) { - unsigned long tot_len; - struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov=iovstack, *ivp; - struct inode *inode; - long retval, i; - IO_fn_t fn; + int i; + u32 buf, len; + struct iovec *ivp, *iov; + + /* Get the "struct iovec" from user memory */ - /* First get the "struct iovec" from user memory and - * verify all the pointers - */ if (!count) return 0; - if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count)) - return -EFAULT; + if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count)) + return(struct iovec *)0; if (count > UIO_MAXIOV) - return -EINVAL; + return(struct iovec *)0; if (count > UIO_FASTIOV) { iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL); if (!iov) - return -ENOMEM; - } + return((struct iovec *)0); + } else + iov = iov_buf; - tot_len = 0; - i = count; ivp = iov; - while(i > 0) { - u32 len; - u32 buf; - - __get_user(len, &vector->iov_len); - __get_user(buf, &vector->iov_base); - tot_len += len; + for (i = 0; i < count; i++) { + if (__get_user(len, &iov32->iov_len) || + __get_user(buf, &iov32->iov_base)) { + if (iov != iov_buf) + kfree(iov); + return((struct iovec *)0); + } + if (verify_area(type, (void *)A(buf), len)) { + if (iov != iov_buf) + kfree(iov); + return((struct iovec *)0); + } ivp->iov_base = (void *)A(buf); - ivp->iov_len = (__kernel_size_t) len; - vector++; - ivp++; - i--; - } - - inode = file->f_dentry->d_inode; - /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); - if (retval) { - if (iov != iovstack) - kfree(iov); - return retval; - } - - /* Then do the actual IO. Note that sockets need to be handled - * specially as they have atomicity guarantees and can handle - * iovec's natively - */ - if (inode->i_sock) { - int err; - err = sock_readv_writev(type, inode, file, iov, count, tot_len); - if (iov != iovstack) - kfree(iov); - return err; - } - - if (!file->f_op) { - if (iov != iovstack) - kfree(iov); - return -EINVAL; - } - /* VERIFY_WRITE actually means a read, as we write to user space */ - fn = file->f_op->read; - if (type == VERIFY_READ) - fn = (IO_fn_t) file->f_op->write; - ivp = iov; - while (count > 0) { - void * base; - int len, nr; - - base = ivp->iov_base; - len = ivp->iov_len; + ivp->iov_len = (__kernel_size_t)len; + iov32++; ivp++; - count--; - nr = fn(file, base, len, &file->f_pos); - if (nr < 0) { - if (retval) - break; - retval = nr; - break; - } - retval += nr; - if (nr != len) - break; } - if (iov != iovstack) - kfree(iov); - return retval; + return(iov); } asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count) { - struct file *file; - long ret = -EBADF; - - file = fget(fd); - if(!file) - goto bad_file; - - if(!(file->f_mode & 1)) - goto out; + struct iovec iovstack[UIO_FASTIOV]; + struct iovec *iov; + int ret; + mm_segment_t old_fs = get_fs(); - ret = do_readv_writev32(VERIFY_WRITE, file, - vector, count); -out: - fput(file); -bad_file: + if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0) + return -EFAULT; + set_fs(KERNEL_DS); + ret = sys_readv(fd, iov, count); + set_fs(old_fs); + if (iov != iovstack) + kfree(iov); return ret; } asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count) { - struct file *file; - int ret = -EBADF; - - file = fget(fd); - if(!file) - goto bad_file; - - if(!(file->f_mode & 2)) - goto out; + struct iovec iovstack[UIO_FASTIOV]; + struct iovec *iov; + int ret; + mm_segment_t old_fs = get_fs(); - down(&file->f_dentry->d_inode->i_sem); - ret = do_readv_writev32(VERIFY_READ, file, - vector, count); - up(&file->f_dentry->d_inode->i_sem); -out: - fput(file); -bad_file: + if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0) + return -EFAULT; + set_fs(KERNEL_DS); + ret = sys_writev(fd, iov, count); + set_fs(old_fs); + if (iov != iovstack) + kfree(iov); return ret; } @@ -1173,21 +1126,22 @@ struct msghdr32 { static inline int shape_msg(struct msghdr *mp, struct msghdr32 *mp32) { + int ret; unsigned int i; if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32))) return(-EFAULT); - __get_user(i, &mp32->msg_name); + ret = __get_user(i, &mp32->msg_name); mp->msg_name = (void *)A(i); - __get_user(mp->msg_namelen, &mp32->msg_namelen); - __get_user(i, &mp32->msg_iov); + ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen); + ret |= __get_user(i, &mp32->msg_iov); mp->msg_iov = (struct iovec *)A(i); - __get_user(mp->msg_iovlen, &mp32->msg_iovlen); - __get_user(i, &mp32->msg_control); + ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen); + ret |= __get_user(i, &mp32->msg_control); mp->msg_control = (void *)A(i); - __get_user(mp->msg_controllen, &mp32->msg_controllen); - __get_user(mp->msg_flags, &mp32->msg_flags); - return(0); + ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen); + ret |= __get_user(mp->msg_flags, &mp32->msg_flags); + return(ret ? -EFAULT : 0); } /* @@ -2341,17 +2295,17 @@ restore_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save) { struct switch_stack *swp; struct pt_regs *ptp; - int i, tos; + int i, tos, ret; int fsrlo, fsrhi; if (!access_ok(VERIFY_READ, save, sizeof(*save))) return(-EIO); - __get_user(tsk->thread.fcr, (unsigned int *)&save->cw); - __get_user(fsrlo, (unsigned int *)&save->sw); - __get_user(fsrhi, (unsigned int *)&save->tag); + ret = __get_user(tsk->thread.fcr, (unsigned int *)&save->cw); + ret |= __get_user(fsrlo, (unsigned int *)&save->sw); + ret |= __get_user(fsrhi, (unsigned int *)&save->tag); tsk->thread.fsr = ((long)fsrhi << 32) | (long)fsrlo; - __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff); - __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff); + ret |= __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff); + ret |= __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff); /* * Stack frames start with 16-bytes of temp space */ @@ -2360,7 +2314,7 @@ restore_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save) tos = (tsk->thread.fsr >> 11) & 3; for (i = 0; i < 8; i++) get_fpreg(i, &save->_st[i], ptp, swp, tos); - return(0); + return(ret ? -EFAULT : 0); } asmlinkage long sys_ptrace(long, pid_t, unsigned long, unsigned long, long, long, long, long, long); @@ -2492,6 +2446,105 @@ sys32_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data, return ret; } +static inline int +get_flock32(struct flock *kfl, struct flock32 *ufl) +{ + int err; + + err = get_user(kfl->l_type, &ufl->l_type); + err |= __get_user(kfl->l_whence, &ufl->l_whence); + err |= __get_user(kfl->l_start, &ufl->l_start); + err |= __get_user(kfl->l_len, &ufl->l_len); + err |= __get_user(kfl->l_pid, &ufl->l_pid); + return err; +} + +static inline int +put_flock32(struct flock *kfl, struct flock32 *ufl) +{ + int err; + + err = __put_user(kfl->l_type, &ufl->l_type); + err |= __put_user(kfl->l_whence, &ufl->l_whence); + err |= __put_user(kfl->l_start, &ufl->l_start); + err |= __put_user(kfl->l_len, &ufl->l_len); + err |= __put_user(kfl->l_pid, &ufl->l_pid); + return err; +} + +extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, + unsigned long arg); + +asmlinkage long +sys32_fcntl(unsigned int fd, unsigned int cmd, int arg) +{ + struct flock f; + mm_segment_t old_fs; + long ret; + + switch (cmd) { + case F_GETLK: + case F_SETLK: + case F_SETLKW: + if(cmd != F_GETLK && get_flock32(&f, (struct flock32 *)((long)arg))) + return -EFAULT; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_fcntl(fd, cmd, (unsigned long)&f); + set_fs(old_fs); + if(cmd == F_GETLK && put_flock32(&f, (struct flock32 *)((long)arg))) + return -EFAULT; + return ret; + default: + /* + * `sys_fcntl' lies about arg, for the F_SETOWN + * sub-function arg can have a negative value. + */ + return sys_fcntl(fd, cmd, (unsigned long)((long)arg)); + } +} + +asmlinkage long +sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset32_t mask; + + ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); + ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); + ret |= __get_user(mask, &act->sa_mask); + if (ret) + return ret; + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); + ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +asmlinkage long sys_ni_syscall(void); + +asmlinkage long +sys32_ni_syscall(int dummy0, int dummy1, int dummy2, int dummy3, + int dummy4, int dummy5, int dummy6, int dummy7, int stack) +{ + struct pt_regs *regs = (struct pt_regs *)&stack; + + printk("IA32 syscall #%d issued, maybe we should implement it\n", + (int)regs->r1); + return(sys_ni_syscall()); +} + #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ /* In order to reduce some races, while at the same time doing additional @@ -2545,61 +2598,6 @@ sys32_ioperm(u32 from, u32 num, int on) return sys_ioperm((unsigned long)from, (unsigned long)num, on); } -static inline int -get_flock(struct flock *kfl, struct flock32 *ufl) -{ - int err; - - err = get_user(kfl->l_type, &ufl->l_type); - err |= __get_user(kfl->l_whence, &ufl->l_whence); - err |= __get_user(kfl->l_start, &ufl->l_start); - err |= __get_user(kfl->l_len, &ufl->l_len); - err |= __get_user(kfl->l_pid, &ufl->l_pid); - return err; -} - -static inline int -put_flock(struct flock *kfl, struct flock32 *ufl) -{ - int err; - - err = __put_user(kfl->l_type, &ufl->l_type); - err |= __put_user(kfl->l_whence, &ufl->l_whence); - err |= __put_user(kfl->l_start, &ufl->l_start); - err |= __put_user(kfl->l_len, &ufl->l_len); - err |= __put_user(kfl->l_pid, &ufl->l_pid); - return err; -} - -extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, - unsigned long arg); - -asmlinkage long -sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case F_GETLK: - case F_SETLK: - case F_SETLKW: - { - struct flock f; - mm_segment_t old_fs; - long ret; - - if(get_flock(&f, (struct flock32 *)arg)) - return -EFAULT; - old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_fcntl(fd, cmd, (unsigned long)&f); - set_fs (old_fs); - if(put_flock(&f, (struct flock32 *)arg)) - return -EFAULT; - return ret; - } - default: - return sys_fcntl(fd, cmd, (unsigned long)arg); - } -} - struct dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; @@ -3862,40 +3860,6 @@ out: extern void check_pending(int signum); -asmlinkage long -sys32_sigaction (int sig, struct old_sigaction32 *act, - struct old_sigaction32 *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if(sig < 0) { - current->tss.new_signal = 1; - sig = -sig; - } - - if (act) { - old_sigset_t32 mask; - - ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); - ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - ret |= __get_user(mask, &act->sa_mask); - if (ret) - return ret; - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); - ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} - #ifdef CONFIG_MODULES extern asmlinkage unsigned long sys_create_module(const char *name_user, diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index dfba2529a..563c308ea 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -9,8 +9,8 @@ all: kernel.o head.o init_task.o -obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \ - pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \ +obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \ + machvec.o pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o obj-$(CONFIG_IA64_GENERIC) += machvec.o diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 20521da36..4bba56e1d 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -19,10 +19,11 @@ #include <linux/irq.h> #include <asm/acpi-ext.h> -#include <asm/page.h> #include <asm/efi.h> #include <asm/io.h> #include <asm/iosapic.h> +#include <asm/machvec.h> +#include <asm/page.h> #undef ACPI_DEBUG /* Guess what this does? */ @@ -75,47 +76,6 @@ acpi_lsapic(char *p) } /* - * Find all IOSAPICs and tag the iosapic_vector structure with the appropriate - * base addresses. - */ -static void __init -acpi_iosapic(char *p) -{ - /* - * This is not good. ACPI is not necessarily limited to CONFIG_IA64_SV, yet - * ACPI does not necessarily imply IOSAPIC either. Perhaps there should be - * a means for platform_setup() to register ACPI handlers? - */ -#ifdef CONFIG_IA64_DIG - acpi_entry_iosapic_t *iosapic = (acpi_entry_iosapic_t *) p; - unsigned int ver, v; - int l, max_pin; - - ver = iosapic_version(iosapic->address); - max_pin = (ver >> 16) & 0xff; - - printk("IOSAPIC Version %x.%x: address 0x%lx IRQs 0x%x - 0x%x\n", - (ver & 0xf0) >> 4, (ver & 0x0f), iosapic->address, - iosapic->irq_base, iosapic->irq_base + max_pin); - - for (l = 0; l <= max_pin; l++) { - v = iosapic->irq_base + l; - if (v < 16) - v = isa_irq_to_vector(v); - if (v > IA64_MAX_VECTORED_IRQ) { - printk(" !!! bad IOSAPIC interrupt vector: %u\n", v); - continue; - } - /* XXX Check for IOSAPIC collisions */ - iosapic_addr(v) = (unsigned long) ioremap(iosapic->address, 0); - iosapic_baseirq(v) = iosapic->irq_base; - } - iosapic_init(iosapic->address, iosapic->irq_base); -#endif -} - - -/* * Configure legacy IRQ information in iosapic_vector */ static void __init @@ -227,7 +187,7 @@ acpi_parse_msapic(acpi_sapic_t *msapic) break; case ACPI_ENTRY_IO_SAPIC: - acpi_iosapic(p); + platform_register_iosapic((acpi_entry_iosapic_t *) p); break; case ACPI_ENTRY_INT_SRC_OVERRIDE: diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index c4383b97f..d55835df6 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -33,9 +33,10 @@ extern efi_status_t efi_call_phys (void *, ...); struct efi efi; - static efi_runtime_services_t *runtime; +static unsigned long mem_limit = ~0UL; + static efi_status_t phys_get_time (efi_time_t *tm, efi_time_cap_t *tc) { @@ -169,15 +170,13 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) case EFI_BOOT_SERVICES_CODE: case EFI_BOOT_SERVICES_DATA: case EFI_CONVENTIONAL_MEMORY: - if (md->phys_addr > 1024*1024*1024UL) { - printk("Warning: ignoring %luMB of memory above 1GB!\n", - md->num_pages >> 8); - md->type = EFI_UNUSABLE_MEMORY; - continue; - } - if (!(md->attribute & EFI_MEMORY_WB)) continue; + if (md->phys_addr + (md->num_pages << 12) > mem_limit) { + if (md->phys_addr > mem_limit) + continue; + md->num_pages = (mem_limit - md->phys_addr) >> 12; + } if (md->num_pages == 0) { printk("efi_memmap_walk: ignoring empty region at 0x%lx", md->phys_addr); @@ -224,8 +223,8 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor * Abstraction Layer chapter 11 in ADAG */ -static void -map_pal_code (void) +void +efi_map_pal_code (void) { void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; @@ -240,13 +239,14 @@ map_pal_code (void) for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if (md->type != EFI_PAL_CODE) continue; + if (md->type != EFI_PAL_CODE) + continue; if (++pal_code_count > 1) { printk(KERN_ERR "Too many EFI Pal Code memory ranges, dropped @ %lx\n", md->phys_addr); continue; - } + } mask = ~((1 << _PAGE_SIZE_4M)-1); /* XXX should be dynamic? */ vaddr = PAGE_OFFSET + md->phys_addr; @@ -281,9 +281,28 @@ efi_init (void) efi_config_table_t *config_tables; efi_char16_t *c16; u64 efi_desc_size; - char vendor[100] = "unknown"; + char *cp, *end, vendor[100] = "unknown"; + extern char saved_command_line[]; int i; + /* it's too early to be able to use the standard kernel command line support... */ + for (cp = saved_command_line; *cp; ) { + if (memcmp(cp, "mem=", 4) == 0) { + cp += 4; + mem_limit = memparse(cp, &end) - 1; + if (end != cp) + break; + cp = end; + } else { + while (*cp != ' ' && *cp) + ++cp; + while (*cp == ' ') + ++cp; + } + } + if (mem_limit != ~0UL) + printk("Ignoring memory above %luMB\n", mem_limit >> 20); + efi.systab = __va(ia64_boot_param.efi_systab); /* @@ -359,7 +378,7 @@ efi_init (void) } #endif - map_pal_code(); + efi_map_pal_code(); } void diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index f9beac21d..e37bd0df8 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -106,29 +106,19 @@ GLOBAL_ENTRY(ia64_switch_to) alloc r16=ar.pfs,1,0,0,0 DO_SAVE_SWITCH_STACK UNW(.body) - // disable interrupts to ensure atomicity for next few instructions: - mov r17=psr // M-unit - ;; - rsm psr.i // M-unit - dep r18=-1,r0,0,61 // build mask 0x1fffffffffffffff - ;; - srlz.d - ;; + adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 + dep r18=-1,r0,0,61 // build mask 0x1fffffffffffffff adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 ;; st8 [r22]=sp // save kernel stack pointer of old task ld8 sp=[r21] // load kernel stack pointer of new task and r20=in0,r18 // physical address of "current" ;; + mov ar.k6=r20 // copy "current" into ar.k6 mov r8=r13 // return pointer to previously running task mov r13=in0 // set "current" pointer - mov ar.k6=r20 // copy "current" into ar.k6 ;; - // restore interrupts - mov psr.l=r17 - ;; - srlz.d DO_LOAD_SWITCH_STACK( ) br.ret.sptk.few rp END(ia64_switch_to) @@ -1207,7 +1197,7 @@ sys_call_table: data8 sys_newlstat data8 sys_newfstat data8 sys_clone2 - data8 ia64_ni_syscall + data8 sys_getdents64 data8 ia64_ni_syscall // 1215 data8 ia64_ni_syscall data8 ia64_ni_syscall diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index b2abc48a4..bea14236d 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -181,7 +181,9 @@ END(ia64_save_debug_regs) GLOBAL_ENTRY(ia64_load_debug_regs) alloc r16=ar.pfs,1,0,0,0 +#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) lfetch.nta [in0] +#endif mov r20=ar.lc // preserve ar.lc add r19=IA64_NUM_DBG_REGS*8,in0 mov ar.lc=IA64_NUM_DBG_REGS-1 @@ -702,3 +704,74 @@ SET_REG(b4); SET_REG(b5); #endif /* CONFIG_IA64_BRL_EMU */ + +#ifdef CONFIG_SMP + + /* + * This routine handles spinlock contention. It uses a simple exponential backoff + * algorithm to reduce unnecessary bus traffic. The initial delay is selected from + * the low-order bits of the cycle counter (a cheap "randomizer"). I'm sure this + * could use additional tuning, especially on systems with a large number of CPUs. + * Also, I think the maximum delay should be made a function of the number of CPUs in + * the system. --davidm 00/08/05 + * + * WARNING: This is not a normal procedure. It gets called from C code without + * the compiler knowing about it. Thus, we must not use any scratch registers + * beyond those that were declared "clobbered" at the call-site (see spin_lock() + * macro). We may not even use the stacked registers, because that could overwrite + * output registers. Similarly, we can't use the scratch stack area as it may be + * in use, too. + * + * Inputs: + * ar.ccv = 0 (and available for use) + * r28 = available for use + * r29 = available for use + * r30 = non-zero (and available for use) + * r31 = address of lock we're trying to acquire + * p15 = available for use + */ + +# define delay r28 +# define timeout r29 +# define tmp r30 + +GLOBAL_ENTRY(ia64_spinlock_contention) + mov tmp=ar.itc + ;; + and delay=0x3f,tmp + ;; + +.retry: add timeout=tmp,delay + shl delay=delay,1 + ;; + dep delay=delay,r0,0,13 // limit delay to 8192 cycles + ;; + // delay a little... +.wait: sub tmp=tmp,timeout + or delay=0xf,delay // make sure delay is non-zero (otherwise we get stuck with 0) + ;; + cmp.lt p15,p0=tmp,r0 + mov tmp=ar.itc +(p15) br.cond.sptk .wait + ;; + ld1 tmp=[r31] + ;; + cmp.ne p15,p0=tmp,r0 + mov tmp=ar.itc +(p15) br.cond.sptk.few .retry // lock is still busy + ;; + // try acquiring lock (we know ar.ccv is still zero!): + mov tmp=1 + ;; + IA64_SEMFIX_INSN + cmpxchg1.acq tmp=[r31],tmp,ar.ccv + ;; + cmp.eq p15,p0=tmp,r0 + + mov tmp=ar.itc +(p15) br.ret.sptk.many b7 // got lock -> return + br .retry // still no luck, retry + +END(ia64_spinlock_contention) + +#endif diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 2e4ffe403..62e792612 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -18,6 +18,7 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strncat); EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strtok); #include <linux/pci.h> @@ -37,6 +38,7 @@ EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(kernel_thread); #ifdef CONFIG_SMP +#include <asm/hardirq.h> EXPORT_SYMBOL(synchronize_irq); #include <asm/smplock.h> diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 1ee2974b5..fe686db0e 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -117,6 +117,13 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs) { unsigned long bsp, sp; + /* + * Note: if the interrupt happened while executing in + * the context switch routine (ia64_switch_to), we may + * get a spurious stack overflow here. This is + * because the register and the memory stack are not + * switched atomically. + */ asm ("mov %0=ar.bsp" : "=r"(bsp)); asm ("mov %0=sp" : "=r"(sp)); diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 9f611c5b0..d1b599f77 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -170,33 +170,27 @@ ia64_ivt: * The ITLB basically does the same as the VHPT handler except * that we always insert exactly one instruction TLB entry. */ -#if 1 /* * Attempt to lookup PTE through virtual linear page table. * The speculative access will fail if there is no TLB entry * for the L3 page table page we're trying to access. */ - mov r31=pr // save predicates - ;; - thash r17=r16 // compute virtual address of L3 PTE + mov r16=cr.iha // get virtual address of L3 PTE ;; - ld8.s r18=[r17] // try to read L3 PTE + ld8.s r16=[r16] // try to read L3 PTE + mov r31=pr // save predicates ;; - tnat.nz p6,p0=r18 // did read succeed? + tnat.nz p6,p0=r16 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.i r18 + itc.i r16 ;; mov pr=r31,-1 rfi -1: rsm psr.dt // use physical addressing for data -#else - mov r16=cr.ifa // get address that caused the TLB miss +1: mov r16=cr.ifa // get address that caused the TLB miss ;; rsm psr.dt // use physical addressing for data -#endif - mov r31=pr // save the predicate registers mov r19=ar.k7 // get page table base address shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 @@ -244,33 +238,27 @@ ia64_ivt: * The DTLB basically does the same as the VHPT handler except * that we always insert exactly one data TLB entry. */ - mov r16=cr.ifa // get address that caused the TLB miss -#if 1 /* * Attempt to lookup PTE through virtual linear page table. * The speculative access will fail if there is no TLB entry * for the L3 page table page we're trying to access. */ - mov r31=pr // save predicates + mov r16=cr.iha // get virtual address of L3 PTE ;; - thash r17=r16 // compute virtual address of L3 PTE - ;; - ld8.s r18=[r17] // try to read L3 PTE + ld8.s r16=[r16] // try to read L3 PTE + mov r31=pr // save predicates ;; - tnat.nz p6,p0=r18 // did read succeed? + tnat.nz p6,p0=r16 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.d r18 + itc.d r16 ;; mov pr=r31,-1 rfi -1: rsm psr.dt // use physical addressing for data -#else - rsm psr.dt // use physical addressing for data - mov r31=pr // save the predicate registers +1: mov r16=cr.ifa // get address that caused the TLB miss ;; -#endif + rsm psr.dt // use physical addressing for data mov r19=ar.k7 // get page table base address shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 @@ -504,7 +492,24 @@ page_fault: mov r29=b0 // save b0 in case of nested fault) ;; 1: ld8 r18=[r17] - ;; // avoid raw on r18 +#if defined(CONFIG_IA32_SUPPORT) && \ + (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B0_SPECIFIC)) + // + // Erratum 85 (Access bit fault could be reported before page not present fault) + // If the PTE is indicates the page is not present, then just turn this into a + // page fault. + // + mov r31=pr // save predicates + ;; + tbit.nz p6,p0=r18,0 // page present bit set? +(p6) br.cond.sptk 1f + ;; // avoid WAW on p6 + mov pr=r31,-1 + br.cond.sptk page_fault // page wasn't present +1: mov pr=r31,-1 +#else + ;; // avoid RAW on r18 +#endif or r18=_PAGE_A,r18 // set the accessed bit mov b0=r29 // restore b0 ;; @@ -541,14 +546,6 @@ page_fault: ;; srlz.d // ensure everyone knows psr.dt is off... cmp.eq p0,p7=r16,r17 // is this a system call? (p7 <- false, if so) -#if 1 - // Allow syscalls via the old system call number for the time being. This is - // so we can transition to the new syscall number in a relatively smooth - // fashion. - mov r17=0x80000 - ;; -(p7) cmp.eq.or.andcm p0,p7=r16,r17 // is this the old syscall number? -#endif (p7) br.cond.spnt.many non_syscall SAVE_MIN // uses r31; defines r2: diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c index 153fb5684..2afb5613e 100644 --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -1,14 +1,12 @@ +#include <linux/config.h> #include <linux/kernel.h> #include <asm/page.h> #include <asm/machvec.h> -struct ia64_machine_vector ia64_mv; +#ifdef CONFIG_IA64_GENERIC -void -machvec_noop (void) -{ -} +struct ia64_machine_vector ia64_mv; /* * Most platforms use this routine for mapping page frame addresses @@ -46,3 +44,10 @@ machvec_init (const char *name) ia64_mv = *mv; printk("booting generic kernel on platform %s\n", name); } + +#endif /* CONFIG_IA64_GENERIC */ + +void +machvec_noop (void) +{ +} diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index 147e2b8fe..0b07163dc 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -191,3 +191,57 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) srlz.d // seralize restoration of psr.l br.ret.sptk.few b0 END(ia64_pal_call_phys_static) + +/* + * Make a PAL call using the stacked registers in physical mode. + * + * Inputs: + * in0 Index of PAL service + * in2 - in3 Remaning PAL arguments + */ +GLOBAL_ENTRY(ia64_pal_call_phys_stacked) + UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)) + alloc loc1 = ar.pfs,5,5,86,0 + movl loc2 = pal_entry_point +1: { + mov r28 = in0 // copy procedure index + mov loc0 = rp // save rp + } + .body + ;; + ld8 loc2 = [loc2] // loc2 <- entry point + mov out0 = in0 // first argument + mov out1 = in1 // copy arg2 + mov out2 = in2 // copy arg3 + mov out3 = in3 // copy arg3 + ;; + mov loc3 = psr // save psr + ;; + mov loc4=ar.rsc // save RSE configuration + dep.z loc2=loc2,0,61 // convert pal entry point to physical + ;; + mov ar.rsc=r0 // put RSE in enforced lazy, LE mode + movl r16=PAL_PSR_BITS_TO_CLEAR + movl r17=PAL_PSR_BITS_TO_SET + ;; + or loc3=loc3,r17 // add in psr the bits to set + mov b7 = loc2 // install target to branch reg + ;; + andcm r16=loc3,r16 // removes bits to clear from psr + br.call.sptk.few rp=ia64_switch_mode +.ret6: + br.call.sptk.many rp=b7 // now make the call +.ret7: + mov ar.rsc=r0 // put RSE in enforced lazy, LE mode + mov r16=loc3 // r16= original psr + br.call.sptk.few rp=ia64_switch_mode // return to virtual mode + +.ret8: mov psr.l = loc3 // restore init PSR + mov ar.pfs = loc1 + mov rp = loc0 + ;; + mov ar.rsc=loc4 // restore RSE configuration + srlz.d // seralize restoration of psr.l + br.ret.sptk.few b0 +END(ia64_pal_call_phys_stacked) + diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index ad40e911e..ecd7b0886 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -16,24 +16,41 @@ * are empty for now. * - remove hack to avoid problem with <= 256M RAM for itr. */ +#include <linux/config.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/mm.h> +#include <linux/module.h> +#if defined(MODVERSIONS) +#include <linux/modversions.h> +#endif #include <asm/pal.h> #include <asm/sal.h> #include <asm/efi.h> #include <asm/page.h> #include <asm/processor.h> +#ifdef CONFIG_SMP +#include <linux/smp.h> +#endif + +MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>"); +MODULE_DESCRIPTION("/proc interface to IA-64 PAL"); /* - * Hope to get rid of these in a near future + * Hope to get rid of this one in a near future */ #define IA64_PAL_VERSION_BUG 1 -#define PALINFO_VERSION "0.1" +#define PALINFO_VERSION "0.3" + +#ifdef CONFIG_SMP +#define cpu_is_online(i) (cpu_online_map & (1UL << i)) +#else +#define cpu_is_online(i) 1 +#endif typedef int (*palinfo_func_t)(char*); @@ -43,7 +60,6 @@ typedef struct { struct proc_dir_entry *entry; /* registered entry (removal) */ } palinfo_entry_t; -static struct proc_dir_entry *palinfo_dir; /* * A bunch of string array to get pretty printing @@ -95,7 +111,7 @@ static const char *rse_hints[]={ #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *)) /* - * The current resvision of the Volume 2 of + * The current revision of the Volume 2 of * IA-64 Architecture Software Developer's Manual is wrong. * Table 4-10 has invalid information concerning the ma field: * Correct table is: @@ -121,64 +137,31 @@ static const char *mem_attrib[]={ /* * Allocate a buffer suitable for calling PAL code in Virtual mode * - * The documentation (PAL2.6) requires thius buffer to have a pinned - * translation to avoid any DTLB faults. For this reason we allocate - * a page (large enough to hold any possible reply) and use a DTC - * to hold the translation during the call. A call the free_palbuffer() - * is required to release ALL resources (page + translation). - * - * The size of the page allocated is based on the PAGE_SIZE defined - * at compile time for the kernel, i.e. >= 4Kb. + * The documentation (PAL2.6) allows DTLB misses on the buffer. So + * using the TC is enough, no need to pin the entry. * - * Return: a pointer to the newly allocated page (virtual address) + * We allocate a kernel-sized page (at least 4KB). This is enough to + * hold any possible reply. */ -static void * +static inline void * get_palcall_buffer(void) { void *tmp; tmp = (void *)__get_free_page(GFP_KERNEL); if (tmp == 0) { - printk(KERN_ERR "%s: can't get a buffer page\n", __FUNCTION__); - } else if ( ((u64)tmp - PAGE_OFFSET) > (1<<_PAGE_SIZE_256M) ) { /* XXX: temporary hack */ - unsigned long flags; - - /* PSR.ic must be zero to insert new DTR */ - ia64_clear_ic(flags); - - /* - * we only insert of DTR - * - * XXX: we need to figure out a way to "allocate" TR(s) to avoid - * conflicts. Maybe something in an include file like pgtable.h - * page.h or processor.h - * - * ITR0/DTR0: used for kernel code/data - * ITR1/DTR1: used by HP simulator - * ITR2/DTR2: used to map PAL code - */ - ia64_itr(0x2, 3, (u64)tmp, - pte_val(mk_pte_phys(__pa(tmp), __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW))), PAGE_SHIFT); - - ia64_srlz_d (); - - __restore_flags(flags); - } - + printk(KERN_ERR __FUNCTION__" : can't get a buffer page\n"); + } return tmp; } /* * Free a palcall buffer allocated with the previous call - * - * The translation is also purged. */ -static void +static inline void free_palcall_buffer(void *addr) { __free_page(addr); - ia64_ptr(0x2, (u64)addr, PAGE_SHIFT); - ia64_srlz_d (); } /* @@ -564,7 +547,6 @@ processor_info(char *page) int i; s64 ret; - /* must be in physical mode */ if ((ret=ia64_pal_proc_get_features(&avail, &status, &control)) != 0) return 0; for(i=0; i < 64; i++, v++,avail >>=1, status >>=1, control >>=1) { @@ -577,6 +559,57 @@ processor_info(char *page) return p - page; } +static const char *bus_features[]={ + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL, + "Request Bus Parking", + "Bus Lock Mask", + "Enable Half Transfer", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + "Disable Transaction Queuing", + "Disable Reponse Error Checking", + "Disable Bus Error Checking", + "Disable Bus Requester Internal Error Signalling", + "Disable Bus Requester Error Signalling", + "Disable Bus Initialization Event Checking", + "Disable Bus Initialization Event Signalling", + "Disable Bus Address Error Checking", + "Disable Bus Address Error Signalling", + "Disable Bus Data Error Checking" +}; + + +static int +bus_info(char *page) +{ + char *p = page; + const char **v = bus_features; + pal_bus_features_u_t av, st, ct; + u64 avail, status, control; + int i; + s64 ret; + + if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) return 0; + + avail = av.pal_bus_features_val; + status = st.pal_bus_features_val; + control = ct.pal_bus_features_val; + + for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { + if ( ! *v ) continue; + p += sprintf(p, "%-48s : %s%s %s\n", *v, + avail & 0x1 ? "" : "NotImpl", + avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", + avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); + } + return p - page; +} + + /* * physical mode call for PAL_VERSION is working fine. * This function is meant to go away once PAL get fixed. @@ -613,21 +646,25 @@ version_info(char *page) #endif if (status != 0) return 0; - p += sprintf(p, "PAL_vendor : 0x%x (min=0x%x)\n" \ - "PAL_A revision : 0x%x (min=0x%x)\n" \ - "PAL_A model : 0x%x (min=0x%x)\n" \ - "PAL_B mode : 0x%x (min=0x%x)\n" \ - "PAL_B revision : 0x%x (min=0x%x)\n", + p += sprintf(p, "PAL_vendor : 0x%02x (min=0x%02x)\n" \ + "PAL_A : %x.%x.%x (min=%x.%x.%x)\n" \ + "PAL_B : %x.%x.%x (min=%x.%x.%x)\n", cur_ver.pal_version_s.pv_pal_vendor, min_ver.pal_version_s.pv_pal_vendor, + + cur_ver.pal_version_s.pv_pal_a_model>>4, + cur_ver.pal_version_s.pv_pal_a_model&0xf, cur_ver.pal_version_s.pv_pal_a_rev, - cur_ver.pal_version_s.pv_pal_a_rev, - cur_ver.pal_version_s.pv_pal_a_model, - min_ver.pal_version_s.pv_pal_a_model, + min_ver.pal_version_s.pv_pal_a_model>>4, + min_ver.pal_version_s.pv_pal_a_model&0xf, + min_ver.pal_version_s.pv_pal_a_rev, + + cur_ver.pal_version_s.pv_pal_b_model>>4, + cur_ver.pal_version_s.pv_pal_b_model&0xf, cur_ver.pal_version_s.pv_pal_b_rev, - min_ver.pal_version_s.pv_pal_b_rev, - cur_ver.pal_version_s.pv_pal_b_model, - min_ver.pal_version_s.pv_pal_b_model); + min_ver.pal_version_s.pv_pal_b_model>>4, + min_ver.pal_version_s.pv_pal_b_model&0xf, + min_ver.pal_version_s.pv_pal_b_rev); return p - page; } @@ -648,6 +685,9 @@ perfmon_info(char *page) } #ifdef IA64_PAL_PERF_MON_INFO_BUG + /* + * This bug has been fixed in PAL 2.2.9 and higher + */ pm_buffer[5]=0x3; pm_info.pal_perf_mon_info_s.cycles = 0x12; pm_info.pal_perf_mon_info_s.retired = 0x08; @@ -708,30 +748,111 @@ frequency_info(char *page) return p - page; } - -/* - * Entry point routine: all calls go trhough this function - */ static int -palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) +tr_info(char *page) { - palinfo_func_t info = (palinfo_func_t)data; - int len = info(page); + char *p = page; + s64 status; + pal_tr_valid_u_t tr_valid; + u64 tr_buffer[4]; + pal_vm_info_1_u_t vm_info_1; + pal_vm_info_2_u_t vm_info_2; + int i, j; + u64 max[3], pgm; + struct ifa_reg { + u64 valid:1; + u64 ig:11; + u64 vpn:52; + } *ifa_reg; + struct itir_reg { + u64 rv1:2; + u64 ps:6; + u64 key:24; + u64 rv2:32; + } *itir_reg; + struct gr_reg { + u64 p:1; + u64 rv1:1; + u64 ma:3; + u64 a:1; + u64 d:1; + u64 pl:2; + u64 ar:3; + u64 ppn:38; + u64 rv2:2; + u64 ed:1; + u64 ig:11; + } *gr_reg; + struct rid_reg { + u64 ig1:1; + u64 rv1:1; + u64 ig2:6; + u64 rid:24; + u64 rv2:32; + } *rid_reg; - if (len <= off+count) *eof = 1; + if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { + printk("ia64_pal_vm_summary=%ld\n", status); + return 0; + } + max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1; + max[1] = vm_info_1.pal_vm_info_1_s.max_dtr_entry+1; - *start = page + off; - len -= off; + for (i=0; i < 2; i++ ) { + for (j=0; j < max[i]; j++) { - if (len>count) len = count; - if (len<0) len = 0; + status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid); + if (status != 0) { + printk(__FUNCTION__ " pal call failed on tr[%d:%d]=%ld\n", i, j, status); + continue; + } - return len; + ifa_reg = (struct ifa_reg *)&tr_buffer[2]; + + if (ifa_reg->valid == 0) continue; + + gr_reg = (struct gr_reg *)tr_buffer; + itir_reg = (struct itir_reg *)&tr_buffer[1]; + rid_reg = (struct rid_reg *)&tr_buffer[3]; + + pgm = -1 << (itir_reg->ps - 12); + p += sprintf(p, "%cTR%d: av=%d pv=%d dv=%d mv=%d\n" \ + "\tppn : 0x%lx\n" \ + "\tvpn : 0x%lx\n" \ + "\tps : ", + + "ID"[i], + j, + tr_valid.pal_tr_valid_s.access_rights_valid, + tr_valid.pal_tr_valid_s.priv_level_valid, + tr_valid.pal_tr_valid_s.dirty_bit_valid, + tr_valid.pal_tr_valid_s.mem_attr_valid, + (gr_reg->ppn & pgm)<< 12, + (ifa_reg->vpn & pgm)<< 12); + + p = bitvector_process(p, 1<< itir_reg->ps); + + p += sprintf(p, "\n\tpl : %d\n" \ + "\tar : %d\n" \ + "\trid : %x\n" \ + "\tp : %d\n" \ + "\tma : %d\n" \ + "\td : %d\n", + gr_reg->pl, + gr_reg->ar, + rid_reg->rid, + gr_reg->p, + gr_reg->ma, + gr_reg->d); + } + } + return p - page; } + + /* - * List names,function pairs for every entry in /proc/palinfo - * Must be terminated with the NULL,NULL entry. + * List {name,function} pairs for every entry in /proc/palinfo/cpu* */ static palinfo_entry_t palinfo_entries[]={ { "version_info", version_info, }, @@ -742,38 +863,190 @@ static palinfo_entry_t palinfo_entries[]={ { "processor_info", processor_info, }, { "perfmon_info", perfmon_info, }, { "frequency_info", frequency_info, }, - { NULL, NULL,} + { "bus_info", bus_info }, + { "tr_info", tr_info, } }; +#define NR_PALINFO_ENTRIES (sizeof(palinfo_entries)/sizeof(palinfo_entry_t)) + +/* + * this array is used to keep track of the proc entries we create. This is + * required in the module mode when we need to remove all entries. The procfs code + * does not do recursion of deletion + * + * Notes: + * - first +1 accounts for the cpuN entry + * - second +1 account for toplevel palinfo + * + */ +#define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1)+1) + +static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES]; + +/* + * This data structure is used to pass which cpu,function is being requested + * It must fit in a 64bit quantity to be passed to the proc callback routine + * + * In SMP mode, when we get a request for another CPU, we must call that + * other CPU using IPI and wait for the result before returning. + */ +typedef union { + u64 value; + struct { + unsigned req_cpu: 32; /* for which CPU this info is */ + unsigned func_id: 32; /* which function is requested */ + } pal_func_cpu; +} pal_func_cpu_u_t; + +#define req_cpu pal_func_cpu.req_cpu +#define func_id pal_func_cpu.func_id + +#ifdef CONFIG_SMP + +/* + * used to hold information about final function to call + */ +typedef struct { + palinfo_func_t func; /* pointer to function to call */ + char *page; /* buffer to store results */ + int ret; /* return value from call */ +} palinfo_smp_data_t; + + +/* + * this function does the actual final call and he called + * from the smp code, i.e., this is the palinfo callback routine + */ +static void +palinfo_smp_call(void *info) +{ + palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; + /* printk(__FUNCTION__" called on CPU %d\n", smp_processor_id());*/ + if (data == NULL) { + printk(KERN_ERR __FUNCTION__" data pointer is NULL\n"); + data->ret = 0; /* no output */ + return; + } + /* does this actual call */ + data->ret = (*data->func)(data->page); +} + +/* + * function called to trigger the IPI, we need to access a remote CPU + * Return: + * 0 : error or nothing to output + * otherwise how many bytes in the "page" buffer were written + */ +static +int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) +{ + palinfo_smp_data_t ptr; + int ret; + + ptr.func = palinfo_entries[f->func_id].proc_read; + ptr.page = page; + ptr.ret = 0; /* just in case */ + + /*printk(__FUNCTION__" calling CPU %d from CPU %d for function %d\n", f->req_cpu,smp_processor_id(), f->func_id);*/ + + /* will send IPI to other CPU and wait for completion of remote call */ + if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) { + printk(__FUNCTION__" remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret); + return 0; + } + return ptr.ret; +} +#else /* ! CONFIG_SMP */ +static +int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) +{ + printk(__FUNCTION__" should not be called with non SMP kernel\n"); + return 0; +} +#endif /* CONFIG_SMP */ + +/* + * Entry point routine: all calls go through this function + */ +static int +palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len=0; + pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data; + + MOD_INC_USE_COUNT; + /* + * in SMP mode, we may need to call another CPU to get correct + * information. PAL, by definition, is processor specific + */ + if (f->req_cpu == smp_processor_id()) + len = (*palinfo_entries[f->func_id].proc_read)(page); + else + len = palinfo_handle_smp(f, page); + + if (len <= off+count) *eof = 1; + + *start = page + off; + len -= off; + + if (len>count) len = count; + if (len<0) len = 0; + + MOD_DEC_USE_COUNT; + + return len; +} static int __init palinfo_init(void) { - palinfo_entry_t *p; +# define CPUSTR "cpu%d" + + pal_func_cpu_u_t f; + struct proc_dir_entry **pdir = palinfo_proc_entries; + struct proc_dir_entry *palinfo_dir, *cpu_dir; + int i, j; + char cpustr[sizeof(CPUSTR)]; printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); - palinfo_dir = create_proc_entry("palinfo", S_IFDIR | S_IRUGO | S_IXUGO, NULL); + palinfo_dir = proc_mkdir("pal", NULL); + + /* + * we keep track of created entries in a depth-first order for + * cleanup purposes. Each entry is stored into palinfo_proc_entries + */ + for (i=0; i < NR_CPUS; i++) { + + if (!cpu_is_online(i)) continue; + + sprintf(cpustr,CPUSTR, i); + + cpu_dir = proc_mkdir(cpustr, palinfo_dir); - for (p = palinfo_entries; p->name ; p++){ - p->entry = create_proc_read_entry (p->name, 0, palinfo_dir, - palinfo_read_entry, p->proc_read); + f.req_cpu = i; + + for (j=0; j < NR_PALINFO_ENTRIES; j++) { + f.func_id = j; + *pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir, + palinfo_read_entry, (void *)f.value); + } + *pdir++ = cpu_dir; } + *pdir = palinfo_dir; return 0; } -static int __exit +static void __exit palinfo_exit(void) { - palinfo_entry_t *p; + int i = 0; - for (p = palinfo_entries; p->name ; p++){ - remove_proc_entry (p->name, palinfo_dir); + /* remove all nodes: depth first pass */ + for (i=0; i< NR_PALINFO_PROC_ENTRIES ; i++) { + remove_proc_entry (palinfo_proc_entries[i]->name, NULL); } - remove_proc_entry ("palinfo", 0); - - return 0; } module_init(palinfo_init); diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index ab86e69b3..80509c6a1 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -3,34 +3,509 @@ * * This implementation is for IA-64 platforms that do not support * I/O TLBs (aka DMA address translation hardware). - * - * XXX This doesn't do the right thing yet. It appears we would have - * to add additional zones so we can implement the various address - * mask constraints that we might encounter. A zone for memory < 32 - * bits is obviously necessary... + * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com> + * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com> */ -#include <linux/types.h> +#include <linux/config.h> + #include <linux/mm.h> -#include <linux/string.h> #include <linux/pci.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/types.h> #include <asm/io.h> +#include <asm/pci.h> +#include <asm/dma.h> + +#ifdef CONFIG_SWIOTLB + +#include <linux/init.h> +#include <linux/bootmem.h> + +#define ALIGN(val, align) ((unsigned long) (((unsigned long) (val) + ((align) - 1)) & ~((align) - 1))) + +/* + * log of the size of each IO TLB slab. The number of slabs is command line + * controllable. + */ +#define IO_TLB_SHIFT 11 + +/* + * Used to do a quick range check in pci_unmap_single and pci_sync_single, to see if the + * memory was in fact allocated by this API. + */ +static char *io_tlb_start, *io_tlb_end; + +/* + * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and io_tlb_end. + * This is command line adjustable via setup_io_tlb_npages. + */ +unsigned long io_tlb_nslabs = 1024; + +/* + * This is a free list describing the number of free entries available from each index + */ +static unsigned int *io_tlb_list; +static unsigned int io_tlb_index; + +/* + * We need to save away the original address corresponding to a mapped entry for the sync + * operations. + */ +static unsigned char **io_tlb_orig_addr; + +/* + * Protect the above data structures in the map and unmap calls + */ +spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED; + +static int __init +setup_io_tlb_npages (char *str) +{ + io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT); + return 1; +} +__setup("swiotlb=", setup_io_tlb_npages); + +/* + * Statically reserve bounce buffer space and initialize bounce buffer + * data structures for the software IO TLB used to implement the PCI DMA API + */ +void +setup_swiotlb (void) +{ + int i; + + /* + * Get IO TLB memory from the low pages + */ + io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + if (!io_tlb_start) + BUG(); + io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); + + /* + * Allocate and initialize the free list array. This array is used + * to find contiguous free memory regions of size 2^IO_TLB_SHIFT between + * io_tlb_start and io_tlb_end. + */ + io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); + for (i = 0; i < io_tlb_nslabs; i++) + io_tlb_list[i] = io_tlb_nslabs - i; + io_tlb_index = 0; + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); + + printk("Placing software IO TLB between 0x%p - 0x%p\n", io_tlb_start, io_tlb_end); +} + +/* + * Allocates bounce buffer and returns its kernel virtual address. + */ +static void * +__pci_map_single (struct pci_dev *hwdev, char *buffer, size_t size, int direction) +{ + unsigned long flags; + char *dma_addr; + unsigned int i, nslots, stride, index, wrap; + + /* + * For mappings greater than a page size, we limit the stride (and hence alignment) + * to a page size. + */ + nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; + if (size > (1 << PAGE_SHIFT)) + stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT)); + else + stride = nslots; + + if (!nslots) + BUG(); + + /* + * Find suitable number of IO TLB entries size that will fit this request and allocate a buffer + * from that IO TLB pool. + */ + spin_lock_irqsave(&io_tlb_lock, flags); + { + wrap = index = ALIGN(io_tlb_index, stride); + do { + /* + * If we find a slot that indicates we have 'nslots' number of + * contiguous buffers, we allocate the buffers from that slot and mark the + * entries as '0' indicating unavailable. + */ + if (io_tlb_list[index] >= nslots) { + for (i = index; i < index + nslots; i++) + io_tlb_list[i] = 0; + dma_addr = io_tlb_start + (index << IO_TLB_SHIFT); + + /* + * Update the indices to avoid searching in the next round. + */ + io_tlb_index = (index + nslots) < io_tlb_nslabs ? (index + nslots) : 0; + + goto found; + } + index += stride; + if (index >= io_tlb_nslabs) + index = 0; + } while (index != wrap); + + /* + * XXX What is a suitable recovery mechanism here? We cannot + * sleep because we are called from with in interrupts! + */ + panic("__pci_map_single: could not allocate software IO TLB (%ld bytes)", size); +found: + } + spin_unlock_irqrestore(&io_tlb_lock, flags); + + /* + * Save away the mapping from the original address to the DMA address. This is needed + * when we sync the memory. Then we sync the buffer if needed. + */ + io_tlb_orig_addr[index] = buffer; + if (direction == PCI_DMA_TODEVICE || direction == PCI_DMA_BIDIRECTIONAL) + memcpy(dma_addr, buffer, size); + + return dma_addr; +} + +/* + * dma_addr is the kernel virtual address of the bounce buffer to unmap. + */ +static void +__pci_unmap_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) +{ + unsigned long flags; + int i, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + /* + * First, sync the memory before unmapping the entry + */ + if ((direction == PCI_DMA_FROMDEVICE) || (direction == PCI_DMA_BIDIRECTIONAL)) + /* + * bounce... copy the data back into the original buffer + * and delete the bounce buffer. + */ + memcpy(buffer, dma_addr, size); + + /* + * Return the buffer to the free list by setting the corresponding entries to indicate + * the number of contigous entries available. + * While returning the entries to the free list, we merge the entries with slots below + * and above the pool being returned. + */ + spin_lock_irqsave(&io_tlb_lock, flags); + { + int count = ((index + nslots) < io_tlb_nslabs ? io_tlb_list[index + nslots] : 0); + /* + * Step 1: return the slots to the free list, merging the slots with superceeding slots + */ + for (i = index + nslots - 1; i >= index; i--) + io_tlb_list[i] = ++count; + /* + * Step 2: merge the returned slots with the preceeding slots, if available (non zero) + */ + for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--) + io_tlb_list[i] += io_tlb_list[index]; + } + spin_unlock_irqrestore(&io_tlb_lock, flags); +} + +static void +__pci_sync_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) +{ + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + /* + * bounce... copy the data back into/from the original buffer + * XXX How do you handle PCI_DMA_BIDIRECTIONAL here ? + */ + if (direction == PCI_DMA_FROMDEVICE) + memcpy(buffer, dma_addr, size); + else if (direction == PCI_DMA_TODEVICE) + memcpy(dma_addr, buffer, size); + else + BUG(); +} + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. + * The PCI address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single is performed. + */ +dma_addr_t +pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + unsigned long pci_addr = virt_to_phys(ptr); + + if (direction == PCI_DMA_NONE) + BUG(); + /* + * Check if the PCI device can DMA to ptr... if so, just return ptr + */ + if ((pci_addr & ~hwdev->dma_mask) == 0) + /* + * Device is bit capable of DMA'ing to the + * buffer... just return the PCI address of ptr + */ + return pci_addr; + + /* + * get a bounce buffer: + */ + pci_addr = virt_to_phys(__pci_map_single(hwdev, ptr, size, direction)); + + /* + * Ensure that the address returned is DMA'ble: + */ + if ((pci_addr & ~hwdev->dma_mask) != 0) + panic("__pci_map_single: bounce buffer is not DMA'ble"); + + return pci_addr; +} + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +void +pci_unmap_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) +{ + char *dma_addr = phys_to_virt(pci_addr); + + if (direction == PCI_DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + __pci_unmap_single(hwdev, dma_addr, size, direction); +} + +/* + * Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +void +pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) +{ + char *dma_addr = phys_to_virt(pci_addr); + + if (direction == PCI_DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + __pci_sync_single(hwdev, dma_addr, size, direction); +} + +/* + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +int +pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) { + sg->orig_address = sg->address; + if ((virt_to_phys(sg->address) & ~hwdev->dma_mask) != 0) { + sg->address = __pci_map_single(hwdev, sg->address, sg->length, direction); + } + } + return nelems; +} + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +void +pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) + if (sg->orig_address != sg->address) { + __pci_unmap_single(hwdev, sg->address, sg->length, direction); + sg->address = sg->orig_address; + } +} + +/* + * Make physical memory consistent for a set of streaming mode DMA + * translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +void +pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) + if (sg->orig_address != sg->address) + __pci_sync_single(hwdev, sg->address, sg->length, direction); +} + +#else +/* + * Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single is performed. + */ +extern inline dma_addr_t +pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + return virt_to_bus(ptr); +} + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +extern inline void +pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} +/* + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +extern inline int +pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + return nents; +} + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +extern inline void +pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} +/* + * Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +extern inline void +pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} + +/* + * Make physical memory consistent for a set of streaming mode DMA + * translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +extern inline void +pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} + +#endif /* CONFIG_SWIOTLB */ void * pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { - void *ret; + unsigned long pci_addr; int gfp = GFP_ATOMIC; + void *ret; - if (!hwdev || hwdev->dma_mask == 0xffffffff) - gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */ + if (!hwdev || hwdev->dma_mask <= 0xffffffff) + gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */ ret = (void *)__get_free_pages(gfp, get_order(size)); + if (!ret) + return NULL; - if (ret) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } + memset(ret, 0, size); + pci_addr = virt_to_phys(ret); + if ((pci_addr & ~hwdev->dma_mask) != 0) + panic("pci_alloc_consistent: allocated memory is out of range for PCI device"); + *dma_handle = pci_addr; return ret; } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 29291e1f9..752b2a9a1 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -11,6 +11,7 @@ #include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/interrupt.h> #include <linux/smp_lock.h> #include <asm/errno.h> @@ -55,24 +56,23 @@ #define WRITE_PMCS 0xa1 #define READ_PMDS 0xa2 #define STOP_PMCS 0xa3 -#define IA64_COUNTER_MASK 0xffffffffffffff6f -#define PERF_OVFL_VAL 0xffffffff +#define IA64_COUNTER_MASK 0xffffffffffffff6fL +#define PERF_OVFL_VAL 0xffffffffL + +volatile int used_by_system; struct perfmon_counter { unsigned long data; unsigned long counter_num; }; -unsigned long pmds[MAX_PERF_COUNTER]; -struct task_struct *perf_owner=NULL; +unsigned long pmds[NR_CPUS][MAX_PERF_COUNTER]; asmlinkage unsigned long sys_perfmonctl (int cmd1, int cmd2, void *ptr) { struct perfmon_counter tmp, *cptr = ptr; - unsigned long pmd, cnum, dcr, flags; - struct task_struct *p; - struct pt_regs *regs; + unsigned long cnum, dcr, flags; struct perf_counter; int i; @@ -80,22 +80,24 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) case WRITE_PMCS: /* Writes to PMC's and clears PMDs */ case WRITE_PMCS_AND_START: /* Also starts counting */ - if (!access_ok(VERIFY_READ, cptr, sizeof(struct perf_counter)*cmd2)) - return -EFAULT; + if (cmd2 <= 0 || cmd2 > MAX_PERF_COUNTER - used_by_system) + return -EINVAL; - if (cmd2 > MAX_PERF_COUNTER) + if (!access_ok(VERIFY_READ, cptr, sizeof(struct perf_counter)*cmd2)) return -EFAULT; - if (perf_owner && perf_owner != current) - return -EBUSY; - perf_owner = current; + current->thread.flags |= IA64_THREAD_PM_VALID; for (i = 0; i < cmd2; i++, cptr++) { copy_from_user(&tmp, cptr, sizeof(tmp)); /* XXX need to check validity of counter_num and perhaps data!! */ + if (tmp.counter_num < 4 + || tmp.counter_num >= 4 + MAX_PERF_COUNTER - used_by_system) + return -EFAULT; + ia64_set_pmc(tmp.counter_num, tmp.data); ia64_set_pmd(tmp.counter_num, 0); - pmds[tmp.counter_num - 4] = 0; + pmds[smp_processor_id()][tmp.counter_num - 4] = 0; } if (cmd1 == WRITE_PMCS_AND_START) { @@ -104,26 +106,13 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) dcr |= IA64_DCR_PP; ia64_set_dcr(dcr); local_irq_restore(flags); - - /* - * This is a no can do. It obviously wouldn't - * work on SMP where another process may not - * be blocked at all. We need to put in a perfmon - * IPI to take care of MP systems. See blurb above. - */ - lock_kernel(); - for_each_task(p) { - regs = (struct pt_regs *) (((char *)p) + IA64_STK_OFFSET) -1 ; - ia64_psr(regs)->pp = 1; - } - unlock_kernel(); ia64_set_pmc(0, 0); } break; case READ_PMDS: - if (cmd2 > MAX_PERF_COUNTER) - return -EFAULT; + if (cmd2 <= 0 || cmd2 > MAX_PERF_COUNTER - used_by_system) + return -EINVAL; if (!access_ok(VERIFY_WRITE, cptr, sizeof(struct perf_counter)*cmd2)) return -EFAULT; @@ -153,9 +142,13 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) * when we re-enabled interrupts. When I muck with dcr, * is the irq_save/restore needed? */ - for (i = 0, cnum = 4;i < MAX_PERF_COUNTER; i++, cnum++, cptr++){ - pmd = pmds[i] + (ia64_get_pmd(cnum) & PERF_OVFL_VAL); - put_user(pmd, &cptr->data); + for (i = 0, cnum = 4;i < cmd2; i++, cnum++, cptr++) { + tmp.data = (pmds[smp_processor_id()][i] + + (ia64_get_pmd(cnum) & PERF_OVFL_VAL)); + tmp.counter_num = cnum; + if (copy_to_user(cptr, &tmp, sizeof(tmp))) + return -EFAULT; + //put_user(pmd, &cptr->data); } local_irq_save(flags); __asm__ __volatile__("ssm psr.pp"); @@ -167,30 +160,22 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) case STOP_PMCS: ia64_set_pmc(0, 1); - for (i = 0; i < MAX_PERF_COUNTER; ++i) - ia64_set_pmc(i, 0); + ia64_srlz_d(); + for (i = 0; i < MAX_PERF_COUNTER - used_by_system; ++i) + ia64_set_pmc(4+i, 0); - local_irq_save(flags); - dcr = ia64_get_dcr(); - dcr &= ~IA64_DCR_PP; - ia64_set_dcr(dcr); - local_irq_restore(flags); - /* - * This is a no can do. It obviously wouldn't - * work on SMP where another process may not - * be blocked at all. We need to put in a perfmon - * IPI to take care of MP systems. See blurb above. - */ - lock_kernel(); - for_each_task(p) { - regs = (struct pt_regs *) (((char *)p) + IA64_STK_OFFSET) - 1; - ia64_psr(regs)->pp = 0; + if (!used_by_system) { + local_irq_save(flags); + dcr = ia64_get_dcr(); + dcr &= ~IA64_DCR_PP; + ia64_set_dcr(dcr); + local_irq_restore(flags); } - unlock_kernel(); - perf_owner = NULL; + current->thread.flags &= ~(IA64_THREAD_PM_VALID); break; default: + return -EINVAL; break; } return 0; @@ -202,13 +187,13 @@ update_counters (void) unsigned long mask, i, cnum, val; mask = ia64_get_pmc(0) >> 4; - for (i = 0, cnum = 4; i < MAX_PERF_COUNTER; cnum++, i++, mask >>= 1) { + for (i = 0, cnum = 4; i < MAX_PERF_COUNTER - used_by_system; cnum++, i++, mask >>= 1) { + val = 0; if (mask & 0x1) - val = PERF_OVFL_VAL; - else + val += PERF_OVFL_VAL + 1; /* since we got an interrupt, might as well clear every pmd. */ - val = ia64_get_pmd(cnum) & PERF_OVFL_VAL; - pmds[i] += val; + val += ia64_get_pmd(cnum) & PERF_OVFL_VAL; + pmds[smp_processor_id()][i] += val; ia64_set_pmd(cnum, 0); } } @@ -221,20 +206,61 @@ perfmon_interrupt (int irq, void *arg, struct pt_regs *regs) ia64_srlz_d(); } +static struct irqaction perfmon_irqaction = { + handler: perfmon_interrupt, + flags: SA_INTERRUPT, + name: "perfmon" +}; + void perfmon_init (void) { - if (request_irq(PERFMON_IRQ, perfmon_interrupt, 0, "perfmon", NULL)) { - printk("perfmon_init: could not allocate performance monitor vector %u\n", - PERFMON_IRQ); - return; - } + irq_desc[PERFMON_IRQ].status |= IRQ_PER_CPU; + irq_desc[PERFMON_IRQ].handler = &irq_type_ia64_sapic; + setup_irq(PERFMON_IRQ, &perfmon_irqaction); + ia64_set_pmv(PERFMON_IRQ); ia64_srlz_d(); printk("Initialized perfmon vector to %u\n",PERFMON_IRQ); } +void +perfmon_init_percpu (void) +{ + ia64_set_pmv(PERFMON_IRQ); + ia64_srlz_d(); +} + +void +ia64_save_pm_regs (struct thread_struct *t) +{ + int i; + + ia64_set_pmc(0, 1); + ia64_srlz_d(); + for (i=0; i< IA64_NUM_PM_REGS - used_by_system ; i++) { + t->pmd[i] = ia64_get_pmd(4+i); + t->pmod[i] = pmds[smp_processor_id()][i]; + t->pmc[i] = ia64_get_pmc(4+i); + } +} + +void +ia64_load_pm_regs (struct thread_struct *t) +{ + int i; + + for (i=0; i< IA64_NUM_PM_REGS - used_by_system ; i++) { + ia64_set_pmd(4+i, t->pmd[i]); + pmds[smp_processor_id()][i] = t->pmod[i]; + ia64_set_pmc(4+i, t->pmc[i]); + } + ia64_set_pmc(0, 0); + ia64_srlz_d(); +} + #else /* !CONFIG_PERFMON */ + asmlinkage unsigned long sys_perfmonctl (int cmd1, int cmd2, void *ptr) { diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 3759e52f8..e586a4074 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -27,6 +27,8 @@ #include <asm/unwind.h> #include <asm/user.h> +#ifdef CONFIG_IA64_NEW_UNWIND + static void do_show_stack (struct unw_frame_info *info, void *arg) { @@ -44,6 +46,8 @@ do_show_stack (struct unw_frame_info *info, void *arg) } while (unw_unwind(info) >= 0); } +#endif + void show_stack (struct task_struct *task) { @@ -118,15 +122,14 @@ cpu_idle (void *unused) current->nice = 20; current->counter = -100; -#ifdef CONFIG_SMP - if (!current->need_resched) - min_xtp(); -#endif while (1) { - while (!current->need_resched) { +#ifdef CONFIG_SMP + if (!current->need_resched) + min_xtp(); +#endif + while (!current->need_resched) continue; - } #ifdef CONFIG_SMP normal_xtp(); #endif @@ -157,11 +160,12 @@ cpu_idle (void *unused) void ia64_save_extra (struct task_struct *task) { - extern void ia64_save_debug_regs (unsigned long *save_area); - extern void ia32_save_state (struct thread_struct *thread); - if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_save_debug_regs(&task->thread.dbr[0]); +#ifdef CONFIG_PERFMON + if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) + ia64_save_pm_regs(&task->thread); +#endif if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_save_state(&task->thread); } @@ -169,11 +173,12 @@ ia64_save_extra (struct task_struct *task) void ia64_load_extra (struct task_struct *task) { - extern void ia64_load_debug_regs (unsigned long *save_area); - extern void ia32_load_state (struct thread_struct *thread); - if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_load_debug_regs(&task->thread.dbr[0]); +#ifdef CONFIG_PERFMON + if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) + ia64_load_pm_regs(&task->thread); +#endif if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_load_state(&task->thread); } @@ -532,17 +537,6 @@ exit_thread (void) } } -/* - * Free remaining state associated with DEAD_TASK. This is called - * after the parent of DEAD_TASK has collected the exist status of the - * task via wait(). - */ -void -release_thread (struct task_struct *dead_task) -{ - /* nothing to do */ -} - unsigned long get_wchan (struct task_struct *p) { diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index ae8991c51..10868ce41 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -549,6 +549,7 @@ void ia64_sync_fph (struct task_struct *child) { if (ia64_psr(ia64_task_regs(child))->mfh && ia64_get_fpu_owner() == child) { + ia64_psr(ia64_task_regs(child))->mfh = 0; ia64_set_fpu_owner(0); ia64_save_fpu(&child->thread.fph[0]); child->thread.flags |= IA64_THREAD_FPH_VALID; diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index f4b8ce9dd..f73cd8968 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -156,6 +156,14 @@ ia64_sal_init (struct ia64_sal_systab *systab) struct ia64_sal_desc_platform_feature *pf = (void *) p; printk("SAL: Platform features "); +#ifdef CONFIG_IA64_HAVE_IRQREDIR + /* + * Early versions of SAL say we don't have + * IRQ redirection, even though we do... + */ + pf->feature_mask |= (1 << 1); +#endif + if (pf->feature_mask & (1 << 0)) printk("BusLock "); diff --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c index bc55670bf..1bbe4feab 100644 --- a/arch/ia64/kernel/semaphore.c +++ b/arch/ia64/kernel/semaphore.c @@ -222,9 +222,6 @@ down_read_failed (struct rw_semaphore *sem) void __down_read_failed (struct rw_semaphore *sem, long count) { - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - while (1) { if (count == -1) { down_read_failed_biased(sem); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index fcb4e6190..62e3e19ea 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -122,6 +122,10 @@ setup_arch (char **cmdline_p) */ memcpy(&ia64_boot_param, (void *) ZERO_PAGE_ADDR, sizeof(ia64_boot_param)); + *cmdline_p = __va(ia64_boot_param.command_line); + strncpy(saved_command_line, *cmdline_p, sizeof(saved_command_line)); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; /* for safety */ + efi_init(); max_pfn = 0; @@ -133,19 +137,65 @@ setup_arch (char **cmdline_p) */ bootmap_start = PAGE_ALIGN(__pa(&_end)); if (ia64_boot_param.initrd_size) - bootmap_start = PAGE_ALIGN(bootmap_start + ia64_boot_param.initrd_size); + bootmap_start = PAGE_ALIGN(bootmap_start + + ia64_boot_param.initrd_size); bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn); efi_memmap_walk(free_available_memory, 0); reserve_bootmem(bootmap_start, bootmap_size); + #ifdef CONFIG_BLK_DEV_INITRD initrd_start = ia64_boot_param.initrd_start; + if (initrd_start) { + u64 start, size; +# define is_same_page(a,b) (((a)&PAGE_MASK) == ((b)&PAGE_MASK)) + +#if 1 + /* XXX for now some backwards compatibility... */ + if (initrd_start >= PAGE_OFFSET) + printk("Warning: boot loader passed virtual address " + "for initrd, please upgrade the loader\n"); + } else +#endif + /* + * The loader ONLY passes physical addresses + */ + initrd_start = (unsigned long)__va(initrd_start); initrd_end = initrd_start+ia64_boot_param.initrd_size; + start = initrd_start; + size = ia64_boot_param.initrd_size; + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *) initrd_start, ia64_boot_param.initrd_size); - reserve_bootmem(virt_to_phys(initrd_start), ia64_boot_param.initrd_size); + + /* + * The kernel end and the beginning of initrd can be + * on the same page. This would cause the page to be + * reserved twice. While not harmful, it does lead to + * a warning message which can cause confusion. Thus, + * we make sure that in this case we only reserve new + * pages, i.e., initrd only pages. We need to: + * + * - align up start + * - adjust size of reserved section accordingly + * + * It should be noted that this operation is only + * valid for the reserve_bootmem() call and does not + * affect the integrety of the initrd itself. + * + * reserve_bootmem() considers partial pages as reserved. + */ + if (is_same_page(initrd_start, (unsigned long)&_end)) { + start = PAGE_ALIGN(start); + size -= start-initrd_start; + + printk("Initial ramdisk & kernel on the same page: " + "reserving start=%lx size=%ld bytes\n", + start, size); + } + reserve_bootmem(__pa(start), size); } #endif #if 0 @@ -164,27 +214,21 @@ setup_arch (char **cmdline_p) /* process SAL system table: */ ia64_sal_init(efi.sal_systab); - *cmdline_p = __va(ia64_boot_param.command_line); - strncpy(saved_command_line, *cmdline_p, sizeof(saved_command_line)); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; /* for safety */ - - printk("args to kernel: %s\n", *cmdline_p); - #ifdef CONFIG_SMP bootstrap_processor = hard_smp_processor_id(); current->processor = bootstrap_processor; #endif cpu_init(); /* initialize the bootstrap CPU */ +#ifdef CONFIG_IA64_GENERIC + machvec_init(acpi_get_sysname()); +#endif + if (efi.acpi) { /* Parse the ACPI tables */ acpi_parse(efi.acpi); } -#ifdef CONFIG_IA64_GENERIC - machvec_init(acpi_get_sysname()); -#endif - #ifdef CONFIG_VT # if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con; @@ -197,8 +241,16 @@ setup_arch (char **cmdline_p) /* enable IA-64 Machine Check Abort Handling */ ia64_mca_init(); #endif + paging_init(); platform_setup(cmdline_p); + +#ifdef CONFIG_SWIOTLB + { + extern void setup_swiotlb (void); + setup_swiotlb(); + } +#endif } /* diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index b5153433f..d64305cf3 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -320,6 +320,58 @@ smp_send_flush_tlb(void) #endif /* !CONFIG_ITANIUM_PTCG */ /* + * Run a function on another CPU + * <func> The function to run. This must be fast and non-blocking. + * <info> An arbitrary pointer to pass to the function. + * <retry> If true, keep retrying until ready. + * <wait> If true, wait until function has completed on other CPUs. + * [RETURNS] 0 on success, else a negative status code. + * + * Does not return until the remote CPU is nearly ready to execute <func> + * or is or has executed. + */ + +int +smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int retry, int wait) +{ + struct smp_call_struct data; + long timeout; + int cpus = 1; + + if (cpuid == smp_processor_id()) { + printk(__FUNCTION__" trying to call self\n"); + return -EBUSY; + } + + data.func = func; + data.info = info; + data.wait = wait; + atomic_set(&data.unstarted_count, cpus); + atomic_set(&data.unfinished_count, cpus); + + if (pointer_lock(&smp_call_function_data, &data, retry)) + return -EBUSY; + + /* Send a message to all other CPUs and wait for them to respond */ + send_IPI_single(cpuid, IPI_CALL_FUNC); + + /* Wait for response */ + timeout = jiffies + HZ; + while ((atomic_read(&data.unstarted_count) > 0) && time_before(jiffies, timeout)) + barrier(); + if (atomic_read(&data.unstarted_count) > 0) { + smp_call_function_data = NULL; + return -ETIMEDOUT; + } + if (wait) + while (atomic_read(&data.unfinished_count) > 0) + barrier(); + /* unlock pointer */ + smp_call_function_data = NULL; + return 0; +} + +/* * Run a function on all other CPUs. * <func> The function to run. This must be fast and non-blocking. * <info> An arbitrary pointer to pass to the function. @@ -396,13 +448,19 @@ void smp_do_timer(struct pt_regs *regs) { int cpu = smp_processor_id(); + int user = user_mode(regs); struct cpuinfo_ia64 *data = &cpu_data[cpu]; - if (!--data->prof_counter) { - irq_enter(cpu, TIMER_IRQ); - update_process_times(user_mode(regs)); + if (--data->prof_counter <= 0) { data->prof_counter = data->prof_multiplier; - irq_exit(cpu, TIMER_IRQ); + /* + * update_process_times() expects us to have done irq_enter(). + * Besides, if we don't timer interrupts ignore the global + * interrupt lock, which is the WrongThing (tm) to do. + */ + irq_enter(cpu, 0); + update_process_times(user); + irq_exit(cpu, 0); } } @@ -473,6 +531,11 @@ smp_callin(void) extern void ia64_rid_init(void); extern void ia64_init_itm(void); extern void ia64_cpu_local_tick(void); +#ifdef CONFIG_PERFMON + extern void perfmon_init_percpu(void); +#endif + + efi_map_pal_code(); cpu_init(); @@ -481,6 +544,10 @@ smp_callin(void) /* setup the CPU local timer tick */ ia64_init_itm(); +#ifdef CONFIG_PERFMON + perfmon_init_percpu(); +#endif + /* Disable all local interrupts */ ia64_set_lrr0(0, 1); ia64_set_lrr1(0, 1); diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 95b2b3fc3..96ff76c01 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -150,11 +150,13 @@ do_gettimeofday (struct timeval *tv) static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - static unsigned long last_time; - static unsigned char count; int cpu = smp_processor_id(); unsigned long new_itm; +#if 0 + static unsigned long last_time; + static unsigned char count; int printed = 0; +#endif /* * Here we are in the timer irq handler. We have irqs locally @@ -192,7 +194,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (time_after(new_itm, ia64_get_itc())) break; -#if !(defined(CONFIG_IA64_SOFTSDV_HACKS) && defined(CONFIG_SMP)) +#if 0 /* * SoftSDV in SMP mode is _slow_, so we do "lose" ticks, * but it's really OK... diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 4003b20f1..bf1abd839 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -204,11 +204,13 @@ disabled_fph_fault (struct pt_regs *regs) { struct task_struct *fpu_owner = ia64_get_fpu_owner(); + /* first, clear psr.dfh and psr.mfh: */ regs->cr_ipsr &= ~(IA64_PSR_DFH | IA64_PSR_MFH); if (fpu_owner != current) { ia64_set_fpu_owner(current); if (fpu_owner && ia64_psr(ia64_task_regs(fpu_owner))->mfh) { + ia64_psr(ia64_task_regs(fpu_owner))->mfh = 0; fpu_owner->thread.flags |= IA64_THREAD_FPH_VALID; __ia64_save_fpu(fpu_owner->thread.fph); } @@ -216,6 +218,11 @@ disabled_fph_fault (struct pt_regs *regs) __ia64_load_fpu(current->thread.fph); } else { __ia64_init_fpu(); + /* + * Set mfh because the state in thread.fph does not match + * the state in the fph partition. + */ + ia64_psr(regs)->mfh = 1; } } } diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 739007a96..5d0049f32 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -62,7 +62,7 @@ #define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1) #define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE) -#define UNW_DEBUG 1 +#define UNW_DEBUG 0 #define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */ #if UNW_DEBUG diff --git a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S index 3b16916d0..350e66256 100644 --- a/arch/ia64/lib/memcpy.S +++ b/arch/ia64/lib/memcpy.S @@ -1,3 +1,20 @@ +/* + * + * Optimized version of the standard memcpy() function + * + * Inputs: + * in0: destination address + * in1: source address + * in2: number of bytes to copy + * Output: + * no return value + * + * Copyright (C) 2000 Hewlett-Packard Co + * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> + * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> + */ +#include <linux/config.h> + #include <asm/asmmacro.h> GLOBAL_ENTRY(bcopy) @@ -10,77 +27,254 @@ END(bcopy) // FALL THROUGH GLOBAL_ENTRY(memcpy) -# define MEM_LAT 4 - -# define N MEM_LAT-1 -# define Nrot ((MEM_LAT + 7) & ~7) +# define MEM_LAT 2 /* latency to L1 cache */ # define dst r2 # define src r3 -# define len r9 -# define saved_pfs r10 -# define saved_lc r11 -# define saved_pr r16 -# define t0 r17 -# define cnt r18 +# define retval r8 +# define saved_pfs r9 +# define saved_lc r10 +# define saved_pr r11 +# define cnt r16 +# define src2 r17 +# define t0 r18 +# define t1 r19 +# define t2 r20 +# define t3 r21 +# define t4 r22 +# define src_end r23 +# define N (MEM_LAT + 4) +# define Nrot ((N + 7) & ~7) + + /* + * First, check if everything (src, dst, len) is a multiple of eight. If + * so, we handle everything with no taken branches (other than the loop + * itself) and a small icache footprint. Otherwise, we jump off to + * the more general copy routine handling arbitrary + * sizes/alignment etc. + */ UNW(.prologue) UNW(.save ar.pfs, saved_pfs) alloc saved_pfs=ar.pfs,3,Nrot,0,Nrot +#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) lfetch [in1] +#else + nop.m 0 +#endif + or t0=in0,in1 + ;; - .rotr val[MEM_LAT] - .rotp p[MEM_LAT] - + or t0=t0,in2 UNW(.save ar.lc, saved_lc) mov saved_lc=ar.lc - - or t0=in0,in1 UNW(.save pr, saved_pr) mov saved_pr=pr - UNW(.body) - - mov ar.ec=MEM_LAT + cmp.eq p6,p0=in2,r0 // zero length? + mov retval=in0 // return dst +(p6) br.ret.spnt.many rp // zero length, return immediately + ;; - mov r8=in0 // return dst - shr cnt=in2,3 // number of 8-byte words to copy + mov dst=in0 // copy because of rotation + shr.u cnt=in2,3 // number of 8-byte words to copy mov pr.rot=1<<16 ;; - cmp.eq p6,p0=in2,r0 // zero length? - or t0=t0,in2 -(p6) br.ret.spnt.many rp // yes, return immediately - mov dst=in0 // copy because of rotation - mov src=in1 // copy because of rotation adds cnt=-1,cnt // br.ctop is repeat/until + cmp.gtu p7,p0=16,in2 // copying less than 16 bytes? + UNW(.body) + mov ar.ec=N ;; + and t0=0x7,t0 mov ar.lc=cnt ;; cmp.ne p6,p0=t0,r0 -(p6) br.cond.spnt.few slow_memcpy + mov src=in1 // copy because of rotation +(p7) br.cond.spnt.few memcpy_short +(p6) br.cond.spnt.few memcpy_long + ;; + .rotr val[N] + .rotp p[N] 1: (p[0]) ld8 val[0]=[src],8 -(p[N]) st8 [dst]=val[N],8 - br.ctop.sptk.few 1b +(p[N-1])st8 [dst]=val[N-1],8 + br.ctop.dptk.few 1b ;; -.exit: mov ar.lc=saved_lc - mov pr=saved_pr,0xffffffffffff0000 + mov pr=saved_pr,-1 mov ar.pfs=saved_pfs br.ret.sptk.many rp -slow_memcpy: - adds cnt=-1,in2 + /* + * Small (<16 bytes) unaligned copying is done via a simple byte-at-the-time + * copy loop. This performs relatively poorly on Itanium, but it doesn't + * get used very often (gcc inlines small copies) and due to atomicity + * issues, we want to avoid read-modify-write of entire words. + */ + .align 32 +memcpy_short: + adds cnt=-1,in2 // br.ctop is repeat/until + mov ar.ec=MEM_LAT ;; mov ar.lc=cnt ;; + /* + * It is faster to put a stop bit in the loop here because it makes + * the pipeline shorter (and latency is what matters on short copies). + */ 1: (p[0]) ld1 val[0]=[src],1 -(p[N]) st1 [dst]=val[N],1 - br.ctop.sptk.few 1b - br.sptk.few .exit + ;; +(p[MEM_LAT-1])st1 [dst]=val[MEM_LAT-1],1 + br.ctop.dptk.few 1b + ;; + mov ar.lc=saved_lc + mov pr=saved_pr,-1 + mov ar.pfs=saved_pfs + br.ret.sptk.many rp + + /* + * Large (>= 16 bytes) copying is done in a fancy way. Latency isn't + * an overriding concern here, but throughput is. We first do + * sub-word copying until the destination is aligned, then we check + * if the source is also aligned. If so, we do a simple load/store-loop + * until there are less than 8 bytes left over and then we do the tail, + * by storing the last few bytes using sub-word copying. If the source + * is not aligned, we branch off to the non-congruent loop. + * + * stage: op: + * 0 ld + * : + * MEM_LAT+3 shrp + * MEM_LAT+4 st + * + * On Itanium, the pipeline itself runs without stalls. However, br.ctop + * seems to introduce an unavoidable bubble in the pipeline so the overall + * latency is 2 cycles/iteration. This gives us a _copy_ throughput + * of 4 byte/cycle. Still not bad. + */ +# undef N +# undef Nrot +# define N (MEM_LAT + 5) /* number of stages */ +# define Nrot ((N+1 + 2 + 7) & ~7) /* number of rotating regs */ + +#define LOG_LOOP_SIZE 6 + +memcpy_long: + alloc t3=ar.pfs,3,Nrot,0,Nrot // resize register frame + and t0=-8,src // t0 = src & ~7 + and t2=7,src // t2 = src & 7 + ;; + ld8 t0=[t0] // t0 = 1st source word + adds src2=7,src // src2 = (src + 7) + sub t4=r0,dst // t4 = -dst + ;; + and src2=-8,src2 // src2 = (src + 7) & ~7 + shl t2=t2,3 // t2 = 8*(src & 7) + shl t4=t4,3 // t4 = 8*(dst & 7) + ;; + ld8 t1=[src2] // t1 = 1st source word if src is 8-byte aligned, 2nd otherwise + sub t3=64,t2 // t3 = 64-8*(src & 7) + shr.u t0=t0,t2 + ;; + add src_end=src,in2 + shl t1=t1,t3 + mov pr=t4,0x38 // (p5,p4,p3)=(dst & 7) + ;; + or t0=t0,t1 + mov cnt=r0 + adds src_end=-1,src_end + ;; +(p3) st1 [dst]=t0,1 +(p3) shr.u t0=t0,8 +(p3) adds cnt=1,cnt + ;; +(p4) st2 [dst]=t0,2 +(p4) shr.u t0=t0,16 +(p4) adds cnt=2,cnt + ;; +(p5) st4 [dst]=t0,4 +(p5) adds cnt=4,cnt + and src_end=-8,src_end // src_end = last word of source buffer + ;; + + // At this point, dst is aligned to 8 bytes and there at least 16-7=9 bytes left to copy: + +1:{ add src=cnt,src // make src point to remainder of source buffer + sub cnt=in2,cnt // cnt = number of bytes left to copy + mov t4=ip + } ;; + and src2=-8,src // align source pointer + adds t4=memcpy_loops-1b,t4 + mov ar.ec=N + + and t0=7,src // t0 = src & 7 + shr.u t2=cnt,3 // t2 = number of 8-byte words left to copy + shl cnt=cnt,3 // move bits 0-2 to 3-5 + ;; + + .rotr val[N+1], w[2] + .rotp p[N] + + cmp.ne p6,p0=t0,r0 // is src aligned, too? + shl t0=t0,LOG_LOOP_SIZE // t0 = 8*(src & 7) + adds t2=-1,t2 // br.ctop is repeat/until + ;; + add t4=t0,t4 + mov pr=cnt,0x38 // set (p5,p4,p3) to # of bytes last-word bytes to copy + mov ar.lc=t2 + ;; +(p6) ld8 val[1]=[src2],8 // prime the pump... + mov b6=t4 + br.sptk.few b6 + ;; + +memcpy_tail: + // At this point, (p5,p4,p3) are set to the number of bytes left to copy (which is + // less than 8) and t0 contains the last few bytes of the src buffer: +(p5) st4 [dst]=t0,4 +(p5) shr.u t0=t0,32 + mov ar.lc=saved_lc + ;; +(p4) st2 [dst]=t0,2 +(p4) shr.u t0=t0,16 + mov ar.pfs=saved_pfs + ;; +(p3) st1 [dst]=t0 + mov pr=saved_pr,-1 + br.ret.sptk.many rp + +/////////////////////////////////////////////////////// + .align 64 + +#define COPY(shift,index) \ + 1: \ + { .mfi \ + (p[0]) ld8 val[0]=[src2],8; \ + nop.f 0; \ + (p[MEM_LAT+3]) shrp w[0]=val[MEM_LAT+3],val[MEM_LAT+4-index],shift; \ + }; \ + { .mbb \ + (p[MEM_LAT+4]) st8 [dst]=w[1],8; \ + nop.b 0; \ + br.ctop.dptk.few 1b; \ + }; \ + ;; \ + ld8 val[N-1]=[src_end]; /* load last word (may be same as val[N]) */ \ + ;; \ + shrp t0=val[N-1],val[N-index],shift; \ + br memcpy_tail +memcpy_loops: + COPY(0, 1) /* no point special casing this---it doesn't go any faster without shrp */ + COPY(8, 0) + COPY(16, 0) + COPY(24, 0) + COPY(32, 0) + COPY(40, 0) + COPY(48, 0) + COPY(56, 0) END(memcpy) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 8ddda7e11..3652cfc80 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -185,8 +185,42 @@ free_initmem (void) void free_initrd_mem(unsigned long start, unsigned long end) { + /* + * EFI uses 4KB pages while the kernel can use 4KB or bigger. + * Thus EFI and the kernel may have different page sizes. It is + * therefore possible to have the initrd share the same page as + * the end of the kernel (given current setup). + * + * To avoid freeing/using the wrong page (kernel sized) we: + * - align up the beginning of initrd + * - keep the end untouched + * + * | | + * |=============| a000 + * | | + * | | + * | | 9000 + * |/////////////| + * |/////////////| + * |=============| 8000 + * |///INITRD////| + * |/////////////| + * |/////////////| 7000 + * | | + * |KKKKKKKKKKKKK| + * |=============| 6000 + * |KKKKKKKKKKKKK| + * |KKKKKKKKKKKKK| + * K=kernel using 8KB pages + * + * In this example, we must free page 8000 ONLY. So we must align up + * initrd_start and keep initrd_end as is. + */ + start = PAGE_ALIGN(start); + if (start < end) printk ("Freeing initrd memory: %ldkB freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { clear_bit(PG_reserved, &virt_to_page(start)->flags); set_page_count(virt_to_page(start), 1); @@ -423,5 +457,4 @@ mem_init (void) #ifdef CONFIG_IA32_SUPPORT ia32_gdt_init(); #endif - return; } diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 026f88998..875ce446c 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -1,8 +1,11 @@ /* * TLB support routines. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> + * + * 08/02/00 A. Mallick <asit.k.mallick@intel.com> + * Modified RID allocation for SMP */ #include <linux/config.h> #include <linux/init.h> @@ -27,9 +30,11 @@ 1 << _PAGE_SIZE_8K | \ 1 << _PAGE_SIZE_4K ) -static void wrap_context (struct mm_struct *mm); - -unsigned long ia64_next_context = (1UL << IA64_HW_CONTEXT_BITS) + 1; +struct ia64_ctx ia64_ctx = { + lock: SPIN_LOCK_UNLOCKED, + next: 1, + limit: (1UL << IA64_HW_CONTEXT_BITS) +}; /* * Put everything in a struct so we avoid the global offset table whenever @@ -106,49 +111,43 @@ flush_tlb_no_ptcg (unsigned long start, unsigned long end, unsigned long nbits) #endif /* CONFIG_SMP && !CONFIG_ITANIUM_PTCG */ -void -get_new_mmu_context (struct mm_struct *mm) -{ - if ((ia64_next_context & IA64_HW_CONTEXT_MASK) == 0) { - wrap_context(mm); - } - mm->context = ia64_next_context++; -} - /* - * This is where we handle the case where (ia64_next_context & - * IA64_HW_CONTEXT_MASK) == 0. Whenever this happens, we need to - * flush the entire TLB and skip over region id number 0, which is - * used by the kernel. + * Acquire the ia64_ctx.lock before calling this function! */ -static void -wrap_context (struct mm_struct *mm) +void +wrap_mmu_context (struct mm_struct *mm) { - struct task_struct *task; + struct task_struct *tsk; + unsigned long tsk_context; + + if (ia64_ctx.next >= (1UL << IA64_HW_CONTEXT_BITS)) + ia64_ctx.next = 300; /* skip daemons */ + ia64_ctx.limit = (1UL << IA64_HW_CONTEXT_BITS); /* - * We wrapped back to the first region id so we nuke the TLB - * so we can switch to the next generation of region ids. + * Scan all the task's mm->context and set proper safe range */ - __flush_tlb_all(); - if (ia64_next_context++ == 0) { - /* - * Oops, we've used up all 64 bits of the context - * space---walk through task table to ensure we don't - * get tricked into using an old context. If this - * happens, the machine has been running for a long, - * long time! - */ - ia64_next_context = (1UL << IA64_HW_CONTEXT_BITS) + 1; - read_lock(&tasklist_lock); - for_each_task (task) { - if (task->mm == mm) - continue; - flush_tlb_mm(mm); + read_lock(&tasklist_lock); + repeat: + for_each_task(tsk) { + if (!tsk->mm) + continue; + tsk_context = tsk->mm->context; + if (tsk_context == ia64_ctx.next) { + if (++ia64_ctx.next >= ia64_ctx.limit) { + /* empty range: reset the range limit and start over */ + if (ia64_ctx.next >= (1UL << IA64_HW_CONTEXT_BITS)) + ia64_ctx.next = 300; + ia64_ctx.limit = (1UL << IA64_HW_CONTEXT_BITS); + goto repeat; + } } - read_unlock(&tasklist_lock); + if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit)) + ia64_ctx.limit = tsk_context; } + read_unlock(&tasklist_lock); + flush_tlb_all(); } void diff --git a/arch/ia64/sn/sn1/irq.c b/arch/ia64/sn/sn1/irq.c index df8e56943..a8270fd2a 100644 --- a/arch/ia64/sn/sn1/irq.c +++ b/arch/ia64/sn/sn1/irq.c @@ -1,9 +1,10 @@ #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/irq.h> -#include <asm/irq.h> #include <asm/ptrace.h> -static int +static unsigned int sn1_startup_irq(unsigned int irq) { return(0); @@ -24,23 +25,16 @@ sn1_enable_irq(unsigned int irq) { } -static int -sn1_handle_irq(unsigned int irq, struct pt_regs *regs) -{ - return(0); -} - struct hw_interrupt_type irq_type_sn1 = { "sn1_irq", sn1_startup_irq, sn1_shutdown_irq, - sn1_handle_irq, sn1_enable_irq, sn1_disable_irq }; void -sn1_irq_init (struct irq_desc desc[NR_IRQS]) +sn1_irq_init (void) { int i; diff --git a/arch/ia64/sn/sn1/machvec.c b/arch/ia64/sn/sn1/machvec.c index 2e36b2e08..409d9a2ea 100644 --- a/arch/ia64/sn/sn1/machvec.c +++ b/arch/ia64/sn/sn1/machvec.c @@ -1,4 +1,2 @@ +#define MACHVEC_PLATFORM_NAME sn1 #include <asm/machvec_init.h> -#include <asm/machvec_sn1.h> - -MACHVEC_DEFINE(sn1) diff --git a/arch/ia64/sn/sn1/setup.c b/arch/ia64/sn/sn1/setup.c index 45242fc26..7b397bb6b 100644 --- a/arch/ia64/sn/sn1/setup.c +++ b/arch/ia64/sn/sn1/setup.c @@ -13,6 +13,7 @@ #include <linux/console.h> #include <linux/timex.h> #include <linux/sched.h> +#include <linux/ioport.h> #include <asm/io.h> #include <asm/machvec.h> diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S index 5c199bc1a..c8c13363c 100644 --- a/arch/ia64/vmlinux.lds.S +++ b/arch/ia64/vmlinux.lds.S @@ -46,6 +46,15 @@ SECTIONS { *(__ex_table) } __stop___ex_table = .; +#if defined(CONFIG_IA64_GENERIC) + /* Machine Vector */ + . = ALIGN(16); + machvec_start = .; + .machvec : AT(ADDR(.machvec) - PAGE_OFFSET) + { *(.machvec) } + machvec_end = .; +#endif + __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET) { *(__ksymtab) } diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 7cbb69d03..165809c56 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -629,6 +629,10 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_setgid) .long SYMBOL_NAME(sys_setfsuid) /* 215 */ .long SYMBOL_NAME(sys_setfsgid) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_getdents64) /* 220 */ .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) diff --git a/arch/mips/config.in b/arch/mips/config.in index fdca265d2..5fd3c002e 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -305,6 +305,8 @@ fi if [ "$CONFIG_DECSTATION" != "y" -a \ "$CONFIG_SGI_IP22" != "y" ]; then source drivers/char/Config.in + + source drivers/media/Config.in fi if [ "$CONFIG_DECSTATION" = "y" ]; then @@ -388,6 +390,7 @@ if [ "$CONFIG_SGI_IP22" = "y" ]; then fi source drivers/usb/Config.in +source drivers/input/Config.in mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/mips/defconfig b/arch/mips/defconfig index f1631b04f..18154a1f4 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -114,10 +114,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -338,6 +336,11 @@ CONFIG_SGI_DS1286=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt index 7cfa2345d..627cc710b 100644 --- a/arch/mips/defconfig-cobalt +++ b/arch/mips/defconfig-cobalt @@ -113,13 +113,11 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set CONFIG_IP_MROUTE=y # CONFIG_IP_PIMSM_V1 is not set # CONFIG_IP_PIMSM_V2 is not set -CONFIG_IP_ALIAS=y # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set @@ -266,6 +264,7 @@ CONFIG_NETDEVICES=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -354,6 +353,7 @@ CONFIG_DE_AOC=y # CONFIG_HISAX_NO_LLC is not set # CONFIG_HISAX_NO_KEYPAD is not set CONFIG_HISAX_1TR6=y +# CONFIG_HISAX_NI1 is not set # # HiSax supported cards @@ -375,6 +375,7 @@ CONFIG_HISAX_ELSA=y # CONFIG_HISAX_SPORTSTER is not set # CONFIG_HISAX_MIC is not set # CONFIG_HISAX_NETJET is not set +# CONFIG_HISAX_NETJET_U is not set # CONFIG_HISAX_NICCY is not set # CONFIG_HISAX_ISURF is not set # CONFIG_HISAX_HSTSAPHIR is not set @@ -426,6 +427,10 @@ CONFIG_HISAX_ELSA=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -435,11 +440,6 @@ CONFIG_HISAX_ELSA=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set CONFIG_RTC=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -452,6 +452,11 @@ CONFIG_RTC=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # CONFIG_QUOTA=y @@ -504,6 +509,7 @@ CONFIG_NFS_FS=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m +CONFIG_SMB_NLS_REMOTE="" # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -572,6 +578,11 @@ CONFIG_NLS_UTF8=m # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # # CONFIG_CROSSCOMPILE is not set diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation index 815b3345e..639fdf0a0 100644 --- a/arch/mips/defconfig-decstation +++ b/arch/mips/defconfig-decstation @@ -108,10 +108,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -308,6 +306,11 @@ CONFIG_ULTRIX_PARTITION=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 index 366079a06..9ed1f4c48 100644 --- a/arch/mips/defconfig-ip22 +++ b/arch/mips/defconfig-ip22 @@ -114,10 +114,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -339,6 +337,11 @@ CONFIG_SGI_DS1286=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion index 9828de133..d0315924d 100644 --- a/arch/mips/defconfig-orion +++ b/arch/mips/defconfig-orion @@ -181,6 +181,10 @@ CONFIG_BLK_DEV_INITRD=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -190,11 +194,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -207,6 +206,11 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -279,6 +283,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200 index ccb1f6472..1a55c072d 100644 --- a/arch/mips/defconfig-rm200 +++ b/arch/mips/defconfig-rm200 @@ -116,10 +116,8 @@ CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -214,6 +212,10 @@ CONFIG_VT_CONSOLE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -223,11 +225,6 @@ CONFIG_VT_CONSOLE=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set CONFIG_RTC=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -240,6 +237,11 @@ CONFIG_RTC=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -344,6 +346,11 @@ CONFIG_VGA_CONSOLE=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index e1720d46e..23d59274b 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -234,3 +234,5 @@ SYS(sys_fstat64, 3) /* 4215 */ SYS(sys_pivot_root, 2) SYS(sys_mincore, 3) SYS(sys_madvise, 3) +SYS(sys_getdents64, 3) +SYS(sys_fcntl64, 3) /* 4220 */ diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 90f2f49f4..9b910d4e7 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1622,7 +1622,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs) pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT); if (!(flags & MAP_ANONYMOUS)) { - if (!(file = fcheck(fd))) { + if (!(file = fget(fd))) { error = -EBADF; goto out; } @@ -1847,7 +1847,7 @@ struct irix_dirent32_callback { #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) static int irix_filldir32(void *__buf, const char *name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct irix_dirent32 *dirent; struct irix_dirent32_callback *buf = @@ -1943,7 +1943,7 @@ struct irix_dirent64_callback { #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) static int irix_filldir64(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct irix_dirent64 *dirent; struct irix_dirent64_callback * buf = diff --git a/arch/mips64/config.in b/arch/mips64/config.in index 70e375fed..7bfc0b3a3 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -210,9 +210,10 @@ endmenu source drivers/char/Config.in - #source drivers/misc/Config.in +source drivers/media/Config.in + source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then @@ -247,6 +248,7 @@ if [ "$CONFIG_SGI_IP22" = "y" ]; then fi source drivers/usb/Config.in +source drivers/input/Config.in mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 12937f110..ed5615783 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -98,10 +98,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set @@ -215,6 +213,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -304,6 +303,10 @@ CONFIG_SERIAL_CONSOLE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -313,11 +316,6 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -330,6 +328,11 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -421,6 +424,11 @@ CONFIG_KCORE_ELF=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 index 497b54e17..64471af14 100644 --- a/arch/mips64/defconfig-ip22 +++ b/arch/mips64/defconfig-ip22 @@ -88,10 +88,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set @@ -142,6 +140,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -223,6 +222,10 @@ CONFIG_VT_CONSOLE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -232,11 +235,6 @@ CONFIG_VT_CONSOLE=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -249,6 +247,11 @@ CONFIG_VT_CONSOLE=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -344,6 +347,11 @@ CONFIG_SGI_DS1286=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index 12937f110..ed5615783 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -98,10 +98,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set @@ -215,6 +213,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -304,6 +303,10 @@ CONFIG_SERIAL_CONSOLE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -313,11 +316,6 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -330,6 +328,11 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_DRM is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # File systems # # CONFIG_QUOTA is not set @@ -421,6 +424,11 @@ CONFIG_KCORE_ELF=y # CONFIG_USB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c index 4b85a104b..e40837c3b 100644 --- a/arch/mips64/kernel/linux32.c +++ b/arch/mips64/kernel/linux32.c @@ -1327,9 +1327,11 @@ static inline int put_flock(struct flock *kfl, struct flock32 *ufl) return err; } -extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); +extern asmlinkage long +sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); -asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) +asmlinkage long +sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { switch (cmd) { case F_GETLK: @@ -1340,12 +1342,12 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg mm_segment_t old_fs; long ret; - if(get_flock(&f, (struct flock32 *)arg)) + if (get_flock(&f, (struct flock32 *)arg)) return -EFAULT; old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs (old_fs); - if(put_flock(&f, (struct flock32 *)arg)) + if (put_flock(&f, (struct flock32 *)arg)) return -EFAULT; return ret; } @@ -1354,6 +1356,21 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg } } +asmlinkage long +sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case F_GETLK64: + return sys_fcntl(fd, F_GETLK, arg); + case F_SETLK64: + return sys_fcntl(fd, F_SETLK, arg); + case F_SETLKW64: + return sys_fcntl(fd, F_SETLKW, arg); + } + + return sys32_fcntl(fd, cmd, arg); +} + struct msgbuf32 { s32 mtype; char mtext[1]; }; struct ipc_perm32 diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S index 2e65e1732..637e63aac 100644 --- a/arch/mips64/kernel/scall_64.S +++ b/arch/mips64/kernel/scall_64.S @@ -220,7 +220,7 @@ sys_call_table: PTR sys_uselib PTR sys_swapon PTR sys_reboot - PTR old_readdir + PTR sys_ni_syscall /* old_readdir */ PTR sys_mmap /* 4090 */ PTR sys_munmap PTR sys_truncate @@ -344,3 +344,4 @@ sys_call_table: PTR sys_pivot_root /* 4210 */ PTR sys_mincore PTR sys_madvise + PTR sys_getdents64 diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S index a43fef7bd..5e668a43b 100644 --- a/arch/mips64/kernel/scall_o32.S +++ b/arch/mips64/kernel/scall_o32.S @@ -416,10 +416,12 @@ illegal_syscall: sys sys_ftruncate64 2 sys sys_newstat 3 sys sys_newlstat 3 - sys sys_newfstat 3 /* 4210 */ + sys sys_newfstat 3 /* 4215 */ sys sys_pivot_root 2 sys sys_mincore 3 sys sys_madvise 3 + sys sys_getdents64 3 + sys sys32_fcntl64 3 /* 4220 */ .endm .macro sys function, nargs diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 3e0721cb4..950118eb2 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -263,6 +263,9 @@ source drivers/video/Config.in endmenu source drivers/char/Config.in + +source drivers/media/Config.in + source fs/Config.in mainmenu_option next_comment @@ -284,6 +287,7 @@ source arch/ppc/8260_io/Config.in fi source drivers/usb/Config.in +source drivers/input/Config.in mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 19a218bd4..081dda7f3 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1216,6 +1216,7 @@ _GLOBAL(sys_call_table) .long sys_pciconfig_write /* 199 */ .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ + .long sys_getdents64 /* 202 */ .rept NR_syscalls-201 .long sys_ni_syscall .endr diff --git a/arch/s390/config.in b/arch/s390/config.in index 7835a0162..cdb88b757 100644 --- a/arch/s390/config.in +++ b/arch/s390/config.in @@ -59,6 +59,8 @@ source fs/Config.in # source drivers/char/Config.in +# source drivers/media/Config.in + mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 9913d5967..e39e18623 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -603,7 +603,8 @@ sys_call_table: .long sys_pivot_root .long sys_mincore .long sys_madvise - .rept 255-219 + .long sys_getdents64 /* 220 */ + .rept 255-220 .long sys_ni_syscall .endr diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index c446a1151..90701ad80 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c @@ -8,7 +8,6 @@ * Enable the CF configuration. */ -#include <linux/config.h> #include <linux/init.h> #include <asm/io.h> diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 4e57175e7..7335803da 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1106,6 +1106,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_pivot_root) .long SYMBOL_NAME(sys_mincore) .long SYMBOL_NAME(sys_madvise) + .long SYMBOL_NAME(sys_getdents64) /* 220 */ /* * NOTE!! This doesn't have to be exact - we just have @@ -1113,7 +1114,7 @@ ENTRY(sys_call_table) * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-219 + .rept NR_syscalls-220 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index 27f250f9f..fca718ece 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c @@ -7,7 +7,6 @@ * Also definitions of machine independant IO functions. */ -#include <linux/config.h> #include <asm/io.h> unsigned int _inb(unsigned long port) diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index 9e5793450..c3d195704 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c @@ -13,7 +13,6 @@ * */ -#include <linux/config.h> #include <asm/io.h> #include <asm/machvec.h> diff --git a/arch/sh/kernel/mach_se.c b/arch/sh/kernel/mach_se.c index ce142a399..17b09c5c4 100644 --- a/arch/sh/kernel/mach_se.c +++ b/arch/sh/kernel/mach_se.c @@ -9,6 +9,7 @@ * Machine vector for the Hitachi SolutionEngine */ +#include <linux/config.h> #include <linux/init.h> #include <asm/machvec.h> diff --git a/arch/sh/kernel/mach_unknown.c b/arch/sh/kernel/mach_unknown.c index 895a65c1d..8e91632c4 100644 --- a/arch/sh/kernel/mach_unknown.c +++ b/arch/sh/kernel/mach_unknown.c @@ -9,6 +9,7 @@ * Machine specific code for an unknown machine (internal peripherials only) */ +#include <linux/config.h> #include <linux/init.h> #include <asm/machvec.h> diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c index 3e0422154..ea5dd7ece 100644 --- a/arch/sh/kernel/setup_cqreek.c +++ b/arch/sh/kernel/setup_cqreek.c @@ -8,6 +8,7 @@ * */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> diff --git a/arch/sparc/config.in b/arch/sparc/config.in index e603d2a64..ef948c181 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.100 2000/08/07 18:06:54 anton Exp $ +# $Id: config.in,v 1.102 2000/08/23 05:59:28 davem Exp $ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # @@ -98,7 +98,7 @@ tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD +#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD #if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then # bool ' Boot support' CONFIG_MD_BOOT # bool ' Auto Detect support' CONFIG_AUTODETECT_RAID @@ -202,9 +202,10 @@ if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then tristate ' Dummy net driver support' CONFIG_DUMMY tristate ' Bonding driver support' CONFIG_BONDING + tristate ' Universal TUN/TAP device driver support' CONFIG_TUN if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_NETLINK" = "y" ]; then - tristate ' Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP + tristate ' Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP fi fi tristate ' PPP (point-to-point) support' CONFIG_PPP diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 8bac6f8e3..19c9feba0 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -115,7 +115,6 @@ CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 615445364..c8c79591c 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.59 2000/07/16 18:21:24 ecd Exp $ +# $Id: Makefile,v 1.60 2000/08/12 08:35:53 ecd Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -7,6 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +SH = $(CONFIG_SHELL) + .S.s: $(CPP) $(AFLAGS) -ansi $< -o $*.s diff --git a/arch/sparc/kernel/check_asm.sh b/arch/sparc/kernel/check_asm.sh index 5f1ed770e..65130aa6c 100644 --- a/arch/sparc/kernel/check_asm.sh +++ b/arch/sparc/kernel/check_asm.sh @@ -1,12 +1,12 @@ #!/bin/sh case $1 in -printf) - sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ + sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ /g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/printf ("#define AOFF_'$2'_\0 0x%08x\\n", check_asm_data[i++]); printf("#define ASIZ_'$2'_\0 0x%08x\\n", check_asm_data[i++]);/' >> $4 echo "printf (\"#define ASIZ_$2\\t0x%08x\\n\", check_asm_data[i++]);" >> $4 ;; -data) - sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ + sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ /g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/ ((char *)\&((struct '$2'_struct *)0)->\0) - ((char *)((struct '$2'_struct *)0)), sizeof(((struct '$2'_struct *)0)->\0),/' >> $4 echo " sizeof(struct $2_struct)," >> $4 ;; diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 8e95ce0ed..ac252f55a 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.129 2000/07/10 20:57:35 davem Exp $ +/* $Id: sys_sunos.c,v 1.130 2000/08/12 13:25:41 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -322,7 +322,7 @@ struct sunos_dirent_callback { #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int sunos_filldir(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct sunos_dirent * dirent; struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; @@ -403,7 +403,7 @@ struct sunos_direntry_callback { }; static int sunos_filldirentry(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct sunos_direntry * dirent; struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf; diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 5bb551a46..84daa1bd9 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.97 2000/04/13 00:55:49 davem Exp $ +/* $Id: systbls.S,v 1.99 2000/08/12 20:49:49 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -48,8 +48,8 @@ sys_call_table: /*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 /*140*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit /*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write -/*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall -/*155*/ .long sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount +/*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 +/*155*/ .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall /*165*/ .long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall /*170*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index b0d45d82a..b323ccacd 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.90 2000/08/09 00:00:15 davem Exp $ +/* $Id: init.c,v 1.91 2000/08/09 23:10:19 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -456,8 +456,6 @@ void __init mem_init(void) #endif highmem_start_page = mem_map + highstart_pfn; - /* cache the highmem_mapnr */ - highmem_mapnr = highstart_pfn; /* Saves us work later. */ memset((void *)&empty_zero_page, 0, PAGE_SIZE); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 96fbf1b88..4f5bd16c5 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.220 2000/08/09 00:00:15 davem Exp $ +/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -137,8 +137,8 @@ static inline unsigned long srmmu_pgd_page(pgd_t pgd) static inline unsigned long srmmu_pmd_page(pmd_t pmd) { return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__nocache_va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } -static inline unsigned long srmmu_pte_pagenr(pte_t pte) -{ return srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT); } +static inline struct page *srmmu_pte_page(pte_t pte) +{ return (mem_map + (unsigned long)(srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT))); } static inline int srmmu_pte_none(pte_t pte) { return !(pte_val(pte) & 0xFFFFFFF); } @@ -2153,7 +2153,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1); BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sparc_pte_pagenr, srmmu_pte_pagenr, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_page, srmmu_pte_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 0ce0ca1e8..66bc3af7b 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.197 2000/08/09 00:00:15 davem Exp $ +/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -2156,9 +2156,9 @@ static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot)); } -static unsigned long sun4c_pte_pagenr(pte_t pte) +static struct page *sun4c_pte_page(pte_t pte) { - return (pte_val(pte) & SUN4C_PFN_MASK); + return (mem_map + (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK)); } static inline unsigned long sun4c_pmd_page(pmd_t pmd) @@ -2650,7 +2650,7 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0); - BTFIXUPSET_CALL(sparc_pte_pagenr, sun4c_pte_pagenr, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_page, sun4c_pte_page, BTFIXUPCALL_NORM); #if PAGE_SHIFT <= 12 BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1)); #else diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index c57f14bb1..bfcb973d7 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.119 2000/08/02 10:45:03 davem Exp $ +# $Id: config.in,v 1.121 2000/08/23 05:59:28 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -86,24 +86,29 @@ comment 'Block devices' bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD -bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD -if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then - tristate ' Linear (append) mode' CONFIG_MD_LINEAR - tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED -# tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING -# tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 -fi +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET + +#tristate 'Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM N +#if [ "$CONFIG_BLK_DEV_LVM" != "n" ]; then +# bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y +#fi + +tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD +dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD +dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD +dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD +#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD +#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then +# bool ' Boot support' CONFIG_MD_BOOT +# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID +#fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096 fi -if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then - bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD -fi - -tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP -tristate 'Network block device support' CONFIG_BLK_DEV_NBD +dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM endmenu @@ -231,9 +236,10 @@ if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then tristate ' Dummy net driver support' CONFIG_DUMMY tristate ' Bonding driver support' CONFIG_BONDING + tristate ' Universal TUN/TAP device driver support' CONFIG_TUN if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_NETLINK" = "y" ]; then - tristate ' Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP + tristate ' Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP fi fi tristate ' PPP (point-to-point) support' CONFIG_PPP diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 168109d49..cbbe20614 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -83,6 +83,7 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_FB_PM2=y # CONFIG_FB_PM2_FIFO_DISCONNECT is not set CONFIG_FB_PM2_PCI=y +# CONFIG_FB_CYBER2000 is not set # CONFIG_FB_MATROX is not set CONFIG_FB_ATY=y # CONFIG_FB_ATY128 is not set @@ -135,10 +136,14 @@ CONFIG_SPARCAUDIO_CS4231=y # Block devices # CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_MD is not set -# CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set # # Networking options @@ -449,6 +454,7 @@ CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_SMB_FS=m +CONFIG_SMB_NLS_REMOTE="" # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index c93f2efc8..9bbc2e193 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.61 2000/08/09 08:25:19 jj Exp $ +# $Id: Makefile,v 1.62 2000/08/12 08:35:53 ecd Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -7,6 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +SH = $(CONFIG_SHELL) + .S.s: $(CPP) $(AFLAGS) -ansi $< -o $*.s diff --git a/arch/sparc64/kernel/check_asm.sh b/arch/sparc64/kernel/check_asm.sh index 5f1ed770e..65130aa6c 100644 --- a/arch/sparc64/kernel/check_asm.sh +++ b/arch/sparc64/kernel/check_asm.sh @@ -1,12 +1,12 @@ #!/bin/sh case $1 in -printf) - sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ + sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ /g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/printf ("#define AOFF_'$2'_\0 0x%08x\\n", check_asm_data[i++]); printf("#define ASIZ_'$2'_\0 0x%08x\\n", check_asm_data[i++]);/' >> $4 echo "printf (\"#define ASIZ_$2\\t0x%08x\\n\", check_asm_data[i++]);" >> $4 ;; -data) - sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ + sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\ /g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/ ((char *)\&((struct '$2'_struct *)0)->\0) - ((char *)((struct '$2'_struct *)0)), sizeof(((struct '$2'_struct *)0)->\0),/' >> $4 echo " sizeof(struct $2_struct)," >> $4 ;; diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index d4f499726..84b4224e5 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.96 2000/08/02 06:22:35 davem Exp $ +/* $Id: ioctl32.c,v 1.98 2000/08/16 12:33:00 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -18,11 +18,11 @@ #include <linux/if.h> #include <linux/malloc.h> #include <linux/hdreg.h> -#if 0 /* New RAID code is half-merged... -DaveM */ -#include <linux/md.h> -#endif +#include <linux/raid/md.h> #include <linux/kd.h> #include <linux/route.h> +#include <linux/in6.h> +#include <linux/ipv6_route.h> #include <linux/skbuff.h> #include <linux/netlink.h> #include <linux/vt.h> @@ -648,31 +648,69 @@ struct rtentry32 { }; +struct in6_rtmsg32 { + struct in6_addr rtmsg_dst; + struct in6_addr rtmsg_src; + struct in6_addr rtmsg_gateway; + u32 rtmsg_type; + u16 rtmsg_dst_len; + u16 rtmsg_src_len; + u32 rtmsg_metric; + u32 rtmsg_info; + u32 rtmsg_flags; + s32 rtmsg_ifindex; +}; + +extern struct socket *sockfd_lookup(int fd, int *err); + static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct rtentry r; + int ret; + void *r = NULL; + struct in6_rtmsg r6; + struct rtentry r4; char devname[16]; u32 rtdev; - int ret; mm_segment_t old_fs = get_fs(); - ret = copy_from_user (&r.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr)); - ret |= __get_user (r.rt_flags, &(((struct rtentry32 *)arg)->rt_flags)); - ret |= __get_user (r.rt_metric, &(((struct rtentry32 *)arg)->rt_metric)); - ret |= __get_user (r.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu)); - ret |= __get_user (r.rt_window, &(((struct rtentry32 *)arg)->rt_window)); - ret |= __get_user (r.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt)); - ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev)); - if (rtdev) { - ret |= copy_from_user (devname, (char *)A(rtdev), 15); - r.rt_dev = devname; devname[15] = 0; - } else - r.rt_dev = 0; + struct socket *mysock = sockfd_lookup(fd, &ret); + + if (mysock && mysock->sk && mysock->sk->family == AF_INET6) { /* ipv6 */ + ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst), + 3 * sizeof(struct in6_addr)); + ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type)); + ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len)); + ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len)); + ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric)); + ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info)); + ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags)); + ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex)); + + r = (void *) &r6; + } else { /* ipv4 */ + ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr)); + ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags)); + ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric)); + ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu)); + ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window)); + ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt)); + ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev)); + if (rtdev) { + ret |= copy_from_user (devname, (char *)A(rtdev), 15); + r4.rt_dev = devname; devname[15] = 0; + } else + r4.rt_dev = 0; + + r = (void *) &r4; + } + if (ret) return -EFAULT; + set_fs (KERNEL_DS); - ret = sys_ioctl (fd, cmd, (long)&r); + ret = sys_ioctl (fd, cmd, (long) r); set_fs (old_fs); + return ret; } @@ -3067,17 +3105,27 @@ COMPATIBLE_IOCTL(BLKFRASET) COMPATIBLE_IOCTL(BLKSECTSET) COMPATIBLE_IOCTL(BLKSSZGET) +/* RAID */ +COMPATIBLE_IOCTL(RAID_VERSION) +COMPATIBLE_IOCTL(GET_ARRAY_INFO) +COMPATIBLE_IOCTL(GET_DISK_INFO) +COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) +COMPATIBLE_IOCTL(CLEAR_ARRAY) +COMPATIBLE_IOCTL(ADD_NEW_DISK) +COMPATIBLE_IOCTL(HOT_REMOVE_DISK) +COMPATIBLE_IOCTL(SET_ARRAY_INFO) +COMPATIBLE_IOCTL(SET_DISK_INFO) +COMPATIBLE_IOCTL(WRITE_RAID_INFO) +COMPATIBLE_IOCTL(UNPROTECT_ARRAY) +COMPATIBLE_IOCTL(PROTECT_ARRAY) +COMPATIBLE_IOCTL(HOT_ADD_DISK) +COMPATIBLE_IOCTL(SET_DISK_FAULTY) +COMPATIBLE_IOCTL(RUN_ARRAY) +COMPATIBLE_IOCTL(START_ARRAY) +COMPATIBLE_IOCTL(STOP_ARRAY) +COMPATIBLE_IOCTL(STOP_ARRAY_RO) +COMPATIBLE_IOCTL(RESTART_ARRAY_RW) -#if 0 /* New RAID code is being merged, fix up to handle - * new RAID ioctls when fully merged in 2.3.x -DaveM - */ -/* 0x09 */ -COMPATIBLE_IOCTL(REGISTER_DEV) -COMPATIBLE_IOCTL(REGISTER_DEV_NEW) -COMPATIBLE_IOCTL(START_MD) -COMPATIBLE_IOCTL(STOP_MD) -#endif - /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 5784201e2..21d43bb1e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.110 2000/07/28 09:43:39 davem Exp $ +/* $Id: process.c,v 1.111 2000/08/16 11:13:12 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -65,6 +65,9 @@ int cpu_idle(void) * But this requires writing back the contents of the * L2 cache etc. so implement this later. -DaveM */ + while (!current->need_resched) + barrier(); + schedule(); check_pgt_cache(); } diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 5bb4c8839..c5559ef79 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.91 2000/08/05 13:30:33 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.92 2000/08/09 08:45:40 anton Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -334,3 +334,7 @@ EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memmove); + +void VISenter(void); +/* RAID code needs this */ +EXPORT_SYMBOL(VISenter); diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index e77d8a385..8683b87d7 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.159 2000/08/08 02:47:50 davem Exp $ +/* $Id: sys_sparc32.c,v 1.163 2000/08/22 10:09:10 jj Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -45,6 +45,10 @@ #include <linux/highmem.h> #include <linux/highuid.h> #include <linux/mman.h> +#include <linux/ipv6.h> +#include <linux/in.h> +#include <linux/icmpv6.h> +#include <linux/sysctl.h> #include <asm/types.h> #include <asm/ipc.h> @@ -866,15 +870,27 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs (old_fs); + if (ret) return ret; + if (f.l_start >= 0x7fffffffUL || + f.l_len >= 0x7fffffffUL || + f.l_start + f.l_len >= 0x7fffffffUL) + return -EOVERFLOW; if(put_flock(&f, (struct flock32 *)arg)) return -EFAULT; - return ret; + return 0; } default: return sys_fcntl(fd, cmd, (unsigned long)arg); } } +asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + if (cmd >= F_GETLK64 && cmd <= F_SETLKW64) + return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg); + return sys32_fcntl(fd, cmd, arg); +} + struct dqblk32 { __u32 dqb_bhardlimit; __u32 dqb_bsoftlimit; @@ -1180,7 +1196,7 @@ struct readdir_callback32 { }; static int fillonedir(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; struct old_linux_dirent32 * dirent; @@ -1235,7 +1251,8 @@ struct getdents_callback32 { int error; }; -static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino, + unsigned int d_type) { struct linux_dirent32 * dirent; struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf; @@ -2699,42 +2716,86 @@ out: extern asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen); -asmlinkage int sys32_setsockopt(int fd, int level, int optname, +static int do_set_attach_filter(int fd, int level, int optname, char *optval, int optlen) { - if (optname == SO_ATTACH_FILTER) { - struct sock_fprog32 { - __u16 len; - __u32 filter; - } *fprog32 = (struct sock_fprog32 *)optval; - struct sock_fprog kfprog; - struct sock_filter *kfilter; - unsigned int fsize; - mm_segment_t old_fs; - __u32 uptr; - int ret; + struct sock_fprog32 { + __u16 len; + __u32 filter; + } *fprog32 = (struct sock_fprog32 *)optval; + struct sock_fprog kfprog; + struct sock_filter *kfilter; + unsigned int fsize; + mm_segment_t old_fs; + __u32 uptr; + int ret; - if (get_user(kfprog.len, &fprog32->len) || - __get_user(uptr, &fprog32->filter)) - return -EFAULT; - kfprog.filter = (struct sock_filter *)A(uptr); - fsize = kfprog.len * sizeof(struct sock_filter); - kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL); - if (kfilter == NULL) - return -ENOMEM; - if (copy_from_user(kfilter, kfprog.filter, fsize)) { - kfree(kfilter); - return -EFAULT; - } - kfprog.filter = kfilter; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_setsockopt(fd, level, optname, - (char *)&kfprog, sizeof(kfprog)); - set_fs(old_fs); + if (get_user(kfprog.len, &fprog32->len) || + __get_user(uptr, &fprog32->filter)) + return -EFAULT; + + kfprog.filter = (struct sock_filter *)A(uptr); + fsize = kfprog.len * sizeof(struct sock_filter); + + kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL); + if (kfilter == NULL) + return -ENOMEM; + + if (copy_from_user(kfilter, kfprog.filter, fsize)) { kfree(kfilter); - return ret; + return -EFAULT; + } + + kfprog.filter = kfilter; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_setsockopt(fd, level, optname, + (char *)&kfprog, sizeof(kfprog)); + set_fs(old_fs); + + kfree(kfilter); + + return ret; +} + +static int do_set_icmpv6_filter(int fd, int level, int optname, + char *optval, int optlen) +{ + struct icmp6_filter kfilter; + mm_segment_t old_fs; + int ret, i; + + if (copy_from_user(&kfilter, optval, sizeof(kfilter))) + return -EFAULT; + + + for (i = 0; i < 8; i += 2) { + u32 tmp = kfilter.data[i]; + + kfilter.data[i] = kfilter.data[i + 1]; + kfilter.data[i + 1] = tmp; } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_setsockopt(fd, level, optname, + (char *) &kfilter, sizeof(kfilter)); + set_fs(old_fs); + + return ret; +} + +asmlinkage int sys32_setsockopt(int fd, int level, int optname, + char *optval, int optlen) +{ + if (optname == SO_ATTACH_FILTER) + return do_set_attach_filter(fd, level, optname, + optval, optlen); + if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER) + return do_set_icmpv6_filter(fd, level, optname, + optval, optlen); + return sys_setsockopt(fd, level, optname, optval, optlen); } @@ -4101,3 +4162,51 @@ asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval) (int) who, (int) niceval); } + +struct __sysctl_args32 { + u32 name; + int nlen; + u32 oldval; + u32 oldlenp; + u32 newval; + u32 newlen; + u32 __unused[4]; +}; + +extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) +{ + struct __sysctl_args32 tmp; + int error; + size_t oldlen, *oldlenp = NULL; + unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; + + if (copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; + + if (tmp.oldval && tmp.oldlenp) { + /* Duh, this is ugly and might not work if sysctl_args + is in read-only memory, but do_sysctl does indirectly + a lot of uaccess in both directions and we'd have to + basically copy the whole sysctl.c here, and + glibc's __sysctl uses rw memory for the structure + anyway. */ + if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || + put_user(oldlen, (size_t *)addr)) + return -EFAULT; + oldlenp = (size_t *)addr; + } + + lock_kernel(); + error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), + oldlenp, (void *)A(tmp.newval), tmp.newlen); + unlock_kernel(); + if (oldlenp) { + if (!error) { + if (get_user(oldlen, (size_t *)addr) || + put_user(oldlen, (u32 *)A(tmp.oldlenp))) + error = -EFAULT; + } + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); + } + return error; +} diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 9015a2fec..75d5c096e 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.53 2000/07/30 23:12:24 davem Exp $ +/* $Id: sys_sunos32.c,v 1.54 2000/08/12 13:25:41 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -277,7 +277,7 @@ struct sunos_dirent_callback { #define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1)) static int sunos_filldir(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct sunos_dirent * dirent; struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; @@ -359,7 +359,7 @@ struct sunos_direntry_callback { }; static int sunos_filldirentry(void * __buf, const char * name, int namlen, - off_t offset, ino_t ino) + off_t offset, ino_t ino, unsigned int d_type) { struct sunos_direntry * dirent; struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf; diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index f73486541..335313796 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.74 2000/07/13 10:59:13 davem Exp $ +/* $Id: systbls.S,v 1.77 2000/08/22 10:09:10 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -49,8 +49,8 @@ sys_call_table32: .word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64 /*140*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit .word sys32_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write -/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall - .word sys_nis_syscall, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount +/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 + .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount /*160*/ .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall .word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall /*170*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents @@ -69,7 +69,7 @@ sys_call_table32: .word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep -/*250*/ .word sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl +/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl .word sys_aplib /* Now the 64-bit native Linux syscall table. */ @@ -108,7 +108,7 @@ sys_call_table: .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_nis_syscall /*140*/ .word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_nis_syscall, sys_getrlimit .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write -/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall +/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount /*160*/ .word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install .word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S index 75dfdbfcf..2a59b2788 100644 --- a/arch/sparc64/lib/dec_and_lock.S +++ b/arch/sparc64/lib/dec_and_lock.S @@ -1,4 +1,4 @@ -/* $Id: dec_and_lock.S,v 1.1 2000/07/10 20:57:34 davem Exp $ +/* $Id: dec_and_lock.S,v 1.2 2000/08/13 18:24:12 davem Exp $ * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" * using cas and ldstub instructions. * @@ -17,12 +17,10 @@ * TMP = *(MEM); * *(MEM) = REG2; * REG2 = TMP; - * } + * } else + * REG2 = *(MEM); * END_ATOMIC(); * } - * - * All non-contention cases are handled in 2 I-cache - * lines which is 1 L2 cache line. */ .globl atomic_dec_and_lock @@ -42,20 +40,24 @@ to_zero:ldstub [%o1], %g3 brnz,pn %g3, spin_on_lock membar #StoreLoad | #StoreStore loop2: cas [%o0], %g5, %g7 /* ASSERT(g7 == 0) */ - brnz,pt %g7, out - mov 1, %g1 + nop + cmp %g5, %g7 + be,pt %icc, out + mov 1, %g1 lduw [%o0], %g5 subcc %g5, 1, %g7 be,pn %icc, loop2 nop membar #StoreStore | #LoadStore stb %g0, [%o1] + b,pt %xcc, nzero nop - spin_on_lock: ldub [%o1], %g3 brnz,pt %g3, spin_on_lock membar #LoadLoad - b,a,pt %xcc, to_zero + ba,pt %xcc, to_zero + nop + nop diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 8c9b7c9fd..9ebe1f494 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.49 2000/08/09 00:00:15 davem Exp $ +/* $Id: fault.c,v 1.50 2000/08/11 03:00:13 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -42,7 +42,7 @@ unsigned long __init prom_probe_memory (void) sp_banks[0].base_addr = base_paddr; sp_banks[0].num_bytes = bytes; - while (mlist->theres_more != (void *) 0){ + while (mlist->theres_more != (void *) 0) { i++; mlist = mlist->theres_more; bytes = mlist->num_bytes; @@ -68,7 +68,7 @@ unsigned long __init prom_probe_memory (void) /* Now mask all bank sizes on a page boundary, it is all we can * use anyways. */ - for(i=0; sp_banks[i].num_bytes != 0; i++) + for (i = 0; sp_banks[i].num_bytes != 0; i++) sp_banks[i].num_bytes &= PAGE_MASK; return tally; @@ -77,7 +77,7 @@ unsigned long __init prom_probe_memory (void) void unhandled_fault(unsigned long address, struct task_struct *tsk, struct pt_regs *regs) { - if((unsigned long) address < PAGE_SIZE) { + if ((unsigned long) address < PAGE_SIZE) { printk(KERN_ALERT "Unable to handle kernel NULL " "pointer dereference\n"); } else { @@ -100,17 +100,17 @@ static unsigned int get_user_insn(unsigned long tpc) unsigned long pa; u32 insn = 0; - if(pgd_none(*pgdp)) + if (pgd_none(*pgdp)) goto out; pmdp = pmd_offset(pgdp, tpc); - if(pmd_none(*pmdp)) + if (pmd_none(*pmdp)) goto out; ptep = pte_offset(pmdp, tpc); pte = *ptep; - if(!pte_present(pte)) + if (!pte_present(pte)) goto out; - pa = phys_base + (sparc64_pte_pagenr(pte) << PAGE_SHIFT); + pa = (pte_val(pte) & _PAGE_PADDR); pa += (tpc & ~PAGE_MASK); /* Use phys bypass so we don't pollute dtlb/dcache. */ diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 5d711d576..a7edd1876 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.28 2000/07/06 01:41:30 davem Exp $ +/* $Id: misc.c,v 1.29 2000/08/14 23:50:31 anton Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -20,7 +20,6 @@ #include <asm/string.h> #include <asm/oplib.h> #include <asm/idprom.h> -#include <asm/machines.h> #include "conv.h" @@ -179,26 +178,7 @@ static char *machine(void) static char *platform(char *buffer) { - int i, len; - struct { - char *platform; - int id_machtype; - } platforms [] = { - { "sun4", (SM_SUN4 | SM_4_110) }, - { "sun4", (SM_SUN4 | SM_4_260) }, - { "sun4", (SM_SUN4 | SM_4_330) }, - { "sun4", (SM_SUN4 | SM_4_470) }, - { "SUNW,Sun_4_60", (SM_SUN4C | SM_4C_SS1) }, - { "SUNW,Sun_4_40", (SM_SUN4C | SM_4C_IPC) }, - { "SUNW,Sun_4_65", (SM_SUN4C | SM_4C_SS1PLUS) }, - { "SUNW,Sun_4_20", (SM_SUN4C | SM_4C_SLC) }, - { "SUNW,Sun_4_75", (SM_SUN4C | SM_4C_SS2) }, - { "SUNW,Sun_4_25", (SM_SUN4C | SM_4C_ELC) }, - { "SUNW,Sun_4_50", (SM_SUN4C | SM_4C_IPX) }, - { "SUNW,Sun_4_600", (SM_SUN4M | SM_4M_SS60) }, - { "SUNW,SPARCstation-5", (SM_SUN4M | SM_4M_SS50) }, - { "SUNW,SPARCstation-20", (SM_SUN4M | SM_4M_SS40) } - }; + int len; *buffer = 0; len = prom_getproperty(prom_root_node, "name", buffer, 256); @@ -211,10 +191,8 @@ static char *platform(char *buffer) if (*p == '/' || *p == ' ') *p = '_'; return buffer; } - for (i = 0; i < sizeof (platforms)/sizeof (platforms[0]); i++) - if (platforms[i].id_machtype == idprom->id_machtype) - return platforms[i].platform; - return "sun4c"; + + return "sun4u"; } static char *serial(char *buffer) diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c index b9db00918..3013d43cf 100644 --- a/arch/sparc64/solaris/socket.c +++ b/arch/sparc64/solaris/socket.c @@ -1,4 +1,4 @@ -/* $Id: socket.c,v 1.2 1999/09/22 09:28:50 davem Exp $ +/* $Id: socket.c,v 1.3 2000/08/14 23:50:31 anton Exp $ * socket.c: Socket syscall emulation for Solaris 2.6+ * * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) @@ -18,7 +18,6 @@ #include <asm/string.h> #include <asm/oplib.h> #include <asm/idprom.h> -#include <asm/machines.h> #include "conv.h" |