Subversion Repositories Kolibri OS

Rev

Rev 5363 | Rev 5570 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5363 Rev 5569
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: 5569 $
Line 8... Line -...
8
$Revision: 5363 $
-
 
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
;-----------------------------------------------------------------
66
proc ide_read stdcall uses edi, \
71
proc ide_read stdcall uses esi edi ebx, \
67
        hd_data, buffer, startsector:qword, numsectors
72
        hd_data, buffer, startsector:qword, numsectors
68
        ; hd_data = pointer to hd*_data
73
        ; hd_data = pointer to hd*_data
69
        ; buffer = pointer to buffer for data
74
        ; buffer = pointer to buffer for data
70
        ; startsector = 64-bit start sector
75
        ; startsector = 64-bit start sector
71
        ; numsectors = pointer to number of sectors on input,
76
        ; numsectors = pointer to number of sectors on input,
72
        ;  must be filled with number of sectors really read
77
        ;  must be filled with number of sectors really read
73
locals
78
locals
74
sectors_todo    dd      ?
79
sectors_todo    dd      ?
75
channel_lock    dd      ?
80
channel_lock    dd      ?
76
endl
81
endl
77
; 1. Initialize number of sectors: get number of requested sectors
-
 
78
; and say that no sectors were read yet.
82
; get number of requested sectors and say that no sectors were read yet
79
        mov     ecx, [numsectors]
83
        mov     ecx, [numsectors]
80
        mov     eax, [ecx]
84
        mov     eax, [ecx]
81
        mov     dword [ecx], 0
85
        mov     dword [ecx], 0
82
        mov     [sectors_todo], eax
86
        mov     [sectors_todo], eax
83
; 2. Acquire the global lock.
87
; acquire the global lock
84
        mov     ecx, ide_mutex
88
        mov     ecx, ide_mutex
85
        call    mutex_lock
89
        call    mutex_lock
86
 
-
 
87
        mov     ecx, [hd_data]
90
        mov     ecx, [hd_data]
88
        mov     ecx, [ecx+HD_DATA.hdpos]
91
        mov     ecx, [ecx+HD_DATA.hdpos]
89
        dec     ecx
92
        dec     ecx
90
        shr     ecx, 1
93
        shr     ecx, 1
91
        shl     ecx, 2
94
        shl     ecx, 2
92
        mov     ecx, [ecx + ide_mutex_table]
95
        mov     ecx, [ecx + ide_mutex_table]
93
        mov     [channel_lock], ecx
96
        mov     [channel_lock], ecx
94
        call    mutex_lock
97
        call    mutex_lock
95
; 3. Convert parameters to the form suitable for worker procedures.
-
 
96
; Underlying procedures do not know about 64-bit sectors.
-
 
97
; Worker procedures use global variables and edi for [buffer].
98
; prepare worker procedures variables
98
        cmp     dword [startsector+4], 0
-
 
99
        jnz     .fail
-
 
100
 
-
 
101
        and     [hd_error], 0
-
 
102
        mov     ecx, [hd_data]
99
        mov     ecx, [hd_data]
103
        mov     eax, [ecx+HD_DATA.hdbase]
100
        mov     eax, [ecx+HD_DATA.hdbase]
104
        mov     [hdbase], eax
101
        mov     [hdbase], eax
105
        mov     eax, [ecx+HD_DATA.hdid]
102
        mov     eax, [ecx+HD_DATA.hdid]
106
        mov     [hdid], eax
103
        mov     [hdid], eax
107
        mov     eax, [ecx+HD_DATA.hdpos]
104
        mov     eax, [ecx+HD_DATA.hdpos]
108
        mov     [hdpos], eax
105
        mov     [hdpos], eax
109
        mov     eax, dword [startsector]
106
        mov     eax, dword [startsector]
110
        mov     edi, [buffer]
107
        mov     [sector], eax
111
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
-
 
112
.sectors_loop:
-
 
113
; DMA read is permitted if [allow_dma_access]=1 or 2
108
        mov     ax, word [startsector+4]
114
        cmp     [allow_dma_access], 2
109
        mov     [sector+4], ax
115
        ja      .nodma
110
        mov     esi, [buffer]
116
 
-
 
117
        push    eax ecx
111
        mov     bl, 25h     ; READ DMA EXT
118
        mov     ecx, [hdpos]
112
        mov     ecx, [hdpos]
119
        dec     ecx
113
        dec     ecx
120
        shr     ecx, 2
114
        shr     ecx, 2
121
        imul    ecx, sizeof.IDE_DATA
115
        imul    ecx, sizeof.IDE_DATA
122
        add     ecx, IDE_controller_1
116
        add     ecx, IDE_controller_1
123
        mov     [IDE_controller_pointer], ecx
