Subversion Repositories Kolibri OS

Rev

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

Rev 9145 Rev 9162
Line 8... Line 8...
8
$Revision$
8
$Revision$
Line 9... Line 9...
9
 
9
 
10
PCI_REG_STATUS_COMMAND = 0x0004
10
PCI_REG_STATUS_COMMAND = 0x0004
Line -... Line 11...
-
 
11
PCI_REG_BAR5 = 0x0024
-
 
12
 
11
PCI_REG_BAR5 = 0x0024
13
AHCI_DBGLVL = 0 ; debug output verbosity level. 0 - less verbose, 1 - more verbose
12
 
14
 
13
; different SATA device signatures
15
; different SATA device signatures
14
SATA_SIG_ATA	= 0x00000101	; SATA drive
16
SATA_SIG_ATA	= 0x00000101	; SATA drive
15
SATA_SIG_ATAPI	= 0xEB140101	; SATAPI drive
17
SATA_SIG_ATAPI	= 0xEB140101	; SATAPI drive
Line 24... Line 26...
24
AHCI_DEV_SATAPI = 4
26
AHCI_DEV_SATAPI = 4
Line 25... Line 27...
25
 
27
 
26
; ATA commands
28
; ATA commands
27
ATA_IDENTIFY        = 0xEC
29
ATA_IDENTIFY         = 0xEC
-
 
30
ATA_CMD_READ_DMA_EX  = 0x25
Line 28... Line 31...
28
ATA_CMD_READ_DMA_EX = 0x25
31
ATA_CMD_WRITE_DMA_EX = 0x35
29
 
32
 
30
; ATA constants
33
; ATA constants
Line 31... Line 34...
31
ATA_DEV_BUSY    = 0x80
34
ATA_DEV_BUSY    = 0x80
32
ATA_DEV_DRQ     = 0x08
35
ATA_DEV_DRQ     = 0x08
Line -... Line 36...
-
 
36
 
-
 
37
; ATAPI commands
33
 
38
ATAPI_IDENTIFY  = 0xA1
34
; ATAPI commands
39
 
35
ATAPI_IDENTIFY  = 0xA1
40
PRDT_MAX_ENTRIES = 16 ;65535
Line 36... Line 41...
36
 
41
 
Line 502... Line 507...
502
        bt      [esi + HBA_MEM.cap], 27 ; check Supports Staggered Spin-up bit in capabilities
507
        bt      [esi + HBA_MEM.cap], 27 ; check Supports Staggered Spin-up bit in capabilities
503
        jnc     @f
508
        jnc     @f
504
        DEBUGF  1, "Supports Staggered Spin-up, spinning up the port..\n"
509
        DEBUGF  1, "Supports Staggered Spin-up, spinning up the port..\n"
505
        or      [edi + HBA_PORT.command], (0x0002 or 0x0004 or 0x10000000)
510
        or      [edi + HBA_PORT.command], (0x0002 or 0x0004 or 0x10000000)
506
        push    ebx
511
        push    ebx
507
        mov     ebx, 1 ; wait 10 ms
512
        mov     ebx, 10 ; wait 100 ms
508
        call    delay_hs
513
        call    delay_hs
509
        pop     ebx
514
        pop     ebx
510
@@:
515
@@:
511
        ; Clear interrupt status and error status
516
        ; Clear interrupt status and error status
512
        mov     [edi + HBA_PORT.sata_error], 0xFFFFFFFF
517
        mov     [edi + HBA_PORT.sata_error], 0xFFFFFFFF
Line 748... Line 753...
748
        pop     edx ecx
753
        pop     edx ecx
749
        xor     eax, eax
754
        xor     eax, eax
750
        ret
755
        ret
751
endp
756
endp
Line 752... Line 757...
752
 
757
 
753
; Read sectors
758
; Read/write sectors
754
; return value: 0 = success, otherwise = error
759
; return value: 0 = success, otherwise = error
755
proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
760
proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, numsectors: dword, is_write: dword
756
        locals
761
        locals
757
            cmdslot dd ?
762
            cmdslot dd ?
758
            cmdheader dd ?
763
            cmdheader dd ?
759
            cmdtable  dd ?
764
            cmdtable  dd ?
-
 
765
            vbuf_orig dd ?
-
 
766
            vbuf_len  dd ?
-
 
767
            phys_region_start dd ?
