1/* 2 * linux/drivers/acorn/scsi/acornscsi-io.S: Acorn SCSI card IO 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8#include <linux/linkage.h> 9 10#include <asm/assembler.h> 11#include <asm/hardware.h> 12 13#if (IO_BASE == (PCIO_BASE & 0xff000000)) 14#define ADDR(off,reg) \ 15 tst off, $0x80000000 ;\ 16 mov reg, $IO_BASE ;\ 17 orreq reg, reg, $(PCIO_BASE & 0x00ff0000) 18#else 19#define ADDR(off,reg) \ 20 tst off, $0x80000000 ;\ 21 movne reg, $IO_BASE ;\ 22 moveq reg, $(PCIO_BASE & 0xff000000) ;\ 23 orreq reg, reg, $(PCIO_BASE & 0x00ff0000) 24#endif 25 26@ Purpose: transfer a block of data from the acorn scsi card to memory 27@ Proto : void acornscsi_in(unsigned int addr_start, char *buffer, int length) 28@ Returns: nothing 29 30 .align 31ENTRY(__acornscsi_in) 32 stmfd sp!, {r4 - r7, lr} 33 bic r0, r0, #3 34 mov lr, #0xff 35 orr lr, lr, #0xff00 36acornscsi_in16lp: 37 subs r2, r2, #16 38 bmi acornscsi_in8 39 ldmia r0!, {r3, r4, r5, r6} 40 and r3, r3, lr 41 orr r3, r3, r4, lsl #16 42 and r4, r5, lr 43 orr r4, r4, r6, lsl #16 44 ldmia r0!, {r5, r6, r7, ip} 45 and r5, r5, lr 46 orr r5, r5, r6, lsl #16 47 and r6, r7, lr 48 orr r6, r6, ip, lsl #16 49 stmia r1!, {r3 - r6} 50 bne acornscsi_in16lp 51 LOADREGS(fd, sp!, {r4 - r7, pc}) 52 53acornscsi_in8: adds r2, r2, #8 54 bmi acornscsi_in4 55 ldmia r0!, {r3, r4, r5, r6} 56 and r3, r3, lr 57 orr r3, r3, r4, lsl #16 58 and r4, r5, lr 59 orr r4, r4, r6, lsl #16 60 stmia r1!, {r3 - r4} 61 LOADREGS(eqfd, sp!, {r4 - r7, pc}) 62 sub r2, r2, #8 63 64acornscsi_in4: adds r2, r2, #4 65 bmi acornscsi_in2 66 ldmia r0!, {r3, r4} 67 and r3, r3, lr 68 orr r3, r3, r4, lsl #16 69 str r3, [r1], #4 70 LOADREGS(eqfd, sp!, {r4 - r7, pc}) 71 sub r2, r2, #4 72 73acornscsi_in2: adds r2, r2, #2 74 ldr r3, [r0], #4 75 and r3, r3, lr 76 strb r3, [r1], #1 77 mov r3, r3, lsr #8 78 strplb r3, [r1], #1 79 LOADREGS(fd, sp!, {r4 - r7, pc}) 80 81@ Purpose: transfer a block of data from memory to the acorn scsi card 82@ Proto : void acornscsi_in(unsigned int addr_start, char *buffer, int length) 83@ Returns: nothing 84 85ENTRY(__acornscsi_out) 86 stmfd sp!, {r4 - r6, lr} 87 bic r0, r0, #3 88acornscsi_out16lp: 89 subs r2, r2, #16 90 bmi acornscsi_out8 91 ldmia r1!, {r4, r6, ip, lr} 92 mov r3, r4, lsl #16 93 orr r3, r3, r3, lsr #16 94 mov r4, r4, lsr #16 95 orr r4, r4, r4, lsl #16 96 mov r5, r6, lsl #16 97 orr r5, r5, r5, lsr #16 98 mov r6, r6, lsr #16 99 orr r6, r6, r6, lsl #16 100 stmia r0!, {r3, r4, r5, r6} 101 mov r3, ip, lsl #16 102 orr r3, r3, r3, lsr #16 103 mov r4, ip, lsr #16 104 orr r4, r4, r4, lsl #16 105 mov ip, lr, lsl #16 106 orr ip, ip, ip, lsr #16 107 mov lr, lr, lsr #16 108 orr lr, lr, lr, lsl #16 109 stmia r0!, {r3, r4, ip, lr} 110 bne acornscsi_out16lp 111 LOADREGS(fd, sp!, {r4 - r6, pc}) 112 113acornscsi_out8: adds r2, r2, #8 114 bmi acornscsi_out4 115 ldmia r1!, {r4, r6} 116 mov r3, r4, lsl #16 117 orr r3, r3, r3, lsr #16 118 mov r4, r4, lsr #16 119 orr r4, r4, r4, lsl #16 120 mov r5, r6, lsl #16 121 orr r5, r5, r5, lsr #16 122 mov r6, r6, lsr #16 123 orr r6, r6, r6, lsl #16 124 stmia r0!, {r3, r4, r5, r6} 125 LOADREGS(eqfd, sp!, {r4 - r6, pc}) 126 127 sub r2, r2, #8 128acornscsi_out4: adds r2, r2, #4 129 bmi acornscsi_out2 130 ldr r4, [r1], #4 131 mov r3, r4, lsl #16 132 orr r3, r3, r3, lsr #16 133 mov r4, r4, lsr #16 134 orr r4, r4, r4, lsl #16 135 stmia r0!, {r3, r4} 136 LOADREGS(eqfd, sp!, {r4 - r6, pc}) 137 138 sub r2, r2, #4 139acornscsi_out2: adds r2, r2, #2 140 ldr r3, [r1], #2 141 strb r3, [r0], #1 142 mov r3, r3, lsr #8 143 strplb r3, [r0], #1 144 LOADREGS(fd, sp!, {r4 - r6, pc}) 145 146