Rev 9142 | Rev 9145 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9142 | Rev 9143 | ||
---|---|---|---|
Line 320... | Line 320... | ||
320 | ahci_callbacks: |
320 | ahci_callbacks: |
321 | dd ahci_callbacks.end - ahci_callbacks |
321 | dd ahci_callbacks.end - ahci_callbacks |
322 | dd 0 ; no close function |
322 | dd 0 ; no close function |
323 | dd 0 ; no closemedia function |
323 | dd 0 ; no closemedia function |
324 | dd ahci_querymedia |
324 | dd ahci_querymedia |
325 | dd 0;ahci_read |
325 | dd ahci_read |
326 | dd 0;ahci_write |
326 | dd 0;ahci_write |
327 | dd 0 ; no flush function |
327 | dd 0 ; no flush function |
328 | dd 0 ; use default cache size |
328 | dd 0 ; use default cache size |
329 | .end: |
329 | .end: |
330 | hd_name db 'hd', 0, 0, 0 |
330 | hd_name db 'hd', 0, 0, 0 |
Line 562... | Line 562... | ||
562 | stdcall ahci_port_identify, ecx |
562 | stdcall ahci_port_identify, ecx |
Line 563... | Line 563... | ||
563 | 563 | ||
564 | cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATA |
564 | cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATA |
565 | jne .after_add_disk ; skip adding disk code |
565 | jne .after_add_disk ; skip adding disk code |
- | 566 | ; register disk in system: |
|
566 | ; register disk in system: |
567 | |
Line 567... | Line 568... | ||
567 | stdcall ahci_read_first_sector, ecx |
568 | ;stdcall ahci_read_first_sector, ecx |
568 | 569 | ||
569 | push ecx |
570 | push ecx |
570 | mov eax, [hd_counter] |
571 | mov eax, [hd_counter] |
Line 881... | Line 882... | ||
881 | ret |
882 | ret |
882 | endp |
883 | endp |
883 | tmpstr2 rb 16 |
884 | tmpstr2 rb 16 |
884 | ;---------------------------------------------------------- |
885 | ;---------------------------------------------------------- |
Line -... | Line 886... | ||
- | 886 | ||
- | 887 | ||
- | 888 | ; Read sectors |
|
- | 889 | ; return value: 0 = success, otherwise = error |
|
- | 890 | proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword |
|
- | 891 | locals |
|
- | 892 | cmdslot dd ? |
|
- | 893 | cmdheader dd ? |
|
- | 894 | cmdtable dd ? |
|
- | 895 | numsectors dd ? |
|
- | 896 | buffer_pos dd ? |
|
- | 897 | buffer_length dd ? |
|
- | 898 | endl |
|
- | 899 | ||
- | 900 | pushad |
|
- | 901 | ||
- | 902 | mov ecx, ahci_mutex |
|
- | 903 | call mutex_lock |
|
- | 904 | ||
- | 905 | ; xor ecx, ecx |
|
- | 906 | ; mov esi, [buffer] |
|
- | 907 | ; .print_data: |
|
- | 908 | ; cmp ecx, 512 |
|
- | 909 | ; jae .end_print_data |
|
- | 910 | ||
- | 911 | ; mov al, byte [esi + ecx] |
|
- | 912 | ; mov byte [tmpstr], al |
|
- | 913 | ; mov byte [tmpstr + 1], 0 |
|
- | 914 | ; DEBUGF 1, "0x%x(%s) ", al:2, tmpstr |
|
- | 915 | ||
- | 916 | ; inc ecx |
|
- | 917 | ; jmp .print_data |
|
- | 918 | ; .end_print_data: |
|
- | 919 | ; DEBUGF 1, "\n" |
|
- | 920 | ||
- | 921 | mov eax, [numsectors_ptr] |
|
- | 922 | mov eax, [eax] |
|
- | 923 | mov [numsectors], eax |
|
- | 924 | ||
- | 925 | DEBUGF 1, " ahci_read: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u\n", [buffer], [startsector], [startsector + 4], eax |
|
- | 926 | ||
- | 927 | mov esi, [pdata] ; esi - address of PORT_DATA struct of port |
|
- | 928 | mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port |
|
- | 929 | mov eax, edi |
|
- | 930 | call ahci_find_cmdslot |
|
- | 931 | cmp eax, -1 |
|
- | 932 | jne .cmdslot_found |
|
- | 933 | ||
- | 934 | DEBUGF 1, "No free cmdslot on port %u\n", [esi + PORT_DATA.portno] |
|
- | 935 | jmp .ret |
|
- | 936 | ||
- | 937 | .cmdslot_found: |
|
- | 938 | mov [cmdslot], eax |
|
- | 939 | DEBUGF 1, "Found free cmdslot %u on port %u\n", [cmdslot], [esi + PORT_DATA.portno] |
|
- | 940 | ||
- | 941 | shl eax, BSF sizeof.HBA_CMD_HDR |
|
- | 942 | add eax, [esi + PORT_DATA.clb] |
|
- | 943 | mov [cmdheader], eax ; address of virtual mapping of command header |
|
- | 944 | mov eax, [cmdslot] |
|
- | 945 | mov eax, [esi + eax*4 + PORT_DATA.ctba_arr] |
|
- | 946 | mov [cmdtable], eax ; address of virtual mapping of command table of command header |
|
- | 947 | ||
- | 948 | mov eax, [cmdheader] |
|
- | 949 | and [eax + HBA_CMD_HDR.flags1], not 0x1F ; zero out lower 5 bits, they will be used for cfl |
|
- | 950 | or [eax + HBA_CMD_HDR.flags1], (sizeof.FIS_REG_H2D / 4) ; set command fis length in dwords |
|
- | 951 | movzx bx, [eax + HBA_CMD_HDR.flags1] |
|
- | 952 | btr bx, 6 ; flag W = 0 |
|
- | 953 | mov [eax + HBA_CMD_HDR.flags1], bl |
|
- | 954 | movzx bx, [eax + HBA_CMD_HDR.flags2] |
|
- | 955 | btr bx, 2 ; flag C = 0 |
|
- | 956 | mov [eax + HBA_CMD_HDR.flags2], bl |
|
- | 957 | ||
- | 958 | mov ebx, [numsectors] |
|
- | 959 | shl ebx, 9 ; *= 512 |
|
- | 960 | mov [buffer_length], ebx |
|
- | 961 | dec ebx |
|
- | 962 | shr ebx, 12 ; /= 4096 |
|
- | 963 | inc ebx |
|
- | 964 | mov [eax + HBA_CMD_HDR.prdtl], bx |
|
- | 965 | ;DEBUGF 1, " prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2 |
|
- | 966 | ||
- | 967 | ; zero out the command table with its prdt entries |
|
- | 968 | dec ebx |
|
- | 969 | shl ebx, BSF sizeof.HBA_PRDT_ENTRY |
|
- | 970 | add ebx, sizeof.HBA_CMD_TBL |
|
- | 971 | stdcall _memset, [cmdtable], 0, ebx |
|
- | 972 | ||
- | 973 | DEBUGF 1, " prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2 |
|
- | 974 | ;jmp .ret |
|
- | 975 | ||
- | 976 | xor ecx, ecx |
|
- | 977 | movzx edx, [eax + HBA_CMD_HDR.prdtl] |
|
- | 978 | dec edx |
|
- | 979 | mov eax, [buffer] |
|
- | 980 | mov [buffer_pos], eax |
|
- | 981 | ||
- | 982 | .prdt_fill: |
|
- | 983 | cmp ecx, edx |
|
- | 984 | jae .prdt_fill_end |
|
- | 985 | ||
- | 986 | mov ebx, [buffer_pos] |
|
- | 987 | and ebx, 0xFFF |
|
- | 988 | call get_pg_addr ; eax = phys addr |
|
- | 989 | add eax, ebx |
|
- | 990 | DEBUGF 1, " PHYS = 0x%x\n", eax |
|
- | 991 | mov ebx, ecx |
|
- | 992 | shl ebx, BSF sizeof.HBA_PRDT_ENTRY |
|
- | 993 | add ebx, [cmdtable] |
|
- | 994 | add ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry |
|
- | 995 | ||
- | 996 | mov [ebx + HBA_PRDT_ENTRY.dba], eax |
|
- | 997 | mov [ebx + HBA_PRDT_ENTRY.dbau], 0 |
|
- | 998 | and [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count |
|
- | 999 | or [ebx + HBA_PRDT_ENTRY.flags], 4096 - 1 ; reason why -1 see in spec on this field |
|
- | 1000 | ; or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion |
|
- | 1001 | add [buffer_pos], 4096 |
|
- | 1002 | sub [buffer_length], 4096 |
|
- | 1003 | ||
- | 1004 | inc ecx |
|
- | 1005 | jmp .prdt_fill |
|
- | 1006 | .prdt_fill_end: |
|
- | 1007 | ||
- | 1008 | mov ebx, [buffer_pos] |
|
- | 1009 | and ebx, 0xFFF |
|
- | 1010 | call get_pg_addr ; eax = phys addr |
|
- | 1011 | add eax, ebx |
|
- | 1012 | DEBUGF 1, " PHYS. = 0x%x\n", eax |
|
- | 1013 | DEBUGF 1, " ecx = 0x%x\n", ecx |
|
- | 1014 | mov ebx, ecx |
|
- | 1015 | shl ebx, BSF sizeof.HBA_PRDT_ENTRY |
|
- | 1016 | add ebx, [cmdtable] |
|
- | 1017 | add ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry |
|
- | 1018 | mov [ebx + HBA_PRDT_ENTRY.dba], eax |
|
- | 1019 | mov [ebx + HBA_PRDT_ENTRY.dbau], 0 |
|
- | 1020 | and [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count |
|
- | 1021 | mov eax, [buffer_length] |
|
- | 1022 | dec eax |
|
- | 1023 | DEBUGF 1, " DBC. = %u\n", eax |
|
- | 1024 | or [ebx + HBA_PRDT_ENTRY.flags], eax ; reason why -1 see in spec on this field |
|
- | 1025 | ; or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion |
|
- | 1026 | ||
- | 1027 | mov eax, [cmdtable] |
|
- | 1028 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D |
|
- | 1029 | movzx ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags] |
|
- | 1030 | bts ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS. |
|
- | 1031 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags], bl |
|
- | 1032 | ||
- | 1033 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATA_CMD_READ_DMA_EX |
|
- | 1034 | ||
- | 1035 | mov ebx, dword [startsector] |
|
- | 1036 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba0], bl |
|
- | 1037 | shr ebx, 8 |
|
- | 1038 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba1], bl |
|
- | 1039 | shr ebx, 8 |
|
- | 1040 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba2], bl |
|
- | 1041 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 1 shl 6 ; LBA mode |
|
- | 1042 | shr ebx, 8 |
|
- | 1043 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba3], bl |
|
- | 1044 | mov ebx, dword [startsector + 4] |
|
- | 1045 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba4], bl |
|
- | 1046 | shr ebx, 8 |
|
- | 1047 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba5], bl |
|
- | 1048 | ||
- | 1049 | mov ebx, [numsectors] |
|
- | 1050 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.countl], bl |
|
- | 1051 | shr ebx, 8 |
|
- | 1052 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl |
|
- | 1053 | ||
- | 1054 | ; Wait on previous command to complete, before issuing new command. |
|
- | 1055 | stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT |
|
- | 1056 | ||
- | 1057 | mov eax, [cmdslot] |
|
- | 1058 | bts [edi + HBA_PORT.command_issue], eax ; Issue the command |
|
- | 1059 | ||
- | 1060 | ; Wait for command completion |
|
- | 1061 | stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT |
|
- | 1062 | ||
- | 1063 | DEBUGF 1, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error] |
|
- | 1064 | ||
- | 1065 | DEBUGF 1, "reading completed\n" |
|
- | 1066 | ||
- | 1067 | xor ecx, ecx |
|
- | 1068 | mov esi, [buffer] |
|
- | 1069 | .print_data: |
|
- | 1070 | cmp ecx, 512 |
|
- | 1071 | jae .end_print_data |
|
- | 1072 | ||
- | 1073 | mov al, byte [esi + ecx] |
|
- | 1074 | mov byte [tmpstr], al |
|
- | 1075 | mov byte [tmpstr + 1], 0 |
|
- | 1076 | DEBUGF 1, "0x%x(%s) ", al:2, tmpstr |
|
- | 1077 | ||
- | 1078 | inc ecx |
|
- | 1079 | jmp .print_data |
|
- | 1080 | .end_print_data: |
|
- | 1081 | DEBUGF 1, "\n" |
|
- | 1082 | ||
- | 1083 | .ret: |
|
- | 1084 | mov ecx, ahci_mutex |
|
- | 1085 | call mutex_unlock |
|
- | 1086 | ||
- | 1087 | popad |
|
- | 1088 | xor eax, eax |
|
- | 1089 | ret |
|
- | 1090 | endp |
|
- | 1091 | tmpstr rb 16 |
|
885 | 1092 | ||
886 | ; Start command engine |
1093 | ; Start command engine |
887 | ; in: eax - address of HBA_PORT structure |
1094 | ; in: eax - address of HBA_PORT structure |
888 | ahci_start_cmd: |
1095 | ahci_start_cmd: |
889 | .wait_cr: ; Wait until CR (bit15) is cleared |
1096 | .wait_cr: ; Wait until CR (bit15) is cleared |