117
        mov     [IDE_controller_pointer], ecx
124
 
-
 
125
        mov     eax, [hdpos]
118
        mov     eax, [hdpos]
126
        dec     eax
119
        dec     eax
127
        and     eax, 11b
120
        and     eax, 11b
128
        shr     eax, 1
121
        shr     eax, 1
129
        add     eax, ecx
122
        add     eax, ecx
130
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
123
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
131
        pop     ecx eax
124
        jz      .next
132
        jnz     .nodma
125
        dec     bl      ; READ SECTOR(S) EXT
133
 
-
 
134
        call    hd_read_dma
126
        mov     edi, esi
135
        jmp     @f
127
; worker procedures take max 8000h sectors per time
136
;--------------------------------------
128
; loop until all sectors will be processed
137
.nodma:
129
.next:
138
        call    hd_read_pio
130
        mov     ecx, 8000h
-
 
131
        cmp     ecx, [sectors_todo]
-
 
132
        jbe     @f
139
;--------------------------------------
133
        mov     ecx, [sectors_todo]
140
@@:
134
@@:
-
 
135
        mov     [blockSize], ecx
-
 
136
        push    ecx
141
        cmp     [hd_error], 0
137
        call    IDE_transfer
-
 
138
        pop     ecx
142
        jnz     .fail
139
        jc      .out
143
 
-
 
144
        mov     ecx, [numsectors]
140
        mov     eax, [numsectors]
145
        inc     dword [ecx]     ; one more sector is read
141
        add     [eax], ecx
146
        dec     [sectors_todo]
142
        sub     [sectors_todo], ecx
147
        jz      .done
143
        jz      .out
148
 
-
 
149
        inc     eax
144
        add     [sector], ecx
150
        jnz     .sectors_loop
145
        adc     word [sector+4], 0
151
;--------------------------------------
146
        jmp     .next
152
; 5. Loop is done, either due to error or because everything is done.
147
; loop is done, either due to error or because everything is done
153
; Release the global lock and return the corresponding status.
148
; release the global lock and return the corresponding status
154
.fail:
149
.out:
155
        mov     ecx, [channel_lock]
-
 
156
        call    mutex_unlock
-
 
157
 
-
 
158
        mov     ecx, ide_mutex
150
        sbb     eax, eax
159
        call    mutex_unlock
-
 
160
 
-
 
161
        or      eax, -1
151
        push    eax
162
        ret
-
 
163
;--------------------------------------
-
 
164
.done:
-
 
165
        mov     ecx, [channel_lock]
152
        mov     ecx, [channel_lock]
166
        call    mutex_unlock
153
        call    mutex_unlock
167
 
-
 
168
        mov     ecx, ide_mutex
154
        mov     ecx, ide_mutex
169
        call    mutex_unlock
155
        call    mutex_unlock
170
 
-
 
171
        xor     eax, eax
156
        pop     eax
172
        ret
157
        ret
173
endp
158
endp
174
;-----------------------------------------------------------------------------
159
;-----------------------------------------------------------------
175
proc ide_write stdcall uses esi edi, \
160
proc ide_write stdcall uses esi edi ebx, \
176
        hd_data, buffer, startsector:qword, numsectors
161
        hd_data, buffer, startsector:qword, numsectors
177
        ; hd_data = pointer to hd*_data
162
        ; hd_data = pointer to hd*_data
178
        ; buffer = pointer to buffer with data
163
        ; buffer = pointer to buffer with data
179
        ; startsector = 64-bit start sector
164
        ; startsector = 64-bit start sector
180
        ; numsectors = pointer to number of sectors on input,
165
        ; numsectors = pointer to number of sectors on input,
181
        ;  must be filled with number of sectors really written
166
        ;  must be filled with number of sectors really written
182
locals
167
locals
183
sectors_todo    dd      ?
168
sectors_todo    dd      ?
184
channel_lock    dd      ?
169
channel_lock    dd      ?
185
endl
170
endl
186
; 1. Initialize number of sectors: get number of requested sectors
-
 
187
; and say that no sectors were read yet.      
171
; get number of requested sectors and say that no sectors were read yet
188
        mov     ecx, [numsectors]
172
        mov     ecx, [numsectors]
189
        mov     eax, [ecx]
173
        mov     eax, [ecx]
190
        mov     dword [ecx], 0
174
        mov     dword [ecx], 0
191
        mov     [sectors_todo], eax
175
        mov     [sectors_todo], eax
192
; 2. Acquire the global lock.
176
; acquire the global lock
193
        mov     ecx, ide_mutex
177
        mov     ecx, ide_mutex
194
        call    mutex_lock
178
        call    mutex_lock
195
 
-
 
196
        mov     ecx, [hd_data]
