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
5 #include <asm/assembler.h>
8 @ Controller base address
9 .global hdc63463_baseaddress
13 .global hdc63463_irqpolladdress
14 hdc63463_irqpolladdress:
17 .global hdc63463_irqpollmask
21 @ where to read/write data from the kernel data space
22 .global hdc63463_dataptr
26 @ Number of bytes left to transfer
27 .global hdc63463_dataleft
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
38 adr r5,hdc63463_irqdata
39 ldmia r5,{r0,r1,r2,r3,r4}
43 @ test number of remaining bytes to transfer
48 @ Check the hdc is interrupting
53 @ Transfer a block of upto 256 bytes
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
64 and r5,r5,#0x8000 @ This is test for things which should be on: Busy
68 @ Bytes remaining at end
71 @ HDC Write register location
75 @ OK - pretty sure we should be doing this
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
82 mov r6,r5,lsr#16 @ Get 2nd 2 bytes
83 orr r6,r6,r6,lsl#16 @ Duplicate
86 subs r7,r7,#4 @ Dec. number of bytes left
89 @ If we were too slow we had better go through again - DAG - took out with new interrupt routine
91 @ adr r2,hdc63463_irqdata
96 adr r5,hdc63463_irqdata+12
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
108 adr r5,hdc63463_irqdata
109 ldmia r5,{r0,r1,r2,r3,r4}
112 @ test number of remaining bytes to transfer
117 @ Check the hdc is interrupting
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
128 and r5,r5,#0x8000 @ This is test for things which should be on: Busy
132 @ Transfer a block of upto 256 bytes
137 @ Bytes remaining at end
140 @ Set a pointer to the data register in the HDC
143 @ OK - pretty sure we should be doing this
149 subs r7,r7,#4 @ Decrement bytes to go
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
159 adr r5,hdc63463_irqdata+12