diff options
Diffstat (limited to 'drivers/acorn/block/fd1772dma.S')
-rw-r--r-- | drivers/acorn/block/fd1772dma.S | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/acorn/block/fd1772dma.S b/drivers/acorn/block/fd1772dma.S new file mode 100644 index 00000000000..7964435443e --- /dev/null +++ b/drivers/acorn/block/fd1772dma.S @@ -0,0 +1,100 @@ +#include <asm/hardware.h> + +@ Code for DMA with the 1772 fdc +.text + + + .global fdc1772_dataaddr +fdc1772_fiqdata: +@ Number of bytes left to DMA + .global fdc1772_bytestogo +fdc1772_bytestogo: + .word 0 +@ Place to put/get data from in DMA + .global fdc1772_dataaddr +fdc1772_dataaddr: + .word 0 + + .global fdc1772_fdc_int_done +fdc1772_fdc_int_done: + .word 0 + .global fdc1772_comendstatus +fdc1772_comendstatus: + .word 0 + +@ We hang this off DMA channel 1 + .global fdc1772_comendhandler +fdc1772_comendhandler: + mov r8,#IOC_BASE + ldrb r9,[r8,#0x34] @ IOC FIQ status + tst r9,#2 + subeqs pc,r14,#4 @ should I leave a space here + orr r9,r8,#0x10000 @ FDC base + adr r8,fdc1772_fdc_int_done + ldrb r10,[r9,#0] @ FDC status + mov r9,#1 @ Got a FIQ flag + stmia r8,{r9,r10} + subs pc,r14,#4 + + + .global fdc1772_dma_read +fdc1772_dma_read: + mov r8,#IOC_BASE + ldrb r9,[r8,#0x34] @ IOC FIQ status + tst r9,#1 + beq fdc1772_dma_read_notours + orr r8,r8,#0x10000 @ FDC base + ldrb r10,[r8,#0xc] @ Read from FDC data reg (also clears interrupt) + ldmia r11,{r8,r9} + subs r8,r8,#1 @ One less byte to go + @ If there was somewhere for this data to go then store it and update pointers + strplb r10,[r9],#1 @ Store the data and increment the pointer + stmplia r11,{r8,r9} @ Update count/pointers + @ Handle any other interrupts if there are any +fdc1772_dma_read_notours: + @ Cant branch because this code has been copied down to the FIQ vector + ldr pc,[pc,#-4] + .word fdc1772_comendhandler + .global fdc1772_dma_read_end +fdc1772_dma_read_end: + + .global fdc1772_dma_write +fdc1772_dma_write: + mov r8,#IOC_BASE + ldrb r9,[r8,#0x34] @ IOC FIQ status + tst r9,#1 + beq fdc1772_dma_write_notours + orr r8,r8,#0x10000 @ FDC base + ldmia r11,{r9,r10} + subs r9,r9,#1 @ One less byte to go + @ If there really is some data then get it, store it and update count + ldrplb r12,[r10],#1 + strplb r12,[r8,#0xc] @ write it to FDC data reg + stmplia r11,{r9,r10} @ Update count and pointer - should clear interrupt + @ Handle any other interrupts +fdc1772_dma_write_notours: + @ Cant branch because this code has been copied down to the FIQ vector + ldr pc,[pc,#-4] + .word fdc1772_comendhandler + + .global fdc1772_dma_write_end +fdc1772_dma_write_end: + + +@ Setup the FIQ R11 to point to the data and store the count, address +@ for this dma +@ R0=count +@ R1=address + .global fdc1772_setupdma +fdc1772_setupdma: + @ The big job is flipping in and out of FIQ mode + adr r2,fdc1772_fiqdata @ This is what we really came here for + stmia r2,{r0,r1} + mov r3, pc + teqp pc,#0x0c000001 @ Disable FIQs, IRQs and switch to FIQ mode + mov r0,r0 @ NOP + mov r11,r2 + teqp r3,#0 @ Normal mode + mov r0,r0 @ NOP + mov pc,r14 + |