Subversion Repositories Kolibri OS

Rev

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

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