Subversion Repositories Kolibri OS

Rev

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

Rev 4291 Rev 4420
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
$Revision: 4291 $
8
$Revision: 4420 $
9
 
9
 
10
 
-
 
11
; Low-level driver for HDD access
10
 
12
; DMA support by Mario79
11
; Low-level driver for HDD access
13
; Access through BIOS by diamond
12
; DMA support by Mario79
14
; LBA48 support by Mario79
13
; LBA48 support by Mario79
15
;-----------------------------------------------------------------------------
14
;-----------------------------------------------------------------------------
Line 30... Line 29...
30
        dd      ide_write
29
        dd      ide_write
31
        dd      0       ; no flush function
30
        dd      0       ; no flush function
32
        dd      0       ; use default cache size
31
        dd      0       ; use default cache size
33
.end:
32
.end:
Line 34... Line -...
34
 
-
 
35
bd_callbacks:
-
 
36
        dd      bd_callbacks.end - bd_callbacks         ; strucsize
-
 
37
        dd      0       ; no close function
-
 
38
        dd      0       ; no closemedia function
-
 
39
        dd      bd_querymedia
-
 
40
        dd      bd_read_interface
-
 
41
        dd      bd_write_interface
-
 
42
        dd      0       ; no flush function
-
 
43
        dd      0       ; use default cache size
-
 
44
.end:
-
 
45
 
33
 
46
hd0_data        HD_DATA         ?,    0, 1
34
hd0_data        HD_DATA         ?,    0, 1
47
hd1_data        HD_DATA         ?, 0x10, 2
35
hd1_data        HD_DATA         ?, 0x10, 2
48
hd2_data        HD_DATA         ?,    0, 3
36
hd2_data        HD_DATA         ?,    0, 3
Line 281... Line 269...
281
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
269
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
282
        xor     eax, eax
270
        xor     eax, eax
283
        ret
271
        ret
284
endp
272
endp
Line 285... Line -...
285
 
-
 
286
proc bd_read_interface stdcall uses edi, \
-
 
287
        userdata, buffer, startsector:qword, numsectors
-
 
288
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
-
 
289
        ; buffer = pointer to buffer for data
-
 
290
        ; startsector = 64-bit start sector
-
 
291
        ; numsectors = pointer to number of sectors on input,
-
 
292
        ;  must be filled with number of sectors really read
-
 
293
locals
-
 
294
sectors_todo    dd      ?
-
 
295
endl
-
 
296
; 1. Initialize number of sectors: get number of requested sectors
-
 
297
; and say that no sectors were read yet.
-
 
298
        mov     ecx, [numsectors]
-
 
299
        mov     eax, [ecx]
-
 
300
        mov     dword [ecx], 0
-
 
301
        mov     [sectors_todo], eax
-
 
302
; 2. Acquire the global lock.
-
 
303
        mov     ecx, ide_mutex
-
 
304
        call    mutex_lock
-
 
305
; 3. Convert parameters to the form suitable for worker procedures.
-
 
306
; Underlying procedures do not know about 64-bit sectors.
-
 
307
; Worker procedures use global variables and edi for [buffer].
-
 
308
        cmp     dword [startsector+4], 0
-
 
309
        jnz     .fail
-
 
310
        and     [hd_error], 0
-
 
311
        mov     eax, [userdata]
-
 
312
        mov     [hdpos], eax
-
 
313
        mov     eax, dword [startsector]
-
 
314
        mov     edi, [buffer]
-
 
315
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
-
 
316
.sectors_loop:
-
 
317
        call    bd_read
-
 
318
        cmp     [hd_error], 0
-
 
319
        jnz     .fail
-
 
320
        mov     ecx, [numsectors]
-
 
321
        inc     dword [ecx]     ; one more sector is read
-
 
322
        dec     [sectors_todo]
-
 
323
        jz      .done
-
 
324
        inc     eax
-
 
325
        jnz     .sectors_loop
-
 
326
; 5. Loop is done, either due to error or because everything is done.
-
 
327
; Release the global lock and return the corresponding status.
-
 
328
.fail:
-
 
329
        mov     ecx, ide_mutex
-
 
330
        call    mutex_unlock
-
 
331
        or      eax, -1
-
 
332
        ret
-
 
333
.done:
-
 
334
        mov     ecx, ide_mutex
-
 
335
        call    mutex_unlock
-
 
336
        xor     eax, eax
-
 
337
        ret
-
 
338
endp
-
 
339
 
-
 
340
proc bd_write_interface stdcall uses esi edi, \
-
 
341
        userdata, buffer, startsector:qword, numsectors
-
 
342
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
-
 
343
        ; buffer = pointer to buffer with data
-
 
344
        ; startsector = 64-bit start sector
-
 
345
        ; numsectors = pointer to number of sectors on input,
-
 
346
        ;  must be filled with number of sectors really written
-
 
347
locals
-
 
348
sectors_todo    dd      ?
-
 
349
endl
-
 
350
; 1. Initialize number of sectors: get number of requested sectors
-
 
351
; and say that no sectors were read yet.      
-
 
352
        mov     ecx, [numsectors]
