Files
yttrium-virtio-gpu/NetKVM/Common/ParaNdis-CX.cpp
T
Sameeh Jubran 2cc38bac81 NetKVM: Integrate WPP Tracing
This commit integrates wpp tracing into builds higher than Vista as
Windows Vista requires much more configuration for wpp integration,
however, this integration may be introduced in the future.

The old style of Dprintf is still preserved by this commit and can be
enabled by disabling WPP tracing. This can be accomplished by commenting
the following line in WPPTrace.h:

Signed-off-by: Sameeh Jubran <[email protected]>
2017-12-12 21:53:43 +02:00

142 lines
4.1 KiB
C++

#include "ndis56common.h"
#include "virtio_net.h"
#include "kdebugprint.h"
#include "Trace.h"
#ifdef NETKVM_WPP_ENABLED
#include "ParaNdis-CX.tmh"
#endif
CParaNdisCX::CParaNdisCX()
{
m_ControlData.Virtual = nullptr;
}
CParaNdisCX::~CParaNdisCX()
{
if (m_ControlData.Virtual != nullptr)
{
ParaNdis_FreePhysicalMemory(m_Context, &m_ControlData);
}
}
bool CParaNdisCX::Create(PPARANDIS_ADAPTER Context, UINT DeviceQueueIndex)
{
m_Context = Context;
m_queueIndex = (u16)DeviceQueueIndex;
if (!ParaNdis_InitialAllocatePhysicalMemory(m_Context, 512, &m_ControlData))
{
DPrintf(0, "CParaNdisCX::Create - ParaNdis_InitialAllocatePhysicalMemory failed for %u\n",
DeviceQueueIndex);
m_ControlData.Virtual = nullptr;
return false;
}
m_Context->m_CxStateMachine.Start();
return m_VirtQueue.Create(DeviceQueueIndex,
&m_Context->IODevice,
m_Context->MiniportHandle);
}
BOOLEAN CParaNdisCX::SendControlMessage(
UCHAR cls,
UCHAR cmd,
PVOID buffer1,
ULONG size1,
PVOID buffer2,
ULONG size2,
int levelIfOK
)
{
BOOLEAN bOK = FALSE;
CLockedContext<CNdisSpinLock> autoLock(m_Lock);
if (m_ControlData.Virtual && m_ControlData.size > (size1 + size2 + 16))
{
struct VirtIOBufferDescriptor sg[4];
PUCHAR pBase = (PUCHAR)m_ControlData.Virtual;
PHYSICAL_ADDRESS phBase = m_ControlData.Physical;
ULONG offset = 0;
UINT nOut = 1;
((virtio_net_ctrl_hdr *)pBase)->class_of_command = cls;
((virtio_net_ctrl_hdr *)pBase)->cmd = cmd;
sg[0].physAddr = phBase;
sg[0].length = sizeof(virtio_net_ctrl_hdr);
offset += sg[0].length;
offset = (offset + 3) & ~3;
if (size1)
{
NdisMoveMemory(pBase + offset, buffer1, size1);
sg[nOut].physAddr = phBase;
sg[nOut].physAddr.QuadPart += offset;
sg[nOut].length = size1;
offset += size1;
offset = (offset + 3) & ~3;
nOut++;
}
if (size2)
{
NdisMoveMemory(pBase + offset, buffer2, size2);
sg[nOut].physAddr = phBase;
sg[nOut].physAddr.QuadPart += offset;
sg[nOut].length = size2;
offset += size2;
offset = (offset + 3) & ~3;
nOut++;
}
sg[nOut].physAddr = phBase;
sg[nOut].physAddr.QuadPart += offset;
sg[nOut].length = sizeof(virtio_net_ctrl_ack);
*(virtio_net_ctrl_ack *)(pBase + offset) = VIRTIO_NET_ERR;
if (0 <= m_VirtQueue.AddBuf(sg, nOut, 1, (PVOID)1, NULL, 0))
{
UINT len;
m_Context->m_CxStateMachine.RegisterOutstandingItem();
m_VirtQueue.Kick();
while (!m_VirtQueue.GetBuf(&len))
{
UINT interval = 1;
NdisStallExecution(interval);
}
m_Context->m_CxStateMachine.UnregisterOutstandingItem();
if (len != sizeof(virtio_net_ctrl_ack))
{
DPrintf(0, "%s - ERROR: wrong len %d\n", __FUNCTION__, len);
}
else if (*(virtio_net_ctrl_ack *)(pBase + offset) != VIRTIO_NET_OK)
{
DPrintf(0, "%s - ERROR: error %d returned for class %d\n", __FUNCTION__, *(virtio_net_ctrl_ack *)(pBase + offset), cls);
}
else
{
// everything is OK
DPrintf(levelIfOK, "%s OK(%d.%d,buffers of %d and %d) \n", __FUNCTION__, cls, cmd, size1, size2);
bOK = TRUE;
}
}
else
{
DPrintf(0, "%s - ERROR: add_buf failed\n", __FUNCTION__);
}
}
else
{
DPrintf(0, "%s (buffer %d,%d) - ERROR: message too LARGE\n", __FUNCTION__, size1, size2);
}
return bOK;
}
NDIS_STATUS CParaNdisCX::SetupMessageIndex(u16 vector)
{
DPrintf(0, "[%s] Using message %u for controls\n", __FUNCTION__, vector);
virtio_set_config_vector(&m_Context->IODevice, vector);
return CParaNdisAbstractPath::SetupMessageIndex(vector);
}