tstMicro.cpp revision 061ba5cd8c4eaf5176d0ee1dadb77d3f46d1f584
/* $Id$ */
/** @file
* Micro Testcase, profiling special CPU operations.
*/
/*
* Copyright (C) 2006-2013 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 *
*******************************************************************************/
#include <iprt/initterm.h>
#include <iprt/semaphore.h>
#include "tstMicro.h"
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
#define TESTCASE "tstVMM"
{
switch (enmTest)
{
case TSTMICROTEST_OVERHEAD: return "Overhead";
case TSTMICROTEST_INVLPG_0: return "invlpg [0]";
case TSTMICROTEST_INVLPG_EIP: return "invlpg [EIP]";
case TSTMICROTEST_INVLPG_ESP: return "invlpg [ESP]";
case TSTMICROTEST_CR3_RELOAD: return "cr3 reload";
case TSTMICROTEST_WP_DISABLE: return "CR0.WP <- 0";
case TSTMICROTEST_WP_ENABLE: return "CR0.WP <- 1";
case TSTMICROTEST_PF_R0: return "R0 #PG (NULL)";
case TSTMICROTEST_PF_R1: return "R1 #PG (NULL)";
case TSTMICROTEST_PF_R2: return "R2 #PG (NULL)";
case TSTMICROTEST_PF_R3: return "R3 #PG (NULL)";
default:
{
static char sz[64];
return sz;
}
}
}
static void PrintHeaderInstr(void)
{
"Test name",
"Min",
"Avg",
"Max");
}
static void PrintResultInstr(PTSTMICRO pTst, TSTMICROTEST enmTest, int rc, uint64_t cMinTicks, uint64_t cAvgTicks, uint64_t cMaxTicks)
{
if (RT_FAILURE(rc))
rc,
else
}
static void PrintHeaderTraps(void)
{
"Test name",
"Total",
"ToRx",
"Trap",
"ToRxTrap",
"int42-done");
}
{
if (RT_FAILURE(rc))
rc,
else
}
/**
*
* 0060 - r0 code
* 0068 - r0 data
*
* 1060 - r1 code
* 1068 - r1 data
*
* 2060 - r2 code
* 2068 - r2 data
*
* 3060 - r3 code
* 3068 - r3 data
*
*/
{
/*
* Find the GDT - This is a HACK :-)
*/
for (unsigned i = 0; i <= 3; i++)
{
/* 32-bit code selector. */
/* 32-bit data selector. */
pGDTE++;
}
}
{
/*
* Loading the module and resolve the entry point.
*/
if (RT_FAILURE(rc))
{
return rc;
}
if (RT_FAILURE(rc))
{
RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRC' entry point in tstMicroRC.gc, rc=%Rra\n", rc);
return rc;
}
if (RT_FAILURE(rc))
{
RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRCAsmStart' entry point in tstMicroRC.gc, rc=%Rra\n", rc);
return rc;
}
if (RT_FAILURE(rc))
{
RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRCAsmEnd' entry point in tstMicroRC.gc, rc=%Rra\n", rc);
return rc;
}
/*
* Allocate and initialize the instance data.
*/
if (RT_FAILURE(rc))
{
RTPrintf(TESTCASE ": Failed to resolve allocate instance memory (%d bytes), rc=%Rra\n", sizeof(*pTst), rc);
return rc;
}
/* the page must be writable from user mode */
rc = PGMMapModifyPage(pVM, pTst->RCPtr, sizeof(*pTst), X86_PTE_US | X86_PTE_RW, ~(uint64_t)(X86_PTE_US | X86_PTE_RW));
if (RT_FAILURE(rc))
{
return rc;
}
/* all the code must be executable from R3. */
rc = PGMMapModifyPage(pVM, RCPtrStart, RCPtrEnd - RCPtrStart + PAGE_SIZE, X86_PTE_US, ~(uint64_t)X86_PTE_US);
if (RT_FAILURE(rc))
{
return rc;
}
DBGFR3PagingDumpEx(pVM->pUVM, 0 /*idCpu*/, DBGFPGDMP_FLAGS_CURRENT_CR3 | DBGFPGDMP_FLAGS_CURRENT_MODE
#if 0
/*
* Disassemble the assembly...
*/
{
char sz[256];
if (RT_SUCCESS(rc))
else
{
cb = 1;
}
}
#endif
#ifdef VBOX_WITH_RAW_MODE
/*
* Do the profiling.
*/
/* execute the instruction profiling tests */
int i;
for (i = TSTMICROTEST_OVERHEAD; i < TSTMICROTEST_TRAP_FIRST; i++)
{
unsigned cSamples = 0;
rc = VINF_SUCCESS;
for (int c = 0; c < 100; c++)
{
if (RT_SUCCESS(rc2))
{
cSamples++;
}
else if (RT_SUCCESS(rc))
}
/* store the overhead */
if (enmTest == TSTMICROTEST_OVERHEAD)
}
#endif
#ifdef VBOX_WITH_RAW_MODE
RTPrintf("\n");
for (i = TSTMICROTEST_TRAP_FIRST; i < TSTMICROTEST_MAX; i++)
{
}
#endif
return VINF_SUCCESS;
}
{
int rcRet = 0; /* error count. */
/*
* Create empty VM.
*/
if (RT_SUCCESS(rc))
{
/*
* Do testing.
*/
/*
* Cleanup.
*/
if (!RT_SUCCESS(rc))
{
rcRet++;
}
if (!RT_SUCCESS(rc))
{
rcRet++;
}
}
else
{
rcRet++;
}
return rcRet;
}