760
            numsectors dd ?
768
            new_phys_region_start dd ?
761
            buffer_pos dd ?
769
            cur_prd   dd ?
-
 
770
            cur_phys  dd ?
-
 
771
            dbc       dd ?
-
 
772
            cur_phys_page dd ?
-
 
773
            next_phys_page dd ?
-
 
774
            cur_antioffset dd ?
762
            buffer_length dd ?
775
            prdt_bytes_total dd ?
Line 763... Line 776...
763
        endl
776
        endl
Line 764... Line -...
764
 
-
 
765
        pushad
-
 
766
 
-
 
767
        mov     ecx, ahci_mutex
-
 
768
        call    mutex_lock
-
 
769
 
-
 
770
;         xor     ecx, ecx
-
 
771
;         mov     esi, [buffer]
-
 
772
; .print_data:
-
 
773
;         cmp     ecx, 512
-
 
774
;         jae     .end_print_data
-
 
775
 
-
 
776
;         mov     al, byte [esi + ecx]
-
 
777
;         mov     byte [tmpstr], al
-
 
778
;         mov     byte [tmpstr + 1], 0
-
 
779
;         DEBUGF  1, "0x%x(%s) ", al:2, tmpstr
-
 
780
 
-
 
781
;         inc     ecx
-
 
782
;         jmp     .print_data
-
 
783
; .end_print_data:
-
 
784
;         DEBUGF  1, "\n"
-
 
785
 
-
 
786
        mov     eax, [numsectors_ptr]
-
 
787
        mov     eax, [eax]
777
 
Line 788... Line 778...
788
        mov     [numsectors], eax
778
        pushad
789
 
779
 
790
        DEBUGF  1, "  ahci_read: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u\n", [buffer], [startsector], [startsector + 4], eax
780
        DEBUGF  AHCI_DBGLVL, "    ahci_rw_sectors: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u, is_write = %u\n", [vbuf], [startsector], [startsector + 4], [numsectors], [is_write]:1
791
 
781
 
792
        mov     esi, [pdata] ; esi - address of PORT_DATA struct of port
782
        mov     esi, [pdata] ; esi - address of PORT_DATA struct of port
793
        mov     edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
783
        mov     edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
Line 794... Line 784...
794
        mov     eax, edi
784
        mov     eax, edi
795
        call    ahci_find_cmdslot
785
        call    ahci_find_cmdslot
Line 796... Line 786...
796
        cmp     eax, -1
786
        cmp     eax, -1
797
        jne      .cmdslot_found
787
        jne      .cmdslot_found
798
 
788
 
Line 799... Line 789...
799
        DEBUGF  1, "No free cmdslot on port %u\n", [esi + PORT_DATA.portno]
789
        DEBUGF  AHCI_DBGLVL, "No free cmdslot on port %u\n", [esi + PORT_DATA.portno]
800
        jmp     .ret
790
        jmp     .fail
801
 
791
 
802
.cmdslot_found:
792
.cmdslot_found:
Line 813... Line 803...
813
        mov     eax, [cmdheader]
803
        mov     eax, [cmdheader]
814
        and     [eax + HBA_CMD_HDR.flags1], not 0x1F ; zero out lower 5 bits, they will be used for cfl
804
        and     [eax + HBA_CMD_HDR.flags1], not 0x1F ; zero out lower 5 bits, they will be used for cfl
815
        or      [eax + HBA_CMD_HDR.flags1], (sizeof.FIS_REG_H2D / 4) ; set command fis length in dwords
805
        or      [eax + HBA_CMD_HDR.flags1], (sizeof.FIS_REG_H2D / 4) ; set command fis length in dwords
816
        movzx   bx, [eax + HBA_CMD_HDR.flags1]
806
        movzx   bx, [eax + HBA_CMD_HDR.flags1]
817
        btr     bx, 6 ; flag W = 0
807
        btr     bx, 6 ; flag W = 0
-
 
808
        cmp     [is_write], 1 ; if is_write then set W flag
-
 
809
        jne     @f
-
 
810
        bts     bx, 6
-
 
811
@@:
818
        mov     [eax + HBA_CMD_HDR.flags1], bl
812
        mov     [eax + HBA_CMD_HDR.flags1], bl
819
        movzx   bx, [eax + HBA_CMD_HDR.flags2]
