Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
593 mikedld 8
$Revision: 593 $
9
 
10
 
472 serge 11
; Low-level driver for HDD access
346 diamond 12
; DMA support by Mario79
160 diamond 13
 
14
align 4
15
hd_read:
16
;-----------------------------------------------------------
17
; input  : eax = block to read
18
;          ebx = destination
19
;-----------------------------------------------------------
256 diamond 20
        and     [hd_error], 0
160 diamond 21
    push  ecx esi edi           ; scan cache
22
 
580 mario79 23
;    mov   ecx,cache_max         ; entries in cache
24
;    mov   esi,HD_CACHE+8
25
    call  calculate_cache
26
    add   esi,8
581 serge 27
 
160 diamond 28
    mov   edi,1
29
 
30
  hdreadcache:
31
 
32
    cmp   dword [esi+4],0       ; empty
33
    je    nohdcache
34
 
35
    cmp   [esi],eax             ; correct sector
36
    je    yeshdcache
37
 
38
  nohdcache:
39
 
40
    add   esi,8
41
    inc   edi
42
    dec   ecx
43
    jnz   hdreadcache
44
 
45
    call  find_empty_slot       ; ret in edi
46
    cmp   [hd_error],0
47
    jne   return_01
514 diamond 48
; DMA read is permitted if [allow_dma_access]=1 or 2
49
        cmp     [allow_dma_access], 2
50
        ja      .nodma
160 diamond 51
        cmp     [dma_hdd], 1
52
        jnz     .nodma
53
        call    hd_read_dma
54
        jmp     @f
55
.nodma:
56
        call    hd_read_pio
57
@@:
580 mario79 58
;    lea   esi,[edi*8+HD_CACHE]
59
;    push  eax
60
    call  calculate_cache_1
61
    lea   esi,[edi*8+esi]
62
;    pop   eax
160 diamond 63
 
64
    mov   [esi],eax             ; sector number
65
    mov   dword [esi+4],1       ; hd read - mark as same as in hd
66
 
67
  yeshdcache:
68
 
69
    mov   esi,edi
70
    shl   esi,9
580 mario79 71
;    add   esi,HD_CACHE+65536
72
    push  eax
73
    call  calculate_cache_2
74
    add   esi,eax
75
    pop   eax
581 serge 76
 
160 diamond 77
    mov   edi,ebx
78
    mov   ecx,512/4
79
    cld
80
    rep   movsd                 ; move data
81
 return_01:
82
    pop   edi esi ecx
83
    ret
84
 
85
align 4
86
hd_read_pio:
87
    push  eax edx
88
 
89
    call  wait_for_hd_idle
90
    cmp   [hd_error],0
389 serge 91
    jne   hd_read_error
160 diamond 92
 
321 diamond 93
    cli
160 diamond 94
    xor   eax,eax
95
    mov   edx,[hdbase]
96
    inc   edx
97
    out   dx,al   ; ATAFeatures регистр "особенностей"
98
    inc   edx
99
    inc   eax
100
    out   dx,al   ; ATASectorCount счётчик секторов
101
    inc   edx
102
    mov   eax,[esp+4]
103
    out   dx,al   ; ATASectorNumber регистр номера сектора
104
    shr   eax,8
105
    inc   edx
106
    out   dx,al   ; ATACylinder номер цилиндра (младший байт)
107
    shr   eax,8
108
    inc   edx
109
    out   dx,al   ; номер цилиндра (старший байт)
110
    shr   eax,8
111
    inc   edx
112
    and   al,1+2+4+8
113
    add   al,byte [hdid]
114
    add   al,128+64+32
115
    out   dx,al   ; номер головки/номер диска
116
    inc   edx
117
    mov   al,20h
118
    out   dx,al   ; ATACommand регистр команд
321 diamond 119
    sti
160 diamond 120
 
121
    call  wait_for_sector_buffer
122
 
123
    cmp   [hd_error],0
124
    jne   hd_read_error
125
 
321 diamond 126
    cli
160 diamond 127
    push  edi
128
    shl   edi,9
580 mario79 129
;    add   edi,HD_CACHE+65536
130
    push  eax
131
    call  calculate_cache_2
