Subversion Repositories Kolibri OS

Rev

Rev 5569 | Rev 5852 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 5570 $
9
 
5569 Pathoswith 10
; HDD driver
2288 clevermous 11
 
3742 clevermous 12
struct HD_DATA
13
hdbase  dd      ?
14
hdid    dd      ?
15
hdpos   dd      ?
16
ends
5569 Pathoswith 17
;-----------------------------------------------------------------
3742 clevermous 18
iglobal
2288 clevermous 19
align 4
3742 clevermous 20
ide_callbacks:
5569 Pathoswith 21
        dd      ide_callbacks.end - ide_callbacks   ; strucsize
22
        dd      0   ; no close function
23
        dd      0   ; no closemedia function
3742 clevermous 24
        dd      ide_querymedia
25
        dd      ide_read
26
        dd      ide_write
5569 Pathoswith 27
        dd      0   ; no flush function
28
        dd      0   ; use default cache size
3742 clevermous 29
.end:
2288 clevermous 30
 
3742 clevermous 31
hd0_data        HD_DATA         ?,    0, 1
32
hd1_data        HD_DATA         ?, 0x10, 2
33
hd2_data        HD_DATA         ?,    0, 3
34
hd3_data        HD_DATA         ?, 0x10, 4
4700 mario79 35
hd4_data        HD_DATA         ?,    0, 5
36
hd5_data        HD_DATA         ?, 0x10, 6
37
hd6_data        HD_DATA         ?,    0, 7
38
hd7_data        HD_DATA         ?, 0x10, 8
39
hd8_data        HD_DATA         ?,    0, 9
40
hd9_data        HD_DATA         ?, 0x10, 10
41
hd10_data       HD_DATA         ?,    0, 11
42
hd11_data       HD_DATA         ?, 0x10, 12
4273 clevermous 43
 
4700 mario79 44
ide_mutex_table:
45
        dd ide_channel1_mutex
46
        dd ide_channel2_mutex
47
        dd ide_channel3_mutex
48
        dd ide_channel4_mutex
49
        dd ide_channel5_mutex
50
        dd ide_channel6_mutex
3742 clevermous 51
endg
5569 Pathoswith 52
;-----------------------------------------------------------------
3742 clevermous 53
uglobal
54
ide_mutex               MUTEX
55
ide_channel1_mutex      MUTEX
56
ide_channel2_mutex      MUTEX
4700 mario79 57
ide_channel3_mutex      MUTEX
58
ide_channel4_mutex      MUTEX
59
ide_channel5_mutex      MUTEX
60
ide_channel6_mutex      MUTEX
5569 Pathoswith 61
blockSize:
62
rb 4
63
sector:
64
rb 6
65
allow_dma_access        db ?
66
IDE_common_irq_param    db ?
67
eventPointer            dd ?
68
eventID                 dd ?
3742 clevermous 69
endg
5569 Pathoswith 70
;-----------------------------------------------------------------
5570 clevermous 71
ide_read:
72
        mov     al, 25h     ; READ DMA EXT
73
        jmp     ide_read_write
74
 
75
ide_write:
76
        mov     al, 35h     ; WRITE DMA EXT
77
; fall through to ide_read_write
78
 
79
proc ide_read_write stdcall uses esi edi ebx, \
3742 clevermous 80
        hd_data, buffer, startsector:qword, numsectors
81
        ; hd_data = pointer to hd*_data
5570 clevermous 82
        ; buffer = pointer to buffer with/for data
3742 clevermous 83
        ; startsector = 64-bit start sector
84
        ; numsectors = pointer to number of sectors on input,
5570 clevermous 85
        ;  must be filled with number of sectors really read/written
3742 clevermous 86
locals
87
sectors_todo    dd      ?
88
channel_lock    dd      ?
5570 clevermous 89
operation       db      ?
3742 clevermous 90
endl
5570 clevermous 91
        mov     [operation], al
5569 Pathoswith 92
; get number of requested sectors and say that no sectors were read yet
3742 clevermous 93
        mov     ecx, [numsectors]
94
        mov     eax, [ecx]
95
        mov     dword [ecx], 0
96
        mov     [sectors_todo], eax
