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 |