132
    add   edi,eax
133
    pop   eax
581 serge 134
 
160 diamond 135
    mov   ecx,256
136
    mov   edx,[hdbase]
137
    cld
138
    rep   insw
139
    pop   edi
321 diamond 140
    sti
160 diamond 141
 
142
    pop   edx eax
143
    ret
144
 
389 serge 145
disable_ide_int:
162 diamond 146
;        mov edx,[hdbase]
147
;        add edx,0x206
148
;        mov al,2
149
;        out dx,al
150
        cli
160 diamond 151
        ret
152
 
153
enable_ide_int:
162 diamond 154
;        mov edx,[hdbase]
155
;        add edx,0x206
156
;        mov al,0
157
;        out dx,al
158
        sti
160 diamond 159
        ret
160
 
161
align 4
162
hd_write:
163
;-----------------------------------------------------------
164
; input  : eax = block
165
;          ebx = pointer to memory
166
;-----------------------------------------------------------
167
    push  ecx esi edi
168
 
169
    ; check if the cache already has the sector and overwrite it
170
 
580 mario79 171
;    mov   ecx,cache_max
172
;    mov   esi,HD_CACHE+8
173
    call  calculate_cache
174
    add   esi,8
581 serge 175
 
160 diamond 176
    mov   edi,1
177
 
178
  hdwritecache:
179
 
180
    cmp   dword [esi+4],0       ; if cache slot is empty
181
    je    not_in_cache_write
182
 
183
    cmp   [esi],eax             ; if the slot has the sector
184
    je    yes_in_cache_write
185
 
186
  not_in_cache_write:
187
 
188
    add   esi,8
189
    inc   edi
190
    dec   ecx
191
    jnz   hdwritecache
192
 
193
    ; sector not found in cache
194
    ; write the block to a new location
195
 
196
    call  find_empty_slot       ; ret in edi
197
    cmp   [hd_error],0
198
    jne   hd_write_access_denied
199
 
580 mario79 200
;    lea   esi,[edi*8+HD_CACHE]
201
;    push  eax
202
    call  calculate_cache_1
203
    lea   esi,[edi*8+esi]
204
;    pop   eax
205
 
160 diamond 206
    mov   [esi],eax             ; sector number
207
 
208
  yes_in_cache_write:
209
 
210
    mov   dword [esi+4],2       ; write - differs from hd
211
 
212
    shl   edi,9
580 mario79 213
;    add   edi,HD_CACHE+65536
214
    push  eax
215
    call  calculate_cache_2
216
    add   edi,eax
217
    pop   eax
581 serge 218
 
160 diamond 219
    mov   esi,ebx
220
    mov   ecx,512/4
221
    cld
222
    rep   movsd                 ; move data
223
 hd_write_access_denied:
224
    pop   edi esi ecx
225
    ret
226
 
227
align 4
228
cache_write_pio:
580 mario79 229
;    call  disable_ide_int
581 serge 230
 
160 diamond 231
    call  wait_for_hd_idle
232
    cmp   [hd_error],0
233
    jne   hd_write_error
234
 
580 mario79 235
    cli
160 diamond 236
    xor   eax,eax
237
    mov   edx,[hdbase]
238
    inc   edx
239
    out   dx,al
240
    inc   edx
241
    inc   eax
242
    out   dx,al
243
    inc   edx
244
    mov   eax,[esi]             ; eax = sector to write
245
    out   dx,al
246
    shr   eax,8
247
    inc   edx
248
    out   dx,al
249
    shr   eax,8
250
    inc   edx
251
    out   dx,al
252
    shr   eax,8
253
    inc   edx
254
    and   al,1+2+4+8
255
    add   al,byte [hdid]
256
    add   al,128+64+32
257
    out   dx,al
258
    inc   edx
259
    mov   al,30h
260
    out   dx,al
580 mario79 261
    sti
160 diamond 262
 
263
    call  wait_for_sector_buffer
264
 
265
    cmp   [hd_error],0
266
    jne   hd_write_error
267
 
268
    push  ecx esi
269
 
580 mario79 270
    cli
160 diamond 271
    mov   esi,edi
272
    shl   esi,9
