示例#1
0
/**
 * Reads a key by name from the host SMC.
 *
 * @returns success indicator.
 * @param   pszName             The key name, must be exactly 4 chars long.
 * @param   pbBuf               The output buffer.
 * @param   cbBuf               The buffer size. Max 32 bytes.
 */
static bool devR0SmcQueryHostKey(const char *pszName, uint8_t *pbBuf, size_t cbBuf)
{
    Assert(strlen(pszName) == 4);
    Assert(cbBuf <= 32);
    Assert(cbBuf > 0);

    /*
     * Issue the READ command.
     */
    uint32_t cMsSleep = 1;
    for (;;)
    {
        ASMOutU32(SMC_PORT_CMD, SMC_CMD_GET_KEY_VALUE);
        RTThreadSleep(cMsSleep);
        uint8_t bCurState = ASMInU8(SMC_PORT_CMD);
        if ((bCurState & 0xf) == 0xc)
            break;
        cMsSleep <<= 1;
        if (cMsSleep > 64)
        {
            LogRel(("devR0Smc: %s: bCurState=%#x, wanted %#x.\n", "cmd", bCurState, 0xc));
            return false;
        }
    }

    /*
     * Send it the key.
     */
    for (unsigned off = 0; off < 4; off++)
    {
        ASMOutU8(SMC_PORT_DATA, pszName[off]);
        if (!devR0SmcWaitHostState(4, "key"))
            return false;
    }

    /*
     * The desired amount of output.
     */
    ASMOutU8(SMC_PORT_DATA, (uint8_t)cbBuf);

    /*
     * Read the output.
     */
    for (size_t off = 0; off < cbBuf; off++)
    {
        if (!devR0SmcWaitHostState(5, off ? "data" : "len"))
            return false;
        pbBuf[off] = ASMInU8(SMC_PORT_DATA);
    }

    LogRel(("SMC: pbBuf=%.*s\n", cbBuf, pbBuf));
    return true;
}
示例#2
0
static UINT32 VBoxReadNVRAM(UINT8 *pu8Buffer, UINT32 cbBuffer)
{
    UINT32 idxBuffer = 0;
    for (idxBuffer = 0; idxBuffer < cbBuffer; ++idxBuffer)
        pu8Buffer[idxBuffer] = ASMInU8(EFI_VARIABLE_OP);
    return idxBuffer;
}
/**
 * R0 mode function to ready byte value from the parallel port
 * status register.
 * @returns VBox status code.
 * @param   pDrvIns    Driver instance.
 * @param   u64Arg     Not used.
 */
static int drvR0HostParallelReqReadStatus(PPDMDRVINS pDrvIns, uint64_t u64Arg)
{
    uint8_t u8Data;
    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    u8Data = ASMInU8(pThis->u32LptAddrStatus);
    LogFlowFunc(("read from status port=%#x val=%#x\n", pThis->u32LptAddr, u8Data));
    pThis->u8ReadInStatus = u8Data;
    return VINF_SUCCESS;
}
示例#4
0
/**
 * RTOnce callback that initializes g_fHaveOsk and g_abOsk0And1.
 *
 * @returns VINF_SUCCESS.
 * @param   pvUserIgnored     Ignored.
 */
static DECLCALLBACK(int) devR0SmcInitOnce(void *pvUserIgnored)
{
    g_fHaveOsk = devR0SmcQueryHostKey("OSK0", &g_abOsk0And1[0],  32)
              && devR0SmcQueryHostKey("OSK1", &g_abOsk0And1[32], 32);

#if 0
    /*
     * Dump the device registers.
     */
    for (uint16_t uPort = 0x300; uPort < 0x320; uPort ++)
        LogRel(("SMC: %#06x=%#010x w={%#06x, %#06x}, b={%#04x %#04x %#04x %#04x}\n", uPort,
                ASMInU32(uPort), ASMInU16(uPort), ASMInU16(uPort + 2),
                ASMInU8(uPort), ASMInU8(uPort + 1), ASMInU8(uPort +2), ASMInU8(uPort + 3) ));
#endif

    NOREF(pvUserIgnored);
    return VINF_SUCCESS;
}
示例#5
0
/**
 * Try undo the harm done by the init function.
 *
 * This may leave the system in an unstable state since we might have been
 * hijacking memory below 1MB that is in use by the kernel.
 */
