VirtualBox

Changeset 64373 in vbox


Ignore:
Timestamp:
Oct 23, 2016 7:03:39 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111478
Message:

PDM,Devices: Support for multiple PCI devices/function in a single PDM device.

Location:
trunk
Files:
1 added
43 edited
2 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/include/Makefile.kmk

    r62476 r64373  
    7878        VBox/VDEPlugSymDefs.h \
    7979        VBox/VBoxKeyboard.h \
     80        VBox/vmm/pdmpcidevint.h \
    8081        iprt/runtime-loader.h \
    8182        iprt/mangling.h \
  • trunk/include/VBox/pci.h

    r64274 r64373  
    11/** @file
    2  * PCI - The PCI Controller And Devices. (DEV)
     2 * PCI - The PCI Controller And Devices Constants. (DEV)
    33 */
    44
     
    3636 */
    3737
    38 /** Pointer to a PCI device. */
    39 typedef struct PCIDevice *PPCIDEVICE;
    40 
    4138
    4239/**
     
    7370} PCIADDRESSSPACE;
    7471
    75 
    76 /**
    77  * Callback function for mapping an PCI I/O region.
    78  *
    79  * @return VBox status code.
    80  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    81  * @param   iRegion         The region number.
    82  * @param   GCPhysAddress   Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
    83  *                          is an I/O port, otherwise it's a physical address.
    84  *
    85  *                          NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
    86  *                          that the device deregister access handlers for it and update its internal
    87  *                          state to reflect this.
    88  *
    89  * @param   cb              Size of the region in bytes.
    90  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
    91  *
    92  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    93  *          that is very likely be a lock order violation.
    94  */
    95 typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    96                                            RTGCPHYS cb, PCIADDRESSSPACE enmType);
    97 /** Pointer to a FNPCIIOREGIONMAP() function. */
    98 typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
    9972
    10073
     
    469442
    470443
    471 /**
    472  * Callback function for reading from the PCI configuration space.
    473  *
    474  * @returns The register value.
    475  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    476  * @param   Address         The configuration space register address. [0..4096]
    477  * @param   cb              The register size. [1,2,4]
    478  *
    479  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    480  *          that is very likely be a lock order violation.
    481  */
    482 typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb);
    483 /** Pointer to a FNPCICONFIGREAD() function. */
    484 typedef FNPCICONFIGREAD *PFNPCICONFIGREAD;
    485 /** Pointer to a PFNPCICONFIGREAD. */
    486 typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD;
    487 
    488 /**
    489  * Callback function for writing to the PCI configuration space.
    490  *
    491  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    492  * @param   Address         The configuration space register address. [0..4096]
    493  * @param   u32Value        The value that's being written. The number of bits actually used from
    494  *                          this value is determined by the cb parameter.
    495  * @param   cb              The register size. [1,2,4]
    496  *
    497  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    498  *          that is very likely be a lock order violation.
    499  */
    500 typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
    501 /** Pointer to a FNPCICONFIGWRITE() function. */
    502 typedef FNPCICONFIGWRITE *PFNPCICONFIGWRITE;
    503 /** Pointer to a PFNPCICONFIGWRITE. */
    504 typedef PFNPCICONFIGWRITE *PPFNPCICONFIGWRITE;
    505 
    506444/** Fixed I/O region number for ROM. */
    507 #define PCI_ROM_SLOT    6
    508445#define VBOX_PCI_ROM_SLOT    6
    509446/** Max number of I/O regions. */
    510 #define PCI_NUM_REGIONS 7
    511447#define VBOX_PCI_NUM_REGIONS 7
    512448
    513 /*
    514  * Hack to include the PCIDEVICEINT structure at the right place
    515  * to avoid duplications of FNPCIIOREGIONMAP and PCI_NUM_REGIONS.
    516  */
    517 #ifdef PCI_INCLUDE_PRIVATE
    518 # include "PCIInternal.h"
    519 #endif
    520 
    521 /**
    522  * PCI Device structure.
    523  */
    524 typedef struct PCIDevice
    525 {
    526     /** PCI config space. */
    527     uint8_t                 config[256];
    528 
    529     /** Internal data. */
    530     union
    531     {
    532 #ifdef PCIDEVICEINT_DECLARED
    533         PCIDEVICEINT        s;
    534 #endif
    535         char                padding[328];
    536     } Int;
    537 
    538     /** Read only data.
    539      * @{
    540      */
    541     /** PCI device number on the pci bus. */
    542     int32_t                 devfn;
    543     uint32_t                Alignment0; /**< Alignment. */
    544     /** Device name. */
    545     R3PTRTYPE(const char *) name;
    546     /** Pointer to the device instance which registered the device. */
    547     PPDMDEVINSR3            pDevIns;
    548     /**  @} */
    549 } PCIDEVICE;
    550 
    551 /** @todo handle extended space access. */
    552 
    553 DECLINLINE(void)     PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t offReg, uint8_t u8Value)
    554 {
    555     pPciDev->config[offReg] = u8Value;
    556 }
    557 
    558 DECLINLINE(uint8_t)  PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t offReg)
    559 {
    560     return pPciDev->config[offReg];
    561 }
    562 
    563 DECLINLINE(void)     PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t offReg, uint16_t u16Value)
    564 {
    565     *(uint16_t*)&pPciDev->config[offReg] = RT_H2LE_U16(u16Value);
    566 }
    567 
    568 DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t offReg)
    569 {
    570     uint16_t u16Value = *(uint16_t*)&pPciDev->config[offReg];
    571     return RT_H2LE_U16(u16Value);
    572 }
    573 
    574 DECLINLINE(void)     PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t offReg, uint32_t u32Value)
    575 {
    576     *(uint32_t*)&pPciDev->config[offReg] = RT_H2LE_U32(u32Value);
    577 }
    578 
    579 DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t offReg)
    580 {
    581     uint32_t u32Value = *(uint32_t*)&pPciDev->config[offReg];
    582     return RT_H2LE_U32(u32Value);
    583 }
    584 
    585 DECLINLINE(void)     PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t offReg, uint64_t u64Value)
    586 {
    587     *(uint64_t*)&pPciDev->config[offReg] = RT_H2LE_U64(u64Value);
    588 }
    589 
    590 DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t offReg)
    591 {
    592     uint64_t u64Value = *(uint64_t*)&pPciDev->config[offReg];
    593     return RT_H2LE_U64(u64Value);
    594 }
    595 
    596 /**
    597  * Sets the vendor id config register.
    598  * @param   pPciDev         The PCI device.
    599  * @param   u16VendorId     The vendor id.
    600  */
    601 DECLINLINE(void) PCIDevSetVendorId(PPCIDEVICE pPciDev, uint16_t u16VendorId)
    602 {
    603     PCIDevSetWord(pPciDev, VBOX_PCI_VENDOR_ID, u16VendorId);
    604 }
    605 
    606 /**
    607  * Gets the vendor id config register.
    608  * @returns the vendor id.
    609  * @param   pPciDev         The PCI device.
    610  */
    611 DECLINLINE(uint16_t) PCIDevGetVendorId(PPCIDEVICE pPciDev)
    612 {
    613     return PCIDevGetWord(pPciDev, VBOX_PCI_VENDOR_ID);
    614 }
    615 
    616 
    617 /**
    618  * Sets the device id config register.
    619  * @param   pPciDev         The PCI device.
    620  * @param   u16DeviceId     The device id.
    621  */
    622 DECLINLINE(void) PCIDevSetDeviceId(PPCIDEVICE pPciDev, uint16_t u16DeviceId)
    623 {
    624     PCIDevSetWord(pPciDev, VBOX_PCI_DEVICE_ID, u16DeviceId);
    625 }
    626 
    627 /**
    628  * Gets the device id config register.
    629  * @returns the device id.
    630  * @param   pPciDev         The PCI device.
    631  */
    632 DECLINLINE(uint16_t) PCIDevGetDeviceId(PPCIDEVICE pPciDev)
    633 {
    634     return PCIDevGetWord(pPciDev, VBOX_PCI_DEVICE_ID);
    635 }
    636 
    637 /**
    638  * Sets the command config register.
    639  *
    640  * @param   pPciDev         The PCI device.
    641  * @param   u16Command      The command register value.
    642  */
    643 DECLINLINE(void) PCIDevSetCommand(PPCIDEVICE pPciDev, uint16_t u16Command)
    644 {
    645     PCIDevSetWord(pPciDev, VBOX_PCI_COMMAND, u16Command);
    646 }
    647 
    648 
    649 /**
    650  * Gets the command config register.
    651  * @returns The command register value.
    652  * @param   pPciDev         The PCI device.
    653  */
    654 DECLINLINE(uint16_t) PCIDevGetCommand(PPCIDEVICE pPciDev)
    655 {
    656     return PCIDevGetWord(pPciDev, VBOX_PCI_COMMAND);
    657 }
    658 
    659 /**
    660  * Checks if the given PCI device is a bus master.
    661  * @returns true if the device is a bus master, false if not.
    662  * @param   pPciDev         The PCI device.
    663  */
    664 DECLINLINE(bool) PCIDevIsBusmaster(PPCIDEVICE pPciDev)
    665 {
    666     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
    667 }
    668 
    669 /**
    670  * Checks if INTx interrupts disabled in the command config register.
    671  * @returns true if disabled.
    672  * @param   pPciDev         The PCI device.
    673  */
    674 DECLINLINE(bool) PCIDevIsIntxDisabled(PPCIDEVICE pPciDev)
    675 {
    676     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
    677 }
    678 
    679 /**
    680  * Gets the status config register.
    681  *
    682  * @returns status config register.
    683  * @param   pPciDev         The PCI device.
    684  */
    685 DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
    686 {
    687     return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
    688 }
    689 
    690 /**
    691  * Sets the status config register.
    692  *
    693  * @param   pPciDev         The PCI device.
    694  * @param   u16Status       The status register value.
    695  */
    696 DECLINLINE(void) PCIDevSetStatus(PPCIDEVICE pPciDev, uint16_t u16Status)
    697 {
    698     PCIDevSetWord(pPciDev, VBOX_PCI_STATUS, u16Status);
    699 }
    700 
    701 
    702 /**
    703  * Sets the revision id config register.
    704  *
    705  * @param   pPciDev         The PCI device.
    706  * @param   u8RevisionId    The revision id.
    707  */
    708 DECLINLINE(void) PCIDevSetRevisionId(PPCIDEVICE pPciDev, uint8_t u8RevisionId)
    709 {
    710     PCIDevSetByte(pPciDev, VBOX_PCI_REVISION_ID, u8RevisionId);
    711 }
    712 
    713 
    714 /**
    715  * Sets the register level programming class config register.
    716  *
    717  * @param   pPciDev         The PCI device.
    718  * @param   u8ClassProg     The new value.
    719  */
    720 DECLINLINE(void) PCIDevSetClassProg(PPCIDEVICE pPciDev, uint8_t u8ClassProg)
    721 {
    722     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_PROG, u8ClassProg);
    723 }
    724 
    725 
    726 /**
    727  * Sets the sub-class (aka device class) config register.
    728  *
    729  * @param   pPciDev         The PCI device.
    730  * @param   u8SubClass      The sub-class.
    731  */
    732 DECLINLINE(void) PCIDevSetClassSub(PPCIDEVICE pPciDev, uint8_t u8SubClass)
    733 {
    734     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_SUB, u8SubClass);
    735 }
    736 
    737 
    738 /**
    739  * Sets the base class config register.
    740  *
    741  * @param   pPciDev         The PCI device.
    742  * @param   u8BaseClass     The base class.
    743  */
    744 DECLINLINE(void) PCIDevSetClassBase(PPCIDEVICE pPciDev, uint8_t u8BaseClass)
    745 {
    746     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_BASE, u8BaseClass);
    747 }
    748 
    749 /**
    750  * Sets the header type config register.
    751  *
    752  * @param   pPciDev         The PCI device.
    753  * @param   u8HdrType       The header type.
    754  */
    755 DECLINLINE(void) PCIDevSetHeaderType(PPCIDEVICE pPciDev, uint8_t u8HdrType)
    756 {
    757     PCIDevSetByte(pPciDev, VBOX_PCI_HEADER_TYPE, u8HdrType);
    758 }
    759 
    760 /**
    761  * Gets the header type config register.
    762  *
    763  * @param   pPciDev         The PCI device.
    764  * @returns u8HdrType       The header type.
    765  */
    766 DECLINLINE(uint8_t) PCIDevGetHeaderType(PPCIDEVICE pPciDev)
    767 {
    768     return PCIDevGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
    769 }
    770 
    771 /**
    772  * Sets the BIST (built-in self-test) config register.
    773  *
    774  * @param   pPciDev         The PCI device.
    775  * @param   u8Bist          The BIST value.
    776  */
    777 DECLINLINE(void) PCIDevSetBIST(PPCIDEVICE pPciDev, uint8_t u8Bist)
    778 {
    779     PCIDevSetByte(pPciDev, VBOX_PCI_BIST, u8Bist);
    780 }
    781 
    782 /**
    783  * Gets the BIST (built-in self-test) config register.
    784  *
    785  * @param   pPciDev         The PCI device.
    786  * @returns u8Bist          The BIST.
    787  */
    788 DECLINLINE(uint8_t) PCIDevGetBIST(PPCIDEVICE pPciDev)
    789 {
    790     return PCIDevGetByte(pPciDev, VBOX_PCI_BIST);
    791 }
    792 
    793 
    794 /**
    795  * Sets a base address config register.
    796  *
    797  * @param   pPciDev         The PCI device.
    798  * @param   iReg            Base address register number (0..5).
    799  * @param   fIOSpace        Whether it's I/O (true) or memory (false) space.
    800  * @param   fPrefetchable   Whether the memory is prefetachable. Must be false if fIOSpace == true.
    801  * @param   f64Bit          Whether the memory can be mapped anywhere in the 64-bit address space. Otherwise restrict to 32-bit.
    802  * @param   u32Addr         The address value.
    803  */
    804 DECLINLINE(void) PCIDevSetBaseAddress(PPCIDEVICE pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit,
    805                                       uint32_t u32Addr)
    806 {
    807     if (fIOSpace)
    808     {
    809         Assert(!(u32Addr & 0x3)); Assert(!fPrefetchable); Assert(!f64Bit);
    810         u32Addr |= RT_BIT_32(0);
    811     }
    812     else
    813     {
    814         Assert(!(u32Addr & 0xf));
    815         if (fPrefetchable)
    816             u32Addr |= RT_BIT_32(3);
    817         if (f64Bit)
    818             u32Addr |= 0x2 << 1;
    819     }
    820     switch (iReg)
    821     {
    822         case 0: iReg = VBOX_PCI_BASE_ADDRESS_0; break;
    823         case 1: iReg = VBOX_PCI_BASE_ADDRESS_1; break;
    824         case 2: iReg = VBOX_PCI_BASE_ADDRESS_2; break;
    825         case 3: iReg = VBOX_PCI_BASE_ADDRESS_3; break;
    826         case 4: iReg = VBOX_PCI_BASE_ADDRESS_4; break;
    827         case 5: iReg = VBOX_PCI_BASE_ADDRESS_5; break;
    828         default: AssertFailedReturnVoid();
    829     }
    830 
    831     PCIDevSetDWord(pPciDev, iReg, u32Addr);
    832 }
    833 
    834 /**
    835  * Please document me. I don't seem to be getting as much as calculating
    836  * the address of some PCI region.
    837  */
    838 DECLINLINE(uint32_t) PCIDevGetRegionReg(uint32_t iRegion)
    839 {
    840     return iRegion == VBOX_PCI_ROM_SLOT
    841          ? VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
    842 }
    843 
    844 /**
    845  * Sets the sub-system vendor id config register.
    846  *
    847  * @param   pPciDev             The PCI device.
    848  * @param   u16SubSysVendorId   The sub-system vendor id.
    849  */
    850 DECLINLINE(void) PCIDevSetSubSystemVendorId(PPCIDEVICE pPciDev, uint16_t u16SubSysVendorId)
    851 {
    852     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID, u16SubSysVendorId);
    853 }
    854 
    855 /**
    856  * Gets the sub-system vendor id config register.
    857  * @returns the sub-system vendor id.
    858  * @param   pPciDev         The PCI device.
    859  */
    860 DECLINLINE(uint16_t) PCIDevGetSubSystemVendorId(PPCIDEVICE pPciDev)
    861 {
    862     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID);
    863 }
    864 
    865 
    866 /**
    867  * Sets the sub-system id config register.
    868  *
    869  * @param   pPciDev         The PCI device.
    870  * @param   u16SubSystemId  The sub-system id.
    871  */
    872 DECLINLINE(void) PCIDevSetSubSystemId(PPCIDEVICE pPciDev, uint16_t u16SubSystemId)
    873 {
    874     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID, u16SubSystemId);
    875 }
    876 
    877 /**
    878  * Gets the sub-system id config register.
    879  * @returns the sub-system id.
    880  * @param   pPciDev         The PCI device.
    881  */
    882 DECLINLINE(uint16_t) PCIDevGetSubSystemId(PPCIDEVICE pPciDev)
    883 {
    884     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID);
    885 }
    886 
    887 /**
    888  * Sets offset to capability list.
    889  *
    890  * @param   pPciDev         The PCI device.
    891  * @param   u8Offset        The offset to capability list.
    892  */
    893 DECLINLINE(void) PCIDevSetCapabilityList(PPCIDEVICE pPciDev, uint8_t u8Offset)
    894 {
    895     PCIDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
    896 }
    897 
    898 /**
    899  * Returns offset to capability list.
    900  *
    901  * @returns offset to capability list.
    902  * @param   pPciDev         The PCI device.
    903  */
    904 DECLINLINE(uint8_t) PCIDevGetCapabilityList(PPCIDEVICE pPciDev)
    905 {
    906     return PCIDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
    907 }
    908 
    909 /**
    910  * Sets the interrupt line config register.
    911  *
    912  * @param   pPciDev         The PCI device.
    913  * @param   u8Line          The interrupt line.
    914  */
    915 DECLINLINE(void) PCIDevSetInterruptLine(PPCIDEVICE pPciDev, uint8_t u8Line)
    916 {
    917     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE, u8Line);
    918 }
    919 
    920 /**
    921  * Gets the interrupt line config register.
    922  *
    923  * @returns The interrupt line.
    924  * @param   pPciDev         The PCI device.
    925  */
    926 DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev)
    927 {
    928     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE);
    929 }
    930 
    931 /**
    932  * Sets the interrupt pin config register.
    933  *
    934  * @param   pPciDev         The PCI device.
    935  * @param   u8Pin           The interrupt pin.
    936  */
    937 DECLINLINE(void) PCIDevSetInterruptPin(PPCIDEVICE pPciDev, uint8_t u8Pin)
    938 {
    939     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN, u8Pin);
    940 }
    941 
    942 /**
    943  * Gets the interrupt pin config register.
    944  *
    945  * @returns The interrupt pin.
    946  * @param   pPciDev         The PCI device.
    947  */
    948 DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev)
    949 {
    950     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN);
    951 }
    952 
    953 #ifdef PCIDEVICEINT_DECLARED
    954 DECLINLINE(void) pciDevSetRequestedDevfunc(PPCIDEVICE pDev)
    955 {
    956     pDev->Int.s.fFlags |= PCIDEV_FLAG_REQUESTED_DEVFUNC;
    957 }
    958 
    959 DECLINLINE(void) pciDevClearRequestedDevfunc(PPCIDEVICE pDev)
    960 {
    961     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_REQUESTED_DEVFUNC;
    962 }
    963 
    964 DECLINLINE(bool) pciDevIsRequestedDevfunc(PPCIDEVICE pDev)
    965 {
    966     return (pDev->Int.s.fFlags & PCIDEV_FLAG_REQUESTED_DEVFUNC) != 0;
    967 }
    968 
    969 DECLINLINE(void) pciDevSetPci2PciBridge(PPCIDEVICE pDev)
    970 {
    971     pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_TO_PCI_BRIDGE;
    972 }
    973 
    974 DECLINLINE(bool) pciDevIsPci2PciBridge(PPCIDEVICE pDev)
    975 {
    976     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_TO_PCI_BRIDGE) != 0;
    977 }
    978 
    979 DECLINLINE(void) pciDevSetPciExpress(PPCIDEVICE pDev)
    980 {
    981     pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_EXPRESS_DEVICE;
    982 }
    983 
    984 DECLINLINE(bool) pciDevIsPciExpress(PPCIDEVICE pDev)
    985 {
    986     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_EXPRESS_DEVICE) != 0;
    987 }
    988 
    989 DECLINLINE(void) pciDevSetMsiCapable(PPCIDEVICE pDev)
    990 {
    991     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI_CAPABLE;
    992 }
    993 
    994 DECLINLINE(void) pciDevClearMsiCapable(PPCIDEVICE pDev)
    995 {
    996     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI_CAPABLE;
    997 }
    998 
    999 DECLINLINE(bool) pciDevIsMsiCapable(PPCIDEVICE pDev)
    1000 {
    1001     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI_CAPABLE) != 0;
    1002 }
    1003 
    1004 DECLINLINE(void) pciDevSetMsi64Capable(PPCIDEVICE pDev)
    1005 {
    1006     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI64_CAPABLE;
    1007 }
    1008 
    1009 DECLINLINE(void) pciDevClearMsi64Capable(PPCIDEVICE pDev)
    1010 {
    1011     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI64_CAPABLE;
    1012 }
    1013 
    1014 DECLINLINE(bool) pciDevIsMsi64Capable(PPCIDEVICE pDev)
    1015 {
    1016     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI64_CAPABLE) != 0;
    1017 }
    1018 
    1019 DECLINLINE(void) pciDevSetMsixCapable(PPCIDEVICE pDev)
    1020 {
    1021     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSIX_CAPABLE;
    1022 }
    1023 
    1024 DECLINLINE(void) pciDevClearMsixCapable(PPCIDEVICE pDev)
    1025 {
    1026     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSIX_CAPABLE;
    1027 }
    1028 
    1029 DECLINLINE(bool) pciDevIsMsixCapable(PPCIDEVICE pDev)
    1030 {
    1031     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSIX_CAPABLE) != 0;
    1032 }
    1033 
    1034 DECLINLINE(void) pciDevSetPassthrough(PPCIDEVICE pDev)
    1035 {
    1036     pDev->Int.s.fFlags |= PCIDEV_FLAG_PASSTHROUGH;
    1037 }
    1038 
    1039 DECLINLINE(void) pciDevClearPassthrough(PPCIDEVICE pDev)
    1040 {
    1041     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_PASSTHROUGH;
    1042 }
    1043 
    1044 DECLINLINE(bool) pciDevIsPassthrough(PPCIDEVICE pDev)
    1045 {
    1046     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PASSTHROUGH) != 0;
    1047 }
    1048 
    1049 #endif /* PCIDEVICEINT_DECLARED */
     449#define PCI_ROM_SLOT         VBOX_PCI_ROM_SLOT    /**< deprecated */
     450#define PCI_NUM_REGIONS      VBOX_PCI_NUM_REGIONS /**< deprecated */
     451
     452/** Number of functions per device. */
     453#define VBOX_PCI_MAX_FUNCTIONS      8
     454/** Number of devices per bus. */
     455#define VBOX_PCI_MAX_DEVICES        32
     456/** The device number shift count for a device+function number. */
     457#define VBOX_PCI_DEVFN_DEV_SHIFT    3
     458/** The device number shift count for a device+function number. */
     459#define VBOX_PCI_DEVFN_FUN_MASK     0x7
     460/** Make a device+function number.   */
     461#define VBOX_PCI_DEVFN_MAKE(a_uPciDevNo, a_uPciFunNo) (((a_uPciDevNo) << VBOX_PCI_DEVFN_DEV_SHIFT) | (a_uPciFunNo))
     462
    1050463
    1051464#if defined(__cplusplus) && defined(IN_RING3)
    1052465/* For RTStrPrintf(). */
    1053 #include <iprt/string.h>
     466# include <iprt/string.h>
    1054467
    1055468/**
     
    1182595    static const size_t cMaxAddrSize = 10;
    1183596};
    1184 #endif /* __cplusplus */
     597
     598#endif /* __cplusplus && IN_RING3 */
    1185599
    1186600/** @} */
  • trunk/include/VBox/types.h

    r62476 r64373  
    341341typedef RCPTRTYPE(PPDMDEVINS) PPDMDEVINSRC;
    342342
     343/** Pointer to a PDM PCI device structure. */
     344typedef struct PDMPCIDEV *PPDMPCIDEV;
     345
    343346/** Pointer to a PDM USB Device Instance. */
    344347typedef struct PDMUSBINS *PPDMUSBINS;
  • trunk/include/VBox/vmm/iom.h

    r64115 r64373  
    350350                                         RCPTRTYPE(PFNIOMMMIOFILL)  pfnFillCallback);
    351351VMMR3_INT_DECL(int)  IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange);
    352 VMMR3_INT_DECL(int)  IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRange,
     352VMMR3_INT_DECL(int)  IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRange,
    353353                                            uint32_t fFlags, const char *pszDesc,
    354354                                            RTR3PTR pvUserR3,
  • trunk/include/VBox/vmm/mm.h

    r63660 r64373  
    278278VMMR3DECL(int)      MMR3HyperMapHCPhys(PVM pVM, void *pvR3, RTR0PTR pvR0, RTHCPHYS HCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
    279279VMMR3DECL(int)      MMR3HyperMapGCPhys(PVM pVM, RTGCPHYS GCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
    280 VMMR3DECL(int)      MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);
     280VMMR3DECL(int)      MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);
    281281VMMR3DECL(int)      MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages, const char *pszDesc, PRTGCPTR pGCPtr);
    282282VMMR3DECL(int)      MMR3HyperReserve(PVM pVM, unsigned cb, const char *pszDesc, PRTGCPTR pGCPtr);
  • trunk/include/VBox/vmm/pdmdev.h

    r64369 r64373  
    3333#include <VBox/vmm/pdmins.h>
    3434#include <VBox/vmm/pdmcommon.h>
     35#include <VBox/vmm/pdmpcidev.h>
    3536#include <VBox/vmm/iom.h>
    3637#include <VBox/vmm/tm.h>
     
    537538     * @param   pDevIns         Device instance of the PCI Bus.
    538539     * @param   pPciDev         The PCI device structure.
    539      *                          Any PCI enabled device must keep this in it's instance data!
    540      *                          Fill in the PCI data config before registration, please.
    541      * @param   pszName         Pointer to device name (permanent, readonly). For debugging, not unique.
    542      * @param   iDev            The device number ((dev << 3) | function) the device should have on the bus.
    543      *                          If negative, the pci bus device will assign one.
     540     * @param   fFlags          Reserved for future use, PDMPCIDEVREG_F_MBZ.
     541     * @param   uPciDevNo       PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, or a specific
     542     *                          device number (0-31).
     543     * @param   uPciFunNo       PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
     544     *                          function number (0-7).
     545     * @param   pszName         Device name (static but not unique).
     546     *
    544547     * @remarks Caller enters the PDM critical section.
    545548     */
    546     DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
     549    DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t fFlags,
     550                                             uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
    547551
    548552    /**
     
    555559     * @remarks Caller enters the PDM critical section.
    556560     */
    557     DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
     561    DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
    558562
    559563    /**
     
    569573     * @remarks Caller enters the PDM critical section.
    570574     */
    571     DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, RTGCPHYS cbRegion,
     575    DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iRegion, RTGCPHYS cbRegion,
    572576                                                     PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
    573577
     
    588592     * @thread  EMT
    589593     */
    590     DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev,
     594    DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
    591595                                                        PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
    592596                                                        PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
     
    602606     * @remarks Caller enters the PDM critical section.
    603607     */
    604     DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
     608    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
    605609
    606610    /**
    607611     * Called to perform the job of the bios.
     612     *
    608613     * This is only called for the first PCI Bus - it is expected to
    609614     * service all the PCI buses.
     
    626631
    627632/** Current PDMPCIBUSREG version number. */
    628 #define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 5, 0)
     633#define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 6, 0)
    629634
    630635/**
     
    23322337#ifdef IN_RING3
    23332338
     2339/** @name Special values for PDMDEVHLPR3::pfnPCIRegister parameters.
     2340 * @{  */
     2341/** Use the primary device configruation (0). */
     2342# define PDMPCIDEVREG_CFG_PRIMARY           0
     2343/** Use the next device configuration number in the sequence (max + 1). */
     2344# define PDMPCIDEVREG_CFG_NEXT              UINT32_MAX
     2345/** Same device number as the previous PCI device registered with the PDM device.
     2346 * This is handy when registering multiple PCI device functions
     2347 * and the device number is left up to the PCI bus. */
     2348# define PDMPCIDEVREG_DEV_NO_SAME_AS_PREV   UINT8_C(0xfd)
     2349/** Use the first unused device number (all functions must be unused). */
     2350# define PDMPCIDEVREG_DEV_NO_FIRST_UNUSED   UINT8_C(0xfe)
     2351/** Use the first unused device function. */
     2352# define PDMPCIDEVREG_FUN_NO_FIRST_UNUSED   UINT8_C(0xff)
     2353
     2354/** The device and function numbers are not mandatory, just suggestions. */
     2355# define PDMPCIDEVREG_F_NOT_MANDATORY_NO    RT_BIT_32(0)
     2356/** Registering a PCI bridge device. */
     2357# define PDMPCIDEVREG_F_PCI_BRIDGE          RT_BIT_32(1)
     2358/** Valid flag mask. */
     2359# define PDMPCIDEVREG_F_VALID_MASK          UINT32_C(0x00000003)
     2360/** @}   */
     2361
    23342362/**
    23352363 * PDM Device API.
     
    25122540     * @returns VBox status.
    25132541     * @param   pDevIns             The device instance.
     2542     * @param   pPciDev             The PCI device the region is associated with, or
     2543     *                              NULL if no PCI device association.
    25142544     * @param   iRegion             The region number. Use the PCI region number as
    25152545     *                              this must be known to the PCI bus device too. If
     
    25242554     * @thread  EMT.
    25252555     */
    2526     DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags,
    2527                                                 void **ppv, const char *pszDesc));
    2528 
    2529     /**
    2530      * Deregisters and frees a MMIO or MMIO2 region.
    2531      *
    2532      * Any physical (and virtual) access handlers registered for the region must
    2533      * be deregistered before calling this function (MMIO2 only).
    2534      *
    2535      * @returns VBox status code.
    2536      * @param   pDevIns             The device instance.
    2537      * @param   iRegion             The region number used during registration.
    2538      * @thread  EMT.
    2539      */
    2540     DECLR3CALLBACKMEMBER(int, pfnMMIOExDeregister,(PPDMDEVINS pDevIns, uint32_t iRegion));
    2541 
    2542     /**
    2543      * Maps a MMIO or MMIO2 region into the physical memory space.
    2544      *
    2545      * A MMIO2 range or a pre-registered MMIO range may overlap with base memory if
    2546      * a lot of RAM is configured for the VM, in  which case we'll drop the base
    2547      * memory pages.  Presently we will make no attempt to preserve anything that
    2548      * happens to be present in the base memory that is replaced, this is of course
    2549      * incorrect but it's too much effort.
    2550      *
    2551      * @returns VBox status code.
    2552      * @param   pDevIns             The device instance.
    2553      * @param   iRegion             The region number used during registration.
    2554      * @param   GCPhys              The physical address to map it at.
    2555      * @thread  EMT.
    2556      */
    2557     DECLR3CALLBACKMEMBER(int, pfnMMIOExMap,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
    2558 
    2559     /**
    2560      * Unmaps a MMIO or MMIO2 region previously mapped using pfnMMIOExMap.
    2561      *
    2562      * @returns VBox status code.
    2563      * @param   pDevIns             The device instance.
    2564      * @param   iRegion             The region number used during registration.
    2565      * @param   GCPhys              The physical address it's currently mapped at.
    2566      * @thread  EMT.
    2567      */
    2568     DECLR3CALLBACKMEMBER(int, pfnMMIOExUnmap,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
    2569 
    2570     /**
    2571      * Maps a portion of an MMIO2 region into the hypervisor region.
    2572      *
    2573      * Callers of this API must never deregister the MMIO2 region before the
    2574      * VM is powered off.
    2575      *
    2576      * @return VBox status code.
    2577      * @param   pDevIns             The device owning the MMIO2 memory.
    2578      * @param   iRegion             The region.
    2579      * @param   off                 The offset into the region. Will be rounded down
    2580      *                              to closest page boundary.
    2581      * @param   cb                  The number of bytes to map. Will be rounded up
    2582      *                              to the closest page boundary.
    2583      * @param   pszDesc             Mapping description.
    2584      * @param   pRCPtr              Where to store the RC address.
    2585      */
    2586     DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    2587                                                   const char *pszDesc, PRTRCPTR pRCPtr));
    2588 
    2589     /**
    2590      * Maps a portion of an MMIO2 region into kernel space (host).
    2591      *
    2592      * The kernel mapping will become invalid when the MMIO2 memory is deregistered
    2593      * or the VM is terminated.
    2594      *
    2595      * @return VBox status code.
    2596      * @param   pDevIns             The device owning the MMIO2 memory.
    2597      * @param   iRegion             The region.
    2598      * @param   off                 The offset into the region. Must be page
    2599      *                              aligned.
    2600      * @param   cb                  The number of bytes to map. Must be page
    2601      *                              aligned.
    2602      * @param   pszDesc             Mapping description.
    2603      * @param   pR0Ptr              Where to store the R0 address.
    2604      */
    2605     DECLR3CALLBACKMEMBER(int, pfnMMIO2MapKernel,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    2606                                                   const char *pszDesc, PRTR0PTR pR0Ptr));
    2607 
    2608     /**
    2609      * Register a ROM (BIOS) region.
    2610      *
    2611      * It goes without saying that this is read-only memory. The memory region must be
    2612      * in unassigned memory. I.e. from the top of the address space or on the PC in
    2613      * the 0xa0000-0xfffff range.
    2614      *
    2615      * @returns VBox status.
    2616      * @param   pDevIns             The device instance owning the ROM region.
    2617      * @param   GCPhysStart         First physical address in the range.
    2618      *                              Must be page aligned!
    2619      * @param   cbRange             The size of the range (in bytes).
    2620      *                              Must be page aligned!
    2621      * @param   pvBinary            Pointer to the binary data backing the ROM image.
    2622      * @param   cbBinary            The size of the binary pointer.  This must
    2623      *                              be equal or smaller than @a cbRange.
    2624      * @param   fFlags              Shadow ROM flags, PGMPHYS_ROM_FLAGS_* in pgm.h.
    2625      * @param   pszDesc             Pointer to description string. This must not be freed.
    2626      *
    2627      * @remark  There is no way to remove the rom, automatically on device cleanup or
    2628      *          manually from the device yet. At present I doubt we need such features...
    2629      */
    2630     DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
    2631                                               const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
    2632 
    2633     /**
    2634      * Changes the protection of shadowed ROM mapping.
    2635      *
    2636      * This is intented for use by the system BIOS, chipset or device in question to
    2637      * change the protection of shadowed ROM code after init and on reset.
    2638      *
    2639      * @param   pDevIns             The device instance.
    2640      * @param   GCPhysStart         Where the mapping starts.
    2641      * @param   cbRange             The size of the mapping.
    2642      * @param   enmProt             The new protection type.
    2643      */
    2644     DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt));
    2645 
    2646     /**
    2647      * Register a save state data unit.
    2648      *
    2649      * @returns VBox status.
    2650      * @param   pDevIns             The device instance.
    2651      * @param   uVersion            Data layout version number.
    2652      * @param   cbGuess             The approximate amount of data in the unit.
    2653      *                              Only for progress indicators.
    2654      * @param   pszBefore           Name of data unit which we should be put in
    2655      *                              front of. Optional (NULL).
    2656      *
    2657      * @param   pfnLivePrep         Prepare live save callback, optional.
    2658      * @param   pfnLiveExec         Execute live save callback, optional.
    2659      * @param   pfnLiveVote         Vote live save callback, optional.
    2660      *
    2661      * @param   pfnSavePrep         Prepare save callback, optional.
    2662      * @param   pfnSaveExec         Execute save callback, optional.
    2663      * @param   pfnSaveDone         Done save callback, optional.
    2664      *
    2665      * @param   pfnLoadPrep         Prepare load callback, optional.
    2666      * @param   pfnLoadExec         Execute load callback, optional.
    2667      * @param   pfnLoadDone         Done load callback, optional.
    2668      * @remarks Caller enters the device critical section prior to invoking the
    2669      *          registered callback methods.
    2670      */
    2671     DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
    2672                                               PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
    2673                                               PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
    2674                                               PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
    2675 
    2676     /**
    2677      * Creates a timer.
    2678      *
    2679      * @returns VBox status.
    2680      * @param   pDevIns             The device instance.
    2681      * @param   enmClock            The clock to use on this timer.
    2682      * @param   pfnCallback         Callback function.
    2683      * @param   pvUser              User argument for the callback.
    2684      * @param   fFlags              Flags, see TMTIMER_FLAGS_*.
    2685      * @param   pszDesc             Pointer to description string which must stay around
    2686      *                              until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
    2687      * @param   ppTimer             Where to store the timer on success.
    2688      * @remarks Caller enters the device critical section prior to invoking the
    2689      *          callback.
    2690      */
    2691     DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
    2692                                                 void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
    2693 
    2694     /**
    2695      * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
    2696      *
    2697      * @returns pTime.
    2698      * @param   pDevIns             The device instance.
    2699      * @param   pTime               Where to store the time.
    2700      */
    2701     DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
    2702 
    2703     /**
    2704      * Read physical memory.
    2705      *
    2706      * @returns VINF_SUCCESS (for now).
    2707      * @param   pDevIns             The device instance.
    2708      * @param   GCPhys              Physical address start reading from.
    2709      * @param   pvBuf               Where to put the read bits.
    2710      * @param   cbRead              How many bytes to read.
    2711      * @thread  Any thread, but the call may involve the emulation thread.
    2712      */
    2713     DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
    2714 
    2715     /**
    2716      * Write to physical memory.
    2717      *
    2718      * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
    2719      * @param   pDevIns             The device instance.
    2720      * @param   GCPhys              Physical address to write to.
    2721      * @param   pvBuf               What to write.
    2722      * @param   cbWrite             How many bytes to write.
    2723      * @thread  Any thread, but the call may involve the emulation thread.
    2724      */
    2725     DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
    2726 
    2727     /**
    2728      * Requests the mapping of a guest page into ring-3.
    2729      *
    2730      * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
    2731      * release it.
    2732      *
    2733      * This API will assume your intention is to write to the page, and will
    2734      * therefore replace shared and zero pages. If you do not intend to modify the
    2735      * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
    2736      *
    2737      * @returns VBox status code.
    2738      * @retval  VINF_SUCCESS on success.
    2739      * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
    2740      *          backing or if the page has any active access handlers. The caller
    2741      *          must fall back on using PGMR3PhysWriteExternal.
    2742      * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
    2743      *
    2744      * @param   pDevIns             The device instance.
    2745      * @param   GCPhys              The guest physical address of the page that
    2746      *                              should be mapped.
    2747      * @param   fFlags              Flags reserved for future use, MBZ.
    2748      * @param   ppv                 Where to store the address corresponding to
    2749      *                              GCPhys.
    2750      * @param   pLock               Where to store the lock information that
    2751      *                              pfnPhysReleasePageMappingLock needs.
    2752      *
    2753      * @remark  Avoid calling this API from within critical sections (other than the
    2754      *          PGM one) because of the deadlock risk when we have to delegating the
    2755      *          task to an EMT.
    2756      * @thread  Any.
    2757      */
    2758     DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv,
    2759                                                    PPGMPAGEMAPLOCK pLock));
    2760 
    2761     /**
    2762      * Requests the mapping of a guest page into ring-3, external threads.
    2763      *
    2764      * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
    2765      * release it.
    2766      *
    2767      * @returns VBox status code.
    2768      * @retval  VINF_SUCCESS on success.
    2769      * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
    2770      *          backing or if the page as an active ALL access handler. The caller
    2771      *          must fall back on using PGMPhysRead.
    2772      * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
    2773      *
    2774      * @param   pDevIns             The device instance.
    2775      * @param   GCPhys              The guest physical address of the page that
    2776      *                              should be mapped.
    2777      * @param   fFlags              Flags reserved for future use, MBZ.
    2778      * @param   ppv                 Where to store the address corresponding to
    2779      *                              GCPhys.
    2780      * @param   pLock               Where to store the lock information that
    2781      *                              pfnPhysReleasePageMappingLock needs.
    2782      *
    2783      * @remark  Avoid calling this API from within critical sections.
    2784      * @thread  Any.
    2785      */
    2786     DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags,
    2787                                                            void const **ppv, PPGMPAGEMAPLOCK pLock));
    2788 
    2789     /**
    2790      * Release the mapping of a guest page.
    2791      *
    2792      * This is the counter part of pfnPhysGCPhys2CCPtr and
    2793      * pfnPhysGCPhys2CCPtrReadOnly.
    2794      *
    2795      * @param   pDevIns             The device instance.
    2796      * @param   pLock               The lock structure initialized by the mapping
    2797      *                              function.
    2798      */
    2799     DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
    2800 
    2801     /**
    2802      * Read guest physical memory by virtual address.
    2803      *
    2804      * @param   pDevIns             The device instance.
    2805      * @param   pvDst               Where to put the read bits.
    2806      * @param   GCVirtSrc           Guest virtual address to start reading from.
    2807      * @param   cb                  How many bytes to read.
    2808      * @thread  The emulation thread.
    2809      */
    2810     DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
    2811 
    2812     /**
    2813      * Write to guest physical memory by virtual address.
    2814      *
    2815      * @param   pDevIns             The device instance.
    2816      * @param   GCVirtDst           Guest virtual address to write to.
    2817      * @param   pvSrc               What to write.
    2818      * @param   cb                  How many bytes to write.
    2819      * @thread  The emulation thread.
    2820      */
    2821     DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
    2822 
    2823     /**
    2824      * Convert a guest virtual address to a guest physical address.
    2825      *
    2826      * @returns VBox status code.
    2827      * @param   pDevIns             The device instance.
    2828      * @param   GCPtr               Guest virtual address.
    2829      * @param   pGCPhys             Where to store the GC physical address
    2830      *                              corresponding to GCPtr.
    2831      * @thread  The emulation thread.
    2832      * @remark  Careful with page boundaries.
    2833      */
    2834     DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
    2835 
    2836     /**
    2837      * Allocate memory which is associated with current VM instance
    2838      * and automatically freed on it's destruction.
    2839      *
    2840      * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
    2841      * @param   pDevIns             The device instance.
    2842      * @param   cb                  Number of bytes to allocate.
    2843      */
    2844     DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
    2845 
    2846     /**
    2847      * Allocate memory which is associated with current VM instance
    2848      * and automatically freed on it's destruction. The memory is ZEROed.
    2849      *
    2850      * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
    2851      * @param   pDevIns             The device instance.
    2852      * @param   cb                  Number of bytes to allocate.
    2853      */
    2854     DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
    2855 
    2856     /**
    2857      * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
    2858      *
    2859      * @param   pDevIns             The device instance.
    2860      * @param   pv                  Pointer to the memory to free.
    2861      */
    2862     DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
    2863 
    2864     /**
    2865      * Gets the VM state.
    2866      *
    2867      * @returns VM state.
    2868      * @param   pDevIns             The device instance.
    2869      * @thread  Any thread (just keep in mind that it's volatile info).
    2870      */
    2871     DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
    2872 
    2873     /**
    2874      * Checks if the VM was teleported and hasn't been fully resumed yet.
    2875      *
    2876      * @returns true / false.
    2877      * @param   pDevIns             The device instance.
    2878      * @thread  Any thread.
    2879      */
    2880     DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
    2881 
    2882     /**
    2883      * Set the VM error message
    2884      *
    2885      * @returns rc.
    2886      * @param   pDevIns             The device instance.
    2887      * @param   rc                  VBox status code.
    2888      * @param   SRC_POS             Use RT_SRC_POS.
    2889      * @param   pszFormat           Error message format string.
    2890      * @param   ...                 Error message arguments.
    2891      */
    2892     DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
    2893                                              const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
    2894 
    2895     /**
    2896      * Set the VM error message
    2897      *
    2898      * @returns rc.
    2899      * @param   pDevIns             The device instance.
    2900      * @param   rc                  VBox status code.
    2901      * @param   SRC_POS             Use RT_SRC_POS.
    2902      * @param   pszFormat           Error message format string.
    2903      * @param   va                  Error message arguments.
    2904      */
    2905     DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
    2906                                               const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
    2907 
    2908     /**
    2909      * Set the VM runtime error message
    2910      *
    2911      * @returns VBox status code.
    2912      * @param   pDevIns             The device instance.
    2913      * @param   fFlags              The action flags. See VMSETRTERR_FLAGS_*.
    2914      * @param   pszErrorId          Error ID string.
    2915      * @param   pszFormat           Error message format string.
    2916      * @param   ...                 Error message arguments.
    2917      */
    2918     DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
    2919                                                     const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5));
    2920 
    2921     /**
    2922      * Set the VM runtime error message
    2923      *
    2924      * @returns VBox status code.
    2925      * @param   pDevIns             The device instance.
    2926      * @param   fFlags              The action flags. See VMSETRTERR_FLAGS_*.
    2927      * @param   pszErrorId          Error ID string.
    2928      * @param   pszFormat           Error message format string.
    2929      * @param   va                  Error message arguments.
    2930      */
    2931     DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
    2932                                                      const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
    2933 
    2934     /**
    2935      * Stops the VM and enters the debugger to look at the guest state.
    2936      *
    2937      * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
    2938      * invoking this function directly.
    2939      *
    2940      * @returns VBox status code which must be passed up to the VMM.
    2941      * @param   pDevIns             The device instance.
    2942      * @param   pszFile             Filename of the assertion location.
    2943      * @param   iLine               The linenumber of the assertion location.
    2944      * @param   pszFunction         Function of the assertion location.
    2945      * @param   pszFormat           Message. (optional)
    2946      * @param   args                Message parameters.
    2947      */
    2948     DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction,
    2949                                             const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(5, 0));
    2950 
    2951     /**
    2952      * Register a info handler with DBGF,
    2953      *
    2954      * @returns VBox status code.
    2955      * @param   pDevIns             The device instance.
    2956      * @param   pszName             The identifier of the info.
    2957      * @param   pszDesc             The description of the info and any arguments
    2958      *                              the handler may take.
    2959      * @param   pfnHandler          The handler function to be called to display the
    2960      *                              info.
    2961      */
    2962     DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
    2963 
    2964     /**
    2965      * Registers a set of registers for a device.
    2966      *
    2967      * The @a pvUser argument of the getter and setter callbacks will be
    2968      * @a pDevIns.  The register names will be prefixed by the device name followed
    2969      * immediately by the instance number.
    2970      *
    2971      * @returns VBox status code.
    2972      * @param   pDevIns             The device instance.
    2973      * @param   paRegisters         The register descriptors.
    2974      *
    2975      * @remarks The device critical section is NOT entered prior to working the
    2976      *          callbacks registered via this helper!
    2977      */
    2978     DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters));
    2979 
    2980     /**
    2981      * Gets the trace buffer handle.
    2982      *
    2983      * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
    2984      * really inteded for direct usage, thus no inline wrapper function.
    2985      *
    2986      * @returns Trace buffer handle or NIL_RTTRACEBUF.
    2987      * @param   pDevIns             The device instance.
    2988      */
    2989     DECLR3CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
    2990 
    2991     /**
    2992      * Registers a statistics sample if statistics are enabled.
    2993      *
    2994      * @param   pDevIns             Device instance of the DMA.
    2995      * @param   pvSample            Pointer to the sample.
    2996      * @param   enmType             Sample type. This indicates what pvSample is
    2997      *                              pointing at.
    2998      * @param   pszName             Sample name. The name is on this form
    2999      *                              "/<component>/<sample>". Further nesting is
    3000      *                              possible.
    3001      * @param   enmUnit             Sample unit.
    3002      * @param   pszDesc             Sample description.
    3003      */
    3004     DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
    3005 
    3006     /**
    3007      * Same as pfnSTAMRegister except that the name is specified in a
    3008      * RTStrPrintf like fashion.
    3009      *
    3010      * @returns VBox status.
    3011      * @param   pDevIns             Device instance of the DMA.
    3012      * @param   pvSample            Pointer to the sample.
    3013      * @param   enmType             Sample type. This indicates what pvSample is
    3014      *                              pointing at.
    3015      * @param   enmVisibility       Visibility type specifying whether unused
    3016      *                              statistics should be visible or not.
    3017      * @param   enmUnit             Sample unit.
    3018      * @param   pszDesc             Sample description.
    3019      * @param   pszName             The sample name format string.
    3020      * @param   ...                 Arguments to the format string.
    3021      */
    3022     DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
    3023                                                  STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
    3024                                                  const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8));
    3025 
    3026     /**
    3027      * Same as pfnSTAMRegister except that the name is specified in a
    3028      * RTStrPrintfV like fashion.
    3029      *
    3030      * @returns VBox status.
    3031      * @param   pDevIns             Device instance of the DMA.
    3032      * @param   pvSample            Pointer to the sample.
    3033      * @param   enmType             Sample type. This indicates what pvSample is
    3034      *                              pointing at.
    3035      * @param   enmVisibility       Visibility type specifying whether unused
    3036      *                              statistics should be visible or not.
    3037      * @param   enmUnit             Sample unit.
    3038      * @param   pszDesc             Sample description.
    3039      * @param   pszName             The sample name format string.
    3040      * @param   args                Arguments to the format string.
    3041      */
    3042     DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
    3043                                                  STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
    3044                                                  const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0));
    3045 
    3046     /**
    3047      * Registers the device with the default PCI bus.
    3048      *
    3049      * @returns VBox status code.
    3050      * @param   pDevIns             The device instance.
    3051      * @param   pPciDev             The PCI device structure.
    3052      *                              Any PCI enabled device must keep this in it's instance data!
    3053      *                              Fill in the PCI data config before registration, please.
    3054      * @remark  This is the simple interface, a Ex interface will be created if
    3055      *          more features are needed later.
    3056      */
    3057     DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev));
    3058 
    3059     /**
    3060      * Initialize MSI support in a PCI device.
    3061      *
    3062      * @returns VBox status code.
    3063      * @param   pDevIns         The device instance.
    3064      * @param   pMsiReg         MSI registartion structure.
    3065      */
    3066     DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg));
    3067 
    3068     /**
    3069      * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
    3070      *
    3071      * @returns VBox status code.
    3072      * @param   pDevIns             The device instance.
    3073      * @param   iRegion             The region number.
    3074      * @param   cbRegion            Size of the region.
    3075      * @param   enmType             PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
    3076      * @param   pfnCallback         Callback for doing the mapping.
    3077      * @remarks The callback will be invoked holding the PDM lock. The device lock
    3078      *          is NOT take because that is very likely be a lock order violation.
    3079      */
    3080     DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, RTGCPHYS cbRegion,
    3081                                                       PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
    3082 
    3083     /**
    3084      * Register PCI configuration space read/write callbacks.
    3085      *
    3086      * @param   pDevIns             The device instance.
    3087      * @param   pPciDev             The PCI device structure.
    3088      *                              If NULL the default PCI device for this device instance is used.
    3089      * @param   pfnRead             Pointer to the user defined PCI config read function.
    3090      * @param   ppfnReadOld         Pointer to function pointer which will receive the old (default)
    3091      *                              PCI config read function. This way, user can decide when (and if)
    3092      *                              to call default PCI config read function. Can be NULL.
    3093      * @param   pfnWrite            Pointer to the user defined PCI config write function.
    3094      * @param   ppfnWriteOld        Pointer to function pointer which will receive
    3095      *                              the old (default) PCI config write function.
    3096      *                              This way, user can decide when (and if) to call
    3097      *                              default PCI config write function. Can be NULL.
    3098      * @remarks The callbacks will be invoked holding the PDM lock. The device lock
    3099      *          is NOT take because that is very likely be a lock order violation.
    3100      * @thread  EMT
    3101      */
    3102     DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev,
    3103                                                          PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
    3104                                                          PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
    3105 
    3106     /**
    3107      * Bus master physical memory read.
    3108      *
    3109      * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
    3110      *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
    3111      * @param   pDevIns             The device instance.
    3112      * @param   GCPhys              Physical address start reading from.
    3113      * @param   pvBuf               Where to put the read bits.
    3114      * @param   cbRead              How many bytes to read.
    3115      * @thread  Any thread, but the call may involve the emulation thread.
    3116      */
    3117     DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
    3118 
    3119     /**
    3120      * Bus master physical memory write.
    3121      *
    3122      * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
    3123      *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
    3124      * @param   pDevIns             The device instance.
    3125      * @param   GCPhys              Physical address to write to.
    3126      * @param   pvBuf               What to write.
    3127      * @param   cbWrite             How many bytes to write.
    3128      * @thread  Any thread, but the call may involve the emulation thread.
    3129      */
    3130     DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
    3131 
    3132     /**
    3133      * Set the IRQ for a PCI device.
    3134      *
    3135      * @param   pDevIns             The device instance.
    3136      * @param   iIrq                IRQ number to set.
    3137      * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
    3138      * @thread  Any thread, but will involve the emulation thread.
    3139      */
    3140     DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    3141 
    3142     /**
    3143      * Set the IRQ for a PCI device, but don't wait for EMT to process
    3144      * the request when not called from EMT.
    3145      *
    3146      * @param   pDevIns             The device instance.
    3147      * @param   iIrq                IRQ number to set.
    3148      * @param   iLevel              IRQ level.
    3149      * @thread  Any thread, but will involve the emulation thread.
    3150      */
    3151     DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    3152 
    3153     /**
    3154      * Set ISA IRQ for a device.
    3155      *
    3156      * @param   pDevIns             The device instance.
    3157      * @param   iIrq                IRQ number to set.
    3158      * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
    3159      * @thread  Any thread, but will involve the emulation thread.
    3160      */
    3161     DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    3162 
    3163     /**
    3164      * Set the ISA IRQ for a device, but don't wait for EMT to process
    3165      * the request when not called from EMT.
    3166      *
    3167      * @param   pDevIns             The device instance.
    3168      * @param   iIrq                IRQ number to set.
    3169      * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
    3170      * @thread  Any thread, but will involve the emulation thread.
    3171      */
    3172     DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
    3173 
    3174     /**
    3175      * Attaches a driver (chain) to the device.
    3176      *
    3177      * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
    3178      * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
    3179      *
    3180      * @returns VBox status code.
    3181      * @param   pDevIns             The device instance.
    3182      * @param   iLun                The logical unit to attach.
    3183      * @param   pBaseInterface      Pointer to the base interface for that LUN. (device side / down)
    3184      * @param   ppBaseInterface     Where to store the pointer to the base interface. (driver side / up)
    3185      * @param   pszDesc             Pointer to a string describing the LUN. This string must remain valid
    3186      *                              for the live of the device instance.
    3187      */
    3188     DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface,
    3189                                                PPDMIBASE *ppBaseInterface, const char *pszDesc));
    3190 
    3191     /**
    3192      * Detaches an attached driver (chain) from the device again.
    3193      *
    3194      * @returns VBox status code.
    3195      * @param   pDevIns             The device instance.
    3196      * @param   pDrvIns             The driver instance to detach.
    3197      * @param   fFlags              Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    3198      */
    3199     DECLR3CALLBACKMEMBER(int, pfnDriverDetach,(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags));
    3200 
    3201     /**
    3202      * Create a queue.
    3203      *
    3204      * @returns VBox status code.
    3205      * @param   pDevIns             The device instance.
    3206      * @param   cbItem              The size of a queue item.
    3207      * @param   cItems              The number of items in the queue.
    3208      * @param   cMilliesInterval    The number of milliseconds between polling the queue.
    3209      *                              If 0 then the emulation thread will be notified whenever an item arrives.
    3210      * @param   pfnCallback         The consumer function.
    3211      * @param   fRZEnabled          Set if the queue should work in RC and R0.
    3212      * @param   pszName             The queue base name. The instance number will be
    3213      *                              appended automatically.
    3214      * @param   ppQueue             Where to store the queue handle on success.
    3215      * @thread  The emulation thread.
    3216      * @remarks The device critical section will NOT be entered before calling the
    3217      *          callback.  No locks will be held, but for now it's safe to assume
    3218      *          that only one EMT will do queue callbacks at any one time.
    3219      */
    3220     DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
    3221                                               PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
    3222 
    3223     /**
    3224      * Initializes a PDM critical section.
    3225      *
    3226      * The PDM critical sections are derived from the IPRT critical sections, but
    3227      * works in RC and R0 as well.
    3228      *
    3229      * @returns VBox status code.
    3230      * @param   pDevIns             The device instance.
    3231      * @param   pCritSect           Pointer to the critical section.
    3232      * @param   SRC_POS             Use RT_SRC_POS.
    3233      * @param   pszNameFmt          Format string for naming the critical section.
    3234      *                              For statistics and lock validation.
    3235      * @param   va                  Arguments for the format string.
    3236      */
    3237     DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
    3238                                                const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
    3239 
    3240     /**
    3241      * Gets the NOP critical section.
    3242      *
    3243      * @returns The ring-3 address of the NOP critical section.
    3244      * @param   pDevIns             The device instance.
    3245      */
    3246     DECLR3CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
    3247 
    3248     /**
    3249      * Gets the NOP critical section.
    3250      *
    3251      * @returns The ring-0 address of the NOP critical section.
    3252      * @param   pDevIns             The device instance.
    3253      */
    3254     DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnCritSectGetNopR0,(PPDMDEVINS pDevIns));
    3255 
    3256     /**
    3257      * Gets the NOP critical section.
    3258      *
    3259      * @returns The raw-mode context address of the NOP critical section.
    3260      * @param   pDevIns             The device instance.
    3261      */
    3262     DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnCritSectGetNopRC,(PPDMDEVINS pDevIns));
    3263 
    3264     /**
    3265      * Changes the device level critical section from the automatically created
    3266      * default to one desired by the device constructor.
    3267      *
    3268      * @returns VBox status code.
    3269      * @param   pDevIns             The device instance.
    3270      * @param   pCritSect           The critical section to use.  NULL is not
    3271      *                              valid, instead use the NOP critical
    3272      *                              section.
    3273      */
    3274     DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
    3275 
    3276     /**
    3277      * Creates a PDM thread.
    3278      *
    3279      * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
    3280      * resuming, and destroying the thread as the VM state changes.
    3281      *
    3282      * @returns VBox status code.
    3283      * @param   pDevIns             The device instance.
    3284      * @param   ppThread            Where to store the thread 'handle'.
    3285      * @param   pvUser              The user argument to the thread function.
    3286      * @param   pfnThread           The thread function.
    3287      * @param   pfnWakeup           The wakup callback. This is called on the EMT
    3288      *                              thread when a state change is pending.
    3289      * @param   cbStack             See RTThreadCreate.
    3290      * @param   enmType             See RTThreadCreate.
    3291      * @param   pszName             See RTThreadCreate.
    3292      * @remarks The device critical section will NOT be entered prior to invoking
    3293      *          the function pointers.
    3294      */
    3295     DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
    3296                                                PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
    3297 
    3298     /**
    3299      * Set up asynchronous handling of a suspend, reset or power off notification.
    3300      *
    3301      * This shall only be called when getting the notification.  It must be called
    3302      * for each one.
    3303      *
    3304      * @returns VBox status code.
    3305      * @param   pDevIns             The device instance.
    3306      * @param   pfnAsyncNotify      The callback.
    3307      * @thread  EMT(0)
    3308      * @remarks The caller will enter the device critical section prior to invoking
    3309      *          the callback.
    3310      */
    3311     DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
    3312 
    3313     /**
    3314      * Notify EMT(0) that the device has completed the asynchronous notification
    3315      * handling.
    3316      *
    3317      * This can be called at any time, spurious calls will simply be ignored.
    3318      *
    3319      * @param   pDevIns             The device instance.
    3320      * @thread  Any
    3321      */
    3322     DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
    3323 
    3324     /**
    3325      * Register the RTC device.
    3326      *
    3327      * @returns VBox status code.
    3328      * @param   pDevIns             The device instance.
    3329      * @param   pRtcReg             Pointer to a RTC registration structure.
    3330      * @param   ppRtcHlp            Where to store the pointer to the helper
    3331      *                              functions.
    3332      */
    3333     DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
    3334 
    3335     /**
    3336      * Register the PCI Bus.
    3337      *
    3338      * @returns VBox status code.
    3339      * @param   pDevIns             The device instance.
    3340      * @param   pPciBusReg          Pointer to PCI bus registration structure.
    3341      * @param   ppPciHlpR3          Where to store the pointer to the PCI Bus
    3342      *                              helpers.
    3343      */
    3344     DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
    3345 
    3346     /**
    3347      * Register the PIC device.
    3348      *
    3349      * @returns VBox status code.
    3350      * @param   pDevIns             The device instance.
    3351      * @param   pPicReg             Pointer to a PIC registration structure.
    3352      * @param   ppPicHlpR3          Where to store the pointer to the PIC HC
    3353      *                              helpers.
    3354      */
    3355     DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
    3356 
    3357     /**
    3358      * Register the APIC device.
    3359      *
    3360      * @returns VBox status code.
    3361      * @param   pDevIns             The device instance.
    3362      * @param   pApicReg            Pointer to a APIC registration structure.
    3363      * @param   ppApicHlpR3         Where to store the pointer to the APIC helpers.
    3364      */
    3365     DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
    3366 
    3367     /**
    3368      * Register the I/O APIC device.
    3369      *
    3370      * @returns VBox status code.
    3371      * @param   pDevIns             The device instance.
    3372      * @param   pIoApicReg          Pointer to a I/O APIC registration structure.
    3373      * @param   ppIoApicHlpR3       Where to store the pointer to the IOAPIC
    3374      *                              helpers.
    3375      */
    3376     DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
    3377 
    3378     /**
    3379      * Register the HPET device.
    3380      *
    3381      * @returns VBox status code.
    3382      * @param   pDevIns             The device instance.
    3383      * @param   pHpetReg            Pointer to a HPET registration structure.
    3384      * @param   ppHpetHlpR3         Where to store the pointer to the HPET
    3385      *                              helpers.
    3386      */
    3387     DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
    3388 
    3389     /**
    3390      * Register a raw PCI device.
    3391      *
    3392      * @returns VBox status code.
    3393      * @param   pDevIns             The device instance.
    3394      * @param   pPciRawReg          Pointer to a raw PCI registration structure.
    3395      * @param   ppPciRawHlpR3       Where to store the pointer to the raw PCI
    3396      *                              device helpers.
    3397      */
    3398     DECLR3CALLBACKMEMBER(int, pfnPciRawRegister,(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3));
    3399 
    3400     /**
    3401      * Register the DMA device.
    3402      *
    3403      * @returns VBox status code.
    3404      * @param   pDevIns             The device instance.
    3405      * @param   pDmacReg            Pointer to a DMAC registration structure.
    3406      * @param   ppDmacHlp           Where to store the pointer to the DMA helpers.
    3407      */
    3408     DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
    3409 
    3410     /**
    3411      * Register transfer function for DMA channel.
    3412      *
    3413      * @returns VBox status code.
    3414      * @param   pDevIns             The device instance.
    3415      * @param   uChannel            Channel number.
    3416      * @param   pfnTransferHandler  Device specific transfer callback function.
    3417      * @param   pvUser              User pointer to pass to the callback.
    3418      * @thread  EMT
    3419      */
    3420     DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
    3421 
    3422     /**
    3423      * Read memory.
    3424      *
    3425      * @returns VBox status code.
    3426      * @param   pDevIns             The device instance.
    3427      * @param   uChannel            Channel number.
    3428      * @param   pvBuffer            Pointer to target buffer.
    3429      * @param   off                 DMA position.
    3430      * @param   cbBlock             Block size.
    3431      * @param   pcbRead             Where to store the number of bytes which was
    3432      *                              read. optional.
    3433      * @thread  EMT
    3434      */
    3435     DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
    3436 
    3437     /**
    3438      * Write memory.
    3439      *
    3440      * @returns VBox status code.
    3441      * @param   pDevIns             The device instance.
    3442      * @param   uChannel            Channel number.
    3443      * @param   pvBuffer            Memory to write.
    3444      * @param   off                 DMA position.
    3445      * @param   cbBlock             Block size.
    3446      * @param   pcbWritten          Where to store the number of bytes which was
    3447      *                              written. optional.
    3448      * @thread  EMT
    3449      */
    3450     DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
    3451 
    3452     /**
    3453      * Set the DREQ line.
    3454      *
    3455      * @returns VBox status code.
    3456      * @param pDevIns               Device instance.
    3457      * @param uChannel              Channel number.
    3458      * @param uLevel                Level of the line.
    3459      * @thread  EMT
    3460      */
    3461     DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
    3462 
    3463     /**
    3464      * Get channel mode.
    3465      *
    3466      * @returns Channel mode. See specs.
    3467      * @param   pDevIns             The device instance.
    3468      * @param   uChannel            Channel number.
    3469      * @thread  EMT
    3470      */
    3471     DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
    3472 
    3473     /**
    3474      * Schedule DMA execution.
    3475      *
    3476      * @param   pDevIns             The device instance.
    3477      * @thread  Any thread.
    3478      */
    3479     DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
    3480 
    3481     /**
    3482      * Write CMOS value and update the checksum(s).
    3483      *
    3484      * @returns VBox status code.
    3485      * @param   pDevIns             The device instance.
    3486      * @param   iReg                The CMOS register index.
    3487      * @param   u8Value             The CMOS register value.
    3488      * @thread  EMT
    3489      */
    3490     DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
    3491 
    3492     /**
    3493      * Read CMOS value.
    3494      *
    3495      * @returns VBox status code.
    3496      * @param   pDevIns             The device instance.
    3497      * @param   iReg                The CMOS register index.
    3498      * @param   pu8Value            Where to store the CMOS register value.
    3499      * @thread  EMT
    3500      */
    3501     DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
    3502 
    3503     /**
    3504      * Assert that the current thread is the emulation thread.
    3505      *
    3506      * @returns True if correct.
    3507      * @returns False if wrong.
    3508      * @param   pDevIns             The device instance.
    3509      * @param   pszFile             Filename of the assertion location.
    3510      * @param   iLine               The linenumber of the assertion location.
    3511      * @param   pszFunction         Function of the assertion location.
    3512      */
    3513     DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
    3514 
    3515     /**
    3516      * Assert that the current thread is NOT the emulation thread.
    3517      *
    3518      * @returns True if correct.
    3519      * @returns False if wrong.
    3520      * @param   pDevIns             The device instance.
    3521      * @param   pszFile             Filename of the assertion location.
    3522      * @param   iLine               The linenumber of the assertion location.
    3523      * @param   pszFunction         Function of the assertion location.
    3524      */
    3525     DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
    3526 
    3527     /**
    3528      * Resolves the symbol for a raw-mode context interface.
    3529      *
    3530      * @returns VBox status code.
    3531      * @param   pDevIns             The device instance.
    3532      * @param   pvInterface         The interface structure.
    3533      * @param   cbInterface         The size of the interface structure.
    3534      * @param   pszSymPrefix        What to prefix the symbols in the list with
    3535      *                              before resolving them.  This must start with
    3536      *                              'dev' and contain the driver name.
    3537      * @param   pszSymList          List of symbols corresponding to the interface.
    3538      *                              There is generally a there is generally a define
    3539      *                              holding this list associated with the interface
    3540      *                              definition (INTERFACE_SYM_LIST).  For more
    3541      *                              details see PDMR3LdrGetInterfaceSymbols.
    3542      * @thread  EMT
    3543      */
    3544     DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
    3545                                                            const char *pszSymPrefix, const char *pszSymList));
    3546 
    3547     /**
    3548      * Resolves the symbol for a ring-0 context interface.
    3549      *
    3550      * @returns VBox status code.
    3551      * @param   pDevIns             The device instance.
    3552      * @param   pvInterface         The interface structure.
    3553      * @param   cbInterface         The size of the interface structure.
    3554      * @param   pszSymPrefix        What to prefix the symbols in the list with
    3555      *                              before resolving them.  This must start with
    3556      *                              'dev' and contain the driver name.
    3557      * @param   pszSymList          List of symbols corresponding to the interface.
    3558      *                              There is generally a there is generally a define
    3559      *                              holding this list associated with the interface
    3560      *                              definition (INTERFACE_SYM_LIST).  For more
    3561      *                              details see PDMR3LdrGetInterfaceSymbols.
    3562      * @thread  EMT
    3563      */
    3564     DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
    3565                                                            const char *pszSymPrefix, const char *pszSymList));
    3566 
    3567     /**
    3568      * Call the ring-0 request handler routine of the device.
    3569      *
    3570      * For this to work, the device must be ring-0 enabled and export a request
    3571      * handler function.  The name of the function must be the device name in
    3572      * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
    3573      * 'ReqHandler'.  The device name will be captialized.  It shall take the
    3574      * exact same arguments as this function and be declared using
    3575      * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
    3576      *
    3577      * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
    3578      * or two as the handler address will be resolved on each invocation.  This
    3579      * is the reason for the EMT only restriction as well.
    3580      *
    3581      * @returns VBox status code.
    3582      * @retval  VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
    3583      *          handler function.
    3584      * @retval  VERR_ACCESS_DENIED if the device isn't ring-0 capable.
    3585      *
    3586      * @param   pDevIns             The device instance.
    3587      * @param   uOperation          The operation to perform.
    3588      * @param   u64Arg              64-bit integer argument.
    3589      * @thread  EMT
    3590      */
    3591     DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
    3592 
    3593     /**
    3594      * Gets the reason for the most recent VM suspend.
    3595      *
    3596      * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
    3597      *          suspend has been made or if the pDevIns is invalid.
    3598      * @param   pDevIns             The device instance.
    3599      */
    3600     DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns));
    3601 
    3602     /**
    3603      * Gets the reason for the most recent VM resume.
    3604      *
    3605      * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
    3606      *          resume has been made or if the pDevIns is invalid.
    3607      * @param   pDevIns             The device instance.
    3608      */
    3609     DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns));
     2556    DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cb,
     2557                                                uint32_t fFlags, void **ppv, const char *pszDesc));
    36102558
    36112559    /**
     
    36542602     *          PDMDevHlpMMIORegisterEx
    36552603     */
    3656     DECLR3CALLBACKMEMBER(int, pfnMMIOExPreRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
     2604    DECLR3CALLBACKMEMBER(int, pfnMMIOExPreRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
    36572605                                                    uint32_t fFlags, const char *pszDesc, RTHCPTR pvUser,
    36582606                                                    PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
    36592607                                                    RTR0PTR pvUserR0, const char *pszWriteR0, const char *pszReadR0, const char *pszFillR0,
    36602608                                                    RTRCPTR pvUserRC, const char *pszWriteRC, const char *pszReadRC, const char *pszFillRC));
     2609
     2610    /**
     2611     * Deregisters and frees a MMIO or MMIO2 region.
     2612     *
     2613     * Any physical (and virtual) access handlers registered for the region must
     2614     * be deregistered before calling this function (MMIO2 only).
     2615     *
     2616     * @returns VBox status code.
     2617     * @param   pDevIns             The device instance.
     2618     * @param   pPciDev             The PCI device the region is associated with, or
     2619     *                              NULL if not associated with any.
     2620     * @param   iRegion             The region number used during registration.
     2621     * @thread  EMT.
     2622     */
     2623    DECLR3CALLBACKMEMBER(int, pfnMMIOExDeregister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion));
     2624
     2625    /**
     2626     * Maps a MMIO or MMIO2 region into the physical memory space.
     2627     *
     2628     * A MMIO2 range or a pre-registered MMIO range may overlap with base memory if
     2629     * a lot of RAM is configured for the VM, in  which case we'll drop the base
     2630     * memory pages.  Presently we will make no attempt to preserve anything that
     2631     * happens to be present in the base memory that is replaced, this is of course
     2632     * incorrect but it's too much effort.
     2633     *
     2634     * @returns VBox status code.
     2635     * @param   pDevIns             The device instance.
     2636     * @param   pPciDev             The PCI device the region is associated with, or
     2637     *                              NULL if not associated with any.
     2638     * @param   iRegion             The region number used during registration.
     2639     * @param   GCPhys              The physical address to map it at.
     2640     * @thread  EMT.
     2641     */
     2642    DECLR3CALLBACKMEMBER(int, pfnMMIOExMap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
     2643
     2644    /**
     2645     * Unmaps a MMIO or MMIO2 region previously mapped using pfnMMIOExMap.
     2646     *
     2647     * @returns VBox status code.
     2648     * @param   pDevIns             The device instance.
     2649     * @param   pPciDev             The PCI device the region is associated with, or
     2650     *                              NULL if not associated with any.
     2651     * @param   iRegion             The region number used during registration.
     2652     * @param   GCPhys              The physical address it's currently mapped at.
     2653     * @thread  EMT.
     2654     */
     2655    DECLR3CALLBACKMEMBER(int, pfnMMIOExUnmap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
     2656
     2657    /**
     2658     * Maps a portion of an MMIO2 region into the hypervisor region.
     2659     *
     2660     * Callers of this API must never deregister the MMIO2 region before the
     2661     * VM is powered off.
     2662     *
     2663     * @return VBox status code.
     2664     * @param   pDevIns             The device owning the MMIO2 memory.
     2665     * @param   pPciDev             The PCI device the region is associated with, or
     2666     *                              NULL if not associated with any.
     2667     * @param   iRegion             The region.
     2668     * @param   off                 The offset into the region. Will be rounded down
     2669     *                              to closest page boundary.
     2670     * @param   cb                  The number of bytes to map. Will be rounded up
     2671     *                              to the closest page boundary.
     2672     * @param   pszDesc             Mapping description.
     2673     * @param   pRCPtr              Where to store the RC address.
     2674     */
     2675    DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
     2676                                                  RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr));
     2677
     2678    /**
     2679     * Maps a portion of an MMIO2 region into kernel space (host).
     2680     *
     2681     * The kernel mapping will become invalid when the MMIO2 memory is deregistered
     2682     * or the VM is terminated.
     2683     *
     2684     * @return VBox status code.
     2685     * @param   pDevIns             The device owning the MMIO2 memory.
     2686     * @param   pPciDev             The PCI device the region is associated with, or
     2687     *                              NULL if not associated with any.
     2688     * @param   iRegion             The region.
     2689     * @param   off                 The offset into the region. Must be page
     2690     *                              aligned.
     2691     * @param   cb                  The number of bytes to map. Must be page
     2692     *                              aligned.
     2693     * @param   pszDesc             Mapping description.
     2694     * @param   pR0Ptr              Where to store the R0 address.
     2695     */
     2696    DECLR3CALLBACKMEMBER(int, pfnMMIO2MapKernel,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
     2697                                                 RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr));
     2698
     2699    /**
     2700     * Register a ROM (BIOS) region.
     2701     *
     2702     * It goes without saying that this is read-only memory. The memory region must be
     2703     * in unassigned memory. I.e. from the top of the address space or on the PC in
     2704     * the 0xa0000-0xfffff range.
     2705     *
     2706     * @returns VBox status.
     2707     * @param   pDevIns             The device instance owning the ROM region.
     2708     * @param   GCPhysStart         First physical address in the range.
     2709     *                              Must be page aligned!
     2710     * @param   cbRange             The size of the range (in bytes).
     2711     *                              Must be page aligned!
     2712     * @param   pvBinary            Pointer to the binary data backing the ROM image.
     2713     * @param   cbBinary            The size of the binary pointer.  This must
     2714     *                              be equal or smaller than @a cbRange.
     2715     * @param   fFlags              Shadow ROM flags, PGMPHYS_ROM_FLAGS_* in pgm.h.
     2716     * @param   pszDesc             Pointer to description string. This must not be freed.
     2717     *
     2718     * @remark  There is no way to remove the rom, automatically on device cleanup or
     2719     *          manually from the device yet. At present I doubt we need such features...
     2720     */
     2721    DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
     2722                                              const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
     2723
     2724    /**
     2725     * Changes the protection of shadowed ROM mapping.
     2726     *
     2727     * This is intented for use by the system BIOS, chipset or device in question to
     2728     * change the protection of shadowed ROM code after init and on reset.
     2729     *
     2730     * @param   pDevIns             The device instance.
     2731     * @param   GCPhysStart         Where the mapping starts.
     2732     * @param   cbRange             The size of the mapping.
     2733     * @param   enmProt             The new protection type.
     2734     */
     2735    DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt));
     2736
     2737    /**
     2738     * Register a save state data unit.
     2739     *
     2740     * @returns VBox status.
     2741     * @param   pDevIns             The device instance.
     2742     * @param   uVersion            Data layout version number.
     2743     * @param   cbGuess             The approximate amount of data in the unit.
     2744     *                              Only for progress indicators.
     2745     * @param   pszBefore           Name of data unit which we should be put in
     2746     *                              front of. Optional (NULL).
     2747     *
     2748     * @param   pfnLivePrep         Prepare live save callback, optional.
     2749     * @param   pfnLiveExec         Execute live save callback, optional.
     2750     * @param   pfnLiveVote         Vote live save callback, optional.
     2751     *
     2752     * @param   pfnSavePrep         Prepare save callback, optional.
     2753     * @param   pfnSaveExec         Execute save callback, optional.
     2754     * @param   pfnSaveDone         Done save callback, optional.
     2755     *
     2756     * @param   pfnLoadPrep         Prepare load callback, optional.
     2757     * @param   pfnLoadExec         Execute load callback, optional.
     2758     * @param   pfnLoadDone         Done load callback, optional.
     2759     * @remarks Caller enters the device critical section prior to invoking the
     2760     *          registered callback methods.
     2761     */
     2762    DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
     2763                                              PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
     2764                                              PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
     2765                                              PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
     2766
     2767    /**
     2768     * Creates a timer.
     2769     *
     2770     * @returns VBox status.
     2771     * @param   pDevIns             The device instance.
     2772     * @param   enmClock            The clock to use on this timer.
     2773     * @param   pfnCallback         Callback function.
     2774     * @param   pvUser              User argument for the callback.
     2775     * @param   fFlags              Flags, see TMTIMER_FLAGS_*.
     2776     * @param   pszDesc             Pointer to description string which must stay around
     2777     *                              until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
     2778     * @param   ppTimer             Where to store the timer on success.
     2779     * @remarks Caller enters the device critical section prior to invoking the
     2780     *          callback.
     2781     */
     2782    DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
     2783                                                void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
     2784
     2785    /**
     2786     * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
     2787     *
     2788     * @returns pTime.
     2789     * @param   pDevIns             The device instance.
     2790     * @param   pTime               Where to store the time.
     2791     */
     2792    DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
     2793
     2794    /**
     2795     * Read physical memory.
     2796     *
     2797     * @returns VINF_SUCCESS (for now).
     2798     * @param   pDevIns             The device instance.
     2799     * @param   GCPhys              Physical address start reading from.
     2800     * @param   pvBuf               Where to put the read bits.
     2801     * @param   cbRead              How many bytes to read.
     2802     * @thread  Any thread, but the call may involve the emulation thread.
     2803     */
     2804    DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
     2805
     2806    /**
     2807     * Write to physical memory.
     2808     *
     2809     * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
     2810     * @param   pDevIns             The device instance.
     2811     * @param   GCPhys              Physical address to write to.
     2812     * @param   pvBuf               What to write.
     2813     * @param   cbWrite             How many bytes to write.
     2814     * @thread  Any thread, but the call may involve the emulation thread.
     2815     */
     2816    DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
     2817
     2818    /**
     2819     * Requests the mapping of a guest page into ring-3.
     2820     *
     2821     * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
     2822     * release it.
     2823     *
     2824     * This API will assume your intention is to write to the page, and will
     2825     * therefore replace shared and zero pages. If you do not intend to modify the
     2826     * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
     2827     *
     2828     * @returns VBox status code.
     2829     * @retval  VINF_SUCCESS on success.
     2830     * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
     2831     *          backing or if the page has any active access handlers. The caller
     2832     *          must fall back on using PGMR3PhysWriteExternal.
     2833     * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
     2834     *
     2835     * @param   pDevIns             The device instance.
     2836     * @param   GCPhys              The guest physical address of the page that
     2837     *                              should be mapped.
     2838     * @param   fFlags              Flags reserved for future use, MBZ.
     2839     * @param   ppv                 Where to store the address corresponding to
     2840     *                              GCPhys.
     2841     * @param   pLock               Where to store the lock information that
     2842     *                              pfnPhysReleasePageMappingLock needs.
     2843     *
     2844     * @remark  Avoid calling this API from within critical sections (other than the
     2845     *          PGM one) because of the deadlock risk when we have to delegating the
     2846     *          task to an EMT.
     2847     * @thread  Any.
     2848     */
     2849    DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv,
     2850                                                   PPGMPAGEMAPLOCK pLock));
     2851
     2852    /**
     2853     * Requests the mapping of a guest page into ring-3, external threads.
     2854     *
     2855     * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
     2856     * release it.
     2857     *
     2858     * @returns VBox status code.
     2859     * @retval  VINF_SUCCESS on success.
     2860     * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
     2861     *          backing or if the page as an active ALL access handler. The caller
     2862     *          must fall back on using PGMPhysRead.
     2863     * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
     2864     *
     2865     * @param   pDevIns             The device instance.
     2866     * @param   GCPhys              The guest physical address of the page that
     2867     *                              should be mapped.
     2868     * @param   fFlags              Flags reserved for future use, MBZ.
     2869     * @param   ppv                 Where to store the address corresponding to
     2870     *                              GCPhys.
     2871     * @param   pLock               Where to store the lock information that
     2872     *                              pfnPhysReleasePageMappingLock needs.
     2873     *
     2874     * @remark  Avoid calling this API from within critical sections.
     2875     * @thread  Any.
     2876     */
     2877    DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags,
     2878                                                           void const **ppv, PPGMPAGEMAPLOCK pLock));
     2879
     2880    /**
     2881     * Release the mapping of a guest page.
     2882     *
     2883     * This is the counter part of pfnPhysGCPhys2CCPtr and
     2884     * pfnPhysGCPhys2CCPtrReadOnly.
     2885     *
     2886     * @param   pDevIns             The device instance.
     2887     * @param   pLock               The lock structure initialized by the mapping
     2888     *                              function.
     2889     */
     2890    DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
     2891
     2892    /**
     2893     * Read guest physical memory by virtual address.
     2894     *
     2895     * @param   pDevIns             The device instance.
     2896     * @param   pvDst               Where to put the read bits.
     2897     * @param   GCVirtSrc           Guest virtual address to start reading from.
     2898     * @param   cb                  How many bytes to read.
     2899     * @thread  The emulation thread.
     2900     */
     2901    DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
     2902
     2903    /**
     2904     * Write to guest physical memory by virtual address.
     2905     *
     2906     * @param   pDevIns             The device instance.
     2907     * @param   GCVirtDst           Guest virtual address to write to.
     2908     * @param   pvSrc               What to write.
     2909     * @param   cb                  How many bytes to write.
     2910     * @thread  The emulation thread.
     2911     */
     2912    DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
     2913
     2914    /**
     2915     * Convert a guest virtual address to a guest physical address.
     2916     *
     2917     * @returns VBox status code.
     2918     * @param   pDevIns             The device instance.
     2919     * @param   GCPtr               Guest virtual address.
     2920     * @param   pGCPhys             Where to store the GC physical address
     2921     *                              corresponding to GCPtr.
     2922     * @thread  The emulation thread.
     2923     * @remark  Careful with page boundaries.
     2924     */
     2925    DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
     2926
     2927    /**
     2928     * Allocate memory which is associated with current VM instance
     2929     * and automatically freed on it's destruction.
     2930     *
     2931     * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
     2932     * @param   pDevIns             The device instance.
     2933     * @param   cb                  Number of bytes to allocate.
     2934     */
     2935    DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
     2936
     2937    /**
     2938     * Allocate memory which is associated with current VM instance
     2939     * and automatically freed on it's destruction. The memory is ZEROed.
     2940     *
     2941     * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
     2942     * @param   pDevIns             The device instance.
     2943     * @param   cb                  Number of bytes to allocate.
     2944     */
     2945    DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
     2946
     2947    /**
     2948     * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
     2949     *
     2950     * @param   pDevIns             The device instance.
     2951     * @param   pv                  Pointer to the memory to free.
     2952     */
     2953    DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
     2954
     2955    /**
     2956     * Gets the VM state.
     2957     *
     2958     * @returns VM state.
     2959     * @param   pDevIns             The device instance.
     2960     * @thread  Any thread (just keep in mind that it's volatile info).
     2961     */
     2962    DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
     2963
     2964    /**
     2965     * Checks if the VM was teleported and hasn't been fully resumed yet.
     2966     *
     2967     * @returns true / false.
     2968     * @param   pDevIns             The device instance.
     2969     * @thread  Any thread.
     2970     */
     2971    DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
     2972
     2973    /**
     2974     * Set the VM error message
     2975     *
     2976     * @returns rc.
     2977     * @param   pDevIns             The device instance.
     2978     * @param   rc                  VBox status code.
     2979     * @param   SRC_POS             Use RT_SRC_POS.
     2980     * @param   pszFormat           Error message format string.
     2981     * @param   ...                 Error message arguments.
     2982     */
     2983    DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
     2984                                             const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
     2985
     2986    /**
     2987     * Set the VM error message
     2988     *
     2989     * @returns rc.
     2990     * @param   pDevIns             The device instance.
     2991     * @param   rc                  VBox status code.
     2992     * @param   SRC_POS             Use RT_SRC_POS.
     2993     * @param   pszFormat           Error message format string.
     2994     * @param   va                  Error message arguments.
     2995     */
     2996    DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
     2997                                              const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
     2998
     2999    /**
     3000     * Set the VM runtime error message
     3001     *
     3002     * @returns VBox status code.
     3003     * @param   pDevIns             The device instance.
     3004     * @param   fFlags              The action flags. See VMSETRTERR_FLAGS_*.
     3005     * @param   pszErrorId          Error ID string.
     3006     * @param   pszFormat           Error message format string.
     3007     * @param   ...                 Error message arguments.
     3008     */
     3009    DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
     3010                                                    const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5));
     3011
     3012    /**
     3013     * Set the VM runtime error message
     3014     *
     3015     * @returns VBox status code.
     3016     * @param   pDevIns             The device instance.
     3017     * @param   fFlags              The action flags. See VMSETRTERR_FLAGS_*.
     3018     * @param   pszErrorId          Error ID string.
     3019     * @param   pszFormat           Error message format string.
     3020     * @param   va                  Error message arguments.
     3021     */
     3022    DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
     3023                                                     const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
     3024
     3025    /**
     3026     * Stops the VM and enters the debugger to look at the guest state.
     3027     *
     3028     * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
     3029     * invoking this function directly.
     3030     *
     3031     * @returns VBox status code which must be passed up to the VMM.
     3032     * @param   pDevIns             The device instance.
     3033     * @param   pszFile             Filename of the assertion location.
     3034     * @param   iLine               The linenumber of the assertion location.
     3035     * @param   pszFunction         Function of the assertion location.
     3036     * @param   pszFormat           Message. (optional)
     3037     * @param   args                Message parameters.
     3038     */
     3039    DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction,
     3040                                            const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(5, 0));
     3041
     3042    /**
     3043     * Register a info handler with DBGF,
     3044     *
     3045     * @returns VBox status code.
     3046     * @param   pDevIns             The device instance.
     3047     * @param   pszName             The identifier of the info.
     3048     * @param   pszDesc             The description of the info and any arguments
     3049     *                              the handler may take.
     3050     * @param   pfnHandler          The handler function to be called to display the
     3051     *                              info.
     3052     */
     3053    DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
     3054
     3055    /**
     3056     * Registers a set of registers for a device.
     3057     *
     3058     * The @a pvUser argument of the getter and setter callbacks will be
     3059     * @a pDevIns.  The register names will be prefixed by the device name followed
     3060     * immediately by the instance number.
     3061     *
     3062     * @returns VBox status code.
     3063     * @param   pDevIns             The device instance.
     3064     * @param   paRegisters         The register descriptors.
     3065     *
     3066     * @remarks The device critical section is NOT entered prior to working the
     3067     *          callbacks registered via this helper!
     3068     */
     3069    DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters));
     3070
     3071    /**
     3072     * Gets the trace buffer handle.
     3073     *
     3074     * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
     3075     * really inteded for direct usage, thus no inline wrapper function.
     3076     *
     3077     * @returns Trace buffer handle or NIL_RTTRACEBUF.
     3078     * @param   pDevIns             The device instance.
     3079     */
     3080    DECLR3CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
     3081
     3082    /**
     3083     * Registers a statistics sample if statistics are enabled.
     3084     *
     3085     * @param   pDevIns             Device instance of the DMA.
     3086     * @param   pvSample            Pointer to the sample.
     3087     * @param   enmType             Sample type. This indicates what pvSample is
     3088     *                              pointing at.
     3089     * @param   pszName             Sample name. The name is on this form
     3090     *                              "/<component>/<sample>". Further nesting is
     3091     *                              possible.
     3092     * @param   enmUnit             Sample unit.
     3093     * @param   pszDesc             Sample description.
     3094     */
     3095    DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
     3096
     3097    /**
     3098     * Same as pfnSTAMRegister except that the name is specified in a
     3099     * RTStrPrintf like fashion.
     3100     *
     3101     * @returns VBox status.
     3102     * @param   pDevIns             Device instance of the DMA.
     3103     * @param   pvSample            Pointer to the sample.
     3104     * @param   enmType             Sample type. This indicates what pvSample is
     3105     *                              pointing at.
     3106     * @param   enmVisibility       Visibility type specifying whether unused
     3107     *                              statistics should be visible or not.
     3108     * @param   enmUnit             Sample unit.
     3109     * @param   pszDesc             Sample description.
     3110     * @param   pszName             The sample name format string.
     3111     * @param   ...                 Arguments to the format string.
     3112     */
     3113    DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
     3114                                                 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
     3115                                                 const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8));
     3116
     3117    /**
     3118     * Same as pfnSTAMRegister except that the name is specified in a
     3119     * RTStrPrintfV like fashion.
     3120     *
     3121     * @returns VBox status.
     3122     * @param   pDevIns             Device instance of the DMA.
     3123     * @param   pvSample            Pointer to the sample.
     3124     * @param   enmType             Sample type. This indicates what pvSample is
     3125     *                              pointing at.
     3126     * @param   enmVisibility       Visibility type specifying whether unused
     3127     *                              statistics should be visible or not.
     3128     * @param   enmUnit             Sample unit.
     3129     * @param   pszDesc             Sample description.
     3130     * @param   pszName             The sample name format string.
     3131     * @param   args                Arguments to the format string.
     3132     */
     3133    DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
     3134                                                 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
     3135                                                 const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0));
     3136
     3137    /**
     3138     * Registers a PCI device with the default PCI bus.
     3139     *
     3140     * @returns VBox status code.
     3141     * @param   pDevIns             The device instance.
     3142     * @param   pPciDev             The PCI device structure.
     3143     *                              This must be kept in the instance data.
     3144     *                              The PCI configuration must be initialized before registration.
     3145     * @param   idxDevCfg           The CFGM configuration index to use for this
     3146     *                              device.
     3147     *                              Zero indicates the default configuration
     3148     *                              (PDMPCIDEVREG_CFG_PRIMARY), whereas 1 to 255
     3149     *                              references subkeys "PciDev1" thru "PciDev255".
     3150     *                              Pass PDMPCIDEVREG_CFG_NEXT to use the next
     3151     *                              number in the sequence (last + 1).
     3152     * @param   fFlags              Reserved for future use, PDMPCIDEVREG_F_MBZ.
     3153     * @param   uPciDevNo           PDMPCIDEVREG_DEV_NO_FIRST_UNUSED,
     3154     *                              PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, or a specific
     3155     *                              device number (0-31).  This will be ignored if
     3156     *                              the CFGM configuration contains a PCIDeviceNo
     3157     *                              value.
     3158     * @param   uPciFunNo           PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
     3159     *                              function number (0-7).  This will be ignored if
     3160     *                              the CFGM configuration contains a PCIFunctionNo
     3161     *                              value.
     3162     * @param   pszName             Device name, if NULL PDMDEVREG::szName is used.
     3163     *                              The pointer is saved, so don't free or changed.
     3164     */
     3165    DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t idxDevCfg, uint32_t fFlags,
     3166                                              uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
     3167
     3168    /**
     3169     * Initialize MSI support for the given PCI device.
     3170     *
     3171     * @returns VBox status code.
     3172     * @param   pDevIns             The device instance.
     3173     * @param   pPciDev             The PCI device.  NULL is an alias for the first
     3174     *                              one registered.
     3175     * @param   pMsiReg             MSI registartion structure.
     3176     */
     3177    DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
     3178
     3179    /**
     3180     * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
     3181     *
     3182     * @returns VBox status code.
     3183     * @param   pDevIns             The device instance.
     3184     * @param   pPciDev             The PCI device structure.  If NULL the default
     3185     *                              PCI device for this device instance is used.
     3186     * @param   iRegion             The region number.
     3187     * @param   cbRegion            Size of the region.
     3188     * @param   enmType             PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
     3189     * @param   pfnCallback         Callback for doing the mapping.
     3190     * @remarks The callback will be invoked holding the PDM lock. The device lock
     3191     *          is NOT take because that is very likely be a lock order violation.
     3192     */
     3193    DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
     3194                                                      PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
     3195
     3196    /**
     3197     * Register PCI configuration space read/write callbacks.
     3198     *
     3199     * @param   pDevIns             The device instance.
     3200     * @param   pPciDev             The PCI device structure.  If NULL the default
     3201     *                              PCI device for this device instance is used.
     3202     * @param   pfnRead             Pointer to the user defined PCI config read function.
     3203     * @param   ppfnReadOld         Pointer to function pointer which will receive the old (default)
     3204     *                              PCI config read function. This way, user can decide when (and if)
     3205     *                              to call default PCI config read function. Can be NULL.
     3206     * @param   pfnWrite            Pointer to the user defined PCI config write function.
     3207     * @param   ppfnWriteOld        Pointer to function pointer which will receive
     3208     *                              the old (default) PCI config write function.
     3209     *                              This way, user can decide when (and if) to call
     3210     *                              default PCI config write function. Can be NULL.
     3211     * @remarks The callbacks will be invoked holding the PDM lock. The device lock
     3212     *          is NOT take because that is very likely be a lock order violation.
     3213     * @thread  EMT
     3214     */
     3215    DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
     3216                                                         PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
     3217                                                         PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
     3218
     3219    /**
     3220     * Bus master physical memory read.
     3221     *
     3222     * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
     3223     *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
     3224     * @param   pDevIns             The device instance.
     3225     * @param   pPciDev             The PCI device structure.  If NULL the default
     3226     *                              PCI device for this device instance is used.
     3227     * @param   GCPhys              Physical address start reading from.
     3228     * @param   pvBuf               Where to put the read bits.
     3229     * @param   cbRead              How many bytes to read.
     3230     * @thread  Any thread, but the call may involve the emulation thread.
     3231     */
     3232    DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
     3233
     3234    /**
     3235     * Bus master physical memory write.
     3236     *
     3237     * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
     3238     *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
     3239     * @param   pDevIns             The device instance.
     3240     * @param   pPciDev             The PCI device structure.  If NULL the default
     3241     *                              PCI device for this device instance is used.
     3242     * @param   GCPhys              Physical address to write to.
     3243     * @param   pvBuf               What to write.
     3244     * @param   cbWrite             How many bytes to write.
     3245     * @thread  Any thread, but the call may involve the emulation thread.
     3246     */
     3247    DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
     3248
     3249    /**
     3250     * Sets the IRQ for the given PCI device.
     3251     *
     3252     * @param   pDevIns             The device instance.
     3253     * @param   pPciDev             The PCI device structure.  If NULL the default
     3254     *                              PCI device for this device instance is used.
     3255     * @param   iIrq                IRQ number to set.
     3256     * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
     3257     * @thread  Any thread, but will involve the emulation thread.
     3258     */
     3259    DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
     3260
     3261    /**
     3262     * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
     3263     * the request when not called from EMT.
     3264     *
     3265     * @param   pDevIns             The device instance.
     3266     * @param   pPciDev             The PCI device structure.  If NULL the default
     3267     *                              PCI device for this device instance is used.
     3268     * @param   iIrq                IRQ number to set.
     3269     * @param   iLevel              IRQ level.
     3270     * @thread  Any thread, but will involve the emulation thread.
     3271     */
     3272    DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
     3273
     3274    /**
     3275     * Set ISA IRQ for a device.
     3276     *
     3277     * @param   pDevIns             The device instance.
     3278     * @param   iIrq                IRQ number to set.
     3279     * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
     3280     * @thread  Any thread, but will involve the emulation thread.
     3281     */
     3282    DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     3283
     3284    /**
     3285     * Set the ISA IRQ for a device, but don't wait for EMT to process
     3286     * the request when not called from EMT.
     3287     *
     3288     * @param   pDevIns             The device instance.
     3289     * @param   iIrq                IRQ number to set.
     3290     * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
     3291     * @thread  Any thread, but will involve the emulation thread.
     3292     */
     3293    DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     3294
     3295    /**
     3296     * Attaches a driver (chain) to the device.
     3297     *
     3298     * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
     3299     * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
     3300     *
     3301     * @returns VBox status code.
     3302     * @param   pDevIns             The device instance.
     3303     * @param   iLun                The logical unit to attach.
     3304     * @param   pBaseInterface      Pointer to the base interface for that LUN. (device side / down)
     3305     * @param   ppBaseInterface     Where to store the pointer to the base interface. (driver side / up)
     3306     * @param   pszDesc             Pointer to a string describing the LUN. This string must remain valid
     3307     *                              for the live of the device instance.
     3308     */
     3309    DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface,
     3310                                               PPDMIBASE *ppBaseInterface, const char *pszDesc));
     3311
     3312    /**
     3313     * Detaches an attached driver (chain) from the device again.
     3314     *
     3315     * @returns VBox status code.
     3316     * @param   pDevIns             The device instance.
     3317     * @param   pDrvIns             The driver instance to detach.
     3318     * @param   fFlags              Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     3319     */
     3320    DECLR3CALLBACKMEMBER(int, pfnDriverDetach,(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags));
     3321
     3322    /**
     3323     * Create a queue.
     3324     *
     3325     * @returns VBox status code.
     3326     * @param   pDevIns             The device instance.
     3327     * @param   cbItem              The size of a queue item.
     3328     * @param   cItems              The number of items in the queue.
     3329     * @param   cMilliesInterval    The number of milliseconds between polling the queue.
     3330     *                              If 0 then the emulation thread will be notified whenever an item arrives.
     3331     * @param   pfnCallback         The consumer function.
     3332     * @param   fRZEnabled          Set if the queue should work in RC and R0.
     3333     * @param   pszName             The queue base name. The instance number will be
     3334     *                              appended automatically.
     3335     * @param   ppQueue             Where to store the queue handle on success.
     3336     * @thread  The emulation thread.
     3337     * @remarks The device critical section will NOT be entered before calling the
     3338     *          callback.  No locks will be held, but for now it's safe to assume
     3339     *          that only one EMT will do queue callbacks at any one time.
     3340     */
     3341    DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
     3342                                              PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
     3343
     3344    /**
     3345     * Initializes a PDM critical section.
     3346     *
     3347     * The PDM critical sections are derived from the IPRT critical sections, but
     3348     * works in RC and R0 as well.
     3349     *
     3350     * @returns VBox status code.
     3351     * @param   pDevIns             The device instance.
     3352     * @param   pCritSect           Pointer to the critical section.
     3353     * @param   SRC_POS             Use RT_SRC_POS.
     3354     * @param   pszNameFmt          Format string for naming the critical section.
     3355     *                              For statistics and lock validation.
     3356     * @param   va                  Arguments for the format string.
     3357     */
     3358    DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
     3359                                               const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
     3360
     3361    /**
     3362     * Gets the NOP critical section.
     3363     *
     3364     * @returns The ring-3 address of the NOP critical section.
     3365     * @param   pDevIns             The device instance.
     3366     */
     3367    DECLR3CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
     3368
     3369    /**
     3370     * Gets the NOP critical section.
     3371     *
     3372     * @returns The ring-0 address of the NOP critical section.
     3373     * @param   pDevIns             The device instance.
     3374     */
     3375    DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnCritSectGetNopR0,(PPDMDEVINS pDevIns));
     3376
     3377    /**
     3378     * Gets the NOP critical section.
     3379     *
     3380     * @returns The raw-mode context address of the NOP critical section.
     3381     * @param   pDevIns             The device instance.
     3382     */
     3383    DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnCritSectGetNopRC,(PPDMDEVINS pDevIns));
     3384
     3385    /**
     3386     * Changes the device level critical section from the automatically created
     3387     * default to one desired by the device constructor.
     3388     *
     3389     * @returns VBox status code.
     3390     * @param   pDevIns             The device instance.
     3391     * @param   pCritSect           The critical section to use.  NULL is not
     3392     *                              valid, instead use the NOP critical
     3393     *                              section.
     3394     */
     3395    DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
     3396
     3397    /**
     3398     * Creates a PDM thread.
     3399     *
     3400     * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
     3401     * resuming, and destroying the thread as the VM state changes.
     3402     *
     3403     * @returns VBox status code.
     3404     * @param   pDevIns             The device instance.
     3405     * @param   ppThread            Where to store the thread 'handle'.
     3406     * @param   pvUser              The user argument to the thread function.
     3407     * @param   pfnThread           The thread function.
     3408     * @param   pfnWakeup           The wakup callback. This is called on the EMT
     3409     *                              thread when a state change is pending.
     3410     * @param   cbStack             See RTThreadCreate.
     3411     * @param   enmType             See RTThreadCreate.
     3412     * @param   pszName             See RTThreadCreate.
     3413     * @remarks The device critical section will NOT be entered prior to invoking
     3414     *          the function pointers.
     3415     */
     3416    DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
     3417                                               PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
     3418
     3419    /**
     3420     * Set up asynchronous handling of a suspend, reset or power off notification.
     3421     *
     3422     * This shall only be called when getting the notification.  It must be called
     3423     * for each one.
     3424     *
     3425     * @returns VBox status code.
     3426     * @param   pDevIns             The device instance.
     3427     * @param   pfnAsyncNotify      The callback.
     3428     * @thread  EMT(0)
     3429     * @remarks The caller will enter the device critical section prior to invoking
     3430     *          the callback.
     3431     */
     3432    DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
     3433
     3434    /**
     3435     * Notify EMT(0) that the device has completed the asynchronous notification
     3436     * handling.
     3437     *
     3438     * This can be called at any time, spurious calls will simply be ignored.
     3439     *
     3440     * @param   pDevIns             The device instance.
     3441     * @thread  Any
     3442     */
     3443    DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
     3444
     3445    /**
     3446     * Register the RTC device.
     3447     *
     3448     * @returns VBox status code.
     3449     * @param   pDevIns             The device instance.
     3450     * @param   pRtcReg             Pointer to a RTC registration structure.
     3451     * @param   ppRtcHlp            Where to store the pointer to the helper
     3452     *                              functions.
     3453     */
     3454    DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
     3455
     3456    /**
     3457     * Register the PCI Bus.
     3458     *
     3459     * @returns VBox status code.
     3460     * @param   pDevIns             The device instance.
     3461     * @param   pPciBusReg          Pointer to PCI bus registration structure.
     3462     * @param   ppPciHlpR3          Where to store the pointer to the PCI Bus
     3463     *                              helpers.
     3464     */
     3465    DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
     3466
     3467    /**
     3468     * Register the PIC device.
     3469     *
     3470     * @returns VBox status code.
     3471     * @param   pDevIns             The device instance.
     3472     * @param   pPicReg             Pointer to a PIC registration structure.
     3473     * @param   ppPicHlpR3          Where to store the pointer to the PIC HC
     3474     *                              helpers.
     3475     */
     3476    DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
     3477
     3478    /**
     3479     * Register the APIC device.
     3480     *
     3481     * @returns VBox status code.
     3482     * @param   pDevIns             The device instance.
     3483     * @param   pApicReg            Pointer to a APIC registration structure.
     3484     * @param   ppApicHlpR3         Where to store the pointer to the APIC helpers.
     3485     */
     3486    DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
     3487
     3488    /**
     3489     * Register the I/O APIC device.
     3490     *
     3491     * @returns VBox status code.
     3492     * @param   pDevIns             The device instance.
     3493     * @param   pIoApicReg          Pointer to a I/O APIC registration structure.
     3494     * @param   ppIoApicHlpR3       Where to store the pointer to the IOAPIC
     3495     *                              helpers.
     3496     */
     3497    DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
     3498
     3499    /**
     3500     * Register the HPET device.
     3501     *
     3502     * @returns VBox status code.
     3503     * @param   pDevIns             The device instance.
     3504     * @param   pHpetReg            Pointer to a HPET registration structure.
     3505     * @param   ppHpetHlpR3         Where to store the pointer to the HPET
     3506     *                              helpers.
     3507     */
     3508    DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
     3509
     3510    /**
     3511     * Register a raw PCI device.
     3512     *
     3513     * @returns VBox status code.
     3514     * @param   pDevIns             The device instance.
     3515     * @param   pPciRawReg          Pointer to a raw PCI registration structure.
     3516     * @param   ppPciRawHlpR3       Where to store the pointer to the raw PCI
     3517     *                              device helpers.
     3518     */
     3519    DECLR3CALLBACKMEMBER(int, pfnPciRawRegister,(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3));
     3520
     3521    /**
     3522     * Register the DMA device.
     3523     *
     3524     * @returns VBox status code.
     3525     * @param   pDevIns             The device instance.
     3526     * @param   pDmacReg            Pointer to a DMAC registration structure.
     3527     * @param   ppDmacHlp           Where to store the pointer to the DMA helpers.
     3528     */
     3529    DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
     3530
     3531    /**
     3532     * Register transfer function for DMA channel.
     3533     *
     3534     * @returns VBox status code.
     3535     * @param   pDevIns             The device instance.
     3536     * @param   uChannel            Channel number.
     3537     * @param   pfnTransferHandler  Device specific transfer callback function.
     3538     * @param   pvUser              User pointer to pass to the callback.
     3539     * @thread  EMT
     3540     */
     3541    DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
     3542
     3543    /**
     3544     * Read memory.
     3545     *
     3546     * @returns VBox status code.
     3547     * @param   pDevIns             The device instance.
     3548     * @param   uChannel            Channel number.
     3549     * @param   pvBuffer            Pointer to target buffer.
     3550     * @param   off                 DMA position.
     3551     * @param   cbBlock             Block size.
     3552     * @param   pcbRead             Where to store the number of bytes which was
     3553     *                              read. optional.
     3554     * @thread  EMT
     3555     */
     3556    DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
     3557
     3558    /**
     3559     * Write memory.
     3560     *
     3561     * @returns VBox status code.
     3562     * @param   pDevIns             The device instance.
     3563     * @param   uChannel            Channel number.
     3564     * @param   pvBuffer            Memory to write.
     3565     * @param   off                 DMA position.
     3566     * @param   cbBlock             Block size.
     3567     * @param   pcbWritten          Where to store the number of bytes which was
     3568     *                              written. optional.
     3569     * @thread  EMT
     3570     */
     3571    DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
     3572
     3573    /**
     3574     * Set the DREQ line.
     3575     *
     3576     * @returns VBox status code.
     3577     * @param pDevIns               Device instance.
     3578     * @param uChannel              Channel number.
     3579     * @param uLevel                Level of the line.
     3580     * @thread  EMT
     3581     */
     3582    DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
     3583
     3584    /**
     3585     * Get channel mode.
     3586     *
     3587     * @returns Channel mode. See specs.
     3588     * @param   pDevIns             The device instance.
     3589     * @param   uChannel            Channel number.
     3590     * @thread  EMT
     3591     */
     3592    DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
     3593
     3594    /**
     3595     * Schedule DMA execution.
     3596     *
     3597     * @param   pDevIns             The device instance.
     3598     * @thread  Any thread.
     3599     */
     3600    DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
     3601
     3602    /**
     3603     * Write CMOS value and update the checksum(s).
     3604     *
     3605     * @returns VBox status code.
     3606     * @param   pDevIns             The device instance.
     3607     * @param   iReg                The CMOS register index.
     3608     * @param   u8Value             The CMOS register value.
     3609     * @thread  EMT
     3610     */
     3611    DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
     3612
     3613    /**
     3614     * Read CMOS value.
     3615     *
     3616     * @returns VBox status code.
     3617     * @param   pDevIns             The device instance.
     3618     * @param   iReg                The CMOS register index.
     3619     * @param   pu8Value            Where to store the CMOS register value.
     3620     * @thread  EMT
     3621     */
     3622    DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
     3623
     3624    /**
     3625     * Assert that the current thread is the emulation thread.
     3626     *
     3627     * @returns True if correct.
     3628     * @returns False if wrong.
     3629     * @param   pDevIns             The device instance.
     3630     * @param   pszFile             Filename of the assertion location.
     3631     * @param   iLine               The linenumber of the assertion location.
     3632     * @param   pszFunction         Function of the assertion location.
     3633     */
     3634    DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
     3635
     3636    /**
     3637     * Assert that the current thread is NOT the emulation thread.
     3638     *
     3639     * @returns True if correct.
     3640     * @returns False if wrong.
     3641     * @param   pDevIns             The device instance.
     3642     * @param   pszFile             Filename of the assertion location.
     3643     * @param   iLine               The linenumber of the assertion location.
     3644     * @param   pszFunction         Function of the assertion location.
     3645     */
     3646    DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
     3647
     3648    /**
     3649     * Resolves the symbol for a raw-mode context interface.
     3650     *
     3651     * @returns VBox status code.
     3652     * @param   pDevIns             The device instance.
     3653     * @param   pvInterface         The interface structure.
     3654     * @param   cbInterface         The size of the interface structure.
     3655     * @param   pszSymPrefix        What to prefix the symbols in the list with
     3656     *                              before resolving them.  This must start with
     3657     *                              'dev' and contain the driver name.
     3658     * @param   pszSymList          List of symbols corresponding to the interface.
     3659     *                              There is generally a there is generally a define
     3660     *                              holding this list associated with the interface
     3661     *                              definition (INTERFACE_SYM_LIST).  For more
     3662     *                              details see PDMR3LdrGetInterfaceSymbols.
     3663     * @thread  EMT
     3664     */
     3665    DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
     3666                                                           const char *pszSymPrefix, const char *pszSymList));
     3667
     3668    /**
     3669     * Resolves the symbol for a ring-0 context interface.
     3670     *
     3671     * @returns VBox status code.
     3672     * @param   pDevIns             The device instance.
     3673     * @param   pvInterface         The interface structure.
     3674     * @param   cbInterface         The size of the interface structure.
     3675     * @param   pszSymPrefix        What to prefix the symbols in the list with
     3676     *                              before resolving them.  This must start with
     3677     *                              'dev' and contain the driver name.
     3678     * @param   pszSymList          List of symbols corresponding to the interface.
     3679     *                              There is generally a there is generally a define
     3680     *                              holding this list associated with the interface
     3681     *                              definition (INTERFACE_SYM_LIST).  For more
     3682     *                              details see PDMR3LdrGetInterfaceSymbols.
     3683     * @thread  EMT
     3684     */
     3685    DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
     3686                                                           const char *pszSymPrefix, const char *pszSymList));
     3687
     3688    /**
     3689     * Call the ring-0 request handler routine of the device.
     3690     *
     3691     * For this to work, the device must be ring-0 enabled and export a request
     3692     * handler function.  The name of the function must be the device name in
     3693     * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
     3694     * 'ReqHandler'.  The device name will be captialized.  It shall take the
     3695     * exact same arguments as this function and be declared using
     3696     * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
     3697     *
     3698     * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
     3699     * or two as the handler address will be resolved on each invocation.  This
     3700     * is the reason for the EMT only restriction as well.
     3701     *
     3702     * @returns VBox status code.
     3703     * @retval  VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
     3704     *          handler function.
     3705     * @retval  VERR_ACCESS_DENIED if the device isn't ring-0 capable.
     3706     *
     3707     * @param   pDevIns             The device instance.
     3708     * @param   uOperation          The operation to perform.
     3709     * @param   u64Arg              64-bit integer argument.
     3710     * @thread  EMT
     3711     */
     3712    DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
     3713
     3714    /**
     3715     * Gets the reason for the most recent VM suspend.
     3716     *
     3717     * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
     3718     *          suspend has been made or if the pDevIns is invalid.
     3719     * @param   pDevIns             The device instance.
     3720     */
     3721    DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns));
     3722
     3723    /**
     3724     * Gets the reason for the most recent VM resume.
     3725     *
     3726     * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
     3727     *          resume has been made or if the pDevIns is invalid.
     3728     * @param   pDevIns             The device instance.
     3729     */
     3730    DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns));
    36613731
    36623732    /** Space reserved for future members.
     
    36683738    DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
    36693739    DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
    3670     /*DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
     3740    DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
    36713741    DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
    3672     DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));*/
    3673     /*DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));*/
     3742    DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
     3743    DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
    36743744    /** @} */
    36753745
     
    38703940
    38713941/** Current PDMDEVHLPR3 version number. */
    3872 /* 5.0 is (18, 0) so the next version for trunk has to be (19, 0)! */
    3873 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 17, 2)
     3942#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 19, 0)
    38743943
    38753944
     
    38833952
    38843953    /**
    3885      * Bus master physical memory read.
     3954     * Bus master physical memory read from the given PCI device.
    38863955     *
    38873956     * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
    38883957     *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
    38893958     * @param   pDevIns             The device instance.
     3959     * @param   pPciDev             The PCI device structure.  If NULL the default
     3960     *                              PCI device for this device instance is used.
    38903961     * @param   GCPhys              Physical address start reading from.
    38913962     * @param   pvBuf               Where to put the read bits.
     
    38933964     * @thread  Any thread, but the call may involve the emulation thread.
    38943965     */
    3895     DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
    3896 
    3897     /**
    3898      * Bus master physical memory write.
     3966    DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     3967                                              void *pvBuf, size_t cbRead));
     3968
     3969    /**
     3970     * Bus master physical memory write from the given PCI device.
    38993971     *
    39003972     * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
    39013973     *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
    39023974     * @param   pDevIns             The device instance.
     3975     * @param   pPciDev             The PCI device structure.  If NULL the default
     3976     *                              PCI device for this device instance is used.
    39033977     * @param   GCPhys              Physical address to write to.
    39043978     * @param   pvBuf               What to write.
     
    39063980     * @thread  Any thread, but the call may involve the emulation thread.
    39073981     */
    3908     DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
    3909 
    3910     /**
    3911      * Set the IRQ for a PCI device.
     3982    DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     3983                                               const void *pvBuf, size_t cbWrite));
     3984
     3985    /**
     3986     * Set the IRQ for the given PCI device.
    39123987     *
    39133988     * @param   pDevIns         Device instance.
     3989     * @param   pPciDev             The PCI device structure.  If NULL the default
     3990     *                              PCI device for this device instance is used.
    39143991     * @param   iIrq            IRQ number to set.
    39153992     * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
    39163993     * @thread  Any thread, but will involve the emulation thread.
    39173994     */
    3918     DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     3995    DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
    39193996
    39203997    /**
     
    40904167     */
    40914168    DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
     4169
     4170    /** Space reserved for future members.
     4171     * @{ */
     4172    DECLRCCALLBACKMEMBER(void, pfnReserved1,(void));
     4173    DECLRCCALLBACKMEMBER(void, pfnReserved2,(void));
     4174    DECLRCCALLBACKMEMBER(void, pfnReserved3,(void));
     4175    DECLRCCALLBACKMEMBER(void, pfnReserved4,(void));
     4176    DECLRCCALLBACKMEMBER(void, pfnReserved5,(void));
     4177    DECLRCCALLBACKMEMBER(void, pfnReserved6,(void));
     4178    DECLRCCALLBACKMEMBER(void, pfnReserved7,(void));
     4179    DECLRCCALLBACKMEMBER(void, pfnReserved8,(void));
     4180    DECLRCCALLBACKMEMBER(void, pfnReserved9,(void));
     4181    DECLRCCALLBACKMEMBER(void, pfnReserved10,(void));
     4182    /** @} */
    40924183
    40934184    /** Just a safety precaution. */
     
    41004191
    41014192/** Current PDMDEVHLP version number. */
    4102 #define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 4, 1)
     4193#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 5, 0)
    41034194
    41044195
     
    41124203
    41134204    /**
    4114      * Bus master physical memory read.
     4205     * Bus master physical memory read from the given PCI device.
    41154206     *
    41164207     * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
    41174208     *          VERR_EM_MEMORY.
    41184209     * @param   pDevIns             The device instance.
     4210     * @param   pPciDev             The PCI device structure.  If NULL the default
     4211     *                              PCI device for this device instance is used.
    41194212     * @param   GCPhys              Physical address start reading from.
    41204213     * @param   pvBuf               Where to put the read bits.
     
    41224215     * @thread  Any thread, but the call may involve the emulation thread.
    41234216     */
    4124     DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
    4125 
    4126     /**
    4127      * Bus master physical memory write.
     4217    DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     4218                                              void *pvBuf, size_t cbRead));
     4219
     4220    /**
     4221     * Bus master physical memory write from the given PCI device.
    41284222     *
    41294223     * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
    41304224     *          VERR_EM_MEMORY.
    41314225     * @param   pDevIns             The device instance.
     4226     * @param   pPciDev             The PCI device structure.  If NULL the default
     4227     *                              PCI device for this device instance is used.
    41324228     * @param   GCPhys              Physical address to write to.
    41334229     * @param   pvBuf               What to write.
     
    41354231     * @thread  Any thread, but the call may involve the emulation thread.
    41364232     */
    4137     DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
    4138 
    4139     /**
    4140      * Set the IRQ for a PCI device.
    4141      *
    4142      * @param   pDevIns         Device instance.
    4143      * @param   iIrq            IRQ number to set.
    4144      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
     4233    DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     4234                                               const void *pvBuf, size_t cbWrite));
     4235
     4236    /**
     4237     * Set the IRQ for the given PCI device.
     4238     *
     4239     * @param   pDevIns             Device instance.
     4240     * @param   pPciDev             The PCI device structure.  If NULL the default
     4241     *                              PCI device for this device instance is used.
     4242     * @param   iIrq                IRQ number to set.
     4243     * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
    41454244     * @thread  Any thread, but will involve the emulation thread.
    41464245     */
    4147     DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     4246    DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
    41484247
    41494248    /**
     
    43274426     */
    43284427    DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
     4428
     4429    /** Space reserved for future members.
     4430     * @{ */
     4431    DECLR0CALLBACKMEMBER(void, pfnReserved1,(void));
     4432    DECLR0CALLBACKMEMBER(void, pfnReserved2,(void));
     4433    DECLR0CALLBACKMEMBER(void, pfnReserved3,(void));
     4434    DECLR0CALLBACKMEMBER(void, pfnReserved4,(void));
     4435    DECLR0CALLBACKMEMBER(void, pfnReserved5,(void));
     4436    DECLR0CALLBACKMEMBER(void, pfnReserved6,(void));
     4437    DECLR0CALLBACKMEMBER(void, pfnReserved7,(void));
     4438    DECLR0CALLBACKMEMBER(void, pfnReserved8,(void));
     4439    DECLR0CALLBACKMEMBER(void, pfnReserved9,(void));
     4440    DECLR0CALLBACKMEMBER(void, pfnReserved10,(void));
     4441    /** @} */
    43294442
    43304443    /** Just a safety precaution. */
     
    43374450
    43384451/** Current PDMDEVHLP version number. */
    4339 #define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 4, 1)
     4452#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 5, 0)
    43404453
    43414454
     
    46904803 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
    46914804 */
    4692 DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
    4693 {
    4694     return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
     4805DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cb,
     4806                                       uint32_t fFlags, void **ppv, const char *pszDesc)
     4807{
     4808    return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, pPciDev, iRegion, cb, fFlags, ppv, pszDesc);
    46954809}
    46964810
     
    46984812 * @copydoc PDMDEVHLPR3::pfnMMIOExPreRegister
    46994813 */
    4700 DECLINLINE(int) PDMDevHlpMMIOExPreRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
     4814DECLINLINE(int) PDMDevHlpMMIOExPreRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
    47014815                                           uint32_t fFlags, const char *pszDesc, RTHCPTR pvUser,
    47024816                                           PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
     
    47154829 *                              NULL to indicate it is not associated with a device.
    47164830 */
    4717 DECLINLINE(int) PDMDevHlpMMIOExDeregister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion)
    4718 {
    4719     NOREF(pPciDev);
    4720     return pDevIns->pHlpR3->pfnMMIOExDeregister(pDevIns, iRegion);
     4831DECLINLINE(int) PDMDevHlpMMIOExDeregister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion)
     4832{
     4833    return pDevIns->pHlpR3->pfnMMIOExDeregister(pDevIns, pPciDev, iRegion);
    47214834}
    47224835
     
    47264839 *                              NULL to indicate it is not associated with a device.
    47274840 */
    4728 DECLINLINE(int) PDMDevHlpMMIOExMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
    4729 {
    4730     NOREF(pPciDev);
    4731     return pDevIns->pHlpR3->pfnMMIOExMap(pDevIns, iRegion, GCPhys);
     4841DECLINLINE(int) PDMDevHlpMMIOExMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
     4842{
     4843    return pDevIns->pHlpR3->pfnMMIOExMap(pDevIns, pPciDev, iRegion, GCPhys);
    47324844}
    47334845
     
    47374849 *                              NULL to indicate it is not associated with a device.
    47384850 */
    4739 DECLINLINE(int) PDMDevHlpMMIOExUnmap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
    4740 {
    4741     NOREF(pPciDev);
    4742     return pDevIns->pHlpR3->pfnMMIOExUnmap(pDevIns, iRegion, GCPhys);
     4851DECLINLINE(int) PDMDevHlpMMIOExUnmap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
     4852{
     4853    return pDevIns->pHlpR3->pfnMMIOExUnmap(pDevIns, pPciDev, iRegion, GCPhys);
    47434854}
    47444855
     
    47464857 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
    47474858 */
    4748 DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
     4859DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    47494860                                         const char *pszDesc, PRTRCPTR pRCPtr)
    47504861{
    4751     return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
     4862    return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, pPciDev, iRegion, off, cb, pszDesc, pRCPtr);
    47524863}
    47534864
     
    47554866 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
    47564867 */
    4757 DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
     4868DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    47584869                                         const char *pszDesc, PRTR0PTR pR0Ptr)
    47594870{
    4760     return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
     4871    return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, pPciDev, iRegion, off, cb, pszDesc, pR0Ptr);
    47614872}
    47624873
     
    50665177}
    50675178
     5179/*
     5180 * Registers the device with the default PCI bus.
     5181 *
     5182 * @returns VBox status code.
     5183 * @param   pDevIns             The device instance.
     5184 * @param   pPciDev             The PCI device structure.
     5185 *                              This must be kept in the instance data.
     5186 *                              The PCI configuration must be initialized before registration.
     5187 */
     5188DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev)
     5189{
     5190    return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, PDMPCIDEVREG_CFG_NEXT, 0 /*fFlags*/,
     5191                                           PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, NULL);
     5192}
     5193
    50685194/**
    50695195 * @copydoc PDMDEVHLPR3::pfnPCIRegister
    50705196 */
    5071 DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
    5072 {
    5073     return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev);
    5074 }
    5075 
    5076 /**
    5077  * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
     5197DECLINLINE(int) PDMDevHlpPCIRegisterEx(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t idxDevCfg, uint32_t fFlags,
     5198                                       uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
     5199{
     5200    return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, idxDevCfg, fFlags, uPciDevNo, uPciFunNo, pszName);
     5201}
     5202
     5203/**
     5204 * Registers a I/O region (memory mapped or I/O ports) for the default PCI
     5205 * device.
     5206 *
     5207 * @returns VBox status code.
     5208 * @param   pDevIns             The device instance.
     5209 * @param   iRegion             The region number.
     5210 * @param   cbRegion            Size of the region.
     5211 * @param   enmType             PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
     5212 * @param   pfnCallback         Callback for doing the mapping.
     5213 * @remarks The callback will be invoked holding the PDM lock. The device lock
     5214 *          is NOT take because that is very likely be a lock order violation.
    50785215 */
    50795216DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, RTGCPHYS cbRegion,
    50805217                                             PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
    50815218{
    5082     return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
     5219    return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, enmType, pfnCallback);
     5220}
     5221
     5222/**
     5223 * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
     5224 */
     5225DECLINLINE(int) PDMDevHlpPCIIORegionRegisterEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iRegion, RTGCPHYS cbRegion,
     5226                                               PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
     5227{
     5228    return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
     5229}
     5230
     5231/**
     5232 * Initialize MSI support for the first PCI device.
     5233 *
     5234 * @returns VBox status code.
     5235 * @param   pDevIns             The device instance.
     5236 * @param   pMsiReg             MSI registartion structure.
     5237 */
     5238DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
     5239{
     5240    return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, NULL, pMsiReg);
    50835241}
    50845242
     
    50865244 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
    50875245 */
    5088 DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
    5089 {
    5090     return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pMsiReg);
     5246DECLINLINE(int) PDMDevHlpPCIRegisterMsiEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg)
     5247{
     5248    return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pPciDev, pMsiReg);
    50915249}
    50925250
     
    50945252 * @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks
    50955253 */
    5096 DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev,
     5254DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
    50975255                                                PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
    50985256                                                PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
     
    51045262
    51055263/**
     5264 * Bus master physical memory read from the default PCI device.
     5265 *
     5266 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
     5267 *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
     5268 * @param   pDevIns             The device instance.
     5269 * @param   GCPhys              Physical address start reading from.
     5270 * @param   pvBuf               Where to put the read bits.
     5271 * @param   cbRead              How many bytes to read.
     5272 * @thread  Any thread, but the call may involve the emulation thread.
     5273 */
     5274DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
     5275{
     5276    return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, NULL, GCPhys, pvBuf, cbRead);
     5277}
     5278
     5279/**
    51065280 * @copydoc PDMDEVHLPR3::pfnPCIPhysRead
    51075281 */
    5108 DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    5109 {
    5110     return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
     5282DECLINLINE(int) PDMDevHlpPCIPhysReadEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
     5283{
     5284    return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead);
     5285}
     5286
     5287/**
     5288 * Bus master physical memory write from the default PCI device.
     5289 *
     5290 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
     5291 *          VERR_EM_MEMORY.  The informational status shall NOT be propagated!
     5292 * @param   pDevIns             The device instance.
     5293 * @param   GCPhys              Physical address to write to.
     5294 * @param   pvBuf               What to write.
     5295 * @param   cbWrite             How many bytes to write.
     5296 * @thread  Any thread, but the call may involve the emulation thread.
     5297 */
     5298DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
     5299{
     5300    return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, NULL, GCPhys, pvBuf, cbWrite);
    51115301}
    51125302
     
    51145304 * @copydoc PDMDEVHLPR3::pfnPCIPhysWrite
    51155305 */
    5116 DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    5117 {
    5118     return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
     5306DECLINLINE(int) PDMDevHlpPCIPhysWriteEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
     5307{
     5308    return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite);
     5309}
     5310
     5311/**
     5312 * Sets the IRQ for the default PCI device.
     5313 *
     5314 * @param   pDevIns             The device instance.
     5315 * @param   iIrq                IRQ number to set.
     5316 * @param   iLevel              IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
     5317 * @thread  Any thread, but will involve the emulation thread.
     5318 */
     5319DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     5320{
     5321    pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
    51195322}
    51205323
     
    51225325 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
    51235326 */
    5124 DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    5125 {
    5126     pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
     5327DECLINLINE(void) PDMDevHlpPCISetIrqEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
     5328{
     5329    pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
     5330}
     5331
     5332/**
     5333 * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
     5334 * the request when not called from EMT.
     5335 *
     5336 * @param   pDevIns             The device instance.
     5337 * @param   iIrq                IRQ number to set.
     5338 * @param   iLevel              IRQ level.
     5339 * @thread  Any thread, but will involve the emulation thread.
     5340 */
     5341DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     5342{
     5343    pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
    51275344}
    51285345
     
    51305347 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
    51315348 */
    5132 DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    5133 {
    5134     pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
     5349DECLINLINE(void) PDMDevHlpPCISetIrqNoWaitEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
     5350{
     5351    pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
    51355352}
    51365353
  • trunk/include/VBox/vmm/pdmpcidev.h

    r64359 r64373  
    2424 */
    2525
    26 #ifndef ___VBox_pci_h
    27 #define ___VBox_pci_h
    28 
    29 #include <VBox/cdefs.h>
    30 #include <VBox/types.h>
     26#ifndef ___VBox_vmm_pdmpcidev_h
     27#define ___VBox_vmm_pdmpcidev_h
     28
     29#include <VBox/pci.h>
    3130#include <iprt/assert.h>
    3231
    33 /** @defgroup grp_pci       PCI - The PCI Controller.
    34  * @ingroup grp_devdrv
     32
     33/** @defgroup grp_pdm_pcidev       PDM PCI Device
     34 * @ingroup grp_pdm_device
    3535 * @{
    3636 */
    3737
    38 /** Pointer to a PCI device. */
    39 typedef struct PCIDevice *PPCIDEVICE;
    40 
    41 
    42 /**
    43  * PCI configuration word 4 (command) and word 6 (status).
    44  */
    45 typedef enum PCICONFIGCOMMAND
    46 {
    47     /** Supports/uses memory accesses. */
    48     PCI_COMMAND_IOACCESS  = 0x0001,
    49     PCI_COMMAND_MEMACCESS = 0x0002,
    50     PCI_COMMAND_BUSMASTER = 0x0004
    51 } PCICONFIGCOMMAND;
    52 
    53 
    54 /**
    55  * PCI Address space specification.
    56  * This is used when registering a I/O region.
    57  */
    58 /**
    59  * Defined by the PCI specification.
    60  */
    61 typedef enum PCIADDRESSSPACE
    62 {
    63     /** Memory. */
    64     PCI_ADDRESS_SPACE_MEM = 0x00,
    65     /** I/O space. */
    66     PCI_ADDRESS_SPACE_IO = 0x01,
    67     /** 32-bit BAR. */
    68     PCI_ADDRESS_SPACE_BAR32 = 0x00,
    69     /** 64-bit BAR. */
    70     PCI_ADDRESS_SPACE_BAR64 = 0x04,
    71     /** Prefetch memory. */
    72     PCI_ADDRESS_SPACE_MEM_PREFETCH = 0x08
    73 } PCIADDRESSSPACE;
    74 
    75 
    76 /**
    77  * Callback function for mapping an PCI I/O region.
    78  *
    79  * @return VBox status code.
    80  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    81  * @param   iRegion         The region number.
    82  * @param   GCPhysAddress   Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
    83  *                          is an I/O port, otherwise it's a physical address.
    84  *
    85  *                          NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
    86  *                          that the device deregister access handlers for it and update its internal
    87  *                          state to reflect this.
    88  *
    89  * @param   cb              Size of the region in bytes.
    90  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
    91  *
    92  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    93  *          that is very likely be a lock order violation.
    94  */
    95 typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    96                                            RTGCPHYS cb, PCIADDRESSSPACE enmType);
    97 /** Pointer to a FNPCIIOREGIONMAP() function. */
    98 typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
    99 
    100 
    101 /** @name PCI Configuration Space Registers
    102  * @{ */
    103 /* Commented out values common for different header types */
    104 /* Common part of the header */
    105 #define VBOX_PCI_VENDOR_ID              0x00    /**< 16-bit  RO */
    106 #define VBOX_PCI_DEVICE_ID              0x02    /**< 16-bit  RO */
    107 #define VBOX_PCI_COMMAND                0x04    /**< 16-bit  RW, some bits RO */
    108 #define VBOX_PCI_STATUS                 0x06    /**< 16-bit  RW, some bits RO */
    109 #define VBOX_PCI_REVISION_ID            0x08    /**<  8-bit  RO  - - device revision */
    110 #define VBOX_PCI_CLASS_PROG             0x09    /**<  8-bit  RO  - - register-level programming class code (device specific). */
    111 #define VBOX_PCI_CLASS_SUB              0x0a    /**<  8-bit  RO  - - sub-class code. */
    112 #define VBOX_PCI_CLASS_DEVICE           VBOX_PCI_CLASS_SUB
    113 #define VBOX_PCI_CLASS_BASE             0x0b    /**<  8-bit  RO  - - base class code. */
    114 #define VBOX_PCI_CACHE_LINE_SIZE        0x0c    /**<  8-bit  RW  - - system cache line size */
    115 #define VBOX_PCI_LATENCY_TIMER          0x0d    /**<  8-bit  RW  - - master latency timer, hardwired to 0 for PCIe */
    116 #define VBOX_PCI_HEADER_TYPE            0x0e    /**<  8-bit  RO  - - header type (0 - device, 1 - bridge, 2  - CardBus bridge)  */
    117 #define VBOX_PCI_BIST                   0x0f    /**<  8-bit  RW  - - built-in self test control */
    118 #define VBOX_PCI_CAPABILITY_LIST        0x34    /**<  8-bit  RO? - - linked list of new capabilities implemented by the device, 2 bottom bits reserved */
    119 #define VBOX_PCI_INTERRUPT_LINE         0x3c    /**<  8-bit  RW  - - interrupt line. */
    120 #define VBOX_PCI_INTERRUPT_PIN          0x3d    /**<  8-bit  RO  - - interrupt pin.  */
    121 
    122 /* Type 0 header, device */
    123 #define VBOX_PCI_BASE_ADDRESS_0         0x10    /**< 32-bit  RW */
    124 #define VBOX_PCI_BASE_ADDRESS_1         0x14    /**< 32-bit  RW */
    125 #define VBOX_PCI_BASE_ADDRESS_2         0x18    /**< 32-bit  RW */
    126 #define VBOX_PCI_BASE_ADDRESS_3         0x1c    /**< 32-bit  RW */
    127 #define VBOX_PCI_BASE_ADDRESS_4         0x20    /**< 32-bit  RW */
    128 #define VBOX_PCI_BASE_ADDRESS_5         0x24    /**< 32-bit  RW */
    129 #define VBOX_PCI_CARDBUS_CIS            0x28    /**< 32-bit  ?? */
    130 #define VBOX_PCI_SUBSYSTEM_VENDOR_ID    0x2c    /**< 16-bit  RO */
    131 #define VBOX_PCI_SUBSYSTEM_ID           0x2e    /**< 16-bit  RO */
    132 #define VBOX_PCI_ROM_ADDRESS            0x30    /**< 32-bit  ?? */
    133 /* #define VBOX_PCI_CAPABILITY_LIST        0x34 */  /**<  8-bit? ?? */
    134 #define VBOX_PCI_RESERVED_35            0x35    /**<  8-bit  ?? - - reserved */
    135 #define VBOX_PCI_RESERVED_36            0x36    /**<  8-bit  ?? - - reserved */
    136 #define VBOX_PCI_RESERVED_37            0x37    /**<  8-bit  ?? - - reserved */
    137 #define VBOX_PCI_RESERVED_38            0x38    /**<  32-bit ?? - - reserved */
    138 /* #define VBOX_PCI_INTERRUPT_LINE         0x3c */   /**<  8-bit  RW  - - interrupt line. */
    139 /* #define VBOX_PCI_INTERRUPT_PIN          0x3d */   /**<  8-bit  RO  - - interrupt pin.  */
    140 #define VBOX_PCI_MIN_GNT                0x3e    /**<  8-bit  RO - - burst period length (in 1/4 microsecond units)  */
    141 #define VBOX_PCI_MAX_LAT                0x3f    /**<  8-bit  RO - - how often the device needs access to the PCI bus (in 1/4 microsecond units) */
    142 
    143 /* Type 1 header, PCI-to-PCI bridge */
    144 /* #define VBOX_PCI_BASE_ADDRESS_0         0x10 */    /**< 32-bit RW */
    145 /* #define VBOX_PCI_BASE_ADDRESS_1         0x14 */    /**< 32-bit RW */
    146 #define VBOX_PCI_PRIMARY_BUS            0x18    /**<  8-bit  ?? - - primary bus number. */
    147 #define VBOX_PCI_SECONDARY_BUS          0x19    /**<  8-bit  ?? - - secondary bus number. */
    148 #define VBOX_PCI_SUBORDINATE_BUS        0x1a    /**<  8-bit  ?? - - highest subordinate bus number. (behind the bridge) */
    149 #define VBOX_PCI_SEC_LATENCY_TIMER      0x1b    /**<  8-bit  ?? - - secondary latency timer. */
    150 #define VBOX_PCI_IO_BASE                0x1c    /**<  8-bit  ?? - - I/O range base. */
    151 #define VBOX_PCI_IO_LIMIT               0x1d    /**<  8-bit  ?? - - I/O range limit. */
    152 #define VBOX_PCI_SEC_STATUS             0x1e    /**< 16-bit  ?? - - secondary status register. */
    153 #define VBOX_PCI_MEMORY_BASE            0x20    /**< 16-bit  ?? - - memory range base. */
    154 #define VBOX_PCI_MEMORY_LIMIT           0x22    /**< 16-bit  ?? - - memory range limit. */
    155 #define VBOX_PCI_PREF_MEMORY_BASE       0x24    /**< 16-bit  ?? - - prefetchable memory range base. */
    156 #define VBOX_PCI_PREF_MEMORY_LIMIT      0x26    /**< 16-bit  ?? - - prefetchable memory range limit. */
    157 #define VBOX_PCI_PREF_BASE_UPPER32      0x28    /**< 32-bit  ?? - - prefetchable memory range high base.*/
    158 #define VBOX_PCI_PREF_LIMIT_UPPER32     0x2c    /**< 32-bit  ?? - - prefetchable memory range high limit. */
    159 #define VBOX_PCI_IO_BASE_UPPER16        0x30    /**< 16-bit  ?? - - memory range high base. */
    160 #define VBOX_PCI_IO_LIMIT_UPPER16       0x32    /**< 16-bit  ?? - - memory range high limit. */
    161 /* #define VBOX_PCI_CAPABILITY_LIST        0x34 */   /**<  8-bit? ?? */
    162 /* #define VBOX_PCI_RESERVED_35            0x35 */   /**<  8-bit ?? - - reserved */
    163 /* #define VBOX_PCI_RESERVED_36            0x36 */   /**<  8-bit ?? - - reserved */
    164 /* #define VBOX_PCI_RESERVED_37            0x37 */   /**<  8-bit ?? - - reserved */
    165 #define VBOX_PCI_ROM_ADDRESS_BR         0x38    /**< 32-bit  ?? - - expansion ROM base address  */
    166 #define VBOX_PCI_BRIDGE_CONTROL         0x3e    /**< 16-bit?  ?? - - bridge control  */
    167 
    168 /* Type 2 header, PCI-to-CardBus bridge */
    169 #define VBOX_PCI_CARDBUS_BASE_ADDRESS   0x10    /**< 32-bit  RW  - - CardBus Socket/ExCa base address */
    170 #define VBOX_PCI_CARDBUS_CAPLIST        0x14    /**<  8-bit  RO? - - offset of capabilities list */
    171 #define VBOX_PCI_CARDBUS_RESERVED_15    0x15    /**<  8-bit  ??  - - reserved */
    172 #define VBOX_PCI_CARDBUS_SEC_STATUS     0x16    /**< 16-bit  ??  - - secondary status  */
    173 #define VBOX_PCI_CARDBUS_PCIBUS_NUMBER  0x18    /**<  8-bit  ??  - - PCI bus number */
    174 #define VBOX_PCI_CARDBUS_CARDBUS_NUMBER 0x19    /**<  8-bit  ??  - - CardBus bus number */
    175 /* #define VBOX_PCI_SUBORDINATE_BUS        0x1a */    /**<  8-bit  ?? - - highest subordinate bus number. (behind the bridge) */
    176 /* #define VBOX_PCI_SEC_LATENCY_TIMER      0x1b */    /**<  8-bit  ?? - - secondary latency timer. */
    177 #define VBOX_PCI_CARDBUS_MEMORY_BASE0   0x1c     /**< 32-bit  RW  - - memory base address 0 */
    178 #define VBOX_PCI_CARDBUS_MEMORY_LIMIT0  0x20     /**< 32-bit  RW  - - memory limit 0 */
    179 #define VBOX_PCI_CARDBUS_MEMORY_BASE1   0x24     /**< 32-bit  RW  - - memory base address 1 */
    180 #define VBOX_PCI_CARDBUS_MEMORY_LIMIT1  0x28     /**< 32-bit  RW  - - memory limit 1 */
    181 #define VBOX_PCI_CARDBUS_IO_BASE0       0x2c     /**< 32-bit  RW  - - IO base address 0 */
    182 #define VBOX_PCI_CARDBUS_IO_LIMIT0      0x30     /**< 32-bit  RW  - - IO limit 0 */
    183 #define VBOX_PCI_CARDBUS_IO_BASE1       0x34     /**< 32-bit  RW  - - IO base address 1 */
    184 #define VBOX_PCI_CARDBUS_IO_LIMIT1      0x38     /**< 32-bit  RW  - - IO limit 1 */
    185 /* #define VBOX_PCI_INTERRUPT_LINE         0x3c */   /**<  8-bit  RW  - - interrupt line. */
    186 /* #define VBOX_PCI_INTERRUPT_PIN          0x3d */   /**<  8-bit  RO  - - interrupt pin.  */
    187 /* #define VBOX_PCI_BRIDGE_CONTROL         0x3e */   /**< 16-bit?  ?? - - bridge control  */
    188 /** @} */
    189 
    190 
    191 /* Possible values in status bitmask */
    192 #define  VBOX_PCI_STATUS_CAP_LIST    0x10    /* Support Capability List */
    193 #define  VBOX_PCI_STATUS_66MHZ       0x20    /* Support 66 Mhz PCI 2.1 bus */
    194 #define  VBOX_PCI_STATUS_UDF         0x40    /* Support User Definable Features [obsolete] */
    195 #define  VBOX_PCI_STATUS_FAST_BACK   0x80    /* Accept fast-back to back */
    196 #define  VBOX_PCI_STATUS_PARITY      0x100   /* Detected parity error */
    197 #define  VBOX_PCI_STATUS_DEVSEL_MASK 0x600   /* DEVSEL timing */
    198 #define  VBOX_PCI_STATUS_DEVSEL_FAST         0x000
    199 #define  VBOX_PCI_STATUS_DEVSEL_MEDIUM       0x200
    200 #define  VBOX_PCI_STATUS_DEVSEL_SLOW         0x400
    201 #define  VBOX_PCI_STATUS_SIG_TARGET_ABORT    0x800 /* Set on target abort */
    202 #define  VBOX_PCI_STATUS_REC_TARGET_ABORT    0x1000 /* Master ack of " */
    203 #define  VBOX_PCI_STATUS_REC_MASTER_ABORT    0x2000 /* Set on master abort */
    204 #define  VBOX_PCI_STATUS_SIG_SYSTEM_ERROR    0x4000 /* Set when we drive SERR */
    205 #define  VBOX_PCI_STATUS_DETECTED_PARITY     0x8000 /* Set on parity error */
    206 
    207 
    208 /* Command bitmask */
    209 #define  VBOX_PCI_COMMAND_IO           0x1     /* Enable response in I/O space */
    210 #define  VBOX_PCI_COMMAND_MEMORY       0x2     /* Enable response in Memory space */
    211 #define  VBOX_PCI_COMMAND_MASTER       0x4     /* Enable bus mastering */
    212 #define  VBOX_PCI_COMMAND_SPECIAL      0x8     /* Enable response to special cycles */
    213 #define  VBOX_PCI_COMMAND_INVALIDATE   0x10    /* Use memory write and invalidate */
    214 #define  VBOX_PCI_COMMAND_VGA_PALETTE  0x20    /* Enable palette snooping */
    215 #define  VBOX_PCI_COMMAND_PARITY       0x40    /* Enable parity checking */
    216 #define  VBOX_PCI_COMMAND_WAIT         0x80    /* Enable address/data stepping */
    217 #define  VBOX_PCI_COMMAND_SERR         0x100   /* Enable SERR */
    218 #define  VBOX_PCI_COMMAND_FAST_BACK    0x200   /* Enable back-to-back writes */
    219 #define  VBOX_PCI_COMMAND_INTX_DISABLE 0x400   /* INTx Emulation Disable */
    220 
    221 
    222 /* Capability list values (capability offset 0) */
    223 /* Next  value pointer in offset 1, or 0 if none */
    224 #define  VBOX_PCI_CAP_ID_PM          0x01    /* Power Management */
    225 #define  VBOX_PCI_CAP_ID_AGP         0x02    /* Accelerated Graphics Port */
    226 #define  VBOX_PCI_CAP_ID_VPD         0x03    /* Vital Product Data */
    227 #define  VBOX_PCI_CAP_ID_SLOTID      0x04    /* Slot Identification */
    228 #define  VBOX_PCI_CAP_ID_MSI         0x05    /* Message Signalled Interrupts */
    229 #define  VBOX_PCI_CAP_ID_CHSWP       0x06    /* CompactPCI HotSwap */
    230 #define  VBOX_PCI_CAP_ID_PCIX        0x07    /* PCI-X */
    231 #define  VBOX_PCI_CAP_ID_HT          0x08    /* HyperTransport */
    232 #define  VBOX_PCI_CAP_ID_VNDR        0x09    /* Vendor specific */
    233 #define  VBOX_PCI_CAP_ID_DBG         0x0A    /* Debug port */
    234 #define  VBOX_PCI_CAP_ID_CCRC        0x0B    /* CompactPCI Central Resource Control */
    235 #define  VBOX_PCI_CAP_ID_SHPC        0x0C    /* PCI Standard Hot-Plug Controller */
    236 #define  VBOX_PCI_CAP_ID_SSVID       0x0D    /* Bridge subsystem vendor/device ID */
    237 #define  VBOX_PCI_CAP_ID_AGP3        0x0E    /* AGP Target PCI-PCI bridge */
    238 #define  VBOX_PCI_CAP_ID_SECURE      0x0F    /* Secure device (?) */
    239 #define  VBOX_PCI_CAP_ID_EXP         0x10    /* PCI Express */
    240 #define  VBOX_PCI_CAP_ID_MSIX        0x11    /* MSI-X */
    241 #define  VBOX_PCI_CAP_ID_SATA        0x12    /* Serial-ATA HBA */
    242 #define  VBOX_PCI_CAP_ID_AF          0x13    /* PCI Advanced Features */
    243 
    244 /* Extended Capabilities (PCI-X 2.0 and Express), start at 0x100, next - bits [20..32] */
    245 #define  VBOX_PCI_EXT_CAP_ID_ERR     0x01    /* Advanced Error Reporting */
    246 #define  VBOX_PCI_EXT_CAP_ID_VC      0x02    /* Virtual Channel */
    247 #define  VBOX_PCI_EXT_CAP_ID_DSN     0x03    /* Device Serial Number */
    248 #define  VBOX_PCI_EXT_CAP_ID_PWR     0x04    /* Power Budgeting */
    249 #define  VBOX_PCI_EXT_CAP_ID_RCLINK  0x05    /* Root Complex Link Declaration */
    250 #define  VBOX_PCI_EXT_CAP_ID_RCILINK 0x06    /* Root Complex Internal Link Declaration */
    251 #define  VBOX_PCI_EXT_CAP_ID_RCECOLL 0x07    /* Root Complex Event Collector */
    252 #define  VBOX_PCI_EXT_CAP_ID_MFVC    0x08    /* Multi-Function Virtual Channel */
    253 #define  VBOX_PCI_EXT_CAP_ID_RBCB    0x0a    /* Root Bridge Control Block */
    254 #define  VBOX_PCI_EXT_CAP_ID_VNDR    0x0b    /* Vendor specific */
    255 #define  VBOX_PCI_EXT_CAP_ID_ACS     0x0d    /* Access Controls */
    256 #define  VBOX_PCI_EXT_CAP_ID_ARI     0x0e
    257 #define  VBOX_PCI_EXT_CAP_ID_ATS     0x0f
    258 #define  VBOX_PCI_EXT_CAP_ID_SRIOV   0x10
    259 
    260 
    261 /* MSI flags, aka Message Control (2 bytes, capability offset 2) */
    262 #define  VBOX_PCI_MSI_FLAGS_ENABLE   0x0001  /* MSI feature enabled */
    263 #define  VBOX_PCI_MSI_FLAGS_64BIT    0x0080  /* 64-bit addresses allowed */
    264 #define  VBOX_PCI_MSI_FLAGS_MASKBIT  0x0100  /* Per-vector masking support */
    265 /* Encoding for 3-bit patterns for message queue (per chapter 6.8.1 of PCI spec),
    266    someone very similar to log_2().
    267    000 1
    268    001 2
    269    010 4
    270    011 8
    271    100 16
    272    101 32
    273    110 Reserved
    274    111 Reserved */
    275 #define  VBOX_PCI_MSI_FLAGS_QSIZE    0x0070  /* Message queue size configured (i.e. vectors per device allocated) */
    276 #define  VBOX_PCI_MSI_FLAGS_QMASK    0x000e  /* Maximum queue size available (i.e. vectors per device possible) */
    277 
    278 /* MSI-X flags (2 bytes, capability offset 2) */
    279 #define  VBOX_PCI_MSIX_FLAGS_ENABLE   0x8000  /* MSI-X enable */
    280 #define  VBOX_PCI_MSIX_FLAGS_FUNCMASK 0x4000  /* Function mask */
    281 
    282 /* Power management flags (2 bytes, capability offset 2) */
    283 #define  VBOX_PCI_PM_CAP_VER_MASK    0x0007  /* Version mask */
    284 #define  VBOX_PCI_PM_CAP_PME_CLOCK   0x0008  /* PME clock required */
    285 #define  VBOX_PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
    286 #define  VBOX_PCI_PM_CAP_DSI         0x0020  /* Device specific initialization */
    287 #define  VBOX_PCI_PM_CAP_AUX_POWER   0x01C0  /* Auxilliary power support mask */
    288 #define  VBOX_PCI_PM_CAP_D1          0x0200  /* D1 power state support */
    289 #define  VBOX_PCI_PM_CAP_D2          0x0400  /* D2 power state support */
    290 #define  VBOX_PCI_PM_CAP_PME         0x0800  /* PME pin supported */
    291 #define  VBOX_PCI_PM_CAP_PME_MASK    0xF800  /* PME Mask of all supported states */
    292 #define  VBOX_PCI_PM_CAP_PME_D0      0x0800  /* PME# from D0 */
    293 #define  VBOX_PCI_PM_CAP_PME_D1      0x1000  /* PME# from D1 */
    294 #define  VBOX_PCI_PM_CAP_PME_D2      0x2000  /* PME# from D2 */
    295 #define  VBOX_PCI_PM_CAP_PME_D3      0x4000  /* PME# from D3 (hot) */
    296 #define  VBOX_PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
    297 
    298 /* Power management control flags (2 bytes, capability offset 4) */
    299 #define  VBOX_PCI_PM_CTRL_STATE_MASK         0x0003  /* Current power state (D0 to D3) */
    300 #define  VBOX_PCI_PM_CTRL_NO_SOFT_RESET      0x0008  /* No reset for D3hot->D0 */
    301 #define  VBOX_PCI_PM_CTRL_PME_ENABLE         0x0100  /* PME pin enable */
    302 #define  VBOX_PCI_PM_CTRL_DATA_SEL_MASK      0x1e00  /* Data select (??) */
    303 #define  VBOX_PCI_PM_CTRL_DATA_SCALE_MASK    0x6000  /* Data scale (??) */
    304 #define  VBOX_PCI_PM_CTRL_PME_STATUS         0x8000  /* PME pin status */
    305 
    306 /* PCI-X config flags (2 bytes, capability offset 2) */
    307 #define  VBOX_PCI_X_CMD_DPERR_E      0x0001  /* Data Parity Error Recovery Enable */
    308 #define  VBOX_PCI_X_CMD_ERO          0x0002  /* Enable Relaxed Ordering */
    309 #define  VBOX_PCI_X_CMD_MAX_OUTSTANDING_SPLIT_TRANS          0x0070
    310 #define  VBOX_PCI_X_CMD_READ_512     0x0000  /* 512 byte maximum read byte count */
    311 #define  VBOX_PCI_X_CMD_READ_1K      0x0004  /* 1Kbyte maximum read byte count */
    312 #define  VBOX_PCI_X_CMD_READ_2K      0x0008  /* 2Kbyte maximum read byte count */
    313 #define  VBOX_PCI_X_CMD_READ_4K      0x000c  /* 4Kbyte maximum read byte count */
    314 #define  VBOX_PCI_X_CMD_MAX_READ     0x000c  /* Max Memory Read Byte Count */
    315 
    316 /* PCI-X config flags (4 bytes, capability offset 4) */
    317 #define  VBOX_PCI_X_STATUS_DEVFN     0x000000ff      /* A copy of devfn */
    318 #define  VBOX_PCI_X_STATUS_BUS       0x0000ff00      /* A copy of bus nr */
    319 #define  VBOX_PCI_X_STATUS_64BIT     0x00010000      /* 64-bit device */
    320 #define  VBOX_PCI_X_STATUS_133MHZ    0x00020000      /* 133 MHz capable */
    321 #define  VBOX_PCI_X_STATUS_SPL_DISC  0x00040000      /* Split Completion Discarded */
    322 #define  VBOX_PCI_X_STATUS_UNX_SPL   0x00080000      /* Unexpected Split Completion */
    323 #define  VBOX_PCI_X_STATUS_COMPLEX   0x00100000      /* Device Complexity, 0 = simple device, 1 = bridge device */
    324 #define  VBOX_PCI_X_STATUS_MAX_READ  0x00600000      /* Designed Max Memory Read Count, 0 = 512 bytes, 1 = 1024, 2 = 2048, 3 = 4096 */
    325 #define  VBOX_PCI_X_STATUS_MAX_SPLIT 0x03800000      /* Designed Max Outstanding Split Transactions */
    326 #define  VBOX_PCI_X_STATUS_MAX_CUM   0x1c000000      /* Designed Max Cumulative Read Size */
    327 #define  VBOX_PCI_X_STATUS_SPL_ERR   0x20000000      /* Rcvd Split Completion Error Msg */
    328 #define  VBOX_PCI_X_STATUS_266MHZ    0x40000000      /* 266 MHz capable */
    329 #define  VBOX_PCI_X_STATUS_533MHZ    0x80000000      /* 533 MHz capable */
    330 
    331 /* PCI Express config flags (2 bytes, capability offset 2) */
    332 #define  VBOX_PCI_EXP_FLAGS_VERS        0x000f  /* Capability version */
    333 #define  VBOX_PCI_EXP_FLAGS_TYPE        0x00f0  /* Device/Port type */
    334 #define  VBOX_PCI_EXP_TYPE_ENDPOINT     0x0     /* Express Endpoint */
    335 #define  VBOX_PCI_EXP_TYPE_LEG_END      0x1     /* Legacy Endpoint */
    336 #define  VBOX_PCI_EXP_TYPE_ROOT_PORT    0x4     /* Root Port */
    337 #define  VBOX_PCI_EXP_TYPE_UPSTREAM     0x5     /* Upstream Port */
    338 #define  VBOX_PCI_EXP_TYPE_DOWNSTREAM   0x6     /* Downstream Port */
    339 #define  VBOX_PCI_EXP_TYPE_PCI_BRIDGE   0x7     /* PCI/PCI-X Bridge */
    340 #define  VBOX_PCI_EXP_TYPE_PCIE_BRIDGE  0x8     /* PCI/PCI-X to PCIE Bridge */
    341 #define  VBOX_PCI_EXP_TYPE_ROOT_INT_EP  0x9     /* Root Complex Integrated Endpoint */
    342 #define  VBOX_PCI_EXP_TYPE_ROOT_EC      0xa     /* Root Complex Event Collector */
    343 #define  VBOX_PCI_EXP_FLAGS_SLOT        0x0100  /* Slot implemented */
    344 #define  VBOX_PCI_EXP_FLAGS_IRQ         0x3e00  /* Interrupt message number */
    345 
    346 /* PCI Express device capabilities (4 bytes, capability offset 4) */
    347 #define  VBOX_PCI_EXP_DEVCAP_PAYLOAD 0x07        /* Max_Payload_Size */
    348 #define  VBOX_PCI_EXP_DEVCAP_PHANTOM 0x18        /* Phantom functions */
    349 #define  VBOX_PCI_EXP_DEVCAP_EXT_TAG 0x20        /* Extended tags */
    350 #define  VBOX_PCI_EXP_DEVCAP_L0S     0x1c0       /* L0s Acceptable Latency */
    351 #define  VBOX_PCI_EXP_DEVCAP_L1      0xe00       /* L1 Acceptable Latency */
    352 #define  VBOX_PCI_EXP_DEVCAP_ATN_BUT 0x1000      /* Attention Button Present */
    353 #define  VBOX_PCI_EXP_DEVCAP_ATN_IND 0x2000      /* Attention Indicator Present */
    354 #define  VBOX_PCI_EXP_DEVCAP_PWR_IND 0x4000      /* Power Indicator Present */
    355 #define  VBOX_PCI_EXP_DEVCAP_RBE     0x8000      /* Role-Based Error Reporting */
    356 #define  VBOX_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000   /* Slot Power Limit Value */
    357 #define  VBOX_PCI_EXP_DEVCAP_PWR_SCL 0xc000000   /* Slot Power Limit Scale */
    358 #define  VBOX_PCI_EXP_DEVCAP_FLRESET 0x10000000  /* Function-Level Reset */
    359 
    360 /* PCI Express device control (2 bytes, capability offset 8) */
    361 #define  VBOX_PCI_EXP_DEVCTL_CERE    0x0001      /* Correctable Error Reporting En. */
    362 #define  VBOX_PCI_EXP_DEVCTL_NFERE   0x0002      /* Non-Fatal Error Reporting Enable */
    363 #define  VBOX_PCI_EXP_DEVCTL_FERE    0x0004      /* Fatal Error Reporting Enable */
    364 #define  VBOX_PCI_EXP_DEVCTL_URRE    0x0008      /* Unsupported Request Reporting En. */
    365 #define  VBOX_PCI_EXP_DEVCTL_RELAXED 0x0010      /* Enable Relaxed Ordering */
    366 #define  VBOX_PCI_EXP_DEVCTL_PAYLOAD 0x00e0      /* Max_Payload_Size */
    367 #define  VBOX_PCI_EXP_DEVCTL_EXT_TAG 0x0100      /* Extended Tag Field Enable */
    368 #define  VBOX_PCI_EXP_DEVCTL_PHANTOM 0x0200      /* Phantom Functions Enable */
    369 #define  VBOX_PCI_EXP_DEVCTL_AUX_PME 0x0400      /* Auxiliary Power PM Enable */
    370 #define  VBOX_PCI_EXP_DEVCTL_NOSNOOP 0x0800      /* Enable No Snoop */
    371 #define  VBOX_PCI_EXP_DEVCTL_READRQ  0x7000      /* Max_Read_Request_Size */
    372 #define  VBOX_PCI_EXP_DEVCTL_BCRE    0x8000      /* Bridge Configuration Retry Enable */
    373 #define  VBOX_PCI_EXP_DEVCTL_FLRESET 0x8000      /* Function-Level Reset [bit shared with BCRE] */
    374 
    375 /* PCI Express device status (2 bytes, capability offset 10) */
    376 #define  VBOX_PCI_EXP_DEVSTA_CED     0x01         /* Correctable Error Detected */
    377 #define  VBOX_PCI_EXP_DEVSTA_NFED    0x02         /* Non-Fatal Error Detected */
    378 #define  VBOX_PCI_EXP_DEVSTA_FED     0x04         /* Fatal Error Detected */
    379 #define  VBOX_PCI_EXP_DEVSTA_URD     0x08         /* Unsupported Request Detected */
    380 #define  VBOX_PCI_EXP_DEVSTA_AUXPD   0x10         /* AUX Power Detected */
    381 #define  VBOX_PCI_EXP_DEVSTA_TRPND   0x20         /* Transactions Pending */
    382 
    383 /* PCI Express link capabilities (4 bytes, capability offset 12) */
    384 #define  VBOX_PCI_EXP_LNKCAP_SPEED   0x0000f       /* Maximum Link Speed */
    385 #define  VBOX_PCI_EXP_LNKCAP_WIDTH   0x003f0       /* Maximum Link Width */
    386 #define  VBOX_PCI_EXP_LNKCAP_ASPM    0x00c00       /* Active State Power Management */
    387 #define  VBOX_PCI_EXP_LNKCAP_L0S     0x07000       /* L0s Acceptable Latency */
    388 #define  VBOX_PCI_EXP_LNKCAP_L1      0x38000       /* L1 Acceptable Latency */
    389 #define  VBOX_PCI_EXP_LNKCAP_CLOCKPM 0x40000       /* Clock Power Management */
    390 #define  VBOX_PCI_EXP_LNKCAP_SURPRISE 0x80000      /* Surprise Down Error Reporting */
    391 #define  VBOX_PCI_EXP_LNKCAP_DLLA    0x100000      /* Data Link Layer Active Reporting */
    392 #define  VBOX_PCI_EXP_LNKCAP_LBNC    0x200000      /* Link Bandwidth Notification Capability */
    393 #define  VBOX_PCI_EXP_LNKCAP_PORT    0xff000000    /* Port Number */
    394 
    395 /* PCI Express link control (2 bytes, capability offset 16) */
    396 #define  VBOX_PCI_EXP_LNKCTL_ASPM    0x0003        /* ASPM Control */
    397 #define  VBOX_PCI_EXP_LNKCTL_RCB     0x0008        /* Read Completion Boundary */
    398 #define  VBOX_PCI_EXP_LNKCTL_DISABLE 0x0010        /* Link Disable */
    399 #define  VBOX_PCI_EXP_LNKCTL_RETRAIN 0x0020        /* Retrain Link */
    400 #define  VBOX_PCI_EXP_LNKCTL_CLOCK   0x0040        /* Common Clock Configuration */
    401 #define  VBOX_PCI_EXP_LNKCTL_XSYNCH  0x0080        /* Extended Synch */
    402 #define  VBOX_PCI_EXP_LNKCTL_CLOCKPM 0x0100        /* Clock Power Management */
    403 #define  VBOX_PCI_EXP_LNKCTL_HWAUTWD 0x0200        /* Hardware Autonomous Width Disable */
    404 #define  VBOX_PCI_EXP_LNKCTL_BWMIE   0x0400        /* Bandwidth Mgmt Interrupt Enable */
    405 #define  VBOX_PCI_EXP_LNKCTL_AUTBWIE 0x0800        /* Autonomous Bandwidth Mgmt Interrupt Enable */
    406 
    407 /* PCI Express link status (2 bytes, capability offset 18) */
    408 #define  VBOX_PCI_EXP_LNKSTA_SPEED   0x000f        /* Negotiated Link Speed */
    409 #define  VBOX_PCI_EXP_LNKSTA_WIDTH   0x03f0        /* Negotiated Link Width */
    410 #define  VBOX_PCI_EXP_LNKSTA_TR_ERR  0x0400        /* Training Error (obsolete) */
    411 #define  VBOX_PCI_EXP_LNKSTA_TRAIN   0x0800        /* Link Training */
    412 #define  VBOX_PCI_EXP_LNKSTA_SL_CLK  0x1000        /* Slot Clock Configuration */
    413 #define  VBOX_PCI_EXP_LNKSTA_DL_ACT  0x2000        /* Data Link Layer in DL_Active State */
    414 #define  VBOX_PCI_EXP_LNKSTA_BWMGMT  0x4000        /* Bandwidth Mgmt Status */
    415 #define  VBOX_PCI_EXP_LNKSTA_AUTBW   0x8000        /* Autonomous Bandwidth Mgmt Status */
    416 
    417 /* PCI Express slot capabilities (4 bytes, capability offset 20) */
    418 #define  VBOX_PCI_EXP_SLTCAP_ATNB    0x0001        /* Attention Button Present */
    419 #define  VBOX_PCI_EXP_SLTCAP_PWRC    0x0002        /* Power Controller Present */
    420 #define  VBOX_PCI_EXP_SLTCAP_MRL     0x0004        /* MRL Sensor Present */
    421 #define  VBOX_PCI_EXP_SLTCAP_ATNI    0x0008        /* Attention Indicator Present */
    422 #define  VBOX_PCI_EXP_SLTCAP_PWRI    0x0010        /* Power Indicator Present */
    423 #define  VBOX_PCI_EXP_SLTCAP_HPS     0x0020        /* Hot-Plug Surprise */
    424 #define  VBOX_PCI_EXP_SLTCAP_HPC     0x0040        /* Hot-Plug Capable */
    425 #define  VBOX_PCI_EXP_SLTCAP_PWR_VAL 0x00007f80    /* Slot Power Limit Value */
    426 #define  VBOX_PCI_EXP_SLTCAP_PWR_SCL 0x00018000    /* Slot Power Limit Scale */
    427 #define  VBOX_PCI_EXP_SLTCAP_INTERLOCK 0x020000    /* Electromechanical Interlock Present */
    428 #define  VBOX_PCI_EXP_SLTCAP_NOCMDCOMP 0x040000    /* No Command Completed Support */
    429 #define  VBOX_PCI_EXP_SLTCAP_PSN     0xfff80000    /* Physical Slot Number */
    430 
    431 /* PCI Express slot control (2 bytes, capability offset 24) */
    432 #define  VBOX_PCI_EXP_SLTCTL_ATNB    0x0001        /* Attention Button Pressed Enable */
    433 #define  VBOX_PCI_EXP_SLTCTL_PWRF    0x0002        /* Power Fault Detected Enable */
    434 #define  VBOX_PCI_EXP_SLTCTL_MRLS    0x0004        /* MRL Sensor Changed Enable */
    435 #define  VBOX_PCI_EXP_SLTCTL_PRSD    0x0008        /* Presence Detect Changed Enable */
    436 #define  VBOX_PCI_EXP_SLTCTL_CMDC    0x0010        /* Command Completed Interrupt Enable */
    437 #define  VBOX_PCI_EXP_SLTCTL_HPIE    0x0020        /* Hot-Plug Interrupt Enable */
    438 #define  VBOX_PCI_EXP_SLTCTL_ATNI    0x00c0        /* Attention Indicator Control */
    439 #define  VBOX_PCI_EXP_SLTCTL_PWRI    0x0300        /* Power Indicator Control */
    440 #define  VBOX_PCI_EXP_SLTCTL_PWRC    0x0400        /* Power Controller Control */
    441 #define  VBOX_PCI_EXP_SLTCTL_INTERLOCK 0x0800      /* Electromechanical Interlock Control */
    442 #define  VBOX_PCI_EXP_SLTCTL_LLCHG   0x1000        /* Data Link Layer State Changed Enable */
    443 
    444 /* PCI Express slot status (2 bytes, capability offset 26) */
    445 #define  VBOX_PCI_EXP_SLTSTA_ATNB    0x0001        /* Attention Button Pressed */
    446 #define  VBOX_PCI_EXP_SLTSTA_PWRF    0x0002        /* Power Fault Detected */
    447 #define  VBOX_PCI_EXP_SLTSTA_MRLS    0x0004        /* MRL Sensor Changed */
    448 #define  VBOX_PCI_EXP_SLTSTA_PRSD    0x0008        /* Presence Detect Changed */
    449 #define  VBOX_PCI_EXP_SLTSTA_CMDC    0x0010        /* Command Completed */
    450 #define  VBOX_PCI_EXP_SLTSTA_MRL_ST  0x0020        /* MRL Sensor State */
    451 #define  VBOX_PCI_EXP_SLTSTA_PRES    0x0040        /* Presence Detect State */
    452 #define  VBOX_PCI_EXP_SLTSTA_INTERLOCK 0x0080      /* Electromechanical Interlock Status */
    453 #define  VBOX_PCI_EXP_SLTSTA_LLCHG   0x0100        /* Data Link Layer State Changed */
    454 
    455 /* PCI Express root control (2 bytes, capability offset 28) */
    456 #define  VBOX_PCI_EXP_RTCTL_SECEE    0x0001        /* System Error on Correctable Error */
    457 #define  VBOX_PCI_EXP_RTCTL_SENFEE   0x0002        /* System Error on Non-Fatal Error */
    458 #define  VBOX_PCI_EXP_RTCTL_SEFEE    0x0004        /* System Error on Fatal Error */
    459 #define  VBOX_PCI_EXP_RTCTL_PMEIE    0x0008        /* PME Interrupt Enable */
    460 #define  VBOX_PCI_EXP_RTCTL_CRSVIS   0x0010        /* Configuration Request Retry Status Visible to SW */
    461 
    462 /* PCI Express root capabilities (2 bytes, capability offset 30) */
    463 #define  VBOX_PCI_EXP_RTCAP_CRSVIS   0x0010        /* Configuration Request Retry Status Visible to SW */
    464 
    465 /* PCI Express root status (4 bytes, capability offset 32) */
    466 #define  VBOX_PCI_EXP_RTSTA_PME_REQID   0x0000ffff /* PME Requester ID */
    467 #define  VBOX_PCI_EXP_RTSTA_PME_STATUS  0x00010000 /* PME Status */
    468 #define  VBOX_PCI_EXP_RTSTA_PME_PENDING 0x00020000 /* PME is Pending */
     38/** @deprecated. */
     39typedef PPDMPCIDEV          PPCIDEVICE;
     40/** @deprecated. */
     41typedef struct PDMPCIDEV    PCIDEVICE;
     42/** Legacy type name.
     43 * @deprecated  */
     44#define PCIDevice           PDMPCIDEV
    46945
    47046
     
    47349 *
    47450 * @returns The register value.
     51 * @param   pDevIns         Pointer to the device instance the PCI device
     52 *                          belongs to.
    47553 * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    47654 * @param   Address         The configuration space register address. [0..4096]
     
    47957 * @remarks Called with the PDM lock held.  The device lock is NOT take because
    48058 *          that is very likely be a lock order violation.
    481  */
    482 typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb);
     59 *
     60 * @todo add pDevIns parameter.
     61 */
     62typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t Address, unsigned cb);
    48363/** Pointer to a FNPCICONFIGREAD() function. */
    48464typedef FNPCICONFIGREAD *PFNPCICONFIGREAD;
     
    48969 * Callback function for writing to the PCI configuration space.
    49070 *
     71 * @param   pDevIns         Pointer to the device instance the PCI device
     72 *                          belongs to.
    49173 * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    49274 * @param   Address         The configuration space register address. [0..4096]
     
    49779 * @remarks Called with the PDM lock held.  The device lock is NOT take because
    49880 *          that is very likely be a lock order violation.
    499  */
    500 typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
     81 *
     82 * @todo add pDevIns parameter and fix iRegion type.
     83 */
     84typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
    50185/** Pointer to a FNPCICONFIGWRITE() function. */
    50286typedef FNPCICONFIGWRITE *PFNPCICONFIGWRITE;
     
    50488typedef PFNPCICONFIGWRITE *PPFNPCICONFIGWRITE;
    50589
    506 /** Fixed I/O region number for ROM. */
    507 #define PCI_ROM_SLOT    6
    508 #define VBOX_PCI_ROM_SLOT    6
    509 /** Max number of I/O regions. */
    510 #define PCI_NUM_REGIONS 7
    511 #define VBOX_PCI_NUM_REGIONS 7
     90/**
     91 * Callback function for mapping an PCI I/O region.
     92 *
     93 * @returns VBox status code.
     94 * @param   pDevIns         Pointer to the device instance the PCI device
     95 *                          belongs to.
     96 * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
     97 * @param   iRegion         The region number.
     98 * @param   GCPhysAddress   Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
     99 *                          is an I/O port, otherwise it's a physical address.
     100 *
     101 *                          NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
     102 *                          that the device deregister access handlers for it and update its internal
     103 *                          state to reflect this.
     104 *
     105 * @param   cb              Size of the region in bytes.
     106 * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
     107 *
     108 * @remarks Called with the PDM lock held.  The device lock is NOT take because
     109 *          that is very likely be a lock order violation.
     110 *
     111 * @todo add pDevIns parameter and fix iRegion type.
     112 */
     113typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     114                                           RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType);
     115/** Pointer to a FNPCIIOREGIONMAP() function. */
     116typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
     117
    512118
    513119/*
    514  * Hack to include the PCIDEVICEINT structure at the right place
    515  * to avoid duplications of FNPCIIOREGIONMAP and PCI_NUM_REGIONS.
    516  */
    517 #ifdef PCI_INCLUDE_PRIVATE
    518 # include "PCIInternal.h"
    519 #endif
    520 
    521 /**
    522  * PCI Device structure.
    523  */
    524 typedef struct PCIDevice
    525 {
    526     /** PCI config space. */
    527     uint8_t                 config[256];
     120 * Hack to include the PDMPCIDEVICEINT structure at the right place
     121 * to avoid duplications of FNPCIIOREGIONMAP and such.
     122 */
     123#ifdef PDMPCIDEV_INCLUDE_PRIVATE
     124# include "pdmpcidevint.h"
     125#endif
     126
     127/**
     128 * PDM PCI Device structure.
     129 *
     130 * A PCI device belongs to a PDM device.  A PDM device may have zero or more PCI
     131 * devices associated with it.  The first PCI device that it registers
     132 * automatically becomes the default PCI device and can be used implicitly
     133 * with the device helper APIs.  Subsequent PCI devices must be specified
     134 * expeclitly to the device helper APIs when used.
     135 */
     136typedef struct PDMPCIDEV
     137{
     138    union
     139    {
     140        /** PCI config space. */
     141        uint8_t             abConfig[256];
     142#ifndef PDMPCIDEVICE_NO_DEPRECATED
     143        /** @deprecated Use abConfig! */
     144        uint8_t             config[256];
     145#endif
     146    };
    528147
    529148    /** Internal data. */
    530149    union
    531150    {
    532 #ifdef PCIDEVICEINT_DECLARED
    533         PCIDEVICEINT        s;
    534 #endif
    535         char                padding[328];
     151#ifdef PDMPCIDEVICEINT_DECLARED
     152        PDMPCIDEVICEINT     s;
     153#endif
     154        uint8_t             padding[HC_ARCH_BITS == 32 ? 272 : 384];
    536155    } Int;
    537156
    538     /** Read only data.
     157    /** @name Read only data.
    539158     * @{
    540159     */
    541     /** PCI device number on the pci bus. */
    542     int32_t                 devfn;
     160    union
     161    {
     162        /** PCI device number [11:3] and function [2:0] on the pci bus.
     163         * @sa VBOX_PCI_DEVFN_MAKE, VBOX_PCI_DEVFN_FUN_MASK, VBOX_PCI_DEVFN_DEV_SHIFT */
     164        uint32_t            uDevFn;
     165#ifndef PDMPCIDEVICE_NO_DEPRECATED
     166        /** @deprecated Use uDevFn! */
     167        int32_t             devfn;
     168#endif
     169    };
    543170    uint32_t                Alignment0; /**< Alignment. */
    544     /** Device name. */
    545     R3PTRTYPE(const char *) name;
    546     /** Pointer to the device instance which registered the device. */
     171
     172    union
     173    {
     174        /** Device name. */
     175        R3PTRTYPE(const char *) pszNameR3;
     176#ifndef PDMPCIDEVICE_NO_DEPRECATED
     177        /** @deprecated Use pszNameR3! */
     178        R3PTRTYPE(const char *) name;
     179#endif
     180    };
     181    /** Pointer to the device instance which registered the device.
     182     * @todo eliminate this one?  */
    547183    PPDMDEVINSR3            pDevIns;
    548     /**  @} */
    549 } PCIDEVICE;
     184    /** @} */
     185} PDMPCIDEV;
     186#ifdef PDMPCIDEVICEINT_DECLARED
     187AssertCompile(RT_SIZEOFMEMB(PDMPCIDEV, Int.s) <= RT_SIZEOFMEMB(PDMPCIDEV, Int.padding));
     188#endif
     189
     190
     191
     192/** @name PDM PCI config space accessor function.
     193 * @{
     194 */
    550195
    551196/** @todo handle extended space access. */
    552197
    553 DECLINLINE(void)     PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t offReg, uint8_t u8Value)
    554 {
    555     pPciDev->config[offReg] = u8Value;
    556 }
    557 
    558 DECLINLINE(uint8_t)  PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t offReg)
    559 {
    560     return pPciDev->config[offReg];
    561 }
    562 
    563 DECLINLINE(void)     PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t offReg, uint16_t u16Value)
    564 {
    565     *(uint16_t*)&pPciDev->config[offReg] = RT_H2LE_U16(u16Value);
    566 }
    567 
    568 DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t offReg)
    569 {
    570     uint16_t u16Value = *(uint16_t*)&pPciDev->config[offReg];
     198DECLINLINE(void)     PDMPciDevSetByte(PPDMPCIDEV pPciDev, uint32_t offReg, uint8_t u8Value)
     199{
     200    Assert(offReg < sizeof(pPciDev->abConfig));
     201    pPciDev->abConfig[offReg] = u8Value;
     202}
     203
     204DECLINLINE(uint8_t)  PDMPciDevGetByte(PPDMPCIDEV pPciDev, uint32_t offReg)
     205{
     206    Assert(offReg < sizeof(pPciDev->abConfig));
     207    return pPciDev->abConfig[offReg];
     208}
     209
     210DECLINLINE(void)     PDMPciDevSetWord(PPDMPCIDEV pPciDev, uint32_t offReg, uint16_t u16Value)
     211{
     212    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint16_t));
     213    *(uint16_t*)&pPciDev->abConfig[offReg] = RT_H2LE_U16(u16Value);
     214}
     215
     216DECLINLINE(uint16_t) PDMPciDevGetWord(PPDMPCIDEV pPciDev, uint32_t offReg)
     217{
     218    uint16_t u16Value;
     219    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint16_t));
     220    u16Value = *(uint16_t*)&pPciDev->abConfig[offReg];
    571221    return RT_H2LE_U16(u16Value);
    572222}
    573223
    574 DECLINLINE(void)     PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t offReg, uint32_t u32Value)
    575 {
    576     *(uint32_t*)&pPciDev->config[offReg] = RT_H2LE_U32(u32Value);
    577 }
    578 
    579 DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t offReg)
    580 {
    581     uint32_t u32Value = *(uint32_t*)&pPciDev->config[offReg];
     224DECLINLINE(void)     PDMPciDevSetDWord(PPDMPCIDEV pPciDev, uint32_t offReg, uint32_t u32Value)
     225{
     226    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint32_t));
     227    *(uint32_t*)&pPciDev->abConfig[offReg] = RT_H2LE_U32(u32Value);
     228}
     229
     230DECLINLINE(uint32_t) PDMPciDevGetDWord(PPDMPCIDEV pPciDev, uint32_t offReg)
     231{
     232    uint32_t u32Value;
     233    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint32_t));
     234    u32Value = *(uint32_t*)&pPciDev->abConfig[offReg];
    582235    return RT_H2LE_U32(u32Value);
    583236}
    584237
    585 DECLINLINE(void)     PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t offReg, uint64_t u64Value)
    586 {
    587     *(uint64_t*)&pPciDev->config[offReg] = RT_H2LE_U64(u64Value);
    588 }
    589 
    590 DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t offReg)
    591 {
    592     uint64_t u64Value = *(uint64_t*)&pPciDev->config[offReg];
     238DECLINLINE(void)     PDMPciDevSetQWord(PPDMPCIDEV pPciDev, uint32_t offReg, uint64_t u64Value)
     239{
     240    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint64_t));
     241    *(uint64_t*)&pPciDev->abConfig[offReg] = RT_H2LE_U64(u64Value);
     242}
     243
     244DECLINLINE(uint64_t) PDMPciDevGetQWord(PPDMPCIDEV pPciDev, uint32_t offReg)
     245{
     246    uint64_t u64Value;
     247    Assert(offReg <= sizeof(pPciDev->abConfig) - sizeof(uint64_t));
     248    u64Value = *(uint64_t*)&pPciDev->abConfig[offReg];
    593249    return RT_H2LE_U64(u64Value);
    594250}
     
    599255 * @param   u16VendorId     The vendor id.
    600256 */
    601 DECLINLINE(void) PCIDevSetVendorId(PPCIDEVICE pPciDev, uint16_t u16VendorId)
    602 {
    603     PCIDevSetWord(pPciDev, VBOX_PCI_VENDOR_ID, u16VendorId);
     257DECLINLINE(void) PDMPciDevSetVendorId(PPDMPCIDEV pPciDev, uint16_t u16VendorId)
     258{
     259    PDMPciDevSetWord(pPciDev, VBOX_PCI_VENDOR_ID, u16VendorId);
    604260}
    605261
     
    609265 * @param   pPciDev         The PCI device.
    610266 */
    611 DECLINLINE(uint16_t) PCIDevGetVendorId(PPCIDEVICE pPciDev)
    612 {
    613     return PCIDevGetWord(pPciDev, VBOX_PCI_VENDOR_ID);
     267DECLINLINE(uint16_t) PDMPciDevGetVendorId(PPDMPCIDEV pPciDev)
     268{
     269    return PDMPciDevGetWord(pPciDev, VBOX_PCI_VENDOR_ID);
    614270}
    615271
     
    620276 * @param   u16DeviceId     The device id.
    621277 */
    622 DECLINLINE(void) PCIDevSetDeviceId(PPCIDEVICE pPciDev, uint16_t u16DeviceId)
    623 {
    624     PCIDevSetWord(pPciDev, VBOX_PCI_DEVICE_ID, u16DeviceId);
     278DECLINLINE(void) PDMPciDevSetDeviceId(PPDMPCIDEV pPciDev, uint16_t u16DeviceId)
     279{
     280    PDMPciDevSetWord(pPciDev, VBOX_PCI_DEVICE_ID, u16DeviceId);
    625281}
    626282
     
    630286 * @param   pPciDev         The PCI device.
    631287 */
    632 DECLINLINE(uint16_t) PCIDevGetDeviceId(PPCIDEVICE pPciDev)
    633 {
    634     return PCIDevGetWord(pPciDev, VBOX_PCI_DEVICE_ID);
     288DECLINLINE(uint16_t) PDMPciDevGetDeviceId(PPDMPCIDEV pPciDev)
     289{
     290    return PDMPciDevGetWord(pPciDev, VBOX_PCI_DEVICE_ID);
    635291}
    636292
     
    641297 * @param   u16Command      The command register value.
    642298 */
    643 DECLINLINE(void) PCIDevSetCommand(PPCIDEVICE pPciDev, uint16_t u16Command)
    644 {
    645     PCIDevSetWord(pPciDev, VBOX_PCI_COMMAND, u16Command);
     299DECLINLINE(void) PDMPciDevSetCommand(PPDMPCIDEV pPciDev, uint16_t u16Command)
     300{
     301    PDMPciDevSetWord(pPciDev, VBOX_PCI_COMMAND, u16Command);
    646302}
    647303
     
    652308 * @param   pPciDev         The PCI device.
    653309 */
    654 DECLINLINE(uint16_t) PCIDevGetCommand(PPCIDEVICE pPciDev)
    655 {
    656     return PCIDevGetWord(pPciDev, VBOX_PCI_COMMAND);
     310DECLINLINE(uint16_t) PDMPciDevGetCommand(PPDMPCIDEV pPciDev)
     311{
     312    return PDMPciDevGetWord(pPciDev, VBOX_PCI_COMMAND);
    657313}
    658314
     
    662318 * @param   pPciDev         The PCI device.
    663319 */
    664 DECLINLINE(bool) PCIDevIsBusmaster(PPCIDEVICE pPciDev)
    665 {
    666     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
     320DECLINLINE(bool) PDMPciDevIsBusmaster(PPDMPCIDEV pPciDev)
     321{
     322    return (PDMPciDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
    667323}
    668324
     
    672328 * @param   pPciDev         The PCI device.
    673329 */
    674 DECLINLINE(bool) PCIDevIsIntxDisabled(PPCIDEVICE pPciDev)
    675 {
    676     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
     330DECLINLINE(bool) PDMPciDevIsIntxDisabled(PPDMPCIDEV pPciDev)
     331{
     332    return (PDMPciDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
    677333}
    678334
     
    683339 * @param   pPciDev         The PCI device.
    684340 */
    685 DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
    686 {
    687     return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
     341DECLINLINE(uint16_t) PDMPciDevGetStatus(PPDMPCIDEV pPciDev)
     342{
     343    return PDMPciDevGetWord(pPciDev, VBOX_PCI_STATUS);
    688344}
    689345
     
    694350 * @param   u16Status       The status register value.
    695351 */
    696 DECLINLINE(void) PCIDevSetStatus(PPCIDEVICE pPciDev, uint16_t u16Status)
    697 {
    698     PCIDevSetWord(pPciDev, VBOX_PCI_STATUS, u16Status);
     352DECLINLINE(void) PDMPciDevSetStatus(PPDMPCIDEV pPciDev, uint16_t u16Status)
     353{
     354    PDMPciDevSetWord(pPciDev, VBOX_PCI_STATUS, u16Status);
    699355}
    700356
     
    706362 * @param   u8RevisionId    The revision id.
    707363 */
    708 DECLINLINE(void) PCIDevSetRevisionId(PPCIDEVICE pPciDev, uint8_t u8RevisionId)
    709 {
    710     PCIDevSetByte(pPciDev, VBOX_PCI_REVISION_ID, u8RevisionId);
     364DECLINLINE(void) PDMPciDevSetRevisionId(PPDMPCIDEV pPciDev, uint8_t u8RevisionId)
     365{
     366    PDMPciDevSetByte(pPciDev, VBOX_PCI_REVISION_ID, u8RevisionId);
    711367}
    712368
     
    718374 * @param   u8ClassProg     The new value.
    719375 */
    720 DECLINLINE(void) PCIDevSetClassProg(PPCIDEVICE pPciDev, uint8_t u8ClassProg)
    721 {
    722     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_PROG, u8ClassProg);
     376DECLINLINE(void) PDMPciDevSetClassProg(PPDMPCIDEV pPciDev, uint8_t u8ClassProg)
     377{
     378    PDMPciDevSetByte(pPciDev, VBOX_PCI_CLASS_PROG, u8ClassProg);
    723379}
    724380
     
    730386 * @param   u8SubClass      The sub-class.
    731387 */
    732 DECLINLINE(void) PCIDevSetClassSub(PPCIDEVICE pPciDev, uint8_t u8SubClass)
    733 {
    734     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_SUB, u8SubClass);
     388DECLINLINE(void) PDMPciDevSetClassSub(PPDMPCIDEV pPciDev, uint8_t u8SubClass)
     389{
     390    PDMPciDevSetByte(pPciDev, VBOX_PCI_CLASS_SUB, u8SubClass);
    735391}
    736392
     
    742398 * @param   u8BaseClass     The base class.
    743399 */
    744 DECLINLINE(void) PCIDevSetClassBase(PPCIDEVICE pPciDev, uint8_t u8BaseClass)
    745 {
    746     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_BASE, u8BaseClass);
     400DECLINLINE(void) PDMPciDevSetClassBase(PPDMPCIDEV pPciDev, uint8_t u8BaseClass)
     401{
     402    PDMPciDevSetByte(pPciDev, VBOX_PCI_CLASS_BASE, u8BaseClass);
    747403}
    748404
     
    753409 * @param   u8HdrType       The header type.
    754410 */
    755 DECLINLINE(void) PCIDevSetHeaderType(PPCIDEVICE pPciDev, uint8_t u8HdrType)
    756 {
    757     PCIDevSetByte(pPciDev, VBOX_PCI_HEADER_TYPE, u8HdrType);
     411DECLINLINE(void) PDMPciDevSetHeaderType(PPDMPCIDEV pPciDev, uint8_t u8HdrType)
     412{
     413    PDMPciDevSetByte(pPciDev, VBOX_PCI_HEADER_TYPE, u8HdrType);
    758414}
    759415
     
    764420 * @returns u8HdrType       The header type.
    765421 */
    766 DECLINLINE(uint8_t) PCIDevGetHeaderType(PPCIDEVICE pPciDev)
    767 {
    768     return PCIDevGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
     422DECLINLINE(uint8_t) PDMPciDevGetHeaderType(PPDMPCIDEV pPciDev)
     423{
     424    return PDMPciDevGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
    769425}
    770426
     
    775431 * @param   u8Bist          The BIST value.
    776432 */
    777 DECLINLINE(void) PCIDevSetBIST(PPCIDEVICE pPciDev, uint8_t u8Bist)
    778 {
    779     PCIDevSetByte(pPciDev, VBOX_PCI_BIST, u8Bist);
     433DECLINLINE(void) PDMPciDevSetBIST(PPDMPCIDEV pPciDev, uint8_t u8Bist)
     434{
     435    PDMPciDevSetByte(pPciDev, VBOX_PCI_BIST, u8Bist);
    780436}
    781437
     
    786442 * @returns u8Bist          The BIST.
    787443 */
    788 DECLINLINE(uint8_t) PCIDevGetBIST(PPCIDEVICE pPciDev)
    789 {
    790     return PCIDevGetByte(pPciDev, VBOX_PCI_BIST);
     444DECLINLINE(uint8_t) PDMPciDevGetBIST(PPDMPCIDEV pPciDev)
     445{
     446    return PDMPciDevGetByte(pPciDev, VBOX_PCI_BIST);
    791447}
    792448
     
    802458 * @param   u32Addr         The address value.
    803459 */
    804 DECLINLINE(void) PCIDevSetBaseAddress(PPCIDEVICE pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit,
    805                                       uint32_t u32Addr)
     460DECLINLINE(void) PDMPciDevSetBaseAddress(PPDMPCIDEV pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit,
     461                                         uint32_t u32Addr)
    806462{
    807463    if (fIOSpace)
     
    829485    }
    830486
    831     PCIDevSetDWord(pPciDev, iReg, u32Addr);
     487    PDMPciDevSetDWord(pPciDev, iReg, u32Addr);
    832488}
    833489
     
    836492 * the address of some PCI region.
    837493 */
    838 DECLINLINE(uint32_t) PCIDevGetRegionReg(uint32_t iRegion)
     494DECLINLINE(uint32_t) PDMPciDevGetRegionReg(uint32_t iRegion)
    839495{
    840496    return iRegion == VBOX_PCI_ROM_SLOT
     
    848504 * @param   u16SubSysVendorId   The sub-system vendor id.
    849505 */
    850 DECLINLINE(void) PCIDevSetSubSystemVendorId(PPCIDEVICE pPciDev, uint16_t u16SubSysVendorId)
    851 {
    852     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID, u16SubSysVendorId);
     506DECLINLINE(void) PDMPciDevSetSubSystemVendorId(PPDMPCIDEV pPciDev, uint16_t u16SubSysVendorId)
     507{
     508    PDMPciDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID, u16SubSysVendorId);
    853509}
    854510
     
    858514 * @param   pPciDev         The PCI device.
    859515 */
    860 DECLINLINE(uint16_t) PCIDevGetSubSystemVendorId(PPCIDEVICE pPciDev)
    861 {
    862     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID);
     516DECLINLINE(uint16_t) PDMPciDevGetSubSystemVendorId(PPDMPCIDEV pPciDev)
     517{
     518    return PDMPciDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID);
    863519}
    864520
     
    870526 * @param   u16SubSystemId  The sub-system id.
    871527 */
    872 DECLINLINE(void) PCIDevSetSubSystemId(PPCIDEVICE pPciDev, uint16_t u16SubSystemId)
    873 {
    874     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID, u16SubSystemId);
     528DECLINLINE(void) PDMPciDevSetSubSystemId(PPDMPCIDEV pPciDev, uint16_t u16SubSystemId)
     529{
     530    PDMPciDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID, u16SubSystemId);
    875531}
    876532
     
    880536 * @param   pPciDev         The PCI device.
    881537 */
    882 DECLINLINE(uint16_t) PCIDevGetSubSystemId(PPCIDEVICE pPciDev)
    883 {
    884     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID);
     538DECLINLINE(uint16_t) PDMPciDevGetSubSystemId(PPDMPCIDEV pPciDev)
     539{
     540    return PDMPciDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID);
    885541}
    886542
     
    891547 * @param   u8Offset        The offset to capability list.
    892548 */
    893 DECLINLINE(void) PCIDevSetCapabilityList(PPCIDEVICE pPciDev, uint8_t u8Offset)
    894 {
    895     PCIDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
     549DECLINLINE(void) PDMPciDevSetCapabilityList(PPDMPCIDEV pPciDev, uint8_t u8Offset)
     550{
     551    PDMPciDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
    896552}
    897553
     
    902558 * @param   pPciDev         The PCI device.
    903559 */
    904 DECLINLINE(uint8_t) PCIDevGetCapabilityList(PPCIDEVICE pPciDev)
    905 {
    906     return PCIDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
     560DECLINLINE(uint8_t) PDMPciDevGetCapabilityList(PPDMPCIDEV pPciDev)
     561{
     562    return PDMPciDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
    907563}
    908564
     
    913569 * @param   u8Line          The interrupt line.
    914570 */
    915 DECLINLINE(void) PCIDevSetInterruptLine(PPCIDEVICE pPciDev, uint8_t u8Line)
    916 {
    917     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE, u8Line);
     571DECLINLINE(void) PDMPciDevSetInterruptLine(PPDMPCIDEV pPciDev, uint8_t u8Line)
     572{
     573    PDMPciDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE, u8Line);
    918574}
    919575
     
    924580 * @param   pPciDev         The PCI device.
    925581 */
    926 DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev)
    927 {
    928     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE);
     582DECLINLINE(uint8_t) PDMPciDevGetInterruptLine(PPDMPCIDEV pPciDev)
     583{
     584    return PDMPciDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE);
    929585}
    930586
     
    935591 * @param   u8Pin           The interrupt pin.
    936592 */
    937 DECLINLINE(void) PCIDevSetInterruptPin(PPCIDEVICE pPciDev, uint8_t u8Pin)
    938 {
    939     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN, u8Pin);
     593DECLINLINE(void) PDMPciDevSetInterruptPin(PPDMPCIDEV pPciDev, uint8_t u8Pin)
     594{
     595    PDMPciDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN, u8Pin);
    940596}
    941597
     
    946602 * @param   pPciDev         The PCI device.
    947603 */
    948 DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev)
    949 {
    950     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN);
    951 }
    952 
    953 #ifdef PCIDEVICEINT_DECLARED
    954 DECLINLINE(void) pciDevSetRequestedDevfunc(PPCIDEVICE pDev)
    955 {
    956     pDev->Int.s.fFlags |= PCIDEV_FLAG_REQUESTED_DEVFUNC;
    957 }
    958 
    959 DECLINLINE(void) pciDevClearRequestedDevfunc(PPCIDEVICE pDev)
    960 {
    961     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_REQUESTED_DEVFUNC;
    962 }
    963 
    964 DECLINLINE(bool) pciDevIsRequestedDevfunc(PPCIDEVICE pDev)
    965 {
    966     return (pDev->Int.s.fFlags & PCIDEV_FLAG_REQUESTED_DEVFUNC) != 0;
    967 }
    968 
    969 DECLINLINE(void) pciDevSetPci2PciBridge(PPCIDEVICE pDev)
    970 {
    971     pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_TO_PCI_BRIDGE;
    972 }
    973 
    974 DECLINLINE(bool) pciDevIsPci2PciBridge(PPCIDEVICE pDev)
    975 {
    976     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_TO_PCI_BRIDGE) != 0;
    977 }
    978 
    979 DECLINLINE(void) pciDevSetPciExpress(PPCIDEVICE pDev)
    980 {
    981     pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_EXPRESS_DEVICE;
    982 }
    983 
    984 DECLINLINE(bool) pciDevIsPciExpress(PPCIDEVICE pDev)
    985 {
    986     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_EXPRESS_DEVICE) != 0;
    987 }
    988 
    989 DECLINLINE(void) pciDevSetMsiCapable(PPCIDEVICE pDev)
    990 {
    991     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI_CAPABLE;
    992 }
    993 
    994 DECLINLINE(void) pciDevClearMsiCapable(PPCIDEVICE pDev)
    995 {
    996     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI_CAPABLE;
    997 }
    998 
    999 DECLINLINE(bool) pciDevIsMsiCapable(PPCIDEVICE pDev)
    1000 {
    1001     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI_CAPABLE) != 0;
    1002 }
    1003 
    1004 DECLINLINE(void) pciDevSetMsi64Capable(PPCIDEVICE pDev)
    1005 {
    1006     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI64_CAPABLE;
    1007 }
    1008 
    1009 DECLINLINE(void) pciDevClearMsi64Capable(PPCIDEVICE pDev)
    1010 {
    1011     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI64_CAPABLE;
    1012 }
    1013 
    1014 DECLINLINE(bool) pciDevIsMsi64Capable(PPCIDEVICE pDev)
    1015 {
    1016     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI64_CAPABLE) != 0;
    1017 }
    1018 
    1019 DECLINLINE(void) pciDevSetMsixCapable(PPCIDEVICE pDev)
    1020 {
    1021     pDev->Int.s.fFlags |= PCIDEV_FLAG_MSIX_CAPABLE;
    1022 }
    1023 
    1024 DECLINLINE(void) pciDevClearMsixCapable(PPCIDEVICE pDev)
    1025 {
    1026     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSIX_CAPABLE;
    1027 }
    1028 
    1029 DECLINLINE(bool) pciDevIsMsixCapable(PPCIDEVICE pDev)
    1030 {
    1031     return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSIX_CAPABLE) != 0;
    1032 }
    1033 
    1034 DECLINLINE(void) pciDevSetPassthrough(PPCIDEVICE pDev)
    1035 {
    1036     pDev->Int.s.fFlags |= PCIDEV_FLAG_PASSTHROUGH;
    1037 }
    1038 
    1039 DECLINLINE(void) pciDevClearPassthrough(PPCIDEVICE pDev)
    1040 {
    1041     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_PASSTHROUGH;
    1042 }
    1043 
    1044 DECLINLINE(bool) pciDevIsPassthrough(PPCIDEVICE pDev)
    1045 {
    1046     return (pDev->Int.s.fFlags & PCIDEV_FLAG_PASSTHROUGH) != 0;
    1047 }
    1048 
    1049 #endif /* PCIDEVICEINT_DECLARED */
    1050 
    1051 #if defined(__cplusplus) && defined(IN_RING3)
    1052 /* For RTStrPrintf(). */
    1053 #include <iprt/string.h>
    1054 
    1055 /**
    1056  * Class representing PCI address. PCI device consist of
    1057  * bus, device and function numbers. Generally device PCI
    1058  * address could be changed during runtime, but only by
    1059  * an OS PCI driver.
    1060  *
    1061  * @remarks C++ classes (structs included) are not generally accepted in
    1062  *          VMM devices or drivers.  An exception may be granted for this class
    1063  *          if it's contained to ring-3 and that this is a one time exception
    1064  *          which sets no precedent.
    1065  */
    1066 struct PCIBusAddress
    1067 {
    1068     /** @todo: think if we'll need domain, which is higher
    1069      *  word of the address. */
    1070     int  miBus;
    1071     int  miDevice;
    1072     int  miFn;
    1073 
    1074     PCIBusAddress()
    1075     {
    1076         clear();
    1077     }
    1078 
    1079     PCIBusAddress(int iBus, int iDevice, int iFn)
    1080     {
    1081         init(iBus, iDevice, iFn);
    1082     }
    1083 
    1084     PCIBusAddress(int32_t iAddr)
    1085     {
    1086         clear();
    1087         fromLong(iAddr);
    1088     }
    1089 
    1090     PCIBusAddress& clear()
    1091     {
    1092         miBus = miDevice = miFn = -1;
    1093         return *this;
    1094     }
    1095 
    1096     void init(int iBus, int iDevice, int iFn)
    1097     {
    1098         miBus    = iBus;
    1099         miDevice = iDevice;
    1100         miFn     = iFn;
    1101     }
    1102 
    1103     void init(const PCIBusAddress &a)
    1104     {
    1105         miBus    = a.miBus;
    1106         miDevice = a.miDevice;
    1107         miFn     = a.miFn;
    1108     }
    1109 
    1110     bool operator<(const PCIBusAddress &a) const
    1111     {
    1112         if (miBus < a.miBus)
    1113             return true;
    1114 
    1115         if (miBus > a.miBus)
    1116             return false;
    1117 
    1118         if (miDevice < a.miDevice)
    1119             return true;
    1120 
    1121         if (miDevice > a.miDevice)
    1122             return false;
    1123 
    1124         if (miFn < a.miFn)
    1125             return true;
    1126 
    1127         if (miFn > a.miFn)
    1128             return false;
    1129 
    1130         return false;
    1131     }
    1132 
    1133     bool operator==(const PCIBusAddress &a) const
    1134     {
    1135         return     (miBus    == a.miBus)
    1136                 && (miDevice == a.miDevice)
    1137                 && (miFn     == a.miFn);
    1138     }
    1139 
    1140     bool operator!=(const PCIBusAddress &a) const
    1141     {
    1142         return     (miBus    != a.miBus)
    1143                 || (miDevice != a.miDevice)
    1144                 || (miFn     != a.miFn);
    1145     }
    1146 
    1147     bool valid() const
    1148     {
    1149         return (miBus    != -1)
    1150             && (miDevice != -1)
    1151             && (miFn     != -1);
    1152     }
    1153 
    1154     int32_t asLong() const
    1155     {
    1156         Assert(valid());
    1157         return (miBus << 8) | (miDevice << 3) | miFn;
    1158     }
    1159 
    1160     PCIBusAddress& fromLong(int32_t value)
    1161     {
    1162         miBus = (value >> 8) & 0xff;
    1163         miDevice = (value & 0xff) >> 3;
    1164         miFn = (value & 7);
    1165         return *this;
    1166     }
    1167 
    1168     /** Create string representation of this PCI address. */
    1169     bool format(char* szBuf, int32_t cBufSize)
    1170     {
    1171         if (cBufSize < (/* bus */ 2 + /* : */ 1 + /* device */ 2 + /* . */ 1 + /* function*/ 1 + /* \0 */1))
    1172             return false;
    1173 
    1174         if (valid())
    1175             RTStrPrintf(szBuf, cBufSize, "%02x:%02x.%01x", miBus, miDevice, miFn);
    1176         else
    1177             RTStrPrintf(szBuf, cBufSize, "%s", "<bad>");
    1178 
    1179         return true;
    1180     }
    1181 
    1182     static const size_t cMaxAddrSize = 10;
    1183 };
    1184 #endif /* __cplusplus */
     604DECLINLINE(uint8_t) PDMPciDevGetInterruptPin(PPDMPCIDEV pPciDev)
     605{
     606    return PDMPciDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN);
     607}
    1185608
    1186609/** @} */
    1187610
    1188 #endif
     611/** @name Aliases for old function names.
     612 * @{
     613 */
     614#if !defined(PDMPCIDEVICE_NO_DEPRECATED) || defined(DOXYGEN_RUNNING)
     615# define PCIDevSetByte               PDMPciDevSetByte
     616# define PCIDevGetByte               PDMPciDevGetByte
     617# define PCIDevSetWord               PDMPciDevSetWord
     618# define PCIDevGetWord               PDMPciDevGetWord
     619# define PCIDevSetDWord              PDMPciDevSetDWord
     620# define PCIDevGetDWord              PDMPciDevGetDWord
     621# define PCIDevSetQWord              PDMPciDevSetQWord
     622# define PCIDevGetQWord              PDMPciDevGetQWord
     623# define PCIDevSetVendorId           PDMPciDevSetVendorId
     624# define PCIDevGetVendorId           PDMPciDevGetVendorId
     625# define PCIDevSetDeviceId           PDMPciDevSetDeviceId
     626# define PCIDevGetDeviceId           PDMPciDevGetDeviceId
     627# define PCIDevSetCommand            PDMPciDevSetCommand
     628# define PCIDevGetCommand            PDMPciDevGetCommand
     629# define PCIDevIsBusmaster           PDMPciDevIsBusmaster
     630# define PCIDevIsIntxDisabled        PDMPciDevIsIntxDisabled
     631# define PCIDevGetStatus             PDMPciDevGetStatus
     632# define PCIDevSetStatus             PDMPciDevSetStatus
     633# define PCIDevSetRevisionId         PDMPciDevSetRevisionId
     634# define PCIDevSetClassProg          PDMPciDevSetClassProg
     635# define PCIDevSetClassSub           PDMPciDevSetClassSub
     636# define PCIDevSetClassBase          PDMPciDevSetClassBase
     637# define PCIDevSetHeaderType         PDMPciDevSetHeaderType
     638# define PCIDevGetHeaderType         PDMPciDevGetHeaderType
     639# define PCIDevSetBIST               PDMPciDevSetBIST
     640# define PCIDevGetBIST               PDMPciDevGetBIST
     641# define PCIDevSetBaseAddress        PDMPciDevSetBaseAddress
     642# define PCIDevGetRegionReg          PDMPciDevGetRegionReg
     643# define PCIDevSetSubSystemVendorId  PDMPciDevSetSubSystemVendorId
     644# define PCIDevGetSubSystemVendorId  PDMPciDevGetSubSystemVendorId
     645# define PCIDevSetSubSystemId        PDMPciDevSetSubSystemId
     646# define PCIDevGetSubSystemId        PDMPciDevGetSubSystemId
     647# define PCIDevSetCapabilityList     PDMPciDevSetCapabilityList
     648# define PCIDevGetCapabilityList     PDMPciDevGetCapabilityList
     649# define PCIDevSetInterruptLine      PDMPciDevSetInterruptLine
     650# define PCIDevGetInterruptLine      PDMPciDevGetInterruptLine
     651# define PCIDevSetInterruptPin       PDMPciDevSetInterruptPin
     652# define PCIDevGetInterruptPin       PDMPciDevGetInterruptPin
     653#endif
     654/** @} */
     655
     656
     657/** @} */
     658
     659#endif
  • trunk/include/VBox/vmm/pdmpcidevint.h

    r64372 r64373  
    11/* $Id$ */
    22/** @file
    3  * DevPCI - PCI Internal header - Only for hiding bits of PCIDEVICE.
     3 * DevPCI - PDM PCI Internal header - Only for hiding bits of PCIDEVICE.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___PCIInternal_h
    19 #define ___PCIInternal_h
    20 
    21 /** @defgroup grp_pci_int   PCI Internals
    22  * @ingroup grp_pci
    23  * @internal
     18#ifndef ___VBox_vmm_pdmpcidevint_h
     19#define ___VBox_vmm_pdmpcidevint_h
     20
     21#include <VBox/vmm/pdmdev.h>
     22
     23/** @defgroup grp_pdm_pcidev_int    The PDM PCI Device Internals
     24 * @ingroup grp_pdm_pci
     25 *
     26 * @remarks The PDM PCI device internals are visible to both PDM and the PCI Bus
     27 *          implementation, thus it lives among the the public headers despite
     28 *          being rather private and internal.
     29 *
    2430 * @{
    2531 */
     
    7985
    8086enum {
    81     /** Set if the specific device function was requested by PDM.
    82      * If clear the device and it's functions can be relocated to satisfy the slot request of another device. */
    83     PCIDEV_FLAG_REQUESTED_DEVFUNC  = RT_BIT_32(0),
    8487    /** Flag whether the device is a pci-to-pci bridge.
    8588     * This is set prior to device registration.  */
     
    101104};
    102105
    103 /**
    104  * PCI Device - Internal data.
    105  */
    106 typedef struct PCIDEVICEINT
     106
     107/**
     108 * PDM PCI Device - Internal data.
     109 *
     110 * @sa PDMPCIDEVICE
     111 */
     112typedef struct PDMPCIDEVICEINT
    107113{
    108     /** I/O regions. */
    109     PCIIOREGION                     aIORegions[VBOX_PCI_NUM_REGIONS];
     114    /** @name Owned by PDM.
     115     * @remarks The bus may use the device instance pointers.
     116     * @{
     117     */
     118    /** Pointer to the PDM device the PCI device belongs to. (R3 ptr)  */
     119    PPDMDEVINSR3                    pDevInsR3;
     120    /** Pointer to the next PDM device associate with the PDM device. (R3 ptr) */
     121    R3PTRTYPE(PPDMPCIDEV)        pNextR3;
     122    /** Pointer to the internal PDM PCI bus for the device. (R3 ptr) */
     123    R3PTRTYPE(struct PDMPCIBUS *)   pPdmBusR3;
     124
     125    /** Pointer to the PDM device the PCI device belongs to. (R0 ptr)  */
     126    PPDMDEVINSR0                    pDevInsR0;
     127    /** Pointer to the next PDM device associate with the PDM device. (R0 ptr) */
     128    R0PTRTYPE(PPDMPCIDEV)        pNextR0;
     129    /** Pointer to the internal PDM PCI bus for the device. (R0 ptr) */
     130    R0PTRTYPE(struct PDMPCIBUS *)   pPdmBusR0;
     131
     132    /** Pointer to the PDM device the PCI device belongs to. (RC ptr)  */
     133    PPDMDEVINSRC                    pDevInsRC;
     134    /** Pointer to the next PDM device associate with the PDM device. (RC ptr) */
     135    RCPTRTYPE(PPDMPCIDEV)        pNextRC;
     136    /** Pointer to the internal PDM PCI bus for the device. (RC ptr) */
     137    RCPTRTYPE(struct PDMPCIBUS *)   pPdmBusRC;
     138
     139    /** The CFGM device configuration index (default, PciDev1..255).
     140     * This also works as the internal sub-device ordinal with MMIOEx. */
     141    uint8_t                         idxDevCfg;
     142    /** Set if the it can be reassigned to a different PCI device number. */
     143    bool                            fReassignableDevNo;
     144    /** Set if the it can be reassigned to a different PCI function number. */
     145    bool                            fReassignableFunNo;
     146    /** Alignment padding.   */
     147    uint8_t                         bPadding0;
     148    /** @} */
     149
     150    /** @name Owned by the PCI Bus
     151     * @remarks PDM will not touch anything here (includes not relocating anything).
     152     * @{
     153     */
    110154    /** Pointer to the PCI bus of the device. (R3 ptr) */
    111155    R3PTRTYPE(struct PCIBus *)      pBusR3;
    112     /** Pointer to the PCI bus of the device. (R0 ptr) */
    113     R0PTRTYPE(struct PCIBus *)      pBusR0;
    114     /** Pointer to the PCI bus of the device. (RC ptr) */
    115     RCPTRTYPE(struct PCIBus *)      pBusRC;
    116 
    117     /** Page used for MSI-X state.             (RC ptr) */
    118     RCPTRTYPE(void *)               pMsixPageRC;
    119156    /** Page used for MSI-X state.             (R3 ptr) */
    120157    R3PTRTYPE(void *)               pMsixPageR3;
    121     /** Page used for MSI-X state.             (R0 ptr) */
    122     R0PTRTYPE(void *)               pMsixPageR0;
    123 
    124158    /** Read config callback. */
    125159    R3PTRTYPE(PFNPCICONFIGREAD)     pfnConfigRead;
    126160    /** Write config callback. */
    127161    R3PTRTYPE(PFNPCICONFIGWRITE)    pfnConfigWrite;
    128 
    129     /** Flags of this PCI device, see PCIDEV_FLAG_XXX constants. */
    130     uint32_t                        fFlags;
    131     /** Current state of the IRQ pin of the device. */
    132     int32_t                         uIrqPinState;
    133 
    134     /** Offset of MSI PCI capability in config space, or 0. */
    135     uint8_t                         u8MsiCapOffset;
    136     /** Size of MSI PCI capability in config space, or 0. */
    137     uint8_t                         u8MsiCapSize;
    138     /** Offset of MSI-X PCI capability in config space, or 0. */
    139     uint8_t                         u8MsixCapOffset;
    140     /** Size of MSI-X PCI capability in config space, or 0. */
    141     uint8_t                         u8MsixCapSize;
    142 
    143     /** Explicit alignment padding. */
    144     uint32_t                        u32Alignment0;
    145 
    146     /** Pointer to bus specific data.                 (R3 ptr) */
    147     R3PTRTYPE(const void *)         pPciBusPtrR3;
    148 
    149162    /** Read config callback for PCI bridges to pass requests
    150163     * to devices on another bus. */
     
    154167    R3PTRTYPE(PFNPCIBRIDGECONFIGWRITE) pfnBridgeConfigWrite;
    155168
    156 } PCIDEVICEINT;
     169    /** Pointer to the PCI bus of the device. (R0 ptr) */
     170    R0PTRTYPE(struct PCIBus *)      pBusR0;
     171    /** Page used for MSI-X state.             (R0 ptr) */
     172    R0PTRTYPE(void *)               pMsixPageR0;
     173
     174    /** Pointer to the PCI bus of the device. (RC ptr) */
     175    RCPTRTYPE(struct PCIBus *)      pBusRC;
     176    /** Page used for MSI-X state.             (RC ptr) */
     177    RCPTRTYPE(void *)               pMsixPageRC;
     178
     179    /** Flags of this PCI device, see PCIDEV_FLAG_XXX constants. */
     180    uint32_t                        fFlags;
     181    /** Current state of the IRQ pin of the device. */
     182    int32_t                         uIrqPinState;
     183
     184    /** Offset of MSI PCI capability in config space, or 0.
     185     * @todo fix non-standard naming.  */
     186    uint8_t                         u8MsiCapOffset;
     187    /** Size of MSI PCI capability in config space, or 0.
     188     * @todo fix non-standard naming.  */
     189    uint8_t                         u8MsiCapSize;
     190    /** Offset of MSI-X PCI capability in config space, or 0.
     191     * @todo fix non-standard naming.  */
     192    uint8_t                         u8MsixCapOffset;
     193    /** Size of MSI-X PCI capability in config space, or 0.
     194     * @todo fix non-standard naming.  */
     195    uint8_t                         u8MsixCapSize;
     196#if HC_ARCH_BITS == 64
     197    /** Explicit alignment padding.   */
     198    uint8_t                         abPadding1[HC_ARCH_BITS == 32 ? 0 : 4];
     199#endif
     200
     201    /** Pointer to bus specific data. (R3 ptr) */
     202    R3PTRTYPE(const void *)         pPciBusPtrR3;
     203
     204    /** I/O regions. */
     205    PCIIOREGION                     aIORegions[VBOX_PCI_NUM_REGIONS];
     206    /** @}  */
     207} PDMPCIDEVICEINT;
     208AssertCompileMemberAlignment(PDMPCIDEVICEINT, aIORegions, 8);
     209AssertCompileSize(PDMPCIDEVICEINT, HC_ARCH_BITS == 32 ? 264 : 384);
    157210
    158211/** Indicate that PCIDEVICE::Int.s can be declared. */
    159 #define PCIDEVICEINT_DECLARED
     212#define PDMPCIDEVICEINT_DECLARED
    160213
    161214/** @} */
    162215
    163216#endif
     217
  • trunk/include/VBox/vmm/pgm.h

    r64203 r64373  
    741741                                          RTR3PTR pvUserR3, RTR0PTR pvUserR0, RTRCPTR pvUserRC, const char *pszDesc);
    742742VMMR3DECL(int)      PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
    743 VMMR3DECL(int)      PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
    744 VMMR3DECL(int)      PGMR3PhysMMIOExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion, PGMPHYSHANDLERTYPE hType,
     743VMMR3DECL(int)      PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
     744VMMR3DECL(int)      PGMR3PhysMMIOExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRegion, PGMPHYSHANDLERTYPE hType,
    745745                                               RTR3PTR pvUserR3, RTR0PTR pvUserR0, RTRCPTR pvUserRC, const char *pszDesc);
    746 VMMR3DECL(int)      PGMR3PhysMMIOExDeregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion);
    747 VMMR3DECL(int)      PGMR3PhysMMIOExMap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
    748 VMMR3DECL(int)      PGMR3PhysMMIOExUnmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
     746VMMR3DECL(int)      PGMR3PhysMMIOExDeregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion);
     747VMMR3DECL(int)      PGMR3PhysMMIOExMap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS GCPhys);
     748VMMR3DECL(int)      PGMR3PhysMMIOExUnmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS GCPhys);
    749749VMMR3DECL(bool)     PGMR3PhysMMIOExIsBase(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys);
    750 VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
    751 VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
     750VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
     751VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
    752752
    753753/** @name PGMR3PhysRegisterRom flags.
  • trunk/src/VBox/Devices/Audio/DevHDA.cpp

    r64351 r64373  
    47694769 * @callback_method_impl{FNPCIIOREGIONMAP}
    47704770 */
    4771 static DECLCALLBACK(int)
    4772 hdaPciIoRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     4771static DECLCALLBACK(int)  hdaPciIoRegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     4772                                            RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    47734773{
    47744774    RT_NOREF(iRegion, enmType);
    4775     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    47764775    PHDASTATE   pThis = RT_FROM_MEMBER(pPciDev, HDASTATE, PciDev);
    47774776
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r64350 r64373  
    22802280 * @callback_method_impl{FNPCIIOREGIONMAP}
    22812281 */
    2282 static DECLCALLBACK(int)
    2283 ichac97IOPortMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2282static DECLCALLBACK(int) ichac97IOPortMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2283                                          RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    22842284{
    22852285    RT_NOREF(cb, enmType);
    2286     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    22872286    PAC97STATE  pThis   = RT_FROM_MEMBER(pPciDev, AC97STATE, PciDev);
    22882287    RTIOPORT    Port    = (RTIOPORT)GCPhysAddress;
     
    22912290    Assert(cb >= 0x20);
    22922291
    2293     if (iRegion < 0 || iRegion > 1) /* We support 2 regions max. at the moment. */
     2292    if (iRegion > 1) /* We support 2 regions max. at the moment. */
    22942293        return VERR_INVALID_PARAMETER;
    22952294
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r64355 r64373  
    4646*********************************************************************************************************************************/
    4747#define LOG_GROUP LOG_GROUP_DEV_PCI
    48 /* Hack to get PCIDEVICEINT declared at the right point - include "PCIInternal.h". */
    49 #define PCI_INCLUDE_PRIVATE
    50 #include <VBox/pci.h>
     48#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
     49#include <VBox/vmm/pdmpcidev.h>
    5150#include <VBox/vmm/pdmdev.h>
    5251#include <VBox/vmm/mm.h>
     
    5554#include <iprt/string.h>
    5655
     56#include "PciInline.h"
    5757#include "VBoxDD.h"
    5858
     
    7878    int32_t             iBus;
    7979    /** Start device number. */
    80     int32_t             iDevSearch;
     80    uint32_t            iDevSearch;
    8181    /** Number of bridges attached to the bus. */
    8282    uint32_t            cBridges;
     
    8484    uint32_t            Alignment0;
    8585
    86     /** Array of PCI devices. */
    87     R3PTRTYPE(PPCIDEVICE) devices[256];
     86    union
     87    {
     88        /** Array of PCI devices. */
     89        R3PTRTYPE(PPCIDEVICE) apDevices[256];
     90        /** @deprecated   */
     91        R3PTRTYPE(PPCIDEVICE) devices[256];
     92    };
    8893    /** Array of bridges attached to the bus. */
    8994    R3PTRTYPE(PPCIDEVICE *) papBridgesR3;
     
    322327                        {
    323328                            /* unmap it. */
    324                             rc = r->map_func(d, i, NIL_RTGCPHYS, r->size, (PCIADDRESSSPACE)(r->type));
     329                            rc = r->map_func(d->Int.s.pDevInsR3, d, i, NIL_RTGCPHYS, r->size, (PCIADDRESSSPACE)(r->type));
    325330                            AssertRC(rc);
    326331                            rc = PDMDevHlpMMIOExUnmap(d->pDevIns, d, i, GCPhysBase);
     
    333338                r->addr = new_addr;
    334339                if (r->addr != ~0U) {
    335                     int rc = r->map_func(d, i,
     340                    int rc = r->map_func(d->Int.s.pDevInsR3, d, i,
    336341                                         r->addr + (r->type & PCI_ADDRESS_SPACE_IO ? 0 : 0),
    337342                                         r->size, (PCIADDRESSSPACE)(r->type));
     
    344349
    345350
    346 static DECLCALLBACK(uint32_t) pci_default_read_config(PCIDevice *d, uint32_t address, unsigned len)
    347 {
     351static DECLCALLBACK(uint32_t) pci_default_read_config(PPDMDEVINS pDevIns, PCIDevice *d, uint32_t address, unsigned len)
     352{
     353    NOREF(pDevIns);
    348354    uint32_t val;
    349355    switch(len) {
     
    362368}
    363369
    364 static DECLCALLBACK(void) pci_default_write_config(PCIDevice *d, uint32_t address, uint32_t val, unsigned len)
    365 {
     370static DECLCALLBACK(void) pci_default_write_config(PPDMDEVINS pDevIns, PCIDevice *d, uint32_t address, uint32_t val, unsigned len)
     371{
     372    NOREF(pDevIns);
    366373    int can_write;
    367374    unsigned i;
     
    527534#ifdef IN_RING3
    528535            Log(("pci_config_write: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, val, len));
    529             pci_dev->Int.s.pfnConfigWrite(pci_dev, config_addr, val, len);
     536            pci_dev->Int.s.pfnConfigWrite(pci_dev->Int.s.CTX_SUFF(pDevIns), pci_dev, config_addr, val, len);
    530537#else
    531538            return VINF_IOM_R3_IOPORT_WRITE;
     
    573580        {
    574581#ifdef IN_RING3
    575             *pu32 = pci_dev->Int.s.pfnConfigRead(pci_dev, config_addr, len);
     582            *pu32 = pci_dev->Int.s.pfnConfigRead(pci_dev->Int.s.CTX_SUFF(pDevIns), pci_dev, config_addr, len);
    576583            Log(("pci_config_read: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, *pu32, len));
    577584#else
     
    12351242#ifdef IN_RING3
    12361243
     1244/*
     1245 * Include code we share with the other PCI bus implementation.
     1246 *
     1247 * Note! No #ifdefs, use instant data booleans/flags/whatever.  Goal is to
     1248 *       completely merge these files!  File #1 contains code we write, where
     1249 *       as a possible file #2 contains external code if there's any left.
     1250 */
     1251typedef PPCIBUS PPCIMERGEDBUS;
     1252# define pciR3UnmergedConfigReadDev  pci_default_read_config
     1253# define pciR3UnmergedConfigWriteDev pci_default_write_config
     1254# include "DevPciMerge1.cpp.h"
     1255
     1256
    12371257/* -=-=-=-=-=- Saved state -=-=-=-=-=- */
    12381258
     
    14451465                if (off == VBOX_PCI_COMMAND)
    14461466                    PCIDevSetCommand(pDev, 0); /* For remapping, see pciR3CommonLoadExec. */
    1447                 pDev->Int.s.pfnConfigWrite(pDev, off, u32Src, cb);
     1467                pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, off, u32Src, cb);
    14481468            }
    14491469        }
     
    14971517        {
    14981518            uint16_t u16 = PCIDevGetCommand(pDev);
    1499             pDev->Int.s.pfnConfigWrite(pDev, VBOX_PCI_COMMAND, 0, 2);
     1519            pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, VBOX_PCI_COMMAND, 0, 2);
    15001520            PCIDevSetCommand(pDev, u16);
    15011521            Assert(PCIDevGetCommand(pDev) == u16);
     
    16341654
    16351655/* -=-=-=-=-=- PCI Bus Interface Methods (PDMPCIBUSREG) -=-=-=-=-=- */
    1636 
    1637 /**
    1638  * Registers the device with the specified PCI bus.
    1639  *
    1640  * @returns VBox status code.
    1641  * @param   pBus            The bus to register with.
    1642  * @param   iDev            The PCI device ordinal.
    1643  * @param   pPciDev         The PCI device structure.
    1644  * @param   pszName         Pointer to device name (permanent, readonly). For debugging, not unique.
    1645  */
    1646 static int pciR3RegisterDeviceInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName)
    1647 {
    1648     /*
    1649      * Find device slot.
    1650      */
    1651     if (iDev < 0)
    1652     {
    1653         /*
    1654          * Special check for the IDE controller which is our function 1 device
    1655          * before searching.
    1656          */
    1657         if (    !strcmp(pszName, "piix3ide")
    1658             &&  !pBus->devices[9])
    1659             iDev = 9;
    1660         /* LPC bus expected to be there by some guests, better make an additional argument to PDM
    1661            device helpers, but requires significant rewrite */
    1662         else if (!strcmp(pszName, "lpc")
    1663              &&  !pBus->devices[0xf8])
    1664             iDev = 0xf8;
    1665         else
    1666         {
    1667             Assert(!(pBus->iDevSearch % 8));
    1668             for (iDev = pBus->iDevSearch; iDev < (int)RT_ELEMENTS(pBus->devices)-7; iDev += 8)
    1669                 if (    !pBus->devices[iDev]
    1670                     &&  !pBus->devices[iDev + 1]
    1671                     &&  !pBus->devices[iDev + 2]
    1672                     &&  !pBus->devices[iDev + 3]
    1673                     &&  !pBus->devices[iDev + 4]
    1674                     &&  !pBus->devices[iDev + 5]
    1675                     &&  !pBus->devices[iDev + 6]
    1676                     &&  !pBus->devices[iDev + 7])
    1677                     break;
    1678             if (iDev >= (int)RT_ELEMENTS(pBus->devices))
    1679             {
    1680                 AssertMsgFailed(("Couldn't find free spot!\n"));
    1681                 return VERR_PDM_TOO_PCI_MANY_DEVICES;
    1682             }
    1683         }
    1684         pciDevClearRequestedDevfunc(pPciDev);
    1685     }
    1686     else
    1687     {
    1688         /*
    1689          * An explicit request.
    1690          *
    1691          * If the slot is occupied we'll have to relocate the device
    1692          * currently occupying it first. This can only be done if the
    1693          * existing device wasn't explicitly assigned. Also we limit
    1694          * ourselves to function 0 devices.
    1695          *
    1696          * If you start setting devices + function in the
    1697          * config, do it for all pci devices!
    1698          */
    1699         //AssertReleaseMsg(iDev > 8 || pBus->iBus != 0, ("iDev=%d pszName=%s\n", iDev, pszName));
    1700         if (pBus->devices[iDev])
    1701         {
    1702             int iDevRel;
    1703             AssertReleaseMsg(!(iDev % 8), ("PCI Configuration Conflict! iDev=%d pszName=%s clashes with %s\n",
    1704                                            iDev, pszName, pBus->devices[iDev]->name));
    1705             if (    pciDevIsRequestedDevfunc(pBus->devices[iDev])
    1706                 ||  (pBus->devices[iDev + 1] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 1]))
    1707                 ||  (pBus->devices[iDev + 2] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 2]))
    1708                 ||  (pBus->devices[iDev + 3] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 3]))
    1709                 ||  (pBus->devices[iDev + 4] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 4]))
    1710                 ||  (pBus->devices[iDev + 5] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 5]))
    1711                 ||  (pBus->devices[iDev + 6] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 6]))
    1712                 ||  (pBus->devices[iDev + 7] && pciDevIsRequestedDevfunc(pBus->devices[iDev + 7])))
    1713             {
    1714                 AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n",
    1715                                         pszName, pBus->devices[iDev]->name, iDev));
    1716                 return VERR_INTERNAL_ERROR;
    1717             }
    1718 
    1719             /* Find free slot for the device(s) we're moving and move them. */
    1720             for (iDevRel = pBus->iDevSearch; iDevRel < (int)RT_ELEMENTS(pBus->devices)-7; iDevRel += 8)
    1721             {
    1722                 if (    !pBus->devices[iDevRel]
    1723                     &&  !pBus->devices[iDevRel + 1]
    1724                     &&  !pBus->devices[iDevRel + 2]
    1725                     &&  !pBus->devices[iDevRel + 3]
    1726                     &&  !pBus->devices[iDevRel + 4]
    1727                     &&  !pBus->devices[iDevRel + 5]
    1728                     &&  !pBus->devices[iDevRel + 6]
    1729                     &&  !pBus->devices[iDevRel + 7])
    1730                 {
    1731                     int i = 0;
    1732                     for (i = 0; i < 8; i++)
    1733                     {
    1734                         if (!pBus->devices[iDev + i])
    1735                             continue;
    1736                         Log(("PCI: relocating '%s' from slot %#x to %#x\n", pBus->devices[iDev + i]->name, iDev + i, iDevRel + i));
    1737                         pBus->devices[iDevRel + i] = pBus->devices[iDev + i];
    1738                         pBus->devices[iDevRel + i]->devfn = iDevRel + i;
    1739                         pBus->devices[iDev + i] = NULL;
    1740                     }
    1741                 }
    1742             }
    1743             if (pBus->devices[iDev])
    1744             {
    1745                 AssertMsgFailed(("Couldn't find free spot!\n"));
    1746                 return VERR_PDM_TOO_PCI_MANY_DEVICES;
    1747             }
    1748         } /* if conflict */
    1749         pciDevSetRequestedDevfunc(pPciDev);
    1750     }
    1751 
    1752     Assert(!pBus->devices[iDev]);
    1753     pPciDev->devfn                  = iDev;
    1754     pPciDev->name                   = pszName;
    1755     pPciDev->Int.s.pBusR3           = pBus;
    1756     pPciDev->Int.s.pBusR0           = MMHyperR3ToR0(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
    1757     pPciDev->Int.s.pBusRC           = MMHyperR3ToRC(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
    1758     pPciDev->Int.s.pfnConfigRead    = pci_default_read_config;
    1759     pPciDev->Int.s.pfnConfigWrite   = pci_default_write_config;
    1760     pBus->devices[iDev]             = pPciDev;
    1761     if (pciDevIsPci2PciBridge(pPciDev))
    1762     {
    1763         AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->devices), ("Number of bridges exceeds the number of possible devices on the bus\n"));
    1764         AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite,
    1765                   ("device is a bridge but does not implement read/write functions\n"));
    1766         pBus->papBridgesR3[pBus->cBridges] = pPciDev;
    1767         pBus->cBridges++;
    1768     }
    1769 
    1770     Log(("PCI: Registered device %d function %d (%#x) '%s'.\n",
    1771          iDev >> 3, iDev & 7, 0x80000000 | (iDev << 8), pszName));
    1772 
    1773     return VINF_SUCCESS;
    1774 }
    1775 
    1776 
    1777 /**
    1778  * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3}
    1779  */
    1780 static DECLCALLBACK(int) pciR3Register(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
    1781 {
    1782     PPCIBUS     pBus = DEVINS_2_PCIBUS(pDevIns);
    1783 
    1784     /*
    1785      * Check input.
    1786      */
    1787     if (    !pszName
    1788         ||  !pPciDev
    1789         ||  iDev >= (int)RT_ELEMENTS(pBus->devices)
    1790         ||  (iDev >= 0 && iDev <= 8))
    1791     {
    1792         AssertMsgFailed(("Invalid argument! pszName=%s pPciDev=%p iDev=%d\n", pszName, pPciDev, iDev));
    1793         return VERR_INVALID_PARAMETER;
    1794     }
    1795 
    1796     /*
    1797      * Register the device.
    1798      */
    1799     return pciR3RegisterDeviceInternal(pBus, iDev, pPciDev, pszName);
    1800 }
    18011656
    18021657
     
    22002055    PPCIBUS      pBus = &pGlobals->PciBus;
    22012056    PciBusReg.u32Version              = PDM_PCIBUSREG_VERSION;
    2202     PciBusReg.pfnRegisterR3           = pciR3Register;
     2057    PciBusReg.pfnRegisterR3           = pciR3MergedRegister;
    22032058    PciBusReg.pfnRegisterMsiR3        = NULL;
    22042059    PciBusReg.pfnIORegionRegisterR3   = pciR3CommonIORegionRegister;
     
    22342089    PCIDevSetClassBase( &pBus->PciDev,   0x06); /* PCI_bridge */
    22352090    PCIDevSetHeaderType(&pBus->PciDev,   0x00);
    2236 
    2237     pBus->PciDev.pDevIns              = pDevIns;
    2238     pciDevSetRequestedDevfunc(&pBus->PciDev);
    2239     pciR3RegisterDeviceInternal(pBus, 0, &pBus->PciDev, "i440FX");
     2091    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pBus->PciDev, PDMPCIDEVREG_CFG_PRIMARY, 0 /*fFlags*/,
     2092                                0 /*uPciDevNo*/, 0 /*uPciFunNo*/, "i440FX");
     2093    AssertLogRelRCReturn(rc, rc);
    22402094
    22412095    /* PIIX3 */
     
    22452099    PCIDevSetClassBase( &pGlobals->PIIX3State.dev,   0x06); /* PCI_bridge */
    22462100    PCIDevSetHeaderType(&pGlobals->PIIX3State.dev,   0x80); /* PCI_multifunction, generic */
    2247 
    2248     pGlobals->PIIX3State.dev.pDevIns      = pDevIns;
    2249     pciDevSetRequestedDevfunc(&pGlobals->PIIX3State.dev);
    2250     pciR3RegisterDeviceInternal(pBus, 8, &pGlobals->PIIX3State.dev, "PIIX3");
     2101    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pGlobals->PIIX3State.dev, PDMPCIDEVREG_CFG_NEXT, 0 /*fFlags*/,
     2102                                1 /*uPciDevNo*/, 0 /*uPciFunNo*/, "PIIX3");
     2103    AssertLogRelRCReturn(rc, rc);
    22512104    pciR3Piix3Reset(&pGlobals->PIIX3State);
    22522105
     
    24192272        {
    24202273            Log(("%s: %s: addr=%02x val=%08x len=%d\n", __FUNCTION__, pPciDev->name, u32Address, u32Value, cb));
    2421             pPciDev->Int.s.pfnConfigWrite(pPciDev, u32Address, u32Value, cb);
     2274            pPciDev->Int.s.pfnConfigWrite(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, u32Address, u32Value, cb);
    24222275        }
    24232276    }
     
    24512304        if (pPciDev)
    24522305        {
    2453             u32Value = pPciDev->Int.s.pfnConfigRead(pPciDev, u32Address, cb);
     2306            u32Value = pPciDev->Int.s.pfnConfigRead(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, u32Address, cb);
    24542307            Log(("%s: %s: u32Address=%02x u32Value=%08x cb=%d\n", __FUNCTION__, pPciDev->name, u32Address, u32Value, cb));
    24552308        }
     
    24792332        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    24802333    return pciR3CommonLoadExec(pThis, pSSM, uVersion, uPass);
    2481 }
    2482 
    2483 
    2484 /**
    2485  * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3}
    2486  */
    2487 static DECLCALLBACK(int) pcibridgeR3RegisterDevice(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
    2488 {
    2489     PPCIBUS pBus = PDMINS_2_DATA(pDevIns, PPCIBUS);
    2490 
    2491     /*
    2492      * Check input.
    2493      */
    2494     if (    !pszName
    2495         ||  !pPciDev
    2496         ||  iDev >= (int)RT_ELEMENTS(pBus->devices))
    2497     {
    2498         AssertMsgFailed(("Invalid argument! pszName=%s pPciDev=%p iDev=%d\n", pszName, pPciDev, iDev));
    2499         return VERR_INVALID_PARAMETER;
    2500     }
    2501 
    2502     /*
    2503      * Register the device.
    2504      */
    2505     return pciR3RegisterDeviceInternal(pBus, iDev, pPciDev, pszName);
    25062334}
    25072335
     
    25772405    PDMPCIBUSREG PciBusReg;
    25782406    PciBusReg.u32Version              = PDM_PCIBUSREG_VERSION;
    2579     PciBusReg.pfnRegisterR3           = pcibridgeR3RegisterDevice;
     2407    PciBusReg.pfnRegisterR3           = pcibridgeR3MergedRegisterDevice;
    25802408    PciBusReg.pfnRegisterMsiR3        = NULL;
    25812409    PciBusReg.pfnIORegionRegisterR3   = pciR3CommonIORegionRegister;
     
    26172445    PCIDevSetInterruptPin(&pBus->PciDev, 0x00);
    26182446
    2619     pBus->PciDev.pDevIns                    = pDevIns;
    2620 
    2621     /* Bridge-specific data */
    2622     pciDevSetPci2PciBridge(&pBus->PciDev);
     2447    /*
     2448     * Register this PCI bridge. The called function will take care on which bus we will get registered.
     2449     */
     2450    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pBus->PciDev, PDMPCIDEVREG_CFG_PRIMARY, PDMPCIDEVREG_F_PCI_BRIDGE,
     2451                                PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, "pcibridge");
     2452    if (RT_FAILURE(rc))
     2453        return rc;
    26232454    pBus->PciDev.Int.s.pfnBridgeConfigRead  = pcibridgeR3ConfigRead;
    26242455    pBus->PciDev.Int.s.pfnBridgeConfigWrite = pcibridgeR3ConfigWrite;
    2625 
    2626     /*
    2627      * Register this PCI bridge. The called function will take care on which bus we will get registered.
    2628      */
    2629     rc = PDMDevHlpPCIRegister(pDevIns, &pBus->PciDev);
    2630     if (RT_FAILURE(rc))
    2631         return rc;
    26322456
    26332457    pBus->iDevSearch = 0;
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r64355 r64373  
    2424*********************************************************************************************************************************/
    2525#define LOG_GROUP LOG_GROUP_DEV_PCI
    26 /* Hack to get PCIDEVICEINT declared at the right point - include "PCIInternal.h". */
    27 #define PCI_INCLUDE_PRIVATE
    28 #define PCIBus ICH9PCIBus
    29 #include <VBox/pci.h>
     26#define PCIBus    ICH9PCIBus        /**< HACK ALERT! Real ugly type hack! */
     27#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
     28#include <VBox/vmm/pdmpcidev.h>
     29
    3030#include <VBox/msi.h>
    3131#include <VBox/vmm/pdmdev.h>
     
    3535#include <iprt/string.h>
    3636#ifdef IN_RING3
    37 #include <iprt/alloc.h>
     37# include <iprt/mem.h>
    3838#endif
    3939
     40#include "PciInline.h"
    4041#include "VBoxDD.h"
    4142#include "MsiCommon.h"
     
    7879    PCIDEVICE           aPciDev;
    7980
     81    /** Start device number - always zero (only for DevPCI source compat). */
     82    uint32_t            iDevSearch;
     83    /** Size alignemnt padding. */
     84    uint32_t            u32Alignment;
    8085} ICH9PCIBUS, *PICH9PCIBUS;
    8186
     
    176181#ifdef IN_RING3
    177182static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
    178 static int ich9pciRegisterInternal(PICH9PCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName);
    179183static void ich9pciUpdateMappings(PCIDevice *pDev);
    180 static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len);
     184static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t u32Address, unsigned len);
     185static DECLCALLBACK(void)     ich9pciConfigWriteDev(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t u32Address, uint32_t val, unsigned len);
    181186DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PICH9PCIBUS pBus, uint8_t iBus);
    182187static void ich9pciBiosInitDevice(PICH9PCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn);
     
    339344    else                    /* forward to directly connected device */
    340345    {
    341         R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
    342         if (aDev)
     346        R3PTRTYPE(PCIDevice *) pPciDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
     347        if (pPciDev)
    343348        {
    344349#ifdef IN_RING3
    345             aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, cb);
     350            pPciDev->Int.s.pfnConfigWrite(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, pAddr->iRegister, val, cb);
    346351#else
    347352            rc = rcReschedule;
     
    455460    else                    /* forward to directly connected device */
    456461    {
    457         R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
    458         if (aDev)
     462        R3PTRTYPE(PCIDevice *) pPciDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
     463        if (pPciDev)
    459464        {
    460465#ifdef IN_RING3
    461             *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, cb);
     466            *pu32 = pPciDev->Int.s.pfnConfigRead(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, pPciAddr->iRegister, cb);
    462467#else
    463468            rc = rcReschedule;
     
    771776#ifdef IN_RING3
    772777
     778/*
     779 * Include code we share with the other PCI bus implementation.
     780 *
     781 * Note! No #ifdefs, use instant data booleans/flags/whatever.  Goal is to
     782 *       completely merge these files!  File #1 contains code we write, where
     783 *       as a possible file #2 contains external code if there's any left.
     784 */
     785typedef PICH9PCIBUS PPCIMERGEDBUS;
     786# define pciR3UnmergedConfigReadDev  ich9pciConfigReadDev
     787# define pciR3UnmergedConfigWriteDev ich9pciConfigWriteDev
     788# include "DevPciMerge1.cpp.h"
     789
     790
    773791DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PICH9PCIBUS pBus, uint8_t iBus)
    774792{
     
    794812}
    795813
    796 static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
    797 {
    798     return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
    799 }
    800 
    801 static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
    802 {
    803     return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
    804 }
    805 
    806 static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
    807 {
    808     return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
    809 }
    810 
    811 static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
    812 {
    813     return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
     814static uint32_t ich9pciGetCfg(PPDMPCIDEV pPciDev, int32_t iRegister, int cb)
     815{
     816    return pPciDev->Int.s.pfnConfigRead(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, iRegister, cb);
     817}
     818
     819static uint8_t ich9pciGetByte(PPDMPCIDEV pPciDev, int32_t iRegister)
     820{
     821    return (uint8_t)ich9pciGetCfg(pPciDev, iRegister, 1);
     822}
     823
     824static uint16_t ich9pciGetWord(PPDMPCIDEV pPciDev, int32_t iRegister)
     825{
     826    return (uint16_t)ich9pciGetCfg(pPciDev, iRegister, 2);
     827}
     828
     829static uint32_t ich9pciGetDWord(PPDMPCIDEV pPciDev, int32_t iRegister)
     830{
     831    return (uint32_t)ich9pciGetCfg(pPciDev, iRegister, 4);
    814832}
    815833
     
    835853        {
    836854            /* Port IO */
    837             rc = PDMDevHlpIOPortDeregister(pDev->pDevIns, pRegion->addr, pRegion->size);
     855            rc = PDMDevHlpIOPortDeregister(pDev->Int.s.pDevInsR3, pRegion->addr, pRegion->size);
    838856            AssertRC(rc);
    839857        }
     
    841859        {
    842860            RTGCPHYS GCPhysBase = pRegion->addr;
    843             if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->pDevIns, GCPhysBase))
     861            if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->Int.s.pDevInsR3, GCPhysBase))
    844862            {
    845863                /* unmap it. */
    846                 rc = pRegion->map_func(pDev, iRegion, NIL_RTGCPHYS, pRegion->size, (PCIADDRESSSPACE)(pRegion->type));
     864                rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
     865                                       NIL_RTGCPHYS, pRegion->size, (PCIADDRESSSPACE)(pRegion->type));
    847866                AssertRC(rc);
    848                 rc = PDMDevHlpMMIOExUnmap(pDev->pDevIns, pDev, iRegion, GCPhysBase);
     867                rc = PDMDevHlpMMIOExUnmap(pDev->Int.s.pDevInsR3, pDev, iRegion, GCPhysBase);
    849868            }
    850869            else
    851                 rc = PDMDevHlpMMIODeregister(pDev->pDevIns, GCPhysBase, pRegion->size);
     870                rc = PDMDevHlpMMIODeregister(pDev->Int.s.pDevInsR3, GCPhysBase, pRegion->size);
    852871        }
    853872
     
    930949
    931950                /* finally, map the region */
    932                 rc = pRegion->map_func(pDev, iRegion,
     951                rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
    933952                                       pRegion->addr, pRegion->size,
    934953                                       (PCIADDRESSSPACE)(pRegion->type));
     
    942961}
    943962
    944 static DECLCALLBACK(int) ich9pciRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
    945 {
    946     PICH9PCIBUS     pBus = DEVINS_2_PCIBUS(pDevIns);
    947 
    948     /*
    949      * Check input.
    950      */
    951     if (    !pszName
    952         ||  !pPciDev
    953         ||  iDev >= (int)RT_ELEMENTS(pBus->apDevices)
    954         )
    955     {
    956         AssertMsgFailed(("Invalid argument! pszName=%s pPciDev=%p iDev=%d\n", pszName, pPciDev, iDev));
    957         return VERR_INVALID_PARAMETER;
    958     }
    959 
    960     /*
    961      * Register the device.
    962      */
    963     return ich9pciRegisterInternal(pBus, iDev, pPciDev, pszName);
    964 }
    965 
    966963
    967964static DECLCALLBACK(int) ich9pciRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)
     
    981978}
    982979
    983 
    984 static DECLCALLBACK(int) ich9pcibridgeRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)
    985 {
    986 
    987     PICH9PCIBUS pBus = PDMINS_2_DATA(pDevIns, PICH9PCIBUS);
    988 
    989     /*
    990      * Check input.
    991      */
    992     if (    !pszName
    993         ||  !pPciDev
    994         ||  iDev >= (int)RT_ELEMENTS(pBus->apDevices))
    995     {
    996         AssertMsgFailed(("Invalid argument! pszName=%s pPciDev=%p iDev=%d\n", pszName, pPciDev, iDev));
    997         return VERR_INVALID_PARAMETER;
    998     }
    999 
    1000     /*
    1001      * Register the device.
    1002      */
    1003     return ich9pciRegisterInternal(pBus, iDev, pPciDev, pszName);
    1004 }
    1005980
    1006981static DECLCALLBACK(int) ich9pciIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, RTGCPHYS cbRegion,
     
    11791154        {
    11801155            Log(("%s: %s: addr=%02x val=%08x len=%d\n", __FUNCTION__, pPciDev->name, u32Address, u32Value, cb));
    1181             pPciDev->Int.s.pfnConfigWrite(pPciDev, u32Address, u32Value, cb);
     1156            pPciDev->Int.s.pfnConfigWrite(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, u32Address, u32Value, cb);
    11821157        }
    11831158    }
     
    12091184        if (pPciDev)
    12101185        {
    1211             u32Value = pPciDev->Int.s.pfnConfigRead(pPciDev, u32Address, cb);
     1186            u32Value = pPciDev->Int.s.pfnConfigRead(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, u32Address, cb);
    12121187            Log(("%s: %s: u32Address=%02x u32Value=%08x cb=%d\n", __FUNCTION__, pPciDev->name, u32Address, u32Value, cb));
    12131188        }
     
    13671342                if (off == VBOX_PCI_COMMAND)
    13681343                    PCIDevSetCommand(pDev, 0); /* For remapping, see ich9pciR3CommonLoadExec. */
    1369                 pDev->Int.s.pfnConfigWrite(pDev, off, u32Src, cb);
     1344                pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, off, u32Src, cb);
    13701345            }
    13711346        }
     
    14201395        {
    14211396            uint16_t u16 = PCIDevGetCommand(pDev);
    1422             pDev->Int.s.pfnConfigWrite(pDev, VBOX_PCI_COMMAND, 0, 2);
     1397            pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, VBOX_PCI_COMMAND, 0, 2);
    14231398            PCIDevSetCommand(pDev, u16);
    14241399            Assert(PCIDevGetCommand(pDev) == u16);
     
    19951970 * connected devices.
    19961971 */
    1997 static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len)
    1998 {
     1972static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t u32Address, unsigned len)
     1973{
     1974    NOREF(pDevIns);
    19991975    if ((u32Address + len) > 256 && (u32Address + len) < 4096)
    20001976    {
    20011977        LogRel(("PCI: %8s/%u: Read from extended register %d fallen back to generic code\n",
    2002                 aDev->name, aDev->pDevIns->iInstance, u32Address));
     1978                pPciDev->name, pPciDev->pDevIns->iInstance, u32Address));
    20031979        return 0;
    20041980    }
     
    20061982    AssertMsgReturn(u32Address + len <= 256, ("Read after the end of PCI config space\n"),
    20071983                    0);
    2008     if (   pciDevIsMsiCapable(aDev)
    2009         && (u32Address >= aDev->Int.s.u8MsiCapOffset)
    2010         && (u32Address < (unsigned)(aDev->Int.s.u8MsiCapOffset + aDev->Int.s.u8MsiCapSize))
     1984    if (   pciDevIsMsiCapable(pPciDev)
     1985        && (u32Address >= pPciDev->Int.s.u8MsiCapOffset)
     1986        && (u32Address < (unsigned)(pPciDev->Int.s.u8MsiCapOffset + pPciDev->Int.s.u8MsiCapSize))
    20111987       )
    20121988    {
    2013         return MsiPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
    2014     }
    2015 
    2016     if (   pciDevIsMsixCapable(aDev)
    2017         && (u32Address >= aDev->Int.s.u8MsixCapOffset)
    2018         && (u32Address < (unsigned)(aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize))
     1989        return MsiPciConfigRead(pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), pPciDev, u32Address, len);
     1990    }
     1991
     1992    if (   pciDevIsMsixCapable(pPciDev)
     1993        && (u32Address >= pPciDev->Int.s.u8MsixCapOffset)
     1994        && (u32Address < (unsigned)(pPciDev->Int.s.u8MsixCapOffset + pPciDev->Int.s.u8MsixCapSize))
    20191995       )
    20201996    {
    2021         return MsixPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
     1997        return MsixPciConfigRead(pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), pPciDev, u32Address, len);
    20221998    }
    20231999
     
    20272003    {
    20282004        case 1:
    2029             return PCIDevGetByte(aDev,  u32Address);
     2005            return PCIDevGetByte(pPciDev,  u32Address);
    20302006        case 2:
    2031             return PCIDevGetWord(aDev,  u32Address);
     2007            return PCIDevGetWord(pPciDev,  u32Address);
    20322008        case 4:
    2033             return PCIDevGetDWord(aDev, u32Address);
     2009            return PCIDevGetDWord(pPciDev, u32Address);
    20342010        default:
    20352011            Assert(false);
     
    20392015
    20402016
    2041 DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset, uint8_t u8Val)
    2042 {
    2043     PCIIORegion * pRegion = &aDev->Int.s.aIORegions[iRegion];
     2017DECLINLINE(void) ich9pciWriteBarByte(PPDMPCIDEV pPciDev, int iRegion, int iOffset, uint8_t u8Val)
     2018{
     2019    PCIIORegion * pRegion = &pPciDev->Int.s.aIORegions[iRegion];
    20442020    int64_t iRegionSize = pRegion->size;
    20452021
     
    20532029    if (pRegion->type == 0xff)
    20542030    {
    2055         ich9pciWriteBarByte(aDev, iRegion-1, iOffset+4, u8Val);
     2031        ich9pciWriteBarByte(pPciDev, iRegion-1, iOffset+4, u8Val);
    20562032        return;
    20572033    }
     
    20742050    }
    20752051
    2076     uint8_t u8Old = PCIDevGetByte(aDev, uAddr) & uMask;
     2052    uint8_t u8Old = PCIDevGetByte(pPciDev, uAddr) & uMask;
    20772053    u8Val = (u8Old & uMask) | (u8Val & ~uMask);
    20782054
    20792055    Log3(("ich9pciWriteBarByte: was %x writing %x\n", u8Old, u8Val));
    20802056
    2081     PCIDevSetByte(aDev, uAddr, u8Val);
     2057    PCIDevSetByte(pPciDev, uAddr, u8Val);
    20822058}
    20832059
     
    20902066 * definition of registers and their writability policy.
    20912067 */
    2092 static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Address,
    2093                                                 uint32_t val, unsigned len)
    2094 {
     2068static DECLCALLBACK(void) ich9pciConfigWriteDev(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
     2069                                                uint32_t u32Address, uint32_t val, unsigned len)
     2070{
     2071    NOREF(pDevIns);
    20952072    Assert(len <= 4);
    20962073
     
    20982075    {
    20992076        LogRel(("PCI: %8s/%u: Write to extended register %d fallen back to generic code\n",
    2100                 aDev->name, aDev->pDevIns->iInstance, u32Address));
     2077                pPciDev->name, pPciDev->pDevIns->iInstance, u32Address));
    21012078        return;
    21022079    }
     
    21042081    AssertMsgReturnVoid(u32Address + len <= 256, ("Write after end of PCI config space\n"));
    21052082
    2106     if (   pciDevIsMsiCapable(aDev)
    2107         && (u32Address >= aDev->Int.s.u8MsiCapOffset)
    2108         && (u32Address < (unsigned)(aDev->Int.s.u8MsiCapOffset + aDev->Int.s.u8MsiCapSize))
     2083    if (   pciDevIsMsiCapable(pPciDev)
     2084        && (u32Address >= pPciDev->Int.s.u8MsiCapOffset)
     2085        && (u32Address < (unsigned)(pPciDev->Int.s.u8MsiCapOffset + pPciDev->Int.s.u8MsiCapSize))
    21092086       )
    21102087    {
    2111         MsiPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
    2112                           aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
    2113                           aDev, u32Address, val, len);
     2088        MsiPciConfigWrite(pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
     2089                          pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
     2090                          pPciDev, u32Address, val, len);
    21142091        return;
    21152092    }
    21162093
    2117     if (   pciDevIsMsixCapable(aDev)
    2118         && (u32Address >= aDev->Int.s.u8MsixCapOffset)
    2119         && (u32Address < (unsigned)(aDev->Int.s.u8MsixCapOffset + aDev->Int.s.u8MsixCapSize))
     2094    if (   pciDevIsMsixCapable(pPciDev)
     2095        && (u32Address >= pPciDev->Int.s.u8MsixCapOffset)
     2096        && (u32Address < (unsigned)(pPciDev->Int.s.u8MsixCapOffset + pPciDev->Int.s.u8MsixCapSize))
    21202097       )
    21212098    {
    2122         MsixPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
    2123                            aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
    2124                            aDev, u32Address, val, len);
     2099        MsixPciConfigWrite(pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
     2100                           pPciDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
     2101                           pPciDev, u32Address, val, len);
    21252102        return;
    21262103    }
     
    21292106    bool     fUpdateMappings = false;
    21302107    bool     fP2PBridge = false;
    2131     /*bool     fPassthrough = pciDevIsPassthrough(aDev);*/
    2132     uint8_t  u8HeaderType = ich9pciGetByte(aDev, VBOX_PCI_HEADER_TYPE);
     2108    /*bool     fPassthrough = pciDevIsPassthrough(pPciDev);*/
     2109    uint8_t  u8HeaderType = ich9pciGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
    21332110
    21342111    for (uint32_t i = 0; i < len; i++)
     
    21852162                break;
    21862163            default:
    2187                 AssertMsgFailed(("Unknown header type %x\n", PCIDevGetHeaderType(aDev)));
     2164                AssertMsgFailed(("Unknown header type %x\n", PCIDevGetHeaderType(pPciDev)));
    21882165                fWritable = false;
    21892166                break;
     
    22052182                u8Val &= ~UINT32_C(0xff);
    22062183                /* status register, low part: clear bits by writing a '1' to the corresponding bit */
    2207                 aDev->config[addr] &= ~u8Val;
     2184                pPciDev->config[addr] &= ~u8Val;
    22082185                break;
    22092186            case VBOX_PCI_STATUS+1:  /* Status register, bits 8-15. */
     
    22112188                u8Val &= ~UINT32_C(0x06);
    22122189                /* status register, high part: clear bits by writing a '1' to the corresponding bit */
    2213                 aDev->config[addr] &= ~u8Val;
     2190                pPciDev->config[addr] &= ~u8Val;
    22142191                break;
    22152192            case VBOX_PCI_ROM_ADDRESS:    case VBOX_PCI_ROM_ADDRESS   +1: case VBOX_PCI_ROM_ADDRESS   +2: case VBOX_PCI_ROM_ADDRESS   +3:
     
    22292206                    int iRegion = fRom ? VBOX_PCI_ROM_SLOT : (addr - VBOX_PCI_BASE_ADDRESS_0) >> 2;
    22302207                    int iOffset = addr & 0x3;
    2231                     ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
     2208                    ich9pciWriteBarByte(pPciDev, iRegion, iOffset, u8Val);
    22322209                    fUpdateMappings = true;
    22332210                }
     
    22372214            default_case:
    22382215                if (fWritable)
    2239                     PCIDevSetByte(aDev, addr, u8Val);
     2216                    PCIDevSetByte(pPciDev, addr, u8Val);
    22402217        }
    22412218        addr++;
     
    22452222    if (fUpdateMappings)
    22462223        /* if the command/base address register is modified, we must modify the mappings */
    2247         ich9pciUpdateMappings(aDev);
    2248 }
    2249 
    2250 static bool assignPosition(PICH9PCIBUS pBus, PPCIDEVICE pPciDev, const char *pszName, int iDevFn, PciAddress* aPosition)
    2251 {
    2252     NOREF(pszName);
    2253     aPosition->iBus = 0;
    2254     aPosition->iDeviceFunc = iDevFn;
    2255     aPosition->iRegister = 0; /* N/A */
    2256 
    2257     /* Explicit slot request */
    2258     if (iDevFn >= 0 && iDevFn < (int)RT_ELEMENTS(pBus->apDevices))
    2259         return true;
    2260 
    2261     int iStartPos = 0;
    2262 
    2263     /* Otherwise when assigning a slot, we need to make sure all its functions are available */
    2264     for (int iPos = iStartPos; iPos < (int)RT_ELEMENTS(pBus->apDevices); iPos += 8)
    2265     {
    2266         if (        !pBus->apDevices[iPos]
    2267                 &&  !pBus->apDevices[iPos + 1]
    2268                 &&  !pBus->apDevices[iPos + 2]
    2269                 &&  !pBus->apDevices[iPos + 3]
    2270                 &&  !pBus->apDevices[iPos + 4]
    2271                 &&  !pBus->apDevices[iPos + 5]
    2272                 &&  !pBus->apDevices[iPos + 6]
    2273                 &&  !pBus->apDevices[iPos + 7])
    2274         {
    2275             pciDevClearRequestedDevfunc(pPciDev);
    2276             aPosition->iDeviceFunc = iPos;
    2277             return true;
    2278         }
    2279     }
    2280 
    2281     return false;
    2282 }
    2283 
    2284 #ifdef SOME_UNUSED_FUNCTION
    2285 static bool hasHardAssignedDevsInSlot(PICH9PCIBUS pBus, int iSlot)
    2286 {
    2287     PCIDevice** aSlot = &pBus->apDevices[iSlot << 3];
    2288 
    2289     return     (aSlot[0] && pciDevIsRequestedDevfunc(aSlot[0]))
    2290             || (aSlot[1] && pciDevIsRequestedDevfunc(aSlot[1]))
    2291             || (aSlot[2] && pciDevIsRequestedDevfunc(aSlot[2]))
    2292             || (aSlot[3] && pciDevIsRequestedDevfunc(aSlot[3]))
    2293             || (aSlot[4] && pciDevIsRequestedDevfunc(aSlot[4]))
    2294             || (aSlot[5] && pciDevIsRequestedDevfunc(aSlot[5]))
    2295             || (aSlot[6] && pciDevIsRequestedDevfunc(aSlot[6]))
    2296             || (aSlot[7] && pciDevIsRequestedDevfunc(aSlot[7]))
    2297            ;
    2298 }
    2299 #endif
    2300 
    2301 static int ich9pciRegisterInternal(PICH9PCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName)
    2302 {
    2303     PciAddress aPosition;
    2304     aPosition.iBus = 0;
    2305     aPosition.iDeviceFunc = 0;
    2306     aPosition.iRegister = 0;
    2307 
    2308     /*
    2309      * Find device position
    2310      */
    2311     if (!assignPosition(pBus, pPciDev, pszName, iDev, &aPosition))
    2312     {
    2313         AssertMsgFailed(("Couldn't asssign position!\n"));
    2314         return VERR_PDM_TOO_PCI_MANY_DEVICES;
    2315     }
    2316 
    2317     AssertMsgReturn(aPosition.iBus == 0,
    2318                     ("Assigning behind the bridge not implemented yet\n"),
    2319                     VERR_PDM_TOO_PCI_MANY_DEVICES);
    2320 
    2321 
    2322     iDev = aPosition.iDeviceFunc;
    2323     /*
    2324      * Check if we can really take this slot, possibly by relocating
    2325      * its current habitant, if it wasn't hard assigned too.
    2326      */
    2327     if (pciDevIsRequestedDevfunc(pPciDev) &&
    2328         pBus->apDevices[iDev]          &&
    2329         pciDevIsRequestedDevfunc(pBus->apDevices[iDev]))
    2330     {
    2331         AssertReleaseMsgFailed(("Configuration error:'%s' and '%s' are both configured as device %d\n",
    2332                                  pszName, pBus->apDevices[iDev]->name, iDev));
    2333         return VERR_INTERNAL_ERROR;
    2334     }
    2335 
    2336     if (pBus->apDevices[iDev])
    2337     {
    2338         /* if we got here, we shall (and usually can) relocate the device */
    2339         bool assigned = assignPosition(pBus, pBus->apDevices[iDev], pBus->apDevices[iDev]->name, -1, &aPosition);
    2340         AssertMsgReturn(aPosition.iBus == 0,
    2341                         ("Assigning behind the bridge not implemented yet\n"),
    2342                         VERR_PDM_TOO_PCI_MANY_DEVICES);
    2343         int iRelDev = aPosition.iDeviceFunc;
    2344         if (!assigned || iRelDev == iDev)
    2345         {
    2346             AssertMsgFailed(("Couldn't find free spot!\n"));
    2347             return VERR_PDM_TOO_PCI_MANY_DEVICES;
    2348         }
    2349         /* Copy device function by function to its new position */
    2350         for (int i = 0; i < 8; i++)
    2351         {
    2352             if (!pBus->apDevices[iDev + i])
    2353                 continue;
    2354             Log(("PCI: relocating '%s' from slot %#x to %#x\n", pBus->apDevices[iDev + i]->name, iDev + i, iRelDev + i));
    2355             pBus->apDevices[iRelDev + i] = pBus->apDevices[iDev + i];
    2356             pBus->apDevices[iRelDev + i]->devfn = iRelDev + i;
    2357             pBus->apDevices[iDev + i] = NULL;
    2358         }
    2359     }
    2360 
    2361     /*
    2362      * Fill in device information.
    2363      */
    2364     pPciDev->devfn                  = iDev;
    2365     pPciDev->name                   = pszName;
    2366     pPciDev->Int.s.pBusR3           = pBus;
    2367     pPciDev->Int.s.pBusR0           = MMHyperR3ToR0(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
    2368     pPciDev->Int.s.pBusRC           = MMHyperR3ToRC(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
    2369     pPciDev->Int.s.pfnConfigRead    = ich9pciConfigReadDev;
    2370     pPciDev->Int.s.pfnConfigWrite   = ich9pciConfigWriteDev;
    2371     pBus->apDevices[iDev]           = pPciDev;
    2372     if (pciDevIsPci2PciBridge(pPciDev))
    2373     {
    2374         AssertMsg(pBus->cBridges < RT_ELEMENTS(pBus->apDevices), ("Number of bridges exceeds the number of possible devices on the bus\n"));
    2375         AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite,
    2376                   ("device is a bridge but does not implement read/write functions\n"));
    2377         Log2(("Setting bridge %d on bus %p\n", pBus->cBridges, pBus));
    2378         pBus->papBridgesR3[pBus->cBridges] = pPciDev;
    2379         pBus->cBridges++;
    2380     }
    2381 
    2382     Log(("PCI: Registered device %d function %d on bus %d (%#x) '%s'.\n",
    2383          iDev >> 3, iDev & 7, pBus->iBus, 0x80000000 | (iDev << 8), pszName));
    2384 
    2385     return VINF_SUCCESS;
    2386 }
     2224        ich9pciUpdateMappings(pPciDev);
     2225}
     2226
    23872227
    23882228static void printIndent(PCDBGFINFOHLP pHlp, int iIndent)
     
    26182458    PDMPCIBUSREG PciBusReg;
    26192459    PciBusReg.u32Version              = PDM_PCIBUSREG_VERSION;
    2620     PciBusReg.pfnRegisterR3           = ich9pciRegister;
     2460    PciBusReg.pfnRegisterR3           = pciR3MergedRegister;
    26212461    PciBusReg.pfnRegisterMsiR3        = ich9pciRegisterMsi;
    26222462    PciBusReg.pfnIORegionRegisterR3   = ich9pciIORegionRegister;
     
    28742714    PDMPCIBUSREG PciBusReg;
    28752715    PciBusReg.u32Version              = PDM_PCIBUSREG_VERSION;
    2876     PciBusReg.pfnRegisterR3           = ich9pcibridgeRegister;
     2716    PciBusReg.pfnRegisterR3           = pcibridgeR3MergedRegisterDevice;
    28772717    PciBusReg.pfnRegisterMsiR3        = ich9pciRegisterMsi;
    28782718    PciBusReg.pfnIORegionRegisterR3   = ich9pciIORegionRegister;
     
    29182758    PCIDevSetInterruptPin (&pBus->aPciDev, 0x00);
    29192759
    2920     pBus->aPciDev.pDevIns                    = pDevIns;
    2921 
    2922     /* Bridge-specific data */
    2923     pciDevSetPci2PciBridge(&pBus->aPciDev);
     2760    /*
     2761     * Register this PCI bridge. The called function will take care on which bus we will get registered.
     2762     */
     2763    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pBus->aPciDev, PDMPCIDEVREG_CFG_PRIMARY, PDMPCIDEVREG_F_PCI_BRIDGE,
     2764                                PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, "ich9pcibridge");
     2765    if (RT_FAILURE(rc))
     2766        return rc;
    29242767    pBus->aPciDev.Int.s.pfnBridgeConfigRead  = ich9pcibridgeConfigRead;
    29252768    pBus->aPciDev.Int.s.pfnBridgeConfigWrite = ich9pcibridgeConfigWrite;
    2926 
    2927     /*
    2928      * Register this PCI bridge. The called function will take care on which bus we will get registered.
    2929      */
    2930     rc = PDMDevHlpPCIRegister (pDevIns, &pBus->aPciDev);
    2931     if (RT_FAILURE(rc))
    2932         return rc;
    29332769
    29342770    /*
  • trunk/src/VBox/Devices/Bus/MsiCommon.cpp

    r63562 r64373  
    22/** @file
    33 * MSI support routines
     4 *
     5 * @todo Straighten up this file!!
    46 */
    57
     
    1618 */
    1719#define LOG_GROUP LOG_GROUP_DEV_PCI
    18 /* Hack to get PCIDEVICEINT declare at the right point - include "PCIInternal.h". */
    19 #define PCI_INCLUDE_PRIVATE
     20#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    2021#include <VBox/pci.h>
    2122#include <VBox/msi.h>
     
    2425
    2526#include "MsiCommon.h"
     27#include "PciInline.h"
    2628
    2729DECLINLINE(uint16_t) msiGetMessageControl(PPCIDEVICE pDev)
     
    3032#ifdef IN_RING3
    3133    if (pciDevIsPassthrough(pDev)) {
    32         return pDev->Int.s.pfnConfigRead(pDev, idxMessageControl, 2);
     34        return pDev->Int.s.pfnConfigRead(pDev->Int.s.CTX_SUFF(pDevIns), pDev, idxMessageControl, 2);
    3335    }
    3436#endif
  • trunk/src/VBox/Devices/Bus/MsixCommon.cpp

    r63690 r64373  
    1616 */
    1717#define LOG_GROUP LOG_GROUP_DEV_PCI
    18 /* Hack to get PCIDEVICEINT declare at the right point - include "PCIInternal.h". */
    19 #define PCI_INCLUDE_PRIVATE
     18#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    2019#include <VBox/pci.h>
    2120#include <VBox/msi.h>
     
    2726
    2827#include "MsiCommon.h"
     28#include "PciInline.h"
    2929
    3030#pragma pack(1)
     
    152152 * @callback_method_impl{FNPCIIOREGIONMAP}
    153153 */
    154 static DECLCALLBACK(int) msixMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     154static DECLCALLBACK(int) msixMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     155                                 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    155156{
    156157    Assert(enmType == PCI_ADDRESS_SPACE_MEM);
    157158    NOREF(iRegion); NOREF(enmType);
    158159
    159     int rc = PDMDevHlpMMIORegister(pPciDev->pDevIns, GCPhysAddress, cb, pPciDev,
     160    int rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, pPciDev,
    160161                                   IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    161162                                   msixMMIOWrite, msixMMIORead, "MSI-X tables");
  • trunk/src/VBox/Devices/Bus/PciInline.h

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/VBox-3.0/include/VBox/pci.h58652,​70973
      /branches/VBox-3.2/include/VBox/pci.h66309,​66318
      /branches/VBox-4.0/include/VBox/pci.h70873
      /branches/VBox-4.1/include/VBox/pci.h74233,​78414,​78691,​82579,​85941,​85944-85947,​85949-85950,​85953,​86701,​86728,​87009
      /branches/VBox-4.2/include/VBox/pci.h82653,​86229-86230,​86234,​86529,​91503-91504,​91506-91508,​91510,​91514-91515,​91521,​108112,​108114,​108127
      /branches/VBox-4.3/include/VBox/pci.h89714,​91223,​94066,​94839,​94897,​95154,​95164,​95167,​95295,​95338,​95353-95354,​95356,​95367,​95451,​95475,​95477,​95480,​95507,​95640,​95659,​95661,​95663,​98913-98915,​99358
      /branches/VBox-4.3/trunk/include/VBox/pci.h91223
      /branches/VBox-5.0/include/VBox/pci.h104445,​104938,​104943,​104950,​104952-104953,​104987-104988,​104990,​106453
      /branches/andy/draganddrop/include/VBox/pci.h90781-91268
      /branches/andy/guestctrl20/include/VBox/pci.h78916,​78930
      /branches/andy/pdmaudio/include/VBox/pci.h94582,​94641,​94654,​94688,​94778,​94783,​94816,​95197,​95215-95216,​95250,​95279,​95505-95506,​95543,​95694,​96323,​96470-96471,​96582,​96587,​96802-96803,​96817,​96904,​96967,​96999,​97020-97021,​97025,​97050,​97099
      /branches/bird/hardenedwindows/include/VBox/pci.h92692-94610
      /branches/dsen/gui/include/VBox/pci.h79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
      /branches/dsen/gui2/include/VBox/pci.h79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
      /branches/dsen/gui3/include/VBox/pci.h79645-79692
      /trunk/src/include/VBox/pci.h92342
    r64359 r64373  
    11/** @file
    2  * PCI - The PCI Controller And Devices. (DEV)
     2 * PCI - The PCI Controller And Devices, inline device helpers.
    33 */
    44
     
    1313 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
    1414 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    15  *
    16  * The contents of this file may alternatively be used under the terms
    17  * of the Common Development and Distribution License Version 1.0
    18  * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
    19  * VirtualBox OSE distribution, in which case the provisions of the
    20  * CDDL are applicable instead of those of the GPL.
    21  *
    22  * You may elect to license modified versions of this file under the
    23  * terms and conditions of either the GPL or the CDDL or both.
    2415 */
    2516
    26 #ifndef ___VBox_pci_h
    27 #define ___VBox_pci_h
     17#ifndef ___Bus_PciInline_h
     18#define ___Bus_PciInline_h
    2819
    29 #include <VBox/cdefs.h>
    30 #include <VBox/types.h>
    31 #include <iprt/assert.h>
    32 
    33 /** @defgroup grp_pci       PCI - The PCI Controller.
    34  * @ingroup grp_devdrv
    35  * @{
    36  */
    37 
    38 /** Pointer to a PCI device. */
    39 typedef struct PCIDevice *PPCIDEVICE;
    40 
    41 
    42 /**
    43  * PCI configuration word 4 (command) and word 6 (status).
    44  */
    45 typedef enum PCICONFIGCOMMAND
    46 {
    47     /** Supports/uses memory accesses. */
    48     PCI_COMMAND_IOACCESS  = 0x0001,
    49     PCI_COMMAND_MEMACCESS = 0x0002,
    50     PCI_COMMAND_BUSMASTER = 0x0004
    51 } PCICONFIGCOMMAND;
    52 
    53 
    54 /**
    55  * PCI Address space specification.
    56  * This is used when registering a I/O region.
    57  */
    58 /**
    59  * Defined by the PCI specification.
    60  */
    61 typedef enum PCIADDRESSSPACE
    62 {
    63     /** Memory. */
    64     PCI_ADDRESS_SPACE_MEM = 0x00,
    65     /** I/O space. */
    66     PCI_ADDRESS_SPACE_IO = 0x01,
    67     /** 32-bit BAR. */
    68     PCI_ADDRESS_SPACE_BAR32 = 0x00,
    69     /** 64-bit BAR. */
    70     PCI_ADDRESS_SPACE_BAR64 = 0x04,
    71     /** Prefetch memory. */
    72     PCI_ADDRESS_SPACE_MEM_PREFETCH = 0x08
    73 } PCIADDRESSSPACE;
    74 
    75 
    76 /**
    77  * Callback function for mapping an PCI I/O region.
    78  *
    79  * @return VBox status code.
    80  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    81  * @param   iRegion         The region number.
    82  * @param   GCPhysAddress   Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
    83  *                          is an I/O port, otherwise it's a physical address.
    84  *
    85  *                          NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
    86  *                          that the device deregister access handlers for it and update its internal
    87  *                          state to reflect this.
    88  *
    89  * @param   cb              Size of the region in bytes.
    90  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
    91  *
    92  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    93  *          that is very likely be a lock order violation.
    94  */
    95 typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    96                                            RTGCPHYS cb, PCIADDRESSSPACE enmType);
    97 /** Pointer to a FNPCIIOREGIONMAP() function. */
    98 typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
    99 
    100 
    101 /** @name PCI Configuration Space Registers
    102  * @{ */
    103 /* Commented out values common for different header types */
    104 /* Common part of the header */
    105 #define VBOX_PCI_VENDOR_ID              0x00    /**< 16-bit  RO */
    106 #define VBOX_PCI_DEVICE_ID              0x02    /**< 16-bit  RO */
    107 #define VBOX_PCI_COMMAND                0x04    /**< 16-bit  RW, some bits RO */
    108 #define VBOX_PCI_STATUS                 0x06    /**< 16-bit  RW, some bits RO */
    109 #define VBOX_PCI_REVISION_ID            0x08    /**<  8-bit  RO  - - device revision */
    110 #define VBOX_PCI_CLASS_PROG             0x09    /**<  8-bit  RO  - - register-level programming class code (device specific). */
    111 #define VBOX_PCI_CLASS_SUB              0x0a    /**<  8-bit  RO  - - sub-class code. */
    112 #define VBOX_PCI_CLASS_DEVICE           VBOX_PCI_CLASS_SUB
    113 #define VBOX_PCI_CLASS_BASE             0x0b    /**<  8-bit  RO  - - base class code. */
    114 #define VBOX_PCI_CACHE_LINE_SIZE        0x0c    /**<  8-bit  RW  - - system cache line size */
    115 #define VBOX_PCI_LATENCY_TIMER          0x0d    /**<  8-bit  RW  - - master latency timer, hardwired to 0 for PCIe */
    116 #define VBOX_PCI_HEADER_TYPE            0x0e    /**<  8-bit  RO  - - header type (0 - device, 1 - bridge, 2  - CardBus bridge)  */
    117 #define VBOX_PCI_BIST                   0x0f    /**<  8-bit  RW  - - built-in self test control */
    118 #define VBOX_PCI_CAPABILITY_LIST        0x34    /**<  8-bit  RO? - - linked list of new capabilities implemented by the device, 2 bottom bits reserved */
    119 #define VBOX_PCI_INTERRUPT_LINE         0x3c    /**<  8-bit  RW  - - interrupt line. */
    120 #define VBOX_PCI_INTERRUPT_PIN          0x3d    /**<  8-bit  RO  - - interrupt pin.  */
    121 
    122 /* Type 0 header, device */
    123 #define VBOX_PCI_BASE_ADDRESS_0         0x10    /**< 32-bit  RW */
    124 #define VBOX_PCI_BASE_ADDRESS_1         0x14    /**< 32-bit  RW */
    125 #define VBOX_PCI_BASE_ADDRESS_2         0x18    /**< 32-bit  RW */
    126 #define VBOX_PCI_BASE_ADDRESS_3         0x1c    /**< 32-bit  RW */
    127 #define VBOX_PCI_BASE_ADDRESS_4         0x20    /**< 32-bit  RW */
    128 #define VBOX_PCI_BASE_ADDRESS_5         0x24    /**< 32-bit  RW */
    129 #define VBOX_PCI_CARDBUS_CIS            0x28    /**< 32-bit  ?? */
    130 #define VBOX_PCI_SUBSYSTEM_VENDOR_ID    0x2c    /**< 16-bit  RO */
    131 #define VBOX_PCI_SUBSYSTEM_ID           0x2e    /**< 16-bit  RO */
    132 #define VBOX_PCI_ROM_ADDRESS            0x30    /**< 32-bit  ?? */
    133 /* #define VBOX_PCI_CAPABILITY_LIST        0x34 */  /**<  8-bit? ?? */
    134 #define VBOX_PCI_RESERVED_35            0x35    /**<  8-bit  ?? - - reserved */
    135 #define VBOX_PCI_RESERVED_36            0x36    /**<  8-bit  ?? - - reserved */
    136 #define VBOX_PCI_RESERVED_37            0x37    /**<  8-bit  ?? - - reserved */
    137 #define VBOX_PCI_RESERVED_38            0x38    /**<  32-bit ?? - - reserved */
    138 /* #define VBOX_PCI_INTERRUPT_LINE         0x3c */   /**<  8-bit  RW  - - interrupt line. */
    139 /* #define VBOX_PCI_INTERRUPT_PIN          0x3d */   /**<  8-bit  RO  - - interrupt pin.  */
    140 #define VBOX_PCI_MIN_GNT                0x3e    /**<  8-bit  RO - - burst period length (in 1/4 microsecond units)  */
    141 #define VBOX_PCI_MAX_LAT                0x3f    /**<  8-bit  RO - - how often the device needs access to the PCI bus (in 1/4 microsecond units) */
    142 
    143 /* Type 1 header, PCI-to-PCI bridge */
    144 /* #define VBOX_PCI_BASE_ADDRESS_0         0x10 */    /**< 32-bit RW */
    145 /* #define VBOX_PCI_BASE_ADDRESS_1         0x14 */    /**< 32-bit RW */
    146 #define VBOX_PCI_PRIMARY_BUS            0x18    /**<  8-bit  ?? - - primary bus number. */
    147 #define VBOX_PCI_SECONDARY_BUS          0x19    /**<  8-bit  ?? - - secondary bus number. */
    148 #define VBOX_PCI_SUBORDINATE_BUS        0x1a    /**<  8-bit  ?? - - highest subordinate bus number. (behind the bridge) */
    149 #define VBOX_PCI_SEC_LATENCY_TIMER      0x1b    /**<  8-bit  ?? - - secondary latency timer. */
    150 #define VBOX_PCI_IO_BASE                0x1c    /**<  8-bit  ?? - - I/O range base. */
    151 #define VBOX_PCI_IO_LIMIT               0x1d    /**<  8-bit  ?? - - I/O range limit. */
    152 #define VBOX_PCI_SEC_STATUS             0x1e    /**< 16-bit  ?? - - secondary status register. */
    153 #define VBOX_PCI_MEMORY_BASE            0x20    /**< 16-bit  ?? - - memory range base. */
    154 #define VBOX_PCI_MEMORY_LIMIT           0x22    /**< 16-bit  ?? - - memory range limit. */
    155 #define VBOX_PCI_PREF_MEMORY_BASE       0x24    /**< 16-bit  ?? - - prefetchable memory range base. */
    156 #define VBOX_PCI_PREF_MEMORY_LIMIT      0x26    /**< 16-bit  ?? - - prefetchable memory range limit. */
    157 #define VBOX_PCI_PREF_BASE_UPPER32      0x28    /**< 32-bit  ?? - - prefetchable memory range high base.*/
    158 #define VBOX_PCI_PREF_LIMIT_UPPER32     0x2c    /**< 32-bit  ?? - - prefetchable memory range high limit. */
    159 #define VBOX_PCI_IO_BASE_UPPER16        0x30    /**< 16-bit  ?? - - memory range high base. */
    160 #define VBOX_PCI_IO_LIMIT_UPPER16       0x32    /**< 16-bit  ?? - - memory range high limit. */
    161 /* #define VBOX_PCI_CAPABILITY_LIST        0x34 */   /**<  8-bit? ?? */
    162 /* #define VBOX_PCI_RESERVED_35            0x35 */   /**<  8-bit ?? - - reserved */
    163 /* #define VBOX_PCI_RESERVED_36            0x36 */   /**<  8-bit ?? - - reserved */
    164 /* #define VBOX_PCI_RESERVED_37            0x37 */   /**<  8-bit ?? - - reserved */
    165 #define VBOX_PCI_ROM_ADDRESS_BR         0x38    /**< 32-bit  ?? - - expansion ROM base address  */
    166 #define VBOX_PCI_BRIDGE_CONTROL         0x3e    /**< 16-bit?  ?? - - bridge control  */
    167 
    168 /* Type 2 header, PCI-to-CardBus bridge */
    169 #define VBOX_PCI_CARDBUS_BASE_ADDRESS   0x10    /**< 32-bit  RW  - - CardBus Socket/ExCa base address */
    170 #define VBOX_PCI_CARDBUS_CAPLIST        0x14    /**<  8-bit  RO? - - offset of capabilities list */
    171 #define VBOX_PCI_CARDBUS_RESERVED_15    0x15    /**<  8-bit  ??  - - reserved */
    172 #define VBOX_PCI_CARDBUS_SEC_STATUS     0x16    /**< 16-bit  ??  - - secondary status  */
    173 #define VBOX_PCI_CARDBUS_PCIBUS_NUMBER  0x18    /**<  8-bit  ??  - - PCI bus number */
    174 #define VBOX_PCI_CARDBUS_CARDBUS_NUMBER 0x19    /**<  8-bit  ??  - - CardBus bus number */
    175 /* #define VBOX_PCI_SUBORDINATE_BUS        0x1a */    /**<  8-bit  ?? - - highest subordinate bus number. (behind the bridge) */
    176 /* #define VBOX_PCI_SEC_LATENCY_TIMER      0x1b */    /**<  8-bit  ?? - - secondary latency timer. */
    177 #define VBOX_PCI_CARDBUS_MEMORY_BASE0   0x1c     /**< 32-bit  RW  - - memory base address 0 */
    178 #define VBOX_PCI_CARDBUS_MEMORY_LIMIT0  0x20     /**< 32-bit  RW  - - memory limit 0 */
    179 #define VBOX_PCI_CARDBUS_MEMORY_BASE1   0x24     /**< 32-bit  RW  - - memory base address 1 */
    180 #define VBOX_PCI_CARDBUS_MEMORY_LIMIT1  0x28     /**< 32-bit  RW  - - memory limit 1 */
    181 #define VBOX_PCI_CARDBUS_IO_BASE0       0x2c     /**< 32-bit  RW  - - IO base address 0 */
    182 #define VBOX_PCI_CARDBUS_IO_LIMIT0      0x30     /**< 32-bit  RW  - - IO limit 0 */
    183 #define VBOX_PCI_CARDBUS_IO_BASE1       0x34     /**< 32-bit  RW  - - IO base address 1 */
    184 #define VBOX_PCI_CARDBUS_IO_LIMIT1      0x38     /**< 32-bit  RW  - - IO limit 1 */
    185 /* #define VBOX_PCI_INTERRUPT_LINE         0x3c */   /**<  8-bit  RW  - - interrupt line. */
    186 /* #define VBOX_PCI_INTERRUPT_PIN          0x3d */   /**<  8-bit  RO  - - interrupt pin.  */
    187 /* #define VBOX_PCI_BRIDGE_CONTROL         0x3e */   /**< 16-bit?  ?? - - bridge control  */
    188 /** @} */
    189 
    190 
    191 /* Possible values in status bitmask */
    192 #define  VBOX_PCI_STATUS_CAP_LIST    0x10    /* Support Capability List */
    193 #define  VBOX_PCI_STATUS_66MHZ       0x20    /* Support 66 Mhz PCI 2.1 bus */
    194 #define  VBOX_PCI_STATUS_UDF         0x40    /* Support User Definable Features [obsolete] */
    195 #define  VBOX_PCI_STATUS_FAST_BACK   0x80    /* Accept fast-back to back */
    196 #define  VBOX_PCI_STATUS_PARITY      0x100   /* Detected parity error */
    197 #define  VBOX_PCI_STATUS_DEVSEL_MASK 0x600   /* DEVSEL timing */
    198 #define  VBOX_PCI_STATUS_DEVSEL_FAST         0x000
    199 #define  VBOX_PCI_STATUS_DEVSEL_MEDIUM       0x200
    200 #define  VBOX_PCI_STATUS_DEVSEL_SLOW         0x400
    201 #define  VBOX_PCI_STATUS_SIG_TARGET_ABORT    0x800 /* Set on target abort */
    202 #define  VBOX_PCI_STATUS_REC_TARGET_ABORT    0x1000 /* Master ack of " */
    203 #define  VBOX_PCI_STATUS_REC_MASTER_ABORT    0x2000 /* Set on master abort */
    204 #define  VBOX_PCI_STATUS_SIG_SYSTEM_ERROR    0x4000 /* Set when we drive SERR */
    205 #define  VBOX_PCI_STATUS_DETECTED_PARITY     0x8000 /* Set on parity error */
    206 
    207 
    208 /* Command bitmask */
    209 #define  VBOX_PCI_COMMAND_IO           0x1     /* Enable response in I/O space */
    210 #define  VBOX_PCI_COMMAND_MEMORY       0x2     /* Enable response in Memory space */
    211 #define  VBOX_PCI_COMMAND_MASTER       0x4     /* Enable bus mastering */
    212 #define  VBOX_PCI_COMMAND_SPECIAL      0x8     /* Enable response to special cycles */
    213 #define  VBOX_PCI_COMMAND_INVALIDATE   0x10    /* Use memory write and invalidate */
    214 #define  VBOX_PCI_COMMAND_VGA_PALETTE  0x20    /* Enable palette snooping */
    215 #define  VBOX_PCI_COMMAND_PARITY       0x40    /* Enable parity checking */
    216 #define  VBOX_PCI_COMMAND_WAIT         0x80    /* Enable address/data stepping */
    217 #define  VBOX_PCI_COMMAND_SERR         0x100   /* Enable SERR */
    218 #define  VBOX_PCI_COMMAND_FAST_BACK    0x200   /* Enable back-to-back writes */
    219 #define  VBOX_PCI_COMMAND_INTX_DISABLE 0x400   /* INTx Emulation Disable */
    220 
    221 
    222 /* Capability list values (capability offset 0) */
    223 /* Next  value pointer in offset 1, or 0 if none */
    224 #define  VBOX_PCI_CAP_ID_PM          0x01    /* Power Management */
    225 #define  VBOX_PCI_CAP_ID_AGP         0x02    /* Accelerated Graphics Port */
    226 #define  VBOX_PCI_CAP_ID_VPD         0x03    /* Vital Product Data */
    227 #define  VBOX_PCI_CAP_ID_SLOTID      0x04    /* Slot Identification */
    228 #define  VBOX_PCI_CAP_ID_MSI         0x05    /* Message Signalled Interrupts */
    229 #define  VBOX_PCI_CAP_ID_CHSWP       0x06    /* CompactPCI HotSwap */
    230 #define  VBOX_PCI_CAP_ID_PCIX        0x07    /* PCI-X */
    231 #define  VBOX_PCI_CAP_ID_HT          0x08    /* HyperTransport */
    232 #define  VBOX_PCI_CAP_ID_VNDR        0x09    /* Vendor specific */
    233 #define  VBOX_PCI_CAP_ID_DBG         0x0A    /* Debug port */
    234 #define  VBOX_PCI_CAP_ID_CCRC        0x0B    /* CompactPCI Central Resource Control */
    235 #define  VBOX_PCI_CAP_ID_SHPC        0x0C    /* PCI Standard Hot-Plug Controller */
    236 #define  VBOX_PCI_CAP_ID_SSVID       0x0D    /* Bridge subsystem vendor/device ID */
    237 #define  VBOX_PCI_CAP_ID_AGP3        0x0E    /* AGP Target PCI-PCI bridge */
    238 #define  VBOX_PCI_CAP_ID_SECURE      0x0F    /* Secure device (?) */
    239 #define  VBOX_PCI_CAP_ID_EXP         0x10    /* PCI Express */
    240 #define  VBOX_PCI_CAP_ID_MSIX        0x11    /* MSI-X */
    241 #define  VBOX_PCI_CAP_ID_SATA        0x12    /* Serial-ATA HBA */
    242 #define  VBOX_PCI_CAP_ID_AF          0x13    /* PCI Advanced Features */
    243 
    244 /* Extended Capabilities (PCI-X 2.0 and Express), start at 0x100, next - bits [20..32] */
    245 #define  VBOX_PCI_EXT_CAP_ID_ERR     0x01    /* Advanced Error Reporting */
    246 #define  VBOX_PCI_EXT_CAP_ID_VC      0x02    /* Virtual Channel */
    247 #define  VBOX_PCI_EXT_CAP_ID_DSN     0x03    /* Device Serial Number */
    248 #define  VBOX_PCI_EXT_CAP_ID_PWR     0x04    /* Power Budgeting */
    249 #define  VBOX_PCI_EXT_CAP_ID_RCLINK  0x05    /* Root Complex Link Declaration */
    250 #define  VBOX_PCI_EXT_CAP_ID_RCILINK 0x06    /* Root Complex Internal Link Declaration */
    251 #define  VBOX_PCI_EXT_CAP_ID_RCECOLL 0x07    /* Root Complex Event Collector */
    252 #define  VBOX_PCI_EXT_CAP_ID_MFVC    0x08    /* Multi-Function Virtual Channel */
    253 #define  VBOX_PCI_EXT_CAP_ID_RBCB    0x0a    /* Root Bridge Control Block */
    254 #define  VBOX_PCI_EXT_CAP_ID_VNDR    0x0b    /* Vendor specific */
    255 #define  VBOX_PCI_EXT_CAP_ID_ACS     0x0d    /* Access Controls */
    256 #define  VBOX_PCI_EXT_CAP_ID_ARI     0x0e
    257 #define  VBOX_PCI_EXT_CAP_ID_ATS     0x0f
    258 #define  VBOX_PCI_EXT_CAP_ID_SRIOV   0x10
    259 
    260 
    261 /* MSI flags, aka Message Control (2 bytes, capability offset 2) */
    262 #define  VBOX_PCI_MSI_FLAGS_ENABLE   0x0001  /* MSI feature enabled */
    263 #define  VBOX_PCI_MSI_FLAGS_64BIT    0x0080  /* 64-bit addresses allowed */
    264 #define  VBOX_PCI_MSI_FLAGS_MASKBIT  0x0100  /* Per-vector masking support */
    265 /* Encoding for 3-bit patterns for message queue (per chapter 6.8.1 of PCI spec),
    266    someone very similar to log_2().
    267    000 1
    268    001 2
    269    010 4
    270    011 8
    271    100 16
    272    101 32
    273    110 Reserved
    274    111 Reserved */
    275 #define  VBOX_PCI_MSI_FLAGS_QSIZE    0x0070  /* Message queue size configured (i.e. vectors per device allocated) */
    276 #define  VBOX_PCI_MSI_FLAGS_QMASK    0x000e  /* Maximum queue size available (i.e. vectors per device possible) */
    277 
    278 /* MSI-X flags (2 bytes, capability offset 2) */
    279 #define  VBOX_PCI_MSIX_FLAGS_ENABLE   0x8000  /* MSI-X enable */
    280 #define  VBOX_PCI_MSIX_FLAGS_FUNCMASK 0x4000  /* Function mask */
    281 
    282 /* Power management flags (2 bytes, capability offset 2) */
    283 #define  VBOX_PCI_PM_CAP_VER_MASK    0x0007  /* Version mask */
    284 #define  VBOX_PCI_PM_CAP_PME_CLOCK   0x0008  /* PME clock required */
    285 #define  VBOX_PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
    286 #define  VBOX_PCI_PM_CAP_DSI         0x0020  /* Device specific initialization */
    287 #define  VBOX_PCI_PM_CAP_AUX_POWER   0x01C0  /* Auxilliary power support mask */
    288 #define  VBOX_PCI_PM_CAP_D1          0x0200  /* D1 power state support */
    289 #define  VBOX_PCI_PM_CAP_D2          0x0400  /* D2 power state support */
    290 #define  VBOX_PCI_PM_CAP_PME         0x0800  /* PME pin supported */
    291 #define  VBOX_PCI_PM_CAP_PME_MASK    0xF800  /* PME Mask of all supported states */
    292 #define  VBOX_PCI_PM_CAP_PME_D0      0x0800  /* PME# from D0 */
    293 #define  VBOX_PCI_PM_CAP_PME_D1      0x1000  /* PME# from D1 */
    294 #define  VBOX_PCI_PM_CAP_PME_D2      0x2000  /* PME# from D2 */
    295 #define  VBOX_PCI_PM_CAP_PME_D3      0x4000  /* PME# from D3 (hot) */
    296 #define  VBOX_PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
    297 
    298 /* Power management control flags (2 bytes, capability offset 4) */
    299 #define  VBOX_PCI_PM_CTRL_STATE_MASK         0x0003  /* Current power state (D0 to D3) */
    300 #define  VBOX_PCI_PM_CTRL_NO_SOFT_RESET      0x0008  /* No reset for D3hot->D0 */
    301 #define  VBOX_PCI_PM_CTRL_PME_ENABLE         0x0100  /* PME pin enable */
    302 #define  VBOX_PCI_PM_CTRL_DATA_SEL_MASK      0x1e00  /* Data select (??) */
    303 #define  VBOX_PCI_PM_CTRL_DATA_SCALE_MASK    0x6000  /* Data scale (??) */
    304 #define  VBOX_PCI_PM_CTRL_PME_STATUS         0x8000  /* PME pin status */
    305 
    306 /* PCI-X config flags (2 bytes, capability offset 2) */
    307 #define  VBOX_PCI_X_CMD_DPERR_E      0x0001  /* Data Parity Error Recovery Enable */
    308 #define  VBOX_PCI_X_CMD_ERO          0x0002  /* Enable Relaxed Ordering */
    309 #define  VBOX_PCI_X_CMD_MAX_OUTSTANDING_SPLIT_TRANS          0x0070
    310 #define  VBOX_PCI_X_CMD_READ_512     0x0000  /* 512 byte maximum read byte count */
    311 #define  VBOX_PCI_X_CMD_READ_1K      0x0004  /* 1Kbyte maximum read byte count */
    312 #define  VBOX_PCI_X_CMD_READ_2K      0x0008  /* 2Kbyte maximum read byte count */
    313 #define  VBOX_PCI_X_CMD_READ_4K      0x000c  /* 4Kbyte maximum read byte count */
    314 #define  VBOX_PCI_X_CMD_MAX_READ     0x000c  /* Max Memory Read Byte Count */
    315 
    316 /* PCI-X config flags (4 bytes, capability offset 4) */
    317 #define  VBOX_PCI_X_STATUS_DEVFN     0x000000ff      /* A copy of devfn */
    318 #define  VBOX_PCI_X_STATUS_BUS       0x0000ff00      /* A copy of bus nr */
    319 #define  VBOX_PCI_X_STATUS_64BIT     0x00010000      /* 64-bit device */
    320 #define  VBOX_PCI_X_STATUS_133MHZ    0x00020000      /* 133 MHz capable */
    321 #define  VBOX_PCI_X_STATUS_SPL_DISC  0x00040000      /* Split Completion Discarded */
    322 #define  VBOX_PCI_X_STATUS_UNX_SPL   0x00080000      /* Unexpected Split Completion */
    323 #define  VBOX_PCI_X_STATUS_COMPLEX   0x00100000      /* Device Complexity, 0 = simple device, 1 = bridge device */
    324 #define  VBOX_PCI_X_STATUS_MAX_READ  0x00600000      /* Designed Max Memory Read Count, 0 = 512 bytes, 1 = 1024, 2 = 2048, 3 = 4096 */
    325 #define  VBOX_PCI_X_STATUS_MAX_SPLIT 0x03800000      /* Designed Max Outstanding Split Transactions */
    326 #define  VBOX_PCI_X_STATUS_MAX_CUM   0x1c000000      /* Designed Max Cumulative Read Size */
    327 #define  VBOX_PCI_X_STATUS_SPL_ERR   0x20000000      /* Rcvd Split Completion Error Msg */
    328 #define  VBOX_PCI_X_STATUS_266MHZ    0x40000000      /* 266 MHz capable */
    329 #define  VBOX_PCI_X_STATUS_533MHZ    0x80000000      /* 533 MHz capable */
    330 
    331 /* PCI Express config flags (2 bytes, capability offset 2) */
    332 #define  VBOX_PCI_EXP_FLAGS_VERS        0x000f  /* Capability version */
    333 #define  VBOX_PCI_EXP_FLAGS_TYPE        0x00f0  /* Device/Port type */
    334 #define  VBOX_PCI_EXP_TYPE_ENDPOINT     0x0     /* Express Endpoint */
    335 #define  VBOX_PCI_EXP_TYPE_LEG_END      0x1     /* Legacy Endpoint */
    336 #define  VBOX_PCI_EXP_TYPE_ROOT_PORT    0x4     /* Root Port */
    337 #define  VBOX_PCI_EXP_TYPE_UPSTREAM     0x5     /* Upstream Port */
    338 #define  VBOX_PCI_EXP_TYPE_DOWNSTREAM   0x6     /* Downstream Port */
    339 #define  VBOX_PCI_EXP_TYPE_PCI_BRIDGE   0x7     /* PCI/PCI-X Bridge */
    340 #define  VBOX_PCI_EXP_TYPE_PCIE_BRIDGE  0x8     /* PCI/PCI-X to PCIE Bridge */
    341 #define  VBOX_PCI_EXP_TYPE_ROOT_INT_EP  0x9     /* Root Complex Integrated Endpoint */
    342 #define  VBOX_PCI_EXP_TYPE_ROOT_EC      0xa     /* Root Complex Event Collector */
    343 #define  VBOX_PCI_EXP_FLAGS_SLOT        0x0100  /* Slot implemented */
    344 #define  VBOX_PCI_EXP_FLAGS_IRQ         0x3e00  /* Interrupt message number */
    345 
    346 /* PCI Express device capabilities (4 bytes, capability offset 4) */
    347 #define  VBOX_PCI_EXP_DEVCAP_PAYLOAD 0x07        /* Max_Payload_Size */
    348 #define  VBOX_PCI_EXP_DEVCAP_PHANTOM 0x18        /* Phantom functions */
    349 #define  VBOX_PCI_EXP_DEVCAP_EXT_TAG 0x20        /* Extended tags */
    350 #define  VBOX_PCI_EXP_DEVCAP_L0S     0x1c0       /* L0s Acceptable Latency */
    351 #define  VBOX_PCI_EXP_DEVCAP_L1      0xe00       /* L1 Acceptable Latency */
    352 #define  VBOX_PCI_EXP_DEVCAP_ATN_BUT 0x1000      /* Attention Button Present */
    353 #define  VBOX_PCI_EXP_DEVCAP_ATN_IND 0x2000      /* Attention Indicator Present */
    354 #define  VBOX_PCI_EXP_DEVCAP_PWR_IND 0x4000      /* Power Indicator Present */
    355 #define  VBOX_PCI_EXP_DEVCAP_RBE     0x8000      /* Role-Based Error Reporting */
    356 #define  VBOX_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000   /* Slot Power Limit Value */
    357 #define  VBOX_PCI_EXP_DEVCAP_PWR_SCL 0xc000000   /* Slot Power Limit Scale */
    358 #define  VBOX_PCI_EXP_DEVCAP_FLRESET 0x10000000  /* Function-Level Reset */
    359 
    360 /* PCI Express device control (2 bytes, capability offset 8) */
    361 #define  VBOX_PCI_EXP_DEVCTL_CERE    0x0001      /* Correctable Error Reporting En. */
    362 #define  VBOX_PCI_EXP_DEVCTL_NFERE   0x0002      /* Non-Fatal Error Reporting Enable */
    363 #define  VBOX_PCI_EXP_DEVCTL_FERE    0x0004      /* Fatal Error Reporting Enable */
    364 #define  VBOX_PCI_EXP_DEVCTL_URRE    0x0008      /* Unsupported Request Reporting En. */
    365 #define  VBOX_PCI_EXP_DEVCTL_RELAXED 0x0010      /* Enable Relaxed Ordering */
    366 #define  VBOX_PCI_EXP_DEVCTL_PAYLOAD 0x00e0      /* Max_Payload_Size */
    367 #define  VBOX_PCI_EXP_DEVCTL_EXT_TAG 0x0100      /* Extended Tag Field Enable */
    368 #define  VBOX_PCI_EXP_DEVCTL_PHANTOM 0x0200      /* Phantom Functions Enable */
    369 #define  VBOX_PCI_EXP_DEVCTL_AUX_PME 0x0400      /* Auxiliary Power PM Enable */
    370 #define  VBOX_PCI_EXP_DEVCTL_NOSNOOP 0x0800      /* Enable No Snoop */
    371 #define  VBOX_PCI_EXP_DEVCTL_READRQ  0x7000      /* Max_Read_Request_Size */
    372 #define  VBOX_PCI_EXP_DEVCTL_BCRE    0x8000      /* Bridge Configuration Retry Enable */
    373 #define  VBOX_PCI_EXP_DEVCTL_FLRESET 0x8000      /* Function-Level Reset [bit shared with BCRE] */
    374 
    375 /* PCI Express device status (2 bytes, capability offset 10) */
    376 #define  VBOX_PCI_EXP_DEVSTA_CED     0x01         /* Correctable Error Detected */
    377 #define  VBOX_PCI_EXP_DEVSTA_NFED    0x02         /* Non-Fatal Error Detected */
    378 #define  VBOX_PCI_EXP_DEVSTA_FED     0x04         /* Fatal Error Detected */
    379 #define  VBOX_PCI_EXP_DEVSTA_URD     0x08         /* Unsupported Request Detected */
    380 #define  VBOX_PCI_EXP_DEVSTA_AUXPD   0x10         /* AUX Power Detected */
    381 #define  VBOX_PCI_EXP_DEVSTA_TRPND   0x20         /* Transactions Pending */
    382 
    383 /* PCI Express link capabilities (4 bytes, capability offset 12) */
    384 #define  VBOX_PCI_EXP_LNKCAP_SPEED   0x0000f       /* Maximum Link Speed */
    385 #define  VBOX_PCI_EXP_LNKCAP_WIDTH   0x003f0       /* Maximum Link Width */
    386 #define  VBOX_PCI_EXP_LNKCAP_ASPM    0x00c00       /* Active State Power Management */
    387 #define  VBOX_PCI_EXP_LNKCAP_L0S     0x07000       /* L0s Acceptable Latency */
    388 #define  VBOX_PCI_EXP_LNKCAP_L1      0x38000       /* L1 Acceptable Latency */
    389 #define  VBOX_PCI_EXP_LNKCAP_CLOCKPM 0x40000       /* Clock Power Management */
    390 #define  VBOX_PCI_EXP_LNKCAP_SURPRISE 0x80000      /* Surprise Down Error Reporting */
    391 #define  VBOX_PCI_EXP_LNKCAP_DLLA    0x100000      /* Data Link Layer Active Reporting */
    392 #define  VBOX_PCI_EXP_LNKCAP_LBNC    0x200000      /* Link Bandwidth Notification Capability */
    393 #define  VBOX_PCI_EXP_LNKCAP_PORT    0xff000000    /* Port Number */
    394 
    395 /* PCI Express link control (2 bytes, capability offset 16) */
    396 #define  VBOX_PCI_EXP_LNKCTL_ASPM    0x0003        /* ASPM Control */
    397 #define  VBOX_PCI_EXP_LNKCTL_RCB     0x0008        /* Read Completion Boundary */
    398 #define  VBOX_PCI_EXP_LNKCTL_DISABLE 0x0010        /* Link Disable */
    399 #define  VBOX_PCI_EXP_LNKCTL_RETRAIN 0x0020        /* Retrain Link */
    400 #define  VBOX_PCI_EXP_LNKCTL_CLOCK   0x0040        /* Common Clock Configuration */
    401 #define  VBOX_PCI_EXP_LNKCTL_XSYNCH  0x0080        /* Extended Synch */
    402 #define  VBOX_PCI_EXP_LNKCTL_CLOCKPM 0x0100        /* Clock Power Management */
    403 #define  VBOX_PCI_EXP_LNKCTL_HWAUTWD 0x0200        /* Hardware Autonomous Width Disable */
    404 #define  VBOX_PCI_EXP_LNKCTL_BWMIE   0x0400        /* Bandwidth Mgmt Interrupt Enable */
    405 #define  VBOX_PCI_EXP_LNKCTL_AUTBWIE 0x0800        /* Autonomous Bandwidth Mgmt Interrupt Enable */
    406 
    407 /* PCI Express link status (2 bytes, capability offset 18) */
    408 #define  VBOX_PCI_EXP_LNKSTA_SPEED   0x000f        /* Negotiated Link Speed */
    409 #define  VBOX_PCI_EXP_LNKSTA_WIDTH   0x03f0        /* Negotiated Link Width */
    410 #define  VBOX_PCI_EXP_LNKSTA_TR_ERR  0x0400        /* Training Error (obsolete) */
    411 #define  VBOX_PCI_EXP_LNKSTA_TRAIN   0x0800        /* Link Training */
    412 #define  VBOX_PCI_EXP_LNKSTA_SL_CLK  0x1000        /* Slot Clock Configuration */
    413 #define  VBOX_PCI_EXP_LNKSTA_DL_ACT  0x2000        /* Data Link Layer in DL_Active State */
    414 #define  VBOX_PCI_EXP_LNKSTA_BWMGMT  0x4000        /* Bandwidth Mgmt Status */
    415 #define  VBOX_PCI_EXP_LNKSTA_AUTBW   0x8000        /* Autonomous Bandwidth Mgmt Status */
    416 
    417 /* PCI Express slot capabilities (4 bytes, capability offset 20) */
    418 #define  VBOX_PCI_EXP_SLTCAP_ATNB    0x0001        /* Attention Button Present */
    419 #define  VBOX_PCI_EXP_SLTCAP_PWRC    0x0002        /* Power Controller Present */
    420 #define  VBOX_PCI_EXP_SLTCAP_MRL     0x0004        /* MRL Sensor Present */
    421 #define  VBOX_PCI_EXP_SLTCAP_ATNI    0x0008        /* Attention Indicator Present */
    422 #define  VBOX_PCI_EXP_SLTCAP_PWRI    0x0010        /* Power Indicator Present */
    423 #define  VBOX_PCI_EXP_SLTCAP_HPS     0x0020        /* Hot-Plug Surprise */
    424 #define  VBOX_PCI_EXP_SLTCAP_HPC     0x0040        /* Hot-Plug Capable */
    425 #define  VBOX_PCI_EXP_SLTCAP_PWR_VAL 0x00007f80    /* Slot Power Limit Value */
    426 #define  VBOX_PCI_EXP_SLTCAP_PWR_SCL 0x00018000    /* Slot Power Limit Scale */
    427 #define  VBOX_PCI_EXP_SLTCAP_INTERLOCK 0x020000    /* Electromechanical Interlock Present */
    428 #define  VBOX_PCI_EXP_SLTCAP_NOCMDCOMP 0x040000    /* No Command Completed Support */
    429 #define  VBOX_PCI_EXP_SLTCAP_PSN     0xfff80000    /* Physical Slot Number */
    430 
    431 /* PCI Express slot control (2 bytes, capability offset 24) */
    432 #define  VBOX_PCI_EXP_SLTCTL_ATNB    0x0001        /* Attention Button Pressed Enable */
    433 #define  VBOX_PCI_EXP_SLTCTL_PWRF    0x0002        /* Power Fault Detected Enable */
    434 #define  VBOX_PCI_EXP_SLTCTL_MRLS    0x0004        /* MRL Sensor Changed Enable */
    435 #define  VBOX_PCI_EXP_SLTCTL_PRSD    0x0008        /* Presence Detect Changed Enable */
    436 #define  VBOX_PCI_EXP_SLTCTL_CMDC    0x0010        /* Command Completed Interrupt Enable */
    437 #define  VBOX_PCI_EXP_SLTCTL_HPIE    0x0020        /* Hot-Plug Interrupt Enable */
    438 #define  VBOX_PCI_EXP_SLTCTL_ATNI    0x00c0        /* Attention Indicator Control */
    439 #define  VBOX_PCI_EXP_SLTCTL_PWRI    0x0300        /* Power Indicator Control */
    440 #define  VBOX_PCI_EXP_SLTCTL_PWRC    0x0400        /* Power Controller Control */
    441 #define  VBOX_PCI_EXP_SLTCTL_INTERLOCK 0x0800      /* Electromechanical Interlock Control */
    442 #define  VBOX_PCI_EXP_SLTCTL_LLCHG   0x1000        /* Data Link Layer State Changed Enable */
    443 
    444 /* PCI Express slot status (2 bytes, capability offset 26) */
    445 #define  VBOX_PCI_EXP_SLTSTA_ATNB    0x0001        /* Attention Button Pressed */
    446 #define  VBOX_PCI_EXP_SLTSTA_PWRF    0x0002        /* Power Fault Detected */
    447 #define  VBOX_PCI_EXP_SLTSTA_MRLS    0x0004        /* MRL Sensor Changed */
    448 #define  VBOX_PCI_EXP_SLTSTA_PRSD    0x0008        /* Presence Detect Changed */
    449 #define  VBOX_PCI_EXP_SLTSTA_CMDC    0x0010        /* Command Completed */
    450 #define  VBOX_PCI_EXP_SLTSTA_MRL_ST  0x0020        /* MRL Sensor State */
    451 #define  VBOX_PCI_EXP_SLTSTA_PRES    0x0040        /* Presence Detect State */
    452 #define  VBOX_PCI_EXP_SLTSTA_INTERLOCK 0x0080      /* Electromechanical Interlock Status */
    453 #define  VBOX_PCI_EXP_SLTSTA_LLCHG   0x0100        /* Data Link Layer State Changed */
    454 
    455 /* PCI Express root control (2 bytes, capability offset 28) */
    456 #define  VBOX_PCI_EXP_RTCTL_SECEE    0x0001        /* System Error on Correctable Error */
    457 #define  VBOX_PCI_EXP_RTCTL_SENFEE   0x0002        /* System Error on Non-Fatal Error */
    458 #define  VBOX_PCI_EXP_RTCTL_SEFEE    0x0004        /* System Error on Fatal Error */
    459 #define  VBOX_PCI_EXP_RTCTL_PMEIE    0x0008        /* PME Interrupt Enable */
    460 #define  VBOX_PCI_EXP_RTCTL_CRSVIS   0x0010        /* Configuration Request Retry Status Visible to SW */
    461 
    462 /* PCI Express root capabilities (2 bytes, capability offset 30) */
    463 #define  VBOX_PCI_EXP_RTCAP_CRSVIS   0x0010        /* Configuration Request Retry Status Visible to SW */
    464 
    465 /* PCI Express root status (4 bytes, capability offset 32) */
    466 #define  VBOX_PCI_EXP_RTSTA_PME_REQID   0x0000ffff /* PME Requester ID */
    467 #define  VBOX_PCI_EXP_RTSTA_PME_STATUS  0x00010000 /* PME Status */
    468 #define  VBOX_PCI_EXP_RTSTA_PME_PENDING 0x00020000 /* PME is Pending */
    469 
    470 
    471 /**
    472  * Callback function for reading from the PCI configuration space.
    473  *
    474  * @returns The register value.
    475  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    476  * @param   Address         The configuration space register address. [0..4096]
    477  * @param   cb              The register size. [1,2,4]
    478  *
    479  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    480  *          that is very likely be a lock order violation.
    481  */
    482 typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb);
    483 /** Pointer to a FNPCICONFIGREAD() function. */
    484 typedef FNPCICONFIGREAD *PFNPCICONFIGREAD;
    485 /** Pointer to a PFNPCICONFIGREAD. */
    486 typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD;
    487 
    488 /**
    489  * Callback function for writing to the PCI configuration space.
    490  *
    491  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    492  * @param   Address         The configuration space register address. [0..4096]
    493  * @param   u32Value        The value that's being written. The number of bits actually used from
    494  *                          this value is determined by the cb parameter.
    495  * @param   cb              The register size. [1,2,4]
    496  *
    497  * @remarks Called with the PDM lock held.  The device lock is NOT take because
    498  *          that is very likely be a lock order violation.
    499  */
    500 typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
    501 /** Pointer to a FNPCICONFIGWRITE() function. */
    502 typedef FNPCICONFIGWRITE *PFNPCICONFIGWRITE;
    503 /** Pointer to a PFNPCICONFIGWRITE. */
    504 typedef PFNPCICONFIGWRITE *PPFNPCICONFIGWRITE;
    505 
    506 /** Fixed I/O region number for ROM. */
    507 #define PCI_ROM_SLOT    6
    508 #define VBOX_PCI_ROM_SLOT    6
    509 /** Max number of I/O regions. */
    510 #define PCI_NUM_REGIONS 7
    511 #define VBOX_PCI_NUM_REGIONS 7
    512 
    513 /*
    514  * Hack to include the PCIDEVICEINT structure at the right place
    515  * to avoid duplications of FNPCIIOREGIONMAP and PCI_NUM_REGIONS.
    516  */
    517 #ifdef PCI_INCLUDE_PRIVATE
    518 # include "PCIInternal.h"
    519 #endif
    520 
    521 /**
    522  * PCI Device structure.
    523  */
    524 typedef struct PCIDevice
    525 {
    526     /** PCI config space. */
    527     uint8_t                 config[256];
    528 
    529     /** Internal data. */
    530     union
    531     {
    532 #ifdef PCIDEVICEINT_DECLARED
    533         PCIDEVICEINT        s;
    534 #endif
    535         char                padding[328];
    536     } Int;
    537 
    538     /** Read only data.
    539      * @{
    540      */
    541     /** PCI device number on the pci bus. */
    542     int32_t                 devfn;
    543     uint32_t                Alignment0; /**< Alignment. */
    544     /** Device name. */
    545     R3PTRTYPE(const char *) name;
    546     /** Pointer to the device instance which registered the device. */
    547     PPDMDEVINSR3            pDevIns;
    548     /**  @} */
    549 } PCIDEVICE;
    550 
    551 /** @todo handle extended space access. */
    552 
    553 DECLINLINE(void)     PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t offReg, uint8_t u8Value)
    554 {
    555     pPciDev->config[offReg] = u8Value;
    556 }
    557 
    558 DECLINLINE(uint8_t)  PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t offReg)
    559 {
    560     return pPciDev->config[offReg];
    561 }
    562 
    563 DECLINLINE(void)     PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t offReg, uint16_t u16Value)
    564 {
    565     *(uint16_t*)&pPciDev->config[offReg] = RT_H2LE_U16(u16Value);
    566 }
    567 
    568 DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t offReg)
    569 {
    570     uint16_t u16Value = *(uint16_t*)&pPciDev->config[offReg];
    571     return RT_H2LE_U16(u16Value);
    572 }
    573 
    574 DECLINLINE(void)     PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t offReg, uint32_t u32Value)
    575 {
    576     *(uint32_t*)&pPciDev->config[offReg] = RT_H2LE_U32(u32Value);
    577 }
    578 
    579 DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t offReg)
    580 {
    581     uint32_t u32Value = *(uint32_t*)&pPciDev->config[offReg];
    582     return RT_H2LE_U32(u32Value);
    583 }
    584 
    585 DECLINLINE(void)     PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t offReg, uint64_t u64Value)
    586 {
    587     *(uint64_t*)&pPciDev->config[offReg] = RT_H2LE_U64(u64Value);
    588 }
    589 
    590 DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t offReg)
    591 {
    592     uint64_t u64Value = *(uint64_t*)&pPciDev->config[offReg];
    593     return RT_H2LE_U64(u64Value);
    594 }
    595 
    596 /**
    597  * Sets the vendor id config register.
    598  * @param   pPciDev         The PCI device.
    599  * @param   u16VendorId     The vendor id.
    600  */
    601 DECLINLINE(void) PCIDevSetVendorId(PPCIDEVICE pPciDev, uint16_t u16VendorId)
    602 {
    603     PCIDevSetWord(pPciDev, VBOX_PCI_VENDOR_ID, u16VendorId);
    604 }
    605 
    606 /**
    607  * Gets the vendor id config register.
    608  * @returns the vendor id.
    609  * @param   pPciDev         The PCI device.
    610  */
    611 DECLINLINE(uint16_t) PCIDevGetVendorId(PPCIDEVICE pPciDev)
    612 {
    613     return PCIDevGetWord(pPciDev, VBOX_PCI_VENDOR_ID);
    614 }
    615 
    616 
    617 /**
    618  * Sets the device id config register.
    619  * @param   pPciDev         The PCI device.
    620  * @param   u16DeviceId     The device id.
    621  */
    622 DECLINLINE(void) PCIDevSetDeviceId(PPCIDEVICE pPciDev, uint16_t u16DeviceId)
    623 {
    624     PCIDevSetWord(pPciDev, VBOX_PCI_DEVICE_ID, u16DeviceId);
    625 }
    626 
    627 /**
    628  * Gets the device id config register.
    629  * @returns the device id.
    630  * @param   pPciDev         The PCI device.
    631  */
    632 DECLINLINE(uint16_t) PCIDevGetDeviceId(PPCIDEVICE pPciDev)
    633 {
    634     return PCIDevGetWord(pPciDev, VBOX_PCI_DEVICE_ID);
    635 }
    636 
    637 /**
    638  * Sets the command config register.
    639  *
    640  * @param   pPciDev         The PCI device.
    641  * @param   u16Command      The command register value.
    642  */
    643 DECLINLINE(void) PCIDevSetCommand(PPCIDEVICE pPciDev, uint16_t u16Command)
    644 {
    645     PCIDevSetWord(pPciDev, VBOX_PCI_COMMAND, u16Command);
    646 }
    647 
    648 
    649 /**
    650  * Gets the command config register.
    651  * @returns The command register value.
    652  * @param   pPciDev         The PCI device.
    653  */
    654 DECLINLINE(uint16_t) PCIDevGetCommand(PPCIDEVICE pPciDev)
    655 {
    656     return PCIDevGetWord(pPciDev, VBOX_PCI_COMMAND);
    657 }
    658 
    659 /**
    660  * Checks if the given PCI device is a bus master.
    661  * @returns true if the device is a bus master, false if not.
    662  * @param   pPciDev         The PCI device.
    663  */
    664 DECLINLINE(bool) PCIDevIsBusmaster(PPCIDEVICE pPciDev)
    665 {
    666     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
    667 }
    668 
    669 /**
    670  * Checks if INTx interrupts disabled in the command config register.
    671  * @returns true if disabled.
    672  * @param   pPciDev         The PCI device.
    673  */
    674 DECLINLINE(bool) PCIDevIsIntxDisabled(PPCIDEVICE pPciDev)
    675 {
    676     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
    677 }
    678 
    679 /**
    680  * Gets the status config register.
    681  *
    682  * @returns status config register.
    683  * @param   pPciDev         The PCI device.
    684  */
    685 DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
    686 {
    687     return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
    688 }
    689 
    690 /**
    691  * Sets the status config register.
    692  *
    693  * @param   pPciDev         The PCI device.
    694  * @param   u16Status       The status register value.
    695  */
    696 DECLINLINE(void) PCIDevSetStatus(PPCIDEVICE pPciDev, uint16_t u16Status)
    697 {
    698     PCIDevSetWord(pPciDev, VBOX_PCI_STATUS, u16Status);
    699 }
    700 
    701 
    702 /**
    703  * Sets the revision id config register.
    704  *
    705  * @param   pPciDev         The PCI device.
    706  * @param   u8RevisionId    The revision id.
    707  */
    708 DECLINLINE(void) PCIDevSetRevisionId(PPCIDEVICE pPciDev, uint8_t u8RevisionId)
    709 {
    710     PCIDevSetByte(pPciDev, VBOX_PCI_REVISION_ID, u8RevisionId);
    711 }
    712 
    713 
    714 /**
    715  * Sets the register level programming class config register.
    716  *
    717  * @param   pPciDev         The PCI device.
    718  * @param   u8ClassProg     The new value.
    719  */
    720 DECLINLINE(void) PCIDevSetClassProg(PPCIDEVICE pPciDev, uint8_t u8ClassProg)
    721 {
    722     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_PROG, u8ClassProg);
    723 }
    724 
    725 
    726 /**
    727  * Sets the sub-class (aka device class) config register.
    728  *
    729  * @param   pPciDev         The PCI device.
    730  * @param   u8SubClass      The sub-class.
    731  */
    732 DECLINLINE(void) PCIDevSetClassSub(PPCIDEVICE pPciDev, uint8_t u8SubClass)
    733 {
    734     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_SUB, u8SubClass);
    735 }
    736 
    737 
    738 /**
    739  * Sets the base class config register.
    740  *
    741  * @param   pPciDev         The PCI device.
    742  * @param   u8BaseClass     The base class.
    743  */
    744 DECLINLINE(void) PCIDevSetClassBase(PPCIDEVICE pPciDev, uint8_t u8BaseClass)
    745 {
    746     PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_BASE, u8BaseClass);
    747 }
    748 
    749 /**
    750  * Sets the header type config register.
    751  *
    752  * @param   pPciDev         The PCI device.
    753  * @param   u8HdrType       The header type.
    754  */
    755 DECLINLINE(void) PCIDevSetHeaderType(PPCIDEVICE pPciDev, uint8_t u8HdrType)
    756 {
    757     PCIDevSetByte(pPciDev, VBOX_PCI_HEADER_TYPE, u8HdrType);
    758 }
    759 
    760 /**
    761  * Gets the header type config register.
    762  *
    763  * @param   pPciDev         The PCI device.
    764  * @returns u8HdrType       The header type.
    765  */
    766 DECLINLINE(uint8_t) PCIDevGetHeaderType(PPCIDEVICE pPciDev)
    767 {
    768     return PCIDevGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
    769 }
    770 
    771 /**
    772  * Sets the BIST (built-in self-test) config register.
    773  *
    774  * @param   pPciDev         The PCI device.
    775  * @param   u8Bist          The BIST value.
    776  */
    777 DECLINLINE(void) PCIDevSetBIST(PPCIDEVICE pPciDev, uint8_t u8Bist)
    778 {
    779     PCIDevSetByte(pPciDev, VBOX_PCI_BIST, u8Bist);
    780 }
    781 
    782 /**
    783  * Gets the BIST (built-in self-test) config register.
    784  *
    785  * @param   pPciDev         The PCI device.
    786  * @returns u8Bist          The BIST.
    787  */
    788 DECLINLINE(uint8_t) PCIDevGetBIST(PPCIDEVICE pPciDev)
    789 {
    790     return PCIDevGetByte(pPciDev, VBOX_PCI_BIST);
    791 }
    792 
    793 
    794 /**
    795  * Sets a base address config register.
    796  *
    797  * @param   pPciDev         The PCI device.
    798  * @param   iReg            Base address register number (0..5).
    799  * @param   fIOSpace        Whether it's I/O (true) or memory (false) space.
    800  * @param   fPrefetchable   Whether the memory is prefetachable. Must be false if fIOSpace == true.
    801  * @param   f64Bit          Whether the memory can be mapped anywhere in the 64-bit address space. Otherwise restrict to 32-bit.
    802  * @param   u32Addr         The address value.
    803  */
    804 DECLINLINE(void) PCIDevSetBaseAddress(PPCIDEVICE pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit,
    805                                       uint32_t u32Addr)
    806 {
    807     if (fIOSpace)
    808     {
    809         Assert(!(u32Addr & 0x3)); Assert(!fPrefetchable); Assert(!f64Bit);
    810         u32Addr |= RT_BIT_32(0);
    811     }
    812     else
    813     {
    814         Assert(!(u32Addr & 0xf));
    815         if (fPrefetchable)
    816             u32Addr |= RT_BIT_32(3);
    817         if (f64Bit)
    818             u32Addr |= 0x2 << 1;
    819     }
    820     switch (iReg)
    821     {
    822         case 0: iReg = VBOX_PCI_BASE_ADDRESS_0; break;
    823         case 1: iReg = VBOX_PCI_BASE_ADDRESS_1; break;
    824         case 2: iReg = VBOX_PCI_BASE_ADDRESS_2; break;
    825         case 3: iReg = VBOX_PCI_BASE_ADDRESS_3; break;
    826         case 4: iReg = VBOX_PCI_BASE_ADDRESS_4; break;
    827         case 5: iReg = VBOX_PCI_BASE_ADDRESS_5; break;
    828         default: AssertFailedReturnVoid();
    829     }
    830 
    831     PCIDevSetDWord(pPciDev, iReg, u32Addr);
    832 }
    833 
    834 /**
    835  * Please document me. I don't seem to be getting as much as calculating
    836  * the address of some PCI region.
    837  */
    838 DECLINLINE(uint32_t) PCIDevGetRegionReg(uint32_t iRegion)
    839 {
    840     return iRegion == VBOX_PCI_ROM_SLOT
    841          ? VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
    842 }
    843 
    844 /**
    845  * Sets the sub-system vendor id config register.
    846  *
    847  * @param   pPciDev             The PCI device.
    848  * @param   u16SubSysVendorId   The sub-system vendor id.
    849  */
    850 DECLINLINE(void) PCIDevSetSubSystemVendorId(PPCIDEVICE pPciDev, uint16_t u16SubSysVendorId)
    851 {
    852     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID, u16SubSysVendorId);
    853 }
    854 
    855 /**
    856  * Gets the sub-system vendor id config register.
    857  * @returns the sub-system vendor id.
    858  * @param   pPciDev         The PCI device.
    859  */
    860 DECLINLINE(uint16_t) PCIDevGetSubSystemVendorId(PPCIDEVICE pPciDev)
    861 {
    862     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID);
    863 }
    864 
    865 
    866 /**
    867  * Sets the sub-system id config register.
    868  *
    869  * @param   pPciDev         The PCI device.
    870  * @param   u16SubSystemId  The sub-system id.
    871  */
    872 DECLINLINE(void) PCIDevSetSubSystemId(PPCIDEVICE pPciDev, uint16_t u16SubSystemId)
    873 {
    874     PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID, u16SubSystemId);
    875 }
    876 
    877 /**
    878  * Gets the sub-system id config register.
    879  * @returns the sub-system id.
    880  * @param   pPciDev         The PCI device.
    881  */
    882 DECLINLINE(uint16_t) PCIDevGetSubSystemId(PPCIDEVICE pPciDev)
    883 {
    884     return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID);
    885 }
    886 
    887 /**
    888  * Sets offset to capability list.
    889  *
    890  * @param   pPciDev         The PCI device.
    891  * @param   u8Offset        The offset to capability list.
    892  */
    893 DECLINLINE(void) PCIDevSetCapabilityList(PPCIDEVICE pPciDev, uint8_t u8Offset)
    894 {
    895     PCIDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
    896 }
    897 
    898 /**
    899  * Returns offset to capability list.
    900  *
    901  * @returns offset to capability list.
    902  * @param   pPciDev         The PCI device.
    903  */
    904 DECLINLINE(uint8_t) PCIDevGetCapabilityList(PPCIDEVICE pPciDev)
    905 {
    906     return PCIDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
    907 }
    908 
    909 /**
    910  * Sets the interrupt line config register.
    911  *
    912  * @param   pPciDev         The PCI device.
    913  * @param   u8Line          The interrupt line.
    914  */
    915 DECLINLINE(void) PCIDevSetInterruptLine(PPCIDEVICE pPciDev, uint8_t u8Line)
    916 {
    917     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE, u8Line);
    918 }
    919 
    920 /**
    921  * Gets the interrupt line config register.
    922  *
    923  * @returns The interrupt line.
    924  * @param   pPciDev         The PCI device.
    925  */
    926 DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev)
    927 {
    928     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE);
    929 }
    930 
    931 /**
    932  * Sets the interrupt pin config register.
    933  *
    934  * @param   pPciDev         The PCI device.
    935  * @param   u8Pin           The interrupt pin.
    936  */
    937 DECLINLINE(void) PCIDevSetInterruptPin(PPCIDEVICE pPciDev, uint8_t u8Pin)
    938 {
    939     PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN, u8Pin);
    940 }
    941 
    942 /**
    943  * Gets the interrupt pin config register.
    944  *
    945  * @returns The interrupt pin.
    946  * @param   pPciDev         The PCI device.
    947  */
    948 DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev)
    949 {
    950     return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN);
    951 }
    952 
    953 #ifdef PCIDEVICEINT_DECLARED
    954 DECLINLINE(void) pciDevSetRequestedDevfunc(PPCIDEVICE pDev)
    955 {
    956     pDev->Int.s.fFlags |= PCIDEV_FLAG_REQUESTED_DEVFUNC;
    957 }
    958 
    959 DECLINLINE(void) pciDevClearRequestedDevfunc(PPCIDEVICE pDev)
    960 {
    961     pDev->Int.s.fFlags &= ~PCIDEV_FLAG_REQUESTED_DEVFUNC;
    962 }
    963 
    964 DECLINLINE(bool) pciDevIsRequestedDevfunc(PPCIDEVICE pDev)
    965 {
    966     return (pDev->Int.s.fFlags & PCIDEV_FLAG_REQUESTED_DEVFUNC) != 0;
    967 }
    968 
    969 DECLINLINE(void) pciDevSetPci2PciBridge(PPCIDEVICE pDev)
     20DECLINLINE(void) pciDevSetPci2PciBridge(PPDMPCIDEV pDev)
    97021{
    97122    pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_TO_PCI_BRIDGE;
    97223}
    97324
    974 DECLINLINE(bool) pciDevIsPci2PciBridge(PPCIDEVICE pDev)
     25DECLINLINE(bool) pciDevIsPci2PciBridge(PPDMPCIDEV pDev)
    97526{
    97627    return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_TO_PCI_BRIDGE) != 0;
    97728}
    97829
    979 DECLINLINE(void) pciDevSetPciExpress(PPCIDEVICE pDev)
     30DECLINLINE(void) pciDevSetPciExpress(PPDMPCIDEV pDev)
    98031{
    98132    pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_EXPRESS_DEVICE;
    98233}
    98334
    984 DECLINLINE(bool) pciDevIsPciExpress(PPCIDEVICE pDev)
     35DECLINLINE(bool) pciDevIsPciExpress(PPDMPCIDEV pDev)
    98536{
    98637    return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_EXPRESS_DEVICE) != 0;
    98738}
    98839
    989 DECLINLINE(void) pciDevSetMsiCapable(PPCIDEVICE pDev)
     40DECLINLINE(void) pciDevSetMsiCapable(PPDMPCIDEV pDev)
    99041{
    99142    pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI_CAPABLE;
    99243}
    99344
    994 DECLINLINE(void) pciDevClearMsiCapable(PPCIDEVICE pDev)
     45DECLINLINE(void) pciDevClearMsiCapable(PPDMPCIDEV pDev)
    99546{
    99647    pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI_CAPABLE;
    99748}
    99849
    999 DECLINLINE(bool) pciDevIsMsiCapable(PPCIDEVICE pDev)
     50DECLINLINE(bool) pciDevIsMsiCapable(PPDMPCIDEV pDev)
    100051{
    100152    return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI_CAPABLE) != 0;
    100253}
    100354
    1004 DECLINLINE(void) pciDevSetMsi64Capable(PPCIDEVICE pDev)
     55DECLINLINE(void) pciDevSetMsi64Capable(PPDMPCIDEV pDev)
    100556{
    100657    pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI64_CAPABLE;
    100758}
    100859
    1009 DECLINLINE(void) pciDevClearMsi64Capable(PPCIDEVICE pDev)
     60DECLINLINE(void) pciDevClearMsi64Capable(PPDMPCIDEV pDev)
    101061{
    101162    pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI64_CAPABLE;
    101263}
    101364
    1014 DECLINLINE(bool) pciDevIsMsi64Capable(PPCIDEVICE pDev)
     65DECLINLINE(bool) pciDevIsMsi64Capable(PPDMPCIDEV pDev)
    101566{
    101667    return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI64_CAPABLE) != 0;
    101768}
    101869
    1019 DECLINLINE(void) pciDevSetMsixCapable(PPCIDEVICE pDev)
     70DECLINLINE(void) pciDevSetMsixCapable(PPDMPCIDEV pDev)
    102071{
    102172    pDev->Int.s.fFlags |= PCIDEV_FLAG_MSIX_CAPABLE;
    102273}
    102374
    1024 DECLINLINE(void) pciDevClearMsixCapable(PPCIDEVICE pDev)
     75DECLINLINE(void) pciDevClearMsixCapable(PPDMPCIDEV pDev)
    102576{
    102677    pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSIX_CAPABLE;
    102778}
    102879
    1029 DECLINLINE(bool) pciDevIsMsixCapable(PPCIDEVICE pDev)
     80DECLINLINE(bool) pciDevIsMsixCapable(PPDMPCIDEV pDev)
    103081{
    103182    return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSIX_CAPABLE) != 0;
    103283}
    103384
    1034 DECLINLINE(void) pciDevSetPassthrough(PPCIDEVICE pDev)
     85DECLINLINE(void) pciDevSetPassthrough(PPDMPCIDEV pDev)
    103586{
    103687    pDev->Int.s.fFlags |= PCIDEV_FLAG_PASSTHROUGH;
    103788}
    103889
    1039 DECLINLINE(void) pciDevClearPassthrough(PPCIDEVICE pDev)
     90DECLINLINE(void) pciDevClearPassthrough(PPDMPCIDEV pDev)
    104091{
    104192    pDev->Int.s.fFlags &= ~PCIDEV_FLAG_PASSTHROUGH;
    104293}
    104394
    1044 DECLINLINE(bool) pciDevIsPassthrough(PPCIDEVICE pDev)
     95DECLINLINE(bool) pciDevIsPassthrough(PPDMPCIDEV pDev)
    104596{
    104697    return (pDev->Int.s.fFlags & PCIDEV_FLAG_PASSTHROUGH) != 0;
    104798}
    104899
    1049 #endif /* PCIDEVICEINT_DECLARED */
     100#endif
    1050101
    1051 #if defined(__cplusplus) && defined(IN_RING3)
    1052 /* For RTStrPrintf(). */
    1053 #include <iprt/string.h>
    1054 
    1055 /**
    1056  * Class representing PCI address. PCI device consist of
    1057  * bus, device and function numbers. Generally device PCI
    1058  * address could be changed during runtime, but only by
    1059  * an OS PCI driver.
    1060  *
    1061  * @remarks C++ classes (structs included) are not generally accepted in
    1062  *          VMM devices or drivers.  An exception may be granted for this class
    1063  *          if it's contained to ring-3 and that this is a one time exception
    1064  *          which sets no precedent.
    1065  */
    1066 struct PCIBusAddress
    1067 {
    1068     /** @todo: think if we'll need domain, which is higher
    1069      *  word of the address. */
    1070     int  miBus;
    1071     int  miDevice;
    1072     int  miFn;
    1073 
    1074     PCIBusAddress()
    1075     {
    1076         clear();
    1077     }
    1078 
    1079     PCIBusAddress(int iBus, int iDevice, int iFn)
    1080     {
    1081         init(iBus, iDevice, iFn);
    1082     }
    1083 
    1084     PCIBusAddress(int32_t iAddr)
    1085     {
    1086         clear();
    1087         fromLong(iAddr);
    1088     }
    1089 
    1090     PCIBusAddress& clear()
    1091     {
    1092         miBus = miDevice = miFn = -1;
    1093         return *this;
    1094     }
    1095 
    1096     void init(int iBus, int iDevice, int iFn)
    1097     {
    1098         miBus    = iBus;
    1099         miDevice = iDevice;
    1100         miFn     = iFn;
    1101     }
    1102 
    1103     void init(const PCIBusAddress &a)
    1104     {
    1105         miBus    = a.miBus;
    1106         miDevice = a.miDevice;
    1107         miFn     = a.miFn;
    1108     }
    1109 
    1110     bool operator<(const PCIBusAddress &a) const
    1111     {
    1112         if (miBus < a.miBus)
    1113             return true;
    1114 
    1115         if (miBus > a.miBus)
    1116             return false;
    1117 
    1118         if (miDevice < a.miDevice)
    1119             return true;
    1120 
    1121         if (miDevice > a.miDevice)
    1122             return false;
    1123 
    1124         if (miFn < a.miFn)
    1125             return true;
    1126 
    1127         if (miFn > a.miFn)
    1128             return false;
    1129 
    1130         return false;
    1131     }
    1132 
    1133     bool operator==(const PCIBusAddress &a) const
    1134     {
    1135         return     (miBus    == a.miBus)
    1136                 && (miDevice == a.miDevice)
    1137                 && (miFn     == a.miFn);
    1138     }
    1139 
    1140     bool operator!=(const PCIBusAddress &a) const
    1141     {
    1142         return     (miBus    != a.miBus)
    1143                 || (miDevice != a.miDevice)
    1144                 || (miFn     != a.miFn);
    1145     }
    1146 
    1147     bool valid() const
    1148     {
    1149         return (miBus    != -1)
    1150             && (miDevice != -1)
    1151             && (miFn     != -1);
    1152     }
    1153 
    1154     int32_t asLong() const
    1155     {
    1156         Assert(valid());
    1157         return (miBus << 8) | (miDevice << 3) | miFn;
    1158     }
    1159 
    1160     PCIBusAddress& fromLong(int32_t value)
    1161     {
    1162         miBus = (value >> 8) & 0xff;
    1163         miDevice = (value & 0xff) >> 3;
    1164         miFn = (value & 7);
    1165         return *this;
    1166     }
    1167 
    1168     /** Create string representation of this PCI address. */
    1169     bool format(char* szBuf, int32_t cBufSize)
    1170     {
    1171         if (cBufSize < (/* bus */ 2 + /* : */ 1 + /* device */ 2 + /* . */ 1 + /* function*/ 1 + /* \0 */1))
    1172             return false;
    1173 
    1174         if (valid())
    1175             RTStrPrintf(szBuf, cBufSize, "%02x:%02x.%01x", miBus, miDevice, miFn);
    1176         else
    1177             RTStrPrintf(szBuf, cBufSize, "%s", "<bad>");
    1178 
    1179         return true;
    1180     }
    1181 
    1182     static const size_t cMaxAddrSize = 10;
    1183 };
    1184 #endif /* __cplusplus */
    1185 
    1186 /** @} */
    1187 
    1188 #endif
  • trunk/src/VBox/Devices/GIMDev/GIMDev.cpp

    r64357 r64373  
    285285        {
    286286            Assert(!pCur->fRegistered);
    287             rc = PDMDevHlpMMIO2Register(pDevIns, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3,
    288                                             pCur->szDescription);
     287            rc = PDMDevHlpMMIO2Register(pDevIns, NULL, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3,
     288                                        pCur->szDescription);
    289289            if (RT_FAILURE(rc))
    290290                return rc;
     
    294294#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
    295295            RTR0PTR pR0Mapping = 0;
    296             rc = PDMDevHlpMMIO2MapKernel(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
     296            rc = PDMDevHlpMMIO2MapKernel(pDevIns, NULL, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
    297297                                         &pR0Mapping);
    298298            AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMapMMIO2IntoR0(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
     
    308308            {
    309309                RTRCPTR pRCMapping = 0;
    310                 rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
     310                rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, NULL, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
    311311                                              &pRCMapping);
    312312                AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r64356 r64373  
    37603760
    37613761/**
    3762  * Callback function for mapping a PCI I/O region.
    3763  *
    3764  * @return VBox status code.
    3765  * @param   pPciDev         Pointer to PCI device.
    3766  *                          Use pPciDev->pDevIns to get the device instance.
    3767  * @param   iRegion         The region number.
    3768  * @param   GCPhysAddress   Physical address of the region.
    3769  *                          If iType is PCI_ADDRESS_SPACE_IO, this is an
    3770  *                          I/O port, else it's a physical address.
    3771  *                          This address is *NOT* relative
    3772  *                          to pci_mem_base like earlier!
    3773  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
     3762 * @callback_method_impl{FNPCIIOREGIONMAP}
    37743763 */
    3775 DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb,
    3776                                       PCIADDRESSSPACE enmType)
     3764DECLCALLBACK(int) vmsvgaR3IORegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     3765                                      RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    37773766{
    37783767    int         rc;
    3779     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    37803768    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
    37813769
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h

    r63690 r64373  
     1/* $Id$ */
    12/** @file
    23 * VMware SVGA device
     
    1314 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1415 */
    15 #ifndef __DEVVGA_SVGA_H__
    16 #define __DEVVGA_SVGA_H__
     16
     17#ifndef ___DevVGA_SVGA_h___
     18#define ___DevVGA_SVGA_h___
    1719
    1820
     
    4143#define VMSVGA_ACTION_CHANGEMODE        RT_BIT(VMSVGA_ACTION_CHANGEMODE_BIT)
    4244
    43 DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType);
     45DECLCALLBACK(int) vmsvgaR3IORegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     46                                      RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType);
    4447
    45 DECLCALLBACK(void) vmsvgaPortSetViewport(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
     48DECLCALLBACK(void) vmsvgaPortSetViewport(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId,
     49                                         uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
    4650
    4751int vmsvgaInit(PPDMDEVINS pDevIns);
     
    5458DECLCALLBACK(void) vmsvgaR3PowerOff(PPDMDEVINS pDevIns);
    5559
    56 #endif  /* __DEVVGA_SVGA_H__ */
     60#endif
     61
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r64356 r64373  
    53985398
    53995399/**
    5400  * Callback function for unmapping and/or mapping the VRAM MMIO2 region (called by the PCI bus).
    5401  *
    5402  * @return VBox status code.
    5403  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    5404  * @param   iRegion         The region number.
    5405  * @param   GCPhysAddress   Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
    5406  *                          I/O port, else it's a physical address.
    5407  *                          This address is *NOT* relative to pci_mem_base like earlier!
    5408  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
    5409  */
    5410 static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    5411                                           RTGCPHYS cb, PCIADDRESSSPACE enmType)
     5400 * @callback_method_impl{FNPCIIOREGIONMAP, Mapping/unmapping the VRAM MMI2 region}
     5401 */
     5402static DECLCALLBACK(int) vgaR3IORegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     5403                                          RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    54125404{
    54135405    RT_NOREF1(cb);
    54145406    int         rc;
    5415     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    54165407    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
    54175408    Log(("vgaR3IORegionMap: iRegion=%d GCPhysAddress=%RGp cb=%RGp enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
    54185409#ifdef VBOX_WITH_VMSVGA
    5419     AssertReturn(   (iRegion == ((pThis->fVMSVGAEnabled) ? 1 : 0))
    5420                  && (enmType == ((pThis->fVMSVGAEnabled) ? PCI_ADDRESS_SPACE_MEM : PCI_ADDRESS_SPACE_MEM_PREFETCH)),
     5410    AssertReturn(   iRegion == (pThis->fVMSVGAEnabled ? 1U : 0U)
     5411                 && enmType == (pThis->fVMSVGAEnabled ? PCI_ADDRESS_SPACE_MEM : PCI_ADDRESS_SPACE_MEM_PREFETCH),
    54215412                 VERR_INTERNAL_ERROR);
    54225413#else
     
    62076198
    62086199    /*
     6200     * PCI device registration.
     6201     */
     6202    rc = PDMDevHlpPCIRegister(pDevIns, &pThis->Dev);
     6203    if (RT_FAILURE(rc))
     6204        return rc;
     6205    /*AssertMsg(pThis->Dev.devfn == 16 || iInstance != 0, ("pThis->Dev.devfn=%d\n", pThis->Dev.devfn));*/
     6206    if (pThis->Dev.devfn != 16 && iInstance == 0)
     6207        Log(("!!WARNING!!: pThis->dev.devfn=%d (ignore if testcase or not started by Main)\n", pThis->Dev.devfn));
     6208
     6209#ifdef VBOX_WITH_VMSVGA
     6210    if (pThis->fVMSVGAEnabled)
     6211    {
     6212        /* Register the io command ports. */
     6213        rc = PDMDevHlpPCIIORegionRegister (pDevIns, 0 /* iRegion */, 0x10, PCI_ADDRESS_SPACE_IO, vmsvgaR3IORegionMap);
     6214        if (RT_FAILURE (rc))
     6215            return rc;
     6216        /* VMware's MetalKit doesn't like PCI_ADDRESS_SPACE_MEM_PREFETCH */
     6217        rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1 /* iRegion */, pThis->vram_size,
     6218                                          PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vgaR3IORegionMap);
     6219        if (RT_FAILURE(rc))
     6220            return rc;
     6221        rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2 /* iRegion */, VMSVGA_FIFO_SIZE,
     6222                                          PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vmsvgaR3IORegionMap);
     6223        if (RT_FAILURE(rc))
     6224            return rc;
     6225    }
     6226    else
     6227#endif /* VBOX_WITH_VMSVGA */
     6228    {
     6229#ifdef VBOX_WITH_VMSVGA
     6230        int iPCIRegionVRAM = (pThis->fVMSVGAEnabled) ? 1 : 0;
     6231#else
     6232        int iPCIRegionVRAM = 0;
     6233#endif
     6234        rc = PDMDevHlpPCIIORegionRegister(pDevIns, iPCIRegionVRAM, pThis->vram_size,
     6235                                          PCI_ADDRESS_SPACE_MEM_PREFETCH, vgaR3IORegionMap);
     6236        if (RT_FAILURE(rc))
     6237            return rc;
     6238    }
     6239
     6240    /*
    62096241     * Allocate the VRAM and map the first 512KB of it into GC so we can speed up VGA support.
    62106242     */
     
    62176249         * Allocate and initialize the FIFO MMIO2 memory.
    62186250         */
    6219         rc = PDMDevHlpMMIO2Register(pDevIns, 2 /*iRegion*/, VMSVGA_FIFO_SIZE, 0 /*fFlags*/, (void **)&pThis->svga.pFIFOR3, "VMSVGA-FIFO");
     6251        rc = PDMDevHlpMMIO2Register(pDevIns, &pThis->Dev, 2 /*iRegion*/, VMSVGA_FIFO_SIZE,
     6252                                    0 /*fFlags*/, (void **)&pThis->svga.pFIFOR3, "VMSVGA-FIFO");
    62206253        if (RT_FAILURE(rc))
    62216254            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     
    62276260    int iPCIRegionVRAM = 0;
    62286261#endif
    6229     rc = PDMDevHlpMMIO2Register(pDevIns, iPCIRegionVRAM, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
     6262    rc = PDMDevHlpMMIO2Register(pDevIns, &pThis->Dev, iPCIRegionVRAM, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
    62306263    AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMIO2Register(%#x,) -> %Rrc\n", pThis->vram_size, rc), rc);
    62316264    pThis->vram_ptrR0 = (RTR0PTR)pThis->vram_ptrR3; /** @todo @bugref{1865} Map parts into R0 or just use PGM access (Mac only). */
     
    62346267    {
    62356268        RTRCPTR pRCMapping = 0;
    6236         rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, iPCIRegionVRAM, 0 /* off */,  VGA_MAPPING_SIZE, "VGA VRam", &pRCMapping);
     6269        rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, &pThis->Dev, iPCIRegionVRAM, 0 /* off */,  VGA_MAPPING_SIZE,
     6270                                      "VGA VRam", &pRCMapping);
    62376271        AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", VGA_MAPPING_SIZE, rc), rc);
    62386272        pThis->vram_ptrRC = pRCMapping;
    6239 # ifdef VBOX_WITH_VMSVGA
     6273#ifdef VBOX_WITH_VMSVGA
    62406274        /* Don't need a mapping in RC */
    6241 # endif
     6275#endif
    62426276    }
    62436277
     
    65316565    if (RT_FAILURE(rc))
    65326566        return rc;
    6533 
    6534     /*
    6535      * PCI device registration.
    6536      */
    6537     rc = PDMDevHlpPCIRegister(pDevIns, &pThis->Dev);
    6538     if (RT_FAILURE(rc))
    6539         return rc;
    6540     /*AssertMsg(pThis->Dev.devfn == 16 || iInstance != 0, ("pThis->Dev.devfn=%d\n", pThis->Dev.devfn));*/
    6541     if (pThis->Dev.devfn != 16 && iInstance == 0)
    6542         Log(("!!WARNING!!: pThis->dev.devfn=%d (ignore if testcase or not started by Main)\n", pThis->Dev.devfn));
    6543 
    6544 #ifdef VBOX_WITH_VMSVGA
    6545     if (pThis->fVMSVGAEnabled)
    6546     {
    6547         /* Register the io command ports. */
    6548         rc = PDMDevHlpPCIIORegionRegister (pDevIns, 0 /* iRegion */, 0x10, PCI_ADDRESS_SPACE_IO, vmsvgaR3IORegionMap);
    6549         if (RT_FAILURE (rc))
    6550             return rc;
    6551         /* VMware's MetalKit doesn't like PCI_ADDRESS_SPACE_MEM_PREFETCH */
    6552         rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1 /* iRegion */, pThis->vram_size,
    6553                                           PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vgaR3IORegionMap);
    6554         if (RT_FAILURE(rc))
    6555             return rc;
    6556         rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2 /* iRegion */, VMSVGA_FIFO_SIZE,
    6557                                           PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vmsvgaR3IORegionMap);
    6558         if (RT_FAILURE(rc))
    6559             return rc;
    6560     }
    6561     else
    6562 #endif /* VBOX_WITH_VMSVGA */
    6563     {
    6564         rc = PDMDevHlpPCIIORegionRegister(pDevIns, iPCIRegionVRAM, pThis->vram_size,
    6565                                           PCI_ADDRESS_SPACE_MEM_PREFETCH, vgaR3IORegionMap);
    6566         if (RT_FAILURE(rc))
    6567             return rc;
    6568     }
    65696567
    65706568    /*
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r64356 r64373  
    61046104 * @callback_method_impl{FNPCIIOREGIONMAP}
    61056105 */
    6106 static DECLCALLBACK(int) e1kMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     6106static DECLCALLBACK(int) e1kMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     6107                                RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    61076108{
    61086109    RT_NOREF(iRegion);
     
    61146115        case PCI_ADDRESS_SPACE_IO:
    61156116            pThis->IOPortBase = (RTIOPORT)GCPhysAddress;
    6116             rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, pThis->IOPortBase, cb, NULL /*pvUser*/,
     6117            rc = PDMDevHlpIOPortRegister(pDevIns, pThis->IOPortBase, cb, NULL /*pvUser*/,
    61176118                                         e1kIOPortOut, e1kIOPortIn, NULL, NULL, "E1000");
    61186119            if (pThis->fR0Enabled && RT_SUCCESS(rc))
    6119                 rc = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, pThis->IOPortBase, cb, NIL_RTR0PTR /*pvUser*/,
     6120                rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, cb, NIL_RTR0PTR /*pvUser*/,
    61206121                                             "e1kIOPortOut", "e1kIOPortIn", NULL, NULL, "E1000");
    61216122            if (pThis->fRCEnabled && RT_SUCCESS(rc))
    6122                 rc = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, pThis->IOPortBase, cb, NIL_RTRCPTR /*pvUser*/,
     6123                rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, cb, NIL_RTRCPTR /*pvUser*/,
    61236124                                               "e1kIOPortOut", "e1kIOPortIn", NULL, NULL, "E1000");
    61246125            break;
     
    61396140            {
    61406141                Assert(!(GCPhysAddress & 7));
    6141                 rc = PDMDevHlpMMIOExMap(pPciDev->pDevIns, pPciDev, iRegion, GCPhysAddress);
     6142                rc = PDMDevHlpMMIOExMap(pDevIns, pPciDev, iRegion, GCPhysAddress);
    61426143            }
    61436144#else
    61446145            pThis->addrMMReg = GCPhysAddress; Assert(!(GCPhysAddress & 7));
    6145             rc = PDMDevHlpMMIORegister(pPciDev->pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
     6146            rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    61466147                                       IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD,
    61476148                                       e1kMMIOWrite, e1kMMIORead, "E1000");
    61486149            if (pThis->fR0Enabled && RT_SUCCESS(rc))
    6149                 rc = PDMDevHlpMMIORegisterR0(pPciDev->pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/,
     6150                rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/,
    61506151                                             "e1kMMIOWrite", "e1kMMIORead");
    61516152            if (pThis->fRCEnabled && RT_SUCCESS(rc))
    6152                 rc = PDMDevHlpMMIORegisterRC(pPciDev->pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/,
     6153                rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/,
    61536154                                             "e1kMMIOWrite", "e1kMMIORead");
    61546155#endif
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r64357 r64373  
    38673867 * @callback_method_impl{FNPCIIOREGIONMAP, For the PC-NET I/O Ports.}
    38683868 */
    3869 static DECLCALLBACK(int) pcnetIOPortMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     3869static DECLCALLBACK(int) pcnetIOPortMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
    38703870                                        RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    38713871{
    38723872    RT_NOREF(iRegion, cb, enmType);
    38733873    int         rc;
    3874     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    38753874    RTIOPORT    Port    = (RTIOPORT)GCPhysAddress;
    38763875    PPCNETSTATE pThis   = PCIDEV_2_PCNETSTATE(pPciDev);
     
    39193918 * @callback_method_impl{FNPCIIOREGIONMAP, For the PC-Net MMIO region.}
    39203919 */
    3921 static DECLCALLBACK(int) pcnetMMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     3920static DECLCALLBACK(int) pcnetMMIOMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
    39223921                                      RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    39233922{
     
    39303929
    39313930    /* We use the assigned size here, because we only support page aligned MMIO ranges. */
    3932     rc = PDMDevHlpMMIORegister(pPciDev->pDevIns, GCPhysAddress, cb, pThis,
     3931    rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, pThis,
    39333932                               IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    39343933                               pcnetMMIOWrite, pcnetMMIORead, "PCNet");
     
    42924291        /* older saved states contain the shared memory region which was never used for ages. */
    42934292        void *pvSharedMMIOR3;
    4294         rc = PDMDevHlpMMIO2Register(pDevIns, 2, _512K, 0, (void **)&pvSharedMMIOR3, "PCNetSh");
     4293        rc = PDMDevHlpMMIO2Register(pDevIns, &pThis->PciDev, 2, _512K, 0, (void **)&pvSharedMMIOR3, "PCNetSh");
    42954294        if (RT_FAILURE(rc))
    42964295            rc = PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r63690 r64373  
    17781778 * @callback_method_impl{FNPCIIOREGIONMAP}
    17791779 */
    1780 static DECLCALLBACK(int) vnetMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     1780static DECLCALLBACK(int) vnetMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     1781                                 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    17811782{
    17821783    RT_NOREF(iRegion);
     
    17921793
    17931794    pThis->VPCI.IOPortBase = (RTIOPORT)GCPhysAddress;
    1794     rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, pThis->VPCI.IOPortBase,
     1795    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->VPCI.IOPortBase,
    17951796                                 cb, 0, vnetIOPortOut, vnetIOPortIn,
    17961797                                 NULL, NULL, "VirtioNet");
    17971798#ifdef VNET_GC_SUPPORT
    17981799    AssertRCReturn(rc, rc);
    1799     rc = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, pThis->VPCI.IOPortBase,
     1800    rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->VPCI.IOPortBase,
    18001801                                   cb, 0, "vnetIOPortOut", "vnetIOPortIn",
    18011802                                   NULL, NULL, "VirtioNet");
    18021803    AssertRCReturn(rc, rc);
    1803     rc = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, pThis->VPCI.IOPortBase,
     1804    rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->VPCI.IOPortBase,
    18041805                                   cb, 0, "vnetIOPortOut", "vnetIOPortIn",
    18051806                                   NULL, NULL, "VirtioNet");
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r64369 r64373  
    32663266 * @callback_method_impl{FNPCICONFIGREAD}
    32673267 */
    3268 static DECLCALLBACK(uint32_t) acpiR3PciConfigRead(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb)
    3269 {
    3270     PPDMDEVINS pDevIns = pPciDev->pDevIns;
     3268static DECLCALLBACK(uint32_t) acpiR3PciConfigRead(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t Address, unsigned cb)
     3269{
    32713270    ACPIState *pThis   = PDMINS_2_DATA(pDevIns, ACPIState *);
    32723271
    32733272    Log2(("acpi: PCI config read: 0x%x (%d)\n", Address, cb));
    3274     return pThis->pfnAcpiPciConfigRead(pPciDev, Address, cb);
     3273    return pThis->pfnAcpiPciConfigRead(pDevIns, pPciDev, Address, cb);
    32753274}
    32763275
     
    32783277 * @callback_method_impl{FNPCICONFIGWRITE}
    32793278 */
    3280 static DECLCALLBACK(void) acpiR3PciConfigWrite(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb)
    3281 {
    3282     PPDMDEVINS  pDevIns = pPciDev->pDevIns;
    3283     ACPIState  *pThis  = PDMINS_2_DATA(pDevIns, ACPIState *);
     3279static DECLCALLBACK(void) acpiR3PciConfigWrite(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t Address,
     3280                                               uint32_t u32Value, unsigned cb)
     3281{
     3282    ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
    32843283
    32853284    Log2(("acpi: PCI config write: 0x%x -> 0x%x (%d)\n", u32Value, Address, cb));
     
    32923291    }
    32933292
    3294     pThis->pfnAcpiPciConfigWrite(pPciDev, Address, u32Value, cb);
     3293    pThis->pfnAcpiPciConfigWrite(pDevIns, pPciDev, Address, u32Value, cb);
    32953294
    32963295    /* Assume that the base address is only changed when the corresponding
  • trunk/src/VBox/Devices/PC/DevLPC.cpp

    r62995 r64373  
    316316    pThis->dev.config[0xf3] = RT_BYTE4(RCBA_BASE);
    317317
    318     rc = PDMDevHlpPCIRegister (pDevIns, &pThis->dev);
     318    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pThis->dev, PDMPCIDEVREG_CFG_PRIMARY, PDMPCIDEVREG_F_NOT_MANDATORY_NO,
     319                                31 /*uPciDevNo*/, 0 /*uPciFunNo*/, "lpc");
    319320    if (RT_FAILURE(rc))
    320321        return rc;
  • trunk/src/VBox/Devices/Samples/DevPlayground.cpp

    r64354 r64373  
    4141*********************************************************************************************************************************/
    4242/**
    43  * Device Instance Data.
     43 * Playground device per function (sub-device) data.
     44 */
     45typedef struct VBOXPLAYGROUNDDEVICEFUNCTION
     46{
     47    /** The PCI devices. */
     48    PDMPCIDEV   PciDev;
     49    /** The function number. */
     50    uint8_t     iFun;
     51    /** Device function name. */
     52    char        szName[31];
     53} VBOXPLAYGROUNDDEVICEFUNCTION;
     54/** Pointer to a PCI function of the playground device. */
     55typedef VBOXPLAYGROUNDDEVICEFUNCTION *PVBOXPLAYGROUNDDEVICEFUNCTION;
     56
     57/**
     58 * Playground device instance data.
    4459 */
    4560typedef struct VBOXPLAYGROUNDDEVICE
    4661{
    47     /** The PCI device. */
    48     PCIDEVICE           PciDev;
     62    /** PCI device functions. */
     63    VBOXPLAYGROUNDDEVICEFUNCTION aPciFuns[8];
    4964} VBOXPLAYGROUNDDEVICE;
     65/** Pointer to the instance data of a playground device instance. */
    5066typedef VBOXPLAYGROUNDDEVICE *PVBOXPLAYGROUNDDEVICE;
    5167
     
    8096 * @callback_method_impl{FNPCIIOREGIONMAP}
    8197 */
    82 static DECLCALLBACK(int)
    83 devPlaygroundMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    84 {
    85     RT_NOREF(enmType, cb);
     98static DECLCALLBACK(int) devPlaygroundMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     99                                          RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     100{
     101    RT_NOREF(pPciDev, enmType, cb);
    86102
    87103    switch (iRegion)
     
    92108            if (GCPhysAddress == NIL_RTGCPHYS)
    93109                return VINF_SUCCESS; /* We ignore the unmap notification. */
    94             return PDMDevHlpMMIOExMap(pPciDev->pDevIns, pPciDev, iRegion, GCPhysAddress);
     110            return PDMDevHlpMMIOExMap(pDevIns, pPciDev, iRegion, GCPhysAddress);
    95111
    96112        default:
     
    131147     */
    132148    PVBOXPLAYGROUNDDEVICE pThis = PDMINS_2_DATA(pDevIns, PVBOXPLAYGROUNDDEVICE);
    133     PCIDevSetVendorId(&pThis->PciDev, 0x80ee);
    134     PCIDevSetDeviceId(&pThis->PciDev, 0xde4e);
    135     PCIDevSetClassBase(&pThis->PciDev, 0x07);   /* communications device */
    136     PCIDevSetClassSub(&pThis->PciDev, 0x80);    /* other communications device */
    137149
    138150    /*
     
    144156     * PCI device setup.
    145157     */
    146     int rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
    147     if (RT_FAILURE(rc))
    148         return rc;
    149 
    150     /* First region. */
    151     RTGCPHYS const cbFirst = 8*_1G64;
    152     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, cbFirst,
    153                                       (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
    154                                       devPlaygroundMap);
    155     AssertLogRelRCReturn(rc, rc);
    156     rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pThis->PciDev, 0, cbFirst,
    157                                     IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR0",
    158                                     NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
    159                                     NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
    160                                     NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
    161     AssertLogRelRCReturn(rc, rc);
    162 
    163     /* Second region. */
    164     RTGCPHYS const cbSecond = 256*_1G64;
    165     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, cbSecond,
    166                                       (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
    167                                       devPlaygroundMap);
    168     AssertLogRelRCReturn(rc, rc);
    169     rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pThis->PciDev, 2, cbSecond,
    170                                     IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR2",
    171                                     NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
    172                                     NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
    173                                     NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
    174     AssertLogRelRCReturn(rc, rc);
     158    uint32_t iPciDevNo = PDMPCIDEVREG_DEV_NO_FIRST_UNUSED;
     159    for (uint32_t iPciFun = 0; iPciFun < RT_ELEMENTS(pThis->aPciFuns); iPciFun++)
     160    {
     161        PVBOXPLAYGROUNDDEVICEFUNCTION pFun = &pThis->aPciFuns[iPciFun];
     162        RTStrPrintf(pFun->szName, sizeof(pThis->aPciFuns[iPciFun].PciDev), "playground%u", iPciFun);
     163        pFun->iFun = iPciFun;
     164
     165        PCIDevSetVendorId( &pFun->PciDev, 0x80ee);
     166        PCIDevSetDeviceId( &pFun->PciDev, 0xde4e);
     167        PCIDevSetClassBase(&pFun->PciDev, 0x07);   /* communications device */
     168        PCIDevSetClassSub( &pFun->PciDev, 0x80);   /* other communications device */
     169        int rc = PDMDevHlpPCIRegisterEx(pDevIns, &pFun->PciDev, iPciFun, 0 /*fFlags*/, iPciDevNo, iPciFun,
     170                                        pThis->aPciFuns[iPciFun].szName);
     171        AssertLogRelRCReturn(rc, rc);
     172
     173        /* First region. */
     174        RTGCPHYS const cbFirst = iPciFun == 0 ? 8*_1G64 : iPciFun * _4K;
     175        rc = PDMDevHlpPCIIORegionRegisterEx(pDevIns, &pFun->PciDev, 0, cbFirst,
     176                                            (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
     177                                            devPlaygroundMap);
     178        AssertLogRelRCReturn(rc, rc);
     179        rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pFun->PciDev, 0, cbFirst,
     180                                        IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR0",
     181                                        NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
     182                                        NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
     183                                        NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
     184        AssertLogRelRCReturn(rc, rc);
     185
     186        /* Second region. */
     187        RTGCPHYS const cbSecond = iPciFun == 0  ? 256*_1G64 : iPciFun * _32K;
     188        rc = PDMDevHlpPCIIORegionRegisterEx(pDevIns, &pFun->PciDev, 2, cbSecond,
     189                                            (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
     190                                            devPlaygroundMap);
     191        AssertLogRelRCReturn(rc, rc);
     192        rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pFun->PciDev, 2, cbSecond,
     193                                        IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR2",
     194                                        NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
     195                                        NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
     196                                        NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
     197        AssertLogRelRCReturn(rc, rc);
     198
     199        /* Subsequent function should use the same major as the previous one. */
     200        iPciDevNo = PDMPCIDEVREG_DEV_NO_SAME_AS_PREV;
     201    }
    175202
    176203    return VINF_SUCCESS;
  • trunk/src/VBox/Devices/Serial/DevSerial.cpp

    r64276 r64373  
    10511051 * @callback_method_impl{FNPCIIOREGIONMAP}
    10521052 */
    1053 static DECLCALLBACK(int) serialIOPortRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress,
    1054                                                RTGCPHYS cb, PCIADDRESSSPACE enmType)
     1053static DECLCALLBACK(int) serialIOPortRegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     1054                                               RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    10551055{
    10561056    PDEVSERIAL pThis = RT_FROM_MEMBER(pPciDev, DEVSERIAL, PciDev);
     
    10681068     * Register our port IO handlers.
    10691069     */
    1070     rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress, 8, (void *)pThis,
     1070    rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, 8, (void *)pThis,
    10711071                                 serial_io_write, serial_io_read, NULL, NULL, "SERIAL");
    10721072    AssertRC(rc);
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r64274 r64373  
    24492449 * @callback_method_impl{FNPCIIOREGIONMAP}
    24502450 */
    2451 static DECLCALLBACK(int) ahciR3MMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    2452                                        RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2451static DECLCALLBACK(int) ahciR3MMIOMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2452                                       RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    24532453{
    24542454    RT_NOREF(iRegion, enmType);
    24552455    PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
    2456     PPDMDEVINS pDevIns = pPciDev->pDevIns;
    24572456
    24582457    Log2(("%s: registering MMIO area at GCPhysAddr=%RGp cb=%RGp\n", __FUNCTION__, GCPhysAddress, cb));
     
    24942493 *      controller.}
    24952494 */
    2496 static DECLCALLBACK(int) ahciR3LegacyFakeIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    2497                                                     RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2495static DECLCALLBACK(int) ahciR3LegacyFakeIORangeMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2496                                                    RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    24982497{
    24992498    RT_NOREF(iRegion, enmType);
    25002499    PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
    2501     PPDMDEVINS pDevIns = pPciDev->pDevIns;
    25022500    int   rc = VINF_SUCCESS;
    25032501
     
    25352533 *      Map the BMDMA I/O port range (used for the Index/Data pair register access)}
    25362534 */
    2537 static DECLCALLBACK(int) ahciR3IdxDataIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress,
    2538                                                  RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2535static DECLCALLBACK(int) ahciR3IdxDataIORangeMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2536                                                 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    25392537{
    25402538    RT_NOREF(iRegion, enmType);
    25412539    PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
    2542     PPDMDEVINS pDevIns = pPciDev->pDevIns;
    25432540    int   rc = VINF_SUCCESS;
    25442541
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r64274 r64373  
    61106110
    61116111/**
    6112  * Callback function for mapping an PCI I/O region.
    6113  *
    6114  * @return VBox status code.
    6115  * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
    6116  * @param   iRegion         The region number.
    6117  * @param   GCPhysAddress   Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
    6118  *                          I/O port, else it's a physical address.
    6119  *                          This address is *NOT* relative to pci_mem_base like earlier!
    6120  * @param   cb              Size of the region in bytes.
    6121  * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
     6112 * @callback_method_impl{FNPCIIOREGIONMAP}
    61226113 */
    6123 static DECLCALLBACK(int) ataR3BMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     6114static DECLCALLBACK(int) ataR3BMDMAIORangeMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
    61246115                                              RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    61256116{
     
    61346125    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
    61356126    {
    6136         int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
     6127        int rc2 = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
    61376128                                          (RTHCPTR)(uintptr_t)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead,
    61386129                                          NULL, NULL, "ATA Bus Master DMA");
     
    61436134        if (pThis->fRCEnabled)
    61446135        {
    6145             rc2 = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
     6136            rc2 = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
    61466137                                            (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",
    61476138                                            NULL, NULL, "ATA Bus Master DMA");
     
    61526143        if (pThis->fR0Enabled)
    61536144        {
    6154             rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
     6145            rc2 = PDMDevHlpIOPortRegisterR0(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
    61556146                                            (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",
    61566147                                            NULL, NULL, "ATA Bus Master DMA");
     
    75057496    /*
    75067497     * Register the PCI device.
    7507      * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
    7508      *      device the slot next to itself.
    75097498     */
    7510     rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
     7499    rc = PDMDevHlpPCIRegisterEx(pDevIns, &pThis->dev, PDMPCIDEVREG_CFG_PRIMARY, PDMPCIDEVREG_F_NOT_MANDATORY_NO,
     7500                                1 /*uPciDevNo*/, 1 /*uPciDevFn*/, "piix3ide");
    75117501    if (RT_FAILURE(rc))
    7512         return PDMDEV_SET_ERROR(pDevIns, rc,
    7513                                 N_("PIIX3 cannot register PCI device"));
    7514     //AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
     7502        return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register PCI device"));
    75157503    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataR3BMDMAIORangeMap);
    75167504    if (RT_FAILURE(rc))
    7517         return PDMDEV_SET_ERROR(pDevIns, rc,
    7518                                 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
     7505        return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register PCI I/O region for BMDMA"));
    75197506
    75207507    /*
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r64274 r64373  
    27802780 * @callback_method_impl{FNPCIIOREGIONMAP}
    27812781 */
    2782 static DECLCALLBACK(int) buslogicR3MmioMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     2782static DECLCALLBACK(int) buslogicR3MmioMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
    27832783                                           RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    27842784{
    2785     RT_NOREF(iRegion);
    2786     PPDMDEVINS pDevIns = pPciDev->pDevIns;
     2785    RT_NOREF(pPciDev, iRegion);
    27872786    PBUSLOGIC  pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    27882787    int   rc = VINF_SUCCESS;
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r64274 r64373  
    39903990 * @callback_method_impl{FNPCIIOREGIONMAP}
    39913991 */
    3992 static DECLCALLBACK(int) lsilogicR3Map(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     3992static DECLCALLBACK(int) lsilogicR3Map(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
    39933993                                       RTGCPHYS GCPhysAddress, RTGCPHYS cb,
    39943994                                       PCIADDRESSSPACE enmType)
    39953995{
    3996     PPDMDEVINS pDevIns = pPciDev->pDevIns;
    3997     PLSILOGICSCSI  pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    3998     int   rc = VINF_SUCCESS;
     3996    RT_NOREF(pPciDev);
     3997    PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
     3998    int         rc = VINF_SUCCESS;
    39993999    const char *pcszCtrl = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI
    40004000                           ? "LsiLogic"
  • trunk/src/VBox/Devices/USB/DevOHCI.cpp

    r64319 r64373  
    53645364 * @callback_method_impl{FNPCIIOREGIONMAP}
    53655365 */
    5366 static DECLCALLBACK(int) ohciR3Map(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     5366static DECLCALLBACK(int) ohciR3Map(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     5367                                   RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    53675368{
    53685369    RT_NOREF(iRegion, enmType);
    53695370    POHCI pThis = (POHCI)pPciDev;
    5370     int rc = PDMDevHlpMMIORegister(pThis->CTX_SUFF(pDevIns), GCPhysAddress, cb, NULL /*pvUser*/,
     5371    int rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    53715372                                   IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED
    53725373                                   | IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_WRITE,
     
    53775378    if (pThis->fRZEnabled)
    53785379    {
    5379         rc = PDMDevHlpMMIORegisterRC(pThis->CTX_SUFF(pDevIns), GCPhysAddress, cb,
    5380                                      NIL_RTRCPTR /*pvUser*/, "ohciMmioWrite", "ohciMmioRead");
     5380        rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/, "ohciMmioWrite", "ohciMmioRead");
    53815381        if (RT_FAILURE(rc))
    53825382            return rc;
    53835383
    5384         rc = PDMDevHlpMMIORegisterR0(pThis->CTX_SUFF(pDevIns), GCPhysAddress, cb,
    5385                                      NIL_RTR0PTR /*pvUser*/, "ohciMmioWrite", "ohciMmioRead");
     5384        rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/, "ohciMmioWrite", "ohciMmioRead");
    53865385        if (RT_FAILURE(rc))
    53875386            return rc;
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r64356 r64373  
    28792879 * @callback_method_impl{FNPCIIOREGIONMAP,MMIO/MMIO2 regions}
    28802880 */
    2881 static DECLCALLBACK(int)
    2882 vmmdevIORAMRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2881static DECLCALLBACK(int) vmmdevIORAMRegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2882                                              RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    28832883{
    28842884    RT_NOREF1(cb);
     
    28982898            pThis->GCPhysVMMDevRAM = GCPhysAddress;
    28992899            Assert(pThis->GCPhysVMMDevRAM == GCPhysAddress);
    2900             rc = PDMDevHlpMMIOExMap(pPciDev->pDevIns, pPciDev, iRegion, GCPhysAddress);
     2900            rc = PDMDevHlpMMIOExMap(pDevIns, pPciDev, iRegion, GCPhysAddress);
    29012901        }
    29022902        else
     
    29202920            pThis->GCPhysVMMDevHeap = GCPhysAddress;
    29212921            Assert(pThis->GCPhysVMMDevHeap == GCPhysAddress);
    2922             rc = PDMDevHlpMMIOExMap(pPciDev->pDevIns, pPciDev, iRegion, GCPhysAddress);
     2922            rc = PDMDevHlpMMIOExMap(pDevIns, pPciDev, iRegion, GCPhysAddress);
    29232923            if (RT_SUCCESS(rc))
    2924                 rc = PDMDevHlpRegisterVMMDevHeap(pPciDev->pDevIns, GCPhysAddress, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
     2924                rc = PDMDevHlpRegisterVMMDevHeap(pDevIns, GCPhysAddress, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
    29252925        }
    29262926        else
     
    29292929             * It is about to be unmapped, just clean up.
    29302930             */
    2931             PDMDevHlpRegisterVMMDevHeap(pPciDev->pDevIns, NIL_RTGCPHYS, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
     2931            PDMDevHlpRegisterVMMDevHeap(pDevIns, NIL_RTGCPHYS, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
    29322932            pThis->GCPhysVMMDevHeap = NIL_RTGCPHYS32;
    29332933            rc = VINF_SUCCESS;
     
    29472947 * @callback_method_impl{FNPCIIOREGIONMAP,I/O Port Region}
    29482948 */
    2949 static DECLCALLBACK(int)
    2950 vmmdevIOPortRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     2949static DECLCALLBACK(int) vmmdevIOPortRegionMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     2950                                              RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    29512951{
    29522952    RT_NOREF3(iRegion, cb, enmType);
     
    29602960     * Register our port IO handlers.
    29612961     */
    2962     int rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + VMMDEV_PORT_OFF_REQUEST, 1,
     2962    int rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress + VMMDEV_PORT_OFF_REQUEST, 1,
    29632963                                     pThis, vmmdevRequestHandler, NULL, NULL, NULL, "VMMDev Request Handler");
    29642964    AssertRC(rc);
     
    41464146
    41474147    /*
    4148      * Allocate and initialize the MMIO2 memory.
    4149      */
    4150     rc = PDMDevHlpMMIO2Register(pDevIns, 1 /*iRegion*/, VMMDEV_RAM_SIZE, 0 /*fFlags*/, (void **)&pThis->pVMMDevRAMR3, "VMMDev");
    4151     if (RT_FAILURE(rc))
    4152         return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    4153                                    N_("Failed to allocate %u bytes of memory for the VMM device"), VMMDEV_RAM_SIZE);
    4154     vmmdevInitRam(pThis);
    4155 
    4156     if (pThis->fHeapEnabled)
    4157     {
    4158         rc = PDMDevHlpMMIO2Register(pDevIns, 2 /*iRegion*/, VMMDEV_HEAP_SIZE, 0 /*fFlags*/, (void **)&pThis->pVMMDevHeapR3, "VMMDev Heap");
    4159         if (RT_FAILURE(rc))
    4160             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    4161                                        N_("Failed to allocate %u bytes of memory for the VMM device heap"), PAGE_SIZE);
    4162 
    4163         /* Register the memory area with PDM so HM can access it before it's mapped. */
    4164         rc = PDMDevHlpRegisterVMMDevHeap(pDevIns, NIL_RTGCPHYS, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
    4165         AssertLogRelRCReturn(rc, rc);
    4166     }
    4167 
    4168     /*
    41694148     * Register the PCI device.
    41704149     */
     
    41854164        if (RT_FAILURE(rc))
    41864165            return rc;
     4166    }
     4167
     4168    /*
     4169     * Allocate and initialize the MMIO2 memory.
     4170     */
     4171    rc = PDMDevHlpMMIO2Register(pDevIns, &pThis->PciDev, 1 /*iRegion*/, VMMDEV_RAM_SIZE, 0 /*fFlags*/,
     4172                                (void **)&pThis->pVMMDevRAMR3, "VMMDev");
     4173    if (RT_FAILURE(rc))
     4174        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     4175                                   N_("Failed to allocate %u bytes of memory for the VMM device"), VMMDEV_RAM_SIZE);
     4176    vmmdevInitRam(pThis);
     4177
     4178    if (pThis->fHeapEnabled)
     4179    {
     4180        rc = PDMDevHlpMMIO2Register(pDevIns, &pThis->PciDev, 2 /*iRegion*/, VMMDEV_HEAP_SIZE, 0 /*fFlags*/,
     4181                                    (void **)&pThis->pVMMDevHeapR3, "VMMDev Heap");
     4182        if (RT_FAILURE(rc))
     4183            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     4184                                       N_("Failed to allocate %u bytes of memory for the VMM device heap"), PAGE_SIZE);
     4185
     4186        /* Register the memory area with PDM so HM can access it before it's mapped. */
     4187        rc = PDMDevHlpRegisterVMMDevHeap(pDevIns, NIL_RTGCPHYS, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
     4188        AssertLogRelRCReturn(rc, rc);
    41874189    }
    41884190
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r64351 r64373  
    148148
    149149    /* DevPCI.cpp */
    150     GEN_CHECK_SIZE(PCIDEVICE);
    151     GEN_CHECK_SIZE(PCIDEVICEINT);
     150    GEN_CHECK_SIZE(PDMPCIDEV);
     151    GEN_CHECK_SIZE(PDMPCIDEVICEINT);
    152152    GEN_CHECK_SIZE(PCIIOREGION);
    153153    GEN_CHECK_OFF(PCIDEVICE, config);
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r62478 r64373  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_PDM_DEVICE
     23#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    2324#include "PDMInternal.h"
    2425#include <VBox/vmm/pdm.h>
     
    6869
    6970/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
    70 static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    71 {
    72     PDMDEV_ASSERT_DEVINS(pDevIns);
     71static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, RTGCPHYS GCPhys,
     72                                                 void *pvBuf, size_t cbRead)
     73{
     74    PDMDEV_ASSERT_DEVINS(pDevIns);
     75    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     76        pPciDev = pDevIns->Internal.s.pHeadPciDevR0;
     77    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    7378
    7479#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     
    7681     * Just check the busmaster setting here and forward the request to the generic read helper.
    7782     */
    78     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR0;
    79     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    80 
    81     if (!PCIDevIsBusmaster(pPciDev))
     83    if (PCIDevIsBusmaster(pPciDev))
     84    { /* likely */ }
     85    else
    8286    {
    8387        Log(("pdmRCDevHlp_PCIPhysRead: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
     
    9296
    9397/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysWrite} */
    94 static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    95 {
    96     PDMDEV_ASSERT_DEVINS(pDevIns);
     98static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, RTGCPHYS GCPhys,
     99                                                  const void *pvBuf, size_t cbWrite)
     100{
     101    PDMDEV_ASSERT_DEVINS(pDevIns);
     102    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     103        pPciDev = pDevIns->Internal.s.pHeadPciDevR0;
     104    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    97105
    98106#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     
    100108     * Just check the busmaster setting here and forward the request to the generic read helper.
    101109     */
    102     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR0;
    103     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    104 
    105     if (!PCIDevIsBusmaster(pPciDev))
     110    if (PCIDevIsBusmaster(pPciDev))
     111    { /* likely */ }
     112    else
    106113    {
    107114        Log(("pdmRCDevHlp_PCIPhysWrite: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
     
    116123
    117124/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
    118 static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    119 {
    120     PDMDEV_ASSERT_DEVINS(pDevIns);
    121     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     125static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
     126{
     127    PDMDEV_ASSERT_DEVINS(pDevIns);
     128    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     129        pPciDev = pDevIns->Internal.s.pHeadPciDevR0;
     130    AssertReturnVoid(pPciDev);
     131    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
     132             pDevIns, pDevIns->iInstance, pPciDev, pPciDev->devfn, iIrq, iLevel));
    122133    PVM          pVM     = pDevIns->Internal.s.pVMR0;
    123     PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
    124     PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
     134    PPDMPCIBUS   pPciBus = pPciDev->Int.s.pPdmBusR0;
    125135
    126136    pdmLock(pVM);
     
    137147        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
    138148
    139     if (    pPciDev
    140         &&  pPciBus
     149    if (    pPciBus
    141150        &&  pPciBus->pDevInsR0)
    142151    {
     
    158167        pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
    159168        pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
    160         pTask->u.SetIRQ.iIrq = iIrq;
    161         pTask->u.SetIRQ.iLevel = iLevel;
    162         pTask->u.SetIRQ.uTagSrc = uTagSrc;
     169        pTask->u.PciSetIRQ.iIrq = iIrq;
     170        pTask->u.PciSetIRQ.iLevel = iLevel;
     171        pTask->u.PciSetIRQ.uTagSrc = uTagSrc;
     172        pTask->u.PciSetIRQ.pPciDevR3 = MMHyperR0ToR3(pVM, pPciDev);
    163173
    164174        PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
     
    410420    pdmR0DevHlp_TMTimeVirtGetNano,
    411421    pdmR0DevHlp_DBGFTraceBuf,
     422    NULL,
     423    NULL,
     424    NULL,
     425    NULL,
     426    NULL,
     427    NULL,
     428    NULL,
     429    NULL,
     430    NULL,
     431    NULL,
    412432    PDM_DEVHLPR0_VERSION
    413433};
     
    787807            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
    788808            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    789             pTask->u.SetIRQ.iIrq = iIrq;
    790             pTask->u.SetIRQ.iLevel = iLevel;
    791             pTask->u.SetIRQ.uTagSrc = uTagSrc;
     809            pTask->u.IoApicSetIRQ.iIrq = iIrq;
     810            pTask->u.IoApicSetIRQ.iLevel = iLevel;
     811            pTask->u.IoApicSetIRQ.uTagSrc = uTagSrc;
    792812
    793813            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
     
    10231043    pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
    10241044    pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    1025     pTask->u.SetIRQ.iIrq = iIrq;
    1026     pTask->u.SetIRQ.iLevel = iLevel;
    1027     pTask->u.SetIRQ.uTagSrc = uTagSrc;
     1045    pTask->u.IsaSetIRQ.iIrq = iIrq;
     1046    pTask->u.IsaSetIRQ.iLevel = iLevel;
     1047    pTask->u.IsaSetIRQ.uTagSrc = uTagSrc;
    10281048
    10291049    PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r64119 r64373  
    16621662 * @param   pVM                 Pointer to the cross context VM structure.
    16631663 * @param   pDevIns             The device.
     1664 * @param   iSubDev             The sub-device number.
    16641665 * @param   iRegion             The region number.
    16651666 * @param   cbRegion            The size of the MMIO region.  Must be a multiple
     
    16831684 * @param   pfnFillCallbackRC   Callback for handling fills, RC. Optional.
    16841685 */
    1685 VMMR3_INT_DECL(int)  IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion,
     1686VMMR3_INT_DECL(int)  IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRegion,
    16861687                                            uint32_t fFlags, const char *pszDesc,
    16871688                                            RTR3PTR pvUserR3,
     
    16981699                                            RCPTRTYPE(PFNIOMMMIOFILL)  pfnFillCallbackRC)
    16991700{
    1700     LogFlow(("IOMR3MmioExPreRegister: pDevIns=%p iRegion=%u cbRegion=%RGp fFlags=%#x pszDesc=%s\n"
     1701    LogFlow(("IOMR3MmioExPreRegister: pDevIns=%p iSubDev=%u iRegion=%u cbRegion=%RGp fFlags=%#x pszDesc=%s\n"
    17011702             "                        pvUserR3=%RHv pfnWriteCallbackR3=%RHv pfnReadCallbackR3=%RHv pfnFillCallbackR3=%RHv\n"
    17021703             "                        pvUserR0=%RHv pfnWriteCallbackR0=%RHv pfnReadCallbackR0=%RHv pfnFillCallbackR0=%RHv\n"
    17031704             "                        pvUserRC=%RRv pfnWriteCallbackRC=%RRv pfnReadCallbackRC=%RRv pfnFillCallbackRC=%RRv\n",
    1704              pDevIns, iRegion, cbRegion, fFlags, pszDesc,
     1705             pDevIns, iSubDev, iRegion, cbRegion, fFlags, pszDesc,
    17051706             pvUserR3, pfnWriteCallbackR3, pfnReadCallbackR3, pfnFillCallbackR3,
    17061707             pvUserR0, pfnWriteCallbackR0, pfnReadCallbackR0, pfnFillCallbackR0,
     
    17631764         * and out of the guest address space, and once it's destroyed.
    17641765         */
    1765         rc = PGMR3PhysMMIOExPreRegister(pVM, pDevIns, iRegion, cbRegion, pVM->iom.s.hMmioHandlerType,
     1766        rc = PGMR3PhysMMIOExPreRegister(pVM, pDevIns, iSubDev, iRegion, cbRegion, pVM->iom.s.hMmioHandlerType,
    17661767                                        pRange, MMHyperR3ToR0(pVM, pRange), MMHyperR3ToRC(pVM, pRange), pszDesc);
    17671768        if (RT_SUCCESS(rc))
  • trunk/src/VBox/VMM/VMMR3/MMHyper.cpp

    r62478 r64373  
    277277                {
    278278                    RTHCPHYS HCPhys;
    279                     rc = PGMR3PhysMMIO2GetHCPhys(pVM, pLookup->u.MMIO2.pDevIns, pLookup->u.MMIO2.iRegion, offCur, &HCPhys);
     279                    rc = PGMR3PhysMMIO2GetHCPhys(pVM, pLookup->u.MMIO2.pDevIns, pLookup->u.MMIO2.iSubDev,
     280                                                 pLookup->u.MMIO2.iRegion, offCur, &HCPhys);
    280281                    if (RT_FAILURE(rc))
    281282                        break;
     
    524525 *
    525526 * Callers of this API must never deregister the MMIO2 region before the
    526  * VM is powered off. If this becomes a requirement MMR3HyperUnmapMMIO2
     527 * VM is powered off.  If this becomes a requirement MMR3HyperUnmapMMIO2
    527528 * API will be needed to perform cleanups.
    528529 *
     
    531532 * @param   pVM         The cross context VM structure.
    532533 * @param   pDevIns     The device owning the MMIO2 memory.
     534 * @param   iSubDev     The sub-device number.
    533535 * @param   iRegion     The region.
    534536 * @param   off         The offset into the region. Will be rounded down to closest page boundary.
     
    537539 * @param   pRCPtr      Where to store the RC address.
    538540 */
    539 VMMR3DECL(int) MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
     541VMMR3DECL(int) MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    540542                                const char *pszDesc, PRTRCPTR pRCPtr)
    541543{
    542     LogFlow(("MMR3HyperMapMMIO2: pDevIns=%p iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
    543              pDevIns, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
     544    LogFlow(("MMR3HyperMapMMIO2: pDevIns=%p iSubDev=%#x iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
     545             pDevIns, iSubDev, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
    544546    int rc;
    545547
     
    558560    {
    559561        RTHCPHYS HCPhys;
    560         rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iRegion, offCur, &HCPhys);
    561         AssertMsgRCReturn(rc, ("rc=%Rrc - iRegion=%d off=%RGp\n", rc, iRegion, off), rc);
     562        rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iSubDev, iRegion, offCur, &HCPhys);
     563        AssertMsgRCReturn(rc, ("rc=%Rrc - iSubDev=%#x iRegion=%#x off=%RGp\n", rc, iSubDev, iRegion, off), rc);
    562564    }
    563565
     
    572574        pLookup->enmType = MMLOOKUPHYPERTYPE_MMIO2;
    573575        pLookup->u.MMIO2.pDevIns = pDevIns;
     576        pLookup->u.MMIO2.iSubDev = iSubDev;
    574577        pLookup->u.MMIO2.iRegion = iRegion;
    575578        pLookup->u.MMIO2.off = off;
     
    583586            {
    584587                RTHCPHYS HCPhys;
    585                 rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iRegion, offCur, &HCPhys);
     588                rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iSubDev, iRegion, offCur, &HCPhys);
    586589                AssertRCReturn(rc, rc);
    587590                rc = PGMMap(pVM, GCPtr + (offCur - off), HCPhys, PAGE_SIZE, 0);
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r64115 r64373  
    254254*********************************************************************************************************************************/
    255255#define LOG_GROUP LOG_GROUP_PDM
     256#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    256257#include "PDMInternal.h"
    257258#include <VBox/vmm/pdm.h>
     
    573574                pDevIns->pCritSectRoRC  = MMHyperR3ToRC(pVM, pDevIns->pCritSectRoR3);
    574575            pDevIns->Internal.s.pVMRC   = pVM->pVMRC;
    575             if (pDevIns->Internal.s.pPciBusR3)
    576                 pDevIns->Internal.s.pPciBusRC    = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3);
    577             if (pDevIns->Internal.s.pPciDeviceR3)
    578                 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciDeviceR3);
     576
     577            PPDMPCIDEV pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     578            if (pPciDev)
     579            {
     580                pDevIns->Internal.s.pHeadPciDevRC = MMHyperR3ToRC(pVM, pPciDev);
     581                do
     582                {
     583                    pPciDev->Int.s.pDevInsRC = MMHyperR3ToRC(pVM, pPciDev->Int.s.pDevInsR3);
     584                    pPciDev->Int.s.pPdmBusRC = MMHyperR3ToRC(pVM, pPciDev->Int.s.pPdmBusR3);
     585                    if (pPciDev->Int.s.pNextR3)
     586                        pPciDev->Int.s.pNextRC = MMHyperR3ToRC(pVM, pPciDev->Int.s.pNextR3);
     587                    pPciDev = pPciDev->Int.s.pNextR3;
     588                } while (pPciDev);
     589            }
     590
    579591            if (pDevIns->pReg->pfnRelocate)
    580592            {
     
    739751        pdmR3ThreadDestroyDevice(pVM, pDevIns);
    740752        PDMR3QueueDestroyDevice(pVM, pDevIns);
    741         PGMR3PhysMMIOExDeregister(pVM, pDevIns, UINT32_MAX);
     753        PGMR3PhysMMIOExDeregister(pVM, pDevIns, UINT32_MAX, UINT32_MAX);
    742754#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
    743755        pdmR3AsyncCompletionTemplateDestroyDevice(pVM, pDevIns);
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r64353 r64373  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_PDM_DEVICE
     23#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    2324#include "PDMInternal.h"
    2425#include <VBox/vmm/pdm.h>
     
    427428 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
    428429 */
    429 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
     430static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS cb,
     431                                                   uint32_t fFlags, void **ppv, const char *pszDesc)
    430432{
    431433    PDMDEV_ASSERT_DEVINS(pDevIns);
    432434    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    433     LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=%#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",
    434              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc));
     435    LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: pPciDev=%p (%#x) iRegion=%#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",
     436             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion,
     437             cb, fFlags, ppv, pszDesc, pszDesc));
     438    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
    435439
    436440/** @todo PGMR3PhysMMIO2Register mangles the description, move it here and
    437441 *        use a real string cache. */
    438     int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
     442    int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion,
     443                                    cb, fFlags, ppv, pszDesc);
    439444
    440445    LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     
    465470             pvUserR0, pszWriteR0, pszReadR0, pszFillR0,
    466471             pvUserRC, pszWriteRC, pszReadRC, pszFillRC));
    467     NOREF(pPciDev);
     472    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
    468473
    469474    /*
     
    524529     * Call IOM to make the registration.
    525530     */
    526     rc = IOMR3MmioExPreRegister(pVM, pDevIns, iRegion, cbRegion, fFlags, pszDesc,
     531    rc = IOMR3MmioExPreRegister(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, cbRegion, fFlags, pszDesc,
    527532                                pvUser,   pfnWrite,   pfnRead,   pfnFill,
    528533                                pvUserR0, pfnWriteR0, pfnReadR0, pfnFillR0,
     
    537542 * @copydoc PDMDEVHLPR3::pfnMMIOExDeregister
    538543 */
    539 static DECLCALLBACK(int) pdmR3DevHlp_MMIOExDeregister(PPDMDEVINS pDevIns, uint32_t iRegion)
     544static DECLCALLBACK(int) pdmR3DevHlp_MMIOExDeregister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion)
    540545{
    541546    PDMDEV_ASSERT_DEVINS(pDevIns);
    542547    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    543     LogFlow(("pdmR3DevHlp_MMIOExDeregister: caller='%s'/%d: iRegion=%#x\n",
    544              pDevIns->pReg->szName, pDevIns->iInstance, iRegion));
     548    LogFlow(("pdmR3DevHlp_MMIOExDeregister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x\n",
     549             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion));
    545550
    546551    AssertReturn(iRegion <= UINT8_MAX || iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);
    547 
    548     int rc = PGMR3PhysMMIOExDeregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion);
     552    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
     553
     554    int rc = PGMR3PhysMMIOExDeregister(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion);
    549555
    550556    LogFlow(("pdmR3DevHlp_MMIOExDeregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     
    556562 * @copydoc PDMDEVHLPR3::pfnMMIOExMap
    557563 */
    558 static DECLCALLBACK(int) pdmR3DevHlp_MMIOExMap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
     564static DECLCALLBACK(int) pdmR3DevHlp_MMIOExMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
    559565{
    560566    PDMDEV_ASSERT_DEVINS(pDevIns);
    561567    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    562     LogFlow(("pdmR3DevHlp_MMIOExMap: caller='%s'/%d: iRegion=%#x GCPhys=%#RGp\n",
    563              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, GCPhys));
    564 
    565     int rc = PGMR3PhysMMIOExMap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);
     568    LogFlow(("pdmR3DevHlp_MMIOExMap: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x GCPhys=%#RGp\n",
     569             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion, GCPhys));
     570    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 != NULL, VERR_INVALID_PARAMETER);
     571
     572    int rc = PGMR3PhysMMIOExMap(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, GCPhys);
    566573
    567574    LogFlow(("pdmR3DevHlp_MMIOExMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     
    573580 * @copydoc PDMDEVHLPR3::pfnMMIOExUnmap
    574581 */
    575 static DECLCALLBACK(int) pdmR3DevHlp_MMIOExUnmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
     582static DECLCALLBACK(int) pdmR3DevHlp_MMIOExUnmap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
    576583{
    577584    PDMDEV_ASSERT_DEVINS(pDevIns);
    578585    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    579     LogFlow(("pdmR3DevHlp_MMIOExUnmap: caller='%s'/%d: iRegion=%#x GCPhys=%#RGp\n",
    580              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, GCPhys));
    581 
    582     int rc = PGMR3PhysMMIOExUnmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);
     586    LogFlow(("pdmR3DevHlp_MMIOExUnmap: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x GCPhys=%#RGp\n",
     587             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion, GCPhys));
     588    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 != NULL, VERR_INVALID_PARAMETER);
     589
     590    int rc = PGMR3PhysMMIOExUnmap(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, GCPhys);
    583591
    584592    LogFlow(("pdmR3DevHlp_MMIOExUnmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     
    590598 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
    591599 */
    592 static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    593                                                      const char *pszDesc, PRTRCPTR pRCPtr)
    594 {
    595     PDMDEV_ASSERT_DEVINS(pDevIns);
    596     PVM pVM = pDevIns->Internal.s.pVMR3;
    597     VM_ASSERT_EMT(pVM);
    598     LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
    599              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
     600static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS off,
     601                                                     RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr)
     602{
     603    PDMDEV_ASSERT_DEVINS(pDevIns);
     604    PVM pVM = pDevIns->Internal.s.pVMR3;
     605    VM_ASSERT_EMT(pVM);
     606    LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
     607             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
     608    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
    600609
    601610    if (pDevIns->iInstance > 0)
     
    606615    }
    607616
    608     int rc = MMR3HyperMapMMIO2(pVM, pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
     617    int rc = MMR3HyperMapMMIO2(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, off, cb, pszDesc, pRCPtr);
    609618
    610619    LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pRCPtr));
     
    616625 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
    617626 */
    618 static DECLCALLBACK(int) pdmR3DevHlp_MMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    619                                                     const char *pszDesc, PRTR0PTR pR0Ptr)
    620 {
    621     PDMDEV_ASSERT_DEVINS(pDevIns);
    622     PVM pVM = pDevIns->Internal.s.pVMR3;
    623     VM_ASSERT_EMT(pVM);
    624     LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pR0Ptr=%p\n",
    625              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pR0Ptr));
     627static DECLCALLBACK(int) pdmR3DevHlp_MMIO2MapKernel(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion, RTGCPHYS off,
     628                                                    RTGCPHYS cb,const char *pszDesc, PRTR0PTR pR0Ptr)
     629{
     630    PDMDEV_ASSERT_DEVINS(pDevIns);
     631    PVM pVM = pDevIns->Internal.s.pVMR3;
     632    VM_ASSERT_EMT(pVM);
     633    LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pR0Ptr=%p\n",
     634             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->devfn : UINT32_MAX, iRegion, off, cb, pszDesc, pszDesc, pR0Ptr));
     635    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
    626636
    627637    if (pDevIns->iInstance > 0)
     
    632642    }
    633643
    634     int rc = PGMR3PhysMMIO2MapKernel(pVM, pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
     644    int rc = PGMR3PhysMMIO2MapKernel(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, off, cb, pszDesc, pR0Ptr);
    635645
    636646    LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: returns %Rrc *pR0Ptr=%RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pR0Ptr));
     
    12021212
    12031213
    1204 /** @interface_method_impl{PDMDEVHLPR3,pfnPCIRegister} */
    1205 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
    1206 {
    1207     PDMDEV_ASSERT_DEVINS(pDevIns);
    1208     PVM pVM = pDevIns->Internal.s.pVMR3;
    1209     VM_ASSERT_EMT(pVM);
    1210     LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Rhxs}\n",
    1211              pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->config));
     1214/**
     1215 * @interface_method_impl{PDMDEVHLPR3,pfnPCIRegister}
     1216 */
     1217static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t idxDevCfg, uint32_t fFlags,
     1218                                                 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
     1219{
     1220    PDMDEV_ASSERT_DEVINS(pDevIns);
     1221    PVM pVM = pDevIns->Internal.s.pVMR3;
     1222    VM_ASSERT_EMT(pVM);
     1223    LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Rhxs} idxDevCfg=%d fFlags=%#x uPciDevNo=%#x uPciFunNo=%#x pszName=%p:{%s}\n",
     1224             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->abConfig, idxDevCfg, fFlags, uPciDevNo, uPciFunNo, pszName, pszName ? pszName : ""));
    12121225
    12131226    /*
    12141227     * Validate input.
    12151228     */
    1216     if (!pPciDev)
    1217     {
    1218         Assert(pPciDev);
    1219         LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc (pPciDev)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    1220         return VERR_INVALID_PARAMETER;
    1221     }
    1222     if (!pPciDev->config[0] && !pPciDev->config[1])
    1223     {
    1224         Assert(pPciDev->config[0] || pPciDev->config[1]);
    1225         LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc (vendor)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    1226         return VERR_INVALID_PARAMETER;
    1227     }
    1228     if (pDevIns->Internal.s.pPciDeviceR3)
    1229     {
    1230         /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to
    1231          * support a PDM device with multiple PCI devices. This might become a problem
    1232          * when upgrading the chipset for instance because of multiple functions in some
    1233          * devices...
    1234          */
    1235         AssertMsgFailed(("Only one PCI device per device is currently implemented!\n"));
    1236         return VERR_PDM_ONE_PCI_FUNCTION_PER_DEVICE;
     1229    AssertLogRelMsgReturn(RT_VALID_PTR(pPciDev),
     1230                          ("'%s'/%d: Invalid pPciDev value: %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pPciDev),
     1231                          VERR_INVALID_POINTER);
     1232    AssertLogRelMsgReturn(PDMPciDevGetVendorId(pPciDev),
     1233                          ("'%s'/%d: Vendor ID is not set!\n", pDevIns->pReg->szName, pDevIns->iInstance),
     1234                          VERR_INVALID_POINTER);
     1235    AssertLogRelMsgReturn(idxDevCfg < 256 || idxDevCfg == PDMPCIDEVREG_CFG_NEXT,
     1236                          ("'%s'/%d: Invalid config selector: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
     1237                          VERR_OUT_OF_RANGE);
     1238    AssertLogRelMsgReturn(   uPciDevNo < 32
     1239                          || uPciDevNo == PDMPCIDEVREG_DEV_NO_FIRST_UNUSED
     1240                          || uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV,
     1241                          ("'%s'/%d: Invalid PCI device number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciDevNo),
     1242                          VERR_INVALID_PARAMETER);
     1243    AssertLogRelMsgReturn(   uPciFunNo < 8
     1244                          || uPciFunNo == PDMPCIDEVREG_FUN_NO_FIRST_UNUSED,
     1245                          ("'%s'/%d: Invalid PCI funcion number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciFunNo),
     1246                          VERR_INVALID_PARAMETER);
     1247    AssertLogRelMsgReturn(!(fFlags & ~PDMPCIDEVREG_F_VALID_MASK),
     1248                          ("'%s'/%d: Invalid flags: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, fFlags),
     1249                          VERR_INVALID_FLAGS);
     1250    if (!pszName)
     1251        pszName = pDevIns->pReg->szName;
     1252    AssertLogRelReturn(RT_VALID_PTR(pszName), VERR_INVALID_POINTER);
     1253
     1254    /*
     1255     * Find the last(/previous) registered PCI device (for linking and more),
     1256     * checking for duplicate registration attempts while doing so.
     1257     */
     1258    uint32_t idxDevCfgNext = 0;
     1259    PPDMPCIDEV pPrevPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1260    while (pPrevPciDev)
     1261    {
     1262        AssertLogRelMsgReturn(pPrevPciDev != pPciDev,
     1263                              ("'%s'/%d attempted to register the same PCI device (%p) twice\n",
     1264                               pDevIns->pReg->szName, pDevIns->iInstance, pPciDev),
     1265                              VERR_DUPLICATE);
     1266        AssertLogRelMsgReturn(pPrevPciDev->Int.s.idxDevCfg != idxDevCfg,
     1267                              ("'%s'/%d attempted to use the same device config index (%u) twice\n",
     1268                               pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
     1269                              VERR_ALREADY_LOADED);
     1270        if (pPrevPciDev->Int.s.idxDevCfg >= idxDevCfgNext)
     1271            idxDevCfgNext = pPrevPciDev->Int.s.idxDevCfg + 1;
     1272
     1273        if (!pPrevPciDev->Int.s.pNextR3)
     1274            break;
     1275        pPrevPciDev = pPrevPciDev->Int.s.pNextR3;
     1276    }
     1277
     1278    /*
     1279     * Resolve the PCI configuration node for the device.  The default (zero'th)
     1280     * is the same as the PDM device, the rest are "PciCfg1..255" CFGM sub-nodes.
     1281     */
     1282    if (idxDevCfg == PDMPCIDEVREG_CFG_NEXT)
     1283    {
     1284        idxDevCfg = idxDevCfgNext;
     1285        AssertLogRelMsgReturn(idxDevCfg < 256, ("'%s'/%d: PDMPCIDEVREG_IDX_DEV_CFG_NEXT ran out of valid indexes (ends at 255)\n",
     1286                                                pDevIns->pReg->szName, pDevIns->iInstance),
     1287                              VERR_OUT_OF_RANGE);
     1288    }
     1289
     1290    PCFGMNODE pCfg = pDevIns->Internal.s.pCfgHandle;
     1291    if (idxDevCfg != 0)
     1292        pCfg = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "PciCfg%u", idxDevCfg);
     1293
     1294    /*
     1295     * We resolve PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, the PCI bus handles
     1296     * PDMPCIDEVREG_DEV_NO_FIRST_UNUSED and PDMPCIDEVREG_FUN_NO_FIRST_UNUSED.
     1297     */
     1298    uint8_t const uPciDevNoRaw = uPciDevNo;
     1299    if (uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV)
     1300    {
     1301        AssertLogRelMsgReturn(pPrevPciDev, ("'%s'/%d: Can't use PDMPCIDEVREG_DEV_NO_SAME_AS_PREV with the first PCI device!\n",
     1302                                            pDevIns->pReg->szName, pDevIns->iInstance),
     1303                              VERR_WRONG_ORDER);
     1304        uPciDevNo = pPrevPciDev->uDevFn >> 3;
    12371305    }
    12381306
     
    12431311     * configuration value will be set. If not the default bus is 0.
    12441312     */
    1245     int rc;
    1246     PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
    1247     if (!pBus)
    1248     {
    1249         uint8_t u8Bus;
    1250         rc = CFGMR3QueryU8Def(pDevIns->Internal.s.pCfgHandle, "PCIBusNo", &u8Bus, 0);
    1251         AssertLogRelMsgRCReturn(rc, ("Configuration error: PCIBusNo query failed with rc=%Rrc (%s/%d)\n",
    1252                                      rc, pDevIns->pReg->szName, pDevIns->iInstance), rc);
    1253         AssertLogRelMsgReturn(u8Bus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
    1254                               ("Configuration error: PCIBusNo=%d, max is %d. (%s/%d)\n", u8Bus,
    1255                                RT_ELEMENTS(pVM->pdm.s.aPciBuses), pDevIns->pReg->szName, pDevIns->iInstance),
    1256                               VERR_PDM_NO_PCI_BUS);
    1257         pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[u8Bus];
    1258     }
     1313    /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIBusNo, uint8_t, 0, 7, 0}
     1314     * Selects the PCI bus number of a device.
     1315     */
     1316    uint8_t u8Bus;
     1317    int rc = CFGMR3QueryU8Def(pCfg, "PCIBusNo", &u8Bus, 0);
     1318    AssertLogRelMsgRCReturn(rc, ("Configuration error: PCIBusNo query failed with rc=%Rrc (%s/%d)\n",
     1319                                 rc, pDevIns->pReg->szName, pDevIns->iInstance), rc);
     1320    AssertLogRelMsgReturn(u8Bus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
     1321                          ("Configuration error: PCIBusNo=%d, max is %d. (%s/%d)\n", u8Bus,
     1322                           RT_ELEMENTS(pVM->pdm.s.aPciBuses), pDevIns->pReg->szName, pDevIns->iInstance),
     1323                          VERR_PDM_NO_PCI_BUS);
     1324    PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3 = &pVM->pdm.s.aPciBuses[u8Bus];
    12591325    if (pBus->pDevInsR3)
    12601326    {
    1261         if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
    1262             pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3);
    1263         else
    1264             pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR;
    1265 
    1266         if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
    1267             pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3);
    1268         else
    1269             pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR;
    1270 
    12711327        /*
    12721328         * Check the configuration for PCI device and function assignment.
    12731329         */
    1274         int iDev = -1;
    1275         uint8_t     u8Device;
    1276         rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device);
     1330        /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIDeviceNo, uint8_t, 0, 31}
     1331         * Overrides the default PCI device number of a device.
     1332         */
     1333        uint8_t uCfgDevice;
     1334        rc = CFGMR3QueryU8(pCfg, "PCIDeviceNo", &uCfgDevice);
    12771335        if (RT_SUCCESS(rc))
    12781336        {
    1279             AssertMsgReturn(u8Device <= 31,
    1280                             ("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n",
    1281                              u8Device, pDevIns->pReg->szName, pDevIns->iInstance),
     1337            AssertMsgReturn(uCfgDevice <= 31,
     1338                            ("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d/%d)\n",
     1339                             uCfgDevice, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
    12821340                            VERR_PDM_BAD_PCI_CONFIG);
    1283 
    1284             uint8_t u8Function;
    1285             rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function);
    1286             AssertMsgRCReturn(rc, ("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Rrc (%s/%d)\n",
    1287                                    rc, pDevIns->pReg->szName, pDevIns->iInstance),
    1288                               rc);
    1289             AssertMsgReturn(u8Function <= 7,
    1290                             ("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n",
    1291                              u8Function, pDevIns->pReg->szName, pDevIns->iInstance),
     1341            uPciDevNo = uCfgDevice;
     1342        }
     1343        else
     1344            AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
     1345                            ("Configuration error: PCIDeviceNo query failed with rc=%Rrc (%s/%d/%d)\n",
     1346                             rc, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
     1347                            rc);
     1348
     1349        /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIFunctionNo, uint8_t, 0, 7}
     1350         * Overrides the default PCI function number of a device.
     1351         */
     1352        uint8_t uCfgFunction;
     1353        rc = CFGMR3QueryU8(pCfg, "PCIFunctionNo", &uCfgFunction);
     1354        if (RT_SUCCESS(rc))
     1355        {
     1356            AssertMsgReturn(uCfgFunction <= 7,
     1357                            ("Configuration error: PCIFunctionNo=%#x, max is 7. (%s/%d/%d)\n",
     1358                             uCfgFunction, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
    12921359                            VERR_PDM_BAD_PCI_CONFIG);
    1293 
    1294             iDev = (u8Device << 3) | u8Function;
    1295         }
    1296         else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
    1297         {
    1298             AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Rrc (%s/%d)\n",
    1299                              rc, pDevIns->pReg->szName, pDevIns->iInstance));
    1300             return rc;
    1301         }
     1360            uPciFunNo = uCfgFunction;
     1361        }
     1362        else
     1363            AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
     1364                            ("Configuration error: PCIFunctionNo query failed with rc=%Rrc (%s/%d/%d)\n",
     1365                             rc, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
     1366                            rc);
     1367
     1368
     1369        /*
     1370         * Initialize the internal data.  We only do the wipe and the members
     1371         * owned by PDM, the PCI bus does the rest in the registration call.
     1372         */
     1373        RT_ZERO(pPciDev->Int);
     1374
     1375        pPciDev->Int.s.idxDevCfg = idxDevCfg;
     1376        pPciDev->Int.s.fReassignableDevNo = uPciDevNoRaw >= VBOX_PCI_MAX_DEVICES;
     1377        pPciDev->Int.s.fReassignableFunNo = uPciFunNo >= VBOX_PCI_MAX_FUNCTIONS;
     1378        pPciDev->Int.s.pDevInsR3 = pDevIns;
     1379        pPciDev->Int.s.pPdmBusR3 = pBus;
     1380        if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
     1381        {
     1382            pPciDev->Int.s.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
     1383            pPciDev->Int.s.pPdmBusR0 = MMHyperR3ToR0(pVM, pBus);
     1384        }
     1385        else
     1386        {
     1387            pPciDev->Int.s.pDevInsR0 = NIL_RTR0PTR;
     1388            pPciDev->Int.s.pPdmBusR0 = NIL_RTR0PTR;
     1389        }
     1390
     1391        if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
     1392        {
     1393            pPciDev->Int.s.pDevInsRC = MMHyperR3ToRC(pVM, pDevIns);
     1394            pPciDev->Int.s.pPdmBusRC = MMHyperR3ToRC(pVM, pBus);
     1395        }
     1396        else
     1397        {
     1398            pPciDev->Int.s.pDevInsRC = NIL_RTRCPTR;
     1399            pPciDev->Int.s.pPdmBusRC = NIL_RTRCPTR;
     1400        }
     1401
     1402        /* Set some of the public members too. */
     1403        pPciDev->pDevIns   = pDevIns;
     1404        pPciDev->pszNameR3 = pszName;
    13021405
    13031406        /*
     
    13051408         */
    13061409        pdmLock(pVM);
    1307         rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pReg->szName, iDev);
     1410        rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName);
    13081411        pdmUnlock(pVM);
    13091412        if (RT_SUCCESS(rc))
    13101413        {
    1311             pPciDev->pDevIns = pDevIns;
    1312 
    1313             pDevIns->Internal.s.pPciDeviceR3 = pPciDev;
    1314             if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
    1315                 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev);
     1414
     1415            /*
     1416             * Link it.
     1417             */
     1418            if (pPrevPciDev)
     1419            {
     1420                Assert(!pPrevPciDev->Int.s.pNextR3);
     1421                pPrevPciDev->Int.s.pNextR3 = pPciDev;
     1422                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
     1423                    pPrevPciDev->Int.s.pNextR0 = MMHyperR3ToR0(pVM, pPciDev);
     1424                else
     1425                    pPrevPciDev->Int.s.pNextR0 = NIL_RTR0PTR;
     1426                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
     1427                    pPrevPciDev->Int.s.pNextRC = MMHyperR3ToRC(pVM, pPciDev);
     1428                else
     1429                    pPrevPciDev->Int.s.pNextRC = NIL_RTRCPTR;
     1430            }
    13161431            else
    1317                 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR;
    1318 
    1319             if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
    1320                 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev);
    1321             else
    1322                 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR;
     1432            {
     1433                Assert(!pDevIns->Internal.s.pHeadPciDevR3);
     1434                pDevIns->Internal.s.pHeadPciDevR3 = pPciDev;
     1435                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
     1436                    pDevIns->Internal.s.pHeadPciDevR0 = MMHyperR3ToR0(pVM, pPciDev);
     1437                else
     1438                    pDevIns->Internal.s.pHeadPciDevR0 = NIL_RTR0PTR;
     1439                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
     1440                    pDevIns->Internal.s.pHeadPciDevRC = MMHyperR3ToRC(pVM, pPciDev);
     1441                else
     1442                    pDevIns->Internal.s.pHeadPciDevRC = NIL_RTRCPTR;
     1443            }
    13231444
    13241445            Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",
    1325                  pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus));
     1446                 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->uDevFn, pBus->iBus));
    13261447        }
    13271448    }
     
    13371458
    13381459
     1460/** @interface_method_impl{PDMDEVHLPR3,pfnPCIRegisterMsi} */
     1461static DECLCALLBACK(int) pdmR3DevHlp_PCIRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)
     1462{
     1463    PDMDEV_ASSERT_DEVINS(pDevIns);
     1464    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1465        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1466    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     1467    LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: pPciDev=%p:{%#x} pMsgReg=%p:{cMsiVectors=%d, cMsixVectors=%d}\n",
     1468             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->devfn, pMsiReg, pMsiReg->cMsiVectors, pMsiReg->cMsixVectors));
     1469
     1470    PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3; Assert(pBus);
     1471    PVM        pVM  = pDevIns->Internal.s.pVMR3;
     1472    pdmLock(pVM);
     1473    int rc;
     1474    if (pBus->pfnRegisterMsiR3)
     1475        rc = pBus->pfnRegisterMsiR3(pBus->pDevInsR3, pPciDev, pMsiReg);
     1476    else
     1477        rc = VERR_NOT_IMPLEMENTED;
     1478    pdmUnlock(pVM);
     1479
     1480    LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     1481    return rc;
     1482}
     1483
     1484
    13391485/** @interface_method_impl{PDMDEVHLPR3,pfnPCIIORegionRegister} */
    1340 static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, RTGCPHYS cbRegion,
    1341                                                          PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
    1342 {
    1343     PDMDEV_ASSERT_DEVINS(pDevIns);
    1344     PVM pVM = pDevIns->Internal.s.pVMR3;
    1345     VM_ASSERT_EMT(pVM);
    1346     LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%RGp enmType=%d pfnCallback=%p\n",
    1347              pDevIns->pReg->szName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback));
     1486static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     1487                                                         RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
     1488{
     1489    PDMDEV_ASSERT_DEVINS(pDevIns);
     1490    PVM pVM = pDevIns->Internal.s.pVMR3;
     1491    VM_ASSERT_EMT(pVM);
     1492    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1493        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1494    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     1495    LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%d cbRegion=%RGp enmType=%d pfnCallback=%p\n",
     1496             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->devfn, iRegion, cbRegion, enmType, pfnCallback));
    13481497
    13491498    /*
    13501499     * Validate input.
    13511500     */
    1352     if (iRegion < 0 || iRegion >= VBOX_PCI_NUM_REGIONS)
    1353     {
    1354         Assert(iRegion >= 0 && iRegion < VBOX_PCI_NUM_REGIONS);
     1501    if (iRegion >= VBOX_PCI_NUM_REGIONS)
     1502    {
     1503        Assert(iRegion < VBOX_PCI_NUM_REGIONS);
    13551504        LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (iRegion)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    13561505        return VERR_INVALID_PARAMETER;
     
    14041553
    14051554    /*
    1406      * Must have a PCI device registered!
    1407      */
    1408     int rc;
    1409     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1410     if (pPciDev)
    1411     {
    1412         /*
    1413          * We're currently restricted to page aligned MMIO regions.
    1414          */
    1415         if (   ((enmType & ~(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH)) == PCI_ADDRESS_SPACE_MEM)
    1416             && cbRegion != RT_ALIGN_64(cbRegion, PAGE_SIZE))
    1417         {
    1418             Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %RGp -> %RGp\n",
    1419                  pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, RT_ALIGN_64(cbRegion, PAGE_SIZE)));
    1420             cbRegion = RT_ALIGN_64(cbRegion, PAGE_SIZE);
    1421         }
    1422 
    1423         /*
    1424          * For registering PCI MMIO memory or PCI I/O memory, the size of the region must be a power of 2!
    1425          */
    1426         int iLastSet = ASMBitLastSetU64(cbRegion);
    1427         Assert(iLastSet > 0);
    1428         uint64_t cbRegionAligned = RT_BIT_64(iLastSet - 1);
    1429         if (cbRegion > cbRegionAligned)
    1430             cbRegion = cbRegionAligned * 2; /* round up */
    1431 
    1432         PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
    1433         Assert(pBus);
    1434         pdmLock(pVM);
    1435         rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
    1436         pdmUnlock(pVM);
    1437     }
    1438     else
    1439     {
    1440         AssertMsgFailed(("No PCI device registered!\n"));
    1441         rc = VERR_PDM_NOT_PCI_DEVICE;
    1442     }
     1555     * We're currently restricted to page aligned MMIO regions.
     1556     */
     1557    if (   ((enmType & ~(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH)) == PCI_ADDRESS_SPACE_MEM)
     1558        && cbRegion != RT_ALIGN_64(cbRegion, PAGE_SIZE))
     1559    {
     1560        Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %RGp -> %RGp\n",
     1561             pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, RT_ALIGN_64(cbRegion, PAGE_SIZE)));
     1562        cbRegion = RT_ALIGN_64(cbRegion, PAGE_SIZE);
     1563    }
     1564
     1565    /*
     1566     * For registering PCI MMIO memory or PCI I/O memory, the size of the region must be a power of 2!
     1567     */
     1568    int iLastSet = ASMBitLastSetU64(cbRegion);
     1569    Assert(iLastSet > 0);
     1570    uint64_t cbRegionAligned = RT_BIT_64(iLastSet - 1);
     1571    if (cbRegion > cbRegionAligned)
     1572        cbRegion = cbRegionAligned * 2; /* round up */
     1573
     1574    PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
     1575    Assert(pBus);
     1576    pdmLock(pVM);
     1577    int rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
     1578    pdmUnlock(pVM);
    14431579
    14441580    LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     
    14541590    PVM pVM = pDevIns->Internal.s.pVMR3;
    14551591    VM_ASSERT_EMT(pVM);
     1592    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1593        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1594    AssertReturnVoid(pPciDev);
    14561595    LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n",
    14571596             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld));
     
    14661605    AssertPtrNull(pPciDev);
    14671606
    1468     if (!pPciDev)
    1469         pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1470     AssertReleaseMsg(pPciDev, ("You must register your device first!\n"));
    1471     PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
     1607    PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
    14721608    AssertRelease(pBus);
    14731609    AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
     
    14851621
    14861622/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysRead} */
    1487 static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    1488 {
    1489     PDMDEV_ASSERT_DEVINS(pDevIns);
     1623static DECLCALLBACK(int)
     1624pdmR3DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
     1625{
     1626    PDMDEV_ASSERT_DEVINS(pDevIns);
     1627    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1628        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1629    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    14901630
    14911631#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     
    14931633     * Just check the busmaster setting here and forward the request to the generic read helper.
    14941634     */
    1495     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1496     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    1497 
    1498     if (!PCIDevIsBusmaster(pPciDev))
     1635    if (PCIDevIsBusmaster(pPciDev))
     1636    { /* likely */ }
     1637    else
    14991638    {
    15001639        Log(("pdmR3DevHlp_PCIPhysRead: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
     
    15091648
    15101649/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysWrite} */
    1511 static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    1512 {
    1513     PDMDEV_ASSERT_DEVINS(pDevIns);
     1650static DECLCALLBACK(int)
     1651pdmR3DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
     1652{
     1653    PDMDEV_ASSERT_DEVINS(pDevIns);
     1654    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1655        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1656    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    15141657
    15151658#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     
    15171660     * Just check the busmaster setting here and forward the request to the generic read helper.
    15181661     */
    1519     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1520     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    1521 
    1522     if (!PCIDevIsBusmaster(pPciDev))
     1662    if (PCIDevIsBusmaster(pPciDev))
     1663    { /* likely */ }
     1664    else
    15231665    {
    15241666        Log(("pdmR3DevHlp_PCIPhysWrite: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
     
    15331675
    15341676/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrq} */
    1535 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    1536 {
    1537     PDMDEV_ASSERT_DEVINS(pDevIns);
    1538     LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
     1677static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
     1678{
     1679    PDMDEV_ASSERT_DEVINS(pDevIns);
     1680    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1681        pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
     1682    AssertReturnVoid(pPciDev);
     1683    LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
     1684             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->devfn, iIrq, iLevel));
    15391685
    15401686    /*
     
    15471693     * Must have a PCI device registered!
    15481694     */
    1549     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1550     if (pPciDev)
    1551     {
    1552         PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */
    1553         Assert(pBus);
    1554         PVM pVM = pDevIns->Internal.s.pVMR3;
    1555 
    1556         pdmLock(pVM);
    1557         uint32_t uTagSrc;
    1558         if (iLevel & PDM_IRQ_LEVEL_HIGH)
    1559         {
    1560             pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
    1561             if (iLevel == PDM_IRQ_LEVEL_HIGH)
    1562                 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    1563             else
    1564                 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    1565         }
     1695    PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
     1696    Assert(pBus);
     1697    PVM pVM = pDevIns->Internal.s.pVMR3;
     1698
     1699    pdmLock(pVM);
     1700    uint32_t uTagSrc;
     1701    if (iLevel & PDM_IRQ_LEVEL_HIGH)
     1702    {
     1703        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
     1704        if (iLevel == PDM_IRQ_LEVEL_HIGH)
     1705            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    15661706        else
    1567             uTagSrc = pDevIns->Internal.s.uLastIrqTag;
    1568 
    1569         pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
    1570 
    1571         if (iLevel == PDM_IRQ_LEVEL_LOW)
    1572             VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    1573         pdmUnlock(pVM);
    1574     }
    1575     else
    1576         AssertReleaseMsgFailed(("No PCI device registered!\n"));
     1707            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     1708    }
     1709    else
     1710        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
     1711
     1712    pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
     1713
     1714    if (iLevel == PDM_IRQ_LEVEL_LOW)
     1715        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     1716    pdmUnlock(pVM);
    15771717
    15781718    LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
     
    15811721
    15821722/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrqNoWait} */
    1583 static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    1584 {
    1585     pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel);
    1586 }
    1587 
    1588 
    1589 /** @interface_method_impl{PDMDEVHLPR3,pfnPCIRegisterMsi} */
    1590 static DECLCALLBACK(int) pdmR3DevHlp_PCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
    1591 {
    1592     PDMDEV_ASSERT_DEVINS(pDevIns);
    1593     LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: %d MSI vectors %d MSI-X vectors\n", pDevIns->pReg->szName, pDevIns->iInstance, pMsiReg->cMsiVectors,pMsiReg->cMsixVectors ));
    1594     int rc = VINF_SUCCESS;
    1595 
    1596     /*
    1597      * Must have a PCI device registered!
    1598      */
    1599     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
    1600     if (pPciDev)
    1601     {
    1602         PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */
    1603         Assert(pBus);
    1604 
    1605         PVM pVM = pDevIns->Internal.s.pVMR3;
    1606         pdmLock(pVM);
    1607         if (pBus->pfnRegisterMsiR3)
    1608             rc = pBus->pfnRegisterMsiR3(pBus->pDevInsR3, pPciDev, pMsiReg);
    1609         else
    1610             rc = VERR_NOT_IMPLEMENTED;
    1611         pdmUnlock(pVM);
    1612     }
    1613     else
    1614         AssertReleaseMsgFailed(("No PCI device registered!\n"));
    1615 
    1616     LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
    1617     return rc;
    1618 }
     1723static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
     1724{
     1725    pdmR3DevHlp_PCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
     1726}
     1727
    16191728
    16201729/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrq} */
     
    37143823    pdmR3DevHlp_MMIODeregister,
    37153824    pdmR3DevHlp_MMIO2Register,
     3825    pdmR3DevHlp_MMIOExPreRegister,
    37163826    pdmR3DevHlp_MMIOExDeregister,
    37173827    pdmR3DevHlp_MMIOExMap,
     
    37923902    pdmR3DevHlp_VMGetSuspendReason,
    37933903    pdmR3DevHlp_VMGetResumeReason,
    3794     pdmR3DevHlp_MMIOExPreRegister,
     3904    0,
     3905    0,
     3906    0,
     3907    0,
    37953908    0,
    37963909    0,
     
    39674080    pdmR3DevHlp_MMIODeregister,
    39684081    pdmR3DevHlp_MMIO2Register,
     4082    pdmR3DevHlp_MMIOExPreRegister,
    39694083    pdmR3DevHlp_MMIOExDeregister,
    39704084    pdmR3DevHlp_MMIOExMap,
     
    40454159    pdmR3DevHlp_VMGetSuspendReason,
    40464160    pdmR3DevHlp_VMGetResumeReason,
    4047     pdmR3DevHlp_MMIOExPreRegister,
     4161    0,
     4162    0,
     4163    0,
     4164    0,
    40484165    0,
    40494166    0,
     
    40894206    {
    40904207        case PDMDEVHLPTASKOP_ISA_SET_IRQ:
    4091             PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
     4208            PDMIsaSetIrq(pVM, pTask->u.IsaSetIRQ.iIrq, pTask->u.IsaSetIRQ.iLevel, pTask->u.IsaSetIRQ.uTagSrc);
    40924209            break;
    40934210
     
    40954212        {
    40964213            /* Same as pdmR3DevHlp_PCISetIrq, except we've got a tag already. */
    4097             PPDMDEVINS pDevIns = pTask->pDevInsR3;
    4098             PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
     4214            PPCIDEVICE pPciDev = pTask->u.PciSetIRQ.pPciDevR3;
    40994215            if (pPciDev)
    41004216            {
    4101                 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */
     4217                PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
    41024218                Assert(pBus);
    41034219
    41044220                pdmLock(pVM);
    4105                 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.SetIRQ.iIrq,
    4106                                   pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
     4221                pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.PciSetIRQ.iIrq,
     4222                                  pTask->u.PciSetIRQ.iLevel, pTask->u.PciSetIRQ.uTagSrc);
    41074223                pdmUnlock(pVM);
    41084224            }
     
    41134229
    41144230        case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
    4115             PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
     4231            PDMIoApicSetIrq(pVM, pTask->u.IoApicSetIRQ.iIrq, pTask->u.IoApicSetIRQ.iLevel, pTask->u.IoApicSetIRQ.uTagSrc);
    41164232            break;
    41174233
  • trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp

    r62643 r64373  
    332332        //pDevIns->Internal.s.pLunsR3             = NULL;
    333333        pDevIns->Internal.s.pCfgHandle          = paDevs[i].pNode;
    334         //pDevIns->Internal.s.pPciDeviceR3        = NULL;
    335         //pDevIns->Internal.s.pPciBusR3           = NULL;
    336         //pDevIns->Internal.s.pPciDeviceR0        = 0;
    337         //pDevIns->Internal.s.pPciBusR0           = 0;
    338         //pDevIns->Internal.s.pPciDeviceRC        = 0;
    339         //pDevIns->Internal.s.pPciBusRC           = 0;
     334        //pDevIns->Internal.s.pHeadPciDevR3       = NULL;
     335        //pDevIns->Internal.s.pHeadPciDevR0       = 0;
     336        //pDevIns->Internal.s.pHeadPciDevRC       = 0;
    340337        pDevIns->Internal.s.fIntFlags           = PDMDEVINSINT_FLAGS_SUSPENDED;
    341338        //pDevIns->Internal.s.uLastIrqTag         = 0;
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r64327 r64373  
    24422442 * @param   pVM             The cross context VM structure.
    24432443 * @param   pDevIns         The device instance owning the region.
     2444 * @param   iSubDev         The sub-device number.
    24442445 * @param   iRegion         The region.
    24452446 */
    2446 DECLINLINE(PPGMREGMMIORANGE) pgmR3PhysMMIOExFind(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion)
     2447DECLINLINE(PPGMREGMMIORANGE) pgmR3PhysMMIOExFind(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion)
    24472448{
    24482449    /*
    24492450     * Search the list.  There shouldn't be many entries.
    24502451     */
     2452    /** @todo Optimize this lookup! There may now be many entries and it'll
     2453     *        become really slow when doing MMR3HyperMapMMIO2 and similar. */
    24512454    for (PPGMREGMMIORANGE pCur = pVM->pgm.s.pRegMmioRangesR3; pCur; pCur = pCur->pNextR3)
    24522455        if (   pCur->pDevInsR3 == pDevIns
    2453             && pCur->iRegion == iRegion)
     2456            && pCur->iRegion == iRegion
     2457            && pCur->iSubDev == iSubDev)
    24542458            return pCur;
    24552459    return NULL;
     
    25532557 * @param   pVM             The cross context VM structure.
    25542558 * @param   pDevIns         The device instance owning the region.
     2559 * @param   iSubDev         The sub-device number (internal PCI config number).
    25552560 * @param   iRegion         The region number.  If the MMIO2 memory is a PCI
    25562561 *                          I/O region this number has to be the number of that
     
    25642569 * @thread  EMT
    25652570 */
    2566 static int pgmR3PhysMMIOExCreate(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, const char *pszDesc,
    2567                                  PPGMREGMMIORANGE *ppHeadRet)
     2571static int pgmR3PhysMMIOExCreate(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cb,
     2572                                 const char *pszDesc, PPGMREGMMIORANGE *ppHeadRet)
    25682573{
    25692574    /*
     
    26842689        if (iChunk + 1 == cChunks)
    26852690            pNew->fFlags |= PGMREGMMIORANGE_F_LAST_CHUNK;
     2691        pNew->iSubDev               = iSubDev;
    26862692        pNew->iRegion               = iRegion;
    26872693        pNew->idSavedState          = UINT8_MAX;
     
    27502756        Assert(pLast->pNextR3);
    27512757        Assert(pLast->pNextR3->pDevInsR3 == pNew->pDevInsR3);
     2758        Assert(pLast->pNextR3->iSubDev   == pNew->iSubDev);
    27522759        Assert(pLast->pNextR3->iRegion   == pNew->iRegion);
    27532760        Assert((pLast->pNextR3->fFlags & PGMREGMMIORANGE_F_MMIO2) == (pNew->fFlags & PGMREGMMIORANGE_F_MMIO2));
     
    28002807 * @param   pVM             The cross context VM structure.
    28012808 * @param   pDevIns         The device instance owning the region.
     2809 * @param   iSubDev         The sub-device number.
    28022810 * @param   iRegion         The region number.  If the MMIO2 memory is a PCI
    28032811 *                          I/O region this number has to be the number of that
     
    28162824 *          PGMR3PhysMMIOExMap, PGMR3PhysMMIOExUnmap, PGMR3PhysMMIOExDeregister.
    28172825 */
    2818 VMMR3DECL(int) PGMR3PhysMMIOExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion, PGMPHYSHANDLERTYPE hType,
    2819                                           RTR3PTR pvUserR3, RTR0PTR pvUserR0, RTRCPTR pvUserRC, const char *pszDesc)
     2826VMMR3DECL(int) PGMR3PhysMMIOExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRegion,
     2827                                          PGMPHYSHANDLERTYPE hType, RTR3PTR pvUserR3, RTR0PTR pvUserR0, RTRCPTR pvUserRC,
     2828                                          const char *pszDesc)
    28202829{
    28212830    /*
     
    28242833    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    28252834    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     2835    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    28262836    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    28272837    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    28282838    AssertReturn(*pszDesc, VERR_INVALID_PARAMETER);
    2829     AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion) == NULL, VERR_ALREADY_EXISTS);
     2839    AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion) == NULL, VERR_ALREADY_EXISTS);
    28302840    AssertReturn(!(cbRegion & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
    28312841    AssertReturn(cbRegion, VERR_INVALID_PARAMETER);
     
    28562866         */
    28572867        PPGMREGMMIORANGE pNew;
    2858         rc = pgmR3PhysMMIOExCreate(pVM, pDevIns, iRegion, cbRegion, pszDesc, &pNew);
     2868        rc = pgmR3PhysMMIOExCreate(pVM, pDevIns, iSubDev, iRegion, cbRegion, pszDesc, &pNew);
    28592869        if (RT_SUCCESS(rc))
    28602870        {
     
    29362946 * @param   pVM             The cross context VM structure.
    29372947 * @param   pDevIns         The device instance owning the region.
     2948 * @param   iSubDev         The sub-device number.
    29382949 * @param   iRegion         The region number.  If the MMIO2 memory is a PCI
    29392950 *                          I/O region this number has to be the number of that
     
    29472958 * @thread  EMT
    29482959 */
    2949 VMMR3DECL(int) PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags,
    2950                                       void **ppv, const char *pszDesc)
     2960VMMR3DECL(int) PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cb,
     2961                                      uint32_t fFlags, void **ppv, const char *pszDesc)
    29512962{
    29522963    /*
     
    29552966    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    29562967    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     2968    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    29572969    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    29582970    AssertPtrReturn(ppv, VERR_INVALID_POINTER);
    29592971    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    29602972    AssertReturn(*pszDesc, VERR_INVALID_PARAMETER);
    2961     AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion) == NULL, VERR_ALREADY_EXISTS);
     2973    AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion) == NULL, VERR_ALREADY_EXISTS);
    29622974    AssertReturn(!(cb & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
    29632975    AssertReturn(cb, VERR_INVALID_PARAMETER);
     
    30163028                 */
    30173029                PPGMREGMMIORANGE pNew;
    3018                 rc = pgmR3PhysMMIOExCreate(pVM, pDevIns, iRegion, cb, pszDesc, &pNew);
     3030                rc = pgmR3PhysMMIOExCreate(pVM, pDevIns, iSubDev, iRegion, cb, pszDesc, &pNew);
    30193031                if (RT_SUCCESS(rc))
    30203032                {
     
    30783090 * @param   pVM             The cross context VM structure.
    30793091 * @param   pDevIns         The device instance owning the region.
    3080  * @param   iRegion         The region. If it's UINT32_MAX it'll be a wildcard match.
    3081  */
    3082 VMMR3DECL(int) PGMR3PhysMMIOExDeregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion)
     3092 * @param   iSubDev         The sub-device number.  Pass UINT32_MAX for wildcard
     3093 *                          matching.
     3094 * @param   iRegion         The region.  Pass UINT32_MAX for wildcard matching.
     3095 */
     3096VMMR3DECL(int) PGMR3PhysMMIOExDeregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion)
    30833097{
    30843098    /*
     
    30873101    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    30883102    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     3103    AssertReturn(iSubDev <= UINT8_MAX || iSubDev == UINT32_MAX, VERR_INVALID_PARAMETER);
    30893104    AssertReturn(iRegion <= UINT8_MAX || iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);
    30903105
     
    31023117        if (    pCur->pDevInsR3 == pDevIns
    31033118            &&  (   iRegion == UINT32_MAX
    3104                  || pCur->iRegion == iRegion))
     3119                 || pCur->iRegion == iRegion)
     3120            &&  (   iSubDev == UINT32_MAX
     3121                 || pCur->iSubDev == iSubDev) )
    31053122        {
    31063123            cFound++;
     
    31113128            if (pCur->fFlags & PGMREGMMIORANGE_F_MAPPED)
    31123129            {
    3113                 int rc2 = PGMR3PhysMMIOExUnmap(pVM, pCur->pDevInsR3, pCur->iRegion, pCur->RamRange.GCPhys);
     3130                int rc2 = PGMR3PhysMMIOExUnmap(pVM, pCur->pDevInsR3, pCur->iSubDev, pCur->iRegion, pCur->RamRange.GCPhys);
    31143131                AssertRC(rc2);
    31153132                if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     
    32033220    pgmPhysInvalidatePageMapTLB(pVM);
    32043221    pgmUnlock(pVM);
    3205     return !cFound && iRegion != UINT32_MAX ? VERR_NOT_FOUND : rc;
     3222    return !cFound && iRegion != UINT32_MAX && iSubDev != UINT32_MAX ? VERR_NOT_FOUND : rc;
    32063223}
    32073224
     
    32183235 * @param   pVM             The cross context VM structure.
    32193236 * @param   pDevIns         The device instance owning the region.
     3237 * @param   iSubDev         The sub-device number of the registered region.
    32203238 * @param   iRegion         The index of the registered region.
    32213239 * @param   GCPhys          The guest-physical address to be remapped.
    32223240 */
    3223 VMMR3DECL(int) PGMR3PhysMMIOExMap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
     3241VMMR3DECL(int) PGMR3PhysMMIOExMap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS GCPhys)
    32243242{
    32253243    /*
     
    32313249    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    32323250    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     3251    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    32333252    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    32343253    AssertReturn(GCPhys != NIL_RTGCPHYS, VERR_INVALID_PARAMETER);
     
    32363255    AssertReturn(!(GCPhys & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
    32373256
    3238     PPGMREGMMIORANGE pFirstMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion);
     3257    PPGMREGMMIORANGE pFirstMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
    32393258    AssertReturn(pFirstMmio, VERR_NOT_FOUND);
    32403259    Assert(pFirstMmio->fFlags & PGMREGMMIORANGE_F_FIRST_CHUNK);
     
    32483267        Assert(pLastMmio->RamRange.GCPhysLast == NIL_RTGCPHYS);
    32493268        Assert(pLastMmio->pDevInsR3 == pFirstMmio->pDevInsR3);
     3269        Assert(pLastMmio->iSubDev   == pFirstMmio->iSubDev);
    32503270        Assert(pLastMmio->iRegion   == pFirstMmio->iRegion);
    32513271        cbRange += pLastMmio->RamRange.cb;
     
    35063526 * as during registration, of course.
    35073527 */
    3508 VMMR3DECL(int) PGMR3PhysMMIOExUnmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
     3528VMMR3DECL(int) PGMR3PhysMMIOExUnmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS GCPhys)
    35093529{
    35103530    /*
     
    35133533    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    35143534    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     3535    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    35153536    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    35163537    AssertReturn(GCPhys != NIL_RTGCPHYS, VERR_INVALID_PARAMETER);
     
    35183539    AssertReturn(!(GCPhys & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
    35193540
    3520     PPGMREGMMIORANGE pFirstMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion);
     3541    PPGMREGMMIORANGE pFirstMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
    35213542    AssertReturn(pFirstMmio, VERR_NOT_FOUND);
    35223543    Assert(pFirstMmio->fFlags & PGMREGMMIORANGE_F_FIRST_CHUNK);
     
    35293550        AssertReturn(pLastMmio->RamRange.GCPhys == GCPhys + cbRange, VERR_INVALID_PARAMETER);
    35303551        Assert(pLastMmio->pDevInsR3 == pFirstMmio->pDevInsR3);
     3552        Assert(pLastMmio->iSubDev   == pFirstMmio->iSubDev);
    35313553        Assert(pLastMmio->iRegion   == pFirstMmio->iRegion);
    35323554        cbRange += pLastMmio->RamRange.cb;
     
    36993721 * @param   pVM             The cross context VM structure.
    37003722 * @param   pDevIns         The owner of the memory, optional.
     3723 * @param   iSubDev         Sub-device number.
    37013724 * @param   iRegion         The region.
    37023725 * @param   off             The page expressed an offset into the MMIO2 region.
    37033726 * @param   pHCPhys         Where to store the result.
    37043727 */
    3705 VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys)
     3728VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion,
     3729                                            RTGCPHYS off, PRTHCPHYS pHCPhys)
    37063730{
    37073731    /*
     
    37103734    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    37113735    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     3736    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    37123737    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    37133738
    37143739    pgmLock(pVM);
    3715     PPGMREGMMIORANGE pCurMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion);
     3740    PPGMREGMMIORANGE pCurMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
    37163741    AssertReturn(pCurMmio, VERR_NOT_FOUND);
    37173742    AssertReturn(pCurMmio->fFlags & (PGMREGMMIORANGE_F_MMIO2 | PGMREGMMIORANGE_F_FIRST_CHUNK), VERR_WRONG_TYPE);
     
    37423767 * @param   pVM         The cross context VM structure.
    37433768 * @param   pDevIns     The device owning the MMIO2 memory.
     3769 * @param   iSubDev     The sub-device number.
    37443770 * @param   iRegion     The region.
    37453771 * @param   off         The offset into the region. Must be page aligned.
     
    37483774 * @param   pR0Ptr      Where to store the R0 address.
    37493775 */
    3750 VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
    3751                                             const char *pszDesc, PRTR0PTR pR0Ptr)
     3776VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion,
     3777                                            RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr)
    37523778{
    37533779    /*
     
    37563782    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    37573783    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     3784    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
    37583785    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
    37593786
    3760     PPGMREGMMIORANGE pFirstRegMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iRegion);
     3787    PPGMREGMMIORANGE pFirstRegMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
    37613788    AssertReturn(pFirstRegMmio, VERR_NOT_FOUND);
    37623789    AssertReturn(pFirstRegMmio->fFlags & (PGMREGMMIORANGE_F_MMIO2 | PGMREGMMIORANGE_F_FIRST_CHUNK), VERR_WRONG_TYPE);
  • trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp

    r62603 r64373  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_PDM_DEVICE
     23#define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
    2324#include "PDMInternal.h"
    2425#include <VBox/vmm/pdm.h>
     
    6566
    6667/** @interface_method_impl{PDMDEVHLPRC,pfnPCIPhysRead} */
    67 static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    68 {
    69     PDMDEV_ASSERT_DEVINS(pDevIns);
     68static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     69                                                 void *pvBuf, size_t cbRead)
     70{
     71    PDMDEV_ASSERT_DEVINS(pDevIns);
     72    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     73        pPciDev = pDevIns->Internal.s.pHeadPciDevRC;
     74    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    7075
    7176#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     
    7378     * Just check the busmaster setting here and forward the request to the generic read helper.
    7479     */
    75     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceRC;
    76     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    77 
    78     if (!PCIDevIsBusmaster(pPciDev))
     80    if (PCIDevIsBusmaster(pPciDev))
     81    { /* likely */ }
     82    else
    7983    {
    8084        Log(("pdmRCDevHlp_PCIPhysRead: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
     
    8993
    9094/** @interface_method_impl{PDMDEVHLPRC,pfnPCIPhysWrite} */
    91 static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    92 {
    93     PDMDEV_ASSERT_DEVINS(pDevIns);
    94 
     95static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     96                                                  const void *pvBuf, size_t cbWrite)
     97{
     98    PDMDEV_ASSERT_DEVINS(pDevIns);
     99    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     100        pPciDev = pDevIns->Internal.s.pHeadPciDevRC;
     101    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     102
     103#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
    95104    /*
    96105     * Just check the busmaster setting here and forward the request to the generic read helper.
    97106     */
    98     PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceRC;
    99     AssertReleaseMsg(pPciDev, ("No PCI device registered!\n"));
    100 
    101     if (!PCIDevIsBusmaster(pPciDev))
     107    if (PCIDevIsBusmaster(pPciDev))
     108    { /* likely*/ }
     109    else
    102110    {
    103111        Log(("pdmRCDevHlp_PCIPhysWrite: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
     
    105113        return VERR_PDM_NOT_PCI_BUS_MASTER;
    106114    }
     115#endif
    107116
    108117    return pDevIns->pHlpRC->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
     
    111120
    112121/** @interface_method_impl{PDMDEVHLPRC,pfnPCISetIrq} */
    113 static DECLCALLBACK(void) pdmRCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    114 {
    115     PDMDEV_ASSERT_DEVINS(pDevIns);
    116     LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     122static DECLCALLBACK(void) pdmRCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
     123{
     124    PDMDEV_ASSERT_DEVINS(pDevIns);
     125    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     126        pPciDev = pDevIns->Internal.s.pHeadPciDevRC;
     127    AssertReturnVoid(pPciDev);
     128    LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
     129             pDevIns, pDevIns->iInstance, pPciDev, pPciDev->devfn, iIrq, iLevel));
    117130
    118131    PVM         pVM     = pDevIns->Internal.s.pVMRC;
    119     PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
    120     PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
     132    PPDMPCIBUS  pPciBus = pPciDev->Int.s.pPdmBusRC;
    121133
    122134    pdmLock(pVM);
     
    154166        pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
    155167        pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
    156         pTask->u.SetIRQ.iIrq = iIrq;
    157         pTask->u.SetIRQ.iLevel = iLevel;
    158         pTask->u.SetIRQ.uTagSrc = uTagSrc;
     168        pTask->u.PciSetIRQ.iIrq = iIrq;
     169        pTask->u.PciSetIRQ.iLevel = iLevel;
     170        pTask->u.PciSetIRQ.uTagSrc = uTagSrc;
     171        pTask->u.PciSetIRQ.pPciDevR3 = MMHyperRCToR3(pVM, pPciDev);
    159172
    160173        PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
     
    392405    pdmRCDevHlp_TMTimeVirtGetNano,
    393406    pdmRCDevHlp_DBGFTraceBuf,
     407    NULL,
     408    NULL,
     409    NULL,
     410    NULL,
     411    NULL,
     412    NULL,
     413    NULL,
     414    NULL,
     415    NULL,
     416    NULL,
    394417    PDM_DEVHLPRC_VERSION
    395418};
     
    742765            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
    743766            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    744             pTask->u.SetIRQ.iIrq = iIrq;
    745             pTask->u.SetIRQ.iLevel = iLevel;
    746             pTask->u.SetIRQ.uTagSrc = uTagSrc;
     767            pTask->u.IoApicSetIRQ.iIrq = iIrq;
     768            pTask->u.IoApicSetIRQ.iLevel = iLevel;
     769            pTask->u.IoApicSetIRQ.uTagSrc = uTagSrc;
    747770
    748771            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
     
    965988    pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
    966989    pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    967     pTask->u.SetIRQ.iIrq = iIrq;
    968     pTask->u.SetIRQ.iLevel = iLevel;
    969     pTask->u.SetIRQ.uTagSrc = uTagSrc;
     990    pTask->u.IsaSetIRQ.iIrq = iIrq;
     991    pTask->u.IsaSetIRQ.iLevel = iLevel;
     992    pTask->u.IsaSetIRQ.uTagSrc = uTagSrc;
    970993
    971994    PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
  • trunk/src/VBox/VMM/include/MMInternal.h

    r63660 r64373  
    674674            /** The device instance owning the MMIO2 region. */
    675675            PPDMDEVINSR3            pDevIns;
     676            /** The sub-device number. */
     677            uint32_t                iSubDev;
    676678            /** The region number. */
    677679            uint32_t                iRegion;
     680#if HC_ARCH_BITS == 32
     681            /** Alignment padding. */
     682            uint32_t                uPadding;
     683#endif
    678684            /** The offset into the MMIO2 region. */
    679685            RTGCPHYS                off;
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r63685 r64373  
    141141    /** R3 pointer to the VM this instance was created for. */
    142142    PVMR3                           pVMR3;
    143     /** R3 pointer to associated PCI device structure. */
    144     R3PTRTYPE(struct PCIDevice *)   pPciDeviceR3;
    145     /** R3 pointer to associated PCI bus structure. */
    146     R3PTRTYPE(PPDMPCIBUS)           pPciBusR3;
     143    /** Associated PCI device list head (first is default). (R3 ptr) */
     144    R3PTRTYPE(PPDMPCIDEV)        pHeadPciDevR3;
    147145
    148146    /** R0 pointer to the VM this instance was created for. */
    149147    PVMR0                           pVMR0;
    150     /** R0 pointer to associated PCI device structure. */
    151     R0PTRTYPE(struct PCIDevice *)   pPciDeviceR0;
    152     /** R0 pointer to associated PCI bus structure. */
    153     R0PTRTYPE(PPDMPCIBUS)           pPciBusR0;
     148    /** Associated PCI device list head (first is default). (R0 ptr) */
     149    R0PTRTYPE(PPDMPCIDEV)        pHeadPciDevR0;
    154150
    155151    /** RC pointer to the VM this instance was created for. */
    156152    PVMRC                           pVMRC;
    157     /** RC pointer to associated PCI device structure. */
    158     RCPTRTYPE(struct PCIDevice *)   pPciDeviceRC;
    159     /** RC pointer to associated PCI bus structure. */
    160     RCPTRTYPE(PPDMPCIBUS)           pPciBusRC;
     153    /** Associated PCI device list head (first is default). (RC ptr) */
     154    RCPTRTYPE(PPDMPCIDEV)        pHeadPciDevRC;
    161155
    162156    /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
     
    164158    /** The last IRQ tag (for tracing it thru clearing). */
    165159    uint32_t                        uLastIrqTag;
    166     /** Size padding. */
    167     uint32_t                        u32Padding;
    168160} PDMDEVINSINT;
    169161
     
    714706    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
    715707    /** @copydoc PDMPCIBUSREG::pfnRegisterR3 */
    716     DECLR3CALLBACKMEMBER(int,       pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
     708    DECLR3CALLBACKMEMBER(int,       pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t fFlags,
     709                                                   uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
    717710    /** @copydoc PDMPCIBUSREG::pfnRegisterMsiR3 */
    718711    DECLR3CALLBACKMEMBER(int,       pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
     
    991984    {
    992985        /**
    993          * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_PCI_SET_IRQ.
     986         * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_IOAPIC_SET_IRQ.
    994987         */
    995         struct PDMDEVHLPTASKSETIRQ
     988        struct PDMDEVHLPTASKISASETIRQ
    996989        {
    997990            /** The IRQ */
     
    1001994            /** The IRQ tag and source. */
    1002995            uint32_t                uTagSrc;
    1003         } SetIRQ;
     996        } IsaSetIRQ, IoApicSetIRQ;
     997
     998        /**
     999         * PDMDEVHLPTASKOP_PCI_SET_IRQ
     1000         */
     1001        struct PDMDEVHLPTASKPCISETIRQ
     1002        {
     1003            /** Pointer to the PCI device (R3 Ptr). */
     1004            R3PTRTYPE(PPDMPCIDEV)    pPciDevR3;
     1005            /** The IRQ */
     1006            int                         iIrq;
     1007            /** The new level. */
     1008            int                         iLevel;
     1009            /** The IRQ tag and source. */
     1010            uint32_t                    uTagSrc;
     1011        } PciSetIRQ;
    10041012
    10051013        /** Expanding the structure. */
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r64327 r64373  
    17111711    /** Flags (PGMREGMMIORANGE_F_XXX). */
    17121712    uint16_t                            fFlags;
    1713     /** The PCI region number.
    1714      * @remarks This ASSUMES that nobody will ever really need to have multiple
    1715      *          PCI devices with matching MMIO region numbers on a single device. */
     1713    /** The sub device number (internal PCI config (CFGM) number). */
     1714    uint8_t                             iSubDev;
     1715    /** The PCI region number. */
    17161716    uint8_t                             iRegion;
    17171717    /** The saved state range ID. */
     
    17201720    uint8_t                             idMmio2;
    17211721    /** Alignment padding for putting the ram range on a PGMPAGE alignment boundary. */
    1722     uint8_t                             abAlignment[HC_ARCH_BITS == 32 ? 7 : 3];
     1722    uint8_t                             abAlignment[HC_ARCH_BITS == 32 ? 6 : 2];
    17231723    /** Pointer to the physical handler for MMIO. */
    17241724    R3PTRTYPE(PPGMPHYSHANDLER)          pPhysHandlerR3;
  • trunk/src/VBox/VMM/testcase/tstVMStruct.h

    r64327 r64373  
    409409    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.HCPhys.HCPhys);
    410410    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.GCPhys.GCPhys);
     411    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.MMIO2.pDevIns);
     412    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.MMIO2.iSubDev);
     413    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.MMIO2.iRegion);
     414    GEN_CHECK_OFF_DOT(MMLOOKUPHYPER, u.MMIO2.off);
    411415    GEN_CHECK_OFF(MMLOOKUPHYPER, pszDesc);
    412416
     
    495499    GEN_CHECK_OFF(PDMDEVINSINT, pPerDeviceNextR3);
    496500    GEN_CHECK_OFF(PDMDEVINSINT, pDevR3);
     501    GEN_CHECK_OFF(PDMDEVINSINT, pLunsR3);
     502    GEN_CHECK_OFF(PDMDEVINSINT, pfnAsyncNotify);
     503    GEN_CHECK_OFF(PDMDEVINSINT, pCfgHandle);
    497504    GEN_CHECK_OFF(PDMDEVINSINT, pVMR3);
    498505    GEN_CHECK_OFF(PDMDEVINSINT, pVMR0);
    499506    GEN_CHECK_OFF(PDMDEVINSINT, pVMRC);
    500     GEN_CHECK_OFF(PDMDEVINSINT, pLunsR3);
    501     GEN_CHECK_OFF(PDMDEVINSINT, pfnAsyncNotify);
    502     GEN_CHECK_OFF(PDMDEVINSINT, pCfgHandle);
    503     GEN_CHECK_OFF(PDMDEVINSINT, pPciDeviceR3);
    504     GEN_CHECK_OFF(PDMDEVINSINT, pPciDeviceR0);
    505     GEN_CHECK_OFF(PDMDEVINSINT, pPciDeviceRC);
    506     GEN_CHECK_OFF(PDMDEVINSINT, pPciBusR3);
    507     GEN_CHECK_OFF(PDMDEVINSINT, pPciBusR0);
    508     GEN_CHECK_OFF(PDMDEVINSINT, pPciBusRC);
     507    GEN_CHECK_OFF(PDMDEVINSINT, pHeadPciDevR3);
     508    GEN_CHECK_OFF(PDMDEVINSINT, pHeadPciDevR0);
     509    GEN_CHECK_OFF(PDMDEVINSINT, pHeadPciDevRC);
    509510    GEN_CHECK_OFF(PDMDEVINSINT, fIntFlags);
     511    GEN_CHECK_OFF(PDMDEVINSINT, uLastIrqTag);
    510512    GEN_CHECK_OFF(PDMDEVINS, u32Version);
    511513    GEN_CHECK_OFF(PDMDEVINS, iInstance);
     
    610612    GEN_CHECK_OFF(PDMDEVHLPTASK, enmOp);
    611613    GEN_CHECK_OFF(PDMDEVHLPTASK, u);
    612     GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.SetIRQ.iIrq);
    613     GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.SetIRQ.iLevel);
     614    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IsaSetIRQ.iIrq);
     615    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IsaSetIRQ.iLevel);
     616    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IsaSetIRQ.uTagSrc);
     617    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IoApicSetIRQ.iIrq);
     618    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IoApicSetIRQ.iLevel);
     619    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.IoApicSetIRQ.uTagSrc);
     620    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.PciSetIRQ.pPciDevR3);
     621    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.PciSetIRQ.iIrq);
     622    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.PciSetIRQ.iLevel);
     623    GEN_CHECK_OFF_DOT(PDMDEVHLPTASK, u.PciSetIRQ.uTagSrc);
    614624
    615625    GEN_CHECK_SIZE(PGM);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette