Changeset 81407 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Oct 21, 2019 1:08:46 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134121
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/virtio.c
r81135 r81407 23 23 #include "pciutil.h" 24 24 #include "vds.h" 25 #include "scsi.h" 25 26 26 27 #define DEBUG_VIRTIO 1 … … 31 32 #endif 32 33 33 #define SCSI_INQUIRY 0x1234 #define VBSCSI_MAX_DEVICES 16 /* Maximum number of devices a SCSI device currently supported. */ 34 35 35 36 /* The maximum CDB size. */ … … 432 433 { 433 434 uint16_t idxUsedOld = virtio->Queue.UsedRing.idxNextUsed; 435 uint64_t idxNext = virtio->Queue.AvailRing.idxNextFree; 434 436 435 437 _fmemset(&virtio->ScsiReqHdr, 0, sizeof(virtio->ScsiReqHdr)); … … 452 454 virtio->Queue.aDescTbl[1].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqSts); 453 455 virtio->Queue.aDescTbl[1].GCPhysBufHigh = 0; 454 virtio->Queue.aDescTbl[1].cbBuf = sizeof(virtio->ScsiReq Hdr);456 virtio->Queue.aDescTbl[1].cbBuf = sizeof(virtio->ScsiReqSts); 455 457 virtio->Queue.aDescTbl[1].fFlags = VIRTIO_Q_DESC_F_WRITE | VIRTIO_Q_DESC_F_NEXT; 456 458 virtio->Queue.aDescTbl[1].idxNext = 2; … … 469 471 /* Notify the device about the new command. */ 470 472 DBG_VIRTIO("VirtIO: Submitting new request, Queue.offNotify=0x%x\n", virtio->Queue.offNotify); 471 virtio_reg_notify_write_u16(virtio, virtio->Queue.offNotify, 0);473 virtio_reg_notify_write_u16(virtio, virtio->Queue.offNotify, idxNext); 472 474 473 475 /* Wait for it to complete. */ … … 481 483 static int virtio_scsi_detect_devices(virtio_t __far *virtio) 482 484 { 483 uint8_t buffer[0x0200]; 484 uint8_t rc; 485 uint8_t aCDB[16]; 486 487 aCDB[0] = SCSI_INQUIRY; 488 aCDB[1] = 0; 489 aCDB[2] = 0; 490 aCDB[3] = 0; 491 aCDB[4] = 5; /* Allocation length. */ 492 aCDB[5] = 0; 493 494 rc = virtio_scsi_cmd_data_in(virtio, 0, aCDB, 6, buffer, 5); 495 if (rc != 0) 496 BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__); 497 498 return rc; 485 int i; 486 uint8_t buffer[0x0200]; 487 bio_dsk_t __far *bios_dsk; 488 489 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 490 491 /* Go through target devices. */ 492 for (i = 0; i < VBSCSI_MAX_DEVICES; i++) 493 { 494 uint8_t rc; 495 uint8_t aCDB[16]; 496 uint8_t hd_index, devcount_scsi; 497 498 aCDB[0] = SCSI_INQUIRY; 499 aCDB[1] = 0; 500 aCDB[2] = 0; 501 aCDB[3] = 0; 502 aCDB[4] = 5; /* Allocation length. */ 503 aCDB[5] = 0; 504 505 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 6, buffer, 5); 506 if (rc != 0) 507 BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__); 508 509 devcount_scsi = bios_dsk->scsi_devcount; 510 511 /* Check the attached device. */ 512 if ( ((buffer[0] & 0xe0) == 0) 513 && ((buffer[0] & 0x1f) == 0x00)) 514 { 515 DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i); 516 517 /* We add the disk only if the maximum is not reached yet. */ 518 if (devcount_scsi < BX_MAX_SCSI_DEVICES) 519 { 520 uint64_t sectors, t; 521 uint32_t sector_size, cylinders; 522 uint16_t heads, sectors_per_track; 523 uint8_t hdcount; 524 uint8_t cmos_base; 525 526 /* Issue a read capacity command now. */ 527 _fmemset(aCDB, 0, sizeof(aCDB)); 528 aCDB[0] = SCSI_SERVICE_ACT; 529 aCDB[1] = SCSI_READ_CAP_16; 530 aCDB[13] = 32; /* Allocation length. */ 531 532 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32); 533 if (rc != 0) 534 BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__); 535 536 /* The value returned is the last addressable LBA, not 537 * the size, which what "+ 1" is for. 538 */ 539 sectors = swap_64(*(uint64_t *)buffer) + 1; 540 541 sector_size = ((uint32_t)buffer[8] << 24) 542 | ((uint32_t)buffer[9] << 16) 543 | ((uint32_t)buffer[10] << 8) 544 | ((uint32_t)buffer[11]); 545 546 /* We only support the disk if sector size is 512 bytes. */ 547 if (sector_size != 512) 548 { 549 /* Leave a log entry. */ 550 BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size); 551 continue; 552 } 553 554 /* Get logical CHS geometry. */ 555 switch (devcount_scsi) 556 { 557 case 0: 558 cmos_base = 0x90; 559 break; 560 case 1: 561 cmos_base = 0x98; 562 break; 563 case 2: 564 cmos_base = 0xA0; 565 break; 566 case 3: 567 cmos_base = 0xA8; 568 break; 569 default: 570 cmos_base = 0; 571 } 572 573 if (cmos_base && inb_cmos(cmos_base + 7)) 574 { 575 /* If provided, grab the logical geometry from CMOS. */ 576 cylinders = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8); 577 heads = inb_cmos(cmos_base + 2); 578 sectors_per_track = inb_cmos(cmos_base + 7); 579 } 580 else 581 { 582 /* Calculate default logical geometry. NB: Very different 583 * from default ATA/SATA logical geometry! 584 */ 585 if (sectors >= (uint32_t)4 * 1024 * 1024) 586 { 587 heads = 255; 588 sectors_per_track = 63; 589 /* Approximate x / (255 * 63) using shifts */ 590 t = (sectors >> 6) + (sectors >> 12); 591 cylinders = (t >> 8) + (t >> 16); 592 } 593 else if (sectors >= (uint32_t)2 * 1024 * 1024) 594 { 595 heads = 128; 596 sectors_per_track = 32; 597 cylinders = sectors >> 12; 598 } 599 else 600 { 601 heads = 64; 602 sectors_per_track = 32; 603 cylinders = sectors >> 11; 604 } 605 } 606 607 /* Calculate index into the generic disk table. */ 608 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 609 610 //bios_dsk->scsidev[devcount_scsi].io_base = io_base; 611 bios_dsk->scsidev[devcount_scsi].target_id = i; 612 bios_dsk->devices[hd_index].type = DSK_TYPE_SCSI; 613 bios_dsk->devices[hd_index].device = DSK_DEVICE_HD; 614 bios_dsk->devices[hd_index].removable = 0; 615 bios_dsk->devices[hd_index].lock = 0; 616 bios_dsk->devices[hd_index].blksize = sector_size; 617 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA; 618 619 /* Write LCHS/PCHS values. */ 620 bios_dsk->devices[hd_index].lchs.heads = heads; 621 bios_dsk->devices[hd_index].lchs.spt = sectors_per_track; 622 bios_dsk->devices[hd_index].pchs.heads = heads; 623 bios_dsk->devices[hd_index].pchs.spt = sectors_per_track; 624 625 if (cylinders > 1024) { 626 bios_dsk->devices[hd_index].lchs.cylinders = 1024; 627 bios_dsk->devices[hd_index].pchs.cylinders = 1024; 628 } else { 629 bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders; 630 bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders; 631 } 632 633 BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi, 634 i, (uint32_t)cylinders, heads, sectors_per_track, sectors); 635 636 bios_dsk->devices[hd_index].sectors = sectors; 637 638 /* Store the id of the disk in the ata hdidmap. */ 639 hdcount = bios_dsk->hdcount; 640 bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 641 hdcount++; 642 bios_dsk->hdcount = hdcount; 643 644 /* Update hdcount in the BDA. */ 645 hdcount = read_byte(0x40, 0x75); 646 hdcount++; 647 write_byte(0x40, 0x75, hdcount); 648 649 devcount_scsi++; 650 } 651 else 652 { 653 /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */ 654 break; 655 } 656 } 657 else if ( ((buffer[0] & 0xe0) == 0) 658 && ((buffer[0] & 0x1f) == 0x05)) 659 { 660 uint8_t cdcount; 661 uint8_t removable; 662 663 BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i); 664 665 /* Calculate index into the generic device table. */ 666 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 667 668 removable = buffer[1] & 0x80 ? 1 : 0; 669 670 //bios_dsk->scsidev[devcount_scsi].io_base = io_base; 671 bios_dsk->scsidev[devcount_scsi].target_id = i; 672 bios_dsk->devices[hd_index].type = DSK_TYPE_SCSI; 673 bios_dsk->devices[hd_index].device = DSK_DEVICE_CDROM; 674 bios_dsk->devices[hd_index].removable = removable; 675 bios_dsk->devices[hd_index].blksize = 2048; 676 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE; 677 678 /* Store the ID of the device in the BIOS cdidmap. */ 679 cdcount = bios_dsk->cdcount; 680 bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES; 681 cdcount++; 682 bios_dsk->cdcount = cdcount; 683 684 devcount_scsi++; 685 } 686 else 687 DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i); 688 689 bios_dsk->scsi_devcount = devcount_scsi; 690 } 499 691 } 500 692 … … 588 780 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_ACK; 589 781 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat); 590 /* Our driver knows how to operate tthe device. */782 /* Our driver knows how to operate the device. */ 591 783 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_DRV; 592 784 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat); 593 785 786 #if 0 594 787 /* Read the feature bits and only program the VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT bit if available. */ 595 788 fFeatures = virtio_reg_common_read_u32(virtio, VIRTIO_COMMON_REG_DEV_FEAT); 596 789 fFeatures &= VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT; 790 #endif 597 791 598 792 /* Check that the device is sane. */ … … 606 800 } 607 801 608 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_D EV_FEAT, fFeatures);802 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_DRV_FEAT, VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT); 609 803 610 804 /* Set the features OK bit. */ … … 721 915 DBG_VIRTIO("VirtIO SCSI HBA with all required capabilities at 0x%x\n", u8PciCapOffVirtIo); 722 916 917 /* Enable PCI memory, I/O, bus mastering access in command register. */ 918 pci_write_config_word(u8Bus, u8DevFn, 4, 0x7); 919 723 920 rc = virtio_scsi_hba_init(u8Bus, u8DevFn, u8PciCapOffVirtIo); 724 921 }
Note:
See TracChangeset
for help on using the changeset viewer.