813
        movzx   bx, [eax + HBA_CMD_HDR.flags2]
820
        btr     bx, 2 ; flag C = 0
814
        btr     bx, 2 ; flag C = 0
821
        mov     [eax + HBA_CMD_HDR.flags2], bl
815
        mov     [eax + HBA_CMD_HDR.flags2], bl
Line -... Line 816...
-
 
816
 
-
 
817
        mov     eax, [vbuf]
822
 
818
        mov     [vbuf_orig], eax
823
        mov     ebx, [numsectors]
819
        mov     ebx, [numsectors]
824
        shl     ebx, 9 ; *= 512
820
        shl     ebx, 9 ; *= 512
825
        mov     [buffer_length], ebx
-
 
826
        dec     ebx
-
 
827
        shr     ebx, 12 ; /= 4096
-
 
828
        inc     ebx
-
 
829
        mov     [eax + HBA_CMD_HDR.prdtl], bx
821
        mov     [vbuf_len], ebx
Line -... Line 822...
-
 
822
        DEBUGF  AHCI_DBGLVL, "vbuf_len = %u bytes\n", ebx
-
 
823
        
-
 
824
        mov     ebx, [vbuf]
-
 
825
        and     ebx, 0xFFF
-
 
826
        mov     eax, [vbuf]
-
 
827
        call    get_pg_addr
-
 
828
        add     eax, ebx
-
 
829
        mov     [phys_region_start], eax
-
 
830
        mov     [prdt_bytes_total], 0
-
 
831
        mov     [cur_prd], 0
830
        ;DEBUGF  1, "  prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2
832
.fill_prdt:
-
 
833
        cmp     [vbuf_len], 0
-
 
834
        jbe     .fill_prdt_end
-
 
835
 
-
 
836
        mov     eax, [vbuf]
-
 
837
        call    get_pg_addr
-
 
838
        mov     [cur_phys_page], eax
-
 
839
        mov     eax, [vbuf]
-
 
840
        add     eax, 4096
-
 
841
        call    get_pg_addr
-
 
842
        mov     [next_phys_page], eax
-
 
843
        mov     eax, 4096
831
        
844
        mov     ebx, [vbuf]
-
 
845
        and     ebx, 0xFFF
832
        ; zero out the command table with its prdt entries
846
        sub     eax, ebx
833
        dec     ebx
847
        mov     [cur_antioffset], eax
834
        shl     ebx, BSF sizeof.HBA_PRDT_ENTRY
848
        mov     eax, [cur_phys_page]
Line -... Line 849...
-
 
849
        add     eax, ebx
-
 
850
        mov     [cur_phys], eax
-
 
851
 
-
 
852
.check_if1:
-
 
853
        mov     eax, [vbuf_len]
-
 
854
        cmp     eax, [cur_antioffset]
835
        add     ebx, sizeof.HBA_CMD_TBL
855
        ja      .check_if2
-
 
856
 
-
 
857
        mov     eax, [cur_phys]
-
 
858
        sub     eax, [phys_region_start]
-
 
859
        add     eax, [vbuf_len]
-
 
860
        dec     eax
-
 
861
        mov     [dbc], eax
-
 
862
        mov     eax, [next_phys_page]
-
 
863
        mov     [new_phys_region_start], eax
-
 
864
        jmp     .add_prd 
-
 
865
 
-
 
866
.check_if2:
-
 
867
        mov     eax, [cur_phys]
-
 
868
        add     eax, [cur_antioffset]
-
 
869
        cmp     eax, [next_phys_page]
-
 
870
        je      .check_if3
-
 
871
 
-
 
872
        mov     eax, [cur_phys]
-
 
873
        add     eax, [cur_antioffset]
-
 
874
        sub     eax, [phys_region_start]
-
 
875
        dec     eax
-
 
876
        mov     [dbc], eax
-
 
877
        mov     eax, [next_phys_page]
-
 
878
        mov     [new_phys_region_start], eax
-
 
879
        jmp     .add_prd
-
 
880
 
-
 
881
.check_if3:
-
 
882
        mov     eax, [cur_phys]
-
 
883
        add     eax, [cur_antioffset]
-
 
884
        sub     eax, [phys_region_start]
-
 
885
        cmp     eax, 4*1024*1024
-
 
886
        jb      .after_ifs
-
 
887
 
836
        stdcall _memset, [cmdtable], 0, ebx
