summaryrefslogtreecommitdiff
path: root/src/VBox/Main/VMMDevInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/VMMDevInterface.cpp')
-rw-r--r--src/VBox/Main/VMMDevInterface.cpp217
1 files changed, 101 insertions, 116 deletions
diff --git a/src/VBox/Main/VMMDevInterface.cpp b/src/VBox/Main/VMMDevInterface.cpp
index 9f82ffc51..7e3797afa 100644
--- a/src/VBox/Main/VMMDevInterface.cpp
+++ b/src/VBox/Main/VMMDevInterface.cpp
@@ -1,9 +1,10 @@
+/* $Id: VMMDevInterface.cpp 29404 2010-05-12 10:11:28Z vboxsync $ */
/** @file
* VirtualBox Driver Interface to VMM device.
*/
/*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -12,16 +13,13 @@
* 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.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include "VMMDev.h"
#include "ConsoleImpl.h"
#include "DisplayImpl.h"
#include "GuestImpl.h"
+#include "MouseImpl.h"
#include "Logging.h"
@@ -86,9 +84,10 @@ typedef struct DRVMAINVMMDEV
//
// constructor / destructor
//
-VMMDev::VMMDev(Console *console) : mpDrv(NULL)
+VMMDev::VMMDev(Console *console)
+ : mpDrv(NULL),
+ mParent(console)
{
- mParent = console;
int rc = RTSemEventCreate(&mCredentialsEvent);
AssertRC(rc);
#ifdef VBOX_WITH_HGCM
@@ -116,7 +115,7 @@ VMMDev::~VMMDev()
PPDMIVMMDEVPORT VMMDev::getVMMDevPort()
{
- Assert(mpDrv);
+ AssertReturn(mpDrv, NULL);
return mpDrv->pUpPort;
}
@@ -251,8 +250,12 @@ DECLCALLBACK(void) vmmdevUpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface
* Tell the console interface about the event
* so that it can notify its consumers.
*/
- pDrv->pVMMDev->getParent()->onMouseCapabilityChange(BOOL (newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE),
- BOOL (newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
+ Mouse *pMouse = pDrv->pVMMDev->getParent()->getMouse();
+ if (pMouse) /** @todo and if not? Can that actually happen? */
+ {
+ pMouse->onVMMDevCanAbsChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE));
+ pMouse->onVMMDevNeedsHostChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
+ }
}
@@ -311,18 +314,32 @@ DECLCALLBACK(void) iface_VideoAccelFlush(PPDMIVMMDEVCONNECTOR pInterface)
}
}
-DECLCALLBACK(int) vmmdevVideoModeSupported(PPDMIVMMDEVCONNECTOR pInterface, uint32_t width, uint32_t height,
+DECLCALLBACK(int) vmmdevVideoModeSupported(PPDMIVMMDEVCONNECTOR pInterface, uint32_t display, uint32_t width, uint32_t height,
uint32_t bpp, bool *fSupported)
{
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
if (!fSupported)
return VERR_INVALID_PARAMETER;
- IFramebuffer *framebuffer = pDrv->pVMMDev->getParent()->getDisplay()->getFramebuffer();
- if (framebuffer)
+#ifdef DEBUG_sunlover
+ Log(("vmmdevVideoModeSupported: [%d]: %dx%dx%d\n", display, width, height, bpp));
+#endif
+ IFramebuffer *framebuffer = NULL;
+ LONG xOrigin = 0;
+ LONG yOrigin = 0;
+ HRESULT hrc = pDrv->pVMMDev->getParent()->getDisplay()->GetFramebuffer(display, &framebuffer, &xOrigin, &yOrigin);
+ if (SUCCEEDED(hrc) && framebuffer)
+ {
framebuffer->VideoModeSupported(width, height, bpp, (BOOL*)fSupported);
+ framebuffer->Release();
+ }
else
+ {
+#ifdef DEBUG_sunlover
+ Log(("vmmdevVideoModeSupported: hrc %x, framebuffer %p!!!\n", hrc, framebuffer));
+#endif
*fSupported = true;
+ }
return VINF_SUCCESS;
}
@@ -355,6 +372,10 @@ DECLCALLBACK(int) vmmdevSetVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32
if (!cRect)
return VERR_INVALID_PARAMETER;
+#ifdef MMSEAMLESS
+ /* Forward to Display, which calls corresponding framebuffers. */
+ pDrv->pVMMDev->getParent()->getDisplay()->handleSetVisibleRegion(cRect, pRect);
+#else
IFramebuffer *framebuffer = pDrv->pVMMDev->getParent()->getDisplay()->getFramebuffer();
if (framebuffer)
{
@@ -381,6 +402,7 @@ DECLCALLBACK(int) vmmdevSetVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32
}
#endif
}
+#endif
return VINF_SUCCESS;
}
@@ -389,6 +411,10 @@ DECLCALLBACK(int) vmmdevQueryVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint
{
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
+#ifdef MMSEAMLESS
+ /* Forward to Display, which calls corresponding framebuffers. */
+ pDrv->pVMMDev->getParent()->getDisplay()->handleQueryVisibleRegion(pcRect, pRect);
+#else
IFramebuffer *framebuffer = pDrv->pVMMDev->getParent()->getDisplay()->getFramebuffer();
if (framebuffer)
{
@@ -397,6 +423,7 @@ DECLCALLBACK(int) vmmdevQueryVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint
*pcRect = cRect;
}
+#endif
return VINF_SUCCESS;
}
@@ -429,6 +456,33 @@ DECLCALLBACK(int) vmmdevQueryStatisticsInterval(PPDMIVMMDEVCONNECTOR pInterface,
}
/**
+ * Query the current balloon size
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pcbBalloon Balloon size
+ * @thread The emulation thread.
+ */
+DECLCALLBACK(int) vmmdevQueryBalloonSize(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcbBalloon)
+{
+ PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
+ ULONG val = 0;
+
+ if (!pcbBalloon)
+ return VERR_INVALID_POINTER;
+
+ /* store that information in IGuest */
+ Guest* guest = pDrv->pVMMDev->getParent()->getGuest();
+ Assert(guest);
+ if (!guest)
+ return VERR_INVALID_PARAMETER; /** @todo wrong error */
+
+ guest->COMGETTER(MemoryBalloonSize)(&val);
+ *pcbBalloon = val;
+ return VINF_SUCCESS;
+}
+
+/**
* Report new guest statistics
*
* @returns VBox status code.
@@ -451,85 +505,33 @@ DECLCALLBACK(int) vmmdevReportStatistics(PPDMIVMMDEVCONNECTOR pInterface, VBoxGu
return VERR_INVALID_PARAMETER; /** @todo wrong error */
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_IDLE)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_CPULoad_Idle, pGuestStats->u32CpuLoad_Idle);
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUIDLE, pGuestStats->u32CpuLoad_Idle);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_KERNEL)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_CPULoad_Kernel, pGuestStats->u32CpuLoad_Kernel);
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUKERNEL, pGuestStats->u32CpuLoad_Kernel);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_USER)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_CPULoad_User, pGuestStats->u32CpuLoad_User);
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_THREADS)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_Threads, pGuestStats->u32Threads);
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PROCESSES)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_Processes, pGuestStats->u32Processes);
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_HANDLES)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_Handles, pGuestStats->u32Handles);
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEMORY_LOAD)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemoryLoad, pGuestStats->u32MemoryLoad);
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUUSER, pGuestStats->u32CpuLoad_User);
- /* Note that reported values are in pages; upper layers expect them in megabytes */
- Assert(pGuestStats->u32PageSize == 4096);
- if (pGuestStats->u32PageSize != 4096)
- pGuestStats->u32PageSize = 4096;
+ /** @todo r=bird: Convert from 4KB to 1KB units?
+ * CollectorGuestHAL::getGuestMemLoad says it returns KB units to
+ * preCollect(). I might be wrong ofc, this is convoluted code... */
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_TOTAL)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_PhysMemTotal, (pGuestStats->u32PhysMemTotal + (_1M/pGuestStats->u32PageSize)-1) / (_1M/pGuestStats->u32PageSize));
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMTOTAL, pGuestStats->u32PhysMemTotal);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_AVAIL)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_PhysMemAvailable, pGuestStats->u32PhysMemAvail / (_1M/pGuestStats->u32PageSize));
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMFREE, pGuestStats->u32PhysMemAvail);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_BALLOON)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_PhysMemBalloon, pGuestStats->u32PhysMemBalloon / (_1M/pGuestStats->u32PageSize));
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_COMMIT_TOTAL)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemCommitTotal, pGuestStats->u32MemCommitTotal / (_1M/pGuestStats->u32PageSize));
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_KERNEL_TOTAL)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemKernelTotal, pGuestStats->u32MemKernelTotal / (_1M/pGuestStats->u32PageSize));
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_KERNEL_PAGED)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemKernelPaged, pGuestStats->u32MemKernelPaged / (_1M/pGuestStats->u32PageSize));
-
- if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_KERNEL_NONPAGED)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemKernelNonpaged, pGuestStats->u32MemKernelNonPaged / (_1M/pGuestStats->u32PageSize));
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMBALLOON, pGuestStats->u32PhysMemBalloon);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_SYSTEM_CACHE)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_MemSystemCache, pGuestStats->u32MemSystemCache / (_1M/pGuestStats->u32PageSize));
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMCACHE, pGuestStats->u32MemSystemCache);
if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PAGE_FILE_SIZE)
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_PageFileSize, pGuestStats->u32PageFileSize / (_1M/pGuestStats->u32PageSize));
-
- /* increase sample number */
- ULONG sample;
-
- int rc = guest->GetStatistic(0, GuestStatisticType_SampleNumber, &sample);
- if (SUCCEEDED(rc))
- guest->SetStatistic(pGuestStats->u32CpuId, GuestStatisticType_SampleNumber, sample+1);
-
- return VINF_SUCCESS;
-}
-
-/**
- * Inflate or deflate the memory balloon
- *
- * @returns VBox status code.
- * @param pInterface Pointer to this interface.
- * @param fInflate Inflate or deflate
- * @param cPages Number of physical pages (must be 256 as we allocate in 1 MB chunks)
- * @param aPhysPage Array of physical page addresses
- * @thread The emulation thread.
- */
-DECLCALLBACK(int) vmmdevChangeMemoryBalloon(PPDMIVMMDEVCONNECTOR pInterface, bool fInflate, uint32_t cPages, RTGCPHYS *aPhysPage)
-{
- if ( cPages != VMMDEV_MEMORY_BALLOON_CHUNK_PAGES
- || !aPhysPage)
- return VERR_INVALID_PARAMETER;
+ guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_PAGETOTAL, pGuestStats->u32PageFileSize);
- Log(("vmmdevChangeMemoryBalloon @todo\n"));
return VINF_SUCCESS;
}
@@ -650,30 +652,19 @@ void VMMDev::hgcmShutdown (void)
/**
- * Queries an interface to the driver.
- *
- * @returns Pointer to interface.
- * @returns NULL if the interface was not supported by the driver.
- * @param pInterface Pointer to this interface structure.
- * @param enmInterface The requested interface identification.
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
*/
-DECLCALLBACK(void *) VMMDev::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
+DECLCALLBACK(void *) VMMDev::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
{
- PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
- PDRVMAINVMMDEV pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINVMMDEV);
- switch (enmInterface)
- {
- case PDMINTERFACE_BASE:
- return &pDrvIns->IBase;
- case PDMINTERFACE_VMMDEV_CONNECTOR:
- return &pDrv->Connector;
+ PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+ PDRVMAINVMMDEV pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINVMMDEV);
+
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIVMMDEVCONNECTOR, &pDrv->Connector);
#ifdef VBOX_WITH_HGCM
- case PDMINTERFACE_HGCM_CONNECTOR:
- return &pDrv->HGCMConnector;
+ PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHGCMCONNECTOR, &pDrv->HGCMConnector);
#endif
- default:
- return NULL;
- }
+ return NULL;
}
/**
@@ -746,7 +737,7 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle,
pData->Connector.pfnQueryVisibleRegion = vmmdevQueryVisibleRegion;
pData->Connector.pfnReportStatistics = vmmdevReportStatistics;
pData->Connector.pfnQueryStatisticsInterval = vmmdevQueryStatisticsInterval;
- pData->Connector.pfnChangeMemoryBalloon = vmmdevChangeMemoryBalloon;
+ pData->Connector.pfnQueryBalloonSize = vmmdevQueryBalloonSize;
#ifdef VBOX_WITH_HGCM
pData->HGCMConnector.pfnConnect = iface_hgcmConnect;
@@ -757,20 +748,12 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle,
/*
* Get the IVMMDevPort interface of the above driver/device.
*/
- pData->pUpPort = (PPDMIVMMDEVPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_VMMDEV_PORT);
- if (!pData->pUpPort)
- {
- AssertMsgFailed(("Configuration error: No VMMDev port interface above!\n"));
- return VERR_PDM_MISSING_INTERFACE_ABOVE;
- }
+ pData->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIVMMDEVPORT);
+ AssertMsgReturn(pData->pUpPort, ("Configuration error: No VMMDev port interface above!\n"), VERR_PDM_MISSING_INTERFACE_ABOVE);
#ifdef VBOX_WITH_HGCM
- pData->pHGCMPort = (PPDMIHGCMPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_HGCM_PORT);
- if (!pData->pHGCMPort)
- {
- AssertMsgFailed(("Configuration error: No HGCM port interface above!\n"));
- return VERR_PDM_MISSING_INTERFACE_ABOVE;
- }
+ pData->pHGCMPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIHGCMPORT);
+ AssertMsgReturn(pData->pHGCMPort, ("Configuration error: No HGCM port interface above!\n"), VERR_PDM_MISSING_INTERFACE_ABOVE);
#endif
/*
@@ -797,12 +780,8 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle,
PPDMILEDPORTS pLedPort;
LogRel(("Shared Folders service loaded.\n"));
- pLedPort = (PPDMILEDPORTS)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_LED_PORTS);
- if (!pLedPort)
- {
- AssertMsgFailed(("Configuration error: No LED port interface above!\n"));
- return VERR_PDM_MISSING_INTERFACE_ABOVE;
- }
+ pLedPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMILEDPORTS);
+ AssertMsgReturn(pLedPort, ("Configuration error: No LED port interface above!\n"), VERR_PDM_MISSING_INTERFACE_ABOVE);
rc = pLedPort->pfnQueryStatusLed(pLedPort, 0, &pLed);
if (RT_SUCCESS(rc) && pLed)
{
@@ -840,8 +819,12 @@ const PDMDRVREG VMMDev::DrvReg =
{
/* u32Version */
PDM_DRVREG_VERSION,
- /* szDriverName */
+ /* szName */
"HGCM",
+ /* szRCMod */
+ "",
+ /* szR0Mod */
+ "",
/* pszDescription */
"Main VMMDev driver (Main as in the API).",
/* fFlags */
@@ -856,6 +839,8 @@ const PDMDRVREG VMMDev::DrvReg =
VMMDev::drvConstruct,
/* pfnDestruct */
VMMDev::drvDestruct,
+ /* pfnRelocate */
+ NULL,
/* pfnIOCtl */
NULL,
/* pfnPowerOn */