179
        mov     ecx, [hd_data]
197
        mov     ecx, [ecx+HD_DATA.hdpos]
180
        mov     ecx, [ecx+HD_DATA.hdpos]
198
        dec     ecx
181
        dec     ecx
199
        shr     ecx, 1
182
        shr     ecx, 1
200
        shl     ecx, 2
183
        shl     ecx, 2
201
        mov     ecx, [ecx + ide_mutex_table]
184
        mov     ecx, [ecx + ide_mutex_table]
202
        mov     [channel_lock], ecx
185
        mov     [channel_lock], ecx
203
        call    mutex_lock
186
        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].
187
; prepare worker procedures variables
207
        cmp     dword [startsector+4], 0
-
 
208
        jnz     .fail
-
 
209
 
-
 
210
        and     [hd_error], 0
-
 
211
        mov     ecx, [hd_data]
188
        mov     ecx, [hd_data]
212
        mov     eax, [ecx+HD_DATA.hdbase]
189
        mov     eax, [ecx+HD_DATA.hdbase]
213
        mov     [hdbase], eax
190
        mov     [hdbase], eax
214
        mov     eax, [ecx+HD_DATA.hdid]
191
        mov     eax, [ecx+HD_DATA.hdid]
215
        mov     [hdid], eax
192
        mov     [hdid], eax
216
        mov     eax, [ecx+HD_DATA.hdpos]
193
        mov     eax, [ecx+HD_DATA.hdpos]
217
        mov     [hdpos], eax
194
        mov     [hdpos], eax
-
 
195
        mov     eax, dword [startsector]
-
 
196
        mov     [sector], eax
-
 
197
        mov     ax, word [startsector+4]
-
 
198
        mov     [sector+4], ax
218
        mov     esi, [buffer]
199
        mov     esi, [buffer]
219
        lea     edi, [startsector]
-
 
220
        mov     [cache_chain_ptr], edi
200
        mov     bl, 35h     ; WRITE DMA EXT
221
; 4. Worker procedures take max 16 sectors per time,
-
 
222
; loop until all sectors will be processed.
-
 
223
.sectors_loop:
-
 
224
        mov     ecx, 16
-
 
225
        cmp     ecx, [sectors_todo]
-
 
226
        jbe     @f
-
 
227
 
-
 
228
        mov     ecx, [sectors_todo]
-
 
229
;--------------------------------------
-
 
230
@@:
-
 
231
        mov     [cache_chain_size], cl
-
 
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
-
 
237
        mov     ecx, [hdpos]
201
        mov     ecx, [hdpos]
238
        dec     ecx
202
        dec     ecx
239
        shr     ecx, 2
203
        shr     ecx, 2
240
        imul    ecx, sizeof.IDE_DATA
204
        imul    ecx, sizeof.IDE_DATA
241
        add     ecx, IDE_controller_1
205
        add     ecx, IDE_controller_1
242
        mov     [IDE_controller_pointer], ecx
206
        mov     [IDE_controller_pointer], ecx
243
 
-
 
244
        mov     eax, [hdpos]
207
        mov     eax, [hdpos]
245
        dec     eax
208
        dec     eax
246
        and     eax, 11b
209
        and     eax, 11b
247
        shr     eax, 1
210
        shr     eax, 1
248
        add     eax, ecx
211
        add     eax, ecx
249
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
212
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
250
        pop     ecx eax
213
        jz      .next
-
 
214
        dec     bl      ; WRITE SECTOR(S) EXT
-
 
215
; worker procedures take max 8000h sectors per time
-
 
216
; loop until all sectors will be processed
-
 
217
.next:
251
        jnz     .nodma
218
        mov     ecx, 8000h
252
 
-
 
253
        call    cache_write_dma
219
        cmp     ecx, [sectors_todo]
254
        jmp     .common
220
        jbe     @f
255
;--------------------------------------
221
        mov     ecx, [sectors_todo]
256
.nodma:
222
@@:
257
        mov     [cache_chain_size], 1
223
        mov     [blockSize], ecx
258
        call    cache_write_pio
224
        push    ecx
259
;--------------------------------------
-
 
260
.common:
-
 
261
        cmp     [hd_error], 0
225
        call    IDE_transfer
262
        jnz     .fail
226
        pop     ecx
263
 
-
 
264
        movzx   ecx, [cache_chain_size]
227
        jc      .out
265
        mov     eax, [numsectors]
228
        mov     eax, [numsectors]
266
        add     [eax], ecx
229
        add     [eax], ecx
267
        sub     [sectors_todo], ecx
230
        sub     [sectors_todo], ecx
268
        jz      .done
231
        jz      .out
269
 
-
 
270
        add     [edi], ecx
232
        add     [sector], ecx
