int VirtualKDPortOutHandler( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb ) { struct { unsigned RequestSize; unsigned MaxReplySize; } RequestHeader = {0, }; static char CmdBody[262144]; if (Port == 0x5659) { int rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)u32, &RequestHeader, sizeof(RequestHeader)); if (!RT_SUCCESS(rc) || !RequestHeader.RequestSize) return VINF_SUCCESS; rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)(u32 + sizeof(RequestHeader)), CmdBody, RequestHeader.RequestSize); if (!RT_SUCCESS(rc)) return VINF_SUCCESS; ASSERT(!memcmp(CmdBody, g_szRPCCommandHeader, sizeof(g_szRPCCommandHeader) - 1)); char *pReply = NULL; #ifdef KDVMWARE_USE_PROXY unsigned done = KDRPCProxyHandler(CmdBody + sizeof(g_szRPCCommandHeader) - 1, RequestHeader.RequestSize - (sizeof(g_szRPCCommandHeader) - 1), &pReply); #else unsigned done = KDRPCDirectHandler(CmdBody + sizeof(g_szRPCCommandHeader) - 1, RequestHeader.RequestSize - (sizeof(g_szRPCCommandHeader) - 1), &pReply); #endif if (!pReply) done = 0; char Prefix[sizeof(done) + 2]; ((unsigned *)Prefix)[0] = done + 2; Prefix[sizeof(unsigned)] = '1'; Prefix[sizeof(unsigned) + 1] = ' '; rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)u32, Prefix, sizeof(Prefix)); if (!RT_SUCCESS(rc)) return VINF_SUCCESS; if (done) { rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)(u32 + sizeof(Prefix)), pReply, done); if (!RT_SUCCESS(rc)) return VINF_SUCCESS; } return VINF_SUCCESS; } else { if ((Port == 0x5658) && (u32 == 0x564D5868)) s_bVMWareOpenChannelDetected = true; else s_bVMWareOpenChannelDetected = false; return VINF_SUCCESS; } }
void vqueuePut(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t uLen, uint32_t uReserved) { unsigned int i, uOffset, cbReserved = uReserved; Log2(("%s vqueuePut: %s desc_idx=%u acb=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pElem->uIndex, uLen)); for (i = uOffset = 0; i < pElem->nIn && uOffset < uLen - uReserved; i++) { uint32_t cbSegLen = RT_MIN(uLen - cbReserved - uOffset, pElem->aSegsIn[i].cb - cbReserved); if (pElem->aSegsIn[i].pv) { Log2(("%s vqueuePut: %s used_idx=%u seg=%u addr=%p pv=%p cb=%u acb=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pQueue->uNextUsedIndex, i, pElem->aSegsIn[i].addr, pElem->aSegsIn[i].pv, pElem->aSegsIn[i].cb, cbSegLen)); PDMDevHlpPhysWrite(pState->CTX_SUFF(pDevIns), pElem->aSegsIn[i].addr + cbReserved, pElem->aSegsIn[i].pv, cbSegLen); cbReserved = 0; } uOffset += cbSegLen; } Assert((uReserved + uOffset) == uLen || pElem->nIn == 0); Log2(("%s vqueuePut: %s used_idx=%u guest_used_idx=%u id=%u len=%u\n", INSTANCE(pState), QUEUENAME(pState, pQueue), pQueue->uNextUsedIndex, vringReadUsedIndex(pState, &pQueue->VRing), pElem->uIndex, uLen)); vringWriteUsedElem(pState, &pQueue->VRing, pQueue->uNextUsedIndex++, pElem->uIndex, uLen); }
/** * Construct the SMBIOS and DMI headers table pointer at VM construction and * reset. * * @param pDevIns The device instance data. */ void FwCommonPlantSmbiosAndDmiHdrs(PPDMDEVINS pDevIns) { struct { struct SMBIOSHDR smbios; struct DMIMAINHDR dmi; } aBiosHeaders = { // The SMBIOS header { { 0x5f, 0x53, 0x4d, 0x5f}, // "_SM_" signature 0x00, // checksum 0x1f, // EPS length, defined by standard VBOX_SMBIOS_MAJOR_VER, // SMBIOS major version VBOX_SMBIOS_MINOR_VER, // SMBIOS minor version VBOX_SMBIOS_MAXSS, // Maximum structure size 0x00, // Entry point revision { 0x00, 0x00, 0x00, 0x00, 0x00 } // padding }, // The DMI header { { 0x5f, 0x44, 0x4d, 0x49, 0x5f }, // "_DMI_" signature 0x00, // checksum VBOX_DMI_TABLE_SIZE, // DMI tables length VBOX_DMI_TABLE_BASE, // DMI tables base VBOX_DMI_TABLE_ENTR, // DMI tables entries VBOX_DMI_TABLE_VER, // DMI version } }; aBiosHeaders.smbios.u8Checksum = fwCommonChecksum((uint8_t*)&aBiosHeaders.smbios, sizeof(aBiosHeaders.smbios)); aBiosHeaders.dmi.u8Checksum = fwCommonChecksum((uint8_t*)&aBiosHeaders.dmi, sizeof(aBiosHeaders.dmi)); PDMDevHlpPhysWrite(pDevIns, 0xfe300, &aBiosHeaders, sizeof(aBiosHeaders)); }
void vringWriteUsedElem(PVPCISTATE pState, PVRING pVRing, uint32_t uIndex, uint32_t uId, uint32_t uLen) { VRINGUSEDELEM elem; elem.uId = uId; elem.uLen = uLen; PDMDevHlpPhysWrite(pState->CTX_SUFF(pDevIns), pVRing->addrUsed + RT_OFFSETOF(VRINGUSED, aRing[uIndex % pVRing->uSize]), &elem, sizeof(elem)); }
void vringSetNotification(PVPCISTATE pState, PVRING pVRing, bool fEnabled) { uint16_t tmp; PDMDevHlpPhysRead(pState->CTX_SUFF(pDevIns), pVRing->addrUsed + RT_OFFSETOF(VRINGUSED, uFlags), &tmp, sizeof(tmp)); if (fEnabled) tmp &= ~ VRINGUSED_F_NO_NOTIFY; else tmp |= VRINGUSED_F_NO_NOTIFY; PDMDevHlpPhysWrite(pState->CTX_SUFF(pDevIns), pVRing->addrUsed + RT_OFFSETOF(VRINGUSED, uFlags), &tmp, sizeof(tmp)); }
/** * Construct the MPS table pointer at VM construction and reset. * * Only applicable if IOAPIC is active! * * @param pDevIns The device instance data. */ void FwCommonPlantMpsFloatPtr(PPDMDEVINS pDevIns) { MPSFLOATPTR floatPtr; floatPtr.au8Signature[0] = '_'; floatPtr.au8Signature[1] = 'M'; floatPtr.au8Signature[2] = 'P'; floatPtr.au8Signature[3] = '_'; floatPtr.u32MPSAddr = VBOX_MPS_TABLE_BASE; floatPtr.u8Length = 1; /* structure size in paragraphs */ floatPtr.u8SpecRev = 4; /* MPS revision 1.4 */ floatPtr.u8Checksum = 0; floatPtr.au8Feature[0] = 0; floatPtr.au8Feature[1] = 0; floatPtr.au8Feature[2] = 0; floatPtr.au8Feature[3] = 0; floatPtr.au8Feature[4] = 0; floatPtr.u8Checksum = fwCommonChecksum((uint8_t*)&floatPtr, 16); PDMDevHlpPhysWrite(pDevIns, 0x9fff0, &floatPtr, 16); }
void vringWriteUsedIndex(PVPCISTATE pState, PVRING pVRing, uint16_t u16Value) { PDMDevHlpPhysWrite(pState->CTX_SUFF(pDevIns), pVRing->addrUsed + RT_OFFSETOF(VRINGUSED, uIndex), &u16Value, sizeof(u16Value)); }