Subversion Repositories Kolibri OS

Rev

Rev 6016 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6016 Rev 6843
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 6016 $
8
$Revision: 6843 $
9
 
9
 
10
; Disk access through BIOS
10
; Disk access through BIOS
11
iglobal
11
iglobal
12
align 4
12
align 4
13
bd_callbacks:
13
bd_callbacks:
14
        dd      bd_callbacks.end - bd_callbacks     ; strucsize
14
        dd      bd_callbacks.end - bd_callbacks     ; strucsize
15
        dd      0   ; no close function
15
        dd      0   ; no close function
16
        dd      0   ; no closemedia function
16
        dd      0   ; no closemedia function
17
        dd      bd_querymedia
17
        dd      bd_querymedia
18
        dd      bd_read_interface
18
        dd      bd_read_interface
19
        dd      bd_write_interface
19
        dd      bd_write_interface
20
        dd      0   ; no flush function
20
        dd      0   ; no flush function
21
        dd      0   ; use default cache size
21
        dd      0   ; use default cache size
22
.end:
22
.end:
23
endg
23
endg
24
 
24
 
25
uglobal
25
uglobal
26
bios_hdpos          dd 0
26
bios_hdpos          dd 0
27
bios_cur_sector     dd ?
27
bios_cur_sector     dd ?
28
bios_read_len       dd ?
28
bios_read_len       dd ?
29
cache_chain_ptr     dd ?
29
cache_chain_ptr     dd ?
30
int13_regs_in       rb sizeof.v86_regs
30
int13_regs_in       rb sizeof.v86_regs
31
int13_regs_out      rb sizeof.v86_regs
31
int13_regs_out      rb sizeof.v86_regs
32
cache_chain_size    db ?
32
cache_chain_size    db ?
33
endg
33
endg
-
 
34
 
-
 
35
struct BiosDiskData
-
 
36
        DriveNumber     db ?
-
 
37
        IRQ             db ?
-
 
38
        ATADEVbit       dw ?
-
 
39
        SectorSize      dd ?
-
 
40
        Capacity        dq ?
-
 
41
ends
34
;-----------------------------------------------------------------
42
;-----------------------------------------------------------------
35
proc bd_read_interface stdcall uses edi, \
43
proc bd_read_interface stdcall uses edi, \
36
        userdata, buffer, startsector:qword, numsectors
44
        userdata, buffer, startsector:qword, numsectors
37
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
45
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
38
        ; buffer = pointer to buffer for data
46
        ; buffer = pointer to buffer for data
39
        ; startsector = 64-bit start sector
47
        ; startsector = 64-bit start sector
40
        ; numsectors = pointer to number of sectors on input,
48
        ; numsectors = pointer to number of sectors on input,
41
        ;  must be filled with number of sectors really read
49
        ;  must be filled with number of sectors really read
42
locals
50
locals
43
sectors_todo    dd      ?
51
sectors_todo    dd      ?
44
endl
52
endl
45
; 1. Initialize number of sectors: get number of requested sectors
53
; 1. Initialize number of sectors: get number of requested sectors
46
; and say that no sectors were read yet.
54
; and say that no sectors were read yet.
47
        mov     ecx, [numsectors]
55
        mov     ecx, [numsectors]
48
        mov     eax, [ecx]
56
        mov     eax, [ecx]
49
        mov     dword [ecx], 0
57
        mov     dword [ecx], 0
50
        mov     [sectors_todo], eax
58
        mov     [sectors_todo], eax
51
; 2. Acquire the global lock.
59
; 2. Acquire the global lock.
52
        mov     ecx, ide_mutex
60
        mov     ecx, ide_mutex
53
        call    mutex_lock
61
        call    mutex_lock
54
; 3. Convert parameters to the form suitable for worker procedures.
62
; 3. Convert parameters to the form suitable for worker procedures.
55
; Underlying procedures do not know about 64-bit sectors.
63
; Underlying procedures do not know about 64-bit sectors.
56
; Worker procedures use global variables and edi for [buffer].
64
; Worker procedures use global variables and edi for [buffer].
57
        cmp     dword [startsector+4], 0
65
        cmp     dword [startsector+4], 0
58
        jnz     .fail
66
        jnz     .fail
59
        and     [hd_error], 0
