Changeset 81033 in vbox
- Timestamp:
- Sep 26, 2019 7:44:09 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 133636
- Location:
- trunk/src/VBox/Devices/Bus
- Files:
-
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPCI.cpp
r81031 r81033 920 920 921 921 922 /*923 * Include code we share with the other PCI bus implementation.924 *925 * Note! No #ifdefs, use instant data booleans/flags/whatever. Goal is to926 * completely merge these files! File #1 contains code we write, where927 * as a possible file #2 contains external code if there's any left.928 */929 # include "DevPciMerge1.cpp.h"930 931 932 922 /* -=-=-=-=-=- Saved state -=-=-=-=-=- */ 933 923 … … 1308 1298 PDMPCIBUSREGCC PciBusReg; 1309 1299 PciBusReg.u32Version = PDM_PCIBUSREGCC_VERSION; 1310 PciBusReg.pfnRegisterR3 = pciR3MergedRegister;1300 PciBusReg.pfnRegisterR3 = devpciR3CommonRegisterDevice; 1311 1301 PciBusReg.pfnRegisterMsiR3 = NULL; 1312 1302 PciBusReg.pfnIORegionRegisterR3 = devpciR3CommonIORegionRegister; … … 1755 1745 PDMPCIBUSREGCC PciBusReg; 1756 1746 PciBusReg.u32Version = PDM_PCIBUSREGCC_VERSION; 1757 PciBusReg.pfnRegisterR3 = pcibridgeR3MergedRegisterDevice;1747 PciBusReg.pfnRegisterR3 = devpcibridgeR3CommonRegisterDevice; 1758 1748 PciBusReg.pfnRegisterMsiR3 = NULL; 1759 1749 PciBusReg.pfnIORegionRegisterR3 = devpciR3CommonIORegionRegister; -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r81031 r81033 747 747 #ifdef IN_RING3 748 748 749 /*750 * Include code we share with the other PCI bus implementation.751 *752 * Note! No #ifdefs, use instant data booleans/flags/whatever. Goal is to753 * completely merge these files! File #1 contains code we write, where754 * as a possible file #2 contains external code if there's any left.755 */756 # include "DevPciMerge1.cpp.h"757 758 759 749 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus) 760 750 { … … 818 808 819 809 /* -=-=-=-=-=- PCI Bus Interface Methods (PDMPCIBUSREG) -=-=-=-=-=- */ 810 811 /** 812 * Search for a completely unused device entry (all 8 functions are unused). 813 * 814 * @returns VBox status code. 815 * @param pBus The bus to register with. 816 * @remarks Caller enters the PDM critical section. 817 */ 818 static uint8_t devpciR3CommonFindUnusedDeviceNo(PDEVPCIBUS pBus) 819 { 820 for (uint8_t uPciDevNo = pBus->iDevSearch >> VBOX_PCI_DEVFN_DEV_SHIFT; uPciDevNo < VBOX_PCI_MAX_DEVICES; uPciDevNo++) 821 if ( !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 0)] 822 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 1)] 823 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 2)] 824 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 3)] 825 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 4)] 826 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 5)] 827 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 6)] 828 && !pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, 7)]) 829 return uPciDevNo; 830 return UINT8_MAX; 831 } 832 833 834 835 /** 836 * Registers the device with the specified PCI bus. 837 * 838 * This is shared between the pci bus and pci bridge code. 839 * 840 * @returns VBox status code. 841 * @param pDevIns The PCI bus device instance. 842 * @param pBus The bus to register with. 843 * @param pPciDev The PCI device structure. 844 * @param fFlags Reserved for future use, PDMPCIDEVREG_F_MBZ. 845 * @param uPciDevNo PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, or a specific 846 * device number (0-31). 847 * @param uPciFunNo PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific 848 * function number (0-7). 849 * @param pszName Device name (static but not unique). 850 * 851 * @remarks Caller enters the PDM critical section. 852 */ 853 static int devpciR3CommonRegisterDeviceOnBus(PPDMDEVINS pDevIns, PDEVPCIBUS pBus, PPDMPCIDEV pPciDev, uint32_t fFlags, 854 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName) 855 { 856 RT_NOREF(pDevIns); 857 858 /* 859 * Validate input. 860 */ 861 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 862 AssertPtrReturn(pPciDev, VERR_INVALID_POINTER); 863 AssertReturn(!(fFlags & ~PDMPCIDEVREG_F_VALID_MASK), VERR_INVALID_FLAGS); 864 AssertReturn(uPciDevNo < VBOX_PCI_MAX_DEVICES || uPciDevNo == PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, VERR_INVALID_PARAMETER); 865 AssertReturn(uPciFunNo < VBOX_PCI_MAX_FUNCTIONS || uPciFunNo == PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, VERR_INVALID_PARAMETER); 866 867 /* 868 * Assign device & function numbers. 869 */ 870 871 /* Work the optional assignment flag. */ 872 if (fFlags & PDMPCIDEVREG_F_NOT_MANDATORY_NO) 873 { 874 AssertLogRelMsgReturn(uPciDevNo < VBOX_PCI_MAX_DEVICES && uPciFunNo < VBOX_PCI_MAX_FUNCTIONS, 875 ("PDMPCIDEVREG_F_NOT_MANDATORY_NO not implemented for #Dev=%#x / #Fun=%#x\n", uPciDevNo, uPciFunNo), 876 VERR_NOT_IMPLEMENTED); 877 if (pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo)]) 878 { 879 uPciDevNo = PDMPCIDEVREG_DEV_NO_FIRST_UNUSED; 880 uPciFunNo = PDMPCIDEVREG_FUN_NO_FIRST_UNUSED; 881 } 882 } 883 884 if (uPciDevNo == PDMPCIDEVREG_DEV_NO_FIRST_UNUSED) 885 { 886 /* Just find the next unused device number and we're good. */ 887 uPciDevNo = devpciR3CommonFindUnusedDeviceNo(pBus); 888 AssertLogRelMsgReturn(uPciDevNo < VBOX_PCI_MAX_DEVICES, ("Couldn't find a free spot!\n"), VERR_PDM_TOO_PCI_MANY_DEVICES); 889 if (uPciFunNo == PDMPCIDEVREG_FUN_NO_FIRST_UNUSED) 890 uPciFunNo = 0; 891 } 892 else 893 { 894 /* 895 * Direct assignment of device number can be more complicated. 896 */ 897 PPDMPCIDEV pClash; 898 if (uPciFunNo != PDMPCIDEVREG_FUN_NO_FIRST_UNUSED) 899 { 900 /* In the case of a specified function, we only relocate an existing 901 device if it belongs to a different device instance. Reasoning is 902 that the device should figure out it's own function assignments. 903 Note! We could make this more flexible by relocating functions assigned 904 via PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, but it can wait till it's needed. */ 905 pClash = pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo)]; 906 if (!pClash) 907 { /* likely */ } 908 else if (pClash->Int.s.pDevInsR3 == pPciDev->Int.s.pDevInsR3) 909 AssertLogRelMsgFailedReturn(("PCI Configuration conflict at %u.%u: %s vs %s (same pDevIns)!\n", 910 uPciDevNo, uPciFunNo, pClash->pszNameR3, pszName), 911 VERR_PDM_TOO_PCI_MANY_DEVICES); 912 else if (!pClash->Int.s.fReassignableDevNo) 913 AssertLogRelMsgFailedReturn(("PCI Configuration conflict at %u.%u: %s vs %s (different pDevIns)!\n", 914 uPciDevNo, uPciFunNo, pClash->pszNameR3, pszName), 915 VERR_PDM_TOO_PCI_MANY_DEVICES); 916 } 917 else 918 { 919 /* First unused function slot. Again, we only relocate the whole 920 thing if all the device instance differs, because we otherwise 921 reason that a device should manage its own functions correctly. */ 922 unsigned cSameDevInses = 0; 923 for (uPciFunNo = 0, pClash = NULL; uPciFunNo < VBOX_PCI_MAX_FUNCTIONS; uPciFunNo++) 924 { 925 pClash = pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo)]; 926 if (!pClash) 927 break; 928 cSameDevInses += pClash->Int.s.pDevInsR3 == pPciDev->Int.s.pDevInsR3; 929 } 930 if (!pClash) 931 Assert(uPciFunNo < VBOX_PCI_MAX_FUNCTIONS); 932 else 933 AssertLogRelMsgReturn(cSameDevInses == 0, 934 ("PCI Configuration conflict at %u.* appending %s (%u of %u pDevIns matches)!\n", 935 uPciDevNo, pszName, cSameDevInses, VBOX_PCI_MAX_FUNCTIONS), 936 VERR_PDM_TOO_PCI_MANY_DEVICES); 937 } 938 if (pClash) 939 { 940 /* 941 * Try relocate the existing device. 942 */ 943 /* Check that all functions can be moved. */ 944 for (uint8_t uMoveFun = 0; uMoveFun < VBOX_PCI_MAX_FUNCTIONS; uMoveFun++) 945 { 946 PPDMPCIDEV pMovePciDev = pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uMoveFun)]; 947 AssertLogRelMsgReturn(!pMovePciDev || pMovePciDev->Int.s.fReassignableDevNo, 948 ("PCI Configuration conflict at %u.%u: %s vs %s\n", 949 uPciDevNo, uMoveFun, pMovePciDev->pszNameR3, pszName), 950 VERR_PDM_TOO_PCI_MANY_DEVICES); 951 } 952 953 /* Find a free device number to move it to. */ 954 uint8_t uMoveToDevNo = devpciR3CommonFindUnusedDeviceNo(pBus); 955 Assert(uMoveToDevNo != uPciFunNo); 956 AssertLogRelMsgReturn(uMoveToDevNo < VBOX_PCI_MAX_DEVICES, 957 ("No space to relocate device at %u so '%s' can be placed there instead!\n", uPciFunNo, pszName), 958 VERR_PDM_TOO_PCI_MANY_DEVICES); 959 960 /* Execute the move. */ 961 for (uint8_t uMoveFun = 0; uMoveFun < VBOX_PCI_MAX_FUNCTIONS; uMoveFun++) 962 { 963 PPDMPCIDEV pMovePciDev = pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uMoveFun)]; 964 if (pMovePciDev) 965 { 966 Log(("PCI: Relocating '%s' from %u.%u to %u.%u.\n", pMovePciDev->pszNameR3, uPciDevNo, uMoveFun, uMoveToDevNo, uMoveFun)); 967 pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uMoveFun)] = NULL; 968 pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uMoveToDevNo, uMoveFun)] = pMovePciDev; 969 pMovePciDev->uDevFn = VBOX_PCI_DEVFN_MAKE(uMoveToDevNo, uMoveFun); 970 } 971 } 972 } 973 } 974 975 /* 976 * Now, initialize the rest of the PCI device structure. 977 */ 978 Assert(!pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo)]); 979 pBus->apDevices[VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo)] = pPciDev; 980 981 pPciDev->uDevFn = VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo); 982 pPciDev->Int.s.pBusR3 = pBus; 983 Assert(pBus == PDMINS_2_DATA(pDevIns, PDEVPCIBUS)); 984 pPciDev->Int.s.pfnConfigRead = NULL; 985 pPciDev->Int.s.pfnConfigWrite = NULL; 986 if (pBus->fTypePiix3 && pPciDev->cbConfig > 256) 987 pPciDev->cbConfig = 256; 988 989 /* Remember and mark bridges. */ 990 if (fFlags & PDMPCIDEVREG_F_PCI_BRIDGE) 991 { 992 AssertLogRelMsgReturn(pBus->cBridges < RT_ELEMENTS(pBus->apDevices), 993 ("Number of bridges exceeds the number of possible devices on the bus\n"), 994 VERR_INTERNAL_ERROR_3); 995 pBus->papBridgesR3[pBus->cBridges++] = pPciDev; 996 pciDevSetPci2PciBridge(pPciDev); 997 } 998 999 Log(("PCI: Registered device %d function %d (%#x) '%s'.\n", 1000 uPciDevNo, uPciFunNo, UINT32_C(0x80000000) | (pPciDev->uDevFn << 8), pszName)); 1001 1002 return VINF_SUCCESS; 1003 } 1004 1005 1006 /** 1007 * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3} 1008 */ 1009 DECLCALLBACK(int) devpciR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags, 1010 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName) 1011 { 1012 PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS); 1013 AssertCompileMemberOffset(DEVPCIROOT, PciBus, 0); 1014 return devpciR3CommonRegisterDeviceOnBus(pDevIns, pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName); 1015 } 1016 1017 1018 /** 1019 * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3} 1020 */ 1021 DECLCALLBACK(int) devpcibridgeR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags, 1022 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName) 1023 { 1024 PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS); 1025 return devpciR3CommonRegisterDeviceOnBus(pDevIns, pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName); 1026 } 820 1027 821 1028 … … 3102 3309 PDMPCIBUSREGCC PciBusReg; 3103 3310 PciBusReg.u32Version = PDM_PCIBUSREGCC_VERSION; 3104 PciBusReg.pfnRegisterR3 = pciR3MergedRegister;3311 PciBusReg.pfnRegisterR3 = devpciR3CommonRegisterDevice; 3105 3312 PciBusReg.pfnRegisterMsiR3 = ich9pciRegisterMsi; 3106 3313 PciBusReg.pfnIORegionRegisterR3 = devpciR3CommonIORegionRegister; … … 3430 3637 PDMPCIBUSREGCC PciBusReg; 3431 3638 PciBusReg.u32Version = PDM_PCIBUSREGCC_VERSION; 3432 PciBusReg.pfnRegisterR3 = pcibridgeR3MergedRegisterDevice;3639 PciBusReg.pfnRegisterR3 = devpcibridgeR3CommonRegisterDevice; 3433 3640 PciBusReg.pfnRegisterMsiR3 = ich9pciRegisterMsi; 3434 3641 PciBusReg.pfnIORegionRegisterR3 = devpciR3CommonIORegionRegister; -
trunk/src/VBox/Devices/Bus/DevPciInternal.h
r81031 r81033 203 203 DECLCALLBACK(void) devpciR3InfoPci(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs); 204 204 DECLCALLBACK(void) devpciR3InfoPciIrq(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs); 205 DECLCALLBACK(int) devpciR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags, 206 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName); 207 DECLCALLBACK(int) devpcibridgeR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags, 208 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName); 205 209 DECLCALLBACK(int) devpciR3CommonIORegionRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iRegion, RTGCPHYS cbRegion, 206 210 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback);
Note:
See TracChangeset
for help on using the changeset viewer.