580 mario79 273
;    add   esi,HD_CACHE+65536    ; esi = from memory position
274
    push  eax
275
    call  calculate_cache_2
276
    add   esi,eax
277
    pop   eax
581 serge 278
 
160 diamond 279
    mov   ecx,256
280
    mov   edx,[hdbase]
281
    cld
282
    rep   outsw
580 mario79 283
    sti
160 diamond 284
 
580 mario79 285
;    call  enable_ide_int
160 diamond 286
    pop   esi ecx
287
 
288
    ret
289
 
290
save_hd_wait_timeout:
291
 
292
    push  eax
465 serge 293
    mov   eax,[timer_ticks]
160 diamond 294
    add   eax,300               ; 3 sec timeout
295
    mov   [hd_wait_timeout],eax
296
    pop   eax
297
    ret
298
 
299
align 4
300
check_hd_wait_timeout:
301
 
302
    push  eax
303
    mov   eax,[hd_wait_timeout]
465 serge 304
    cmp   [timer_ticks], eax
160 diamond 305
    jg    hd_timeout_error
306
    pop   eax
307
    mov   [hd_error],0
308
    ret
309
 
358 mikedld 310
;iglobal
311
;  hd_timeout_str   db 'K : FS - HD timeout',0
312
;  hd_read_str      db 'K : FS - HD read error',0
313
;  hd_write_str     db 'K : FS - HD write error',0
314
;  hd_lba_str       db 'K : FS - HD LBA error',0
315
;endg
160 diamond 316
 
317
hd_timeout_error:
318
 
321 diamond 319
;    call  clear_hd_cache
320
;    call  clear_application_table_status
358 mikedld 321
;    mov   esi,hd_timeout_str
322
;    call  sys_msg_board_str
465 serge 323
    DEBUGF 1,"K : FS - HD timeout\n"
324
 
160 diamond 325
    mov   [hd_error],1
326
    pop   eax
327
    ret
328
 
329
hd_read_error:
330
 
321 diamond 331
;    call  clear_hd_cache
332
;    call  clear_application_table_status
358 mikedld 333
;    mov   esi,hd_read_str
334
;    call  sys_msg_board_str
465 serge 335
    DEBUGF 1,"K : FS - HD read error\n"
160 diamond 336
    pop   edx eax
161 diamond 337
    ret
160 diamond 338
 
339
hd_write_error:
340
 
321 diamond 341
;    call  clear_hd_cache
342
;    call  clear_application_table_status
465 serge 343
;     mov   esi,hd_write_str
344
;     call  sys_msg_board_str
345
    DEBUGF 1,"K : FS - HD write error\n"
346
     ret
160 diamond 347
 
348
hd_write_error_dma:
321 diamond 349
;        call    clear_hd_cache
350
;        call    clear_application_table_status
358 mikedld 351
;        mov     esi, hd_write_str
352
;        call    sys_msg_board_str
465 serge 353
        DEBUGF 1,"K : FS - HD read error\n"
160 diamond 354
        pop     esi
161 diamond 355
        ret
160 diamond 356
 
357
hd_lba_error:
321 diamond 358
;    call  clear_hd_cache
359
;    call  clear_application_table_status
358 mikedld 360
;    mov   esi,hd_lba_str
361
;    call  sys_msg_board_str
465 serge 362
     DEBUGF 1,"K : FS - HD LBA error\n"
363
     jmp   LBA_read_ret
160 diamond 364
 
365
 
366
align 4
367
wait_for_hd_idle:
368
 
369
    push  eax edx
370
 
371
    call  save_hd_wait_timeout
372
 
373
    mov   edx,[hdbase]
374
    add   edx,0x7
375
 
376
  wfhil1:
377
 
378
    call  check_hd_wait_timeout
379
    cmp   [hd_error],0
380
    jne   @f
381
 
382
    in    al,dx
383
    test  al,128
384
    jnz   wfhil1
389 serge 385
 
160 diamond 386
 @@:
387
 
388
    pop   edx eax
389
    ret
390
 
391
 
392
align 4
393
wait_for_sector_buffer:
394
 
395
    push  eax edx
396
 
397
    mov   edx,[hdbase]
