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