Subversion Repositories Kolibri OS

Rev

Rev 4578 | Rev 4700 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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