a8834d85501bd084d0d42b819a385467d05489fdvboxsync/* $Id$ */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/** @file
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Guest Interface Manager Device.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Copyright (C) 2014 Oracle Corporation
a8834d85501bd084d0d42b819a385467d05489fdvboxsync *
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * available from http://www.virtualbox.org. This file is free software;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * General Public License (GPL) as published by the Free Software
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/*******************************************************************************
a8834d85501bd084d0d42b819a385467d05489fdvboxsync* Header Files *
a8834d85501bd084d0d42b819a385467d05489fdvboxsync*******************************************************************************/
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#define LOG_GROUP LOG_GROUP_DEV_GIM
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#include <VBox/vmm/pdmdev.h>
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#include <VBox/vmm/gim.h>
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#include <VBox/vmm/vm.h>
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#include "VBoxDD.h"
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * GIM device.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsynctypedef struct GIMDEV
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** Pointer to the device instance - R3 Ptr. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PPDMDEVINSR3 pDevInsR3;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** Pointer to the device instance - R0 Ptr. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PPDMDEVINSR0 pDevInsR0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** Pointer to the device instance - RC Ptr. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PPDMDEVINSRC pDevInsRC;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** Alignment. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync RTRCPTR Alignment0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync} GIMDEV;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/** Pointer to the GIM device state. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsynctypedef GIMDEV *PGIMDEV;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#ifndef VBOX_DEVICE_STRUCT_TESTCASE
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#ifdef IN_RING3
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * @interface_method_impl{PDMDEVREG,pfnConstruct}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsyncstatic DECLCALLBACK(int) gimdevR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync Assert(iInstance == 0);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PGIMDEV pThis = PDMINS_2_DATA(pDevIns, PGIMDEV);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Initialize relevant state bits.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pThis->pDevInsR3 = pDevIns;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Register ourselves with the GIM VMM component.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PVM pVM = PDMDevHlpGetVM(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync GIMR3GimDeviceRegister(pVM, pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Get the MMIO2 regions from the GIM provider.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync uint32_t cRegions = 0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PGIMMMIO2REGION pRegionsR3 = GIMR3GetMmio2Regions(pVM, &cRegions);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync if ( cRegions
a8834d85501bd084d0d42b819a385467d05489fdvboxsync && pRegionsR3)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync {
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Register the MMIO2 regions.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PGIMMMIO2REGION pCur = pRegionsR3;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync for (uint32_t i = 0; i < cRegions; i++, pCur++)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync {
a8834d85501bd084d0d42b819a385467d05489fdvboxsync Assert(!pCur->fRegistered);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync int rc = PDMDevHlpMMIO2Register(pDevIns, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->szDescription);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync if (RT_FAILURE(rc))
a8834d85501bd084d0d42b819a385467d05489fdvboxsync return rc;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->fRegistered = true;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync RTR0PTR pR0Mapping = 0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync rc = PDMDevHlpMMIO2MapKernel(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync &pR0Mapping);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMapMMIO2IntoR0(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->pvPageR0 = pR0Mapping;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#else
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->pvPageR0 = (RTR0PTR)pCur->pvPageR3;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#endif
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /*
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * Map into RC if required.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync if (pCur->fRCMapping)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync {
a8834d85501bd084d0d42b819a385467d05489fdvboxsync RTRCPTR pRCMapping = 0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync &pRCMapping);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->pvPageRC = pRCMapping;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync }
a8834d85501bd084d0d42b819a385467d05489fdvboxsync else
a8834d85501bd084d0d42b819a385467d05489fdvboxsync pCur->pvPageRC = NIL_RTRCPTR;
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync LogRel(("GIMDev: Registered %s\n", pCur->szDescription));
a8834d85501bd084d0d42b819a385467d05489fdvboxsync }
a8834d85501bd084d0d42b819a385467d05489fdvboxsync }
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** @todo Register SSM: PDMDevHlpSSMRegister(). */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** @todo Register statistics: STAM_REG(). */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /** @todo Register DBGFInfo: PDMDevHlpDBGFInfoRegister(). */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync return VINF_SUCCESS;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * @interface_method_impl{PDMDEVREG,pfnDestruct}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsyncstatic DECLCALLBACK(int) gimdevR3Destruct(PPDMDEVINS pDevIns)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PGIMDEV pThis = PDMINS_2_DATA(pDevIns, PGIMDEV);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PVM pVM = PDMDevHlpGetVM(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync uint32_t cRegions = 0;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PGIMMMIO2REGION pCur = GIMR3GetMmio2Regions(pVM, &cRegions);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync for (uint32_t i = 0; i < cRegions; i++, pCur++)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync {
a8834d85501bd084d0d42b819a385467d05489fdvboxsync int rc = PDMDevHlpMMIO2Deregister(pDevIns, pCur->iRegion);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync if (RT_FAILURE(rc))
a8834d85501bd084d0d42b819a385467d05489fdvboxsync return rc;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync }
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync return VINF_SUCCESS;
a8834d85501bd084d0d42b819a385467d05489fdvboxsync}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * @interface_method_impl{PDMDEVREG,pfnRelocate}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsyncstatic DECLCALLBACK(void) gimdevR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NOREF(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NOREF(offDelta);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * @interface_method_impl{PDMDEVREG,pfnReset}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsyncstatic DECLCALLBACK(void) gimdevR3Reset(PPDMDEVINS pDevIns)
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NOREF(pDevIns);
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* We do not deregister any MMIO2 regions as the regions are expected to be static. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync}
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync/**
a8834d85501bd084d0d42b819a385467d05489fdvboxsync * The device registration structure.
a8834d85501bd084d0d42b819a385467d05489fdvboxsync */
a8834d85501bd084d0d42b819a385467d05489fdvboxsyncconst PDMDEVREG g_DeviceGIMDev =
a8834d85501bd084d0d42b819a385467d05489fdvboxsync{
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* u32Version */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PDM_DEVREG_VERSION,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* szName */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync "GIMDev",
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* szRCMod */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync "VBoxDDGC.gc",
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* szR0Mod */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync "VBoxDDR0.r0",
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pszDescription */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync "VirtualBox GIM Device",
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* fFlags */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* fClass */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PDM_DEVREG_CLASS_MISC,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* cMaxInstances */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync 1,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* cbInstance */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync sizeof(GIMDEV),
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnConstruct */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync gimdevR3Construct,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnDestruct */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync gimdevR3Destruct,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnRelocate */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync gimdevR3Relocate,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnMemSetup */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnPowerOn */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnReset */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync gimdevR3Reset,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnSuspend */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnResume */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnAttach */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnDetach */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnQueryInterface. */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnInitComplete */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnPowerOff */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* pfnSoftReset */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync NULL,
a8834d85501bd084d0d42b819a385467d05489fdvboxsync /* u32VersionEnd */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync PDM_DEVREG_VERSION
a8834d85501bd084d0d42b819a385467d05489fdvboxsync};
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#endif /* IN_RING3 */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync
a8834d85501bd084d0d42b819a385467d05489fdvboxsync#endif /* VBOX_DEVICE_STRUCT_TESTCASE */
a8834d85501bd084d0d42b819a385467d05489fdvboxsync