summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnon Gilboa <agilboa@redhat.com>2013-06-05 09:06:12 +0300
committerYonit Halperin <yhalperi@redhat.com>2013-06-05 01:58:16 -0400
commitdefd02b8a4f18ac5fab92657706009a7122e7e37 (patch)
treef33cde8103b0418144d541863fa85c2410308862
parentaa24bbee0bf6ef115bf7339c95c2b4901a681304 (diff)
add rings and events
-rw-r--r--C++/Sample/SampleDisplay.vcxproj1
-rw-r--r--C++/bdd.cxx82
-rw-r--r--C++/bdd.hxx15
3 files changed, 98 insertions, 0 deletions
diff --git a/C++/Sample/SampleDisplay.vcxproj b/C++/Sample/SampleDisplay.vcxproj
index 4b5c724..23a8989 100644
--- a/C++/Sample/SampleDisplay.vcxproj
+++ b/C++/Sample/SampleDisplay.vcxproj
@@ -91,6 +91,7 @@
<WarningLevel>Level4</WarningLevel>
<ExceptionHandling>
</ExceptionHandling>
+ <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|Win32'">false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/C++/bdd.cxx b/C++/bdd.cxx
index 5fd84f4..2b763d7 100644
--- a/C++/bdd.cxx
+++ b/C++/bdd.cxx
@@ -13,6 +13,59 @@
#pragma code_seg("PAGE")
+// TODO: consider threading levels (interrupt related, cursor)
+// http://msdn.microsoft.com/en-us/library/windows/hardware/ff569957%28v=vs.85%29.aspx
+
+VOID BASIC_DISPLAY_DRIVER::push_display_cmd()
+{
+ int notify;
+ SPICE_RING_PUSH(m_display_ring, notify);
+ if (notify) {
+ QxlWritePortUchar(QXL_IO_NOTIFY_CMD, 0);
+ }
+}
+
+VOID BASIC_DISPLAY_DRIVER::push_cursor_cmd()
+{
+ int notify;
+ SPICE_RING_PUSH(m_cursor_ring, notify);
+ if (notify) {
+ QxlWritePortUchar(QXL_IO_NOTIFY_CURSOR, 0);
+ }
+}
+
+VOID BASIC_DISPLAY_DRIVER::wait_for_display_cmd()
+{
+ int wait;
+
+ //LogMessage("%s\n", __FUNCTION__);
+ for (;;) {
+ SPICE_RING_PROD_WAIT(m_display_ring, wait);
+
+ if (!wait) {
+ break;
+ }
+ //FIXME: support surprise removal? (WHQL)
+ KeWaitForSingleObject(m_display_event, Executive, KernelMode, TRUE, NULL);
+ }
+}
+
+VOID BASIC_DISPLAY_DRIVER::wait_for_cursor_cmd()
+{
+ int wait;
+
+ //LogMessage("%s\n", __FUNCTION__);
+ for (;;) {
+ SPICE_RING_PROD_WAIT(m_cursor_ring, wait);
+
+ if (!wait) {
+ break;
+ }
+ //FIXME: support surprise removal? (WHQL)
+ KeWaitForSingleObject(m_cursor_event, Executive, KernelMode, TRUE, NULL);
+ }
+}
+
BASIC_DISPLAY_DRIVER::BASIC_DISPLAY_DRIVER(_In_ DEVICE_OBJECT* pPhysicalDeviceObject) : m_pPhysicalDevice(pPhysicalDeviceObject),
m_MonitorPowerState(PowerDeviceD0),
@@ -174,6 +227,11 @@ NTSTATUS BASIC_DISPLAY_DRIVER::QxlInitRam()
(UINT8 *)m_mem_regions[QXL_RAM_RANGE_INDEX].mapped_start + m_rom->surface0_area_size,
m_rom->num_pages * PAGE_SIZE);
+ //FIXME: remove?
+ m_display_ring = &ram_header->cmd_ring;
+ m_cursor_ring = &ram_header->cursor_ring;
+ m_release_ring = &ram_header->release_ring;
+
return STATUS_SUCCESS;
error:
m_DxgkInterface.DxgkCbUnmapMemory(m_DxgkInterface.DeviceHandle,
@@ -269,6 +327,26 @@ NTSTATUS BASIC_DISPLAY_DRIVER::QxlInit()
// TODO: support async
QxlWritePortUchar(QXL_IO_MEMSLOT_ADD, m_mem_regions[QXL_VRAM_RANGE_INDEX].slot_id);
}
+
+ // TODO: consider also NotificationEvent
+ // http://msdn.microsoft.com/en-us/library/windows/hardware/ff543006%28v=vs.85%29.aspx
+ // FIXME: additional interrupt & event for multimon client capabilities
+ m_display_event = IoCreateSynchronizationEvent(NULL, &m_display_event_handle);
+ if (!m_display_event) {
+ LogMessage("%s: display event create failed\n", __FUNCTION__);
+ goto error;
+ }
+ m_cursor_event = IoCreateSynchronizationEvent(NULL, &m_cursor_event_handle);
+ if (!m_cursor_event) {
+ LogMessage("%s: cursor event create failed\n", __FUNCTION__);
+ goto error;
+ }
+ m_async_io_event = IoCreateSynchronizationEvent(NULL, &m_async_io_event_handle);
+ if (!m_async_io_event) {
+ LogMessage("%s: async io event create failed\n", __FUNCTION__);
+ goto error;
+ }
+
// TODO: memslots
return STATUS_SUCCESS;
// TODO: share validity check code with XDDM. XDDM assumes the rom is mapped before the ram
@@ -283,6 +361,10 @@ error:
VOID BASIC_DISPLAY_DRIVER::QxlCleanup()
{
+ ZwClose(m_display_event_handle);
+ ZwClose(m_cursor_event_handle);
+ ZwClose(m_async_io_event_handle);
+
for (int i = 0; i < QXL_PCI_RANGES; i++) {
if (m_mem_regions[i].mapped_start) {
m_DxgkInterface.DxgkCbUnmapMemory(m_DxgkInterface.DeviceHandle,
diff --git a/C++/bdd.hxx b/C++/bdd.hxx
index 4bc990b..2086a49 100644
--- a/C++/bdd.hxx
+++ b/C++/bdd.hxx
@@ -239,6 +239,17 @@ private:
MspaceInfo m_mspaces[NUM_MSPACES];
+ QXLCommandRing *m_display_ring;
+ QXLCursorRing *m_cursor_ring;
+ QXLReleaseRing *m_release_ring;
+
+ PKEVENT m_display_event;
+ HANDLE m_display_event_handle;
+ PKEVENT m_cursor_event;
+ HANDLE m_cursor_event_handle;
+ PKEVENT m_async_io_event;
+ HANDLE m_async_io_event_handle;
+
public:
BASIC_DISPLAY_DRIVER(_In_ DEVICE_OBJECT* pPhysicalDeviceObject);
~BASIC_DISPLAY_DRIVER();
@@ -441,6 +452,10 @@ private:
VOID QxlWritePortUchar(UINT qxl_port, UCHAR val);
VOID InitMspace(UINT32 mspace_type, UINT8 *start, size_t capacity);
+ VOID push_display_cmd();
+ VOID push_cursor_cmd();
+ VOID wait_for_display_cmd();
+ VOID wait_for_cursor_cmd();
};
//