271
        jc      .fail
-
 
272
 
-
 
273
        shl     ecx, 9
-
 
274
        add     esi, ecx
233
        adc     word [sector+4], 0
275
        jmp     .sectors_loop
234
        jmp     .next
276
;--------------------------------------
-
 
277
; 5. Loop is done, either due to error or because everything is done.
235
; loop is done, either due to error or because everything is done
278
; Release the global lock and return the corresponding status.
236
; release the global lock and return the corresponding status
279
.fail:
237
.out:
280
        mov     ecx, [channel_lock]
-
 
281
        call    mutex_unlock
-
 
282
 
-
 
283
        mov     ecx, ide_mutex
238
        sbb     eax, eax
284
        call    mutex_unlock
-
 
285
 
-
 
286
        or      eax, -1
239
        push    eax
287
        ret
-
 
288
;--------------------------------------
-
 
289
.done:
-
 
290
        mov     ecx, [channel_lock]
240
        mov     ecx, [channel_lock]
291
        call    mutex_unlock
241
        call    mutex_unlock
292
 
-
 
293
        mov     ecx, ide_mutex
242
        mov     ecx, ide_mutex
294
        call    mutex_unlock
243
        call    mutex_unlock
295
 
-
 
296
        xor     eax, eax
244
        pop     eax
297
        ret
245
        ret
298
endp
246
endp
299
;-----------------------------------------------------------------------------
247
;-----------------------------------------------------------------
300
; This is a stub.
248
; this is a stub
301
proc ide_querymedia stdcall, hd_data, mediainfo
249
proc ide_querymedia stdcall, hd_data, mediainfo
302
        mov     eax, [mediainfo]
250
        mov     eax, [mediainfo]
303
        mov     [eax+DISKMEDIAINFO.Flags], 0
251
        mov     [eax+DISKMEDIAINFO.Flags], 0
304
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
252
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
305
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
253
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
306
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
254
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
307
        xor     eax, eax
255
        xor     eax, eax
308
        ret
256
        ret
309
endp
257
endp
310
;-----------------------------------------------------------------------------
258
;-----------------------------------------------------------------
311
align 4
-
 
312
; input: eax = sector, edi -> buffer
259
; input: esi -> buffer, bl = command, [sector], [blockSize]
313
; output: edi = edi + 512
260
; output: esi -> next block in buffer
314
hd_read_pio:
-
 
315
        push    eax edx
261
; for pio read esi equal edi
316
; Select the desired drive
262
IDE_transfer:
317
        mov     edx, [hdbase]
263
        mov     edx, [hdbase]
318
        add     edx, 6   ;адрСс рСгистра Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
264
        add     edx, 6
319
        mov     al, byte [hdid]
265
        mov     al, byte [hdid]
320
        add     al, 128+64+32
266
        add     al, 224
321
        out     dx, al; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
267
        out     dx, al  ; select the desired drive
322
        
-
 
323
        call    wait_for_hd_idle
268
        call    save_hd_wait_timeout
-
 
269
        inc     edx
324
 
270
@@:
325
        cmp     [hd_error], 0
271
        call    check_hd_wait_timeout
326
        jne     hd_read_error
272
        jc      .hd_error
327
; ATA with 28 or 48 bit for sector number?
-
 
328
        mov     eax, [esp+4]
273
        in      al, dx
329
        cmp     eax, 0x10000000
274
        test    al, 128 ; ready for command?
330
        jae     .lba48
275
        jnz     @b
331
;--------------------------------------
-
 
332
.lba28:
-
 
333
        pushfd
276
        pushfd          ; fill the ports
334
        cli
277
        cli
335
        xor     eax, eax
-
 
336
        mov     edx, [hdbase]
278
        mov     edx, [hdbase]
337
        inc     edx
279
        inc     edx
338
        out     dx, al ; ATA Features рСгистр "особСнностСй"
-
 
339
        inc     edx
280
        inc     edx
340
        inc     eax
281
        mov     al, [blockSize+1]
341
        out     dx, al ; ATA Sector Counter счётчик сСкторов
282
        out     dx, al  ; Sector count (15:8)
342
        inc     edx
283
        inc     edx
343
        mov     eax, [esp+4+4]
284
        mov     eax, [sector+3]
344
        out     dx, al ; LBA Low LBA (7:0)
285
        out     dx, al  ; LBA (31:24)
345
        shr     eax, 8
-
 
346
        inc     edx
286
        inc     edx
347
        out     dx, al ; LBA Mid LBA (15:8)
-
 
348
        shr     eax, 8
287
        shr     eax, 8
-
 
288
        out     dx, al  ; LBA (39:32)
349
        inc     edx
289
        inc     edx
350
        out     dx, al ; LBA High LBA (23:16)
