Subversion Repositories Kolibri OS

Rev

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

Rev 5570 Rev 5852
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
$Revision: 5570 $
8
$Revision: 5852 $
Line 9... Line 9...
9
 
9
 
10
; HDD driver
10
; HDD driver
11
 
11
 
12
struct HD_DATA
12
struct HD_DATA
-
 
13
hdbase  dw  ?
13
hdbase  dd      ?
14
hdid    dw  ?
14
hdid    dd      ?
15
hdpos   dw  ?
15
hdpos   dd      ?
16
hd48    dw  ?
16
ends
17
ends
17
;-----------------------------------------------------------------
18
;-----------------------------------------------------------------
18
iglobal
19
iglobal
19
align 4
20
align 4
20
ide_callbacks:
21
ide_callbacks:
21
        dd      ide_callbacks.end - ide_callbacks   ; strucsize
22
    dd  ide_callbacks.end - ide_callbacks
22
        dd      0   ; no close function
23
    dd  0   ; no close function
23
        dd      0   ; no closemedia function
24
    dd  0   ; no closemedia function
24
        dd      ide_querymedia
25
    dd  ide_querymedia
25
        dd      ide_read
26
    dd  ide_read
26
        dd      ide_write
27
    dd  ide_write
Line 27... Line 28...
27
        dd      0   ; no flush function
28
    dd  0   ; no flush function
28
        dd      0   ; use default cache size
29
    dd  0   ; use default cache size
29
.end:
30
.end:
30
 
31
 
31
hd0_data        HD_DATA         ?,    0, 1
32
hd0_data    HD_DATA     ?,  0,  1, 0
32
hd1_data        HD_DATA         ?, 0x10, 2
33
hd1_data    HD_DATA     ?, 16,  2, 0
33
hd2_data        HD_DATA         ?,    0, 3
34
hd2_data    HD_DATA     ?,  0,  3, 0
34
hd3_data        HD_DATA         ?, 0x10, 4
35
hd3_data    HD_DATA     ?, 16,  4, 0
35
hd4_data        HD_DATA         ?,    0, 5
36
hd4_data    HD_DATA     ?,  0,  5, 0
36
hd5_data        HD_DATA         ?, 0x10, 6
37
hd5_data    HD_DATA     ?, 16,  6, 0
37
hd6_data        HD_DATA         ?,    0, 7
38
hd6_data    HD_DATA     ?,  0,  7, 0
38
hd7_data        HD_DATA         ?, 0x10, 8
39
hd7_data    HD_DATA     ?, 16,  8, 0
Line 39... Line 40...
39
hd8_data        HD_DATA         ?,    0, 9
40
hd8_data    HD_DATA     ?,  0,  9, 0
40
hd9_data        HD_DATA         ?, 0x10, 10
41
hd9_data    HD_DATA     ?, 16, 10, 0
41
hd10_data       HD_DATA         ?,    0, 11
42
hd10_data   HD_DATA     ?,  0, 11, 0
42
hd11_data       HD_DATA         ?, 0x10, 12
43
hd11_data   HD_DATA     ?, 16, 12, 0
Line 72... Line 73...
72
        mov     al, 25h     ; READ DMA EXT
73
        mov     al, 25h     ; READ DMA EXT
73
        jmp     ide_read_write
74
        jmp     ide_read_write
Line 74... Line 75...
74
 
75
 
75
ide_write:
76
ide_write:
76
        mov     al, 35h     ; WRITE DMA EXT
-
 
Line 77... Line 77...
77
; fall through to ide_read_write
77
        mov     al, 35h     ; WRITE DMA EXT
78
 
78
 
79
proc ide_read_write stdcall uses esi edi ebx, \
79
proc ide_read_write stdcall uses esi edi ebx, \
80
        hd_data, buffer, startsector:qword, numsectors
80
        hd_data, buffer, startsector:qword, numsectors
Line 84... Line 84...
84
        ; numsectors = pointer to number of sectors on input,
84
        ; numsectors = pointer to number of sectors on input,
85
        ;  must be filled with number of sectors really read/written
85
        ;  must be filled with number of sectors really read/written
86
locals
86
locals
87
sectors_todo    dd      ?
87
sectors_todo    dd      ?
88
channel_lock    dd      ?
88
channel_lock    dd      ?
89
operation       db      ?
-
 
