xref: /OK3568_Linux_fs/kernel/drivers/scsi/arm/acornscsi-io.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun *  linux/drivers/acorn/scsi/acornscsi-io.S: Acorn SCSI card IO
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun#include <linux/linkage.h>
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun#include <asm/assembler.h>
8*4882a593Smuzhiyun#include <mach/hardware.h>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun#if defined(__APCS_32__)
11*4882a593Smuzhiyun#define LOADREGS(t,r,l...)	ldm##t	r, l
12*4882a593Smuzhiyun#elif defined(__APCS_26__)
13*4882a593Smuzhiyun#define LOADREGS(t,r,l...)	ldm##t	r, l##^
14*4882a593Smuzhiyun#endif
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun@ Purpose: transfer a block of data from the acorn scsi card to memory
17*4882a593Smuzhiyun@ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
18*4882a593Smuzhiyun@ Returns: nothing
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun		.align
21*4882a593SmuzhiyunENTRY(__acornscsi_in)
22*4882a593Smuzhiyun		stmfd	sp!, {r4 - r7, lr}
23*4882a593Smuzhiyun		bic	r0, r0, #3
24*4882a593Smuzhiyun		mov	lr, #0xff
25*4882a593Smuzhiyun		orr	lr, lr, #0xff00
26*4882a593Smuzhiyunacornscsi_in16lp:
27*4882a593Smuzhiyun		subs	r2, r2, #16
28*4882a593Smuzhiyun		bmi	acornscsi_in8
29*4882a593Smuzhiyun		ldmia	r0!, {r3, r4, r5, r6}
30*4882a593Smuzhiyun		and	r3, r3, lr
31*4882a593Smuzhiyun		orr	r3, r3, r4, lsl #16
32*4882a593Smuzhiyun		and 	r4, r5, lr
33*4882a593Smuzhiyun		orr	r4, r4, r6, lsl #16
34*4882a593Smuzhiyun		ldmia	r0!, {r5, r6, r7, ip}
35*4882a593Smuzhiyun		and	r5, r5, lr
36*4882a593Smuzhiyun		orr	r5, r5, r6, lsl #16
37*4882a593Smuzhiyun		and	r6, r7, lr
38*4882a593Smuzhiyun		orr	r6, r6, ip, lsl #16
39*4882a593Smuzhiyun		stmia	r1!, {r3 - r6}
40*4882a593Smuzhiyun		bne	acornscsi_in16lp
41*4882a593Smuzhiyun		LOADREGS(fd, sp!, {r4 - r7, pc})
42*4882a593Smuzhiyun
43*4882a593Smuzhiyunacornscsi_in8:	adds	r2, r2, #8
44*4882a593Smuzhiyun		bmi	acornscsi_in4
45*4882a593Smuzhiyun		ldmia	r0!, {r3, r4, r5, r6}
46*4882a593Smuzhiyun		and	r3, r3, lr
47*4882a593Smuzhiyun		orr	r3, r3, r4, lsl #16
48*4882a593Smuzhiyun		and	r4, r5, lr
49*4882a593Smuzhiyun		orr	r4, r4, r6, lsl #16
50*4882a593Smuzhiyun		stmia	r1!, {r3 - r4}
51*4882a593Smuzhiyun		LOADREGS(eqfd, sp!, {r4 - r7, pc})
52*4882a593Smuzhiyun		sub	r2, r2, #8
53*4882a593Smuzhiyun
54*4882a593Smuzhiyunacornscsi_in4:	adds	r2, r2, #4
55*4882a593Smuzhiyun		bmi	acornscsi_in2
56*4882a593Smuzhiyun		ldmia	r0!, {r3, r4}
57*4882a593Smuzhiyun		and	r3, r3, lr
58*4882a593Smuzhiyun		orr	r3, r3, r4, lsl #16
59*4882a593Smuzhiyun		str	r3, [r1], #4
60*4882a593Smuzhiyun		LOADREGS(eqfd, sp!, {r4 - r7, pc})
61*4882a593Smuzhiyun		sub	r2, r2, #4
62*4882a593Smuzhiyun
63*4882a593Smuzhiyunacornscsi_in2:	adds	r2, r2, #2
64*4882a593Smuzhiyun		ldr	r3, [r0], #4
65*4882a593Smuzhiyun		and	r3, r3, lr
66*4882a593Smuzhiyun		strb	r3, [r1], #1
67*4882a593Smuzhiyun		mov	r3, r3, lsr #8
68*4882a593Smuzhiyun		strplb	r3, [r1], #1
69*4882a593Smuzhiyun		LOADREGS(fd, sp!, {r4 - r7, pc})
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun@ Purpose: transfer a block of data from memory to the acorn scsi card
72*4882a593Smuzhiyun@ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
73*4882a593Smuzhiyun@ Returns: nothing
74*4882a593Smuzhiyun
75*4882a593SmuzhiyunENTRY(__acornscsi_out)
76*4882a593Smuzhiyun		stmfd	sp!, {r4 - r6, lr}
77*4882a593Smuzhiyun		bic	r0, r0, #3
78*4882a593Smuzhiyunacornscsi_out16lp:
79*4882a593Smuzhiyun		subs	r2, r2, #16
80*4882a593Smuzhiyun		bmi	acornscsi_out8
81*4882a593Smuzhiyun		ldmia	r1!, {r4, r6, ip, lr}
82*4882a593Smuzhiyun		mov	r3, r4, lsl #16
83*4882a593Smuzhiyun		orr	r3, r3, r3, lsr #16
84*4882a593Smuzhiyun		mov	r4, r4, lsr #16
85*4882a593Smuzhiyun		orr	r4, r4, r4, lsl #16
86*4882a593Smuzhiyun		mov	r5, r6, lsl #16
87*4882a593Smuzhiyun		orr	r5, r5, r5, lsr #16
88*4882a593Smuzhiyun		mov	r6, r6, lsr #16
89*4882a593Smuzhiyun		orr	r6, r6, r6, lsl #16
90*4882a593Smuzhiyun		stmia	r0!, {r3, r4, r5, r6}
91*4882a593Smuzhiyun		mov	r3, ip, lsl #16
92*4882a593Smuzhiyun		orr	r3, r3, r3, lsr #16
93*4882a593Smuzhiyun		mov	r4, ip, lsr #16
94*4882a593Smuzhiyun		orr	r4, r4, r4, lsl #16
95*4882a593Smuzhiyun		mov	ip, lr, lsl #16
96*4882a593Smuzhiyun		orr	ip, ip, ip, lsr #16
97*4882a593Smuzhiyun		mov	lr, lr, lsr #16
98*4882a593Smuzhiyun		orr	lr, lr, lr, lsl #16
99*4882a593Smuzhiyun		stmia	r0!, {r3, r4, ip, lr}
100*4882a593Smuzhiyun		bne	acornscsi_out16lp
101*4882a593Smuzhiyun		LOADREGS(fd, sp!, {r4 - r6, pc})
102*4882a593Smuzhiyun
103*4882a593Smuzhiyunacornscsi_out8:	adds	r2, r2, #8
104*4882a593Smuzhiyun		bmi	acornscsi_out4
105*4882a593Smuzhiyun		ldmia	r1!, {r4, r6}
106*4882a593Smuzhiyun		mov	r3, r4, lsl #16
107*4882a593Smuzhiyun		orr	r3, r3, r3, lsr #16
108*4882a593Smuzhiyun		mov	r4, r4, lsr #16
109*4882a593Smuzhiyun		orr	r4, r4, r4, lsl #16
110*4882a593Smuzhiyun		mov	r5, r6, lsl #16
111*4882a593Smuzhiyun		orr	r5, r5, r5, lsr #16
112*4882a593Smuzhiyun		mov	r6, r6, lsr #16
113*4882a593Smuzhiyun		orr	r6, r6, r6, lsl #16
114*4882a593Smuzhiyun		stmia	r0!, {r3, r4, r5, r6}
115*4882a593Smuzhiyun		LOADREGS(eqfd, sp!, {r4 - r6, pc})
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun		sub	r2, r2, #8
118*4882a593Smuzhiyunacornscsi_out4:	adds	r2, r2, #4
119*4882a593Smuzhiyun		bmi	acornscsi_out2
120*4882a593Smuzhiyun		ldr	r4, [r1], #4
121*4882a593Smuzhiyun		mov	r3, r4, lsl #16
122*4882a593Smuzhiyun		orr	r3, r3, r3, lsr #16
123*4882a593Smuzhiyun		mov	r4, r4, lsr #16
124*4882a593Smuzhiyun		orr	r4, r4, r4, lsl #16
125*4882a593Smuzhiyun		stmia	r0!, {r3, r4}
126*4882a593Smuzhiyun		LOADREGS(eqfd, sp!, {r4 - r6, pc})
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun		sub	r2, r2, #4
129*4882a593Smuzhiyunacornscsi_out2:	adds	r2, r2, #2
130*4882a593Smuzhiyun		ldr	r3, [r1], #2
131*4882a593Smuzhiyun		strb	r3, [r0], #1
132*4882a593Smuzhiyun		mov	r3, r3, lsr #8
133*4882a593Smuzhiyun		strplb	r3, [r0], #1
134*4882a593Smuzhiyun		LOADREGS(fd, sp!, {r4 - r6, pc})
135*4882a593Smuzhiyun
136