summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Makefile231
-rw-r--r--arch/arm/boot/compressed/Makefile98
-rw-r--r--arch/arm/boot/compressed/head-netwinder.S30
-rw-r--r--arch/arm/boot/compressed/head-victor.S45
-rw-r--r--arch/arm/boot/compressed/head.S301
-rw-r--r--arch/arm/boot/compressed/misc.c48
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in52
-rw-r--r--arch/arm/config.in76
-rw-r--r--arch/arm/def-configs/brutus221
-rw-r--r--arch/arm/def-configs/empeg264
-rw-r--r--arch/arm/def-configs/footbridge128
-rw-r--r--arch/arm/def-configs/victor207
-rw-r--r--arch/arm/defconfig4
-rw-r--r--arch/arm/kernel/Makefile26
-rw-r--r--arch/arm/kernel/armksyms.c14
-rw-r--r--arch/arm/kernel/bios32.c33
-rw-r--r--arch/arm/kernel/debug-armo.S86
-rw-r--r--arch/arm/kernel/debug-armv.S206
-rw-r--r--arch/arm/kernel/dec21285.c399
-rw-r--r--arch/arm/kernel/dma-dummy.c19
-rw-r--r--arch/arm/kernel/dma-footbridge.c5
-rw-r--r--arch/arm/kernel/dma-isa.c7
-rw-r--r--arch/arm/kernel/dma-rpc.c2
-rw-r--r--arch/arm/kernel/ecard.c4
-rw-r--r--arch/arm/kernel/entry-armv.S42
-rw-r--r--arch/arm/kernel/head-armo.S8
-rw-r--r--arch/arm/kernel/head-armv.S717
-rw-r--r--arch/arm/kernel/hw-footbridge.c269
-rw-r--r--arch/arm/kernel/init_task.c1
-rw-r--r--arch/arm/kernel/ioport.c8
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/leds-footbridge.c18
-rw-r--r--arch/arm/kernel/process.c64
-rw-r--r--arch/arm/kernel/ptrace.c4
-rw-r--r--arch/arm/kernel/semaphore.c1
-rw-r--r--arch/arm/kernel/setup.c363
-rw-r--r--arch/arm/kernel/signal.c3
-rw-r--r--arch/arm/kernel/sys_arm.c1
-rw-r--r--arch/arm/kernel/traps.c1
-rw-r--r--arch/arm/lib/Makefile14
-rw-r--r--arch/arm/lib/backtrace.S7
-rw-r--r--arch/arm/lib/checksum.S26
-rw-r--r--arch/arm/lib/getconsdata.c16
-rw-r--r--arch/arm/lib/loaders.S53
-rw-r--r--arch/arm/lib/memcpy.S319
-rw-r--r--arch/arm/lib/string.S441
-rw-r--r--arch/arm/lib/system.S20
-rw-r--r--arch/arm/lib/system.c22
-rw-r--r--arch/arm/lib/uaccess-armo.S2
-rw-r--r--arch/arm/lib/uaccess.S141
-rw-r--r--arch/arm/mm/Makefile10
-rw-r--r--arch/arm/mm/fault-armo.c53
-rw-r--r--arch/arm/mm/fault-armv.c106
-rw-r--r--arch/arm/mm/fault-common.c12
-rw-r--r--arch/arm/mm/init.c168
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/map.h32
-rw-r--r--arch/arm/mm/mm-armo.c170
-rw-r--r--arch/arm/mm/mm-armv.c403
-rw-r--r--arch/arm/mm/mm-ebsa110.c24
-rw-r--r--arch/arm/mm/mm-footbridge.c52
-rw-r--r--arch/arm/mm/mm-nexuspci.c28
-rw-r--r--arch/arm/mm/mm-rpc.c101
-rw-r--r--arch/arm/mm/mm-sa1100.c84
-rw-r--r--arch/arm/mm/mm-tbox.c55
-rw-r--r--arch/arm/mm/proc-arm2,3.S584
-rw-r--r--arch/arm/mm/proc-arm6,7.S149
-rw-r--r--arch/arm/mm/proc-sa110.S232
-rw-r--r--arch/arm/nwfpe/ChangeLog46
-rw-r--r--arch/arm/nwfpe/Makefile7
-rw-r--r--arch/arm/nwfpe/double_cpdo.c65
-rw-r--r--arch/arm/nwfpe/entry.S17
-rw-r--r--arch/arm/nwfpe/entry26.S2
-rw-r--r--arch/arm/nwfpe/extended_cpdo.c67
-rw-r--r--arch/arm/nwfpe/fpa11.c16
-rw-r--r--arch/arm/nwfpe/fpa11.h20
-rw-r--r--arch/arm/nwfpe/fpa11.inl2
-rw-r--r--arch/arm/nwfpe/fpa11_cpdo.c35
-rw-r--r--arch/arm/nwfpe/fpa11_cpdt.c94
-rw-r--r--arch/arm/nwfpe/fpa11_cprt.c85
-rw-r--r--arch/arm/nwfpe/fpmodule.c81
-rw-r--r--arch/arm/nwfpe/fpmodule.inl78
-rw-r--r--arch/arm/nwfpe/fpopcode.c1
-rw-r--r--arch/arm/nwfpe/single_cpdo.c60
-rw-r--r--arch/arm/vmlinux-armo.lds.in38
-rw-r--r--arch/arm/vmlinux-armv.lds.in6
86 files changed, 4917 insertions, 3144 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 11fefd85b..0895fc0ba 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -12,91 +12,101 @@
#
# Copyright (C) 1995-1999 by Russell King
-# GCC 2.7 uses different options to later compilers; sort out which we have
-CONFIG_GCC_NEW := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
+LD := $(CROSS_COMPILE)ld
+OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
+CPP := $(CC) -E
+PERL := perl
+LINKFLAGS := -X -T arch/arm/vmlinux.lds
+ARCHCC := $(word 1,$(CC))
+
+
+CFLAGS_PIPE := -pipe
+CFLAGS := $(CFLAGS) $(CFLAGS_PIPE)
+
+ifdef CONFIG_FRAME_POINTER
+CFLAGS := $(CFLAGS:-fomit-frame-pointer=)
+endif
+
+ifdef CONFIG_DEBUG_INFO
+CFLAGS += -g
+endif
-# See if this is ld "2.9.4" or later
-NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
-# CFLAGS_PROC - processor dependent CFLAGS
-# PROCESSOR - processor type
-# TEXTADDR - Uncompressed kernel link text address
-# ZTEXTADDR - Compressed kernel link text address
-# ZRELADDR - Compressed kernel relocating address
-# (point at which uncompressed kernel is loaded).
+# GCC 2.7 uses different options to later compilers; sort out which we have
+NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
#
# select flags depending on the compiler
#
-ifeq ($(CONFIG_GCC_NEW),y)
- CFLAGS_PROC := -mshort-load-bytes -msoft-float
- CFLAGS_PROC_CPU_26 := -mcpu=arm3 -Os
- CFLAGS_PROC_CPU_32v3 := -march=armv3
- CFLAGS_PROC_CPU_32v4 := -march=armv4
- CFLAGS_ARM6 := -mtune=arm6
- CFLAGS_ARM7 := -mtune=arm7
- CFLAGS_SA110 := -mtune=strongarm110
+ifeq ($(NEW_GCC),y)
+CFLAGS += -mshort-load-bytes -msoft-float
+CFLAGS_PROC_CPU_26 := -mcpu=arm3 -Os
+CFLAGS_PROC_CPU_32v3 := -march=armv3
+CFLAGS_PROC_CPU_32v4 := -march=armv4
+CFLAGS_ARM6 := -mtune=arm6
+CFLAGS_ARM7 := -mtune=arm7
+CFLAGS_SA110 := -mtune=strongarm110
else
- CFLAGS_PROC :=
- CFLAGS_PROC_CPU_26 := -m3
- CFLAGS_PROC_CPU_32v3 :=
- CFLAGS_PROC_CPU_32v4 :=
- CFLAGS_ARM6 := -m6
- CFLAGS_ARM7 := -m6
- CFLAGS_SA110 := -m6
+CFLAGS_PROC_CPU_26 := -m3
+CFLAGS_PROC_CPU_32v3 :=
+CFLAGS_PROC_CPU_32v4 :=
+CFLAGS_ARM6 := -m6
+CFLAGS_ARM7 := -m6
+CFLAGS_SA110 := -m6
endif
+# See if this is ld "2.9.4" or later
+NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
+
ifeq ($(NEW_LINKER),y)
- ASFLAGS_PROC := -mno-fpu
- ASFLAGS_PROC_CPU_26 := -mapcs-26
- ASFLAGS_PROC_CPU_32v3 := -mapcs-32 -marmv3m
- ASFLAGS_PROC_CPU_32v4 := -mapcs-32 -marmv4t
- LINKFLAGS := -p
+AFLAGS += -mno-fpu
+AFLAGS_PROC_CPU_26 := -mapcs-26
+AFLAGS_PROC_CPU_32v3 := -mapcs-32 -marmv3m
+AFLAGS_PROC_CPU_32v4 := -mapcs-32 -marmv4t
+LINKFLAGS := -p $(LINKFLAGS)
else
- ASFLAGS_PROC :=
- ASFLAGS_PROC_CPU_26 := -m3
- ASFLAGS_PROC_CPU_32v3 := -m6
- ASFLAGS_PROC_CPU_32v4 := -m6
- LINKFLAGS :=
+AFLAGS_PROC_CPU_26 := -m3
+AFLAGS_PROC_CPU_32v3 := -m6
+AFLAGS_PROC_CPU_32v4 := -m6
endif
+#
+# Select CPU dependent flags
+#
ifeq ($(CONFIG_CPU_26),y)
- PROCESSOR = armo
- TEXTADDR = 0x02080000
- ZTEXTADDR = 0x01800000
- ZRELADDR = 0x02080000
- CFLAGS_PROC += $(CFLAGS_PROC_CPU_26)
- ASFLAGS_PROC += $(ASFLAGS_PROC_CPU_26)
+ PROCESSOR = armo
+ TEXTADDR = 0x02080000
+ CFLAGS += $(CFLAGS_PROC_CPU_26)
+ AFLAGS += $(AFLAGS_PROC_CPU_26)
endif
ifeq ($(CONFIG_CPU_32),y)
- PROCESSOR = armv
- TEXTADDR = 0xC0008000
- ifeq ($(CONFIG_CPU_32v4),y)
- CFLAGS_PROC += $(CFLAGS_PROC_CPU_32v4)
- ASFLAGS_PROC += $(ASFLAGS_PROC_CPU_32v4)
- else
- CFLAGS_PROC += $(CFLAGS_PROC_CPU_32v3)
- ASFLAGS_PROC += $(ASFLAGS_PROC_CPU_32v3)
- endif
- #
- # Exactly one of the following must be selected
- #
- ifeq ($(CONFIG_CPU_ARM6),y)
- CFLAGS_PROC += $(CFLAGS_ARM6)
- else
- ifeq ($(CONFIG_CPU_ARM7),y)
- CFLAGS_PROC += $(CFLAGS_ARM7)
- else
- ifeq ($(CONFIG_CPU_SA110),y)
- CFLAGS_PROC += $(CFLAGS_SA110)
- endif
- endif
- endif
+ PROCESSOR = armv
+ TEXTADDR = 0xC0008000
+ ifeq ($(CONFIG_CPU_32v4),y)
+ CFLAGS += $(CFLAGS_PROC_CPU_32v4)
+ AFLAGS += $(AFLAGS_PROC_CPU_32v4)
+ else
+ CFLAGS += $(CFLAGS_PROC_CPU_32v3)
+ AFLAGS += $(AFLAGS_PROC_CPU_32v3)
+ endif
+ #
+ # Exactly one of the following must be selected
+ #
+ ifeq ($(CONFIG_CPU_ARM6),y)
+ CFLAGS += $(CFLAGS_ARM6)
+ else
+ ifeq ($(CONFIG_CPU_ARM7),y)
+ CFLAGS += $(CFLAGS_ARM7)
+ else
+ ifeq ($(CONFIG_CPU_SA110),y)
+ CFLAGS += $(CFLAGS_SA110)
+ endif
+ endif
+ endif
endif
-
-COMPRESSED_HEAD = head.o
+GCCLIB := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
ifeq ($(CONFIG_ARCH_A5K),y)
MACHINE = a5k
@@ -111,22 +121,16 @@ endif
ifeq ($(CONFIG_ARCH_RPC),y)
MACHINE = rpc
ARCHDIR = rpc
-ZTEXTADDR = 0x10008000
-ZRELADDR = 0x10008000
endif
ifeq ($(CONFIG_ARCH_EBSA110),y)
MACHINE = ebsa110
ARCHDIR = ebsa110
-ZTEXTADDR = 0x00008000
-ZRELADDR = 0x00008000
endif
ifeq ($(CONFIG_FOOTBRIDGE),y)
MACHINE = footbridge
ARCHDIR = ebsa285
-ZTEXTADDR = 0x00008000
-ZRELADDR = 0x00008000
endif
ifeq ($(CONFIG_ARCH_CO285),y)
@@ -136,56 +140,31 @@ endif
ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
MACHINE = nexuspci
ARCHDIR = nexuspci
-ZTEXTADDR = 0x40200000
-ZRELADDR = 0x40008000
-COMPRESSED_EXTRA = $(TOPDIR)/arch/arm/lib/ll_char_wr_scc.o
-COMPRESSED_HEAD = head-nexuspci.o
endif
-
-
-PERL = perl
-LD = $(CROSS_COMPILE)ld
-OBJCOPY = $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
-OBJDUMP = $(CROSS_COMPILE)objdump
-CPP = $(CC) -E
-ARCHCC := $(word 1,$(CC))
-GCCLIB := `$(CC) $(CFLAGS_PROC) --print-libgcc-file-name`
-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 += -X -T $(TOPDIR)/arch/arm/vmlinux-$(PROCESSOR).lds -e stext
-ZLINKFLAGS = -Ttext $(ZTEXTADDR)
-
-# If we're intending to debug the kernel, make sure it has line number
-# information. This gets stripped out when building (z)Image so it doesn't
-# add anything to the footprint of the running kernel.
-ifeq ($(CONFIG_DEBUG_INFO),y)
-CFLAGS += -g
+ifeq ($(CONFIG_ARCH_SA1100),u)
+MACHINE = sa1100
+ARCHDIR = sa1100
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
arch/arm/kernel/init_task.o
-SUBDIRS := arch/arm/special $(SUBDIRS) arch/arm/lib arch/arm/kernel \
- arch/arm/mm arch/arm/nwfpe
+SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib \
+ arch/arm/special arch/arm/nwfpe
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
LIBS := arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
DRIVERS += arch/arm/special/special.a
-ifeq ($(CONFIG_ARCH_ACORN),y)
-SUBDIRS += drivers/acorn/block drivers/acorn/char drivers/acorn/net \
- drivers/acorn/scsi
-DRIVERS += drivers/acorn/block/acorn-block.a \
- drivers/acorn/char/acorn-char.a \
- drivers/acorn/net/acorn-net.a \
- drivers/acorn/scsi/acorn-scsi.a
+ifeq ($(CONFIG_NWFPE),y)
+CORE_FILES += arch/arm/nwfpe/math-emu.o
endif
-ifeq ($(CONFIG_NWFPE),y)
-DRIVERS += arch/arm/nwfpe/math-emu.a
+ifeq ($(CONFIG_ARCH_ACORN),y)
+SUBDIRS += drivers/acorn
+DRIVERS += drivers/acorn/block/acorn-block.a
+DRIVERS += drivers/acorn/char/acorn-char.a
+DRIVERS += drivers/acorn/net/acorn-net.a
+DRIVERS += drivers/acorn/scsi/acorn-scsi.a
endif
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
@@ -203,14 +182,9 @@ archsymlinks:
$(RM) include/asm-arm/arch include/asm-arm/proc
(cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc)
-# We need to rebuild the linker script
-# each time, in case the architecture has
-# changed.
-.PHONY: arch/arm/vmlinux-$(PROCESSOR).lds
-
-vmlinux: arch/arm/vmlinux-$(PROCESSOR).lds
+vmlinux: arch/arm/vmlinux.lds
-arch/arm/vmlinux-$(PROCESSOR).lds: $(TOPDIR)/arch/arm/vmlinux-$(PROCESSOR).lds.in
+arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
arch/arm/kernel: dummy
@@ -225,15 +199,13 @@ arch/arm/lib: dummy
zImage zinstall Image install: vmlinux
@$(MAKEBOOT) $@
-# Once we've finished integrating the sources, the @$(MAKE) will disappear
archmrproper:
- rm -f include/asm-arm/arch include/asm-arm/proc
@$(MAKE) -C arch/$(ARCH)/special mrproper
- rm -f $(TOPDIR)/arch/arm/vmlinux-*.lds
+ $(RM) include/asm-arm/arch include/asm-arm/proc
archclean:
@$(MAKEBOOT) clean
- $(RM) arch/arm/lib/constants.h
+ $(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds
archdep:
@$(MAKEBOOT) dep
@@ -244,6 +216,10 @@ Img:; @$(MAKEBOOT) Image
i:; @$(MAKEBOOT) install
zi:; @$(MAKEBOOT) zinstall
+#
+# Configuration targets. Use these to select a
+# configuration for your architecture
+#
a5k_config:
$(RM) arch/arm/defconfig
cp arch/arm/def-configs/a5k arch/arm/defconfig
@@ -260,3 +236,16 @@ rpc_config:
$(RM) arch/arm/defconfig
cp arch/arm/def-configs/rpc arch/arm/defconfig
+brutus_config:
+ $(RM) arch/arm/defconfig
+ cp arch/arm/def-configs/brutus arch/arm/defconfig
+
+victor_config:
+ $(RM) arch/arm/defconfig
+ cp arch/arm/def-configs/victor arch/arm/defconfig
+
+empeg_config:
+ $(RM) arch/arm/defconfig
+ cp arch/arm/def-configs/empeg arch/arm/defconfig
+
+
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index e31e8b288..3c0478ab3 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -2,47 +2,97 @@
# linux/arch/arm/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
-#
-# With this config, max compressed image size = 640k
-# Uncompressed image size = 1.3M (text+data)
-SYSTEM =$(TOPDIR)/vmlinux
-HEAD =$(COMPRESSED_HEAD)
-OBJS =$(HEAD) misc.o $(COMPRESSED_EXTRA)
-CFLAGS =-O2 -DSTDC_HEADERS $(CFLAGS_PROC)
-ARFLAGS =rc
-FONTC =$(TOPDIR)/drivers/video/font_acorn_8x8.c
+HEAD = head.o
+OBJS = misc.o
+SYSTEM = $(TOPDIR)/vmlinux
+CFLAGS = -O2 -DSTDC_HEADERS $(CFLAGS_PROC)
+FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c
+ZLDFLAGS = -X -T vmlinux.lds
+#
+# Architecture dependencies
+#
ifeq ($(CONFIG_ARCH_ACORN),y)
-OBJS += ll_char_wr.o font.o
+OBJS += ll_char_wr.o font.o
+endif
+
+ifeq ($(CONFIG_CPU_26),y)
+ZTEXTADDR = 0x02080000
+endif
+
+ifeq ($(CONFIG_ARCH_RPC),y)
+ZTEXTADDR = 0x10008000
+endif
+
+ifeq ($(CONFIG_ARCH_EBSA110),y)
+ZTEXTADDR = 0x00008000
+endif
+
+ifeq ($(CONFIG_FOOTBRIDGE),y)
+ZTEXTADDR = 0x00008000
+endif
+
+ifeq ($(CONFIG_ARCH_NETWINDER),y)
+OBJS += head-netwinder.o
endif
-ifeq ($(NEW_LINKER),y)
-BINFMT := elf32-littlearm
+ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
+HEAD = head-nexuspci.o
+OBJS += $(TOPDIR)/arch/arm/lib/ll_char_wr_scc.o
+ZTEXTADDR = 0x40200000
+ZRELADDR = 0x40008000
+endif
+
+ifeq ($(CONFIG_ARCH_SA110),y)
+ifeq ($(CONFIG_SA1100_VICTOR),y)
+HEAD = head-victor.o
+ZTEXTADDR = 0x00002000
+ZBSSADDR = 0xc0100000
else
-BINFMT := elf32-arm
+ZTEXTADDR = 0xc0008000
+endif
+ZRELADDR = 0xc0008000
+endif
+
+#
+# If you don't define ZRELADDR above,
+# then it defaults to ZTEXTADDR
+#
+ifeq ($(ZRELADDR),)
+ZRELADDR = $(ZTEXTADDR)
endif
+SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;
+
+ifneq ($(ZBSSADDR),)
+SEDFLAGS += s/BSS_START/$(ZBSSADDR)/
+else
+SEDFLAGS += s/BSS_START/ALIGN(4)/
+endif
all: vmlinux
-vmlinux: $(OBJS) piggy.o
- $(LD) $(ZLINKFLAGS) -o vmlinux $(OBJS) piggy.o
+vmlinux: $(HEAD) $(OBJS) piggy.o vmlinux.lds
+ $(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(GCCLIB) -o vmlinux
$(HEAD): $(HEAD:.o=.S)
- $(CC) -traditional -DLOADADDR=$(ZRELADDR) -c $(HEAD:.o=.S)
+ $(CC) -traditional -c $(HEAD:.o=.S)
piggy.o: $(SYSTEM)
- tmppiggy=_tmp_$$$$piggy; \
- rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
- $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
- gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
- echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
- $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b $(BINFMT) -T $$tmppiggy.lnk; \
- rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk;
+ $(OBJCOPY) $(SYSTEM) piggy
+ gzip -9 < piggy > piggy.gz
+ $(LD) -r -o $@ -b binary piggy.gz
+ rm -f piggy piggy.gz
font.o: $(FONTC)
$(CC) -Dstatic= -c -o $@ $(FONTC)
-clean:; rm -f vmlinux core
+vmlinux.lds: vmlinux.lds.in
+ @sed "$(SEDFLAGS)" < vmlinux.lds.in > $@
+
+clean:; rm -f vmlinux core piggy*
+
+.PHONY: vmlinux.lds clean
+misc.o: misc.c $(TOPDIR)/include/asm/arch/uncompress.h $(TOPDIR)/lib/inflate.c
diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S
new file mode 100644
index 000000000..1dcdfcd14
--- /dev/null
+++ b/arch/arm/boot/compressed/head-netwinder.S
@@ -0,0 +1,30 @@
+ .section ".start", #alloc, #execinstr
+
+ adr r2, 1f
+ ldmdb r2, {r7, r8}
+ and r3, r2, #0xc000
+ teq r3, #0x8000
+ beq 2f
+ bic r3, r2, #0xc000
+ orr r3, r3, #0x8000
+ mov r0, r3
+ mov r4, #64
+ sub r5, r8, r7
+ b 1f
+
+ .word _start
+ .word __bss_start
+
+1:
+ .rept 4
+ ldmia r2!, {r6, r7, r8, r9}
+ stmia r3!, {r6, r7, r8, r9}
+ .endr
+ subs r4, r4, #64
+ bcs 1b
+ movs r4, r5
+ mov r5, #0
+ movne pc, r0
+
+ mov r0, #0
+2:
diff --git a/arch/arm/boot/compressed/head-victor.S b/arch/arm/boot/compressed/head-victor.S
new file mode 100644
index 000000000..e556383ba
--- /dev/null
+++ b/arch/arm/boot/compressed/head-victor.S
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/boot/compressed/head-victor.S
+ *
+ * Copyright (C) 1998 Nicolas Pitre <nico@visuaide.com>
+ */
+
+#include <linux/linkage.h>
+
+ .text
+ .globl _start
+_start:
+ @ just in case we still use an a.out loader...
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ @ load different addresses
+ adr r2, LC0
+ ldmia r2, {r4, r5, r6, sp}
+
+ @ clear BSS
+ mov r2, #0
+1: str r2, [r5], #4
+ cmp r5, r6
+ blt 1b
+
+ @ uncompress the kernel
+ mov r8, r0 @ save cmdline ptr
+ mov r0, r4 @ where to put uncompressed data
+ add r1, r6, #31
+ bic r1, r1, #31 @ free memory space
+ add r2, r1, #65536 @ end of free mem space
+ bl SYMBOL_NAME(decompress_kernel)
+ mov r0, r8 @ retrieve cmdline ptr
+ mov pc, r4 @ call via EXEC entry
+
+LC0: .word _load_addr
+ .word __bss_start
+ .word SYMBOL_NAME(_end)
+ .word SYMBOL_NAME(user_stack)+4096
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index ab2541f34..721967e4b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -1,129 +1,232 @@
/*
* linux/arch/arm/boot/compressed/head.S
*
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
*/
#include <linux/linkage.h>
- .text
+ .section ".start", #alloc, #execinstr
/*
* sort out different calling conventions
*/
.align
- .globl _start
-_start:
-start: mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
+start:
+ .type start,#function
+ .rept 8
mov r0, r0
+ .endr
+
b 1f
- .word 0x016f2818 @ Magic numbers to help the loader
- .word _start
+ .word 0x016f2818 @ Magic numbers to help the loader
+ .word start
+1:
+
+ /*
+ * some architecture specific code can
+ * be inserted by the linker here
+ */
+
+ .text
1: teq r0, #0
- beq 2f
- mov r4, #0x02000000
- add r4, r4, #0x7C000
- mov r3, #0x4000
- sub r3, r3, #4
-1: ldmia r0!, {r5 - r12}
- stmia r4!, {r5 - r12}
- subs r3, r3, #32
- bpl 1b
-2: adr r2, LC0
- ldmia r2, {r2, r3, r4, r5, r6, sp}
- add r2, r2, #3
- add r3, r3, #3
- add sp, sp, #3
- bic r2, r2, #3
- bic r3, r3, #3
- bic sp, sp, #3
- adr r7, start
- sub r6, r7, r6
-/*
- * Relocate pointers
- */
- add r2, r2, r6
- add r3, r3, r6
- add r5, r5, r6
- add sp, sp, r6
-/*
- * Clear zero-init
- */
- mov r6, #0
-1: str r6, [r2], #4
+ bne 1b
+ mov r7, r1 @ save architecture ID
+ mrc p15, 0, r6, c0, c0 @ get processor ID
+ adr r2, LC0
+ ldmia r2, {r2, r3, r4, r5, sp}
+
+ mov r0, #0
+1: str r0, [r2], #4 @ clear bss
+ str r0, [r2], #4
+ str r0, [r2], #4
+ str r0, [r2], #4
cmp r2, r3
blt 1b
- str r1, [r5] @ save architecture
-/*
- * Uncompress the kernel
- */
- mov r1, #0x8000
- add r3, r2, r1, lsl #1 @ Add 64k for malloc
- sub r1, r1, #1
- add r3, r3, r1
- bic r5, r3, r1 @ decompress kernel to after end of the compressed
+
+ mov r1, sp @ malloc space above stack
+ add r2, sp, #0x10000 @ 64k max
+
+ teq r4, r5 @ will we overwrite ourselves?
+ moveq r5, r2
+ movne r5, r4
+
mov r0, r5
- mov r1, r2
- mov r2, r0
+ mov r3, r7
bl SYMBOL_NAME(decompress_kernel)
- add r0, r0, #7
- bic r2, r0, #7
+
+ teq r4, r5 @ do we need to relocate
+ beq call_kernel @ the kernel?
+
+ add r0, r0, #127
+ bic r0, r0, #127 @ align the kernel length
/*
- * Now move the kernel to the correct location (r5 -> r4, len r0)
+ * r0 = decompressed kernel length
+ * r1-r3 = unused
+ * r4 = kernel execution address
+ * r5 = decompressed kernel start
+ * r6 = processor ID
+ * r7 = architecture ID
+ * r8-r14 = unused
*/
- mov r0, r4 @ r0 = start of real kernel
- mov r1, r5 @ r1 = start of kernel image
- add r3, r5, r2 @ r3 = end of kernel
- adr r4, movecode
- adr r5, movecodeend
-1: ldmia r4!, {r6 - r12, lr}
- stmia r3!, {r6 - r12, lr}
- cmp r4, r5
+ add r1, r5, r0 @ end of decompressed kernel
+ adr r2, reloc_start
+ adr r3, reloc_end
+1: ldmia r2!, {r8 - r13} @ copy relocation code
+ stmia r1!, {r8 - r13}
+ ldmia r2!, {r8 - r13}
+ stmia r1!, {r8 - r13}
+ cmp r2, r3
blt 1b
- mrc p15, 0, r5, c0, c0
- eor r5, r5, #0x44 << 24
- eor r5, r5, #0x01 << 16
- eor r5, r5, #0xa1 << 8
- movs r5, r5, lsr #4
- mov r5, #0
- mcreq p15, 0, r5, c7, c5, 0 @ flush I cache
- ldr r5, LC0 + 12 @ get architecture
- ldr r5, [r5]
- add pc, r1, r2 @ Call move code
+
+ eor r1, r6, #0x44 << 24 @ SA-110?
+ eor r1, r1, #0x01 << 16
+ eor r1, r1, #0xa1 << 8
+ movs r1, r1, lsr #4
+ mcreq p15, 0, r1, c7, c7, 0 @ flush I & D-cache
+ mcreq p15, 0, r1, c7, c10, 4 @ drain WB
+ add pc, r5, r0 @ call relocation code
/*
- * r0 = length, r1 = to, r2 = from
+ * r0 = decompressed kernel length
+ * r1-r3 = unused
+ * r4 = kernel execution address
+ * r5 = decompressed kernel start
+ * r6 = processor ID
+ * r7 = architecture ID
+ * r8-r14 = unused
*/
-movecode: add r3, r1, r2
- mov r4, r0
-1: ldmia r1!, {r6 - r12, lr}
- stmia r0!, {r6 - r12, lr}
- cmp r1, r3
+reloc_start: add r8, r5, r0
+#if 0
+ mov r0, r6
+ mov r1, #8
+ bl phex
+ mov r0, #':'
+ bl putc
+ mov r0, r5
+ mov r1, #8
+ bl phex
+ mov r0, #'-'
+ bl putc
+ mov r0, r8
+ mov r1, #8
+ bl phex
+ mov r0, #'>'
+ bl putc
+ mov r0, r4
+ mov r1, #8
+ bl phex
+ mov r0, #'\n'
+ bl putc
+#endif
+ mov r0, r8
+ mov r1, r4
+1:
+ .rept 4
+ ldmia r5!, {r2, r3, r8 - r13} @ relocate kernel
+ stmia r1!, {r2, r3, r8 - r13}
+ .endr
+
+ cmp r5, r0
blt 1b
- mrc p15, 0, r0, c0, c0
- eor r0, r0, #0x44 << 24
+#if 0
+ mov r8, r0
+ mov r0, r5
+ mov r1, #8
+ bl phex
+ mov r0, #'-'
+ bl putc
+ mov r0, r8
+ mov r1, #8
+ bl phex
+ mov r0, #'\n'
+ bl putc
+ mov r0, r4
+ bl memdump
+#endif
+ eor r0, r6, #0x44 << 24 @ SA-110?
eor r0, r0, #0x01 << 16
eor r0, r0, #0xa1 << 8
movs r0, r0, lsr #4
+ mcreq p15, 0, r0, c7, c7, 0 @ flush I cache
+ mcreq p15, 0, r1, c7, c10, 4 @ drain WB
+
+call_kernel: mov r0, #0
+ mov r1, r7 @ restore architecture number
+ mov pc, r4 @ call kernel
+
+phexbuf: .space 12
+
+phex: adr r3, phexbuf
+ mov r2, #0
+ strb r2, [r3, r1]
+1: subs r1, r1, #1
+ movmi r0, r3
+ bmi puts
+ and r2, r0, #15
+ mov r0, r0, lsr #4
+ cmp r2, #10
+ addge r2, r2, #7
+ add r2, r2, #'0'
+ strb r2, [r3, r1]
+ b 1b
+
+puts: mov r3, #0x7c000000
+1: ldrb r2, [r0], #1
+ teq r2, #0
+ moveq pc, lr
+2: strb r2, [r3, #0x3f8]
+ mov r1, #0x00020000
+3: subs r1, r1, #1
+ bne 3b
+ teq r2, #'\n'
+ moveq r2, #'\r'
+ beq 2b
+ teq r0, #0
+ bne 1b
+ mov pc, lr
+putc:
+ mov r2, r0
mov r0, #0
- mcreq p15, 0, r0, c7, c5, 0 @ flush I cache
- mov r1, r5 @ call kernel correctly
- mov pc, r4 @ call via EXEC entry
-movecodeend:
-
-LC0: .word SYMBOL_NAME(_edata)
- .word SYMBOL_NAME(_end)
- .word LOADADDR
- .word SYMBOL_NAME(architecture)
- .word start
- .word SYMBOL_NAME(user_stack)+4096
- .align
+ mov r3, #0x7c000000
+ b 2b
- .bss
-SYMBOL_NAME(architecture):
- .space 4
+memdump: mov r12, r0
+ mov r10, lr
+ mov r1, #8
+ bl phex
+ mov r0, #'\n'
+ bl putc
+ mov r11, #0
+2: mov r0, r11, lsl #2
+ mov r1, #4
+ bl phex
+ mov r0, #':'
+ bl putc
+1: mov r0, #' '
+ bl putc
+ ldr r0, [r12, r11, lsl #2]
+ mov r1, #8
+ bl phex
+ and r0, r11, #7
+ teq r0, #3
+ moveq r0, #' '
+ bleq putc
+ and r0, r11, #7
+ add r11, r11, #1
+ teq r0, #7
+ bne 1b
+ mov r0, #'\n'
+ bl putc
+ cmp r11, #64
+ blt 2b
+ mov pc, r10
+reloc_end:
+
+LC0: .word __bss_start
+ .word _end
+ .word _load_addr
+ .word _start
+ .word user_stack+4096
.align
+
+ .section ".stack"
+user_stack: .space 4096
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 1d8517104..66b4f2d0e 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -7,8 +7,17 @@
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
+ * For this code to run directly from Flash, all constant variables must
+ * be marked with 'const' and all other variables initialized at run-time
+ * only. This way all non constant variables will end up in the bss segment,
+ * which should point to addresses in RAM and cleared to 0 on start.
+ * This allows for a much quicker boot time.
*/
+unsigned int __machine_arch_type;
+
#include <asm/uaccess.h>
#include <asm/arch/uncompress.h>
#include <asm/proc/uncompress.h>
@@ -22,7 +31,7 @@
/*
* Optimised C version of memzero for the ARM.
*/
-extern __inline__ __ptr_t __memzero (__ptr_t s, size_t n)
+void __memzero (__ptr_t s, size_t n)
{
union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
int i;
@@ -62,11 +71,8 @@ extern __inline__ __ptr_t __memzero (__ptr_t s, size_t n)
if (n & 1)
*u.ucp++ = 0;
- return s;
}
-#define memzero(s,n) __memzero(s,n)
-
extern __inline__ __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
size_t __n)
{
@@ -157,11 +163,11 @@ static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[];
-extern int input_len;
+extern char input_data_end[];
static uch *output_data;
static ulg output_ptr;
-static ulg bytes_out = 0;
+static ulg bytes_out;
static void *malloc(int size);
static void free(void *where);
@@ -226,13 +232,14 @@ static void gzip_release(void **ptr)
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
-int fill_inbuf()
+int fill_inbuf(void)
{
if (insize != 0)
error("ran out of input data\n");
inbuf = input_data;
- insize = input_len;
+ insize = &input_data_end[0] - &input_data[0];
+
inptr = 1;
return inbuf[0];
}
@@ -241,7 +248,7 @@ int fill_inbuf()
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
-void flush_window()
+void flush_window(void)
{
ulg c = crc;
unsigned n;
@@ -257,6 +264,7 @@ void flush_window()
bytes_out += (ulg)outcnt;
output_ptr += (ulg)outcnt;
outcnt = 0;
+ puts(".");
}
static void error(char *x)
@@ -270,26 +278,24 @@ static void error(char *x)
while(1); /* Halt */
}
-#define STACK_SIZE (4096)
-
-ulg user_stack [STACK_SIZE];
-
#ifndef STANDALONE_DEBUG
-ulg decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p)
+ulg
+decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
+ int arch_id)
{
- free_mem_ptr = free_mem_ptr_p;
- free_mem_ptr_end = free_mem_ptr_end_p;
-
- proc_decomp_setup ();
- arch_decomp_setup ();
+ output_data = (uch *)output_start; /* Points to kernel start */
+ free_mem_ptr = free_mem_ptr_p;
+ free_mem_ptr_end = free_mem_ptr_end_p;
+ __machine_arch_type = arch_id;
- output_data = (uch *)output_start; /* Points to kernel start */
+ proc_decomp_setup();
+ arch_decomp_setup();
makecrc();
puts("Uncompressing Linux...");
gunzip();
- puts("done.\nNow booting the kernel\n");
+ puts(" done, booting the kernel.\n");
return output_ptr;
}
#else
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
new file mode 100644
index 000000000..f7469c634
--- /dev/null
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -0,0 +1,52 @@
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = LOAD_ADDR;
+ _load_addr = .;
+
+ . = TEXT_START;
+ _text = .;
+
+ .text : {
+ _start = .;
+ head.o(.start)
+ *(.start)
+ head.o(.text)
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ input_data = .;
+ piggy.o
+ input_data_end = .;
+ . = ALIGN(4);
+ }
+
+ _etext = .;
+
+ .data : {
+ *(.data)
+ }
+
+ _edata = .;
+
+ . = BSS_START;
+ __bss_start = .;
+ .bss : {
+ *(.bss)
+ }
+ _end = .;
+
+ .stack : {
+ *(.stack)
+ }
+
+ .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/config.in b/arch/arm/config.in
index 52f69bcd8..4271d12a6 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -20,7 +20,7 @@ choice 'ARM system type' \
RiscPC CONFIG_ARCH_RPC \
EBSA-110 CONFIG_ARCH_EBSA110 \
FootBridge-based CONFIG_FOOTBRIDGE" RiscPC
-
+# SA1100-based CONFIG_ARCH_SA1100
if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
bool 'FootBridge in HOST mode' CONFIG_HOST_FOOTBRIDGE
if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
@@ -31,9 +31,9 @@ if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
fi
if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
- bool ' Include support for Intel EBSA285' CONFIG_ARCH_EBSA285
- bool ' Include support for Chalice CATS boards' CONFIG_CATS
- bool ' Include support for Corel NetWinder' CONFIG_ARCH_NETWINDER
+ bool ' Include support for EBSA285' CONFIG_ARCH_EBSA285
+ bool ' Include support for CATS' CONFIG_CATS
+ bool ' Include support for NetWinder' CONFIG_ARCH_NETWINDER
fi
if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then
@@ -42,6 +42,18 @@ if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then
define_bool CONFIG_ARCH_CO285 y
fi
+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+ define_bool CONFIG_CPU_SA1100 y
+ choice 'SA1100 implementation' \
+ "Brutus CONFIG_SA1100_BRUTUS \
+ empeg CONFIG_SA1100_EMPEG \
+ Itsy CONFIG_SA1100_ITSY \
+ LART CONFIG_SA1100_LART \
+ PLEB CONFIG_SA1100_PLEB \
+ Victor CONFIG_SA1100_VICTOR \
+ Tifon CONFIG_SA1100_TIFON" Brutus
+fi
+
#
# Select various configuration options depending on the machine type
# Easy check for Acorn-style architectures
@@ -76,6 +88,7 @@ else
# Select CPU and optimisation dependent on architecture
#
if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
+ "$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_FOOTBRIDGE" = "y" -o \
"$CONFIG_ARCH_NEXUSPCI" = "y" ]; then
define_bool CONFIG_CPU_32v4 y
@@ -139,21 +152,10 @@ if [ "$CONFIG_CPU_32" = "y" ]; then
tristate 'RISC OS personality' CONFIG_ARTHUR
fi
-tristate 'Parallel port support' CONFIG_PARPORT
-if [ "$CONFIG_PARPORT" != "n" ]; then
- if [ "$CONFIG_ARCH_ARC" = "y" ]; then
- dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
- fi
- dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $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
+source drivers/parport/Config.in
+
if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
+ "$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_CATS" = "y" ]; then
string 'Initial kernel command string' CONFIG_CMDLINE
@@ -165,10 +167,10 @@ if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
bool 'Timer and CPU usage LEDs' CONFIG_LEDS
if [ "$CONFIG_LEDS" = "y" ]; then
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
- "$CONFIG_ARCH_EBSA285" = "y" -o \
+ "$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" ]; then
- bool ' Timer LED' CONFIG_LEDS_TIMER
- bool ' CPU usage LED' CONFIG_LEDS_CPU
+ bool ' Timer LED' CONFIG_LEDS_TIMER
+ bool ' CPU usage LED' CONFIG_LEDS_CPU
fi
fi
fi
@@ -186,11 +188,11 @@ fi
source drivers/char/Config.in
if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
- if [ "$CONFIG_MOUSE" = "y" ]; then
+ if [ "$CONFIG_BUSMOUSE" = "y" ]; then
if [ "$CONFIG_ARCH_RPC" != "y" ]; then
- define_bool CONFIG_KBDMOUSE y
+ define_bool CONFIG_KBDMOUSE y
else
- define_bool CONFIG_RPCMOUSE y
+ define_bool CONFIG_RPCMOUSE y
fi
fi
fi
@@ -230,7 +232,7 @@ fi
#
# tristate 'ISDN support' CONFIG_ISDN
# if [ "$CONFIG_ISDN" != "n" ]; then
-# source drivers/isdn/Config.in
+# source drivers/isdn/Config.in
# fi
# endmenu
@@ -267,17 +269,17 @@ bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_CPU_26" = "y" ]; then
- bool 'Disable pgtable cache (EXPERIMENTAL)' CONFIG_NO_PGT_CACHE
- fi
-
- # These options are only for real kernel hackers
- # who want to get their hands dirty.
- bool 'Kernel low-level debugging functions' CONFIG_DEBUG_LL
- if [ "$CONFIG_DEBUG_LL" = "y" ]; then
- if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
- bool 'Kernel low-level debugging messages via DC21285 port' CONFIG_DEBUG_DC21285_PORT
- fi
- fi
+ if [ "$CONFIG_CPU_26" = "y" ]; then
+ bool 'Disable pgtable cache (EXPERIMENTAL)' CONFIG_NO_PGT_CACHE
+ fi
+
+ # These options are only for real kernel hackers
+ # who want to get their hands dirty.
+ bool 'Kernel low-level debugging functions' CONFIG_DEBUG_LL
+ if [ "$CONFIG_DEBUG_LL" = "y" ]; then
+ if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
+ bool 'Kernel low-level debugging messages via DC21285 port' CONFIG_DEBUG_DC21285_PORT
+ fi
+ fi
fi
endmenu
diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus
new file mode 100644
index 000000000..a700f7d17
--- /dev/null
+++ b/arch/arm/def-configs/brutus
@@ -0,0 +1,221 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+
+#
+# System and processor type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_FOOTBRIDGE is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_CPU_SA1100=y
+CONFIG_SA1100_BRUTUS=y
+# CONFIG_SA1100_EMPEG is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_TIFON is not set
+# CONFIG_ARCH_ACORN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v4=y
+CONFIG_CPU_SA110=y
+# CONFIG_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# General setup
+#
+# CONFIG_NET is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE=""
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL_SA1100=y
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_SA1100=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/empeg b/arch/arm/def-configs/empeg
new file mode 100644
index 000000000..cd3792b53
--- /dev/null
+++ b/arch/arm/def-configs/empeg
@@ -0,0 +1,264 @@
+#
+# Example empeg-car kernel configuration file.
+#
+CONFIG_ARM=y
+
+#
+# System and processor type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_FOOTBRIDGE is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_CPU_SA1100=y
+# CONFIG_SA1100_BRUTUS is not set
+CONFIG_SA1100_EMPEG=y
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_EMPEG_HENRY is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM2 is not set
+# CONFIG_CPU_ARM3 is not set
+# CONFIG_CPU_ARM6 is not set
+# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_SA110=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_TEXT_SECTIONS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+# CONFIG_KMOD is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE=""
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EMPEG_IR=y
+CONFIG_EMPEG_USB=y
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_DEV=y
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_EMPEG=y
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_FILTER is not set
+# CONFIG_UNIX is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_RARP is not set
+# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA subsystem support
+#
+# CONFIG_IRDA is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_DLCI is not set
+CONFIG_PPP=y
+# CONFIG_SLIP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+# CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
+# CONFIG_RCPCI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_USER_BACKTRACE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/footbridge b/arch/arm/def-configs/footbridge
index ce85d6ffc..a3acd8954 100644
--- a/arch/arm/def-configs/footbridge
+++ b/arch/arm/def-configs/footbridge
@@ -17,22 +17,18 @@ CONFIG_ARCH_EBSA285=y
# CONFIG_CATS is not set
CONFIG_ARCH_NETWINDER=y
# CONFIG_ARCH_ACORN is not set
-CONFIG_PCI=y
-CONFIG_ISA_DMA=y
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM2 is not set
-# CONFIG_CPU_ARM3 is not set
-# CONFIG_CPU_ARM6 is not set
-# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_32v4=y
CONFIG_CPU_SA110=y
+CONFIG_PCI=y
+CONFIG_ISA_DMA=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
# CONFIG_ALIGNMENT_TRAP is not set
-# CONFIG_TEXT_SECTIONS is not set
#
# Loadable module support
@@ -55,15 +51,35 @@ CONFIG_BINFMT_ELF=y
# CONFIG_ARTHUR is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
CONFIG_CMDLINE="root=/dev/hda2 ro mem=32M parport=0x378,7 ide0=autotune"
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
#
-# Plug and Play support
+# I2O device support
#
-# CONFIG_PNP is not set
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Plug and Play configuration
+#
+CONFIG_PNP=y
+CONFIG_ISAPNP=y
#
# Block devices
@@ -76,6 +92,7 @@ CONFIG_BLK_DEV_IDE=y
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -89,7 +106,7 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82C586 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_SL82C105=y
# CONFIG_IDE_CHIPSETS is not set
@@ -136,6 +153,7 @@ CONFIG_PARIDE_KBIC=m
CONFIG_PARIDE_KTTI=m
CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_IDE_MODES=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -149,15 +167,14 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
-CONFIG_MOUSE=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
#
# Mice
#
-# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
@@ -172,6 +189,8 @@ CONFIG_WATCHDOG=y
CONFIG_SOFT_WATCHDOG=y
# CONFIG_PCWATCHDOG is not set
# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+CONFIG_977_WATCHDOG=m
CONFIG_DS1620=y
CONFIG_NWBUTTON=y
CONFIG_NWBUTTON_REBOOT=y
@@ -189,6 +208,8 @@ CONFIG_RTC=y
#
# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
@@ -196,11 +217,35 @@ CONFIG_RTC=y
# CONFIG_FTAPE is not set
#
+# USB drivers - not for the faint of heart
+#
+CONFIG_USB=m
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=m
+CONFIG_USB_OHCI_DEBUG=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_VROOTHUB=y
+# CONFIG_USB_DEBUG_ISOC is not set
+CONFIG_USB_HUB=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_KBD=m
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+# CONFIG_USB_CPIA is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_USS720 is not set
+CONFIG_USB_PROC=y
+
+#
# Console drivers
#
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_CYBER2000=y
# CONFIG_FB_MATROX is not set
@@ -220,6 +265,7 @@ CONFIG_FBCON_CFB24=y
# CONFIG_FBCON_IPLAN2P4 is not set
# CONFIG_FBCON_IPLAN2P8 is not set
# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
CONFIG_FBCON_VGA=y
# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
CONFIG_FBCON_FONTS=y
@@ -235,8 +281,9 @@ CONFIG_FONT_ACORN_8x8=y
# Networking options
#
CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -254,15 +301,17 @@ CONFIG_IP_ALIAS=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
@@ -271,7 +320,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
#
# QoS and/or fair queueing
@@ -284,7 +332,7 @@ CONFIG_SKB_LARGE=y
# CONFIG_HAMRADIO is not set
#
-# IrDA subsystem support
+# IrDA (infrared) support
#
# CONFIG_IRDA is not set
@@ -292,9 +340,18 @@ CONFIG_SKB_LARGE=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
# CONFIG_ARM_AM79C961A is not set
CONFIG_NET_VENDOR_3COM=y
@@ -309,11 +366,12 @@ CONFIG_VORTEX=y
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_RTL8139 is not set
+# CONFIG_SIS900 is not set
# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
+# CONFIG_ACENIC is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
@@ -332,23 +390,32 @@ CONFIG_NE2K_PCI=y
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
-
-#
-# CCP compressors for PPP are only built as modules.
-#
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
# CONFIG_NET_RADIO is not set
+
+#
+# Token ring devices
+#
# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
# CONFIG_HOSTESS_SV11 is not set
# CONFIG_COSA is not set
-# CONFIG_RCPCI is not set
+# CONFIG_SEALEVEL_4021 is not set
+# CONFIG_DLCI is not set
#
# SCSI support
@@ -359,8 +426,10 @@ CONFIG_SLIP_MODE_SLIP6=y
# Sound
#
CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
# CONFIG_SOUND_SONICVIBES is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
@@ -410,6 +479,7 @@ CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
# CONFIG_UMSDOS_FS is not set
CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_MINIX_FS is not set
@@ -438,12 +508,17 @@ CONFIG_LOCKD=y
#
# Partition Types
#
+CONFIG_PARTITION_ADVANCED=y
# CONFIG_OSF_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_ADFS=y
# CONFIG_ACORN_PARTITION_ICS is not set
@@ -479,6 +554,7 @@ CONFIG_NLS_ISO8859_2=m
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=m
# CONFIG_NLS_KOI8_R is not set
@@ -487,7 +563,7 @@ CONFIG_NLS_ISO8859_15=m
#
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_INFO is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/victor b/arch/arm/def-configs/victor
new file mode 100644
index 000000000..569cc458d
--- /dev/null
+++ b/arch/arm/def-configs/victor
@@ -0,0 +1,207 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+
+#
+# System and processor type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_FOOTBRIDGE is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_CPU_SA1100=y
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_EMPEG is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_PLEB is not set
+CONFIG_SA1100_VICTOR=y
+# CONFIG_VICTOR_BOARD1 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM2 is not set
+# CONFIG_CPU_ARM3 is not set
+# CONFIG_CPU_ARM6 is not set
+# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_SA110=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_TEXT_SECTIONS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# General setup
+#
+# CONFIG_NET is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_NWFPE=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE=""
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index 4f1ec7e28..d289870ea 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -55,7 +55,7 @@ CONFIG_BINFMT_ELF=y
# CONFIG_ARTHUR is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
-CONFIG_CMDLINE="root=/dev/hda2 ro mem=32M parport=0x378,7 ide0=autotune"
+CONFIG_CMDLINE="root=/dev/hda1 ro mem=32M parport=0x378,7 ide0=autotune"
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
@@ -89,7 +89,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82C586 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_SL82C105=y
# CONFIG_IDE_CHIPSETS is not set
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 557aa6fc5..31ca81ddc 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -22,6 +22,7 @@ O_OBJS_rpc = dma-rpc.o iic.o fiq.o
O_OBJS_ebsa110 = dma-dummy.o
O_OBJS_footbridge = dma-footbridge.o $(ISA_DMA_OBJS) isa.o
O_OBJS_nexuspci = dma-dummy.o
+O_OBJS_sa1100 = dma-dummy.o fiq.o
OX_OBJS_arc = dma.o
OX_OBJS_a5k = dma.o
@@ -29,11 +30,16 @@ OX_OBJS_rpc = dma.o
OX_OBJS_ebsa110 =
OX_OBJS_footbridge= dma.o hw-footbridge.o
OX_OBJS_nexuspci =
+OX_OBJS_sa1100 =
all: kernel.o $(HEAD_OBJ) init_task.o
O_OBJS += $(O_OBJS_$(MACHINE))
+ifeq ($(CONFIG_DEBUG_LL),y)
+ O_OBJS += debug-$(PROCESSOR).o
+endif
+
ifeq ($(CONFIG_MODULES),y)
OX_OBJS = armksyms.o
endif
@@ -42,17 +48,15 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
OX_OBJS += ecard.o
endif
-ifeq ($(MACHINE),nexuspci)
- ifdef CONFIG_PCI
+ifeq ($(CONFIG_PCI),y)
+ ifeq ($(MACHINE),nexuspci)
O_OBJS += plx9080.o
- endif
-else
- ifdef CONFIG_PCI
+ else
O_OBJS += bios32.o dec21285.o
endif
endif
-ifdef CONFIG_LEDS
+ifeq ($(CONFIG_LEDS),y)
OX_OBJS += leds-$(MACHINE).o
endif
@@ -73,13 +77,11 @@ endif
$(HEAD_OBJ): $(HEAD_OBJ:.o=.S)
$(CC) -D__ASSEMBLY__ -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@
-$(ENTRY_OBJ): $(ENTRY_OBJ:.o=.S)
- $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $(ENTRY_OBJ:.o=.S) -o $@
-
include $(TOPDIR)/Rules.make
-$(ENTRY_OBJ): ../lib/constants.h
+.S.o:
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_$@) -c -o $*.o $<
# Spell out some dependencies that `make dep' doesn't spot
-entry-armv.o: calls.S
-entry-armo.o: calls.S
+entry-armv.o: calls.S ../lib/constants.h
+entry-armo.o: calls.S ../lib/constants.h
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 0905d55b5..ebb2f150d 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -2,12 +2,14 @@
#include <linux/module.h>
#include <linux/user.h>
#include <linux/string.h>
+#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/in6.h>
+#include <asm/byteorder.h>
#include <asm/elf.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -93,6 +95,9 @@ EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(__iounmap);
#endif
EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(system_rev);
+EXPORT_SYMBOL(system_serial_low);
+EXPORT_SYMBOL(system_serial_high);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
@@ -108,7 +113,7 @@ EXPORT_SYMBOL(cpu_clean_cache_area);
EXPORT_SYMBOL(cpu_flush_ram_page);
EXPORT_SYMBOL(cpu_flush_tlb_all);
EXPORT_SYMBOL(cpu_flush_tlb_area);
-EXPORT_SYMBOL(cpu_switch_mm);
+EXPORT_SYMBOL(cpu_set_pgd);
EXPORT_SYMBOL(cpu_set_pmd);
EXPORT_SYMBOL(cpu_set_pte);
EXPORT_SYMBOL(cpu_flush_icache_area);
@@ -165,19 +170,20 @@ EXPORT_SYMBOL_NOVERS(strpbrk);
EXPORT_SYMBOL_NOVERS(strtok);
EXPORT_SYMBOL_NOVERS(strrchr);
EXPORT_SYMBOL_NOVERS(strstr);
-EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(__memset);
+EXPORT_SYMBOL_NOVERS(memset); /* needed for some versions of gcc */
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memmove);
EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memscan);
-EXPORT_SYMBOL_NOVERS(memzero);
+EXPORT_SYMBOL_NOVERS(__memzero);
/* user mem (segment) */
#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);
+EXPORT_SYMBOL(__arch_strnlen_user);
#elif defined(CONFIG_CPU_26)
EXPORT_SYMBOL(uaccess_kernel);
EXPORT_SYMBOL(uaccess_user);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 35bb0a36a..3bd7a7358 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/errno.h>
#include <linux/init.h>
#include <asm/irq.h>
@@ -73,6 +74,38 @@ struct pci_fixup pcibios_fixups[] = {
};
/*
+ * Assign new address to PCI resource. We hope our resource information
+ * is complete. On the PC, we don't re-assign resources unless we are
+ * forced to do so.
+ *
+ * Expects start=0, end=size-1, flags=resource type.
+ */
+
+int __init pcibios_assign_resource(struct pci_dev *dev, int i)
+{
+ struct resource *r = &dev->resource[i];
+ struct resource *pr = pci_find_parent_resource(dev, r);
+ unsigned long size = r->end + 1;
+ unsigned long flags = 0;
+
+ if (!pr)
+ return -EINVAL;
+ if (r->flags & IORESOURCE_IO) {
+ if (size > 0x100)
+ return -EFBIG;
+ if (allocate_resource(pr, r, size, 0x9000, ~0, 1024))
+ return -EBUSY;
+ flags = PCI_BASE_ADDRESS_SPACE_IO;
+ } else {
+ if (allocate_resource(pr, r, size, 0x00100000, 0x7fffffff, size))
+ return -EBUSY;
+ }
+ if (i < 6)
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4*i, r->start | flags);
+ return 0;
+}
+
+/*
* Assign an address to an I/O range.
*/
static void __init pcibios_fixup_io_addr(struct pci_dev *dev, struct resource *r, int idx)
diff --git a/arch/arm/kernel/debug-armo.S b/arch/arm/kernel/debug-armo.S
new file mode 100644
index 000000000..1c6aaccc3
--- /dev/null
+++ b/arch/arm/kernel/debug-armo.S
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/kernel/debug-armo.S
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * 26-bit debugging code
+ */
+#include <linux/linkage.h>
+
+ .macro addruart,rx
+ mov \rx, #0x03000000
+ orr \rx, \rx, #0x00010000
+ orr \rx, \rx, #0x00000fe0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #0x14]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x18]
+ tst \rd, #0x10
+ beq 1001b
+ .endm
+
+ .text
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+ mov r1, #8
+ b printhex
+
+ENTRY(printhex4)
+ mov r1, #4
+ b printhex
+
+ENTRY(printhex2)
+ mov r1, #2
+printhex: ldr r2, =hexbuf
+ add r3, r2, r1
+ mov r1, #0
+ strb r1, [r3]
+1: and r1, r0, #15
+ mov r0, r0, lsr #4
+ cmp r1, #10
+ addlt r1, r1, #'0'
+ addge r1, r1, #'a' - 10
+ strb r1, [r3, #-1]!
+ teq r3, r2
+ bne 1b
+ mov r0, r2
+ b printascii
+
+ .ltorg
+
+ENTRY(printascii)
+ addruart r3
+ b 2f
+1: waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ teq r1, #'\n'
+ moveq r1, #'\r'
+ beq 1b
+2: teq r0, #0
+ ldrneb r1, [r0], #1
+ teqne r1, #0
+ bne 1b
+ mov pc, lr
+
+ENTRY(printch)
+ addruart r3
+ mov r1, r0
+ mov r0, #0
+ b 1b
+
+ .bss
+hexbuf: .space 16
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
new file mode 100644
index 000000000..fef1489b7
--- /dev/null
+++ b/arch/arm/kernel/debug-armv.S
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/kernel/debug-armv.S
+ *
+ * Copyright (C) 1994-1999 Russell King
+ *
+ * 32-bit debugging code
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/hardware.h>
+#include <asm/dec21285.h>
+
+ .text
+
+/*
+ * Some debugging routines (useful if you've got MM problems and
+ * printk isn't working). For DEBUGGING ONLY!!! Do not leave
+ * references to these in a production kernel!
+ */
+#if defined(CONFIG_ARCH_RPC)
+ .macro addruart,rx
+ mov \rx, #0xe0000000
+ orr \rx, \rx, #0x00010000
+ orr \rx, \rx, #0x00000fe0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #0x14]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x18]
+ tst \rd, #0x10
+ beq 1001b
+ .endm
+
+#elif defined(CONFIG_ARCH_EBSA110)
+ .macro addruart,rx
+ mov \rx, #0xf0000000
+ orr \rx, \rx, #0x00000be0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #0x14]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x18]
+ tst \rd, #0x10
+ beq 1001b
+ .endm
+
+#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE)
+#ifndef CONFIG_DEBUG_DC21285_PORT
+ /* For NetWinder debugging */
+ .macro addruart,rx
+ mov \rx, #0xff000000
+ orr \rx, \rx, #0x000003f8
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #0x5]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x6]
+ tst \rd, #0x10
+ beq 1001b
+ .endm
+#else
+ /* For EBSA285 debugging */
+ .equ dc21285_high, ARMCSR_BASE & 0xff000000
+ .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+ .macro addruart,rx
+ mov \rx, #dc21285_high
+ .if dc21285_low
+ orr \rx, \rx, #dc21285_low
+ .endif
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x160] @ UARTDR
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x178] @ UARTFLG
+ tst \rd, #1 << 3
+ bne 1001b
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+#endif
+#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
+
+#elif defined(CONFIG_ARCH_SA1100)
+ .macro addruart,rx
+ mov \rx, #0xf8000000
+ add \rx, \rx, #0x00050000
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x14] @ UARTDR
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x20] @ UTSR1
+ tst \rd, #1 << 2
+ beq 1001b
+ .endm
+
+#else
+#error Unknown architecture
+#endif
+
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+ mov r1, #8
+ b printhex
+
+ENTRY(printhex4)
+ mov r1, #4
+ b printhex
+
+ENTRY(printhex2)
+ mov r1, #2
+printhex: ldr r2, =hexbuf
+ add r3, r2, r1
+ mov r1, #0
+ strb r1, [r3]
+1: and r1, r0, #15
+ mov r0, r0, lsr #4
+ cmp r1, #10
+ addlt r1, r1, #'0'
+ addge r1, r1, #'a' - 10
+ strb r1, [r3, #-1]!
+ teq r3, r2
+ bne 1b
+ mov r0, r2
+ b printascii
+
+ .ltorg
+
+ENTRY(printascii)
+ addruart r3
+ b 2f
+1: waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ teq r1, #'\n'
+ moveq r1, #'\r'
+ beq 1b
+2: teq r0, #0
+ ldrneb r1, [r0], #1
+ teqne r1, #0
+ bne 1b
+ mov pc, lr
+
+ENTRY(printch)
+ addruart r3
+ mov r1, r0
+ mov r0, #0
+ b 1b
+
+ .bss
+hexbuf: .space 16
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 6a4988b15..42a9a616f 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -13,241 +13,318 @@
#include <linux/init.h>
#include <linux/ioport.h>
+#include <asm/dec21285.h>
+#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/hardware.h>
#define MAX_SLOTS 21
-extern void pcibios_fixup_ebsa285(struct pci_dev *dev);
-extern void pcibios_init_ebsa285(void);
-
-int
-pcibios_present(void)
-{
- return 1;
-}
+extern int setup_arm_irq(int, struct irqaction *);
+extern void pcibios_report_device_errors(void);
+extern int (*pci_irq_fixup)(struct pci_dev *dev);
static unsigned long
-pcibios_base_address(unsigned char bus, unsigned char dev_fn)
+dc21285_base_address(struct pci_dev *dev, int where)
{
- if (bus == 0) {
- int slot = PCI_SLOT(dev_fn);
-
- if (slot < MAX_SLOTS)
- return PCICFG0_BASE + 0xc00000 +
- (slot << 11) + (PCI_FUNC(dev_fn) << 8);
- else
- return 0;
- } else
- return PCICFG1_BASE | (bus << 16) | (dev_fn << 8);
+ unsigned long addr = 0;
+ unsigned int devfn = dev->devfn;
+
+ if (dev->bus->number != 0)
+ addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn << 8);
+ else if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+ addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
+
+ return addr;
}
-int
-pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char *val)
+static int
+dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
- unsigned char v;
+ unsigned long addr = dc21285_base_address(dev, where);
+ u8 v;
if (addr)
- __asm__("ldr%?b %0, [%1, %2]"
- : "=r" (v)
- : "r" (addr), "r" (where));
+ asm("ldr%?b %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where));
else
v = 0xff;
- *val = v;
+
+ *value = v;
+
return PCIBIOS_SUCCESSFUL;
}
-int
-pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned short *val)
+static int
+dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
- unsigned short v;
+ unsigned long addr = dc21285_base_address(dev, where);
+ u16 v;
if (addr)
- __asm__("ldr%?h %0, [%1, %2]"
- : "=r" (v)
- : "r" (addr), "r" (where));
+ asm("ldr%?h %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where));
else
v = 0xffff;
- *val = v;
+
+ *value = v;
+
return PCIBIOS_SUCCESSFUL;
}
-int
-pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned int *val)
+static int
+dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
- unsigned int v;
+ unsigned long addr = dc21285_base_address(dev, where);
+ u32 v;
if (addr)
- __asm__("ldr%? %0, [%1, %2]"
- : "=r" (v)
- : "r" (addr), "r" (where));
+ asm("ldr%? %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where));
else
v = 0xffffffff;
- *val = v;
+
+ *value = v;
+
return PCIBIOS_SUCCESSFUL;
}
-int
-pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char val)
+static int
+dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
+ unsigned long addr = dc21285_base_address(dev, where);
if (addr)
- __asm__("str%?b %0, [%1, %2]"
- : : "r" (val), "r" (addr), "r" (where));
+ asm("str%?b %0, [%1, %2]"
+ : : "r" (value), "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)
+static int
+dc21285_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
+ unsigned long addr = dc21285_base_address(dev, where);
if (addr)
- __asm__("str%?h %0, [%1, %2]"
- : : "r" (val), "r" (addr), "r" (where));
+ asm("str%?h %0, [%1, %2]"
+ : : "r" (value), "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)
+static int
+dc21285_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
- unsigned long addr = pcibios_base_address(bus, dev_fn);
+ unsigned long addr = dc21285_base_address(dev, where);
if (addr)
- __asm__("str%? %0, [%1, %2]"
- : : "r" (val), "r" (addr), "r" (where));
+ asm("str%? %0, [%1, %2]"
+ : : "r" (value), "r" (addr), "r" (where));
+
return PCIBIOS_SUCCESSFUL;
}
-void __init pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned short set)
+static struct pci_ops dc21285_ops = {
+ dc21285_read_config_byte,
+ dc21285_read_config_word,
+ dc21285_read_config_dword,
+ dc21285_write_config_byte,
+ dc21285_write_config_word,
+ dc21285_write_config_dword,
+};
+
+/*
+ * Warn on PCI errors.
+ */
+static void
+dc21285_error(int irq, void *dev_id, struct pt_regs *regs)
{
- unsigned short cmd;
+ static unsigned long next_warn;
+ unsigned long cmd = *CSR_PCICMD & 0x0000ffff;
+ unsigned long ctrl = (*CSR_SA110_CNTL) & 0xffffde07;
+ unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
+ int warn = time_after_eq(jiffies, next_warn);
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd = (cmd & ~clear) | set;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
-}
+ ctrl |= SA110_CNTL_DISCARDTIMER;
-void __init pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int addr)
-{
- int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
+ if (warn) {
+ next_warn = jiffies + HZ;
+ printk(KERN_DEBUG "PCI: ");
+ }
- pci_write_config_dword(dev, reg, addr);
- pci_read_config_dword(dev, reg, &addr);
+ if (irqstatus & (1 << 31)) {
+ if (warn)
+ printk("parity error ");
+ cmd |= 1 << 31;
+ }
- dev->base_address[idx] = addr;
-}
+ if (irqstatus & (1 << 30)) {
+ if (warn)
+ printk("target abort ");
+ cmd |= 1 << 28;
+ }
-void __init pcibios_fixup(void)
-{
- struct pci_dev *dev;
+ if (irqstatus & (1 << 29)) {
+ if (warn)
+ printk("master abort ");
+ cmd |= 1 << 29;
+ }
- for (dev = pci_devices; dev; dev = dev->next) {
- pcibios_fixup_ebsa285(dev);
+ if (irqstatus & (1 << 28)) {
+ if (warn)
+ printk("data parity error ");
+ cmd |= 1 << 24;
+ }
- pcibios_write_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_LINE, dev->irq);
+ if (irqstatus & (1 << 27)) {
+ if (warn)
+ printk("discard timer expired ");
+ ctrl &= ~SA110_CNTL_DISCARDTIMER;
+ }
- printk(KERN_DEBUG
- "PCI: %02x:%02x [%04x/%04x] on irq %d\n",
- dev->bus->number, dev->devfn,
- dev->vendor, dev->device, dev->irq);
+ if (irqstatus & (1 << 23)) {
+ if (warn)
+ printk("system error ");
+ ctrl |= SA110_CNTL_RXSERR;
}
- hw_init();
+ if (warn)
+ printk("pc=[<%08lX>]\n", instruction_pointer(regs));
+
+ pcibios_report_device_errors();
+
+ *CSR_PCICMD = cmd;
+ *CSR_SA110_CNTL = ctrl;
}
-void __init pcibios_init(void)
-{
- unsigned int mem_size = (unsigned int)high_memory - PAGE_OFFSET;
- unsigned long cntl;
+static struct irqaction dc21285_error_action = {
+ dc21285_error, SA_INTERRUPT, 0, "PCI error", NULL, NULL
+};
- *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
- *CSR_SDRAMBASEOFFSET = 0;
- *CSR_ROMBASEMASK = 0x80000000;
- *CSR_CSRBASEMASK = 0;
- *CSR_CSRBASEOFFSET = 0;
- *CSR_PCIADDR_EXTN = 0;
+static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
-#ifdef CONFIG_HOST_FOOTBRIDGE
- /*
- * Against my better judgement, Philip Blundell still seems
- * to be saying that we should initialise the PCI stuff here
- * when the PCI_CFN bit is not set, dispite my comment below,
- * which he decided to remove. If it is not set, then
- * the card is in add-in mode, and we're in a machine where
- * the bus is set up by 'others'.
- *
- * We should therefore not mess about with the mapping in
- * anyway, and we should not be using the virt_to_bus functions
- * that exist in the HOST architecture mode (since they assume
- * a fixed mapping).
- *
- * Instead, you should be using ADDIN mode, which allows for
- * this situation. This does assume that you have correctly
- * initialised the PCI bus, which you must have done to get
- * your PC booted.
- *
- * Unfortunately, he seems to be blind to this. I guess he'll
- * also remove all this.
- *
- * And THIS COMMENT STAYS, even if this gets patched, thank
- * you.
- */
-
- /*
- * Map our SDRAM at a known address in PCI space, just in case
- * the firmware had other ideas. Using a nonzero base is
- * necessary, since some VGA cards forcefully use PCI addresses
- * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
- *
- * NOTE! If you need to chec the PCI_CFN bit in the SA110
- * control register then you've configured the kernel wrong.
- * If you're not using host mode, then DO NOT set
- * CONFIG_HOST_FOOTBRIDGE, but use CONFIG_ADDIN_FOOTBRIDGE
- * instead. In this case, you MUST supply some firmware
- * to allow your PC to boot, plus we should not modify the
- * mappings that the PC BIOS has set up for us.
- */
- *CSR_PCICACHELINESIZE = 0x00002008;
- *CSR_PCICSRBASE = 0;
- *CSR_PCICSRIOBASE = 0;
- *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
- *CSR_PCIROMBASE = 0;
- *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
- (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
-#endif
+static int __init ebsa_irqval(struct pci_dev *dev)
+{
+ u8 pin;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
- /*
- * Clear any existing errors - we aren't
- * interested in historical data...
- */
- cntl = *CSR_SA110_CNTL & 0xffffde07;
- *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+ return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3];
+}
- pcibios_init_ebsa285();
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
- printk(KERN_DEBUG"PCI: DEC21285 revision %02lX\n", *CSR_CLASSREV & 0xff);
+static int __init cats_irqval(struct pci_dev *dev)
+{
+ if (dev->irq >= 128)
+ return 16 + (dev->irq & 0x1f);
+
+ switch (dev->irq) {
+ case 1 ... 4:
+ return irqmap_cats[dev->irq - 1];
+
+ default:
+ printk("PCI: device %02x:%02x has unknown irq line %x\n",
+ dev->bus->number, dev->devfn, dev->irq);
+ case 0:
+ break;
+ }
+ return 0;
}
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+static int __init netwinder_irqval(struct pci_dev *dev)
{
+#define DEV(v,d) ((v)<<16|(d))
+ switch (DEV(dev->vendor, dev->device)) {
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
+ return IRQ_NETWINDER_ETHER100;
+
+ case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a):
+ return IRQ_NETWINDER_ETHER10;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
+ return 0;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
+ return IRQ_ISA_HARDDISK1;
+
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
+ return IRQ_NETWINDER_VGA;
+
+ default:
+ printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
+ dev->bus->number, dev->devfn,
+ dev->vendor, dev->device);
+ return 0;
+ }
}
-char * __init pcibios_setup(char *str)
+struct pci_ops * __init dc21285_init(int pass)
{
- return str;
+ unsigned int mem_size;
+ unsigned long cntl;
+
+ if (pass == 0) {
+ mem_size = (unsigned int)high_memory - PAGE_OFFSET;
+ *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
+ *CSR_SDRAMBASEOFFSET = 0;
+ *CSR_ROMBASEMASK = 0x80000000;
+ *CSR_CSRBASEMASK = 0;
+ *CSR_CSRBASEOFFSET = 0;
+ *CSR_PCIADDR_EXTN = 0;
+
+#ifdef CONFIG_HOST_FOOTBRIDGE
+ /*
+ * Map our SDRAM at a known address in PCI space, just in case
+ * the firmware had other ideas. Using a nonzero base is
+ * necessary, since some VGA cards forcefully use PCI addresses
+ * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
+ */
+ *CSR_PCICACHELINESIZE = 0x00002008;
+ *CSR_PCICSRBASE = 0;
+ *CSR_PCICSRIOBASE = 0;
+ *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCIROMBASE = 0;
+ *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
+ (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
+#endif
+
+ printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n",
+ *CSR_CLASSREV & 0xff);
+
+ switch (machine_arch_type) {
+ case MACH_TYPE_EBSA285:
+ pci_irq_fixup = ebsa_irqval;
+ break;
+
+ case MACH_TYPE_CATS:
+ pci_irq_fixup = cats_irqval;
+ break;
+
+ case MACH_TYPE_NETWINDER:
+ pci_irq_fixup = netwinder_irqval;
+ break;
+ }
+
+ return &dc21285_ops;
+ } else {
+ /*
+ * Clear any existing errors - we aren't
+ * interested in historical data...
+ */
+ cntl = *CSR_SA110_CNTL & 0xffffde07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+ cntl = *CSR_PCICMD & 0x0000ffff;
+ *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
+
+ /*
+ * Initialise PCI error IRQ after we've finished probing
+ */
+ setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action);
+
+ return NULL;
+ }
}
diff --git a/arch/arm/kernel/dma-dummy.c b/arch/arm/kernel/dma-dummy.c
index 7efc85363..ebb9755c1 100644
--- a/arch/arm/kernel/dma-dummy.c
+++ b/arch/arm/kernel/dma-dummy.c
@@ -17,15 +17,18 @@ int request_dma(int channel, const char *device_id)
return -EINVAL;
}
-void free_dma(int channel)
-{
-}
-
-int get_dma_list(char *buf)
+int no_dma(void)
{
return 0;
}
-void __init init_dma(void)
-{
-}
+#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
+GLOBAL_ALIAS(disable_dma, no_dma);
+GLOBAL_ALIAS(enable_dma, no_dma);
+GLOBAL_ALIAS(free_dma, no_dma);
+GLOBAL_ALIAS(get_dma_residue, no_dma);
+GLOBAL_ALIAS(get_dma_list, no_dma);
+GLOBAL_ALIAS(set_dma_mode, no_dma);
+GLOBAL_ALIAS(set_dma_count, no_dma);
+GLOBAL_ALIAS(set_dma_addr, no_dma);
+GLOBAL_ALIAS(init_dma, no_dma);
diff --git a/arch/arm/kernel/dma-footbridge.c b/arch/arm/kernel/dma-footbridge.c
index 016b11c15..65875831c 100644
--- a/arch/arm/kernel/dma-footbridge.c
+++ b/arch/arm/kernel/dma-footbridge.c
@@ -13,14 +13,11 @@
#include <linux/config.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
-#include <linux/mman.h>
+#include <linux/errno.h>
#include <linux/init.h>
-#include <asm/page.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include <asm/hardware.h>
#include "dma.h"
#include "dma-isa.h"
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index f5f98bbac..74967a055 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -126,6 +126,13 @@ void isa_disable_dma(int channel, dma_t *dma)
outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
}
+static struct resource dma_resources[] = {
+ { "dma1", 0x0000, 0x000f },
+ { "dma low page", 0x0080, 0x008f },
+ { "dma2", 0x00c0, 0x00df },
+ { "dma high page", 0x0480, 0x048f }
+};
+
int __init isa_init_dma(void)
{
int dmac_found;
diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c
index e27232255..ad9afac30 100644
--- a/arch/arm/kernel/dma-rpc.c
+++ b/arch/arm/kernel/dma-rpc.c
@@ -357,6 +357,8 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
}
outb(tcr, IOMD_DMATCR);
+
+ return speed;
}
void __init arch_dma_init(dma_t *dma)
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index c4b0efef8..99b2b2b1d 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -82,7 +82,7 @@ static unsigned int have_expmask;
/* List of descriptions of cards which don't have an extended
* identification, or chunk directories containing a description.
*/
-static const struct expcard_blacklist __init blacklist[] = {
+static struct expcard_blacklist __initdata blacklist[] = {
{ MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
};
@@ -827,6 +827,8 @@ unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
ectcr |= 1 << slot;
break;
#endif
+ default:
+ break;
}
#ifdef IOMD_ECTCR
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 3e015d866..7e6d4fe51 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -298,6 +298,30 @@ irq_prio_ebsa110:
.macro irq_prio_table
.endm
+
+#elif defined(CONFIG_ARCH_SA1100)
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base
+ mov r4, #0xfa000000 @ ICIP = 0xfa050000
+ add r4, r4, #0x00050000
+ ldr \irqstat, [r4] @ get irqs
+ ldr \irqnr, [r4, #4] @ ICMR = 0xfa050004
+ ands \irqstat, \irqstat, \irqnr
+ mov \irqnr, #0
+ beq 1002f
+1001: tst \irqstat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \irqstat, \irqstat, lsr #1
+ beq 1001b
+1002:
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
#else
#error Unknown architecture
#endif
@@ -449,11 +473,15 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+
+ mrs r9, cpsr @ Enable interrupts if they were
tst r3, #I_BIT
- mrseq r0, cpsr @ Enable interrupts if they were
- biceq r0, r0, #I_BIT @ previously
- msreq cpsr, r0
+ biceq r9, r9, #I_BIT @ previously
+
mov r0, r2
+/*
+ * This routine must not corrupt r9
+ */
#ifdef MULTI_CPU
ldr r2, .LCprocfns
mov lr, pc
@@ -461,6 +489,7 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
#else
bl cpu_data_abort
#endif
+ msr cpsr, r9
mov r3, sp
bl SYMBOL_NAME(do_DataAbort)
ldr r0, [sp, #S_PSR]
@@ -544,9 +573,6 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#endif
mov fp, #0
- mrs r2, cpsr @ Enable interrupts if they were
- bic r2, r2, #I_BIT @ previously
- msr cpsr, r2
#ifdef MULTI_CPU
ldr r2, .LCprocfns
mov lr, pc
@@ -554,6 +580,10 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#else
bl cpu_data_abort
#endif
+ mrs r3, cpsr @ Enable interrupts if they were
+ bic r3, r3, #I_BIT @ previously
+ msr cpsr, r3
+
mov r3, sp
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_DataAbort)
diff --git a/arch/arm/kernel/head-armo.S b/arch/arm/kernel/head-armo.S
index d6b2b79e6..df5b02ae8 100644
--- a/arch/arm/kernel/head-armo.S
+++ b/arch/arm/kernel/head-armo.S
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/kernel/head.S
+ * linux/arch/arm/kernel/head-armo.S
*
* Copyright (C) 1994, 1995, 1996, 1997 Russell King
*
@@ -7,11 +7,13 @@
*/
#include <linux/linkage.h>
- .text
- .align
+ .globl SYMBOL_NAME(swapper_pg_dir)
+ .equ SYMBOL_NAME(swapper_pg_dir), 0x0207d000
+
/*
* Entry point.
*/
+ .section ".text.init",#alloc,#execinstr
ENTRY(stext)
ENTRY(_stext)
__entry: cmp pc, #0x02000000
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index e9a05aed6..16436684e 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -1,54 +1,60 @@
/*
- * linux/arch/arm/kernel/head32.S
+ * linux/arch/arm/kernel/head-armv.S
*
- * Copyright (C) 1994-1998 Russell King
+ * Copyright (C) 1994-1999 Russell King
*
- * Kernel 32 bit startup code for ARM6 / ARM7 / StrongARM
+ * 32-bit kernel startup code for all architectures
*/
#include <linux/config.h>
#include <linux/linkage.h>
+
+#include <asm/assembler.h>
#include <asm/hardware.h>
#include <asm/dec21285.h>
+#if (TEXTADDR & 0xffff) != 0x8000
+#error TEXTADDR must start at 0xXXXX8000
+#endif
+
+#define SWAPPER_PGDIR_OFFSET 0x4000
+
.globl SYMBOL_NAME(swapper_pg_dir)
- .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
+ .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET
.section ".text.init",#alloc,#execinstr
ENTRY(stext)
ENTRY(_stext)
-#if (TEXTADDR & 0xffff) != 0x8000
-#error TEXTADDR must start at 0xXXXX8000
-#endif
-
#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * Compatability cruft for old NetWinder NeTTroms. This
+ * code is currently scheduled for destruction in 2.5.xx
+ */
+ .rept 8
mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
+ .endr
adr r2, 1f
ldmdb r2, {r7, r8}
- and r3, r2, #0x0000c000
- teq r3, #0x00008000
+ and r3, r2, #0xc000
+ teq r3, #0x8000
beq __entry
bic r3, r2, #0xc000
orr r3, r3, #0x8000
mov r0, r3
- mov r4, #32
+ mov r4, #64
sub r5, r8, r7
b 1f
.word _stext
- .word _end
+ .word __bss_start
-1: ldmia r2!, {r6, r7, r8, r9}
+1:
+ .rept 4
+ ldmia r2!, {r6, r7, r8, r9}
stmia r3!, {r6, r7, r8, r9}
- subs r4, r4, #16
+ .endr
+ subs r4, r4, #64
bcs 1b
movs r4, r5
mov r5, #0
@@ -59,78 +65,114 @@ ENTRY(_stext)
#endif
/*
- * Entry point and restart point. Entry *must* be called with r0 == 0,
- * MMU off. Note! These should be unique!!! Please read Documentation/ARM-README
- * for more information.
- *
- * r1 = 0 -> DEC EBSA-110
- * r1 = 1 -> Acorn RiscPC
- * r1 = 2 -> ebsit
- * r1 = 3 -> nexuspci
- * r1 = 4 -> DEC EBSA-285
- * r1 = 5 -> Corel Netwinder
- * r1 = 6 -> CATS
- * r1 = 7 -> tbox
- * r1 = 8 -> SA110/21285 as co-processor
- * r1 = 9 -> CL-PS7110 system
- * r1 = 12 -> SA1100 based system
+ * Entry point. Entry *must* be called with r0 == 0, with the MMU off.
+ * r1 contains the unique architecture number. See
+ * linux/arch/arm/kernel/setup.c machine_desc[] array for the complete
+ * list. If you require a new number, please follow the instructions
+ * given in Documentation/ARM-README.
*/
+__entry: teq r0, #0
+ movne r0, #'i'
+ bne __error
+ bl __lookup_processor_type
+ teq r10, #0 @ invalid processor?
+ moveq r0, #'p'
+ beq __error
+ bl __lookup_architecture_type
+ teq r7, #0 @ invalid architecture?
+ moveq r0, #'a'
+ beq __error
+ bl __create_page_tables
+ adr lr, __aligned_call
+ add pc, r10, #12 @ flush caches (returns ctrl reg)
+
+__switch_data: .long __mmap_switched
+ .long SYMBOL_NAME(__bss_start)
+ .long SYMBOL_NAME(_end)
+ .long SYMBOL_NAME(processor_id)
+ .long SYMBOL_NAME(__machine_arch_type)
+ .long SYMBOL_NAME(cr_alignment)
+ .long SYMBOL_NAME(init_task_union)+8192
+
+ /*
+ * This needs to be aligned to a cache line.
+ */
+ .align 5
+__aligned_call:
+ ldr lr, __switch_data
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #2 @ ...........A.
+#endif
+ mcr p15, 0, r0, c1, c0
+ mov pc, lr
+
+ /*
+ * This code follows on after the page
+ * table switch and jump above.
+ *
+ * r0 = processor control register
+ * r1 = machine ID
+ * r9 = processor ID
+ */
+ .align 5
+__mmap_switched:
+ adr r3, __switch_data + 4
+ ldmia r3, {r4, r5, r6, r7, r8, sp} @ Setup stack
+
+ mov fp, #0 @ Clear BSS
+1: cmp r4, r5
+ strcc fp, [r4],#4
+ bcc 1b
+
+ str r9, [r6] @ Save processor ID
+ str r1, [r7] @ Save machine type
+ bic r2, r0, #2 @ Clear 'A' bit
+ stmia r8, {r0, r2} @ Save control register values
+ b SYMBOL_NAME(start_kernel)
+
-__entry: teq r0, #0 @ check for illegal entry...
- bne .Lerror @ loop indefinitely
- cmp r1, #9 @ Unknown machine architecture
- bge .Lerror
-/* First thing to do is to get the page tables set up so that we can call
- * the kernel in the correct place. This is relocatable code...
- * - Read processor ID register (CP#15, CR0).
- */
- mrc p15, 0, r9, c0, c0 @ get Processor ID
-/* Values are:
- * XX01XXXX = ARMv4 architecture (StrongARM)
- * XX00XXXX = ARMv3 architecture
- * 4156061X = ARM 610
- */
- adr r10, .LCProcTypes
-1: ldmia r10!, {r5, r6, r8} @ Get Set, Mask, MMU Flags
- teq r5, #0 @ End of list?
- beq .Lerror
- eor r5, r5, r9
- tst r5, r6
- addne r10, r10, #8
- bne 1b
- adr r4, .LCMachTypes
- add r4, r4, r1, lsl #4
- ldmia r4, {r4, r5, r6, r7}
/*
- * r4 = page dir in physical ram
+ * Setup the initial page tables. We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * We only map in 2MB of RAM, which should be sufficient in
+ * all cases.
+ *
+ * r4 = physical address of page tables
* r5 = physical address of start of RAM
- * r6 = I/O address
+ * r6 = physical IO address
+ * r7 = byte offset into page tables for IO
+ * r8 = page table flags
*/
+__create_page_tables:
mov r0, r4
mov r3, #0
- add r2, r0, #0x4000
-1: str r3, [r0], #4 @ Clear page table
+ add r2, r0, #0x4000 @ Clear page table
+1: str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
teq r0, r2
bne 1b
-/*
- * Add enough entries to allow the kernel to be called.
- * It will sort out the real mapping in paging_init.
- * We map in 2MB of memory into (TEXTADDR-0x8000) + 2MB
- */
+ /*
+ * map in two sections (2MB) for kernel.
+ * these are marked cacheable and bufferable.
+ */
add r0, r4, #(TEXTADDR - 0x8000) >> 18
- mov r3, #0x0000000c @ SECT_CACHEABLE | SECT_BUFFERABLE
+ mov r3, #0x0c
orr r3, r3, r8
add r3, r3, r5
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
- add r3, r3, #1 << 20
#ifdef CONFIG_DEBUG_LL
-/* Map in IO space
- * This allows debug messages to be output via a serial
- * before/while paging_init.
- */
+ /*
+ * Map in IO space for serial debugging.
+ * This allows debug messages to be output
+ * via a serial before paging_init.
+ */
add r0, r4, r7
orr r3, r6, r8
add r2, r0, #0x0800
@@ -147,45 +189,39 @@ __entry: teq r0, #0 @ check for illegal entry...
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
-1:
#endif
#endif
#ifdef CONFIG_ARCH_RPC
-/* Map in screen at 0x02000000 & SCREEN2_BASE
- * Similar reasons here - for debug, and when things go
- * wrong to a certain extent. This is of limited use to
- * non-Acorn RiscPC architectures though.
- */
+ /*
+ * Map in screen at 0x02000000 & SCREEN2_BASE
+ * Similar reasons here - for debug. This is
+ * only for Acorn RiscPC architectures.
+ */
teq r5, #0
- addne r0, r4, #0x80 @ 02000000
+ addne r0, r4, #0x80 @ 02000000
movne r3, #0x02000000
orrne r3, r3, r8
strne r3, [r0]
- addne r0, r4, #0x3600 @ d8000000
+ addne r0, r4, #0x3600 @ d8000000
strne r3, [r0]
#endif
- b aligned_call
-/*
- * The following should work on both v3 and v4 implementations
- * Note: it seems that if the mov pc,lr is on the next cache
- * line, it doesn't get fetched before the MMU starts
- * translating, which prevents the kernel from booting.
- * Ensure that this never happens.
- */
- .align 5
-aligned_call:
- mov lr, pc
- mov pc, r10 @ Call processor flush (returns ctrl reg)
- adr r5, __entry
- sub r10, r10, r5 @ Make r10 PIC
- ldr lr, .Lbranch
- mcr p15, 0, r0, c1, c0 @ Enable MMU & caches. In 3 instructions
- @ we lose this page!
mov pc, lr
-.Lerror:
+
+
+/*
+ * Exception handling. Something went wrong and we can't
+ * proceed. We ought to tell the user, but since we
+ * don't have any guarantee that we're even running on
+ * the right architecture, we do virtually nothing.
+ * r0 = ascii error character
+ *
+ * Generally, only serious errors cause this.
+ */
+__error:
#ifdef CONFIG_ARCH_RPC
-/* Turn the screen red on a error - RiscPC only.
+/*
+ * Turn the screen red on a error - RiscPC only.
*/
mov r0, #0x02000000
mov r3, #0x11
@@ -199,356 +235,171 @@ aligned_call:
1: mov r0, r0
b 1b
-.Lbranch: .long .Lalready_done_mmap @ Real address of routine
- @ DEC EBSA110 (pg dir phys, phys ram start, phys i/o)
-.LCMachTypes: .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long 0xe0000000 @ I/O address
- .long 0x3800
- @ Acorn RiscPC
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x10000000
- .long 0x10000000
- .long 0x03000000
- .long 0x3800
+/*
+ * Read processor ID register (CP#15, CR0), and determine
+ * processor type.
+ *
+ * Returns:
+ * r5, r6, r7 corrupted
+ * r8 = page table flags
+ * r9 = processor ID
+ * r10 = pointer to processor structure
+ */
+__lookup_processor_type:
+ adr r5, 2f
+ ldmia r5, {r7, r9, r10}
+ sub r5, r5, r9
+ add r7, r7, r5
+ add r10, r10, r5
+ mrc p15, 0, r9, c0, c0 @ get processor id
+1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags
+ eor r5, r5, r9
+ tst r5, r6
+ moveq pc, lr
+ add r10, r10, #36 @ sizeof(proc_info_list)
+ cmp r10, r7
+ blt 1b
+ mov r10, #0
+ mov pc, lr
- @ EBSIT ???
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000
- .long 0
- .long 0xe0000000
- .long 0x3800
+2: .long __proc_info_end
+ .long 2b
+ .long __proc_info_begin
- @ NexusPCI
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x40000000
- .long 0x40000000
- .long 0x10000000
- .long 0x3800
-
- @ DEC EBSA285
- .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 0x3800
-
- @ 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 0x3800
-
- @ 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 0x3800
-
- @ tbox
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x80000000
- .long 0x80000000 @ Address of RAM
- .long 0x00400000 @ Uart
- .long 0x3800
-
- @ DEC EBSA285 as co-processor
- .long 0x4000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long DC21285_ARMCSR_BASE @ Physical I/O base address
- .long 0x7cf00000 >> 18 @ Virtual I/O base address
-
- @ SA1100
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0xc0000000
- .long 0xc0000000
- .long 0x80000000 @ IO mapping will change when kernel gets on its feet
- .long 0x3800
-
-.LCProcTypes: @ ARM6 / 610
- .long 0x41560600
- .long 0xffffff00
- .long 0x00000c12
- b .Larmv3_flush_early @ arm v3 flush & ctrl early setup
+/*
+ * Lookup machine architecture
+ * r1 = machine architecture number
+ * Returns:
+ * r4 = physical address of page tables
+ * r5 = physical start address of RAM
+ * r6 = physical address of IO
+ * r7 = byte offset into page tables for IO
+ */
+__lookup_architecture_type:
+ cmp r1, #(__arch_types_end - __arch_types_start) / 16
+ bge 1f
+ adr r4, __arch_types_start
+ add r4, r4, r1, lsl #4
+ ldmia r4, {r4, r5, r6, r7}
+ add r4, r5, #SWAPPER_PGDIR_OFFSET
+ mov r7, r7, lsr #18
mov pc, lr
-
- @ ARM7
- .long 0x41007000
- .long 0xfffff000
- .long 0x00000c12
- b .Larmv3_flush_late @ arm v3 flush & ctrl late setup
+1: mov r7, #0
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
+/*
+ * Machine parameters. Each machine requires 4 words, which are:
+ *
+ * word0: unused
+ * word1: physical start address of RAM
+ * word2: physical start address of IO
+ * word3: virtual start address of IO
+ *
+ * The IO mappings entered here are used to set up mappings
+ * required for debugging information to be shown to the user.
+ * paging_init() does the real page table initialisation.
+ */
+ @ 0x00 - DEC EBSA110
+__arch_types_start:
+ .long 0
+ .long 0
+ .long 0xe0000000
+ .long 0xe0000000
- @ StrongARM-110 and StrongARM-1100
- .long 0x4401a100 @ 4401a100 and 4401a110
- .long 0xffffffe0
- .long 0x00000c02
- b .Larmv4_flush_early
- b .Lsa_fastclock
+ @ 0x01 - Acorn RiscPC
+ .long 0
+ .long 0x10000000
+ .long 0x03000000
+ .long 0xe0000000
+ @ 0x02 - Unused
+ .long 0
.long 0
- .align
+ .long 0xe0000000
+ .long 0xe0000000
-.Larmv3_flush_early:
- mov r0, #0
- mcr p15, 0, r0, c7, c0 @ flush caches on v3
- mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
-#ifdef CONFIG_ALIGNMENT_TRAP
- mov r0, #0x3f @ ....S..DPWCAM
-#else
- mov r0, #0x3d @ ....S..DPWC.M
-#endif
- orr r0, r0, #0x100
- mov pc, lr
+ @ 0x03 - NexusPCI
+ .long 0
+ .long 0x40000000
+ .long 0x10000000
+ .long 0xe0000000
-.Larmv3_flush_late:
- mov r0, #0
- mcr p15, 0, r0, c7, c0 @ flush caches on v3
- mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
-#ifdef CONFIG_ALIGNMENT_TRAP
- mov r0, #0x7f @ ....S.LDPWCAM
-#else
- mov r0, #0x7d @ ....S.LDPWC.M
-#endif
- orr r0, r0, #0x100
- mov pc, lr
+ @ 0x04 - DEC EBSA285
+ .long 0
+ .long 0
+ .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
+ .long 0xe0000000
-.Larmv4_flush_early:
- mov r0, #0
- mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
- mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
- mrc p15, 0, r0, c1, c0 @ get control register v4
- bic r0, r0, #0x0e00
- bic r0, r0, #0x0002
-#ifdef CONFIG_ALIGNMENT_TRAP
- orr r0, r0, #0x003f @ I...S..DPWCAM
-#else
- orr r0, r0, #0x003d @ I...S..DPWC.M
-#endif
- orr r0, r0, #0x1100 @ v4 supports separate I cache
- mov pc, lr
+ @ 0x05 - Rebel.com NetWinder
+ .long 0
+ .long 0
+ .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
+ .long 0xe0000000
-.Lsa_fastclock: mcr p15, 0, r4, c15, c1, 2 @ Enable clock switching
- mov pc, lr
+ @ 0x06 - CATS
+ .long 0
+ .long 0
+ .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
+ .long 0xe0000000
-.LC0: .long SYMBOL_NAME(__entry)
- .long SYMBOL_NAME(__machine_arch_type)
- .long SYMBOL_NAME(__bss_start)
- .long SYMBOL_NAME(processor_id)
- .long SYMBOL_NAME(_end)
- .long SYMBOL_NAME(cr_alignment)
- .long SYMBOL_NAME(init_task_union)+8192
- .align
-
-.Lalready_done_mmap:
- adr r4, .LC0
- ldmia r4, {r3, r4, r5, r6, r7, r8, sp} @ Setup stack
- add r10, r10, r3 @ Add base back in
- mov fp, #0
-1: cmp r5, r7 @ Clear BSS
- strcc fp, [r5],#4
- bcc 1b
+ @ 0x07 - tbox
+ .long 0
+ .long 0x80000000
+ .long 0x00400000 @ Uart
+ .long 0xe0000000
- bic r2, r0, #2 @ Clear 'A' bit
- stmia r8, {r0, r2} @ Save control register values
+ @ 0x08 - DEC EBSA285 as co-processor
+ .long 0
+ .long 0
+ .long DC21285_ARMCSR_BASE @ Physical I/O base address
+ .long 0x7cf00000 @ Virtual I/O base address
- str r1, [r4] @ Save machine type
- str r9, [r6] @ Save processor ID
- mov lr, pc
- add pc, r10, #4 @ Call post-processor init
- mov fp, #0
- b SYMBOL_NAME(start_kernel)
+ @ 0x09 - CL-PS7110
+ .long 0
+ .long 0
+ .long 0
+ .long 0
- .text
+ @ 0x0a - Acorn Archimedes
+ .long 0
+ .long 0
+ .long 0
+ .long 0
-#ifdef CONFIG_DEBUG_LL
-/*
- * Some debugging routines (useful if you've got MM problems and
- * printk isn't working). For DEBUGGING ONLY!!! Do not leave
- * references to these in a production kernel!
- */
-#if defined(CONFIG_ARCH_RPC)
- .macro addruart,rx
- mov \rx, #0xe0000000
- orr \rx, \rx, #0x00010000
- orr \rx, \rx, #0x00000fe0
- .endm
-
- .macro senduart,rd,rx
- strb \rd, [\rx]
- .endm
-
- .macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x14]
- and \rd, \rd, #0x60
- teq \rd, #0x60
- bne 1002b
- .endm
-
- .macro waituart,rd,rx
-1001: ldrb \rd, [\rx, #0x18]
- tst \rd, #0x10
- beq 1001b
- .endm
-
-#elif defined(CONFIG_ARCH_EBSA110)
- .macro addruart,rx
- mov \rx, #0xf0000000
- orr \rx, \rx, #0x00000be0
- .endm
-
- .macro senduart,rd,rx
- strb \rd, [\rx]
- .endm
-
- .macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x14]
- and \rd, \rd, #0x60
- teq \rd, #0x60
- bne 1002b
- .endm
-
- .macro waituart,rd,rx
-1001: ldrb \rd, [\rx, #0x18]
- tst \rd, #0x10
- beq 1001b
- .endm
-
-#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE)
-#ifndef CONFIG_DEBUG_DC21285_PORT
- /* For NetWinder debugging */
- .macro addruart,rx
- mov \rx, #0xff000000
- orr \rx, \rx, #0x000003f8
- .endm
-
- .macro senduart,rd,rx
- strb \rd, [\rx]
- .endm
-
- .macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x5]
- and \rd, \rd, #0x60
- teq \rd, #0x60
- bne 1002b
- .endm
-
- .macro waituart,rd,rx
-1001: ldrb \rd, [\rx, #0x6]
- tst \rd, #0x10
- beq 1001b
- .endm
-#else
- /* For EBSA285 debugging */
- .equ dc21285_high, ARMCSR_BASE & 0xff000000
- .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
-
- .macro addruart,rx
- mov \rx, #dc21285_high
- .if dc21285_low
- orr \rx, \rx, #dc21285_low
- .endif
- .endm
-
- .macro senduart,rd,rx
- str \rd, [\rx, #0x160] @ UARTDR
- .endm
-
- .macro busyuart,rd,rx
-1001: ldr \rd, [\rx, #0x178] @ UARTFLG
- tst \rd, #1 << 3
- bne 1001b
- .endm
-
- .macro waituart,rd,rx
- .endm
-#endif
-#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
+ @ 0x0b - Acorn A5000
+ .long 0
+ .long 0
+ .long 0
+ .long 0
-/*
- * Useful debugging routines
- */
-ENTRY(printhex8)
- mov r1, #8
- b printhex
-
-ENTRY(printhex4)
- mov r1, #4
- b printhex
-
-ENTRY(printhex2)
- mov r1, #2
-printhex: ldr r2, =hexbuf
- add r3, r2, r1
- mov r1, #0
- strb r1, [r3]
-1: and r1, r0, #15
- mov r0, r0, lsr #4
- cmp r1, #10
- addlt r1, r1, #'0'
- addge r1, r1, #'a' - 10
- strb r1, [r3, #-1]!
- teq r3, r2
- bne 1b
- mov r0, r2
- b printascii
-
- .ltorg
-
-ENTRY(printascii)
- addruart r3
- b 2f
-1: waituart r2, r3
- senduart r1, r3
- busyuart r2, r3
- teq r1, #'\n'
- moveq r1, #'\r'
- beq 1b
-2: teq r0, #0
- ldrneb r1, [r0], #1
- teqne r1, #0
- bne 1b
- mov pc, lr
+ @ 0x0c - Etoile
+ .long 0
+ .long 0
+ .long 0
+ .long 0
-ENTRY(printch)
- addruart r3
- mov r1, r0
- mov r0, #0
- b 1b
+ @ 0x0d - LaCie_NAS
+ .long 0
+ .long 0
+ .long 0
+ .long 0
- .bss
-hexbuf: .space 16
+ @ 0x0e - CL-PS7500
+ .long 0
+ .long 0
+ .long 0
+ .long 0
-#endif
+ @ 0x0f - Shark
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+__arch_types_end:
+ @ unknown - SA1100
+ .long 0
+ .long 0xc0000000
+ .long 0x80000000
+ .long 0xe0000000
diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c
index 54a64b811..117011e1d 100644
--- a/arch/arm/kernel/hw-footbridge.c
+++ b/arch/arm/kernel/hw-footbridge.c
@@ -25,269 +25,8 @@
#include <asm/system.h>
#define IRDA_IO_BASE 0x180
-#define ETHER10_IO_BASE 0x301
#define GP1_IO_BASE 0x338
#define GP2_IO_BASE 0x33a
-#define DEC21143_IO_BASE 0x401
-#define DEC21143_MEM_BASE 0x00800000
-#define CYBER2000_MEM_BASE 0x01000000
-
-int have_isa_bridge;
-
-extern int setup_arm_irq(int, struct irqaction *);
-extern void pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned short set);
-extern void pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int addr);
-extern void pci_set_irq_line(struct pci_dev *dev, unsigned int irq);
-extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
-
-#ifdef CONFIG_PCI
-
-static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
-
-static int __init ebsa_irqval(struct pci_dev *dev)
-{
- unsigned char pin;
-
- pcibios_read_config_byte(dev->bus->number,
- dev->devfn,
- PCI_INTERRUPT_PIN,
- &pin);
-
- return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3];
-}
-
-#ifdef CONFIG_CATS
-static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
-
-static int __init cats_irqval(struct pci_dev *dev)
-{
- if (dev->irq >= 128)
- return 16 + (dev->irq & 0x1f);
-
- switch (dev->irq) {
- case 1:
- case 2:
- case 3:
- case 4:
- return irqmap_cats[dev->irq - 1];
- case 0:
- return 0;
- }
-
- printk("PCI: device %02x:%02x has unknown irq line %x\n",
- dev->bus->number, dev->devfn, dev->irq);
- return 0;
-}
-#endif
-
-void __init pcibios_fixup_ebsa285(struct pci_dev *dev)
-{
- /* Latency timer of 32 */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
-
- /* 32-byte cache line size */
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
-
- /* Set SysErr enable, Parity enable */
- pci_set_cmd(dev, 0, PCI_COMMAND_FAST_BACK | PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
-
- /* If this device is an ISA bridge, set the
- * have_isa_bridge flag. We will then go looking
- * for things like keyboard, etc
- */
- if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA ||
- (dev->class >> 8) == PCI_CLASS_BRIDGE_EISA)
- have_isa_bridge = !0;
-
- /* sort out the irq mapping for this device */
- switch (machine_arch_type) {
- case MACH_TYPE_EBSA285:
- dev->irq = ebsa_irqval(dev);
- /* Turn on bus mastering - boot loader doesn't
- * - perhaps it should! - dag
- */
- pci_set_cmd(dev, 0, PCI_COMMAND_MASTER);
- break;
-
-#ifdef CONFIG_CATS
- case MACH_TYPE_CATS:
- dev->irq = cats_irqval(dev);
- /* Turn on bus mastering - boot loader doesn't
- * - perhaps it should! - dag
- */
- pci_set_cmd(dev, 0, PCI_COMMAND_MASTER);
- break;
-#endif
-#ifdef CONFIG_ARCH_NETWINDER
- case MACH_TYPE_NETWINDER:
- /* disable ROM */
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
-
-#define DEV(v,d) ((v)<<16|(d))
- switch (DEV(dev->vendor, dev->device)) {
- /* Ether 100 */
- case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
- pci_set_base_addr(dev, 0, DEC21143_IO_BASE);
- pci_set_base_addr(dev, 1, DEC21143_MEM_BASE);
- pci_set_cmd(dev, 0, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
- /* Put the chip to sleep in case the driver isn't loaded */
- pci_write_config_dword(dev, 0x40, 0x80000000);
- dev->irq = IRQ_NETWINDER_ETHER100;
- break;
-
- /* Ether 10 */
- case DEV(PCI_VENDOR_ID_WINBOND2,0x5a5a):
- pci_set_base_addr(dev, 0, ETHER10_IO_BASE);
- pci_set_cmd(dev, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY, PCI_COMMAND_IO);
- dev->irq = IRQ_NETWINDER_ETHER10;
- break;
-
- /* ISA bridge */
- case DEV(PCI_VENDOR_ID_WINBOND,PCI_DEVICE_ID_WINBOND_83C553):
- pci_set_base_addr(dev, 0, 0);
- pci_set_cmd(dev, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY, PCI_COMMAND_IO);
- /*
- * Enable all memory requests from ISA to be channeled to PCI
- */
- pci_write_config_byte(dev, 0x48, 255);
- /*
- * Disable ping-pong (as per errata)
- */
- pci_write_config_byte(dev, 0x42, 0);
- /*
- * Enable PCI packet retry
- */
- pci_write_config_byte(dev, 0x40, 0x22);
- /*
- * Do not use PCI CPU park enable, park on
- * last master, disable GAT bit
- */
- pci_write_config_byte(dev, 0x83, 0x02);
- /*
- * Default rotating priorities
- */
- pci_write_config_byte(dev, 0x80, 0xe0);
- /*
- * Rotate bank 4
- */
- pci_write_config_byte(dev, 0x81, 0x01);
- break;
-
- /* IDE */
- case DEV(PCI_VENDOR_ID_WINBOND,PCI_DEVICE_ID_WINBOND_82C105):
- pci_set_base_addr(dev, 0, 0x1f1);
- pci_set_base_addr(dev, 1, 0x3f5);
- pci_set_base_addr(dev, 2, 0x171);
- pci_set_base_addr(dev, 3, 0x375);
- pci_set_base_addr(dev, 4, 0xe801);
- pci_set_cmd(dev, PCI_COMMAND_MEMORY, PCI_COMMAND_MASTER | PCI_COMMAND_IO);
- dev->irq = IRQ_ISA_HARDDISK1;
- break;
-
- /* VGA */
- case DEV(PCI_VENDOR_ID_INTERG,0x2000):
- pci_set_base_addr(dev, 0, CYBER2000_MEM_BASE);
- pci_set_cmd(dev, PCI_COMMAND_MASTER, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- dev->irq = IRQ_NETWINDER_VGA;
- break;
- }
-#endif
- }
-}
-
-static inline void
-report_pci_dev_error(void)
-{
- struct pci_dev *dev;
-
- for (dev = pci_devices; dev; dev = dev->next) {
- unsigned short status;
-
- pci_read_config_word(dev, PCI_STATUS, &status);
- if (status & 0xf900) {
- printk(KERN_DEBUG "PCI: [%04X:%04X] status = %X\n",
- dev->vendor, dev->device, status);
-
- pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
- }
- }
-}
-#else
-#define report_pci_dev_error()
-#endif
-
-/*
- * Warn on PCI errors. Please report any occurances!
- */
-static void
-irq_pci_err(int irq, void *dev_id, struct pt_regs *regs)
-{
- static unsigned long next_warn;
- unsigned long cmd = *CSR_PCICMD & 0x0000ffff;
- unsigned long ctrl = (*CSR_SA110_CNTL) & 0xffffde07;
- unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
- int warn = time_after_eq(jiffies, next_warn);
-
- ctrl |= SA110_CNTL_DISCARDTIMER;
-
- if (warn) {
- next_warn = jiffies + 3 * HZ / 100;
- printk(KERN_DEBUG "PCI: ");
- }
-
- if (irqstatus & (1 << 31)) {
- if (warn)
- printk("parity error ");
- cmd |= 1 << 31;
- }
-
- if (irqstatus & (1 << 30)) {
- if (warn)
- printk("target abort ");
- cmd |= 1 << 28;
- }
-
- if (irqstatus & (1 << 29)) {
- if (warn)
- printk("master abort ");
- cmd |= 1 << 29;
- }
-
- if (irqstatus & (1 << 28)) {
- if (warn)
- printk("data parity error ");
- cmd |= 1 << 24;
- }
-
- if (irqstatus & (1 << 27)) {
- if (warn)
- printk("discard timer expired ");
- ctrl &= ~SA110_CNTL_DISCARDTIMER;
- }
-
- if (irqstatus & (1 << 23)) {
- if (warn)
- printk("system error ");
- ctrl |= SA110_CNTL_RXSERR;
- }
-
- if (warn)
- printk("pc=[<%08lX>]\n", instruction_pointer(regs));
-
- report_pci_dev_error();
-
- *CSR_PCICMD = cmd;
- *CSR_SA110_CNTL = ctrl;
-}
-
-static struct irqaction irq_pci_error = {
- irq_pci_err, SA_INTERRUPT, 0, "PCI error", NULL, NULL
-};
-
-void __init pcibios_init_ebsa285(void)
-{
- setup_arm_irq(IRQ_PCI_ERR, &irq_pci_error);
-}
/*
* Netwinder stuff
@@ -627,7 +366,7 @@ void __netwinder_text cpld_modify(int mask, int set)
current_cpld = (current_cpld & ~mask) | set;
- gpio_modify_io(GPIO_DATA, 0);
+ gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0);
gpio_modify_op(GPIO_IOLOAD, 0);
for (msk = 8; msk; msk >>= 1) {
@@ -647,7 +386,7 @@ static void __init cpld_init(void)
unsigned long flags;
spin_lock_irqsave(&gpio_lock, flags);
- cpld_modify(-1, CPLD_UNMUTE | 4);
+ cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
spin_unlock_irqrestore(&gpio_lock, flags);
}
@@ -713,12 +452,15 @@ static inline void rwa010_global_init(void)
dprintk("Card no = %d\n", inb(0x203));
+ /* disable the modem section of the chip */
WRITE_RWA(7, 3);
WRITE_RWA(0x30, 0);
+ /* disable the cdrom section of the chip */
WRITE_RWA(7, 4);
WRITE_RWA(0x30, 0);
+ /* disable the MPU-401 section of the chip */
WRITE_RWA(7, 2);
WRITE_RWA(0x30, 0);
}
@@ -925,6 +667,7 @@ void __init hw_init(void)
extern void register_isa_ports(unsigned int, unsigned int,
unsigned int);
register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
+
#ifdef CONFIG_ARCH_NETWINDER
/*
* this ought to have a better home...
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index e3853f3d5..1a379ee10 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -1,4 +1,5 @@
#include <linux/mm.h>
+#include <linux/fs.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
diff --git a/arch/arm/kernel/ioport.c b/arch/arm/kernel/ioport.c
index bae897747..d40ea1cf1 100644
--- a/arch/arm/kernel/ioport.c
+++ b/arch/arm/kernel/ioport.c
@@ -9,10 +9,12 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/ioport.h>
+#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_CPU_32
asmlinkage int sys_iopl(unsigned long turn_on)
{
if (turn_on && !capable(CAP_SYS_RAWIO))
@@ -25,3 +27,9 @@ asmlinkage int sys_iopl(unsigned long turn_on)
return 0;
}
+#else
+asmlinkage int sys_iopl(unsigned long turn_on)
+{
+ return -ENOSYS;
+}
+#endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 41e2050e6..f6c310905 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -494,8 +494,5 @@ void __init init_IRQ(void)
}
irq_init_irq();
-#ifdef CONFIG_ARCH_ACORN
- init_FIQ();
-#endif
init_dma();
}
diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/kernel/leds-footbridge.c
index 6b4cb001b..90f2fe109 100644
--- a/arch/arm/kernel/leds-footbridge.c
+++ b/arch/arm/kernel/leds-footbridge.c
@@ -138,7 +138,7 @@ static void __netwinder_text netwinder_leds_event(led_event_t evt)
switch (evt) {
case led_start:
led_state |= LED_STATE_ENABLED;
- hw_led_state = 0;
+ hw_led_state = GPIO_GREEN_LED;
break;
case led_stop:
@@ -223,26 +223,20 @@ static void dummy_leds_event(led_event_t evt)
{
}
-void __init
+static void __init
init_leds_event(led_event_t evt)
{
- switch (machine_arch_type) {
+ leds_event = dummy_leds_event;
+
#ifdef CONFIG_FOOTBRIDGE
- case MACH_TYPE_EBSA285:
- case MACH_TYPE_CO285:
+ if (machine_is_ebsa285() || machine_is_co285())
leds_event = ebsa285_leds_event;
- break;
#endif
#ifdef CONFIG_ARCH_NETWINDER
- case MACH_TYPE_NETWINDER:
+ if (machine_is_netwinder())
leds_event = netwinder_leds_event;
- break;
#endif
- default:
- leds_event = dummy_leds_event;
- }
-
leds_event(evt);
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 776dc9b88..ab92aae52 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/kernel/process.c
*
- * Copyright (C) 1996 Russell King - Converted to ARM.
+ * Copyright (C) 1996-1999 Russell King - Converted to ARM.
* Origional Copyright (C) 1995 Linus Torvalds
*/
@@ -32,6 +32,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
+#include <asm/arch/system.h>
#include <asm/io.h>
extern char *processor_modes[];
@@ -60,26 +61,38 @@ void cpu_idle(void)
current->priority = 0;
current->counter = -100;
while (1) {
- if (!current->need_resched && !hlt_counter)
- proc_idle();
- schedule();
+ if (!hlt_counter)
+ arch_do_idle();
+ if (current->need_resched) {
+ schedule();
#ifndef CONFIG_NO_PGT_CACHE
- check_pgt_cache();
+ check_pgt_cache();
#endif
+ }
}
}
static char reboot_mode = 'h';
-void __init reboot_setup(char *str, int *ints)
+int __init reboot_setup(char *str)
{
reboot_mode = str[0];
+ return 0;
}
+__setup("reboot=", reboot_setup);
+
void machine_restart(char * __unused)
{
+ /*
+ * Turn off caches, interrupts, etc
+ */
+ cpu_proc_fin();
+
arch_reset(reboot_mode);
- panic("Reboot failed\n");
+
+ printk("Reboot failed -- System halted\n");
+
while (1);
}
@@ -135,6 +148,35 @@ void show_regs(struct pt_regs * regs)
#endif
}
+void show_fpregs(struct user_fp *regs)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ unsigned long *p;
+ char type;
+
+ p = (unsigned long *)(regs->fpregs + i);
+
+ switch (regs->ftype[i]) {
+ case 1: type = 'f'; break;
+ case 2: type = 'd'; break;
+ case 3: type = 'e'; break;
+ default: type = '?'; break;
+ }
+ if (regs->init_flag)
+ type = '?';
+
+ printk(" f%d(%c): %08lx %08lx %08lx%c",
+ i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' ');
+ }
+
+
+ printk("FPSR: %08lx FPCR: %08lx\n",
+ (unsigned long)regs->fpsr,
+ (unsigned long)regs->fpcr);
+}
+
/*
* Task structure and kernel stack allocation.
*
@@ -206,6 +248,7 @@ void exit_thread(void)
void flush_thread(void)
{
memset(&current->thread.debug, 0, sizeof(current->thread.debug));
+ memset(&current->thread.fpstate, 0, sizeof(current->thread.fpstate));
current->used_math = 0;
current->flags &= ~PF_USEDFPU;
}
@@ -237,12 +280,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
*/
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
- int fpvalid = 0;
-
if (current->used_math)
- memcpy (fp, &current->thread.fpstate.soft, sizeof (fp));
+ memcpy(fp, &current->thread.fpstate.soft, sizeof (fp));
- return fpvalid;
+ return current->used_math;
}
/*
@@ -281,6 +322,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
*/
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
+ extern long sys_exit(int) __attribute__((noreturn));
pid_t __ret;
__asm__ __volatile__(
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 6104b4dbe..0692d1a6c 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -447,8 +447,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
unsigned long tmp;
ret = read_long(child, addr, &tmp);
- if (ret)
- put_user(tmp, (unsigned long *) data);
+ if (!ret)
+ ret = put_user(tmp, (unsigned long *) data);
goto out;
}
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index 1bb21be3f..71bf85e09 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -8,6 +8,7 @@
* Modified for ARM by Russell King
*/
#include <linux/sched.h>
+#include <linux/errno.h>
#include <asm/semaphore.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8258bd767..b09b3798b 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -10,36 +10,27 @@
*/
#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/malloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/major.h>
#include <linux/utsname.h>
#include <linux/blk.h>
-#include <linux/init.h>
#include <linux/console.h>
+#include <linux/init.h>
#include <asm/elf.h>
#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/procinfo.h>
-#include <asm/segment.h>
#include <asm/setup.h>
#include <asm/system.h>
+#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
-#define COMMAND_LINE_SIZE 256
+#endif
#ifndef CONFIG_CMDLINE
#define CONFIG_CMDLINE ""
@@ -50,7 +41,6 @@
#endif
extern void reboot_setup(char *str, int *ints);
-extern void fpe_init(void);
extern void disable_hlt(void);
struct drive_info_struct { char dummy[32]; } drive_info;
@@ -64,10 +54,9 @@ struct screen_info screen_info = {
};
extern int root_mountflags;
-extern int _etext, _edata, _end;
+extern int _text, _etext, _edata, _end;
unsigned char aux_device_present;
-
char elf_platform[ELF_PLATFORM_SIZE];
unsigned int elf_hwcap;
@@ -76,13 +65,16 @@ unsigned int elf_hwcap;
*/
unsigned int processor_id;
unsigned int __machine_arch_type;
+unsigned int vram_size;
+unsigned int system_rev;
+unsigned int system_serial_low;
+unsigned int system_serial_high;
#ifdef MULTI_CPU
struct processor processor;
#endif
#ifdef CONFIG_ARCH_ACORN
-int memc_ctrl_reg;
-int number_mfm_drives;
-unsigned int vram_size;
+unsigned int memc_ctrl_reg;
+unsigned int number_mfm_drives;
#endif
static struct proc_info_item proc_info;
@@ -95,39 +87,41 @@ static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '
* symbol to be empty if not configured.
*/
-/*
- * initial ram disk
- */
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init
-check_initrd(unsigned long mem_start, unsigned long mem_end)
+static void __init setup_processor(void)
{
- if (initrd_end > mem_end) {
- printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx) - disabling initrd\n",
- initrd_end, mem_end);
- initrd_start = 0;
- }
-}
+ extern struct proc_info_list __proc_info_begin, __proc_info_end;
+ struct proc_info_list *list;
-#else
-#define check_initrd(ms,me)
-#endif
+ /*
+ * locate processor in the list of supported processor
+ * types. The linker builds this table for us from the
+ * entries in arch/arm/mm/proc-*.S
+ */
+ for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
+ if ((processor_id & list->cpu_mask) == list->cpu_val)
+ break;
-void __init
-setup_processor(void)
-{
- armidindex = 0;
+ /*
+ * If processor type is unrecognised, then we
+ * can do nothing...
+ */
+ if (list >= &__proc_info_end) {
+ printk("CPU configuration botched (ID %08x), unable "
+ "to continue.\n", processor_id);
+ while (1);
+ }
- while ((armidlist[armidindex].id ^ processor_id) &
- armidlist[armidindex].mask)
- armidindex += 1;
+ proc_info = *list->info;
- if (armidlist[armidindex].id == 0)
- while (1);
+#ifdef MULTI_CPU
+ processor = *list->proc;
+#endif
- processor = *armidlist[armidindex].proc;
- processor._proc_init();
+ sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
+ sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
+ elf_hwcap = list->elf_hwcap;
+
+ cpu_proc_init();
}
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -135,12 +129,13 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, };
char saved_command_line[COMMAND_LINE_SIZE];
static void __init
-setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz)
+setup_mem(char *cmd_line, unsigned long *mem_sz)
{
char c = ' ', *to = command_line;
int len = 0;
- *mem_start = (unsigned long)&_end;
+ if (!*mem_sz)
+ *mem_sz = MEM_SIZE;
for (;;) {
if (c == ' ') {
@@ -181,24 +176,27 @@ setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz)
}
static void __init
-setup_ram(int doload, int prompt, int image_start)
+setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
{
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload;
extern int rd_prompt;
extern int rd_image_start;
+ extern int rd_size;
rd_image_start = image_start;
rd_prompt = prompt;
rd_doload = doload;
+
+ if (rd_sz)
+ rd_size = rd_sz;
#endif
}
/*
* initial ram disk
*/
-static void __init
-setup_initrd(unsigned int start, unsigned int size)
+static void __init setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (start) {
@@ -211,30 +209,62 @@ setup_initrd(unsigned int start, unsigned int size)
#endif
}
-#ifdef CONFIG_ARCH_ACORN
-int memc_ctrl_reg;
-int number_mfm_drives;
-unsigned int vram_size;
+static void __init check_initrd(unsigned long mem_end)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_end > mem_end) {
+ printk ("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx) - disabling initrd\n",
+ initrd_end, mem_end);
+ initrd_start = 0;
+ }
#endif
+}
-#ifndef PARAMS_BASE
-#define PARAMS_BASE NULL
-#endif
+/*
+ * Standard memory resources
+ */
+static struct resource system_ram = { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY };
+static struct resource video_ram = { "Video RAM", 0, 0, IORESOURCE_MEM };
+static struct resource kernel_code = { "Kernel code", 0, 0, IORESOURCE_MEM };
+static struct resource kernel_data = { "Kernel data", 0, 0, IORESOURCE_MEM };
+static struct resource lpt1 = { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY };
+static struct resource lpt2 = { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY };
+static struct resource lpt3 = { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY };
+
+static void __init request_standard_resources(unsigned long end)
+{
+ kernel_code.start = __virt_to_bus((unsigned long) &_text);
+ kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1);
+ kernel_data.start = __virt_to_bus((unsigned long) &_etext);
+ kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1);
+ system_ram.start = __virt_to_bus(PAGE_OFFSET);
+ system_ram.end = __virt_to_bus(end - 1);
+
+ request_resource(&iomem_resource, &system_ram);
+ request_resource(&system_ram, &kernel_code);
+ request_resource(&system_ram, &kernel_data);
+ if (video_ram.start != video_ram.end)
+ request_resource(&iomem_resource, &video_ram);
-static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
-#define ENDIANNESS ((char)endian_test.l)
+ /*
+ * Some machines don't have the possibility of ever
+ * possessing LPT1 (lp0) and LPT3 (lp2)
+ */
+ if (machine_is_ebsa110() || machine_is_riscpc() ||
+ machine_is_netwinder())
+ request_resource(&ioport_resource, &lpt1);
+ if (machine_is_riscpc())
+ request_resource(&ioport_resource, &lpt2);
+ if (machine_is_ebsa110() || machine_is_netwinder())
+ request_resource(&ioport_resource, &lpt3);
+}
-void __init
-setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
+void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
{
struct param_struct *params = (struct param_struct *)PARAMS_BASE;
- static unsigned char smptrap;
unsigned long memory_end = 0;
- char *from = NULL;
-
- if (smptrap == 1)
- return;
- smptrap = 1;
+ char *from = default_command_line;
#if defined(CONFIG_ARCH_ARC)
__machine_arch_type = MACH_TYPE_ARCHIMEDES;
@@ -244,10 +274,11 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
setup_processor();
- init_mm.start_code = TASK_SIZE;
- init_mm.end_code = TASK_SIZE + (unsigned long) &_etext;
- init_mm.end_data = TASK_SIZE + (unsigned long) &_edata;
- init_mm.brk = TASK_SIZE + (unsigned long) &_end;
+ /*
+ * Defaults
+ */
+ ROOT_DEV = MKDEV(0, 255);
+ setup_ramdisk(1, 1, 0, 0);
/*
* Add your machine dependencies here
@@ -256,14 +287,35 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
case MACH_TYPE_EBSA110:
/* EBSA110 locks if we execute 'wait for interrupt' */
disable_hlt();
- if (params && params->u1.s.page_size != 4096)
+ if (params && params->u1.s.page_size != PAGE_SIZE)
params = NULL;
break;
+#ifdef CONFIG_ARCH_ACORN
+#ifdef CONFIG_ARCH_RPC
case MACH_TYPE_RISCPC:
/* RiscPC can't handle half-word loads and stores */
elf_hwcap &= ~HWCAP_HALF;
+ {
+ extern void init_dram_banks(struct param_struct *);
+ init_dram_banks(params);
+ }
+
+ switch (params->u1.s.pages_in_vram) {
+ case 512:
+ vram_size += PAGE_SIZE * 256;
+ case 256:
+ vram_size += PAGE_SIZE * 256;
+ default:
+ break;
+ }
+#endif
+ case MACH_TYPE_ARCHIMEDES:
+ case MACH_TYPE_A5K:
+ memc_ctrl_reg = params->u1.s.memc_control_reg;
+ number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
break;
+#endif
case MACH_TYPE_EBSA285:
if (params) {
@@ -271,6 +323,8 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
ORIG_Y = params->u1.s.video_y;
ORIG_VIDEO_COLS = params->u1.s.video_num_cols;
ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+ video_ram.start = 0x0a0000;
+ video_ram.end = 0x0bffff;
}
break;
@@ -288,53 +342,67 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
break;
case MACH_TYPE_CATS:
- /* CATS must use soft-reboot */
+ /* CATS uses soft-reboot by default, since hard reboots
+ * fail on early boards.
+ */
reboot_setup("s", NULL);
+ params = NULL;
+ ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_POINTS = 16;
+ ORIG_Y = 24;
+ video_ram.start = 0x0a0000;
+ video_ram.end = 0x0bffff;
break;
case MACH_TYPE_NETWINDER:
/*
* to be fixed in a future NeTTrom
*/
- if (params->u1.s.page_size == 4096) {
+ if (params->u1.s.page_size == PAGE_SIZE) {
if (params->u1.s.nr_pages != 0x2000 &&
params->u1.s.nr_pages != 0x4000) {
printk("Warning: bad NeTTrom parameters detected, using defaults\n");
- /*
- * This stuff doesn't appear to be initialised
- * properly by NeTTrom 2.0.6 and 2.0.7
- */
+ /*
+ * This stuff doesn't appear to be initialised
+ * properly by NeTTrom 2.0.6 and 2.0.7
+ */
params->u1.s.nr_pages = 0x2000; /* 32MB */
params->u1.s.ramdisk_size = 0;
params->u1.s.flags = FLAG_READONLY;
params->u1.s.initrd_start = 0;
params->u1.s.initrd_size = 0;
params->u1.s.rd_start = 0;
- params->u1.s.video_x = 0;
- params->u1.s.video_y = 0;
- params->u1.s.video_num_cols = 80;
- params->u1.s.video_num_rows = 30;
}
} else {
printk("Warning: no NeTTrom parameter page detected, using "
"compiled-in settings\n");
params = NULL;
}
+ video_ram.start = 0x0a0000;
+ video_ram.end = 0x0bffff;
break;
default:
break;
}
- if (params) {
- memory_end = params->u1.s.page_size *
- params->u1.s.nr_pages;
+ if (params && params->u1.s.page_size != PAGE_SIZE) {
+ printk("Warning: wrong page size configuration, "
+ "trying to continue\n");
+ params = NULL;
+ }
- ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
+ if (params) {
+ memory_end = PAGE_SIZE * params->u1.s.nr_pages;
+ ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
+ system_rev = params->u1.s.system_rev;
+ system_serial_low = params->u1.s.system_serial_low;
+ system_serial_high = params->u1.s.system_serial_high;
- setup_ram((params->u1.s.flags & FLAG_RDLOAD) == 0,
- (params->u1.s.flags & FLAG_RDPROMPT) == 0,
- params->u1.s.rd_start);
+ setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0,
+ (params->u1.s.flags & FLAG_RDPROMPT) == 0,
+ params->u1.s.rd_start,
+ params->u1.s.ramdisk_size);
setup_initrd(params->u1.s.initrd_start,
params->u1.s.initrd_size);
@@ -342,57 +410,27 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
if (!(params->u1.s.flags & FLAG_READONLY))
root_mountflags &= ~MS_RDONLY;
-#ifdef CONFIG_ARCH_ACORN
-#ifdef CONFIG_ARCH_RPC
- {
- extern void init_dram_banks(struct param_struct *);
- init_dram_banks(params);
- }
-#endif
-
- memc_ctrl_reg = params->u1.s.memc_control_reg;
- number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
- vram_size = 0;
-
- switch (params->u1.s.pages_in_vram) {
- case 512:
- vram_size += PAGE_SIZE * 256;
- case 256:
- vram_size += PAGE_SIZE * 256;
- default:
- break;
- }
-
- memory_end -= vram_size;
-#endif
-
from = params->commandline;
- } else {
- ROOT_DEV = to_kdev_t(0x00ff);
-
- setup_ram(1, 1, 0);
- setup_initrd(0, 0);
}
- if (!memory_end)
- memory_end = MEM_SIZE;
-
- if (!from)
- from = default_command_line;
-
-#ifdef CONFIG_NWFPE
- fpe_init();
-#endif
-
/* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
- setup_mem(from, memory_start_p, &memory_end);
+ setup_mem(from, &memory_end);
memory_end += PAGE_OFFSET;
- check_initrd(*memory_start_p, memory_end);
+ *cmdline_p = command_line;
+ init_mm.start_code = (unsigned long) &_text;
+ init_mm.end_code = (unsigned long) &_etext;
+ init_mm.end_data = (unsigned long) &_edata;
+ init_mm.brk = (unsigned long) &_end;
+ *memory_start_p = (unsigned long) &_end;
+ *memory_end_p = memory_end;
+
+ request_standard_resources(memory_end);
+ check_initrd(memory_end);
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
@@ -401,40 +439,49 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
conswitchp = &dummy_con;
#endif
#endif
-
- *cmdline_p = command_line;
- *memory_end_p = memory_end;
}
static const char *machine_desc[] = {
- "EBSA110",
- "Acorn-RiscPC",
+ /* Machine name Allocater */
+ "EBSA110", /* RMK */
+ "Acorn-RiscPC", /* RMK */
"unknown",
- "Nexus-FTV/PCI",
- "EBSA285",
- "Rebel-NetWinder",
- "Chalice-CATS",
- "unknown-TBOX",
- "co-EBSA285",
- "CL-PS7110",
- "Acorn-Archimedes",
- "Acorn-A5000"
+ "Nexus-FTV/PCI", /* Philip Blundell */
+ "EBSA285", /* RMK */
+ "Rebel-NetWinder", /* RMK */
+ "Chalice-CATS", /* Philip Blundell */
+ "unknown-TBOX", /* Philip Blundell */
+ "co-EBSA285", /* Mark van Doesburg */
+ "CL-PS7110", /* Werner Almesberger */
+ "Acorn-Archimedes", /* RMK/DAG */
+ "Acorn-A5000", /* RMK/PB */
+ "Etoile", /* Alex de Vries */
+ "LaCie_NAS", /* Benjamin Herrenschmidt */
+ "CL-PS7500", /* Philip Blundell */
+ "Shark" /* Alexander Schulz */
};
int get_cpuinfo(char * buffer)
{
- int len;
-
- len = sprintf(buffer,
- "Processor\t: %s %s rev %d (%s)\n"
- "BogoMips\t: %lu.%02lu\n"
- "Hardware\t: %s\n",
- proc_info.manufacturer,
- proc_info.cpu_name,
- (int)processor_id & 15,
- elf_platform,
- (loops_per_sec+2500) / 500000,
- ((loops_per_sec+2500) / 5000) % 100,
- machine_desc[machine_arch_type]);
- return len;
+ char *p = buffer;
+
+ p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
+ proc_info.manufacturer, proc_info.cpu_name,
+ (int)processor_id & 15, elf_platform);
+
+ p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
+ (loops_per_sec+2500) / 500000,
+ ((loops_per_sec+2500) / 5000) % 100);
+
+ p += sprintf(p, "Hardware\t: %s\n",
+ machine_desc[machine_arch_type]);
+
+ p += sprintf(p, "Revision\t: %04x\n",
+ system_rev);
+
+ p += sprintf(p, "Serial\t\t: %08x%08x\n",
+ system_serial_high,
+ system_serial_low);
+
+ return p - buffer;
}
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 7b2f430c1..3f86f4740 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -16,6 +16,8 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
+#include <linux/binfmts.h>
+#include <linux/tty.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -550,6 +552,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
default:
lock_kernel();
sigaddset(&current->signal, signr);
+ recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 94f158b3e..3d39c8d39 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -19,6 +19,7 @@
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/mman.h>
+#include <linux/fs.h>
#include <linux/file.h>
#include <linux/utsname.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9f9e6934f..da0d464f6 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -365,7 +365,6 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
{
pgd_t *pgd;
- printk ("current->thread.memmap = %08lX\n", current->thread.memmap);
pgd = pgd_offset(current->mm, addr);
printk ("*pgd = %08lx", pgd_val (*pgd));
if (!pgd_none (*pgd)) {
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 7f5ff3012..9a22fe08f 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -1,11 +1,11 @@
#
# linux/arch/arm/lib/Makefile
#
-# Copyright (C) 1995-1998 Russell King
+# Copyright (C) 1995-1999 Russell King
#
L_TARGET := lib.a
-L_OBJS := backtrace.o bitops.o checksum.o delay.o memcpy.o \
+L_OBJS := backtrace.o bitops.o checksum.o delay.o \
string.o system.o uaccess.o
ifeq ($(PROCESSOR),armo)
@@ -13,7 +13,7 @@ ifeq ($(PROCESSOR),armo)
endif
ifdef CONFIG_ARCH_ACORN
- L_OBJS += loaders.o io-acorn.o
+ L_OBJS += io-acorn.o
ifdef CONFIG_ARCH_A5K
L_OBJS += floppydma.o
endif
@@ -34,13 +34,13 @@ endif
include $(TOPDIR)/Rules.make
+.S.o:
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $<
+
constants.h: getconsdata.o extractconstants.pl
$(PERL) extractconstants.pl $(OBJDUMP) > $@
getconsdata.o: getconsdata.c
$(CC) $(CFLAGS) -c getconsdata.c
-checksum.o: constants.h
-
-%.o: %.S
- $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+checksum.o string.o: constants.h
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index 3789d7d4d..fd85107c3 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -21,6 +21,11 @@ ENTRY(__backtrace)
mov r0, fp
ENTRY(c_backtrace)
+
+#ifndef CONFIG_FRAME_POINTER
+ mov pc, lr
+#else
+
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?
@@ -103,3 +108,5 @@ ENTRY(c_backtrace)
.align
.Ldsi: .word 0x00e92dd8 >> 2
.word 0x00e92d00 >> 2
+
+#endif
diff --git a/arch/arm/lib/checksum.S b/arch/arm/lib/checksum.S
index daf49fc94..ae78b657a 100644
--- a/arch/arm/lib/checksum.S
+++ b/arch/arm/lib/checksum.S
@@ -74,8 +74,9 @@ ENTRY(csum_partial)
stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
.endm
-#define LOAD_REGS(cond) \
- LOADREGS(##cond##ea,fp,{r1 - r2, r4 - r8, fp, sp, pc})
+ .macro load_regs,flags
+ ldm\flags fp, {r1, r2, r4-r8, fp, sp, pc}
+ .endm
.macro load1b, reg1
9999: ldrbt \reg1, [r0], $1
@@ -134,8 +135,9 @@ ENTRY(csum_partial)
mov r9, r9, lsr #24
.endm
-#define LOAD_REGS(cond) \
- LOADREGS(##cond##ea,fp,{r1 - r2, r4 - r9, fp, sp, pc})
+ .macro load_regs,flags
+ ldm\flags fp, {r1, r2, r4-r9, fp, sp, pc}^
+ .endm
.macro load1b, reg1
tst r9, #0x01
@@ -245,7 +247,7 @@ ENTRY(csum_partial_copy_from_user)
adcs r3, r3, r4
4: ands r2, r2, #3
adceq r0, r3, #0
- LOAD_REGS(eq)
+ load_regs eqea
load1l r4
tst r2, #2
beq .exit
@@ -259,11 +261,11 @@ ENTRY(csum_partial_copy_from_user)
andne r4, r4, #255
adcnes r3, r3, r4
adcs r0, r3, #0
- LOAD_REGS(al)
+ load_regs ea
.too_small_user:
teq r2, #0
- LOAD_REGS(eq)
+ load_regs eqea
cmp r2, #2
blt .too_small_user1
load2b ip, r8
@@ -278,7 +280,7 @@ ENTRY(csum_partial_copy_from_user)
strb ip, [r1], #1
adcs r3, r3, ip
.csum_exit: adc r0, r3, #0
- LOAD_REGS(al)
+ load_regs ea
.src_not_aligned_user:
cmp r2, #4
@@ -331,7 +333,7 @@ ENTRY(csum_partial_copy_from_user)
mov r4, r5, lsr #8
4: ands r2, r2, #3
adceq r0, r3, #0
- LOAD_REGS(eq)
+ load_regs eqea
tst r2, #2
beq .exit
adcs r3, r3, r4, lsl #16
@@ -384,7 +386,7 @@ ENTRY(csum_partial_copy_from_user)
mov r4, r5, lsr #16
4: ands r2, r2, #3
adceq r0, r3, #0
- LOAD_REGS(eq)
+ load_regs eqea
tst r2, #2
beq .exit
adcs r3, r3, r4, lsl #16
@@ -437,7 +439,7 @@ ENTRY(csum_partial_copy_from_user)
mov r4, r5, lsr #24
4: ands r2, r2, #3
adceq r0, r3, #0
- LOAD_REGS(eq)
+ load_regs eqea
tst r2, #2
beq .exit
adcs r3, r3, r4, lsl #16
@@ -461,7 +463,7 @@ ENTRY(csum_partial_copy_from_user)
6002: teq r2, r1
strneb r3, [r1], #1
bne 6002b
- LOAD_REGS(al)
+ load_regs ea
#if defined(CONFIG_CPU_32)
.previous
#endif
diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c
index 9c317b639..5b46baad0 100644
--- a/arch/arm/lib/getconsdata.c
+++ b/arch/arm/lib/getconsdata.c
@@ -6,7 +6,7 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/unistd.h>
+
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -15,13 +15,6 @@
#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n)
-#ifdef KERNEL_DOMAIN
-unsigned long DOM_KERNELDOMAIN = KERNEL_DOMAIN;
-#endif
-#ifdef USER_DOMAIN
-unsigned long DOM_USERDOMAIN = USER_DOMAIN;
-#endif
-
unsigned long TSK_STATE = OFF_TSK(state);
unsigned long TSK_FLAGS = OFF_TSK(flags);
unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched);
@@ -34,10 +27,7 @@ unsigned long PGD = OFF_MM(pgd);
unsigned long TSS_SAVE = OFF_TSK(thread.save);
unsigned long TSS_FPESAVE = OFF_TSK(thread.fpstate.soft.save);
-#ifdef CONFIG_CPU_26
-unsigned long TSS_MEMMAP = OFF_TSK(thread.memmap);
-unsigned long TSS_MEMCMAP = OFF_TSK(thread.memcmap);
-#elif defined(CONFIG_CPU_32)
+#ifdef CONFIG_CPU_32
unsigned long TSS_DOMAIN = OFF_TSK(thread.domain);
#endif
@@ -86,6 +76,8 @@ unsigned long LPTE_EXEC = L_PTE_EXEC;
unsigned long LPTE_DIRTY = L_PTE_DIRTY;
#endif
+unsigned long PAGE_SZ = PAGE_SIZE;
+
unsigned long KSWI_BASE = 0x900000;
unsigned long KSWI_SYS_BASE = 0x9f0000;
unsigned long SYS_ERROR0 = 0x9f0000;
diff --git a/arch/arm/lib/loaders.S b/arch/arm/lib/loaders.S
deleted file mode 100644
index 760e2e311..000000000
--- a/arch/arm/lib/loaders.S
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * linux/arch/arm/lib/loaders.S
- *
- * This file contains the ROM loaders for buggy cards
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-/*
- * Oak SCSI
- */
-
-ENTRY(oak_scsi_loader)
- b Loak_scsi_read
- .word 0
-Loak_scsi_reset: bic r10, r11, #0x00ff0000
- ldr r2, [r10]
- RETINSTR(mov,pc,lr)
-
-Loak_scsi_read: mov r2, r1, lsr #3
- and r2, r2, #15 << 9
- bic r10, r11, #0x00ff0000
- ldr r2, [r10, r2]
- mov r2, r1, lsl #20
- ldrb r0, [r11, r2, lsr #18]
- ldr r2, [r10]
- RETINSTR(mov,pc,lr)
-
-ENTRY(atomwide_serial_loader)
- b Latomwide_serial_read
- .word 0
-Latomwide_serial_reset: mov r2, #0x3c00
- strb r2, [r11, r2]
- RETINSTR(mov,pc,lr)
-
-Latomwide_serial_read: cmp r1, #0x8000
- RETINSTR(movhi,pc,lr)
- add r0, r1, #0x800
- mov r0, r0, lsr #11
- mov r3, #0x3c00
- strb r0, [r11, r3]
- mov r2, r1, lsl #21
- ldrb r0, [r11, r2, lsr #19]
- strb r2, [r11, r3]
- RETINSTR(mov,pc,lr)
-
-/*
- * Cards we don't know about yet
- */
-ENTRY(noloader)
- mov r0, r0
- mov r0, #0
- RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
deleted file mode 100644
index f26e6cb1c..000000000
--- a/arch/arm/lib/memcpy.S
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * linux/arch/arm/lib/segment.S
- *
- * Copyright (C) 1995, 1996 Russell King
- * Except memcpy/memmove routine.
- */
-
-#include <asm/assembler.h>
-#include <linux/linkage.h>
-
-#ifndef ENTRY
-#define ENTRY(x...) \
- .globl _##x; \
-_##x:
-#endif
-
- .text
-#define ENTER \
- mov ip,sp ;\
- stmfd sp!,{r4-r9,fp,ip,lr,pc} ;\
- sub fp,ip,#4
-
-#define EXIT \
- LOADREGS(ea, fp, {r4 - r9, fp, sp, pc})
-
-#define EXITEQ \
- LOADREGS(eqea, fp, {r4 - r9, fp, sp, pc})
-
-# Prototype: void memcpy(void *to,const void *from,unsigned long n);
-# ARM3: cant use memcopy here!!!
-
-ENTRY(memcpy)
-ENTRY(memmove)
- ENTER
- cmp r1, r0
- bcc 19f
- subs r2, r2, #4
- blt 6f
- ands ip, r0, #3
- bne 7f
- ands ip, r1, #3
- bne 8f
-
-1: subs r2, r2, #8
- blt 5f
- subs r2, r2, #0x14
- blt 3f
-2: ldmia r1!,{r3 - r9, ip}
- stmia r0!,{r3 - r9, ip}
- subs r2, r2, #32
- bge 2b
- cmn r2, #16
- ldmgeia r1!, {r3 - r6}
- stmgeia r0!, {r3 - r6}
- subge r2, r2, #0x10
-3: adds r2, r2, #0x14
-4: ldmgeia r1!, {r3 - r5}
- stmgeia r0!, {r3 - r5}
- subges r2, r2, #12
- bge 4b
-5: adds r2, r2, #8
- blt 6f
- subs r2, r2, #4
- ldrlt r3, [r1], #4
- strlt r3, [r0], #4
- ldmgeia r1!, {r3, r4}
- stmgeia r0!, {r3, r4}
- subge r2, r2, #4
-
-6: adds r2, r2, #4
- EXITEQ
- cmp r2, #2
- ldrb r3, [r1], #1
- strb r3, [r0], #1
- ldrgeb r3, [r1], #1
- strgeb r3, [r0], #1
- ldrgtb r3, [r1], #1
- strgtb r3, [r0], #1
- EXIT
-
-7: rsb ip, ip, #4
- cmp ip, #2
- ldrb r3, [r1], #1
- strb r3, [r0], #1
- ldrgeb r3, [r1], #1
- strgeb r3, [r0], #1
- ldrgtb r3, [r1], #1
- strgtb r3, [r0], #1
- subs r2, r2, ip
- blt 6b
- ands ip, r1, #3
- beq 1b
-
-8: bic r1, r1, #3
- ldr r7, [r1], #4
- cmp ip, #2
- bgt 15f
- beq 11f
- cmp r2, #12
- blt 10f
- sub r2, r2, #12
-9: mov r3, r7, lsr #8
- ldmia r1!, {r4 - r7}
- orr r3, r3, r4, lsl #24
- mov r4, r4, lsr #8
- orr r4, r4, r5, lsl #24
- mov r5, r5, lsr #8
- orr r5, r5, r6, lsl #24
- mov r6, r6, lsr #8
- orr r6, r6, r7, lsl #24
- stmia r0!, {r3 - r6}
- subs r2, r2, #16
- bge 9b
- adds r2, r2, #12
- blt 100f
-10: mov r3, r7, lsr #8
- ldr r7, [r1], #4
- orr r3, r3, r7, lsl #24
- str r3, [r0], #4
- subs r2, r2, #4
- bge 10b
-100: sub r1, r1, #3
- b 6b
-
-11: cmp r2, #12
- blt 13f /* */
- sub r2, r2, #12
-12: mov r3, r7, lsr #16
- ldmia r1!, {r4 - r7}
- orr r3, r3, r4, lsl #16
- mov r4, r4, lsr #16
- orr r4, r4, r5, lsl #16
- mov r5, r5, lsr #16
- orr r5, r5, r6, lsl #16
- mov r6, r6, lsr #16
- orr r6, r6, r7,LSL#16
- stmia r0!, {r3 - r6}
- subs r2, r2, #16
- bge 12b
- adds r2, r2, #12
- blt 14f
-13: mov r3, r7, lsr #16
- ldr r7, [r1], #4
- orr r3, r3, r7, lsl #16
- str r3, [r0], #4
- subs r2, r2, #4
- bge 13b
-14: sub r1, r1, #2
- b 6b
-
-15: cmp r2, #12
- blt 17f
- sub r2, r2, #12
-16: mov r3, r7, lsr #24
- ldmia r1!,{r4 - r7}
- orr r3, r3, r4, lsl #8
- mov r4, r4, lsr #24
- orr r4, r4, r5, lsl #8
- mov r5, r5, lsr #24
- orr r5, r5, r6, lsl #8
- mov r6, r6, lsr #24
- orr r6, r6, r7, lsl #8
- stmia r0!, {r3 - r6}
- subs r2, r2, #16
- bge 16b
- adds r2, r2, #12
- blt 18f
-17: mov r3, r7, lsr #24
- ldr r7, [r1], #4
- orr r3, r3, r7, lsl#8
- str r3, [r0], #4
- subs r2, r2, #4
- bge 17b
-18: sub r1, r1, #1
- b 6b
-
-
-19: add r1, r1, r2
- add r0, r0, r2
- subs r2, r2, #4
- blt 24f
- ands ip, r0, #3
- bne 25f
- ands ip, r1, #3
- bne 26f
-
-20: subs r2, r2, #8
- blt 23f
- subs r2, r2, #0x14
- blt 22f
-21: ldmdb r1!, {r3 - r9, ip}
- stmdb r0!, {r3 - r9, ip}
- subs r2, r2, #32
- bge 21b
-22: cmn r2, #16
- ldmgedb r1!, {r3 - r6}
- stmgedb r0!, {r3 - r6}
- subge r2, r2, #16
- adds r2, r2, #20
- ldmgedb r1!, {r3 - r5}
- stmgedb r0!, {r3 - r5}
- subge r2, r2, #12
-23: adds r2, r2, #8
- blt 24f
- subs r2, r2, #4
- ldrlt r3, [r1, #-4]!
- strlt r3, [r0, #-4]!
- ldmgedb r1!, {r3, r4}
- stmgedb r0!, {r3, r4}
- subge r2, r2, #4
-
-24: adds r2, r2, #4
- EXITEQ
- cmp r2, #2
- ldrb r3, [r1, #-1]!
- strb r3, [r0, #-1]!
- ldrgeb r3, [r1, #-1]!
- strgeb r3, [r0, #-1]!
- ldrgtb r3, [r1, #-1]!
- strgtb r3, [r0, #-1]!
- EXIT
-
-25: cmp ip, #2
- ldrb r3, [r1, #-1]!
- strb r3, [r0, #-1]!
- ldrgeb r3, [r1, #-1]!
- strgeb r3, [r0, #-1]!
- ldrgtb r3, [r1, #-1]!
- strgtb r3, [r0, #-1]!
- subs r2, r2, ip
- blt 24b
- ands ip, r1, #3
- beq 20b
-
-26: bic r1, r1, #3
- ldr r3, [r1], #0
- cmp ip, #2
- blt 34f
- beq 30f
- cmp r2, #12
- blt 28f
- sub r2, r2, #12
-27: mov r7, r3, lsl #8
- ldmdb r1!, {r3, r4, r5, r6}
- orr r7, r7, r6, lsr #24
- mov r6, r6, lsl #8
- orr r6, r6, r5, lsr #24
- mov r5, r5, lsl #8
- orr r5, r5, r4, lsr #24
- mov r4, r4, lsl #8
- orr r4, r4, r3, lsr #24
- stmdb r0!, {r4, r5, r6, r7}
- subs r2, r2, #16
- bge 27b
- adds r2, r2, #12
- blt 29f
-28: mov ip, r3, lsl #8
- ldr r3, [r1, #-4]!
- orr ip, ip, r3, lsr #24
- str ip, [r0, #-4]!
- subs r2, r2, #4
- bge 28b
-29: add r1, r1, #3
- b 24b
-
-30: cmp r2, #12
- blt 32f
- sub r2, r2, #12
-31: mov r7, r3, lsl #16
- ldmdb r1!, {r3, r4, r5, r6}
- orr r7, r7, r6, lsr #16
- mov r6, r6, lsl #16
- orr r6, r6, r5, lsr #16
- mov r5, r5, lsl #16
- orr r5, r5, r4, lsr #16
- mov r4, r4, lsl #16
- orr r4, r4, r3, lsr #16
- stmdb r0!, {r4, r5, r6, r7}
- subs r2, r2, #16
- bge 31b
- adds r2, r2, #12
- blt 33f
-32: mov ip, r3, lsl #16
- ldr r3, [r1, #-4]!
- orr ip, ip, r3, lsr #16
- str ip, [r0, #-4]!
- subs r2, r2, #4
- bge 32b
-33: add r1, r1, #2
- b 24b
-
-34: cmp r2, #12
- blt 36f
- sub r2, r2, #12
-35: mov r7, r3, lsl #24
- ldmdb r1!, {r3, r4, r5, r6}
- orr r7, r7, r6, lsr #8
- mov r6, r6, lsl #24
- orr r6, r6, r5, lsr #8
- mov r5, r5, lsl #24
- orr r5, r5, r4, lsr #8
- mov r4, r4, lsl #24
- orr r4, r4, r3, lsr #8
- stmdb r0!, {r4, r5, r6, r7}
- subs r2, r2, #16
- bge 35b
- adds r2, r2, #12
- blt 37f
-36: mov ip, r3, lsl #24
- ldr r3, [r1, #-4]!
- orr ip, ip, r3, lsr #8
- str ip, [r0, #-4]!
- subs r2, r2, #4
- bge 36b
-37: add r1, r1, #1
- b 24b
-
- .align
-
diff --git a/arch/arm/lib/string.S b/arch/arm/lib/string.S
index 17daa9d26..ff809fd51 100644
--- a/arch/arm/lib/string.S
+++ b/arch/arm/lib/string.S
@@ -1,69 +1,112 @@
/*
* linux/arch/arm/lib/string.S
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1999 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.
+ * ASM optimised string functions
*
- * Optimisations by Matthew Wilcox
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "constants.h"
+
.text
-# Prototype: char *strrchr(const char *s,char c);
/*
* 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
+1: @ 4 <= r1
+ cmp ip, #2 @ 1
+ strltb r2, [r0], #1 @ 1
+ strleb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ rsb ip, ip, #4 @ 1
+ sub r1, r1, ip @ 1
+ cmp r1, #3 @ 1
+ bgt 2f @ 1 @ +8
+ b 4f @ 1 @ +9
- @ r2 = {32 ... 4}
+ .align 5
-1: subs r2, r2, #32
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- bgt 1b
- LOADREGS(eqfd, sp!, {pc})
+ENTRY(__memzero)
+ mov r2, #0 @ 1
+ cmp r1, #4 @ 1
+ blt 4f @ 1 @ = 3
- @ r2 can be {-4 ... -28}
+ @ r1 >= 4
- cmp r2, #-16
- stmgeia r0!, {r1, r3, ip, lr}
- addlts r2, r2, #16
- LOADREGS(eqfd, sp!, {pc})
+ ands ip, r0, #3 @ 1
+ bne 1b @ 1 @ = 5
- @ r2 can be {-4 ... -12}
+2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11
- cmp r2, #-8
- stmgeia r0!, {r1, r3}
- strne r1, [r0]
- LOADREGS(fd, sp!, {pc})
+ str lr, [sp, #-4]! @ 1
+ mov r3, #0 @ 1
+ mov ip, #0 @ 1
+ mov lr, #0 @ 1
+
+ @ 4 <= r1 <= 32 @ = 9 or 15
+
+3: subs r1, r1, #32 @ 1
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ bgt 3b @ 1
+ LOADREGS(eqfd, sp!, {pc}) @ 1/2
+
+ @ -28 <= r1 <= -1
+
+ cmp r1, #-16 @ 1
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ ldr lr, [sp], #4 @ 1
+ addlts r1, r1, #16 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
- .global __page_memcpy
-__page_memcpy: stmfd sp!, {r4, r5, lr}
-1: subs r2, r2, #4*8
- ldmgeia r1!, {r3, r4, r5, ip}
- stmgeia r0!, {r3, r4, r5, ip}
- ldmgeia r1!, {r3, r4, r5, ip}
- stmgeia r0!, {r3, r4, r5, ip}
- bgt 1b
- LOADREGS(fd, sp!, {r4, r5, pc})
-
- .global memset
-memset: mov r3, r0
+ @ -12 <= r1 <= -1
+
+ cmp r1, #-8 @ 1
+ stmgeia r0!, {r2, r3} @ 2
+ addlts r1, r1, #8 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
+
+ @ -4 <= r1 <= -1
+
+ cmp r1, #-4 @ 1
+ strge r2, [r0], #4 @ 1
+ adds r1, r1, #4 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
+
+4: @ 1 <= r1 <= 3
+ cmp r1, #2 @ 1
+ strgtb r2, [r0], #1 @ 1
+ strgeb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ RETINSTR(mov,pc,lr) @ 1
+
+/*
+ * StrongARM optimised copy_page routine
+ * now 1.72bytes/cycle, was 1.60 bytes/cycle
+ * (50MHz bus -> 86MB/s)
+ */
+
+ENTRY(copy_page)
+ stmfd sp!, {r4, lr} @ 2
+ mov r2, #PAGE_SZ/64 @ 1
+1: ldmia r1!, {r3, r4, ip, lr} @ 4
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ bne 1b @ 1
+ LOADREGS(fd, sp!, {r4, pc}) @ 3
+
+ .align 5
+ENTRY(memset) /* needed for some versions of gcc */
+ENTRY(__memset)
+ mov r3, r0
cmp r2, #16
blt 6f
ands ip, r3, #3
@@ -168,3 +211,309 @@ ENTRY(memchr)
2: movne r0, #0
subeq r0, r0, #1
LOADREGS(fd, sp!, {pc})
+
+
+#define ENTER \
+ mov ip,sp ;\
+ stmfd sp!,{r4-r9,fp,ip,lr,pc} ;\
+ sub fp,ip,#4
+
+#define EXIT \
+ LOADREGS(ea, fp, {r4 - r9, fp, sp, pc})
+
+#define EXITEQ \
+ LOADREGS(eqea, fp, {r4 - r9, fp, sp, pc})
+
+/*
+ * Prototype: void memcpy(void *to,const void *from,unsigned long n);
+ * ARM3: cant use memcopy here!!!
+ */
+ENTRY(memcpy)
+ENTRY(memmove)
+ ENTER
+ cmp r1, r0
+ bcc 19f
+ subs r2, r2, #4
+ blt 6f
+ ands ip, r0, #3
+ bne 7f
+ ands ip, r1, #3
+ bne 8f
+
+1: subs r2, r2, #8
+ blt 5f
+ subs r2, r2, #0x14
+ blt 3f
+2: ldmia r1!,{r3 - r9, ip}
+ stmia r0!,{r3 - r9, ip}
+ subs r2, r2, #32
+ bge 2b
+ cmn r2, #16
+ ldmgeia r1!, {r3 - r6}
+ stmgeia r0!, {r3 - r6}
+ subge r2, r2, #0x10
+3: adds r2, r2, #0x14
+4: ldmgeia r1!, {r3 - r5}
+ stmgeia r0!, {r3 - r5}
+ subges r2, r2, #12
+ bge 4b
+5: adds r2, r2, #8
+ blt 6f
+ subs r2, r2, #4
+ ldrlt r3, [r1], #4
+ strlt r3, [r0], #4
+ ldmgeia r1!, {r3, r4}
+ stmgeia r0!, {r3, r4}
+ subge r2, r2, #4
+
+6: adds r2, r2, #4
+ EXITEQ
+ cmp r2, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0], #1
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0], #1
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0], #1
+ EXIT
+
+7: rsb ip, ip, #4
+ cmp ip, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0], #1
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0], #1
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0], #1
+ subs r2, r2, ip
+ blt 6b
+ ands ip, r1, #3
+ beq 1b
+
+8: bic r1, r1, #3
+ ldr r7, [r1], #4
+ cmp ip, #2
+ bgt 15f
+ beq 11f
+ cmp r2, #12
+ blt 10f
+ sub r2, r2, #12
+9: mov r3, r7, lsr #8
+ ldmia r1!, {r4 - r7}
+ orr r3, r3, r4, lsl #24
+ mov r4, r4, lsr #8
+ orr r4, r4, r5, lsl #24
+ mov r5, r5, lsr #8
+ orr r5, r5, r6, lsl #24
+ mov r6, r6, lsr #8
+ orr r6, r6, r7, lsl #24
+ stmia r0!, {r3 - r6}
+ subs r2, r2, #16
+ bge 9b
+ adds r2, r2, #12
+ blt 100f
+10: mov r3, r7, lsr #8
+ ldr r7, [r1], #4
+ orr r3, r3, r7, lsl #24
+ str r3, [r0], #4
+ subs r2, r2, #4
+ bge 10b
+100: sub r1, r1, #3
+ b 6b
+
+11: cmp r2, #12
+ blt 13f /* */
+ sub r2, r2, #12
+12: mov r3, r7, lsr #16
+ ldmia r1!, {r4 - r7}
+ orr r3, r3, r4, lsl #16
+ mov r4, r4, lsr #16
+ orr r4, r4, r5, lsl #16
+ mov r5, r5, lsr #16
+ orr r5, r5, r6, lsl #16
+ mov r6, r6, lsr #16
+ orr r6, r6, r7,LSL#16
+ stmia r0!, {r3 - r6}
+ subs r2, r2, #16
+ bge 12b
+ adds r2, r2, #12
+ blt 14f
+13: mov r3, r7, lsr #16
+ ldr r7, [r1], #4
+ orr r3, r3, r7, lsl #16
+ str r3, [r0], #4
+ subs r2, r2, #4
+ bge 13b
+14: sub r1, r1, #2
+ b 6b
+
+15: cmp r2, #12
+ blt 17f
+ sub r2, r2, #12
+16: mov r3, r7, lsr #24
+ ldmia r1!,{r4 - r7}
+ orr r3, r3, r4, lsl #8
+ mov r4, r4, lsr #24
+ orr r4, r4, r5, lsl #8
+ mov r5, r5, lsr #24
+ orr r5, r5, r6, lsl #8
+ mov r6, r6, lsr #24
+ orr r6, r6, r7, lsl #8
+ stmia r0!, {r3 - r6}
+ subs r2, r2, #16
+ bge 16b
+ adds r2, r2, #12
+ blt 18f
+17: mov r3, r7, lsr #24
+ ldr r7, [r1], #4
+ orr r3, r3, r7, lsl#8
+ str r3, [r0], #4
+ subs r2, r2, #4
+ bge 17b
+18: sub r1, r1, #1
+ b 6b
+
+
+19: add r1, r1, r2
+ add r0, r0, r2
+ subs r2, r2, #4
+ blt 24f
+ ands ip, r0, #3
+ bne 25f
+ ands ip, r1, #3
+ bne 26f
+
+20: subs r2, r2, #8
+ blt 23f
+ subs r2, r2, #0x14
+ blt 22f
+21: ldmdb r1!, {r3 - r9, ip}
+ stmdb r0!, {r3 - r9, ip}
+ subs r2, r2, #32
+ bge 21b
+22: cmn r2, #16
+ ldmgedb r1!, {r3 - r6}
+ stmgedb r0!, {r3 - r6}
+ subge r2, r2, #16
+ adds r2, r2, #20
+ ldmgedb r1!, {r3 - r5}
+ stmgedb r0!, {r3 - r5}
+ subge r2, r2, #12
+23: adds r2, r2, #8
+ blt 24f
+ subs r2, r2, #4
+ ldrlt r3, [r1, #-4]!
+ strlt r3, [r0, #-4]!
+ ldmgedb r1!, {r3, r4}
+ stmgedb r0!, {r3, r4}
+ subge r2, r2, #4
+
+24: adds r2, r2, #4
+ EXITEQ
+ cmp r2, #2
+ ldrb r3, [r1, #-1]!
+ strb r3, [r0, #-1]!
+ ldrgeb r3, [r1, #-1]!
+ strgeb r3, [r0, #-1]!
+ ldrgtb r3, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ EXIT
+
+25: cmp ip, #2
+ ldrb r3, [r1, #-1]!
+ strb r3, [r0, #-1]!
+ ldrgeb r3, [r1, #-1]!
+ strgeb r3, [r0, #-1]!
+ ldrgtb r3, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ subs r2, r2, ip
+ blt 24b
+ ands ip, r1, #3
+ beq 20b
+
+26: bic r1, r1, #3
+ ldr r3, [r1], #0
+ cmp ip, #2
+ blt 34f
+ beq 30f
+ cmp r2, #12
+ blt 28f
+ sub r2, r2, #12
+27: mov r7, r3, lsl #8
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr r7, r7, r6, lsr #24
+ mov r6, r6, lsl #8
+ orr r6, r6, r5, lsr #24
+ mov r5, r5, lsl #8
+ orr r5, r5, r4, lsr #24
+ mov r4, r4, lsl #8
+ orr r4, r4, r3, lsr #24
+ stmdb r0!, {r4, r5, r6, r7}
+ subs r2, r2, #16
+ bge 27b
+ adds r2, r2, #12
+ blt 29f
+28: mov ip, r3, lsl #8
+ ldr r3, [r1, #-4]!
+ orr ip, ip, r3, lsr #24
+ str ip, [r0, #-4]!
+ subs r2, r2, #4
+ bge 28b
+29: add r1, r1, #3
+ b 24b
+
+30: cmp r2, #12
+ blt 32f
+ sub r2, r2, #12
+31: mov r7, r3, lsl #16
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr r7, r7, r6, lsr #16
+ mov r6, r6, lsl #16
+ orr r6, r6, r5, lsr #16
+ mov r5, r5, lsl #16
+ orr r5, r5, r4, lsr #16
+ mov r4, r4, lsl #16
+ orr r4, r4, r3, lsr #16
+ stmdb r0!, {r4, r5, r6, r7}
+ subs r2, r2, #16
+ bge 31b
+ adds r2, r2, #12
+ blt 33f
+32: mov ip, r3, lsl #16
+ ldr r3, [r1, #-4]!
+ orr ip, ip, r3, lsr #16
+ str ip, [r0, #-4]!
+ subs r2, r2, #4
+ bge 32b
+33: add r1, r1, #2
+ b 24b
+
+34: cmp r2, #12
+ blt 36f
+ sub r2, r2, #12
+35: mov r7, r3, lsl #24
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr r7, r7, r6, lsr #8
+ mov r6, r6, lsl #24
+ orr r6, r6, r5, lsr #8
+ mov r5, r5, lsl #24
+ orr r5, r5, r4, lsr #8
+ mov r4, r4, lsl #24
+ orr r4, r4, r3, lsr #8
+ stmdb r0!, {r4, r5, r6, r7}
+ subs r2, r2, #16
+ bge 35b
+ adds r2, r2, #12
+ blt 37f
+36: mov ip, r3, lsl #24
+ ldr r3, [r1, #-4]!
+ orr ip, ip, r3, lsr #8
+ str ip, [r0, #-4]!
+ subs r2, r2, #4
+ bge 36b
+37: add r1, r1, #1
+ b 24b
+
+ .align
+
+
diff --git a/arch/arm/lib/system.S b/arch/arm/lib/system.S
deleted file mode 100644
index f037d56ff..000000000
--- a/arch/arm/lib/system.S
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/arch/arm/lib/system.S
- *
- * Copyright (C) 1995, 1996 Russell King
- *
- * 07/06/96: Now support tasks running in SVC mode.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
- .text
-
-ENTRY(abort)
- adr r0, .abort_msg
- mov r1, lr
- b SYMBOL_NAME(panic)
-
-.abort_msg: .ascii "Eek! Got to an abort() from %p! "
- .ascii "(Please report to rmk@arm.uk.linux.org)\n\0"
- .align
diff --git a/arch/arm/lib/system.c b/arch/arm/lib/system.c
new file mode 100644
index 000000000..f3b32cd82
--- /dev/null
+++ b/arch/arm/lib/system.c
@@ -0,0 +1,22 @@
+/*
+ * linux/arch/arm/lib/system.c
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * Converted from ASM version 04/09/1999
+ */
+#include <linux/kernel.h>
+
+extern void abort(void)
+{
+ void *lr = __builtin_return_address(0);
+
+ printk(KERN_CRIT "kernel abort from %p! (Please report to rmk@arm.linux.org.uk)\n",
+ lr);
+
+ /* force an oops */
+ *(int *)0 = 0;
+
+ /* if that doesn't kill us, halt */
+ panic("Oops failed to kill thread");
+}
diff --git a/arch/arm/lib/uaccess-armo.S b/arch/arm/lib/uaccess-armo.S
index 1a740493a..695fdf0c1 100644
--- a/arch/arm/lib/uaccess-armo.S
+++ b/arch/arm/lib/uaccess-armo.S
@@ -30,7 +30,7 @@ SYMBOL_NAME(uaccess_user):
.word __arch_copy_to_user
.word __arch_clear_user
.word __arch_strncpy_from_user
- .word __arch_strlen_user
+ .word __arch_strnlen_user
@ In : r0 = x, r1 = addr, r2 = error
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index 67684cb1a..898d2ef77 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -42,11 +42,11 @@ _##x:
rsb ip, ip, #4
cmp ip, #2
ldrb r3, [r1], #1
-USER( strbt r3, [r0], #1) // May fault
+USER( strbt r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( strgebt r3, [r0], #1) // May fault
+USER( strgebt r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( strgtbt r3, [r0], #1) // May fault
+USER( strgtbt r3, [r0], #1) @ May fault
sub r2, r2, ip
b .c2u_dest_aligned
@@ -69,8 +69,8 @@ ENTRY(__arch_copy_to_user)
addmi ip, r2, #4
bmi .c2u_0nowords
ldr r3, [r1], #4
-USER( strt r3, [r0], #4) // May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT // On each page, use a ld/st??t instruction
+USER( strt r3, [r0], #4) @ May fault
+ mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
beq .c2u_0fupi
@@ -84,31 +84,31 @@ USER( strt r3, [r0], #4) // May fault
blt .c2u_0rem8lp
.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
- stmia r0!, {r3 - r6} // Shouldn't fault
+ stmia r0!, {r3 - r6} @ Shouldn't fault
ldmia r1!, {r3 - r6}
- stmia r0!, {r3 - r6} // Shouldn't fault
+ stmia r0!, {r3 - r6} @ Shouldn't fault
subs ip, ip, #32
bpl .c2u_0cpy8lp
.c2u_0rem8lp: cmn ip, #16
ldmgeia r1!, {r3 - r6}
- stmgeia r0!, {r3 - r6} // Shouldn't fault
+ stmgeia r0!, {r3 - r6} @ Shouldn't fault
tst ip, #8
ldmneia r1!, {r3 - r4}
- stmneia r0!, {r3 - r4} // Shouldn't fault
+ stmneia r0!, {r3 - r4} @ Shouldn't fault
tst ip, #4
ldrne r3, [r1], #4
- strnet r3, [r0], #4 // Shouldn't fault
+ strnet r3, [r0], #4 @ Shouldn't fault
ands ip, ip, #3
beq .c2u_0fupi
.c2u_0nowords: teq ip, #0
beq .c2u_finished
.c2u_nowords: cmp ip, #2
ldrb r3, [r1], #1
-USER( strbt r3, [r0], #1) // May fault
+USER( strbt r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( strgebt r3, [r0], #1) // May fault
+USER( strgebt r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( strgtbt r3, [r0], #1) // May fault
+USER( strgtbt r3, [r0], #1) @ May fault
b .c2u_finished
.c2u_not_enough:
@@ -129,7 +129,7 @@ USER( strgtbt r3, [r0], #1) // May fault
mov r3, r7, lsr #8
ldr r7, [r1], #4
orr r3, r3, r7, lsl #24
-USER( strt r3, [r0], #4) // May fault
+USER( strt r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -149,7 +149,7 @@ USER( strt r3, [r0], #4) // May fault
orr r5, r5, r6, lsl #24
mov r6, r6, lsr #8
orr r6, r6, r7, lsl #24
- stmia r0!, {r3 - r6} // Shouldn't fault
+ stmia r0!, {r3 - r6} @ Shouldn't fault
subs ip, ip, #16
bpl .c2u_1cpy8lp
.c2u_1rem8lp: tst ip, #8
@@ -158,23 +158,23 @@ USER( strt r3, [r0], #4) // May fault
orrne r3, r3, r4, lsl #24
movne r4, r4, lsr #8
orrne r4, r4, r7, lsl #24
- stmneia r0!, {r3 - r4} // Shouldn't fault
+ stmneia r0!, {r3 - r4} @ Shouldn't fault
tst ip, #4
movne r3, r7, lsr #8
ldrne r7, [r1], #4
orrne r3, r3, r7, lsl #24
- strnet r3, [r0], #4 // Shouldn't fault
+ strnet r3, [r0], #4 @ Shouldn't fault
ands ip, ip, #3
beq .c2u_1fupi
.c2u_1nowords: mov r3, r7, lsr #8
teq ip, #0
beq .c2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) // May fault
+USER( strbt r3, [r0], #1) @ May fault
movge r3, r3, lsr #8
-USER( strgebt r3, [r0], #1) // May fault
+USER( strgebt r3, [r0], #1) @ May fault
movgt r3, r3, lsr #8
-USER( strgtbt r3, [r0], #1) // May fault
+USER( strgtbt r3, [r0], #1) @ May fault
b .c2u_finished
.c2u_2fupi: subs r2, r2, #4
@@ -183,7 +183,7 @@ USER( strgtbt r3, [r0], #1) // May fault
mov r3, r7, lsr #16
ldr r7, [r1], #4
orr r3, r3, r7, lsl #16
-USER( strt r3, [r0], #4) // May fault
+USER( strt r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -203,7 +203,7 @@ USER( strt r3, [r0], #4) // May fault
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
- stmia r0!, {r3 - r6} // Shouldn't fault
+ stmia r0!, {r3 - r6} @ Shouldn't fault
subs ip, ip, #16
bpl .c2u_2cpy8lp
.c2u_2rem8lp: tst ip, #8
@@ -212,23 +212,23 @@ USER( strt r3, [r0], #4) // May fault
orrne r3, r3, r4, lsl #16
movne r4, r4, lsr #16
orrne r4, r4, r7, lsl #16
- stmneia r0!, {r3 - r4} // Shouldn't fault
+ stmneia r0!, {r3 - r4} @ Shouldn't fault
tst ip, #4
movne r3, r7, lsr #16
ldrne r7, [r1], #4
orrne r3, r3, r7, lsl #16
- strnet r3, [r0], #4 // Shouldn't fault
+ strnet r3, [r0], #4 @ Shouldn't fault
ands ip, ip, #3
beq .c2u_2fupi
.c2u_2nowords: mov r3, r7, lsr #16
teq ip, #0
beq .c2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) // May fault
+USER( strbt r3, [r0], #1) @ May fault
movge r3, r3, lsr #8
-USER( strgebt r3, [r0], #1) // May fault
+USER( strgebt r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0
-USER( strgtbt r3, [r0], #1) // May fault
+USER( strgtbt r3, [r0], #1) @ May fault
b .c2u_finished
.c2u_3fupi: subs r2, r2, #4
@@ -237,7 +237,7 @@ USER( strgtbt r3, [r0], #1) // May fault
mov r3, r7, lsr #24
ldr r7, [r1], #4
orr r3, r3, r7, lsl #8
-USER( strt r3, [r0], #4) // May fault
+USER( strt r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -257,7 +257,7 @@ USER( strt r3, [r0], #4) // May fault
orr r5, r5, r6, lsl #8
mov r6, r6, lsr #24
orr r6, r6, r7, lsl #8
- stmia r0!, {r3 - r6} // Shouldn't fault
+ stmia r0!, {r3 - r6} @ Shouldn't fault
subs ip, ip, #16
bpl .c2u_3cpy8lp
.c2u_3rem8lp: tst ip, #8
@@ -266,23 +266,23 @@ USER( strt r3, [r0], #4) // May fault
orrne r3, r3, r4, lsl #8
movne r4, r4, lsr #24
orrne r4, r4, r7, lsl #8
- stmneia r0!, {r3 - r4} // Shouldn't fault
+ stmneia r0!, {r3 - r4} @ Shouldn't fault
tst ip, #4
movne r3, r7, lsr #24
ldrne r7, [r1], #4
orrne r3, r3, r7, lsl #8
- strnet r3, [r0], #4 // Shouldn't fault
+ strnet r3, [r0], #4 @ Shouldn't fault
ands ip, ip, #3
beq .c2u_3fupi
.c2u_3nowords: mov r3, r7, lsr #24
teq ip, #0
beq .c2u_finished
cmp ip, #2
-USER( strbt r3, [r0], #1) // May fault
+USER( strbt r3, [r0], #1) @ May fault
ldrge r3, [r1], #0
-USER( strgebt r3, [r0], #1) // May fault
+USER( strgebt r3, [r0], #1) @ May fault
movgt r3, r3, lsr #8
-USER( strgtbt r3, [r0], #1) // May fault
+USER( strgtbt r3, [r0], #1) @ May fault
b .c2u_finished
#ifndef TESTING
@@ -302,11 +302,11 @@ USER( strgtbt r3, [r0], #1) // May fault
.cfu_dest_not_aligned:
rsb ip, ip, #4
cmp ip, #2
-USER( ldrbt r3, [r1], #1) // May fault
+USER( ldrbt r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( ldrgebt r3, [r1], #1) // May fault
+USER( ldrgebt r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #1) // May fault
+USER( ldrgtbt r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
sub r2, r2, ip
b .cfu_dest_aligned
@@ -330,7 +330,7 @@ ENTRY(__arch_copy_from_user)
bmi .cfu_0nowords
USER( ldrt r3, [r1], #4)
str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT // On each page, use a ld/st??t instruction
+ mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
beq .cfu_0fupi
@@ -343,31 +343,31 @@ USER( ldrt r3, [r1], #4)
subs ip, ip, #32
blt .cfu_0rem8lp
-.cfu_0cpy8lp: ldmia r1!, {r3 - r6} // Shouldn't fault
+.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldn't fault
stmia r0!, {r3 - r6}
- ldmia r1!, {r3 - r6} // Shouldn't fault
+ ldmia r1!, {r3 - r6} @ Shouldn't fault
stmia r0!, {r3 - r6}
subs ip, ip, #32
bpl .cfu_0cpy8lp
.cfu_0rem8lp: cmn ip, #16
- ldmgeia r1!, {r3 - r6} // Shouldn't fault
+ ldmgeia r1!, {r3 - r6} @ Shouldn't fault
stmgeia r0!, {r3 - r6}
tst ip, #8
- ldmneia r1!, {r3 - r4} // Shouldn't fault
+ ldmneia r1!, {r3 - r4} @ Shouldn't fault
stmneia r0!, {r3 - r4}
tst ip, #4
- ldrnet r3, [r1], #4 // Shouldn't fault
+ ldrnet r3, [r1], #4 @ Shouldn't fault
strne r3, [r0], #4
ands ip, ip, #3
beq .cfu_0fupi
.cfu_0nowords: teq ip, #0
beq .cfu_finished
.cfu_nowords: cmp ip, #2
-USER( ldrbt r3, [r1], #1) // May fault
+USER( ldrbt r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( ldrgebt r3, [r1], #1) // May fault
+USER( ldrgebt r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #1) // May fault
+USER( ldrgtbt r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
b .cfu_finished
@@ -380,7 +380,7 @@ USER( ldrgtbt r3, [r1], #1) // May fault
.cfu_src_not_aligned:
bic r1, r1, #3
-USER( ldrt r7, [r1], #4) // May fault
+USER( ldrt r7, [r1], #4) @ May fault
cmp ip, #2
bgt .cfu_3fupi
beq .cfu_2fupi
@@ -388,7 +388,7 @@ USER( ldrt r7, [r1], #4) // May fault
addmi ip, r2, #4
bmi .cfu_1nowords
mov r3, r7, lsr #8
-USER( ldrt r7, [r1], #4) // May fault
+USER( ldrt r7, [r1], #4) @ May fault
orr r3, r3, r7, lsl #24
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -402,7 +402,7 @@ USER( ldrt r7, [r1], #4) // May fault
blt .cfu_1rem8lp
.cfu_1cpy8lp: mov r3, r7, lsr #8
- ldmia r1!, {r4 - r7} // Shouldn't fault
+ ldmia r1!, {r4 - r7} @ Shouldn't fault
orr r3, r3, r4, lsl #24
mov r4, r4, lsr #8
orr r4, r4, r5, lsl #24
@@ -415,14 +415,14 @@ USER( ldrt r7, [r1], #4) // May fault
bpl .cfu_1cpy8lp
.cfu_1rem8lp: tst ip, #8
movne r3, r7, lsr #8
- ldmneia r1!, {r4, r7} // Shouldn't fault
+ ldmneia r1!, {r4, r7} @ Shouldn't fault
orrne r3, r3, r4, lsl #24
movne r4, r4, lsr #8
orrne r4, r4, r7, lsl #24
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, lsr #8
-USER( ldrnet r7, [r1], #4) // May fault
+USER( ldrnet r7, [r1], #4) @ May fault
orrne r3, r3, r7, lsl #24
strne r3, [r0], #4
ands ip, ip, #3
@@ -442,7 +442,7 @@ USER( ldrnet r7, [r1], #4) // May fault
addmi ip, r2, #4
bmi .cfu_2nowords
mov r3, r7, lsr #16
-USER( ldrt r7, [r1], #4) // May fault
+USER( ldrt r7, [r1], #4) @ May fault
orr r3, r3, r7, lsl #16
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -456,7 +456,7 @@ USER( ldrt r7, [r1], #4) // May fault
blt .cfu_2rem8lp
.cfu_2cpy8lp: mov r3, r7, lsr #16
- ldmia r1!, {r4 - r7} // Shouldn't fault
+ ldmia r1!, {r4 - r7} @ Shouldn't fault
orr r3, r3, r4, lsl #16
mov r4, r4, lsr #16
orr r4, r4, r5, lsl #16
@@ -469,14 +469,14 @@ USER( ldrt r7, [r1], #4) // May fault
bpl .cfu_2cpy8lp
.cfu_2rem8lp: tst ip, #8
movne r3, r7, lsr #16
- ldmneia r1!, {r4, r7} // Shouldn't fault
+ ldmneia r1!, {r4, r7} @ Shouldn't fault
orrne r3, r3, r4, lsl #16
movne r4, r4, lsr #16
orrne r4, r4, r7, lsl #16
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, lsr #16
-USER( ldrnet r7, [r1], #4) // May fault
+USER( ldrnet r7, [r1], #4) @ May fault
orrne r3, r3, r7, lsl #16
strne r3, [r0], #4
ands ip, ip, #3
@@ -488,7 +488,7 @@ USER( ldrnet r7, [r1], #4) // May fault
strb r3, [r0], #1
movge r3, r3, lsr #8
strgeb r3, [r0], #1
-USER( ldrgtbt r3, [r1], #0) // May fault
+USER( ldrgtbt r3, [r1], #0) @ May fault
strgtb r3, [r0], #1
b .cfu_finished
@@ -496,7 +496,7 @@ USER( ldrgtbt r3, [r1], #0) // May fault
addmi ip, r2, #4
bmi .cfu_3nowords
mov r3, r7, lsr #24
-USER( ldrt r7, [r1], #4) // May fault
+USER( ldrt r7, [r1], #4) @ May fault
orr r3, r3, r7, lsl #8
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -510,7 +510,7 @@ USER( ldrt r7, [r1], #4) // May fault
blt .cfu_3rem8lp
.cfu_3cpy8lp: mov r3, r7, lsr #24
- ldmia r1!, {r4 - r7} // Shouldn't fault
+ ldmia r1!, {r4 - r7} @ Shouldn't fault
orr r3, r3, r4, lsl #8
mov r4, r4, lsr #24
orr r4, r4, r5, lsl #8
@@ -523,14 +523,14 @@ USER( ldrt r7, [r1], #4) // May fault
bpl .cfu_3cpy8lp
.cfu_3rem8lp: tst ip, #8
movne r3, r7, lsr #24
- ldmneia r1!, {r4, r7} // Shouldn't fault
+ ldmneia r1!, {r4, r7} @ Shouldn't fault
orrne r3, r3, r4, lsl #8
movne r4, r4, lsr #24
orrne r4, r4, r7, lsl #8
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, lsr #24
-USER( ldrnet r7, [r1], #4) // May fault
+USER( ldrnet r7, [r1], #4) @ May fault
orrne r3, r3, r7, lsl #8
strne r3, [r0], #4
ands ip, ip, #3
@@ -540,7 +540,7 @@ USER( ldrnet r7, [r1], #4) // May fault
beq .cfu_finished
cmp ip, #2
strb r3, [r0], #1
-USER( ldrget r3, [r1], #0) // May fault
+USER( ldrget r3, [r1], #0) @ May fault
strgeb r3, [r0], #1
movgt r3, r3, lsr #8
strgtb r3, [r0], #1
@@ -553,7 +553,8 @@ USER( ldrget r3, [r1], #0) // May fault
data was copied. */
9001: ldr r0, [sp], #4
ldr r1, [sp]
- bl SYMBOL_NAME(memzero)
+ teq r1, #0
+ blne SYMBOL_NAME(__memzero)
LOADREGS(fd,sp!, {r0, r4 - r7, pc})
.previous
#endif
@@ -597,19 +598,23 @@ USER( strnebt r2, [r0], #1)
9001: LOADREGS(fd,sp!, {r0, pc})
.previous
-/* Prototype: int __arch_strlen_user(char *str)
+/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
* Purpose : get length of a string in user memory
* Params : str - address of string in user memory
- * Returns : length of string *including terminator*, or zero on error
+ * Returns : length of string *including terminator*
+ * or zero on exception, or n + 1 if too long
*/
-ENTRY(__arch_strlen_user)
+ENTRY(__arch_strnlen_user)
stmfd sp!, {lr}
mov r2, r0
1:
-USER( ldrbt r1, [r0], #1)
- teq r1, #0
+USER( ldrbt r3, [r0], #1)
+ teq r3, #0
+ beq 2f
+ subs r1, r1, #1
bne 1b
- sub r0, r0, r2
+ add r0, r0, #1
+2: sub r0, r0, r2
LOADREGS(fd,sp!, {pc})
.section .fixup,"ax"
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 42a92201f..b9bffb7c9 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -8,7 +8,8 @@
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
-O_OBJS := init.o extable.o fault-$(PROCESSOR).o small_page.o
+O_OBJS := init.o extable.o fault-$(PROCESSOR).o mm-$(PROCESSOR).o \
+ small_page.o
ifeq ($(CONFIG_CPU_26),y)
O_OBJS += proc-arm2,3.o
@@ -24,13 +25,16 @@ ifeq ($(CONFIG_CPU_32),y)
ifeq ($(CONFIG_CPU_SA110),y)
P_OBJS += proc-sa110.o
endif
+ ifeq ($(CONFIG_CPU_SA1100),y)
+ P_OBJS += proc-sa110.o
+ endif
O_OBJS += mm-$(MACHINE).o ioremap.o $(sort $(P_OBJS))
endif
include $(TOPDIR)/Rules.make
-%.o: %.S
- $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+.S.o:
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_$@) -traditional -c -o $*.o $<
# Special dependencies
fault-armv.o: fault-common.c
diff --git a/arch/arm/mm/fault-armo.c b/arch/arm/mm/fault-armo.c
index c51980771..19a1fff7c 100644
--- a/arch/arm/mm/fault-armo.c
+++ b/arch/arm/mm/fault-armo.c
@@ -23,61 +23,12 @@
#define FAULT_CODE_FORCECOW 0x80
#define FAULT_CODE_PREFETCH 0x04
#define FAULT_CODE_WRITE 0x02
-#define FAULT_CODE_USER 0x01
#define DO_COW(m) ((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
#define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE))
#include "fault-common.c"
-static void *alloc_table(int size, int prio)
-{
- if (size != 128)
- printk("invalid table size\n");
- return (void *)get_page_8k(prio);
-}
-
-void free_table(void *table)
-{
- free_page_8k((unsigned long)table);
-}
-
-pgd_t *get_pgd_slow(void)
-{
- pgd_t *pgd = (pgd_t *)alloc_table(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
- pgd_t *init;
-
- if (pgd) {
- init = pgd_offset(&init_mm, 0);
- memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
- memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
- }
- return pgd;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *pte;
-
- pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (pte) {
- memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
- set_pmd(pmd, mk_pmd(pte));
- return pte + offset;
- }
- set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
- return NULL;
- }
- free_table((void *)pte);
- if (pmd_bad(*pmd)) {
- __bad_pmd(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
/*
* Handle a data abort. Note that we have to handle a range of addresses
* on ARM2/3 for ldm. If both pages are zero-mapped, then we have to force
@@ -96,11 +47,11 @@ asmlinkage int
do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
{
#if 0
- if (the memc mapping for this page exists - can check now...) {
+ if (the memc mapping for this page exists) {
printk ("Page in, but got abort (undefined instruction?)\n");
return 0;
}
#endif
- do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_PREFETCH, regs);
+ do_page_fault(addr, FAULT_CODE_PREFETCH, regs);
return 1;
}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 0c5582fb7..8c2df7f5e 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -25,104 +25,12 @@
#include <asm/unaligned.h>
#define FAULT_CODE_READ 0x02
-#define FAULT_CODE_USER 0x01
#define DO_COW(m) (!((m) & FAULT_CODE_READ))
#define READ_FAULT(m) ((m) & FAULT_CODE_READ)
#include "fault-common.c"
-/*
- * need to get a 16k page for level 1
- */
-pgd_t *get_pgd_slow(void)
-{
- pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,2);
- pgd_t *init;
- pmd_t *new_pmd;
-
- if (pgd) {
- init = pgd_offset(&init_mm, 0);
- memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
- memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
- clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
-
- /*
- * On ARM, first page must always be allocated
- */
- if (!pmd_alloc(pgd, 0))
- goto nomem;
- else {
- pmd_t *old_pmd = pmd_offset(init, 0);
- new_pmd = pmd_offset(pgd, 0);
-
- if (!pte_alloc(new_pmd, 0))
- goto nomem_pmd;
- else {
- pte_t *new_pte = pte_offset(new_pmd, 0);
- pte_t *old_pte = pte_offset(old_pmd, 0);
-
- set_pte (new_pte, *old_pte);
- }
- }
- }
- return pgd;
-
-nomem_pmd:
- pmd_free(new_pmd);
-nomem:
- return NULL;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *pte;
-
- pte = (pte_t *)get_page_2k(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (pte) {
- memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
- clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
- pte += PTRS_PER_PTE;
- set_pmd(pmd, mk_user_pmd(pte));
- return pte + offset;
- }
- set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
- return NULL;
- }
- free_page_2k((unsigned long)pte);
- if (pmd_bad(*pmd)) {
- __bad_pmd(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *pte;
-
- pte = (pte_t *)get_page_2k(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (pte) {
- memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
- clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
- pte += PTRS_PER_PTE;
- set_pmd(pmd, mk_kernel_pmd(pte));
- return pte + offset;
- }
- set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
- return NULL;
- }
- free_page_2k((unsigned long)pte);
- if (pmd_bad(*pmd)) {
- __bad_pmd_kernel(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
#ifdef DEBUG
static int sp_valid(unsigned long *sp)
{
@@ -406,6 +314,10 @@ do_alignment_exception(struct pt_regs *regs)
#endif
+#define BUG_PROC_MSG \
+ "Buggy processor (%08X), trying to continue.\n" \
+ "Please read http://www.arm.linux.org.uk/state.html for more information"
+
asmlinkage void
do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
{
@@ -416,17 +328,11 @@ do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
/*
* I want statistical information on this problem!
*/
- printk(KERN_ERR "Buggy processor (%08X), "
- "trying to continue.\n"
- "Please send contents of /proc/cpuinfo "
- "and this message to linux@arm.linux.org.uk",
- fsr);
+ printk(KERN_ERR BUG_PROC_MSG, fsr);
first = 0;
}
return;
}
-
- error_code |= FAULT_CODE_USER;
}
#define DIE(signr,nam)\
@@ -522,6 +428,6 @@ do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
asmlinkage int
do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
{
- do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
+ do_page_fault(addr, FAULT_CODE_READ, regs);
return 1;
}
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index a536515af..c87fa760e 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -30,7 +30,7 @@ void __bad_pmd_kernel(pmd_t *pmd)
* This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'.
*/
-void show_pte(struct mm_struct *mm, unsigned long addr)
+static void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
@@ -62,7 +62,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
pte = pte_offset(pmd, addr);
printk(", *pte = %08lx", pte_val(*pte));
+#ifdef CONFIG_CPU_32
printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
+#endif
} while(0);
printk("\n");
@@ -73,7 +75,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
* terminate things with extreme prejudice.
*/
static void
-kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
+kernel_page_fault(unsigned long addr, int write_access, struct pt_regs *regs,
struct task_struct *tsk, struct mm_struct *mm)
{
char *reason;
@@ -90,7 +92,7 @@ kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
printk(KERN_ALERT "pgd = %p\n", mm->pgd);
show_pte(mm, addr);
- die("Oops", regs, mode);
+ die("Oops", regs, write_access);
do_exit(SIGKILL);
}
@@ -153,7 +155,7 @@ bad_area:
up(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */
- if (mode & FAULT_CODE_USER) {
+ if (user_mode(regs)) {
tsk->thread.error_code = mode;
tsk->thread.trap_no = 14;
#ifdef CONFIG_DEBUG_USER
@@ -194,7 +196,7 @@ do_sigbus:
force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */
- if (!(mode & FAULT_CODE_USER))
+ if (!user_mode(regs))
goto no_context;
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 4fa1ca498..115cec885 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/init.c
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995-1999 Russell King
*/
#include <linux/config.h>
@@ -15,6 +15,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/swapctl.h>
#include <linux/smp.h>
#include <linux/init.h>
#ifdef CONFIG_BLK_DEV_INITRD
@@ -26,14 +27,18 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/hardware.h>
-#include <asm/proc/mm-init.h>
+
+#include "map.h"
pgd_t swapper_pg_dir[PTRS_PER_PGD];
#ifndef CONFIG_NO_PGT_CACHE
struct pgtable_cache_struct quicklists;
#endif
-extern char _etext, _stext, _edata, __bss_start, _end;
+extern unsigned long free_area_init(unsigned long, unsigned long);
+extern void show_net_buffers(void);
+
+extern char _etext, _text, _edata, __bss_start, _end;
extern char __init_begin, __init_end;
int do_check_pgt_cache(int low, int high)
@@ -67,7 +72,6 @@ int do_check_pgt_cache(int low, int high)
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
-#if PTRS_PER_PTE != 1
pte_t *empty_bad_page_table;
pte_t *__bad_pagetable(void)
@@ -81,7 +85,6 @@ pte_t *__bad_pagetable(void)
return empty_bad_page_table;
}
-#endif
unsigned long *empty_zero_page;
unsigned long *empty_bad_page;
@@ -94,27 +97,39 @@ pte_t __bad_page(void)
void show_mem(void)
{
- extern void show_net_buffers(void);
- int i,free = 0,total = 0,reserved = 0;
- int shared = 0;
+ int free = 0, total = 0, reserved = 0;
+ int shared = 0, cached = 0;
+ struct page *page, *end;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- i = MAP_NR(high_memory);
- while (i-- > 0) {
+ for (page = mem_map, end = mem_map + max_mapnr;
+ page < end; page++) {
+ if (PageSkip(page)) {
+ if (page->next_hash < page)
+ break;
+ page = page->next_hash;
+ }
total++;
- if (PageReserved(mem_map+i))
+ if (PageReserved(page))
reserved++;
- else if (!atomic_read(&mem_map[i].count))
+ else if (PageSwapCache(page))
+ cached++;
+ else if (!atomic_read(&page->count))
free++;
else
- shared += atomic_read(&mem_map[i].count) - 1;
+ shared += atomic_read(&page->count) - 1;
}
- printk("%d pages of RAM\n",total);
- printk("%d free pages\n",free);
- printk("%d reserved pages\n",reserved);
- printk("%d pages shared\n",shared);
+ printk("%d pages of RAM\n", total);
+ printk("%d free pages\n", free);
+ printk("%d reserved pages\n", reserved);
+ printk("%d pages shared\n", shared);
+ printk("%d pages swap cached\n", cached);
+#ifndef CONFIG_NO_PGT_CACHE
+ printk("%ld page tables cached\n", pgtable_cache_size);
+#endif
+ show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
@@ -125,25 +140,24 @@ void show_mem(void)
*/
unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
{
- extern unsigned long free_area_init(unsigned long, unsigned long);
-
start_mem = PAGE_ALIGN(start_mem);
+
empty_zero_page = (unsigned long *)start_mem;
+ memzero(empty_zero_page, PAGE_SIZE);
start_mem += PAGE_SIZE;
+
empty_bad_page = (unsigned long *)start_mem;
start_mem += PAGE_SIZE;
-#if PTRS_PER_PTE != 1
+
#ifdef CONFIG_CPU_32
start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
#endif
empty_bad_page_table = (pte_t *)start_mem;
start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
-#endif
- memzero (empty_zero_page, PAGE_SIZE);
- start_mem = setup_pagetables (start_mem, end_mem);
+
+ start_mem = setup_page_tables(start_mem, end_mem);
flush_tlb_all();
- update_memc_all();
end_mem &= PAGE_MASK;
high_memory = (void *)end_mem;
@@ -151,6 +165,31 @@ unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
return free_area_init(start_mem, end_mem);
}
+static inline void free_unused_mem_map(void)
+{
+ struct page *page, *end;
+
+ end = mem_map + max_mapnr;
+
+ for (page = mem_map; page < end; page++) {
+ unsigned long low, high;
+
+ if (!PageSkip(page))
+ continue;
+
+ low = PAGE_ALIGN((unsigned long)(page + 1));
+ if (page->next_hash < page)
+ high = ((unsigned long)end) & PAGE_MASK;
+ else
+ high = ((unsigned long)page->next_hash) & PAGE_MASK;
+
+ while (low < high) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(low)].flags);
+ low += PAGE_SIZE;
+ }
+ }
+}
+
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -158,28 +197,48 @@ unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
*/
void __init mem_init(unsigned long start_mem, unsigned long end_mem)
{
- extern void sound_init(void);
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
- int initpages = 0;
+ int initpages = 0, i, min_nr;
unsigned long tmp;
- end_mem &= PAGE_MASK;
- high_memory = (void *)end_mem;
- max_mapnr = num_physpages = MAP_NR(end_mem);
+ end_mem &= PAGE_MASK;
+ high_memory = (void *)end_mem;
+ max_mapnr = MAP_NR(end_mem);
+ num_physpages = 0;
+
+ /* setup address validity bitmap */
+ start_mem = create_mem_holes(start_mem, end_mem);
+
+ start_mem = PAGE_ALIGN(start_mem);
/* mark usable pages in the mem_map[] */
- mark_usable_memory_areas(&start_mem, end_mem);
+ mark_usable_memory_areas(start_mem, end_mem);
+
+ /* free unused mem_map[] entries */
+ free_unused_mem_map();
#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \
(w) < (unsigned long)(max))
for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) {
+ if (PageSkip(mem_map+MAP_NR(tmp))) {
+ unsigned long next;
+
+ next = mem_map[MAP_NR(tmp)].next_hash - mem_map;
+
+ next = (next << PAGE_SHIFT) + PAGE_OFFSET;
+
+ if (next < tmp || next >= end_mem)
+ break;
+ tmp = next;
+ }
+ num_physpages++;
if (PageReserved(mem_map+MAP_NR(tmp))) {
if (BETWEEN(tmp, &__init_begin, &__init_end))
initpages++;
- else if (BETWEEN(tmp, &_stext, &_etext))
+ else if (BETWEEN(tmp, &_text, &_etext))
codepages++;
else if (BETWEEN(tmp, &_etext, &_edata))
datapages++;
@@ -200,11 +259,24 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
- max_mapnr >> (20 - PAGE_SHIFT),
- codepages << (PAGE_SHIFT-10),
+ num_physpages >> (20 - PAGE_SHIFT),
+ codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
- datapages << (PAGE_SHIFT-10),
- initpages << (PAGE_SHIFT-10));
+ datapages << (PAGE_SHIFT-10),
+ initpages << (PAGE_SHIFT-10));
+
+ i = nr_free_pages >> 7;
+ if (PAGE_SIZE < 32768)
+ min_nr = 10;
+ else
+ min_nr = 2;
+ if (i < min_nr)
+ i = min_nr;
+ if (i > 256)
+ i = 256;
+ freepages.min = i;
+ freepages.low = i * 2;
+ freepages.high = i * 3;
#ifdef CONFIG_CPU_26
if (max_mapnr <= 128) {
@@ -240,14 +312,16 @@ void free_initmem (void)
#ifdef CONFIG_FOOTBRIDGE
{
- extern int __netwinder_begin, __netwinder_end, __ebsa285_begin, __ebsa285_end;
+ extern int __netwinder_begin, __netwinder_end,
+ __ebsa285_begin, __ebsa285_end;
if (!machine_is_netwinder())
free_area((unsigned long)(&__netwinder_begin),
(unsigned long)(&__netwinder_end),
"netwinder");
- if (!machine_is_ebsa285() && !machine_is_cats() && !machine_is_co285())
+ if (!machine_is_ebsa285() && !machine_is_cats() &&
+ !machine_is_co285())
free_area((unsigned long)(&__ebsa285_begin),
(unsigned long)(&__ebsa285_end),
"ebsa285/cats");
@@ -259,22 +333,28 @@ void free_initmem (void)
void si_meminfo(struct sysinfo *val)
{
- int i;
+ struct page *page, *end;
- i = MAP_NR(high_memory);
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = atomic_read(&buffermem);
- while (i-- > 0) {
- if (PageReserved(mem_map+i))
+ for (page = mem_map, end = mem_map + max_mapnr;
+ page < end; page++) {
+ if (PageSkip(page)) {
+ if (page->next_hash < page)
+ break;
+ page = page->next_hash;
+ }
+ if (PageReserved(page))
continue;
val->totalram++;
- if (!atomic_read(&mem_map[i].count))
+ if (!atomic_read(&page->count))
continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
+ val->sharedram += atomic_read(&page->count) - 1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
+ val->totalbig = 0;
+ val->freebig = 0;
}
-
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index e4c84fa71..141644ae2 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -27,8 +27,12 @@
* FIFO. Unfortunately, it is not possible to tell the DC21285 to
* flush this - flushing the area causes the bus to lock.
*/
-
+#include <linux/errno.h>
+#include <linux/mm.h>
#include <linux/vmalloc.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
#include <asm/io.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
@@ -145,5 +149,5 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
void __iounmap(void *addr)
{
- return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+ vfree((void *) (PAGE_MASK & (unsigned long) addr));
}
diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h
new file mode 100644
index 000000000..a1fc92b2c
--- /dev/null
+++ b/arch/arm/mm/map.h
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/mm/map.h
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * Page table mapping constructs and function prototypes
+ */
+struct map_desc {
+ unsigned long virtual;
+ unsigned long physical;
+ unsigned long length;
+ int domain:4,
+ prot_read:1,
+ prot_write:1,
+ cacheable:1,
+ bufferable:1;
+};
+
+struct mem_desc {
+ unsigned long virt_start;
+ unsigned long virt_end;
+};
+
+extern struct map_desc io_desc[];
+extern unsigned int io_desc_size;
+extern struct mem_desc mem_desc[];
+extern unsigned int mem_desc_size;
+
+extern void mark_usable_memory_areas(unsigned long start, unsigned long end);
+extern unsigned long create_mem_holes(unsigned long start, unsigned long end);
+extern unsigned long setup_page_tables(unsigned long start, unsigned long end);
+
diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c
new file mode 100644
index 000000000..55245f4e8
--- /dev/null
+++ b/arch/arm/mm/mm-armo.c
@@ -0,0 +1,170 @@
+/*
+ * arch/arm/mm/mm-armo.c
+ *
+ * Page table sludge for older ARM processor architectures.
+ *
+ * Copyright (C) 1998-1999 Russell King
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/arch/memory.h>
+
+#include "map.h"
+
+#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
+#define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR)
+
+/*
+ * FIXME: the following over-allocates by 6400%
+ */
+static inline void *alloc_table(int size, int prio)
+{
+ if (size != 128)
+ printk("invalid table size\n");
+ return (void *)get_page_8k(prio);
+}
+
+/*
+ * Allocate a page table. Note that we place the MEMC
+ * table before the page directory. This means we can
+ * easily get to both tightly-associated data structures
+ * with a single pointer. This function is slightly
+ * better - it over-allocates by only 711%
+ */
+static inline void *alloc_pgd_table(int priority)
+{
+ unsigned long pg8k;
+
+ pg8k = get_page_8k(priority);
+ if (pg8k)
+ pg8k += MEMC_TABLE_SIZE;
+
+ return (void *)pg8k;
+}
+
+void free_table(void *table)
+{
+ unsigned long tbl = (unsigned long)table;
+
+ tbl &= ~8191;
+ free_page_8k(tbl);
+}
+
+pgd_t *get_pgd_slow(void)
+{
+ pgd_t *pgd = (pgd_t *)alloc_pgd_table(GFP_KERNEL);
+ pmd_t *new_pmd;
+
+ if (pgd) {
+ pgd_t *init = pgd_offset(&init_mm, 0);
+
+ memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+ memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
+
+ /*
+ * On ARM, first page must always be allocated
+ */
+ if (!pmd_alloc(pgd, 0))
+ goto nomem;
+ else {
+ pmd_t *old_pmd = pmd_offset(init, 0);
+ new_pmd = pmd_offset(pgd, 0);
+
+ if (!pte_alloc(new_pmd, 0))
+ goto nomem_pmd;
+ else {
+ pte_t *new_pte = pte_offset(new_pmd, 0);
+ pte_t *old_pte = pte_offset(old_pmd, 0);
+
+ set_pte (new_pte, *old_pte);
+ }
+ }
+ /* update MEMC tables */
+ cpu_memc_update_all(pgd);
+ }
+ return pgd;
+
+nomem_pmd:
+ pmd_free(new_pmd);
+nomem:
+ free_table(pgd);
+ return NULL;
+}
+
+pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+{
+ pte_t *pte;
+
+ pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
+ if (pmd_none(*pmd)) {
+ if (pte) {
+ memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ set_pmd(pmd, mk_pmd(pte));
+ return pte + offset;
+ }
+ set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+ return NULL;
+ }
+ free_table((void *)pte);
+ if (pmd_bad(*pmd)) {
+ __bad_pmd(pmd);
+ return NULL;
+ }
+ return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+/*
+ * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
+ * machine. This is both processor & architecture specific, and requires
+ * some more work to get it to fit into our separate processor and
+ * architecture structure.
+ */
+int page_nr;
+
+#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
+
+static inline void setup_swapper_dir (int index, pte_t *ptep)
+{
+ set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep));
+}
+
+unsigned long __init
+setup_page_tables(unsigned long start_mem, unsigned long end_mem)
+{
+ unsigned int i;
+ union { unsigned long l; pte_t *pte; } u;
+
+ page_nr = MAP_NR(end_mem);
+
+ /* map in pages for (0x0000 - 0x8000) */
+ u.l = ((start_mem + (PTE_SIZE-1)) & ~(PTE_SIZE-1));
+ start_mem = u.l + PTE_SIZE;
+ memzero (u.pte, PTE_SIZE);
+ u.pte[0] = mk_pte(PAGE_OFFSET + 491520, PAGE_READONLY);
+ setup_swapper_dir (0, u.pte);
+
+ for (i = 1; i < PTRS_PER_PGD; i++)
+ pgd_val(swapper_pg_dir[i]) = 0;
+
+ return start_mem;
+}
+
+unsigned long __init
+create_mem_holes(unsigned long start, unsigned long end)
+{
+ return start;
+}
+
+void __init
+mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem)
+{
+ while (start_mem < end_mem) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ start_mem += PAGE_SIZE;
+ }
+}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 02890c55b..d52c21cc4 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,72 +1,375 @@
/*
* arch/arm/mm/mm-armv.c
*
- * Common routines for ARM v3 and v4 architectures.
+ * Page table sludge for ARM v3 and v4 processor architectures.
*
- * Copyright (C) 1998 Russell King
- *
- * Do not compile this file directly!
+ * Copyright (C) 1998-1999 Russell King
*/
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
-#ifndef MAPPING
-#error MAPPING not defined - do not compile this file individually
-#endif
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include "map.h"
+
+unsigned long *valid_addr_bitmap;
+
+/*
+ * need to get a 16k page for level 1
+ */
+pgd_t *get_pgd_slow(void)
+{
+ pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,2);
+ pmd_t *new_pmd;
+
+ if (pgd) {
+ pgd_t *init = pgd_offset(&init_mm, 0);
+
+ memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+ memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
+ clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
+
+ /*
+ * On ARM, first page must always be allocated
+ */
+ if (!pmd_alloc(pgd, 0))
+ goto nomem;
+ else {
+ pmd_t *old_pmd = pmd_offset(init, 0);
+ new_pmd = pmd_offset(pgd, 0);
+
+ if (!pte_alloc(new_pmd, 0))
+ goto nomem_pmd;
+ else {
+ pte_t *new_pte = pte_offset(new_pmd, 0);
+ pte_t *old_pte = pte_offset(old_pmd, 0);
+
+ set_pte (new_pte, *old_pte);
+ }
+ }
+ }
+ return pgd;
-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
+nomem_pmd:
+ pmd_free(new_pmd);
+nomem:
+ free_pages((unsigned long)pgd, 2);
+ return NULL;
+}
+
+pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+{
+ pte_t *pte;
+
+ pte = (pte_t *)get_page_2k(GFP_KERNEL);
+ if (pmd_none(*pmd)) {
+ if (pte) {
+ memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+ clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ pte += PTRS_PER_PTE;
+ set_pmd(pmd, mk_user_pmd(pte));
+ return pte + offset;
+ }
+ set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
+ return NULL;
+ }
+ free_page_2k((unsigned long)pte);
+ if (pmd_bad(*pmd)) {
+ __bad_pmd(pmd);
+ return NULL;
+ }
+ return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
+{
+ pte_t *pte;
+
+ pte = (pte_t *)get_page_2k(GFP_KERNEL);
+ if (pmd_none(*pmd)) {
+ if (pte) {
+ memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+ clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ pte += PTRS_PER_PTE;
+ set_pmd(pmd, mk_kernel_pmd(pte));
+ return pte + offset;
+ }
+ set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
+ return NULL;
+ }
+ free_page_2k((unsigned long)pte);
+ if (pmd_bad(*pmd)) {
+ __bad_pmd_kernel(pmd);
+ return NULL;
+ }
+ return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+/*
+ * Create a SECTION PGD between VIRT and PHYS in domain
+ * DOMAIN with protection PROT
+ */
+static inline void
+alloc_init_section(unsigned long virt, unsigned long phys, int prot)
+{
+ pmd_t pmd;
+
+ pmd_val(pmd) = phys | prot;
+
+ set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
+}
+
+/*
+ * Add a PAGE mapping between VIRT and PHYS in domain
+ * DOMAIN with protection PROT. Note that due to the
+ * way we map the PTEs, we must allocate two PTE_SIZE'd
+ * blocks - one for the Linux pte table, and one for
+ * the hardware pte table.
+ */
+static inline void
+alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
+{
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ pmdp = pmd_offset(pgd_offset_k(virt), virt);
+
+#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
+
+ if (pmd_none(*pmdp)) {
+ unsigned long memory = *mem;
+
+ memory = (memory + PTE_SIZE - 1) & ~(PTE_SIZE - 1);
+
+ ptep = (pte_t *)memory;
+ memzero(ptep, PTE_SIZE);
+ memory += PTE_SIZE;
+
+ ptep = (pte_t *)memory;
+ memzero(ptep, PTE_SIZE);
+
+ set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
+
+ *mem = memory + PTE_SIZE;
+ }
+
+#undef PTE_SIZE
+
+ ptep = pte_offset(pmdp, virt);
+
+ set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
+}
+
+/*
+ * Clear any PGD mapping. On a two-level page table system,
+ * the clearance is done by the middle-level functions (pmd)
+ * rather than the top-level (pgd) functions.
+ */
+static inline void
+free_init_section(unsigned long virt)
+{
+ pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
+}
+
+/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'. We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections.
+ */
+static void __init
+create_mapping(unsigned long *mem_ptr, struct map_desc *md)
+{
+ unsigned long virt, length;
+ int prot_sect, prot_pte;
+ long off;
+
+ prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ (md->prot_read ? L_PTE_USER : 0) |
+ (md->prot_write ? L_PTE_WRITE : 0) |
+ (md->cacheable ? L_PTE_CACHEABLE : 0) |
+ (md->bufferable ? L_PTE_BUFFERABLE : 0);
+
+ prot_sect = PMD_TYPE_SECT | PMD_DOMAIN(md->domain) |
+ (md->prot_read ? PMD_SECT_AP_READ : 0) |
+ (md->prot_write ? PMD_SECT_AP_WRITE : 0) |
+ (md->cacheable ? PMD_SECT_CACHEABLE : 0) |
+ (md->bufferable ? PMD_SECT_BUFFERABLE : 0);
+
+ virt = md->virtual;
+ off = md->physical - virt;
+ length = md->length;
+
+ while ((virt & 1048575 || (virt + off) & 1048575) && length >= PAGE_SIZE) {
+ alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte);
+
+ virt += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+
+ while (length >= PGDIR_SIZE) {
+ alloc_init_section(virt, virt + off, prot_sect);
+
+ virt += PGDIR_SIZE;
+ length -= PGDIR_SIZE;
+ }
+
+ while (length >= PAGE_SIZE) {
+ alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte);
+
+ virt += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+}
+
+/*
+ * Initial boot-time mapping. This covers just the
+ * zero page, kernel and the flush area. NB: it
+ * must be sorted by virtual address, and no
+ * virtual address overlaps.
+ * init_map[2..4] are for architectures with small
+ * amounts of banked memory.
+ */
+static struct map_desc init_map[] __initdata = {
+ { 0, 0, PAGE_SIZE, DOMAIN_USER, 0, 0, 1, 0 }, /* zero page */
+ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */
+ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
+ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
+ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
+ { 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */
+ { 0, 0, 0, DOMAIN_KERNEL, 1, 0, 1, 0 } /* cache flush 2 */
};
-#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
+#define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0]))
-unsigned long __init setup_io_pagetables(unsigned long start_mem)
+unsigned long __init
+setup_page_tables(unsigned long start_mem, unsigned long end_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 ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
- | L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
-
- 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;
+ unsigned long address = 0;
+ int idx = 0;
+
+ /*
+ * Correct the above mappings
+ */
+ init_map[0].physical =
+ init_map[1].physical = __virt_to_phys(PAGE_OFFSET);
+ init_map[1].virtual = PAGE_OFFSET;
+ init_map[1].length = end_mem - PAGE_OFFSET;
+ init_map[5].physical = FLUSH_BASE_PHYS;
+ init_map[5].virtual = FLUSH_BASE;
+#ifdef FLUSH_BASE_MINICACHE
+ init_map[6].physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
+ init_map[6].virtual = FLUSH_BASE_MINICACHE;
+ init_map[6].length = PGDIR_SIZE;
+#endif
+
+ /*
+ * Firstly, go through the initial mappings,
+ * but clear out any pgdir entries that are
+ * not in the description.
+ */
+ do {
+ if (address < init_map[idx].virtual || idx == NR_INIT_MAPS) {
+ free_init_section(address);
+ address += PGDIR_SIZE;
+ } else {
+ create_mapping(&start_mem, init_map + idx);
+
+ address = init_map[idx].virtual + init_map[idx].length;
+ address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
+
+ do {
+ idx += 1;
+ } while (init_map[idx].length == 0 && idx < NR_INIT_MAPS);
}
+ } while (address != 0);
+
+ /*
+ * Now, create the architecture specific mappings
+ */
+ for (idx = 0; idx < io_desc_size; idx++)
+ create_mapping(&start_mem, io_desc + idx);
+
+ flush_cache_all();
+
+ return start_mem;
+}
+
+/*
+ * The mem_map array can get very big. Mark the end of the
+ * valid mem_map banks with PG_skip, and setup the address
+ * validity bitmap.
+ */
+unsigned long __init
+create_mem_holes(unsigned long start_mem, unsigned long end_mem)
+{
+ struct page *pg = NULL;
+ unsigned int sz, i;
- prot = (mp->prot_read ? PMD_SECT_AP_READ : 0) |
- (mp->prot_write ? PMD_SECT_AP_WRITE : 0);
+ if (!machine_is_riscpc())
+ return start_mem;
- while (length >= 1048576) {
- alloc_init_section(&start_mem, virtual, physical, mp->domain, prot);
- length -= 1048576;
- virtual += 1048576;
- physical += 1048576;
+ sz = (end_mem - PAGE_OFFSET) >> 20;
+ sz = (sz + 31) >> 3;
+
+ valid_addr_bitmap = (unsigned long *)start_mem;
+ start_mem += sz;
+
+ memset(valid_addr_bitmap, 0, sz);
+
+ if (start_mem > mem_desc[0].virt_end)
+ printk(KERN_CRIT "*** Error: RAM bank 0 too small\n");
+
+ for (i = 0; i < mem_desc_size; i++) {
+ unsigned int idx, end;
+
+ if (pg) {
+ pg->next_hash = mem_map +
+ MAP_NR(mem_desc[i].virt_start);
+ pg = NULL;
}
- prot = (mp->prot_read ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
- | L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
+ idx = __kern_valid_idx(mem_desc[i].virt_start);
+ end = __kern_valid_idx(mem_desc[i].virt_end);
+
+ do
+ set_bit(idx, valid_addr_bitmap);
+ while (++idx < end);
+
+ if (mem_desc[i].virt_end < end_mem) {
+ pg = mem_map + MAP_NR(mem_desc[i].virt_end);
- while (length >= PAGE_SIZE) {
- alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
- length -= PAGE_SIZE;
- virtual += PAGE_SIZE;
- physical += PAGE_SIZE;
+ set_bit(PG_skip, &pg->flags);
}
}
+ if (pg)
+ pg->next_hash = NULL;
+
return start_mem;
}
+
+void __init
+mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem)
+{
+ /*
+ * Mark all of memory from the end of kernel to end of memory
+ */
+ while (start_mem < end_mem) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ start_mem += PAGE_SIZE;
+ }
+
+ /*
+ * Mark memory from page 1 to start of the swapper page directory
+ */
+ start_mem = PAGE_OFFSET + PAGE_SIZE;
+ while (start_mem < (unsigned long)&swapper_pg_dir) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ start_mem += PAGE_SIZE;
+ }
+}
diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c
index a85302473..8086bbc08 100644
--- a/arch/arm/mm/mm-ebsa110.c
+++ b/arch/arm/mm/mm-ebsa110.c
@@ -3,19 +3,27 @@
*
* Extra MM routines for the EBSA-110 architecture
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998-1999 Russell King
*/
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <asm/pgtable.h>
#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
+
+#include "map.h"
-#define MAPPING \
- { IO_BASE - PGDIR_SIZE , 0xc0000000 , PGDIR_SIZE , DOMAIN_IO, 0, 1 }, \
- { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1 }
+struct mem_desc mem_desc[] __initdata = {
+ 0, 0
+};
+
+unsigned int __initdata mem_desc_size = 0;
+
+const struct map_desc io_desc[] __initdata = {
+ { IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }
+};
+
+#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-#include "mm-armv.c"
+unsigned int __initdata io_desc_size = SIZEOFMAP;
diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c
index ec7e64c90..74bac27ea 100644
--- a/arch/arm/mm/mm-footbridge.c
+++ b/arch/arm/mm/mm-footbridge.c
@@ -1,9 +1,9 @@
/*
- * arch/arm/mm/mm-ebsa285.c
+ * arch/arm/mm/mm-footbridge.c
*
* Extra MM routines for the EBSA285 architecture
*
- * Copyright (C) 1998 Russell King, Dave Gilbert.
+ * Copyright (C) 1998-1999 Russell King, Dave Gilbert.
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -13,9 +13,10 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/io.h>
-#include <asm/proc/mm-init.h>
#include <asm/dec21285.h>
+#include "map.h"
+
/*
* The first entry allows us to fiddle with the EEPROM from user-space.
* This entry will go away in time, once the fmu32 can mmap() the
@@ -32,15 +33,15 @@
* The mapping when the footbridge is in host mode.
*/
#define MAPPING \
- { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1 }, \
- { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1 }, \
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1 }, \
- { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1 }
+ { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
#else
@@ -79,13 +80,26 @@ unsigned long __bus_to_virt(unsigned long res)
* The mapping when the footbridge is in add-in mode.
*/
#define MAPPING \
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1 }, \
- { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1 }, \
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1 }, \
- { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1 }, \
- { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1 }, \
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1 }
+ { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
+ { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
#endif
-#include "mm-armv.c"
+struct mem_desc mem_desc[] __initdata = {
+ 0, 0
+};
+
+unsigned int __initdata mem_desc_size = 0;
+
+struct map_desc io_desc[] __initdata = {
+ MAPPING
+};
+
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+unsigned int __initdata io_desc_size = SIZE(io_desc);
+
diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c
index a7407c130..a4ee48f8d 100644
--- a/arch/arm/mm/mm-nexuspci.c
+++ b/arch/arm/mm/mm-nexuspci.c
@@ -5,7 +5,7 @@
* Extra MM routines for the NexusPCI architecture
*
* Copyright (C) 1998 Phil Blundell
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998-1999 Russell King
*/
#include <linux/sched.h>
@@ -15,13 +15,23 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/io.h>
-#include <asm/proc/mm-init.h>
+
+#include "map.h"
-#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 }
+struct mem_desc mem_desc[] __initdata = {
+ 0, 0
+};
+
+unsigned int __initdata mem_desc_size = 0;
+
+const struct map_desc io_desc[] __initdata = {
+ { 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffe00000, 0x20000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffc00000, 0x60000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xfe000000, 0x80000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }
+};
+
+#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-#include "mm-armv.c"
+unsigned int __initdata io_desc_size = SIZEOFMAP;
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 80f821245..634bb3c8f 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -3,95 +3,48 @@
*
* Extra MM routines for RiscPC architecture
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998-1999 Russell King
*/
-#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
-#include <asm/pgtable.h>
+#include <asm/hardware.h>
+#include <asm/page.h>
+#include <asm/proc/domain.h>
#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
-#include <asm/arch/mm-init.h>
-#define NR_DRAM_BANKS 4
-#define NR_VRAM_BANKS 1
+#include "map.h"
-#define NR_BANKS (NR_DRAM_BANKS + NR_VRAM_BANKS)
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-#define FIRST_BANK 0
-#define FIRST_DRAM_BANK 0
-#define FIRST_VRAM_BANK NR_DRAM_BANKS
-
-#define BANK_SHIFT 26
-#define FIRST_DRAM_ADDR 0x10000000
-
-#define PHYS_TO_BANK(x) (((x) >> BANK_SHIFT) & (NR_DRAM_BANKS - 1))
-#define BANK_TO_PHYS(x) ((FIRST_DRAM_ADDR) + \
- (((x) - FIRST_DRAM_BANK) << BANK_SHIFT))
-
-struct ram_bank {
- unsigned int virt_addr; /* virtual address of the *end* of this bank + 1 */
- signed int phys_offset; /* offset to physical address of this bank */
+struct mem_desc mem_desc[] __initdata = {
+ { 0xc0000000, 0xc0000000 },
+ { 0xc4000000, 0xc4000000 },
+ { 0xc8000000, 0xc8000000 },
+ { 0xcc000000, 0xcc000000 }
};
-static struct ram_bank rambank[NR_BANKS];
-
-/*
- * Return the physical (0x10000000 -> 0x20000000) address of
- * the virtual (0xc0000000 -> 0xd0000000) address
- */
-unsigned long __virt_to_phys(unsigned long vpage)
-{
- unsigned int bank = FIRST_BANK;
-
- while (vpage >= rambank[bank].virt_addr && bank < NR_BANKS)
- bank ++;
-
- return vpage - rambank[bank].phys_offset;
-}
-
-/*
- * Return the virtual (0xc0000000 -> 0xd0000000) address of
- * the physical (0x10000000 -> 0x20000000) address
- */
-unsigned long __phys_to_virt(unsigned long phys)
-{
- unsigned int bank;
-
- if (phys > FIRST_DRAM_ADDR)
- bank = PHYS_TO_BANK(phys);
- else
- bank = FIRST_VRAM_BANK;
-
- return phys + rambank[bank].phys_offset;
-}
+unsigned int __initdata mem_desc_size = SIZE(mem_desc);
void __init
init_dram_banks(struct param_struct *params)
{
unsigned int bank;
- unsigned int bytes = 0;
- for (bank = FIRST_DRAM_BANK; bank < NR_DRAM_BANKS; bank++) {
- rambank[bank].phys_offset = PAGE_OFFSET + bytes
- - BANK_TO_PHYS(bank);
+ for (bank = 0; bank < mem_desc_size; bank++)
+ mem_desc[bank].virt_end += PAGE_SIZE *
+ params->u1.s.pages_in_bank[bank];
- bytes += params->u1.s.pages_in_bank[bank - FIRST_DRAM_BANK] * PAGE_SIZE;
-
- rambank[bank].virt_addr = PAGE_OFFSET + bytes;
- }
-
- rambank[FIRST_VRAM_BANK].phys_offset = 0xd6000000;
- rambank[FIRST_VRAM_BANK].virt_addr = 0xd8000000;
+ params->u1.s.nr_pages = mem_desc[3].virt_end - PAGE_OFFSET;
+ params->u1.s.nr_pages /= PAGE_SIZE;
}
-#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 */ \
- { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1 } /* EASI space */
-/*
- * Include common routine to set up page tables
- */
-#include "mm-armv.c"
+struct map_desc io_desc[] __initdata = {
+ /* VRAM */
+ { SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 },
+ /* IO space */
+ { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
+ /* EASI space */
+ { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
+};
+
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
new file mode 100644
index 000000000..eba2984b6
--- /dev/null
+++ b/arch/arm/mm/mm-sa1100.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mm/mm-sa1100.c
+ *
+ * Extra MM routines for the SA1100 architecture
+ *
+ * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1999 Hugo Fiennes
+ *
+ * 1999/09/12 Nicolas Pitre <nico@visuaide.com>
+ * Specific RAM implementation details are in
+ * linux/include/asm/arch-sa1100/memory.h now.
+ * Allows for better macro optimisations when possible.
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include "map.h"
+
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+/*
+ * These are the memory size mappings for the
+ * SA1100. Note that LART is a special case -
+ * it doesn't use physical address A23 on the
+ * DRAM, so we effectively have 4 * 8MB in
+ * two banks.
+ */
+struct mem_desc mem_desc[] __initdata = {
+ /* virt start virt end */
+#if defined(CONFIG_SA1100_BRUTUS)
+ { 0xc0000000, 0xc0400000 }, /* 4MB */
+ { 0xc1000000, 0xc1400000 }, /* 4MB */
+ { 0xc2000000, 0xc2400000 }, /* 4MB */
+ { 0xc3000000, 0xc3400000 } /* 4MB */
+#elif defined(CONFIG_SA1100_EMPEG)
+ { 0xc0000000, 0xc0400000 }, /* 4MB */
+ { 0xc1000000, 0xc1400000 } /* 4MB */
+#elif defined(CONFIG_SA1100_LART)
+ { 0xc0000000, 0xc0800000 }, /* 16MB */
+ { 0xc1000000, 0xc1800000 },
+ { 0xc2000000, 0xc2800000 }, /* 16MB */
+ { 0xc3000000, 0xc3800000 }
+#elif defined(CONFIG_SA1100_VICTOR)
+ { 0xc0000000, 0xc0400000 } /* 4MB */
+#elif defined(CONFIG_SA1100_TIFON)
+ { 0xc0000000, 0xc1000000 }, /* 16MB */
+ { 0xc1000000, 0xc2000000 } /* 16MB */
+#else
+#error missing memory configuration
+#endif
+};
+
+unsigned int __initdata mem_desc_size = SIZE(mem_desc);
+
+struct map_desc io_desc[] __initdata = {
+ /* virtual physical length domain r w c b */
+#if defined(CONFIG_SA1100_VICTOR)
+ { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+#elif defined(CONFIG_SA1100_EMPEG)
+ { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+#elif defined(CONFIG_SA1100_TIFON)
+ { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */
+#endif
+#ifdef CONFIG_SA1101
+ { 0xdc000000, SA1101_BASE, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1101 */
+#endif
+ { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */
+ { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */
+ { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 attr */
+ { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 attr */
+ { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 mem */
+ { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 mem */
+ { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */
+ { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */
+ { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */
+ { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */
+};
+
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c
index 2cc5cc9e1..a6dd2a28f 100644
--- a/arch/arm/mm/mm-tbox.c
+++ b/arch/arm/mm/mm-tbox.c
@@ -5,7 +5,7 @@
* Extra MM routines for the Tbox architecture
*
* Copyright (C) 1998 Phil Blundell
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998-1999 Russell King
*/
#include <linux/sched.h>
@@ -15,9 +15,15 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
-#include <asm/proc/mm-init.h>
-
+
+#include "map.h"
+struct mem_desc mem_desc[] __initdata = {
+ 0, 0
+};
+
+unsigned int __initdata mem_desc_size = 0;
+
/* Logical Physical
* 0xffff1000 0x00100000 DMA registers
* 0xffff2000 0x00200000 MPEG
@@ -34,23 +40,26 @@
* 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"
+
+const struct map_desc io_desc[] __initdata = {
+ { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }
+};
+
+#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
+
+unsigned int __initdata io_desc_size = SIZEOFMAP;
diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index 6ec34b612..df2e13357 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -12,349 +12,184 @@
#include "../lib/constants.h"
/*
- * Code common to all processors - MEMC specific not processor
- * specific!
+ * MEMC workhorse code. It's both a horse which things it's a pig.
*/
-
-LC1: .word SYMBOL_NAME(page_nr)
-/*
- * Function: arm2_3_update_map (struct task_struct *tsk)
- *
- * Params : tsk Task structure to be updated
- *
- * Purpose : Re-generate memc maps for task from its pseudo page tables
- */
-_arm2_3_update_map:
- mov ip, sp
- stmfd sp!, {r4 - r6, fp, ip, lr, pc}
- sub fp, ip, #4
- add r1, r0, #TSS_MEMCMAP
- ldr r2, LC1
- ldr r2, [r2]
- mov r3, #0x03f00000
- orr r3, r3, #0x00000f00
- orr r4, r3, #1
- orr r5, r3, #2
- orr r6, r3, #3
-1: stmia r1!, {r3, r4, r5, r6} @ Default mapping (null mapping)
- add r3, r3, #4
- add r4, r4, #4
- add r5, r5, #4
- add r6, r6, #4
- stmia r1!, {r3, r4, r5, r6} @ Default mapping (null mapping)
- add r3, r3, #4
- add r4, r4, #4
- add r5, r5, #4
- add r6, r6, #4
- subs r2, r2, #8
- bhi 1b
-
- adr r2, Lphystomemc32 @ r2 = conversion table to logical page number
- ldr r4, [r0, #TSS_MEMMAP] @ r4 = active mem map
- add r5, r4, #32 << 2 @ r5 = end of active mem map
- add r0, r0, #TSS_MEMCMAP @ r0 = memc map
-
- mov r6, #0
-2: ldmia r4!, {r1, r3}
- tst r1, #PAGE_PRESENT
- blne update_map_pgd
- add r6, r6, #32 << 2
- tst r3, #PAGE_PRESENT
- blne update_map_pgd3
- add r6, r6, #32 << 2
- cmp r4, r5
- blt 2b
- ldmea fp, {r4 - r6, fp, sp, pc}^
-
-@ r0,r2,r3,r4,r5 = preserve
-@ r1,ip = available
-@ r0 = memc map
-@ r1 = pgd entry
-@ r2 = conversion table
-@ r6 = logical page no << 2
-
-update_map_pgd3:
- mov r1, r3
-update_map_pgd: stmfd sp!, {r3, r4, r5, lr}
- bic r4, r1, #3 @ r4 = page table
- sub r5, r6, #1 << 2
- add ip, r4, #32 << 2 @ ip = end of page table
-
-1: ldr r1, [r4], #4 @ get entry
- add r5, r5, #1 << 2
- tst r1, #PAGE_PRESENT @ page present?
- blne Lconvertmemc @ yes
- ldr r1, [r4], #4 @ get entry
- add r5, r5, #1 << 2
- tst r1, #PAGE_PRESENT @ page present?
- blne Lconvertmemc @ yes
- ldr r1, [r4], #4 @ get entry
- add r5, r5, #1 << 2
- tst r1, #PAGE_PRESENT @ page present?
- blne Lconvertmemc @ yes
- ldr r1, [r4], #4 @ get entry
- add r5, r5, #1 << 2
- tst r1, #PAGE_PRESENT @ page present?
- blne Lconvertmemc @ yes
- cmp r4, ip
- blt 1b
- ldmfd sp!, {r3, r4, r5, pc}^
-
-Lconvertmemc: mov r3, r1, lsr #13 @
- and r3, r3, #0x3fc @ Convert to memc physical page no
- ldr r3, [r2, r3] @
-
- tst r1, #PAGE_OLD|PAGE_NOT_USER @ check for MEMC read
- biceq r3, r3, #0x200 @
- tsteq r1, #PAGE_READONLY|PAGE_CLEAN @ check for MEMC write
- biceq r3, r3, #0x300 @
-
- orr r3, r3, r5, lsl #13
- and r1, r5, #0x01800000 >> 13
- orr r3, r3, r1
-
- and r1, r3, #255
- str r3, [r0, r1, lsl #2]
- movs pc, lr
-
/*
- * Function: arm2_3_update_cache (struct task_struct *tsk, unsigned long addr, pte_t pte)
- * Params : tsk Task to update
- * address Address of fault.
- * pte New PTE at address
- * Purpose : Update the mapping for this address.
- * Notes : does the ARM3 run faster if you do not use the result in the next instruction?
+ * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
+ * Params : pgd Page tables/MEMC mapping
+ * : phys_pte physical address, or PTE
+ * : addr virtual address
*/
-_arm2_3_update_cache:
- tst r2, #PAGE_PRESENT
- moveqs pc, lr
- mov r3, r2, lsr #13 @ Physical page no.
- adr ip, Lphystomemc32 @ Convert to logical page number
+ENTRY(cpu_memc_update_entry)
+ tst r1, #PAGE_PRESENT @ is the page present
+ orreq r1, r1, #PAGE_OLD | PAGE_CLEAN
+ moveq r2, #0x01f00000
+ mov r3, r1, lsr #13 @ convert to physical page nr
and r3, r3, #0x3fc
- mov r1, r1, lsr #15
- ldr r3, [ip, r3] @ Convert to memc phys page no.
- tst r2, #PAGE_OLD|PAGE_NOT_USER
+ adr ip, memc_phys_table_32
+ ldr r3, [ip, r3]
+ tst r1, #PAGE_OLD | PAGE_NOT_USER
biceq r3, r3, #0x200
- tsteq r2, #PAGE_READONLY|PAGE_CLEAN
+ tsteq r1, #PAGE_READONLY | PAGE_CLEAN
biceq r3, r3, #0x300
- mov ip, sp, lsr #13
- orr r3, r3, r1, lsl #15
- mov ip, ip, lsl #13
- and r1, r1, #0x300
- teq ip, r0
- orr r3, r3, r1, lsl #2
- add r0, r0, #TSS_MEMCMAP
+ mov r2, r2, lsr #15 @ virtual -> nr
+ orr r3, r3, r2, lsl #15
+ and r2, r2, #0x300
+ orr r3, r3, r2, lsl #2
and r2, r3, #255
- streqb r3, [r3]
+ sub r0, r0, #256 * 4
str r3, [r0, r2, lsl #2]
- movs pc, lr
-
-#define PCD(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \
- .long a0| 0x03800300; .long a1| 0x03800300;\
- .long a2| 0x03800300; .long a3| 0x03800300;\
- .long a4| 0x03800300; .long a5| 0x03800300;\
- .long a6| 0x03800300; .long a7| 0x03800300;\
- .long a8| 0x03800300; .long a9| 0x03800300;\
- .long aa| 0x03800300; .long ab| 0x03800300;\
- .long ac| 0x03800300; .long ad| 0x03800300;\
- .long ae| 0x03800300; .long af| 0x03800300
-
-@ Table to map from page number to vidc page number
-Lphystomemc32: PCD(0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78)
- PCD(0x01,0x09,0x11,0x19,0x21,0x29,0x31,0x39,0x41,0x49,0x51,0x59,0x61,0x69,0x71,0x79)
- PCD(0x04,0x0C,0x14,0x1C,0x24,0x2C,0x34,0x3C,0x44,0x4C,0x54,0x5C,0x64,0x6C,0x74,0x7C)
- PCD(0x05,0x0D,0x15,0x1D,0x25,0x2D,0x35,0x3D,0x45,0x4D,0x55,0x5D,0x65,0x6D,0x75,0x7D)
- PCD(0x02,0x0A,0x12,0x1A,0x22,0x2A,0x32,0x3A,0x42,0x4A,0x52,0x5A,0x62,0x6A,0x72,0x7A)
- PCD(0x03,0x0B,0x13,0x1B,0x23,0x2B,0x33,0x3B,0x43,0x4B,0x53,0x5B,0x63,0x6B,0x73,0x7B)
- PCD(0x06,0x0E,0x16,0x1E,0x26,0x2E,0x36,0x3E,0x46,0x4E,0x56,0x5E,0x66,0x6E,0x76,0x7E)
- PCD(0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,0x3F,0x47,0x4F,0x57,0x5F,0x67,0x6F,0x77,0x7F)
- PCD(0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8)
- PCD(0x81,0x89,0x91,0x99,0xA1,0xA9,0xB1,0xB9,0xC1,0xC9,0xD1,0xD9,0xE1,0xE9,0xF1,0xF9)
- PCD(0x84,0x8C,0x94,0x9C,0xA4,0xAC,0xB4,0xBC,0xC4,0xCC,0xD4,0xDC,0xE4,0xEC,0xF4,0xFC)
- PCD(0x85,0x8D,0x95,0x9D,0xA5,0xAD,0xB5,0xBD,0xC5,0xCD,0xD5,0xDD,0xE5,0xED,0xF5,0xFD)
- PCD(0x82,0x8A,0x92,0x9A,0xA2,0xAA,0xB2,0xBA,0xC2,0xCA,0xD2,0xDA,0xE2,0xEA,0xF2,0xFA)
- PCD(0x83,0x8B,0x93,0x9B,0xA3,0xAB,0xB3,0xBB,0xC3,0xCB,0xD3,0xDB,0xE3,0xEB,0xF3,0xFB)
- PCD(0x86,0x8E,0x96,0x9E,0xA6,0xAE,0xB6,0xBE,0xC6,0xCE,0xD6,0xDE,0xE6,0xEE,0xF6,0xFE)
- PCD(0x87,0x8F,0x97,0x9F,0xA7,0xAF,0xB7,0xBF,0xC7,0xCF,0xD7,0xDF,0xE7,0xEF,0xF7,0xFF)
-
+ strb r3, [r3]
+ movs pc, lr
/*
- * Function: arm2_3_data_abort ()
- *
- * Params : r0 = address of aborted instruction
- *
- * Purpose :
- *
- * Returns : r0 = address of abort
- * : r1 = FSR
- * : r2 != 0 if writing
+ * Params : r0 = preserved
+ * : r1 = memc table base (preserved)
+ * : r2 = page table entry
+ * : r3 = preserved
+ * : r4 = unused
+ * : r5 = memc physical address translation table
+ * : ip = virtual address (preserved)
*/
-
-_arm2_3_data_abort:
+update_pte:
+ mov r4, r2, lsr #13
+ and r4, r4, #0x3fc
+ ldr r4, [r5, r4] @ covert to MEMC page
+
+ tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read
+ biceq r4, r4, #0x200
+ tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
+ biceq r4, r4, #0x300
+
+ orr r4, r4, ip
+ and r2, ip, #0x01800000
+ orr r4, r4, r2, lsr #13
+
+ and r2, r4, #255
+ str r4, [r1, r2, lsl #2]
movs pc, lr
-_arm2_3_check_bugs:
- bics pc, lr, #0x04000000 @ Clear FIQ disable bit
-
/*
- * Processor specific - ARM2
+ * Params : r0 = preserved
+ * : r1 = memc table base (preserved)
+ * : r2 = page table base
+ * : r3 = preserved
+ * : r4 = unused
+ * : r5 = memc physical address translation table
+ * : ip = virtual address (updated)
*/
+update_pte_table:
+ stmfd sp!, {r0, lr}
+ bic r0, r2, #3
+1: ldr r2, [r0], #4 @ get entry
+ tst r2, #PAGE_PRESENT @ page present
+ blne update_pte @ process pte
+ add ip, ip, #32768 @ increment virt addr
+ ldr r2, [r0], #4 @ get entry
+ tst r2, #PAGE_PRESENT @ page present
+ blne update_pte @ process pte
+ add ip, ip, #32768 @ increment virt addr
+ ldr r2, [r0], #4 @ get entry
+ tst r2, #PAGE_PRESENT @ page present
+ blne update_pte @ process pte
+ add ip, ip, #32768 @ increment virt addr
+ ldr r2, [r0], #4 @ get entry
+ tst r2, #PAGE_PRESENT @ page present
+ blne update_pte @ process pte
+ add ip, ip, #32768 @ increment virt addr
+ tst ip, #32768 * 31 @ finished?
+ bne 1b
+ ldmfd sp!, {r0, pc}^
-LC0: .word SYMBOL_NAME(page_nr)
/*
- * Function: arm2_switch_to (struct task_struct *prev, struct task_struct *next)
- * Params : prev Old task structure
- * : next New task structure for process to run
- * Returns : prev
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- * the new.
- * Notes : We don't fiddle with the FP registers here - we postpone this until
- * the new task actually uses FP. This way, we don't swap FP for tasks
- * that do not require it.
+ * Function: cpu_memc_update_all(pgd_t *pgd)
+ * Params : pgd Page tables/MEMC mapping
+ * Notes : this is optimised for 32k pages
*/
-_arm2_switch_to:
- stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- mov r4, r1
- add r7, r1, #TSS_MEMCMAP @ Remap MEMC
- ldr r1, LC0
- ldr r1, [r1]
-1: ldmia r7!, {r2, r3, r5, r6}
- strb r2, [r2]
- strb r3, [r3]
- strb r5, [r5]
- strb r6, [r6]
- ldmia r7!, {r2, r3, r5, r6}
- strb r2, [r2]
- strb r3, [r3]
- strb r5, [r5]
- strb r6, [r6]
- subs r1, r1, #8
- bhi 1b
- ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
+ENTRY(cpu_memc_update_all)
+ stmfd sp!, {r4, r5, lr}
+ bl clear_tables
+ sub r1, r0, #256 * 4 @ start of MEMC tables
+ adr r5, memc_phys_table_32 @ Convert to logical page number
+ mov ip, #0 @ virtual address
+1: ldmia r0!, {r2, r3}
+ tst r2, #PAGE_PRESENT
+ addeq ip, ip, #1048576
+ blne update_pte_table
+ mov r2, r3
+ tst r2, #PAGE_PRESENT
+ addeq ip, ip, #1048576
+ blne update_pte_table
+ teq ip, #32 * 1048576
+ bne 1b
+ ldmfd sp!, {r4, r5, pc}^
/*
- * Function: arm2_remap_memc (struct task_struct *tsk)
- *
- * Params : tsk Task structure specifing the new mapping structure
- *
- * Purpose : remap MEMC tables
+ * Build the table to map from physical page number to memc page number
*/
-_arm2_remap_memc:
- stmfd sp!, {lr}
- add r0, r0, #TSS_MEMCMAP
- ldr r1, LC0
- ldr r1, [r1]
-1: ldmia r0!, {r2, r3, ip, lr}
- strb r2, [r2]
- strb r3, [r3]
- strb ip, [ip]
- strb lr, [lr]
- ldmia r0!, {r2, r3, ip, lr}
- strb r2, [r2]
- strb r3, [r3]
- strb ip, [ip]
- strb lr, [lr]
- subs r1, r1, #8
- bhi 1b
- ldmfd sp!, {pc}^
+ .type memc_phys_table_32, #object
+memc_phys_table_32:
+ .irp b7, 0x00, 0x80
+ .irp b6, 0x00, 0x02
+ .irp b5, 0x00, 0x04
+ .irp b4, 0x00, 0x01
+
+ .irp b3, 0x00, 0x40
+ .irp b2, 0x00, 0x20
+ .irp b1, 0x00, 0x10
+ .irp b0, 0x00, 0x08
+ .long 0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
+ .endr
+ .endr
+ .endr
+ .endr
+
+ .endr
+ .endr
+ .endr
+ .endr
+ .size memc_phys_table_32, . - memc_phys_table_32
/*
- * Function: arm2_xchg_1 (int new, volatile void *ptr)
- *
- * Params : new New value to store at...
- * : ptr pointer to byte-wide location
- *
- * Purpose : Performs an exchange operation
- *
- * Returns : Original byte data at 'ptr'
- *
- * Notes : This will have to be changed if we ever use multi-processing using these
- * processors, but that is very unlikely...
+ * helper for cpu_memc_update_all, this clears out all
+ * mappings, setting them close to the top of memory,
+ * and inaccessible (0x01f00000).
+ * Params : r0 = page table pointer
*/
-_arm2_xchg_1: mov r2, pc
- orr r2, r2, #I_BIT
- teqp r2, #0
- ldrb r2, [r1]
- strb r0, [r1]
- mov r0, r2
- movs pc, lr
+clear_tables: ldr r1, _arm3_set_pgd - 4
+ ldr r2, [r1]
+ sub r1, r0, #256 * 4 @ start of MEMC tables
+ add r2, r1, r2, lsl #2 @ end of tables
+ mov r3, #0x03f00000 @ Default mapping (null mapping)
+ orr r3, r3, #0x00000f00
+ orr r4, r3, #1
+ orr r5, r3, #2
+ orr ip, r3, #3
+1: stmia r1!, {r3, r4, r5, ip}
+ add r3, r3, #4
+ add r4, r4, #4
+ add r5, r5, #4
+ add ip, ip, #4
+ stmia r1!, {r3, r4, r5, ip}
+ add r3, r3, #4
+ add r4, r4, #4
+ add r5, r5, #4
+ add ip, ip, #4
+ teq r1, r2
+ bne 1b
+ mov pc, lr
/*
- * Function: arm2_xchg_4 (int new, volatile void *ptr)
- *
- * Params : new New value to store at...
- * : ptr pointer to word-wide location
- *
- * Purpose : Performs an exchange operation
- *
- * Returns : Original word data at 'ptr'
- *
- * Notes : This will have to be changed if we ever use multi-processing using these
- * processors, but that is very unlikely...
+ * Function: *_set_pgd(pgd_t *pgd)
+ * Params : pgd New page tables/MEMC mapping
+ * Purpose : update MEMC hardware with new mapping
*/
-_arm2_xchg_4: mov r2, pc
- orr r2, r2, #I_BIT
- teqp r2, #0
+ .word SYMBOL_NAME(page_nr)
+_arm3_set_pgd: mcr p15, 0, r1, c1, c0, 0 @ flush cache
+_arm2_set_pgd: stmfd sp!, {lr}
+ ldr r1, _arm3_set_pgd - 4
ldr r2, [r1]
- str r0, [r1]
- mov r0, r2
-/*
- * fall through
- */
-/*
- * Function: arm2_proc_init (void)
- * : arm2_proc_fin (void)
- *
- * Purpose : Initialise / finalise processor specifics (none required)
- */
-_arm2_proc_init:
-_arm2_proc_fin: movs pc, lr
-/*
- * Function: arm3_switch_to (struct task_struct *prev, struct task_struct *next)
- * Params : prev Old task structure
- * : next New task structure for process to run
- * Returns : prev
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- * the new.
- * Notes : We don't fiddle with the FP registers here - we postpone this until
- * the new task actually uses FP. This way, we don't swap FP for tasks
- * that do not require it.
- */
-_arm3_switch_to:
- stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- mov r4, r1
- add r7, r1, #TSS_MEMCMAP @ Remap MEMC
- ldr r1, LC0
- ldr r1, [r1]
-1: ldmia r7!, {r2, r3, r5, r6}
- strb r2, [r2]
- strb r3, [r3]
- strb r5, [r5]
- strb r6, [r6]
- ldmia r7!, {r2, r3, r5, r6}
- strb r2, [r2]
- strb r3, [r3]
- strb r5, [r5]
- strb r6, [r6]
- subs r1, r1, #8
- bhi 1b
- mcr p15, 0, r7, c1, c0, 0 @ flush cache
- ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
-/*
- * Function: arm3_remap_memc (struct task_struct *tsk)
- *
- * Params : tsk Task structure specifing the new mapping structure
- *
- * Purpose : remap MEMC tables
- */
-_arm3_remap_memc:
- stmfd sp!, {lr}
- add r0, r0, #TSS_MEMCMAP
- ldr r1, LC0
- ldr r1, [r1]
+ sub r0, r0, #256 * 4 @ start of MEMC tables
+ add r1, r0, r2, lsl #2 @ end of tables
1: ldmia r0!, {r2, r3, ip, lr}
strb r2, [r2]
strb r3, [r3]
@@ -365,14 +200,12 @@ _arm3_remap_memc:
strb r3, [r3]
strb ip, [ip]
strb lr, [lr]
- subs r1, r1, #8
- bhi 1b
- mcr p15, 0, r0, c1, c0, 0 @ flush cache
+ teq r0, r1
+ bne 1b
ldmfd sp!, {pc}^
/*
- * Function: arm3_proc_init (void)
- *
+ * Function: *_proc_init (void)
* Purpose : Initialise the cache control registers
*/
_arm3_proc_init:
@@ -386,43 +219,55 @@ _arm3_proc_init:
mcr p15, 0, r0, c1, c0 @ ARM3 Flush
mov r0, #3
mcr p15, 0, r0, c2, c0 @ ARM3 Control
+_arm2_proc_init:
movs pc, lr
/*
- * Function: arm3_proc_fin (void)
- *
+ * Function: *_proc_fin (void)
* Purpose : Finalise processor (disable caches)
*/
_arm3_proc_fin: mov r0, #2
mcr p15, 0, r0, c2, c0
- movs pc, lr
+_arm2_proc_fin: orrs pc, lr, #I_BIT|F_BIT
/*
- * Function: arm3_xchg_1 (int new, volatile void *ptr)
- *
+ * Function: *_xchg_1 (int new, volatile void *ptr)
* Params : new New value to store at...
* : ptr pointer to byte-wide location
- *
* Purpose : Performs an exchange operation
- *
* Returns : Original byte data at 'ptr'
*/
+_arm2_xchg_1: mov r2, pc
+ orr r2, r2, #I_BIT
+ teqp r2, #0
+ ldrb r2, [r1]
+ strb r0, [r1]
+ mov r0, r2
+ movs pc, lr
+
_arm3_xchg_1: swpb r0, r0, [r1]
movs pc, lr
/*
- * Function: arm3_xchg_4 (int new, volatile void *ptr)
- *
+ * Function: *_xchg_4 (int new, volatile void *ptr)
* Params : new New value to store at...
* : ptr pointer to word-wide location
- *
* Purpose : Performs an exchange operation
- *
* Returns : Original word data at 'ptr'
*/
+_arm2_xchg_4: mov r2, pc
+ orr r2, r2, #I_BIT
+ teqp r2, #0
+ ldr r2, [r1]
+ str r0, [r1]
+ mov r0, r2
+ movs pc, lr
+
_arm3_xchg_4: swp r0, r0, [r1]
movs pc, lr
+_arm2_3_check_bugs:
+ bics pc, lr, #0x04000000 @ Clear FIQ disable bit
armvlsi_name: .asciz "ARM/VLSI"
_arm2_name: .asciz "arm2"
@@ -436,57 +281,42 @@ _arm3_name: .asciz "arm3"
*/
.globl SYMBOL_NAME(arm2_processor_functions)
SYMBOL_NAME(arm2_processor_functions):
- .word _arm2_switch_to @ 4
- .word _arm2_3_data_abort @ 8
- .word _arm2_3_check_bugs @ 12
- .word _arm2_proc_init @ 16
- .word _arm2_proc_fin @ 20
-
- .word _arm2_remap_memc @ 24
- .word _arm2_3_update_map @ 28
- .word _arm2_3_update_cache @ 32
- .word _arm2_xchg_1 @ 36
- .word SYMBOL_NAME(abort) @ 40
- .word _arm2_xchg_4 @ 44
-
- .globl SYMBOL_NAME(arm250_processor_functions)
-SYMBOL_NAME(arm250_processor_functions):
- .word _arm2_switch_to @ 4
- .word _arm2_3_data_abort @ 8
- .word _arm2_3_check_bugs @ 12
- .word _arm2_proc_init @ 16
- .word _arm2_proc_fin @ 20
-
- .word _arm2_remap_memc @ 24
- .word _arm2_3_update_map @ 28
- .word _arm2_3_update_cache @ 32
- .word _arm3_xchg_1 @ 36
- .word SYMBOL_NAME(abort) @ 40
- .word _arm3_xchg_4 @ 44
-
- .globl SYMBOL_NAME(arm3_processor_functions)
-SYMBOL_NAME(arm3_processor_functions):
- .word _arm3_switch_to @ 4
- .word _arm2_3_data_abort @ 8
- .word _arm2_3_check_bugs @ 12
- .word _arm3_proc_init @ 16
- .word _arm3_proc_fin @ 20
-
- .word _arm3_remap_memc @ 24
- .word _arm2_3_update_map @ 28
- .word _arm2_3_update_cache @ 32
- .word _arm3_xchg_1 @ 36
- .word SYMBOL_NAME(abort) @ 40
- .word _arm3_xchg_4 @ 44
+ .word _arm2_3_check_bugs
+ .word _arm2_proc_init
+ .word _arm2_proc_fin
+ .word _arm2_set_pgd
+ .word _arm2_xchg_1
+ .word SYMBOL_NAME(abort)
+ .word _arm2_xchg_4
cpu_arm2_info:
.long armvlsi_name
.long _arm2_name
+ .globl SYMBOL_NAME(arm250_processor_functions)
+SYMBOL_NAME(arm250_processor_functions):
+ .word _arm2_3_check_bugs
+ .word _arm2_proc_init
+ .word _arm2_proc_fin
+ .word _arm2_set_pgd
+ .word _arm3_xchg_1
+ .word SYMBOL_NAME(abort)
+ .word _arm3_xchg_4
+
cpu_arm250_info:
.long armvlsi_name
.long _arm250_name
+ .globl SYMBOL_NAME(arm3_processor_functions)
+SYMBOL_NAME(arm3_processor_functions):
+ .word _arm2_3_check_bugs
+ .word _arm3_proc_init
+ .word _arm3_proc_fin
+ .word _arm3_set_pgd
+ .word _arm3_xchg_1
+ .word SYMBOL_NAME(abort)
+ .word _arm3_xchg_4
+
cpu_arm3_info:
.long armvlsi_name
.long _arm3_name
@@ -501,6 +331,8 @@ arm3_elf_name: .asciz "v2"
.long 0x41560200
.long 0xfffffff0
+ .long 0
+ mov pc, lr
.long arm2_arch_name
.long arm2_elf_name
.long 0
@@ -509,6 +341,8 @@ arm3_elf_name: .asciz "v2"
.long 0x41560250
.long 0xfffffff0
+ .long 0
+ mov pc, lr
.long arm3_arch_name
.long arm3_elf_name
.long 0
@@ -517,6 +351,8 @@ arm3_elf_name: .asciz "v2"
.long 0x41560300
.long 0xfffffff0
+ .long 0
+ mov pc, lr
.long arm3_arch_name
.long arm3_elf_name
.long 0
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index 67fb0aa8b..f3819fa01 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -9,6 +9,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/procinfo.h>
+#include <asm/errno.h>
#include "../lib/constants.h"
/*
@@ -70,6 +71,19 @@ ENTRY(cpu_arm7_flush_tlb_area)
mov pc, lr
/*
+ * Function: arm6_7_flush_tlb_page (unsigned long address, int flags)
+ *
+ * Params : address Address
+ * : flags b0 = I-TLB as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm6_flush_tlb_page)
+ENTRY(cpu_arm7_flush_tlb_page)
+ mcr p15, 0, r0, c6, c0, 0 @ flush TLB
+ mov pc, lr
+
+/*
* Function: arm6_7_data_abort ()
*
* Params : r0 = address of aborted instruction
@@ -89,6 +103,16 @@ msg: .ascii "DA*%p=%p\n\0"
.align
ENTRY(cpu_arm6_data_abort)
+Ldata_simple:
+ ldr r4, [r0] @ read instruction causing problem
+ mov r2, r4, lsr #19 @ r2 b1 = L
+ and r2, r2, #2 @ check read/write bit
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ and r1, r1, #15
+ mov pc, lr
+
+ENTRY(cpu_arm7_data_abort)
ldr r4, [r0] @ read instruction causing problem
mov r2, r4, lsr #19 @ r2 b1 = L
and r1, r4, #15 << 24
@@ -98,10 +122,10 @@ ENTRY(cpu_arm6_data_abort)
b Ldata_unknown
b Ldata_unknown
b Ldata_unknown
- b Ldata_earlyldrpost @ ldr rd, [rn], #m
- b Ldata_simple @ ldr rd, [rn, #m] @ RegVal
- b Ldata_earlyldrpost @ ldr rd, [rn], rm
- b Ldata_simple @ ldr rd, [rn, rm]
+ b Ldata_lateldrpostconst @ ldr rd, [rn], #m
+ b Ldata_lateldrpreconst @ ldr rd, [rn, #m] @ RegVal
+ b Ldata_lateldrpostreg @ ldr rd, [rn], rm
+ b Ldata_lateldrprereg @ ldr rd, [rn, rm]
b Ldata_ldmstm @ ldm*a rn, <rlist>
b Ldata_ldmstm @ ldm*b rn, <rlist>
b Ldata_unknown
@@ -119,29 +143,6 @@ Ldata_unknown: @ Part of jumptable
bl SYMBOL_NAME(panic)
Lstop: b Lstop
-ENTRY(cpu_arm7_data_abort)
- ldr r4, [r0] @ read instruction causing problem
- mov r2, r4, lsr #19 @ r2 b1 = L
- and r1, r4, #15 << 24
- add pc, pc, r1, lsr #22 @ Now branch to the relevent processing routine
- movs pc, lr
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_lateldrpostconst @ ldr rd, [rn], #m
- b Ldata_lateldrpreconst @ ldr rd, [rn, #m] @ RegVal
- b Ldata_lateldrpostreg @ ldr rd, [rn], rm
- b Ldata_lateldrprereg @ ldr rd, [rn, rm]
- b Ldata_ldmstm @ ldm*a rn, <rlist>
- b Ldata_ldmstm @ ldm*b rn, <rlist>
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_simple @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
- b Ldata_simple @ ldc rd, [rn, #m]
- b Ldata_unknown
- b Ldata_unknown
-
Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
beq Ldata_simple
@@ -165,31 +166,16 @@ Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
add r7, r0, r7, lsl #2 @ Do correction (signed)
str r7, [sp, r5, lsr #14] @ Put register
-Ldata_simple: and r2, r2, #2 @ check read/write bit
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mrc p15, 0, r1, c5, c0, 0 @ get FSR
- and r1, r1, #15
- mov pc, lr
-
-Ldata_earlyldrpost:
- tst r2, #4
- and r2, r2, #2 @ check read/write bit
- orrne r2, r2, #1 @ T bit
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mrc p15, 0, r1, c5, c0, 0 @ get FSR
- and r1, r1, #15
- mov pc, lr
-
Ldata_lateldrpostconst:
movs r1, r4, lsl #20 @ Get offset
- beq Ldata_earlyldrpost @ if offset is zero, no effect
+ beq Ldata_simple @ if offset is zero, no effect
and r5, r4, #15 << 16 @ Get Rn
ldr r0, [sp, r5, lsr #14]
tst r4, #1 << 23 @ U bit
subne r0, r0, r1, lsr #20
addeq r0, r0, r1, lsr #20
str r0, [sp, r5, lsr #14] @ Put register
- b Ldata_earlyldrpost
+ b Ldata_simple
Ldata_lateldrpreconst:
tst r4, #1 << 21 @ check writeback bit
@@ -252,7 +238,7 @@ Ldata_lateldrpostreg:
subne r0, r0, r1
addeq r0, r0, r1
str r0, [sp, r5, lsr #14] @ Put register
- b Ldata_earlyldrpost
+ b Ldata_simple
Ldata_lateldrprereg:
tst r4, #1 << 21 @ check writeback bit
@@ -319,10 +305,24 @@ ENTRY(cpu_arm7_check_bugs)
mrs ip, cpsr
bic ip, ip, #F_BIT
msr cpsr, ip
+ mov pc, lr
+
ENTRY(cpu_arm6_proc_init)
ENTRY(cpu_arm7_proc_init)
+ mov pc, lr
+
ENTRY(cpu_arm6_proc_fin)
ENTRY(cpu_arm7_proc_fin)
+ mrs r0, cpsr
+ orr r0, r0, #F_BIT | I_BIT
+ msr cpsr, r0
+ mov r0, #0x31 @ ....S..DP...M
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+ENTRY(cpu_arm6_do_idle)
+ENTRY(cpu_arm7_do_idle)
+ mov r0, #-EINVAL
mov pc, lr
/*
@@ -381,23 +381,22 @@ ENTRY(cpu_arm6_set_pte)
ENTRY(cpu_arm7_set_pte)
str r1, [r0], #-1024 @ linux version
+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
bic r2, r1, #0xff0
bic r2, r2, #3
orr r2, r2, #HPTE_TYPE_SMALL
- tst r1, #LPTE_USER | LPTE_EXEC
+ tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
orrne r2, r2, #HPTE_AP_READ
- tst r1, #LPTE_WRITE
- tstne r1, #LPTE_DIRTY
- orrne r2, r2, #HPTE_AP_WRITE
+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+ orreq r2, r2, #HPTE_AP_WRITE
- tst r1, #LPTE_PRESENT
- tstne r1, #LPTE_YOUNG
- moveq r2, #0
+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young
+ movne r2, #0
str r2, [r0] @ hardware version
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
mov pc, lr
/*
@@ -407,13 +406,9 @@ ENTRY(cpu_arm7_set_pte)
*/
ENTRY(cpu_arm6_reset)
ENTRY(cpu_arm7_reset)
- mrs r1, cpsr
- orr r1, r1, #F_BIT|I_BIT
- msr cpsr, r1
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ flush cache
mcr p15, 0, r0, c5, c0, 0 @ flush TLB
- mov r1, #F_BIT | I_BIT | 3
mov pc, lr
cpu_armvlsi_name:
@@ -428,6 +423,26 @@ cpu_arm710_name:
.section ".text.init", #alloc, #execinstr
+__arm6_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mov r0, #0x3d @ ....S..DPWC.M
+ orr r0, r0, #0x100
+ mov pc, lr
+
+__arm7_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mov r0, #0x7d @ ....S.LDPWC.M
+ orr r0, r0, #0x100
+ mov pc, lr
+
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
@@ -452,6 +467,8 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_flush_icache_area
.word cpu_arm6_cache_wback_area
.word cpu_arm6_cache_purge_area
+ .word cpu_arm6_flush_tlb_page
+ .word cpu_arm7_do_idle
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -478,6 +495,8 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_flush_icache_area
.word cpu_arm7_cache_wback_area
.word cpu_arm7_cache_purge_area
+ .word cpu_arm7_flush_tlb_page
+ .word cpu_arm7_do_idle
.size arm7_processor_functions, . - arm7_processor_functions
.type cpu_arm6_info, #object
@@ -519,9 +538,11 @@ cpu_elf_name: .asciz "v3"
__arm6_proc_info:
.long 0x41560600
.long 0xfffffff0
+ .long 0x00000c12
+ b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP
+ .long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm6_info
.long arm6_processor_functions
.size __arm6_proc_info, . - __arm6_proc_info
@@ -530,9 +551,11 @@ __arm6_proc_info:
__arm610_proc_info:
.long 0x41560610
.long 0xfffffff0
+ .long 0x00000c12
+ b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP
+ .long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm610_info
.long arm6_processor_functions
.size __arm610_proc_info, . - __arm610_proc_info
@@ -541,9 +564,11 @@ __arm610_proc_info:
__arm7_proc_info:
.long 0x41007000
.long 0xffffff00
+ .long 0x00000c12
+ b __arm7_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP
+ .long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm7_info
.long arm7_processor_functions
.size __arm7_proc_info, . - __arm7_proc_info
@@ -552,9 +577,11 @@ __arm7_proc_info:
__arm710_proc_info:
.long 0x41007100
.long 0xfff8ff00
+ .long 0x00000c12
+ b __arm7_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP
+ .long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm710_info
.long arm7_processor_functions
.size __arm710_proc_info, . - __arm710_proc_info
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index aecc223af..73c0f83df 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -4,7 +4,7 @@
* (C) 1997-1999 Russell King
*
* These are the low level assembler for performing cache and TLB
- * functions on the sa110.
+ * functions on the StrongARM-110 and StrongARM-1100
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -17,6 +17,27 @@
*/
#define MAX_AREA_SIZE 32768
+ .macro flush_110_dcache rd, ra, re
+ add \re, \ra, #16384 @ only necessary for 16k
+1001: ldr \rd, [\ra], #32
+ teq \re, \ra
+ bne 1001b
+ .endm
+
+ .macro flush_1100_dcache rd, ra, re
+ add \re, \ra, #8192 @ only necessary for 8k
+1001: ldr \rd, [\ra], #32
+ teq \re, \ra
+ bne 1001b
+#ifdef FLUSH_BASE_MINICACHE
+ add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
+ add \re, \ra, #512 @ only 512 bytes
+1002: ldr \rd, [\ra], #32
+ teq \re, \ra
+ bne 1002b
+#endif
+ .endm
+
.data
Lclean_switch: .long 0
.text
@@ -36,12 +57,27 @@ cpu_sa110_flush_cache_all_r2:
eor r1, r1, #1
str r1, [r3]
addne ip, ip, #32768
- add r1, ip, #16384 @ only necessary for 16k
-1: ldr r3, [ip], #32
- teq r1, ip
- bne 1b
+ flush_110_dcache r3, ip, r1
+ mov ip, #0
+ teq r2, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+ENTRY(cpu_sa1100_flush_cache_all) @ preserves r0
+ mov r2, #1
+cpu_sa1100_flush_cache_all_r2:
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r1, [r3]
+ ands r1, r1, #1
+ eor r1, r1, #1
+ str r1, [r3]
+ addne ip, ip, #32768
+ flush_1100_dcache r3, ip, r1
mov ip, #0
- tst r2, #1
+ teq r2, #0
mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov pc, lr
@@ -66,11 +102,17 @@ ENTRY(cpu_sa110_flush_cache_area)
add r0, r0, #32
cmp r0, r1
blt 1b
- tst r2, #1
+ teq r2, #0
movne r0, #0
mcrne p15, 0, r0, c7, c5, 0 @ flush I cache
mov pc, lr
+ENTRY(cpu_sa1100_flush_cache_area)
+ sub r3, r1, r0
+ cmp r3, #MAX_AREA_SIZE
+ bgt cpu_sa1100_flush_cache_all_r2
+ b 1b
+
/*
* Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
* Params : address Area start address
@@ -94,6 +136,13 @@ ENTRY(cpu_sa110_cache_wback_area)
mcr p15, 0, r2, c7, c10, 4 @ drain WB
mov pc, lr
+ENTRY(cpu_sa1100_cache_wback_area)
+ sub r3, r1, r0
+ cmp r3, #MAX_AREA_SIZE
+ mov r2, #0
+ bgt cpu_sa1100_flush_cache_all_r2
+ bic r0, r0, #31
+ b 1b
/*
* Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
* Params : address Area start address
@@ -105,6 +154,7 @@ ENTRY(cpu_sa110_cache_wback_area)
*/
.align 5
ENTRY(cpu_sa110_cache_purge_area)
+ENTRY(cpu_sa1100_cache_purge_area)
tst r0, #31
bic r0, r0, #31
mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -123,6 +173,7 @@ ENTRY(cpu_sa110_cache_purge_area)
*/
.align 5
ENTRY(cpu_sa110_flush_cache_entry)
+ENTRY(cpu_sa1100_flush_cache_entry)
mov r1, #0
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r1, c7, c10, 4 @ drain WB
@@ -136,6 +187,7 @@ ENTRY(cpu_sa110_flush_cache_entry)
* for page table purposes.
*/
ENTRY(cpu_sa110_clean_cache_area)
+ENTRY(cpu_sa1100_clean_cache_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
add r0, r0, #32
subs r1, r1, #32
@@ -149,6 +201,7 @@ ENTRY(cpu_sa110_clean_cache_area)
*/
.align 5
ENTRY(cpu_sa110_flush_ram_page)
+ENTRY(cpu_sa1100_flush_ram_page)
mov r1, #4096
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #32
@@ -170,6 +223,7 @@ ENTRY(cpu_sa110_flush_ram_page)
*/
.align 5
ENTRY(cpu_sa110_flush_tlb_all)
+ENTRY(cpu_sa1100_flush_tlb_all)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c8, c7, 0 @ flush I & D tlbs
@@ -184,6 +238,7 @@ ENTRY(cpu_sa110_flush_tlb_all)
*/
.align 5
ENTRY(cpu_sa110_flush_tlb_area)
+ENTRY(cpu_sa1100_flush_tlb_area)
mov r3, #0
mcr p15, 0, r3, c7, c10, 4 @ drain WB
1: cmp r0, r1
@@ -193,12 +248,35 @@ ENTRY(cpu_sa110_flush_tlb_area)
mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry
addlt r0, r0, #4096
blt 1b
- tst r2, #1
+ teq r2, #0
mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB
mov pc, lr
+/*
+ * Function: sa110_flush_tlb_page (unsigned long address, int flags)
+ * Params : address Address to flush
+ * : flags b0 = I-TLB as well
+ * Purpose : flush a TLB entry
+ */
+ .align 5
+ENTRY(cpu_sa110_flush_tlb_page)
+ENTRY(cpu_sa1100_flush_tlb_page)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c8, c6, 1 @ flush D TLB entry
+ teq r1, #0
+ mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB
+ mov pc, lr
+
+/*
+ * Function: sa110_flush_icache_area (unsigned long address, unsigned long size)
+ * Params : address Address of area to flush
+ * : size Size of area to flush
+ * Purpose : flush an area from the Icache
+ */
.align 5
ENTRY(cpu_sa110_flush_icache_area)
+ENTRY(cpu_sa1100_flush_icache_area)
1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
add r0, r0, #32
subs r1, r1, #32
@@ -218,6 +296,7 @@ ENTRY(cpu_sa110_flush_icache_area)
*/
.align 5
ENTRY(cpu_sa110_data_abort)
+ENTRY(cpu_sa1100_data_abort)
ldr r2, [r0] @ read instruction causing problem
mrc p15, 0, r0, c6, c0, 0 @ get FAR
mov r2, r2, lsr #19 @ b1 = L
@@ -237,16 +316,30 @@ ENTRY(cpu_sa110_data_abort)
.align 5
ENTRY(cpu_sa110_set_pgd)
ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
ldr r2, [r3]
ands r2, r2, #1
eor r2, r2, #1
str r2, [r3]
- ldr r2, =FLUSH_BASE
- addne r2, r2, #32768
- add r1, r2, #16384 @ only necessary for 16k
-1: ldr r3, [r2], #32
- teq r1, r2
- bne 1b
+ addne ip, ip, #32768
+ flush_110_dcache r3, ip, r1
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
+ mov pc, lr
+
+ .align 5
+ENTRY(cpu_sa1100_set_pgd)
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r2, [r3]
+ ands r2, r2, #1
+ eor r2, r2, #1
+ str r2, [r3]
+ addne ip, ip, #32768
+ flush_1100_dcache r3, ip, r1
mov r1, #0
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
mcr p15, 0, r1, c7, c10, 4 @ drain WB
@@ -262,9 +355,10 @@ ENTRY(cpu_sa110_set_pgd)
*/
.align 5
ENTRY(cpu_sa110_set_pmd)
+ENTRY(cpu_sa1100_set_pmd)
str r1, [r0]
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c10, 4 @ drain WB (TLB bypasses WB)
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
/*
@@ -275,6 +369,7 @@ ENTRY(cpu_sa110_set_pmd)
*/
.align 5
ENTRY(cpu_sa110_set_pte)
+ENTRY(cpu_sa1100_set_pte)
str r1, [r0], #-1024 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
@@ -294,8 +389,8 @@ ENTRY(cpu_sa110_set_pte)
str r2, [r0] @ hardware version
mov r0, r0
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
- mcr p15, 0, r0, c7, c10, 4 @ drain WB (TLB bypasses WB)
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
/*
@@ -305,12 +400,39 @@ ENTRY(cpu_sa110_set_pte)
* Notes : This processor does not require these
*/
ENTRY(cpu_sa110_check_bugs)
+ENTRY(cpu_sa1100_check_bugs)
mrs ip, cpsr
bic ip, ip, #F_BIT
msr cpsr, ip
+ mov pc, lr
ENTRY(cpu_sa110_proc_init)
+ENTRY(cpu_sa1100_proc_init)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
+ mov pc, lr
+
ENTRY(cpu_sa110_proc_fin)
+ENTRY(cpu_sa1100_proc_fin)
+ mrs r0, cpsr
+ orr r0, r0, #F_BIT | I_BIT
+ msr cpsr, r0
+ mov r0, #0
+ mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x1100 @ ...i...s........
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+ .align 5
+ENTRY(cpu_sa110_do_idle)
+ENTRY(cpu_sa1100_do_idle)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
+ @ load from uncacheable loc?
+ mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt
+ mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
mov pc, lr
/*
@@ -318,17 +440,13 @@ ENTRY(cpu_sa110_proc_fin)
* Notes : This sets up everything for a reset
*/
ENTRY(cpu_sa110_reset)
- mrs r1, cpsr
- orr r1, r1, #F_BIT | I_BIT
- msr cpsr, r1
+ENTRY(cpu_sa1100_reset)
stmfd sp!, {r1, lr}
- mov r2, #1
bl cpu_sa110_flush_cache_all
bl cpu_sa110_flush_tlb_all
mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
- bic r0, r0, #0x1800
- bic r0, r0, #0x000f
+ bic r0, r0, #1 @ ...............m
ldmfd sp!, {r1, pc}
/*
* Purpose : Function pointers used to access above functions - all calls
@@ -338,10 +456,26 @@ ENTRY(cpu_sa110_reset)
cpu_manu_name: .asciz "Intel"
ENTRY(cpu_sa110_name)
.asciz "sa110"
+ENTRY(cpu_sa1100_name)
+ .asciz "sa1100"
.align
.section ".text.init", #alloc, #execinstr
+__sa110_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+ mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, #0x0e00 @ ....??r.........
+ bic r0, r0, #0x0002 @ ..............a.
+ orr r0, r0, #0x003d @ ..........DPWC.M
+ orr r0, r0, #0x1100 @ ...I...S........
+ mov pc, lr
+
.type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.word cpu_sa110_data_abort
@@ -362,7 +496,8 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_flush_icache_area
.word cpu_sa110_cache_wback_area
.word cpu_sa110_cache_purge_area
-
+ .word cpu_sa110_flush_tlb_page
+ .word cpu_sa110_do_idle
.size sa110_processor_functions, . - sa110_processor_functions
.type cpu_sa110_info, #object
@@ -371,6 +506,36 @@ cpu_sa110_info:
.long cpu_sa110_name
.size cpu_sa110_info, . - cpu_sa110_info
+
+ .type sa1100_processor_functions, #object
+ENTRY(sa1100_processor_functions)
+ .word cpu_sa1100_data_abort
+ .word cpu_sa1100_check_bugs
+ .word cpu_sa1100_proc_init
+ .word cpu_sa1100_proc_fin
+ .word cpu_sa1100_flush_cache_all
+ .word cpu_sa1100_flush_cache_area
+ .word cpu_sa1100_flush_cache_entry
+ .word cpu_sa1100_clean_cache_area
+ .word cpu_sa1100_flush_ram_page
+ .word cpu_sa1100_flush_tlb_all
+ .word cpu_sa1100_flush_tlb_area
+ .word cpu_sa1100_set_pgd
+ .word cpu_sa1100_set_pmd
+ .word cpu_sa1100_set_pte
+ .word cpu_sa1100_reset
+ .word cpu_sa1100_flush_icache_area
+ .word cpu_sa1100_cache_wback_area
+ .word cpu_sa1100_cache_purge_area
+ .word cpu_sa1100_flush_tlb_page
+ .word cpu_sa1100_do_idle
+ .size sa1100_processor_functions, . - sa1100_processor_functions
+
+cpu_sa1100_info:
+ .long cpu_manu_name
+ .long cpu_sa1100_name
+ .size cpu_sa1100_info, . - cpu_sa1100_info
+
.type cpu_arch_name, #object
cpu_arch_name: .asciz "armv4"
.size cpu_arch_name, . - cpu_arch_name
@@ -385,9 +550,26 @@ cpu_elf_name: .asciz "v4"
__sa110_proc_info:
.long 0x4401a100
.long 0xfffffff0
+ .long 0x00000c02
+ b __sa110_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
.long cpu_sa110_info
.long sa110_processor_functions
.size __sa110_proc_info, . - __sa110_proc_info
+
+ .type __sa1100_proc_info,#object
+__sa1100_proc_info:
+ .long 0x4401a110
+ .long 0xfffffff0
+ .long 0x00000c02
+ b __sa110_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_sa1100_info
+ .long sa1100_processor_functions
+ .size __sa1100_proc_info, . - __sa1100_proc_info
+
+
diff --git a/arch/arm/nwfpe/ChangeLog b/arch/arm/nwfpe/ChangeLog
index e160d36c3..8d76e09ba 100644
--- a/arch/arm/nwfpe/ChangeLog
+++ b/arch/arm/nwfpe/ChangeLog
@@ -1,10 +1,50 @@
-1998-11-23 Scott Bambrough <scottb@corelcomputer.com>
+1999-08-19 Scott Bambrough <scottb@netwinder.org>
+
+ * fpmodule.c - Changed version number to 0.95
+ * fpa11.h - modified FPA11, FPREG structures
+ * fpa11.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cpdt.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cprt.c - Changes due to FPA11, FPREG structure alterations.
+ * single_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * double_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * extended_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+
+ * I discovered several bugs. First and worst is that the kernel
+ passes in a pointer to the FPE's state area. This is defined
+ as a struct user_fp (see user.h). This pointer was cast to a
+ FPA11*. Unfortunately FPA11 and user_fp are of different sizes;
+ user_fp is smaller. This meant that the FPE scribbled on things
+ below its area, which is bad, as the area is in the thread_struct
+ embedded in the process task structure. Thus we were scribbling
+ over one of the most important structures in the entire OS.
+
+ * user_fp and FPA11 have now been harmonized. Most of the changes
+ in the above code were dereferencing problems due to moving the
+ register type out of FPREG, and getting rid of the union variable
+ fpvalue.
+
+ * Second I noticed resetFPA11 was not always being called for a
+ task. This should happen on the first floating point exception
+ that occurs. It is controlled by init_flag in FPA11. The
+ comment in the code beside init_flag state the kernel guarantees
+ this to be zero. Not so. I found that the kernel recycles task
+ structures, and that recycled ones may not have init_flag zeroed.
+ I couldn't even find anything that guarantees it is zeroed when
+ when the task structure is initially allocated. In any case
+ I now initialize the entire FPE state in the thread structure to
+ zero when allocated and recycled. See alloc_task_struct() and
+ flush_thread() in arch/arm/process.c. The change to
+ alloc_task_struct() may not be necessary, but I left it in for
+ completeness (better safe than sorry).
+
+1998-11-23 Scott Bambrough <scottb@netwinder.org>
* README.FPE - fix typo in description of lfm/sfm instructions
* NOTES - Added file to describe known bugs/problems
* fpmodule.c - Changed version number to 0.94
-1998-11-20 Scott Bambrough <scottb@corelcomputer.com>
+1998-11-20 Scott Bambrough <scottb@netwinder.org>
* README.FPE - fix description of URD, NRM instructions
* TODO - remove URD, NRM instructions from TODO list
@@ -12,7 +52,7 @@
* double_cpdo.c - implement URD, NRM
* extended_cpdo.c - implement URD, NRM
-1998-11-19 Scott Bambrough <scottb@corelcomputer.com>
+1998-11-19 Scott Bambrough <scottb@netwinder.org>
* ChangeLog - Added this file to track changes made.
* fpa11.c - added code to initialize register types to typeNone
diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
index 5db79c6d4..a14371e5d 100644
--- a/arch/arm/nwfpe/Makefile
+++ b/arch/arm/nwfpe/Makefile
@@ -14,16 +14,15 @@ else
NWFPE_OBJS += entry.o
endif
-L_TARGET := math-emu.a
-
ifeq ($(CONFIG_NWFPE),y)
-L_OBJS = $(NWFPE_OBJS)
+O_TARGET := math-emu.o
+O_OBJS = $(NWFPE_OBJS)
else
ifeq ($(CONFIG_NWFPE),m)
M_OBJS = nwfpe.o
MI_OBJS = $(NWFPE_OBJS)
endif
-endif
+endif
include $(TOPDIR)/Rules.make
diff --git a/arch/arm/nwfpe/double_cpdo.c b/arch/arm/nwfpe/double_cpdo.c
index 3db9e7066..0415f31e0 100644
--- a/arch/arm/nwfpe/double_cpdo.c
+++ b/arch/arm/nwfpe/double_cpdo.c
@@ -19,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "softfloat.h"
#include "fpopcode.h"
#include "fpa11.h"
@@ -54,14 +53,14 @@ unsigned int DoubleCPDO(const unsigned int opcode)
}
else
{
- switch (fpa11->fpreg[Fm].fType)
+ switch (fpa11->fType[Fm])
{
case typeSingle:
- rFm = float32_to_float64(fpa11->fpreg[Fm].fValue.fSingle);
+ rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
break;
case typeDouble:
- rFm = fpa11->fpreg[Fm].fValue.fDouble;
+ rFm = fpa11->fpreg[Fm].fDouble;
break;
case typeExtended:
@@ -80,14 +79,14 @@ unsigned int DoubleCPDO(const unsigned int opcode)
if (!MONADIC_INSTRUCTION(opcode))
{
Fn = getFn(opcode);
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
- rFn = float32_to_float64(fpa11->fpreg[Fn].fValue.fSingle);
+ rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
break;
case typeDouble:
- rFn = fpa11->fpreg[Fn].fValue.fDouble;
+ rFn = fpa11->fpreg[Fn].fDouble;
break;
default: return 0;
@@ -100,62 +99,62 @@ unsigned int DoubleCPDO(const unsigned int opcode)
{
/* dyadic opcodes */
case ADF_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_add(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
break;
case MUF_CODE:
case FML_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_mul(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
break;
- case SUF_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_sub(rFn,rFm);
+ case SUF_CODE:
+ fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
break;
case RSF_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_sub(rFm,rFn);
+ fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
break;
case DVF_CODE:
case FDV_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_div(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
break;
case RDF_CODE:
case FRD_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_div(rFm,rFn);
+ fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
break;
#if 0
case POW_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_pow(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
break;
case RPW_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_pow(rFm,rFn);
+ fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
break;
#endif
case RMF_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_rem(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
break;
#if 0
case POL_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_pol(rFn,rFm);
+ fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
break;
#endif
/* monadic opcodes */
case MVF_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = rFm;
+ fpa11->fpreg[Fd].fDouble = rFm;
break;
case MNF_CODE:
{
unsigned int *p = (unsigned int*)&rFm;
p[1] ^= 0x80000000;
- fpa11->fpreg[Fd].fValue.fDouble = rFm;
+ fpa11->fpreg[Fd].fDouble = rFm;
}
break;
@@ -163,55 +162,55 @@ unsigned int DoubleCPDO(const unsigned int opcode)
{
unsigned int *p = (unsigned int*)&rFm;
p[1] &= 0x7fffffff;
- fpa11->fpreg[Fd].fValue.fDouble = rFm;
+ fpa11->fpreg[Fd].fDouble = rFm;
}
break;
case RND_CODE:
case URD_CODE:
- fpa11->fpreg[Fd].fValue.fDouble =
+ fpa11->fpreg[Fd].fDouble =
int32_to_float64(float64_to_int32(rFm));
break;
case SQT_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_sqrt(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
break;
#if 0
case LOG_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_log(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_log(rFm);
break;
case LGN_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_ln(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
break;
case EXP_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_exp(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
break;
case SIN_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_sin(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
break;
case COS_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_cos(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
break;
case TAN_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_tan(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
break;
case ASN_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_arcsin(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
break;
case ACS_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_arccos(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
break;
case ATN_CODE:
- fpa11->fpreg[Fd].fValue.fDouble = float64_arctan(rFm);
+ fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
break;
#endif
@@ -224,7 +223,7 @@ unsigned int DoubleCPDO(const unsigned int opcode)
}
}
- if (0 != nRc) fpa11->fpreg[Fd].fType = typeDouble;
+ if (0 != nRc) fpa11->fType[Fd] = typeDouble;
return nRc;
}
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 6f0077fbe..f6a9a9799 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -3,7 +3,7 @@
(c) Corel Computer Corporation, 1998
(c) Philip Blundell 1998-1999
- Direct questions, comments to Scott Bambrough <scottb@corelcomputer.com>
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,14 +85,15 @@ nwfpe_enter:
mov r10, lr @ save the failure-return addresses
ldr r5, [r4, #60] @ get contents of PC;
- ldr r0, [r5, #-4] @ get actual instruction into r0
+ sub r8, r5, #4
+.Lx2: ldrt r0, [r8], #0 @ get actual instruction into r0
emulate:
bl EmulateAll @ emulate the instruction
cmp r0, #0 @ was emulation successful
moveq pc, r10 @ no, return failure
next:
-__x1: ldrt r6, [r5], #4 @ get the next instruction and
+.Lx1: ldrt r6, [r5], #4 @ get the next instruction and
@ increment PC
and r2, r6, #0x0F000000 @ test for FP insns
@@ -114,13 +115,15 @@ __x1: ldrt r6, [r5], #4 @ get the next instruction and
mov r0, r6 @ prepare for EmulateAll()
b emulate @ if r0 != 0, goto EmulateAll
- @ We need to be prepared for the instruction at __x1 to fault.
- @ Emit the appropriate exception gunk to fix things up.
+ @ We need to be prepared for the instruction at .Lx1 or .Lx2
+ @ to fault.
.section .fixup,"ax"
.align
-__f1: mov pc, r9
+.Lfix: mov pc, r9
.previous
+
.section __ex_table,"a"
.align 3
- .long __x1, __f1
+ .long .Lx2, .Lfix
+ .long .Lx1, .Lfix
.previous
diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S
index 6b1ec3354..5108ce63d 100644
--- a/arch/arm/nwfpe/entry26.S
+++ b/arch/arm/nwfpe/entry26.S
@@ -3,7 +3,7 @@
(c) Corel Computer Corporation, 1998
(c) Philip Blundell 1998-1999
- Direct questions, comments to Scott Bambrough <scottb@corelcomputer.com>
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/arch/arm/nwfpe/extended_cpdo.c b/arch/arm/nwfpe/extended_cpdo.c
index 4f55333fc..810f57102 100644
--- a/arch/arm/nwfpe/extended_cpdo.c
+++ b/arch/arm/nwfpe/extended_cpdo.c
@@ -19,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "softfloat.h"
#include "fpopcode.h"
#include "fpa11.h"
@@ -52,18 +51,18 @@ unsigned int ExtendedCPDO(const unsigned int opcode)
}
else
{
- switch (fpa11->fpreg[Fm].fType)
+ switch (fpa11->fType[Fm])
{
case typeSingle:
- rFm = float32_to_floatx80(fpa11->fpreg[Fm].fValue.fSingle);
+ rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
break;
case typeDouble:
- rFm = float64_to_floatx80(fpa11->fpreg[Fm].fValue.fDouble);
+ rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
break;
case typeExtended:
- rFm = fpa11->fpreg[Fm].fValue.fExtended;
+ rFm = fpa11->fpreg[Fm].fExtended;
break;
default: return 0;
@@ -73,18 +72,18 @@ unsigned int ExtendedCPDO(const unsigned int opcode)
if (!MONADIC_INSTRUCTION(opcode))
{
Fn = getFn(opcode);
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
- rFn = float32_to_floatx80(fpa11->fpreg[Fn].fValue.fSingle);
+ rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
break;
case typeDouble:
- rFn = float64_to_floatx80(fpa11->fpreg[Fn].fValue.fDouble);
+ rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
break;
case typeExtended:
- rFn = fpa11->fpreg[Fn].fValue.fExtended;
+ rFn = fpa11->fpreg[Fn].fExtended;
break;
default: return 0;
@@ -96,112 +95,112 @@ unsigned int ExtendedCPDO(const unsigned int opcode)
{
/* dyadic opcodes */
case ADF_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_add(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
break;
case MUF_CODE:
case FML_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_mul(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
break;
case SUF_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_sub(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
break;
case RSF_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_sub(rFm,rFn);
+ fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
break;
case DVF_CODE:
case FDV_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_div(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
break;
case RDF_CODE:
case FRD_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_div(rFm,rFn);
+ fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
break;
#if 0
case POW_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_pow(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
break;
case RPW_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_pow(rFm,rFn);
+ fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
break;
#endif
case RMF_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_rem(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
break;
#if 0
case POL_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_pol(rFn,rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
break;
#endif
/* monadic opcodes */
case MVF_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = rFm;
+ fpa11->fpreg[Fd].fExtended = rFm;
break;
case MNF_CODE:
rFm.high ^= 0x8000;
- fpa11->fpreg[Fd].fValue.fExtended = rFm;
+ fpa11->fpreg[Fd].fExtended = rFm;
break;
case ABS_CODE:
rFm.high &= 0x7fff;
- fpa11->fpreg[Fd].fValue.fExtended = rFm;
+ fpa11->fpreg[Fd].fExtended = rFm;
break;
case RND_CODE:
case URD_CODE:
- fpa11->fpreg[Fd].fValue.fExtended =
+ fpa11->fpreg[Fd].fExtended =
int32_to_floatx80(floatx80_to_int32(rFm));
break;
case SQT_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_sqrt(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
break;
#if 0
case LOG_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_log(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
break;
case LGN_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_ln(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
break;
case EXP_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_exp(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
break;
case SIN_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_sin(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
break;
case COS_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_cos(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
break;
case TAN_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_tan(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
break;
case ASN_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_arcsin(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
break;
case ACS_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_arccos(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
break;
case ATN_CODE:
- fpa11->fpreg[Fd].fValue.fExtended = floatx80_arctan(rFm);
+ fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
break;
#endif
@@ -214,7 +213,7 @@ unsigned int ExtendedCPDO(const unsigned int opcode)
}
}
- if (0 != nRc) fpa11->fpreg[Fd].fType = typeExtended;
+ if (0 != nRc) fpa11->fType[Fd] = typeExtended;
return nRc;
}
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c
index 3e11d5ddd..dfc4663b7 100644
--- a/arch/arm/nwfpe/fpa11.c
+++ b/arch/arm/nwfpe/fpa11.c
@@ -19,9 +19,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <asm/system.h>
+
#include "fpa11.h"
-#include "milieu.h"
#include "fpopcode.h"
#include "fpmodule.h"
@@ -39,17 +39,18 @@ FPA11 *fpa11;
void resetFPA11(void)
{
int i;
- /* initialize the registers */
+
+ /* initialize the register type array */
for (i=0;i<=7;i++)
{
- fpa11->fpreg[i].fType = typeNone;
+ fpa11->fType[i] = typeNone;
}
/* FPSR: set system id to FP_EMULATOR, clear all other bits */
fpa11->fpsr = FP_EMULATOR;
/* FPCR: set SB, AB and DA bits, clear all others */
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr = MASK_RESET;
#endif
}
@@ -128,6 +129,9 @@ void SetRoundingPrecision(const unsigned int opcode)
unsigned int EmulateAll(unsigned int opcode)
{
unsigned int nRc = 0;
+ unsigned long flags;
+
+ save_flags(flags); sti();
if (fpa11->initflag == 0) /* good place for __builtin_expect */
{
@@ -162,6 +166,8 @@ unsigned int EmulateAll(unsigned int opcode)
nRc = 0;
}
+ restore_flags(flags);
+
return(nRc);
}
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index f7040dbb6..c55ac6f9b 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -31,25 +31,25 @@
#define typeDouble 0x02
#define typeExtended 0x03
-typedef struct tagFPREG {
- unsigned int fType;
- union {
- float32 fSingle;
- float64 fDouble;
- floatx80 fExtended;
- } fValue;
+typedef union tagFPREG {
+ float32 fSingle;
+ float64 fDouble;
+ floatx80 fExtended;
} FPREG;
/* FPA11 device model */
typedef struct tagFPA11 {
+ FPREG fpreg[8]; /* 8 floating point registers */
+ FPSR fpsr; /* floating point status register */
+ FPCR fpcr; /* floating point control register */
+ unsigned char fType[8]; /* type of floating point value held in
+ floating point registers. One of none
+ single, double or extended. */
int initflag; /* this is special. The kernel guarantees
to set it to 0 when a thread is launched,
so we can use it to detect whether this
instance of the emulator needs to be
initialised. */
- FPREG fpreg[8]; /* 8 floating point registers */
- FPSR fpsr; /* floating point status register */
- FPCR fpcr; /* floating point control register */
} FPA11;
extern void resetFPA11(void);
diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl
index 321ab7c1c..bc86317a2 100644
--- a/arch/arm/nwfpe/fpa11.inl
+++ b/arch/arm/nwfpe/fpa11.inl
@@ -2,7 +2,7 @@
NetWinder Floating Point Emulator
(c) Corel Computer Corporation, 1998
- Direct questions, comments to Scott Bambrough <scottb@corelcomputer.com>
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/arch/arm/nwfpe/fpa11_cpdo.c b/arch/arm/nwfpe/fpa11_cpdo.c
index 19dd08802..fd39a59f7 100644
--- a/arch/arm/nwfpe/fpa11_cpdo.c
+++ b/arch/arm/nwfpe/fpa11_cpdo.c
@@ -19,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "fpa11.h"
#include "fpopcode.h"
@@ -48,14 +47,14 @@ unsigned int EmulateCPDO(const unsigned int opcode)
if (MONADIC_INSTRUCTION(opcode))
nType = nDest;
else
- nType = fpa11->fpreg[getFn(opcode)].fType;
+ nType = fpa11->fType[getFn(opcode)];
if (!CONSTANT_FM(opcode))
{
register unsigned int Fm = getFm(opcode);
- if (nType < fpa11->fpreg[Fm].fType)
+ if (nType < fpa11->fType[Fm])
{
- nType = fpa11->fpreg[Fm].fType;
+ nType = fpa11->fType[Fm];
}
}
@@ -71,7 +70,7 @@ unsigned int EmulateCPDO(const unsigned int opcode)
destination register is the correct size. If not force it
to be. */
Fd = getFd(opcode);
- nType = fpa11->fpreg[Fd].fType;
+ nType = fpa11->fType[Fd];
if ((0 != nRc) && (nDest != nType))
{
switch (nDest)
@@ -79,38 +78,38 @@ unsigned int EmulateCPDO(const unsigned int opcode)
case typeSingle:
{
if (typeDouble == nType)
- fpa11->fpreg[Fd].fValue.fSingle =
- float64_to_float32(fpa11->fpreg[Fd].fValue.fDouble);
+ fpa11->fpreg[Fd].fSingle =
+ float64_to_float32(fpa11->fpreg[Fd].fDouble);
else
- fpa11->fpreg[Fd].fValue.fSingle =
- floatx80_to_float32(fpa11->fpreg[Fd].fValue.fExtended);
+ fpa11->fpreg[Fd].fSingle =
+ floatx80_to_float32(fpa11->fpreg[Fd].fExtended);
}
break;
case typeDouble:
{
if (typeSingle == nType)
- fpa11->fpreg[Fd].fValue.fDouble =
- float32_to_float64(fpa11->fpreg[Fd].fValue.fSingle);
+ fpa11->fpreg[Fd].fDouble =
+ float32_to_float64(fpa11->fpreg[Fd].fSingle);
else
- fpa11->fpreg[Fd].fValue.fDouble =
- floatx80_to_float64(fpa11->fpreg[Fd].fValue.fExtended);
+ fpa11->fpreg[Fd].fDouble =
+ floatx80_to_float64(fpa11->fpreg[Fd].fExtended);
}
break;
case typeExtended:
{
if (typeSingle == nType)
- fpa11->fpreg[Fd].fValue.fExtended =
- float32_to_floatx80(fpa11->fpreg[Fd].fValue.fSingle);
+ fpa11->fpreg[Fd].fExtended =
+ float32_to_floatx80(fpa11->fpreg[Fd].fSingle);
else
- fpa11->fpreg[Fd].fValue.fExtended =
- float64_to_floatx80(fpa11->fpreg[Fd].fValue.fDouble);
+ fpa11->fpreg[Fd].fExtended =
+ float64_to_floatx80(fpa11->fpreg[Fd].fDouble);
}
break;
}
- fpa11->fpreg[Fd].fType = nDest;
+ fpa11->fType[Fd] = nDest;
}
return nRc;
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
index e32bf3421..0bad18769 100644
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -20,7 +20,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "softfloat.h"
#include "fpopcode.h"
#include "fpa11.h"
@@ -32,16 +31,16 @@
extern __inline__
void loadSingle(const unsigned int Fn,const unsigned int *pMem)
{
- fpa11->fpreg[Fn].fType = typeSingle;
- get_user(fpa11->fpreg[Fn].fValue.fSingle, pMem);
+ fpa11->fType[Fn] = typeSingle;
+ get_user(fpa11->fpreg[Fn].fSingle, pMem);
}
extern __inline__
void loadDouble(const unsigned int Fn,const unsigned int *pMem)
{
unsigned int *p;
- p = (unsigned int*)&fpa11->fpreg[Fn].fValue.fDouble;
- fpa11->fpreg[Fn].fType = typeDouble;
+ p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
+ fpa11->fType[Fn] = typeDouble;
get_user(p[0], &pMem[1]);
get_user(p[1], &pMem[0]); /* sign & exponent */
}
@@ -50,8 +49,8 @@ extern __inline__
void loadExtended(const unsigned int Fn,const unsigned int *pMem)
{
unsigned int *p;
- p = (unsigned int*)&fpa11->fpreg[Fn].fValue.fExtended;
- fpa11->fpreg[Fn].fType = typeExtended;
+ p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
+ fpa11->fType[Fn] = typeExtended;
get_user(p[0], &pMem[0]); /* sign & exponent */
get_user(p[1], &pMem[2]); /* ls bits */
get_user(p[2], &pMem[1]); /* ms bits */
@@ -63,11 +62,11 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
register unsigned int *p;
unsigned long x;
- p = (unsigned int*)&(fpa11->fpreg[Fn].fValue);
+ p = (unsigned int*)&(fpa11->fpreg[Fn]);
get_user(x, &pMem[0]);
- fpa11->fpreg[Fn].fType = (x >> 14) & 0x00000003;
+ fpa11->fType[Fn] = (x >> 14) & 0x00000003;
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
case typeDouble:
@@ -94,17 +93,17 @@ void storeSingle(const unsigned int Fn,unsigned int *pMem)
float32 val;
register unsigned int *p = (unsigned int*)&val;
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeDouble:
- val = float64_to_float32(fpa11->fpreg[Fn].fValue.fDouble);
+ val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
break;
case typeExtended:
- val = floatx80_to_float32(fpa11->fpreg[Fn].fValue.fExtended);
+ val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
break;
- default: val = fpa11->fpreg[Fn].fValue.fSingle;
+ default: val = fpa11->fpreg[Fn].fSingle;
}
put_user(p[0], pMem);
@@ -116,17 +115,17 @@ void storeDouble(const unsigned int Fn,unsigned int *pMem)
float64 val;
register unsigned int *p = (unsigned int*)&val;
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
- val = float32_to_float64(fpa11->fpreg[Fn].fValue.fSingle);
+ val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
break;
case typeExtended:
- val = floatx80_to_float64(fpa11->fpreg[Fn].fValue.fExtended);
+ val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
break;
- default: val = fpa11->fpreg[Fn].fValue.fDouble;
+ default: val = fpa11->fpreg[Fn].fDouble;
}
put_user(p[1], &pMem[0]); /* msw */
put_user(p[0], &pMem[1]); /* lsw */
@@ -138,17 +137,17 @@ void storeExtended(const unsigned int Fn,unsigned int *pMem)
floatx80 val;
register unsigned int *p = (unsigned int*)&val;
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
- val = float32_to_floatx80(fpa11->fpreg[Fn].fValue.fSingle);
+ val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
break;
case typeDouble:
- val = float64_to_floatx80(fpa11->fpreg[Fn].fValue.fDouble);
+ val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
break;
- default: val = fpa11->fpreg[Fn].fValue.fExtended;
+ default: val = fpa11->fpreg[Fn].fExtended;
}
put_user(p[0], &pMem[0]); /* sign & exp */
@@ -161,8 +160,8 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem)
{
register unsigned int nType, *p;
- p = (unsigned int*)&(fpa11->fpreg[Fn].fValue);
- nType = fpa11->fpreg[Fn].fType;
+ p = (unsigned int*)&(fpa11->fpreg[Fn]);
+ nType = fpa11->fType[Fn];
switch (nType)
{
@@ -187,12 +186,17 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem)
unsigned int PerformLDF(const unsigned int opcode)
{
- unsigned int *pBase, *pAddress, *pFinal, nRc = 1;
-
+ unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+ write_back = WRITE_BACK(opcode);
+
//fp_printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
pBase = (unsigned int*)readRegister(getRn(opcode));
- if (REG_PC == getRn(opcode)) pBase += 2;
+ if (REG_PC == getRn(opcode))
+ {
+ pBase += 2;
+ write_back = 0;
+ }
pFinal = pBase;
if (BIT_UP_SET(opcode))
@@ -210,19 +214,24 @@ unsigned int PerformLDF(const unsigned int opcode)
default: nRc = 0;
}
- if (WRITE_BACK(opcode)) writeRegister(getRn(opcode),(unsigned int)pFinal);
+ if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return nRc;
}
unsigned int PerformSTF(const unsigned int opcode)
{
- unsigned int *pBase, *pAddress, *pFinal, nRc = 1;
+ unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+ write_back = WRITE_BACK(opcode);
//fp_printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
SetRoundingMode(ROUND_TO_NEAREST);
pBase = (unsigned int*)readRegister(getRn(opcode));
- if (REG_PC == getRn(opcode)) pBase += 2;
+ if (REG_PC == getRn(opcode))
+ {
+ pBase += 2;
+ write_back = 0;
+ }
pFinal = pBase;
if (BIT_UP_SET(opcode))
@@ -240,15 +249,21 @@ unsigned int PerformSTF(const unsigned int opcode)
default: nRc = 0;
}
- if (WRITE_BACK(opcode)) writeRegister(getRn(opcode),(unsigned int)pFinal);
+ if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return nRc;
}
unsigned int PerformLFM(const unsigned int opcode)
{
- unsigned int i, Fd, *pBase, *pAddress, *pFinal;
+ unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+ write_back = WRITE_BACK(opcode);
+
pBase = (unsigned int*)readRegister(getRn(opcode));
- if (REG_PC == getRn(opcode)) pBase += 2;
+ if (REG_PC == getRn(opcode))
+ {
+ pBase += 2;
+ write_back = 0;
+ }
pFinal = pBase;
if (BIT_UP_SET(opcode))
@@ -266,16 +281,21 @@ unsigned int PerformLFM(const unsigned int opcode)
if (Fd == 8) Fd = 0;
}
- if (WRITE_BACK(opcode)) writeRegister(getRn(opcode),(unsigned int)pFinal);
+ if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return 1;
}
unsigned int PerformSFM(const unsigned int opcode)
{
- unsigned int i, Fd, *pBase, *pAddress, *pFinal;
+ unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+ write_back = WRITE_BACK(opcode);
pBase = (unsigned int*)readRegister(getRn(opcode));
- if (REG_PC == getRn(opcode)) pBase += 2;
+ if (REG_PC == getRn(opcode))
+ {
+ pBase += 2;
+ write_back = 0;
+ }
pFinal = pBase;
if (BIT_UP_SET(opcode))
@@ -293,7 +313,7 @@ unsigned int PerformSFM(const unsigned int opcode)
if (Fd == 8) Fd = 0;
}
- if (WRITE_BACK(opcode)) writeRegister(getRn(opcode),(unsigned int)pFinal);
+ if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return 1;
}
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c
index cbfde092e..d479ee932 100644
--- a/arch/arm/nwfpe/fpa11_cprt.c
+++ b/arch/arm/nwfpe/fpa11_cprt.c
@@ -20,7 +20,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "milieu.h"
#include "softfloat.h"
#include "fpopcode.h"
@@ -65,37 +64,10 @@ unsigned int EmulateCPRT(const unsigned int opcode)
case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
-#if 0
- /* ?? Not at all sure about the mode checks here. Linux never
- calls the emulator from a non-USR fault but we always run in SVC
- mode. Is there even any point trying to emulate the way FPA11
- behaves in this respect?
-
- No - and I quote: 'The FPCR may only be present in some
- implementations: it is there to control the hardware in an
- implementation-specific manner, ... The user mode of the
- ARM is not permitted to use this register, and the WFC and
- RFC instructions will trap if tried from user mode.'
- Therefore, we do not provide the RFC and WFC instructions.
- (rmk, 3/05/1999)
- */
- case WFC_CODE >> 20:
- {
- int mode = 0;
- __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "g" (mode));
- nRc = (0x13 == mode) ? 1 : 0; /* in SVC processor mode? */
- if (nRc) writeFPCR(readRegister(getRd(opcode)));
- }
- break;
-
- case RFC_CODE >> 20:
- {
- int mode = 0;
- __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "g" (mode));
- nRc = (0x13 == mode) ? 1 : 0; /* in SVC processor mode? */
- if (nRc) writeRegister(getRd(opcode),readFPCR()); break;
- }
- break;
+#if 0 /* We currently have no use for the FPCR, so there's no point
+ in emulating it. */
+ case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
+ case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
#endif
default: nRc = 0;
@@ -114,24 +86,24 @@ unsigned int PerformFLT(const unsigned int opcode)
{
case ROUND_SINGLE:
{
- fpa11->fpreg[getFn(opcode)].fType = typeSingle;
- fpa11->fpreg[getFn(opcode)].fValue.fSingle =
+ fpa11->fType[getFn(opcode)] = typeSingle;
+ fpa11->fpreg[getFn(opcode)].fSingle =
int32_to_float32(readRegister(getRd(opcode)));
}
break;
case ROUND_DOUBLE:
{
- fpa11->fpreg[getFn(opcode)].fType = typeDouble;
- fpa11->fpreg[getFn(opcode)].fValue.fDouble =
+ fpa11->fType[getFn(opcode)] = typeDouble;
+ fpa11->fpreg[getFn(opcode)].fDouble =
int32_to_float64(readRegister(getRd(opcode)));
}
break;
case ROUND_EXTENDED:
{
- fpa11->fpreg[getFn(opcode)].fType = typeExtended;
- fpa11->fpreg[getFn(opcode)].fValue.fExtended =
+ fpa11->fType[getFn(opcode)] = typeExtended;
+ fpa11->fpreg[getFn(opcode)].fExtended =
int32_to_floatx80(readRegister(getRd(opcode)));
}
break;
@@ -149,26 +121,26 @@ unsigned int PerformFIX(const unsigned int opcode)
SetRoundingMode(opcode);
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
{
writeRegister(getRd(opcode),
- float32_to_int32(fpa11->fpreg[Fn].fValue.fSingle));
+ float32_to_int32(fpa11->fpreg[Fn].fSingle));
}
break;
case typeDouble:
{
writeRegister(getRd(opcode),
- float64_to_int32(fpa11->fpreg[Fn].fValue.fDouble));
+ float64_to_int32(fpa11->fpreg[Fn].fDouble));
}
break;
case typeExtended:
{
writeRegister(getRd(opcode),
- floatx80_to_int32(fpa11->fpreg[Fn].fValue.fExtended));
+ floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
}
break;
@@ -226,27 +198,27 @@ static unsigned int PerformComparison(const unsigned int opcode)
?? Might be some mileage in avoiding this conversion if possible.
Eg, if both operands are 32-bit, detect this and do a 32-bit
comparison (cheaper than an 80-bit one). */
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
//fp_printk("single.\n");
- if (float32_is_nan(fpa11->fpreg[Fn].fValue.fSingle))
+ if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
goto unordered;
- rFn = float32_to_floatx80(fpa11->fpreg[Fn].fValue.fSingle);
+ rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
break;
case typeDouble:
//fp_printk("double.\n");
- if (float64_is_nan(fpa11->fpreg[Fn].fValue.fDouble))
+ if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
goto unordered;
- rFn = float64_to_floatx80(fpa11->fpreg[Fn].fValue.fDouble);
+ rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
break;
case typeExtended:
//fp_printk("extended.\n");
- if (floatx80_is_nan(fpa11->fpreg[Fn].fValue.fExtended))
+ if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
goto unordered;
- rFn = fpa11->fpreg[Fn].fValue.fExtended;
+ rFn = fpa11->fpreg[Fn].fExtended;
break;
default: return 0;
@@ -262,27 +234,27 @@ static unsigned int PerformComparison(const unsigned int opcode)
else
{
//fp_printk("Fm = r%d which contains a ",Fm);
- switch (fpa11->fpreg[Fm].fType)
+ switch (fpa11->fType[Fm])
{
case typeSingle:
//fp_printk("single.\n");
- if (float32_is_nan(fpa11->fpreg[Fm].fValue.fSingle))
+ if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
goto unordered;
- rFm = float32_to_floatx80(fpa11->fpreg[Fm].fValue.fSingle);
+ rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
break;
case typeDouble:
//fp_printk("double.\n");
- if (float64_is_nan(fpa11->fpreg[Fm].fValue.fDouble))
+ if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
goto unordered;
- rFm = float64_to_floatx80(fpa11->fpreg[Fm].fValue.fDouble);
+ rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
break;
case typeExtended:
//fp_printk("extended.\n");
- if (floatx80_is_nan(fpa11->fpreg[Fm].fValue.fExtended))
+ if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
goto unordered;
- rFm = fpa11->fpreg[Fm].fValue.fExtended;
+ rFm = fpa11->fpreg[Fm].fExtended;
break;
default: return 0;
@@ -303,6 +275,7 @@ static unsigned int PerformComparison(const unsigned int opcode)
the data sheet, observation of how the Acorn emulator actually
behaves (and how programs expect it to) and guesswork. */
flags |= CC_OVERFLOW;
+ flags &= ~(CC_ZERO | CC_NEGATIVE);
if (BIT_AC & readFPSR()) flags |= CC_CARRY;
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
index de28e39f5..b9ca935eb 100644
--- a/arch/arm/nwfpe/fpmodule.c
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -1,3 +1,4 @@
+
/*
NetWinder Floating Point Emulator
(c) Rebel.com, 1998-1999
@@ -20,30 +21,16 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-
-#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
+#include <linux/config.h>
/* XXX */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
-#include <linux/mm.h>
#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/pgtable.h>
/* XXX */
#include "softfloat.h"
@@ -62,7 +49,7 @@ typedef struct task_struct* PTASK;
int fp_printk(const char *,...);
void fp_send_sig(unsigned long sig, PTASK p, int priv);
#if LINUX_VERSION_CODE > 0x20115
-MODULE_AUTHOR("Scott Bambrough <scottb@netwinder.org>");
+MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
MODULE_DESCRIPTION("NWFPE floating point emulator");
#endif
@@ -73,57 +60,51 @@ MODULE_DESCRIPTION("NWFPE floating point emulator");
#endif
/* kernel function prototypes required */
-void C_SYMBOL_NAME(fp_setup)(void);
+void fp_setup(void);
/* external declarations for saved kernel symbols */
-extern unsigned int C_SYMBOL_NAME(kern_fp_enter);
+extern void (*kern_fp_enter)(void);
+
+/* Original value of fp_enter from kernel before patched by fpe_init. */
+static void (*orig_fp_enter)(void);
/* forward declarations */
extern void nwfpe_enter(void);
-/* Original value of fp_enter from kernel before patched by fpe_init. */
-static unsigned int orig_fp_enter;
-
/* Address of user registers on the kernel stack. */
unsigned int *userRegisters;
-void __init C_SYMBOL_NAME(fpe_version)(void)
+void __init fpe_version(void)
{
static const char szTitle[] = "<4>NetWinder Floating Point Emulator ";
- static const char szVersion[] = "V0.94.1 ";
+ static const char szVersion[] = "V0.95 ";
static const char szCopyright[] = "(c) 1998-1999 Rebel.com\n";
- C_SYMBOL_NAME(fp_printk)(szTitle);
- C_SYMBOL_NAME(fp_printk)(szVersion);
- C_SYMBOL_NAME(fp_printk)(szCopyright);
+ fp_printk(szTitle);
+ fp_printk(szVersion);
+ fp_printk(szCopyright);
}
int __init fpe_init(void)
{
- /* Display title, version and copyright information. */
- C_SYMBOL_NAME(fpe_version)();
-
- /* Save pointer to the old FP handler and then patch ourselves in */
- orig_fp_enter = C_SYMBOL_NAME(kern_fp_enter);
- C_SYMBOL_NAME(kern_fp_enter) = (unsigned int)C_SYMBOL_NAME(nwfpe_enter);
+ if (sizeof(FPA11) > sizeof(union fp_state))
+ printk(KERN_ERR "nwfpe: bad structure size\n");
+ else {
+ /* Display title, version and copyright information. */
+ fpe_version();
+
+ /* Save pointer to the old FP handler and then patch ourselves in */
+ orig_fp_enter = kern_fp_enter;
+ kern_fp_enter = nwfpe_enter;
+ }
return 0;
}
-#ifdef MODULE
-int init_module(void)
-{
- return(fpe_init());
-}
-
-void cleanup_module(void)
+void __exit fpe_exit(void)
{
/* Restore the values we saved earlier. */
- C_SYMBOL_NAME(kern_fp_enter) = orig_fp_enter;
+ kern_fp_enter = orig_fp_enter;
}
-#endif
-
-#define _ARM_pc 60
-#define _ARM_cpsr 64
/*
ScottB: November 4, 1998
@@ -135,7 +116,7 @@ fpmodule.c to integrate with the NetBSD kernel (I hope!).
[1/1/99: Not quite true any more unfortunately. There is Linux-specific
code to access data in user space in some other source files at the
-moment. --philb]
+moment (grep for get_user / put_user calls). --philb]
float_exception_flags is a global variable in SoftFloat.
@@ -147,8 +128,9 @@ cumulative exceptions flag byte are set and we return.
void float_raise(signed char flags)
{
-#if 0
- printk(KERN_DEBUG "NWFPE: exception %08x at %08x from %08x\n", flags,
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
+ current->comm, current->pid, flags,
__builtin_return_address(0), userRegisters[15]);
#endif
@@ -156,7 +138,7 @@ void float_raise(signed char flags)
if (readFPSR() & (flags << 16))
{
/* raise exception */
- C_SYMBOL_NAME(fp_send_sig)(SIGFPE,C_SYMBOL_NAME(current),1);
+ fp_send_sig(SIGFPE, current, 1);
}
else
{
@@ -164,3 +146,6 @@ void float_raise(signed char flags)
writeFPSR(flags);
}
}
+
+module_init(fpe_init);
+module_exit(fpe_exit);
diff --git a/arch/arm/nwfpe/fpmodule.inl b/arch/arm/nwfpe/fpmodule.inl
index c76b7fd55..127b24218 100644
--- a/arch/arm/nwfpe/fpmodule.inl
+++ b/arch/arm/nwfpe/fpmodule.inl
@@ -1,23 +1,23 @@
/*
NetWinder Floating Point Emulator
- (c) Corel Computer Corporation, 1998
+ (c) Rebel.com, 1998-1999
- Direct questions, comments to Scott Bambrough <scottb@corelcomputer.com>
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
/* Address of user registers on the kernel stack. */
extern unsigned int *userRegisters;
@@ -25,64 +25,60 @@ extern unsigned int *userRegisters;
extern __inline__
unsigned int readRegister(const unsigned int nReg)
{
- /* Note: The CPU thinks it has dealt with the current instruction. As
- a result the program counter has been advanced to the next
- instruction, and points 4 bytes beyond the actual instruction
- that caused the invalid instruction trap to occur. We adjust
- for this in this routine. LDF/STF instructions with Rn = PC
- depend on the PC being correct, as they use PC+8 in their
- address calculations. */
- unsigned int val = userRegisters[nReg];
-
- if (REG_PC == nReg)
- val -= 4;
-
- return val;
+ /* Note: The CPU thinks it has dealt with the current instruction. As
+ a result the program counter has been advanced to the next
+ instruction, and points 4 bytes beyond the actual instruction
+ that caused the invalid instruction trap to occur. We adjust
+ for this in this routine. LDF/STF instructions with Rn = PC
+ depend on the PC being correct, as they use PC+8 in their
+ address calculations. */
+ unsigned int val = userRegisters[nReg];
+ if (REG_PC == nReg) val -= 4;
+ return val;
}
extern __inline__
void writeRegister(const unsigned int nReg, const unsigned int val)
{
- userRegisters[nReg] = val;
+ userRegisters[nReg] = val;
}
extern __inline__
unsigned int readCPSR(void)
{
- return (readRegister(REG_CPSR));
+ return(readRegister(REG_CPSR));
}
extern __inline__
void writeCPSR(const unsigned int val)
{
- writeRegister(REG_CPSR, val);
+ writeRegister(REG_CPSR,val);
}
extern __inline__
unsigned int readConditionCodes(void)
{
#ifdef __FPEM_TEST__
- return (0);
+ return(0);
#else
- return (readCPSR() & CC_MASK);
+ return(readCPSR() & CC_MASK);
#endif
}
extern __inline__
void writeConditionCodes(const unsigned int val)
{
- unsigned int rval;
-
- /*
- * Operate directly on userRegisters since
- * the CPSR may be the PC register itself.
- */
- rval = userRegisters[REG_CPSR] & ~CC_MASK;
- userRegisters[REG_CPSR] = rval | (val & CC_MASK);
+ unsigned int rval;
+ /*
+ * Operate directly on userRegisters since
+ * the CPSR may be the PC register itself.
+ */
+ rval = userRegisters[REG_CPSR] & ~CC_MASK;
+ userRegisters[REG_CPSR] = rval | (val & CC_MASK);
}
extern __inline__
unsigned int readMemoryInt(unsigned int *pMem)
{
- return *pMem;
+ return *pMem;
}
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
index 0d12f7269..4b01b43c6 100644
--- a/arch/arm/nwfpe/fpopcode.c
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -19,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
#include "softfloat.h"
#include "fpopcode.h"
#include "fpsr.h"
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c
index a2a9f6f81..77bb73515 100644
--- a/arch/arm/nwfpe/single_cpdo.c
+++ b/arch/arm/nwfpe/single_cpdo.c
@@ -19,8 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
-#include "milieu.h"
#include "softfloat.h"
#include "fpopcode.h"
#include "fpa11.h"
@@ -51,10 +49,10 @@ unsigned int SingleCPDO(const unsigned int opcode)
}
else
{
- switch (fpa11->fpreg[Fm].fType)
+ switch (fpa11->fType[Fm])
{
case typeSingle:
- rFm = fpa11->fpreg[Fm].fValue.fSingle;
+ rFm = fpa11->fpreg[Fm].fSingle;
break;
default: return 0;
@@ -64,10 +62,10 @@ unsigned int SingleCPDO(const unsigned int opcode)
if (!MONADIC_INSTRUCTION(opcode))
{
Fn = getFn(opcode);
- switch (fpa11->fpreg[Fn].fType)
+ switch (fpa11->fType[Fn])
{
case typeSingle:
- rFn = fpa11->fpreg[Fn].fValue.fSingle;
+ rFn = fpa11->fpreg[Fn].fSingle;
break;
default: return 0;
@@ -79,112 +77,112 @@ unsigned int SingleCPDO(const unsigned int opcode)
{
/* dyadic opcodes */
case ADF_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_add(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
break;
case MUF_CODE:
case FML_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_mul(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
break;
case SUF_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_sub(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
break;
case RSF_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_sub(rFm,rFn);
+ fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
break;
case DVF_CODE:
case FDV_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_div(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
break;
case RDF_CODE:
case FRD_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_div(rFm,rFn);
+ fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
break;
#if 0
case POW_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_pow(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
break;
case RPW_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_pow(rFm,rFn);
+ fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
break;
#endif
case RMF_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_rem(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
break;
#if 0
case POL_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_pol(rFn,rFm);
+ fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
break;
#endif
/* monadic opcodes */
case MVF_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = rFm;
+ fpa11->fpreg[Fd].fSingle = rFm;
break;
case MNF_CODE:
rFm ^= 0x80000000;
- fpa11->fpreg[Fd].fValue.fSingle = rFm;
+ fpa11->fpreg[Fd].fSingle = rFm;
break;
case ABS_CODE:
rFm &= 0x7fffffff;
- fpa11->fpreg[Fd].fValue.fSingle = rFm;
+ fpa11->fpreg[Fd].fSingle = rFm;
break;
case RND_CODE:
case URD_CODE:
- fpa11->fpreg[Fd].fValue.fSingle =
+ fpa11->fpreg[Fd].fSingle =
int32_to_float32(float32_to_int32(rFm));
break;
case SQT_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_sqrt(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
break;
#if 0
case LOG_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_log(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_log(rFm);
break;
case LGN_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_ln(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
break;
case EXP_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_exp(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
break;
case SIN_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_sin(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
break;
case COS_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_cos(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
break;
case TAN_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_tan(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
break;
case ASN_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_arcsin(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
break;
case ACS_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_arccos(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
break;
case ATN_CODE:
- fpa11->fpreg[Fd].fValue.fSingle = float32_arctan(rFm);
+ fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
break;
#endif
@@ -197,7 +195,7 @@ unsigned int SingleCPDO(const unsigned int opcode)
}
}
- if (0 != nRc) fpa11->fpreg[Fd].fType = typeSingle;
+ if (0 != nRc) fpa11->fType[Fd] = typeSingle;
return nRc;
}
diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
index f336370b4..446f49924 100644
--- a/arch/arm/vmlinux-armo.lds.in
+++ b/arch/arm/vmlinux-armo.lds.in
@@ -3,16 +3,36 @@
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
OUTPUT_ARCH(arm)
-ENTRY(_start)
+ENTRY(stext)
SECTIONS
{
. = TEXTADDR;
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ __proc_info_begin = .;
+ .proc.info : { *(.proc.info) }
+ __proc_info_end = .;
+ .data.init : { *(.data.init) }
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+ . = ALIGN(32768);
+ __init_end = .;
+
+ .init.task : {
+ *(.init.task)
+ }
+
_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) }
@@ -26,27 +46,17 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
+ .got : { *(.got) } /* Global offset table */
+
_etext = .; /* End of text section */
- . = ALIGN(8192);
.data : { /* Data */
- *(.init.task)
*(.data)
CONSTRUCTORS
}
_edata = .; /* End of data section */
- . = ALIGN(32768); /* Init code and data */
- __init_begin = .;
- .text.init : { *(.text.init) }
- __proc_info_begin = .;
- .proc.info : { *(.proc.info) }
- __proc_info_end = .;
- .data.init : { *(.data.init) }
- . = ALIGN(32768);
- __init_end = .;
-
__bss_start = .; /* BSS */
.bss : {
*(.bss)
diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
index a1f6d414b..f83109875 100644
--- a/arch/arm/vmlinux-armv.lds.in
+++ b/arch/arm/vmlinux-armv.lds.in
@@ -3,11 +3,10 @@
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
OUTPUT_ARCH(arm)
-ENTRY(_start)
+ENTRY(stext)
SECTIONS
{
. = TEXTADDR;
- _text = .; /* Text and read-only data */
.text : { } /* Set text start address */
__init_begin = .; /* Init code and data */
@@ -38,6 +37,7 @@ SECTIONS
. = ALIGN(4096);
__netwinder_end = .;
+ _text = .; /* Text and read-only data */
.text.real : { /* Real text segment */
*(.text)
*(.fixup)
@@ -57,6 +57,8 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
+ .got : { *(.got) } /* Global offset table */
+
_etext = .; /* End of text section */
. = ALIGN(8192);