888
        mov     [dbc], 4*1024*1024 - 1
Line 837... Line -...
837
        
-
 
838
        DEBUGF  1, "  prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2
-
 
839
        ;jmp     .ret
-
 
840
 
-
 
841
        xor     ecx, ecx
-
 
842
        movzx   edx, [eax + HBA_CMD_HDR.prdtl]
-
 
843
        dec     edx
889
        mov     eax, [phys_region_start]
844
        mov     eax, [buffer]
890
        add     eax, 4*1024*1024
845
        mov     [buffer_pos], eax
-
 
Line 846... Line -...
846
 
-
 
847
.prdt_fill:
-
 
848
        cmp     ecx, edx
-
 
849
        jae     .prdt_fill_end
-
 
850
 
891
        jmp     .add_prd
851
        mov     ebx, [buffer_pos]
-
 
852
        and     ebx, 0xFFF
892
 
853
        mov     eax, [buffer_pos]
893
.after_ifs:
854
        call    get_pg_addr ; eax = phys addr 
894
        jmp     .step_next
855
        add     eax, ebx
895
 
Line -... Line 896...
-
 
896
.add_prd:
-
 
897
        mov     ebx, [cur_prd]
856
        DEBUGF  1, "  PHYS = 0x%x\n", eax
898
        shl     ebx, BSF sizeof.HBA_PRDT_ENTRY
857
        mov     ebx, ecx
899
        add     ebx, [cmdtable]
858
        shl     ebx, BSF sizeof.HBA_PRDT_ENTRY
900
        add     ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of 'th prdt_entry
859
        add     ebx, [cmdtable]
-
 
860
        add     ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry
-
 
861
 
901
 
862
        mov     [ebx + HBA_PRDT_ENTRY.dba], eax
902
        DEBUGF  AHCI_DBGLVL, "Added PRDT entry: dba = 0x%x, dbc = %u\n", [phys_region_start], [dbc]
Line -... Line 903...
-
 
903
        mov     eax, [phys_region_start]
-
 
904
        mov     [ebx + HBA_PRDT_ENTRY.dba], eax
863
        mov     [ebx + HBA_PRDT_ENTRY.dbau], 0
905
        mov     [ebx + HBA_PRDT_ENTRY.dbau], 0
-
 
906
        and     [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count
-
 
907
        mov     eax, [dbc]
-
 
908
        or      [ebx + HBA_PRDT_ENTRY.flags], eax
-
 
909
        
864
        and     [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count
910
        inc     [cur_prd]
865
        or      [ebx + HBA_PRDT_ENTRY.flags], 4096 - 1 ; reason why -1 see in spec on this field
911
        mov     eax, [dbc]
-
 
912
        inc     eax
Line -... Line 913...
-
 
913
        add     [prdt_bytes_total], eax
866
        ; or      [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion
914
        mov     eax, [new_phys_region_start]
867
        add     [buffer_pos], 4096
915
        mov     [phys_region_start], eax
868
        sub     [buffer_length], 4096
916
        cmp     [cur_prd], PRDT_MAX_ENTRIES
869
 
917
        jne     @f
-
 
918
        jmp     .fill_prdt_end
870
        inc     ecx
919
@@:
871
        jmp     .prdt_fill
920
        
872
.prdt_fill_end:
921
.step_next:
-
 
922
        mov     eax, [vbuf_len]
873
 
923
        cmp     eax, [cur_antioffset]
-
 
924
        jbe     @f
874
        mov     ebx, [buffer_pos]
925
        mov     eax, [cur_antioffset]
875
        and     ebx, 0xFFF
926
@@:
876
        mov     eax, [buffer_pos]
927
        add     [vbuf], eax
877
        call    get_pg_addr ; eax = phys addr 
928
        sub     [vbuf_len], eax
-
 
929
        jmp     .fill_prdt
878
        add     eax, ebx
930
 
879
        DEBUGF  1, "  PHYS. = 0x%x\n", eax
-
 
880
        DEBUGF  1, "  ecx = 0x%x\n", ecx
931
.fill_prdt_end:
881
        mov     ebx, ecx
932
 
882
        shl     ebx, BSF sizeof.HBA_PRDT_ENTRY
933
        mov     eax, [cmdheader]
883
        add     ebx, [cmdtable]
-
 
884
        add     ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry
-
 
Line 885... Line 934...
885
        mov     [ebx + HBA_PRDT_ENTRY.dba], eax
934
        mov     ebx, [cur_prd]
886
        mov     [ebx + HBA_PRDT_ENTRY.dbau], 0
935
        DEBUGF  AHCI_DBGLVL, " PRDTL = %u\n", ebx
887
        and     [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count
936
        mov     [eax + HBA_CMD_HDR.prdtl], bx
888
        mov     eax, [buffer_length]
937
 
889
        dec     eax
938
        mov     eax, [prdt_bytes_total]
Line 890... Line 939...
890
        DEBUGF  1, " DBC. = %u\n", eax
939
        DEBUGF  AHCI_DBGLVL, " prdt_bytes_total = %u\n", eax
-
 
940
        shr     eax, 9 ; /= 512
-
 
941
        mov     [numsectors], eax
-
 
942
 
891
        or      [ebx + HBA_PRDT_ENTRY.flags], eax ; reason why -1 see in spec on this field
943
        mov     eax, [cmdtable]
892
        ; or      [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion
944
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D
893
 
945
        movzx   ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags]
894
        mov     eax, [cmdtable]
946
        bts     ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS.
895
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D
947
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags], bl
896
        movzx   ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags]
948
 
Line 925... Line 977...
925
        bts     [edi + HBA_PORT.command_issue], eax ; Issue the command
977
        bts     [edi + HBA_PORT.command_issue], eax ; Issue the command
Line 926... Line 978...
926
 
978
 
927
        ; Wait for command completion
979
        ; Wait for command completion
Line 928... Line 980...
928
        stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT
980
        stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT
Line 929... Line 981...
929
 
981
 
Line 930... Line 982...
930
        DEBUGF  1, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error]
982
        DEBUGF  AHCI_DBGLVL, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error]