-
 
351
        shr     eax, 8
290
        shr     eax, 8
-
 
291
        out     dx, al  ; LBA (47:40)
-
 
292
        sub     edx, 3
-
 
293
        mov     al, [blockSize]
-
 
294
        out     dx, al  ; Sector count (7:0)
352
        inc     edx
295
        inc     edx
353
        and     al, 1+2+4+8 ; LBA (27:24)
-
 
354
        add     al, byte [hdid]
296
        mov     eax, [sector]
355
        add     al, 128+64+32
297
        out     dx, al  ; LBA (7:0)
356
        out     dx, al ; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
-
 
357
        inc     edx
298
        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]
-
 
368
        inc     edx
-
 
369
        out     dx, al ; Features Previous Reserved
-
 
370
        out     dx, al ; Features Current Reserved
-
 
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
-
 
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
299
        shr     eax, 8
-
 
300
        out     dx, al  ; LBA (15:8)
388
        inc     edx
301
        inc     edx
389
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
390
        shr     eax, 8
302
        shr     eax, 8
391
        inc     edx
-
 
392
        out     dx, al ; LBA High Current LBA (23:16)
303
        out     dx, al  ; LBA (23:16)
393
        inc     edx
304
        inc     edx
394
        mov     al, byte [hdid]
305
        mov     al, byte [hdid]
395
        add     al, 128+64+32
306
        add     al, 224
-
 
307
        out     dx, al
-
 
308
        test    bl, 1
-
 
309
        jz      .PIO
-
 
310
; DMA
-
 
311
        mov     dword [esp], 0x1000
-
 
312
        call    kernel_alloc
-
 
313
        mov     edi, eax
-
 
314
        push    eax
-
 
315
        shl     dword [blockSize], 9
-
 
316
        mov     eax, esi
-
 
317
        add     eax, [blockSize]
-
 
318
        push    eax
-
 
319
; check buffer pages physical addresses and fill the scatter-gather list
396
        out     dx, al ; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
320
; buffer may be not aligned and may have size not divisible by page size
-
 
321
; [edi] = block physical address, [edi+4] = block size in bytes
-
 
322
; block addresses can not cross 10000h borders
-
 
323
        mov     ecx, esi
-
 
324
        and     ecx, 0xFFF
-
 
325
        jz      .aligned
-
 
326
        mov     eax, esi
-
 
327
        call    get_pg_addr
-
 
328
        add     eax, ecx
397
        inc     edx
329
        neg     ecx
-
 
330
        add     ecx, 0x1000
398
        mov     al, 24h ; READ SECTOR(S) EXT
331
        mov     [edi], eax
399
        out     dx, al ; ATACommand рСгистр ΠΊΠΎΠΌΠ°Π½Π΄
332
        cmp     ecx, [blockSize]
400
        popfd
333
        jnc     .end
-
 
334
        mov     [edi+4], ecx
-
 
335
        add     esi, 0x1000
-
 
336
        add     edi, 8
401
;--------------------------------------
337
        sub     [blockSize], ecx
402
.continue:
338
.aligned:
-
 
339
        mov     eax, esi
403
        call    wait_for_sector_buffer
340
        call    get_pg_addr
-
 
341
        mov     ecx, eax
-
 
342
        mov     [edi], eax
-
 
343
        and     ecx, 0xFFFF
-
 
344
        neg     ecx
-
 
345
        add     ecx, 0x10000
-
 
346
        cmp     [blockSize], ecx
-
 
347
        jnc     @f
-
 
348
        mov     ecx, [blockSize]
-
 
349
        and     ecx, 0xF000
-
 
350
        jz      .end
-
 
351
@@:
-
 
352
        push    ecx
404
 
353
@@:
-
 
354
        add     esi, 0x1000
-
 
355
        add     eax, 0x1000
-
 
356
        sub     ecx, 0x1000
-
 
357
        jz      @f
-
 
358
        mov     edx, eax
-
 
359
        mov     eax, esi
-
 
360
        call    get_pg_addr
405
        cmp     [hd_error], 0
361
        cmp     eax, edx
-
 
362
        jz      @b
-
 
363
@@:
-
 
364
        pop     edx
-
 
365
        sub     edx, ecx
-
 
366
        mov     [edi+4], edx
-
 
367
        add     edi, 8
-
 
368
        sub     [blockSize], edx
406
        jne     hd_read_error
369
        jnz     .aligned
-
 
370
        sub     edi, 8
-
 
371
        jmp     @f
-
 
372
.end:
-
 
373
        mov     ecx, [blockSize]
-
 
374
        mov     [edi+4], ecx
-
 
375
@@:
-
 
376
        mov     byte [edi+7], 80h   ; list end
-
 
377
        pop     esi
-
 
