summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
commit1a1d77dd589de5a567fa95e36aa6999c704ceca4 (patch)
tree141e31f89f18b9fe0831f31852e0435ceaccafc5 /arch
parentfb9c690a18b3d66925a65b17441c37fa14d4370b (diff)
Merge with 2.4.0-test7.
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in4
-rw-r--r--arch/alpha/kernel/entry.S1
-rw-r--r--arch/alpha/kernel/osf_sys.c3
-rw-r--r--arch/alpha/kernel/time.c33
-rw-r--r--arch/arm/Makefile77
-rw-r--r--arch/arm/boot/Makefile90
-rw-r--r--arch/arm/boot/bootp/Makefile26
-rw-r--r--arch/arm/boot/bootp/init.S57
-rw-r--r--arch/arm/boot/compressed/Makefile55
-rw-r--r--arch/arm/boot/compressed/head-l7200.S30
-rw-r--r--arch/arm/boot/compressed/head-netwinder.S38
-rw-r--r--arch/arm/boot/compressed/head-sa1100.S28
-rw-r--r--arch/arm/boot/compressed/head.S29
-rw-r--r--arch/arm/boot/compressed/hw-bse.c74
-rw-r--r--arch/arm/boot/compressed/setup-sa1100.S26
-rw-r--r--arch/arm/config.in92
-rw-r--r--arch/arm/kernel/Makefile11
-rw-r--r--arch/arm/kernel/arch.c56
-rw-r--r--arch/arm/kernel/armksyms.c10
-rw-r--r--arch/arm/kernel/bios32.c33
-rw-r--r--arch/arm/kernel/calls.S3
-rw-r--r--arch/arm/kernel/debug-armv.S8
-rw-r--r--arch/arm/kernel/dec21285.c2
-rw-r--r--arch/arm/kernel/dma-arc.c1
-rw-r--r--arch/arm/kernel/dma-rpc.c2
-rw-r--r--arch/arm/kernel/dma.c25
-rw-r--r--arch/arm/kernel/ecard.c25
-rw-r--r--arch/arm/kernel/entry-armo.S18
-rw-r--r--arch/arm/kernel/entry-armv.S16
-rw-r--r--arch/arm/kernel/entry-common.S24
-rw-r--r--arch/arm/kernel/fiq.c7
-rw-r--r--arch/arm/kernel/head-armo.S87
-rw-r--r--arch/arm/kernel/head-armv.S44
-rw-r--r--arch/arm/kernel/hw-footbridge.c2
-rw-r--r--arch/arm/kernel/hw-sa1100.c35
-rw-r--r--arch/arm/kernel/irq.c16
-rw-r--r--arch/arm/kernel/leds-footbridge.c19
-rw-r--r--arch/arm/kernel/leds-sa1100.c106
-rw-r--r--arch/arm/kernel/oldlatches.c5
-rw-r--r--arch/arm/kernel/process.c5
-rw-r--r--arch/arm/kernel/semaphore.c131
-rw-r--r--arch/arm/kernel/setup.c14
-rw-r--r--arch/arm/kernel/signal.c131
-rw-r--r--arch/arm/kernel/traps.c4
-rw-r--r--arch/arm/lib/Makefile5
-rw-r--r--arch/arm/lib/uaccess.S54
-rw-r--r--arch/arm/mm/Makefile9
-rw-r--r--arch/arm/mm/init.c46
-rw-r--r--arch/arm/mm/mm-footbridge.c40
-rw-r--r--arch/arm/mm/mm-l7200.c4
-rw-r--r--arch/arm/mm/mm-sa1100.c46
-rw-r--r--arch/arm/mm/proc-arm720.S51
-rw-r--r--arch/arm/mm/proc-sa110.S2
-rw-r--r--arch/arm/nwfpe/Makefile2
-rw-r--r--arch/arm/tools/gen-mach-types73
-rw-r--r--arch/arm/tools/mach-types44
-rw-r--r--arch/i386/Makefile4
-rw-r--r--arch/i386/config.in17
-rw-r--r--arch/i386/defconfig28
-rw-r--r--arch/i386/kernel/apic.c112
-rw-r--r--arch/i386/kernel/entry.S5
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/mca.c101
-rw-r--r--arch/i386/kernel/microcode.c2
-rw-r--r--arch/i386/kernel/mpparse.c4
-rw-r--r--arch/i386/kernel/setup.c69
-rw-r--r--arch/i386/kernel/smpboot.c45
-rw-r--r--arch/ia64/config.in30
-rw-r--r--arch/ia64/dig/iosapic.c57
-rw-r--r--arch/ia64/dig/machvec.c4
-rw-r--r--arch/ia64/dig/setup.c4
-rw-r--r--arch/ia64/hp/hpsim_machvec.c4
-rw-r--r--arch/ia64/ia32/ia32_entry.S58
-rw-r--r--arch/ia64/ia32/sys_ia32.c424
-rw-r--r--arch/ia64/kernel/Makefile4
-rw-r--r--arch/ia64/kernel/acpi.c46
-rw-r--r--arch/ia64/kernel/efi.c47
-rw-r--r--arch/ia64/kernel/entry.S18
-rw-r--r--arch/ia64/kernel/head.S73
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c2
-rw-r--r--arch/ia64/kernel/irq_ia64.c7
-rw-r--r--arch/ia64/kernel/ivt.S65
-rw-r--r--arch/ia64/kernel/machvec.c15
-rw-r--r--arch/ia64/kernel/pal.S54
-rw-r--r--arch/ia64/kernel/palinfo.c443
-rw-r--r--arch/ia64/kernel/pci-dma.c503
-rw-r--r--arch/ia64/kernel/perfmon.c148
-rw-r--r--arch/ia64/kernel/process.c40
-rw-r--r--arch/ia64/kernel/ptrace.c1
-rw-r--r--arch/ia64/kernel/sal.c8
-rw-r--r--arch/ia64/kernel/semaphore.c3
-rw-r--r--arch/ia64/kernel/setup.c76
-rw-r--r--arch/ia64/kernel/smp.c75
-rw-r--r--arch/ia64/kernel/time.c8
-rw-r--r--arch/ia64/kernel/traps.c7
-rw-r--r--arch/ia64/kernel/unwind.c2
-rw-r--r--arch/ia64/lib/memcpy.S264
-rw-r--r--arch/ia64/mm/init.c35
-rw-r--r--arch/ia64/mm/tlb.c77
-rw-r--r--arch/ia64/sn/sn1/irq.c14
-rw-r--r--arch/ia64/sn/sn1/machvec.c4
-rw-r--r--arch/ia64/sn/sn1/setup.c1
-rw-r--r--arch/ia64/vmlinux.lds.S9
-rw-r--r--arch/m68k/kernel/entry.S4
-rw-r--r--arch/mips/config.in3
-rw-r--r--arch/mips/defconfig7
-rw-r--r--arch/mips/defconfig-cobalt25
-rw-r--r--arch/mips/defconfig-decstation7
-rw-r--r--arch/mips/defconfig-ip227
-rw-r--r--arch/mips/defconfig-orion19
-rw-r--r--arch/mips/defconfig-rm20021
-rw-r--r--arch/mips/kernel/syscalls.h2
-rw-r--r--arch/mips/kernel/sysirix.c6
-rw-r--r--arch/mips64/config.in4
-rw-r--r--arch/mips64/defconfig22
-rw-r--r--arch/mips64/defconfig-ip2222
-rw-r--r--arch/mips64/defconfig-ip2722
-rw-r--r--arch/mips64/kernel/linux32.c25
-rw-r--r--arch/mips64/kernel/scall_64.S3
-rw-r--r--arch/mips64/kernel/scall_o32.S4
-rw-r--r--arch/ppc/config.in4
-rw-r--r--arch/ppc/kernel/misc.S1
-rw-r--r--arch/s390/config.in2
-rw-r--r--arch/s390/kernel/entry.S3
-rw-r--r--arch/sh/kernel/cf-enabler.c1
-rw-r--r--arch/sh/kernel/entry.S3
-rw-r--r--arch/sh/kernel/io.c1
-rw-r--r--arch/sh/kernel/io_generic.c1
-rw-r--r--arch/sh/kernel/mach_se.c1
-rw-r--r--arch/sh/kernel/mach_unknown.c1
-rw-r--r--arch/sh/kernel/setup_cqreek.c1
-rw-r--r--arch/sparc/config.in7
-rw-r--r--arch/sparc/defconfig1
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/check_asm.sh4
-rw-r--r--arch/sparc/kernel/sys_sunos.c6
-rw-r--r--arch/sparc/kernel/systbls.S6
-rw-r--r--arch/sparc/mm/init.c4
-rw-r--r--arch/sparc/mm/srmmu.c8
-rw-r--r--arch/sparc/mm/sun4c.c8
-rw-r--r--arch/sparc64/config.in36
-rw-r--r--arch/sparc64/defconfig10
-rw-r--r--arch/sparc64/kernel/Makefile4
-rw-r--r--arch/sparc64/kernel/check_asm.sh4
-rw-r--r--arch/sparc64/kernel/ioctl32.c106
-rw-r--r--arch/sparc64/kernel/process.c5
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c6
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c179
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c6
-rw-r--r--arch/sparc64/kernel/systbls.S10
-rw-r--r--arch/sparc64/lib/dec_and_lock.S20
-rw-r--r--arch/sparc64/mm/fault.c16
-rw-r--r--arch/sparc64/solaris/misc.c30
-rw-r--r--arch/sparc64/solaris/socket.c3
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 = (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(&current->blocked);
- sigemptyset(&current->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(&current->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"