931
 
983
 
932
        DEBUGF  1, "reading completed\n"
984
        DEBUGF  AHCI_DBGLVL, "reading completed\n"
933
 
985
 
934
;         xor     ecx, ecx
986
;         xor     ecx, ecx
Line 935... Line 987...
935
;         mov     esi, [buffer]
987
;         mov     esi, [vbuf_orig]
Line 945... Line 997...
945
;         inc     ecx
997
;         inc     ecx
946
;         jmp     .print_data
998
;         jmp     .print_data
947
; .end_print_data:
999
; .end_print_data:
948
;         DEBUGF  1, "\n"
1000
;         DEBUGF  1, "\n"
Line -... Line 1001...
-
 
1001
 
-
 
1002
        popad
-
 
1003
        ;mov     eax, [cmdheader]
-
 
1004
        ;mov     eax, [eax + HBA_CMD_HDR.prdbc]
-
 
1005
        mov     eax, [numsectors]
-
 
1006
        shl     eax, 9 ; *= 512
-
 
1007
        ret
949
 
1008
 
-
 
1009
.fail:
-
 
1010
        popad
-
 
1011
        xor     eax, eax
-
 
1012
        ret
-
 
1013
endp
-
 
1014
tmpstr    rb 16
-
 
1015
 
-
 
1016
; Read sectors
-
 
1017
; return value: 0 = success, otherwise = error
-
 
1018
proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
-
 
1019
        locals
-
 
1020
                numsectors dd ?
-
 
1021
        endl
-
 
1022
 
-
 
1023
        pushad
-
 
1024
 
-
 
1025
        mov     ecx, ahci_mutex
-
 
1026
        call    mutex_lock
-
 
1027
 
-
 
1028
        mov     eax, [numsectors_ptr]
-
 
1029
        mov     eax, [eax]
-
 
1030
        mov     [numsectors], eax
-
 
1031
        DEBUGF  AHCI_DBGLVL, "  ahci_read: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u\n", [buffer], [startsector], [startsector + 4], eax
-
 
1032
 
-
 
1033
        xor     ecx, ecx ; how many sectors have been read
-
 
1034
.read_loop:
-
 
1035
        cmp     ecx, [numsectors]
-
 
1036
        jae     .read_loop_end
-
 
1037
 
-
 
1038
        ; mov     eax, [buffer]
-
 
1039
        ; call    get_pg_addr
-
 
1040
        ; DEBUGF  1, "buf phys = 0x%x\n", eax
-
 