378
        pop     edi
-
 
379
; select controller Primary or Secondary
-
 
380
        mov     ecx, [IDE_controller_pointer]
-
 
381
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
-
 
382
        mov     eax, [hdpos]
-
 
383
        dec     eax
-
 
384
        test    eax, 10b
-
 
385
        jz      @f
-
 
386
        add     edx, 8
-
 
387
@@:
-
 
388
        add     edx, 2      ; Bus Master IDE Status register
-
 
389
        mov     al, 6
-
 
390
        out     dx, al      ; clear Error bit and Interrupt bit
Line 407... Line 391...
407
 
391
 
408
        pushfd
-
 
409
        cli
392
        add     edx, 2      ; Bus Master IDE PRD Table Address
410
        mov     ecx, 256
393
        mov     eax, edi
411
        mov     edx, [hdbase]
-
 
412
        cld
394
        call    get_pg_addr
413
        rep insw
-
 
Line 414... Line 395...
414
        popfd
395
        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:
396
 
422
; Select the desired drive
-
 
423
        mov     edx, [hdbase]
397
        push    edx
424
        add     edx, 6   ;адрСс рСгистра Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
398
        mov     edx, [hdbase]
425
        mov     al, byte [hdid]
-
 
426
        add     al, 128+64+32
-
 
427
        out     dx, al ; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
399
        add     edx, 7      ; ATACommand
428
 
-
 
429
        call    wait_for_hd_idle
400
        mov     al, bl
430
 
-
 
Line 431... Line 401...
431
        cmp     [hd_error], 0
401
        out     dx, al      ; Start hard drive
432
        jne     hd_write_error
402
        pop     edx
433
 
403
 
434
; ATA with 28 or 48 bit for sector number?
404
        sub     edx, 4      ; Bus Master IDE Command register
435
        mov     eax, [edi]
405
        mov     al, 1       ; set direction
436
        cmp     eax, 0x10000000
406
        cmp     bl, 35h     ; write
437
        jae     .lba48
-
 
438
;--------------------------------------
-
 
439
.lba28:
407
        jz      @f
440
        pushfd
408
        add     al, 8       ; read
441
        cli
-
 
442
        xor     eax, eax
-
 
443
        mov     edx, [hdbase]
409
@@:
444
        inc     edx
410
        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
411
        mov     [IDE_common_irq_param], 14
450
        mov     eax, [edi]      ; eax = sector to write
412
        mov     eax, [hdpos]
451
        out     dx, al ; LBA Low LBA (7:0)
413
        dec     eax
452
        shr     eax, 8
414
        test    eax, 10b
453
        inc     edx
415
        jz      @f
454
        out     dx, al ; LBA Mid LBA (15:8)
-
 
455
        shr     eax, 8
416
        inc     [IDE_common_irq_param]
456
        inc     edx
417
@@:
457
        out     dx, al ; LBA High LBA (23:16)
-
 
458
        shr     eax, 8
418
        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
419
        xor     ecx, ecx
463
        out     dx, al ; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
-
 
464
        inc     edx
420
        xor     esi, esi
465
        mov     al, 30h ; WRITE SECTOR(S)
-
 
466
        out     dx, al ; ATACommand рСгистр ΠΊΠΎΠΌΠ°Π½Π΄
-
 
467
        jmp     .continue
-
 
468
;--------------------------------------
421
        call    create_event
469
.lba48:
422
        mov     [eventPointer], eax
470
        pushfd
423
        mov     [eventID], edx
471
        cli
-
 
472
        xor     eax, eax
-
 
473
        mov     edx, [hdbase]
424
        sti
474
        inc     edx
425
        mov     ebx, edx
475
        out     dx, al ; Features Previous Reserved
-
 
476
        out     dx, al ; Features Current Reserved
426
        mov     ecx, 300
477
        inc     edx
427
        call    wait_event_timeout
478
        out     dx, al ; Sector Count Previous Sector count (15:8)
428
        test    eax, eax
479
        inc     eax
429
        jnz     @f
480
        out     dx, al ; Sector Count Current Sector count (7:0)
430
        mov     [IDE_common_irq_param], 0
481
        inc     edx
-
 
482
        mov     eax, [edi]
-
 
483
        rol     eax, 8
431
        mov     eax, [eventPointer]
484
        out     dx, al ; LBA Low Previous LBA (31:24)
-
 
485
        xor     eax, eax ; because only 32 bit cache
432
        mov     ebx, [eventID]
486
        inc     edx
-
 
487
        out     dx, al ; LBA Mid Previous LBA (39:32)
433
        call    destroy_event
488
        inc     edx
434
        mov     [eventPointer], 0
489
        out     dx, al ; LBA High Previous LBA (47:40)
-
 
