## Automatically generated incremental diff
## From: linux-2.5.70-bk13
## To: linux-2.5.70-bk14
## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $
diff -urN linux-2.5.70-bk13/Documentation/DocBook/Makefile linux-2.5.70-bk14/Documentation/DocBook/Makefile
--- linux-2.5.70-bk13/Documentation/DocBook/Makefile 2003-06-09 04:41:53.000000000 -0700
+++ linux-2.5.70-bk14/Documentation/DocBook/Makefile 2003-06-09 04:42:01.000000000 -0700
@@ -39,8 +39,8 @@
###
#External programs used
-KERNELDOC=$(objtree)/scripts/kernel-doc
-DOCPROC=$(objtree)/scripts/docproc
+KERNELDOC = scripts/kernel-doc
+DOCPROC = scripts/docproc
###
# DOCPROC is used for two purposes:
@@ -50,14 +50,14 @@
# The following rules are used to generate the .sgml documentation
# required to generate the final targets. (ps, pdf, html).
quiet_cmd_docproc = DOCPROC $@
-cmd_docproc = $(DOCPROC) doc $< >$@
+ cmd_docproc = $(DOCPROC) doc $< >$@
define rule_docproc
- set -e
- $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';)
- $(cmd_$(1)); \
- ( \
- echo 'cmd_$@ := $(cmd_$(1))'; \
- echo $@: `$(DOCPROC) depend $<`; \
+ set -e; \
+ $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
+ $(cmd_$(1)); \
+ ( \
+ echo 'cmd_$@ := $(cmd_$(1))'; \
+ echo $@: `$(DOCPROC) depend $<`; \
) > $(dir $@).$(notdir $@).cmd
endef
@@ -96,41 +96,55 @@
###
# Rules to generate postscript, PDF and HTML
# db2html creates a directory. Generate a html file used for timestamp
+
+quiet_cmd_db2ps = DB2PS $@
+ cmd_db2ps = db2ps -o $(dir $@) $<
%.ps : %.sgml
@(which db2ps > /dev/null 2>&1) || \
(echo "*** You need to install DocBook stylesheets ***"; \
exit 1)
- $(call do_cmd,DB2PS $@,db2ps -o $(dir $@) $<)
+ $(call cmd,db2ps)
+quiet_cmd_db2pdf = DB2PDF $@
+ cmd_db2pdf = db2pdf -o $(dir $@) $<
%.pdf : %.sgml
@(which db2pdf > /dev/null 2>&1) || \
(echo "*** You need to install DocBook stylesheets ***"; \
exit 1)
- $(call do_cmd,DB2PDF $@,db2pdf -o $(dir $@) $<)
+ $(call cmd,db2pdf)
+
+quiet_cmd_db2html = DB2HTML $@
+ cmd_db2html = db2html -o $(patsubst %.html,%,$@) $< && \
+ echo ' \
+ Goto $(patsubst %.html,%,$(notdir $@))
' > $@
%.html: %.sgml
@(which db2html > /dev/null 2>&1) || \
(echo "*** You need to install DocBook stylesheets ***"; \
exit 1)
@rm -rf $@ $(patsubst %.html,%,$@)
- $(call do_cmd,DB2HTML $@,db2html -o $(patsubst %.html,%,$@) $< && \
- echo '\
- Goto $(patsubst %.html,%,$(notdir $@))
' > $@)
+ $(call cmd,db2html)
@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
###
# Rules to generate postscripts and PNG imgages from .fig format files
+quiet_cmd_fig2eps = FIG2EPS $@
+ cmd_fig2eps = fig2dev -Leps $< $@
+
%.eps: %.fig
- $(call do_cmd,FIG2DEV -Leps $@,fig2dev -Leps $< $@)
+ $(call cmd,fig2eps)
+
+quiet_cmd_fig2png = FIG2PNG $@
+ cmd_fig2png = fig2dev -Lpng $< $@
%.png: %.fig
- $(call do_cmd,FIG2DEV -Lpng $@,fig2dev -Lpng $< $@)
+ $(call cmd,fig2png)
###
# Rule to convert a .c file to inline SGML documentation
%.sgml: %.c
- @echo ' Generating $@'
+ @echo ' GEN $@'
@( \
echo ""; \
expand --tabs=8 < $< | \
diff -urN linux-2.5.70-bk13/Documentation/DocBook/kernel-api.tmpl linux-2.5.70-bk14/Documentation/DocBook/kernel-api.tmpl
--- linux-2.5.70-bk13/Documentation/DocBook/kernel-api.tmpl 2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk14/Documentation/DocBook/kernel-api.tmpl 2003-06-09 04:42:01.000000000 -0700
@@ -79,6 +79,7 @@
String Manipulation
!Ilib/string.c
+!Elib/string.c
Bit Operations
!Iinclude/asm-i386/bitops.h
@@ -176,7 +177,7 @@
!Edrivers/pci/pci.c
PCI Hotplug Support Library
-!Edrivers/hotplug/pci_hotplug_core.c
+!Edrivers/pci/hotplug/pci_hotplug_core.c
MCA Architecture
MCA Device Functions
diff -urN linux-2.5.70-bk13/Documentation/kbuild/makefiles.txt linux-2.5.70-bk14/Documentation/kbuild/makefiles.txt
--- linux-2.5.70-bk13/Documentation/kbuild/makefiles.txt 2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk14/Documentation/kbuild/makefiles.txt 2003-06-09 04:42:01.000000000 -0700
@@ -11,7 +11,7 @@
--- 3.2 Built-in object goals - obj-y
--- 3.3 Loadable module goals - obj-m
--- 3.4 Objects which export symbols
- --- 3.5 Library file goals - L_TARGET
+ --- 3.5 Library file goals - lib-y
--- 3.6 Descending down in directories
--- 3.7 Compilation flags
--- 3.8 Command line dependency
@@ -214,20 +214,33 @@
modules exporting symbols.
See also Documentation/modules.txt.
---- 3.5 Library file goals - L_TARGET
+--- 3.5 Library file goals - lib-y
- Instead of building a built-in.o file, you may also
- build an archive which again contains objects listed in $(obj-y).
- This is normally not necessary and only used in lib/ and
- arch/$(ARCH)/lib directories.
- Only the name lib.a is allowed.
+ Objects listed with obj-* is used for modules or
+ are combined in a built-in.o for that specific directory.
+ There is also the possibility to list objects that will
+ be included in a library, lib.a.
+ All objects listed with lib-y are combined in a single
+ library for that directory.
+ Objects that are listed in obj-y and additional listed in
+ lib-y will not be included in the library, since they will anyway
+ be accessible.
+ For consistency objects listed in lib-m will be included in lib.a.
+
+ Note that the same kbuild makefile may list files to be built-in
+ and to be part of a library. Therefore the same directory
+ may contain both a built-in.o and a lib.a file.
Example:
#arch/i386/lib/Makefile
- L_TARGET := lib.a
- obj-y := checksum.o delay.o
+ lib-y := checksum.o delay.o
This will create a library lib.a based on checksum.o and delay.o.
+ For kbuild to actually recognize that there is a lib.a being build
+ the directory shall be listed in libs-y.
+ See also "6.3 List directories to visit when descending".
+
+ Usage of lib-y is normally restricted to lib/ and arch/*/lib.
--- 3.6 Descending down in directories
@@ -727,7 +740,7 @@
head-y, init-y, core-y, libs-y, drivers-y, net-y
$(head-y) list objects to be linked first in vmlinux.
- $(libs-y) list directories where a libs.a archive can be located.
+ $(libs-y) list directories where a lib.a archive can be located.
The rest list directories where a built-in.o object file can be located.
$(init-y) objects will be located after $(head-y).
diff -urN linux-2.5.70-bk13/MAINTAINERS linux-2.5.70-bk14/MAINTAINERS
--- linux-2.5.70-bk13/MAINTAINERS 2003-06-09 04:41:53.000000000 -0700
+++ linux-2.5.70-bk14/MAINTAINERS 2003-06-09 04:42:02.000000000 -0700
@@ -395,27 +395,6 @@
L: pcihpd-discuss@lists.sourceforge.net
S: Supported
-COMPAQ FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA
-P: Amy Vanzant-Hodge
-M: Amy Vanzant-Hodge (fibrechannel@compaq.com)
-L: compaqandlinux@cpqlin.van-dijk.net
-W: ftp.compaq.com/pub/products/drivers/linux
-S: Supported
-
-COMPAQ SMART2 RAID DRIVER
-P: Charles White
-M: Charles White
-L: compaqandlinux@cpqlin.van-dijk.net
-W: ftp.compaq.com/pub/products/drivers/linux
-S: Supported
-
-COMPAQ SMART CISS RAID DRIVER
-P: Charles White
-M: Charles White
-L: compaqandlinux@cpqlin.van-dijk.net
-W: ftp.compaq.com/pub/products/drivers/linux
-S: Supported
-
COMPUTONE INTELLIPORT MULTIPORT CARD
P: Michael H. Warfield
M: Michael H. Warfield
@@ -792,6 +771,27 @@
L: linux-hippi@sunsite.dk
S: Maintained
+HP (was COMPAQ) FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA
+P: Stephen Cameron
+M: arrays@hp.com
+M: steve.cameron@hp.com
+L: cpqfc-discuss@lists.sourceforge.net
+S: Odd Fixes
+
+HP (was COMPAQ) SMART2 RAID DRIVER
+P: Stephen Cameron
+M: arrays@hp.com
+M: steve.cameron@hp.com
+L: cpqarray-discuss@lists.sourceforge.net
+S: Odd Fixes
+
+HP (was COMPAQ) SMART CISS RAID DRIVER
+P: Stephen Cameron
+M: arrays@hp.com
+M: steve.cameron@hp.com
+L: cciss-discuss@lists.sourceforge.net
+S: Supported
+
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
P: Jaroslav Kysela
M: perex@suse.cz
diff -urN linux-2.5.70-bk13/Makefile linux-2.5.70-bk14/Makefile
--- linux-2.5.70-bk13/Makefile 2003-06-09 04:41:53.000000000 -0700
+++ linux-2.5.70-bk14/Makefile 2003-06-09 04:42:02.000000000 -0700
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 5
SUBLEVEL = 70
-EXTRAVERSION = -bk13
+EXTRAVERSION = -bk14
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
diff -urN linux-2.5.70-bk13/arch/alpha/kernel/asm-offsets.c linux-2.5.70-bk14/arch/alpha/kernel/asm-offsets.c
--- linux-2.5.70-bk13/arch/alpha/kernel/asm-offsets.c 2003-05-26 18:01:01.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/kernel/asm-offsets.c 2003-06-09 04:42:02.000000000 -0700
@@ -31,6 +31,7 @@
DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
BLANK();
+ DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
diff -urN linux-2.5.70-bk13/arch/alpha/kernel/head.S linux-2.5.70-bk14/arch/alpha/kernel/head.S
--- linux-2.5.70-bk13/arch/alpha/kernel/head.S 2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/kernel/head.S 2003-06-09 04:42:02.000000000 -0700
@@ -9,6 +9,7 @@
#include
#include
+#include
.globl swapper_pg_dir
.globl _stext
@@ -25,7 +26,7 @@
/* We need to get current_task_info loaded up... */
lda $8,init_thread_union
/* ... and find our stack ... */
- lda $30,0x4000($8)
+ lda $30,0x4000 - SIZEOF_PT_REGS($8)
/* ... and then we can start the kernel. */
jsr $26,start_kernel
call_pal PAL_halt
diff -urN linux-2.5.70-bk13/arch/alpha/kernel/systbls.S linux-2.5.70-bk14/arch/alpha/kernel/systbls.S
--- linux-2.5.70-bk13/arch/alpha/kernel/systbls.S 2003-06-09 04:41:53.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/kernel/systbls.S 2003-06-09 04:42:02.000000000 -0700
@@ -442,6 +442,7 @@
.quad sys_clock_gettime /* 420 */
.quad sys_clock_getres
.quad sys_clock_nanosleep
+ .quad sys_semtimedop
.size sys_call_table, . - sys_call_table
.type sys_call_table, @object
diff -urN linux-2.5.70-bk13/arch/alpha/kernel/traps.c linux-2.5.70-bk14/arch/alpha/kernel/traps.c
--- linux-2.5.70-bk13/arch/alpha/kernel/traps.c 2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/kernel/traps.c 2003-06-09 04:42:02.000000000 -0700
@@ -485,9 +485,9 @@
" extwh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -505,9 +505,9 @@
" extlh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -525,9 +525,9 @@
" extqh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -554,13 +554,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
@@ -584,13 +584,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
@@ -614,13 +614,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n\t"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
@@ -845,9 +845,9 @@
" extwh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -865,9 +865,9 @@
" extlh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -885,9 +885,9 @@
" extqh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -905,9 +905,9 @@
" extlh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -925,9 +925,9 @@
" extqh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %1,3b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %2,3b-2b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
@@ -954,13 +954,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
@@ -988,13 +988,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
@@ -1022,13 +1022,13 @@
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n\t"
- " .gprel32 1b\n"
+ " .long 1b - .\n"
" lda %2,5b-1b(%0)\n"
- " .gprel32 2b\n"
+ " .long 2b - .\n"
" lda %1,5b-2b(%0)\n"
- " .gprel32 3b\n"
+ " .long 3b - .\n"
" lda $31,5b-3b(%0)\n"
- " .gprel32 4b\n"
+ " .long 4b - .\n"
" lda $31,5b-4b(%0)\n"
".previous"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
diff -urN linux-2.5.70-bk13/arch/alpha/lib/csum_partial_copy.c linux-2.5.70-bk14/arch/alpha/lib/csum_partial_copy.c
--- linux-2.5.70-bk13/arch/alpha/lib/csum_partial_copy.c 2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/lib/csum_partial_copy.c 2003-06-09 04:42:02.000000000 -0700
@@ -46,7 +46,7 @@
"1: ldq_u %0,%2\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
- " .gprel32 1b\n" \
+ " .long 1b - .\n" \
" lda %0,2b-1b(%1)\n" \
".previous" \
: "=r"(x), "=r"(__guu_err) \
@@ -61,7 +61,7 @@
"1: stq_u %2,%1\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
- " .gprel32 1b" \
+ " .long 1b - ." \
" lda $31,2b-1b(%0)\n" \
".previous" \
: "=r"(__puu_err) \
diff -urN linux-2.5.70-bk13/arch/alpha/lib/memmove.S linux-2.5.70-bk14/arch/alpha/lib/memmove.S
--- linux-2.5.70-bk13/arch/alpha/lib/memmove.S 2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk14/arch/alpha/lib/memmove.S 2003-06-09 04:42:02.000000000 -0700
@@ -12,6 +12,15 @@
.text
.align 4
+ .globl bcopy
+ .ent bcopy
+bcopy:
+ mov $16,$0
+ mov $17,$16
+ mov $0,$17
+ .end bcopy
+
+ .align 4
.globl memmove
.ent memmove
memmove:
diff -urN linux-2.5.70-bk13/arch/arm26/ACKNOWLEDGEMENTS linux-2.5.70-bk14/arch/arm26/ACKNOWLEDGEMENTS
--- linux-2.5.70-bk13/arch/arm26/ACKNOWLEDGEMENTS 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/ACKNOWLEDGEMENTS 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,27 @@
+The work in this architecture (ARM26) is that of a great many people.
+
+This is what has happened:
+
+I [Ian Molton] have been trying to repair the ARM26 architecture support, but it has become an impossible task whilst it is still merged with the ARM32 (arch/arm) code. The ARM26 code is too different to be sensible to keep with the ARM32 code now, and Russell King really doesnt have the time to maintain the ARM26 code. Add to that that most ARM32 developers dont know about or care about ARM26 when writing patches, and you have a reall mess.
+
+As a result, I've split it off into a new architecture of its own. I've named it arm26 since these CPUs have only a 26 bit address space, unlike the other ARMs.
+
+The upheaval in moving around so many source files and chopping out vasty ammounts of cruft was enormous, and the copyright of many files is sometimes unclear. Because of this, I am writing this, in order that no-one is left out / misaccredited / blamed for any of the code.
+
+People I KNOW have made major contributions to the code:
+
+David Alan Gilbert (former maintainer of ARM26 bits)
+Philip Blundell
+Russell King
+Keith Owens
+
+Currently maintaing the code are
+
+Ian Molton (Maintainer / Archimedes)
+John Appleby (kernel / A5K)
+
+If anyone has a problem with attributions in header files / source files, please do contact me to straighten things out.
+
+Ian Molton (aka spyro) - ARM26 maintainer
+spyro@f2s.com
+
diff -urN linux-2.5.70-bk13/arch/arm26/Config.help linux-2.5.70-bk14/arch/arm26/Config.help
--- linux-2.5.70-bk13/arch/arm26/Config.help 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/Config.help 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,387 @@
+CONFIG_ARM
+ The ARM series is a line of low-power-consumption RISC chip designs
+ licensed by ARM ltd and targeted at embedded applications.
+
+CONFIG_IDE
+ If you say Y here, your kernel will be able to manage low cost mass
+ storage units such as ATA/(E)IDE and ATAPI units. The most common
+ cases are IDE hard drives and ATAPI CD-ROM drives.
+
+ If your system is pure SCSI and doesn't use these interfaces, you
+ can say N here.
+
+ Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
+ for mass storage units such as hard disks. It was designed by
+ Western Digital and Compaq Computer in 1984. It was then named
+ ST506. Quite a number of disks use the IDE interface.
+
+ AT Attachment (ATA) is the superset of the IDE specifications.
+ ST506 was also called ATA-1.
+
+ Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
+ ATA-3. It provides support for larger disks (up to 8.4GB by means of
+ the LBA standard), more disks (4 instead of 2) and for other mass
+ storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
+ ATA-4 and provides faster (and more CPU friendly) transfer modes
+ than previous PIO (Programmed processor Input/Output) from previous
+ ATA/IDE standards by means of fast DMA controllers.
+
+ ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
+ CD-ROM drives, similar in many respects to the SCSI protocol.
+
+ SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
+ designed in order to prevent data corruption and disk crash by
+ detecting pre hardware failure conditions (heat, access time, and
+ the like...). Disks built since June 1995 may follow this standard.
+ The kernel itself don't manage this; however there are quite a
+ number of user programs such as smart that can query the status of
+ SMART parameters disk.
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read . The module
+ will be called ide.o.
+
+ For further information, please read .
+
+ If unsure, say Y.
+
+CONFIG_ISA
+ Find out whether you have ISA slots on your motherboard. ISA is the
+ name of a bus system, i.e. the way the CPU talks to the other stuff
+ inside your box. Other bus systems are PCI, EISA, MicroChannel
+ (MCA) or VESA. ISA is an older system, now being displaced by PCI;
+ newer boards don't support it. If you have ISA, say Y, otherwise N.
+
+CONFIG_PREEMPT
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ This allows applications to run more reliably even when the system is
+ under load.
+
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
+
+CONFIG_MCA
+ MicroChannel Architecture is found in some IBM PS/2 machines and
+ laptops. It is a bus system similar to PCI or ISA. See
+ (and especially the web page given
+ there) before attempting to build an MCA bus kernel.
+
+CONFIG_EISA
+ The Extended Industry Standard Architecture (EISA) bus was
+ developed as an open alternative to the IBM MicroChannel bus.
+
+ The EISA bus provided some of the features of the IBM MicroChannel
+ bus while maintaining backward compatibility with cards made for
+ the older ISA bus. The EISA bus saw limited use between 1988 and
+ 1995 when it was made obsolete by the PCI bus.
+
+ Say Y here if you are building a kernel for an EISA-based machine.
+
+ Otherwise, say N.
+
+CONFIG_HOTPLUG
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
+
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
+
+ Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
+ software (at ) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
+
+CONFIG_KCORE_ELF
+ If you enabled support for /proc file system then the file
+ /proc/kcore will contain the kernel core image. This can be used
+ in gdb:
+
+ $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
+
+ You have two choices here: ELF and A.OUT. Selecting ELF will make
+ /proc/kcore appear in ELF core format as defined by the Executable
+ and Linking Format specification. Selecting A.OUT will choose the
+ old "a.out" format which may be necessary for some old versions
+ of binutils or on some architectures.
+
+ This is especially useful if you have compiled the kernel with the
+ "-g" option to preserve debugging information. It is mainly used
+ for examining kernel data structures on the live kernel so if you
+ don't understand what this means or are not a kernel hacker, just
+ leave it at its default value ELF.
+
+CONFIG_KCORE_AOUT
+ Not necessary unless you're using a very out-of-date binutils
+ version. You probably want KCORE_ELF.
+
+CONFIG_BINFMT_ELF
+ ELF (Executable and Linkable Format) is a format for libraries and
+ executables used across different architectures and operating
+ systems. Saying Y here will enable your kernel to run ELF binaries
+ and enlarge it by about 13 KB. ELF support under Linux has now all
+ but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
+ because it is portable (this does *not* mean that you will be able
+ to run executables from different architectures or operating systems
+ however) and makes building run-time libraries very easy. Many new
+ executables are distributed solely in ELF format. You definitely
+ want to say Y here.
+
+ Information about ELF is contained in the ELF HOWTO available from
+ .
+
+ If you find that after upgrading from Linux kernel 1.2 and saying Y
+ here, you still can't run any ELF binaries (they just crash), then
+ you'll have to install the newest ELF runtime libraries, including
+ ld.so (check the file for location and
+ latest version).
+
+ If you want to compile this as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read . The module
+ will be called binfmt_elf.o. Saying M or N here is dangerous because
+ some crucial programs on your system might be in ELF format.
+
+CONFIG_BINFMT_AOUT
+ A.out (Assembler.OUTput) is a set of formats for libraries and
+ executables used in the earliest versions of UNIX. Linux used the
+ a.out formats QMAGIC and ZMAGIC until they were replaced with the
+ ELF format.
+
+ As more and more programs are converted to ELF, the use for a.out
+ will gradually diminish. If you disable this option it will reduce
+ your kernel by one page. This is not much and by itself does not
+ warrant removing support. However its removal is a good idea if you
+ wish to ensure that absolutely none of your programs will use this
+ older executable format. If you don't know what to answer at this
+ point then answer Y. If someone told you "You need a kernel with
+ QMAGIC support" then you'll have to say Y here. You may answer M to
+ compile a.out support as a module and later load the module when you
+ want to use a program or library in a.out format. The module will be
+ called binfmt_aout.o. Saying M or N here is dangerous though,
+ because some crucial programs on your system might still be in A.OUT
+ format.
+
+CONFIG_BINFMT_MISC
+ If you say Y here, it will be possible to plug wrapper-driven binary
+ formats into the kernel. You will like this especially when you use
+ programs that need an interpreter to run like Java, Python or
+ Emacs-Lisp. It's also useful if you often run DOS executables under
+ the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
+ ). Once you have
+ registered such a binary class with the kernel, you can start one of
+ those programs simply by typing in its name at a shell prompt; Linux
+ will automatically feed it to the correct interpreter.
+
+ You can do other nice things, too. Read the file
+ to learn how to use this
+ feature, and for information about how
+ to include Java support.
+
+ You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
+ use this part of the kernel.
+
+ You may say M here for module support and later load the module when
+ you have use for it; the module is called binfmt_misc.o. If you
+ don't know what to answer at this point, say Y.
+
+CONFIG_SCSI
+ If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
+ any other SCSI device under Linux, say Y and make sure that you know
+ the name of your SCSI host adapter (the card inside your computer
+ that "speaks" the SCSI protocol, also called SCSI controller),
+ because you will be asked for it.
+
+ You also need to say Y here if you want support for the parallel
+ port version of the 100 MB IOMEGA ZIP drive.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called scsi_mod.o. If you want to compile it as
+ a module, say M here and read and
+ . However, do not compile this as a
+ module if your root file system (the one containing the directory /)
+ is located on a SCSI device.
+
+CONFIG_NETDEVICES
+ You can say N here if you don't intend to connect your Linux box to
+ any other computer at all or if all your connections will be over a
+ telephone line with a modem either via UUCP (UUCP is a protocol to
+ forward mail and news between unix hosts over telephone lines; read
+ the UUCP-HOWTO, available from
+ ) or dialing up a shell
+ account or a BBS, even using term (term is a program which gives you
+ almost full Internet connectivity if you have a regular dial up
+ shell account on some Internet connected Unix computer. Read
+ ).
+
+ You'll have to say Y if your computer contains a network card that
+ you want to use under Linux (make sure you know its name because you
+ will be asked for it and read the Ethernet-HOWTO (especially if you
+ plan to use more than one network card under Linux)) or if you want
+ to use SLIP (Serial Line Internet Protocol is the protocol used to
+ send Internet traffic over telephone lines or null modem cables) or
+ CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
+ and newer replacement for SLIP) or PLIP (Parallel Line Internet
+ Protocol is mainly used to create a mini network by connecting the
+ parallel ports of two local machines) or AX.25/KISS (protocol for
+ sending Internet traffic over amateur radio links).
+
+ Make sure to read the NET-3-HOWTO. Eventually, you will have to read
+ Olaf Kirch's excellent and free book "Network Administrator's
+ Guide", to be found in . If
+ unsure, say Y.
+
+CONFIG_MAGIC_SYSRQ
+ If you say Y here, you will have some control over the system even
+ if the system crashes for example during kernel debugging (e.g., you
+ will be able to flush the buffer cache to disk, reboot the system
+ immediately or dump some status information). This is accomplished
+ by pressing various keys while holding SysRq (Alt+PrintScreen). It
+ also works on a serial console (on PC hardware at least), if you
+ send a BREAK and then within 5 seconds a command keypress. The
+ keys are documented in . Don't say Y
+ unless you really know what this hack does.
+
+CONFIG_ARCH_ARCA5K
+ This selects support for 'ARM26' CPUs (ARM 2 and 3)
+
+CONFIG_ARCH_A5K
+ Say Y here to to support the Acorn A5000. Linux can support the
+ internal IDE disk and CD-ROM interface, serial and parallel port,
+ and the floppy drive. Note that on some A5000s the floppy is
+ plugged into the wrong socket on the motherboard.
+
+CONFIG_ARCH_ARC
+ The Acorn Archimedes was an personal computer based on an 8MHz ARM2
+ processor, released in 1987. It supported 512K of RAM and 2 800K
+ floppy disks. Picture and more detailed specifications at
+ .
+
+CONFIG_PAGESIZE_16
+ Say Y here if your Archimedes or A5000 system has only 2MB of
+ memory, otherwise say N. The resulting kernel will not run on a
+ machine with 4MB of memory.
+
+CONFIG_FPE_NWFPE
+ Say Y to include the NWFPE floating point emulator in the kernel.
+ This is necessary to run most binaries. Linux does not currently
+ support floating point hardware so you need to say Y here even if
+ your machine has an FPA or floating point co-processor podule.
+
+ It is also possible to say M to build the emulator as a module
+ (nwfpe.o) or indeed to leave it out altogether. However, unless you
+ know what you are doing this can easily render your machine
+ unbootable. Saying Y is the safe option.
+
+ You may say N here if you are going to load the Acorn FPEmulator
+ early in the bootup.
+
+CONFIG_FPE_FASTFPE
+ Say Y here to include the FAST floating point emulator in the kernel.
+ This is an experimental much faster emulator which now also has full
+ precision for the mantissa. It does not support any exceptions.
+ It is very simple, and approximately 3-6 times faster than NWFPE.
+
+ It should be sufficient for most programs. It may be not suitable
+ for scientific calculations, but you have to check this for yourself.
+ If you do not feel you need a faster FP emulation you should better
+ choose NWFPE.
+
+ It is also possible to say M to build the emulator as a module
+ (fastfpe.o). But keep in mind that you should only load the FP
+ emulator early in the bootup. You should never change from NWFPE to
+ FASTFPE or vice versa in an active system!
+
+CONFIG_DEBUG_ERRORS
+ This option controls verbose debugging information which can be
+ printed when the kernel detects an internal error. This debugging
+ information is useful to kernel hackers when tracking down problems,
+ but mostly meaningless to other people. It's safe to say Y unless
+ you are concerned with the code size or don't want to see these
+ messages.
+
+CONFIG_NO_FRAME_POINTER
+ If you say Y here, the resulting kernel will be slightly smaller and
+ faster. However, when a problem occurs with the kernel, the
+ information that is reported is severely limited. Most people
+ should say N here.
+
+CONFIG_DEBUG_USER
+ When a user program crashes due to an exception, the kernel can
+ print a brief message explaining what the problem was. This is
+ sometimes helpful for debugging but serves no purpose on a
+ production system. Most people should say N here.
+
+CONFIG_DEBUG_INFO
+ Say Y here to include source-level debugging information in the
+ `vmlinux' binary image. This is handy if you want to use gdb or
+ addr2line to debug the kernel. It has no impact on the in-memory
+ footprint of the running kernel but it can increase the amount of
+ time and disk space needed for compilation of the kernel. If in
+ doubt say N.
+
+CONFIG_DEBUG_LL
+ Say Y here to include definitions of printascii, printchar, printhex
+ in the kernel. This is helpful if you are debugging code that
+ executes before the console is initialized.
+
+CONFIG_NO_PGT_CACHE
+ Normally the kernel maintains a `quicklist' of preallocated
+ pagetable structures in order to increase performance. On machines
+ with very few pages this may however be a loss. Say Y here to
+ disable the pgtable cache.
+
+CONFIG_ARTHUR
+ Say Y here to include the kernel code necessary if you want to run
+ Acorn RISC OS/Arthur binaries under Linux. This code is still very
+ experimental; if this sounds frightening, say N and sleep in peace.
+ You can also say M here to compile this support as a module (which
+ will be called arthur.o).
+
+CONFIG_CMDLINE
+ On some architectures (EBSA110 and CATS), there is currently no way
+ for the boot loader to pass arguments to the kernel. For these
+ architectures, you should supply some command-line options at build
+ time by entering them here. As a minimum, you should specify the
+ memory size and the root device (e.g., mem=64M root=/dev/nfs).
+
+CONFIG_DEBUG_KERNEL
+ Say Y here if you are developing drivers or trying to debug and
+ identify kernel problems.
+
+CONFIG_DEBUG_SLAB
+ Say Y here to have the kernel do limited verification on memory
+ allocation as well as poisoning memory on free to catch use of freed
+ memory.
+
+CONFIG_DEBUG_SPINLOCK
+ Say Y here and build SMP to catch missing spinlock initialization
+ and certain other kinds of spinlock errors commonly made. This is
+ best used in conjunction with the NMI watchdog so that spinlock
+ deadlocks are also debuggable.
+
+CONFIG_DEBUG_BUGVERBOSE
+ Say Y here to make BUG() panics output the file name and line number
+ of the BUG call as well as the EIP and oops trace. This aids
+ debugging but costs about 70-100K of memory.
+
+CONFIG_ZBOOT_ROM
+ Say Y here if you intend to execute your compressed kernel image (zImage)
+ directly from ROM or flash. If unsure, say N.
+
+CONFIG_ZBOOT_ROM_TEXT
+ The base address for zImage. Unless you have special requirements, you
+ should not change this value.
+
+CONFIG_ZBOOT_ROM_BSS
+ The base address of 64KiB of read/write memory, which must be available
+ while the decompressor is running. Unless you have special requirements,
+ you should not change this value.
+
diff -urN linux-2.5.70-bk13/arch/arm26/Kconfig linux-2.5.70-bk14/arch/arm26/Kconfig
--- linux-2.5.70-bk13/arch/arm26/Kconfig 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/Kconfig 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,572 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "Linux Kernel Configuration"
+
+config ARM
+ bool
+ default y
+ help
+ The ARM series is a line of low-power-consumption RISC chip designs
+ licensed by ARM ltd and targeted at embedded applications and
+ handhelds such as the Compaq IPAQ. ARM-based PCs are no longer
+ manufactured, but legacy ARM-based PC hardware remains popular in
+ Europe. There is an ARM Linux project with a web page at
+ .
+
+config ARCH_ARCA5K
+ bool
+ default y
+
+config MMU
+ bool
+ default y
+
+config ARCH_ACORN
+ bool
+ default y
+
+config CPU_26
+ bool
+ default y
+
+config FIQ
+ bool
+ default y
+
+# 9 = 512 pages 8 = 256 pages 7 = 128 pages
+config FORCE_MAX_ZONEORDER
+ int
+ default 9
+
+config UID16
+ bool
+ default y
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config GENERIC_BUST_SPINLOCK
+ bool
+
+config GENERIC_ISA_DMA
+ bool
+
+source "init/Kconfig"
+
+
+menu "System Type"
+
+comment "Archimedes/A5000 Implementations (select only ONE)"
+
+config ARCH_ARC
+ bool "Archimedes"
+ depends on ARCH_ARCA5K
+ help
+ The Acorn Archimedes was an personal computer based on an 8K ARM2
+ processor, released in 1987. It supported 512K of RAM and 2 800K
+ floppy disks. Picture and more detailed specifications at
+ .
+
+config ARCH_A5K
+ bool "A5000"
+ depends on ARCH_ARCA5K
+ help
+ Say Y here to to support the Acorn A5000. Linux can support the
+ internal IDE disk and CD-ROM interface, serial and parallel port,
+ and the floppy drive. Note that on some A5000s the floppy is
+ plugged into the wrong socket on the motherboard.
+
+config PAGESIZE_16
+ bool "2MB physical memory"
+ depends on ARCH_ARCA5K
+ help
+ Say Y here if your Archimedes or A5000 system has only 2MB of
+ memory, otherwise say N. The resulting kernel will not run on a
+ machine with 4MB of memory.
+endmenu
+
+menu "General setup"
+
+# Compressed boot loader in ROM. Yes, we really want to ask about
+# TEXT and BSS so we preserve their values in the config files.
+config ZBOOT_ROM
+ bool "Compressed boot loader in ROM/flash"
+ help
+ Say Y here if you intend to execute your compressed kernel image (zImage)
+ directly from ROM or flash. If unsure, say N.
+
+config ZBOOT_ROM_TEXT
+ hex "Compressed ROM boot loader base address"
+ default "0"
+ help
+ The base address for zImage. Unless you have special requirements, you
+ should not change this value.
+
+config ZBOOT_ROM_BSS
+ hex "Compressed ROM boot loader BSS address"
+ default "0"
+ help
+ The base address of 64KiB of read/write memory, which must be available
+ while the decompressor is running. Unless you have special requirements,
+ you should not change this value.
+
+config HOTPLUG
+ bool "Support for hot-pluggable devices"
+ ---help---
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
+
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
+
+ Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
+ software (at ) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
+
+comment "At least one math emulation must be selected"
+
+config FPE_NWFPE
+ tristate "NWFPE math emulation"
+ ---help---
+ Say Y to include the NWFPE floating point emulator in the kernel.
+ This is necessary to run most binaries. Linux does not currently
+ support floating point hardware so you need to say Y here even if
+ your machine has an FPA or floating point co-processor podule.
+
+ It is also possible to say M to build the emulator as a module
+ (nwfpe) or indeed to leave it out altogether. However, unless you
+ know what you are doing this can easily render your machine
+ unbootable. Saying Y is the safe option.
+
+ You may say N here if you are going to load the Acorn FPEmulator
+ early in the bootup.
+
+choice
+ prompt "Kernel core (/proc/kcore) format"
+ default KCORE_ELF
+
+config KCORE_ELF
+ bool "ELF"
+ ---help---
+ If you enabled support for /proc file system then the file
+ /proc/kcore will contain the kernel core image. This can be used
+ in gdb:
+
+ $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
+
+ You have two choices here: ELF and A.OUT. Selecting ELF will make
+ /proc/kcore appear in ELF core format as defined by the Executable
+ and Linking Format specification. Selecting A.OUT will choose the
+ old "a.out" format which may be necessary for some old versions
+ of binutils or on some architectures.
+
+ This is especially useful if you have compiled the kernel with the
+ "-g" option to preserve debugging information. It is mainly used
+ for examining kernel data structures on the live kernel so if you
+ don't understand what this means or are not a kernel hacker, just
+ leave it at its default value ELF.
+
+config KCORE_AOUT
+ bool "A.OUT"
+ help
+ Not necessary unless you're using a very out-of-date binutils
+ version. You probably want KCORE_ELF.
+
+endchoice
+
+config BINFMT_AOUT
+ tristate "Kernel support for a.out binaries"
+ ---help---
+ A.out (Assembler.OUTput) is a set of formats for libraries and
+ executables used in the earliest versions of UNIX. Linux used the
+ a.out formats QMAGIC and ZMAGIC until they were replaced with the
+ ELF format.
+
+ As more and more programs are converted to ELF, the use for a.out
+ will gradually diminish. If you disable this option it will reduce
+ your kernel by one page. This is not much and by itself does not
+ warrant removing support. However its removal is a good idea if you
+ wish to ensure that absolutely none of your programs will use this
+ older executable format. If you don't know what to answer at this
+ point then answer Y. If someone told you "You need a kernel with
+ QMAGIC support" then you'll have to say Y here. You may answer M to
+ compile a.out support as a module and later load the module when you
+ want to use a program or library in a.out format. The module will be
+ called binfmt_aout. Saying M or N here is dangerous though,
+ because some crucial programs on your system might still be in A.OUT
+ format.
+
+config BINFMT_ELF
+ tristate "Kernel support for ELF binaries"
+ ---help---
+ ELF (Executable and Linkable Format) is a format for libraries and
+ executables used across different architectures and operating
+ systems. Saying Y here will enable your kernel to run ELF binaries
+ and enlarge it by about 13 KB. ELF support under Linux has now all
+ but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
+ because it is portable (this does *not* mean that you will be able
+ to run executables from different architectures or operating systems
+ however) and makes building run-time libraries very easy. Many new
+ executables are distributed solely in ELF format. You definitely
+ want to say Y here.
+
+ Information about ELF is contained in the ELF HOWTO available from
+ .
+
+ If you find that after upgrading from Linux kernel 1.2 and saying Y
+ here, you still can't run any ELF binaries (they just crash), then
+ you'll have to install the newest ELF runtime libraries, including
+ ld.so (check the file for location and
+ latest version).
+
+ If you want to compile this as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read . The module
+ will be called binfmt_elf. Saying M or N here is dangerous because
+ some crucial programs on your system might be in ELF format.
+
+config BINFMT_MISC
+ tristate "Kernel support for MISC binaries"
+ ---help---
+ If you say Y here, it will be possible to plug wrapper-driven binary
+ formats into the kernel. You will like this especially when you use
+ programs that need an interpreter to run like Java, Python or
+ Emacs-Lisp. It's also useful if you often run DOS executables under
+ the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
+ ). Once you have
+ registered such a binary class with the kernel, you can start one of
+ those programs simply by typing in its name at a shell prompt; Linux
+ will automatically feed it to the correct interpreter.
+
+ You can do other nice things, too. Read the file
+ to learn how to use this
+ feature, and for information about how
+ to include Java support.
+
+ You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
+ use this part of the kernel.
+
+ You may say M here for module support and later load the module when
+ you have use for it; the module is called binfmt_misc. If you
+ don't know what to answer at this point, say Y.
+
+config PREEMPT
+ bool "Preemptible Kernel (EXPERIMENTAL)"
+ depends on CPU_32 && EXPERIMENTAL
+ help
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ This allows applications to run more reliably even when the system is
+ under load.
+
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
+
+config ARTHUR
+ tristate "RISC OS personality"
+ depends on CPU_32
+ help
+ Say Y here to include the kernel code necessary if you want to run
+ Acorn RISC OS/Arthur binaries under Linux. This code is still very
+ experimental; if this sounds frightening, say N and sleep in peace.
+ You can also say M here to compile this support as a module (which
+ will be called arthur).
+
+config CMDLINE
+ string "Default kernel command string"
+ default ""
+ help
+ On some architectures (EBSA110 and CATS), there is currently no way
+ for the boot loader to pass arguments to the kernel. For these
+ architectures, you should supply some command-line options at build
+ time by entering them here. As a minimum, you should specify the
+ memory size and the root device (e.g., mem=64M root=/dev/nfs).
+
+endmenu
+
+source "drivers/parport/Kconfig"
+
+source "drivers/pnp/Kconfig"
+
+source "drivers/block/Kconfig"
+
+source "drivers/md/Kconfig"
+
+source "net/Kconfig"
+
+source "net/irda/Kconfig"
+
+menu "ATA/ATAPI/MFM/RLL support"
+
+config IDE
+ tristate "ATA/ATAPI/MFM/RLL support"
+ ---help---
+ If you say Y here, your kernel will be able to manage low cost mass
+ storage units such as ATA/(E)IDE and ATAPI units. The most common
+ cases are IDE hard drives and ATAPI CD-ROM drives.
+
+ If your system is pure SCSI and doesn't use these interfaces, you
+ can say N here.
+
+ Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
+ for mass storage units such as hard disks. It was designed by
+ Western Digital and Compaq Computer in 1984. It was then named
+ ST506. Quite a number of disks use the IDE interface.
+
+ AT Attachment (ATA) is the superset of the IDE specifications.
+ ST506 was also called ATA-1.
+
+ Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
+ ATA-3. It provides support for larger disks (up to 8.4GB by means of
+ the LBA standard), more disks (4 instead of 2) and for other mass
+ storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
+ ATA-4 and provides faster (and more CPU friendly) transfer modes
+ than previous PIO (Programmed processor Input/Output) from previous
+ ATA/IDE standards by means of fast DMA controllers.
+
+ ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
+ CD-ROM drives, similar in many respects to the SCSI protocol.
+
+ SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
+ designed in order to prevent data corruption and disk crash by
+ detecting pre hardware failure conditions (heat, access time, and
+ the like...). Disks built since June 1995 may follow this standard.
+ The kernel itself don't manage this; however there are quite a
+ number of user programs such as smart that can query the status of
+ SMART parameters disk.
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read . The module
+ will be called ide.
+
+ For further information, please read .
+
+ If unsure, say Y.
+
+source "drivers/ide/Kconfig"
+
+endmenu
+
+
+menu "SCSI support"
+
+config SCSI
+ tristate "SCSI support"
+ ---help---
+ If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
+ any other SCSI device under Linux, say Y and make sure that you know
+ the name of your SCSI host adapter (the card inside your computer
+ that "speaks" the SCSI protocol, also called SCSI controller),
+ because you will be asked for it.
+
+ You also need to say Y here if you want support for the parallel
+ port version of the 100 MB IOMEGA ZIP drive.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called scsi_mod. If you want to compile it as
+ a module, say M here and read and
+ . However, do not compile this as a
+ module if your root file system (the one containing the directory /)
+ is located on a SCSI device.
+
+source "drivers/scsi/Kconfig"
+
+endmenu
+
+source "drivers/isdn/Kconfig"
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source "drivers/input/Kconfig"
+
+source "drivers/char/Kconfig"
+
+config KBDMOUSE
+ bool
+ depends on ARCH_ACORN && BUSMOUSE=y
+ default y
+
+source "drivers/media/Kconfig"
+
+source "fs/Kconfig"
+
+source "drivers/video/Kconfig"
+
+menu "Sound"
+ depends on ARCH_ACORN
+
+config SOUND
+ tristate "Sound card support"
+ ---help---
+ If you have a sound card in your computer, i.e. if it can say more
+ than an occasional beep, say Y. Be sure to have all the information
+ about your sound card and its configuration down (I/O port,
+ interrupt and DMA channel), because you will be asked for it.
+
+ You want to read the Sound-HOWTO, available from
+ . General information about
+ the modular sound system is contained in the files
+ . The file
+ contains some slightly
+ outdated but still useful information as well.
+
+ If you have a PnP sound card and you want to configure it at boot
+ time using the ISA PnP tools (read
+ ), then you need to
+ compile the sound card support as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want)
+ and load that module after the PnP configuration is finished. To do
+ this, say M here and read as well
+ as ; the module will be
+ called soundcore.
+
+ I'm told that even without a sound card, you can make your computer
+ say more than an occasional beep, by programming the PC speaker.
+ Kernel patches and supporting utilities to do that are in the pcsp
+ package, available at .
+
+source "sound/Kconfig"
+
+endmenu
+
+source "drivers/misc/Kconfig"
+
+source "drivers/usb/Kconfig"
+
+source "net/bluetooth/Kconfig"
+
+
+menu "Kernel hacking"
+
+# RMK wants arm kernels compiled with frame pointers so hardwire this to y.
+# If you know what you are doing and are willing to live without stack
+# traces, you can get a slightly smaller kernel by setting this option to
+# n, but then RMK will have to kill you ;).
+config FRAME_POINTER
+ bool
+ default y
+ help
+ If you say N here, the resulting kernel will be slightly smaller and
+ faster. However, when a problem occurs with the kernel, the
+ information that is reported is severely limited. Most people
+ should say Y here.
+
+config DEBUG_USER
+ bool "Verbose user fault messages"
+ help
+ When a user program crashes due to an exception, the kernel can
+ print a brief message explaining what the problem was. This is
+ sometimes helpful for debugging but serves no purpose on a
+ production system. Most people should say N here.
+
+config DEBUG_INFO
+ bool "Include GDB debugging information in kernel binary"
+ help
+ Say Y here to include source-level debugging information in the
+ `vmlinux' binary image. This is handy if you want to use gdb or
+ addr2line to debug the kernel. It has no impact on the in-memory
+ footprint of the running kernel but it can increase the amount of
+ time and disk space needed for compilation of the kernel. If in
+ doubt say N.
+
+config DEBUG_KERNEL
+ bool "Kernel debugging"
+ help
+ Say Y here if you are developing drivers or trying to debug and
+ identify kernel problems.
+
+config DEBUG_SLAB
+ bool "Debug memory allocations"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to have the kernel do limited verification on memory
+ allocation as well as poisoning memory on free to catch use of freed
+ memory.
+
+config MAGIC_SYSRQ
+ bool "Magic SysRq key"
+ depends on DEBUG_KERNEL
+ help
+ If you say Y here, you will have some control over the system even
+ if the system crashes for example during kernel debugging (e.g., you
+ will be able to flush the buffer cache to disk, reboot the system
+ immediately or dump some status information). This is accomplished
+ by pressing various keys while holding SysRq (Alt+PrintScreen). It
+ also works on a serial console (on PC hardware at least), if you
+ send a BREAK and then within 5 seconds a command keypress. The
+ keys are documented in . Don't say Y
+ unless you really know what this hack does.
+
+config DEBUG_SPINLOCK
+ bool "Spinlock debugging"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here and build SMP to catch missing spinlock initialization
+ and certain other kinds of spinlock errors commonly made. This is
+ best used in conjunction with the NMI watchdog so that spinlock
+ deadlocks are also debuggable.
+
+config DEBUG_WAITQ
+ bool "Wait queue debugging"
+ depends on DEBUG_KERNEL
+
+config DEBUG_BUGVERBOSE
+ bool "Verbose BUG() reporting (adds 70K)"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to make BUG() panics output the file name and line number
+ of the BUG call as well as the EIP and oops trace. This aids
+ debugging but costs about 70-100K of memory.
+
+config DEBUG_ERRORS
+ bool "Verbose kernel error messages"
+ depends on DEBUG_KERNEL
+ help
+ This option controls verbose debugging information which can be
+ printed when the kernel detects an internal error. This debugging
+ information is useful to kernel hackers when tracking down problems,
+ but mostly meaningless to other people. It's safe to say Y unless
+ you are concerned with the code size or don't want to see these
+ messages.
+
+config KALLSYMS
+ bool "Load all symbols for debugging/kksymoops"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to let the kernel print out symbolic crash information and
+ symbolic stack backtraces. This increases the size of the kernel
+ somewhat, as all symbols have to be loaded into the kernel image.
+
+# These options are only for real kernel hackers who want to get their hands dirty.
+config DEBUG_LL
+ bool "Kernel low-level debugging functions"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to include definitions of printascii, printchar, printhex
+ in the kernel. This is helpful if you are debugging code that
+ executes before the console is initialized.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
diff -urN linux-2.5.70-bk13/arch/arm26/Makefile linux-2.5.70-bk14/arch/arm26/Makefile
--- linux-2.5.70-bk13/arch/arm26/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/Makefile 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,126 @@
+#
+# arch/arm26/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2001 by Russell King
+
+LDFLAGS_vmlinux :=-p -X
+LDFLAGS_BLOB :=--format binary
+AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
+OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
+GZFLAGS :=-9
+#CFLAGS +=-pipe
+CFLAGS :=$(CFLAGS:-O2=-Os)
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+CFLAGS +=-fno-omit-frame-pointer -mno-sched-prolog
+endif
+
+ifeq ($(CONFIG_DEBUG_INFO),y)
+CFLAGS +=-g
+endif
+
+# Force -mno-fpu to be passed to the assembler. Some versions of gcc don't
+# do this with -msoft-float
+CFLAGS_BOOT :=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
+CFLAGS +=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
+AFLAGS +=-mapcs-26 -mcpu=arm3 -mno-fpu -msoft-float -Wa,-mno-fpu
+
+#Default value
+DATAADDR := .
+
+ifeq ($(CONFIG_CPU_26),y)
+head-y := arch/arm26/machine/head.o arch/arm26/kernel/init_task.o
+LDFLAGS_BLOB += --oformat elf32-littlearm
+ ifeq ($(CONFIG_ROM_KERNEL),y)
+ DATAADDR := 0x02080000
+ textaddr-y := 0x03800000
+ else
+ textaddr-y := 0x02080000
+ endif
+endif
+
+TEXTADDR := $(textaddr-y)
+ifeq ($(incdir-y),)
+incdir-y :=
+endif
+INCDIR :=
+
+export MACHINE TEXTADDR GZFLAGS CFLAGS_BOOT
+
+# If we have a machine-specific directory, then include it in the build.
+core-y += arch/arm26/kernel/ arch/arm26/mm/ arch/arm26/machine/
+core-$(CONFIG_FPE_NWFPE) += arch/arm26/nwfpe/
+
+libs-y += arch/arm26/lib/
+
+# Default target when executing plain make
+all: zImage
+
+boot := arch/arm26/boot
+
+prepare: include/asm-$(ARCH)/asm_offsets.h
+CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
+
+
+.PHONY: maketools FORCE
+maketools: FORCE
+
+
+# Convert bzImage to zImage
+bzImage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
+
+zImage Image bootpImage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+zinstall install: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $@
+
+# We use MRPROPER_FILES and CLEAN_FILES now
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+# My testing targets (that short circuit a few dependencies)
+zImg:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
+Img:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/Image
+bp:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/bootpImage
+i:; $(Q)$(MAKE) $(build)=$(boot) install
+zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
+
+#
+# Configuration targets. Use these to select a
+# configuration for your architecture
+%_config:
+ @( \
+ CFG=$(@:_config=); \
+ if [ -f arch/arm26/def-configs/$$CFG ]; then \
+ [ -f .config ] && mv -f .config .config.old; \
+ cp arch/arm26/def-configs/$$CFG .config; \
+ echo "*** Default configuration for $$CFG installed"; \
+ echo "*** Next, you may run 'make oldconfig'"; \
+ else \
+ echo "$$CFG does not exist"; \
+ fi; \
+ )
+
+arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+ include/config/MARKER
+
+include/asm-$(ARCH)/asm_offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
+ $(call filechk,gen-asm-offsets)
+
+define archhelp
+ echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+ echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+ echo ' bootpImage - Combined zImage and initial RAM disk'
+ echo ' initrd - Create an initial image'
+ echo ' install - Install uncompressed kernel'
+ echo ' zinstall - Install compressed kernel'
+ echo ' Install using (your) ~/bin/installkernel or'
+ echo ' (distribution) /sbin/installkernel or'
+ echo ' install to $$(INSTALL_PATH) and run lilo'
+endef
diff -urN linux-2.5.70-bk13/arch/arm26/boot/Makefile linux-2.5.70-bk14/arch/arm26/boot/Makefile
--- linux-2.5.70-bk13/arch/arm26/boot/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/Makefile 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,69 @@
+#
+# arch/arm/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2002 Russell King
+#
+
+# Note: the following conditions must always be true:
+# ZRELADDR == virt_to_phys(TEXTADDR)
+# PARAMS_PHYS must be with 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+
+ zreladdr-y := 0x02080000
+params_phys-y := 0x0207c000
+initrd_phys-y := 0x02180000
+
+ZRELADDR := 0x02080000
+ZTEXTADDR := 0x0207c000
+PARAMS_PHYS := $(params_phys-y)
+INITRD_PHYS := 0x02180000
+
+# We now have a PIC decompressor implementation. Decompressors running
+# from RAM should not define ZTEXTADDR. Decompressors running directly
+# from ROM or Flash must define ZTEXTADDR (preferably via the config)
+# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
+ifeq ($(CONFIG_ZBOOT_ROM),y)
+ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
+else
+ZTEXTADDR := 0
+ZBSSADDR := ALIGN(4)
+endif
+
+export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
+
+targets := Image zImage bootpImage
+
+$(obj)/Image: vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: vmlinux FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+.PHONY: initrd
+initrd:
+ @test "$(INITRD_PHYS)" != "" || \
+ (echo This machine does not support INITRD; exit -1)
+ @test "$(INITRD)" != "" || \
+ (echo You must specify INITRD; exit -1)
+
+install: $(obj)/Image
+ $(CONFIG_SHELL) $(obj)/install.sh \
+ $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) \
+ $(obj)/Image System.map "$(INSTALL_PATH)"
+
+zinstall: $(obj)/zImage
+ $(CONFIG_SHELL) $(obj)/install.sh \
+ $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) \
+ $(obj)/zImage System.map "$(INSTALL_PATH)"
+
+subdir- := compressed
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/Makefile linux-2.5.70-bk14/arch/arm26/boot/compressed/Makefile
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/Makefile 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,50 @@
+#
+# linux/arch/arm26/boot/compressed/Makefile
+#
+# create a compressed vmlinuz image from the original vmlinux
+#
+# Note! ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported
+# from arch/arm26/boot/Makefile
+#
+
+HEAD = head.o
+OBJS = misc.o
+FONTC = drivers/video/console/font_acorn_8x8.c
+
+OBJS += ll_char_wr.o font.o
+CFLAGS_misc.o := -DPARAMS_PHYS=$(PARAMS_PHYS)
+
+targets := vmlinux vmlinux.lds piggy piggy.gz piggy.o font.o head.o $(OBJS)
+
+SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
+
+EXTRA_CFLAGS := $(CFLAGS_BOOT) -fpic
+EXTRA_AFLAGS := -traditional
+
+LDFLAGS_vmlinux := -p -X \
+ $(shell $(CC) $(CFLAGS)) -T
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
+ $(addprefix $(obj)/, $(OBJS)) FORCE
+ $(call if_changed,ld)
+ @:
+
+
+$(obj)/piggy: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/piggy.gz: $(obj)/piggy FORCE
+ $(call if_changed,gzip)
+
+LDFLAGS_piggy.o := -r -b binary
+$(obj)/piggy.o: $(obj)/piggy.gz FORCE
+ $(call if_changed,ld)
+
+$(obj)/font.o: $(FONTC)
+ $(CC) $(CFLAGS) -Dstatic= -c $(FONTC) -o $(obj)/font.o
+
+$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in Makefile arch/arm26/boot/Makefile .config
+ @sed "$(SEDFLAGS)" < $< > $@
+
+$(obj)/misc.o: $(obj)/misc.c $(obj)/uncompress.h lib/inflate.c
+
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/head.S linux-2.5.70-bk14/arch/arm26/boot/compressed/head.S
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/head.S 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/head.S 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,517 @@
+/*
+ * linux/arch/arm/boot/compressed/head.S
+ *
+ * Copyright (C) 1996-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+
+/*
+ * Debugging stuff
+ *
+ * Note that these macros must not contain any code which is not
+ * 100% relocatable. Any attempt to do so will result in a crash.
+ * Please select one of the following when turning on debugging.
+ */
+
+ .macro kputc,val
+ mov r0, \val
+ bl putc
+ .endm
+
+ .macro kphex,val,len
+ mov r0, \val
+ mov r1, #\len
+ bl phex
+ .endm
+
+ .macro debug_reloc_start
+ .endm
+
+ .macro debug_reloc_end
+ .endm
+
+ .section ".start", #alloc, #execinstr
+/*
+ * sort out different calling conventions
+ */
+ .align
+start:
+ .type start,#function
+ .rept 8
+ mov r0, r0
+ .endr
+
+ b 1f
+ .word 0x016f2818 @ Magic numbers to help the loader
+ .word start @ absolute load/run zImage address
+ .word _edata @ zImage end address
+1: mov r7, r1 @ save architecture ID
+ mov r8, #0 @ save r0
+ teqp pc, #0x0c000003 @ turn off interrupts
+
+ .text
+ adr r0, LC0
+ ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
+ subs r0, r0, r1 @ calculate the delta offset
+
+ teq r0, #0 @ if delta is zero, we're
+ beq not_relocated @ running at the address we
+ @ were linked at.
+
+ add r2, r2, r0 @ different address, so we
+ add r3, r3, r0 @ need to fix up various
+ add r5, r5, r0 @ pointers.
+ add r6, r6, r0
+ add ip, ip, r0
+ add sp, sp, r0
+
+1: ldr r1, [r6, #0] @ relocate entries in the GOT
+ add r1, r1, r0 @ table. This fixes up the
+ str r1, [r6], #4 @ C references.
+ cmp r6, ip
+ blo 1b
+
+not_relocated: 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
+ blo 1b
+
+ bl cache_on
+
+ mov r1, sp @ malloc space above stack
+ add r2, sp, #0x10000 @ 64k max
+
+/*
+ * Check to see if we will overwrite ourselves.
+ * r4 = final kernel address
+ * r5 = start of this image
+ * r2 = end of malloc space (and therefore this image)
+ * We basically want:
+ * r4 >= r2 -> OK
+ * r4 + image length <= r5 -> OK
+ */
+ cmp r4, r2
+ bhs wont_overwrite
+ add r0, r4, #4096*1024 @ 4MB largest kernel size
+ cmp r0, r5
+ bls wont_overwrite
+
+ mov r5, r2 @ decompress after malloc space
+ mov r0, r5
+ mov r3, r7
+ bl decompress_kernel
+
+ add r0, r0, #127
+ bic r0, r0, #127 @ align the kernel length
+/*
+ * r0 = decompressed kernel length
+ * r1-r3 = unused
+ * r4 = kernel execution address
+ * r5 = decompressed kernel start
+ * r6 = processor ID
+ * r7 = architecture ID
+ * r8-r14 = unused
+ */
+ add r1, r5, r0 @ end of decompressed kernel
+ adr r2, reloc_start
+ ldr r3, LC1
+ add r3, r2, r3
+1: ldmia r2!, {r8 - r13} @ copy relocation code
+ stmia r1!, {r8 - r13}
+ ldmia r2!, {r8 - r13}
+ stmia r1!, {r8 - r13}
+ cmp r2, r3
+ blo 1b
+
+ bl cache_clean_flush
+ add pc, r5, r0 @ call relocation code
+
+/*
+ * We're not in danger of overwriting ourselves. Do this the simple way.
+ *
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ */
+wont_overwrite: mov r0, r4
+ mov r3, r7
+ bl decompress_kernel
+ b call_kernel
+
+ .type LC0, #object
+LC0: .word LC0 @ r1
+ .word __bss_start @ r2
+ .word _end @ r3
+ .word _load_addr @ r4
+ .word _start @ r5
+ .word _got_start @ r6
+ .word _got_end @ ip
+ .word user_stack+4096 @ sp
+LC1: .word reloc_end - reloc_start
+ .size LC0, . - LC0
+
+/*
+ * Turn on the cache. We need to setup some page tables so that we
+ * can have both the I and D caches on.
+ *
+ * We place the page tables 16k down from the kernel execution address,
+ * and we hope that nothing else is using it. If we're using it, we
+ * will go pop!
+ *
+ * On entry,
+ * r4 = kernel execution address
+ * r6 = processor ID
+ * r7 = architecture number
+ * r8 = run-time address of "start"
+ * On exit,
+ * r1, r2, r3, r8, r9, r12 corrupted
+ * This routine must preserve:
+ * r4, r5, r6, r7
+ */
+ .align 5
+cache_on: mov r3, #8 @ cache_on function
+ b call_cache_fn
+
+__setup_mmu: sub r3, r4, #16384 @ Page directory size
+ bic r3, r3, #0xff @ Align the pointer
+ bic r3, r3, #0x3f00
+/*
+ * Initialise the page tables, turning on the cacheable and bufferable
+ * bits for the RAM area only.
+ */
+ mov r0, r3
+ mov r8, r0, lsr #18
+ mov r8, r8, lsl #18 @ start of RAM
+ add r9, r8, #0x10000000 @ a reasonable RAM size
+ mov r1, #0x12
+ orr r1, r1, #3 << 10
+ add r2, r3, #16384
+1: cmp r1, r8 @ if virt > start of RAM
+ orrhs r1, r1, #0x0c @ set cacheable, bufferable
+ cmp r1, r9 @ if virt > end of RAM
+ bichs r1, r1, #0x0c @ clear cacheable, bufferable
+ str r1, [r0], #4 @ 1:1 mapping
+ add r1, r1, #1048576
+ teq r0, r2
+ bne 1b
+/*
+ * If ever we are running from Flash, then we surely want the cache
+ * to be enabled also for our execution instance... We map 2MB of it
+ * so there is no map overlap problem for up to 1 MB compressed kernel.
+ * If the execution is in RAM then we would only be duplicating the above.
+ */
+ mov r1, #0x1e
+ orr r1, r1, #3 << 10
+ mov r2, pc, lsr #20
+ orr r1, r1, r2, lsl #20
+ add r0, r3, r2, lsl #2
+ str r1, [r0], #4
+ add r1, r1, #1048576
+ str r1, [r0]
+ mov pc, lr
+
+__armv4_cache_on:
+ mov r12, lr
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #0x1000 @ I-cache enable
+ orr r0, r0, #0x0030
+ b __common_cache_on
+
+__arm6_cache_on:
+ mov r12, lr
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
+ mov r0, #0x30
+__common_cache_on:
+#ifndef DEBUG
+ orr r0, r0, #0x000d @ Write buffer, mmu
+#endif
+ mov r1, #-1
+ mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c3, c0, 0 @ load domain access control
+ mcr p15, 0, r0, c1, c0, 0 @ load control register
+ mov pc, r12
+
+/*
+ * All code following this line is relocatable. It is relocated by
+ * the above code to the end of the decompressed kernel image and
+ * executed there. During this time, we have no stacks.
+ *
+ * r0 = decompressed kernel length
+ * r1-r3 = unused
+ * r4 = kernel execution address
+ * r5 = decompressed kernel start
+ * r6 = processor ID
+ * r7 = architecture ID
+ * r8-r14 = unused
+ */
+ .align 5
+reloc_start: add r8, r5, r0
+ debug_reloc_start
+ mov r1, r4
+1:
+ .rept 4
+ ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
+ stmia r1!, {r0, r2, r3, r9 - r13}
+ .endr
+
+ cmp r5, r8
+ blo 1b
+ debug_reloc_end
+
+call_kernel: bl cache_clean_flush
+ bl cache_off
+ mov r0, #0
+ mov r1, r7 @ restore architecture number
+ mov pc, r4 @ call kernel
+
+/*
+ * Here follow the relocatable cache support functions for the
+ * various processors. This is a generic hook for locating an
+ * entry and jumping to an instruction at the specified offset
+ * from the start of the block. Please note this is all position
+ * independent code.
+ *
+ * r1 = corrupted
+ * r2 = corrupted
+ * r3 = block offset
+ * r6 = corrupted
+ * r12 = corrupted
+ */
+
+call_cache_fn: adr r12, proc_types
+ mrc p15, 0, r6, c0, c0 @ get processor ID
+1: ldr r1, [r12, #0] @ get value
+ ldr r2, [r12, #4] @ get mask
+ eor r1, r1, r6 @ (real ^ match)
+ tst r1, r2 @ & mask
+ addeq pc, r12, r3 @ call cache function
+ add r12, r12, #4*5
+ b 1b
+
+/*
+ * Table for cache operations. This is basically:
+ * - CPU ID match
+ * - CPU ID mask
+ * - 'cache on' method instruction
+ * - 'cache off' method instruction
+ * - 'cache flush' method instruction
+ *
+ * We match an entry using: ((real_id ^ match) & mask) == 0
+ *
+ * Writethrough caches generally only need 'on' and 'off'
+ * methods. Writeback caches _must_ have the flush method
+ * defined.
+ */
+ .type proc_types,#object
+proc_types:
+ .word 0x41560600 @ ARM6/610
+ .word 0xffffffe0
+ b __arm6_cache_off @ works, but slow
+ b __arm6_cache_off
+ mov pc, lr
+@ b __arm6_cache_on @ untested
+@ b __arm6_cache_off
+@ b __armv3_cache_flush
+
+ .word 0x41007000 @ ARM7/710
+ .word 0xfff8fe00
+ b __arm7_cache_off
+ b __arm7_cache_off
+ mov pc, lr
+
+ .word 0x41807200 @ ARM720T (writethrough)
+ .word 0xffffff00
+ b __armv4_cache_on
+ b __armv4_cache_off
+ mov pc, lr
+
+ .word 0x41129200 @ ARM920T
+ .word 0xff00fff0
+ b __armv4_cache_on
+ b __armv4_cache_off
+ b __armv4_cache_flush
+
+ .word 0x4401a100 @ sa110 / sa1100
+ .word 0xffffffe0
+ b __armv4_cache_on
+ b __armv4_cache_off
+ b __armv4_cache_flush
+
+ .word 0x6901b110 @ sa1110
+ .word 0xfffffff0
+ b __armv4_cache_on
+ b __armv4_cache_off
+ b __armv4_cache_flush
+
+ .word 0x69050000 @ xscale
+ .word 0xffff0000
+ b __armv4_cache_on
+ b __armv4_cache_off
+ b __armv4_cache_flush
+
+ .word 0 @ unrecognised type
+ .word 0
+ mov pc, lr
+ mov pc, lr
+ mov pc, lr
+
+ .size proc_types, . - proc_types
+
+/*
+ * Turn off the Cache and MMU. ARMv3 does not support
+ * reading the control register, but ARMv4 does.
+ *
+ * On entry, r6 = processor ID
+ * On exit, r0, r1, r2, r3, r12 corrupted
+ * This routine must preserve: r4, r6, r7
+ */
+ .align 5
+cache_off: mov r3, #12 @ cache_off function
+ b call_cache_fn
+
+__armv4_cache_off:
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
+ mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
+ mov pc, lr
+
+__arm6_cache_off:
+ mov r0, #0x00000030 @ ARM6 control reg.
+ b __armv3_cache_off
+
+__arm7_cache_off:
+ mov r0, #0x00000070 @ ARM7 control reg.
+ b __armv3_cache_off
+
+__armv3_cache_off:
+ mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
+ mov pc, lr
+
+/*
+ * Clean and flush the cache to maintain consistency.
+ *
+ * On entry,
+ * r6 = processor ID
+ * On exit,
+ * r1, r2, r3, r12 corrupted
+ * This routine must preserve:
+ * r0, r4, r5, r6, r7
+ */
+ .align 5
+cache_clean_flush:
+ mov r3, #16
+ b call_cache_fn
+
+__armv4_cache_flush:
+ bic r1, pc, #31
+ add r2, r1, #65536 @ 2x the largest dcache size
+1: ldr r12, [r1], #32 @ s/w flush D cache
+ teq r1, r2
+ bne 1b
+
+ mcr p15, 0, r1, c7, c7, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__armv3_cache_flush:
+ mov r1, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mov pc, lr
+
+/*
+ * Various debugging routines for printing hex characters and
+ * memory, which again must be relocatable.
+ */
+#ifdef DEBUG
+ .type phexbuf,#object
+phexbuf: .space 12
+ .size phexbuf, . - phexbuf
+
+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: loadsp r3
+1: ldrb r2, [r0], #1
+ teq r2, #0
+ moveq pc, lr
+2: writeb r2
+ 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
+ loadsp r3
+ b 2b
+
+memdump: mov r12, r0
+ mov r10, lr
+ mov r11, #0
+2: mov r0, r11, lsl #2
+ add r0, r0, r12
+ mov r1, #8
+ 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
+#endif
+
+reloc_end:
+
+ .align
+ .section ".stack", "aw"
+user_stack: .space 4096
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/hw-bse.c linux-2.5.70-bk14/arch/arm26/boot/compressed/hw-bse.c
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/hw-bse.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/hw-bse.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,74 @@
+/*
+ * Bright Star Engineering Inc.
+ *
+ * code for readng parameters from the
+ * parameter blocks of the boot block
+ * flash memory
+ *
+ */
+
+static int strcmp(const char *s1, const char *s2)
+{
+ while (*s1 != '\0' && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+}
+
+struct pblk_t {
+ char type;
+ unsigned short size;
+};
+
+static char *bse_getflashparam(char *name) {
+ unsigned int esize;
+ char *q,*r;
+ unsigned char *p,*e;
+ struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
+ struct pblk_t *altpb = (struct pblk_t *) 0x00006000;
+ if (thepb->type&1) {
+ if (altpb->type&1) {
+ /* no valid param block */
+ return (char*)0;
+ } else {
+ /* altpb is valid */
+ struct pblk_t *tmp;
+ tmp = thepb;
+ thepb = altpb;
+ altpb = tmp;
+ }
+ }
+ p = (char*)thepb + sizeof(struct pblk_t);
+ e = p + thepb->size;
+ while (p < e) {
+ q = p;
+ esize = *p;
+ if (esize == 0xFF) break;
+ if (esize == 0) break;
+ if (esize > 127) {
+ esize = (esize&0x7F)<<8 | p[1];
+ q++;
+ }
+ q++;
+ r=q;
+ if (*r && ((name == 0) || (!strcmp(name,r)))) {
+ while (*q++) ;
+ return q;
+ }
+ p+=esize;
+ }
+ return (char*)0;
+}
+
+void bse_setup(void) {
+ /* extract the linux cmdline from flash */
+ char *name=bse_getflashparam("linuxboot");
+ char *x = (char *)0xc0000100;
+ if (name) {
+ while (*name) *x++=*name++;
+ }
+ *x=0;
+}
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/ll_char_wr.S linux-2.5.70-bk14/arch/arm26/boot/compressed/ll_char_wr.S
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/ll_char_wr.S 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/ll_char_wr.S 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,162 @@
+/*
+ * linux/arch/arm/lib/ll_char_wr.S
+ *
+ * Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
+ *
+ * 10-04-96 RMK Various cleanups & reduced register usage.
+ * 08-04-98 RMK Shifts re-ordered
+ */
+
+@ Regs: [] = corruptible
+@ {} = used
+@ () = do not use
+
+#include
+#include
+ .text
+
+#define BOLD 0x01
+#define ITALIC 0x02
+#define UNDERLINE 0x04
+#define FLASH 0x08
+#define INVERSE 0x10
+
+LC0: .word bytes_per_char_h
+ .word video_size_row
+ .word acorndata_8x8
+ .word con_charconvtable
+
+ENTRY(ll_write_char)
+ stmfd sp!, {r4 - r7, lr}
+@
+@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+ eor ip, r1, #UNDERLINE << 9
+/*
+ * calculate colours
+ */
+ tst r1, #INVERSE << 9
+ moveq r2, r1, lsr #16
+ moveq r3, r1, lsr #24
+ movne r2, r1, lsr #24
+ movne r3, r1, lsr #16
+ and r3, r3, #255
+ and r2, r2, #255
+/*
+ * calculate offset into character table
+ */
+ mov r1, r1, lsl #23
+ mov r1, r1, lsr #20
+/*
+ * calculate offset required for each row [maybe I should make this an argument to this fn.
+ * Have to see what the register usage is like in the calling routines.
+ */
+ adr r4, LC0
+ ldmia r4, {r4, r5, r6, lr}
+ ldr r4, [r4]
+ ldr r5, [r5]
+/*
+ * Go to resolution-dependent routine...
+ */
+ cmp r4, #4
+ blt Lrow1bpp
+ eor r2, r3, r2 @ Create eor mask to change colour from bg
+ orr r3, r3, r3, lsl #8 @ to fg.
+ orr r3, r3, r3, lsl #16
+ add r0, r0, r5, lsl #3 @ Move to bottom of character
+ add r1, r1, #7
+ ldrb r7, [r6, r1]
+ tst ip, #UNDERLINE << 9
+ eoreq r7, r7, #255
+ teq r4, #8
+ beq Lrow8bpplp
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+ orr r3, r3, r3, lsl #4
+Lrow4bpplp: ldr r7, [lr, r7, lsl #2]
+ mul r7, r2, r7
+ tst r1, #7 @ avoid using r7 directly after
+ eor ip, r3, r7
+ str ip, [r0, -r5]!
+ LOADREGS(eqfd, sp!, {r4 - r7, pc})
+ sub r1, r1, #1
+ ldrb r7, [r6, r1]
+ ldr r7, [lr, r7, lsl #2]
+ mul r7, r2, r7
+ tst r1, #7 @ avoid using r7 directly after
+ eor ip, r3, r7
+ str ip, [r0, -r5]!
+ subne r1, r1, #1
+ ldrneb r7, [r6, r1]
+ bne Lrow4bpplp
+ LOADREGS(fd, sp!, {r4 - r7, pc})
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+Lrow8bpplp: mov ip, r7, lsr #4
+ ldr ip, [lr, ip, lsl #2]
+ mul r4, r2, ip
+ and ip, r7, #15 @ avoid r4
+ ldr ip, [lr, ip, lsl #2] @ avoid r4
+ mul ip, r2, ip @ avoid r4
+ eor r4, r3, r4 @ avoid ip
+ tst r1, #7 @ avoid ip
+ sub r0, r0, r5 @ avoid ip
+ eor ip, r3, ip
+ stmia r0, {r4, ip}
+ LOADREGS(eqfd, sp!, {r4 - r7, pc})
+ sub r1, r1, #1
+ ldrb r7, [r6, r1]
+ mov ip, r7, lsr #4
+ ldr ip, [lr, ip, lsl #2]
+ mul r4, r2, ip
+ and ip, r7, #15 @ avoid r4
+ ldr ip, [lr, ip, lsl #2] @ avoid r4
+ mul ip, r2, ip @ avoid r4
+ eor r4, r3, r4 @ avoid ip
+ tst r1, #7 @ avoid ip
+ sub r0, r0, r5 @ avoid ip
+ eor ip, r3, ip
+ stmia r0, {r4, ip}
+ subne r1, r1, #1
+ ldrneb r7, [r6, r1]
+ bne Lrow8bpplp
+ LOADREGS(fd, sp!, {r4 - r7, pc})
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+Lrow1bpp: add r6, r6, r1
+ ldmia r6, {r4, r7}
+ tst ip, #INVERSE << 9
+ mvnne r4, r4
+ mvnne r7, r7
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ tst ip, #UNDERLINE << 9
+ mvneq r7, r7
+ strb r7, [r0], r5
+ LOADREGS(fd, sp!, {r4 - r7, pc})
+
+ .bss
+ENTRY(con_charconvtable)
+ .space 1024
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/misc.c linux-2.5.70-bk14/arch/arm26/boot/compressed/misc.c
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/misc.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/misc.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,316 @@
+/*
+ * misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre 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
+
+#include
+#include "uncompress.h"
+
+#ifdef STANDALONE_DEBUG
+#define puts printf
+#endif
+
+#define __ptr_t void *
+
+/*
+ * Optimised C version of memzero for the ARM.
+ */
+void __memzero (__ptr_t s, size_t n)
+{
+ union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
+ int i;
+
+ u.vp = s;
+
+ for (i = n >> 5; i > 0; i--) {
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ }
+
+ if (n & 1 << 4) {
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ }
+
+ if (n & 1 << 3) {
+ *u.ulp++ = 0;
+ *u.ulp++ = 0;
+ }
+
+ if (n & 1 << 2)
+ *u.ulp++ = 0;
+
+ if (n & 1 << 1) {
+ *u.ucp++ = 0;
+ *u.ucp++ = 0;
+ }
+
+ if (n & 1)
+ *u.ucp++ = 0;
+}
+
+static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
+ size_t __n)
+{
+ int i = 0;
+ unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+ for (i = __n >> 3; i > 0; i--) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 2) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 1) {
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1)
+ *d++ = *s++;
+
+ return __dest;
+}
+
+/*
+ * gzip delarations
+ */
+#define OF(args) args
+#define STATIC static
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize; /* valid bytes in inbuf */
+static unsigned inptr; /* index of next byte to be processed in inbuf */
+static unsigned outcnt; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern char input_data_end[];
+
+static uch *output_data;
+static ulg output_ptr;
+static ulg bytes_out;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+extern int end;
+static ulg free_mem_ptr;
+static ulg free_mem_ptr_end;
+
+#define HEAP_SIZE 0x2000
+
+#include "../../../../lib/inflate.c"
+
+#ifndef STANDALONE_DEBUG
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error\n");
+ if (free_mem_ptr <= 0) error("Memory error\n");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_ptr_end)
+ error("Out of memory");
+ return p;
+}
+
+static void free(void *where)
+{ /* gzip_mark & gzip_release do the free */
+}
+
+static void gzip_mark(void **ptr)
+{
+ arch_decomp_wdog();
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ arch_decomp_wdog();
+ free_mem_ptr = (long) *ptr;
+}
+#else
+static void gzip_mark(void **ptr)
+{
+}
+
+static void gzip_release(void **ptr)
+{
+}
+#endif
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf(void)
+{
+ if (insize != 0)
+ error("ran out of input data\n");
+
+ inbuf = input_data;
+ insize = &input_data_end[0] - &input_data[0];
+
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window(void)
+{
+ ulg c = crc;
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+ puts(".");
+}
+
+static void error(char *x)
+{
+ int ptr;
+
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+#ifndef STANDALONE_DEBUG
+
+ulg
+decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
+ int arch_id)
+{
+ 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;
+
+ arch_decomp_setup();
+
+ makecrc();
+ puts("Uncompressing Linux...");
+ gunzip();
+ puts(" done, booting the kernel.\n");
+ return output_ptr;
+}
+#else
+
+char output_buffer[1500*1024];
+
+int main()
+{
+ output_data = output_buffer;
+
+ makecrc();
+ puts("Uncompressing Linux...");
+ gunzip();
+ puts("done.\n");
+ return 0;
+}
+#endif
+
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/ofw-shark.c linux-2.5.70-bk14/arch/arm26/boot/compressed/ofw-shark.c
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/ofw-shark.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/ofw-shark.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,258 @@
+/*
+ * linux/arch/arm/boot/compressed/ofw-shark.c
+ *
+ * by Alexander Schulz
+ *
+ * This file is used to get some basic information
+ * about the memory layout of the shark we are running
+ * on. Memory is usually divided in blocks a 8 MB.
+ * And bootargs are copied from OpenFirmware.
+ */
+
+
+#include
+#include
+#include
+#include
+
+
+asmlinkage void
+create_params (unsigned long *buffer)
+{
+ /* Is there a better address? Also change in mach-shark/core.c */
+ struct tag *tag = (struct tag *) 0x08003000;
+ int j,i,m,k,nr_banks,size;
+ unsigned char *c;
+
+ /* Head of the taglist */
+ tag->hdr.tag = ATAG_CORE;
+ tag->hdr.size = tag_size(tag_core);
+ tag->u.core.flags = FLAG_READONLY;
+ tag->u.core.pagesize = PAGE_SIZE;
+ tag->u.core.rootdev = 0;
+
+ /* Build up one tagged block for each memory region */
+ size=0;
+ nr_banks=(unsigned int) buffer[0];
+ for (j=0;jhdr.tag = ATAG_MEM;
+ tag->hdr.size = tag_size(tag_mem32);
+ tag->u.mem.size = buffer[2*k+2];
+ tag->u.mem.start = buffer[2*k+1];
+
+ size += buffer[2*k+2];
+
+ buffer[2*k+1]=0xffffffff; /* mark as copied */
+ }
+
+ /* The command line */
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_CMDLINE;
+
+ c=(unsigned char *)(&buffer[34]);
+ j=0;
+ while (*c) tag->u.cmdline.cmdline[j++]=*c++;
+
+ tag->u.cmdline.cmdline[j]=0;
+ tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
+
+ /* Hardware revision */
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_REVISION;
+ tag->hdr.size = tag_size(tag_revision);
+ tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
+
+ /* End of the taglist */
+ tag = tag_next(tag);
+ tag->hdr.tag = 0;
+ tag->hdr.size = 0;
+}
+
+
+typedef int (*ofw_handle_t)(void *);
+
+/* Everything below is called with a wrong MMU setting.
+ * This means: no string constants, no initialization of
+ * arrays, no global variables! This is ugly but I didn't
+ * want to write this in assembler :-)
+ */
+
+int
+of_decode_int(const unsigned char *p)
+{
+ unsigned int i = *p++ << 8;
+ i = (i + *p++) << 8;
+ i = (i + *p++) << 8;
+ return (i + *p);
+}
+
+int
+OF_finddevice(ofw_handle_t openfirmware, char *name)
+{
+ unsigned int args[8];
+ char service[12];
+
+ service[0]='f';
+ service[1]='i';
+ service[2]='n';
+ service[3]='d';
+ service[4]='d';
+ service[5]='e';
+ service[6]='v';
+ service[7]='i';
+ service[8]='c';
+ service[9]='e';
+ service[10]='\0';
+
+ args[0]=(unsigned int)service;
+ args[1]=1;
+ args[2]=1;
+ args[3]=(unsigned int)name;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[4];
+}
+
+int
+OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
+{
+ unsigned int args[8];
+ char service[12];
+
+ service[0]='g';
+ service[1]='e';
+ service[2]='t';
+ service[3]='p';
+ service[4]='r';
+ service[5]='o';
+ service[6]='p';
+ service[7]='l';
+ service[8]='e';
+ service[9]='n';
+ service[10]='\0';
+
+ args[0] = (unsigned int)service;
+ args[1] = 2;
+ args[2] = 1;
+ args[3] = (unsigned int)handle;
+ args[4] = (unsigned int)prop;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[5];
+}
+
+int
+OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
+{
+ unsigned int args[8];
+ char service[8];
+
+ service[0]='g';
+ service[1]='e';
+ service[2]='t';
+ service[3]='p';
+ service[4]='r';
+ service[5]='o';
+ service[6]='p';
+ service[7]='\0';
+
+ args[0] = (unsigned int)service;
+ args[1] = 4;
+ args[2] = 1;
+ args[3] = (unsigned int)handle;
+ args[4] = (unsigned int)prop;
+ args[5] = (unsigned int)buf;
+ args[6] = buflen;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[7];
+}
+
+asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
+{
+ int phandle,i,mem_len,buffer[32];
+ char temp[15];
+
+ temp[0]='/';
+ temp[1]='m';
+ temp[2]='e';
+ temp[3]='m';
+ temp[4]='o';
+ temp[5]='r';
+ temp[6]='y';
+ temp[7]='\0';
+
+ phandle=OF_finddevice(o,temp);
+
+ temp[0]='r';
+ temp[1]='e';
+ temp[2]='g';
+ temp[3]='\0';
+
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ *nomr=mem_len >> 3;
+
+ for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
+
+ temp[0]='/';
+ temp[1]='c';
+ temp[2]='h';
+ temp[3]='o';
+ temp[4]='s';
+ temp[5]='e';
+ temp[6]='n';
+ temp[7]='\0';
+
+ phandle=OF_finddevice(o,temp);
+
+ temp[0]='b';
+ temp[1]='o';
+ temp[2]='o';
+ temp[3]='t';
+ temp[4]='a';
+ temp[5]='r';
+ temp[6]='g';
+ temp[7]='s';
+ temp[8]='\0';
+
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ if (mem_len > 128) mem_len=128;
+ for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
+ pointer[i+33]=0;
+
+ temp[0]='/';
+ temp[1]='\0';
+ phandle=OF_finddevice(o,temp);
+ temp[0]='b';
+ temp[1]='a';
+ temp[2]='n';
+ temp[3]='n';
+ temp[4]='e';
+ temp[5]='r';
+ temp[6]='-';
+ temp[7]='n';
+ temp[8]='a';
+ temp[9]='m';
+ temp[10]='e';
+ temp[11]='\0';
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ (unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
+}
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/uncompress.h linux-2.5.70-bk14/arch/arm26/boot/compressed/uncompress.h
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/uncompress.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/uncompress.h 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,111 @@
+/*
+ * linux/include/asm-arm/arch-arc/uncompress.h
+ *
+ * Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VIDMEM ((char *)0x02000000)
+
+int video_num_columns, video_num_lines, video_size_row;
+int white, bytes_per_char_h;
+extern unsigned long con_charconvtable[256];
+
+struct param_struct {
+ unsigned long page_size;
+ unsigned long nr_pages;
+ unsigned long ramdisk_size;
+ unsigned long mountrootrdonly;
+ unsigned long rootdev;
+ unsigned long video_num_cols;
+ unsigned long video_num_rows;
+ unsigned long video_x;
+ unsigned long video_y;
+ unsigned long memc_control_reg;
+ unsigned char sounddefault;
+ unsigned char adfsdrives;
+ unsigned char bytes_per_char_h;
+ unsigned char bytes_per_char_v;
+ unsigned long unused[256/4-11];
+};
+
+static struct param_struct *params = (struct param_struct *)0x0207c000;
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+ extern void ll_write_char(char *, unsigned long);
+ int x,y;
+ unsigned char c;
+ char *ptr;
+
+ x = params->video_x;
+ y = params->video_y;
+
+ while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
+ if ( c == '\n' ) {
+ x = 0;
+ if ( ++y >= video_num_lines ) {
+ y--;
+ }
+ } else {
+ ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
+ ll_write_char(ptr, c|(white<<16));
+ if ( ++x >= video_num_columns ) {
+ x = 0;
+ if ( ++y >= video_num_lines ) {
+ y--;
+ }
+ }
+ }
+ }
+
+ params->video_x = x;
+ params->video_y = y;
+}
+
+static void error(char *x);
+
+/*
+ * Setup for decompression
+ */
+static void arch_decomp_setup(void)
+{
+ int i;
+
+ video_num_lines = params->video_num_rows;
+ video_num_columns = params->video_num_cols;
+ bytes_per_char_h = params->bytes_per_char_h;
+ video_size_row = video_num_columns * bytes_per_char_h;
+ if (bytes_per_char_h == 4)
+ for (i = 0; i < 256; i++)
+ con_charconvtable[i] =
+ (i & 128 ? 1 << 0 : 0) |
+ (i & 64 ? 1 << 4 : 0) |
+ (i & 32 ? 1 << 8 : 0) |
+ (i & 16 ? 1 << 12 : 0) |
+ (i & 8 ? 1 << 16 : 0) |
+ (i & 4 ? 1 << 20 : 0) |
+ (i & 2 ? 1 << 24 : 0) |
+ (i & 1 ? 1 << 28 : 0);
+ else
+ for (i = 0; i < 16; i++)
+ con_charconvtable[i] =
+ (i & 8 ? 1 << 0 : 0) |
+ (i & 4 ? 1 << 8 : 0) |
+ (i & 2 ? 1 << 16 : 0) |
+ (i & 1 ? 1 << 24 : 0);
+
+ white = bytes_per_char_h == 8 ? 0xfc : 7;
+
+ if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_wdog()
diff -urN linux-2.5.70-bk13/arch/arm26/boot/compressed/vmlinux.lds.in linux-2.5.70-bk14/arch/arm26/boot/compressed/vmlinux.lds.in
--- linux-2.5.70-bk13/arch/arm26/boot/compressed/vmlinux.lds.in 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/compressed/vmlinux.lds.in 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,60 @@
+/*
+ * linux/arch/arm/boot/compressed/vmlinux.lds.in
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = LOAD_ADDR;
+ _load_addr = .;
+
+ . = TEXT_START;
+ _text = .;
+
+ .text : {
+ _start = .;
+ *(.start)
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ input_data = .;
+ arch/arm26/boot/compressed/piggy.o
+ input_data_end = .;
+ . = ALIGN(4);
+ }
+
+ _etext = .;
+
+ _got_start = .;
+ .got : { *(.got) }
+ _got_end = .;
+ .got.plt : { *(.got.plt) }
+ .data : { *(.data) }
+ _edata = .;
+
+ . = BSS_START;
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+
+ .stack (NOLOAD) : { *(.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 -urN linux-2.5.70-bk13/arch/arm26/boot/install.sh linux-2.5.70-bk14/arch/arm26/boot/install.sh
--- linux-2.5.70-bk13/arch/arm26/boot/install.sh 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/boot/install.sh 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,62 @@
+#!/bin/sh
+#
+# arch/arm/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Stolen from arch/arm/boot/install.sh by Ian Molton
+#
+# "make install" script for arm architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+ exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+ echo "Installing compressed kernel"
+ if [ -f $4/vmlinuz-$1 ]; then
+ mv $4/vmlinuz-$1 $4/vmlinuz.old
+ fi
+
+ if [ -f $4/System.map-$1 ]; then
+ mv $4/System.map-$1 $4/System.old
+ fi
+
+ cat $2 > $4/vmlinuz-$1
+ cp $3 $4/System.map-$1
+else
+# Normal install
+ echo "Installing normal kernel"
+ if [ -f $4/vmlinux-$1 ]; then
+ mv $4/vmlinux-$1 $4/vmlinux.old
+ fi
+
+ if [ -f $4/System.map ]; then
+ mv $4/System.map $4/System.old
+ fi
+
+ cat $2 > $4/vmlinux-$1
+ cp $3 $4/System.map
+fi
+
+if [ -x /sbin/loadmap ]; then
+ /sbin/loadmap --rdev /dev/ima
+else
+ echo "You have to install it yourself"
+fi
diff -urN linux-2.5.70-bk13/arch/arm26/config.in linux-2.5.70-bk14/arch/arm26/config.in
--- linux-2.5.70-bk13/arch/arm26/config.in 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/config.in 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,151 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+mainmenu_name "Linux Kernel Configuration"
+
+define_bool CONFIG_ARM y
+define_bool CONFIG_EISA n
+define_bool CONFIG_SBUS n
+define_bool CONFIG_MCA n
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
+define_bool CONFIG_GENERIC_ISA_DMA n
+
+source init/Config.in
+
+mainmenu_option next_comment
+comment 'System Type'
+
+define_bool CONFIG_ARCH_ARCA5K
+bool ' Archimedes' CONFIG_ARCH_ARC
+bool ' A5000' CONFIG_ARCH_A5K
+
+# Definitions to make life easier
+define_bool CONFIG_ARCH_ACORN y
+define_bool CONFIG_CPU_32 n
+define_bool CONFIG_CPU_26 y
+bool '2MB physical memory' CONFIG_PAGESIZE_16
+
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+define_bool CONFIG_FIQ y
+
+# Compressed boot loader in ROM. Yes, we really want to ask about
+# TEXT and BSS so we preserve their values in the config files.
+bool 'Compressed boot loader in ROM/flash' CONFIG_ZBOOT_ROM
+hex 'Compressed ROM boot loader base address' CONFIG_ZBOOT_ROM_TEXT 0
+hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
+
+comment 'At least one math emulation must be selected'
+define_bool CONFIG_FPE_NWFPE y
+choice 'Kernel core (/proc/kcore) format' \
+ "ELF CONFIG_KCORE_ELF \
+ A.OUT CONFIG_KCORE_AOUT" ELF
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+string 'Default kernel command string' CONFIG_CMDLINE ""
+
+define_bool CONFIG_ALIGNMENT_TRAP n
+endmenu
+
+source drivers/parport/Config.in
+source drivers/pnp/Config.in
+source drivers/block/Config.in
+source drivers/md/Config.in
+source drivers/acorn/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+ source net/Config.in
+
+ mainmenu_option next_comment
+ comment 'Network device support'
+
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
+ source drivers/net/Config.in
+ fi
+ endmenu
+fi
+
+mainmenu_option next_comment
+comment 'ATA/ATAPI/MFM/RLL support'
+
+tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+ source drivers/ide/Config.in
+else
+ define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+endmenu
+
+source drivers/isdn/Config.in
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+
+source drivers/char/Config.in
+if [ "$CONFIG_BUSMOUSE" = "y" ]; then
+ define_bool CONFIG_KBDMOUSE y
+fi
+
+source drivers/media/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ source drivers/video/Config.in
+ endmenu
+fi
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+ source sound/Config.in
+fi
+endmenu
+
+source drivers/misc/Config.in
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+# Always compile kernel with framepointer (until 2.4 real comes out)
+# Bug reports aren't much use without this.
+bool 'Compile kernel without frame pointer' CONFIG_NO_FRAME_POINTER
+bool 'Verbose user fault messages' CONFIG_DEBUG_USER
+bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
+
+bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
+dep_bool ' Debug memory allocations' CONFIG_DEBUG_SLAB $CONFIG_DEBUG_KERNEL
+dep_bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_DEBUG_KERNEL
+dep_bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK $CONFIG_DEBUG_KERNEL
+dep_bool ' Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL
+dep_bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL
+dep_bool ' Verbose kernel error messages' CONFIG_DEBUG_ERRORS $CONFIG_DEBUG_KERNEL
+# These options are only for real kernel hackers who want to get their hands dirty.
+dep_bool ' Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
+endmenu
+
+source security/Config.in
+source lib/Config.in
diff -urN linux-2.5.70-bk13/arch/arm26/defconfig linux-2.5.70-bk14/arch/arm26/defconfig
--- linux-2.5.70-bk13/arch/arm26/defconfig 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/defconfig 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,367 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+# CONFIG_NET is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+CONFIG_ARCH_ARC=y
+# CONFIG_ARCH_A5K is not set
+CONFIG_ARCH_ACORN=y
+# CONFIG_CPU_32 is not set
+CONFIG_CPU_26=y
+# CONFIG_PAGESIZE_16 is not set
+
+#
+# General setup
+#
+CONFIG_FIQ=y
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_FPE_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_ELF is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_CMDLINE=""
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Acorn-specific block devices
+#
+# CONFIG_BLK_DEV_FD1772 is not set
+# CONFIG_BLK_DEV_MFM is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_TSLIBDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_ACORN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+# CONFIG_ATOMWIDE_SERIAL is not set
+# CONFIG_DUALSP_SERIAL is not set
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_ALGOPCF=y
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_PROC is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_PSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC 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_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+# CONFIG_ACORN_PARTITION_EESOX is not set
+# CONFIG_ACORN_PARTITION_ICS is not set
+CONFIG_ACORN_PARTITION_ADFS=y
+# CONFIG_ACORN_PARTITION_POWERTEC is not set
+CONFIG_ACORN_PARTITION_RISCIX=y
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# Console Switches
+#
+# CONFIG_SWITCHES is not set
+# CONFIG_SWITCHES_SA1100 is not set
+# CONFIG_SWITCHES_UCB1X00 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/Makefile linux-2.5.70-bk14/arch/arm26/kernel/Makefile
--- linux-2.5.70-bk13/arch/arm26/kernel/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/Makefile 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+
+ENTRY_OBJ = entry.o
+
+# Object file lists.
+
+obj-y := arch.o compat.o dma.o entry.o irq.o \
+ process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
+ time.o traps.o ecard.o time-acorn.o dma.o \
+ ecard.o fiq.o time.o
+
+obj-$(CONFIG_FIQ) += fiq.o
+obj-$(CONFIG_MODULES) += armksyms.o
+
+extra-y := init_task.o
+
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/arch.c linux-2.5.70-bk14/arch/arm26/kernel/arch.c
--- linux-2.5.70-bk13/arch/arm26/kernel/arch.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/arch.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/kernel/arch.c
+ *
+ * Architecture specific fixups.
+ */
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+unsigned int vram_size;
+
+
+unsigned int memc_ctrl_reg;
+unsigned int number_mfm_drives;
+
+static int __init parse_tag_acorn(const struct tag *tag)
+{
+ memc_ctrl_reg = tag->u.acorn.memc_control_reg;
+ number_mfm_drives = tag->u.acorn.adfsdrives;
+ return 0;
+}
+
+__tagtable(ATAG_ACORN, parse_tag_acorn);
+
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/armksyms.c linux-2.5.70-bk14/arch/arm26/kernel/armksyms.c
--- linux-2.5.70-bk13/arch/arm26/kernel/armksyms.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/armksyms.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,233 @@
+/*
+ * linux/arch/arm26/kernel/armksyms.c
+ *
+ * Copyright (C) 2003 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+//#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(struct pt_regs *, struct user_fp_struct *);
+extern void inswb(unsigned int port, void *to, int len);
+extern void outswb(unsigned int port, const void *to, int len);
+
+extern void __bad_xchg(volatile void *ptr, int size);
+
+/*
+ * syscalls
+ */
+extern int sys_write(int, const char *, int);
+extern int sys_read(int, char *, int);
+extern int sys_lseek(int, off_t, int);
+extern int sys_exit(int);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __umoddi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umodsi3(void);
+extern void abort(void);
+
+extern void ret_from_exception(void);
+extern void fpundefinstr(void);
+extern void fp_enter(void);
+
+/*
+ * This has a special calling convention; it doesn't
+ * modify any of the usual registers, except for LR.
+ */
+extern void __do_softirq(void);
+
+#define EXPORT_SYMBOL_ALIAS(sym,orig) \
+ const char __kstrtab_##sym[] \
+ __attribute__((section(".kstrtab"))) = \
+ __MODULE_STRING(sym); \
+ const struct module_symbol __ksymtab_##sym \
+ __attribute__((section("__ksymtab"))) = \
+ { (unsigned long)&orig, __kstrtab_##sym };
+
+/*
+ * floating point math emulator support.
+ * These symbols will never change their calling convention...
+ */
+EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
+EXPORT_SYMBOL_ALIAS(fp_printk,printk);
+EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
+
+EXPORT_SYMBOL(fpundefinstr);
+EXPORT_SYMBOL(ret_from_exception);
+
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(kd_mksound);
+#endif
+
+EXPORT_SYMBOL_NOVERS(__do_softirq);
+
+ /* platform dependent support */
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(udelay);
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(system_rev);
+EXPORT_SYMBOL(system_serial_low);
+EXPORT_SYMBOL(system_serial_high);
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+EXPORT_SYMBOL(__bug);
+#endif
+EXPORT_SYMBOL(__bad_xchg);
+EXPORT_SYMBOL(__readwrite_bug);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(set_irq_type);
+EXPORT_SYMBOL(pm_idle);
+EXPORT_SYMBOL(pm_power_off);
+
+ /* processor dependencies */
+EXPORT_SYMBOL(__machine_arch_type);
+
+ /* networking */
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_ipv6_magic);
+
+ /* io */
+#ifndef __raw_readsb
+EXPORT_SYMBOL_NOVERS(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL_NOVERS(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL_NOVERS(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL_NOVERS(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL_NOVERS(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL_NOVERS(__raw_writesl);
+#endif
+
+ /* string / mem functions */
+EXPORT_SYMBOL_NOVERS(strcpy);
+EXPORT_SYMBOL_NOVERS(strncpy);
+EXPORT_SYMBOL_NOVERS(strcat);
+EXPORT_SYMBOL_NOVERS(strncat);
+EXPORT_SYMBOL_NOVERS(strcmp);
+EXPORT_SYMBOL_NOVERS(strncmp);
+EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strlen);
+EXPORT_SYMBOL_NOVERS(strnlen);
+EXPORT_SYMBOL_NOVERS(strpbrk);
+EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(__memzero);
+
+ /* user mem (segment) */
+EXPORT_SYMBOL(uaccess_kernel);
+EXPORT_SYMBOL(uaccess_user);
+
+EXPORT_SYMBOL_NOVERS(__get_user_1);
+EXPORT_SYMBOL_NOVERS(__get_user_2);
+EXPORT_SYMBOL_NOVERS(__get_user_4);
+EXPORT_SYMBOL_NOVERS(__get_user_8);
+
+EXPORT_SYMBOL_NOVERS(__put_user_1);
+EXPORT_SYMBOL_NOVERS(__put_user_2);
+EXPORT_SYMBOL_NOVERS(__put_user_4);
+EXPORT_SYMBOL_NOVERS(__put_user_8);
+
+ /* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
+
+ /* bitops */
+EXPORT_SYMBOL(_set_bit_le);
+EXPORT_SYMBOL(_test_and_set_bit_le);
+EXPORT_SYMBOL(_clear_bit_le);
+EXPORT_SYMBOL(_test_and_clear_bit_le);
+EXPORT_SYMBOL(_change_bit_le);
+EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_find_first_zero_bit_le);
+EXPORT_SYMBOL(_find_next_zero_bit_le);
+
+ /* elf */
+EXPORT_SYMBOL(elf_platform);
+EXPORT_SYMBOL(elf_hwcap);
+
+ /* syscalls */
+EXPORT_SYMBOL(sys_write);
+EXPORT_SYMBOL(sys_read);
+EXPORT_SYMBOL(sys_lseek);
+EXPORT_SYMBOL(sys_open);
+EXPORT_SYMBOL(sys_exit);
+EXPORT_SYMBOL(sys_wait4);
+
+ /* semaphores */
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
+EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
+
+#ifdef CONFIG_PREEMPT
+EXPORT_SYMBOL(kernel_flag);
+#endif
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/asm-offsets.c linux-2.5.70-bk14/arch/arm26/kernel/asm-offsets.c
--- linux-2.5.70-bk13/arch/arm26/kernel/asm-offsets.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/asm-offsets.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 1995-2001 Russell King
+ * 2001-2002 Keith Owens
+ * 2003-? Ian Molton
+ *
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
+#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
+#endif
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
+#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later.
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
+/* shame we can't detect the .1 or .2 releases */
+#warning GCC 2.95.2 and earlier miscompiles kernels.
+#endif
+
+/* Use marker if you need to separate the values later */
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+ DEFINE(TSK_USED_MATH, offsetof(struct task_struct, used_math));
+ DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+ BLANK();
+ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
+ DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
+ BLANK();
+ DEFINE(VM_EXEC, VM_EXEC);
+ BLANK();
+ BLANK();
+ DEFINE(PAGE_PRESENT, _PAGE_PRESENT);
+ DEFINE(PAGE_READONLY, _PAGE_READONLY);
+ DEFINE(PAGE_NOT_USER, _PAGE_NOT_USER);
+ DEFINE(PAGE_OLD, _PAGE_OLD);
+ DEFINE(PAGE_CLEAN, _PAGE_CLEAN);
+ BLANK();
+ DEFINE(PAGE_SZ, PAGE_SIZE);
+ BLANK();
+ DEFINE(SYS_ERROR0, 0x9f0000);
+ return 0;
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/compat.c linux-2.5.70-bk14/arch/arm26/kernel/compat.c
--- linux-2.5.70-bk13/arch/arm26/kernel/compat.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/compat.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/arm/kernel/compat.c
+ *
+ * Copyright (C) 2001 Russell King
+ * 2003 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * We keep the old params compatibility cruft in one place (here)
+ * so we don't end up with lots of mess around other places.
+ *
+ * NOTE:
+ * The old struct param_struct is deprecated, but it will be kept in
+ * the kernel for 5 years from now (2001). This will allow boot loaders
+ * to convert to the new struct tag way.
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+//#include
+
+/*
+ * Usage:
+ * - do not go blindly adding fields, add them at the end
+ * - when adding fields, don't rely on the address until
+ * a patch from me has been released
+ * - unused fields should be zero (for future expansion)
+ * - this structure is relatively short-lived - only
+ * guaranteed to contain useful data in setup_arch()
+ *
+ * This is the old deprecated way to pass parameters to the kernel
+ */
+struct param_struct {
+ union {
+ struct {
+ unsigned long page_size; /* 0 */
+ unsigned long nr_pages; /* 4 */
+ unsigned long ramdisk_size; /* 8 */
+ unsigned long flags; /* 12 */
+#define FLAG_READONLY 1
+#define FLAG_RDLOAD 4
+#define FLAG_RDPROMPT 8
+ unsigned long rootdev; /* 16 */
+ unsigned long video_num_cols; /* 20 */
+ unsigned long video_num_rows; /* 24 */
+ unsigned long video_x; /* 28 */
+ unsigned long video_y; /* 32 */
+ unsigned long memc_control_reg; /* 36 */
+ unsigned char sounddefault; /* 40 */
+ unsigned char adfsdrives; /* 41 */
+ unsigned char bytes_per_char_h; /* 42 */
+ unsigned char bytes_per_char_v; /* 43 */
+ unsigned long pages_in_bank[4]; /* 44 */
+ unsigned long pages_in_vram; /* 60 */
+ unsigned long initrd_start; /* 64 */
+ unsigned long initrd_size; /* 68 */
+ unsigned long rd_start; /* 72 */
+ unsigned long system_rev; /* 76 */
+ unsigned long system_serial_low; /* 80 */
+ unsigned long system_serial_high; /* 84 */
+ unsigned long mem_fclk_21285; /* 88 */
+ } s;
+ char unused[256];
+ } u1;
+ union {
+ char paths[8][128];
+ struct {
+ unsigned long magic;
+ char n[1024 - sizeof(unsigned long)];
+ } s;
+ } u2;
+ char commandline[COMMAND_LINE_SIZE];
+};
+
+static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size)
+{
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_MEM;
+ tag->hdr.size = tag_size(tag_mem32);
+ tag->u.mem.size = size;
+ tag->u.mem.start = start;
+
+ return tag;
+}
+
+static void __init build_tag_list(struct param_struct *params, void *taglist)
+{
+ struct tag *tag = taglist;
+
+ if (params->u1.s.page_size != PAGE_SIZE) {
+ printk(KERN_WARNING "Warning: bad configuration page, "
+ "trying to continue\n");
+ return;
+ }
+
+ printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
+
+ tag->hdr.tag = ATAG_CORE;
+ tag->hdr.size = tag_size(tag_core);
+ tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
+ tag->u.core.pagesize = params->u1.s.page_size;
+ tag->u.core.rootdev = params->u1.s.rootdev;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_RAMDISK;
+ tag->hdr.size = tag_size(tag_ramdisk);
+ tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) |
+ (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0);
+ tag->u.ramdisk.size = params->u1.s.ramdisk_size;
+ tag->u.ramdisk.start = params->u1.s.rd_start;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_INITRD;
+ tag->hdr.size = tag_size(tag_initrd);
+ tag->u.initrd.start = params->u1.s.initrd_start;
+ tag->u.initrd.size = params->u1.s.initrd_size;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_SERIAL;
+ tag->hdr.size = tag_size(tag_serialnr);
+ tag->u.serialnr.low = params->u1.s.system_serial_low;
+ tag->u.serialnr.high = params->u1.s.system_serial_high;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_REVISION;
+ tag->hdr.size = tag_size(tag_revision);
+ tag->u.revision.rev = params->u1.s.system_rev;
+
+ tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_ACORN;
+ tag->hdr.size = tag_size(tag_acorn);
+ tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg;
+ tag->u.acorn.vram_pages = params->u1.s.pages_in_vram;
+ tag->u.acorn.sounddefault = params->u1.s.sounddefault;
+ tag->u.acorn.adfsdrives = params->u1.s.adfsdrives;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_CMDLINE;
+ tag->hdr.size = (strlen(params->commandline) + 3 +
+ sizeof(struct tag_header)) >> 2;
+ strcpy(tag->u.cmdline.cmdline, params->commandline);
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_NONE;
+ tag->hdr.size = 0;
+
+ memmove(params, taglist, ((int)tag) - ((int)taglist) +
+ sizeof(struct tag_header));
+}
+
+void __init convert_to_tag_list(struct tag *tags)
+{
+ struct param_struct *params = (struct param_struct *)tags;
+ build_tag_list(params, ¶ms->u2);
+}
+
+void __init squash_mem_tags(struct tag *tag)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM)
+ tag->hdr.tag = ATAG_NONE;
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/dma.c linux-2.5.70-bk14/arch/arm26/kernel/dma.c
--- linux-2.5.70-bk13/arch/arm26/kernel/dma.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/dma.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/arm/kernel/dma.c
+ *
+ * Copyright (C) 1995-2000 Russell King
+ * 2003-? Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+
+#if MAX_DMA_CHANNELS > 0
+
+static dma_t dma_chan[MAX_DMA_CHANNELS];
+
+/*
+ * Get dma list for /proc/dma
+ */
+int get_dma_list(char *buf)
+{
+ dma_t *dma;
+ char *p = buf;
+ int i;
+
+ for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++)
+ if (dma->lock)
+ p += sprintf(p, "%2d: %14s %s\n", i,
+ dma->d_ops->type, dma->device_id);
+
+ return p - buf;
+}
+
+/*
+ * Request DMA channel
+ *
+ * On certain platforms, we have to allocate an interrupt as well...
+ */
+int request_dma(dmach_t channel, const char *device_id)
+{
+ dma_t *dma = dma_chan + channel;
+ int ret;
+
+ if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ goto bad_dma;
+
+ if (xchg(&dma->lock, 1) != 0)
+ goto busy;
+
+ dma->device_id = device_id;
+ dma->active = 0;
+ dma->invalid = 1;
+
+ ret = 0;
+ if (dma->d_ops->request)
+ ret = dma->d_ops->request(channel, dma);
+
+ if (ret)
+ xchg(&dma->lock, 0);
+
+ return ret;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
+ return -EINVAL;
+
+busy:
+ return -EBUSY;
+}
+
+/*
+ * Free DMA channel
+ *
+ * On certain platforms, we have to free interrupt as well...
+ */
+void free_dma(dmach_t channel)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ goto bad_dma;
+
+ if (dma->active) {
+ printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
+ dma->d_ops->disable(channel, dma);
+ dma->active = 0;
+ }
+
+ if (xchg(&dma->lock, 0) != 0) {
+ if (dma->d_ops->free)
+ dma->d_ops->free(channel, dma);
+ return;
+ }
+
+ printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
+ return;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
+}
+
+/* Set DMA Scatter-Gather list
+ */
+void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA SG while "
+ "DMA active\n", channel);
+
+ dma->sg = sg;
+ dma->sgcount = nr_sg;
+ dma->using_sg = 1;
+ dma->invalid = 1;
+}
+
+/* Set DMA address
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void set_dma_addr (dmach_t channel, unsigned long physaddr)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA address while "
+ "DMA active\n", channel);
+
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.__address = (char *)physaddr;//FIXME - not pretty
+ dma->using_sg = 0;
+ dma->invalid = 1;
+}
+
+/* Set DMA byte count
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void set_dma_count (dmach_t channel, unsigned long count)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA count while "
+ "DMA active\n", channel);
+
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.length = count;
+ dma->using_sg = 0;
+ dma->invalid = 1;
+}
+
+/* Set DMA direction mode
+ */
+void set_dma_mode (dmach_t channel, dmamode_t mode)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA mode while "
+ "DMA active\n", channel);
+
+ dma->dma_mode = mode;
+ dma->invalid = 1;
+}
+
+/* Enable DMA channel
+ */
+void enable_dma (dmach_t channel)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 0) {
+ dma->active = 1;
+ dma->d_ops->enable(channel, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
+ BUG();
+}
+
+/* Disable DMA channel
+ */
+void disable_dma (dmach_t channel)
+{
+ dma_t *dma = dma_chan + channel;
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 1) {
+ dma->active = 0;
+ dma->d_ops->disable(channel, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
+ BUG();
+}
+
+/*
+ * Is the specified DMA channel active?
+ */
+int dma_channel_active(dmach_t channel)
+{
+ return dma_chan[channel].active;
+}
+
+void set_dma_page(dmach_t channel, char pagenr)
+{
+ printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+}
+
+void set_dma_speed(dmach_t channel, int cycle_ns)
+{
+ dma_t *dma = dma_chan + channel;
+ int ret = 0;
+
+ if (dma->d_ops->setspeed)
+ ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
+ dma->speed = ret;
+}
+
+int get_dma_residue(dmach_t channel)
+{
+ dma_t *dma = dma_chan + channel;
+ int ret = 0;
+
+ if (dma->d_ops->residue)
+ ret = dma->d_ops->residue(channel, dma);
+
+ return ret;
+}
+
+void __init init_dma(void)
+{
+ arch_dma_init(dma_chan);
+}
+
+#else
+
+int request_dma(dmach_t channel, const char *device_id)
+{
+ return -EINVAL;
+}
+
+int get_dma_residue(dmach_t channel)
+{
+ return 0;
+}
+
+#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
+GLOBAL_ALIAS(disable_dma, get_dma_residue);
+GLOBAL_ALIAS(enable_dma, get_dma_residue);
+GLOBAL_ALIAS(free_dma, get_dma_residue);
+GLOBAL_ALIAS(get_dma_list, get_dma_residue);
+GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
+GLOBAL_ALIAS(set_dma_page, get_dma_residue);
+GLOBAL_ALIAS(set_dma_count, get_dma_residue);
+GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
+GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
+GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
+GLOBAL_ALIAS(init_dma, get_dma_residue);
+
+#endif
+
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_page);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(set_dma_sg);
+EXPORT_SYMBOL(set_dma_speed);
+
+EXPORT_SYMBOL(dma_spin_lock);
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/ecard.c linux-2.5.70-bk14/arch/arm26/kernel/ecard.c
--- linux-2.5.70-bk13/arch/arm26/kernel/ecard.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/ecard.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,899 @@
+/*
+ * linux/arch/arm26/kernel/ecard.c
+ *
+ * Copyright 1995-2001 Russell King
+ * Copyright 2003 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Find all installed expansion cards, and handle interrupts from them.
+ *
+ * Created from information from Acorns RiscOS3 PRMs
+ *
+ * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether
+ * podule slot.
+ * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
+ * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
+ * - cards can now register their own routine to control
+ * interrupts (recommended).
+ * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
+ * on reset from Linux. (Caused cards not to respond
+ * under RiscOS without hard reset).
+ * 15-Feb-1998 RMK Added DMA support
+ * 12-Sep-1998 RMK Added EASI support
+ * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
+ * 17-Apr-1999 RMK Support for EASI Type C cycles.
+ */
+#define ECARD_C
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+enum req {
+ req_readbytes,
+ req_reset
+};
+
+struct ecard_request {
+ enum req req;
+ ecard_t *ec;
+ unsigned int address;
+ unsigned int length;
+ unsigned int use_loader;
+ void *buffer;
+};
+
+struct expcard_blacklist {
+ unsigned short manufacturer;
+ unsigned short product;
+ const char *type;
+};
+
+static ecard_t *cards;
+static ecard_t *slot_to_expcard[MAX_ECARDS];
+static unsigned int ectcr;
+
+/* List of descriptions of cards which don't have an extended
+ * identification, or chunk directories containing a description.
+ */
+static struct expcard_blacklist __initdata blacklist[] = {
+ { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
+};
+
+asmlinkage extern int
+ecard_loader_reset(volatile unsigned char *pa, loader_t loader);
+asmlinkage extern int
+ecard_loader_read(int off, volatile unsigned char *pa, loader_t loader);
+
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec);
+
+static inline unsigned short
+ecard_getu16(unsigned char *v)
+{
+ return v[0] | v[1] << 8;
+}
+
+static inline signed long
+ecard_gets24(unsigned char *v)
+{
+ return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
+}
+
+static inline ecard_t *
+slot_to_ecard(unsigned int slot)
+{
+ return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
+}
+
+/* ===================== Expansion card daemon ======================== */
+/*
+ * Since the loader programs on the expansion cards need to be run
+ * in a specific environment, create a separate task with this
+ * environment up, and pass requests to this task as and when we
+ * need to.
+ *
+ * This should allow 99% of loaders to be called from Linux.
+ *
+ * From a security standpoint, we trust the card vendors. This
+ * may be a misplaced trust.
+ */
+#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+#define POD_INT_ADDR(x) ((volatile unsigned char *)\
+ ((BUS_ADDR((x)) - IO_BASE) + IO_START))
+
+static inline void ecard_task_reset(struct ecard_request *req)
+{
+ struct expansion_card *ec = req->ec;
+ if (ec->loader)
+ ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader);
+}
+
+static void
+ecard_task_readbytes(struct ecard_request *req)
+{
+ unsigned char *buf = (unsigned char *)req->buffer;
+ volatile unsigned char *base_addr =
+ (volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
+ unsigned int len = req->length;
+ unsigned int off = req->address;
+
+ if (req->ec->slot_no == 8) {
+ /*
+ * The card maintains an index which increments the address
+ * into a 4096-byte page on each access. We need to keep
+ * track of the counter.
+ */
+ static unsigned int index;
+ unsigned int page;
+
+ page = (off >> 12) * 4;
+ if (page > 256 * 4)
+ return;
+
+ off &= 4095;
+
+ /*
+ * If we are reading offset 0, or our current index is
+ * greater than the offset, reset the hardware index counter.
+ */
+ if (off == 0 || index > off) {
+ *base_addr = 0;
+ index = 0;
+ }
+
+ /*
+ * Increment the hardware index counter until we get to the
+ * required offset. The read bytes are discarded.
+ */
+ while (index < off) {
+ unsigned char byte;
+ byte = base_addr[page];
+ index += 1;
+ }
+
+ while (len--) {
+ *buf++ = base_addr[page];
+ index += 1;
+ }
+ } else {
+
+ if (!req->use_loader || !req->ec->loader) {
+ off *= 4;
+ while (len--) {
+ *buf++ = base_addr[off];
+ off += 4;
+ }
+ } else {
+ while(len--) {
+ /*
+ * The following is required by some
+ * expansion card loader programs.
+ */
+ *(unsigned long *)0x108 = 0;
+ *buf++ = ecard_loader_read(off++, base_addr,
+ req->ec->loader);
+ }
+ }
+ }
+
+}
+
+static void ecard_do_request(struct ecard_request *req)
+{
+ switch (req->req) {
+ case req_readbytes:
+ ecard_task_readbytes(req);
+ break;
+
+ case req_reset:
+ ecard_task_reset(req);
+ break;
+ }
+}
+
+/*
+ * On 26-bit processors, we don't need the kcardd thread to access the
+ * expansion card loaders. We do it directly.
+ */
+#define ecard_call(req) ecard_do_request(req)
+
+/* ======================= Mid-level card control ===================== */
+
+static void
+ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+{
+ struct ecard_request req;
+
+ req.req = req_readbytes;
+ req.ec = ec;
+ req.address = off;
+ req.length = len;
+ req.use_loader = useld;
+ req.buffer = addr;
+
+ ecard_call(&req);
+}
+
+int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+{
+ struct ex_chunk_dir excd;
+ int index = 16;
+ int useld = 0;
+
+ if (!ec->cid.cd)
+ return 0;
+
+ while(1) {
+ ecard_readbytes(&excd, ec, index, 8, useld);
+ index += 8;
+ if (c_id(&excd) == 0) {
+ if (!useld && ec->loader) {
+ useld = 1;
+ index = 0;
+ continue;
+ }
+ return 0;
+ }
+ if (c_id(&excd) == 0xf0) { /* link */
+ index = c_start(&excd);
+ continue;
+ }
+ if (c_id(&excd) == 0x80) { /* loader */
+ if (!ec->loader) {
+ ec->loader = (loader_t)kmalloc(c_len(&excd),
+ GFP_KERNEL);
+ if (ec->loader)
+ ecard_readbytes(ec->loader, ec,
+ (int)c_start(&excd),
+ c_len(&excd), useld);
+ else
+ return 0;
+ }
+ continue;
+ }
+ if (c_id(&excd) == id && num-- == 0)
+ break;
+ }
+
+ if (c_id(&excd) & 0x80) {
+ switch (c_id(&excd) & 0x70) {
+ case 0x70:
+ ecard_readbytes((unsigned char *)excd.d.string, ec,
+ (int)c_start(&excd), c_len(&excd),
+ useld);
+ break;
+ case 0x00:
+ break;
+ }
+ }
+ cd->start_offset = c_start(&excd);
+ memcpy(cd->d.string, excd.d.string, 256);
+ return 1;
+}
+
+/* ======================= Interrupt control ============================ */
+
+static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
+{
+}
+
+static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
+{
+}
+
+static int ecard_def_irq_pending(ecard_t *ec)
+{
+ return !ec->irqmask || ec->irqaddr[0] & ec->irqmask;
+}
+
+static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
+{
+ panic("ecard_def_fiq_enable called - impossible");
+}
+
+static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
+{
+ panic("ecard_def_fiq_disable called - impossible");
+}
+
+static int ecard_def_fiq_pending(ecard_t *ec)
+{
+ return !ec->fiqmask || ec->fiqaddr[0] & ec->fiqmask;
+}
+
+static expansioncard_ops_t ecard_default_ops = {
+ ecard_def_irq_enable,
+ ecard_def_irq_disable,
+ ecard_def_irq_pending,
+ ecard_def_fiq_enable,
+ ecard_def_fiq_disable,
+ ecard_def_fiq_pending
+};
+
+/*
+ * Enable and disable interrupts from expansion cards.
+ * (interrupts are disabled for these functions).
+ *
+ * They are not meant to be called directly, but via enable/disable_irq.
+ */
+static void ecard_irq_unmask(unsigned int irqnr)
+{
+ ecard_t *ec = slot_to_ecard(irqnr - 32);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->claimed && ec->ops->irqenable)
+ ec->ops->irqenable(ec, irqnr);
+ else
+ printk(KERN_ERR "ecard: rejecting request to "
+ "enable IRQs for %d\n", irqnr);
+ }
+}
+
+static void ecard_irq_mask(unsigned int irqnr)
+{
+ ecard_t *ec = slot_to_ecard(irqnr - 32);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->ops && ec->ops->irqdisable)
+ ec->ops->irqdisable(ec, irqnr);
+ }
+}
+
+static struct irqchip ecard_chip = {
+ .ack = ecard_irq_mask,
+ .mask = ecard_irq_mask,
+ .unmask = ecard_irq_unmask,
+};
+
+void ecard_enablefiq(unsigned int fiqnr)
+{
+ ecard_t *ec = slot_to_ecard(fiqnr);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->claimed && ec->ops->fiqenable)
+ ec->ops->fiqenable(ec, fiqnr);
+ else
+ printk(KERN_ERR "ecard: rejecting request to "
+ "enable FIQs for %d\n", fiqnr);
+ }
+}
+
+void ecard_disablefiq(unsigned int fiqnr)
+{
+ ecard_t *ec = slot_to_ecard(fiqnr);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->ops->fiqdisable)
+ ec->ops->fiqdisable(ec, fiqnr);
+ }
+}
+
+static void
+ecard_dump_irq_state(ecard_t *ec)
+{
+ printk(" %d: %sclaimed, ",
+ ec->slot_no,
+ ec->claimed ? "" : "not ");
+
+ if (ec->ops && ec->ops->irqpending &&
+ ec->ops != &ecard_default_ops)
+ printk("irq %spending\n",
+ ec->ops->irqpending(ec) ? "" : "not ");
+ else
+ printk("irqaddr %p, mask = %02X, status = %02X\n",
+ ec->irqaddr, ec->irqmask, *ec->irqaddr);
+}
+
+static void ecard_check_lockup(struct irqdesc *desc)
+{
+ static int last, lockup;
+ ecard_t *ec;
+
+ /*
+ * If the timer interrupt has not run since the last million
+ * unrecognised expansion card interrupts, then there is
+ * something seriously wrong. Disable the expansion card
+ * interrupts so at least we can continue.
+ *
+ * Maybe we ought to start a timer to re-enable them some time
+ * later?
+ */
+ if (last == jiffies) {
+ lockup += 1;
+ if (lockup > 1000000) {
+ printk(KERN_ERR "\nInterrupt lockup detected - "
+ "disabling all expansion card interrupts\n");
+
+ desc->chip->mask(IRQ_EXPANSIONCARD);
+
+ printk("Expansion card IRQ state:\n");
+
+ for (ec = cards; ec; ec = ec->next)
+ ecard_dump_irq_state(ec);
+ }
+ } else
+ lockup = 0;
+
+ /*
+ * If we did not recognise the source of this interrupt,
+ * warn the user, but don't flood the user with these messages.
+ */
+ if (!last || time_after(jiffies, (unsigned long)(last + 5*HZ))) {
+ last = jiffies;
+ printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
+ }
+}
+
+static void
+ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ ecard_t *ec;
+ int called = 0;
+
+ desc->chip->mask(irq);
+ for (ec = cards; ec; ec = ec->next) {
+ int pending;
+
+ if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+ continue;
+
+ if (ec->ops && ec->ops->irqpending)
+ pending = ec->ops->irqpending(ec);
+ else
+ pending = ecard_default_ops.irqpending(ec);
+
+ if (pending) {
+ struct irqdesc *d = irq_desc + ec->irq;
+ d->handle(ec->irq, d, regs);
+ called ++;
+ }
+ }
+ desc->chip->unmask(irq);
+
+ if (called == 0)
+ ecard_check_lockup(desc);
+}
+
+#define ecard_irqexp_handler NULL
+#define ecard_probeirqhw() (0)
+
+unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+{
+ unsigned long address = 0;
+ int slot = ec->slot_no;
+
+ if (ec->slot_no == 8)
+ return 0;
+
+ ectcr &= ~(1 << slot);
+
+ switch (type) {
+ case ECARD_MEMC:
+ if (slot < 4)
+ address = IO_EC_MEMC_BASE + (slot << 12);
+ break;
+
+ case ECARD_IOC:
+ if (slot < 4)
+ address = IO_EC_IOC_BASE + (slot << 12);
+ if (address)
+ address += speed << 17;
+ break;
+
+ default:
+ break;
+ }
+
+ return address;
+}
+
+static int ecard_prints(char *buffer, ecard_t *ec)
+{
+ char *start = buffer;
+
+ buffer += sprintf(buffer, " %d: %s ", ec->slot_no,
+ ec->type == ECARD_EASI ? "EASI" : " ");
+
+ if (ec->cid.id == 0) {
+ struct in_chunk_dir incd;
+
+ buffer += sprintf(buffer, "[%04X:%04X] ",
+ ec->cid.manufacturer, ec->cid.product);
+
+ if (!ec->card_desc && ec->cid.cd &&
+ ecard_readchunk(&incd, ec, 0xf5, 0)) {
+ ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
+
+ if (ec->card_desc)
+ strcpy((char *)ec->card_desc, incd.d.string);
+ }
+
+ buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
+ } else
+ buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id);
+
+ return buffer - start;
+}
+
+static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count)
+{
+ ecard_t *ec = cards;
+ off_t at = 0;
+ int len, cnt;
+
+ cnt = 0;
+ while (ec && count > cnt) {
+ len = ecard_prints(buf, ec);
+ at += len;
+ if (at >= pos) {
+ if (!*start) {
+ *start = buf + (pos - (at - len));
+ cnt = at - pos;
+ } else
+ cnt += len;
+ buf += len;
+ }
+ ec = ec->next;
+ }
+ return (count > cnt) ? cnt : count;
+}
+
+static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
+
+static void ecard_proc_init(void)
+{
+ proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
+ create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
+ get_ecard_dev_info);
+}
+
+#define ec_set_resource(ec,nr,st,sz,flg) \
+ do { \
+ (ec)->resource[nr].name = ec->dev.name; \
+ (ec)->resource[nr].start = st; \
+ (ec)->resource[nr].end = (st) + (sz) - 1; \
+ (ec)->resource[nr].flags = flg; \
+ } while (0)
+
+static void __init ecard_init_resources(struct expansion_card *ec)
+{
+ unsigned long base = PODSLOT_IOC0_BASE;
+ unsigned int slot = ec->slot_no;
+ int i;
+
+ if (slot < 4) {
+ ec_set_resource(ec, ECARD_RES_MEMC,
+ PODSLOT_MEMC_BASE + (slot << 14),
+ PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
+ }
+
+ for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
+ ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+ base + (slot << 14) + (i << 19),
+ PODSLOT_IOC_SIZE, IORESOURCE_MEM);
+ }
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+ if (ec->resource[i].start &&
+ request_resource(&iomem_resource, &ec->resource[i])) {
+ printk(KERN_ERR "%s: resource(s) not available\n",
+ ec->dev.bus_id);
+ ec->resource[i].end -= ec->resource[i].start;
+ ec->resource[i].start = 0;
+ }
+ }
+}
+
+static ssize_t ecard_show_irq(struct device *dev, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->irq);
+}
+
+static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
+
+static ssize_t ecard_show_dma(struct device *dev, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->dma);
+}
+
+static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
+
+static ssize_t ecard_show_resources(struct device *dev, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ char *str = buf;
+ int i;
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+ str += sprintf(str, "%08lx %08lx %08lx\n",
+ ec->resource[i].start,
+ ec->resource[i].end,
+ ec->resource[i].flags);
+
+ return str - buf;
+}
+
+static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
+
+/*
+ * Probe for an expansion card.
+ *
+ * If bit 1 of the first byte of the card is set, then the
+ * card does not exist.
+ */
+static int __init
+ecard_probe(int slot, card_type_t type)
+{
+ ecard_t **ecp;
+ ecard_t *ec;
+ struct ex_ecid cid;
+ int i, rc = -ENOMEM;
+
+ ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
+ if (!ec)
+ goto nomem;
+
+ memset(ec, 0, sizeof(ecard_t));
+
+ ec->slot_no = slot;
+ ec->type = type;
+ ec->irq = NO_IRQ;
+ ec->fiq = NO_IRQ;
+ ec->dma = NO_DMA;
+ ec->card_desc = NULL;
+ ec->ops = &ecard_default_ops;
+
+ rc = -ENODEV;
+ if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
+ goto nodev;
+
+ cid.r_zero = 1;
+ ecard_readbytes(&cid, ec, 0, 16, 0);
+ if (cid.r_zero)
+ goto nodev;
+
+ ec->cid.id = cid.r_id;
+ ec->cid.cd = cid.r_cd;
+ ec->cid.is = cid.r_is;
+ ec->cid.w = cid.r_w;
+ ec->cid.manufacturer = ecard_getu16(cid.r_manu);
+ ec->cid.product = ecard_getu16(cid.r_prod);
+ ec->cid.country = cid.r_country;
+ ec->cid.irqmask = cid.r_irqmask;
+ ec->cid.irqoff = ecard_gets24(cid.r_irqoff);
+ ec->cid.fiqmask = cid.r_fiqmask;
+ ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
+ ec->fiqaddr =
+ ec->irqaddr = (unsigned char *)ioaddr(ec->podaddr);
+
+ if (ec->cid.is) {
+ ec->irqmask = ec->cid.irqmask;
+ ec->irqaddr += ec->cid.irqoff;
+ ec->fiqmask = ec->cid.fiqmask;
+ ec->fiqaddr += ec->cid.fiqoff;
+ } else {
+ ec->irqmask = 1;
+ ec->fiqmask = 4;
+ }
+
+ for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
+ if (blacklist[i].manufacturer == ec->cid.manufacturer &&
+ blacklist[i].product == ec->cid.product) {
+ ec->card_desc = blacklist[i].type;
+ break;
+ }
+
+ snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
+ snprintf(ec->dev.name, sizeof(ec->dev.name), "ecard %04x:%04x",
+ ec->cid.manufacturer, ec->cid.product);
+ ec->dev.parent = NULL;
+ ec->dev.bus = &ecard_bus_type;
+ ec->dev.dma_mask = &ec->dma_mask;
+ ec->dma_mask = (u64)0xffffffff;
+
+ ecard_init_resources(ec);
+
+ /*
+ * hook the interrupt handlers
+ */
+ if (slot < 8) {
+ ec->irq = 32 + slot;
+ set_irq_chip(ec->irq, &ecard_chip);
+ set_irq_handler(ec->irq, do_level_IRQ);
+ set_irq_flags(ec->irq, IRQF_VALID);
+ }
+
+ for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
+
+ *ecp = ec;
+ slot_to_expcard[slot] = ec;
+
+ device_register(&ec->dev);
+ device_create_file(&ec->dev, &dev_attr_dma);
+ device_create_file(&ec->dev, &dev_attr_irq);
+ device_create_file(&ec->dev, &dev_attr_resource);
+
+ return 0;
+
+nodev:
+ kfree(ec);
+nomem:
+ return rc;
+}
+
+/*
+ * Initialise the expansion card system.
+ * Locate all hardware - interrupt management and
+ * actual cards.
+ */
+static int __init ecard_init(void)
+{
+ int slot, irqhw;
+
+ printk("Probing expansion cards\n");
+
+ for (slot = 0; slot < 8; slot ++) {
+ if (ecard_probe(slot, ECARD_EASI) == -ENODEV)
+ ecard_probe(slot, ECARD_IOC);
+ }
+
+ irqhw = ecard_probeirqhw();
+
+ set_irq_chained_handler(IRQ_EXPANSIONCARD,
+ irqhw ? ecard_irqexp_handler : ecard_irq_handler);
+
+ ecard_proc_init();
+
+ return 0;
+}
+
+subsys_initcall(ecard_init);
+
+/*
+ * ECARD "bus"
+ */
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
+{
+ int i;
+
+ for (i = 0; ids[i].manufacturer != 65535; i++)
+ if (ec->cid.manufacturer == ids[i].manufacturer &&
+ ec->cid.product == ids[i].product)
+ return ids + i;
+
+ return NULL;
+}
+
+static int ecard_drv_probe(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+ const struct ecard_id *id;
+ int ret;
+
+ id = ecard_match_device(drv->id_table, ec);
+
+ ecard_claim(ec);
+ ret = drv->probe(ec, id);
+ if (ret)
+ ecard_release(ec);
+ return ret;
+}
+
+static int ecard_drv_remove(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+
+ drv->remove(ec);
+ ecard_release(ec);
+
+ return 0;
+}
+
+/*
+ * Before rebooting, we must make sure that the expansion card is in a
+ * sensible state, so it can be re-detected. This means that the first
+ * page of the ROM must be visible. We call the expansion cards reset
+ * handler, if any.
+ */
+static void ecard_drv_shutdown(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+ struct ecard_request req;
+
+ if (drv->shutdown)
+ drv->shutdown(ec);
+ ecard_release(ec);
+ req.req = req_reset;
+ req.ec = ec;
+ ecard_call(&req);
+}
+
+int ecard_register_driver(struct ecard_driver *drv)
+{
+ drv->drv.bus = &ecard_bus_type;
+ drv->drv.probe = ecard_drv_probe;
+ drv->drv.remove = ecard_drv_remove;
+ drv->drv.shutdown = ecard_drv_shutdown;
+
+ return driver_register(&drv->drv);
+}
+
+void ecard_remove_driver(struct ecard_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+static int ecard_match(struct device *_dev, struct device_driver *_drv)
+{
+ struct expansion_card *ec = ECARD_DEV(_dev);
+ struct ecard_driver *drv = ECARD_DRV(_drv);
+ int ret;
+
+ if (drv->id_table) {
+ ret = ecard_match_device(drv->id_table, ec) != NULL;
+ } else {
+ ret = ec->cid.id == drv->id;
+ }
+
+ return ret;
+}
+
+struct bus_type ecard_bus_type = {
+ .name = "ecard",
+ .match = ecard_match,
+};
+
+static int ecard_bus_init(void)
+{
+ return bus_register(&ecard_bus_type);
+}
+
+postcore_initcall(ecard_bus_init);
+
+EXPORT_SYMBOL(ecard_readchunk);
+EXPORT_SYMBOL(ecard_address);
+EXPORT_SYMBOL(ecard_register_driver);
+EXPORT_SYMBOL(ecard_remove_driver);
+EXPORT_SYMBOL(ecard_bus_type);
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/entry.S linux-2.5.70-bk14/arch/arm26/kernel/entry.S
--- linux-2.5.70-bk13/arch/arm26/kernel/entry.S 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/entry.S 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,982 @@
+/* arch/arm26/kernel/entry.S
+ *
+ * Assembled from chunks of code in arch/arm
+ *
+ * Copyright (C) 2003 Ian Molton
+ *
+ */
+
+#include /* for CONFIG_ARCH_xxxx */
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+ .macro zero_fp
+#ifndef CONFIG_NO_FRAME_POINTER
+ mov fp, #0
+#endif
+ .endm
+
+ .text
+
+@ Bad Abort numbers
+@ -----------------
+@
+#define BAD_PREFETCH 0
+#define BAD_DATA 1
+#define BAD_ADDREXCPTN 2
+#define BAD_IRQ 3
+#define BAD_UNDEFINSTR 4
+
+#define PT_TRACESYS 0x00000002
+
+@ OS version number used in SWIs
+@ RISC OS is 0
+@ RISC iX is 8
+@
+#define OS_NUMBER 9
+#define ARMSWI_OFFSET 0x000f0000
+
+@
+@ Stack format (ensured by USER_* and SVC_*)
+@
+#define S_FRAME_SIZE 72
+#define S_OLD_R0 64
+#define S_PSR 60
+#define S_PC 60
+#define S_LR 56
+#define S_SP 52
+#define S_IP 48
+#define S_FP 44
+#define S_R10 40
+#define S_R9 36
+#define S_R8 32
+#define S_R7 28
+#define S_R6 24
+#define S_R5 20
+#define S_R4 16
+#define S_R3 12
+#define S_R2 8
+#define S_R1 4
+#define S_R0 0
+#define S_OFF 8
+
+ .macro save_user_regs
+ str r0, [sp, #-4]!
+ str lr, [sp, #-4]!
+ sub sp, sp, #15*4
+ stmia sp, {r0 - lr}^
+ mov r0, r0
+ .endm
+
+ .macro slow_restore_user_regs
+ ldmia sp, {r0 - lr}^
+ mov r0, r0
+ ldr lr, [sp, #15*4]
+ add sp, sp, #15*4+8
+ movs pc, lr
+ .endm
+
+ .macro fast_restore_user_regs
+ add sp, sp, #S_OFF
+ ldmib sp, {r1 - lr}^
+ mov r0, r0
+ ldr lr, [sp, #15*4]
+ add sp, sp, #15*4+8
+ movs pc, lr
+ .endm
+
+ .macro mask_pc, rd, rm
+ bic \rd, \rm, #PCMASK
+ .endm
+
+ .macro disable_irqs, temp
+ mov \temp, pc
+ orr \temp, \temp, #PSR_I_BIT
+ teqp \temp, #0
+ .endm
+
+ .macro enable_irqs, temp
+ mov \temp, pc
+ and \temp, \temp, #~PSR_I_BIT
+ teqp \temp, #0
+ .endm
+
+ .macro initialise_traps_extra
+ .endm
+
+ .macro get_thread_info, rd
+ mov \rd, sp, lsr #13
+ mov \rd, \rd, lsl #13
+ .endm
+
+ /*
+ * Like adr, but force SVC mode (if required)
+ */
+ .macro adrsvc, cond, reg, label
+ adr\cond \reg, \label
+ orr\cond \reg, \reg, #PSR_I_BIT | MODE_SVC26
+ .endm
+
+
+/*
+ * These are the registers used in the syscall handler, and allow us to
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * r7 is reserved for the system call number for thumb mode.
+ *
+ * Note that tbl == why is intentional.
+ *
+ * We must set at least "tsk" and "why" when calling ret_with_reschedule.
+ */
+scno .req r7 @ syscall number
+tbl .req r8 @ syscall table pointer
+why .req r8 @ Linux syscall (!= 0)
+tsk .req r9 @ current thread_info
+
+/*
+ * Get the system call number.
+ */
+ .macro get_scno
+ mask_pc lr, lr
+ ldr scno, [lr, #-4] @ get SWI instruction
+ .endm
+/*
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * We rely on the fact that R0 is at the bottom of the stack (due to
+ * slow/fast restore user regs).
+ */
+#if S_R0 != 0
+#error "Please fix"
+#endif
+
+/*
+ * Our do_softirq out of line code. See include/asm-arm/softirq.h for
+ * the calling assembly.
+ */
+ENTRY(__do_softirq)
+ stmfd sp!, {r0 - r3, ip, lr}
+ bl do_softirq
+ ldmfd sp!, {r0 - r3, ip, pc}
+
+ .align 5
+
+/*
+ * This is the fast syscall return path. We do as little as
+ * possible here, and this includes saving r0 back into the SVC
+ * stack.
+ */
+ret_fast_syscall:
+ disable_irqs r1 @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+ fast_restore_user_regs
+
+/*
+ * Ok, we need to do extra processing, enter the slow path.
+ */
+fast_work_pending:
+ str r0, [sp, #S_R0+S_OFF]! @ returned r0
+work_pending:
+ tst r1, #_TIF_NEED_RESCHED
+ bne work_resched
+ tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING
+ beq no_work_pending
+ mov r0, sp @ 'regs'
+ mov r2, why @ 'syscall'
+ bl do_notify_resume
+ disable_irqs r1 @ disable interrupts
+ b no_work_pending
+
+work_resched:
+ bl schedule
+/*
+ * "slow" syscall return path. "why" tells us if this was a real syscall.
+ */
+ENTRY(ret_to_user)
+ret_slow_syscall:
+ disable_irqs r1 @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ bne work_pending
+no_work_pending:
+ slow_restore_user_regs
+
+/*
+ * This is how we return from a fork.
+ */
+ENTRY(ret_from_fork)
+ bl schedule_tail
+ get_thread_info tsk
+ ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
+ mov why, #1
+ tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+ beq ret_slow_syscall
+ mov r1, sp
+ mov r0, #1 @ trace exit [IP = 1]
+ bl syscall_trace
+ b ret_slow_syscall
+
+#include
+
+/*=============================================================================
+ * SWI handler
+ *-----------------------------------------------------------------------------
+ */
+
+ .align 5
+ENTRY(vector_swi)
+ save_user_regs
+ zero_fp
+ get_scno
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr ip, __cr_alignment
+ ldr ip, [ip]
+ mcr p15, 0, ip, c1, c0 @ update control register
+#endif
+ enable_irqs ip
+
+ str r4, [sp, #-S_OFF]! @ push fifth arg
+
+ get_thread_info tsk
+ ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
+ bic scno, scno, #0xff000000 @ mask off SWI op-code
+ eor scno, scno, #OS_NUMBER << 20 @ check OS number
+ adr tbl, sys_call_table @ load syscall table pointer
+ tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+ bne __sys_trace
+
+ adrsvc al, lr, ret_fast_syscall @ return address
+ cmp scno, #NR_syscalls @ check upper syscall limit
+ ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+
+ add r1, sp, #S_OFF
+2: mov why, #0 @ no longer a real syscall
+ cmp scno, #ARMSWI_OFFSET
+ eor r0, scno, #OS_NUMBER << 20 @ put OS number back
+ bcs arm_syscall
+ b sys_ni_syscall @ not private func
+
+ /*
+ * This is the really slow path. We're going to be doing
+ * context switches, and waiting for our parent to respond.
+ */
+__sys_trace:
+ add r1, sp, #S_OFF
+ mov r0, #0 @ trace entry [IP = 0]
+ bl syscall_trace
+
+ adrsvc al, lr, __sys_trace_return @ return address
+ add r1, sp, #S_R0 + S_OFF @ pointer to regs
+ cmp scno, #NR_syscalls @ check upper syscall limit
+ ldmccia r1, {r0 - r3} @ have to reload r0 - r3
+ ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+ b 2b
+
+__sys_trace_return:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ mov r1, sp
+ mov r0, #1 @ trace exit [IP = 1]
+ bl syscall_trace
+ b ret_slow_syscall
+
+ .align 5
+#ifdef CONFIG_ALIGNMENT_TRAP
+ .type __cr_alignment, #object
+__cr_alignment:
+ .word cr_alignment
+#endif
+
+ .type sys_call_table, #object
+ENTRY(sys_call_table)
+#include
+
+/*============================================================================
+ * Special system call wrappers
+ */
+@ r0 = syscall number
+@ r5 = syscall table
+ .type sys_syscall, #function
+sys_syscall:
+ eor scno, r0, #OS_NUMBER << 20
+ cmp scno, #NR_syscalls @ check range
+ stmleia sp, {r5, r6} @ shuffle args
+ movle r0, r1
+ movle r1, r2
+ movle r2, r3
+ movle r3, r4
+ ldrle pc, [tbl, scno, lsl #2]
+ b sys_ni_syscall
+
+sys_fork_wrapper:
+ add r0, sp, #S_OFF
+ b sys_fork
+
+sys_vfork_wrapper:
+ add r0, sp, #S_OFF
+ b sys_vfork
+
+sys_execve_wrapper:
+ add r3, sp, #S_OFF
+ b sys_execve
+
+sys_clone_wapper:
+ add r2, sp, #S_OFF
+ b sys_clone
+
+sys_sigsuspend_wrapper:
+ add r3, sp, #S_OFF
+ b sys_sigsuspend
+
+sys_rt_sigsuspend_wrapper:
+ add r2, sp, #S_OFF
+ b sys_rt_sigsuspend
+
+sys_sigreturn_wrapper:
+ add r0, sp, #S_OFF
+ b sys_sigreturn
+
+sys_rt_sigreturn_wrapper:
+ add r0, sp, #S_OFF
+ b sys_rt_sigreturn
+
+sys_sigaltstack_wrapper:
+ ldr r2, [sp, #S_OFF + S_SP]
+ b do_sigaltstack
+
+/*
+ * Note: off_4k (r5) is always units of 4K. If we can't do the requested
+ * offset, we return EINVAL. FIXME - this lost some stuff from arm32 to
+ * ifdefs. check it out.
+ */
+sys_mmap2:
+ tst r5, #((1 << (PAGE_SHIFT - 12)) - 1)
+ moveq r5, r5, lsr #PAGE_SHIFT - 12
+ streq r5, [sp, #4]
+ beq do_mmap2
+ mov r0, #-EINVAL
+ RETINSTR(mov,pc, lr)
+
+/*
+ * Design issues:
+ * - We have several modes that each vector can be called from,
+ * each with its own set of registers. On entry to any vector,
+ * we *must* save the registers used in *that* mode.
+ *
+ * - This code must be as fast as possible.
+ *
+ * There are a few restrictions on the vectors:
+ * - the SWI vector cannot be called from *any* non-user mode
+ *
+ * - the FP emulator is *never* called from *any* non-user mode undefined
+ * instruction.
+ *
+ */
+
+ .text
+
+ .equ ioc_base_high, IOC_BASE & 0xff000000
+ .equ ioc_base_low, IOC_BASE & 0x00ff0000
+ .macro disable_fiq
+ mov r12, #ioc_base_high
+ .if ioc_base_low
+ orr r12, r12, #ioc_base_low
+ .endif
+ strb r12, [r12, #0x38] @ Disable FIQ register
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, base
+ mov r4, #ioc_base_high @ point at IOC
+ .if ioc_base_low
+ orr r4, r4, #ioc_base_low
+ .endif
+ ldrb \irqnr, [r4, #0x24] @ get high priority first
+ adr \base, irq_prio_h
+ teq \irqnr, #0
+ ldreqb \irqnr, [r4, #0x14] @ get low priority
+ adreq \base, irq_prio_l
+ .endm
+
+/*
+ * Interrupt table (incorporates priority)
+ */
+ .macro irq_prio_table
+irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .endm
+
+#if 1
+/* FIXME (well, ok, dont - but its easy to grep for :) */
+/*
+ * Uncomment these if you wish to get more debugging into about data aborts.
+ */
+#define FAULT_CODE_LDRSTRPOST 0x80
+#define FAULT_CODE_LDRSTRPRE 0x40
+#define FAULT_CODE_LDRSTRREG 0x20
+#define FAULT_CODE_LDMSTM 0x10
+#define FAULT_CODE_LDCSTC 0x08
+#endif
+#define FAULT_CODE_PREFETCH 0x04
+#define FAULT_CODE_WRITE 0x02
+#define FAULT_CODE_FORCECOW 0x01
+
+#define SVC_SAVE_ALL \
+ str sp, [sp, #-16]! ;\
+ str lr, [sp, #8] ;\
+ str lr, [sp, #4] ;\
+ stmfd sp!, {r0 - r12} ;\
+ mov r0, #-1 ;\
+ str r0, [sp, #S_OLD_R0] ;\
+ zero_fp
+
+#define SVC_IRQ_SAVE_ALL \
+ str sp, [sp, #-16]! ;\
+ str lr, [sp, #4] ;\
+ ldr lr, .LCirq ;\
+ ldr lr, [lr] ;\
+ str lr, [sp, #8] ;\
+ stmfd sp!, {r0 - r12} ;\
+ mov r0, #-1 ;\
+ str r0, [sp, #S_OLD_R0] ;\
+ zero_fp
+
+#define SVC_RESTORE_ALL \
+ ldmfd sp, {r0 - pc}^
+
+/*=============================================================================
+ * Undefined FIQs
+ *-----------------------------------------------------------------------------
+ */
+_unexp_fiq: ldr sp, .LCfiq
+ mov r12, #IOC_BASE
+ strb r12, [r12, #0x38] @ Disable FIQ register
+ teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_SVC26
+ mov r0, r0
+ stmfd sp!, {r0 - r3, ip, lr}
+ adr r0, Lfiqmsg
+ bl printk
+ ldmfd sp!, {r0 - r3, ip, lr}
+ teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_FIQ26
+ mov r0, r0
+ movs pc, lr
+
+Lfiqmsg: .ascii "*** Unexpected FIQ\n\0"
+ .align
+
+.LCfiq: .word __temp_fiq
+.LCirq: .word __temp_irq
+
+/*=============================================================================
+ * Undefined instruction handler
+ *-----------------------------------------------------------------------------
+ * Handles floating point instructions
+ */
+vector_undefinstr:
+ tst lr,#3
+ bne __und_svc
+ save_user_regs
+ zero_fp
+ teqp pc, #PSR_I_BIT | MODE_SVC26
+.Lbug_undef:
+ ldr r4, .LC2
+ ldr pc, [r4] @ Call FP module USR entry point
+
+ .globl fpundefinstr
+fpundefinstr: @ Called by FP module on undefined instr
+ mov r0, lr
+ mov r1, sp
+ teqp pc, #MODE_SVC26
+ bl do_undefinstr
+ b ret_from_exception @ Normal FP exit
+
+__und_svc: SVC_SAVE_ALL @ Non-user mode
+ mask_pc r0, lr
+ and r2, lr, #3
+ sub r0, r0, #4
+ mov r1, sp
+ bl do_undefinstr
+ SVC_RESTORE_ALL
+
+#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
+ /* The FPE is always present */
+ .equ fpe_not_present, 0
+#else
+/* We get here if an undefined instruction happens and the floating
+ * point emulator is not present. If the offending instruction was
+ * a WFS, we just perform a normal return as if we had emulated the
+ * operation. This is a hack to allow some basic userland binaries
+ * to run so that the emulator module proper can be loaded. --philb
+ */
+fpe_not_present:
+ adr r10, wfs_mask_data
+ ldmia r10, {r4, r5, r6, r7, r8}
+ ldr r10, [sp, #S_PC] @ Load PC
+ sub r10, r10, #4
+ mask_pc r10, r10
+ ldrt r10, [r10] @ get instruction
+ and r5, r10, r5
+ teq r5, r4 @ Is it WFS?
+ beq ret_from_exception
+ and r5, r10, r8
+ teq r5, r6 @ Is it LDF/STF on sp or fp?
+ teqne r5, r7
+ bne fpundefinstr
+ tst r10, #0x00200000 @ Does it have WB
+ beq ret_from_exception
+ and r4, r10, #255 @ get offset
+ and r6, r10, #0x000f0000
+ tst r10, #0x00800000 @ +/-
+ ldr r5, [sp, r6, lsr #14] @ Load reg
+ rsbeq r4, r4, #0
+ add r5, r5, r4, lsl #2
+ str r5, [sp, r6, lsr #14] @ Save reg
+ b ret_from_exception
+
+wfs_mask_data: .word 0x0e200110 @ WFS/RFS
+ .word 0x0fef0fff
+ .word 0x0d0d0100 @ LDF [sp]/STF [sp]
+ .word 0x0d0b0100 @ LDF [fp]/STF [fp]
+ .word 0x0f0f0f00
+#endif
+
+.LC2: .word fp_enter
+
+/*=============================================================================
+ * Prefetch abort handler
+ *-----------------------------------------------------------------------------
+ */
+
+/* remember: lr = USR pc */
+vector_prefetch:
+ sub lr, lr, #4
+ tst lr, #3
+ bne __pabt_invalid
+ save_user_regs
+ teqp pc, #MODE_SVC26
+ mask_pc r0, lr @ Address of abort
+ mov r1, sp @ Tasks registers
+ bl do_PrefetchAbort
+ teq r0, #0 @ If non-zero, we believe this abort..
+ bne ret_from_exception
+#ifdef DEBUG_UNDEF
+ adr r0, t
+ bl printk
+#endif
+ ldr lr, [sp,#S_PC] @ program to test this on. I think its
+ b .Lbug_undef @ broken at the moment though!)
+
+__pabt_invalid: SVC_SAVE_ALL
+ mov r0, sp @ Prefetch aborts are definitely *not*
+ mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant
+ and r2, lr, #3 @ recover from this problem.
+ b bad_mode
+
+#ifdef DEBUG_UNDEF
+t: .ascii "*** undef ***\r\n\0"
+ .align
+#endif
+
+/*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen).
+ * In order to debug the reason for address exceptions in non-user modes,
+ * we have to obtain all the registers so that we can see what's going on.
+ */
+
+vector_addrexcptn:
+ sub lr, lr, #8
+ tst lr, #3
+ bne Laddrexcptn_not_user
+ save_user_regs
+ teq pc, #MODE_SVC26
+ mask_pc r0, lr @ Point to instruction
+ mov r1, sp @ Point to registers
+ mov r2, #0x400
+ mov lr, pc
+ bl do_excpt
+ b ret_from_exception
+
+Laddrexcptn_not_user:
+ SVC_SAVE_ALL
+ and r2, lr, #3
+ teq r2, #3
+ bne Laddrexcptn_illegal_mode
+ teqp pc, #MODE_SVC26
+ mask_pc r0, lr
+ mov r1, sp
+ orr r2, r2, #0x400
+ bl do_excpt
+ ldmia sp, {r0 - lr} @ I cant remember the reason I changed this...
+ add sp, sp, #15*4
+ movs pc, lr
+
+Laddrexcptn_illegal_mode:
+ mov r0, sp
+ str lr, [sp, #-4]!
+ orr r1, r2, #PSR_I_BIT | PSR_F_BIT
+ teqp r1, #0 @ change into mode (wont be user mode)
+ mov r0, r0
+ mov r1, r8 @ Any register from r8 - r14 can be banked
+ mov r2, r9
+ mov r3, r10
+ mov r4, r11
+ mov r5, r12
+ mov r6, r13
+ mov r7, r14
+ teqp pc, #PSR_F_BIT | MODE_SVC26 @ back to svc
+ mov r0, r0
+ stmfd sp!, {r1-r7}
+ ldmia r0, {r0-r7}
+ stmfd sp!, {r0-r7}
+ mov r0, sp
+ mov r1, #BAD_ADDREXCPTN
+ b bad_mode
+
+/*=============================================================================
+ * Interrupt (IRQ) handler
+ *-----------------------------------------------------------------------------
+ * Note: if in user mode, then *no* kernel routine is running, so do not have
+ * to save svc lr
+ * (r13 points to irq temp save area)
+ */
+
+vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case...
+ sub lr, lr, #4
+ str lr, [r13]
+ tst lr, #3
+ bne __irq_svc
+ teqp pc, #PSR_I_BIT | MODE_SVC26
+ mov r0, r0
+ ldr lr, .LCirq
+ ldr lr, [lr]
+ save_user_regs
+
+1: get_irqnr_and_base r6, r5
+ teq r6, #0
+ ldrneb r0, [r5, r6] @ get IRQ number
+ movne r1, sp
+ @
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ @
+ adr lr, 1b
+ orr lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC
+ bne asm_do_IRQ
+
+ mov why, #0
+ get_thread_info r5
+ b ret_to_user
+
+ irq_prio_table
+
+__irq_svc: teqp pc, #PSR_I_BIT | MODE_SVC26
+ mov r0, r0
+ SVC_IRQ_SAVE_ALL
+ and r2, lr, #3
+ teq r2, #3
+ bne __irq_invalid
+1: get_irqnr_and_base r6, r5
+ teq r6, #0
+ ldrneb r0, [r5, r6] @ get IRQ number
+ movne r1, sp
+ @
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ @
+ adr lr, 1b
+ orr lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC
+ bne asm_do_IRQ @ Returns to 1b
+ SVC_RESTORE_ALL
+
+__irq_invalid: mov r0, sp
+ mov r1, #BAD_IRQ
+ b bad_mode
+
+/*=============================================================================
+ * Data abort handler code
+ *-----------------------------------------------------------------------------
+ *
+ * This handles both exceptions from user and SVC modes, computes the address
+ * range of the problem, and does any correction that is required. It then
+ * calls the kernel data abort routine.
+ *
+ * This is where I wish that the ARM would tell you which address aborted.
+ */
+
+vector_data: sub lr, lr, #8 @ Correct lr
+ tst lr, #3
+ bne Ldata_not_user
+ save_user_regs
+ teqp pc, #MODE_SVC26
+ mask_pc r0, lr
+ bl Ldata_do
+ b ret_from_exception
+
+Ldata_not_user:
+ SVC_SAVE_ALL
+ and r2, lr, #3
+ teq r2, #3
+ bne Ldata_illegal_mode
+ tst lr, #PSR_I_BIT
+ teqeqp pc, #MODE_SVC26
+ mask_pc r0, lr
+ bl Ldata_do
+ SVC_RESTORE_ALL
+
+Ldata_illegal_mode:
+ mov r0, sp
+ mov r1, #BAD_DATA
+ b bad_mode
+
+Ldata_do: mov r3, sp
+ ldr r4, [r0] @ Get instruction
+ mov r2, #0
+ tst r4, #1 << 20 @ Check to see if it is a write instruction
+ orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
+ mov r1, r4, lsr #22 @ Now branch to the relevent processing routine
+ and r1, r1, #15 << 2
+ add pc, pc, r1
+ movs pc, lr
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_ldrstr_post @ ldr rd, [rn], #m
+ b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal
+ b Ldata_ldrstr_post @ ldr rd, [rn], rm
+ b Ldata_ldrstr_regindex @ ldr rd, [rn, rm]
+ b Ldata_ldmstm @ ldm*a rn,
+ b Ldata_ldmstm @ ldm*b rn,
+ b Ldata_unknown
+ b Ldata_unknown
+ b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+ b Ldata_ldcstc_pre @ ldc rd, [rn, #m]
+ b Ldata_unknown
+Ldata_unknown: @ Part of jumptable
+ mov r0, r1
+ mov r1, r4
+ mov r2, r3
+ b baddataabort
+
+Ldata_ldrstr_post:
+ mov r0, r4, lsr #14 @ Get Rn
+ and r0, r0, #15 << 2 @ Mask out reg.
+ teq r0, #15 << 2
+ ldr r0, [r3, r0] @ Get register
+ biceq r0, r0, #PCMASK
+ mov r1, r0
+#ifdef FAULT_CODE_LDRSTRPOST
+ orr r2, r2, #FAULT_CODE_LDRSTRPOST
+#endif
+ b do_DataAbort
+
+Ldata_ldrstr_numindex:
+ mov r0, r4, lsr #14 @ Get Rn
+ and r0, r0, #15 << 2 @ Mask out reg.
+ teq r0, #15 << 2
+ ldr r0, [r3, r0] @ Get register
+ mov r1, r4, lsl #20
+ biceq r0, r0, #PCMASK
+ tst r4, #1 << 23
+ addne r0, r0, r1, lsr #20
+ subeq r0, r0, r1, lsr #20
+ mov r1, r0
+#ifdef FAULT_CODE_LDRSTRPRE
+ orr r2, r2, #FAULT_CODE_LDRSTRPRE
+#endif
+ b do_DataAbort
+
+Ldata_ldrstr_regindex:
+ mov r0, r4, lsr #14 @ Get Rn
+ and r0, r0, #15 << 2 @ Mask out reg.
+ teq r0, #15 << 2
+ ldr r0, [r3, r0] @ Get register
+ and r7, r4, #15
+ biceq r0, r0, #PCMASK
+ teq r7, #15 @ Check for PC
+ ldr r7, [r3, r7, lsl #2] @ Get Rm
+ and r8, r4, #0x60 @ Get shift types
+ biceq r7, r7, #PCMASK
+ mov r9, r4, lsr #7 @ Get shift amount
+ and r9, r9, #31
+ teq r8, #0
+ moveq r7, r7, lsl r9
+ teq r8, #0x20 @ LSR shift
+ moveq r7, r7, lsr r9
+ teq r8, #0x40 @ ASR shift
+ moveq r7, r7, asr r9
+ teq r8, #0x60 @ ROR shift
+ moveq r7, r7, ror r9
+ tst r4, #1 << 23
+ addne r0, r0, r7
+ subeq r0, r0, r7 @ Apply correction
+ mov r1, r0
+#ifdef FAULT_CODE_LDRSTRREG
+ orr r2, r2, #FAULT_CODE_LDRSTRREG
+#endif
+ b do_DataAbort
+
+Ldata_ldmstm:
+ mov r7, #0x11
+ orr r7, r7, r7, lsl #8
+ and r0, r4, r7
+ and r1, r4, r7, lsl #1
+ add r0, r0, r1, lsr #1
+ and r1, r4, r7, lsl #2
+ add r0, r0, r1, lsr #2
+ and r1, r4, r7, lsl #3
+ add r0, r0, r1, lsr #3
+ add r0, r0, r0, lsr #8
+ add r0, r0, r0, lsr #4
+ and r7, r0, #15 @ r7 = no. of registers to transfer.
+ mov r5, r4, lsr #14 @ Get Rn
+ and r5, r5, #15 << 2
+ ldr r0, [r3, r5] @ Get reg
+ eor r6, r4, r4, lsl #2
+ tst r6, #1 << 23 @ Check inc/dec ^ writeback
+ rsbeq r7, r7, #0
+ add r7, r0, r7, lsl #2 @ Do correction (signed)
+ subne r1, r7, #1
+ subeq r1, r0, #1
+ moveq r0, r7
+ tst r4, #1 << 21 @ Check writeback
+ strne r7, [r3, r5]
+ eor r6, r4, r4, lsl #1
+ tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec
+ addeq r0, r0, #4
+ addeq r1, r1, #4
+ teq r5, #15*4 @ CHECK FOR PC
+ biceq r1, r1, #PCMASK
+ biceq r0, r0, #PCMASK
+#ifdef FAULT_CODE_LDMSTM
+ orr r2, r2, #FAULT_CODE_LDMSTM
+#endif
+ b do_DataAbort
+
+Ldata_ldcstc_pre:
+ mov r0, r4, lsr #14 @ Get Rn
+ and r0, r0, #15 << 2 @ Mask out reg.
+ teq r0, #15 << 2
+ ldr r0, [r3, r0] @ Get register
+ mov r1, r4, lsl #24 @ Get offset
+ biceq r0, r0, #PCMASK
+ tst r4, #1 << 23
+ addne r0, r0, r1, lsr #24
+ subeq r0, r0, r1, lsr #24
+ mov r1, r0
+#ifdef FAULT_CODE_LDCSTC
+ orr r2, r2, #FAULT_CODE_LDCSTC
+#endif
+ b do_DataAbort
+
+
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+ get_thread_info tsk
+ mov why, #0
+ b ret_to_user
+
+ .data
+ENTRY(fp_enter)
+ .word fpe_not_present
+ .text
+/*
+ * Register switch for older 26-bit only ARMs
+ */
+ENTRY(__switch_to)
+ add r0, r0, #TI_CPU_SAVE
+ stmia r0, {r4 - sl, fp, sp, lr}
+ add r1, r1, #TI_CPU_SAVE
+ ldmia r1, {r4 - sl, fp, sp, pc}^
+
+/*
+ *=============================================================================
+ * Low-level interface code
+ *-----------------------------------------------------------------------------
+ * Trap initialisation
+ *-----------------------------------------------------------------------------
+ *
+ * Note - FIQ code has changed. The default is a couple of words in 0x1c, 0x20
+ * that call _unexp_fiq. Nowever, we now copy the FIQ routine to 0x1c (removes
+ * some excess cycles).
+ *
+ * What we need to put into 0-0x1c are branches to branch to the kernel.
+ */
+
+ .section ".init.text",#alloc,#execinstr
+
+.Ljump_addresses:
+ swi SYS_ERROR0
+ .word vector_undefinstr - 12
+ .word vector_swi - 16
+ .word vector_prefetch - 20
+ .word vector_data - 24
+ .word vector_addrexcptn - 28
+ .word vector_IRQ - 32
+ .word _unexp_fiq - 36
+ b . + 8
+/*
+ * initialise the trap system
+ */
+ENTRY(__trap_init)
+ stmfd sp!, {r4 - r7, lr}
+ adr r1, .Ljump_addresses
+ ldmia r1, {r1 - r7, ip, lr}
+ orr r2, lr, r2, lsr #2
+ orr r3, lr, r3, lsr #2
+ orr r4, lr, r4, lsr #2
+ orr r5, lr, r5, lsr #2
+ orr r6, lr, r6, lsr #2
+ orr r7, lr, r7, lsr #2
+ orr ip, lr, ip, lsr #2
+ mov r0, #0
+ stmia r0, {r1 - r7, ip}
+ ldmfd sp!, {r4 - r7, pc}^
+
+ .bss
+__temp_irq: .space 4 @ saved lr_irq
+__temp_fiq: .space 128
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/fiq.c linux-2.5.70-bk14/arch/arm26/kernel/fiq.c
--- linux-2.5.70-bk13/arch/arm26/kernel/fiq.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/fiq.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,202 @@
+/*
+ * linux/arch/arm26/kernel/fiq.c
+ *
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998, 1999 Phil Blundell
+ * Copyright (C) 2003 Ian Molton
+ *
+ * FIQ support written by Philip Blundell , 1998.
+ *
+ * FIQ support re-written by Russell King to be more generic
+ *
+ * We now properly support a method by which the FIQ handlers can
+ * be stacked onto the vector. We still do not support sharing
+ * the FIQ vector itself.
+ *
+ * Operation is as follows:
+ * 1. Owner A claims FIQ:
+ * - default_fiq relinquishes control.
+ * 2. Owner A:
+ * - inserts code.
+ * - sets any registers,
+ * - enables FIQ.
+ * 3. Owner B claims FIQ:
+ * - if owner A has a relinquish function.
+ * - disable FIQs.
+ * - saves any registers.
+ * - returns zero.
+ * 4. Owner B:
+ * - inserts code.
+ * - sets any registers,
+ * - enables FIQ.
+ * 5. Owner B releases FIQ:
+ * - Owner A is asked to reacquire FIQ:
+ * - inserts code.
+ * - restores saved registers.
+ * - enables FIQ.
+ * 6. Goto 3
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FIQ_VECTOR (vectors_base() + 0x1c)
+
+static unsigned long no_fiq_insn;
+
+#define unprotect_page_0()
+#define protect_page_0()
+
+/* Default reacquire function
+ * - we always relinquish FIQ control
+ * - we always reacquire FIQ control
+ */
+static int fiq_def_op(void *ref, int relinquish)
+{
+ if (!relinquish) {
+ unprotect_page_0();
+ *(unsigned long *)FIQ_VECTOR = no_fiq_insn;
+ protect_page_0();
+ }
+
+ return 0;
+}
+
+static struct fiq_handler default_owner = {
+ .name = "default",
+ .fiq_op = fiq_def_op,
+};
+
+static struct fiq_handler *current_fiq = &default_owner;
+
+int show_fiq_list(struct seq_file *p, void *v)
+{
+ if (current_fiq != &default_owner)
+ seq_printf(p, "FIQ: %s\n", current_fiq->name);
+
+ return 0;
+}
+
+void set_fiq_handler(void *start, unsigned int length)
+{
+ unprotect_page_0();
+
+ memcpy((void *)FIQ_VECTOR, start, length);
+
+ protect_page_0();
+}
+
+/*
+ * Taking an interrupt in FIQ mode is death, so both these functions
+ * disable irqs for the duration.
+ */
+void set_fiq_regs(struct pt_regs *regs)
+{
+ register unsigned long tmp, tmp2;
+ __asm__ volatile (
+ "mov %0, pc
+ bic %1, %0, #0x3
+ orr %1, %1, %3
+ teqp %1, #0 @ select FIQ mode
+ mov r0, r0
+ ldmia %2, {r8 - r14}
+ teqp %0, #0 @ return to SVC mode
+ mov r0, r0"
+ : "=&r" (tmp), "=&r" (tmp2)
+ : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
+ /* These registers aren't modified by the above code in a way
+ visible to the compiler, but we mark them as clobbers anyway
+ so that GCC won't put any of the input or output operands in
+ them. */
+ : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+}
+
+void get_fiq_regs(struct pt_regs *regs)
+{
+ register unsigned long tmp, tmp2;
+ __asm__ volatile (
+ "mov %0, pc
+ bic %1, %0, #0x3
+ orr %1, %1, %3
+ teqp %1, #0 @ select FIQ mode
+ mov r0, r0
+ stmia %2, {r8 - r14}
+ teqp %0, #0 @ return to SVC mode
+ mov r0, r0"
+ : "=&r" (tmp), "=&r" (tmp2)
+ : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
+ /* These registers aren't modified by the above code in a way
+ visible to the compiler, but we mark them as clobbers anyway
+ so that GCC won't put any of the input or output operands in
+ them. */
+ : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+}
+
+int claim_fiq(struct fiq_handler *f)
+{
+ int ret = 0;
+
+ if (current_fiq) {
+ ret = -EBUSY;
+
+ if (current_fiq->fiq_op != NULL)
+ ret = current_fiq->fiq_op(current_fiq->dev_id, 1);
+ }
+
+ if (!ret) {
+ f->next = current_fiq;
+ current_fiq = f;
+ }
+
+ return ret;
+}
+
+void release_fiq(struct fiq_handler *f)
+{
+ if (current_fiq != f) {
+ printk(KERN_ERR "%s FIQ trying to release %s FIQ\n",
+ f->name, current_fiq->name);
+#ifdef CONFIG_DEBUG_ERRORS
+ __backtrace();
+#endif
+ return;
+ }
+
+ do
+ current_fiq = current_fiq->next;
+ while (current_fiq->fiq_op(current_fiq->dev_id, 0));
+}
+
+void enable_fiq(int fiq)
+{
+ enable_irq(fiq + FIQ_START);
+}
+
+void disable_fiq(int fiq)
+{
+ disable_irq(fiq + FIQ_START);
+}
+
+EXPORT_SYMBOL(set_fiq_handler);
+EXPORT_SYMBOL(set_fiq_regs);
+EXPORT_SYMBOL(get_fiq_regs);
+EXPORT_SYMBOL(claim_fiq);
+EXPORT_SYMBOL(release_fiq);
+EXPORT_SYMBOL(enable_fiq);
+EXPORT_SYMBOL(disable_fiq);
+
+void __init init_FIQ(void)
+{
+ no_fiq_insn = *(unsigned long *)FIQ_VECTOR;
+ set_fs(get_fs());
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/init_task.c linux-2.5.70-bk14/arch/arm26/kernel/init_task.c
--- linux-2.5.70-bk13/arch/arm26/kernel/init_task.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/init_task.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,41 @@
+/*
+ * linux/arch/arm/kernel/init_task.c
+ *
+ * Copyright (C) 2003 Ian Molton
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance...
+ */
+union thread_union init_thread_union
+ __attribute__((__section__(".init.task"))) =
+ { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/irq.c linux-2.5.70-bk14/arch/arm26/kernel/irq.c
--- linux-2.5.70-bk13/arch/arm26/kernel/irq.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/irq.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,705 @@
+/*
+ * linux/arch/arm/kernel/irq.c
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
+ * 'Borrowed' for ARM26 and (C) 2003 Ian Molton.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/*
+ * Maximum IRQ count. Currently, this is arbitary. However, it should
+ * not be set too low to prevent false triggering. Conversely, if it
+ * is set too high, then you could miss a stuck IRQ.
+ *
+ * Maybe we ought to set a timer and re-enable the IRQ at a later time?
+ */
+#define MAX_IRQ_CNT 100000
+
+static volatile unsigned long irq_err_count;
+static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+
+struct irqdesc irq_desc[NR_IRQS];
+void (*init_arch_irq)(void) __initdata = NULL;
+
+/*
+ * Dummy mask/unmask handler
+ */
+void dummy_mask_unmask_irq(unsigned int irq)
+{
+}
+
+void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ irq_err_count += 1;
+ printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+}
+
+static struct irqchip bad_chip = {
+ .ack = dummy_mask_unmask_irq,
+ .mask = dummy_mask_unmask_irq,
+ .unmask = dummy_mask_unmask_irq,
+};
+
+static struct irqdesc bad_irq_desc = {
+ .chip = &bad_chip,
+ .handle = do_bad_IRQ,
+ .depth = 1,
+};
+
+/**
+ * disable_irq - disable an irq and wait for completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. We do this lazily.
+ *
+ * This function may be called from IRQ context.
+ */
+void disable_irq(unsigned int irq)
+{
+ struct irqdesc *desc = irq_desc + irq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ if (!desc->depth++)
+ desc->enabled = 0;
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+/**
+ * enable_irq - enable interrupt handling on an irq
+ * @irq: Interrupt to enable
+ *
+ * Re-enables the processing of interrupts on this IRQ line.
+ * Note that this may call the interrupt handler, so you may
+ * get unexpected results if you hold IRQs disabled.
+ *
+ * This function may be called from IRQ context.
+ */
+void enable_irq(unsigned int irq)
+{
+ struct irqdesc *desc = irq_desc + irq;
+ unsigned long flags;
+ int pending = 0;
+
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ if (unlikely(!desc->depth)) {
+ printk("enable_irq(%u) unbalanced from %p\n", irq,
+ __builtin_return_address(0));
+ } else if (!--desc->depth) {
+ desc->probing = 0;
+ desc->enabled = 1;
+ desc->chip->unmask(irq);
+ pending = desc->pending;
+ desc->pending = 0;
+ /*
+ * If the interrupt was waiting to be processed,
+ * retrigger it.
+ */
+ if (pending)
+ desc->chip->rerun(irq);
+ }
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i;
+ struct irqaction * action;
+
+ for (i = 0 ; i < NR_IRQS ; i++) {
+ action = irq_desc[i].action;
+ if (!action)
+ continue;
+ seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
+ seq_printf(p, " %s", action->name);
+ for (action = action->next; action; action = action->next) {
+ seq_printf(p, ", %s", action->name);
+ }
+ seq_putc(p, '\n');
+ }
+
+ show_fiq_list(p, v);
+ seq_printf(p, "Err: %10lu\n", irq_err_count);
+ return 0;
+}
+
+/*
+ * IRQ lock detection.
+ *
+ * Hopefully, this should get us out of a few locked situations.
+ * However, it may take a while for this to happen, since we need
+ * a large number if IRQs to appear in the same jiffie with the
+ * same instruction pointer (or within 2 instructions).
+ */
+static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
+{
+ unsigned long instr_ptr = instruction_pointer(regs);
+
+ if (desc->lck_jif == jiffies &&
+ desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
+ desc->lck_cnt += 1;
+
+ if (desc->lck_cnt > MAX_IRQ_CNT) {
+ printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
+ return 1;
+ }
+ } else {
+ desc->lck_cnt = 0;
+ desc->lck_pc = instruction_pointer(regs);
+ desc->lck_jif = jiffies;
+ }
+ return 0;
+}
+
+static void
+__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
+{
+ unsigned int status;
+
+ spin_unlock(&irq_controller_lock);
+
+ if (!(action->flags & SA_INTERRUPT))
+ local_irq_enable();
+
+ status = 0;
+ do {
+ status |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while (action);
+
+ if (status & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+
+ spin_lock_irq(&irq_controller_lock);
+}
+
+/*
+ * This is for software-decoded IRQs. The caller is expected to
+ * handle the ack, clear, mask and unmask issues.
+ */
+void
+do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ const int cpu = smp_processor_id();
+
+ desc->triggered = 1;
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ action = desc->action;
+ if (action)
+ __do_irq(irq, desc->action, regs);
+}
+
+/*
+ * Most edge-triggered IRQ implementations seem to take a broken
+ * approach to this. Hence the complexity.
+ */
+void
+do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ const int cpu = smp_processor_id();
+
+ desc->triggered = 1;
+
+ /*
+ * If we're currently running this IRQ, or its disabled,
+ * we shouldn't process the IRQ. Instead, turn on the
+ * hardware masks.
+ */
+ if (unlikely(desc->running || !desc->enabled))
+ goto running;
+
+ /*
+ * Acknowledge and clear the IRQ, but don't mask it.
+ */
+ desc->chip->ack(irq);
+
+ /*
+ * Mark the IRQ currently in progress.
+ */
+ desc->running = 1;
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ do {
+ struct irqaction *action;
+
+ action = desc->action;
+ if (!action)
+ break;
+
+ if (desc->pending && desc->enabled) {
+ desc->pending = 0;
+ desc->chip->unmask(irq);
+ }
+
+ __do_irq(irq, action, regs);
+ } while (desc->pending);
+
+ desc->running = 0;
+
+ /*
+ * If we were disabled or freed, shut down the handler.
+ */
+ if (likely(desc->action && !check_irq_lock(desc, irq, regs)))
+ return;
+
+ running:
+ /*
+ * We got another IRQ while this one was masked or
+ * currently running. Delay it.
+ */
+ desc->pending = 1;
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+}
+
+/*
+ * Level-based IRQ handler. Nice and simple.
+ */
+void
+do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ const int cpu = smp_processor_id();
+
+ desc->triggered = 1;
+
+ /*
+ * Acknowledge, clear _AND_ disable the interrupt.
+ */
+ desc->chip->ack(irq);
+
+ if (likely(desc->enabled)) {
+ kstat_cpu(cpu).irqs[irq]++;
+
+ /*
+ * Return with this interrupt masked if no action
+ */
+ action = desc->action;
+ if (action) {
+ __do_irq(irq, desc->action, regs);
+
+ if (likely(desc->enabled &&
+ !check_irq_lock(desc, irq, regs)))
+ desc->chip->unmask(irq);
+ }
+ }
+}
+
+/*
+ * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+ * come via this function. Instead, they should provide their
+ * own 'handler'
+ */
+asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
+{
+ struct irqdesc *desc = irq_desc + irq;
+
+ /*
+ * Some hardware gives randomly wrong interrupts. Rather
+ * than crashing, do something sensible.
+ */
+ if (irq >= NR_IRQS)
+ desc = &bad_irq_desc;
+
+ irq_enter();
+ spin_lock(&irq_controller_lock);
+ desc->handle(irq, desc, regs);
+ spin_unlock(&irq_controller_lock);
+ irq_exit();
+}
+
+void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained)
+{
+ struct irqdesc *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
+ return;
+ }
+
+ if (handle == NULL)
+ handle = do_bad_IRQ;
+
+ desc = irq_desc + irq;
+
+ if (is_chained && desc->chip == &bad_chip)
+ printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
+
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ if (handle == do_bad_IRQ) {
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+ desc->depth = 1;
+ desc->enabled = 0;
+ }
+ desc->handle = handle;
+ if (handle != do_bad_IRQ && is_chained) {
+ desc->valid = 0;
+ desc->probe_ok = 0;
+ desc->depth = 0;
+ desc->chip->unmask(irq);
+ }
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+void set_irq_chip(unsigned int irq, struct irqchip *chip)
+{
+ struct irqdesc *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ return;
+ }
+
+ if (chip == NULL)
+ chip = &bad_chip;
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ desc->chip = chip;
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+int set_irq_type(unsigned int irq, unsigned int type)
+{
+ struct irqdesc *desc;
+ unsigned long flags;
+ int ret = -ENXIO;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
+ return -ENODEV;
+ }
+
+ desc = irq_desc + irq;
+ if (desc->chip->type) {
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ ret = desc->chip->type(irq, type);
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+ }
+
+ return ret;
+}
+
+void set_irq_flags(unsigned int irq, unsigned int iflags)
+{
+ struct irqdesc *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
+ return;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ desc->valid = (iflags & IRQF_VALID) != 0;
+ desc->probe_ok = (iflags & IRQF_PROBE) != 0;
+ desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+int setup_irq(unsigned int irq, struct irqaction *new)
+{
+ int shared = 0;
+ struct irqaction *old, **p;
+ unsigned long flags;
+ struct irqdesc *desc;
+
+ /*
+ * Some drivers like serial.c use request_irq() heavily,
+ * so we have to be careful not to interfere with a
+ * running system.
+ */
+ if (new->flags & SA_SAMPLE_RANDOM) {
+ /*
+ * This function might sleep, we want to call it first,
+ * outside of the atomic block.
+ * Yes, this might clear the entropy pool if the wrong
+ * driver is attempted to be loaded, without actually
+ * installing a new handler, but is this really a problem,
+ * only the sysadmin is able to do this.
+ */
+ rand_initialize_irq(irq);
+ }
+
+ /*
+ * The following block of code has to be executed atomically
+ */
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ p = &desc->action;
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & new->flags & SA_SHIRQ)) {
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+ return -EBUSY;
+ }
+
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ shared = 1;
+ }
+
+ *p = new;
+
+ if (!shared) {
+ desc->probing = 0;
+ desc->running = 0;
+ desc->pending = 0;
+ desc->depth = 1;
+ if (!desc->noautoenable) {
+ desc->depth = 0;
+ desc->enabled = 1;
+ desc->chip->unmask(irq);
+ }
+ }
+
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+ return 0;
+}
+
+/**
+ * request_irq - allocate an interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs
+ * @irqflags: Interrupt type flags
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the
+ * interrupt line and IRQ handling. From the point this
+ * call is made your handler function may be invoked. Since
+ * your handler function must clear any interrupt the board
+ * raises, you must take care both to initialise your hardware
+ * and to set up the interrupt handler in the right order.
+ *
+ * Dev_id must be globally unique. Normally the address of the
+ * device data structure is used as the cookie. Since the handler
+ * receives this value it makes sense to use it.
+ *
+ * If your interrupt is shared you must pass a non NULL dev_id
+ * as this is required when freeing the interrupt.
+ *
+ * Flags:
+ *
+ * SA_SHIRQ Interrupt is shared
+ *
+ * SA_INTERRUPT Disable local interrupts while processing
+ *
+ * SA_SAMPLE_RANDOM The interrupt can be used for entropy
+ *
+ */
+
+//FIXME - handler used to return void - whats the significance of the change?
+int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irq_flags, const char * devname, void *dev_id)
+{
+ unsigned long retval;
+ struct irqaction *action;
+
+ if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
+ (irq_flags & SA_SHIRQ && !dev_id))
+ return -EINVAL;
+
+ action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+
+ action->handler = handler;
+ action->flags = irq_flags;
+ action->mask = 0;
+ action->name = devname;
+ action->next = NULL;
+ action->dev_id = dev_id;
+
+ retval = setup_irq(irq, action);
+
+ if (retval)
+ kfree(action);
+ return retval;
+}
+
+/**
+ * free_irq - free an interrupt
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
+ *
+ * Remove an interrupt handler. The handler is removed and if the
+ * interrupt line is no longer in use by any driver it is disabled.
+ * On a shared IRQ the caller must ensure the interrupt is disabled
+ * on the card it drives before calling this function.
+ *
+ * This function may be called from interrupt context.
+ */
+void free_irq(unsigned int irq, void *dev_id)
+{
+ struct irqaction * action, **p;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS || !irq_desc[irq].valid) {
+ printk(KERN_ERR "Trying to free IRQ%d\n",irq);
+#ifdef CONFIG_DEBUG_ERRORS
+ __backtrace();
+#endif
+ return;
+ }
+
+ spin_lock_irqsave(&irq_controller_lock, flags);
+ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
+ if (action->dev_id != dev_id)
+ continue;
+
+ /* Found it - now free it */
+ *p = action->next;
+ kfree(action);
+ goto out;
+ }
+ printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
+#ifdef CONFIG_DEBUG_ERRORS
+ __backtrace();
+#endif
+out:
+ spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+/* Start the interrupt probing. Unlike other architectures,
+ * we don't return a mask of interrupts from probe_irq_on,
+ * but return the number of interrupts enabled for the probe.
+ * The interrupts which have been enabled for probing is
+ * instead recorded in the irq_desc structure.
+ */
+unsigned long probe_irq_on(void)
+{
+ unsigned int i, irqs = 0;
+ unsigned long delay;
+
+ /*
+ * first snaffle up any unassigned but
+ * probe-able interrupts
+ */
+ spin_lock_irq(&irq_controller_lock);
+ for (i = 0; i < NR_IRQS; i++) {
+ if (!irq_desc[i].probe_ok || irq_desc[i].action)
+ continue;
+
+ irq_desc[i].probing = 1;
+ irq_desc[i].triggered = 0;
+ if (irq_desc[i].chip->type)
+ irq_desc[i].chip->type(i, IRQT_PROBE);
+ irq_desc[i].chip->unmask(i);
+ irqs += 1;
+ }
+ spin_unlock_irq(&irq_controller_lock);
+
+ /*
+ * wait for spurious interrupts to mask themselves out again
+ */
+ for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
+ /* min 100ms delay */;
+
+ /*
+ * now filter out any obviously spurious interrupts
+ */
+ spin_lock_irq(&irq_controller_lock);
+ for (i = 0; i < NR_IRQS; i++) {
+ if (irq_desc[i].probing && irq_desc[i].triggered) {
+ irq_desc[i].probing = 0;
+ irqs -= 1;
+ }
+ }
+ spin_unlock_irq(&irq_controller_lock);
+
+ return irqs;
+}
+
+/*
+ * Possible return values:
+ * >= 0 - interrupt number
+ * -1 - no interrupt/many interrupts
+ */
+int probe_irq_off(unsigned long irqs)
+{
+ unsigned int i;
+ int irq_found = NO_IRQ;
+
+ /*
+ * look at the interrupts, and find exactly one
+ * that we were probing has been triggered
+ */
+ spin_lock_irq(&irq_controller_lock);
+ for (i = 0; i < NR_IRQS; i++) {
+ if (irq_desc[i].probing &&
+ irq_desc[i].triggered) {
+ if (irq_found != NO_IRQ) {
+ irq_found = NO_IRQ;
+ goto out;
+ }
+ irq_found = i;
+ }
+ }
+
+ if (irq_found == -1)
+ irq_found = NO_IRQ;
+out:
+ spin_unlock_irq(&irq_controller_lock);
+
+ return irq_found;
+}
+
+void __init init_irq_proc(void)
+{
+}
+
+void __init init_IRQ(void)
+{
+ struct irqdesc *desc;
+ extern void init_dma(void);
+ int irq;
+
+ for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++)
+ *desc = bad_irq_desc;
+
+ init_arch_irq();
+ init_dma();
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/process.c linux-2.5.70-bk14/arch/arm26/kernel/process.c
--- linux-2.5.70-bk13/arch/arm26/kernel/process.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/process.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,414 @@
+/*
+ * linux/arch/arm26/kernel/process.c
+ *
+ * Copyright (C) 2003 Ian Molton - adapted for ARM26
+ * Copyright (C) 1996-2000 Russell King - Converted to ARM.
+ * Origional Copyright (C) 1995 Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+extern const char *processor_modes[];
+extern void setup_mm_for_reboot(char mode);
+
+static volatile int hlt_counter;
+
+void disable_hlt(void)
+{
+ hlt_counter++;
+}
+
+void enable_hlt(void)
+{
+ hlt_counter--;
+}
+
+static int __init nohlt_setup(char *__unused)
+{
+ hlt_counter = 1;
+ return 1;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+ hlt_counter = 0;
+ return 1;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+void (*pm_power_off)(void);
+
+/*
+ * This is our default idle handler. We need to disable
+ * interrupts here to ensure we don't miss a wakeup call.
+ */
+void default_idle(void)
+{
+ local_irq_disable();
+ if (!need_resched() && !hlt_counter)
+ local_irq_enable();
+}
+
+/*
+ * The idle thread. We try to conserve power, while trying to keep
+ * overall latency low. The architecture specific idle is passed
+ * a value to indicate the level of "idleness" of the system.
+ */
+void cpu_idle(void)
+{
+ /* endless idle loop with no priority at all */
+ preempt_disable();
+ while (1) {
+ void (*idle)(void) = pm_idle;
+ if (!idle)
+ idle = default_idle;
+ leds_event(led_idle_start);
+ while (!need_resched())
+ idle();
+ leds_event(led_idle_end);
+ schedule();
+ }
+}
+
+static char reboot_mode = 'h';
+
+int __init reboot_setup(char *str)
+{
+ reboot_mode = str[0];
+ return 1;
+}
+
+__setup("reboot=", reboot_setup);
+
+void machine_halt(void)
+{
+ leds_event(led_halted);
+}
+
+void machine_power_off(void)
+{
+ leds_event(led_halted);
+ if (pm_power_off)
+ pm_power_off();
+}
+
+void machine_restart(char * __unused)
+{
+ /*
+ * Clean and disable cache, and turn off interrupts
+ */
+ cpu_proc_fin();
+
+ /*
+ * Tell the mm system that we are going to reboot -
+ * we may need it to insert some 1:1 mappings so that
+ * soft boot works.
+ */
+ setup_mm_for_reboot(reboot_mode);
+
+ /*
+ * copy branch instruction to reset location and call it
+ */
+
+ *(unsigned long *)0 = *(unsigned long *)0x03800000;
+ ((void(*)(void))0)();
+
+ /*
+ * Whoops - the architecture was unable to reboot.
+ * Tell the user! Should never happen...
+ */
+ mdelay(1000);
+ printk("Reboot failed -- System halted\n");
+ while (1);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+ unsigned long flags;
+
+ flags = condition_codes(regs);
+
+ printk("pc : [<%08lx>] lr : [<%08lx>] %s\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer(regs),
+ regs->ARM_lr, print_tainted(), regs->ARM_sp,
+ regs->ARM_ip, regs->ARM_fp);
+ printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9,
+ regs->ARM_r8);
+ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6,
+ regs->ARM_r5, regs->ARM_r4);
+ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2,
+ regs->ARM_r1, regs->ARM_r0);
+ printk("Flags: %c%c%c%c",
+ flags & PSR_N_BIT ? 'N' : 'n',
+ flags & PSR_Z_BIT ? 'Z' : 'z',
+ flags & PSR_C_BIT ? 'C' : 'c',
+ flags & PSR_V_BIT ? 'V' : 'v');
+ printk(" IRQs o%s FIQs o%s Mode %s Segment %s\n",
+ interrupts_enabled(regs) ? "n" : "ff",
+ fast_interrupts_enabled(regs) ? "n" : "ff",
+ processor_modes[processor_mode(regs)],
+ get_fs() == get_ds() ? "kernel" : "user");
+}
+
+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.
+ */
+static unsigned long *thread_info_head;
+static unsigned int nr_thread_info;
+
+extern unsigned long get_page_8k(int priority);
+extern void free_page_8k(unsigned long page);
+
+// FIXME - is this valid?
+#define EXTRA_TASK_STRUCT 0
+#define ll_alloc_task_struct() ((struct thread_info *)get_page_8k(GFP_KERNEL))
+#define ll_free_task_struct(p) free_page_8k((unsigned long)(p))
+
+struct thread_info *alloc_thread_info(void)
+{
+ struct thread_info *thread = NULL;
+
+ if (EXTRA_TASK_STRUCT) {
+ unsigned long *p = thread_info_head;
+
+ if (p) {
+ thread_info_head = (unsigned long *)p[0];
+ nr_thread_info -= 1;
+ }
+ thread = (struct thread_info *)p;
+ }
+
+ if (!thread)
+ thread = ll_alloc_task_struct();
+
+#ifdef CONFIG_SYSRQ
+ /*
+ * The stack must be cleared if you want SYSRQ-T to
+ * give sensible stack usage information
+ */
+ if (thread) {
+ char *p = (char *)thread;
+ memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
+ }
+#endif
+ return thread;
+}
+
+void free_thread_info(struct thread_info *thread)
+{
+ if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) {
+ unsigned long *p = (unsigned long *)thread;
+ p[0] = (unsigned long)thread_info_head;
+ thread_info_head = p;
+ nr_thread_info += 1;
+ } else
+ ll_free_task_struct(thread);
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+}
+
+void flush_thread(void)
+{
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = current;
+
+ memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+ memset(&thread->fpstate, 0, sizeof(union fp_state));
+
+ current->used_math = 0;
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+}
+
+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+ unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+{
+ struct thread_info *thread = p->thread_info;
+ struct pt_regs *childregs;
+
+ childregs = __get_user_regs(thread);
+ *childregs = *regs;
+ childregs->ARM_r0 = 0;
+ childregs->ARM_sp = esp;
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+ thread->cpu_context.sp = (unsigned long)childregs;
+ thread->cpu_context.pc = (unsigned long)ret_from_fork | MODE_SVC26 | PSR_I_BIT;
+
+ return 0;
+}
+
+/*
+ * fill in the fpe structure for a core dump...
+ */
+int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
+{
+ struct thread_info *thread = current_thread_info();
+ int used_math = current->used_math;
+
+ if (used_math)
+ memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
+
+ return used_math;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+ struct task_struct *tsk = current;
+
+ dump->magic = CMAGIC;
+ dump->start_code = tsk->mm->start_code;
+ dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
+
+ dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+ dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ dump->u_ssize = 0;
+
+ dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
+ dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
+ dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
+ dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+ dump->u_debugreg[4] = tsk->thread.debug.nsaved;
+
+ if (dump->start_stack < 0x04000000)
+ dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
+
+ dump->regs = *regs;
+ dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ * FIXME - taken from arm32
+ */
+pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ register unsigned int r0 asm("r0") = flags | CLONE_VM | CLONE_UNTRACED;
+ register unsigned int r1 asm("r1") = 0;
+ register pid_t __ret asm("r0");
+
+ __asm__ __volatile__(
+ __syscall(clone)" @ kernel_thread sys_clone \n\
+ movs %0, r0 @ if we are the child \n\
+ bne 1f \n\
+ mov fp, #0 @ ensure that fp is zero \n\
+ mov r0, %4 \n\
+ mov lr, pc \n\
+ mov pc, %3 \n\
+ b sys_exit \n\
+1: "
+ : "=r" (__ret)
+ : "0" (r0), "r" (r1), "r" (fn), "r" (arg)
+ : "lr");
+ return __ret;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched ((unsigned long) scheduling_functions_start_here)
+#define last_sched ((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, lr;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = 4096 + (unsigned long)p;
+ fp = thread_saved_fp(p);
+ do {
+ if (fp < stack_page || fp > 4092+stack_page)
+ return 0;
+ lr = pc_pointer (((unsigned long *)fp)[-1]);
+ if (lr < first_sched || lr > last_sched)
+ return lr;
+ fp = *(unsigned long *) (fp - 12);
+ } while (count ++ < 16);
+ return 0;
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/ptrace.c linux-2.5.70-bk14/arch/arm26/kernel/ptrace.c
--- linux-2.5.70-bk13/arch/arm26/kernel/ptrace.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/ptrace.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,747 @@
+/*
+ * linux/arch/arm26/kernel/ptrace.c
+ *
+ * By Ross Biro 1/23/92
+ * edited by Linus Torvalds
+ * ARM modifications Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+//#include
+
+#include "ptrace.h"
+
+#define REG_PC 15
+#define REG_PSR 15
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * Breakpoint SWI instruction: SWI &9F0001
+ */
+#define BREAKINST_ARM 0xef9f0001
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+static inline struct pt_regs *
+get_user_regs(struct task_struct *task)
+{
+ return __get_user_regs(task->thread_info);
+}
+
+/*
+ * this routine will get a word off of the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline long get_user_reg(struct task_struct *task, int offset)
+{
+ return get_user_regs(task)->uregs[offset];
+}
+
+/*
+ * this routine will put a word on the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline int
+put_user_reg(struct task_struct *task, int offset, long data)
+{
+ struct pt_regs newregs, *regs = get_user_regs(task);
+ int ret = -EINVAL;
+
+ newregs = *regs;
+ newregs.uregs[offset] = data;
+
+ if (valid_user_regs(&newregs)) {
+ regs->uregs[offset] = data;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static inline int
+read_u32(struct task_struct *task, unsigned long addr, u32 *res)
+{
+ int ret;
+
+ ret = access_process_vm(task, addr, res, sizeof(*res), 0);
+
+ return ret == sizeof(*res) ? 0 : -EIO;
+}
+
+static inline int
+read_instr(struct task_struct *task, unsigned long addr, u32 *res)
+{
+ int ret;
+ u32 val;
+ ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
+ ret = ret == sizeof(val) ? 0 : -EIO;
+ *res = val;
+ return ret;
+}
+
+/*
+ * Get value of register `rn' (in the instruction)
+ */
+static unsigned long
+ptrace_getrn(struct task_struct *child, unsigned long insn)
+{
+ unsigned int reg = (insn >> 16) & 15;
+ unsigned long val;
+
+ val = get_user_reg(child, reg);
+ if (reg == 15)
+ val = pc_pointer(val + 8); //FIXME - correct for arm26?
+
+ return val;
+}
+
+/*
+ * Get value of operand 2 (in an ALU instruction)
+ */
+static unsigned long
+ptrace_getaluop2(struct task_struct *child, unsigned long insn)
+{
+ unsigned long val;
+ int shift;
+ int type;
+
+ if (insn & 1 << 25) {
+ val = insn & 255;
+ shift = (insn >> 8) & 15;
+ type = 3;
+ } else {
+ val = get_user_reg (child, insn & 15);
+
+ if (insn & (1 << 4))
+ shift = (int)get_user_reg (child, (insn >> 8) & 15);
+ else
+ shift = (insn >> 7) & 31;
+
+ type = (insn >> 5) & 3;
+ }
+
+ switch (type) {
+ case 0: val <<= shift; break;
+ case 1: val >>= shift; break;
+ case 2:
+ val = (((signed long)val) >> shift);
+ break;
+ case 3:
+ val = (val >> shift) | (val << (32 - shift));
+ break;
+ }
+ return val;
+}
+
+/*
+ * Get value of operand 2 (in a LDR instruction)
+ */
+static unsigned long
+ptrace_getldrop2(struct task_struct *child, unsigned long insn)
+{
+ unsigned long val;
+ int shift;
+ int type;
+
+ val = get_user_reg(child, insn & 15);
+ shift = (insn >> 7) & 31;
+ type = (insn >> 5) & 3;
+
+ switch (type) {
+ case 0: val <<= shift; break;
+ case 1: val >>= shift; break;
+ case 2:
+ val = (((signed long)val) >> shift);
+ break;
+ case 3:
+ val = (val >> shift) | (val << (32 - shift));
+ break;
+ }
+ return val;
+}
+
+#define OP_MASK 0x01e00000
+#define OP_AND 0x00000000
+#define OP_EOR 0x00200000
+#define OP_SUB 0x00400000
+#define OP_RSB 0x00600000
+#define OP_ADD 0x00800000
+#define OP_ADC 0x00a00000
+#define OP_SBC 0x00c00000
+#define OP_RSC 0x00e00000
+#define OP_ORR 0x01800000
+#define OP_MOV 0x01a00000
+#define OP_BIC 0x01c00000
+#define OP_MVN 0x01e00000
+
+static unsigned long
+get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
+{
+ u32 alt = 0;
+
+ switch (insn & 0x0e000000) {
+ case 0x00000000:
+ case 0x02000000: {
+ /*
+ * data processing
+ */
+ long aluop1, aluop2, ccbit;
+
+ if ((insn & 0xf000) != 0xf000)
+ break;
+
+ aluop1 = ptrace_getrn(child, insn);
+ aluop2 = ptrace_getaluop2(child, insn);
+ ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
+
+ switch (insn & OP_MASK) {
+ case OP_AND: alt = aluop1 & aluop2; break;
+ case OP_EOR: alt = aluop1 ^ aluop2; break;
+ case OP_SUB: alt = aluop1 - aluop2; break;
+ case OP_RSB: alt = aluop2 - aluop1; break;
+ case OP_ADD: alt = aluop1 + aluop2; break;
+ case OP_ADC: alt = aluop1 + aluop2 + ccbit; break;
+ case OP_SBC: alt = aluop1 - aluop2 + ccbit; break;
+ case OP_RSC: alt = aluop2 - aluop1 + ccbit; break;
+ case OP_ORR: alt = aluop1 | aluop2; break;
+ case OP_MOV: alt = aluop2; break;
+ case OP_BIC: alt = aluop1 & ~aluop2; break;
+ case OP_MVN: alt = ~aluop2; break;
+ }
+ break;
+ }
+
+ case 0x04000000:
+ case 0x06000000:
+ /*
+ * ldr
+ */
+ if ((insn & 0x0010f000) == 0x0010f000) {
+ unsigned long base;
+
+ base = ptrace_getrn(child, insn);
+ if (insn & 1 << 24) {
+ long aluop2;
+
+ if (insn & 0x02000000)
+ aluop2 = ptrace_getldrop2(child, insn);
+ else
+ aluop2 = insn & 0xfff;
+
+ if (insn & 1 << 23)
+ base += aluop2;
+ else
+ base -= aluop2;
+ }
+ if (read_u32(child, base, &alt) == 0)
+ alt = pc_pointer(alt);
+ }
+ break;
+
+ case 0x08000000:
+ /*
+ * ldm
+ */
+ if ((insn & 0x00108000) == 0x00108000) {
+ unsigned long base;
+ unsigned int nr_regs;
+
+ if (insn & (1 << 23)) {
+ nr_regs = hweight16(insn & 65535) << 2;
+
+ if (!(insn & (1 << 24)))
+ nr_regs -= 4;
+ } else {
+ if (insn & (1 << 24))
+ nr_regs = -4;
+ else
+ nr_regs = 0;
+ }
+
+ base = ptrace_getrn(child, insn);
+
+ if (read_u32(child, base + nr_regs, &alt) == 0)
+ alt = pc_pointer(alt);
+ break;
+ }
+ break;
+
+ case 0x0a000000: {
+ /*
+ * bl or b
+ */
+ signed long displ;
+ /* It's a branch/branch link: instead of trying to
+ * figure out whether the branch will be taken or not,
+ * we'll put a breakpoint at both locations. This is
+ * simpler, more reliable, and probably not a whole lot
+ * slower than the alternative approach of emulating the
+ * branch.
+ */
+ displ = (insn & 0x00ffffff) << 8;
+ displ = (displ >> 6) + 8;
+ if (displ != 0 && displ != 4)
+ alt = pc + displ;
+ }
+ break;
+ }
+
+ return alt;
+}
+
+static int
+swap_insn(struct task_struct *task, unsigned long addr,
+ void *old_insn, void *new_insn, int size)
+{
+ int ret;
+
+ ret = access_process_vm(task, addr, old_insn, size, 0);
+ if (ret == size)
+ ret = access_process_vm(task, addr, new_insn, size, 1);
+ return ret;
+}
+
+static void
+add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
+{
+ int nr = dbg->nsaved;
+
+ if (nr < 2) {
+ u32 new_insn = BREAKINST_ARM;
+ int res;
+
+ res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
+
+ if (res == 4) {
+ dbg->bp[nr].address = addr;
+ dbg->nsaved += 1;
+ }
+ } else
+ printk(KERN_ERR "ptrace: too many breakpoints\n");
+}
+
+/*
+ * Clear one breakpoint in the user program. We copy what the hardware
+ * does and use bit 0 of the address to indicate whether this is a Thumb
+ * breakpoint or an ARM breakpoint.
+ */
+static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
+{
+ unsigned long addr = bp->address;
+ u32 old_insn;
+ int ret;
+
+ ret = swap_insn(task, addr & ~3, &old_insn,
+ &bp->insn, 4);
+
+ if (ret != 4 || old_insn != BREAKINST_ARM)
+ printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
+ "0x%08lx (0x%08x)\n", task->comm, task->pid,
+ addr, old_insn);
+}
+
+void ptrace_set_bpt(struct task_struct *child)
+{
+ struct pt_regs *regs;
+ unsigned long pc;
+ u32 insn;
+ int res;
+
+ regs = get_user_regs(child);
+ pc = instruction_pointer(regs);
+
+ res = read_instr(child, pc, &insn);
+ if (!res) {
+ struct debug_info *dbg = &child->thread.debug;
+ unsigned long alt;
+
+ dbg->nsaved = 0;
+
+ alt = get_branch_address(child, pc, insn);
+ if (alt)
+ add_breakpoint(child, dbg, alt);
+
+ /*
+ * Note that we ignore the result of setting the above
+ * breakpoint since it may fail. When it does, this is
+ * not so much an error, but a forewarning that we may
+ * be receiving a prefetch abort shortly.
+ *
+ * If we don't set this breakpoint here, then we can
+ * lose control of the thread during single stepping.
+ */
+ if (!alt || predicate(insn) != PREDICATE_ALWAYS)
+ add_breakpoint(child, dbg, pc + 4);
+ }
+}
+
+/*
+ * Ensure no single-step breakpoint is pending. Returns non-zero
+ * value if child was being single-stepped.
+ */
+void ptrace_cancel_bpt(struct task_struct *child)
+{
+ int i, nsaved = child->thread.debug.nsaved;
+
+ child->thread.debug.nsaved = 0;
+
+ if (nsaved > 2) {
+ printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
+ nsaved = 2;
+ }
+
+ for (i = 0; i < nsaved; i++)
+ clear_breakpoint(child, &child->thread.debug.bp[i]);
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ child->ptrace &= ~PT_SINGLESTEP;
+ ptrace_cancel_bpt(child);
+}
+
+/*
+ * Handle hitting a breakpoint.
+ */
+void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ /*
+ * The PC is always left pointing at the next instruction. Fix this.
+ */
+ regs->ARM_pc -= 4;
+
+ if (tsk->thread.debug.nsaved == 0)
+ printk(KERN_ERR "ptrace: bogus breakpoint trap\n");
+
+ ptrace_cancel_bpt(tsk);
+
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void *)instruction_pointer(regs) - 4;
+
+ force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/*
+ * Read the word at offset "off" into the "struct user". We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
+ unsigned long *ret)
+{
+ unsigned long tmp;
+
+ if (off & 3 || off >= sizeof(struct user))
+ return -EIO;
+
+ tmp = 0;
+ if (off < sizeof(struct pt_regs))
+ tmp = get_user_reg(tsk, off >> 2);
+
+ return put_user(tmp, ret);
+}
+
+/*
+ * Write the word at offset "off" into "struct user". We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
+ unsigned long val)
+{
+ if (off & 3 || off >= sizeof(struct user))
+ return -EIO;
+
+ if (off >= sizeof(struct pt_regs))
+ return 0;
+
+ return put_user_reg(tsk, off >> 2, val);
+}
+
+/*
+ * Get all user integer registers.
+ */
+static int ptrace_getregs(struct task_struct *tsk, void *uregs)
+{
+ struct pt_regs *regs = get_user_regs(tsk);
+
+ return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
+}
+
+/*
+ * Set all user integer registers.
+ */
+static int ptrace_setregs(struct task_struct *tsk, void *uregs)
+{
+ struct pt_regs newregs;
+ int ret;
+
+ ret = -EFAULT;
+ if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
+ struct pt_regs *regs = get_user_regs(tsk);
+
+ ret = -EINVAL;
+ if (valid_user_regs(&newregs)) {
+ *regs = newregs;
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Get the child FPU state.
+ */
+static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
+{
+ return copy_to_user(ufp, &tsk->thread_info->fpstate,
+ sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
+/*
+ * Set the child FPU state.
+ */
+static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
+{
+ tsk->used_math = 1;
+ return copy_from_user(&tsk->thread_info->fpstate, ufp,
+ sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
+static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+{
+ unsigned long tmp;
+ int ret;
+
+ switch (request) {
+ /*
+ * read word at location "addr" in the child process.
+ */
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA:
+ ret = access_process_vm(child, addr, &tmp,
+ sizeof(unsigned long), 0);
+ if (ret == sizeof(unsigned long))
+ ret = put_user(tmp, (unsigned long *) data);
+ else
+ ret = -EIO;
+ break;
+
+ case PTRACE_PEEKUSR:
+ ret = ptrace_read_user(child, addr, (unsigned long *)data);
+ break;
+
+ /*
+ * write the word at location addr.
+ */
+ case PTRACE_POKETEXT:
+ case PTRACE_POKEDATA:
+ ret = access_process_vm(child, addr, &data,
+ sizeof(unsigned long), 1);
+ if (ret == sizeof(unsigned long))
+ ret = 0;
+ else
+ ret = -EIO;
+ break;
+
+ case PTRACE_POKEUSR:
+ ret = ptrace_write_user(child, addr, data);
+ break;
+
+ /*
+ * continue/restart and stop at next (return from) syscall
+ */
+ case PTRACE_SYSCALL:
+ case PTRACE_CONT:
+ ret = -EIO;
+ if ((unsigned long) data > _NSIG)
+ break;
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->exit_code = data;
+ /* make sure single-step breakpoint is gone. */
+ child->ptrace &= ~PT_SINGLESTEP;
+ ptrace_cancel_bpt(child);
+ wake_up_process(child);
+ ret = 0;
+ break;
+
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ /* make sure single-step breakpoint is gone. */
+ child->ptrace &= ~PT_SINGLESTEP;
+ ptrace_cancel_bpt(child);
+ if (child->state != TASK_ZOMBIE) {
+ child->exit_code = SIGKILL;
+ wake_up_process(child);
+ }
+ ret = 0;
+ break;
+
+ /*
+ * execute single instruction.
+ */
+ case PTRACE_SINGLESTEP:
+ ret = -EIO;
+ if ((unsigned long) data > _NSIG)
+ break;
+ child->ptrace |= PT_SINGLESTEP;
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->exit_code = data;
+ /* give it a chance to run. */
+ wake_up_process(child);
+ ret = 0;
+ break;
+
+ case PTRACE_DETACH:
+ ret = ptrace_detach(child, data);
+ break;
+
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs(child, (void *)data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs(child, (void *)data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs(child, (void *)data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs(child, (void *)data);
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+ struct task_struct *child;
+ int ret;
+
+ lock_kernel();
+ ret = -EPERM;
+ if (request == PTRACE_TRACEME) {
+ /* are we already being traced? */
+ if (current->ptrace & PT_PTRACED)
+ goto out;
+ ret = security_ptrace(current->parent, current);
+ if (ret)
+ goto out;
+ /* set the ptrace bit in the process flags. */
+ current->ptrace |= PT_PTRACED;
+ ret = 0;
+ goto out;
+ }
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ goto out;
+
+ ret = -EPERM;
+ if (pid == 1) /* you may not mess with init */
+ goto out_tsk;
+
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out_tsk;
+ }
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret == 0)
+ ret = do_ptrace(request, child, addr, data);
+
+out_tsk:
+ put_task_struct(child);
+out:
+ unlock_kernel();
+ return ret;
+}
+
+asmlinkage void syscall_trace(int why, struct pt_regs *regs)
+{
+ unsigned long ip;
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+
+ /*
+ * Save IP. IP is used to denote syscall entry/exit:
+ * IP = 0 -> entry, = 1 -> exit
+ */
+ ip = regs->ARM_ip;
+ regs->ARM_ip = why;
+
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+ current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ ? 0x80 : 0);
+ current->state = TASK_STOPPED;
+ notify_parent(current, SIGCHLD);
+ schedule();
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+ regs->ARM_ip = ip;
+}
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/ptrace.h linux-2.5.70-bk14/arch/arm26/kernel/ptrace.h
--- linux-2.5.70-bk13/arch/arm26/kernel/ptrace.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/ptrace.h 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm26/kernel/ptrace.h
+ *
+ * Copyright (C) 2000-2003 Russell King
+ * Copyright (C) 2003 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+extern void ptrace_cancel_bpt(struct task_struct *);
+extern void ptrace_set_bpt(struct task_struct *);
+extern void ptrace_break(struct task_struct *, struct pt_regs *);
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/semaphore.c linux-2.5.70-bk14/arch/arm26/kernel/semaphore.c
--- linux-2.5.70-bk13/arch/arm26/kernel/semaphore.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/semaphore.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,215 @@
+/*
+ * ARM semaphore implementation, taken from
+ *
+ * i386 semaphore implementation.
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ * (C) Copyright 2003 Ian Molton (ARM26 mods)
+ *
+ * Modified for ARM by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+#include
+
+#include
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ * - only on a boundary condition do we need to care. When we go
+ * from a negative count to a non-negative, we wake people up.
+ * - when we go from a non-negative count to a negative do we
+ * (a) synchronize with the "sleeper" count and (b) make sure
+ * that we're on the wakeup list before we synchronize so that
+ * we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+ wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ spin_lock_irq(&semaphore_lock);
+ sem->sleepers++;
+ for (;;) {
+ int sleepers = sem->sleepers;
+
+ /*
+ * Add "everybody else" into it. They aren't
+ * playing, because we own the spinlock.
+ */
+ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+ sem->sleepers = 0;
+ break;
+ }
+ sem->sleepers = 1; /* us - see -1 above */
+ spin_unlock_irq(&semaphore_lock);
+
+ schedule();
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ spin_lock_irq(&semaphore_lock);
+ }
+ spin_unlock_irq(&semaphore_lock);
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+ wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+ int retval = 0;
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+ tsk->state = TASK_INTERRUPTIBLE;
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ spin_lock_irq(&semaphore_lock);
+ sem->sleepers ++;
+ for (;;) {
+ int sleepers = sem->sleepers;
+
+ /*
+ * With signals pending, this turns into
+ * the trylock failure case - we won't be
+ * sleeping, and we* can't get the lock as
+ * it has contention. Just correct the count
+ * and exit.
+ */
+ if (signal_pending(current)) {
+ retval = -EINTR;
+ sem->sleepers = 0;
+ atomic_add(sleepers, &sem->count);
+ break;
+ }
+
+ /*
+ * Add "everybody else" into it. They aren't
+ * playing, because we own the spinlock. The
+ * "-1" is because we're still hoping to get
+ * the lock.
+ */
+ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+ sem->sleepers = 0;
+ break;
+ }
+ sem->sleepers = 1; /* us - see -1 above */
+ spin_unlock_irq(&semaphore_lock);
+
+ schedule();
+ tsk->state = TASK_INTERRUPTIBLE;
+ spin_lock_irq(&semaphore_lock);
+ }
+ spin_unlock_irq(&semaphore_lock);
+ tsk->state = TASK_RUNNING;
+ remove_wait_queue(&sem->wait, &wait);
+ wake_up(&sem->wait);
+ return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ *
+ * We could have done the trylock with a
+ * single "cmpxchg" without failure cases,
+ * but then it wouldn't work on a 386.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+ int sleepers;
+ unsigned long flags;
+
+ spin_lock_irqsave(&semaphore_lock, flags);
+ sleepers = sem->sleepers + 1;
+ sem->sleepers = 0;
+
+ /*
+ * Add "everybody else" and us into it. They aren't
+ * playing, because we own the spinlock.
+ */
+ if (!atomic_add_negative(sleepers, &sem->count))
+ wake_up(&sem->wait);
+
+ spin_unlock_irqrestore(&semaphore_lock, flags);
+ return 1;
+}
+
+/*
+ * The semaphore operations have a special calling sequence that
+ * allow us to do a simpler in-line version of them. These routines
+ * need to convert that sequence back into the C sequence when
+ * there is contention on the semaphore.
+ *
+ * ip contains the semaphore pointer on entry. Save the C-clobbered
+ * registers (r0 to r3 and lr), but not ip, as we use it as a return
+ * value in some cases..
+ */
+asm(" .align 5 \n\
+ .globl __down_failed \n\
+__down_failed: \n\
+ stmfd sp!, {r0 - r3, lr} \n\
+ mov r0, ip \n\
+ bl __down \n\
+ ldmfd sp!, {r0 - r3, pc}^ \n\
+ \n\
+ .align 5 \n\
+ .globl __down_interruptible_failed \n\
+__down_interruptible_failed: \n\
+ stmfd sp!, {r0 - r3, lr} \n\
+ mov r0, ip \n\
+ bl __down_interruptible \n\
+ mov ip, r0 \n\
+ ldmfd sp!, {r0 - r3, pc}^ \n\
+ \n\
+ .align 5 \n\
+ .globl __down_trylock_failed \n\
+__down_trylock_failed: \n\
+ stmfd sp!, {r0 - r3, lr} \n\
+ mov r0, ip \n\
+ bl __down_trylock \n\
+ mov ip, r0 \n\
+ ldmfd sp!, {r0 - r3, pc}^ \n\
+ \n\
+ .align 5 \n\
+ .globl __up_wakeup \n\
+__up_wakeup: \n\
+ stmfd sp!, {r0 - r3, lr} \n\
+ mov r0, ip \n\
+ bl __up \n\
+ ldmfd sp!, {r0 - r3, pc}^ \n\
+ ");
+
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/setup.c linux-2.5.70-bk14/arch/arm26/kernel/setup.c
--- linux-2.5.70-bk13/arch/arm26/kernel/setup.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/setup.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,581 @@
+/*
+ * linux/arch/arm/kernel/setup.c
+ *
+ * Copyright (C) 1995-2001 Russell King
+ * Copyright (C) 2003 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#ifndef MEM_SIZE
+#define MEM_SIZE (16*1024*1024)
+#endif
+
+#ifdef CONFIG_PREEMPT
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
+#endif
+
+#if defined(CONFIG_FPE_NWFPE)
+char fpe_type[8];
+
+static int __init fpe_setup(char *line)
+{
+ memcpy(fpe_type, line, 8);
+ return 1;
+}
+
+__setup("fpe=", fpe_setup);
+#endif
+
+extern void paging_init(struct meminfo *);
+extern void convert_to_tag_list(struct tag *tags);
+extern void squash_mem_tags(struct tag *tag);
+extern void bootmem_init(struct meminfo *);
+extern int root_mountflags;
+extern int _stext, _text, _etext, _edata, _end;
+
+unsigned int processor_id;
+unsigned int __machine_arch_type;
+unsigned int system_rev;
+unsigned int system_serial_low;
+unsigned int system_serial_high;
+unsigned int elf_hwcap;
+
+struct processor processor;
+
+unsigned char aux_device_present;
+char elf_platform[ELF_PLATFORM_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
+
+unsigned long phys_initrd_start __initdata = 0;
+unsigned long phys_initrd_size __initdata = 0;
+static struct meminfo meminfo __initdata = { 0, };
+static struct proc_info_item proc_info;
+static const char *machine_name;
+static char command_line[COMMAND_LINE_SIZE];
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+
+/*
+ * Standard memory resources
+ */
+static struct resource mem_res[] = {
+ { "Video RAM", 0, 0, IORESOURCE_MEM },
+ { "Kernel code", 0, 0, IORESOURCE_MEM },
+ { "Kernel data", 0, 0, IORESOURCE_MEM }
+};
+
+#define video_ram mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
+
+static struct resource io_res[] = {
+ { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
+};
+
+#define lp0 io_res[0]
+#define lp1 io_res[1]
+#define lp2 io_res[2]
+
+#define dump_cpu_info() do { } while (0)
+
+static void __init setup_processor(void)
+{
+ extern struct proc_info_list __proc_info_begin, __proc_info_end;
+ struct proc_info_list *list;
+
+ /*
+ * 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;
+ /*
+ * 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);
+ }
+
+ proc_info = *list->info;
+ processor = *list->proc;
+
+
+ printk("CPU: %s %s revision %d\n",
+ proc_info.manufacturer, proc_info.cpu_name,
+ (int)processor_id & 15);
+
+ dump_cpu_info();
+
+ sprintf(system_utsname.machine, "%s", list->arch_name);
+ sprintf(elf_platform, "%s", list->elf_name);
+ elf_hwcap = list->elf_hwcap;
+
+ cpu_proc_init();
+}
+
+static struct machine_desc * __init setup_machine(unsigned int nr)
+{
+ extern struct machine_desc __arch_info_begin, __arch_info_end;
+ struct machine_desc *list;
+
+ /*
+ * locate architecture in the list of supported architectures.
+ */
+ for (list = &__arch_info_begin; list < &__arch_info_end; list++)
+ if (list->nr == nr)
+ break;
+
+ /*
+ * If the architecture type is not recognised, then we
+ * can co nothing...
+ */
+ if (list >= &__arch_info_end) {
+ printk("Architecture configuration botched (nr %d), unable "
+ "to continue.\n", nr);
+ while (1);
+ }
+
+ printk("Machine: %s\n", list->name);
+
+ return list;
+}
+
+/*
+ * Initial parsing of the command line. We need to pick out the
+ * memory size. We look for mem=size@start, where start and size
+ * are "size[KkMm]"
+ */
+static void __init
+parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
+{
+ char c = ' ', *to = command_line;
+ int usermem = 0, len = 0;
+
+ for (;;) {
+ if (c == ' ' && !memcmp(from, "mem=", 4)) {
+ unsigned long size, start;
+
+ if (to != command_line)
+ to -= 1;
+
+ /*
+ * If the user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ usermem = 1;
+ mi->nr_banks = 0;
+ }
+
+ start = PHYS_OFFSET;
+ size = memparse(from + 4, &from);
+ if (*from == '@')
+ start = memparse(from + 1, &from);
+
+ mi->bank[mi->nr_banks].start = start;
+ mi->bank[mi->nr_banks].size = size;
+ mi->bank[mi->nr_banks].node = PHYS_TO_NID(start);
+ mi->nr_banks += 1;
+ }
+ c = *from++;
+ if (!c)
+ break;
+ if (COMMAND_LINE_SIZE <= ++len)
+ break;
+ *to++ = c;
+ }
+ *to = '\0';
+ *cmdline_p = command_line;
+}
+
+static void __init
+setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
+{
+#ifdef CONFIG_BLK_DEV_RAM
+ extern int rd_size, rd_image_start, rd_prompt, rd_doload;
+
+ rd_image_start = image_start;
+ rd_prompt = prompt;
+ rd_doload = doload;
+
+ if (rd_sz)
+ rd_size = rd_sz;
+#endif
+}
+
+static void __init
+request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
+{
+ struct resource *res;
+ int i;
+
+ kernel_code.start = init_mm.start_code;
+ kernel_code.end = init_mm.end_code - 1;
+ kernel_data.start = init_mm.end_code;
+ kernel_data.end = init_mm.brk - 1;
+
+ for (i = 0; i < mi->nr_banks; i++) {
+ unsigned long virt_start, virt_end;
+
+ if (mi->bank[i].size == 0)
+ continue;
+
+ virt_start = mi->bank[i].start;
+ virt_end = virt_start + mi->bank[i].size - 1;
+
+ res = alloc_bootmem_low(sizeof(*res));
+ res->name = "System RAM";
+ res->start = virt_start;
+ res->end = virt_end;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ request_resource(&iomem_resource, res);
+
+ if (kernel_code.start >= res->start &&
+ kernel_code.end <= res->end)
+ request_resource(res, &kernel_code);
+ if (kernel_data.start >= res->start &&
+ kernel_data.end <= res->end)
+ request_resource(res, &kernel_data);
+ }
+
+ if (mdesc->video_start) {
+ video_ram.start = mdesc->video_start;
+ video_ram.end = mdesc->video_end;
+ request_resource(&iomem_resource, &video_ram);
+ }
+
+ /*
+ * Some machines don't have the possibility of ever
+ * possessing lp0, lp1 or lp2
+ */
+ if (mdesc->reserve_lp0)
+ request_resource(&ioport_resource, &lp0);
+ if (mdesc->reserve_lp1)
+ request_resource(&ioport_resource, &lp1);
+ if (mdesc->reserve_lp2)
+ request_resource(&ioport_resource, &lp2);
+}
+
+/*
+ * Tag parsing.
+ *
+ * This is the new way of passing data to the kernel at boot time. Rather
+ * than passing a fixed inflexible structure to the kernel, we pass a list
+ * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
+ * tag for the list to be recognised (to distinguish the tagged list from
+ * a param_struct). The list is terminated with a zero-length tag (this tag
+ * is not parsed in any way).
+ */
+static int __init parse_tag_core(const struct tag *tag)
+{
+ if (tag->hdr.size > 2) {
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+ ROOT_DEV = tag->u.core.rootdev;
+ }
+ return 0;
+}
+
+__tagtable(ATAG_CORE, parse_tag_core);
+
+static int __init parse_tag_mem32(const struct tag *tag)
+{
+ if (meminfo.nr_banks >= NR_BANKS) {
+ printk(KERN_WARNING
+ "Ignoring memory bank 0x%08x size %dKB\n",
+ tag->u.mem.start, tag->u.mem.size / 1024);
+ return -EINVAL;
+ }
+ meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
+ meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
+ meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
+ meminfo.nr_banks += 1;
+
+ return 0;
+}
+
+__tagtable(ATAG_MEM, parse_tag_mem32);
+
+#if defined(CONFIG_DUMMY_CONSOLE)
+struct screen_info screen_info = {
+ orig_video_lines: 30,
+ orig_video_cols: 80,
+ orig_video_mode: 0,
+ orig_video_ega_bx: 0,
+ orig_video_isVGA: 1,
+ orig_video_points: 8
+};
+
+static int __init parse_tag_videotext(const struct tag *tag)
+{
+ screen_info.orig_x = tag->u.videotext.x;
+ screen_info.orig_y = tag->u.videotext.y;
+ screen_info.orig_video_page = tag->u.videotext.video_page;
+ screen_info.orig_video_mode = tag->u.videotext.video_mode;
+ screen_info.orig_video_cols = tag->u.videotext.video_cols;
+ screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
+ screen_info.orig_video_lines = tag->u.videotext.video_lines;
+ screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
+ screen_info.orig_video_points = tag->u.videotext.video_points;
+ return 0;
+}
+
+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
+#endif
+
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
+ (tag->u.ramdisk.flags & 2) == 0,
+ tag->u.ramdisk.start, tag->u.ramdisk.size);
+ return 0;
+}
+
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+ printk(KERN_WARNING "ATAG_INITRD is deprecated; please update your bootloader. \n");
+ phys_initrd_start = (unsigned long)tag->u.initrd.start;
+ phys_initrd_size = (unsigned long)tag->u.initrd.size;
+ return 0;
+}
+
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+ printk(KERN_WARNING "ATAG_INITRD is deprecated; please update your bootloader. \n");
+ phys_initrd_start = (unsigned long)tag->u.initrd.start;
+ phys_initrd_size = (unsigned long)tag->u.initrd.size;
+ return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+
+static int __init parse_tag_serialnr(const struct tag *tag)
+{
+ system_serial_low = tag->u.serialnr.low;
+ system_serial_high = tag->u.serialnr.high;
+ return 0;
+}
+
+__tagtable(ATAG_SERIAL, parse_tag_serialnr);
+
+static int __init parse_tag_revision(const struct tag *tag)
+{
+ system_rev = tag->u.revision.rev;
+ return 0;
+}
+
+__tagtable(ATAG_REVISION, parse_tag_revision);
+
+static int __init parse_tag_cmdline(const struct tag *tag)
+{
+ strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+ default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+ return 0;
+}
+
+__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
+
+/*
+ * Scan the tag table for this tag, and call its parse function.
+ * The tag table is built by the linker from all the __tagtable
+ * declarations.
+ */
+static int __init parse_tag(const struct tag *tag)
+{
+ extern struct tagtable __tagtable_begin, __tagtable_end;
+ struct tagtable *t;
+
+ for (t = &__tagtable_begin; t < &__tagtable_end; t++)
+ if (tag->hdr.tag == t->tag) {
+ t->parse(tag);
+ break;
+ }
+
+ return t < &__tagtable_end;
+}
+
+/*
+ * Parse all tags in the list, checking both the global and architecture
+ * specific tag tables.
+ */
+static void __init parse_tags(const struct tag *t)
+{
+ for (; t->hdr.size; t = tag_next(t))
+ if (!parse_tag(t))
+ printk(KERN_WARNING
+ "Ignoring unrecognised tag 0x%08x\n",
+ t->hdr.tag);
+}
+
+/*
+ * This holds our defaults.
+ */
+static struct init_tags {
+ struct tag_header hdr1;
+ struct tag_core core;
+ struct tag_header hdr2;
+ struct tag_mem32 mem;
+ struct tag_header hdr3;
+} init_tags __initdata = {
+ { tag_size(tag_core), ATAG_CORE },
+ { 1, PAGE_SIZE, 0xff },
+ { tag_size(tag_mem32), ATAG_MEM },
+ { MEM_SIZE, PHYS_OFFSET },
+ { 0, ATAG_NONE }
+};
+
+void __init setup_arch(char **cmdline_p)
+{
+ struct tag *tags = (struct tag *)&init_tags;
+ struct machine_desc *mdesc;
+ char *from = default_command_line;
+
+ setup_processor();
+ mdesc = setup_machine(machine_arch_type);
+ machine_name = mdesc->name;
+
+ if (mdesc->param_offset)
+ tags = (struct tag *)mdesc->param_offset; //FIXME - ugly?
+
+ /*
+ * If we have the old style parameters, convert them to
+ * a tag list.
+ */
+ if (tags->hdr.tag != ATAG_CORE)
+ convert_to_tag_list(tags);
+ if (tags->hdr.tag != ATAG_CORE)
+ tags = (struct tag *)&init_tags;
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (meminfo.nr_banks != 0)
+ squash_mem_tags(tags);
+ parse_tags(tags);
+ }
+
+ 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;
+
+ memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+ parse_cmdline(&meminfo, cmdline_p, from);
+ bootmem_init(&meminfo);
+ paging_init(&meminfo);
+ request_standard_resources(&meminfo, mdesc);
+
+ /*
+ * Set up various architecture-specific pointers
+ */
+ init_arch_irq = mdesc->init_irq;
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+static const char *hwcap_str[] = {
+ "swp",
+ "half",
+ "thumb",
+ "26bit",
+ "fastmult",
+ "fpa",
+ "vfp",
+ "edsp",
+ NULL
+};
+
+static int c_show(struct seq_file *m, void *v)
+{
+ int i;
+
+ seq_printf(m, "Processor\t: %s %s rev %d (%s)\n",
+ proc_info.manufacturer, proc_info.cpu_name,
+ (int)processor_id & 15, elf_platform);
+
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
+
+ /* dump out the processor features */
+ seq_puts(m, "Features\t: ");
+
+ for (i = 0; hwcap_str[i]; i++)
+ if (elf_hwcap & (1 << i))
+ seq_printf(m, "%s ", hwcap_str[i]);
+
+ seq_puts(m, "\n");
+
+ seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
+ seq_printf(m, "CPU revision\t: %d\n\n", processor_id & 15);
+ seq_printf(m, "Hardware\t: %s\n", machine_name);
+ seq_printf(m, "Revision\t: %04x\n", system_rev);
+ seq_printf(m, "Serial\t\t: %08x%08x\n",
+ system_serial_high, system_serial_low);
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show
+};
diff -urN linux-2.5.70-bk13/arch/arm26/kernel/signal.c linux-2.5.70-bk14/arch/arm26/kernel/signal.c
--- linux-2.5.70-bk13/arch/arm26/kernel/signal.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk14/arch/arm26/kernel/signal.c 2003-06-09 04:42:02.000000000 -0700
@@ -0,0 +1,542 @@
+/*
+ * linux/arch/arm26/kernel/signal.c
+ *
+ * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 2003 Ian Molton (ARM26)
+ *
+ * FIXME!!! This is probably very broken (13/05/2003)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include