90
endl
89
endl
91
        mov     [operation], al
90
        mov     bl, al
92
; get number of requested sectors and say that no sectors were read yet
91
; get number of requested sectors and say that no sectors were read yet
93
        mov     ecx, [numsectors]
92
        mov     ecx, [numsectors]
94
        mov     eax, [ecx]
93
        mov     eax, [ecx]
95
        mov     dword [ecx], 0
94
        mov     dword [ecx], 0
96
        mov     [sectors_todo], eax
95
        mov     [sectors_todo], eax
97
; acquire the global lock
96
; acquire the global lock
98
        mov     ecx, ide_mutex
97
        mov     ecx, ide_mutex
99
        call    mutex_lock
98
        call    mutex_lock
100
        mov     ecx, [hd_data]
99
        mov     ecx, [hd_data]
101
        mov     ecx, [ecx+HD_DATA.hdpos]
100
        movzx   ecx, [ecx+HD_DATA.hdpos]
102
        dec     ecx
101
        dec     ecx
103
        shr     ecx, 1
102
        shr     ecx, 1
104
        shl     ecx, 2
103
        shl     ecx, 2
105
        mov     ecx, [ecx + ide_mutex_table]
104
        mov     ecx, [ecx + ide_mutex_table]
106
        mov     [channel_lock], ecx
105
        mov     [channel_lock], ecx
107
        call    mutex_lock
106
        call    mutex_lock
108
; prepare worker procedures variables
107
; prepare worker procedures variables
-
 
108
        mov     esi, [buffer]
-
 
109
        mov     edi, esi
109
        mov     ecx, [hd_data]
110
        mov     ecx, [hd_data]
110
        mov     eax, [ecx+HD_DATA.hdbase]
111
        movzx   eax, [ecx+HD_DATA.hdbase]
111
        mov     [hdbase], eax
112
        mov     [hdbase], eax
112
        mov     eax, [ecx+HD_DATA.hdid]
113
        mov     ax, [ecx+HD_DATA.hdid]
113
        mov     [hdid], eax
114
        mov     [hdid], eax
114
        mov     eax, [ecx+HD_DATA.hdpos]
-
 
115
        mov     [hdpos], eax
-
 
116
        mov     eax, dword [startsector]
115
        mov     eax, dword [startsector]
117
        mov     [sector], eax
116
        mov     [sector], eax
-
 
117
        cmp     [ecx+HD_DATA.hd48], 0
-
 
118
        jz      .LBA28
118
        mov     ax, word [startsector+4]
119
        mov     ax, word [startsector+4]
119
        mov     [sector+4], ax
120
        mov     [sector+4], ax
120
        mov     esi, [buffer]
121
        movzx   ecx, [ecx+HD_DATA.hdpos]
121
        mov     edi, esi
122
        mov     [hdpos], ecx
122
        mov     bl, [operation]
-
 
123
        mov     ecx, [hdpos]
-
 
124
        dec     ecx
123
        dec     ecx
125
        shr     ecx, 2
124
        shr     ecx, 2
126
        imul    ecx, sizeof.IDE_DATA
125
        imul    ecx, sizeof.IDE_DATA
127
        add     ecx, IDE_controller_1
126
        add     ecx, IDE_controller_1
128
        mov     [IDE_controller_pointer], ecx
127
        mov     [IDE_controller_pointer], ecx
Line 132... Line 131...
132
        shr     eax, 1
131
        shr     eax, 1
133
        add     eax, ecx
132
        add     eax, ecx
134
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
133
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
135
        jz      .next
134
        jz      .next
136
        dec     ebx     ; READ/WRITE SECTOR(S) EXT
135
        dec     ebx     ; READ/WRITE SECTOR(S) EXT
137
; worker procedures take max 8000h sectors per time
136
; LBA48 supports max 10000h sectors per time
138
; loop until all sectors will be processed
137
; loop until all sectors will be processed
139
.next:
138
.next:
140
        mov     ecx, 8000h
139
        mov     ecx, 8000h
141
        cmp     ecx, [sectors_todo]
140
        cmp     ecx, [sectors_todo]
142
        jbe     @f
141
        jbe     @f
Line 152... Line 151...
152
        sub     [sectors_todo], ecx
151
        sub     [sectors_todo], ecx
153
        jz      .out
152
        jz      .out
154
        add     [sector], ecx