490
        sub     edx, 2
435
@@:
491
        mov     eax, [edi]
436
        pop     ebx esi
492
        out     dx, al ; LBA Low Current LBA (7:0)
-
 
493
        shr     eax, 8
437
        call    kernel_free
494
        inc     edx
438
        cmp     [eventPointer], 0
495
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
496
        shr     eax, 8
439
        jz      .hd_error
497
        inc     edx
440
        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
441
.PIO:
502
        out     dx, al ; Π½ΠΎΠΌΠ΅Ρ€ Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ/Π½ΠΎΠΌΠ΅Ρ€ диска
-
 
503
        inc     edx
-
 
504
        mov     al, 34h ; WRITE SECTOR(S) EXT
-
 
505
        out     dx, al ; ATACommand рСгистр ΠΊΠΎΠΌΠ°Π½Π΄
442
        inc     edx     ; ATACommand
-
 
443
        mov     al, bl
506
;--------------------------------------
444
        out     dx, al  ; Start hard drive
-
 
445
        popfd
-
 
446
.sectorTransfer:
-
 
447
        call    save_hd_wait_timeout
-
 
448
        in      al, dx
507
.continue:
449
        in      al, dx
-
 
450
        in      al, dx
508
        popfd
451
        in      al, dx
509
        call    wait_for_sector_buffer
452
@@:
510
 
-
 
-
 
453
        call    check_hd_wait_timeout
-
 
454
        jc      .hd_error
-
 
455
        in      al, dx
511
        cmp     [hd_error], 0
456
        test    al, 8   ; ready for transfer?
-
 
457
        jz      @b
-
 
458
        cmp     [hd_setup], 1   ; do not mark error for setup request
512
        jne     hd_write_error
459
        jz      @f
513
 
460
        test    al, 1   ; previous command ended up with an error
514
        push    ecx esi
461
        jnz     .hd_error
-
 
462
@@:
515
 
463
        pushfd
516
        pushfd
464
        cli
-
 
465
        cld
-
 
466
        mov     ecx, 256
517
        cli
467
        mov     edx, [hdbase]
-
 
468
        cmp     bl, 34h
-
 
469
        jz      .write
518
        mov     ecx, 256
470
        rep insw
-
 
471
        jmp     @f
519
        mov     edx, [hdbase]
472
.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]
473
        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:
474
@@:
538
        push    eax
-
 
539
        mov     eax, [hd_wait_timeout]
-
 
540
        cmp     [timer_ticks], eax
-
 
541
        jg      hd_timeout_error
475
        popfd
542
 
476
        add     edx, 7
543
        pop     eax
-
 
544
        mov     [hd_error], 0
477
        dec     dword [blockSize]
545
        ret
478
        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
479
        ret
551
        DEBUGF 1,"K : FS - HD timeout\n"
-
 
552
        end if
-
 
553
        mov     [hd_error], 1
480
.hd_error:
554
        pop     eax
481
        cmp     bl, 30h
555
        ret
482
        jnc     hd_write_error
556
;-----------------------------------------------------------------------------
483
;-----------------------------------------------------------------
557
hd_read_error:
484
hd_read_error:
558
        if lang eq sp
485
        if lang eq sp
559
        DEBUGF 1,"K : FS - HD error de lectura\n"
486
        DEBUGF 1,"K : FS - HD error de lectura\n"
560
        else
487
        else
561
        DEBUGF 1,"K : FS - HD read error\n"
488
        DEBUGF 1,"K : FS - HD read error\n"
562
        end if
489
        end if
563
        pop     edx eax
-
 
564
        ret
-
 
565
;-----------------------------------------------------------------------------
490
        stc
566
hd_write_error_dma:
491
        ret
567
        pop     esi
492
;-----------------------------------------------------------------
568
hd_write_error:
493
hd_write_error:
569
        if lang eq sp
494
        if lang eq sp
570
        DEBUGF 1,"K : FS - HD error de escritura\n"
495
        DEBUGF 1,"K : FS - HD error de escritura\n"
-
 
496
        else
571
        else
497
        DEBUGF 1,"K : FS - HD write error\n"
572
        DEBUGF 1,"K : FS - HD write error\n"
498
        end if
573
        end if
-
 
574
        ret
-
 
575
;-----------------------------------------------------------------------------
-
 
576
align 4
-
 
577
wait_for_hd_idle:
499
        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:
500
        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:
501
;-----------------------------------------------------------------
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:
502
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:
503
        mov     eax, [timer_ticks]
684
        pop     edx
504
        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
505
        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
506
        ret
717
        pushad
-
 
718
        mov     [IDE_common_irq_param], 0
-
 
719
        mov     ecx, [IDE_controller_pointer]
-
 
