Subversion Repositories Kolibri OS

Rev

Rev 161 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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