Rev 9272 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9272 | Rev 9417 | ||
---|---|---|---|
Line 343... | Line 343... | ||
343 | dd ahci_read |
343 | dd ahci_read |
344 | dd ahci_write |
344 | dd ahci_write |
345 | dd 0 ; no flush function |
345 | dd 0 ; no flush function |
346 | dd 0 ; use default cache size |
346 | dd 0 ; use default cache size |
347 | .end: |
347 | .end: |
348 | hd_name db 'sd', 0, 0, 0 |
348 | sata_dev_name db 'sd', 0, 0, 0 |
- | 349 | satapi_dev_name db 'scd', 0, 0, 0 |
|
349 | sata_dev_counter dd 0 ; sata devices counter |
350 | sata_dev_counter dd 0 ; sata devices counter |
350 | ; TODO: satapi_dev_counter dd 0 ; satapi devices (optical drives) counter |
351 | satapi_dev_counter dd 0 ; satapi devices (optical drives) counter |
351 | ctr_counter dd 0 ; controllers counter |
352 | ctr_counter dd 0 ; controllers counter |
- | 353 | disk_to_add_name dd 0 ; local var for ahci_init |
|
352 | endg |
354 | endg |
Line 353... | Line 355... | ||
353 | 355 | ||
354 | ; ----------------------------------------------------------------------- |
356 | ; ----------------------------------------------------------------------- |
355 | ; detect ahci controller and initialize |
357 | ; detect ahci controller and initialize |
Line 359... | Line 361... | ||
359 | mov [ctr_ptr], ctr1_data |
361 | mov [ctr_ptr], ctr1_data |
360 | mov [sata_dev_counter], 0 |
362 | mov [sata_dev_counter], 0 |
361 | .find_ahci_ctr: |
363 | .find_ahci_ctr: |
362 | mov esi, [esi + PCIDEV.fd] |
364 | mov esi, [esi + PCIDEV.fd] |
363 | cmp esi, pcidev_list |
365 | cmp esi, pcidev_list |
364 | jz .ahci_ctr_not_found |
366 | jz .end_find_ahci_ctr |
365 | mov eax, [esi + PCIDEV.class] |
367 | mov eax, [esi + PCIDEV.class] |
366 | ;DEBUGF 1, "K: device class = %x\n", eax |
368 | ;DEBUGF 1, "K: device class = %x\n", eax |
367 | shr eax, 8 ; shift right because lowest 8 bits if ProgIf field |
369 | shr eax, 8 ; shift right because lowest 8 bits if ProgIf field |
368 | cmp eax, 0x0106 ; 0x01 - Mass Storage Controller class, 0x06 - Serial ATA Controller subclass |
370 | cmp eax, 0x0106 ; 0x01 - Mass Storage Controller class, 0x06 - Serial ATA Controller subclass |
369 | jz .ahci_ctr_found |
371 | jz .ahci_ctr_found |
370 | jmp .find_ahci_ctr |
372 | jmp .find_ahci_ctr |
Line 371... | Line 373... | ||
371 | 373 | ||
- | 374 | .end_find_ahci_ctr: |
|
- | 375 | cmp [ctr_counter], 0 |
|
372 | .ahci_ctr_not_found: |
376 | ja @f |
- | 377 | DEBUGF 1, "K: AHCI: controllers not found\n" |
|
373 | DEBUGF 1, "K: AHCI controller not found\n" |
378 | @@: |
Line 374... | Line 379... | ||
374 | ret |
379 | ret |
375 | 380 | ||
Line 590... | Line 595... | ||
590 | 595 | ||
Line 591... | Line 596... | ||
591 | DEBUGF 1, "K: AHCI: found drive on port %u: TYPE = %u\n", ebx, [ecx + PORT_DATA.drive_type] |
596 | DEBUGF 1, "K: AHCI: found drive on port %u: TYPE = %u\n", ebx, [ecx + PORT_DATA.drive_type] |
Line -... | Line 597... | ||
- | 597 | ||
592 | 598 | stdcall ahci_port_identify, ecx |
|
593 | stdcall ahci_port_identify, ecx |
599 | |
- | 600 | ; register drive as disk in system if it is SATA or SATAPI: |
|
594 | 601 | cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATA |
|
595 | cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATA |
- | |
596 | jne .after_add_disk ; skip adding disk code |
602 | je .disk_add_sata |
Line -... | Line 603... | ||
- | 603 | cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATAPI |
|
597 | ; register disk in system: |
604 | je .disk_add_satapi |
598 | 605 | jne .after_add_disk ; else skip adding disk code |
|
599 | ;stdcall ahci_read_first_sector, ecx |
606 | |
600 | 607 | .disk_add_sata: |
|
601 | push ecx |
608 | push ecx |
602 | mov eax, [sata_dev_counter] |
609 | mov eax, [sata_dev_counter] |
603 | inc [sata_dev_counter] |
610 | inc [sata_dev_counter] |
604 | xor edx, edx |
611 | xor edx, edx |
605 | mov ecx, 10 |
612 | mov ecx, 10 |
606 | div ecx ; eax = sata_dev_counter / 10, edx = sata_dev_counter % 10 |
613 | div ecx ; eax = sata_dev_counter / 10, edx = sata_dev_counter % 10 |
607 | test eax, eax |
614 | test eax, eax |
608 | jz .concat_one |
615 | jz .concat_one_digit |
609 | add al, '0' |
616 | add al, '0' |
610 | mov byte [hd_name + 2], al |
617 | mov byte [sata_dev_name + 2], al |
611 | add dl, '0' |
618 | add dl, '0' |
612 | mov byte [hd_name + 3], dl |
619 | mov byte [sata_dev_name + 3], dl |
613 | jmp .endif1 |
620 | jmp .endif1 |
- | 621 | .concat_one_digit: |
|
- | 622 | add dl, '0' |
|
- | 623 | mov byte [sata_dev_name + 2], dl |
|
- | 624 | .endif1: |
|
- | 625 | mov [disk_to_add_name], sata_dev_name |
|
- | 626 | pop ecx |
|
- | 627 | jmp .disk_add |
|
- | 628 | ||
- | 629 | .disk_add_satapi: |
|
- | 630 | push ecx |
|
- | 631 | mov eax, [satapi_dev_counter] |
|
- | 632 | inc [satapi_dev_counter] |
|
- | 633 | xor edx, edx |
|
- | 634 | mov ecx, 10 |
|
- | 635 | div ecx ; eax = satapi_dev_counter / 10, edx = satapi_dev_counter % 10 |
|
- | 636 | test eax, eax |
|
- | 637 | jz .concat_one_digit2 |
|
- | 638 | add al, '0' |
|
- | 639 | mov byte [satapi_dev_name + 3], al |
|
- | 640 | add dl, '0' |
|
- | 641 | mov byte [satapi_dev_name + 4], dl |
|
- | 642 | jmp .endif2 |
|
- | 643 | .concat_one_digit2: |
|
614 | .concat_one: |
644 | add dl, '0' |
Line -... | Line 645... | ||
- | 645 | mov byte [satapi_dev_name + 3], dl |
|
615 | add dl, '0' |
646 | .endif2: |
Line 616... | Line 647... | ||
616 | mov byte [hd_name + 2], dl |
647 | mov [disk_to_add_name], satapi_dev_name |
617 | .endif1: |
648 | pop ecx |
618 | pop ecx |
649 | |
619 | 650 | .disk_add: |
|
620 | DEBUGF 1, "adding '%s'\n", hd_name |
651 | DEBUGF 1, "adding '%s'\n", [disk_to_add_name] |
621 | 652 | ||
622 | push ecx |
653 | push ecx |
Line 636... | Line 667... | ||
636 | 667 | ||
637 | .continue_detect_drives: |
668 | .continue_detect_drives: |
638 | inc ebx |
669 | inc ebx |
Line 639... | Line -... | ||
639 | jmp .detect_drives |
- | |
640 | - | ||
641 | 670 | jmp .detect_drives |
|
642 | 671 | ||
643 | .end_detect_drives: |
672 | .end_detect_drives: |
644 | pop esi |
673 | pop esi |
645 | add [ctr_ptr], sizeof.AHCI_CTR |
674 | add [ctr_ptr], sizeof.AHCI_CTR |
Line 715... | Line 744... | ||
715 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D |
744 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D |
716 | movzx ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags] |
745 | movzx ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags] |
717 | bts ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS. |
746 | bts ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS. |
718 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags], bl |
747 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags], bl |
Line -... | Line 748... | ||
- | 748 | ||
719 | 749 | ; Choose identify command depending on drive type |
|
720 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATA_IDENTIFY |
750 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATA_IDENTIFY |
721 | cmp [esi + PORT_DATA.drive_type], AHCI_DEV_SATAPI |
751 | cmp [esi + PORT_DATA.drive_type], AHCI_DEV_SATAPI |
722 | jne @f |
752 | jne @f |
723 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATAPI_IDENTIFY |
753 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATAPI_IDENTIFY |
Line 738... | Line 768... | ||
738 | stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT |
768 | stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT |
739 | ; DEBUGF 1, " eax = %x\n", eax |
769 | ; DEBUGF 1, " eax = %x\n", eax |
740 | ; TODO check eax error value |
770 | ; TODO check eax error value |
Line 741... | Line 771... | ||
741 | 771 | ||
742 | ; DEBUGF 1, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error] |
- | |
743 | 772 | ; DEBUGF 1, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error] |
|
744 | mov esi, [buf_virt] |
773 | mov esi, [buf_virt] |
745 | add esi, 27*2 |
774 | add esi, 27*2 |
746 | mov edi, modelstr |
775 | mov edi, modelstr |
747 | mov ecx, ((46-27)+1)*2 |
776 | mov ecx, ((46-27)+1)*2 |
Line 750... | Line 779... | ||
750 | mov byte [edi], 0 |
779 | mov byte [edi], 0 |
Line 751... | Line 780... | ||
751 | 780 | ||
752 | stdcall swap_bytes_in_words, modelstr, (46-27)+1 |
781 | stdcall swap_bytes_in_words, modelstr, (46-27)+1 |
Line -... | Line 782... | ||
- | 782 | DEBUGF 1, "IDENTIFICATION RESULT: MODEL = %s\n", modelstr |
|
- | 783 | ||
- | 784 | mov esi, [pdata] |
|
- | 785 | cmp [esi + PORT_DATA.drive_type], AHCI_DEV_SATAPI |
|
- | 786 | je .satapi_get_capacity |
|
753 | DEBUGF 1, "IDENTIFICATION RESULT: MODEL = %s\n", modelstr |
787 | |
754 | 788 | .sata_get_capacity: |
|
755 | mov esi, [buf_virt] |
789 | mov esi, [buf_virt] |
756 | mov eax, [esi + 200] |
790 | mov eax, [esi + 200] |
Line 763... | Line 797... | ||
763 | 797 | ||
764 | shrd eax, edx, 11 ; i.e *512 / 1024 / 1024, 512 - sector size |
798 | shrd eax, edx, 11 ; i.e *512 / 1024 / 1024, 512 - sector size |
765 | DEBUGF 1, "disk capacity = %u MiB ", eax |
799 | DEBUGF 1, "disk capacity = %u MiB ", eax |
766 | shrd eax, edx, 10 ; / 1024 |
800 | shrd eax, edx, 10 ; / 1024 |
- | 801 | DEBUGF 1, "= %u GiB\n", eax |
|
- | 802 | jmp .end_get_capacity |
|
- | 803 | ||
- | 804 | .satapi_get_capacity: |
|
- | 805 | mov eax, [cmdtable] |
|
- | 806 | mov ebx, [buf_phys] |
|
- | 807 | mov dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dba], ebx |
|
- | 808 | mov dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dbau], 0 |
|
- | 809 | and [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count |
|
- | 810 | or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 2048 - 1 ; reason why -1 see in spec on this field |
|
- | 811 | ; or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion |
|
- | 812 | ||
- | 813 | mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], 0xA0 ; TODO: move to ATA_PACKET const |
|
- | 814 | mov byte [eax + HBA_CMD_TBL.acmd], 0x25 ; means: cmd_table->acmd[0] = ATAPI_READ_CAPACITY >> 8; TODO use consts. |
|
- | 815 | ||
- | 816 | mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port |
|
- | 817 | ; Wait on previous command to complete, before issuing new command. |
|
- | 818 | stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT |
|
- | 819 | ; DEBUGF 1, "eax = %x\n", eax |
|
- | 820 | ; TODO check eax error value |
|
- | 821 | mov eax, [cmdslot] |
|
- | 822 | bts [edi + HBA_PORT.command_issue], eax ; Issue the command |
|
- | 823 | ; Wait for command completion |
|
- | 824 | stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT |
|
- | 825 | ||
- | 826 | ; DEBUGF 1, ". sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error] |
|
- | 827 | ||
- | 828 | mov esi, [buf_virt] |
|
- | 829 | mov eax, [esi] |
|
- | 830 | mov edx, [esi + 4] |
|
- | 831 | DEBUGF 1, "ATAPI sector count = 0x%x:%x\n", edx, eax |
|
- | 832 | ||
- | 833 | mov ebx, [pdata] |
|
- | 834 | mov dword [ebx + PORT_DATA.sector_count], eax |
|
- | 835 | mov dword [ebx + PORT_DATA.sector_count + 4], edx |
|
- | 836 | ||
- | 837 | shrd eax, edx, 9 ; i.e *2048 / 1024 / 1024, 2048 - sector size |
|
- | 838 | DEBUGF 1, "ATAPI disk capacity = %u MiB ", eax |
|
- | 839 | shrd eax, edx, 10 ; / 1024 |
|
- | 840 | DEBUGF 1, "= %u GiB\n", eax |
|
- | 841 | ||
- | 842 | ; aboba |
|
- | 843 | .end_get_capacity: |
|
767 | DEBUGF 1, "= %u GiB\n", eax |
844 | |
768 | .ret: |
845 | .ret: |
769 | popad |
846 | popad |
770 | ret |
847 | ret |
Line 771... | Line 848... | ||
771 | endp |
848 | endp |
772 | 849 | ||
773 | proc ahci_querymedia stdcall, pdata, mediainfo |
850 | proc ahci_querymedia stdcall, pdata, mediainfo |
774 | push ecx edx |
851 | push ecx edx |
775 | mov eax, [mediainfo] |
852 | mov eax, [mediainfo] |
776 | mov edx, [pdata] |
853 | mov edx, [pdata] |
- | 854 | mov [eax + DISKMEDIAINFO.Flags], 0 |
|
- | 855 | mov [eax + DISKMEDIAINFO.SectorSize], 512 ; TODO: use const |
|
- | 856 | cmp [edx + PORT_DATA.drive_type], AHCI_DEV_SATAPI |
|
- | 857 | jne @f |
|
777 | mov [eax + DISKMEDIAINFO.Flags], 0 |
858 | mov [eax + DISKMEDIAINFO.SectorSize], 2048 ; TODO: use const |
778 | mov [eax + DISKMEDIAINFO.SectorSize], 512 |
859 | @@: |
779 | mov ecx, dword[edx + PORT_DATA.sector_count] |
860 | mov ecx, dword[edx + PORT_DATA.sector_count] |
780 | mov dword [eax + DISKMEDIAINFO.Capacity], ecx |
861 | mov dword [eax + DISKMEDIAINFO.Capacity], ecx |
781 | mov ecx, dword[edx + PORT_DATA.sector_count + 4] |
862 | mov ecx, dword[edx + PORT_DATA.sector_count + 4] |