67
        and     [hd_error], 0
60
        mov     eax, [userdata]
68
        mov     eax, [userdata]
61
        mov     [hdpos], eax
69
        mov     [hdpos], eax
62
        mov     eax, dword [startsector]
70
        mov     eax, dword [startsector]
63
        mov     edi, [buffer]
71
        mov     edi, [buffer]
64
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
72
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
65
.sectors_loop:
73
.sectors_loop:
66
        call    bd_read
74
        call    bd_read
67
        cmp     [hd_error], 0
75
        cmp     [hd_error], 0
68
        jnz     .fail
76
        jnz     .fail
69
        mov     ecx, [numsectors]
77
        mov     ecx, [numsectors]
70
        inc     dword [ecx]     ; one more sector is read
78
        inc     dword [ecx]     ; one more sector is read
71
        dec     [sectors_todo]
79
        dec     [sectors_todo]
72
        jz      .done
80
        jz      .done
73
        inc     eax
81
        inc     eax
74
        jnz     .sectors_loop
82
        jnz     .sectors_loop
75
; 5. Loop is done, either due to error or because everything is done.
83
; 5. Loop is done, either due to error or because everything is done.
76
; Release the global lock and return the corresponding status.
84
; Release the global lock and return the corresponding status.
77
.fail:
85
.fail:
78
        mov     ecx, ide_mutex
86
        mov     ecx, ide_mutex
79
        call    mutex_unlock
87
        call    mutex_unlock
80
        or      eax, -1
88
        or      eax, -1
81
        ret
89
        ret
82
.done:
90
.done:
83
        mov     ecx, ide_mutex
91
        mov     ecx, ide_mutex
84
        call    mutex_unlock
92
        call    mutex_unlock
85
        xor     eax, eax
93
        xor     eax, eax
86
        ret
94
        ret
87
endp
95
endp
88
;-----------------------------------------------------------------
96
;-----------------------------------------------------------------
89
proc bd_write_interface stdcall uses esi edi, \
97
proc bd_write_interface stdcall uses esi edi, \
90
        userdata, buffer, startsector:qword, numsectors
98
        userdata, buffer, startsector:qword, numsectors
91
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
99
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
92
        ; buffer = pointer to buffer with data
100
        ; buffer = pointer to buffer with data
93
        ; startsector = 64-bit start sector
101
        ; startsector = 64-bit start sector
94
        ; numsectors = pointer to number of sectors on input,
102
        ; numsectors = pointer to number of sectors on input,
95
        ;  must be filled with number of sectors really written
103
        ;  must be filled with number of sectors really written
96
locals
104
locals
97
sectors_todo    dd      ?
105
sectors_todo    dd      ?
98
endl
106
endl
99
; 1. Initialize number of sectors: get number of requested sectors
107
; 1. Initialize number of sectors: get number of requested sectors
100
; and say that no sectors were read yet.      
108
; and say that no sectors were read yet.      
101
        mov     ecx, [numsectors]
109
        mov     ecx, [numsectors]
102
        mov     eax, [ecx]
110
        mov     eax, [ecx]
103
        mov     dword [ecx], 0
111
        mov     dword [ecx], 0
104
        mov     [sectors_todo], eax
112
        mov     [sectors_todo], eax
105
; 2. Acquire the global lock.
113
; 2. Acquire the global lock.
106
        mov     ecx, ide_mutex
114
        mov     ecx, ide_mutex
107
        call    mutex_lock
115
        call    mutex_lock
108
; 3. Convert parameters to the form suitable for worker procedures.
116
; 3. Convert parameters to the form suitable for worker procedures.
109
; Underlying procedures do not know about 64-bit sectors.
117
; Underlying procedures do not know about 64-bit sectors.
110
; Worker procedures use global variables and esi for [buffer].
118
; Worker procedures use global variables and esi for [buffer].
111
        cmp     dword [startsector+4], 0
119
        cmp     dword [startsector+4], 0
112
        jnz     .fail
120
        jnz     .fail
113
        and     [hd_error], 0
121
        and     [hd_error], 0
114
        mov     eax, [userdata]
122
        mov     eax, [userdata]
115
        mov     [hdpos], eax
123
        mov     [hdpos], eax
116
        mov     esi, [buffer]
124
        mov     esi, [buffer]
