Changeset 80148 in vbox for trunk/src/VBox/Devices/VirtIO
- Timestamp:
- Aug 6, 2019 6:36:58 AM (5 years ago)
- Location:
- trunk/src/VBox/Devices/VirtIO
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r80108 r80148 36 36 #endif 37 37 38 /* These ACCESSOR macros handle the most basic kinds of MMIO accesses to fields 39 * virtio 1.0 spec's virtio_pci_common_cfg avoiding a lot of visual bloat. 40 */ 41 42 /** 43 * If the physical address and access length is within the mapped capability struct 44 * the ptrByType will be set to the mapped capability start. Otherwise ptrByType will be NULL. 45 * 46 * Implied parameters: 47 * GPhysAddr - Physical address accessed (via MMIO callback) 48 * cb - Number of bytes to access 49 * 50 * Actual Parameters: 51 * [IN] pCapStruct - Pointer to MMIO mapped capability struct 52 * [IN] type - Capability struct type 53 * [OUT] result - A pointer of type capType that will be set to a mapped capability 54 * if phys. addr / access len is within it's span. 55 * [OUT] offset - The offset of the physical address into the capability if applicable. 56 */ 57 58 #define MATCH_VIRTIO_CAP_STRUCT(pCapStruct, type, result, offset) \ 59 type *result = NULL; \ 60 if ( GCPhysAddr >= (RTGCPHYS)pCapStruct \ 61 && GCPhysAddr < ((RTGCPHYS)pCapStruct + sizeof(type)) \ 62 && cb <= sizeof(type)) \ 63 { \ 64 offset = GCPhysAddr - (RTGCPHYS)pCapStruct; \ 65 result = (type *)pCapStruct; \ 66 } 67 68 #define LOG_ACCESSOR(member, type) \ 69 LogFunc(("Guest %s 0x%x %s %s\n", fWrite ? "wrote" : "read ", \ 70 *(type *)pv, fWrite ? " to" : "from", #member)); 71 72 #define LOG_INDEXED_ACCESSOR(member, type, idx) \ 73 LogFunc(("Guest %s 0x%x %s %s[%d]\n", fWrite ? "wrote" : "read ", \ 74 *(type *)pv, fWrite ? " to" : "from", #member, idx)); 75 76 #define ACCESSOR(member, type) \ 38 39 /** 40 * Returns true if physical address and access length are within the mapped capability struct. 41 * 42 * Actual Parameters: 43 * [IN] pPhysCapStruct - Pointer to MMIO mapped capability struct 44 * [IN] pCfgCap - Pointer to capability in PCI configuration area 45 * [OUT] fMatched - True if GCPhysAddr is within the physically mapped capability. 46 * 47 * Implied parameters: 48 * [IN] GCPhysAddr - Physical address accessed (via MMIO callback) 49 * [IN] cb - Number of bytes to access 50 * [OUT] result - true or false 51 * 52 */ 53 #define MATCH_VIRTIO_CAP_STRUCT(pGcPhysCapData, pCfgCap, fMatched) \ 54 bool fMatched = false; \ 55 if (pGcPhysCapData && pCfgCap && GCPhysAddr >= (RTGCPHYS)pGcPhysCapData \ 56 && GCPhysAddr < ((RTGCPHYS)pGcPhysCapData + ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \ 57 && cb <= ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \ 58 fMatched = true; 59 60 /** 61 * This macro resolves to boolean true if uoff is within the specified member offset and length. 62 * 63 * Actual Parameters: 64 * [IN] member - Member of VIRTIO_PCI_COMMON_CFG_T 65 * 66 * Implied Parameters: 67 * [IN] uoff - Offset into VIRTIO_PCI_COMMON_CFG_T 68 * [IN] cb - Number of bytes to access 69 * [OUT] result - true or false 70 */ 71 #define COMMON_CFG(member) \ 72 (uoff >= RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \ 73 && uoff < (uint32_t)(RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \ 74 + RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member)) \ 75 && cb <= RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) \ 76 - (uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member))) 77 78 #define LOG_ACCESSOR(member) \ 79 LogFunc(("Guest %s %s[%d:%d]: %.*Rhxs\n", \ 80 fWrite ? "wrote" : "read ", #member, foff, foff + cb, cb, pv)); 81 82 #define LOG_INDEXED_ACCESSOR(member, idx) \ 83 LogFunc(("Guest %s %s[%d][%d:%d]: %.*Rhxs\n", \ 84 fWrite ? "wrote" : "read ", #member, idx, foff, foff + cb, cb, pv)); 85 86 #define ACCESSOR(member) \ 77 87 { \ 88 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \ 78 89 if (fWrite) \ 79 { \ 80 pVirtio->member = *(type *)pv; \ 81 } \ 90 memcpy(((char *)&pVirtio->member) + uoff, (const char *)pv, cb); \ 91 else \ 92 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \ 93 LOG_ACCESSOR(member); \ 94 } 95 96 #define ACCESSOR_WITH_IDX(member, idx) \ 97 { \ 98 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \ 99 if (fWrite) \ 100 memcpy(((char *)(pVirtio->member + idx)) + uoff, (const char *)pv, cb); \ 101 else \ 102 memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uoff), cb); \ 103 LOG_INDEXED_ACCESSOR(member, idx); \ 104 } 105 106 #define ACCESSOR_READONLY(member) \ 107 { \ 108 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \ 109 if (fWrite) \ 110 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \ 82 111 else \ 83 112 { \ 84 *(type *)pv = pVirtio->member; \ 113 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \ 114 LOG_ACCESSOR(member); \ 85 115 } \ 86 LOG_ACCESSOR(member, type); \87 } 88 #define ACCESSOR_ WITH_IDX(member, type, idx) \116 } 117 118 #define ACCESSOR_READONLY_WITH_IDX(member, idx) \ 89 119 { \ 120 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \ 90 121 if (fWrite) \ 91 { \ 92 pVirtio->member[idx] = *(type *)pv; \ 93 } \ 122 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \ 94 123 else \ 95 124 { \ 96 *(type *)pv = pVirtio->member[idx]; \ 97 } \ 98 LOG_INDEXED_ACCESSOR(member, type, idx); \ 99 } 100 101 #define ACCESSOR_READONLY(member, type) \ 102 { \ 103 if (fWrite) \ 104 { \ 105 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \ 106 AssertMsgFailed(("bad access\n")); \ 107 } \ 108 else \ 109 { \ 110 *(type *)pv = pVirtio->member; \ 111 LOG_ACCESSOR(member, type); \ 112 } \ 113 } 114 115 #define ACCESSOR_READONLY_WITH_IDX(member, type, idx) \ 116 { \ 117 if (fWrite) \ 118 { \ 119 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \ 120 AssertMsgFailed(("bad access\n")); \ 121 } \ 122 else \ 123 { \ 124 *(type *)pv = pVirtio->member[idx]; \ 125 LOG_INDEXED_ACCESSOR(member, type, idx); \ 125 memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uoff, cb); \ 126 LOG_INDEXED_ACCESSOR(member, idx); \ 126 127 } \ 127 128 } … … 625 626 * @param cb Number of bytes to read or write 626 627 */ 627 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, void const *pv) 628 629 630 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, unsigned cb, void const *pv) 628 631 { 629 632 int rv = VINF_SUCCESS; 630 if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeature))631 {632 if (fWrite) /* Guest WRITE pCommonCfg->uDeviceFeature */633 {634 AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n"));635 }636 else /* Guest READ pCommonCfg->uDeviceFeature */637 {638 switch(pVirtio->u FeaturesOfferedSelect)633 uint64_t val; 634 if (COMMON_CFG(uDeviceFeatures)) 635 { 636 if (fWrite) /* Guest WRITE pCommonCfg>uDeviceFeatures */ 637 Log(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n")); 638 else /* Guest READ pCommonCfg->uDeviceFeatures */ 639 { 640 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures); 641 switch(pVirtio->uDeviceFeaturesSelect) 639 642 { 640 643 case 0: 641 *(uint32_t *)pv = pVirtio->uFeaturesOffered & 0xffffffff; 642 LogFunc(("Guest read 0x%8x from LO DWORD of uFeaturesOffered\n", *(uint32_t *)pv)); 644 val = pVirtio->uDeviceFeatures & 0xffffffff; 645 memcpy((void *)pv, (const void *)&val, cb); 646 LogFunc(("Guest read uDeviceFeatures(LO)[%d:%d]: %.*Rhxs\n", 647 foff, foff + cb, cb, pv)); 643 648 break; 644 649 case 1: 645 *(uint32_t *)pv = (pVirtio->uFeaturesOffered >> 32) & 0xffffffff; 646 LogFunc(("Guest read 0x%8x from HI DWORD of uFeaturesOffered\n", *(uint32_t *)pv)); 650 val = (pVirtio->uDeviceFeatures >> 32) & 0xffffffff; 651 memcpy((void *)pv, (const void *)&val, cb); 652 LogFunc(("Guest read uDeviceFeatures(HI)[%d:%d]: %.*Rhxs\n", 653 foff, foff + cb, cb, pv)); 647 654 break; 648 655 default: 649 Log(("Guest read uDeviceFeature with out of range selector (%d), returning 0\n",650 pVirtio->uFeaturesOfferedSelect));656 Log(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n", 657 pVirtio->uDeviceFeaturesSelect)); 651 658 } 652 659 } 653 660 } 654 else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeature)) 655 { 656 if (fWrite) /* Guest WRITE pCommonCfg->uDriverFeature */ 657 { 658 switch(pVirtio->uFeaturesOfferedSelect) 661 else if (COMMON_CFG(uDriverFeatures)) 662 { 663 if (fWrite) /* Guest WRITE pCommonCfg->udriverFeatures */ 664 { 665 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures); 666 switch(pVirtio->uDriverFeaturesSelect) 659 667 { 660 668 case 0: 661 pVirtio->uFeaturesAccepted = *(uint32_t *)pv; 662 LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 669 memcpy(&pVirtio->uDriverFeatures, pv, cb); 670 LogFunc(("Guest wrote uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n", 671 foff, foff + cb, cb, pv)); 663 672 break; 664 673 case 1: 665 pVirtio->uFeaturesAccepted = (uint64_t)(*(uint32_t *)pv) << 32; 666 LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 674 memcpy(((char *)&pVirtio->uDriverFeatures) + sizeof(uint32_t), pv, cb); 675 LogFunc(("Guest wrote uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n", 676 foff, foff + cb, cb, pv)); 667 677 break; 668 678 } 669 679 } 670 else /* Guest READ pCommonCfg->uDriverFeature */ 671 { 672 switch(pVirtio->uFeaturesOfferedSelect) 680 else /* Guest READ pCommonCfg->udriverFeatures */ 681 { 682 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures); 683 switch(pVirtio->uDriverFeaturesSelect) 673 684 { 674 685 case 0: 675 *(uint32_t *)pv = pVirtio->uFeaturesAccepted & 0xffffffff; 676 LogFunc(("Guest read 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 686 val = pVirtio->uDriverFeatures & 0xffffffff; 687 memcpy((void *)pv, (const void *)&val, cb); 688 LogFunc(("Guest read uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n", 689 foff, foff + cb, cb, pv)); 677 690 break; 678 691 case 1: 679 *(uint32_t *)pv = (pVirtio->uFeaturesAccepted >> 32) & 0xffffffff; 680 LogFunc(("Guest read 0x%8x from HI DWORD of uFeaturesAccepted\n", *(uint32_t *)pv)); 692 val = (pVirtio->uDriverFeatures >> 32) & 0xffffffff; 693 memcpy((void *)pv, (const void *)&val, cb); 694 LogFunc(("Guest read uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n", 695 foff, foff + cb, cb, pv)); 681 696 break; 697 default: 698 Log(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n", 699 pVirtio->uDriverFeaturesSelect)); 682 700 } 683 701 } 684 702 } 685 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uNumQueues))703 else if (COMMON_CFG(uNumQueues)) 686 704 { 687 705 if (fWrite) 688 { 689 AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n")); 690 } 706 Log(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n")); 691 707 else 692 708 { … … 695 711 } 696 712 } 697 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uDeviceStatus))713 else if (COMMON_CFG(uDeviceStatus)) 698 714 { 699 715 if (fWrite) /* Guest WRITE pCommonCfg->uDeviceStatus */ … … 712 728 } 713 729 } 714 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uMsixConfig))715 { 716 ACCESSOR(uMsixConfig , uint32_t);717 } 718 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatureSelect))719 { 720 ACCESSOR(u FeaturesOfferedSelect, uint32_t);721 } 722 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatureSelect))723 { 724 ACCESSOR(u FeaturesAcceptedSelect, uint32_t);725 } 726 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uConfigGeneration))727 { 728 ACCESSOR_READONLY(uConfigGeneration , uint8_t);729 } 730 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueSelect))731 { 732 ACCESSOR(uQueueSelect , uint16_t);733 } 734 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueSize))735 { 736 ACCESSOR_WITH_IDX(uQueueSize, uint16_t,pVirtio->uQueueSelect);737 } 738 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueMsixVector))739 { 740 ACCESSOR_WITH_IDX(uQueueMsixVector, uint16_t,pVirtio->uQueueSelect);741 } 742 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueEnable))743 { 744 ACCESSOR_WITH_IDX(uQueueEnable, uint16_t,pVirtio->uQueueSelect);745 } 746 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueNotifyOff))747 { 748 ACCESSOR_READONLY_WITH_IDX(uQueueNotifyOff, uint16_t,pVirtio->uQueueSelect);749 } 750 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueDesc))751 { 752 ACCESSOR_WITH_IDX(uQueueDesc, uint64_t,pVirtio->uQueueSelect);753 } 754 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueAvail))755 { 756 ACCESSOR_WITH_IDX(uQueueAvail, uint64_t,pVirtio->uQueueSelect);757 } 758 else if ( uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T,uQueueUsed))759 { 760 ACCESSOR_WITH_IDX(uQueueUsed, uint64_t,pVirtio->uQueueSelect);730 else if (COMMON_CFG(uMsixConfig)) 731 { 732 ACCESSOR(uMsixConfig); 733 } 734 else if (COMMON_CFG(uDeviceFeaturesSelect)) 735 { 736 ACCESSOR(uDeviceFeaturesSelect); 737 } 738 else if (COMMON_CFG(uDriverFeaturesSelect)) 739 { 740 ACCESSOR(uDriverFeaturesSelect); 741 } 742 else if (COMMON_CFG(uConfigGeneration)) 743 { 744 ACCESSOR_READONLY(uConfigGeneration); 745 } 746 else if (COMMON_CFG(uQueueSelect)) 747 { 748 ACCESSOR(uQueueSelect); 749 } 750 else if (COMMON_CFG(uQueueSize)) 751 { 752 ACCESSOR_WITH_IDX(uQueueSize, pVirtio->uQueueSelect); 753 } 754 else if (COMMON_CFG(uQueueMsixVector)) 755 { 756 ACCESSOR_WITH_IDX(uQueueMsixVector, pVirtio->uQueueSelect); 757 } 758 else if (COMMON_CFG(uQueueEnable)) 759 { 760 ACCESSOR_WITH_IDX(uQueueEnable, pVirtio->uQueueSelect); 761 } 762 else if (COMMON_CFG(uQueueNotifyOff)) 763 { 764 ACCESSOR_READONLY_WITH_IDX(uQueueNotifyOff, pVirtio->uQueueSelect); 765 } 766 else if (COMMON_CFG(uQueueDesc)) 767 { 768 ACCESSOR_WITH_IDX(uQueueDesc, pVirtio->uQueueSelect); 769 } 770 else if (COMMON_CFG(uQueueAvail)) 771 { 772 ACCESSOR_WITH_IDX(uQueueAvail, pVirtio->uQueueSelect); 773 } 774 else if (COMMON_CFG(uQueueUsed)) 775 { 776 ACCESSOR_WITH_IDX(uQueueUsed, pVirtio->uQueueSelect); 761 777 } 762 778 else 763 779 { 764 765 AssertMsgFailed(("virtio: Bad common cfg offset \n"));780 LogFunc(("Bad access by guest to virtio_pci_common_cfg: uoff=%d, cb=%d\n", uoff, cb)); 781 rv = VERR_ACCESS_DENIED; 766 782 } 767 783 return rv; … … 786 802 787 803 //#ifdef LOG_ENABLED 788 // LogF lowFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));804 // LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb)); 789 805 //#endif 790 806 791 /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */ 792 793 off_t uoff = 0; 794 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg, uoff); 795 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, VIRTIO_PCI_ISR_CAP_T, pIsrCap, uoff); 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 } 804 if (pCommonCfg) 805 virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uoff, pv); 806 else if (pIsrCap) 807 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap, fDevSpecific); 808 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, pVirtio->pCommonCfgCap, fCommonCfg); 809 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, pVirtio->pIsrCap, fIsrCap); 810 811 if (fDevSpecific) 812 { 813 uint32_t uDevSpecificDataOffset = GCPhysAddr - pVirtio->pGcPhysDeviceCap; 814 rc = pVirtio->virtioCallbacks.pfnVirtioDevCapRead(pDevIns, uDevSpecificDataOffset, pv, cb); 815 } 816 else 817 if (fCommonCfg) 818 { 819 uint32_t uCommonCfgDataOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg; 820 virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uCommonCfgDataOffset, cb, pv); 821 } 822 else 823 if (fIsrCap) 807 824 { 808 825 *(uint8_t *)pv = pVirtio->fQueueInterrupt | pVirtio->fDeviceConfigInterrupt << 1; … … 811 828 else { 812 829 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)); 830 AssertMsgFailed(("virtio: Read outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb)); 816 831 } 817 832 return rc; … … 831 846 PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 832 847 { 833 834 848 RT_NOREF(pvUser); 835 849 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); … … 839 853 // LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb)); 840 854 //#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 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap, fDevSpecific); 857 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, pVirtio->pCommonCfgCap, fCommonCfg); 858 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap, pVirtio->pIsrCap, fIsrCap); 859 860 if (fDevSpecific) 861 { 862 uint32_t uDevSpecificDataOffset = GCPhysAddr - pVirtio->pGcPhysDeviceCap; 863 rc = pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uDevSpecificDataOffset, pv, cb); 864 } 865 else 866 if (fCommonCfg) 867 { 868 uint32_t uCommonCfgDataOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg; 869 virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uCommonCfgDataOffset, cb, pv); 870 } 871 else 872 if (fIsrCap) 855 873 { 856 874 pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1; … … 861 879 else 862 880 { 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 } 867 881 LogFunc(("virtio: Write outside of capabilities region:\nGCPhysAddr=%RGp cb=%RGp,", GCPhysAddr, cb)); 882 } 868 883 return rc; 869 884 } … … 899 914 GCPhysAddress, cb, iRegion)); 900 915 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);916 pVirtio->pGcPhysCommonCfg = GCPhysAddress + pVirtio->pCommonCfgCap->uOffset; 917 pVirtio->pGcPhysNotifyCap = GCPhysAddress + pVirtio->pNotifyCap->pciCap.uOffset; 918 pVirtio->pGcPhysIsrCap = GCPhysAddress + pVirtio->pIsrCap->uOffset; 919 if (pVirtio->fHaveDevSpecificCap) 920 pVirtio->pGcPhysDeviceCap = GCPhysAddress + pVirtio->pDeviceCap->uOffset; 906 921 } 907 922 return rc; … … 926 941 PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE); 927 942 928 if (uAddress == pVirtio->uPciCfgDataOff)943 if (uAddress == (uint64_t)&pVirtio->pPciCfgCap->uPciCfgData) 929 944 { 930 945 /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability … … 1018 1033 static uint64_t virtioGetHostFeatures(PVIRTIOSTATE pVirtio) 1019 1034 { 1020 return pVirtio->u FeaturesAccepted;1035 return pVirtio->uDriverFeatures; 1021 1036 } 1022 1037 … … 1028 1043 * 1029 1044 * @param pState Virtio state 1030 * @param u FeaturesOfferedFeature bits (0-63) to set1031 */ 1032 1033 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t u FeaturesOffered)1034 { 1035 pVirtio->u FeaturesOffered = VIRTIO_F_VERSION_1 | uFeaturesOffered;1045 * @param uDeviceFeatures Feature bits (0-63) to set 1046 */ 1047 1048 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uDeviceFeatures) 1049 { 1050 pVirtio->uDeviceFeatures = VIRTIO_F_VERSION_1 | uDeviceFeatures; 1036 1051 } 1037 1052 … … 1098 1113 pVirtio->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1099 1114 pVirtio->uDeviceStatus = 0; 1115 pVirtio->cbDevSpecificCap = cbDevSpecificCap; 1100 1116 pVirtio->uVirtioCapRegion = uVirtioCapRegion; 1101 1117 pVirtio->fHaveDevSpecificCap = fHaveDevSpecificCap; … … 1137 1153 #endif 1138 1154 1139 uint8_t uCfgCapOffset = 0x40; 1140 PVIRTIO_PCI_NOTIFY_CAP_T pNotifyCap; 1141 PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap, pDeviceCap; 1142 uint32_t cbVirtioCaps = 0; 1155 #define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig) 1143 1156 1144 1157 /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T) … … 1148 1161 * therefore does not contribute to the capabilities region (BAR) the other capabilities use. 1149 1162 */ 1150 pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1151 pVirtio->uPciCfgDataOff = uCfgCapOffset + RT_OFFSETOF(VIRTIO_PCI_CFG_CAP_T, uPciCfgData); 1152 PVIRTIO_PCI_CAP_T pCfg = (PVIRTIO_PCI_CAP_T)pVirtio->pPciCfgCap; 1163 PVIRTIO_PCI_CAP_T pCfg; 1164 1165 /* Common capability (VirtIO 1.0 spec) */ 1166 pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[0x40]; 1167 pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG; 1153 1168 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1154 pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_CFG_CAP_T); 1169 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1170 pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen; 1171 pCfg->uBar = uVirtioCapRegion; 1172 pCfg->uOffset = 0; 1173 pCfg->uLength = sizeof(VIRTIO_PCI_COMMON_CFG_T); 1174 pVirtio->pCommonCfgCap = pCfg; 1175 1176 /* Notify capability (VirtIO 1.0 spec) */ 1177 pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext]; 1178 pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG; 1179 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1180 pCfg->uCapLen = sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1181 pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen; 1182 pCfg->uBar = uVirtioCapRegion; 1183 pCfg->uOffset = pVirtio->pCommonCfgCap->uOffset + pVirtio->pCommonCfgCap->uLength; 1184 pCfg->uLength = 4; /* This needs to be calculated differently */ 1185 pVirtio->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg; 1186 pVirtio->pNotifyCap->uNotifyOffMultiplier = uNotifyOffMultiplier; 1187 1188 /* ISR capability (VirtIO 1.0 spec) */ 1189 pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext]; 1190 pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG; 1191 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1192 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1193 pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen; 1194 pCfg->uBar = uVirtioCapRegion; 1195 pCfg->uOffset = pVirtio->pNotifyCap->pciCap.uOffset + pVirtio->pNotifyCap->pciCap.uLength; 1196 pCfg->uLength = sizeof(uint32_t); 1197 pVirtio->pIsrCap = pCfg; 1198 1199 /* PCI Cfg capability (VirtIO 1.0 spec) */ 1200 pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext]; 1201 pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG; 1202 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1155 1203 pCfg->uCapLen = sizeof(VIRTIO_PCI_CFG_CAP_T); 1156 pCfg->uC fgType = VIRTIO_PCI_CAP_PCI_CFG;1204 pCfg->uCapNext = (fMsiSupport || pVirtio->fHaveDevSpecificCap) ? CFGADDR2IDX(pCfg) + pCfg->uCapLen : 0; 1157 1205 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 */ 1160 cbVirtioCaps += pCfg->uLength; 1161 1162 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/ 1163 pCfg = pCommonCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1164 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1165 pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T); 1166 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1167 pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG; 1168 pCfg->uBar = uVirtioCapRegion; 1169 pCfg->uOffset = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset 1170 + pVirtio->pPciCfgCap->pciCap.uLength; 1171 pCfg->uLength = sizeof(VIRTIO_PCI_COMMON_CFG_T); 1172 cbVirtioCaps += pCfg->uLength; 1173 1174 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/ 1175 pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1176 pCfg = (PVIRTIO_PCI_CAP_T)pNotifyCap; 1177 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1178 pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1179 pCfg->uCapLen = sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1180 pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG; 1181 pCfg->uBar = uVirtioCapRegion; 1182 pCfg->uOffset = pVirtio->uNotifyCapOffset = pCommonCfg->uOffset + sizeof(VIRTIO_PCI_COMMON_CFG_T); 1183 pCfg->uLength = sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1184 pNotifyCap->uNotifyOffMultiplier = uNotifyOffMultiplier; 1185 cbVirtioCaps += pCfg->uLength; 1186 1187 /* Following capability mapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T) */ 1188 pCfg = pIsrCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1189 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1190 pCfg->uCapNext = (uint8_t)(fMsiSupport || pVirtio->fHaveDevSpecificCap 1191 ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0); 1192 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1193 pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG; 1194 pCfg->uBar = uVirtioCapRegion; 1195 pCfg->uOffset = pVirtio->uIsrCapOffset = pNotifyCap->pciCap.uOffset + sizeof(VIRTIO_PCI_NOTIFY_CAP_T); 1196 pCfg->uLength = sizeof(VIRTIO_PCI_ISR_CAP_T); 1197 cbVirtioCaps += pCfg->uLength; 1206 pCfg->uOffset = pVirtio->pIsrCap->uOffset + pVirtio->pIsrCap->uLength; 1207 pCfg->uLength = 4; /* Initialize a non-zero 4-byte aligned so Linux virtio_pci module recognizes this cap */ 1208 pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg; 1198 1209 1199 1210 if (pVirtio->fHaveDevSpecificCap) 1200 1211 { 1201 1212 /* Following capability mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/ 1202 pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset]; 1213 pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext]; 1214 pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG; 1203 1215 pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR; 1204 pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0);1205 1216 pCfg->uCapLen = sizeof(VIRTIO_PCI_CAP_T); 1206 pCfg->uC fgType = VIRTIO_PCI_CAP_DEVICE_CFG;1217 pCfg->uCapNext = fMsiSupport ? CFGADDR2IDX(pCfg) + pCfg->uCapLen : 0; 1207 1218 pCfg->uBar = uVirtioCapRegion; 1208 pCfg->uOffset = pVirtio-> uDeviceCapOffset = pIsrCap->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T);1219 pCfg->uOffset = pVirtio->pIsrCap->uOffset + pVirtio->pIsrCap->uLength; 1209 1220 pCfg->uLength = cbDevSpecificCap; 1210 cbVirtioCaps += pCfg->uLength;1221 pVirtio->pDeviceCap = pCfg; 1211 1222 } 1212 1223 … … 1219 1230 PDMMSIREG aMsiReg; 1220 1231 RT_ZERO(aMsiReg); 1221 aMsiReg.iMsixCapOffset = uCfgCapOffset;1232 aMsiReg.iMsixCapOffset = pCfg->uCapNext; 1222 1233 aMsiReg.iMsixNextOffset = 0; 1223 1234 aMsiReg.iMsixBar = 0; … … 1229 1240 } 1230 1241 1231 rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, cbVirtioCaps,1242 rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, 4096, 1232 1243 PCI_ADDRESS_SPACE_MEM, virtioR3Map); 1233 1244 if (RT_FAILURE(rc)) -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r80108 r80148 141 141 142 142 /* Per device fields */ 143 uint32_t uDeviceFeature Select; /** RW (driver selects device features) */144 uint32_t uDeviceFeature ; /** RO (device reports features to driver) */145 uint32_t uDriverFeature Select; /** RW (driver selects driver features) */146 uint32_t uDriverFeature ; /** RW (driver accepts device features) */143 uint32_t uDeviceFeaturesSelect; /** RW (driver selects device features) */ 144 uint32_t uDeviceFeatures; /** RO (device reports features to driver) */ 145 uint32_t uDriverFeaturesSelect; /** RW (driver selects driver features) */ 146 uint32_t uDriverFeatures; /** RW (driver accepts device features) */ 147 147 uint16_t uMsixConfig; /** RW (driver sets MSI-X config vector) */ 148 148 uint16_t uNumQueues; /** RO (device specifies max queues) */ … … 177 177 } VIRTIO_PCI_NOTIFY_CAP_T, *PVIRTIO_PCI_NOTIFY_CAP_T; 178 178 179 typedef uint8_t VIRTIO_PCI_ISR_CAP_T, *PVIRTIO_PCI_ISR_CAP_T;180 181 179 /* 182 180 * If the client of this library has any device-specific capabilities, it must define … … 278 276 */ 279 277 280 typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite); 278 /** 279 * VirtIO Device-specific capabilities read callback 280 * (other VirtIO capabilities and features are handled in VirtIO implementation) 281 * 282 * @param pDevIns The device instance. 283 * @param offset Offset within device specific capabilities struct 284 * @param pvBuf Buffer in which to save read data 285 * @param cbWrite Number of bytes to write 286 */ 287 typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite); 281 288 typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE; 282 289 283 typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead); 290 /** 291 * VirtIO Device-specific capabilities read callback 292 * (other VirtIO capabilities and features are handled in VirtIO implementation) 293 * 294 * @param pDevIns The device instance. 295 * @param offset Offset within device specific capabilities struct 296 * @param pvBuf Buffer in which to save read data 297 * @param cbRead Number of bytes to read 298 */ 299 typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead); 284 300 typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD; 285 301 … … 289 305 { 290 306 DECLCALLBACKMEMBER(int, pfnVirtioDevCapRead) 291 (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead);307 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead); 292 308 DECLCALLBACKMEMBER(int, pfnVirtioDevCapWrite) 293 (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite);309 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite); 294 310 } VIRTIOCALLBACKS, *PVIRTALCALLBACKS; 295 311 /** @} */ … … 307 323 char szInstance[8]; /**< Instance name, e.g. VNet#1. */ 308 324 309 bool fHaveDevSpecificCap;310 325 #if HC_ARCH_BITS != 64 311 326 uint32_t padding1; … … 352 367 VQUEUE Queues[VIRTIO_MAX_NQUEUES]; 353 368 354 uint32_t u FeaturesOfferedSelect; /** Select hi/lo 32-bit uFeaturesOfferedto r/w */355 uint64_t u FeaturesOffered; /** Host features offered */356 uint32_t u FeaturesAcceptedSelect; /** Selects hi/lo 32-bit uFeaturesAcceptedto r/w*/357 uint64_t u FeaturesAccepted;/** Host features accepted by guest */369 uint32_t uDeviceFeaturesSelect; /** Select hi/lo 32-bit uDeviceFeatures to r/w */ 370 uint64_t uDeviceFeatures; /** Host features offered */ 371 uint32_t uDriverFeaturesSelect; /** Selects hi/lo 32-bit uDriverFeatures to r/w*/ 372 uint64_t uDriverFeatures; /** Host features accepted by guest */ 358 373 359 374 uint32_t uMsixConfig; … … 371 386 uint64_t uQueueUsed[MAX_QUEUES]; 372 387 373 /** Base address of PCI capabilities */374 RTGCPHYS GCPhysPciCapBase;375 388 376 389 uint8_t uVirtioCapRegion; /* Client assigned Virtio dedicated capabilities region*/ … … 380 393 PFNPCICONFIGWRITE pfnPciConfigWriteOld; 381 394 382 383 uint32_t uNotifyCapOffset; 384 uint32_t uIsrCapOffset; 385 uint32_t uPciCfgCapOffset; 386 uint32_t uDeviceCapOffset; 387 uint32_t uCommonCfgOffset; 395 bool fHaveDevSpecificCap; 396 uint32_t cbDevSpecificCap; 388 397 389 398 PVIRTIO_PCI_CFG_CAP_T pPciCfgCap; /** Pointer to struct in configuration area */ 390 391 PVIRTIO_PCI_COMMON_CFG_T pGcPhysCommonCfg; /** Pointer to MMIO mapped struct */ 392 PVIRTIO_PCI_NOTIFY_CAP_T pGcPhysNotifyCap; /** Pointer to MMIO mapped struct */ 393 PVIRTIO_PCI_ISR_CAP_T pGcPhysIsrCap; /** Pointer to MMIO mapped struct */ 394 PVIRTIO_PCI_CFG_CAP_T pGcPhysPciCfgCap; /** Pointer to MMIO mapped struct */ 395 PVIRTIO_PCI_DEVICE_CAP_T pGcPhysDeviceCap; /** Pointer to MMIO mapped struct */ 399 PVIRTIO_PCI_NOTIFY_CAP_T pNotifyCap; /** Pointer to struct in configuration area */ 400 PVIRTIO_PCI_CAP_T pCommonCfgCap; /** Pointer to struct in configuration area */ 401 PVIRTIO_PCI_CAP_T pIsrCap; /** Pointer to struct in configuration area */ 402 PVIRTIO_PCI_CAP_T pDeviceCap; /** Pointer to struct in configuration area */ 403 404 /** Base address of PCI capabilities */ 405 RTGCPHYS GCPhysPciCapBase; 406 RTGCPHYS pGcPhysCommonCfg; /** Pointer to MMIO mapped capability data */ 407 RTGCPHYS pGcPhysNotifyCap; /** Pointer to MMIO mapped capability data */ 408 RTGCPHYS pGcPhysIsrCap; /** Pointer to MMIO mapped capability data */ 409 RTGCPHYS pGcPhysDeviceCap; /** Pointer to MMIO mapped capability data */ 396 410 397 411 bool fDeviceConfigInterrupt; … … 416 430 int virtioRaiseInterrupt(PVIRTIOSTATE pVirtio, int rcBusy, uint8_t uint8_tIntCause); 417 431 void virtioNotify(PVIRTIOSTATE pVirtio); 418 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t u FeaturesOffered);432 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uDeviceFeatures); 419 433 420 434 PVQUEUE virtioAddQueue(PVIRTIOSTATE pVirtio, unsigned uSize, PFNVIRTIOQUEUECALLBACK pfnCallback, const char *pcszName);
Note:
See TracChangeset
for help on using the changeset viewer.