398
    add   edx,0x7
399
 
400
    call  save_hd_wait_timeout
401
 
402
  hdwait_sbuf:                  ; wait for sector buffer to be ready
403
 
404
    call  check_hd_wait_timeout
405
    cmp   [hd_error],0
406
    jne   @f
407
 
408
    in    al,dx
409
    test  al,8
410
    jz    hdwait_sbuf
411
 
412
    mov   [hd_error],0
413
 
414
    cmp   [hd_setup],1          ; do not mark error for setup request
415
    je    buf_wait_ok
416
 
417
    test  al,1                  ; previous command ended up with an error
418
    jz    buf_wait_ok
419
 @@:
420
    mov   [hd_error],1
421
 
422
  buf_wait_ok:
423
 
424
    pop   edx eax
425
    ret
426
 
346 diamond 427
; \begin{Mario79}
160 diamond 428
align 4
429
wait_for_sector_dma_ide0:
430
        push    eax
431
        push    edx
432
        call    save_hd_wait_timeout
433
.wait:
434
        call    change_task
435
        cmp     [irq14_func], hdd_irq14
436
        jnz     .done
437
        call    check_hd_wait_timeout
438
        cmp     [hd_error], 0
439
        jz      .wait
440
        mov     [irq14_func], hdd_irq_null
441
        mov     dx, [IDEContrRegsBaseAddr]
442
        mov     al, 0
443
        out     dx, al
444
.done:
445
        pop     edx
446
        pop     eax
447
        ret
448
 
449
align 4
450
wait_for_sector_dma_ide1:
451
        push    eax
452
        push    edx
453
        call    save_hd_wait_timeout
454
.wait:
455
        call    change_task
456
        cmp     [irq15_func], hdd_irq15
457
        jnz     .done
458
        call    check_hd_wait_timeout
459
        cmp     [hd_error], 0
460
        jz      .wait
461
        mov     [irq15_func], hdd_irq_null
462
        mov     dx, [IDEContrRegsBaseAddr]
463
        add     dx, 8
464
        mov     al, 0
465
        out     dx, al
466
.done:
467
        pop     edx
468
        pop     eax
469
        ret
470
 
471
iglobal
472
align 4
473
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
474
IDE_descriptor_table:
581 serge 475
        dd      IDE_DMA
465 serge 476
        dw      0x2000
477
        dw      0x8000
160 diamond 478
 
479
dma_cur_sector  dd      not 40h
480
irq14_func      dd      hdd_irq_null
481
irq15_func      dd      hdd_irq_null
482
endg
483
 
484
uglobal
485
; all uglobals are zeroed at boot
486
dma_process     dd      0
487
dma_slot_ptr    dd      0
488
cache_chain_pos dd      0
489
cache_chain_ptr dd      0
490
cache_chain_size        db      0
491
cache_chain_started     db      0
492
dma_task_switched       db      0
493
dma_hdd         db      0
514 diamond 494
allow_dma_access db      0
160 diamond 495
endg
496
 
497
align 4
498
hdd_irq14:
499
        pushfd
500
        cli
501
        pushad
502
        mov     [irq14_func], hdd_irq_null
503
        mov     dx, [IDEContrRegsBaseAddr]
504
        mov     al, 0
505
        out     dx, al
465 serge 506
;        call    update_counters
507
;        mov     ebx, [dma_process]
508
;        cmp     [CURRENT_TASK], ebx
509
;        jz      .noswitch
510
;        mov     [dma_task_switched], 1
511
;        mov     edi, [dma_slot_ptr]
512
;        mov     eax, [CURRENT_TASK]
513
;        mov     [dma_process], eax
514
;        mov     eax, [TASK_BASE]
515
;        mov     [dma_slot_ptr], eax
516
;        mov     [CURRENT_TASK], ebx
517
;        mov     [TASK_BASE], edi
518
;        mov     byte [DONT_SWITCH], 1
519
;        call    do_change_task
160 diamond 520
.noswitch:
521
        popad
522
        popfd
523
align 4
524
hdd_irq_null:
525
        ret
526
 
527
align 4
528
hdd_irq15:
529
        pushfd
