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