PDMAll.cpp revision 13cf6cf8e0bca3f99b5c122d775bdbffde41e4b6
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * PDM Critical Sections
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * available from http://www.virtualbox.org. This file is free software;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * you can redistribute it and/or modify it under the terms of the GNU
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * General Public License (GPL) as published by the Free Software
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * additional information or have any questions.
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync/*******************************************************************************
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync* Header Files *
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync*******************************************************************************/
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Gets the pending interrupt.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @returns VBox status code.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param pVCpu VMCPU handle.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param pu8Interrupt Where to store the interrupt on success.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncVMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt)
9939c713bffcfc4305d99d994552aa2ad9bce097vboxsync * The local APIC has a higer priority than the PIC.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC))
c2046db2cc346cc299f0cd9b2d1e160179159cfcvboxsync int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
c2046db2cc346cc299f0cd9b2d1e160179159cfcvboxsync if (i >= 0)
2d8870843ff566fee9bd3a6a5942414254106479vboxsync * Check the PIC.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync int i = pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns));
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (i >= 0)
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** @todo Figure out exactly why we can get here without anything being set. (REM) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Sets the pending interrupt.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @returns VBox status code.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param pVM VM handle.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param u8Irq The IRQ line.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param u8Level The new level.
044af0d1e6474076366759db86f101778c5f20ccvboxsyncVMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level)
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), u8Irq, u8Level);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level);
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Sets the pending I/O APIC interrupt.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @returns VBox status code.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param pVM VM handle.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param u8Irq The IRQ line.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param u8Level The new level.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncVMMDECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Returns presence of an IO-APIC
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * @returns VBox true if IO-APIC is present
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pVM VM handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return pVM->pdm.s.IoApic.CTX_SUFF(pDevIns) != NULL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Set the APIC base.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @returns VBox status code.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @param pVM VM handle.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param u64Base The new base.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncVMMDECL(int) PDMApicSetBase(PVM pVM, uint64_t u64Base)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pVM->pdm.s.Apic.CTX_SUFF(pfnSetBase)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), u64Base);
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Get the APIC base.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * @returns VBox status code.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param pVM VM handle.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pu64Base Where to store the APIC base.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncVMMDECL(int) PDMApicGetBase(PVM pVM, uint64_t *pu64Base)
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsync *pu64Base = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBase)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsync * Check if the APIC has a pending interrupt/if a TPR change would active one.
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsync * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsync * @param pDevIns Device instance of the APIC.
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsync * @param pfPending Pending state (out).
7d80dfbe5d66fc4c6de6fe109ce96a081496dcd4vboxsyncVMMDECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending)
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Set the TPR (task priority register).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VBox status code.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVCpu VMCPU handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param u8TPR The new TPR.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param fMMIOFormat Update as if MMIO write to ApicBase + 0x80
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicSetTPREx(PVMCPU pVCpu, uint8_t u8TPR, bool fMMIOFormat)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync pVM->pdm.s.Apic.CTX_SUFF(pfnSetTPR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu->idCpu, u8TPR, fMMIOFormat);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Set the TPR (task priority register).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VBox status code.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVCpu VMCPU handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param u8TPR The new TPR.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync return PDMApicSetTPREx(pVCpu, u8TPR, false /* TPR only */);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Get the TPR (task priority register).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns The current TPR.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVCpu VMCPU handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pu8TPR Where to store the TRP.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param fMMIOFormat Return as if MMIO read from ApicBase + 0x80
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pfPending Pending interrupt state (out).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicGetTPREx(PVMCPU pVCpu, uint8_t *pu8TPR, bool fMMIOFormat, bool *pfPending)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTPR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu->idCpu, fMMIOFormat);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Get the TPR (task priority register).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns The current TPR.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVCpu VMCPU handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pu8TPR Where to store the TRP.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pfPending Pending interrupt state (out).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync return PDMApicGetTPREx(pVCpu, pu8TPR, false /* TPR only */, pfPending);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Write MSR in APIC range.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VBox status code.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param iCpu Target CPU.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param u32Reg MSR to write.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param u64Value Value to write.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync * Read MSR in APIC range.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VBox status code.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param iCpu Target CPU.
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync * @param u32Reg MSR to read.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pu64Value Value read.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Locks PDM.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * This might call back to Ring-3 in order to deal with lock contention in GC and R3.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM The VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync int rc = PDMCritSectEnter(&pVM->pdm.s.CritSect, VERR_INTERNAL_ERROR);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync int rc = PDMCritSectEnter(&pVM->pdm.s.CritSect, VERR_GENERAL_FAILURE);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Locks PDM but don't go to ring-3 if it's owned by someone.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VINF_SUCCESS on success.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns rc if we're in GC or R0 and can't get the lock.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM The VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param rc The RC to return in GC or R0 when we can't get the lock.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Unlocks PDM.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM The VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Converts ring 3 VMM heap pointer to a guest physical address
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VBox status code.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pVM VM handle.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pv Ring-3 pointer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pGCPhys GC phys address (out).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncVMMDECL(int) PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(pv >= pVM->pdm.s.pvVMMDevHeap && (RTR3UINTPTR)pv < (RTR3UINTPTR)pVM->pdm.s.pvVMMDevHeap + pVM->pdm.s.cbVMMDevHeap, VERR_INVALID_PARAMETER);
d6f8b76ab3b2ec0c270c96f9db6e2568fc41b5fevboxsync *pGCPhys = (pVM->pdm.s.GCPhysVMMDevHeap + ((RTR3UINTPTR)pv - (RTR3UINTPTR)pVM->pdm.s.pvVMMDevHeap));