/** @file * IOM - Input / Output Monitor. */ /* * Copyright (C) 2006 InnoTek Systemberatung GmbH * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE * distribution. VirtualBox OSE is distributed in the hope that it will * be useful, but WITHOUT ANY WARRANTY of any kind. * * If you received this file as part of a commercial VirtualBox * distribution, then only the terms of your commercial VirtualBox * license agreement apply instead of the previous paragraph. */ #ifndef __VBox_iom_h__ #define __VBox_iom_h__ #include #include #include #include __BEGIN_DECLS /** @defgroup grp_iom The Input / Ouput Monitor API * @{ */ /** @def IOM_NO_PDMINS_CHECKS * Untill all devices have been fully adjusted to PDM style, the pPdmIns parameter * is not checked by IOM. */ #define IOM_NO_PDMINS_CHECKS /** * Port I/O Handler for IN operations. * * @returns VINF_SUCCESS or VINF_EM_*. * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned. * * @param pDevIns The device instance. * @param pvUser User argument. * @param uPort Port number used for the IN operation. * @param pu32 Where to store the result. * @param cb Number of bytes read. */ typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); /** Pointer to a FNIOMIOPORTIN(). */ typedef FNIOMIOPORTIN *PFNIOMIOPORTIN; /** * Port I/O Handler for string IN operations. * * @returns VINF_SUCCESS or VINF_EM_*. * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned. * * @param pDevIns The device instance. * @param pvUser User argument. * @param uPort Port number used for the IN operation. * @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). */ typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, unsigned *pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTINSTRING(). */ typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING; /** * Port I/O Handler for OUT operations. * * @returns VINF_SUCCESS or VINF_EM_*. * * @param pDevIns The device instance. * @param pvUser User argument. * @param uPort Port number used for the OUT operation. * @param u32 The value to output. * @param cb The value size in bytes. */ typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); /** Pointer to a FNIOMIOPORTOUT(). */ typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT; /** * Port I/O Handler for string OUT operations. * * @returns VINF_SUCCESS or VINF_EM_*. * * @param pDevIns The device instance. * @param pvUser User argument. * @param uPort Port number used for the OUT operation. * @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). */ typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, unsigned *pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTOUTSTRING(). */ typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING; /** * Memory mapped I/O Handler for read operations. * * @returns VBox status code. * * @param pDevIns The device instance. * @param pvUser User argument. * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to store the result. * @param cb Number of bytes read. * * @remark wonder if we could merge the IOMMMIO* and IOMPORT* callbacks... */ typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb); /** Pointer to a FNIOMMMIOREAD(). */ typedef FNIOMMMIOREAD *PFNIOMMMIOREAD; /** * Port I/O Handler for write operations. * * @returns VBox status code. * * @param pDevIns The device instance. * @param pvUser User argument. * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to fetch the result. * @param cb Number of bytes to write. * * @remark wonder if we could merge the IOMMMIO* and IOMPORT* callbacks... */ typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb); /** Pointer to a FNIOMMMIOWRITE(). */ typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE; /** * Port I/O Handler for memset operations, actually for REP STOS* instructions handling. * * @returns VBox status code. * * @param pDevIns The device instance. * @param pvUser User argument. * @param GCPhysAddr Physical address (in GC) where the write starts. * @param u32Item Byte/Word/Dword data to fill. * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes. * @param cItems Number of iterations. */ typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems); /** Pointer to a FNIOMMMIOFILL(). */ typedef FNIOMMMIOFILL *PFNIOMMMIOFILL; /** * Registers a Port IO GC handler. * * This API is called by PDM on behalf of a device. Devices must first register HC ranges * using IOMR3IOPortRegisterHC() before calling this function. * * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the port range. * @param PortStart First port number in the range. * @param cPorts Number of ports to register. * @param pvUser User argument for the callbacks. * @param pfnOutCallback Pointer to function which is gonna handle OUT operations in GC. * @param pfnInCallback Pointer to function which is gonna handle IN operations in GC. * @param pfnOutStrCallback Pointer to function which is gonna handle OUT operations in GC. * @param pfnInStrCallback Pointer to function which is gonna handle IN operations in GC. * @param pszDesc Pointer to description string. This must not be freed. */ IOMDECL(int) IOMIOPortRegisterGC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTGCPTR pvUser, GCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, GCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback, GCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, GCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc); /** * Registers a Memory Mapped I/O GC handler range. * * This API is called by PDM on behalf of a device. Devices must first register HC ranges * using IOMMR3MIORegisterHC() before calling this function. * * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the MMIO range. * @param GCPhysStart First physical address in the range. * @param cbRange The size of the range (in bytes). * @param pvUser User argument for the callbacks. * @param pfnWriteCallback Pointer to function which is gonna handle Write operations. * @param pfnReadCallback Pointer to function which is gonna handle Read operations. * @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations. * @param pszDesc Pointer to description string. This must not be freed. */ IOMDECL(int) IOMMMIORegisterGC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser, GCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, GCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, GCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc); /** * Registers a Port IO R0 handler. * * This API is called by PDM on behalf of a device. Devices must first register ring-3 ranges * using IOMR3IOPortRegisterR3() before calling this function. * * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the port range. * @param PortStart First port number in the range. * @param cPorts Number of ports to register. * @param pvUser User argument for the callbacks. * @param pfnOutCallback Pointer to function which is gonna handle OUT operations in GC. * @param pfnInCallback Pointer to function which is gonna handle IN operations in GC. * @param pfnOutStrCallback Pointer to function which is gonna handle OUT operations in GC. * @param pfnInStrCallback Pointer to function which is gonna handle IN operations in GC. * @param pszDesc Pointer to description string. This must not be freed. */ IOMDECL(int) IOMIOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser, HCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, HCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback, HCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, HCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback, const char *pszDesc); /** * Registers a Memory Mapped I/O R0 handler range. * * This API is called by PDM on behalf of a device. Devices must first register ring-3 ranges * using IOMMR3MIORegisterR3() before calling this function. * * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the MMIO range. * @param GCPhysStart First physical address in the range. * @param cbRange The size of the range (in bytes). * @param pvUser User argument for the callbacks. * @param pfnWriteCallback Pointer to function which is gonna handle Write operations. * @param pfnReadCallback Pointer to function which is gonna handle Read operations. * @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations. * @param pszDesc Pointer to description string. This must not be freed. */ IOMDECL(int) IOMMMIORegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, HCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, HCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, HCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc); /** * Reads an I/O port register. * * @returns VBox status code. * * @param pVM VM handle. * @param Port The port to read. * @param pu32Value Where to store the value read. * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. */ IOMDECL(int) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); /** * Writes to an I/O port register. * * @returns VBox status code. * * @param pVM VM handle. * @param Port The port to write to. * @param u32Value The value to write. * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. */ IOMDECL(int) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue); /** * Reads the string buffer of an I/O port register. * * @returns VBox status code. * * @param pVM VM handle. * @param Port The port to read. * @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). */ IOMDECL(int) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); /** * Writes the string buffer of an I/O port register. * * @returns VBox status code. * * @param pVM VM handle. * @param Port The port to write. * @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately). * @param pcTransfer Pointer to the number of transfer units to write, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). */ IOMDECL(int) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); /** * Flushes the IOM port & statistics lookup cache * * @param pVM The VM. */ IOMDECL(void) IOMFlushCache(PVM pVM); /** * Reads a MMIO register. * * @returns VBox status code. * * @param pVM VM handle. * @param GCPhys The physical address to read. * @param pu32Value Where to store the value read. * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. */ IOMDECL(int) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue); /** * Writes to a MMIO register. * * @returns VBox status code. * * @param pVM VM handle. * @param GCPhys The physical address to write to. * @param u32Value The value to write. * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. */ IOMDECL(int) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); /** * Checks that the operation is allowed according to the IOPL * level and I/O bitmap. * * @returns VBox status code. * If not VINF_SUCCESS a \#GP(0) was raised or an error occured. * * @param pVM VM handle. * @param pCtxCore Pointer to register frame. * @param Port The I/O port number. * @param cb The access size. */ IOMDECL(int) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb); #ifdef IN_GC /** @defgroup grp_iom_gc The IOM Guest Context API * @ingroup grp_iom * @{ */ /** * Attempts to service an IN/OUT instruction. * * The \#GP trap handler in GC will call this function if the opcode causing the * trap is a in or out type instruction. * * @returns VBox status code. * * @param pVM The virtual machine (GC pointer ofcourse). * @param pRegFrame Pointer to CPUMCTXCORE guest registers structure. * @param pCpu Disassembler CPU state. */ IOMGCDECL(int) IOMGCIOPortHandler(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); /** @} */ #endif #ifdef IN_RING3 /** @defgroup grp_iom_r3 The IOM Host Context Ring-3 API * @ingroup grp_iom * @{ */ /** * Initializes the IOM. * * @returns VBox status code. * @param pVM The VM to operate on. */ IOMR3DECL(int) IOMR3Init(PVM pVM); /** * The VM is being reset. * * @param pVM VM handle. */ IOMR3DECL(void) IOMR3Reset(PVM pVM); /** * Applies relocations to data and code managed by this * component. This function will be called at init and * whenever the VMM need to relocate it self inside the GC. * * The IOM will update the addresses used by the switcher. * * @param pVM The VM. * @param offDelta Relocation delta relative to old location. */ IOMR3DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta); /** * Terminates the IOM. * * Termination means cleaning up and freeing all resources, * the VM it self is at this point powered off or suspended. * * @returns VBox status code. * @param pVM The VM to operate on. */ IOMR3DECL(int) IOMR3Term(PVM pVM); /** * Registers a I/O port R3 handler. * * This API is called by PDM on behalf of a device. Devices must first register * ring-3 ranges before any GC and R0 ranges can be registered using IOMIOPortRegisterGC() * and IOMIOPortRegisterR0(). * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the port range. * @param PortStart First port number in the range. * @param cPorts Number of ports to register. * @param pvUser User argument for the callbacks. * @param pfnOutCallback Pointer to function which is gonna handle OUT operations in R3. * @param pfnInCallback Pointer to function which is gonna handle IN operations in R3. * @param pfnOutStringCallback Pointer to function which is gonna handle string OUT operations in R3. * @param pfnInStringCallback Pointer to function which is gonna handle string IN operations in R3. * @param pszDesc Pointer to description string. This must not be freed. */ IOMR3DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser, HCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, HCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback, HCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStringCallback, HCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStringCallback, const char *pszDesc); /** * Registers a Memory Mapped I/O R3 handler. * * This API is called by PDM on behalf of a device. Devices must register ring-3 ranges * before any GC and R0 ranges can be registered using IOMMMIORegisterGC() and IOMMMIORegisterR0(). * * @returns VBox status code. * * @param pVM VM handle. * @param pDevIns PDM device instance owning the MMIO range. * @param GCPhysStart First physical address in the range. * @param cbRange The size of the range (in bytes). * @param pvUser User argument for the callbacks. * @param pfnWriteCallback Pointer to function which is gonna handle Write operations. * @param pfnReadCallback Pointer to function which is gonna handle Read operations. * @param pfnFillCallback Pointer to function which is gonna handle Fill/memset operations. * @param pszDesc Pointer to description string. This must not be freed. */ IOMR3DECL(int) IOMR3MMIORegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser, HCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback, HCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback, HCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback, const char *pszDesc); /** * Deregisters a I/O Port range. * * The specified range must be registered using IOMR3IOPortRegister previous to * this call. The range does can be a smaller part of the range specified to * IOMR3IOPortRegister, but it can never be larger. * * This function will remove GC, R0 and R3 context port handlers for this range. * * @returns VBox status code. * * @param pVM The virtual machine. * @param pDevIns The device instance associated with the range. * @param PortStart First port number in the range. * @param cPorts Number of ports to remove starting at PortStart. */ IOMR3DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts); /** * Deregisters a Memory Mapped I/O handler range. * * Registered GC, R0, and R3 ranges are affected. * * @returns VBox status code. * * @param pVM The virtual machine. * @param pDevIns Device instance which the MMIO region is registered. * @param GCPhysStart First physical address (GC) in the range. * @param cbRange Number of bytes to deregister. * * * @remark This function mainly for PCI PnP Config and will not do * all the checks you might expect it to do. */ IOMR3DECL(int) IOMR3MMIODeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange); /** @} */ #endif /** @} */ __END_DECLS #endif