5569 Pathoswith 97
; acquire the global lock
3742 clevermous 98
        mov     ecx, ide_mutex
99
        call    mutex_lock
4700 mario79 100
        mov     ecx, [hd_data]
101
        mov     ecx, [ecx+HD_DATA.hdpos]
102
        dec     ecx
103
        shr     ecx, 1
104
        shl     ecx, 2
105
        mov     ecx, [ecx + ide_mutex_table]
3742 clevermous 106
        mov     [channel_lock], ecx
107
        call    mutex_lock
5569 Pathoswith 108
; prepare worker procedures variables
3742 clevermous 109
        mov     ecx, [hd_data]
110
        mov     eax, [ecx+HD_DATA.hdbase]
111
        mov     [hdbase], eax
112
        mov     eax, [ecx+HD_DATA.hdid]
113
        mov     [hdid], eax
114
        mov     eax, [ecx+HD_DATA.hdpos]
115
        mov     [hdpos], eax
116
        mov     eax, dword [startsector]
5569 Pathoswith 117
        mov     [sector], eax
118
        mov     ax, word [startsector+4]
119
        mov     [sector+4], ax
120
        mov     esi, [buffer]
121
        mov     edi, esi
5570 clevermous 122
        mov     bl, [operation]
4720 mario79 123
        mov     ecx, [hdpos]
124
        dec     ecx
125
        shr     ecx, 2
126
        imul    ecx, sizeof.IDE_DATA
127
        add     ecx, IDE_controller_1
128
        mov     [IDE_controller_pointer], ecx
129
        mov     eax, [hdpos]
130
        dec     eax
131
        and     eax, 11b
132
        shr     eax, 1
133
        add     eax, ecx
134
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
5569 Pathoswith 135
        jz      .next
5570 clevermous 136
        dec     ebx     ; READ/WRITE SECTOR(S) EXT
5569 Pathoswith 137
; worker procedures take max 8000h sectors per time
138
; loop until all sectors will be processed
139
.next:
140
        mov     ecx, 8000h
141
        cmp     ecx, [sectors_todo]
142
        jbe     @f
143
        mov     ecx, [sectors_todo]
144
@@:
145
        mov     [blockSize], ecx
146
        push    ecx
147
        call    IDE_transfer
148
        pop     ecx
149
        jc      .out
3742 clevermous 150
        mov     eax, [numsectors]
151
        add     [eax], ecx
152
        sub     [sectors_todo], ecx
5569 Pathoswith 153
        jz      .out
154
        add     [sector], ecx
155
        adc     word [sector+4], 0
156
        jmp     .next
157
; loop is done, either due to error or because everything is done
158
; release the global lock and return the corresponding status
159
.out:
160
        sbb     eax, eax
161
        push    eax
3742 clevermous 162
        mov     ecx, [channel_lock]
163
        call    mutex_unlock
164
        mov     ecx, ide_mutex
165
        call    mutex_unlock
5569 Pathoswith 166
        pop     eax
3742 clevermous 167
        ret
168
endp
5569 Pathoswith 169
;-----------------------------------------------------------------
170
; this is a stub
3742 clevermous 171
proc ide_querymedia stdcall, hd_data, mediainfo
172
        mov     eax, [mediainfo]
173
        mov     [eax+DISKMEDIAINFO.Flags], 0
174
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
175
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
176
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
177
        xor     eax, eax
178
        ret
179
endp
5569 Pathoswith 180
;-----------------------------------------------------------------
181
; input: esi -> buffer, bl = command, [sector], [blockSize]
182
; output: esi -> next block in buffer
183
; for pio read esi equal edi
184
IDE_transfer:
3702 mario79 185
        mov     edx, [hdbase]
5569 Pathoswith 186
        add     edx, 6
3702 mario79 187
        mov     al, byte [hdid]
5569 Pathoswith 188
        add     al, 224
189
        out     dx, al  ; select the desired drive
190
        call    save_hd_wait_timeout
191
        inc     edx
192
@@:
193
        call    check_hd_wait_timeout
194
        jc      .hd_error
195
        in      al, dx
196
        test    al, 128 ; ready for command?
197
        jnz     @b
198
        pushfd          ; fill the ports
2288 clevermous 199
        cli
