Beispiel #1
0
/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    PVM pVM = pDevIns->Internal.s.pVMR0;

    pdmLock(pVM);
    uint32_t uTagSrc;
    if (iLevel & PDM_IRQ_LEVEL_HIGH)
    {
        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
        if (iLevel == PDM_IRQ_LEVEL_HIGH)
            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
        else
            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    }
    else
        uTagSrc = pDevIns->Internal.s.uLastIrqTag;

    bool fRc = pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc);

    if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    pdmUnlock(pVM);
    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
}
Beispiel #2
0
bool WinAltGrMonitor::isCurrentEventDefinitelyFake(unsigned iDownScanCode,
                                                   bool fKeyDown,
                                                   bool fExtendedKey) const
{
    MSG peekMsg;
    LONG messageTime = GetMessageTime();

    if (   iDownScanCode != 0x1d /* scan code: Control */ || fExtendedKey)
        return false;
    if (!PeekMessage(&peekMsg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE))
        return false;

	if (messageTime != peekMsg.time)
	    return false;
	if (   fKeyDown
        && (peekMsg.message != WM_KEYDOWN && peekMsg.message != WM_SYSKEYDOWN))
        return false;
    if (   !fKeyDown
        && (peekMsg.message != WM_KEYUP && peekMsg.message != WM_SYSKEYUP))
        return false;
    if (   ((RT_HIWORD(peekMsg.lParam) & 0xFF) != 0x38 /* scan code: Alt */)
        || !(RT_HIWORD(peekMsg.lParam) & KF_EXTENDED))
        return false;
    if (!doesCurrentLayoutHaveAltGr())
        return false;
    return true;
}
/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
    PVM pVM = pDevIns->Internal.s.pVMR3;

    pdmLock(pVM);
    uint32_t uTagSrc;
    if (iLevel & PDM_IRQ_LEVEL_HIGH)
    {
        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
        if (iLevel == PDM_IRQ_LEVEL_HIGH)
            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
        else
            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    }
    else
        uTagSrc = pDevIns->Internal.s.uLastIrqTag;

    PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */

    if (iLevel == PDM_IRQ_LEVEL_LOW)
        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    pdmUnlock(pVM);
    return 0;
}
/**
 * @brief isSyntheticLCtrl
 * @param   pMsg  Windows WM_[SYS]KEY* event message structure
 * @return  true if this is a synthetic LCtrl event, false otherwise
 * This function is a heuristic to tell whether a key event is the first in
 * a synthetic LCtrl+RAlt sequence which Windows uses to signal AltGr.  Our
 * heuristic is in two parts.  First of all, we check whether there is a pending
 * RAlt key event matching this LCtrl event (i.e. both key up or both key down)
 * and if there is, we check whether the current layout has an AltGr key.  We
 * check this by looking to see if any of the layout-dependent keys has a symbol
 * associated when AltGr is pressed.
 */
