Rev 4720 | Rev 4839 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4720 | Rev 4838 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | $Revision: 4720 $ |
8 | $Revision: 4838 $ |
9 | 9 | ||
10 | 10 | ||
11 | ; Low-level driver for HDD access |
11 | ; Low-level driver for HDD access |
12 | ; DMA support by Mario79 |
12 | ; DMA support by Mario79 |
13 | ; LBA48 support by Mario79 |
13 | ; LBA48 support by Mario79 |
14 | ;----------------------------------------------------------------------------- |
14 | ;----------------------------------------------------------------------------- |
15 | struct HD_DATA |
15 | struct HD_DATA |
16 | hdbase dd ? |
16 | hdbase dd ? |
17 | hdid dd ? |
17 | hdid dd ? |
18 | hdpos dd ? |
18 | hdpos dd ? |
19 | ends |
19 | ends |
20 | ;----------------------------------------------------------------------------- |
20 | ;----------------------------------------------------------------------------- |
21 | iglobal |
21 | iglobal |
22 | align 4 |
22 | align 4 |
23 | ide_callbacks: |
23 | ide_callbacks: |
24 | dd ide_callbacks.end - ide_callbacks ; strucsize |
24 | dd ide_callbacks.end - ide_callbacks ; strucsize |
25 | dd 0 ; no close function |
25 | dd 0 ; no close function |
26 | dd 0 ; no closemedia function |
26 | dd 0 ; no closemedia function |
27 | dd ide_querymedia |
27 | dd ide_querymedia |
28 | dd ide_read |
28 | dd ide_read |
29 | dd ide_write |
29 | dd ide_write |
30 | dd 0 ; no flush function |
30 | dd 0 ; no flush function |
31 | dd 0 ; use default cache size |
31 | dd 0 ; use default cache size |
32 | .end: |
32 | .end: |
33 | 33 | ||
34 | hd0_data HD_DATA ?, 0, 1 |
34 | hd0_data HD_DATA ?, 0, 1 |
35 | hd1_data HD_DATA ?, 0x10, 2 |
35 | hd1_data HD_DATA ?, 0x10, 2 |
36 | hd2_data HD_DATA ?, 0, 3 |
36 | hd2_data HD_DATA ?, 0, 3 |
37 | hd3_data HD_DATA ?, 0x10, 4 |
37 | hd3_data HD_DATA ?, 0x10, 4 |
38 | hd4_data HD_DATA ?, 0, 5 |
38 | hd4_data HD_DATA ?, 0, 5 |
39 | hd5_data HD_DATA ?, 0x10, 6 |
39 | hd5_data HD_DATA ?, 0x10, 6 |
40 | hd6_data HD_DATA ?, 0, 7 |
40 | hd6_data HD_DATA ?, 0, 7 |
41 | hd7_data HD_DATA ?, 0x10, 8 |
41 | hd7_data HD_DATA ?, 0x10, 8 |
42 | hd8_data HD_DATA ?, 0, 9 |
42 | hd8_data HD_DATA ?, 0, 9 |
43 | hd9_data HD_DATA ?, 0x10, 10 |
43 | hd9_data HD_DATA ?, 0x10, 10 |
44 | hd10_data HD_DATA ?, 0, 11 |
44 | hd10_data HD_DATA ?, 0, 11 |
45 | hd11_data HD_DATA ?, 0x10, 12 |
45 | hd11_data HD_DATA ?, 0x10, 12 |
46 | 46 | ||
47 | ide_mutex_table: |
47 | ide_mutex_table: |
48 | dd ide_channel1_mutex |
48 | dd ide_channel1_mutex |
49 | dd ide_channel2_mutex |
49 | dd ide_channel2_mutex |
50 | dd ide_channel3_mutex |
50 | dd ide_channel3_mutex |
51 | dd ide_channel4_mutex |
51 | dd ide_channel4_mutex |
52 | dd ide_channel5_mutex |
52 | dd ide_channel5_mutex |
53 | dd ide_channel6_mutex |
53 | dd ide_channel6_mutex |
54 | endg |
54 | endg |
55 | ;----------------------------------------------------------------------------- |
55 | ;----------------------------------------------------------------------------- |
56 | uglobal |
56 | uglobal |
57 | ide_mutex MUTEX |
57 | ide_mutex MUTEX |
58 | ide_channel1_mutex MUTEX |
58 | ide_channel1_mutex MUTEX |
59 | ide_channel2_mutex MUTEX |
59 | ide_channel2_mutex MUTEX |
60 | ide_channel3_mutex MUTEX |
60 | ide_channel3_mutex MUTEX |
61 | ide_channel4_mutex MUTEX |
61 | ide_channel4_mutex MUTEX |
62 | ide_channel5_mutex MUTEX |
62 | ide_channel5_mutex MUTEX |
63 | ide_channel6_mutex MUTEX |
63 | ide_channel6_mutex MUTEX |
64 | endg |
64 | endg |
65 | ;----------------------------------------------------------------------------- |
65 | ;----------------------------------------------------------------------------- |
66 | proc ide_read stdcall uses edi, \ |
66 | proc ide_read stdcall uses edi, \ |
67 | hd_data, buffer, startsector:qword, numsectors |
67 | hd_data, buffer, startsector:qword, numsectors |
68 | ; hd_data = pointer to hd*_data |
68 | ; hd_data = pointer to hd*_data |
69 | ; buffer = pointer to buffer for data |
69 | ; buffer = pointer to buffer for data |
70 | ; startsector = 64-bit start sector |
70 | ; startsector = 64-bit start sector |
71 | ; numsectors = pointer to number of sectors on input, |
71 | ; numsectors = pointer to number of sectors on input, |
72 | ; must be filled with number of sectors really read |
72 | ; must be filled with number of sectors really read |
73 | locals |
73 | locals |
74 | sectors_todo dd ? |
74 | sectors_todo dd ? |
75 | channel_lock dd ? |
75 | channel_lock dd ? |
76 | endl |
76 | endl |
77 | ; 1. Initialize number of sectors: get number of requested sectors |
77 | ; 1. Initialize number of sectors: get number of requested sectors |
78 | ; and say that no sectors were read yet. |
78 | ; and say that no sectors were read yet. |
79 | mov ecx, [numsectors] |
79 | mov ecx, [numsectors] |
80 | mov eax, [ecx] |
80 | mov eax, [ecx] |
81 | mov dword [ecx], 0 |
81 | mov dword [ecx], 0 |
82 | mov [sectors_todo], eax |
82 | mov [sectors_todo], eax |
83 | ; 2. Acquire the global lock. |
83 | ; 2. Acquire the global lock. |
84 | mov ecx, ide_mutex |
84 | mov ecx, ide_mutex |
85 | call mutex_lock |
85 | call mutex_lock |
86 | 86 | ||
87 | mov ecx, [hd_data] |
87 | mov ecx, [hd_data] |
88 | mov ecx, [ecx+HD_DATA.hdpos] |
88 | mov ecx, [ecx+HD_DATA.hdpos] |
89 | dec ecx |
89 | dec ecx |
90 | shr ecx, 1 |
90 | shr ecx, 1 |
91 | shl ecx, 2 |
91 | shl ecx, 2 |
92 | mov ecx, [ecx + ide_mutex_table] |
92 | mov ecx, [ecx + ide_mutex_table] |
93 | mov [channel_lock], ecx |
93 | mov [channel_lock], ecx |
94 | call mutex_lock |
94 | call mutex_lock |
95 | ; 3. Convert parameters to the form suitable for worker procedures. |
95 | ; 3. Convert parameters to the form suitable for worker procedures. |
96 | ; Underlying procedures do not know about 64-bit sectors. |
96 | ; Underlying procedures do not know about 64-bit sectors. |
97 | ; Worker procedures use global variables and edi for [buffer]. |
97 | ; Worker procedures use global variables and edi for [buffer]. |
98 | cmp dword [startsector+4], 0 |
98 | cmp dword [startsector+4], 0 |
99 | jnz .fail |
99 | jnz .fail |
100 | 100 | ||
101 | and [hd_error], 0 |
101 | and [hd_error], 0 |
102 | mov ecx, [hd_data] |
102 | mov ecx, [hd_data] |
103 | mov eax, [ecx+HD_DATA.hdbase] |
103 | mov eax, [ecx+HD_DATA.hdbase] |
104 | mov [hdbase], eax |
104 | mov [hdbase], eax |
105 | mov eax, [ecx+HD_DATA.hdid] |
105 | mov eax, [ecx+HD_DATA.hdid] |
106 | mov [hdid], eax |
106 | mov [hdid], eax |
107 | mov eax, [ecx+HD_DATA.hdpos] |
107 | mov eax, [ecx+HD_DATA.hdpos] |
108 | mov [hdpos], eax |
108 | mov [hdpos], eax |
109 | mov eax, dword [startsector] |
109 | mov eax, dword [startsector] |
110 | mov edi, [buffer] |
110 | mov edi, [buffer] |
111 | ; 4. Worker procedures take one sectors per time, so loop over all sectors to read. |
111 | ; 4. Worker procedures take one sectors per time, so loop over all sectors to read. |
112 | .sectors_loop: |
112 | .sectors_loop: |
113 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
113 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
114 | cmp [allow_dma_access], 2 |
114 | cmp [allow_dma_access], 2 |
115 | ja .nodma |
115 | ja .nodma |
116 | 116 | ||
117 | push eax ecx |
117 | push eax ecx |
118 | mov ecx, [hdpos] |
118 | mov ecx, [hdpos] |
119 | dec ecx |
119 | dec ecx |
120 | shr ecx, 2 |
120 | shr ecx, 2 |
121 | imul ecx, sizeof.IDE_DATA |
121 | imul ecx, sizeof.IDE_DATA |
122 | add ecx, IDE_controller_1 |
122 | add ecx, IDE_controller_1 |
123 | mov [IDE_controller_pointer], ecx |
123 | mov [IDE_controller_pointer], ecx |
124 | 124 | ||
125 | mov eax, [hdpos] |
125 | mov eax, [hdpos] |
126 | dec eax |
126 | dec eax |
127 | and eax, 11b |
127 | and eax, 11b |
128 | shr eax, 1 |
128 | shr eax, 1 |
129 | add eax, ecx |
129 | add eax, ecx |
130 | cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 |
130 | cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 |
131 | pop ecx eax |
131 | pop ecx eax |
132 | jnz .nodma |
132 | jnz .nodma |
133 | 133 | ||
134 | call hd_read_dma |
134 | call hd_read_dma |
135 | jmp @f |
135 | jmp @f |
136 | ;-------------------------------------- |
136 | ;-------------------------------------- |
137 | .nodma: |
137 | .nodma: |
138 | call hd_read_pio |
138 | call hd_read_pio |
139 | ;-------------------------------------- |
139 | ;-------------------------------------- |
140 | @@: |
140 | @@: |
141 | cmp [hd_error], 0 |
141 | cmp [hd_error], 0 |
142 | jnz .fail |
142 | jnz .fail |
143 | 143 | ||
144 | mov ecx, [numsectors] |
144 | mov ecx, [numsectors] |
145 | inc dword [ecx] ; one more sector is read |
145 | inc dword [ecx] ; one more sector is read |
146 | dec [sectors_todo] |
146 | dec [sectors_todo] |
147 | jz .done |
147 | jz .done |
148 | 148 | ||
149 | inc eax |
149 | inc eax |
150 | jnz .sectors_loop |
150 | jnz .sectors_loop |
151 | ;-------------------------------------- |
151 | ;-------------------------------------- |
152 | ; 5. Loop is done, either due to error or because everything is done. |
152 | ; 5. Loop is done, either due to error or because everything is done. |
153 | ; Release the global lock and return the corresponding status. |
153 | ; Release the global lock and return the corresponding status. |
154 | .fail: |
154 | .fail: |
155 | mov ecx, [channel_lock] |
155 | mov ecx, [channel_lock] |
156 | call mutex_unlock |
156 | call mutex_unlock |
157 | 157 | ||
158 | mov ecx, ide_mutex |
158 | mov ecx, ide_mutex |
159 | call mutex_unlock |
159 | call mutex_unlock |
160 | 160 | ||
161 | or eax, -1 |
161 | or eax, -1 |
162 | ret |
162 | ret |
163 | ;-------------------------------------- |
163 | ;-------------------------------------- |
164 | .done: |
164 | .done: |
165 | mov ecx, [channel_lock] |
165 | mov ecx, [channel_lock] |
166 | call mutex_unlock |
166 | call mutex_unlock |
167 | 167 | ||
168 | mov ecx, ide_mutex |
168 | mov ecx, ide_mutex |
169 | call mutex_unlock |
169 | call mutex_unlock |
170 | 170 | ||
171 | xor eax, eax |
171 | xor eax, eax |
172 | ret |
172 | ret |
173 | endp |
173 | endp |
174 | ;----------------------------------------------------------------------------- |
174 | ;----------------------------------------------------------------------------- |
175 | proc ide_write stdcall uses esi edi, \ |
175 | proc ide_write stdcall uses esi edi, \ |
176 | hd_data, buffer, startsector:qword, numsectors |
176 | hd_data, buffer, startsector:qword, numsectors |
177 | ; hd_data = pointer to hd*_data |
177 | ; hd_data = pointer to hd*_data |
178 | ; buffer = pointer to buffer with data |
178 | ; buffer = pointer to buffer with data |
179 | ; startsector = 64-bit start sector |
179 | ; startsector = 64-bit start sector |
180 | ; numsectors = pointer to number of sectors on input, |
180 | ; numsectors = pointer to number of sectors on input, |
181 | ; must be filled with number of sectors really written |
181 | ; must be filled with number of sectors really written |
182 | locals |
182 | locals |
183 | sectors_todo dd ? |
183 | sectors_todo dd ? |
184 | channel_lock dd ? |
184 | channel_lock dd ? |
185 | endl |
185 | endl |
186 | ; 1. Initialize number of sectors: get number of requested sectors |
186 | ; 1. Initialize number of sectors: get number of requested sectors |
187 | ; and say that no sectors were read yet. |
187 | ; and say that no sectors were read yet. |
188 | mov ecx, [numsectors] |
188 | mov ecx, [numsectors] |
189 | mov eax, [ecx] |
189 | mov eax, [ecx] |
190 | mov dword [ecx], 0 |
190 | mov dword [ecx], 0 |
191 | mov [sectors_todo], eax |
191 | mov [sectors_todo], eax |
192 | ; 2. Acquire the global lock. |
192 | ; 2. Acquire the global lock. |
193 | mov ecx, ide_mutex |
193 | mov ecx, ide_mutex |
194 | call mutex_lock |
194 | call mutex_lock |
195 | 195 | ||
196 | mov ecx, [hd_data] |
196 | mov ecx, [hd_data] |
197 | mov ecx, [ecx+HD_DATA.hdpos] |
197 | mov ecx, [ecx+HD_DATA.hdpos] |
198 | dec ecx |
198 | dec ecx |
199 | shr ecx, 1 |
199 | shr ecx, 1 |
200 | shl ecx, 2 |
200 | shl ecx, 2 |
201 | mov ecx, [ecx + ide_mutex_table] |
201 | mov ecx, [ecx + ide_mutex_table] |
202 | mov [channel_lock], ecx |
202 | mov [channel_lock], ecx |
203 | call mutex_lock |
203 | call mutex_lock |
204 | ; 3. Convert parameters to the form suitable for worker procedures. |
204 | ; 3. Convert parameters to the form suitable for worker procedures. |
205 | ; Underlying procedures do not know about 64-bit sectors. |
205 | ; Underlying procedures do not know about 64-bit sectors. |
206 | ; Worker procedures use global variables and esi for [buffer]. |
206 | ; Worker procedures use global variables and esi for [buffer]. |
207 | cmp dword [startsector+4], 0 |
207 | cmp dword [startsector+4], 0 |
208 | jnz .fail |
208 | jnz .fail |
209 | 209 | ||
210 | and [hd_error], 0 |
210 | and [hd_error], 0 |
211 | mov ecx, [hd_data] |
211 | mov ecx, [hd_data] |
212 | mov eax, [ecx+HD_DATA.hdbase] |
212 | mov eax, [ecx+HD_DATA.hdbase] |
213 | mov [hdbase], eax |
213 | mov [hdbase], eax |
214 | mov eax, [ecx+HD_DATA.hdid] |
214 | mov eax, [ecx+HD_DATA.hdid] |
215 | mov [hdid], eax |
215 | mov [hdid], eax |
216 | mov eax, [ecx+HD_DATA.hdpos] |
216 | mov eax, [ecx+HD_DATA.hdpos] |
217 | mov [hdpos], eax |
217 | mov [hdpos], eax |
218 | mov esi, [buffer] |
218 | mov esi, [buffer] |
219 | lea edi, [startsector] |
219 | lea edi, [startsector] |
220 | mov [cache_chain_ptr], edi |
220 | mov [cache_chain_ptr], edi |
221 | ; 4. Worker procedures take max 16 sectors per time, |
221 | ; 4. Worker procedures take max 16 sectors per time, |
222 | ; loop until all sectors will be processed. |
222 | ; loop until all sectors will be processed. |
223 | .sectors_loop: |
223 | .sectors_loop: |
224 | mov ecx, 16 |
224 | mov ecx, 16 |
225 | cmp ecx, [sectors_todo] |
225 | cmp ecx, [sectors_todo] |
226 | jbe @f |
226 | jbe @f |
227 | 227 | ||
228 | mov ecx, [sectors_todo] |
228 | mov ecx, [sectors_todo] |
229 | ;-------------------------------------- |
229 | ;-------------------------------------- |
230 | @@: |
230 | @@: |
231 | mov [cache_chain_size], cl |
231 | mov [cache_chain_size], cl |
232 | ; DMA write is permitted only if [allow_dma_access]=1 |
232 | ; DMA write is permitted only if [allow_dma_access]=1 |
233 | cmp [allow_dma_access], 2 |
233 | cmp [allow_dma_access], 2 |
234 | jae .nodma |
234 | jae .nodma |
235 | 235 | ||
236 | push eax ecx |
236 | push eax ecx |
237 | mov ecx, [hdpos] |
237 | mov ecx, [hdpos] |
238 | dec ecx |
238 | dec ecx |
239 | shr ecx, 2 |
239 | shr ecx, 2 |
240 | imul ecx, sizeof.IDE_DATA |
240 | imul ecx, sizeof.IDE_DATA |
241 | add ecx, IDE_controller_1 |
241 | add ecx, IDE_controller_1 |
242 | mov [IDE_controller_pointer], ecx |
242 | mov [IDE_controller_pointer], ecx |
243 | 243 | ||
244 | mov eax, [hdpos] |
244 | mov eax, [hdpos] |
245 | dec eax |
245 | dec eax |
246 | and eax, 11b |
246 | and eax, 11b |
247 | shr eax, 1 |
247 | shr eax, 1 |
248 | add eax, ecx |
248 | add eax, ecx |
249 | cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 |
249 | cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 |
250 | pop ecx eax |
250 | pop ecx eax |
251 | jnz .nodma |
251 | jnz .nodma |
252 | 252 | ||
253 | call cache_write_dma |
253 | call cache_write_dma |
254 | jmp .common |
254 | jmp .common |
255 | ;-------------------------------------- |
255 | ;-------------------------------------- |
256 | .nodma: |
256 | .nodma: |
257 | mov [cache_chain_size], 1 |
257 | mov [cache_chain_size], 1 |
258 | call cache_write_pio |
258 | call cache_write_pio |
259 | ;-------------------------------------- |
259 | ;-------------------------------------- |
260 | .common: |
260 | .common: |
261 | cmp [hd_error], 0 |
261 | cmp [hd_error], 0 |
262 | jnz .fail |
262 | jnz .fail |
263 | 263 | ||
264 | movzx ecx, [cache_chain_size] |
264 | movzx ecx, [cache_chain_size] |
265 | mov eax, [numsectors] |
265 | mov eax, [numsectors] |
266 | add [eax], ecx |
266 | add [eax], ecx |
267 | sub [sectors_todo], ecx |
267 | sub [sectors_todo], ecx |
268 | jz .done |
268 | jz .done |
269 | 269 | ||
270 | add [edi], ecx |
270 | add [edi], ecx |
271 | jc .fail |
271 | jc .fail |
272 | 272 | ||
273 | shl ecx, 9 |
273 | shl ecx, 9 |
274 | add esi, ecx |
274 | add esi, ecx |
275 | jmp .sectors_loop |
275 | jmp .sectors_loop |
276 | ;-------------------------------------- |
276 | ;-------------------------------------- |
277 | ; 5. Loop is done, either due to error or because everything is done. |
277 | ; 5. Loop is done, either due to error or because everything is done. |
278 | ; Release the global lock and return the corresponding status. |
278 | ; Release the global lock and return the corresponding status. |
279 | .fail: |
279 | .fail: |
280 | mov ecx, [channel_lock] |
280 | mov ecx, [channel_lock] |
281 | call mutex_unlock |
281 | call mutex_unlock |
282 | 282 | ||
283 | mov ecx, ide_mutex |
283 | mov ecx, ide_mutex |
284 | call mutex_unlock |
284 | call mutex_unlock |
285 | 285 | ||
286 | or eax, -1 |
286 | or eax, -1 |
287 | ret |
287 | ret |
288 | ;-------------------------------------- |
288 | ;-------------------------------------- |
289 | .done: |
289 | .done: |
290 | mov ecx, [channel_lock] |
290 | mov ecx, [channel_lock] |
291 | call mutex_unlock |
291 | call mutex_unlock |
292 | 292 | ||
293 | mov ecx, ide_mutex |
293 | mov ecx, ide_mutex |
294 | call mutex_unlock |
294 | call mutex_unlock |
295 | 295 | ||
296 | xor eax, eax |
296 | xor eax, eax |
297 | ret |
297 | ret |
298 | endp |
298 | endp |
299 | ;----------------------------------------------------------------------------- |
299 | ;----------------------------------------------------------------------------- |
300 | ; This is a stub. |
300 | ; This is a stub. |
301 | proc ide_querymedia stdcall, hd_data, mediainfo |
301 | proc ide_querymedia stdcall, hd_data, mediainfo |
302 | mov eax, [mediainfo] |
302 | mov eax, [mediainfo] |
303 | mov [eax+DISKMEDIAINFO.Flags], 0 |
303 | mov [eax+DISKMEDIAINFO.Flags], 0 |
304 | mov [eax+DISKMEDIAINFO.SectorSize], 512 |
304 | mov [eax+DISKMEDIAINFO.SectorSize], 512 |
305 | or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF |
305 | or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF |
306 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
306 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
307 | xor eax, eax |
307 | xor eax, eax |
308 | ret |
308 | ret |
309 | endp |
309 | endp |
310 | ;----------------------------------------------------------------------------- |
310 | ;----------------------------------------------------------------------------- |
311 | align 4 |
311 | align 4 |
312 | ; input: eax = sector, edi -> buffer |
312 | ; input: eax = sector, edi -> buffer |
313 | ; output: edi = edi + 512 |
313 | ; output: edi = edi + 512 |
314 | hd_read_pio: |
314 | hd_read_pio: |
315 | push eax edx |
315 | push eax edx |
316 | ; Select the desired drive |
316 | ; Select the desired drive |
317 | mov edx, [hdbase] |
317 | mov edx, [hdbase] |
318 | add edx, 6 ;адрес регистра головок |
318 | add edx, 6 ;адрес регистра головок |
319 | mov al, byte [hdid] |
319 | mov al, byte [hdid] |
320 | add al, 128+64+32 |
320 | add al, 128+64+32 |
321 | out dx, al; номер головки/номер диска |
321 | out dx, al; номер головки/номер диска |
322 | 322 | ||
323 | call wait_for_hd_idle |
323 | call wait_for_hd_idle |
324 | 324 | ||
325 | cmp [hd_error], 0 |
325 | cmp [hd_error], 0 |
326 | jne hd_read_error |
326 | jne hd_read_error |
327 | ; ATA with 28 or 48 bit for sector number? |
327 | ; ATA with 28 or 48 bit for sector number? |
328 | mov eax, [esp+4] |
328 | mov eax, [esp+4] |
329 | cmp eax, 0x10000000 |
329 | cmp eax, 0x10000000 |
330 | jae .lba48 |
330 | jae .lba48 |
331 | ;-------------------------------------- |
331 | ;-------------------------------------- |
332 | .lba28: |
332 | .lba28: |
333 | pushfd |
333 | pushfd |
334 | cli |
334 | cli |
335 | xor eax, eax |
335 | xor eax, eax |
336 | mov edx, [hdbase] |
336 | mov edx, [hdbase] |
337 | inc edx |
337 | inc edx |
338 | out dx, al ; ATA Features регистр "особенностей" |
338 | out dx, al ; ATA Features регистр "особенностей" |
339 | inc edx |
339 | inc edx |
340 | inc eax |
340 | inc eax |
341 | out dx, al ; ATA Sector Counter счётчик секторов |
341 | out dx, al ; ATA Sector Counter счётчик секторов |
342 | inc edx |
342 | inc edx |
343 | mov eax, [esp+4+4] |
343 | mov eax, [esp+4+4] |
344 | out dx, al ; LBA Low LBA (7:0) |
344 | out dx, al ; LBA Low LBA (7:0) |
345 | shr eax, 8 |
345 | shr eax, 8 |
346 | inc edx |
346 | inc edx |
347 | out dx, al ; LBA Mid LBA (15:8) |
347 | out dx, al ; LBA Mid LBA (15:8) |
348 | shr eax, 8 |
348 | shr eax, 8 |
349 | inc edx |
349 | inc edx |
350 | out dx, al ; LBA High LBA (23:16) |
350 | out dx, al ; LBA High LBA (23:16) |
351 | shr eax, 8 |
351 | shr eax, 8 |
352 | inc edx |
352 | inc edx |
353 | and al, 1+2+4+8 ; LBA (27:24) |
353 | and al, 1+2+4+8 ; LBA (27:24) |
354 | add al, byte [hdid] |
354 | add al, byte [hdid] |
355 | add al, 128+64+32 |
355 | add al, 128+64+32 |
356 | out dx, al ; номер головки/номер диска |
356 | out dx, al ; номер головки/номер диска |
357 | inc edx |
357 | inc edx |
358 | mov al, 20h ; READ SECTOR(S) |
358 | mov al, 20h ; READ SECTOR(S) |
359 | out dx, al ; ATACommand регистр команд |
359 | out dx, al ; ATACommand регистр команд |
360 | popfd |
360 | popfd |
361 | jmp .continue |
361 | jmp .continue |
362 | ;-------------------------------------- |
362 | ;-------------------------------------- |
363 | .lba48: |
363 | .lba48: |
364 | pushfd |
364 | pushfd |
365 | cli |
365 | cli |
366 | xor eax, eax |
366 | xor eax, eax |
367 | mov edx, [hdbase] |
367 | mov edx, [hdbase] |
368 | inc edx |
368 | inc edx |
369 | out dx, al ; Features Previous Reserved |
369 | out dx, al ; Features Previous Reserved |
370 | out dx, al ; Features Current Reserved |
370 | out dx, al ; Features Current Reserved |
371 | inc edx |
371 | inc edx |
372 | out dx, al ; Sector Count Previous Sector count (15:8) |
372 | out dx, al ; Sector Count Previous Sector count (15:8) |
373 | inc eax |
373 | inc eax |
374 | out dx, al ; Sector Count Current Sector count (7:0) |
374 | out dx, al ; Sector Count Current Sector count (7:0) |
375 | inc edx |
375 | inc edx |
376 | mov eax, [esp+4+4] |
376 | mov eax, [esp+4+4] |
377 | rol eax, 8 |
377 | rol eax, 8 |
378 | out dx, al ; LBA Low Previous LBA (31:24) |
378 | out dx, al ; LBA Low Previous LBA (31:24) |
379 | xor eax, eax ; because only 32 bit cache |
379 | xor eax, eax ; because only 32 bit cache |
380 | inc edx |
380 | inc edx |
381 | out dx, al ; LBA Mid Previous LBA (39:32) |
381 | out dx, al ; LBA Mid Previous LBA (39:32) |
382 | inc edx |
382 | inc edx |
383 | out dx, al ; LBA High Previous LBA (47:40) |
383 | out dx, al ; LBA High Previous LBA (47:40) |
384 | sub edx, 2 |
384 | sub edx, 2 |
385 | mov eax, [esp+4+4] |
385 | mov eax, [esp+4+4] |
386 | out dx, al ; LBA Low Current LBA (7:0) |
386 | out dx, al ; LBA Low Current LBA (7:0) |
387 | shr eax, 8 |
387 | shr eax, 8 |
388 | inc edx |
388 | inc edx |
389 | out dx, al ; LBA Mid Current LBA (15:8) |
389 | out dx, al ; LBA Mid Current LBA (15:8) |
390 | shr eax, 8 |
390 | shr eax, 8 |
391 | inc edx |
391 | inc edx |
392 | out dx, al ; LBA High Current LBA (23:16) |
392 | out dx, al ; LBA High Current LBA (23:16) |
393 | inc edx |
393 | inc edx |
394 | mov al, byte [hdid] |
394 | mov al, byte [hdid] |
395 | add al, 128+64+32 |
395 | add al, 128+64+32 |
396 | out dx, al ; номер головки/номер диска |
396 | out dx, al ; номер головки/номер диска |
397 | inc edx |
397 | inc edx |
398 | mov al, 24h ; READ SECTOR(S) EXT |
398 | mov al, 24h ; READ SECTOR(S) EXT |
399 | out dx, al ; ATACommand регистр команд |
399 | out dx, al ; ATACommand регистр команд |
400 | popfd |
400 | popfd |
401 | ;-------------------------------------- |
401 | ;-------------------------------------- |
402 | .continue: |
402 | .continue: |
403 | call wait_for_sector_buffer |
403 | call wait_for_sector_buffer |
404 | 404 | ||
405 | cmp [hd_error], 0 |
405 | cmp [hd_error], 0 |
406 | jne hd_read_error |
406 | jne hd_read_error |
407 | 407 | ||
408 | pushfd |
408 | pushfd |
409 | cli |
409 | cli |
410 | mov ecx, 256 |
410 | mov ecx, 256 |
411 | mov edx, [hdbase] |
411 | mov edx, [hdbase] |
412 | cld |
412 | cld |
413 | rep insw |
413 | rep insw |
414 | popfd |
414 | popfd |
415 | 415 | ||
416 | pop edx eax |
416 | pop edx eax |
417 | ret |
417 | ret |
418 | ;----------------------------------------------------------------------------- |
418 | ;----------------------------------------------------------------------------- |
419 | align 4 |
419 | align 4 |
420 | ; edi -> sector, esi -> data |
420 | ; edi -> sector, esi -> data |
421 | cache_write_pio: |
421 | cache_write_pio: |
422 | ; Select the desired drive |
422 | ; Select the desired drive |
423 | mov edx, [hdbase] |
423 | mov edx, [hdbase] |
424 | add edx, 6 ;адрес регистра головок |
424 | add edx, 6 ;адрес регистра головок |
425 | mov al, byte [hdid] |
425 | mov al, byte [hdid] |
426 | add al, 128+64+32 |
426 | add al, 128+64+32 |
427 | out dx, al ; номер головки/номер диска |
427 | out dx, al ; номер головки/номер диска |
428 | 428 | ||
429 | call wait_for_hd_idle |
429 | call wait_for_hd_idle |
430 | 430 | ||
431 | cmp [hd_error], 0 |
431 | cmp [hd_error], 0 |
432 | jne hd_write_error |
432 | jne hd_write_error |
433 | 433 | ||
434 | ; ATA with 28 or 48 bit for sector number? |
434 | ; ATA with 28 or 48 bit for sector number? |
435 | mov eax, [edi] |
435 | mov eax, [edi] |
436 | cmp eax, 0x10000000 |
436 | cmp eax, 0x10000000 |
437 | jae .lba48 |
437 | jae .lba48 |
438 | ;-------------------------------------- |
438 | ;-------------------------------------- |
439 | .lba28: |
439 | .lba28: |
440 | pushfd |
440 | pushfd |
441 | cli |
441 | cli |
442 | xor eax, eax |
442 | xor eax, eax |
443 | mov edx, [hdbase] |
443 | mov edx, [hdbase] |
444 | inc edx |
444 | inc edx |
445 | out dx, al ; ATA Features регистр "особенностей" |
445 | out dx, al ; ATA Features регистр "особенностей" |
446 | inc edx |
446 | inc edx |
447 | inc eax |
447 | inc eax |
448 | out dx, al ; ATA Sector Counter счётчик секторов |
448 | out dx, al ; ATA Sector Counter счётчик секторов |
449 | inc edx |
449 | inc edx |
450 | mov eax, [edi] ; eax = sector to write |
450 | mov eax, [edi] ; eax = sector to write |
451 | out dx, al ; LBA Low LBA (7:0) |
451 | out dx, al ; LBA Low LBA (7:0) |
452 | shr eax, 8 |
452 | shr eax, 8 |
453 | inc edx |
453 | inc edx |
454 | out dx, al ; LBA Mid LBA (15:8) |
454 | out dx, al ; LBA Mid LBA (15:8) |
455 | shr eax, 8 |
455 | shr eax, 8 |
456 | inc edx |
456 | inc edx |
457 | out dx, al ; LBA High LBA (23:16) |
457 | out dx, al ; LBA High LBA (23:16) |
458 | shr eax, 8 |
458 | shr eax, 8 |
459 | inc edx |
459 | inc edx |
460 | and al, 1+2+4+8 ; LBA (27:24) |
460 | and al, 1+2+4+8 ; LBA (27:24) |
461 | add al, byte [hdid] |
461 | add al, byte [hdid] |
462 | add al, 128+64+32 |
462 | add al, 128+64+32 |
463 | out dx, al ; номер головки/номер диска |
463 | out dx, al ; номер головки/номер диска |
464 | inc edx |
464 | inc edx |
465 | mov al, 30h ; WRITE SECTOR(S) |
465 | mov al, 30h ; WRITE SECTOR(S) |
466 | out dx, al ; ATACommand регистр команд |
466 | out dx, al ; ATACommand регистр команд |
467 | jmp .continue |
467 | jmp .continue |
468 | ;-------------------------------------- |
468 | ;-------------------------------------- |
469 | .lba48: |
469 | .lba48: |
470 | pushfd |
470 | pushfd |
471 | cli |
471 | cli |
472 | xor eax, eax |
472 | xor eax, eax |
473 | mov edx, [hdbase] |
473 | mov edx, [hdbase] |
474 | inc edx |
474 | inc edx |
475 | out dx, al ; Features Previous Reserved |
475 | out dx, al ; Features Previous Reserved |
476 | out dx, al ; Features Current Reserved |
476 | out dx, al ; Features Current Reserved |
477 | inc edx |
477 | inc edx |
478 | out dx, al ; Sector Count Previous Sector count (15:8) |
478 | out dx, al ; Sector Count Previous Sector count (15:8) |
479 | inc eax |
479 | inc eax |
480 | out dx, al ; Sector Count Current Sector count (7:0) |
480 | out dx, al ; Sector Count Current Sector count (7:0) |
481 | inc edx |
481 | inc edx |
482 | mov eax, [edi] |
482 | mov eax, [edi] |
483 | rol eax, 8 |
483 | rol eax, 8 |
484 | out dx, al ; LBA Low Previous LBA (31:24) |
484 | out dx, al ; LBA Low Previous LBA (31:24) |
485 | xor eax, eax ; because only 32 bit cache |
485 | xor eax, eax ; because only 32 bit cache |
486 | inc edx |
486 | inc edx |
487 | out dx, al ; LBA Mid Previous LBA (39:32) |
487 | out dx, al ; LBA Mid Previous LBA (39:32) |
488 | inc edx |
488 | inc edx |
489 | out dx, al ; LBA High Previous LBA (47:40) |
489 | out dx, al ; LBA High Previous LBA (47:40) |
490 | sub edx, 2 |
490 | sub edx, 2 |
491 | mov eax, [edi] |
491 | mov eax, [edi] |
492 | out dx, al ; LBA Low Current LBA (7:0) |
492 | out dx, al ; LBA Low Current LBA (7:0) |
493 | shr eax, 8 |
493 | shr eax, 8 |
494 | inc edx |
494 | inc edx |
495 | out dx, al ; LBA Mid Current LBA (15:8) |
495 | out dx, al ; LBA Mid Current LBA (15:8) |
496 | shr eax, 8 |
496 | shr eax, 8 |
497 | inc edx |
497 | inc edx |
498 | out dx, al ; LBA High Current LBA (23:16) |
498 | out dx, al ; LBA High Current LBA (23:16) |
499 | inc edx |
499 | inc edx |
500 | mov al, byte [hdid] |
500 | mov al, byte [hdid] |
501 | add al, 128+64+32 |
501 | add al, 128+64+32 |
502 | out dx, al ; номер головки/номер диска |
502 | out dx, al ; номер головки/номер диска |
503 | inc edx |
503 | inc edx |
504 | mov al, 34h ; WRITE SECTOR(S) EXT |
504 | mov al, 34h ; WRITE SECTOR(S) EXT |
505 | out dx, al ; ATACommand регистр команд |
505 | out dx, al ; ATACommand регистр команд |
506 | ;-------------------------------------- |
506 | ;-------------------------------------- |
507 | .continue: |
507 | .continue: |
508 | popfd |
508 | popfd |
509 | call wait_for_sector_buffer |
509 | call wait_for_sector_buffer |
510 | 510 | ||
511 | cmp [hd_error], 0 |
511 | cmp [hd_error], 0 |
512 | jne hd_write_error |
512 | jne hd_write_error |
513 | 513 | ||
514 | push ecx esi |
514 | push ecx esi |
515 | 515 | ||
516 | pushfd |
516 | pushfd |
517 | cli |
517 | cli |
518 | mov ecx, 256 |
518 | mov ecx, 256 |
519 | mov edx, [hdbase] |
519 | mov edx, [hdbase] |
520 | cld |
520 | cld |
521 | rep outsw |
521 | rep outsw |
522 | popfd |
522 | popfd |
523 | 523 | ||
524 | pop esi ecx |
524 | pop esi ecx |
525 | ret |
525 | ret |
526 | ;----------------------------------------------------------------------------- |
526 | ;----------------------------------------------------------------------------- |
527 | align 4 |
527 | align 4 |
528 | save_hd_wait_timeout: |
528 | save_hd_wait_timeout: |
529 | push eax |
529 | push eax |
530 | mov eax, [timer_ticks] |
530 | mov eax, [timer_ticks] |
531 | add eax, 300 ; 3 sec timeout |
531 | add eax, 300 ; 3 sec timeout |
532 | mov [hd_wait_timeout], eax |
532 | mov [hd_wait_timeout], eax |
533 | pop eax |
533 | pop eax |
534 | ret |
534 | ret |
535 | ;----------------------------------------------------------------------------- |
535 | ;----------------------------------------------------------------------------- |
536 | align 4 |
536 | align 4 |
537 | check_hd_wait_timeout: |
537 | check_hd_wait_timeout: |
538 | push eax |
538 | push eax |
539 | mov eax, [hd_wait_timeout] |
539 | mov eax, [hd_wait_timeout] |
540 | cmp [timer_ticks], eax |
540 | cmp [timer_ticks], eax |
541 | jg hd_timeout_error |
541 | jg hd_timeout_error |
542 | 542 | ||
543 | pop eax |
543 | pop eax |
544 | mov [hd_error], 0 |
544 | mov [hd_error], 0 |
545 | ret |
545 | ret |
546 | ;----------------------------------------------------------------------------- |
546 | ;----------------------------------------------------------------------------- |
547 | hd_timeout_error: |
547 | hd_timeout_error: |
548 | if lang eq sp |
548 | if lang eq sp |
549 | DEBUGF 1,"K : FS - HD tiempo de espera agotado\n" |
549 | DEBUGF 1,"K : FS - HD tiempo de espera agotado\n" |
550 | else |
550 | else |
551 | DEBUGF 1,"K : FS - HD timeout\n" |
551 | DEBUGF 1,"K : FS - HD timeout\n" |
552 | end if |
552 | end if |
553 | mov [hd_error], 1 |
553 | mov [hd_error], 1 |
554 | pop eax |
554 | pop eax |
555 | ret |
555 | ret |
556 | ;----------------------------------------------------------------------------- |
556 | ;----------------------------------------------------------------------------- |
557 | hd_read_error: |
557 | hd_read_error: |
558 | if lang eq sp |
558 | if lang eq sp |
559 | DEBUGF 1,"K : FS - HD error de lectura\n" |
559 | DEBUGF 1,"K : FS - HD error de lectura\n" |
560 | else |
560 | else |
561 | DEBUGF 1,"K : FS - HD read error\n" |
561 | DEBUGF 1,"K : FS - HD read error\n" |
562 | end if |
562 | end if |
563 | pop edx eax |
563 | pop edx eax |
564 | ret |
564 | ret |
565 | ;----------------------------------------------------------------------------- |
565 | ;----------------------------------------------------------------------------- |
566 | hd_write_error_dma: |
566 | hd_write_error_dma: |
567 | pop esi |
567 | pop esi |
568 | hd_write_error: |
568 | hd_write_error: |
569 | if lang eq sp |
569 | if lang eq sp |
570 | DEBUGF 1,"K : FS - HD error de escritura\n" |
570 | DEBUGF 1,"K : FS - HD error de escritura\n" |
571 | else |
571 | else |
572 | DEBUGF 1,"K : FS - HD write error\n" |
572 | DEBUGF 1,"K : FS - HD write error\n" |
573 | end if |
573 | end if |
574 | ret |
574 | ret |
575 | ;----------------------------------------------------------------------------- |
575 | ;----------------------------------------------------------------------------- |
576 | align 4 |
576 | align 4 |
577 | wait_for_hd_idle: |
577 | wait_for_hd_idle: |
578 | push eax edx |
578 | push eax edx |
579 | 579 | ||
580 | call save_hd_wait_timeout |
580 | call save_hd_wait_timeout |
581 | 581 | ||
582 | mov edx, [hdbase] |
582 | mov edx, [hdbase] |
583 | add edx, 0x7 |
583 | add edx, 0x7 |
584 | ;-------------------------------------- |
584 | ;-------------------------------------- |
585 | align 4 |
585 | align 4 |
586 | wfhil1: |
586 | wfhil1: |
587 | call check_hd_wait_timeout |
587 | call check_hd_wait_timeout |
588 | 588 | ||
589 | cmp [hd_error], 0 |
589 | cmp [hd_error], 0 |
590 | jne @f |
590 | jne @f |
591 | 591 | ||
592 | in al, dx |
592 | in al, dx |
593 | test al, 128 |
593 | test al, 128 |
594 | jnz wfhil1 |
594 | jnz wfhil1 |
595 | ;-------------------------------------- |
595 | ;-------------------------------------- |
596 | @@: |
596 | @@: |
597 | pop edx eax |
597 | pop edx eax |
598 | ret |
598 | ret |
599 | ;----------------------------------------------------------------------------- |
599 | ;----------------------------------------------------------------------------- |
600 | align 4 |
600 | align 4 |
601 | wait_for_sector_buffer: |
601 | wait_for_sector_buffer: |
602 | push eax edx |
602 | push eax edx |
603 | 603 | ||
604 | mov edx, [hdbase] |
604 | mov edx, [hdbase] |
605 | add edx, 0x7 |
605 | add edx, 0x7 |
606 | 606 | ||
607 | call save_hd_wait_timeout |
607 | call save_hd_wait_timeout |
608 | ;-------------------------------------- |
608 | ;-------------------------------------- |
609 | align 4 |
609 | align 4 |
610 | hdwait_sbuf: ; wait for sector buffer to be ready |
610 | hdwait_sbuf: ; wait for sector buffer to be ready |
611 | call check_hd_wait_timeout |
611 | call check_hd_wait_timeout |
612 | 612 | ||
613 | cmp [hd_error], 0 |
613 | cmp [hd_error], 0 |
614 | jne @f |
614 | jne @f |
615 | 615 | ||
616 | in al, dx |
616 | in al, dx |
617 | test al, 8 |
617 | test al, 8 |
618 | jz hdwait_sbuf |
618 | jz hdwait_sbuf |
619 | 619 | ||
620 | mov [hd_error], 0 |
620 | mov [hd_error], 0 |
621 | 621 | ||
622 | cmp [hd_setup], 1 ; do not mark error for setup request |
622 | cmp [hd_setup], 1 ; do not mark error for setup request |
623 | je buf_wait_ok |
623 | je buf_wait_ok |
624 | 624 | ||
625 | test al, 1 ; previous command ended up with an error |
625 | test al, 1 ; previous command ended up with an error |
626 | jz buf_wait_ok |
626 | jz buf_wait_ok |
627 | ;-------------------------------------- |
627 | ;-------------------------------------- |
628 | @@: |
628 | @@: |
629 | mov [hd_error], 1 |
629 | mov [hd_error], 1 |
630 | ;-------------------------------------- |
630 | ;-------------------------------------- |
631 | buf_wait_ok: |
631 | buf_wait_ok: |
632 | pop edx eax |
632 | pop edx eax |
633 | ret |
633 | ret |
634 | ;----------------------------------------------------------------------------- |
634 | ;----------------------------------------------------------------------------- |
635 | irq14_num equ byte 14 |
635 | irq14_num equ byte 14 |
636 | irq15_num equ byte 15 |
636 | irq15_num equ byte 15 |
637 | ;----------------------------------------------------------------------------- |
637 | ;----------------------------------------------------------------------------- |
638 | align 4 |
638 | align 4 |
639 | wait_for_sector_dma_ide0: |
639 | wait_for_sector_dma_ide0: |
640 | push eax |
640 | push eax |
641 | push edx |
641 | push edx |
642 | call save_hd_wait_timeout |
642 | call save_hd_wait_timeout |
643 | ;-------------------------------------- |
643 | ;-------------------------------------- |
644 | align 4 |
644 | align 4 |
645 | .wait: |
645 | .wait: |
646 | call change_task |
646 | call change_task |
647 | 647 | ||
648 | cmp [IDE_common_irq_param], 0 |
648 | cmp [IDE_common_irq_param], 0 |
649 | jz .done |
649 | jz .done |
650 | 650 | ||
651 | call check_hd_wait_timeout |
651 | call check_hd_wait_timeout |
652 | 652 | ||
653 | cmp [hd_error], 0 |
653 | cmp [hd_error], 0 |
654 | jz .wait |
654 | jz .wait |
655 | 655 | ||
656 | mov [IDE_common_irq_param], 0 |
656 | mov [IDE_common_irq_param], 0 |
657 | ;-------------------------------------- |
657 | ;-------------------------------------- |
658 | .done: |
658 | .done: |
659 | pop edx |
659 | pop edx |
660 | pop eax |
660 | pop eax |
661 | ret |
661 | ret |
662 | ;----------------------------------------------------------------------------- |
662 | ;----------------------------------------------------------------------------- |
663 | align 4 |
663 | align 4 |
664 | wait_for_sector_dma_ide1: |
664 | wait_for_sector_dma_ide1: |
665 | push eax |
665 | push eax |
666 | push edx |
666 | push edx |
667 | call save_hd_wait_timeout |
667 | call save_hd_wait_timeout |
668 | ;-------------------------------------- |
668 | ;-------------------------------------- |
669 | align 4 |
669 | align 4 |
670 | .wait: |
670 | .wait: |
671 | call change_task |
671 | call change_task |
672 | 672 | ||
673 | cmp [IDE_common_irq_param], 0 |
673 | cmp [IDE_common_irq_param], 0 |
674 | jz .done |
674 | jz .done |
675 | 675 | ||
676 | call check_hd_wait_timeout |
676 | call check_hd_wait_timeout |
677 | 677 | ||
678 | cmp [hd_error], 0 |
678 | cmp [hd_error], 0 |
679 | jz .wait |
679 | jz .wait |
680 | 680 | ||
681 | mov [IDE_common_irq_param], 0 |
681 | mov [IDE_common_irq_param], 0 |
682 | ;-------------------------------------- |
682 | ;-------------------------------------- |
683 | .done: |
683 | .done: |
684 | pop edx |
684 | pop edx |
685 | pop eax |
685 | pop eax |
686 | ret |
686 | ret |
687 | ;----------------------------------------------------------------------------- |
687 | ;----------------------------------------------------------------------------- |
688 | iglobal |
688 | iglobal |
689 | align 4 |
689 | align 4 |
690 | ; note that IDE descriptor table must be 4-byte aligned |
690 | ; note that IDE descriptor table must be 4-byte aligned |
691 | ; and do not cross 4K boundary |
691 | ; and do not cross 4K boundary |
692 | IDE_descriptor_table: |
692 | IDE_descriptor_table: |
693 | dd IDE_DMA |
693 | dd IDE_DMA |
694 | dw 0x2000 |
694 | dw 0x2000 |
695 | dw 0x8000 |
695 | dw 0x8000 |
696 | 696 | ||
697 | dma_cur_sector dd not 40h |
697 | dma_cur_sector dd not 40h |
698 | dma_hdpos dd 0 |
698 | dma_hdpos dd 0 |
699 | IDE_common_irq_param db 0 |
699 | IDE_common_irq_param db 0 |
700 | endg |
700 | endg |
701 | ;----------------------------------------------------------------------------- |
701 | ;----------------------------------------------------------------------------- |
702 | uglobal |
702 | uglobal |
703 | ; all uglobals are zeroed at boot |
703 | ; all uglobals are zeroed at boot |
704 | cache_chain_ptr dd 0 |
704 | cache_chain_ptr dd 0 |
705 | cache_chain_size db 0 |
705 | cache_chain_size db 0 |
706 | allow_dma_access db 0 |
706 | allow_dma_access db 0 |
707 | endg |
707 | endg |
708 | ;----------------------------------------------------------------------------- |
708 | ;----------------------------------------------------------------------------- |
709 | align 4 |
709 | align 4 |
710 | IDE_irq_14_handler: |
710 | IDE_irq_14_handler: |
- | 711 | ; DEBUGF 1, 'K : IDE_irq_14_handler %x\n', [IDE_common_irq_param]:2 |
|
711 | cmp [IDE_common_irq_param], irq14_num |
712 | cmp [IDE_common_irq_param], irq14_num |
712 | jne .exit |
713 | jne .exit |
713 | 714 | ||
714 | pushfd |
715 | pushfd |
715 | cli |
716 | cli |
716 | pushad |
717 | pushad |
717 | mov [IDE_common_irq_param], 0 |
718 | mov [IDE_common_irq_param], 0 |
718 | mov ecx, [IDE_controller_pointer] |
719 | mov ecx, [IDE_controller_pointer] |
719 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
720 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
720 | ; test whether it is our interrupt? |
721 | ; test whether it is our interrupt? |
721 | add edx, 2 |
722 | add edx, 2 |
722 | in al, dx |
723 | in al, dx |
723 | test al, 100b |
724 | test al, 100b |
724 | jz @f |
725 | jz @f |
725 | ; clear Bus Master IDE Status register |
726 | ; clear Bus Master IDE Status register |
726 | ; clear Interrupt bit |
727 | ; clear Interrupt bit |
727 | out dx, al |
728 | out dx, al |
728 | ; clear Bus Master IDE Command register |
729 | ; clear Bus Master IDE Command register |
729 | sub edx, 2 |
730 | sub edx, 2 |
730 | xor eax, eax |
731 | xor eax, eax |
731 | out dx, al |
732 | out dx, al |
732 | ; read status register and remove the interrupt request |
733 | ; read status register and remove the interrupt request |
733 | mov edx, [hdbase] |
734 | mov edx, [hdbase] |
734 | add edx, 0x7 |
735 | add edx, 0x7 |
735 | in al, dx |
736 | in al, dx |
736 | popad |
737 | popad |
737 | popfd |
738 | popfd |
738 | mov al, 1 |
739 | mov al, 1 |
739 | ret |
740 | ret |
740 | ;-------------------------------------- |
741 | ;-------------------------------------- |
741 | @@: |
742 | @@: |
742 | popad |
743 | popad |
743 | popfd |
744 | popfd |
744 | ;-------------------------------------- |
745 | ;-------------------------------------- |
745 | .exit: |
746 | .exit: |
746 | mov al, 0 |
747 | mov al, 0 |
747 | ret |
748 | ret |
748 | ;----------------------------------------------------------------------------- |
749 | ;----------------------------------------------------------------------------- |
749 | align 4 |
750 | align 4 |
750 | IDE_irq_15_handler: |
751 | IDE_irq_15_handler: |
- | 752 | ; DEBUGF 1, 'K : IDE_irq_15_handler %x\n', [IDE_common_irq_param]:2 |
|
751 | cmp [IDE_common_irq_param], irq15_num |
753 | cmp [IDE_common_irq_param], irq15_num |
752 | jne .exit |
754 | jne .exit |
753 | 755 | ||
754 | pushfd |
756 | pushfd |
755 | cli |
757 | cli |
756 | pushad |
758 | pushad |
757 | mov [IDE_common_irq_param], 0 |
759 | mov [IDE_common_irq_param], 0 |
758 | mov ecx, [IDE_controller_pointer] |
760 | mov ecx, [IDE_controller_pointer] |
759 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
761 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
760 | add dx, 8 |
762 | add dx, 8 |
761 | ; test whether it is our interrupt? |
763 | ; test whether it is our interrupt? |
762 | add edx, 2 |
764 | add edx, 2 |
763 | in al, dx |
765 | in al, dx |
764 | test al, 100b |
766 | test al, 100b |
765 | jz @f |
767 | jz @f |
766 | ; clear Bus Master IDE Status register |
768 | ; clear Bus Master IDE Status register |
767 | ; clear Interrupt bit |
769 | ; clear Interrupt bit |
768 | out dx, al |
770 | out dx, al |
769 | ; clear Bus Master IDE Command register |
771 | ; clear Bus Master IDE Command register |
770 | sub edx, 2 |
772 | sub edx, 2 |
771 | mov al, 0 |
773 | mov al, 0 |
772 | out dx, al |
774 | out dx, al |
773 | ; read status register and remove the interrupt request |
775 | ; read status register and remove the interrupt request |
774 | mov edx, [hdbase] |
776 | mov edx, [hdbase] |
775 | add edx, 0x7 |
777 | add edx, 0x7 |
776 | in al, dx |
778 | in al, dx |
777 | popad |
779 | popad |
778 | popfd |
780 | popfd |
779 | mov al, 1 |
781 | mov al, 1 |
780 | ret |
782 | ret |
781 | ;-------------------------------------- |
783 | ;-------------------------------------- |
782 | @@: |
784 | @@: |
783 | popad |
785 | popad |
784 | popfd |
786 | popfd |
785 | ;-------------------------------------- |
787 | ;-------------------------------------- |
786 | .exit: |
788 | .exit: |
787 | mov al, 0 |
789 | mov al, 0 |
788 | ret |
790 | ret |
789 | ;----------------------------------------------------------------------------- |
791 | ;----------------------------------------------------------------------------- |
790 | align 4 |
792 | align 4 |
791 | IDE_common_irq_handler: |
793 | IDE_common_irq_handler: |
- | 794 | ; DEBUGF 1, 'K : IDE_common_irq_handler %x\n', [IDE_common_irq_param]:2 |
|
792 | cmp [IDE_common_irq_param], 0 |
795 | cmp [IDE_common_irq_param], 0 |
793 | je .exit |
796 | je .exit |
794 | 797 | ||
795 | pushfd |
798 | pushfd |
796 | cli |
799 | cli |
797 | pushad |
800 | pushad |
798 | xor ebx, ebx |
801 | xor ebx, ebx |
799 | mov ecx, [IDE_controller_pointer] |
802 | mov ecx, [IDE_controller_pointer] |
800 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
803 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
801 | mov eax, IDE_common_irq_param |
804 | mov eax, IDE_common_irq_param |
802 | cmp [eax], irq14_num |
805 | cmp [eax], irq14_num |
803 | mov [eax], bl |
806 | mov [eax], bl |
804 | je @f |
807 | je @f |
805 | 808 | ||
806 | add dx, 8 |
809 | add dx, 8 |
807 | ;-------------------------------------- |
810 | ;-------------------------------------- |
808 | @@: |
811 | @@: |
809 | ; test whether it is our interrupt? |
812 | ; test whether it is our interrupt? |
810 | add edx, 2 |
813 | add edx, 2 |
811 | in al, dx |
814 | in al, dx |
812 | test al, 100b |
815 | test al, 100b |
813 | jz @f |
816 | jz @f |
814 | ; clear Bus Master IDE Status register |
817 | ; clear Bus Master IDE Status register |
815 | ; clear Interrupt bit |
818 | ; clear Interrupt bit |
816 | out dx, al |
819 | out dx, al |
817 | ; clear Bus Master IDE Command register |
820 | ; clear Bus Master IDE Command register |
818 | sub edx, 2 |
821 | sub edx, 2 |
819 | xor eax, eax |
822 | xor eax, eax |
820 | out dx, al |
823 | out dx, al |
821 | ; read status register and remove the interrupt request |
824 | ; read status register and remove the interrupt request |
822 | mov edx, [hdbase] |
825 | mov edx, [hdbase] |
823 | add edx, 0x7 |
826 | add edx, 0x7 |
824 | in al, dx |
827 | in al, dx |
825 | popad |
828 | popad |
826 | popfd |
829 | popfd |
827 | mov al, 1 |
830 | mov al, 1 |
828 | ret |
831 | ret |
829 | ;-------------------------------------- |
832 | ;-------------------------------------- |
830 | @@: |
833 | @@: |
831 | popad |
834 | popad |
832 | popfd |
835 | popfd |
833 | ;-------------------------------------- |
836 | ;-------------------------------------- |
834 | .exit: |
837 | .exit: |
835 | mov al, 0 |
838 | mov al, 0 |
836 | ret |
839 | ret |
837 | ;----------------------------------------------------------------------------- |
840 | ;----------------------------------------------------------------------------- |
838 | align 4 |
841 | align 4 |
839 | hd_read_dma: |
842 | hd_read_dma: |
840 | push eax |
843 | push eax |
841 | push edx |
844 | push edx |
842 | mov edx, [dma_hdpos] |
845 | mov edx, [dma_hdpos] |
843 | cmp edx, [hdpos] |
846 | cmp edx, [hdpos] |
844 | jne .notread |
847 | jne .notread |
845 | 848 | ||
846 | mov edx, [dma_cur_sector] |
849 | mov edx, [dma_cur_sector] |
847 | cmp eax, edx |
850 | cmp eax, edx |
848 | jb .notread |
851 | jb .notread |
849 | 852 | ||
850 | add edx, 15 |
853 | add edx, 15 |
851 | cmp [esp+4], edx |
854 | cmp [esp+4], edx |
852 | ja .notread |
855 | ja .notread |
853 | 856 | ||
854 | mov eax, [esp+4] |
857 | mov eax, [esp+4] |
855 | sub eax, [dma_cur_sector] |
858 | sub eax, [dma_cur_sector] |
856 | shl eax, 9 |
859 | shl eax, 9 |
857 | add eax, (OS_BASE+IDE_DMA) |
860 | add eax, (OS_BASE+IDE_DMA) |
858 | 861 | ||
859 | push ecx esi |
862 | push ecx esi |
860 | mov esi, eax |
863 | mov esi, eax |
861 | mov ecx, 512/4 |
864 | mov ecx, 512/4 |
862 | cld |
865 | cld |
863 | rep movsd |
866 | rep movsd |
864 | pop esi ecx |
867 | pop esi ecx |
865 | 868 | ||
866 | pop edx |
869 | pop edx |
867 | pop eax |
870 | pop eax |
868 | ret |
871 | ret |
869 | ;-------------------------------------- |
872 | ;-------------------------------------- |
870 | .notread: |
873 | .notread: |
871 | ; set data for PRD Table |
874 | ; set data for PRD Table |
872 | mov eax, IDE_descriptor_table |
875 | mov eax, IDE_descriptor_table |
873 | mov dword [eax], IDE_DMA |
876 | mov dword [eax], IDE_DMA |
874 | mov word [eax+4], 0x2000 |
877 | mov word [eax+4], 0x2000 |
875 | sub eax, OS_BASE |
878 | sub eax, OS_BASE |
876 | ; select controller Primary or Secondary |
879 | ; select controller Primary or Secondary |
877 | mov ecx, [IDE_controller_pointer] |
880 | mov ecx, [IDE_controller_pointer] |
878 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
881 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
879 | 882 | ||
880 | push eax |
883 | push eax |
881 | mov eax, [hdpos] |
884 | mov eax, [hdpos] |
882 | dec eax |
885 | dec eax |
883 | test eax, 10b |
886 | test eax, 10b |
884 | pop eax |
887 | pop eax |
885 | jz @f |
888 | jz @f |
886 | 889 | ||
887 | add edx, 8 |
890 | add edx, 8 |
888 | ;-------------------------------------- |
891 | ;-------------------------------------- |
889 | @@: |
892 | @@: |
890 | push edx |
893 | push edx |
891 | ; Bus Master IDE PRD Table Address |
894 | ; Bus Master IDE PRD Table Address |
892 | add edx, 4 |
895 | add edx, 4 |
893 | ; save IDE_descriptor_table |
896 | ; save IDE_descriptor_table |
894 | out dx, eax |
897 | out dx, eax |
895 | pop edx |
898 | pop edx |
896 | ; clear Bus Master IDE Command register |
899 | ; clear Bus Master IDE Command register |
897 | mov al, 0 |
900 | mov al, 0 |
898 | out dx, al |
901 | out dx, al |
899 | ; clear Bus Master IDE Status register |
902 | ; clear Bus Master IDE Status register |
900 | ; clear Error bit and Interrupt bit |
903 | ; clear Error bit and Interrupt bit |
901 | add edx, 2 |
904 | add edx, 2 |
902 | mov al, 6 ; 110b |
905 | mov al, 6 ; 110b |
903 | out dx, al |
906 | out dx, al |
904 | ; Select the desired drive |
907 | ; Select the desired drive |
905 | mov edx, [hdbase] |
908 | mov edx, [hdbase] |
906 | add edx, 6 ; адрес регистра головок |
909 | add edx, 6 ; адрес регистра головок |
907 | mov al, byte [hdid] |
910 | mov al, byte [hdid] |
908 | add al, 128+64+32 |
911 | add al, 128+64+32 |
909 | out dx, al ; номер головки/номер диска |
912 | out dx, al ; номер головки/номер диска |
910 | 913 | ||
911 | call wait_for_hd_idle |
914 | call wait_for_hd_idle |
912 | 915 | ||
913 | cmp [hd_error], 0 |
916 | cmp [hd_error], 0 |
914 | jnz hd_read_error |
917 | jnz hd_read_error |
915 | ; ATA with 28 or 48 bit for sector number? |
918 | ; ATA with 28 or 48 bit for sector number? |
916 | mov eax, [esp+4] |
919 | mov eax, [esp+4] |
917 | ; -10h because the PreCache hits the boundary between lba28 and lba48 |
920 | ; -10h because the PreCache hits the boundary between lba28 and lba48 |
918 | ; 10h = 16 - size of PreCache |
921 | ; 10h = 16 - size of PreCache |
919 | cmp eax, 0x10000000-10h |
922 | cmp eax, 0x10000000-10h |
920 | jae .lba48 |
923 | jae .lba48 |
921 | ;-------------------------------------- |
924 | ;-------------------------------------- |
922 | .lba28: |
925 | .lba28: |
923 | pushfd |
926 | pushfd |
924 | cli |
927 | cli |
925 | xor eax, eax |
928 | xor eax, eax |
926 | mov edx, [hdbase] |
929 | mov edx, [hdbase] |
927 | inc edx |
930 | inc edx |
928 | out dx, al ; ATA Features регистр "особенностей" |
931 | out dx, al ; ATA Features регистр "особенностей" |
929 | inc edx |
932 | inc edx |
930 | mov eax, 10h ; Sector Counter = 16 ; PreCache |
933 | mov eax, 10h ; Sector Counter = 16 ; PreCache |
931 | out dx, al ; ATA Sector Counter счётчик секторов |
934 | out dx, al ; ATA Sector Counter счётчик секторов |
932 | inc edx |
935 | inc edx |
933 | mov eax, [esp+4+4] |
936 | mov eax, [esp+4+4] |
934 | out dx, al ; LBA Low LBA (7:0) |
937 | out dx, al ; LBA Low LBA (7:0) |
935 | shr eax, 8 |
938 | shr eax, 8 |
936 | inc edx |
939 | inc edx |
937 | out dx, al ; LBA Mid LBA (15:8) |
940 | out dx, al ; LBA Mid LBA (15:8) |
938 | shr eax, 8 |
941 | shr eax, 8 |
939 | inc edx |
942 | inc edx |
940 | out dx, al ; LBA High LBA (23:16) |
943 | out dx, al ; LBA High LBA (23:16) |
941 | shr eax, 8 |
944 | shr eax, 8 |
942 | inc edx |
945 | inc edx |
943 | and al, 0xF ; LBA (27:24) |
946 | and al, 0xF ; LBA (27:24) |
944 | add al, byte [hdid] |
947 | add al, byte [hdid] |
945 | add al, 11100000b |
948 | add al, 11100000b |
946 | out dx, al ; номер головки/номер диска |
949 | out dx, al ; номер головки/номер диска |
947 | inc edx |
950 | inc edx |
948 | mov al, 0xC8 ; READ DMA |
951 | mov al, 0xC8 ; READ DMA |
949 | out dx, al ; ATACommand регистр команд |
952 | out dx, al ; ATACommand регистр команд |
950 | jmp .continue |
953 | jmp .continue |
951 | ;-------------------------------------- |
954 | ;-------------------------------------- |
952 | .lba48: |
955 | .lba48: |
953 | pushfd |
956 | pushfd |
954 | cli |
957 | cli |
955 | xor eax, eax |
958 | xor eax, eax |
956 | mov edx, [hdbase] |
959 | mov edx, [hdbase] |
957 | inc edx |
960 | inc edx |
958 | out dx, al ; Features Previous Reserved |
961 | out dx, al ; Features Previous Reserved |
959 | out dx, al ; Features Current Reserved |
962 | out dx, al ; Features Current Reserved |
960 | inc edx |
963 | inc edx |
961 | out dx, al ; Sector Count Previous Sector count (15:8) |
964 | out dx, al ; Sector Count Previous Sector count (15:8) |
962 | mov eax, 10h ; Sector Counter = 16 PreCache |
965 | mov eax, 10h ; Sector Counter = 16 PreCache |
963 | out dx, al ; Sector Count Current Sector count (7:0) |
966 | out dx, al ; Sector Count Current Sector count (7:0) |
964 | inc edx |
967 | inc edx |
965 | mov eax, [esp+4+4] |
968 | mov eax, [esp+4+4] |
966 | rol eax, 8 |
969 | rol eax, 8 |
967 | out dx, al ; LBA Low Previous LBA (31:24) |
970 | out dx, al ; LBA Low Previous LBA (31:24) |
968 | xor eax, eax ; because only 32 bit cache |
971 | xor eax, eax ; because only 32 bit cache |
969 | inc edx |
972 | inc edx |
970 | out dx, al ; LBA Mid Previous LBA (39:32) |
973 | out dx, al ; LBA Mid Previous LBA (39:32) |
971 | inc edx |
974 | inc edx |
972 | out dx, al ; LBA High Previous LBA (47:40) |
975 | out dx, al ; LBA High Previous LBA (47:40) |
973 | sub edx, 2 |
976 | sub edx, 2 |
974 | mov eax, [esp+4+4] |
977 | mov eax, [esp+4+4] |
975 | out dx, al ; LBA Low Current LBA (7:0) |
978 | out dx, al ; LBA Low Current LBA (7:0) |
976 | shr eax, 8 |
979 | shr eax, 8 |
977 | inc edx |
980 | inc edx |
978 | out dx, al ; LBA Mid Current LBA (15:8) |
981 | out dx, al ; LBA Mid Current LBA (15:8) |
979 | shr eax, 8 |
982 | shr eax, 8 |
980 | inc edx |
983 | inc edx |
981 | out dx, al ; LBA High Current LBA (23:16) |
984 | out dx, al ; LBA High Current LBA (23:16) |
982 | inc edx |
985 | inc edx |
983 | mov al, byte [hdid] |
986 | mov al, byte [hdid] |
984 | add al, 128+64+32 |
987 | add al, 128+64+32 |
985 | out dx, al ; номер головки/номер диска |
988 | out dx, al ; номер головки/номер диска |
986 | inc edx |
989 | inc edx |
987 | mov al, 25h ; READ DMA EXT |
990 | mov al, 25h ; READ DMA EXT |
988 | out dx, al ; ATACommand регистр команд |
991 | out dx, al ; ATACommand регистр команд |
989 | ;-------------------------------------- |
992 | ;-------------------------------------- |
990 | .continue: |
993 | .continue: |
991 | ; select controller Primary or Secondary |
994 | ; select controller Primary or Secondary |
992 | mov ecx, [IDE_controller_pointer] |
995 | mov ecx, [IDE_controller_pointer] |
993 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
996 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
994 | 997 | ||
995 | mov eax, [hdpos] |
998 | mov eax, [hdpos] |
996 | dec eax |
999 | dec eax |
997 | test eax, 10b |
1000 | test eax, 10b |
998 | jz @f |
1001 | jz @f |
999 | 1002 | ||
1000 | add dx, 8 |
1003 | add dx, 8 |
1001 | ;-------------------------------------- |
1004 | ;-------------------------------------- |
1002 | @@: |
1005 | @@: |
1003 | ; set write to memory and Start Bus Master |
1006 | ; set write to memory and Start Bus Master |
1004 | mov al, 9 |
1007 | mov al, 9 |
1005 | out dx, al |
1008 | out dx, al |
1006 | 1009 | ||
1007 | mov eax, [hdpos] |
1010 | mov eax, [hdpos] |
1008 | dec eax |
1011 | dec eax |
1009 | test eax, 10b |
1012 | test eax, 10b |
1010 | jnz .ide1 |
1013 | jnz .ide1 |
1011 | 1014 | ||
1012 | mov [IDE_common_irq_param], irq14_num |
1015 | mov [IDE_common_irq_param], irq14_num |
1013 | jmp @f |
1016 | jmp @f |
1014 | ;-------------------------------------- |
1017 | ;-------------------------------------- |
1015 | .ide1: |
1018 | .ide1: |
1016 | mov [IDE_common_irq_param], irq15_num |
1019 | mov [IDE_common_irq_param], irq15_num |
1017 | ;-------------------------------------- |
1020 | ;-------------------------------------- |
1018 | @@: |
1021 | @@: |
1019 | popfd |
1022 | popfd |
1020 | ; wait for interrupt |
1023 | ; wait for interrupt |
1021 | mov eax, [hdpos] |
1024 | mov eax, [hdpos] |
1022 | dec eax |
1025 | dec eax |
1023 | test eax, 10b |
1026 | test eax, 10b |
1024 | jnz .wait_ide1 |
1027 | jnz .wait_ide1 |
1025 | 1028 | ||
1026 | call wait_for_sector_dma_ide0 |
1029 | call wait_for_sector_dma_ide0 |
1027 | jmp @f |
1030 | jmp @f |
1028 | ;-------------------------------------- |
1031 | ;-------------------------------------- |
1029 | .wait_ide1: |
1032 | .wait_ide1: |
1030 | call wait_for_sector_dma_ide1 |
1033 | call wait_for_sector_dma_ide1 |
1031 | ;-------------------------------------- |
1034 | ;-------------------------------------- |
1032 | @@: |
1035 | @@: |
1033 | cmp [hd_error], 0 |
1036 | cmp [hd_error], 0 |
1034 | jnz hd_read_error |
1037 | jnz hd_read_error |
1035 | 1038 | ||
1036 | mov eax, [hdpos] |
1039 | mov eax, [hdpos] |
1037 | mov [dma_hdpos], eax |
1040 | mov [dma_hdpos], eax |
1038 | pop edx |
1041 | pop edx |
1039 | pop eax |
1042 | pop eax |
1040 | 1043 | ||
1041 | mov [dma_cur_sector], eax |
1044 | mov [dma_cur_sector], eax |
1042 | jmp hd_read_dma |
1045 | jmp hd_read_dma |
1043 | ;----------------------------------------------------------------------------- |
1046 | ;----------------------------------------------------------------------------- |
1044 | cache_write_dma: |
1047 | cache_write_dma: |
1045 | mov eax, [cache_chain_ptr] ; for what? |
1048 | mov eax, [cache_chain_ptr] ; for what? |
1046 | push esi |
1049 | push esi |
1047 | ; set data for PRD Table |
1050 | ; set data for PRD Table |
1048 | mov eax, IDE_descriptor_table |
1051 | mov eax, IDE_descriptor_table |
1049 | mov edx, eax |
1052 | mov edx, eax |
1050 | 1053 | ||
1051 | pusha |
1054 | pusha |
1052 | mov edi, (OS_BASE+IDE_DMA) |
1055 | mov edi, (OS_BASE+IDE_DMA) |
1053 | mov dword [edx], IDE_DMA |
1056 | mov dword [edx], IDE_DMA |
1054 | movzx ecx, [cache_chain_size] |
1057 | movzx ecx, [cache_chain_size] |
1055 | shl ecx, 9 |
1058 | shl ecx, 9 |
1056 | mov word [edx+4], cx |
1059 | mov word [edx+4], cx |
1057 | shr ecx, 2 |
1060 | shr ecx, 2 |
1058 | cld |
1061 | cld |
1059 | rep movsd |
1062 | rep movsd |
1060 | popa |
1063 | popa |
1061 | 1064 | ||
1062 | sub eax, OS_BASE |
1065 | sub eax, OS_BASE |
1063 | ; select controller Primary or Secondary |
1066 | ; select controller Primary or Secondary |
1064 | mov ecx, [IDE_controller_pointer] |
1067 | mov ecx, [IDE_controller_pointer] |
1065 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
1068 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
1066 | 1069 | ||
1067 | push eax |
1070 | push eax |
1068 | mov eax, [hdpos] |
1071 | mov eax, [hdpos] |
1069 | dec eax |
1072 | dec eax |
1070 | test eax, 10b |
1073 | test eax, 10b |
1071 | pop eax |
1074 | pop eax |
1072 | jz @f |
1075 | jz @f |
1073 | 1076 | ||
1074 | add edx, 8 |
1077 | add edx, 8 |
1075 | ;-------------------------------------- |
1078 | ;-------------------------------------- |
1076 | @@: |
1079 | @@: |
1077 | push edx |
1080 | push edx |
1078 | ; Bus Master IDE PRD Table Address |
1081 | ; Bus Master IDE PRD Table Address |
1079 | add edx, 4 |
1082 | add edx, 4 |
1080 | ; save IDE_descriptor_table |
1083 | ; save IDE_descriptor_table |
1081 | out dx, eax |
1084 | out dx, eax |
1082 | pop edx |
1085 | pop edx |
1083 | ; clear Bus Master IDE Command register |
1086 | ; clear Bus Master IDE Command register |
1084 | mov al, 0 |
1087 | mov al, 0 |
1085 | out dx, al |
1088 | out dx, al |
1086 | ; clear Bus Master IDE Status register |
1089 | ; clear Bus Master IDE Status register |
1087 | ; clear Error bit and Interrupt bit |
1090 | ; clear Error bit and Interrupt bit |
1088 | add edx, 2 |
1091 | add edx, 2 |
1089 | mov al, 6 |
1092 | mov al, 6 |
1090 | out dx, al |
1093 | out dx, al |
1091 | ; Select the desired drive |
1094 | ; Select the desired drive |
1092 | mov edx, [hdbase] |
1095 | mov edx, [hdbase] |
1093 | add edx, 6 ; адрес регистра головок |
1096 | add edx, 6 ; адрес регистра головок |
1094 | mov al, byte [hdid] |
1097 | mov al, byte [hdid] |
1095 | add al, 128+64+32 |
1098 | add al, 128+64+32 |
1096 | out dx, al ; номер головки/номер диска |
1099 | out dx, al ; номер головки/номер диска |
1097 | 1100 | ||
1098 | call wait_for_hd_idle |
1101 | call wait_for_hd_idle |
1099 | 1102 | ||
1100 | cmp [hd_error], 0 |
1103 | cmp [hd_error], 0 |
1101 | jnz hd_write_error_dma |
1104 | jnz hd_write_error_dma |
1102 | ; ATA with 28 or 48 bit for sector number? |
1105 | ; ATA with 28 or 48 bit for sector number? |
1103 | mov esi, [cache_chain_ptr] |
1106 | mov esi, [cache_chain_ptr] |
1104 | mov eax, [esi] |
1107 | mov eax, [esi] |
1105 | ; -40h because the PreCache hits the boundary between lba28 and lba48 |
1108 | ; -40h because the PreCache hits the boundary between lba28 and lba48 |
1106 | ; 40h = 64 - the maximum number of sectors to be written for one command |
1109 | ; 40h = 64 - the maximum number of sectors to be written for one command |
1107 | cmp eax, 0x10000000-40h |
1110 | cmp eax, 0x10000000-40h |
1108 | jae .lba48 |
1111 | jae .lba48 |
1109 | ;-------------------------------------- |
1112 | ;-------------------------------------- |
1110 | .lba28: |
1113 | .lba28: |
1111 | pushfd |
1114 | pushfd |
1112 | cli |
1115 | cli |
1113 | xor eax, eax |
1116 | xor eax, eax |
1114 | mov edx, [hdbase] |
1117 | mov edx, [hdbase] |
1115 | inc edx |
1118 | inc edx |
1116 | out dx, al ; ATA Features регистр "особенностей" |
1119 | out dx, al ; ATA Features регистр "особенностей" |
1117 | inc edx |
1120 | inc edx |
1118 | mov al, [cache_chain_size] ; Sector Counter |
1121 | mov al, [cache_chain_size] ; Sector Counter |
1119 | out dx, al ; ATA Sector Counter счётчик секторов |
1122 | out dx, al ; ATA Sector Counter счётчик секторов |
1120 | inc edx |
1123 | inc edx |
1121 | mov eax, [esi] |
1124 | mov eax, [esi] |
1122 | out dx, al ; LBA Low LBA (7:0) |
1125 | out dx, al ; LBA Low LBA (7:0) |
1123 | shr eax, 8 |
1126 | shr eax, 8 |
1124 | inc edx |
1127 | inc edx |
1125 | out dx, al ; LBA Mid LBA (15:8) |
1128 | out dx, al ; LBA Mid LBA (15:8) |
1126 | shr eax, 8 |
1129 | shr eax, 8 |
1127 | inc edx |
1130 | inc edx |
1128 | out dx, al ; LBA High LBA (23:16) |
1131 | out dx, al ; LBA High LBA (23:16) |
1129 | shr eax, 8 |
1132 | shr eax, 8 |
1130 | inc edx |
1133 | inc edx |
1131 | and al, 0xF ; LBA (27:24) |
1134 | and al, 0xF ; LBA (27:24) |
1132 | add al, byte [hdid] |
1135 | add al, byte [hdid] |
1133 | add al, 11100000b |
1136 | add al, 11100000b |
1134 | out dx, al ; номер головки/номер диска |
1137 | out dx, al ; номер головки/номер диска |
1135 | inc edx |
1138 | inc edx |
1136 | mov al, 0xCA ; WRITE DMA |
1139 | mov al, 0xCA ; WRITE DMA |
1137 | out dx, al ; ATACommand регистр команд |
1140 | out dx, al ; ATACommand регистр команд |
1138 | jmp .continue |
1141 | jmp .continue |
1139 | ;-------------------------------------- |
1142 | ;-------------------------------------- |
1140 | .lba48: |
1143 | .lba48: |
1141 | pushfd |
1144 | pushfd |
1142 | cli |
1145 | cli |
1143 | xor eax, eax |
1146 | xor eax, eax |
1144 | mov edx, [hdbase] |
1147 | mov edx, [hdbase] |
1145 | inc edx |
1148 | inc edx |
1146 | out dx, al ; Features Previous Reserved |
1149 | out dx, al ; Features Previous Reserved |
1147 | out dx, al ; Features Current Reserved |
1150 | out dx, al ; Features Current Reserved |
1148 | inc edx |
1151 | inc edx |
1149 | out dx, al ; Sector Count Previous Sector count (15:8) |
1152 | out dx, al ; Sector Count Previous Sector count (15:8) |
1150 | mov al, [cache_chain_size] ; Sector Counter |
1153 | mov al, [cache_chain_size] ; Sector Counter |
1151 | out dx, al ; Sector Count Current Sector count (7:0) |
1154 | out dx, al ; Sector Count Current Sector count (7:0) |
1152 | inc edx |
1155 | inc edx |
1153 | mov eax, [esi] |
1156 | mov eax, [esi] |
1154 | rol eax, 8 |
1157 | rol eax, 8 |
1155 | out dx, al ; LBA Low Previous LBA (31:24) |
1158 | out dx, al ; LBA Low Previous LBA (31:24) |
1156 | xor eax, eax ; because only 32 bit cache |
1159 | xor eax, eax ; because only 32 bit cache |
1157 | inc edx |
1160 | inc edx |
1158 | out dx, al ; LBA Mid Previous LBA (39:32) |
1161 | out dx, al ; LBA Mid Previous LBA (39:32) |
1159 | inc edx |
1162 | inc edx |
1160 | out dx, al ; LBA High Previous LBA (47:40) |
1163 | out dx, al ; LBA High Previous LBA (47:40) |
1161 | sub edx, 2 |
1164 | sub edx, 2 |
1162 | mov eax, [esi] |
1165 | mov eax, [esi] |
1163 | out dx, al ; LBA Low Current LBA (7:0) |
1166 | out dx, al ; LBA Low Current LBA (7:0) |
1164 | shr eax, 8 |
1167 | shr eax, 8 |
1165 | inc edx |
1168 | inc edx |
1166 | out dx, al ; LBA Mid Current LBA (15:8) |
1169 | out dx, al ; LBA Mid Current LBA (15:8) |
1167 | shr eax, 8 |
1170 | shr eax, 8 |
1168 | inc edx |
1171 | inc edx |
1169 | out dx, al ; LBA High Current LBA (23:16) |
1172 | out dx, al ; LBA High Current LBA (23:16) |
1170 | inc edx |
1173 | inc edx |
1171 | mov al, byte [hdid] |
1174 | mov al, byte [hdid] |
1172 | add al, 128+64+32 |
1175 | add al, 128+64+32 |
1173 | out dx, al ; номер головки/номер диска |
1176 | out dx, al ; номер головки/номер диска |
1174 | inc edx |
1177 | inc edx |
1175 | mov al, 35h ; WRITE DMA EXT |
1178 | mov al, 35h ; WRITE DMA EXT |
1176 | out dx, al ; ATACommand регистр команд |
1179 | out dx, al ; ATACommand регистр команд |
1177 | ;-------------------------------------- |
1180 | ;-------------------------------------- |
1178 | .continue: |
1181 | .continue: |
1179 | ; select controller Primary or Secondary |
1182 | ; select controller Primary or Secondary |
1180 | mov ecx, [IDE_controller_pointer] |
1183 | mov ecx, [IDE_controller_pointer] |
1181 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
1184 | mov dx, [ecx+IDE_DATA.RegsBaseAddres] |
1182 | 1185 | ||
1183 | mov eax, [hdpos] |
1186 | mov eax, [hdpos] |
1184 | dec eax |
1187 | dec eax |
1185 | test eax, 10b |
1188 | test eax, 10b |
1186 | jz @f |
1189 | jz @f |
1187 | 1190 | ||
1188 | add dx, 8 |
1191 | add dx, 8 |
1189 | ;-------------------------------------- |
1192 | ;-------------------------------------- |
1190 | @@: |
1193 | @@: |
1191 | ; set write to device and Start Bus Master |
1194 | ; set write to device and Start Bus Master |
1192 | mov al, 1 |
1195 | mov al, 1 |
1193 | out dx, al |
1196 | out dx, al |
1194 | 1197 | ||
1195 | mov eax, [hdpos] |
1198 | mov eax, [hdpos] |
1196 | dec eax |
1199 | dec eax |
1197 | test eax, 10b |
1200 | test eax, 10b |
1198 | jnz .ide1 |
1201 | jnz .ide1 |
1199 | 1202 | ||
1200 | mov [IDE_common_irq_param], irq14_num |
1203 | mov [IDE_common_irq_param], irq14_num |
1201 | jmp @f |
1204 | jmp @f |
1202 | ;-------------------------------------- |
1205 | ;-------------------------------------- |
1203 | .ide1: |
1206 | .ide1: |
1204 | mov [IDE_common_irq_param], irq15_num |
1207 | mov [IDE_common_irq_param], irq15_num |
1205 | ;-------------------------------------- |
1208 | ;-------------------------------------- |
1206 | @@: |
1209 | @@: |
1207 | popfd |
1210 | popfd |
1208 | ; wait for interrupt |
1211 | ; wait for interrupt |
1209 | mov [dma_cur_sector], not 0x40 |
1212 | mov [dma_cur_sector], not 0x40 |
1210 | 1213 | ||
1211 | mov eax, [hdpos] |
1214 | mov eax, [hdpos] |
1212 | dec eax |
1215 | dec eax |
1213 | test eax, 10b |
1216 | test eax, 10b |
1214 | jnz .wait_ide1 |
1217 | jnz .wait_ide1 |
1215 | 1218 | ||
1216 | call wait_for_sector_dma_ide0 |
1219 | call wait_for_sector_dma_ide0 |
1217 | 1220 | ||
1218 | jmp @f |
1221 | jmp @f |
1219 | ;-------------------------------------- |
1222 | ;-------------------------------------- |
1220 | .wait_ide1: |
1223 | .wait_ide1: |
1221 | call wait_for_sector_dma_ide1 |
1224 | call wait_for_sector_dma_ide1 |
1222 | ;-------------------------------------- |
1225 | ;-------------------------------------- |
1223 | @@: |
1226 | @@: |
1224 | cmp [hd_error], 0 |
1227 | cmp [hd_error], 0 |
1225 | jnz hd_write_error_dma |
1228 | jnz hd_write_error_dma |
1226 | pop esi |
1229 | pop esi |
1227 | ret |
1230 | ret |
1228 | ;----------------------------------------------------------------------------- |
1231 | ;----------------------------------------------------------------------------- |
1229 | proc clear_pci_ide_interrupts |
1232 | proc clear_pci_ide_interrupts |
1230 | mov esi, pcidev_list |
1233 | mov esi, pcidev_list |
1231 | ;-------------------------------------- |
1234 | ;-------------------------------------- |
1232 | align 4 |
1235 | align 4 |
1233 | .loop: |
1236 | .loop: |
1234 | mov esi, [esi+PCIDEV.fd] |
1237 | mov esi, [esi+PCIDEV.fd] |
1235 | cmp esi, pcidev_list |
1238 | cmp esi, pcidev_list |
1236 | jz .done |
1239 | jz .done |
1237 | 1240 | ||
1238 | ; cmp [esi+PCIDEV.class], 0x01018F |
1241 | ; cmp [esi+PCIDEV.class], 0x01018F |
1239 | mov eax, [esi+PCIDEV.class] |
1242 | mov eax, [esi+PCIDEV.class] |
1240 | shr eax, 4 |
1243 | shr eax, 4 |
1241 | cmp eax, 0x01018 |
1244 | cmp eax, 0x01018 |
1242 | jnz .loop |
1245 | jnz .loop |
1243 | 1246 | ||
1244 | mov ah, [esi+PCIDEV.bus] |
1247 | mov ah, [esi+PCIDEV.bus] |
1245 | mov al, 2 |
1248 | mov al, 2 |
1246 | mov bh, [esi+PCIDEV.devfn] |
1249 | mov bh, [esi+PCIDEV.devfn] |
1247 | mov bl, 0x20 |
1250 | mov bl, 0x20 |
1248 | call pci_read_reg |
1251 | call pci_read_reg |
1249 | 1252 | ||
1250 | and eax, 0FFFCh |
1253 | and eax, 0FFFCh |
1251 | mov edx, eax |
1254 | mov edx, eax |
1252 | add edx, 2 |
1255 | add edx, 2 |
1253 | in al, dx |
1256 | in al, dx |
1254 | DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al |
1257 | DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al |
1255 | out dx, al |
1258 | out dx, al |
1256 | in al, dx |
1259 | in al, dx |
1257 | DEBUGF 1,'-> %x; ',al |
1260 | DEBUGF 1,'-> %x; ',al |
1258 | add edx, 8 |
1261 | add edx, 8 |
1259 | in al, dx |
1262 | in al, dx |
1260 | DEBUGF 1,'port[%x] = %x ',dx,al |
1263 | DEBUGF 1,'port[%x] = %x ',dx,al |
1261 | out dx, al |
1264 | out dx, al |
1262 | in al, dx |
1265 | in al, dx |
1263 | DEBUGF 1,'-> %x\n',al |
1266 | DEBUGF 1,'-> %x\n',al |
1264 | jmp .loop |
1267 | jmp .loop |
1265 | ;-------------------------------------- |
1268 | ;-------------------------------------- |
1266 | .done: |
1269 | .done: |
1267 | ret |
1270 | ret |
1268 | endp |
1271 | endp |
1269 | ;----------------------------------------------------------------------------- |
1272 | ;----------------------------------------------------------------------------- |