void vmmR0TripleFaultHackTerm(void)
{
    /*
     * Restore overwritten memory.
     */
    if (   g_pvSavedLowCore
        && g_pbLowCore)
        memcpy(g_pbLowCore, g_pvSavedLowCore, PAGE_SIZE);

    if (g_pbPage0)
    {
        g_pbPage0[0x467+0] = RT_BYTE1(g_u32SavedVector);
        g_pbPage0[0x467+1] = RT_BYTE2(g_u32SavedVector);
        g_pbPage0[0x467+2] = RT_BYTE3(g_u32SavedVector);
        g_pbPage0[0x467+3] = RT_BYTE4(g_u32SavedVector);

        g_pbPage0[0x472+0] = RT_BYTE1(g_u16SavedCadIndicator);
        g_pbPage0[0x472+1] = RT_BYTE2(g_u16SavedCadIndicator);
    }

    /*
     * Fix the CMOS.
     */
    if (g_pvSavedLowCore)
    {
        uint32_t fSaved = ASMIntDisableFlags();

        ASMOutU8(0x70, 0x0f);
        ASMOutU8(0x71, 0x0a);

        ASMOutU8(0x70, 0x00);
        ASMInU8(0x71);

        ASMReloadCR3();
        ASMWriteBackAndInvalidateCaches();

        ASMSetFlags(fSaved);
    }

    /*
     * Release resources.
     */
    RTMemFree(g_pvSavedLowCore);
    g_pvSavedLowCore = NULL;

    RTR0MemObjFree(g_hMemLowCore, true /*fFreeMappings*/);
    g_hMemLowCore   = NIL_RTR0MEMOBJ;
    g_hMapLowCore   = NIL_RTR0MEMOBJ;
    g_pbLowCore     = NULL;
    g_HCPhysLowCore = NIL_RTHCPHYS;

    RTR0MemObjFree(g_hMemPage0, true /*fFreeMappings*/);
    g_hMemPage0     = NIL_RTR0MEMOBJ;
    g_hMapPage0     = NIL_RTR0MEMOBJ;
    g_pbPage0       = NULL;
}
/**
 * R0 mode function to set the direction of parallel port -
 * operate in bidirectional mode or single direction.
 * @returns VBox status code.
 * @param   pDrvIns    Driver instance.
 * @param   u64Arg     Mode.
 */
static int drvR0HostParallelReqSetPortDir(PPDMDRVINS pDrvIns, uint64_t u64Arg)
{
    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    uint8_t u8ReadControlVal;
    uint8_t u8WriteControlVal;

    if (u64Arg)
    {
       u8ReadControlVal = ASMInU8(pThis->u32LptAddrControl);
       u8WriteControlVal = u8ReadControlVal | LPT_CONTROL_ENABLE_BIDIRECT; /* enable input direction */
       ASMOutU8(pThis->u32LptAddrControl, u8WriteControlVal);
    }
    else
    {
        u8ReadControlVal = ASMInU8(pThis->u32LptAddrControl);
        u8WriteControlVal = u8ReadControlVal & ~LPT_CONTROL_ENABLE_BIDIRECT; /* disable input direction */
        ASMOutU8(pThis->u32LptAddrControl, u8WriteControlVal);
    }
    return VINF_SUCCESS;
}
示例#7
0
/**
 * Waits for the specified state on the host SMC.
 *
 * @returns success indicator.
 * @param   bState              The desired state.
 * @param   pszWhat             What we're currently doing. For the log.
 */
static bool devR0SmcWaitHostState(uint8_t bState, const char *pszWhat)
{
    uint8_t bCurState;
    for (uint32_t cMsSleep = 1; cMsSleep <= 64; cMsSleep <<= 1)
    {
        RTThreadSleep(cMsSleep);
        bCurState = ASMInU16(SMC_PORT_CMD);
        if ((bCurState & 0xf) == bState)
            return true;
    }

    LogRel(("devR0Smc: %s: bCurState=%#x, wanted %#x.\n", pszWhat, bCurState, bState));
#if 0
    uint8_t  bCurStatus2 = ASMInU8(SMC_PORT_STATUS_CODE);
    uint8_t  bCurStatus3 = ASMInU8(SMC_PORT_STATUS_CODE);
    uint16_t wCurStatus3 = ASMInU16(SMC_PORT_STATUS_CODE);
    uint32_t dwCurStatus3 = ASMInU32(SMC_PORT_STATUS_CODE);
    LogRel(("SMC: status2=%#x status3=%#x w=%#x dw=%#x\n", bCurStatus2, bCurStatus3, wCurStatus3, dwCurStatus3));
#endif
    return false;
}
示例#8
0
/**
 * Waits for the specified status on the host SMC.
 *
 * @returns success indicator.
 * @param   bStatus             The desired status.
 * @param   pszWhat             What we're currently doing. For the log.
 */