720
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
507
;-----------------------------------------------------------------
721
; test whether it is our interrupt?
-
 
722
        add     edx, 2
508
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
509
        mov     eax, [timer_ticks]
738
        popfd
-
 
739
        mov     al, 1
510
        cmp     [hd_wait_timeout], eax
740
        ret
511
        jc      @f
-
 
512
        ret
741
;--------------------------------------
513
@@:
742
@@:
514
        if lang eq sp
743
        popad
515
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
744
        popfd
516
        else
745
;--------------------------------------
517
        DEBUGF 1,"K : FS - HD timeout\n"
746
.exit:
518
        end if
747
        mov     al, 0
519
        stc
-
 
520
        ret
748
        ret
521
;-----------------------------------------------------------------
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
522
align 4
791
;-----------------------------------------------------------------------------
523
IDE_irq_14_handler:
-
 
524
IDE_irq_15_handler:
-
 
525
IDE_common_irq_handler:
792
align 4
526
; DEBUGF  1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2
793
IDE_common_irq_handler:
527
        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
528
        jz      .exit
798
        je      .exit
-
 
799
 
529
        pushfd
800
        pushad
530
        cli
801
        xor     ebx, ebx
531
        pushad
802
        mov     ecx, [IDE_controller_pointer]
-
 
803
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
-
 
804
        mov     eax, IDE_common_irq_param
532
        mov     ecx, [IDE_controller_pointer]
805
        cmp     [eax], irq14_num
-
 
806
        mov     [eax], bl
533
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
807
        je      @f
-
 
808
 
534
        cmp     [IDE_common_irq_param], 14
809
        add     dx, 8
-
 
810
;--------------------------------------
535
        jz      @f
811
@@:
536
        add     dx, 8
812
; test whether it is our interrupt?
537
@@:
813
        add     edx, 2
538
        add     edx, 2  ; Bus Master IDE Status register
814
        in      al, dx
539
        in      al, dx
815
        test    al, 100b
-
 
816
        jz      @f
540
        test    al, 4
817
; clear Bus Master IDE Status register
-
 
818
; clear Interrupt bit
541
        jz      @f
819
        out     dx, al
542
        mov     [IDE_common_irq_param], 0
820
; clear Bus Master IDE Command register
-
 
821
        sub     edx, 2
543
        out     dx, al  ; clear Interrupt bit
822
        xor     eax, eax
544
        sub     edx, 2
823
        out     dx, al
545
        xor     eax, eax
-
 
546
        out     dx, al  ; clear Bus Master IDE Command register
-
 
547
        mov     edx, [hdbase]
-
 
548
        add     edx, 7
824
; read status register and remove the interrupt request
549
        in      al, dx  ; read status register
-
 
550
        mov     eax, [eventPointer]
-
 
551
        mov     ebx, [eventID]
825
        mov     edx, [hdbase]
552
        xor     edx, edx
826
        add     edx, 0x7
553
        xor     esi, esi
827
        in      al, dx
554
        call    raise_event
828
        popad
555
        popad
829
        popfd
-
 
830
        mov     al, 1
556
        popfd
831
        ret
557
        mov     al, 1   ; remove the interrupt request
832
;--------------------------------------
-
 
833
@@:
-
 
834
        popad
558
        ret
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
559
@@:
1016
        jmp     @f
-
 
1017
;--------------------------------------
-
 
1018
.ide1:
-
 
1019
        mov     [IDE_common_irq_param], irq15_num
-
 
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 рСгистр ΠΊΠΎΠΌΠ°Π½Π΄
-
 
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]
560
        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
561
        popfd
1228
        jnz     hd_write_error_dma
562
.exit:
1229
        pop     esi
563
        xor     eax, eax    ; not our interrupt
1230
        ret
564
        ret
1231
;-----------------------------------------------------------------------------
-
 
1232
proc clear_pci_ide_interrupts
565
;-----------------------------------------------------------------
1233
        mov     esi, pcidev_list
566
proc clear_pci_ide_interrupts
1234
;--------------------------------------
567
        mov     esi, pcidev_list
1235
align 4
568
align 4
1236
.loop:
569
.loop:
Line 1263... Line 596...
1263
        DEBUGF 1,'port[%x] = %x ',dx,al
596
        DEBUGF 1,'port[%x] = %x ',dx,al
1264
        out     dx, al
597
        out     dx, al
1265
        in      al, dx
598
        in      al, dx
1266
        DEBUGF 1,'-> %x\n',al
599
        DEBUGF 1,'-> %x\n',al
1267
        jmp     .loop
600
        jmp     .loop
1268
;--------------------------------------
-
 
1269
.done:
601
.done:
1270
        ret
602
        ret
1271
endp
603
endp
1272
;-----------------------------------------------------------------------------
-