⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfm.s

📁 linux-2.6.15.6
💻 S
字号:
@ Read/Write DMA code for the ST506/MFM hard drive controllers on the A400 Acorn Archimedes@   motherboard and on ST506 expansion podules.@ (c) David Alan Gilbert (linux@treblig.org) 1996-1999#include <asm/assembler.h> hdc63463_irqdata:@ Controller base address  .global hdc63463_baseaddresshdc63463_baseaddress:  .word 0  .global hdc63463_irqpolladdresshdc63463_irqpolladdress:  .word 0   .global hdc63463_irqpollmaskhdc63463_irqpollmask:  .word 0@ where to read/write data  from the kernel data space  .global hdc63463_dataptrhdc63463_dataptr:  .word 0@ Number of bytes left to transfer  .global hdc63463_datalefthdc63463_dataleft:  .word 0@ -------------------------------------------------------------------------@ hdc63463_writedma: DMA from host to controller@  internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask@                      r3=data ptr, r4=data left, r5,r6=temporary  .global hdc63463_writedmahdc63463_writedma:  stmfd sp!,{r4-r7}  adr r5,hdc63463_irqdata  ldmia r5,{r0,r1,r2,r3,r4}writedma_again:  @ test number of remaining bytes to transfer  cmp r4,#0  beq writedma_end  bmi writedma_end  @ Check the hdc is interrupting  ldrb r5,[r1,#0]  tst r5,r2  beq writedma_end  @ Transfer a block of upto 256 bytes  cmp r4,#256  movlt r7,r4  movge r7,#256  @ Check the hdc is still busy and command has not ended and no errors  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status  @ think we should continue DMA until it drops busy - perhaps this was  @ the main problem with corrected errors causing a hang  @tst r5,#0x3c00        @ Test for things which should be off  @bne writedma_end  and r5,r5,#0x8000        @ This is test for things which should be on: Busy  cmp r5,#0x8000  bne writedma_end   @ Bytes remaining at end  sub r4,r4,r7  @ HDC Write register location  add r0,r0,#32+8writedma_loop:  @ OK - pretty sure we should be doing this  ldr r5,[r3],#4          @ Get a word to be written  @ get bottom half to be sent first  mov r6,r5,lsl#16        @ Separate the first 2 bytes  orr r2,r6,r6,lsr #16    @ Duplicate them in the bottom half of the word  @ now the top half  mov r6,r5,lsr#16        @ Get 2nd 2 bytes  orr r6,r6,r6,lsl#16     @ Duplicate  @str r6,[r0]       @ to hdc  stmia r0,{r2,r6}  subs r7,r7,#4           @ Dec. number of bytes left  bne writedma_loop  @ If we were too slow we had better go through again - DAG - took out with new interrupt routine  @ sub r0,r0,#32+8  @ adr r2,hdc63463_irqdata  @ ldr r2,[r2,#8]  @ b writedma_againwritedma_end:  adr r5,hdc63463_irqdata+12  stmia r5,{r3,r4}  ldmfd sp!,{r4-r7}  RETINSTR(mov,pc,lr)@ -------------------------------------------------------------------------@ hdc63463_readdma: DMA from controller to host@  internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask@                      r3=data ptr, r4=data left, r5,r6=temporary  .global hdc63463_readdmahdc63463_readdma:  stmfd sp!,{r4-r7}  adr r5,hdc63463_irqdata  ldmia r5,{r0,r1,r2,r3,r4}readdma_again:  @ test number of remaining bytes to transfer  cmp r4,#0  beq readdma_end  bmi readdma_end  @ Check the hdc is interrupting  ldrb r5,[r1,#0]  tst r5,r2  beq readdma_end  @ Check the hdc is still busy and command has not ended and no errors  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status  @ think we should continue DMA until it drops busy - perhaps this was  @ the main problem with corrected errors causing a hang  @tst r5,#0x3c00      @ Test for things which should be off  @bne readdma_end  and r5,r5,#0x8000        @ This is test for things which should be on: Busy  cmp r5,#0x8000  bne readdma_end   @ Transfer a block of upto 256 bytes  cmp r4,#256  movlt r7,r4  movge r7,#256  @ Bytes remaining at end  sub r4,r4,r7  @ Set a pointer to the data register in the HDC  add r0,r0,#8readdma_loop:  @ OK - pretty sure we should be doing this  ldmia r0,{r5,r6}  mov r5,r5,lsl#16  mov r6,r6,lsl#16  orr r6,r6,r5,lsr #16  str r6,[r3],#4  subs r7,r7,#4        @ Decrement bytes to go  bne readdma_loop  @ Try reading multiple blocks - if this was fast enough then I do not think  @ this should help - NO taken out DAG - new interrupt handler has  @ non-consecutive memory blocks  @ sub r0,r0,#8  @ b readdma_againreaddma_end:  adr r5,hdc63463_irqdata+12  stmia r5,{r3,r4}  ldmfd sp!,{r4-r7}  RETINSTR(mov,pc,lr)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -