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