tstOhciRegisterAccess.cpp revision cde46304e0c614aad7fd63abacb0180e4e83f24c
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/* $Id$ */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/** @file
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * tstOhciRegisterAccess - OHCI Register Access Tests / Experiments.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Copyright (C) 2011 Oracle Corporation
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync *
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * available from http://www.virtualbox.org. This file is free software;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * General Public License (GPL) as published by the Free Software
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/*******************************************************************************
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync* Header Files *
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync*******************************************************************************/
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <VBox/log.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <iprt/mem.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <iprt/memobj.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <iprt/string.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <iprt/asm-amd64-x86.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <iprt/param.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#include <VBox/sup.h>
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#undef LogRel
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync#define LogRel(a) SUPR0Printf a
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/*******************************************************************************
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync* Global Variables *
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync*******************************************************************************/
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync/** Register names. */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsyncstatic const char * const g_apszRegNms[] =
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync{
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRevision",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcControl",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcCommandStatus",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcInterruptStatus",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcInterruptEnable",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcInterruptDisable",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcHCCA",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcPeriodCurrentED",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcControlHeadED",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcControlCurrentED",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcBulkHeadED",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcBulkCurrentED",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcDoneHead",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcFmInterval",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcFmRemaining",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcFmNumber",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcPeriodicStart",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcLSThreshold",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhDescriptorA",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhDescriptorB",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhStatus",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /* Variable number of root hub ports: */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[0]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[1]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[2]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[3]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[4]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[5]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[6]",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "HcRhPortStatus[7]"
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync};
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsyncstatic bool TestOhciWrites(RTVPTRUNION uPtr)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync{
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync return true;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync}
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsyncstatic bool TestOhciReads(RTVPTRUNION uPtr)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync{
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * We can read just about any register we like since read shouldn't have
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * any side effects. However, some registers are volatile and makes for
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * difficult targets, thus the ugly code.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync bool fSuccess = true;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uint32_t cMaxReg = RT_ELEMENTS(g_apszRegNms);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (uint32_t iReg = 0; iReg < cMaxReg; iReg++, uPtr.pu32++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync const char *pszError = NULL;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync bool fDone = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uint32_t uInitialValue = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uint32_t u32A = 0;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uint32_t u32B = 0;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uint32_t u32C = 0;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("TestOhciReads: %p iReg=%2d %20s = %08RX32\n", uPtr.pv, iReg, g_apszRegNms[iReg], uInitialValue));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (uint32_t iTry = 0; !fDone && iTry < 1024; iTry++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync pszError = NULL;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fDone = true;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32A = u32B = u32C = 0;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTCCUINTREG const fFlags = ASMIntDisableFlags();
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uInitialValue = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /* Test byte access. */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (unsigned iByte = 0; iByte < 4; iByte++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32A = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B = uPtr.pu8[iByte];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32C = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32A != uInitialValue || u32C != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fDone = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync static uint32_t const a_au32Masks[] =
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync UINT32_C(0xffffff00), UINT32_C(0xffff00ff), UINT32_C(0xff00ffff), UINT32_C(0x00ffffff)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync };
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B <<= iByte * 8;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B |= uInitialValue & a_au32Masks[iByte];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32B != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync static const char * const s_apsz[] = { "byte 0", "byte 1", "byte 2", "byte 3" };
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync pszError = s_apsz[iByte];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /* Test aligned word access. */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (fDone)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (unsigned iWord = 0; iWord < 2; iWord++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32A = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B = uPtr.pu16[iWord];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32C = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32A != uInitialValue || u32C != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fDone = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B <<= iWord * 16;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B |= uInitialValue & (iWord == 0 ? UINT32_C(0xffff0000) : UINT32_C(0x0000ffff));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32B != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync pszError = iWord == 0 ? "aligned word 0 access" : "aligned word 1 access";
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /* Test unaligned word access. */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (fDone)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (int iWord = ((uintptr_t)uPtr.pv & PAGE_OFFSET_MASK) == 0; iWord < 3; iWord++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32A = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B = *(volatile uint16_t *)&uPtr.pu8[iWord * 2 - 1];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32C = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32A != uInitialValue || u32C != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fDone = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync switch (iWord)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 0: u32B = (u32B >> 8) | (u32A & UINT32_C(0xffffff00)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 1: u32B = (u32B << 8) | (u32A & UINT32_C(0xff0000ff)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 2: u32B = (u32B << 24) | (u32A & UINT32_C(0x00ffffff)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32B != u32A)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync static const char * const s_apsz[] = { "unaligned word 0", "unaligned word 1", "unaligned word 2" };
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync pszError = s_apsz[iWord];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /* Test unaligned dword access. */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (fDone)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync for (int iByte = ((uintptr_t)uPtr.pv & PAGE_OFFSET_MASK) == 0 ? 0 : -3; iByte < 4; iByte++)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32A = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32B = *(volatile uint32_t *)&uPtr.pu8[iByte];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync u32C = *uPtr.pu32;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32A != uInitialValue || u32C != uInitialValue)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fDone = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync switch (iByte)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case -3: u32B = (u32B >> 24) | (uInitialValue & UINT32_C(0xffffff00)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case -2: u32B = (u32B >> 16) | (uInitialValue & UINT32_C(0xffff0000)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case -1: u32B = (u32B >> 8) | (uInitialValue & UINT32_C(0xff000000)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 0: break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 1: u32B = (u32B << 8) | (uInitialValue & UINT32_C(0x000000ff)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 2: u32B = (u32B << 16) | (uInitialValue & UINT32_C(0x0000ffff)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync case 3: u32B = (u32B << 24) | (uInitialValue & UINT32_C(0x00ffffff)); break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (u32B != u32A)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync static const char * const s_apsz[] =
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "unaligned dword -3", "unaligned dword -2", "unaligned dword -1",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync "unaligned dword 0", "unaligned dword 1", "unaligned dword 2", "unaligned dword 3"
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync };
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync pszError = s_apsz[iByte + 3];
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync break;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync ASMSetFlags(fFlags);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync ASMNopPause();
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync } /* try loop */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Complain on failure.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (!fDone)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("TestOhciReads: Warning! Register %s was never stable enough for testing! %08RX32 %08RX32 %08RX32\n",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync g_apszRegNms[iReg], uInitialValue, u32A, u32C));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync else if (pszError)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("TestOhciReads: Error! Register %s failed: %s; uInitialValue=%08RX32 u32B=%08RX32\n",
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync g_apszRegNms[iReg], pszError, uInitialValue, u32B));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fSuccess = false;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync return fSuccess;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync}
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsyncint tstOhciRegisterAccess(RTHCPHYS HCPhysOHCI)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync{
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: HCPhysOHCI=%RHp\n", HCPhysOHCI));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Map the OHCI registers so we can access them.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTR0MEMOBJ hMemObj;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync int rc = RTR0MemObjEnterPhys(&hMemObj, HCPhysOHCI, PAGE_SIZE, RTMEM_CACHE_POLICY_MMIO);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (RT_FAILURE(rc))
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: Failed to enter OHCI memory at %RHp: %Rrc\n", HCPhysOHCI, rc));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync return rc;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTR0MEMOBJ hMapObj;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync rc = RTR0MemObjMapKernel(&hMapObj, hMemObj, (void *)-1, 0 /*uAlignment*/, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (RT_SUCCESS(rc))
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTVPTRUNION uPtr;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync uPtr.pv = (void volatile *)RTR0MemObjAddress(hMapObj);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: mapping address %p\n", uPtr.pv));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (RT_VALID_PTR(uPtr.pv))
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync {
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: HcRevision=%#x\n", *uPtr.pu32));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Do the access tests.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync bool fSuccess = TestOhciReads(uPtr);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (fSuccess)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync fSuccess = TestOhciWrites(uPtr);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync if (fSuccess)
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: Success!\n"));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync else
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: Failed!\n"));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync else
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync rc = VERR_INTERNAL_ERROR_2;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync /*
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync * Clean up.
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync */
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTR0MemObjFree(hMapObj, false);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync }
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync else
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: Failed to map OHCI memory at %RHp: %Rrc\n", HCPhysOHCI, rc));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync RTR0MemObjFree(hMemObj, false);
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync LogRel(("tstOhciRegisterAccess: returns %Rrc\n", rc));
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync return rc;
cde46304e0c614aad7fd63abacb0180e4e83f24cvboxsync}