From c7fc24dc4420057f103afe8fc64524ebc25c5d37 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 25 Aug 1998 09:12:35 +0000 Subject: o Merge with Linux 2.1.116. o New Newport console code. o New G364 console code. --- arch/arm/Makefile | 158 ++++++++++--------- arch/arm/boot/compressed/Makefile.debug | 13 +- arch/arm/boot/compressed/head-nexuspci.S | 96 ++++++------ arch/arm/boot/compressed/head.S | 13 +- arch/arm/boot/compressed/misc.c | 6 +- arch/arm/boot/tools/.cvsignore | 2 + arch/arm/config.in | 130 +++++++++------- arch/arm/defconfig | 2 - arch/arm/kernel/Makefile | 25 +-- arch/arm/kernel/armksyms.c | 54 +++---- arch/arm/kernel/bios32.c | 144 ------------------ arch/arm/kernel/calls.S | 21 ++- arch/arm/kernel/dec21285.c | 157 +++++++++++++++++++ arch/arm/kernel/dma-a5k.c | 44 +++--- arch/arm/kernel/dma-dummy.c | 31 +--- arch/arm/kernel/dma-rpc.c | 7 + arch/arm/kernel/dma.c | 12 ++ arch/arm/kernel/entry-armo.S | 27 ++-- arch/arm/kernel/entry-armv.S | 87 ++++++++++- arch/arm/kernel/entry-common.S | 44 +++++- arch/arm/kernel/head-armv.S | 74 +++++++-- arch/arm/kernel/iic.c | 3 +- arch/arm/kernel/irq.c | 76 ++++++--- arch/arm/kernel/process.c | 36 ++--- arch/arm/kernel/setup-ebsa110.c | 27 +++- arch/arm/kernel/setup.c | 198 +++++++++++++++--------- arch/arm/kernel/signal.c | 7 +- arch/arm/kernel/sys_arm.c | 20 ++- arch/arm/kernel/time.c | 2 +- arch/arm/kernel/traps.c | 117 +++++++++----- arch/arm/lib/Makefile | 4 +- arch/arm/lib/backtrace.S | 5 + arch/arm/lib/checksum.S | 254 +++++++++++++++++++++++-------- arch/arm/lib/extractconstants.pl | 6 +- arch/arm/lib/getconsdata.c | 4 +- arch/arm/lib/io-acorn.S | 5 +- arch/arm/lib/io-ebsa285.S | 43 +++++- arch/arm/lib/io.c | 43 ++++++ arch/arm/lib/ll_char_wr.S | 28 ++-- arch/arm/lib/memfastset.S | 35 ----- arch/arm/lib/string.S | 53 +++++-- arch/arm/lib/uaccess.S | 1 - arch/arm/mm/Makefile | 12 +- arch/arm/mm/fault-armo.c | 25 ++- arch/arm/mm/fault-armv.c | 2 + arch/arm/mm/init.c | 22 ++- arch/arm/mm/mm-arc.c | 76 ++++++++- arch/arm/mm/mm-armv.c | 71 +++++++++ arch/arm/mm/mm-ebsa110.c | 23 +-- arch/arm/mm/mm-ebsa285.c | 128 +++++++--------- arch/arm/mm/mm-nexuspci.c | 31 ++-- arch/arm/mm/mm-rpc.c | 56 +------ arch/arm/mm/mm-tbox.c | 56 +++++++ arch/arm/mm/mm-vnc.c | 32 ++++ arch/arm/mm/proc-arm2,3.S | 12 +- arch/arm/mm/proc-arm6,7.S | 12 +- arch/arm/vmlinux-armo.lds | 63 ++++++++ arch/arm/vmlinux-armv.lds | 63 ++++++++ arch/arm/vmlinux.lds | 63 -------- 59 files changed, 1864 insertions(+), 997 deletions(-) create mode 100644 arch/arm/boot/tools/.cvsignore delete mode 100644 arch/arm/kernel/bios32.c create mode 100644 arch/arm/kernel/dec21285.c create mode 100644 arch/arm/lib/io.c delete mode 100644 arch/arm/lib/memfastset.S create mode 100644 arch/arm/mm/mm-armv.c create mode 100644 arch/arm/mm/mm-tbox.c create mode 100644 arch/arm/mm/mm-vnc.c create mode 100644 arch/arm/vmlinux-armo.lds create mode 100644 arch/arm/vmlinux-armv.lds delete mode 100644 arch/arm/vmlinux.lds (limited to 'arch/arm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0c39121be..201442d04 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -12,52 +12,58 @@ # # Copyright (C) 1995, 1996 by Russell King -CFLAGS_PROC := -ASFLAGS_PROC := - -ifeq ($(CONFIG_CPU_ARM2),y) -PROCESSOR = armo -ASFLAGS_PROC += -m2 -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mcpu=arm2 -ASFLAGS_PROC += -m2 -else -CFLAGS_PROC += -m2 -ASFLAGS_PROC += -m2 -endif -endif - -ifeq ($(CONFIG_CPU_ARM3),y) -PROCESSOR = armo -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mcpu=arm3 -ASFLAGS_PROC += -m3 -else -CFLAGS_PROC += -m3 -ASFLAGS_PROC += -m3 -endif -endif - -ifeq ($(CONFIG_CPU_ARM6),y) -PROCESSOR = armv -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mcpu=arm6 -ASFLAGS_PROC += -m6 -else -CFLAGS_PROC += -m6 -ASFLAGS_PROC += -m6 -endif -endif - -ifeq ($(CONFIG_CPU_SA110),y) -PROCESSOR = armv -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mcpu=strongarm110 -ASFLAGS_PROC += -m6 -else -CFLAGS_PROC += -m6 -ASFLAGS_PROC += -m6 -endif +CFLAGS_PROC := +ASFLAGS_PROC := + +# All processors get `-mshort-load-bytes' for now, to work around alignment +# problems. This is more of a hack that just happens to work than a real fix +# but it will do for now. + +ifeq ($(CONFIG_CPU_26),y) + PROCESSOR = armo + TEXTADDR = 0x02080000 + ZTEXTADDR = 0x01800000 + ZRELADDR = 0x02080000 + ifeq ($(CONFIG_BINUTILS_NEW),y) + CFLAGS_PROC += -mapcs-26 -mshort-load-bytes + ifeq ($(CONFIG_CPU_ARM2),y) + CFLAGS_PROC += -mcpu=arm2 + ASFLAGS_PROC += -m2 + endif + ifeq ($(CONFIG_CPU_ARM3),y) + CFLAGS_PROC += -mcpu=arm3 + ASFLAGS_PROC += -m3 + endif + else + ifeq ($(CONFIG_CPU_ARM2),y) + CFLAGS_PROC += -m2 + ASFLAGS_PROC += -m2 + endif + ifeq ($(CONFIG_CPU_ARM3),y) + CFLAGS_PROC += -m3 + ASFLAGS_PROC += -m3 + endif + endif +endif + +ifeq ($(CONFIG_CPU_32),y) + PROCESSOR = armv + TEXTADDR = 0xC0008000 + ifeq ($(CONFIG_BINUTILS_NEW),y) + CFLAGS_PROC += -mapcs-32 -mshort-load-bytes + ifeq ($(CONFIG_CPU_ARM6),y) + CFLAGS_PROC += -mcpu=arm6 + endif + ifeq ($(CONFIG_CPU_ARM7),y) + CFLAGS_PROC += -mcpu=arm7 + endif + ifeq ($(CONFIG_CPU_SA110),y) + CFLAGS_PROC += -mcpu=strongarm110 + endif + else + CFLAGS_PROC += -m6 + endif + ASFLAGS_PROC += -m6 endif # Processor Architecture @@ -70,15 +76,6 @@ endif COMPRESSED_HEAD = head.o -ifeq ($(PROCESSOR),armo) -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mapcs-26 -mshort-load-bytes -endif -TEXTADDR = 0x02080000 -ZTEXTADDR = 0x01800000 -ZRELADDR = 0x02080000 -endif - ifeq ($(CONFIG_ARCH_A5K),y) MACHINE = a5k ARCHDIR = arc @@ -91,13 +88,6 @@ ARCHDIR = arc COMPRESSED_EXTRA = $(TOPDIR)/arch/arm/lib/ll_char_wr.o endif -ifeq ($(PROCESSOR),armv) -ifeq ($(CONFIG_BINUTILS_NEW),y) -CFLAGS_PROC += -mapcs-32 -mshort-load-bytes -endif -TEXTADDR = 0xC0008000 -endif - ifeq ($(CONFIG_ARCH_RPC),y) MACHINE = rpc ARCHDIR = rpc @@ -122,44 +112,65 @@ endif ifeq ($(CONFIG_ARCH_NEXUSPCI),y) MACHINE = nexuspci -TEXTADDR = 0xc0000000 +ARCHDIR = nexuspci ZTEXTADDR = 0x40200000 -ZRELADDR = 0x40000000 +ZRELADDR = 0x40008000 COMPRESSED_EXTRA = $(TOPDIR)/arch/arm/lib/ll_char_wr_scc.o COMPRESSED_HEAD = head-nexuspci.o endif -OBJDUMP = $(CROSS_COMPILE)objdump +ifeq ($(CONFIG_ARCH_VNC),y) +MACHINE = vnc +ARCHDIR = vnc +endif + +ifeq ($(CONFIG_ARCH_TBOX),y) +MACHINE = tbox +ARCHDIR = tbox +ZTEXTADDR = 0x80008000 +ZRELDIR = 0x80008000 +endif + PERL = perl +ifeq ($(CONFIG_BINUTILS_NEW),y) +LD = $(CROSS_COMPILE)ld -m elf32arm +else LD = $(CROSS_COMPILE)ld -m elf_arm -CPP = $(CC) -E +endif OBJCOPY = $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S +OBJDUMP = $(CROSS_COMPILE)objdump +CPP = $(CC) -E ARCHCC := $(word 1,$(CC)) GCCLIB := `$(ARCHCC) $(CFLAGS_PROC) --print-libgcc-file-name` -GCCARCH := -B/usr/src/bin/arm/arm-linuxelf- +#GCCARCH := -B/usr/bin/arm-linuxelf- HOSTCFLAGS := $(CFLAGS:-fomit-frame-pointer=) ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS := $(CFLAGS:-fomit-frame-pointer=) endif CFLAGS := $(CFLAGS_PROC) $(CFLAGS) -pipe ASFLAGS := $(ASFLAGS_PROC) $(ASFLAGS) -LINKFLAGS = -T $(TOPDIR)/arch/arm/vmlinux.lds -e stext -Ttext $(TEXTADDR) +LINKFLAGS = -T $(TOPDIR)/arch/arm/vmlinux-$(PROCESSOR).lds -e stext -Ttext $(TEXTADDR) ZLINKFLAGS = -Ttext $(ZTEXTADDR) -SUBDIRS := $(SUBDIRS:drivers=) arch/arm/lib arch/arm/kernel arch/arm/mm arch/arm/drivers +SUBDIRS := $(SUBDIRS:drivers=arch/arm/drivers) arch/arm/lib arch/arm/kernel arch/arm/mm HEAD := arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) LIBS := arch/arm/lib/lib.a $(LIBS) $(GCCLIB) BLOCK_DRIVERS := arch/arm/drivers/block/block.a CDROM_DRIVERS := drivers/cdrom/cdrom.a +ifeq ($(CONFIG_FB),y) +CHAR_DRIVERS := arch/arm/drivers/char1/char.a +else CHAR_DRIVERS := arch/arm/drivers/char/char.a +endif MISC_DRIVERS := drivers/misc/misc.a NET_DRIVERS := drivers/net/net.a PARIDE_DRIVERS := drivers/block/paride/paride.a PCI_DRIVERS := drivers/pci/pci.a SCSI_DRIVERS := drivers/scsi/scsi.a SOUND_DRIVERS := drivers/sound/sound.a +VIDEO_DRIVERS := drivers/video/video.a ifeq ($(CONFIG_ARCH_ACORN),y) BLOCK_DRIVERS += drivers/acorn/block/acorn-block.a @@ -170,6 +181,9 @@ endif DRIVERS := $(BLOCK_DRIVERS) $(CHAR_DRIVERS) $(MISC_DRIVERS) $(NET_DRIVERS) +ifeq ($(CONFIG_FB),y) +DRIVERS := $(DRIVERS) $(VIDEO_DRIVERS) +endif ifeq ($(CONFIG_SCSI),y) DRIVERS := $(DRIVERS) $(SCSI_DRIVERS) endif @@ -191,7 +205,7 @@ symlinks:: (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc) # Once we've finished integrating the sources, the @$(MAKE) will disappear -mrproper:: +archmrproper: rm -f include/asm-arm/arch include/asm-arm/proc @$(MAKE) -C arch/$(ARCH)/drivers mrproper @@ -201,6 +215,9 @@ arch/arm/kernel: dummy arch/arm/mm: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm +arch/arm/lib: dummy + $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot zImage: vmlinux @@ -227,3 +244,4 @@ archclean: archdep: @$(MAKEBOOT) dep +sed -e /^MACHINE..*=/s,= .*,= rpc,;/^PROCESSOR..*=/s,= .*,= armv, linux/arch/arm/Makefile.normal diff --git a/arch/arm/boot/compressed/Makefile.debug b/arch/arm/boot/compressed/Makefile.debug index 3c87b0569..491a037b2 100644 --- a/arch/arm/boot/compressed/Makefile.debug +++ b/arch/arm/boot/compressed/Makefile.debug @@ -5,12 +5,19 @@ # COMPRESSED_EXTRA=../../lib/ll_char_wr.o -OBJECTS=misc-debug.o $(COMPRESSED_EXTRA) +OBJECTS=misc-debug.o ll_char_wr.aout.o CFLAGS=-D__KERNEL__ -O2 -DSTDC_HEADERS -DSTANDALONE_DEBUG -Wall -I../../../../include -c -test-gzip: piggy.o $(OBJECTS) - $(CC) -o $@ $(OBJECTS) piggy.o +test-gzip: piggy.aout.o $(OBJECTS) + $(CC) -o $@ $(OBJECTS) piggy.aout.o misc-debug.o: misc.c $(CC) $(CFLAGS) -o $@ misc.c + +piggy.aout.o: piggy.o + arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux piggy.o piggy.aout.o + +ll_char_wr.aout.o: $(COMPRESSED_EXTRA) + arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux $(COMPRESSED_EXTRA) ll_char_wr.aout.o + diff --git a/arch/arm/boot/compressed/head-nexuspci.S b/arch/arm/boot/compressed/head-nexuspci.S index 92840fbda..1fd49a95c 100644 --- a/arch/arm/boot/compressed/head-nexuspci.S +++ b/arch/arm/boot/compressed/head-nexuspci.S @@ -1,35 +1,32 @@ /* * linux/arch/arm/boot/compressed/head-nexuspci.S * - * Copyright (C) 1996 Philip Blundell + * Copyright (C) 1996, 1997, 1998 Philip Blundell + * + * NexusPCI is unusual because we don't have a bootloader -- the kernel is + * run directly out of ROM at the moment. Maybe this will change one day and + * then this file can go away. + * */ -#define ARM_CP p15 -#define ARM610_REG_CONTROL cr1 -#define ARM_REG_ZERO cr0 - .text -start: b skip1 - b go_uncompress - b go_uncompress - b go_uncompress - b go_uncompress +.globl _start +_start: b reset + b undefined + b undefined + b undefined + b undefined + b undefined + b undefined + b undefined b go_uncompress - b go_uncompress - b go_uncompress - b go_uncompress - b go_uncompress -skip1: mov sp, #0x40000000 - add sp, sp, #0x200000 - mov r2, #0x20000000 + +reset: mov r2, #0x20000000 @ LED off mov r1, #0x1a str r1, [r2] - MOV r0, #0x30 - MCR ARM_CP, 0, r0, ARM610_REG_CONTROL, ARM_REG_ZERO - - mov r2, #0x10000000 + mov r2, #0x10000000 @ SCC init mov r1, #42 strb r1, [r2, #8] @@ -57,37 +54,46 @@ skip1: mov sp, #0x40000000 mov r1, #5 strb r1, [r2, #0x8] - mov r0, #0x50 + ldr r2, =_start + ldr r3, =_edata + mov r8, r2 + mov r0, #0 +1: + ldmia r0!, {r4, r5, r6, r7} + stmia r2!, {r4, r5, r6, r7} + cmp r2, r3 + ble 1b + + ldr r3, =_edata + ldr r1, =_end + mov r2, #0 +1: + strb r2, [r3] + cmp r3, r1 + beq 2f + add r3, r3, #1 + b 1b +2: + add pc, r8, #0x20 + +undefined: ldr r4, =undef_msg +1: ldrb r0, [r4], #1 + movs r0, r0 +2: beq 2b bl _ll_write_char + b 1b - mov r4, #0x40000000 - mov r1, #0x00200000 - add r4, r4, r1 -copylp: - ldr r3, [r1] - str r3, [r4, r1] - subs r1, r1, #4 - bne copylp - - add pc, r4, #0x28 - +undef_msg: .ascii "Undefined instruction (or other problem)\000" + .align 4 /* * Uncompress the kernel */ go_uncompress: - mov r0, #0x40000000 - add r0, r0, #0x300000 - bl _decompress_kernel - - mov r0, #0x40000000 - add r1, r0, #0x300000 - mov r2, #0x100000 - -clp2: ldr r3, [r1, r2] - str r3, [r0, r2] - subs r2, r2, #4 - bne clp2 + mov r0, #0x40000000 + ldr sp, =user_stack + add sp, sp, #4096 + bl decompress_kernel mov r2, #0x40000000 mov r0, #0 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 98853511b..ab2541f34 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -20,7 +20,10 @@ start: mov r0, r0 mov r0, r0 mov r0, r0 mov r0, r0 - teq r0, #0 + b 1f + .word 0x016f2818 @ Magic numbers to help the loader + .word _start +1: teq r0, #0 beq 2f mov r4, #0x02000000 add r4, r4, #0x7C000 @@ -59,11 +62,13 @@ start: mov r0, r0 * Uncompress the kernel */ mov r1, #0x8000 - add r2, r2, r1, lsl #1 @ Add 64k for malloc + add r3, r2, r1, lsl #1 @ Add 64k for malloc sub r1, r1, #1 - add r2, r2, r1 - bic r5, r2, r1 @ decompress kernel to after end of the compressed + add r3, r3, r1 + bic r5, r3, r1 @ decompress kernel to after end of the compressed mov r0, r5 + mov r1, r2 + mov r2, r0 bl SYMBOL_NAME(decompress_kernel) add r0, r0, #7 bic r2, r0, #7 diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 181583b75..ce2672911 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -274,10 +274,10 @@ ulg user_stack [STACK_SIZE]; #ifndef STANDALONE_DEBUG -ulg decompress_kernel(ulg output_start) +ulg decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p) { - free_mem_ptr = (ulg)&end; - free_mem_ptr_end = output_start; + free_mem_ptr = free_mem_ptr_p; + free_mem_ptr_end = free_mem_ptr_end_p; proc_decomp_setup (); arch_decomp_setup (); diff --git a/arch/arm/boot/tools/.cvsignore b/arch/arm/boot/tools/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/arch/arm/boot/tools/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/arch/arm/config.in b/arch/arm/config.in index 3396b1510..59eae0e87 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -7,7 +7,7 @@ mainmenu_name "Linux Kernel Configuration" define_bool CONFIG_ARM y mainmenu_option next_comment -comment 'System type and processor type' +comment 'System and processor type' choice 'ARM system type' \ "Archimedes CONFIG_ARCH_ARC \ A5000 CONFIG_ARCH_A5K \ @@ -20,29 +20,55 @@ if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" -o "$CONFIG_ARCH_RPC" else define_bool CONFIG_ARCH_ACORN n fi -if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_EBSA285" = "y" ]; then +if [ "$CONFIG_ARCH_NEXUSPCI" = "y" ]; then define_bool CONFIG_PCI y else - define_bool CONFIG_PCI n + if [ "$CONFIG_ARCH_EBSA285" = "y" ]; then + bool "PCI support" CONFIG_PCI + fi fi -if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_ARCH_EBSA285" = "y" ]; then - define_bool CONFIG_CPU_SA110 y + +# Figure out whether this system uses 26-bit or 32-bit CPUs. Nobody has +# ever built a machine that can take both, and now that ARM3 is obsolete +# nobody is likely to either. + +if [ "$CONFIG_ARCH_RPC" = "y" -o "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_ARCH_EBSA285" = "y" ]; then + define_bool CONFIG_CPU_32 y + define_bool CONFIG_CPU_26 n else - if [ "$CONFIG_ARCH_A5K" = "y" ]; then - define_bool CONFIG_CPU_ARM3 y - else - choice 'ARM cpu type' \ - "ARM2 CONFIG_CPU_ARM2 \ - ARM3 CONFIG_CPU_ARM3 \ - ARM6/7 CONFIG_CPU_ARM6 \ - StrongARM CONFIG_CPU_SA110" StrongARM + if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then + define_bool CONFIG_CPU_32 n + define_bool CONFIG_CPU_26 y fi fi + +# Now allow the user to choose a more precise CPU. This is only used to set +# the flags we pass to GCC, not in any code. + +choice 'Optimise for CPU' \ + "ARM2 CONFIG_CPU_ARM2 \ + ARM3 CONFIG_CPU_ARM3 \ + ARM6 CONFIG_CPU_ARM6 \ + ARM7 CONFIG_CPU_ARM7 \ + SA110 CONFIG_CPU_SA110" ARM6 + +if [ "$CONFIG_CPU_26" = "y" ]; then + +# For 26-bit CPUs, the page size changes with the amount of physical RAM! +# The default is 4MB but if the user has less they have to own up to it here. + + choice 'Physical memory size' \ + "4MB+ CONFIG_PAGESIZE_32 \ + 2MB CONFIG_PAGESIZE_16 \ + 1MB/512K CONFIG_PAGESIZE_8" 4MB+ +fi endmenu mainmenu_option next_comment comment 'Code maturity level options' bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +bool 'Use new compilation options (for GCC 2.8)' CONFIG_BINUTILS_NEW +bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER endmenu mainmenu_option next_comment @@ -56,33 +82,54 @@ endmenu mainmenu_option next_comment comment 'General setup' -bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER -bool 'Use new compilation options (for GCC 2.8)' CONFIG_BINUTILS_NEW -bool 'Debug kernel errors' CONFIG_DEBUG_ERRORS bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC -# This needs kernel/acct.c to be updated -#bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -# tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA - define_bool CONFIG_BINFMT_JAVA n -fi +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC + tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT + dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT +# If exactly one hardware type is selected then parport will optimise away +# support for loading any others. Defeat this if the user is keen. + if [ "$CONFIG_PARPORT_PC" = "n" -o "$CONFIG_PARPORT_ARC" = "n" ]; then + if [ "$CONFIG_PARPORT_PC" != "n" -o "$CONFIG_PARPORT_ARC" != "n" ]; then + bool ' Support foreign hardware' CONFIG_PARPORT_OTHER + fi + fi fi endmenu source arch/arm/drivers/block/Config.in source drivers/acorn/block/Config.in +source arch/arm/drivers/char/Config.in + +mainmenu_option next_comment +comment 'Console drivers' +bool 'Support Frame buffer devices' CONFIG_FB +source drivers/video/Config.in +endmenu + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi +if [ "$CONFIG_NET" = "y" ]; then + mainmenu_option next_comment + comment 'Network device support' + + bool 'Network device support?' CONFIG_NETDEVICES + if [ "$CONFIG_NETDEVICES" = "y" ]; then + source drivers/net/Config.in + fi + endmenu +fi + mainmenu_option next_comment comment 'SCSI support' @@ -93,13 +140,13 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu -if [ "$CONFIG_NET" = "y" ]; then +if [ "$CONFIG_ARCH_ACORN" = "y" ]; then mainmenu_option next_comment - comment 'Network device support' + comment 'Sound' - bool 'Network device support?' CONFIG_NETDEVICES - if [ "$CONFIG_NETDEVICES" = "y" ]; then - source drivers/net/Config.in + tristate 'Sound support' CONFIG_SOUND + if [ "$CONFIG_SOUND" != "n" ]; then + source drivers/sound/Config.in fi endmenu fi @@ -113,41 +160,14 @@ fi # fi # endmenu -# Conditionally compile in the Uniform CD-ROM driver -if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" ]; then - define_bool CONFIG_CDROM y -else - if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" ]; then - define_bool CONFIG_CDROM m - else - define_bool CONFIG_CDROM n - fi -fi - source fs/Config.in source fs/nls/Config.in -source arch/arm/drivers/char/Config.in - -if [ "$CONFIG_ARCH_ACORN" = "y" ]; then - mainmenu_option next_comment - comment 'Sound' - - tristate 'Sound support' CONFIG_SOUND - if [ "$CONFIG_SOUND" != "n" ]; then - source drivers/sound/Config.in - fi - endmenu -fi - mainmenu_option next_comment comment 'Kernel hacking' +bool 'Debug kernel errors' CONFIG_DEBUG_ERRORS #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC -bool 'Kernel profiling support' CONFIG_PROFILE -if [ "$CONFIG_PROFILE" = "y" ]; then - int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 -fi bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu diff --git a/arch/arm/defconfig b/arch/arm/defconfig index 5e587ffbf..64fb0d7ab 100644 --- a/arch/arm/defconfig +++ b/arch/arm/defconfig @@ -172,7 +172,6 @@ CONFIG_PPP=m CONFIG_ETHER1=m CONFIG_ETHER3=m CONFIG_ETHERH=m -CONFIG_CDROM=y # # Filesystems @@ -264,5 +263,4 @@ DSP_BUFFSIZE=65536 # # Kernel hacking # -# CONFIG_PROFILE is not set CONFIG_MAGIC_SYSRQ=y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f263b2a7f..7795dd0bc 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -11,7 +11,7 @@ ENTRY_OBJ = entry-$(PROCESSOR).o O_TARGET := kernel.o O_OBJS := $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o signal.o sys_arm.o time.o traps.o -all: kernel.o $(HEAD_OBJ) init_task.o +all: lib kernel.o $(HEAD_OBJ) init_task.o ifeq ($(CONFIG_MODULES),y) OX_OBJS = armksyms.o @@ -19,28 +19,31 @@ else O_OBJS += armksyms.o endif -ifdef CONFIG_PCI - O_OBJS += bios32.o -endif - ifdef CONFIG_ARCH_ACORN - O_OBJS += setup.o ecard.o iic.o dma.o + O_OBJS += setup.o ecard.o iic.o ifdef CONFIG_ARCH_ARC O_OBJS += oldlatches.o endif O_OBJS += dma-$(MACHINE).o + OX_OBJS += dma.o endif ifeq ($(MACHINE),ebsa110) - O_OBJS += setup-ebsa110.o dma.o dma-dummy.o + O_OBJS += setup-ebsa110.o dma-dummy.o endif ifeq ($(MACHINE),ebsa285) - O_OBJS += dma.o dma-dummy.o leds-ebsa285.o setup-ebsa110.o + O_OBJS += dma-dummy.o leds-ebsa285.o setup-ebsa110.o + ifdef CONFIG_PCI + O_OBJS += dec21285.o + endif endif ifeq ($(MACHINE),nexuspci) - O_OBJS += setup-ebsa110.o + O_OBJS += setup-ebsa110.o dma-dummy.o + ifdef CONFIG_PCI + O_OBJS += plx9080.o + endif endif $(HEAD_OBJ): $(HEAD_OBJ:.o=.S) @@ -53,7 +56,7 @@ include $(TOPDIR)/Rules.make $(ENTRY_OBJ): ../lib/constants.h -.PHONY: ../lib/constants.h +.PHONY: lib -../lib/constants.h: +lib: $(MAKE) -C ../lib constants.h diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index a5b49bf2a..5c2f1b502 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -5,10 +5,11 @@ #include #include #include +#include #include +#include #include -#include #include #include #include @@ -73,6 +74,9 @@ EXPORT_SYMBOL(ecard_readchunk); EXPORT_SYMBOL(ecard_address); #endif +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); + /* processor dependencies */ EXPORT_SYMBOL(processor); @@ -100,36 +104,23 @@ EXPORT_SYMBOL(quicklists); EXPORT_SYMBOL(__bad_pmd); EXPORT_SYMBOL(__bad_pmd_kernel); -/* dma */ -EXPORT_SYMBOL(dma_str); -EXPORT_SYMBOL(enable_dma); -EXPORT_SYMBOL(disable_dma); -EXPORT_SYMBOL(set_dma_addr); -EXPORT_SYMBOL(set_dma_count); -EXPORT_SYMBOL(set_dma_mode); -EXPORT_SYMBOL(get_dma_residue); -EXPORT_SYMBOL(set_dma_sg); - +#define EXPORT_VERS0(sym,orig) \ + const char __kstrtab_##sym##[] __attribute__((section(".kstrtab"))) = \ + __MODULE_STRING(##sym##_R00000000); \ + const struct module_symbol __ksymtab_##sym __attribute__((section("__ksymtab"))) = \ + { (unsigned long)&##orig, __kstrtab_##sym }; /* * floating point math emulator support. * These symbols will never change their calling convention... */ -EXPORT_SYMBOL_NOVERS(fpreturn); -EXPORT_SYMBOL_NOVERS(fpundefinstr); -EXPORT_SYMBOL_NOVERS(fp_enter); -EXPORT_SYMBOL_NOVERS(fp_save); -EXPORT_SYMBOL_NOVERS(fp_restore); -EXPORT_SYMBOL_NOVERS(fp_setup); - -const char __kstrtab_fp_printk[] __attribute__((section(".kstrtab"))) = __MODULE_STRING(fp_printk); -const struct module_symbol __ksymtab_fp_printk __attribute__((section("__ksymtab"))) = -{ (unsigned long)&printk, __kstrtab_fp_printk }; - -const char __kstrtab_fp_send_sig[] __attribute__((section(".kstrtab"))) = __MODULE_STRING(fp_send_sig); -const struct module_symbol __ksymtab_fp_send_sig __attribute__((section("__ksymtab"))) = -{ (unsigned long)&send_sig, __kstrtab_fp_send_sig }; - -//EXPORT_SYMBOL_NOVERS(fp_current); +EXPORT_VERS0(fpreturn,fpreturn); +EXPORT_VERS0(fpundefinstr,fpundefinstr); +EXPORT_VERS0(fp_enter,fp_enter); +EXPORT_VERS0(fp_save,fp_save); +EXPORT_VERS0(fp_restore,fp_restore); +EXPORT_VERS0(fp_setup,fp_setup); +EXPORT_VERS0(fp_printk,printk); +EXPORT_VERS0(fp_send_sig,send_sig); /* * string / mem functions @@ -155,12 +146,12 @@ EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memzero); /* user mem (segment) */ -#if defined(CONFIG_CPU_ARM6) || defined(CONFIG_CPU_SA110) +#if defined(CONFIG_CPU_32) EXPORT_SYMBOL(__arch_copy_from_user); EXPORT_SYMBOL(__arch_copy_to_user); EXPORT_SYMBOL(__arch_clear_user); EXPORT_SYMBOL(__arch_strlen_user); -#elif defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) +#elif defined(CONFIG_CPU_26) EXPORT_SYMBOL(uaccess_kernel); EXPORT_SYMBOL(uaccess_user); #endif @@ -193,3 +184,8 @@ EXPORT_SYMBOL(change_bit); EXPORT_SYMBOL(test_and_change_bit); EXPORT_SYMBOL(find_first_zero_bit); EXPORT_SYMBOL(find_next_zero_bit); + + /* elf */ +EXPORT_SYMBOL(armidlist); +EXPORT_SYMBOL(armidindex); +EXPORT_SYMBOL(elf_platform); diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c deleted file mode 100644 index 4400dda42..000000000 --- a/arch/arm/kernel/bios32.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * arch/arm/kernel/bios32.c: PCI functions for ARM - * - * Copyright (C) 1998 Russell King - */ -#include -#include -#include - -int pcibios_present(void) -{ - return 1; -} - -static unsigned long pcibios_base_address(unsigned char dev_fn) -{ - int slot = PCI_SLOT(dev_fn); - - if (slot < 4) - return 0xf8000000 + (1 << (19 - slot)); - else - return 0; -} - -int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - unsigned char v; - - if (addr) { - __asm__("ldr%?b %0, [%1, %2]" - : "=r" (v) - : "r" (addr), "r" (where)); - *val = v; - } else - *val = 0xff; - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - unsigned short v; - - if (addr) { - __asm__("ldrh%? %0, [%1, %2]" - : "=r" (v) - : "r" (addr), "r" (where)); - *val = v; - } else - *val = 0xffff; - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - unsigned int v; - - if (addr) { - __asm__("ldr%? %0, [%1, %2]" - : "=r" (v) - : "r" (addr), "r" (where)); - *val = v; - } else - *val = 0xffffffff; - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - - if (addr) - __asm__("str%?b %0, [%1, %2]" - : : "r" (val), "r" (addr), "r" (where)); - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - - if (addr) - __asm__("strh%? %0, [%1, %2]" - : : "r" (val), "r" (addr), "r" (where)); - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val) -{ - unsigned long addr = pcibios_base_address(dev_fn); - - if (addr) - __asm__("str%? %0, [%1, %2]" - : : "r" (val), "r" (addr), "r" (where)); - return PCIBIOS_SUCCESSFUL; -} - -static int irq[] = { 18, 8, 9, 11 }; - -__initfunc(void pcibios_fixup(void)) -{ - struct pci_dev *dev; - unsigned char pin; - - for (dev = pci_devices; dev; dev = dev->next) { - pcibios_read_config_byte(dev->bus->number, - dev->devfn, - PCI_INTERRUPT_PIN, - &pin); - - dev->irq = irq[(PCI_SLOT(dev->devfn) + pin) & 3]; - - pcibios_write_config_byte(dev->bus->number, - dev->devfn, - PCI_INTERRUPT_LINE, - dev->irq); - - printk("PCI: %02x:%02x [%04x/%04x] pin %d irq %d\n", - dev->bus->number, dev->devfn, - dev->vendor, dev->device, - pin, dev->irq); - } -} - -__initfunc(void pcibios_init(void)) -{ - int rev; - - rev = *(unsigned char *)0xfe000008; - printk("DEC21285 PCI revision %02X\n", rev); -} - -__initfunc(char *pcibios_setup(char *str)) -{ - return str; -} diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 8a248c728..751f9616a 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -1,11 +1,12 @@ /* * linux/arch/arm/lib/calls.h * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This file is included twice in entry-common.S */ -#ifndef NR_SYSCALLS +#ifndef NR_syscalls #define NR_syscalls 256 -#define NR_SYSCALLS 184 #else /* 0 */ .long SYMBOL_NAME(sys_setup) @@ -24,7 +25,7 @@ .long SYMBOL_NAME(sys_time) .long SYMBOL_NAME(sys_mknod) /* 15 */ .long SYMBOL_NAME(sys_chmod) - .long SYMBOL_NAME(sys_chown) + .long SYMBOL_NAME(sys_lchown) .long SYMBOL_NAME(sys_ni_syscall) /* was sys_break */ .long SYMBOL_NAME(sys_stat) .long SYMBOL_NAME(sys_lseek) @@ -190,7 +191,13 @@ .long SYMBOL_NAME(sys_rt_sigsuspend_wrapper) /* 180 */ .long SYMBOL_NAME(sys_pread) .long SYMBOL_NAME(sys_pwrite) - .long SYMBOL_NAME(sys_xstat) - .long SYMBOL_NAME(sys_xmknod) - .space (NR_syscalls - 184) * 4 + .long SYMBOL_NAME(sys_chown) + .long SYMBOL_NAME(sys_getcwd) + .long SYMBOL_NAME(sys_capget) +/* 185 */ .long SYMBOL_NAME(sys_capset) + .long SYMBOL_NAME(sys_sigaltstack_wrapper) + + .rept NR_syscalls-186 + .long SYMBOL_NAME(sys_ni_syscall) + .endr #endif diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c new file mode 100644 index 000000000..11ea39e7a --- /dev/null +++ b/arch/arm/kernel/dec21285.c @@ -0,0 +1,157 @@ +/* + * arch/arm/kernel/dec21285.c: PCI functions for DEC 21285 + * + * Copyright (C) 1998 Russell King + */ +#include +#include +#include + +int pcibios_present(void) +{ + return 1; +} + +static unsigned long pcibios_base_address(unsigned char dev_fn) +{ + int slot = PCI_SLOT(dev_fn); + + if (slot < 4) + return 0xf8000000 + (1 << (19 - slot)); + else + return 0; +} + +int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char *val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + unsigned char v; + + if (addr) + __asm__("ldr%?b %0, [%1, %2]" + : "=r" (v) + : "r" (addr), "r" (where)); + else + v = 0xff; + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short *val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + unsigned short v; + + if (addr) + __asm__("ldr%?h %0, [%1, %2]" + : "=r" (v) + : "r" (addr), "r" (where)); + else + v = 0xffff; + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int *val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + unsigned int v; + + if (addr) + __asm__("ldr%? %0, [%1, %2]" + : "=r" (v) + : "r" (addr), "r" (where)); + else + v = 0xffffffff; + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + + if (addr) + __asm__("str%?b %0, [%1, %2]" + : : "r" (val), "r" (addr), "r" (where)); + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + + if (addr) + __asm__("str%?h %0, [%1, %2]" + : : "r" (val), "r" (addr), "r" (where)); + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int val) +{ + unsigned long addr = pcibios_base_address(dev_fn); + + if (addr) + __asm__("str%? %0, [%1, %2]" + : : "r" (val), "r" (addr), "r" (where)); + return PCIBIOS_SUCCESSFUL; +} + +static int irq[] = { 18, 8, 9, 11 }; + +__initfunc(void pcibios_fixup(void)) +{ + struct pci_dev *dev; + unsigned char pin; + unsigned int cmd; + + for (dev = pci_devices; dev; dev = dev->next) { + pcibios_read_config_byte(dev->bus->number, + dev->devfn, + PCI_INTERRUPT_PIN, + &pin); + + dev->irq = irq[(PCI_SLOT(dev->devfn) + pin) & 3]; + + pcibios_write_config_byte(dev->bus->number, + dev->devfn, + PCI_INTERRUPT_LINE, + dev->irq); + + printk("PCI: %02x:%02x [%04x/%04x] pin %d irq %d\n", + dev->bus->number, dev->devfn, + dev->vendor, dev->device, + pin, dev->irq); + + /* Turn on bus mastering - boot loader doesn't - perhaps it should! */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, &cmd); + pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + } +} + +__initfunc(void pcibios_init(void)) +{ + int rev; + + rev = *(unsigned char *)0xfe000008; + printk("DEC21285 PCI revision %02X\n", rev); +} + +__initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) +{ +} + +__initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) +{ +} + +__initfunc(char *pcibios_setup(char *str)) +{ + return str; +} diff --git a/arch/arm/kernel/dma-a5k.c b/arch/arm/kernel/dma-a5k.c index f722809fa..50ee42435 100644 --- a/arch/arm/kernel/dma-a5k.c +++ b/arch/arm/kernel/dma-a5k.c @@ -9,14 +9,18 @@ #include #include +#include #include #include +#include #include "dma.h" -int arch_request_dma(dmach_t channel, dma_t *dma) +static struct fiq_handler fh = { "floppydma", NULL }; + +int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id) { - if (channel == DMA_VIRTUAL_FLOPPY0) + if (channel == DMA_VIRTUAL_FLOPPY) return 0; else return -EINVAL; @@ -24,14 +28,14 @@ int arch_request_dma(dmach_t channel, dma_t *dma) void arch_free_dma(dmach_t channel, dma_t *dma) { - if (channel != DMA_VIRTUAL_FLOPPY0) - printk ("arch_free_dma: invalid channel %d\n", channel); + if (channel != DMA_VIRTUAL_FLOPPY) + printk("arch_free_dma: invalid channel %d\n", channel); } int arch_get_dma_residue(dmach_t channel, dma_t *dma) { - if (channel != DMA_VIRTUAL_FLOPPY0) - printk ("arch_dma_count: invalid channel %d\n", dmanr); + if (channel != DMA_VIRTUAL_FLOPPY) + printk("arch_dma_count: invalid channel %d\n", channel); else { extern int floppy_fiqresidual(void); return floppy_fiqresidual(); @@ -41,12 +45,12 @@ int arch_get_dma_residue(dmach_t channel, dma_t *dma) void arch_enable_dma(dmach_t channel, dma_t *dma) { - if (channel != DMA_VIRTUAL_FLOPPY0) - printk ("arch_enable_dma: invalid channel %d\n", channel); + if (channel != DMA_VIRTUAL_FLOPPY) + printk("arch_enable_dma: invalid channel %d\n", channel); else { void *fiqhandler_start; unsigned int fiqhandler_length; - extern void floppy_fiqsetup (unsigned long len, unsigned long addr, + extern void floppy_fiqsetup(unsigned long len, unsigned long addr, unsigned long port); if (dma->dma_mode == DMA_MODE_READ) { @@ -58,22 +62,28 @@ void arch_enable_dma(dmach_t channel, dma_t *dma) fiqhandler_start = &floppy_fiqout_start; fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start; } - memcpy ((void *)0x1c, fiqhandler_start, fiqhandler_length); + if (claim_fiq(&fh)) { + printk("floppydma: couldn't claim FIQ.\n"); + return; + } + memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length); flush_page_to_ram(0); - floppy_fiqsetup (dma->buf.length, __bus_to_virt(dma->buf.address), (int)PCIO_FLOPPYDMABASE); - enable_irq (dma->dma_irq); + floppy_fiqsetup(dma->buf.length, __bus_to_virt(dma->buf.address), (int)PCIO_FLOPPYDMABASE); + enable_irq(dma->dma_irq); } } void arch_disable_dma(dmach_t channel, dma_t *dma) { - if (channel != DMA_VIRTUAL_FLOPPY0) - printk ("arch_disable_dma: invalid channel %d\n", channel); - else - disable_irq (dma->dma_irq); + if (channel != DMA_VIRTUAL_FLOPPY) + printk("arch_disable_dma: invalid channel %d\n", channel); + else { + disable_irq(dma->dma_irq); + release_fiq(&fh); + } } __initfunc(void arch_dma_init(dma_t *dma)) { - dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64; + dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64; } diff --git a/arch/arm/kernel/dma-dummy.c b/arch/arm/kernel/dma-dummy.c index af47512dd..be72a8965 100644 --- a/arch/arm/kernel/dma-dummy.c +++ b/arch/arm/kernel/dma-dummy.c @@ -1,45 +1,28 @@ /* * arch/arm/kernel/dma-dummy.c * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Philip Blundell + * Copyright (c) 1998 Russell King * * Dummy DMA functions */ -#include +#include #include -#include -#include -#include - -#include "dma.h" - -int arch_request_dma(dmach_t channel, dma_t *dma, const char *devname) +int request_dma(int channel, const char *device_id) { return -EINVAL; } -void arch_free_dma(dmach_t channel, dma_t *dma) -{ - printk ("arch_free_dma: invalid channel %d\n", channel); -} - -void arch_enable_dma(dmach_t channel, dma_t *dma) -{ - printk ("arch_enable_dma: invalid channel %d\n", channel); -} - -void arch_disable_dma(dmach_t channel, dma_t *dma) +void free_dma(int channel) { - printk ("arch_disable_dma: invalid channel %d\n", channel); } -int arch_get_dma_residue(dmach_t channel, dma_t *dma) +int get_dma_list(char *buf) { - printk ("arch_get_dma_residue: invalid channel %d\n", channel); return 0; } -__initfunc(void arch_dma_init(dma_t *dma)) +__initfunc(void init_dma(void)) { } diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c index eb5bc87d7..301b32071 100644 --- a/arch/arm/kernel/dma-rpc.c +++ b/arch/arm/kernel/dma-rpc.c @@ -13,12 +13,15 @@ #include #include #include +#include #include #include #include #include "dma.h" +static struct fiq_handler fh = { "floppydma", NULL }; + #if 0 typedef enum { dma_size_8 = 1, @@ -270,6 +273,10 @@ void arch_enable_dma(dmach_t channel, dma_t *dma) fiqhandler_start = &floppy_fiqout_start; fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start; } + if (claim_fiq(&fh)) { + printk("floppydma: couldn't claim FIQ.\n"); + return; + } /* Allow access to page 0 via domains */ __asm__ __volatile__("mcr p15, 0, %0, c3, c0" : : "r" (DOMAIN_USER_MANAGER | diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 6058a2863..592cc979c 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -15,6 +15,7 @@ * Moved DMA resource allocation here... */ #include +#include #include #include #include @@ -28,6 +29,8 @@ #include "dma.h" +const char dma_str[] = "%s: dma %d not supported\n"; + static dma_t dma_chan[MAX_DMA_CHANNELS]; /* Get dma list @@ -183,6 +186,15 @@ int get_dma_residue(dmach_t channel) return arch_get_dma_residue(channel, &dma_chan[channel]); } +EXPORT_SYMBOL(dma_str); +EXPORT_SYMBOL(enable_dma); +EXPORT_SYMBOL(disable_dma); +EXPORT_SYMBOL(set_dma_addr); +EXPORT_SYMBOL(set_dma_count); +EXPORT_SYMBOL(set_dma_mode); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(set_dma_sg); + __initfunc(void init_dma(void)) { arch_dma_init(dma_chan); diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S index 20c1b8e7c..4c65fc892 100644 --- a/arch/arm/kernel/entry-armo.S +++ b/arch/arm/kernel/entry-armo.S @@ -21,7 +21,6 @@ * Ok, so this file may be a mess, but its as efficient as possible while * adhering to the above criteria. */ -#include #include #include @@ -189,7 +188,7 @@ irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 */ .macro adrsvc, cond, reg, label adr\cond \reg, \label - orr\cond \reg, \reg, #3 + orr\cond \reg, \reg, #0x08000003 .endm #if 0 @@ -398,12 +397,12 @@ Laddrexcptn_illegal_mode: /*============================================================================= * Interrupt (IRQ) handler *----------------------------------------------------------------------------- - * Note: if in user mode, then *no* kernel routine is running, so dont have + * Note: if in user mode, then *no* kernel routine is running, so do not have * to save svc lr * (r13 points to irq temp save area) */ -vector_IRQ: ldr r13, .LCirq @ Ill leave this one in just in case... +vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case... sub lr, lr, #4 str lr, [r13] tst lr, #3 @@ -422,7 +421,7 @@ vector_IRQ: ldr r13, .LCirq @ Ill leave this one in just in case... @ routine called with r0 = irq number, r1 = struct pt_regs * @ adr lr, 1b - orr lr, lr, #3 @ Force SVC + orr lr, lr, #0x08000003 @ Force SVC bne do_IRQ b ret_with_reschedule @@ -442,7 +441,7 @@ __irq_svc: teqp pc, #0x08000003 @ routine called with r0 = irq number, r1 = struct pt_regs * @ adr lr, 1b - orr lr, lr, #3 @ Force SVC + orr lr, lr, #0x08000003 @ Force SVC bne do_IRQ @ Returns to 1b SVC_RESTORE_ALL @@ -512,17 +511,11 @@ Ldata_do: mov r3, sp b Ldata_ldcstc_pre @ ldc rd, [rn, #m] b Ldata_unknown Ldata_unknown: @ Part of jumptable - ldr r3, [sp, #15 * 4] - str r3, [sp, #-4]! - mov r1, r1, lsr #2 - mov r2, r0 - mov r3, r4 - adr r0, Ltt - bl SYMBOL_NAME(printk) -Llpxx: b Llpxx - -Ltt: .ascii "Unknown data abort code %d [pc=%p, *pc=%p]\nLR=%p\0" - .align + mov r0, r1 + mov r1, r4 + mov r2, r3 + mov r3, lr + b baddataabort Ldata_ldrstr_post: mov r0, r4, lsr #14 @ Get Rn diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index f2d752cd4..a7553d350 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -9,13 +9,13 @@ * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes * it to save wrong values... Be aware! */ -#include /* for CONFIG_ARCH_EBSA110 */ -#include +#include /* for CONFIG_ARCH_xxxx */ #include #include #include #include +#include #include "../lib/constants.h" @@ -90,7 +90,7 @@ adreq \base, irq_prio_l teq \irqstat, #0 - ldrneb \irqnr, [r5, \irqstat] @ get IRQ number + ldrneb \irqnr, [\base, \irqstat] @ get IRQ number .endm /* @@ -160,7 +160,7 @@ irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 adr \base, irq_prio_ebsa110 teq \irqstat, #0 - ldrneb \irqnr, [r5, \irqstat] @ get IRQ number + ldrneb \irqnr, [\base, \irqstat] @ get IRQ number .endm .macro irq_prio_table @@ -206,6 +206,85 @@ irq_prio_ebsa110: .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_NEXUSPCI) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base + ldr r4, =0xffe00000 + ldr \irqstat, [r4, #0x180] @ get interrupts + mov \irqnr, #0 +1001: tst \irqstat, #1 + addeq \irqnr, \irqnr, #1 + moveq \irqstat, \irqstat, lsr #1 + tsteq \irqnr, #32 + beq 1001b + teq \irqnr, #32 + .endm + + .macro irq_prio_table + .endm + +#elif defined(CONFIG_ARCH_VNC) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base + mov r4, #IO_BASE_ARM_CSR + ldr \irqstat, [r4, #IRQ_STATUS] @ just show us the unmasked ones + + @ run through hard priorities + @ timer + tst \irqstat, #IRQ_MASK_TIMER0 + movne \irqnr, #IRQ_TIMER0 + bne 1f + + @ ether10 + tst \irqstat, #IRQ_MASK_ETHER10 + movne \irqnr, #IRQ_ETHER10 + bne 1f + + @ ether100 + tst \irqstat, #IRQ_MASK_ETHER100 + movne \irqnr, #IRQ_ETHER100 + bne 1f + + @ video compressor + tst \irqstat, #IRQ_VIDCOMP_MASK + movne \irqnr, #IRQ_VIDCOMP + bne 1f + + @ now try all the PIC sources + @ determine whether we have an irq + tst \irqstat, #IRQ_MASK_EXTERN_IRQ + beq 3f + mov r4, #(IO_BASE_PCI_IACK & 0xff000000) + orr r4, r4, #(IO_BASE_PCI_IACK & 0x00ff0000) + ldrb \irqnr, [r4] @ get the IACK byte + b 1f + +3: @ PCI errors + tst \irqstat, #IRQ_MASK_PCI_ERR + movne \irqnr, #IRQ_PCI_ERR + bne 1f + + @ softint + tst \irqstat, #IRQ_MASK_SOFT_IRQ + movne \irqnr, #IRQ_SOFT_IRQ + bne 1f + + @ debug uart + tst \irqstat, #IRQ_MASK_UART_DEBUG + movne \irqnr, #IRQ_UART_DEBUG + bne 1f + + @ watchdog + tst \irqstat, #IRQ_WATCHDOG_MASK + movne \irqnr, #IRQ_WATCHDOG + +1: @ If Z is set, then we will not enter an interrupt #else #error Unknown architecture #endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 98c41266f..422326338 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -2,6 +2,8 @@ * All exits to user mode from the kernel go through this code. */ +#include + .globl ret_from_sys_call .globl SYMBOL_NAME(fpreturn) @@ -71,7 +73,7 @@ vector_swi: save_user_regs bic r6, r6, #0xff000000 @ mask off SWI op-code eor r6, r6, #OS_NUMBER<<20 @ check OS number - cmp r6, #NR_SYSCALLS @ check upper syscall limit + cmp r6, #NR_syscalls @ check upper syscall limit bcs 2f get_current_task r5 @@ -131,7 +133,7 @@ vector_swi: save_user_regs SYMBOL_NAME(sys_syscall): mov r6, r0 eor r6, r6, #OS_NUMBER << 20 - cmp r6, #NR_SYSCALLS @ check range + cmp r6, #NR_syscalls @ check range movgt r0, #-ENOSYS movgt pc, lr add sp, sp, #4 @ take of the save of our r4 @@ -191,6 +193,10 @@ sys_rt_sigreturn_wrapper: add r0, sp, #4 b SYMBOL_NAME(sys_rt_sigreturn) +sys_sigaltstack_wrapper: + ldr r2, [sp, #4 + S_SP] + b do_sigaltstack + /* *============================================================================= * Low-level interface code @@ -207,6 +213,7 @@ sys_rt_sigreturn_wrapper: * 0x1c onwards is reserved for FIQ, so I think that I will allocate 0xe0 onwards for * the actuall address to jump to. */ +#if defined(CONFIG_CPU_32) /* * these go into 0x00 */ @@ -237,13 +244,42 @@ ENTRY(trap_init) initialise_traps_extra mov r0, #0xe4 adr r1, .Ljump_addresses - ldmia r1, {r1 - r6} - stmia r0, {r1 - r6} + ldmia r1, {r1 - r7} + stmia r0, {r1 - r7} mov r0, #0 adr r1, .Lbranches ldmia r1, {r1 - r7} stmia r0, {r1 - r7} LOADREGS(fd, sp!, {r4 - r7, pc}) +#elif defined(CONFIG_CPU_26) +.Ljump_addresses: + swi SYS_ERROR0 + .word vector_undefinstr - 12 + .word vector_swi - 16 + .word vector_prefetch - 20 + .word vector_data - 24 + .word vector_addrexcptn - 28 + .word vector_IRQ - 32 + .word _unexp_fiq - 36 + b . + 8 +/* + * initialise the trap system + */ +ENTRY(trap_init) + stmfd sp!, {r4 - r7, lr} + adr r1, .Ljump_addresses + ldmia r1, {r1 - r7, ip, lr} + orr r2, lr, r2, lsr #2 + orr r3, lr, r3, lsr #2 + orr r4, lr, r4, lsr #2 + orr r5, lr, r5, lsr #2 + orr r6, lr, r6, lsr #2 + orr r7, lr, r7, lsr #2 + orr ip, lr, ip, lsr #2 + mov r0, #0 + stmia r0, {r1 - r7, ip} + ldmfd sp!, {r4 - r7, pc}^ +#endif /*============================================================================ * FP support diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S index e53b7144f..2219d37c3 100644 --- a/arch/arm/kernel/head-armv.S +++ b/arch/arm/kernel/head-armv.S @@ -7,6 +7,9 @@ */ #include #include + +#define DEBUG + .text .align @@ -19,18 +22,20 @@ * MMU off. Note! These should be unique!!! Please read Documentation/ARM-README * for more information. * - * r1 = 0 -> ebsa110 (Ram @ 0x00000000) - * r1 = 1 -> RPC (Ram @ 0x10000000) - * r1 = 2 -> ebsit (???) + * r1 = 0 -> ebsa110 + * r1 = 1 -> RPC + * r1 = 2 -> ebsit * r1 = 3 -> nexuspci - * r1 = 4 -> ebsa285 (Ram @ 0x00000000) + * r1 = 4 -> ebsa285 + * r1 = 5 -> vnc + * r1 = 6 -> CATS */ ENTRY(stext) ENTRY(_stext) __entry: teq r0, #0 @ check for illegal entry... bne .Lerror @ loop indefinitely - cmp r1, #5 @ Unknown machine architecture + cmp r1, #7 @ Unknown machine architecture bge .Lerror @ @ First thing to do is to get the page tables set up so that we can call the kernel @@ -116,7 +121,8 @@ __entry: @ we lose this page! mov pc, lr -.Lerror: mov r0, #0x02000000 +.Lerror: +1: mov r0, #0x02000000 mov r1, #0x11 orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 @@ -124,7 +130,7 @@ __entry: str r1, [r0], #4 str r1, [r0], #4 str r1, [r0], #4 - b .Lerror + b 1b .Lbranch: .long .Lalready_done_mmap @ Real address of routine @@ -153,12 +159,22 @@ __entry: .long 0 @ EBSA285 - .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) + .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) .long 0 @ Address of RAM .long 0x24000000 @ I/O base address (0x42000000 -> 0xFE000000) .long 0 + @ Corel VNC + .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) + .long 0 @ Address of RAM + .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000) + .long 0 + @ CATS + .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) + .long 0 @ Address of RAM + .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000) + .long 0 .LCProcTypes: @ ARM6 / 610 .long 0x41560600 @@ -167,13 +183,20 @@ __entry: b .Larmv3_flush_early @ arm v3 flush & ctrl early setup mov pc, lr - @ ARM7 / 710 + @ ARM7 .long 0x41007000 .long 0xfffff000 .long 0x00000c12 b .Larmv3_flush_late @ arm v3 flush & ctrl late setup mov pc, lr + @ ARM710 + .long 0x41007000 + .long 0xfff8f000 @ arm710 processors are weird + .long 0x00000c12 + b .Larmv3_flush_late @ arm v3 flush & ctrl late setup + mov pc, lr + @ StrongARM .long 0x4401a100 .long 0xfffffff0 @@ -245,8 +268,11 @@ __entry: mov fp, #0 b SYMBOL_NAME(start_kernel) -#if 1 - +#ifdef DEBUG +/* + * Some debugging routines (useful if you've got MM problems and + * printk isn't working). For DEBUGGING ONLY!!! + */ #if defined(CONFIG_ARCH_RPC) .macro addruart,rx mov \rx, #0xe0000000 @@ -261,6 +287,7 @@ __entry: .macro busyuart,rd,rx 1002: ldrb \rd, [\rx, #0x14] and \rd, \rd, #0x60 + teq \rd, #0x60 bne 1002b .endm @@ -283,6 +310,7 @@ __entry: .macro busyuart,rd,rx 1002: ldrb \rd, [\rx, #0x14] and \rd, \rd, #0x60 + teq \rd, #0x60 bne 1002b .endm @@ -292,7 +320,7 @@ __entry: beq 1001b .endm -#elif defined(CONFIG_ARCH_EBSA285) +#elif defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_VNC) .macro addruart,rx mov \rx, #0xfe000000 .endm @@ -309,6 +337,26 @@ __entry: .macro waituart,rd,rx .endm + +#elif defined(CONFIG_ARCH_NEXUSPCI) + .macro addruart,rx + ldr \rx, =0xfff00000 + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0xc] + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x4] + tst \rd, #1 << 0 + bne 1001b + .endm + + .macro waituart,rd,rx + .endm +#else +#error Unknown architecture #endif /* @@ -359,6 +407,8 @@ ENTRY(printch) mov r0, #0 b 1b + .ltorg + .bss hexbuf: .space 16 diff --git a/arch/arm/kernel/iic.c b/arch/arm/kernel/iic.c index 10a25e01b..6eb0122e8 100644 --- a/arch/arm/kernel/iic.c +++ b/arch/arm/kernel/iic.c @@ -6,8 +6,9 @@ * IIC is used to get the current time from the CMOS rtc. */ +#include + #include -#include #include #include diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 1dde0e0ba..89116048e 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -2,7 +2,8 @@ * linux/arch/arm/kernel/irq.c * * Copyright (C) 1992 Linus Torvalds - * Modifications for ARM processor Copyright (C) 1995, 1996 Russell King. + * Modifications for ARM processor Copyright (C) 1995-1998 Russell King. + * FIQ support written by Philip Blundell , 1998. * * This file contains the code used by various IRQ handling routines: * asking for different IRQ's should be done through these routines @@ -30,14 +31,20 @@ #include #include +#include +#include #include +#include #include -#include #include unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; spinlock_t irq_controller_lock; +static struct fiq_handler *current_fiq; +static unsigned long no_fiq_insn; + +#define FIQ_VECTOR ((unsigned long *)0x1c) #ifndef SMP #define irq_enter(cpu, irq) (++local_irq_count[cpu]) @@ -46,6 +53,20 @@ spinlock_t irq_controller_lock; #error SMP not supported #endif +#ifdef CONFIG_ARCH_ACORN +/* Bitmask indicating valid interrupt numbers + * (to be moved to include/asm-arm/arch-*) + */ +unsigned long validirqs[NR_IRQS / 32] = { + 0x003ffe7f, 0x000001ff, 0x000000ff, 0x00000000 +}; + +#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31))) +#else + +#define valid_irq(x) ((x) < NR_IRQS) +#endif + void disable_irq(unsigned int irq_nr) { unsigned long flags; @@ -74,21 +95,6 @@ void enable_irq(unsigned int irq_nr) struct irqaction *irq_action[NR_IRQS]; -#ifdef CONFIG_ARCH_ACORN -/* Bitmask indicating valid interrupt numbers - * (to be moved to include/asm-arm/arch-*) - */ -unsigned long validirqs[NR_IRQS / 32] = { - 0x003ffe7f, 0x000001ff, 0x000000ff, 0x00000000 -}; - -#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31))) -#else - -#define valid_irq(x) ((x) < NR_IRQS) - -#endif - int get_irq_list(char *buf) { int i; @@ -106,6 +112,8 @@ int get_irq_list(char *buf) } *p++ = '\n'; } + p += sprintf(p, "FIQ: %s\n", + current_fiq?current_fiq->name:"unused"); return p - buf; } @@ -186,7 +194,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) } } -#if defined(HAS_IOMD) || defined(HAS_IOC) +#if defined(CONFIG_ARCH_ACORN) void do_ecard_IRQ(int irq, struct pt_regs *regs) { struct irqaction * action; @@ -336,9 +344,41 @@ int probe_irq_off (unsigned long irqs) return i; } +int claim_fiq(struct fiq_handler *f) +{ + if (current_fiq) { + if (current_fiq->callback == NULL || (*current_fiq->callback)()) + return -EBUSY; + } + current_fiq = f; + return 0; +} + +void release_fiq(struct fiq_handler *f) +{ + if (current_fiq != f) { + printk(KERN_ERR "%s tried to release FIQ when not owner!\n", + f->name); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + return; + } + current_fiq = NULL; + + *FIQ_VECTOR = no_fiq_insn; + __flush_entry_to_ram(FIQ_VECTOR); +} + __initfunc(void init_IRQ(void)) { extern void init_dma(void); + irq_init_irq(); + + current_fiq = NULL; + no_fiq_insn = *FIQ_VECTOR; + init_dma(); } + diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 9372539ef..b606384c8 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -38,6 +38,8 @@ #include #include +struct task_struct *last_task_used_math; + extern void fpe_save(struct fp_soft_struct *); extern char *processor_modes[]; @@ -69,8 +71,9 @@ asmlinkage int sys_idle(void) current->priority = -100; for (;;) { + check_pgt_cache(); #if 0 //def ARCH_IDLE_OK - if (!hlt_counter && !need_resched) + if (!hlt_counter && !current->need_resched) proc_idle (); #endif run_task_queue(&tq_scheduler); @@ -112,9 +115,7 @@ void show_regs(struct pt_regs * regs) flags = condition_codes(regs); - printk("\n" - "pc : [<%08lx>]\n" - "lr : [<%08lx>]\n" + printk( "pc : [<%08lx>] lr : [<%08lx>]\n" "sp : %08lx ip : %08lx fp : %08lx\n", instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp, @@ -133,22 +134,23 @@ void show_regs(struct pt_regs * regs) flags & CC_Z_BIT ? 'Z' : 'z', flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); - printk(" IRQs %s FIQs %s Mode %s\n", + printk(" IRQs %s FIQs %s Mode %s Segment %s\n", interrupts_enabled(regs) ? "on" : "off", fast_interrupts_enabled(regs) ? "on" : "off", - processor_modes[processor_mode(regs)]); -#if defined(CONFIG_CPU_ARM6) || defined(CONFIG_CPU_SA110) -{ int ctrl, transbase, dac; - __asm__ ( -" mrc p15, 0, %0, c1, c0\n" -" mrc p15, 0, %1, c2, c0\n" -" mrc p15, 0, %2, c3, c0\n" - : "=r" (ctrl), "=r" (transbase), "=r" (dac)); - printk("Control: %04X Table: %08X DAC: %08X ", - ctrl, transbase, dac); - } + processor_modes[processor_mode(regs)], + get_fs() == get_ds() ? "kernel" : "user"); +#if defined(CONFIG_CPU_32) + { + int ctrl, transbase, dac; + __asm__ ( + " mrc p15, 0, %0, c1, c0\n" + " mrc p15, 0, %1, c2, c0\n" + " mrc p15, 0, %2, c3, c0\n" + : "=r" (ctrl), "=r" (transbase), "=r" (dac)); + printk("Control: %04X Table: %08X DAC: %08X\n", + ctrl, transbase, dac); + } #endif - printk ("Segment %s\n", get_fs() == get_ds() ? "kernel" : "user"); } /* diff --git a/arch/arm/kernel/setup-ebsa110.c b/arch/arm/kernel/setup-ebsa110.c index 8cbfe7dc3..2da4d6327 100644 --- a/arch/arm/kernel/setup-ebsa110.c +++ b/arch/arm/kernel/setup-ebsa110.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -27,9 +26,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -41,17 +42,25 @@ #define MEM_SIZE (16*1024*1024) -static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; - -struct processor processor; struct screen_info screen_info; +struct processor processor; unsigned char aux_device_present; + +extern const struct processor sa110_processor_functions; + +struct armversions armidlist[] = { + { 0x4401a100, 0xfffffff0, F_MMU|F_32BIT , "DEC", "sa110" , &sa110_processor_functions , "sa1x"}, + { 0x00000000, 0x00000000, 0 , "***", "*unknown*" , NULL , NULL } +}; + unsigned long arm_id; +int armidindex; extern int root_mountflags; extern int _etext, _edata, _end; -extern const struct processor sa110_processor_functions; + +static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, }; + char saved_command_line[COMMAND_LINE_SIZE]; #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ @@ -111,6 +120,8 @@ __initfunc(void setup_arch(char **cmdline_p, memory_start = (unsigned long)&_end; + armidindex = 0; + processor = sa110_processor_functions; processor._proc_init(); @@ -154,6 +165,10 @@ __initfunc(void setup_arch(char **cmdline_p, *memory_start_p = memory_start; *memory_end_p = memory_end; strcpy (system_utsname.machine, "sa110"); + +#ifdef CONFIG_FB + conswitchp = &fb_con; +#endif } int get_cpuinfo(char * buffer) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a3b86fef7..b69ce22cb 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -27,7 +27,9 @@ #include #include #include +#include +#include #include #include #include @@ -38,7 +40,9 @@ #include struct drive_info_struct { char dummy[32]; } drive_info; -struct screen_info screen_info; +struct screen_info screen_info = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8 +}; struct processor processor; unsigned char aux_device_present; @@ -49,28 +53,39 @@ extern const struct processor arm6_processor_functions; extern const struct processor arm7_processor_functions; extern const struct processor sa110_processor_functions; -struct armversions armidlist[] = { -#if defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) - { 0x41560200, 0xfffffff0, F_MEMC , "ARM/VLSI", "arm2" , &arm2_processor_functions }, - { 0x41560250, 0xfffffff0, F_MEMC , "ARM/VLSI", "arm250" , &arm250_processor_functions }, - { 0x41560300, 0xfffffff0, F_MEMC|F_CACHE, "ARM/VLSI", "arm3" , &arm3_processor_functions }, -#endif -#if defined(CONFIG_CPU_ARM6) || defined(CONFIG_CPU_SA110) - { 0x41560600, 0xfffffff0, F_MMU|F_32BIT , "ARM/VLSI", "arm6" , &arm6_processor_functions }, - { 0x41560610, 0xfffffff0, F_MMU|F_32BIT , "ARM/VLSI", "arm610" , &arm6_processor_functions }, - { 0x41007000, 0xffffff00, F_MMU|F_32BIT , "ARM/VLSI", "arm7" , &arm7_processor_functions }, - { 0x41007100, 0xffffff00, F_MMU|F_32BIT , "ARM/VLSI", "arm710" , &arm7_processor_functions }, - { 0x4401a100, 0xfffffff0, F_MMU|F_32BIT , "DEC", "sa110" , &sa110_processor_functions }, +char elf_platform[ELF_PLATFORM_SIZE]; + +const struct armversions armidlist[] = { + /*-- Match -- --- Mask -- -- Manu -- Processor uname -m --- ELF STUFF --- + --- processor asm funcs --- */ +#if defined(CONFIG_CPU_26) + { 0x41560200, 0xfffffff0, "ARM/VLSI", "arm2" , "armv1" , "v1", 0, + &arm2_processor_functions }, + { 0x41560250, 0xfffffff0, "ARM/VLSI", "arm250" , "armv2" , "v2", HWCAP_SWP, + &arm250_processor_functions }, + { 0x41560300, 0xfffffff0, "ARM/VLSI", "arm3" , "armv2" , "v2", HWCAP_SWP, + &arm3_processor_functions }, +#elif defined(CONFIG_CPU_32) + { 0x41560600, 0xfffffff0, "ARM/VLSI", "arm6" , "armv3" , "v3", HWCAP_SWP, + &arm6_processor_functions }, + { 0x41560610, 0xfffffff0, "ARM/VLSI", "arm610" , "armv3" , "v3", HWCAP_SWP, + &arm6_processor_functions }, + { 0x41007000, 0xffffff00, "ARM/VLSI", "arm7" , "armv3" , "v3", HWCAP_SWP, + &arm7_processor_functions }, + /* ARM710 IDs are non-standard */ + { 0x41007100, 0xfff8ff00, "ARM/VLSI", "arm710" , "armv3" , "v3", HWCAP_SWP, + &arm7_processor_functions }, + { 0x4401a100, 0xfffffff0, "DEC", "sa110" , "armv4" , "v3", HWCAP_SWP|HWCAP_HALF, + &sa110_processor_functions }, #endif - { 0x00000000, 0x00000000, 0 , "***", "*unknown*" , NULL } + { 0x00000000, 0x00000000, "***", "unknown", "unknown", "**", 0, NULL } }; -static struct param_struct *params = (struct param_struct *)PARAMS_BASE; +static const struct param_struct *params = (struct param_struct *)PARAMS_BASE; unsigned long arm_id; unsigned int vram_half_sam; int armidindex; -int ioebpresent; int memc_ctrl_reg; int number_ide_drives; int number_mfm_drives; @@ -92,9 +107,11 @@ extern unsigned long real_end_mem; */ #ifdef CONFIG_ARCH_RPC -extern void init_dram_banks(struct param_struct *params); +extern void +init_dram_banks(const struct param_struct *params); -static void setup_rpc (struct param_struct *params) +static void +setup_rpc(const struct param_struct *params) { init_dram_banks(params); @@ -124,11 +141,12 @@ extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ extern int rd_image_start; /* starting block # of image */ -static void setup_ramdisk (struct param_struct *params) +static void +setup_ramdisk(const struct param_struct *params) { - rd_image_start = params->u1.s.rd_start; - rd_prompt = (params->u1.s.flags & FLAG_RDPROMPT) == 0; - rd_doload = (params->u1.s.flags & FLAG_RDLOAD) == 0; + rd_image_start = params->u1.s.rd_start; + rd_prompt = (params->u1.s.flags & FLAG_RDPROMPT) == 0; + rd_doload = (params->u1.s.flags & FLAG_RDLOAD) == 0; } #else #define setup_ramdisk(p) @@ -138,33 +156,30 @@ static void setup_ramdisk (struct param_struct *params) * initial ram disk */ #ifdef CONFIG_BLK_DEV_INITRD -static void setup_initrd (struct param_struct *params, unsigned long memory_end) +static void +setup_initrd(const struct param_struct *params, unsigned long memory_end) { - initrd_start = params->u1.s.initrd_start; - initrd_end = params->u1.s.initrd_start + params->u1.s.initrd_size; - - if (initrd_end > memory_end) { - printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx) - disabling initrd\n", - initrd_end, memory_end); - initrd_start = 0; - } -} -#else -#define setup_initrd(p,m) -#endif + if (params->u1.s.initrd_start) { + initrd_start = params->u1.s.initrd_start; + initrd_end = initrd_start + params->u1.s.initrd_size; + } else { + initrd_start = 0; + initrd_end = 0; + } -#ifdef IOEB_BASE -static inline void check_ioeb_present(void) -{ - if (((*IOEB_BASE) & 15) == 5) - armidlist[armidindex].features |= F_IOEB; + if (initrd_end > memory_end) { + printk ("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx) - disabling initrd\n", + initrd_end, memory_end); + initrd_start = 0; + } } #else -#define check_ioeb_present() +#define setup_initrd(p,m) #endif -static inline void get_processor_type (void) +static inline void +get_processor_type(void) { for (armidindex = 0; ; armidindex ++) if (!((armidlist[armidindex].id ^ arm_id) & @@ -187,7 +202,7 @@ static inline void get_processor_type (void) /* Can this be initdata? --pb * command_line can be, saved_command_line can't though */ -static char command_line[COMMAND_LINE_SIZE] = { 0, }; +static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; __initfunc(void setup_arch(char **cmdline_p, @@ -195,7 +210,8 @@ __initfunc(void setup_arch(char **cmdline_p, { static unsigned char smptrap; unsigned long memory_start, memory_end; - char c = ' ', *to = command_line, *from; + char endian = 'l', c = ' ', *to = command_line; + char *from; int len = 0; if (smptrap == 1) @@ -203,12 +219,13 @@ __initfunc(void setup_arch(char **cmdline_p, smptrap = 1; get_processor_type (); - check_ioeb_present (); processor._proc_init (); +#ifndef CONFIG_FB bytes_per_char_h = params->u1.s.bytes_per_char_h; bytes_per_char_v = params->u1.s.bytes_per_char_v; - from = params->commandline; +#endif + from = (char *)params->commandline; ROOT_DEV = to_kdev_t (params->u1.s.rootdev); ORIG_X = params->u1.s.video_x; ORIG_Y = params->u1.s.video_y; @@ -218,8 +235,8 @@ __initfunc(void setup_arch(char **cmdline_p, number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3; number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; - setup_rpc (params); - setup_ramdisk (params); + setup_rpc(params); + setup_ramdisk(params); if (!(params->u1.s.flags & FLAG_READONLY)) root_mountflags &= ~MS_RDONLY; @@ -265,36 +282,73 @@ __initfunc(void setup_arch(char **cmdline_p, *memory_start_p = memory_start; *memory_end_p = memory_end; - setup_initrd (params, memory_end); + setup_initrd(params, memory_end); + + sprintf(system_utsname.machine, "%s%c", armidlist[armidindex].arch_vsn, endian); + sprintf(elf_platform, "%s%c", armidlist[armidindex].elf_vsn, endian); - strcpy (system_utsname.machine, armidlist[armidindex].name); +#ifdef CONFIG_FB + conswitchp = &fb_con; +#endif } -#define ISSET(bit) (armidlist[armidindex].features & bit) +#if defined(CONFIG_ARCH_ARC) +#define HARDWARE "Acorn-Archimedes" +#define IO_BUS "Acorn" +#elif defined(CONFIG_ARCH_A5K) +#define HARDWARE "Acorn-A5000" +#define IO_BUS "Acorn" +#elif defined(CONFIG_ARCH_RPC) +#define HARDWARE "Acorn-RiscPC" +#define IO_BUS "Acorn" +#elif defined(CONFIG_ARCH_EBSA110) +#define HARDWARE "DEC-EBSA110" +#define IO_BUS "DEC" +#elif defined(CONFIG_ARCH_EBSA285) +#define HARDWARE "DEC-EBSA285" +#define IO_BUS "PCI" +#elif defined(CONFIG_ARCH_NEXUSPCI) +#define HARDWARE "Nexus-NexusPCI" +#define IO_BUS "PCI" +#elif defined(CONFIG_ARCH_VNC) +#define HARDWARE "Corel-VNC" +#define IO_BUS "PCI" +#else +#define HARDWARE "unknown" +#define IO_BUS "unknown" +#endif + +#if defined(CONFIG_CPU_ARM2) +#define OPTIMISATION "ARM2" +#elif defined(CONFIG_CPU_ARM3) +#define OPTIMISATION "ARM3" +#elif defined(CONFIG_CPU_ARM6) +#define OPTIMISATION "ARM6" +#elif defined(CONFIG_CPU_ARM7) +#define OPTIMISATION "ARM7" +#elif defined(CONFIG_CPU_SA110) +#define OPTIMISATION "StrongARM" +#else +#define OPTIMISATION "unknown" +#endif int get_cpuinfo(char * buffer) { int len; - len = sprintf (buffer, "CPU:\n" - "Type\t\t: %s\n" - "Revision\t: %d\n" - "Manufacturer\t: %s\n" - "32bit modes\t: %s\n" - "BogoMips\t: %lu.%02lu\n", - armidlist[armidindex].name, - (int)arm_id & 15, - armidlist[armidindex].manu, - ISSET (F_32BIT) ? "yes" : "no", - (loops_per_sec+2500) / 500000, - ((loops_per_sec+2500) / 5000) % 100); - len += sprintf (buffer + len, - "\nHardware:\n" - "Mem System\t: %s\n" - "IOEB\t\t: %s\n", - ISSET(F_MEMC) ? "MEMC" : - ISSET(F_MMU) ? "MMU" : "*unknown*", - ISSET(F_IOEB) ? "present" : "absent" - ); + len = sprintf(buffer, + "Processor\t: %s %s rev %d\n" + "BogoMips\t: %lu.%02lu\n" + "Hardware\t: %s\n" + "Optimisation\t: %s\n" + "IO Bus\t: %s\n", + armidlist[armidindex].manu, + armidlist[armidindex].name, + (int)arm_id & 15, + (loops_per_sec+2500) / 500000, + ((loops_per_sec+2500) / 5000) % 100, + HARDWARE, + OPTIMISATION, + IO_BUS); return len; } diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 0cba3dd07..59e802a6c 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -4,7 +4,7 @@ * Copyright (C) 1995, 1996 Russell King */ -#include /* for CONFIG_CPU_ARM6 and CONFIG_CPU_SA110 */ +#include #include #include #include @@ -37,7 +37,6 @@ extern int ptrace_set_bpt (struct task_struct *); */ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) { - sigset_t saveset; mask &= _BLOCKABLE; @@ -154,7 +153,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) __get_user(regs->ARM_sp, &sc->arm_sp); __get_user(regs->ARM_lr, &sc->arm_lr); __get_user(regs->ARM_pc, &sc->arm_pc); /* security! */ -#if defined(CONFIG_CPU_ARM6) || defined(CONFIG_CPU_SA110) +#ifdef CONFIG_CPU_32 __get_user(regs->ARM_cpsr, &sc->arm_cpsr); /* security! */ #endif @@ -238,7 +237,7 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/ __put_user (regs->ARM_sp, &sc->arm_sp); __put_user (regs->ARM_lr, &sc->arm_lr); __put_user (regs->ARM_pc, &sc->arm_pc); /* security! */ -#if defined(CONFIG_CPU_ARM6) || defined(CONFIG_CPU_SA110) +#ifdef CONFIG_CPU_32 __put_user (regs->ARM_cpsr, &sc->arm_cpsr); /* security! */ #endif diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index ab514903d..ba0d4eda2 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -30,8 +30,6 @@ */ /* proc/system.h */ const char xchg_str[] = "xchg"; -/* arch/dma.h */ -const char dma_str[] = "%s: dma %d not supported\n"; /* * sys_pipe() is the normal C calling standard for creating @@ -241,7 +239,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct lock_kernel(); if (!newsp) newsp = regs->ARM_sp; - ret = do_fork(clone_flags, newsp, regs); unlock_kernel(); return ret; @@ -311,16 +308,20 @@ sys_compat_mount (char *devname, char *dirname, char *type, unsigned long flags, asmlinkage int sys_uname (struct old_utsname * name) { static int warned = 0; - + int err; + if (warned == 0) { warned ++; printk (KERN_NOTICE "%s (%d): obsolete uname call\n", current->comm, current->pid); } - if (name && !copy_to_user (name, &system_utsname, sizeof (*name))) - return 0; - return -EFAULT; + if(!name) + return -EFAULT; + down(&uts_sem); + err=copy_to_user (name, &system_utsname, sizeof (*name)); + up(&uts_sem); + return err?-EFAULT:0; } asmlinkage int sys_olduname(struct oldold_utsname * name) @@ -340,6 +341,8 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; + down(&uts_sem); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error -= __put_user(0,name->sysname+__OLD_UTS_LEN); error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); @@ -350,6 +353,9 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) error -= __put_user(0,name->version+__OLD_UTS_LEN); error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error -= __put_user(0,name->machine+__OLD_UTS_LEN); + + up(&uts_sem); + error = error ? -EFAULT : 0; return error; diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 1f598e14d..32aa6a083 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -24,11 +24,11 @@ #include #include #include +#include #include #include #include -#include #include #include diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 222fd6b17..2170dfd58 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -24,6 +24,7 @@ #include #include +extern struct task_struct *last_task_used_math; extern void fpe_save(struct fp_soft_struct *); extern void fpe_restore(struct fp_soft_struct *); extern void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret); @@ -49,7 +50,7 @@ int kstack_depth_to_print = 200; static int verify_stack_pointer (unsigned long stackptr, int size) { -#if defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) +#ifdef CONFIG_CPU_26 if (stackptr < 0x02048000 || stackptr + size > 0x03000000) return -EFAULT; #else @@ -90,38 +91,52 @@ void dump_mem(unsigned long bottom, unsigned long top) #define VMALLOC_OFFSET (8*1024*1024) #define MODULE_RANGE (8*1024*1024) -static void dump_instr (unsigned long pc) +static void dump_instr(unsigned long pc, int user) { unsigned long module_start, module_end; int pmin = -2, pmax = 3, ok = 0; extern char start_kernel, _etext; - module_start = VMALLOC_START; - module_end = module_start + MODULE_RANGE; - - if ((pc >= (unsigned long) &start_kernel) && - (pc <= (unsigned long) &_etext)) { - if (pc + pmin < (unsigned long) &start_kernel) - pmin = ((unsigned long) &start_kernel) - pc; - if (pc + pmax > (unsigned long) &_etext) - pmax = ((unsigned long) &_etext) - pc; - ok = 1; - } else if (pc >= module_start && pc <= module_end) { - if (pc + pmin < module_start) - pmin = module_start - pc; - if (pc + pmax > module_end) - pmax = module_end - pc; - ok = 1; - } + if (!user) { + module_start = VMALLOC_START; + module_end = module_start + MODULE_RANGE; + + if ((pc >= (unsigned long) &start_kernel) && + (pc <= (unsigned long) &_etext)) { + if (pc + pmin < (unsigned long) &start_kernel) + pmin = ((unsigned long) &start_kernel) - pc; + if (pc + pmax > (unsigned long) &_etext) + pmax = ((unsigned long) &_etext) - pc; + ok = 1; + } else if (pc >= module_start && pc <= module_end) { + if (pc + pmin < module_start) + pmin = module_start - pc; + if (pc + pmax > module_end) + pmax = module_end - pc; + ok = 1; + } + } else + ok = verify_area(VERIFY_READ, (void *)(pc + pmin), pmax - pmin) == 0; + printk ("Code: "); if (ok) { int i; for (i = pmin; i < pmax; i++) - printk("%08lx ", ((unsigned long *)pc)[i]); + printk(i == 0 ? "(%08lx) " : "%08lx ", ((unsigned long *)pc)[i]); printk ("\n"); } else printk ("pc not in code space\n"); -} +} + +static void dump_state(char *str, struct pt_regs *regs, int err) +{ + console_verbose(); + printk("Internal error: %s: %x\n", str, err); + printk("CPU: %d\n", smp_processor_id()); + show_regs(regs); + printk("Process %s (pid: %d, stackpage=%08lx)\n", + current->comm, current->pid, 4096+(unsigned long)current); +} /* * This function is protected against kernel-mode re-entrancy. If it @@ -149,12 +164,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret) break; } - console_verbose(); - printk("Internal error: %s: %x\n", str, err); - printk("CPU: %d", smp_processor_id()); - show_regs(regs); - printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, 4096+(unsigned long)current); + dump_state(str, regs, err); cstack = (unsigned long)(regs + 1); sstack = 4096+(unsigned long)current; @@ -180,7 +190,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret) } } - dump_instr(instruction_pointer(regs)); + dump_instr(instruction_pointer(regs), 0); died = 0; if (ret != -1) do_exit (ret); @@ -268,13 +278,13 @@ asmlinkage void arm_syscall (int no, struct pt_regs *regs) { switch (no) { case 0: /* branch through 0 */ - printk ("[%d] %s: branch through zero\n", current->pid, current->comm); - force_sig (SIGILL, current); - if (user_mode(regs)) { - show_regs (regs); - c_backtrace (regs->ARM_fp, processor_mode(regs)); - } - die_if_kernel ("Oops", regs, 0, SIGILL); + force_sig(SIGSEGV, current); +// if (user_mode(regs)) { +// dump_state("branch through zero", regs, 0); +// if (regs->ARM_fp) +// c_backtrace (regs->ARM_fp, processor_mode(regs)); +// } + die_if_kernel ("branch through zero", regs, 0, SIGSEGV); break; case 1: /* SWI_BREAK_POINT */ @@ -297,8 +307,7 @@ asmlinkage void arm_syscall (int no, struct pt_regs *regs) asmlinkage void deferred(int n, struct pt_regs *regs) { - printk ("[%d] %s: old system call %X\n", current->pid, current->comm, n); - show_regs (regs); + dump_state("old system call", regs, n); force_sig (SIGILL, current); } @@ -312,3 +321,37 @@ asmlinkage void arm_invalidptr (const char *function, int size) printk ("Invalid pointer size in %s (PC=%p) size %d\n", function, __builtin_return_address(0), size); } + +#ifdef CONFIG_CPU_26 +asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs) +{ + unsigned long phys, addr = instruction_pointer(regs); + +#ifdef CONFIG_DEBUG_ERRORS + printk("pid=%d\n", current->pid); + + show_regs(regs); + dump_instr(instruction_pointer(regs), 1); + { + pgd_t *pgd; + + printk ("current->tss.memmap = %08lX\n", current->tss.memmap); + pgd = pgd_offset(current->mm, addr); + printk ("*pgd = %08lx", pgd_val (*pgd)); + if (!pgd_none (*pgd)) { + pmd_t *pmd; + pmd = pmd_offset (pgd, addr); + printk (", *pmd = %08lx", pmd_val (*pmd)); + if (!pmd_none (*pmd)) { + unsigned long ptr = pte_page(*pte_offset(pmd, addr)); + printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr))); + phys = ptr + (addr & 0x7fff); + } + } + printk ("\n"); + } +#endif + panic("unknown data abort code %d [pc=%08lx *pc=%08lx lr=%08lx sp=%08lx]", + code, regs->ARM_pc, instr, regs->ARM_lr, regs->ARM_sp); +} +#endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 8ec13266d..5d0974ab3 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -6,7 +6,7 @@ L_TARGET := lib.a L_OBJS := backtrace.o bitops.o checksum.o delay.o fp_support.o \ - loaders.o memcpy.o memfastset.o system.o string.o uaccess.o + loaders.o memcpy.o system.o string.o uaccess.o io.o ifeq ($(PROCESSOR),armo) L_OBJS += uaccess-armo.o @@ -38,6 +38,8 @@ constants.h: getconsdata.o extractconstants.pl getconsdata.o: getconsdata.c $(CC) $(CFLAGS) -c getconsdata.c +checksum.o: constants.h + %.o: %.S ifneq ($(CONFIG_BINUTILS_NEW),y) $(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< | tr ';$$' '\n#' > ..tmp.$<.s diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index d48055b70..3789d7d4d 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -3,6 +3,7 @@ * * Copyright (C) 1995, 1996 Russell King */ +#include #include #include .text @@ -21,9 +22,13 @@ ENTRY(__backtrace) ENTRY(c_backtrace) stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... +#ifdef CONFIG_CPU_32 tst r1, #0x10 @ 26 or 32-bit? moveq mask, #0xfc000003 movne mask, #0 +#else + mov mask, #0xfc000003 +#endif tst mask, r0 movne r0, #0 movs frame, r0 diff --git a/arch/arm/lib/checksum.S b/arch/arm/lib/checksum.S index f273f960d..06eb98edd 100644 --- a/arch/arm/lib/checksum.S +++ b/arch/arm/lib/checksum.S @@ -3,9 +3,11 @@ * * Copyright (C) 1995, 1996, 1997, 1998 Russell King */ +#include #include #include #include +#include "constants.h" .text @@ -66,25 +68,147 @@ ENTRY(csum_partial) * Params : r0 = src, r1 = dst, r2 = len, r3 = sum, [sp, #0] = &err * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT */ +#if defined(CONFIG_CPU_32) -#define USER_LDR(instr...) \ -9999: instr; \ - .section __ex_table, "a"; \ - .align 3; \ - .long 9999b, 6001f; \ - .previous; + .macro save_regs + stmfd sp!, {r4 - r8, fp, ip, lr, pc} + .endm + +#define LOAD_REGS(cond) \ + LOADREGS(##cond##ea,fp,{r4 - r8, fp, sp, pc}) + + .macro load1b, reg1 +9999: ldrbt \reg1, [r0], $1 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2b, reg1, reg2 +9999: ldrbt \reg1, [r0], $1 +9998: ldrbt \reg2, [r0], $1 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load1l, reg1 +9999: ldrt \reg1, [r0], $4 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2l, reg1, reg2 +9999: ldrt \reg1, [r0], $4 +9998: ldrt \reg2, [r0], $4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load4l, reg1, reg2, reg3, reg4 +9999: ldrt \reg1, [r0], $4 +9998: ldrt \reg2, [r0], $4 +9997: ldrt \reg3, [r0], $4 +9996: ldrt \reg4, [r0], $4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .long 9997b, 6001f + .long 9996b, 6001f + .previous + .endm + +#elif defined(CONFIG_CPU_26) + + .macro save_regs + stmfd sp!, {r4 - r9, fp, ip, lr, pc} + mov r9, sp, lsr #13 + mov r9, r9, lsl #13 + ldr r9, [r9, #TSK_ADDR_LIMIT] + mov r9, r9, lsr #24 + .endm + +#define LOAD_REGS(cond) \ + LOADREGS(##cond##ea,fp,{r4 - r9, fp, sp, pc}) + + .macro load1b, reg1 + tst r9, #0x01 +9999: ldreqbt \reg1, [r0], #1 + ldrneb \reg1, [r0], #1 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2b, reg1, reg2 + tst r9, #0x01 +9999: ldreqbt \reg1, [r0], #1 + ldrneb \reg1, [r0], #1 +9998: ldreqbt \reg2, [r0], #1 + ldrneb \reg2, [r0], #1 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load1l, reg1 + tst r9, #0x01 +9999: ldreqt \reg1, [r0], #4 + ldrne \reg1, [r0], #4 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2l, reg1, reg2 + tst r9, #0x01 + ldmneia r0!, {\reg1, \reg2} +9999: ldreqt \reg1, [r0], #4 +9998: ldreqt \reg2, [r0], #4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load4l, reg1, reg2, reg3, reg4 + tst r9, #0x01 + ldmneia r0!, {\reg1, \reg2, \reg3, \reg4} +9999: ldreqt \reg1, [r0], #4 +9998: ldreqt \reg2, [r0], #4 +9997: ldreqt \reg3, [r0], #4 +9996: ldreqt \reg4, [r0], #4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .long 9997b, 6001f + .long 9996b, 6001f + .previous + .endm + +#else +#error Unknown CPU architecture +#endif ENTRY(csum_partial_copy_from_user) mov ip, sp - stmfd sp!, {r4 - r8, fp, ip, lr, pc} + save_regs sub fp, ip, #4 cmp r2, #4 blt .too_small_user tst r1, #2 @ Test destination alignment beq .dst_aligned_user - subs r2, r2, #2 @ We dont know if SRC is aligned... -USER_LDR( ldrbt ip, [r0], #1) -USER_LDR( ldrbt r8, [r0], #1) + subs r2, r2, #2 @ We do not know if SRC is aligned... + load2b ip, r8 orr ip, ip, r8, lsl #8 adds r3, r3, ip adcs r3, r3, #0 @@ -97,11 +221,7 @@ USER_LDR( ldrbt r8, [r0], #1) adds r3, r3, #0 bics ip, r2, #15 @ Routine for src & dst aligned beq 2f -1: -USER_LDR( ldrt r4, [r0], #4) -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) -USER_LDR( ldrt r7, [r0], #4) +1: load4l r4, r5, r6, r7 stmia r1!, {r4, r5, r6, r7} adcs r3, r3, r4 adcs r3, r3, r5 @@ -114,21 +234,19 @@ USER_LDR( ldrt r7, [r0], #4) beq 4f tst ip, #8 beq 3f -USER_LDR( ldrt r4, [r0], #4) -USER_LDR( ldrt r5, [r0], #4) + load2l r4, r5 stmia r1!, {r4, r5} adcs r3, r3, r4 adcs r3, r3, r5 tst ip, #4 beq 4f -3: -USER_LDR( ldrt r4, [r0], #4) +3: load1l r4 str r4, [r1], #4 adcs r3, r3, r4 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) -USER_LDR( ldrt r4, [r0], #4) + LOAD_REGS(eq) + load1l r4 tst r2, #2 beq .exit adcs r3, r3, r4, lsl #16 @@ -141,33 +259,33 @@ USER_LDR( ldrt r4, [r0], #4) andne r4, r4, #255 adcnes r3, r3, r4 adcs r0, r3, #0 - LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(al) .too_small_user: teq r2, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(eq) cmp r2, #2 blt .too_small_user1 -USER_LDR( ldrbt ip, [r0], #1) -USER_LDR( ldrbt r8, [r0], #1) + load2b ip, r8 orr ip, ip, r8, lsl #8 adds r3, r3, ip strb ip, [r1], #1 strb r8, [r1], #1 tst r2, #1 -.too_small_user1: -USER_LDR( ldrnebt ip, [r0], #1) - strneb ip, [r1], #1 - adcnes r3, r3, ip - adcs r0, r3, #0 - LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) +.too_small_user1: @ C = 0 + beq .csum_exit + load1b ip + strb ip, [r1], #1 + adcs r3, r3, ip +.csum_exit: adc r0, r3, #0 + LOAD_REGS(al) .src_not_aligned_user: cmp r2, #4 blt .too_small_user and ip, r0, #3 bic r0, r0, #3 -USER_LDR( ldrt r4, [r0], #4) + load1l r4 cmp ip, #2 beq .src2_aligned_user bhi .src3_aligned_user @@ -175,11 +293,7 @@ USER_LDR( ldrt r4, [r0], #4) adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) -USER_LDR( ldrt r7, [r0], #4) -USER_LDR( ldrt r8, [r0], #4) +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #24 mov r5, r5, lsr #8 orr r5, r5, r6, lsl #24 @@ -200,8 +314,7 @@ USER_LDR( ldrt r8, [r0], #4) beq 4f tst ip, #8 beq 3f -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) + load2l r5, r6 orr r4, r4, r5, lsl #24 mov r5, r5, lsr #8 orr r5, r5, r6, lsl #24 @@ -211,15 +324,14 @@ USER_LDR( ldrt r6, [r0], #4) mov r4, r6, lsr #8 tst ip, #4 beq 4f -3: -USER_LDR( ldrt r5, [r0], #4) +3: load1l r5 orr r4, r4, r5, lsl #24 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #8 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(eq) tst r2, #2 beq .exit adcs r3, r3, r4, lsl #16 @@ -234,11 +346,7 @@ USER_LDR( ldrt r5, [r0], #4) adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) -USER_LDR( ldrt r7, [r0], #4) -USER_LDR( ldrt r8, [r0], #4) +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #16 mov r5, r5, lsr #16 orr r5, r5, r6, lsl #16 @@ -259,8 +367,7 @@ USER_LDR( ldrt r8, [r0], #4) beq 4f tst ip, #8 beq 3f -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) + load2l r5, r6 orr r4, r4, r5, lsl #16 mov r5, r5, lsr #16 orr r5, r5, r6, lsl #16 @@ -270,22 +377,21 @@ USER_LDR( ldrt r6, [r0], #4) mov r4, r6, lsr #16 tst ip, #4 beq 4f -3: -USER_LDR( ldrt r5, [r0], #4) +3: load1l r5 orr r4, r4, r5, lsl #16 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #16 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(eq) tst r2, #2 beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 mov r4, r4, lsr #8 strb r4, [r1], #1 -USER_LDR( ldrb r4, [r0], #1) + load1b r4 b .exit .src3_aligned_user: @@ -293,11 +399,7 @@ USER_LDR( ldrb r4, [r0], #1) adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) -USER_LDR( ldrt r7, [r0], #4) -USER_LDR( ldrt r8, [r0], #4) +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #8 mov r5, r5, lsr #24 orr r5, r5, r6, lsl #8 @@ -318,8 +420,7 @@ USER_LDR( ldrt r8, [r0], #4) beq 4f tst ip, #8 beq 3f -USER_LDR( ldrt r5, [r0], #4) -USER_LDR( ldrt r6, [r0], #4) + load2l r5, r6 orr r4, r4, r5, lsl #8 mov r5, r5, lsr #24 orr r5, r5, r6, lsl #8 @@ -329,20 +430,19 @@ USER_LDR( ldrt r6, [r0], #4) mov r4, r6, lsr #24 tst ip, #4 beq 4f -3: -USER_LDR( ldrt r5, [r0], #4) +3: load1l r5 orr r4, r4, r5, lsl #8 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #24 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(eq) tst r2, #2 beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 -USER_LDR( ldrt r4, [r0], #4) + load1l r4 strb r4, [r1], #1 adcs r3, r3, r4, lsl #24 mov r4, r4, lsr #8 @@ -351,14 +451,16 @@ USER_LDR( ldrt r4, [r0], #4) .section .fixup,"ax" .align 4 6001: mov r4, #-EFAULT - ldr r5, [sp, #4*8] + ldr r5, [fp, #4] str r4, [r5] - LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) + LOAD_REGS(al) + .previous /* Function: __u32 csum_partial_copy (const char *src, char *dst, int len, __u32 sum) * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum * Returns : r0 = new checksum */ +ENTRY(csum_partial_copy_nocheck) ENTRY(csum_partial_copy) mov ip, sp stmfd sp!, {r4 - r8, fp, ip, lr, pc} @@ -367,7 +469,7 @@ ENTRY(csum_partial_copy) blt Ltoo_small tst r1, #2 @ Test destination alignment beq Ldst_aligned - subs r2, r2, #2 @ We dont know if SRC is aligned... + subs r2, r2, #2 @ We do not know if SRC is aligned... ldrb ip, [r0], #1 ldrb r8, [r0], #1 orr ip, ip, r8, lsl #8 @@ -598,3 +700,21 @@ Lsrc3_aligned: mov r4, r4, lsr #24 adcs r3, r3, r4, lsl #24 mov r4, r4, lsr #8 b Lexit + +ENTRY(csum_ipv6_magic) + stmfd sp!, {lr} + adds ip, r2, r3 + ldmia r1, {r1 - r3, lr} + adcs ip, ip, r1 + adcs ip, ip, r2 + adcs ip, ip, r3 + adcs ip, ip, lr + ldmia r0, {r0 - r3} + adcs r0, ip, r0 + adcs r0, r0, r1 + adcs r0, r0, r2 + adcs r0, r0, r3 + ldr r3, [sp, #4] + adcs r0, r0, r3 + adcs r0, r0, #0 + LOADREGS(fd, sp!, {pc}) diff --git a/arch/arm/lib/extractconstants.pl b/arch/arm/lib/extractconstants.pl index ff095a232..8c96b3f28 100644 --- a/arch/arm/lib/extractconstants.pl +++ b/arch/arm/lib/extractconstants.pl @@ -24,7 +24,7 @@ while () { /elf32/ && ( $elf = 1 ); /a.out/ && ( $aout = 1 ); next if ($aout && ! / 07 /); - next if ($elf && ! (/^00...... g/ && /.data/)); + next if ($elf && ! (/^0*0...... g/ && /.data/)); next if (!$aout && !$elf); if ($aout) { @@ -33,8 +33,8 @@ while () { } if ($elf) { chomp; - $addr = substr ($_, 0, 8); - $name = substr ($_, 32); + $addr = substr ($_, 0, index($_, " ")); + $name = substr ($_, rindex($_, " ") + 1); $nam[hex($addr)] = $name; } } diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c index bdf09d5a3..59f989cfb 100644 --- a/arch/arm/lib/getconsdata.c +++ b/arch/arm/lib/getconsdata.c @@ -10,6 +10,8 @@ #include #include +#undef PAGE_READONLY + #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) #define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n) @@ -31,7 +33,7 @@ unsigned long PGD = OFF_MM(pgd); unsigned long TSS_MEMMAP = OFF_TSK(tss.memmap); unsigned long TSS_SAVE = OFF_TSK(tss.save); unsigned long TSS_FPESAVE = OFF_TSK(tss.fpstate.soft.save); -#if defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) +#ifdef CONFIG_CPU_26 unsigned long TSS_MEMCMAP = OFF_TSK(tss.memcmap); #endif diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S index 51550e014..d7769eef3 100644 --- a/arch/arm/lib/io-acorn.S +++ b/arch/arm/lib/io-acorn.S @@ -3,8 +3,7 @@ * * Copyright (C) 1995, 1996 Russell King */ -#include /* for CONFIG_CPU_ARM2 and CONFIG_CPU_ARM3 */ -#include +#include /* for CONFIG_CPU_nn */ #include #include #include @@ -171,7 +170,7 @@ ENTRY(outswb) @ Proto : void memc_write(int register, int value); @ Returns: nothing -#if defined(CONFIG_CPU_ARM2) || defined(CONFIG_CPU_ARM3) +#if defined(CONFIG_CPU_26) ENTRY(memc_write) cmp r0, #7 RETINSTR(movgt,pc,lr) diff --git a/arch/arm/lib/io-ebsa285.S b/arch/arm/lib/io-ebsa285.S index a5c6386f0..0ee1e37fc 100644 --- a/arch/arm/lib/io-ebsa285.S +++ b/arch/arm/lib/io-ebsa285.S @@ -1,4 +1,3 @@ -#define __ASSEMBLER__ #include ENTRY(insl) @@ -98,12 +97,50 @@ ENTRY(outsl) bne 4b mov pc, lr + /* Nobody could say these are optimal, but not to worry. */ -ENTRY(outsw) ENTRY(outswb) + mov r2, r2, lsr #1 +ENTRY(outsw) + add r0, r0, #0xff000000 + add r0, r0, #0x00e00000 +1: teq r2, #0 + ldrneh r3, [r1], #2 + strneh r3, [r0] + subne r2, r2, #1 + bne 1b mov pc, lr -ENTRY(insw) ENTRY(inswb) + mov r2, r2, lsr #1 +ENTRY(insw) + add r0, r0, #0xff000000 + add r0, r0, #0x00e00000 +1: teq r2, #0 + ldrneh r3, [r0] + strneh r3, [r1], #2 + subne r2, r2, #1 + bne 1b mov pc, lr + +ENTRY(insb) + add r0, r0, #0xff000000 + add r0, r0, #0x00e00000 +1: teq r2, #0 + ldrneb r3, [r0] + strneb r3, [r1], #1 + subne r2, r2, #1 + bne 1b + mov pc, lr + + +ENTRY(outsb) + add r0, r0, #0xff000000 + add r0, r0, #0x00e00000 +1: teq r2, #0 + ldrneb r3, [r1], #1 + strneb r3, [r0] + subne r2, r2, #1 + bne 1b + mov pc, lr diff --git a/arch/arm/lib/io.c b/arch/arm/lib/io.c new file mode 100644 index 000000000..ba2f9efd0 --- /dev/null +++ b/arch/arm/lib/io.c @@ -0,0 +1,43 @@ +#include + +/* + * Copy data from IO memory space to "real" memory space. + * This needs to be optimized. + */ +void _memcpy_fromio(void * to, unsigned long from, unsigned long count) +{ + while (count) { + count--; + *(char *) to = readb(from); + ((char *) to)++; + from++; + } +} + +/* + * Copy data from "real" memory space to IO memory space. + * This needs to be optimized. + */ +void _memcpy_toio(unsigned long to, void * from, unsigned long count) +{ + while (count) { + count--; + writeb(*(char *) from, to); + ((char *) from)++; + to++; + } +} + +/* + * "memset" on IO memory space. + * This needs to be optimized. + */ +void _memset_io(unsigned long dst, int c, unsigned long count) +{ + while (count) { + count--; + writeb(c, dst); + dst++; + } +} + diff --git a/arch/arm/lib/ll_char_wr.S b/arch/arm/lib/ll_char_wr.S index fb1a5c5a4..966d2846e 100644 --- a/arch/arm/lib/ll_char_wr.S +++ b/arch/arm/lib/ll_char_wr.S @@ -9,9 +9,9 @@ * 08-04-98 RMK Shifts re-ordered */ -@ Regs: [] = corruptable +@ Regs: [] = corruptible @ {} = used -@ () = dont use +@ () = do not use #include #include @@ -100,13 +100,13 @@ Lrow4bpplp: ldr r7, [lr, r7, lsl #2] Lrow8bpplp: mov ip, r7, lsr #4 ldr ip, [lr, ip, lsl #2] mul r4, r2, ip - and ip, r7, #15 - eor r4, r3, r4 - ldr ip, [lr, ip, lsl #2] - mul ip, r2, ip - tst r1, #7 + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + eor r4, r3, r4 @ avoid ip + tst r1, #7 @ avoid ip + sub r0, r0, r5 @ avoid ip eor ip, r3, ip - sub r0, r0, r5 stmia r0, {r4, ip} LOADREGS(eqfd, sp!, {r4 - r7, pc}) sub r1, r1, #1 @@ -114,13 +114,13 @@ Lrow8bpplp: mov ip, r7, lsr #4 mov ip, r7, lsr #4 ldr ip, [lr, ip, lsl #2] mul r4, r2, ip - and ip, r7, #15 - eor r4, r3, r4 - ldr ip, [lr, ip, lsl #2] - mul ip, r2, ip - tst r1, #7 + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + eor r4, r3, r4 @ avoid ip + tst r1, #7 @ avoid ip + sub r0, r0, r5 @ avoid ip eor ip, r3, ip - sub r0, r0, r5 stmia r0, {r4, ip} subne r1, r1, #1 ldrneb r7, [r6, r1] diff --git a/arch/arm/lib/memfastset.S b/arch/arm/lib/memfastset.S deleted file mode 100644 index a7e8a5d29..000000000 --- a/arch/arm/lib/memfastset.S +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/lib/memfastset.S - * - * Copyright (C) 1995, 1996 Russell King - */ -#include -#include - .text -@ Prototype: void memsetl (unsigned long *d, unsigned long c, size_t n); - -ENTRY(memsetl) - stmfd sp!, {lr} - cmp r2, #16 - blt 5f - mov r3, r1 - mov ip, r1 - mov lr, r1 - subs r2, r2, #32 - bmi 2f -1: stmia r0!, {r1, r3, ip, lr} - stmia r0!, {r1, r3, ip, lr} - LOADREGS(eqfd, sp!, {pc}) - subs r2, r2, #32 - bpl 1b -2: adds r2, r2, #16 - bmi 4f -3: stmia r0!, {r1, r3, ip, lr} - LOADREGS(eqfd, sp!, {pc}) - subs r2, r2, #16 - bpl 3b -4: add r2, r2, #16 -5: subs r2, r2, #4 - strge r1, [r0], #4 - bgt 5b - LOADREGS(fd, sp!, {pc}) diff --git a/arch/arm/lib/string.S b/arch/arm/lib/string.S index b54c902a4..17daa9d26 100644 --- a/arch/arm/lib/string.S +++ b/arch/arm/lib/string.S @@ -1,24 +1,55 @@ /* * linux/arch/arm/lib/string.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This is commonly used to clear the frame buffer and the frame + * backing buffer. As such, it will be rarely called with r2 < 32. + * + * Optimisations by Matthew Wilcox */ #include #include .text # Prototype: char *strrchr(const char *s,char c); -@ r0 = pointer, r1 = length - .global memzero -memzero: stmfd sp!, {lr} - mov r2, #0 - mov r3, #0 - mov ip, #0 - mov lr, #0 -1: subs r1, r1, #4*8 - stmgeia r0!, {r2, r3, ip, lr} - stmgeia r0!, {r2, r3, ip, lr} +/* + * Prototype: void memzero(void *d, size_t n) + */ +ENTRY(memzero) + mov r2, r1 + mov r1, #0 +/* + * Prototype: void memsetl(unsigned long *d, unsigned long c, size_t n) + */ +ENTRY(memsetl) + teq r2, #0 + RETINSTR(moveq,pc,lr) + stmfd sp!, {lr} + mov lr, r1 + mov r3, r1 + mov ip, r1 + + @ r2 = {32 ... 4} + +1: subs r2, r2, #32 + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} bgt 1b + LOADREGS(eqfd, sp!, {pc}) + + @ r2 can be {-4 ... -28} + + cmp r2, #-16 + stmgeia r0!, {r1, r3, ip, lr} + addlts r2, r2, #16 + LOADREGS(eqfd, sp!, {pc}) + + @ r2 can be {-4 ... -12} + + cmp r2, #-8 + stmgeia r0!, {r1, r3} + strne r1, [r0] LOADREGS(fd, sp!, {pc}) .global __page_memcpy diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index 78256b319..c9d729e85 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S @@ -7,7 +7,6 @@ * These are highly optimised both for the 4k page size * and for various alignments. */ -#include #include #include #include diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index be9be35f0..fc9809144 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -7,6 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +all: lib first_rule ifeq ($(MACHINE),a5k) MMARCH=arc else @@ -30,13 +31,14 @@ proc-arm2,3.o: ../lib/constants.h proc-arm6,7.o: ../lib/constants.h proc-sa110.o: ../lib/constants.h -.PHONY: ../lib/constants.h -../lib/constants.h: - @$(MAKE) -C ../lib constants.h - -ifneq ($(CONFIG_BINUTILS_NEW),y) %.o: %.S +ifneq ($(CONFIG_BINUTILS_NEW),y) $(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< | tr ';$$' '\n#' > ..$@.tmp.s $(CC) $(CFLAGS:-pipe=) -c -o $@ ..$@.tmp.s $(RM) ..$@.tmp.s +else + $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< endif + +.PHONY: lib +lib:; @$(MAKE) -C ../lib constants.h diff --git a/arch/arm/mm/fault-armo.c b/arch/arm/mm/fault-armo.c index 6e1024c30..9959eacb6 100644 --- a/arch/arm/mm/fault-armo.c +++ b/arch/arm/mm/fault-armo.c @@ -5,6 +5,7 @@ * Modifications for ARM processor (c) 1995, 1996 Russell King */ +#include #include #include #include @@ -29,9 +30,21 @@ struct pgtable_cache_struct quicklists; -void __bad_pte(pmd_t *pmd) +void __bad_pmd(pmd_t *pmd) { printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + set_pmd(pmd, mk_pmd(BAD_PAGETABLE)); +} + +void __bad_pmd_kernel(pmd_t *pmd) +{ + printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif set_pmd(pmd, mk_pmd(BAD_PAGETABLE)); } @@ -65,7 +78,7 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) } kfree (pte); if (pmd_bad(*pmd)) { - __bad_pte(pmd); + __bad_pmd(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; @@ -145,11 +158,11 @@ good_area: bad_area: up(&mm->mmap_sem); if (mode & FAULT_CODE_USER) { -extern int console_loglevel; -cli(); +//extern int console_loglevel; +//cli(); tsk->tss.error_code = mode; tsk->tss.trap_no = 14; -console_loglevel = 9; +//console_loglevel = 9; printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n", tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode); //#ifdef DEBUG @@ -157,7 +170,7 @@ console_loglevel = 9; c_backtrace (regs->ARM_fp, 0); //#endif force_sig(SIGSEGV, tsk); -while (1); +//while (1); goto out; } diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 051b336bf..370dbd28e 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -25,6 +25,8 @@ #define FAULT_CODE_READ 0x02 #define FAULT_CODE_USER 0x01 +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) + struct pgtable_cache_struct quicklists; void __bad_pmd(pmd_t *pmd) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 36b118eb2..a674b578d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -34,6 +34,22 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern char _etext, _stext, _edata, __bss_start, _end; extern char __init_begin, __init_end; +int do_check_pgt_cache(int low, int high) +{ + int freed = 0; + if(pgtable_cache_size > high) { + do { + if(pgd_quicklist) + free_pgd_slow(get_pgd_fast()), freed++; + if(pmd_quicklist) + free_pmd_slow(get_pmd_fast()), freed++; + if(pte_quicklist) + free_pte_slow(get_pte_fast()), freed++; + } while(pgtable_cache_size > low); + } + return freed; +} + /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -119,10 +135,10 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_ memzero (empty_zero_page, PAGE_SIZE); start_mem = setup_pagetables (start_mem, end_mem); - flush_tlb_all (); - update_mm_cache_all (); + flush_tlb_all(); + update_memc_all(); - return free_area_init (start_mem, end_mem); + return free_area_init(start_mem, end_mem); } /* diff --git a/arch/arm/mm/mm-arc.c b/arch/arm/mm/mm-arc.c index ff447a6be..6bb92f037 100644 --- a/arch/arm/mm/mm-arc.c +++ b/arch/arm/mm/mm-arc.c @@ -5,4 +5,78 @@ * * Copyright (C) 1998 Russell King */ -#include +#include +#include +#include + +unsigned long phys_screen_end; + +/* + * This routine needs more work to make it dynamically release/allocate mem! + */ +__initfunc(unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update)) +{ + static int updated = 0; + + if (updated) + return 0; + + updated = update; + + if (update) { + unsigned long address = log_start, offset; + pgd_t *pgdp; + + kmem = (kmem + 3) & ~3; + + pgdp = pgd_offset (&init_mm, address); /* +31 */ + offset = SCREEN_START; + while (address < SCREEN1_END) { + unsigned long addr_pmd, end_pmd; + pmd_t *pmdp; + + /* if (pgd_none (*pgdp)) alloc pmd */ + pmdp = pmd_offset (pgdp, address); /* +0 */ + addr_pmd = address & ~PGDIR_MASK; /* 088000 */ + end_pmd = addr_pmd + SCREEN1_END - address; /* 100000 */ + if (end_pmd > PGDIR_SIZE) + end_pmd = PGDIR_SIZE; + + do { + unsigned long addr_pte, end_pte; + pte_t *ptep; + + if (pmd_none (*pmdp)) { + pte_t *new_pte = (pte_t *)kmem; + kmem += PTRS_PER_PTE * BYTES_PER_PTR; + memzero (new_pte, PTRS_PER_PTE * BYTES_PER_PTR); + set_pmd (pmdp, mk_pmd(new_pte)); + } + + ptep = pte_offset (pmdp, addr_pmd); /* +11 */ + addr_pte = addr_pmd & ~PMD_MASK; /* 088000 */ + end_pte = addr_pte + end_pmd - addr_pmd; /* 100000 */ + if (end_pte > PMD_SIZE) + end_pte = PMD_SIZE; + + do { + set_pte (ptep, mk_pte(offset, PAGE_KERNEL)); + addr_pte += PAGE_SIZE; + offset += PAGE_SIZE; + ptep++; + } while (addr_pte < end_pte); + + pmdp++; + addr_pmd = (addr_pmd + PMD_SIZE) & PMD_MASK; + } while (addr_pmd < end_pmd); + + address = (address + PGDIR_SIZE) & PGDIR_MASK; + pgdp ++; + } + + phys_screen_end = offset; + flush_tlb_all (); + update_memc_all (); + } + return kmem; +} diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c new file mode 100644 index 000000000..b229e8987 --- /dev/null +++ b/arch/arm/mm/mm-armv.c @@ -0,0 +1,71 @@ +/* + * arch/arm/mm/mm-armv.c + * + * Common routines for ARM v3 and v4 architectures. + * + * Copyright (C) 1998 Russell King + * + * Do not compile this file directly! + */ + +#ifndef MAPPING +#error MAPPING not defined - do not compile this file individually +#endif + +static const struct mapping { + unsigned long virtual; + unsigned long physical; + unsigned long length; + int domain:4, + prot_read:1, + prot_write:1; +} mapping[] __initdata = { + MAPPING +}; + +#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0])) + +__initfunc(unsigned long setup_io_pagetables(unsigned long start_mem)) +{ + const struct mapping *mp; + int i; + + for (i = 0, mp = mapping; i < SIZEOFMAP; i++, mp++) { + unsigned long virtual, physical, length; + int prot; + + virtual = mp->virtual; + physical = mp->physical; + length = mp->length; + prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0); + + while ((virtual & 1048575 || physical & 1048575) && length >= PAGE_SIZE) { + alloc_init_page(&start_mem, virtual, physical, mp->domain, prot); + length -= PAGE_SIZE; + virtual += PAGE_SIZE; + physical += PAGE_SIZE; + } + + prot = (mp->prot_read ? PMD_SECT_AP_READ : 0) | + (mp->prot_write ? PMD_SECT_AP_WRITE : 0); + + while (length >= 1048576) { + alloc_init_section(&start_mem, virtual, physical, mp->domain, prot); + length -= 1048576; + virtual += 1048576; + physical += 1048576; + } + + prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0); + + while (length >= PAGE_SIZE) { + alloc_init_page(&start_mem, virtual, physical, mp->domain, prot); + length -= PAGE_SIZE; + virtual += PAGE_SIZE; + physical += PAGE_SIZE; + } + } + + return start_mem; +} + diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c index a937e098d..90865e0b6 100644 --- a/arch/arm/mm/mm-ebsa110.c +++ b/arch/arm/mm/mm-ebsa110.c @@ -1,26 +1,15 @@ /* * arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the Archimedes architecture + * Extra MM routines for the EBSA-110 architecture * * Copyright (C) 1998 Russell King */ - +#include #include -/* map in IO */ -void setup_io_pagetables(void) -{ - unsigned long address = IO_START; - int spi = IO_BASE >> PGDIR_SHIFT; - - pgd_val(swapper_pg_dir[spi-1]) = 0xc0000000 | PMD_TYPE_SECT | - PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE; +#define MAPPING \ + { IO_BASE - PGDIR_SIZE , 0xc0000000 , PGDIR_SIZE , DOMAIN_IO, 0, 1 }, \ + { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1 } - while (address < IO_START + IO_SIZE && address) { - pgd_val(swapper_pg_dir[spi++]) = address | PMD_TYPE_SECT | - PMD_DOMAIN(DOMAIN_IO) | - PMD_SECT_AP_WRITE; - address += PGDIR_SIZE; - } -} +#include "mm-armv.c" diff --git a/arch/arm/mm/mm-ebsa285.c b/arch/arm/mm/mm-ebsa285.c index eb5d7152a..82bbce899 100644 --- a/arch/arm/mm/mm-ebsa285.c +++ b/arch/arm/mm/mm-ebsa285.c @@ -3,16 +3,48 @@ * * Extra MM routines for the EBSA285 architecture * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Russell King, Dave Gilbert. */ +#include #include #include +#include #include #include #include #include - + +/* + * These two functions convert PCI bus addresses to virtual addresses + * and back again. + */ +unsigned long __virt_to_bus(unsigned long res) +{ + if (res < PAGE_OFFSET || res >= 0xD0000000) { + printk("__virt_to_bus: invalid address 0x%08lx\n", res); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + } else + res = (res - PAGE_OFFSET) + 0x10000000; + + return res; +} + +unsigned long __bus_to_virt(unsigned long res) +{ + if (res < 0x10000000 || res >= 0x20000000) { + printk("__bus_to_virt: invalid address 0x%08lx\n", res); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + } else + res = (res - 0x10000000) + PAGE_OFFSET; + + return res; +} + /* Logical Physical * 0xfff00000 0x40000000 X-Bus * 0xffe00000 0x7c000000 PCI I/O space @@ -23,75 +55,25 @@ * 0xf8000000 0x7b000000 PCI Config type 0 */ -static struct mapping { - unsigned long virtual; - unsigned long physical; - unsigned long length; -} io_mapping[] = { - /* - * This is to allow us to fiddle with the EEPROM - * This entry will go away in time - */ - { 0xd8000000, 0x41000000, 0x00400000 }, - - /* - * These ones are so that we can fiddle - * with the various cards (eg VGA) - * until we're happy with them... - */ - { 0xdc000000, 0x7c000000, 0x00100000 }, - { 0xe0000000, 0x80000000, 0x10000000 }, - - { 0xf8000000, 0x7b000000, 0x01000000 }, /* Type 0 Config */ - - { 0xf9000000, 0x7a000000, 0x01000000 }, /* Type 1 Config */ - - { 0xfc000000, 0x79000000, 0x01000000 }, /* PCI IACK */ - { 0xfd000000, 0x78000000, 0x01000000 }, /* Outbound wflsh*/ - { 0xfe000000, 0x42000000, 0x01000000 }, /* CSR */ - { 0xffe00000, 0x7c000000, 0x00100000 }, /* PCI I/O */ - { 0xfff00000, 0x40000000, 0x00100000 }, /* X-Bus */ -}; - -#define SIZEOFIO (sizeof(io_mapping) / sizeof(io_mapping[0])) - -/* map in IO */ -unsigned long setup_io_pagetables(unsigned long start_mem) -{ - struct mapping *mp; - int i; - - for (i = 0, mp = io_mapping; i < SIZEOFIO; i++, mp++) { - while ((mp->virtual & 1048575 || mp->physical & 1048575) && mp->length >= PAGE_SIZE) { - alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PTE_AP_WRITE); - - mp->length -= PAGE_SIZE; - mp->virtual += PAGE_SIZE; - mp->physical += PAGE_SIZE; - } - - while (mp->length >= 1048576) { -if (mp->virtual > 0xf0000000) - alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PMD_SECT_AP_WRITE); -else -alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_USER, PMD_SECT_AP_WRITE | PMD_SECT_AP_READ); - - mp->length -= 1048576; - mp->virtual += 1048576; - mp->physical += 1048576; - } - - while (mp->length >= PAGE_SIZE) { - alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PTE_AP_WRITE); - - mp->length -= PAGE_SIZE; - mp->virtual += PAGE_SIZE; - mp->physical += PAGE_SIZE; - } - } - return start_mem; -} +/* + * This is to allow us to fiddle with the EEPROM + * This entry will go away in time, once the fmu + * can mmap() the flash. + * + * These ones are so that we can fiddle + * with the various cards (eg VGA) + * until we're happy with them... + */ +#define MAPPING \ + { 0xd8000000, 0x41000000, 0x00400000, DOMAIN_USER, 1, 1 }, /* EEPROM */ \ + { 0xdc000000, 0x7c000000, 0x00100000, DOMAIN_USER, 1, 1 }, /* VGA */ \ + { 0xe0000000, 0x80000000, 0x10000000, DOMAIN_USER, 1, 1 }, /* VGA */ \ + { 0xf8000000, 0x7b000000, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 0 Config */ \ + { 0xf9000000, 0x7a000000, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 1 Config */ \ + { 0xfc000000, 0x79000000, 0x01000000, DOMAIN_IO , 0, 1 }, /* PCI IACK */ \ + { 0xfd000000, 0x78000000, 0x01000000, DOMAIN_IO , 0, 1 }, /* Outbound wflsh*/ \ + { 0xfe000000, 0x42000000, 0x01000000, DOMAIN_IO , 0, 1 }, /* CSR */ \ + { 0xffe00000, 0x7c000000, 0x00100000, DOMAIN_IO , 0, 1 }, /* PCI I/O */ \ + { 0xfff00000, 0x40000000, 0x00100000, DOMAIN_IO , 0, 1 }, /* X-Bus */ +#include "mm-armv.c" diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c index 2bb2d0fab..a7407c130 100644 --- a/arch/arm/mm/mm-nexuspci.c +++ b/arch/arm/mm/mm-nexuspci.c @@ -4,25 +4,24 @@ * * Extra MM routines for the NexusPCI architecture * + * Copyright (C) 1998 Phil Blundell * Copyright (C) 1998 Russell King */ +#include +#include +#include + +#include +#include #include +#include -/* map in IO */ -void setup_io_pagetables(void) -{ - unsigned long address = IO_START; - int spi = IO_BASE >> PGDIR_SHIFT; - - pgd_val(swapper_pg_dir[spi-1]) = 0xc0000000 | PMD_TYPE_SECT | - PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE; - - while (address < IO_START + IO_SIZE && address) { - pgd_val(swapper_pg_dir[spi++]) = address | PMD_TYPE_SECT | - PMD_DOMAIN(DOMAIN_IO) | - PMD_SECT_AP_WRITE; - address += PGDIR_SIZE; - } -} +#define MAPPING \ + { 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffe00000, 0x20000000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffc00000, 0x60000000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xfe000000, 0x80000000, 0x00100000, DOMAIN_IO, 0, 1 }, \ + { 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1 } +#include "mm-armv.c" diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index f789b8f79..573a89b90 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -5,9 +5,9 @@ * * Copyright (C) 1998 Russell King */ - #include #include +#include #include #include @@ -88,50 +88,10 @@ void init_dram_banks(struct param_struct *params) current->tss.memmap = __virt_to_phys((unsigned long)swapper_pg_dir); } -static struct mapping { - unsigned long virtual; - unsigned long physical; - unsigned long length; -} io_mapping[] = { - { SCREEN2_BASE, SCREEN_START, 2*1048576 }, /* VRAM */ - { IO_BASE, IO_START, IO_SIZE } /* IO space */ -}; - -#define SIZEOFIO (sizeof(io_mapping) / sizeof(io_mapping[0])) - -/* map in IO */ -unsigned long setup_io_pagetables(unsigned long start_mem) -{ - struct mapping *mp; - int i; - - for (i = 0, mp = io_mapping; i < SIZEOFIO; i++, mp++) { - while ((mp->virtual & 1048575 || mp->physical & 1048575) && mp->length >= PAGE_SIZE) { - alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PTE_AP_WRITE); - - mp->length -= PAGE_SIZE; - mp->virtual += PAGE_SIZE; - mp->physical += PAGE_SIZE; - } - - while (mp->length >= 1048576) { - alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PMD_SECT_AP_WRITE); - mp->length -= 1048576; - mp->virtual += 1048576; - mp->physical += 1048576; - } - - while (mp->length >= PAGE_SIZE) { - alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO, - PTE_AP_WRITE); - - mp->length -= PAGE_SIZE; - mp->virtual += PAGE_SIZE; - mp->physical += PAGE_SIZE; - } - } - - return start_mem; -} +#define MAPPING \ + { SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1 }, /* VRAM */ \ + { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1 } /* IO space */ +/* + * Include common routine to set up page tables + */ +#include "mm-armv.c" diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c new file mode 100644 index 000000000..2cc5cc9e1 --- /dev/null +++ b/arch/arm/mm/mm-tbox.c @@ -0,0 +1,56 @@ +/* + * arch/arm/mm/mm-tbox.c + * from arch/arm/mm/mm-ebsa110.c + * + * Extra MM routines for the Tbox architecture + * + * Copyright (C) 1998 Phil Blundell + * Copyright (C) 1998 Russell King + */ + +#include +#include +#include + +#include +#include +#include +#include + + +/* Logical Physical + * 0xffff1000 0x00100000 DMA registers + * 0xffff2000 0x00200000 MPEG + * 0xffff3000 0x00300000 FPGA1 local control + * 0xffff4000 0x00400000 External serial + * 0xffff5000 0x00500000 Internal serial + * 0xffff6000 0x00600000 Parallel + * 0xffff7000 0x00700000 Interrupt control + * 0xffff8000 0x00800000 Computer video + * 0xffff9000 0x00900000 Control register 0 + * 0xffffs000 0x00a00000 Control register 1 + * 0xffffb000 0x00b00000 Control register 2 + * 0xffffc000 0x00c00000 FPGA2 local control + * 0xffffd000 0x00d00000 Interrupt reset + * 0xffffe000 0x00e00000 MPEG DMA throttle + */ + +#define MAPPING \ + { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1 }, \ + { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1 } + +#include "mm-armv.c" diff --git a/arch/arm/mm/mm-vnc.c b/arch/arm/mm/mm-vnc.c new file mode 100644 index 000000000..eed49eb29 --- /dev/null +++ b/arch/arm/mm/mm-vnc.c @@ -0,0 +1,32 @@ +/* + * arch/arm/mm/mm-vnc.c + * + * Extra MM routines for the Corel VNC architecture + * + * Copyright (C) 1998 Russell King + */ +#include +#include +#include + +#include +#include +#include +#include + +/* Table describing the MMU translation mapping + * mainly used to set up the I/O mappings. + */ +#define MAPPING \ + { 0xe0000000, DC21285_PCI_IO, 0x00100000, DOMAIN_IO, 0, 1 }, /* PCI I/O */ \ + { 0xe0100000, DC21285_PCI_TYPE_0_CONFIG, 0x00f00000, DOMAIN_IO, 0, 1 }, /* Type 0 Config */ \ + { 0xe1000000, DC21285_ARMCSR_BASE, 0x00100000, DOMAIN_IO, 0, 1 }, /* ARM CSR */ \ + { 0xe1100000, DC21285_PCI_IACK, 0x00100000, DOMAIN_IO, 0, 1 }, /* PCI IACK */ \ + { 0xe1300000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh */ \ + { 0xe1400000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh */ \ + { 0xe1500000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh */ \ + { 0xe1600000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh */ \ + { 0xe1700000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh */ \ + { 0xe1800000, DC21285_FLASH, 0x00800000, DOMAIN_IO, 0, 1 } /* Flash */ + +#include "mm-armv.c" diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index 916bab104..86cab564a 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -123,7 +123,7 @@ Lconvertmemc: mov r3, r1, lsr #13 @ * address Address of fault. * pte New PTE at address * Purpose : Update the mapping for this address. - * Notes : does the ARM3 run faster if you dont use the result in the next instruction? + * Notes : does the ARM3 run faster if you do not use the result in the next instruction? */ _arm2_3_update_cache: tst r2, #PAGE_PRESENT @@ -383,13 +383,13 @@ _arm3_proc_init: mov r0, #0x001f0000 orr r0, r0, #0x0000ff00 orr r0, r0, #0x000000ff - mcr p15, 0, r0, c3, c0 - mcr p15, 0, r0, c4, c0 + mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable + mcr p15, 0, r0, c4, c0 @ ARM3 Updateable mov r0, #0 - mcr p15, 0, r0, c5, c0 + mcr p15, 0, r0, c5, c0 @ ARM3 Disruptive + mcr p15, 0, r0, c1, c0 @ ARM3 Flush mov r0, #3 - mcr p15, 0, r0, c1, c0 - mcr p15, 0, r0, c2, c0 + mcr p15, 0, r0, c2, c0 @ ARM3 Control movs pc, lr /* diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index a853671fc..f4f4dfee9 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -347,12 +347,11 @@ _arm6_7_proc_fin: * * Purpose : Set a PMD and flush it out of any WB cache */ -_arm6_set_pmd: and r2, r1, #3 - teq r2, #2 - andeq r2, r1, #8 - orreq r1, r1, r2, lsl #1 @ Updatable = Cachable +_arm6_set_pmd: and r2, r1, #11 teq r2, #1 - orreq r1, r1, #16 @ Updatable = 1 if Page table + teqne r2, #9 + teqne r2, #10 + orreq r1, r1, #16 @ Updatable = 1 if Page table/Cacheable section str r1, [r0] mov pc, lr @@ -364,7 +363,8 @@ _arm6_set_pmd: and r2, r1, #3 * * Purpose : Set a PMD and flush it out of any WB cache */ -_arm7_set_pmd: orr r1, r1, #16 @ Updatable bit is always set on ARM7 +_arm7_set_pmd: tst r1, #3 + orrne r1, r1, #16 @ Updatable bit is always set on ARM7 str r1, [r0] mov pc, lr diff --git a/arch/arm/vmlinux-armo.lds b/arch/arm/vmlinux-armo.lds new file mode 100644 index 000000000..db1f720e7 --- /dev/null +++ b/arch/arm/vmlinux-armo.lds @@ -0,0 +1,63 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version + * Written by Martin Mares + */ +OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x9090 + .text.lock : { *(.text.lock) } /* out-of-line lock text */ + .rodata : { *(.rodata) } + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; /* End of text section */ + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + _edata = .; /* End of data section */ + + /* This has to be aligned to a page boundary to do us any good. This + alignment is overkill for ARM6 up but needed for ARM3. Since all this + data will be thrown away I don't think the extra padding will hurt. + -- pb */ + . = ALIGN(32768); /* Init code and data */ + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(32768); + __init_end = .; + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + _end = . ; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/vmlinux-armv.lds b/arch/arm/vmlinux-armv.lds new file mode 100644 index 000000000..a40664c75 --- /dev/null +++ b/arch/arm/vmlinux-armv.lds @@ -0,0 +1,63 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version + * Written by Martin Mares + */ +OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x9090 + .text.lock : { *(.text.lock) } /* out-of-line lock text */ + .rodata : { *(.rodata) } + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; /* End of text section */ + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + _edata = .; /* End of data section */ + + /* This has to be aligned to a page boundary to do us any good. This + alignment is overkill for ARM6 up but needed for ARM3. Since all this + data will be thrown away I don't think the extra padding will hurt. + -- pb */ + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + _end = . ; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/vmlinux.lds b/arch/arm/vmlinux.lds deleted file mode 100644 index db1f720e7..000000000 --- a/arch/arm/vmlinux.lds +++ /dev/null @@ -1,63 +0,0 @@ -/* ld script to make ARM Linux kernel - * taken from the i386 version - * Written by Martin Mares - */ -OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - .rodata : { *(.rodata) } - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - /* This has to be aligned to a page boundary to do us any good. This - alignment is overkill for ARM6 up but needed for ARM3. Since all this - data will be thrown away I don't think the extra padding will hurt. - -- pb */ - . = ALIGN(32768); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(32768); - __init_end = .; - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - _end = . ; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} -- cgit v1.2.3