OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [block/] [mfm.S] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
@ Read/Write DMA code for the ST506/MFM hard drive controllers on the A400
2
@   motherboard on ST506 podules.
3
@ (c) David Alan Gilbert (gilbertd@cs.man.ac.uk) 1996
4
 
5
#include 
6
 
7
_hdc63463_irqdata:
8
@ Controller base address
9
  .global _hdc63463_baseaddress
10
_hdc63463_baseaddress:
11
  .word 0
12
 
13
  .global _hdc63463_irqpolladdress
14
_hdc63463_irqpolladdress:
15
  .word 0
16
 
17
  .global _hdc63463_irqpollmask
18
_hdc63463_irqpollmask:
19
  .word 0
20
 
21
@ where to read/write data  from the kernel data space
22
  .global _hdc63463_dataptr
23
_hdc63463_dataptr:
24
  .word 0
25
 
26
@ Number of bytes left to transfer
27
  .global _hdc63463_dataleft
28
_hdc63463_dataleft:
29
  .word 0
30
 
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
36
_hdc63463_writedma:
37
  stmfd sp!,{r4-r7}
38
  adr r5,_hdc63463_irqdata
39
  ldmia r5,{r0,r1,r2,r3,r4}
40
 
41
 
42
writedma_again:
43
 
44
  @ test number of remaining bytes to transfer
45
  cmp r4,#0
46
  beq writedma_end
47
  bmi writedma_end
48
 
49
  @ Check the hdc is interrupting
50
  ldrb r5,[r1,#0]
51
  tst r5,r2
52
  beq writedma_end
53
 
54
  @ Transfer a block of upto 256 bytes
55
  cmp r4,#256
56
  movlt r7,r4
57
  movge r7,#256
58
 
59
  @ Check the hdc is still busy and command has not ended and no errors
60
  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status
61
  @ think we should continue DMA until it drops busy - perhaps this was
62
  @ the main problem with corrected errors causing a hang
63
  @tst r5,#0x3c00        @ Test for things which should be off
64
  @bne writedma_end
65
  and r5,r5,#0x8000        @ This is test for things which should be on: Busy
66
  cmp r5,#0x8000
67
  bne writedma_end
68
 
69
  @ Bytes remaining at end
70
  sub r4,r4,r7
71
 
72
  @ HDC Write register location
73
  add r0,r0,#32+8
74
 
75
writedma_loop:
76
  @ OK - pretty sure we should be doing this
77
 
78
  ldr r5,[r3],#4          @ Get a word to be written
79
  @ get bottom half to be sent first
80
  mov r6,r5,lsl#16        @ Separate the first 2 bytes
81
  orr r2,r6,r6,lsr #16    @ Duplicate them in the bottom half of the word
82
  @ now the top half
83
  mov r6,r5,lsr#16        @ Get 2nd 2 bytes
84
  orr r6,r6,r6,lsl#16     @ Duplicate
85
  @str r6,[r0]       @ to hdc
86
  stmia r0,{r2,r6}
87
  subs r7,r7,#4           @ Dec. number of bytes left
88
  bne writedma_loop
89
 
90
  @ If we were too slow we had better go through again - DAG - took out with new interrupt routine
91
  @ sub r0,r0,#32+8
92
  @ adr r2,_hdc63463_irqdata
93
  @ ldr r2,[r2,#8]
94
  @ b writedma_again
95
 
96
writedma_end:
97
  adr r5,_hdc63463_irqdata+12
98
  stmia r5,{r3,r4}
99
  ldmfd sp!,{r4-r7}
100
  RETINSTR(mov,pc,lr)
101
 
102
@ -------------------------------------------------------------------------
103
@ hdc63463_readdma: DMA from controller to host
104
@  internal reg usage: r0=hdc base address, r1=irq poll address, r2=poll mask
105
@                      r3=data ptr, r4=data left, r5,r6=temporary
106
  .global _hdc63463_readdma
107
_hdc63463_readdma:
108
  stmfd sp!,{r4-r7}
109
  adr r5,_hdc63463_irqdata
110
  ldmia r5,{r0,r1,r2,r3,r4}
111
 
112
readdma_again:
113
  @ test number of remaining bytes to transfer
114
  cmp r4,#0
115
  beq readdma_end
116
  bmi readdma_end
117
 
118
  @ Check the hdc is interrupting
119
  ldrb r5,[r1,#0]
120
  tst r5,r2
121
  beq readdma_end
122
 
123
  @ Check the hdc is still busy and command has not ended and no errors
124
  ldr r5,[r0,#32]     @ Status reg - 16 bit - its the top few bits which are status
125
  @ think we should continue DMA until it drops busy - perhaps this was
126
  @ the main problem with corrected errors causing a hang
127
  @tst r5,#0x3c00      @ Test for things which should be off
128
  @bne readdma_end
129
  and r5,r5,#0x8000        @ This is test for things which should be on: Busy
130
  cmp r5,#0x8000
131
  bne readdma_end
132
 
133
  @ Transfer a block of upto 256 bytes
134
  cmp r4,#256
135
  movlt r7,r4
136
  movge r7,#256
137
 
138
  @ Bytes remaining at end
139
  sub r4,r4,r7
140
 
141
  @ Set a pointer to the data register in the HDC
142
  add r0,r0,#8
143
readdma_loop:
144
  @ OK - pretty sure we should be doing this
145
  ldmia r0,{r5,r6}
146
  mov r5,r5,lsl#16
147
  mov r6,r6,lsl#16
148
  orr r6,r6,r5,lsr #16
149
  str r6,[r3],#4
150
  subs r7,r7,#4        @ Decrement bytes to go
151
  bne readdma_loop
152
 
153
  @ Try reading multiple blocks - if this was fast enough then I dont think
154
  @ this should help - NO taken out DAG - new interrupt handler has
155
  @ non-consecutive memory blocks
156
  @ sub r0,r0,#8
157
  @ b readdma_again
158
 
159
readdma_end:
160
  adr r5,_hdc63463_irqdata+12
161
  stmia r5,{r3,r4}
162
  ldmfd sp!,{r4-r7}
163
  RETINSTR(mov,pc,lr)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.