200
        mov     edx, [hdbase]
201
        inc     edx
202
        inc     edx
5569 Pathoswith 203
        mov     al, [blockSize+1]
204
        out     dx, al  ; Sector count (15:8)
2288 clevermous 205
        inc     edx
5569 Pathoswith 206
        mov     eax, [sector+3]
207
        out     dx, al  ; LBA (31:24)
2288 clevermous 208
        inc     edx
209
        shr     eax, 8
5569 Pathoswith 210
        out     dx, al  ; LBA (39:32)
2288 clevermous 211
        inc     edx
212
        shr     eax, 8
5569 Pathoswith 213
        out     dx, al  ; LBA (47:40)
214
        sub     edx, 3
215
        mov     al, [blockSize]
216
        out     dx, al  ; Sector count (7:0)
2288 clevermous 217
        inc     edx
5569 Pathoswith 218
        mov     eax, [sector]
219
        out     dx, al  ; LBA (7:0)
2288 clevermous 220
        inc     edx
3702 mario79 221
        shr     eax, 8
5569 Pathoswith 222
        out     dx, al  ; LBA (15:8)
3702 mario79 223
        inc     edx
224
        shr     eax, 8
5569 Pathoswith 225
        out     dx, al  ; LBA (23:16)
3702 mario79 226
        inc     edx
227
        mov     al, byte [hdid]
5569 Pathoswith 228
        add     al, 224
229
        out     dx, al
230
        test    bl, 1
231
        jz      .PIO
232
; DMA
233
        mov     dword [esp], 0x1000
234
        call    kernel_alloc
235
        mov     edi, eax
236
        push    eax
237
        shl     dword [blockSize], 9
238
        mov     eax, esi
239
        add     eax, [blockSize]
240
        push    eax
241
; check buffer pages physical addresses and fill the scatter-gather list
242
; buffer may be not aligned and may have size not divisible by page size
243
; [edi] = block physical address, [edi+4] = block size in bytes
244
; block addresses can not cross 10000h borders
245
        mov     ecx, esi
246
        and     ecx, 0xFFF
247
        jz      .aligned
248
        mov     eax, esi
249
        call    get_pg_addr
250
        add     eax, ecx
251
        neg     ecx
252
        add     ecx, 0x1000
253
        mov     [edi], eax
254
        cmp     ecx, [blockSize]
255
        jnc     .end
256
        mov     [edi+4], ecx
257
        add     esi, 0x1000
258
        add     edi, 8
259
        sub     [blockSize], ecx
260
.aligned:
261
        mov     eax, esi
262
        call    get_pg_addr
263
        mov     ecx, eax
264
        mov     [edi], eax
265
        and     ecx, 0xFFFF
266
        neg     ecx
267
        add     ecx, 0x10000
268
        cmp     [blockSize], ecx
269
        jnc     @f
270
        mov     ecx, [blockSize]
271
        and     ecx, 0xF000
272
        jz      .end
273
@@:
274
        push    ecx
275
@@:
276
        add     esi, 0x1000
277
        add     eax, 0x1000
278
        sub     ecx, 0x1000
279
        jz      @f
280
        mov     edx, eax
281
        mov     eax, esi
282
        call    get_pg_addr
283
        cmp     eax, edx
284
        jz      @b
285
@@:
286
        pop     edx
287
        sub     edx, ecx
288
        mov     [edi+4], edx
289
        add     edi, 8
290
        sub     [blockSize], edx
291
        jnz     .aligned
292
        sub     edi, 8
293
        jmp     @f
294
.end:
295
        mov     ecx, [blockSize]
296
        mov     [edi+4], ecx
297
@@:
298
        mov     byte [edi+7], 80h   ; list end
299
        pop     esi
300
        pop     edi
301
; select controller Primary or Secondary
302
        mov     ecx, [IDE_controller_pointer]
303
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
304
        mov     eax, [hdpos]
305
        dec     eax
306
        test    eax, 10b
307
        jz      @f
308
        add     edx, 8
309
@@:
310
        add     edx, 2      ; Bus Master IDE Status register
311
        mov     al, 6
312
        out     dx, al      ; clear Error bit and Interrupt bit
2288 clevermous 313
 
