VMMDevTesting.cpp revision 5349ebd2456382ce66be9a76f82c00ae4fb58251
/* $Id$ */
/** @file
* VMMDev - Testing Extensions.
*/
/*
* Copyright (C) 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;
* General Public License (GPL) 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.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_VMM
#ifdef IN_RING3
#endif
#include "VMMDevState.h"
#include "VMMDevTesting.h"
#ifndef VBOX_WITHOUT_TESTING_FEATURES
/**
* @callback_method_impl{FNIOMMMIOWRITE}
*/
PDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
{
switch (GCPhysAddr)
{
case VMMDEV_TESTING_MMIO_NOP:
switch (cb)
{
case 8:
case 4:
case 2:
case 1:
break;
default:
AssertFailed();
return VERR_INTERNAL_ERROR_5;
}
return VINF_SUCCESS;
default:
break;
}
return VINF_SUCCESS;
}
/**
* @callback_method_impl{FNIOMMMIOREAD}
*/
PDMBOTHCBDECL(int) vmmdevTestingMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
{
switch (GCPhysAddr)
{
case VMMDEV_TESTING_MMIO_NOP:
switch (cb)
{
case 8:
break;
case 4:
break;
case 2:
break;
case 1:
break;
default:
AssertFailed();
return VERR_INTERNAL_ERROR_5;
}
return VINF_SUCCESS;
default:
break;
}
return VINF_IOM_MMIO_UNUSED_FF;
}
/**
* @callback_method_impl{FNIOMIOPORTOUT}
*/
PDMBOTHCBDECL(int) vmmdevTestingIoWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
switch (Port)
{
switch (cb)
{
case 4:
case 2:
case 1:
break;
default:
AssertFailed();
return VERR_INTERNAL_ERROR_2;
}
return VINF_SUCCESS;
break;
break;
if (cb == 4)
{
pThis->offTestingData = 0;
return VINF_SUCCESS;
}
break;
{
switch (uCmd)
{
case VMMDEV_TESTING_CMD_INIT:
&& cb == 1)
{
if (u32)
{
}
else
{
#ifdef IN_RING3
switch (uCmd)
{
case VMMDEV_TESTING_CMD_INIT:
RTPrintf("testing: INIT '%.*s'\n", sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz);
break;
RTPrintf("testing: SUB_NEW '%.*s'\n", sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz);
break;
RTPrintf("testing: FAILED '%.*s'\n", sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz);
break;
}
#else
return VINF_IOM_HC_IOPORT_WRITE;
#endif
}
return VINF_SUCCESS;
}
break;
case VMMDEV_TESTING_CMD_TERM:
if ( off == 0
&& cb == 4)
{
#ifdef IN_RING3
if (uCmd == VMMDEV_TESTING_CMD_TERM)
else
return VINF_SUCCESS;
#else
return VINF_IOM_HC_IOPORT_WRITE;
#endif
}
break;
case VMMDEV_TESTING_CMD_VALUE:
if (cb == 4)
{
if (off == 0)
else if (off == 4)
else if (off == 8)
else
break;
return VINF_SUCCESS;
}
if ( off >= 12
&& cb == 1
{
if (u32)
{
}
else
{
#ifdef IN_RING3
RTPrintf("testing: VALUE '%.*s'%*s: %'9llu (%#llx) [%u]\n",
#else
return VINF_IOM_HC_IOPORT_WRITE;
#endif
}
return VINF_SUCCESS;
#ifdef IN_RING3
if (uCmd == VMMDEV_TESTING_CMD_TERM)
else
return VINF_SUCCESS;
#else
return VINF_IOM_HC_IOPORT_WRITE;
#endif
}
break;
default:
break;
}
Log(("VMMDEV_TESTING_IOPORT_CMD: bad access; cmd=%#x off=%#x cb=%#x u32=%#x\n", uCmd, off, cb, u32));
return VINF_SUCCESS;
}
default:
break;
}
return VERR_IOM_IOPORT_UNUSED;
}
/**
* @callback_method_impl{FNIOMIOPORTIN}
*/
PDMBOTHCBDECL(int) vmmdevTestingIoRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
switch (Port)
{
switch (cb)
{
case 4:
case 2:
case 1:
break;
default:
AssertFailed();
return VERR_INTERNAL_ERROR_2;
}
return VINF_SUCCESS;
if (cb == 4)
{
return VINF_SUCCESS;
}
break;
if (cb == 4)
{
return VINF_SUCCESS;
}
break;
break;
default:
break;
}
return VERR_IOM_IOPORT_UNUSED;
}
#ifdef IN_RING3
/**
* Initializes the testing part of the VMMDev if enabled.
*
* @returns VBox status code.
* @param pDevIns The VMMDev device instance.
*/
{
if (!pThis->fTestingEnabled)
return VINF_SUCCESS;
/*
* Register a chunk of MMIO memory that we'll use for various
* tests interfaces.
*/
int rc = PDMDevHlpMMIORegister(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NULL /*pvUser*/,
NULL /*pfnFill*/,
"VMMDev Testing");
if (pThis->fRZEnabled)
{
rc = PDMDevHlpMMIORegisterR0(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTR0PTR /*pvUser*/,
"vmmdevTestingMmioWrite",
"vmmdevTestingMmioRead",
NULL /*pszFill*/);
rc = PDMDevHlpMMIORegisterRC(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTRCPTR /*pvUser*/,
"vmmdevTestingMmioWrite",
"vmmdevTestingMmioRead",
NULL /*pszFill*/);
}
/*
* Register the I/O ports used for testing.
*/
rc = PDMDevHlpIOPortRegister(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NULL,
NULL /*pfnOutStr*/,
NULL /*pfnInStr*/,
"VMMDev Testing");
if (pThis->fRZEnabled)
{
rc = PDMDevHlpIOPortRegisterR0(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTR0PTR /*pvUser*/,
"vmmdevTestingIoWrite",
"vmmdevTestingIoRead",
NULL /*pszOutStr*/,
NULL /*pszInStr*/,
"VMMDev Testing");
rc = PDMDevHlpIOPortRegisterRC(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTRCPTR /*pvUser*/,
"vmmdevTestingIoWrite",
"vmmdevTestingIoRead",
NULL /*pszOutStr*/,
NULL /*pszInStr*/,
"VMMDev Testing");
}
return VINF_SUCCESS;
}
#endif /* IN_RING3 */
#endif /* !VBOX_WITHOUT_TESTING_FEATURES */