static bool isSyntheticLCtrl(MSG *pMsg)
{
    MSG peekMsg;
    /** Keyboard state array with VK_CONTROL and VK_MENU depressed. */
    const BYTE auKeyStates[256] =
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x80 };
    WORD ach;
    unsigned i;

    Assert(   pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN
           || pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP);
    if (   ((RT_HIWORD(pMsg->lParam) & 0xFF) != 0x1d /* scan code: Control */)
        || RT_HIWORD(pMsg->lParam) & KF_EXTENDED)
        return false;
    if (!PeekMessage(&peekMsg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE))
        return false;
    if (   (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
        && (peekMsg.message != WM_KEYDOWN && peekMsg.message != WM_SYSKEYDOWN))
        return false;
    if (   (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
        && (peekMsg.message != WM_KEYUP && peekMsg.message != WM_SYSKEYUP))
        return false;
    if (   ((RT_HIWORD(peekMsg.lParam) & 0xFF) != 0x38 /* scan code: Alt */)
        || !(RT_HIWORD(peekMsg.lParam) & KF_EXTENDED))
        return false;
    /* If we got this far then we have a key event which could potentially
     * be a synthetic left control.  Now we check to see whether the current
     * keyboard layout actually has an AltGr key by checking whether any of
     * the keys which might do produce a symbol when AltGr (Control + Alt) is
     * depressed.  Generally this loop will exit pretty early (it exits on the
     * first iteration for my German layout).  If there is no AltGr key in the
     * layout then it will run right through, but that should not happen very
     * often as we should hardly ever reach the loop in that case.
     *
     * In theory we could do this once and cache the result, but that involves
     * tracking layout switches to invalidate the cache, and I don't think
     * that the added complexity is worth the price.
     */
    for (i = '0'; i <= VK_OEM_102; ++i)
    {
        if (ToAscii(i, 0, auKeyStates, &ach, 0))
            break;
        /* Skip ranges of virtual keys which are undefined or not relevant. */
        if (i == '9')
            i = 'A' - 1;
        if (i == 'Z')
            i = VK_OEM_1 - 1;
        if (i == VK_OEM_3)
            i = VK_OEM_4 - 1;
        if (i == VK_OEM_8)
            i = VK_OEM_102 - 1;
    }
    if (i > VK_OEM_102)
        return false;
    return true;
}
Beispiel #5
0
/**
 * Gets the pending interrupt.
 *
 * @returns VBox status code.
 * @param   pVCpu           Pointer to the VMCPU.
 * @param   pu8Interrupt    Where to store the interrupt on success.
 */
VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt)
{
    PVM pVM = pVCpu->CTX_SUFF(pVM);

    pdmLock(pVM);

    /*
     * The local APIC has a higher priority than the PIC.
     */
    if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC))
    {
        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
        Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
        uint32_t uTagSrc;
        int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu->idCpu, &uTagSrc);
        AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i));
        if (i >= 0)
        {
            pdmUnlock(pVM);
            *pu8Interrupt = (uint8_t)i;
            VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i);
            return VINF_SUCCESS;
        }
    }

    /*
     * Check the PIC.
     */
    if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC))
    {
        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
        Assert(pVM->pdm.s.Pic.CTX_SUFF(pDevIns));
        Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt));
        uint32_t uTagSrc;
        int i = pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), &uTagSrc);
        AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i));
        if (i >= 0)
        {
            pdmUnlock(pVM);
            *pu8Interrupt = (uint8_t)i;
            VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i);
            return VINF_SUCCESS;
        }
    }

    /** @todo Figure out exactly why we can get here without anything being set. (REM) */

    pdmUnlock(pVM);
    return VERR_NO_DATA;
}
Beispiel #6
0
/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    PVM          pVM     = pDevIns->Internal.s.pVMR0;
    PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
    PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;

    pdmLock(pVM);
    uint32_t uTagSrc;
    if (iLevel & PDM_IRQ_LEVEL_HIGH)
    {
        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
        if (iLevel == PDM_IRQ_LEVEL_HIGH)
            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
        else
            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    }
    else
        uTagSrc = pDevIns->Internal.s.uLastIrqTag;

    if (    pPciDev
        &&  pPciBus
        &&  pPciBus->pDevInsR0)
    {
        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc);

        pdmUnlock(pVM);

        if (iLevel == PDM_IRQ_LEVEL_LOW)
            VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    }
    else
    {
        pdmUnlock(pVM);

        /* queue for ring-3 execution. */
        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
        AssertReturnVoid(pTask);

        pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
        pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
        pTask->u.SetIRQ.iIrq = iIrq;
        pTask->u.SetIRQ.iLevel = iLevel;
        pTask->u.SetIRQ.uTagSrc = uTagSrc;

        PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
    }

    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
}
Beispiel #7
0
/**
 * @copydoc RTNetIPv6PseudoChecksumBits
 */
DECLINLINE(uint32_t) rtNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr,
                                                 uint8_t bProtocol, uint32_t cbPkt)
{
    uint32_t u32Sum = pSrcAddr->au16[0]
                    + pSrcAddr->au16[1]
                    + pSrcAddr->au16[2]
                    + pSrcAddr->au16[3]
                    + pSrcAddr->au16[4]
                    + pSrcAddr->au16[5]
                    + pSrcAddr->au16[6]
                    + pSrcAddr->au16[7]
                    + pDstAddr->au16[0]
                    + pDstAddr->au16[1]
                    + pDstAddr->au16[2]
                    + pDstAddr->au16[3]
                    + pDstAddr->au16[4]
                    + pDstAddr->au16[5]
                    + pDstAddr->au16[6]
                    + pDstAddr->au16[7]
                    + RT_H2BE_U16(RT_HIWORD(cbPkt))
                    + RT_H2BE_U16(RT_LOWORD(cbPkt))
                    + 0
                    + RT_H2BE_U16(RT_MAKE_U16(bProtocol, 0));
    return u32Sum;
}
Beispiel #8
0
/** @interface_method_impl{PDMAPICHLPR0,pfnCalcIrqTag} */
static DECLCALLBACK(uint32_t) pdmR0ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
{
    PDMDEV_ASSERT_DEVINS(pDevIns);
    PVM pVM = pDevIns->Internal.s.pVMR0;

    pdmLock(pVM);

    uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
    if (u8Level == PDM_IRQ_LEVEL_HIGH)
        VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    else
        VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));


    pdmUnlock(pVM);
    LogFlow(("pdmR0ApicHlp_CalcIrqTag: caller=%p/%d: returns %#x (u8Level=%d)\n",
             pDevIns, pDevIns->iInstance, uTagSrc, u8Level));
    return uTagSrc;
}