5569 Pathoswith 314
        add     edx, 2      ; Bus Master IDE PRD Table Address
315
        mov     eax, edi
316
        call    get_pg_addr
317
        out     dx, eax     ; send scatter-gather list physical address
2288 clevermous 318
 
5569 Pathoswith 319
        push    edx
2288 clevermous 320
        mov     edx, [hdbase]
5569 Pathoswith 321
        add     edx, 7      ; ATACommand
322
        mov     al, bl
323
        out     dx, al      ; Start hard drive
324
        pop     edx
2288 clevermous 325
 
5569 Pathoswith 326
        sub     edx, 4      ; Bus Master IDE Command register
327
        mov     al, 1       ; set direction
328
        cmp     bl, 35h     ; write
329
        jz      @f
330
        add     al, 8       ; read
331
@@:
332
        out     dx, al      ; Start Bus Master
333
        mov     [IDE_common_irq_param], 14
334
        mov     eax, [hdpos]
335
        dec     eax
336
        test    eax, 10b
337
        jz      @f
338
        inc     [IDE_common_irq_param]
339
@@:
340
        push    edi esi ebx
341
        xor     ecx, ecx
342
        xor     esi, esi
343
        call    create_event
344
        mov     [eventPointer], eax
345
        mov     [eventID], edx
346
        sti
347
        mov     ebx, edx
348
        mov     ecx, 300
349
        call    wait_event_timeout
350
        test    eax, eax
351
        jnz     @f
352
        mov     [IDE_common_irq_param], 0
353
        mov     eax, [eventPointer]
354
        mov     ebx, [eventID]
355
        call    destroy_event
356
        mov     [eventPointer], 0
357
@@:
358
        pop     ebx esi
359
        call    kernel_free
360
        cmp     [eventPointer], 0
361
        jz      .hd_error
2288 clevermous 362
        ret
5569 Pathoswith 363
.PIO:
364
        inc     edx     ; ATACommand
365
        mov     al, bl
366
        out     dx, al  ; Start hard drive
3881 mario79 367
        popfd
5569 Pathoswith 368
.sectorTransfer:
369
        call    save_hd_wait_timeout
370
        in      al, dx
371
        in      al, dx
372
        in      al, dx
373
        in      al, dx
374
@@:
375
        call    check_hd_wait_timeout
376
        jc      .hd_error
377
        in      al, dx
378
        test    al, 8   ; ready for transfer?
379
        jz      @b
380
        cmp     [hd_setup], 1   ; do not mark error for setup request
381
        jz      @f
382
        test    al, 1   ; previous command ended up with an error
383
        jnz     .hd_error
384
@@:
3712 mario79 385
        pushfd
2288 clevermous 386
        cli
5569 Pathoswith 387
        cld
2288 clevermous 388
        mov     ecx, 256
389
        mov     edx, [hdbase]
5569 Pathoswith 390
        cmp     bl, 34h
391
        jz      .write
392
        rep insw
393
        jmp     @f
394
.write:
2288 clevermous 395
        rep outsw
5569 Pathoswith 396
@@:
3712 mario79 397
        popfd
5569 Pathoswith 398
        add     edx, 7
399
        dec     dword [blockSize]
400
        jnz     .sectorTransfer
2288 clevermous 401
        ret
5569 Pathoswith 402
.hd_error:
403
        cmp     bl, 30h
404
        jnc     hd_write_error
405
;-----------------------------------------------------------------
2288 clevermous 406
hd_read_error:
3712 mario79 407
        if lang eq sp
408
        DEBUGF 1,"K : FS - HD error de lectura\n"
409
        else
410
        DEBUGF 1,"K : FS - HD read error\n"
411
        end if
5569 Pathoswith 412
        stc
2288 clevermous 413
        ret
5569 Pathoswith 414
;-----------------------------------------------------------------
2288 clevermous 415
hd_write_error:
3309 esevece 416
        if lang eq sp
417
        DEBUGF 1,"K : FS - HD error de escritura\n"
418
        else
419
        DEBUGF 1,"K : FS - HD write error\n"
420
        end if
5569 Pathoswith 421
        stc
2288 clevermous 422
        ret
