Init.cpp revision fea3b04b1b6d6c8d86fbfc6b7f75b0b157089a48
de4157257515400c2c25373591135f110227b68cvboxsync/* $Revision$ */
de4157257515400c2c25373591135f110227b68cvboxsync/** @file
de4157257515400c2c25373591135f110227b68cvboxsync * VBoxGuestLibR0 - Library initialization.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2007 Oracle Corporation
de4157257515400c2c25373591135f110227b68cvboxsync *
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * available from http://www.virtualbox.org. This file is free software;
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * General Public License (GPL) as published by the Free Software
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b263fac6f6e7fa933c7bfb2a45d598fe8e458c09vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * The contents of this file may alternatively be used under the terms
de4157257515400c2c25373591135f110227b68cvboxsync * of the Common Development and Distribution License Version 1.0
de4157257515400c2c25373591135f110227b68cvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * VirtualBox OSE distribution, in which case the provisions of the
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * CDDL are applicable instead of those of the GPL.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * You may elect to license modified versions of this file under the
de4157257515400c2c25373591135f110227b68cvboxsync * terms and conditions of either the GPL or the CDDL or both.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/*******************************************************************************
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync* Header Files *
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync*******************************************************************************/
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#define VBGL_DECL_DATA
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#include "VBGLInternal.h"
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#include <iprt/string.h>
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync#include <iprt/assert.h>
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/*******************************************************************************
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync* Global Variables *
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync*******************************************************************************/
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/** The global VBGL instance data. */
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsyncVBGLDATA g_vbgldata;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/**
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * Used by vbglQueryVMMDevPort and VbglInit to try get the host feature mask and
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * version information (g_vbgldata::hostVersion).
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync *
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * This was first implemented by the host in 3.1 and we quietly ignore failures
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * for that reason.
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync */
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsyncstatic void vbglR0QueryHostVersion (void)
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync{
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync VMMDevReqHostVersion *pReq;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (RT_SUCCESS (rc))
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync rc = VbglGRPerform (&pReq->header);
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (RT_SUCCESS (rc))
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync g_vbgldata.hostVersion = *pReq;
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync VbglGRFree (&pReq->header);
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#ifndef VBGL_VBOXGUEST
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync/**
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * The guest library uses lazy initialization for VMMDev port and memory,
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * because these values are provided by the VBoxGuest driver and it might
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync * be loaded later than other drivers.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * The VbglEnter checks the current library status, tries to retrieve these
de4157257515400c2c25373591135f110227b68cvboxsync * values and fails if they are unavailable.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsyncstatic void vbglQueryVMMDevPort (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync int rc = VINF_SUCCESS;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync VBGLDRIVER driver;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = vbglDriverOpen (&driver);
de4157257515400c2c25373591135f110227b68cvboxsync
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync if (RT_SUCCESS(rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync /*
de4157257515400c2c25373591135f110227b68cvboxsync * Try query the port info.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsync VBoxGuestPortInfo port;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = vbglDriverIOCtl (&driver, VBOXGUEST_IOCTL_GETVMMDEVPORT, &port, sizeof (port));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (RT_SUCCESS (rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.portVMMDev = port.portAddress;
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.pVMMDevMemory = port.pVMMDevMemory;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.status = VbglStatusReady;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync vbglR0QueryHostVersion();
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync vbglDriverClose (&driver);
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync dprintf (("vbglQueryVMMDevPort rc = %d\n", rc));
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync#endif /* !VBGL_VBOXGUEST */
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync/**
de4157257515400c2c25373591135f110227b68cvboxsync * Checks if VBGL has been initialized.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * The the client library, this will lazily complete the initialization.
de4157257515400c2c25373591135f110227b68cvboxsync *
de4157257515400c2c25373591135f110227b68cvboxsync * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
de4157257515400c2c25373591135f110227b68cvboxsync */
de4157257515400c2c25373591135f110227b68cvboxsyncint vbglR0Enter (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync int rc;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#ifndef VBGL_VBOXGUEST
de4157257515400c2c25373591135f110227b68cvboxsync if (g_vbgldata.status == VbglStatusInitializing)
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync vbglQueryVMMDevPort ();
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync#endif
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync // dprintf(("VbglEnter: rc = %d\n", rc));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncint vbglInitCommon (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync int rc = VINF_SUCCESS;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync RT_ZERO(g_vbgldata);
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.status = VbglStatusInitializing;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = VbglPhysHeapInit ();
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (RT_SUCCESS(rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync /* other subsystems, none yet */
de4157257515400c2c25373591135f110227b68cvboxsync ;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync else
de4157257515400c2c25373591135f110227b68cvboxsync LogRel(("vbglInitCommon: VbglPhysHeapInit failed. rc=%Rrc\n", rc));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync dprintf(("vbglInitCommon: rc = %d\n", rc));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(void) vbglTerminateCommon (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync VbglPhysHeapTerminate ();
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync RT_ZERO(g_vbgldata);
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#ifdef VBGL_VBOXGUEST
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VbglInit (VBGLIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync int rc = VINF_SUCCESS;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
de4157257515400c2c25373591135f110227b68cvboxsync dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (g_vbgldata.status == VbglStatusInitializing
de4157257515400c2c25373591135f110227b68cvboxsync || g_vbgldata.status == VbglStatusReady)
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync /* Initialization is already in process. */
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync# else
de4157257515400c2c25373591135f110227b68cvboxsync dprintf(("vbglInit: starts\n"));
de4157257515400c2c25373591135f110227b68cvboxsync# endif
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = vbglInitCommon ();
75479ee94ecd639290ae67b38c9497d9492f89e1vboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (RT_SUCCESS(rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.portVMMDev = portVMMDev;
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.pVMMDevMemory = pVMMDevMemory;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.status = VbglStatusReady;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync vbglR0QueryHostVersion();
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync else
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync g_vbgldata.status = VbglStatusNotInitialized;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(void) VbglTerminate (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync vbglTerminateCommon ();
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync#else /* !VBGL_VBOXGUEST */
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(int) VbglInit (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync int rc = VINF_SUCCESS;
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (g_vbgldata.status == VbglStatusInitializing
de4157257515400c2c25373591135f110227b68cvboxsync || g_vbgldata.status == VbglStatusReady)
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync /* Initialization is already in process. */
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync rc = vbglInitCommon ();
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (RT_SUCCESS(rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
de4157257515400c2c25373591135f110227b68cvboxsync vbglQueryVMMDevPort ();
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync# ifdef VBOX_WITH_HGCM
de4157257515400c2c25373591135f110227b68cvboxsync rc = vbglR0HGCMInit ();
de4157257515400c2c25373591135f110227b68cvboxsync# endif /* VBOX_WITH_HGCM */
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync if (RT_FAILURE(rc))
de4157257515400c2c25373591135f110227b68cvboxsync {
de4157257515400c2c25373591135f110227b68cvboxsync vbglTerminateCommon ();
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync }
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync return rc;
de4157257515400c2c25373591135f110227b68cvboxsync}
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsyncDECLVBGL(void) VbglTerminate (void)
de4157257515400c2c25373591135f110227b68cvboxsync{
de4157257515400c2c25373591135f110227b68cvboxsync# ifdef VBOX_WITH_HGCM
de4157257515400c2c25373591135f110227b68cvboxsync vbglR0HGCMTerminate ();
de4157257515400c2c25373591135f110227b68cvboxsync# endif
de4157257515400c2c25373591135f110227b68cvboxsync
de4157257515400c2c25373591135f110227b68cvboxsync vbglTerminateCommon ();
de4157257515400c2c25373591135f110227b68cvboxsync
ccc948c886b751603889a67909fbd4a5fcaeac85vboxsync return;
ccc948c886b751603889a67909fbd4a5fcaeac85vboxsync}
ccc948c886b751603889a67909fbd4a5fcaeac85vboxsync
66d43d6192fb8fbb95c01515ba64f8a1e678a863vboxsync#endif /* !VBGL_VBOXGUEST */
ccc948c886b751603889a67909fbd4a5fcaeac85vboxsync
de4157257515400c2c25373591135f110227b68cvboxsync