summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/Makefile32
-rw-r--r--arch/arm/lib/ecard.S47
-rw-r--r--arch/arm/lib/io-acorn.S549
-rw-r--r--arch/arm/lib/io-ebsa110.S169
-rw-r--r--arch/arm/lib/io-footbridge.S202
-rw-r--r--arch/arm/lib/io-pcio.S38
-rw-r--r--arch/arm/lib/io-readsb.S111
-rw-r--r--arch/arm/lib/io-readsl.S65
-rw-r--r--arch/arm/lib/io-readsw-armv3.S102
-rw-r--r--arch/arm/lib/io-readsw-armv4.S87
-rw-r--r--arch/arm/lib/io-writesb.S115
-rw-r--r--arch/arm/lib/io-writesl.S55
-rw-r--r--arch/arm/lib/io-writesw-armv3.S125
-rw-r--r--arch/arm/lib/io-writesw-armv4.S79
14 files changed, 859 insertions, 917 deletions
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index b7e29ca55..fa7f10117 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -13,19 +13,35 @@ L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \
testchangebit.o testclearbit.o testsetbit.o uaccess.o
+l-obj-y :=
+l-obj-n :=
+
O_TARGET := lib.o
O_OBJS := backtrace.o delay.o
-L_OBJS_arc := io-acorn.o floppydma.o
-L_OBJS_rpc := io-acorn.o floppydma.o
+ifeq ($(CONFIG_ARCH_ACORN),y)
+ half := n
+ full := y
+else
+ half := y
+ full := n
+endif
+
+L_OBJS_arc := ecard.o io-acorn.o floppydma.o
+L_OBJS_rpc := ecard.o io-acorn.o floppydma.o
L_OBJS_clps7500 := io-acorn.o
-L_OBJS_ebsa110 := io-ebsa110.o
-L_OBJS_footbridge := io-footbridge.o
+L_OBJS_footbridge := io-pcio.o
L_OBJS_l7200 := io-acorn.o
-L_OBJS_nexuspci := io-footbridge.o
-L_OBJS_sa1100 := io-footbridge.o
+L_OBJS_nexuspci := io-pcio.o
+L_OBJS_sa1100 := io-pcio.o
L_OBJS_shark := io-shark.o
-L_OBJS_integrator := io-shark.o
+L_OBJS_integrator := io-pcio.o
+L_OBJS_clps711x := io-shark.o
+
+l-obj-y += io-readsb.o io-writesb.o
+l-obj-$(full) += io-readsw-armv3.o io-writesw-armv3.o
+l-obj-$(half) += io-readsw-armv4.o io-writesw-armv4.o
+l-obj-y += io-readsl.o io-writesl.o
ifeq ($(PROCESSOR),armo)
L_OBJS += uaccess-armo.o
@@ -35,7 +51,7 @@ ifneq ($(MACHINE),ebsa110)
OX_OBJS += io.o
endif
-L_OBJS += $(L_OBJS_$(MACHINE))
+L_OBJS += $(L_OBJS_$(MACHINE)) $(l-obj-y)
include $(TOPDIR)/Rules.make
diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S
new file mode 100644
index 000000000..9b0452d01
--- /dev/null
+++ b/arch/arm/lib/ecard.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/lib/ecard.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h> /* for CONFIG_CPU_nn */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#if defined(CONFIG_CPU_26)
+#define CPSR2SPSR(rt)
+#else
+#define CPSR2SPSR(rt) \
+ mrs rt, cpsr; \
+ msr spsr, rt
+#endif
+
+@ Purpose: call an expansion card loader to read bytes.
+@ Proto : char read_loader(int offset, char *card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_read)
+ stmfd sp!, {r4 - r12, lr}
+ mov r11, r1
+ mov r1, r0
+ CPSR2SPSR(r0)
+ mov lr, pc
+ mov pc, r2
+ LOADREGS(fd, sp!, {r4 - r12, pc})
+
+@ Purpose: call an expansion card loader to reset the card
+@ Proto : void read_loader(int card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_reset)
+ stmfd sp!, {r4 - r12, lr}
+ mov r11, r0
+ CPSR2SPSR(r0)
+ mov lr, pc
+ add pc, r1, #8
+ LOADREGS(fd, sp!, {r4 - r12, pc})
+
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S
index bc40496ac..a40272fdb 100644
--- a/arch/arm/lib/io-acorn.S
+++ b/arch/arm/lib/io-acorn.S
@@ -40,8 +40,6 @@
addeq \rd, \rd, #diff_pcio_base
.endm
-.iosw_bad_align_msg:
- .ascii "insw: bad buffer alignment (%p), called from %08lX\n\0"
.iosl_warning:
.ascii "<4>insl/outsl not implemented, called from %08lX\0"
.align
@@ -56,422 +54,38 @@ ENTRY(outsl)
mov r1, lr
b SYMBOL_NAME(printk)
-.iosw_bad_alignment:
- adr r0, .iosw_bad_align_msg
- mov r2, lr
- b SYMBOL_NAME(panic)
-
-
/* Purpose: read a block of data from a hardware register to memory.
* Proto : void insw(int from_port, void *to, int len_in_words);
* Notes : increment to, 'to' must be 16-bit aligned
*/
-.insw_align: tst r1, #1
- bne .iosw_bad_alignment
-
- ldr r3, [r0]
- strb r3, [r1], #1
- mov r3, r3, lsr #8
- strb r3, [r1], #1
-
- subs r2, r2, #1
- bne .insw_aligned
-
ENTRY(insw)
teq r2, #0
- RETINSTR(moveq,pc,lr)
+ RETINSTR(moveq, pc, lr)
addr r0
- tst r1, #3
- bne .insw_align
-
-.insw_aligned: mov ip, #0xff
- orr ip, ip, ip, lsl #8
- stmfd sp!, {r4, r5, r6, lr}
-
- subs r2, r2, #8
- bmi .no_insw_8
-
-.insw_8_lp: ldr r3, [r0]
- and r3, r3, ip
- ldr r4, [r0]
- orr r3, r3, r4, lsl #16
-
- ldr r4, [r0]
- and r4, r4, ip
- ldr r5, [r0]
- orr r4, r4, r5, lsl #16
-
- ldr r5, [r0]
- and r5, r5, ip
- ldr r6, [r0]
- orr r5, r5, r6, lsl #16
-
- ldr r6, [r0]
- and r6, r6, ip
- ldr lr, [r0]
- orr r6, r6, lr, lsl #16
-
- stmia r1!, {r3 - r6}
- subs r2, r2, #8
- bpl .insw_8_lp
- tst r2, #7
- LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+ b __arch_readsw
-.no_insw_8: tst r2, #4
- beq .no_insw_4
-
- ldr r3, [r0]
- and r3, r3, ip
- ldr r4, [r0]
- orr r3, r3, r4, lsl #16
-
- ldr r4, [r0]
- and r4, r4, ip
- ldr r5, [r0]
- orr r4, r4, r5, lsl #16
-
- stmia r1!, {r3, r4}
-
-.no_insw_4: tst r2, #2
- beq .no_insw_2
-
- ldr r3, [r0]
- and r3, r3, ip
- ldr r4, [r0]
- orr r3, r3, r4, lsl #16
-
- str r3, [r1], #4
-
-.no_insw_2: tst r2, #1
- ldrne r3, [r0]
- strneb r3, [r1], #1
- movne r3, r3, lsr #8
- strneb r3, [r1]
- LOADREGS(fd, sp!, {r4, r5, r6, pc})
+ENTRY(insb)
+ teq r2, #0
+ RETINSTR(moveq, pc, lr)
+ addr r0
+ b __arch_readsb
@ Purpose: write a block of data from memory to a hardware register.
@ Proto : outsw(int to_reg, void *from, int len_in_words);
@ Notes : increments from
-.outsw_align: tst r1, #1
- bne .iosw_bad_alignment
-
- add r1, r1, #2
-
- ldr r3, [r1, #-4]
- mov r3, r3, lsr #16
- orr r3, r3, r3, lsl #16
- str r3, [r0]
- subs r2, r2, #1
- bne .outsw_aligned
-
ENTRY(outsw)
teq r2, #0
- RETINSTR(moveq,pc,lr)
- addr r0
- tst r1, #3
- bne .outsw_align
-
-.outsw_aligned: stmfd sp!, {r4, r5, r6, lr}
-
- subs r2, r2, #8
- bmi .no_outsw_8
-.outsw_8_lp: ldmia r1!, {r3, r4, r5, r6}
-
- mov ip, r3, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r3, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
- mov ip, r4, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r4, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
- mov ip, r5, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r5, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
- mov ip, r6, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r6, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
- subs r2, r2, #8
- bpl .outsw_8_lp
- tst r2, #7
- LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
-
-.no_outsw_8: tst r2, #4
- beq .no_outsw_4
-
- ldmia r1!, {r3, r4}
-
- mov ip, r3, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r3, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
- mov ip, r4, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r4, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
-.no_outsw_4: tst r2, #2
- beq .no_outsw_2
-
- ldr r3, [r1], #4
-
- mov ip, r3, lsl #16
- orr ip, ip, ip, lsr #16
- str ip, [r0]
-
- mov ip, r3, lsr #16
- orr ip, ip, ip, lsl #16
- str ip, [r0]
-
-.no_outsw_2: tst r2, #1
-
- ldrne r3, [r1]
-
- movne ip, r3, lsl #16
- orrne ip, ip, ip, lsr #16
- strne ip, [r0]
-
- LOADREGS(fd, sp!, {r4, r5, r6, pc})
-
-.insb_align: rsb ip, ip, #4
- cmp ip, r2
- movgt ip, r2
- cmp ip, #2
- ldrb r3, [r0]
- strb r3, [r1], #1
- ldrgeb r3, [r0]
- strgeb r3, [r1], #1
- ldrgtb r3, [r0]
- strgtb r3, [r1], #1
- subs r2, r2, ip
- bne .insb_aligned
-
-ENTRY(insb)
- teq r2, #0
- moveq pc, lr
+ RETINSTR(moveq, pc, lr)
addr r0
- ands ip, r1, #3
- bne .insb_align
-
-.insb_aligned: stmfd sp!, {r4 - r6, lr}
-
- subs r2, r2, #16
- bmi .insb_no_16
-
-.insb_16_lp: ldrb r3, [r0]
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #8
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #16
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #24
- ldrb r4, [r0]
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #8
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #16
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #24
- ldrb r5, [r0]
- ldrb r6, [r0]
- orr r5, r5, r6, lsl #8
- ldrb r6, [r0]
- orr r5, r5, r6, lsl #16
- ldrb r6, [r0]
- orr r5, r5, r6, lsl #24
- ldrb r6, [r0]
- ldrb ip, [r0]
- orr r6, r6, ip, lsl #8
- ldrb ip, [r0]
- orr r6, r6, ip, lsl #16
- ldrb ip, [r0]
- orr r6, r6, ip, lsl #24
- stmia r1!, {r3 - r6}
- subs r2, r2, #16
- bpl .insb_16_lp
-
- tst r2, #15
- LOADREGS(eqfd, sp!, {r4 - r6, pc})
-
-.insb_no_16: tst r2, #8
- beq .insb_no_8
-
- ldrb r3, [r0]
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #8
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #16
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #24
- ldrb r4, [r0]
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #8
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #16
- ldrb r5, [r0]
- orr r4, r4, r5, lsl #24
- stmia r1!, {r3, r4}
-
-.insb_no_8: tst r2, #4
- bne .insb_no_4
-
- ldrb r3, [r0]
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #8
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #16
- ldrb r4, [r0]
- orr r3, r3, r4, lsl #24
- str r3, [r1], #4
-
-.insb_no_4: ands r2, r2, #3
- LOADREGS(eqfd, sp!, {r4 - r6, pc})
- cmp r2, #2
- ldrb r3, [r0]
- strb r3, [r1], #1
- ldrgeb r3, [r0]
- strgeb r3, [r1], #1
- ldrgtb r3, [r0]
- strgtb r3, [r1]
- LOADREGS(fd, sp!, {r4 - r6, pc})
-
-
-
-.outsb_align: rsb ip, ip, #4
- cmp ip, r2
- mov ip, r2
- cmp ip, #2
- ldrb r3, [r1], #1
- strb r3, [r0]
- ldrgeb r3, [r1], #1
- strgeb r3, [r0]
- ldrgtb r3, [r1], #1
- strgtb r3, [r0]
- subs r2, r2, ip
- bne .outsb_aligned
+ b __arch_writesw
ENTRY(outsb)
teq r2, #0
- moveq pc, lr
+ RETINSTR(moveq, pc, lr)
addr r0
- ands ip, r1, #3
- bne .outsb_align
-
-.outsb_aligned: stmfd sp!, {r4 - r6, lr}
-
- subs r2, r2, #16
- bmi .outsb_no_16
-
-.outsb_16_lp: ldmia r1!, {r3 - r6}
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
-
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
-
- strb r5, [r0]
- mov r5, r5, lsr #8
- strb r5, [r0]
- mov r5, r5, lsr #8
- strb r5, [r0]
- mov r5, r5, lsr #8
- strb r5, [r0]
-
- strb r6, [r0]
- mov r6, r6, lsr #8
- strb r6, [r0]
- mov r6, r6, lsr #8
- strb r6, [r0]
- mov r6, r6, lsr #8
- strb r6, [r0]
- subs r2, r2, #16
- bpl .outsb_16_lp
-
- tst r2, #15
- LOADREGS(eqfd, sp!, {r4 - r6, pc})
-
-.outsb_no_16: tst r2, #8
- beq .outsb_no_8
-
- ldmia r1, {r3, r4}
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
-
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
- mov r4, r4, lsr #8
- strb r4, [r0]
-
-.outsb_no_8: tst r2, #4
- bne .outsb_no_4
-
- ldr r3, [r1], #4
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
- mov r3, r3, lsr #8
- strb r3, [r0]
-
-.outsb_no_4: ands r2, r2, #3
- LOADREGS(eqfd, sp!, {r4 - r6, pc})
- cmp r2, #2
- ldrb r3, [r1], #1
- strb r3, [r0]
- ldrgeb r3, [r1], #1
- strgeb r3, [r0]
- ldrgtb r3, [r1]
- strgtb r3, [r0]
- LOADREGS(fd, sp!, {r4 - r6, pc})
-
-
-
+ b __arch_writesb
@ Purpose: write a memc register
@ Proto : void memc_write(int register, int value);
@@ -488,146 +102,5 @@ ENTRY(memc_write)
add r0, r0, #0x03600000
strb r0, [r0]
RETINSTR(mov,pc,lr)
-#define CPSR2SPSR(rt)
-#else
-#define CPSR2SPSR(rt) \
- mrs rt, cpsr; \
- msr spsr, rt
-#endif
-
-@ Purpose: call an expansion card loader to read bytes.
-@ Proto : char read_loader(int offset, char *card_base, char *loader);
-@ Returns: byte read
-
-ENTRY(ecard_loader_read)
- stmfd sp!, {r4 - r12, lr}
- mov r11, r1
- mov r1, r0
- CPSR2SPSR(r0)
- mov lr, pc
- mov pc, r2
- LOADREGS(fd, sp!, {r4 - r12, pc})
-
-@ Purpose: call an expansion card loader to reset the card
-@ Proto : void read_loader(int card_base, char *loader);
-@ Returns: byte read
-
-ENTRY(ecard_loader_reset)
- stmfd sp!, {r4 - r12, lr}
- mov r11, r0
- CPSR2SPSR(r0)
- mov lr, pc
- add pc, r1, #8
- LOADREGS(fd, sp!, {r4 - r12, pc})
-
-
-#if 0
- mov r2, r2, lsl#1
- mov ip, sp
- stmfd sp!, {r4 - r10, fp, ip, lr, pc}
- sub fp, ip, #4
- addr r3, r0
- add r0, r3, r0, lsl #2
- tst r1, #3
- beq Linswok
- tst r1, #1
- bne Linsw_notaligned
- cmp r2, #1
- ldrge r4, [r0]
- strgeb r4, [r1], #1
- movgt r4, r4, LSR#8
- strgtb r4, [r1], #1
- LOADREGS(leea, fp, {r4 - r10, fp, sp, pc})
- sub r2, r2, #2
-Linswok: mov ip, #0xFF
- orr ip, ip, ip, lsl #8
-Linswlp: subs r2, r2, #64
- bmi Linsw_toosmall
- IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- bne Linswlp
- LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
-Linsw_toosmall:
- adds r2, r2, #32
- bmi Linsw_toosmall2
-Linsw2lp: IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- LOADREGS(eqea, fp, {r4 - r10, fp, sp, pc})
- b Linsw_notaligned
-Linsw_toosmall2:
- add r2, r2, #32
-Linsw_notaligned:
- cmp r2, #1
- LOADREGS(ltea, fp, {r4 - r10, fp, sp, pc})
- ldr r4, [r0]
- strb r4, [r1], #1
- movgt r4, r4, LSR#8
- strgtb r4, [r1], #1
- subs r2, r2, #2
- bgt Linsw_notaligned
- LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
-
-
-ENTRY(outsw)
- mov r2, r2, lsl#1
- mov ip, sp
- stmfd sp!, {r4 - r8, fp, ip, lr, pc}
- sub fp, ip, #4
- addr r3, r0
- tst r1, #2
- beq 1f
- ldr r4, [r1], #2
- mov r4, r4, lsl #16
- orr r4, r4, r4, lsr #16
- str r4, [r3, r0, lsl #2]
- subs r2, r2, #2
- LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
-1: subs r2, r2, #32
- blt 2f
- ldmia r1!, {r4, r5, r6, r7}
- OUT(r4)
- OUT(r5)
- OUT(r6)
- OUT(r7)
- ldmia r1!, {r4, r5, r6, r7}
- OUT(r4)
- OUT(r5)
- OUT(r6)
- OUT(r7)
- bne 1b
- LOADREGS(ea, fp, {r4 - r8, fp, sp, pc})
-2: adds r2, r2, #32
- LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
-3: ldr r4, [r1],#2
- mov r4, r4, lsl#16
- orr r4, r4, r4, lsr#16
- str r4, [r3, r0, lsl#2]
- subs r2, r2, #2
- bgt 3b
- LOADREGS(ea, fp, {r4 - r8, fp, sp, pc})
-
#endif
diff --git a/arch/arm/lib/io-ebsa110.S b/arch/arm/lib/io-ebsa110.S
deleted file mode 100644
index b1c507886..000000000
--- a/arch/arm/lib/io-ebsa110.S
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * linux/arch/arm/lib/io-ebsa.S
- *
- * Copyright (C) 1995, 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
- .text
- .align
-
-#define OUT(reg) \
- mov r8, reg, lsl $16 ;\
- orr r8, r8, r8, lsr $16 ;\
- str r8, [r3, r0, lsl $2] ;\
- mov r8, reg, lsr $16 ;\
- orr r8, r8, r8, lsl $16 ;\
- str r8, [r3, r0, lsl $2]
-
-#define IN(reg) \
- ldr reg, [r0] ;\
- and reg, reg, ip ;\
- ldr lr, [r0] ;\
- orr reg, reg, lr, lsl $16
-
-/*
- * These make no sense on these machines.
- * Print a warning message.
- */
-ENTRY(insl)
-ENTRY(outsl)
-ENTRY(insb)
-ENTRY(outsb)
- adr r0, io_long_warning
- mov r1, lr
- b SYMBOL_NAME(printk)
-
-io_long_warning:
- .ascii "<4>ins?/outs? not implemented on this architecture\0"
- .align
-
-@ Purpose: read a block of data from a hardware register to memory.
-@ Proto : insw(int from_port, void *to, int len_in_words);
-@ Proto : inswb(int from_port, void *to, int len_in_bytes);
-@ Notes : increment to
-
-ENTRY(insw)
- mov r2, r2, lsl#1
-ENTRY(inswb)
- mov ip, sp
- stmfd sp!, {r4 - r10 ,fp ,ip ,lr ,pc}
- sub fp, ip, #4
- cmp r0, #0x00c00000
- movge r3, #0
- movlt r3, #0xf0000000
- add r0, r3, r0, lsl #2
- tst r1, #3
- beq Linswok
- tst r1, #1
- bne Linsw_notaligned
- cmp r2, #1
- ldrge r4, [r0]
- strgeb r4, [r1], #1
- movgt r4, r4, LSR#8
- strgtb r4, [r1], #1
- ldmleea fp, {r4 - r10, fp, sp, pc}^
- sub r2, r2, #2
-Linswok: mov ip, #0xFF
- orr ip, ip, ip, lsl #8
-Linswlp: subs r2, r2, #64
- bmi Linsw_toosmall
- IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- bne Linswlp
- LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
-Linsw_toosmall:
- add r2, r2, #32
- bmi Linsw_toosmall2
-Linsw2lp: IN(r3)
- IN(r4)
- IN(r5)
- IN(r6)
- IN(r7)
- IN(r8)
- IN(r9)
- IN(r10)
- stmia r1!, {r3 - r10}
- LOADREGS(eqea, fp, {r4 - r10, fp, sp, pc})
- b Linsw_notaligned
-Linsw_toosmall2:
- add r2, r2, #32
-Linsw_notaligned:
- cmp r2, #1
- LOADREGS(ltea, fp, {r4 - r10, fp, sp, pc})
- ldr r4, [r0]
- strb r4, [r1], #1
- movgt r4, r4, LSR#8
- strgtb r4, [r1], #1
- subs r2, r2, #2
- bgt Linsw_notaligned
- LOADREGS(ea, fp, {r4 - r10, fp, sp, pc})
-
-@ Purpose: write a block of data from memory to a hardware register.
-@ Proto : outsw(int to_reg, void *from, int len_in_words);
-@ Proto : outswb(int to_reg, void *from, int len_in_bytes);
-@ Notes : increments from
-
-ENTRY(outsw)
- mov r2, r2, LSL#1
-ENTRY(outswb)
- mov ip, sp
- stmfd sp!, {r4 - r8, fp, ip, lr, pc}
- sub fp, ip, #4
- cmp r0, #0x00c00000
- movge r3, #0
- movlt r3, #0xf0000000
- tst r1, #2
- beq Loutsw32lp
- ldr r4, [r1], #2
- mov r4, r4, lsl #16
- orr r4, r4, r4, lsr #16
- str r4, [r3, r0, lsl #2]
- sub r2, r2, #2
- teq r2, #0
- LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
-Loutsw32lp: subs r2,r2,#32
- blt Loutsw_toosmall
- ldmia r1!,{r4,r5,r6,r7}
- OUT(r4)
- OUT(r5)
- OUT(r6)
- OUT(r7)
- ldmia r1!,{r4,r5,r6,r7}
- OUT(r4)
- OUT(r5)
- OUT(r6)
- OUT(r7)
- LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
- b Loutsw32lp
-Loutsw_toosmall:
- adds r2,r2,#32
- LOADREGS(eqea, fp, {r4 - r8, fp, sp, pc})
-Llpx: ldr r4,[r1],#2
- mov r4,r4,LSL#16
- orr r4,r4,r4,LSR#16
- str r4,[r3,r0,LSL#2]
- subs r2,r2,#2
- bgt Llpx
- LOADREGS(ea, fp, {r4 - r8, fp, sp, pc})
-
diff --git a/arch/arm/lib/io-footbridge.S b/arch/arm/lib/io-footbridge.S
deleted file mode 100644
index 98f751258..000000000
--- a/arch/arm/lib/io-footbridge.S
+++ /dev/null
@@ -1,202 +0,0 @@
-#include <linux/linkage.h>
-#include <asm/hardware.h>
-
- .equ pcio_high, PCIO_BASE & 0xff000000
- .equ pcio_low, PCIO_BASE & 0x00ffffff
-
- .macro ioaddr, rd,rn
- add \rd, \rn, #pcio_high
- .if pcio_low
- add \rd, \rd, #pcio_low
- .endif
- .endm
-
-ENTRY(insl)
- ioaddr r0, r0
- ands ip, r1, #3
- bne 2f
-
-1: ldr r3, [r0]
- str r3, [r1], #4
- subs r2, r2, #1
- bne 1b
- mov pc, lr
-
-2: cmp ip, #2
- ldr ip, [r0]
- blt 4f
- bgt 6f
-
- strh ip, [r1], #2
- mov ip, ip, lsr #16
-3: subs r2, r2, #1
- ldrne r3, [r0]
- orrne ip, ip, r3, lsl #16
- strne ip, [r1], #4
- movne ip, r3, lsr #16
- bne 3b
- strh ip, [r1], #2
- mov pc, lr
-
-4: strb ip, [r1], #1
- mov ip, ip, lsr #8
- strh ip, [r1], #2
- mov ip, ip, lsr #16
-5: subs r2, r2, #1
- ldrne r3, [r0]
- orrne ip, ip, r3, lsl #8
- strne ip, [r1], #4
- movne ip, r3, lsr #24
- bne 5b
- strb ip, [r1], #1
- mov pc, lr
-
-6: strb ip, [r1], #1
- mov ip, ip, lsr #8
-7: subs r2, r2, #1
- ldrne r3, [r0]
- orrne ip, ip, r3, lsl #24
- strne ip, [r1], #4
- movne ip, r3, lsr #8
- bne 7b
- strb ip, [r1], #1
- mov ip, ip, lsr #8
- strh ip, [r1], #2
- mov pc, lr
-
-ENTRY(outsl)
- ioaddr r0, r0
- ands ip, r1, #3
- bne 2f
-
-1: ldr r3, [r1], #4
- str r3, [r0]
- subs r2, r2, #1
- bne 1b
- mov pc, lr
-
-2: bic r1, r1, #3
- cmp ip, #2
- ldr ip, [r1], #4
- mov ip, ip, lsr #16
- blt 4f
- bgt 5f
-
-3: ldr r3, [r1], #4
- orr ip, ip, r3, lsl #16
- str ip, [r0]
- mov ip, r3, lsr #16
- subs r2, r2, #1
- bne 3b
- mov pc, lr
-
-4: ldr r3, [r1], #4
- orr ip, ip, r3, lsl #8
- str ip, [r0]
- mov ip, r3, lsr #24
- subs r2, r2, #1
- bne 4b
- mov pc, lr
-
-5: ldr r3, [r1], #4
- orr ip, ip, r3, lsl #24
- str ip, [r0]
- mov ip, r3, lsr #8
- subs r2, r2, #1
- bne 5b
- mov pc, lr
-
- /* Nobody could say these are optimal, but not to worry. */
-
-ENTRY(outswb)
- mov r2, r2, lsr #1
-ENTRY(outsw)
- ioaddr r0, r0
-1: subs r2, r2, #1
- ldrgeh r3, [r1], #2
- strgeh r3, [r0]
- bgt 1b
- mov pc, lr
-
-ENTRY(inswb)
- mov r2, r2, lsr #1
-ENTRY(insw)
- stmfd sp!, {r4, r5, lr}
- ioaddr r0, r0
- @ + 8 + 9 +10 +11 +12 +13 +14 +15 +16 +17
- subs ip, r2, #8
- blo too_little
- @ + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
- ands lr, r1, #3 @ check alignment
- beq 1f
-
- ldrh r3, [r0]
- strh r3, [r1], #2
- sub ip, ip, #1
- cmn ip, #8
- blo too_little
-
-1: ldrh r2, [r0]
- ldrh r3, [r0]
- orr r2, r2, r3, lsl #16
- ldrh r3, [r0]
- ldrh r4, [r0]
- orr r3, r3, r4, lsl #16
- ldrh r4, [r0]
- ldrh r5, [r0]
- orr r4, r4, r5, lsl #16
- ldrh r5, [r0]
- ldrh lr, [r0]
- orr r5, r5, lr, lsl #16
- stmia r1!, {r2, r3, r4, r5}
- subs ip, ip, #8
- @ - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 + 0 + 1
- bhs 1b
- @ - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 8 - 7
- cmn ip, #4
- ldrhsh r2, [r0] @ ... ... ... ... - 4 - 3 - 2 - 1 ... ...
- ldrhsh r3, [r0]
- orrhs r2, r2, r3, lsl #16
- ldrhsh r3, [r0]
- ldrhsh r4, [r0]
- orrhs r3, r3, r4, lsl #16
- stmhsia r1!, {r2, r3}
-
- tst ip, #2
- ldrneh r2, [r0] @ ... ... - 6 - 5 ... ... - 2 - 1 ... ...
- ldrneh r3, [r0]
- orrne r2, r2, r3, lsl #16
- strne r2, [r1], #4
-
- tst ip, #1
- ldrneh r2, [r0]
- strneh r2, [r1], #2
-
- ldmfd sp!, {r4, r5, pc}
-
-too_little: subs r2, r2, #1
- ldrgeh r3, [r0]
- strgeh r3, [r1], #2
- bgt too_little
-
- ldmfd sp!, {r4, r5, pc}
-
-
-ENTRY(insb)
- ioaddr r0, r0
-1: teq r2, #0
- ldrneb r3, [r0]
- strneb r3, [r1], #1
- subne r2, r2, #1
- bne 1b
- mov pc, lr
-
-
-ENTRY(outsb)
- ioaddr r0, r0
-1: teq r2, #0
- ldrneb r3, [r1], #1
- strneb r3, [r0]
- subne r2, r2, #1
- bne 1b
- mov pc, lr
diff --git a/arch/arm/lib/io-pcio.S b/arch/arm/lib/io-pcio.S
new file mode 100644
index 000000000..f57abfc10
--- /dev/null
+++ b/arch/arm/lib/io-pcio.S
@@ -0,0 +1,38 @@
+#include <linux/linkage.h>
+#include <asm/hardware.h>
+
+ .equ pcio_high, PCIO_BASE & 0xff000000
+ .equ pcio_low, PCIO_BASE & 0x00ffffff
+
+ .macro ioaddr, rd,rn
+ add \rd, \rn, #pcio_high
+ .if pcio_low
+ add \rd, \rd, #pcio_low
+ .endif
+ .endm
+
+ENTRY(insl)
+ ioaddr r0, r0
+ b __arch_readsl
+
+ENTRY(outsl)
+ ioaddr r0, r0
+ b __arch_writesl
+
+ /* Nobody could say these are optimal, but not to worry. */
+
+ENTRY(outsw)
+ ioaddr r0, r0
+ b __arch_writesw
+
+ENTRY(insw)
+ ioaddr r0, r0
+ b __arch_readsw
+
+ENTRY(insb)
+ ioaddr r0, r0
+ b __arch_readsb
+
+ENTRY(outsb)
+ ioaddr r0, r0
+ b __arch_writesb
diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S
new file mode 100644
index 000000000..23cca8929
--- /dev/null
+++ b/arch/arm/lib/io-readsb.S
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.insb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1], #1
+ subs r2, r2, ip
+ bne .insb_aligned
+
+ENTRY(__arch_readsb)
+ ands ip, r1, #3
+ bne .insb_align
+
+.insb_aligned: stmfd sp!, {r4 - r6, lr}
+
+ subs r2, r2, #16
+ bmi .insb_no_16
+
+.insb_16_lp: ldrb r3, [r0]
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #8
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #16
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #24
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #8
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #16
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #24
+ ldrb r5, [r0]
+ ldrb r6, [r0]
+ orr r5, r5, r6, lsl #8
+ ldrb r6, [r0]
+ orr r5, r5, r6, lsl #16
+ ldrb r6, [r0]
+ orr r5, r5, r6, lsl #24
+ ldrb r6, [r0]
+ ldrb ip, [r0]
+ orr r6, r6, ip, lsl #8
+ ldrb ip, [r0]
+ orr r6, r6, ip, lsl #16
+ ldrb ip, [r0]
+ orr r6, r6, ip, lsl #24
+ stmia r1!, {r3 - r6}
+ subs r2, r2, #16
+ bpl .insb_16_lp
+
+ tst r2, #15
+ LOADREGS(eqfd, sp!, {r4 - r6, pc})
+
+.insb_no_16: tst r2, #8
+ beq .insb_no_8
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #8
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #16
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #24
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #8
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #16
+ ldrb r5, [r0]
+ orr r4, r4, r5, lsl #24
+ stmia r1!, {r3, r4}
+
+.insb_no_8: tst r2, #4
+ bne .insb_no_4
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #8
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #16
+ ldrb r4, [r0]
+ orr r3, r3, r4, lsl #24
+ str r3, [r1], #4
+
+.insb_no_4: ands r2, r2, #3
+ LOADREGS(eqfd, sp!, {r4 - r6, pc})
+ cmp r2, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1]
+ LOADREGS(fd, sp!, {r4 - r6, pc})
diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S
new file mode 100644
index 000000000..530175485
--- /dev/null
+++ b/arch/arm/lib/io-readsl.S
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+ENTRY(__arch_readsl)
+ ands ip, r1, #3
+ bne 2f
+
+1: ldr r3, [r0]
+ str r3, [r1], #4
+ subs r2, r2, #1
+ bne 1b
+ mov pc, lr
+
+2: cmp ip, #2
+ ldr ip, [r0]
+ blt 4f
+ bgt 6f
+
+ strh ip, [r1], #2
+ mov ip, ip, lsr #16
+3: subs r2, r2, #1
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lsl #16
+ strne ip, [r1], #4
+ movne ip, r3, lsr #16
+ bne 3b
+ strh ip, [r1], #2
+ mov pc, lr
+
+4: strb ip, [r1], #1
+ mov ip, ip, lsr #8
+ strh ip, [r1], #2
+ mov ip, ip, lsr #16
+5: subs r2, r2, #1
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lsl #8
+ strne ip, [r1], #4
+ movne ip, r3, lsr #24
+ bne 5b
+ strb ip, [r1], #1
+ mov pc, lr
+
+6: strb ip, [r1], #1
+ mov ip, ip, lsr #8
+7: subs r2, r2, #1
+ ldrne r3, [r0]
+ orrne ip, ip, r3, lsl #24
+ strne ip, [r1], #4
+ movne ip, r3, lsr #8
+ bne 7b
+ strb ip, [r1], #1
+ mov ip, ip, lsr #8
+ strh ip, [r1], #2
+ mov pc, lr
+
diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S
new file mode 100644
index 000000000..65fb94e2f
--- /dev/null
+++ b/arch/arm/lib/io-readsw-armv3.S
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.insw_bad_alignment:
+ adr r0, .insw_bad_align_msg
+ mov r2, lr
+ b SYMBOL_NAME(panic)
+.insw_bad_align_msg:
+ .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.insw_align: tst r1, #1
+ bne .insw_bad_alignment
+
+ ldr r3, [r0]
+ strb r3, [r1], #1
+ mov r3, r3, lsr #8
+ strb r3, [r1], #1
+
+ subs r2, r2, #1
+ RETINSTR(moveq, pc, lr)
+
+ENTRY(__arch_readsw)
+ tst r1, #3
+ bne .insw_align
+
+.insw_aligned: mov ip, #0xff
+ orr ip, ip, ip, lsl #8
+ stmfd sp!, {r4, r5, r6, lr}
+
+ subs r2, r2, #8
+ bmi .no_insw_8
+
+.insw_8_lp: ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldr r4, [r0]
+ and r4, r4, ip
+ ldr r5, [r0]
+ orr r4, r4, r5, lsl #16
+
+ ldr r5, [r0]
+ and r5, r5, ip
+ ldr r6, [r0]
+ orr r5, r5, r6, lsl #16
+
+ ldr r6, [r0]
+ and r6, r6, ip
+ ldr lr, [r0]
+ orr r6, r6, lr, lsl #16
+
+ stmia r1!, {r3 - r6}
+ subs r2, r2, #8
+ bpl .insw_8_lp
+ tst r2, #7
+ LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_insw_8: tst r2, #4
+ beq .no_insw_4
+
+ ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldr r4, [r0]
+ and r4, r4, ip
+ ldr r5, [r0]
+ orr r4, r4, r5, lsl #16
+
+ stmia r1!, {r3, r4}
+
+.no_insw_4: tst r2, #2
+ beq .no_insw_2
+
+ ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ str r3, [r1], #4
+
+.no_insw_2: tst r2, #1
+ ldrne r3, [r0]
+ strneb r3, [r1], #1
+ movne r3, r3, lsr #8
+ strneb r3, [r1]
+ LOADREGS(fd, sp!, {r4, r5, r6, pc})
+
+
diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
new file mode 100644
index 000000000..6f1750a49
--- /dev/null
+++ b/arch/arm/lib/io-readsw-armv4.S
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.insw_bad_alignment:
+ adr r0, .insw_bad_align_msg
+ mov r2, lr
+ b SYMBOL_NAME(panic)
+.insw_bad_align_msg:
+ .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.insw_align: tst r1, #1
+ bne .insw_bad_alignment
+
+ ldrh r3, [r0]
+ strh r3, [r1], #2
+
+ subs r2, r2, #1
+ RETINSTR(moveq, pc, lr)
+
+ENTRY(__arch_readsw)
+ tst r1, #3
+ bne .insw_align
+
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #8
+ bmi .no_insw_8
+
+.insw_8_lp: ldrh r3, [r0]
+ ldrh r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldrh r4, [r0]
+ ldrh r5, [r0]
+ orr r4, r4, r5, lsl #16
+
+ ldrh r5, [r0]
+ ldrh r6, [r0]
+ orr r5, r5, r6, lsl #16
+
+ ldrh ip, [r0]
+ ldrh lr, [r0]
+ orr ip, ip, lr, lsl #16
+
+ stmia r1!, {r3 - r5, ip}
+ subs r2, r2, #8
+ bpl .insw_8_lp
+ tst r2, #7
+ LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+.no_insw_8: tst r2, #4
+ beq .no_insw_4
+
+ ldrh r3, [r0]
+ ldrh r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldrh r4, [r0]
+ ldrh ip, [r0]
+ orr r4, r4, ip, lsl #16
+
+ stmia r1!, {r3, r4}
+
+.no_insw_4: tst r2, #2
+ beq .no_insw_2
+
+ ldrh r3, [r0]
+ ldrh ip, [r0]
+ orr r3, r3, ip, lsl #16
+
+ str r3, [r1], #4
+
+.no_insw_2: tst r2, #1
+ ldrneh r3, [r0]
+ strneh r3, [r1]
+ LOADREGS(fd, sp!, {r4, r5, pc})
diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S
new file mode 100644
index 000000000..b919fdaad
--- /dev/null
+++ b/arch/arm/lib/io-writesb.S
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.outsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ mov ip, r2
+ cmp ip, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0]
+ subs r2, r2, ip
+ bne .outsb_aligned
+
+ENTRY(__arch_writesb)
+ ands ip, r1, #3
+ bne .outsb_align
+
+.outsb_aligned: stmfd sp!, {r4 - r6, lr}
+
+ subs r2, r2, #16
+ bmi .outsb_no_16
+
+.outsb_16_lp: ldmia r1!, {r3 - r6}
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+
+ strb r5, [r0]
+ mov r5, r5, lsr #8
+ strb r5, [r0]
+ mov r5, r5, lsr #8
+ strb r5, [r0]
+ mov r5, r5, lsr #8
+ strb r5, [r0]
+
+ strb r6, [r0]
+ mov r6, r6, lsr #8
+ strb r6, [r0]
+ mov r6, r6, lsr #8
+ strb r6, [r0]
+ mov r6, r6, lsr #8
+ strb r6, [r0]
+ subs r2, r2, #16
+ bpl .outsb_16_lp
+
+ tst r2, #15
+ LOADREGS(eqfd, sp!, {r4 - r6, pc})
+
+.outsb_no_16: tst r2, #8
+ beq .outsb_no_8
+
+ ldmia r1, {r3, r4}
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+ mov r4, r4, lsr #8
+ strb r4, [r0]
+
+.outsb_no_8: tst r2, #4
+ bne .outsb_no_4
+
+ ldr r3, [r1], #4
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+ mov r3, r3, lsr #8
+ strb r3, [r0]
+
+.outsb_no_4: ands r2, r2, #3
+ LOADREGS(eqfd, sp!, {r4 - r6, pc})
+ cmp r2, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1]
+ strgtb r3, [r0]
+ LOADREGS(fd, sp!, {r4 - r6, pc})
diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S
new file mode 100644
index 000000000..ccda08c39
--- /dev/null
+++ b/arch/arm/lib/io-writesl.S
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+ENTRY(__arch_writesl)
+ ands ip, r1, #3
+ bne 2f
+
+1: ldr r3, [r1], #4
+ str r3, [r0]
+ subs r2, r2, #1
+ bne 1b
+ mov pc, lr
+
+2: bic r1, r1, #3
+ cmp ip, #2
+ ldr ip, [r1], #4
+ mov ip, ip, lsr #16
+ blt 4f
+ bgt 5f
+
+3: ldr r3, [r1], #4
+ orr ip, ip, r3, lsl #16
+ str ip, [r0]
+ mov ip, r3, lsr #16
+ subs r2, r2, #1
+ bne 3b
+ mov pc, lr
+
+4: ldr r3, [r1], #4
+ orr ip, ip, r3, lsl #8
+ str ip, [r0]
+ mov ip, r3, lsr #24
+ subs r2, r2, #1
+ bne 4b
+ mov pc, lr
+
+5: ldr r3, [r1], #4
+ orr ip, ip, r3, lsl #24
+ str ip, [r0]
+ mov ip, r3, lsr #8
+ subs r2, r2, #1
+ bne 5b
+ mov pc, lr
+
+
diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S
new file mode 100644
index 000000000..29c94cc3d
--- /dev/null
+++ b/arch/arm/lib/io-writesw-armv3.S
@@ -0,0 +1,125 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.outsw_bad_alignment:
+ adr r0, .outsw_bad_align_msg
+ mov r2, lr
+ b SYMBOL_NAME(panic)
+.outsw_bad_align_msg:
+ .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.outsw_align: tst r1, #1
+ bne .outsw_bad_alignment
+
+ add r1, r1, #2
+
+ ldr r3, [r1, #-4]
+ mov r3, r3, lsr #16
+ orr r3, r3, r3, lsl #16
+ str r3, [r0]
+ subs r2, r2, #1
+ RETINSTR(moveq, pc, lr)
+
+ENTRY(__arch_writesw)
+ tst r1, #3
+ bne .outsw_align
+
+.outsw_aligned: stmfd sp!, {r4, r5, r6, lr}
+
+ subs r2, r2, #8
+ bmi .no_outsw_8
+.outsw_8_lp: ldmia r1!, {r3, r4, r5, r6}
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r4, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r4, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r5, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r5, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r6, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r6, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ subs r2, r2, #8
+ bpl .outsw_8_lp
+ tst r2, #7
+ LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_outsw_8: tst r2, #4
+ beq .no_outsw_4
+
+ ldmia r1!, {r3, r4}
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r4, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r4, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+.no_outsw_4: tst r2, #2
+ beq .no_outsw_2
+
+ ldr r3, [r1], #4
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+.no_outsw_2: tst r2, #1
+
+ ldrne r3, [r1]
+
+ movne ip, r3, lsl #16
+ orrne ip, ip, ip, lsr #16
+ strne ip, [r0]
+
+ LOADREGS(fd, sp!, {r4, r5, r6, pc})
+
+
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
new file mode 100644
index 000000000..0f96d1325
--- /dev/null
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.outsw_bad_alignment:
+ adr r0, .outsw_bad_align_msg
+ mov r2, lr
+ b SYMBOL_NAME(panic)
+.outsw_bad_align_msg:
+ .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.outsw_align: tst r1, #1
+ bne .outsw_bad_alignment
+
+ ldrh r3, [r1], #2
+ strh r3, [r0]
+
+ subs r2, r2, #1
+ RETINSTR(moveq, pc, lr)
+
+ENTRY(__arch_writesw)
+ tst r1, #3
+ bne .outsw_align
+
+ subs r2, r2, #8
+ bmi .no_outsw_8
+
+ stmfd sp!, {r4, r5, lr}
+
+.outsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
+
+ strh r3, [r0]
+ mov r3, r3, lsr #16
+ strh r3, [r0]
+ strh r4, [r0]
+ mov r4, r4, lsr #16
+ strh r4, [r0]
+ strh r5, [r0]
+ mov r5, r5, lsr #16
+ strh r5, [r0]
+ strh ip, [r0]
+ mov ip, ip, lsr #16
+ strh ip, [r0]
+
+ subs r2, r2, #8
+ bpl .outsw_8_lp
+ ldmfd sp!, {r4, r5, lr}
+ tst r2, #7
+ RETINSTR(moveq, pc, lr)
+
+.no_outsw_8: tst r2, #4
+ ldmneia r1!, {r3, ip}
+ strneh r3, [r0]
+ movne r3, r3, lsr #16
+ strneh r3, [r0]
+ strneh ip, [r0]
+ movne ip, ip, lsr #16
+ strneh ip, [r0]
+ tst r2, #2
+ ldrne r3, [r1], #4
+ strneh r3, [r0]
+ movne r3, r3, lsr #16
+ strneh r3, [r0]
+ tst r2, #1
+ ldrneh r3, [r1]
+ strneh r3, [r0]
+ RETINSTR(mov, pc, lr)
+
+