1041
        ; mov     eax, [buffer]
-
 
1042
        ; add     eax, 4096
-
 
1043
        ; call    get_pg_addr
-
 
1044
        ; DEBUGF  1, "buf + 4096 phys = 0x%x\n", eax
-
 
1045
 
-
 
1046
        mov     ebx, [numsectors]
-
 
1047
        sub     ebx, ecx
-
 
1048
        ; DEBUGF  1, "buffer = 0x%x\n", [buffer]
-
 
1049
        stdcall ahci_rw_sectors, [pdata], [buffer], dword [startsector], dword [startsector + 4], ebx, 0
-
 
1050
        ;; TODO check if eax == 0 ?
-
 
1051
 
-
 
1052
        DEBUGF  AHCI_DBGLVL, "    EAX = 0x%x\n", eax
-
 
1053
 
-
 
1054
        add     [buffer], eax
-
 
1055
        shr     eax, 9 ; /=  512
-
 
1056
        add     ecx, eax
-
 
1057
        add     dword [startsector], eax
-
 
1058
        adc     dword [startsector + 4], 0
-
 
1059
 
-
 
1060
        jmp     .read_loop
-
 
1061
.read_loop_end:
950
.ret:
1062
 
951
        mov     ecx, ahci_mutex
1063
        mov     ecx, ahci_mutex
Line 952... Line 1064...
952
        call    mutex_unlock
1064
        call    mutex_unlock
953
 
1065
 
954
        popad
1066
        popad
955
        xor     eax, eax
1067
        xor     eax, eax
956
        ret
-
 
Line 957... Line 1068...
957
endp
1068
        ret
958
tmpstr    rb 16
1069
endp
959
 
1070
 
960
; Start command engine
1071
; Start command engine
Line 1000... Line 1111...
1000
        jz      .wait_end
1111
        jz      .wait_end
1001
        inc     ecx
1112
        inc     ecx
1002
        jmp     .wait
1113
        jmp     .wait
1003
.wait_end:
1114
.wait_end:
1004
        xor     eax, eax
1115
        xor     eax, eax
1005
        DEBUGF  1, "port wait counter = %u\n", ecx
1116
        DEBUGF  AHCI_DBGLVL, "port wait counter = %u\n", ecx
1006
        cmp     ecx, [timeout] ; if they equal it means port is hung
1117
        cmp     ecx, [timeout] ; if they equal it means port is hung
1007
        setz    al
1118
        setz    al
1008
        pop     ecx ebx
1119
        pop     ecx ebx
1009
        ret
1120
        ret
1010
endp
1121
endp
Line 1026... Line 1137...
1026
        bt      [ebx + HBA_PORT.interrupt_status], bit_AHCI_HBA_PxIS_TFES ; check for Task File Error
1137
        bt      [ebx + HBA_PORT.interrupt_status], bit_AHCI_HBA_PxIS_TFES ; check for Task File Error
1027
        jc      .error
1138
        jc      .error
1028
        inc     ecx
1139
        inc     ecx
1029
        jmp     .wait
1140
        jmp     .wait
1030
.wait_end:
1141
.wait_end:
1031
        DEBUGF  1, "port cmd wait counter = %u\n", ecx
1142
        DEBUGF  AHCI_DBGLVL, "port cmd wait counter = %u\n", ecx
1032
        bt      [ebx + HBA_PORT.interrupt_status], bit_AHCI_HBA_PxIS_TFES ; check for Task File Error
1143
        bt      [ebx + HBA_PORT.interrupt_status], bit_AHCI_HBA_PxIS_TFES ; check for Task File Error
1033
        jc      .error
1144
        jc      .error
1034
        jmp     .ret
1145
        jmp     .ret
1035
.error:
1146
.error:
1036
        mov     eax, 1
1147
        mov     eax, 1
Line 1116... Line 1227...
1116
        mov     eax, [virt_page1]
1227
        mov     eax, [virt_page1]
1117
        add     eax, 1024
1228
        add     eax, 1024
1118
        mov     [edi + PORT_DATA.fb], eax ; set pdata->fb 
1229
        mov     [edi + PORT_DATA.fb], eax ; set pdata->fb 
1119
        stdcall _memset, eax, 0, 256 ; zero out
1230
        stdcall _memset, eax, 0, 256 ; zero out
Line 1120... Line 1231...
1120
        