530
        cli
531
        pushad
532
        mov     [irq15_func], hdd_irq_null
533
        mov     dx, [IDEContrRegsBaseAddr]
534
        add     dx, 8
535
        mov     al, 0
536
        out     dx, al
465 serge 537
;        call    update_counters
538
;        mov     ebx, [dma_process]
539
;        cmp     [CURRENT_TASK], ebx
540
;        jz      .noswitch
541
;        mov     [dma_task_switched], 1
542
;        mov     edi, [dma_slot_ptr]
543
;        mov     eax, [CURRENT_TASK]
544
;        mov     [dma_process], eax
545
;        mov     eax, [TASK_BASE]
546
;        mov     [dma_slot_ptr], eax
547
;        mov     [CURRENT_TASK], ebx
548
;        mov     [TASK_BASE], edi
549
;        mov     byte [DONT_SWITCH], 1
550
;        call    do_change_task
160 diamond 551
.noswitch:
552
        popad
553
        popfd
554
        ret
555
 
556
align 4
557
hd_read_dma:
558
        push    eax
559
        push    edx
560
        mov     edx, [dma_cur_sector]
561
        cmp     eax, edx
562
        jb      .notread
563
        add     edx, 15
564
        cmp     [esp+4], edx
565
        ja      .notread
566
        mov     eax, [esp+4]
567
        sub     eax, [dma_cur_sector]
568
        shl     eax, 9
581 serge 569
        add     eax, (OS_BASE+IDE_DMA)
160 diamond 570
        push    ecx esi edi
571
        mov     esi, eax
572
        shl     edi, 9
580 mario79 573
;        add     edi, HD_CACHE+0x10000
574
        push  eax
575
        call  calculate_cache_2
576
        add   edi,eax
577
        pop   eax
581 serge 578
 
160 diamond 579
        mov     ecx, 512/4
580
        cld
581
        rep     movsd
582
        pop     edi esi ecx
583
        pop     edx
584
        pop     eax
585
        ret
586
.notread:
465 serge 587
        mov     eax, IDE_descriptor_table
581 serge 588
        mov     dword [eax],  IDE_DMA
465 serge 589
        mov     word [eax+4], 0x2000
590
        sub     eax, OS_BASE
160 diamond 591
        mov     dx, [IDEContrRegsBaseAddr]
592
        cmp     [hdbase], 0x1F0
593
        jz      @f
594
        add     edx, 8
595
@@:
596
        push    edx
597
        add     edx, 4
598
        out     dx, eax
599
        pop     edx
600
        mov     al, 0
601
        out     dx, al
602
        add     edx, 2
603
        mov     al, 6
604
        out     dx, al
605
        call    wait_for_hd_idle
606
        cmp     [hd_error], 0
607
        jnz     hd_read_error
608
        call    disable_ide_int
609
        xor     eax, eax
610
        mov     edx, [hdbase]
611
        inc     edx
612
        out     dx, al
613
        inc     edx
614
        mov     eax, 10h
615
        out     dx, al
616
        inc     edx
617
        mov     eax, [esp+4]
618
        out     dx, al
619
        shr     eax, 8
620
        inc     edx
621
        out     dx, al
622
        shr     eax, 8
623
        inc     edx
624
        out     dx, al
625
        shr     eax, 8
626
        inc     edx
627
        and     al, 0xF
628
        add     al, byte [hdid]
629
        add     al, 11100000b
630
        out     dx, al
631
        inc     edx
632
        mov     al, 0xC8
633
        out     dx, al
634
        mov     dx, [IDEContrRegsBaseAddr]
635
        cmp     [hdbase], 0x1F0
636
        jz      @f
637
        add     dx, 8
638
@@:
639
        mov     al, 9
640
        out     dx, al
389 serge 641
        mov     eax, [CURRENT_TASK]
160 diamond 642
        mov     [dma_process], eax
389 serge 643
        mov     eax, [TASK_BASE]
160 diamond 644
        mov     [dma_slot_ptr], eax
645
        cmp     [hdbase], 0x1F0
646
        jnz     .ide1
647
        mov     [irq14_func], hdd_irq14
648
        jmp     @f