153
        add     [sector], ecx
155
        adc     word [sector+4], 0
154
        adc     word [sector+4], 0
156
        jmp     .next
155
        jmp     .next
-
 
156
.LBA28:
-
 
157
        add     eax, [sectors_todo]
-
 
158
        add     eax, 0xF0000000
-
 
159
        jc      .out
-
 
160
        sub     bl, 5   ; READ/WRITE SECTOR(S)
-
 
161
; LBA28 supports max 256 sectors per time
-
 
162
; loop until all sectors will be processed
-
 
163
.next28:
-
 
164
        mov     ecx, 256
-
 
165
        cmp     ecx, [sectors_todo]
-
 
166
        jbe     @f
-
 
167
        mov     ecx, [sectors_todo]
-
 
168
@@:
-
 
169
        mov     [blockSize], ecx
-
 
170
        push    ecx
-
 
171
        call    IDE_transfer.LBA28
-
 
172
        pop     ecx
-
 
173
        jc      .out
-
 
174
        mov     eax, [numsectors]
-
 
175
        add     [eax], ecx
-
 
176
        sub     [sectors_todo], ecx
-
 
177
        jz      .out
-
 
178
        add     [sector], ecx
-
 
179
        jmp     .next28
157
; loop is done, either due to error or because everything is done
180
; loop is done, either due to error or because everything is done
158
; release the global lock and return the corresponding status
181
; release the global lock and return the corresponding status
159
.out:
182
.out:
160
        sbb     eax, eax
183
        sbb     eax, eax
161
        push    eax
184
        push    eax
Line 358... Line 381...
358
        pop     ebx esi
381
        pop     ebx esi
359
        call    kernel_free
382
        call    kernel_free
360
        cmp     [eventPointer], 0
383
        cmp     [eventPointer], 0
361
        jz      .hd_error
384
        jz      .hd_error
362
        ret
385
        ret
-
 
386
 
-
 
387
.LBA28:
-
 
388
        mov     edx, [hdbase]
-
 
389
        add     edx, 6
-
 
390
        mov     al, byte [hdid]
-
 
391
        add     al, 224
-
 
392
        out     dx, al  ; select the desired drive
-
 
393
        call    save_hd_wait_timeout
-
 
394
        inc     edx
-
 
395
@@:
-
 
396
        call    check_hd_wait_timeout
-
 
397
        jc      .hd_error
-
 
398
        in      al, dx
-
 
399
        test    al, 128 ; ready for command?
-
 
400
        jnz     @b
-
 
401
        pushfd          ; fill the ports
-
 
402
        cli
-
 
403
        mov     edx, [hdbase]
-
 
404
        inc     edx
-
 
405
        inc     edx
-
 
406
        mov     al, [blockSize]
-
 
407
        out     dx, al  ; Sector count (7:0)
-
 
408
        inc     edx
-
 
409
        mov     eax, [sector]
-
 
410
        out     dx, al  ; LBA (7:0)
-
 
411
        inc     edx
-
 
412
        shr     eax, 8
-
 
413
        out     dx, al  ; LBA (15:8)
-
 
414
        inc     edx
-
 
415
        shr     eax, 8
-
 
416
        out     dx, al  ; LBA (23:16)
-
 
417
        inc     edx
-
 
418
        shr     eax, 8
-
 
419
        add     al, byte [hdid]
-
 
420
        add     al, 224
-
 
421
        out     dx, al  ; LBA (27:24)
363
.PIO:
422
.PIO:
364
        inc     edx     ; ATACommand
423
        inc     edx     ; ATACommand
365
        mov     al, bl
424
        mov     al, bl
366
        out     dx, al  ; Start hard drive
425
        out     dx, al  ; Start hard drive
367
        popfd
426
        popfd
Line 385... Line 444...
385
        pushfd
444
        pushfd
386
        cli
445
        cli
387
        cld
446
        cld
388
        mov     ecx, 256
447
        mov     ecx, 256
389
        mov     edx, [hdbase]
448
        mov     edx, [hdbase]
390
        cmp     bl, 34h
449
        cmp     bl, 30h
391
        jz      .write
450
        jnc     .write
392
        rep insw
451
        rep insw
393
        jmp     @f
452
        jmp     @f
394
.write:
453
.write:
395
        rep outsw
454
        rep outsw
396
@@:
455
@@: