Changeset 82182 in vbox for trunk/src/VBox/Devices/PC/BIOS/virtio.c
- Timestamp:
- Nov 25, 2019 3:09:28 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/virtio.c
r82180 r82182 760 760 761 761 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 6, buffer, 5, 0, 0); 762 if (rc != 0) 763 BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__); 764 765 devcount_scsi = bios_dsk->scsi_devcount; 766 767 /* Check the attached device. */ 768 if ( ((buffer[0] & 0xe0) == 0) 769 && ((buffer[0] & 0x1f) == 0x00)) 762 if (!rc) 770 763 { 771 DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i); 772 773 /* We add the disk only if the maximum is not reached yet. */ 774 if (devcount_scsi < BX_MAX_SCSI_DEVICES) 764 devcount_scsi = bios_dsk->scsi_devcount; 765 766 /* Check the attached device. */ 767 if ( ((buffer[0] & 0xe0) == 0) 768 && ((buffer[0] & 0x1f) == 0x00)) 775 769 { 776 uint64_t sectors, t; 777 uint32_t sector_size, cylinders; 778 uint16_t heads, sectors_per_track; 779 uint8_t hdcount; 780 uint8_t cmos_base; 781 782 /* Issue a read capacity command now. */ 783 _fmemset(aCDB, 0, sizeof(aCDB)); 784 aCDB[0] = SCSI_SERVICE_ACT; 785 aCDB[1] = SCSI_READ_CAP_16; 786 aCDB[13] = 32; /* Allocation length. */ 787 788 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32, 0, 0); 789 if (rc != 0) 790 BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__); 791 792 /* The value returned is the last addressable LBA, not 793 * the size, which what "+ 1" is for. 794 */ 795 sectors = swap_64(*(uint64_t *)buffer) + 1; 796 797 sector_size = ((uint32_t)buffer[8] << 24) 798 | ((uint32_t)buffer[9] << 16) 799 | ((uint32_t)buffer[10] << 8) 800 | ((uint32_t)buffer[11]); 801 802 /* We only support the disk if sector size is 512 bytes. */ 803 if (sector_size != 512) 770 DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i); 771 772 /* We add the disk only if the maximum is not reached yet. */ 773 if (devcount_scsi < BX_MAX_SCSI_DEVICES) 804 774 { 805 /* Leave a log entry. */ 806 BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size); 807 continue; 808 } 809 810 /* Get logical CHS geometry. */ 811 switch (devcount_scsi) 812 { 813 case 0: 814 cmos_base = 0x90; 815 break; 816 case 1: 817 cmos_base = 0x98; 818 break; 819 case 2: 820 cmos_base = 0xA0; 821 break; 822 case 3: 823 cmos_base = 0xA8; 824 break; 825 default: 826 cmos_base = 0; 827 } 828 829 if (cmos_base && inb_cmos(cmos_base + 7)) 830 { 831 /* If provided, grab the logical geometry from CMOS. */ 832 cylinders = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8); 833 heads = inb_cmos(cmos_base + 2); 834 sectors_per_track = inb_cmos(cmos_base + 7); 775 uint64_t sectors, t; 776 uint32_t sector_size, cylinders; 777 uint16_t heads, sectors_per_track; 778 uint8_t hdcount; 779 uint8_t cmos_base; 780 781 /* Issue a read capacity command now. */ 782 _fmemset(aCDB, 0, sizeof(aCDB)); 783 aCDB[0] = SCSI_SERVICE_ACT; 784 aCDB[1] = SCSI_READ_CAP_16; 785 aCDB[13] = 32; /* Allocation length. */ 786 787 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32, 0, 0); 788 if (rc != 0) 789 BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__); 790 791 /* The value returned is the last addressable LBA, not 792 * the size, which what "+ 1" is for. 793 */ 794 sectors = swap_64(*(uint64_t *)buffer) + 1; 795 796 sector_size = ((uint32_t)buffer[8] << 24) 797 | ((uint32_t)buffer[9] << 16) 798 | ((uint32_t)buffer[10] << 8) 799 | ((uint32_t)buffer[11]); 800 801 /* We only support the disk if sector size is 512 bytes. */ 802 if (sector_size != 512) 803 { 804 /* Leave a log entry. */ 805 BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size); 806 continue; 807 } 808 809 /* Get logical CHS geometry. */ 810 switch (devcount_scsi) 811 { 812 case 0: 813 cmos_base = 0x90; 814 break; 815 case 1: 816 cmos_base = 0x98; 817 break; 818 case 2: 819 cmos_base = 0xA0; 820 break; 821 case 3: 822 cmos_base = 0xA8; 823 break; 824 default: 825 cmos_base = 0; 826 } 827 828 if (cmos_base && inb_cmos(cmos_base + 7)) 829 { 830 /* If provided, grab the logical geometry from CMOS. */ 831 cylinders = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8); 832 heads = inb_cmos(cmos_base + 2); 833 sectors_per_track = inb_cmos(cmos_base + 7); 834 } 835 else 836 { 837 /* Calculate default logical geometry. NB: Very different 838 * from default ATA/SATA logical geometry! 839 */ 840 if (sectors >= (uint32_t)4 * 1024 * 1024) 841 { 842 heads = 255; 843 sectors_per_track = 63; 844 /* Approximate x / (255 * 63) using shifts */ 845 t = (sectors >> 6) + (sectors >> 12); 846 cylinders = (t >> 8) + (t >> 16); 847 } 848 else if (sectors >= (uint32_t)2 * 1024 * 1024) 849 { 850 heads = 128; 851 sectors_per_track = 32; 852 cylinders = sectors >> 12; 853 } 854 else 855 { 856 heads = 64; 857 sectors_per_track = 32; 858 cylinders = sectors >> 11; 859 } 860 } 861 862 /* Calculate index into the generic disk table. */ 863 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 864 865 bios_dsk->scsidev[devcount_scsi].target_id = i; 866 bios_dsk->devices[hd_index].type = DSK_TYPE_VIRTIO_SCSI; 867 bios_dsk->devices[hd_index].device = DSK_DEVICE_HD; 868 bios_dsk->devices[hd_index].removable = 0; 869 bios_dsk->devices[hd_index].lock = 0; 870 bios_dsk->devices[hd_index].blksize = sector_size; 871 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA; 872 873 /* Write LCHS/PCHS values. */ 874 bios_dsk->devices[hd_index].lchs.heads = heads; 875 bios_dsk->devices[hd_index].lchs.spt = sectors_per_track; 876 bios_dsk->devices[hd_index].pchs.heads = heads; 877 bios_dsk->devices[hd_index].pchs.spt = sectors_per_track; 878 879 if (cylinders > 1024) { 880 bios_dsk->devices[hd_index].lchs.cylinders = 1024; 881 bios_dsk->devices[hd_index].pchs.cylinders = 1024; 882 } else { 883 bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders; 884 bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders; 885 } 886 887 BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi, 888 i, (uint32_t)cylinders, heads, sectors_per_track, sectors); 889 890 bios_dsk->devices[hd_index].sectors = sectors; 891 892 /* Store the id of the disk in the ata hdidmap. */ 893 hdcount = bios_dsk->hdcount; 894 bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 895 hdcount++; 896 bios_dsk->hdcount = hdcount; 897 898 /* Update hdcount in the BDA. */ 899 hdcount = read_byte(0x40, 0x75); 900 hdcount++; 901 write_byte(0x40, 0x75, hdcount); 902 903 devcount_scsi++; 835 904 } 836 905 else 837 906 { 838 /* Calculate default logical geometry. NB: Very different 839 * from default ATA/SATA logical geometry! 840 */ 841 if (sectors >= (uint32_t)4 * 1024 * 1024) 842 { 843 heads = 255; 844 sectors_per_track = 63; 845 /* Approximate x / (255 * 63) using shifts */ 846 t = (sectors >> 6) + (sectors >> 12); 847 cylinders = (t >> 8) + (t >> 16); 848 } 849 else if (sectors >= (uint32_t)2 * 1024 * 1024) 850 { 851 heads = 128; 852 sectors_per_track = 32; 853 cylinders = sectors >> 12; 854 } 855 else 856 { 857 heads = 64; 858 sectors_per_track = 32; 859 cylinders = sectors >> 11; 860 } 907 /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */ 908 break; 861 909 } 862 863 /* Calculate index into the generic disk table. */ 910 } 911 else if ( ((buffer[0] & 0xe0) == 0) 912 && ((buffer[0] & 0x1f) == 0x05)) 913 { 914 uint8_t cdcount; 915 uint8_t removable; 916 917 BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i); 918 919 /* Calculate index into the generic device table. */ 864 920 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 921 922 removable = buffer[1] & 0x80 ? 1 : 0; 865 923 866 924 bios_dsk->scsidev[devcount_scsi].target_id = i; 867 925 bios_dsk->devices[hd_index].type = DSK_TYPE_VIRTIO_SCSI; 868 bios_dsk->devices[hd_index].device = DSK_DEVICE_HD; 869 bios_dsk->devices[hd_index].removable = 0; 870 bios_dsk->devices[hd_index].lock = 0; 871 bios_dsk->devices[hd_index].blksize = sector_size; 872 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA; 873 874 /* Write LCHS/PCHS values. */ 875 bios_dsk->devices[hd_index].lchs.heads = heads; 876 bios_dsk->devices[hd_index].lchs.spt = sectors_per_track; 877 bios_dsk->devices[hd_index].pchs.heads = heads; 878 bios_dsk->devices[hd_index].pchs.spt = sectors_per_track; 879 880 if (cylinders > 1024) { 881 bios_dsk->devices[hd_index].lchs.cylinders = 1024; 882 bios_dsk->devices[hd_index].pchs.cylinders = 1024; 883 } else { 884 bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders; 885 bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders; 886 } 887 888 BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi, 889 i, (uint32_t)cylinders, heads, sectors_per_track, sectors); 890 891 bios_dsk->devices[hd_index].sectors = sectors; 892 893 /* Store the id of the disk in the ata hdidmap. */ 894 hdcount = bios_dsk->hdcount; 895 bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 896 hdcount++; 897 bios_dsk->hdcount = hdcount; 898 899 /* Update hdcount in the BDA. */ 900 hdcount = read_byte(0x40, 0x75); 901 hdcount++; 902 write_byte(0x40, 0x75, hdcount); 926 bios_dsk->devices[hd_index].device = DSK_DEVICE_CDROM; 927 bios_dsk->devices[hd_index].removable = removable; 928 bios_dsk->devices[hd_index].blksize = 2048; 929 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE; 930 931 /* Store the ID of the device in the BIOS cdidmap. */ 932 cdcount = bios_dsk->cdcount; 933 bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 934 cdcount++; 935 bios_dsk->cdcount = cdcount; 903 936 904 937 devcount_scsi++; 905 938 } 906 939 else 907 { 908 /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */ 909 break; 910 } 911 } 912 else if ( ((buffer[0] & 0xe0) == 0) 913 && ((buffer[0] & 0x1f) == 0x05)) 914 { 915 uint8_t cdcount; 916 uint8_t removable; 917 918 BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i); 919 920 /* Calculate index into the generic device table. */ 921 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 922 923 removable = buffer[1] & 0x80 ? 1 : 0; 924 925 bios_dsk->scsidev[devcount_scsi].target_id = i; 926 bios_dsk->devices[hd_index].type = DSK_TYPE_VIRTIO_SCSI; 927 bios_dsk->devices[hd_index].device = DSK_DEVICE_CDROM; 928 bios_dsk->devices[hd_index].removable = removable; 929 bios_dsk->devices[hd_index].blksize = 2048; 930 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE; 931 932 /* Store the ID of the device in the BIOS cdidmap. */ 933 cdcount = bios_dsk->cdcount; 934 bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 935 cdcount++; 936 bios_dsk->cdcount = cdcount; 937 938 devcount_scsi++; 940 DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i); 939 941 } 940 942 else 941 DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i);943 DBG_VIRTIO("%s: INQUIRY failed with %u\n", __func__, rc); 942 944 943 945 bios_dsk->scsi_devcount = devcount_scsi;
Note:
See TracChangeset
for help on using the changeset viewer.