649
.ide1:
650
        mov     [irq15_func], hdd_irq15
651
@@:
652
        call    enable_ide_int
653
        cmp     [hdbase], 0x1F0
654
        jnz     .wait_ide1
655
        call    wait_for_sector_dma_ide0
656
        jmp     @f
657
.wait_ide1:
658
        call    wait_for_sector_dma_ide1
659
@@:
660
        cmp     [hd_error], 0
661
        jnz     hd_read_error
662
        pop     edx
663
        pop     eax
664
        mov     [dma_cur_sector], eax
665
        jmp     hd_read_dma
666
 
667
align 4
668
write_cache_sector:
580 mario79 669
        mov     [cache_chain_size],1
670
        mov     [cache_chain_pos],edi
581 serge 671
write_cache_chain:
160 diamond 672
        push    esi
673
        mov     eax, IDE_descriptor_table
580 mario79 674
        mov     edx,eax
675
        pusha
676
        mov     esi,[cache_chain_pos]
677
        shl     esi, 9
678
        call    calculate_cache_2
679
        add     esi,eax
581 serge 680
        mov     edi, (OS_BASE+IDE_DMA)
681
        mov     dword [edx], IDE_DMA
580 mario79 682
        movzx   ecx, [cache_chain_size]
683
        shl     ecx, 9
684
        mov     word [edx+4], cx
685
        shr     ecx,2
686
        cld
687
        rep movsd
688
        popa
465 serge 689
        sub     eax, OS_BASE
160 diamond 690
        mov     dx, [IDEContrRegsBaseAddr]
691
        cmp     [hdbase], 0x1F0
692
        jz      @f
693
        add     edx, 8
694
@@:
695
        push    edx
696
        add     edx, 4
697
        out     dx, eax
698
        pop     edx
699
        mov     al, 0
700
        out     dx, al
701
        add     edx, 2
702
        mov     al, 6
703
        out     dx, al
704
        call    wait_for_hd_idle
705
        cmp     [hd_error], 0
706
        jnz     hd_write_error_dma
707
        call    disable_ide_int
708
        xor     eax, eax
709
        mov     edx, [hdbase]
710
        inc     edx
711
        out     dx, al
712
        inc     edx
713
        mov     al, [cache_chain_size]
714
        out     dx, al
715
        inc     edx
716
        mov     esi, [cache_chain_ptr]
717
        mov     eax, [esi]
718
        out     dx, al
719
        shr     eax, 8
720
        inc     edx
721
        out     dx, al
722
        shr     eax, 8
723
        inc     edx
724
        out     dx, al
725
        shr     eax, 8
726
        inc     edx
727
        and     al, 0xF
728
        add     al, byte [hdid]
729
        add     al, 11100000b
730
        out     dx, al
731
        inc     edx
732
        mov     al, 0xCA
733
        out     dx, al
734
        mov     dx, [IDEContrRegsBaseAddr]
735
        cmp     [hdbase], 0x1F0
736
        jz      @f
737
        add     dx, 8
738
@@:
739
        mov     al, 1
740
        out     dx, al
389 serge 741
        mov     eax, [CURRENT_TASK]
160 diamond 742
        mov     [dma_process], eax
389 serge 743
        mov     eax, [TASK_BASE]
160 diamond 744
        mov     [dma_slot_ptr], eax
745
        cmp     [hdbase], 0x1F0
746
        jnz     .ide1
747
        mov     [irq14_func], hdd_irq14
748
        jmp     @f
749
.ide1:
750
        mov     [irq15_func], hdd_irq15
751
@@:
752
        call    enable_ide_int
753
        mov     [dma_cur_sector], not 0x40
754
        cmp     [hdbase], 0x1F0
755
        jnz     .wait_ide1
756
        call    wait_for_sector_dma_ide0
757
        jmp     @f
758
.wait_ide1:
759
        call    wait_for_sector_dma_ide1
760
@@:
761
        cmp     [hd_error], 0
762
        jnz     hd_write_error_dma
763
        pop     esi
764
        ret
765
 
766
uglobal
767
IDEContrRegsBaseAddr    dw      ?
768
endg
346 diamond 769
; \end{Mario79}