1231
        
1121
        stdcall alloc_pages, 2
1232
        stdcall alloc_pages, 32*(64 + 16 + 48 + PRDT_MAX_ENTRIES*16)/4096
1122
        mov     [phys_page23], eax
1233
        mov     [phys_page23], eax
1123
        stdcall map_io_mem, eax, 2*4096, PG_NOCACHE + PG_SWR
1234
        stdcall map_io_mem, eax, 32*(64 + 16 + 48 + PRDT_MAX_ENTRIES*16), PG_NOCACHE + PG_SWR
Line 1124... Line 1235...
1124
        mov     [virt_page23], eax
1235
        mov     [virt_page23], eax
1125
 
1236
 
1126
        ; Command table size = 256*32 = 8K per port
1237
        ; Command table size = N*32 per port
Line 1127... Line 1238...
1127
        mov     edx, [edi + PORT_DATA.clb] ; cmdheader array base
1238
        mov     edx, [edi + PORT_DATA.clb] ; cmdheader array base
1128
        xor     ecx, ecx
1239
        xor     ecx, ecx
Line 1133... Line 1244...
1133
 
1244
 
1134
        mov     ebx, ecx
1245
        mov     ebx, ecx
1135
        shl     ebx, BSF sizeof.HBA_CMD_HDR
1246
        shl     ebx, BSF sizeof.HBA_CMD_HDR
Line 1136... Line 1247...
1136
        add     ebx, edx ; ebx = cmdheader[ecx]
1247
        add     ebx, edx ; ebx = cmdheader[ecx]
Line 1137... Line 1248...
1137
 
1248
 
Line 1138... Line 1249...
1138
        mov     [ebx + HBA_CMD_HDR.prdtl], 8 ; 8 prdt entries per command table
1249
        mov     [ebx + HBA_CMD_HDR.prdtl], PRDT_MAX_ENTRIES ; prdt entries per command table
Line 1139... Line 1250...
1139
 
1250
 
1140
        ; 256 bytes per command table, 64+16+48+16*8
1251
        ; bytes per command table = 64+16+48+PRDT_MAX_ENTRIES*16 = N
-
 
1252
 
-
 
1253
        push    edx
1141
 
1254
        
1142
        push    edx
1255
        ; cmdheader[ecx].ctba = phys_page23 + ecx*N
1143
        
1256
        mov     [ebx + HBA_CMD_HDR.ctba], ecx
1144
        ; cmdheader[ecx].ctba = phys_page23 + ecx*256
1257
        mov     edx, [ebx + HBA_CMD_HDR.ctba]
Line 1145... Line 1258...
1145
        mov     [ebx + HBA_CMD_HDR.ctba], ecx
1258
        imul    edx, (64+16+48+PRDT_MAX_ENTRIES*16) ; *= N
1146
        shl     [ebx + HBA_CMD_HDR.ctba], BSF 256 ; *= 256
1259
        mov     [ebx + HBA_CMD_HDR.ctba], edx
1147
        mov     eax, [ebx + HBA_CMD_HDR.ctba]
1260
        mov     eax, [ebx + HBA_CMD_HDR.ctba]
1148
        mov     edx, [phys_page23]
1261
        mov     edx, [phys_page23]
1149
        add     [ebx + HBA_CMD_HDR.ctba], edx
1262
        add     [ebx + HBA_CMD_HDR.ctba], edx
Line 1150... Line 1263...
1150
 
1263
 
Line 1151... Line 1264...
1151
        add     eax, [virt_page23]
1264
        add     eax, [virt_page23]
1152
        mov     [tmp], eax  ; tmp = virt_page23 + ecx*256
1265
        mov     [tmp], eax  ; tmp = virt_page23 + ecx*N
Line 1153... Line 1266...
1153
        lea     eax, [ecx*4 + edi + PORT_DATA.ctba_arr] ; eax = pdata->ctba_arr[ecx]
1266
        lea     eax, [ecx*4 + edi + PORT_DATA.ctba_arr] ; eax = pdata->ctba_arr[ecx]
1154
        mov     edx, [tmp]
1267
        mov     edx, [tmp]
1155
        mov     [eax], edx  ; pdata->ctba_arr[ecx] = virt_page23 + ecx*256
1268
        mov     [eax], edx  ; pdata->ctba_arr[ecx] = virt_page23 + ecx*N