static bool devR0SmcWaitHostStatus(uint8_t bStatus, const char *pszWhat)
{
    uint8_t bCurStatus;
    for (uint32_t cMsSleep = 1; cMsSleep <= 64; cMsSleep <<= 1)
    {
        RTThreadSleep(cMsSleep);
        bCurStatus = ASMInU8(APPLESMC_CMD_PORT);
        if ((bCurStatus & 0xf) == bStatus)
            return true;
    }

    LogRel(("devR0Smc: %s: bCurStatus=%#x, wanted %#x.\n", pszWhat, bCurStatus, bStatus));
    return false;
}
示例#9
0
/*
 *   Internal Functions                                                        *
 */
static UINT32
GetVmVariable(UINT32 Variable, CHAR8* Buffer, UINT32 Size )
{
    UINT32 VarLen, i;


    ASMOutU32(EFI_INFO_PORT, Variable);
    VarLen = ASMInU32(EFI_INFO_PORT);

    for (i=0; i < VarLen && i < Size; i++)
    {
        Buffer[i] = ASMInU8(EFI_INFO_PORT);
    }

    return VarLen;
}
示例#10
0
/**
 * Initalizes the triple fault / boot hack.
 *
 * Always call vmmR0TripleFaultHackTerm to clean up, even when this call fails.
 *
 * @returns VBox status code.
 */
int vmmR0TripleFaultHackInit(void)
{
    /*
     * Map the first page.
     */
    int rc = RTR0MemObjEnterPhys(&g_hMemPage0, 0, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE);
    AssertRCReturn(rc, rc);
    rc = RTR0MemObjMapKernel(&g_hMapPage0, g_hMemPage0, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
    AssertRCReturn(rc, rc);
    g_pbPage0 = (uint8_t *)RTR0MemObjAddress(g_hMapPage0);
    LogRel(("0040:0067 = %04x:%04x\n", RT_MAKE_U16(g_pbPage0[0x467+2],  g_pbPage0[0x467+3]),  RT_MAKE_U16(g_pbPage0[0x467+0],  g_pbPage0[0x467+1]) ));

    /*
     * Allocate some "low core" memory.  If that fails, just grab some memory.
     */
    //rc = RTR0MemObjAllocPhys(&g_hMemLowCore, PAGE_SIZE, _1M - 1);
    //__debugbreak();
    rc = RTR0MemObjEnterPhys(&g_hMemLowCore, 0x7000, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE);
    AssertRCReturn(rc, rc);
    rc = RTR0MemObjMapKernel(&g_hMapLowCore, g_hMemLowCore, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
    AssertRCReturn(rc, rc);
    g_pbLowCore = (uint8_t *)RTR0MemObjAddress(g_hMapLowCore);
    g_HCPhysLowCore = RTR0MemObjGetPagePhysAddr(g_hMapLowCore, 0);
    LogRel(("Low core at %RHp mapped at %p\n", g_HCPhysLowCore, g_pbLowCore));

    /*
     * Save memory we'll be overwriting.
     */
    g_pvSavedLowCore = RTMemAlloc(PAGE_SIZE);
    AssertReturn(g_pvSavedLowCore, VERR_NO_MEMORY);
    memcpy(g_pvSavedLowCore, g_pbLowCore, PAGE_SIZE);

    g_u32SavedVector = RT_MAKE_U32_FROM_U8(g_pbPage0[0x467], g_pbPage0[0x467+1], g_pbPage0[0x467+2], g_pbPage0[0x467+3]);
    g_u16SavedCadIndicator = RT_MAKE_U16(g_pbPage0[0x472], g_pbPage0[0x472+1]);

    /*
     * Install the code.
     */
    size_t cbCode = (uintptr_t)&vmmR0TripleFaultHackEnd - (uintptr_t)&vmmR0TripleFaultHackStart;
    AssertLogRelReturn(cbCode <= PAGE_SIZE, VERR_OUT_OF_RANGE);
    memcpy(g_pbLowCore, &vmmR0TripleFaultHackStart, cbCode);

    g_pbPage0[0x467+0] = 0x00;
    g_pbPage0[0x467+1] = 0x70;
    g_pbPage0[0x467+2] = 0x00;
    g_pbPage0[0x467+3] = 0x00;

    g_pbPage0[0x472+0] = 0x34;
    g_pbPage0[0x472+1] = 0x12;

    /*
     * Configure the status port and cmos shutdown command.
     */
    uint32_t fSaved = ASMIntDisableFlags();

    ASMOutU8(0x70, 0x0f);
    ASMOutU8(0x71, 0x0a);

    ASMOutU8(0x70, 0x05);
    ASMInU8(0x71);

    ASMReloadCR3();
    ASMWriteBackAndInvalidateCaches();

    ASMSetFlags(fSaved);

#if 1 /* For testing & debugging. */
    vmmR0TripleFaultHackTripleFault();
#endif

    return VINF_SUCCESS;
}