VMMDevTesting.cpp revision e98a0184c6fd934a03d6a492eaae3e24b9fc4e9f
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/* $Id$ */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/** @file
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * VMMDev - Testing Extensions.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/*
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * Copyright (C) 2010 Oracle Corporation
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * available from http://www.virtualbox.org. This file is free software;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * General Public License (GPL) as published by the Free Software
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/*******************************************************************************
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync* Header Files *
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync*******************************************************************************/
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#define LOG_GROUP LOG_GROUP_DEV_VMM
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include <VBox/VMMDev.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include <VBox/log.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include <VBox/err.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include <iprt/asm.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include <iprt/assert.h>
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync#include <iprt/string.h>
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync#include <iprt/time.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync# include <iprt/stream.h>
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include "VMMDevState.h"
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#include "VMMDevTesting.h"
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#ifndef VBOX_WITHOUT_TESTING_FEATURES
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#define VMMDEV_TESTING_OUTPUT(a) \
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync do \
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync { \
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync LogAlways(a);\
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync LogRel(a);\
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync RTPrintf a; \
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync } while (0)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync/**
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync * @callback_method_impl{FNIOMMMIOWRITE}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsyncPDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync{
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync switch (GCPhysAddr)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync {
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case VMMDEV_TESTING_MMIO_NOP:
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync switch (cb)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync {
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case 8:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 4:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 2:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 1:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertFailed();
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_INTERNAL_ERROR_5;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync return VINF_SUCCESS;
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync}
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync/**
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync * @callback_method_impl{FNIOMMMIOREAD}
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync */
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsyncPDMBOTHCBDECL(int) vmmdevTestingMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync{
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync switch (GCPhysAddr)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync {
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case VMMDEV_TESTING_MMIO_NOP:
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync switch (cb)
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync {
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case 8:
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync *(uint64_t *)pv = VMMDEV_TESTING_NOP_RET | ((uint64_t)VMMDEV_TESTING_NOP_RET << 32);
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync break;
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case 4:
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync *(uint32_t *)pv = VMMDEV_TESTING_NOP_RET;
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync break;
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync case 2:
750df3fe104e01cadbc3d5bd20243055d283d4e5vboxsync *(uint16_t *)pv = (uint16_t)VMMDEV_TESTING_NOP_RET;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 1:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *(uint8_t *)pv = (uint8_t)VMMDEV_TESTING_NOP_RET;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertFailed();
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_INTERNAL_ERROR_5;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_IOM_MMIO_UNUSED_FF;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/**
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * @callback_method_impl{FNIOMIOPORTOUT}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsyncPDMBOTHCBDECL(int) vmmdevTestingIoWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync{
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (Port)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_NOP:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (cb)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 4:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 2:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 1:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertFailed();
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_INTERNAL_ERROR_2;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_TS_LOW:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_TS_HIGH:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_CMD:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (cb == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->u32TestingCmd = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->offTestingData = 0;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync RT_ZERO(pThis->TestingData);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_DATA:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync uint32_t uCmd = pThis->u32TestingCmd;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync uint32_t off = pThis->offTestingData;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (uCmd)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_INIT:
11b175175a0ed424b8e8354acda681ad0adde0f8vboxsync case VMMDEV_TESTING_CMD_SUB_NEW:
11b175175a0ed424b8e8354acda681ad0adde0f8vboxsync case VMMDEV_TESTING_CMD_FAILED:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if ( off < sizeof(pThis->TestingData.String.sz) - 1
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync && cb == 1)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
11b175175a0ed424b8e8354acda681ad0adde0f8vboxsync if (u32)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.String.sz[off] = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->offTestingData = off + 1;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (uCmd)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_INIT:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: INIT '%.*s'\n",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_SUB_NEW:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: SUB_NEW '%.*s'\n",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_FAILED:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: FAILED '%.*s'\n",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_IOM_R3_IOPORT_WRITE;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_TERM:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_SUB_DONE:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if ( off == 0
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync && cb == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Error.c = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (uCmd == VMMDEV_TESTING_CMD_TERM)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: TERM - %u errors\n", u32));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: SUB_DONE - %u errors\n", u32));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_IOM_R3_IOPORT_WRITE;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_CMD_VALUE:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (cb == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (off == 0)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.u64Value.s.Lo = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else if (off == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.u64Value.s.Hi = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else if (off == 8)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.u32Unit = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->offTestingData = off + 4;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if ( off >= 12
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync && cb == 1
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync && off < sizeof(pThis->TestingData.Value.szName) - 1 - 12)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (u32)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.szName[off - 12] = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->offTestingData = off + 1;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: VALUE '%.*s'%*s: %'9llu (%#llx) [%u]\n",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync sizeof(pThis->TestingData.Value.szName) - 1, pThis->TestingData.Value.szName,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync off - 12 > 48 ? 0 : 48 - (off - 12), "",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.u64Value.u, pThis->TestingData.Value.u64Value.u,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Value.u32Unit));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_IOM_R3_IOPORT_WRITE;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->TestingData.Error.c = u32;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (uCmd == VMMDEV_TESTING_CMD_TERM)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: TERM - %u errors\n", u32));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDEV_TESTING_OUTPUT(("testing: SUB_DONE - %u errors\n", u32));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#else
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_IOM_R3_IOPORT_WRITE;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync Log(("VMMDEV_TESTING_IOPORT_CMD: bad access; cmd=%#x off=%#x cb=%#x u32=%#x\n", uCmd, off, cb, u32));
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_IOM_IOPORT_UNUSED;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/**
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * @callback_method_impl{FNIOMIOPORTIN}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsyncPDMBOTHCBDECL(int) vmmdevTestingIoRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync{
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (Port)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_NOP:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync switch (cb)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 4:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 2:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case 1:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertFailed();
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_INTERNAL_ERROR_2;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *pu32 = VMMDEV_TESTING_NOP_RET;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_TS_LOW:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (cb == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync uint64_t NowTS = RTTimeNanoTS();
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *pu32 = (uint32_t)NowTS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync pThis->u32TestingHighTimestamp = (uint32_t)(NowTS >> 32);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_TS_HIGH:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (cb == 4)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *pu32 = pThis->u32TestingHighTimestamp;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_CMD:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync case VMMDEV_TESTING_IOPORT_DATA:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync default:
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync break;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VERR_IOM_IOPORT_UNUSED;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#ifdef IN_RING3
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync/**
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * Initializes the testing part of the VMMDev if enabled.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync *
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * @returns VBox status code.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * @param pDevIns The VMMDev device instance.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsyncint vmmdevTestingInitialize(PPDMDEVINS pDevIns)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync{
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (!pThis->fTestingEnabled)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync /*
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * Register a chunk of MMIO memory that we'll use for various
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * tests interfaces.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync int rc = PDMDevHlpMMIORegister(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NULL /*pvUser*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync vmmdevTestingMmioWrite, vmmdevTestingMmioRead, "VMMDev Testing");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (pThis->fRZEnabled)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync rc = PDMDevHlpMMIORegisterR0(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTR0PTR /*pvUser*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingMmioWrite", "vmmdevTestingMmioRead");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync rc = PDMDevHlpMMIORegisterRC(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTRCPTR /*pvUser*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingMmioWrite", "vmmdevTestingMmioRead");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync /*
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync * Register the I/O ports used for testing.
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync rc = PDMDevHlpIOPortRegister(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NULL,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync vmmdevTestingIoWrite,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync vmmdevTestingIoRead,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pfnOutStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pfnInStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "VMMDev Testing");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync if (pThis->fRZEnabled)
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync {
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync rc = PDMDevHlpIOPortRegisterR0(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTR0PTR /*pvUser*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingIoWrite",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingIoRead",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pszOutStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pszInStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "VMMDev Testing");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync rc = PDMDevHlpIOPortRegisterRC(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTRCPTR /*pvUser*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingIoWrite",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "vmmdevTestingIoRead",
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pszOutStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync NULL /*pszInStr*/,
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync "VMMDev Testing");
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync AssertRCReturn(rc, rc);
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync }
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync return VINF_SUCCESS;
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync}
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif /* IN_RING3 */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync#endif /* !VBOX_WITHOUT_TESTING_FEATURES */
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync
553a2f0d8ef91a6dad8de4eef206ff093af53a5dvboxsync