-
 
353
        mov     eax, [ecx]
-
 
354
        mov     dword [ecx], 0
-
 
355
        mov     [sectors_todo], eax
-
 
356
; 2. Acquire the global lock.
-
 
357
        mov     ecx, ide_mutex
-
 
358
        call    mutex_lock
-
 
359
; 3. Convert parameters to the form suitable for worker procedures.
-
 
360
; Underlying procedures do not know about 64-bit sectors.
-
 
361
; Worker procedures use global variables and esi for [buffer].
-
 
362
        cmp     dword [startsector+4], 0
-
 
363
        jnz     .fail
-
 
364
        and     [hd_error], 0
-
 
365
        mov     eax, [userdata]
-
 
366
        mov     [hdpos], eax
-
 
367
        mov     esi, [buffer]
-
 
368
        lea     edi, [startsector]
-
 
369
        mov     [cache_chain_ptr], edi
-
 
370
; 4. Worker procedures take max 16 sectors per time,
-
 
371
; loop until all sectors will be processed.
-
 
372
.sectors_loop:
-
 
373
        mov     ecx, 16
-
 
374
        cmp     ecx, [sectors_todo]
-
 
375
        jbe     @f
-
 
376
        mov     ecx, [sectors_todo]
-
 
377
@@:
-
 
378
        mov     [cache_chain_size], cl
-
 
379
        call    bd_write_cache_chain
-
 
380
        cmp     [hd_error], 0
-
 
381
        jnz     .fail
-
 
382
        movzx   ecx, [cache_chain_size]
-
 
383
        mov     eax, [numsectors]
-
 
384
        add     [eax], ecx
-
 
385
        sub     [sectors_todo], ecx
-
 
386
        jz      .done
-
 
387
        add     [edi], ecx
-
 
388
        jc      .fail
-
 
389
        shl     ecx, 9
-
 
390
        add     esi, ecx
-
 
391
        jmp     .sectors_loop
-
 
392
; 5. Loop is done, either due to error or because everything is done.
-
 
393
; Release the global lock and return the corresponding status.
-
 
394
.fail:
-
 
395
        mov     ecx, ide_mutex
-
 
396
        call    mutex_unlock
-
 
397
        or      eax, -1
-
 
398
        ret
-
 
399
.done:
-
 
400
        mov     ecx, ide_mutex
-
 
401
        call    mutex_unlock
-
 
402
        xor     eax, eax
-
 
403
        ret
-
 
404
endp
-
 
405
 
-
 
406
; This is a stub.
-
 
407
proc bd_querymedia stdcall, hd_data, mediainfo
-
 
408
        mov     eax, [mediainfo]
-
 
409
        mov     [eax+DISKMEDIAINFO.Flags], 0
-
 
410
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
-
 
411
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
-
 
412
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
-
 
413
        xor     eax, eax
-
 
414
        ret
-
 
415
endp
-
 
416
 
273
 
417
;-----------------------------------------------------------------------------
274
;-----------------------------------------------------------------------------
418
align 4
275
align 4
419
; input: eax = sector, edi -> buffer
276
; input: eax = sector, edi -> buffer
420
; output: edi = edi + 512
277
; output: edi = edi + 512
Line 1324... Line 1181...
1324
IDE_BAR1_val    dw ?
1181
IDE_BAR1_val    dw ?
1325
IDE_BAR2_val    dw ?
1182
IDE_BAR2_val    dw ?
1326
IDE_BAR3_val    dw ?
1183
IDE_BAR3_val    dw ?
1327
endg
1184
endg
1328
;-----------------------------------------------------------------------------
1185
;-----------------------------------------------------------------------------
1329
; \begin{diamond}
-
 
1330
uglobal
-
 
1331
bios_hdpos      dd 0       ; 0 is invalid value for [hdpos]
-
 
1332
bios_cur_sector dd ?
-
 
1333
bios_read_len   dd ?
-
 
1334
endg
-
 
1335
;-----------------------------------------------------------------------------
-
 
1336
align 4
-
 
1337
bd_read:
-
 
1338
        push    eax
-
 
1339
        push    edx
-
 
1340
        mov     edx, [bios_hdpos]
-
 
1341
        cmp     edx, [hdpos]
-
 
1342
        jne     .notread
-
 
1343
        mov     edx, [bios_cur_sector]
-
 
1344
        cmp     eax, edx
-
 
1345
        jb      .notread
-
 
1346
        add     edx, [bios_read_len]
-
 
1347
        dec     edx
-
 
1348
        cmp     eax, edx
-
 
1349
        ja      .notread
-
 
1350
        sub     eax, [bios_cur_sector]
-
 
1351
        shl     eax, 9
-
 
1352
        add     eax, (OS_BASE+0x9A000)
-
 
1353
        push    ecx esi
-
 
1354
        mov     esi, eax
-
 
1355
        mov     ecx, 512/4
-
 
1356
        cld
-
 
1357
        rep movsd
-
 
1358
        pop     esi ecx
-
 
1359
        pop     edx
-
 
1360
        pop     eax
-
 
1361
        ret
-
 
