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