aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS15
-rw-r--r--arch/arm/nwfpe/Makefile1
-rw-r--r--arch/arm/nwfpe/entry26.S112
-rw-r--r--arch/arm26/ACKNOWLEDGEMENTS29
-rw-r--r--arch/arm26/Kconfig253
-rw-r--r--arch/arm26/Kconfig.debug50
-rw-r--r--arch/arm26/Makefile107
-rw-r--r--arch/arm26/boot/Makefile83
-rw-r--r--arch/arm26/boot/compressed/Makefile50
-rw-r--r--arch/arm26/boot/compressed/head.S516
-rw-r--r--arch/arm26/boot/compressed/ll_char_wr.S162
-rw-r--r--arch/arm26/boot/compressed/misc.c316
-rw-r--r--arch/arm26/boot/compressed/uncompress.h110
-rw-r--r--arch/arm26/boot/compressed/vmlinux.lds.in60
-rw-r--r--arch/arm26/boot/install.sh62
-rw-r--r--arch/arm26/defconfig361
-rw-r--r--arch/arm26/kernel/Makefile17
-rw-r--r--arch/arm26/kernel/armksyms.c204
-rw-r--r--arch/arm26/kernel/asm-offsets.c55
-rw-r--r--arch/arm26/kernel/calls.S265
-rw-r--r--arch/arm26/kernel/compat.c173
-rw-r--r--arch/arm26/kernel/dma.c273
-rw-r--r--arch/arm26/kernel/ecard.c847
-rw-r--r--arch/arm26/kernel/entry.S951
-rw-r--r--arch/arm26/kernel/fiq.c201
-rw-r--r--arch/arm26/kernel/head.S112
-rw-r--r--arch/arm26/kernel/init_task.c49
-rw-r--r--arch/arm26/kernel/irq.c722
-rw-r--r--arch/arm26/kernel/process.c392
-rw-r--r--arch/arm26/kernel/ptrace.c670
-rw-r--r--arch/arm26/kernel/ptrace.h13
-rw-r--r--arch/arm26/kernel/semaphore.c222
-rw-r--r--arch/arm26/kernel/setup.c572
-rw-r--r--arch/arm26/kernel/signal.c538
-rw-r--r--arch/arm26/kernel/sys_arm.c323
-rw-r--r--arch/arm26/kernel/time.c210
-rw-r--r--arch/arm26/kernel/traps.c548
-rw-r--r--arch/arm26/kernel/vmlinux-arm26-xip.lds.in136
-rw-r--r--arch/arm26/kernel/vmlinux-arm26.lds.in129
-rw-r--r--arch/arm26/kernel/vmlinux.lds.S11
-rw-r--r--arch/arm26/lib/Makefile26
-rw-r--r--arch/arm26/lib/ashldi3.c61
-rw-r--r--arch/arm26/lib/ashrdi3.c61
-rw-r--r--arch/arm26/lib/backtrace.S144
-rw-r--r--arch/arm26/lib/changebit.S28
-rw-r--r--arch/arm26/lib/clearbit.S31
-rw-r--r--arch/arm26/lib/copy_page.S62
-rw-r--r--arch/arm26/lib/csumipv6.S32
-rw-r--r--arch/arm26/lib/csumpartial.S130
-rw-r--r--arch/arm26/lib/csumpartialcopy.S52
-rw-r--r--arch/arm26/lib/csumpartialcopygeneric.S352
-rw-r--r--arch/arm26/lib/csumpartialcopyuser.S114
-rw-r--r--arch/arm26/lib/delay.S57
-rw-r--r--arch/arm26/lib/ecard.S40
-rw-r--r--arch/arm26/lib/findbit.S67
-rw-r--r--arch/arm26/lib/floppydma.S32
-rw-r--r--arch/arm26/lib/gcclib.h21
-rw-r--r--arch/arm26/lib/getuser.S112
-rw-r--r--arch/arm26/lib/io-acorn.S70
-rw-r--r--arch/arm26/lib/io-readsb.S116
-rw-r--r--arch/arm26/lib/io-readsl.S78
-rw-r--r--arch/arm26/lib/io-readsw.S107
-rw-r--r--arch/arm26/lib/io-writesb.S122
-rw-r--r--arch/arm26/lib/io-writesl.S56
-rw-r--r--arch/arm26/lib/io-writesw.S127
-rw-r--r--arch/arm26/lib/kbd.c278
-rw-r--r--arch/arm26/lib/lib1funcs.S313
-rw-r--r--arch/arm26/lib/longlong.h184
-rw-r--r--arch/arm26/lib/lshrdi3.c61
-rw-r--r--arch/arm26/lib/memchr.S25
-rw-r--r--arch/arm26/lib/memcpy.S318
-rw-r--r--arch/arm26/lib/memset.S80
-rw-r--r--arch/arm26/lib/memzero.S80
-rw-r--r--arch/arm26/lib/muldi3.c77
-rw-r--r--arch/arm26/lib/putuser.S109
-rw-r--r--arch/arm26/lib/setbit.S29
-rw-r--r--arch/arm26/lib/strchr.S25
-rw-r--r--arch/arm26/lib/strrchr.S25
-rw-r--r--arch/arm26/lib/testchangebit.S29
-rw-r--r--arch/arm26/lib/testclearbit.S29
-rw-r--r--arch/arm26/lib/testsetbit.S29
-rw-r--r--arch/arm26/lib/uaccess-kernel.S173
-rw-r--r--arch/arm26/lib/uaccess-user.S718
-rw-r--r--arch/arm26/lib/ucmpdi2.c51
-rw-r--r--arch/arm26/lib/udivdi3.c242
-rw-r--r--arch/arm26/machine/Makefile8
-rw-r--r--arch/arm26/machine/dma.c214
-rw-r--r--arch/arm26/machine/irq.c164
-rw-r--r--arch/arm26/machine/latches.c72
-rw-r--r--arch/arm26/mm/Makefile6
-rw-r--r--arch/arm26/mm/extable.c24
-rw-r--r--arch/arm26/mm/fault.c312
-rw-r--r--arch/arm26/mm/fault.h5
-rw-r--r--arch/arm26/mm/init.c403
-rw-r--r--arch/arm26/mm/memc.c184
-rw-r--r--arch/arm26/mm/proc-funcs.S359
-rw-r--r--arch/arm26/mm/small_page.c192
-rw-r--r--arch/arm26/nwfpe/ARM-gcc.h120
-rw-r--r--arch/arm26/nwfpe/ChangeLog83
-rw-r--r--arch/arm26/nwfpe/Makefile15
-rw-r--r--arch/arm26/nwfpe/double_cpdo.c288
-rw-r--r--arch/arm26/nwfpe/entry.S114
-rw-r--r--arch/arm26/nwfpe/extended_cpdo.c273
-rw-r--r--arch/arm26/nwfpe/fpa11.c221
-rw-r--r--arch/arm26/nwfpe/fpa11.h87
-rw-r--r--arch/arm26/nwfpe/fpa11.inl51
-rw-r--r--arch/arm26/nwfpe/fpa11_cpdo.c117
-rw-r--r--arch/arm26/nwfpe/fpa11_cpdt.c368
-rw-r--r--arch/arm26/nwfpe/fpa11_cprt.c289
-rw-r--r--arch/arm26/nwfpe/fpmodule.c180
-rw-r--r--arch/arm26/nwfpe/fpmodule.h46
-rw-r--r--arch/arm26/nwfpe/fpmodule.inl84
-rw-r--r--arch/arm26/nwfpe/fpopcode.c148
-rw-r--r--arch/arm26/nwfpe/fpopcode.h390
-rw-r--r--arch/arm26/nwfpe/fpsr.h108
-rw-r--r--arch/arm26/nwfpe/milieu.h48
-rw-r--r--arch/arm26/nwfpe/single_cpdo.c255
-rw-r--r--arch/arm26/nwfpe/softfloat-macros740
-rw-r--r--arch/arm26/nwfpe/softfloat-specialize366
-rw-r--r--arch/arm26/nwfpe/softfloat.c3439
-rw-r--r--arch/arm26/nwfpe/softfloat.h232
-rw-r--r--drivers/acorn/README1
-rw-r--r--drivers/acorn/block/Kconfig36
-rw-r--r--drivers/acorn/block/Makefile9
-rw-r--r--drivers/acorn/block/fd1772.c1604
-rw-r--r--drivers/acorn/block/fd1772dma.S100
-rw-r--r--drivers/acorn/block/mfm.S162
-rw-r--r--drivers/acorn/block/mfmhd.c1385
-rw-r--r--drivers/ide/Kconfig2
-rw-r--r--drivers/ide/arm/ide_arm.c20
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/scsi/arm/Kconfig9
-rw-r--r--drivers/scsi/arm/Makefile1
-rw-r--r--drivers/scsi/arm/ecoscsi.c166
-rw-r--r--drivers/video/acornfb.c20
-rw-r--r--include/asm-arm26/a.out.h39
-rw-r--r--include/asm-arm26/assembler.h106
-rw-r--r--include/asm-arm26/atomic.h123
-rw-r--r--include/asm-arm26/auxvec.h4
-rw-r--r--include/asm-arm26/bitops.h207
-rw-r--r--include/asm-arm26/bug.h19
-rw-r--r--include/asm-arm26/bugs.h15
-rw-r--r--include/asm-arm26/byteorder.h24
-rw-r--r--include/asm-arm26/cache.h12
-rw-r--r--include/asm-arm26/cacheflush.h53
-rw-r--r--include/asm-arm26/checksum.h151
-rw-r--r--include/asm-arm26/constants.h28
-rw-r--r--include/asm-arm26/cputime.h6
-rw-r--r--include/asm-arm26/current.h15
-rw-r--r--include/asm-arm26/delay.h34
-rw-r--r--include/asm-arm26/device.h7
-rw-r--r--include/asm-arm26/div64.h1
-rw-r--r--include/asm-arm26/dma.h183
-rw-r--r--include/asm-arm26/ecard.h294
-rw-r--r--include/asm-arm26/elf.h77
-rw-r--r--include/asm-arm26/emergency-restart.h6
-rw-r--r--include/asm-arm26/errno.h6
-rw-r--r--include/asm-arm26/fb.h12
-rw-r--r--include/asm-arm26/fcntl.h13
-rw-r--r--include/asm-arm26/fiq.h37
-rw-r--r--include/asm-arm26/floppy.h141
-rw-r--r--include/asm-arm26/fpstate.h29
-rw-r--r--include/asm-arm26/futex.h6
-rw-r--r--include/asm-arm26/hardirq.h32
-rw-r--r--include/asm-arm26/hardware.h109
-rw-r--r--include/asm-arm26/ide.h34
-rw-r--r--include/asm-arm26/io.h434
-rw-r--r--include/asm-arm26/ioc.h72
-rw-r--r--include/asm-arm26/ioctl.h1
-rw-r--r--include/asm-arm26/ioctls.h85
-rw-r--r--include/asm-arm26/ipc.h1
-rw-r--r--include/asm-arm26/ipcbuf.h29
-rw-r--r--include/asm-arm26/irq.h43
-rw-r--r--include/asm-arm26/irqchip.h101
-rw-r--r--include/asm-arm26/kdebug.h1
-rw-r--r--include/asm-arm26/kmap_types.h12
-rw-r--r--include/asm-arm26/leds.h50
-rw-r--r--include/asm-arm26/limits.h11
-rw-r--r--include/asm-arm26/linkage.h7
-rw-r--r--include/asm-arm26/local.h2
-rw-r--r--include/asm-arm26/locks.h161
-rw-r--r--include/asm-arm26/mach-types.h36
-rw-r--r--include/asm-arm26/map.h24
-rw-r--r--include/asm-arm26/mc146818rtc.h28
-rw-r--r--include/asm-arm26/memory.h101
-rw-r--r--include/asm-arm26/mman.h17
-rw-r--r--include/asm-arm26/mmu.h9
-rw-r--r--include/asm-arm26/mmu_context.h53
-rw-r--r--include/asm-arm26/module.h7
-rw-r--r--include/asm-arm26/msgbuf.h31
-rw-r--r--include/asm-arm26/namei.h25
-rw-r--r--include/asm-arm26/oldlatches.h37
-rw-r--r--include/asm-arm26/page.h102
-rw-r--r--include/asm-arm26/param.h33
-rw-r--r--include/asm-arm26/parport.h18
-rw-r--r--include/asm-arm26/pci.h6
-rw-r--r--include/asm-arm26/percpu.h6
-rw-r--r--include/asm-arm26/pgalloc.h70
-rw-r--r--include/asm-arm26/pgtable.h298
-rw-r--r--include/asm-arm26/poll.h8
-rw-r--r--include/asm-arm26/posix_types.h81
-rw-r--r--include/asm-arm26/proc-fns.h49
-rw-r--r--include/asm-arm26/processor.h113
-rw-r--r--include/asm-arm26/procinfo.h56
-rw-r--r--include/asm-arm26/ptrace.h104
-rw-r--r--include/asm-arm26/resource.h6
-rw-r--r--include/asm-arm26/scatterlist.h26
-rw-r--r--include/asm-arm26/sections.h2
-rw-r--r--include/asm-arm26/segment.h11
-rw-r--r--include/asm-arm26/semaphore-helper.h84
-rw-r--r--include/asm-arm26/semaphore.h100
-rw-r--r--include/asm-arm26/sembuf.h25
-rw-r--r--include/asm-arm26/serial.h44
-rw-r--r--include/asm-arm26/setup.h209
-rw-r--r--include/asm-arm26/shmbuf.h42
-rw-r--r--include/asm-arm26/shmparam.h15
-rw-r--r--include/asm-arm26/sigcontext.h33
-rw-r--r--include/asm-arm26/siginfo.h6
-rw-r--r--include/asm-arm26/signal.h176
-rw-r--r--include/asm-arm26/sizes.h52
-rw-r--r--include/asm-arm26/smp.h9
-rw-r--r--include/asm-arm26/socket.h55
-rw-r--r--include/asm-arm26/sockios.h13
-rw-r--r--include/asm-arm26/spinlock.h6
-rw-r--r--include/asm-arm26/stat.h77
-rw-r--r--include/asm-arm26/statfs.h8
-rw-r--r--include/asm-arm26/string.h43
-rw-r--r--include/asm-arm26/suspend.h4
-rw-r--r--include/asm-arm26/sysirq.h60
-rw-r--r--include/asm-arm26/system.h247
-rw-r--r--include/asm-arm26/termbits.h196
-rw-r--r--include/asm-arm26/termios.h92
-rw-r--r--include/asm-arm26/thread_info.h137
-rw-r--r--include/asm-arm26/timex.h29
-rw-r--r--include/asm-arm26/tlb.h63
-rw-r--r--include/asm-arm26/tlbflush.h70
-rw-r--r--include/asm-arm26/topology.h6
-rw-r--r--include/asm-arm26/types.h59
-rw-r--r--include/asm-arm26/uaccess-asm.h153
-rw-r--r--include/asm-arm26/uaccess.h293
-rw-r--r--include/asm-arm26/ucontext.h12
-rw-r--r--include/asm-arm26/unaligned.h118
-rw-r--r--include/asm-arm26/uncompress.h111
-rw-r--r--include/asm-arm26/unistd.h343
-rw-r--r--include/asm-arm26/user.h84
-rw-r--r--include/asm-arm26/xor.h141
-rw-r--r--include/linux/mmzone.h1
-rw-r--r--lib/Kconfig.debug2
248 files changed, 9 insertions, 35814 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index ce8066d3604e..c29289760741 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -387,21 +387,6 @@ P: Jaya Kumar
387M: jayalk@intworks.biz 387M: jayalk@intworks.biz
388S: Maintained 388S: Maintained
389 389
390ARM26 ARCHITECTURE
391P: Ian Molton
392M: spyro@f2s.com
393S: Maintained
394
395ARM26/ARCHIMEDES
396P: Ian Molton
397M: spyro@f2s.com
398S: Maintained
399
400ARM26/A5000
401P: John Appleby
402M: john@dnsworld.co.uk
403S: Maintained
404
405ARM MFM AND FLOPPY DRIVERS 390ARM MFM AND FLOPPY DRIVERS
406P: Ian Molton 391P: Ian Molton
407M: spyro@f2s.com 392M: spyro@f2s.com
diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
index ed7b26bf73f5..b29178c0414e 100644
--- a/arch/arm/nwfpe/Makefile
+++ b/arch/arm/nwfpe/Makefile
@@ -9,5 +9,4 @@ nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
9 softfloat.o single_cpdo.o double_cpdo.o 9 softfloat.o single_cpdo.o double_cpdo.o
10 10
11nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o 11nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o
12nwfpe-$(CONFIG_CPU_26) += entry26.o
13nwfpe-$(CONFIG_CPU_32) += entry.o 12nwfpe-$(CONFIG_CPU_32) += entry.o
diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S
deleted file mode 100644
index 3e6fb5d21d64..000000000000
--- a/arch/arm/nwfpe/entry26.S
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998
4 (c) Philip Blundell 1998-1999
5
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <asm/asm-offsets.h>
24
25/* This is the kernel's entry point into the floating point emulator.
26It is called from the kernel with code similar to this:
27
28 mov fp, #0
29 teqp pc, #PSR_I_BIT | SVC_MODE
30 ldr r4, .LC2
31 ldr pc, [r4] @ Call FP module USR entry point
32
33The kernel expects the emulator to return via one of two possible
34points of return it passes to the emulator. The emulator, if
35successful in its emulation, jumps to ret_from_exception and the
36kernel takes care of returning control from the trap to the user code.
37If the emulator is unable to emulate the instruction, it returns to
38fpundefinstr and the kernel halts the user program with a core dump.
39
40This routine does four things:
41
421) It saves SP into a variable called userRegisters. The kernel has
43created a struct pt_regs on the stack and saved the user registers
44into it. See /usr/include/asm/proc/ptrace.h for details. The
45emulator code uses userRegisters as the base of an array of words from
46which the contents of the registers can be extracted.
47
482) It locates the FP emulator work area within the TSS structure and
49points `fpa11' to it.
50
513) It calls EmulateAll to emulate a floating point instruction.
52EmulateAll returns 1 if the emulation was successful, or 0 if not.
53
544) If an instruction has been emulated successfully, it looks ahead at
55the next instruction. If it is a floating point instruction, it
56executes the instruction, without returning to user space. In this
57way it repeatedly looks ahead and executes floating point instructions
58until it encounters a non floating point instruction, at which time it
59returns via _fpreturn.
60
61This is done to reduce the effect of the trap overhead on each
62floating point instructions. GCC attempts to group floating point
63instructions to allow the emulator to spread the cost of the trap over
64several floating point instructions. */
65
66 .globl nwfpe_enter
67nwfpe_enter:
68 mov sl, sp
69 ldr r5, [sp, #60] @ get contents of PC
70 bic r5, r5, #0xfc000003
71 ldr r0, [r5, #-4] @ get actual instruction into r0
72 bl EmulateAll @ emulate the instruction
731: cmp r0, #0 @ was emulation successful
74 beq fpundefinstr @ no, return failure
75
76next:
77.Lx1: ldrt r6, [r5], #4 @ get the next instruction and
78 @ increment PC
79
80 and r2, r6, #0x0F000000 @ test for FP insns
81 teq r2, #0x0C000000
82 teqne r2, #0x0D000000
83 teqne r2, #0x0E000000
84 bne ret_from_exception @ return ok if not a fp insn
85
86 ldr r9, [sp, #60] @ get new condition codes
87 and r9, r9, #0xfc000003
88 orr r7, r5, r9
89 str r7, [sp, #60] @ update PC copy in regs
90
91 mov r0, r6 @ save a copy
92 mov r1, r9 @ fetch the condition codes
93 bl checkCondition @ check the condition
94 cmp r0, #0 @ r0 = 0 ==> condition failed
95
96 @ if condition code failed to match, next insn
97 beq next @ get the next instruction;
98
99 mov r0, r6 @ prepare for EmulateAll()
100 adr lr, 1b
101 orr lr, lr, #3
102 b EmulateAll @ if r0 != 0, goto EmulateAll
103
104.Lret: b ret_from_exception @ let the user eat segfaults
105
106 @ We need to be prepared for the instruction at .Lx1 to fault.
107 @ Emit the appropriate exception gunk to fix things up.
108 .section __ex_table,"a"
109 .align 3
110 .long .Lx1
111 ldr lr, [lr, $(.Lret - .Lx1)/4]
112 .previous
diff --git a/arch/arm26/ACKNOWLEDGEMENTS b/arch/arm26/ACKNOWLEDGEMENTS
deleted file mode 100644
index 0a17a45110e7..000000000000
--- a/arch/arm26/ACKNOWLEDGEMENTS
+++ /dev/null
@@ -1,29 +0,0 @@
1The work in this architecture (ARM26) is that of a great many people.
2
3This is what has happened:
4
5I [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.
6
7As 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.
8
9The 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.
10
11People I KNOW have made major contributions to the code:
12
13David Alan Gilbert (former maintainer of ARM26 bits)
14Philip Blundell
15Russell King
16Keith Owens
17
18also thanks to Nicholas Pitre for hints, and for the basis or our XIP support.
19
20Currently maintaing the code are
21
22Ian Molton (Maintainer / Archimedes)
23John Appleby (kernel / A5K)
24
25If anyone has a problem with attributions in header files / source files, please do contact me to straighten things out.
26
27Ian Molton (aka spyro) - ARM26 maintainer
28spyro@f2s.com
29
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
deleted file mode 100644
index 9044f33299f7..000000000000
--- a/arch/arm26/Kconfig
+++ /dev/null
@@ -1,253 +0,0 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6mainmenu "Linux Kernel Configuration"
7
8config ARM
9 bool
10 default y
11
12config ARM26
13 bool
14 default y
15
16config MMU
17 bool
18 default y
19
20config NO_DMA
21 def_bool y
22
23config ARCH_ACORN
24 bool
25 default y
26
27config CPU_26
28 bool
29 default y
30
31config FIQ
32 bool
33 default y
34
35# 9 = 512 pages 8 = 256 pages 7 = 128 pages
36config FORCE_MAX_ZONEORDER
37 int
38 default 9
39
40config RWSEM_GENERIC_SPINLOCK
41 bool
42 default y
43
44config RWSEM_XCHGADD_ALGORITHM
45 bool
46
47config ARCH_HAS_ILOG2_U32
48 bool
49 default n
50
51config ARCH_HAS_ILOG2_U64
52 bool
53 default n
54
55config GENERIC_HWEIGHT
56 bool
57 default y
58
59config GENERIC_CALIBRATE_DELAY
60 bool
61 default y
62
63config ZONE_DMA
64 bool
65 default y
66
67config GENERIC_ISA_DMA
68 bool
69
70config ARCH_MAY_HAVE_PC_FDC
71 bool
72
73source "init/Kconfig"
74
75
76menu "System Type"
77
78choice
79 prompt "Archimedes/A5000 Implementations"
80
81config ARCH_ARC
82 bool "Archimedes"
83 help
84 Say Y to support the Acorn Archimedes.
85
86 The Acorn Archimedes was an personal computer based on an 8MHz ARM2
87 processor, released in 1987. It supported up to 16MB of RAM in
88 later models and floppy, harddisc, ethernet etc.
89
90config ARCH_A5K
91 bool "A5000"
92 select ARCH_MAY_HAVE_PC_FDC
93 help
94 Say Y here to support the Acorn A5000.
95
96 Linux can support the
97 internal IDE disk and CD-ROM interface, serial and parallel port,
98 and the floppy drive. Note that on some A5000s the floppy is
99 plugged into the wrong socket on the motherboard.
100
101config PAGESIZE_16
102 bool "2MB physical memory (broken)"
103 help
104 Say Y here if your Archimedes or A5000 system has only 2MB of
105 memory, otherwise say N. The resulting kernel will not run on a
106 machine with 4MB of memory.
107endchoice
108endmenu
109
110config ISA_DMA_API
111 bool
112 default y
113
114menu "General setup"
115
116# Compressed boot loader in ROM. Yes, we really want to ask about
117# TEXT and BSS so we preserve their values in the config files.
118config ZBOOT_ROM
119 bool "Compressed boot loader in ROM/flash"
120 help
121 Say Y here if you intend to execute your compressed kernel image (zImage)
122 directly from ROM or flash. If unsure, say N.
123
124config ZBOOT_ROM_TEXT
125 depends on ZBOOT_ROM
126 hex "Compressed ROM boot loader base address"
127 default "0"
128 help
129 The base address for zImage. Unless you have special requirements, you
130 should not change this value.
131
132config ZBOOT_ROM_BSS
133 depends on ZBOOT_ROM
134 hex "Compressed ROM boot loader BSS address"
135 default "0"
136 help
137 The base address of 64KiB of read/write memory, which must be available
138 while the decompressor is running. Unless you have special requirements,
139 you should not change this value.
140
141config XIP_KERNEL
142 bool "Execute In Place (XIP) kernel image"
143 help
144 Select this option to create a kernel that can be programmed into
145 the OS ROMs.
146
147comment "At least one math emulation must be selected"
148
149config FPE_NWFPE
150 tristate "NWFPE math emulation"
151 ---help---
152 Say Y to include the NWFPE floating point emulator in the kernel.
153 This is necessary to run most binaries. Linux does not currently
154 support floating point hardware so you need to say Y here even if
155 your machine has an FPA or floating point co-processor module.
156
157 It is also possible to say M to build the emulator as a module
158 (nwfpe) or indeed to leave it out altogether. However, unless you
159 know what you are doing this can easily render your machine
160 unbootable. Saying Y is the safe option.
161
162 You may say N here if you are going to load the Acorn FPEmulator
163 early in the bootup.
164
165source "fs/Kconfig.binfmt"
166
167config PREEMPT
168 bool "Preemptible Kernel (EXPERIMENTAL)"
169 depends on CPU_32 && EXPERIMENTAL
170 help
171 This option reduces the latency of the kernel when reacting to
172 real-time or interactive events by allowing a low priority process to
173 be preempted even if it is in kernel mode executing a system call.
174 This allows applications to run more reliably even when the system is
175 under load.
176
177 Say Y here if you are building a kernel for a desktop, embedded
178 or real-time system. Say N if you are unsure.
179
180config ARTHUR
181 tristate "RISC OS personality"
182 depends on CPU_32
183 help
184 Say Y here to include the kernel code necessary if you want to run
185 Acorn RISC OS/Arthur binaries under Linux. This code is still very
186 experimental; if this sounds frightening, say N and sleep in peace.
187 You can also say M here to compile this support as a module (which
188 will be called arthur).
189
190config CMDLINE
191 string "Default kernel command string"
192 default ""
193 help
194 On some architectures (EBSA110 and CATS), there is currently no way
195 for the boot loader to pass arguments to the kernel. For these
196 architectures, you should supply some command-line options at build
197 time by entering them here. As a minimum, you should specify the
198 memory size and the root device (e.g., mem=64M root=/dev/nfs).
199
200source "mm/Kconfig"
201
202endmenu
203
204source "net/Kconfig"
205
206source "drivers/base/Kconfig"
207
208source "drivers/parport/Kconfig"
209
210source "drivers/pnp/Kconfig"
211
212source "drivers/block/Kconfig"
213
214source "drivers/md/Kconfig"
215
216source "drivers/net/Kconfig"
217
218source "drivers/ide/Kconfig"
219
220source "drivers/scsi/Kconfig"
221
222source "drivers/isdn/Kconfig"
223
224#
225# input before char - char/joystick depends on it. As does USB.
226#
227source "drivers/input/Kconfig"
228
229source "drivers/char/Kconfig"
230
231source "drivers/media/Kconfig"
232
233source "fs/Kconfig"
234
235source "drivers/video/Kconfig"
236
237if ARCH_ACORN
238
239source "sound/Kconfig"
240
241endif
242
243source "drivers/misc/Kconfig"
244
245source "drivers/usb/Kconfig"
246
247source "arch/arm26/Kconfig.debug"
248
249source "security/Kconfig"
250
251source "crypto/Kconfig"
252
253source "lib/Kconfig"
diff --git a/arch/arm26/Kconfig.debug b/arch/arm26/Kconfig.debug
deleted file mode 100644
index 611fc86503fc..000000000000
--- a/arch/arm26/Kconfig.debug
+++ /dev/null
@@ -1,50 +0,0 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5# RMK wants arm kernels compiled with frame pointers so hardwire this to y.
6# If you know what you are doing and are willing to live without stack
7# traces, you can get a slightly smaller kernel by setting this option to
8# n, but then RMK will have to kill you ;).
9config FRAME_POINTER
10 bool
11 default y
12 help
13 If you say N here, the resulting kernel will be slightly smaller and
14 faster. However, when a problem occurs with the kernel, the
15 information that is reported is severely limited. Most people
16 should say Y here.
17
18config DEBUG_USER
19 bool "Verbose user fault messages"
20 help
21 When a user program crashes due to an exception, the kernel can
22 print a brief message explaining what the problem was. This is
23 sometimes helpful for debugging but serves no purpose on a
24 production system. Most people should say N here.
25
26config DEBUG_WAITQ
27 bool "Wait queue debugging"
28 depends on DEBUG_KERNEL
29
30config DEBUG_ERRORS
31 bool "Verbose kernel error messages"
32 depends on DEBUG_KERNEL
33 help
34 This option controls verbose debugging information which can be
35 printed when the kernel detects an internal error. This debugging
36 information is useful to kernel hackers when tracking down problems,
37 but mostly meaningless to other people. It's safe to say Y unless
38 you are concerned with the code size or don't want to see these
39 messages.
40
41# These options are only for real kernel hackers who want to get their hands dirty.
42config DEBUG_LL
43 bool "Kernel low-level debugging functions"
44 depends on DEBUG_KERNEL
45 help
46 Say Y here to include definitions of printascii, printchar, printhex
47 in the kernel. This is helpful if you are debugging code that
48 executes before the console is initialized.
49
50endmenu
diff --git a/arch/arm26/Makefile b/arch/arm26/Makefile
deleted file mode 100644
index fe91eda98a94..000000000000
--- a/arch/arm26/Makefile
+++ /dev/null
@@ -1,107 +0,0 @@
1#
2# arch/arm26/Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies.
6#
7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive
9# for more details.
10#
11# Copyright (C) 1995-2001 by Russell King
12# Copyright (c) 2004 Ian Molton
13
14LDFLAGS_vmlinux :=-p -X
15CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
16OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
17GZFLAGS :=-9
18
19ifeq ($(CONFIG_FRAME_POINTER),y)
20CFLAGS +=-fno-omit-frame-pointer -mno-sched-prolog
21endif
22
23CFLAGS_BOOT :=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
24CFLAGS +=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
25AFLAGS +=-mapcs-26 -mcpu=arm3 -msoft-float
26
27ifeq ($(CONFIG_XIP_KERNEL),y)
28 TEXTADDR := 0x03880000
29 DATAADDR := 0x02080000
30else
31 TEXTADDR := 0x02080000
32 DATAADDR := .
33endif
34
35head-y := arch/arm26/kernel/head.o arch/arm26/kernel/init_task.o
36
37ifeq ($(incdir-y),)
38incdir-y :=
39endif
40INCDIR :=
41
42export MACHINE TEXTADDR GZFLAGS CFLAGS_BOOT
43
44# If we have a machine-specific directory, then include it in the build.
45core-y += arch/arm26/kernel/ arch/arm26/mm/ arch/arm26/machine/
46core-$(CONFIG_FPE_NWFPE) += arch/arm26/nwfpe/
47
48libs-y += arch/arm26/lib/
49
50# Default target when executing plain make
51all: zImage
52
53boot := arch/arm26/boot
54
55PHONY += maketools FORCE
56maketools: FORCE
57
58
59# Convert bzImage to zImage
60bzImage: vmlinux
61 $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
62
63zImage Image bootpImage xipImage: vmlinux
64 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
65
66zinstall install: vmlinux
67 $(Q)$(MAKE) $(build)=$(boot) $@
68
69# We use MRPROPER_FILES and CLEAN_FILES now
70archclean:
71 $(Q)$(MAKE) $(clean)=$(boot)
72
73# My testing targets (that short circuit a few dependencies)
74zImg:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
75Img:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/Image
76bp:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/bootpImage
77i:; $(Q)$(MAKE) $(build)=$(boot) install
78zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
79
80#
81# Configuration targets. Use these to select a
82# configuration for your architecture
83%_config:
84 @( \
85 CFG=$(@:_config=); \
86 if [ -f arch/arm26/def-configs/$$CFG ]; then \
87 [ -f .config ] && mv -f .config .config.old; \
88 cp arch/arm26/def-configs/$$CFG .config; \
89 echo "*** Default configuration for $$CFG installed"; \
90 echo "*** Next, you may run 'make oldconfig'"; \
91 else \
92 echo "$$CFG does not exist"; \
93 fi; \
94 )
95
96define archhelp
97 echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
98 echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
99 echo ' bootpImage - Combined zImage and initial RAM disk'
100 echo ' xipImage - eXecute In Place capable image for ROM use (arch/$(ARCH)/boot/xipImage)'
101 echo ' initrd - Create an initial image'
102 echo ' install - Install uncompressed kernel'
103 echo ' zinstall - Install compressed kernel'
104 echo ' Install using (your) ~/bin/installkernel or'
105 echo ' (distribution) /sbin/installkernel or'
106 echo ' install to $$(INSTALL_PATH) and run lilo'
107endef
diff --git a/arch/arm26/boot/Makefile b/arch/arm26/boot/Makefile
deleted file mode 100644
index 68acb7b0d47f..000000000000
--- a/arch/arm26/boot/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
1#
2# arch/arm26/boot/Makefile
3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies.
6#
7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive
9# for more details.
10#
11# Copyright (C) 1995-2002 Russell King
12#
13
14# Note: the following conditions must always be true:
15# ZRELADDR == virt_to_phys(TEXTADDR)
16# PARAMS_PHYS must be with 4MB of ZRELADDR
17# INITRD_PHYS must be in RAM
18
19 zreladdr-y := 0x02080000
20params_phys-y := 0x0207c000
21initrd_phys-y := 0x02180000
22
23ZRELADDR := 0x02080000
24ZTEXTADDR := 0x0207c000
25PARAMS_PHYS := $(params_phys-y)
26INITRD_PHYS := 0x02180000
27
28# We now have a PIC decompressor implementation. Decompressors running
29# from RAM should not define ZTEXTADDR. Decompressors running directly
30# from ROM or Flash must define ZTEXTADDR (preferably via the config)
31# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
32ifeq ($(CONFIG_ZBOOT_ROM),y)
33ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
34ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
35else
36ZTEXTADDR := 0
37ZBSSADDR := ALIGN(4)
38endif
39
40export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
41
42targets := Image zImage bootpImage xipImage
43
44$(obj)/Image: vmlinux FORCE
45 $(call if_changed,objcopy)
46 @echo ' Kernel: $@ is ready'
47
48$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
49 $(call if_changed,objcopy)
50 @echo ' Kernel: $@ is ready'
51
52$(obj)/compressed/vmlinux: vmlinux FORCE
53 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
54
55ifeq ($(CONFIG_XIP_KERNEL),y)
56$(obj)/xipImage: vmlinux FORCE
57# $(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
58# FIXME - where has .pci_fixup crept in from?
59 $(OBJCOPY) -S -O binary -R .data -R .pci_fixup -R .comment vmlinux vmlinux-text.bin
60 $(OBJCOPY) -S -O binary -R .init -R .text -R __ex_table -R .pci_fixup -R __ksymtab -R __ksymtab_gpl -R __kcrctab -R __kcrctab_gpl -R __param -R .comment vmlinux vmlinux-data.bin
61 cat vmlinux-text.bin vmlinux-data.bin > $@
62 $(RM) -f vmlinux-text.bin vmlinux-data.bin
63 @echo ' Kernel: $@ is ready'
64endif
65
66PHONY += initrd
67initrd:
68 @test "$(INITRD_PHYS)" != "" || \
69 (echo This machine does not support INITRD; exit -1)
70 @test "$(INITRD)" != "" || \
71 (echo You must specify INITRD; exit -1)
72
73install: $(obj)/Image
74 $(CONFIG_SHELL) $(obj)/install.sh \
75 $(KERNELRELEASE) \
76 $(obj)/Image System.map "$(INSTALL_PATH)"
77
78zinstall: $(obj)/zImage
79 $(CONFIG_SHELL) $(obj)/install.sh \
80 $(KERNELRELEASE) \
81 $(obj)/zImage System.map "$(INSTALL_PATH)"
82
83subdir- := compressed
diff --git a/arch/arm26/boot/compressed/Makefile b/arch/arm26/boot/compressed/Makefile
deleted file mode 100644
index b1d9ddebbe74..000000000000
--- a/arch/arm26/boot/compressed/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
1#
2# linux/arch/arm26/boot/compressed/Makefile
3#
4# create a compressed vmlinuz image from the original vmlinux
5#
6# Note! ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported
7# from arch/arm26/boot/Makefile
8#
9
10HEAD = head.o
11OBJS = misc.o
12FONTC = drivers/video/console/font_acorn_8x8.c
13
14OBJS += ll_char_wr.o font.o
15CFLAGS_misc.o := -DPARAMS_PHYS=$(PARAMS_PHYS)
16
17targets := vmlinux vmlinux.lds piggy piggy.gz piggy.o font.o head.o $(OBJS)
18
19SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
20
21EXTRA_CFLAGS := $(CFLAGS_BOOT) -fpic
22EXTRA_AFLAGS := -traditional
23
24LDFLAGS_vmlinux := -p -X \
25 $(shell $(CC) $(CFLAGS)) -T
26
27$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
28 $(addprefix $(obj)/, $(OBJS)) FORCE
29 $(call if_changed,ld)
30 @:
31
32
33$(obj)/piggy: vmlinux FORCE
34 $(call if_changed,objcopy)
35
36$(obj)/piggy.gz: $(obj)/piggy FORCE
37 $(call if_changed,gzip)
38
39LDFLAGS_piggy.o := -r -b binary
40$(obj)/piggy.o: $(obj)/piggy.gz FORCE
41 $(call if_changed,ld)
42
43$(obj)/font.o: $(FONTC)
44 $(CC) $(CFLAGS) -Dstatic= -c $(FONTC) -o $(obj)/font.o
45
46$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in Makefile arch/arm26/boot/Makefile .config
47 @sed "$(SEDFLAGS)" < $< > $@
48
49$(obj)/misc.o: $(obj)/misc.c $(obj)/uncompress.h lib/inflate.c
50
diff --git a/arch/arm26/boot/compressed/head.S b/arch/arm26/boot/compressed/head.S
deleted file mode 100644
index 2a2cda36d83b..000000000000
--- a/arch/arm26/boot/compressed/head.S
+++ /dev/null
@@ -1,516 +0,0 @@
1/*
2 * linux/arch/arm26/boot/compressed/head.S
3 *
4 * Copyright (C) 1996-2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11
12/*
13 * Debugging stuff
14 *
15 * Note that these macros must not contain any code which is not
16 * 100% relocatable. Any attempt to do so will result in a crash.
17 * Please select one of the following when turning on debugging.
18 */
19
20 .macro kputc,val
21 mov r0, \val
22 bl putc
23 .endm
24
25 .macro kphex,val,len
26 mov r0, \val
27 mov r1, #\len
28 bl phex
29 .endm
30
31 .macro debug_reloc_start
32 .endm
33
34 .macro debug_reloc_end
35 .endm
36
37 .section ".start", #alloc, #execinstr
38/*
39 * sort out different calling conventions
40 */
41 .align
42start:
43 .type start,#function
44 .rept 8
45 mov r0, r0
46 .endr
47
48 b 1f
49 .word 0x016f2818 @ Magic numbers to help the loader
50 .word start @ absolute load/run zImage address
51 .word _edata @ zImage end address
521: mov r7, r1 @ save architecture ID
53 mov r8, #0 @ save r0
54 teqp pc, #0x0c000003 @ turn off interrupts
55
56 .text
57 adr r0, LC0
58 ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
59 subs r0, r0, r1 @ calculate the delta offset
60
61 teq r0, #0 @ if delta is zero, we're
62 beq not_relocated @ running at the address we
63 @ were linked at.
64
65 add r2, r2, r0 @ different address, so we
66 add r3, r3, r0 @ need to fix up various
67 add r5, r5, r0 @ pointers.
68 add r6, r6, r0
69 add ip, ip, r0
70 add sp, sp, r0
71
721: ldr r1, [r6, #0] @ relocate entries in the GOT
73 add r1, r1, r0 @ table. This fixes up the
74 str r1, [r6], #4 @ C references.
75 cmp r6, ip
76 blo 1b
77
78not_relocated: mov r0, #0
791: str r0, [r2], #4 @ clear bss
80 str r0, [r2], #4
81 str r0, [r2], #4
82 str r0, [r2], #4
83 cmp r2, r3
84 blo 1b
85
86 bl cache_on
87
88 mov r1, sp @ malloc space above stack
89 add r2, sp, #0x10000 @ 64k max
90
91/*
92 * Check to see if we will overwrite ourselves.
93 * r4 = final kernel address
94 * r5 = start of this image
95 * r2 = end of malloc space (and therefore this image)
96 * We basically want:
97 * r4 >= r2 -> OK
98 * r4 + image length <= r5 -> OK
99 */
100 cmp r4, r2
101 bhs wont_overwrite
102 add r0, r4, #4096*1024 @ 4MB largest kernel size
103 cmp r0, r5
104 bls wont_overwrite
105
106 mov r5, r2 @ decompress after malloc space
107 mov r0, r5
108 mov r3, r7
109 bl decompress_kernel
110
111 add r0, r0, #127
112 bic r0, r0, #127 @ align the kernel length
113/*
114 * r0 = decompressed kernel length
115 * r1-r3 = unused
116 * r4 = kernel execution address
117 * r5 = decompressed kernel start
118 * r6 = processor ID
119 * r7 = architecture ID
120 * r8-r14 = unused
121 */
122 add r1, r5, r0 @ end of decompressed kernel
123 adr r2, reloc_start
124 ldr r3, LC1
125 add r3, r2, r3
1261: ldmia r2!, {r8 - r13} @ copy relocation code
127 stmia r1!, {r8 - r13}
128 ldmia r2!, {r8 - r13}
129 stmia r1!, {r8 - r13}
130 cmp r2, r3
131 blo 1b
132
133 bl cache_clean_flush
134 add pc, r5, r0 @ call relocation code
135
136/*
137 * We're not in danger of overwriting ourselves. Do this the simple way.
138 *
139 * r4 = kernel execution address
140 * r7 = architecture ID
141 */
142wont_overwrite: mov r0, r4
143 mov r3, r7
144 bl decompress_kernel
145 b call_kernel
146
147 .type LC0, #object
148LC0: .word LC0 @ r1
149 .word __bss_start @ r2
150 .word _end @ r3
151 .word _load_addr @ r4
152 .word _start @ r5
153 .word _got_start @ r6
154 .word _got_end @ ip
155 .word user_stack+4096 @ sp
156LC1: .word reloc_end - reloc_start
157 .size LC0, . - LC0
158
159/*
160 * Turn on the cache. We need to setup some page tables so that we
161 * can have both the I and D caches on.
162 *
163 * We place the page tables 16k down from the kernel execution address,
164 * and we hope that nothing else is using it. If we're using it, we
165 * will go pop!
166 *
167 * On entry,
168 * r4 = kernel execution address
169 * r6 = processor ID
170 * r7 = architecture number
171 * r8 = run-time address of "start"
172 * On exit,
173 * r1, r2, r3, r8, r9, r12 corrupted
174 * This routine must preserve:
175 * r4, r5, r6, r7
176 */
177 .align 5
178cache_on: mov r3, #8 @ cache_on function
179 b call_cache_fn
180
181__setup_mmu: sub r3, r4, #16384 @ Page directory size
182 bic r3, r3, #0xff @ Align the pointer
183 bic r3, r3, #0x3f00
184/*
185 * Initialise the page tables, turning on the cacheable and bufferable
186 * bits for the RAM area only.
187 */
188 mov r0, r3
189 mov r8, r0, lsr #18
190 mov r8, r8, lsl #18 @ start of RAM
191 add r9, r8, #0x10000000 @ a reasonable RAM size
192 mov r1, #0x12
193 orr r1, r1, #3 << 10
194 add r2, r3, #16384
1951: cmp r1, r8 @ if virt > start of RAM
196 orrhs r1, r1, #0x0c @ set cacheable, bufferable
197 cmp r1, r9 @ if virt > end of RAM
198 bichs r1, r1, #0x0c @ clear cacheable, bufferable
199 str r1, [r0], #4 @ 1:1 mapping
200 add r1, r1, #1048576
201 teq r0, r2
202 bne 1b
203/*
204 * If ever we are running from Flash, then we surely want the cache
205 * to be enabled also for our execution instance... We map 2MB of it
206 * so there is no map overlap problem for up to 1 MB compressed kernel.
207 * If the execution is in RAM then we would only be duplicating the above.
208 */
209 mov r1, #0x1e
210 orr r1, r1, #3 << 10
211 mov r2, pc, lsr #20
212 orr r1, r1, r2, lsl #20
213 add r0, r3, r2, lsl #2
214 str r1, [r0], #4
215 add r1, r1, #1048576
216 str r1, [r0]
217 mov pc, lr
218
219__armv4_cache_on:
220 mov r12, lr
221 bl __setup_mmu
222 mov r0, #0
223 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
224 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
225 mrc p15, 0, r0, c1, c0, 0 @ read control reg
226 orr r0, r0, #0x1000 @ I-cache enable
227 orr r0, r0, #0x0030
228 b __common_cache_on
229
230__arm6_cache_on:
231 mov r12, lr
232 bl __setup_mmu
233 mov r0, #0
234 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
235 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
236 mov r0, #0x30
237__common_cache_on:
238#ifndef DEBUG
239 orr r0, r0, #0x000d @ Write buffer, mmu
240#endif
241 mov r1, #-1
242 mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
243 mcr p15, 0, r1, c3, c0, 0 @ load domain access control
244 mcr p15, 0, r0, c1, c0, 0 @ load control register
245 mov pc, r12
246
247/*
248 * All code following this line is relocatable. It is relocated by
249 * the above code to the end of the decompressed kernel image and
250 * executed there. During this time, we have no stacks.
251 *
252 * r0 = decompressed kernel length
253 * r1-r3 = unused
254 * r4 = kernel execution address
255 * r5 = decompressed kernel start
256 * r6 = processor ID
257 * r7 = architecture ID
258 * r8-r14 = unused
259 */
260 .align 5
261reloc_start: add r8, r5, r0
262 debug_reloc_start
263 mov r1, r4
2641:
265 .rept 4
266 ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
267 stmia r1!, {r0, r2, r3, r9 - r13}
268 .endr
269
270 cmp r5, r8
271 blo 1b
272 debug_reloc_end
273
274call_kernel: bl cache_clean_flush
275 bl cache_off
276 mov r0, #0
277 mov r1, r7 @ restore architecture number
278 mov pc, r4 @ call kernel
279
280/*
281 * Here follow the relocatable cache support functions for the
282 * various processors. This is a generic hook for locating an
283 * entry and jumping to an instruction at the specified offset
284 * from the start of the block. Please note this is all position
285 * independent code.
286 *
287 * r1 = corrupted
288 * r2 = corrupted
289 * r3 = block offset
290 * r6 = corrupted
291 * r12 = corrupted
292 */
293
294call_cache_fn: adr r12, proc_types
295 mrc p15, 0, r6, c0, c0 @ get processor ID
2961: ldr r1, [r12, #0] @ get value
297 ldr r2, [r12, #4] @ get mask
298 eor r1, r1, r6 @ (real ^ match)
299 tst r1, r2 @ & mask
300 addeq pc, r12, r3 @ call cache function
301 add r12, r12, #4*5
302 b 1b
303
304/*
305 * Table for cache operations. This is basically:
306 * - CPU ID match
307 * - CPU ID mask
308 * - 'cache on' method instruction
309 * - 'cache off' method instruction
310 * - 'cache flush' method instruction
311 *
312 * We match an entry using: ((real_id ^ match) & mask) == 0
313 *
314 * Writethrough caches generally only need 'on' and 'off'
315 * methods. Writeback caches _must_ have the flush method
316 * defined.
317 */
318 .type proc_types,#object
319proc_types:
320 .word 0x41560600 @ ARM6/610
321 .word 0xffffffe0
322 b __arm6_cache_off @ works, but slow
323 b __arm6_cache_off
324 mov pc, lr
325@ b __arm6_cache_on @ untested
326@ b __arm6_cache_off
327@ b __armv3_cache_flush
328
329 .word 0x41007000 @ ARM7/710
330 .word 0xfff8fe00
331 b __arm7_cache_off
332 b __arm7_cache_off
333 mov pc, lr
334
335 .word 0x41807200 @ ARM720T (writethrough)
336 .word 0xffffff00
337 b __armv4_cache_on
338 b __armv4_cache_off
339 mov pc, lr
340
341 .word 0x41129200 @ ARM920T
342 .word 0xff00fff0
343 b __armv4_cache_on
344 b __armv4_cache_off
345 b __armv4_cache_flush
346
347 .word 0x4401a100 @ sa110 / sa1100
348 .word 0xffffffe0
349 b __armv4_cache_on
350 b __armv4_cache_off
351 b __armv4_cache_flush
352
353 .word 0x6901b110 @ sa1110
354 .word 0xfffffff0
355 b __armv4_cache_on
356 b __armv4_cache_off
357 b __armv4_cache_flush
358
359 .word 0x69050000 @ xscale
360 .word 0xffff0000
361 b __armv4_cache_on
362 b __armv4_cache_off
363 b __armv4_cache_flush
364
365 .word 0 @ unrecognised type
366 .word 0
367 mov pc, lr
368 mov pc, lr
369 mov pc, lr
370
371 .size proc_types, . - proc_types
372
373/*
374 * Turn off the Cache and MMU. ARMv3 does not support
375 * reading the control register, but ARMv4 does.
376 *
377 * On entry, r6 = processor ID
378 * On exit, r0, r1, r2, r3, r12 corrupted
379 * This routine must preserve: r4, r6, r7
380 */
381 .align 5
382cache_off: mov r3, #12 @ cache_off function
383 b call_cache_fn
384
385__armv4_cache_off:
386 mrc p15, 0, r0, c1, c0
387 bic r0, r0, #0x000d
388 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
389 mov r0, #0
390 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
391 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
392 mov pc, lr
393
394__arm6_cache_off:
395 mov r0, #0x00000030 @ ARM6 control reg.
396 b __armv3_cache_off
397
398__arm7_cache_off:
399 mov r0, #0x00000070 @ ARM7 control reg.
400 b __armv3_cache_off
401
402__armv3_cache_off:
403 mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
404 mov r0, #0
405 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
406 mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
407 mov pc, lr
408
409/*
410 * Clean and flush the cache to maintain consistency.
411 *
412 * On entry,
413 * r6 = processor ID
414 * On exit,
415 * r1, r2, r3, r12 corrupted
416 * This routine must preserve:
417 * r0, r4, r5, r6, r7
418 */
419 .align 5
420cache_clean_flush:
421 mov r3, #16
422 b call_cache_fn
423
424__armv4_cache_flush:
425 bic r1, pc, #31
426 add r2, r1, #65536 @ 2x the largest dcache size
4271: ldr r12, [r1], #32 @ s/w flush D cache
428 teq r1, r2
429 bne 1b
430
431 mcr p15, 0, r1, c7, c7, 0 @ flush I cache
432 mcr p15, 0, r1, c7, c10, 4 @ drain WB
433 mov pc, lr
434
435__armv3_cache_flush:
436 mov r1, #0
437 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
438 mov pc, lr
439
440/*
441 * Various debugging routines for printing hex characters and
442 * memory, which again must be relocatable.
443 */
444#ifdef DEBUG
445 .type phexbuf,#object
446phexbuf: .space 12
447 .size phexbuf, . - phexbuf
448
449phex: adr r3, phexbuf
450 mov r2, #0
451 strb r2, [r3, r1]
4521: subs r1, r1, #1
453 movmi r0, r3
454 bmi puts
455 and r2, r0, #15
456 mov r0, r0, lsr #4
457 cmp r2, #10
458 addge r2, r2, #7
459 add r2, r2, #'0'
460 strb r2, [r3, r1]
461 b 1b
462
463puts: loadsp r3
4641: ldrb r2, [r0], #1
465 teq r2, #0
466 moveq pc, lr
4672: writeb r2
468 mov r1, #0x00020000
4693: subs r1, r1, #1
470 bne 3b
471 teq r2, #'\n'
472 moveq r2, #'\r'
473 beq 2b
474 teq r0, #0
475 bne 1b
476 mov pc, lr
477putc:
478 mov r2, r0
479 mov r0, #0
480 loadsp r3
481 b 2b
482
483memdump: mov r12, r0
484 mov r10, lr
485 mov r11, #0
4862: mov r0, r11, lsl #2
487 add r0, r0, r12
488 mov r1, #8
489 bl phex
490 mov r0, #':'
491 bl putc
4921: mov r0, #' '
493 bl putc
494 ldr r0, [r12, r11, lsl #2]
495 mov r1, #8
496 bl phex
497 and r0, r11, #7
498 teq r0, #3
499 moveq r0, #' '
500 bleq putc
501 and r0, r11, #7
502 add r11, r11, #1
503 teq r0, #7
504 bne 1b
505 mov r0, #'\n'
506 bl putc
507 cmp r11, #64
508 blt 2b
509 mov pc, r10
510#endif
511
512reloc_end:
513
514 .align
515 .section ".stack", "aw"
516user_stack: .space 4096
diff --git a/arch/arm26/boot/compressed/ll_char_wr.S b/arch/arm26/boot/compressed/ll_char_wr.S
deleted file mode 100644
index f024c3ebdfa5..000000000000
--- a/arch/arm26/boot/compressed/ll_char_wr.S
+++ /dev/null
@@ -1,162 +0,0 @@
1/*
2 * linux/arch/arm26/lib/ll_char_wr.S
3 *
4 * Copyright (C) 1995, 1996 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
11 *
12 * 10-04-96 RMK Various cleanups & reduced register usage.
13 * 08-04-98 RMK Shifts re-ordered
14 */
15
16@ Regs: [] = corruptible
17@ {} = used
18@ () = do not use
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22 .text
23
24#define BOLD 0x01
25#define ITALIC 0x02
26#define UNDERLINE 0x04
27#define FLASH 0x08
28#define INVERSE 0x10
29
30LC0: .word bytes_per_char_h
31 .word video_size_row
32 .word acorndata_8x8
33 .word con_charconvtable
34
35ENTRY(ll_write_char)
36 stmfd sp!, {r4 - r7, lr}
37@
38@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
39@
40 eor ip, r1, #UNDERLINE << 9
41/*
42 * calculate colours
43 */
44 tst r1, #INVERSE << 9
45 moveq r2, r1, lsr #16
46 moveq r3, r1, lsr #24
47 movne r2, r1, lsr #24
48 movne r3, r1, lsr #16
49 and r3, r3, #255
50 and r2, r2, #255
51/*
52 * calculate offset into character table
53 */
54 mov r1, r1, lsl #23
55 mov r1, r1, lsr #20
56/*
57 * calculate offset required for each row [maybe I should make this an argument to this fn.
58 * Have to see what the register usage is like in the calling routines.
59 */
60 adr r4, LC0
61 ldmia r4, {r4, r5, r6, lr}
62 ldr r4, [r4]
63 ldr r5, [r5]
64/*
65 * Go to resolution-dependent routine...
66 */
67 cmp r4, #4
68 blt Lrow1bpp
69 eor r2, r3, r2 @ Create eor mask to change colour from bg
70 orr r3, r3, r3, lsl #8 @ to fg.
71 orr r3, r3, r3, lsl #16
72 add r0, r0, r5, lsl #3 @ Move to bottom of character
73 add r1, r1, #7
74 ldrb r7, [r6, r1]
75 tst ip, #UNDERLINE << 9
76 eoreq r7, r7, #255
77 teq r4, #8
78 beq Lrow8bpplp
79@
80@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
81@
82 orr r3, r3, r3, lsl #4
83Lrow4bpplp: ldr r7, [lr, r7, lsl #2]
84 mul r7, r2, r7
85 tst r1, #7 @ avoid using r7 directly after
86 eor ip, r3, r7
87 str ip, [r0, -r5]!
88 LOADREGS(eqfd, sp!, {r4 - r7, pc})
89 sub r1, r1, #1
90 ldrb r7, [r6, r1]
91 ldr r7, [lr, r7, lsl #2]
92 mul r7, r2, r7
93 tst r1, #7 @ avoid using r7 directly after
94 eor ip, r3, r7
95 str ip, [r0, -r5]!
96 subne r1, r1, #1
97 ldrneb r7, [r6, r1]
98 bne Lrow4bpplp
99 LOADREGS(fd, sp!, {r4 - r7, pc})
100
101@
102@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
103@
104Lrow8bpplp: mov ip, r7, lsr #4
105 ldr ip, [lr, ip, lsl #2]
106 mul r4, r2, ip
107 and ip, r7, #15 @ avoid r4
108 ldr ip, [lr, ip, lsl #2] @ avoid r4
109 mul ip, r2, ip @ avoid r4
110 eor r4, r3, r4 @ avoid ip
111 tst r1, #7 @ avoid ip
112 sub r0, r0, r5 @ avoid ip
113 eor ip, r3, ip
114 stmia r0, {r4, ip}
115 LOADREGS(eqfd, sp!, {r4 - r7, pc})
116 sub r1, r1, #1
117 ldrb r7, [r6, r1]
118 mov ip, r7, lsr #4
119 ldr ip, [lr, ip, lsl #2]
120 mul r4, r2, ip
121 and ip, r7, #15 @ avoid r4
122 ldr ip, [lr, ip, lsl #2] @ avoid r4
123 mul ip, r2, ip @ avoid r4
124 eor r4, r3, r4 @ avoid ip
125 tst r1, #7 @ avoid ip
126 sub r0, r0, r5 @ avoid ip
127 eor ip, r3, ip
128 stmia r0, {r4, ip}
129 subne r1, r1, #1
130 ldrneb r7, [r6, r1]
131 bne Lrow8bpplp
132 LOADREGS(fd, sp!, {r4 - r7, pc})
133
134@
135@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
136@
137Lrow1bpp: add r6, r6, r1
138 ldmia r6, {r4, r7}
139 tst ip, #INVERSE << 9
140 mvnne r4, r4
141 mvnne r7, r7
142 strb r4, [r0], r5
143 mov r4, r4, lsr #8
144 strb r4, [r0], r5
145 mov r4, r4, lsr #8
146 strb r4, [r0], r5
147 mov r4, r4, lsr #8
148 strb r4, [r0], r5
149 strb r7, [r0], r5
150 mov r7, r7, lsr #8
151 strb r7, [r0], r5
152 mov r7, r7, lsr #8
153 strb r7, [r0], r5
154 mov r7, r7, lsr #8
155 tst ip, #UNDERLINE << 9
156 mvneq r7, r7
157 strb r7, [r0], r5
158 LOADREGS(fd, sp!, {r4 - r7, pc})
159
160 .bss
161ENTRY(con_charconvtable)
162 .space 1024
diff --git a/arch/arm26/boot/compressed/misc.c b/arch/arm26/boot/compressed/misc.c
deleted file mode 100644
index 0714d19c5776..000000000000
--- a/arch/arm26/boot/compressed/misc.c
+++ /dev/null
@@ -1,316 +0,0 @@
1/*
2 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Modified for ARM Linux by Russell King
10 *
11 * Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
12 * For this code to run directly from Flash, all constant variables must
13 * be marked with 'const' and all other variables initialized at run-time
14 * only. This way all non constant variables will end up in the bss segment,
15 * which should point to addresses in RAM and cleared to 0 on start.
16 * This allows for a much quicker boot time.
17 */
18
19unsigned int __machine_arch_type;
20
21#include <linux/kernel.h>
22
23#include <asm/uaccess.h>
24#include "uncompress.h"
25
26#ifdef STANDALONE_DEBUG
27#define puts printf
28#endif
29
30#define __ptr_t void *
31
32/*
33 * Optimised C version of memzero for the ARM.
34 */
35void __memzero (__ptr_t s, size_t n)
36{
37 union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
38 int i;
39
40 u.vp = s;
41
42 for (i = n >> 5; i > 0; i--) {
43 *u.ulp++ = 0;
44 *u.ulp++ = 0;
45 *u.ulp++ = 0;
46 *u.ulp++ = 0;
47 *u.ulp++ = 0;
48 *u.ulp++ = 0;
49 *u.ulp++ = 0;
50 *u.ulp++ = 0;
51 }
52
53 if (n & 1 << 4) {
54 *u.ulp++ = 0;
55 *u.ulp++ = 0;
56 *u.ulp++ = 0;
57 *u.ulp++ = 0;
58 }
59
60 if (n & 1 << 3) {
61 *u.ulp++ = 0;
62 *u.ulp++ = 0;
63 }
64
65 if (n & 1 << 2)
66 *u.ulp++ = 0;
67
68 if (n & 1 << 1) {
69 *u.ucp++ = 0;
70 *u.ucp++ = 0;
71 }
72
73 if (n & 1)
74 *u.ucp++ = 0;
75}
76
77static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
78 size_t __n)
79{
80 int i = 0;
81 unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
82
83 for (i = __n >> 3; i > 0; i--) {
84 *d++ = *s++;
85 *d++ = *s++;
86 *d++ = *s++;
87 *d++ = *s++;
88 *d++ = *s++;
89 *d++ = *s++;
90 *d++ = *s++;
91 *d++ = *s++;
92 }
93
94 if (__n & 1 << 2) {
95 *d++ = *s++;
96 *d++ = *s++;
97 *d++ = *s++;
98 *d++ = *s++;
99 }
100
101 if (__n & 1 << 1) {
102 *d++ = *s++;
103 *d++ = *s++;
104 }
105
106 if (__n & 1)
107 *d++ = *s++;
108
109 return __dest;
110}
111
112/*
113 * gzip delarations
114 */
115#define OF(args) args
116#define STATIC static
117
118typedef unsigned char uch;
119typedef unsigned short ush;
120typedef unsigned long ulg;
121
122#define WSIZE 0x8000 /* Window size must be at least 32k, */
123 /* and a power of two */
124
125static uch *inbuf; /* input buffer */
126static uch window[WSIZE]; /* Sliding window buffer */
127
128static unsigned insize; /* valid bytes in inbuf */
129static unsigned inptr; /* index of next byte to be processed in inbuf */
130static unsigned outcnt; /* bytes in output buffer */
131
132/* gzip flag byte */
133#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
134#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
135#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
136#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
137#define COMMENT 0x10 /* bit 4 set: file comment present */
138#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
139#define RESERVED 0xC0 /* bit 6,7: reserved */
140
141#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
142
143/* Diagnostic functions */
144#ifdef DEBUG
145# define Assert(cond,msg) {if(!(cond)) error(msg);}
146# define Trace(x) fprintf x
147# define Tracev(x) {if (verbose) fprintf x ;}
148# define Tracevv(x) {if (verbose>1) fprintf x ;}
149# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
150# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
151#else
152# define Assert(cond,msg)
153# define Trace(x)
154# define Tracev(x)
155# define Tracevv(x)
156# define Tracec(c,x)
157# define Tracecv(c,x)
158#endif
159
160static int fill_inbuf(void);
161static void flush_window(void);
162static void error(char *m);
163static void gzip_mark(void **);
164static void gzip_release(void **);
165
166extern char input_data[];
167extern char input_data_end[];
168
169static uch *output_data;
170static ulg output_ptr;
171static ulg bytes_out;
172
173static void *malloc(int size);
174static void free(void *where);
175static void error(char *m);
176static void gzip_mark(void **);
177static void gzip_release(void **);
178
179static void puts(const char *);
180
181extern int end;
182static ulg free_mem_ptr;
183static ulg free_mem_ptr_end;
184
185#define HEAP_SIZE 0x3000
186
187#include "../../../../lib/inflate.c"
188
189#ifndef STANDALONE_DEBUG
190static void *malloc(int size)
191{
192 void *p;
193
194 if (size <0) error("Malloc error");
195 if (free_mem_ptr <= 0) error("Memory error");
196
197 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
198
199 p = (void *)free_mem_ptr;
200 free_mem_ptr += size;
201
202 if (free_mem_ptr >= free_mem_ptr_end)
203 error("Out of memory");
204 return p;
205}
206
207static void free(void *where)
208{ /* gzip_mark & gzip_release do the free */
209}
210
211static void gzip_mark(void **ptr)
212{
213 arch_decomp_wdog();
214 *ptr = (void *) free_mem_ptr;
215}
216
217static void gzip_release(void **ptr)
218{
219 arch_decomp_wdog();
220 free_mem_ptr = (long) *ptr;
221}
222#else
223static void gzip_mark(void **ptr)
224{
225}
226
227static void gzip_release(void **ptr)
228{
229}
230#endif
231
232/* ===========================================================================
233 * Fill the input buffer. This is called only when the buffer is empty
234 * and at least one byte is really needed.
235 */
236int fill_inbuf(void)
237{
238 if (insize != 0)
239 error("ran out of input data");
240
241 inbuf = input_data;
242 insize = &input_data_end[0] - &input_data[0];
243
244 inptr = 1;
245 return inbuf[0];
246}
247
248/* ===========================================================================
249 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
250 * (Used for the decompressed data only.)
251 */
252void flush_window(void)
253{
254 ulg c = crc;
255 unsigned n;
256 uch *in, *out, ch;
257
258 in = window;
259 out = &output_data[output_ptr];
260 for (n = 0; n < outcnt; n++) {
261 ch = *out++ = *in++;
262 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
263 }
264 crc = c;
265 bytes_out += (ulg)outcnt;
266 output_ptr += (ulg)outcnt;
267 outcnt = 0;
268 puts(".");
269}
270
271static void error(char *x)
272{
273 int ptr;
274
275 puts("\n\n");
276 puts(x);
277 puts("\n\n -- System halted");
278
279 while(1); /* Halt */
280}
281
282#ifndef STANDALONE_DEBUG
283
284ulg
285decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
286 int arch_id)
287{
288 output_data = (uch *)output_start; /* Points to kernel start */
289 free_mem_ptr = free_mem_ptr_p;
290 free_mem_ptr_end = free_mem_ptr_end_p;
291 __machine_arch_type = arch_id;
292
293 arch_decomp_setup();
294
295 makecrc();
296 puts("Uncompressing Linux...");
297 gunzip();
298 puts(" done, booting the kernel.\n");
299 return output_ptr;
300}
301#else
302
303char output_buffer[1500*1024];
304
305int main()
306{
307 output_data = output_buffer;
308
309 makecrc();
310 puts("Uncompressing Linux...");
311 gunzip();
312 puts("done.\n");
313 return 0;
314}
315#endif
316
diff --git a/arch/arm26/boot/compressed/uncompress.h b/arch/arm26/boot/compressed/uncompress.h
deleted file mode 100644
index 66d9b938a7a4..000000000000
--- a/arch/arm26/boot/compressed/uncompress.h
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 *
3 * Copyright (C) 1996 Russell King
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#define VIDMEM ((char *)0x02000000)
10
11int video_num_columns, video_num_lines, video_size_row;
12int white, bytes_per_char_h;
13extern unsigned long con_charconvtable[256];
14
15struct param_struct {
16 unsigned long page_size;
17 unsigned long nr_pages;
18 unsigned long ramdisk_size;
19 unsigned long mountrootrdonly;
20 unsigned long rootdev;
21 unsigned long video_num_cols;
22 unsigned long video_num_rows;
23 unsigned long video_x;
24 unsigned long video_y;
25 unsigned long memc_control_reg;
26 unsigned char sounddefault;
27 unsigned char adfsdrives;
28 unsigned char bytes_per_char_h;
29 unsigned char bytes_per_char_v;
30 unsigned long unused[256/4-11];
31};
32
33static struct param_struct *params = (struct param_struct *)0x0207c000;
34
35/*
36 * This does not append a newline
37 */
38static void puts(const char *s)
39{
40 extern void ll_write_char(char *, unsigned long);
41 int x,y;
42 unsigned char c;
43 char *ptr;
44
45 x = params->video_x;
46 y = params->video_y;
47
48 while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
49 if ( c == '\n' ) {
50 x = 0;
51 if ( ++y >= video_num_lines ) {
52 y--;
53 }
54 } else {
55 ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
56 ll_write_char(ptr, c|(white<<16));
57 if ( ++x >= video_num_columns ) {
58 x = 0;
59 if ( ++y >= video_num_lines ) {
60 y--;
61 }
62 }
63 }
64 }
65
66 params->video_x = x;
67 params->video_y = y;
68}
69
70static void error(char *x);
71
72/*
73 * Setup for decompression
74 */
75static void arch_decomp_setup(void)
76{
77 int i;
78
79 video_num_lines = params->video_num_rows;
80 video_num_columns = params->video_num_cols;
81 bytes_per_char_h = params->bytes_per_char_h;
82 video_size_row = video_num_columns * bytes_per_char_h;
83 if (bytes_per_char_h == 4)
84 for (i = 0; i < 256; i++)
85 con_charconvtable[i] =
86 (i & 128 ? 1 << 0 : 0) |
87 (i & 64 ? 1 << 4 : 0) |
88 (i & 32 ? 1 << 8 : 0) |
89 (i & 16 ? 1 << 12 : 0) |
90 (i & 8 ? 1 << 16 : 0) |
91 (i & 4 ? 1 << 20 : 0) |
92 (i & 2 ? 1 << 24 : 0) |
93 (i & 1 ? 1 << 28 : 0);
94 else
95 for (i = 0; i < 16; i++)
96 con_charconvtable[i] =
97 (i & 8 ? 1 << 0 : 0) |
98 (i & 4 ? 1 << 8 : 0) |
99 (i & 2 ? 1 << 16 : 0) |
100 (i & 1 ? 1 << 24 : 0);
101
102 white = bytes_per_char_h == 8 ? 0xfc : 7;
103
104 if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
105}
106
107/*
108 * nothing to do
109 */
110#define arch_decomp_wdog()
diff --git a/arch/arm26/boot/compressed/vmlinux.lds.in b/arch/arm26/boot/compressed/vmlinux.lds.in
deleted file mode 100644
index 86d821d5ab70..000000000000
--- a/arch/arm26/boot/compressed/vmlinux.lds.in
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * linux/arch/arm26/boot/compressed/vmlinux.lds.in
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10OUTPUT_ARCH(arm)
11ENTRY(_start)
12SECTIONS
13{
14 . = LOAD_ADDR;
15 _load_addr = .;
16
17 . = TEXT_START;
18 _text = .;
19
20 .text : {
21 _start = .;
22 *(.start)
23 *(.text)
24 *(.fixup)
25 *(.gnu.warning)
26 *(.rodata)
27 *(.rodata.*)
28 *(.glue_7)
29 *(.glue_7t)
30 input_data = .;
31 arch/arm26/boot/compressed/piggy.o
32 input_data_end = .;
33 . = ALIGN(4);
34 }
35
36 _etext = .;
37
38 _got_start = .;
39 .got : { *(.got) }
40 _got_end = .;
41 .got.plt : { *(.got.plt) }
42 .data : { *(.data) }
43 _edata = .;
44
45 . = BSS_START;
46 __bss_start = .;
47 .bss : { *(.bss) }
48 _end = .;
49
50 .stack (NOLOAD) : { *(.stack) }
51
52 .stab 0 : { *(.stab) }
53 .stabstr 0 : { *(.stabstr) }
54 .stab.excl 0 : { *(.stab.excl) }
55 .stab.exclstr 0 : { *(.stab.exclstr) }
56 .stab.index 0 : { *(.stab.index) }
57 .stab.indexstr 0 : { *(.stab.indexstr) }
58 .comment 0 : { *(.comment) }
59}
60
diff --git a/arch/arm26/boot/install.sh b/arch/arm26/boot/install.sh
deleted file mode 100644
index 8a8399b26cf7..000000000000
--- a/arch/arm26/boot/install.sh
+++ /dev/null
@@ -1,62 +0,0 @@
1#!/bin/sh
2#
3# arch/arm26/boot/install.sh
4#
5# This file is subject to the terms and conditions of the GNU General Public
6# License. See the file "COPYING" in the main directory of this archive
7# for more details.
8#
9# Copyright (C) 1995 by Linus Torvalds
10#
11# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
12# Adapted from code in arch/i386/boot/install.sh by Russell King
13# Stolen from arm32 by Ian Molton
14#
15# "make install" script for arm architecture
16#
17# Arguments:
18# $1 - kernel version
19# $2 - kernel image file
20# $3 - kernel map file
21# $4 - default install path (blank if root directory)
22#
23
24# User may have a custom install script
25
26if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then
27 exec /sbin/${CROSS_COMPILE}installkernel "$@"
28fi
29
30if [ "$2" = "zImage" ]; then
31# Compressed install
32 echo "Installing compressed kernel"
33 if [ -f $4/vmlinuz-$1 ]; then
34 mv $4/vmlinuz-$1 $4/vmlinuz.old
35 fi
36
37 if [ -f $4/System.map-$1 ]; then
38 mv $4/System.map-$1 $4/System.old
39 fi
40
41 cat $2 > $4/vmlinuz-$1
42 cp $3 $4/System.map-$1
43else
44# Normal install
45 echo "Installing normal kernel"
46 if [ -f $4/vmlinux-$1 ]; then
47 mv $4/vmlinux-$1 $4/vmlinux.old
48 fi
49
50 if [ -f $4/System.map ]; then
51 mv $4/System.map $4/System.old
52 fi
53
54 cat $2 > $4/vmlinux-$1
55 cp $3 $4/System.map
56fi
57
58if [ -x /sbin/loadmap ]; then
59 /sbin/loadmap --rdev /dev/ima
60else
61 echo "You have to install it yourself"
62fi
diff --git a/arch/arm26/defconfig b/arch/arm26/defconfig
deleted file mode 100644
index 2b7d44bf49bf..000000000000
--- a/arch/arm26/defconfig
+++ /dev/null
@@ -1,361 +0,0 @@
1#
2# Automatically generated by make menuconfig: don't edit
3#
4CONFIG_ARM=y
5# CONFIG_EISA is not set
6# CONFIG_SBUS is not set
7# CONFIG_MCA is not set
8CONFIG_UID16=y
9CONFIG_RWSEM_GENERIC_SPINLOCK=y
10# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
11# CONFIG_GENERIC_BUST_SPINLOCK is not set
12# CONFIG_GENERIC_ISA_DMA is not set
13
14#
15# Code maturity level options
16#
17CONFIG_EXPERIMENTAL=y
18
19#
20# General setup
21#
22# CONFIG_NET is not set
23# CONFIG_SYSVIPC is not set
24# CONFIG_BSD_PROCESS_ACCT is not set
25# CONFIG_SYSCTL is not set
26
27#
28# Loadable module support
29#
30# CONFIG_MODULES is not set
31
32#
33# System Type
34#
35CONFIG_ARCH_ARC=y
36# CONFIG_ARCH_A5K is not set
37CONFIG_ARCH_ACORN=y
38# CONFIG_CPU_32 is not set
39CONFIG_CPU_26=y
40# CONFIG_PAGESIZE_16 is not set
41
42#
43# General setup
44#
45CONFIG_FIQ=y
46# CONFIG_ZBOOT_ROM is not set
47CONFIG_ZBOOT_ROM_TEXT=0
48CONFIG_ZBOOT_ROM_BSS=0
49CONFIG_FPE_NWFPE=y
50CONFIG_KCORE_ELF=y
51# CONFIG_KCORE_AOUT is not set
52# CONFIG_BINFMT_AOUT is not set
53# CONFIG_BINFMT_ELF is not set
54# CONFIG_BINFMT_MISC is not set
55CONFIG_CMDLINE=""
56# CONFIG_ALIGNMENT_TRAP is not set
57
58#
59# Parallel port support
60#
61# CONFIG_PARPORT is not set
62
63#
64# Plug and Play configuration
65#
66# CONFIG_PNP is not set
67# CONFIG_ISAPNP is not set
68# CONFIG_PNPBIOS is not set
69
70#
71# Block devices
72#
73# CONFIG_BLK_DEV_FD is not set
74# CONFIG_BLK_DEV_XD is not set
75# CONFIG_PARIDE is not set
76# CONFIG_BLK_CPQ_DA is not set
77# CONFIG_BLK_CPQ_CISS_DA is not set
78# CONFIG_CISS_SCSI_TAPE is not set
79# CONFIG_BLK_DEV_DAC960 is not set
80# CONFIG_BLK_DEV_UMEM is not set
81# CONFIG_BLK_DEV_LOOP is not set
82# CONFIG_BLK_DEV_NBD is not set
83# CONFIG_BLK_DEV_RAM is not set
84# CONFIG_BLK_DEV_INITRD is not set
85
86#
87# Multi-device support (RAID and LVM)
88#
89# CONFIG_MD is not set
90# CONFIG_BLK_DEV_MD is not set
91# CONFIG_MD_LINEAR is not set
92# CONFIG_MD_RAID0 is not set
93# CONFIG_MD_RAID1 is not set
94# CONFIG_MD_RAID5 is not set
95# CONFIG_MD_MULTIPATH is not set
96# CONFIG_BLK_DEV_LVM is not set
97
98#
99# Acorn-specific block devices
100#
101# CONFIG_BLK_DEV_FD1772 is not set
102# CONFIG_BLK_DEV_MFM is not set
103
104#
105# ATA/ATAPI/MFM/RLL support
106#
107# CONFIG_IDE is not set
108# CONFIG_BLK_DEV_HD is not set
109
110#
111# SCSI support
112#
113# CONFIG_SCSI is not set
114
115#
116# ISDN subsystem
117#
118
119#
120# Input device support
121#
122# CONFIG_INPUT is not set
123# CONFIG_INPUT_KEYBDEV is not set
124# CONFIG_INPUT_MOUSEDEV is not set
125# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
126# CONFIG_INPUT_JOYDEV is not set
127# CONFIG_INPUT_TSDEV is not set
128# CONFIG_INPUT_TSLIBDEV is not set
129# CONFIG_INPUT_EVDEV is not set
130# CONFIG_INPUT_EVBUG is not set
131# CONFIG_INPUT_UINPUT is not set
132# CONFIG_GAMEPORT is not set
133CONFIG_SOUND_GAMEPORT=y
134# CONFIG_GAMEPORT_NS558 is not set
135# CONFIG_GAMEPORT_L4 is not set
136# CONFIG_GAMEPORT_EMU10K1 is not set
137# CONFIG_GAMEPORT_VORTEX is not set
138# CONFIG_GAMEPORT_FM801 is not set
139# CONFIG_GAMEPORT_CS461x is not set
140# CONFIG_SERIO is not set
141# CONFIG_SERIO_I8042 is not set
142# CONFIG_SERIO_SERPORT is not set
143# CONFIG_SERIO_CT82C710 is not set
144# CONFIG_SERIO_PARKBD is not set
145# CONFIG_SERIO_ACORN is not set
146
147#
148# Character devices
149#
150# CONFIG_VT is not set
151# CONFIG_SERIAL_NONSTANDARD is not set
152
153#
154# Serial drivers
155#
156# CONFIG_SERIAL_8250 is not set
157# CONFIG_SERIAL_8250_CONSOLE is not set
158# CONFIG_SERIAL_8250_CS is not set
159# CONFIG_SERIAL_8250_EXTENDED is not set
160# CONFIG_SERIAL_8250_MANY_PORTS is not set
161# CONFIG_SERIAL_8250_SHARE_IRQ is not set
162# CONFIG_SERIAL_8250_DETECT_IRQ is not set
163# CONFIG_SERIAL_8250_MULTIPORT is not set
164# CONFIG_SERIAL_8250_RSA is not set
165# CONFIG_ATOMWIDE_SERIAL is not set
166# CONFIG_DUALSP_SERIAL is not set
167# CONFIG_SERIAL_AMBA is not set
168# CONFIG_SERIAL_AMBA_CONSOLE is not set
169# CONFIG_SERIAL_CLPS711X is not set
170# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
171# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
172# CONFIG_SERIAL_21285 is not set
173# CONFIG_SERIAL_21285_OLD is not set
174# CONFIG_SERIAL_21285_CONSOLE is not set
175# CONFIG_SERIAL_UART00 is not set
176# CONFIG_SERIAL_UART00_CONSOLE is not set
177# CONFIG_SERIAL_SA1100 is not set
178# CONFIG_SERIAL_SA1100_CONSOLE is not set
179# CONFIG_UNIX98_PTYS is not set
180
181#
182# I2C support
183#
184CONFIG_I2C=y
185CONFIG_I2C_ALGOBIT=y
186CONFIG_I2C_ALGOPCF=y
187# CONFIG_I2C_ELEKTOR is not set
188CONFIG_I2C_CHARDEV=y
189# CONFIG_I2C_PROC is not set
190
191#
192# L3 serial bus support
193#
194# CONFIG_L3 is not set
195# CONFIG_L3_ALGOBIT is not set
196# CONFIG_L3_BIT_SA1100_GPIO is not set
197# CONFIG_L3_SA1111 is not set
198# CONFIG_BIT_SA1100_GPIO is not set
199
200#
201# Mice
202#
203# CONFIG_BUSMOUSE is not set
204# CONFIG_PSMOUSE is not set
205# CONFIG_QIC02_TAPE is not set
206
207#
208# Watchdog Cards
209#
210# CONFIG_WATCHDOG is not set
211# CONFIG_NVRAM is not set
212# CONFIG_RTC is not set
213# CONFIG_DTLK is not set
214# CONFIG_R3964 is not set
215# CONFIG_APPLICOM is not set
216
217#
218# Ftape, the floppy tape device driver
219#
220# CONFIG_FTAPE is not set
221# CONFIG_AGP is not set
222# CONFIG_DRM is not set
223# CONFIG_RAW_DRIVER is not set
224
225#
226# Multimedia devices
227#
228# CONFIG_VIDEO_DEV is not set
229
230#
231# File systems
232#
233# CONFIG_QUOTA is not set
234# CONFIG_QFMT_V1 is not set
235# CONFIG_QFMT_V2 is not set
236# CONFIG_AUTOFS_FS is not set
237# CONFIG_AUTOFS4_FS is not set
238# CONFIG_REISERFS_FS is not set
239# CONFIG_REISERFS_CHECK is not set
240# CONFIG_REISERFS_PROC_INFO is not set
241# CONFIG_ADFS_FS is not set
242# CONFIG_ADFS_FS_RW is not set
243# CONFIG_AFFS_FS is not set
244# CONFIG_HFS_FS is not set
245# CONFIG_BFS_FS is not set
246# CONFIG_EXT3_FS is not set
247# CONFIG_JBD is not set
248# CONFIG_JBD_DEBUG is not set
249# CONFIG_FAT_FS is not set
250# CONFIG_MSDOS_FS is not set
251# CONFIG_VFAT_FS is not set
252# CONFIG_EFS_FS is not set
253# CONFIG_JFFS_FS is not set
254# CONFIG_JFFS2_FS is not set
255# CONFIG_CRAMFS is not set
256# CONFIG_TMPFS is not set
257CONFIG_RAMFS=y
258# CONFIG_ISO9660_FS is not set
259# CONFIG_JOLIET is not set
260# CONFIG_ZISOFS is not set
261# CONFIG_JFS_FS is not set
262# CONFIG_JFS_DEBUG is not set
263# CONFIG_JFS_STATISTICS is not set
264# CONFIG_MINIX_FS is not set
265# CONFIG_VXFS_FS is not set
266# CONFIG_NTFS_FS is not set
267# CONFIG_NTFS_DEBUG is not set
268# CONFIG_HPFS_FS is not set
269CONFIG_PROC_FS=y
270# CONFIG_DEVFS_FS is not set
271# CONFIG_DEVFS_MOUNT is not set
272# CONFIG_DEVFS_DEBUG is not set
273# CONFIG_DEVPTS_FS is not set
274# CONFIG_QNX4FS_FS is not set
275# CONFIG_QNX4FS_RW is not set
276# CONFIG_ROMFS_FS is not set
277CONFIG_EXT2_FS=y
278# CONFIG_SYSV_FS is not set
279# CONFIG_UDF_FS is not set
280# CONFIG_UDF_RW is not set
281# CONFIG_UFS_FS is not set
282# CONFIG_UFS_FS_WRITE is not set
283# CONFIG_NCPFS_NLS is not set
284# CONFIG_SMB_FS is not set
285# CONFIG_ZISOFS_FS is not set
286
287#
288# Partition Types
289#
290CONFIG_PARTITION_ADVANCED=y
291CONFIG_ACORN_PARTITION=y
292# CONFIG_ACORN_PARTITION_EESOX is not set
293# CONFIG_ACORN_PARTITION_ICS is not set
294CONFIG_ACORN_PARTITION_ADFS=y
295# CONFIG_ACORN_PARTITION_POWERTEC is not set
296CONFIG_ACORN_PARTITION_RISCIX=y
297# CONFIG_OSF_PARTITION is not set
298# CONFIG_AMIGA_PARTITION is not set
299# CONFIG_ATARI_PARTITION is not set
300# CONFIG_MAC_PARTITION is not set
301# CONFIG_MSDOS_PARTITION is not set
302# CONFIG_LDM_PARTITION is not set
303# CONFIG_SGI_PARTITION is not set
304# CONFIG_ULTRIX_PARTITION is not set
305# CONFIG_SUN_PARTITION is not set
306# CONFIG_EFI_PARTITION is not set
307# CONFIG_SMB_NLS is not set
308# CONFIG_NLS is not set
309
310#
311# Sound
312#
313# CONFIG_SOUND is not set
314
315#
316# Multimedia Capabilities Port drivers
317#
318# CONFIG_MCP is not set
319# CONFIG_MCP_SA1100 is not set
320# CONFIG_MCP_UCB1200 is not set
321# CONFIG_MCP_UCB1200_AUDIO is not set
322# CONFIG_MCP_UCB1200_TS is not set
323
324#
325# Console Switches
326#
327# CONFIG_SWITCHES is not set
328# CONFIG_SWITCHES_SA1100 is not set
329# CONFIG_SWITCHES_UCB1X00 is not set
330
331#
332# USB support
333#
334# CONFIG_USB is not set
335
336#
337# Kernel hacking
338#
339# CONFIG_NO_FRAME_POINTER is not set
340CONFIG_DEBUG_USER=y
341CONFIG_DEBUG_INFO=y
342CONFIG_DEBUG_KERNEL=y
343CONFIG_DEBUG_SLAB=y
344CONFIG_MAGIC_SYSRQ=y
345CONFIG_DEBUG_SPINLOCK=y
346CONFIG_DEBUG_WAITQ=y
347CONFIG_DEBUG_BUGVERBOSE=y
348CONFIG_DEBUG_ERRORS=y
349CONFIG_DEBUG_LL=y
350
351#
352# Security options
353#
354CONFIG_SECURITY_CAPABILITIES=y
355
356#
357# Library routines
358#
359CONFIG_CRC32=y
360# CONFIG_ZLIB_INFLATE is not set
361# CONFIG_ZLIB_DEFLATE is not set
diff --git a/arch/arm26/kernel/Makefile b/arch/arm26/kernel/Makefile
deleted file mode 100644
index ee9fb49fdb78..000000000000
--- a/arch/arm26/kernel/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
8
9obj-y := compat.o dma.o entry.o irq.o process.o ptrace.o \
10 semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
11 ecard.o dma.o ecard.o fiq.o time.o
12
13extra-y := head.o init_task.o vmlinux.lds
14
15obj-$(CONFIG_FIQ) += fiq.o
16obj-$(CONFIG_MODULES) += armksyms.o
17
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
deleted file mode 100644
index fe1e3ceed7cb..000000000000
--- a/arch/arm26/kernel/armksyms.c
+++ /dev/null
@@ -1,204 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/armksyms.c
3 *
4 * Copyright (C) 2003 Ian Molton
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/module.h>
11#include <linux/module.h>
12#include <linux/user.h>
13#include <linux/string.h>
14#include <linux/fs.h>
15#include <linux/mm.h>
16#include <linux/mman.h>
17#include <linux/delay.h>
18#include <linux/in6.h>
19#include <linux/interrupt.h>
20#include <linux/pm.h>
21#include <linux/tty.h>
22#include <linux/vt_kern.h>
23#include <linux/syscalls.h>
24
25#include <asm/byteorder.h>
26#include <asm/elf.h>
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/processor.h>
30#include <asm/semaphore.h>
31#include <asm/system.h>
32#include <asm/uaccess.h>
33#include <asm/checksum.h>
34#include <asm/mach-types.h>
35
36extern int dump_fpu(struct pt_regs *, struct user_fp_struct *);
37extern void inswb(unsigned int port, void *to, int len);
38extern void outswb(unsigned int port, const void *to, int len);
39
40extern void __bad_xchg(volatile void *ptr, int size);
41
42/*
43 * libgcc functions - functions that are used internally by the
44 * compiler... (prototypes are not correct though, but that
45 * doesn't really matter since they're not versioned).
46 */
47extern void __ashldi3(void);
48extern void __ashrdi3(void);
49extern void __divsi3(void);
50extern void __lshrdi3(void);
51extern void __modsi3(void);
52extern void __muldi3(void);
53extern void __ucmpdi2(void);
54extern void __udivdi3(void);
55extern void __umoddi3(void);
56extern void __udivmoddi4(void);
57extern void __udivsi3(void);
58extern void __umodsi3(void);
59extern void abort(void);
60
61extern void ret_from_exception(void);
62extern void fpundefinstr(void);
63extern void fp_enter(void);
64
65/*
66 * This has a special calling convention; it doesn't
67 * modify any of the usual registers, except for LR.
68 * FIXME - we used to use our own local version - looks to be in kernel/softirq now
69 */
70//extern void __do_softirq(void);
71
72#define EXPORT_SYMBOL_ALIAS(sym,orig) \
73 const char __kstrtab_##sym[] \
74 __attribute__((section(".kstrtab"))) = \
75 __MODULE_STRING(sym); \
76 const struct module_symbol __ksymtab_##sym \
77 __attribute__((section("__ksymtab"))) = \
78 { (unsigned long)&orig, __kstrtab_##sym };
79
80/*
81 * floating point math emulator support.
82 * These symbols will never change their calling convention...
83 */
84EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
85EXPORT_SYMBOL_ALIAS(fp_printk,printk);
86EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
87
88EXPORT_SYMBOL(fpundefinstr);
89EXPORT_SYMBOL(ret_from_exception);
90
91#ifdef CONFIG_VT
92EXPORT_SYMBOL(kd_mksound);
93#endif
94
95//EXPORT_SYMBOL(__do_softirq);
96
97 /* platform dependent support */
98EXPORT_SYMBOL(dump_thread);
99EXPORT_SYMBOL(dump_fpu);
100EXPORT_SYMBOL(udelay);
101EXPORT_SYMBOL(kernel_thread);
102EXPORT_SYMBOL(system_rev);
103EXPORT_SYMBOL(system_serial_low);
104EXPORT_SYMBOL(system_serial_high);
105#ifdef CONFIG_DEBUG_BUGVERBOSE
106EXPORT_SYMBOL(__bug);
107#endif
108EXPORT_SYMBOL(__bad_xchg);
109EXPORT_SYMBOL(__readwrite_bug);
110EXPORT_SYMBOL(set_irq_type);
111EXPORT_SYMBOL(pm_idle);
112EXPORT_SYMBOL(pm_power_off);
113
114 /* processor dependencies */
115EXPORT_SYMBOL(__machine_arch_type);
116
117 /* networking */
118EXPORT_SYMBOL(csum_partial_copy_nocheck);
119EXPORT_SYMBOL(__csum_ipv6_magic);
120
121 /* io */
122#ifndef __raw_readsb
123EXPORT_SYMBOL(__raw_readsb);
124#endif
125#ifndef __raw_readsw
126EXPORT_SYMBOL(__raw_readsw);
127#endif
128#ifndef __raw_readsl
129EXPORT_SYMBOL(__raw_readsl);
130#endif
131#ifndef __raw_writesb
132EXPORT_SYMBOL(__raw_writesb);
133#endif
134#ifndef __raw_writesw
135EXPORT_SYMBOL(__raw_writesw);
136#endif
137#ifndef __raw_writesl
138EXPORT_SYMBOL(__raw_writesl);
139#endif
140
141 /* string / mem functions */
142EXPORT_SYMBOL(strcpy);
143EXPORT_SYMBOL(strncpy);
144EXPORT_SYMBOL(strcat);
145EXPORT_SYMBOL(strncat);
146EXPORT_SYMBOL(strcmp);
147EXPORT_SYMBOL(strncmp);
148EXPORT_SYMBOL(strchr);
149EXPORT_SYMBOL(strlen);
150EXPORT_SYMBOL(strnlen);
151EXPORT_SYMBOL(strrchr);
152EXPORT_SYMBOL(strstr);
153EXPORT_SYMBOL(memset);
154EXPORT_SYMBOL(memcpy);
155EXPORT_SYMBOL(memmove);
156EXPORT_SYMBOL(memcmp);
157EXPORT_SYMBOL(memscan);
158EXPORT_SYMBOL(__memzero);
159
160 /* user mem (segment) */
161EXPORT_SYMBOL(uaccess_kernel);
162EXPORT_SYMBOL(uaccess_user);
163
164EXPORT_SYMBOL(__get_user_1);
165EXPORT_SYMBOL(__get_user_2);
166EXPORT_SYMBOL(__get_user_4);
167EXPORT_SYMBOL(__get_user_8);
168
169EXPORT_SYMBOL(__put_user_1);
170EXPORT_SYMBOL(__put_user_2);
171EXPORT_SYMBOL(__put_user_4);
172EXPORT_SYMBOL(__put_user_8);
173
174 /* gcc lib functions */
175EXPORT_SYMBOL(__ashldi3);
176EXPORT_SYMBOL(__ashrdi3);
177EXPORT_SYMBOL(__divsi3);
178EXPORT_SYMBOL(__lshrdi3);
179EXPORT_SYMBOL(__modsi3);
180EXPORT_SYMBOL(__muldi3);
181EXPORT_SYMBOL(__ucmpdi2);
182EXPORT_SYMBOL(__udivdi3);
183EXPORT_SYMBOL(__umoddi3);
184EXPORT_SYMBOL(__udivmoddi4);
185EXPORT_SYMBOL(__udivsi3);
186EXPORT_SYMBOL(__umodsi3);
187
188 /* bitops */
189EXPORT_SYMBOL(_set_bit_le);
190EXPORT_SYMBOL(_test_and_set_bit_le);
191EXPORT_SYMBOL(_clear_bit_le);
192EXPORT_SYMBOL(_test_and_clear_bit_le);
193EXPORT_SYMBOL(_change_bit_le);
194EXPORT_SYMBOL(_test_and_change_bit_le);
195EXPORT_SYMBOL(_find_first_zero_bit_le);
196EXPORT_SYMBOL(_find_next_zero_bit_le);
197
198 /* elf */
199EXPORT_SYMBOL(elf_platform);
200EXPORT_SYMBOL(elf_hwcap);
201
202#ifdef CONFIG_PREEMPT
203EXPORT_SYMBOL(kernel_flag);
204#endif
diff --git a/arch/arm26/kernel/asm-offsets.c b/arch/arm26/kernel/asm-offsets.c
deleted file mode 100644
index 76d9d7d489a8..000000000000
--- a/arch/arm26/kernel/asm-offsets.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * Copyright (C) 1995-2001 Russell King
3 * 2001-2002 Keith Owens
4 * 2003 Ian Molton
5 *
6 * Generate definitions needed by assembly language modules.
7 * This code generates raw asm output which is post-processed to extract
8 * and format the required data.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/sched.h>
16#include <linux/mm.h>
17
18#include <asm/pgtable.h>
19#include <asm/uaccess.h>
20
21/*
22 * Make sure that the compiler and target are compatible.
23 */
24#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
25#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
26#endif
27
28/* Use marker if you need to separate the values later */
29
30#define DEFINE(sym, val) \
31 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
32
33#define BLANK() asm volatile("\n->" : : )
34
35int main(void)
36{
37 DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
38 BLANK();
39 DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
40 DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
41 BLANK();
42 DEFINE(VM_EXEC, VM_EXEC);
43 BLANK();
44 BLANK();
45 DEFINE(PAGE_PRESENT, _PAGE_PRESENT);
46 DEFINE(PAGE_READONLY, _PAGE_READONLY);
47 DEFINE(PAGE_NOT_USER, _PAGE_NOT_USER);
48 DEFINE(PAGE_OLD, _PAGE_OLD);
49 DEFINE(PAGE_CLEAN, _PAGE_CLEAN);
50 BLANK();
51 DEFINE(PAGE_SZ, PAGE_SIZE);
52 BLANK();
53 DEFINE(SYS_ERROR0, 0x9f0000);
54 return 0;
55}
diff --git a/arch/arm26/kernel/calls.S b/arch/arm26/kernel/calls.S
deleted file mode 100644
index e3d276827c84..000000000000
--- a/arch/arm26/kernel/calls.S
+++ /dev/null
@@ -1,265 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/calls.S
3 *
4 * Copyright (C) 2003 Ian Molton
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * FIXME
11 * This file is included twice in entry.S which may not be necessary
12 */
13
14//FIXME - clearly NR_syscalls is never defined here
15
16#ifndef NR_syscalls
17#define NR_syscalls 256
18#else
19
20__syscall_start:
21/* 0 */ .long sys_ni_syscall
22 .long sys_exit
23 .long sys_fork_wrapper
24 .long sys_read
25 .long sys_write
26/* 5 */ .long sys_open
27 .long sys_close
28 .long sys_ni_syscall /* was sys_waitpid */
29 .long sys_creat
30 .long sys_link
31/* 10 */ .long sys_unlink
32 .long sys_execve_wrapper
33 .long sys_chdir
34 .long sys_time /* used by libc4 */
35 .long sys_mknod
36/* 15 */ .long sys_chmod
37 .long sys_lchown16
38 .long sys_ni_syscall /* was sys_break */
39 .long sys_ni_syscall /* was sys_stat */
40 .long sys_lseek
41/* 20 */ .long sys_getpid
42 .long sys_mount
43 .long sys_oldumount /* used by libc4 */
44 .long sys_setuid16
45 .long sys_getuid16
46/* 25 */ .long sys_stime
47 .long sys_ptrace
48 .long sys_alarm /* used by libc4 */
49 .long sys_ni_syscall /* was sys_fstat */
50 .long sys_pause
51/* 30 */ .long sys_utime /* used by libc4 */
52 .long sys_ni_syscall /* was sys_stty */
53 .long sys_ni_syscall /* was sys_getty */
54 .long sys_access
55 .long sys_nice
56/* 35 */ .long sys_ni_syscall /* was sys_ftime */
57 .long sys_sync
58 .long sys_kill
59 .long sys_rename
60 .long sys_mkdir
61/* 40 */ .long sys_rmdir
62 .long sys_dup
63 .long sys_pipe
64 .long sys_times
65 .long sys_ni_syscall /* was sys_prof */
66/* 45 */ .long sys_brk
67 .long sys_setgid16
68 .long sys_getgid16
69 .long sys_ni_syscall /* was sys_signal */
70 .long sys_geteuid16
71/* 50 */ .long sys_getegid16
72 .long sys_acct
73 .long sys_umount
74 .long sys_ni_syscall /* was sys_lock */
75 .long sys_ioctl
76/* 55 */ .long sys_fcntl
77 .long sys_ni_syscall /* was sys_mpx */
78 .long sys_setpgid
79 .long sys_ni_syscall /* was sys_ulimit */
80 .long sys_ni_syscall /* was sys_olduname */
81/* 60 */ .long sys_umask
82 .long sys_chroot
83 .long sys_ustat
84 .long sys_dup2
85 .long sys_getppid
86/* 65 */ .long sys_getpgrp
87 .long sys_setsid
88 .long sys_sigaction
89 .long sys_ni_syscall /* was sys_sgetmask */
90 .long sys_ni_syscall /* was sys_ssetmask */
91/* 70 */ .long sys_setreuid16
92 .long sys_setregid16
93 .long sys_sigsuspend_wrapper
94 .long sys_sigpending
95 .long sys_sethostname
96/* 75 */ .long sys_setrlimit
97 .long sys_old_getrlimit /* used by libc4 */
98 .long sys_getrusage
99 .long sys_gettimeofday
100 .long sys_settimeofday
101/* 80 */ .long sys_getgroups16
102 .long sys_setgroups16
103 .long old_select /* used by libc4 */
104 .long sys_symlink
105 .long sys_ni_syscall /* was sys_lstat */
106/* 85 */ .long sys_readlink
107 .long sys_uselib
108 .long sys_swapon
109 .long sys_reboot
110 .long old_readdir /* used by libc4 */
111/* 90 */ .long old_mmap /* used by libc4 */
112 .long sys_munmap
113 .long sys_truncate
114 .long sys_ftruncate
115 .long sys_fchmod
116/* 95 */ .long sys_fchown16
117 .long sys_getpriority
118 .long sys_setpriority
119 .long sys_ni_syscall /* was sys_profil */
120 .long sys_statfs
121/* 100 */ .long sys_fstatfs
122 .long sys_ni_syscall
123 .long sys_socketcall
124 .long sys_syslog
125 .long sys_setitimer
126/* 105 */ .long sys_getitimer
127 .long sys_newstat
128 .long sys_newlstat
129 .long sys_newfstat
130 .long sys_ni_syscall /* was sys_uname */
131/* 110 */ .long sys_ni_syscall /* was sys_iopl */
132 .long sys_vhangup
133 .long sys_ni_syscall
134 .long sys_syscall /* call a syscall */
135 .long sys_wait4
136/* 115 */ .long sys_swapoff
137 .long sys_sysinfo
138 .long sys_ipc
139 .long sys_fsync
140 .long sys_sigreturn_wrapper
141/* 120 */ .long sys_clone_wapper
142 .long sys_setdomainname
143 .long sys_newuname
144 .long sys_ni_syscall
145 .long sys_adjtimex
146/* 125 */ .long sys_mprotect
147 .long sys_sigprocmask
148 .long sys_ni_syscall /* WAS: sys_create_module */
149 .long sys_init_module
150 .long sys_delete_module
151/* 130 */ .long sys_ni_syscall /* WAS: sys_get_kernel_syms */
152 .long sys_quotactl
153 .long sys_getpgid
154 .long sys_fchdir
155 .long sys_bdflush
156/* 135 */ .long sys_sysfs
157 .long sys_personality
158 .long sys_ni_syscall /* .long _sys_afs_syscall */
159 .long sys_setfsuid16
160 .long sys_setfsgid16
161/* 140 */ .long sys_llseek
162 .long sys_getdents
163 .long sys_select
164 .long sys_flock
165 .long sys_msync
166/* 145 */ .long sys_readv
167 .long sys_writev
168 .long sys_getsid
169 .long sys_fdatasync
170 .long sys_sysctl
171/* 150 */ .long sys_mlock
172 .long sys_munlock
173 .long sys_mlockall
174 .long sys_munlockall
175 .long sys_sched_setparam
176/* 155 */ .long sys_sched_getparam
177 .long sys_sched_setscheduler
178 .long sys_sched_getscheduler
179 .long sys_sched_yield
180 .long sys_sched_get_priority_max
181/* 160 */ .long sys_sched_get_priority_min
182 .long sys_sched_rr_get_interval
183 .long sys_nanosleep
184 .long sys_arm_mremap
185 .long sys_setresuid16
186/* 165 */ .long sys_getresuid16
187 .long sys_ni_syscall
188 .long sys_ni_syscall /* WAS: sys_query_module */
189 .long sys_poll
190 .long sys_nfsservctl
191/* 170 */ .long sys_setresgid16
192 .long sys_getresgid16
193 .long sys_prctl
194 .long sys_rt_sigreturn_wrapper
195 .long sys_rt_sigaction
196/* 175 */ .long sys_rt_sigprocmask
197 .long sys_rt_sigpending
198 .long sys_rt_sigtimedwait
199 .long sys_rt_sigqueueinfo
200 .long sys_rt_sigsuspend_wrapper
201/* 180 */ .long sys_pread64
202 .long sys_pwrite64
203 .long sys_chown16
204 .long sys_getcwd
205 .long sys_capget
206/* 185 */ .long sys_capset
207 .long sys_sigaltstack_wrapper
208 .long sys_sendfile
209 .long sys_ni_syscall
210 .long sys_ni_syscall
211/* 190 */ .long sys_vfork_wrapper
212 .long sys_getrlimit
213 .long sys_mmap2
214 .long sys_truncate64
215 .long sys_ftruncate64
216/* 195 */ .long sys_stat64
217 .long sys_lstat64
218 .long sys_fstat64
219 .long sys_lchown
220 .long sys_getuid
221/* 200 */ .long sys_getgid
222 .long sys_geteuid
223 .long sys_getegid
224 .long sys_setreuid
225 .long sys_setregid
226/* 205 */ .long sys_getgroups
227 .long sys_setgroups
228 .long sys_fchown
229 .long sys_setresuid
230 .long sys_getresuid
231/* 210 */ .long sys_setresgid
232 .long sys_getresgid
233 .long sys_chown
234 .long sys_setuid
235 .long sys_setgid
236/* 215 */ .long sys_setfsuid
237 .long sys_setfsgid
238 .long sys_getdents64
239 .long sys_pivot_root
240 .long sys_mincore
241/* 220 */ .long sys_madvise
242 .long sys_fcntl64
243 .long sys_ni_syscall /* TUX */
244 .long sys_ni_syscall /* WAS: sys_security */
245 .long sys_gettid
246/* 225 */ .long sys_readahead
247 .long sys_setxattr
248 .long sys_lsetxattr
249 .long sys_fsetxattr
250 .long sys_getxattr
251/* 230 */ .long sys_lgetxattr
252 .long sys_fgetxattr
253 .long sys_listxattr
254 .long sys_llistxattr
255 .long sys_flistxattr
256/* 235 */ .long sys_removexattr
257 .long sys_lremovexattr
258 .long sys_fremovexattr
259 .long sys_tkill
260__syscall_end:
261
262 .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
263 .long sys_ni_syscall
264 .endr
265#endif
diff --git a/arch/arm26/kernel/compat.c b/arch/arm26/kernel/compat.c
deleted file mode 100644
index 21e966ff0aa7..000000000000
--- a/arch/arm26/kernel/compat.c
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/compat.c
3 *
4 * Copyright (C) 2001 Russell King
5 * 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * We keep the old params compatibility cruft in one place (here)
12 * so we don't end up with lots of mess around other places.
13 *
14 * NOTE:
15 * The old struct param_struct is deprecated, but it will be kept in
16 * the kernel for 5 years from now (2001). This will allow boot loaders
17 * to convert to the new struct tag way.
18 */
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/init.h>
23
24#include <asm/setup.h>
25#include <asm/mach-types.h>
26#include <asm/page.h>
27
28//#include <asm/arch.h>
29//#include <asm/mach/irq.h>
30
31/*
32 * Usage:
33 * - do not go blindly adding fields, add them at the end
34 * - when adding fields, don't rely on the address until
35 * a patch from me has been released
36 * - unused fields should be zero (for future expansion)
37 * - this structure is relatively short-lived - only
38 * guaranteed to contain useful data in setup_arch()
39 *
40 * This is the old deprecated way to pass parameters to the kernel
41 */
42struct param_struct {
43 union {
44 struct {
45 unsigned long page_size; /* 0 */
46 unsigned long nr_pages; /* 4 */
47 unsigned long ramdisk_size; /* 8 */
48 unsigned long flags; /* 12 */
49#define FLAG_READONLY 1
50#define FLAG_RDLOAD 4
51#define FLAG_RDPROMPT 8
52 unsigned long rootdev; /* 16 */
53 unsigned long video_num_cols; /* 20 */
54 unsigned long video_num_rows; /* 24 */
55 unsigned long video_x; /* 28 */
56 unsigned long video_y; /* 32 */
57 unsigned long memc_control_reg; /* 36 */
58 unsigned char sounddefault; /* 40 */
59 unsigned char adfsdrives; /* 41 */
60 unsigned char bytes_per_char_h; /* 42 */
61 unsigned char bytes_per_char_v; /* 43 */
62 unsigned long pages_in_bank[4]; /* 44 */
63 unsigned long pages_in_vram; /* 60 */
64 unsigned long initrd_start; /* 64 */
65 unsigned long initrd_size; /* 68 */
66 unsigned long rd_start; /* 72 */
67 unsigned long system_rev; /* 76 */
68 unsigned long system_serial_low; /* 80 */
69 unsigned long system_serial_high; /* 84 */
70 unsigned long mem_fclk_21285; /* 88 */
71 } s;
72 char unused[256];
73 } u1;
74 union {
75 char paths[8][128];
76 struct {
77 unsigned long magic;
78 char n[1024 - sizeof(unsigned long)];
79 } s;
80 } u2;
81 char commandline[COMMAND_LINE_SIZE];
82};
83
84static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size)
85{
86 tag = tag_next(tag);
87 tag->hdr.tag = ATAG_MEM;
88 tag->hdr.size = tag_size(tag_mem32);
89 tag->u.mem.size = size;
90 tag->u.mem.start = start;
91
92 return tag;
93}
94
95static void __init build_tag_list(struct param_struct *params, void *taglist)
96{
97 struct tag *tag = taglist;
98
99 if (params->u1.s.page_size != PAGE_SIZE) {
100 printk(KERN_WARNING "Warning: bad configuration page, "
101 "trying to continue\n");
102 return;
103 }
104
105 printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
106
107 tag->hdr.tag = ATAG_CORE;
108 tag->hdr.size = tag_size(tag_core);
109 tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
110 tag->u.core.pagesize = params->u1.s.page_size;
111 tag->u.core.rootdev = params->u1.s.rootdev;
112
113 tag = tag_next(tag);
114 tag->hdr.tag = ATAG_RAMDISK;
115 tag->hdr.size = tag_size(tag_ramdisk);
116 tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) |
117 (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0);
118 tag->u.ramdisk.size = params->u1.s.ramdisk_size;
119 tag->u.ramdisk.start = params->u1.s.rd_start;
120
121 tag = tag_next(tag);
122 tag->hdr.tag = ATAG_INITRD;
123 tag->hdr.size = tag_size(tag_initrd);
124 tag->u.initrd.start = params->u1.s.initrd_start;
125 tag->u.initrd.size = params->u1.s.initrd_size;
126
127 tag = tag_next(tag);
128 tag->hdr.tag = ATAG_SERIAL;
129 tag->hdr.size = tag_size(tag_serialnr);
130 tag->u.serialnr.low = params->u1.s.system_serial_low;
131 tag->u.serialnr.high = params->u1.s.system_serial_high;
132
133 tag = tag_next(tag);
134 tag->hdr.tag = ATAG_REVISION;
135 tag->hdr.size = tag_size(tag_revision);
136 tag->u.revision.rev = params->u1.s.system_rev;
137
138 tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
139
140 tag = tag_next(tag);
141 tag->hdr.tag = ATAG_ACORN;
142 tag->hdr.size = tag_size(tag_acorn);
143 tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg;
144 tag->u.acorn.vram_pages = params->u1.s.pages_in_vram;
145 tag->u.acorn.sounddefault = params->u1.s.sounddefault;
146 tag->u.acorn.adfsdrives = params->u1.s.adfsdrives;
147
148 tag = tag_next(tag);
149 tag->hdr.tag = ATAG_CMDLINE;
150 tag->hdr.size = (strlen(params->commandline) + 3 +
151 sizeof(struct tag_header)) >> 2;
152 strcpy(tag->u.cmdline.cmdline, params->commandline);
153
154 tag = tag_next(tag);
155 tag->hdr.tag = ATAG_NONE;
156 tag->hdr.size = 0;
157
158 memmove(params, taglist, ((int)tag) - ((int)taglist) +
159 sizeof(struct tag_header));
160}
161
162void __init convert_to_tag_list(struct tag *tags)
163{
164 struct param_struct *params = (struct param_struct *)tags;
165 build_tag_list(params, &params->u2);
166}
167
168void __init squash_mem_tags(struct tag *tag)
169{
170 for (; tag->hdr.size; tag = tag_next(tag))
171 if (tag->hdr.tag == ATAG_MEM)
172 tag->hdr.tag = ATAG_NONE;
173}
diff --git a/arch/arm26/kernel/dma.c b/arch/arm26/kernel/dma.c
deleted file mode 100644
index 80b5a774d905..000000000000
--- a/arch/arm26/kernel/dma.c
+++ /dev/null
@@ -1,273 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/dma.c
3 *
4 * Copyright (C) 1995-2000 Russell King
5 * 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Front-end to the DMA handling. This handles the allocation/freeing
12 * of DMA channels, and provides a unified interface to the machines
13 * DMA facilities.
14 */
15#include <linux/module.h>
16#include <linux/slab.h>
17#include <linux/sched.h>
18#include <linux/mman.h>
19#include <linux/init.h>
20#include <linux/spinlock.h>
21#include <linux/errno.h>
22
23#include <asm/dma.h>
24
25DEFINE_SPINLOCK(dma_spin_lock);
26
27static dma_t dma_chan[MAX_DMA_CHANNELS];
28
29/*
30 * Get dma list for /proc/dma
31 */
32int get_dma_list(char *buf)
33{
34 dma_t *dma;
35 char *p = buf;
36 int i;
37
38 for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++)
39 if (dma->lock)
40 p += sprintf(p, "%2d: %14s %s\n", i,
41 dma->d_ops->type, dma->device_id);
42
43 return p - buf;
44}
45
46/*
47 * Request DMA channel
48 *
49 * On certain platforms, we have to allocate an interrupt as well...
50 */
51int request_dma(dmach_t channel, const char *device_id)
52{
53 dma_t *dma = dma_chan + channel;
54 int ret;
55
56 if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
57 goto bad_dma;
58
59 if (xchg(&dma->lock, 1) != 0)
60 goto busy;
61
62 dma->device_id = device_id;
63 dma->active = 0;
64 dma->invalid = 1;
65
66 ret = 0;
67 if (dma->d_ops->request)
68 ret = dma->d_ops->request(channel, dma);
69
70 if (ret)
71 xchg(&dma->lock, 0);
72
73 return ret;
74
75bad_dma:
76 printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
77 return -EINVAL;
78
79busy:
80 return -EBUSY;
81}
82
83/*
84 * Free DMA channel
85 *
86 * On certain platforms, we have to free interrupt as well...
87 */
88void free_dma(dmach_t channel)
89{
90 dma_t *dma = dma_chan + channel;
91
92 if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
93 goto bad_dma;
94
95 if (dma->active) {
96 printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
97 dma->d_ops->disable(channel, dma);
98 dma->active = 0;
99 }
100
101 if (xchg(&dma->lock, 0) != 0) {
102 if (dma->d_ops->free)
103 dma->d_ops->free(channel, dma);
104 return;
105 }
106
107 printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
108 return;
109
110bad_dma:
111 printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
112}
113
114/* Set DMA Scatter-Gather list
115 */
116void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
117{
118 dma_t *dma = dma_chan + channel;
119
120 if (dma->active)
121 printk(KERN_ERR "dma%d: altering DMA SG while "
122 "DMA active\n", channel);
123
124 dma->sg = sg;
125 dma->sgcount = nr_sg;
126 dma->using_sg = 1;
127 dma->invalid = 1;
128}
129
130/* Set DMA address
131 *
132 * Copy address to the structure, and set the invalid bit
133 */
134void set_dma_addr (dmach_t channel, unsigned long physaddr)
135{
136 dma_t *dma = dma_chan + channel;
137
138 if (dma->active)
139 printk(KERN_ERR "dma%d: altering DMA address while "
140 "DMA active\n", channel);
141
142 dma->sg = &dma->buf;
143 dma->sgcount = 1;
144 dma->buf.__address = (char *)physaddr;//FIXME - not pretty
145 dma->using_sg = 0;
146 dma->invalid = 1;
147}
148
149/* Set DMA byte count
150 *
151 * Copy address to the structure, and set the invalid bit
152 */
153void set_dma_count (dmach_t channel, unsigned long count)
154{
155 dma_t *dma = dma_chan + channel;
156
157 if (dma->active)
158 printk(KERN_ERR "dma%d: altering DMA count while "
159 "DMA active\n", channel);
160
161 dma->sg = &dma->buf;
162 dma->sgcount = 1;
163 dma->buf.length = count;
164 dma->using_sg = 0;
165 dma->invalid = 1;
166}
167
168/* Set DMA direction mode
169 */
170void set_dma_mode (dmach_t channel, dmamode_t mode)
171{
172 dma_t *dma = dma_chan + channel;
173
174 if (dma->active)
175 printk(KERN_ERR "dma%d: altering DMA mode while "
176 "DMA active\n", channel);
177
178 dma->dma_mode = mode;
179 dma->invalid = 1;
180}
181
182/* Enable DMA channel
183 */
184void enable_dma (dmach_t channel)
185{
186 dma_t *dma = dma_chan + channel;
187
188 if (!dma->lock)
189 goto free_dma;
190
191 if (dma->active == 0) {
192 dma->active = 1;
193 dma->d_ops->enable(channel, dma);
194 }
195 return;
196
197free_dma:
198 printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
199 BUG();
200}
201
202/* Disable DMA channel
203 */
204void disable_dma (dmach_t channel)
205{
206 dma_t *dma = dma_chan + channel;
207
208 if (!dma->lock)
209 goto free_dma;
210
211 if (dma->active == 1) {
212 dma->active = 0;
213 dma->d_ops->disable(channel, dma);
214 }
215 return;
216
217free_dma:
218 printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
219 BUG();
220}
221
222/*
223 * Is the specified DMA channel active?
224 */
225int dma_channel_active(dmach_t channel)
226{
227 return dma_chan[channel].active;
228}
229
230void set_dma_page(dmach_t channel, char pagenr)
231{
232 printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
233}
234
235void set_dma_speed(dmach_t channel, int cycle_ns)
236{
237 dma_t *dma = dma_chan + channel;
238 int ret = 0;
239
240 if (dma->d_ops->setspeed)
241 ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
242 dma->speed = ret;
243}
244
245int get_dma_residue(dmach_t channel)
246{
247 dma_t *dma = dma_chan + channel;
248 int ret = 0;
249
250 if (dma->d_ops->residue)
251 ret = dma->d_ops->residue(channel, dma);
252
253 return ret;
254}
255
256void __init init_dma(void)
257{
258 arch_dma_init(dma_chan);
259}
260
261EXPORT_SYMBOL(request_dma);
262EXPORT_SYMBOL(free_dma);
263EXPORT_SYMBOL(enable_dma);
264EXPORT_SYMBOL(disable_dma);
265EXPORT_SYMBOL(set_dma_addr);
266EXPORT_SYMBOL(set_dma_count);
267EXPORT_SYMBOL(set_dma_mode);
268EXPORT_SYMBOL(set_dma_page);
269EXPORT_SYMBOL(get_dma_residue);
270EXPORT_SYMBOL(set_dma_sg);
271EXPORT_SYMBOL(set_dma_speed);
272
273EXPORT_SYMBOL(dma_spin_lock);
diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c
deleted file mode 100644
index e2bcefc91cc3..000000000000
--- a/arch/arm26/kernel/ecard.c
+++ /dev/null
@@ -1,847 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/ecard.c
3 *
4 * Copyright 1995-2001 Russell King
5 * Copyright 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Find all installed expansion cards, and handle interrupts from them.
12 *
13 * Created from information from Acorns RiscOS3 PRMs
14 * 15-Jun-2003 IM Modified from ARM32 (RiscPC capable) version
15 * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
16 * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
17 * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
18 * - cards can now register their own routine to control
19 * interrupts (recommended).
20 * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
21 * on reset from Linux. (Caused cards not to respond
22 * under RiscOS without hard reset).
23 *
24 */
25#define ECARD_C
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/types.h>
30#include <linux/sched.h>
31#include <linux/interrupt.h>
32#include <linux/reboot.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <linux/proc_fs.h>
36#include <linux/device.h>
37#include <linux/init.h>
38
39#include <asm/dma.h>
40#include <asm/ecard.h>
41#include <asm/hardware.h>
42#include <asm/io.h>
43#include <asm/irq.h>
44#include <asm/mmu_context.h>
45#include <asm/irqchip.h>
46#include <asm/tlbflush.h>
47
48enum req {
49 req_readbytes,
50 req_reset
51};
52
53struct ecard_request {
54 enum req req;
55 ecard_t *ec;
56 unsigned int address;
57 unsigned int length;
58 unsigned int use_loader;
59 void *buffer;
60};
61
62struct expcard_blacklist {
63 unsigned short manufacturer;
64 unsigned short product;
65 const char *type;
66};
67
68static ecard_t *cards;
69static ecard_t *slot_to_expcard[MAX_ECARDS];
70static unsigned int ectcr;
71
72/* List of descriptions of cards which don't have an extended
73 * identification, or chunk directories containing a description.
74 */
75static struct expcard_blacklist __initdata blacklist[] = {
76 { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
77};
78
79asmlinkage extern int
80ecard_loader_reset(volatile unsigned char *pa, loader_t loader);
81asmlinkage extern int
82ecard_loader_read(int off, volatile unsigned char *pa, loader_t loader);
83
84static const struct ecard_id *
85ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec);
86
87static inline unsigned short
88ecard_getu16(unsigned char *v)
89{
90 return v[0] | v[1] << 8;
91}
92
93static inline signed long
94ecard_gets24(unsigned char *v)
95{
96 return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
97}
98
99static inline ecard_t *
100slot_to_ecard(unsigned int slot)
101{
102 return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
103}
104
105/* ===================== Expansion card daemon ======================== */
106/*
107 * Since the loader programs on the expansion cards need to be run
108 * in a specific environment, create a separate task with this
109 * environment up, and pass requests to this task as and when we
110 * need to.
111 *
112 * This should allow 99% of loaders to be called from Linux.
113 *
114 * From a security standpoint, we trust the card vendors. This
115 * may be a misplaced trust.
116 */
117#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
118#define POD_INT_ADDR(x) ((volatile unsigned char *)\
119 ((BUS_ADDR((x)) - IO_BASE) + IO_START))
120
121static inline void ecard_task_reset(struct ecard_request *req)
122{
123 struct expansion_card *ec = req->ec;
124 if (ec->loader)
125 ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader);
126}
127
128static void
129ecard_task_readbytes(struct ecard_request *req)
130{
131 unsigned char *buf = (unsigned char *)req->buffer;
132 volatile unsigned char *base_addr =
133 (volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
134 unsigned int len = req->length;
135 unsigned int off = req->address;
136
137 if (!req->use_loader || !req->ec->loader) {
138 off *= 4;
139 while (len--) {
140 *buf++ = base_addr[off];
141 off += 4;
142 }
143 } else {
144 while(len--) {
145 /*
146 * The following is required by some
147 * expansion card loader programs.
148 */
149 *(unsigned long *)0x108 = 0;
150 *buf++ = ecard_loader_read(off++, base_addr,
151 req->ec->loader);
152 }
153 }
154}
155
156static void ecard_do_request(struct ecard_request *req)
157{
158 switch (req->req) {
159 case req_readbytes:
160 ecard_task_readbytes(req);
161 break;
162
163 case req_reset:
164 ecard_task_reset(req);
165 break;
166 }
167}
168
169/*
170 * On 26-bit processors, we don't need the kcardd thread to access the
171 * expansion card loaders. We do it directly.
172 */
173#define ecard_call(req) ecard_do_request(req)
174
175/* ======================= Mid-level card control ===================== */
176
177static void
178ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
179{
180 struct ecard_request req;
181
182 req.req = req_readbytes;
183 req.ec = ec;
184 req.address = off;
185 req.length = len;
186 req.use_loader = useld;
187 req.buffer = addr;
188
189 ecard_call(&req);
190}
191
192int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
193{
194 struct ex_chunk_dir excd;
195 int index = 16;
196 int useld = 0;
197
198 if (!ec->cid.cd)
199 return 0;
200
201 while(1) {
202 ecard_readbytes(&excd, ec, index, 8, useld);
203 index += 8;
204 if (c_id(&excd) == 0) {
205 if (!useld && ec->loader) {
206 useld = 1;
207 index = 0;
208 continue;
209 }
210 return 0;
211 }
212 if (c_id(&excd) == 0xf0) { /* link */
213 index = c_start(&excd);
214 continue;
215 }
216 if (c_id(&excd) == 0x80) { /* loader */
217 if (!ec->loader) {
218 ec->loader = kmalloc(c_len(&excd),
219 GFP_KERNEL);
220 if (ec->loader)
221 ecard_readbytes(ec->loader, ec,
222 (int)c_start(&excd),
223 c_len(&excd), useld);
224 else
225 return 0;
226 }
227 continue;
228 }
229 if (c_id(&excd) == id && num-- == 0)
230 break;
231 }
232
233 if (c_id(&excd) & 0x80) {
234 switch (c_id(&excd) & 0x70) {
235 case 0x70:
236 ecard_readbytes((unsigned char *)excd.d.string, ec,
237 (int)c_start(&excd), c_len(&excd),
238 useld);
239 break;
240 case 0x00:
241 break;
242 }
243 }
244 cd->start_offset = c_start(&excd);
245 memcpy(cd->d.string, excd.d.string, 256);
246 return 1;
247}
248
249/* ======================= Interrupt control ============================ */
250
251static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
252{
253}
254
255static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
256{
257}
258
259static int ecard_def_irq_pending(ecard_t *ec)
260{
261 return !ec->irqmask || ec->irqaddr[0] & ec->irqmask;
262}
263
264static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
265{
266 panic("ecard_def_fiq_enable called - impossible");
267}
268
269static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
270{
271 panic("ecard_def_fiq_disable called - impossible");
272}
273
274static int ecard_def_fiq_pending(ecard_t *ec)
275{
276 return !ec->fiqmask || ec->fiqaddr[0] & ec->fiqmask;
277}
278
279static expansioncard_ops_t ecard_default_ops = {
280 ecard_def_irq_enable,
281 ecard_def_irq_disable,
282 ecard_def_irq_pending,
283 ecard_def_fiq_enable,
284 ecard_def_fiq_disable,
285 ecard_def_fiq_pending
286};
287
288/*
289 * Enable and disable interrupts from expansion cards.
290 * (interrupts are disabled for these functions).
291 *
292 * They are not meant to be called directly, but via enable/disable_irq.
293 */
294static void ecard_irq_unmask(unsigned int irqnr)
295{
296 ecard_t *ec = slot_to_ecard(irqnr - 32);
297
298 if (ec) {
299 if (!ec->ops)
300 ec->ops = &ecard_default_ops;
301
302 if (ec->claimed && ec->ops->irqenable)
303 ec->ops->irqenable(ec, irqnr);
304 else
305 printk(KERN_ERR "ecard: rejecting request to "
306 "enable IRQs for %d\n", irqnr);
307 }
308}
309
310static void ecard_irq_mask(unsigned int irqnr)
311{
312 ecard_t *ec = slot_to_ecard(irqnr - 32);
313
314 if (ec) {
315 if (!ec->ops)
316 ec->ops = &ecard_default_ops;
317
318 if (ec->ops && ec->ops->irqdisable)
319 ec->ops->irqdisable(ec, irqnr);
320 }
321}
322
323static struct irqchip ecard_chip = {
324 .ack = ecard_irq_mask,
325 .mask = ecard_irq_mask,
326 .unmask = ecard_irq_unmask,
327};
328
329void ecard_enablefiq(unsigned int fiqnr)
330{
331 ecard_t *ec = slot_to_ecard(fiqnr);
332
333 if (ec) {
334 if (!ec->ops)
335 ec->ops = &ecard_default_ops;
336
337 if (ec->claimed && ec->ops->fiqenable)
338 ec->ops->fiqenable(ec, fiqnr);
339 else
340 printk(KERN_ERR "ecard: rejecting request to "
341 "enable FIQs for %d\n", fiqnr);
342 }
343}
344
345void ecard_disablefiq(unsigned int fiqnr)
346{
347 ecard_t *ec = slot_to_ecard(fiqnr);
348
349 if (ec) {
350 if (!ec->ops)
351 ec->ops = &ecard_default_ops;
352
353 if (ec->ops->fiqdisable)
354 ec->ops->fiqdisable(ec, fiqnr);
355 }
356}
357
358static void
359ecard_dump_irq_state(ecard_t *ec)
360{
361 printk(" %d: %sclaimed, ",
362 ec->slot_no,
363 ec->claimed ? "" : "not ");
364
365 if (ec->ops && ec->ops->irqpending &&
366 ec->ops != &ecard_default_ops)
367 printk("irq %spending\n",
368 ec->ops->irqpending(ec) ? "" : "not ");
369 else
370 printk("irqaddr %p, mask = %02X, status = %02X\n",
371 ec->irqaddr, ec->irqmask, *ec->irqaddr);
372}
373
374static void ecard_check_lockup(struct irqdesc *desc)
375{
376 static int last, lockup;
377 ecard_t *ec;
378
379 /*
380 * If the timer interrupt has not run since the last million
381 * unrecognised expansion card interrupts, then there is
382 * something seriously wrong. Disable the expansion card
383 * interrupts so at least we can continue.
384 *
385 * Maybe we ought to start a timer to re-enable them some time
386 * later?
387 */
388 if (last == jiffies) {
389 lockup += 1;
390 if (lockup > 1000000) {
391 printk(KERN_ERR "\nInterrupt lockup detected - "
392 "disabling all expansion card interrupts\n");
393
394 desc->chip->mask(IRQ_EXPANSIONCARD);
395
396 printk("Expansion card IRQ state:\n");
397
398 for (ec = cards; ec; ec = ec->next)
399 ecard_dump_irq_state(ec);
400 }
401 } else
402 lockup = 0;
403
404 /*
405 * If we did not recognise the source of this interrupt,
406 * warn the user, but don't flood the user with these messages.
407 */
408 if (!last || time_after(jiffies, (unsigned long)(last + 5*HZ))) {
409 last = jiffies;
410 printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
411 }
412}
413
414static void
415ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
416{
417 ecard_t *ec;
418 int called = 0;
419
420 desc->chip->mask(irq);
421 for (ec = cards; ec; ec = ec->next) {
422 int pending;
423
424 if (!ec->claimed || ec->irq == NO_IRQ)
425 continue;
426
427 if (ec->ops && ec->ops->irqpending)
428 pending = ec->ops->irqpending(ec);
429 else
430 pending = ecard_default_ops.irqpending(ec);
431
432 if (pending) {
433 struct irqdesc *d = irq_desc + ec->irq;
434 d->handle(ec->irq, d, regs);
435 called ++;
436 }
437 }
438 desc->chip->unmask(irq);
439
440 if (called == 0)
441 ecard_check_lockup(desc);
442}
443
444#define ecard_irqexp_handler NULL
445#define ecard_probeirqhw() (0)
446
447unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
448{
449 unsigned long address = 0;
450 int slot = ec->slot_no;
451
452 ectcr &= ~(1 << slot);
453
454 switch (type) {
455 case ECARD_MEMC:
456 address = IO_EC_MEMC_BASE + (slot << 12);
457 break;
458
459 case ECARD_IOC:
460 address = IO_EC_IOC_BASE + (slot << 12) + (speed << 17);
461 break;
462
463 default:
464 break;
465 }
466
467 return address;
468}
469
470static int ecard_prints(char *buffer, ecard_t *ec)
471{
472 char *start = buffer;
473
474 buffer += sprintf(buffer, " %d: ", ec->slot_no);
475
476 if (ec->cid.id == 0) {
477 struct in_chunk_dir incd;
478
479 buffer += sprintf(buffer, "[%04X:%04X] ",
480 ec->cid.manufacturer, ec->cid.product);
481
482 if (!ec->card_desc && ec->cid.cd &&
483 ecard_readchunk(&incd, ec, 0xf5, 0)) {
484 ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
485
486 if (ec->card_desc)
487 strcpy((char *)ec->card_desc, incd.d.string);
488 }
489
490 buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
491 } else
492 buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id);
493
494 return buffer - start;
495}
496
497static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count)
498{
499 ecard_t *ec = cards;
500 off_t at = 0;
501 int len, cnt;
502
503 cnt = 0;
504 while (ec && count > cnt) {
505 len = ecard_prints(buf, ec);
506 at += len;
507 if (at >= pos) {
508 if (!*start) {
509 *start = buf + (pos - (at - len));
510 cnt = at - pos;
511 } else
512 cnt += len;
513 buf += len;
514 }
515 ec = ec->next;
516 }
517 return (count > cnt) ? cnt : count;
518}
519
520static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
521
522static void ecard_proc_init(void)
523{
524 proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
525 create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
526 get_ecard_dev_info);
527}
528
529#define ec_set_resource(ec,nr,st,sz,flg) \
530 do { \
531 (ec)->resource[nr].name = ec->dev.bus_id; \
532 (ec)->resource[nr].start = st; \
533 (ec)->resource[nr].end = (st) + (sz) - 1; \
534 (ec)->resource[nr].flags = flg; \
535 } while (0)
536
537static void __init ecard_init_resources(struct expansion_card *ec)
538{
539 unsigned long base = PODSLOT_IOC0_BASE;
540 unsigned int slot = ec->slot_no;
541 int i;
542
543 ec_set_resource(ec, ECARD_RES_MEMC,
544 PODSLOT_MEMC_BASE + (slot << 14),
545 PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
546
547 for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
548 ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
549 base + (slot << 14) + (i << 19),
550 PODSLOT_IOC_SIZE, IORESOURCE_MEM);
551 }
552
553 for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
554 if (ec->resource[i].start &&
555 request_resource(&iomem_resource, &ec->resource[i])) {
556 printk(KERN_ERR "%s: resource(s) not available\n",
557 ec->dev.bus_id);
558 ec->resource[i].end -= ec->resource[i].start;
559 ec->resource[i].start = 0;
560 }
561 }
562}
563
564static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
565{
566 struct expansion_card *ec = ECARD_DEV(dev);
567 return sprintf(buf, "%u\n", ec->irq);
568}
569
570static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
571{
572 struct expansion_card *ec = ECARD_DEV(dev);
573 return sprintf(buf, "%u\n", ec->cid.manufacturer);
574}
575
576static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
577{
578 struct expansion_card *ec = ECARD_DEV(dev);
579 return sprintf(buf, "%u\n", ec->cid.product);
580}
581
582static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
583{
584 struct expansion_card *ec = ECARD_DEV(dev);
585 return sprintf(buf, "%u\n", ec->dma);
586}
587
588static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
589{
590 struct expansion_card *ec = ECARD_DEV(dev);
591 char *str = buf;
592 int i;
593
594 for (i = 0; i < ECARD_NUM_RESOURCES; i++)
595 str += sprintf(str, "%08lx %08lx %08lx\n",
596 ec->resource[i].start,
597 ec->resource[i].end,
598 ec->resource[i].flags);
599
600 return str - buf;
601}
602
603static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
604static DEVICE_ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL);
605static DEVICE_ATTR(device, S_IRUGO, ecard_show_device, NULL);
606static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
607static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
608
609/*
610 * Probe for an expansion card.
611 *
612 * If bit 1 of the first byte of the card is set, then the
613 * card does not exist.
614 */
615static int __init
616ecard_probe(int slot, card_type_t type)
617{
618 ecard_t **ecp;
619 ecard_t *ec;
620 struct ex_ecid cid;
621 int i, rc = -ENOMEM;
622
623 ec = kzalloc(sizeof(ecard_t), GFP_KERNEL);
624 if (!ec)
625 goto nomem;
626
627 ec->slot_no = slot;
628 ec->type = type;
629 ec->irq = NO_IRQ;
630 ec->fiq = NO_IRQ;
631 ec->dma = NO_DMA;
632 ec->card_desc = NULL;
633 ec->ops = &ecard_default_ops;
634
635 rc = -ENODEV;
636 if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
637 goto nodev;
638
639 cid.r_zero = 1;
640 ecard_readbytes(&cid, ec, 0, 16, 0);
641 if (cid.r_zero)
642 goto nodev;
643
644 ec->cid.id = cid.r_id;
645 ec->cid.cd = cid.r_cd;
646 ec->cid.is = cid.r_is;
647 ec->cid.w = cid.r_w;
648 ec->cid.manufacturer = ecard_getu16(cid.r_manu);
649 ec->cid.product = ecard_getu16(cid.r_prod);
650 ec->cid.country = cid.r_country;
651 ec->cid.irqmask = cid.r_irqmask;
652 ec->cid.irqoff = ecard_gets24(cid.r_irqoff);
653 ec->cid.fiqmask = cid.r_fiqmask;
654 ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
655 ec->fiqaddr =
656 ec->irqaddr = (unsigned char *)ioaddr(ec->podaddr);
657
658 if (ec->cid.is) {
659 ec->irqmask = ec->cid.irqmask;
660 ec->irqaddr += ec->cid.irqoff;
661 ec->fiqmask = ec->cid.fiqmask;
662 ec->fiqaddr += ec->cid.fiqoff;
663 } else {
664 ec->irqmask = 1;
665 ec->fiqmask = 4;
666 }
667
668 for (i = 0; i < ARRAY_SIZE(blacklist); i++)
669 if (blacklist[i].manufacturer == ec->cid.manufacturer &&
670 blacklist[i].product == ec->cid.product) {
671 ec->card_desc = blacklist[i].type;
672 break;
673 }
674
675 snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
676 ec->dev.parent = NULL;
677 ec->dev.bus = &ecard_bus_type;
678 ec->dev.dma_mask = &ec->dma_mask;
679 ec->dma_mask = (u64)0xffffffff;
680
681 ecard_init_resources(ec);
682
683 /*
684 * hook the interrupt handlers
685 */
686 ec->irq = 32 + slot;
687 set_irq_chip(ec->irq, &ecard_chip);
688 set_irq_handler(ec->irq, do_level_IRQ);
689 set_irq_flags(ec->irq, IRQF_VALID);
690
691 for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
692
693 *ecp = ec;
694 slot_to_expcard[slot] = ec;
695
696 device_register(&ec->dev);
697 device_create_file(&ec->dev, &dev_attr_dma);
698 device_create_file(&ec->dev, &dev_attr_irq);
699 device_create_file(&ec->dev, &dev_attr_resource);
700 device_create_file(&ec->dev, &dev_attr_vendor);
701 device_create_file(&ec->dev, &dev_attr_device);
702
703 return 0;
704
705nodev:
706 kfree(ec);
707nomem:
708 return rc;
709}
710
711/*
712 * Initialise the expansion card system.
713 * Locate all hardware - interrupt management and
714 * actual cards.
715 */
716static int __init ecard_init(void)
717{
718 int slot, irqhw;
719
720 printk("Probing expansion cards\n");
721
722 for (slot = 0; slot < MAX_ECARDS; slot ++) {
723 ecard_probe(slot, ECARD_IOC);
724 }
725
726 irqhw = ecard_probeirqhw();
727
728 set_irq_chained_handler(IRQ_EXPANSIONCARD,
729 irqhw ? ecard_irqexp_handler : ecard_irq_handler);
730
731 ecard_proc_init();
732
733 return 0;
734}
735
736subsys_initcall(ecard_init);
737
738/*
739 * ECARD "bus"
740 */
741static const struct ecard_id *
742ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
743{
744 int i;
745
746 for (i = 0; ids[i].manufacturer != 65535; i++)
747 if (ec->cid.manufacturer == ids[i].manufacturer &&
748 ec->cid.product == ids[i].product)
749 return ids + i;
750
751 return NULL;
752}
753
754static int ecard_drv_probe(struct device *dev)
755{
756 struct expansion_card *ec = ECARD_DEV(dev);
757 struct ecard_driver *drv = ECARD_DRV(dev->driver);
758 const struct ecard_id *id;
759 int ret;
760
761 id = ecard_match_device(drv->id_table, ec);
762
763 ecard_claim(ec);
764 ret = drv->probe(ec, id);
765 if (ret)
766 ecard_release(ec);
767 return ret;
768}
769
770static int ecard_drv_remove(struct device *dev)
771{
772 struct expansion_card *ec = ECARD_DEV(dev);
773 struct ecard_driver *drv = ECARD_DRV(dev->driver);
774
775 drv->remove(ec);
776 ecard_release(ec);
777
778 return 0;
779}
780
781/*
782 * Before rebooting, we must make sure that the expansion card is in a
783 * sensible state, so it can be re-detected. This means that the first
784 * page of the ROM must be visible. We call the expansion cards reset
785 * handler, if any.
786 */
787static void ecard_drv_shutdown(struct device *dev)
788{
789 struct expansion_card *ec = ECARD_DEV(dev);
790 struct ecard_driver *drv = ECARD_DRV(dev->driver);
791 struct ecard_request req;
792
793 if (drv->shutdown)
794 drv->shutdown(ec);
795 ecard_release(ec);
796 req.req = req_reset;
797 req.ec = ec;
798 ecard_call(&req);
799}
800
801int ecard_register_driver(struct ecard_driver *drv)
802{
803 drv->drv.bus = &ecard_bus_type;
804 drv->drv.probe = ecard_drv_probe;
805 drv->drv.remove = ecard_drv_remove;
806 drv->drv.shutdown = ecard_drv_shutdown;
807
808 return driver_register(&drv->drv);
809}
810
811void ecard_remove_driver(struct ecard_driver *drv)
812{
813 driver_unregister(&drv->drv);
814}
815
816static int ecard_match(struct device *_dev, struct device_driver *_drv)
817{
818 struct expansion_card *ec = ECARD_DEV(_dev);
819 struct ecard_driver *drv = ECARD_DRV(_drv);
820 int ret;
821
822 if (drv->id_table) {
823 ret = ecard_match_device(drv->id_table, ec) != NULL;
824 } else {
825 ret = ec->cid.id == drv->id;
826 }
827
828 return ret;
829}
830
831struct bus_type ecard_bus_type = {
832 .name = "ecard",
833 .match = ecard_match,
834};
835
836static int ecard_bus_init(void)
837{
838 return bus_register(&ecard_bus_type);
839}
840
841postcore_initcall(ecard_bus_init);
842
843EXPORT_SYMBOL(ecard_readchunk);
844EXPORT_SYMBOL(ecard_address);
845EXPORT_SYMBOL(ecard_register_driver);
846EXPORT_SYMBOL(ecard_remove_driver);
847EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm26/kernel/entry.S b/arch/arm26/kernel/entry.S
deleted file mode 100644
index 7ffcc6e4770e..000000000000
--- a/arch/arm26/kernel/entry.S
+++ /dev/null
@@ -1,951 +0,0 @@
1/* arch/arm26/kernel/entry.S
2 *
3 * Assembled from chunks of code in arch/arm
4 *
5 * Copyright (C) 2003 Ian Molton
6 * Based on the work of RMK.
7 *
8 */
9
10#include <linux/linkage.h>
11
12#include <asm/assembler.h>
13#include <asm/asm-offsets.h>
14#include <asm/errno.h>
15#include <asm/hardware.h>
16#include <asm/sysirq.h>
17#include <asm/thread_info.h>
18#include <asm/page.h>
19#include <asm/ptrace.h>
20
21 .macro zero_fp
22#ifndef CONFIG_NO_FRAME_POINTER
23 mov fp, #0
24#endif
25 .endm
26
27 .text
28
29@ Bad Abort numbers
30@ -----------------
31@
32#define BAD_PREFETCH 0
33#define BAD_DATA 1
34#define BAD_ADDREXCPTN 2
35#define BAD_IRQ 3
36#define BAD_UNDEFINSTR 4
37
38@ OS version number used in SWIs
39@ RISC OS is 0
40@ RISC iX is 8
41@
42#define OS_NUMBER 9
43#define ARMSWI_OFFSET 0x000f0000
44
45@
46@ Stack format (ensured by USER_* and SVC_*)
47@ PSR and PC are comined on arm26
48@
49
50#define S_OFF 8
51
52#define S_OLD_R0 64
53#define S_PC 60
54#define S_LR 56
55#define S_SP 52
56#define S_IP 48
57#define S_FP 44
58#define S_R10 40
59#define S_R9 36
60#define S_R8 32
61#define S_R7 28
62#define S_R6 24
63#define S_R5 20
64#define S_R4 16
65#define S_R3 12
66#define S_R2 8
67#define S_R1 4
68#define S_R0 0
69
70 .macro save_user_regs
71 str r0, [sp, #-4]! @ Store SVC r0
72 str lr, [sp, #-4]! @ Store user mode PC
73 sub sp, sp, #15*4
74 stmia sp, {r0 - lr}^ @ Store the other user-mode regs
75 mov r0, r0
76 .endm
77
78 .macro slow_restore_user_regs
79 ldmia sp, {r0 - lr}^ @ restore the user regs not including PC
80 mov r0, r0
81 ldr lr, [sp, #15*4] @ get user PC
82 add sp, sp, #15*4+8 @ free stack
83 movs pc, lr @ return
84 .endm
85
86 .macro fast_restore_user_regs
87 add sp, sp, #S_OFF
88 ldmib sp, {r1 - lr}^
89 mov r0, r0
90 ldr lr, [sp, #15*4]
91 add sp, sp, #15*4+8
92 movs pc, lr
93 .endm
94
95 .macro save_svc_regs
96 str sp, [sp, #-16]!
97 str lr, [sp, #8]
98 str lr, [sp, #4]
99 stmfd sp!, {r0 - r12}
100 mov r0, #-1
101 str r0, [sp, #S_OLD_R0]
102 zero_fp
103 .endm
104
105 .macro save_svc_regs_irq
106 str sp, [sp, #-16]!
107 str lr, [sp, #4]
108 ldr lr, .LCirq
109 ldr lr, [lr]
110 str lr, [sp, #8]
111 stmfd sp!, {r0 - r12}
112 mov r0, #-1
113 str r0, [sp, #S_OLD_R0]
114 zero_fp
115 .endm
116
117 .macro restore_svc_regs
118 ldmfd sp, {r0 - pc}^
119 .endm
120
121 .macro mask_pc, rd, rm
122 bic \rd, \rm, #PCMASK
123 .endm
124
125 .macro disable_irqs, temp
126 mov \temp, pc
127 orr \temp, \temp, #PSR_I_BIT
128 teqp \temp, #0
129 .endm
130
131 .macro enable_irqs, temp
132 mov \temp, pc
133 and \temp, \temp, #~PSR_I_BIT
134 teqp \temp, #0
135 .endm
136
137 .macro initialise_traps_extra
138 .endm
139
140 .macro get_thread_info, rd
141 mov \rd, sp, lsr #13
142 mov \rd, \rd, lsl #13
143 .endm
144
145/*
146 * These are the registers used in the syscall handler, and allow us to
147 * have in theory up to 7 arguments to a function - r0 to r6.
148 *
149 * Note that tbl == why is intentional.
150 *
151 * We must set at least "tsk" and "why" when calling ret_with_reschedule.
152 */
153scno .req r7 @ syscall number
154tbl .req r8 @ syscall table pointer
155why .req r8 @ Linux syscall (!= 0)
156tsk .req r9 @ current thread_info
157
158/*
159 * Get the system call number.
160 */
161 .macro get_scno
162 mask_pc lr, lr
163 ldr scno, [lr, #-4] @ get SWI instruction
164 .endm
165/*
166 * -----------------------------------------------------------------------
167 */
168
169/*
170 * We rely on the fact that R0 is at the bottom of the stack (due to
171 * slow/fast restore user regs).
172 */
173#if S_R0 != 0
174#error "Please fix"
175#endif
176
177/*
178 * This is the fast syscall return path. We do as little as
179 * possible here, and this includes saving r0 back into the SVC
180 * stack.
181 */
182ret_fast_syscall:
183 disable_irqs r1 @ disable interrupts
184 ldr r1, [tsk, #TI_FLAGS]
185 tst r1, #_TIF_WORK_MASK
186 bne fast_work_pending
187 fast_restore_user_regs
188
189/*
190 * Ok, we need to do extra processing, enter the slow path.
191 */
192fast_work_pending:
193 str r0, [sp, #S_R0+S_OFF]! @ returned r0
194work_pending:
195 tst r1, #_TIF_NEED_RESCHED
196 bne work_resched
197 tst r1, #_TIF_SIGPENDING
198 beq no_work_pending
199 mov r0, sp @ 'regs'
200 mov r2, why @ 'syscall'
201 bl do_notify_resume
202 disable_irqs r1 @ disable interrupts
203 b no_work_pending
204
205work_resched:
206 bl schedule
207/*
208 * "slow" syscall return path. "why" tells us if this was a real syscall.
209 */
210ENTRY(ret_to_user)
211ret_slow_syscall:
212 disable_irqs r1 @ disable interrupts
213 ldr r1, [tsk, #TI_FLAGS]
214 tst r1, #_TIF_WORK_MASK
215 bne work_pending
216no_work_pending:
217 slow_restore_user_regs
218
219/*
220 * This is how we return from a fork.
221 */
222ENTRY(ret_from_fork)
223 bl schedule_tail
224 get_thread_info tsk
225 ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
226 mov why, #1
227 tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
228 beq ret_slow_syscall
229 mov r1, sp
230 mov r0, #1 @ trace exit [IP = 1]
231 bl syscall_trace
232 b ret_slow_syscall
233
234// FIXME - is this strictly necessary?
235#include "calls.S"
236
237/*=============================================================================
238 * SWI handler
239 *-----------------------------------------------------------------------------
240 */
241
242 .align 5
243ENTRY(vector_swi)
244 save_user_regs
245 zero_fp
246 get_scno
247
248 enable_irqs ip
249
250 str r4, [sp, #-S_OFF]! @ push fifth arg
251
252 get_thread_info tsk
253 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
254 bic scno, scno, #0xff000000 @ mask off SWI op-code
255 eor scno, scno, #OS_NUMBER << 20 @ check OS number
256 adr tbl, sys_call_table @ load syscall table pointer
257 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
258 bne __sys_trace
259
260 adral lr, ret_fast_syscall @ set return address
261 orral lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
262 cmp scno, #NR_syscalls @ check upper syscall limit
263 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
264
265 add r1, sp, #S_OFF
2662: mov why, #0 @ no longer a real syscall
267 cmp scno, #ARMSWI_OFFSET
268 eor r0, scno, #OS_NUMBER << 20 @ put OS number back
269 bcs arm_syscall
270 b sys_ni_syscall @ not private func
271
272 /*
273 * This is the really slow path. We're going to be doing
274 * context switches, and waiting for our parent to respond.
275 */
276__sys_trace:
277 add r1, sp, #S_OFF
278 mov r0, #0 @ trace entry [IP = 0]
279 bl syscall_trace
280
281 adral lr, __sys_trace_return @ set return address
282 orral lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
283 add r1, sp, #S_R0 + S_OFF @ pointer to regs
284 cmp scno, #NR_syscalls @ check upper syscall limit
285 ldmccia r1, {r0 - r3} @ have to reload r0 - r3
286 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
287 b 2b
288
289__sys_trace_return:
290 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
291 mov r1, sp
292 mov r0, #1 @ trace exit [IP = 1]
293 bl syscall_trace
294 b ret_slow_syscall
295
296 .align 5
297
298 .type sys_call_table, #object
299ENTRY(sys_call_table)
300#include "calls.S"
301
302/*============================================================================
303 * Special system call wrappers
304 */
305@ r0 = syscall number
306@ r5 = syscall table
307 .type sys_syscall, #function
308sys_syscall:
309 eor scno, r0, #OS_NUMBER << 20
310 cmp scno, #NR_syscalls @ check range
311 stmleia sp, {r5, r6} @ shuffle args
312 movle r0, r1
313 movle r1, r2
314 movle r2, r3
315 movle r3, r4
316 ldrle pc, [tbl, scno, lsl #2]
317 b sys_ni_syscall
318
319sys_fork_wrapper:
320 add r0, sp, #S_OFF
321 b sys_fork
322
323sys_vfork_wrapper:
324 add r0, sp, #S_OFF
325 b sys_vfork
326
327sys_execve_wrapper:
328 add r3, sp, #S_OFF
329 b sys_execve
330
331sys_clone_wapper:
332 add r2, sp, #S_OFF
333 b sys_clone
334
335sys_sigsuspend_wrapper:
336 add r3, sp, #S_OFF
337 b sys_sigsuspend
338
339sys_rt_sigsuspend_wrapper:
340 add r2, sp, #S_OFF
341 b sys_rt_sigsuspend
342
343sys_sigreturn_wrapper:
344 add r0, sp, #S_OFF
345 b sys_sigreturn
346
347sys_rt_sigreturn_wrapper:
348 add r0, sp, #S_OFF
349 b sys_rt_sigreturn
350
351sys_sigaltstack_wrapper:
352 ldr r2, [sp, #S_OFF + S_SP]
353 b do_sigaltstack
354
355/*
356 * Note: off_4k (r5) is always units of 4K. If we can't do the requested
357 * offset, we return EINVAL. FIXME - this lost some stuff from arm32 to
358 * ifdefs. check it out.
359 */
360sys_mmap2:
361 tst r5, #((1 << (PAGE_SHIFT - 12)) - 1)
362 moveq r5, r5, lsr #PAGE_SHIFT - 12
363 streq r5, [sp, #4]
364 beq do_mmap2
365 mov r0, #-EINVAL
366 RETINSTR(mov,pc, lr)
367
368/*
369 * Design issues:
370 * - We have several modes that each vector can be called from,
371 * each with its own set of registers. On entry to any vector,
372 * we *must* save the registers used in *that* mode.
373 *
374 * - This code must be as fast as possible.
375 *
376 * There are a few restrictions on the vectors:
377 * - the SWI vector cannot be called from *any* non-user mode
378 *
379 * - the FP emulator is *never* called from *any* non-user mode undefined
380 * instruction.
381 *
382 */
383
384 .text
385
386 .macro handle_irq
3871: mov r4, #IOC_BASE
388 ldrb r6, [r4, #0x24] @ get high priority first
389 adr r5, irq_prio_h
390 teq r6, #0
391 ldreqb r6, [r4, #0x14] @ get low priority
392 adreq r5, irq_prio_l
393
394 teq r6, #0 @ If an IRQ happened...
395 ldrneb r0, [r5, r6] @ get IRQ number
396 movne r1, sp @ get struct pt_regs
397 adrne lr, 1b @ Set return address to 1b
398 orrne lr, lr, #PSR_I_BIT | MODE_SVC26 @ (and force SVC mode)
399 bne asm_do_IRQ @ process IRQ (if asserted)
400 .endm
401
402
403/*
404 * Interrupt table (incorporates priority)
405 */
406 .macro irq_prio_table
407irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
408 .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
409 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
410 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
411 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
412 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
413 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
414 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
415 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
416 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
417 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
418 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
419 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
420 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
421 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
422 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
423irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
424 .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
425 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
426 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
427 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
428 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
429 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
430 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
431 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
432 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
433 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
434 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
435 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
436 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
437 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
438 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
439 .endm
440
441#if 1
442/*
443 * Uncomment these if you wish to get more debugging into about data aborts.
444 * FIXME - I bet we can find a way to encode these and keep performance.
445 */
446#define FAULT_CODE_LDRSTRPOST 0x80
447#define FAULT_CODE_LDRSTRPRE 0x40
448#define FAULT_CODE_LDRSTRREG 0x20
449#define FAULT_CODE_LDMSTM 0x10
450#define FAULT_CODE_LDCSTC 0x08
451#endif
452#define FAULT_CODE_PREFETCH 0x04
453#define FAULT_CODE_WRITE 0x02
454#define FAULT_CODE_FORCECOW 0x01
455
456/*=============================================================================
457 * Undefined FIQs
458 *-----------------------------------------------------------------------------
459 */
460_unexp_fiq: ldr sp, .LCfiq
461 mov r12, #IOC_BASE
462 strb r12, [r12, #0x38] @ Disable FIQ register
463 teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_SVC26
464 mov r0, r0
465 stmfd sp!, {r0 - r3, ip, lr}
466 adr r0, Lfiqmsg
467 bl printk
468 ldmfd sp!, {r0 - r3, ip, lr}
469 teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_FIQ26
470 mov r0, r0
471 movs pc, lr
472
473Lfiqmsg: .ascii "*** Unexpected FIQ\n\0"
474 .align
475
476.LCfiq: .word __temp_fiq
477.LCirq: .word __temp_irq
478
479/*=============================================================================
480 * Undefined instruction handler
481 *-----------------------------------------------------------------------------
482 * Handles floating point instructions
483 */
484vector_undefinstr:
485 tst lr, #MODE_SVC26 @ did we come from a non-user mode?
486 bne __und_svc @ yes - deal with it.
487/* Otherwise, fall through for the user-space (common) case. */
488 save_user_regs
489 zero_fp @ zero frame pointer
490 teqp pc, #PSR_I_BIT | MODE_SVC26 @ disable IRQs
491.Lbug_undef:
492 ldr r4, .LC2
493 ldr pc, [r4] @ Call FP module entry point
494/* FIXME - should we trap for a null pointer here? */
495
496/* The SVC mode case */
497__und_svc: save_svc_regs @ Non-user mode
498 mask_pc r0, lr
499 and r2, lr, #3
500 sub r0, r0, #4
501 mov r1, sp
502 bl do_undefinstr
503 restore_svc_regs
504
505/* We get here if the FP emulator doesnt handle the undef instr.
506 * If the insn WAS handled, the emulator jumps to ret_from_exception by itself/
507 */
508 .globl fpundefinstr
509fpundefinstr:
510 mov r0, lr
511 mov r1, sp
512 teqp pc, #MODE_SVC26
513 bl do_undefinstr
514 b ret_from_exception @ Normal FP exit
515
516#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
517 /* The FPE is always present */
518 .equ fpe_not_present, 0
519#else
520/* We get here if an undefined instruction happens and the floating
521 * point emulator is not present. If the offending instruction was
522 * a WFS, we just perform a normal return as if we had emulated the
523 * operation. This is a hack to allow some basic userland binaries
524 * to run so that the emulator module proper can be loaded. --philb
525 * FIXME - probably a broken useless hack...
526 */
527fpe_not_present:
528 adr r10, wfs_mask_data
529 ldmia r10, {r4, r5, r6, r7, r8}
530 ldr r10, [sp, #S_PC] @ Load PC
531 sub r10, r10, #4
532 mask_pc r10, r10
533 ldrt r10, [r10] @ get instruction
534 and r5, r10, r5
535 teq r5, r4 @ Is it WFS?
536 beq ret_from_exception
537 and r5, r10, r8
538 teq r5, r6 @ Is it LDF/STF on sp or fp?
539 teqne r5, r7
540 bne fpundefinstr
541 tst r10, #0x00200000 @ Does it have WB
542 beq ret_from_exception
543 and r4, r10, #255 @ get offset
544 and r6, r10, #0x000f0000
545 tst r10, #0x00800000 @ +/-
546 ldr r5, [sp, r6, lsr #14] @ Load reg
547 rsbeq r4, r4, #0
548 add r5, r5, r4, lsl #2
549 str r5, [sp, r6, lsr #14] @ Save reg
550 b ret_from_exception
551
552wfs_mask_data: .word 0x0e200110 @ WFS/RFS
553 .word 0x0fef0fff
554 .word 0x0d0d0100 @ LDF [sp]/STF [sp]
555 .word 0x0d0b0100 @ LDF [fp]/STF [fp]
556 .word 0x0f0f0f00
557#endif
558
559.LC2: .word fp_enter
560
561/*=============================================================================
562 * Prefetch abort handler
563 *-----------------------------------------------------------------------------
564 */
565#define DEBUG_UNDEF
566/* remember: lr = USR pc */
567vector_prefetch:
568 sub lr, lr, #4
569 tst lr, #MODE_SVC26
570 bne __pabt_invalid
571 save_user_regs
572 teqp pc, #MODE_SVC26 @ Enable IRQs...
573 mask_pc r0, lr @ Address of abort
574 mov r1, sp @ Tasks registers
575 bl do_PrefetchAbort
576 teq r0, #0 @ If non-zero, we believe this abort..
577 bne ret_from_exception
578#ifdef DEBUG_UNDEF
579 adr r0, t
580 bl printk
581#endif
582 ldr lr, [sp,#S_PC] @ FIXME program to test this on. I think its
583 b .Lbug_undef @ broken at the moment though!)
584
585__pabt_invalid: save_svc_regs
586 mov r0, sp @ Prefetch aborts are definitely *not*
587 mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant
588 and r2, lr, #3 @ recover from this problem.
589 b bad_mode
590
591#ifdef DEBUG_UNDEF
592t: .ascii "*** undef ***\r\n\0"
593 .align
594#endif
595
596/*=============================================================================
597 * Address exception handler
598 *-----------------------------------------------------------------------------
599 * These aren't too critical.
600 * (they're not supposed to happen).
601 * In order to debug the reason for address exceptions in non-user modes,
602 * we have to obtain all the registers so that we can see what's going on.
603 */
604
605vector_addrexcptn:
606 sub lr, lr, #8
607 tst lr, #3
608 bne Laddrexcptn_not_user
609 save_user_regs
610 teq pc, #MODE_SVC26
611 mask_pc r0, lr @ Point to instruction
612 mov r1, sp @ Point to registers
613 mov r2, #0x400
614 mov lr, pc
615 bl do_excpt
616 b ret_from_exception
617
618Laddrexcptn_not_user:
619 save_svc_regs
620 and r2, lr, #3
621 teq r2, #3
622 bne Laddrexcptn_illegal_mode
623 teqp pc, #MODE_SVC26
624 mask_pc r0, lr
625 mov r1, sp
626 orr r2, r2, #0x400
627 bl do_excpt
628 ldmia sp, {r0 - lr} @ I cant remember the reason I changed this...
629 add sp, sp, #15*4
630 movs pc, lr
631
632Laddrexcptn_illegal_mode:
633 mov r0, sp
634 str lr, [sp, #-4]!
635 orr r1, r2, #PSR_I_BIT | PSR_F_BIT
636 teqp r1, #0 @ change into mode (wont be user mode)
637 mov r0, r0
638 mov r1, r8 @ Any register from r8 - r14 can be banked
639 mov r2, r9
640 mov r3, r10
641 mov r4, r11
642 mov r5, r12
643 mov r6, r13
644 mov r7, r14
645 teqp pc, #PSR_F_BIT | MODE_SVC26 @ back to svc
646 mov r0, r0
647 stmfd sp!, {r1-r7}
648 ldmia r0, {r0-r7}
649 stmfd sp!, {r0-r7}
650 mov r0, sp
651 mov r1, #BAD_ADDREXCPTN
652 b bad_mode
653
654/*=============================================================================
655 * Interrupt (IRQ) handler
656 *-----------------------------------------------------------------------------
657 * Note: if the IRQ was taken whilst in user mode, then *no* kernel routine
658 * is running, so do not have to save svc lr.
659 *
660 * Entered in IRQ mode.
661 */
662
663vector_IRQ: ldr sp, .LCirq @ Setup some temporary stack
664 sub lr, lr, #4
665 str lr, [sp] @ push return address
666
667 tst lr, #3
668 bne __irq_non_usr
669
670__irq_usr: teqp pc, #PSR_I_BIT | MODE_SVC26 @ Enter SVC mode
671 mov r0, r0
672
673 ldr lr, .LCirq
674 ldr lr, [lr] @ Restore lr for jump back to USR
675
676 save_user_regs
677
678 handle_irq
679
680 mov why, #0
681 get_thread_info tsk
682 b ret_to_user
683
684@ Place the IRQ priority table here so that the handle_irq macros above
685@ and below here can access it.
686
687 irq_prio_table
688
689__irq_non_usr: teqp pc, #PSR_I_BIT | MODE_SVC26 @ Enter SVC mode
690 mov r0, r0
691
692 save_svc_regs_irq
693
694 and r2, lr, #3
695 teq r2, #3
696 bne __irq_invalid @ IRQ not from SVC mode
697
698 handle_irq
699
700 restore_svc_regs
701
702__irq_invalid: mov r0, sp
703 mov r1, #BAD_IRQ
704 b bad_mode
705
706/*=============================================================================
707 * Data abort handler code
708 *-----------------------------------------------------------------------------
709 *
710 * This handles both exceptions from user and SVC modes, computes the address
711 * range of the problem, and does any correction that is required. It then
712 * calls the kernel data abort routine.
713 *
714 * This is where I wish that the ARM would tell you which address aborted.
715 */
716
717vector_data: sub lr, lr, #8 @ Correct lr
718 tst lr, #3
719 bne Ldata_not_user
720 save_user_regs
721 teqp pc, #MODE_SVC26
722 mask_pc r0, lr
723 bl Ldata_do
724 b ret_from_exception
725
726Ldata_not_user:
727 save_svc_regs
728 and r2, lr, #3
729 teq r2, #3
730 bne Ldata_illegal_mode
731 tst lr, #PSR_I_BIT
732 teqeqp pc, #MODE_SVC26
733 mask_pc r0, lr
734 bl Ldata_do
735 restore_svc_regs
736
737Ldata_illegal_mode:
738 mov r0, sp
739 mov r1, #BAD_DATA
740 b bad_mode
741
742Ldata_do: mov r3, sp
743 ldr r4, [r0] @ Get instruction
744 mov r2, #0
745 tst r4, #1 << 20 @ Check to see if it is a write instruction
746 orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
747 mov r1, r4, lsr #22 @ Now branch to the relevent processing routine
748 and r1, r1, #15 << 2
749 add pc, pc, r1
750 movs pc, lr
751 b Ldata_unknown
752 b Ldata_unknown
753 b Ldata_unknown
754 b Ldata_unknown
755 b Ldata_ldrstr_post @ ldr rd, [rn], #m
756 b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal
757 b Ldata_ldrstr_post @ ldr rd, [rn], rm
758 b Ldata_ldrstr_regindex @ ldr rd, [rn, rm]
759 b Ldata_ldmstm @ ldm*a rn, <rlist>
760 b Ldata_ldmstm @ ldm*b rn, <rlist>
761 b Ldata_unknown
762 b Ldata_unknown
763 b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
764 b Ldata_ldcstc_pre @ ldc rd, [rn, #m]
765 b Ldata_unknown
766Ldata_unknown: @ Part of jumptable
767 mov r0, r1
768 mov r1, r4
769 mov r2, r3
770 b baddataabort
771
772Ldata_ldrstr_post:
773 mov r0, r4, lsr #14 @ Get Rn
774 and r0, r0, #15 << 2 @ Mask out reg.
775 teq r0, #15 << 2
776 ldr r0, [r3, r0] @ Get register
777 biceq r0, r0, #PCMASK
778 mov r1, r0
779#ifdef FAULT_CODE_LDRSTRPOST
780 orr r2, r2, #FAULT_CODE_LDRSTRPOST
781#endif
782 b do_DataAbort
783
784Ldata_ldrstr_numindex:
785 mov r0, r4, lsr #14 @ Get Rn
786 and r0, r0, #15 << 2 @ Mask out reg.
787 teq r0, #15 << 2
788 ldr r0, [r3, r0] @ Get register
789 mov r1, r4, lsl #20
790 biceq r0, r0, #PCMASK
791 tst r4, #1 << 23
792 addne r0, r0, r1, lsr #20
793 subeq r0, r0, r1, lsr #20
794 mov r1, r0
795#ifdef FAULT_CODE_LDRSTRPRE
796 orr r2, r2, #FAULT_CODE_LDRSTRPRE
797#endif
798 b do_DataAbort
799
800Ldata_ldrstr_regindex:
801 mov r0, r4, lsr #14 @ Get Rn
802 and r0, r0, #15 << 2 @ Mask out reg.
803 teq r0, #15 << 2
804 ldr r0, [r3, r0] @ Get register
805 and r7, r4, #15
806 biceq r0, r0, #PCMASK
807 teq r7, #15 @ Check for PC
808 ldr r7, [r3, r7, lsl #2] @ Get Rm
809 and r8, r4, #0x60 @ Get shift types
810 biceq r7, r7, #PCMASK
811 mov r9, r4, lsr #7 @ Get shift amount
812 and r9, r9, #31
813 teq r8, #0
814 moveq r7, r7, lsl r9
815 teq r8, #0x20 @ LSR shift
816 moveq r7, r7, lsr r9
817 teq r8, #0x40 @ ASR shift
818 moveq r7, r7, asr r9
819 teq r8, #0x60 @ ROR shift
820 moveq r7, r7, ror r9
821 tst r4, #1 << 23
822 addne r0, r0, r7
823 subeq r0, r0, r7 @ Apply correction
824 mov r1, r0
825#ifdef FAULT_CODE_LDRSTRREG
826 orr r2, r2, #FAULT_CODE_LDRSTRREG
827#endif
828 b do_DataAbort
829
830Ldata_ldmstm:
831 mov r7, #0x11
832 orr r7, r7, r7, lsl #8
833 and r0, r4, r7
834 and r1, r4, r7, lsl #1
835 add r0, r0, r1, lsr #1
836 and r1, r4, r7, lsl #2
837 add r0, r0, r1, lsr #2
838 and r1, r4, r7, lsl #3
839 add r0, r0, r1, lsr #3
840 add r0, r0, r0, lsr #8
841 add r0, r0, r0, lsr #4
842 and r7, r0, #15 @ r7 = no. of registers to transfer.
843 mov r5, r4, lsr #14 @ Get Rn
844 and r5, r5, #15 << 2
845 ldr r0, [r3, r5] @ Get reg
846 eor r6, r4, r4, lsl #2
847 tst r6, #1 << 23 @ Check inc/dec ^ writeback
848 rsbeq r7, r7, #0
849 add r7, r0, r7, lsl #2 @ Do correction (signed)
850 subne r1, r7, #1
851 subeq r1, r0, #1
852 moveq r0, r7
853 tst r4, #1 << 21 @ Check writeback
854 strne r7, [r3, r5]
855 eor r6, r4, r4, lsl #1
856 tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec
857 addeq r0, r0, #4
858 addeq r1, r1, #4
859 teq r5, #15*4 @ CHECK FOR PC
860 biceq r1, r1, #PCMASK
861 biceq r0, r0, #PCMASK
862#ifdef FAULT_CODE_LDMSTM
863 orr r2, r2, #FAULT_CODE_LDMSTM
864#endif
865 b do_DataAbort
866
867Ldata_ldcstc_pre:
868 mov r0, r4, lsr #14 @ Get Rn
869 and r0, r0, #15 << 2 @ Mask out reg.
870 teq r0, #15 << 2
871 ldr r0, [r3, r0] @ Get register
872 mov r1, r4, lsl #24 @ Get offset
873 biceq r0, r0, #PCMASK
874 tst r4, #1 << 23
875 addne r0, r0, r1, lsr #24
876 subeq r0, r0, r1, lsr #24
877 mov r1, r0
878#ifdef FAULT_CODE_LDCSTC
879 orr r2, r2, #FAULT_CODE_LDCSTC
880#endif
881 b do_DataAbort
882
883
884/*
885 * This is the return code to user mode for abort handlers
886 */
887ENTRY(ret_from_exception)
888 get_thread_info tsk
889 mov why, #0
890 b ret_to_user
891
892 .data
893ENTRY(fp_enter)
894 .word fpe_not_present
895 .text
896/*
897 * Register switch for older 26-bit only ARMs
898 */
899ENTRY(__switch_to)
900 add r0, r0, #TI_CPU_SAVE
901 stmia r0, {r4 - sl, fp, sp, lr}
902 add r1, r1, #TI_CPU_SAVE
903 ldmia r1, {r4 - sl, fp, sp, pc}^
904
905/*
906 *=============================================================================
907 * Low-level interface code
908 *-----------------------------------------------------------------------------
909 * Trap initialisation
910 *-----------------------------------------------------------------------------
911 *
912 * Note - FIQ code has changed. The default is a couple of words in 0x1c, 0x20
913 * that call _unexp_fiq. Nowever, we now copy the FIQ routine to 0x1c (removes
914 * some excess cycles).
915 *
916 * What we need to put into 0-0x1c are branches to branch to the kernel.
917 */
918
919 .section ".init.text",#alloc,#execinstr
920
921.Ljump_addresses:
922 swi SYS_ERROR0
923 .word vector_undefinstr - 12
924 .word vector_swi - 16
925 .word vector_prefetch - 20
926 .word vector_data - 24
927 .word vector_addrexcptn - 28
928 .word vector_IRQ - 32
929 .word _unexp_fiq - 36
930 b . + 8
931/*
932 * initialise the trap system
933 */
934ENTRY(__trap_init)
935 stmfd sp!, {r4 - r7, lr}
936 adr r1, .Ljump_addresses
937 ldmia r1, {r1 - r7, ip, lr}
938 orr r2, lr, r2, lsr #2
939 orr r3, lr, r3, lsr #2
940 orr r4, lr, r4, lsr #2
941 orr r5, lr, r5, lsr #2
942 orr r6, lr, r6, lsr #2
943 orr r7, lr, r7, lsr #2
944 orr ip, lr, ip, lsr #2
945 mov r0, #0
946 stmia r0, {r1 - r7, ip}
947 ldmfd sp!, {r4 - r7, pc}^
948
949 .bss
950__temp_irq: .space 4 @ saved lr_irq
951__temp_fiq: .space 128
diff --git a/arch/arm26/kernel/fiq.c b/arch/arm26/kernel/fiq.c
deleted file mode 100644
index c4776c96be6b..000000000000
--- a/arch/arm26/kernel/fiq.c
+++ /dev/null
@@ -1,201 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/fiq.c
3 *
4 * Copyright (C) 1998 Russell King
5 * Copyright (C) 1998, 1999 Phil Blundell
6 * Copyright (C) 2003 Ian Molton
7 *
8 * FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
9 *
10 * FIQ support re-written by Russell King to be more generic
11 *
12 * We now properly support a method by which the FIQ handlers can
13 * be stacked onto the vector. We still do not support sharing
14 * the FIQ vector itself.
15 *
16 * Operation is as follows:
17 * 1. Owner A claims FIQ:
18 * - default_fiq relinquishes control.
19 * 2. Owner A:
20 * - inserts code.
21 * - sets any registers,
22 * - enables FIQ.
23 * 3. Owner B claims FIQ:
24 * - if owner A has a relinquish function.
25 * - disable FIQs.
26 * - saves any registers.
27 * - returns zero.
28 * 4. Owner B:
29 * - inserts code.
30 * - sets any registers,
31 * - enables FIQ.
32 * 5. Owner B releases FIQ:
33 * - Owner A is asked to reacquire FIQ:
34 * - inserts code.
35 * - restores saved registers.
36 * - enables FIQ.
37 * 6. Goto 3
38 */
39#include <linux/module.h>
40#include <linux/mm.h>
41#include <linux/mman.h>
42#include <linux/init.h>
43#include <linux/seq_file.h>
44
45#include <asm/fiq.h>
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/pgalloc.h>
49#include <asm/system.h>
50#include <asm/uaccess.h>
51
52#define FIQ_VECTOR (vectors_base() + 0x1c)
53
54static unsigned long no_fiq_insn;
55
56#define unprotect_page_0()
57#define protect_page_0()
58
59/* Default reacquire function
60 * - we always relinquish FIQ control
61 * - we always reacquire FIQ control
62 */
63static int fiq_def_op(void *ref, int relinquish)
64{
65 if (!relinquish) {
66 unprotect_page_0();
67 *(unsigned long *)FIQ_VECTOR = no_fiq_insn;
68 protect_page_0();
69 }
70
71 return 0;
72}
73
74static struct fiq_handler default_owner = {
75 .name = "default",
76 .fiq_op = fiq_def_op,
77};
78
79static struct fiq_handler *current_fiq = &default_owner;
80
81int show_fiq_list(struct seq_file *p, void *v)
82{
83 if (current_fiq != &default_owner)
84 seq_printf(p, "FIQ: %s\n", current_fiq->name);
85
86 return 0;
87}
88
89void set_fiq_handler(void *start, unsigned int length)
90{
91 unprotect_page_0();
92
93 memcpy((void *)FIQ_VECTOR, start, length);
94
95 protect_page_0();
96}
97
98/*
99 * Taking an interrupt in FIQ mode is death, so both these functions
100 * disable irqs for the duration.
101 */
102void set_fiq_regs(struct pt_regs *regs)
103{
104 register unsigned long tmp, tmp2;
105 __asm__ volatile (
106 "mov %0, pc \n"
107 "bic %1, %0, #0x3 \n"
108 "orr %1, %1, %3 \n"
109 "teqp %1, #0 @ select FIQ mode \n"
110 "mov r0, r0 \n"
111 "ldmia %2, {r8 - r14} \n"
112 "teqp %0, #0 @ return to SVC mode \n"
113 "mov r0, r0 "
114 : "=&r" (tmp), "=&r" (tmp2)
115 : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
116 /* These registers aren't modified by the above code in a way
117 visible to the compiler, but we mark them as clobbers anyway
118 so that GCC won't put any of the input or output operands in
119 them. */
120 : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
121}
122
123void get_fiq_regs(struct pt_regs *regs)
124{
125 register unsigned long tmp, tmp2;
126 __asm__ volatile (
127 "mov %0, pc \n"
128 "bic %1, %0, #0x3 \n"
129 "orr %1, %1, %3 \n"
130 "teqp %1, #0 @ select FIQ mode \n"
131 "mov r0, r0 \n"
132 "stmia %2, {r8 - r14} \n"
133 "teqp %0, #0 @ return to SVC mode \n"
134 "mov r0, r0 "
135 : "=&r" (tmp), "=&r" (tmp2)
136 : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
137 /* These registers aren't modified by the above code in a way
138 visible to the compiler, but we mark them as clobbers anyway
139 so that GCC won't put any of the input or output operands in
140 them. */
141 : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
142}
143
144int claim_fiq(struct fiq_handler *f)
145{
146 int ret = 0;
147
148 if (current_fiq) {
149 ret = -EBUSY;
150
151 if (current_fiq->fiq_op != NULL)
152 ret = current_fiq->fiq_op(current_fiq->dev_id, 1);
153 }
154
155 if (!ret) {
156 f->next = current_fiq;
157 current_fiq = f;
158 }
159
160 return ret;
161}
162
163void release_fiq(struct fiq_handler *f)
164{
165 if (current_fiq != f) {
166 printk(KERN_ERR "%s FIQ trying to release %s FIQ\n",
167 f->name, current_fiq->name);
168#ifdef CONFIG_DEBUG_ERRORS
169 __backtrace();
170#endif
171 return;
172 }
173
174 do
175 current_fiq = current_fiq->next;
176 while (current_fiq->fiq_op(current_fiq->dev_id, 0));
177}
178
179void enable_fiq(int fiq)
180{
181 enable_irq(fiq + FIQ_START);
182}
183
184void disable_fiq(int fiq)
185{
186 disable_irq(fiq + FIQ_START);
187}
188
189EXPORT_SYMBOL(set_fiq_handler);
190EXPORT_SYMBOL(set_fiq_regs);
191EXPORT_SYMBOL(get_fiq_regs);
192EXPORT_SYMBOL(claim_fiq);
193EXPORT_SYMBOL(release_fiq);
194EXPORT_SYMBOL(enable_fiq);
195EXPORT_SYMBOL(disable_fiq);
196
197void __init init_FIQ(void)
198{
199 no_fiq_insn = *(unsigned long *)FIQ_VECTOR;
200 set_fs(get_fs());
201}
diff --git a/arch/arm26/kernel/head.S b/arch/arm26/kernel/head.S
deleted file mode 100644
index 93575e0e58fe..000000000000
--- a/arch/arm26/kernel/head.S
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/head.S
3 *
4 * Copyright (C) 1994-2000 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 26-bit kernel startup code
12 */
13#include <linux/linkage.h>
14#include <asm/mach-types.h>
15
16 .globl swapper_pg_dir
17 .equ swapper_pg_dir, 0x0207d000
18
19/*
20 * Entry point.
21 */
22 .section ".init.text",#alloc,#execinstr
23ENTRY(stext)
24
25__entry:
26 cmp pc, #0x02000000
27 ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000
28 teq r0, #0 @ Check for old calling method
29 blne oldparams @ Move page if old
30
31 adr r0, LC0
32 ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values)
33
34 mov r0, #0 @ Clear BSS
351: cmp r2, r3
36 strcc r0, [r2], #4
37 bcc 1b
38
39 bl detect_proc_type
40 str r0, [r4]
41 bl detect_arch_type
42 str r0, [r5]
43
44#ifdef CONFIG_XIP_KERNEL
45 ldr r3, ETEXT @ data section copy
46 ldr r4, SDATA
47 ldr r5, EDATA
481:
49 ldr r6, [r3], #4
50 str r6, [r4], #4
51 cmp r4, r5
52 blt 1b
53#endif
54 mov fp, #0
55 b start_kernel
56
57LC0: .word _stext
58 .word __bss_start @ r2
59 .word _end @ r3
60 .word processor_id @ r4
61 .word __machine_arch_type @ r5
62 .word init_thread_union+8192 @ sp
63#ifdef CONFIG_XIP_KERNEL
64ETEXT: .word _endtext
65SDATA: .word _sdata
66EDATA: .word __bss_start
67#endif
68
69arm2_id: .long 0x41560200 @ ARM2 and 250 dont have a CPUID
70arm250_id: .long 0x41560250 @ So we create some after probing for them
71 .align
72
73oldparams: mov r4, #0x02000000
74 add r3, r4, #0x00080000
75 add r4, r4, #0x0007c000
761: ldmia r0!, {r5 - r12}
77 stmia r4!, {r5 - r12}
78 cmp r4, r3
79 blt 1b
80 mov pc, lr
81
82/*
83 * We need some way to automatically detect the difference between
84 * these two machines. Unfortunately, it is not possible to detect
85 * the presence of the SuperIO chip, because that will hang the old
86 * Archimedes machines solid.
87 */
88/* DAG: Outdated, these have been combined !!!!!!! */
89detect_arch_type:
90#if defined(CONFIG_ARCH_ARC)
91 mov r0, #MACH_TYPE_ARCHIMEDES
92#elif defined(CONFIG_ARCH_A5K)
93 mov r0, #MACH_TYPE_A5K
94#endif
95 mov pc, lr
96
97detect_proc_type:
98 mov ip, lr
99 mov r2, #0xea000000 @ Point undef instr to continuation
100 adr r0, continue - 12
101 orr r0, r2, r0, lsr #2
102 mov r1, #0
103 str r0, [r1, #4]
104 ldr r0, arm2_id
105 swp r2, r2, [r1] @ check for swp (ARM2 cant)
106 ldr r0, arm250_id
107 mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 cant)
108 mov r0, r3
109continue: mov r2, #0xeb000000 @ Make undef vector loop
110 sub r2, r2, #2
111 str r2, [r1, #4]
112 mov pc, ip
diff --git a/arch/arm26/kernel/init_task.c b/arch/arm26/kernel/init_task.c
deleted file mode 100644
index 4191565b889b..000000000000
--- a/arch/arm26/kernel/init_task.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/init_task.c
3 *
4 * Copyright (C) 2003 Ian Molton
5 *
6 */
7#include <linux/mm.h>
8#include <linux/module.h>
9#include <linux/fs.h>
10#include <linux/sched.h>
11#include <linux/init.h>
12#include <linux/init_task.h>
13#include <linux/mqueue.h>
14
15#include <asm/uaccess.h>
16#include <asm/pgtable.h>
17
18static struct fs_struct init_fs = INIT_FS;
19static struct files_struct init_files = INIT_FILES;
20static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
21static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
22struct mm_struct init_mm = INIT_MM(init_mm);
23
24EXPORT_SYMBOL(init_mm);
25
26/*
27 * Initial thread structure.
28 *
29 * We need to make sure that this is 8192-byte aligned due to the
30 * way process stacks are handled. This is done by making sure
31 * the linker maps this in the .text segment right after head.S,
32 * and making the linker scripts ensure the proper alignment.
33 *
34 * FIXME - should this be 32K alignment on arm26?
35 *
36 * The things we do for performance...
37 */
38union thread_union init_thread_union
39 __attribute__((__section__(".init.task"))) =
40 { INIT_THREAD_INFO(init_task) };
41
42/*
43 * Initial task structure.
44 *
45 * All other task structs will be allocated on slabs in fork.c
46 */
47struct task_struct init_task = INIT_TASK(init_task);
48
49EXPORT_SYMBOL(init_task);
diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c
deleted file mode 100644
index 2ffe695b062e..000000000000
--- a/arch/arm26/kernel/irq.c
+++ /dev/null
@@ -1,722 +0,0 @@
1/*
2 * linux/arch/arm/kernel/irq.c
3 *
4 * Copyright (C) 1992 Linus Torvalds
5 * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
6 * 'Borrowed' for ARM26 and (C) 2003 Ian Molton.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This file contains the code used by various IRQ handling routines:
13 * asking for different IRQ's should be done through these routines
14 * instead of just grabbing them. Thus setups with different IRQ numbers
15 * shouldn't result in any weird surprises, and installing new handlers
16 * should be easier.
17 *
18 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
19 * Naturally it's not a 1:1 relation, but there are similarities.
20 */
21#include <linux/module.h>
22#include <linux/ptrace.h>
23#include <linux/kernel_stat.h>
24#include <linux/signal.h>
25#include <linux/sched.h>
26#include <linux/ioport.h>
27#include <linux/interrupt.h>
28#include <linux/slab.h>
29#include <linux/random.h>
30#include <linux/smp.h>
31#include <linux/init.h>
32#include <linux/seq_file.h>
33#include <linux/errno.h>
34
35#include <asm/irq.h>
36#include <asm/system.h>
37#include <asm/irqchip.h>
38
39//FIXME - this ought to be in a header IMO
40void __init arc_init_irq(void);
41
42/*
43 * Maximum IRQ count. Currently, this is arbitary. However, it should
44 * not be set too low to prevent false triggering. Conversely, if it
45 * is set too high, then you could miss a stuck IRQ.
46 *
47 * FIXME Maybe we ought to set a timer and re-enable the IRQ at a later time?
48 */
49#define MAX_IRQ_CNT 100000
50
51static volatile unsigned long irq_err_count;
52static DEFINE_SPINLOCK(irq_controller_lock);
53
54struct irqdesc irq_desc[NR_IRQS];
55
56/*
57 * Dummy mask/unmask handler
58 */
59void dummy_mask_unmask_irq(unsigned int irq)
60{
61}
62
63void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
64{
65 irq_err_count += 1;
66 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
67}
68
69static struct irqchip bad_chip = {
70 .ack = dummy_mask_unmask_irq,
71 .mask = dummy_mask_unmask_irq,
72 .unmask = dummy_mask_unmask_irq,
73};
74
75static struct irqdesc bad_irq_desc = {
76 .chip = &bad_chip,
77 .handle = do_bad_IRQ,
78 .depth = 1,
79};
80
81/**
82 * disable_irq - disable an irq and wait for completion
83 * @irq: Interrupt to disable
84 *
85 * Disable the selected interrupt line. We do this lazily.
86 *
87 * This function may be called from IRQ context.
88 */
89void disable_irq(unsigned int irq)
90{
91 struct irqdesc *desc = irq_desc + irq;
92 unsigned long flags;
93 spin_lock_irqsave(&irq_controller_lock, flags);
94 if (!desc->depth++)
95 desc->enabled = 0;
96 spin_unlock_irqrestore(&irq_controller_lock, flags);
97}
98EXPORT_SYMBOL(disable_irq);
99
100void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
101
102EXPORT_SYMBOL(disable_irq_nosync);
103
104/**
105 * enable_irq - enable interrupt handling on an irq
106 * @irq: Interrupt to enable
107 *
108 * Re-enables the processing of interrupts on this IRQ line.
109 * Note that this may call the interrupt handler, so you may
110 * get unexpected results if you hold IRQs disabled.
111 *
112 * This function may be called from IRQ context.
113 */
114void enable_irq(unsigned int irq)
115{
116 struct irqdesc *desc = irq_desc + irq;
117 unsigned long flags;
118 int pending = 0;
119
120 spin_lock_irqsave(&irq_controller_lock, flags);
121 if (unlikely(!desc->depth)) {
122 printk("enable_irq(%u) unbalanced from %p\n", irq,
123 __builtin_return_address(0)); //FIXME bum addresses reported - why?
124 } else if (!--desc->depth) {
125 desc->probing = 0;
126 desc->enabled = 1;
127 desc->chip->unmask(irq);
128 pending = desc->pending;
129 desc->pending = 0;
130 /*
131 * If the interrupt was waiting to be processed,
132 * retrigger it.
133 */
134 if (pending)
135 desc->chip->rerun(irq);
136 }
137 spin_unlock_irqrestore(&irq_controller_lock, flags);
138}
139EXPORT_SYMBOL(enable_irq);
140
141int show_interrupts(struct seq_file *p, void *v)
142{
143 int i = *(loff_t *) v;
144 struct irqaction * action;
145
146 if (i < NR_IRQS) {
147 action = irq_desc[i].action;
148 if (!action)
149 goto out;
150 seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
151 seq_printf(p, " %s", action->name);
152 for (action = action->next; action; action = action->next) {
153 seq_printf(p, ", %s", action->name);
154 }
155 seq_putc(p, '\n');
156 } else if (i == NR_IRQS) {
157 show_fiq_list(p, v);
158 seq_printf(p, "Err: %10lu\n", irq_err_count);
159 }
160out:
161 return 0;
162}
163
164/*
165 * IRQ lock detection.
166 *
167 * Hopefully, this should get us out of a few locked situations.
168 * However, it may take a while for this to happen, since we need
169 * a large number if IRQs to appear in the same jiffie with the
170 * same instruction pointer (or within 2 instructions).
171 */
172static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
173{
174 unsigned long instr_ptr = instruction_pointer(regs);
175
176 if (desc->lck_jif == jiffies &&
177 desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
178 desc->lck_cnt += 1;
179
180 if (desc->lck_cnt > MAX_IRQ_CNT) {
181 printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
182 return 1;
183 }
184 } else {
185 desc->lck_cnt = 0;
186 desc->lck_pc = instruction_pointer(regs);
187 desc->lck_jif = jiffies;
188 }
189 return 0;
190}
191
192static void
193__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
194{
195 unsigned int status;
196 int ret;
197
198 spin_unlock(&irq_controller_lock);
199 if (!(action->flags & IRQF_DISABLED))
200 local_irq_enable();
201
202 status = 0;
203 do {
204 ret = action->handler(irq, action->dev_id, regs);
205 if (ret == IRQ_HANDLED)
206 status |= action->flags;
207 action = action->next;
208 } while (action);
209
210 if (status & IRQF_SAMPLE_RANDOM)
211 add_interrupt_randomness(irq);
212
213 spin_lock_irq(&irq_controller_lock);
214}
215
216/*
217 * This is for software-decoded IRQs. The caller is expected to
218 * handle the ack, clear, mask and unmask issues.
219 */
220void
221do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
222{
223 struct irqaction *action;
224 const int cpu = smp_processor_id();
225
226 desc->triggered = 1;
227
228 kstat_cpu(cpu).irqs[irq]++;
229
230 action = desc->action;
231 if (action)
232 __do_irq(irq, desc->action, regs);
233}
234
235/*
236 * Most edge-triggered IRQ implementations seem to take a broken
237 * approach to this. Hence the complexity.
238 */
239void
240do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
241{
242 const int cpu = smp_processor_id();
243
244 desc->triggered = 1;
245
246 /*
247 * If we're currently running this IRQ, or its disabled,
248 * we shouldn't process the IRQ. Instead, turn on the
249 * hardware masks.
250 */
251 if (unlikely(desc->running || !desc->enabled))
252 goto running;
253
254 /*
255 * Acknowledge and clear the IRQ, but don't mask it.
256 */
257 desc->chip->ack(irq);
258
259 /*
260 * Mark the IRQ currently in progress.
261 */
262 desc->running = 1;
263
264 kstat_cpu(cpu).irqs[irq]++;
265
266 do {
267 struct irqaction *action;
268
269 action = desc->action;
270 if (!action)
271 break;
272
273 if (desc->pending && desc->enabled) {
274 desc->pending = 0;
275 desc->chip->unmask(irq);
276 }
277
278 __do_irq(irq, action, regs);
279 } while (desc->pending);
280
281 desc->running = 0;
282
283 /*
284 * If we were disabled or freed, shut down the handler.
285 */
286 if (likely(desc->action && !check_irq_lock(desc, irq, regs)))
287 return;
288
289 running:
290 /*
291 * We got another IRQ while this one was masked or
292 * currently running. Delay it.
293 */
294 desc->pending = 1;
295 desc->chip->mask(irq);
296 desc->chip->ack(irq);
297}
298
299/*
300 * Level-based IRQ handler. Nice and simple.
301 */
302void
303do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
304{
305 struct irqaction *action;
306 const int cpu = smp_processor_id();
307
308 desc->triggered = 1;
309
310 /*
311 * Acknowledge, clear _AND_ disable the interrupt.
312 */
313 desc->chip->ack(irq);
314
315 if (likely(desc->enabled)) {
316 kstat_cpu(cpu).irqs[irq]++;
317
318 /*
319 * Return with this interrupt masked if no action
320 */
321 action = desc->action;
322 if (action) {
323 __do_irq(irq, desc->action, regs);
324
325 if (likely(desc->enabled &&
326 !check_irq_lock(desc, irq, regs)))
327 desc->chip->unmask(irq);
328 }
329 }
330}
331
332/*
333 * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
334 * come via this function. Instead, they should provide their
335 * own 'handler'
336 */
337asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
338{
339 struct irqdesc *desc = irq_desc + irq;
340
341 /*
342 * Some hardware gives randomly wrong interrupts. Rather
343 * than crashing, do something sensible.
344 */
345 if (irq >= NR_IRQS)
346 desc = &bad_irq_desc;
347
348 irq_enter();
349 spin_lock(&irq_controller_lock);
350 desc->handle(irq, desc, regs);
351 spin_unlock(&irq_controller_lock);
352 irq_exit();
353}
354
355void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained)
356{
357 struct irqdesc *desc;
358 unsigned long flags;
359
360 if (irq >= NR_IRQS) {
361 printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
362 return;
363 }
364
365 if (handle == NULL)
366 handle = do_bad_IRQ;
367
368 desc = irq_desc + irq;
369
370 if (is_chained && desc->chip == &bad_chip)
371 printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
372
373 spin_lock_irqsave(&irq_controller_lock, flags);
374 if (handle == do_bad_IRQ) {
375 desc->chip->mask(irq);
376 desc->chip->ack(irq);
377 desc->depth = 1;
378 desc->enabled = 0;
379 }
380 desc->handle = handle;
381 if (handle != do_bad_IRQ && is_chained) {
382 desc->valid = 0;
383 desc->probe_ok = 0;
384 desc->depth = 0;
385 desc->chip->unmask(irq);
386 }
387 spin_unlock_irqrestore(&irq_controller_lock, flags);
388}
389
390void set_irq_chip(unsigned int irq, struct irqchip *chip)
391{
392 struct irqdesc *desc;
393 unsigned long flags;
394
395 if (irq >= NR_IRQS) {
396 printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
397 return;
398 }
399
400 if (chip == NULL)
401 chip = &bad_chip;
402
403 desc = irq_desc + irq;
404 spin_lock_irqsave(&irq_controller_lock, flags);
405 desc->chip = chip;
406 spin_unlock_irqrestore(&irq_controller_lock, flags);
407}
408
409int set_irq_type(unsigned int irq, unsigned int type)
410{
411 struct irqdesc *desc;
412 unsigned long flags;
413 int ret = -ENXIO;
414
415 if (irq >= NR_IRQS) {
416 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
417 return -ENODEV;
418 }
419
420 desc = irq_desc + irq;
421 if (desc->chip->type) {
422 spin_lock_irqsave(&irq_controller_lock, flags);
423 ret = desc->chip->type(irq, type);
424 spin_unlock_irqrestore(&irq_controller_lock, flags);
425 }
426
427 return ret;
428}
429
430void set_irq_flags(unsigned int irq, unsigned int iflags)
431{
432 struct irqdesc *desc;
433 unsigned long flags;
434
435 if (irq >= NR_IRQS) {
436 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
437 return;
438 }
439
440 desc = irq_desc + irq;
441 spin_lock_irqsave(&irq_controller_lock, flags);
442 desc->valid = (iflags & IRQF_VALID) != 0;
443 desc->probe_ok = (iflags & IRQF_PROBE) != 0;
444 desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
445 spin_unlock_irqrestore(&irq_controller_lock, flags);
446}
447
448int setup_irq(unsigned int irq, struct irqaction *new)
449{
450 int shared = 0;
451 struct irqaction *old, **p;
452 unsigned long flags;
453 struct irqdesc *desc;
454
455 /*
456 * Some drivers like serial.c use request_irq() heavily,
457 * so we have to be careful not to interfere with a
458 * running system.
459 */
460 if (new->flags & IRQF_SAMPLE_RANDOM) {
461 /*
462 * This function might sleep, we want to call it first,
463 * outside of the atomic block.
464 * Yes, this might clear the entropy pool if the wrong
465 * driver is attempted to be loaded, without actually
466 * installing a new handler, but is this really a problem,
467 * only the sysadmin is able to do this.
468 */
469 rand_initialize_irq(irq);
470 }
471
472 /*
473 * The following block of code has to be executed atomically
474 */
475 desc = irq_desc + irq;
476 spin_lock_irqsave(&irq_controller_lock, flags);
477 p = &desc->action;
478 if ((old = *p) != NULL) {
479 /* Can't share interrupts unless both agree to */
480 if (!(old->flags & new->flags & IRQF_SHARED)) {
481 spin_unlock_irqrestore(&irq_controller_lock, flags);
482 return -EBUSY;
483 }
484
485 /* add new interrupt at end of irq queue */
486 do {
487 p = &old->next;
488 old = *p;
489 } while (old);
490 shared = 1;
491 }
492
493 *p = new;
494
495 if (!shared) {
496 desc->probing = 0;
497 desc->running = 0;
498 desc->pending = 0;
499 desc->depth = 1;
500 if (!desc->noautoenable) {
501 desc->depth = 0;
502 desc->enabled = 1;
503 desc->chip->unmask(irq);
504 }
505 }
506
507 spin_unlock_irqrestore(&irq_controller_lock, flags);
508 return 0;
509}
510
511/**
512 * request_irq - allocate an interrupt line
513 * @irq: Interrupt line to allocate
514 * @handler: Function to be called when the IRQ occurs
515 * @irqflags: Interrupt type flags
516 * @devname: An ascii name for the claiming device
517 * @dev_id: A cookie passed back to the handler function
518 *
519 * This call allocates interrupt resources and enables the
520 * interrupt line and IRQ handling. From the point this
521 * call is made your handler function may be invoked. Since
522 * your handler function must clear any interrupt the board
523 * raises, you must take care both to initialise your hardware
524 * and to set up the interrupt handler in the right order.
525 *
526 * Dev_id must be globally unique. Normally the address of the
527 * device data structure is used as the cookie. Since the handler
528 * receives this value it makes sense to use it.
529 *
530 * If your interrupt is shared you must pass a non NULL dev_id
531 * as this is required when freeing the interrupt.
532 *
533 * Flags:
534 *
535 * IRQF_SHARED Interrupt is shared
536 *
537 * IRQF_DISABLED Disable local interrupts while processing
538 *
539 * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
540 *
541 */
542
543//FIXME - handler used to return void - whats the significance of the change?
544int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
545 unsigned long irq_flags, const char * devname, void *dev_id)
546{
547 unsigned long retval;
548 struct irqaction *action;
549
550 if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
551 (irq_flags & IRQF_SHARED && !dev_id))
552 return -EINVAL;
553
554 action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
555 if (!action)
556 return -ENOMEM;
557
558 action->handler = handler;
559 action->flags = irq_flags;
560 cpus_clear(action->mask);
561 action->name = devname;
562 action->next = NULL;
563 action->dev_id = dev_id;
564
565 retval = setup_irq(irq, action);
566
567 if (retval)
568 kfree(action);
569 return retval;
570}
571
572EXPORT_SYMBOL(request_irq);
573
574/**
575 * free_irq - free an interrupt
576 * @irq: Interrupt line to free
577 * @dev_id: Device identity to free
578 *
579 * Remove an interrupt handler. The handler is removed and if the
580 * interrupt line is no longer in use by any driver it is disabled.
581 * On a shared IRQ the caller must ensure the interrupt is disabled
582 * on the card it drives before calling this function.
583 *
584 * This function may be called from interrupt context.
585 */
586void free_irq(unsigned int irq, void *dev_id)
587{
588 struct irqaction * action, **p;
589 unsigned long flags;
590
591 if (irq >= NR_IRQS || !irq_desc[irq].valid) {
592 printk(KERN_ERR "Trying to free IRQ%d\n",irq);
593#ifdef CONFIG_DEBUG_ERRORS
594 __backtrace();
595#endif
596 return;
597 }
598
599 spin_lock_irqsave(&irq_controller_lock, flags);
600 for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
601 if (action->dev_id != dev_id)
602 continue;
603
604 /* Found it - now free it */
605 *p = action->next;
606 kfree(action);
607 goto out;
608 }
609 printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
610#ifdef CONFIG_DEBUG_ERRORS
611 __backtrace();
612#endif
613out:
614 spin_unlock_irqrestore(&irq_controller_lock, flags);
615}
616
617EXPORT_SYMBOL(free_irq);
618
619/* Start the interrupt probing. Unlike other architectures,
620 * we don't return a mask of interrupts from probe_irq_on,
621 * but return the number of interrupts enabled for the probe.
622 * The interrupts which have been enabled for probing is
623 * instead recorded in the irq_desc structure.
624 */
625unsigned long probe_irq_on(void)
626{
627 unsigned int i, irqs = 0;
628 unsigned long delay;
629
630 /*
631 * first snaffle up any unassigned but
632 * probe-able interrupts
633 */
634 spin_lock_irq(&irq_controller_lock);
635 for (i = 0; i < NR_IRQS; i++) {
636 if (!irq_desc[i].probe_ok || irq_desc[i].action)
637 continue;
638
639 irq_desc[i].probing = 1;
640 irq_desc[i].triggered = 0;
641 if (irq_desc[i].chip->type)
642 irq_desc[i].chip->type(i, IRQT_PROBE);
643 irq_desc[i].chip->unmask(i);
644 irqs += 1;
645 }
646 spin_unlock_irq(&irq_controller_lock);
647
648 /*
649 * wait for spurious interrupts to mask themselves out again
650 */
651 for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
652 /* min 100ms delay */;
653
654 /*
655 * now filter out any obviously spurious interrupts
656 */
657 spin_lock_irq(&irq_controller_lock);
658 for (i = 0; i < NR_IRQS; i++) {
659 if (irq_desc[i].probing && irq_desc[i].triggered) {
660 irq_desc[i].probing = 0;
661 irqs -= 1;
662 }
663 }
664 spin_unlock_irq(&irq_controller_lock);
665
666 return irqs;
667}
668
669EXPORT_SYMBOL(probe_irq_on);
670
671/*
672 * Possible return values:
673 * >= 0 - interrupt number
674 * -1 - no interrupt/many interrupts
675 */
676int probe_irq_off(unsigned long irqs)
677{
678 unsigned int i;
679 int irq_found = NO_IRQ;
680
681 /*
682 * look at the interrupts, and find exactly one
683 * that we were probing has been triggered
684 */
685 spin_lock_irq(&irq_controller_lock);
686 for (i = 0; i < NR_IRQS; i++) {
687 if (irq_desc[i].probing &&
688 irq_desc[i].triggered) {
689 if (irq_found != NO_IRQ) {
690 irq_found = NO_IRQ;
691 goto out;
692 }
693 irq_found = i;
694 }
695 }
696
697 if (irq_found == -1)
698 irq_found = NO_IRQ;
699out:
700 spin_unlock_irq(&irq_controller_lock);
701
702 return irq_found;
703}
704
705EXPORT_SYMBOL(probe_irq_off);
706
707void __init init_irq_proc(void)
708{
709}
710
711void __init init_IRQ(void)
712{
713 struct irqdesc *desc;
714 extern void init_dma(void);
715 int irq;
716
717 for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++)
718 *desc = bad_irq_desc;
719
720 arc_init_irq();
721 init_dma();
722}
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
deleted file mode 100644
index dcd81e62ff4e..000000000000
--- a/arch/arm26/kernel/process.c
+++ /dev/null
@@ -1,392 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/process.c
3 *
4 * Copyright (C) 2003 Ian Molton - adapted for ARM26
5 * Copyright (C) 1996-2000 Russell King - Converted to ARM.
6 * Origional Copyright (C) 1995 Linus Torvalds
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <stdarg.h>
13
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/stddef.h>
19#include <linux/unistd.h>
20#include <linux/ptrace.h>
21#include <linux/slab.h>
22#include <linux/user.h>
23#include <linux/a.out.h>
24#include <linux/delay.h>
25#include <linux/reboot.h>
26#include <linux/interrupt.h>
27#include <linux/init.h>
28
29#include <asm/system.h>
30#include <asm/io.h>
31#include <asm/leds.h>
32#include <asm/processor.h>
33#include <asm/uaccess.h>
34
35extern const char *processor_modes[];
36extern void setup_mm_for_reboot(char mode);
37
38static volatile int hlt_counter;
39
40void disable_hlt(void)
41{
42 hlt_counter++;
43}
44
45EXPORT_SYMBOL(disable_hlt);
46
47void enable_hlt(void)
48{
49 hlt_counter--;
50}
51
52EXPORT_SYMBOL(enable_hlt);
53
54static int __init nohlt_setup(char *__unused)
55{
56 hlt_counter = 1;
57 return 1;
58}
59
60static int __init hlt_setup(char *__unused)
61{
62 hlt_counter = 0;
63 return 1;
64}
65
66__setup("nohlt", nohlt_setup);
67__setup("hlt", hlt_setup);
68
69/*
70 * This is our default idle handler. We need to disable
71 * interrupts here to ensure we don't miss a wakeup call.
72 */
73void cpu_idle(void)
74{
75 /* endless idle loop with no priority at all */
76 while (1) {
77 while (!need_resched())
78 cpu_relax();
79 preempt_enable_no_resched();
80 schedule();
81 preempt_disable();
82 }
83}
84
85static char reboot_mode = 'h';
86
87int __init reboot_setup(char *str)
88{
89 reboot_mode = str[0];
90 return 1;
91}
92
93__setup("reboot=", reboot_setup);
94
95/* ARM26 cant do these but we still need to define them. */
96void machine_halt(void)
97{
98}
99void machine_power_off(void)
100{
101}
102
103void machine_restart(char * __unused)
104{
105 /*
106 * Clean and disable cache, and turn off interrupts
107 */
108 cpu_proc_fin();
109
110 /*
111 * Tell the mm system that we are going to reboot -
112 * we may need it to insert some 1:1 mappings so that
113 * soft boot works.
114 */
115 setup_mm_for_reboot(reboot_mode);
116
117 /*
118 * copy branch instruction to reset location and call it
119 */
120
121 *(unsigned long *)0 = *(unsigned long *)0x03800000;
122 ((void(*)(void))0)();
123
124 /*
125 * Whoops - the architecture was unable to reboot.
126 * Tell the user! Should never happen...
127 */
128 mdelay(1000);
129 printk("Reboot failed -- System halted\n");
130 while (1);
131}
132
133void show_regs(struct pt_regs * regs)
134{
135 unsigned long flags;
136
137 flags = condition_codes(regs);
138
139 printk("pc : [<%08lx>] lr : [<%08lx>] %s\n"
140 "sp : %08lx ip : %08lx fp : %08lx\n",
141 instruction_pointer(regs),
142 regs->ARM_lr, print_tainted(), regs->ARM_sp,
143 regs->ARM_ip, regs->ARM_fp);
144 printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
145 regs->ARM_r10, regs->ARM_r9,
146 regs->ARM_r8);
147 printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
148 regs->ARM_r7, regs->ARM_r6,
149 regs->ARM_r5, regs->ARM_r4);
150 printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
151 regs->ARM_r3, regs->ARM_r2,
152 regs->ARM_r1, regs->ARM_r0);
153 printk("Flags: %c%c%c%c",
154 flags & PSR_N_BIT ? 'N' : 'n',
155 flags & PSR_Z_BIT ? 'Z' : 'z',
156 flags & PSR_C_BIT ? 'C' : 'c',
157 flags & PSR_V_BIT ? 'V' : 'v');
158 printk(" IRQs o%s FIQs o%s Mode %s Segment %s\n",
159 interrupts_enabled(regs) ? "n" : "ff",
160 fast_interrupts_enabled(regs) ? "n" : "ff",
161 processor_modes[processor_mode(regs)],
162 get_fs() == get_ds() ? "kernel" : "user");
163}
164
165void show_fpregs(struct user_fp *regs)
166{
167 int i;
168
169 for (i = 0; i < 8; i++) {
170 unsigned long *p;
171 char type;
172
173 p = (unsigned long *)(regs->fpregs + i);
174
175 switch (regs->ftype[i]) {
176 case 1: type = 'f'; break;
177 case 2: type = 'd'; break;
178 case 3: type = 'e'; break;
179 default: type = '?'; break;
180 }
181 if (regs->init_flag)
182 type = '?';
183
184 printk(" f%d(%c): %08lx %08lx %08lx%c",
185 i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' ');
186 }
187
188
189 printk("FPSR: %08lx FPCR: %08lx\n",
190 (unsigned long)regs->fpsr,
191 (unsigned long)regs->fpcr);
192}
193
194/*
195 * Task structure and kernel stack allocation.
196 */
197static unsigned long *thread_info_head;
198static unsigned int nr_thread_info;
199
200extern unsigned long get_page_8k(int priority);
201extern void free_page_8k(unsigned long page);
202
203// FIXME - is this valid?
204#define EXTRA_TASK_STRUCT 0
205#define ll_alloc_task_struct() ((struct thread_info *)get_page_8k(GFP_KERNEL))
206#define ll_free_task_struct(p) free_page_8k((unsigned long)(p))
207
208//FIXME - do we use *task param below looks like we dont, which is ok?
209//FIXME - if EXTRA_TASK_STRUCT is zero we can optimise the below away permanently. *IF* its supposed to be zero.
210struct thread_info *alloc_thread_info(struct task_struct *task)
211{
212 struct thread_info *thread = NULL;
213
214 if (EXTRA_TASK_STRUCT) {
215 unsigned long *p = thread_info_head;
216
217 if (p) {
218 thread_info_head = (unsigned long *)p[0];
219 nr_thread_info -= 1;
220 }
221 thread = (struct thread_info *)p;
222 }
223
224 if (!thread)
225 thread = ll_alloc_task_struct();
226
227#ifdef CONFIG_MAGIC_SYSRQ
228 /*
229 * The stack must be cleared if you want SYSRQ-T to
230 * give sensible stack usage information
231 */
232 if (thread) {
233 char *p = (char *)thread;
234 memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
235 }
236#endif
237 return thread;
238}
239
240void free_thread_info(struct thread_info *thread)
241{
242 if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) {
243 unsigned long *p = (unsigned long *)thread;
244 p[0] = (unsigned long)thread_info_head;
245 thread_info_head = p;
246 nr_thread_info += 1;
247 } else
248 ll_free_task_struct(thread);
249}
250
251/*
252 * Free current thread data structures etc..
253 */
254void exit_thread(void)
255{
256}
257
258void flush_thread(void)
259{
260 struct thread_info *thread = current_thread_info();
261 struct task_struct *tsk = current;
262
263 memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
264 memset(&thread->fpstate, 0, sizeof(union fp_state));
265
266 clear_used_math();
267}
268
269void release_thread(struct task_struct *dead_task)
270{
271}
272
273asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
274
275int
276copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
277 unsigned long unused, struct task_struct *p, struct pt_regs *regs)
278{
279 struct thread_info *thread = task_thread_info(p);
280 struct pt_regs *childregs = task_pt_regs(p);
281
282 *childregs = *regs;
283 childregs->ARM_r0 = 0;
284 childregs->ARM_sp = stack_start;
285
286 memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
287 thread->cpu_context.sp = (unsigned long)childregs;
288 thread->cpu_context.pc = (unsigned long)ret_from_fork | MODE_SVC26 | PSR_I_BIT;
289
290 return 0;
291}
292
293/*
294 * fill in the fpe structure for a core dump...
295 */
296int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
297{
298 struct thread_info *thread = current_thread_info();
299 int used_math = !!used_math();
300
301 if (used_math)
302 memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
303
304 return used_math;
305}
306
307/*
308 * fill in the user structure for a core dump..
309 */
310void dump_thread(struct pt_regs * regs, struct user * dump)
311{
312 struct task_struct *tsk = current;
313
314 dump->magic = CMAGIC;
315 dump->start_code = tsk->mm->start_code;
316 dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
317
318 dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
319 dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
320 dump->u_ssize = 0;
321
322 dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
323 dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
324 dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
325 dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
326 dump->u_debugreg[4] = tsk->thread.debug.nsaved;
327
328 if (dump->start_stack < 0x04000000)
329 dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
330
331 dump->regs = *regs;
332 dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
333}
334
335/*
336 * Shuffle the argument into the correct register before calling the
337 * thread function. r1 is the thread argument, r2 is the pointer to
338 * the thread function, and r3 points to the exit function.
339 * FIXME - make sure this is right - the older code used to zero fp
340 * and cause the parent to call sys_exit (do_exit in this version)
341 */
342extern void kernel_thread_helper(void);
343
344asm( ".section .text\n"
345" .align\n"
346" .type kernel_thread_helper, #function\n"
347"kernel_thread_helper:\n"
348" mov r0, r1\n"
349" mov lr, r3\n"
350" mov pc, r2\n"
351" .size kernel_thread_helper, . - kernel_thread_helper\n"
352" .previous");
353
354/*
355 * Create a kernel thread.
356 */
357pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
358{
359 struct pt_regs regs;
360
361 memset(&regs, 0, sizeof(regs));
362
363 regs.ARM_r1 = (unsigned long)arg;
364 regs.ARM_r2 = (unsigned long)fn;
365 regs.ARM_r3 = (unsigned long)do_exit;
366 regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
367
368 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
369}
370EXPORT_SYMBOL(kernel_thread);
371
372
373unsigned long get_wchan(struct task_struct *p)
374{
375 unsigned long fp, lr;
376 unsigned long stack_page;
377 int count = 0;
378 if (!p || p == current || p->state == TASK_RUNNING)
379 return 0;
380
381 stack_page = 4096 + (unsigned long)p;
382 fp = thread_saved_fp(p);
383 do {
384 if (fp < stack_page || fp > 4092+stack_page)
385 return 0;
386 lr = pc_pointer (((unsigned long *)fp)[-1]);
387 if (!in_sched_functions(lr))
388 return lr;
389 fp = *(unsigned long *) (fp - 12);
390 } while (count ++ < 16);
391 return 0;
392}
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
deleted file mode 100644
index 0fefb86970c6..000000000000
--- a/arch/arm26/kernel/ptrace.c
+++ /dev/null
@@ -1,670 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/ptrace.c
3 *
4 * By Ross Biro 1/23/92
5 * edited by Linus Torvalds
6 * ARM modifications Copyright (C) 2000 Russell King
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
16#include <linux/ptrace.h>
17#include <linux/user.h>
18#include <linux/security.h>
19#include <linux/signal.h>
20
21#include <asm/uaccess.h>
22#include <asm/pgtable.h>
23#include <asm/system.h>
24//#include <asm/processor.h>
25
26#include "ptrace.h"
27
28#define REG_PC 15
29#define REG_PSR 15
30/*
31 * does not yet catch signals sent when the child dies.
32 * in exit.c or in signal.c.
33 */
34
35/*
36 * Breakpoint SWI instruction: SWI &9F0001
37 */
38#define BREAKINST_ARM 0xef9f0001
39
40/*
41 * this routine will get a word off of the processes privileged stack.
42 * the offset is how far from the base addr as stored in the THREAD.
43 * this routine assumes that all the privileged stacks are in our
44 * data space.
45 */
46static inline long get_user_reg(struct task_struct *task, int offset)
47{
48 return task_pt_regs(task)->uregs[offset];
49}
50
51/*
52 * this routine will put a word on the processes privileged stack.
53 * the offset is how far from the base addr as stored in the THREAD.
54 * this routine assumes that all the privileged stacks are in our
55 * data space.
56 */
57static inline int
58put_user_reg(struct task_struct *task, int offset, long data)
59{
60 struct pt_regs newregs, *regs = task_pt_regs(task);
61 int ret = -EINVAL;
62
63 newregs = *regs;
64 newregs.uregs[offset] = data;
65
66 if (valid_user_regs(&newregs)) {
67 regs->uregs[offset] = data;
68 ret = 0;
69 }
70
71 return ret;
72}
73
74static inline int
75read_u32(struct task_struct *task, unsigned long addr, u32 *res)
76{
77 int ret;
78
79 ret = access_process_vm(task, addr, res, sizeof(*res), 0);
80
81 return ret == sizeof(*res) ? 0 : -EIO;
82}
83
84static inline int
85read_instr(struct task_struct *task, unsigned long addr, u32 *res)
86{
87 int ret;
88 u32 val;
89 ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
90 ret = ret == sizeof(val) ? 0 : -EIO;
91 *res = val;
92 return ret;
93}
94
95/*
96 * Get value of register `rn' (in the instruction)
97 */
98static unsigned long
99ptrace_getrn(struct task_struct *child, unsigned long insn)
100{
101 unsigned int reg = (insn >> 16) & 15;
102 unsigned long val;
103
104 val = get_user_reg(child, reg);
105 if (reg == 15)
106 val = pc_pointer(val + 8); //FIXME - correct for arm26?
107
108 return val;
109}
110
111/*
112 * Get value of operand 2 (in an ALU instruction)
113 */
114static unsigned long
115ptrace_getaluop2(struct task_struct *child, unsigned long insn)
116{
117 unsigned long val;
118 int shift;
119 int type;
120
121 if (insn & 1 << 25) {
122 val = insn & 255;
123 shift = (insn >> 8) & 15;
124 type = 3;
125 } else {
126 val = get_user_reg (child, insn & 15);
127
128 if (insn & (1 << 4))
129 shift = (int)get_user_reg (child, (insn >> 8) & 15);
130 else
131 shift = (insn >> 7) & 31;
132
133 type = (insn >> 5) & 3;
134 }
135
136 switch (type) {
137 case 0: val <<= shift; break;
138 case 1: val >>= shift; break;
139 case 2:
140 val = (((signed long)val) >> shift);
141 break;
142 case 3:
143 val = (val >> shift) | (val << (32 - shift));
144 break;
145 }
146 return val;
147}
148
149/*
150 * Get value of operand 2 (in a LDR instruction)
151 */
152static unsigned long
153ptrace_getldrop2(struct task_struct *child, unsigned long insn)
154{
155 unsigned long val;
156 int shift;
157 int type;
158
159 val = get_user_reg(child, insn & 15);
160 shift = (insn >> 7) & 31;
161 type = (insn >> 5) & 3;
162
163 switch (type) {
164 case 0: val <<= shift; break;
165 case 1: val >>= shift; break;
166 case 2:
167 val = (((signed long)val) >> shift);
168 break;
169 case 3:
170 val = (val >> shift) | (val << (32 - shift));
171 break;
172 }
173 return val;
174}
175
176#define OP_MASK 0x01e00000
177#define OP_AND 0x00000000
178#define OP_EOR 0x00200000
179#define OP_SUB 0x00400000
180#define OP_RSB 0x00600000
181#define OP_ADD 0x00800000
182#define OP_ADC 0x00a00000
183#define OP_SBC 0x00c00000
184#define OP_RSC 0x00e00000
185#define OP_ORR 0x01800000
186#define OP_MOV 0x01a00000
187#define OP_BIC 0x01c00000
188#define OP_MVN 0x01e00000
189
190static unsigned long
191get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
192{
193 u32 alt = 0;
194
195 switch (insn & 0x0e000000) {
196 case 0x00000000:
197 case 0x02000000: {
198 /*
199 * data processing
200 */
201 long aluop1, aluop2, ccbit;
202
203 if ((insn & 0xf000) != 0xf000)
204 break;
205
206 aluop1 = ptrace_getrn(child, insn);
207 aluop2 = ptrace_getaluop2(child, insn);
208 ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
209
210 switch (insn & OP_MASK) {
211 case OP_AND: alt = aluop1 & aluop2; break;
212 case OP_EOR: alt = aluop1 ^ aluop2; break;
213 case OP_SUB: alt = aluop1 - aluop2; break;
214 case OP_RSB: alt = aluop2 - aluop1; break;
215 case OP_ADD: alt = aluop1 + aluop2; break;
216 case OP_ADC: alt = aluop1 + aluop2 + ccbit; break;
217 case OP_SBC: alt = aluop1 - aluop2 + ccbit; break;
218 case OP_RSC: alt = aluop2 - aluop1 + ccbit; break;
219 case OP_ORR: alt = aluop1 | aluop2; break;
220 case OP_MOV: alt = aluop2; break;
221 case OP_BIC: alt = aluop1 & ~aluop2; break;
222 case OP_MVN: alt = ~aluop2; break;
223 }
224 break;
225 }
226
227 case 0x04000000:
228 case 0x06000000:
229 /*
230 * ldr
231 */
232 if ((insn & 0x0010f000) == 0x0010f000) {
233 unsigned long base;
234
235 base = ptrace_getrn(child, insn);
236 if (insn & 1 << 24) {
237 long aluop2;
238
239 if (insn & 0x02000000)
240 aluop2 = ptrace_getldrop2(child, insn);
241 else
242 aluop2 = insn & 0xfff;
243
244 if (insn & 1 << 23)
245 base += aluop2;
246 else
247 base -= aluop2;
248 }
249 if (read_u32(child, base, &alt) == 0)
250 alt = pc_pointer(alt);
251 }
252 break;
253
254 case 0x08000000:
255 /*
256 * ldm
257 */
258 if ((insn & 0x00108000) == 0x00108000) {
259 unsigned long base;
260 unsigned int nr_regs;
261
262 if (insn & (1 << 23)) {
263 nr_regs = hweight16(insn & 65535) << 2;
264
265 if (!(insn & (1 << 24)))
266 nr_regs -= 4;
267 } else {
268 if (insn & (1 << 24))
269 nr_regs = -4;
270 else
271 nr_regs = 0;
272 }
273
274 base = ptrace_getrn(child, insn);
275
276 if (read_u32(child, base + nr_regs, &alt) == 0)
277 alt = pc_pointer(alt);
278 break;
279 }
280 break;
281
282 case 0x0a000000: {
283 /*
284 * bl or b
285 */
286 signed long displ;
287 /* It's a branch/branch link: instead of trying to
288 * figure out whether the branch will be taken or not,
289 * we'll put a breakpoint at both locations. This is
290 * simpler, more reliable, and probably not a whole lot
291 * slower than the alternative approach of emulating the
292 * branch.
293 */
294 displ = (insn & 0x00ffffff) << 8;
295 displ = (displ >> 6) + 8;
296 if (displ != 0 && displ != 4)
297 alt = pc + displ;
298 }
299 break;
300 }
301
302 return alt;
303}
304
305static int
306swap_insn(struct task_struct *task, unsigned long addr,
307 void *old_insn, void *new_insn, int size)
308{
309 int ret;
310
311 ret = access_process_vm(task, addr, old_insn, size, 0);
312 if (ret == size)
313 ret = access_process_vm(task, addr, new_insn, size, 1);
314 return ret;
315}
316
317static void
318add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
319{
320 int nr = dbg->nsaved;
321
322 if (nr < 2) {
323 u32 new_insn = BREAKINST_ARM;
324 int res;
325
326 res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
327
328 if (res == 4) {
329 dbg->bp[nr].address = addr;
330 dbg->nsaved += 1;
331 }
332 } else
333 printk(KERN_ERR "ptrace: too many breakpoints\n");
334}
335
336/*
337 * Clear one breakpoint in the user program. We copy what the hardware
338 * does and use bit 0 of the address to indicate whether this is a Thumb
339 * breakpoint or an ARM breakpoint.
340 */
341static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
342{
343 unsigned long addr = bp->address;
344 u32 old_insn;
345 int ret;
346
347 ret = swap_insn(task, addr & ~3, &old_insn,
348 &bp->insn, 4);
349
350 if (ret != 4 || old_insn != BREAKINST_ARM)
351 printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
352 "0x%08lx (0x%08x)\n", task->comm, task->pid,
353 addr, old_insn);
354}
355
356void ptrace_set_bpt(struct task_struct *child)
357{
358 struct pt_regs *regs;
359 unsigned long pc;
360 u32 insn;
361 int res;
362
363 regs = task_pt_regs(child);
364 pc = instruction_pointer(regs);
365
366 res = read_instr(child, pc, &insn);
367 if (!res) {
368 struct debug_info *dbg = &child->thread.debug;
369 unsigned long alt;
370
371 dbg->nsaved = 0;
372
373 alt = get_branch_address(child, pc, insn);
374 if (alt)
375 add_breakpoint(child, dbg, alt);
376
377 /*
378 * Note that we ignore the result of setting the above
379 * breakpoint since it may fail. When it does, this is
380 * not so much an error, but a forewarning that we may
381 * be receiving a prefetch abort shortly.
382 *
383 * If we don't set this breakpoint here, then we can
384 * lose control of the thread during single stepping.
385 */
386 if (!alt || predicate(insn) != PREDICATE_ALWAYS)
387 add_breakpoint(child, dbg, pc + 4);
388 }
389}
390
391/*
392 * Ensure no single-step breakpoint is pending. Returns non-zero
393 * value if child was being single-stepped.
394 */
395void ptrace_cancel_bpt(struct task_struct *child)
396{
397 int i, nsaved = child->thread.debug.nsaved;
398
399 child->thread.debug.nsaved = 0;
400
401 if (nsaved > 2) {
402 printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
403 nsaved = 2;
404 }
405
406 for (i = 0; i < nsaved; i++)
407 clear_breakpoint(child, &child->thread.debug.bp[i]);
408}
409
410/*
411 * Called by kernel/ptrace.c when detaching..
412 *
413 * Make sure the single step bit is not set.
414 */
415void ptrace_disable(struct task_struct *child)
416{
417 child->ptrace &= ~PT_SINGLESTEP;
418 ptrace_cancel_bpt(child);
419}
420
421/*
422 * Handle hitting a breakpoint.
423 */
424void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
425{
426 siginfo_t info;
427
428 /*
429 * The PC is always left pointing at the next instruction. Fix this.
430 */
431 regs->ARM_pc -= 4;
432
433 if (tsk->thread.debug.nsaved == 0)
434 printk(KERN_ERR "ptrace: bogus breakpoint trap\n");
435
436 ptrace_cancel_bpt(tsk);
437
438 info.si_signo = SIGTRAP;
439 info.si_errno = 0;
440 info.si_code = TRAP_BRKPT;
441 info.si_addr = (void *)instruction_pointer(regs) - 4;
442
443 force_sig_info(SIGTRAP, &info, tsk);
444}
445
446/*
447 * Read the word at offset "off" into the "struct user". We
448 * actually access the pt_regs stored on the kernel stack.
449 */
450static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
451 unsigned long *ret)
452{
453 unsigned long tmp;
454
455 if (off & 3 || off >= sizeof(struct user))
456 return -EIO;
457
458 tmp = 0;
459 if (off < sizeof(struct pt_regs))
460 tmp = get_user_reg(tsk, off >> 2);
461
462 return put_user(tmp, ret);
463}
464
465/*
466 * Write the word at offset "off" into "struct user". We
467 * actually access the pt_regs stored on the kernel stack.
468 */
469static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
470 unsigned long val)
471{
472 if (off & 3 || off >= sizeof(struct user))
473 return -EIO;
474
475 if (off >= sizeof(struct pt_regs))
476 return 0;
477
478 return put_user_reg(tsk, off >> 2, val);
479}
480
481/*
482 * Get all user integer registers.
483 */
484static int ptrace_getregs(struct task_struct *tsk, void *uregs)
485{
486 struct pt_regs *regs = task_pt_regs(tsk);
487
488 return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
489}
490
491/*
492 * Set all user integer registers.
493 */
494static int ptrace_setregs(struct task_struct *tsk, void *uregs)
495{
496 struct pt_regs newregs;
497 int ret;
498
499 ret = -EFAULT;
500 if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
501 struct pt_regs *regs = task_pt_regs(tsk);
502
503 ret = -EINVAL;
504 if (valid_user_regs(&newregs)) {
505 *regs = newregs;
506 ret = 0;
507 }
508 }
509
510 return ret;
511}
512
513/*
514 * Get the child FPU state.
515 */
516static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
517{
518 return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
519 sizeof(struct user_fp)) ? -EFAULT : 0;
520}
521
522/*
523 * Set the child FPU state.
524 */
525static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
526{
527 set_stopped_child_used_math(tsk);
528 return copy_from_user(&task_thread_info(tsk)->fpstate, ufp,
529 sizeof(struct user_fp)) ? -EFAULT : 0;
530}
531
532long arch_ptrace(struct task_struct *child, long request, long addr, long data)
533{
534 int ret;
535
536 switch (request) {
537 /*
538 * read word at location "addr" in the child process.
539 */
540 case PTRACE_PEEKTEXT:
541 case PTRACE_PEEKDATA:
542 ret = generic_ptrace_peekdata(child, addr, data);
543 break;
544
545 case PTRACE_PEEKUSR:
546 ret = ptrace_read_user(child, addr, (unsigned long *)data);
547 break;
548
549 /*
550 * write the word at location addr.
551 */
552 case PTRACE_POKETEXT:
553 case PTRACE_POKEDATA:
554 ret = generic_ptrace_pokedata(child, addr, data);
555 break;
556
557 case PTRACE_POKEUSR:
558 ret = ptrace_write_user(child, addr, data);
559 break;
560
561 /*
562 * continue/restart and stop at next (return from) syscall
563 */
564 case PTRACE_SYSCALL:
565 case PTRACE_CONT:
566 ret = -EIO;
567 if (!valid_signal(data))
568 break;
569 if (request == PTRACE_SYSCALL)
570 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
571 else
572 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
573 child->exit_code = data;
574 /* make sure single-step breakpoint is gone. */
575 child->ptrace &= ~PT_SINGLESTEP;
576 ptrace_cancel_bpt(child);
577 wake_up_process(child);
578 ret = 0;
579 break;
580
581 /*
582 * make the child exit. Best I can do is send it a sigkill.
583 * perhaps it should be put in the status that it wants to
584 * exit.
585 */
586 case PTRACE_KILL:
587 /* make sure single-step breakpoint is gone. */
588 child->ptrace &= ~PT_SINGLESTEP;
589 ptrace_cancel_bpt(child);
590 if (child->exit_state != EXIT_ZOMBIE) {
591 child->exit_code = SIGKILL;
592 wake_up_process(child);
593 }
594 ret = 0;
595 break;
596
597 /*
598 * execute single instruction.
599 */
600 case PTRACE_SINGLESTEP:
601 ret = -EIO;
602 if (!valid_signal(data))
603 break;
604 child->ptrace |= PT_SINGLESTEP;
605 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
606 child->exit_code = data;
607 /* give it a chance to run. */
608 wake_up_process(child);
609 ret = 0;
610 break;
611
612 case PTRACE_DETACH:
613 ret = ptrace_detach(child, data);
614 break;
615
616 case PTRACE_GETREGS:
617 ret = ptrace_getregs(child, (void *)data);
618 break;
619
620 case PTRACE_SETREGS:
621 ret = ptrace_setregs(child, (void *)data);
622 break;
623
624 case PTRACE_GETFPREGS:
625 ret = ptrace_getfpregs(child, (void *)data);
626 break;
627
628 case PTRACE_SETFPREGS:
629 ret = ptrace_setfpregs(child, (void *)data);
630 break;
631
632 default:
633 ret = ptrace_request(child, request, addr, data);
634 break;
635 }
636
637 return ret;
638}
639
640asmlinkage void syscall_trace(int why, struct pt_regs *regs)
641{
642 unsigned long ip;
643
644 if (!test_thread_flag(TIF_SYSCALL_TRACE))
645 return;
646 if (!(current->ptrace & PT_PTRACED))
647 return;
648
649 /*
650 * Save IP. IP is used to denote syscall entry/exit:
651 * IP = 0 -> entry, = 1 -> exit
652 */
653 ip = regs->ARM_ip;
654 regs->ARM_ip = why;
655
656 /* the 0x80 provides a way for the tracing parent to distinguish
657 between a syscall stop and SIGTRAP delivery */
658 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
659 ? 0x80 : 0));
660 /*
661 * this isn't the same as continuing with a signal, but it will do
662 * for normal use. strace only continues with a signal if the
663 * stopping signal is not SIGTRAP. -brl
664 */
665 if (current->exit_code) {
666 send_sig(current->exit_code, current, 1);
667 current->exit_code = 0;
668 }
669 regs->ARM_ip = ip;
670}
diff --git a/arch/arm26/kernel/ptrace.h b/arch/arm26/kernel/ptrace.h
deleted file mode 100644
index 846c9d8d36ed..000000000000
--- a/arch/arm26/kernel/ptrace.h
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/ptrace.h
3 *
4 * Copyright (C) 2000-2003 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11extern void ptrace_cancel_bpt(struct task_struct *);
12extern void ptrace_set_bpt(struct task_struct *);
13extern void ptrace_break(struct task_struct *, struct pt_regs *);
diff --git a/arch/arm26/kernel/semaphore.c b/arch/arm26/kernel/semaphore.c
deleted file mode 100644
index 5447a06db3fa..000000000000
--- a/arch/arm26/kernel/semaphore.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/*
2 * ARM semaphore implementation, taken from
3 *
4 * i386 semaphore implementation.
5 *
6 * (C) Copyright 1999 Linus Torvalds
7 * (C) Copyright 2003 Ian Molton (ARM26 mods)
8 *
9 * Modified for ARM by Russell King
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15#include <linux/module.h>
16#include <linux/sched.h>
17#include <linux/errno.h>
18#include <linux/init.h>
19
20#include <asm/semaphore.h>
21
22/*
23 * Semaphores are implemented using a two-way counter:
24 * The "count" variable is decremented for each process
25 * that tries to acquire the semaphore, while the "sleeping"
26 * variable is a count of such acquires.
27 *
28 * Notably, the inline "up()" and "down()" functions can
29 * efficiently test if they need to do any extra work (up
30 * needs to do something only if count was negative before
31 * the increment operation.
32 *
33 * "sleeping" and the contention routine ordering is
34 * protected by the semaphore spinlock.
35 *
36 * Note that these functions are only called when there is
37 * contention on the lock, and as such all this is the
38 * "non-critical" part of the whole semaphore business. The
39 * critical part is the inline stuff in <asm/semaphore.h>
40 * where we want to avoid any extra jumps and calls.
41 */
42
43/*
44 * Logic:
45 * - only on a boundary condition do we need to care. When we go
46 * from a negative count to a non-negative, we wake people up.
47 * - when we go from a non-negative count to a negative do we
48 * (a) synchronize with the "sleeper" count and (b) make sure
49 * that we're on the wakeup list before we synchronize so that
50 * we cannot lose wakeup events.
51 */
52
53void __up(struct semaphore *sem)
54{
55 wake_up(&sem->wait);
56}
57
58static DEFINE_SPINLOCK(semaphore_lock);
59
60void __sched __down(struct semaphore * sem)
61{
62 struct task_struct *tsk = current;
63 DECLARE_WAITQUEUE(wait, tsk);
64 tsk->state = TASK_UNINTERRUPTIBLE;
65 add_wait_queue_exclusive(&sem->wait, &wait);
66
67 spin_lock_irq(&semaphore_lock);
68 sem->sleepers++;
69 for (;;) {
70 int sleepers = sem->sleepers;
71
72 /*
73 * Add "everybody else" into it. They aren't
74 * playing, because we own the spinlock.
75 */
76 if (!atomic_add_negative(sleepers - 1, &sem->count)) {
77 sem->sleepers = 0;
78 break;
79 }
80 sem->sleepers = 1; /* us - see -1 above */
81 spin_unlock_irq(&semaphore_lock);
82
83 schedule();
84 tsk->state = TASK_UNINTERRUPTIBLE;
85 spin_lock_irq(&semaphore_lock);
86 }
87 spin_unlock_irq(&semaphore_lock);
88 remove_wait_queue(&sem->wait, &wait);
89 tsk->state = TASK_RUNNING;
90 wake_up(&sem->wait);
91}
92
93int __sched __down_interruptible(struct semaphore * sem)
94{
95 int retval = 0;
96 struct task_struct *tsk = current;
97 DECLARE_WAITQUEUE(wait, tsk);
98 tsk->state = TASK_INTERRUPTIBLE;
99 add_wait_queue_exclusive(&sem->wait, &wait);
100
101 spin_lock_irq(&semaphore_lock);
102 sem->sleepers ++;
103 for (;;) {
104 int sleepers = sem->sleepers;
105
106 /*
107 * With signals pending, this turns into
108 * the trylock failure case - we won't be
109 * sleeping, and we* can't get the lock as
110 * it has contention. Just correct the count
111 * and exit.
112 */
113 if (signal_pending(current)) {
114 retval = -EINTR;
115 sem->sleepers = 0;
116 atomic_add(sleepers, &sem->count);
117 break;
118 }
119
120 /*
121 * Add "everybody else" into it. They aren't
122 * playing, because we own the spinlock. The
123 * "-1" is because we're still hoping to get
124 * the lock.
125 */
126 if (!atomic_add_negative(sleepers - 1, &sem->count)) {
127 sem->sleepers = 0;
128 break;
129 }
130 sem->sleepers = 1; /* us - see -1 above */
131 spin_unlock_irq(&semaphore_lock);
132
133 schedule();
134 tsk->state = TASK_INTERRUPTIBLE;
135 spin_lock_irq(&semaphore_lock);
136 }
137 spin_unlock_irq(&semaphore_lock);
138 tsk->state = TASK_RUNNING;
139 remove_wait_queue(&sem->wait, &wait);
140 wake_up(&sem->wait);
141 return retval;
142}
143
144/*
145 * Trylock failed - make sure we correct for
146 * having decremented the count.
147 *
148 * We could have done the trylock with a
149 * single "cmpxchg" without failure cases,
150 * but then it wouldn't work on a 386.
151 */
152int __down_trylock(struct semaphore * sem)
153{
154 int sleepers;
155 unsigned long flags;
156
157 spin_lock_irqsave(&semaphore_lock, flags);
158 sleepers = sem->sleepers + 1;
159 sem->sleepers = 0;
160
161 /*
162 * Add "everybody else" and us into it. They aren't
163 * playing, because we own the spinlock.
164 */
165 if (!atomic_add_negative(sleepers, &sem->count))
166 wake_up(&sem->wait);
167
168 spin_unlock_irqrestore(&semaphore_lock, flags);
169 return 1;
170}
171
172/*
173 * The semaphore operations have a special calling sequence that
174 * allow us to do a simpler in-line version of them. These routines
175 * need to convert that sequence back into the C sequence when
176 * there is contention on the semaphore.
177 *
178 * ip contains the semaphore pointer on entry. Save the C-clobbered
179 * registers (r0 to r3 and lr), but not ip, as we use it as a return
180 * value in some cases..
181 */
182asm(" .section .sched.text , #alloc, #execinstr \n\
183 .align 5 \n\
184 .globl __down_failed \n\
185__down_failed: \n\
186 stmfd sp!, {r0 - r3, lr} \n\
187 mov r0, ip \n\
188 bl __down \n\
189 ldmfd sp!, {r0 - r3, pc}^ \n\
190 \n\
191 .align 5 \n\
192 .globl __down_interruptible_failed \n\
193__down_interruptible_failed: \n\
194 stmfd sp!, {r0 - r3, lr} \n\
195 mov r0, ip \n\
196 bl __down_interruptible \n\
197 mov ip, r0 \n\
198 ldmfd sp!, {r0 - r3, pc}^ \n\
199 \n\
200 .align 5 \n\
201 .globl __down_trylock_failed \n\
202__down_trylock_failed: \n\
203 stmfd sp!, {r0 - r3, lr} \n\
204 mov r0, ip \n\
205 bl __down_trylock \n\
206 mov ip, r0 \n\
207 ldmfd sp!, {r0 - r3, pc}^ \n\
208 \n\
209 .align 5 \n\
210 .globl __up_wakeup \n\
211__up_wakeup: \n\
212 stmfd sp!, {r0 - r3, lr} \n\
213 mov r0, ip \n\
214 bl __up \n\
215 ldmfd sp!, {r0 - r3, pc}^ \n\
216 ");
217
218EXPORT_SYMBOL(__down_failed);
219EXPORT_SYMBOL(__down_interruptible_failed);
220EXPORT_SYMBOL(__down_trylock_failed);
221EXPORT_SYMBOL(__up_wakeup);
222
diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c
deleted file mode 100644
index 0e006c6cd5a0..000000000000
--- a/arch/arm26/kernel/setup.c
+++ /dev/null
@@ -1,572 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/setup.c
3 *
4 * Copyright (C) 1995-2001 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/stddef.h>
13#include <linux/ioport.h>
14#include <linux/delay.h>
15#include <linux/utsname.h>
16#include <linux/blkdev.h>
17#include <linux/console.h>
18#include <linux/bootmem.h>
19#include <linux/seq_file.h>
20#include <linux/screen_info.h>
21#include <linux/init.h>
22#include <linux/root_dev.h>
23
24#include <asm/elf.h>
25#include <asm/hardware.h>
26#include <asm/io.h>
27#include <asm/procinfo.h>
28#include <asm/setup.h>
29#include <asm/mach-types.h>
30#include <asm/tlbflush.h>
31
32#include <asm/irqchip.h>
33
34#ifndef MEM_SIZE
35#define MEM_SIZE (16*1024*1024)
36#endif
37
38#ifdef CONFIG_PREEMPT
39DEFINE_SPINLOCK(kernel_flag);
40#endif
41
42#if defined(CONFIG_FPE_NWFPE)
43char fpe_type[8];
44
45static int __init fpe_setup(char *line)
46{
47 memcpy(fpe_type, line, 8);
48 return 1;
49}
50
51__setup("fpe=", fpe_setup);
52#endif
53
54extern void paging_init(struct meminfo *);
55extern void convert_to_tag_list(struct tag *tags);
56extern void squash_mem_tags(struct tag *tag);
57extern void bootmem_init(struct meminfo *);
58extern int root_mountflags;
59extern int _stext, _text, _etext, _edata, _end;
60#ifdef CONFIG_XIP_KERNEL
61extern int _endtext, _sdata;
62#endif
63
64
65unsigned int processor_id;
66unsigned int __machine_arch_type;
67unsigned int system_rev;
68unsigned int system_serial_low;
69unsigned int system_serial_high;
70unsigned int elf_hwcap;
71unsigned int memc_ctrl_reg;
72unsigned int number_mfm_drives;
73
74struct processor processor;
75
76char elf_platform[ELF_PLATFORM_SIZE];
77
78unsigned long phys_initrd_start __initdata = 0;
79unsigned long phys_initrd_size __initdata = 0;
80static struct meminfo meminfo __initdata = { 0, };
81static struct proc_info_item proc_info;
82static const char *machine_name;
83static char __initdata command_line[COMMAND_LINE_SIZE];
84
85static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
86
87/*
88 * Standard memory resources
89 */
90static struct resource mem_res[] = {
91 { "Video RAM", 0, 0, IORESOURCE_MEM },
92 { "Kernel code", 0, 0, IORESOURCE_MEM },
93 { "Kernel data", 0, 0, IORESOURCE_MEM }
94};
95
96#define video_ram mem_res[0]
97#define kernel_code mem_res[1]
98#define kernel_data mem_res[2]
99
100static struct resource io_res[] = {
101 { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
102 { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
103 { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
104};
105
106#define lp0 io_res[0]
107#define lp1 io_res[1]
108#define lp2 io_res[2]
109
110#define dump_cpu_info() do { } while (0)
111
112static void __init setup_processor(void)
113{
114 extern struct proc_info_list __proc_info_begin, __proc_info_end;
115 struct proc_info_list *list;
116
117 /*
118 * locate processor in the list of supported processor
119 * types. The linker builds this table for us from the
120 * entries in arch/arm26/mm/proc-*.S
121 */
122 for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
123 if ((processor_id & list->cpu_mask) == list->cpu_val)
124 break;
125
126 /*
127 * If processor type is unrecognised, then we
128 * can do nothing...
129 */
130 if (list >= &__proc_info_end) {
131 printk("CPU configuration botched (ID %08x), unable "
132 "to continue.\n", processor_id);
133 while (1);
134 }
135
136 proc_info = *list->info;
137 processor = *list->proc;
138
139
140 printk("CPU: %s %s revision %d\n",
141 proc_info.manufacturer, proc_info.cpu_name,
142 (int)processor_id & 15);
143
144 dump_cpu_info();
145
146 sprintf(init_utsname()->machine, "%s", list->arch_name);
147 sprintf(elf_platform, "%s", list->elf_name);
148 elf_hwcap = list->elf_hwcap;
149
150 cpu_proc_init();
151}
152
153/*
154 * Initial parsing of the command line. We need to pick out the
155 * memory size. We look for mem=size@start, where start and size
156 * are "size[KkMm]"
157 */
158static void __init
159parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
160{
161 char c = ' ', *to = command_line;
162 int usermem = 0, len = 0;
163
164 for (;;) {
165 if (c == ' ' && !memcmp(from, "mem=", 4)) {
166 unsigned long size, start;
167
168 if (to != command_line)
169 to -= 1;
170
171 /*
172 * If the user specifies memory size, we
173 * blow away any automatically generated
174 * size.
175 */
176 if (usermem == 0) {
177 usermem = 1;
178 mi->nr_banks = 0;
179 }
180
181 start = PHYS_OFFSET;
182 size = memparse(from + 4, &from);
183 if (*from == '@')
184 start = memparse(from + 1, &from);
185
186 mi->bank[mi->nr_banks].start = start;
187 mi->bank[mi->nr_banks].size = size;
188 mi->bank[mi->nr_banks].node = PHYS_TO_NID(start);
189 mi->nr_banks += 1;
190 }
191 c = *from++;
192 if (!c)
193 break;
194 if (COMMAND_LINE_SIZE <= ++len)
195 break;
196 *to++ = c;
197 }
198 *to = '\0';
199 *cmdline_p = command_line;
200}
201
202static void __init
203setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
204{
205#ifdef CONFIG_BLK_DEV_RAM
206 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
207
208 rd_image_start = image_start;
209 rd_prompt = prompt;
210 rd_doload = doload;
211
212 if (rd_sz)
213 rd_size = rd_sz;
214#endif
215}
216
217static void __init
218request_standard_resources(struct meminfo *mi)
219{
220 struct resource *res;
221 int i;
222
223 kernel_code.start = init_mm.start_code;
224 kernel_code.end = init_mm.end_code - 1;
225#ifdef CONFIG_XIP_KERNEL
226 kernel_data.start = init_mm.start_data;
227#else
228 kernel_data.start = init_mm.end_code;
229#endif
230 kernel_data.end = init_mm.brk - 1;
231
232 for (i = 0; i < mi->nr_banks; i++) {
233 unsigned long virt_start, virt_end;
234
235 if (mi->bank[i].size == 0)
236 continue;
237
238 virt_start = mi->bank[i].start;
239 virt_end = virt_start + mi->bank[i].size - 1;
240
241 res = alloc_bootmem_low(sizeof(*res));
242 res->name = "System RAM";
243 res->start = virt_start;
244 res->end = virt_end;
245 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
246
247 request_resource(&iomem_resource, res);
248
249 if (kernel_code.start >= res->start &&
250 kernel_code.end <= res->end)
251 request_resource(res, &kernel_code);
252 if (kernel_data.start >= res->start &&
253 kernel_data.end <= res->end)
254 request_resource(res, &kernel_data);
255 }
256
257/* FIXME - needed? if (mdesc->video_start) {
258 video_ram.start = mdesc->video_start;
259 video_ram.end = mdesc->video_end;
260 request_resource(&iomem_resource, &video_ram);
261 }*/
262
263 /*
264 * Some machines don't have the possibility of ever
265 * possessing lp1 or lp2
266 */
267 if (0) /* FIXME - need to do this for A5k at least */
268 request_resource(&ioport_resource, &lp0);
269}
270
271/*
272 * Tag parsing.
273 *
274 * This is the new way of passing data to the kernel at boot time. Rather
275 * than passing a fixed inflexible structure to the kernel, we pass a list
276 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
277 * tag for the list to be recognised (to distinguish the tagged list from
278 * a param_struct). The list is terminated with a zero-length tag (this tag
279 * is not parsed in any way).
280 */
281static int __init parse_tag_core(const struct tag *tag)
282{
283 if (tag->hdr.size > 2) {
284 if ((tag->u.core.flags & 1) == 0)
285 root_mountflags &= ~MS_RDONLY;
286 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
287 }
288 return 0;
289}
290
291__tagtable(ATAG_CORE, parse_tag_core);
292
293static int __init parse_tag_mem32(const struct tag *tag)
294{
295 if (meminfo.nr_banks >= NR_BANKS) {
296 printk(KERN_WARNING
297 "Ignoring memory bank 0x%08x size %dKB\n",
298 tag->u.mem.start, tag->u.mem.size / 1024);
299 return -EINVAL;
300 }
301 meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
302 meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
303 meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
304 meminfo.nr_banks += 1;
305
306 return 0;
307}
308
309__tagtable(ATAG_MEM, parse_tag_mem32);
310
311#if defined(CONFIG_DUMMY_CONSOLE)
312struct screen_info screen_info = {
313 .orig_video_lines = 30,
314 .orig_video_cols = 80,
315 .orig_video_mode = 0,
316 .orig_video_ega_bx = 0,
317 .orig_video_isVGA = 1,
318 .orig_video_points = 8
319};
320
321static int __init parse_tag_videotext(const struct tag *tag)
322{
323 screen_info.orig_x = tag->u.videotext.x;
324 screen_info.orig_y = tag->u.videotext.y;
325 screen_info.orig_video_page = tag->u.videotext.video_page;
326 screen_info.orig_video_mode = tag->u.videotext.video_mode;
327 screen_info.orig_video_cols = tag->u.videotext.video_cols;
328 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
329 screen_info.orig_video_lines = tag->u.videotext.video_lines;
330 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
331 screen_info.orig_video_points = tag->u.videotext.video_points;
332 return 0;
333}
334
335__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
336#endif
337
338static int __init parse_tag_acorn(const struct tag *tag)
339{
340 memc_ctrl_reg = tag->u.acorn.memc_control_reg;
341 number_mfm_drives = tag->u.acorn.adfsdrives;
342 return 0;
343}
344
345__tagtable(ATAG_ACORN, parse_tag_acorn);
346
347static int __init parse_tag_ramdisk(const struct tag *tag)
348{
349 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
350 (tag->u.ramdisk.flags & 2) == 0,
351 tag->u.ramdisk.start, tag->u.ramdisk.size);
352 return 0;
353}
354
355__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
356
357static int __init parse_tag_initrd(const struct tag *tag)
358{
359 printk(KERN_WARNING "ATAG_INITRD is deprecated; please update your bootloader. \n");
360 phys_initrd_start = (unsigned long)tag->u.initrd.start;
361 phys_initrd_size = (unsigned long)tag->u.initrd.size;
362 return 0;
363}
364
365__tagtable(ATAG_INITRD, parse_tag_initrd);
366
367static int __init parse_tag_initrd2(const struct tag *tag)
368{
369 printk(KERN_WARNING "ATAG_INITRD is deprecated; please update your bootloader. \n");
370 phys_initrd_start = (unsigned long)tag->u.initrd.start;
371 phys_initrd_size = (unsigned long)tag->u.initrd.size;
372 return 0;
373}
374
375__tagtable(ATAG_INITRD2, parse_tag_initrd2);
376
377static int __init parse_tag_serialnr(const struct tag *tag)
378{
379 system_serial_low = tag->u.serialnr.low;
380 system_serial_high = tag->u.serialnr.high;
381 return 0;
382}
383
384__tagtable(ATAG_SERIAL, parse_tag_serialnr);
385
386static int __init parse_tag_revision(const struct tag *tag)
387{
388 system_rev = tag->u.revision.rev;
389 return 0;
390}
391
392__tagtable(ATAG_REVISION, parse_tag_revision);
393
394static int __init parse_tag_cmdline(const struct tag *tag)
395{
396 strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
397 default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
398 return 0;
399}
400
401__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
402
403/*
404 * Scan the tag table for this tag, and call its parse function.
405 * The tag table is built by the linker from all the __tagtable
406 * declarations.
407 */
408static int __init parse_tag(const struct tag *tag)
409{
410 extern struct tagtable __tagtable_begin, __tagtable_end;
411 struct tagtable *t;
412
413 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
414 if (tag->hdr.tag == t->tag) {
415 t->parse(tag);
416 break;
417 }
418
419 return t < &__tagtable_end;
420}
421
422/*
423 * Parse all tags in the list, checking both the global and architecture
424 * specific tag tables.
425 */
426static void __init parse_tags(const struct tag *t)
427{
428 for (; t->hdr.size; t = tag_next(t))
429 if (!parse_tag(t))
430 printk(KERN_WARNING
431 "Ignoring unrecognised tag 0x%08x\n",
432 t->hdr.tag);
433}
434
435/*
436 * This holds our defaults.
437 */
438static struct init_tags {
439 struct tag_header hdr1;
440 struct tag_core core;
441 struct tag_header hdr2;
442 struct tag_mem32 mem;
443 struct tag_header hdr3;
444} init_tags __initdata = {
445 { tag_size(tag_core), ATAG_CORE },
446 { 1, PAGE_SIZE, 0xff },
447 { tag_size(tag_mem32), ATAG_MEM },
448 { MEM_SIZE, PHYS_OFFSET },
449 { 0, ATAG_NONE }
450};
451
452void __init setup_arch(char **cmdline_p)
453{
454 struct tag *tags = (struct tag *)&init_tags;
455 char *from = default_command_line;
456
457 setup_processor();
458 if(machine_arch_type == MACH_TYPE_A5K)
459 machine_name = "A5000";
460 else if(machine_arch_type == MACH_TYPE_ARCHIMEDES)
461 machine_name = "Archimedes";
462 else
463 machine_name = "UNKNOWN";
464
465 //FIXME - the tag struct is always copied here but this is a block
466 // of RAM that is accidentally reserved along with video RAM. perhaps
467 // it would be a good idea to explicitly reserve this?
468
469 tags = (struct tag *)0x0207c000;
470
471 /*
472 * If we have the old style parameters, convert them to
473 * a tag list.
474 */
475 if (tags->hdr.tag != ATAG_CORE)
476 convert_to_tag_list(tags);
477 if (tags->hdr.tag != ATAG_CORE)
478 tags = (struct tag *)&init_tags;
479 if (tags->hdr.tag == ATAG_CORE) {
480 if (meminfo.nr_banks != 0)
481 squash_mem_tags(tags);
482 parse_tags(tags);
483 }
484
485 init_mm.start_code = (unsigned long) &_text;
486#ifndef CONFIG_XIP_KERNEL
487 init_mm.end_code = (unsigned long) &_etext;
488#else
489 init_mm.end_code = (unsigned long) &_endtext;
490 init_mm.start_data = (unsigned long) &_sdata;
491#endif
492 init_mm.end_data = (unsigned long) &_edata;
493 init_mm.brk = (unsigned long) &_end;
494
495 memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
496 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
497 parse_cmdline(&meminfo, cmdline_p, from);
498 bootmem_init(&meminfo);
499 paging_init(&meminfo);
500 request_standard_resources(&meminfo);
501
502#ifdef CONFIG_VT
503#if defined(CONFIG_DUMMY_CONSOLE)
504 conswitchp = &dummy_con;
505#endif
506#endif
507}
508
509static const char *hwcap_str[] = {
510 "swp",
511 "half",
512 "thumb",
513 "26bit",
514 "fastmult",
515 "fpa",
516 "vfp",
517 "edsp",
518 NULL
519};
520
521static int c_show(struct seq_file *m, void *v)
522{
523 int i;
524
525 seq_printf(m, "Processor\t: %s %s rev %d (%s)\n",
526 proc_info.manufacturer, proc_info.cpu_name,
527 (int)processor_id & 15, elf_platform);
528
529 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
530 loops_per_jiffy / (500000/HZ),
531 (loops_per_jiffy / (5000/HZ)) % 100);
532
533 /* dump out the processor features */
534 seq_puts(m, "Features\t: ");
535
536 for (i = 0; hwcap_str[i]; i++)
537 if (elf_hwcap & (1 << i))
538 seq_printf(m, "%s ", hwcap_str[i]);
539
540 seq_puts(m, "\n");
541
542 seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
543 seq_printf(m, "CPU revision\t: %d\n\n", processor_id & 15);
544 seq_printf(m, "Hardware\t: %s\n", machine_name);
545 seq_printf(m, "Revision\t: %04x\n", system_rev);
546 seq_printf(m, "Serial\t\t: %08x%08x\n",
547 system_serial_high, system_serial_low);
548
549 return 0;
550}
551
552static void *c_start(struct seq_file *m, loff_t *pos)
553{
554 return *pos < 1 ? (void *)1 : NULL;
555}
556
557static void *c_next(struct seq_file *m, void *v, loff_t *pos)
558{
559 ++*pos;
560 return NULL;
561}
562
563static void c_stop(struct seq_file *m, void *v)
564{
565}
566
567struct seq_operations cpuinfo_op = {
568 .start = c_start,
569 .next = c_next,
570 .stop = c_stop,
571 .show = c_show
572};
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c
deleted file mode 100644
index 379b82dc645f..000000000000
--- a/arch/arm26/kernel/signal.c
+++ /dev/null
@@ -1,538 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/signal.c
3 *
4 * Copyright (C) 1995-2002 Russell King
5 * Copyright (C) 2003 Ian Molton (ARM26)
6 *
7 * FIXME!!! This is probably very broken (13/05/2003)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/signal.h>
19#include <linux/wait.h>
20#include <linux/ptrace.h>
21#include <linux/personality.h>
22#include <linux/tty.h>
23#include <linux/binfmts.h>
24#include <linux/elf.h>
25
26#include <asm/pgalloc.h>
27#include <asm/ucontext.h>
28#include <asm/uaccess.h>
29#include <asm/unistd.h>
30
31#include "ptrace.h"
32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35/*
36 * For ARM syscalls, we encode the syscall number into the instruction.
37 */
38#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn))
39#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
40
41static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
42
43/*
44 * atomically swap in the new signal mask, and wait for a signal.
45 */
46asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
47{
48 sigset_t saveset;
49
50 mask &= _BLOCKABLE;
51 spin_lock_irq(&current->sighand->siglock);
52 saveset = current->blocked;
53 siginitset(&current->blocked, mask);
54 recalc_sigpending();
55 spin_unlock_irq(&current->sighand->siglock);
56 regs->ARM_r0 = -EINTR;
57
58 while (1) {
59 current->state = TASK_INTERRUPTIBLE;
60 schedule();
61 if (do_signal(&saveset, regs, 0))
62 return regs->ARM_r0;
63 }
64}
65
66asmlinkage int
67sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs)
68{
69 sigset_t saveset, newset;
70
71 /* XXX: Don't preclude handling different sized sigset_t's. */
72 if (sigsetsize != sizeof(sigset_t))
73 return -EINVAL;
74
75 if (copy_from_user(&newset, unewset, sizeof(newset)))
76 return -EFAULT;
77 sigdelsetmask(&newset, ~_BLOCKABLE);
78
79 spin_lock_irq(&current->sighand->siglock);
80 saveset = current->blocked;
81 current->blocked = newset;
82 recalc_sigpending();
83 spin_unlock_irq(&current->sighand->siglock);
84 regs->ARM_r0 = -EINTR;
85
86 while (1) {
87 current->state = TASK_INTERRUPTIBLE;
88 schedule();
89 if (do_signal(&saveset, regs, 0))
90 return regs->ARM_r0;
91 }
92}
93
94asmlinkage int
95sys_sigaction(int sig, const struct old_sigaction *act,
96 struct old_sigaction *oact)
97{
98 struct k_sigaction new_ka, old_ka;
99 int ret;
100
101 if (act) {
102 old_sigset_t mask;
103 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
104 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
105 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
106 return -EFAULT;
107 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
108 __get_user(mask, &act->sa_mask);
109 siginitset(&new_ka.sa.sa_mask, mask);
110 }
111
112 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
113
114 if (!ret && oact) {
115 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
116 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
117 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
118 return -EFAULT;
119 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
120 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
121 }
122
123 return ret;
124}
125
126/*
127 * Do a signal return; undo the signal stack.
128 */
129struct sigframe
130{
131 struct sigcontext sc;
132 unsigned long extramask[_NSIG_WORDS-1];
133 unsigned long retcode;
134};
135
136struct rt_sigframe
137{
138 struct siginfo *pinfo;
139 void *puc;
140 struct siginfo info;
141 struct ucontext uc;
142 unsigned long retcode;
143};
144
145static int
146restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
147{
148 int err = 0;
149
150 __get_user_error(regs->ARM_r0, &sc->arm_r0, err);
151 __get_user_error(regs->ARM_r1, &sc->arm_r1, err);
152 __get_user_error(regs->ARM_r2, &sc->arm_r2, err);
153 __get_user_error(regs->ARM_r3, &sc->arm_r3, err);
154 __get_user_error(regs->ARM_r4, &sc->arm_r4, err);
155 __get_user_error(regs->ARM_r5, &sc->arm_r5, err);
156 __get_user_error(regs->ARM_r6, &sc->arm_r6, err);
157 __get_user_error(regs->ARM_r7, &sc->arm_r7, err);
158 __get_user_error(regs->ARM_r8, &sc->arm_r8, err);
159 __get_user_error(regs->ARM_r9, &sc->arm_r9, err);
160 __get_user_error(regs->ARM_r10, &sc->arm_r10, err);
161 __get_user_error(regs->ARM_fp, &sc->arm_fp, err);
162 __get_user_error(regs->ARM_ip, &sc->arm_ip, err);
163 __get_user_error(regs->ARM_sp, &sc->arm_sp, err);
164 __get_user_error(regs->ARM_lr, &sc->arm_lr, err);
165 __get_user_error(regs->ARM_pc, &sc->arm_pc, err);
166
167 err |= !valid_user_regs(regs);
168
169 return err;
170}
171
172asmlinkage int sys_sigreturn(struct pt_regs *regs)
173{
174 struct sigframe *frame;
175 sigset_t set;
176
177 /*
178 * Since we stacked the signal on a 64-bit boundary,
179 * then 'sp' should be word aligned here. If it's
180 * not, then the user is trying to mess with us.
181 */
182 if (regs->ARM_sp & 7)
183 goto badframe;
184
185 frame = (struct sigframe *)regs->ARM_sp;
186
187 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
188 goto badframe;
189 if (__get_user(set.sig[0], &frame->sc.oldmask)
190 || (_NSIG_WORDS > 1
191 && __copy_from_user(&set.sig[1], &frame->extramask,
192 sizeof(frame->extramask))))
193 goto badframe;
194
195 sigdelsetmask(&set, ~_BLOCKABLE);
196 spin_lock_irq(&current->sighand->siglock);
197 current->blocked = set;
198 recalc_sigpending();
199 spin_unlock_irq(&current->sighand->siglock);
200
201 if (restore_sigcontext(regs, &frame->sc))
202 goto badframe;
203
204 /* Send SIGTRAP if we're single-stepping */
205 if (current->ptrace & PT_SINGLESTEP) {
206 ptrace_cancel_bpt(current);
207 send_sig(SIGTRAP, current, 1);
208 }
209
210 return regs->ARM_r0;
211
212badframe:
213 force_sig(SIGSEGV, current);
214 return 0;
215}
216
217asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
218{
219 struct rt_sigframe *frame;
220 sigset_t set;
221
222 /*
223 * Since we stacked the signal on a 64-bit boundary,
224 * then 'sp' should be word aligned here. If it's
225 * not, then the user is trying to mess with us.
226 */
227 if (regs->ARM_sp & 7)
228 goto badframe;
229
230 frame = (struct rt_sigframe *)regs->ARM_sp;
231
232 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
233 goto badframe;
234 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
235 goto badframe;
236
237 sigdelsetmask(&set, ~_BLOCKABLE);
238 spin_lock_irq(&current->sighand->siglock);
239 current->blocked = set;
240 recalc_sigpending();
241 spin_unlock_irq(&current->sighand->siglock);
242
243 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
244 goto badframe;
245
246 /* Send SIGTRAP if we're single-stepping */
247 if (current->ptrace & PT_SINGLESTEP) {
248 ptrace_cancel_bpt(current);
249 send_sig(SIGTRAP, current, 1);
250 }
251
252 return regs->ARM_r0;
253
254badframe:
255 force_sig(SIGSEGV, current);
256 return 0;
257}
258
259static int
260setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
261 struct pt_regs *regs, unsigned long mask)
262{
263 int err = 0;
264
265 __put_user_error(regs->ARM_r0, &sc->arm_r0, err);
266 __put_user_error(regs->ARM_r1, &sc->arm_r1, err);
267 __put_user_error(regs->ARM_r2, &sc->arm_r2, err);
268 __put_user_error(regs->ARM_r3, &sc->arm_r3, err);
269 __put_user_error(regs->ARM_r4, &sc->arm_r4, err);
270 __put_user_error(regs->ARM_r5, &sc->arm_r5, err);
271 __put_user_error(regs->ARM_r6, &sc->arm_r6, err);
272 __put_user_error(regs->ARM_r7, &sc->arm_r7, err);
273 __put_user_error(regs->ARM_r8, &sc->arm_r8, err);
274 __put_user_error(regs->ARM_r9, &sc->arm_r9, err);
275 __put_user_error(regs->ARM_r10, &sc->arm_r10, err);
276 __put_user_error(regs->ARM_fp, &sc->arm_fp, err);
277 __put_user_error(regs->ARM_ip, &sc->arm_ip, err);
278 __put_user_error(regs->ARM_sp, &sc->arm_sp, err);
279 __put_user_error(regs->ARM_lr, &sc->arm_lr, err);
280 __put_user_error(regs->ARM_pc, &sc->arm_pc, err);
281
282 __put_user_error(current->thread.trap_no, &sc->trap_no, err);
283 __put_user_error(current->thread.error_code, &sc->error_code, err);
284 __put_user_error(current->thread.address, &sc->fault_address, err);
285 __put_user_error(mask, &sc->oldmask, err);
286
287 return err;
288}
289
290static inline void *
291get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
292{
293 unsigned long sp = regs->ARM_sp;
294
295 /*
296 * This is the X/Open sanctioned signal stack switching.
297 */
298 if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
299 sp = current->sas_ss_sp + current->sas_ss_size;
300
301 /*
302 * ATPCS B01 mandates 8-byte alignment
303 */
304 return (void *)((sp - framesize) & ~7);
305}
306
307static int
308setup_return(struct pt_regs *regs, struct k_sigaction *ka,
309 unsigned long *rc, void *frame, int usig)
310{
311 unsigned long handler = (unsigned long)ka->sa.sa_handler;
312 unsigned long retcode;
313
314 if (ka->sa.sa_flags & SA_RESTORER) {
315 retcode = (unsigned long)ka->sa.sa_restorer;
316 } else {
317
318 if (__put_user((ka->sa.sa_flags & SA_SIGINFO)?SWI_SYS_RT_SIGRETURN:SWI_SYS_SIGRETURN, rc))
319 return 1;
320
321 retcode = ((unsigned long)rc);
322 }
323
324 regs->ARM_r0 = usig;
325 regs->ARM_sp = (unsigned long)frame;
326 regs->ARM_lr = retcode;
327 regs->ARM_pc = handler & ~3;
328
329 return 0;
330}
331
332static int
333setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs)
334{
335 struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
336 int err = 0;
337
338 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
339 return 1;
340
341 err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
342
343 if (_NSIG_WORDS > 1) {
344 err |= __copy_to_user(frame->extramask, &set->sig[1],
345 sizeof(frame->extramask));
346 }
347
348 if (err == 0)
349 err = setup_return(regs, ka, &frame->retcode, frame, usig);
350
351 return err;
352}
353
354static int
355setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
356 sigset_t *set, struct pt_regs *regs)
357{
358 struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
359 int err = 0;
360
361 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
362 return 1;
363
364 __put_user_error(&frame->info, &frame->pinfo, err);
365 __put_user_error(&frame->uc, &frame->puc, err);
366 err |= copy_siginfo_to_user(&frame->info, info);
367
368 /* Clear all the bits of the ucontext we don't use. */
369 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
370
371 err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
372 regs, set->sig[0]);
373 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
374
375 if (err == 0)
376 err = setup_return(regs, ka, &frame->retcode, frame, usig);
377
378 if (err == 0) {
379 /*
380 * For realtime signals we must also set the second and third
381 * arguments for the signal handler.
382 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
383 */
384 regs->ARM_r1 = (unsigned long)frame->pinfo;
385 regs->ARM_r2 = (unsigned long)frame->puc;
386 }
387
388 return err;
389}
390
391static inline void restart_syscall(struct pt_regs *regs)
392{
393 regs->ARM_r0 = regs->ARM_ORIG_r0;
394 regs->ARM_pc -= 4;
395}
396
397/*
398 * OK, we're invoking a handler
399 */
400static void
401handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
402 struct pt_regs * regs, int syscall)
403{
404 struct thread_info *thread = current_thread_info();
405 struct task_struct *tsk = current;
406 struct k_sigaction *ka = &tsk->sighand->action[sig-1];
407 int usig = sig;
408 int ret;
409
410 /*
411 * If we were from a system call, check for system call restarting...
412 */
413 if (syscall) {
414 switch (regs->ARM_r0) {
415 case -ERESTART_RESTARTBLOCK:
416 current_thread_info()->restart_block.fn =
417 do_no_restart_syscall;
418 case -ERESTARTNOHAND:
419 regs->ARM_r0 = -EINTR;
420 break;
421 case -ERESTARTSYS:
422 if (!(ka->sa.sa_flags & SA_RESTART)) {
423 regs->ARM_r0 = -EINTR;
424 break;
425 }
426 /* fallthrough */
427 case -ERESTARTNOINTR:
428 restart_syscall(regs);
429 }
430 }
431
432 /*
433 * translate the signal
434 */
435 if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
436 usig = thread->exec_domain->signal_invmap[usig];
437
438 /*
439 * Set up the stack frame
440 */
441 if (ka->sa.sa_flags & SA_SIGINFO)
442 ret = setup_rt_frame(usig, ka, info, oldset, regs);
443 else
444 ret = setup_frame(usig, ka, oldset, regs);
445
446 /*
447 * Check that the resulting registers are actually sane.
448 */
449 ret |= !valid_user_regs(regs);
450
451 if (ret == 0) {
452 if (ka->sa.sa_flags & SA_ONESHOT)
453 ka->sa.sa_handler = SIG_DFL;
454
455 spin_lock_irq(&tsk->sighand->siglock);
456 sigorsets(&tsk->blocked, &tsk->blocked,
457 &ka->sa.sa_mask);
458 if (!(ka->sa.sa_flags & SA_NODEFER))
459 sigaddset(&tsk->blocked, sig);
460 recalc_sigpending();
461 spin_unlock_irq(&tsk->sighand->siglock);
462 return;
463 }
464
465 force_sigsegv(sig, tsk);
466}
467
468/*
469 * Note that 'init' is a special process: it doesn't get signals it doesn't
470 * want to handle. Thus you cannot kill init even with a SIGKILL even by
471 * mistake.
472 *
473 * Note that we go through the signals twice: once to check the signals that
474 * the kernel can handle, and then we build all the user-level signal handling
475 * stack-frames in one go after that.
476 */
477static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
478{
479 siginfo_t info;
480 int signr;
481 struct k_sigaction ka;
482
483 /*
484 * We want the common case to go fast, which
485 * is why we may in certain cases get here from
486 * kernel mode. Just return without doing anything
487 * if so.
488 */
489 if (!user_mode(regs))
490 return 0;
491
492 if (current->ptrace & PT_SINGLESTEP)
493 ptrace_cancel_bpt(current);
494
495 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
496 if (signr > 0) {
497 handle_signal(signr, &info, oldset, regs, syscall);
498 if (current->ptrace & PT_SINGLESTEP)
499 ptrace_set_bpt(current);
500 return 1;
501 }
502
503 /*
504 * No signal to deliver to the process - restart the syscall.
505 */
506 if (syscall) {
507 if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
508 u32 *usp;
509
510 regs->ARM_sp -= 12;
511 usp = (u32 *)regs->ARM_sp;
512
513 put_user(regs->ARM_pc, &usp[0]);
514 /* swi __NR_restart_syscall */
515 put_user(0xef000000 | __NR_restart_syscall, &usp[1]);
516 /* ldr pc, [sp], #12 */
517// FIXME!!! is #12 correct there?
518 put_user(0xe49df00c, &usp[2]);
519
520 regs->ARM_pc = regs->ARM_sp + 4;
521 }
522 if (regs->ARM_r0 == -ERESTARTNOHAND ||
523 regs->ARM_r0 == -ERESTARTSYS ||
524 regs->ARM_r0 == -ERESTARTNOINTR) {
525 restart_syscall(regs);
526 }
527 }
528 if (current->ptrace & PT_SINGLESTEP)
529 ptrace_set_bpt(current);
530 return 0;
531}
532
533asmlinkage void
534do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
535{
536 if (thread_flags & _TIF_SIGPENDING)
537 do_signal(&current->blocked, regs, syscall);
538}
diff --git a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c
deleted file mode 100644
index dc05aba58baf..000000000000
--- a/arch/arm26/kernel/sys_arm.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/sys_arm.c
3 *
4 * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
5 * Copyright (C) 1995, 1996 Russell King.
6 * Copyright (C) 2003 Ian Molton.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This file contains various random system calls that
13 * have a non-standard calling sequence on the Linux/arm
14 * platform.
15 */
16#include <linux/module.h>
17#include <linux/errno.h>
18#include <linux/sched.h>
19#include <linux/slab.h>
20#include <linux/mm.h>
21#include <linux/sem.h>
22#include <linux/msg.h>
23#include <linux/shm.h>
24#include <linux/stat.h>
25#include <linux/syscalls.h>
26#include <linux/mman.h>
27#include <linux/fs.h>
28#include <linux/file.h>
29#include <linux/utsname.h>
30
31#include <asm/uaccess.h>
32#include <asm/ipc.h>
33
34extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
35 unsigned long new_len, unsigned long flags,
36 unsigned long new_addr);
37
38/*
39 * sys_pipe() is the normal C calling standard for creating
40 * a pipe. It's not the way unix traditionally does this, though.
41 */
42asmlinkage int sys_pipe(unsigned long * fildes)
43{
44 int fd[2];
45 int error;
46
47 error = do_pipe(fd);
48 if (!error) {
49 if (copy_to_user(fildes, fd, 2*sizeof(int)))
50 error = -EFAULT;
51 }
52 return error;
53}
54
55/* common code for old and new mmaps */
56inline long do_mmap2(
57 unsigned long addr, unsigned long len,
58 unsigned long prot, unsigned long flags,
59 unsigned long fd, unsigned long pgoff)
60{
61 int error = -EINVAL;
62 struct file * file = NULL;
63
64 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
65
66 /*
67 * If we are doing a fixed mapping, and address < FIRST_USER_ADDRESS,
68 * then deny it.
69 */
70 if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
71 goto out;
72
73 error = -EBADF;
74 if (!(flags & MAP_ANONYMOUS)) {
75 file = fget(fd);
76 if (!file)
77 goto out;
78 }
79
80 down_write(&current->mm->mmap_sem);
81 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
82 up_write(&current->mm->mmap_sem);
83
84 if (file)
85 fput(file);
86out:
87 return error;
88}
89
90struct mmap_arg_struct {
91 unsigned long addr;
92 unsigned long len;
93 unsigned long prot;
94 unsigned long flags;
95 unsigned long fd;
96 unsigned long offset;
97};
98
99asmlinkage int old_mmap(struct mmap_arg_struct *arg)
100{
101 int error = -EFAULT;
102 struct mmap_arg_struct a;
103
104 if (copy_from_user(&a, arg, sizeof(a)))
105 goto out;
106
107 error = -EINVAL;
108 if (a.offset & ~PAGE_MASK)
109 goto out;
110
111 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
112out:
113 return error;
114}
115
116asmlinkage unsigned long
117sys_arm_mremap(unsigned long addr, unsigned long old_len,
118 unsigned long new_len, unsigned long flags,
119 unsigned long new_addr)
120{
121 unsigned long ret = -EINVAL;
122
123 /*
124 * If we are doing a fixed mapping, and address < FIRST_USER_ADDRESS,
125 * then deny it.
126 */
127 if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
128 goto out;
129
130 down_write(&current->mm->mmap_sem);
131 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
132 up_write(&current->mm->mmap_sem);
133
134out:
135 return ret;
136}
137
138/*
139 * Perform the select(nd, in, out, ex, tv) and mmap() system
140 * calls.
141 */
142
143struct sel_arg_struct {
144 unsigned long n;
145 fd_set *inp, *outp, *exp;
146 struct timeval *tvp;
147};
148
149asmlinkage int old_select(struct sel_arg_struct *arg)
150{
151 struct sel_arg_struct a;
152
153 if (copy_from_user(&a, arg, sizeof(a)))
154 return -EFAULT;
155 /* sys_select() does the appropriate kernel locking */
156 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
157}
158
159/*
160 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
161 *
162 * This is really horribly ugly.
163 */
164asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
165{
166 int version, ret;
167
168 version = call >> 16; /* hack for backward compatibility */
169 call &= 0xffff;
170
171 switch (call) {
172 case SEMOP:
173 return sys_semop (first, (struct sembuf *)ptr, second);
174 case SEMGET:
175 return sys_semget (first, second, third);
176 case SEMCTL: {
177 union semun fourth;
178 if (!ptr)
179 return -EINVAL;
180 if (get_user(fourth.__pad, (void **) ptr))
181 return -EFAULT;
182 return sys_semctl (first, second, third, fourth);
183 }
184
185 case MSGSND:
186 return sys_msgsnd (first, (struct msgbuf *) ptr,
187 second, third);
188 case MSGRCV:
189 switch (version) {
190 case 0: {
191 struct ipc_kludge tmp;
192 if (!ptr)
193 return -EINVAL;
194 if (copy_from_user(&tmp,(struct ipc_kludge *) ptr,
195 sizeof (tmp)))
196 return -EFAULT;
197 return sys_msgrcv (first, tmp.msgp, second,
198 tmp.msgtyp, third);
199 }
200 default:
201 return sys_msgrcv (first,
202 (struct msgbuf *) ptr,
203 second, fifth, third);
204 }
205 case MSGGET:
206 return sys_msgget ((key_t) first, second);
207 case MSGCTL:
208 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
209
210 case SHMAT:
211 switch (version) {
212 default: {
213 ulong raddr;
214 ret = do_shmat (first, (char *) ptr, second, &raddr);
215 if (ret)
216 return ret;
217 return put_user (raddr, (ulong *) third);
218 }
219 case 1: /* iBCS2 emulator entry point */
220 if (!segment_eq(get_fs(), get_ds()))
221 return -EINVAL;
222 return do_shmat (first, (char *) ptr,
223 second, (ulong *) third);
224 }
225 case SHMDT:
226 return sys_shmdt ((char *)ptr);
227 case SHMGET:
228 return sys_shmget (first, second, third);
229 case SHMCTL:
230 return sys_shmctl (first, second,
231 (struct shmid_ds *) ptr);
232 default:
233 return -EINVAL;
234 }
235}
236
237/* Fork a new task - this creates a new program thread.
238 * This is called indirectly via a small wrapper
239 */
240asmlinkage int sys_fork(struct pt_regs *regs)
241{
242 return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
243}
244
245/* Clone a task - this clones the calling program thread.
246 * This is called indirectly via a small wrapper
247 */
248asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
249{
250 /*
251 * We don't support SETTID / CLEARTID (FIXME!!! (nicked from arm32))
252 */
253 if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID))
254 return -EINVAL;
255
256 if (!newsp)
257 newsp = regs->ARM_sp;
258
259 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
260}
261
262asmlinkage int sys_vfork(struct pt_regs *regs)
263{
264 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
265}
266
267/* sys_execve() executes a new program.
268 * This is called indirectly via a small wrapper
269 */
270asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_regs *regs)
271{
272 int error;
273 char * filename;
274
275 filename = getname(filenamei);
276 error = PTR_ERR(filename);
277 if (IS_ERR(filename))
278 goto out;
279 error = do_execve(filename, argv, envp, regs);
280 putname(filename);
281out:
282 return error;
283}
284
285/* FIXME - see if this is correct for arm26 */
286int kernel_execve(const char *filename, char *const argv[], char *const envp[])
287{
288 struct pt_regs regs;
289 int ret;
290 memset(&regs, 0, sizeof(struct pt_regs));
291 ret = do_execve((char *)filename, (char __user * __user *)argv, (char __user * __user *)envp, &regs);
292 if (ret < 0)
293 goto out;
294
295 /*
296 * Save argc to the register structure for userspace.
297 */
298 regs.ARM_r0 = ret;
299
300 /*
301 * We were successful. We won't be returning to our caller, but
302 * instead to user space by manipulating the kernel stack.
303 */
304 asm( "add r0, %0, %1\n\t"
305 "mov r1, %2\n\t"
306 "mov r2, %3\n\t"
307 "bl memmove\n\t" /* copy regs to top of stack */
308 "mov r8, #0\n\t" /* not a syscall */
309 "mov r9, %0\n\t" /* thread structure */
310 "mov sp, r0\n\t" /* reposition stack pointer */
311 "b ret_to_user"
312 :
313 : "r" (current_thread_info()),
314 "Ir" (THREAD_SIZE - 8 - sizeof(regs)),
315 "r" (&regs),
316 "Ir" (sizeof(regs))
317 : "r0", "r1", "r2", "r3", "ip", "memory");
318
319 out:
320 return ret;
321}
322
323EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
deleted file mode 100644
index 0f1d57fbd3d7..000000000000
--- a/arch/arm26/kernel/time.c
+++ /dev/null
@@ -1,210 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 * Modifications for ARM (C) 1994-2001 Russell King
6 * Mods for ARM26 (C) 2003 Ian Molton
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This file contains the ARM-specific time handling details:
13 * reading the RTC at bootup, etc...
14 *
15 * 1994-07-02 Alan Modra
16 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
17 * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
18 * "A Kernel Model for Precision Timekeeping" by Dave Mills
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/time.h>
25#include <linux/init.h>
26#include <linux/smp.h>
27#include <linux/timex.h>
28#include <linux/errno.h>
29#include <linux/profile.h>
30
31#include <asm/hardware.h>
32#include <asm/io.h>
33#include <asm/irq.h>
34#include <asm/ioc.h>
35
36/* this needs a better home */
37DEFINE_SPINLOCK(rtc_lock);
38
39/* change this if you have some constant time drift */
40#define USECS_PER_JIFFY (1000000/HZ)
41
42static int dummy_set_rtc(void)
43{
44 return 0;
45}
46
47/*
48 * hook for setting the RTC's idea of the current time.
49 */
50int (*set_rtc)(void) = dummy_set_rtc;
51
52/*
53 * Get time offset based on IOCs timer.
54 * FIXME - if this is called with interrutps off, why the shennanigans
55 * below ?
56 */
57static unsigned long gettimeoffset(void)
58{
59 unsigned int count1, count2, status;
60 long offset;
61
62 ioc_writeb (0, IOC_T0LATCH);
63 barrier ();
64 count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
65 barrier ();
66 status = ioc_readb(IOC_IRQREQA);
67 barrier ();
68 ioc_writeb (0, IOC_T0LATCH);
69 barrier ();
70 count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
71
72 offset = count2;
73 if (count2 < count1) {
74 /*
75 * We have not had an interrupt between reading count1
76 * and count2.
77 */
78 if (status & (1 << 5))
79 offset -= LATCH;
80 } else if (count2 > count1) {
81 /*
82 * We have just had another interrupt between reading
83 * count1 and count2.
84 */
85 offset -= LATCH;
86 }
87
88 offset = (LATCH - offset) * (tick_nsec / 1000);
89 return (offset + LATCH/2) / LATCH;
90}
91
92static unsigned long next_rtc_update;
93
94/*
95 * If we have an externally synchronized linux clock, then update
96 * CMOS clock accordingly every ~11 minutes. set_rtc() has to be
97 * called as close as possible to 500 ms before the new second
98 * starts.
99 */
100static inline void do_set_rtc(void)
101{
102 if (!ntp_synced() || set_rtc == NULL)
103 return;
104
105//FIXME - timespec.tv_sec is a time_t not unsigned long
106 if (next_rtc_update &&
107 time_before((unsigned long)xtime.tv_sec, next_rtc_update))
108 return;
109
110 if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
111 xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
112 return;
113
114 if (set_rtc())
115 /*
116 * rtc update failed. Try again in 60s
117 */
118 next_rtc_update = xtime.tv_sec + 60;
119 else
120 next_rtc_update = xtime.tv_sec + 660;
121}
122
123#define do_leds()
124
125void do_gettimeofday(struct timeval *tv)
126{
127 unsigned long flags;
128 unsigned long seq;
129 unsigned long usec, sec;
130
131 do {
132 seq = read_seqbegin_irqsave(&xtime_lock, flags);
133 usec = gettimeoffset();
134 sec = xtime.tv_sec;
135 usec += xtime.tv_nsec / 1000;
136 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
137
138 /* usec may have gone up a lot: be safe */
139 while (usec >= 1000000) {
140 usec -= 1000000;
141 sec++;
142 }
143
144 tv->tv_sec = sec;
145 tv->tv_usec = usec;
146}
147
148EXPORT_SYMBOL(do_gettimeofday);
149
150int do_settimeofday(struct timespec *tv)
151{
152 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
153 return -EINVAL;
154
155 write_seqlock_irq(&xtime_lock);
156 /*
157 * This is revolting. We need to set "xtime" correctly. However, the
158 * value in this location is the value at the most recent update of
159 * wall time. Discover what correction gettimeofday() would have
160 * done, and then undo it!
161 */
162 tv->tv_nsec -= 1000 * gettimeoffset();
163
164 while (tv->tv_nsec < 0) {
165 tv->tv_nsec += NSEC_PER_SEC;
166 tv->tv_sec--;
167 }
168
169 xtime.tv_sec = tv->tv_sec;
170 xtime.tv_nsec = tv->tv_nsec;
171 ntp_clear();
172 write_sequnlock_irq(&xtime_lock);
173 clock_was_set();
174 return 0;
175}
176
177EXPORT_SYMBOL(do_settimeofday);
178
179static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
180{
181 do_timer(1);
182#ifndef CONFIG_SMP
183 update_process_times(user_mode(regs));
184#endif
185 do_set_rtc(); //FIME - EVERY timer IRQ?
186 profile_tick(CPU_PROFILING, regs);
187 return IRQ_HANDLED; //FIXME - is this right?
188}
189
190static struct irqaction timer_irq = {
191 .name = "timer",
192 .flags = IRQF_DISABLED,
193 .handler = timer_interrupt,
194};
195
196extern void ioctime_init(void);
197
198/*
199 * Set up timer interrupt.
200 */
201void __init time_init(void)
202{
203 ioc_writeb(LATCH & 255, IOC_T0LTCHL);
204 ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
205 ioc_writeb(0, IOC_T0GO);
206
207
208 setup_irq(IRQ_TIMER, &timer_irq);
209}
210
diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c
deleted file mode 100644
index 2911e2eae80e..000000000000
--- a/arch/arm26/kernel/traps.c
+++ /dev/null
@@ -1,548 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/traps.c
3 *
4 * Copyright (C) 1995-2002 Russell King
5 * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
6 * Copyright (C) 2003 Ian Molton (ARM26)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * 'traps.c' handles hardware exceptions after we have saved some state in
13 * 'linux/arch/arm26/lib/traps.S'. Mostly a debugging aid, but will probably
14 * kill the offending process.
15 */
16
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/signal.h>
21#include <linux/sched.h>
22#include <linux/mm.h>
23#include <linux/spinlock.h>
24#include <linux/personality.h>
25#include <linux/ptrace.h>
26#include <linux/elf.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29
30#include <asm/atomic.h>
31#include <asm/io.h>
32#include <asm/pgtable.h>
33#include <asm/system.h>
34#include <asm/uaccess.h>
35#include <asm/unistd.h>
36#include <linux/mutex.h>
37
38#include "ptrace.h"
39
40extern void c_backtrace (unsigned long fp, int pmode);
41extern void show_pte(struct mm_struct *mm, unsigned long addr);
42
43const char *processor_modes[] = { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" };
44
45static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" "*bad reason*"};
46
47/*
48 * Stack pointers should always be within the kernels view of
49 * physical memory. If it is not there, then we can't dump
50 * out any information relating to the stack.
51 */
52static int verify_stack(unsigned long sp)
53{
54 if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0))
55 return -EFAULT;
56
57 return 0;
58}
59
60/*
61 * Dump out the contents of some memory nicely...
62 */
63static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
64{
65 unsigned long p = bottom & ~31;
66 mm_segment_t fs;
67 int i;
68
69 /*
70 * We need to switch to kernel mode so that we can use __get_user
71 * to safely read from kernel space. Note that we now dump the
72 * code first, just in case the backtrace kills us.
73 */
74 fs = get_fs();
75 set_fs(KERNEL_DS);
76
77 printk("%s", str);
78 printk("(0x%08lx to 0x%08lx)\n", bottom, top);
79
80 for (p = bottom & ~31; p < top;) {
81 printk("%04lx: ", p & 0xffff);
82
83 for (i = 0; i < 8; i++, p += 4) {
84 unsigned int val;
85
86 if (p < bottom || p >= top)
87 printk(" ");
88 else {
89 __get_user(val, (unsigned long *)p);
90 printk("%08x ", val);
91 }
92 }
93 printk ("\n");
94 }
95
96 set_fs(fs);
97}
98
99static void dump_instr(struct pt_regs *regs)
100{
101 unsigned long addr = instruction_pointer(regs);
102 const int width = 8;
103 mm_segment_t fs;
104 int i;
105
106 /*
107 * We need to switch to kernel mode so that we can use __get_user
108 * to safely read from kernel space. Note that we now dump the
109 * code first, just in case the backtrace kills us.
110 */
111 fs = get_fs();
112 set_fs(KERNEL_DS);
113
114 printk("Code: ");
115 for (i = -4; i < 1; i++) {
116 unsigned int val, bad;
117
118 bad = __get_user(val, &((u32 *)addr)[i]);
119
120 if (!bad)
121 printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
122 else {
123 printk("bad PC value.");
124 break;
125 }
126 }
127 printk("\n");
128
129 set_fs(fs);
130}
131
132/*static*/ void __dump_stack(struct task_struct *tsk, unsigned long sp)
133{
134 dump_mem("Stack: ", sp, 8192+(unsigned long)task_stack_page(tsk));
135}
136
137void dump_stack(void)
138{
139#ifdef CONFIG_DEBUG_ERRORS
140 __backtrace();
141#endif
142}
143
144EXPORT_SYMBOL(dump_stack);
145
146//FIXME - was a static fn
147void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
148{
149 unsigned int fp;
150 int ok = 1;
151
152 printk("Backtrace: ");
153 fp = regs->ARM_fp;
154 if (!fp) {
155 printk("no frame pointer");
156 ok = 0;
157 } else if (verify_stack(fp)) {
158 printk("invalid frame pointer 0x%08x", fp);
159 ok = 0;
160 } else if (fp < (unsigned long)end_of_stack(tsk))
161 printk("frame pointer underflow");
162 printk("\n");
163
164 if (ok)
165 c_backtrace(fp, processor_mode(regs));
166}
167
168/* FIXME - this is probably wrong.. */
169void show_stack(struct task_struct *task, unsigned long *sp) {
170 dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task_stack_page(task));
171}
172
173DEFINE_SPINLOCK(die_lock);
174
175/*
176 * This function is protected against re-entrancy.
177 */
178NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
179{
180 struct task_struct *tsk = current;
181
182 console_verbose();
183 spin_lock_irq(&die_lock);
184
185 printk("Internal error: %s: %x\n", str, err);
186 printk("CPU: %d\n", smp_processor_id());
187 show_regs(regs);
188 add_taint(TAINT_DIE);
189 printk("Process %s (pid: %d, stack limit = 0x%p)\n",
190 current->comm, current->pid, end_of_stack(tsk));
191
192 if (!user_mode(regs) || in_interrupt()) {
193 __dump_stack(tsk, (unsigned long)(regs + 1));
194 dump_backtrace(regs, tsk);
195 dump_instr(regs);
196 }
197while(1);
198 spin_unlock_irq(&die_lock);
199 do_exit(SIGSEGV);
200}
201
202void die_if_kernel(const char *str, struct pt_regs *regs, int err)
203{
204 if (user_mode(regs))
205 return;
206
207 die(str, regs, err);
208}
209
210static DEFINE_MUTEX(undef_mutex);
211static int (*undef_hook)(struct pt_regs *);
212
213int request_undef_hook(int (*fn)(struct pt_regs *))
214{
215 int ret = -EBUSY;
216
217 mutex_lock(&undef_mutex);
218 if (undef_hook == NULL) {
219 undef_hook = fn;
220 ret = 0;
221 }
222 mutex_unlock(&undef_mutex);
223
224 return ret;
225}
226
227int release_undef_hook(int (*fn)(struct pt_regs *))
228{
229 int ret = -EINVAL;
230
231 mutex_lock(&undef_mutex);
232 if (undef_hook == fn) {
233 undef_hook = NULL;
234 ret = 0;
235 }
236 mutex_unlock(&undef_mutex);
237
238 return ret;
239}
240
241static int undefined_extension(struct pt_regs *regs, unsigned int op)
242{
243 switch (op) {
244 case 1: /* 0xde01 / 0x?7f001f0 */
245 ptrace_break(current, regs);
246 return 0;
247 }
248 return 1;
249}
250
251asmlinkage void do_undefinstr(struct pt_regs *regs)
252{
253 siginfo_t info;
254 void *pc;
255
256 regs->ARM_pc -= 4;
257
258 pc = (unsigned long *)instruction_pointer(regs); /* strip PSR */
259
260 if (user_mode(regs)) {
261 u32 instr;
262
263 get_user(instr, (u32 *)pc);
264
265 if ((instr & 0x0fff00ff) == 0x07f000f0 &&
266 undefined_extension(regs, (instr >> 8) & 255) == 0) {
267 regs->ARM_pc += 4;
268 return;
269 }
270 } else {
271 if (undef_hook && undef_hook(regs) == 0) {
272 regs->ARM_pc += 4;
273 return;
274 }
275 }
276
277#ifdef CONFIG_DEBUG_USER
278 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
279 current->comm, current->pid, pc);
280 dump_instr(regs);
281#endif
282
283 current->thread.error_code = 0;
284 current->thread.trap_no = 6;
285
286 info.si_signo = SIGILL;
287 info.si_errno = 0;
288 info.si_code = ILL_ILLOPC;
289 info.si_addr = pc;
290
291 force_sig_info(SIGILL, &info, current);
292
293 die_if_kernel("Oops - undefined instruction", regs, 0);
294}
295
296asmlinkage void do_excpt(unsigned long address, struct pt_regs *regs, int mode)
297{
298 siginfo_t info;
299
300#ifdef CONFIG_DEBUG_USER
301 printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
302 current->comm, current->pid, instruction_pointer(regs));
303 dump_instr(regs);
304#endif
305
306 current->thread.error_code = 0;
307 current->thread.trap_no = 11;
308
309 info.si_signo = SIGBUS;
310 info.si_errno = 0;
311 info.si_code = BUS_ADRERR;
312 info.si_addr = (void *)address;
313
314 force_sig_info(SIGBUS, &info, current);
315
316 die_if_kernel("Oops - address exception", regs, mode);
317}
318
319asmlinkage void do_unexp_fiq (struct pt_regs *regs)
320{
321#ifndef CONFIG_IGNORE_FIQ
322 printk("Hmm. Unexpected FIQ received, but trying to continue\n");
323 printk("You may have a hardware problem...\n");
324#endif
325}
326
327/*
328 * bad_mode handles the impossible case in the vectors. If you see one of
329 * these, then it's extremely serious, and could mean you have buggy hardware.
330 * It never returns, and never tries to sync. We hope that we can at least
331 * dump out some state information...
332 */
333asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
334{
335 unsigned int vectors = vectors_base();
336
337 console_verbose();
338
339 printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
340 handler[reason<5?reason:4], processor_modes[proc_mode]);
341
342 /*
343 * Dump out the vectors and stub routines. Maybe a better solution
344 * would be to dump them out only if we detect that they are corrupted.
345 */
346 dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
347 dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
348
349 die("Oops", regs, 0);
350 local_irq_disable();
351 panic("bad mode");
352}
353
354static int bad_syscall(int n, struct pt_regs *regs)
355{
356 struct thread_info *thread = current_thread_info();
357 siginfo_t info;
358
359 if (current->personality != PER_LINUX && thread->exec_domain->handler) {
360 thread->exec_domain->handler(n, regs);
361 return regs->ARM_r0;
362 }
363
364#ifdef CONFIG_DEBUG_USER
365 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
366 current->pid, current->comm, n);
367 dump_instr(regs);
368#endif
369
370 info.si_signo = SIGILL;
371 info.si_errno = 0;
372 info.si_code = ILL_ILLTRP;
373 info.si_addr = (void *)instruction_pointer(regs) - 4;
374
375 force_sig_info(SIGILL, &info, current);
376 die_if_kernel("Oops", regs, n);
377 return regs->ARM_r0;
378}
379
380static inline void
381do_cache_op(unsigned long start, unsigned long end, int flags)
382{
383 struct vm_area_struct *vma;
384
385 if (end < start)
386 return;
387
388 vma = find_vma(current->active_mm, start);
389 if (vma && vma->vm_start < end) {
390 if (start < vma->vm_start)
391 start = vma->vm_start;
392 if (end > vma->vm_end)
393 end = vma->vm_end;
394 }
395}
396
397/*
398 * Handle all unrecognised system calls.
399 * 0x9f0000 - 0x9fffff are some more esoteric system calls
400 */
401#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
402asmlinkage int arm_syscall(int no, struct pt_regs *regs)
403{
404 siginfo_t info;
405
406 if ((no >> 16) != 0x9f)
407 return bad_syscall(no, regs);
408
409 switch (no & 0xffff) {
410 case 0: /* branch through 0 */
411 info.si_signo = SIGSEGV;
412 info.si_errno = 0;
413 info.si_code = SEGV_MAPERR;
414 info.si_addr = NULL;
415
416 force_sig_info(SIGSEGV, &info, current);
417
418 die_if_kernel("branch through zero", regs, 0);
419 return 0;
420
421 case NR(breakpoint): /* SWI BREAK_POINT */
422 ptrace_break(current, regs);
423 return regs->ARM_r0;
424
425 case NR(cacheflush):
426 return 0;
427
428 case NR(usr26):
429 break;
430
431 default:
432 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
433 if not implemented, rather than raising SIGILL. This
434 way the calling program can gracefully determine whether
435 a feature is supported. */
436 if (no <= 0x7ff)
437 return -ENOSYS;
438 break;
439 }
440#ifdef CONFIG_DEBUG_USER
441 /*
442 * experience shows that these seem to indicate that
443 * something catastrophic has happened
444 */
445 printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
446 dump_instr(regs);
447 if (user_mode(regs)) {
448 show_regs(regs);
449 c_backtrace(regs->ARM_fp, processor_mode(regs));
450 }
451#endif
452 info.si_signo = SIGILL;
453 info.si_errno = 0;
454 info.si_code = ILL_ILLTRP;
455 info.si_addr = (void *)instruction_pointer(regs) - 4;
456
457 force_sig_info(SIGILL, &info, current);
458 die_if_kernel("Oops", regs, no);
459 return 0;
460}
461
462void __bad_xchg(volatile void *ptr, int size)
463{
464 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
465 __builtin_return_address(0), ptr, size);
466 BUG();
467}
468
469/*
470 * A data abort trap was taken, but we did not handle the instruction.
471 * Try to abort the user program, or panic if it was the kernel.
472 */
473asmlinkage void
474baddataabort(int code, unsigned long instr, struct pt_regs *regs)
475{
476 unsigned long addr = instruction_pointer(regs);
477 siginfo_t info;
478
479#ifdef CONFIG_DEBUG_USER
480 printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
481 current->pid, current->comm, code, instr);
482 dump_instr(regs);
483 show_pte(current->mm, addr);
484#endif
485
486 info.si_signo = SIGILL;
487 info.si_errno = 0;
488 info.si_code = ILL_ILLOPC;
489 info.si_addr = (void *)addr;
490
491 force_sig_info(SIGILL, &info, current);
492 die_if_kernel("unknown data abort code", regs, instr);
493}
494
495volatile void __bug(const char *file, int line, void *data)
496{
497 printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
498 if (data)
499 printk(KERN_CRIT" - extra data = %p", data);
500 printk("\n");
501 *(int *)0 = 0;
502}
503
504void __readwrite_bug(const char *fn)
505{
506 printk("%s called, but not implemented", fn);
507 BUG();
508}
509
510void __pte_error(const char *file, int line, unsigned long val)
511{
512 printk("%s:%d: bad pte %08lx.\n", file, line, val);
513}
514
515void __pmd_error(const char *file, int line, unsigned long val)
516{
517 printk("%s:%d: bad pmd %08lx.\n", file, line, val);
518}
519
520void __pgd_error(const char *file, int line, unsigned long val)
521{
522 printk("%s:%d: bad pgd %08lx.\n", file, line, val);
523}
524
525asmlinkage void __div0(void)
526{
527 printk("Division by zero in kernel.\n");
528 dump_stack();
529}
530
531void abort(void)
532{
533 BUG();
534
535 /* if that doesn't kill us, halt */
536 panic("Oops failed to kill thread");
537}
538
539void __init trap_init(void)
540{
541 extern void __trap_init(unsigned long);
542 unsigned long base = vectors_base();
543
544 __trap_init(base);
545 if (base != 0)
546 printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
547 base);
548}
diff --git a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
deleted file mode 100644
index 4ec715c25dea..000000000000
--- a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
+++ /dev/null
@@ -1,136 +0,0 @@
1/* ld script to make ARM Linux kernel
2 * taken from the i386 version by Russell King
3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
4 * borrowed from Russels ARM port by Ian Molton
5 */
6
7#include <asm-generic/vmlinux.lds.h>
8
9OUTPUT_ARCH(arm)
10ENTRY(stext)
11jiffies = jiffies_64;
12SECTIONS
13{
14 . = TEXTADDR;
15 .init : { /* Init code and data */
16 _stext = .;
17 __init_begin = .;
18 _sinittext = .;
19 *(.init.text)
20 _einittext = .;
21 __proc_info_begin = .;
22 *(.proc.info)
23 __proc_info_end = .;
24 __arch_info_begin = .;
25 *(.arch.info)
26 __arch_info_end = .;
27 __tagtable_begin = .;
28 *(.taglist)
29 __tagtable_end = .;
30 . = ALIGN(16);
31 __setup_start = .;
32 *(.init.setup)
33 __setup_end = .;
34 __early_begin = .;
35 *(__early_param)
36 __early_end = .;
37 __initcall_start = .;
38 *(.initcall1.init)
39 *(.initcall2.init)
40 *(.initcall3.init)
41 *(.initcall4.init)
42 *(.initcall5.init)
43 *(.initcall6.init)
44 *(.initcall7.init)
45 __initcall_end = .;
46 __con_initcall_start = .;
47 *(.con_initcall.init)
48 __con_initcall_end = .;
49#ifdef CONFIG_BLK_DEV_INITRD
50 . = ALIGN(32);
51 __initramfs_start = .;
52 usr/built-in.o(.init.ramfs)
53 __initramfs_end = .;
54#endif
55 . = ALIGN(32768);
56 __init_end = .;
57 }
58
59 /DISCARD/ : { /* Exit code and data */
60 *(.exit.text)
61 *(.exit.data)
62 *(.exitcall.exit)
63 }
64
65 .text : { /* Real text segment */
66 _text = .; /* Text and read-only data */
67 TEXT_TEXT
68 SCHED_TEXT
69 LOCK_TEXT /* FIXME - borrowed from arm32 - check*/
70 *(.fixup)
71 *(.gnu.warning)
72 *(.rodata)
73 *(.rodata.*)
74 *(.glue_7)
75 *(.glue_7t)
76 *(.got) /* Global offset table */
77
78 _etext = .; /* End of text section */
79 }
80
81 . = ALIGN(16);
82 __ex_table : { /* Exception table */
83 __start___ex_table = .;
84 *(__ex_table)
85 __stop___ex_table = .;
86 }
87
88 RODATA
89
90 _endtext = .;
91
92 . = DATAADDR;
93
94 _sdata = .;
95
96 .data : {
97 . = ALIGN(8192);
98 /*
99 * first, the init thread union, aligned
100 * to an 8192 byte boundary. (see arm26/kernel/init_task.c)
101 * FIXME - sould this be 32K aligned on arm26?
102 */
103 *(.init.task)
104
105 /*
106 * The cacheline aligned data
107 */
108 . = ALIGN(32);
109 *(.data.cacheline_aligned)
110
111 /*
112 * and the usual data section
113 */
114 DATA_DATA
115 CONSTRUCTORS
116
117 *(.init.data)
118
119 _edata = .;
120 }
121
122 .bss : {
123 __bss_start = .; /* BSS */
124 *(.bss)
125 *(COMMON)
126 _end = . ;
127 }
128 /* Stabs debugging sections. */
129 .stab 0 : { *(.stab) }
130 .stabstr 0 : { *(.stabstr) }
131 .stab.excl 0 : { *(.stab.excl) }
132 .stab.exclstr 0 : { *(.stab.exclstr) }
133 .stab.index 0 : { *(.stab.index) }
134 .stab.indexstr 0 : { *(.stab.indexstr) }
135 .comment 0 : { *(.comment) }
136}
diff --git a/arch/arm26/kernel/vmlinux-arm26.lds.in b/arch/arm26/kernel/vmlinux-arm26.lds.in
deleted file mode 100644
index 6c44f6a17bf7..000000000000
--- a/arch/arm26/kernel/vmlinux-arm26.lds.in
+++ /dev/null
@@ -1,129 +0,0 @@
1/* ld script to make ARM Linux kernel
2 * taken from the i386 version by Russell King
3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
4 * borrowed from Russels ARM port by Ian Molton and subsequently modified.
5 */
6
7#include <asm-generic/vmlinux.lds.h>
8
9OUTPUT_ARCH(arm)
10ENTRY(stext)
11jiffies = jiffies_64;
12SECTIONS
13{
14 . = TEXTADDR;
15 .init : { /* Init code and data */
16 _stext = .;
17 __init_begin = .;
18 _sinittext = .;
19 *(.init.text)
20 _einittext = .;
21 __proc_info_begin = .;
22 *(.proc.info)
23 __proc_info_end = .;
24 __arch_info_begin = .;
25 *(.arch.info)
26 __arch_info_end = .;
27 __tagtable_begin = .;
28 *(.taglist)
29 __tagtable_end = .;
30 *(.init.data)
31 . = ALIGN(16);
32 __setup_start = .;
33 *(.init.setup)
34 __setup_end = .;
35 __early_begin = .;
36 *(__early_param)
37 __early_end = .;
38 __initcall_start = .;
39 *(.initcall1.init)
40 *(.initcall2.init)
41 *(.initcall3.init)
42 *(.initcall4.init)
43 *(.initcall5.init)
44 *(.initcall6.init)
45 *(.initcall7.init)
46 __initcall_end = .;
47 __con_initcall_start = .;
48 *(.con_initcall.init)
49 __con_initcall_end = .;
50#ifdef CONFIG_BLK_DEV_INITRD
51 . = ALIGN(32);
52 __initramfs_start = .;
53 usr/built-in.o(.init.ramfs)
54 __initramfs_end = .;
55#endif
56 . = ALIGN(32768);
57 __init_end = .;
58 }
59
60 /DISCARD/ : { /* Exit code and data */
61 *(.exit.text)
62 *(.exit.data)
63 *(.exitcall.exit)
64 }
65
66 .text : { /* Real text segment */
67 _text = .; /* Text and read-only data */
68 TEXT_TEXT
69 SCHED_TEXT
70 LOCK_TEXT
71 *(.fixup)
72 *(.gnu.warning)
73 *(.rodata)
74 *(.rodata.*)
75 *(.glue_7)
76 *(.glue_7t)
77 *(.got) /* Global offset table */
78
79 _etext = .; /* End of text section */
80 }
81
82 . = ALIGN(16);
83 __ex_table : { /* Exception table */
84 __start___ex_table = .;
85 *(__ex_table)
86 __stop___ex_table = .;
87 }
88
89 RODATA
90
91 . = ALIGN(8192);
92
93 .data : {
94 /*
95 * first, the init task union, aligned
96 * to an 8192 byte boundary. (see arm26/kernel/init_task.c)
97 */
98 *(.init.task)
99
100 /*
101 * The cacheline aligned data
102 */
103 . = ALIGN(32);
104 *(.data.cacheline_aligned)
105
106 /*
107 * and the usual data section
108 */
109 DATA_DATA
110 CONSTRUCTORS
111
112 _edata = .;
113 }
114
115 .bss : {
116 __bss_start = .; /* BSS */
117 *(.bss)
118 *(COMMON)
119 _end = . ;
120 }
121 /* Stabs debugging sections. */
122 .stab 0 : { *(.stab) }
123 .stabstr 0 : { *(.stabstr) }
124 .stab.excl 0 : { *(.stab.excl) }
125 .stab.exclstr 0 : { *(.stab.exclstr) }
126 .stab.index 0 : { *(.stab.index) }
127 .stab.indexstr 0 : { *(.stab.indexstr) }
128 .comment 0 : { *(.comment) }
129}
diff --git a/arch/arm26/kernel/vmlinux.lds.S b/arch/arm26/kernel/vmlinux.lds.S
deleted file mode 100644
index 1fa39f02e07c..000000000000
--- a/arch/arm26/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,11 +0,0 @@
1
2#ifdef CONFIG_XIP_KERNEL
3
4#include "vmlinux-arm26-xip.lds.in"
5
6#else
7
8#include "vmlinux-arm26.lds.in"
9
10#endif
11
diff --git a/arch/arm26/lib/Makefile b/arch/arm26/lib/Makefile
deleted file mode 100644
index 6df2b793d367..000000000000
--- a/arch/arm26/lib/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
1#
2# linux/arch/arm26/lib/Makefile
3#
4# Copyright (C) 1995-2000 Russell King
5#
6
7lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
8 csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
9 copy_page.o delay.o findbit.o memchr.o memcpy.o \
10 memset.o memzero.o setbit.o \
11 strchr.o strrchr.o testchangebit.o \
12 testclearbit.o testsetbit.o getuser.o \
13 putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
14 ucmpdi2.o udivdi3.o lib1funcs.o ecard.o io-acorn.o \
15 floppydma.o io-readsb.o io-writesb.o io-writesl.o \
16 uaccess-kernel.o uaccess-user.o io-readsw.o \
17 io-writesw.o io-readsl.o ecard.o io-acorn.o \
18 floppydma.o
19
20lib-n :=
21
22lib-$(CONFIG_VT)+= kbd.o
23
24csumpartialcopy.o: csumpartialcopygeneric.S
25csumpartialcopyuser.o: csumpartialcopygeneric.S
26
diff --git a/arch/arm26/lib/ashldi3.c b/arch/arm26/lib/ashldi3.c
deleted file mode 100644
index 130f5a839669..000000000000
--- a/arch/arm26/lib/ashldi3.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33
34DItype
35__ashldi3 (DItype u, word_type b)
36{
37 DIunion w;
38 word_type bm;
39 DIunion uu;
40
41 if (b == 0)
42 return u;
43
44 uu.ll = u;
45
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
47 if (bm <= 0)
48 {
49 w.s.low = 0;
50 w.s.high = (USItype)uu.s.low << -bm;
51 }
52 else
53 {
54 USItype carries = (USItype)uu.s.low >> bm;
55 w.s.low = (USItype)uu.s.low << b;
56 w.s.high = ((USItype)uu.s.high << b) | carries;
57 }
58
59 return w.ll;
60}
61
diff --git a/arch/arm26/lib/ashrdi3.c b/arch/arm26/lib/ashrdi3.c
deleted file mode 100644
index 71625d218f8d..000000000000
--- a/arch/arm26/lib/ashrdi3.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33
34DItype
35__ashrdi3 (DItype u, word_type b)
36{
37 DIunion w;
38 word_type bm;
39 DIunion uu;
40
41 if (b == 0)
42 return u;
43
44 uu.ll = u;
45
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
47 if (bm <= 0)
48 {
49 /* w.s.high = 1..1 or 0..0 */
50 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
51 w.s.low = uu.s.high >> -bm;
52 }
53 else
54 {
55 USItype carries = (USItype)uu.s.high << bm;
56 w.s.high = uu.s.high >> b;
57 w.s.low = ((USItype)uu.s.low >> b) | carries;
58 }
59
60 return w.ll;
61}
diff --git a/arch/arm26/lib/backtrace.S b/arch/arm26/lib/backtrace.S
deleted file mode 100644
index e27feb1e891d..000000000000
--- a/arch/arm26/lib/backtrace.S
+++ /dev/null
@@ -1,144 +0,0 @@
1/*
2 * linux/arch/arm26/lib/backtrace.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14@ fp is 0 or stack frame
15
16#define frame r4
17#define next r5
18#define save r6
19#define mask r7
20#define offset r8
21
22ENTRY(__backtrace)
23 mov r1, #0x10
24 mov r0, fp
25
26ENTRY(c_backtrace)
27
28#ifdef CONFIG_NO_FRAME_POINTER
29 mov pc, lr
30#else
31
32 stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
33 mov mask, #0xfc000003
34 tst mask, r0
35 movne r0, #0
36 movs frame, r0
371: moveq r0, #-2
38 LOADREGS(eqfd, sp!, {r4 - r8, pc})
39
402: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction
41 ldr r0, [sp], #4
42 adr r1, 2b - 4
43 sub offset, r0, r1
44
453: tst frame, mask @ Check for address exceptions...
46 bne 1b
47
481001: ldr next, [frame, #-12] @ get fp
491002: ldr r2, [frame, #-4] @ get lr
501003: ldr r3, [frame, #0] @ get pc
51 sub save, r3, offset @ Correct PC for prefetching
52 bic save, save, mask
531004: ldr r1, [save, #0] @ get instruction at function
54 mov r1, r1, lsr #10
55 ldr r3, .Ldsi+4
56 teq r1, r3
57 subeq save, save, #4
58 adr r0, .Lfe
59 mov r1, save
60 bic r2, r2, mask
61 bl printk @ print pc and link register
62
63 ldr r0, [frame, #-8] @ get sp
64 sub r0, r0, #4
651005: ldr r1, [save, #4] @ get instruction at function+4
66 mov r3, r1, lsr #10
67 ldr r2, .Ldsi+4
68 teq r3, r2 @ Check for stmia sp!, {args}
69 addeq save, save, #4 @ next instruction
70 bleq .Ldumpstm
71
72 sub r0, frame, #16
731006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
74 mov r3, r1, lsr #10
75 ldr r2, .Ldsi
76 teq r3, r2
77 bleq .Ldumpstm
78
79 teq frame, next
80 movne frame, next
81 teqne frame, #0
82 bne 3b
83 LOADREGS(fd, sp!, {r4 - r8, pc})
84
85/*
86 * Fixup for LDMDB
87 */
88 .section .fixup,"ax"
89 .align 0
901007: ldr r0, =.Lbad
91 mov r1, frame
92 bl printk
93 LOADREGS(fd, sp!, {r4 - r8, pc})
94 .ltorg
95 .previous
96
97 .section __ex_table,"a"
98 .align 3
99 .long 1001b, 1007b
100 .long 1002b, 1007b
101 .long 1003b, 1007b
102 .long 1004b, 1007b
103 .long 1005b, 1007b
104 .long 1006b, 1007b
105 .previous
106
107#define instr r4
108#define reg r5
109#define stack r6
110
111.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
112 mov stack, r0
113 mov instr, r1
114 mov reg, #9
115 mov r7, #0
1161: mov r3, #1
117 tst instr, r3, lsl reg
118 beq 2f
119 add r7, r7, #1
120 teq r7, #4
121 moveq r7, #0
122 moveq r3, #'\n'
123 movne r3, #' '
124 ldr r2, [stack], #-4
125 mov r1, reg
126 adr r0, .Lfp
127 bl printk
1282: subs reg, reg, #1
129 bpl 1b
130 teq r7, #0
131 adrne r0, .Lcr
132 blne printk
133 mov r0, stack
134 LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
135
136.Lfe: .asciz "Function entered at [<%p>] from [<%p>]\n"
137.Lfp: .asciz " r%d = %08X%c"
138.Lcr: .asciz "\n"
139.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
140 .align
141.Ldsi: .word 0x00e92dd8 >> 2
142 .word 0x00e92d00 >> 2
143
144#endif
diff --git a/arch/arm26/lib/changebit.S b/arch/arm26/lib/changebit.S
deleted file mode 100644
index 1b6a077be5a6..000000000000
--- a/arch/arm26/lib/changebit.S
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * linux/arch/arm26/lib/changebit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14/* Purpose : Function to change a bit
15 * Prototype: int change_bit(int bit, void *addr)
16 */
17ENTRY(_change_bit_be)
18 eor r0, r0, #0x18 @ big endian byte ordering
19ENTRY(_change_bit_le)
20 and r2, r0, #7
21 mov r3, #1
22 mov r3, r3, lsl r2
23 save_and_disable_irqs ip, r2
24 ldrb r2, [r1, r0, lsr #3]
25 eor r2, r2, r3
26 strb r2, [r1, r0, lsr #3]
27 restore_irqs ip
28 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/clearbit.S b/arch/arm26/lib/clearbit.S
deleted file mode 100644
index 0a895b0c759f..000000000000
--- a/arch/arm26/lib/clearbit.S
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * linux/arch/arm26/lib/clearbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14/*
15 * Purpose : Function to clear a bit
16 * Prototype: int clear_bit(int bit, void *addr)
17 */
18ENTRY(_clear_bit_be)
19 eor r0, r0, #0x18 @ big endian byte ordering
20ENTRY(_clear_bit_le)
21 and r2, r0, #7
22 mov r3, #1
23 mov r3, r3, lsl r2
24 save_and_disable_irqs ip, r2
25 ldrb r2, [r1, r0, lsr #3]
26 bic r2, r2, r3
27 strb r2, [r1, r0, lsr #3]
28 restore_irqs ip
29 RETINSTR(mov,pc,lr)
30
31
diff --git a/arch/arm26/lib/copy_page.S b/arch/arm26/lib/copy_page.S
deleted file mode 100644
index c7511a2739d3..000000000000
--- a/arch/arm26/lib/copy_page.S
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * linux/arch/arm26/lib/copypage.S
3 *
4 * Copyright (C) 1995-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14#include <asm/asm-offsets.h>
15
16 .text
17 .align 5
18/*
19 * ARMv3 optimised copy_user_page
20 *
21 * FIXME: rmk do we need to handle cache stuff...
22 * FIXME: im is this right on ARM26?
23 */
24ENTRY(__copy_user_page)
25 stmfd sp!, {r4, lr} @ 2
26 mov r2, #PAGE_SZ/64 @ 1
27 ldmia r1!, {r3, r4, ip, lr} @ 4+1
281: stmia r0!, {r3, r4, ip, lr} @ 4
29 ldmia r1!, {r3, r4, ip, lr} @ 4+1
30 stmia r0!, {r3, r4, ip, lr} @ 4
31 ldmia r1!, {r3, r4, ip, lr} @ 4+1
32 stmia r0!, {r3, r4, ip, lr} @ 4
33 ldmia r1!, {r3, r4, ip, lr} @ 4
34 subs r2, r2, #1 @ 1
35 stmia r0!, {r3, r4, ip, lr} @ 4
36 ldmneia r1!, {r3, r4, ip, lr} @ 4
37 bne 1b @ 1
38 LOADREGS(fd, sp!, {r4, pc}) @ 3
39
40 .align 5
41/*
42 * ARMv3 optimised clear_user_page
43 *
44 * FIXME: rmk do we need to handle cache stuff...
45 */
46ENTRY(__clear_user_page)
47 str lr, [sp, #-4]!
48 mov r1, #PAGE_SZ/64 @ 1
49 mov r2, #0 @ 1
50 mov r3, #0 @ 1
51 mov ip, #0 @ 1
52 mov lr, #0 @ 1
531: stmia r0!, {r2, r3, ip, lr} @ 4
54 stmia r0!, {r2, r3, ip, lr} @ 4
55 stmia r0!, {r2, r3, ip, lr} @ 4
56 stmia r0!, {r2, r3, ip, lr} @ 4
57 subs r1, r1, #1 @ 1
58 bne 1b @ 1
59 ldr pc, [sp], #4
60
61 .section ".init.text", #alloc, #execinstr
62
diff --git a/arch/arm26/lib/csumipv6.S b/arch/arm26/lib/csumipv6.S
deleted file mode 100644
index 62831155acde..000000000000
--- a/arch/arm26/lib/csumipv6.S
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * linux/arch/arm26/lib/csumipv6.S
3 *
4 * Copyright (C) 1995-1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14
15ENTRY(__csum_ipv6_magic)
16 str lr, [sp, #-4]!
17 adds ip, r2, r3
18 ldmia r1, {r1 - r3, lr}
19 adcs ip, ip, r1
20 adcs ip, ip, r2
21 adcs ip, ip, r3
22 adcs ip, ip, lr
23 ldmia r0, {r0 - r3}
24 adcs r0, ip, r0
25 adcs r0, r0, r1
26 adcs r0, r0, r2
27 ldr r2, [sp, #4]
28 adcs r0, r0, r3
29 adcs r0, r0, r2
30 adcs r0, r0, #0
31 LOADREGS(fd, sp!, {pc})
32
diff --git a/arch/arm26/lib/csumpartial.S b/arch/arm26/lib/csumpartial.S
deleted file mode 100644
index e53e7109e623..000000000000
--- a/arch/arm26/lib/csumpartial.S
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 * linux/arch/arm26/lib/csumpartial.S
3 *
4 * Copyright (C) 1995-1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14
15/*
16 * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
17 * Params : r0 = buffer, r1 = len, r2 = checksum
18 * Returns : r0 = new checksum
19 */
20
21buf .req r0
22len .req r1
23sum .req r2
24td0 .req r3
25td1 .req r4 @ save before use
26td2 .req r5 @ save before use
27td3 .req lr
28
29.zero: mov r0, sum
30 add sp, sp, #4
31 ldr pc, [sp], #4
32
33 /*
34 * Handle 0 to 7 bytes, with any alignment of source and
35 * destination pointers. Note that when we get here, C = 0
36 */
37.less8: teq len, #0 @ check for zero count
38 beq .zero
39
40 /* we must have at least one byte. */
41 tst buf, #1 @ odd address?
42 ldrneb td0, [buf], #1
43 subne len, len, #1
44 adcnes sum, sum, td0, lsl #byte(1)
45
46.less4: tst len, #6
47 beq .less8_byte
48
49 /* we are now half-word aligned */
50
51.less8_wordlp:
52#if __LINUX_ARM_ARCH__ >= 4
53 ldrh td0, [buf], #2
54 sub len, len, #2
55#else
56 ldrb td0, [buf], #1
57 ldrb td3, [buf], #1
58 sub len, len, #2
59 orr td0, td0, td3, lsl #8
60#endif
61 adcs sum, sum, td0
62 tst len, #6
63 bne .less8_wordlp
64
65.less8_byte: tst len, #1 @ odd number of bytes
66 ldrneb td0, [buf], #1 @ include last byte
67 adcnes sum, sum, td0, lsl #byte(0) @ update checksum
68
69.done: adc r0, sum, #0 @ collect up the last carry
70 ldr td0, [sp], #4
71 tst td0, #1 @ check buffer alignment
72 movne td0, r0, lsl #8 @ rotate checksum by 8 bits
73 orrne r0, td0, r0, lsr #24
74 ldr pc, [sp], #4 @ return
75
76.not_aligned: tst buf, #1 @ odd address
77 ldrneb td0, [buf], #1 @ make even
78 subne len, len, #1
79 adcnes sum, sum, td0, lsl #byte(1) @ update checksum
80
81 tst buf, #2 @ 32-bit aligned?
82#if __LINUX_ARM_ARCH__ >= 4
83 ldrneh td0, [buf], #2 @ make 32-bit aligned
84 subne len, len, #2
85#else
86 ldrneb td0, [buf], #1
87 ldrneb ip, [buf], #1
88 subne len, len, #2
89 orrne td0, td0, ip, lsl #8
90#endif
91 adcnes sum, sum, td0 @ update checksum
92 mov pc, lr
93
94ENTRY(csum_partial)
95 stmfd sp!, {buf, lr}
96 cmp len, #8 @ Ensure that we have at least
97 blo .less8 @ 8 bytes to copy.
98
99 adds sum, sum, #0 @ C = 0
100 tst buf, #3 @ Test destination alignment
101 blne .not_aligned @ aligh destination, return here
102
1031: bics ip, len, #31
104 beq 3f
105
106 stmfd sp!, {r4 - r5}
1072: ldmia buf!, {td0, td1, td2, td3}
108 adcs sum, sum, td0
109 adcs sum, sum, td1
110 adcs sum, sum, td2
111 adcs sum, sum, td3
112 ldmia buf!, {td0, td1, td2, td3}
113 adcs sum, sum, td0
114 adcs sum, sum, td1
115 adcs sum, sum, td2
116 adcs sum, sum, td3
117 sub ip, ip, #32
118 teq ip, #0
119 bne 2b
120 ldmfd sp!, {r4 - r5}
121
1223: tst len, #0x1c @ should not change C
123 beq .less4
124
1254: ldr td0, [buf], #4
126 sub len, len, #4
127 adcs sum, sum, td0
128 tst len, #0x1c
129 bne 4b
130 b .less4
diff --git a/arch/arm26/lib/csumpartialcopy.S b/arch/arm26/lib/csumpartialcopy.S
deleted file mode 100644
index a1c4b5fdd498..000000000000
--- a/arch/arm26/lib/csumpartialcopy.S
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * linux/arch/arm26/lib/csumpartialcopy.S
3 *
4 * Copyright (C) 1995-1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14
15/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
16 * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
17 * Returns : r0 = new checksum
18 */
19
20 .macro save_regs
21 stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
22 .endm
23
24 .macro load_regs,flags
25 LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
26 .endm
27
28 .macro load1b, reg1
29 ldrb \reg1, [r0], #1
30 .endm
31
32 .macro load2b, reg1, reg2
33 ldrb \reg1, [r0], #1
34 ldrb \reg2, [r0], #1
35 .endm
36
37 .macro load1l, reg1
38 ldr \reg1, [r0], #4
39 .endm
40
41 .macro load2l, reg1, reg2
42 ldr \reg1, [r0], #4
43 ldr \reg2, [r0], #4
44 .endm
45
46 .macro load4l, reg1, reg2, reg3, reg4
47 ldmia r0!, {\reg1, \reg2, \reg3, \reg4}
48 .endm
49
50#define FN_ENTRY ENTRY(csum_partial_copy_nocheck)
51
52#include "csumpartialcopygeneric.S"
diff --git a/arch/arm26/lib/csumpartialcopygeneric.S b/arch/arm26/lib/csumpartialcopygeneric.S
deleted file mode 100644
index 5249c3ad11db..000000000000
--- a/arch/arm26/lib/csumpartialcopygeneric.S
+++ /dev/null
@@ -1,352 +0,0 @@
1/*
2 * linux/arch/arm26/lib/csumpartialcopygeneric.S
3 *
4 * Copyright (C) 1995-2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * JMA 01/06/03 Commented out some shl0s; probobly irrelevant to arm26
11 *
12 */
13
14/*
15 * unsigned int
16 * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
17 * r0 = src, r1 = dst, r2 = len, r3 = sum
18 * Returns : r0 = checksum
19 *
20 * Note that 'tst' and 'teq' preserve the carry flag.
21 */
22
23/* Quick hack */
24 .macro save_regs
25 stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
26 .endm
27
28/* end Quick Hack */
29
30src .req r0
31dst .req r1
32len .req r2
33sum .req r3
34
35.zero: mov r0, sum
36 load_regs ea
37
38 /*
39 * Align an unaligned destination pointer. We know that
40 * we have >= 8 bytes here, so we don't need to check
41 * the length. Note that the source pointer hasn't been
42 * aligned yet.
43 */
44.dst_unaligned: tst dst, #1
45 beq .dst_16bit
46
47 load1b ip
48 sub len, len, #1
49 adcs sum, sum, ip, lsl #byte(1) @ update checksum
50 strb ip, [dst], #1
51 tst dst, #2
52 moveq pc, lr @ dst is now 32bit aligned
53
54.dst_16bit: load2b r8, ip
55 sub len, len, #2
56 adcs sum, sum, r8, lsl #byte(0)
57 strb r8, [dst], #1
58 adcs sum, sum, ip, lsl #byte(1)
59 strb ip, [dst], #1
60 mov pc, lr @ dst is now 32bit aligned
61
62 /*
63 * Handle 0 to 7 bytes, with any alignment of source and
64 * destination pointers. Note that when we get here, C = 0
65 */
66.less8: teq len, #0 @ check for zero count
67 beq .zero
68
69 /* we must have at least one byte. */
70 tst dst, #1 @ dst 16-bit aligned
71 beq .less8_aligned
72
73 /* Align dst */
74 load1b ip
75 sub len, len, #1
76 adcs sum, sum, ip, lsl #byte(1) @ update checksum
77 strb ip, [dst], #1
78 tst len, #6
79 beq .less8_byteonly
80
811: load2b r8, ip
82 sub len, len, #2
83 adcs sum, sum, r8, lsl #byte(0)
84 strb r8, [dst], #1
85 adcs sum, sum, ip, lsl #byte(1)
86 strb ip, [dst], #1
87.less8_aligned: tst len, #6
88 bne 1b
89.less8_byteonly:
90 tst len, #1
91 beq .done
92 load1b r8
93 adcs sum, sum, r8, lsl #byte(0) @ update checksum
94 strb r8, [dst], #1
95 b .done
96
97FN_ENTRY
98 mov ip, sp
99 save_regs
100 sub fp, ip, #4
101
102 cmp len, #8 @ Ensure that we have at least
103 blo .less8 @ 8 bytes to copy.
104
105 adds sum, sum, #0 @ C = 0
106 tst dst, #3 @ Test destination alignment
107 blne .dst_unaligned @ align destination, return here
108
109 /*
110 * Ok, the dst pointer is now 32bit aligned, and we know
111 * that we must have more than 4 bytes to copy. Note
112 * that C contains the carry from the dst alignment above.
113 */
114
115 tst src, #3 @ Test source alignment
116 bne .src_not_aligned
117
118 /* Routine for src & dst aligned */
119
120 bics ip, len, #15
121 beq 2f
122
1231: load4l r4, r5, r6, r7
124 stmia dst!, {r4, r5, r6, r7}
125 adcs sum, sum, r4
126 adcs sum, sum, r5
127 adcs sum, sum, r6
128 adcs sum, sum, r7
129 sub ip, ip, #16
130 teq ip, #0
131 bne 1b
132
1332: ands ip, len, #12
134 beq 4f
135 tst ip, #8
136 beq 3f
137 load2l r4, r5
138 stmia dst!, {r4, r5}
139 adcs sum, sum, r4
140 adcs sum, sum, r5
141 tst ip, #4
142 beq 4f
143
1443: load1l r4
145 str r4, [dst], #4
146 adcs sum, sum, r4
147
1484: ands len, len, #3
149 beq .done
150 load1l r4
151 tst len, #2
152/* mov r5, r4, lsr #byte(0)
153FIXME? 0 Shift anyhow!
154*/
155 beq .exit
156 adcs sum, sum, r4, push #16
157 strb r5, [dst], #1
158 mov r5, r4, lsr #byte(1)
159 strb r5, [dst], #1
160 mov r5, r4, lsr #byte(2)
161.exit: tst len, #1
162 strneb r5, [dst], #1
163 andne r5, r5, #255
164 adcnes sum, sum, r5, lsl #byte(0)
165
166 /*
167 * If the dst pointer was not 16-bit aligned, we
168 * need to rotate the checksum here to get around
169 * the inefficient byte manipulations in the
170 * architecture independent code.
171 */
172.done: adc r0, sum, #0
173 ldr sum, [sp, #0] @ dst
174 tst sum, #1
175 movne sum, r0, lsl #8
176 orrne r0, sum, r0, lsr #24
177 load_regs ea
178
179.src_not_aligned:
180 adc sum, sum, #0 @ include C from dst alignment
181 and ip, src, #3
182 bic src, src, #3
183 load1l r5
184 cmp ip, #2
185 beq .src2_aligned
186 bhi .src3_aligned
187 mov r4, r5, pull #8 @ C = 0
188 bics ip, len, #15
189 beq 2f
1901: load4l r5, r6, r7, r8
191 orr r4, r4, r5, push #24
192 mov r5, r5, pull #8
193 orr r5, r5, r6, push #24
194 mov r6, r6, pull #8
195 orr r6, r6, r7, push #24
196 mov r7, r7, pull #8
197 orr r7, r7, r8, push #24
198 stmia dst!, {r4, r5, r6, r7}
199 adcs sum, sum, r4
200 adcs sum, sum, r5
201 adcs sum, sum, r6
202 adcs sum, sum, r7
203 mov r4, r8, pull #8
204 sub ip, ip, #16
205 teq ip, #0
206 bne 1b
2072: ands ip, len, #12
208 beq 4f
209 tst ip, #8
210 beq 3f
211 load2l r5, r6
212 orr r4, r4, r5, push #24
213 mov r5, r5, pull #8
214 orr r5, r5, r6, push #24
215 stmia dst!, {r4, r5}
216 adcs sum, sum, r4
217 adcs sum, sum, r5
218 mov r4, r6, pull #8
219 tst ip, #4
220 beq 4f
2213: load1l r5
222 orr r4, r4, r5, push #24
223 str r4, [dst], #4
224 adcs sum, sum, r4
225 mov r4, r5, pull #8
2264: ands len, len, #3
227 beq .done
228/* mov r5, r4, lsr #byte(0)
229FIXME? 0 Shift anyhow
230*/
231 tst len, #2
232 beq .exit
233 adcs sum, sum, r4, push #16
234 strb r5, [dst], #1
235 mov r5, r4, lsr #byte(1)
236 strb r5, [dst], #1
237 mov r5, r4, lsr #byte(2)
238 b .exit
239
240.src2_aligned: mov r4, r5, pull #16
241 adds sum, sum, #0
242 bics ip, len, #15
243 beq 2f
2441: load4l r5, r6, r7, r8
245 orr r4, r4, r5, push #16
246 mov r5, r5, pull #16
247 orr r5, r5, r6, push #16
248 mov r6, r6, pull #16
249 orr r6, r6, r7, push #16
250 mov r7, r7, pull #16
251 orr r7, r7, r8, push #16
252 stmia dst!, {r4, r5, r6, r7}
253 adcs sum, sum, r4
254 adcs sum, sum, r5
255 adcs sum, sum, r6
256 adcs sum, sum, r7
257 mov r4, r8, pull #16
258 sub ip, ip, #16
259 teq ip, #0
260 bne 1b
2612: ands ip, len, #12
262 beq 4f
263 tst ip, #8
264 beq 3f
265 load2l r5, r6
266 orr r4, r4, r5, push #16
267 mov r5, r5, pull #16
268 orr r5, r5, r6, push #16
269 stmia dst!, {r4, r5}
270 adcs sum, sum, r4
271 adcs sum, sum, r5
272 mov r4, r6, pull #16
273 tst ip, #4
274 beq 4f
2753: load1l r5
276 orr r4, r4, r5, push #16
277 str r4, [dst], #4
278 adcs sum, sum, r4
279 mov r4, r5, pull #16
2804: ands len, len, #3
281 beq .done
282/* mov r5, r4, lsr #byte(0)
283FIXME? 0 Shift anyhow
284*/
285 tst len, #2
286 beq .exit
287 adcs sum, sum, r4
288 strb r5, [dst], #1
289 mov r5, r4, lsr #byte(1)
290 strb r5, [dst], #1
291 tst len, #1
292 beq .done
293 load1b r5
294 b .exit
295
296.src3_aligned: mov r4, r5, pull #24
297 adds sum, sum, #0
298 bics ip, len, #15
299 beq 2f
3001: load4l r5, r6, r7, r8
301 orr r4, r4, r5, push #8
302 mov r5, r5, pull #24
303 orr r5, r5, r6, push #8
304 mov r6, r6, pull #24
305 orr r6, r6, r7, push #8
306 mov r7, r7, pull #24
307 orr r7, r7, r8, push #8
308 stmia dst!, {r4, r5, r6, r7}
309 adcs sum, sum, r4
310 adcs sum, sum, r5
311 adcs sum, sum, r6
312 adcs sum, sum, r7
313 mov r4, r8, pull #24
314 sub ip, ip, #16
315 teq ip, #0
316 bne 1b
3172: ands ip, len, #12
318 beq 4f
319 tst ip, #8
320 beq 3f
321 load2l r5, r6
322 orr r4, r4, r5, push #8
323 mov r5, r5, pull #24
324 orr r5, r5, r6, push #8
325 stmia dst!, {r4, r5}
326 adcs sum, sum, r4
327 adcs sum, sum, r5
328 mov r4, r6, pull #24
329 tst ip, #4
330 beq 4f
3313: load1l r5
332 orr r4, r4, r5, push #8
333 str r4, [dst], #4
334 adcs sum, sum, r4
335 mov r4, r5, pull #24
3364: ands len, len, #3
337 beq .done
338/* mov r5, r4, lsr #byte(0)
339FIXME? 0 Shift anyhow
340*/
341 tst len, #2
342 beq .exit
343 strb r5, [dst], #1
344 adcs sum, sum, r4
345 load1l r4
346/* mov r5, r4, lsr #byte(0)
347FIXME? 0 Shift anyhow
348*/
349 strb r5, [dst], #1
350 adcs sum, sum, r4, push #24
351 mov r5, r4, lsr #byte(1)
352 b .exit
diff --git a/arch/arm26/lib/csumpartialcopyuser.S b/arch/arm26/lib/csumpartialcopyuser.S
deleted file mode 100644
index a98eea74305a..000000000000
--- a/arch/arm26/lib/csumpartialcopyuser.S
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 * linux/arch/arm26/lib/csumpartialcopyuser.S
3 *
4 * Copyright (C) 1995-1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/errno.h>
13#include <asm/asm-offsets.h>
14
15 .text
16
17 .macro save_regs
18 stmfd sp!, {r1 - r2, r4 - r9, fp, ip, lr, pc}
19 mov r9, sp, lsr #13
20 mov r9, r9, lsl #13
21 ldr r9, [r9, #TSK_ADDR_LIMIT]
22 mov r9, r9, lsr #24
23 .endm
24
25 .macro load_regs,flags
26 ldm\flags fp, {r1, r2, r4-r9, fp, sp, pc}^
27 .endm
28
29 .macro load1b, reg1
30 tst r9, #0x01
319999: ldreqbt \reg1, [r0], #1
32 ldrneb \reg1, [r0], #1
33 .section __ex_table, "a"
34 .align 3
35 .long 9999b, 6001f
36 .previous
37 .endm
38
39 .macro load2b, reg1, reg2
40 tst r9, #0x01
419999: ldreqbt \reg1, [r0], #1
42 ldrneb \reg1, [r0], #1
439998: ldreqbt \reg2, [r0], #1
44 ldrneb \reg2, [r0], #1
45 .section __ex_table, "a"
46 .long 9999b, 6001f
47 .long 9998b, 6001f
48 .previous
49 .endm
50
51 .macro load1l, reg1
52 tst r9, #0x01
539999: ldreqt \reg1, [r0], #4
54 ldrne \reg1, [r0], #4
55 .section __ex_table, "a"
56 .align 3
57 .long 9999b, 6001f
58 .previous
59 .endm
60
61 .macro load2l, reg1, reg2
62 tst r9, #0x01
63 ldmneia r0!, {\reg1, \reg2}
649999: ldreqt \reg1, [r0], #4
659998: ldreqt \reg2, [r0], #4
66 .section __ex_table, "a"
67 .long 9999b, 6001f
68 .long 9998b, 6001f
69 .previous
70 .endm
71
72 .macro load4l, reg1, reg2, reg3, reg4
73 tst r9, #0x01
74 ldmneia r0!, {\reg1, \reg2, \reg3, \reg4}
759999: ldreqt \reg1, [r0], #4
769998: ldreqt \reg2, [r0], #4
779997: ldreqt \reg3, [r0], #4
789996: ldreqt \reg4, [r0], #4
79 .section __ex_table, "a"
80 .long 9999b, 6001f
81 .long 9998b, 6001f
82 .long 9997b, 6001f
83 .long 9996b, 6001f
84 .previous
85 .endm
86
87/*
88 * unsigned int
89 * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
90 * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
91 * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
92 */
93
94#define FN_ENTRY ENTRY(csum_partial_copy_from_user)
95
96#include "csumpartialcopygeneric.S"
97
98/*
99 * FIXME: minor buglet here
100 * We don't return the checksum for the data present in the buffer. To do
101 * so properly, we would have to add in whatever registers were loaded before
102 * the fault, which, with the current asm above is not predictable.
103 */
104 .align 4
1056001: mov r4, #-EFAULT
106 ldr r5, [fp, #4] @ *err_ptr
107 str r4, [r5]
108 ldmia sp, {r1, r2} @ retrieve dst, len
109 add r2, r2, r1
110 mov r0, #0 @ zero the buffer
1116002: teq r2, r1
112 strneb r0, [r1], #1
113 bne 6002b
114 load_regs ea
diff --git a/arch/arm26/lib/delay.S b/arch/arm26/lib/delay.S
deleted file mode 100644
index 66f2b68e1b13..000000000000
--- a/arch/arm26/lib/delay.S
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * linux/arch/arm26/lib/delay.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14LC0: .word loops_per_jiffy
15
16/*
17 * 0 <= r0 <= 2000
18 */
19ENTRY(udelay)
20 mov r2, #0x6800
21 orr r2, r2, #0x00db
22 mul r1, r0, r2
23 ldr r2, LC0
24 ldr r2, [r2]
25 mov r1, r1, lsr #11
26 mov r2, r2, lsr #11
27 mul r0, r1, r2
28 movs r0, r0, lsr #6
29 RETINSTR(moveq,pc,lr)
30
31/*
32 * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32
33 *
34 * Oh, if only we had a cycle counter...
35 */
36
37@ Delay routine
38ENTRY(__delay)
39 subs r0, r0, #1
40#if 0
41 RETINSTR(movls,pc,lr)
42 subs r0, r0, #1
43 RETINSTR(movls,pc,lr)
44 subs r0, r0, #1
45 RETINSTR(movls,pc,lr)
46 subs r0, r0, #1
47 RETINSTR(movls,pc,lr)
48 subs r0, r0, #1
49 RETINSTR(movls,pc,lr)
50 subs r0, r0, #1
51 RETINSTR(movls,pc,lr)
52 subs r0, r0, #1
53 RETINSTR(movls,pc,lr)
54 subs r0, r0, #1
55#endif
56 bhi __delay
57 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/ecard.S b/arch/arm26/lib/ecard.S
deleted file mode 100644
index 658bc4529c9d..000000000000
--- a/arch/arm26/lib/ecard.S
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * linux/arch/arm26/lib/ecard.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14#define CPSR2SPSR(rt)
15
16@ Purpose: call an expansion card loader to read bytes.
17@ Proto : char read_loader(int offset, char *card_base, char *loader);
18@ Returns: byte read
19
20ENTRY(ecard_loader_read)
21 stmfd sp!, {r4 - r12, lr}
22 mov r11, r1
23 mov r1, r0
24 CPSR2SPSR(r0)
25 mov lr, pc
26 mov pc, r2
27 LOADREGS(fd, sp!, {r4 - r12, pc})
28
29@ Purpose: call an expansion card loader to reset the card
30@ Proto : void read_loader(int card_base, char *loader);
31@ Returns: byte read
32
33ENTRY(ecard_loader_reset)
34 stmfd sp!, {r4 - r12, lr}
35 mov r11, r0
36 CPSR2SPSR(r0)
37 mov lr, pc
38 add pc, r1, #8
39 LOADREGS(fd, sp!, {r4 - r12, pc})
40
diff --git a/arch/arm26/lib/findbit.S b/arch/arm26/lib/findbit.S
deleted file mode 100644
index 26f67cccc37c..000000000000
--- a/arch/arm26/lib/findbit.S
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * linux/arch/arm/lib/findbit.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 16th March 2001 - John Ripley <jripley@sonicblue.com>
11 * Fixed so that "size" is an exclusive not an inclusive quantity.
12 * All users of these functions expect exclusive sizes, and may
13 * also call with zero size.
14 * Reworked by rmk.
15 */
16#include <linux/linkage.h>
17#include <asm/assembler.h>
18 .text
19
20/*
21 * Purpose : Find a 'zero' bit
22 * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
23 */
24ENTRY(_find_first_zero_bit_le)
25 teq r1, #0
26 beq 3f
27 mov r2, #0
281: ldrb r3, [r0, r2, lsr #3]
29 eors r3, r3, #0xff @ invert bits
30 bne .found @ any now set - found zero bit
31 add r2, r2, #8 @ next bit pointer
322: cmp r2, r1 @ any more?
33 blo 1b
343: mov r0, r1 @ no free bits
35 RETINSTR(mov,pc,lr)
36
37/*
38 * Purpose : Find next 'zero' bit
39 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
40 */
41ENTRY(_find_next_zero_bit_le)
42 teq r1, #0
43 beq 2b
44 ands ip, r2, #7
45 beq 1b @ If new byte, goto old routine
46 ldrb r3, [r0, r2, lsr #3]
47 eor r3, r3, #0xff @ now looking for a 1 bit
48 movs r3, r3, lsr ip @ shift off unused bits
49 bne .found
50 orr r2, r2, #7 @ if zero, then no bits here
51 add r2, r2, #1 @ align bit pointer
52 b 2b @ loop for next bit
53
54/*
55 * One or more bits in the LSB of r3 are assumed to be set.
56 */
57.found: tst r3, #0x0f
58 addeq r2, r2, #4
59 movne r3, r3, lsl #4
60 tst r3, #0x30
61 addeq r2, r2, #2
62 movne r3, r3, lsl #2
63 tst r3, #0x40
64 addeq r2, r2, #1
65 mov r0, r2
66 RETINSTR(mov,pc,lr)
67
diff --git a/arch/arm26/lib/floppydma.S b/arch/arm26/lib/floppydma.S
deleted file mode 100644
index e99ebbb20353..000000000000
--- a/arch/arm26/lib/floppydma.S
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * linux/arch/arm26/lib/floppydma.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14 .global floppy_fiqin_end
15ENTRY(floppy_fiqin_start)
16 subs r9, r9, #1
17 ldrgtb r12, [r11, #-4]
18 ldrleb r12, [r11], #0
19 strb r12, [r10], #1
20 subs pc, lr, #4
21floppy_fiqin_end:
22
23 .global floppy_fiqout_end
24ENTRY(floppy_fiqout_start)
25 subs r9, r9, #1
26 ldrgeb r12, [r10], #1
27 movlt r12, #0
28 strleb r12, [r11], #0
29 subles pc, lr, #4
30 strb r12, [r11, #-4]
31 subs pc, lr, #4
32floppy_fiqout_end:
diff --git a/arch/arm26/lib/gcclib.h b/arch/arm26/lib/gcclib.h
deleted file mode 100644
index 9895e78904b5..000000000000
--- a/arch/arm26/lib/gcclib.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
2/* I Molton 29/07/01 */
3
4#define BITS_PER_UNIT 8
5#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
6
7typedef unsigned int UQItype __attribute__ ((mode (QI)));
8typedef int SItype __attribute__ ((mode (SI)));
9typedef unsigned int USItype __attribute__ ((mode (SI)));
10typedef int DItype __attribute__ ((mode (DI)));
11typedef int word_type __attribute__ ((mode (__word__)));
12typedef unsigned int UDItype __attribute__ ((mode (DI)));
13
14struct DIstruct {SItype low, high;};
15
16typedef union
17{
18 struct DIstruct s;
19 DItype ll;
20} DIunion;
21
diff --git a/arch/arm26/lib/getuser.S b/arch/arm26/lib/getuser.S
deleted file mode 100644
index 2b1de7fbfe1f..000000000000
--- a/arch/arm26/lib/getuser.S
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * linux/arch/arm26/lib/getuser.S
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
11 *
12 * These functions have a non-standard call interface to make them more
13 * efficient, especially as they return an error value in addition to
14 * the "real" return value.
15 *
16 * __get_user_X
17 *
18 * Inputs: r0 contains the address
19 * Outputs: r0 is the error code
20 * r1, r2 contains the zero-extended value
21 * lr corrupted
22 *
23 * No other registers must be altered. (see include/asm-arm/uaccess.h
24 * for specific ASM register usage).
25 *
26 * Note that ADDR_LIMIT is either 0 or 0xc0000000.
27 * Note also that it is intended that __get_user_bad is not global.
28 */
29#include <asm/asm-offsets.h>
30#include <asm/thread_info.h>
31#include <asm/errno.h>
32
33 .global __get_user_1
34__get_user_1:
35 bic r1, sp, #0x1f00
36 bic r1, r1, #0x00ff
37 str lr, [sp, #-4]!
38 ldr r1, [r1, #TI_ADDR_LIMIT]
39 sub r1, r1, #1
40 cmp r0, r1
41 bge __get_user_bad
42 cmp r0, #0x02000000
431: ldrlsbt r1, [r0]
44 ldrgeb r1, [r0]
45 mov r0, #0
46 ldmfd sp!, {pc}^
47
48 .global __get_user_2
49__get_user_2:
50 bic r2, sp, #0x1f00
51 bic r2, r2, #0x00ff
52 str lr, [sp, #-4]!
53 ldr r2, [r2, #TI_ADDR_LIMIT]
54 sub r2, r2, #2
55 cmp r0, r2
56 bge __get_user_bad
57 cmp r0, #0x02000000
582: ldrlsbt r1, [r0], #1
593: ldrlsbt r2, [r0]
60 ldrgeb r1, [r0], #1
61 ldrgeb r2, [r0]
62 orr r1, r1, r2, lsl #8
63 mov r0, #0
64 ldmfd sp!, {pc}^
65
66 .global __get_user_4
67__get_user_4:
68 bic r1, sp, #0x1f00
69 bic r1, r1, #0x00ff
70 str lr, [sp, #-4]!
71 ldr r1, [r1, #TI_ADDR_LIMIT]
72 sub r1, r1, #4
73 cmp r0, r1
74 bge __get_user_bad
75 cmp r0, #0x02000000
764: ldrlst r1, [r0]
77 ldrge r1, [r0]
78 mov r0, #0
79 ldmfd sp!, {pc}^
80
81 .global __get_user_8
82__get_user_8:
83 bic r2, sp, #0x1f00
84 bic r2, r2, #0x00ff
85 str lr, [sp, #-4]!
86 ldr r2, [r2, #TI_ADDR_LIMIT]
87 sub r2, r2, #8
88 cmp r0, r2
89 bge __get_user_bad_8
90 cmp r0, #0x02000000
915: ldrlst r1, [r0], #4
926: ldrlst r2, [r0]
93 ldrge r1, [r0], #4
94 ldrge r2, [r0]
95 mov r0, #0
96 ldmfd sp!, {pc}^
97
98__get_user_bad_8:
99 mov r2, #0
100__get_user_bad:
101 mov r1, #0
102 mov r0, #-EFAULT
103 ldmfd sp!, {pc}^
104
105.section __ex_table, "a"
106 .long 1b, __get_user_bad
107 .long 2b, __get_user_bad
108 .long 3b, __get_user_bad
109 .long 4b, __get_user_bad
110 .long 5b, __get_user_bad_8
111 .long 6b, __get_user_bad_8
112.previous
diff --git a/arch/arm26/lib/io-acorn.S b/arch/arm26/lib/io-acorn.S
deleted file mode 100644
index 5f62ade5be39..000000000000
--- a/arch/arm26/lib/io-acorn.S
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-acorn.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14 .text
15 .align
16
17 .equ diff_pcio_base, PCIO_BASE - IO_BASE
18
19 .macro outw2 rd
20 mov r8, \rd, lsl #16
21 orr r8, r8, r8, lsr #16
22 str r8, [r3, r0, lsl #2]
23 mov r8, \rd, lsr #16
24 orr r8, r8, r8, lsl #16
25 str r8, [r3, r0, lsl #2]
26 .endm
27
28 .macro inw2 rd, mask, temp
29 ldr \rd, [r0]
30 and \rd, \rd, \mask
31 ldr \temp, [r0]
32 orr \rd, \rd, \temp, lsl #16
33 .endm
34
35 .macro addr rd
36 tst \rd, #0x80000000
37 mov \rd, \rd, lsl #2
38 add \rd, \rd, #IO_BASE
39 addeq \rd, \rd, #diff_pcio_base
40 .endm
41
42.iosl_warning:
43 .ascii "<4>insl/outsl not implemented, called from %08lX\0"
44 .align
45
46/*
47 * These make no sense on Acorn machines.
48 * Print a warning message.
49 */
50ENTRY(insl)
51ENTRY(outsl)
52 adr r0, .iosl_warning
53 mov r1, lr
54 b printk
55
56@ Purpose: write a memc register
57@ Proto : void memc_write(int register, int value);
58@ Returns: nothing
59
60ENTRY(memc_write)
61 cmp r0, #7
62 RETINSTR(movgt,pc,lr)
63 mov r0, r0, lsl #17
64 mov r1, r1, lsl #15
65 mov r1, r1, lsr #17
66 orr r0, r0, r1, lsl #2
67 add r0, r0, #0x03600000
68 strb r0, [r0]
69 RETINSTR(mov,pc,lr)
70
diff --git a/arch/arm26/lib/io-readsb.S b/arch/arm26/lib/io-readsb.S
deleted file mode 100644
index 4c4d99c05856..000000000000
--- a/arch/arm26/lib/io-readsb.S
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-readsb.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14.insb_align: rsb ip, ip, #4
15 cmp ip, r2
16 movgt ip, r2
17 cmp ip, #2
18 ldrb r3, [r0]
19 strb r3, [r1], #1
20 ldrgeb r3, [r0]
21 strgeb r3, [r1], #1
22 ldrgtb r3, [r0]
23 strgtb r3, [r1], #1
24 subs r2, r2, ip
25 bne .insb_aligned
26
27ENTRY(__raw_readsb)
28 teq r2, #0 @ do we have to check for the zero len?
29 moveq pc, lr
30 ands ip, r1, #3
31 bne .insb_align
32
33.insb_aligned: stmfd sp!, {r4 - r6, lr}
34
35 subs r2, r2, #16
36 bmi .insb_no_16
37
38.insb_16_lp: ldrb r3, [r0]
39 ldrb r4, [r0]
40 orr r3, r3, r4, lsl #8
41 ldrb r4, [r0]
42 orr r3, r3, r4, lsl #16
43 ldrb r4, [r0]
44 orr r3, r3, r4, lsl #24
45 ldrb r4, [r0]
46 ldrb r5, [r0]
47 orr r4, r4, r5, lsl #8
48 ldrb r5, [r0]
49 orr r4, r4, r5, lsl #16
50 ldrb r5, [r0]
51 orr r4, r4, r5, lsl #24
52 ldrb r5, [r0]
53 ldrb r6, [r0]
54 orr r5, r5, r6, lsl #8
55 ldrb r6, [r0]
56 orr r5, r5, r6, lsl #16
57 ldrb r6, [r0]
58 orr r5, r5, r6, lsl #24
59 ldrb r6, [r0]
60 ldrb ip, [r0]
61 orr r6, r6, ip, lsl #8
62 ldrb ip, [r0]
63 orr r6, r6, ip, lsl #16
64 ldrb ip, [r0]
65 orr r6, r6, ip, lsl #24
66 stmia r1!, {r3 - r6}
67
68 subs r2, r2, #16
69 bpl .insb_16_lp
70
71 tst r2, #15
72 LOADREGS(eqfd, sp!, {r4 - r6, pc})
73
74.insb_no_16: tst r2, #8
75 beq .insb_no_8
76
77 ldrb r3, [r0]
78 ldrb r4, [r0]
79 orr r3, r3, r4, lsl #8
80 ldrb r4, [r0]
81 orr r3, r3, r4, lsl #16
82 ldrb r4, [r0]
83 orr r3, r3, r4, lsl #24
84 ldrb r4, [r0]
85 ldrb r5, [r0]
86 orr r4, r4, r5, lsl #8
87 ldrb r5, [r0]
88 orr r4, r4, r5, lsl #16
89 ldrb r5, [r0]
90 orr r4, r4, r5, lsl #24
91 stmia r1!, {r3, r4}
92
93.insb_no_8: tst r2, #4
94 beq .insb_no_4
95
96 ldrb r3, [r0]
97 ldrb r4, [r0]
98 orr r3, r3, r4, lsl #8
99 ldrb r4, [r0]
100 orr r3, r3, r4, lsl #16
101 ldrb r4, [r0]
102 orr r3, r3, r4, lsl #24
103 str r3, [r1], #4
104
105.insb_no_4: ands r2, r2, #3
106 LOADREGS(eqfd, sp!, {r4 - r6, pc})
107
108 cmp r2, #2
109 ldrb r3, [r0]
110 strb r3, [r1], #1
111 ldrgeb r3, [r0]
112 strgeb r3, [r1], #1
113 ldrgtb r3, [r0]
114 strgtb r3, [r1]
115
116 LOADREGS(fd, sp!, {r4 - r6, pc})
diff --git a/arch/arm26/lib/io-readsl.S b/arch/arm26/lib/io-readsl.S
deleted file mode 100644
index 7be208bd23c6..000000000000
--- a/arch/arm26/lib/io-readsl.S
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-readsl.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14/*
15 * Note that some reads can be aligned on half-word boundaries.
16 */
17ENTRY(__raw_readsl)
18 teq r2, #0 @ do we have to check for the zero len?
19 moveq pc, lr
20 ands ip, r1, #3
21 bne 2f
22
231: ldr r3, [r0]
24 str r3, [r1], #4
25 subs r2, r2, #1
26 bne 1b
27 mov pc, lr
28
292: cmp ip, #2
30 ldr ip, [r0]
31 blt 4f
32 bgt 6f
33
34 strb ip, [r1], #1
35 mov ip, ip, lsr #8
36 strb ip, [r1], #1
37 mov ip, ip, lsr #8
383: subs r2, r2, #1
39 ldrne r3, [r0]
40 orrne ip, ip, r3, lsl #16
41 strne ip, [r1], #4
42 movne ip, r3, lsr #16
43 bne 3b
44 strb ip, [r1], #1
45 mov ip, ip, lsr #8
46 strb ip, [r1], #1
47 mov pc, lr
48
494: strb ip, [r1], #1
50 mov ip, ip, lsr #8
51 strb ip, [r1], #1
52 mov ip, ip, lsr #8
53 strb ip, [r1], #1
54 mov ip, ip, lsr #8
555: subs r2, r2, #1
56 ldrne r3, [r0]
57 orrne ip, ip, r3, lsl #8
58 strne ip, [r1], #4
59 movne ip, r3, lsr #24
60 bne 5b
61 strb ip, [r1], #1
62 mov pc, lr
63
646: strb ip, [r1], #1
65 mov ip, ip, lsr #8
667: subs r2, r2, #1
67 ldrne r3, [r0]
68 orrne ip, ip, r3, lsl #24
69 strne ip, [r1], #4
70 movne ip, r3, lsr #8
71 bne 7b
72 strb ip, [r1], #1
73 mov ip, ip, lsr #8
74 strb ip, [r1], #1
75 mov ip, ip, lsr #8
76 strb ip, [r1], #1
77 mov pc, lr
78
diff --git a/arch/arm26/lib/io-readsw.S b/arch/arm26/lib/io-readsw.S
deleted file mode 100644
index c65c1f28fcff..000000000000
--- a/arch/arm26/lib/io-readsw.S
+++ /dev/null
@@ -1,107 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-readsw.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14.insw_bad_alignment:
15 adr r0, .insw_bad_align_msg
16 mov r2, lr
17 b panic
18.insw_bad_align_msg:
19 .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
20 .align
21
22.insw_align: tst r1, #1
23 bne .insw_bad_alignment
24
25 ldr r3, [r0]
26 strb r3, [r1], #1
27 mov r3, r3, lsr #8
28 strb r3, [r1], #1
29
30 subs r2, r2, #1
31 RETINSTR(moveq, pc, lr)
32
33ENTRY(__raw_readsw)
34 teq r2, #0 @ do we have to check for the zero len?
35 moveq pc, lr
36 tst r1, #3
37 bne .insw_align
38
39.insw_aligned: mov ip, #0xff
40 orr ip, ip, ip, lsl #8
41 stmfd sp!, {r4, r5, r6, lr}
42
43 subs r2, r2, #8
44 bmi .no_insw_8
45
46.insw_8_lp: ldr r3, [r0]
47 and r3, r3, ip
48 ldr r4, [r0]
49 orr r3, r3, r4, lsl #16
50
51 ldr r4, [r0]
52 and r4, r4, ip
53 ldr r5, [r0]
54 orr r4, r4, r5, lsl #16
55
56 ldr r5, [r0]
57 and r5, r5, ip
58 ldr r6, [r0]
59 orr r5, r5, r6, lsl #16
60
61 ldr r6, [r0]
62 and r6, r6, ip
63 ldr lr, [r0]
64 orr r6, r6, lr, lsl #16
65
66 stmia r1!, {r3 - r6}
67
68 subs r2, r2, #8
69 bpl .insw_8_lp
70
71 tst r2, #7
72 LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
73
74.no_insw_8: tst r2, #4
75 beq .no_insw_4
76
77 ldr r3, [r0]
78 and r3, r3, ip
79 ldr r4, [r0]
80 orr r3, r3, r4, lsl #16
81
82 ldr r4, [r0]
83 and r4, r4, ip
84 ldr r5, [r0]
85 orr r4, r4, r5, lsl #16
86
87 stmia r1!, {r3, r4}
88
89.no_insw_4: tst r2, #2
90 beq .no_insw_2
91
92 ldr r3, [r0]
93 and r3, r3, ip
94 ldr r4, [r0]
95 orr r3, r3, r4, lsl #16
96
97 str r3, [r1], #4
98
99.no_insw_2: tst r2, #1
100 ldrne r3, [r0]
101 strneb r3, [r1], #1
102 movne r3, r3, lsr #8
103 strneb r3, [r1]
104
105 LOADREGS(fd, sp!, {r4, r5, r6, pc})
106
107
diff --git a/arch/arm26/lib/io-writesb.S b/arch/arm26/lib/io-writesb.S
deleted file mode 100644
index 16251b4d5101..000000000000
--- a/arch/arm26/lib/io-writesb.S
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-writesb.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14.outsb_align: rsb ip, ip, #4
15 cmp ip, r2
16 movgt ip, r2
17 cmp ip, #2
18 ldrb r3, [r1], #1
19 strb r3, [r0]
20 ldrgeb r3, [r1], #1
21 strgeb r3, [r0]
22 ldrgtb r3, [r1], #1
23 strgtb r3, [r0]
24 subs r2, r2, ip
25 bne .outsb_aligned
26
27ENTRY(__raw_writesb)
28 teq r2, #0 @ do we have to check for the zero len?
29 moveq pc, lr
30 ands ip, r1, #3
31 bne .outsb_align
32
33.outsb_aligned: stmfd sp!, {r4 - r6, lr}
34
35 subs r2, r2, #16
36 bmi .outsb_no_16
37
38.outsb_16_lp: ldmia r1!, {r3 - r6}
39
40 strb r3, [r0]
41 mov r3, r3, lsr #8
42 strb r3, [r0]
43 mov r3, r3, lsr #8
44 strb r3, [r0]
45 mov r3, r3, lsr #8
46 strb r3, [r0]
47
48 strb r4, [r0]
49 mov r4, r4, lsr #8
50 strb r4, [r0]
51 mov r4, r4, lsr #8
52 strb r4, [r0]
53 mov r4, r4, lsr #8
54 strb r4, [r0]
55
56 strb r5, [r0]
57 mov r5, r5, lsr #8
58 strb r5, [r0]
59 mov r5, r5, lsr #8
60 strb r5, [r0]
61 mov r5, r5, lsr #8
62 strb r5, [r0]
63
64 strb r6, [r0]
65 mov r6, r6, lsr #8
66 strb r6, [r0]
67 mov r6, r6, lsr #8
68 strb r6, [r0]
69 mov r6, r6, lsr #8
70 strb r6, [r0]
71
72 subs r2, r2, #16
73 bpl .outsb_16_lp
74
75 tst r2, #15
76 LOADREGS(eqfd, sp!, {r4 - r6, pc})
77
78.outsb_no_16: tst r2, #8
79 beq .outsb_no_8
80
81 ldmia r1!, {r3, r4}
82
83 strb r3, [r0]
84 mov r3, r3, lsr #8
85 strb r3, [r0]
86 mov r3, r3, lsr #8
87 strb r3, [r0]
88 mov r3, r3, lsr #8
89 strb r3, [r0]
90
91 strb r4, [r0]
92 mov r4, r4, lsr #8
93 strb r4, [r0]
94 mov r4, r4, lsr #8
95 strb r4, [r0]
96 mov r4, r4, lsr #8
97 strb r4, [r0]
98
99.outsb_no_8: tst r2, #4
100 beq .outsb_no_4
101
102 ldr r3, [r1], #4
103 strb r3, [r0]
104 mov r3, r3, lsr #8
105 strb r3, [r0]
106 mov r3, r3, lsr #8
107 strb r3, [r0]
108 mov r3, r3, lsr #8
109 strb r3, [r0]
110
111.outsb_no_4: ands r2, r2, #3
112 LOADREGS(eqfd, sp!, {r4 - r6, pc})
113
114 cmp r2, #2
115 ldrb r3, [r1], #1
116 strb r3, [r0]
117 ldrgeb r3, [r1], #1
118 strgeb r3, [r0]
119 ldrgtb r3, [r1]
120 strgtb r3, [r0]
121
122 LOADREGS(fd, sp!, {r4 - r6, pc})
diff --git a/arch/arm26/lib/io-writesl.S b/arch/arm26/lib/io-writesl.S
deleted file mode 100644
index 4d6049b16e71..000000000000
--- a/arch/arm26/lib/io-writesl.S
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-writesl.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14ENTRY(__raw_writesl)
15 teq r2, #0 @ do we have to check for the zero len?
16 moveq pc, lr
17 ands ip, r1, #3
18 bne 2f
19
201: ldr r3, [r1], #4
21 str r3, [r0]
22 subs r2, r2, #1
23 bne 1b
24 mov pc, lr
25
262: bic r1, r1, #3
27 cmp ip, #2
28 ldr r3, [r1], #4
29 bgt 4f
30 blt 5f
31
323: mov ip, r3, lsr #16
33 ldr r3, [r1], #4
34 orr ip, ip, r3, lsl #16
35 str ip, [r0]
36 subs r2, r2, #1
37 bne 3b
38 mov pc, lr
39
404: mov ip, r3, lsr #24
41 ldr r3, [r1], #4
42 orr ip, ip, r3, lsl #8
43 str ip, [r0]
44 subs r2, r2, #1
45 bne 4b
46 mov pc, lr
47
485: mov ip, r3, lsr #8
49 ldr r3, [r1], #4
50 orr ip, ip, r3, lsl #24
51 str ip, [r0]
52 subs r2, r2, #1
53 bne 5b
54 mov pc, lr
55
56
diff --git a/arch/arm26/lib/io-writesw.S b/arch/arm26/lib/io-writesw.S
deleted file mode 100644
index a24f891f6b1c..000000000000
--- a/arch/arm26/lib/io-writesw.S
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * linux/arch/arm26/lib/io-writesw.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12#include <asm/hardware.h>
13
14.outsw_bad_alignment:
15 adr r0, .outsw_bad_align_msg
16 mov r2, lr
17 b panic
18.outsw_bad_align_msg:
19 .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
20 .align
21
22.outsw_align: tst r1, #1
23 bne .outsw_bad_alignment
24
25 add r1, r1, #2
26
27 ldr r3, [r1, #-4]
28 mov r3, r3, lsr #16
29 orr r3, r3, r3, lsl #16
30 str r3, [r0]
31 subs r2, r2, #1
32 RETINSTR(moveq, pc, lr)
33
34ENTRY(__raw_writesw)
35 teq r2, #0 @ do we have to check for the zero len?
36 moveq pc, lr
37 tst r1, #3
38 bne .outsw_align
39
40.outsw_aligned: stmfd sp!, {r4, r5, r6, lr}
41
42 subs r2, r2, #8
43 bmi .no_outsw_8
44
45.outsw_8_lp: ldmia r1!, {r3, r4, r5, r6}
46
47 mov ip, r3, lsl #16
48 orr ip, ip, ip, lsr #16
49 str ip, [r0]
50
51 mov ip, r3, lsr #16
52 orr ip, ip, ip, lsl #16
53 str ip, [r0]
54
55 mov ip, r4, lsl #16
56 orr ip, ip, ip, lsr #16
57 str ip, [r0]
58
59 mov ip, r4, lsr #16
60 orr ip, ip, ip, lsl #16
61 str ip, [r0]
62
63 mov ip, r5, lsl #16
64 orr ip, ip, ip, lsr #16
65 str ip, [r0]
66
67 mov ip, r5, lsr #16
68 orr ip, ip, ip, lsl #16
69 str ip, [r0]
70
71 mov ip, r6, lsl #16
72 orr ip, ip, ip, lsr #16
73 str ip, [r0]
74
75 mov ip, r6, lsr #16
76 orr ip, ip, ip, lsl #16
77 str ip, [r0]
78
79 subs r2, r2, #8
80 bpl .outsw_8_lp
81
82 tst r2, #7
83 LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
84
85.no_outsw_8: tst r2, #4
86 beq .no_outsw_4
87
88 ldmia r1!, {r3, r4}
89
90 mov ip, r3, lsl #16
91 orr ip, ip, ip, lsr #16
92 str ip, [r0]
93
94 mov ip, r3, lsr #16
95 orr ip, ip, ip, lsl #16
96 str ip, [r0]
97
98 mov ip, r4, lsl #16
99 orr ip, ip, ip, lsr #16
100 str ip, [r0]
101
102 mov ip, r4, lsr #16
103 orr ip, ip, ip, lsl #16
104 str ip, [r0]
105
106.no_outsw_4: tst r2, #2
107 beq .no_outsw_2
108
109 ldr r3, [r1], #4
110
111 mov ip, r3, lsl #16
112 orr ip, ip, ip, lsr #16
113 str ip, [r0]
114
115 mov ip, r3, lsr #16
116 orr ip, ip, ip, lsl #16
117 str ip, [r0]
118
119.no_outsw_2: tst r2, #1
120
121 ldrne r3, [r1]
122
123 movne ip, r3, lsl #16
124 orrne ip, ip, ip, lsr #16
125 strne ip, [r0]
126
127 LOADREGS(fd, sp!, {r4, r5, r6, pc})
diff --git a/arch/arm26/lib/kbd.c b/arch/arm26/lib/kbd.c
deleted file mode 100644
index cb56e943e006..000000000000
--- a/arch/arm26/lib/kbd.c
+++ /dev/null
@@ -1,278 +0,0 @@
1#include <linux/kd.h>
2//#include <linux/kbd_ll.h>
3#include <linux/kbd_kern.h>
4
5/*
6 * Translation of escaped scancodes to keycodes.
7 * This is now user-settable.
8 * The keycodes 1-88,96-111,119 are fairly standard, and
9 * should probably not be changed - changing might confuse X.
10 * X also interprets scancode 0x5d (KEY_Begin).
11 *
12 * For 1-88 keycode equals scancode.
13 */
14
15#define E0_KPENTER 96
16#define E0_RCTRL 97
17#define E0_KPSLASH 98
18#define E0_PRSCR 99
19#define E0_RALT 100
20#define E0_BREAK 101 /* (control-pause) */
21#define E0_HOME 102
22#define E0_UP 103
23#define E0_PGUP 104
24#define E0_LEFT 105
25#define E0_RIGHT 106
26#define E0_END 107
27#define E0_DOWN 108
28#define E0_PGDN 109
29#define E0_INS 110
30#define E0_DEL 111
31
32/* for USB 106 keyboard */
33#define E0_YEN 124
34#define E0_BACKSLASH 89
35
36
37#define E1_PAUSE 119
38
39/*
40 * The keycodes below are randomly located in 89-95,112-118,120-127.
41 * They could be thrown away (and all occurrences below replaced by 0),
42 * but that would force many users to use the `setkeycodes' utility, where
43 * they needed not before. It does not matter that there are duplicates, as
44 * long as no duplication occurs for any single keyboard.
45 */
46#define SC_LIM 89
47
48#define FOCUS_PF1 85 /* actual code! */
49#define FOCUS_PF2 89
50#define FOCUS_PF3 90
51#define FOCUS_PF4 91
52#define FOCUS_PF5 92
53#define FOCUS_PF6 93
54#define FOCUS_PF7 94
55#define FOCUS_PF8 95
56#define FOCUS_PF9 120
57#define FOCUS_PF10 121
58#define FOCUS_PF11 122
59#define FOCUS_PF12 123
60
61#define JAP_86 124
62/* tfj@olivia.ping.dk:
63 * The four keys are located over the numeric keypad, and are
64 * labelled A1-A4. It's an rc930 keyboard, from
65 * Regnecentralen/RC International, Now ICL.
66 * Scancodes: 59, 5a, 5b, 5c.
67 */
68#define RGN1 124
69#define RGN2 125
70#define RGN3 126
71#define RGN4 127
72
73static unsigned char high_keys[128 - SC_LIM] = {
74 RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
75 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
76 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
77 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
78 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
79 FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
80};
81
82/* BTC */
83#define E0_MACRO 112
84/* LK450 */
85#define E0_F13 113
86#define E0_F14 114
87#define E0_HELP 115
88#define E0_DO 116
89#define E0_F17 117
90#define E0_KPMINPLUS 118
91/*
92 * My OmniKey generates e0 4c for the "OMNI" key and the
93 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
94 */
95#define E0_OK 124
96/*
97 * New microsoft keyboard is rumoured to have
98 * e0 5b (left window button), e0 5c (right window button),
99 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
100 * [or: Windows_L, Windows_R, TaskMan]
101 */
102#define E0_MSLW 125
103#define E0_MSRW 126
104#define E0_MSTM 127
105
106static unsigned char e0_keys[128] = {
107 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
108 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
109 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
110 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
111 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
112 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
113 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
114 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
115 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
116 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END, /* 0x48-0x4f */
117 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
118 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
119 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
120 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
121 //0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
122 0, 0, 0, 0, 0, E0_BACKSLASH, 0, 0, /* 0x70-0x77 */
123 0, 0, 0, E0_YEN, 0, 0, 0, 0 /* 0x78-0x7f */
124};
125
126static int gen_setkeycode(unsigned int scancode, unsigned int keycode)
127{
128 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
129 return -EINVAL;
130 if (scancode < 128)
131 high_keys[scancode - SC_LIM] = keycode;
132 else
133 e0_keys[scancode - 128] = keycode;
134 return 0;
135}
136
137static int gen_getkeycode(unsigned int scancode)
138{
139 return
140 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
141 (scancode <
142 128) ? high_keys[scancode - SC_LIM] : e0_keys[scancode - 128];
143}
144
145static int
146gen_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
147{
148 static int prev_scancode;
149
150 /* special prefix scancodes.. */
151 if (scancode == 0xe0 || scancode == 0xe1) {
152 prev_scancode = scancode;
153 return 0;
154 }
155
156 /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
157 if (scancode == 0x00 || scancode == 0xff) {
158 prev_scancode = 0;
159 return 0;
160 }
161
162 scancode &= 0x7f;
163
164 if (prev_scancode) {
165 /*
166 * usually it will be 0xe0, but a Pause key generates
167 * e1 1d 45 e1 9d c5 when pressed, and nothing when released
168 */
169 if (prev_scancode != 0xe0) {
170 if (prev_scancode == 0xe1 && scancode == 0x1d) {
171 prev_scancode = 0x100;
172 return 0;
173 }
174 else if (prev_scancode == 0x100
175 && scancode == 0x45) {
176 *keycode = E1_PAUSE;
177 prev_scancode = 0;
178 } else {
179#ifdef KBD_REPORT_UNKN
180 if (!raw_mode)
181 printk(KERN_INFO
182 "keyboard: unknown e1 escape sequence\n");
183#endif
184 prev_scancode = 0;
185 return 0;
186 }
187 } else {
188 prev_scancode = 0;
189 /*
190 * The keyboard maintains its own internal caps lock and
191 * num lock statuses. In caps lock mode E0 AA precedes make
192 * code and E0 2A follows break code. In num lock mode,
193 * E0 2A precedes make code and E0 AA follows break code.
194 * We do our own book-keeping, so we will just ignore these.
195 */
196 /*
197 * For my keyboard there is no caps lock mode, but there are
198 * both Shift-L and Shift-R modes. The former mode generates
199 * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
200 * So, we should also ignore the latter. - aeb@cwi.nl
201 */
202 if (scancode == 0x2a || scancode == 0x36)
203 return 0;
204
205 if (e0_keys[scancode])
206 *keycode = e0_keys[scancode];
207 else {
208#ifdef KBD_REPORT_UNKN
209 if (!raw_mode)
210 printk(KERN_INFO
211 "keyboard: unknown scancode e0 %02x\n",
212 scancode);
213#endif
214 return 0;
215 }
216 }
217 } else if (scancode >= SC_LIM) {
218 /* This happens with the FOCUS 9000 keyboard
219 Its keys PF1..PF12 are reported to generate
220 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
221 Moreover, unless repeated, they do not generate
222 key-down events, so we have to zero up_flag below */
223 /* Also, Japanese 86/106 keyboards are reported to
224 generate 0x73 and 0x7d for \ - and \ | respectively. */
225 /* Also, some Brazilian keyboard is reported to produce
226 0x73 and 0x7e for \ ? and KP-dot, respectively. */
227
228 *keycode = high_keys[scancode - SC_LIM];
229
230 if (!*keycode) {
231 if (!raw_mode) {
232#ifdef KBD_REPORT_UNKN
233 printk(KERN_INFO
234 "keyboard: unrecognized scancode (%02x)"
235 " - ignored\n", scancode);
236#endif
237 }
238 return 0;
239 }
240 } else
241 *keycode = scancode;
242 return 1;
243}
244
245static char gen_unexpected_up(unsigned char keycode)
246{
247 /* unexpected, but this can happen: maybe this was a key release for a
248 FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
249 if (keycode >= SC_LIM || keycode == 85)
250 return 0;
251 else
252 return 0200;
253}
254
255/*
256 * These are the default mappings
257 */
258int (*k_setkeycode)(unsigned int, unsigned int) = gen_setkeycode;
259int (*k_getkeycode)(unsigned int) = gen_getkeycode;
260int (*k_translate)(unsigned char, unsigned char *, char) = gen_translate;
261char (*k_unexpected_up)(unsigned char) = gen_unexpected_up;
262void (*k_leds)(unsigned char);
263
264/* Simple translation table for the SysRq keys */
265
266#ifdef CONFIG_MAGIC_SYSRQ
267static unsigned char gen_sysrq_xlate[128] =
268 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
269 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
270 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
271 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
272 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
273 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
274 "\r\000/"; /* 0x60 - 0x6f */
275
276unsigned char *k_sysrq_xlate = gen_sysrq_xlate;
277int k_sysrq_key = 0x54;
278#endif
diff --git a/arch/arm26/lib/lib1funcs.S b/arch/arm26/lib/lib1funcs.S
deleted file mode 100644
index 0e29970b0e8a..000000000000
--- a/arch/arm26/lib/lib1funcs.S
+++ /dev/null
@@ -1,313 +0,0 @@
1@ libgcc1 routines for ARM cpu.
2@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3
4/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
5
6This file is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11In addition to the permissions in the GNU General Public License, the
12Free Software Foundation gives you unlimited permission to link the
13compiled version of this file with other programs, and to distribute
14those programs without any restriction coming from the use of this
15file. (The General Public License restrictions do apply in other
16respects; for example, they cover modification of the file, and
17distribution when not linked into another program.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 59 Temple Place - Suite 330,
27Boston, MA 02111-1307, USA. */
28
29/* As a special exception, if you link this library with other files,
30 some of which are compiled with GCC, to produce an executable,
31 this library does not by itself cause the resulting executable
32 to be covered by the GNU General Public License.
33 This exception does not however invalidate any other reasons why
34 the executable file might be covered by the GNU General Public License.
35 */
36/* This code is derived from gcc 2.95.3 */
37/* I Molton 29/07/01 */
38
39#include <linux/linkage.h>
40#include <asm/assembler.h>
41#include <asm/hardware.h>
42
43#define RET movs
44#define RETc(x) mov##x##s
45#define RETCOND ^
46
47dividend .req r0
48divisor .req r1
49result .req r2
50overdone .req r2
51curbit .req r3
52ip .req r12
53sp .req r13
54lr .req r14
55pc .req r15
56
57ENTRY(__udivsi3)
58 cmp divisor, #0
59 beq Ldiv0
60 mov curbit, #1
61 mov result, #0
62 cmp dividend, divisor
63 bcc Lgot_result_udivsi3
641:
65 @ Unless the divisor is very big, shift it up in multiples of
66 @ four bits, since this is the amount of unwinding in the main
67 @ division loop. Continue shifting until the divisor is
68 @ larger than the dividend.
69 cmp divisor, #0x10000000
70 cmpcc divisor, dividend
71 movcc divisor, divisor, lsl #4
72 movcc curbit, curbit, lsl #4
73 bcc 1b
74
752:
76 @ For very big divisors, we must shift it a bit at a time, or
77 @ we will be in danger of overflowing.
78 cmp divisor, #0x80000000
79 cmpcc divisor, dividend
80 movcc divisor, divisor, lsl #1
81 movcc curbit, curbit, lsl #1
82 bcc 2b
83
843:
85 @ Test for possible subtractions, and note which bits
86 @ are done in the result. On the final pass, this may subtract
87 @ too much from the dividend, but the result will be ok, since the
88 @ "bit" will have been shifted out at the bottom.
89 cmp dividend, divisor
90 subcs dividend, dividend, divisor
91 orrcs result, result, curbit
92 cmp dividend, divisor, lsr #1
93 subcs dividend, dividend, divisor, lsr #1
94 orrcs result, result, curbit, lsr #1
95 cmp dividend, divisor, lsr #2
96 subcs dividend, dividend, divisor, lsr #2
97 orrcs result, result, curbit, lsr #2
98 cmp dividend, divisor, lsr #3
99 subcs dividend, dividend, divisor, lsr #3
100 orrcs result, result, curbit, lsr #3
101 cmp dividend, #0 @ Early termination?
102 movnes curbit, curbit, lsr #4 @ No, any more bits to do?
103 movne divisor, divisor, lsr #4
104 bne 3b
105Lgot_result_udivsi3:
106 mov r0, result
107 RET pc, lr
108
109Ldiv0:
110 str lr, [sp, #-4]!
111 bl __div0
112 mov r0, #0 @ about as wrong as it could be
113 ldmia sp!, {pc}RETCOND
114
115/* __umodsi3 ----------------------- */
116
117ENTRY(__umodsi3)
118 cmp divisor, #0
119 beq Ldiv0
120 mov curbit, #1
121 cmp dividend, divisor
122 RETc(cc) pc, lr
1231:
124 @ Unless the divisor is very big, shift it up in multiples of
125 @ four bits, since this is the amount of unwinding in the main
126 @ division loop. Continue shifting until the divisor is
127 @ larger than the dividend.
128 cmp divisor, #0x10000000
129 cmpcc divisor, dividend
130 movcc divisor, divisor, lsl #4
131 movcc curbit, curbit, lsl #4
132 bcc 1b
133
1342:
135 @ For very big divisors, we must shift it a bit at a time, or
136 @ we will be in danger of overflowing.
137 cmp divisor, #0x80000000
138 cmpcc divisor, dividend
139 movcc divisor, divisor, lsl #1
140 movcc curbit, curbit, lsl #1
141 bcc 2b
142
1433:
144 @ Test for possible subtractions. On the final pass, this may
145 @ subtract too much from the dividend, so keep track of which
146 @ subtractions are done, we can fix them up afterwards...
147 mov overdone, #0
148 cmp dividend, divisor
149 subcs dividend, dividend, divisor
150 cmp dividend, divisor, lsr #1
151 subcs dividend, dividend, divisor, lsr #1
152 orrcs overdone, overdone, curbit, ror #1
153 cmp dividend, divisor, lsr #2
154 subcs dividend, dividend, divisor, lsr #2
155 orrcs overdone, overdone, curbit, ror #2
156 cmp dividend, divisor, lsr #3
157 subcs dividend, dividend, divisor, lsr #3
158 orrcs overdone, overdone, curbit, ror #3
159 mov ip, curbit
160 cmp dividend, #0 @ Early termination?
161 movnes curbit, curbit, lsr #4 @ No, any more bits to do?
162 movne divisor, divisor, lsr #4
163 bne 3b
164
165 @ Any subtractions that we should not have done will be recorded in
166 @ the top three bits of "overdone". Exactly which were not needed
167 @ are governed by the position of the bit, stored in ip.
168 @ If we terminated early, because dividend became zero,
169 @ then none of the below will match, since the bit in ip will not be
170 @ in the bottom nibble.
171 ands overdone, overdone, #0xe0000000
172 RETc(eq) pc, lr @ No fixups needed
173 tst overdone, ip, ror #3
174 addne dividend, dividend, divisor, lsr #3
175 tst overdone, ip, ror #2
176 addne dividend, dividend, divisor, lsr #2
177 tst overdone, ip, ror #1
178 addne dividend, dividend, divisor, lsr #1
179 RET pc, lr
180
181ENTRY(__divsi3)
182 eor ip, dividend, divisor @ Save the sign of the result.
183 mov curbit, #1
184 mov result, #0
185 cmp divisor, #0
186 rsbmi divisor, divisor, #0 @ Loops below use unsigned.
187 beq Ldiv0
188 cmp dividend, #0
189 rsbmi dividend, dividend, #0
190 cmp dividend, divisor
191 bcc Lgot_result_divsi3
192
1931:
194 @ Unless the divisor is very big, shift it up in multiples of
195 @ four bits, since this is the amount of unwinding in the main
196 @ division loop. Continue shifting until the divisor is
197 @ larger than the dividend.
198 cmp divisor, #0x10000000
199 cmpcc divisor, dividend
200 movcc divisor, divisor, lsl #4
201 movcc curbit, curbit, lsl #4
202 bcc 1b
203
2042:
205 @ For very big divisors, we must shift it a bit at a time, or
206 @ we will be in danger of overflowing.
207 cmp divisor, #0x80000000
208 cmpcc divisor, dividend
209 movcc divisor, divisor, lsl #1
210 movcc curbit, curbit, lsl #1
211 bcc 2b
212
2133:
214 @ Test for possible subtractions, and note which bits
215 @ are done in the result. On the final pass, this may subtract
216 @ too much from the dividend, but the result will be ok, since the
217 @ "bit" will have been shifted out at the bottom.
218 cmp dividend, divisor
219 subcs dividend, dividend, divisor
220 orrcs result, result, curbit
221 cmp dividend, divisor, lsr #1
222 subcs dividend, dividend, divisor, lsr #1
223 orrcs result, result, curbit, lsr #1
224 cmp dividend, divisor, lsr #2
225 subcs dividend, dividend, divisor, lsr #2
226 orrcs result, result, curbit, lsr #2
227 cmp dividend, divisor, lsr #3
228 subcs dividend, dividend, divisor, lsr #3
229 orrcs result, result, curbit, lsr #3
230 cmp dividend, #0 @ Early termination?
231 movnes curbit, curbit, lsr #4 @ No, any more bits to do?
232 movne divisor, divisor, lsr #4
233 bne 3b
234Lgot_result_divsi3:
235 mov r0, result
236 cmp ip, #0
237 rsbmi r0, r0, #0
238 RET pc, lr
239
240ENTRY(__modsi3)
241 mov curbit, #1
242 cmp divisor, #0
243 rsbmi divisor, divisor, #0 @ Loops below use unsigned.
244 beq Ldiv0
245 @ Need to save the sign of the dividend, unfortunately, we need
246 @ ip later on; this is faster than pushing lr and using that.
247 str dividend, [sp, #-4]!
248 cmp dividend, #0
249 rsbmi dividend, dividend, #0
250 cmp dividend, divisor
251 bcc Lgot_result_modsi3
252
2531:
254 @ Unless the divisor is very big, shift it up in multiples of
255 @ four bits, since this is the amount of unwinding in the main
256 @ division loop. Continue shifting until the divisor is
257 @ larger than the dividend.
258 cmp divisor, #0x10000000
259 cmpcc divisor, dividend
260 movcc divisor, divisor, lsl #4
261 movcc curbit, curbit, lsl #4
262 bcc 1b
263
2642:
265 @ For very big divisors, we must shift it a bit at a time, or
266 @ we will be in danger of overflowing.
267 cmp divisor, #0x80000000
268 cmpcc divisor, dividend
269 movcc divisor, divisor, lsl #1
270 movcc curbit, curbit, lsl #1
271 bcc 2b
272
2733:
274 @ Test for possible subtractions. On the final pass, this may
275 @ subtract too much from the dividend, so keep track of which
276 @ subtractions are done, we can fix them up afterwards...
277 mov overdone, #0
278 cmp dividend, divisor
279 subcs dividend, dividend, divisor
280 cmp dividend, divisor, lsr #1
281 subcs dividend, dividend, divisor, lsr #1
282 orrcs overdone, overdone, curbit, ror #1
283 cmp dividend, divisor, lsr #2
284 subcs dividend, dividend, divisor, lsr #2
285 orrcs overdone, overdone, curbit, ror #2
286 cmp dividend, divisor, lsr #3
287 subcs dividend, dividend, divisor, lsr #3
288 orrcs overdone, overdone, curbit, ror #3
289 mov ip, curbit
290 cmp dividend, #0 @ Early termination?
291 movnes curbit, curbit, lsr #4 @ No, any more bits to do?
292 movne divisor, divisor, lsr #4
293 bne 3b
294
295 @ Any subtractions that we should not have done will be recorded in
296 @ the top three bits of "overdone". Exactly which were not needed
297 @ are governed by the position of the bit, stored in ip.
298 @ If we terminated early, because dividend became zero,
299 @ then none of the below will match, since the bit in ip will not be
300 @ in the bottom nibble.
301 ands overdone, overdone, #0xe0000000
302 beq Lgot_result_modsi3
303 tst overdone, ip, ror #3
304 addne dividend, dividend, divisor, lsr #3
305 tst overdone, ip, ror #2
306 addne dividend, dividend, divisor, lsr #2
307 tst overdone, ip, ror #1
308 addne dividend, dividend, divisor, lsr #1
309Lgot_result_modsi3:
310 ldr ip, [sp], #4
311 cmp ip, #0
312 rsbmi dividend, dividend, #0
313 RET pc, lr
diff --git a/arch/arm26/lib/longlong.h b/arch/arm26/lib/longlong.h
deleted file mode 100644
index 05ec1abd6a2c..000000000000
--- a/arch/arm26/lib/longlong.h
+++ /dev/null
@@ -1,184 +0,0 @@
1/* longlong.h -- based on code from gcc-2.95.3
2
3 definitions for mixed size 32/64 bit arithmetic.
4 Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
5
6 This definition file is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2, or (at your option) any later version.
10
11 This definition file is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied
13 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
22
23#ifndef SI_TYPE_SIZE
24#define SI_TYPE_SIZE 32
25#endif
26
27#define __BITS4 (SI_TYPE_SIZE / 4)
28#define __ll_B (1L << (SI_TYPE_SIZE / 2))
29#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
30#define __ll_highpart(t) ((USItype) (t) / __ll_B)
31
32/* Define auxiliary asm macros.
33
34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
35 multiplies two USItype integers MULTIPLER and MULTIPLICAND,
36 and generates a two-part USItype product in HIGH_PROD and
37 LOW_PROD.
38
39 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
40 and returns a UDItype product. This is just a variant of umul_ppmm.
41
42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
43 denominator) divides a two-word unsigned integer, composed by the
44 integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
45 places the quotient in QUOTIENT and the remainder in REMAINDER.
46 HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
47 If, in addition, the most significant bit of DENOMINATOR must be 1,
48 then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
49
50 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
51 denominator). Like udiv_qrnnd but the numbers are signed. The
52 quotient is rounded towards 0.
53
54 5) count_leading_zeros(count, x) counts the number of zero-bits from
55 the msb to the first non-zero bit. This is the number of steps X
56 needs to be shifted left to set the msb. Undefined for X == 0.
57
58 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
59 high_addend_2, low_addend_2) adds two two-word unsigned integers,
60 composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
61 LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
62 LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
63 lost.
64
65 7) sub_ddmmss(high_difference, low_difference, high_minuend,
66 low_minuend, high_subtrahend, low_subtrahend) subtracts two
67 two-word unsigned integers, composed by HIGH_MINUEND_1 and
68 LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
69 respectively. The result is placed in HIGH_DIFFERENCE and
70 LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
71 and is lost.
72
73 If any of these macros are left undefined for a particular CPU,
74 C macros are used. */
75
76#if defined (__arm__)
77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
78 __asm__ ("adds %1, %4, %5 \n\
79 adc %0, %2, %3" \
80 : "=r" ((USItype) (sh)), \
81 "=&r" ((USItype) (sl)) \
82 : "%r" ((USItype) (ah)), \
83 "rI" ((USItype) (bh)), \
84 "%r" ((USItype) (al)), \
85 "rI" ((USItype) (bl)))
86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
87 __asm__ ("subs %1, %4, %5 \n\
88 sbc %0, %2, %3" \
89 : "=r" ((USItype) (sh)), \
90 "=&r" ((USItype) (sl)) \
91 : "r" ((USItype) (ah)), \
92 "rI" ((USItype) (bh)), \
93 "r" ((USItype) (al)), \
94 "rI" ((USItype) (bl)))
95#define umul_ppmm(xh, xl, a, b) \
96{register USItype __t0, __t1, __t2; \
97 __asm__ ("%@ Inlined umul_ppmm \n\
98 mov %2, %5, lsr #16 \n\
99 mov %0, %6, lsr #16 \n\
100 bic %3, %5, %2, lsl #16 \n\
101 bic %4, %6, %0, lsl #16 \n\
102 mul %1, %3, %4 \n\
103 mul %4, %2, %4 \n\
104 mul %3, %0, %3 \n\
105 mul %0, %2, %0 \n\
106 adds %3, %4, %3 \n\
107 addcs %0, %0, #65536 \n\
108 adds %1, %1, %3, lsl #16 \n\
109 adc %0, %0, %3, lsr #16" \
110 : "=&r" ((USItype) (xh)), \
111 "=r" ((USItype) (xl)), \
112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
113 : "r" ((USItype) (a)), \
114 "r" ((USItype) (b)));}
115#define UMUL_TIME 20
116#define UDIV_TIME 100
117#endif /* __arm__ */
118
119#define __umulsidi3(u, v) \
120 ({DIunion __w; \
121 umul_ppmm (__w.s.high, __w.s.low, u, v); \
122 __w.ll; })
123
124#define __udiv_qrnnd_c(q, r, n1, n0, d) \
125 do { \
126 USItype __d1, __d0, __q1, __q0; \
127 USItype __r1, __r0, __m; \
128 __d1 = __ll_highpart (d); \
129 __d0 = __ll_lowpart (d); \
130 \
131 __r1 = (n1) % __d1; \
132 __q1 = (n1) / __d1; \
133 __m = (USItype) __q1 * __d0; \
134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
135 if (__r1 < __m) \
136 { \
137 __q1--, __r1 += (d); \
138 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
139 if (__r1 < __m) \
140 __q1--, __r1 += (d); \
141 } \
142 __r1 -= __m; \
143 \
144 __r0 = __r1 % __d1; \
145 __q0 = __r1 / __d1; \
146 __m = (USItype) __q0 * __d0; \
147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
148 if (__r0 < __m) \
149 { \
150 __q0--, __r0 += (d); \
151 if (__r0 >= (d)) \
152 if (__r0 < __m) \
153 __q0--, __r0 += (d); \
154 } \
155 __r0 -= __m; \
156 \
157 (q) = (USItype) __q1 * __ll_B | __q0; \
158 (r) = __r0; \
159 } while (0)
160
161#define UDIV_NEEDS_NORMALIZATION 1
162#define udiv_qrnnd __udiv_qrnnd_c
163
164extern const UQItype __clz_tab[];
165#define count_leading_zeros(count, x) \
166 do { \
167 USItype __xr = (x); \
168 USItype __a; \
169 \
170 if (SI_TYPE_SIZE <= 32) \
171 { \
172 __a = __xr < ((USItype)1<<2*__BITS4) \
173 ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
174 : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
175 } \
176 else \
177 { \
178 for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
179 if (((__xr >> __a) & 0xff) != 0) \
180 break; \
181 } \
182 \
183 (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
184 } while (0)
diff --git a/arch/arm26/lib/lshrdi3.c b/arch/arm26/lib/lshrdi3.c
deleted file mode 100644
index b666f1bad451..000000000000
--- a/arch/arm26/lib/lshrdi3.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33
34DItype
35__lshrdi3 (DItype u, word_type b)
36{
37 DIunion w;
38 word_type bm;
39 DIunion uu;
40
41 if (b == 0)
42 return u;
43
44 uu.ll = u;
45
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
47 if (bm <= 0)
48 {
49 w.s.high = 0;
50 w.s.low = (USItype)uu.s.high >> -bm;
51 }
52 else
53 {
54 USItype carries = (USItype)uu.s.high << bm;
55 w.s.high = (USItype)uu.s.high >> b;
56 w.s.low = ((USItype)uu.s.low >> b) | carries;
57 }
58
59 return w.ll;
60}
61
diff --git a/arch/arm26/lib/memchr.S b/arch/arm26/lib/memchr.S
deleted file mode 100644
index 34e7c14c08ad..000000000000
--- a/arch/arm26/lib/memchr.S
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * linux/arch/arm26/lib/memchr.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15 .text
16 .align 5
17ENTRY(memchr)
181: subs r2, r2, #1
19 bmi 2f
20 ldrb r3, [r0], #1
21 teq r3, r1
22 bne 1b
23 sub r0, r0, #1
242: movne r0, #0
25 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/memcpy.S b/arch/arm26/lib/memcpy.S
deleted file mode 100644
index 3f719e412069..000000000000
--- a/arch/arm26/lib/memcpy.S
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * linux/arch/arm26/lib/memcpy.S
3 *
4 * Copyright (C) 1995-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15 .text
16
17#define ENTER \
18 mov ip,sp ;\
19 stmfd sp!,{r4-r9,fp,ip,lr,pc} ;\
20 sub fp,ip,#4
21
22#define EXIT \
23 LOADREGS(ea, fp, {r4 - r9, fp, sp, pc})
24
25#define EXITEQ \
26 LOADREGS(eqea, fp, {r4 - r9, fp, sp, pc})
27
28/*
29 * Prototype: void memcpy(void *to,const void *from,unsigned long n);
30 * ARM3: cant use memcopy here!!!
31 */
32ENTRY(memcpy)
33ENTRY(memmove)
34 ENTER
35 cmp r1, r0
36 bcc 19f
37 subs r2, r2, #4
38 blt 6f
39 ands ip, r0, #3
40 bne 7f
41 ands ip, r1, #3
42 bne 8f
43
441: subs r2, r2, #8
45 blt 5f
46 subs r2, r2, #0x14
47 blt 3f
482: ldmia r1!,{r3 - r9, ip}
49 stmia r0!,{r3 - r9, ip}
50 subs r2, r2, #32
51 bge 2b
52 cmn r2, #16
53 ldmgeia r1!, {r3 - r6}
54 stmgeia r0!, {r3 - r6}
55 subge r2, r2, #0x10
563: adds r2, r2, #0x14
574: ldmgeia r1!, {r3 - r5}
58 stmgeia r0!, {r3 - r5}
59 subges r2, r2, #12
60 bge 4b
615: adds r2, r2, #8
62 blt 6f
63 subs r2, r2, #4
64 ldrlt r3, [r1], #4
65 ldmgeia r1!, {r4, r5}
66 strlt r3, [r0], #4
67 stmgeia r0!, {r4, r5}
68 subge r2, r2, #4
69
706: adds r2, r2, #4
71 EXITEQ
72 cmp r2, #2
73 ldrb r3, [r1], #1
74 ldrgeb r4, [r1], #1
75 ldrgtb r5, [r1], #1
76 strb r3, [r0], #1
77 strgeb r4, [r0], #1
78 strgtb r5, [r0], #1
79 EXIT
80
817: rsb ip, ip, #4
82 cmp ip, #2
83 ldrb r3, [r1], #1
84 ldrgeb r4, [r1], #1
85 ldrgtb r5, [r1], #1
86 strb r3, [r0], #1
87 strgeb r4, [r0], #1
88 strgtb r5, [r0], #1
89 subs r2, r2, ip
90 blt 6b
91 ands ip, r1, #3
92 beq 1b
93
948: bic r1, r1, #3
95 ldr r7, [r1], #4
96 cmp ip, #2
97 bgt 15f
98 beq 11f
99 cmp r2, #12
100 blt 10f
101 sub r2, r2, #12
1029: mov r3, r7, pull #8
103 ldmia r1!, {r4 - r7}
104 orr r3, r3, r4, push #24
105 mov r4, r4, pull #8
106 orr r4, r4, r5, push #24
107 mov r5, r5, pull #8
108 orr r5, r5, r6, push #24
109 mov r6, r6, pull #8
110 orr r6, r6, r7, push #24
111 stmia r0!, {r3 - r6}
112 subs r2, r2, #16
113 bge 9b
114 adds r2, r2, #12
115 blt 100f
11610: mov r3, r7, pull #8
117 ldr r7, [r1], #4
118 subs r2, r2, #4
119 orr r3, r3, r7, push #24
120 str r3, [r0], #4
121 bge 10b
122100: sub r1, r1, #3
123 b 6b
124
12511: cmp r2, #12
126 blt 13f /* */
127 sub r2, r2, #12
12812: mov r3, r7, pull #16
129 ldmia r1!, {r4 - r7}
130 orr r3, r3, r4, push #16
131 mov r4, r4, pull #16
132 orr r4, r4, r5, push #16
133 mov r5, r5, pull #16
134 orr r5, r5, r6, push #16
135 mov r6, r6, pull #16
136 orr r6, r6, r7, push #16
137 stmia r0!, {r3 - r6}
138 subs r2, r2, #16
139 bge 12b
140 adds r2, r2, #12
141 blt 14f
14213: mov r3, r7, pull #16
143 ldr r7, [r1], #4
144 subs r2, r2, #4
145 orr r3, r3, r7, push #16
146 str r3, [r0], #4
147 bge 13b
14814: sub r1, r1, #2
149 b 6b
150
15115: cmp r2, #12
152 blt 17f
153 sub r2, r2, #12
15416: mov r3, r7, pull #24
155 ldmia r1!, {r4 - r7}
156 orr r3, r3, r4, push #8
157 mov r4, r4, pull #24
158 orr r4, r4, r5, push #8
159 mov r5, r5, pull #24
160 orr r5, r5, r6, push #8
161 mov r6, r6, pull #24
162 orr r6, r6, r7, push #8
163 stmia r0!, {r3 - r6}
164 subs r2, r2, #16
165 bge 16b
166 adds r2, r2, #12
167 blt 18f
16817: mov r3, r7, pull #24
169 ldr r7, [r1], #4
170 subs r2, r2, #4
171 orr r3, r3, r7, push #8
172 str r3, [r0], #4
173 bge 17b
17418: sub r1, r1, #1
175 b 6b
176
177
17819: add r1, r1, r2
179 add r0, r0, r2
180 subs r2, r2, #4
181 blt 24f
182 ands ip, r0, #3
183 bne 25f
184 ands ip, r1, #3
185 bne 26f
186
18720: subs r2, r2, #8
188 blt 23f
189 subs r2, r2, #0x14
190 blt 22f
19121: ldmdb r1!, {r3 - r9, ip}
192 stmdb r0!, {r3 - r9, ip}
193 subs r2, r2, #32
194 bge 21b
19522: cmn r2, #16
196 ldmgedb r1!, {r3 - r6}
197 stmgedb r0!, {r3 - r6}
198 subge r2, r2, #16
199 adds r2, r2, #20
200 ldmgedb r1!, {r3 - r5}
201 stmgedb r0!, {r3 - r5}
202 subge r2, r2, #12
20323: adds r2, r2, #8
204 blt 24f
205 subs r2, r2, #4
206 ldrlt r3, [r1, #-4]!
207 ldmgedb r1!, {r4, r5}
208 strlt r3, [r0, #-4]!
209 stmgedb r0!, {r4, r5}
210 subge r2, r2, #4
211
21224: adds r2, r2, #4
213 EXITEQ
214 cmp r2, #2
215 ldrb r3, [r1, #-1]!
216 ldrgeb r4, [r1, #-1]!
217 ldrgtb r5, [r1, #-1]!
218 strb r3, [r0, #-1]!
219 strgeb r4, [r0, #-1]!
220 strgtb r5, [r0, #-1]!
221 EXIT
222
22325: cmp ip, #2
224 ldrb r3, [r1, #-1]!
225 ldrgeb r4, [r1, #-1]!
226 ldrgtb r5, [r1, #-1]!
227 strb r3, [r0, #-1]!
228 strgeb r4, [r0, #-1]!
229 strgtb r5, [r0, #-1]!
230 subs r2, r2, ip
231 blt 24b
232 ands ip, r1, #3
233 beq 20b
234
23526: bic r1, r1, #3
236 ldr r3, [r1], #0
237 cmp ip, #2
238 blt 34f
239 beq 30f
240 cmp r2, #12
241 blt 28f
242 sub r2, r2, #12
24327: mov r7, r3, push #8
244 ldmdb r1!, {r3, r4, r5, r6}
245 orr r7, r7, r6, pull #24
246 mov r6, r6, push #8
247 orr r6, r6, r5, pull #24
248 mov r5, r5, push #8
249 orr r5, r5, r4, pull #24
250 mov r4, r4, push #8
251 orr r4, r4, r3, pull #24
252 stmdb r0!, {r4, r5, r6, r7}
253 subs r2, r2, #16
254 bge 27b
255 adds r2, r2, #12
256 blt 29f
25728: mov ip, r3, push #8
258 ldr r3, [r1, #-4]!
259 subs r2, r2, #4
260 orr ip, ip, r3, pull #24
261 str ip, [r0, #-4]!
262 bge 28b
26329: add r1, r1, #3
264 b 24b
265
26630: cmp r2, #12
267 blt 32f
268 sub r2, r2, #12
26931: mov r7, r3, push #16
270 ldmdb r1!, {r3, r4, r5, r6}
271 orr r7, r7, r6, pull #16
272 mov r6, r6, push #16
273 orr r6, r6, r5, pull #16
274 mov r5, r5, push #16
275 orr r5, r5, r4, pull #16
276 mov r4, r4, push #16
277 orr r4, r4, r3, pull #16
278 stmdb r0!, {r4, r5, r6, r7}
279 subs r2, r2, #16
280 bge 31b
281 adds r2, r2, #12
282 blt 33f
28332: mov ip, r3, push #16
284 ldr r3, [r1, #-4]!
285 subs r2, r2, #4
286 orr ip, ip, r3, pull #16
287 str ip, [r0, #-4]!
288 bge 32b
28933: add r1, r1, #2
290 b 24b
291
29234: cmp r2, #12
293 blt 36f
294 sub r2, r2, #12
29535: mov r7, r3, push #24
296 ldmdb r1!, {r3, r4, r5, r6}
297 orr r7, r7, r6, pull #8
298 mov r6, r6, push #24
299 orr r6, r6, r5, pull #8
300 mov r5, r5, push #24
301 orr r5, r5, r4, pull #8
302 mov r4, r4, push #24
303 orr r4, r4, r3, pull #8
304 stmdb r0!, {r4, r5, r6, r7}
305 subs r2, r2, #16
306 bge 35b
307 adds r2, r2, #12
308 blt 37f
30936: mov ip, r3, push #24
310 ldr r3, [r1, #-4]!
311 subs r2, r2, #4
312 orr ip, ip, r3, pull #8
313 str ip, [r0, #-4]!
314 bge 36b
31537: add r1, r1, #1
316 b 24b
317
318 .align
diff --git a/arch/arm26/lib/memset.S b/arch/arm26/lib/memset.S
deleted file mode 100644
index aedec10b58f5..000000000000
--- a/arch/arm26/lib/memset.S
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/arch/arm26/lib/memset.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15 .text
16 .align 5
17 .word 0
18
191: subs r2, r2, #4 @ 1 do we have enough
20 blt 5f @ 1 bytes to align with?
21 cmp r3, #2 @ 1
22 strltb r1, [r0], #1 @ 1
23 strleb r1, [r0], #1 @ 1
24 strb r1, [r0], #1 @ 1
25 add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
26/*
27 * The pointer is now aligned and the length is adjusted. Try doing the
28 * memzero again.
29 */
30
31ENTRY(memset)
32 ands r3, r0, #3 @ 1 unaligned?
33 bne 1b @ 1
34/*
35 * we know that the pointer in r0 is aligned to a word boundary.
36 */
37 orr r1, r1, r1, lsl #8
38 orr r1, r1, r1, lsl #16
39 mov r3, r1
40 cmp r2, #16
41 blt 4f
42/*
43 * We need an extra register for this loop - save the return address and
44 * use the LR
45 */
46 str lr, [sp, #-4]!
47 mov ip, r1
48 mov lr, r1
49
502: subs r2, r2, #64
51 stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
52 stmgeia r0!, {r1, r3, ip, lr}
53 stmgeia r0!, {r1, r3, ip, lr}
54 stmgeia r0!, {r1, r3, ip, lr}
55 bgt 2b
56 LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go.
57/*
58 * No need to correct the count; we're only testing bits from now on
59 */
60 tst r2, #32
61 stmneia r0!, {r1, r3, ip, lr}
62 stmneia r0!, {r1, r3, ip, lr}
63 tst r2, #16
64 stmneia r0!, {r1, r3, ip, lr}
65 ldr lr, [sp], #4
66
674: tst r2, #8
68 stmneia r0!, {r1, r3}
69 tst r2, #4
70 strne r1, [r0], #4
71/*
72 * When we get here, we've got less than 4 bytes to zero. We
73 * may have an unaligned pointer as well.
74 */
755: tst r2, #2
76 strneb r1, [r0], #1
77 strneb r1, [r0], #1
78 tst r2, #1
79 strneb r1, [r0], #1
80 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/memzero.S b/arch/arm26/lib/memzero.S
deleted file mode 100644
index cc5bf6860061..000000000000
--- a/arch/arm26/lib/memzero.S
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/arch/arm26/lib/memzero.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14 .align 5
15 .word 0
16/*
17 * Align the pointer in r0. r3 contains the number of bytes that we are
18 * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
19 * don't bother; we use byte stores instead.
20 */
211: subs r1, r1, #4 @ 1 do we have enough
22 blt 5f @ 1 bytes to align with?
23 cmp r3, #2 @ 1
24 strltb r2, [r0], #1 @ 1
25 strleb r2, [r0], #1 @ 1
26 strb r2, [r0], #1 @ 1
27 add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3))
28/*
29 * The pointer is now aligned and the length is adjusted. Try doing the
30 * memzero again.
31 */
32
33ENTRY(__memzero)
34 mov r2, #0 @ 1
35 ands r3, r0, #3 @ 1 unaligned?
36 bne 1b @ 1
37/*
38 * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
39 */
40 cmp r1, #16 @ 1 we can skip this chunk if we
41 blt 4f @ 1 have < 16 bytes
42/*
43 * We need an extra register for this loop - save the return address and
44 * use the LR
45 */
46 str lr, [sp, #-4]! @ 1
47 mov ip, r2 @ 1
48 mov lr, r2 @ 1
49
503: subs r1, r1, #64 @ 1 write 32 bytes out per loop
51 stmgeia r0!, {r2, r3, ip, lr} @ 4
52 stmgeia r0!, {r2, r3, ip, lr} @ 4
53 stmgeia r0!, {r2, r3, ip, lr} @ 4
54 stmgeia r0!, {r2, r3, ip, lr} @ 4
55 bgt 3b @ 1
56 LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit
57/*
58 * No need to correct the count; we're only testing bits from now on
59 */
60 tst r1, #32 @ 1
61 stmneia r0!, {r2, r3, ip, lr} @ 4
62 stmneia r0!, {r2, r3, ip, lr} @ 4
63 tst r1, #16 @ 1 16 bytes or more?
64 stmneia r0!, {r2, r3, ip, lr} @ 4
65 ldr lr, [sp], #4 @ 1
66
674: tst r1, #8 @ 1 8 bytes or more?
68 stmneia r0!, {r2, r3} @ 2
69 tst r1, #4 @ 1 4 bytes or more?
70 strne r2, [r0], #4 @ 1
71/*
72 * When we get here, we've got less than 4 bytes to zero. We
73 * may have an unaligned pointer as well.
74 */
755: tst r1, #2 @ 1 2 bytes or more?
76 strneb r2, [r0], #1 @ 1
77 strneb r2, [r0], #1 @ 1
78 tst r1, #1 @ 1 a byte left over
79 strneb r2, [r0], #1 @ 1
80 RETINSTR(mov,pc,lr) @ 1
diff --git a/arch/arm26/lib/muldi3.c b/arch/arm26/lib/muldi3.c
deleted file mode 100644
index 44d611b1cfdb..000000000000
--- a/arch/arm26/lib/muldi3.c
+++ /dev/null
@@ -1,77 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33
34#define umul_ppmm(xh, xl, a, b) \
35{register USItype __t0, __t1, __t2; \
36 __asm__ ("%@ Inlined umul_ppmm \n\
37 mov %2, %5, lsr #16 \n\
38 mov %0, %6, lsr #16 \n\
39 bic %3, %5, %2, lsl #16 \n\
40 bic %4, %6, %0, lsl #16 \n\
41 mul %1, %3, %4 \n\
42 mul %4, %2, %4 \n\
43 mul %3, %0, %3 \n\
44 mul %0, %2, %0 \n\
45 adds %3, %4, %3 \n\
46 addcs %0, %0, #65536 \n\
47 adds %1, %1, %3, lsl #16 \n\
48 adc %0, %0, %3, lsr #16" \
49 : "=&r" ((USItype) (xh)), \
50 "=r" ((USItype) (xl)), \
51 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
52 : "r" ((USItype) (a)), \
53 "r" ((USItype) (b)));}
54
55
56#define __umulsidi3(u, v) \
57 ({DIunion __w; \
58 umul_ppmm (__w.s.high, __w.s.low, u, v); \
59 __w.ll; })
60
61
62DItype
63__muldi3 (DItype u, DItype v)
64{
65 DIunion w;
66 DIunion uu, vv;
67
68 uu.ll = u,
69 vv.ll = v;
70
71 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
72 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
73 + (USItype) uu.s.high * (USItype) vv.s.low);
74
75 return w.ll;
76}
77
diff --git a/arch/arm26/lib/putuser.S b/arch/arm26/lib/putuser.S
deleted file mode 100644
index 46c7f15f9f2d..000000000000
--- a/arch/arm26/lib/putuser.S
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * linux/arch/arm26/lib/putuser.S
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
11 *
12 * These functions have a non-standard call interface to make
13 * them more efficient, especially as they return an error
14 * value in addition to the "real" return value.
15 *
16 * __put_user_X
17 *
18 * Inputs: r0 contains the address
19 * r1, r2 contains the value
20 * Outputs: r0 is the error code
21 * lr corrupted
22 *
23 * No other registers must be altered. (see include/asm-arm/uaccess.h
24 * for specific ASM register usage).
25 *
26 * Note that ADDR_LIMIT is either 0 or 0xc0000000
27 * Note also that it is intended that __put_user_bad is not global.
28 */
29#include <asm/asm-offsets.h>
30#include <asm/thread_info.h>
31#include <asm/errno.h>
32
33 .global __put_user_1
34__put_user_1:
35 bic r2, sp, #0x1f00
36 bic r2, r2, #0x00ff
37 str lr, [sp, #-4]!
38 ldr r2, [r2, #TI_ADDR_LIMIT]
39 sub r2, r2, #1
40 cmp r0, r2
41 bge __put_user_bad
421: cmp r0, #0x02000000
43 strlsbt r1, [r0]
44 strgeb r1, [r0]
45 mov r0, #0
46 ldmfd sp!, {pc}^
47
48 .global __put_user_2
49__put_user_2:
50 bic r2, sp, #0x1f00
51 bic r2, r2, #0x00ff
52 str lr, [sp, #-4]!
53 ldr r2, [r2, #TI_ADDR_LIMIT]
54 sub r2, r2, #2
55 cmp r0, r2
56 bge __put_user_bad
572: cmp r0, #0x02000000
58 strlsbt r1, [r0], #1
59 strgeb r1, [r0], #1
60 mov r1, r1, lsr #8
613: strlsbt r1, [r0]
62 strgeb r1, [r0]
63 mov r0, #0
64 ldmfd sp!, {pc}^
65
66 .global __put_user_4
67__put_user_4:
68 bic r2, sp, #0x1f00
69 bic r2, r2, #0x00ff
70 str lr, [sp, #-4]!
71 ldr r2, [r2, #TI_ADDR_LIMIT]
72 sub r2, r2, #4
73 cmp r0, r2
744: bge __put_user_bad
75 cmp r0, #0x02000000
76 strlst r1, [r0]
77 strge r1, [r0]
78 mov r0, #0
79 ldmfd sp!, {pc}^
80
81 .global __put_user_8
82__put_user_8:
83 bic ip, sp, #0x1f00
84 bic ip, ip, #0x00ff
85 str lr, [sp, #-4]!
86 ldr ip, [ip, #TI_ADDR_LIMIT]
87 sub ip, ip, #8
88 cmp r0, ip
89 bge __put_user_bad
90 cmp r0, #0x02000000
915: strlst r1, [r0], #4
926: strlst r2, [r0]
93 strge r1, [r0], #4
94 strge r2, [r0]
95 mov r0, #0
96 ldmfd sp!, {pc}^
97
98__put_user_bad:
99 mov r0, #-EFAULT
100 mov pc, lr
101
102.section __ex_table, "a"
103 .long 1b, __put_user_bad
104 .long 2b, __put_user_bad
105 .long 3b, __put_user_bad
106 .long 4b, __put_user_bad
107 .long 5b, __put_user_bad
108 .long 6b, __put_user_bad
109.previous
diff --git a/arch/arm26/lib/setbit.S b/arch/arm26/lib/setbit.S
deleted file mode 100644
index e180c1a1b2f1..000000000000
--- a/arch/arm26/lib/setbit.S
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/arch/arm26/lib/setbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14/*
15 * Purpose : Function to set a bit
16 * Prototype: int set_bit(int bit, void *addr)
17 */
18ENTRY(_set_bit_be)
19 eor r0, r0, #0x18 @ big endian byte ordering
20ENTRY(_set_bit_le)
21 and r2, r0, #7
22 mov r3, #1
23 mov r3, r3, lsl r2
24 save_and_disable_irqs ip, r2
25 ldrb r2, [r1, r0, lsr #3]
26 orr r2, r2, r3
27 strb r2, [r1, r0, lsr #3]
28 restore_irqs ip
29 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/strchr.S b/arch/arm26/lib/strchr.S
deleted file mode 100644
index ecfff21aa7c7..000000000000
--- a/arch/arm26/lib/strchr.S
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * linux/arch/arm26/lib/strchr.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15 .text
16 .align 5
17ENTRY(strchr)
181: ldrb r2, [r0], #1
19 teq r2, r1
20 teqne r2, #0
21 bne 1b
22 teq r2, #0
23 moveq r0, #0
24 subne r0, r0, #1
25 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/strrchr.S b/arch/arm26/lib/strrchr.S
deleted file mode 100644
index db43b28e78dc..000000000000
--- a/arch/arm26/lib/strrchr.S
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * linux/arch/arm26/lib/strrchr.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15 .text
16 .align 5
17ENTRY(strrchr)
18 mov r3, #0
191: ldrb r2, [r0], #1
20 teq r2, r1
21 subeq r3, r0, #1
22 teq r2, #0
23 bne 1b
24 mov r0, r3
25 RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/testchangebit.S b/arch/arm26/lib/testchangebit.S
deleted file mode 100644
index 17049a2d93a4..000000000000
--- a/arch/arm26/lib/testchangebit.S
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/arch/arm26/lib/testchangebit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14ENTRY(_test_and_change_bit_be)
15 eor r0, r0, #0x18 @ big endian byte ordering
16ENTRY(_test_and_change_bit_le)
17 add r1, r1, r0, lsr #3
18 and r3, r0, #7
19 mov r0, #1
20 save_and_disable_irqs ip, r2
21 ldrb r2, [r1]
22 tst r2, r0, lsl r3
23 eor r2, r2, r0, lsl r3
24 strb r2, [r1]
25 restore_irqs ip
26 moveq r0, #0
27 RETINSTR(mov,pc,lr)
28
29
diff --git a/arch/arm26/lib/testclearbit.S b/arch/arm26/lib/testclearbit.S
deleted file mode 100644
index 2506bd743ab4..000000000000
--- a/arch/arm26/lib/testclearbit.S
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/arch/arm26/lib/testclearbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14ENTRY(_test_and_clear_bit_be)
15 eor r0, r0, #0x18 @ big endian byte ordering
16ENTRY(_test_and_clear_bit_le)
17 add r1, r1, r0, lsr #3 @ Get byte offset
18 and r3, r0, #7 @ Get bit offset
19 mov r0, #1
20 save_and_disable_irqs ip, r2
21 ldrb r2, [r1]
22 tst r2, r0, lsl r3
23 bic r2, r2, r0, lsl r3
24 strb r2, [r1]
25 restore_irqs ip
26 moveq r0, #0
27 RETINSTR(mov,pc,lr)
28
29
diff --git a/arch/arm26/lib/testsetbit.S b/arch/arm26/lib/testsetbit.S
deleted file mode 100644
index f827de64b22d..000000000000
--- a/arch/arm26/lib/testsetbit.S
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/arch/arm26/lib/testsetbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12 .text
13
14ENTRY(_test_and_set_bit_be)
15 eor r0, r0, #0x18 @ big endian byte ordering
16ENTRY(_test_and_set_bit_le)
17 add r1, r1, r0, lsr #3 @ Get byte offset
18 and r3, r0, #7 @ Get bit offset
19 mov r0, #1
20 save_and_disable_irqs ip, r2
21 ldrb r2, [r1]
22 tst r2, r0, lsl r3
23 orr r2, r2, r0, lsl r3
24 strb r2, [r1]
25 restore_irqs ip
26 moveq r0, #0
27 RETINSTR(mov,pc,lr)
28
29
diff --git a/arch/arm26/lib/uaccess-kernel.S b/arch/arm26/lib/uaccess-kernel.S
deleted file mode 100644
index 3950a1f6bc99..000000000000
--- a/arch/arm26/lib/uaccess-kernel.S
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * linux/arch/arm26/lib/uaccess-kernel.S
3 *
4 * Copyright (C) 1998 Russell King
5 *
6 * Note! Some code fragments found in here have a special calling
7 * convention - they are not APCS compliant!
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16 .text
17
18//FIXME - surely this can be done in C not asm, removing the problem of keeping C and asm in sync? (this is a struct uaccess_t)
19
20 .globl uaccess_kernel
21uaccess_kernel:
22 .word uaccess_kernel_put_byte
23 .word uaccess_kernel_get_byte
24 .word uaccess_kernel_put_half
25 .word uaccess_kernel_get_half
26 .word uaccess_kernel_put_word
27 .word uaccess_kernel_get_word
28 .word uaccess_kernel_put_dword
29 .word uaccess_kernel_copy
30 .word uaccess_kernel_copy
31 .word uaccess_kernel_clear
32 .word uaccess_kernel_strncpy
33 .word uaccess_kernel_strnlen
34
35@ In : r0 = x, r1 = addr, r2 = error
36@ Out: r2 = error
37uaccess_kernel_put_byte:
38 stmfd sp!, {lr}
39 strb r0, [r1]
40 ldmfd sp!, {pc}^
41
42@ In : r0 = x, r1 = addr, r2 = error
43@ Out: r2 = error
44uaccess_kernel_put_half:
45 stmfd sp!, {lr}
46 strb r0, [r1]
47 mov r0, r0, lsr #8
48 strb r0, [r1, #1]
49 ldmfd sp!, {pc}^
50
51@ In : r0 = x, r1 = addr, r2 = error
52@ Out: r2 = error
53uaccess_kernel_put_word:
54 stmfd sp!, {lr}
55 str r0, [r1]
56 ldmfd sp!, {pc}^
57
58@ In : r0 = x, r1 = addr, r2 = error
59@ Out: r2 = error
60uaccess_kernel_put_dword:
61 stmfd sp!, {lr}
62 str r0, [r1], #4
63 str r0, [r1], #0
64 ldmfd sp!, {pc}^
65
66@ In : r0 = addr, r1 = error
67@ Out: r0 = x, r1 = error
68uaccess_kernel_get_byte:
69 stmfd sp!, {lr}
70 ldrb r0, [r0]
71 ldmfd sp!, {pc}^
72
73@ In : r0 = addr, r1 = error
74@ Out: r0 = x, r1 = error
75uaccess_kernel_get_half:
76 stmfd sp!, {lr}
77 ldr r0, [r0]
78 mov r0, r0, lsl #16
79 mov r0, r0, lsr #16
80 ldmfd sp!, {pc}^
81
82@ In : r0 = addr, r1 = error
83@ Out: r0 = x, r1 = error
84uaccess_kernel_get_word:
85 stmfd sp!, {lr}
86 ldr r0, [r0]
87 ldmfd sp!, {pc}^
88
89
90/* Prototype: int uaccess_kernel_copy(void *to, const char *from, size_t n)
91 * Purpose : copy a block to kernel memory from kernel memory
92 * Params : to - kernel memory
93 * : from - kernel memory
94 * : n - number of bytes to copy
95 * Returns : Number of bytes NOT copied.
96 */
97uaccess_kernel_copy:
98 stmfd sp!, {lr}
99 bl memcpy
100 mov r0, #0
101 ldmfd sp!, {pc}^
102
103/* Prototype: int uaccess_kernel_clear(void *addr, size_t sz)
104 * Purpose : clear some kernel memory
105 * Params : addr - kernel memory address to clear
106 * : sz - number of bytes to clear
107 * Returns : number of bytes NOT cleared
108 */
109uaccess_kernel_clear:
110 stmfd sp!, {lr}
111 mov r2, #0
112 cmp r1, #4
113 blt 2f
114 ands ip, r0, #3
115 beq 1f
116 cmp ip, #1
117 strb r2, [r0], #1
118 strleb r2, [r0], #1
119 strltb r2, [r0], #1
120 rsb ip, ip, #4
121 sub r1, r1, ip @ 7 6 5 4 3 2 1
1221: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
123 bmi 2f
124 str r2, [r0], #4
125 str r2, [r0], #4
126 b 1b
1272: adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
128 strpl r2, [r0], #4
129 tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
130 strneb r2, [r0], #1
131 strneb r2, [r0], #1
132 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
133 strneb r2, [r0], #1
134 mov r0, #0
135 ldmfd sp!, {pc}^
136
137/* Prototype: size_t uaccess_kernel_strncpy(char *dst, char *src, size_t len)
138 * Purpose : copy a string from kernel memory to kernel memory
139 * Params : dst - kernel memory destination
140 * : src - kernel memory source
141 * : len - maximum length of string
142 * Returns : number of characters copied
143 */
144uaccess_kernel_strncpy:
145 stmfd sp!, {lr}
146 mov ip, r2
1471: subs r2, r2, #1
148 bmi 2f
149 ldrb r3, [r1], #1
150 strb r3, [r0], #1
151 teq r3, #0
152 bne 1b
1532: subs r0, ip, r2
154 ldmfd sp!, {pc}^
155
156/* Prototype: int uaccess_kernel_strlen(char *str, long n)
157 * Purpose : get length of a string in kernel memory
158 * Params : str - address of string in kernel memory
159 * Returns : length of string *including terminator*,
160 * or zero on exception, or n + 1 if too long
161 */
162uaccess_kernel_strnlen:
163 stmfd sp!, {lr}
164 mov r2, r0
1651: ldrb r1, [r0], #1
166 teq r1, #0
167 beq 2f
168 subs r1, r1, #1
169 bne 1b
170 add r0, r0, #1
1712: sub r0, r0, r2
172 ldmfd sp!, {pc}^
173
diff --git a/arch/arm26/lib/uaccess-user.S b/arch/arm26/lib/uaccess-user.S
deleted file mode 100644
index 130b8f28610a..000000000000
--- a/arch/arm26/lib/uaccess-user.S
+++ /dev/null
@@ -1,718 +0,0 @@
1/*
2 * linux/arch/arm26/lib/uaccess-user.S
3 *
4 * Copyright (C) 1995, 1996,1997,1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Routines to block copy data to/from user memory
11 * These are highly optimised both for the 4k page size
12 * and for various alignments.
13 */
14#include <linux/linkage.h>
15#include <asm/assembler.h>
16#include <asm/errno.h>
17#include <asm/page.h>
18
19 .text
20
21//FIXME - surely this can be done in C not asm, removing the problem of keeping C and asm in sync? (this is a struct uaccess_t)
22 .globl uaccess_user
23uaccess_user:
24 .word uaccess_user_put_byte
25 .word uaccess_user_get_byte
26 .word uaccess_user_put_half
27 .word uaccess_user_get_half
28 .word uaccess_user_put_word
29 .word uaccess_user_get_word
30 .word uaccess_user_put_dword
31 .word uaccess_user_copy_from_user
32 .word uaccess_user_copy_to_user
33 .word uaccess_user_clear_user
34 .word uaccess_user_strncpy_from_user
35 .word uaccess_user_strnlen_user
36
37
38@ In : r0 = x, r1 = addr, r2 = error
39@ Out: r2 = error
40uaccess_user_put_byte:
41 stmfd sp!, {lr}
42USER( strbt r0, [r1])
43 ldmfd sp!, {pc}^
44
45@ In : r0 = x, r1 = addr, r2 = error
46@ Out: r2 = error
47uaccess_user_put_half:
48 stmfd sp!, {lr}
49USER( strbt r0, [r1], #1)
50 mov r0, r0, lsr #8
51USER( strbt r0, [r1])
52 ldmfd sp!, {pc}^
53
54@ In : r0 = x, r1 = addr, r2 = error
55@ Out: r2 = error
56uaccess_user_put_word:
57 stmfd sp!, {lr}
58USER( strt r0, [r1])
59 ldmfd sp!, {pc}^
60
61@ In : r0 = x, r1 = addr, r2 = error
62@ Out: r2 = error
63uaccess_user_put_dword:
64 stmfd sp!, {lr}
65USER( strt r0, [r1], #4)
66USER( strt r0, [r1], #0)
67 ldmfd sp!, {pc}^
68
699001: mov r2, #-EFAULT
70 ldmfd sp!, {pc}^
71
72
73@ In : r0 = addr, r1 = error
74@ Out: r0 = x, r1 = error
75uaccess_user_get_byte:
76 stmfd sp!, {lr}
77USER( ldrbt r0, [r0])
78 ldmfd sp!, {pc}^
79
80@ In : r0 = addr, r1 = error
81@ Out: r0 = x, r1 = error
82uaccess_user_get_half:
83 stmfd sp!, {lr}
84USER( ldrt r0, [r0])
85 mov r0, r0, lsl #16
86 mov r0, r0, lsr #16
87 ldmfd sp!, {pc}^
88
89@ In : r0 = addr, r1 = error
90@ Out: r0 = x, r1 = error
91uaccess_user_get_word:
92 stmfd sp!, {lr}
93USER( ldrt r0, [r0])
94 ldmfd sp!, {pc}^
95
969001: mov r1, #-EFAULT
97 ldmfd sp!, {pc}^
98
99/* Prototype: int uaccess_user_copy_to_user(void *to, const char *from, size_t n)
100 * Purpose : copy a block to user memory from kernel memory
101 * Params : to - user memory
102 * : from - kernel memory
103 * : n - number of bytes to copy
104 * Returns : Number of bytes NOT copied.
105 */
106
107.c2u_dest_not_aligned:
108 rsb ip, ip, #4
109 cmp ip, #2
110 ldrb r3, [r1], #1
111USER( strbt r3, [r0], #1) @ May fault
112 ldrgeb r3, [r1], #1
113USER( strgebt r3, [r0], #1) @ May fault
114 ldrgtb r3, [r1], #1
115USER( strgtbt r3, [r0], #1) @ May fault
116 sub r2, r2, ip
117 b .c2u_dest_aligned
118
119ENTRY(uaccess_user_copy_to_user)
120 stmfd sp!, {r2, r4 - r7, lr}
121 cmp r2, #4
122 blt .c2u_not_enough
123 ands ip, r0, #3
124 bne .c2u_dest_not_aligned
125.c2u_dest_aligned:
126
127 ands ip, r1, #3
128 bne .c2u_src_not_aligned
129/*
130 * Seeing as there has to be at least 8 bytes to copy, we can
131 * copy one word, and force a user-mode page fault...
132 */
133
134.c2u_0fupi: subs r2, r2, #4
135 addmi ip, r2, #4
136 bmi .c2u_0nowords
137 ldr r3, [r1], #4
138USER( strt r3, [r0], #4) @ May fault
139 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
140 rsb ip, ip, #0
141 movs ip, ip, lsr #32 - PAGE_SHIFT
142 beq .c2u_0fupi
143/*
144 * ip = max no. of bytes to copy before needing another "strt" insn
145 */
146 cmp r2, ip
147 movlt ip, r2
148 sub r2, r2, ip
149 subs ip, ip, #32
150 blt .c2u_0rem8lp
151
152.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
153 stmia r0!, {r3 - r6} @ Shouldnt fault
154 ldmia r1!, {r3 - r6}
155 stmia r0!, {r3 - r6} @ Shouldnt fault
156 subs ip, ip, #32
157 bpl .c2u_0cpy8lp
158.c2u_0rem8lp: cmn ip, #16
159 ldmgeia r1!, {r3 - r6}
160 stmgeia r0!, {r3 - r6} @ Shouldnt fault
161 tst ip, #8
162 ldmneia r1!, {r3 - r4}
163 stmneia r0!, {r3 - r4} @ Shouldnt fault
164 tst ip, #4
165 ldrne r3, [r1], #4
166 strnet r3, [r0], #4 @ Shouldnt fault
167 ands ip, ip, #3
168 beq .c2u_0fupi
169.c2u_0nowords: teq ip, #0
170 beq .c2u_finished
171.c2u_nowords: cmp ip, #2
172 ldrb r3, [r1], #1
173USER( strbt r3, [r0], #1) @ May fault
174 ldrgeb r3, [r1], #1
175USER( strgebt r3, [r0], #1) @ May fault
176 ldrgtb r3, [r1], #1
177USER( strgtbt r3, [r0], #1) @ May fault
178 b .c2u_finished
179
180.c2u_not_enough:
181 movs ip, r2
182 bne .c2u_nowords
183.c2u_finished: mov r0, #0
184 LOADREGS(fd,sp!,{r2, r4 - r7, pc})
185
186.c2u_src_not_aligned:
187 bic r1, r1, #3
188 ldr r7, [r1], #4
189 cmp ip, #2
190 bgt .c2u_3fupi
191 beq .c2u_2fupi
192.c2u_1fupi: subs r2, r2, #4
193 addmi ip, r2, #4
194 bmi .c2u_1nowords
195 mov r3, r7, pull #8
196 ldr r7, [r1], #4
197 orr r3, r3, r7, push #24
198USER( strt r3, [r0], #4) @ May fault
199 mov ip, r0, lsl #32 - PAGE_SHIFT
200 rsb ip, ip, #0
201 movs ip, ip, lsr #32 - PAGE_SHIFT
202 beq .c2u_1fupi
203 cmp r2, ip
204 movlt ip, r2
205 sub r2, r2, ip
206 subs ip, ip, #16
207 blt .c2u_1rem8lp
208
209.c2u_1cpy8lp: mov r3, r7, pull #8
210 ldmia r1!, {r4 - r7}
211 orr r3, r3, r4, push #24
212 mov r4, r4, pull #8
213 orr r4, r4, r5, push #24
214 mov r5, r5, pull #8
215 orr r5, r5, r6, push #24
216 mov r6, r6, pull #8
217 orr r6, r6, r7, push #24
218 stmia r0!, {r3 - r6} @ Shouldnt fault
219 subs ip, ip, #16
220 bpl .c2u_1cpy8lp
221.c2u_1rem8lp: tst ip, #8
222 movne r3, r7, pull #8
223 ldmneia r1!, {r4, r7}
224 orrne r3, r3, r4, push #24
225 movne r4, r4, pull #8
226 orrne r4, r4, r7, push #24
227 stmneia r0!, {r3 - r4} @ Shouldnt fault
228 tst ip, #4
229 movne r3, r7, pull #8
230 ldrne r7, [r1], #4
231 orrne r3, r3, r7, push #24
232 strnet r3, [r0], #4 @ Shouldnt fault
233 ands ip, ip, #3
234 beq .c2u_1fupi
235.c2u_1nowords: mov r3, r7, lsr #byte(1)
236 teq ip, #0
237 beq .c2u_finished
238 cmp ip, #2
239USER( strbt r3, [r0], #1) @ May fault
240 movge r3, r7, lsr #byte(2)
241USER( strgebt r3, [r0], #1) @ May fault
242 movgt r3, r7, lsr #byte(3)
243USER( strgtbt r3, [r0], #1) @ May fault
244 b .c2u_finished
245
246.c2u_2fupi: subs r2, r2, #4
247 addmi ip, r2, #4
248 bmi .c2u_2nowords
249 mov r3, r7, pull #16
250 ldr r7, [r1], #4
251 orr r3, r3, r7, push #16
252USER( strt r3, [r0], #4) @ May fault
253 mov ip, r0, lsl #32 - PAGE_SHIFT
254 rsb ip, ip, #0
255 movs ip, ip, lsr #32 - PAGE_SHIFT
256 beq .c2u_2fupi
257 cmp r2, ip
258 movlt ip, r2
259 sub r2, r2, ip
260 subs ip, ip, #16
261 blt .c2u_2rem8lp
262
263.c2u_2cpy8lp: mov r3, r7, pull #16
264 ldmia r1!, {r4 - r7}
265 orr r3, r3, r4, push #16
266 mov r4, r4, pull #16
267 orr r4, r4, r5, push #16
268 mov r5, r5, pull #16
269 orr r5, r5, r6, push #16
270 mov r6, r6, pull #16
271 orr r6, r6, r7, push #16
272 stmia r0!, {r3 - r6} @ Shouldnt fault
273 subs ip, ip, #16
274 bpl .c2u_2cpy8lp
275.c2u_2rem8lp: tst ip, #8
276 movne r3, r7, pull #16
277 ldmneia r1!, {r4, r7}
278 orrne r3, r3, r4, push #16
279 movne r4, r4, pull #16
280 orrne r4, r4, r7, push #16
281 stmneia r0!, {r3 - r4} @ Shouldnt fault
282 tst ip, #4
283 movne r3, r7, pull #16
284 ldrne r7, [r1], #4
285 orrne r3, r3, r7, push #16
286 strnet r3, [r0], #4 @ Shouldnt fault
287 ands ip, ip, #3
288 beq .c2u_2fupi
289.c2u_2nowords: mov r3, r7, lsr #byte(2)
290 teq ip, #0
291 beq .c2u_finished
292 cmp ip, #2
293USER( strbt r3, [r0], #1) @ May fault
294 movge r3, r7, lsr #byte(3)
295USER( strgebt r3, [r0], #1) @ May fault
296 ldrgtb r3, [r1], #0
297USER( strgtbt r3, [r0], #1) @ May fault
298 b .c2u_finished
299
300.c2u_3fupi: subs r2, r2, #4
301 addmi ip, r2, #4
302 bmi .c2u_3nowords
303 mov r3, r7, pull #24
304 ldr r7, [r1], #4
305 orr r3, r3, r7, push #8
306USER( strt r3, [r0], #4) @ May fault
307 mov ip, r0, lsl #32 - PAGE_SHIFT
308 rsb ip, ip, #0
309 movs ip, ip, lsr #32 - PAGE_SHIFT
310 beq .c2u_3fupi
311 cmp r2, ip
312 movlt ip, r2
313 sub r2, r2, ip
314 subs ip, ip, #16
315 blt .c2u_3rem8lp
316
317.c2u_3cpy8lp: mov r3, r7, pull #24
318 ldmia r1!, {r4 - r7}
319 orr r3, r3, r4, push #8
320 mov r4, r4, pull #24
321 orr r4, r4, r5, push #8
322 mov r5, r5, pull #24
323 orr r5, r5, r6, push #8
324 mov r6, r6, pull #24
325 orr r6, r6, r7, push #8
326 stmia r0!, {r3 - r6} @ Shouldnt fault
327 subs ip, ip, #16
328 bpl .c2u_3cpy8lp
329.c2u_3rem8lp: tst ip, #8
330 movne r3, r7, pull #24
331 ldmneia r1!, {r4, r7}
332 orrne r3, r3, r4, push #8
333 movne r4, r4, pull #24
334 orrne r4, r4, r7, push #8
335 stmneia r0!, {r3 - r4} @ Shouldnt fault
336 tst ip, #4
337 movne r3, r7, pull #24
338 ldrne r7, [r1], #4
339 orrne r3, r3, r7, push #8
340 strnet r3, [r0], #4 @ Shouldnt fault
341 ands ip, ip, #3
342 beq .c2u_3fupi
343.c2u_3nowords: mov r3, r7, lsr #byte(3)
344 teq ip, #0
345 beq .c2u_finished
346 cmp ip, #2
347USER( strbt r3, [r0], #1) @ May fault
348 ldrgeb r3, [r1], #1
349USER( strgebt r3, [r0], #1) @ May fault
350 ldrgtb r3, [r1], #0
351USER( strgtbt r3, [r0], #1) @ May fault
352 b .c2u_finished
353
354 .section .fixup,"ax"
355 .align 0
3569001: LOADREGS(fd,sp!, {r0, r4 - r7, pc})
357 .previous
358
359/* Prototype: unsigned long uaccess_user_copy_from_user(void *to,const void *from,unsigned long n);
360 * Purpose : copy a block from user memory to kernel memory
361 * Params : to - kernel memory
362 * : from - user memory
363 * : n - number of bytes to copy
364 * Returns : Number of bytes NOT copied.
365 */
366.cfu_dest_not_aligned:
367 rsb ip, ip, #4
368 cmp ip, #2
369USER( ldrbt r3, [r1], #1) @ May fault
370 strb r3, [r0], #1
371USER( ldrgebt r3, [r1], #1) @ May fault
372 strgeb r3, [r0], #1
373USER( ldrgtbt r3, [r1], #1) @ May fault
374 strgtb r3, [r0], #1
375 sub r2, r2, ip
376 b .cfu_dest_aligned
377
378ENTRY(uaccess_user_copy_from_user)
379 stmfd sp!, {r0, r2, r4 - r7, lr}
380 cmp r2, #4
381 blt .cfu_not_enough
382 ands ip, r0, #3
383 bne .cfu_dest_not_aligned
384.cfu_dest_aligned:
385 ands ip, r1, #3
386 bne .cfu_src_not_aligned
387/*
388 * Seeing as there has to be at least 8 bytes to copy, we can
389 * copy one word, and force a user-mode page fault...
390 */
391
392.cfu_0fupi: subs r2, r2, #4
393 addmi ip, r2, #4
394 bmi .cfu_0nowords
395USER( ldrt r3, [r1], #4)
396 str r3, [r0], #4
397 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
398 rsb ip, ip, #0
399 movs ip, ip, lsr #32 - PAGE_SHIFT
400 beq .cfu_0fupi
401/*
402 * ip = max no. of bytes to copy before needing another "strt" insn
403 */
404 cmp r2, ip
405 movlt ip, r2
406 sub r2, r2, ip
407 subs ip, ip, #32
408 blt .cfu_0rem8lp
409
410.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
411 stmia r0!, {r3 - r6}
412 ldmia r1!, {r3 - r6} @ Shouldnt fault
413 stmia r0!, {r3 - r6}
414 subs ip, ip, #32
415 bpl .cfu_0cpy8lp
416.cfu_0rem8lp: cmn ip, #16
417 ldmgeia r1!, {r3 - r6} @ Shouldnt fault
418 stmgeia r0!, {r3 - r6}
419 tst ip, #8
420 ldmneia r1!, {r3 - r4} @ Shouldnt fault
421 stmneia r0!, {r3 - r4}
422 tst ip, #4
423 ldrnet r3, [r1], #4 @ Shouldnt fault
424 strne r3, [r0], #4
425 ands ip, ip, #3
426 beq .cfu_0fupi
427.cfu_0nowords: teq ip, #0
428 beq .cfu_finished
429.cfu_nowords: cmp ip, #2
430USER( ldrbt r3, [r1], #1) @ May fault
431 strb r3, [r0], #1
432USER( ldrgebt r3, [r1], #1) @ May fault
433 strgeb r3, [r0], #1
434USER( ldrgtbt r3, [r1], #1) @ May fault
435 strgtb r3, [r0], #1
436 b .cfu_finished
437
438.cfu_not_enough:
439 movs ip, r2
440 bne .cfu_nowords
441.cfu_finished: mov r0, #0
442 add sp, sp, #8
443 LOADREGS(fd,sp!,{r4 - r7, pc})
444
445.cfu_src_not_aligned:
446 bic r1, r1, #3
447USER( ldrt r7, [r1], #4) @ May fault
448 cmp ip, #2
449 bgt .cfu_3fupi
450 beq .cfu_2fupi
451.cfu_1fupi: subs r2, r2, #4
452 addmi ip, r2, #4
453 bmi .cfu_1nowords
454 mov r3, r7, pull #8
455USER( ldrt r7, [r1], #4) @ May fault
456 orr r3, r3, r7, push #24
457 str r3, [r0], #4
458 mov ip, r1, lsl #32 - PAGE_SHIFT
459 rsb ip, ip, #0
460 movs ip, ip, lsr #32 - PAGE_SHIFT
461 beq .cfu_1fupi
462 cmp r2, ip
463 movlt ip, r2
464 sub r2, r2, ip
465 subs ip, ip, #16
466 blt .cfu_1rem8lp
467
468.cfu_1cpy8lp: mov r3, r7, pull #8
469 ldmia r1!, {r4 - r7} @ Shouldnt fault
470 orr r3, r3, r4, push #24
471 mov r4, r4, pull #8
472 orr r4, r4, r5, push #24
473 mov r5, r5, pull #8
474 orr r5, r5, r6, push #24
475 mov r6, r6, pull #8
476 orr r6, r6, r7, push #24
477 stmia r0!, {r3 - r6}
478 subs ip, ip, #16
479 bpl .cfu_1cpy8lp
480.cfu_1rem8lp: tst ip, #8
481 movne r3, r7, pull #8
482 ldmneia r1!, {r4, r7} @ Shouldnt fault
483 orrne r3, r3, r4, push #24
484 movne r4, r4, pull #8
485 orrne r4, r4, r7, push #24
486 stmneia r0!, {r3 - r4}
487 tst ip, #4
488 movne r3, r7, pull #8
489USER( ldrnet r7, [r1], #4) @ May fault
490 orrne r3, r3, r7, push #24
491 strne r3, [r0], #4
492 ands ip, ip, #3
493 beq .cfu_1fupi
494.cfu_1nowords: mov r3, r7, lsr #byte(1)
495 teq ip, #0
496 beq .cfu_finished
497 cmp ip, #2
498 strb r3, [r0], #1
499 movge r3, r7, lsr #byte(2)
500 strgeb r3, [r0], #1
501 movgt r3, r7, lsr #byte(3)
502 strgtb r3, [r0], #1
503 b .cfu_finished
504
505.cfu_2fupi: subs r2, r2, #4
506 addmi ip, r2, #4
507 bmi .cfu_2nowords
508 mov r3, r7, pull #16
509USER( ldrt r7, [r1], #4) @ May fault
510 orr r3, r3, r7, push #16
511 str r3, [r0], #4
512 mov ip, r1, lsl #32 - PAGE_SHIFT
513 rsb ip, ip, #0
514 movs ip, ip, lsr #32 - PAGE_SHIFT
515 beq .cfu_2fupi
516 cmp r2, ip
517 movlt ip, r2
518 sub r2, r2, ip
519 subs ip, ip, #16
520 blt .cfu_2rem8lp
521
522.cfu_2cpy8lp: mov r3, r7, pull #16
523 ldmia r1!, {r4 - r7} @ Shouldnt fault
524 orr r3, r3, r4, push #16
525 mov r4, r4, pull #16
526 orr r4, r4, r5, push #16
527 mov r5, r5, pull #16
528 orr r5, r5, r6, push #16
529 mov r6, r6, pull #16
530 orr r6, r6, r7, push #16
531 stmia r0!, {r3 - r6}
532 subs ip, ip, #16
533 bpl .cfu_2cpy8lp
534.cfu_2rem8lp: tst ip, #8
535 movne r3, r7, pull #16
536 ldmneia r1!, {r4, r7} @ Shouldnt fault
537 orrne r3, r3, r4, push #16
538 movne r4, r4, pull #16
539 orrne r4, r4, r7, push #16
540 stmneia r0!, {r3 - r4}
541 tst ip, #4
542 movne r3, r7, pull #16
543USER( ldrnet r7, [r1], #4) @ May fault
544 orrne r3, r3, r7, push #16
545 strne r3, [r0], #4
546 ands ip, ip, #3
547 beq .cfu_2fupi
548.cfu_2nowords: mov r3, r7, lsr #byte(2)
549 teq ip, #0
550 beq .cfu_finished
551 cmp ip, #2
552 strb r3, [r0], #1
553 movge r3, r7, lsr #byte(3)
554 strgeb r3, [r0], #1
555USER( ldrgtbt r3, [r1], #0) @ May fault
556 strgtb r3, [r0], #1
557 b .cfu_finished
558
559.cfu_3fupi: subs r2, r2, #4
560 addmi ip, r2, #4
561 bmi .cfu_3nowords
562 mov r3, r7, pull #24
563USER( ldrt r7, [r1], #4) @ May fault
564 orr r3, r3, r7, push #8
565 str r3, [r0], #4
566 mov ip, r1, lsl #32 - PAGE_SHIFT
567 rsb ip, ip, #0
568 movs ip, ip, lsr #32 - PAGE_SHIFT
569 beq .cfu_3fupi
570 cmp r2, ip
571 movlt ip, r2
572 sub r2, r2, ip
573 subs ip, ip, #16
574 blt .cfu_3rem8lp
575
576.cfu_3cpy8lp: mov r3, r7, pull #24
577 ldmia r1!, {r4 - r7} @ Shouldnt fault
578 orr r3, r3, r4, push #8
579 mov r4, r4, pull #24
580 orr r4, r4, r5, push #8
581 mov r5, r5, pull #24
582 orr r5, r5, r6, push #8
583 mov r6, r6, pull #24
584 orr r6, r6, r7, push #8
585 stmia r0!, {r3 - r6}
586 subs ip, ip, #16
587 bpl .cfu_3cpy8lp
588.cfu_3rem8lp: tst ip, #8
589 movne r3, r7, pull #24
590 ldmneia r1!, {r4, r7} @ Shouldnt fault
591 orrne r3, r3, r4, push #8
592 movne r4, r4, pull #24
593 orrne r4, r4, r7, push #8
594 stmneia r0!, {r3 - r4}
595 tst ip, #4
596 movne r3, r7, pull #24
597USER( ldrnet r7, [r1], #4) @ May fault
598 orrne r3, r3, r7, push #8
599 strne r3, [r0], #4
600 ands ip, ip, #3
601 beq .cfu_3fupi
602.cfu_3nowords: mov r3, r7, lsr #byte(3)
603 teq ip, #0
604 beq .cfu_finished
605 cmp ip, #2
606 strb r3, [r0], #1
607USER( ldrgebt r3, [r1], #1) @ May fault
608 strgeb r3, [r0], #1
609USER( ldrgtbt r3, [r1], #1) @ May fault
610 strgtb r3, [r0], #1
611 b .cfu_finished
612
613 .section .fixup,"ax"
614 .align 0
615 /*
616 * We took an exception. r0 contains a pointer to
617 * the byte not copied.
618 */
6199001: ldr r2, [sp], #4 @ void *to
620 sub r2, r0, r2 @ bytes copied
621 ldr r1, [sp], #4 @ unsigned long count
622 subs r4, r1, r2 @ bytes left to copy
623 movne r1, r4
624 blne __memzero
625 mov r0, r4
626 LOADREGS(fd,sp!, {r4 - r7, pc})
627 .previous
628
629/* Prototype: int uaccess_user_clear_user(void *addr, size_t sz)
630 * Purpose : clear some user memory
631 * Params : addr - user memory address to clear
632 * : sz - number of bytes to clear
633 * Returns : number of bytes NOT cleared
634 */
635ENTRY(uaccess_user_clear_user)
636 stmfd sp!, {r1, lr}
637 mov r2, #0
638 cmp r1, #4
639 blt 2f
640 ands ip, r0, #3
641 beq 1f
642 cmp ip, #2
643USER( strbt r2, [r0], #1)
644USER( strlebt r2, [r0], #1)
645USER( strltbt r2, [r0], #1)
646 rsb ip, ip, #4
647 sub r1, r1, ip @ 7 6 5 4 3 2 1
6481: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
649USER( strplt r2, [r0], #4)
650USER( strplt r2, [r0], #4)
651 bpl 1b
652 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
653USER( strplt r2, [r0], #4)
6542: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
655USER( strnebt r2, [r0], #1)
656USER( strnebt r2, [r0], #1)
657 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
658USER( strnebt r2, [r0], #1)
659 mov r0, #0
660 LOADREGS(fd,sp!, {r1, pc})
661
662 .section .fixup,"ax"
663 .align 0
6649001: LOADREGS(fd,sp!, {r0, pc})
665 .previous
666
667/*
668 * Copy a string from user space to kernel space.
669 * r0 = dst, r1 = src, r2 = byte length
670 * returns the number of characters copied (strlen of copied string),
671 * -EFAULT on exception, or "len" if we fill the whole buffer
672 */
673ENTRY(uaccess_user_strncpy_from_user)
674 save_lr
675 mov ip, r1
6761: subs r2, r2, #1
677USER( ldrplbt r3, [r1], #1)
678 bmi 2f
679 strb r3, [r0], #1
680 teq r3, #0
681 bne 1b
682 sub r1, r1, #1 @ take NUL character out of count
6832: sub r0, r1, ip
684 restore_pc
685
686 .section .fixup,"ax"
687 .align 0
6889001: mov r3, #0
689 strb r3, [r0, #0] @ null terminate
690 mov r0, #-EFAULT
691 restore_pc
692 .previous
693
694/* Prototype: unsigned long uaccess_user_strnlen_user(const char *str, long n)
695 * Purpose : get length of a string in user memory
696 * Params : str - address of string in user memory
697 * Returns : length of string *including terminator*
698 * or zero on exception, or n + 1 if too long
699 */
700ENTRY(uaccess_user_strnlen_user)
701 save_lr
702 mov r2, r0
7031:
704USER( ldrbt r3, [r0], #1)
705 teq r3, #0
706 beq 2f
707 subs r1, r1, #1
708 bne 1b
709 add r0, r0, #1
7102: sub r0, r0, r2
711 restore_pc
712
713 .section .fixup,"ax"
714 .align 0
7159001: mov r0, #0
716 restore_pc
717 .previous
718
diff --git a/arch/arm26/lib/ucmpdi2.c b/arch/arm26/lib/ucmpdi2.c
deleted file mode 100644
index 6c6ae63efa02..000000000000
--- a/arch/arm26/lib/ucmpdi2.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33
34word_type
35__ucmpdi2 (DItype a, DItype b)
36{
37 DIunion au, bu;
38
39 au.ll = a, bu.ll = b;
40
41 if ((USItype) au.s.high < (USItype) bu.s.high)
42 return 0;
43 else if ((USItype) au.s.high > (USItype) bu.s.high)
44 return 2;
45 if ((USItype) au.s.low < (USItype) bu.s.low)
46 return 0;
47 else if ((USItype) au.s.low > (USItype) bu.s.low)
48 return 2;
49 return 1;
50}
51
diff --git a/arch/arm26/lib/udivdi3.c b/arch/arm26/lib/udivdi3.c
deleted file mode 100644
index d25195f673f4..000000000000
--- a/arch/arm26/lib/udivdi3.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33#include "longlong.h"
34
35static const UQItype __clz_tab[] =
36{
37 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
38 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
40 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
41 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
42 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
43 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
45};
46
47UDItype
48__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
49{
50 DIunion ww;
51 DIunion nn, dd;
52 DIunion rr;
53 USItype d0, d1, n0, n1, n2;
54 USItype q0, q1;
55 USItype b, bm;
56
57 nn.ll = n;
58 dd.ll = d;
59
60 d0 = dd.s.low;
61 d1 = dd.s.high;
62 n0 = nn.s.low;
63 n1 = nn.s.high;
64
65 if (d1 == 0)
66 {
67 if (d0 > n1)
68 {
69 /* 0q = nn / 0D */
70
71 count_leading_zeros (bm, d0);
72
73 if (bm != 0)
74 {
75 /* Normalize, i.e. make the most significant bit of the
76 denominator set. */
77
78 d0 = d0 << bm;
79 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
80 n0 = n0 << bm;
81 }
82
83 udiv_qrnnd (q0, n0, n1, n0, d0);
84 q1 = 0;
85
86 /* Remainder in n0 >> bm. */
87 }
88 else
89 {
90 /* qq = NN / 0d */
91
92 if (d0 == 0)
93 d0 = 1 / d0; /* Divide intentionally by zero. */
94
95 count_leading_zeros (bm, d0);
96
97 if (bm == 0)
98 {
99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
100 conclude (the most significant bit of n1 is set) /\ (the
101 leading quotient digit q1 = 1).
102
103 This special case is necessary, not an optimization.
104 (Shifts counts of SI_TYPE_SIZE are undefined.) */
105
106 n1 -= d0;
107 q1 = 1;
108 }
109 else
110 {
111 /* Normalize. */
112
113 b = SI_TYPE_SIZE - bm;
114
115 d0 = d0 << bm;
116 n2 = n1 >> b;
117 n1 = (n1 << bm) | (n0 >> b);
118 n0 = n0 << bm;
119
120 udiv_qrnnd (q1, n1, n2, n1, d0);
121 }
122
123 /* n1 != d0... */
124
125 udiv_qrnnd (q0, n0, n1, n0, d0);
126
127 /* Remainder in n0 >> bm. */
128 }
129
130 if (rp != 0)
131 {
132 rr.s.low = n0 >> bm;
133 rr.s.high = 0;
134 *rp = rr.ll;
135 }
136 }
137 else
138 {
139 if (d1 > n1)
140 {
141 /* 00 = nn / DD */
142
143 q0 = 0;
144 q1 = 0;
145
146 /* Remainder in n1n0. */
147 if (rp != 0)
148 {
149 rr.s.low = n0;
150 rr.s.high = n1;
151 *rp = rr.ll;
152 }
153 }
154 else
155 {
156 /* 0q = NN / dd */
157
158 count_leading_zeros (bm, d1);
159 if (bm == 0)
160 {
161 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
162 conclude (the most significant bit of n1 is set) /\ (the
163 quotient digit q0 = 0 or 1).
164
165 This special case is necessary, not an optimization. */
166
167 /* The condition on the next line takes advantage of that
168 n1 >= d1 (true due to program flow). */
169 if (n1 > d1 || n0 >= d0)
170 {
171 q0 = 1;
172 sub_ddmmss (n1, n0, n1, n0, d1, d0);
173 }
174 else
175 q0 = 0;
176
177 q1 = 0;
178
179 if (rp != 0)
180 {
181 rr.s.low = n0;
182 rr.s.high = n1;
183 *rp = rr.ll;
184 }
185 }
186 else
187 {
188 USItype m1, m0;
189 /* Normalize. */
190
191 b = SI_TYPE_SIZE - bm;
192
193 d1 = (d1 << bm) | (d0 >> b);
194 d0 = d0 << bm;
195 n2 = n1 >> b;
196 n1 = (n1 << bm) | (n0 >> b);
197 n0 = n0 << bm;
198
199 udiv_qrnnd (q0, n1, n2, n1, d1);
200 umul_ppmm (m1, m0, q0, d0);
201
202 if (m1 > n1 || (m1 == n1 && m0 > n0))
203 {
204 q0--;
205 sub_ddmmss (m1, m0, m1, m0, d1, d0);
206 }
207
208 q1 = 0;
209
210 /* Remainder in (n1n0 - m1m0) >> bm. */
211 if (rp != 0)
212 {
213 sub_ddmmss (n1, n0, n1, n0, m1, m0);
214 rr.s.low = (n1 << b) | (n0 >> bm);
215 rr.s.high = n1 >> bm;
216 *rp = rr.ll;
217 }
218 }
219 }
220 }
221
222 ww.s.low = q0;
223 ww.s.high = q1;
224 return ww.ll;
225}
226
227UDItype
228__udivdi3 (UDItype n, UDItype d)
229{
230 return __udivmoddi4 (n, d, (UDItype *) 0);
231}
232
233UDItype
234__umoddi3 (UDItype u, UDItype v)
235{
236 UDItype w;
237
238 (void) __udivmoddi4 (u ,v, &w);
239
240 return w;
241}
242
diff --git a/arch/arm26/machine/Makefile b/arch/arm26/machine/Makefile
deleted file mode 100644
index 86ea97cc07fc..000000000000
--- a/arch/arm26/machine/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := dma.o irq.o latches.o
8
diff --git a/arch/arm26/machine/dma.c b/arch/arm26/machine/dma.c
deleted file mode 100644
index 4402a5a1b78f..000000000000
--- a/arch/arm26/machine/dma.c
+++ /dev/null
@@ -1,214 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/dma.c
3 *
4 * Copyright (C) 1998-1999 Dave Gilbert / Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * DMA functions specific to Archimedes and A5000 architecture
12 */
13#include <linux/sched.h>
14#include <linux/init.h>
15
16#include <asm/dma.h>
17#include <asm/fiq.h>
18#include <asm/irq.h>
19#include <asm/io.h>
20#include <asm/hardware.h>
21#include <asm/mach-types.h>
22
23#define DPRINTK(x...) printk(KERN_DEBUG x)
24
25#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
26
27extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
28extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
29extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
30
31static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma)
32{
33 DPRINTK("arc_floppy_data_enable_dma\n");
34
35 if (dma->using_sg)
36 BUG();
37
38 switch (dma->dma_mode) {
39 case DMA_MODE_READ: { /* read */
40 unsigned long flags;
41 DPRINTK("enable_dma fdc1772 data read\n");
42 local_save_flags_cli(flags);
43 clf();
44
45 memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
46 &fdc1772_dma_read_end - &fdc1772_dma_read);
47 fdc1772_setupdma(dma->buf.length, dma->buf.__address); /* Sets data pointer up */
48 enable_fiq(FIQ_FLOPPYDATA);
49 local_irq_restore(flags);
50 }
51 break;
52
53 case DMA_MODE_WRITE: { /* write */
54 unsigned long flags;
55 DPRINTK("enable_dma fdc1772 data write\n");
56 local_save_flags_cli(flags);
57 clf();
58 memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
59 &fdc1772_dma_write_end - &fdc1772_dma_write);
60 fdc1772_setupdma(dma->buf.length, dma->buf.__address); /* Sets data pointer up */
61 enable_fiq(FIQ_FLOPPYDATA);
62
63 local_irq_restore(flags);
64 }
65 break;
66 default:
67 printk ("enable_dma: dma%d not initialised\n", channel);
68 }
69}
70
71static int arc_floppy_data_get_dma_residue(dmach_t channel, dma_t *dma)
72{
73 extern unsigned int fdc1772_bytestogo;
74
75 /* 10/1/1999 DAG - I presume its the number of bytes left? */
76 return fdc1772_bytestogo;
77}
78
79static void arc_floppy_cmdend_enable_dma(dmach_t channel, dma_t *dma)
80{
81 /* Need to build a branch at the FIQ address */
82 extern void fdc1772_comendhandler(void);
83 unsigned long flags;
84
85 DPRINTK("arc_floppy_cmdend_enable_dma\n");
86 /*printk("enable_dma fdc1772 command end FIQ\n");*/
87 save_flags(flags);
88 clf();
89
90 /* B fdc1772_comendhandler */
91 *((unsigned int *)0x1c)=0xea000000 |
92 (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4);
93
94 local_irq_restore(flags);
95}
96
97static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma)
98{
99 /* 10/1/1999 DAG - Presume whether there is an outstanding command? */
100 extern unsigned int fdc1772_fdc_int_done;
101
102 /* Explicit! If the int done is 0 then 1 int to go */
103 return (fdc1772_fdc_int_done==0)?1:0;
104}
105
106static void arc_disable_dma(dmach_t channel, dma_t *dma)
107{
108 disable_fiq(dma->dma_irq);
109}
110
111static struct dma_ops arc_floppy_data_dma_ops = {
112 .type = "FIQDMA",
113 .enable = arc_floppy_data_enable_dma,
114 .disable = arc_disable_dma,
115 .residue = arc_floppy_data_get_dma_residue,
116};
117
118static struct dma_ops arc_floppy_cmdend_dma_ops = {
119 .type = "FIQCMD",
120 .enable = arc_floppy_cmdend_enable_dma,
121 .disable = arc_disable_dma,
122 .residue = arc_floppy_cmdend_get_dma_residue,
123};
124#endif
125
126#ifdef CONFIG_ARCH_A5K
127static struct fiq_handler fh = {
128 .name = "floppydata"
129};
130
131static int a5k_floppy_get_dma_residue(dmach_t channel, dma_t *dma)
132{
133 struct pt_regs regs;
134 get_fiq_regs(&regs);
135 return regs.ARM_r9;
136}
137
138static void a5k_floppy_enable_dma(dmach_t channel, dma_t *dma)
139{
140 struct pt_regs regs;
141 void *fiqhandler_start;
142 unsigned int fiqhandler_length;
143 extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
144 unsigned long port);
145
146 if (dma->using_sg)
147 BUG();
148
149 if (dma->dma_mode == DMA_MODE_READ) {
150 extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
151 fiqhandler_start = &floppy_fiqin_start;
152 fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
153 } else {
154 extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
155 fiqhandler_start = &floppy_fiqout_start;
156 fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
157 }
158 if (claim_fiq(&fh)) {
159 printk("floppydma: couldn't claim FIQ.\n");
160 return;
161 }
162 memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
163 regs.ARM_r9 = dma->buf.length;
164 regs.ARM_r10 = (unsigned long)dma->buf.__address;
165 regs.ARM_fp = FLOPPYDMA_BASE;
166 set_fiq_regs(&regs);
167 enable_fiq(dma->dma_irq);
168}
169
170static void a5k_floppy_disable_dma(dmach_t channel, dma_t *dma)
171{
172 disable_fiq(dma->dma_irq);
173 release_fiq(&fh);
174}
175
176static struct dma_ops a5k_floppy_dma_ops = {
177 .type = "FIQDMA",
178 .enable = a5k_floppy_enable_dma,
179 .disable = a5k_floppy_disable_dma,
180 .residue = a5k_floppy_get_dma_residue,
181};
182#endif
183
184/*
185 * This is virtual DMA - we don't need anything here
186 */
187static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
188{
189}
190
191static struct dma_ops sound_dma_ops = {
192 .type = "VIRTUAL",
193 .enable = sound_enable_disable_dma,
194 .disable = sound_enable_disable_dma,
195};
196
197void __init arch_dma_init(dma_t *dma)
198{
199#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
200 if (machine_is_archimedes()) {
201 dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
202 dma[DMA_VIRTUAL_FLOPPY0].d_ops = &arc_floppy_data_dma_ops;
203 dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 1;
204 dma[DMA_VIRTUAL_FLOPPY1].d_ops = &arc_floppy_cmdend_dma_ops;
205 }
206#endif
207#ifdef CONFIG_ARCH_A5K
208 if (machine_is_a5k()) {
209 dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
210 dma[DMA_VIRTUAL_FLOPPY0].d_ops = &a5k_floppy_dma_ops;
211 }
212#endif
213 dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
214}
diff --git a/arch/arm26/machine/irq.c b/arch/arm26/machine/irq.c
deleted file mode 100644
index a60d543edecc..000000000000
--- a/arch/arm26/machine/irq.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * linux/arch/arm26/mach-arc/irq.c
3 *
4 * Copyright (C) 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Changelog:
11 * 24-09-1996 RMK Created
12 * 10-10-1996 RMK Brought up to date with arch-sa110eval
13 * 22-10-1996 RMK Changed interrupt numbers & uses new inb/outb macros
14 * 11-01-1998 RMK Added mask_and_ack_irq
15 * 22-08-1998 RMK Restructured IRQ routines
16 * 08-09-2002 IM Brought up to date for 2.5
17 * 01-06-2003 JMA Removed arc_fiq_chip
18 */
19#include <linux/init.h>
20
21#include <asm/irq.h>
22#include <asm/irqchip.h>
23#include <asm/ioc.h>
24#include <asm/io.h>
25#include <asm/system.h>
26
27extern void init_FIQ(void);
28
29#define a_clf() clf()
30#define a_stf() stf()
31
32static void arc_ack_irq_a(unsigned int irq)
33{
34 unsigned int val, mask;
35
36 mask = 1 << irq;
37 a_clf();
38 val = ioc_readb(IOC_IRQMASKA);
39 ioc_writeb(val & ~mask, IOC_IRQMASKA);
40 ioc_writeb(mask, IOC_IRQCLRA);
41 a_stf();
42}
43
44static void arc_mask_irq_a(unsigned int irq)
45{
46 unsigned int val, mask;
47
48 mask = 1 << irq;
49 a_clf();
50 val = ioc_readb(IOC_IRQMASKA);
51 ioc_writeb(val & ~mask, IOC_IRQMASKA);
52 a_stf();
53}
54
55static void arc_unmask_irq_a(unsigned int irq)
56{
57 unsigned int val, mask;
58
59 mask = 1 << irq;
60 a_clf();
61 val = ioc_readb(IOC_IRQMASKA);
62 ioc_writeb(val | mask, IOC_IRQMASKA);
63 a_stf();
64}
65
66static struct irqchip arc_a_chip = {
67 .ack = arc_ack_irq_a,
68 .mask = arc_mask_irq_a,
69 .unmask = arc_unmask_irq_a,
70};
71
72static void arc_mask_irq_b(unsigned int irq)
73{
74 unsigned int val, mask;
75 mask = 1 << (irq & 7);
76 val = ioc_readb(IOC_IRQMASKB);
77 ioc_writeb(val & ~mask, IOC_IRQMASKB);
78}
79
80static void arc_unmask_irq_b(unsigned int irq)
81{
82 unsigned int val, mask;
83
84 mask = 1 << (irq & 7);
85 val = ioc_readb(IOC_IRQMASKB);
86 ioc_writeb(val | mask, IOC_IRQMASKB);
87}
88
89static struct irqchip arc_b_chip = {
90 .ack = arc_mask_irq_b,
91 .mask = arc_mask_irq_b,
92 .unmask = arc_unmask_irq_b,
93};
94
95/* FIXME - JMA none of these functions are used in arm26 currently
96static void arc_mask_irq_fiq(unsigned int irq)
97{
98 unsigned int val, mask;
99
100 mask = 1 << (irq & 7);
101 val = ioc_readb(IOC_FIQMASK);
102 ioc_writeb(val & ~mask, IOC_FIQMASK);
103}
104
105static void arc_unmask_irq_fiq(unsigned int irq)
106{
107 unsigned int val, mask;
108
109 mask = 1 << (irq & 7);
110 val = ioc_readb(IOC_FIQMASK);
111 ioc_writeb(val | mask, IOC_FIQMASK);
112}
113
114static struct irqchip arc_fiq_chip = {
115 .ack = arc_mask_irq_fiq,
116 .mask = arc_mask_irq_fiq,
117 .unmask = arc_unmask_irq_fiq,
118};
119*/
120
121void __init arc_init_irq(void)
122{
123 unsigned int irq, flags;
124
125 /* Disable all IOC interrupt sources */
126 ioc_writeb(0, IOC_IRQMASKA);
127 ioc_writeb(0, IOC_IRQMASKB);
128 ioc_writeb(0, IOC_FIQMASK);
129
130 for (irq = 0; irq < NR_IRQS; irq++) {
131 flags = IRQF_VALID;
132
133 if (irq <= 6 || (irq >= 9 && irq <= 15))
134 flags |= IRQF_PROBE;
135
136 if (irq == IRQ_KEYBOARDTX)
137 flags |= IRQF_NOAUTOEN;
138
139 switch (irq) {
140 case 0 ... 7:
141 set_irq_chip(irq, &arc_a_chip);
142 set_irq_handler(irq, do_level_IRQ);
143 set_irq_flags(irq, flags);
144 break;
145
146 case 8 ... 15:
147 set_irq_chip(irq, &arc_b_chip);
148 set_irq_handler(irq, do_level_IRQ);
149 set_irq_flags(irq, flags);
150
151/* case 64 ... 72:
152 set_irq_chip(irq, &arc_fiq_chip);
153 set_irq_flags(irq, flags);
154 break;
155*/
156
157 }
158 }
159
160 irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
161
162 init_FIQ();
163}
164
diff --git a/arch/arm26/machine/latches.c b/arch/arm26/machine/latches.c
deleted file mode 100644
index 94f05d2a3b2b..000000000000
--- a/arch/arm26/machine/latches.c
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * linux/arch/arm26/kernel/latches.c
3 *
4 * Copyright (C) David Alan Gilbert 1995/1996,2000
5 * Copyright (C) Ian Molton 2003
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Support for the latches on the old Archimedes which control the floppy,
12 * hard disc and printer
13 */
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sched.h>
18
19#include <asm/io.h>
20#include <asm/hardware.h>
21#include <asm/mach-types.h>
22#include <asm/oldlatches.h>
23
24static unsigned char latch_a_copy;
25static unsigned char latch_b_copy;
26
27/* newval=(oldval & ~mask)|newdata */
28void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
29{
30 unsigned long flags;
31
32 BUG_ON(!machine_is_archimedes());
33
34 local_irq_save(flags); //FIXME: was local_save_flags
35 latch_a_copy = (latch_a_copy & ~mask) | newdata;
36 __raw_writeb(latch_a_copy, LATCHA_BASE);
37 local_irq_restore(flags);
38
39 printk("Latch: A = 0x%02x\n", latch_a_copy);
40}
41
42
43/* newval=(oldval & ~mask)|newdata */
44void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
45{
46 unsigned long flags;
47
48 BUG_ON(!machine_is_archimedes());
49
50
51 local_irq_save(flags);//FIXME: was local_save_flags
52 latch_b_copy = (latch_b_copy & ~mask) | newdata;
53 __raw_writeb(latch_b_copy, LATCHB_BASE);
54 local_irq_restore(flags);
55
56 printk("Latch: B = 0x%02x\n", latch_b_copy);
57}
58
59static int __init oldlatch_init(void)
60{
61 if (machine_is_archimedes()) {
62 oldlatch_aupdate(0xff, 0xff);
63 /* Thats no FDC reset...*/
64 oldlatch_bupdate(0xff, LATCHB_FDCRESET);
65 }
66 return 0;
67}
68
69arch_initcall(oldlatch_init);
70
71EXPORT_SYMBOL(oldlatch_aupdate);
72EXPORT_SYMBOL(oldlatch_bupdate);
diff --git a/arch/arm26/mm/Makefile b/arch/arm26/mm/Makefile
deleted file mode 100644
index a8fb166d5c6d..000000000000
--- a/arch/arm26/mm/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Makefile for the linux arm26-specific parts of the memory manager.
3#
4
5obj-y := init.o extable.o proc-funcs.o memc.o fault.o \
6 small_page.o
diff --git a/arch/arm26/mm/extable.c b/arch/arm26/mm/extable.c
deleted file mode 100644
index 38e1958d9538..000000000000
--- a/arch/arm26/mm/extable.c
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * linux/arch/arm26/mm/extable.c
3 */
4
5#include <linux/module.h>
6#include <asm/uaccess.h>
7
8int fixup_exception(struct pt_regs *regs)
9{
10 const struct exception_table_entry *fixup;
11
12 fixup = search_exception_tables(instruction_pointer(regs));
13
14 /*
15 * The kernel runs in SVC mode - make sure we keep running in SVC mode
16 * by frobbing the PSR appropriately (PSR and PC are in the same reg.
17 * on ARM26)
18 */
19 if (fixup)
20 regs->ARM_pc = fixup->fixup | PSR_I_BIT | MODE_SVC26;
21
22 return fixup != NULL;
23}
24
diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c
deleted file mode 100644
index dec638a0c8d9..000000000000
--- a/arch/arm26/mm/fault.c
+++ /dev/null
@@ -1,312 +0,0 @@
1/*
2 * linux/arch/arm26/mm/fault.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Modifications for ARM processor (c) 1995-2001 Russell King
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/interrupt.h>
21#include <linux/proc_fs.h>
22#include <linux/init.h>
23
24#include <asm/system.h>
25#include <asm/pgtable.h>
26#include <asm/uaccess.h> //FIXME this header may be bogusly included
27
28#include "fault.h"
29
30#define FAULT_CODE_LDRSTRPOST 0x80
31#define FAULT_CODE_LDRSTRPRE 0x40
32#define FAULT_CODE_LDRSTRREG 0x20
33#define FAULT_CODE_LDMSTM 0x10
34#define FAULT_CODE_LDCSTC 0x08
35#define FAULT_CODE_PREFETCH 0x04
36#define FAULT_CODE_WRITE 0x02
37#define FAULT_CODE_FORCECOW 0x01
38
39#define DO_COW(m) ((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
40#define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE))
41#define DEBUG
42/*
43 * This is useful to dump out the page tables associated with
44 * 'addr' in mm 'mm'.
45 */
46void show_pte(struct mm_struct *mm, unsigned long addr)
47{
48 pgd_t *pgd;
49
50 if (!mm)
51 mm = &init_mm;
52
53 printk(KERN_ALERT "pgd = %p\n", mm->pgd);
54 pgd = pgd_offset(mm, addr);
55 printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
56
57 do {
58 pmd_t *pmd;
59 pte_t *pte;
60
61 pmd = pmd_offset(pgd, addr);
62
63 if (pmd_none(*pmd))
64 break;
65
66 if (pmd_bad(*pmd)) {
67 printk("(bad)");
68 break;
69 }
70
71 /* We must not map this if we have highmem enabled */
72 /* FIXME */
73 pte = pte_offset_map(pmd, addr);
74 printk(", *pte=%08lx", pte_val(*pte));
75 pte_unmap(pte);
76 } while(0);
77
78 printk("\n");
79}
80
81/*
82 * Oops. The kernel tried to access some page that wasn't present.
83 */
84static void
85__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
86 struct pt_regs *regs)
87{
88 /*
89 * Are we prepared to handle this kernel fault?
90 */
91 if (fixup_exception(regs))
92 return;
93
94 /*
95 * No handler, we'll have to terminate things with extreme prejudice.
96 */
97 bust_spinlocks(1);
98 printk(KERN_ALERT
99 "Unable to handle kernel %s at virtual address %08lx\n",
100 (addr < PAGE_SIZE) ? "NULL pointer dereference" :
101 "paging request", addr);
102
103 show_pte(mm, addr);
104 die("Oops", regs, fsr);
105 bust_spinlocks(0);
106 do_exit(SIGKILL);
107}
108
109/*
110 * Something tried to access memory that isn't in our memory map..
111 * User mode accesses just cause a SIGSEGV
112 */
113static void
114__do_user_fault(struct task_struct *tsk, unsigned long addr,
115 unsigned int fsr, int code, struct pt_regs *regs)
116{
117 struct siginfo si;
118
119#ifdef CONFIG_DEBUG_USER
120 printk("%s: unhandled page fault at 0x%08lx, code 0x%03x\n",
121 tsk->comm, addr, fsr);
122 show_pte(tsk->mm, addr);
123 show_regs(regs);
124 //dump_backtrace(regs, tsk); // FIXME ARM32 dropped this - why?
125 while(1); //FIXME - hack to stop debug going nutso
126#endif
127
128 tsk->thread.address = addr;
129 tsk->thread.error_code = fsr;
130 tsk->thread.trap_no = 14;
131 si.si_signo = SIGSEGV;
132 si.si_errno = 0;
133 si.si_code = code;
134 si.si_addr = (void *)addr;
135 force_sig_info(SIGSEGV, &si, tsk);
136}
137
138static int
139__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
140 struct task_struct *tsk)
141{
142 struct vm_area_struct *vma;
143 int fault, mask;
144
145 vma = find_vma(mm, addr);
146 fault = -2; /* bad map area */
147 if (!vma)
148 goto out;
149 if (vma->vm_start > addr)
150 goto check_stack;
151
152 /*
153 * Ok, we have a good vm_area for this
154 * memory access, so we can handle it.
155 */
156good_area:
157 if (READ_FAULT(fsr)) /* read? */
158 mask = VM_READ|VM_EXEC|VM_WRITE;
159 else
160 mask = VM_WRITE;
161
162 fault = -1; /* bad access type */
163 if (!(vma->vm_flags & mask))
164 goto out;
165
166 /*
167 * If for any reason at all we couldn't handle
168 * the fault, make sure we exit gracefully rather
169 * than endlessly redo the fault.
170 */
171survive:
172 fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
173 if (unlikely(fault & VM_FAULT_ERROR)) {
174 if (fault & VM_FAULT_OOM)
175 goto out_of_memory;
176 else if (fault & VM_FAULT_SIGBUS)
177 return fault;
178 BUG();
179 }
180 if (fault & VM_FAULT_MAJOR)
181 tsk->maj_flt++;
182 else
183 tsk->min_flt++;
184 return fault;
185
186out_of_memory:
187 fault = -3; /* out of memory */
188 if (!is_init(tsk))
189 goto out;
190
191 /*
192 * If we are out of memory for pid1,
193 * sleep for a while and retry
194 */
195 yield();
196 goto survive;
197
198check_stack:
199 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
200 goto good_area;
201out:
202 return fault;
203}
204
205int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
206{
207 struct task_struct *tsk;
208 struct mm_struct *mm;
209 int fault;
210
211 tsk = current;
212 mm = tsk->mm;
213
214 /*
215 * If we're in an interrupt or have no user
216 * context, we must not take the fault..
217 */
218 if (in_atomic() || !mm)
219 goto no_context;
220
221 down_read(&mm->mmap_sem);
222 fault = __do_page_fault(mm, addr, fsr, tsk);
223 up_read(&mm->mmap_sem);
224
225 /*
226 * Handle the "normal" case first
227 */
228 if (likely(!(fault & VM_FAULT_ERROR)))
229 return 0;
230 if (fault & VM_FAULT_SIGBUS)
231 goto do_sigbus;
232 /* else VM_FAULT_OOM */
233
234 /*
235 * If we are in kernel mode at this point, we
236 * have no context to handle this fault with.
237 * FIXME - is this test right?
238 */
239 if (!user_mode(regs)){
240 goto no_context;
241 }
242
243 if (fault == -3) {
244 /*
245 * We ran out of memory, or some other thing happened to
246 * us that made us unable to handle the page fault gracefully.
247 */
248 printk("VM: killing process %s\n", tsk->comm);
249 do_exit(SIGKILL);
250 }
251 else{
252 __do_user_fault(tsk, addr, fsr, fault == -1 ? SEGV_ACCERR : SEGV_MAPERR, regs);
253 }
254
255 return 0;
256
257
258/*
259 * We ran out of memory, or some other thing happened to us that made
260 * us unable to handle the page fault gracefully.
261 */
262do_sigbus:
263 /*
264 * Send a sigbus, regardless of whether we were in kernel
265 * or user mode.
266 */
267 tsk->thread.address = addr; //FIXME - need other bits setting?
268 tsk->thread.error_code = fsr;
269 tsk->thread.trap_no = 14;
270 force_sig(SIGBUS, tsk);
271#ifdef CONFIG_DEBUG_USER
272 printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
273 current->comm, addr, instruction_pointer(regs));
274#endif
275
276 /* Kernel mode? Handle exceptions or die */
277 if (user_mode(regs))
278 return 0;
279
280no_context:
281 __do_kernel_fault(mm, addr, fsr, regs);
282 return 0;
283}
284
285/*
286 * Handle a data abort. Note that we have to handle a range of addresses
287 * on ARM2/3 for ldm. If both pages are zero-mapped, then we have to force
288 * a copy-on-write. However, on the second page, we always force COW.
289 */
290asmlinkage void
291do_DataAbort(unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
292{
293 do_page_fault(min_addr, mode, regs);
294
295 if ((min_addr ^ max_addr) >> PAGE_SHIFT){
296 do_page_fault(max_addr, mode | FAULT_CODE_FORCECOW, regs);
297 }
298}
299
300asmlinkage int
301do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
302{
303#if 0
304 if (the memc mapping for this page exists) {
305 printk ("Page in, but got abort (undefined instruction?)\n");
306 return 0;
307 }
308#endif
309 do_page_fault(addr, FAULT_CODE_PREFETCH, regs);
310 return 1;
311}
312
diff --git a/arch/arm26/mm/fault.h b/arch/arm26/mm/fault.h
deleted file mode 100644
index 4442d00d86ac..000000000000
--- a/arch/arm26/mm/fault.h
+++ /dev/null
@@ -1,5 +0,0 @@
1void show_pte(struct mm_struct *mm, unsigned long addr);
2
3int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
4
5unsigned long search_extable(unsigned long addr); //FIXME - is it right?
diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c
deleted file mode 100644
index 36e7ee3f8321..000000000000
--- a/arch/arm26/mm/init.c
+++ /dev/null
@@ -1,403 +0,0 @@
1/*
2 * linux/arch/arm26/mm/init.c
3 *
4 * Copyright (C) 1995-2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/signal.h>
11#include <linux/sched.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/types.h>
16#include <linux/ptrace.h>
17#include <linux/mman.h>
18#include <linux/mm.h>
19#include <linux/swap.h>
20#include <linux/smp.h>
21#include <linux/init.h>
22#include <linux/initrd.h>
23#include <linux/bootmem.h>
24#include <linux/blkdev.h>
25#include <linux/pfn.h>
26
27#include <asm/segment.h>
28#include <asm/mach-types.h>
29#include <asm/dma.h>
30#include <asm/hardware.h>
31#include <asm/setup.h>
32#include <asm/tlb.h>
33
34#include <asm/map.h>
35
36struct mmu_gather mmu_gathers[NR_CPUS];
37
38extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
39extern char _stext, _text, _etext, _end, __init_begin, __init_end;
40#ifdef CONFIG_XIP_KERNEL
41extern char _endtext, _sdata;
42#endif
43extern unsigned long phys_initrd_start;
44extern unsigned long phys_initrd_size;
45
46/*
47 * The sole use of this is to pass memory configuration
48 * data from paging_init to mem_init.
49 */
50static struct meminfo meminfo __initdata = { 0, };
51
52/*
53 * empty_zero_page is a special page that is used for
54 * zero-initialized data and COW.
55 */
56struct page *empty_zero_page;
57
58void show_mem(void)
59{
60 int free = 0, total = 0, reserved = 0;
61 int shared = 0, cached = 0, slab = 0;
62 struct page *page, *end;
63
64 printk("Mem-info:\n");
65 show_free_areas();
66 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
67
68
69 page = NODE_MEM_MAP(0);
70 end = page + NODE_DATA(0)->node_spanned_pages;
71
72 do {
73 total++;
74 if (PageReserved(page))
75 reserved++;
76 else if (PageSwapCache(page))
77 cached++;
78 else if (PageSlab(page))
79 slab++;
80 else if (!page_count(page))
81 free++;
82 else
83 shared += page_count(page) - 1;
84 page++;
85 } while (page < end);
86
87 printk("%d pages of RAM\n", total);
88 printk("%d free pages\n", free);
89 printk("%d reserved pages\n", reserved);
90 printk("%d slab pages\n", slab);
91 printk("%d pages shared\n", shared);
92 printk("%d pages swap cached\n", cached);
93}
94
95struct node_info {
96 unsigned int start;
97 unsigned int end;
98 int bootmap_pages;
99};
100
101/*
102 * FIXME: We really want to avoid allocating the bootmap bitmap
103 * over the top of the initrd. Hopefully, this is located towards
104 * the start of a bank, so if we allocate the bootmap bitmap at
105 * the end, we won't clash.
106 */
107static unsigned int __init
108find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages)
109{
110 unsigned int start_pfn, bootmap_pfn;
111 unsigned int start, end;
112
113 start_pfn = PFN_UP((unsigned long)&_end);
114 bootmap_pfn = 0;
115
116 /* ARM26 machines only have one node */
117 if (mi->bank->node != 0)
118 BUG();
119
120 start = PFN_UP(mi->bank->start);
121 end = PFN_DOWN(mi->bank->size + mi->bank->start);
122
123 if (start < start_pfn)
124 start = start_pfn;
125
126 if (end <= start)
127 BUG();
128
129 if (end - start >= bootmap_pages)
130 bootmap_pfn = start;
131 else
132 BUG();
133
134 return bootmap_pfn;
135}
136
137/*
138 * Scan the memory info structure and pull out:
139 * - the end of memory
140 * - the number of nodes
141 * - the pfn range of each node
142 * - the number of bootmem bitmap pages
143 */
144static void __init
145find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
146{
147 unsigned int memend_pfn = 0;
148
149 nodes_clear(node_online_map);
150 node_set_online(0);
151
152 np->bootmap_pages = 0;
153
154 if (mi->bank->size == 0) {
155 BUG();
156 }
157
158 /*
159 * Get the start and end pfns for this bank
160 */
161 np->start = PFN_UP(mi->bank->start);
162 np->end = PFN_DOWN(mi->bank->start + mi->bank->size);
163
164 if (memend_pfn < np->end)
165 memend_pfn = np->end;
166
167 /*
168 * Calculate the number of pages we require to
169 * store the bootmem bitmaps.
170 */
171 np->bootmap_pages = bootmem_bootmap_pages(np->end - np->start);
172
173 /*
174 * This doesn't seem to be used by the Linux memory
175 * manager any more. If we can get rid of it, we
176 * also get rid of some of the stuff above as well.
177 */
178 max_low_pfn = memend_pfn - PFN_DOWN(PHYS_OFFSET);
179 max_pfn = memend_pfn - PFN_DOWN(PHYS_OFFSET);
180 mi->end = memend_pfn << PAGE_SHIFT;
181
182}
183
184/*
185 * Initialise the bootmem allocator for all nodes. This is called
186 * early during the architecture specific initialisation.
187 */
188void __init bootmem_init(struct meminfo *mi)
189{
190 struct node_info node_info;
191 unsigned int bootmap_pfn;
192 pg_data_t *pgdat = NODE_DATA(0);
193
194 find_memend_and_nodes(mi, &node_info);
195
196 bootmap_pfn = find_bootmap_pfn(mi, node_info.bootmap_pages);
197
198 /*
199 * Note that node 0 must always have some pages.
200 */
201 if (node_info.end == 0)
202 BUG();
203
204 /*
205 * Initialise the bootmem allocator.
206 */
207 init_bootmem_node(pgdat, bootmap_pfn, node_info.start, node_info.end);
208
209 /*
210 * Register all available RAM in this node with the bootmem allocator.
211 */
212 free_bootmem_node(pgdat, mi->bank->start, mi->bank->size);
213
214 /*
215 * Register the kernel text and data with bootmem.
216 * Note: with XIP we dont register .text since
217 * its in ROM.
218 */
219#ifdef CONFIG_XIP_KERNEL
220 reserve_bootmem_node(pgdat, __pa(&_sdata), &_end - &_sdata);
221#else
222 reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
223#endif
224
225 /*
226 * And don't forget to reserve the allocator bitmap,
227 * which will be freed later.
228 */
229 reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
230 node_info.bootmap_pages << PAGE_SHIFT);
231
232 /*
233 * These should likewise go elsewhere. They pre-reserve
234 * the screen memory region at the start of main system
235 * memory. FIXME - screen RAM is not 512K!
236 */
237 reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
238
239#ifdef CONFIG_BLK_DEV_INITRD
240 initrd_start = phys_initrd_start;
241 initrd_end = initrd_start + phys_initrd_size;
242
243 /* Achimedes machines only have one node, so initrd is in node 0 */
244#ifdef CONFIG_XIP_KERNEL
245 /* Only reserve initrd space if it is in RAM */
246 if(initrd_start && initrd_start < 0x03000000){
247#else
248 if(initrd_start){
249#endif
250 reserve_bootmem_node(pgdat, __pa(initrd_start),
251 initrd_end - initrd_start);
252 }
253#endif /* CONFIG_BLK_DEV_INITRD */
254
255
256}
257
258/*
259 * paging_init() sets up the page tables, initialises the zone memory
260 * maps, and sets up the zero page, bad page and bad page tables.
261 */
262void __init paging_init(struct meminfo *mi)
263{
264 void *zero_page;
265 unsigned long zone_size[MAX_NR_ZONES];
266 unsigned long zhole_size[MAX_NR_ZONES];
267 struct bootmem_data *bdata;
268 pg_data_t *pgdat;
269 int i;
270
271 memcpy(&meminfo, mi, sizeof(meminfo));
272
273 /*
274 * allocate the zero page. Note that we count on this going ok.
275 */
276 zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
277
278 /*
279 * initialise the page tables.
280 */
281 memtable_init(mi);
282 flush_tlb_all();
283
284 /*
285 * initialise the zones in node 0 (archimedes have only 1 node)
286 */
287
288 for (i = 0; i < MAX_NR_ZONES; i++) {
289 zone_size[i] = 0;
290 zhole_size[i] = 0;
291 }
292
293 pgdat = NODE_DATA(0);
294 bdata = pgdat->bdata;
295 zone_size[0] = bdata->node_low_pfn -
296 (bdata->node_boot_start >> PAGE_SHIFT);
297 if (!zone_size[0])
298 BUG();
299 pgdat->node_mem_map = NULL;
300 free_area_init_node(0, pgdat, zone_size,
301 bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
302
303 /*
304 * finish off the bad pages once
305 * the mem_map is initialised
306 */
307 memzero(zero_page, PAGE_SIZE);
308 empty_zero_page = virt_to_page(zero_page);
309}
310
311static inline void free_area(unsigned long addr, unsigned long end, char *s)
312{
313 unsigned int size = (end - addr) >> 10;
314
315 for (; addr < end; addr += PAGE_SIZE) {
316 struct page *page = virt_to_page(addr);
317 ClearPageReserved(page);
318 init_page_count(page);
319 free_page(addr);
320 totalram_pages++;
321 }
322
323 if (size && s)
324 printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
325}
326
327/*
328 * mem_init() marks the free areas in the mem_map and tells us how much
329 * memory is free. This is done after various parts of the system have
330 * claimed their memory after the kernel image.
331 */
332void __init mem_init(void)
333{
334 unsigned int codepages, datapages, initpages;
335 pg_data_t *pgdat = NODE_DATA(0);
336 extern int sysctl_overcommit_memory;
337
338
339 /* Note: data pages includes BSS */
340#ifdef CONFIG_XIP_KERNEL
341 codepages = &_endtext - &_text;
342 datapages = &_end - &_sdata;
343#else
344 codepages = &_etext - &_text;
345 datapages = &_end - &_etext;
346#endif
347 initpages = &__init_end - &__init_begin;
348
349 high_memory = (void *)__va(meminfo.end);
350 max_mapnr = virt_to_page(high_memory) - mem_map;
351
352 /* this will put all unused low memory onto the freelists */
353 if (pgdat->node_spanned_pages != 0)
354 totalram_pages += free_all_bootmem_node(pgdat);
355
356 num_physpages = meminfo.bank[0].size >> PAGE_SHIFT;
357
358 printk(KERN_INFO "Memory: %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
359 printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
360 "%dK data, %dK init)\n",
361 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
362 codepages >> 10, datapages >> 10, initpages >> 10);
363
364 /*
365 * Turn on overcommit on tiny machines
366 */
367 if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
368 sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
369 printk("Turning on overcommit\n");
370 }
371}
372
373void free_initmem(void){
374#ifndef CONFIG_XIP_KERNEL
375 free_area((unsigned long)(&__init_begin),
376 (unsigned long)(&__init_end),
377 "init");
378#endif
379}
380
381#ifdef CONFIG_BLK_DEV_INITRD
382
383static int keep_initrd;
384
385void free_initrd_mem(unsigned long start, unsigned long end)
386{
387#ifdef CONFIG_XIP_KERNEL
388 /* Only bin initrd if it is in RAM... */
389 if(!keep_initrd && start < 0x03000000)
390#else
391 if (!keep_initrd)
392#endif
393 free_area(start, end, "initrd");
394}
395
396static int __init keepinitrd_setup(char *__unused)
397{
398 keep_initrd = 1;
399 return 1;
400}
401
402__setup("keepinitrd", keepinitrd_setup);
403#endif
diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
deleted file mode 100644
index ffecd8578247..000000000000
--- a/arch/arm26/mm/memc.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/*
2 * linux/arch/arm26/mm/memc.c
3 *
4 * Copyright (C) 1998-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Page table sludge for older ARM processor architectures.
11 */
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/init.h>
15#include <linux/bootmem.h>
16
17#include <asm/pgtable.h>
18#include <asm/pgalloc.h>
19#include <asm/page.h>
20#include <asm/memory.h>
21#include <asm/hardware.h>
22
23#include <asm/map.h>
24
25#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
26
27struct kmem_cache *pte_cache, *pgd_cache;
28int page_nr;
29
30/*
31 * Allocate space for a page table and a MEMC table.
32 * Note that we place the MEMC
33 * table before the page directory. This means we can
34 * easily get to both tightly-associated data structures
35 * with a single pointer.
36 */
37static inline pgd_t *alloc_pgd_table(void)
38{
39 void *pg2k = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
40
41 if (pg2k)
42 pg2k += MEMC_TABLE_SIZE;
43
44 return (pgd_t *)pg2k;
45}
46
47/*
48 * Free a page table. this function is the counterpart to get_pgd_slow
49 * below, not alloc_pgd_table above.
50 */
51void free_pgd_slow(pgd_t *pgd)
52{
53 unsigned long tbl = (unsigned long)pgd;
54
55 tbl -= MEMC_TABLE_SIZE;
56
57 kmem_cache_free(pgd_cache, (void *)tbl);
58}
59
60/*
61 * Allocate a new pgd and fill it in ready for use
62 *
63 * A new tasks pgd is completely empty (all pages !present) except for:
64 *
65 * o The machine vectors at virtual address 0x0
66 * o The vmalloc region at the top of address space
67 *
68 */
69#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
70
71pgd_t *get_pgd_slow(struct mm_struct *mm)
72{
73 pgd_t *new_pgd, *init_pgd;
74 pmd_t *new_pmd, *init_pmd;
75 pte_t *new_pte, *init_pte;
76
77 new_pgd = alloc_pgd_table();
78 if (!new_pgd)
79 goto no_pgd;
80
81 /*
82 * On ARM, first page must always be allocated since it contains
83 * the machine vectors.
84 */
85 new_pmd = pmd_alloc(mm, new_pgd, 0);
86 if (!new_pmd)
87 goto no_pmd;
88
89 new_pte = pte_alloc_map(mm, new_pmd, 0);
90 if (!new_pte)
91 goto no_pte;
92
93 init_pgd = pgd_offset(&init_mm, 0);
94 init_pmd = pmd_offset(init_pgd, 0);
95 init_pte = pte_offset(init_pmd, 0);
96
97 set_pte(new_pte, *init_pte);
98 pte_unmap(new_pte);
99
100 /*
101 * the page table entries are zeroed
102 * when the table is created. (see the cache_ctor functions below)
103 * Now we need to plonk the kernel (vmalloc) area at the end of
104 * the address space. We copy this from the init thread, just like
105 * the init_pte we copied above...
106 */
107 memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
108 (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
109
110 /* update MEMC tables */
111 cpu_memc_update_all(new_pgd);
112 return new_pgd;
113
114no_pte:
115 pmd_free(new_pmd);
116no_pmd:
117 free_pgd_slow(new_pgd);
118no_pgd:
119 return NULL;
120}
121
122/*
123 * No special code is required here.
124 */
125void setup_mm_for_reboot(char mode)
126{
127}
128
129/*
130 * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
131 * o swapper_pg_dir = 0x0207d000
132 * o kernel proper starts at 0x0208000
133 * o create (allocate) a pte to contain the machine vectors
134 * o populate the pte (points to 0x02078000) (FIXME - is it zeroed?)
135 * o populate the init tasks page directory (pgd) with the new pte
136 * o zero the rest of the init tasks pgdir (FIXME - what about vmalloc?!)
137 */
138void __init memtable_init(struct meminfo *mi)
139{
140 pte_t *pte;
141 int i;
142
143 page_nr = max_low_pfn;
144
145 pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
146 pte[0] = mk_pte_phys(PAGE_OFFSET + SCREEN_SIZE, PAGE_READONLY);
147 pmd_populate(&init_mm, pmd_offset(swapper_pg_dir, 0), pte);
148
149 for (i = 1; i < PTRS_PER_PGD; i++)
150 pgd_val(swapper_pg_dir[i]) = 0;
151}
152
153void __init iotable_init(struct map_desc *io_desc)
154{
155 /* nothing to do */
156}
157
158/*
159 * We never have holes in the memmap
160 */
161void __init create_memmap_holes(struct meminfo *mi)
162{
163}
164
165static void pte_cache_ctor(void *pte, struct kmem_cache *cache, unsigned long flags)
166{
167 memzero(pte, sizeof(pte_t) * PTRS_PER_PTE);
168}
169
170static void pgd_cache_ctor(void *pgd, struct kmem_cache *cache, unsigned long flags)
171{
172 memzero(pgd + MEMC_TABLE_SIZE, USER_PTRS_PER_PGD * sizeof(pgd_t));
173}
174
175void __init pgtable_cache_init(void)
176{
177 pte_cache = kmem_cache_create("pte-cache",
178 sizeof(pte_t) * PTRS_PER_PTE,
179 0, SLAB_PANIC, pte_cache_ctor);
180
181 pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE +
182 sizeof(pgd_t) * PTRS_PER_PGD,
183 0, SLAB_PANIC, pgd_cache_ctor);
184}
diff --git a/arch/arm26/mm/proc-funcs.S b/arch/arm26/mm/proc-funcs.S
deleted file mode 100644
index f9fca524c57a..000000000000
--- a/arch/arm26/mm/proc-funcs.S
+++ /dev/null
@@ -1,359 +0,0 @@
1/*
2 * linux/arch/arm26/mm/proc-arm2,3.S
3 *
4 * Copyright (C) 1997-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * MMU functions for ARM2,3
11 *
12 * These are the low level assembler for performing cache
13 * and memory functions on ARM2, ARM250 and ARM3 processors.
14 */
15#include <linux/linkage.h>
16#include <asm/assembler.h>
17#include <asm/asm-offsets.h>
18#include <asm/procinfo.h>
19#include <asm/ptrace.h>
20
21/*
22 * MEMC workhorse code. It's both a horse which things it's a pig.
23 */
24/*
25 * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
26 * Params : pgd Page tables/MEMC mapping
27 * : phys_pte physical address, or PTE
28 * : addr virtual address
29 */
30ENTRY(cpu_memc_update_entry)
31 tst r1, #PAGE_PRESENT @ is the page present
32 orreq r1, r1, #PAGE_OLD | PAGE_CLEAN
33 moveq r2, #0x01f00000
34 mov r3, r1, lsr #13 @ convert to physical page nr
35 and r3, r3, #0x3fc
36 adr ip, memc_phys_table_32
37 ldr r3, [ip, r3]
38 tst r1, #PAGE_OLD | PAGE_NOT_USER
39 biceq r3, r3, #0x200
40 tsteq r1, #PAGE_READONLY | PAGE_CLEAN
41 biceq r3, r3, #0x300
42 mov r2, r2, lsr #15 @ virtual -> nr
43 orr r3, r3, r2, lsl #15
44 and r2, r2, #0x300
45 orr r3, r3, r2, lsl #2
46 and r2, r3, #255
47 sub r0, r0, #256 * 4
48 str r3, [r0, r2, lsl #2]
49 strb r3, [r3]
50 movs pc, lr
51/*
52 * Params : r0 = preserved
53 * : r1 = memc table base (preserved)
54 * : r2 = page table entry
55 * : r3 = preserved
56 * : r4 = unused
57 * : r5 = memc physical address translation table
58 * : ip = virtual address (preserved)
59 */
60update_pte:
61 mov r4, r2, lsr #13
62 and r4, r4, #0x3fc
63 ldr r4, [r5, r4] @ covert to MEMC page
64
65 tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read
66 biceq r4, r4, #0x200
67 tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
68 biceq r4, r4, #0x300
69
70 orr r4, r4, ip
71 and r2, ip, #0x01800000
72 orr r4, r4, r2, lsr #13
73
74 and r2, r4, #255
75 str r4, [r1, r2, lsl #2]
76 movs pc, lr
77
78/*
79 * Params : r0 = preserved
80 * : r1 = memc table base (preserved)
81 * : r2 = page table base
82 * : r3 = preserved
83 * : r4 = unused
84 * : r5 = memc physical address translation table
85 * : ip = virtual address (updated)
86 */
87update_pte_table:
88 stmfd sp!, {r0, lr}
89 bic r0, r2, #3
901: ldr r2, [r0], #4 @ get entry
91 tst r2, #PAGE_PRESENT @ page present
92 blne update_pte @ process pte
93 add ip, ip, #32768 @ increment virt addr
94 ldr r2, [r0], #4 @ get entry
95 tst r2, #PAGE_PRESENT @ page present
96 blne update_pte @ process pte
97 add ip, ip, #32768 @ increment virt addr
98 ldr r2, [r0], #4 @ get entry
99 tst r2, #PAGE_PRESENT @ page present
100 blne update_pte @ process pte
101 add ip, ip, #32768 @ increment virt addr
102 ldr r2, [r0], #4 @ get entry
103 tst r2, #PAGE_PRESENT @ page present
104 blne update_pte @ process pte
105 add ip, ip, #32768 @ increment virt addr
106 tst ip, #32768 * 31 @ finished?
107 bne 1b
108 ldmfd sp!, {r0, pc}^
109
110/*
111 * Function: cpu_memc_update_all(pgd_t *pgd)
112 * Params : pgd Page tables/MEMC mapping
113 * Notes : this is optimised for 32k pages
114 */
115ENTRY(cpu_memc_update_all)
116 stmfd sp!, {r4, r5, lr}
117 bl clear_tables
118 sub r1, r0, #256 * 4 @ start of MEMC tables
119 adr r5, memc_phys_table_32 @ Convert to logical page number
120 mov ip, #0 @ virtual address
1211: ldmia r0!, {r2, r3} @ load two pgd entries
122 tst r2, #PAGE_PRESENT @ is pgd entry present?
123 addeq ip, ip, #1048576 @FIXME - PAGE_PRESENT is for PTEs technically...
124 blne update_pte_table
125 mov r2, r3
126 tst r2, #PAGE_PRESENT @ is pgd entry present?
127 addeq ip, ip, #1048576
128 blne update_pte_table
129 teq ip, #32 * 1048576
130 bne 1b
131 ldmfd sp!, {r4, r5, pc}^
132
133/*
134 * Build the table to map from physical page number to memc page number
135 */
136 .type memc_phys_table_32, #object
137memc_phys_table_32:
138 .irp b7, 0x00, 0x80
139 .irp b6, 0x00, 0x02
140 .irp b5, 0x00, 0x04
141 .irp b4, 0x00, 0x01
142
143 .irp b3, 0x00, 0x40
144 .irp b2, 0x00, 0x20
145 .irp b1, 0x00, 0x10
146 .irp b0, 0x00, 0x08
147 .long 0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
148 .endr
149 .endr
150 .endr
151 .endr
152
153 .endr
154 .endr
155 .endr
156 .endr
157 .size memc_phys_table_32, . - memc_phys_table_32
158
159/*
160 * helper for cpu_memc_update_all, this clears out all
161 * mappings, setting them close to the top of memory,
162 * and inaccessible (0x01f00000).
163 * Params : r0 = page table pointer
164 */
165clear_tables: ldr r1, _arm3_set_pgd - 4
166 ldr r2, [r1]
167 sub r1, r0, #256 * 4 @ start of MEMC tables
168 add r2, r1, r2, lsl #2 @ end of tables
169 mov r3, #0x03f00000 @ Default mapping (null mapping)
170 orr r3, r3, #0x00000f00
171 orr r4, r3, #1
172 orr r5, r3, #2
173 orr ip, r3, #3
1741: stmia r1!, {r3, r4, r5, ip}
175 add r3, r3, #4
176 add r4, r4, #4
177 add r5, r5, #4
178 add ip, ip, #4
179 stmia r1!, {r3, r4, r5, ip}
180 add r3, r3, #4
181 add r4, r4, #4
182 add r5, r5, #4
183 add ip, ip, #4
184 teq r1, r2
185 bne 1b
186 mov pc, lr
187
188/*
189 * Function: *_set_pgd(pgd_t *pgd)
190 * Params : pgd New page tables/MEMC mapping
191 * Purpose : update MEMC hardware with new mapping
192 */
193 .word page_nr @ extern - declared in mm-memc.c
194_arm3_set_pgd: mcr p15, 0, r1, c1, c0, 0 @ flush cache
195_arm2_set_pgd: stmfd sp!, {lr}
196 ldr r1, _arm3_set_pgd - 4
197 ldr r2, [r1]
198 sub r0, r0, #256 * 4 @ start of MEMC tables
199 add r1, r0, r2, lsl #2 @ end of tables
2001: ldmia r0!, {r2, r3, ip, lr}
201 strb r2, [r2]
202 strb r3, [r3]
203 strb ip, [ip]
204 strb lr, [lr]
205 ldmia r0!, {r2, r3, ip, lr}
206 strb r2, [r2]
207 strb r3, [r3]
208 strb ip, [ip]
209 strb lr, [lr]
210 teq r0, r1
211 bne 1b
212 ldmfd sp!, {pc}^
213
214/*
215 * Function: *_proc_init (void)
216 * Purpose : Initialise the cache control registers
217 */
218_arm3_proc_init:
219 mov r0, #0x001f0000
220 orr r0, r0, #0x0000ff00
221 orr r0, r0, #0x000000ff
222 mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable
223 mcr p15, 0, r0, c4, c0 @ ARM3 Updateable
224 mov r0, #0
225 mcr p15, 0, r0, c5, c0 @ ARM3 Disruptive
226 mcr p15, 0, r0, c1, c0 @ ARM3 Flush
227 mov r0, #3
228 mcr p15, 0, r0, c2, c0 @ ARM3 Control
229_arm2_proc_init:
230 movs pc, lr
231
232/*
233 * Function: *_proc_fin (void)
234 * Purpose : Finalise processor (disable caches)
235 */
236_arm3_proc_fin: mov r0, #2
237 mcr p15, 0, r0, c2, c0
238_arm2_proc_fin: orrs pc, lr, #PSR_I_BIT|PSR_F_BIT
239
240/*
241 * Function: *_xchg_1 (int new, volatile void *ptr)
242 * Params : new New value to store at...
243 * : ptr pointer to byte-wide location
244 * Purpose : Performs an exchange operation
245 * Returns : Original byte data at 'ptr'
246 */
247_arm2_xchg_1: mov r2, pc
248 orr r2, r2, #PSR_I_BIT
249 teqp r2, #0
250 ldrb r2, [r1]
251 strb r0, [r1]
252 mov r0, r2
253 movs pc, lr
254
255_arm3_xchg_1: swpb r0, r0, [r1]
256 movs pc, lr
257
258/*
259 * Function: *_xchg_4 (int new, volatile void *ptr)
260 * Params : new New value to store at...
261 * : ptr pointer to word-wide location
262 * Purpose : Performs an exchange operation
263 * Returns : Original word data at 'ptr'
264 */
265_arm2_xchg_4: mov r2, pc
266 orr r2, r2, #PSR_I_BIT
267 teqp r2, #0
268 ldr r2, [r1]
269 str r0, [r1]
270 mov r0, r2
271 movs pc, lr
272
273_arm3_xchg_4: swp r0, r0, [r1]
274 movs pc, lr
275
276_arm2_3_check_bugs:
277 bics pc, lr, #PSR_F_BIT @ Clear FIQ disable bit
278
279armvlsi_name: .asciz "ARM/VLSI"
280_arm2_name: .asciz "ARM 2"
281_arm250_name: .asciz "ARM 250"
282_arm3_name: .asciz "ARM 3"
283
284 .section ".init.text", #alloc, #execinstr
285/*
286 * Purpose : Function pointers used to access above functions - all calls
287 * come through these
288 */
289 .globl arm2_processor_functions
290arm2_processor_functions:
291 .word _arm2_3_check_bugs
292 .word _arm2_proc_init
293 .word _arm2_proc_fin
294 .word _arm2_set_pgd
295 .word _arm2_xchg_1
296 .word _arm2_xchg_4
297
298cpu_arm2_info:
299 .long armvlsi_name
300 .long _arm2_name
301
302 .globl arm250_processor_functions
303arm250_processor_functions:
304 .word _arm2_3_check_bugs
305 .word _arm2_proc_init
306 .word _arm2_proc_fin
307 .word _arm2_set_pgd
308 .word _arm3_xchg_1
309 .word _arm3_xchg_4
310
311cpu_arm250_info:
312 .long armvlsi_name
313 .long _arm250_name
314
315 .globl arm3_processor_functions
316arm3_processor_functions:
317 .word _arm2_3_check_bugs
318 .word _arm3_proc_init
319 .word _arm3_proc_fin
320 .word _arm3_set_pgd
321 .word _arm3_xchg_1
322 .word _arm3_xchg_4
323
324cpu_arm3_info:
325 .long armvlsi_name
326 .long _arm3_name
327
328arm2_arch_name: .asciz "armv1"
329arm3_arch_name: .asciz "armv2"
330arm2_elf_name: .asciz "v1"
331arm3_elf_name: .asciz "v2"
332 .align
333
334 .section ".proc.info", #alloc, #execinstr
335
336 .long 0x41560200
337 .long 0xfffffff0
338 .long arm2_arch_name
339 .long arm2_elf_name
340 .long 0
341 .long cpu_arm2_info
342 .long arm2_processor_functions
343
344 .long 0x41560250
345 .long 0xfffffff0
346 .long arm3_arch_name
347 .long arm3_elf_name
348 .long 0
349 .long cpu_arm250_info
350 .long arm250_processor_functions
351
352 .long 0x41560300
353 .long 0xfffffff0
354 .long arm3_arch_name
355 .long arm3_elf_name
356 .long 0
357 .long cpu_arm3_info
358 .long arm3_processor_functions
359
diff --git a/arch/arm26/mm/small_page.c b/arch/arm26/mm/small_page.c
deleted file mode 100644
index 30447106c25f..000000000000
--- a/arch/arm26/mm/small_page.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/*
2 * linux/arch/arm26/mm/small_page.c
3 *
4 * Copyright (C) 1996 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Changelog:
12 * 26/01/1996 RMK Cleaned up various areas to make little more generic
13 * 07/02/1999 RMK Support added for 16K and 32K page sizes
14 * containing 8K blocks
15 * 23/05/2004 IM Fixed to use struct page->lru (thanks wli)
16 *
17 */
18#include <linux/signal.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/string.h>
23#include <linux/types.h>
24#include <linux/ptrace.h>
25#include <linux/mman.h>
26#include <linux/mm.h>
27#include <linux/swap.h>
28#include <linux/smp.h>
29#include <linux/bitops.h>
30
31#include <asm/pgtable.h>
32
33#define PEDANTIC
34
35/*
36 * Requirement:
37 * We need to be able to allocate naturally aligned memory of finer
38 * granularity than the page size. This is typically used for the
39 * second level page tables on 32-bit ARMs.
40 *
41 * FIXME - this comment is *out of date*
42 * Theory:
43 * We "misuse" the Linux memory management system. We use alloc_page
44 * to allocate a page and then mark it as reserved. The Linux memory
45 * management system will then ignore the "offset", "next_hash" and
46 * "pprev_hash" entries in the mem_map for this page.
47 *
48 * We then use a bitstring in the "offset" field to mark which segments
49 * of the page are in use, and manipulate this as required during the
50 * allocation and freeing of these small pages.
51 *
52 * We also maintain a queue of pages being used for this purpose using
53 * the "next_hash" and "pprev_hash" entries of mem_map;
54 */
55
56struct order {
57 struct list_head queue;
58 unsigned int mask; /* (1 << shift) - 1 */
59 unsigned int shift; /* (1 << shift) size of page */
60 unsigned int block_mask; /* nr_blocks - 1 */
61 unsigned int all_used; /* (1 << nr_blocks) - 1 */
62};
63
64
65static struct order orders[] = {
66#if PAGE_SIZE == 32768
67 { LIST_HEAD_INIT(orders[0].queue), 2047, 11, 15, 0x0000ffff },
68 { LIST_HEAD_INIT(orders[1].queue), 8191, 13, 3, 0x0000000f }
69#else
70#error unsupported page size (ARGH!)
71#endif
72};
73
74#define USED_MAP(pg) ((pg)->index)
75#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &USED_MAP(pg)))
76#define SET_USED(pg,off) (set_bit(off, &USED_MAP(pg)))
77
78static DEFINE_SPINLOCK(small_page_lock);
79
80static unsigned long __get_small_page(int priority, struct order *order)
81{
82 unsigned long flags;
83 struct page *page;
84 int offset;
85
86 do {
87 spin_lock_irqsave(&small_page_lock, flags);
88
89 if (list_empty(&order->queue))
90 goto need_new_page;
91
92 page = list_entry(order->queue.next, struct page, lru);
93again:
94#ifdef PEDANTIC
95 BUG_ON(USED_MAP(page) & ~order->all_used);
96#endif
97 offset = ffz(USED_MAP(page));
98 SET_USED(page, offset);
99 if (USED_MAP(page) == order->all_used)
100 list_del_init(&page->lru);
101 spin_unlock_irqrestore(&small_page_lock, flags);
102
103 return (unsigned long) page_address(page) + (offset << order->shift);
104
105need_new_page:
106 spin_unlock_irqrestore(&small_page_lock, flags);
107 page = alloc_page(priority);
108 spin_lock_irqsave(&small_page_lock, flags);
109
110 if (list_empty(&order->queue)) {
111 if (!page)
112 goto no_page;
113 SetPageReserved(page);
114 USED_MAP(page) = 0;
115 list_add(&page->lru, &order->queue);
116 goto again;
117 }
118
119 spin_unlock_irqrestore(&small_page_lock, flags);
120 __free_page(page);
121 } while (1);
122
123no_page:
124 spin_unlock_irqrestore(&small_page_lock, flags);
125 return 0;
126}
127
128static void __free_small_page(unsigned long spage, struct order *order)
129{
130 unsigned long flags;
131 struct page *page;
132
133 if (virt_addr_valid(spage)) {
134 page = virt_to_page(spage);
135
136 /*
137 * The container-page must be marked Reserved
138 */
139 if (!PageReserved(page) || spage & order->mask)
140 goto non_small;
141
142#ifdef PEDANTIC
143 BUG_ON(USED_MAP(page) & ~order->all_used);
144#endif
145
146 spage = spage >> order->shift;
147 spage &= order->block_mask;
148
149 /*
150 * the following must be atomic wrt get_page
151 */
152 spin_lock_irqsave(&small_page_lock, flags);
153
154 if (USED_MAP(page) == order->all_used)
155 list_add(&page->lru, &order->queue);
156
157 if (!TEST_AND_CLEAR_USED(page, spage))
158 goto already_free;
159
160 if (USED_MAP(page) == 0)
161 goto free_page;
162
163 spin_unlock_irqrestore(&small_page_lock, flags);
164 }
165 return;
166
167free_page:
168 /*
169 * unlink the page from the small page queue and free it
170 */
171 list_del_init(&page->lru);
172 spin_unlock_irqrestore(&small_page_lock, flags);
173 ClearPageReserved(page);
174 __free_page(page);
175 return;
176
177non_small:
178 printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
179 return;
180already_free:
181 printk("Trying to free free small page from %p\n", __builtin_return_address(0));
182}
183
184unsigned long get_page_8k(int priority)
185{
186 return __get_small_page(priority, orders+1);
187}
188
189void free_page_8k(unsigned long spage)
190{
191 __free_small_page(spage, orders+1);
192}
diff --git a/arch/arm26/nwfpe/ARM-gcc.h b/arch/arm26/nwfpe/ARM-gcc.h
deleted file mode 100644
index e6598470b076..000000000000
--- a/arch/arm26/nwfpe/ARM-gcc.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2-------------------------------------------------------------------------------
3The macro `BITS64' can be defined to indicate that 64-bit integer types are
4supported by the compiler.
5-------------------------------------------------------------------------------
6*/
7#define BITS64
8
9/*
10-------------------------------------------------------------------------------
11Each of the following `typedef's defines the most convenient type that holds
12integers of at least as many bits as specified. For example, `uint8' should
13be the most convenient type that can hold unsigned integers of as many as
148 bits. The `flag' type must be able to hold either a 0 or 1. For most
15implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
16to the same as `int'.
17-------------------------------------------------------------------------------
18*/
19typedef char flag;
20typedef unsigned char uint8;
21typedef signed char int8;
22typedef int uint16;
23typedef int int16;
24typedef unsigned int uint32;
25typedef signed int int32;
26#ifdef BITS64
27typedef unsigned long long int bits64;
28typedef signed long long int sbits64;
29#endif
30
31/*
32-------------------------------------------------------------------------------
33Each of the following `typedef's defines a type that holds integers
34of _exactly_ the number of bits specified. For instance, for most
35implementation of C, `bits16' and `sbits16' should be `typedef'ed to
36`unsigned short int' and `signed short int' (or `short int'), respectively.
37-------------------------------------------------------------------------------
38*/
39typedef unsigned char bits8;
40typedef signed char sbits8;
41typedef unsigned short int bits16;
42typedef signed short int sbits16;
43typedef unsigned int bits32;
44typedef signed int sbits32;
45#ifdef BITS64
46typedef unsigned long long int uint64;
47typedef signed long long int int64;
48#endif
49
50#ifdef BITS64
51/*
52-------------------------------------------------------------------------------
53The `LIT64' macro takes as its argument a textual integer literal and if
54necessary ``marks'' the literal as having a 64-bit integer type. For
55example, the Gnu C Compiler (`gcc') requires that 64-bit literals be
56appended with the letters `LL' standing for `long long', which is `gcc's
57name for the 64-bit integer type. Some compilers may allow `LIT64' to be
58defined as the identity macro: `#define LIT64( a ) a'.
59-------------------------------------------------------------------------------
60*/
61#define LIT64( a ) a##LL
62#endif
63
64/*
65-------------------------------------------------------------------------------
66The macro `INLINE' can be used before functions that should be inlined. If
67a compiler does not support explicit inlining, this macro should be defined
68to be `static'.
69-------------------------------------------------------------------------------
70*/
71#define INLINE extern __inline__
72
73
74/* For use as a GCC soft-float library we need some special function names. */
75
76#ifdef __LIBFLOAT__
77
78/* Some 32-bit ops can be mapped straight across by just changing the name. */
79#define float32_add __addsf3
80#define float32_sub __subsf3
81#define float32_mul __mulsf3
82#define float32_div __divsf3
83#define int32_to_float32 __floatsisf
84#define float32_to_int32_round_to_zero __fixsfsi
85#define float32_to_uint32_round_to_zero __fixunssfsi
86
87/* These ones go through the glue code. To avoid namespace pollution
88 we rename the internal functions too. */
89#define float32_eq ___float32_eq
90#define float32_le ___float32_le
91#define float32_lt ___float32_lt
92
93/* All the 64-bit ops have to go through the glue, so we pull the same
94 trick. */
95#define float64_add ___float64_add
96#define float64_sub ___float64_sub
97#define float64_mul ___float64_mul
98#define float64_div ___float64_div
99#define int32_to_float64 ___int32_to_float64
100#define float64_to_int32_round_to_zero ___float64_to_int32_round_to_zero
101#define float64_to_uint32_round_to_zero ___float64_to_uint32_round_to_zero
102#define float64_to_float32 ___float64_to_float32
103#define float32_to_float64 ___float32_to_float64
104#define float64_eq ___float64_eq
105#define float64_le ___float64_le
106#define float64_lt ___float64_lt
107
108#if 0
109#define float64_add __adddf3
110#define float64_sub __subdf3
111#define float64_mul __muldf3
112#define float64_div __divdf3
113#define int32_to_float64 __floatsidf
114#define float64_to_int32_round_to_zero __fixdfsi
115#define float64_to_uint32_round_to_zero __fixunsdfsi
116#define float64_to_float32 __truncdfsf2
117#define float32_to_float64 __extendsfdf2
118#endif
119
120#endif
diff --git a/arch/arm26/nwfpe/ChangeLog b/arch/arm26/nwfpe/ChangeLog
deleted file mode 100644
index 0c580f764baf..000000000000
--- a/arch/arm26/nwfpe/ChangeLog
+++ /dev/null
@@ -1,83 +0,0 @@
12002-01-19 Russell King <rmk@arm.linux.org.uk>
2
3 * fpa11.h - Add documentation
4 - remove userRegisters pointer from this structure.
5 - add new method to obtain integer register values.
6 * softfloat.c - Remove float128
7 * softfloat.h - Remove float128
8 * softfloat-specialize - Remove float128
9
10 * The FPA11 structure is not a kernel-specific data structure.
11 It is used by users of ptrace to examine the values of the
12 floating point registers. Therefore, any changes to the
13 FPA11 structure (size or position of elements contained
14 within) have to be well thought out.
15
16 * Since 128-bit float requires the FPA11 structure to change
17 size, it has been removed. 128-bit float is currently unused,
18 and needs various things to be re-worked so that we won't
19 overflow the available space in the task structure.
20
21 * The changes are designed to break any patch that goes on top
22 of this code, so that the authors properly review their changes.
23
241999-08-19 Scott Bambrough <scottb@netwinder.org>
25
26 * fpmodule.c - Changed version number to 0.95
27 * fpa11.h - modified FPA11, FPREG structures
28 * fpa11.c - Changes due to FPA11, FPREG structure alterations.
29 * fpa11_cpdo.c - Changes due to FPA11, FPREG structure alterations.
30 * fpa11_cpdt.c - Changes due to FPA11, FPREG structure alterations.
31 * fpa11_cprt.c - Changes due to FPA11, FPREG structure alterations.
32 * single_cpdo.c - Changes due to FPA11, FPREG structure alterations.
33 * double_cpdo.c - Changes due to FPA11, FPREG structure alterations.
34 * extended_cpdo.c - Changes due to FPA11, FPREG structure alterations.
35
36 * I discovered several bugs. First and worst is that the kernel
37 passes in a pointer to the FPE's state area. This is defined
38 as a struct user_fp (see user.h). This pointer was cast to a
39 FPA11*. Unfortunately FPA11 and user_fp are of different sizes;
40 user_fp is smaller. This meant that the FPE scribbled on things
41 below its area, which is bad, as the area is in the thread_struct
42 embedded in the process task structure. Thus we were scribbling
43 over one of the most important structures in the entire OS.
44
45 * user_fp and FPA11 have now been harmonized. Most of the changes
46 in the above code were dereferencing problems due to moving the
47 register type out of FPREG, and getting rid of the union variable
48 fpvalue.
49
50 * Second I noticed resetFPA11 was not always being called for a
51 task. This should happen on the first floating point exception
52 that occurs. It is controlled by init_flag in FPA11. The
53 comment in the code beside init_flag state the kernel guarantees
54 this to be zero. Not so. I found that the kernel recycles task
55 structures, and that recycled ones may not have init_flag zeroed.
56 I couldn't even find anything that guarantees it is zeroed when
57 when the task structure is initially allocated. In any case
58 I now initialize the entire FPE state in the thread structure to
59 zero when allocated and recycled. See alloc_task_struct() and
60 flush_thread() in arch/arm/process.c. The change to
61 alloc_task_struct() may not be necessary, but I left it in for
62 completeness (better safe than sorry).
63
641998-11-23 Scott Bambrough <scottb@netwinder.org>
65
66 * README.FPE - fix typo in description of lfm/sfm instructions
67 * NOTES - Added file to describe known bugs/problems
68 * fpmodule.c - Changed version number to 0.94
69
701998-11-20 Scott Bambrough <scottb@netwinder.org>
71
72 * README.FPE - fix description of URD, NRM instructions
73 * TODO - remove URD, NRM instructions from TODO list
74 * single_cpdo.c - implement URD, NRM
75 * double_cpdo.c - implement URD, NRM
76 * extended_cpdo.c - implement URD, NRM
77
781998-11-19 Scott Bambrough <scottb@netwinder.org>
79
80 * ChangeLog - Added this file to track changes made.
81 * fpa11.c - added code to initialize register types to typeNone
82 * fpa11_cpdt.c - fixed bug in storeExtended (typeExtended changed to
83 typeDouble in switch statement)
diff --git a/arch/arm26/nwfpe/Makefile b/arch/arm26/nwfpe/Makefile
deleted file mode 100644
index b39d34dff054..000000000000
--- a/arch/arm26/nwfpe/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
1#
2# Copyright (C) 1998, 1999, 2001 Philip Blundell
3#
4
5obj-y :=
6obj-m :=
7obj-n :=
8
9obj-$(CONFIG_FPE_NWFPE) += nwfpe.o
10
11nwfpe-objs := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
12 fpmodule.o fpopcode.o softfloat.o \
13 single_cpdo.o double_cpdo.o extended_cpdo.o \
14 entry.o
15
diff --git a/arch/arm26/nwfpe/double_cpdo.c b/arch/arm26/nwfpe/double_cpdo.c
deleted file mode 100644
index 7f4fef0216c7..000000000000
--- a/arch/arm26/nwfpe/double_cpdo.c
+++ /dev/null
@@ -1,288 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "softfloat.h"
24#include "fpopcode.h"
25
26float64 float64_exp(float64 Fm);
27float64 float64_ln(float64 Fm);
28float64 float64_sin(float64 rFm);
29float64 float64_cos(float64 rFm);
30float64 float64_arcsin(float64 rFm);
31float64 float64_arctan(float64 rFm);
32float64 float64_log(float64 rFm);
33float64 float64_tan(float64 rFm);
34float64 float64_arccos(float64 rFm);
35float64 float64_pow(float64 rFn,float64 rFm);
36float64 float64_pol(float64 rFn,float64 rFm);
37
38unsigned int DoubleCPDO(const unsigned int opcode)
39{
40 FPA11 *fpa11 = GET_FPA11();
41 float64 rFm, rFn = 0; //FIXME - should be zero?
42 unsigned int Fd, Fm, Fn, nRc = 1;
43
44 //printk("DoubleCPDO(0x%08x)\n",opcode);
45
46 Fm = getFm(opcode);
47 if (CONSTANT_FM(opcode))
48 {
49 rFm = getDoubleConstant(Fm);
50 }
51 else
52 {
53 switch (fpa11->fType[Fm])
54 {
55 case typeSingle:
56 rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
57 break;
58
59 case typeDouble:
60 rFm = fpa11->fpreg[Fm].fDouble;
61 break;
62
63 case typeExtended:
64 // !! patb
65 //printk("not implemented! why not?\n");
66 //!! ScottB
67 // should never get here, if extended involved
68 // then other operand should be promoted then
69 // ExtendedCPDO called.
70 break;
71
72 default: return 0;
73 }
74 }
75
76 if (!MONADIC_INSTRUCTION(opcode))
77 {
78 Fn = getFn(opcode);
79 switch (fpa11->fType[Fn])
80 {
81 case typeSingle:
82 rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
83 break;
84
85 case typeDouble:
86 rFn = fpa11->fpreg[Fn].fDouble;
87 break;
88
89 default: return 0;
90 }
91 }
92
93 Fd = getFd(opcode);
94 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
95 switch (opcode & MASK_ARITHMETIC_OPCODE)
96 {
97 /* dyadic opcodes */
98 case ADF_CODE:
99 fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
100 break;
101
102 case MUF_CODE:
103 case FML_CODE:
104 fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
105 break;
106
107 case SUF_CODE:
108 fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
109 break;
110
111 case RSF_CODE:
112 fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
113 break;
114
115 case DVF_CODE:
116 case FDV_CODE:
117 fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
118 break;
119
120 case RDF_CODE:
121 case FRD_CODE:
122 fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
123 break;
124
125#if 0
126 case POW_CODE:
127 fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
128 break;
129
130 case RPW_CODE:
131 fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
132 break;
133#endif
134
135 case RMF_CODE:
136 fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
137 break;
138
139#if 0
140 case POL_CODE:
141 fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
142 break;
143#endif
144
145 /* monadic opcodes */
146 case MVF_CODE:
147 fpa11->fpreg[Fd].fDouble = rFm;
148 break;
149
150 case MNF_CODE:
151 {
152 unsigned int *p = (unsigned int*)&rFm;
153 p[1] ^= 0x80000000;
154 fpa11->fpreg[Fd].fDouble = rFm;
155 }
156 break;
157
158 case ABS_CODE:
159 {
160 unsigned int *p = (unsigned int*)&rFm;
161 p[1] &= 0x7fffffff;
162 fpa11->fpreg[Fd].fDouble = rFm;
163 }
164 break;
165
166 case RND_CODE:
167 case URD_CODE:
168 fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm);
169 break;
170
171 case SQT_CODE:
172 fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
173 break;
174
175#if 0
176 case LOG_CODE:
177 fpa11->fpreg[Fd].fDouble = float64_log(rFm);
178 break;
179
180 case LGN_CODE:
181 fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
182 break;
183
184 case EXP_CODE:
185 fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
186 break;
187
188 case SIN_CODE:
189 fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
190 break;
191
192 case COS_CODE:
193 fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
194 break;
195
196 case TAN_CODE:
197 fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
198 break;
199
200 case ASN_CODE:
201 fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
202 break;
203
204 case ACS_CODE:
205 fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
206 break;
207
208 case ATN_CODE:
209 fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
210 break;
211#endif
212
213 case NRM_CODE:
214 break;
215
216 default:
217 {
218 nRc = 0;
219 }
220 }
221
222 if (0 != nRc) fpa11->fType[Fd] = typeDouble;
223 return nRc;
224}
225
226#if 0
227float64 float64_exp(float64 rFm)
228{
229 return rFm;
230//series
231}
232
233float64 float64_ln(float64 rFm)
234{
235 return rFm;
236//series
237}
238
239float64 float64_sin(float64 rFm)
240{
241 return rFm;
242//series
243}
244
245float64 float64_cos(float64 rFm)
246{
247 return rFm;
248 //series
249}
250
251#if 0
252float64 float64_arcsin(float64 rFm)
253{
254//series
255}
256
257float64 float64_arctan(float64 rFm)
258{
259 //series
260}
261#endif
262
263float64 float64_log(float64 rFm)
264{
265 return float64_div(float64_ln(rFm),getDoubleConstant(7));
266}
267
268float64 float64_tan(float64 rFm)
269{
270 return float64_div(float64_sin(rFm),float64_cos(rFm));
271}
272
273float64 float64_arccos(float64 rFm)
274{
275return rFm;
276 //return float64_sub(halfPi,float64_arcsin(rFm));
277}
278
279float64 float64_pow(float64 rFn,float64 rFm)
280{
281 return float64_exp(float64_mul(rFm,float64_ln(rFn)));
282}
283
284float64 float64_pol(float64 rFn,float64 rFm)
285{
286 return float64_arctan(float64_div(rFn,rFm));
287}
288#endif
diff --git a/arch/arm26/nwfpe/entry.S b/arch/arm26/nwfpe/entry.S
deleted file mode 100644
index e6312000d9f8..000000000000
--- a/arch/arm26/nwfpe/entry.S
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998
4 (c) Philip Blundell 1998-1999
5
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <asm/asm-offsets.h>
24
25/* This is the kernel's entry point into the floating point emulator.
26It is called from the kernel with code similar to this:
27
28 mov fp, #0
29 teqp pc, #PSR_I_BIT | MODE_SVC
30 ldr r4, .LC2
31 ldr pc, [r4] @ Call FP module USR entry point
32
33The kernel expects the emulator to return via one of two possible
34points of return it passes to the emulator. The emulator, if
35successful in its emulation, jumps to ret_from_exception and the
36kernel takes care of returning control from the trap to the user code.
37If the emulator is unable to emulate the instruction, it returns to
38fpundefinstr and the kernel halts the user program with a core dump.
39
40This routine does four things:
41
421) It saves SP into a variable called userRegisters. The kernel has
43created a struct pt_regs on the stack and saved the user registers
44into it. See /usr/include/asm/proc/ptrace.h for details. The
45emulator code uses userRegisters as the base of an array of words from
46which the contents of the registers can be extracted.
47
482) It locates the FP emulator work area within the TSS structure and
49points `fpa11' to it.
50
513) It calls EmulateAll to emulate a floating point instruction.
52EmulateAll returns 1 if the emulation was successful, or 0 if not.
53
544) If an instruction has been emulated successfully, it looks ahead at
55the next instruction. If it is a floating point instruction, it
56executes the instruction, without returning to user space. In this
57way it repeatedly looks ahead and executes floating point instructions
58until it encounters a non floating point instruction, at which time it
59returns via _fpreturn.
60
61This is done to reduce the effect of the trap overhead on each
62floating point instructions. GCC attempts to group floating point
63instructions to allow the emulator to spread the cost of the trap over
64several floating point instructions. */
65
66 .globl nwfpe_enter
67nwfpe_enter:
68 mov sl, sp
69 bl FPA11_CheckInit @ check to see if we are initialised
70
71 ldr r5, [sp, #60] @ get contents of PC
72 bic r5, r5, #0xfc000003
73 ldr r0, [r5, #-4] @ get actual instruction into r0
74 bl EmulateAll @ emulate the instruction
751: cmp r0, #0 @ was emulation successful
76 beq fpundefinstr @ no, return failure
77
78next:
79.Lx1: ldrt r6, [r5], #4 @ get the next instruction and
80 @ increment PC
81
82 and r2, r6, #0x0F000000 @ test for FP insns
83 teq r2, #0x0C000000
84 teqne r2, #0x0D000000
85 teqne r2, #0x0E000000
86 bne ret_from_exception @ return ok if not a fp insn
87
88 ldr r9, [sp, #60] @ get new condition codes
89 and r9, r9, #0xfc000003
90 orr r7, r5, r9
91 str r7, [sp, #60] @ update PC copy in regs
92
93 mov r0, r6 @ save a copy
94 mov r1, r9 @ fetch the condition codes
95 bl checkCondition @ check the condition
96 cmp r0, #0 @ r0 = 0 ==> condition failed
97
98 @ if condition code failed to match, next insn
99 beq next @ get the next instruction;
100
101 mov r0, r6 @ prepare for EmulateAll()
102 adr lr, 1b
103 orr lr, lr, #3
104 b EmulateAll @ if r0 != 0, goto EmulateAll
105
106.Lret: b ret_from_exception @ let the user eat segfaults
107
108 @ We need to be prepared for the instruction at .Lx1 to fault.
109 @ Emit the appropriate exception gunk to fix things up.
110 .section __ex_table,"a"
111 .align 3
112 .long .Lx1
113 ldr lr, [lr, $(.Lret - .Lx1)/4]
114 .previous
diff --git a/arch/arm26/nwfpe/extended_cpdo.c b/arch/arm26/nwfpe/extended_cpdo.c
deleted file mode 100644
index 331407596d91..000000000000
--- a/arch/arm26/nwfpe/extended_cpdo.c
+++ /dev/null
@@ -1,273 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "softfloat.h"
24#include "fpopcode.h"
25
26floatx80 floatx80_exp(floatx80 Fm);
27floatx80 floatx80_ln(floatx80 Fm);
28floatx80 floatx80_sin(floatx80 rFm);
29floatx80 floatx80_cos(floatx80 rFm);
30floatx80 floatx80_arcsin(floatx80 rFm);
31floatx80 floatx80_arctan(floatx80 rFm);
32floatx80 floatx80_log(floatx80 rFm);
33floatx80 floatx80_tan(floatx80 rFm);
34floatx80 floatx80_arccos(floatx80 rFm);
35floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
36floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
37
38unsigned int ExtendedCPDO(const unsigned int opcode)
39{
40 FPA11 *fpa11 = GET_FPA11();
41 floatx80 rFm, rFn;
42 unsigned int Fd, Fm, Fn, nRc = 1;
43
44 //printk("ExtendedCPDO(0x%08x)\n",opcode);
45
46 Fm = getFm(opcode);
47 if (CONSTANT_FM(opcode))
48 {
49 rFm = getExtendedConstant(Fm);
50 }
51 else
52 {
53 switch (fpa11->fType[Fm])
54 {
55 case typeSingle:
56 rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
57 break;
58
59 case typeDouble:
60 rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
61 break;
62
63 case typeExtended:
64 rFm = fpa11->fpreg[Fm].fExtended;
65 break;
66
67 default: return 0;
68 }
69 }
70
71 if (!MONADIC_INSTRUCTION(opcode))
72 {
73 Fn = getFn(opcode);
74 switch (fpa11->fType[Fn])
75 {
76 case typeSingle:
77 rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
78 break;
79
80 case typeDouble:
81 rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
82 break;
83
84 case typeExtended:
85 rFn = fpa11->fpreg[Fn].fExtended;
86 break;
87
88 default: return 0;
89 }
90 }
91
92 Fd = getFd(opcode);
93 switch (opcode & MASK_ARITHMETIC_OPCODE)
94 {
95 /* dyadic opcodes */
96 case ADF_CODE:
97 fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
98 break;
99
100 case MUF_CODE:
101 case FML_CODE:
102 fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
103 break;
104
105 case SUF_CODE:
106 fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
107 break;
108
109 case RSF_CODE:
110 fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
111 break;
112
113 case DVF_CODE:
114 case FDV_CODE:
115 fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
116 break;
117
118 case RDF_CODE:
119 case FRD_CODE:
120 fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
121 break;
122
123#if 0
124 case POW_CODE:
125 fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
126 break;
127
128 case RPW_CODE:
129 fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
130 break;
131#endif
132
133 case RMF_CODE:
134 fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
135 break;
136
137#if 0
138 case POL_CODE:
139 fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
140 break;
141#endif
142
143 /* monadic opcodes */
144 case MVF_CODE:
145 fpa11->fpreg[Fd].fExtended = rFm;
146 break;
147
148 case MNF_CODE:
149 rFm.high ^= 0x8000;
150 fpa11->fpreg[Fd].fExtended = rFm;
151 break;
152
153 case ABS_CODE:
154 rFm.high &= 0x7fff;
155 fpa11->fpreg[Fd].fExtended = rFm;
156 break;
157
158 case RND_CODE:
159 case URD_CODE:
160 fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm);
161 break;
162
163 case SQT_CODE:
164 fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
165 break;
166
167#if 0
168 case LOG_CODE:
169 fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
170 break;
171
172 case LGN_CODE:
173 fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
174 break;
175
176 case EXP_CODE:
177 fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
178 break;
179
180 case SIN_CODE:
181 fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
182 break;
183
184 case COS_CODE:
185 fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
186 break;
187
188 case TAN_CODE:
189 fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
190 break;
191
192 case ASN_CODE:
193 fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
194 break;
195
196 case ACS_CODE:
197 fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
198 break;
199
200 case ATN_CODE:
201 fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
202 break;
203#endif
204
205 case NRM_CODE:
206 break;
207
208 default:
209 {
210 nRc = 0;
211 }
212 }
213
214 if (0 != nRc) fpa11->fType[Fd] = typeExtended;
215 return nRc;
216}
217
218#if 0
219floatx80 floatx80_exp(floatx80 Fm)
220{
221//series
222}
223
224floatx80 floatx80_ln(floatx80 Fm)
225{
226//series
227}
228
229floatx80 floatx80_sin(floatx80 rFm)
230{
231//series
232}
233
234floatx80 floatx80_cos(floatx80 rFm)
235{
236//series
237}
238
239floatx80 floatx80_arcsin(floatx80 rFm)
240{
241//series
242}
243
244floatx80 floatx80_arctan(floatx80 rFm)
245{
246 //series
247}
248
249floatx80 floatx80_log(floatx80 rFm)
250{
251 return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
252}
253
254floatx80 floatx80_tan(floatx80 rFm)
255{
256 return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
257}
258
259floatx80 floatx80_arccos(floatx80 rFm)
260{
261 //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
262}
263
264floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
265{
266 return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
267}
268
269floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
270{
271 return floatx80_arctan(floatx80_div(rFn,rFm));
272}
273#endif
diff --git a/arch/arm26/nwfpe/fpa11.c b/arch/arm26/nwfpe/fpa11.c
deleted file mode 100644
index e954540a9464..000000000000
--- a/arch/arm26/nwfpe/fpa11.c
+++ /dev/null
@@ -1,221 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "fpopcode.h"
24
25#include "fpmodule.h"
26#include "fpmodule.inl"
27
28#include <linux/compiler.h>
29#include <asm/system.h>
30
31/* forward declarations */
32unsigned int EmulateCPDO(const unsigned int);
33unsigned int EmulateCPDT(const unsigned int);
34unsigned int EmulateCPRT(const unsigned int);
35
36/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
37void resetFPA11(void)
38{
39 int i;
40 FPA11 *fpa11 = GET_FPA11();
41
42 /* initialize the register type array */
43 for (i=0;i<=7;i++)
44 {
45 fpa11->fType[i] = typeNone;
46 }
47
48 /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
49 fpa11->fpsr = FP_EMULATOR | BIT_AC;
50
51 /* FPCR: set SB, AB and DA bits, clear all others */
52#if MAINTAIN_FPCR
53 fpa11->fpcr = MASK_RESET;
54#endif
55}
56
57void SetRoundingMode(const unsigned int opcode)
58{
59#if MAINTAIN_FPCR
60 FPA11 *fpa11 = GET_FPA11();
61 fpa11->fpcr &= ~MASK_ROUNDING_MODE;
62#endif
63 switch (opcode & MASK_ROUNDING_MODE)
64 {
65 default:
66 case ROUND_TO_NEAREST:
67 float_rounding_mode = float_round_nearest_even;
68#if MAINTAIN_FPCR
69 fpa11->fpcr |= ROUND_TO_NEAREST;
70#endif
71 break;
72
73 case ROUND_TO_PLUS_INFINITY:
74 float_rounding_mode = float_round_up;
75#if MAINTAIN_FPCR
76 fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
77#endif
78 break;
79
80 case ROUND_TO_MINUS_INFINITY:
81 float_rounding_mode = float_round_down;
82#if MAINTAIN_FPCR
83 fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
84#endif
85 break;
86
87 case ROUND_TO_ZERO:
88 float_rounding_mode = float_round_to_zero;
89#if MAINTAIN_FPCR
90 fpa11->fpcr |= ROUND_TO_ZERO;
91#endif
92 break;
93 }
94}
95
96void SetRoundingPrecision(const unsigned int opcode)
97{
98#if MAINTAIN_FPCR
99 FPA11 *fpa11 = GET_FPA11();
100 fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
101#endif
102 switch (opcode & MASK_ROUNDING_PRECISION)
103 {
104 case ROUND_SINGLE:
105 floatx80_rounding_precision = 32;
106#if MAINTAIN_FPCR
107 fpa11->fpcr |= ROUND_SINGLE;
108#endif
109 break;
110
111 case ROUND_DOUBLE:
112 floatx80_rounding_precision = 64;
113#if MAINTAIN_FPCR
114 fpa11->fpcr |= ROUND_DOUBLE;
115#endif
116 break;
117
118 case ROUND_EXTENDED:
119 floatx80_rounding_precision = 80;
120#if MAINTAIN_FPCR
121 fpa11->fpcr |= ROUND_EXTENDED;
122#endif
123 break;
124
125 default: floatx80_rounding_precision = 80;
126 }
127}
128
129void FPA11_CheckInit(void)
130{
131 FPA11 *fpa11 = GET_FPA11();
132 if (unlikely(fpa11->initflag == 0))
133 {
134 resetFPA11();
135 SetRoundingMode(ROUND_TO_NEAREST);
136 SetRoundingPrecision(ROUND_EXTENDED);
137 fpa11->initflag = 1;
138 }
139}
140
141/* Emulate the instruction in the opcode. */
142unsigned int EmulateAll(unsigned int opcode)
143{
144 unsigned int nRc = 1, code;
145
146 code = opcode & 0x00000f00;
147 if (code == 0x00000100 || code == 0x00000200)
148 {
149 /* For coprocessor 1 or 2 (FPA11) */
150 code = opcode & 0x0e000000;
151 if (code == 0x0e000000)
152 {
153 if (opcode & 0x00000010)
154 {
155 /* Emulate conversion opcodes. */
156 /* Emulate register transfer opcodes. */
157 /* Emulate comparison opcodes. */
158 nRc = EmulateCPRT(opcode);
159 }
160 else
161 {
162 /* Emulate monadic arithmetic opcodes. */
163 /* Emulate dyadic arithmetic opcodes. */
164 nRc = EmulateCPDO(opcode);
165 }
166 }
167 else if (code == 0x0c000000)
168 {
169 /* Emulate load/store opcodes. */
170 /* Emulate load/store multiple opcodes. */
171 nRc = EmulateCPDT(opcode);
172 }
173 else
174 {
175 /* Invalid instruction detected. Return FALSE. */
176 nRc = 0;
177 }
178 }
179
180 return(nRc);
181}
182
183#if 0
184unsigned int EmulateAll1(unsigned int opcode)
185{
186 switch ((opcode >> 24) & 0xf)
187 {
188 case 0xc:
189 case 0xd:
190 if ((opcode >> 20) & 0x1)
191 {
192 switch ((opcode >> 8) & 0xf)
193 {
194 case 0x1: return PerformLDF(opcode); break;
195 case 0x2: return PerformLFM(opcode); break;
196 default: return 0;
197 }
198 }
199 else
200 {
201 switch ((opcode >> 8) & 0xf)
202 {
203 case 0x1: return PerformSTF(opcode); break;
204 case 0x2: return PerformSFM(opcode); break;
205 default: return 0;
206 }
207 }
208 break;
209
210 case 0xe:
211 if (opcode & 0x10)
212 return EmulateCPDO(opcode);
213 else
214 return EmulateCPRT(opcode);
215 break;
216
217 default: return 0;
218 }
219}
220#endif
221
diff --git a/arch/arm26/nwfpe/fpa11.h b/arch/arm26/nwfpe/fpa11.h
deleted file mode 100644
index be09902a211d..000000000000
--- a/arch/arm26/nwfpe/fpa11.h
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.com, 1998-1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __FPA11_H__
23#define __FPA11_H__
24
25#define GET_FPA11() ((FPA11 *)(&current_thread_info()->fpstate))
26
27/*
28 * The processes registers are always at the very top of the 8K
29 * stack+task struct. Use the same method as 'current' uses to
30 * reach them.
31 */
32register unsigned int *user_registers asm("sl");
33
34#define GET_USERREG() (user_registers)
35
36#include <linux/thread_info.h>
37
38/* includes */
39#include "fpsr.h" /* FP control and status register definitions */
40#include "softfloat.h"
41
42#define typeNone 0x00
43#define typeSingle 0x01
44#define typeDouble 0x02
45#define typeExtended 0x03
46
47/*
48 * This must be no more and no less than 12 bytes.
49 */
50typedef union tagFPREG {
51 floatx80 fExtended;
52 float64 fDouble;
53 float32 fSingle;
54} FPREG;
55
56/*
57 * FPA11 device model.
58 *
59 * This structure is exported to user space. Do not re-order.
60 * Only add new stuff to the end, and do not change the size of
61 * any element. Elements of this structure are used by user
62 * space, and must match struct user_fp in include/asm-arm/user.h.
63 * We include the byte offsets below for documentation purposes.
64 *
65 * The size of this structure and FPREG are checked by fpmodule.c
66 * on initialisation. If the rules have been broken, NWFPE will
67 * not initialise.
68 */
69typedef struct tagFPA11 {
70/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */
71/* 96 */ FPSR fpsr; /* floating point status register */
72/* 100 */ FPCR fpcr; /* floating point control register */
73/* 104 */ unsigned char fType[8]; /* type of floating point value held in
74 floating point registers. One of none
75 single, double or extended. */
76/* 112 */ int initflag; /* this is special. The kernel guarantees
77 to set it to 0 when a thread is launched,
78 so we can use it to detect whether this
79 instance of the emulator needs to be
80 initialised. */
81} FPA11;
82
83extern void resetFPA11(void);
84extern void SetRoundingMode(const unsigned int);
85extern void SetRoundingPrecision(const unsigned int);
86
87#endif
diff --git a/arch/arm26/nwfpe/fpa11.inl b/arch/arm26/nwfpe/fpa11.inl
deleted file mode 100644
index 1c45cba2de66..000000000000
--- a/arch/arm26/nwfpe/fpa11.inl
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23
24/* Read and write floating point status register */
25extern __inline__ unsigned int readFPSR(void)
26{
27 FPA11 *fpa11 = GET_FPA11();
28 return(fpa11->fpsr);
29}
30
31extern __inline__ void writeFPSR(FPSR reg)
32{
33 FPA11 *fpa11 = GET_FPA11();
34 /* the sysid byte in the status register is readonly */
35 fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
36}
37
38/* Read and write floating point control register */
39extern __inline__ FPCR readFPCR(void)
40{
41 FPA11 *fpa11 = GET_FPA11();
42 /* clear SB, AB and DA bits before returning FPCR */
43 return(fpa11->fpcr & ~MASK_RFC);
44}
45
46extern __inline__ void writeFPCR(FPCR reg)
47{
48 FPA11 *fpa11 = GET_FPA11();
49 fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */
50 fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */
51}
diff --git a/arch/arm26/nwfpe/fpa11_cpdo.c b/arch/arm26/nwfpe/fpa11_cpdo.c
deleted file mode 100644
index 343a6b9fd520..000000000000
--- a/arch/arm26/nwfpe/fpa11_cpdo.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "fpopcode.h"
24
25unsigned int SingleCPDO(const unsigned int opcode);
26unsigned int DoubleCPDO(const unsigned int opcode);
27unsigned int ExtendedCPDO(const unsigned int opcode);
28
29unsigned int EmulateCPDO(const unsigned int opcode)
30{
31 FPA11 *fpa11 = GET_FPA11();
32 unsigned int Fd, nType, nDest, nRc = 1;
33
34 //printk("EmulateCPDO(0x%08x)\n",opcode);
35
36 /* Get the destination size. If not valid let Linux perform
37 an invalid instruction trap. */
38 nDest = getDestinationSize(opcode);
39 if (typeNone == nDest) return 0;
40
41 SetRoundingMode(opcode);
42
43 /* Compare the size of the operands in Fn and Fm.
44 Choose the largest size and perform operations in that size,
45 in order to make use of all the precision of the operands.
46 If Fm is a constant, we just grab a constant of a size
47 matching the size of the operand in Fn. */
48 if (MONADIC_INSTRUCTION(opcode))
49 nType = nDest;
50 else
51 nType = fpa11->fType[getFn(opcode)];
52
53 if (!CONSTANT_FM(opcode))
54 {
55 register unsigned int Fm = getFm(opcode);
56 if (nType < fpa11->fType[Fm])
57 {
58 nType = fpa11->fType[Fm];
59 }
60 }
61
62 switch (nType)
63 {
64 case typeSingle : nRc = SingleCPDO(opcode); break;
65 case typeDouble : nRc = DoubleCPDO(opcode); break;
66 case typeExtended : nRc = ExtendedCPDO(opcode); break;
67 default : nRc = 0;
68 }
69
70 /* If the operation succeeded, check to see if the result in the
71 destination register is the correct size. If not force it
72 to be. */
73 Fd = getFd(opcode);
74 nType = fpa11->fType[Fd];
75 if ((0 != nRc) && (nDest != nType))
76 {
77 switch (nDest)
78 {
79 case typeSingle:
80 {
81 if (typeDouble == nType)
82 fpa11->fpreg[Fd].fSingle =
83 float64_to_float32(fpa11->fpreg[Fd].fDouble);
84 else
85 fpa11->fpreg[Fd].fSingle =
86 floatx80_to_float32(fpa11->fpreg[Fd].fExtended);
87 }
88 break;
89
90 case typeDouble:
91 {
92 if (typeSingle == nType)
93 fpa11->fpreg[Fd].fDouble =
94 float32_to_float64(fpa11->fpreg[Fd].fSingle);
95 else
96 fpa11->fpreg[Fd].fDouble =
97 floatx80_to_float64(fpa11->fpreg[Fd].fExtended);
98 }
99 break;
100
101 case typeExtended:
102 {
103 if (typeSingle == nType)
104 fpa11->fpreg[Fd].fExtended =
105 float32_to_floatx80(fpa11->fpreg[Fd].fSingle);
106 else
107 fpa11->fpreg[Fd].fExtended =
108 float64_to_floatx80(fpa11->fpreg[Fd].fDouble);
109 }
110 break;
111 }
112
113 fpa11->fType[Fd] = nDest;
114 }
115
116 return nRc;
117}
diff --git a/arch/arm26/nwfpe/fpa11_cpdt.c b/arch/arm26/nwfpe/fpa11_cpdt.c
deleted file mode 100644
index e12db7c51a76..000000000000
--- a/arch/arm26/nwfpe/fpa11_cpdt.c
+++ /dev/null
@@ -1,368 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.com, 1998-1999
4 (c) Philip Blundell, 1998
5
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "fpa11.h"
24#include "softfloat.h"
25#include "fpopcode.h"
26#include "fpmodule.h"
27#include "fpmodule.inl"
28
29#include <asm/uaccess.h>
30
31static inline
32void loadSingle(const unsigned int Fn,const unsigned int *pMem)
33{
34 FPA11 *fpa11 = GET_FPA11();
35 fpa11->fType[Fn] = typeSingle;
36 get_user(fpa11->fpreg[Fn].fSingle, pMem);
37}
38
39static inline
40void loadDouble(const unsigned int Fn,const unsigned int *pMem)
41{
42 FPA11 *fpa11 = GET_FPA11();
43 unsigned int *p;
44 p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
45 fpa11->fType[Fn] = typeDouble;
46 get_user(p[0], &pMem[1]);
47 get_user(p[1], &pMem[0]); /* sign & exponent */
48}
49
50static inline
51void loadExtended(const unsigned int Fn,const unsigned int *pMem)
52{
53 FPA11 *fpa11 = GET_FPA11();
54 unsigned int *p;
55 p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
56 fpa11->fType[Fn] = typeExtended;
57 get_user(p[0], &pMem[0]); /* sign & exponent */
58 get_user(p[1], &pMem[2]); /* ls bits */
59 get_user(p[2], &pMem[1]); /* ms bits */
60}
61
62static inline
63void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
64{
65 FPA11 *fpa11 = GET_FPA11();
66 register unsigned int *p;
67 unsigned long x;
68
69 p = (unsigned int*)&(fpa11->fpreg[Fn]);
70 get_user(x, &pMem[0]);
71 fpa11->fType[Fn] = (x >> 14) & 0x00000003;
72
73 switch (fpa11->fType[Fn])
74 {
75 case typeSingle:
76 case typeDouble:
77 {
78 get_user(p[0], &pMem[2]); /* Single */
79 get_user(p[1], &pMem[1]); /* double msw */
80 p[2] = 0; /* empty */
81 }
82 break;
83
84 case typeExtended:
85 {
86 get_user(p[1], &pMem[2]);
87 get_user(p[2], &pMem[1]); /* msw */
88 p[0] = (x & 0x80003fff);
89 }
90 break;
91 }
92}
93
94static inline
95void storeSingle(const unsigned int Fn,unsigned int *pMem)
96{
97 FPA11 *fpa11 = GET_FPA11();
98 union
99 {
100 float32 f;
101 unsigned int i[1];
102 } val;
103
104 switch (fpa11->fType[Fn])
105 {
106 case typeDouble:
107 val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
108 break;
109
110 case typeExtended:
111 val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
112 break;
113
114 default: val.f = fpa11->fpreg[Fn].fSingle;
115 }
116
117 put_user(val.i[0], pMem);
118}
119
120static inline
121void storeDouble(const unsigned int Fn,unsigned int *pMem)
122{
123 FPA11 *fpa11 = GET_FPA11();
124 union
125 {
126 float64 f;
127 unsigned int i[2];
128 } val;
129
130 switch (fpa11->fType[Fn])
131 {
132 case typeSingle:
133 val.f = float32_to_float64(fpa11->fpreg[Fn].fSingle);
134 break;
135
136 case typeExtended:
137 val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
138 break;
139
140 default: val.f = fpa11->fpreg[Fn].fDouble;
141 }
142
143 put_user(val.i[1], &pMem[0]); /* msw */
144 put_user(val.i[0], &pMem[1]); /* lsw */
145}
146
147static inline
148void storeExtended(const unsigned int Fn,unsigned int *pMem)
149{
150 FPA11 *fpa11 = GET_FPA11();
151 union
152 {
153 floatx80 f;
154 unsigned int i[3];
155 } val;
156
157 switch (fpa11->fType[Fn])
158 {
159 case typeSingle:
160 val.f = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
161 break;
162
163 case typeDouble:
164 val.f = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
165 break;
166
167 default: val.f = fpa11->fpreg[Fn].fExtended;
168 }
169
170 put_user(val.i[0], &pMem[0]); /* sign & exp */
171 put_user(val.i[1], &pMem[2]);
172 put_user(val.i[2], &pMem[1]); /* msw */
173}
174
175static inline
176void storeMultiple(const unsigned int Fn,unsigned int *pMem)
177{
178 FPA11 *fpa11 = GET_FPA11();
179 register unsigned int nType, *p;
180
181 p = (unsigned int*)&(fpa11->fpreg[Fn]);
182 nType = fpa11->fType[Fn];
183
184 switch (nType)
185 {
186 case typeSingle:
187 case typeDouble:
188 {
189 put_user(p[0], &pMem[2]); /* single */
190 put_user(p[1], &pMem[1]); /* double msw */
191 put_user(nType << 14, &pMem[0]);
192 }
193 break;
194
195 case typeExtended:
196 {
197 put_user(p[2], &pMem[1]); /* msw */
198 put_user(p[1], &pMem[2]);
199 put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
200 }
201 break;
202 }
203}
204
205unsigned int PerformLDF(const unsigned int opcode)
206{
207 unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
208 write_back = WRITE_BACK(opcode);
209
210 //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
211
212 pBase = (unsigned int*)readRegister(getRn(opcode));
213 if (REG_PC == getRn(opcode))
214 {
215 pBase += 2;
216 write_back = 0;
217 }
218
219 pFinal = pBase;
220 if (BIT_UP_SET(opcode))
221 pFinal += getOffset(opcode);
222 else
223 pFinal -= getOffset(opcode);
224
225 if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
226
227 switch (opcode & MASK_TRANSFER_LENGTH)
228 {
229 case TRANSFER_SINGLE : loadSingle(getFd(opcode),pAddress); break;
230 case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break;
231 case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
232 default: nRc = 0;
233 }
234
235 if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
236 return nRc;
237}
238
239unsigned int PerformSTF(const unsigned int opcode)
240{
241 unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
242 write_back = WRITE_BACK(opcode);
243
244 //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
245 SetRoundingMode(ROUND_TO_NEAREST);
246
247 pBase = (unsigned int*)readRegister(getRn(opcode));
248 if (REG_PC == getRn(opcode))
249 {
250 pBase += 2;
251 write_back = 0;
252 }
253
254 pFinal = pBase;
255 if (BIT_UP_SET(opcode))
256 pFinal += getOffset(opcode);
257 else
258 pFinal -= getOffset(opcode);
259
260 if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
261
262 switch (opcode & MASK_TRANSFER_LENGTH)
263 {
264 case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break;
265 case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break;
266 case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
267 default: nRc = 0;
268 }
269
270 if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
271 return nRc;
272}
273
274unsigned int PerformLFM(const unsigned int opcode)
275{
276 unsigned int i, Fd, *pBase, *pAddress, *pFinal,
277 write_back = WRITE_BACK(opcode);
278
279 pBase = (unsigned int*)readRegister(getRn(opcode));
280 if (REG_PC == getRn(opcode))
281 {
282 pBase += 2;
283 write_back = 0;
284 }
285
286 pFinal = pBase;
287 if (BIT_UP_SET(opcode))
288 pFinal += getOffset(opcode);
289 else
290 pFinal -= getOffset(opcode);
291
292 if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
293
294 Fd = getFd(opcode);
295 for (i=getRegisterCount(opcode);i>0;i--)
296 {
297 loadMultiple(Fd,pAddress);
298 pAddress += 3; Fd++;
299 if (Fd == 8) Fd = 0;
300 }
301
302 if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
303 return 1;
304}
305
306unsigned int PerformSFM(const unsigned int opcode)
307{
308 unsigned int i, Fd, *pBase, *pAddress, *pFinal,
309 write_back = WRITE_BACK(opcode);
310
311 pBase = (unsigned int*)readRegister(getRn(opcode));
312 if (REG_PC == getRn(opcode))
313 {
314 pBase += 2;
315 write_back = 0;
316 }
317
318 pFinal = pBase;
319 if (BIT_UP_SET(opcode))
320 pFinal += getOffset(opcode);
321 else
322 pFinal -= getOffset(opcode);
323
324 if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
325
326 Fd = getFd(opcode);
327 for (i=getRegisterCount(opcode);i>0;i--)
328 {
329 storeMultiple(Fd,pAddress);
330 pAddress += 3; Fd++;
331 if (Fd == 8) Fd = 0;
332 }
333
334 if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
335 return 1;
336}
337
338#if 1
339unsigned int EmulateCPDT(const unsigned int opcode)
340{
341 unsigned int nRc = 0;
342
343 //printk("EmulateCPDT(0x%08x)\n",opcode);
344
345 if (LDF_OP(opcode))
346 {
347 nRc = PerformLDF(opcode);
348 }
349 else if (LFM_OP(opcode))
350 {
351 nRc = PerformLFM(opcode);
352 }
353 else if (STF_OP(opcode))
354 {
355 nRc = PerformSTF(opcode);
356 }
357 else if (SFM_OP(opcode))
358 {
359 nRc = PerformSFM(opcode);
360 }
361 else
362 {
363 nRc = 0;
364 }
365
366 return nRc;
367}
368#endif
diff --git a/arch/arm26/nwfpe/fpa11_cprt.c b/arch/arm26/nwfpe/fpa11_cprt.c
deleted file mode 100644
index a201076c1f14..000000000000
--- a/arch/arm26/nwfpe/fpa11_cprt.c
+++ /dev/null
@@ -1,289 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4 (c) Philip Blundell, 1999
5
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "fpa11.h"
24#include "milieu.h"
25#include "softfloat.h"
26#include "fpopcode.h"
27#include "fpa11.inl"
28#include "fpmodule.h"
29#include "fpmodule.inl"
30
31extern flag floatx80_is_nan(floatx80);
32extern flag float64_is_nan( float64);
33extern flag float32_is_nan( float32);
34
35void SetRoundingMode(const unsigned int opcode);
36
37unsigned int PerformFLT(const unsigned int opcode);
38unsigned int PerformFIX(const unsigned int opcode);
39
40static unsigned int
41PerformComparison(const unsigned int opcode);
42
43unsigned int EmulateCPRT(const unsigned int opcode)
44{
45 unsigned int nRc = 1;
46
47 //printk("EmulateCPRT(0x%08x)\n",opcode);
48
49 if (opcode & 0x800000)
50 {
51 /* This is some variant of a comparison (PerformComparison will
52 sort out which one). Since most of the other CPRT
53 instructions are oddball cases of some sort or other it makes
54 sense to pull this out into a fast path. */
55 return PerformComparison(opcode);
56 }
57
58 /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
59 switch ((opcode & 0x700000) >> 20)
60 {
61 case FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
62 case FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
63
64 case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
65 case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
66
67#if 0 /* We currently have no use for the FPCR, so there's no point
68 in emulating it. */
69 case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
70 case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
71#endif
72
73 default: nRc = 0;
74 }
75
76 return nRc;
77}
78
79unsigned int PerformFLT(const unsigned int opcode)
80{
81 FPA11 *fpa11 = GET_FPA11();
82
83 unsigned int nRc = 1;
84 SetRoundingMode(opcode);
85
86 switch (opcode & MASK_ROUNDING_PRECISION)
87 {
88 case ROUND_SINGLE:
89 {
90 fpa11->fType[getFn(opcode)] = typeSingle;
91 fpa11->fpreg[getFn(opcode)].fSingle =
92 int32_to_float32(readRegister(getRd(opcode)));
93 }
94 break;
95
96 case ROUND_DOUBLE:
97 {
98 fpa11->fType[getFn(opcode)] = typeDouble;
99 fpa11->fpreg[getFn(opcode)].fDouble =
100 int32_to_float64(readRegister(getRd(opcode)));
101 }
102 break;
103
104 case ROUND_EXTENDED:
105 {
106 fpa11->fType[getFn(opcode)] = typeExtended;
107 fpa11->fpreg[getFn(opcode)].fExtended =
108 int32_to_floatx80(readRegister(getRd(opcode)));
109 }
110 break;
111
112 default: nRc = 0;
113 }
114
115 return nRc;
116}
117
118unsigned int PerformFIX(const unsigned int opcode)
119{
120 FPA11 *fpa11 = GET_FPA11();
121 unsigned int nRc = 1;
122 unsigned int Fn = getFm(opcode);
123
124 SetRoundingMode(opcode);
125
126 switch (fpa11->fType[Fn])
127 {
128 case typeSingle:
129 {
130 writeRegister(getRd(opcode),
131 float32_to_int32(fpa11->fpreg[Fn].fSingle));
132 }
133 break;
134
135 case typeDouble:
136 {
137 writeRegister(getRd(opcode),
138 float64_to_int32(fpa11->fpreg[Fn].fDouble));
139 }
140 break;
141
142 case typeExtended:
143 {
144 writeRegister(getRd(opcode),
145 floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
146 }
147 break;
148
149 default: nRc = 0;
150 }
151
152 return nRc;
153}
154
155
156static unsigned int __inline__
157PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
158{
159 unsigned int flags = 0;
160
161 /* test for less than condition */
162 if (floatx80_lt(Fn,Fm))
163 {
164 flags |= CC_NEGATIVE;
165 }
166
167 /* test for equal condition */
168 if (floatx80_eq(Fn,Fm))
169 {
170 flags |= CC_ZERO;
171 }
172
173 /* test for greater than or equal condition */
174 if (floatx80_lt(Fm,Fn))
175 {
176 flags |= CC_CARRY;
177 }
178
179 writeConditionCodes(flags);
180 return 1;
181}
182
183/* This instruction sets the flags N, Z, C, V in the FPSR. */
184
185static unsigned int PerformComparison(const unsigned int opcode)
186{
187 FPA11 *fpa11 = GET_FPA11();
188 unsigned int Fn, Fm;
189 floatx80 rFn, rFm;
190 int e_flag = opcode & 0x400000; /* 1 if CxFE */
191 int n_flag = opcode & 0x200000; /* 1 if CNxx */
192 unsigned int flags = 0;
193
194 //printk("PerformComparison(0x%08x)\n",opcode);
195
196 Fn = getFn(opcode);
197 Fm = getFm(opcode);
198
199 /* Check for unordered condition and convert all operands to 80-bit
200 format.
201 ?? Might be some mileage in avoiding this conversion if possible.
202 Eg, if both operands are 32-bit, detect this and do a 32-bit
203 comparison (cheaper than an 80-bit one). */
204 switch (fpa11->fType[Fn])
205 {
206 case typeSingle:
207 //printk("single.\n");
208 if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
209 goto unordered;
210 rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
211 break;
212
213 case typeDouble:
214 //printk("double.\n");
215 if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
216 goto unordered;
217 rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
218 break;
219
220 case typeExtended:
221 //printk("extended.\n");
222 if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
223 goto unordered;
224 rFn = fpa11->fpreg[Fn].fExtended;
225 break;
226
227 default: return 0;
228 }
229
230 if (CONSTANT_FM(opcode))
231 {
232 //printk("Fm is a constant: #%d.\n",Fm);
233 rFm = getExtendedConstant(Fm);
234 if (floatx80_is_nan(rFm))
235 goto unordered;
236 }
237 else
238 {
239 //printk("Fm = r%d which contains a ",Fm);
240 switch (fpa11->fType[Fm])
241 {
242 case typeSingle:
243 //printk("single.\n");
244 if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
245 goto unordered;
246 rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
247 break;
248
249 case typeDouble:
250 //printk("double.\n");
251 if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
252 goto unordered;
253 rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
254 break;
255
256 case typeExtended:
257 //printk("extended.\n");
258 if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
259 goto unordered;
260 rFm = fpa11->fpreg[Fm].fExtended;
261 break;
262
263 default: return 0;
264 }
265 }
266
267 if (n_flag)
268 {
269 rFm.high ^= 0x8000;
270 }
271
272 return PerformComparisonOperation(rFn,rFm);
273
274 unordered:
275 /* ?? The FPA data sheet is pretty vague about this, in particular
276 about whether the non-E comparisons can ever raise exceptions.
277 This implementation is based on a combination of what it says in
278 the data sheet, observation of how the Acorn emulator actually
279 behaves (and how programs expect it to) and guesswork. */
280 flags |= CC_OVERFLOW;
281 flags &= ~(CC_ZERO | CC_NEGATIVE);
282
283 if (BIT_AC & readFPSR()) flags |= CC_CARRY;
284
285 if (e_flag) float_raise(float_flag_invalid);
286
287 writeConditionCodes(flags);
288 return 1;
289}
diff --git a/arch/arm26/nwfpe/fpmodule.c b/arch/arm26/nwfpe/fpmodule.c
deleted file mode 100644
index a8fad92eb44f..000000000000
--- a/arch/arm26/nwfpe/fpmodule.c
+++ /dev/null
@@ -1,180 +0,0 @@
1
2/*
3 NetWinder Floating Point Emulator
4 (c) Rebel.com, 1998-1999
5 (c) Philip Blundell, 1998-1999
6
7 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include "fpa11.h"
25
26#include <linux/module.h>
27#include <linux/version.h>
28
29/* XXX */
30#include <linux/errno.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/init.h>
36/* XXX */
37
38#include "softfloat.h"
39#include "fpopcode.h"
40#include "fpmodule.h"
41#include "fpa11.inl"
42
43/* kernel symbols required for signal handling */
44typedef struct task_struct* PTASK;
45
46#ifdef MODULE
47void fp_send_sig(unsigned long sig, PTASK p, int priv);
48
49MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
50MODULE_DESCRIPTION("NWFPE floating point emulator");
51
52#else
53#define fp_send_sig send_sig
54#define kern_fp_enter fp_enter
55
56extern char fpe_type[];
57#endif
58
59/* kernel function prototypes required */
60void fp_setup(void);
61
62/* external declarations for saved kernel symbols */
63extern void (*kern_fp_enter)(void);
64
65/* Original value of fp_enter from kernel before patched by fpe_init. */
66static void (*orig_fp_enter)(void);
67
68/* forward declarations */
69extern void nwfpe_enter(void);
70
71#ifdef MODULE
72/*
73 * Return 0 if we can be unloaded. This can only happen if
74 * kern_fp_enter is still pointing at nwfpe_enter
75 */
76static int fpe_unload(void)
77{
78 return (kern_fp_enter == nwfpe_enter) ? 0 : 1;
79}
80#endif
81
82static int __init fpe_init(void)
83{
84 if (sizeof(FPA11) > sizeof(union fp_state)) {
85 printk(KERN_ERR "nwfpe: bad structure size\n");
86 return -EINVAL;
87 }
88
89 if (sizeof(FPREG) != 12) {
90 printk(KERN_ERR "nwfpe: bad register size\n");
91 return -EINVAL;
92 }
93
94#ifdef MODULE
95 if (!mod_member_present(&__this_module, can_unload))
96 return -EINVAL;
97 __this_module.can_unload = fpe_unload;
98#else
99 if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
100 return 0;
101#endif
102
103 /* Display title, version and copyright information. */
104 printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 "
105 "(c) 1998-1999 Rebel.com\n");
106
107 /* Save pointer to the old FP handler and then patch ourselves in */
108 orig_fp_enter = kern_fp_enter;
109 kern_fp_enter = nwfpe_enter;
110
111 return 0;
112}
113
114static void __exit fpe_exit(void)
115{
116 /* Restore the values we saved earlier. */
117 kern_fp_enter = orig_fp_enter;
118}
119
120/*
121ScottB: November 4, 1998
122
123Moved this function out of softfloat-specialize into fpmodule.c.
124This effectively isolates all the changes required for integrating with the
125Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying
126fpmodule.c to integrate with the NetBSD kernel (I hope!).
127
128[1/1/99: Not quite true any more unfortunately. There is Linux-specific
129code to access data in user space in some other source files at the
130moment (grep for get_user / put_user calls). --philb]
131
132float_exception_flags is a global variable in SoftFloat.
133
134This function is called by the SoftFloat routines to raise a floating
135point exception. We check the trap enable byte in the FPSR, and raise
136a SIGFPE exception if necessary. If not the relevant bits in the
137cumulative exceptions flag byte are set and we return.
138*/
139
140void float_raise(signed char flags)
141{
142 register unsigned int fpsr, cumulativeTraps;
143
144#ifdef CONFIG_DEBUG_USER
145 printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
146 current->comm, current->pid, flags,
147 __builtin_return_address(0), GET_USERREG()[15]);
148#endif
149
150 /* Keep SoftFloat exception flags up to date. */
151 float_exception_flags |= flags;
152
153 /* Read fpsr and initialize the cumulativeTraps. */
154 fpsr = readFPSR();
155 cumulativeTraps = 0;
156
157 /* For each type of exception, the cumulative trap exception bit is only
158 set if the corresponding trap enable bit is not set. */
159 if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
160 cumulativeTraps |= BIT_IXC;
161 if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
162 cumulativeTraps |= BIT_UFC;
163 if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
164 cumulativeTraps |= BIT_OFC;
165 if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
166 cumulativeTraps |= BIT_DZC;
167 if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
168 cumulativeTraps |= BIT_IOC;
169
170 /* Set the cumulative exceptions flags. */
171 if (cumulativeTraps)
172 writeFPSR(fpsr | cumulativeTraps);
173
174 /* Raise an exception if necessary. */
175 if (fpsr & (flags << 16))
176 fp_send_sig(SIGFPE, current, 1);
177}
178
179module_init(fpe_init);
180module_exit(fpe_exit);
diff --git a/arch/arm26/nwfpe/fpmodule.h b/arch/arm26/nwfpe/fpmodule.h
deleted file mode 100644
index f971ddd60cc1..000000000000
--- a/arch/arm26/nwfpe/fpmodule.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.com, 1998-1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __FPMODULE_H__
23#define __FPMODULE_H__
24
25
26#define REG_ORIG_R0 16
27#define REG_CPSR 15
28#define REG_PC 15
29#define REG_LR 14
30#define REG_SP 13
31#define REG_IP 12
32#define REG_FP 11
33#define REG_R10 10
34#define REG_R9 9
35#define REG_R9 9
36#define REG_R8 8
37#define REG_R7 7
38#define REG_R6 6
39#define REG_R5 5
40#define REG_R4 4
41#define REG_R3 3
42#define REG_R2 2
43#define REG_R1 1
44#define REG_R0 0
45
46#endif
diff --git a/arch/arm26/nwfpe/fpmodule.inl b/arch/arm26/nwfpe/fpmodule.inl
deleted file mode 100644
index ef228378ffaf..000000000000
--- a/arch/arm26/nwfpe/fpmodule.inl
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22extern __inline__
23unsigned int readRegister(const unsigned int nReg)
24{
25 /* Note: The CPU thinks it has dealt with the current instruction. As
26 a result the program counter has been advanced to the next
27 instruction, and points 4 bytes beyond the actual instruction
28 that caused the invalid instruction trap to occur. We adjust
29 for this in this routine. LDF/STF instructions with Rn = PC
30 depend on the PC being correct, as they use PC+8 in their
31 address calculations. */
32 unsigned int *userRegisters = GET_USERREG();
33 unsigned int val = userRegisters[nReg];
34 if (REG_PC == nReg) val -= 4;
35 return val;
36}
37
38extern __inline__
39void writeRegister(const unsigned int nReg, const unsigned int val)
40{
41 unsigned int *userRegisters = GET_USERREG();
42 userRegisters[nReg] = val;
43}
44
45extern __inline__
46unsigned int readCPSR(void)
47{
48 return(readRegister(REG_CPSR));
49}
50
51extern __inline__
52void writeCPSR(const unsigned int val)
53{
54 writeRegister(REG_CPSR,val);
55}
56
57extern __inline__
58unsigned int readConditionCodes(void)
59{
60#ifdef __FPEM_TEST__
61 return(0);
62#else
63 return(readCPSR() & CC_MASK);
64#endif
65}
66
67extern __inline__
68void writeConditionCodes(const unsigned int val)
69{
70 unsigned int *userRegisters = GET_USERREG();
71 unsigned int rval;
72 /*
73 * Operate directly on userRegisters since
74 * the CPSR may be the PC register itself.
75 */
76 rval = userRegisters[REG_CPSR] & ~CC_MASK;
77 userRegisters[REG_CPSR] = rval | (val & CC_MASK);
78}
79
80extern __inline__
81unsigned int readMemoryInt(unsigned int *pMem)
82{
83 return *pMem;
84}
diff --git a/arch/arm26/nwfpe/fpopcode.c b/arch/arm26/nwfpe/fpopcode.c
deleted file mode 100644
index d81ddd188322..000000000000
--- a/arch/arm26/nwfpe/fpopcode.c
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "softfloat.h"
24#include "fpopcode.h"
25#include "fpsr.h"
26#include "fpmodule.h"
27#include "fpmodule.inl"
28
29const floatx80 floatx80Constant[] = {
30 { 0x0000, 0x0000000000000000ULL}, /* extended 0.0 */
31 { 0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */
32 { 0x4000, 0x8000000000000000ULL}, /* extended 2.0 */
33 { 0x4000, 0xc000000000000000ULL}, /* extended 3.0 */
34 { 0x4001, 0x8000000000000000ULL}, /* extended 4.0 */
35 { 0x4001, 0xa000000000000000ULL}, /* extended 5.0 */
36 { 0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */
37 { 0x4002, 0xa000000000000000ULL} /* extended 10.0 */
38};
39
40const float64 float64Constant[] = {
41 0x0000000000000000ULL, /* double 0.0 */
42 0x3ff0000000000000ULL, /* double 1.0 */
43 0x4000000000000000ULL, /* double 2.0 */
44 0x4008000000000000ULL, /* double 3.0 */
45 0x4010000000000000ULL, /* double 4.0 */
46 0x4014000000000000ULL, /* double 5.0 */
47 0x3fe0000000000000ULL, /* double 0.5 */
48 0x4024000000000000ULL /* double 10.0 */
49};
50
51const float32 float32Constant[] = {
52 0x00000000, /* single 0.0 */
53 0x3f800000, /* single 1.0 */
54 0x40000000, /* single 2.0 */
55 0x40400000, /* single 3.0 */
56 0x40800000, /* single 4.0 */
57 0x40a00000, /* single 5.0 */
58 0x3f000000, /* single 0.5 */
59 0x41200000 /* single 10.0 */
60};
61
62unsigned int getTransferLength(const unsigned int opcode)
63{
64 unsigned int nRc;
65
66 switch (opcode & MASK_TRANSFER_LENGTH)
67 {
68 case 0x00000000: nRc = 1; break; /* single precision */
69 case 0x00008000: nRc = 2; break; /* double precision */
70 case 0x00400000: nRc = 3; break; /* extended precision */
71 default: nRc = 0;
72 }
73
74 return(nRc);
75}
76
77unsigned int getRegisterCount(const unsigned int opcode)
78{
79 unsigned int nRc;
80
81 switch (opcode & MASK_REGISTER_COUNT)
82 {
83 case 0x00000000: nRc = 4; break;
84 case 0x00008000: nRc = 1; break;
85 case 0x00400000: nRc = 2; break;
86 case 0x00408000: nRc = 3; break;
87 default: nRc = 0;
88 }
89
90 return(nRc);
91}
92
93unsigned int getRoundingPrecision(const unsigned int opcode)
94{
95 unsigned int nRc;
96
97 switch (opcode & MASK_ROUNDING_PRECISION)
98 {
99 case 0x00000000: nRc = 1; break;
100 case 0x00000080: nRc = 2; break;
101 case 0x00080000: nRc = 3; break;
102 default: nRc = 0;
103 }
104
105 return(nRc);
106}
107
108unsigned int getDestinationSize(const unsigned int opcode)
109{
110 unsigned int nRc;
111
112 switch (opcode & MASK_DESTINATION_SIZE)
113 {
114 case 0x00000000: nRc = typeSingle; break;
115 case 0x00000080: nRc = typeDouble; break;
116 case 0x00080000: nRc = typeExtended; break;
117 default: nRc = typeNone;
118 }
119
120 return(nRc);
121}
122
123/* condition code lookup table
124 index into the table is test code: EQ, NE, ... LT, GT, AL, NV
125 bit position in short is condition code: NZCV */
126static const unsigned short aCC[16] = {
127 0xF0F0, // EQ == Z set
128 0x0F0F, // NE
129 0xCCCC, // CS == C set
130 0x3333, // CC
131 0xFF00, // MI == N set
132 0x00FF, // PL
133 0xAAAA, // VS == V set
134 0x5555, // VC
135 0x0C0C, // HI == C set && Z clear
136 0xF3F3, // LS == C clear || Z set
137 0xAA55, // GE == (N==V)
138 0x55AA, // LT == (N!=V)
139 0x0A05, // GT == (!Z && (N==V))
140 0xF5FA, // LE == (Z || (N!=V))
141 0xFFFF, // AL always
142 0 // NV
143};
144
145unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
146{
147 return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
148}
diff --git a/arch/arm26/nwfpe/fpopcode.h b/arch/arm26/nwfpe/fpopcode.h
deleted file mode 100644
index 13c7419262ab..000000000000
--- a/arch/arm26/nwfpe/fpopcode.h
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __FPOPCODE_H__
23#define __FPOPCODE_H__
24
25/*
26ARM Floating Point Instruction Classes
27| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
28|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT
29|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT
30| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
31|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO
32|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT
33|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons
34| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
35
36CPDT data transfer instructions
37 LDF, STF, LFM, SFM
38
39CPDO dyadic arithmetic instructions
40 ADF, MUF, SUF, RSF, DVF, RDF,
41 POW, RPW, RMF, FML, FDV, FRD, POL
42
43CPDO monadic arithmetic instructions
44 MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
45 SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
46
47CPRT joint arithmetic/data transfer instructions
48 FIX (arithmetic followed by load/store)
49 FLT (load/store followed by arithmetic)
50 CMF, CNF CMFE, CNFE (comparisons)
51 WFS, RFS (write/read floating point status register)
52 WFC, RFC (write/read floating point control register)
53
54cond condition codes
55P pre/post index bit: 0 = postindex, 1 = preindex
56U up/down bit: 0 = stack grows down, 1 = stack grows up
57W write back bit: 1 = update base register (Rn)
58L load/store bit: 0 = store, 1 = load
59Rn base register
60Rd destination/source register
61Fd floating point destination register
62Fn floating point source register
63Fm floating point source register or floating point constant
64
65uv transfer length (TABLE 1)
66wx register count (TABLE 2)
67abcd arithmetic opcode (TABLES 3 & 4)
68ef destination size (rounding precision) (TABLE 5)
69gh rounding mode (TABLE 6)
70j dyadic/monadic bit: 0 = dyadic, 1 = monadic
71i constant bit: 1 = constant (TABLE 6)
72*/
73
74/*
75TABLE 1
76+-------------------------+---+---+---------+---------+
77| Precision | u | v | FPSR.EP | length |
78+-------------------------+---+---+---------+---------+
79| Single | 0 � 0 | x | 1 words |
80| Double | 1 � 1 | x | 2 words |
81| Extended | 1 � 1 | x | 3 words |
82| Packed decimal | 1 � 1 | 0 | 3 words |
83| Expanded packed decimal | 1 � 1 | 1 | 4 words |
84+-------------------------+---+---+---------+---------+
85Note: x = don't care
86*/
87
88/*
89TABLE 2
90+---+---+---------------------------------+
91| w | x | Number of registers to transfer |
92+---+---+---------------------------------+
93| 0 � 1 | 1 |
94| 1 � 0 | 2 |
95| 1 � 1 | 3 |
96| 0 � 0 | 4 |
97+---+---+---------------------------------+
98*/
99
100/*
101TABLE 3: Dyadic Floating Point Opcodes
102+---+---+---+---+----------+-----------------------+-----------------------+
103| a | b | c | d | Mnemonic | Description | Operation |
104+---+---+---+---+----------+-----------------------+-----------------------+
105| 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm |
106| 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm |
107| 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm |
108| 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn |
109| 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm |
110| 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn |
111| 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm |
112| 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn |
113| 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) |
114| 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm |
115| 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm |
116| 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn |
117| 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) |
118| 1 | 1 | 0 | 1 | | undefined instruction | trap |
119| 1 | 1 | 1 | 0 | | undefined instruction | trap |
120| 1 | 1 | 1 | 1 | | undefined instruction | trap |
121+---+---+---+---+----------+-----------------------+-----------------------+
122Note: POW, RPW, POL are deprecated, and are available for backwards
123 compatibility only.
124*/
125
126/*
127TABLE 4: Monadic Floating Point Opcodes
128+---+---+---+---+----------+-----------------------+-----------------------+
129| a | b | c | d | Mnemonic | Description | Operation |
130+---+---+---+---+----------+-----------------------+-----------------------+
131| 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm |
132| 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm |
133| 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) |
134| 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) |
135| 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) |
136| 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) |
137| 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) |
138| 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm |
139| 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) |
140| 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) |
141| 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) |
142| 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) |
143| 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) |
144| 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) |
145| 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) |
146| 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) |
147+---+---+---+---+----------+-----------------------+-----------------------+
148Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
149 available for backwards compatibility only.
150*/
151
152/*
153TABLE 5
154+-------------------------+---+---+
155| Rounding Precision | e | f |
156+-------------------------+---+---+
157| IEEE Single precision | 0 � 0 |
158| IEEE Double precision | 0 � 1 |
159| IEEE Extended precision | 1 � 0 |
160| undefined (trap) | 1 � 1 |
161+-------------------------+---+---+
162*/
163
164/*
165TABLE 5
166+---------------------------------+---+---+
167| Rounding Mode | g | h |
168+---------------------------------+---+---+
169| Round to nearest (default) | 0 � 0 |
170| Round toward plus infinity | 0 � 1 |
171| Round toward negative infinity | 1 � 0 |
172| Round toward zero | 1 � 1 |
173+---------------------------------+---+---+
174*/
175
176/*
177===
178=== Definitions for load and store instructions
179===
180*/
181
182/* bit masks */
183#define BIT_PREINDEX 0x01000000
184#define BIT_UP 0x00800000
185#define BIT_WRITE_BACK 0x00200000
186#define BIT_LOAD 0x00100000
187
188/* masks for load/store */
189#define MASK_CPDT 0x0c000000 /* data processing opcode */
190#define MASK_OFFSET 0x000000ff
191#define MASK_TRANSFER_LENGTH 0x00408000
192#define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH
193#define MASK_COPROCESSOR 0x00000f00
194
195/* Tests for transfer length */
196#define TRANSFER_SINGLE 0x00000000
197#define TRANSFER_DOUBLE 0x00008000
198#define TRANSFER_EXTENDED 0x00400000
199#define TRANSFER_PACKED MASK_TRANSFER_LENGTH
200
201/* Get the coprocessor number from the opcode. */
202#define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8)
203
204/* Get the offset from the opcode. */
205#define getOffset(opcode) (opcode & MASK_OFFSET)
206
207/* Tests for specific data transfer load/store opcodes. */
208#define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask))
209
210#define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
211#define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
212
213#define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
214#define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
215#define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
216#define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
217
218#define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0)
219#define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0)
220#define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0)
221#define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0)
222#define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0)
223#define LOAD(opcode) ((opcode & BIT_LOAD) != 0)
224#define STORE(opcode) ((opcode & BIT_LOAD) == 0)
225
226/*
227===
228=== Definitions for arithmetic instructions
229===
230*/
231/* bit masks */
232#define BIT_MONADIC 0x00008000
233#define BIT_CONSTANT 0x00000008
234
235#define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0)
236#define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0)
237
238/* instruction identification masks */
239#define MASK_CPDO 0x0e000000 /* arithmetic opcode */
240#define MASK_ARITHMETIC_OPCODE 0x00f08000
241#define MASK_DESTINATION_SIZE 0x00080080
242
243/* dyadic arithmetic opcodes. */
244#define ADF_CODE 0x00000000
245#define MUF_CODE 0x00100000
246#define SUF_CODE 0x00200000
247#define RSF_CODE 0x00300000
248#define DVF_CODE 0x00400000
249#define RDF_CODE 0x00500000
250#define POW_CODE 0x00600000
251#define RPW_CODE 0x00700000
252#define RMF_CODE 0x00800000
253#define FML_CODE 0x00900000
254#define FDV_CODE 0x00a00000
255#define FRD_CODE 0x00b00000
256#define POL_CODE 0x00c00000
257/* 0x00d00000 is an invalid dyadic arithmetic opcode */
258/* 0x00e00000 is an invalid dyadic arithmetic opcode */
259/* 0x00f00000 is an invalid dyadic arithmetic opcode */
260
261/* monadic arithmetic opcodes. */
262#define MVF_CODE 0x00008000
263#define MNF_CODE 0x00108000
264#define ABS_CODE 0x00208000
265#define RND_CODE 0x00308000
266#define SQT_CODE 0x00408000
267#define LOG_CODE 0x00508000
268#define LGN_CODE 0x00608000
269#define EXP_CODE 0x00708000
270#define SIN_CODE 0x00808000
271#define COS_CODE 0x00908000
272#define TAN_CODE 0x00a08000
273#define ASN_CODE 0x00b08000
274#define ACS_CODE 0x00c08000
275#define ATN_CODE 0x00d08000
276#define URD_CODE 0x00e08000
277#define NRM_CODE 0x00f08000
278
279/*
280===
281=== Definitions for register transfer and comparison instructions
282===
283*/
284
285#define MASK_CPRT 0x0e000010 /* register transfer opcode */
286#define MASK_CPRT_CODE 0x00f00000
287#define FLT_CODE 0x00000000
288#define FIX_CODE 0x00100000
289#define WFS_CODE 0x00200000
290#define RFS_CODE 0x00300000
291#define WFC_CODE 0x00400000
292#define RFC_CODE 0x00500000
293#define CMF_CODE 0x00900000
294#define CNF_CODE 0x00b00000
295#define CMFE_CODE 0x00d00000
296#define CNFE_CODE 0x00f00000
297
298/*
299===
300=== Common definitions
301===
302*/
303
304/* register masks */
305#define MASK_Rd 0x0000f000
306#define MASK_Rn 0x000f0000
307#define MASK_Fd 0x00007000
308#define MASK_Fm 0x00000007
309#define MASK_Fn 0x00070000
310
311/* condition code masks */
312#define CC_MASK 0xf0000000
313#define CC_NEGATIVE 0x80000000
314#define CC_ZERO 0x40000000
315#define CC_CARRY 0x20000000
316#define CC_OVERFLOW 0x10000000
317#define CC_EQ 0x00000000
318#define CC_NE 0x10000000
319#define CC_CS 0x20000000
320#define CC_HS CC_CS
321#define CC_CC 0x30000000
322#define CC_LO CC_CC
323#define CC_MI 0x40000000
324#define CC_PL 0x50000000
325#define CC_VS 0x60000000
326#define CC_VC 0x70000000
327#define CC_HI 0x80000000
328#define CC_LS 0x90000000
329#define CC_GE 0xa0000000
330#define CC_LT 0xb0000000
331#define CC_GT 0xc0000000
332#define CC_LE 0xd0000000
333#define CC_AL 0xe0000000
334#define CC_NV 0xf0000000
335
336/* rounding masks/values */
337#define MASK_ROUNDING_MODE 0x00000060
338#define ROUND_TO_NEAREST 0x00000000
339#define ROUND_TO_PLUS_INFINITY 0x00000020
340#define ROUND_TO_MINUS_INFINITY 0x00000040
341#define ROUND_TO_ZERO 0x00000060
342
343#define MASK_ROUNDING_PRECISION 0x00080080
344#define ROUND_SINGLE 0x00000000
345#define ROUND_DOUBLE 0x00000080
346#define ROUND_EXTENDED 0x00080000
347
348/* Get the condition code from the opcode. */
349#define getCondition(opcode) (opcode >> 28)
350
351/* Get the source register from the opcode. */
352#define getRn(opcode) ((opcode & MASK_Rn) >> 16)
353
354/* Get the destination floating point register from the opcode. */
355#define getFd(opcode) ((opcode & MASK_Fd) >> 12)
356
357/* Get the first source floating point register from the opcode. */
358#define getFn(opcode) ((opcode & MASK_Fn) >> 16)
359
360/* Get the second source floating point register from the opcode. */
361#define getFm(opcode) (opcode & MASK_Fm)
362
363/* Get the destination register from the opcode. */
364#define getRd(opcode) ((opcode & MASK_Rd) >> 12)
365
366/* Get the rounding mode from the opcode. */
367#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5)
368
369static inline const floatx80 getExtendedConstant(const unsigned int nIndex)
370{
371 extern const floatx80 floatx80Constant[];
372 return floatx80Constant[nIndex];
373}
374
375static inline const float64 getDoubleConstant(const unsigned int nIndex)
376{
377 extern const float64 float64Constant[];
378 return float64Constant[nIndex];
379}
380
381static inline const float32 getSingleConstant(const unsigned int nIndex)
382{
383 extern const float32 float32Constant[];
384 return float32Constant[nIndex];
385}
386
387extern unsigned int getRegisterCount(const unsigned int opcode);
388extern unsigned int getDestinationSize(const unsigned int opcode);
389
390#endif
diff --git a/arch/arm26/nwfpe/fpsr.h b/arch/arm26/nwfpe/fpsr.h
deleted file mode 100644
index 6dafb0f5243c..000000000000
--- a/arch/arm26/nwfpe/fpsr.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.com, 1998-1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __FPSR_H__
23#define __FPSR_H__
24
25/*
26The FPSR is a 32 bit register consisting of 4 parts, each exactly
27one byte.
28
29 SYSTEM ID
30 EXCEPTION TRAP ENABLE BYTE
31 SYSTEM CONTROL BYTE
32 CUMULATIVE EXCEPTION FLAGS BYTE
33
34The FPCR is a 32 bit register consisting of bit flags.
35*/
36
37/* SYSTEM ID
38------------
39Note: the system id byte is read only */
40
41typedef unsigned int FPSR; /* type for floating point status register */
42typedef unsigned int FPCR; /* type for floating point control register */
43
44#define MASK_SYSID 0xff000000
45#define BIT_HARDWARE 0x80000000
46#define FP_EMULATOR 0x01000000 /* System ID for emulator */
47#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */
48
49/* EXCEPTION TRAP ENABLE BYTE
50----------------------------- */
51
52#define MASK_TRAP_ENABLE 0x00ff0000
53#define MASK_TRAP_ENABLE_STRICT 0x001f0000
54#define BIT_IXE 0x00100000 /* inexact exception enable */
55#define BIT_UFE 0x00080000 /* underflow exception enable */
56#define BIT_OFE 0x00040000 /* overflow exception enable */
57#define BIT_DZE 0x00020000 /* divide by zero exception enable */
58#define BIT_IOE 0x00010000 /* invalid operation exception enable */
59
60/* SYSTEM CONTROL BYTE
61---------------------- */
62
63#define MASK_SYSTEM_CONTROL 0x0000ff00
64#define MASK_TRAP_STRICT 0x00001f00
65
66#define BIT_AC 0x00001000 /* use alternative C-flag definition
67 for compares */
68#define BIT_EP 0x00000800 /* use expanded packed decimal format */
69#define BIT_SO 0x00000400 /* select synchronous operation of FPA */
70#define BIT_NE 0x00000200 /* NaN exception bit */
71#define BIT_ND 0x00000100 /* no denormalized numbers bit */
72
73/* CUMULATIVE EXCEPTION FLAGS BYTE
74---------------------------------- */
75
76#define MASK_EXCEPTION_FLAGS 0x000000ff
77#define MASK_EXCEPTION_FLAGS_STRICT 0x0000001f
78
79#define BIT_IXC 0x00000010 /* inexact exception flag */
80#define BIT_UFC 0x00000008 /* underflow exception flag */
81#define BIT_OFC 0x00000004 /* overfloat exception flag */
82#define BIT_DZC 0x00000002 /* divide by zero exception flag */
83#define BIT_IOC 0x00000001 /* invalid operation exception flag */
84
85/* Floating Point Control Register
86----------------------------------*/
87
88#define BIT_RU 0x80000000 /* rounded up bit */
89#define BIT_IE 0x10000000 /* inexact bit */
90#define BIT_MO 0x08000000 /* mantissa overflow bit */
91#define BIT_EO 0x04000000 /* exponent overflow bit */
92#define BIT_SB 0x00000800 /* store bounce */
93#define BIT_AB 0x00000400 /* arithmetic bounce */
94#define BIT_RE 0x00000200 /* rounding exception */
95#define BIT_DA 0x00000100 /* disable FPA */
96
97#define MASK_OP 0x00f08010 /* AU operation code */
98#define MASK_PR 0x00080080 /* AU precision */
99#define MASK_S1 0x00070000 /* AU source register 1 */
100#define MASK_S2 0x00000007 /* AU source register 2 */
101#define MASK_DS 0x00007000 /* AU destination register */
102#define MASK_RM 0x00000060 /* AU rounding mode */
103#define MASK_ALU 0x9cfff2ff /* only ALU can write these bits */
104#define MASK_RESET 0x00000d00 /* bits set on reset, all others cleared */
105#define MASK_WFC MASK_RESET
106#define MASK_RFC ~MASK_RESET
107
108#endif
diff --git a/arch/arm26/nwfpe/milieu.h b/arch/arm26/nwfpe/milieu.h
deleted file mode 100644
index a3892ab2dca4..000000000000
--- a/arch/arm26/nwfpe/milieu.h
+++ /dev/null
@@ -1,48 +0,0 @@
1
2/*
3===============================================================================
4
5This C header file is part of the SoftFloat IEC/IEEE Floating-point
6Arithmetic Package, Release 2.
7
8Written by John R. Hauser. This work was made possible in part by the
9International Computer Science Institute, located at Suite 600, 1947 Center
10Street, Berkeley, California 94704. Funding was partially provided by the
11National Science Foundation under grant MIP-9311980. The original version
12of this code was written as part of a project to build a fixed-point vector
13processor in collaboration with the University of California at Berkeley,
14overseen by Profs. Nelson Morgan and John Wawrzynek. More information
15is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16arithmetic/softfloat.html'.
17
18THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
19has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23
24Derivative works are acceptable, even for commercial purposes, so long as
25(1) they include prominent notice that the work is derivative, and (2) they
26include prominent notice akin to these three paragraphs for those parts of
27this code that are retained.
28
29===============================================================================
30*/
31
32/*
33-------------------------------------------------------------------------------
34Include common integer types and flags.
35-------------------------------------------------------------------------------
36*/
37#include "ARM-gcc.h"
38
39/*
40-------------------------------------------------------------------------------
41Symbolic Boolean literals.
42-------------------------------------------------------------------------------
43*/
44enum {
45 FALSE = 0,
46 TRUE = 1
47};
48
diff --git a/arch/arm26/nwfpe/single_cpdo.c b/arch/arm26/nwfpe/single_cpdo.c
deleted file mode 100644
index 5cdcddbb8999..000000000000
--- a/arch/arm26/nwfpe/single_cpdo.c
+++ /dev/null
@@ -1,255 +0,0 @@
1/*
2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "fpa11.h"
23#include "softfloat.h"
24#include "fpopcode.h"
25
26float32 float32_exp(float32 Fm);
27float32 float32_ln(float32 Fm);
28float32 float32_sin(float32 rFm);
29float32 float32_cos(float32 rFm);
30float32 float32_arcsin(float32 rFm);
31float32 float32_arctan(float32 rFm);
32float32 float32_log(float32 rFm);
33float32 float32_tan(float32 rFm);
34float32 float32_arccos(float32 rFm);
35float32 float32_pow(float32 rFn,float32 rFm);
36float32 float32_pol(float32 rFn,float32 rFm);
37
38unsigned int SingleCPDO(const unsigned int opcode)
39{
40 FPA11 *fpa11 = GET_FPA11();
41 float32 rFm, rFn = 0; //FIXME - should be zero?
42 unsigned int Fd, Fm, Fn, nRc = 1;
43
44 Fm = getFm(opcode);
45 if (CONSTANT_FM(opcode))
46 {
47 rFm = getSingleConstant(Fm);
48 }
49 else
50 {
51 switch (fpa11->fType[Fm])
52 {
53 case typeSingle:
54 rFm = fpa11->fpreg[Fm].fSingle;
55 break;
56
57 default: return 0;
58 }
59 }
60
61 if (!MONADIC_INSTRUCTION(opcode))
62 {
63 Fn = getFn(opcode);
64 switch (fpa11->fType[Fn])
65 {
66 case typeSingle:
67 rFn = fpa11->fpreg[Fn].fSingle;
68 break;
69
70 default: return 0;
71 }
72 }
73
74 Fd = getFd(opcode);
75 switch (opcode & MASK_ARITHMETIC_OPCODE)
76 {
77 /* dyadic opcodes */
78 case ADF_CODE:
79 fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
80 break;
81
82 case MUF_CODE:
83 case FML_CODE:
84 fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
85 break;
86
87 case SUF_CODE:
88 fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
89 break;
90
91 case RSF_CODE:
92 fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
93 break;
94
95 case DVF_CODE:
96 case FDV_CODE:
97 fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
98 break;
99
100 case RDF_CODE:
101 case FRD_CODE:
102 fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
103 break;
104
105#if 0
106 case POW_CODE:
107 fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
108 break;
109
110 case RPW_CODE:
111 fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
112 break;
113#endif
114
115 case RMF_CODE:
116 fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
117 break;
118
119#if 0
120 case POL_CODE:
121 fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
122 break;
123#endif
124
125 /* monadic opcodes */
126 case MVF_CODE:
127 fpa11->fpreg[Fd].fSingle = rFm;
128 break;
129
130 case MNF_CODE:
131 rFm ^= 0x80000000;
132 fpa11->fpreg[Fd].fSingle = rFm;
133 break;
134
135 case ABS_CODE:
136 rFm &= 0x7fffffff;
137 fpa11->fpreg[Fd].fSingle = rFm;
138 break;
139
140 case RND_CODE:
141 case URD_CODE:
142 fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm);
143 break;
144
145 case SQT_CODE:
146 fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
147 break;
148
149#if 0
150 case LOG_CODE:
151 fpa11->fpreg[Fd].fSingle = float32_log(rFm);
152 break;
153
154 case LGN_CODE:
155 fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
156 break;
157
158 case EXP_CODE:
159 fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
160 break;
161
162 case SIN_CODE:
163 fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
164 break;
165
166 case COS_CODE:
167 fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
168 break;
169
170 case TAN_CODE:
171 fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
172 break;
173
174 case ASN_CODE:
175 fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
176 break;
177
178 case ACS_CODE:
179 fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
180 break;
181
182 case ATN_CODE:
183 fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
184 break;
185#endif
186
187 case NRM_CODE:
188 break;
189
190 default:
191 {
192 nRc = 0;
193 }
194 }
195
196 if (0 != nRc) fpa11->fType[Fd] = typeSingle;
197 return nRc;
198}
199
200#if 0
201float32 float32_exp(float32 Fm)
202{
203//series
204}
205
206float32 float32_ln(float32 Fm)
207{
208//series
209}
210
211float32 float32_sin(float32 rFm)
212{
213//series
214}
215
216float32 float32_cos(float32 rFm)
217{
218//series
219}
220
221float32 float32_arcsin(float32 rFm)
222{
223//series
224}
225
226float32 float32_arctan(float32 rFm)
227{
228 //series
229}
230
231float32 float32_arccos(float32 rFm)
232{
233 //return float32_sub(halfPi,float32_arcsin(rFm));
234}
235
236float32 float32_log(float32 rFm)
237{
238 return float32_div(float32_ln(rFm),getSingleConstant(7));
239}
240
241float32 float32_tan(float32 rFm)
242{
243 return float32_div(float32_sin(rFm),float32_cos(rFm));
244}
245
246float32 float32_pow(float32 rFn,float32 rFm)
247{
248 return float32_exp(float32_mul(rFm,float32_ln(rFn)));
249}
250
251float32 float32_pol(float32 rFn,float32 rFm)
252{
253 return float32_arctan(float32_div(rFn,rFm));
254}
255#endif
diff --git a/arch/arm26/nwfpe/softfloat-macros b/arch/arm26/nwfpe/softfloat-macros
deleted file mode 100644
index 5469989f2c5e..000000000000
--- a/arch/arm26/nwfpe/softfloat-macros
+++ /dev/null
@@ -1,740 +0,0 @@
1
2/*
3===============================================================================
4
5This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
6Arithmetic Package, Release 2.
7
8Written by John R. Hauser. This work was made possible in part by the
9International Computer Science Institute, located at Suite 600, 1947 Center
10Street, Berkeley, California 94704. Funding was partially provided by the
11National Science Foundation under grant MIP-9311980. The original version
12of this code was written as part of a project to build a fixed-point vector
13processor in collaboration with the University of California at Berkeley,
14overseen by Profs. Nelson Morgan and John Wawrzynek. More information
15is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16arithmetic/softfloat.html'.
17
18THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
19has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23
24Derivative works are acceptable, even for commercial purposes, so long as
25(1) they include prominent notice that the work is derivative, and (2) they
26include prominent notice akin to these three paragraphs for those parts of
27this code that are retained.
28
29===============================================================================
30*/
31
32/*
33-------------------------------------------------------------------------------
34Shifts `a' right by the number of bits given in `count'. If any nonzero
35bits are shifted off, they are ``jammed'' into the least significant bit of
36the result by setting the least significant bit to 1. The value of `count'
37can be arbitrarily large; in particular, if `count' is greater than 32, the
38result will be either 0 or 1, depending on whether `a' is zero or nonzero.
39The result is stored in the location pointed to by `zPtr'.
40-------------------------------------------------------------------------------
41*/
42INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
43{
44 bits32 z;
45 if ( count == 0 ) {
46 z = a;
47 }
48 else if ( count < 32 ) {
49 z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
50 }
51 else {
52 z = ( a != 0 );
53 }
54 *zPtr = z;
55}
56
57/*
58-------------------------------------------------------------------------------
59Shifts `a' right by the number of bits given in `count'. If any nonzero
60bits are shifted off, they are ``jammed'' into the least significant bit of
61the result by setting the least significant bit to 1. The value of `count'
62can be arbitrarily large; in particular, if `count' is greater than 64, the
63result will be either 0 or 1, depending on whether `a' is zero or nonzero.
64The result is stored in the location pointed to by `zPtr'.
65-------------------------------------------------------------------------------
66*/
67INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
68{
69 bits64 z;
70
71 __asm__("@shift64RightJamming -- start");
72 if ( count == 0 ) {
73 z = a;
74 }
75 else if ( count < 64 ) {
76 z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
77 }
78 else {
79 z = ( a != 0 );
80 }
81 __asm__("@shift64RightJamming -- end");
82 *zPtr = z;
83}
84
85/*
86-------------------------------------------------------------------------------
87Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
88_plus_ the number of bits given in `count'. The shifted result is at most
8964 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
90bits shifted off form a second 64-bit result as follows: The _last_ bit
91shifted off is the most-significant bit of the extra result, and the other
9263 bits of the extra result are all zero if and only if _all_but_the_last_
93bits shifted off were all zero. This extra result is stored in the location
94pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
95 (This routine makes more sense if `a0' and `a1' are considered to form a
96fixed-point value with binary point between `a0' and `a1'. This fixed-point
97value is shifted right by the number of bits given in `count', and the
98integer part of the result is returned at the location pointed to by
99`z0Ptr'. The fractional part of the result may be slightly corrupted as
100described above, and is returned at the location pointed to by `z1Ptr'.)
101-------------------------------------------------------------------------------
102*/
103INLINE void
104 shift64ExtraRightJamming(
105 bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
106{
107 bits64 z0, z1;
108 int8 negCount = ( - count ) & 63;
109
110 if ( count == 0 ) {
111 z1 = a1;
112 z0 = a0;
113 }
114 else if ( count < 64 ) {
115 z1 = ( a0<<negCount ) | ( a1 != 0 );
116 z0 = a0>>count;
117 }
118 else {
119 if ( count == 64 ) {
120 z1 = a0 | ( a1 != 0 );
121 }
122 else {
123 z1 = ( ( a0 | a1 ) != 0 );
124 }
125 z0 = 0;
126 }
127 *z1Ptr = z1;
128 *z0Ptr = z0;
129
130}
131
132/*
133-------------------------------------------------------------------------------
134Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
135number of bits given in `count'. Any bits shifted off are lost. The value
136of `count' can be arbitrarily large; in particular, if `count' is greater
137than 128, the result will be 0. The result is broken into two 64-bit pieces
138which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
139-------------------------------------------------------------------------------
140*/
141INLINE void
142 shift128Right(
143 bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
144{
145 bits64 z0, z1;
146 int8 negCount = ( - count ) & 63;
147
148 if ( count == 0 ) {
149 z1 = a1;
150 z0 = a0;
151 }
152 else if ( count < 64 ) {
153 z1 = ( a0<<negCount ) | ( a1>>count );
154 z0 = a0>>count;
155 }
156 else {
157 z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
158 z0 = 0;
159 }
160 *z1Ptr = z1;
161 *z0Ptr = z0;
162
163}
164
165/*
166-------------------------------------------------------------------------------
167Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
168number of bits given in `count'. If any nonzero bits are shifted off, they
169are ``jammed'' into the least significant bit of the result by setting the
170least significant bit to 1. The value of `count' can be arbitrarily large;
171in particular, if `count' is greater than 128, the result will be either 0
172or 1, depending on whether the concatenation of `a0' and `a1' is zero or
173nonzero. The result is broken into two 64-bit pieces which are stored at
174the locations pointed to by `z0Ptr' and `z1Ptr'.
175-------------------------------------------------------------------------------
176*/
177INLINE void
178 shift128RightJamming(
179 bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
180{
181 bits64 z0, z1;
182 int8 negCount = ( - count ) & 63;
183
184 if ( count == 0 ) {
185 z1 = a1;
186 z0 = a0;
187 }
188 else if ( count < 64 ) {
189 z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
190 z0 = a0>>count;
191 }
192 else {
193 if ( count == 64 ) {
194 z1 = a0 | ( a1 != 0 );
195 }
196 else if ( count < 128 ) {
197 z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
198 }
199 else {
200 z1 = ( ( a0 | a1 ) != 0 );
201 }
202 z0 = 0;
203 }
204 *z1Ptr = z1;
205 *z0Ptr = z0;
206
207}
208
209/*
210-------------------------------------------------------------------------------
211Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
212by 64 _plus_ the number of bits given in `count'. The shifted result is
213at most 128 nonzero bits; these are broken into two 64-bit pieces which are
214stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
215off form a third 64-bit result as follows: The _last_ bit shifted off is
216the most-significant bit of the extra result, and the other 63 bits of the
217extra result are all zero if and only if _all_but_the_last_ bits shifted off
218were all zero. This extra result is stored in the location pointed to by
219`z2Ptr'. The value of `count' can be arbitrarily large.
220 (This routine makes more sense if `a0', `a1', and `a2' are considered
221to form a fixed-point value with binary point between `a1' and `a2'. This
222fixed-point value is shifted right by the number of bits given in `count',
223and the integer part of the result is returned at the locations pointed to
224by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
225corrupted as described above, and is returned at the location pointed to by
226`z2Ptr'.)
227-------------------------------------------------------------------------------
228*/
229INLINE void
230 shift128ExtraRightJamming(
231 bits64 a0,
232 bits64 a1,
233 bits64 a2,
234 int16 count,
235 bits64 *z0Ptr,
236 bits64 *z1Ptr,
237 bits64 *z2Ptr
238 )
239{
240 bits64 z0, z1, z2;
241 int8 negCount = ( - count ) & 63;
242
243 if ( count == 0 ) {
244 z2 = a2;
245 z1 = a1;
246 z0 = a0;
247 }
248 else {
249 if ( count < 64 ) {
250 z2 = a1<<negCount;
251 z1 = ( a0<<negCount ) | ( a1>>count );
252 z0 = a0>>count;
253 }
254 else {
255 if ( count == 64 ) {
256 z2 = a1;
257 z1 = a0;
258 }
259 else {
260 a2 |= a1;
261 if ( count < 128 ) {
262 z2 = a0<<negCount;
263 z1 = a0>>( count & 63 );
264 }
265 else {
266 z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
267 z1 = 0;
268 }
269 }
270 z0 = 0;
271 }
272 z2 |= ( a2 != 0 );
273 }
274 *z2Ptr = z2;
275 *z1Ptr = z1;
276 *z0Ptr = z0;
277
278}
279
280/*
281-------------------------------------------------------------------------------
282Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
283number of bits given in `count'. Any bits shifted off are lost. The value
284of `count' must be less than 64. The result is broken into two 64-bit
285pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
286-------------------------------------------------------------------------------
287*/
288INLINE void
289 shortShift128Left(
290 bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
291{
292
293 *z1Ptr = a1<<count;
294 *z0Ptr =
295 ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
296
297}
298
299/*
300-------------------------------------------------------------------------------
301Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
302by the number of bits given in `count'. Any bits shifted off are lost.
303The value of `count' must be less than 64. The result is broken into three
30464-bit pieces which are stored at the locations pointed to by `z0Ptr',
305`z1Ptr', and `z2Ptr'.
306-------------------------------------------------------------------------------
307*/
308INLINE void
309 shortShift192Left(
310 bits64 a0,
311 bits64 a1,
312 bits64 a2,
313 int16 count,
314 bits64 *z0Ptr,
315 bits64 *z1Ptr,
316 bits64 *z2Ptr
317 )
318{
319 bits64 z0, z1, z2;
320 int8 negCount;
321
322 z2 = a2<<count;
323 z1 = a1<<count;
324 z0 = a0<<count;
325 if ( 0 < count ) {
326 negCount = ( ( - count ) & 63 );
327 z1 |= a2>>negCount;
328 z0 |= a1>>negCount;
329 }
330 *z2Ptr = z2;
331 *z1Ptr = z1;
332 *z0Ptr = z0;
333
334}
335
336/*
337-------------------------------------------------------------------------------
338Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
339value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
340any carry out is lost. The result is broken into two 64-bit pieces which
341are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
342-------------------------------------------------------------------------------
343*/
344INLINE void
345 add128(
346 bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
347{
348 bits64 z1;
349
350 z1 = a1 + b1;
351 *z1Ptr = z1;
352 *z0Ptr = a0 + b0 + ( z1 < a1 );
353
354}
355
356/*
357-------------------------------------------------------------------------------
358Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
359192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
360modulo 2^192, so any carry out is lost. The result is broken into three
36164-bit pieces which are stored at the locations pointed to by `z0Ptr',
362`z1Ptr', and `z2Ptr'.
363-------------------------------------------------------------------------------
364*/
365INLINE void
366 add192(
367 bits64 a0,
368 bits64 a1,
369 bits64 a2,
370 bits64 b0,
371 bits64 b1,
372 bits64 b2,
373 bits64 *z0Ptr,
374 bits64 *z1Ptr,
375 bits64 *z2Ptr
376 )
377{
378 bits64 z0, z1, z2;
379 int8 carry0, carry1;
380
381 z2 = a2 + b2;
382 carry1 = ( z2 < a2 );
383 z1 = a1 + b1;
384 carry0 = ( z1 < a1 );
385 z0 = a0 + b0;
386 z1 += carry1;
387 z0 += ( z1 < carry1 );
388 z0 += carry0;
389 *z2Ptr = z2;
390 *z1Ptr = z1;
391 *z0Ptr = z0;
392
393}
394
395/*
396-------------------------------------------------------------------------------
397Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
398128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
3992^128, so any borrow out (carry out) is lost. The result is broken into two
40064-bit pieces which are stored at the locations pointed to by `z0Ptr' and
401`z1Ptr'.
402-------------------------------------------------------------------------------
403*/
404INLINE void
405 sub128(
406 bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
407{
408
409 *z1Ptr = a1 - b1;
410 *z0Ptr = a0 - b0 - ( a1 < b1 );
411
412}
413
414/*
415-------------------------------------------------------------------------------
416Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
417from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
418Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
419result is broken into three 64-bit pieces which are stored at the locations
420pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
421-------------------------------------------------------------------------------
422*/
423INLINE void
424 sub192(
425 bits64 a0,
426 bits64 a1,
427 bits64 a2,
428 bits64 b0,
429 bits64 b1,
430 bits64 b2,
431 bits64 *z0Ptr,
432 bits64 *z1Ptr,
433 bits64 *z2Ptr
434 )
435{
436 bits64 z0, z1, z2;
437 int8 borrow0, borrow1;
438
439 z2 = a2 - b2;
440 borrow1 = ( a2 < b2 );
441 z1 = a1 - b1;
442 borrow0 = ( a1 < b1 );
443 z0 = a0 - b0;
444 z0 -= ( z1 < borrow1 );
445 z1 -= borrow1;
446 z0 -= borrow0;
447 *z2Ptr = z2;
448 *z1Ptr = z1;
449 *z0Ptr = z0;
450
451}
452
453/*
454-------------------------------------------------------------------------------
455Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
456into two 64-bit pieces which are stored at the locations pointed to by
457`z0Ptr' and `z1Ptr'.
458-------------------------------------------------------------------------------
459*/
460INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
461{
462 bits32 aHigh, aLow, bHigh, bLow;
463 bits64 z0, zMiddleA, zMiddleB, z1;
464
465 aLow = a;
466 aHigh = a>>32;
467 bLow = b;
468 bHigh = b>>32;
469 z1 = ( (bits64) aLow ) * bLow;
470 zMiddleA = ( (bits64) aLow ) * bHigh;
471 zMiddleB = ( (bits64) aHigh ) * bLow;
472 z0 = ( (bits64) aHigh ) * bHigh;
473 zMiddleA += zMiddleB;
474 z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
475 zMiddleA <<= 32;
476 z1 += zMiddleA;
477 z0 += ( z1 < zMiddleA );
478 *z1Ptr = z1;
479 *z0Ptr = z0;
480
481}
482
483/*
484-------------------------------------------------------------------------------
485Multiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to
486obtain a 192-bit product. The product is broken into three 64-bit pieces
487which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
488`z2Ptr'.
489-------------------------------------------------------------------------------
490*/
491INLINE void
492 mul128By64To192(
493 bits64 a0,
494 bits64 a1,
495 bits64 b,
496 bits64 *z0Ptr,
497 bits64 *z1Ptr,
498 bits64 *z2Ptr
499 )
500{
501 bits64 z0, z1, z2, more1;
502
503 mul64To128( a1, b, &z1, &z2 );
504 mul64To128( a0, b, &z0, &more1 );
505 add128( z0, more1, 0, z1, &z0, &z1 );
506 *z2Ptr = z2;
507 *z1Ptr = z1;
508 *z0Ptr = z0;
509
510}
511
512/*
513-------------------------------------------------------------------------------
514Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
515128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
516product. The product is broken into four 64-bit pieces which are stored at
517the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
518-------------------------------------------------------------------------------
519*/
520INLINE void
521 mul128To256(
522 bits64 a0,
523 bits64 a1,
524 bits64 b0,
525 bits64 b1,
526 bits64 *z0Ptr,
527 bits64 *z1Ptr,
528 bits64 *z2Ptr,
529 bits64 *z3Ptr
530 )
531{
532 bits64 z0, z1, z2, z3;
533 bits64 more1, more2;
534
535 mul64To128( a1, b1, &z2, &z3 );
536 mul64To128( a1, b0, &z1, &more2 );
537 add128( z1, more2, 0, z2, &z1, &z2 );
538 mul64To128( a0, b0, &z0, &more1 );
539 add128( z0, more1, 0, z1, &z0, &z1 );
540 mul64To128( a0, b1, &more1, &more2 );
541 add128( more1, more2, 0, z2, &more1, &z2 );
542 add128( z0, z1, 0, more1, &z0, &z1 );
543 *z3Ptr = z3;
544 *z2Ptr = z2;
545 *z1Ptr = z1;
546 *z0Ptr = z0;
547
548}
549
550/*
551-------------------------------------------------------------------------------
552Returns an approximation to the 64-bit integer quotient obtained by dividing
553`b' into the 128-bit value formed by concatenating `a0' and `a1'. The
554divisor `b' must be at least 2^63. If q is the exact quotient truncated
555toward zero, the approximation returned lies between q and q + 2 inclusive.
556If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
557unsigned integer is returned.
558-------------------------------------------------------------------------------
559*/
560static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
561{
562 bits64 b0, b1;
563 bits64 rem0, rem1, term0, term1;
564 bits64 z;
565 if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
566 b0 = b>>32;
567 z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
568 mul64To128( b, z, &term0, &term1 );
569 sub128( a0, a1, term0, term1, &rem0, &rem1 );
570 while ( ( (sbits64) rem0 ) < 0 ) {
571 z -= LIT64( 0x100000000 );
572 b1 = b<<32;
573 add128( rem0, rem1, b0, b1, &rem0, &rem1 );
574 }
575 rem0 = ( rem0<<32 ) | ( rem1>>32 );
576 z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
577 return z;
578
579}
580
581/*
582-------------------------------------------------------------------------------
583Returns an approximation to the square root of the 32-bit significand given
584by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
585`aExp' (the least significant bit) is 1, the integer returned approximates
5862^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
587is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
588case, the approximation returned lies strictly within +/-2 of the exact
589value.
590-------------------------------------------------------------------------------
591*/
592static bits32 estimateSqrt32( int16 aExp, bits32 a )
593{
594 static const bits16 sqrtOddAdjustments[] = {
595 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
596 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
597 };
598 static const bits16 sqrtEvenAdjustments[] = {
599 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
600 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
601 };
602 int8 index;
603 bits32 z;
604
605 index = ( a>>27 ) & 15;
606 if ( aExp & 1 ) {
607 z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
608 z = ( ( a / z )<<14 ) + ( z<<15 );
609 a >>= 1;
610 }
611 else {
612 z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
613 z = a / z + z;
614 z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
615 if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
616 }
617 return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
618
619}
620
621/*
622-------------------------------------------------------------------------------
623Returns the number of leading 0 bits before the most-significant 1 bit
624of `a'. If `a' is zero, 32 is returned.
625-------------------------------------------------------------------------------
626*/
627static int8 countLeadingZeros32( bits32 a )
628{
629 static const int8 countLeadingZerosHigh[] = {
630 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
631 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
632 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
633 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
634 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
635 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
636 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
637 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
639 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
646 };
647 int8 shiftCount;
648
649 shiftCount = 0;
650 if ( a < 0x10000 ) {
651 shiftCount += 16;
652 a <<= 16;
653 }
654 if ( a < 0x1000000 ) {
655 shiftCount += 8;
656 a <<= 8;
657 }
658 shiftCount += countLeadingZerosHigh[ a>>24 ];
659 return shiftCount;
660
661}
662
663/*
664-------------------------------------------------------------------------------
665Returns the number of leading 0 bits before the most-significant 1 bit
666of `a'. If `a' is zero, 64 is returned.
667-------------------------------------------------------------------------------
668*/
669static int8 countLeadingZeros64( bits64 a )
670{
671 int8 shiftCount;
672
673 shiftCount = 0;
674 if ( a < ( (bits64) 1 )<<32 ) {
675 shiftCount += 32;
676 }
677 else {
678 a >>= 32;
679 }
680 shiftCount += countLeadingZeros32( a );
681 return shiftCount;
682
683}
684
685/*
686-------------------------------------------------------------------------------
687Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
688is equal to the 128-bit value formed by concatenating `b0' and `b1'.
689Otherwise, returns 0.
690-------------------------------------------------------------------------------
691*/
692INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
693{
694
695 return ( a0 == b0 ) && ( a1 == b1 );
696
697}
698
699/*
700-------------------------------------------------------------------------------
701Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
702than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
703Otherwise, returns 0.
704-------------------------------------------------------------------------------
705*/
706INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
707{
708
709 return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
710
711}
712
713/*
714-------------------------------------------------------------------------------
715Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
716than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
717returns 0.
718-------------------------------------------------------------------------------
719*/
720INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
721{
722
723 return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
724
725}
726
727/*
728-------------------------------------------------------------------------------
729Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
730not equal to the 128-bit value formed by concatenating `b0' and `b1'.
731Otherwise, returns 0.
732-------------------------------------------------------------------------------
733*/
734INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
735{
736
737 return ( a0 != b0 ) || ( a1 != b1 );
738
739}
740
diff --git a/arch/arm26/nwfpe/softfloat-specialize b/arch/arm26/nwfpe/softfloat-specialize
deleted file mode 100644
index acf409144763..000000000000
--- a/arch/arm26/nwfpe/softfloat-specialize
+++ /dev/null
@@ -1,366 +0,0 @@
1
2/*
3===============================================================================
4
5This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
6Arithmetic Package, Release 2.
7
8Written by John R. Hauser. This work was made possible in part by the
9International Computer Science Institute, located at Suite 600, 1947 Center
10Street, Berkeley, California 94704. Funding was partially provided by the
11National Science Foundation under grant MIP-9311980. The original version
12of this code was written as part of a project to build a fixed-point vector
13processor in collaboration with the University of California at Berkeley,
14overseen by Profs. Nelson Morgan and John Wawrzynek. More information
15is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16arithmetic/softfloat.html'.
17
18THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
19has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23
24Derivative works are acceptable, even for commercial purposes, so long as
25(1) they include prominent notice that the work is derivative, and (2) they
26include prominent notice akin to these three paragraphs for those parts of
27this code that are retained.
28
29===============================================================================
30*/
31
32/*
33-------------------------------------------------------------------------------
34Underflow tininess-detection mode, statically initialized to default value.
35(The declaration in `softfloat.h' must match the `int8' type here.)
36-------------------------------------------------------------------------------
37*/
38int8 float_detect_tininess = float_tininess_after_rounding;
39
40/*
41-------------------------------------------------------------------------------
42Raises the exceptions specified by `flags'. Floating-point traps can be
43defined here if desired. It is currently not possible for such a trap to
44substitute a result value. If traps are not implemented, this routine
45should be simply `float_exception_flags |= flags;'.
46
47ScottB: November 4, 1998
48Moved this function out of softfloat-specialize into fpmodule.c.
49This effectively isolates all the changes required for integrating with the
50Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying
51fpmodule.c to integrate with the NetBSD kernel (I hope!).
52-------------------------------------------------------------------------------
53void float_raise( int8 flags )
54{
55 float_exception_flags |= flags;
56}
57*/
58
59/*
60-------------------------------------------------------------------------------
61Internal canonical NaN format.
62-------------------------------------------------------------------------------
63*/
64typedef struct {
65 flag sign;
66 bits64 high, low;
67} commonNaNT;
68
69/*
70-------------------------------------------------------------------------------
71The pattern for a default generated single-precision NaN.
72-------------------------------------------------------------------------------
73*/
74#define float32_default_nan 0xFFFFFFFF
75
76/*
77-------------------------------------------------------------------------------
78Returns 1 if the single-precision floating-point value `a' is a NaN;
79otherwise returns 0.
80-------------------------------------------------------------------------------
81*/
82flag float32_is_nan( float32 a )
83{
84
85 return ( 0xFF000000 < (bits32) ( a<<1 ) );
86
87}
88
89/*
90-------------------------------------------------------------------------------
91Returns 1 if the single-precision floating-point value `a' is a signaling
92NaN; otherwise returns 0.
93-------------------------------------------------------------------------------
94*/
95flag float32_is_signaling_nan( float32 a )
96{
97
98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99
100}
101
102/*
103-------------------------------------------------------------------------------
104Returns the result of converting the single-precision floating-point NaN
105`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
106exception is raised.
107-------------------------------------------------------------------------------
108*/
109static commonNaNT float32ToCommonNaN( float32 a )
110{
111 commonNaNT z;
112
113 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
114 z.sign = a>>31;
115 z.low = 0;
116 z.high = ( (bits64) a )<<41;
117 return z;
118
119}
120
121/*
122-------------------------------------------------------------------------------
123Returns the result of converting the canonical NaN `a' to the single-
124precision floating-point format.
125-------------------------------------------------------------------------------
126*/
127static float32 commonNaNToFloat32( commonNaNT a )
128{
129
130 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
131
132}
133
134/*
135-------------------------------------------------------------------------------
136Takes two single-precision floating-point values `a' and `b', one of which
137is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
138signaling NaN, the invalid exception is raised.
139-------------------------------------------------------------------------------
140*/
141static float32 propagateFloat32NaN( float32 a, float32 b )
142{
143 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
144
145 aIsNaN = float32_is_nan( a );
146 aIsSignalingNaN = float32_is_signaling_nan( a );
147 bIsNaN = float32_is_nan( b );
148 bIsSignalingNaN = float32_is_signaling_nan( b );
149 a |= 0x00400000;
150 b |= 0x00400000;
151 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
152 if ( aIsNaN ) {
153 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
154 }
155 else {
156 return b;
157 }
158
159}
160
161/*
162-------------------------------------------------------------------------------
163The pattern for a default generated double-precision NaN.
164-------------------------------------------------------------------------------
165*/
166#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
167
168/*
169-------------------------------------------------------------------------------
170Returns 1 if the double-precision floating-point value `a' is a NaN;
171otherwise returns 0.
172-------------------------------------------------------------------------------
173*/
174flag float64_is_nan( float64 a )
175{
176
177 return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
178
179}
180
181/*
182-------------------------------------------------------------------------------
183Returns 1 if the double-precision floating-point value `a' is a signaling
184NaN; otherwise returns 0.
185-------------------------------------------------------------------------------
186*/
187flag float64_is_signaling_nan( float64 a )
188{
189
190 return
191 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
192 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
193
194}
195
196/*
197-------------------------------------------------------------------------------
198Returns the result of converting the double-precision floating-point NaN
199`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
200exception is raised.
201-------------------------------------------------------------------------------
202*/
203static commonNaNT float64ToCommonNaN( float64 a )
204{
205 commonNaNT z;
206
207 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
208 z.sign = a>>63;
209 z.low = 0;
210 z.high = a<<12;
211 return z;
212
213}
214
215/*
216-------------------------------------------------------------------------------
217Returns the result of converting the canonical NaN `a' to the double-
218precision floating-point format.
219-------------------------------------------------------------------------------
220*/
221static float64 commonNaNToFloat64( commonNaNT a )
222{
223
224 return
225 ( ( (bits64) a.sign )<<63 )
226 | LIT64( 0x7FF8000000000000 )
227 | ( a.high>>12 );
228
229}
230
231/*
232-------------------------------------------------------------------------------
233Takes two double-precision floating-point values `a' and `b', one of which
234is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
235signaling NaN, the invalid exception is raised.
236-------------------------------------------------------------------------------
237*/
238static float64 propagateFloat64NaN( float64 a, float64 b )
239{
240 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
241
242 aIsNaN = float64_is_nan( a );
243 aIsSignalingNaN = float64_is_signaling_nan( a );
244 bIsNaN = float64_is_nan( b );
245 bIsSignalingNaN = float64_is_signaling_nan( b );
246 a |= LIT64( 0x0008000000000000 );
247 b |= LIT64( 0x0008000000000000 );
248 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
249 if ( aIsNaN ) {
250 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
251 }
252 else {
253 return b;
254 }
255
256}
257
258#ifdef FLOATX80
259
260/*
261-------------------------------------------------------------------------------
262The pattern for a default generated extended double-precision NaN. The
263`high' and `low' values hold the most- and least-significant bits,
264respectively.
265-------------------------------------------------------------------------------
266*/
267#define floatx80_default_nan_high 0xFFFF
268#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
269
270/*
271-------------------------------------------------------------------------------
272Returns 1 if the extended double-precision floating-point value `a' is a
273NaN; otherwise returns 0.
274-------------------------------------------------------------------------------
275*/
276flag floatx80_is_nan( floatx80 a )
277{
278
279 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
280
281}
282
283/*
284-------------------------------------------------------------------------------
285Returns 1 if the extended double-precision floating-point value `a' is a
286signaling NaN; otherwise returns 0.
287-------------------------------------------------------------------------------
288*/
289flag floatx80_is_signaling_nan( floatx80 a )
290{
291 //register int lr;
292 bits64 aLow;
293
294 //__asm__("mov %0, lr" : : "g" (lr));
295 //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
296 aLow = a.low & ~ LIT64( 0x4000000000000000 );
297 return
298 ( ( a.high & 0x7FFF ) == 0x7FFF )
299 && (bits64) ( aLow<<1 )
300 && ( a.low == aLow );
301
302}
303
304/*
305-------------------------------------------------------------------------------
306Returns the result of converting the extended double-precision floating-
307point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
308invalid exception is raised.
309-------------------------------------------------------------------------------
310*/
311static commonNaNT floatx80ToCommonNaN( floatx80 a )
312{
313 commonNaNT z;
314
315 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
316 z.sign = a.high>>15;
317 z.low = 0;
318 z.high = a.low<<1;
319 return z;
320
321}
322
323/*
324-------------------------------------------------------------------------------
325Returns the result of converting the canonical NaN `a' to the extended
326double-precision floating-point format.
327-------------------------------------------------------------------------------
328*/
329static floatx80 commonNaNToFloatx80( commonNaNT a )
330{
331 floatx80 z;
332
333 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
334 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
335 return z;
336
337}
338
339/*
340-------------------------------------------------------------------------------
341Takes two extended double-precision floating-point values `a' and `b', one
342of which is a NaN, and returns the appropriate NaN result. If either `a' or
343`b' is a signaling NaN, the invalid exception is raised.
344-------------------------------------------------------------------------------
345*/
346static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
347{
348 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
349
350 aIsNaN = floatx80_is_nan( a );
351 aIsSignalingNaN = floatx80_is_signaling_nan( a );
352 bIsNaN = floatx80_is_nan( b );
353 bIsSignalingNaN = floatx80_is_signaling_nan( b );
354 a.low |= LIT64( 0xC000000000000000 );
355 b.low |= LIT64( 0xC000000000000000 );
356 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
357 if ( aIsNaN ) {
358 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
359 }
360 else {
361 return b;
362 }
363
364}
365
366#endif
diff --git a/arch/arm26/nwfpe/softfloat.c b/arch/arm26/nwfpe/softfloat.c
deleted file mode 100644
index 26c1b916e527..000000000000
--- a/arch/arm26/nwfpe/softfloat.c
+++ /dev/null
@@ -1,3439 +0,0 @@
1/*
2===============================================================================
3
4This C source file is part of the SoftFloat IEC/IEEE Floating-point
5Arithmetic Package, Release 2.
6
7Written by John R. Hauser. This work was made possible in part by the
8International Computer Science Institute, located at Suite 600, 1947 Center
9Street, Berkeley, California 94704. Funding was partially provided by the
10National Science Foundation under grant MIP-9311980. The original version
11of this code was written as part of a project to build a fixed-point vector
12processor in collaboration with the University of California at Berkeley,
13overseen by Profs. Nelson Morgan and John Wawrzynek. More information
14is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
15arithmetic/softfloat.html'.
16
17THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
18has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
19TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
20PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
21AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
22
23Derivative works are acceptable, even for commercial purposes, so long as
24(1) they include prominent notice that the work is derivative, and (2) they
25include prominent notice akin to these three paragraphs for those parts of
26this code that are retained.
27
28===============================================================================
29*/
30
31#include "fpa11.h"
32#include "milieu.h"
33#include "softfloat.h"
34
35/*
36-------------------------------------------------------------------------------
37Floating-point rounding mode, extended double-precision rounding precision,
38and exception flags.
39-------------------------------------------------------------------------------
40*/
41int8 float_rounding_mode = float_round_nearest_even;
42int8 floatx80_rounding_precision = 80;
43int8 float_exception_flags;
44
45/*
46-------------------------------------------------------------------------------
47Primitive arithmetic functions, including multi-word arithmetic, and
48division and square root approximations. (Can be specialized to target if
49desired.)
50-------------------------------------------------------------------------------
51*/
52#include "softfloat-macros"
53
54/*
55-------------------------------------------------------------------------------
56Functions and definitions to determine: (1) whether tininess for underflow
57is detected before or after rounding by default, (2) what (if anything)
58happens when exceptions are raised, (3) how signaling NaNs are distinguished
59from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
60are propagated from function inputs to output. These details are target-
61specific.
62-------------------------------------------------------------------------------
63*/
64#include "softfloat-specialize"
65
66/*
67-------------------------------------------------------------------------------
68Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
69and 7, and returns the properly rounded 32-bit integer corresponding to the
70input. If `zSign' is nonzero, the input is negated before being converted
71to an integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point
72input is simply rounded to an integer, with the inexact exception raised if
73the input cannot be represented exactly as an integer. If the fixed-point
74input is too large, however, the invalid exception is raised and the largest
75positive or negative integer is returned.
76-------------------------------------------------------------------------------
77*/
78static int32 roundAndPackInt32( flag zSign, bits64 absZ )
79{
80 int8 roundingMode;
81 flag roundNearestEven;
82 int8 roundIncrement, roundBits;
83 int32 z;
84
85 roundingMode = float_rounding_mode;
86 roundNearestEven = ( roundingMode == float_round_nearest_even );
87 roundIncrement = 0x40;
88 if ( ! roundNearestEven ) {
89 if ( roundingMode == float_round_to_zero ) {
90 roundIncrement = 0;
91 }
92 else {
93 roundIncrement = 0x7F;
94 if ( zSign ) {
95 if ( roundingMode == float_round_up ) roundIncrement = 0;
96 }
97 else {
98 if ( roundingMode == float_round_down ) roundIncrement = 0;
99 }
100 }
101 }
102 roundBits = absZ & 0x7F;
103 absZ = ( absZ + roundIncrement )>>7;
104 absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
105 z = absZ;
106 if ( zSign ) z = - z;
107 if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
108 float_exception_flags |= float_flag_invalid;
109 return zSign ? 0x80000000 : 0x7FFFFFFF;
110 }
111 if ( roundBits ) float_exception_flags |= float_flag_inexact;
112 return z;
113
114}
115
116/*
117-------------------------------------------------------------------------------
118Returns the fraction bits of the single-precision floating-point value `a'.
119-------------------------------------------------------------------------------
120*/
121INLINE bits32 extractFloat32Frac( float32 a )
122{
123
124 return a & 0x007FFFFF;
125
126}
127
128/*
129-------------------------------------------------------------------------------
130Returns the exponent bits of the single-precision floating-point value `a'.
131-------------------------------------------------------------------------------
132*/
133INLINE int16 extractFloat32Exp( float32 a )
134{
135
136 return ( a>>23 ) & 0xFF;
137
138}
139
140/*
141-------------------------------------------------------------------------------
142Returns the sign bit of the single-precision floating-point value `a'.
143-------------------------------------------------------------------------------
144*/
145INLINE flag extractFloat32Sign( float32 a )
146{
147
148 return a>>31;
149
150}
151
152/*
153-------------------------------------------------------------------------------
154Normalizes the subnormal single-precision floating-point value represented
155by the denormalized significand `aSig'. The normalized exponent and
156significand are stored at the locations pointed to by `zExpPtr' and
157`zSigPtr', respectively.
158-------------------------------------------------------------------------------
159*/
160static void
161 normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
162{
163 int8 shiftCount;
164
165 shiftCount = countLeadingZeros32( aSig ) - 8;
166 *zSigPtr = aSig<<shiftCount;
167 *zExpPtr = 1 - shiftCount;
168
169}
170
171/*
172-------------------------------------------------------------------------------
173Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
174single-precision floating-point value, returning the result. After being
175shifted into the proper positions, the three fields are simply added
176together to form the result. This means that any integer portion of `zSig'
177will be added into the exponent. Since a properly normalized significand
178will have an integer portion equal to 1, the `zExp' input should be 1 less
179than the desired result exponent whenever `zSig' is a complete, normalized
180significand.
181-------------------------------------------------------------------------------
182*/
183INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
184{
185#if 0
186 float32 f;
187 __asm__("@ packFloat32; \n\
188 mov %0, %1, asl #31; \n\
189 orr %0, %2, asl #23; \n\
190 orr %0, %3"
191 : /* no outputs */
192 : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
193 : "cc");
194 return f;
195#else
196 return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
197#endif
198}
199
200/*
201-------------------------------------------------------------------------------
202Takes an abstract floating-point value having sign `zSign', exponent `zExp',
203and significand `zSig', and returns the proper single-precision floating-
204point value corresponding to the abstract input. Ordinarily, the abstract
205value is simply rounded and packed into the single-precision format, with
206the inexact exception raised if the abstract input cannot be represented
207exactly. If the abstract value is too large, however, the overflow and
208inexact exceptions are raised and an infinity or maximal finite value is
209returned. If the abstract value is too small, the input value is rounded to
210a subnormal number, and the underflow and inexact exceptions are raised if
211the abstract input cannot be represented exactly as a subnormal single-
212precision floating-point number.
213 The input significand `zSig' has its binary point between bits 30
214and 29, which is 7 bits to the left of the usual location. This shifted
215significand must be normalized or smaller. If `zSig' is not normalized,
216`zExp' must be 0; in that case, the result returned is a subnormal number,
217and it must not require rounding. In the usual case that `zSig' is
218normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
219The handling of underflow and overflow follows the IEC/IEEE Standard for
220Binary Floating-point Arithmetic.
221-------------------------------------------------------------------------------
222*/
223static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
224{
225 int8 roundingMode;
226 flag roundNearestEven;
227 int8 roundIncrement, roundBits;
228 flag isTiny;
229
230 roundingMode = float_rounding_mode;
231 roundNearestEven = ( roundingMode == float_round_nearest_even );
232 roundIncrement = 0x40;
233 if ( ! roundNearestEven ) {
234 if ( roundingMode == float_round_to_zero ) {
235 roundIncrement = 0;
236 }
237 else {
238 roundIncrement = 0x7F;
239 if ( zSign ) {
240 if ( roundingMode == float_round_up ) roundIncrement = 0;
241 }
242 else {
243 if ( roundingMode == float_round_down ) roundIncrement = 0;
244 }
245 }
246 }
247 roundBits = zSig & 0x7F;
248 if ( 0xFD <= (bits16) zExp ) {
249 if ( ( 0xFD < zExp )
250 || ( ( zExp == 0xFD )
251 && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
252 ) {
253 float_raise( float_flag_overflow | float_flag_inexact );
254 return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
255 }
256 if ( zExp < 0 ) {
257 isTiny =
258 ( float_detect_tininess == float_tininess_before_rounding )
259 || ( zExp < -1 )
260 || ( zSig + roundIncrement < 0x80000000 );
261 shift32RightJamming( zSig, - zExp, &zSig );
262 zExp = 0;
263 roundBits = zSig & 0x7F;
264 if ( isTiny && roundBits ) float_raise( float_flag_underflow );
265 }
266 }
267 if ( roundBits ) float_exception_flags |= float_flag_inexact;
268 zSig = ( zSig + roundIncrement )>>7;
269 zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
270 if ( zSig == 0 ) zExp = 0;
271 return packFloat32( zSign, zExp, zSig );
272
273}
274
275/*
276-------------------------------------------------------------------------------
277Takes an abstract floating-point value having sign `zSign', exponent `zExp',
278and significand `zSig', and returns the proper single-precision floating-
279point value corresponding to the abstract input. This routine is just like
280`roundAndPackFloat32' except that `zSig' does not have to be normalized in
281any way. In all cases, `zExp' must be 1 less than the ``true'' floating-
282point exponent.
283-------------------------------------------------------------------------------
284*/
285static float32
286 normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
287{
288 int8 shiftCount;
289
290 shiftCount = countLeadingZeros32( zSig ) - 1;
291 return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
292
293}
294
295/*
296-------------------------------------------------------------------------------
297Returns the fraction bits of the double-precision floating-point value `a'.
298-------------------------------------------------------------------------------
299*/
300INLINE bits64 extractFloat64Frac( float64 a )
301{
302
303 return a & LIT64( 0x000FFFFFFFFFFFFF );
304
305}
306
307/*
308-------------------------------------------------------------------------------
309Returns the exponent bits of the double-precision floating-point value `a'.
310-------------------------------------------------------------------------------
311*/
312INLINE int16 extractFloat64Exp( float64 a )
313{
314
315 return ( a>>52 ) & 0x7FF;
316
317}
318
319/*
320-------------------------------------------------------------------------------
321Returns the sign bit of the double-precision floating-point value `a'.
322-------------------------------------------------------------------------------
323*/
324INLINE flag extractFloat64Sign( float64 a )
325{
326
327 return a>>63;
328
329}
330
331/*
332-------------------------------------------------------------------------------
333Normalizes the subnormal double-precision floating-point value represented
334by the denormalized significand `aSig'. The normalized exponent and
335significand are stored at the locations pointed to by `zExpPtr' and
336`zSigPtr', respectively.
337-------------------------------------------------------------------------------
338*/
339static void
340 normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
341{
342 int8 shiftCount;
343
344 shiftCount = countLeadingZeros64( aSig ) - 11;
345 *zSigPtr = aSig<<shiftCount;
346 *zExpPtr = 1 - shiftCount;
347
348}
349
350/*
351-------------------------------------------------------------------------------
352Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
353double-precision floating-point value, returning the result. After being
354shifted into the proper positions, the three fields are simply added
355together to form the result. This means that any integer portion of `zSig'
356will be added into the exponent. Since a properly normalized significand
357will have an integer portion equal to 1, the `zExp' input should be 1 less
358than the desired result exponent whenever `zSig' is a complete, normalized
359significand.
360-------------------------------------------------------------------------------
361*/
362INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
363{
364
365 return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
366
367}
368
369/*
370-------------------------------------------------------------------------------
371Takes an abstract floating-point value having sign `zSign', exponent `zExp',
372and significand `zSig', and returns the proper double-precision floating-
373point value corresponding to the abstract input. Ordinarily, the abstract
374value is simply rounded and packed into the double-precision format, with
375the inexact exception raised if the abstract input cannot be represented
376exactly. If the abstract value is too large, however, the overflow and
377inexact exceptions are raised and an infinity or maximal finite value is
378returned. If the abstract value is too small, the input value is rounded to
379a subnormal number, and the underflow and inexact exceptions are raised if
380the abstract input cannot be represented exactly as a subnormal double-
381precision floating-point number.
382 The input significand `zSig' has its binary point between bits 62
383and 61, which is 10 bits to the left of the usual location. This shifted
384significand must be normalized or smaller. If `zSig' is not normalized,
385`zExp' must be 0; in that case, the result returned is a subnormal number,
386and it must not require rounding. In the usual case that `zSig' is
387normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
388The handling of underflow and overflow follows the IEC/IEEE Standard for
389Binary Floating-point Arithmetic.
390-------------------------------------------------------------------------------
391*/
392static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
393{
394 int8 roundingMode;
395 flag roundNearestEven;
396 int16 roundIncrement, roundBits;
397 flag isTiny;
398
399 roundingMode = float_rounding_mode;
400 roundNearestEven = ( roundingMode == float_round_nearest_even );
401 roundIncrement = 0x200;
402 if ( ! roundNearestEven ) {
403 if ( roundingMode == float_round_to_zero ) {
404 roundIncrement = 0;
405 }
406 else {
407 roundIncrement = 0x3FF;
408 if ( zSign ) {
409 if ( roundingMode == float_round_up ) roundIncrement = 0;
410 }
411 else {
412 if ( roundingMode == float_round_down ) roundIncrement = 0;
413 }
414 }
415 }
416 roundBits = zSig & 0x3FF;
417 if ( 0x7FD <= (bits16) zExp ) {
418 if ( ( 0x7FD < zExp )
419 || ( ( zExp == 0x7FD )
420 && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
421 ) {
422 //register int lr = __builtin_return_address(0);
423 //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
424 float_raise( float_flag_overflow | float_flag_inexact );
425 return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
426 }
427 if ( zExp < 0 ) {
428 isTiny =
429 ( float_detect_tininess == float_tininess_before_rounding )
430 || ( zExp < -1 )
431 || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
432 shift64RightJamming( zSig, - zExp, &zSig );
433 zExp = 0;
434 roundBits = zSig & 0x3FF;
435 if ( isTiny && roundBits ) float_raise( float_flag_underflow );
436 }
437 }
438 if ( roundBits ) float_exception_flags |= float_flag_inexact;
439 zSig = ( zSig + roundIncrement )>>10;
440 zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
441 if ( zSig == 0 ) zExp = 0;
442 return packFloat64( zSign, zExp, zSig );
443
444}
445
446/*
447-------------------------------------------------------------------------------
448Takes an abstract floating-point value having sign `zSign', exponent `zExp',
449and significand `zSig', and returns the proper double-precision floating-
450point value corresponding to the abstract input. This routine is just like
451`roundAndPackFloat64' except that `zSig' does not have to be normalized in
452any way. In all cases, `zExp' must be 1 less than the ``true'' floating-
453point exponent.
454-------------------------------------------------------------------------------
455*/
456static float64
457 normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
458{
459 int8 shiftCount;
460
461 shiftCount = countLeadingZeros64( zSig ) - 1;
462 return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
463
464}
465
466#ifdef FLOATX80
467
468/*
469-------------------------------------------------------------------------------
470Returns the fraction bits of the extended double-precision floating-point
471value `a'.
472-------------------------------------------------------------------------------
473*/
474INLINE bits64 extractFloatx80Frac( floatx80 a )
475{
476
477 return a.low;
478
479}
480
481/*
482-------------------------------------------------------------------------------
483Returns the exponent bits of the extended double-precision floating-point
484value `a'.
485-------------------------------------------------------------------------------
486*/
487INLINE int32 extractFloatx80Exp( floatx80 a )
488{
489
490 return a.high & 0x7FFF;
491
492}
493
494/*
495-------------------------------------------------------------------------------
496Returns the sign bit of the extended double-precision floating-point value
497`a'.
498-------------------------------------------------------------------------------
499*/
500INLINE flag extractFloatx80Sign( floatx80 a )
501{
502
503 return a.high>>15;
504
505}
506
507/*
508-------------------------------------------------------------------------------
509Normalizes the subnormal extended double-precision floating-point value
510represented by the denormalized significand `aSig'. The normalized exponent
511and significand are stored at the locations pointed to by `zExpPtr' and
512`zSigPtr', respectively.
513-------------------------------------------------------------------------------
514*/
515static void
516 normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
517{
518 int8 shiftCount;
519
520 shiftCount = countLeadingZeros64( aSig );
521 *zSigPtr = aSig<<shiftCount;
522 *zExpPtr = 1 - shiftCount;
523
524}
525
526/*
527-------------------------------------------------------------------------------
528Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
529extended double-precision floating-point value, returning the result.
530-------------------------------------------------------------------------------
531*/
532INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
533{
534 floatx80 z;
535
536 z.low = zSig;
537 z.high = ( ( (bits16) zSign )<<15 ) + zExp;
538 return z;
539
540}
541
542/*
543-------------------------------------------------------------------------------
544Takes an abstract floating-point value having sign `zSign', exponent `zExp',
545and extended significand formed by the concatenation of `zSig0' and `zSig1',
546and returns the proper extended double-precision floating-point value
547corresponding to the abstract input. Ordinarily, the abstract value is
548rounded and packed into the extended double-precision format, with the
549inexact exception raised if the abstract input cannot be represented
550exactly. If the abstract value is too large, however, the overflow and
551inexact exceptions are raised and an infinity or maximal finite value is
552returned. If the abstract value is too small, the input value is rounded to
553a subnormal number, and the underflow and inexact exceptions are raised if
554the abstract input cannot be represented exactly as a subnormal extended
555double-precision floating-point number.
556 If `roundingPrecision' is 32 or 64, the result is rounded to the same
557number of bits as single or double precision, respectively. Otherwise, the
558result is rounded to the full precision of the extended double-precision
559format.
560 The input significand must be normalized or smaller. If the input
561significand is not normalized, `zExp' must be 0; in that case, the result
562returned is a subnormal number, and it must not require rounding. The
563handling of underflow and overflow follows the IEC/IEEE Standard for Binary
564Floating-point Arithmetic.
565-------------------------------------------------------------------------------
566*/
567static floatx80
568 roundAndPackFloatx80(
569 int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
570 )
571{
572 int8 roundingMode;
573 flag roundNearestEven, increment, isTiny;
574 int64 roundIncrement, roundMask, roundBits;
575
576 roundingMode = float_rounding_mode;
577 roundNearestEven = ( roundingMode == float_round_nearest_even );
578 if ( roundingPrecision == 80 ) goto precision80;
579 if ( roundingPrecision == 64 ) {
580 roundIncrement = LIT64( 0x0000000000000400 );
581 roundMask = LIT64( 0x00000000000007FF );
582 }
583 else if ( roundingPrecision == 32 ) {
584 roundIncrement = LIT64( 0x0000008000000000 );
585 roundMask = LIT64( 0x000000FFFFFFFFFF );
586 }
587 else {
588 goto precision80;
589 }
590 zSig0 |= ( zSig1 != 0 );
591 if ( ! roundNearestEven ) {
592 if ( roundingMode == float_round_to_zero ) {
593 roundIncrement = 0;
594 }
595 else {
596 roundIncrement = roundMask;
597 if ( zSign ) {
598 if ( roundingMode == float_round_up ) roundIncrement = 0;
599 }
600 else {
601 if ( roundingMode == float_round_down ) roundIncrement = 0;
602 }
603 }
604 }
605 roundBits = zSig0 & roundMask;
606 if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
607 if ( ( 0x7FFE < zExp )
608 || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
609 ) {
610 goto overflow;
611 }
612 if ( zExp <= 0 ) {
613 isTiny =
614 ( float_detect_tininess == float_tininess_before_rounding )
615 || ( zExp < 0 )
616 || ( zSig0 <= zSig0 + roundIncrement );
617 shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
618 zExp = 0;
619 roundBits = zSig0 & roundMask;
620 if ( isTiny && roundBits ) float_raise( float_flag_underflow );
621 if ( roundBits ) float_exception_flags |= float_flag_inexact;
622 zSig0 += roundIncrement;
623 if ( (sbits64) zSig0 < 0 ) zExp = 1;
624 roundIncrement = roundMask + 1;
625 if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
626 roundMask |= roundIncrement;
627 }
628 zSig0 &= ~ roundMask;
629 return packFloatx80( zSign, zExp, zSig0 );
630 }
631 }
632 if ( roundBits ) float_exception_flags |= float_flag_inexact;
633 zSig0 += roundIncrement;
634 if ( zSig0 < roundIncrement ) {
635 ++zExp;
636 zSig0 = LIT64( 0x8000000000000000 );
637 }
638 roundIncrement = roundMask + 1;
639 if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
640 roundMask |= roundIncrement;
641 }
642 zSig0 &= ~ roundMask;
643 if ( zSig0 == 0 ) zExp = 0;
644 return packFloatx80( zSign, zExp, zSig0 );
645 precision80:
646 increment = ( (sbits64) zSig1 < 0 );
647 if ( ! roundNearestEven ) {
648 if ( roundingMode == float_round_to_zero ) {
649 increment = 0;
650 }
651 else {
652 if ( zSign ) {
653 increment = ( roundingMode == float_round_down ) && zSig1;
654 }
655 else {
656 increment = ( roundingMode == float_round_up ) && zSig1;
657 }
658 }
659 }
660 if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
661 if ( ( 0x7FFE < zExp )
662 || ( ( zExp == 0x7FFE )
663 && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
664 && increment
665 )
666 ) {
667 roundMask = 0;
668 overflow:
669 float_raise( float_flag_overflow | float_flag_inexact );
670 if ( ( roundingMode == float_round_to_zero )
671 || ( zSign && ( roundingMode == float_round_up ) )
672 || ( ! zSign && ( roundingMode == float_round_down ) )
673 ) {
674 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
675 }
676 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
677 }
678 if ( zExp <= 0 ) {
679 isTiny =
680 ( float_detect_tininess == float_tininess_before_rounding )
681 || ( zExp < 0 )
682 || ! increment
683 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
684 shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
685 zExp = 0;
686 if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
687 if ( zSig1 ) float_exception_flags |= float_flag_inexact;
688 if ( roundNearestEven ) {
689 increment = ( (sbits64) zSig1 < 0 );
690 }
691 else {
692 if ( zSign ) {
693 increment = ( roundingMode == float_round_down ) && zSig1;
694 }
695 else {
696 increment = ( roundingMode == float_round_up ) && zSig1;
697 }
698 }
699 if ( increment ) {
700 ++zSig0;
701 zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
702 if ( (sbits64) zSig0 < 0 ) zExp = 1;
703 }
704 return packFloatx80( zSign, zExp, zSig0 );
705 }
706 }
707 if ( zSig1 ) float_exception_flags |= float_flag_inexact;
708 if ( increment ) {
709 ++zSig0;
710 if ( zSig0 == 0 ) {
711 ++zExp;
712 zSig0 = LIT64( 0x8000000000000000 );
713 }
714 else {
715 zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
716 }
717 }
718 else {
719 if ( zSig0 == 0 ) zExp = 0;
720 }
721
722 return packFloatx80( zSign, zExp, zSig0 );
723}
724
725/*
726-------------------------------------------------------------------------------
727Takes an abstract floating-point value having sign `zSign', exponent
728`zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
729and returns the proper extended double-precision floating-point value
730corresponding to the abstract input. This routine is just like
731`roundAndPackFloatx80' except that the input significand does not have to be
732normalized.
733-------------------------------------------------------------------------------
734*/
735static floatx80
736 normalizeRoundAndPackFloatx80(
737 int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
738 )
739{
740 int8 shiftCount;
741
742 if ( zSig0 == 0 ) {
743 zSig0 = zSig1;
744 zSig1 = 0;
745 zExp -= 64;
746 }
747 shiftCount = countLeadingZeros64( zSig0 );
748 shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
749 zExp -= shiftCount;
750 return
751 roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
752
753}
754
755#endif
756
757/*
758-------------------------------------------------------------------------------
759Returns the result of converting the 32-bit two's complement integer `a' to
760the single-precision floating-point format. The conversion is performed
761according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
762-------------------------------------------------------------------------------
763*/
764float32 int32_to_float32( int32 a )
765{
766 flag zSign;
767
768 if ( a == 0 ) return 0;
769 if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
770 zSign = ( a < 0 );
771 return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
772
773}
774
775/*
776-------------------------------------------------------------------------------
777Returns the result of converting the 32-bit two's complement integer `a' to
778the double-precision floating-point format. The conversion is performed
779according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
780-------------------------------------------------------------------------------
781*/
782float64 int32_to_float64( int32 a )
783{
784 flag aSign;
785 uint32 absA;
786 int8 shiftCount;
787 bits64 zSig;
788
789 if ( a == 0 ) return 0;
790 aSign = ( a < 0 );
791 absA = aSign ? - a : a;
792 shiftCount = countLeadingZeros32( absA ) + 21;
793 zSig = absA;
794 return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount );
795
796}
797
798#ifdef FLOATX80
799
800/*
801-------------------------------------------------------------------------------
802Returns the result of converting the 32-bit two's complement integer `a'
803to the extended double-precision floating-point format. The conversion
804is performed according to the IEC/IEEE Standard for Binary Floating-point
805Arithmetic.
806-------------------------------------------------------------------------------
807*/
808floatx80 int32_to_floatx80( int32 a )
809{
810 flag zSign;
811 uint32 absA;
812 int8 shiftCount;
813 bits64 zSig;
814
815 if ( a == 0 ) return packFloatx80( 0, 0, 0 );
816 zSign = ( a < 0 );
817 absA = zSign ? - a : a;
818 shiftCount = countLeadingZeros32( absA ) + 32;
819 zSig = absA;
820 return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
821
822}
823
824#endif
825
826/*
827-------------------------------------------------------------------------------
828Returns the result of converting the single-precision floating-point value
829`a' to the 32-bit two's complement integer format. The conversion is
830performed according to the IEC/IEEE Standard for Binary Floating-point
831Arithmetic---which means in particular that the conversion is rounded
832according to the current rounding mode. If `a' is a NaN, the largest
833positive integer is returned. Otherwise, if the conversion overflows, the
834largest integer with the same sign as `a' is returned.
835-------------------------------------------------------------------------------
836*/
837int32 float32_to_int32( float32 a )
838{
839 flag aSign;
840 int16 aExp, shiftCount;
841 bits32 aSig;
842 bits64 zSig;
843
844 aSig = extractFloat32Frac( a );
845 aExp = extractFloat32Exp( a );
846 aSign = extractFloat32Sign( a );
847 if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
848 if ( aExp ) aSig |= 0x00800000;
849 shiftCount = 0xAF - aExp;
850 zSig = aSig;
851 zSig <<= 32;
852 if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
853 return roundAndPackInt32( aSign, zSig );
854
855}
856
857/*
858-------------------------------------------------------------------------------
859Returns the result of converting the single-precision floating-point value
860`a' to the 32-bit two's complement integer format. The conversion is
861performed according to the IEC/IEEE Standard for Binary Floating-point
862Arithmetic, except that the conversion is always rounded toward zero. If
863`a' is a NaN, the largest positive integer is returned. Otherwise, if the
864conversion overflows, the largest integer with the same sign as `a' is
865returned.
866-------------------------------------------------------------------------------
867*/
868int32 float32_to_int32_round_to_zero( float32 a )
869{
870 flag aSign;
871 int16 aExp, shiftCount;
872 bits32 aSig;
873 int32 z;
874
875 aSig = extractFloat32Frac( a );
876 aExp = extractFloat32Exp( a );
877 aSign = extractFloat32Sign( a );
878 shiftCount = aExp - 0x9E;
879 if ( 0 <= shiftCount ) {
880 if ( a == 0xCF000000 ) return 0x80000000;
881 float_raise( float_flag_invalid );
882 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
883 return 0x80000000;
884 }
885 else if ( aExp <= 0x7E ) {
886 if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
887 return 0;
888 }
889 aSig = ( aSig | 0x00800000 )<<8;
890 z = aSig>>( - shiftCount );
891 if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
892 float_exception_flags |= float_flag_inexact;
893 }
894 return aSign ? - z : z;
895
896}
897
898/*
899-------------------------------------------------------------------------------
900Returns the result of converting the single-precision floating-point value
901`a' to the double-precision floating-point format. The conversion is
902performed according to the IEC/IEEE Standard for Binary Floating-point
903Arithmetic.
904-------------------------------------------------------------------------------
905*/
906float64 float32_to_float64( float32 a )
907{
908 flag aSign;
909 int16 aExp;
910 bits32 aSig;
911
912 aSig = extractFloat32Frac( a );
913 aExp = extractFloat32Exp( a );
914 aSign = extractFloat32Sign( a );
915 if ( aExp == 0xFF ) {
916 if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
917 return packFloat64( aSign, 0x7FF, 0 );
918 }
919 if ( aExp == 0 ) {
920 if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
921 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
922 --aExp;
923 }
924 return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
925
926}
927
928#ifdef FLOATX80
929
930/*
931-------------------------------------------------------------------------------
932Returns the result of converting the single-precision floating-point value
933`a' to the extended double-precision floating-point format. The conversion
934is performed according to the IEC/IEEE Standard for Binary Floating-point
935Arithmetic.
936-------------------------------------------------------------------------------
937*/
938floatx80 float32_to_floatx80( float32 a )
939{
940 flag aSign;
941 int16 aExp;
942 bits32 aSig;
943
944 aSig = extractFloat32Frac( a );
945 aExp = extractFloat32Exp( a );
946 aSign = extractFloat32Sign( a );
947 if ( aExp == 0xFF ) {
948 if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
949 return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
950 }
951 if ( aExp == 0 ) {
952 if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
953 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
954 }
955 aSig |= 0x00800000;
956 return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
957
958}
959
960#endif
961
962/*
963-------------------------------------------------------------------------------
964Rounds the single-precision floating-point value `a' to an integer, and
965returns the result as a single-precision floating-point value. The
966operation is performed according to the IEC/IEEE Standard for Binary
967Floating-point Arithmetic.
968-------------------------------------------------------------------------------
969*/
970float32 float32_round_to_int( float32 a )
971{
972 flag aSign;
973 int16 aExp;
974 bits32 lastBitMask, roundBitsMask;
975 int8 roundingMode;
976 float32 z;
977
978 aExp = extractFloat32Exp( a );
979 if ( 0x96 <= aExp ) {
980 if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
981 return propagateFloat32NaN( a, a );
982 }
983 return a;
984 }
985 if ( aExp <= 0x7E ) {
986 if ( (bits32) ( a<<1 ) == 0 ) return a;
987 float_exception_flags |= float_flag_inexact;
988 aSign = extractFloat32Sign( a );
989 switch ( float_rounding_mode ) {
990 case float_round_nearest_even:
991 if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
992 return packFloat32( aSign, 0x7F, 0 );
993 }
994 break;
995 case float_round_down:
996 return aSign ? 0xBF800000 : 0;
997 case float_round_up:
998 return aSign ? 0x80000000 : 0x3F800000;
999 }
1000 return packFloat32( aSign, 0, 0 );
1001 }
1002 lastBitMask = 1;
1003 lastBitMask <<= 0x96 - aExp;
1004 roundBitsMask = lastBitMask - 1;
1005 z = a;
1006 roundingMode = float_rounding_mode;
1007 if ( roundingMode == float_round_nearest_even ) {
1008 z += lastBitMask>>1;
1009 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
1010 }
1011 else if ( roundingMode != float_round_to_zero ) {
1012 if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
1013 z += roundBitsMask;
1014 }
1015 }
1016 z &= ~ roundBitsMask;
1017 if ( z != a ) float_exception_flags |= float_flag_inexact;
1018 return z;
1019
1020}
1021
1022/*
1023-------------------------------------------------------------------------------
1024Returns the result of adding the absolute values of the single-precision
1025floating-point values `a' and `b'. If `zSign' is true, the sum is negated
1026before being returned. `zSign' is ignored if the result is a NaN. The
1027addition is performed according to the IEC/IEEE Standard for Binary
1028Floating-point Arithmetic.
1029-------------------------------------------------------------------------------
1030*/
1031static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
1032{
1033 int16 aExp, bExp, zExp;
1034 bits32 aSig, bSig, zSig;
1035 int16 expDiff;
1036
1037 aSig = extractFloat32Frac( a );
1038 aExp = extractFloat32Exp( a );
1039 bSig = extractFloat32Frac( b );
1040 bExp = extractFloat32Exp( b );
1041 expDiff = aExp - bExp;
1042 aSig <<= 6;
1043 bSig <<= 6;
1044 if ( 0 < expDiff ) {
1045 if ( aExp == 0xFF ) {
1046 if ( aSig ) return propagateFloat32NaN( a, b );
1047 return a;
1048 }
1049 if ( bExp == 0 ) {
1050 --expDiff;
1051 }
1052 else {
1053 bSig |= 0x20000000;
1054 }
1055 shift32RightJamming( bSig, expDiff, &bSig );
1056 zExp = aExp;
1057 }
1058 else if ( expDiff < 0 ) {
1059 if ( bExp == 0xFF ) {
1060 if ( bSig ) return propagateFloat32NaN( a, b );
1061 return packFloat32( zSign, 0xFF, 0 );
1062 }
1063 if ( aExp == 0 ) {
1064 ++expDiff;
1065 }
1066 else {
1067 aSig |= 0x20000000;
1068 }
1069 shift32RightJamming( aSig, - expDiff, &aSig );
1070 zExp = bExp;
1071 }
1072 else {
1073 if ( aExp == 0xFF ) {
1074 if ( aSig | bSig ) return propagateFloat32NaN( a, b );
1075 return a;
1076 }
1077 if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
1078 zSig = 0x40000000 + aSig + bSig;
1079 zExp = aExp;
1080 goto roundAndPack;
1081 }
1082 aSig |= 0x20000000;
1083 zSig = ( aSig + bSig )<<1;
1084 --zExp;
1085 if ( (sbits32) zSig < 0 ) {
1086 zSig = aSig + bSig;
1087 ++zExp;
1088 }
1089 roundAndPack:
1090 return roundAndPackFloat32( zSign, zExp, zSig );
1091
1092}
1093
1094/*
1095-------------------------------------------------------------------------------
1096Returns the result of subtracting the absolute values of the single-
1097precision floating-point values `a' and `b'. If `zSign' is true, the
1098difference is negated before being returned. `zSign' is ignored if the
1099result is a NaN. The subtraction is performed according to the IEC/IEEE
1100Standard for Binary Floating-point Arithmetic.
1101-------------------------------------------------------------------------------
1102*/
1103static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
1104{
1105 int16 aExp, bExp, zExp;
1106 bits32 aSig, bSig, zSig;
1107 int16 expDiff;
1108
1109 aSig = extractFloat32Frac( a );
1110 aExp = extractFloat32Exp( a );
1111 bSig = extractFloat32Frac( b );
1112 bExp = extractFloat32Exp( b );
1113 expDiff = aExp - bExp;
1114 aSig <<= 7;
1115 bSig <<= 7;
1116 if ( 0 < expDiff ) goto aExpBigger;
1117 if ( expDiff < 0 ) goto bExpBigger;
1118 if ( aExp == 0xFF ) {
1119 if ( aSig | bSig ) return propagateFloat32NaN( a, b );
1120 float_raise( float_flag_invalid );
1121 return float32_default_nan;
1122 }
1123 if ( aExp == 0 ) {
1124 aExp = 1;
1125 bExp = 1;
1126 }
1127 if ( bSig < aSig ) goto aBigger;
1128 if ( aSig < bSig ) goto bBigger;
1129 return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
1130 bExpBigger:
1131 if ( bExp == 0xFF ) {
1132 if ( bSig ) return propagateFloat32NaN( a, b );
1133 return packFloat32( zSign ^ 1, 0xFF, 0 );
1134 }
1135 if ( aExp == 0 ) {
1136 ++expDiff;
1137 }
1138 else {
1139 aSig |= 0x40000000;
1140 }
1141 shift32RightJamming( aSig, - expDiff, &aSig );
1142 bSig |= 0x40000000;
1143 bBigger:
1144 zSig = bSig - aSig;
1145 zExp = bExp;
1146 zSign ^= 1;
1147 goto normalizeRoundAndPack;
1148 aExpBigger:
1149 if ( aExp == 0xFF ) {
1150 if ( aSig ) return propagateFloat32NaN( a, b );
1151 return a;
1152 }
1153 if ( bExp == 0 ) {
1154 --expDiff;
1155 }
1156 else {
1157 bSig |= 0x40000000;
1158 }
1159 shift32RightJamming( bSig, expDiff, &bSig );
1160 aSig |= 0x40000000;
1161 aBigger:
1162 zSig = aSig - bSig;
1163 zExp = aExp;
1164 normalizeRoundAndPack:
1165 --zExp;
1166 return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
1167
1168}
1169
1170/*
1171-------------------------------------------------------------------------------
1172Returns the result of adding the single-precision floating-point values `a'
1173and `b'. The operation is performed according to the IEC/IEEE Standard for
1174Binary Floating-point Arithmetic.
1175-------------------------------------------------------------------------------
1176*/
1177float32 float32_add( float32 a, float32 b )
1178{
1179 flag aSign, bSign;
1180
1181 aSign = extractFloat32Sign( a );
1182 bSign = extractFloat32Sign( b );
1183 if ( aSign == bSign ) {
1184 return addFloat32Sigs( a, b, aSign );
1185 }
1186 else {
1187 return subFloat32Sigs( a, b, aSign );
1188 }
1189
1190}
1191
1192/*
1193-------------------------------------------------------------------------------
1194Returns the result of subtracting the single-precision floating-point values
1195`a' and `b'. The operation is performed according to the IEC/IEEE Standard
1196for Binary Floating-point Arithmetic.
1197-------------------------------------------------------------------------------
1198*/
1199float32 float32_sub( float32 a, float32 b )
1200{
1201 flag aSign, bSign;
1202
1203 aSign = extractFloat32Sign( a );
1204 bSign = extractFloat32Sign( b );
1205 if ( aSign == bSign ) {
1206 return subFloat32Sigs( a, b, aSign );
1207 }
1208 else {
1209 return addFloat32Sigs( a, b, aSign );
1210 }
1211
1212}
1213
1214/*
1215-------------------------------------------------------------------------------
1216Returns the result of multiplying the single-precision floating-point values
1217`a' and `b'. The operation is performed according to the IEC/IEEE Standard
1218for Binary Floating-point Arithmetic.
1219-------------------------------------------------------------------------------
1220*/
1221float32 float32_mul( float32 a, float32 b )
1222{
1223 flag aSign, bSign, zSign;
1224 int16 aExp, bExp, zExp;
1225 bits32 aSig, bSig;
1226 bits64 zSig64;
1227 bits32 zSig;
1228
1229 aSig = extractFloat32Frac( a );
1230 aExp = extractFloat32Exp( a );
1231 aSign = extractFloat32Sign( a );
1232 bSig = extractFloat32Frac( b );
1233 bExp = extractFloat32Exp( b );
1234 bSign = extractFloat32Sign( b );
1235 zSign = aSign ^ bSign;
1236 if ( aExp == 0xFF ) {
1237 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1238 return propagateFloat32NaN( a, b );
1239 }
1240 if ( ( bExp | bSig ) == 0 ) {
1241 float_raise( float_flag_invalid );
1242 return float32_default_nan;
1243 }
1244 return packFloat32( zSign, 0xFF, 0 );
1245 }
1246 if ( bExp == 0xFF ) {
1247 if ( bSig ) return propagateFloat32NaN( a, b );
1248 if ( ( aExp | aSig ) == 0 ) {
1249 float_raise( float_flag_invalid );
1250 return float32_default_nan;
1251 }
1252 return packFloat32( zSign, 0xFF, 0 );
1253 }
1254 if ( aExp == 0 ) {
1255 if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1256 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1257 }
1258 if ( bExp == 0 ) {
1259 if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
1260 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1261 }
1262 zExp = aExp + bExp - 0x7F;
1263 aSig = ( aSig | 0x00800000 )<<7;
1264 bSig = ( bSig | 0x00800000 )<<8;
1265 shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
1266 zSig = zSig64;
1267 if ( 0 <= (sbits32) ( zSig<<1 ) ) {
1268 zSig <<= 1;
1269 --zExp;
1270 }
1271 return roundAndPackFloat32( zSign, zExp, zSig );
1272
1273}
1274
1275/*
1276-------------------------------------------------------------------------------
1277Returns the result of dividing the single-precision floating-point value `a'
1278by the corresponding value `b'. The operation is performed according to the
1279IEC/IEEE Standard for Binary Floating-point Arithmetic.
1280-------------------------------------------------------------------------------
1281*/
1282float32 float32_div( float32 a, float32 b )
1283{
1284 flag aSign, bSign, zSign;
1285 int16 aExp, bExp, zExp;
1286 bits32 aSig, bSig, zSig;
1287
1288 aSig = extractFloat32Frac( a );
1289 aExp = extractFloat32Exp( a );
1290 aSign = extractFloat32Sign( a );
1291 bSig = extractFloat32Frac( b );
1292 bExp = extractFloat32Exp( b );
1293 bSign = extractFloat32Sign( b );
1294 zSign = aSign ^ bSign;
1295 if ( aExp == 0xFF ) {
1296 if ( aSig ) return propagateFloat32NaN( a, b );
1297 if ( bExp == 0xFF ) {
1298 if ( bSig ) return propagateFloat32NaN( a, b );
1299 float_raise( float_flag_invalid );
1300 return float32_default_nan;
1301 }
1302 return packFloat32( zSign, 0xFF, 0 );
1303 }
1304 if ( bExp == 0xFF ) {
1305 if ( bSig ) return propagateFloat32NaN( a, b );
1306 return packFloat32( zSign, 0, 0 );
1307 }
1308 if ( bExp == 0 ) {
1309 if ( bSig == 0 ) {
1310 if ( ( aExp | aSig ) == 0 ) {
1311 float_raise( float_flag_invalid );
1312 return float32_default_nan;
1313 }
1314 float_raise( float_flag_divbyzero );
1315 return packFloat32( zSign, 0xFF, 0 );
1316 }
1317 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1318 }
1319 if ( aExp == 0 ) {
1320 if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1321 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1322 }
1323 zExp = aExp - bExp + 0x7D;
1324 aSig = ( aSig | 0x00800000 )<<7;
1325 bSig = ( bSig | 0x00800000 )<<8;
1326 if ( bSig <= ( aSig + aSig ) ) {
1327 aSig >>= 1;
1328 ++zExp;
1329 }
1330 zSig = ( ( (bits64) aSig )<<32 ) / bSig;
1331 if ( ( zSig & 0x3F ) == 0 ) {
1332 zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
1333 }
1334 return roundAndPackFloat32( zSign, zExp, zSig );
1335
1336}
1337
1338/*
1339-------------------------------------------------------------------------------
1340Returns the remainder of the single-precision floating-point value `a'
1341with respect to the corresponding value `b'. The operation is performed
1342according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1343-------------------------------------------------------------------------------
1344*/
1345float32 float32_rem( float32 a, float32 b )
1346{
1347 flag aSign, bSign, zSign;
1348 int16 aExp, bExp, expDiff;
1349 bits32 aSig, bSig;
1350 bits32 q;
1351 bits64 aSig64, bSig64, q64;
1352 bits32 alternateASig;
1353 sbits32 sigMean;
1354
1355 aSig = extractFloat32Frac( a );
1356 aExp = extractFloat32Exp( a );
1357 aSign = extractFloat32Sign( a );
1358 bSig = extractFloat32Frac( b );
1359 bExp = extractFloat32Exp( b );
1360 bSign = extractFloat32Sign( b );
1361 if ( aExp == 0xFF ) {
1362 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1363 return propagateFloat32NaN( a, b );
1364 }
1365 float_raise( float_flag_invalid );
1366 return float32_default_nan;
1367 }
1368 if ( bExp == 0xFF ) {
1369 if ( bSig ) return propagateFloat32NaN( a, b );
1370 return a;
1371 }
1372 if ( bExp == 0 ) {
1373 if ( bSig == 0 ) {
1374 float_raise( float_flag_invalid );
1375 return float32_default_nan;
1376 }
1377 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1378 }
1379 if ( aExp == 0 ) {
1380 if ( aSig == 0 ) return a;
1381 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1382 }
1383 expDiff = aExp - bExp;
1384 aSig |= 0x00800000;
1385 bSig |= 0x00800000;
1386 if ( expDiff < 32 ) {
1387 aSig <<= 8;
1388 bSig <<= 8;
1389 if ( expDiff < 0 ) {
1390 if ( expDiff < -1 ) return a;
1391 aSig >>= 1;
1392 }
1393 q = ( bSig <= aSig );
1394 if ( q ) aSig -= bSig;
1395 if ( 0 < expDiff ) {
1396 q = ( ( (bits64) aSig )<<32 ) / bSig;
1397 q >>= 32 - expDiff;
1398 bSig >>= 2;
1399 aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
1400 }
1401 else {
1402 aSig >>= 2;
1403 bSig >>= 2;
1404 }
1405 }
1406 else {
1407 if ( bSig <= aSig ) aSig -= bSig;
1408 aSig64 = ( (bits64) aSig )<<40;
1409 bSig64 = ( (bits64) bSig )<<40;
1410 expDiff -= 64;
1411 while ( 0 < expDiff ) {
1412 q64 = estimateDiv128To64( aSig64, 0, bSig64 );
1413 q64 = ( 2 < q64 ) ? q64 - 2 : 0;
1414 aSig64 = - ( ( bSig * q64 )<<38 );
1415 expDiff -= 62;
1416 }
1417 expDiff += 64;
1418 q64 = estimateDiv128To64( aSig64, 0, bSig64 );
1419 q64 = ( 2 < q64 ) ? q64 - 2 : 0;
1420 q = q64>>( 64 - expDiff );
1421 bSig <<= 6;
1422 aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
1423 }
1424 do {
1425 alternateASig = aSig;
1426 ++q;
1427 aSig -= bSig;
1428 } while ( 0 <= (sbits32) aSig );
1429 sigMean = aSig + alternateASig;
1430 if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
1431 aSig = alternateASig;
1432 }
1433 zSign = ( (sbits32) aSig < 0 );
1434 if ( zSign ) aSig = - aSig;
1435 return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
1436
1437}
1438
1439/*
1440-------------------------------------------------------------------------------
1441Returns the square root of the single-precision floating-point value `a'.
1442The operation is performed according to the IEC/IEEE Standard for Binary
1443Floating-point Arithmetic.
1444-------------------------------------------------------------------------------
1445*/
1446float32 float32_sqrt( float32 a )
1447{
1448 flag aSign;
1449 int16 aExp, zExp;
1450 bits32 aSig, zSig;
1451 bits64 rem, term;
1452
1453 aSig = extractFloat32Frac( a );
1454 aExp = extractFloat32Exp( a );
1455 aSign = extractFloat32Sign( a );
1456 if ( aExp == 0xFF ) {
1457 if ( aSig ) return propagateFloat32NaN( a, 0 );
1458 if ( ! aSign ) return a;
1459 float_raise( float_flag_invalid );
1460 return float32_default_nan;
1461 }
1462 if ( aSign ) {
1463 if ( ( aExp | aSig ) == 0 ) return a;
1464 float_raise( float_flag_invalid );
1465 return float32_default_nan;
1466 }
1467 if ( aExp == 0 ) {
1468 if ( aSig == 0 ) return 0;
1469 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1470 }
1471 zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
1472 aSig = ( aSig | 0x00800000 )<<8;
1473 zSig = estimateSqrt32( aExp, aSig ) + 2;
1474 if ( ( zSig & 0x7F ) <= 5 ) {
1475 if ( zSig < 2 ) {
1476 zSig = 0xFFFFFFFF;
1477 }
1478 else {
1479 aSig >>= aExp & 1;
1480 term = ( (bits64) zSig ) * zSig;
1481 rem = ( ( (bits64) aSig )<<32 ) - term;
1482 while ( (sbits64) rem < 0 ) {
1483 --zSig;
1484 rem += ( ( (bits64) zSig )<<1 ) | 1;
1485 }
1486 zSig |= ( rem != 0 );
1487 }
1488 }
1489 shift32RightJamming( zSig, 1, &zSig );
1490 return roundAndPackFloat32( 0, zExp, zSig );
1491
1492}
1493
1494/*
1495-------------------------------------------------------------------------------
1496Returns 1 if the single-precision floating-point value `a' is equal to the
1497corresponding value `b', and 0 otherwise. The comparison is performed
1498according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1499-------------------------------------------------------------------------------
1500*/
1501flag float32_eq( float32 a, float32 b )
1502{
1503
1504 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1505 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1506 ) {
1507 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1508 float_raise( float_flag_invalid );
1509 }
1510 return 0;
1511 }
1512 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1513
1514}
1515
1516/*
1517-------------------------------------------------------------------------------
1518Returns 1 if the single-precision floating-point value `a' is less than or
1519equal to the corresponding value `b', and 0 otherwise. The comparison is
1520performed according to the IEC/IEEE Standard for Binary Floating-point
1521Arithmetic.
1522-------------------------------------------------------------------------------
1523*/
1524flag float32_le( float32 a, float32 b )
1525{
1526 flag aSign, bSign;
1527
1528 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1529 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1530 ) {
1531 float_raise( float_flag_invalid );
1532 return 0;
1533 }
1534 aSign = extractFloat32Sign( a );
1535 bSign = extractFloat32Sign( b );
1536 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1537 return ( a == b ) || ( aSign ^ ( a < b ) );
1538
1539}
1540
1541/*
1542-------------------------------------------------------------------------------
1543Returns 1 if the single-precision floating-point value `a' is less than
1544the corresponding value `b', and 0 otherwise. The comparison is performed
1545according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1546-------------------------------------------------------------------------------
1547*/
1548flag float32_lt( float32 a, float32 b )
1549{
1550 flag aSign, bSign;
1551
1552 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1553 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1554 ) {
1555 float_raise( float_flag_invalid );
1556 return 0;
1557 }
1558 aSign = extractFloat32Sign( a );
1559 bSign = extractFloat32Sign( b );
1560 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1561 return ( a != b ) && ( aSign ^ ( a < b ) );
1562
1563}
1564
1565/*
1566-------------------------------------------------------------------------------
1567Returns 1 if the single-precision floating-point value `a' is equal to the
1568corresponding value `b', and 0 otherwise. The invalid exception is raised
1569if either operand is a NaN. Otherwise, the comparison is performed
1570according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1571-------------------------------------------------------------------------------
1572*/
1573flag float32_eq_signaling( float32 a, float32 b )
1574{
1575
1576 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1577 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1578 ) {
1579 float_raise( float_flag_invalid );
1580 return 0;
1581 }
1582 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1583
1584}
1585
1586/*
1587-------------------------------------------------------------------------------
1588Returns 1 if the single-precision floating-point value `a' is less than or
1589equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
1590cause an exception. Otherwise, the comparison is performed according to the
1591IEC/IEEE Standard for Binary Floating-point Arithmetic.
1592-------------------------------------------------------------------------------
1593*/
1594flag float32_le_quiet( float32 a, float32 b )
1595{
1596 flag aSign, bSign;
1597 //int16 aExp, bExp;
1598
1599 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1600 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1601 ) {
1602 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1603 float_raise( float_flag_invalid );
1604 }
1605 return 0;
1606 }
1607 aSign = extractFloat32Sign( a );
1608 bSign = extractFloat32Sign( b );
1609 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1610 return ( a == b ) || ( aSign ^ ( a < b ) );
1611
1612}
1613
1614/*
1615-------------------------------------------------------------------------------
1616Returns 1 if the single-precision floating-point value `a' is less than
1617the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
1618exception. Otherwise, the comparison is performed according to the IEC/IEEE
1619Standard for Binary Floating-point Arithmetic.
1620-------------------------------------------------------------------------------
1621*/
1622flag float32_lt_quiet( float32 a, float32 b )
1623{
1624 flag aSign, bSign;
1625
1626 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1627 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1628 ) {
1629 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1630 float_raise( float_flag_invalid );
1631 }
1632 return 0;
1633 }
1634 aSign = extractFloat32Sign( a );
1635 bSign = extractFloat32Sign( b );
1636 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1637 return ( a != b ) && ( aSign ^ ( a < b ) );
1638
1639}
1640
1641/*
1642-------------------------------------------------------------------------------
1643Returns the result of converting the double-precision floating-point value
1644`a' to the 32-bit two's complement integer format. The conversion is
1645performed according to the IEC/IEEE Standard for Binary Floating-point
1646Arithmetic---which means in particular that the conversion is rounded
1647according to the current rounding mode. If `a' is a NaN, the largest
1648positive integer is returned. Otherwise, if the conversion overflows, the
1649largest integer with the same sign as `a' is returned.
1650-------------------------------------------------------------------------------
1651*/
1652int32 float64_to_int32( float64 a )
1653{
1654 flag aSign;
1655 int16 aExp, shiftCount;
1656 bits64 aSig;
1657
1658 aSig = extractFloat64Frac( a );
1659 aExp = extractFloat64Exp( a );
1660 aSign = extractFloat64Sign( a );
1661 if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1662 if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1663 shiftCount = 0x42C - aExp;
1664 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1665 return roundAndPackInt32( aSign, aSig );
1666
1667}
1668
1669/*
1670-------------------------------------------------------------------------------
1671Returns the result of converting the double-precision floating-point value
1672`a' to the 32-bit two's complement integer format. The conversion is
1673performed according to the IEC/IEEE Standard for Binary Floating-point
1674Arithmetic, except that the conversion is always rounded toward zero. If
1675`a' is a NaN, the largest positive integer is returned. Otherwise, if the
1676conversion overflows, the largest integer with the same sign as `a' is
1677returned.
1678-------------------------------------------------------------------------------
1679*/
1680int32 float64_to_int32_round_to_zero( float64 a )
1681{
1682 flag aSign;
1683 int16 aExp, shiftCount;
1684 bits64 aSig, savedASig;
1685 int32 z;
1686
1687 aSig = extractFloat64Frac( a );
1688 aExp = extractFloat64Exp( a );
1689 aSign = extractFloat64Sign( a );
1690 shiftCount = 0x433 - aExp;
1691 if ( shiftCount < 21 ) {
1692 if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1693 goto invalid;
1694 }
1695 else if ( 52 < shiftCount ) {
1696 if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
1697 return 0;
1698 }
1699 aSig |= LIT64( 0x0010000000000000 );
1700 savedASig = aSig;
1701 aSig >>= shiftCount;
1702 z = aSig;
1703 if ( aSign ) z = - z;
1704 if ( ( z < 0 ) ^ aSign ) {
1705 invalid:
1706 float_exception_flags |= float_flag_invalid;
1707 return aSign ? 0x80000000 : 0x7FFFFFFF;
1708 }
1709 if ( ( aSig<<shiftCount ) != savedASig ) {
1710 float_exception_flags |= float_flag_inexact;
1711 }
1712 return z;
1713
1714}
1715
1716/*
1717-------------------------------------------------------------------------------
1718Returns the result of converting the double-precision floating-point value
1719`a' to the 32-bit two's complement unsigned integer format. The conversion
1720is performed according to the IEC/IEEE Standard for Binary Floating-point
1721Arithmetic---which means in particular that the conversion is rounded
1722according to the current rounding mode. If `a' is a NaN, the largest
1723positive integer is returned. Otherwise, if the conversion overflows, the
1724largest positive integer is returned.
1725-------------------------------------------------------------------------------
1726*/
1727int32 float64_to_uint32( float64 a )
1728{
1729 flag aSign;
1730 int16 aExp, shiftCount;
1731 bits64 aSig;
1732
1733 aSig = extractFloat64Frac( a );
1734 aExp = extractFloat64Exp( a );
1735 aSign = 0; //extractFloat64Sign( a );
1736 //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1737 if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1738 shiftCount = 0x42C - aExp;
1739 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1740 return roundAndPackInt32( aSign, aSig );
1741}
1742
1743/*
1744-------------------------------------------------------------------------------
1745Returns the result of converting the double-precision floating-point value
1746`a' to the 32-bit two's complement integer format. The conversion is
1747performed according to the IEC/IEEE Standard for Binary Floating-point
1748Arithmetic, except that the conversion is always rounded toward zero. If
1749`a' is a NaN, the largest positive integer is returned. Otherwise, if the
1750conversion overflows, the largest positive integer is returned.
1751-------------------------------------------------------------------------------
1752*/
1753int32 float64_to_uint32_round_to_zero( float64 a )
1754{
1755 flag aSign;
1756 int16 aExp, shiftCount;
1757 bits64 aSig, savedASig;
1758 int32 z;
1759
1760 aSig = extractFloat64Frac( a );
1761 aExp = extractFloat64Exp( a );
1762 aSign = extractFloat64Sign( a );
1763 shiftCount = 0x433 - aExp;
1764 if ( shiftCount < 21 ) {
1765 if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1766 goto invalid;
1767 }
1768 else if ( 52 < shiftCount ) {
1769 if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
1770 return 0;
1771 }
1772 aSig |= LIT64( 0x0010000000000000 );
1773 savedASig = aSig;
1774 aSig >>= shiftCount;
1775 z = aSig;
1776 if ( aSign ) z = - z;
1777 if ( ( z < 0 ) ^ aSign ) {
1778 invalid:
1779 float_exception_flags |= float_flag_invalid;
1780 return aSign ? 0x80000000 : 0x7FFFFFFF;
1781 }
1782 if ( ( aSig<<shiftCount ) != savedASig ) {
1783 float_exception_flags |= float_flag_inexact;
1784 }
1785 return z;
1786}
1787
1788/*
1789-------------------------------------------------------------------------------
1790Returns the result of converting the double-precision floating-point value
1791`a' to the single-precision floating-point format. The conversion is
1792performed according to the IEC/IEEE Standard for Binary Floating-point
1793Arithmetic.
1794-------------------------------------------------------------------------------
1795*/
1796float32 float64_to_float32( float64 a )
1797{
1798 flag aSign;
1799 int16 aExp;
1800 bits64 aSig;
1801 bits32 zSig;
1802
1803 aSig = extractFloat64Frac( a );
1804 aExp = extractFloat64Exp( a );
1805 aSign = extractFloat64Sign( a );
1806 if ( aExp == 0x7FF ) {
1807 if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
1808 return packFloat32( aSign, 0xFF, 0 );
1809 }
1810 shift64RightJamming( aSig, 22, &aSig );
1811 zSig = aSig;
1812 if ( aExp || zSig ) {
1813 zSig |= 0x40000000;
1814 aExp -= 0x381;
1815 }
1816 return roundAndPackFloat32( aSign, aExp, zSig );
1817
1818}
1819
1820#ifdef FLOATX80
1821
1822/*
1823-------------------------------------------------------------------------------
1824Returns the result of converting the double-precision floating-point value
1825`a' to the extended double-precision floating-point format. The conversion
1826is performed according to the IEC/IEEE Standard for Binary Floating-point
1827Arithmetic.
1828-------------------------------------------------------------------------------
1829*/
1830floatx80 float64_to_floatx80( float64 a )
1831{
1832 flag aSign;
1833 int16 aExp;
1834 bits64 aSig;
1835
1836 aSig = extractFloat64Frac( a );
1837 aExp = extractFloat64Exp( a );
1838 aSign = extractFloat64Sign( a );
1839 if ( aExp == 0x7FF ) {
1840 if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
1841 return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
1842 }
1843 if ( aExp == 0 ) {
1844 if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1845 normalizeFloat64Subnormal( aSig, &aExp, &aSig );
1846 }
1847 return
1848 packFloatx80(
1849 aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
1850
1851}
1852
1853#endif
1854
1855/*
1856-------------------------------------------------------------------------------
1857Rounds the double-precision floating-point value `a' to an integer, and
1858returns the result as a double-precision floating-point value. The
1859operation is performed according to the IEC/IEEE Standard for Binary
1860Floating-point Arithmetic.
1861-------------------------------------------------------------------------------
1862*/
1863float64 float64_round_to_int( float64 a )
1864{
1865 flag aSign;
1866 int16 aExp;
1867 bits64 lastBitMask, roundBitsMask;
1868 int8 roundingMode;
1869 float64 z;
1870
1871 aExp = extractFloat64Exp( a );
1872 if ( 0x433 <= aExp ) {
1873 if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
1874 return propagateFloat64NaN( a, a );
1875 }
1876 return a;
1877 }
1878 if ( aExp <= 0x3FE ) {
1879 if ( (bits64) ( a<<1 ) == 0 ) return a;
1880 float_exception_flags |= float_flag_inexact;
1881 aSign = extractFloat64Sign( a );
1882 switch ( float_rounding_mode ) {
1883 case float_round_nearest_even:
1884 if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
1885 return packFloat64( aSign, 0x3FF, 0 );
1886 }
1887 break;
1888 case float_round_down:
1889 return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
1890 case float_round_up:
1891 return
1892 aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
1893 }
1894 return packFloat64( aSign, 0, 0 );
1895 }
1896 lastBitMask = 1;
1897 lastBitMask <<= 0x433 - aExp;
1898 roundBitsMask = lastBitMask - 1;
1899 z = a;
1900 roundingMode = float_rounding_mode;
1901 if ( roundingMode == float_round_nearest_even ) {
1902 z += lastBitMask>>1;
1903 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
1904 }
1905 else if ( roundingMode != float_round_to_zero ) {
1906 if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
1907 z += roundBitsMask;
1908 }
1909 }
1910 z &= ~ roundBitsMask;
1911 if ( z != a ) float_exception_flags |= float_flag_inexact;
1912 return z;
1913
1914}
1915
1916/*
1917-------------------------------------------------------------------------------
1918Returns the result of adding the absolute values of the double-precision
1919floating-point values `a' and `b'. If `zSign' is true, the sum is negated
1920before being returned. `zSign' is ignored if the result is a NaN. The
1921addition is performed according to the IEC/IEEE Standard for Binary
1922Floating-point Arithmetic.
1923-------------------------------------------------------------------------------
1924*/
1925static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
1926{
1927 int16 aExp, bExp, zExp;
1928 bits64 aSig, bSig, zSig;
1929 int16 expDiff;
1930
1931 aSig = extractFloat64Frac( a );
1932 aExp = extractFloat64Exp( a );
1933 bSig = extractFloat64Frac( b );
1934 bExp = extractFloat64Exp( b );
1935 expDiff = aExp - bExp;
1936 aSig <<= 9;
1937 bSig <<= 9;
1938 if ( 0 < expDiff ) {
1939 if ( aExp == 0x7FF ) {
1940 if ( aSig ) return propagateFloat64NaN( a, b );
1941 return a;
1942 }
1943 if ( bExp == 0 ) {
1944 --expDiff;
1945 }
1946 else {
1947 bSig |= LIT64( 0x2000000000000000 );
1948 }
1949 shift64RightJamming( bSig, expDiff, &bSig );
1950 zExp = aExp;
1951 }
1952 else if ( expDiff < 0 ) {
1953 if ( bExp == 0x7FF ) {
1954 if ( bSig ) return propagateFloat64NaN( a, b );
1955 return packFloat64( zSign, 0x7FF, 0 );
1956 }
1957 if ( aExp == 0 ) {
1958 ++expDiff;
1959 }
1960 else {
1961 aSig |= LIT64( 0x2000000000000000 );
1962 }
1963 shift64RightJamming( aSig, - expDiff, &aSig );
1964 zExp = bExp;
1965 }
1966 else {
1967 if ( aExp == 0x7FF ) {
1968 if ( aSig | bSig ) return propagateFloat64NaN( a, b );
1969 return a;
1970 }
1971 if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
1972 zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
1973 zExp = aExp;
1974 goto roundAndPack;
1975 }
1976 aSig |= LIT64( 0x2000000000000000 );
1977 zSig = ( aSig + bSig )<<1;
1978 --zExp;
1979 if ( (sbits64) zSig < 0 ) {
1980 zSig = aSig + bSig;
1981 ++zExp;
1982 }
1983 roundAndPack:
1984 return roundAndPackFloat64( zSign, zExp, zSig );
1985
1986}
1987
1988/*
1989-------------------------------------------------------------------------------
1990Returns the result of subtracting the absolute values of the double-
1991precision floating-point values `a' and `b'. If `zSign' is true, the
1992difference is negated before being returned. `zSign' is ignored if the
1993result is a NaN. The subtraction is performed according to the IEC/IEEE
1994Standard for Binary Floating-point Arithmetic.
1995-------------------------------------------------------------------------------
1996*/
1997static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
1998{
1999 int16 aExp, bExp, zExp;
2000 bits64 aSig, bSig, zSig;
2001 int16 expDiff;
2002
2003 aSig = extractFloat64Frac( a );
2004 aExp = extractFloat64Exp( a );
2005 bSig = extractFloat64Frac( b );
2006 bExp = extractFloat64Exp( b );
2007 expDiff = aExp - bExp;
2008 aSig <<= 10;
2009 bSig <<= 10;
2010 if ( 0 < expDiff ) goto aExpBigger;
2011 if ( expDiff < 0 ) goto bExpBigger;
2012 if ( aExp == 0x7FF ) {
2013 if ( aSig | bSig ) return propagateFloat64NaN( a, b );
2014 float_raise( float_flag_invalid );
2015 return float64_default_nan;
2016 }
2017 if ( aExp == 0 ) {
2018 aExp = 1;
2019 bExp = 1;
2020 }
2021 if ( bSig < aSig ) goto aBigger;
2022 if ( aSig < bSig ) goto bBigger;
2023 return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
2024 bExpBigger:
2025 if ( bExp == 0x7FF ) {
2026 if ( bSig ) return propagateFloat64NaN( a, b );
2027 return packFloat64( zSign ^ 1, 0x7FF, 0 );
2028 }
2029 if ( aExp == 0 ) {
2030 ++expDiff;
2031 }
2032 else {
2033 aSig |= LIT64( 0x4000000000000000 );
2034 }
2035 shift64RightJamming( aSig, - expDiff, &aSig );
2036 bSig |= LIT64( 0x4000000000000000 );
2037 bBigger:
2038 zSig = bSig - aSig;
2039 zExp = bExp;
2040 zSign ^= 1;
2041 goto normalizeRoundAndPack;
2042 aExpBigger:
2043 if ( aExp == 0x7FF ) {
2044 if ( aSig ) return propagateFloat64NaN( a, b );
2045 return a;
2046 }
2047 if ( bExp == 0 ) {
2048 --expDiff;
2049 }
2050 else {
2051 bSig |= LIT64( 0x4000000000000000 );
2052 }
2053 shift64RightJamming( bSig, expDiff, &bSig );
2054 aSig |= LIT64( 0x4000000000000000 );
2055 aBigger:
2056 zSig = aSig - bSig;
2057 zExp = aExp;
2058 normalizeRoundAndPack:
2059 --zExp;
2060 return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
2061
2062}
2063
2064/*
2065-------------------------------------------------------------------------------
2066Returns the result of adding the double-precision floating-point values `a'
2067and `b'. The operation is performed according to the IEC/IEEE Standard for
2068Binary Floating-point Arithmetic.
2069-------------------------------------------------------------------------------
2070*/
2071float64 float64_add( float64 a, float64 b )
2072{
2073 flag aSign, bSign;
2074
2075 aSign = extractFloat64Sign( a );
2076 bSign = extractFloat64Sign( b );
2077 if ( aSign == bSign ) {
2078 return addFloat64Sigs( a, b, aSign );
2079 }
2080 else {
2081 return subFloat64Sigs( a, b, aSign );
2082 }
2083
2084}
2085
2086/*
2087-------------------------------------------------------------------------------
2088Returns the result of subtracting the double-precision floating-point values
2089`a' and `b'. The operation is performed according to the IEC/IEEE Standard
2090for Binary Floating-point Arithmetic.
2091-------------------------------------------------------------------------------
2092*/
2093float64 float64_sub( float64 a, float64 b )
2094{
2095 flag aSign, bSign;
2096
2097 aSign = extractFloat64Sign( a );
2098 bSign = extractFloat64Sign( b );
2099 if ( aSign == bSign ) {
2100 return subFloat64Sigs( a, b, aSign );
2101 }
2102 else {
2103 return addFloat64Sigs( a, b, aSign );
2104 }
2105
2106}
2107
2108/*
2109-------------------------------------------------------------------------------
2110Returns the result of multiplying the double-precision floating-point values
2111`a' and `b'. The operation is performed according to the IEC/IEEE Standard
2112for Binary Floating-point Arithmetic.
2113-------------------------------------------------------------------------------
2114*/
2115float64 float64_mul( float64 a, float64 b )
2116{
2117 flag aSign, bSign, zSign;
2118 int16 aExp, bExp, zExp;
2119 bits64 aSig, bSig, zSig0, zSig1;
2120
2121 aSig = extractFloat64Frac( a );
2122 aExp = extractFloat64Exp( a );
2123 aSign = extractFloat64Sign( a );
2124 bSig = extractFloat64Frac( b );
2125 bExp = extractFloat64Exp( b );
2126 bSign = extractFloat64Sign( b );
2127 zSign = aSign ^ bSign;
2128 if ( aExp == 0x7FF ) {
2129 if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
2130 return propagateFloat64NaN( a, b );
2131 }
2132 if ( ( bExp | bSig ) == 0 ) {
2133 float_raise( float_flag_invalid );
2134 return float64_default_nan;
2135 }
2136 return packFloat64( zSign, 0x7FF, 0 );
2137 }
2138 if ( bExp == 0x7FF ) {
2139 if ( bSig ) return propagateFloat64NaN( a, b );
2140 if ( ( aExp | aSig ) == 0 ) {
2141 float_raise( float_flag_invalid );
2142 return float64_default_nan;
2143 }
2144 return packFloat64( zSign, 0x7FF, 0 );
2145 }
2146 if ( aExp == 0 ) {
2147 if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
2148 normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2149 }
2150 if ( bExp == 0 ) {
2151 if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
2152 normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2153 }
2154 zExp = aExp + bExp - 0x3FF;
2155 aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
2156 bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2157 mul64To128( aSig, bSig, &zSig0, &zSig1 );
2158 zSig0 |= ( zSig1 != 0 );
2159 if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
2160 zSig0 <<= 1;
2161 --zExp;
2162 }
2163 return roundAndPackFloat64( zSign, zExp, zSig0 );
2164
2165}
2166
2167/*
2168-------------------------------------------------------------------------------
2169Returns the result of dividing the double-precision floating-point value `a'
2170by the corresponding value `b'. The operation is performed according to
2171the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2172-------------------------------------------------------------------------------
2173*/
2174float64 float64_div( float64 a, float64 b )
2175{
2176 flag aSign, bSign, zSign;
2177 int16 aExp, bExp, zExp;
2178 bits64 aSig, bSig, zSig;
2179 bits64 rem0, rem1;
2180 bits64 term0, term1;
2181
2182 aSig = extractFloat64Frac( a );
2183 aExp = extractFloat64Exp( a );
2184 aSign = extractFloat64Sign( a );
2185 bSig = extractFloat64Frac( b );
2186 bExp = extractFloat64Exp( b );
2187 bSign = extractFloat64Sign( b );
2188 zSign = aSign ^ bSign;
2189 if ( aExp == 0x7FF ) {
2190 if ( aSig ) return propagateFloat64NaN( a, b );
2191 if ( bExp == 0x7FF ) {
2192 if ( bSig ) return propagateFloat64NaN( a, b );
2193 float_raise( float_flag_invalid );
2194 return float64_default_nan;
2195 }
2196 return packFloat64( zSign, 0x7FF, 0 );
2197 }
2198 if ( bExp == 0x7FF ) {
2199 if ( bSig ) return propagateFloat64NaN( a, b );
2200 return packFloat64( zSign, 0, 0 );
2201 }
2202 if ( bExp == 0 ) {
2203 if ( bSig == 0 ) {
2204 if ( ( aExp | aSig ) == 0 ) {
2205 float_raise( float_flag_invalid );
2206 return float64_default_nan;
2207 }
2208 float_raise( float_flag_divbyzero );
2209 return packFloat64( zSign, 0x7FF, 0 );
2210 }
2211 normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2212 }
2213 if ( aExp == 0 ) {
2214 if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
2215 normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2216 }
2217 zExp = aExp - bExp + 0x3FD;
2218 aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
2219 bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2220 if ( bSig <= ( aSig + aSig ) ) {
2221 aSig >>= 1;
2222 ++zExp;
2223 }
2224 zSig = estimateDiv128To64( aSig, 0, bSig );
2225 if ( ( zSig & 0x1FF ) <= 2 ) {
2226 mul64To128( bSig, zSig, &term0, &term1 );
2227 sub128( aSig, 0, term0, term1, &rem0, &rem1 );
2228 while ( (sbits64) rem0 < 0 ) {
2229 --zSig;
2230 add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
2231 }
2232 zSig |= ( rem1 != 0 );
2233 }
2234 return roundAndPackFloat64( zSign, zExp, zSig );
2235
2236}
2237
2238/*
2239-------------------------------------------------------------------------------
2240Returns the remainder of the double-precision floating-point value `a'
2241with respect to the corresponding value `b'. The operation is performed
2242according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2243-------------------------------------------------------------------------------
2244*/
2245float64 float64_rem( float64 a, float64 b )
2246{
2247 flag aSign, bSign, zSign;
2248 int16 aExp, bExp, expDiff;
2249 bits64 aSig, bSig;
2250 bits64 q, alternateASig;
2251 sbits64 sigMean;
2252
2253 aSig = extractFloat64Frac( a );
2254 aExp = extractFloat64Exp( a );
2255 aSign = extractFloat64Sign( a );
2256 bSig = extractFloat64Frac( b );
2257 bExp = extractFloat64Exp( b );
2258 bSign = extractFloat64Sign( b );
2259 if ( aExp == 0x7FF ) {
2260 if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
2261 return propagateFloat64NaN( a, b );
2262 }
2263 float_raise( float_flag_invalid );
2264 return float64_default_nan;
2265 }
2266 if ( bExp == 0x7FF ) {
2267 if ( bSig ) return propagateFloat64NaN( a, b );
2268 return a;
2269 }
2270 if ( bExp == 0 ) {
2271 if ( bSig == 0 ) {
2272 float_raise( float_flag_invalid );
2273 return float64_default_nan;
2274 }
2275 normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2276 }
2277 if ( aExp == 0 ) {
2278 if ( aSig == 0 ) return a;
2279 normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2280 }
2281 expDiff = aExp - bExp;
2282 aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
2283 bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2284 if ( expDiff < 0 ) {
2285 if ( expDiff < -1 ) return a;
2286 aSig >>= 1;
2287 }
2288 q = ( bSig <= aSig );
2289 if ( q ) aSig -= bSig;
2290 expDiff -= 64;
2291 while ( 0 < expDiff ) {
2292 q = estimateDiv128To64( aSig, 0, bSig );
2293 q = ( 2 < q ) ? q - 2 : 0;
2294 aSig = - ( ( bSig>>2 ) * q );
2295 expDiff -= 62;
2296 }
2297 expDiff += 64;
2298 if ( 0 < expDiff ) {
2299 q = estimateDiv128To64( aSig, 0, bSig );
2300 q = ( 2 < q ) ? q - 2 : 0;
2301 q >>= 64 - expDiff;
2302 bSig >>= 2;
2303 aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
2304 }
2305 else {
2306 aSig >>= 2;
2307 bSig >>= 2;
2308 }
2309 do {
2310 alternateASig = aSig;
2311 ++q;
2312 aSig -= bSig;
2313 } while ( 0 <= (sbits64) aSig );
2314 sigMean = aSig + alternateASig;
2315 if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
2316 aSig = alternateASig;
2317 }
2318 zSign = ( (sbits64) aSig < 0 );
2319 if ( zSign ) aSig = - aSig;
2320 return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
2321
2322}
2323
2324/*
2325-------------------------------------------------------------------------------
2326Returns the square root of the double-precision floating-point value `a'.
2327The operation is performed according to the IEC/IEEE Standard for Binary
2328Floating-point Arithmetic.
2329-------------------------------------------------------------------------------
2330*/
2331float64 float64_sqrt( float64 a )
2332{
2333 flag aSign;
2334 int16 aExp, zExp;
2335 bits64 aSig, zSig;
2336 bits64 rem0, rem1, term0, term1; //, shiftedRem;
2337 //float64 z;
2338
2339 aSig = extractFloat64Frac( a );
2340 aExp = extractFloat64Exp( a );
2341 aSign = extractFloat64Sign( a );
2342 if ( aExp == 0x7FF ) {
2343 if ( aSig ) return propagateFloat64NaN( a, a );
2344 if ( ! aSign ) return a;
2345 float_raise( float_flag_invalid );
2346 return float64_default_nan;
2347 }
2348 if ( aSign ) {
2349 if ( ( aExp | aSig ) == 0 ) return a;
2350 float_raise( float_flag_invalid );
2351 return float64_default_nan;
2352 }
2353 if ( aExp == 0 ) {
2354 if ( aSig == 0 ) return 0;
2355 normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2356 }
2357 zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
2358 aSig |= LIT64( 0x0010000000000000 );
2359 zSig = estimateSqrt32( aExp, aSig>>21 );
2360 zSig <<= 31;
2361 aSig <<= 9 - ( aExp & 1 );
2362 zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2;
2363 if ( ( zSig & 0x3FF ) <= 5 ) {
2364 if ( zSig < 2 ) {
2365 zSig = LIT64( 0xFFFFFFFFFFFFFFFF );
2366 }
2367 else {
2368 aSig <<= 2;
2369 mul64To128( zSig, zSig, &term0, &term1 );
2370 sub128( aSig, 0, term0, term1, &rem0, &rem1 );
2371 while ( (sbits64) rem0 < 0 ) {
2372 --zSig;
2373 shortShift128Left( 0, zSig, 1, &term0, &term1 );
2374 term1 |= 1;
2375 add128( rem0, rem1, term0, term1, &rem0, &rem1 );
2376 }
2377 zSig |= ( ( rem0 | rem1 ) != 0 );
2378 }
2379 }
2380 shift64RightJamming( zSig, 1, &zSig );
2381 return roundAndPackFloat64( 0, zExp, zSig );
2382
2383}
2384
2385/*
2386-------------------------------------------------------------------------------
2387Returns 1 if the double-precision floating-point value `a' is equal to the
2388corresponding value `b', and 0 otherwise. The comparison is performed
2389according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2390-------------------------------------------------------------------------------
2391*/
2392flag float64_eq( float64 a, float64 b )
2393{
2394
2395 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2396 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2397 ) {
2398 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2399 float_raise( float_flag_invalid );
2400 }
2401 return 0;
2402 }
2403 return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
2404
2405}
2406
2407/*
2408-------------------------------------------------------------------------------
2409Returns 1 if the double-precision floating-point value `a' is less than or
2410equal to the corresponding value `b', and 0 otherwise. The comparison is
2411performed according to the IEC/IEEE Standard for Binary Floating-point
2412Arithmetic.
2413-------------------------------------------------------------------------------
2414*/
2415flag float64_le( float64 a, float64 b )
2416{
2417 flag aSign, bSign;
2418
2419 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2420 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2421 ) {
2422 float_raise( float_flag_invalid );
2423 return 0;
2424 }
2425 aSign = extractFloat64Sign( a );
2426 bSign = extractFloat64Sign( b );
2427 if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
2428 return ( a == b ) || ( aSign ^ ( a < b ) );
2429
2430}
2431
2432/*
2433-------------------------------------------------------------------------------
2434Returns 1 if the double-precision floating-point value `a' is less than
2435the corresponding value `b', and 0 otherwise. The comparison is performed
2436according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2437-------------------------------------------------------------------------------
2438*/
2439flag float64_lt( float64 a, float64 b )
2440{
2441 flag aSign, bSign;
2442
2443 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2444 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2445 ) {
2446 float_raise( float_flag_invalid );
2447 return 0;
2448 }
2449 aSign = extractFloat64Sign( a );
2450 bSign = extractFloat64Sign( b );
2451 if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
2452 return ( a != b ) && ( aSign ^ ( a < b ) );
2453
2454}
2455
2456/*
2457-------------------------------------------------------------------------------
2458Returns 1 if the double-precision floating-point value `a' is equal to the
2459corresponding value `b', and 0 otherwise. The invalid exception is raised
2460if either operand is a NaN. Otherwise, the comparison is performed
2461according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2462-------------------------------------------------------------------------------
2463*/
2464flag float64_eq_signaling( float64 a, float64 b )
2465{
2466
2467 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2468 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2469 ) {
2470 float_raise( float_flag_invalid );
2471 return 0;
2472 }
2473 return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
2474
2475}
2476
2477/*
2478-------------------------------------------------------------------------------
2479Returns 1 if the double-precision floating-point value `a' is less than or
2480equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
2481cause an exception. Otherwise, the comparison is performed according to the
2482IEC/IEEE Standard for Binary Floating-point Arithmetic.
2483-------------------------------------------------------------------------------
2484*/
2485flag float64_le_quiet( float64 a, float64 b )
2486{
2487 flag aSign, bSign;
2488 //int16 aExp, bExp;
2489
2490 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2491 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2492 ) {
2493 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2494 float_raise( float_flag_invalid );
2495 }
2496 return 0;
2497 }
2498 aSign = extractFloat64Sign( a );
2499 bSign = extractFloat64Sign( b );
2500 if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
2501 return ( a == b ) || ( aSign ^ ( a < b ) );
2502
2503}
2504
2505/*
2506-------------------------------------------------------------------------------
2507Returns 1 if the double-precision floating-point value `a' is less than
2508the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
2509exception. Otherwise, the comparison is performed according to the IEC/IEEE
2510Standard for Binary Floating-point Arithmetic.
2511-------------------------------------------------------------------------------
2512*/
2513flag float64_lt_quiet( float64 a, float64 b )
2514{
2515 flag aSign, bSign;
2516
2517 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2518 || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2519 ) {
2520 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2521 float_raise( float_flag_invalid );
2522 }
2523 return 0;
2524 }
2525 aSign = extractFloat64Sign( a );
2526 bSign = extractFloat64Sign( b );
2527 if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
2528 return ( a != b ) && ( aSign ^ ( a < b ) );
2529
2530}
2531
2532#ifdef FLOATX80
2533
2534/*
2535-------------------------------------------------------------------------------
2536Returns the result of converting the extended double-precision floating-
2537point value `a' to the 32-bit two's complement integer format. The
2538conversion is performed according to the IEC/IEEE Standard for Binary
2539Floating-point Arithmetic---which means in particular that the conversion
2540is rounded according to the current rounding mode. If `a' is a NaN, the
2541largest positive integer is returned. Otherwise, if the conversion
2542overflows, the largest integer with the same sign as `a' is returned.
2543-------------------------------------------------------------------------------
2544*/
2545int32 floatx80_to_int32( floatx80 a )
2546{
2547 flag aSign;
2548 int32 aExp, shiftCount;
2549 bits64 aSig;
2550
2551 aSig = extractFloatx80Frac( a );
2552 aExp = extractFloatx80Exp( a );
2553 aSign = extractFloatx80Sign( a );
2554 if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
2555 shiftCount = 0x4037 - aExp;
2556 if ( shiftCount <= 0 ) shiftCount = 1;
2557 shift64RightJamming( aSig, shiftCount, &aSig );
2558 return roundAndPackInt32( aSign, aSig );
2559
2560}
2561
2562/*
2563-------------------------------------------------------------------------------
2564Returns the result of converting the extended double-precision floating-
2565point value `a' to the 32-bit two's complement integer format. The
2566conversion is performed according to the IEC/IEEE Standard for Binary
2567Floating-point Arithmetic, except that the conversion is always rounded
2568toward zero. If `a' is a NaN, the largest positive integer is returned.
2569Otherwise, if the conversion overflows, the largest integer with the same
2570sign as `a' is returned.
2571-------------------------------------------------------------------------------
2572*/
2573int32 floatx80_to_int32_round_to_zero( floatx80 a )
2574{
2575 flag aSign;
2576 int32 aExp, shiftCount;
2577 bits64 aSig, savedASig;
2578 int32 z;
2579
2580 aSig = extractFloatx80Frac( a );
2581 aExp = extractFloatx80Exp( a );
2582 aSign = extractFloatx80Sign( a );
2583 shiftCount = 0x403E - aExp;
2584 if ( shiftCount < 32 ) {
2585 if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
2586 goto invalid;
2587 }
2588 else if ( 63 < shiftCount ) {
2589 if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
2590 return 0;
2591 }
2592 savedASig = aSig;
2593 aSig >>= shiftCount;
2594 z = aSig;
2595 if ( aSign ) z = - z;
2596 if ( ( z < 0 ) ^ aSign ) {
2597 invalid:
2598 float_exception_flags |= float_flag_invalid;
2599 return aSign ? 0x80000000 : 0x7FFFFFFF;
2600 }
2601 if ( ( aSig<<shiftCount ) != savedASig ) {
2602 float_exception_flags |= float_flag_inexact;
2603 }
2604 return z;
2605
2606}
2607
2608/*
2609-------------------------------------------------------------------------------
2610Returns the result of converting the extended double-precision floating-
2611point value `a' to the single-precision floating-point format. The
2612conversion is performed according to the IEC/IEEE Standard for Binary
2613Floating-point Arithmetic.
2614-------------------------------------------------------------------------------
2615*/
2616float32 floatx80_to_float32( floatx80 a )
2617{
2618 flag aSign;
2619 int32 aExp;
2620 bits64 aSig;
2621
2622 aSig = extractFloatx80Frac( a );
2623 aExp = extractFloatx80Exp( a );
2624 aSign = extractFloatx80Sign( a );
2625 if ( aExp == 0x7FFF ) {
2626 if ( (bits64) ( aSig<<1 ) ) {
2627 return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
2628 }
2629 return packFloat32( aSign, 0xFF, 0 );
2630 }
2631 shift64RightJamming( aSig, 33, &aSig );
2632 if ( aExp || aSig ) aExp -= 0x3F81;
2633 return roundAndPackFloat32( aSign, aExp, aSig );
2634
2635}
2636
2637/*
2638-------------------------------------------------------------------------------
2639Returns the result of converting the extended double-precision floating-
2640point value `a' to the double-precision floating-point format. The
2641conversion is performed according to the IEC/IEEE Standard for Binary
2642Floating-point Arithmetic.
2643-------------------------------------------------------------------------------
2644*/
2645float64 floatx80_to_float64( floatx80 a )
2646{
2647 flag aSign;
2648 int32 aExp;
2649 bits64 aSig, zSig;
2650
2651 aSig = extractFloatx80Frac( a );
2652 aExp = extractFloatx80Exp( a );
2653 aSign = extractFloatx80Sign( a );
2654 if ( aExp == 0x7FFF ) {
2655 if ( (bits64) ( aSig<<1 ) ) {
2656 return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
2657 }
2658 return packFloat64( aSign, 0x7FF, 0 );
2659 }
2660 shift64RightJamming( aSig, 1, &zSig );
2661 if ( aExp || aSig ) aExp -= 0x3C01;
2662 return roundAndPackFloat64( aSign, aExp, zSig );
2663
2664}
2665
2666/*
2667-------------------------------------------------------------------------------
2668Rounds the extended double-precision floating-point value `a' to an integer,
2669and returns the result as an extended quadruple-precision floating-point
2670value. The operation is performed according to the IEC/IEEE Standard for
2671Binary Floating-point Arithmetic.
2672-------------------------------------------------------------------------------
2673*/
2674floatx80 floatx80_round_to_int( floatx80 a )
2675{
2676 flag aSign;
2677 int32 aExp;
2678 bits64 lastBitMask, roundBitsMask;
2679 int8 roundingMode;
2680 floatx80 z;
2681
2682 aExp = extractFloatx80Exp( a );
2683 if ( 0x403E <= aExp ) {
2684 if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
2685 return propagateFloatx80NaN( a, a );
2686 }
2687 return a;
2688 }
2689 if ( aExp <= 0x3FFE ) {
2690 if ( ( aExp == 0 )
2691 && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
2692 return a;
2693 }
2694 float_exception_flags |= float_flag_inexact;
2695 aSign = extractFloatx80Sign( a );
2696 switch ( float_rounding_mode ) {
2697 case float_round_nearest_even:
2698 if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
2699 ) {
2700 return
2701 packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
2702 }
2703 break;
2704 case float_round_down:
2705 return
2706 aSign ?
2707 packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
2708 : packFloatx80( 0, 0, 0 );
2709 case float_round_up:
2710 return
2711 aSign ? packFloatx80( 1, 0, 0 )
2712 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
2713 }
2714 return packFloatx80( aSign, 0, 0 );
2715 }
2716 lastBitMask = 1;
2717 lastBitMask <<= 0x403E - aExp;
2718 roundBitsMask = lastBitMask - 1;
2719 z = a;
2720 roundingMode = float_rounding_mode;
2721 if ( roundingMode == float_round_nearest_even ) {
2722 z.low += lastBitMask>>1;
2723 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
2724 }
2725 else if ( roundingMode != float_round_to_zero ) {
2726 if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
2727 z.low += roundBitsMask;
2728 }
2729 }
2730 z.low &= ~ roundBitsMask;
2731 if ( z.low == 0 ) {
2732 ++z.high;
2733 z.low = LIT64( 0x8000000000000000 );
2734 }
2735 if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
2736 return z;
2737
2738}
2739
2740/*
2741-------------------------------------------------------------------------------
2742Returns the result of adding the absolute values of the extended double-
2743precision floating-point values `a' and `b'. If `zSign' is true, the sum is
2744negated before being returned. `zSign' is ignored if the result is a NaN.
2745The addition is performed according to the IEC/IEEE Standard for Binary
2746Floating-point Arithmetic.
2747-------------------------------------------------------------------------------
2748*/
2749static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
2750{
2751 int32 aExp, bExp, zExp;
2752 bits64 aSig, bSig, zSig0, zSig1;
2753 int32 expDiff;
2754
2755 aSig = extractFloatx80Frac( a );
2756 aExp = extractFloatx80Exp( a );
2757 bSig = extractFloatx80Frac( b );
2758 bExp = extractFloatx80Exp( b );
2759 expDiff = aExp - bExp;
2760 if ( 0 < expDiff ) {
2761 if ( aExp == 0x7FFF ) {
2762 if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
2763 return a;
2764 }
2765 if ( bExp == 0 ) --expDiff;
2766 shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2767 zExp = aExp;
2768 }
2769 else if ( expDiff < 0 ) {
2770 if ( bExp == 0x7FFF ) {
2771 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2772 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2773 }
2774 if ( aExp == 0 ) ++expDiff;
2775 shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2776 zExp = bExp;
2777 }
2778 else {
2779 if ( aExp == 0x7FFF ) {
2780 if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
2781 return propagateFloatx80NaN( a, b );
2782 }
2783 return a;
2784 }
2785 zSig1 = 0;
2786 zSig0 = aSig + bSig;
2787 if ( aExp == 0 ) {
2788 normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
2789 goto roundAndPack;
2790 }
2791 zExp = aExp;
2792 goto shiftRight1;
2793 }
2794
2795 zSig0 = aSig + bSig;
2796
2797 if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
2798 shiftRight1:
2799 shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
2800 zSig0 |= LIT64( 0x8000000000000000 );
2801 ++zExp;
2802 roundAndPack:
2803 return
2804 roundAndPackFloatx80(
2805 floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
2806
2807}
2808
2809/*
2810-------------------------------------------------------------------------------
2811Returns the result of subtracting the absolute values of the extended
2812double-precision floating-point values `a' and `b'. If `zSign' is true,
2813the difference is negated before being returned. `zSign' is ignored if the
2814result is a NaN. The subtraction is performed according to the IEC/IEEE
2815Standard for Binary Floating-point Arithmetic.
2816-------------------------------------------------------------------------------
2817*/
2818static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
2819{
2820 int32 aExp, bExp, zExp;
2821 bits64 aSig, bSig, zSig0, zSig1;
2822 int32 expDiff;
2823 floatx80 z;
2824
2825 aSig = extractFloatx80Frac( a );
2826 aExp = extractFloatx80Exp( a );
2827 bSig = extractFloatx80Frac( b );
2828 bExp = extractFloatx80Exp( b );
2829 expDiff = aExp - bExp;
2830 if ( 0 < expDiff ) goto aExpBigger;
2831 if ( expDiff < 0 ) goto bExpBigger;
2832 if ( aExp == 0x7FFF ) {
2833 if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
2834 return propagateFloatx80NaN( a, b );
2835 }
2836 float_raise( float_flag_invalid );
2837 z.low = floatx80_default_nan_low;
2838 z.high = floatx80_default_nan_high;
2839 return z;
2840 }
2841 if ( aExp == 0 ) {
2842 aExp = 1;
2843 bExp = 1;
2844 }
2845 zSig1 = 0;
2846 if ( bSig < aSig ) goto aBigger;
2847 if ( aSig < bSig ) goto bBigger;
2848 return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
2849 bExpBigger:
2850 if ( bExp == 0x7FFF ) {
2851 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2852 return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
2853 }
2854 if ( aExp == 0 ) ++expDiff;
2855 shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2856 bBigger:
2857 sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
2858 zExp = bExp;
2859 zSign ^= 1;
2860 goto normalizeRoundAndPack;
2861 aExpBigger:
2862 if ( aExp == 0x7FFF ) {
2863 if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
2864 return a;
2865 }
2866 if ( bExp == 0 ) --expDiff;
2867 shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2868 aBigger:
2869 sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
2870 zExp = aExp;
2871 normalizeRoundAndPack:
2872 return
2873 normalizeRoundAndPackFloatx80(
2874 floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
2875
2876}
2877
2878/*
2879-------------------------------------------------------------------------------
2880Returns the result of adding the extended double-precision floating-point
2881values `a' and `b'. The operation is performed according to the IEC/IEEE
2882Standard for Binary Floating-point Arithmetic.
2883-------------------------------------------------------------------------------
2884*/
2885floatx80 floatx80_add( floatx80 a, floatx80 b )
2886{
2887 flag aSign, bSign;
2888
2889 aSign = extractFloatx80Sign( a );
2890 bSign = extractFloatx80Sign( b );
2891 if ( aSign == bSign ) {
2892 return addFloatx80Sigs( a, b, aSign );
2893 }
2894 else {
2895 return subFloatx80Sigs( a, b, aSign );
2896 }
2897
2898}
2899
2900/*
2901-------------------------------------------------------------------------------
2902Returns the result of subtracting the extended double-precision floating-
2903point values `a' and `b'. The operation is performed according to the
2904IEC/IEEE Standard for Binary Floating-point Arithmetic.
2905-------------------------------------------------------------------------------
2906*/
2907floatx80 floatx80_sub( floatx80 a, floatx80 b )
2908{
2909 flag aSign, bSign;
2910
2911 aSign = extractFloatx80Sign( a );
2912 bSign = extractFloatx80Sign( b );
2913 if ( aSign == bSign ) {
2914 return subFloatx80Sigs( a, b, aSign );
2915 }
2916 else {
2917 return addFloatx80Sigs( a, b, aSign );
2918 }
2919
2920}
2921
2922/*
2923-------------------------------------------------------------------------------
2924Returns the result of multiplying the extended double-precision floating-
2925point values `a' and `b'. The operation is performed according to the
2926IEC/IEEE Standard for Binary Floating-point Arithmetic.
2927-------------------------------------------------------------------------------
2928*/
2929floatx80 floatx80_mul( floatx80 a, floatx80 b )
2930{
2931 flag aSign, bSign, zSign;
2932 int32 aExp, bExp, zExp;
2933 bits64 aSig, bSig, zSig0, zSig1;
2934 floatx80 z;
2935
2936 aSig = extractFloatx80Frac( a );
2937 aExp = extractFloatx80Exp( a );
2938 aSign = extractFloatx80Sign( a );
2939 bSig = extractFloatx80Frac( b );
2940 bExp = extractFloatx80Exp( b );
2941 bSign = extractFloatx80Sign( b );
2942 zSign = aSign ^ bSign;
2943 if ( aExp == 0x7FFF ) {
2944 if ( (bits64) ( aSig<<1 )
2945 || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
2946 return propagateFloatx80NaN( a, b );
2947 }
2948 if ( ( bExp | bSig ) == 0 ) goto invalid;
2949 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2950 }
2951 if ( bExp == 0x7FFF ) {
2952 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2953 if ( ( aExp | aSig ) == 0 ) {
2954 invalid:
2955 float_raise( float_flag_invalid );
2956 z.low = floatx80_default_nan_low;
2957 z.high = floatx80_default_nan_high;
2958 return z;
2959 }
2960 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2961 }
2962 if ( aExp == 0 ) {
2963 if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2964 normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2965 }
2966 if ( bExp == 0 ) {
2967 if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
2968 normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2969 }
2970 zExp = aExp + bExp - 0x3FFE;
2971 mul64To128( aSig, bSig, &zSig0, &zSig1 );
2972 if ( 0 < (sbits64) zSig0 ) {
2973 shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
2974 --zExp;
2975 }
2976 return
2977 roundAndPackFloatx80(
2978 floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
2979
2980}
2981
2982/*
2983-------------------------------------------------------------------------------
2984Returns the result of dividing the extended double-precision floating-point
2985value `a' by the corresponding value `b'. The operation is performed
2986according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2987-------------------------------------------------------------------------------
2988*/
2989floatx80 floatx80_div( floatx80 a, floatx80 b )
2990{
2991 flag aSign, bSign, zSign;
2992 int32 aExp, bExp, zExp;
2993 bits64 aSig, bSig, zSig0, zSig1;
2994 bits64 rem0, rem1, rem2, term0, term1, term2;
2995 floatx80 z;
2996
2997 aSig = extractFloatx80Frac( a );
2998 aExp = extractFloatx80Exp( a );
2999 aSign = extractFloatx80Sign( a );
3000 bSig = extractFloatx80Frac( b );
3001 bExp = extractFloatx80Exp( b );
3002 bSign = extractFloatx80Sign( b );
3003 zSign = aSign ^ bSign;
3004 if ( aExp == 0x7FFF ) {
3005 if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
3006 if ( bExp == 0x7FFF ) {
3007 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3008 goto invalid;
3009 }
3010 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3011 }
3012 if ( bExp == 0x7FFF ) {
3013 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3014 return packFloatx80( zSign, 0, 0 );
3015 }
3016 if ( bExp == 0 ) {
3017 if ( bSig == 0 ) {
3018 if ( ( aExp | aSig ) == 0 ) {
3019 invalid:
3020 float_raise( float_flag_invalid );
3021 z.low = floatx80_default_nan_low;
3022 z.high = floatx80_default_nan_high;
3023 return z;
3024 }
3025 float_raise( float_flag_divbyzero );
3026 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3027 }
3028 normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
3029 }
3030 if ( aExp == 0 ) {
3031 if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
3032 normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3033 }
3034 zExp = aExp - bExp + 0x3FFE;
3035 rem1 = 0;
3036 if ( bSig <= aSig ) {
3037 shift128Right( aSig, 0, 1, &aSig, &rem1 );
3038 ++zExp;
3039 }
3040 zSig0 = estimateDiv128To64( aSig, rem1, bSig );
3041 mul64To128( bSig, zSig0, &term0, &term1 );
3042 sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
3043 while ( (sbits64) rem0 < 0 ) {
3044 --zSig0;
3045 add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
3046 }
3047 zSig1 = estimateDiv128To64( rem1, 0, bSig );
3048 if ( (bits64) ( zSig1<<1 ) <= 8 ) {
3049 mul64To128( bSig, zSig1, &term1, &term2 );
3050 sub128( rem1, 0, term1, term2, &rem1, &rem2 );
3051 while ( (sbits64) rem1 < 0 ) {
3052 --zSig1;
3053 add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
3054 }
3055 zSig1 |= ( ( rem1 | rem2 ) != 0 );
3056 }
3057 return
3058 roundAndPackFloatx80(
3059 floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
3060
3061}
3062
3063/*
3064-------------------------------------------------------------------------------
3065Returns the remainder of the extended double-precision floating-point value
3066`a' with respect to the corresponding value `b'. The operation is performed
3067according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3068-------------------------------------------------------------------------------
3069*/
3070floatx80 floatx80_rem( floatx80 a, floatx80 b )
3071{
3072 flag aSign, bSign, zSign;
3073 int32 aExp, bExp, expDiff;
3074 bits64 aSig0, aSig1, bSig;
3075 bits64 q, term0, term1, alternateASig0, alternateASig1;
3076 floatx80 z;
3077
3078 aSig0 = extractFloatx80Frac( a );
3079 aExp = extractFloatx80Exp( a );
3080 aSign = extractFloatx80Sign( a );
3081 bSig = extractFloatx80Frac( b );
3082 bExp = extractFloatx80Exp( b );
3083 bSign = extractFloatx80Sign( b );
3084 if ( aExp == 0x7FFF ) {
3085 if ( (bits64) ( aSig0<<1 )
3086 || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
3087 return propagateFloatx80NaN( a, b );
3088 }
3089 goto invalid;
3090 }
3091 if ( bExp == 0x7FFF ) {
3092 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3093 return a;
3094 }
3095 if ( bExp == 0 ) {
3096 if ( bSig == 0 ) {
3097 invalid:
3098 float_raise( float_flag_invalid );
3099 z.low = floatx80_default_nan_low;
3100 z.high = floatx80_default_nan_high;
3101 return z;
3102 }
3103 normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
3104 }
3105 if ( aExp == 0 ) {
3106 if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
3107 normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3108 }
3109 bSig |= LIT64( 0x8000000000000000 );
3110 zSign = aSign;
3111 expDiff = aExp - bExp;
3112 aSig1 = 0;
3113 if ( expDiff < 0 ) {
3114 if ( expDiff < -1 ) return a;
3115 shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
3116 expDiff = 0;
3117 }
3118 q = ( bSig <= aSig0 );
3119 if ( q ) aSig0 -= bSig;
3120 expDiff -= 64;
3121 while ( 0 < expDiff ) {
3122 q = estimateDiv128To64( aSig0, aSig1, bSig );
3123 q = ( 2 < q ) ? q - 2 : 0;
3124 mul64To128( bSig, q, &term0, &term1 );
3125 sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3126 shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
3127 expDiff -= 62;
3128 }
3129 expDiff += 64;
3130 if ( 0 < expDiff ) {
3131 q = estimateDiv128To64( aSig0, aSig1, bSig );
3132 q = ( 2 < q ) ? q - 2 : 0;
3133 q >>= 64 - expDiff;
3134 mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
3135 sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3136 shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
3137 while ( le128( term0, term1, aSig0, aSig1 ) ) {
3138 ++q;
3139 sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3140 }
3141 }
3142 else {
3143 term1 = 0;
3144 term0 = bSig;
3145 }
3146 sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
3147 if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
3148 || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
3149 && ( q & 1 ) )
3150 ) {
3151 aSig0 = alternateASig0;
3152 aSig1 = alternateASig1;
3153 zSign = ! zSign;
3154 }
3155 return
3156 normalizeRoundAndPackFloatx80(
3157 80, zSign, bExp + expDiff, aSig0, aSig1 );
3158
3159}
3160
3161/*
3162-------------------------------------------------------------------------------
3163Returns the square root of the extended double-precision floating-point
3164value `a'. The operation is performed according to the IEC/IEEE Standard
3165for Binary Floating-point Arithmetic.
3166-------------------------------------------------------------------------------
3167*/
3168floatx80 floatx80_sqrt( floatx80 a )
3169{
3170 flag aSign;
3171 int32 aExp, zExp;
3172 bits64 aSig0, aSig1, zSig0, zSig1;
3173 bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
3174 bits64 shiftedRem0, shiftedRem1;
3175 floatx80 z;
3176
3177 aSig0 = extractFloatx80Frac( a );
3178 aExp = extractFloatx80Exp( a );
3179 aSign = extractFloatx80Sign( a );
3180 if ( aExp == 0x7FFF ) {
3181 if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
3182 if ( ! aSign ) return a;
3183 goto invalid;
3184 }
3185 if ( aSign ) {
3186 if ( ( aExp | aSig0 ) == 0 ) return a;
3187 invalid:
3188 float_raise( float_flag_invalid );
3189 z.low = floatx80_default_nan_low;
3190 z.high = floatx80_default_nan_high;
3191 return z;
3192 }
3193 if ( aExp == 0 ) {
3194 if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
3195 normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3196 }
3197 zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
3198 zSig0 = estimateSqrt32( aExp, aSig0>>32 );
3199 zSig0 <<= 31;
3200 aSig1 = 0;
3201 shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
3202 zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
3203 if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
3204 shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
3205 mul64To128( zSig0, zSig0, &term0, &term1 );
3206 sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
3207 while ( (sbits64) rem0 < 0 ) {
3208 --zSig0;
3209 shortShift128Left( 0, zSig0, 1, &term0, &term1 );
3210 term1 |= 1;
3211 add128( rem0, rem1, term0, term1, &rem0, &rem1 );
3212 }
3213 shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
3214 zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
3215 if ( (bits64) ( zSig1<<1 ) <= 10 ) {
3216 if ( zSig1 == 0 ) zSig1 = 1;
3217 mul64To128( zSig0, zSig1, &term1, &term2 );
3218 shortShift128Left( term1, term2, 1, &term1, &term2 );
3219 sub128( rem1, 0, term1, term2, &rem1, &rem2 );
3220 mul64To128( zSig1, zSig1, &term2, &term3 );
3221 sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
3222 while ( (sbits64) rem1 < 0 ) {
3223 --zSig1;
3224 shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
3225 term3 |= 1;
3226 add192(
3227 rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
3228 }
3229 zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
3230 }
3231 return
3232 roundAndPackFloatx80(
3233 floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
3234
3235}
3236
3237/*
3238-------------------------------------------------------------------------------
3239Returns 1 if the extended double-precision floating-point value `a' is
3240equal to the corresponding value `b', and 0 otherwise. The comparison is
3241performed according to the IEC/IEEE Standard for Binary Floating-point
3242Arithmetic.
3243-------------------------------------------------------------------------------
3244*/
3245flag floatx80_eq( floatx80 a, floatx80 b )
3246{
3247
3248 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3249 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3250 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3251 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3252 ) {
3253 if ( floatx80_is_signaling_nan( a )
3254 || floatx80_is_signaling_nan( b ) ) {
3255 float_raise( float_flag_invalid );
3256 }
3257 return 0;
3258 }
3259 return
3260 ( a.low == b.low )
3261 && ( ( a.high == b.high )
3262 || ( ( a.low == 0 )
3263 && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
3264 );
3265
3266}
3267
3268/*
3269-------------------------------------------------------------------------------
3270Returns 1 if the extended double-precision floating-point value `a' is
3271less than or equal to the corresponding value `b', and 0 otherwise. The
3272comparison is performed according to the IEC/IEEE Standard for Binary
3273Floating-point Arithmetic.
3274-------------------------------------------------------------------------------
3275*/
3276flag floatx80_le( floatx80 a, floatx80 b )
3277{
3278 flag aSign, bSign;
3279
3280 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3281 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3282 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3283 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3284 ) {
3285 float_raise( float_flag_invalid );
3286 return 0;
3287 }
3288 aSign = extractFloatx80Sign( a );
3289 bSign = extractFloatx80Sign( b );
3290 if ( aSign != bSign ) {
3291 return
3292 aSign
3293 || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3294 == 0 );
3295 }
3296 return
3297 aSign ? le128( b.high, b.low, a.high, a.low )
3298 : le128( a.high, a.low, b.high, b.low );
3299
3300}
3301
3302/*
3303-------------------------------------------------------------------------------
3304Returns 1 if the extended double-precision floating-point value `a' is
3305less than the corresponding value `b', and 0 otherwise. The comparison
3306is performed according to the IEC/IEEE Standard for Binary Floating-point
3307Arithmetic.
3308-------------------------------------------------------------------------------
3309*/
3310flag floatx80_lt( floatx80 a, floatx80 b )
3311{
3312 flag aSign, bSign;
3313
3314 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3315 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3316 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3317 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3318 ) {
3319 float_raise( float_flag_invalid );
3320 return 0;
3321 }
3322 aSign = extractFloatx80Sign( a );
3323 bSign = extractFloatx80Sign( b );
3324 if ( aSign != bSign ) {
3325 return
3326 aSign
3327 && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3328 != 0 );
3329 }
3330 return
3331 aSign ? lt128( b.high, b.low, a.high, a.low )
3332 : lt128( a.high, a.low, b.high, b.low );
3333
3334}
3335
3336/*
3337-------------------------------------------------------------------------------
3338Returns 1 if the extended double-precision floating-point value `a' is equal
3339to the corresponding value `b', and 0 otherwise. The invalid exception is
3340raised if either operand is a NaN. Otherwise, the comparison is performed
3341according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3342-------------------------------------------------------------------------------
3343*/
3344flag floatx80_eq_signaling( floatx80 a, floatx80 b )
3345{
3346
3347 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3348 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3349 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3350 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3351 ) {
3352 float_raise( float_flag_invalid );
3353 return 0;
3354 }
3355 return
3356 ( a.low == b.low )
3357 && ( ( a.high == b.high )
3358 || ( ( a.low == 0 )
3359 && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
3360 );
3361
3362}
3363
3364/*
3365-------------------------------------------------------------------------------
3366Returns 1 if the extended double-precision floating-point value `a' is less
3367than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
3368do not cause an exception. Otherwise, the comparison is performed according
3369to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3370-------------------------------------------------------------------------------
3371*/
3372flag floatx80_le_quiet( floatx80 a, floatx80 b )
3373{
3374 flag aSign, bSign;
3375
3376 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3377 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3378 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3379 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3380 ) {
3381 if ( floatx80_is_signaling_nan( a )
3382 || floatx80_is_signaling_nan( b ) ) {
3383 float_raise( float_flag_invalid );
3384 }
3385 return 0;
3386 }
3387 aSign = extractFloatx80Sign( a );
3388 bSign = extractFloatx80Sign( b );
3389 if ( aSign != bSign ) {
3390 return
3391 aSign
3392 || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3393 == 0 );
3394 }
3395 return
3396 aSign ? le128( b.high, b.low, a.high, a.low )
3397 : le128( a.high, a.low, b.high, b.low );
3398
3399}
3400
3401/*
3402-------------------------------------------------------------------------------
3403Returns 1 if the extended double-precision floating-point value `a' is less
3404than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
3405an exception. Otherwise, the comparison is performed according to the
3406IEC/IEEE Standard for Binary Floating-point Arithmetic.
3407-------------------------------------------------------------------------------
3408*/
3409flag floatx80_lt_quiet( floatx80 a, floatx80 b )
3410{
3411 flag aSign, bSign;
3412
3413 if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3414 && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3415 || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3416 && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3417 ) {
3418 if ( floatx80_is_signaling_nan( a )
3419 || floatx80_is_signaling_nan( b ) ) {
3420 float_raise( float_flag_invalid );
3421 }
3422 return 0;
3423 }
3424 aSign = extractFloatx80Sign( a );
3425 bSign = extractFloatx80Sign( b );
3426 if ( aSign != bSign ) {
3427 return
3428 aSign
3429 && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3430 != 0 );
3431 }
3432 return
3433 aSign ? lt128( b.high, b.low, a.high, a.low )
3434 : lt128( a.high, a.low, b.high, b.low );
3435
3436}
3437
3438#endif
3439
diff --git a/arch/arm26/nwfpe/softfloat.h b/arch/arm26/nwfpe/softfloat.h
deleted file mode 100644
index 22c2193a4997..000000000000
--- a/arch/arm26/nwfpe/softfloat.h
+++ /dev/null
@@ -1,232 +0,0 @@
1
2/*
3===============================================================================
4
5This C header file is part of the SoftFloat IEC/IEEE Floating-point
6Arithmetic Package, Release 2.
7
8Written by John R. Hauser. This work was made possible in part by the
9International Computer Science Institute, located at Suite 600, 1947 Center
10Street, Berkeley, California 94704. Funding was partially provided by the
11National Science Foundation under grant MIP-9311980. The original version
12of this code was written as part of a project to build a fixed-point vector
13processor in collaboration with the University of California at Berkeley,
14overseen by Profs. Nelson Morgan and John Wawrzynek. More information
15is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16arithmetic/softfloat.html'.
17
18THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
19has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23
24Derivative works are acceptable, even for commercial purposes, so long as
25(1) they include prominent notice that the work is derivative, and (2) they
26include prominent notice akin to these three paragraphs for those parts of
27this code that are retained.
28
29===============================================================================
30*/
31
32#ifndef __SOFTFLOAT_H__
33#define __SOFTFLOAT_H__
34
35/*
36-------------------------------------------------------------------------------
37The macro `FLOATX80' must be defined to enable the extended double-precision
38floating-point format `floatx80'. If this macro is not defined, the
39`floatx80' type will not be defined, and none of the functions that either
40input or output the `floatx80' type will be defined.
41-------------------------------------------------------------------------------
42*/
43#define FLOATX80
44
45/*
46-------------------------------------------------------------------------------
47Software IEC/IEEE floating-point types.
48-------------------------------------------------------------------------------
49*/
50typedef unsigned long int float32;
51typedef unsigned long long float64;
52typedef struct {
53 unsigned short high;
54 unsigned long long low;
55} floatx80;
56
57/*
58-------------------------------------------------------------------------------
59Software IEC/IEEE floating-point underflow tininess-detection mode.
60-------------------------------------------------------------------------------
61*/
62extern signed char float_detect_tininess;
63enum {
64 float_tininess_after_rounding = 0,
65 float_tininess_before_rounding = 1
66};
67
68/*
69-------------------------------------------------------------------------------
70Software IEC/IEEE floating-point rounding mode.
71-------------------------------------------------------------------------------
72*/
73extern signed char float_rounding_mode;
74enum {
75 float_round_nearest_even = 0,
76 float_round_to_zero = 1,
77 float_round_down = 2,
78 float_round_up = 3
79};
80
81/*
82-------------------------------------------------------------------------------
83Software IEC/IEEE floating-point exception flags.
84-------------------------------------------------------------------------------
85extern signed char float_exception_flags;
86enum {
87 float_flag_inexact = 1,
88 float_flag_underflow = 2,
89 float_flag_overflow = 4,
90 float_flag_divbyzero = 8,
91 float_flag_invalid = 16
92};
93
94ScottB: November 4, 1998
95Changed the enumeration to match the bit order in the FPA11.
96*/
97
98extern signed char float_exception_flags;
99enum {
100 float_flag_invalid = 1,
101 float_flag_divbyzero = 2,
102 float_flag_overflow = 4,
103 float_flag_underflow = 8,
104 float_flag_inexact = 16
105};
106
107/*
108-------------------------------------------------------------------------------
109Routine to raise any or all of the software IEC/IEEE floating-point
110exception flags.
111-------------------------------------------------------------------------------
112*/
113void float_raise( signed char );
114
115/*
116-------------------------------------------------------------------------------
117Software IEC/IEEE integer-to-floating-point conversion routines.
118-------------------------------------------------------------------------------
119*/
120float32 int32_to_float32( signed int );
121float64 int32_to_float64( signed int );
122#ifdef FLOATX80
123floatx80 int32_to_floatx80( signed int );
124#endif
125
126/*
127-------------------------------------------------------------------------------
128Software IEC/IEEE single-precision conversion routines.
129-------------------------------------------------------------------------------
130*/
131signed int float32_to_int32( float32 );
132signed int float32_to_int32_round_to_zero( float32 );
133float64 float32_to_float64( float32 );
134#ifdef FLOATX80
135floatx80 float32_to_floatx80( float32 );
136#endif
137
138/*
139-------------------------------------------------------------------------------
140Software IEC/IEEE single-precision operations.
141-------------------------------------------------------------------------------
142*/
143float32 float32_round_to_int( float32 );
144float32 float32_add( float32, float32 );
145float32 float32_sub( float32, float32 );
146float32 float32_mul( float32, float32 );
147float32 float32_div( float32, float32 );
148float32 float32_rem( float32, float32 );
149float32 float32_sqrt( float32 );
150char float32_eq( float32, float32 );
151char float32_le( float32, float32 );
152char float32_lt( float32, float32 );
153char float32_eq_signaling( float32, float32 );
154char float32_le_quiet( float32, float32 );
155char float32_lt_quiet( float32, float32 );
156char float32_is_signaling_nan( float32 );
157
158/*
159-------------------------------------------------------------------------------
160Software IEC/IEEE double-precision conversion routines.
161-------------------------------------------------------------------------------
162*/
163signed int float64_to_int32( float64 );
164signed int float64_to_int32_round_to_zero( float64 );
165float32 float64_to_float32( float64 );
166#ifdef FLOATX80
167floatx80 float64_to_floatx80( float64 );
168#endif
169
170/*
171-------------------------------------------------------------------------------
172Software IEC/IEEE double-precision operations.
173-------------------------------------------------------------------------------
174*/
175float64 float64_round_to_int( float64 );
176float64 float64_add( float64, float64 );
177float64 float64_sub( float64, float64 );
178float64 float64_mul( float64, float64 );
179float64 float64_div( float64, float64 );
180float64 float64_rem( float64, float64 );
181float64 float64_sqrt( float64 );
182char float64_eq( float64, float64 );
183char float64_le( float64, float64 );
184char float64_lt( float64, float64 );
185char float64_eq_signaling( float64, float64 );
186char float64_le_quiet( float64, float64 );
187char float64_lt_quiet( float64, float64 );
188char float64_is_signaling_nan( float64 );
189
190#ifdef FLOATX80
191
192/*
193-------------------------------------------------------------------------------
194Software IEC/IEEE extended double-precision conversion routines.
195-------------------------------------------------------------------------------
196*/
197signed int floatx80_to_int32( floatx80 );
198signed int floatx80_to_int32_round_to_zero( floatx80 );
199float32 floatx80_to_float32( floatx80 );
200float64 floatx80_to_float64( floatx80 );
201
202/*
203-------------------------------------------------------------------------------
204Software IEC/IEEE extended double-precision rounding precision. Valid
205values are 32, 64, and 80.
206-------------------------------------------------------------------------------
207*/
208extern signed char floatx80_rounding_precision;
209
210/*
211-------------------------------------------------------------------------------
212Software IEC/IEEE extended double-precision operations.
213-------------------------------------------------------------------------------
214*/
215floatx80 floatx80_round_to_int( floatx80 );
216floatx80 floatx80_add( floatx80, floatx80 );
217floatx80 floatx80_sub( floatx80, floatx80 );
218floatx80 floatx80_mul( floatx80, floatx80 );
219floatx80 floatx80_div( floatx80, floatx80 );
220floatx80 floatx80_rem( floatx80, floatx80 );
221floatx80 floatx80_sqrt( floatx80 );
222char floatx80_eq( floatx80, floatx80 );
223char floatx80_le( floatx80, floatx80 );
224char floatx80_lt( floatx80, floatx80 );
225char floatx80_eq_signaling( floatx80, floatx80 );
226char floatx80_le_quiet( floatx80, floatx80 );
227char floatx80_lt_quiet( floatx80, floatx80 );
228char floatx80_is_signaling_nan( floatx80 );
229
230#endif
231
232#endif
diff --git a/drivers/acorn/README b/drivers/acorn/README
deleted file mode 100644
index d399c09ca61c..000000000000
--- a/drivers/acorn/README
+++ /dev/null
@@ -1 +0,0 @@
1Drivers for the ACORN "podule" ARM specific bus.
diff --git a/drivers/acorn/block/Kconfig b/drivers/acorn/block/Kconfig
deleted file mode 100644
index a0ff25ea439f..000000000000
--- a/drivers/acorn/block/Kconfig
+++ /dev/null
@@ -1,36 +0,0 @@
1#
2# Block device driver configuration
3#
4
5menu "Acorn-specific block devices"
6 depends on ARCH_ARC || ARCH_A5K
7
8config BLK_DEV_FD1772
9 tristate "Old Archimedes floppy (1772) support"
10 depends on ARCH_ARC || ARCH_A5K
11 help
12 Support the floppy drive on the Acorn Archimedes (A300, A4x0, A540,
13 R140 and R260) series of computers; it supports only 720K floppies
14 at the moment. If you don't have one of these machines just answer
15 N.
16
17config BLK_DEV_MFM
18 tristate "MFM harddisk support"
19 depends on ARCH_ARC || ARCH_A5K
20 help
21 Support the MFM hard drives on the Acorn Archimedes both
22 on-board the A4x0 motherboards and via the Acorn MFM podules.
23 Drives up to 64MB are supported. If you haven't got one of these
24 machines or drives just say N.
25
26config BLK_DEV_MFM_AUTODETECT
27 bool "Autodetect hard drive geometry"
28 depends on BLK_DEV_MFM
29 help
30 If you answer Y, the MFM code will attempt to automatically detect
31 the cylinders/heads/sectors count on your hard drive. WARNING: This
32 sometimes doesn't work and it also does some dodgy stuff which
33 potentially might damage your drive.
34
35endmenu
36
diff --git a/drivers/acorn/block/Makefile b/drivers/acorn/block/Makefile
deleted file mode 100644
index 38a9afe8e03f..000000000000
--- a/drivers/acorn/block/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Makefile for the Acorn block device drivers.
3#
4
5fd1772_mod-objs := fd1772.o fd1772dma.o
6mfmhd_mod-objs := mfmhd.o mfm.o
7
8obj-$(CONFIG_BLK_DEV_FD1772) += fd1772_mod.o
9obj-$(CONFIG_BLK_DEV_MFM) += mfmhd_mod.o
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
deleted file mode 100644
index d7e18ce8dad9..000000000000
--- a/drivers/acorn/block/fd1772.c
+++ /dev/null
@@ -1,1604 +0,0 @@
1/*
2 * linux/kernel/arch/arm/drivers/block/fd1772.c
3 * Based on ataflop.c in the m68k Linux
4 * Copyright (C) 1993 Greg Harp
5 * Atari Support by Bjoern Brauel, Roman Hodek
6 * Archimedes Support by Dave Gilbert (linux@treblig.org)
7 *
8 * Big cleanup Sep 11..14 1994 Roman Hodek:
9 * - Driver now works interrupt driven
10 * - Support for two drives; should work, but I cannot test that :-(
11 * - Reading is done in whole tracks and buffered to speed up things
12 * - Disk change detection and drive deselecting after motor-off
13 * similar to TOS
14 * - Autodetection of disk format (DD/HD); untested yet, because I
15 * don't have an HD drive :-(
16 *
17 * Fixes Nov 13 1994 Martin Schaller:
18 * - Autodetection works now
19 * - Support for 5 1/4" disks
20 * - Removed drive type (unknown on atari)
21 * - Do seeks with 8 Mhz
22 *
23 * Changes by Andreas Schwab:
24 * - After errors in multiple read mode try again reading single sectors
25 * (Feb 1995):
26 * - Clean up error handling
27 * - Set blk_size for proper size checking
28 * - Initialize track register when testing presence of floppy
29 * - Implement some ioctl's
30 *
31 * Changes by Torsten Lang:
32 * - When probing the floppies we should add the FDC1772CMDADD_H flag since
33 * the FDC1772 will otherwise wait forever when no disk is inserted...
34 *
35 * Things left to do:
36 * - Formatting
37 * - Maybe a better strategy for disk change detection (does anyone
38 * know one?)
39 * - There are some strange problems left: The strangest one is
40 * that, at least on my TT (4+4MB), the first 2 Bytes of the last
41 * page of the TT-Ram (!) change their contents (some bits get
42 * set) while a floppy DMA is going on. But there are no accesses
43 * to these memory locations from the kernel... (I tested that by
44 * making the page read-only). I cannot explain what's going on...
45 * - Sometimes the drive-change-detection stops to work. The
46 * function is still called, but the WP bit always reads as 0...
47 * Maybe a problem with the status reg mode or a timing problem.
48 * Note 10/12/94: The change detection now seems to work reliably.
49 * There is no proof, but I've seen no hang for a long time...
50 *
51 * ARCHIMEDES changes: (gilbertd@cs.man.ac.uk)
52 * 26/12/95 - Changed all names starting with FDC to FDC1772
53 * Removed all references to clock speed of FDC - we're stuck with 8MHz
54 * Modified disk_type structure to remove HD formats
55 *
56 * 7/ 1/96 - Wrote FIQ code, removed most remaining atariisms
57 *
58 * 13/ 1/96 - Well I think its read a single sector; but there is a problem
59 * fd_rwsec_done which is called in FIQ mode starts another transfer
60 * off (in fd_rwsec) while still in FIQ mode. Because its still in
61 * FIQ mode it can't service the DMA and loses data. So need to
62 * heavily restructure.
63 * 14/ 1/96 - Found that the definitions of the register numbers of the
64 * FDC were multiplied by 2 in the header for the 16bit words
65 * of the atari so half the writes were going in the wrong place.
66 * Also realised that the FIQ entry didn't make any attempt to
67 * preserve registers or return correctly; now in assembler.
68 *
69 * 11/ 2/96 - Hmm - doesn't work on real machine. Auto detect doesn't
70 * and hacking that past seems to wait forever - check motor
71 * being turned on.
72 *
73 * 17/ 2/96 - still having problems - forcing track to -1 when selecting
74 * new drives seems to allow it to read first few sectors
75 * but then we get solid hangs at apparently random places
76 * which change depending what is happening.
77 *
78 * 9/ 3/96 - Fiddled a lot of stuff around to move to kernel 1.3.35
79 * A lot of fiddling in DMA stuff. Having problems with it
80 * constnatly thinking its timeing out. Ah - its timeout
81 * was set to (6*HZ) rather than jiffies+(6*HZ). Now giving
82 * duff data!
83 *
84 * 5/ 4/96 - Made it use the new IOC_ macros rather than *ioc
85 * Hmm - giving unexpected FIQ and then timeouts
86 * 18/ 8/96 - Ran through indent -kr -i8
87 * Some changes to disc change detect; don't know how well it
88 * works.
89 * 24/ 8/96 - Put all the track buffering code back in from the atari
90 * code - I wonder if it will still work... No :-)
91 * Still works if I turn off track buffering.
92 * 25/ 8/96 - Changed the timer expires that I'd added back to be
93 * jiffies + ....; and it all sprang to life! Got 2.8K/sec
94 * off a cp -r of a 679K disc (showed 94% cpu usage!)
95 * (PC gets 14.3K/sec - 0% CPU!) Hmm - hard drive corrupt!
96 * Also perhaps that compile was with cache off.
97 * changed cli in fd_readtrack_check to cliIF
98 * changed vmallocs to kmalloc (whats the difference!!)
99 * Removed the busy wait loop in do_fd_request and replaced
100 * by a routine on tq_immediate; only 11% cpu on a dd off the
101 * raw disc - but the speed is the same.
102 * 1/ 9/96 - Idea (failed!) - set the 'disable spin-up sequence'
103 * when we read the track if we know the motor is on; didn't
104 * help - perhaps we have to do it in stepping as well.
105 * Nope. Still doesn't help.
106 * Hmm - what seems to be happening is that fd_readtrack_check
107 * is never getting called. Its job is to terminate the read
108 * just after we think we should have got the data; otherwise
109 * the fdc takes 1 second to timeout; which is what's happening
110 * Now I can see 'readtrack_timer' being set (which should do the
111 * call); but it never seems to be called - hmm!
112 * OK - I've moved the check to my tq_immediate code -
113 * and it WORKS! 13.95K/second at 19% CPU.
114 * I wish I knew why that timer didn't work.....
115 *
116 * 16/11/96 - Fiddled and frigged for 2.0.18
117 *
118 * DAG 30/01/99 - Started frobbing for 2.2.1
119 * DAG 20/06/99 - A little more frobbing:
120 * Included include/asm/uaccess.h for get_user/put_user
121 *
122 * DAG 1/09/00 - Dusted off for 2.4.0-test7
123 * MAX_SECTORS was name clashing so it is now FD1772_...
124 * Minor parameter, name layouts for 2.4.x differences
125 */
126
127#include <linux/sched.h>
128#include <linux/fs.h>
129#include <linux/fcntl.h>
130#include <linux/slab.h>
131#include <linux/kernel.h>
132#include <linux/interrupt.h>
133#include <linux/timer.h>
134#include <linux/workqueue.h>
135#include <linux/fd.h>
136#include <linux/fd1772.h>
137#include <linux/errno.h>
138#include <linux/types.h>
139#include <linux/delay.h>
140#include <linux/mm.h>
141#include <linux/bitops.h>
142
143#include <asm/arch/oldlatches.h>
144#include <asm/dma.h>
145#include <asm/hardware.h>
146#include <asm/hardware/ioc.h>
147#include <asm/io.h>
148#include <asm/irq.h>
149#include <asm/mach-types.h>
150#include <asm/pgtable.h>
151#include <asm/system.h>
152#include <asm/uaccess.h>
153
154
155/* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
156 * little additional rework in this file). But I'm not yet sure if
157 * some other code depends on the number of floppies... (It is defined
158 * in a public header!)
159 */
160#if 0
161#undef FD_MAX_UNITS
162#define FD_MAX_UNITS 2
163#endif
164
165/* Ditto worries for Arc - DAG */
166#define FD_MAX_UNITS 4
167#define TRACKBUFFER 0
168/*#define DEBUG*/
169
170#ifdef DEBUG
171#define DPRINT(a) printk a
172#else
173#define DPRINT(a)
174#endif
175
176static struct request_queue *floppy_queue;
177
178#define MAJOR_NR FLOPPY_MAJOR
179#define FLOPPY_DMA 0
180#define DEVICE_NAME "floppy"
181#define QUEUE (floppy_queue)
182#define CURRENT elv_next_request(floppy_queue)
183
184/* Disk types: DD */
185static struct archy_disk_type {
186 const char *name;
187 unsigned spt; /* sectors per track */
188 unsigned blocks; /* total number of blocks */
189 unsigned stretch; /* track doubling ? */
190} disk_type[] = {
191
192 { "d360", 9, 720, 0 }, /* 360kB diskette */
193 { "D360", 9, 720, 1 }, /* 360kb in 720kb drive */
194 { "D720", 9, 1440, 0 }, /* 720kb diskette (DD) */
195 /*{ "D820", 10,1640, 0}, *//* DD disk with 82 tracks/10 sectors
196 - DAG - can't see how type detect can distinguish this
197 from 720K until it reads block 4 by which time its too late! */
198};
199
200#define NUM_DISK_TYPES (sizeof(disk_type)/sizeof(*disk_type))
201
202/*
203 * Maximum disk size (in kilobytes). This default is used whenever the
204 * current disk size is unknown.
205 */
206#define MAX_DISK_SIZE 720
207
208static struct gendisk *disks[FD_MAX_UNIT];
209
210/* current info on each unit */
211static struct archy_floppy_struct {
212 int connected; /* !=0 : drive is connected */
213 int autoprobe; /* !=0 : do autoprobe */
214
215 struct archy_disk_type *disktype; /* current type of disk */
216
217 int track; /* current head position or -1
218 * if unknown */
219 unsigned int steprate; /* steprate setting */
220 unsigned int wpstat; /* current state of WP signal
221 * (for disk change detection) */
222} unit[FD_MAX_UNITS];
223
224/* DAG: On Arc we spin on a flag being cleared by fdc1772_comendhandler which
225 is an assembler routine */
226extern void fdc1772_comendhandler(void); /* Actually doens't have these parameters - see fd1772.S */
227extern volatile int fdc1772_comendstatus;
228extern volatile int fdc1772_fdc_int_done;
229
230#define FDC1772BASE ((0x210000>>2)|0x80000000)
231
232#define FDC1772_READ(reg) inb(FDC1772BASE+(reg/2))
233
234/* DAG: You wouldn't be silly to ask why FDC1772_WRITE is a function rather
235 than the #def below - well simple - the #def won't compile - and I
236 don't understand why (__outwc not defined) */
237/* NOTE: Reg is 0,2,4,6 as opposed to 0,1,2,3 or 0,4,8,12 to keep compatibility
238 with the ST version of fd1772.h */
239/*#define FDC1772_WRITE(reg,val) outw(val,(reg+FDC1772BASE)); */
240void FDC1772_WRITE(int reg, unsigned char val)
241{
242 if (reg == FDC1772REG_CMD) {
243 DPRINT(("FDC1772_WRITE new command 0x%x @ %d\n", val,jiffies));
244 if (fdc1772_fdc_int_done) {
245 DPRINT(("FDC1772_WRITE: Hmm fdc1772_fdc_int_done true - resetting\n"));
246 fdc1772_fdc_int_done = 0;
247 };
248 };
249 outb(val, (reg / 2) + FDC1772BASE);
250};
251
252#define FD1772_MAX_SECTORS 22
253
254unsigned char *DMABuffer; /* buffer for writes */
255/*static unsigned long PhysDMABuffer; *//* physical address */
256/* DAG: On Arc we just go straight for the DMA buffer */
257#define PhysDMABuffer DMABuffer
258
259#ifdef TRACKBUFFER
260unsigned char *TrackBuffer; /* buffer for reads */
261#define PhysTrackBuffer TrackBuffer /* physical address */
262static int BufferDrive, BufferSide, BufferTrack;
263static int read_track; /* non-zero if we are reading whole tracks */
264
265#define SECTOR_BUFFER(sec) (TrackBuffer + ((sec)-1)*512)
266#define IS_BUFFERED(drive,side,track) \
267 (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
268#endif
269
270/*
271 * These are global variables, as that's the easiest way to give
272 * information to interrupts. They are the data used for the current
273 * request.
274 */
275static int SelectedDrive = 0;
276static int ReqCmd, ReqBlock;
277static int ReqSide, ReqTrack, ReqSector, ReqCnt;
278static int HeadSettleFlag = 0;
279static unsigned char *ReqData, *ReqBuffer;
280static int MotorOn = 0, MotorOffTrys;
281
282/* Synchronization of FDC1772 access. */
283static volatile int fdc_busy = 0;
284static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
285
286
287/* long req'd for set_bit --RR */
288static unsigned long changed_floppies = 0xff, fake_change = 0;
289#define CHECK_CHANGE_DELAY HZ/2
290
291/* DAG - increased to 30*HZ - not sure if this is the correct thing to do */
292#define FD_MOTOR_OFF_DELAY (10*HZ)
293#define FD_MOTOR_OFF_MAXTRY (10*20)
294
295#define FLOPPY_TIMEOUT (6*HZ)
296#define RECALIBRATE_ERRORS 4 /* After this many errors the drive
297 * will be recalibrated. */
298#define MAX_ERRORS 8 /* After this many errors the driver
299 * will give up. */
300
301#define START_MOTOR_OFF_TIMER(delay) \
302 do { \
303 motor_off_timer.expires = jiffies + (delay); \
304 add_timer( &motor_off_timer ); \
305 MotorOffTrys = 0; \
306 } while(0)
307
308#define START_CHECK_CHANGE_TIMER(delay) \
309 do { \
310 mod_timer(&fd_timer, jiffies + (delay)); \
311 } while(0)
312
313#define START_TIMEOUT() \
314 do { \
315 mod_timer(&timeout_timer, jiffies+FLOPPY_TIMEOUT); \
316 } while(0)
317
318#define STOP_TIMEOUT() \
319 do { \
320 del_timer( &timeout_timer ); \
321 } while(0)
322
323#define ENABLE_IRQ() enable_irq(FIQ_FD1772+64);
324
325#define DISABLE_IRQ() disable_irq(FIQ_FD1772+64);
326
327static void fd1772_checkint(void);
328
329DECLARE_WORK(fd1772_tq, (void *)fd1772_checkint, NULL);
330/*
331 * The driver is trying to determine the correct media format
332 * while Probing is set. fd_rwsec_done() clears it after a
333 * successful access.
334 */
335static int Probing = 0;
336
337/* This flag is set when a dummy seek is necessary to make the WP
338 * status bit accessible.
339 */
340static int NeedSeek = 0;
341
342
343/***************************** Prototypes *****************************/
344
345static void fd_select_side(int side);
346static void fd_select_drive(int drive);
347static void fd_deselect(void);
348static void fd_motor_off_timer(unsigned long dummy);
349static void check_change(unsigned long dummy);
350static void floppy_irqconsequencehandler(void);
351static void fd_error(void);
352static void do_fd_action(int drive);
353static void fd_calibrate(void);
354static void fd_calibrate_done(int status);
355static void fd_seek(void);
356static void fd_seek_done(int status);
357static void fd_rwsec(void);
358#ifdef TRACKBUFFER
359static void fd_readtrack_check( unsigned long dummy );
360#endif
361static void fd_rwsec_done(int status);
362static void fd_times_out(unsigned long dummy);
363static void finish_fdc(void);
364static void finish_fdc_done(int dummy);
365static void floppy_off(unsigned int nr);
366static void setup_req_params(int drive);
367static void redo_fd_request(void);
368static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int
369 cmd, unsigned long param);
370static void fd_probe(int drive);
371static int fd_test_drive_present(int drive);
372static void config_types(void);
373static int floppy_open(struct inode *inode, struct file *filp);
374static int floppy_release(struct inode *inode, struct file *filp);
375static void do_fd_request(struct request_queue *);
376
377/************************* End of Prototypes **************************/
378
379static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
380
381#ifdef TRACKBUFFER
382static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
383#endif
384
385static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
386
387static DEFINE_TIMER(fd_timer, check_change, 0, 0);
388
389/* DAG: Haven't got a clue what this is? */
390int stdma_islocked(void)
391{
392 return 0;
393};
394
395/* Select the side to use. */
396
397static void fd_select_side(int side)
398{
399 oldlatch_aupdate(LATCHA_SIDESEL, side ? 0 : LATCHA_SIDESEL);
400}
401
402
403/* Select a drive, update the FDC1772's track register
404 */
405
406static void fd_select_drive(int drive)
407{
408#ifdef DEBUG
409 printk("fd_select_drive:%d\n", drive);
410#endif
411 /* Hmm - nowhere do we seem to turn the motor on - I'm going to do it here! */
412 oldlatch_aupdate(LATCHA_MOTOR | LATCHA_INUSE, 0);
413
414 if (drive == SelectedDrive)
415 return;
416
417 oldlatch_aupdate(LATCHA_FDSELALL, 0xf - (1 << drive));
418
419 /* restore track register to saved value */
420 FDC1772_WRITE(FDC1772REG_TRACK, unit[drive].track);
421 udelay(25);
422
423 SelectedDrive = drive;
424}
425
426
427/* Deselect both drives. */
428
429static void fd_deselect(void)
430{
431 unsigned long flags;
432
433 DPRINT(("fd_deselect\n"));
434
435 oldlatch_aupdate(LATCHA_FDSELALL | LATCHA_MOTOR | LATCHA_INUSE, 0xf | LATCHA_MOTOR | LATCHA_INUSE);
436
437 SelectedDrive = -1;
438}
439
440
441/* This timer function deselects the drives when the FDC1772 switched the
442 * motor off. The deselection cannot happen earlier because the FDC1772
443 * counts the index signals, which arrive only if one drive is selected.
444 */
445
446static void fd_motor_off_timer(unsigned long dummy)
447{
448 unsigned long flags;
449 unsigned char status;
450 int delay;
451
452 del_timer(&motor_off_timer);
453
454 if (SelectedDrive < 0)
455 /* no drive selected, needn't deselect anyone */
456 return;
457
458 save_flags(flags);
459 cli();
460
461 if (fdc_busy) /* was stdma_islocked */
462 goto retry;
463
464 status = FDC1772_READ(FDC1772REG_STATUS);
465
466 if (!(status & 0x80)) {
467 /*
468 * motor already turned off by FDC1772 -> deselect drives
469 * In actual fact its this deselection which turns the motor
470 * off on the Arc, since the motor control is actually on
471 * Latch A
472 */
473 DPRINT(("fdc1772: deselecting in fd_motor_off_timer\n"));
474 fd_deselect();
475 MotorOn = 0;
476 restore_flags(flags);
477 return;
478 }
479 /* not yet off, try again */
480
481retry:
482 restore_flags(flags);
483 /* Test again later; if tested too often, it seems there is no disk
484 * in the drive and the FDC1772 will leave the motor on forever (or,
485 * at least until a disk is inserted). So we'll test only twice
486 * per second from then on...
487 */
488 delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ?
489 (++MotorOffTrys, HZ / 20) : HZ / 2;
490 START_MOTOR_OFF_TIMER(delay);
491}
492
493
494/* This function is repeatedly called to detect disk changes (as good
495 * as possible) and keep track of the current state of the write protection.
496 */
497
498static void check_change(unsigned long dummy)
499{
500 static int drive = 0;
501
502 unsigned long flags;
503 int stat;
504
505 if (fdc_busy)
506 return; /* Don't start poking about if the fdc is busy */
507
508 return; /* let's just forget it for the mo DAG */
509
510 if (++drive > 1 || !unit[drive].connected)
511 drive = 0;
512
513 save_flags(flags);
514 cli();
515
516 if (!stdma_islocked()) {
517 stat = !!(FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_WPROT);
518
519 /* The idea here is that if the write protect line has changed then
520 the disc must have changed */
521 if (stat != unit[drive].wpstat) {
522 DPRINT(("wpstat[%d] = %d\n", drive, stat));
523 unit[drive].wpstat = stat;
524 set_bit(drive, &changed_floppies);
525 }
526 }
527 restore_flags(flags);
528
529 START_CHECK_CHANGE_TIMER(CHECK_CHANGE_DELAY);
530}
531
532
533/* Handling of the Head Settling Flag: This flag should be set after each
534 * seek operation, because we don't use seeks with verify.
535 */
536
537static inline void set_head_settle_flag(void)
538{
539 HeadSettleFlag = FDC1772CMDADD_E;
540}
541
542static inline int get_head_settle_flag(void)
543{
544 int tmp = HeadSettleFlag;
545 HeadSettleFlag = 0;
546 return (tmp);
547}
548
549
550
551
552/* General Interrupt Handling */
553
554static inline void copy_buffer(void *from, void *to)
555{
556 ulong *p1 = (ulong *) from, *p2 = (ulong *) to;
557 int cnt;
558
559 for (cnt = 512 / 4; cnt; cnt--)
560 *p2++ = *p1++;
561}
562
563static void (*FloppyIRQHandler) (int status) = NULL;
564
565static void floppy_irqconsequencehandler(void)
566{
567 unsigned char status;
568 void (*handler) (int);
569
570 fdc1772_fdc_int_done = 0;
571
572 handler = FloppyIRQHandler;
573 FloppyIRQHandler = NULL;
574
575 if (handler) {
576 nop();
577 status = (unsigned char) fdc1772_comendstatus;
578 DPRINT(("FDC1772 irq, status = %02x handler = %08lx\n", (unsigned int) status, (unsigned long) handler));
579 handler(status);
580 } else {
581 DPRINT(("FDC1772 irq, no handler status=%02x\n", fdc1772_comendstatus));
582 }
583 DPRINT(("FDC1772 irq: end of floppy_irq\n"));
584}
585
586
587/* Error handling: If some error happened, retry some times, then
588 * recalibrate, then try again, and fail after MAX_ERRORS.
589 */
590
591static void fd_error(void)
592{
593 printk("FDC1772: fd_error\n");
594 /*panic("fd1772: fd_error"); *//* DAG tmp */
595 if (!CURRENT)
596 return;
597 CURRENT->errors++;
598 if (CURRENT->errors >= MAX_ERRORS) {
599 printk("fd%d: too many errors.\n", SelectedDrive);
600 end_request(CURRENT, 0);
601 } else if (CURRENT->errors == RECALIBRATE_ERRORS) {
602 printk("fd%d: recalibrating\n", SelectedDrive);
603 if (SelectedDrive != -1)
604 unit[SelectedDrive].track = -1;
605 }
606 redo_fd_request();
607}
608
609
610
611#define SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
612
613
614/* do_fd_action() is the general procedure for a fd request: All
615 * required parameter settings (drive select, side select, track
616 * position) are checked and set if needed. For each of these
617 * parameters and the actual reading or writing exist two functions:
618 * one that starts the setting (or skips it if possible) and one
619 * callback for the "done" interrupt. Each done func calls the next
620 * set function to propagate the request down to fd_rwsec_done().
621 */
622
623static void do_fd_action(int drive)
624{
625 struct request *req;
626 DPRINT(("do_fd_action unit[drive].track=%d\n", unit[drive].track));
627
628#ifdef TRACKBUFFER
629repeat:
630
631 if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
632 req = CURRENT;
633 if (ReqCmd == READ) {
634 copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
635 if (++ReqCnt < req->current_nr_sectors) {
636 /* read next sector */
637 setup_req_params( drive );
638 goto repeat;
639 } else {
640 /* all sectors finished */
641 req->nr_sectors -= req->current_nr_sectors;
642 req->sector += req->current_nr_sectors;
643 end_request(req, 1);
644 redo_fd_request();
645 return;
646 }
647 } else {
648 /* cmd == WRITE, pay attention to track buffer
649 * consistency! */
650 copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
651 }
652 }
653#endif
654
655 if (SelectedDrive != drive) {
656 /*unit[drive].track = -1; DAG */
657 fd_select_drive(drive);
658 };
659
660
661 if (unit[drive].track == -1)
662 fd_calibrate();
663 else if (unit[drive].track != ReqTrack << unit[drive].disktype->stretch)
664 fd_seek();
665 else
666 fd_rwsec();
667}
668
669
670/* Seek to track 0 if the current track is unknown */
671
672static void fd_calibrate(void)
673{
674 DPRINT(("fd_calibrate\n"));
675 if (unit[SelectedDrive].track >= 0) {
676 fd_calibrate_done(0);
677 return;
678 }
679 DPRINT(("fd_calibrate (after track compare)\n"));
680 SET_IRQ_HANDLER(fd_calibrate_done);
681 /* we can't verify, since the speed may be incorrect */
682 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | unit[SelectedDrive].steprate);
683
684 NeedSeek = 1;
685 MotorOn = 1;
686 START_TIMEOUT();
687 /* wait for IRQ */
688}
689
690
691static void fd_calibrate_done(int status)
692{
693 DPRINT(("fd_calibrate_done()\n"));
694 STOP_TIMEOUT();
695
696 /* set the correct speed now */
697 if (status & FDC1772STAT_RECNF) {
698 printk("fd%d: restore failed\n", SelectedDrive);
699 fd_error();
700 } else {
701 unit[SelectedDrive].track = 0;
702 fd_seek();
703 }
704}
705
706
707/* Seek the drive to the requested track. The drive must have been
708 * calibrated at some point before this.
709 */
710
711static void fd_seek(void)
712{
713 unsigned long flags;
714 DPRINT(("fd_seek() to track %d (unit[SelectedDrive].track=%d)\n", ReqTrack,
715 unit[SelectedDrive].track));
716 if (unit[SelectedDrive].track == ReqTrack <<
717 unit[SelectedDrive].disktype->stretch) {
718 fd_seek_done(0);
719 return;
720 }
721 FDC1772_WRITE(FDC1772REG_DATA, ReqTrack <<
722 unit[SelectedDrive].disktype->stretch);
723 udelay(25);
724 save_flags(flags);
725 clf();
726 SET_IRQ_HANDLER(fd_seek_done);
727 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK | unit[SelectedDrive].steprate |
728 /* DAG */
729 (MotorOn?FDC1772CMDADD_H:0));
730
731 restore_flags(flags);
732 MotorOn = 1;
733 set_head_settle_flag();
734 START_TIMEOUT();
735 /* wait for IRQ */
736}
737
738
739static void fd_seek_done(int status)
740{
741 DPRINT(("fd_seek_done()\n"));
742 STOP_TIMEOUT();
743
744 /* set the correct speed */
745 if (status & FDC1772STAT_RECNF) {
746 printk("fd%d: seek error (to track %d)\n",
747 SelectedDrive, ReqTrack);
748 /* we don't know exactly which track we are on now! */
749 unit[SelectedDrive].track = -1;
750 fd_error();
751 } else {
752 unit[SelectedDrive].track = ReqTrack <<
753 unit[SelectedDrive].disktype->stretch;
754 NeedSeek = 0;
755 fd_rwsec();
756 }
757}
758
759
760/* This does the actual reading/writing after positioning the head
761 * over the correct track.
762 */
763
764#ifdef TRACKBUFFER
765static int MultReadInProgress = 0;
766#endif
767
768
769static void fd_rwsec(void)
770{
771 unsigned long paddr, flags;
772 unsigned int rwflag, old_motoron;
773 unsigned int track;
774
775 DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n", ReqSector, ReqCmd == WRITE ? 'w' : 'r'));
776 if (ReqCmd == WRITE) {
777 /*cache_push( (unsigned long)ReqData, 512 ); */
778 paddr = (unsigned long) ReqData;
779 rwflag = 0x100;
780 } else {
781 paddr = (unsigned long) PhysDMABuffer;
782#ifdef TRACKBUFFER
783 if (read_track)
784 paddr = (unsigned long)PhysTrackBuffer;
785#endif
786 rwflag = 0;
787 }
788
789 DPRINT(("fd_rwsec() before sidesel rwflag=%d sec=%d trk=%d\n", rwflag,
790 ReqSector, FDC1772_READ(FDC1772REG_TRACK)));
791 fd_select_side(ReqSide);
792
793 /*DPRINT(("fd_rwsec() before start sector \n")); */
794 /* Start sector of this operation */
795#ifdef TRACKBUFFER
796 FDC1772_WRITE( FDC1772REG_SECTOR, !read_track ? ReqSector : 1 );
797#else
798 FDC1772_WRITE( FDC1772REG_SECTOR, ReqSector );
799#endif
800
801 /* Cheat for track if stretch != 0 */
802 if (unit[SelectedDrive].disktype->stretch) {
803 track = FDC1772_READ(FDC1772REG_TRACK);
804 FDC1772_WRITE(FDC1772REG_TRACK, track >>
805 unit[SelectedDrive].disktype->stretch);
806 }
807 udelay(25);
808
809 DPRINT(("fd_rwsec() before setup DMA \n"));
810 /* Setup DMA - Heavily modified by DAG */
811 save_flags(flags);
812 clf();
813 disable_dma(FLOPPY_DMA);
814 set_dma_mode(FLOPPY_DMA, rwflag ? DMA_MODE_WRITE : DMA_MODE_READ);
815 set_dma_addr(FLOPPY_DMA, (long) paddr); /* DAG - changed from Atari specific */
816#ifdef TRACKBUFFER
817 set_dma_count(FLOPPY_DMA,(!read_track ? 1 : unit[SelectedDrive].disktype->spt)*512);
818#else
819 set_dma_count(FLOPPY_DMA, 512); /* Block/sector size - going to have to change */
820#endif
821 SET_IRQ_HANDLER(fd_rwsec_done);
822 /* Turn on dma int */
823 enable_dma(FLOPPY_DMA);
824 /* Now give it something to do */
825 FDC1772_WRITE(FDC1772REG_CMD, (rwflag ? (FDC1772CMD_WRSEC | FDC1772CMDADD_P) :
826#ifdef TRACKBUFFER
827 (FDC1772CMD_RDSEC | (read_track ? FDC1772CMDADD_M : 0) |
828 /* Hmm - the idea here is to stop the FDC spinning the disc
829 up when we know that we already still have it spinning */
830 (MotorOn?FDC1772CMDADD_H:0))
831#else
832 FDC1772CMD_RDSEC
833#endif
834 ));
835
836 restore_flags(flags);
837 DPRINT(("fd_rwsec() after DMA setup flags=0x%08x\n", flags));
838 /*sti(); *//* DAG - Hmm */
839 /* Hmm - should do something DAG */
840 old_motoron = MotorOn;
841 MotorOn = 1;
842 NeedSeek = 1;
843
844 /* wait for interrupt */
845
846#ifdef TRACKBUFFER
847 if (read_track) {
848 /*
849 * If reading a whole track, wait about one disk rotation and
850 * then check if all sectors are read. The FDC will even
851 * search for the first non-existant sector and need 1 sec to
852 * recognise that it isn't present :-(
853 */
854 /* 1 rot. + 5 rot.s if motor was off */
855 mod_timer(&readtrack_timer, jiffies + HZ/5 + (old_motoron ? 0 : HZ));
856 DPRINT(("Setting readtrack_timer to %d @ %d\n",
857 readtrack_timer.expires,jiffies));
858 MultReadInProgress = 1;
859 }
860#endif
861
862 /*DPRINT(("fd_rwsec() before START_TIMEOUT \n")); */
863 START_TIMEOUT();
864 /*DPRINT(("fd_rwsec() after START_TIMEOUT \n")); */
865}
866
867
868#ifdef TRACKBUFFER
869
870static void fd_readtrack_check(unsigned long dummy)
871{
872 unsigned long flags, addr;
873 extern unsigned char *fdc1772_dataaddr;
874
875 DPRINT(("fd_readtrack_check @ %d\n",jiffies));
876
877 save_flags(flags);
878 clf();
879
880 del_timer( &readtrack_timer );
881
882 if (!MultReadInProgress) {
883 /* This prevents a race condition that could arise if the
884 * interrupt is triggered while the calling of this timer
885 * callback function takes place. The IRQ function then has
886 * already cleared 'MultReadInProgress' when control flow
887 * gets here.
888 */
889 restore_flags(flags);
890 return;
891 }
892
893 /* get the current DMA address */
894 addr=(unsigned long)fdc1772_dataaddr; /* DAG - ? */
895 DPRINT(("fd_readtrack_check: addr=%x PhysTrackBuffer=%x\n",addr,PhysTrackBuffer));
896
897 if (addr >= (unsigned int)PhysTrackBuffer + unit[SelectedDrive].disktype->spt*512) {
898 /* already read enough data, force an FDC interrupt to stop
899 * the read operation
900 */
901 SET_IRQ_HANDLER( NULL );
902 restore_flags(flags);
903 DPRINT(("fd_readtrack_check(): done\n"));
904 FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI );
905 udelay(25);
906
907 /* No error until now -- the FDC would have interrupted
908 * otherwise!
909 */
910 fd_rwsec_done( 0 );
911 } else {
912 /* not yet finished, wait another tenth rotation */
913 restore_flags(flags);
914 DPRINT(("fd_readtrack_check(): not yet finished\n"));
915 readtrack_timer.expires = jiffies + HZ/5/10;
916 add_timer( &readtrack_timer );
917 }
918}
919
920#endif
921
922static void fd_rwsec_done(int status)
923{
924 unsigned int track;
925
926 DPRINT(("fd_rwsec_done() status=%d @ %d\n", status,jiffies));
927
928#ifdef TRACKBUFFER
929 if (read_track && !MultReadInProgress)
930 return;
931
932 MultReadInProgress = 0;
933
934 STOP_TIMEOUT();
935
936 if (read_track)
937 del_timer( &readtrack_timer );
938#endif
939
940
941 /* Correct the track if stretch != 0 */
942 if (unit[SelectedDrive].disktype->stretch) {
943 track = FDC1772_READ(FDC1772REG_TRACK);
944 FDC1772_WRITE(FDC1772REG_TRACK, track <<
945 unit[SelectedDrive].disktype->stretch);
946 }
947 if (ReqCmd == WRITE && (status & FDC1772STAT_WPROT)) {
948 printk("fd%d: is write protected\n", SelectedDrive);
949 goto err_end;
950 }
951 if ((status & FDC1772STAT_RECNF)
952#ifdef TRACKBUFFER
953 /* RECNF is no error after a multiple read when the FDC
954 * searched for a non-existant sector!
955 */
956 && !(read_track &&
957 FDC1772_READ(FDC1772REG_SECTOR) > unit[SelectedDrive].disktype->spt)
958#endif
959 ) {
960 if (Probing) {
961 if (unit[SelectedDrive].disktype > disk_type) {
962 /* try another disk type */
963 unit[SelectedDrive].disktype--;
964 set_capacity(disks[SelectedDrive],
965 unit[SelectedDrive].disktype->blocks);
966 } else
967 Probing = 0;
968 } else {
969 /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
970 if (unit[SelectedDrive].autoprobe) {
971 unit[SelectedDrive].disktype = disk_type + NUM_DISK_TYPES - 1;
972 set_capacity(disks[SelectedDrive],
973 unit[SelectedDrive].disktype->blocks);
974 Probing = 1;
975 }
976 }
977 if (Probing) {
978 setup_req_params(SelectedDrive);
979#ifdef TRACKBUFFER
980 BufferDrive = -1;
981#endif
982 do_fd_action(SelectedDrive);
983 return;
984 }
985 printk("fd%d: sector %d not found (side %d, track %d)\n",
986 SelectedDrive, FDC1772_READ(FDC1772REG_SECTOR), ReqSide, ReqTrack);
987 goto err_end;
988 }
989 if (status & FDC1772STAT_CRC) {
990 printk("fd%d: CRC error (side %d, track %d, sector %d)\n",
991 SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR));
992 goto err_end;
993 }
994 if (status & FDC1772STAT_LOST) {
995 printk("fd%d: lost data (side %d, track %d, sector %d)\n",
996 SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR));
997 goto err_end;
998 }
999 Probing = 0;
1000
1001 if (ReqCmd == READ) {
1002#ifdef TRACKBUFFER
1003 if (!read_track) {
1004 /*cache_clear (PhysDMABuffer, 512);*/
1005 copy_buffer (DMABuffer, ReqData);
1006 } else {
1007 /*cache_clear (PhysTrackBuffer, FD1772_MAX_SECTORS * 512);*/
1008 BufferDrive = SelectedDrive;
1009 BufferSide = ReqSide;
1010 BufferTrack = ReqTrack;
1011 copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
1012 }
1013#else
1014 /*cache_clear( PhysDMABuffer, 512 ); */
1015 copy_buffer(DMABuffer, ReqData);
1016#endif
1017 }
1018 if (++ReqCnt < CURRENT->current_nr_sectors) {
1019 /* read next sector */
1020 setup_req_params(SelectedDrive);
1021 do_fd_action(SelectedDrive);
1022 } else {
1023 /* all sectors finished */
1024 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1025 CURRENT->sector += CURRENT->current_nr_sectors;
1026 end_request(CURRENT, 1);
1027 redo_fd_request();
1028 }
1029 return;
1030
1031err_end:
1032#ifdef TRACKBUFFER
1033 BufferDrive = -1;
1034#endif
1035
1036 fd_error();
1037}
1038
1039
1040static void fd_times_out(unsigned long dummy)
1041{
1042 SET_IRQ_HANDLER(NULL);
1043 /* If the timeout occurred while the readtrack_check timer was
1044 * active, we need to cancel it, else bad things will happen */
1045 del_timer( &readtrack_timer );
1046 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1047 udelay(25);
1048
1049 printk("floppy timeout\n");
1050 STOP_TIMEOUT(); /* hmm - should we do this ? */
1051 fd_error();
1052}
1053
1054
1055/* The (noop) seek operation here is needed to make the WP bit in the
1056 * FDC1772 status register accessible for check_change. If the last disk
1057 * operation would have been a RDSEC, this bit would always read as 0
1058 * no matter what :-( To save time, the seek goes to the track we're
1059 * already on.
1060 */
1061
1062static void finish_fdc(void)
1063{
1064 /* DAG - just try without this dummy seek! */
1065 finish_fdc_done(0);
1066 return;
1067
1068 if (!NeedSeek) {
1069 finish_fdc_done(0);
1070 } else {
1071 DPRINT(("finish_fdc: dummy seek started\n"));
1072 FDC1772_WRITE(FDC1772REG_DATA, unit[SelectedDrive].track);
1073 SET_IRQ_HANDLER(finish_fdc_done);
1074 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK);
1075 MotorOn = 1;
1076 START_TIMEOUT();
1077 /* we must wait for the IRQ here, because the ST-DMA is
1078 * released immediately afterwards and the interrupt may be
1079 * delivered to the wrong driver.
1080 */
1081 }
1082}
1083
1084
1085static void finish_fdc_done(int dummy)
1086{
1087 unsigned long flags;
1088
1089 DPRINT(("finish_fdc_done entered\n"));
1090 STOP_TIMEOUT();
1091 NeedSeek = 0;
1092
1093 if (timer_pending(&fd_timer) &&
1094 time_after(jiffies + 5, fd_timer.expires))
1095 /* If the check for a disk change is done too early after this
1096 * last seek command, the WP bit still reads wrong :-((
1097 */
1098 mod_timer(&fd_timer, jiffies + 5);
1099 else {
1100 /* START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
1101 };
1102 del_timer(&motor_off_timer);
1103 START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY);
1104
1105 save_flags(flags);
1106 cli();
1107 /* stdma_release(); - not sure if I should do something DAG */
1108 fdc_busy = 0;
1109 wake_up(&fdc_wait);
1110 restore_flags(flags);
1111
1112 DPRINT(("finish_fdc() finished\n"));
1113}
1114
1115
1116/* Prevent "aliased" accesses. */
1117static int fd_ref[4];
1118static int fd_device[4];
1119
1120/* dummy for blk.h */
1121static void floppy_off(unsigned int nr)
1122{
1123}
1124
1125
1126/* On the old arcs write protect depends on the particular model
1127 of machine. On the A310, R140, and A440 there is a disc changed
1128 detect, however on the A4x0/1 range there is not. There
1129 is nothing to tell you which machine your on.
1130 At the moment I'm just marking changed always. I've
1131 left the Atari's 'change on write protect change' code in this
1132 part (but nothing sets it).
1133 RiscOS apparently checks the disc serial number etc. to detect changes
1134 - but if it sees a disc change line go high (?) it flips to using
1135 it. Well maybe I'll add that in the future (!?)
1136*/
1137static int check_floppy_change(struct gendisk *disk)
1138{
1139 struct archy_floppy_struct *p = disk->private_data;
1140 unsigned int drive = p - unit;
1141
1142 if (test_bit(drive, &fake_change)) {
1143 /* simulated change (e.g. after formatting) */
1144 return 1;
1145 }
1146 if (test_bit(drive, &changed_floppies)) {
1147 /* surely changed (the WP signal changed at least once) */
1148 return 1;
1149 }
1150 if (p->wpstat) {
1151 /* WP is on -> could be changed: to be sure, buffers should be
1152 * invalidated...
1153 */
1154 return 1;
1155 }
1156 return 1; /* DAG - was 0 */
1157}
1158
1159static int floppy_revalidate(struct gendisk *disk)
1160{
1161 struct archy_floppy_struct *p = disk->private_data;
1162 unsigned int drive = p - unit;
1163
1164 if (test_bit(drive, &changed_floppies) || test_bit(drive, &fake_change)
1165 || unit[drive].disktype == 0) {
1166#ifdef TRACKBUFFER
1167 BufferDrive = -1;
1168#endif
1169 clear_bit(drive, &fake_change);
1170 clear_bit(drive, &changed_floppies);
1171 p->disktype = 0;
1172 }
1173 return 0;
1174}
1175
1176/* This sets up the global variables describing the current request. */
1177
1178static void setup_req_params(int drive)
1179{
1180 int block = ReqBlock + ReqCnt;
1181
1182 ReqTrack = block / unit[drive].disktype->spt;
1183 ReqSector = block - ReqTrack * unit[drive].disktype->spt + 1;
1184 ReqSide = ReqTrack & 1;
1185 ReqTrack >>= 1;
1186 ReqData = ReqBuffer + 512 * ReqCnt;
1187
1188#ifdef TRACKBUFFER
1189 read_track = (ReqCmd == READ && CURRENT->errors == 0);
1190#endif
1191
1192 DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n", ReqSide,
1193 ReqTrack, ReqSector, (unsigned long) ReqData));
1194}
1195
1196
1197static void redo_fd_request(void)
1198{
1199 int drive, type;
1200 struct archy_floppy_struct *floppy;
1201
1202 DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
1203 CURRENT, CURRENT ? CURRENT->rq_disk->disk_name : "",
1204 CURRENT ? CURRENT->sector : 0));
1205
1206repeat:
1207
1208 if (!CURRENT)
1209 goto the_end;
1210
1211 floppy = CURRENT->rq_disk->private_data;
1212 drive = floppy - unit;
1213 type = fd_device[drive];
1214
1215 if (!floppy->connected) {
1216 /* drive not connected */
1217 printk("Unknown Device: fd%d\n", drive);
1218 end_request(CURRENT, 0);
1219 goto repeat;
1220 }
1221 if (type == 0) {
1222 if (!floppy->disktype) {
1223 Probing = 1;
1224 floppy->disktype = disk_type + NUM_DISK_TYPES - 1;
1225 set_capacity(disks[drive], floppy->disktype->blocks);
1226 floppy->autoprobe = 1;
1227 }
1228 } else {
1229 /* user supplied disk type */
1230 --type;
1231 if (type >= NUM_DISK_TYPES) {
1232 printk("fd%d: invalid disk format", drive);
1233 end_request(CURRENT, 0);
1234 goto repeat;
1235 }
1236 floppy->disktype = &disk_type[type];
1237 set_capacity(disks[drive], floppy->disktype->blocks);
1238 floppy->autoprobe = 0;
1239 }
1240
1241 if (CURRENT->sector + 1 > floppy->disktype->blocks) {
1242 end_request(CURRENT, 0);
1243 goto repeat;
1244 }
1245 /* stop deselect timer */
1246 del_timer(&motor_off_timer);
1247
1248 ReqCnt = 0;
1249 ReqCmd = rq_data_dir(CURRENT);
1250 ReqBlock = CURRENT->sector;
1251 ReqBuffer = CURRENT->buffer;
1252 setup_req_params(drive);
1253 do_fd_action(drive);
1254
1255 return;
1256
1257the_end:
1258 finish_fdc();
1259}
1260
1261static void fd1772_checkint(void)
1262{
1263 extern int fdc1772_bytestogo;
1264
1265 /*printk("fd1772_checkint %d\n",fdc1772_fdc_int_done);*/
1266 if (fdc1772_fdc_int_done)
1267 floppy_irqconsequencehandler();
1268 if ((MultReadInProgress) && (fdc1772_bytestogo==0)) fd_readtrack_check(0);
1269 if (fdc_busy) {
1270 schedule_work(&fd1772_tq);
1271 }
1272}
1273
1274static void do_fd_request(struct request_queue* q)
1275{
1276 unsigned long flags;
1277
1278 DPRINT(("do_fd_request for pid %d\n", current->pid));
1279 if (fdc_busy) return;
1280 save_flags(flags);
1281 cli();
1282 wait_event(fdc_wait, !fdc_busy);
1283 fdc_busy = 1;
1284 ENABLE_IRQ();
1285 restore_flags(flags);
1286
1287 fdc1772_fdc_int_done = 0;
1288
1289 redo_fd_request();
1290
1291 schedule_work(&fd1772_tq);
1292}
1293
1294
1295static int invalidate_drive(struct block_device *bdev)
1296{
1297 struct archy_floppy_struct *p = bdev->bd_disk->private_data;
1298 /* invalidate the buffer track to force a reread */
1299#ifdef TRACKBUFFER
1300 BufferDrive = -1;
1301#endif
1302
1303 set_bit(p - unit, &fake_change);
1304 return 0;
1305}
1306
1307static int fd_ioctl(struct inode *inode, struct file *filp,
1308 unsigned int cmd, unsigned long param)
1309{
1310 struct block_device *bdev = inode->i_bdev;
1311
1312 switch (cmd) {
1313 case FDFMTEND:
1314 case FDFLUSH:
1315 invalidate_drive(bdev);
1316 check_disk_change(bdev);
1317 case FDFMTBEG:
1318 return 0;
1319 default:
1320 return -EINVAL;
1321 }
1322}
1323
1324
1325/* Initialize the 'unit' variable for drive 'drive' */
1326
1327static void fd_probe(int drive)
1328{
1329 unit[drive].connected = 0;
1330 unit[drive].disktype = NULL;
1331
1332 if (!fd_test_drive_present(drive))
1333 return;
1334
1335 unit[drive].connected = 1;
1336 unit[drive].track = -1; /* If we put the auto detect back in this can go to 0 */
1337 unit[drive].steprate = FDC1772STEP_6;
1338 MotorOn = 1; /* from probe restore operation! */
1339}
1340
1341
1342/* This function tests the physical presence of a floppy drive (not
1343 * whether a disk is inserted). This is done by issuing a restore
1344 * command, waiting max. 2 seconds (that should be enough to move the
1345 * head across the whole disk) and looking at the state of the "TR00"
1346 * signal. This should now be raised if there is a drive connected
1347 * (and there is no hardware failure :-) Otherwise, the drive is
1348 * declared absent.
1349 */
1350
1351static int fd_test_drive_present(int drive)
1352{
1353 unsigned long timeout;
1354 unsigned char status;
1355 int ok;
1356
1357 printk("fd_test_drive_present %d\n", drive);
1358 if (drive > 1)
1359 return (0);
1360 return (1); /* Simple hack for the moment - the autodetect doesn't seem to work on arc */
1361 fd_select_drive(drive);
1362
1363 /* disable interrupt temporarily */
1364 DISABLE_IRQ();
1365 FDC1772_WRITE(FDC1772REG_TRACK, 0x00); /* was ff00 why? */
1366 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6);
1367
1368 /*printk("fd_test_drive_present: Going into timeout loop\n"); */
1369 for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; time_before(jiffies, timeout);) {
1370 /* What does this piece of atariism do? - query for an interrupt? */
1371 /* if (!(mfp.par_dt_reg & 0x20))
1372 break; */
1373 /* Well this is my nearest guess - quit when we get an FDC interrupt */
1374 if (ioc_readb(IOC_FIQSTAT) & 2)
1375 break;
1376 }
1377
1378 /*printk("fd_test_drive_present: Coming out of timeout loop\n"); */
1379 status = FDC1772_READ(FDC1772REG_STATUS);
1380 ok = (status & FDC1772STAT_TR00) != 0;
1381
1382 /*printk("fd_test_drive_present: ok=%d\n",ok); */
1383 /* force interrupt to abort restore operation (FDC1772 would try
1384 * about 50 seconds!) */
1385 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1386 udelay(500);
1387 status = FDC1772_READ(FDC1772REG_STATUS);
1388 udelay(20);
1389 /*printk("fd_test_drive_present: just before OK code %d\n",ok); */
1390
1391 if (ok) {
1392 /* dummy seek command to make WP bit accessible */
1393 FDC1772_WRITE(FDC1772REG_DATA, 0);
1394 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK);
1395 printk("fd_test_drive_present: just before wait for int\n");
1396 /* DAG: Guess means wait for interrupt */
1397 while (!(ioc_readb(IOC_FIQSTAT) & 2));
1398 printk("fd_test_drive_present: just after wait for int\n");
1399 status = FDC1772_READ(FDC1772REG_STATUS);
1400 }
1401 printk("fd_test_drive_present: just before ENABLE_IRQ\n");
1402 ENABLE_IRQ();
1403 printk("fd_test_drive_present: about to return\n");
1404 return (ok);
1405}
1406
1407
1408/* Look how many and which kind of drives are connected. If there are
1409 * floppies, additionally start the disk-change and motor-off timers.
1410 */
1411
1412static void config_types(void)
1413{
1414 int drive, cnt = 0;
1415
1416 printk("Probing floppy drive(s):\n");
1417 for (drive = 0; drive < FD_MAX_UNITS; drive++) {
1418 fd_probe(drive);
1419 if (unit[drive].connected) {
1420 printk("fd%d\n", drive);
1421 ++cnt;
1422 }
1423 }
1424
1425 if (FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_BUSY) {
1426 /* If FDC1772 is still busy from probing, give it another FORCI
1427 * command to abort the operation. If this isn't done, the FDC1772
1428 * will interrupt later and its IRQ line stays low, because
1429 * the status register isn't read. And this will block any
1430 * interrupts on this IRQ line :-(
1431 */
1432 FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1433 udelay(500);
1434 FDC1772_READ(FDC1772REG_STATUS);
1435 udelay(20);
1436 }
1437 if (cnt > 0) {
1438 START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY);
1439 if (cnt == 1)
1440 fd_select_drive(0);
1441 /*START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
1442 }
1443}
1444
1445/*
1446 * floppy_open check for aliasing (/dev/fd0 can be the same as
1447 * /dev/PS0 etc), and disallows simultaneous access to the same
1448 * drive with different device numbers.
1449 */
1450
1451static int floppy_open(struct inode *inode, struct file *filp)
1452{
1453 int drive = iminor(inode) & 3;
1454 int type = iminor(inode) >> 2;
1455 int old_dev = fd_device[drive];
1456
1457 if (fd_ref[drive] && old_dev != type)
1458 return -EBUSY;
1459
1460 if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
1461 return -EBUSY;
1462
1463 if (filp->f_flags & O_EXCL)
1464 fd_ref[drive] = -1;
1465 else
1466 fd_ref[drive]++;
1467
1468 fd_device[drive] = type;
1469
1470 if (filp->f_flags & O_NDELAY)
1471 return 0;
1472
1473 if (filp->f_mode & 3) {
1474 check_disk_change(inode->i_bdev);
1475 if (filp->f_mode & 2) {
1476 if (unit[drive].wpstat) {
1477 floppy_release(inode, filp);
1478 return -EROFS;
1479 }
1480 }
1481 }
1482 return 0;
1483}
1484
1485
1486static int floppy_release(struct inode *inode, struct file *filp)
1487{
1488 int drive = iminor(inode) & 3;
1489
1490 if (fd_ref[drive] < 0)
1491 fd_ref[drive] = 0;
1492 else if (!fd_ref[drive]--) {
1493 printk("floppy_release with fd_ref == 0");
1494 fd_ref[drive] = 0;
1495 }
1496
1497 return 0;
1498}
1499
1500static struct block_device_operations floppy_fops =
1501{
1502 .open = floppy_open,
1503 .release = floppy_release,
1504 .ioctl = fd_ioctl,
1505 .media_changed = check_floppy_change,
1506 .revalidate_disk= floppy_revalidate,
1507};
1508
1509static struct kobject *floppy_find(dev_t dev, int *part, void *data)
1510{
1511 int drive = *part & 3;
1512 if ((*part >> 2) > NUM_DISK_TYPES || drive >= FD_MAX_UNITS)
1513 return NULL;
1514 *part = 0;
1515 return get_disk(disks[drive]);
1516}
1517
1518int fd1772_init(void)
1519{
1520 static DEFINE_SPINLOCK(lock);
1521 int i, err = -ENOMEM;
1522
1523 if (!machine_is_archimedes())
1524 return 0;
1525
1526 for (i = 0; i < FD_MAX_UNITS; i++) {
1527 disks[i] = alloc_disk(1);
1528 if (!disks[i])
1529 goto err_disk;
1530 }
1531
1532 err = register_blkdev(MAJOR_NR, "fd");
1533 if (err)
1534 goto err_disk;
1535
1536 err = -EBUSY;
1537 if (request_dma(FLOPPY_DMA, "fd1772")) {
1538 printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA);
1539 goto err_blkdev;
1540 };
1541
1542 if (request_dma(FIQ_FD1772, "fd1772 end")) {
1543 printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772);
1544 goto err_dma1;
1545 };
1546
1547 /* initialize variables */
1548 SelectedDrive = -1;
1549#ifdef TRACKBUFFER
1550 BufferDrive = BufferSide = BufferTrack = -1;
1551 /* Atari uses 512 - I want to eventually cope with 1K sectors */
1552 DMABuffer = kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
1553 TrackBuffer = DMABuffer + 512;
1554#else
1555 /* Allocate memory for the DMAbuffer - on the Atari this takes it
1556 out of some special memory... */
1557 DMABuffer = kmalloc(2048); /* Copes with pretty large sectors */
1558#endif
1559 err = -ENOMEM;
1560 if (!DMAbuffer)
1561 goto err_dma2;
1562
1563 enable_dma(FIQ_FD1772); /* This inserts a call to our command end routine */
1564
1565 floppy_queue = blk_init_queue(do_fd_request, &lock);
1566 if (!floppy_queue)
1567 goto err_queue;
1568
1569 for (i = 0; i < FD_MAX_UNITS; i++) {
1570 unit[i].track = -1;
1571 disks[i]->major = MAJOR_NR;
1572 disks[i]->first_minor = 0;
1573 disks[i]->fops = &floppy_fops;
1574 sprintf(disks[i]->disk_name, "fd%d", i);
1575 disks[i]->private_data = &unit[i];
1576 disks[i]->queue = floppy_queue;
1577 set_capacity(disks[i], MAX_DISK_SIZE * 2);
1578 }
1579 blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE,
1580 floppy_find, NULL, NULL);
1581
1582 for (i = 0; i < FD_MAX_UNITS; i++)
1583 add_disk(disks[i]);
1584
1585 config_types();
1586
1587 return 0;
1588
1589 err_queue:
1590 kfree(DMAbuffer);
1591 err_dma2:
1592 free_dma(FIQ_FD1772);
1593
1594 err_dma1:
1595 free_dma(FLOPPY_DMA);
1596
1597 err_blkdev:
1598 unregister_blkdev(MAJOR_NR, "fd");
1599
1600 err_disk:
1601 while (i--)
1602 put_disk(disks[i]);
1603 return err;
1604}
diff --git a/drivers/acorn/block/fd1772dma.S b/drivers/acorn/block/fd1772dma.S
deleted file mode 100644
index 7964435443ec..000000000000
--- a/drivers/acorn/block/fd1772dma.S
+++ /dev/null
@@ -1,100 +0,0 @@
1#include <asm/hardware.h>
2
3@ Code for DMA with the 1772 fdc
4.text
5
6
7 .global fdc1772_dataaddr
8fdc1772_fiqdata:
9@ Number of bytes left to DMA
10 .global fdc1772_bytestogo
11fdc1772_bytestogo:
12 .word 0
13@ Place to put/get data from in DMA
14 .global fdc1772_dataaddr
15fdc1772_dataaddr:
16 .word 0
17
18 .global fdc1772_fdc_int_done
19fdc1772_fdc_int_done:
20 .word 0
21 .global fdc1772_comendstatus
22fdc1772_comendstatus:
23 .word 0
24
25@ We hang this off DMA channel 1
26 .global fdc1772_comendhandler
27fdc1772_comendhandler:
28 mov r8,#IOC_BASE
29 ldrb r9,[r8,#0x34] @ IOC FIQ status
30 tst r9,#2
31 subeqs pc,r14,#4 @ should I leave a space here
32 orr r9,r8,#0x10000 @ FDC base
33 adr r8,fdc1772_fdc_int_done
34 ldrb r10,[r9,#0] @ FDC status
35 mov r9,#1 @ Got a FIQ flag
36 stmia r8,{r9,r10}
37 subs pc,r14,#4
38
39
40 .global fdc1772_dma_read
41fdc1772_dma_read:
42 mov r8,#IOC_BASE
43 ldrb r9,[r8,#0x34] @ IOC FIQ status
44 tst r9,#1
45 beq fdc1772_dma_read_notours
46 orr r8,r8,#0x10000 @ FDC base
47 ldrb r10,[r8,#0xc] @ Read from FDC data reg (also clears interrupt)
48 ldmia r11,{r8,r9}
49 subs r8,r8,#1 @ One less byte to go
50 @ If there was somewhere for this data to go then store it and update pointers
51 strplb r10,[r9],#1 @ Store the data and increment the pointer
52 stmplia r11,{r8,r9} @ Update count/pointers
53 @ Handle any other interrupts if there are any
54fdc1772_dma_read_notours:
55 @ Cant branch because this code has been copied down to the FIQ vector
56 ldr pc,[pc,#-4]
57 .word fdc1772_comendhandler
58 .global fdc1772_dma_read_end
59fdc1772_dma_read_end:
60
61 .global fdc1772_dma_write
62fdc1772_dma_write:
63 mov r8,#IOC_BASE
64 ldrb r9,[r8,#0x34] @ IOC FIQ status
65 tst r9,#1
66 beq fdc1772_dma_write_notours
67 orr r8,r8,#0x10000 @ FDC base
68 ldmia r11,{r9,r10}
69 subs r9,r9,#1 @ One less byte to go
70 @ If there really is some data then get it, store it and update count
71 ldrplb r12,[r10],#1
72 strplb r12,[r8,#0xc] @ write it to FDC data reg
73 stmplia r11,{r9,r10} @ Update count and pointer - should clear interrupt
74 @ Handle any other interrupts
75fdc1772_dma_write_notours:
76 @ Cant branch because this code has been copied down to the FIQ vector
77 ldr pc,[pc,#-4]
78 .word fdc1772_comendhandler
79
80 .global fdc1772_dma_write_end
81fdc1772_dma_write_end:
82
83
84@ Setup the FIQ R11 to point to the data and store the count, address
85@ for this dma
86@ R0=count
87@ R1=address
88 .global fdc1772_setupdma
89fdc1772_setupdma:
90 @ The big job is flipping in and out of FIQ mode
91 adr r2,fdc1772_fiqdata @ This is what we really came here for
92 stmia r2,{r0,r1}
93 mov r3, pc
94 teqp pc,#0x0c000001 @ Disable FIQs, IRQs and switch to FIQ mode
95 mov r0,r0 @ NOP
96 mov r11,r2
97 teqp r3,#0 @ Normal mode
98 mov r0,r0 @ NOP
99 mov pc,r14
100
diff --git a/drivers/acorn/block/mfm.S b/drivers/acorn/block/mfm.S
deleted file mode 100644
index c90cbd41ce21..000000000000
--- a/drivers/acorn/block/mfm.S
+++ /dev/null
@@ -1,162 +0,0 @@
1@ Read/Write DMA code for the ST506/MFM hard drive controllers on the A400 Acorn Archimedes
2@ motherboard and on ST506 expansion podules.
3@ (c) David Alan Gilbert (linux@treblig.org) 1996-1999
4
5#include <asm/assembler.h>
6
7hdc63463_irqdata:
8@ Controller base address
9 .global hdc63463_baseaddress
10hdc63463_baseaddress:
11 .word 0
12
13 .global hdc63463_irqpolladdress
14hdc63463_irqpolladdress:
15 .word 0
16
17 .global hdc63463_irqpollmask
18hdc63463_irqpollmask:
19 .word 0
20
21@ where to read/write data from the kernel data space
22 .global hdc63463_dataptr
23hdc63463_dataptr:
24 .word 0
25
26@ Number of bytes left to transfer
27 .global hdc63463_dataleft
28hdc63463_dataleft:
29 .word 0
30
31@ -------------------------------------------------------------------------
32@ hdc63463_writedma: DMA from host to controller
33@ internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask
34@ r3=data ptr, r4=data left, r5,r6=temporary
35 .global hdc63463_writedma
36hdc63463_writedma:
37 stmfd sp!,{r4-r7}
38 adr r5,hdc63463_irqdata
39 ldmia r5,{r0,r1,r2,r3,r4}
40
41writedma_again:
42
43 @ test number of remaining bytes to transfer
44 cmp r4,#0
45 beq writedma_end
46 bmi writedma_end
47
48 @ Check the hdc is interrupting
49 ldrb r5,[r1,#0]
50 tst r5,r2
51 beq writedma_end
52
53 @ Transfer a block of upto 256 bytes
54 cmp r4,#256
55 movlt r7,r4
56 movge r7,#256
57
58 @ Check the hdc is still busy and command has not ended and no errors
59 ldr r5,[r0,#32] @ Status reg - 16 bit - its the top few bits which are status
60 @ think we should continue DMA until it drops busy - perhaps this was
61 @ the main problem with corrected errors causing a hang
62 @tst r5,#0x3c00 @ Test for things which should be off
63 @bne writedma_end
64 and r5,r5,#0x8000 @ This is test for things which should be on: Busy
65 cmp r5,#0x8000
66 bne writedma_end
67
68 @ Bytes remaining at end
69 sub r4,r4,r7
70
71 @ HDC Write register location
72 add r0,r0,#32+8
73
74writedma_loop:
75 @ OK - pretty sure we should be doing this
76
77 ldr r5,[r3],#4 @ Get a word to be written
78 @ get bottom half to be sent first
79 mov r6,r5,lsl#16 @ Separate the first 2 bytes
80 orr r2,r6,r6,lsr #16 @ Duplicate them in the bottom half of the word
81 @ now the top half
82 mov r6,r5,lsr#16 @ Get 2nd 2 bytes
83 orr r6,r6,r6,lsl#16 @ Duplicate
84 @str r6,[r0] @ to hdc
85 stmia r0,{r2,r6}
86 subs r7,r7,#4 @ Dec. number of bytes left
87 bne writedma_loop
88
89 @ If we were too slow we had better go through again - DAG - took out with new interrupt routine
90 @ sub r0,r0,#32+8
91 @ adr r2,hdc63463_irqdata
92 @ ldr r2,[r2,#8]
93 @ b writedma_again
94
95writedma_end:
96 adr r5,hdc63463_irqdata+12
97 stmia r5,{r3,r4}
98 ldmfd sp!,{r4-r7}
99 RETINSTR(mov,pc,lr)
100
101@ -------------------------------------------------------------------------
102@ hdc63463_readdma: DMA from controller to host
103@ internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask
104@ r3=data ptr, r4=data left, r5,r6=temporary
105 .global hdc63463_readdma
106hdc63463_readdma:
107 stmfd sp!,{r4-r7}
108 adr r5,hdc63463_irqdata
109 ldmia r5,{r0,r1,r2,r3,r4}
110
111readdma_again:
112 @ test number of remaining bytes to transfer
113 cmp r4,#0
114 beq readdma_end
115 bmi readdma_end
116
117 @ Check the hdc is interrupting
118 ldrb r5,[r1,#0]
119 tst r5,r2
120 beq readdma_end
121
122 @ Check the hdc is still busy and command has not ended and no errors
123 ldr r5,[r0,#32] @ Status reg - 16 bit - its the top few bits which are status
124 @ think we should continue DMA until it drops busy - perhaps this was
125 @ the main problem with corrected errors causing a hang
126 @tst r5,#0x3c00 @ Test for things which should be off
127 @bne readdma_end
128 and r5,r5,#0x8000 @ This is test for things which should be on: Busy
129 cmp r5,#0x8000
130 bne readdma_end
131
132 @ Transfer a block of upto 256 bytes
133 cmp r4,#256
134 movlt r7,r4
135 movge r7,#256
136
137 @ Bytes remaining at end
138 sub r4,r4,r7
139
140 @ Set a pointer to the data register in the HDC
141 add r0,r0,#8
142readdma_loop:
143 @ OK - pretty sure we should be doing this
144 ldmia r0,{r5,r6}
145 mov r5,r5,lsl#16
146 mov r6,r6,lsl#16
147 orr r6,r6,r5,lsr #16
148 str r6,[r3],#4
149 subs r7,r7,#4 @ Decrement bytes to go
150 bne readdma_loop
151
152 @ Try reading multiple blocks - if this was fast enough then I do not think
153 @ this should help - NO taken out DAG - new interrupt handler has
154 @ non-consecutive memory blocks
155 @ sub r0,r0,#8
156 @ b readdma_again
157
158readdma_end:
159 adr r5,hdc63463_irqdata+12
160 stmia r5,{r3,r4}
161 ldmfd sp!,{r4-r7}
162 RETINSTR(mov,pc,lr)
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
deleted file mode 100644
index 74058db674db..000000000000
--- a/drivers/acorn/block/mfmhd.c
+++ /dev/null
@@ -1,1385 +0,0 @@
1/*
2 * linux/drivers/acorn/block/mfmhd.c
3 *
4 * Copyright (C) 1995, 1996 Russell King, Dave Alan Gilbert (gilbertd@cs.man.ac.uk)
5 *
6 * MFM hard drive code [experimental]
7 */
8
9/*
10 * Change list:
11 *
12 * 3/2/96:DAG: Started a change list :-)
13 * Set the hardsect_size pointers up since we are running 256 byte
14 * sectors
15 * Added DMA code, put it into the rw_intr
16 * Moved RCAL out of generic interrupt code - don't want to do it
17 * while DMA'ing - its now in individual handlers.
18 * Took interrupt handlers off task queue lists and called
19 * directly - not sure of implications.
20 *
21 * 18/2/96:DAG: Well its reading OK I think, well enough for image file code
22 * to find the image file; but now I've discovered that I actually
23 * have to put some code in for image files.
24 *
25 * Added stuff for image files; seems to work, but I've not
26 * got a multisegment image file (I don't think!).
27 * Put in a hack (yep a real hack) for multiple cylinder reads.
28 * Not convinced its working.
29 *
30 * 5/4/96:DAG: Added asm/hardware.h and use IOC_ macros
31 * Rewrote dma code in mfm.S (again!) - now takes a word at a time
32 * from main RAM for speed; still doesn't feel speedy!
33 *
34 * 20/4/96:DAG: After rewriting mfm.S a heck of a lot of times and speeding
35 * things up, I've finally figured out why its so damn slow.
36 * Linux is only reading a block at a time, and so you never
37 * get more than 1K per disc revoloution ~=60K/second.
38 *
39 * 27/4/96:DAG: On Russell's advice I change ll_rw_blk.c to ask it to
40 * join adjacent blocks together. Everything falls flat on its
41 * face.
42 * Four hours of debugging later; I hadn't realised that
43 * ll_rw_blk would be so generous as to join blocks whose
44 * results aren't going into consecutive buffers.
45 *
46 * OK; severe rehacking of mfm_rw_interrupt; now end_request's
47 * as soon as its DMA'd each request. Odd thing is that
48 * we are sometimes getting interrupts where we are not transferring
49 * any data; why? Is that what happens when you miss? I doubt
50 * it; are we too fast? No - its just at command ends. Got 240K/s
51 * better than before, but RiscOS hits 480K/s
52 *
53 * 25/6/96:RMK: Fixed init code to allow the MFM podule to work. Increased the
54 * number of errors for my Miniscribe drive (8425).
55 *
56 * 30/6/96:DAG: Russell suggested that a check drive 0 might turn the LEDs off
57 * - so in request_done just before it clears Busy it sends a
58 * check drive 0 - and the LEDs go off!!!!
59 *
60 * Added test for mainboard controller. - Removes need for separate
61 * define.
62 *
63 * 13/7/96:DAG: Changed hardware sectore size to 512 in attempt to make
64 * IM drivers work.
65 * 21/7/96:DAG: Took out old image file stuff (accessing it now produces an IO
66 * error.)
67 *
68 * 17/8/96:DAG: Ran through indent -kr -i8; evil - all my nice 2 character indents
69 * gone :-( Hand modified afterwards.
70 * Took out last remains of the older image map system.
71 *
72 * 22/9/96:DAG: Changed mfm.S so it will carry on DMA'ing til; BSY is dropped
73 * Changed mfm_rw_intr so that it doesn't follow the error
74 * code until BSY is dropped. Nope - still broke. Problem
75 * may revolve around when it reads the results for the error
76 * number?
77 *
78 *16/11/96:DAG: Modified for 2.0.18; request_irq changed
79 *
80 *17/12/96:RMK: Various cleanups, reorganisation, and the changes for new IO system.
81 * Improved probe for onboard MFM chip - it was hanging on my A5k.
82 * Added autodetect CHS code such that we don't rely on the presence
83 * of an ADFS boot block. Added ioport resource manager calls so
84 * that we don't clash with already-running hardware (eg. RiscPC Ether
85 * card slots if someone tries this)!
86 *
87 * 17/1/97:RMK: Upgraded to 2.1 kernels.
88 *
89 * 4/3/98:RMK: Changed major number to 21.
90 *
91 * 27/6/98:RMK: Changed asm/delay.h to linux/delay.h for mdelay().
92 */
93
94/*
95 * Possible enhancements:
96 * Multi-thread the code so that it is possible that while one drive
97 * is seeking, the other one can be reading data/seeking as well.
98 * This would be a performance boost with dual drive systems.
99 */
100
101#include <linux/module.h>
102#include <linux/fs.h>
103#include <linux/interrupt.h>
104#include <linux/kernel.h>
105#include <linux/timer.h>
106#include <linux/mm.h>
107#include <linux/errno.h>
108#include <linux/genhd.h>
109#include <linux/major.h>
110#include <linux/ioport.h>
111#include <linux/delay.h>
112#include <linux/blkpg.h>
113
114#include <asm/system.h>
115#include <asm/io.h>
116#include <asm/irq.h>
117#include <asm/uaccess.h>
118#include <asm/dma.h>
119#include <asm/hardware.h>
120#include <asm/ecard.h>
121#include <asm/hardware/ioc.h>
122
123static void (*do_mfm)(void) = NULL;
124static struct request_queue *mfm_queue;
125static DEFINE_SPINLOCK(mfm_lock);
126
127#define MAJOR_NR MFM_ACORN_MAJOR
128#define QUEUE (mfm_queue)
129#define CURRENT elv_next_request(mfm_queue)
130
131/*
132 * Configuration section
133 *
134 * This is the maximum number of drives that we accept
135 */
136#define MFM_MAXDRIVES 2
137/*
138 * Linux I/O address of onboard MFM controller or 0 to disable this
139 */
140#define ONBOARD_MFM_ADDRESS ((0x002d0000 >> 2) | 0x80000000)
141/*
142 * Uncomment this to enable debugging in the MFM driver...
143 */
144#ifndef DEBUG
145/*#define DEBUG */
146#endif
147/*
148 * End of configuration
149 */
150
151
152/*
153 * This structure contains all information to do with a particular physical
154 * device.
155 */
156struct mfm_info {
157 unsigned char sectors;
158 unsigned char heads;
159 unsigned short cylinders;
160 unsigned short lowcurrent;
161 unsigned short precomp;
162#define NO_TRACK -1
163#define NEED_1_RECAL -2
164#define NEED_2_RECAL -3
165 int cylinder;
166 struct {
167 char recal;
168 char report;
169 char abort;
170 } errors;
171} mfm_info[MFM_MAXDRIVES];
172
173#define MFM_DRV_INFO mfm_info[raw_cmd.dev]
174
175/* Stuff from the assembly routines */
176extern unsigned int hdc63463_baseaddress; /* Controller base address */
177extern unsigned int hdc63463_irqpolladdress; /* Address to read to test for int */
178extern unsigned int hdc63463_irqpollmask; /* Mask for irq register */
179extern unsigned int hdc63463_dataptr; /* Pointer to kernel data space to DMA */
180extern int hdc63463_dataleft; /* Number of bytes left to transfer */
181
182
183
184
185static int lastspecifieddrive;
186static unsigned Busy;
187
188static unsigned int PartFragRead; /* The number of sectors which have been read
189 during a partial read split over two
190 cylinders. If 0 it means a partial
191 read did not occur. */
192
193static unsigned int PartFragRead_RestartBlock; /* Where to restart on a split access */
194static unsigned int PartFragRead_SectorsLeft; /* Where to restart on a split access */
195
196static int Sectors256LeftInCurrent; /* i.e. 256 byte sectors left in current */
197static int SectorsLeftInRequest; /* i.e. blocks left in the thing mfm_request was called for */
198static int Copy_Sector; /* The 256 byte sector we are currently at - fragments need to know
199 where to take over */
200static char *Copy_buffer;
201
202
203static void mfm_seek(void);
204static void mfm_rerequest(void);
205static void mfm_request(void);
206static void mfm_specify (void);
207static void issue_request(unsigned int block, unsigned int nsect,
208 struct request *req);
209
210static unsigned int mfm_addr; /* Controller address */
211static unsigned int mfm_IRQPollLoc; /* Address to read for IRQ information */
212static unsigned int mfm_irqenable; /* Podule IRQ enable location */
213static unsigned char mfm_irq; /* Interrupt number */
214static int mfm_drives = 0; /* drives available */
215static int mfm_status = 0; /* interrupt status */
216static int *errors;
217
218static struct rawcmd {
219 unsigned int dev;
220 unsigned int cylinder;
221 unsigned int head;
222 unsigned int sector;
223 unsigned int cmdtype;
224 unsigned int cmdcode;
225 unsigned char cmddata[16];
226 unsigned int cmdlen;
227} raw_cmd;
228
229static unsigned char result[16];
230
231static struct cont {
232 void (*interrupt) (void); /* interrupt handler */
233 void (*error) (void); /* error handler */
234 void (*redo) (void); /* redo handler */
235 void (*done) (int st); /* done handler */
236} *cont = NULL;
237
238#if 0
239static struct tq_struct mfm_tq = {0, 0, (void (*)(void *)) NULL, 0};
240#endif
241
242int number_mfm_drives = 1;
243
244/* ------------------------------------------------------------------------------------------ */
245/*
246 * From the HD63463 data sheet from Hitachi Ltd.
247 */
248
249#define MFM_COMMAND (mfm_addr + 0)
250#define MFM_DATAOUT (mfm_addr + 1)
251#define MFM_STATUS (mfm_addr + 8)
252#define MFM_DATAIN (mfm_addr + 9)
253
254#define CMD_ABT 0xF0 /* Abort */
255#define CMD_SPC 0xE8 /* Specify */
256#define CMD_TST 0xE0 /* Test */
257#define CMD_RCLB 0xC8 /* Recalibrate */
258#define CMD_SEK 0xC0 /* Seek */
259#define CMD_WFS 0xAB /* Write Format Skew */
260#define CMD_WFM 0xA3 /* Write Format */
261#define CMD_MTB 0x90 /* Memory to buffer */
262#define CMD_CMPD 0x88 /* Compare data */
263#define CMD_WD 0x87 /* Write data */
264#define CMD_RED 0x70 /* Read erroneous data */
265#define CMD_RIS 0x68 /* Read ID skew */
266#define CMD_FID 0x61 /* Find ID */
267#define CMD_RID 0x60 /* Read ID */
268#define CMD_BTM 0x50 /* Buffer to memory */
269#define CMD_CKD 0x48 /* Check data */
270#define CMD_RD 0x40 /* Read data */
271#define CMD_OPBW 0x38 /* Open buffer write */
272#define CMD_OPBR 0x30 /* Open buffer read */
273#define CMD_CKV 0x28 /* Check drive */
274#define CMD_CKE 0x20 /* Check ECC */
275#define CMD_POD 0x18 /* Polling disable */
276#define CMD_POL 0x10 /* Polling enable */
277#define CMD_RCAL 0x08 /* Recall */
278
279#define STAT_BSY 0x8000 /* Busy */
280#define STAT_CPR 0x4000 /* Command Parameter Rejection */
281#define STAT_CED 0x2000 /* Command end */
282#define STAT_SED 0x1000 /* Seek end */
283#define STAT_DER 0x0800 /* Drive error */
284#define STAT_ABN 0x0400 /* Abnormal end */
285#define STAT_POL 0x0200 /* Polling */
286
287/* ------------------------------------------------------------------------------------------ */
288#ifdef DEBUG
289static void console_printf(const char *fmt,...)
290{
291 static char buffer[2048]; /* Arbitary! */
292 extern void console_print(const char *);
293 unsigned long flags;
294 va_list ap;
295
296 local_irq_save(flags);
297
298 va_start(ap, fmt);
299 vsprintf(buffer, fmt, ap);
300 console_print(buffer);
301 va_end(fmt);
302
303 local_irq_restore(flags);
304}; /* console_printf */
305
306#define DBG(x...) console_printf(x)
307#else
308#define DBG(x...)
309#endif
310
311static void print_status(void)
312{
313 char *error;
314 static char *errors[] = {
315 "no error",
316 "command aborted",
317 "invalid command",
318 "parameter error",
319 "not initialised",
320 "rejected TEST",
321 "no useld",
322 "write fault",
323 "not ready",
324 "no scp",
325 "in seek",
326 "invalid NCA",
327 "invalid step rate",
328 "seek error",
329 "over run",
330 "invalid PHA",
331 "data field EEC error",
332 "data field CRC error",
333 "error corrected",
334 "data field fatal error",
335 "no data am",
336 "not hit",
337 "ID field CRC error",
338 "time over",
339 "no ID am",
340 "not writable"
341 };
342 if (result[1] < 0x65)
343 error = errors[result[1] >> 2];
344 else
345 error = "unknown";
346 printk("(");
347 if (mfm_status & STAT_BSY) printk("BSY ");
348 if (mfm_status & STAT_CPR) printk("CPR ");
349 if (mfm_status & STAT_CED) printk("CED ");
350 if (mfm_status & STAT_SED) printk("SED ");
351 if (mfm_status & STAT_DER) printk("DER ");
352 if (mfm_status & STAT_ABN) printk("ABN ");
353 if (mfm_status & STAT_POL) printk("POL ");
354 printk(") SSB = %X (%s)\n", result[1], error);
355
356}
357
358/* ------------------------------------------------------------------------------------- */
359
360static void issue_command(int command, unsigned char *cmdb, int len)
361{
362 int status;
363#ifdef DEBUG
364 int i;
365 console_printf("issue_command: %02X: ", command);
366 for (i = 0; i < len; i++)
367 console_printf("%02X ", cmdb[i]);
368 console_printf("\n");
369#endif
370
371 do {
372 status = inw(MFM_STATUS);
373 } while (status & (STAT_BSY | STAT_POL));
374 DBG("issue_command: status after pol/bsy loop: %02X:\n ", status >> 8);
375
376 if (status & (STAT_CPR | STAT_CED | STAT_SED | STAT_DER | STAT_ABN)) {
377 outw(CMD_RCAL, MFM_COMMAND);
378 while (inw(MFM_STATUS) & STAT_BSY);
379 }
380 status = inw(MFM_STATUS);
381 DBG("issue_command: status before parameter issue: %02X:\n ", status >> 8);
382
383 while (len > 0) {
384 outw(cmdb[1] | (cmdb[0] << 8), MFM_DATAOUT);
385 len -= 2;
386 cmdb += 2;
387 }
388 status = inw(MFM_STATUS);
389 DBG("issue_command: status before command issue: %02X:\n ", status >> 8);
390
391 outw(command, MFM_COMMAND);
392 status = inw(MFM_STATUS);
393 DBG("issue_command: status immediately after command issue: %02X:\n ", status >> 8);
394}
395
396static void wait_for_completion(void)
397{
398 while ((mfm_status = inw(MFM_STATUS)) & STAT_BSY);
399}
400
401static void wait_for_command_end(void)
402{
403 int i;
404
405 while (!((mfm_status = inw(MFM_STATUS)) & STAT_CED));
406
407 for (i = 0; i < 16;) {
408 int in;
409 in = inw(MFM_DATAIN);
410 result[i++] = in >> 8;
411 result[i++] = in;
412 }
413 outw (CMD_RCAL, MFM_COMMAND);
414}
415
416/* ------------------------------------------------------------------------------------- */
417
418static void mfm_rw_intr(void)
419{
420 int old_status; /* Holds status on entry, we read to see if the command just finished */
421#ifdef DEBUG
422 console_printf("mfm_rw_intr...dataleft=%d\n", hdc63463_dataleft);
423 print_status();
424#endif
425
426 /* Now don't handle the error until BSY drops */
427 if ((mfm_status & (STAT_DER | STAT_ABN)) && ((mfm_status&STAT_BSY)==0)) {
428 /* Something has gone wrong - let's try that again */
429 outw(CMD_RCAL, MFM_COMMAND); /* Clear interrupt condition */
430 if (cont) {
431 DBG("mfm_rw_intr: DER/ABN err\n");
432 cont->error();
433 cont->redo();
434 };
435 return;
436 };
437
438 /* OK so what ever happened it's not an error, now I reckon we are left between
439 a choice of command end or some data which is ready to be collected */
440 /* I think we have to transfer data while the interrupt line is on and its
441 not any other type of interrupt */
442 if (rq_data_dir(CURRENT) == WRITE) {
443 extern void hdc63463_writedma(void);
444 if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) {
445 printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n");
446 if (cont) {
447 cont->error();
448 cont->redo();
449 };
450 return;
451 };
452 hdc63463_writedma();
453 } else {
454 extern void hdc63463_readdma(void);
455 if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) {
456 printk("mfm_rw_intr: Apparent DMA read request when no more to DMA\n");
457 if (cont) {
458 cont->error();
459 cont->redo();
460 };
461 return;
462 };
463 DBG("Going to try read dma..............status=0x%x, buffer=%p\n", mfm_status, hdc63463_dataptr);
464 hdc63463_readdma();
465 }; /* Read */
466
467 if (hdc63463_dataptr != ((unsigned int) Copy_buffer + 256)) {
468 /* If we didn't actually manage to get any data on this interrupt - but why? We got the interrupt */
469 /* Ah - well looking at the status its just when we get command end; so no problem */
470 /*console_printf("mfm: dataptr mismatch. dataptr=0x%08x Copy_buffer+256=0x%08p\n",
471 hdc63463_dataptr,Copy_buffer+256);
472 print_status(); */
473 } else {
474 Sectors256LeftInCurrent--;
475 Copy_buffer += 256;
476 Copy_Sector++;
477
478 /* We have come to the end of this request */
479 if (!Sectors256LeftInCurrent) {
480 DBG("mfm: end_request for CURRENT=0x%p CURRENT(sector=%d current_nr_sectors=%d nr_sectors=%d)\n",
481 CURRENT, CURRENT->sector, CURRENT->current_nr_sectors, CURRENT->nr_sectors);
482
483 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
484 CURRENT->sector += CURRENT->current_nr_sectors;
485 SectorsLeftInRequest -= CURRENT->current_nr_sectors;
486
487 end_request(CURRENT, 1);
488 if (SectorsLeftInRequest) {
489 hdc63463_dataptr = (unsigned int) CURRENT->buffer;
490 Copy_buffer = CURRENT->buffer;
491 Sectors256LeftInCurrent = CURRENT->current_nr_sectors * 2;
492 errors = &(CURRENT->errors);
493 /* These should match the present calculations of the next logical sector
494 on the device
495 Copy_Sector=CURRENT->sector*2; */
496
497 if (Copy_Sector != CURRENT->sector * 2)
498#ifdef DEBUG
499 /*console_printf*/printk("mfm: Copy_Sector mismatch. Copy_Sector=%d CURRENT->sector*2=%d\n",
500 Copy_Sector, CURRENT->sector * 2);
501#else
502 printk("mfm: Copy_Sector mismatch! Eek!\n");
503#endif
504 }; /* CURRENT */
505 }; /* Sectors256LeftInCurrent */
506 };
507
508 old_status = mfm_status;
509 mfm_status = inw(MFM_STATUS);
510 if (mfm_status & (STAT_DER | STAT_ABN)) {
511 /* Something has gone wrong - let's try that again */
512 if (cont) {
513 DBG("mfm_rw_intr: DER/ABN error\n");
514 cont->error();
515 cont->redo();
516 };
517 return;
518 };
519
520 /* If this code wasn't entered due to command_end but there is
521 now a command end we must read the command results out. If it was
522 entered like this then mfm_interrupt_handler would have done the
523 job. */
524 if ((!((old_status & (STAT_CPR | STAT_BSY)) == STAT_CPR)) &&
525 ((mfm_status & (STAT_CPR | STAT_BSY)) == STAT_CPR)) {
526 int len = 0;
527 while (len < 16) {
528 int in;
529 in = inw(MFM_DATAIN);
530 result[len++] = in >> 8;
531 result[len++] = in;
532 };
533 }; /* Result read */
534
535 /*console_printf ("mfm_rw_intr nearexit [%02X]\n", __raw_readb(mfm_IRQPollLoc)); */
536
537 /* If end of command move on */
538 if (mfm_status & (STAT_CED)) {
539 outw(CMD_RCAL, MFM_COMMAND); /* Clear interrupt condition */
540 /* End of command - trigger the next command */
541 if (cont) {
542 cont->done(1);
543 }
544 DBG("mfm_rw_intr: returned from cont->done\n");
545 } else {
546 /* Its going to generate another interrupt */
547 do_mfm = mfm_rw_intr;
548 };
549}
550
551static void mfm_setup_rw(void)
552{
553 DBG("setting up for rw...\n");
554
555 do_mfm = mfm_rw_intr;
556 issue_command(raw_cmd.cmdcode, raw_cmd.cmddata, raw_cmd.cmdlen);
557}
558
559static void mfm_recal_intr(void)
560{
561#ifdef DEBUG
562 console_printf("recal intr - status = ");
563 print_status();
564#endif
565 outw(CMD_RCAL, MFM_COMMAND); /* Clear interrupt condition */
566 if (mfm_status & (STAT_DER | STAT_ABN)) {
567 printk("recal failed\n");
568 MFM_DRV_INFO.cylinder = NEED_2_RECAL;
569 if (cont) {
570 cont->error();
571 cont->redo();
572 }
573 return;
574 }
575 /* Thats seek end - we are finished */
576 if (mfm_status & STAT_SED) {
577 issue_command(CMD_POD, NULL, 0);
578 MFM_DRV_INFO.cylinder = 0;
579 mfm_seek();
580 return;
581 }
582 /* Command end without seek end (see data sheet p.20) for parallel seek
583 - we have to send a POL command to wait for the seek */
584 if (mfm_status & STAT_CED) {
585 do_mfm = mfm_recal_intr;
586 issue_command(CMD_POL, NULL, 0);
587 return;
588 }
589 printk("recal: unknown status\n");
590}
591
592static void mfm_seek_intr(void)
593{
594#ifdef DEBUG
595 console_printf("seek intr - status = ");
596 print_status();
597#endif
598 outw(CMD_RCAL, MFM_COMMAND); /* Clear interrupt condition */
599 if (mfm_status & (STAT_DER | STAT_ABN)) {
600 printk("seek failed\n");
601 MFM_DRV_INFO.cylinder = NEED_2_RECAL;
602 if (cont) {
603 cont->error();
604 cont->redo();
605 }
606 return;
607 }
608 if (mfm_status & STAT_SED) {
609 issue_command(CMD_POD, NULL, 0);
610 MFM_DRV_INFO.cylinder = raw_cmd.cylinder;
611 mfm_seek();
612 return;
613 }
614 if (mfm_status & STAT_CED) {
615 do_mfm = mfm_seek_intr;
616 issue_command(CMD_POL, NULL, 0);
617 return;
618 }
619 printk("seek: unknown status\n");
620}
621
622/* IDEA2 seems to work better - its what RiscOS sets my
623 * disc to - on its SECOND call to specify!
624 */
625#define IDEA2
626#ifndef IDEA2
627#define SPEC_SL 0x16
628#define SPEC_SH 0xa9 /* Step pulse high=21, Record Length=001 (256 bytes) */
629#else
630#define SPEC_SL 0x00 /* OM2 - SL - step pulse low */
631#define SPEC_SH 0x21 /* Step pulse high=4, Record Length=001 (256 bytes) */
632#endif
633
634static void mfm_setupspecify (int drive, unsigned char *cmdb)
635{
636 cmdb[0] = 0x1f; /* OM0 - !SECT,!MOD,!DIF,PADP,ECD,CRCP,CRCI,ACOR */
637 cmdb[1] = 0xc3; /* OM1 - DTM,BRST,!CEDM,!SEDM,!DERM,0,AMEX,PSK */
638 cmdb[2] = SPEC_SL; /* OM2 - SL - step pulse low */
639 cmdb[3] = (number_mfm_drives == 1) ? 0x02 : 0x06; /* 1 or 2 drives */
640 cmdb[4] = 0xfc | ((mfm_info[drive].cylinders - 1) >> 8);/* RW time over/high part of number of cylinders */
641 cmdb[5] = mfm_info[drive].cylinders - 1; /* low part of number of cylinders */
642 cmdb[6] = mfm_info[drive].heads - 1; /* Number of heads */
643 cmdb[7] = mfm_info[drive].sectors - 1; /* Number of sectors */
644 cmdb[8] = SPEC_SH;
645 cmdb[9] = 0x0a; /* gap length 1 */
646 cmdb[10] = 0x0d; /* gap length 2 */
647 cmdb[11] = 0x0c; /* gap length 3 */
648 cmdb[12] = (mfm_info[drive].precomp - 1) >> 8; /* pre comp cylinder */
649 cmdb[13] = mfm_info[drive].precomp - 1;
650 cmdb[14] = (mfm_info[drive].lowcurrent - 1) >> 8; /* Low current cylinder */
651 cmdb[15] = mfm_info[drive].lowcurrent - 1;
652}
653
654static void mfm_specify (void)
655{
656 unsigned char cmdb[16];
657
658 DBG("specify...dev=%d lastspecified=%d\n", raw_cmd.dev, lastspecifieddrive);
659 mfm_setupspecify (raw_cmd.dev, cmdb);
660
661 issue_command (CMD_SPC, cmdb, 16);
662 /* Ensure that we will do another specify if we move to the other drive */
663 lastspecifieddrive = raw_cmd.dev;
664 wait_for_completion();
665}
666
667static void mfm_seek(void)
668{
669 unsigned char cmdb[4];
670
671 DBG("seeking...\n");
672 if (MFM_DRV_INFO.cylinder < 0) {
673 do_mfm = mfm_recal_intr;
674 DBG("mfm_seek: about to call specify\n");
675 mfm_specify (); /* DAG added this */
676
677 cmdb[0] = raw_cmd.dev + 1;
678 cmdb[1] = 0;
679
680 issue_command(CMD_RCLB, cmdb, 2);
681 return;
682 }
683 if (MFM_DRV_INFO.cylinder != raw_cmd.cylinder) {
684 cmdb[0] = raw_cmd.dev + 1;
685 cmdb[1] = 0; /* raw_cmd.head; DAG: My data sheet says this should be 0 */
686 cmdb[2] = raw_cmd.cylinder >> 8;
687 cmdb[3] = raw_cmd.cylinder;
688
689 do_mfm = mfm_seek_intr;
690 issue_command(CMD_SEK, cmdb, 4);
691 } else
692 mfm_setup_rw();
693}
694
695static void mfm_initialise(void)
696{
697 DBG("init...\n");
698 mfm_seek();
699}
700
701static void request_done(int uptodate)
702{
703 DBG("mfm:request_done\n");
704 if (uptodate) {
705 unsigned char block[2] = {0, 0};
706
707 /* Apparently worked - let's check bytes left to DMA */
708 if (hdc63463_dataleft != (PartFragRead_SectorsLeft * 256)) {
709 printk("mfm: request_done - dataleft=%d - should be %d - Eek!\n", hdc63463_dataleft, PartFragRead_SectorsLeft * 256);
710 end_request(CURRENT, 0);
711 Busy = 0;
712 };
713 /* Potentially this means that we've done; but we might be doing
714 a partial access, (over two cylinders) or we may have a number
715 of fragments in an image file. First let's deal with partial accesss
716 */
717 if (PartFragRead) {
718 /* Yep - a partial access */
719
720 /* and issue the remainder */
721 issue_request(PartFragRead_RestartBlock, PartFragRead_SectorsLeft, CURRENT);
722 return;
723 }
724
725 /* ah well - perhaps there is another fragment to go */
726
727 /* Increment pointers/counts to start of next fragment */
728 if (SectorsLeftInRequest > 0) printk("mfm: SectorsLeftInRequest>0 - Eek! Shouldn't happen!\n");
729
730 /* No - its the end of the line */
731 /* end_request's should have happened at the end of sector DMAs */
732 /* Turns Drive LEDs off - may slow it down? */
733 if (!elv_next_request(QUEUE))
734 issue_command(CMD_CKV, block, 2);
735
736 Busy = 0;
737 DBG("request_done: About to mfm_request\n");
738 /* Next one please */
739 mfm_request(); /* Moved from mfm_rw_intr */
740 DBG("request_done: returned from mfm_request\n");
741 } else {
742 printk("mfm:request_done: update=0\n");
743 end_request(CURRENT, 0);
744 Busy = 0;
745 }
746}
747
748static void error_handler(void)
749{
750 printk("error detected... status = ");
751 print_status();
752 (*errors)++;
753 if (*errors > MFM_DRV_INFO.errors.abort)
754 cont->done(0);
755 if (*errors > MFM_DRV_INFO.errors.recal)
756 MFM_DRV_INFO.cylinder = NEED_2_RECAL;
757}
758
759static void rw_interrupt(void)
760{
761 printk("rw_interrupt\n");
762}
763
764static struct cont rw_cont =
765{
766 rw_interrupt,
767 error_handler,
768 mfm_rerequest,
769 request_done
770};
771
772/*
773 * Actually gets round to issuing the request - note everything at this
774 * point is in 256 byte sectors not Linux 512 byte blocks
775 */
776static void issue_request(unsigned int block, unsigned int nsect,
777 struct request *req)
778{
779 struct gendisk *disk = req->rq_disk;
780 struct mfm_info *p = disk->private_data;
781 int track, start_head, start_sector;
782 int sectors_to_next_cyl;
783 dev = p - mfm_info;
784
785 track = block / p->sectors;
786 start_sector = block % p->sectors;
787 start_head = track % p->heads;
788
789 /* First get the number of whole tracks which are free before the next
790 track */
791 sectors_to_next_cyl = (p->heads - (start_head + 1)) * p->sectors;
792 /* Then add in the number of sectors left on this track */
793 sectors_to_next_cyl += (p->sectors - start_sector);
794
795 DBG("issue_request: mfm_info[dev].sectors=%d track=%d\n", p->sectors, track);
796
797 raw_cmd.dev = dev;
798 raw_cmd.sector = start_sector;
799 raw_cmd.head = start_head;
800 raw_cmd.cylinder = track / p->heads;
801 raw_cmd.cmdtype = CURRENT->cmd;
802 raw_cmd.cmdcode = rq_data_dir(CURRENT) == WRITE ? CMD_WD : CMD_RD;
803 raw_cmd.cmddata[0] = dev + 1; /* DAG: +1 to get US */
804 raw_cmd.cmddata[1] = raw_cmd.head;
805 raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8;
806 raw_cmd.cmddata[3] = raw_cmd.cylinder;
807 raw_cmd.cmddata[4] = raw_cmd.head;
808 raw_cmd.cmddata[5] = raw_cmd.sector;
809
810 /* Was == and worked - how the heck??? */
811 if (lastspecifieddrive != raw_cmd.dev)
812 mfm_specify ();
813
814 if (nsect <= sectors_to_next_cyl) {
815 raw_cmd.cmddata[6] = nsect >> 8;
816 raw_cmd.cmddata[7] = nsect;
817 PartFragRead = 0; /* All in one */
818 PartFragRead_SectorsLeft = 0; /* Must set this - used in DMA calcs */
819 } else {
820 raw_cmd.cmddata[6] = sectors_to_next_cyl >> 8;
821 raw_cmd.cmddata[7] = sectors_to_next_cyl;
822 PartFragRead = sectors_to_next_cyl; /* only do this many this time */
823 PartFragRead_RestartBlock = block + sectors_to_next_cyl; /* Where to restart from */
824 PartFragRead_SectorsLeft = nsect - sectors_to_next_cyl;
825 }
826 raw_cmd.cmdlen = 8;
827
828 /* Setup DMA pointers */
829 hdc63463_dataptr = (unsigned int) Copy_buffer;
830 hdc63463_dataleft = nsect * 256; /* Better way? */
831
832 DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n",
833 raw_cmd.dev + 'a', rq_data_dir(CURRENT) == READ ? "read" : "writ",
834 raw_cmd.cylinder,
835 raw_cmd.head,
836 raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT);
837
838 cont = &rw_cont;
839 errors = &(CURRENT->errors);
840#if 0
841 mfm_tq.routine = (void (*)(void *)) mfm_initialise;
842 queue_task(&mfm_tq, &tq_immediate);
843 mark_bh(IMMEDIATE_BH);
844#else
845 mfm_initialise();
846#endif
847} /* issue_request */
848
849/*
850 * Called when an error has just happened - need to trick mfm_request
851 * into thinking we weren't busy
852 *
853 * Turn off ints - mfm_request expects them this way
854 */
855static void mfm_rerequest(void)
856{
857 DBG("mfm_rerequest\n");
858 cli();
859 Busy = 0;
860 mfm_request();
861}
862
863static struct gendisk *mfm_gendisk[2];
864
865static void mfm_request(void)
866{
867 DBG("mfm_request CURRENT=%p Busy=%d\n", CURRENT, Busy);
868
869 /* If we are still processing then return; we will get called again */
870 if (Busy) {
871 /* Again seems to be common in 1.3.45 */
872 /*DBG*/printk("mfm_request: Exiting due to busy\n");
873 return;
874 }
875 Busy = 1;
876
877 while (1) {
878 unsigned int block, nsect;
879 struct gendisk *disk;
880
881 DBG("mfm_request: loop start\n");
882 sti();
883
884 DBG("mfm_request: before !CURRENT\n");
885
886 if (!CURRENT) {
887 printk("mfm_request: Exiting due to empty queue (pre)\n");
888 do_mfm = NULL;
889 Busy = 0;
890 return;
891 }
892
893 DBG("mfm_request: before arg extraction\n");
894
895 disk = CURRENT->rq_disk;
896 block = CURRENT->sector;
897 nsect = CURRENT->nr_sectors;
898 if (block >= get_capacity(disk) ||
899 block+nsect > get_capacity(disk)) {
900 printk("%s: bad access: block=%d, count=%d, nr_sects=%ld\n",
901 disk->disk_name, block, nsect, get_capacity(disk));
902 printk("mfm: continue 1\n");
903 end_request(CURRENT, 0);
904 Busy = 0;
905 continue;
906 }
907
908 /* DAG: Linux doesn't cope with this - even though it has an array telling
909 it the hardware block size - silly */
910 block <<= 1; /* Now in 256 byte sectors */
911 nsect <<= 1; /* Ditto */
912
913 SectorsLeftInRequest = nsect >> 1;
914 Sectors256LeftInCurrent = CURRENT->current_nr_sectors * 2;
915 Copy_buffer = CURRENT->buffer;
916 Copy_Sector = CURRENT->sector << 1;
917
918 DBG("mfm_request: block after offset=%d\n", block);
919
920 issue_request(block, nsect, CURRENT);
921
922 break;
923 }
924 DBG("mfm_request: Dropping out bottom\n");
925}
926
927static void do_mfm_request(struct request_queue *q)
928{
929 DBG("do_mfm_request: about to mfm_request\n");
930 mfm_request();
931}
932
933static void mfm_interrupt_handler(int unused, void *dev_id)
934{
935 void (*handler) (void) = do_mfm;
936
937 do_mfm = NULL;
938
939 DBG("mfm_interrupt_handler (handler=0x%p)\n", handler);
940
941 mfm_status = inw(MFM_STATUS);
942
943 /* If CPR (Command Parameter Reject) and not busy it means that the command
944 has some return message to give us */
945 if ((mfm_status & (STAT_CPR | STAT_BSY)) == STAT_CPR) {
946 int len = 0;
947 while (len < 16) {
948 int in;
949 in = inw(MFM_DATAIN);
950 result[len++] = in >> 8;
951 result[len++] = in;
952 }
953 }
954 if (handler) {
955 handler();
956 return;
957 }
958 outw (CMD_RCAL, MFM_COMMAND); /* Clear interrupt condition */
959 printk ("mfm: unexpected interrupt - status = ");
960 print_status ();
961 while (1);
962}
963
964
965
966
967
968/*
969 * Tell the user about the drive if we decided it exists.
970 */
971static void mfm_geometry(int drive)
972{
973 struct mfm_info *p = mfm_info + drive;
974 struct gendisk *disk = mfm_gendisk[drive];
975 disk->private_data = p;
976 if (p->cylinders)
977 printk ("%s: %dMB CHS=%d/%d/%d LCC=%d RECOMP=%d\n",
978 disk->disk_name,
979 p->cylinders * p->heads * p->sectors / 4096,
980 p->cylinders, p->heads, p->sectors,
981 p->lowcurrent, p->precomp);
982 set_capacity(disk, p->cylinders * p->heads * p->sectors / 2);
983}
984
985#ifdef CONFIG_BLK_DEV_MFM_AUTODETECT
986/*
987 * Attempt to detect a drive and find its geometry. The drive has already been
988 * specified...
989 *
990 * We first recalibrate the disk, then try to probe sectors, heads and then
991 * cylinders. NOTE! the cylinder probe may break drives. The xd disk driver
992 * does something along these lines, so I assume that most drives are up to
993 * this mistreatment...
994 */
995static int mfm_detectdrive (int drive)
996{
997 unsigned int mingeo[3], maxgeo[3];
998 unsigned int attribute, need_recal = 1;
999 unsigned char cmdb[8];
1000
1001 memset (mingeo, 0, sizeof (mingeo));
1002 maxgeo[0] = mfm_info[drive].sectors;
1003 maxgeo[1] = mfm_info[drive].heads;
1004 maxgeo[2] = mfm_info[drive].cylinders;
1005
1006 cmdb[0] = drive + 1;
1007 cmdb[6] = 0;
1008 cmdb[7] = 1;
1009 for (attribute = 0; attribute < 3; attribute++) {
1010 while (mingeo[attribute] != maxgeo[attribute]) {
1011 unsigned int variable;
1012
1013 variable = (maxgeo[attribute] + mingeo[attribute]) >> 1;
1014 cmdb[1] = cmdb[2] = cmdb[3] = cmdb[4] = cmdb[5] = 0;
1015
1016 if (need_recal) {
1017 int tries = 5;
1018
1019 do {
1020 issue_command (CMD_RCLB, cmdb, 2);
1021 wait_for_completion ();
1022 wait_for_command_end ();
1023 if (result[1] == 0x20)
1024 break;
1025 } while (result[1] && --tries);
1026 if (result[1]) {
1027 outw (CMD_RCAL, MFM_COMMAND);
1028 return 0;
1029 }
1030 need_recal = 0;
1031 }
1032
1033 switch (attribute) {
1034 case 0:
1035 cmdb[5] = variable;
1036 issue_command (CMD_CMPD, cmdb, 8);
1037 break;
1038 case 1:
1039 cmdb[1] = variable;
1040 cmdb[4] = variable;
1041 issue_command (CMD_CMPD, cmdb, 8);
1042 break;
1043 case 2:
1044 cmdb[2] = variable >> 8;
1045 cmdb[3] = variable;
1046 issue_command (CMD_SEK, cmdb, 4);
1047 break;
1048 }
1049 wait_for_completion ();
1050 wait_for_command_end ();
1051
1052 switch (result[1]) {
1053 case 0x00:
1054 case 0x50:
1055 mingeo[attribute] = variable + 1;
1056 break;
1057
1058 case 0x20:
1059 outw (CMD_RCAL, MFM_COMMAND);
1060 return 0;
1061
1062 case 0x24:
1063 need_recal = 1;
1064 default:
1065 maxgeo[attribute] = variable;
1066 break;
1067 }
1068 }
1069 }
1070 mfm_info[drive].cylinders = mingeo[2];
1071 mfm_info[drive].lowcurrent = mingeo[2];
1072 mfm_info[drive].precomp = mingeo[2] / 2;
1073 mfm_info[drive].heads = mingeo[1];
1074 mfm_info[drive].sectors = mingeo[0];
1075 outw (CMD_RCAL, MFM_COMMAND);
1076 return 1;
1077}
1078#endif
1079
1080/*
1081 * Initialise all drive information for this controller.
1082 */
1083static int mfm_initdrives(void)
1084{
1085 int drive;
1086
1087 if (number_mfm_drives > MFM_MAXDRIVES) {
1088 number_mfm_drives = MFM_MAXDRIVES;
1089 printk("No. of ADFS MFM drives is greater than MFM_MAXDRIVES - you can't have that many!\n");
1090 }
1091
1092 for (drive = 0; drive < number_mfm_drives; drive++) {
1093 mfm_info[drive].lowcurrent = 1;
1094 mfm_info[drive].precomp = 1;
1095 mfm_info[drive].cylinder = -1;
1096 mfm_info[drive].errors.recal = 0;
1097 mfm_info[drive].errors.report = 0;
1098 mfm_info[drive].errors.abort = 4;
1099
1100#ifdef CONFIG_BLK_DEV_MFM_AUTODETECT
1101 mfm_info[drive].cylinders = 1024;
1102 mfm_info[drive].heads = 8;
1103 mfm_info[drive].sectors = 64;
1104 {
1105 unsigned char cmdb[16];
1106
1107 mfm_setupspecify (drive, cmdb);
1108 cmdb[1] &= ~0x81;
1109 issue_command (CMD_SPC, cmdb, 16);
1110 wait_for_completion ();
1111 if (!mfm_detectdrive (drive)) {
1112 mfm_info[drive].cylinders = 0;
1113 mfm_info[drive].heads = 0;
1114 mfm_info[drive].sectors = 0;
1115 }
1116 cmdb[0] = cmdb[1] = 0;
1117 issue_command (CMD_CKV, cmdb, 2);
1118 }
1119#else
1120 mfm_info[drive].cylinders = 1; /* its going to have to figure it out from the partition info */
1121 mfm_info[drive].heads = 4;
1122 mfm_info[drive].sectors = 32;
1123#endif
1124 }
1125 return number_mfm_drives;
1126}
1127
1128
1129
1130/*
1131 * The 'front' end of the mfm driver follows...
1132 */
1133
1134static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1135{
1136 struct mfm_info *p = bdev->bd_disk->private_data;
1137
1138 geo->heads = p->heads;
1139 geo->sectors = p->sectors;
1140 geo->cylinders = p->cylinders;
1141 return 0;
1142}
1143
1144/*
1145 * This is to handle various kernel command line parameters
1146 * specific to this driver.
1147 */
1148void mfm_setup(char *str, int *ints)
1149{
1150 return;
1151}
1152
1153/*
1154 * Set the CHS from the ADFS boot block if it is present. This is not ideal
1155 * since if there are any non-ADFS partitions on the disk, this won't work!
1156 * Hence, I want to get rid of this...
1157 */
1158void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
1159 unsigned char heads, unsigned int secsize)
1160{
1161 struct mfm_info *p = bdev->bd_disk->private_data;
1162 int drive = p - mfm_info;
1163 unsigned long disksize = bdev->bd_inode->i_size;
1164
1165 if (p->cylinders == 1) {
1166 p->sectors = secsptrack;
1167 p->heads = heads;
1168 p->cylinders = discsize / (secsptrack * heads * secsize);
1169
1170 if ((heads < 1) || (p->cylinders > 1024)) {
1171 printk("%s: Insane disc shape! Setting to 512/4/32\n",
1172 bdev->bd_disk->disk_name);
1173
1174 /* These values are fairly arbitary, but are there so that if your
1175 * lucky you can pick apart your disc to find out what is going on -
1176 * I reckon these figures won't hurt MOST drives
1177 */
1178 p->sectors = 32;
1179 p->heads = 4;
1180 p->cylinders = 512;
1181 }
1182 if (raw_cmd.dev == drive)
1183 mfm_specify ();
1184 mfm_geometry (drive);
1185 }
1186}
1187
1188static struct block_device_operations mfm_fops =
1189{
1190 .owner = THIS_MODULE,
1191 .getgeo = mfm_getgeo,
1192};
1193
1194/*
1195 * See if there is a controller at the address presently at mfm_addr
1196 *
1197 * We check to see if the controller is busy - if it is, we abort it first,
1198 * and check that the chip is no longer busy after at least 180 clock cycles.
1199 * We then issue a command and check that the BSY or CPR bits are set.
1200 */
1201static int mfm_probecontroller (unsigned int mfm_addr)
1202{
1203 if (inw (MFM_STATUS) & STAT_BSY) {
1204 outw (CMD_ABT, MFM_COMMAND);
1205 udelay (50);
1206 if (inw (MFM_STATUS) & STAT_BSY)
1207 return 0;
1208 }
1209
1210 if (inw (MFM_STATUS) & STAT_CED)
1211 outw (CMD_RCAL, MFM_COMMAND);
1212
1213 outw (CMD_SEK, MFM_COMMAND);
1214
1215 if (inw (MFM_STATUS) & (STAT_BSY | STAT_CPR)) {
1216 unsigned int count = 2000;
1217 while (inw (MFM_STATUS) & STAT_BSY) {
1218 udelay (500);
1219 if (!--count)
1220 return 0;
1221 }
1222
1223 outw (CMD_RCAL, MFM_COMMAND);
1224 }
1225 return 1;
1226}
1227
1228static int mfm_do_init(unsigned char irqmask)
1229{
1230 int i, ret;
1231
1232 printk("mfm: found at address %08X, interrupt %d\n", mfm_addr, mfm_irq);
1233
1234 ret = -EBUSY;
1235 if (!request_region (mfm_addr, 10, "mfm"))
1236 goto out1;
1237
1238 ret = register_blkdev(MAJOR_NR, "mfm");
1239 if (ret)
1240 goto out2;
1241
1242 /* Stuff for the assembler routines to get to */
1243 hdc63463_baseaddress = ioaddr(mfm_addr);
1244 hdc63463_irqpolladdress = mfm_IRQPollLoc;
1245 hdc63463_irqpollmask = irqmask;
1246
1247 mfm_queue = blk_init_queue(do_mfm_request, &mfm_lock);
1248 if (!mfm_queue)
1249 goto out2a;
1250
1251 Busy = 0;
1252 lastspecifieddrive = -1;
1253
1254 mfm_drives = mfm_initdrives();
1255 if (!mfm_drives) {
1256 ret = -ENODEV;
1257 goto out3;
1258 }
1259
1260 for (i = 0; i < mfm_drives; i++) {
1261 struct gendisk *disk = alloc_disk(64);
1262 if (!disk)
1263 goto Enomem;
1264 disk->major = MAJOR_NR;
1265 disk->first_minor = i << 6;
1266 disk->fops = &mfm_fops;
1267 sprintf(disk->disk_name, "mfm%c", 'a'+i);
1268 mfm_gendisk[i] = disk;
1269 }
1270
1271 printk("mfm: detected %d hard drive%s\n", mfm_drives,
1272 mfm_drives == 1 ? "" : "s");
1273 ret = request_irq(mfm_irq, mfm_interrupt_handler, IRQF_DISABLED, "MFM harddisk", NULL);
1274 if (ret) {
1275 printk("mfm: unable to get IRQ%d\n", mfm_irq);
1276 goto out4;
1277 }
1278
1279 if (mfm_irqenable)
1280 outw(0x80, mfm_irqenable); /* Required to enable IRQs from MFM podule */
1281
1282 for (i = 0; i < mfm_drives; i++) {
1283 mfm_geometry(i);
1284 mfm_gendisk[i]->queue = mfm_queue;
1285 add_disk(mfm_gendisk[i]);
1286 }
1287 return 0;
1288
1289out4:
1290 for (i = 0; i < mfm_drives; i++)
1291 put_disk(mfm_gendisk[i]);
1292out3:
1293 blk_cleanup_queue(mfm_queue);
1294out2a:
1295 unregister_blkdev(MAJOR_NR, "mfm");
1296out2:
1297 release_region(mfm_addr, 10);
1298out1:
1299 return ret;
1300Enomem:
1301 while (i--)
1302 put_disk(mfm_gendisk[i]);
1303 goto out3;
1304}
1305
1306static void mfm_do_exit(void)
1307{
1308 int i;
1309
1310 free_irq(mfm_irq, NULL);
1311 for (i = 0; i < mfm_drives; i++) {
1312 del_gendisk(mfm_gendisk[i]);
1313 put_disk(mfm_gendisk[i]);
1314 }
1315 blk_cleanup_queue(mfm_queue);
1316 unregister_blkdev(MAJOR_NR, "mfm");
1317 if (mfm_addr)
1318 release_region(mfm_addr, 10);
1319}
1320
1321static int __devinit mfm_probe(struct expansion_card *ec, struct ecard_id *id)
1322{
1323 if (mfm_addr)
1324 return -EBUSY;
1325
1326 mfm_addr = ecard_address(ec, ECARD_IOC, ECARD_MEDIUM) + 0x800;
1327 mfm_IRQPollLoc = ioaddr(mfm_addr + 0x400);
1328 mfm_irqenable = mfm_IRQPollLoc;
1329 mfm_irq = ec->irq;
1330
1331 return mfm_do_init(0x08);
1332}
1333
1334static void __devexit mfm_remove(struct expansion_card *ec)
1335{
1336 outw (0, mfm_irqenable); /* Required to enable IRQs from MFM podule */
1337 mfm_do_exit();
1338}
1339
1340static const struct ecard_id mfm_cids[] = {
1341 { MANU_ACORN, PROD_ACORN_MFM },
1342 { 0xffff, 0xffff },
1343};
1344
1345static struct ecard_driver mfm_driver = {
1346 .probe = mfm_probe,
1347 .remove = __devexit(mfm_remove),
1348 .id_table = mfm_cids,
1349 .drv = {
1350 .name = "mfm",
1351 },
1352};
1353
1354/*
1355 * Look for a MFM controller - first check the motherboard, then the podules
1356 * The podules have an extra interrupt enable that needs to be played with
1357 *
1358 * The HDC is accessed at MEDIUM IOC speeds.
1359 */
1360static int __init mfm_init (void)
1361{
1362 unsigned char irqmask;
1363
1364 if (mfm_probecontroller(ONBOARD_MFM_ADDRESS)) {
1365 mfm_addr = ONBOARD_MFM_ADDRESS;
1366 mfm_IRQPollLoc = IOC_IRQSTATB;
1367 mfm_irqenable = 0;
1368 mfm_irq = IRQ_HARDDISK;
1369 return mfm_do_init(0x08); /* IL3 pin */
1370 } else {
1371 return ecard_register_driver(&mfm_driver);
1372 }
1373}
1374
1375static void __exit mfm_exit(void)
1376{
1377 if (mfm_addr == ONBOARD_MFM_ADDRESS)
1378 mfm_do_exit();
1379 else
1380 ecard_unregister_driver(&mfm_driver);
1381}
1382
1383module_init(mfm_init)
1384module_exit(mfm_exit)
1385MODULE_LICENSE("GPL");
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b1a9b81c211f..e049f65bc3a2 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -833,7 +833,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
833 depends on BLK_DEV_IDE_AU1XXX 833 depends on BLK_DEV_IDE_AU1XXX
834 834
835config IDE_ARM 835config IDE_ARM
836 def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) 836 def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
837 837
838config BLK_DEV_IDE_ICSIDE 838config BLK_DEV_IDE_ICSIDE
839 tristate "ICS IDE interface support" 839 tristate "ICS IDE interface support"
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index a3d6744e870a..bce2bec81413 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ARM/ARM26 default IDE host driver 2 * ARM default IDE host driver
3 * 3 *
4 * Copyright (C) 2004 Bartlomiej Zolnierkiewicz 4 * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
5 * Based on code by: Russell King, Ian Molton and Alexander Schulz. 5 * Based on code by: Russell King, Ian Molton and Alexander Schulz.
@@ -14,12 +14,6 @@
14#include <asm/mach-types.h> 14#include <asm/mach-types.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16 16
17#ifdef CONFIG_ARM26
18# define IDE_ARM_HOST (machine_is_a5k())
19#else
20# define IDE_ARM_HOST (1)
21#endif
22
23#ifdef CONFIG_ARCH_CLPS7500 17#ifdef CONFIG_ARCH_CLPS7500
24# include <asm/arch/hardware.h> 18# include <asm/arch/hardware.h>
25# 19#
@@ -32,12 +26,10 @@
32 26
33void __init ide_arm_init(void) 27void __init ide_arm_init(void)
34{ 28{
35 if (IDE_ARM_HOST) { 29 hw_regs_t hw;
36 hw_regs_t hw;
37 30
38 memset(&hw, 0, sizeof(hw)); 31 memset(&hw, 0, sizeof(hw));
39 ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); 32 ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
40 hw.irq = IDE_ARM_IRQ; 33 hw.irq = IDE_ARM_IRQ;
41 ide_register_hw(&hw, 1, NULL); 34 ide_register_hw(&hw, 1, NULL);
42 }
43} 35}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9d8d40d5c8f7..9ed0a98bf565 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -275,7 +275,7 @@ comment "Platform RTC drivers"
275 275
276config RTC_DRV_CMOS 276config RTC_DRV_CMOS
277 tristate "PC-style 'CMOS'" 277 tristate "PC-style 'CMOS'"
278 depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ 278 depends on RTC_CLASS && (X86 || ALPHA || ARM \
279 || M32R || ATARI || PPC || MIPS) 279 || M32R || ATARI || PPC || MIPS)
280 help 280 help
281 Say "yes" here to get direct support for the real time clock 281 Say "yes" here to get direct support for the real time clock
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index d006a8cb4a74..7236143941f3 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -74,15 +74,6 @@ config SCSI_CUMANA_1
74 This enables support for the Cumana SCSI I card. If you have an 74 This enables support for the Cumana SCSI I card. If you have an
75 Acorn system with one of these, say Y. If unsure, say N. 75 Acorn system with one of these, say Y. If unsure, say N.
76 76
77config SCSI_ECOSCSI
78 tristate "EcoScsi support (EXPERIMENTAL)"
79 depends on ARCH_ACORN && EXPERIMENTAL && (ARCH_ARC || ARCH_A5K) && SCSI
80 select SCSI_SPI_ATTRS
81 help
82 This enables support for the EcoSCSI card -- a small card that sits
83 in the Econet socket. If you have an Acorn system with one of these,
84 say Y. If unsure, say N.
85
86config SCSI_OAK1 77config SCSI_OAK1
87 tristate "Oak SCSI support (EXPERIMENTAL)" 78 tristate "Oak SCSI support (EXPERIMENTAL)"
88 depends on ARCH_ACORN && EXPERIMENTAL && SCSI 79 depends on ARCH_ACORN && EXPERIMENTAL && SCSI
diff --git a/drivers/scsi/arm/Makefile b/drivers/scsi/arm/Makefile
index e8db17924c1d..16c3e86a6b1b 100644
--- a/drivers/scsi/arm/Makefile
+++ b/drivers/scsi/arm/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_SCSI_ACORNSCSI_3) += acornscsi_mod.o queue.o msgqueue.o
8obj-$(CONFIG_SCSI_ARXESCSI) += arxescsi.o fas216.o queue.o msgqueue.o 8obj-$(CONFIG_SCSI_ARXESCSI) += arxescsi.o fas216.o queue.o msgqueue.o
9obj-$(CONFIG_SCSI_CUMANA_1) += cumana_1.o 9obj-$(CONFIG_SCSI_CUMANA_1) += cumana_1.o
10obj-$(CONFIG_SCSI_CUMANA_2) += cumana_2.o fas216.o queue.o msgqueue.o 10obj-$(CONFIG_SCSI_CUMANA_2) += cumana_2.o fas216.o queue.o msgqueue.o
11obj-$(CONFIG_SCSI_ECOSCSI) += ecoscsi.o
12obj-$(CONFIG_SCSI_OAK1) += oak.o 11obj-$(CONFIG_SCSI_OAK1) += oak.o
13obj-$(CONFIG_SCSI_POWERTECSCSI) += powertec.o fas216.o queue.o msgqueue.o 12obj-$(CONFIG_SCSI_POWERTECSCSI) += powertec.o fas216.o queue.o msgqueue.o
14obj-$(CONFIG_SCSI_EESOXSCSI) += eesox.o fas216.o queue.o msgqueue.o 13obj-$(CONFIG_SCSI_EESOXSCSI) += eesox.o fas216.o queue.o msgqueue.o
diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
deleted file mode 100644
index 5265a9884338..000000000000
--- a/drivers/scsi/arm/ecoscsi.c
+++ /dev/null
@@ -1,166 +0,0 @@
1#define AUTOSENSE
2/* #define PSEUDO_DMA */
3
4/*
5 * EcoSCSI Generic NCR5380 driver
6 *
7 * Copyright 1995, Russell King
8 *
9 * ALPHA RELEASE 1.
10 *
11 * For more information, please consult
12 *
13 * NCR 5380 Family
14 * SCSI Protocol Controller
15 * Databook
16 *
17 * NCR Microelectronics
18 * 1635 Aeroplaza Drive
19 * Colorado Springs, CO 80916
20 * 1+ (719) 578-3400
21 * 1+ (800) 334-5454
22 */
23
24#include <linux/module.h>
25#include <linux/signal.h>
26#include <linux/ioport.h>
27#include <linux/delay.h>
28#include <linux/init.h>
29#include <linux/blkdev.h>
30
31#include <asm/io.h>
32#include <asm/system.h>
33
34#include "../scsi.h"
35#include <scsi/scsi_host.h>
36
37#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
38
39#define NCR5380_local_declare() void __iomem *_base
40#define NCR5380_setup(host) _base = priv(host)->base
41
42#define NCR5380_read(reg) ({ writeb(reg | 8, _base); readb(_base + 4); })
43#define NCR5380_write(reg, value) ({ writeb(reg | 8, _base); writeb(value, _base + 4); })
44
45#define NCR5380_intr ecoscsi_intr
46#define NCR5380_queue_command ecoscsi_queue_command
47#define NCR5380_proc_info ecoscsi_proc_info
48
49#define NCR5380_implementation_fields \
50 void __iomem *base
51
52#include "../NCR5380.h"
53
54#define ECOSCSI_PUBLIC_RELEASE 1
55
56/*
57 * Function : ecoscsi_setup(char *str, int *ints)
58 *
59 * Purpose : LILO command line initialization of the overrides array,
60 *
61 * Inputs : str - unused, ints - array of integer parameters with ints[0]
62 * equal to the number of ints.
63 *
64 */
65
66void ecoscsi_setup(char *str, int *ints)
67{
68}
69
70const char * ecoscsi_info (struct Scsi_Host *spnt)
71{
72 return "";
73}
74
75#define BOARD_NORMAL 0
76#define BOARD_NCR53C400 1
77
78#include "../NCR5380.c"
79
80static struct scsi_host_template ecoscsi_template = {
81 .module = THIS_MODULE,
82 .name = "Serial Port EcoSCSI NCR5380",
83 .proc_name = "ecoscsi",
84 .info = ecoscsi_info,
85 .queuecommand = ecoscsi_queue_command,
86 .eh_abort_handler = NCR5380_abort,
87 .eh_bus_reset_handler = NCR5380_bus_reset,
88 .can_queue = 16,
89 .this_id = 7,
90 .sg_tablesize = SG_ALL,
91 .cmd_per_lun = 2,
92 .use_clustering = DISABLE_CLUSTERING
93};
94
95static struct Scsi_Host *host;
96
97static int __init ecoscsi_init(void)
98{
99 void __iomem *_base;
100 int ret;
101
102 if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) {
103 ret = -EBUSY;
104 goto out;
105 }
106
107 _base = ioremap(0x33a0000, 4096);
108 if (!_base) {
109 ret = -ENOMEM;
110 goto out_release;
111 }
112
113 NCR5380_write(MODE_REG, 0x20); /* Is it really SCSI? */
114 if (NCR5380_read(MODE_REG) != 0x20) /* Write to a reg. */
115 goto out_unmap;
116
117 NCR5380_write(MODE_REG, 0x00); /* it back. */
118 if (NCR5380_read(MODE_REG) != 0x00)
119 goto out_unmap;
120
121 host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
122 if (!host) {
123 ret = -ENOMEM;
124 goto out_unmap;
125 }
126
127 priv(host)->base = _base;
128 host->irq = IRQ_NONE;
129
130 NCR5380_init(host, 0);
131
132 printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port);
133 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
134 host->can_queue, host->cmd_per_lun, ECOSCSI_PUBLIC_RELEASE);
135 printk("\nscsi%d:", host->host_no);
136 NCR5380_print_options(host);
137 printk("\n");
138
139 scsi_add_host(host, NULL); /* XXX handle failure */
140 scsi_scan_host(host);
141 return 0;
142
143 out_unmap:
144 iounmap(_base);
145 out_release:
146 release_mem_region(0x33a0000, 4096);
147 out:
148 return ret;
149}
150
151static void __exit ecoscsi_exit(void)
152{
153 scsi_remove_host(host);
154 NCR5380_exit(host);
155 scsi_host_put(host);
156 release_mem_region(0x33a0000, 4096);
157 return 0;
158}
159
160module_init(ecoscsi_init);
161module_exit(ecoscsi_exit);
162
163MODULE_AUTHOR("Russell King");
164MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
165MODULE_LICENSE("GPL");
166
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 61a8bf159cb0..eedb8285e32f 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -138,17 +138,6 @@ static struct pixclock arc_clocks[] = {
138 { 41250, 42083, VIDC_CTRL_DIV1, VID_CTL_24MHz }, /* 24.000MHz */ 138 { 41250, 42083, VIDC_CTRL_DIV1, VID_CTL_24MHz }, /* 24.000MHz */
139}; 139};
140 140
141#ifdef CONFIG_ARCH_A5K
142static struct pixclock a5k_clocks[] = {
143 { 117974, 120357, VIDC_CTRL_DIV3, VID_CTL_25MHz }, /* 8.392MHz */
144 { 78649, 80238, VIDC_CTRL_DIV2, VID_CTL_25MHz }, /* 12.588MHz */
145 { 58987, 60178, VIDC_CTRL_DIV1_5, VID_CTL_25MHz }, /* 16.588MHz */
146 { 55000, 56111, VIDC_CTRL_DIV2, VID_CTL_36MHz }, /* 18.000MHz */
147 { 39325, 40119, VIDC_CTRL_DIV1, VID_CTL_25MHz }, /* 25.175MHz */
148 { 27500, 28055, VIDC_CTRL_DIV1, VID_CTL_36MHz }, /* 36.000MHz */
149};
150#endif
151
152static struct pixclock * 141static struct pixclock *
153acornfb_valid_pixrate(struct fb_var_screeninfo *var) 142acornfb_valid_pixrate(struct fb_var_screeninfo *var)
154{ 143{
@@ -163,15 +152,6 @@ acornfb_valid_pixrate(struct fb_var_screeninfo *var)
163 pixclock < arc_clocks[i].max_clock) 152 pixclock < arc_clocks[i].max_clock)
164 return arc_clocks + i; 153 return arc_clocks + i;
165 154
166#ifdef CONFIG_ARCH_A5K
167 if (machine_is_a5k()) {
168 for (i = 0; i < ARRAY_SIZE(a5k_clocks); i++)
169 if (pixclock > a5k_clocks[i].min_clock &&
170 pixclock < a5k_clocks[i].max_clock)
171 return a5k_clocks + i;
172 }
173#endif
174
175 return NULL; 155 return NULL;
176} 156}
177 157
diff --git a/include/asm-arm26/a.out.h b/include/asm-arm26/a.out.h
deleted file mode 100644
index 7167f54ae3fc..000000000000
--- a/include/asm-arm26/a.out.h
+++ /dev/null
@@ -1,39 +0,0 @@
1#ifndef __ARM_A_OUT_H__
2#define __ARM_A_OUT_H__
3
4#include <linux/personality.h>
5#include <asm/types.h>
6
7struct exec
8{
9 __u32 a_info; /* Use macros N_MAGIC, etc for access */
10 __u32 a_text; /* length of text, in bytes */
11 __u32 a_data; /* length of data, in bytes */
12 __u32 a_bss; /* length of uninitialized data area for file, in bytes */
13 __u32 a_syms; /* length of symbol table data in file, in bytes */
14 __u32 a_entry; /* start address */
15 __u32 a_trsize; /* length of relocation info for text, in bytes */
16 __u32 a_drsize; /* length of relocation info for data, in bytes */
17};
18
19/*
20 * This is always the same
21 */
22#define N_TXTADDR(a) (0x00008000)
23
24#define N_TRSIZE(a) ((a).a_trsize)
25#define N_DRSIZE(a) ((a).a_drsize)
26#define N_SYMSIZE(a) ((a).a_syms)
27
28#define M_ARM 103
29
30#ifdef __KERNEL__
31#define STACK_TOP TASK_SIZE
32#define STACK_TOP_MAX STACK_TOP
33#endif
34
35#ifndef LIBRARY_START_TEXT
36#define LIBRARY_START_TEXT (0x00c00000)
37#endif
38
39#endif /* __A_OUT_GNU_H__ */
diff --git a/include/asm-arm26/assembler.h b/include/asm-arm26/assembler.h
deleted file mode 100644
index bb507a9a4a55..000000000000
--- a/include/asm-arm26/assembler.h
+++ /dev/null
@@ -1,106 +0,0 @@
1/*
2 * linux/include/asm-arm26/assembler.h
3 *
4 * This file contains arm architecture specific defines
5 * for the different processors.
6 *
7 * Do not include any C declarations in this file - it is included by
8 * assembler source.
9 */
10#ifndef __ASSEMBLY__
11#error "Only include this from assembly code"
12#endif
13
14/*
15 * Endian independent macros for shifting bytes within registers.
16 */
17#define pull lsr
18#define push lsl
19#define byte(x) (x*8)
20
21#ifdef __STDC__
22#define LOADREGS(cond, base, reglist...)\
23 ldm##cond base,reglist^
24
25#define RETINSTR(instr, regs...)\
26 instr##s regs
27#else
28#define LOADREGS(cond, base, reglist...)\
29 ldm/**/cond base,reglist^
30
31#define RETINSTR(instr, regs...)\
32 instr/**/s regs
33#endif
34
35#define MODENOP\
36 mov r0, r0
37
38#define MODE(savereg,tmpreg,mode) \
39 mov savereg, pc; \
40 bic tmpreg, savereg, $0x0c000003; \
41 orr tmpreg, tmpreg, $mode; \
42 teqp tmpreg, $0
43
44#define RESTOREMODE(savereg) \
45 teqp savereg, $0
46
47#define SAVEIRQS(tmpreg)
48
49#define RESTOREIRQS(tmpreg)
50
51#define DISABLEIRQS(tmpreg)\
52 teqp pc, $0x08000003
53
54#define ENABLEIRQS(tmpreg)\
55 teqp pc, $0x00000003
56
57#define USERMODE(tmpreg)\
58 teqp pc, $0x00000000;\
59 mov r0, r0
60
61#define SVCMODE(tmpreg)\
62 teqp pc, $0x00000003;\
63 mov r0, r0
64
65
66/*
67 * Save the current IRQ state and disable IRQs
68 * Note that this macro assumes FIQs are enabled, and
69 * that the processor is in SVC mode.
70 */
71 .macro save_and_disable_irqs, oldcpsr, temp
72 mov \oldcpsr, pc
73 orr \temp, \oldcpsr, #0x08000000
74 teqp \temp, #0
75 .endm
76
77/*
78 * Restore interrupt state previously stored in
79 * a register
80 * ** Actually do nothing on Arc - hope that the caller uses a MOVS PC soon
81 * after!
82 */
83 .macro restore_irqs, oldcpsr
84 @ This be restore_irqs
85 .endm
86
87/*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we save lr (R14)
90 */
91 .macro save_lr
92 str lr, [sp, #-4]!
93 .endm
94
95 .macro restore_pc
96 ldmfd sp!, {pc}^
97 .endm
98
99#define USER(x...) \
1009999: x; \
101 .section __ex_table,"a"; \
102 .align 3; \
103 .long 9999b,9001f; \
104 .previous
105
106
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
deleted file mode 100644
index d6dd42374cf3..000000000000
--- a/include/asm-arm26/atomic.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * linux/include/asm-arm26/atomic.h
3 *
4 * Copyright (c) 1996 Russell King.
5 * Modified for arm26 by Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Changelog:
12 * 25-11-2004 IM Updated for 2.6.9
13 * 27-06-1996 RMK Created
14 * 13-04-1997 RMK Made functions atomic!
15 * 07-12-1997 RMK Upgraded for v2.1.
16 * 26-08-1998 PJB Added #ifdef __KERNEL__
17 *
18 * FIXME - its probably worth seeing what these compile into...
19 */
20#ifndef __ASM_ARM_ATOMIC_H
21#define __ASM_ARM_ATOMIC_H
22
23#ifdef CONFIG_SMP
24#error SMP is NOT supported
25#endif
26
27typedef struct { volatile int counter; } atomic_t;
28
29#define ATOMIC_INIT(i) { (i) }
30
31#ifdef __KERNEL__
32#include <asm/system.h>
33
34#define atomic_read(v) ((v)->counter)
35#define atomic_set(v,i) (((v)->counter) = (i))
36
37static inline int atomic_add_return(int i, atomic_t *v)
38{
39 unsigned long flags;
40 int val;
41
42 local_irq_save(flags);
43 val = v->counter;
44 v->counter = val += i;
45 local_irq_restore(flags);
46
47 return val;
48}
49
50static inline int atomic_sub_return(int i, atomic_t *v)
51{
52 unsigned long flags;
53 int val;
54
55 local_irq_save(flags);
56 val = v->counter;
57 v->counter = val -= i;
58 local_irq_restore(flags);
59
60 return val;
61}
62
63static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
64{
65 int ret;
66 unsigned long flags;
67
68 local_irq_save(flags);
69 ret = v->counter;
70 if (likely(ret == old))
71 v->counter = new;
72 local_irq_restore(flags);
73
74 return ret;
75}
76
77#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
78
79static inline int atomic_add_unless(atomic_t *v, int a, int u)
80{
81 int ret;
82 unsigned long flags;
83
84 local_irq_save(flags);
85 ret = v->counter;
86 if (ret != u)
87 v->counter += a;
88 local_irq_restore(flags);
89
90 return ret != u;
91}
92#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
93
94static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
95{
96 unsigned long flags;
97
98 local_irq_save(flags);
99 *addr &= ~mask;
100 local_irq_restore(flags);
101}
102
103#define atomic_add(i, v) (void) atomic_add_return(i, v)
104#define atomic_inc(v) (void) atomic_add_return(1, v)
105#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
106#define atomic_dec(v) (void) atomic_sub_return(1, v)
107
108#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
109#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
110#define atomic_inc_return(v) (atomic_add_return(1, v))
111#define atomic_dec_return(v) (atomic_sub_return(1, v))
112
113#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
114
115/* Atomic operations are already serializing on ARM26 */
116#define smp_mb__before_atomic_dec() barrier()
117#define smp_mb__after_atomic_dec() barrier()
118#define smp_mb__before_atomic_inc() barrier()
119#define smp_mb__after_atomic_inc() barrier()
120
121#include <asm-generic/atomic.h>
122#endif
123#endif
diff --git a/include/asm-arm26/auxvec.h b/include/asm-arm26/auxvec.h
deleted file mode 100644
index c0536f6b29a7..000000000000
--- a/include/asm-arm26/auxvec.h
+++ /dev/null
@@ -1,4 +0,0 @@
1#ifndef __ASMARM_AUXVEC_H
2#define __ASMARM_AUXVEC_H
3
4#endif
diff --git a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h
deleted file mode 100644
index 19a69573a654..000000000000
--- a/include/asm-arm26/bitops.h
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * Copyright 1995, Russell King.
3 *
4 * Based on the arm32 version by RMK (and others). Their copyrights apply to
5 * Those parts.
6 * Modified for arm26 by Ian Molton on 25/11/04
7 *
8 * bit 0 is the LSB of an "unsigned long" quantity.
9 *
10 * Please note that the code in this file should never be included
11 * from user space. Many of these are not implemented in assembler
12 * since they would be too costly. Also, they require privileged
13 * instructions (which are not available from user mode) to ensure
14 * that they are atomic.
15 */
16
17#ifndef __ASM_ARM_BITOPS_H
18#define __ASM_ARM_BITOPS_H
19
20#ifdef __KERNEL__
21
22#include <linux/compiler.h>
23#include <asm/system.h>
24
25#define smp_mb__before_clear_bit() do { } while (0)
26#define smp_mb__after_clear_bit() do { } while (0)
27
28/*
29 * These functions are the basis of our bit ops.
30 *
31 * First, the atomic bitops. These use native endian.
32 */
33static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
34{
35 unsigned long flags;
36 unsigned long mask = 1UL << (bit & 31);
37
38 p += bit >> 5;
39
40 local_irq_save(flags);
41 *p |= mask;
42 local_irq_restore(flags);
43}
44
45static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
46{
47 unsigned long flags;
48 unsigned long mask = 1UL << (bit & 31);
49
50 p += bit >> 5;
51
52 local_irq_save(flags);
53 *p &= ~mask;
54 local_irq_restore(flags);
55}
56
57static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
58{
59 unsigned long flags;
60 unsigned long mask = 1UL << (bit & 31);
61
62 p += bit >> 5;
63
64 local_irq_save(flags);
65 *p ^= mask;
66 local_irq_restore(flags);
67}
68
69static inline int
70____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
71{
72 unsigned long flags;
73 unsigned int res;
74 unsigned long mask = 1UL << (bit & 31);
75
76 p += bit >> 5;
77
78 local_irq_save(flags);
79 res = *p;
80 *p = res | mask;
81 local_irq_restore(flags);
82
83 return res & mask;
84}
85
86static inline int
87____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
88{
89 unsigned long flags;
90 unsigned int res;
91 unsigned long mask = 1UL << (bit & 31);
92
93 p += bit >> 5;
94
95 local_irq_save(flags);
96 res = *p;
97 *p = res & ~mask;
98 local_irq_restore(flags);
99
100 return res & mask;
101}
102
103static inline int
104____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
105{
106 unsigned long flags;
107 unsigned int res;
108 unsigned long mask = 1UL << (bit & 31);
109
110 p += bit >> 5;
111
112 local_irq_save(flags);
113 res = *p;
114 *p = res ^ mask;
115 local_irq_restore(flags);
116
117 return res & mask;
118}
119
120#include <asm-generic/bitops/non-atomic.h>
121
122/*
123 * Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
124 */
125extern void _set_bit_le(int nr, volatile unsigned long * p);
126extern void _clear_bit_le(int nr, volatile unsigned long * p);
127extern void _change_bit_le(int nr, volatile unsigned long * p);
128extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
129extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
130extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
131extern int _find_first_zero_bit_le(const unsigned long * p, unsigned size);
132extern int _find_next_zero_bit_le(void * p, int size, int offset);
133extern int _find_first_bit_le(const unsigned long *p, unsigned size);
134extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
135
136/*
137 * The __* form of bitops are non-atomic and may be reordered.
138 */
139#define ATOMIC_BITOP_LE(name,nr,p) \
140 (__builtin_constant_p(nr) ? \
141 ____atomic_##name(nr, p) : \
142 _##name##_le(nr,p))
143
144#define NONATOMIC_BITOP(name,nr,p) \
145 (____nonatomic_##name(nr, p))
146
147/*
148 * These are the little endian, atomic definitions.
149 */
150#define set_bit(nr,p) ATOMIC_BITOP_LE(set_bit,nr,p)
151#define clear_bit(nr,p) ATOMIC_BITOP_LE(clear_bit,nr,p)
152#define change_bit(nr,p) ATOMIC_BITOP_LE(change_bit,nr,p)
153#define test_and_set_bit(nr,p) ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
154#define test_and_clear_bit(nr,p) ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
155#define test_and_change_bit(nr,p) ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
156#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
157#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
158#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
159#define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off)
160
161#define WORD_BITOFF_TO_LE(x) ((x))
162
163#include <asm-generic/bitops/ffz.h>
164#include <asm-generic/bitops/__ffs.h>
165#include <asm-generic/bitops/fls.h>
166#include <asm-generic/bitops/fls64.h>
167#include <asm-generic/bitops/ffs.h>
168#include <asm-generic/bitops/sched.h>
169#include <asm-generic/bitops/hweight.h>
170
171/*
172 * Ext2 is defined to use little-endian byte ordering.
173 * These do not need to be atomic.
174 */
175#define ext2_set_bit(nr,p) \
176 __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
177#define ext2_set_bit_atomic(lock,nr,p) \
178 test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
179#define ext2_clear_bit(nr,p) \
180 __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
181#define ext2_clear_bit_atomic(lock,nr,p) \
182 test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
183#define ext2_test_bit(nr,p) \
184 test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
185#define ext2_find_first_zero_bit(p,sz) \
186 _find_first_zero_bit_le(p,sz)
187#define ext2_find_next_zero_bit(p,sz,off) \
188 _find_next_zero_bit_le(p,sz,off)
189
190/*
191 * Minix is defined to use little-endian byte ordering.
192 * These do not need to be atomic.
193 */
194#define minix_set_bit(nr,p) \
195 __set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
196#define minix_test_bit(nr,p) \
197 test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
198#define minix_test_and_set_bit(nr,p) \
199 __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
200#define minix_test_and_clear_bit(nr,p) \
201 __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
202#define minix_find_first_zero_bit(p,sz) \
203 _find_first_zero_bit_le((unsigned long *)(p),sz)
204
205#endif /* __KERNEL__ */
206
207#endif /* _ARM_BITOPS_H */
diff --git a/include/asm-arm26/bug.h b/include/asm-arm26/bug.h
deleted file mode 100644
index 8545d58b0475..000000000000
--- a/include/asm-arm26/bug.h
+++ /dev/null
@@ -1,19 +0,0 @@
1#ifndef _ASMARM_BUG_H
2#define _ASMARM_BUG_H
3
4
5#ifdef CONFIG_BUG
6#ifdef CONFIG_DEBUG_BUGVERBOSE
7extern volatile void __bug(const char *file, int line, void *data);
8/* give file/line information */
9#define BUG() __bug(__FILE__, __LINE__, NULL)
10#else
11#define BUG() (*(int *)0 = 0)
12#endif
13
14#define HAVE_ARCH_BUG
15#endif
16
17#include <asm-generic/bug.h>
18
19#endif
diff --git a/include/asm-arm26/bugs.h b/include/asm-arm26/bugs.h
deleted file mode 100644
index e99ac2e46d7f..000000000000
--- a/include/asm-arm26/bugs.h
+++ /dev/null
@@ -1,15 +0,0 @@
1/*
2 * linux/include/asm-arm26/bugs.h
3 *
4 * Copyright (C) 1995 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASM_BUGS_H
11#define __ASM_BUGS_H
12
13#define check_bugs() cpu_check_bugs()
14
15#endif
diff --git a/include/asm-arm26/byteorder.h b/include/asm-arm26/byteorder.h
deleted file mode 100644
index 0b4af9ac76e9..000000000000
--- a/include/asm-arm26/byteorder.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * linux/include/asm-arm/byteorder.h
3 *
4 * ARM Endian-ness. In little endian mode, the data bus is connected such
5 * that byte accesses appear as:
6 * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
7 * and word accesses (data or instruction) appear as:
8 * d0...d31
9 *
10 */
11#ifndef __ASM_ARM_BYTEORDER_H
12#define __ASM_ARM_BYTEORDER_H
13
14#include <asm/types.h>
15
16#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
17# define __BYTEORDER_HAS_U64__
18# define __SWAB_64_THRU_32__
19#endif
20
21#include <linux/byteorder/little_endian.h>
22
23#endif
24
diff --git a/include/asm-arm26/cache.h b/include/asm-arm26/cache.h
deleted file mode 100644
index 8c3abcf728fe..000000000000
--- a/include/asm-arm26/cache.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * linux/include/asm-arm26/cache.h
3 */
4#ifndef __ASMARM_CACHE_H
5#define __ASMARM_CACHE_H
6
7#define L1_CACHE_SHIFT 5
8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
9#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
10#define SMP_CACHE_BYTES L1_CACHE_BYTES
11
12#endif
diff --git a/include/asm-arm26/cacheflush.h b/include/asm-arm26/cacheflush.h
deleted file mode 100644
index 14ae15b6faab..000000000000
--- a/include/asm-arm26/cacheflush.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * linux/include/asm-arm/cacheflush.h
3 *
4 * Copyright (C) 2000-2002 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ARM26 cache 'functions'
12 *
13 */
14
15#ifndef _ASMARM_CACHEFLUSH_H
16#define _ASMARM_CACHEFLUSH_H
17
18#if 1 //FIXME - BAD INCLUDES!!!
19#include <linux/sched.h>
20#include <linux/mm.h>
21#endif
22
23#define flush_cache_all() do { } while (0)
24#define flush_cache_mm(mm) do { } while (0)
25#define flush_cache_dup_mm(mm) do { } while (0)
26#define flush_cache_range(vma,start,end) do { } while (0)
27#define flush_cache_page(vma,vmaddr,pfn) do { } while (0)
28#define flush_cache_vmap(start, end) do { } while (0)
29#define flush_cache_vunmap(start, end) do { } while (0)
30
31#define invalidate_dcache_range(start,end) do { } while (0)
32#define clean_dcache_range(start,end) do { } while (0)
33#define flush_dcache_range(start,end) do { } while (0)
34#define flush_dcache_page(page) do { } while (0)
35#define flush_dcache_mmap_lock(mapping) do { } while (0)
36#define flush_dcache_mmap_unlock(mapping) do { } while (0)
37#define clean_dcache_entry(_s) do { } while (0)
38#define clean_cache_entry(_start) do { } while (0)
39
40#define flush_icache_user_range(start,end, bob, fred) do { } while (0)
41#define flush_icache_range(start,end) do { } while (0)
42#define flush_icache_page(vma,page) do { } while (0)
43
44#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
45 memcpy(dst, src, len)
46#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
47 memcpy(dst, src, len)
48
49/* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
50/* IM : Yes, it will, but only if setup to do so (we do this). */
51#define clean_cache_area(_start,_size) do { } while (0)
52
53#endif
diff --git a/include/asm-arm26/checksum.h b/include/asm-arm26/checksum.h
deleted file mode 100644
index f2b4b0a403bd..000000000000
--- a/include/asm-arm26/checksum.h
+++ /dev/null
@@ -1,151 +0,0 @@
1/*
2 * linux/include/asm-arm/checksum.h
3 *
4 * IP checksum routines
5 *
6 * Copyright (C) Original authors of ../asm-i386/checksum.h
7 * Copyright (C) 1996-1999 Russell King
8 */
9#ifndef __ASM_ARM_CHECKSUM_H
10#define __ASM_ARM_CHECKSUM_H
11
12#include <linux/in6.h>
13
14/*
15 * computes the checksum of a memory block at buff, length len,
16 * and adds in "sum" (32-bit)
17 *
18 * returns a 32-bit number suitable for feeding into itself
19 * or csum_tcpudp_magic
20 *
21 * this function must be called with even lengths, except
22 * for the last fragment, which may be odd
23 *
24 * it's best to have buff aligned on a 32-bit boundary
25 */
26__wsum csum_partial(const void *buff, int len, __wsum sum);
27
28/*
29 * the same as csum_partial, but copies from src while it
30 * checksums, and handles user-space pointer exceptions correctly, when needed.
31 *
32 * here even more important to align src and dst on a 32-bit (or even
33 * better 64-bit) boundary
34 */
35
36__wsum
37csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
38
39__wsum
40csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
41
42/*
43 * This is a version of ip_compute_csum() optimized for IP headers,
44 * which always checksum on 4 octet boundaries.
45 */
46static inline __sum16
47ip_fast_csum(const void *iph, unsigned int ihl)
48{
49 unsigned int sum, tmp1;
50
51 __asm__ __volatile__(
52 "ldr %0, [%1], #4 @ ip_fast_csum \n\
53 ldr %3, [%1], #4 \n\
54 sub %2, %2, #5 \n\
55 adds %0, %0, %3 \n\
56 ldr %3, [%1], #4 \n\
57 adcs %0, %0, %3 \n\
58 ldr %3, [%1], #4 \n\
591: adcs %0, %0, %3 \n\
60 ldr %3, [%1], #4 \n\
61 tst %2, #15 @ do this carefully \n\
62 subne %2, %2, #1 @ without destroying \n\
63 bne 1b @ the carry flag \n\
64 adcs %0, %0, %3 \n\
65 adc %0, %0, #0 \n\
66 adds %0, %0, %0, lsl #16 \n\
67 addcs %0, %0, #0x10000 \n\
68 mvn %0, %0 \n\
69 mov %0, %0, lsr #16"
70 : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
71 : "1" (iph), "2" (ihl)
72 : "cc");
73 return (__force __sum16)sum;
74}
75
76/*
77 * Fold a partial checksum without adding pseudo headers
78 */
79static inline __sum16 csum_fold(__wsum sum)
80{
81 __asm__(
82 "adds %0, %1, %1, lsl #16 @ csum_fold \n\
83 addcs %0, %0, #0x10000"
84 : "=r" (sum)
85 : "r" (sum)
86 : "cc");
87 return (__force __sum16)(~(__force u32)sum >> 16);
88}
89
90static inline __wsum
91csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
92 unsigned short proto, __wsum sum)
93{
94 __asm__(
95 "adds %0, %1, %2 @ csum_tcpudp_nofold \n\
96 adcs %0, %0, %3 \n\
97 adcs %0, %0, %4 \n\
98 adcs %0, %0, %5 \n\
99 adc %0, %0, #0"
100 : "=&r"(sum)
101 : "r" (sum), "r" (daddr), "r" (saddr), "r" (htons(len)), "Ir" (htons(proto))
102 : "cc");
103 return sum;
104}
105/*
106 * computes the checksum of the TCP/UDP pseudo-header
107 * returns a 16-bit checksum, already complemented
108 */
109static inline __sum16
110csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
111 unsigned short proto, __wsum sum)
112{
113 __asm__(
114 "adds %0, %1, %2 @ csum_tcpudp_magic \n\
115 adcs %0, %0, %3 \n\
116 adcs %0, %0, %4 \n\
117 adcs %0, %0, %5 \n\
118 adc %0, %0, #0 \n\
119 adds %0, %0, %0, lsl #16 \n\
120 addcs %0, %0, #0x10000 \n\
121 mvn %0, %0"
122 : "=&r"(sum)
123 : "r" (sum), "r" (daddr), "r" (saddr), "r" (htons(len)), "Ir" (htons(proto))
124 : "cc");
125 return (__force __sum16)((__force u32)sum >> 16);
126}
127
128
129/*
130 * this routine is used for miscellaneous IP-like checksums, mainly
131 * in icmp.c
132 */
133static inline __sum16
134ip_compute_csum(const void *buff, int len)
135{
136 return csum_fold(csum_partial(buff, len, 0));
137}
138
139#define _HAVE_ARCH_IPV6_CSUM
140extern __wsum
141__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len,
142 __be32 proto, __wsum sum);
143
144static inline __sum16
145csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len,
146 unsigned short proto, __wsum sum)
147{
148 return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
149 htonl(proto), sum));
150}
151#endif
diff --git a/include/asm-arm26/constants.h b/include/asm-arm26/constants.h
deleted file mode 100644
index 0d0b14415563..000000000000
--- a/include/asm-arm26/constants.h
+++ /dev/null
@@ -1,28 +0,0 @@
1#ifndef __ASM_OFFSETS_H__
2#define __ASM_OFFSETS_H__
3/*
4 * DO NOT MODIFY.
5 *
6 * This file was generated by arch/arm26/Makefile
7 *
8 */
9
10#define TSK_ACTIVE_MM 96 /* offsetof(struct task_struct, active_mm) */
11
12#define VMA_VM_MM 0 /* offsetof(struct vm_area_struct, vm_mm) */
13#define VMA_VM_FLAGS 20 /* offsetof(struct vm_area_struct, vm_flags) */
14
15#define VM_EXEC 4 /* VM_EXEC */
16
17
18#define PAGE_PRESENT 1 /* L_PTE_PRESENT */
19#define PAGE_READONLY 95 /* PAGE_READONLY */
20#define PAGE_NOT_USER 3 /* PAGE_NONE */
21#define PAGE_OLD 3 /* PAGE_NONE */
22#define PAGE_CLEAN 128 /* L_PTE_DIRTY */
23
24#define PAGE_SZ 32768 /* PAGE_SIZE */
25
26#define SYS_ERROR0 10420224 /* 0x9f0000 */
27
28#endif
diff --git a/include/asm-arm26/cputime.h b/include/asm-arm26/cputime.h
deleted file mode 100644
index d2783a9e47b3..000000000000
--- a/include/asm-arm26/cputime.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __ARM26_CPUTIME_H
2#define __ARM26_CPUTIME_H
3
4#include <asm-generic/cputime.h>
5
6#endif /* __ARM26_CPUTIME_H */
diff --git a/include/asm-arm26/current.h b/include/asm-arm26/current.h
deleted file mode 100644
index 75d21e2a3ff7..000000000000
--- a/include/asm-arm26/current.h
+++ /dev/null
@@ -1,15 +0,0 @@
1#ifndef _ASMARM_CURRENT_H
2#define _ASMARM_CURRENT_H
3
4#include <linux/thread_info.h>
5
6static inline struct task_struct *get_current(void) __attribute_const__;
7
8static inline struct task_struct *get_current(void)
9{
10 return current_thread_info()->task;
11}
12
13#define current (get_current())
14
15#endif /* _ASMARM_CURRENT_H */
diff --git a/include/asm-arm26/delay.h b/include/asm-arm26/delay.h
deleted file mode 100644
index 40fbf7bbe6c2..000000000000
--- a/include/asm-arm26/delay.h
+++ /dev/null
@@ -1,34 +0,0 @@
1#ifndef __ASM_ARM_DELAY_H
2#define __ASM_ARM_DELAY_H
3
4/*
5 * Copyright (C) 1995 Russell King
6 *
7 * Delay routines, using a pre-computed "loops_per_second" value.
8 */
9
10extern void __delay(int loops);
11
12/*
13 * division by multiplication: you don't have to worry about
14 * loss of precision.
15 *
16 * Use only for very small delays ( < 1 msec). Should probably use a
17 * lookup table, really, as the multiplications take much too long with
18 * short delays. This is a "reasonable" implementation, though (and the
19 * first constant multiplications gets optimized away if the delay is
20 * a constant)
21 *
22 * FIXME - lets improve it then...
23 */
24extern void udelay(unsigned long usecs);
25
26static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
27{
28 return a * b / c;
29}
30
31
32
33#endif /* defined(_ARM_DELAY_H) */
34
diff --git a/include/asm-arm26/device.h b/include/asm-arm26/device.h
deleted file mode 100644
index d8f9872b0e2d..000000000000
--- a/include/asm-arm26/device.h
+++ /dev/null
@@ -1,7 +0,0 @@
1/*
2 * Arch specific extensions to struct device
3 *
4 * This file is released under the GPLv2
5 */
6#include <asm-generic/device.h>
7
diff --git a/include/asm-arm26/div64.h b/include/asm-arm26/div64.h
deleted file mode 100644
index 6cd978cefb28..000000000000
--- a/include/asm-arm26/div64.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/div64.h>
diff --git a/include/asm-arm26/dma.h b/include/asm-arm26/dma.h
deleted file mode 100644
index 4326ba85eb72..000000000000
--- a/include/asm-arm26/dma.h
+++ /dev/null
@@ -1,183 +0,0 @@
1#ifndef __ASM_ARM_DMA_H
2#define __ASM_ARM_DMA_H
3
4typedef unsigned int dmach_t;
5
6#include <linux/spinlock.h>
7#include <asm/system.h>
8#include <asm/memory.h>
9#include <asm/scatterlist.h>
10
11// FIXME - do we really need this? arm26 cant do 'proper' DMA
12
13typedef struct dma_struct dma_t;
14typedef unsigned int dmamode_t;
15
16struct dma_ops {
17 int (*request)(dmach_t, dma_t *); /* optional */
18 void (*free)(dmach_t, dma_t *); /* optional */
19 void (*enable)(dmach_t, dma_t *); /* mandatory */
20 void (*disable)(dmach_t, dma_t *); /* mandatory */
21 int (*residue)(dmach_t, dma_t *); /* optional */
22 int (*setspeed)(dmach_t, dma_t *, int); /* optional */
23 char *type;
24};
25
26struct dma_struct {
27 struct scatterlist buf; /* single DMA */
28 int sgcount; /* number of DMA SG */
29 struct scatterlist *sg; /* DMA Scatter-Gather List */
30
31 unsigned int active:1; /* Transfer active */
32 unsigned int invalid:1; /* Address/Count changed */
33 unsigned int using_sg:1; /* using scatter list? */
34 dmamode_t dma_mode; /* DMA mode */
35 int speed; /* DMA speed */
36
37 unsigned int lock; /* Device is allocated */
38 const char *device_id; /* Device name */
39
40 unsigned int dma_base; /* Controller base address */
41 int dma_irq; /* Controller IRQ */
42 int state; /* Controller state */
43 struct scatterlist cur_sg; /* Current controller buffer */
44
45 struct dma_ops *d_ops;
46};
47
48/* Prototype: void arch_dma_init(dma)
49 * Purpose : Initialise architecture specific DMA
50 * Params : dma - pointer to array of DMA structures
51 */
52extern void arch_dma_init(dma_t *dma);
53
54extern void isa_init_dma(dma_t *dma);
55
56
57#define MAX_DMA_ADDRESS 0x03000000
58#define MAX_DMA_CHANNELS 3
59
60/* ARC */
61#define DMA_VIRTUAL_FLOPPY0 0
62#define DMA_VIRTUAL_FLOPPY1 1
63#define DMA_VIRTUAL_SOUND 2
64
65/* A5K */
66#define DMA_FLOPPY 0
67
68/*
69 * DMA modes
70 */
71#define DMA_MODE_MASK 3
72
73#define DMA_MODE_READ 0
74#define DMA_MODE_WRITE 1
75#define DMA_MODE_CASCADE 2
76#define DMA_AUTOINIT 4
77
78extern spinlock_t dma_spin_lock;
79
80static inline unsigned long claim_dma_lock(void)
81{
82 unsigned long flags;
83 spin_lock_irqsave(&dma_spin_lock, flags);
84 return flags;
85}
86
87static inline void release_dma_lock(unsigned long flags)
88{
89 spin_unlock_irqrestore(&dma_spin_lock, flags);
90}
91
92/* Clear the 'DMA Pointer Flip Flop'.
93 * Write 0 for LSB/MSB, 1 for MSB/LSB access.
94 */
95#define clear_dma_ff(channel)
96
97/* Set only the page register bits of the transfer address.
98 *
99 * NOTE: This is an architecture specific function, and should
100 * be hidden from the drivers
101 */
102extern void set_dma_page(dmach_t channel, char pagenr);
103
104/* Request a DMA channel
105 *
106 * Some architectures may need to do allocate an interrupt
107 */
108extern int request_dma(dmach_t channel, const char * device_id);
109
110/* Free a DMA channel
111 *
112 * Some architectures may need to do free an interrupt
113 */
114extern void free_dma(dmach_t channel);
115
116/* Enable DMA for this channel
117 *
118 * On some architectures, this may have other side effects like
119 * enabling an interrupt and setting the DMA registers.
120 */
121extern void enable_dma(dmach_t channel);
122
123/* Disable DMA for this channel
124 *
125 * On some architectures, this may have other side effects like
126 * disabling an interrupt or whatever.
127 */
128extern void disable_dma(dmach_t channel);
129
130/* Test whether the specified channel has an active DMA transfer
131 */
132extern int dma_channel_active(dmach_t channel);
133
134/* Set the DMA scatter gather list for this channel
135 *
136 * This should not be called if a DMA channel is enabled,
137 * especially since some DMA architectures don't update the
138 * DMA address immediately, but defer it to the enable_dma().
139 */
140extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
141
142/* Set the DMA address for this channel
143 *
144 * This should not be called if a DMA channel is enabled,
145 * especially since some DMA architectures don't update the
146 * DMA address immediately, but defer it to the enable_dma().
147 */
148extern void set_dma_addr(dmach_t channel, unsigned long physaddr);
149
150/* Set the DMA byte count for this channel
151 *
152 * This should not be called if a DMA channel is enabled,
153 * especially since some DMA architectures don't update the
154 * DMA count immediately, but defer it to the enable_dma().
155 */
156extern void set_dma_count(dmach_t channel, unsigned long count);
157
158/* Set the transfer direction for this channel
159 *
160 * This should not be called if a DMA channel is enabled,
161 * especially since some DMA architectures don't update the
162 * DMA transfer direction immediately, but defer it to the
163 * enable_dma().
164 */
165extern void set_dma_mode(dmach_t channel, dmamode_t mode);
166
167/* Set the transfer speed for this channel
168 */
169extern void set_dma_speed(dmach_t channel, int cycle_ns);
170
171/* Get DMA residue count. After a DMA transfer, this
172 * should return zero. Reading this while a DMA transfer is
173 * still in progress will return unpredictable results.
174 * If called before the channel has been used, it may return 1.
175 * Otherwise, it returns the number of _bytes_ left to transfer.
176 */
177extern int get_dma_residue(dmach_t channel);
178
179#ifndef NO_DMA
180#define NO_DMA 255
181#endif
182
183#endif /* _ARM_DMA_H */
diff --git a/include/asm-arm26/ecard.h b/include/asm-arm26/ecard.h
deleted file mode 100644
index 66691939c3c1..000000000000
--- a/include/asm-arm26/ecard.h
+++ /dev/null
@@ -1,294 +0,0 @@
1/*
2 * linux/include/asm-arm26/ecard.h
3 *
4 * definitions for expansion cards
5 *
6 * This is a new system as from Linux 1.2.3
7 *
8 * Changelog:
9 * 11-12-1996 RMK Further minor improvements
10 * 12-09-1997 RMK Added interrupt enable/disable for card level
11 * 18-05-2003 IM Adjusted for ARM26
12 *
13 * Reference: Acorns Risc OS 3 Programmers Reference Manuals.
14 */
15
16#ifndef __ASM_ECARD_H
17#define __ASM_ECARD_H
18
19/*
20 * Currently understood cards (but not necessarily
21 * supported):
22 * Manufacturer Product ID
23 */
24#define MANU_ACORN 0x0000
25#define PROD_ACORN_SCSI 0x0002
26#define PROD_ACORN_ETHER1 0x0003
27#define PROD_ACORN_MFM 0x000b
28
29#define MANU_CCONCEPTS 0x0009
30#define PROD_CCONCEPTS_COLOURCARD 0x0050
31
32#define MANU_ANT2 0x0011
33#define PROD_ANT_ETHER3 0x00a4
34
35#define MANU_ATOMWIDE 0x0017
36#define PROD_ATOMWIDE_3PSERIAL 0x0090
37
38#define MANU_IRLAM_INSTRUMENTS 0x001f
39#define MANU_IRLAM_INSTRUMENTS_ETHERN 0x5678
40
41#define MANU_OAK 0x0021
42#define PROD_OAK_SCSI 0x0058
43
44#define MANU_MORLEY 0x002b
45#define PROD_MORLEY_SCSI_UNCACHED 0x0067
46
47#define MANU_CUMANA 0x003a
48#define PROD_CUMANA_SCSI_2 0x003a
49#define PROD_CUMANA_SCSI_1 0x00a0
50
51#define MANU_ICS 0x003c
52#define PROD_ICS_IDE 0x00ae
53
54#define MANU_ICS2 0x003d
55#define PROD_ICS2_IDE 0x00ae
56
57#define MANU_SERPORT 0x003f
58#define PROD_SERPORT_DSPORT 0x00b9
59
60#define MANU_ARXE 0x0041
61#define PROD_ARXE_SCSI 0x00be
62
63#define MANU_I3 0x0046
64#define PROD_I3_ETHERLAN500 0x00d4
65#define PROD_I3_ETHERLAN600 0x00ec
66#define PROD_I3_ETHERLAN600A 0x011e
67
68#define MANU_ANT 0x0053
69#define PROD_ANT_ETHERM 0x00d8
70#define PROD_ANT_ETHERB 0x00e4
71
72#define MANU_ALSYSTEMS 0x005b
73#define PROD_ALSYS_SCSIATAPI 0x0107
74
75#define MANU_MCS 0x0063
76#define PROD_MCS_CONNECT32 0x0125
77
78#define MANU_EESOX 0x0064
79#define PROD_EESOX_SCSI2 0x008c
80
81#define MANU_YELLOWSTONE 0x0096
82#define PROD_YELLOWSTONE_RAPIDE32 0x0120
83
84#define MANU_SIMTEC 0x005f
85#define PROD_SIMTEC_IDE8 0x0130
86#define PROD_SIMTEC_IDE16 0x0131
87
88
89#ifdef ECARD_C
90#define CONST
91#else
92#define CONST const
93#endif
94
95#define MAX_ECARDS 4
96
97typedef enum { /* Cards address space */
98 ECARD_IOC,
99 ECARD_MEMC,
100 ECARD_EASI
101} card_type_t;
102
103typedef enum { /* Speed for ECARD_IOC space */
104 ECARD_SLOW = 0,
105 ECARD_MEDIUM = 1,
106 ECARD_FAST = 2,
107 ECARD_SYNC = 3
108} card_speed_t;
109
110struct ecard_id { /* Card ID structure */
111 unsigned short manufacturer;
112 unsigned short product;
113 void *data;
114};
115
116struct in_ecid { /* Packed card ID information */
117 unsigned short product; /* Product code */
118 unsigned short manufacturer; /* Manufacturer code */
119 unsigned char id:4; /* Simple ID */
120 unsigned char cd:1; /* Chunk dir present */
121 unsigned char is:1; /* Interrupt status pointers */
122 unsigned char w:2; /* Width */
123 unsigned char country; /* Country */
124 unsigned char irqmask; /* IRQ mask */
125 unsigned char fiqmask; /* FIQ mask */
126 unsigned long irqoff; /* IRQ offset */
127 unsigned long fiqoff; /* FIQ offset */
128};
129
130typedef struct expansion_card ecard_t;
131typedef unsigned long *loader_t;
132
133typedef struct { /* Card handler routines */
134 void (*irqenable)(ecard_t *ec, int irqnr);
135 void (*irqdisable)(ecard_t *ec, int irqnr);
136 int (*irqpending)(ecard_t *ec);
137 void (*fiqenable)(ecard_t *ec, int fiqnr);
138 void (*fiqdisable)(ecard_t *ec, int fiqnr);
139 int (*fiqpending)(ecard_t *ec);
140} expansioncard_ops_t;
141
142#define ECARD_NUM_RESOURCES (6)
143
144#define ECARD_RES_IOCSLOW (0)
145#define ECARD_RES_IOCMEDIUM (1)
146#define ECARD_RES_IOCFAST (2)
147#define ECARD_RES_IOCSYNC (3)
148#define ECARD_RES_MEMC (4)
149#define ECARD_RES_EASI (5)
150
151#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start)
152#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end)
153#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \
154 (ec)->resource[nr].start + 1)
155
156/*
157 * This contains all the info needed on an expansion card
158 */
159struct expansion_card {
160 struct expansion_card *next;
161
162 struct device dev;
163 struct resource resource[ECARD_NUM_RESOURCES];
164
165 /* Public data */
166 volatile unsigned char *irqaddr; /* address of IRQ register */
167 volatile unsigned char *fiqaddr; /* address of FIQ register */
168 unsigned char irqmask; /* IRQ mask */
169 unsigned char fiqmask; /* FIQ mask */
170 unsigned char claimed; /* Card claimed? */
171
172 void *irq_data; /* Data for use for IRQ by card */
173 void *fiq_data; /* Data for use for FIQ by card */
174 const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
175
176 CONST unsigned int slot_no; /* Slot number */
177 CONST unsigned int dma; /* DMA number (for request_dma) */
178 CONST unsigned int irq; /* IRQ number (for request_irq) */
179 CONST unsigned int fiq; /* FIQ number (for request_irq) */
180 CONST card_type_t type; /* Type of card */
181 CONST struct in_ecid cid; /* Card Identification */
182
183 /* Private internal data */
184 const char *card_desc; /* Card description */
185 CONST unsigned int podaddr; /* Base Linux address for card */
186 CONST loader_t loader; /* loader program */
187 u64 dma_mask;
188};
189
190struct in_chunk_dir {
191 unsigned int start_offset;
192 union {
193 unsigned char string[256];
194 unsigned char data[1];
195 } d;
196};
197
198/*
199 * ecard_claim: claim an expansion card entry
200 * FIXME - are these atomic / called with interrupts off ?
201 */
202#define ecard_claim(ec) ((ec)->claimed = 1)
203
204/*
205 * ecard_release: release an expansion card entry
206 */
207#define ecard_release(ec) ((ec)->claimed = 0)
208
209/*
210 * Read a chunk from an expansion card
211 * cd : where to put read data
212 * ec : expansion card info struct
213 * id : id number to find
214 * num: (n+1)'th id to find.
215 */
216extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
217
218/*
219 * Obtain the address of a card
220 */
221extern unsigned int ecard_address (struct expansion_card *ec, card_type_t card_type, card_speed_t speed);
222
223#ifdef ECARD_C
224/* Definitions internal to ecard.c - for it's use only!!
225 *
226 * External expansion card header as read from the card
227 */
228struct ex_ecid {
229 unsigned char r_irq:1;
230 unsigned char r_zero:1;
231 unsigned char r_fiq:1;
232 unsigned char r_id:4;
233 unsigned char r_a:1;
234
235 unsigned char r_cd:1;
236 unsigned char r_is:1;
237 unsigned char r_w:2;
238 unsigned char r_r1:4;
239
240 unsigned char r_r2:8;
241
242 unsigned char r_prod[2];
243
244 unsigned char r_manu[2];
245
246 unsigned char r_country;
247
248 unsigned char r_irqmask;
249 unsigned char r_irqoff[3];
250
251 unsigned char r_fiqmask;
252 unsigned char r_fiqoff[3];
253};
254
255/*
256 * Chunk directory entry as read from the card
257 */
258struct ex_chunk_dir {
259 unsigned char r_id;
260 unsigned char r_len[3];
261 unsigned long r_start;
262 union {
263 char string[256];
264 char data[1];
265 } d;
266#define c_id(x) ((x)->r_id)
267#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
268#define c_start(x) ((x)->r_start)
269};
270
271#endif
272
273extern struct bus_type ecard_bus_type;
274
275#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
276
277struct ecard_driver {
278 int (*probe)(struct expansion_card *, const struct ecard_id *id);
279 void (*remove)(struct expansion_card *);
280 void (*shutdown)(struct expansion_card *);
281 const struct ecard_id *id_table;
282 unsigned int id;
283 struct device_driver drv;
284};
285
286#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv)
287
288#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data))
289#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev)
290
291int ecard_register_driver(struct ecard_driver *);
292void ecard_remove_driver(struct ecard_driver *);
293
294#endif
diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h
deleted file mode 100644
index 5a47fdb3015d..000000000000
--- a/include/asm-arm26/elf.h
+++ /dev/null
@@ -1,77 +0,0 @@
1#ifndef __ASMARM_ELF_H
2#define __ASMARM_ELF_H
3
4/*
5 * ELF register definitions..
6 */
7
8#include <asm/ptrace.h>
9#include <asm/procinfo.h>
10
11//FIXME - is it always 32K ?
12
13#define ELF_EXEC_PAGESIZE 32768
14#define SET_PERSONALITY(ex,ibcs2) set_personality(PER_LINUX)
15
16typedef unsigned long elf_greg_t;
17typedef unsigned long elf_freg_t[3];
18
19#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
20typedef elf_greg_t elf_gregset_t[ELF_NGREG];
21
22typedef struct { void *null; } elf_fpregset_t;
23
24/*
25 * This is used to ensure we don't load something for the wrong architecture.
26 * We can only execute 26-bit code.
27 */
28
29#define EM_ARM 40
30#define EF_ARM_APCS26 0x08
31
32//#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && ((x)->e_flags & EF_ARM_APCS26) ) FIXME!!!!! - this looks OK, but the flags seem to be wrong.
33#define elf_check_arch(x) (1)
34
35/*
36 * These are used to set parameters in the core dumps.
37 */
38#define ELF_CLASS ELFCLASS32
39#define ELF_DATA ELFDATA2LSB
40#define ELF_ARCH EM_ARM
41
42#define USE_ELF_CORE_DUMP
43
44/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
45 use of this is to invoke "./ld.so someprog" to test out a new version of
46 the loader. We need to make sure that it is out of the way of the program
47 that it will "exec", and that there is sufficient room for the brk. */
48
49#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
50
51/* When the program starts, a1 contains a pointer to a function to be
52 registered with atexit, as per the SVR4 ABI. A value of 0 means we
53 have no such handler. */
54#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
55
56/* This yields a mask that user programs can use to figure out what
57 instruction set this cpu supports. */
58
59extern unsigned int elf_hwcap;
60#define ELF_HWCAP (elf_hwcap)
61
62/* This yields a string that ld.so will use to load implementation
63 specific libraries for optimization. This is more specific in
64 intent than poking at uname or /proc/cpuinfo. */
65
66/* For now we just provide a fairly general string that describes the
67 processor family. This could be made more specific later if someone
68 implemented optimisations that require it. 26-bit CPUs give you
69 "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
70 supported).
71 */
72
73#define ELF_PLATFORM_SIZE 8
74extern char elf_platform[];
75#define ELF_PLATFORM (elf_platform)
76
77#endif
diff --git a/include/asm-arm26/emergency-restart.h b/include/asm-arm26/emergency-restart.h
deleted file mode 100644
index 108d8c48e42e..000000000000
--- a/include/asm-arm26/emergency-restart.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASM_EMERGENCY_RESTART_H
2#define _ASM_EMERGENCY_RESTART_H
3
4#include <asm-generic/emergency-restart.h>
5
6#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-arm26/errno.h b/include/asm-arm26/errno.h
deleted file mode 100644
index 6e60f0612bb6..000000000000
--- a/include/asm-arm26/errno.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ARM_ERRNO_H
2#define _ARM_ERRNO_H
3
4#include <asm-generic/errno.h>
5
6#endif
diff --git a/include/asm-arm26/fb.h b/include/asm-arm26/fb.h
deleted file mode 100644
index c7df38030992..000000000000
--- a/include/asm-arm26/fb.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef _ASM_FB_H_
2#define _ASM_FB_H_
3#include <linux/fb.h>
4
5#define fb_pgprotect(...) do {} while (0)
6
7static inline int fb_is_primary_device(struct fb_info *info)
8{
9 return 0;
10}
11
12#endif /* _ASM_FB_H_ */
diff --git a/include/asm-arm26/fcntl.h b/include/asm-arm26/fcntl.h
deleted file mode 100644
index d85995e7459e..000000000000
--- a/include/asm-arm26/fcntl.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef _ARM_FCNTL_H
2#define _ARM_FCNTL_H
3
4/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
5 located on an ext2 file system */
6#define O_DIRECTORY 040000 /* must be a directory */
7#define O_NOFOLLOW 0100000 /* don't follow links */
8#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
9#define O_LARGEFILE 0400000
10
11#include <asm-generic/fcntl.h>
12
13#endif
diff --git a/include/asm-arm26/fiq.h b/include/asm-arm26/fiq.h
deleted file mode 100644
index a3bad09e825c..000000000000
--- a/include/asm-arm26/fiq.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * linux/include/asm-arm/fiq.h
3 *
4 * Support for FIQ on ARM architectures.
5 * Written by Philip Blundell <philb@gnu.org>, 1998
6 * Re-written by Russell King
7 */
8
9#ifndef __ASM_FIQ_H
10#define __ASM_FIQ_H
11
12#include <asm/ptrace.h>
13
14struct fiq_handler {
15 struct fiq_handler *next;
16 /* Name
17 */
18 const char *name;
19 /* Called to ask driver to relinquish/
20 * reacquire FIQ
21 * return zero to accept, or -<errno>
22 */
23 int (*fiq_op)(void *, int relinquish);
24 /* data for the relinquish/reacquire functions
25 */
26 void *dev_id;
27};
28
29extern int claim_fiq(struct fiq_handler *f);
30extern void release_fiq(struct fiq_handler *f);
31extern void set_fiq_handler(void *start, unsigned int length);
32extern void set_fiq_regs(struct pt_regs *regs);
33extern void get_fiq_regs(struct pt_regs *regs);
34extern void enable_fiq(int fiq);
35extern void disable_fiq(int fiq);
36
37#endif
diff --git a/include/asm-arm26/floppy.h b/include/asm-arm26/floppy.h
deleted file mode 100644
index efb732165a4f..000000000000
--- a/include/asm-arm26/floppy.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/*
2 * linux/include/asm-arm/floppy.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
11 */
12#ifndef __ASM_ARM_FLOPPY_H
13#define __ASM_ARM_FLOPPY_H
14
15#define fd_outb(val,port) \
16 do { \
17 if ((port) == FD_DOR) \
18 fd_setdor((val)); \
19 else \
20 outb((val),(port)); \
21 } while(0)
22
23#define fd_inb(port) inb((port))
24#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
25 IRQF_DISABLED,"floppy",NULL)
26#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
27#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK)
28#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK)
29
30#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy")
31#define fd_free_dma() free_dma(DMA_FLOPPY)
32#define fd_disable_dma() disable_dma(DMA_FLOPPY)
33#define fd_enable_dma() enable_dma(DMA_FLOPPY)
34#define fd_clear_dma_ff() clear_dma_ff(DMA_FLOPPY)
35#define fd_set_dma_mode(mode) set_dma_mode(DMA_FLOPPY, (mode))
36#define fd_set_dma_addr(addr) set_dma_addr(DMA_FLOPPY, virt_to_bus((addr)))
37#define fd_set_dma_count(len) set_dma_count(DMA_FLOPPY, (len))
38#define fd_cacheflush(addr,sz)
39
40/* need to clean up dma.h */
41#define DMA_FLOPPYDISK DMA_FLOPPY
42
43/* Floppy_selects is the list of DOR's to select drive fd
44 *
45 * On initialisation, the floppy list is scanned, and the drives allocated
46 * in the order that they are found. This is done by seeking the drive
47 * to a non-zero track, and then restoring it to track 0. If an error occurs,
48 * then there is no floppy drive present. [to be put back in again]
49 */
50static unsigned char floppy_selects[2][4] =
51{
52 { 0x10, 0x21, 0x23, 0x33 },
53 { 0x10, 0x21, 0x23, 0x33 }
54};
55
56#define fd_setdor(dor) \
57do { \
58 int new_dor = (dor); \
59 if (new_dor & 0xf0) \
60 new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \
61 else \
62 new_dor &= 0x0c; \
63 outb(new_dor, FD_DOR); \
64} while (0)
65
66/*
67 * Someday, we'll automatically detect which drives are present...
68 */
69static inline void fd_scandrives (void)
70{
71#if 0
72 int floppy, drive_count;
73
74 fd_disable_irq();
75 raw_cmd = &default_raw_cmd;
76 raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK;
77 raw_cmd->track = 0;
78 raw_cmd->rate = ?;
79 drive_count = 0;
80 for (floppy = 0; floppy < 4; floppy ++) {
81 current_drive = drive_count;
82 /*
83 * Turn on floppy motor
84 */
85 if (start_motor(redo_fd_request))
86 continue;
87 /*
88 * Set up FDC
89 */
90 fdc_specify();
91 /*
92 * Tell FDC to recalibrate
93 */
94 output_byte(FD_RECALIBRATE);
95 LAST_OUT(UNIT(floppy));
96 /* wait for command to complete */
97 if (!successful) {
98 int i;
99 for (i = drive_count; i < 3; i--)
100 floppy_selects[fdc][i] = floppy_selects[fdc][i + 1];
101 floppy_selects[fdc][3] = 0;
102 floppy -= 1;
103 } else
104 drive_count++;
105 }
106#else
107 floppy_selects[0][0] = 0x10;
108 floppy_selects[0][1] = 0x21;
109 floppy_selects[0][2] = 0x23;
110 floppy_selects[0][3] = 0x33;
111#endif
112}
113
114#define FDC1 (0x3f0)
115
116#define FLOPPY0_TYPE 4
117#define FLOPPY1_TYPE 4
118
119#define N_FDC 1
120#define N_DRIVE 4
121
122#define FLOPPY_MOTOR_MASK 0xf0
123
124#define CROSS_64KB(a,s) (0)
125
126/*
127 * This allows people to reverse the order of
128 * fd0 and fd1, in case their hardware is
129 * strangely connected (as some RiscPCs
130 * and A5000s seem to be).
131 */
132static void driveswap(int *ints, int dummy, int dummy2)
133{
134 floppy_selects[0][0] ^= floppy_selects[0][1];
135 floppy_selects[0][1] ^= floppy_selects[0][0];
136 floppy_selects[0][0] ^= floppy_selects[0][1];
137}
138
139#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
140
141#endif
diff --git a/include/asm-arm26/fpstate.h b/include/asm-arm26/fpstate.h
deleted file mode 100644
index 785749b3c5ab..000000000000
--- a/include/asm-arm26/fpstate.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/include/asm-arm/fpstate.h
3 *
4 * Copyright (C) 1995 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARM_FPSTATE_H
12#define __ASM_ARM_FPSTATE_H
13
14#define FP_SIZE 35
15
16struct fp_hard_struct {
17 unsigned int save[FP_SIZE]; /* as yet undefined */
18};
19
20struct fp_soft_struct {
21 unsigned int save[FP_SIZE]; /* undefined information */
22};
23
24union fp_state {
25 struct fp_hard_struct hard;
26 struct fp_soft_struct soft;
27};
28
29#endif
diff --git a/include/asm-arm26/futex.h b/include/asm-arm26/futex.h
deleted file mode 100644
index 6a332a9f099c..000000000000
--- a/include/asm-arm26/futex.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H
3
4#include <asm-generic/futex.h>
5
6#endif
diff --git a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h
deleted file mode 100644
index e717742ffce0..000000000000
--- a/include/asm-arm26/hardirq.h
+++ /dev/null
@@ -1,32 +0,0 @@
1#ifndef __ASM_HARDIRQ_H
2#define __ASM_HARDIRQ_H
3
4#include <linux/cache.h>
5#include <linux/threads.h>
6#include <asm/irq.h>
7
8typedef struct {
9 unsigned int __softirq_pending;
10} ____cacheline_aligned irq_cpustat_t;
11
12#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
13
14#define HARDIRQ_BITS 8
15
16/*
17 * The hardirq mask has to be large enough to have space
18 * for potentially all IRQ sources in the system nesting
19 * on a single CPU:
20 */
21#if (1 << HARDIRQ_BITS) < NR_IRQS
22# error HARDIRQ_BITS is too low!
23#endif
24
25#ifndef CONFIG_SMP
26
27extern asmlinkage void __do_softirq(void);
28
29#endif
30
31
32#endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-arm26/hardware.h b/include/asm-arm26/hardware.h
deleted file mode 100644
index 801df0bde8b7..000000000000
--- a/include/asm-arm26/hardware.h
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * linux/include/asm-arm/arch-arc/hardware.h
3 *
4 * Copyright (C) 1996-1999 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains the hardware definitions of the
11 * Acorn Archimedes/A5000 machines.
12 *
13 * Modifications:
14 * 04-04-1998 PJB/RMK Merged arc and a5k versions
15 */
16#ifndef __ASM_HARDWARE_H
17#define __ASM_HARDWARE_H
18
19
20
21/*
22 * What hardware must be present - these can be tested by the kernel
23 * source.
24 */
25#define HAS_IOC
26#define HAS_MEMC
27#define HAS_VIDC
28
29#define VDMA_ALIGNMENT PAGE_SIZE
30#define VDMA_XFERSIZE 16
31#define VDMA_INIT 0
32#define VDMA_START 1
33#define VDMA_END 2
34
35#ifndef __ASSEMBLY__
36extern void memc_write(unsigned int reg, unsigned long val);
37
38#define video_set_dma(start,end,offset) \
39do { \
40 memc_write (VDMA_START, (start >> 2)); \
41 memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \
42 memc_write (VDMA_INIT, (offset >> 2)); \
43} while (0)
44#endif
45
46
47/* Hardware addresses of major areas.
48 * *_START is the physical address
49 * *_SIZE is the size of the region
50 * *_BASE is the virtual address
51 */
52#define IO_START 0x03000000
53#define IO_SIZE 0x01000000
54#define IO_BASE 0x03000000
55
56/*
57 * Screen mapping information
58 */
59#define SCREEN_START 0x02000000
60#define SCREEN_END 0x02078000
61#define SCREEN_SIZE 0x00078000
62#define SCREEN_BASE 0x02000000
63
64
65#define EXPMASK_BASE 0x03360000
66#define IOEB_BASE 0x03350000
67#define VIDC_BASE 0x03400000
68#define LATCHA_BASE 0x03250040
69#define LATCHB_BASE 0x03250018
70#define IOC_BASE 0x03200000
71#define FLOPPYDMA_BASE 0x0302a000
72#define PCIO_BASE 0x03010000
73
74// FIXME - are the below correct?
75#define PODSLOT_IOC0_BASE 0x03240000
76#define PODSLOT_IOC_SIZE (1 << 14)
77#define PODSLOT_MEMC_BASE 0x03000000
78#define PODSLOT_MEMC_SIZE (1 << 14)
79
80#define vidc_writel(val) __raw_writel(val, VIDC_BASE)
81
82#ifndef __ASSEMBLY__
83
84/*
85 * for use with inb/outb
86 */
87#define IOEB_VID_CTL (IOEB_BASE + 0x48)
88#define IOEB_PRESENT (IOEB_BASE + 0x50)
89#define IOEB_PSCLR (IOEB_BASE + 0x58)
90#define IOEB_MONTYPE (IOEB_BASE + 0x70)
91
92//FIXME - These adresses are weird - ISTR some weirdo address shifting stuff was going on here...
93#define IO_EC_IOC_BASE 0x80090000
94#define IO_EC_MEMC_BASE 0x80000000
95
96#ifdef CONFIG_ARCH_ARC
97/* A680 hardware */
98#define WD1973_BASE 0x03290000
99#define WD1973_LATCH 0x03350000
100#define Z8530_BASE 0x032b0008
101#define SCSI_BASE 0x03100000
102#endif
103
104#endif
105
106#define EXPMASK_STATUS (EXPMASK_BASE + 0x00)
107#define EXPMASK_ENABLE (EXPMASK_BASE + 0x04)
108
109#endif
diff --git a/include/asm-arm26/ide.h b/include/asm-arm26/ide.h
deleted file mode 100644
index db804d751df9..000000000000
--- a/include/asm-arm26/ide.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * linux/include/asm-arm/ide.h
3 *
4 * Copyright (C) 1994-1996 Linus Torvalds & authors
5 */
6
7/*
8 * This file contains the i386 architecture specific IDE code.
9 */
10
11#ifndef __ASMARM_IDE_H
12#define __ASMARM_IDE_H
13
14#ifdef __KERNEL__
15
16#ifndef MAX_HWIFS
17#define MAX_HWIFS 4
18#endif
19
20#include <asm/irq.h>
21#include <asm/mach-types.h>
22
23/* JMA 18.05.03 these will never be needed, but the kernel needs them to compile */
24#define __ide_mm_insw(port,addr,len) readsw(port,addr,len)
25#define __ide_mm_insl(port,addr,len) readsl(port,addr,len)
26#define __ide_mm_outsw(port,addr,len) writesw(port,addr,len)
27#define __ide_mm_outsl(port,addr,len) writesl(port,addr,len)
28
29#define IDE_ARCH_OBSOLETE_INIT
30#define ide_default_io_ctl(base) (0)
31
32#endif /* __KERNEL__ */
33
34#endif /* __ASMARM_IDE_H */
diff --git a/include/asm-arm26/io.h b/include/asm-arm26/io.h
deleted file mode 100644
index a5a7a4d5e09c..000000000000
--- a/include/asm-arm26/io.h
+++ /dev/null
@@ -1,434 +0,0 @@
1/*
2 * linux/include/asm-arm/io.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Modifications:
11 * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
12 * constant addresses and variable addresses.
13 * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
14 * specific IO header files.
15 * 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
16 * 04-Apr-1999 PJB Added check_signature.
17 * 12-Dec-1999 RMK More cleanups
18 * 18-Jun-2000 RMK Removed virt_to_* and friends definitions
19 */
20#ifndef __ASM_ARM_IO_H
21#define __ASM_ARM_IO_H
22
23#ifdef __KERNEL__
24
25#include <linux/types.h>
26#include <asm/byteorder.h>
27#include <asm/memory.h>
28#include <asm/hardware.h>
29
30/*
31 * Generic IO read/write. These perform native-endian accesses. Note
32 * that some architectures will want to re-define __raw_{read,write}w.
33 */
34extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
35extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
36extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
37
38extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
39extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
40extern void __raw_readsl(unsigned int addr, void *data, int longlen);
41
42#define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
43#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v))
44#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v))
45
46#define __raw_readb(a) (*(volatile unsigned char *)(a))
47#define __raw_readw(a) (*(volatile unsigned short *)(a))
48#define __raw_readl(a) (*(volatile unsigned int *)(a))
49
50
51/*
52 * Bad read/write accesses...
53 */
54extern void __readwrite_bug(const char *fn);
55
56/*
57 * Now, pick up the machine-defined IO definitions
58 */
59
60#define IO_SPACE_LIMIT 0xffffffff
61
62/*
63 * GCC is totally crap at loading/storing data. We try to persuade it
64 * to do the right thing by using these whereever possible instead of
65 * the above.
66 */
67#define __arch_base_getb(b,o) \
68 ({ \
69 unsigned int v, r = (b); \
70 __asm__ __volatile__( \
71 "ldrb %0, [%1, %2]" \
72 : "=r" (v) \
73 : "r" (r), "Ir" (o)); \
74 v; \
75 })
76
77#define __arch_base_getl(b,o) \
78 ({ \
79 unsigned int v, r = (b); \
80 __asm__ __volatile__( \
81 "ldr %0, [%1, %2]" \
82 : "=r" (v) \
83 : "r" (r), "Ir" (o)); \
84 v; \
85 })
86
87#define __arch_base_putb(v,b,o) \
88 ({ \
89 unsigned int r = (b); \
90 __asm__ __volatile__( \
91 "strb %0, [%1, %2]" \
92 : \
93 : "r" (v), "r" (r), "Ir" (o)); \
94 })
95
96#define __arch_base_putl(v,b,o) \
97 ({ \
98 unsigned int r = (b); \
99 __asm__ __volatile__( \
100 "str %0, [%1, %2]" \
101 : \
102 : "r" (v), "r" (r), "Ir" (o)); \
103 })
104
105/*
106 * We use two different types of addressing - PC style addresses, and ARM
107 * addresses. PC style accesses the PC hardware with the normal PC IO
108 * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+
109 * and are translated to the start of IO. Note that all addresses are
110 * shifted left!
111 */
112#define __PORT_PCIO(x) (!((x) & 0x80000000))
113
114/*
115 * Dynamic IO functions - let the compiler
116 * optimize the expressions
117 */
118static inline void __outb (unsigned int value, unsigned int port)
119{
120 unsigned long temp;
121 __asm__ __volatile__(
122 "tst %2, #0x80000000\n\t"
123 "mov %0, %4\n\t"
124 "addeq %0, %0, %3\n\t"
125 "strb %1, [%0, %2, lsl #2] @ outb"
126 : "=&r" (temp)
127 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
128 : "cc");
129}
130
131static inline void __outw (unsigned int value, unsigned int port)
132{
133 unsigned long temp;
134 __asm__ __volatile__(
135 "tst %2, #0x80000000\n\t"
136 "mov %0, %4\n\t"
137 "addeq %0, %0, %3\n\t"
138 "str %1, [%0, %2, lsl #2] @ outw"
139 : "=&r" (temp)
140 : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
141 : "cc");
142}
143
144static inline void __outl (unsigned int value, unsigned int port)
145{
146 unsigned long temp;
147 __asm__ __volatile__(
148 "tst %2, #0x80000000\n\t"
149 "mov %0, %4\n\t"
150 "addeq %0, %0, %3\n\t"
151 "str %1, [%0, %2, lsl #2] @ outl"
152 : "=&r" (temp)
153 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
154 : "cc");
155}
156
157#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
158static inline unsigned sz __in##fnsuffix (unsigned int port) \
159{ \
160 unsigned long temp, value; \
161 __asm__ __volatile__( \
162 "tst %2, #0x80000000\n\t" \
163 "mov %0, %4\n\t" \
164 "addeq %0, %0, %3\n\t" \
165 "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \
166 : "=&r" (temp), "=r" (value) \
167 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
168 : "cc"); \
169 return (unsigned sz)value; \
170}
171
172static inline unsigned int __ioaddr (unsigned int port) \
173{ \
174 if (__PORT_PCIO(port)) \
175 return (unsigned int)(PCIO_BASE + (port << 2)); \
176 else \
177 return (unsigned int)(IO_BASE + (port << 2)); \
178}
179
180#define DECLARE_IO(sz,fnsuffix,instr) \
181 DECLARE_DYN_IN(sz,fnsuffix,instr)
182
183DECLARE_IO(char,b,"b")
184DECLARE_IO(short,w,"")
185DECLARE_IO(int,l,"")
186
187#undef DECLARE_IO
188#undef DECLARE_DYN_IN
189
190/*
191 * Constant address IO functions
192 *
193 * These have to be macros for the 'J' constraint to work -
194 * +/-4096 immediate operand.
195 */
196#define __outbc(value,port) \
197({ \
198 if (__PORT_PCIO((port))) \
199 __asm__ __volatile__( \
200 "strb %0, [%1, %2] @ outbc" \
201 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
202 else \
203 __asm__ __volatile__( \
204 "strb %0, [%1, %2] @ outbc" \
205 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \
206})
207
208#define __inbc(port) \
209({ \
210 unsigned char result; \
211 if (__PORT_PCIO((port))) \
212 __asm__ __volatile__( \
213 "ldrb %0, [%1, %2] @ inbc" \
214 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
215 else \
216 __asm__ __volatile__( \
217 "ldrb %0, [%1, %2] @ inbc" \
218 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
219 result; \
220})
221
222#define __outwc(value,port) \
223({ \
224 unsigned long v = value; \
225 if (__PORT_PCIO((port))) \
226 __asm__ __volatile__( \
227 "str %0, [%1, %2] @ outwc" \
228 : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
229 else \
230 __asm__ __volatile__( \
231 "str %0, [%1, %2] @ outwc" \
232 : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \
233})
234
235#define __inwc(port) \
236({ \
237 unsigned short result; \
238 if (__PORT_PCIO((port))) \
239 __asm__ __volatile__( \
240 "ldr %0, [%1, %2] @ inwc" \
241 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
242 else \
243 __asm__ __volatile__( \
244 "ldr %0, [%1, %2] @ inwc" \
245 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
246 result & 0xffff; \
247})
248
249#define __outlc(value,port) \
250({ \
251 unsigned long v = value; \
252 if (__PORT_PCIO((port))) \
253 __asm__ __volatile__( \
254 "str %0, [%1, %2] @ outlc" \
255 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
256 else \
257 __asm__ __volatile__( \
258 "str %0, [%1, %2] @ outlc" \
259 : : "r" (v), "r" (IO_BASE), "r" ((port) << 2)); \
260})
261
262#define __inlc(port) \
263({ \
264 unsigned long result; \
265 if (__PORT_PCIO((port))) \
266 __asm__ __volatile__( \
267 "ldr %0, [%1, %2] @ inlc" \
268 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
269 else \
270 __asm__ __volatile__( \
271 "ldr %0, [%1, %2] @ inlc" \
272 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
273 result; \
274})
275
276#define __ioaddrc(port) \
277({ \
278 unsigned long addr; \
279 if (__PORT_PCIO((port))) \
280 addr = PCIO_BASE + ((port) << 2); \
281 else \
282 addr = IO_BASE + ((port) << 2); \
283 addr; \
284})
285
286#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
287#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
288#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
289#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
290#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
291#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
292#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p))
293
294/* JMA 18.02.03 added sb,sl from arm/io.h, changing io to ioaddr */
295
296#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)
297#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
298#define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l)
299
300#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
301#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
302#define insl(p,d,l) __raw_readsl(__ioaddr(p),d,l)
303
304#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
305#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
306
307#define readb(c) (__readwrite_bug("readb"),0)
308#define readw(c) (__readwrite_bug("readw"),0)
309#define readl(c) (__readwrite_bug("readl"),0)
310#define readb_relaxed(addr) readb(addr)
311#define readw_relaxed(addr) readw(addr)
312#define readl_relaxed(addr) readl(addr)
313#define writeb(v,c) __readwrite_bug("writeb")
314#define writew(v,c) __readwrite_bug("writew")
315#define writel(v,c) __readwrite_bug("writel")
316
317#define readsw(p,d,l) (__readwrite_bug("readsw"),0)
318#define readsl(p,d,l) (__readwrite_bug("readsl"),0)
319#define writesw(p,d,l) __readwrite_bug("writesw")
320#define writesl(p,d,l) __readwrite_bug("writesl")
321
322#define mmiowb()
323
324/* the following macro is deprecated */
325#define ioaddr(port) __ioaddr((port))
326
327/*
328 * No ioremap support here.
329 */
330#define __arch_ioremap(c,s,f,a) ((void *)(c))
331#define __arch_iounmap(c) do { } while (0)
332
333
334#if defined(__arch_putb) || defined(__arch_putw) || defined(__arch_putl) || \
335 defined(__arch_getb) || defined(__arch_getw) || defined(__arch_getl)
336#warning machine class uses old __arch_putw or __arch_getw
337#endif
338
339/*
340 * IO port access primitives
341 * -------------------------
342 *
343 * The ARM doesn't have special IO access instructions; all IO is memory
344 * mapped. Note that these are defined to perform little endian accesses
345 * only. Their primary purpose is to access PCI and ISA peripherals.
346 *
347 * Note that for a big endian machine, this implies that the following
348 * big endian mode connectivity is in place, as described by numerious
349 * ARM documents:
350 *
351 * PCI: D0-D7 D8-D15 D16-D23 D24-D31
352 * ARM: D24-D31 D16-D23 D8-D15 D0-D7
353 *
354 * The machine specific io.h include defines __io to translate an "IO"
355 * address to a memory address.
356 *
357 * Note that we prevent GCC re-ordering or caching values in expressions
358 * by introducing sequence points into the in*() definitions. Note that
359 * __raw_* do not guarantee this behaviour.
360 */
361/*
362#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
363#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
364
365#define insb(p,d,l) __raw_readsb(__io(p),d,l)
366#define insw(p,d,l) __raw_readsw(__io(p),d,l)
367*/
368#define outb_p(val,port) outb((val),(port))
369#define outw_p(val,port) outw((val),(port))
370#define inb_p(port) inb((port))
371#define inw_p(port) inw((port))
372#define inl_p(port) inl((port))
373
374#define outsb_p(port,from,len) outsb(port,from,len)
375#define outsw_p(port,from,len) outsw(port,from,len)
376#define insb_p(port,to,len) insb(port,to,len)
377#define insw_p(port,to,len) insw(port,to,len)
378
379/*
380 * String version of IO memory access ops:
381 */
382extern void _memcpy_fromio(void *, unsigned long, size_t);
383extern void _memcpy_toio(unsigned long, const void *, size_t);
384extern void _memset_io(unsigned long, int, size_t);
385
386/*
387 * ioremap and friends.
388 *
389 * ioremap takes a PCI memory address, as specified in
390 * Documentation/IO-mapping.txt.
391 */
392extern void * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
393extern void __iounmap(void *addr);
394
395#ifndef __arch_ioremap
396#define ioremap(cookie,size) __ioremap(cookie,size,0,1)
397#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1)
398#define iounmap(cookie) __iounmap(cookie)
399#else
400#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1)
401#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1)
402#define iounmap(cookie) __arch_iounmap(cookie)
403#endif
404
405/*
406 * DMA-consistent mapping functions. These allocate/free a region of
407 * uncached, unwrite-buffered mapped memory space for use with DMA
408 * devices. This is the "generic" version. The PCI specific version
409 * is in pci.h
410 */
411extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
412extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
413extern void consistent_sync(void *vaddr, size_t size, int rw);
414
415/*
416 * can the hardware map this into one segment or not, given no other
417 * constraints.
418 */
419#define BIOVEC_MERGEABLE(vec1, vec2) \
420 ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
421
422/*
423 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
424 * access
425 */
426#define xlate_dev_mem_ptr(p) __va(p)
427
428/*
429 * Convert a virtual cached pointer to an uncached pointer
430 */
431#define xlate_dev_kmem_ptr(p) p
432
433#endif /* __KERNEL__ */
434#endif /* __ASM_ARM_IO_H */
diff --git a/include/asm-arm26/ioc.h b/include/asm-arm26/ioc.h
deleted file mode 100644
index b3b46ef65943..000000000000
--- a/include/asm-arm26/ioc.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * linux/include/asm-arm/hardware/ioc.h
3 *
4 * Copyright (C) Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Use these macros to read/write the IOC. All it does is perform the actual
11 * read/write.
12 */
13#ifndef __ASMARM_HARDWARE_IOC_H
14#define __ASMARM_HARDWARE_IOC_H
15
16#ifndef __ASSEMBLY__
17
18/*
19 * We use __raw_base variants here so that we give the compiler the
20 * chance to keep IOC_BASE in a register.
21 */
22#define ioc_readb(off) __raw_readb(IOC_BASE + (off))
23#define ioc_writeb(val,off) __raw_writeb(val, IOC_BASE + (off))
24
25#endif
26
27#define IOC_CONTROL (0x00)
28#define IOC_KARTTX (0x04)
29#define IOC_KARTRX (0x04)
30
31#define IOC_IRQSTATA (0x10)
32#define IOC_IRQREQA (0x14)
33#define IOC_IRQCLRA (0x14)
34#define IOC_IRQMASKA (0x18)
35
36#define IOC_IRQSTATB (0x20)
37#define IOC_IRQREQB (0x24)
38#define IOC_IRQMASKB (0x28)
39
40#define IOC_FIQSTAT (0x30)
41#define IOC_FIQREQ (0x34)
42#define IOC_FIQMASK (0x38)
43
44#define IOC_T0CNTL (0x40)
45#define IOC_T0LTCHL (0x40)
46#define IOC_T0CNTH (0x44)
47#define IOC_T0LTCHH (0x44)
48#define IOC_T0GO (0x48)
49#define IOC_T0LATCH (0x4c)
50
51#define IOC_T1CNTL (0x50)
52#define IOC_T1LTCHL (0x50)
53#define IOC_T1CNTH (0x54)
54#define IOC_T1LTCHH (0x54)
55#define IOC_T1GO (0x58)
56#define IOC_T1LATCH (0x5c)
57
58#define IOC_T2CNTL (0x60)
59#define IOC_T2LTCHL (0x60)
60#define IOC_T2CNTH (0x64)
61#define IOC_T2LTCHH (0x64)
62#define IOC_T2GO (0x68)
63#define IOC_T2LATCH (0x6c)
64
65#define IOC_T3CNTL (0x70)
66#define IOC_T3LTCHL (0x70)
67#define IOC_T3CNTH (0x74)
68#define IOC_T3LTCHH (0x74)
69#define IOC_T3GO (0x78)
70#define IOC_T3LATCH (0x7c)
71
72#endif
diff --git a/include/asm-arm26/ioctl.h b/include/asm-arm26/ioctl.h
deleted file mode 100644
index b279fe06dfe5..000000000000
--- a/include/asm-arm26/ioctl.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ioctl.h>
diff --git a/include/asm-arm26/ioctls.h b/include/asm-arm26/ioctls.h
deleted file mode 100644
index 8a3296200be1..000000000000
--- a/include/asm-arm26/ioctls.h
+++ /dev/null
@@ -1,85 +0,0 @@
1#ifndef __ASM_ARM_IOCTLS_H
2#define __ASM_ARM_IOCTLS_H
3
4#include <asm/ioctl.h>
5
6/* 0x54 is just a magic number to make these relatively unique ('T') */
7
8#define TCGETS 0x5401
9#define TCSETS 0x5402
10#define TCSETSW 0x5403
11#define TCSETSF 0x5404
12#define TCGETA 0x5405
13#define TCSETA 0x5406
14#define TCSETAW 0x5407
15#define TCSETAF 0x5408
16#define TCSBRK 0x5409
17#define TCXONC 0x540A
18#define TCFLSH 0x540B
19#define TIOCEXCL 0x540C
20#define TIOCNXCL 0x540D
21#define TIOCSCTTY 0x540E
22#define TIOCGPGRP 0x540F
23#define TIOCSPGRP 0x5410
24#define TIOCOUTQ 0x5411
25#define TIOCSTI 0x5412
26#define TIOCGWINSZ 0x5413
27#define TIOCSWINSZ 0x5414
28#define TIOCMGET 0x5415
29#define TIOCMBIS 0x5416
30#define TIOCMBIC 0x5417
31#define TIOCMSET 0x5418
32#define TIOCGSOFTCAR 0x5419
33#define TIOCSSOFTCAR 0x541A
34#define FIONREAD 0x541B
35#define TIOCINQ FIONREAD
36#define TIOCLINUX 0x541C
37#define TIOCCONS 0x541D
38#define TIOCGSERIAL 0x541E
39#define TIOCSSERIAL 0x541F
40#define TIOCPKT 0x5420
41#define FIONBIO 0x5421
42#define TIOCNOTTY 0x5422
43#define TIOCSETD 0x5423
44#define TIOCGETD 0x5424
45#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
46#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
47#define TIOCSBRK 0x5427 /* BSD compatibility */
48#define TIOCCBRK 0x5428 /* BSD compatibility */
49#define TIOCGSID 0x5429 /* Return the session ID of FD */
50#define TCGETS2 _IOR('T',0x2A, struct termios2)
51#define TCSETS2 _IOW('T',0x2B, struct termios2)
52#define TCSETSW2 _IOW('T',0x2C, struct termios2)
53#define TCSETSF2 _IOW('T',0x2D, struct termios2)
54#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
55#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
56
57#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
58#define FIOCLEX 0x5451
59#define FIOASYNC 0x5452
60#define TIOCSERCONFIG 0x5453
61#define TIOCSERGWILD 0x5454
62#define TIOCSERSWILD 0x5455
63#define TIOCGLCKTRMIOS 0x5456
64#define TIOCSLCKTRMIOS 0x5457
65#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
66#define TIOCSERGETLSR 0x5459 /* Get line status register */
67#define TIOCSERGETMULTI 0x545A /* Get multiport config */
68#define TIOCSERSETMULTI 0x545B /* Set multiport config */
69
70#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
71#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
72#define FIOQSIZE 0x545E
73
74/* Used for packet mode */
75#define TIOCPKT_DATA 0
76#define TIOCPKT_FLUSHREAD 1
77#define TIOCPKT_FLUSHWRITE 2
78#define TIOCPKT_STOP 4
79#define TIOCPKT_START 8
80#define TIOCPKT_NOSTOP 16
81#define TIOCPKT_DOSTOP 32
82
83#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
84
85#endif
diff --git a/include/asm-arm26/ipc.h b/include/asm-arm26/ipc.h
deleted file mode 100644
index a46e3d9c2a3f..000000000000
--- a/include/asm-arm26/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ipc.h>
diff --git a/include/asm-arm26/ipcbuf.h b/include/asm-arm26/ipcbuf.h
deleted file mode 100644
index 97683975f7df..000000000000
--- a/include/asm-arm26/ipcbuf.h
+++ /dev/null
@@ -1,29 +0,0 @@
1#ifndef __ASMARM_IPCBUF_H
2#define __ASMARM_IPCBUF_H
3
4/*
5 * The ipc64_perm structure for arm architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space is left for:
10 * - 32-bit mode_t and seq
11 * - 2 miscellaneous 32-bit values
12 */
13
14struct ipc64_perm
15{
16 __kernel_key_t key;
17 __kernel_uid32_t uid;
18 __kernel_gid32_t gid;
19 __kernel_uid32_t cuid;
20 __kernel_gid32_t cgid;
21 __kernel_mode_t mode;
22 unsigned short __pad1;
23 unsigned short seq;
24 unsigned short __pad2;
25 unsigned long __unused1;
26 unsigned long __unused2;
27};
28
29#endif /* __ASMARM_IPCBUF_H */
diff --git a/include/asm-arm26/irq.h b/include/asm-arm26/irq.h
deleted file mode 100644
index 52971b49ed3b..000000000000
--- a/include/asm-arm26/irq.h
+++ /dev/null
@@ -1,43 +0,0 @@
1#ifndef __ASM_ARM_IRQ_H
2#define __ASM_ARM_IRQ_H
3
4#include <asm/sysirq.h>
5
6#ifndef NR_IRQS
7#define NR_IRQS 128
8#endif
9
10
11/* JMA 18.05.02 Copied off arch/arm/irq.h */
12#ifndef irq_canonicalize
13#define irq_canonicalize(i) (i)
14#endif
15
16
17/*
18 * Use this value to indicate lack of interrupt
19 * capability
20 */
21#ifndef NO_IRQ
22#define NO_IRQ ((unsigned int)(-1))
23#endif
24
25struct irqaction;
26
27#define __IRQT_FALEDGE (1 << 0)
28#define __IRQT_RISEDGE (1 << 1)
29#define __IRQT_LOWLVL (1 << 2)
30#define __IRQT_HIGHLVL (1 << 3)
31
32#define IRQT_NOEDGE (0)
33#define IRQT_RISING (__IRQT_RISEDGE)
34#define IRQT_FALLING (__IRQT_FALEDGE)
35#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
36#define IRQT_LOW (__IRQT_LOWLVL)
37#define IRQT_HIGH (__IRQT_HIGHLVL)
38#define IRQT_PROBE (1 << 4)
39
40int set_irq_type(unsigned int irq, unsigned int type);
41
42#endif
43
diff --git a/include/asm-arm26/irqchip.h b/include/asm-arm26/irqchip.h
deleted file mode 100644
index 6a007a954098..000000000000
--- a/include/asm-arm26/irqchip.h
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * linux/include/asm-arm/mach/irq.h
3 *
4 * Copyright (C) 1995-2000 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASM_ARM_MACH_IRQ_H
11#define __ASM_ARM_MACH_IRQ_H
12
13struct irqdesc;
14struct pt_regs;
15struct seq_file;
16
17typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
18typedef void (*irq_control_t)(unsigned int);
19
20struct irqchip {
21 /*
22 * Acknowledge the IRQ.
23 * If this is a level-based IRQ, then it is expected to mask the IRQ
24 * as well.
25 */
26 void (*ack)(unsigned int);
27 /*
28 * Mask the IRQ in hardware.
29 */
30 void (*mask)(unsigned int);
31 /*
32 * Unmask the IRQ in hardware.
33 */
34 void (*unmask)(unsigned int);
35 /*
36 * Re-run the IRQ
37 */
38 void (*rerun)(unsigned int);
39 /*
40 * Set the type of the IRQ.
41 */
42 int (*type)(unsigned int, unsigned int);
43};
44
45struct irqdesc {
46 irq_handler_t handle;
47 struct irqchip *chip;
48 struct irqaction *action;
49
50 unsigned int enabled : 1; /* IRQ is currently enabled */
51 unsigned int triggered: 1; /* IRQ has occurred */
52 unsigned int running : 1; /* IRQ is running */
53 unsigned int pending : 1; /* IRQ is pending */
54 unsigned int probing : 1; /* IRQ in use for a probe */
55 unsigned int probe_ok : 1; /* IRQ can be used for probe */
56 unsigned int valid : 1; /* IRQ claimable */
57 unsigned int noautoenable : 1; /* don't automatically enable IRQ */
58 unsigned int unused :23;
59 unsigned int depth; /* disable depth */
60
61 /*
62 * IRQ lock detection
63 */
64 unsigned int lck_cnt;
65 unsigned int lck_pc;
66 unsigned int lck_jif;
67};
68
69extern struct irqdesc irq_desc[];
70
71/*
72 * This is internal. Do not use it.
73 */
74extern void (*init_arch_irq)(void);
75extern void init_FIQ(void);
76extern int show_fiq_list(struct seq_file *, void *);
77void __set_irq_handler(unsigned int irq, irq_handler_t, int);
78
79/*
80 * External stuff.
81 */
82#define set_irq_handler(irq,handler) __set_irq_handler(irq,handler,0)
83#define set_irq_chained_handler(irq,handler) __set_irq_handler(irq,handler,1)
84
85void set_irq_chip(unsigned int irq, struct irqchip *);
86void set_irq_flags(unsigned int irq, unsigned int flags);
87
88#define IRQF_VALID (1 << 0)
89#define IRQF_PROBE (1 << 1)
90#define IRQF_NOAUTOEN (1 << 2)
91
92/*
93 * Built-in IRQ handlers.
94 */
95void do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
96void do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
97void do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
98void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
99void dummy_mask_unmask_irq(unsigned int irq);
100
101#endif
diff --git a/include/asm-arm26/kdebug.h b/include/asm-arm26/kdebug.h
deleted file mode 100644
index 6ece1b037665..000000000000
--- a/include/asm-arm26/kdebug.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/kdebug.h>
diff --git a/include/asm-arm26/kmap_types.h b/include/asm-arm26/kmap_types.h
deleted file mode 100644
index d5da712b723c..000000000000
--- a/include/asm-arm26/kmap_types.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef __ARM_KMAP_TYPES_H
2#define __ARM_KMAP_TYPES_H
3
4/*
5 * This is the "bare minimum". AIO seems to require this.
6 */
7enum km_type {
8 KM_IRQ0,
9 KM_USER1
10};
11
12#endif
diff --git a/include/asm-arm26/leds.h b/include/asm-arm26/leds.h
deleted file mode 100644
index 12290ea55801..000000000000
--- a/include/asm-arm26/leds.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * linux/include/asm-arm/leds.h
3 *
4 * Copyright (C) 1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Event-driven interface for LEDs on machines
11 * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
12 */
13#ifndef ASM_ARM_LEDS_H
14#define ASM_ARM_LEDS_H
15
16
17typedef enum {
18 led_idle_start,
19 led_idle_end,
20 led_timer,
21 led_start,
22 led_stop,
23 led_claim, /* override idle & timer leds */
24 led_release, /* restore idle & timer leds */
25 led_start_timer_mode,
26 led_stop_timer_mode,
27 led_green_on,
28 led_green_off,
29 led_amber_on,
30 led_amber_off,
31 led_red_on,
32 led_red_off,
33 led_blue_on,
34 led_blue_off,
35 /*
36 * I want this between led_timer and led_start, but
37 * someone has decided to export this to user space
38 */
39 led_halted
40} led_event_t;
41
42/* Use this routine to handle LEDs */
43
44#ifdef CONFIG_LEDS
45extern void (*leds_event)(led_event_t);
46#else
47#define leds_event(e)
48#endif
49
50#endif
diff --git a/include/asm-arm26/limits.h b/include/asm-arm26/limits.h
deleted file mode 100644
index 08d8c6600804..000000000000
--- a/include/asm-arm26/limits.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef __ASM_PIPE_H
2#define __ASM_PIPE_H
3
4#ifndef PAGE_SIZE
5#include <asm/page.h>
6#endif
7
8#define PIPE_BUF PAGE_SIZE
9
10#endif
11
diff --git a/include/asm-arm26/linkage.h b/include/asm-arm26/linkage.h
deleted file mode 100644
index dbe4b4e31a5b..000000000000
--- a/include/asm-arm26/linkage.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __ASM_LINKAGE_H
2#define __ASM_LINKAGE_H
3
4#define __ALIGN .align 0
5#define __ALIGN_STR ".align 0"
6
7#endif
diff --git a/include/asm-arm26/local.h b/include/asm-arm26/local.h
deleted file mode 100644
index 6759e9183cef..000000000000
--- a/include/asm-arm26/local.h
+++ /dev/null
@@ -1,2 +0,0 @@
1//FIXME - nicked from arm32 - check it is correct...
2#include <asm-generic/local.h>
diff --git a/include/asm-arm26/locks.h b/include/asm-arm26/locks.h
deleted file mode 100644
index 81b3bda2ed00..000000000000
--- a/include/asm-arm26/locks.h
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * linux/include/asm-arm/proc-armo/locks.h
3 *
4 * Copyright (C) 2000 Russell King
5 * Fixes for 26 bit machines, (C) 2000 Dave Gilbert
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Interrupt safe locking assembler.
12 */
13#ifndef __ASM_PROC_LOCKS_H
14#define __ASM_PROC_LOCKS_H
15
16/* Decrements by 1, fails if value < 0 */
17#define __down_op(ptr,fail) \
18 ({ \
19 __asm__ __volatile__ ( \
20 "@ atomic down operation\n" \
21" mov ip, pc\n" \
22" orr lr, ip, #0x08000000\n" \
23" teqp lr, #0\n" \
24" ldr lr, [%0]\n" \
25" and ip, ip, #0x0c000003\n" \
26" subs lr, lr, #1\n" \
27" str lr, [%0]\n" \
28" orrmi ip, ip, #0x80000000 @ set N\n" \
29" teqp ip, #0\n" \
30" movmi ip, %0\n" \
31" blmi " #fail \
32 : \
33 : "r" (ptr) \
34 : "ip", "lr", "cc"); \
35 })
36
37#define __down_op_ret(ptr,fail) \
38 ({ \
39 unsigned int result; \
40 __asm__ __volatile__ ( \
41" @ down_op_ret\n" \
42" mov ip, pc\n" \
43" orr lr, ip, #0x08000000\n" \
44" teqp lr, #0\n" \
45" ldr lr, [%1]\n" \
46" and ip, ip, #0x0c000003\n" \
47" subs lr, lr, #1\n" \
48" str lr, [%1]\n" \
49" orrmi ip, ip, #0x80000000 @ set N\n" \
50" teqp ip, #0\n" \
51" movmi ip, %1\n" \
52" movpl ip, #0\n" \
53" blmi " #fail "\n" \
54" mov %0, ip" \
55 : "=&r" (result) \
56 : "r" (ptr) \
57 : "ip", "lr", "cc"); \
58 result; \
59 })
60
61#define __up_op(ptr,wake) \
62 ({ \
63 __asm__ __volatile__ ( \
64 "@ up_op\n" \
65" mov ip, pc\n" \
66" orr lr, ip, #0x08000000\n" \
67" teqp lr, #0\n" \
68" ldr lr, [%0]\n" \
69" and ip, ip, #0x0c000003\n" \
70" adds lr, lr, #1\n" \
71" str lr, [%0]\n" \
72" orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
73" teqp ip, #0\n" \
74" movmi ip, %0\n" \
75" blmi " #wake \
76 : \
77 : "r" (ptr) \
78 : "ip", "lr", "cc"); \
79 })
80
81/*
82 * The value 0x01000000 supports up to 128 processors and
83 * lots of processes. BIAS must be chosen such that sub'ing
84 * BIAS once per CPU will result in the long remaining
85 * negative.
86 */
87#define RW_LOCK_BIAS 0x01000000
88#define RW_LOCK_BIAS_STR "0x01000000"
89
90/* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */
91#define __down_op_write(ptr,fail) \
92 ({ \
93 __asm__ __volatile__( \
94 "@ down_op_write\n" \
95" mov ip, pc\n" \
96" orr lr, ip, #0x08000000\n" \
97" teqp lr, #0\n" \
98" and ip, ip, #0x0c000003\n" \
99\
100" ldr lr, [%0]\n" \
101" subs lr, lr, %1\n" \
102" str lr, [%0]\n" \
103\
104" orreq ip, ip, #0x40000000 @ set Z \n"\
105" teqp ip, #0\n" \
106" movne ip, %0\n" \
107" blne " #fail \
108 : \
109 : "r" (ptr), "I" (RW_LOCK_BIAS) \
110 : "ip", "lr", "cc"); \
111 })
112
113/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
114#define __up_op_write(ptr,wake) \
115 ({ \
116 __asm__ __volatile__( \
117 "@ up_op_read\n" \
118" mov ip, pc\n" \
119" orr lr, ip, #0x08000000\n" \
120" teqp lr, #0\n" \
121\
122" ldr lr, [%0]\n" \
123" and ip, ip, #0x0c000003\n" \
124" adds lr, lr, %1\n" \
125" str lr, [%0]\n" \
126\
127" orrcs ip, ip, #0x20000000 @ set C\n" \
128" teqp ip, #0\n" \
129" movcs ip, %0\n" \
130" blcs " #wake \
131 : \
132 : "r" (ptr), "I" (RW_LOCK_BIAS) \
133 : "ip", "lr", "cc"); \
134 })
135
136#define __down_op_read(ptr,fail) \
137 __down_op(ptr, fail)
138
139#define __up_op_read(ptr,wake) \
140 ({ \
141 __asm__ __volatile__( \
142 "@ up_op_read\n" \
143" mov ip, pc\n" \
144" orr lr, ip, #0x08000000\n" \
145" teqp lr, #0\n" \
146\
147" ldr lr, [%0]\n" \
148" and ip, ip, #0x0c000003\n" \
149" adds lr, lr, %1\n" \
150" str lr, [%0]\n" \
151\
152" orreq ip, ip, #0x40000000 @ Set Z \n" \
153" teqp ip, #0\n" \
154" moveq ip, %0\n" \
155" bleq " #wake \
156 : \
157 : "r" (ptr), "I" (1) \
158 : "ip", "lr", "cc"); \
159 })
160
161#endif
diff --git a/include/asm-arm26/mach-types.h b/include/asm-arm26/mach-types.h
deleted file mode 100644
index 0aeaedcbac96..000000000000
--- a/include/asm-arm26/mach-types.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Unlike ARM32 this is NOT automatically generated. DONT delete it
3 * Instead, consider FIXME-ing it so its auto-detected.
4 */
5
6#ifndef __ASM_ARM_MACH_TYPE_H
7#define __ASM_ARM_MACH_TYPE_H
8
9
10#ifndef __ASSEMBLY__
11extern unsigned int __machine_arch_type;
12#endif
13
14#define MACH_TYPE_ARCHIMEDES 10
15#define MACH_TYPE_A5K 11
16
17#ifdef CONFIG_ARCH_ARC
18# define machine_arch_type MACH_TYPE_ARCHIMEDES
19# define machine_is_archimedes() (machine_arch_type == MACH_TYPE_ARCHIMEDES)
20#else
21# define machine_is_archimedes() (0)
22#endif
23
24#ifdef CONFIG_ARCH_A5K
25# define machine_arch_type MACH_TYPE_A5K
26# define machine_is_a5k() (machine_arch_type == MACH_TYPE_A5K)
27#else
28# define machine_is_a5k() (0)
29#endif
30
31#ifndef machine_arch_type
32#error Unknown machine type
33#define machine_arch_type __machine_arch_type
34#endif
35
36#endif
diff --git a/include/asm-arm26/map.h b/include/asm-arm26/map.h
deleted file mode 100644
index 6e12a7fa5c5d..000000000000
--- a/include/asm-arm26/map.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * linux/include/asm-arm/map.h
3 *
4 * Copyright (C) 1999-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Page table mapping constructs and function prototypes
11 */
12struct map_desc {
13 unsigned long virtual;
14 unsigned long physical;
15 unsigned long length;
16 unsigned int type;
17};
18
19struct meminfo;
20
21extern void create_memmap_holes(struct meminfo *);
22extern void memtable_init(struct meminfo *);
23extern void iotable_init(struct map_desc *);
24extern void setup_io_desc(void);
diff --git a/include/asm-arm26/mc146818rtc.h b/include/asm-arm26/mc146818rtc.h
deleted file mode 100644
index a234130db8f1..000000000000
--- a/include/asm-arm26/mc146818rtc.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Machine dependent access functions for RTC registers.
3 */
4#ifndef _ASM_MC146818RTC_H
5#define _ASM_MC146818RTC_H
6
7#include <asm/irq.h>
8#include <asm/io.h>
9
10#ifndef RTC_PORT
11#define RTC_PORT(x) (0x70 + (x))
12#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
13#endif
14
15/*
16 * The yet supported machines all access the RTC index register via
17 * an ISA port access but the way to access the date register differs ...
18 */
19#define CMOS_READ(addr) ({ \
20outb_p((addr),RTC_PORT(0)); \
21inb_p(RTC_PORT(1)); \
22})
23#define CMOS_WRITE(val, addr) ({ \
24outb_p((addr),RTC_PORT(0)); \
25outb_p((val),RTC_PORT(1)); \
26})
27
28#endif /* _ASM_MC146818RTC_H */
diff --git a/include/asm-arm26/memory.h b/include/asm-arm26/memory.h
deleted file mode 100644
index 7c1e5be39060..000000000000
--- a/include/asm-arm26/memory.h
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * linux/include/asm-arm26/memory.h
3 *
4 * Copyright (C) 2000-2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Note: this file should not be included by non-asm/.h files
11 */
12#ifndef __ASM_ARM_MEMORY_H
13#define __ASM_ARM_MEMORY_H
14
15/*
16 * User space: 26MB
17 */
18#define TASK_SIZE (0x01a00000UL)
19
20/*
21 * This decides where the kernel will search for a free chunk of vm
22 * space during mmap's.
23 */
24#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
25
26/*
27 * Page offset: 32MB
28 */
29#define PAGE_OFFSET (0x02000000UL)
30#define PHYS_OFFSET (0x02000000UL)
31
32#define PHYS_TO_NID(addr) (0)
33
34/*
35 * PFNs are used to describe any physical page; this means
36 * PFN 0 == physical address 0.
37 *
38 * This is the PFN of the first RAM page in the kernel
39 * direct-mapped view. We assume this is the first page
40 * of RAM in the mem_map as well.
41 */
42#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
43
44/*
45 * These are *only* valid on the kernel direct mapped RAM memory.
46 */
47static inline unsigned long virt_to_phys(void *x)
48{
49 return (unsigned long)x;
50}
51
52static inline void *phys_to_virt(unsigned long x)
53{
54 return (void *)((unsigned long)x);
55}
56
57#define __pa(x) (unsigned long)(x)
58#define __va(x) ((void *)(unsigned long)(x))
59
60/*
61 * Virtual <-> DMA view memory address translations
62 * Again, these are *only* valid on the kernel direct mapped RAM
63 * memory. Use of these is *deprecated*.
64 */
65#define virt_to_bus(x) ((unsigned long)(x))
66#define bus_to_virt(x) ((void *)((unsigned long)(x)))
67
68/*
69 * Conversion between a struct page and a physical address.
70 *
71 * Note: when converting an unknown physical address to a
72 * struct page, the resulting pointer must be validated
73 * using VALID_PAGE(). It must return an invalid struct page
74 * for any physical address not corresponding to a system
75 * RAM address.
76 *
77 * page_to_pfn(page) convert a struct page * to a PFN number
78 * pfn_to_page(pfn) convert a _valid_ PFN number to struct page *
79 * pfn_valid(pfn) indicates whether a PFN number is valid
80 *
81 * virt_to_page(k) convert a _valid_ virtual address to struct page *
82 * virt_addr_valid(k) indicates whether a virtual address is valid
83 */
84#define ARCH_PFN_OFFSET (PHYS_PFN_OFFSET)
85#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
86
87#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
88#define virt_addr_valid(kaddr) ((int)(kaddr) >= PAGE_OFFSET && (int)(kaddr) < (unsigned long)high_memory)
89
90/*
91 * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die.
92 */
93#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
94
95/*
96 * We should really eliminate virt_to_bus() here - it's deprecated.
97 */
98#define page_to_bus(page) (page_address(page))
99
100#include <asm-generic/memory_model.h>
101#endif
diff --git a/include/asm-arm26/mman.h b/include/asm-arm26/mman.h
deleted file mode 100644
index 4000a6c1b76b..000000000000
--- a/include/asm-arm26/mman.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef __ARM_MMAN_H__
2#define __ARM_MMAN_H__
3
4#include <asm-generic/mman.h>
5
6#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
7#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
8#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
9#define MAP_LOCKED 0x2000 /* pages are locked */
10#define MAP_NORESERVE 0x4000 /* don't check for reservations */
11#define MAP_POPULATE 0x8000 /* populate (prefault) page tables */
12#define MAP_NONBLOCK 0x10000 /* do not block on IO */
13
14#define MCL_CURRENT 1 /* lock all current mappings */
15#define MCL_FUTURE 2 /* lock all future mappings */
16
17#endif /* __ARM_MMAN_H__ */
diff --git a/include/asm-arm26/mmu.h b/include/asm-arm26/mmu.h
deleted file mode 100644
index 9b8d3d781a1e..000000000000
--- a/include/asm-arm26/mmu.h
+++ /dev/null
@@ -1,9 +0,0 @@
1#ifndef __ARM_MMU_H
2#define __ARM_MMU_H
3
4/*
5 * The ARM doesn't have a mmu context
6 */
7typedef struct { } mm_context_t;
8
9#endif
diff --git a/include/asm-arm26/mmu_context.h b/include/asm-arm26/mmu_context.h
deleted file mode 100644
index 16c821f81b8d..000000000000
--- a/include/asm-arm26/mmu_context.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * linux/include/asm-arm/mmu_context.h
3 *
4 * Copyright (C) 1996 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Changelog:
11 * 27-06-1996 RMK Created
12 */
13#ifndef __ASM_ARM_MMU_CONTEXT_H
14#define __ASM_ARM_MMU_CONTEXT_H
15
16#include <asm-generic/mm_hooks.h>
17
18#define init_new_context(tsk,mm) 0
19#define destroy_context(mm) do { } while(0)
20
21/*
22 * This is called when "tsk" is about to enter lazy TLB mode.
23 *
24 * mm: describes the currently active mm context
25 * tsk: task which is entering lazy tlb
26 * cpu: cpu number which is entering lazy tlb
27 *
28 * tsk->mm will be NULL
29 */
30static inline void
31enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
32{
33}
34
35/*
36 * This is the actual mm switch as far as the scheduler
37 * is concerned. No registers are touched.
38 */
39static inline void
40switch_mm(struct mm_struct *prev, struct mm_struct *next,
41 struct task_struct *tsk)
42{
43 cpu_switch_mm(next->pgd, next);
44}
45
46#define deactivate_mm(tsk,mm) do { } while (0)
47
48static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
49{
50 cpu_switch_mm(next->pgd, next);
51}
52
53#endif
diff --git a/include/asm-arm26/module.h b/include/asm-arm26/module.h
deleted file mode 100644
index 1157f178daec..000000000000
--- a/include/asm-arm26/module.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _ASM_ARM_MODULE_H
2#define _ASM_ARM_MODULE_H
3/*
4 * This file contains the arm architecture specific module code.
5 */
6
7#endif /* _ASM_ARM_MODULE_H */
diff --git a/include/asm-arm26/msgbuf.h b/include/asm-arm26/msgbuf.h
deleted file mode 100644
index 33b35b946eaa..000000000000
--- a/include/asm-arm26/msgbuf.h
+++ /dev/null
@@ -1,31 +0,0 @@
1#ifndef _ASMARM_MSGBUF_H
2#define _ASMARM_MSGBUF_H
3
4/*
5 * The msqid64_ds structure for arm architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space is left for:
10 * - 64-bit time_t to solve y2038 problem
11 * - 2 miscellaneous 32-bit values
12 */
13
14struct msqid64_ds {
15 struct ipc64_perm msg_perm;
16 __kernel_time_t msg_stime; /* last msgsnd time */
17 unsigned long __unused1;
18 __kernel_time_t msg_rtime; /* last msgrcv time */
19 unsigned long __unused2;
20 __kernel_time_t msg_ctime; /* last change time */
21 unsigned long __unused3;
22 unsigned long msg_cbytes; /* current number of bytes on queue */
23 unsigned long msg_qnum; /* number of messages in queue */
24 unsigned long msg_qbytes; /* max number of bytes on queue */
25 __kernel_pid_t msg_lspid; /* pid of last msgsnd */
26 __kernel_pid_t msg_lrpid; /* last receive pid */
27 unsigned long __unused4;
28 unsigned long __unused5;
29};
30
31#endif /* _ASMARM_MSGBUF_H */
diff --git a/include/asm-arm26/namei.h b/include/asm-arm26/namei.h
deleted file mode 100644
index 3f5d340110eb..000000000000
--- a/include/asm-arm26/namei.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * linux/include/asm-arm26/namei.h
3 *
4 * Routines to handle famous /usr/gnemul
5 * Derived from the Sparc version of this file
6 *
7 * Included from linux/fs/namei.c
8 */
9
10#ifndef __ASMARM_NAMEI_H
11#define __ASMARM_NAMEI_H
12
13#define ARM_BSD_EMUL "usr/gnemul/bsd/"
14
15static inline char *__emul_prefix(void)
16{
17 switch (current->personality) {
18 case PER_BSD:
19 return ARM_BSD_EMUL;
20 default:
21 return NULL;
22 }
23}
24
25#endif /* __ASMARM_NAMEI_H */
diff --git a/include/asm-arm26/oldlatches.h b/include/asm-arm26/oldlatches.h
deleted file mode 100644
index bc87089b2152..000000000000
--- a/include/asm-arm26/oldlatches.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * linux/include/asm-arm/arch-arc/oldlatches.h
3 *
4 * Copyright (C) 1996 Russell King, Dave Gilbert
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Modifications:
11 * 04-04-1998 PJB/RMK Merged arc and a5k versions
12 */
13#ifndef _ASM_ARCH_OLDLATCH_H
14#define _ASM_ARCH_OLDLATCH_H
15
16#define LATCHA_FDSEL0 (1<<0)
17#define LATCHA_FDSEL1 (1<<1)
18#define LATCHA_FDSEL2 (1<<2)
19#define LATCHA_FDSEL3 (1<<3)
20#define LATCHA_FDSELALL (0xf)
21#define LATCHA_SIDESEL (1<<4)
22#define LATCHA_MOTOR (1<<5)
23#define LATCHA_INUSE (1<<6)
24#define LATCHA_CHANGERST (1<<7)
25
26#define LATCHB_FDCDENSITY (1<<1)
27#define LATCHB_FDCRESET (1<<3)
28#define LATCHB_PRINTSTROBE (1<<4)
29
30/* newval=(oldval & mask)|newdata */
31void oldlatch_bupdate(unsigned char mask,unsigned char newdata);
32
33/* newval=(oldval & mask)|newdata */
34void oldlatch_aupdate(unsigned char mask,unsigned char newdata);
35
36#endif
37
diff --git a/include/asm-arm26/page.h b/include/asm-arm26/page.h
deleted file mode 100644
index fa19de28fda0..000000000000
--- a/include/asm-arm26/page.h
+++ /dev/null
@@ -1,102 +0,0 @@
1#ifndef _ASMARM_PAGE_H
2#define _ASMARM_PAGE_H
3
4
5#ifdef __KERNEL__
6#ifndef __ASSEMBLY__
7
8extern void __clear_user_page(void *p, unsigned long user);
9extern void __copy_user_page(void *to, const void *from, unsigned long user);
10extern void copy_page(void *to, const void *from);
11
12//FIXME these may be wrong on ARM26
13#define clear_user_page(addr,vaddr,pg) \
14 do { \
15 preempt_disable(); \
16 __clear_user_page(addr, vaddr); \
17 preempt_enable(); \
18 } while (0)
19
20#define copy_user_page(to,from,vaddr,pg) \
21 do { \
22 preempt_disable(); \
23 __copy_user_page(to, from, vaddr); \
24 preempt_enable(); \
25 } while (0)
26
27#define clear_page(page) memzero((void *)(page), PAGE_SIZE)
28#define copy_page(to, from) __copy_user_page(to, from, 0);
29
30#undef STRICT_MM_TYPECHECKS
31
32#ifdef STRICT_MM_TYPECHECKS
33/*
34 * These are used to make use of C type-checking..
35 */
36typedef struct { unsigned long pgd; } pgd_t;
37typedef struct { unsigned long pte; } pte_t;
38typedef struct { unsigned long pmd; } pmd_t;
39typedef struct { unsigned long pgprot; } pgprot_t;
40
41#define pgd_val(x) ((x).pgd)
42#define pte_val(x) ((x).pte)
43#define pmd_val(x) ((x).pmd)
44#define pgprot_val(x) ((x).pgprot)
45
46#define __pte(x) ((pte_t) { (x) } )
47#define __pmd(x) ((pmd_t) { (x) } )
48#define __pgprot(x) ((pgprot_t) { (x) } )
49
50#else
51/*
52 * .. while these make it easier on the compiler
53 */
54typedef unsigned long pgd_t;
55typedef unsigned long pte_t;
56typedef unsigned long pmd_t;
57typedef unsigned long pgprot_t;
58
59//FIXME - should these cast to unsigned long?
60#define pgd_val(x) (x)
61#define pte_val(x) (x)
62#define pmd_val(x) (x)
63#define pgprot_val(x) (x)
64
65#define __pte(x) (x)
66#define __pmd(x) (x)
67#define __pgprot(x) (x)
68
69#endif /* STRICT_MM_TYPECHECKS */
70#endif /* !__ASSEMBLY__ */
71#endif /* __KERNEL__ */
72
73/* PAGE_SHIFT determines the page size. This is configurable. */
74#if defined(CONFIG_PAGESIZE_16)
75#define PAGE_SHIFT 14 /* 16K */
76#else /* default */
77#define PAGE_SHIFT 15 /* 32K */
78#endif
79
80#define EXEC_PAGESIZE 32768
81
82#define PAGE_SIZE (1UL << PAGE_SHIFT)
83#define PAGE_MASK (~(PAGE_SIZE-1))
84
85/* to align the pointer to the (next) page boundary */
86#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
87
88#ifdef __KERNEL__
89#ifndef __ASSEMBLY__
90
91#include <asm/memory.h>
92
93#endif /* !__ASSEMBLY__ */
94
95#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
96 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
97
98#endif /* __KERNEL__ */
99
100#include <asm-generic/page.h>
101
102#endif
diff --git a/include/asm-arm26/param.h b/include/asm-arm26/param.h
deleted file mode 100644
index 6b1e52df542e..000000000000
--- a/include/asm-arm26/param.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * linux/include/asm-arm/param.h
3 *
4 * Copyright (C) 1995-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASM_PARAM_H
11#define __ASM_PARAM_H
12
13#ifndef __KERNEL_HZ
14#define __KERNEL_HZ 100
15#endif
16
17#ifdef __KERNEL__
18# define HZ __KERNEL_HZ /* Internal kernel timer frequency */
19# define USER_HZ 100 /* User interfaces are in "ticks" */
20# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
21#else
22# define HZ 100
23#endif
24
25#ifndef NOGROUP
26#define NOGROUP (-1)
27#endif
28
29/* max length of hostname */
30#define MAXHOSTNAMELEN 64
31
32#endif
33
diff --git a/include/asm-arm26/parport.h b/include/asm-arm26/parport.h
deleted file mode 100644
index f2f90c76ddd1..000000000000
--- a/include/asm-arm26/parport.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * linux/include/asm-arm/parport.h: ARM-specific parport initialisation
3 *
4 * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
5 *
6 * This file should only be included by drivers/parport/parport_pc.c.
7 */
8
9#ifndef __ASMARM_PARPORT_H
10#define __ASMARM_PARPORT_H
11
12static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
13static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
14{
15 return parport_pc_find_isa_ports (autoirq, autodma);
16}
17
18#endif /* !(_ASMARM_PARPORT_H) */
diff --git a/include/asm-arm26/pci.h b/include/asm-arm26/pci.h
deleted file mode 100644
index 6ac67ed7718c..000000000000
--- a/include/asm-arm26/pci.h
+++ /dev/null
@@ -1,6 +0,0 @@
1/* Should not be needed. IDE stupidity */
2/* JMA 18.05.03 - is kinda needed, if only to tell it we don't have a PCI bus */
3
4#define PCI_DMA_BUS_IS_PHYS 0
5#define pcibios_scan_all_fns(a, b) 0
6
diff --git a/include/asm-arm26/percpu.h b/include/asm-arm26/percpu.h
deleted file mode 100644
index b4e32d8ec072..000000000000
--- a/include/asm-arm26/percpu.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __ARM_PERCPU
2#define __ARM_PERCPU
3
4#include <asm-generic/percpu.h>
5
6#endif
diff --git a/include/asm-arm26/pgalloc.h b/include/asm-arm26/pgalloc.h
deleted file mode 100644
index 7725af3ddb4d..000000000000
--- a/include/asm-arm26/pgalloc.h
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * linux/include/asm-arm/pgalloc.h
3 *
4 * Copyright (C) 2000-2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef _ASMARM_PGALLOC_H
11#define _ASMARM_PGALLOC_H
12
13#include <asm/processor.h>
14#include <asm/cacheflush.h>
15#include <asm/tlbflush.h>
16#include <linux/slab.h>
17
18extern struct kmem_cache *pte_cache;
19
20static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr){
21 return kmem_cache_alloc(pte_cache, GFP_KERNEL);
22}
23
24static inline void pte_free_kernel(pte_t *pte){
25 if (pte)
26 kmem_cache_free(pte_cache, pte);
27}
28
29/*
30 * Populate the pmdp entry with a pointer to the pte. This pmd is part
31 * of the mm address space.
32 *
33 * If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
34 * need to set stuff up correctly for it.
35 */
36static inline void
37pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
38{
39//FIXME - is this doing the right thing?
40 set_pmd(pmdp, (unsigned long)ptep | 1/*FIXME _PMD_PRESENT*/);
41}
42
43/*
44 * FIXME - We use the old 2.5.5-rmk1 hack for this.
45 * This is not truly correct, but should be functional.
46 */
47#define pte_alloc_one(mm,addr) ((struct page *)pte_alloc_one_kernel(mm,addr))
48#define pte_free(pte) pte_free_kernel((pte_t *)pte)
49#define pmd_populate(mm,pmdp,ptep) pmd_populate_kernel(mm,pmdp,(pte_t *)ptep)
50
51/*
52 * Since we have only two-level page tables, these are trivial
53 *
54 * trick __pmd_alloc into optimising away. The actual value is irrelevant though as it
55 * is thrown away. It just cant be zero. -IM
56 */
57
58#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
59#define pmd_free(pmd) do { } while (0)
60#define pgd_populate(mm,pmd,pte) BUG()
61
62extern pgd_t *get_pgd_slow(struct mm_struct *mm);
63extern void free_pgd_slow(pgd_t *pgd);
64
65#define pgd_alloc(mm) get_pgd_slow(mm)
66#define pgd_free(pgd) free_pgd_slow(pgd)
67
68#define check_pgt_cache() do { } while (0)
69
70#endif
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
deleted file mode 100644
index 55a1a697d12b..000000000000
--- a/include/asm-arm26/pgtable.h
+++ /dev/null
@@ -1,298 +0,0 @@
1/*
2 * linux/include/asm-arm26/pgtable.h
3 *
4 * Copyright (C) 2000-2002 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASMARM_PGTABLE_H
12#define _ASMARM_PGTABLE_H
13
14#include <asm-generic/4level-fixup.h>
15
16#include <asm/memory.h>
17
18/*
19 * The table below defines the page protection levels that we insert into our
20 * Linux page table version. These get translated into the best that the
21 * architecture can perform. Note that on most ARM hardware:
22 * 1) We cannot do execute protection
23 * 2) If we could do execute protection, then read is implied
24 * 3) write implies read permissions
25 */
26#define __P000 PAGE_NONE
27#define __P001 PAGE_READONLY
28#define __P010 PAGE_COPY
29#define __P011 PAGE_COPY
30#define __P100 PAGE_READONLY
31#define __P101 PAGE_READONLY
32#define __P110 PAGE_COPY
33#define __P111 PAGE_COPY
34
35#define __S000 PAGE_NONE
36#define __S001 PAGE_READONLY
37#define __S010 PAGE_SHARED
38#define __S011 PAGE_SHARED
39#define __S100 PAGE_READONLY
40#define __S101 PAGE_READONLY
41#define __S110 PAGE_SHARED
42#define __S111 PAGE_SHARED
43
44/*
45 * PMD_SHIFT determines the size of the area a second-level page table can map
46 * PGDIR_SHIFT determines what a third-level page table entry can map
47 */
48#define PGD_SHIFT 25
49#define PMD_SHIFT 20
50
51#define PGD_SIZE (1UL << PGD_SHIFT)
52#define PGD_MASK (~(PGD_SIZE-1))
53#define PMD_SIZE (1UL << PMD_SHIFT)
54#define PMD_MASK (~(PMD_SIZE-1))
55
56/* The kernel likes to use these names for the above (ick) */
57#define PGDIR_SIZE PGD_SIZE
58#define PGDIR_MASK PGD_MASK
59
60#define PTRS_PER_PGD 32
61#define PTRS_PER_PMD 1
62#define PTRS_PER_PTE 32
63
64/*
65 * This is the lowest virtual address we can permit any user space
66 * mapping to be mapped at. This is particularly important for
67 * non-high vector CPUs.
68 */
69#define FIRST_USER_ADDRESS PAGE_SIZE
70
71#define FIRST_USER_PGD_NR 1
72#define USER_PTRS_PER_PGD ((TASK_SIZE/PGD_SIZE) - FIRST_USER_PGD_NR)
73
74// FIXME - WTF?
75#define LIBRARY_TEXT_START 0x0c000000
76
77
78
79#ifndef __ASSEMBLY__
80extern void __pte_error(const char *file, int line, unsigned long val);
81extern void __pmd_error(const char *file, int line, unsigned long val);
82extern void __pgd_error(const char *file, int line, unsigned long val);
83
84#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
85#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
86#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
87
88/*
89 * ZERO_PAGE is a global shared page that is always zero: used
90 * for zero-mapped memory areas etc..
91 */
92extern struct page *empty_zero_page;
93#define ZERO_PAGE(vaddr) (empty_zero_page)
94
95#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
96#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
97#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
98#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
99#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
100
101/*
102 * Terminology: PGD = Page Directory, PMD = Page Middle Directory,
103 * PTE = Page Table Entry
104 *
105 * on arm26 we have no 2nd level page table. we simulate this by removing the
106 * PMD.
107 *
108 * pgd_none is 0 to prevernt pmd_alloc() calling __pmd_alloc(). This causes it
109 * to return pmd_offset(pgd,addr) which is a pointer to the pgd (IOW, a no-op).
110 *
111 * however, to work this way, whilst we are allocating 32 pgds, containing 32
112 * PTEs, the actual work is done on the PMDs, thus:
113 *
114 * instead of mm->pgd->pmd->pte
115 * we have mm->pgdpmd->pte
116 *
117 * IOW, think of PGD operations and PMD ones as being the same thing, just
118 * that PGD stuff deals with the mm_struct side of things, wheras PMD stuff
119 * deals with the pte side of things.
120 *
121 * additionally, we store some bits in the PGD and PTE pointers:
122 * PGDs:
123 * o The lowest (1) bit of the PGD is to determine if it is present or swap.
124 * o The 2nd bit of the PGD is unused and must be zero.
125 * o The top 6 bits of the PGD must be zero.
126 * PTEs:
127 * o The lower 5 bits of a pte are flags. bit 1 is the 'present' flag. The
128 * others determine the pages attributes.
129 *
130 * the pgd_val, pmd_val, and pte_val macros seem to be private to our code.
131 * They get the RAW value of the PGD/PMD/PTE entry, including our flags
132 * encoded into the pointers.
133 *
134 * The pgd_offset, pmd_offset, and pte_offset macros are used by the kernel,
135 * so they shouldnt have our flags attached.
136 *
137 * If you understood that, feel free to explain it to me...
138 *
139 */
140
141#define _PMD_PRESENT (0x01)
142
143/* These definitions allow us to optimise out stuff like pmd_alloc() */
144#define pgd_none(pgd) (0)
145#define pgd_bad(pgd) (0)
146#define pgd_present(pgd) (1)
147#define pgd_clear(pgdp) do { } while (0)
148
149/* Whilst these handle our actual 'page directory' (the agglomeration of pgd and pmd)
150 */
151#define pmd_none(pmd) (!pmd_val(pmd))
152#define pmd_bad(pmd) ((pmd_val(pmd) & 0xfc000002))
153#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT)
154#define set_pmd(pmd_ptr, pmd) ((*(pmd_ptr)) = (pmd))
155#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
156
157/* and these handle our pte tables */
158#define pte_none(pte) (!pte_val(pte))
159#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
160#define set_pte(pte_ptr, pte) ((*(pte_ptr)) = (pte))
161#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
162#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0))
163
164/* macros to ease the getting of pointers to stuff... */
165#define pgd_offset(mm, addr) ((pgd_t *)(mm)->pgd + __pgd_index(addr))
166#define pmd_offset(pgd, addr) ((pmd_t *)(pgd))
167#define pte_offset(pmd, addr) ((pte_t *)pmd_page(*(pmd)) + __pte_index(addr))
168
169/* there is no __pmd_index as we dont use pmds */
170#define __pgd_index(addr) ((addr) >> PGD_SHIFT)
171#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
172
173
174/* Keep the kernel happy */
175#define pgd_index(addr) __pgd_index(addr)
176#define pgd_offset_k(addr) (pgd_offset(&init_mm, addr))
177
178/*
179 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
180 * area for the same reason. ;) FIXME: surely 1 page not 4k ?
181 */
182#define VMALLOC_START 0x01a00000
183#define VMALLOC_END 0x01c00000
184
185/* Is pmd_page supposed to return a pointer to a page in some arches? ours seems to
186 * return a pointer to memory (no special alignment)
187 */
188#define pmd_page(pmd) ((struct page *)(pmd_val((pmd)) & ~_PMD_PRESENT))
189#define pmd_page_vaddr(pmd) ((pte_t *)(pmd_val((pmd)) & ~_PMD_PRESENT))
190
191#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
192
193#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
194#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
195#define pte_unmap(pte) do { } while (0)
196#define pte_unmap_nested(pte) do { } while (0)
197
198
199#define _PAGE_PRESENT 0x01
200#define _PAGE_READONLY 0x02
201#define _PAGE_NOT_USER 0x04
202#define _PAGE_OLD 0x08
203#define _PAGE_CLEAN 0x10
204
205// an old page has never been read.
206// a clean page has never been written.
207
208/* -- present -- -- !dirty -- --- !write --- ---- !user --- */
209#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY | _PAGE_NOT_USER)
210#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_CLEAN )
211#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY )
212#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY )
213#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_NOT_USER)
214
215#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_OLD | _PAGE_CLEAN)
216
217/*
218 * The following only work if pte_present() is true.
219 * Undefined behaviour if not..
220 */
221#define pte_write(pte) (!(pte_val(pte) & _PAGE_READONLY))
222#define pte_dirty(pte) (!(pte_val(pte) & _PAGE_CLEAN))
223#define pte_young(pte) (!(pte_val(pte) & _PAGE_OLD))
224//ONLY when !pte_present() I think. nicked from arm32 (FIXME!)
225#define pte_file(pte) (!(pte_val(pte) & _PAGE_OLD))
226
227#define PTE_BIT_FUNC(fn,op) \
228static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
229
230PTE_BIT_FUNC(wrprotect, |= _PAGE_READONLY);
231PTE_BIT_FUNC(mkwrite, &= ~_PAGE_READONLY);
232PTE_BIT_FUNC(mkclean, |= _PAGE_CLEAN);
233PTE_BIT_FUNC(mkdirty, &= ~_PAGE_CLEAN);
234PTE_BIT_FUNC(mkold, |= _PAGE_OLD);
235PTE_BIT_FUNC(mkyoung, &= ~_PAGE_OLD);
236
237/*
238 * We don't store cache state bits in the page table here. FIXME - or do we?
239 */
240#define pgprot_noncached(prot) (prot)
241#define pgprot_writecombine(prot) (prot) //FIXME - is a no-op?
242
243extern void pgtable_cache_init(void);
244
245//FIXME - nicked from arm32 and brutally hacked. probably wrong.
246#define pte_to_pgoff(x) (pte_val(x) >> 2)
247#define pgoff_to_pte(x) __pte(((x) << 2) & ~_PAGE_OLD)
248
249//FIXME - next line borrowed from arm32. is it right?
250#define PTE_FILE_MAX_BITS 30
251
252
253static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
254{
255 pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
256 return pte;
257}
258
259extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
260
261/* Encode and decode a swap entry.
262 *
263 * We support up to 32GB of swap on 4k machines
264 */
265#define __swp_type(x) (((x).val >> 2) & 0x7f)
266#define __swp_offset(x) ((x).val >> 9)
267#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
268#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
269#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
270
271/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
272/* FIXME: this is not correct */
273#define kern_addr_valid(addr) (1)
274
275/*
276 * Conversion functions: convert a page and protection to a page entry,
277 * and a page entry and page directory to the page they refer to.
278 */
279static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
280{
281 pte_t pte;
282 pte_val(pte) = physpage | pgprot_val(pgprot);
283 return pte;
284}
285
286
287#include <asm-generic/pgtable.h>
288
289/*
290 * remap a physical page `pfn' of size `size' with page protection `prot'
291 * into virtual address `from'
292 */
293#define io_remap_pfn_range(vma,from,pfn,size,prot) \
294 remap_pfn_range(vma, from, pfn, size, prot)
295
296#endif /* !__ASSEMBLY__ */
297
298#endif /* _ASMARM_PGTABLE_H */
diff --git a/include/asm-arm26/poll.h b/include/asm-arm26/poll.h
deleted file mode 100644
index 1170e7065f6a..000000000000
--- a/include/asm-arm26/poll.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef __ASMARM_POLL_H
2#define __ASMARM_POLL_H
3
4#include <asm-generic/poll.h>
5
6#undef POLLREMOVE
7
8#endif
diff --git a/include/asm-arm26/posix_types.h b/include/asm-arm26/posix_types.h
deleted file mode 100644
index f8d1eb4f4cb1..000000000000
--- a/include/asm-arm26/posix_types.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * linux/include/asm-arm/posix_types.h
3 *
4 * Copyright (C) 1996-1998 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Changelog:
11 * 27-06-1996 RMK Created
12 */
13#ifndef __ARCH_ARM_POSIX_TYPES_H
14#define __ARCH_ARM_POSIX_TYPES_H
15
16/*
17 * This file is generally used by user-level software, so you need to
18 * be a little careful about namespace pollution etc. Also, we cannot
19 * assume GCC is being used.
20 */
21
22typedef unsigned long __kernel_ino_t;
23typedef unsigned short __kernel_mode_t;
24typedef unsigned short __kernel_nlink_t;
25typedef long __kernel_off_t;
26typedef int __kernel_pid_t;
27typedef unsigned short __kernel_ipc_pid_t;
28typedef unsigned short __kernel_uid_t;
29typedef unsigned short __kernel_gid_t;
30typedef unsigned int __kernel_size_t;
31typedef int __kernel_ssize_t;
32typedef int __kernel_ptrdiff_t;
33typedef long __kernel_time_t;
34typedef long __kernel_suseconds_t;
35typedef long __kernel_clock_t;
36typedef int __kernel_timer_t;
37typedef int __kernel_clockid_t;
38typedef int __kernel_daddr_t;
39typedef char * __kernel_caddr_t;
40typedef unsigned short __kernel_uid16_t;
41typedef unsigned short __kernel_gid16_t;
42typedef unsigned int __kernel_uid32_t;
43typedef unsigned int __kernel_gid32_t;
44
45typedef unsigned short __kernel_old_uid_t;
46typedef unsigned short __kernel_old_gid_t;
47typedef unsigned short __kernel_old_dev_t;
48
49#ifdef __GNUC__
50typedef long long __kernel_loff_t;
51#endif
52
53typedef struct {
54#if defined(__KERNEL__) || defined(__USE_ALL)
55 int val[2];
56#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
57 int __val[2];
58#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
59} __kernel_fsid_t;
60
61#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
62
63#undef __FD_SET
64#define __FD_SET(fd, fdsetp) \
65 (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
66
67#undef __FD_CLR
68#define __FD_CLR(fd, fdsetp) \
69 (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
70
71#undef __FD_ISSET
72#define __FD_ISSET(fd, fdsetp) \
73 ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
74
75#undef __FD_ZERO
76#define __FD_ZERO(fdsetp) \
77 (memset ((fdsetp), 0, sizeof (*(fd_set *)(fdsetp))))
78
79#endif
80
81#endif
diff --git a/include/asm-arm26/proc-fns.h b/include/asm-arm26/proc-fns.h
deleted file mode 100644
index a83100454055..000000000000
--- a/include/asm-arm26/proc-fns.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * linux/include/asm-arm26/proc-fns.h
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASSEMBLY__
11
12#include <asm/page.h>
13
14/*
15 * Don't change this structure - ASM code
16 * relies on it.
17 */
18extern struct processor {
19 /* check for any bugs */
20 void (*_check_bugs)(void);
21 /* Set up any processor specifics */
22 void (*_proc_init)(void);
23 /* Disable any processor specifics */
24 void (*_proc_fin)(void);
25 /* set the MEMC hardware mappings */
26 void (*_set_pgd)(pgd_t *pgd);
27 /* XCHG */
28 unsigned long (*_xchg_1)(unsigned long x, volatile void *ptr);
29 unsigned long (*_xchg_4)(unsigned long x, volatile void *ptr);
30} processor;
31
32extern const struct processor arm2_processor_functions;
33extern const struct processor arm250_processor_functions;
34extern const struct processor arm3_processor_functions;
35
36#define cpu_check_bugs() processor._check_bugs()
37#define cpu_proc_init() processor._proc_init()
38#define cpu_proc_fin() processor._proc_fin()
39#define cpu_do_idle() do { } while (0)
40#define cpu_switch_mm(pgd,mm) processor._set_pgd(pgd)
41#define cpu_xchg_1(x,ptr) processor._xchg_1(x,ptr)
42#define cpu_xchg_4(x,ptr) processor._xchg_4(x,ptr)
43
44
45//FIXME - these shouldnt be in proc-fn.h
46extern void cpu_memc_update_all(pgd_t *pgd);
47extern void cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long log_addr);
48
49#endif
diff --git a/include/asm-arm26/processor.h b/include/asm-arm26/processor.h
deleted file mode 100644
index 1d2d5f7b467b..000000000000
--- a/include/asm-arm26/processor.h
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * linux/include/asm-arm26/processor.h
3 *
4 * Copyright (C) 1995 Russell King
5 * Copyright (C) 2003 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __ASM_ARM_PROCESSOR_H
13#define __ASM_ARM_PROCESSOR_H
14
15/*
16 * Default implementation of macro that returns current
17 * instruction pointer ("program counter").
18 */
19#define current_text_addr() ({ __label__ _l; _l: &&_l;})
20
21#ifdef __KERNEL__
22
23#include <asm/atomic.h>
24#include <asm/ptrace.h>
25#include <linux/string.h>
26
27#define KERNEL_STACK_SIZE 4096
28
29typedef struct {
30 void (*put_byte)(void); /* Special calling convention */
31 void (*get_byte)(void); /* Special calling convention */
32 void (*put_half)(void); /* Special calling convention */
33 void (*get_half)(void); /* Special calling convention */
34 void (*put_word)(void); /* Special calling convention */
35 void (*get_word)(void); /* Special calling convention */
36 void (*put_dword)(void); /* Special calling convention */
37 unsigned long (*copy_from_user)(void *to, const void *from, unsigned long sz);
38 unsigned long (*copy_to_user)(void *to, const void *from, unsigned long sz);
39 unsigned long (*clear_user)(void *addr, unsigned long sz);
40 unsigned long (*strncpy_from_user)(char *to, const char *from, unsigned long sz);
41 unsigned long (*strnlen_user)(const char *s, long n);
42} uaccess_t;
43
44extern uaccess_t uaccess_user, uaccess_kernel;
45
46#define EXTRA_THREAD_STRUCT \
47 uaccess_t *uaccess; /* User access functions*/
48
49#define EXTRA_THREAD_STRUCT_INIT \
50 .uaccess = &uaccess_kernel,
51
52// FIXME?!!
53
54#define start_thread(regs,pc,sp) \
55({ \
56 unsigned long *stack = (unsigned long *)sp; \
57 set_fs(USER_DS); \
58 memzero(regs->uregs, sizeof (regs->uregs)); \
59 regs->ARM_pc = pc | ~0xfc000003; /* pc */ \
60 regs->ARM_sp = sp; /* sp */ \
61 regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
62 regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
63 regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
64})
65
66#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
67#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1018])
68
69struct debug_entry {
70 u32 address;
71 u32 insn;
72};
73
74struct debug_info {
75 int nsaved;
76 struct debug_entry bp[2];
77};
78
79struct thread_struct {
80 /* fault info */
81 unsigned long address;
82 unsigned long trap_no;
83 unsigned long error_code;
84 /* debugging */
85 struct debug_info debug;
86 EXTRA_THREAD_STRUCT
87};
88
89#define INIT_THREAD { \
90EXTRA_THREAD_STRUCT_INIT \
91}
92
93/* Forward declaration, a strange C thing */
94struct task_struct;
95
96/* Free all resources held by a thread. */
97extern void release_thread(struct task_struct *);
98
99unsigned long get_wchan(struct task_struct *p);
100
101#define cpu_relax() barrier()
102
103/* Prepare to copy thread state - unlazy all lazy status */
104#define prepare_to_copy(tsk) do { } while (0)
105
106/*
107 * Create a new kernel thread
108 */
109extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
110
111#endif
112
113#endif /* __ASM_ARM_PROCESSOR_H */
diff --git a/include/asm-arm26/procinfo.h b/include/asm-arm26/procinfo.h
deleted file mode 100644
index b28624db69ff..000000000000
--- a/include/asm-arm26/procinfo.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * linux/include/asm-arm/procinfo.h
3 *
4 * Copyright (C) 1996-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASM_PROCINFO_H
11#define __ASM_PROCINFO_H
12
13#ifndef __ASSEMBLY__
14
15//struct processor;
16//struct cpu_user_fns;
17
18struct proc_info_item {
19 const char *manufacturer;
20 const char *cpu_name;
21};
22
23/*
24 * Note! struct processor is always defined if we're
25 * using MULTI_CPU, otherwise this entry is unused,
26 * but still exists.
27 *
28 * NOTE! The following structure is defined by assembly
29 * language, NOT C code. For more information, check:
30 * arch/arm/mm/proc-*.S and arch/arm/kernel/head-armv.S
31 */
32struct proc_info_list {
33 unsigned int cpu_val;
34 unsigned int cpu_mask;
35 const char *arch_name;
36 const char *elf_name;
37 unsigned int elf_hwcap;
38 struct proc_info_item *info;
39 struct processor *proc;
40};
41
42#endif /* __ASSEMBLY__ */
43
44#define PROC_INFO_SZ 48
45
46#define HWCAP_SWP 1
47#define HWCAP_HALF 2
48#define HWCAP_THUMB 4
49#define HWCAP_26BIT 8 /* Play it safe */
50#define HWCAP_FAST_MULT 16
51#define HWCAP_FPA 32
52#define HWCAP_VFP 64
53#define HWCAP_EDSP 128
54#define HWCAP_JAVA 256
55
56#endif
diff --git a/include/asm-arm26/ptrace.h b/include/asm-arm26/ptrace.h
deleted file mode 100644
index 6a46b5ae1156..000000000000
--- a/include/asm-arm26/ptrace.h
+++ /dev/null
@@ -1,104 +0,0 @@
1#ifndef __ASM_ARM_PTRACE_H
2#define __ASM_ARM_PTRACE_H
3
4#define PTRACE_GETREGS 12
5#define PTRACE_SETREGS 13
6#define PTRACE_GETFPREGS 14
7#define PTRACE_SETFPREGS 15
8#define PTRACE_OLDSETOPTIONS 21
9
10/* options set using PTRACE_SETOPTIONS */
11#define PTRACE_O_TRACESYSGOOD 0x00000001
12
13#define MODE_USR26 0x00000000
14#define MODE_FIQ26 0x00000001
15#define MODE_IRQ26 0x00000002
16#define MODE_SVC26 0x00000003
17#define MODE_MASK 0x00000003
18
19#define PSR_F_BIT 0x04000000
20#define PSR_I_BIT 0x08000000
21#define PSR_V_BIT 0x10000000
22#define PSR_C_BIT 0x20000000
23#define PSR_Z_BIT 0x40000000
24#define PSR_N_BIT 0x80000000
25
26#define PCMASK 0xfc000003
27
28
29#ifndef __ASSEMBLY__
30
31#define pc_pointer(v) ((v) & ~PCMASK) /* convert v to pc type address */
32#define instruction_pointer(regs) (pc_pointer((regs)->ARM_pc)) /* get pc */
33#define profile_pc(regs) instruction_pointer(regs)
34
35/* this struct defines the way the registers are stored on the
36 stack during a system call. */
37
38struct pt_regs {
39 long uregs[17];
40};
41
42#define ARM_pc uregs[15]
43#define ARM_lr uregs[14]
44#define ARM_sp uregs[13]
45#define ARM_ip uregs[12]
46#define ARM_fp uregs[11]
47#define ARM_r10 uregs[10]
48#define ARM_r9 uregs[9]
49#define ARM_r8 uregs[8]
50#define ARM_r7 uregs[7]
51#define ARM_r6 uregs[6]
52#define ARM_r5 uregs[5]
53#define ARM_r4 uregs[4]
54#define ARM_r3 uregs[3]
55#define ARM_r2 uregs[2]
56#define ARM_r1 uregs[1]
57#define ARM_r0 uregs[0]
58#define ARM_ORIG_r0 uregs[16]
59
60#ifdef __KERNEL__
61
62#define processor_mode(regs) \
63 ((regs)->ARM_pc & MODE_MASK)
64
65#define user_mode(regs) \
66 (processor_mode(regs) == MODE_USR26)
67
68#define interrupts_enabled(regs) \
69 (!((regs)->ARM_pc & PSR_I_BIT))
70
71#define fast_interrupts_enabled(regs) \
72 (!((regs)->ARM_pc & PSR_F_BIT))
73
74#define condition_codes(regs) \
75 ((regs)->ARM_pc & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT))
76
77/* Are the current registers suitable for user mode?
78 * (used to maintain security in signal handlers)
79 */
80static inline int valid_user_regs(struct pt_regs *regs)
81{
82 if (user_mode(regs) &&
83 (regs->ARM_pc & (PSR_F_BIT | PSR_I_BIT)) == 0)
84 return 1;
85
86 /*
87 * force it to be something sensible
88 */
89 regs->ARM_pc &= ~(MODE_MASK | PSR_F_BIT | PSR_I_BIT);
90
91 return 0;
92}
93
94extern void show_regs(struct pt_regs *);
95
96#define predicate(x) (x & 0xf0000000)
97#define PREDICATE_ALWAYS 0xe0000000
98
99#endif /* __KERNEL__ */
100
101#endif /* __ASSEMBLY__ */
102
103#endif
104
diff --git a/include/asm-arm26/resource.h b/include/asm-arm26/resource.h
deleted file mode 100644
index 734b581b5b6a..000000000000
--- a/include/asm-arm26/resource.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ARM_RESOURCE_H
2#define _ARM_RESOURCE_H
3
4#include <asm-generic/resource.h>
5
6#endif
diff --git a/include/asm-arm26/scatterlist.h b/include/asm-arm26/scatterlist.h
deleted file mode 100644
index d9c056c7784e..000000000000
--- a/include/asm-arm26/scatterlist.h
+++ /dev/null
@@ -1,26 +0,0 @@
1#ifndef _ASMARM_SCATTERLIST_H
2#define _ASMARM_SCATTERLIST_H
3
4#include <asm/types.h>
5
6struct scatterlist {
7 struct page *page; /* buffer page */
8 unsigned int offset; /* buffer offset */
9 dma_addr_t dma_address; /* dma address */
10 unsigned int length; /* length */
11 char *__address; /* for set_dma_addr */
12};
13
14/*
15 * These macros should be used after a pci_map_sg call has been done
16 * to get bus addresses of each of the SG entries and their lengths.
17 * You should only work with the number of sg entries pci_map_sg
18 * returns, or alternatively stop on the first sg_dma_len(sg) which
19 * is 0.
20 */
21#define sg_dma_address(sg) ((sg)->dma_address)
22#define sg_dma_len(sg) ((sg)->length)
23
24#define ISA_DMA_THRESHOLD (0xffffffff)
25
26#endif /* _ASMARM_SCATTERLIST_H */
diff --git a/include/asm-arm26/sections.h b/include/asm-arm26/sections.h
deleted file mode 100644
index 10b6370efad0..000000000000
--- a/include/asm-arm26/sections.h
+++ /dev/null
@@ -1,2 +0,0 @@
1//FIXME - nicked from arm32 - check its correct.
2#include <asm-generic/sections.h>
diff --git a/include/asm-arm26/segment.h b/include/asm-arm26/segment.h
deleted file mode 100644
index 9e24c21f6304..000000000000
--- a/include/asm-arm26/segment.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef __ASM_ARM_SEGMENT_H
2#define __ASM_ARM_SEGMENT_H
3
4#define __KERNEL_CS 0x0
5#define __KERNEL_DS 0x0
6
7#define __USER_CS 0x1
8#define __USER_DS 0x1
9
10#endif /* __ASM_ARM_SEGMENT_H */
11
diff --git a/include/asm-arm26/semaphore-helper.h b/include/asm-arm26/semaphore-helper.h
deleted file mode 100644
index 1d7f1987edb9..000000000000
--- a/include/asm-arm26/semaphore-helper.h
+++ /dev/null
@@ -1,84 +0,0 @@
1#ifndef ASMARM_SEMAPHORE_HELPER_H
2#define ASMARM_SEMAPHORE_HELPER_H
3
4/*
5 * These two _must_ execute atomically wrt each other.
6 */
7static inline void wake_one_more(struct semaphore * sem)
8{
9 unsigned long flags;
10
11 spin_lock_irqsave(&semaphore_wake_lock, flags);
12 if (atomic_read(&sem->count) <= 0)
13 sem->waking++;
14 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
15}
16
17static inline int waking_non_zero(struct semaphore *sem)
18{
19 unsigned long flags;
20 int ret = 0;
21
22 spin_lock_irqsave(&semaphore_wake_lock, flags);
23 if (sem->waking > 0) {
24 sem->waking--;
25 ret = 1;
26 }
27 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
28 return ret;
29}
30
31/*
32 * waking non zero interruptible
33 * 1 got the lock
34 * 0 go to sleep
35 * -EINTR interrupted
36 *
37 * We must undo the sem->count down_interruptible() increment while we are
38 * protected by the spinlock in order to make this atomic_inc() with the
39 * atomic_read() in wake_one_more(), otherwise we can race. -arca
40 */
41static inline int waking_non_zero_interruptible(struct semaphore *sem,
42 struct task_struct *tsk)
43{
44 unsigned long flags;
45 int ret = 0;
46
47 spin_lock_irqsave(&semaphore_wake_lock, flags);
48 if (sem->waking > 0) {
49 sem->waking--;
50 ret = 1;
51 } else if (signal_pending(tsk)) {
52 atomic_inc(&sem->count);
53 ret = -EINTR;
54 }
55 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
56 return ret;
57}
58
59/*
60 * waking_non_zero_try_lock:
61 * 1 failed to lock
62 * 0 got the lock
63 *
64 * We must undo the sem->count down_interruptible() increment while we are
65 * protected by the spinlock in order to make this atomic_inc() with the
66 * atomic_read() in wake_one_more(), otherwise we can race. -arca
67 */
68static inline int waking_non_zero_trylock(struct semaphore *sem)
69{
70 unsigned long flags;
71 int ret = 1;
72
73 spin_lock_irqsave(&semaphore_wake_lock, flags);
74 if (sem->waking <= 0)
75 atomic_inc(&sem->count);
76 else {
77 sem->waking--;
78 ret = 0;
79 }
80 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
81 return ret;
82}
83
84#endif
diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
deleted file mode 100644
index 1fda54375ed8..000000000000
--- a/include/asm-arm26/semaphore.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * linux/include/asm-arm26/semaphore.h
3 */
4#ifndef __ASM_ARM_SEMAPHORE_H
5#define __ASM_ARM_SEMAPHORE_H
6
7#include <linux/linkage.h>
8#include <linux/spinlock.h>
9#include <linux/wait.h>
10#include <linux/rwsem.h>
11
12#include <asm/atomic.h>
13#include <asm/locks.h>
14
15struct semaphore {
16 atomic_t count;
17 int sleepers;
18 wait_queue_head_t wait;
19};
20
21#define __SEMAPHORE_INIT(name, n) \
22{ \
23 .count = ATOMIC_INIT(n), \
24 .sleepers = 0, \
25 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
26}
27
28#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
29 struct semaphore name = __SEMAPHORE_INIT(name,count)
30
31#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
32#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
33
34static inline void sema_init(struct semaphore *sem, int val)
35{
36 atomic_set(&sem->count, val);
37 sem->sleepers = 0;
38 init_waitqueue_head(&sem->wait);
39}
40
41static inline void init_MUTEX(struct semaphore *sem)
42{
43 sema_init(sem, 1);
44}
45
46static inline void init_MUTEX_LOCKED(struct semaphore *sem)
47{
48 sema_init(sem, 0);
49}
50
51/*
52 * special register calling convention
53 */
54asmlinkage void __down_failed(void);
55asmlinkage int __down_interruptible_failed(void);
56asmlinkage int __down_trylock_failed(void);
57asmlinkage void __up_wakeup(void);
58
59extern void __down(struct semaphore * sem);
60extern int __down_interruptible(struct semaphore * sem);
61extern int __down_trylock(struct semaphore * sem);
62extern void __up(struct semaphore * sem);
63
64/*
65 * This is ugly, but we want the default case to fall through.
66 * "__down" is the actual routine that waits...
67 */
68static inline void down(struct semaphore * sem)
69{
70 might_sleep();
71 __down_op(sem, __down_failed);
72}
73
74/*
75 * This is ugly, but we want the default case to fall through.
76 * "__down_interruptible" is the actual routine that waits...
77 */
78static inline int down_interruptible (struct semaphore * sem)
79{
80 might_sleep();
81 return __down_op_ret(sem, __down_interruptible_failed);
82}
83
84static inline int down_trylock(struct semaphore *sem)
85{
86 return __down_op_ret(sem, __down_trylock_failed);
87}
88
89/*
90 * Note! This is subtle. We jump to wake people up only if
91 * the semaphore was negative (== somebody was waiting on it).
92 * The default case (no contention) will result in NO
93 * jumps for both down() and up().
94 */
95static inline void up(struct semaphore * sem)
96{
97 __up_op(sem, __up_wakeup);
98}
99
100#endif
diff --git a/include/asm-arm26/sembuf.h b/include/asm-arm26/sembuf.h
deleted file mode 100644
index 1c0283954289..000000000000
--- a/include/asm-arm26/sembuf.h
+++ /dev/null
@@ -1,25 +0,0 @@
1#ifndef _ASMARM_SEMBUF_H
2#define _ASMARM_SEMBUF_H
3
4/*
5 * The semid64_ds structure for arm architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space is left for:
10 * - 64-bit time_t to solve y2038 problem
11 * - 2 miscellaneous 32-bit values
12 */
13
14struct semid64_ds {
15 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
16 __kernel_time_t sem_otime; /* last semop time */
17 unsigned long __unused1;
18 __kernel_time_t sem_ctime; /* last change time */
19 unsigned long __unused2;
20 unsigned long sem_nsems; /* no. of semaphores in array */
21 unsigned long __unused3;
22 unsigned long __unused4;
23};
24
25#endif /* _ASMARM_SEMBUF_H */
diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h
deleted file mode 100644
index dd86a716cb0b..000000000000
--- a/include/asm-arm26/serial.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * linux/include/asm-arm/serial.h
3 *
4 * Copyright (C) 1996 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Changelog:
11 * 15-10-1996 RMK Created
12 */
13
14#ifndef __ASM_SERIAL_H
15#define __ASM_SERIAL_H
16
17
18/*
19 * This assumes you have a 1.8432 MHz clock for your UART.
20 *
21 * It'd be nice if someone built a serial card with a 24.576 MHz
22 * clock, since the 16550A is capable of handling a top speed of 1.5
23 * megabits/second; but this requires the faster clock.
24 */
25#define BASE_BAUD (1843200 / 16)
26
27#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
28
29#if defined(CONFIG_ARCH_A5K)
30 /* UART CLK PORT IRQ FLAGS */
31
32#define SERIAL_PORT_DFNS \
33 { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \
34 { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */
35
36#else
37
38#define SERIAL_PORT_DFNS \
39 { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS0 */ \
40 { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */
41
42#endif
43
44#endif
diff --git a/include/asm-arm26/setup.h b/include/asm-arm26/setup.h
deleted file mode 100644
index e82562306475..000000000000
--- a/include/asm-arm26/setup.h
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 * linux/include/asm/setup.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Structure passed to kernel to tell it about the
11 * hardware it's running on. See Documentation/arm/Setup
12 * for more info.
13 */
14#ifndef __ASMARM_SETUP_H
15#define __ASMARM_SETUP_H
16
17#define COMMAND_LINE_SIZE 1024
18
19#ifdef __KERNEL__
20
21/* The list ends with an ATAG_NONE node. */
22#define ATAG_NONE 0x00000000
23
24struct tag_header {
25 u32 size;
26 u32 tag;
27};
28
29/* The list must start with an ATAG_CORE node */
30#define ATAG_CORE 0x54410001
31
32struct tag_core {
33 u32 flags; /* bit 0 = read-only */
34 u32 pagesize;
35 u32 rootdev;
36};
37
38/* it is allowed to have multiple ATAG_MEM nodes */
39#define ATAG_MEM 0x54410002
40
41struct tag_mem32 {
42 u32 size;
43 u32 start; /* physical start address */
44};
45
46/* VGA text type displays */
47#define ATAG_VIDEOTEXT 0x54410003
48
49struct tag_videotext {
50 u8 x;
51 u8 y;
52 u16 video_page;
53 u8 video_mode;
54 u8 video_cols;
55 u16 video_ega_bx;
56 u8 video_lines;
57 u8 video_isvga;
58 u16 video_points;
59};
60
61/* describes how the ramdisk will be used in kernel */
62#define ATAG_RAMDISK 0x54410004
63
64struct tag_ramdisk {
65 u32 flags; /* bit 0 = load, bit 1 = prompt */
66 u32 size; /* decompressed ramdisk size in _kilo_ bytes */
67 u32 start; /* starting block of floppy-based RAM disk image */
68};
69
70/* describes where the compressed ramdisk image lives */
71/*
72 * this one accidentally used virtual addresses - as such,
73 * it's deprecated.
74 */
75#define ATAG_INITRD 0x54410005
76
77/* describes where the compressed ramdisk image lives */
78#define ATAG_INITRD2 0x54420005
79
80struct tag_initrd {
81 u32 start; /* physical start address */
82 u32 size; /* size of compressed ramdisk image in bytes */
83};
84
85/* board serial number. "64 bits should be enough for everybody" */
86#define ATAG_SERIAL 0x54410006
87
88struct tag_serialnr {
89 u32 low;
90 u32 high;
91};
92
93/* board revision */
94#define ATAG_REVISION 0x54410007
95
96struct tag_revision {
97 u32 rev;
98};
99
100/* initial values for vesafb-type framebuffers. see struct screen_info
101 * in include/linux/tty.h
102 */
103#define ATAG_VIDEOLFB 0x54410008
104
105struct tag_videolfb {
106 u16 lfb_width;
107 u16 lfb_height;
108 u16 lfb_depth;
109 u16 lfb_linelength;
110 u32 lfb_base;
111 u32 lfb_size;
112 u8 red_size;
113 u8 red_pos;
114 u8 green_size;
115 u8 green_pos;
116 u8 blue_size;
117 u8 blue_pos;
118 u8 rsvd_size;
119 u8 rsvd_pos;
120};
121
122/* command line: \0 terminated string */
123#define ATAG_CMDLINE 0x54410009
124
125struct tag_cmdline {
126 char cmdline[1]; /* this is the minimum size */
127};
128
129/* acorn RiscPC specific information */
130#define ATAG_ACORN 0x41000101
131
132struct tag_acorn {
133 u32 memc_control_reg;
134 u32 vram_pages;
135 u8 sounddefault;
136 u8 adfsdrives;
137};
138
139/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
140#define ATAG_MEMCLK 0x41000402
141
142struct tag_memclk {
143 u32 fmemclk;
144};
145
146struct tag {
147 struct tag_header hdr;
148 union {
149 struct tag_core core;
150 struct tag_mem32 mem;
151 struct tag_videotext videotext;
152 struct tag_ramdisk ramdisk;
153 struct tag_initrd initrd;
154 struct tag_serialnr serialnr;
155 struct tag_revision revision;
156 struct tag_videolfb videolfb;
157 struct tag_cmdline cmdline;
158
159 /*
160 * Acorn specific
161 */
162 struct tag_acorn acorn;
163
164 /*
165 * DC21285 specific
166 */
167 struct tag_memclk memclk;
168 } u;
169};
170
171struct tagtable {
172 u32 tag;
173 int (*parse)(const struct tag *);
174};
175
176#define __tag __used __attribute__((__section__(".taglist")))
177#define __tagtable(tag, fn) \
178static struct tagtable __tagtable_##fn __tag = { tag, fn }
179
180#define tag_member_present(tag,member) \
181 ((unsigned long)(&((struct tag *)0L)->member + 1) \
182 <= (tag)->hdr.size * 4)
183
184#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
185#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
186
187#define for_each_tag(t,base) \
188 for (t = base; t->hdr.size; t = tag_next(t))
189
190/*
191 * Memory map description
192 */
193#define NR_BANKS 8
194
195struct meminfo {
196 int nr_banks;
197 unsigned long end;
198 struct {
199 unsigned long start;
200 unsigned long size;
201 int node;
202 } bank[NR_BANKS];
203};
204
205extern struct meminfo meminfo;
206
207#endif /* __KERNEL__ */
208
209#endif
diff --git a/include/asm-arm26/shmbuf.h b/include/asm-arm26/shmbuf.h
deleted file mode 100644
index 2e5c67ba1c97..000000000000
--- a/include/asm-arm26/shmbuf.h
+++ /dev/null
@@ -1,42 +0,0 @@
1#ifndef _ASMARM_SHMBUF_H
2#define _ASMARM_SHMBUF_H
3
4/*
5 * The shmid64_ds structure for arm architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space is left for:
10 * - 64-bit time_t to solve y2038 problem
11 * - 2 miscellaneous 32-bit values
12 */
13
14struct shmid64_ds {
15 struct ipc64_perm shm_perm; /* operation perms */
16 size_t shm_segsz; /* size of segment (bytes) */
17 __kernel_time_t shm_atime; /* last attach time */
18 unsigned long __unused1;
19 __kernel_time_t shm_dtime; /* last detach time */
20 unsigned long __unused2;
21 __kernel_time_t shm_ctime; /* last change time */
22 unsigned long __unused3;
23 __kernel_pid_t shm_cpid; /* pid of creator */
24 __kernel_pid_t shm_lpid; /* pid of last operator */
25 unsigned long shm_nattch; /* no. of current attaches */
26 unsigned long __unused4;
27 unsigned long __unused5;
28};
29
30struct shminfo64 {
31 unsigned long shmmax;
32 unsigned long shmmin;
33 unsigned long shmmni;
34 unsigned long shmseg;
35 unsigned long shmall;
36 unsigned long __unused1;
37 unsigned long __unused2;
38 unsigned long __unused3;
39 unsigned long __unused4;
40};
41
42#endif /* _ASMARM_SHMBUF_H */
diff --git a/include/asm-arm26/shmparam.h b/include/asm-arm26/shmparam.h
deleted file mode 100644
index d3748686631e..000000000000
--- a/include/asm-arm26/shmparam.h
+++ /dev/null
@@ -1,15 +0,0 @@
1#ifndef _ASMARM_SHMPARAM_H
2#define _ASMARM_SHMPARAM_H
3
4#ifndef SHMMAX
5#define SHMMAX 0x003fa000
6#endif
7
8/*
9 * This should be the size of the virtually indexed cache/ways,
10 * or page size, whichever is greater since the cache aliases
11 * every size/ways bytes.
12 */
13#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
14
15#endif /* _ASMARM_SHMPARAM_H */
diff --git a/include/asm-arm26/sigcontext.h b/include/asm-arm26/sigcontext.h
deleted file mode 100644
index 013ad2074fc7..000000000000
--- a/include/asm-arm26/sigcontext.h
+++ /dev/null
@@ -1,33 +0,0 @@
1#ifndef _ASMARM_SIGCONTEXT_H
2#define _ASMARM_SIGCONTEXT_H
3
4/*
5 * Signal context structure - contains all info to do with the state
6 * before the signal handler was invoked. Note: only add new entries
7 * to the end of the structure.
8 */
9struct sigcontext {
10 unsigned long trap_no;
11 unsigned long error_code;
12 unsigned long oldmask;
13 unsigned long arm_r0;
14 unsigned long arm_r1;
15 unsigned long arm_r2;
16 unsigned long arm_r3;
17 unsigned long arm_r4;
18 unsigned long arm_r5;
19 unsigned long arm_r6;
20 unsigned long arm_r7;
21 unsigned long arm_r8;
22 unsigned long arm_r9;
23 unsigned long arm_r10;
24 unsigned long arm_fp;
25 unsigned long arm_ip;
26 unsigned long arm_sp;
27 unsigned long arm_lr;
28 unsigned long arm_pc;
29 unsigned long fault_address;
30};
31
32
33#endif
diff --git a/include/asm-arm26/siginfo.h b/include/asm-arm26/siginfo.h
deleted file mode 100644
index 5e21852e6039..000000000000
--- a/include/asm-arm26/siginfo.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASMARM_SIGINFO_H
2#define _ASMARM_SIGINFO_H
3
4#include <asm-generic/siginfo.h>
5
6#endif
diff --git a/include/asm-arm26/signal.h b/include/asm-arm26/signal.h
deleted file mode 100644
index 967ba4947e40..000000000000
--- a/include/asm-arm26/signal.h
+++ /dev/null
@@ -1,176 +0,0 @@
1#ifndef _ASMARM_SIGNAL_H
2#define _ASMARM_SIGNAL_H
3
4#include <linux/types.h>
5
6/* Avoid too many header ordering problems. */
7struct siginfo;
8
9#ifdef __KERNEL__
10/* Most things should be clean enough to redefine this at will, if care
11 is taken to make libc match. */
12
13#define _NSIG 64
14#define _NSIG_BPW 32
15#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
16
17typedef unsigned long old_sigset_t; /* at least 32 bits */
18
19typedef struct {
20 unsigned long sig[_NSIG_WORDS];
21} sigset_t;
22
23#else
24/* Here we must cater to libcs that poke about in kernel headers. */
25
26#define NSIG 32
27typedef unsigned long sigset_t;
28
29#endif /* __KERNEL__ */
30
31#define SIGHUP 1
32#define SIGINT 2
33#define SIGQUIT 3
34#define SIGILL 4
35#define SIGTRAP 5
36#define SIGABRT 6
37#define SIGIOT 6
38#define SIGBUS 7
39#define SIGFPE 8
40#define SIGKILL 9
41#define SIGUSR1 10
42#define SIGSEGV 11
43#define SIGUSR2 12
44#define SIGPIPE 13
45#define SIGALRM 14
46#define SIGTERM 15
47#define SIGSTKFLT 16
48#define SIGCHLD 17
49#define SIGCONT 18
50#define SIGSTOP 19
51#define SIGTSTP 20
52#define SIGTTIN 21
53#define SIGTTOU 22
54#define SIGURG 23
55#define SIGXCPU 24
56#define SIGXFSZ 25
57#define SIGVTALRM 26
58#define SIGPROF 27
59#define SIGWINCH 28
60#define SIGIO 29
61#define SIGPOLL SIGIO
62/*
63#define SIGLOST 29
64*/
65#define SIGPWR 30
66#define SIGSYS 31
67#define SIGUNUSED 31
68
69/* These should not be considered constants from userland. */
70#define SIGRTMIN 32
71#define SIGRTMAX _NSIG
72
73#define SIGSWI 32
74
75/*
76 * SA_FLAGS values:
77 *
78 * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
79 * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
80 * SA_SIGINFO deliver the signal with SIGINFO structs
81 * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
82 * is running in 26-bit.
83 * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
84 * SA_RESTART flag to get restarting signals (which were the default long ago)
85 * SA_NODEFER prevents the current signal from being masked in the handler.
86 * SA_RESETHAND clears the handler when the signal is delivered.
87 *
88 * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
89 * Unix names RESETHAND and NODEFER respectively.
90 */
91#define SA_NOCLDSTOP 0x00000001
92#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
93#define SA_SIGINFO 0x00000004
94#define SA_THIRTYTWO 0x02000000
95#define SA_RESTORER 0x04000000
96#define SA_ONSTACK 0x08000000
97#define SA_RESTART 0x10000000
98#define SA_NODEFER 0x40000000
99#define SA_RESETHAND 0x80000000
100
101#define SA_NOMASK SA_NODEFER
102#define SA_ONESHOT SA_RESETHAND
103
104
105/*
106 * sigaltstack controls
107 */
108#define SS_ONSTACK 1
109#define SS_DISABLE 2
110
111#define MINSIGSTKSZ 2048
112#define SIGSTKSZ 8192
113
114#ifdef __KERNEL__
115#define SA_IRQNOMASK 0x08000000
116#endif
117
118#include <asm-generic/signal.h>
119
120#ifdef __KERNEL__
121struct old_sigaction {
122 __sighandler_t sa_handler;
123 old_sigset_t sa_mask;
124 unsigned long sa_flags;
125 void (*sa_restorer)(void);
126};
127
128struct sigaction {
129 __sighandler_t sa_handler;
130 unsigned long sa_flags;
131 void (*sa_restorer)(void);
132 sigset_t sa_mask; /* mask last for extensibility */
133};
134
135struct k_sigaction {
136 struct sigaction sa;
137};
138
139#else
140/* Here we must cater to libcs that poke about in kernel headers. */
141
142struct sigaction {
143 union {
144 __sighandler_t _sa_handler;
145 void (*_sa_sigaction)(int, struct siginfo *, void *);
146 } _u;
147 sigset_t sa_mask;
148 unsigned long sa_flags;
149 void (*sa_restorer)(void);
150};
151
152#define sa_handler _u._sa_handler
153#define sa_sigaction _u._sa_sigaction
154
155#endif /* __KERNEL__ */
156
157typedef struct sigaltstack {
158 void *ss_sp;
159 int ss_flags;
160 size_t ss_size;
161} stack_t;
162
163#ifdef __KERNEL__
164#include <asm/sigcontext.h>
165
166#define sigmask(sig) (1UL << ((sig) - 1))
167#endif
168
169
170#ifdef __KERNEL__
171#include <asm/sigcontext.h>
172#define ptrace_signal_deliver(regs, cookie) do { } while (0)
173#endif
174
175
176#endif
diff --git a/include/asm-arm26/sizes.h b/include/asm-arm26/sizes.h
deleted file mode 100644
index f8d92ca12040..000000000000
--- a/include/asm-arm26/sizes.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16/* DO NOT EDIT!! - this file automatically generated
17 * from .s file by awk -f s2h.awk
18 */
19/* Size defintions
20 * Copyright (C) ARM Limited 1998. All rights reserved.
21 */
22
23#ifndef __sizes_h
24#define __sizes_h 1
25
26/* handy sizes */
27#define SZ_1K 0x00000400
28#define SZ_4K 0x00001000
29#define SZ_8K 0x00002000
30#define SZ_16K 0x00004000
31#define SZ_64K 0x00010000
32#define SZ_128K 0x00020000
33#define SZ_256K 0x00040000
34#define SZ_512K 0x00080000
35
36#define SZ_1M 0x00100000
37#define SZ_2M 0x00200000
38#define SZ_4M 0x00400000
39#define SZ_8M 0x00800000
40#define SZ_16M 0x01000000
41#define SZ_32M 0x02000000
42#define SZ_64M 0x04000000
43#define SZ_128M 0x08000000
44#define SZ_256M 0x10000000
45#define SZ_512M 0x20000000
46
47#define SZ_1G 0x40000000
48#define SZ_2G 0x80000000
49
50#endif
51
52/* END */
diff --git a/include/asm-arm26/smp.h b/include/asm-arm26/smp.h
deleted file mode 100644
index 38349ec8b61b..000000000000
--- a/include/asm-arm26/smp.h
+++ /dev/null
@@ -1,9 +0,0 @@
1#ifndef __ASM_SMP_H
2#define __ASM_SMP_H
3
4
5#ifdef CONFIG_SMP
6#error SMP not supported
7#endif
8
9#endif
diff --git a/include/asm-arm26/socket.h b/include/asm-arm26/socket.h
deleted file mode 100644
index 65a1a64bf934..000000000000
--- a/include/asm-arm26/socket.h
+++ /dev/null
@@ -1,55 +0,0 @@
1#ifndef _ASMARM_SOCKET_H
2#define _ASMARM_SOCKET_H
3
4#include <asm/sockios.h>
5
6/* For setsockopt(2) */
7#define SOL_SOCKET 1
8
9#define SO_DEBUG 1
10#define SO_REUSEADDR 2
11#define SO_TYPE 3
12#define SO_ERROR 4
13#define SO_DONTROUTE 5
14#define SO_BROADCAST 6
15#define SO_SNDBUF 7
16#define SO_RCVBUF 8
17#define SO_SNDBUFFORCE 32
18#define SO_RCVBUFFORCE 33
19#define SO_KEEPALIVE 9
20#define SO_OOBINLINE 10
21#define SO_NO_CHECK 11
22#define SO_PRIORITY 12
23#define SO_LINGER 13
24#define SO_BSDCOMPAT 14
25/* To add :#define SO_REUSEPORT 15 */
26#define SO_PASSCRED 16
27#define SO_PEERCRED 17
28#define SO_RCVLOWAT 18
29#define SO_SNDLOWAT 19
30#define SO_RCVTIMEO 20
31#define SO_SNDTIMEO 21
32
33/* Security levels - as per NRL IPv6 - don't actually do anything */
34#define SO_SECURITY_AUTHENTICATION 22
35#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
36#define SO_SECURITY_ENCRYPTION_NETWORK 24
37
38#define SO_BINDTODEVICE 25
39
40/* Socket filtering */
41#define SO_ATTACH_FILTER 26
42#define SO_DETACH_FILTER 27
43
44#define SO_PEERNAME 28
45#define SO_TIMESTAMP 29
46#define SCM_TIMESTAMP SO_TIMESTAMP
47
48#define SO_ACCEPTCONN 30
49
50#define SO_PEERSEC 31
51#define SO_PASSSEC 34
52#define SO_TIMESTAMPNS 35
53#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
54
55#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-arm26/sockios.h b/include/asm-arm26/sockios.h
deleted file mode 100644
index a2588a2512df..000000000000
--- a/include/asm-arm26/sockios.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef __ARCH_ARM_SOCKIOS_H
2#define __ARCH_ARM_SOCKIOS_H
3
4/* Socket-level I/O control calls. */
5#define FIOSETOWN 0x8901
6#define SIOCSPGRP 0x8902
7#define FIOGETOWN 0x8903
8#define SIOCGPGRP 0x8904
9#define SIOCATMARK 0x8905
10#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
11#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
12
13#endif
diff --git a/include/asm-arm26/spinlock.h b/include/asm-arm26/spinlock.h
deleted file mode 100644
index e92e81deb4fd..000000000000
--- a/include/asm-arm26/spinlock.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __ASM_SPINLOCK_H
2#define __ASM_SPINLOCK_H
3
4#error ARM architecture does not support SMP spin locks
5
6#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-arm26/stat.h b/include/asm-arm26/stat.h
deleted file mode 100644
index e4abc4fa0850..000000000000
--- a/include/asm-arm26/stat.h
+++ /dev/null
@@ -1,77 +0,0 @@
1#ifndef _ASMARM_STAT_H
2#define _ASMARM_STAT_H
3
4struct __old_kernel_stat {
5 unsigned short st_dev;
6 unsigned short st_ino;
7 unsigned short st_mode;
8 unsigned short st_nlink;
9 unsigned short st_uid;
10 unsigned short st_gid;
11 unsigned short st_rdev;
12 unsigned long st_size;
13 unsigned long st_atime;
14 unsigned long st_mtime;
15 unsigned long st_ctime;
16};
17
18struct stat {
19 unsigned short st_dev;
20 unsigned short __pad1;
21 unsigned long st_ino;
22 unsigned short st_mode;
23 unsigned short st_nlink;
24 unsigned short st_uid;
25 unsigned short st_gid;
26 unsigned short st_rdev;
27 unsigned short __pad2;
28 unsigned long st_size;
29 unsigned long st_blksize;
30 unsigned long st_blocks;
31 unsigned long st_atime;
32 unsigned long st_atime_nsec;
33 unsigned long st_mtime;
34 unsigned long st_mtime_nsec;
35 unsigned long st_ctime;
36 unsigned long st_ctime_nsec;
37 unsigned long __unused4;
38 unsigned long __unused5;
39};
40
41/* This matches struct stat64 in glibc2.1, hence the absolutely
42 * insane amounts of padding around dev_t's.
43 */
44struct stat64 {
45 unsigned long long st_dev;
46 unsigned char __pad0[4];
47
48#define STAT64_HAS_BROKEN_ST_INO 1
49 unsigned long __st_ino;
50 unsigned int st_mode;
51 unsigned int st_nlink;
52
53 unsigned long st_uid;
54 unsigned long st_gid;
55
56 unsigned long long st_rdev;
57 unsigned char __pad3[4];
58
59 long long st_size;
60 unsigned long st_blksize;
61
62 unsigned long st_blocks; /* Number 512-byte blocks allocated. */
63 unsigned long __pad4; /* Future possible st_blocks hi bits */
64
65 unsigned long st_atime;
66 unsigned long st_atime_nsec;
67
68 unsigned long st_mtime;
69 unsigned long st_mtime_nsec;
70
71 unsigned long st_ctime;
72 unsigned long st_ctime_nsec;
73
74 unsigned long long st_ino;
75};
76
77#endif
diff --git a/include/asm-arm26/statfs.h b/include/asm-arm26/statfs.h
deleted file mode 100644
index 776dbc8f7623..000000000000
--- a/include/asm-arm26/statfs.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef _ASMARM_STATFS_H
2#define _ASMARM_STATFS_H
3
4//FIXME - this may not be appropriate for arm26. check it out.
5
6#include <asm-generic/statfs.h>
7
8#endif
diff --git a/include/asm-arm26/string.h b/include/asm-arm26/string.h
deleted file mode 100644
index 2a8ab162412f..000000000000
--- a/include/asm-arm26/string.h
+++ /dev/null
@@ -1,43 +0,0 @@
1#ifndef __ASM_ARM_STRING_H
2#define __ASM_ARM_STRING_H
3
4/*
5 * We don't do inline string functions, since the
6 * optimised inline asm versions are not small.
7 */
8
9#define __HAVE_ARCH_STRRCHR
10extern char * strrchr(const char * s, int c);
11
12#define __HAVE_ARCH_STRCHR
13extern char * strchr(const char * s, int c);
14
15#define __HAVE_ARCH_MEMCPY
16extern void * memcpy(void *, const void *, __kernel_size_t);
17
18#define __HAVE_ARCH_MEMMOVE
19extern void * memmove(void *, const void *, __kernel_size_t);
20
21#define __HAVE_ARCH_MEMCHR
22extern void * memchr(const void *, int, __kernel_size_t);
23
24#define __HAVE_ARCH_MEMZERO
25#define __HAVE_ARCH_MEMSET
26extern void * memset(void *, int, __kernel_size_t);
27
28extern void __memzero(void *ptr, __kernel_size_t n);
29
30#define memset(p,v,n) \
31 ({ \
32 if ((n) != 0) { \
33 if (__builtin_constant_p((v)) && (v) == 0) \
34 __memzero((p),(n)); \
35 else \
36 memset((p),(v),(n)); \
37 } \
38 (p); \
39 })
40
41#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); })
42
43#endif
diff --git a/include/asm-arm26/suspend.h b/include/asm-arm26/suspend.h
deleted file mode 100644
index 5e4c1cc0c19d..000000000000
--- a/include/asm-arm26/suspend.h
+++ /dev/null
@@ -1,4 +0,0 @@
1#ifdef _ASMARM_SUSPEND_H
2#define _ASMARM_SUSPEND_H
3
4#endif
diff --git a/include/asm-arm26/sysirq.h b/include/asm-arm26/sysirq.h
deleted file mode 100644
index 81dca90d9a3f..000000000000
--- a/include/asm-arm26/sysirq.h
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * linux/include/asm-arm/arch-arc/irqs.h
3 *
4 * Copyright (C) 1996 Russell King, Dave Gilbert
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Modifications:
11 * 04-04-1998 PJB Merged arc and a5k versions
12 */
13
14
15#if defined(CONFIG_ARCH_A5K)
16#define IRQ_PRINTER 0
17#define IRQ_BATLOW 1
18#define IRQ_FLOPPYINDEX 2
19#define IRQ_FLOPPYDISK 12
20#elif defined(CONFIG_ARCH_ARC)
21#define IRQ_PRINTERBUSY 0
22#define IRQ_SERIALRING 1
23#define IRQ_PRINTERACK 2
24#define IRQ_FLOPPYCHANGED 12
25#endif
26
27#define IRQ_VSYNCPULSE 3
28#define IRQ_POWERON 4
29#define IRQ_TIMER0 5
30#define IRQ_TIMER1 6
31#define IRQ_IMMEDIATE 7
32#define IRQ_EXPCARDFIQ 8
33#define IRQ_SOUNDCHANGE 9
34#define IRQ_SERIALPORT 10
35#define IRQ_HARDDISK 11
36#define IRQ_EXPANSIONCARD 13
37#define IRQ_KEYBOARDTX 14
38#define IRQ_KEYBOARDRX 15
39
40#if defined(CONFIG_ARCH_A5K)
41#define FIQ_SERIALPORT 4
42#elif defined(CONFIG_ARCH_ARC)
43#define FIQ_FLOPPYIRQ 1
44#define FIQ_FD1772 FIQ_FLOPPYIRQ
45#endif
46
47#define FIQ_FLOPPYDATA 0
48#define FIQ_ECONET 2
49#define FIQ_EXPANSIONCARD 6
50#define FIQ_FORCE 7
51
52#define IRQ_TIMER IRQ_TIMER0
53
54/*
55 * This is the offset of the FIQ "IRQ" numbers
56 */
57#define FIQ_START 64
58
59#define irq_cannonicalize(i) (i)
60
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
deleted file mode 100644
index e09da5ff1f54..000000000000
--- a/include/asm-arm26/system.h
+++ /dev/null
@@ -1,247 +0,0 @@
1#ifndef __ASM_ARM_SYSTEM_H
2#define __ASM_ARM_SYSTEM_H
3
4#ifdef __KERNEL__
5
6
7/*
8 * This is used to ensure the compiler did actually allocate the register we
9 * asked it for some inline assembly sequences. Apparently we can't trust
10 * the compiler from one version to another so a bit of paranoia won't hurt.
11 * This string is meant to be concatenated with the inline asm string and
12 * will cause compilation to stop on mismatch. (From ARM32 - may come in handy)
13 */
14#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
15
16#ifndef __ASSEMBLY__
17
18#include <linux/linkage.h>
19
20struct thread_info;
21struct task_struct;
22
23#if 0
24/* information about the system we're running on */
25extern unsigned int system_rev;
26extern unsigned int system_serial_low;
27extern unsigned int system_serial_high;
28extern unsigned int mem_fclk_21285;
29
30FIXME - sort this
31/*
32 * We need to turn the caches off before calling the reset vector - RiscOS
33 * messes up if we don't
34 */
35#define proc_hard_reset() cpu_proc_fin()
36
37#endif
38
39struct pt_regs;
40
41void die(const char *msg, struct pt_regs *regs, int err)
42 __attribute__((noreturn));
43
44void die_if_kernel(const char *str, struct pt_regs *regs, int err);
45
46void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
47 struct pt_regs *),
48 int sig, const char *name);
49
50#include <asm/proc-fns.h>
51
52#define xchg(ptr,x) \
53 ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
54
55extern asmlinkage void __backtrace(void);
56
57#define set_cr(x) \
58 __asm__ __volatile__( \
59 "mcr p15, 0, %0, c1, c0, 0 @ set CR" \
60 : : "r" (x) : "cc")
61
62#define get_cr() \
63 ({ \
64 unsigned int __val; \
65 __asm__ __volatile__( \
66 "mrc p15, 0, %0, c1, c0, 0 @ get CR" \
67 : "=r" (__val) : : "cc"); \
68 __val; \
69 })
70
71extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
72extern unsigned long cr_alignment; /* defined in entry-armv.S */
73
74#define UDBG_UNDEFINED (1 << 0)
75#define UDBG_SYSCALL (1 << 1)
76#define UDBG_BADABORT (1 << 2)
77#define UDBG_SEGV (1 << 3)
78#define UDBG_BUS (1 << 4)
79
80extern unsigned int user_debug;
81
82#define vectors_base() (0)
83
84#define mb() __asm__ __volatile__ ("" : : : "memory")
85#define rmb() mb()
86#define wmb() mb()
87#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
88
89#define read_barrier_depends() do { } while(0)
90#define set_mb(var, value) do { var = value; mb(); } while (0)
91
92/*
93 * We assume knowledge of how
94 * spin_unlock_irq() and friends are implemented. This avoids
95 * us needlessly decrementing and incrementing the preempt count.
96 */
97#define prepare_arch_switch(next) local_irq_enable()
98#define finish_arch_switch(prev) spin_unlock(&(rq)->lock)
99
100/*
101 * switch_to(prev, next) should switch from task `prev' to `next'
102 * `prev' will never be the same as `next'. schedule() itself
103 * contains the memory barrier to tell GCC not to cache `current'.
104 */
105extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
106
107#define switch_to(prev,next,last) \
108do { \
109 last = __switch_to(prev,task_thread_info(prev),task_thread_info(next)); \
110} while (0)
111
112/*
113 * Save the current interrupt enable state & disable IRQs
114 */
115#define local_irq_save(x) \
116 do { \
117 unsigned long temp; \
118 __asm__ __volatile__( \
119" mov %0, pc @ save_flags_cli\n" \
120" orr %1, %0, #0x08000000\n" \
121" and %0, %0, #0x0c000000\n" \
122" teqp %1, #0\n" \
123 : "=r" (x), "=r" (temp) \
124 : \
125 : "memory"); \
126 } while (0)
127
128/*
129 * Enable IRQs (sti)
130 */
131#define local_irq_enable() \
132 do { \
133 unsigned long temp; \
134 __asm__ __volatile__( \
135" mov %0, pc @ sti\n" \
136" bic %0, %0, #0x08000000\n" \
137" teqp %0, #0\n" \
138 : "=r" (temp) \
139 : \
140 : "memory"); \
141 } while(0)
142
143/*
144 * Disable IRQs (cli)
145 */
146#define local_irq_disable() \
147 do { \
148 unsigned long temp; \
149 __asm__ __volatile__( \
150" mov %0, pc @ cli\n" \
151" orr %0, %0, #0x08000000\n" \
152" teqp %0, #0\n" \
153 : "=r" (temp) \
154 : \
155 : "memory"); \
156 } while(0)
157
158/* Enable FIQs (stf) */
159
160#define __stf() do { \
161 unsigned long temp; \
162 __asm__ __volatile__( \
163" mov %0, pc @ stf\n" \
164" bic %0, %0, #0x04000000\n" \
165" teqp %0, #0\n" \
166 : "=r" (temp)); \
167 } while(0)
168
169/* Disable FIQs (clf) */
170
171#define __clf() do { \
172 unsigned long temp; \
173 __asm__ __volatile__( \
174" mov %0, pc @ clf\n" \
175" orr %0, %0, #0x04000000\n" \
176" teqp %0, #0\n" \
177 : "=r" (temp)); \
178 } while(0)
179
180
181/*
182 * Save the current interrupt enable state.
183 */
184#define local_save_flags(x) \
185 do { \
186 __asm__ __volatile__( \
187" mov %0, pc @ save_flags\n" \
188" and %0, %0, #0x0c000000\n" \
189 : "=r" (x)); \
190 } while (0)
191
192
193/*
194 * restore saved IRQ & FIQ state
195 */
196#define local_irq_restore(x) \
197 do { \
198 unsigned long temp; \
199 __asm__ __volatile__( \
200" mov %0, pc @ restore_flags\n" \
201" bic %0, %0, #0x0c000000\n" \
202" orr %0, %0, %1\n" \
203" teqp %0, #0\n" \
204 : "=&r" (temp) \
205 : "r" (x) \
206 : "memory"); \
207 } while (0)
208
209
210#ifdef CONFIG_SMP
211#error SMP not supported
212#endif
213
214#define smp_mb() barrier()
215#define smp_rmb() barrier()
216#define smp_wmb() barrier()
217#define smp_read_barrier_depends() do { } while(0)
218
219#define clf() __clf()
220#define stf() __stf()
221
222#define irqs_disabled() \
223({ \
224 unsigned long flags; \
225 local_save_flags(flags); \
226 flags & PSR_I_BIT; \
227})
228
229static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
230{
231 extern void __bad_xchg(volatile void *, int);
232
233 switch (size) {
234 case 1: return cpu_xchg_1(x, ptr);
235 case 4: return cpu_xchg_4(x, ptr);
236 default: __bad_xchg(ptr, size);
237 }
238 return 0;
239}
240
241#endif /* __ASSEMBLY__ */
242
243#define arch_align_stack(x) (x)
244
245#endif /* __KERNEL__ */
246
247#endif
diff --git a/include/asm-arm26/termbits.h b/include/asm-arm26/termbits.h
deleted file mode 100644
index 48d2f5c7bcb8..000000000000
--- a/include/asm-arm26/termbits.h
+++ /dev/null
@@ -1,196 +0,0 @@
1#ifndef __ASM_ARM_TERMBITS_H
2#define __ASM_ARM_TERMBITS_H
3
4typedef unsigned char cc_t;
5typedef unsigned int speed_t;
6typedef unsigned int tcflag_t;
7
8#define NCCS 19
9struct termios {
10 tcflag_t c_iflag; /* input mode flags */
11 tcflag_t c_oflag; /* output mode flags */
12 tcflag_t c_cflag; /* control mode flags */
13 tcflag_t c_lflag; /* local mode flags */
14 cc_t c_line; /* line discipline */
15 cc_t c_cc[NCCS]; /* control characters */
16};
17
18struct termios2 {
19 tcflag_t c_iflag; /* input mode flags */
20 tcflag_t c_oflag; /* output mode flags */
21 tcflag_t c_cflag; /* control mode flags */
22 tcflag_t c_lflag; /* local mode flags */
23 cc_t c_line; /* line discipline */
24 cc_t c_cc[NCCS]; /* control characters */
25 speed_t c_ispeed; /* input speed */
26 speed_t c_ospeed; /* output speed */
27};
28
29struct ktermios {
30 tcflag_t c_iflag; /* input mode flags */
31 tcflag_t c_oflag; /* output mode flags */
32 tcflag_t c_cflag; /* control mode flags */
33 tcflag_t c_lflag; /* local mode flags */
34 cc_t c_line; /* line discipline */
35 cc_t c_cc[NCCS]; /* control characters */
36 speed_t c_ispeed; /* input speed */
37 speed_t c_ospeed; /* output speed */
38};
39
40/* c_cc characters */
41#define VINTR 0
42#define VQUIT 1
43#define VERASE 2
44#define VKILL 3
45#define VEOF 4
46#define VTIME 5
47#define VMIN 6
48#define VSWTC 7
49#define VSTART 8
50#define VSTOP 9
51#define VSUSP 10
52#define VEOL 11
53#define VREPRINT 12
54#define VDISCARD 13
55#define VWERASE 14
56#define VLNEXT 15
57#define VEOL2 16
58
59/* c_iflag bits */
60#define IGNBRK 0000001
61#define BRKINT 0000002
62#define IGNPAR 0000004
63#define PARMRK 0000010
64#define INPCK 0000020
65#define ISTRIP 0000040
66#define INLCR 0000100
67#define IGNCR 0000200
68#define ICRNL 0000400
69#define IUCLC 0001000
70#define IXON 0002000
71#define IXANY 0004000
72#define IXOFF 0010000
73#define IMAXBEL 0020000
74#define IUTF8 0040000
75
76/* c_oflag bits */
77#define OPOST 0000001
78#define OLCUC 0000002
79#define ONLCR 0000004
80#define OCRNL 0000010
81#define ONOCR 0000020
82#define ONLRET 0000040
83#define OFILL 0000100
84#define OFDEL 0000200
85#define NLDLY 0000400
86#define NL0 0000000
87#define NL1 0000400
88#define CRDLY 0003000
89#define CR0 0000000
90#define CR1 0001000
91#define CR2 0002000
92#define CR3 0003000
93#define TABDLY 0014000
94#define TAB0 0000000
95#define TAB1 0004000
96#define TAB2 0010000
97#define TAB3 0014000
98#define XTABS 0014000
99#define BSDLY 0020000
100#define BS0 0000000
101#define BS1 0020000
102#define VTDLY 0040000
103#define VT0 0000000
104#define VT1 0040000
105#define FFDLY 0100000
106#define FF0 0000000
107#define FF1 0100000
108
109/* c_cflag bit meaning */
110#define CBAUD 0010017
111#define B0 0000000 /* hang up */
112#define B50 0000001
113#define B75 0000002
114#define B110 0000003
115#define B134 0000004
116#define B150 0000005
117#define B200 0000006
118#define B300 0000007
119#define B600 0000010
120#define B1200 0000011
121#define B1800 0000012
122#define B2400 0000013
123#define B4800 0000014
124#define B9600 0000015
125#define B19200 0000016
126#define B38400 0000017
127#define EXTA B19200
128#define EXTB B38400
129#define CSIZE 0000060
130#define CS5 0000000
131#define CS6 0000020
132#define CS7 0000040
133#define CS8 0000060
134#define CSTOPB 0000100
135#define CREAD 0000200
136#define PARENB 0000400
137#define PARODD 0001000
138#define HUPCL 0002000
139#define CLOCAL 0004000
140#define CBAUDEX 0010000
141#define BOTHER 0010000
142#define B57600 0010001
143#define B115200 0010002
144#define B230400 0010003
145#define B460800 0010004
146#define B500000 0010005
147#define B576000 0010006
148#define B921600 0010007
149#define B1000000 0010010
150#define B1152000 0010011
151#define B1500000 0010012
152#define B2000000 0010013
153#define B2500000 0010014
154#define B3000000 0010015
155#define B3500000 0010016
156#define B4000000 0010017
157#define CIBAUD 002003600000 /* input baud rate */
158#define CMSPAR 010000000000 /* mark or space (stick) parity */
159#define CRTSCTS 020000000000 /* flow control */
160
161#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
162
163/* c_lflag bits */
164#define ISIG 0000001
165#define ICANON 0000002
166#define XCASE 0000004
167#define ECHO 0000010
168#define ECHOE 0000020
169#define ECHOK 0000040
170#define ECHONL 0000100
171#define NOFLSH 0000200
172#define TOSTOP 0000400
173#define ECHOCTL 0001000
174#define ECHOPRT 0002000
175#define ECHOKE 0004000
176#define FLUSHO 0010000
177#define PENDIN 0040000
178#define IEXTEN 0100000
179
180/* tcflow() and TCXONC use these */
181#define TCOOFF 0
182#define TCOON 1
183#define TCIOFF 2
184#define TCION 3
185
186/* tcflush() and TCFLSH use these */
187#define TCIFLUSH 0
188#define TCOFLUSH 1
189#define TCIOFLUSH 2
190
191/* tcsetattr uses these */
192#define TCSANOW 0
193#define TCSADRAIN 1
194#define TCSAFLUSH 2
195
196#endif /* __ASM_ARM_TERMBITS_H */
diff --git a/include/asm-arm26/termios.h b/include/asm-arm26/termios.h
deleted file mode 100644
index 293e3f1bc3f2..000000000000
--- a/include/asm-arm26/termios.h
+++ /dev/null
@@ -1,92 +0,0 @@
1#ifndef __ASM_ARM_TERMIOS_H
2#define __ASM_ARM_TERMIOS_H
3
4#include <asm/termbits.h>
5#include <asm/ioctls.h>
6
7struct winsize {
8 unsigned short ws_row;
9 unsigned short ws_col;
10 unsigned short ws_xpixel;
11 unsigned short ws_ypixel;
12};
13
14#define NCC 8
15struct termio {
16 unsigned short c_iflag; /* input mode flags */
17 unsigned short c_oflag; /* output mode flags */
18 unsigned short c_cflag; /* control mode flags */
19 unsigned short c_lflag; /* local mode flags */
20 unsigned char c_line; /* line discipline */
21 unsigned char c_cc[NCC]; /* control characters */
22};
23
24#ifdef __KERNEL__
25/* intr=^C quit=^| erase=del kill=^U
26 eof=^D vtime=\0 vmin=\1 sxtc=\0
27 start=^Q stop=^S susp=^Z eol=\0
28 reprint=^R discard=^U werase=^W lnext=^V
29 eol2=\0
30*/
31#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
32#endif
33
34/* modem lines */
35#define TIOCM_LE 0x001
36#define TIOCM_DTR 0x002
37#define TIOCM_RTS 0x004
38#define TIOCM_ST 0x008
39#define TIOCM_SR 0x010
40#define TIOCM_CTS 0x020
41#define TIOCM_CAR 0x040
42#define TIOCM_RNG 0x080
43#define TIOCM_DSR 0x100
44#define TIOCM_CD TIOCM_CAR
45#define TIOCM_RI TIOCM_RNG
46#define TIOCM_OUT1 0x2000
47#define TIOCM_OUT2 0x4000
48#define TIOCM_LOOP 0x8000
49
50/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
51
52#ifdef __KERNEL__
53
54/*
55 * Translate a "termio" structure into a "termios". Ugh.
56 */
57#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
58 unsigned short __tmp; \
59 get_user(__tmp,&(termio)->x); \
60 *(unsigned short *) &(termios)->x = __tmp; \
61}
62
63#define user_termio_to_kernel_termios(termios, termio) \
64({ \
65 SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
66 SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
67 SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
68 SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
69 copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
70})
71
72/*
73 * Translate a "termios" structure into a "termio". Ugh.
74 */
75#define kernel_termios_to_user_termio(termio, termios) \
76({ \
77 put_user((termios)->c_iflag, &(termio)->c_iflag); \
78 put_user((termios)->c_oflag, &(termio)->c_oflag); \
79 put_user((termios)->c_cflag, &(termio)->c_cflag); \
80 put_user((termios)->c_lflag, &(termio)->c_lflag); \
81 put_user((termios)->c_line, &(termio)->c_line); \
82 copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
83})
84
85#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
86#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
87#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
88#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
89
90#endif /* __KERNEL__ */
91
92#endif /* __ASM_ARM_TERMIOS_H */
diff --git a/include/asm-arm26/thread_info.h b/include/asm-arm26/thread_info.h
deleted file mode 100644
index f9b5c09b560f..000000000000
--- a/include/asm-arm26/thread_info.h
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * linux/include/asm-arm26/thread_info.h
3 *
4 * Copyright (C) 2002 Russell King.
5 * Copyright (C) 2003 Ian Molton.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef __ASM_ARM_THREAD_INFO_H
12#define __ASM_ARM_THREAD_INFO_H
13
14#ifdef __KERNEL__
15
16#ifndef __ASSEMBLY__
17
18struct task_struct;
19struct exec_domain;
20
21#include <linux/compiler.h>
22#include <asm/fpstate.h>
23#include <asm/ptrace.h>
24#include <asm/types.h>
25
26typedef unsigned long mm_segment_t;
27
28struct cpu_context_save {
29 __u32 r4;
30 __u32 r5;
31 __u32 r6;
32 __u32 r7;
33 __u32 r8;
34 __u32 r9;
35 __u32 sl;
36 __u32 fp;
37 __u32 sp;
38 __u32 pc;
39};
40
41/*
42 * low level task data that entry.S needs immediate access to.
43 * We assume cpu_context follows immedately after cpu_domain.
44 */
45struct thread_info {
46 unsigned long flags; /* low level flags */
47 int preempt_count; /* 0 => preemptable, <0 => bug */
48 mm_segment_t addr_limit; /* address limit */
49 struct task_struct *task; /* main task structure */
50 struct exec_domain *exec_domain; /* execution domain */
51 __u32 cpu; /* cpu */
52 struct cpu_context_save cpu_context; /* cpu context */
53 struct restart_block restart_block;
54 union fp_state fpstate;
55};
56
57#define INIT_THREAD_INFO(tsk) \
58{ \
59 .task &tsk, \
60 .exec_domain &default_exec_domain, \
61 .flags 0, \
62 .preempt_count 0, \
63 .addr_limit KERNEL_DS, \
64 .restart_block = { \
65 .fn = do_no_restart_syscall, \
66 }, \
67}
68
69#define init_thread_info (init_thread_union.thread_info)
70#define init_stack (init_thread_union.stack)
71
72/*
73 * how to get the thread information struct from C
74 */
75static inline struct thread_info *current_thread_info(void) __attribute_const__;
76
77static inline struct thread_info *current_thread_info(void)
78{
79 register unsigned long sp asm ("sp");
80 return (struct thread_info *)(sp & ~0x1fff);
81}
82
83#define THREAD_SIZE PAGE_SIZE
84#define task_pt_regs(task) ((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE - 8) - 1)
85
86extern struct thread_info *alloc_thread_info(struct task_struct *task);
87extern void free_thread_info(struct thread_info *);
88
89#define thread_saved_pc(tsk) \
90 ((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc)))
91#define thread_saved_fp(tsk) \
92 ((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
93
94#else /* !__ASSEMBLY__ */
95
96#define TI_FLAGS 0
97#define TI_PREEMPT 4
98#define TI_ADDR_LIMIT 8
99#define TI_TASK 12
100#define TI_EXEC_DOMAIN 16
101#define TI_CPU 20
102#define TI_CPU_SAVE 24
103#define TI_RESTART_BLOCK 28
104#define TI_FPSTATE 68
105
106#endif
107
108#define PREEMPT_ACTIVE 0x04000000
109
110/*
111 * thread information flags:
112 * TIF_SYSCALL_TRACE - syscall trace active
113 * TIF_SIGPENDING - signal pending
114 * TIF_NEED_RESCHED - rescheduling necessary
115 * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
116 * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
117 */
118#define TIF_SIGPENDING 0
119#define TIF_NEED_RESCHED 1
120#define TIF_SYSCALL_TRACE 8
121#define TIF_USED_FPU 16
122#define TIF_POLLING_NRFLAG 17
123#define TIF_MEMDIE 18
124
125#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
126#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
127#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
128#define _TIF_USED_FPU (1 << TIF_USED_FPU)
129#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
130
131/*
132 * Change these and you break ASM code in entry-common.S
133 */
134#define _TIF_WORK_MASK 0x000000ff
135
136#endif /* __KERNEL__ */
137#endif /* __ASM_ARM_THREAD_INFO_H */
diff --git a/include/asm-arm26/timex.h b/include/asm-arm26/timex.h
deleted file mode 100644
index 68322fbc1aed..000000000000
--- a/include/asm-arm26/timex.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/include/asm-arm/timex.h
3 *
4 * Copyright (C) 1997,1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Architecture Specific TIME specifications
11 */
12#ifndef _ASMARM_TIMEX_H
13#define _ASMARM_TIMEX_H
14
15/*
16 * On the RiscPC, the clock ticks at 2MHz.
17 */
18#define CLOCK_TICK_RATE 2000000
19
20/* IS THAT RIGHT ON A5000? FIXME */
21
22typedef unsigned long cycles_t;
23
24static inline cycles_t get_cycles (void)
25{
26 return 0;
27}
28
29#endif
diff --git a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h
deleted file mode 100644
index 08ddd85b8d35..000000000000
--- a/include/asm-arm26/tlb.h
+++ /dev/null
@@ -1,63 +0,0 @@
1#ifndef __ASMARM_TLB_H
2#define __ASMARM_TLB_H
3
4#include <asm/pgalloc.h>
5#include <asm/tlbflush.h>
6
7/*
8 * TLB handling. This allows us to remove pages from the page
9 * tables, and efficiently handle the TLB issues.
10 */
11struct mmu_gather {
12 struct mm_struct *mm;
13 unsigned int need_flush;
14 unsigned int fullmm;
15};
16
17DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
18
19static inline struct mmu_gather *
20tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
21{
22 struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
23
24 tlb->mm = mm;
25 tlb->need_flush = 0;
26 tlb->fullmm = full_mm_flush;
27
28 return tlb;
29}
30
31static inline void
32tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
33{
34 if (tlb->need_flush)
35 flush_tlb_mm(tlb->mm);
36
37 /* keep the page table cache within bounds */
38 check_pgt_cache();
39
40 put_cpu_var(mmu_gathers);
41}
42
43#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
44//#define tlb_start_vma(tlb,vma) do { } while (0)
45//FIXME - ARM32 uses this now that things changed in the kernel. seems like it may be pointless on arm26, however to get things compiling...
46#define tlb_start_vma(tlb,vma) \
47 do { \
48 if (!tlb->fullmm) \
49 flush_cache_range(vma, vma->vm_start, vma->vm_end); \
50 } while (0)
51#define tlb_end_vma(tlb,vma) do { } while (0)
52
53static inline void
54tlb_remove_page(struct mmu_gather *tlb, struct page *page)
55{
56 tlb->need_flush = 1;
57 free_page_and_swap_cache(page);
58}
59
60#define pte_free_tlb(tlb,ptep) pte_free(ptep)
61#define pmd_free_tlb(tlb,pmdp) pmd_free(pmdp)
62
63#endif
diff --git a/include/asm-arm26/tlbflush.h b/include/asm-arm26/tlbflush.h
deleted file mode 100644
index f79c1cbf4f69..000000000000
--- a/include/asm-arm26/tlbflush.h
+++ /dev/null
@@ -1,70 +0,0 @@
1#ifndef __ASMARM_TLBFLUSH_H
2#define __ASMARM_TLBFLUSH_H
3
4/*
5 * TLB flushing:
6 *
7 * - flush_tlb_all() flushes all processes TLBs
8 * - flush_tlb_mm(mm) flushes the specified mm context TLB's
9 * - flush_tlb_page(vma, vmaddr) flushes one page
10 * - flush_tlb_range(vma, start, end) flushes a range of pages
11 */
12
13#define flush_tlb_all() memc_update_all()
14#define flush_tlb_mm(mm) memc_update_mm(mm)
15#define flush_tlb_page(vma, vmaddr) do { printk("flush_tlb_page\n");} while (0) // IS THIS RIGHT?
16#define flush_tlb_range(vma,start,end) \
17 do { memc_update_mm(vma->vm_mm); (void)(start); (void)(end); } while (0)
18#define flush_tlb_pgtables(mm,start,end) do { printk("flush_tlb_pgtables\n");} while (0)
19#define flush_tlb_kernel_range(s,e) do { printk("flush_tlb_range\n");} while (0)
20
21/*
22 * The following handle the weird MEMC chip
23 */
24static inline void memc_update_all(void)
25{
26 struct task_struct *p;
27 cpu_memc_update_all(init_mm.pgd);
28 for_each_process(p) {
29 if (!p->mm)
30 continue;
31 cpu_memc_update_all(p->mm->pgd);
32 }
33 processor._set_pgd(current->active_mm->pgd);
34}
35
36static inline void memc_update_mm(struct mm_struct *mm)
37{
38 cpu_memc_update_all(mm->pgd);
39
40 if (mm == current->active_mm)
41 processor._set_pgd(mm->pgd);
42}
43
44static inline void
45memc_clear(struct mm_struct *mm, struct page *page)
46{
47 cpu_memc_update_entry(mm->pgd, (unsigned long) page_address(page), 0);
48
49 if (mm == current->active_mm)
50 processor._set_pgd(mm->pgd);
51}
52
53static inline void
54memc_update_addr(struct mm_struct *mm, pte_t pte, unsigned long vaddr)
55{
56 cpu_memc_update_entry(mm->pgd, pte_val(pte), vaddr);
57
58 if (mm == current->active_mm)
59 processor._set_pgd(mm->pgd);
60}
61
62static inline void
63update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
64{
65 struct mm_struct *mm = vma->vm_mm;
66printk("update_mmu_cache\n");
67 memc_update_addr(mm, pte, addr);
68}
69
70#endif
diff --git a/include/asm-arm26/topology.h b/include/asm-arm26/topology.h
deleted file mode 100644
index accbd7cad9b5..000000000000
--- a/include/asm-arm26/topology.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASM_ARM_TOPOLOGY_H
2#define _ASM_ARM_TOPOLOGY_H
3
4#include <asm-generic/topology.h>
5
6#endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/include/asm-arm26/types.h b/include/asm-arm26/types.h
deleted file mode 100644
index 81bd357ada02..000000000000
--- a/include/asm-arm26/types.h
+++ /dev/null
@@ -1,59 +0,0 @@
1#ifndef __ASM_ARM_TYPES_H
2#define __ASM_ARM_TYPES_H
3
4#ifndef __ASSEMBLY__
5
6typedef unsigned short umode_t;
7
8/*
9 * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
10 * header files exported to user space
11 */
12
13typedef __signed__ char __s8;
14typedef unsigned char __u8;
15
16typedef __signed__ short __s16;
17typedef unsigned short __u16;
18
19typedef __signed__ int __s32;
20typedef unsigned int __u32;
21
22#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
23typedef __signed__ long long __s64;
24typedef unsigned long long __u64;
25#endif
26
27#endif /* __ASSEMBLY__ */
28
29/*
30 * These aren't exported outside the kernel to avoid name space clashes
31 */
32#ifdef __KERNEL__
33
34#define BITS_PER_LONG 32
35
36#ifndef __ASSEMBLY__
37
38typedef signed char s8;
39typedef unsigned char u8;
40
41typedef signed short s16;
42typedef unsigned short u16;
43
44typedef signed int s32;
45typedef unsigned int u32;
46
47typedef signed long long s64;
48typedef unsigned long long u64;
49
50/* Dma addresses are 32-bits wide. */
51
52typedef u32 dma_addr_t;
53typedef u32 dma64_addr_t;
54
55#endif /* __ASSEMBLY__ */
56
57#endif /* __KERNEL__ */
58
59#endif
diff --git a/include/asm-arm26/uaccess-asm.h b/include/asm-arm26/uaccess-asm.h
deleted file mode 100644
index ade76ec02995..000000000000
--- a/include/asm-arm26/uaccess-asm.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * linux/include/asm-arm/proc-armo/uaccess.h
3 *
4 * Copyright (C) 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11/*
12 * The fs functions are implemented on the ARM2 and ARM3 architectures
13 * manually.
14 * Use *_user functions to access user memory with faulting behaving
15 * as though the user is accessing the memory.
16 * Use set_fs(get_ds()) and then the *_user functions to allow them to
17 * access kernel memory.
18 */
19
20/*
21 * These are the values used to represent the user `fs' and the kernel `ds'
22 * FIXME - the KERNEL_DS should end at 0x03000000 but we want to access ROM at
23 * 0x03400000. ideally we want to forbid access to the IO space inbetween.
24 */
25#define KERNEL_DS 0x03FFFFFF
26#define USER_DS 0x02000000
27
28extern uaccess_t uaccess_user, uaccess_kernel;
29
30static inline void set_fs (mm_segment_t fs)
31{
32 current_thread_info()->addr_limit = fs;
33 current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel);
34}
35
36#define __range_ok(addr,size) ({ \
37 unsigned long flag, roksum; \
38 __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
39 : "=&r" (flag), "=&r" (roksum) \
40 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
41 : "cc"); \
42 flag; })
43
44#define __addr_ok(addr) ({ \
45 unsigned long flag; \
46 __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \
47 : "=&r" (flag) \
48 : "0" (current_thread_info()->addr_limit), "r" (addr) \
49 : "cc"); \
50 (flag == 0); })
51
52#define __put_user_asm_byte(x,addr,err) \
53 __asm__ __volatile__( \
54 " mov r0, %1\n" \
55 " mov r1, %2\n" \
56 " mov r2, %0\n" \
57 " mov lr, pc\n" \
58 " mov pc, %3\n" \
59 " mov %0, r2\n" \
60 : "=r" (err) \
61 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \
62 "0" (err) \
63 : "r0", "r1", "r2", "lr")
64
65#define __put_user_asm_half(x,addr,err) \
66 __asm__ __volatile__( \
67 " mov r0, %1\n" \
68 " mov r1, %2\n" \
69 " mov r2, %0\n" \
70 " mov lr, pc\n" \
71 " mov pc, %3\n" \
72 " mov %0, r2\n" \
73 : "=r" (err) \
74 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \
75 "0" (err) \
76 : "r0", "r1", "r2", "lr")
77
78#define __put_user_asm_word(x,addr,err) \
79 __asm__ __volatile__( \
80 " mov r0, %1\n" \
81 " mov r1, %2\n" \
82 " mov r2, %0\n" \
83 " mov lr, pc\n" \
84 " mov pc, %3\n" \
85 " mov %0, r2\n" \
86 : "=r" (err) \
87 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \
88 "0" (err) \
89 : "r0", "r1", "r2", "lr")
90
91#define __put_user_asm_dword(x,addr,err) \
92 __asm__ __volatile__( \
93 " mov r0, %1\n" \
94 " mov r1, %2\n" \
95 " mov r2, %0\n" \
96 " mov lr, pc\n" \
97 " mov pc, %3\n" \
98 " mov %0, r2\n" \
99 : "=r" (err) \
100 : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_dword), \
101 "0" (err) \
102 : "r0", "r1", "r2", "lr")
103
104#define __get_user_asm_byte(x,addr,err) \
105 __asm__ __volatile__( \
106 " mov r0, %2\n" \
107 " mov r1, %0\n" \
108 " mov lr, pc\n" \
109 " mov pc, %3\n" \
110 " mov %0, r1\n" \
111 " mov %1, r0\n" \
112 : "=r" (err), "=r" (x) \
113 : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \
114 : "r0", "r1", "r2", "lr")
115
116#define __get_user_asm_half(x,addr,err) \
117 __asm__ __volatile__( \
118 " mov r0, %2\n" \
119 " mov r1, %0\n" \
120 " mov lr, pc\n" \
121 " mov pc, %3\n" \
122 " mov %0, r1\n" \
123 " mov %1, r0\n" \
124 : "=r" (err), "=r" (x) \
125 : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \
126 : "r0", "r1", "r2", "lr")
127
128#define __get_user_asm_word(x,addr,err) \
129 __asm__ __volatile__( \
130 " mov r0, %2\n" \
131 " mov r1, %0\n" \
132 " mov lr, pc\n" \
133 " mov pc, %3\n" \
134 " mov %0, r1\n" \
135 " mov %1, r0\n" \
136 : "=r" (err), "=r" (x) \
137 : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \
138 : "r0", "r1", "r2", "lr")
139
140#define __do_copy_from_user(to,from,n) \
141 (n) = current->thread.uaccess->copy_from_user((to),(from),(n))
142
143#define __do_copy_to_user(to,from,n) \
144 (n) = current->thread.uaccess->copy_to_user((to),(from),(n))
145
146#define __do_clear_user(addr,sz) \
147 (sz) = current->thread.uaccess->clear_user((addr),(sz))
148
149#define __do_strncpy_from_user(dst,src,count,res) \
150 (res) = current->thread.uaccess->strncpy_from_user(dst,src,count)
151
152#define __do_strnlen_user(s,n,res) \
153 (res) = current->thread.uaccess->strnlen_user(s,n)
diff --git a/include/asm-arm26/uaccess.h b/include/asm-arm26/uaccess.h
deleted file mode 100644
index d64ed84cb2d3..000000000000
--- a/include/asm-arm26/uaccess.h
+++ /dev/null
@@ -1,293 +0,0 @@
1#ifndef _ASMARM_UACCESS_H
2#define _ASMARM_UACCESS_H
3
4/*
5 * User space memory access functions
6 */
7#include <linux/sched.h>
8#include <asm/errno.h>
9
10#define VERIFY_READ 0
11#define VERIFY_WRITE 1
12
13/*
14 * The exception table consists of pairs of addresses: the first is the
15 * address of an instruction that is allowed to fault, and the second is
16 * the address at which the program should continue. No registers are
17 * modified, so it is entirely up to the continuation code to figure out
18 * what to do.
19 *
20 * All the routines below use bits of fixup code that are out of line
21 * with the main instruction path. This means when everything is well,
22 * we don't even have to jump over them. Further, they do not intrude
23 * on our cache or tlb entries.
24 */
25
26struct exception_table_entry
27{
28 unsigned long insn, fixup;
29};
30
31/* Returns 0 if exception not found and fixup otherwise. */
32extern unsigned long search_exception_table(unsigned long);
33extern int fixup_exception(struct pt_regs *regs);
34
35#define get_ds() (KERNEL_DS)
36#define get_fs() (current_thread_info()->addr_limit)
37#define segment_eq(a,b) ((a) == (b))
38
39#include <asm/uaccess-asm.h>
40
41#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
42
43/*
44 * Single-value transfer routines. They automatically use the right
45 * size if we just have the right pointer type. Note that the functions
46 * which read from user space (*get_*) need to take care not to leak
47 * kernel data even if the calling code is buggy and fails to check
48 * the return value. This means zeroing out the destination variable
49 * or buffer on error. Normally this is done out of line by the
50 * fixup code, but there are a few places where it intrudes on the
51 * main code path. When we only write to user space, there is no
52 * problem.
53 *
54 * The "__xxx" versions of the user access functions do not verify the
55 * address space - it must have been done previously with a separate
56 * "access_ok()" call.
57 *
58 * The "xxx_error" versions set the third argument to EFAULT if an
59 * error occurs, and leave it unchanged on success. Note that these
60 * versions are void (ie, don't return a value as such).
61 */
62
63extern int __get_user_1(void *);
64extern int __get_user_2(void *);
65extern int __get_user_4(void *);
66extern int __get_user_8(void *);
67extern int __get_user_bad(void);
68
69#define __get_user_x(__r1,__p,__e,__s,__i...) \
70 __asm__ __volatile__ ("bl __get_user_" #__s \
71 : "=&r" (__e), "=r" (__r1) \
72 : "0" (__p) \
73 : __i)
74
75#define get_user(x,p) \
76 ({ \
77 register const typeof(*(p)) *__p asm("r0") = (p); \
78 register typeof(*(p)) __r1 asm("r1"); \
79 register int __e asm("r0"); \
80 switch (sizeof(*(p))) { \
81 case 1: \
82 __get_user_x(__r1, __p, __e, 1, "lr"); \
83 break; \
84 case 2: \
85 __get_user_x(__r1, __p, __e, 2, "r2", "lr"); \
86 break; \
87 case 4: \
88 __get_user_x(__r1, __p, __e, 4, "lr"); \
89 break; \
90 case 8: \
91 __get_user_x(__r1, __p, __e, 8, "lr"); \
92 break; \
93 default: __e = __get_user_bad(); break; \
94 } \
95 x = __r1; \
96 __e; \
97 })
98
99
100#define __get_user(x,ptr) \
101({ \
102 long __gu_err = 0; \
103 __get_user_err((x),(ptr),__gu_err); \
104 __gu_err; \
105})
106
107#define __get_user_error(x,ptr,err) \
108({ \
109 __get_user_err((x),(ptr),err); \
110 (void) 0; \
111})
112
113#define __get_user_err(x,ptr,err) \
114do { \
115 unsigned long __gu_addr = (unsigned long)(ptr); \
116 unsigned long __gu_val; \
117 switch (sizeof(*(ptr))) { \
118 case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
119 case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
120 case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \
121 default: (__gu_val) = __get_user_bad(); \
122 } \
123 (x) = (__typeof__(*(ptr)))__gu_val; \
124} while (0)
125
126extern int __put_user_1(void *, unsigned int);
127extern int __put_user_2(void *, unsigned int);
128extern int __put_user_4(void *, unsigned int);
129extern int __put_user_8(void *, unsigned long long);
130extern int __put_user_bad(void);
131
132#define __put_user_x(__r1,__p,__e,__s) \
133 __asm__ __volatile__ ( \
134 __asmeq("%0", "r0") __asmeq("%2", "r1") \
135 "bl __put_user_" #__s \
136 : "=&r" (__e) \
137 : "0" (__p), "r" (__r1) \
138 : "ip", "lr", "cc")
139
140#define put_user(x,p) \
141 ({ \
142 register const typeof(*(p)) __r1 asm("r1") = (x); \
143 register const typeof(*(p)) *__p asm("r0") = (p); \
144 register int __e asm("r0"); \
145 switch (sizeof(*(__p))) { \
146 case 1: \
147 __put_user_x(__r1, __p, __e, 1); \
148 break; \
149 case 2: \
150 __put_user_x(__r1, __p, __e, 2); \
151 break; \
152 case 4: \
153 __put_user_x(__r1, __p, __e, 4); \
154 break; \
155 case 8: \
156 __put_user_x(__r1, __p, __e, 8); \
157 break; \
158 default: __e = __put_user_bad(); break; \
159 } \
160 __e; \
161 })
162
163#if 0
164/********************* OLD METHOD *******************/
165#define __put_user_x(__r1,__p,__e,__s,__i...) \
166 __asm__ __volatile__ ("bl __put_user_" #__s \
167 : "=&r" (__e) \
168 : "0" (__p), "r" (__r1) \
169 : __i)
170
171#define put_user(x,p) \
172 ({ \
173 register const typeof(*(p)) __r1 asm("r1") = (x); \
174 register const typeof(*(p)) *__p asm("r0") = (p); \
175 register int __e asm("r0"); \
176 switch (sizeof(*(p))) { \
177 case 1: \
178 __put_user_x(__r1, __p, __e, 1, "r2", "lr"); \
179 break; \
180 case 2: \
181 __put_user_x(__r1, __p, __e, 2, "r2", "lr"); \
182 break; \
183 case 4: \
184 __put_user_x(__r1, __p, __e, 4, "r2", "lr"); \
185 break; \
186 case 8: \
187 __put_user_x(__r1, __p, __e, 8, "r2", "ip", "lr"); \
188 break; \
189 default: __e = __put_user_bad(); break; \
190 } \
191 __e; \
192 })
193/*************************************************/
194#endif
195
196#define __put_user(x,ptr) \
197({ \
198 long __pu_err = 0; \
199 __put_user_err((x),(ptr),__pu_err); \
200 __pu_err; \
201})
202
203#define __put_user_error(x,ptr,err) \
204({ \
205 __put_user_err((x),(ptr),err); \
206 (void) 0; \
207})
208
209#define __put_user_err(x,ptr,err) \
210do { \
211 unsigned long __pu_addr = (unsigned long)(ptr); \
212 __typeof__(*(ptr)) __pu_val = (x); \
213 switch (sizeof(*(ptr))) { \
214 case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
215 case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
216 case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
217 case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
218 default: __put_user_bad(); \
219 } \
220} while (0)
221
222static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
223{
224 if (access_ok(VERIFY_READ, from, n))
225 __do_copy_from_user(to, from, n);
226 else /* security hole - plug it */
227 memzero(to, n);
228 return n;
229}
230
231static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
232{
233 __do_copy_from_user(to, from, n);
234 return n;
235}
236
237static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
238{
239 if (access_ok(VERIFY_WRITE, to, n))
240 __do_copy_to_user(to, from, n);
241 return n;
242}
243
244static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
245{
246 __do_copy_to_user(to, from, n);
247 return n;
248}
249
250#define __copy_to_user_inatomic __copy_to_user
251#define __copy_from_user_inatomic __copy_from_user
252
253static __inline__ unsigned long clear_user (void *to, unsigned long n)
254{
255 if (access_ok(VERIFY_WRITE, to, n))
256 __do_clear_user(to, n);
257 return n;
258}
259
260static __inline__ unsigned long __clear_user (void *to, unsigned long n)
261{
262 __do_clear_user(to, n);
263 return n;
264}
265
266static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
267{
268 long res = -EFAULT;
269 if (access_ok(VERIFY_READ, src, 1))
270 __do_strncpy_from_user(dst, src, count, res);
271 return res;
272}
273
274static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
275{
276 long res;
277 __do_strncpy_from_user(dst, src, count, res);
278 return res;
279}
280
281#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
282
283static inline long strnlen_user(const char *s, long n)
284{
285 unsigned long res = 0;
286
287 if (__addr_ok(s))
288 __do_strnlen_user(s, n, res);
289
290 return res;
291}
292
293#endif /* _ASMARM_UACCESS_H */
diff --git a/include/asm-arm26/ucontext.h b/include/asm-arm26/ucontext.h
deleted file mode 100644
index f853130137cc..000000000000
--- a/include/asm-arm26/ucontext.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef _ASMARM_UCONTEXT_H
2#define _ASMARM_UCONTEXT_H
3
4struct ucontext {
5 unsigned long uc_flags;
6 struct ucontext *uc_link;
7 stack_t uc_stack;
8 struct sigcontext uc_mcontext;
9 sigset_t uc_sigmask; /* mask last for extensibility */
10};
11
12#endif /* !_ASMARM_UCONTEXT_H */
diff --git a/include/asm-arm26/unaligned.h b/include/asm-arm26/unaligned.h
deleted file mode 100644
index d992782089fd..000000000000
--- a/include/asm-arm26/unaligned.h
+++ /dev/null
@@ -1,118 +0,0 @@
1#ifndef __ASM_ARM_UNALIGNED_H
2#define __ASM_ARM_UNALIGNED_H
3
4#include <asm/types.h>
5
6extern int __bug_unaligned_x(void *ptr);
7
8/*
9 * What is the most efficient way of loading/storing an unaligned value?
10 *
11 * That is the subject of this file. Efficiency here is defined as
12 * minimum code size with minimum register usage for the common cases.
13 * It is currently not believed that long longs are common, so we
14 * trade efficiency for the chars, shorts and longs against the long
15 * longs.
16 *
17 * Current stats with gcc 2.7.2.2 for these functions:
18 *
19 * ptrsize get: code regs put: code regs
20 * 1 1 1 1 2
21 * 2 3 2 3 2
22 * 4 7 3 7 3
23 * 8 20 6 16 6
24 *
25 * gcc 2.95.1 seems to code differently:
26 *
27 * ptrsize get: code regs put: code regs
28 * 1 1 1 1 2
29 * 2 3 2 3 2
30 * 4 7 4 7 4
31 * 8 19 8 15 6
32 *
33 * which may or may not be more efficient (depending upon whether
34 * you can afford the extra registers). Hopefully the gcc 2.95
35 * is inteligent enough to decide if it is better to use the
36 * extra register, but evidence so far seems to suggest otherwise.
37 *
38 * Unfortunately, gcc is not able to optimise the high word
39 * out of long long >> 32, or the low word from long long << 32
40 */
41
42#define __get_unaligned_2_le(__p) \
43 (__p[0] | __p[1] << 8)
44
45#define __get_unaligned_4_le(__p) \
46 (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
47
48#define __get_unaligned_le(ptr) \
49 ({ \
50 __typeof__(*(ptr)) __v; \
51 __u8 *__p = (__u8 *)(ptr); \
52 switch (sizeof(*(ptr))) { \
53 case 1: __v = *(ptr); break; \
54 case 2: __v = __get_unaligned_2_le(__p); break; \
55 case 4: __v = __get_unaligned_4_le(__p); break; \
56 case 8: { \
57 unsigned int __v1, __v2; \
58 __v2 = __get_unaligned_4_le((__p+4)); \
59 __v1 = __get_unaligned_4_le(__p); \
60 __v = ((unsigned long long)__v2 << 32 | __v1); \
61 } \
62 break; \
63 default: __v = __bug_unaligned_x(__p); break; \
64 } \
65 __v; \
66 })
67
68static inline void __put_unaligned_2_le(__u32 __v, register __u8 *__p)
69{
70 *__p++ = __v;
71 *__p++ = __v >> 8;
72}
73
74static inline void __put_unaligned_4_le(__u32 __v, register __u8 *__p)
75{
76 __put_unaligned_2_le(__v >> 16, __p + 2);
77 __put_unaligned_2_le(__v, __p);
78}
79
80static inline void __put_unaligned_8_le(const unsigned long long __v, register __u8 *__p)
81{
82 /*
83 * tradeoff: 8 bytes of stack for all unaligned puts (2
84 * instructions), or an extra register in the long long
85 * case - go for the extra register.
86 */
87 __put_unaligned_4_le(__v >> 32, __p+4);
88 __put_unaligned_4_le(__v, __p);
89}
90
91/*
92 * Try to store an unaligned value as efficiently as possible.
93 */
94#define __put_unaligned_le(val,ptr) \
95 ({ \
96 switch (sizeof(*(ptr))) { \
97 case 1: \
98 *(ptr) = (val); \
99 break; \
100 case 2: __put_unaligned_2_le((val),(__u8 *)(ptr)); \
101 break; \
102 case 4: __put_unaligned_4_le((val),(__u8 *)(ptr)); \
103 break; \
104 case 8: __put_unaligned_8_le((val),(__u8 *)(ptr)); \
105 break; \
106 default: __bug_unaligned_x(ptr); \
107 break; \
108 } \
109 (void) 0; \
110 })
111
112/*
113 * Select endianness
114 */
115#define get_unaligned __get_unaligned_le
116#define put_unaligned __put_unaligned_le
117
118#endif
diff --git a/include/asm-arm26/uncompress.h b/include/asm-arm26/uncompress.h
deleted file mode 100644
index df2cba816a4e..000000000000
--- a/include/asm-arm26/uncompress.h
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * linux/include/asm-arm/arch-arc/uncompress.h
3 *
4 * Copyright (C) 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#define VIDMEM ((char *)0x02000000)
11
12int video_num_columns, video_num_lines, video_size_row;
13int white, bytes_per_char_h;
14extern unsigned long con_charconvtable[256];
15
16struct param_struct {
17 unsigned long page_size;
18 unsigned long nr_pages;
19 unsigned long ramdisk_size;
20 unsigned long mountrootrdonly;
21 unsigned long rootdev;
22 unsigned long video_num_cols;
23 unsigned long video_num_rows;
24 unsigned long video_x;
25 unsigned long video_y;
26 unsigned long memc_control_reg;
27 unsigned char sounddefault;
28 unsigned char adfsdrives;
29 unsigned char bytes_per_char_h;
30 unsigned char bytes_per_char_v;
31 unsigned long unused[256/4-11];
32};
33
34static struct param_struct *params = (struct param_struct *)0x0207c000;
35
36/*
37 * This does not append a newline
38 */
39static void puts(const char *s)
40{
41 extern void ll_write_char(char *, unsigned long);
42 int x,y;
43 unsigned char c;
44 char *ptr;
45
46 x = params->video_x;
47 y = params->video_y;
48
49 while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
50 if ( c == '\n' ) {
51 x = 0;
52 if ( ++y >= video_num_lines ) {
53 y--;
54 }
55 } else {
56 ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
57 ll_write_char(ptr, c|(white<<16));
58 if ( ++x >= video_num_columns ) {
59 x = 0;
60 if ( ++y >= video_num_lines ) {
61 y--;
62 }
63 }
64 }
65 }
66
67 params->video_x = x;
68 params->video_y = y;
69}
70
71static void error(char *x);
72
73/*
74 * Setup for decompression
75 */
76static void arch_decomp_setup(void)
77{
78 int i;
79
80 video_num_lines = params->video_num_rows;
81 video_num_columns = params->video_num_cols;
82 bytes_per_char_h = params->bytes_per_char_h;
83 video_size_row = video_num_columns * bytes_per_char_h;
84 if (bytes_per_char_h == 4)
85 for (i = 0; i < 256; i++)
86 con_charconvtable[i] =
87 (i & 128 ? 1 << 0 : 0) |
88 (i & 64 ? 1 << 4 : 0) |
89 (i & 32 ? 1 << 8 : 0) |
90 (i & 16 ? 1 << 12 : 0) |
91 (i & 8 ? 1 << 16 : 0) |
92 (i & 4 ? 1 << 20 : 0) |
93 (i & 2 ? 1 << 24 : 0) |
94 (i & 1 ? 1 << 28 : 0);
95 else
96 for (i = 0; i < 16; i++)
97 con_charconvtable[i] =
98 (i & 8 ? 1 << 0 : 0) |
99 (i & 4 ? 1 << 8 : 0) |
100 (i & 2 ? 1 << 16 : 0) |
101 (i & 1 ? 1 << 24 : 0);
102
103 white = bytes_per_char_h == 8 ? 0xfc : 7;
104
105 if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
106}
107
108/*
109 * nothing to do
110 */
111#define arch_decomp_wdog()
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
deleted file mode 100644
index 4c3b919177e5..000000000000
--- a/include/asm-arm26/unistd.h
+++ /dev/null
@@ -1,343 +0,0 @@
1/*
2 * linux/include/asm-arm/unistd.h
3 *
4 * Copyright (C) 2001-2003 Russell King
5 * Modified 25/11/04 Ian Molton for arm26.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Please forward _all_ changes to this file to spyro@f2s.com
12 * no matter what the change is. Thanks!
13 */
14#ifndef __ASM_ARM_UNISTD_H
15#define __ASM_ARM_UNISTD_H
16
17#define __NR_SYSCALL_BASE 0x900000
18
19/*
20 * This file contains the system call numbers.
21 */
22
23#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
24#define __NR_exit (__NR_SYSCALL_BASE+ 1)
25#define __NR_fork (__NR_SYSCALL_BASE+ 2)
26#define __NR_read (__NR_SYSCALL_BASE+ 3)
27#define __NR_write (__NR_SYSCALL_BASE+ 4)
28#define __NR_open (__NR_SYSCALL_BASE+ 5)
29#define __NR_close (__NR_SYSCALL_BASE+ 6)
30 /* 7 was sys_waitpid */
31#define __NR_creat (__NR_SYSCALL_BASE+ 8)
32#define __NR_link (__NR_SYSCALL_BASE+ 9)
33#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
34#define __NR_execve (__NR_SYSCALL_BASE+ 11)
35#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
36#define __NR_time (__NR_SYSCALL_BASE+ 13)
37#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
38#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
39#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
40 /* 17 was sys_break */
41 /* 18 was sys_stat */
42#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
43#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
44#define __NR_mount (__NR_SYSCALL_BASE+ 21)
45#define __NR_umount (__NR_SYSCALL_BASE+ 22)
46#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
47#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
48#define __NR_stime (__NR_SYSCALL_BASE+ 25)
49#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
50#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
51 /* 28 was sys_fstat */
52#define __NR_pause (__NR_SYSCALL_BASE+ 29)
53#define __NR_utime (__NR_SYSCALL_BASE+ 30)
54 /* 31 was sys_stty */
55 /* 32 was sys_gtty */
56#define __NR_access (__NR_SYSCALL_BASE+ 33)
57#define __NR_nice (__NR_SYSCALL_BASE+ 34)
58 /* 35 was sys_ftime */
59#define __NR_sync (__NR_SYSCALL_BASE+ 36)
60#define __NR_kill (__NR_SYSCALL_BASE+ 37)
61#define __NR_rename (__NR_SYSCALL_BASE+ 38)
62#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
63#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
64#define __NR_dup (__NR_SYSCALL_BASE+ 41)
65#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
66#define __NR_times (__NR_SYSCALL_BASE+ 43)
67 /* 44 was sys_prof */
68#define __NR_brk (__NR_SYSCALL_BASE+ 45)
69#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
70#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
71 /* 48 was sys_signal */
72#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
73#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
74#define __NR_acct (__NR_SYSCALL_BASE+ 51)
75#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
76 /* 53 was sys_lock */
77#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
78#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
79 /* 56 was sys_mpx */
80#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
81 /* 58 was sys_ulimit */
82 /* 59 was sys_olduname */
83#define __NR_umask (__NR_SYSCALL_BASE+ 60)
84#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
85#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
86#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
87#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
88#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
89#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
90#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
91 /* 68 was sys_sgetmask */
92 /* 69 was sys_ssetmask */
93#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
94#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
95#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
96#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
97#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
98#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
99#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
100#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
101#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
102#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
103#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
104#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
105#define __NR_select (__NR_SYSCALL_BASE+ 82)
106#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
107 /* 84 was sys_lstat */
108#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
109#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
110#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
111#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
112#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
113#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
114#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
115#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
116#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
117#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
118#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
119#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
120#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
121 /* 98 was sys_profil */
122#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
123#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
124 /* 101 was sys_ioperm */
125#define __NR_socketcall (__NR_SYSCALL_BASE+102)
126#define __NR_syslog (__NR_SYSCALL_BASE+103)
127#define __NR_setitimer (__NR_SYSCALL_BASE+104)
128#define __NR_getitimer (__NR_SYSCALL_BASE+105)
129#define __NR_stat (__NR_SYSCALL_BASE+106)
130#define __NR_lstat (__NR_SYSCALL_BASE+107)
131#define __NR_fstat (__NR_SYSCALL_BASE+108)
132 /* 109 was sys_uname */
133 /* 110 was sys_iopl */
134#define __NR_vhangup (__NR_SYSCALL_BASE+111)
135 /* 112 was sys_idle */
136#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
137#define __NR_wait4 (__NR_SYSCALL_BASE+114)
138#define __NR_swapoff (__NR_SYSCALL_BASE+115)
139#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
140#define __NR_ipc (__NR_SYSCALL_BASE+117)
141#define __NR_fsync (__NR_SYSCALL_BASE+118)
142#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
143#define __NR_clone (__NR_SYSCALL_BASE+120)
144#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
145#define __NR_uname (__NR_SYSCALL_BASE+122)
146 /* 123 was sys_modify_ldt */
147#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
148#define __NR_mprotect (__NR_SYSCALL_BASE+125)
149#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
150 /* 127 was sys_create_module */
151#define __NR_init_module (__NR_SYSCALL_BASE+128)
152#define __NR_delete_module (__NR_SYSCALL_BASE+129)
153 /* 130 was sys_get_kernel_syms */
154#define __NR_quotactl (__NR_SYSCALL_BASE+131)
155#define __NR_getpgid (__NR_SYSCALL_BASE+132)
156#define __NR_fchdir (__NR_SYSCALL_BASE+133)
157#define __NR_bdflush (__NR_SYSCALL_BASE+134)
158#define __NR_sysfs (__NR_SYSCALL_BASE+135)
159#define __NR_personality (__NR_SYSCALL_BASE+136)
160 /* 137 was sys_afs_syscall */
161#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
162#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
163#define __NR__llseek (__NR_SYSCALL_BASE+140)
164#define __NR_getdents (__NR_SYSCALL_BASE+141)
165#define __NR__newselect (__NR_SYSCALL_BASE+142)
166#define __NR_flock (__NR_SYSCALL_BASE+143)
167#define __NR_msync (__NR_SYSCALL_BASE+144)
168#define __NR_readv (__NR_SYSCALL_BASE+145)
169#define __NR_writev (__NR_SYSCALL_BASE+146)
170#define __NR_getsid (__NR_SYSCALL_BASE+147)
171#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
172#define __NR__sysctl (__NR_SYSCALL_BASE+149)
173#define __NR_mlock (__NR_SYSCALL_BASE+150)
174#define __NR_munlock (__NR_SYSCALL_BASE+151)
175#define __NR_mlockall (__NR_SYSCALL_BASE+152)
176#define __NR_munlockall (__NR_SYSCALL_BASE+153)
177#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
178#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
179#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
180#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
181#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
182#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
183#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
184#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
185#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
186#define __NR_mremap (__NR_SYSCALL_BASE+163)
187#define __NR_setresuid (__NR_SYSCALL_BASE+164)
188#define __NR_getresuid (__NR_SYSCALL_BASE+165)
189 /* 166 was sys_vm86 */
190 /* 167 was sys_query_module */
191#define __NR_poll (__NR_SYSCALL_BASE+168)
192#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
193#define __NR_setresgid (__NR_SYSCALL_BASE+170)
194#define __NR_getresgid (__NR_SYSCALL_BASE+171)
195#define __NR_prctl (__NR_SYSCALL_BASE+172)
196#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
197#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
198#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
199#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
200#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
201#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
202#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
203#define __NR_pread64 (__NR_SYSCALL_BASE+180)
204#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
205#define __NR_chown (__NR_SYSCALL_BASE+182)
206#define __NR_getcwd (__NR_SYSCALL_BASE+183)
207#define __NR_capget (__NR_SYSCALL_BASE+184)
208#define __NR_capset (__NR_SYSCALL_BASE+185)
209#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
210#define __NR_sendfile (__NR_SYSCALL_BASE+187)
211 /* 188 reserved */
212 /* 189 reserved */
213#define __NR_vfork (__NR_SYSCALL_BASE+190)
214#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
215#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
216#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
217#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
218#define __NR_stat64 (__NR_SYSCALL_BASE+195)
219#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
220#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
221#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
222#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
223#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
224#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
225#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
226#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
227#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
228#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
229#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
230#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
231#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
232#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
233#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
234#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
235#define __NR_chown32 (__NR_SYSCALL_BASE+212)
236#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
237#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
238#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
239#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
240#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
241#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
242#define __NR_mincore (__NR_SYSCALL_BASE+219)
243#define __NR_madvise (__NR_SYSCALL_BASE+220)
244#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
245 /* 222 for tux */
246 /* 223 is unused */
247#define __NR_gettid (__NR_SYSCALL_BASE+224)
248#define __NR_readahead (__NR_SYSCALL_BASE+225)
249#define __NR_setxattr (__NR_SYSCALL_BASE+226)
250#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
251#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
252#define __NR_getxattr (__NR_SYSCALL_BASE+229)
253#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
254#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
255#define __NR_listxattr (__NR_SYSCALL_BASE+232)
256#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
257#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
258#define __NR_removexattr (__NR_SYSCALL_BASE+235)
259#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
260#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
261#define __NR_tkill (__NR_SYSCALL_BASE+238)
262#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
263#define __NR_futex (__NR_SYSCALL_BASE+240)
264#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
265#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
266#define __NR_io_setup (__NR_SYSCALL_BASE+243)
267#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
268#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
269#define __NR_io_submit (__NR_SYSCALL_BASE+246)
270#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
271#define __NR_exit_group (__NR_SYSCALL_BASE+248)
272#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
273#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
274#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
275#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
276#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
277 /* 254 for set_thread_area */
278 /* 255 for get_thread_area */
279 /* 256 for set_tid_address */
280#define __NR_timer_create (__NR_SYSCALL_BASE+257)
281#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
282#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
283#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
284#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
285#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
286#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
287#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
288#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
289#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
290#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
291#define __NR_tgkill (__NR_SYSCALL_BASE+268)
292#define __NR_utimes (__NR_SYSCALL_BASE+269)
293#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270)
294#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
295#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
296#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
297#define __NR_mq_open (__NR_SYSCALL_BASE+274)
298#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
299#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
300#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
301#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
302#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
303#define __NR_waitid (__NR_SYSCALL_BASE+280)
304
305/*
306 * The following SWIs are ARM private. FIXME - make appropriate for arm26
307 */
308#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
309#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
310#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
311#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
312
313#ifdef __KERNEL__
314
315#define __ARCH_WANT_IPC_PARSE_VERSION
316#define __ARCH_WANT_OLD_READDIR
317#define __ARCH_WANT_STAT64
318#define __ARCH_WANT_SYS_ALARM
319#define __ARCH_WANT_SYS_GETHOSTNAME
320#define __ARCH_WANT_SYS_PAUSE
321#define __ARCH_WANT_SYS_TIME
322#define __ARCH_WANT_SYS_UTIME
323#define __ARCH_WANT_SYS_SOCKETCALL
324#define __ARCH_WANT_SYS_FADVISE64
325#define __ARCH_WANT_SYS_GETPGRP
326#define __ARCH_WANT_SYS_LLSEEK
327#define __ARCH_WANT_SYS_NICE
328#define __ARCH_WANT_SYS_OLD_GETRLIMIT
329#define __ARCH_WANT_SYS_OLDUMOUNT
330#define __ARCH_WANT_SYS_SIGPENDING
331#define __ARCH_WANT_SYS_SIGPROCMASK
332#define __ARCH_WANT_SYS_RT_SIGACTION
333
334/*
335 * "Conditional" syscalls
336 *
337 * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
338 * but it doesn't work on all toolchains, so we just do it by hand
339 */
340#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
341
342#endif /* __KERNEL__ */
343#endif /* __ASM_ARM_UNISTD_H */
diff --git a/include/asm-arm26/user.h b/include/asm-arm26/user.h
deleted file mode 100644
index 3e8b0f879159..000000000000
--- a/include/asm-arm26/user.h
+++ /dev/null
@@ -1,84 +0,0 @@
1#ifndef _ARM_USER_H
2#define _ARM_USER_H
3
4#include <asm/page.h>
5#include <asm/ptrace.h>
6/* Core file format: The core file is written in such a way that gdb
7 can understand it and provide useful information to the user (under
8 linux we use the 'trad-core' bfd). There are quite a number of
9 obstacles to being able to view the contents of the floating point
10 registers, and until these are solved you will not be able to view the
11 contents of them. Actually, you can read in the core file and look at
12 the contents of the user struct to find out what the floating point
13 registers contain.
14 The actual file contents are as follows:
15 UPAGE: 1 page consisting of a user struct that tells gdb what is present
16 in the file. Directly after this is a copy of the task_struct, which
17 is currently not used by gdb, but it may come in useful at some point.
18 All of the registers are stored as part of the upage. The upage should
19 always be only one page.
20 DATA: The data area is stored. We use current->end_text to
21 current->brk to pick up all of the user variables, plus any memory
22 that may have been malloced. No attempt is made to determine if a page
23 is demand-zero or if a page is totally unused, we just cover the entire
24 range. All of the addresses are rounded in such a way that an integral
25 number of pages is written.
26 STACK: We need the stack information in order to get a meaningful
27 backtrace. We need to write the data from (esp) to
28 current->start_stack, so we round each of these off in order to be able
29 to write an integer number of pages.
30 The minimum core file size is 3 pages, or 12288 bytes.
31*/
32
33struct user_fp {
34 struct fp_reg {
35 unsigned int sign1:1;
36 unsigned int unused:15;
37 unsigned int sign2:1;
38 unsigned int exponent:14;
39 unsigned int j:1;
40 unsigned int mantissa1:31;
41 unsigned int mantissa0:32;
42 } fpregs[8];
43 unsigned int fpsr:32;
44 unsigned int fpcr:32;
45 unsigned char ftype[8];
46 unsigned int init_flag;
47};
48
49/* When the kernel dumps core, it starts by dumping the user struct -
50 this will be used by gdb to figure out where the data and stack segments
51 are within the file, and what virtual addresses to use. */
52struct user{
53/* We start with the registers, to mimic the way that "memory" is returned
54 from the ptrace(3,...) function. */
55 struct pt_regs regs; /* Where the registers are actually stored */
56/* ptrace does not yet supply these. Someday.... */
57 int u_fpvalid; /* True if math co-processor being used. */
58 /* for this mess. Not yet used. */
59/* The rest of this junk is to help gdb figure out what goes where */
60 unsigned long int u_tsize; /* Text segment size (pages). */
61 unsigned long int u_dsize; /* Data segment size (pages). */
62 unsigned long int u_ssize; /* Stack segment size (pages). */
63 unsigned long start_code; /* Starting virtual address of text. */
64 unsigned long start_stack; /* Starting virtual address of stack area.
65 This is actually the bottom of the stack,
66 the top of the stack is always found in the
67 esp register. */
68 long int signal; /* Signal that caused the core dump. */
69 int reserved; /* No longer used */
70 struct pt_regs * u_ar0; /* Used by gdb to help find the values for */
71 /* the registers. */
72 unsigned long magic; /* To uniquely identify a core file */
73 char u_comm[32]; /* User command that was responsible */
74 int u_debugreg[8];
75 struct user_fp u_fp; /* FP state */
76 struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */
77 /* the FP registers. */
78};
79#define NBPG PAGE_SIZE
80#define UPAGES 1
81#define HOST_TEXT_START_ADDR (u.start_code)
82#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
83
84#endif /* _ARM_USER_H */
diff --git a/include/asm-arm26/xor.h b/include/asm-arm26/xor.h
deleted file mode 100644
index e7c4cf58bed1..000000000000
--- a/include/asm-arm26/xor.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/*
2 * linux/include/asm-arm/xor.h
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm-generic/xor.h>
11
12#define __XOR(a1, a2) a1 ^= a2
13
14#define GET_BLOCK_2(dst) \
15 __asm__("ldmia %0, {%1, %2}" \
16 : "=r" (dst), "=r" (a1), "=r" (a2) \
17 : "0" (dst))
18
19#define GET_BLOCK_4(dst) \
20 __asm__("ldmia %0, {%1, %2, %3, %4}" \
21 : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
22 : "0" (dst))
23
24#define XOR_BLOCK_2(src) \
25 __asm__("ldmia %0!, {%1, %2}" \
26 : "=r" (src), "=r" (b1), "=r" (b2) \
27 : "0" (src)); \
28 __XOR(a1, b1); __XOR(a2, b2);
29
30#define XOR_BLOCK_4(src) \
31 __asm__("ldmia %0!, {%1, %2, %3, %4}" \
32 : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
33 : "0" (src)); \
34 __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
35
36#define PUT_BLOCK_2(dst) \
37 __asm__ __volatile__("stmia %0!, {%2, %3}" \
38 : "=r" (dst) \
39 : "0" (dst), "r" (a1), "r" (a2))
40
41#define PUT_BLOCK_4(dst) \
42 __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \
43 : "=r" (dst) \
44 : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
45
46static void
47xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
48{
49 unsigned int lines = bytes / sizeof(unsigned long) / 4;
50 register unsigned int a1 __asm__("r4");
51 register unsigned int a2 __asm__("r5");
52 register unsigned int a3 __asm__("r6");
53 register unsigned int a4 __asm__("r7");
54 register unsigned int b1 __asm__("r8");
55 register unsigned int b2 __asm__("r9");
56 register unsigned int b3 __asm__("ip");
57 register unsigned int b4 __asm__("lr");
58
59 do {
60 GET_BLOCK_4(p1);
61 XOR_BLOCK_4(p2);
62 PUT_BLOCK_4(p1);
63 } while (--lines);
64}
65
66static void
67xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
68 unsigned long *p3)
69{
70 unsigned int lines = bytes / sizeof(unsigned long) / 4;
71 register unsigned int a1 __asm__("r4");
72 register unsigned int a2 __asm__("r5");
73 register unsigned int a3 __asm__("r6");
74 register unsigned int a4 __asm__("r7");
75 register unsigned int b1 __asm__("r8");
76 register unsigned int b2 __asm__("r9");
77 register unsigned int b3 __asm__("ip");
78 register unsigned int b4 __asm__("lr");
79
80 do {
81 GET_BLOCK_4(p1);
82 XOR_BLOCK_4(p2);
83 XOR_BLOCK_4(p3);
84 PUT_BLOCK_4(p1);
85 } while (--lines);
86}
87
88static void
89xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
90 unsigned long *p3, unsigned long *p4)
91{
92 unsigned int lines = bytes / sizeof(unsigned long) / 2;
93 register unsigned int a1 __asm__("r8");
94 register unsigned int a2 __asm__("r9");
95 register unsigned int b1 __asm__("ip");
96 register unsigned int b2 __asm__("lr");
97
98 do {
99 GET_BLOCK_2(p1);
100 XOR_BLOCK_2(p2);
101 XOR_BLOCK_2(p3);
102 XOR_BLOCK_2(p4);
103 PUT_BLOCK_2(p1);
104 } while (--lines);
105}
106
107static void
108xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
109 unsigned long *p3, unsigned long *p4, unsigned long *p5)
110{
111 unsigned int lines = bytes / sizeof(unsigned long) / 2;
112 register unsigned int a1 __asm__("r8");
113 register unsigned int a2 __asm__("r9");
114 register unsigned int b1 __asm__("ip");
115 register unsigned int b2 __asm__("lr");
116
117 do {
118 GET_BLOCK_2(p1);
119 XOR_BLOCK_2(p2);
120 XOR_BLOCK_2(p3);
121 XOR_BLOCK_2(p4);
122 XOR_BLOCK_2(p5);
123 PUT_BLOCK_2(p1);
124 } while (--lines);
125}
126
127static struct xor_block_template xor_block_arm4regs = {
128 .name = "arm4regs",
129 .do_2 = xor_arm4regs_2,
130 .do_3 = xor_arm4regs_3,
131 .do_4 = xor_arm4regs_4,
132 .do_5 = xor_arm4regs_5,
133};
134
135#undef XOR_TRY_TEMPLATES
136#define XOR_TRY_TEMPLATES \
137 do { \
138 xor_speed(&xor_block_arm4regs); \
139 xor_speed(&xor_block_8regs); \
140 xor_speed(&xor_block_32regs); \
141 } while (0)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index da8eb8ad9e9b..3ea68cd3b61f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -120,7 +120,6 @@ enum zone_type {
120 * --------------------------- 120 * ---------------------------
121 * parisc, ia64, sparc <4G 121 * parisc, ia64, sparc <4G
122 * s390 <2G 122 * s390 <2G
123 * arm26 <48M
124 * arm Various 123 * arm Various
125 * alpha Unlimited or 0-16MB. 124 * alpha Unlimited or 0-16MB.
126 * 125 *
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f3e0c2abcbd0..50a94eee4d92 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -349,7 +349,7 @@ config DEBUG_HIGHMEM
349config DEBUG_BUGVERBOSE 349config DEBUG_BUGVERBOSE
350 bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED 350 bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
351 depends on BUG 351 depends on BUG
352 depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG || BFIN 352 depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG || BFIN
353 default !EMBEDDED 353 default !EMBEDDED
354 help 354 help
355 Say Y here to make BUG() panics output the file name and line number 355 Say Y here to make BUG() panics output the file name and line number