Changeset 80108 in vbox
- Timestamp:
- Aug 1, 2019 8:24:22 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 132548
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r80059 r80108 83 83 | VIRTIOSCSI_F_T10_PI \ 84 84 85 typedef struct VIRTIO_PCI_DEV_CAP_T 86 { 87 uint32_t uTestField1; 88 uint32_t uTestField2; 89 } VIRTIO_PCI_DEV_CAP_T, *PVIRTIO_PCI_DEV_CAP_T; 90 85 91 /** 86 92 * State of a target attached to the VirtIO SCSI Host … … 143 149 /* virtioState must be first member */ 144 150 VIRTIOSTATE virtioState; 151 152 VIRTIO_PCI_DEV_CAP_T devSpecificCap; 145 153 146 154 /* SCSI target instances data */ … … 180 188 /** The event semaphore the processing thread waits on. */ 181 189 SUPSEMEVENT hEvtProcess; 182 183 PVIRTIOCALLBACKS pVirtioCallbacks;184 190 185 191 /** Number of ports detected */ … … 971 977 PVIRTIOSTATE pVirtio = &(pThis->virtioState); 972 978 979 virtioSetHostFeatures(pVirtio, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED); 980 973 981 pThis->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 974 rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams, &pThis->pVirtioCallbacks, 982 983 rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams, 975 984 VIRTIOSCSI_NAME_FMT, VIRTIOSCSI_N_QUEUES, VIRTIOSCSI_REGION_PCI_CAP, 976 985 virtioScsiR3DevCapRead, virtioScsiR3DevCapWrite, 977 0/* cbDevSpecificCap */,978 0 /* uNotifyOffMultiplier */);986 sizeof(VIRTIO_PCI_DEV_CAP_T ) /* cbDevSpecificCap */, 987 false /* fHaveDevSpecificCap */, 0 /* uNotifyOffMultiplier */); 979 988 980 989 … … 982 991 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO")); 983 992 984 pThis->pVirtioCallbacks->pfnSetHostFeatures(pVirtio, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED);985 993 986 994 rc = PDMDevHlpPCIIORegionRegister(pDevIns, VIRTIOSCSI_REGION_MEM_IO, 32, -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r80058 r80108 424 424 } 425 425 426 427 426 /** 428 427 * Raise interrupt. … … 432 431 * @param u8IntCause Interrupt cause bit mask to set in PCI ISR port. 433 432 */ 433 __attribute__((unused)) 434 434 int virtioRaiseInterrupt(VIRTIOSTATE *pState, int rcBusy, uint8_t u8IntCause) 435 435 { 436 436 RT_NOREF2(pState, u8IntCause); 437 437 RT_NOREF_PV(rcBusy); 438 /* PK TODO: Adapt to VirtIO 1.0439 STAM_COUNTER_INC(&pState->StatIntsRaised);440 438 LogFlow(("%s virtioRaiseInterrupt: u8IntCause=%x\n", 441 439 INSTANCE(pState), u8IntCause)); … … 443 441 pState->uISR |= u8IntCause; 444 442 PDMDevHlpPCISetIrq(pState->CTX_SUFF(pDevIns), 0, 1); 445 */446 443 return VINF_SUCCESS; 447 444 } … … 459 456 } 460 457 461 DECLINLINE(uint32_t) virtioGetHostFeatures(PVIRTIOSTATE pState,462 PFNGETHOSTFEATURES pfnGetHostFeatures)463 {464 return pfnGetHostFeatures(pState) /*| VIRTIO_F_NOTIFY_ON_EMPTY */;465 }466 467 458 468 459 #ifdef IN_RING3 469 470 471 460 /** 472 461 * Saves the state of device. … … 645 634 AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n")); 646 635 } 647 else /* Guest WRITEpCommonCfg->uDeviceFeature */636 else /* Guest READ pCommonCfg->uDeviceFeature */ 648 637 { 649 638 switch(pVirtio->uFeaturesOfferedSelect) 650 639 { 651 640 case 0: 652 pVirtio->uFeaturesOffered = *(uint32_t *)pv;653 L OG_ACCESSOR(uFeaturesOffered, uint32_t);641 *(uint32_t *)pv = pVirtio->uFeaturesOffered & 0xffffffff; 642 LogFunc(("Guest read 0x%8x from LO DWORD of uFeaturesOffered\n", *(uint32_t *)pv)); 654 643 break; 655 644 case 1: 656 pVirtio->uFeaturesOffered = (uint64_t)(*(uint32_t *)pv) << 32;657 L OG_ACCESSOR(uFeaturesOffered, uint32_t);645 *(uint32_t *)pv = (pVirtio->uFeaturesOffered >> 32) & 0xffffffff; 646 LogFunc(("Guest read 0x%8x from HI DWORD of uFeaturesOffered\n", *(uint32_t *)pv)); 658 647 break; 659 648 default: 660 Log(("Guest selected out of range pVirtio->uDeviceFeature(%d), returning 0\n",649 Log(("Guest read uDeviceFeature with out of range selector (%d), returning 0\n", 661 650 pVirtio->uFeaturesOfferedSelect)); 662 651 } … … 671 660 case 0: 672 661 pVirtio->uFeaturesAccepted = *(uint32_t *)pv; 673 L OG_ACCESSOR(uFeaturesAccepted, uint32_t);662 LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 674 663 break; 675 664 case 1: 676 665 pVirtio->uFeaturesAccepted = (uint64_t)(*(uint32_t *)pv) << 32; 677 L OG_ACCESSOR(uFeaturesAccepted, uint32_t);666 LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 678 667 break; 679 668 } … … 685 674 case 0: 686 675 *(uint32_t *)pv = pVirtio->uFeaturesAccepted & 0xffffffff; 687 L OG_ACCESSOR(uFeaturesAccepted, uint32_t);676 LogFunc(("Guest read 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 688 677 break; 689 678 case 1: 690 679 *(uint32_t *)pv = (pVirtio->uFeaturesAccepted >> 32) & 0xffffffff; 691 L OG_ACCESSOR(uFeaturesAccepted, uint32_t);680 LogFunc(("Guest read 0x%8x from HI DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 692 681 break; 693 682 } … … 712 701 pVirtio->uDeviceStatus = *(uint8_t *)pv; 713 702 LogFunc(("Driver wrote uDeviceStatus:\n")); 714 showDeviceStatus(pVirtio->uDeviceStatus);703 logDeviceStatus(pVirtio->uDeviceStatus); 715 704 if (pVirtio->uDeviceStatus == 0) 716 705 virtioResetDevice(pVirtio); … … 720 709 LogFunc(("Driver read uDeviceStatus:\n")); 721 710 *(uint32_t *)pv = pVirtio->uDeviceStatus; 722 showDeviceStatus(pVirtio->uDeviceStatus);711 logDeviceStatus(pVirtio->uDeviceStatus); 723 712 } 724 713 } … … 799 788 // LogFlowFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb)); 800 789 //#endif 790 791 /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */ 792 801 793 off_t uoff = 0; 802 794 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg, uoff); 803 795 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, VIRTIO_PCI_ISR_CAP_T, pIsrCap, uoff); 804 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 805 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap, uoff); 806 #endif 807 /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */ 808 796 797 if (pVirtio->fHaveDevSpecificCap) 798 { 799 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap, uoff); 800 if (pDeviceCap) 801 rc = pVirtio->virtioCallbacks.pfnVirtioDevCapRead(pDevIns, GCPhysAddr, pv, cb); 802 return rc; 803 } 809 804 if (pCommonCfg) 810 805 virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uoff, pv); … … 814 809 LogFunc(("Read 0x%s from pIsrCap\n", *(uint8_t *)pv)); 815 810 } 816 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 817 else if (pDeviceCap) 818 rc = pThis->pfnVirtioDevCapRead(pDevIns, GCPhysAddr, pv, cb); 819 #endif 811 else { 812 813 AssertMsgFailed(("virtio: Write outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb)); 814 Log(("pCommonCfg=%p, pIsrCap=%p, uoff=%d\n", 815 pCommonCfg, pIsrCap, uoff)); 816 } 817 return rc; 818 } 819 820 /** 821 * Memory mapped I/O Handler for PCI Capabilities write operations. 822 * 823 * @returns VBox status code. 824 * 825 * @param pDevIns The device instance. 826 * @param pvUser User argument. 827 * @param GCPhysAddr Physical address (in GC) where the write starts. 828 * @param pv Where to fetch the result. 829 * @param cb Number of bytes to write. 830 */ 831 PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 832 { 833 834 RT_NOREF(pvUser); 835 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 836 int rc = VINF_SUCCESS; 837 838 //#ifdef LOG_ENABLED 839 // LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb)); 840 //#endif 841 off_t uoff = 0; 842 843 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg, uoff); 844 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, VIRTIO_PCI_ISR_CAP_T, pIsrCap, uoff); 845 if (pVirtio->fHaveDevSpecificCap) 846 { 847 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap, uoff); 848 if (pDeviceCap) 849 rc = pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, GCPhysAddr, pv, cb); 850 return rc; 851 } 852 if (pCommonCfg) 853 virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uoff, pv); 854 else if (pIsrCap) 855 { 856 pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1; 857 pVirtio->fDeviceConfigInterrupt = !!(*((uint8_t *)pv) & 2); 858 Log(("pIsrCap... setting fQueueInterrupt=%d fDeviceConfigInterrupt=%d\n", 859 pVirtio->fQueueInterrupt, pVirtio->fDeviceConfigInterrupt)); 860 } 820 861 else 821 AssertMsgFailed(("virtio: Write outside of capabilities region\n")); 862 { 863 AssertMsgFailed(("virtio: Write outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb)); 864 Log(("pCommonCfg=%p, pIsrCap=%p, uoff=%d\n", 865 pCommonCfg, pIsrCap, uoff)); 866 } 822 867 823 868 return rc; 824 869 } 825 #if TBD 870 871 872 /** 873 * @callback_method_impl{FNPCIIOREGIONMAP} 874 */ 875 static DECLCALLBACK(int) virtioR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 876 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType) 877 { 878 RT_NOREF3(pPciDev, iRegion, enmType); 879 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 880 int rc = VINF_SUCCESS; 881 882 Assert(cb >= 32); 883 884 if (iRegion == pVirtio->uVirtioCapRegion) 885 { 886 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 887 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 888 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 889 virtioR3MmioWrite, virtioR3MmioRead, 890 "virtio-scsi MMIO"); 891 892 if (RT_FAILURE(rc)) 893 { 894 LogFunc(("virtio: PCI Capabilities failed to map GCPhysAddr=%RGp cb=%RGp, region=%d\n", 895 GCPhysAddress, cb, iRegion)); 896 return rc; 897 } 898 LogFunc(("virtio: PCI Capabilities mapped at GCPhysAddr=%RGp cb=%RGp, region=%d\n", 899 GCPhysAddress, cb, iRegion)); 900 pVirtio->GCPhysPciCapBase = GCPhysAddress; 901 pVirtio->pGcPhysCommonCfg = (PVIRTIO_PCI_COMMON_CFG_T)(GCPhysAddress + pVirtio->uCommonCfgOffset); 902 pVirtio->pGcPhysNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)(GCPhysAddress + pVirtio->uNotifyCapOffset); 903 pVirtio->pGcPhysIsrCap = (PVIRTIO_PCI_ISR_CAP_T)( GCPhysAddress + pVirtio->uIsrCapOffset); 904 pVirtio->pGcPhysPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)( GCPhysAddress + pVirtio->uPciCfgCapOffset); 905 pVirtio->pGcPhysDeviceCap = (PVIRTIO_PCI_DEVICE_CAP_T)(GCPhysAddress + pVirtio->uDeviceCapOffset); 906 } 907 return rc; 908 } 909 826 910 /** 827 911 * Callback function for reading from the PCI configuration space. … … 841 925 { 842 926 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 843 int rc = VINF_SUCCESS; 844 845 LogFunc(("uAddress: %d, uPciConfigDataOffset: %d\n", uAddress, pVirtio->uPciConfigDataOffset)); 846 847 if (uAddress == pVirtio->uPciConfigDataOffset) 848 Log(("Read uPciConfigDataOffset\n")); 849 rc = pVirtio->pfnPciConfigReadOld(pDevIns, pPciDev, uAddress, cb); 850 return rc; 851 927 928 if (uAddress == pVirtio->uPciCfgDataOff) 929 { 930 /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability 931 * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space 932 * (the virtio_pci_cfg_cap capability), and access data items. */ 933 uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength; 934 uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset; 935 uint8_t uBar = pVirtio->pPciCfgCap->pciCap.uBar; 936 uint32_t pv = 0; 937 if (uBar == pVirtio->uVirtioCapRegion) 938 (void)virtioR3MmioRead(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->GCPhysPciCapBase + uOffset), 939 &pv, uLength); 940 else 941 { 942 LogFunc(("Guest read virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring")); 943 return 0; 944 } 945 LogFunc(("virtio: Guest read virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%d, length=%d, result=%d\n", 946 uBar, uOffset, uLength, pv)); 947 return pv; 948 } 949 return pVirtio->pfnPciConfigReadOld(pDevIns, pPciDev, uAddress, cb); 852 950 } 853 951 … … 872 970 { 873 971 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 874 VBOXSTRICTRC strictRc; 875 876 LogFunc(("uAddress: %d, uPciConfigDataOffset: %d\n", uAddress, pVirtio->uPciConfigDataOffset)); 877 if (uAddress == pVirtio->uPciConfigDataOffset) 878 Log(("Wrote uPciConfigDataOffset\n")); 879 strictRc = pVirtio->pfnPciConfigWriteOld(pDevIns, pPciDev, uAddress, u32Value, cb); 880 return strictRc; 881 } 882 #endif 883 /** 884 * Memory mapped I/O Handler for PCI Capabilities write operations. 885 * 886 * @returns VBox status code. 887 * 888 * @param pDevIns The device instance. 889 * @param pvUser User argument. 890 * @param GCPhysAddr Physical address (in GC) where the write starts. 891 * @param pv Where to fetch the result. 892 * @param cb Number of bytes to write. 893 */ 894 PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 895 { 896 897 RT_NOREF(pvUser); 898 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 899 int rc = VINF_SUCCESS; 900 901 #ifdef LOG_ENABLED 902 // LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb)); 903 #endif 904 off_t uoff = 0; 905 906 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg, uoff); 907 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, VIRTIO_PCI_ISR_CAP_T, pIsrCap, uoff); 908 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 909 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap, uoff); 910 #endif 911 912 if (pCommonCfg) 913 virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uoff, pv); 914 else if (pIsrCap) 915 { 916 pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1; 917 pVirtio->fDeviceConfigInterrupt = !!(*((uint8_t *)pv) & 2); 918 Log(("pIsrCap... setting fQueueInterrupt=%d fDeviceConfigInterrupt=%d\n", 919 pVirtio->fQueueInterrupt, pVirtio->fDeviceConfigInterrupt)); 920 } 921 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 922 else if (pDeviceCap) 923 rc = pThis->pfnVirtioDevCapWrite(pDevIns, GCPhysAddr, pv, cb); 924 #endif 925 else 926 AssertMsgFailed(("virtio: Write outside of capabilities region\n")); 927 928 return rc; 929 } 930 931 932 /** 933 * @callback_method_impl{FNPCIIOREGIONMAP} 934 */ 935 static DECLCALLBACK(int) virtioR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 936 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType) 937 { 938 RT_NOREF3(pPciDev, iRegion, enmType); 939 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 940 int rc = VINF_SUCCESS; 941 942 Assert(cb >= 32); 943 944 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 945 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 946 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 947 virtioR3MmioWrite, virtioR3MmioRead, 948 "virtio-scsi MMIO"); 949 950 LogFunc(("virtio: PCI Capabilities mapped at GCPhysAddr=%RGp cb=%RGp, region=%d\n", GCPhysAddress, cb, iRegion)); 951 952 if (RT_SUCCESS(rc)) 953 { 954 pVirtio->GCPhysPciCapBase = GCPhysAddress; 955 pVirtio->pGcPhysCommonCfg = (PVIRTIO_PCI_COMMON_CFG_T)(GCPhysAddress + pVirtio->uCommonCfgOffset); 956 pVirtio->pGcPhysNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)(GCPhysAddress + pVirtio->uNotifyCapOffset); 957 pVirtio->pGcPhysIsrCap = (PVIRTIO_PCI_ISR_CAP_T)(GCPhysAddress + pVirtio->uIsrCapOffset); 958 pVirtio->pGcPhysPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)(GCPhysAddress + pVirtio->uPciCfgCapOffset); 959 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 960 pVirtio->pGcPhysDeviceCap = (PVIRTIO_PCI_DEVICE_CAP_T)(GCPhysAddress + pVirtio->uuDeviceCapOffset); 961 #endif 962 } 963 return rc; 964 } 965 972 973 if (uAddress == pVirtio->uPciCfgDataOff) 974 { 975 /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability 976 * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space 977 * (the virtio_pci_cfg_cap capability), and access data items. */ 978 uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength; 979 uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset; 980 uint8_t uBar = pVirtio->pPciCfgCap->pciCap.uBar; 981 if (uBar == pVirtio->uVirtioCapRegion) 982 (void)virtioR3MmioWrite(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->GCPhysPciCapBase + uOffset), 983 (void *)&u32Value, uLength); 984 else 985 { 986 LogFunc(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring")); 987 return VINF_SUCCESS; 988 } 989 LogFunc(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%x, length=%x, value=%d\n", 990 uBar, uOffset, uLength, u32Value)); 991 return VINF_SUCCESS; 992 } 993 return pVirtio->pfnPciConfigWriteOld(pDevIns, pPciDev, uAddress, u32Value, cb); 994 } 966 995 967 996 /** … … 978 1007 979 1008 /** 980 * Get VirtIO a vailablehost-side features1009 * Get VirtIO accepted host-side features 981 1010 * 982 1011 * @returns feature bits selected or 0 if selector out of range. … … 986 1015 */ 987 1016 1017 __attribute__((unused)) 988 1018 static uint64_t virtioGetHostFeatures(PVIRTIOSTATE pVirtio) 989 1019 { 990 return pVirtio->uFeatures Offered;1020 return pVirtio->uFeaturesAccepted; 991 1021 } 992 1022 … … 1001 1031 */ 1002 1032 1003 static intvirtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered)1033 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered) 1004 1034 { 1005 1035 pVirtio->uFeaturesOffered = VIRTIO_F_VERSION_1 | uFeaturesOffered; 1006 return VINF_SUCCESS;1007 1036 } 1008 1037 … … 1055 1084 1056 1085 int virtioConstruct(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, int iInstance, PVIRTIOPCIPARAMS pPciParams, 1057 PPVIRTIOCALLBACKS ppVirtioCallbacks, const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioRegion,1086 const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioCapRegion, 1058 1087 PFNVIRTIODEVCAPREAD devCapReadCallback, PFNVIRTIODEVCAPWRITE devCapWriteCallback, 1059 uint16_t cbDevSpecificCap, uint32_t uNotifyOffMultiplier)1088 uint16_t cbDevSpecificCap, bool fHaveDevSpecificCap, uint32_t uNotifyOffMultiplier) 1060 1089 { 1061 1090 pVirtio->nQueues = nQueues; … … 1064 1093 /* Init handles and log related stuff. */ 1065 1094 RTStrPrintf(pVirtio->szInstance, sizeof(pVirtio->szInstance), pcszNameFmt, iInstance); 1066 1067 VIRTIOCALLBACKS virtioCallbacks;1068 virtioCallbacks.pfnSetHostFeatures = virtioSetHostFeatures;1069 virtioCallbacks.pfnGetHostFeatures = virtioGetHostFeatures;1070 virtioCallbacks.pfnReset = virtioReset;1071 *ppVirtioCallbacks = &virtioCallbacks;1072 1095 1073 1096 pVirtio->pDevInsR3 = pDevIns; … … 1075 1098 pVirtio->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1076 1099 pVirtio->uDeviceStatus = 0; 1077 pVirtio->pfnVirtioDevCapRead = devCapReadCallback; 1078 pVirtio->pfnVirtioDevCapWrite = devCapWriteCallback; 1100 pVirtio->uVirtioCapRegion = uVirtioCapRegion; 1101 pVirtio->fHaveDevSpecificCap = fHaveDevSpecificCap; 1102 pVirtio->virtioCallbacks.pfnVirtioDevCapRead = devCapReadCallback; 1103 pVirtio->virtioCallbacks.pfnVirtioDevCapWrite = devCapWriteCallback; 1079 1104 1080 1105 /* Set PCI config registers (assume 32-bit mode) */ … … 1099 1124 pVirtio->IBase = pDevIns->IBase; 1100 1125 1126 1127 PDMDevHlpPCISetConfigCallbacks(pDevIns, &pVirtio->dev, 1128 virtioPciConfigRead, &pVirtio->pfnPciConfigReadOld, 1129 virtioPciConfigWrite, &pVirtio->pfnPciConfigWriteOld); 1130 1101 1131 /** Construct & map PCI vendor-specific capabilities for virtio host negotiation with guest driver */ 1102 1132 … … 1109 1139 uint8_t uCfgCapOffset = 0x40; 1110 1140 PVIRTIO_PCI_NOTIFY_CAP_T pNotifyCap; 1111 PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap; 1112 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 1113 PVIRTIO_PCI_CAP_T pDeviceCap; 1114 #endif 1141 PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap, pDeviceCap; 1115 1142 uint32_t cbVirtioCaps = 0; 1116 1143 1117 /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CAP_T) */ 1144 /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T) 1145 * as a mandatory but suboptimal alternative interface to host device capabilities, facilitating 1146 * access the memory of any BAR. If the guest uses it (the VirtIO driver on Linux doesn't), 1147 * Unlike Common, Notify, ISR and Device capabilities, it is accessed directly via PCI Config region. 1148 * therefore does not contribute to the capabilities region (BAR) the other capabilities use. 1149 */ 1118 1150 pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1119 pVirtio->uPciC onfigDataOffset = 0x40 + sizeof(VIRTIO_PCI_CAP_T);1151 pVirtio->uPciCfgDataOff = uCfgCapOffset + RT_OFFSETOF(VIRTIO_PCI_CFG_CAP_T, uPciCfgData); 1120 1152 PVIRTIO_PCI_CAP_T pCfg = (PVIRTIO_PCI_CAP_T)pVirtio->pPciCfgCap; 1121 1153 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; … … 1123 1155 pCfg->uCapLen = sizeof(VIRTIO_PCI_CFG_CAP_T); 1124 1156 pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG; 1125 pCfg->uBar = uVirtio Region;1126 pCfg->uOffset = pVirtio->uPciCfgCapOffset = 0;1127 pCfg->uLength = sizeof(VIRTIO_PCI_CFG_CAP_T);1157 pCfg->uBar = uVirtioCapRegion; 1158 pCfg->uOffset = 4; 1159 pCfg->uLength = 4; /* Initially make non-zero 4-byte aligned so Linux Virtio impl's scan doesn't reject this cap */ 1128 1160 cbVirtioCaps += pCfg->uLength; 1129 1161 1130 /* Capability will bemapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/1162 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/ 1131 1163 pCfg = pCommonCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1132 1164 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; … … 1134 1166 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1135 1167 pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG; 1136 pCfg->uBar = uVirtioRegion; 1137 pCfg->uOffset = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset + sizeof(VIRTIO_PCI_CFG_CAP_T); 1168 pCfg->uBar = uVirtioCapRegion; 1169 pCfg->uOffset = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset 1170 + pVirtio->pPciCfgCap->pciCap.uLength; 1138 1171 pCfg->uLength = sizeof(VIRTIO_PCI_COMMON_CFG_T); 1139 1172 cbVirtioCaps += pCfg->uLength; 1140 1173 1141 /* Capability will bemapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/1174 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/ 1142 1175 pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1143 1176 pCfg = (PVIRTIO_PCI_CAP_T)pNotifyCap; … … 1146 1179 pCfg->uCapLen = sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1147 1180 pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG; 1148 pCfg->uBar = uVirtio Region;1181 pCfg->uBar = uVirtioCapRegion; 1149 1182 pCfg->uOffset = pVirtio->uNotifyCapOffset = pCommonCfg->uOffset + sizeof(VIRTIO_PCI_COMMON_CFG_T); 1150 1183 pCfg->uLength = sizeof(VIRTIO_PCI_NOTIFY_CAP_T); … … 1152 1185 cbVirtioCaps += pCfg->uLength; 1153 1186 1154 /* Capability will bemapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T) */1187 /* Following capability mapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T) */ 1155 1188 pCfg = pIsrCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1156 1189 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1157 pCfg->uCapNext = (uint8_t)(fMsiSupport || cbDevSpecificCap ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0); 1190 pCfg->uCapNext = (uint8_t)(fMsiSupport || pVirtio->fHaveDevSpecificCap 1191 ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0); 1158 1192 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1159 1193 pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG; 1160 pCfg->uBar = uVirtio Region;1194 pCfg->uBar = uVirtioCapRegion; 1161 1195 pCfg->uOffset = pVirtio->uIsrCapOffset = pNotifyCap->pciCap.uOffset + sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1162 1196 pCfg->uLength = sizeof(VIRTIO_PCI_ISR_CAP_T); 1163 1197 cbVirtioCaps += pCfg->uLength; 1164 1198 1165 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP 1166 /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/ 1167 pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1168 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1169 pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0); 1170 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1171 pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG; 1172 pCfg->uBar = uVirtioRegion; 1173 pCfg->uOffset = uDeviceCapOffset->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T); 1174 pCfg->uLength = cbDevSpecificCap; 1175 cbVirtioCaps += pCfg->uLength; 1176 #endif 1199 if (pVirtio->fHaveDevSpecificCap) 1200 { 1201 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/ 1202 pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1203 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1204 pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0); 1205 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1206 pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG; 1207 pCfg->uBar = uVirtioCapRegion; 1208 pCfg->uOffset = pVirtio->uDeviceCapOffset = pIsrCap->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T); 1209 pCfg->uLength = cbDevSpecificCap; 1210 cbVirtioCaps += pCfg->uLength; 1211 } 1177 1212 1178 1213 /* Set offset to first capability and enable PCI dev capabilities */ … … 1193 1228 PCIDevSetCapabilityList(&pVirtio->dev, 0x40); 1194 1229 } 1195 /* 1196 PDMDevHlpPCISetConfigCallbacks(pDevIns, &pVirtio->dev, 1197 virtioPciConfigRead, &pVirtio->pfnPciConfigReadOld, 1198 virtioPciConfigWrite, &pVirtio->pfnPciConfigWriteOld); 1199 */ 1200 rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioRegion, cbVirtioCaps, 1230 1231 rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, cbVirtioCaps, 1201 1232 PCI_ADDRESS_SPACE_MEM, virtioR3Map); 1202 1233 if (RT_FAILURE(rc)) -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r80058 r80108 34 34 /** @} */ 35 35 36 37 36 /** Reserved Feature Bits */ 38 37 #define VIRTIO_F_RING_INDIRECT_DESC RT_BIT_64(28) … … 62 61 #define VIRTIO_STATUS_FAILED 0x80 /** Fatal: Something wrong, guest gave up */ 63 62 #define VIRTIO_STATUS_DEVICE_NEEDS_RESET 0x40 /** Device experienced unrecoverable error */ 64 65 63 66 64 #define VIRTIO_MAX_NQUEUES 256 /** Max queues we allow guest to create */ … … 157 155 uint16_t uQueueMsixVector; /** RW (driver selects MSI-X queue vector) */ 158 156 uint16_t uQueueEnable; /** RW (driver controls usability of queue) */ 159 uint16_t uQueueNotifyOff; /** RO (offset uto virtqueue; see spec) 157 uint16_t uQueueNotifyOff; /** RO (offset uto virtqueue; see spec) */ 160 158 uint64_t uQueueDesc; /** RW (driver writes desc table phys addr) */ 161 159 uint64_t uQueueAvail; /** RW (driver writes avail ring phys addr) */ … … 163 161 } VIRTIO_PCI_COMMON_CFG_T, *PVIRTIO_PCI_COMMON_CFG_T; 164 162 163 /* The following two types are opaque here. The device-specific capabilities are handled 164 * through a callback to the consumer host device driver, where the corresponding 165 * struct is declared, since it cannot be defined in the host-generic section of 166 * the VirtIO specification. */ 167 168 typedef void * PVIRTIO_PCI_DEVICE_CAP_T; 169 typedef struct virtio_pci_device_cap 170 { 171 } VIRTIO_PCI_DEVICE_CAP_T; 172 165 173 typedef struct virtio_pci_notify_cap 166 174 { … … 175 183 * and implement this struct and the macro 176 184 */ 177 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP178 typedef struct virtio_pci_dev_cfg VIRTIO_PCI_DEVICE_CAP_T, *PVIRTIO_PCI_DEVICE_CAP_T;179 #endif180 181 185 typedef struct virtio_pci_cfg_cap { 182 186 struct virtio_pci_cap pciCap; … … 280 284 typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD; 281 285 286 /** @name VirtIO port I/O callbacks. 287 * @{ */ 288 typedef struct VIRTIOCALLBACKS 289 { 290 DECLCALLBACKMEMBER(int, pfnVirtioDevCapRead) 291 (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead); 292 DECLCALLBACKMEMBER(int, pfnVirtioDevCapWrite) 293 (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite); 294 } VIRTIOCALLBACKS, *PVIRTALCALLBACKS; 295 /** @} */ 296 282 297 /** 283 298 * The core (/common) state of the VirtIO PCI device … … 287 302 typedef struct VIRTIOSTATE 288 303 { 289 PDMPCIDEV dev;290 PDMCRITSECT cs; /**< Critical section - what is it protecting? */304 PDMPCIDEV dev; 305 PDMCRITSECT cs; /**< Critical section - what is it protecting? */ 291 306 /* Read-only part, never changes after initialization. */ 292 char szInstance[8]; /**< Instance name, e.g. VNet#1. */ 293 307 char szInstance[8]; /**< Instance name, e.g. VNet#1. */ 308 309 bool fHaveDevSpecificCap; 294 310 #if HC_ARCH_BITS != 64 295 uint32_t padding1;311 uint32_t padding1; 296 312 #endif 297 313 298 314 /** Status LUN: Base interface. */ 299 PDMIBASE IBase;315 PDMIBASE IBase; 300 316 301 317 /** Status LUN: LED port interface. */ 302 PDMILEDPORTS ILed;318 PDMILEDPORTS ILed; 303 319 304 320 /* Read/write part, protected with critical section. */ 305 321 /** Status LED. */ 306 PDMLED led; 307 322 PDMLED led; 323 324 VIRTIOCALLBACKS virtioCallbacks; 308 325 309 326 /** Status LUN: LED connector (peer). */ 310 327 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector; 311 328 312 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */ 313 PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */ 314 PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */ 315 316 /** Base address of PCI capabilities */ 317 RTGCPHYS GCPhysPciCapBase; 318 319 320 /** Callbacks when guest driver reads or writes VirtIO device-specific capabilities(s) */ 321 322 PFNVIRTIODEVCAPWRITE pfnVirtioDevCapWrite; 323 PFNVIRTIODEVCAPREAD pfnVirtioDevCapRead; 324 PFNPCICONFIGREAD pfnPciConfigReadOld; 325 PFNPCICONFIGWRITE pfnPciConfigWriteOld; 326 327 uint8_t uPciConfigDataOffset; 329 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */ 330 PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */ 331 PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */ 332 333 334 uint8_t uPciCfgDataOff; 328 335 #if HC_ARCH_BITS == 64 329 336 uint32_t padding2; … … 364 371 uint64_t uQueueUsed[MAX_QUEUES]; 365 372 373 /** Base address of PCI capabilities */ 374 RTGCPHYS GCPhysPciCapBase; 375 376 uint8_t uVirtioCapRegion; /* Client assigned Virtio dedicated capabilities region*/ 377 378 /** Callbacks when guest driver reads or writes VirtIO device-specific capabilities(s) */ 379 PFNPCICONFIGREAD pfnPciConfigReadOld; 380 PFNPCICONFIGWRITE pfnPciConfigWriteOld; 381 382 366 383 uint32_t uNotifyCapOffset; 367 384 uint32_t uIsrCapOffset; … … 376 393 PVIRTIO_PCI_ISR_CAP_T pGcPhysIsrCap; /** Pointer to MMIO mapped struct */ 377 394 PVIRTIO_PCI_CFG_CAP_T pGcPhysPciCfgCap; /** Pointer to MMIO mapped struct */ 378 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP379 395 PVIRTIO_PCI_DEVICE_CAP_T pGcPhysDeviceCap; /** Pointer to MMIO mapped struct */ 380 #endif381 396 382 397 bool fDeviceConfigInterrupt; … … 385 400 } VIRTIOSTATE, *PVIRTIOSTATE; 386 401 387 /** @name VirtIO port I/O callbacks.388 * @{ */389 typedef struct VIRTIOIOCALLBACKS390 {391 DECLCALLBACKMEMBER(uint64_t, pfnGetHostFeatures)(PVIRTIOSTATE pVirtio);392 DECLCALLBACKMEMBER(int, pfnSetHostFeatures)(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered);393 DECLCALLBACKMEMBER(int, pfnReset)(PVIRTIOSTATE pVirtio);394 /* DECLCALLBACKMEMBER(uint32_t, pfnGetHostMinimalFeatures)(void *pvState); */395 /* DECLCALLBACKMEMBER(int, pfnGetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData); */396 /* DECLCALLBACKMEMBER(int, pfnSetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData); */397 /* DECLCALLBACKMEMBER(void, pfnReady)(void *pvState); */398 } VIRTIOCALLBACKS, *PVIRTIOCALLBACKS, **PPVIRTIOCALLBACKS;399 /** @} */400 401 402 void virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta); 402 403 void *virtioQueryInterface(struct PDMIBASE *pInterface, const char *pszIID); 403 404 404 405 int virtioConstruct(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, int iInstance, PVIRTIOPCIPARAMS pPciParams, 405 PPVIRTIOCALLBACKS ppVirtioCallbacks, const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioRegion,406 const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioCapRegion, 406 407 PFNVIRTIODEVCAPREAD devCapReadCallback, PFNVIRTIODEVCAPWRITE devCapWriteCallback, 407 uint16_t cbDevSpecificCap, uint32_t uNotifyOffMultiplier);408 uint16_t cbDevSpecificCap, bool fHaveDevSpecificCap, uint32_t uNotifyOffMultiplier); 408 409 409 410 int virtioDestruct(PVIRTIOSTATE pVirtio); … … 415 416 int virtioRaiseInterrupt(PVIRTIOSTATE pVirtio, int rcBusy, uint8_t uint8_tIntCause); 416 417 void virtioNotify(PVIRTIOSTATE pVirtio); 418 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered); 417 419 418 420 PVQUEUE virtioAddQueue(PVIRTIOSTATE pVirtio, unsigned uSize, PFNVIRTIOQUEUECALLBACK pfnCallback, const char *pcszName); … … 424 426 void vringSetNotification( PVIRTIOSTATE pVirtio, PVIRTQUEUE pVirtQueue, bool fEnabled); 425 427 426 DECLINLINE(void) showDeviceStatus(uint8_t status)428 DECLINLINE(void) logDeviceStatus(uint8_t status) 427 429 { 428 430 if (status & VIRTIO_STATUS_ACKNOWLEDGE) 429 Log((" ACKNOWLEDGE\n"));431 Log((" ACKNOWLEDGE\n")); 430 432 if (status & VIRTIO_STATUS_DRIVER) 431 Log((" DRIVER\n"));433 Log((" DRIVER\n")); 432 434 if (status & VIRTIO_STATUS_DRIVER_OK) 433 Log((" DRIVER_OK\n"));435 Log((" DRIVER_OK\n")); 434 436 if (status & VIRTIO_STATUS_FEATURES_OK) 435 Log((" FEATURES_OK\n"));437 Log((" FEATURES_OK\n")); 436 438 if (status & VIRTIO_STATUS_FAILED) 437 Log((" FAILED\n"));439 Log((" FAILED\n")); 438 440 if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET) 439 Log((" ACKNOWLEDGE\n"));441 Log((" ACKNOWLEDGE\n")); 440 442 if (status == 0) 441 Log((" RESET\n"));443 Log((" RESET\n")); 442 444 Log(("\n")); 443 445 }
Note:
See TracChangeset
for help on using the changeset viewer.