5569 Pathoswith 423
;-----------------------------------------------------------------
424
save_hd_wait_timeout:
425
        mov     eax, [timer_ticks]
426
        add     eax, 300        ; 3 sec timeout
427
        mov     [hd_wait_timeout], eax
2288 clevermous 428
        ret
5569 Pathoswith 429
;-----------------------------------------------------------------
430
check_hd_wait_timeout:
431
        mov     eax, [timer_ticks]
432
        cmp     [hd_wait_timeout], eax
433
        jc      @f
434
        ret
3712 mario79 435
@@:
5569 Pathoswith 436
        if lang eq sp
437
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
438
        else
439
        DEBUGF 1,"K : FS - HD timeout\n"
440
        end if
441
        stc
2288 clevermous 442
        ret
5569 Pathoswith 443
;-----------------------------------------------------------------
2288 clevermous 444
align 4
3870 mario79 445
IDE_irq_14_handler:
446
IDE_irq_15_handler:
5569 Pathoswith 447
IDE_common_irq_handler:
448
; DEBUGF  1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2
449
        cmp     [IDE_common_irq_param], 0
450
        jz      .exit
3870 mario79 451
        pushfd
452
        cli
453
        pushad
4700 mario79 454
        mov     ecx, [IDE_controller_pointer]
455
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
5569 Pathoswith 456
        cmp     [IDE_common_irq_param], 14
4291 mario79 457
        jz      @f
3870 mario79 458
        add     dx, 8
459
@@:
5569 Pathoswith 460
        add     edx, 2  ; Bus Master IDE Status register
4291 mario79 461
        in      al, dx
5569 Pathoswith 462
        test    al, 4
4291 mario79 463
        jz      @f
5569 Pathoswith 464
        mov     [IDE_common_irq_param], 0
465
        out     dx, al  ; clear Interrupt bit
4291 mario79 466
        sub     edx, 2
467
        xor     eax, eax
5569 Pathoswith 468
        out     dx, al  ; clear Bus Master IDE Command register
4291 mario79 469
        mov     edx, [hdbase]
5569 Pathoswith 470
        add     edx, 7
471
        in      al, dx  ; read status register
472
        mov     eax, [eventPointer]
473
        mov     ebx, [eventID]
474
        xor     edx, edx
475
        xor     esi, esi
476
        call    raise_event
2288 clevermous 477
        popad
478
        popfd
5569 Pathoswith 479
        mov     al, 1   ; remove the interrupt request
4291 mario79 480
        ret
481
@@:
482
        popad
5569 Pathoswith 483
        popfd
3870 mario79 484
.exit:
5569 Pathoswith 485
        xor     eax, eax    ; not our interrupt
2288 clevermous 486
        ret
5569 Pathoswith 487
;-----------------------------------------------------------------
4578 clevermous 488
proc clear_pci_ide_interrupts
489
        mov     esi, pcidev_list
4700 mario79 490
align 4
4578 clevermous 491
.loop:
492
        mov     esi, [esi+PCIDEV.fd]
493
        cmp     esi, pcidev_list
494
        jz      .done
4700 mario79 495
 
4720 mario79 496
;        cmp     [esi+PCIDEV.class], 0x01018F
497
        mov     eax, [esi+PCIDEV.class]
498
        shr     eax, 4
499
        cmp     eax, 0x01018
4578 clevermous 500
        jnz     .loop
4700 mario79 501
 
4578 clevermous 502
        mov     ah, [esi+PCIDEV.bus]
503
        mov     al, 2
504
        mov     bh, [esi+PCIDEV.devfn]
505
        mov     bl, 0x20
506
        call    pci_read_reg
4700 mario79 507
 
4578 clevermous 508
        and     eax, 0FFFCh
509
        mov     edx, eax
510
        add     edx, 2
511
        in      al, dx
512
        DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
513
        out     dx, al
514
        in      al, dx
515
        DEBUGF 1,'-> %x; ',al
516
        add     edx, 8
517
        in      al, dx
518
        DEBUGF 1,'port[%x] = %x ',dx,al
519
        out     dx, al
520
        in      al, dx
521
        DEBUGF 1,'-> %x\n',al
522
        jmp     .loop
523
.done:
524
        ret
525
endp