117
        lea     edi, [startsector]
125
        lea     edi, [startsector]
118
        mov     [cache_chain_ptr], edi
126
        mov     [cache_chain_ptr], edi
119
; 4. Worker procedures take max 16 sectors per time,
127
; 4. Worker procedures take max 16 sectors per time,
120
; loop until all sectors will be processed.
128
; loop until all sectors will be processed.
121
.sectors_loop:
129
.sectors_loop:
122
        mov     ecx, 16
130
        mov     ecx, 16
123
        cmp     ecx, [sectors_todo]
131
        cmp     ecx, [sectors_todo]
124
        jbe     @f
132
        jbe     @f
125
        mov     ecx, [sectors_todo]
133
        mov     ecx, [sectors_todo]
126
@@:
134
@@:
127
        mov     [cache_chain_size], cl
135
        mov     [cache_chain_size], cl
128
        call    bd_write_cache_chain
136
        call    bd_write_cache_chain
129
        cmp     [hd_error], 0
137
        cmp     [hd_error], 0
130
        jnz     .fail
138
        jnz     .fail
131
        movzx   ecx, [cache_chain_size]
139
        movzx   ecx, [cache_chain_size]
132
        mov     eax, [numsectors]
140
        mov     eax, [numsectors]
133
        add     [eax], ecx
141
        add     [eax], ecx
134
        sub     [sectors_todo], ecx
142
        sub     [sectors_todo], ecx
135
        jz      .done
143
        jz      .done
136
        add     [edi], ecx
144
        add     [edi], ecx
137
        jc      .fail
145
        jc      .fail
138
        shl     ecx, 9
146
        shl     ecx, 9
139
        add     esi, ecx
147
        add     esi, ecx
140
        jmp     .sectors_loop
148
        jmp     .sectors_loop
141
; 5. Loop is done, either due to error or because everything is done.
149
; 5. Loop is done, either due to error or because everything is done.
142
; Release the global lock and return the corresponding status.
150
; Release the global lock and return the corresponding status.
143
.fail:
151
.fail:
144
        mov     ecx, ide_mutex
152
        mov     ecx, ide_mutex
145
        call    mutex_unlock
153
        call    mutex_unlock
146
        or      eax, -1
154
        or      eax, -1
147
        ret
155
        ret
148
.done:
156
.done:
149
        mov     ecx, ide_mutex
157
        mov     ecx, ide_mutex
150
        call    mutex_unlock
158
        call    mutex_unlock
151
        xor     eax, eax
159
        xor     eax, eax
152
        ret
160
        ret
153
endp
161
endp
154
;-----------------------------------------------------------------
162
;-----------------------------------------------------------------
155
; This is a stub.
-
 
156
proc bd_querymedia stdcall, hd_data, mediainfo
163
proc bd_querymedia stdcall, hd_data, mediainfo
157
        mov     eax, [mediainfo]
164
        mov     edx, [mediainfo]
-
 
165
        mov     eax, [hd_data]
-
 
166
        lea     eax, [(eax-80h)*4]
-
 
167
        lea     eax, [BiosDisksData+eax*4]
158
        mov     [eax+DISKMEDIAINFO.Flags], 0
168
        mov     [edx+DISKMEDIAINFO.Flags], 0
-
 
169
        mov     ecx, [eax+BiosDiskData.SectorSize]
159
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
170
        mov     [edx+DISKMEDIAINFO.SectorSize], ecx
-
 
171
        mov     ecx, dword [eax+BiosDiskData.Capacity+0]
-
 
172
        mov     eax, dword [eax+BiosDiskData.Capacity+4]
160
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
173
        mov     dword [edx+DISKMEDIAINFO.Capacity+0], ecx
161
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
174
        mov     dword [edx+DISKMEDIAINFO.Capacity+4], eax
162
        xor     eax, eax
175
        xor     eax, eax
163
        ret
176
        ret
164
endp
177
endp
165
;-----------------------------------------------------------------
178
;-----------------------------------------------------------------
166
bd_read:
179
bd_read:
167
        push    eax
180
        push    eax
168
        push    edx
181
        push    edx
169
        mov     edx, [bios_hdpos]
182
        mov     edx, [bios_hdpos]
170
        cmp     edx, [hdpos]
183
        cmp     edx, [hdpos]
171
        jne     .notread
184
        jne     .notread
172
        mov     edx, [bios_cur_sector]
185
        mov     edx, [bios_cur_sector]
173
        cmp     eax, edx
186
        cmp     eax, edx
174
        jb      .notread
187
        jb      .notread
175
        add     edx, [bios_read_len]
188
        add     edx, [bios_read_len]
176
        dec     edx
189
        dec     edx
177
        cmp     eax, edx
190
        cmp     eax, edx
178
        ja      .notread
191
        ja      .notread
179
        sub     eax, [bios_cur_sector]
192
        sub     eax, [bios_cur_sector]
180
        shl     eax, 9
193
        shl     eax, 9
181
        add     eax, (OS_BASE+0x99000)
194
        add     eax, (OS_BASE+0x99000)
182
        push    ecx esi
195
        push    ecx esi
183
        mov     esi, eax
196
        mov     esi, eax
184
        mov     ecx, 512/4
197
        mov     ecx, 512/4
185
        cld
198
        cld
186
        rep movsd
199
        rep movsd
187
        pop     esi ecx
200
        pop     esi ecx
188
        pop     edx
201
        pop     edx
189
        pop     eax
202
        pop     eax
190
        ret
203
        ret
191
.notread:
204
.notread:
192
        push    ecx
205
        push    ecx
193
        mov     dl, 42h
206
        mov     dl, 42h
194
        mov     ecx, 16
207
        mov     ecx, 16
195
        call    int13_call
208
        call    int13_call
196
        pop     ecx
209
        pop     ecx
197
        test    eax, eax
210
        test    eax, eax
198
        jnz     .v86err
211
        jnz     .v86err
199
        test    edx, edx
212
        test    edx, edx
200
        jz      .readerr
213
        jz      .readerr
201
        mov     [bios_read_len], edx
214
        mov     [bios_read_len], edx
202
        mov     edx, [hdpos]
215
        mov     edx, [hdpos]
203
        mov     [bios_hdpos], edx
216
        mov     [bios_hdpos], edx
204
        pop     edx
217
        pop     edx
205
        pop     eax
218
        pop     eax
206
        mov     [bios_cur_sector], eax
219
        mov     [bios_cur_sector], eax
207
        jmp     bd_read
220
        jmp     bd_read
208
.readerr:
221
.readerr:
209
.v86err:
222
.v86err:
210
        pop     edx
223
        pop     edx
211
        pop     eax
224
        pop     eax
212
        mov     [hd_error], 1
225
        mov     [hd_error], 1
213
        jmp     hd_read_error
226
        jmp     hd_read_error
214
;-----------------------------------------------------------------
227
;-----------------------------------------------------------------
215
bd_write_cache_chain:
228
bd_write_cache_chain:
216
        pusha
229
        pusha
217
        mov     edi, OS_BASE + 0x99000
230
        mov     edi, OS_BASE + 0x99000
218
        movzx   ecx, [cache_chain_size]
231
        movzx   ecx, [cache_chain_size]
219
        push    ecx
232
        push    ecx
220
        shl     ecx, 9-2
233
        shl     ecx, 9-2
221
        rep movsd
234
        rep movsd
222
        pop     ecx
235
        pop     ecx
223
        mov     dl, 43h
236
        mov     dl, 43h
224
        mov     eax, [cache_chain_ptr]
237
        mov     eax, [cache_chain_ptr]
225
        mov     eax, [eax]
238
        mov     eax, [eax]
226
        call    int13_call
239
        call    int13_call
227
        test    eax, eax
240
        test    eax, eax
228
        jnz     .v86err
241
        jnz     .v86err
229
        cmp     edx, ecx
242
        cmp     edx, ecx
230
        jnz     .writeerr
243
        jnz     .writeerr
231
        popa
244
        popa
232
        ret
245
        ret
233
.v86err:
246
.v86err:
234
.writeerr:
247
.writeerr:
235
        popa
248
        popa
236
        mov     [hd_error], 1
249
        mov     [hd_error], 1
237
        jmp     hd_write_error
250
        jmp     hd_write_error
238
;-----------------------------------------------------------------
251
;-----------------------------------------------------------------
239
int13_call:
252
int13_call:
240
; Because this code uses fixed addresses,
253
; Because this code uses fixed addresses,
241
; it can not be run simultaniously by many threads.
254
; it can not be run simultaniously by many threads.
242
; In current implementation it is protected by common mutex 'ide_status'
255
; In current implementation it is protected by common mutex 'ide_status'
243
        mov     word [OS_BASE + 510h], 10h          ; packet length
256
        mov     word [OS_BASE + 510h], 10h          ; packet length
244
        mov     word [OS_BASE + 512h], cx           ; number of sectors
257
        mov     word [OS_BASE + 512h], cx           ; number of sectors
245
        mov     dword [OS_BASE + 514h], 99000000h   ; buffer 9900:0000
258
        mov     dword [OS_BASE + 514h], 99000000h   ; buffer 9900:0000
246
        mov     dword [OS_BASE + 518h], eax
259
        mov     dword [OS_BASE + 518h], eax
247
        and     dword [OS_BASE + 51Ch], 0
260
        and     dword [OS_BASE + 51Ch], 0
248
        push    ebx ecx esi edi
261
        push    ebx ecx esi edi
249
        mov     ebx, int13_regs_in
262
        mov     ebx, int13_regs_in
250
        mov     edi, ebx
263
        mov     edi, ebx
251
        mov     ecx, sizeof.v86_regs/4
264
        mov     ecx, sizeof.v86_regs/4
252
        xor     eax, eax
265
        xor     eax, eax
253
        rep stosd
266
        rep stosd
254
        mov     byte [ebx+v86_regs.eax+1], dl
267
        mov     byte [ebx+v86_regs.eax+1], dl
255
        mov     eax, [hdpos]
268
        mov     eax, [hdpos]
-
 
269
        lea     eax, [(eax-80h)*4]
256
        lea     eax, [BiosDisksData+(eax-80h)*4]
270
        lea     eax, [BiosDisksData+eax*4]
257
        mov     dl, [eax]
271
        mov     dl, [eax]
258
        mov     byte [ebx+v86_regs.edx], dl
272
        mov     byte [ebx+v86_regs.edx], dl
259
        movzx   edx, byte [eax+1]
273
        movzx   edx, byte [eax+1]
260
;        mov     dl, 5
274
;        mov     dl, 5
261
        test    edx, edx
275
        test    edx, edx
262
        jnz     .hasirq
276
        jnz     .hasirq
263
        dec     edx
277
        dec     edx
264
        jmp     @f
278
        jmp     @f
265
.hasirq:
279
.hasirq:
266
        pushad
280
        pushad
267
        stdcall enable_irq, edx
281
        stdcall enable_irq, edx
268
        popad
282
        popad
269
@@:
283
@@:
270
        mov     word [ebx+v86_regs.esi], 510h
284
        mov     word [ebx+v86_regs.esi], 510h
271
        mov     word [ebx+v86_regs.ss], 9000h
285
        mov     word [ebx+v86_regs.ss], 9000h
272
        mov     word [ebx+v86_regs.esp], 09000h
286
        mov     word [ebx+v86_regs.esp], 09000h
273
        mov     word [ebx+v86_regs.eip], 500h
287
        mov     word [ebx+v86_regs.eip], 500h
274
        mov     [ebx+v86_regs.eflags], 20200h
288
        mov     [ebx+v86_regs.eflags], 20200h
275
        mov     esi, [sys_v86_machine]
289
        mov     esi, [sys_v86_machine]
276
        mov     ecx, 0x502
290
        mov     ecx, 0x502
277
        push    fs
291
        push    fs
278
        call    v86_start
292
        call    v86_start
279
        pop     fs
293
        pop     fs
280
        and     [bios_hdpos], 0
294
        and     [bios_hdpos], 0
281
        pop     edi esi ecx ebx
295
        pop     edi esi ecx ebx
282
        movzx   edx, byte [OS_BASE + 512h]
296
        movzx   edx, byte [OS_BASE + 512h]
283
        test    byte [int13_regs_out+v86_regs.eflags], 1
297
        test    byte [int13_regs_out+v86_regs.eflags], 1
284
        jnz     @f
298
        jnz     @f
285
        mov     edx, ecx
299
        mov     edx, ecx
286
@@:
300
@@:
287
        ret
301
        ret