1362
.notread:
-
 
1363
        push    ecx
-
 
1364
        mov     dl, 42h
-
 
1365
        mov     ecx, 16
-
 
1366
        call    int13_call
-
 
1367
        pop     ecx
-
 
1368
        test    eax, eax
-
 
1369
        jnz     .v86err
-
 
1370
        test    edx, edx
-
 
1371
        jz      .readerr
-
 
1372
        mov     [bios_read_len], edx
-
 
1373
        mov     edx, [hdpos]
-
 
1374
        mov     [bios_hdpos], edx
-
 
1375
        pop     edx
-
 
1376
        pop     eax
-
 
1377
        mov     [bios_cur_sector], eax
-
 
1378
        jmp     bd_read
-
 
1379
.readerr:
-
 
1380
.v86err:
-
 
1381
        mov     [hd_error], 1
-
 
1382
        jmp     hd_read_error
-
 
1383
;-----------------------------------------------------------------------------
-
 
1384
align 4
-
 
1385
bd_write_cache_chain:
-
 
1386
        pusha
-
 
1387
        mov     edi, OS_BASE + 0x9A000
-
 
1388
        movzx   ecx, [cache_chain_size]
-
 
1389
        push    ecx
-
 
1390
        shl     ecx, 9-2
-
 
1391
        rep movsd
-
 
1392
        pop     ecx
-
 
1393
        mov     dl, 43h
-
 
1394
        mov     eax, [cache_chain_ptr]
-
 
1395
        mov     eax, [eax]
-
 
1396
        call    int13_call
-
 
1397
        test    eax, eax
-
 
1398
        jnz     .v86err
-
 
1399
        cmp     edx, ecx
-
 
1400
        jnz     .writeerr
-
 
1401
        popa
-
 
1402
        ret
-
 
1403
.v86err:
-
 
1404
.writeerr:
-
 
1405
        popa
-
 
1406
        mov     [hd_error], 1
-
 
1407
        jmp     hd_write_error
-
 
1408
;-----------------------------------------------------------------------------
-
 
1409
uglobal
-
 
1410
int13_regs_in   rb sizeof.v86_regs
-
 
1411
int13_regs_out  rb sizeof.v86_regs
-
 
1412
endg
-
 
1413
;-----------------------------------------------------------------------------
-
 
1414
align 4
-
 
1415
int13_call:
-
 
1416
; Because this code uses fixed addresses,
-
 
1417
; it can not be run simultaniously by many threads.
-
 
1418
; In current implementation it is protected by common mutex 'ide_status'
-
 
1419
        mov     word [OS_BASE + 510h], 10h             ; packet length
-
 
1420
        mov     word [OS_BASE + 512h], cx              ; number of sectors
-
 
1421
        mov     dword [OS_BASE + 514h], 9A000000h      ; buffer 9A00:0000
-
 
1422
        mov     dword [OS_BASE + 518h], eax
-
 
1423
        and     dword [OS_BASE + 51Ch], 0
-
 
1424
        push    ebx ecx esi edi
-
 
1425
        mov     ebx, int13_regs_in
-
 
1426
        mov     edi, ebx
-
 
1427
        mov     ecx, sizeof.v86_regs/4
-
 
1428
        xor     eax, eax
-
 
1429
        rep stosd
-
 
1430
        mov     byte [ebx+v86_regs.eax+1], dl
-
 
1431
        mov     eax, [hdpos]
-
 
1432
        lea     eax, [BiosDisksData+(eax-80h)*4]
-
 
1433
        mov     dl, [eax]
-
 
1434
        mov     byte [ebx+v86_regs.edx], dl
-
 
1435
        movzx   edx, byte [eax+1]
-
 
1436
;        mov     dl, 5
-
 
1437
        test    edx, edx
-
 
1438
        jnz     .hasirq
-
 
1439
        dec     edx
-
 
1440
        jmp     @f
-
 
1441
.hasirq:
-
 
1442
        pushad
-
 
1443
        stdcall enable_irq, edx
-
 
1444
        popad
-
 
1445
@@:
-
 
1446
        mov     word [ebx+v86_regs.esi], 510h
-
 
1447
        mov     word [ebx+v86_regs.ss], 9000h
-
 
1448
        mov     word [ebx+v86_regs.esp], 0A000h
-
 
1449
        mov     word [ebx+v86_regs.eip], 500h
-
 
1450
        mov     [ebx+v86_regs.eflags], 20200h
-
 
1451
        mov     esi, [sys_v86_machine]
-
 
1452
        mov     ecx, 0x502
-
 
1453
        push    fs
-
 
1454
        call    v86_start
-
 
1455
        pop     fs
-
 
1456
        and     [bios_hdpos], 0
-
 
1457
        pop     edi esi ecx ebx
-
 
1458
        movzx   edx, byte [OS_BASE + 512h]
-
 
1459
        test    byte [int13_regs_out+v86_regs.eflags], 1
-
 
1460
        jnz     @f
-
 
1461
        mov     edx, ecx
-
 
1462
@@:
-
 
1463
        ret
-
 
1464
; \end{diamond}
-