add display subsystem and vmwaresvga driver, support absolute mouse and qemu tablet, map pci mmio to private virtual aperture, better smp panic handling, remove legacy io publish/match, add sys query display info and display command to native shell

This commit is contained in:
maksw committed 2026-06-15 09:58:12 +02:00
1 parent e41bf6e2c0
commit 6260de0085
38 files changed
+4011 -467

No files matched your search

+51 -9
View File
@@ -20,6 +20,40 @@ static const HAL_API* gHal;
static DRIVER_OBJECT gPciDriver;
static uint32_t gPciDeviceCount;
/*
* PCI MMIO BARs use a private virtual aperture instead of the physical
* direct map. This avoids cacheability aliasing with large direct-map pages
* and keeps BAR mappings page-granular.
*/
#define PCI_MMIO_VA_BASE 0xFFFF900000000000ULL
#define PCI_MMIO_VA_LIMIT 0xFFFF980000000000ULL
static uintptr_t gPciMmioNext = PCI_MMIO_VA_BASE;
static uint64_t PciAlignUp64(uint64_t value, uint64_t alignment) {
return (value + alignment - 1u) & ~(alignment - 1u);
}
static uint64_t PciDefaultMmioFlags(void) {
return PAGE_PRESENT | PAGE_WRITE | PAGE_WRITETHROUGH | PAGE_NOCACHE | PAGE_NX;
}
static KSTATUS PciAllocateMmioVa(uint64_t length, uintptr_t* outVa) {
if (!outVa || !length)
return STATUS_INVALID_PARAMETER;
uint64_t alignedLength = PciAlignUp64(length, PAGE_SIZE);
uintptr_t va = (uintptr_t)PciAlignUp64((uint64_t)gPciMmioNext, PAGE_SIZE);
if (va < PCI_MMIO_VA_BASE || va >= PCI_MMIO_VA_LIMIT)
return STATUS_NO_MEMORY;
if (alignedLength > (uint64_t)(PCI_MMIO_VA_LIMIT - va))
return STATUS_NO_MEMORY;
gPciMmioNext = va + (uintptr_t)alignedLength;
*outVa = va;
return STATUS_SUCCESS;
}
static bool PciIsPdo(DEVICE_OBJECT* pdo, PCI_PDO_EXTENSION** outExt) {
if (!pdo || pdo->Type != DeviceObjectPhysical || pdo->u.Pdo.BusType != IoBusPci)
return false;
@@ -455,27 +489,35 @@ __declspec(dllexport) KSTATUS PciGetBar(DEVICE_OBJECT* pdo, uint8_t index, PCI_B
__declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint64_t pageFlags, void** outVirtual, uint64_t* outLength) {
PCI_BAR bar;
if (!outVirtual) return STATUS_INVALID_PARAMETER;
*outVirtual = NULL;
KSTATUS st = PciGetBar(pdo, index, &bar);
if (!KSUCCESS(st)) return st;
if (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64)
return STATUS_NOT_SUPPORTED;
if (!bar.Length)
return STATUS_DEVICE_ERROR;
if (bar.Base + bar.Length < bar.Base)
return STATUS_INVALID_PARAMETER;
uint64_t flags = pageFlags ? pageFlags : (PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE);
uint64_t pageBase = bar.Base & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t pageEnd = (bar.Base + bar.Length + PAGE_SIZE - 1u) & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t flags = pageFlags ? pageFlags : PciDefaultMmioFlags();
flags |= PAGE_PRESENT;
for (uint64_t phys = pageBase; phys < pageEnd; phys += PAGE_SIZE) {
uintptr_t virt = (uintptr_t)gHal->PhysToVirt(phys);
st = MmMapPage(virt, phys, flags, MmMapFailIfPresent);
if (st == STATUS_ALREADY_EXISTS)
st = MmSetPageProtect(virt, PAGE_SIZE, flags);
uint64_t physBase = bar.Base & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t physOffset = bar.Base - physBase;
uint64_t mapLength = PciAlignUp64(physOffset + bar.Length, PAGE_SIZE);
uintptr_t virtBase = 0;
st = PciAllocateMmioVa(mapLength, &virtBase);
if (!KSUCCESS(st))
return st;
for (uint64_t off = 0; off < mapLength; off += PAGE_SIZE) {
st = MmMapPage(virtBase + (uintptr_t)off, physBase + off, flags, MmMapFailIfPresent);
if (!KSUCCESS(st))
return st;
}
*outVirtual = (void*)((uintptr_t)gHal->PhysToVirt(pageBase) + (uintptr_t)(bar.Base - pageBase));
*outVirtual = (void*)(virtBase + (uintptr_t)physOffset);
if (outLength) *outLength = bar.Length;
return STATUS_SUCCESS;
}
+7 -5
View File
@@ -115,6 +115,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define XHCI_CC_SUCCESS 1u
#define XHCI_CC_SHORT_PACKET 13u
#define XHCI_TRB_ISP (1u << 2)
#define XHCI_TRB_IOC (1u << 5)
@@ -458,6 +459,7 @@ struct USB_URB {
PHYSICAL_ADDRESS BufferPhys;
uint32_t Length;
uint32_t ActualLength;
uint32_t HcdCompletionCode;
KSTATUS Status;
IRP* Irp;
USB_URB_COMPLETION Complete;
@@ -562,6 +564,11 @@ typedef struct USB_HID_EXTENSION {
bool Removed;
bool Keyboard;
bool Mouse;
bool AbsoluteMouse;
uint16_t AbsoluteMaxX;
uint16_t AbsoluteMaxY;
uint16_t LastAbsoluteX;
uint16_t LastAbsoluteY;
uint8_t InterfaceNumber;
uint8_t Protocol;
uint8_t EndpointAddress;
@@ -954,9 +961,6 @@ KSTATUS XhciStartHidInterrupts(XHCI_CONTROLLER* xhci);
KSTATUS XhciSetHidBootProtocol(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciAllocateHidMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
const IO_PUBLISHED_USB_ENDPOINT* UsbFindEndpoint(const IO_PUBLISHED_DEVICE* pub, uint8_t endpointType, bool wantIn);
bool UsbHidMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbHidBind(IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t trbCount, uint8_t cycle);
@@ -982,8 +986,6 @@ KSTATUS XhciAllocateMassStorageMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint8_t UsbFindFreeDiskIndex(void);
KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage);
bool UsbStorageMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbStorageBind(IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS XhciSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t configurationValue);
void XhciLogConfigurationTree(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_CONFIGURATION_DESCRIPTOR* config, uint16_t totalLength);
KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_DEVICE_DESCRIPTOR* devDesc);
+84 -90
View File
@@ -135,7 +135,7 @@ static void XhciHandleLegacyHidTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trb
return;
dev->HidArmed = false;
if (completionCode != XHCI_CC_SUCCESS) {
if (completionCode != XHCI_CC_SUCCESS && completionCode != XHCI_CC_SHORT_PACKET) {
DbgPrint("usb: HID transfer failed slot=%u ep=%u cc=%u residue=%u\n",
slotId, endpointId, completionCode, residue);
return;
@@ -298,73 +298,6 @@ KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
}
const IO_PUBLISHED_USB_ENDPOINT* UsbFindEndpoint(const IO_PUBLISHED_DEVICE* pub,
uint8_t endpointType,
bool wantIn) {
if (!pub || pub->BusType != IoBusUsb) return (const IO_PUBLISHED_USB_ENDPOINT*)0;
for (uint8_t i = 0; i < pub->u.Usb.EndpointCount; i++) {
const IO_PUBLISHED_USB_ENDPOINT* ep = &pub->u.Usb.Endpoints[i];
uint8_t type = ep->Attributes & USB_ENDPOINT_ATTR_TYPE_MASK;
bool in = (ep->Address & USB_ENDPOINT_DIR_IN) != 0;
if (type == endpointType && in == wantIn)
return ep;
}
return (const IO_PUBLISHED_USB_ENDPOINT*)0;
}
bool UsbHidMatch(const IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || pub->BusType != IoBusUsb)
return false;
if (pub->u.Usb.InterfaceClass != USB_CLASS_HID)
return false;
if (pub->u.Usb.InterfaceSubclass != USB_HID_SUBCLASS_BOOT)
return false;
if (pub->u.Usb.InterfaceProtocol != USB_HID_PROTOCOL_KEYBOARD &&
pub->u.Usb.InterfaceProtocol != USB_HID_PROTOCOL_MOUSE)
return false;
return UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_INTERRUPT, true) != (const IO_PUBLISHED_USB_ENDPOINT*)0;
}
KSTATUS UsbHidBind(IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || !pub->BusContext || !pub->DeviceContext)
return STATUS_INVALID_PARAMETER;
XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)pub->BusContext;
XHCI_DEVICE* dev = (XHCI_DEVICE*)pub->DeviceContext;
if (dev->HidActive || dev->HidCandidate)
return STATUS_ALREADY_EXISTS;
const IO_PUBLISHED_USB_ENDPOINT* ep = UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_INTERRUPT, true);
if (!ep)
return STATUS_NOT_FOUND;
dev->HidCandidate = true;
dev->HidKeyboard = (pub->u.Usb.InterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
dev->HidMouse = (pub->u.Usb.InterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
dev->HidInterface = pub->u.Usb.InterfaceNumber;
dev->HidProtocol = pub->u.Usb.InterfaceProtocol;
dev->HidEndpointAddress = ep->Address;
dev->HidEndpointId = XhciEndpointIdFromAddress(ep->Address);
dev->HidInterval = ep->Interval;
dev->HidMaxPacket = ep->MaxPacketSize;
KSTATUS st = XhciConfigureHidEndpoint(xhci, dev);
if (!KSUCCESS(st)) {
dev->HidCandidate = false;
dev->HidKeyboard = false;
dev->HidMouse = false;
}
return st;
}
// -------------------------------------------------------------------------
// PDO/FDO boot HID function driver path.
// -------------------------------------------------------------------------
@@ -374,6 +307,7 @@ DRIVER_OBJECT gUsbHidDriver;
static const IO_DEVICE_ID gUsbHidIds[] = {
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_01&PROT_01", sizeof("USB\\CLASS_03&SUBCLASS_01&PROT_01") - 1 } },
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_01&PROT_02", sizeof("USB\\CLASS_03&SUBCLASS_01&PROT_02") - 1 } },
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_00&PROT_00", sizeof("USB\\CLASS_03&SUBCLASS_00&PROT_00") - 1 } },
};
static const IO_DRIVER_ID_TABLE gUsbHidIdTable = {
@@ -381,6 +315,26 @@ static const IO_DRIVER_ID_TABLE gUsbHidIdTable = {
sizeof(gUsbHidIds) / sizeof(gUsbHidIds[0]),
};
static bool UsbHidIsQemuAbsoluteTabletPdo(const USB_PDO_EXTENSION* pdoExt, const USB_ENDPOINT_DESCRIPTOR* ep) {
if (!pdoExt || !pdoExt->Device || !ep)
return false;
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID)
return false;
if (pdoExt->InterfaceDescriptor.bInterfaceSubClass != 0 ||
pdoExt->InterfaceDescriptor.bInterfaceProtocol != 0)
return false;
if (pdoExt->Device->VendorId != 0x0627u || pdoExt->Device->ProductId != 0x0001u)
return false;
/*
* QEMU's usb-kbd and usb-tablet commonly share VID:PID 0627:0001.
* Do not classify by VID:PID alone: the boot keyboard is subclass/protocol
* 01/01, while usb-tablet is the non-boot HID interface 00/00.
*/
return (ep->wMaxPacketSize & 0x07FFu) >= 6u;
}
static const USB_ENDPOINT_DESCRIPTOR* UsbHidFindInterruptInPdo(const USB_PDO_EXTENSION* ext) {
if (!ext) return (const USB_ENDPOINT_DESCRIPTOR*)0;
@@ -443,6 +397,24 @@ static void UsbHidProcessBootMouseReport(USB_HID_EXTENSION* ext, const uint8_t*
ext->LastButtons = buttons;
}
static void UsbHidProcessQemuTabletReport(USB_HID_EXTENSION* ext, const uint8_t* report, uint16_t len) {
if (!ext || len < 5) return;
uint8_t buttons = report[0] & 0x07u;
uint16_t x = (uint16_t)report[1] | ((uint16_t)report[2] << 8);
uint16_t y = (uint16_t)report[3] | ((uint16_t)report[4] << 8);
int wheel = (len >= 6) ? (int)(int8_t)report[5] : 0;
if (x != ext->LastAbsoluteX || y != ext->LastAbsoluteY ||
wheel || buttons != ext->LastButtons) {
KeInputSubmitMouseAbsoluteScaled(x, y, ext->AbsoluteMaxX, ext->AbsoluteMaxY, wheel, buttons);
}
ext->LastAbsoluteX = x;
ext->LastAbsoluteY = y;
ext->LastButtons = buttons;
}
static KSTATUS UsbHidArmInterrupt(USB_HID_EXTENSION* ext);
static void UsbHidInterruptComplete(USB_URB* urb, void* context) {
@@ -460,14 +432,19 @@ static void UsbHidInterruptComplete(USB_URB* urb, void* context) {
if (ext->Keyboard)
UsbHidProcessBootKeyboardReport(ext, ext->ReportBuffer, length);
else if (ext->AbsoluteMouse)
UsbHidProcessQemuTabletReport(ext, ext->ReportBuffer, length);
else if (ext->Mouse)
UsbHidProcessBootMouseReport(ext, ext->ReportBuffer, length);
} else if (urb->Status != STATUS_CANCELLED) {
DbgPrint("usb: HID interrupt URB failed slot=%u if=%u ep=%02x st=0x%x\n",
DbgPrint("usb: HID interrupt URB failed slot=%u if=%u ep=%02x st=0x%x cc=%u actual=%u/%u\n",
ext->Device ? ext->Device->SlotId : 0,
ext->InterfaceNumber,
ext->EndpointAddress,
urb->Status);
urb->Status,
urb->HcdCompletionCode,
urb->ActualLength,
urb->Length);
}
if (!ext->SurpriseRemoved && !ext->Removed)
@@ -563,8 +540,14 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (!ep)
return STATUS_NOT_FOUND;
ext->Keyboard = (pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
ext->Mouse = (pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
ext->Keyboard = (pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
ext->AbsoluteMouse = UsbHidIsQemuAbsoluteTabletPdo(pdoExt, ep);
ext->Mouse = ext->AbsoluteMouse ||
(pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
ext->AbsoluteMaxX = 0x7FFFu;
ext->AbsoluteMaxY = 0x7FFFu;
ext->InterfaceNumber = pdoExt->InterfaceDescriptor.bInterfaceNumber;
ext->Protocol = pdoExt->InterfaceDescriptor.bInterfaceProtocol;
ext->EndpointAddress = ep->bEndpointAddress;
@@ -572,9 +555,10 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
ext->Interval = ep->bInterval;
uint16_t reportLength = ext->MaxPacketSize & 0x07FFu;
if (reportLength == 0) reportLength = ext->Keyboard ? 8u : 4u;
if (reportLength == 0) reportLength = ext->Keyboard ? 8u : (ext->AbsoluteMouse ? 6u : 4u);
if (ext->Keyboard && reportLength < 8) reportLength = 8;
if (ext->Mouse && reportLength < 3) reportLength = 3;
if (ext->AbsoluteMouse && reportLength < 6) reportLength = 6;
if (ext->Mouse && !ext->AbsoluteMouse && reportLength < 3) reportLength = 3;
if (reportLength > XHCI_MAX_HID_REPORT) reportLength = XHCI_MAX_HID_REPORT;
ext->ReportLength = reportLength;
@@ -591,15 +575,17 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (!KSUCCESS(st))
return st;
st = UsbHidSendBootProtocol(ext);
if (!KSUCCESS(st))
return st;
if (!ext->AbsoluteMouse) {
st = UsbHidSendBootProtocol(ext);
if (!KSUCCESS(st))
return st;
}
memset(ext->LastKeys, 0, sizeof(ext->LastKeys));
ext->LastModifiers = 0;
ext->LastButtons = 0;
KeInputRegisterDevice(ext->Keyboard ? "usb-hid-keyboard" : "usb-hid-mouse", 0, &ext->InputDeviceId);
KeInputRegisterDevice(ext->Keyboard ? "usb-hid-keyboard" : (ext->AbsoluteMouse ? "usb-hid-tablet" : "usb-hid-mouse"), 0, &ext->InputDeviceId);
ext->Started = true;
device->PnpState = DevicePnpStarted;
@@ -616,8 +602,8 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (xhci)
xhci->HidDeviceCount++;
DbgPrint("usb: HID boot %s bound slot=%u if=%u ep=%02x maxpkt=%u interval=%u input=%u urb\n",
ext->Keyboard ? "keyboard" : "mouse",
DbgPrint("usb: HID %s bound slot=%u if=%u ep=%02x maxpkt=%u interval=%u input=%u urb\n",
ext->Keyboard ? "boot-keyboard" : (ext->AbsoluteMouse ? "qemu-tablet" : "boot-mouse"),
ext->Device->SlotId,
ext->InterfaceNumber,
ext->EndpointAddress,
@@ -720,24 +706,31 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje
USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension;
if (!pdoExt || pdoExt->Kind != UsbPdoInterface || !pdoExt->Device)
return STATUS_INVALID_PARAMETER;
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID ||
pdoExt->InterfaceDescriptor.bInterfaceSubClass != USB_HID_SUBCLASS_BOOT)
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID)
return STATUS_INVALID_PARAMETER;
if (pdoExt->InterfaceDescriptor.bInterfaceProtocol != USB_HID_PROTOCOL_KEYBOARD &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol != USB_HID_PROTOCOL_MOUSE)
return STATUS_INVALID_PARAMETER;
if (!UsbHidFindInterruptInPdo(pdoExt))
const USB_ENDPOINT_DESCRIPTOR* ep = UsbHidFindInterruptInPdo(pdoExt);
if (!ep)
return STATUS_NOT_FOUND;
bool bootKeyboard = pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD;
bool bootMouse = pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE;
bool qemuTablet = UsbHidIsQemuAbsoluteTabletPdo(pdoExt, ep);
if (!bootKeyboard && !bootMouse && !qemuTablet)
return STATUS_INVALID_PARAMETER;
DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0;
KSTATUS st = IoCreateDevice(driver, sizeof(USB_HID_EXTENSION), &fdo);
if (!KSUCCESS(st))
return st;
(void)IoSetDeviceName(fdo,
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD
bootKeyboard
? SYS_SV_LITERAL("usb-hid-keyboard")
: SYS_SV_LITERAL("usb-hid-mouse"));
: (qemuTablet ? SYS_SV_LITERAL("usb-hid-tablet")
: SYS_SV_LITERAL("usb-hid-mouse")));
USB_HID_EXTENSION* ext = (USB_HID_EXTENSION*)fdo->DeviceExtension;
ext->Self = fdo;
@@ -758,10 +751,11 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje
return STATUS_FAILURE;
}
DbgPrint("usb: HID FDO attached slot=%u if=%u proto=%u\n",
DbgPrint("usb: HID FDO attached slot=%u if=%u proto=%u kind=%s\n",
ext->Device->SlotId,
pdoExt->InterfaceDescriptor.bInterfaceNumber,
pdoExt->InterfaceDescriptor.bInterfaceProtocol);
pdoExt->InterfaceDescriptor.bInterfaceProtocol,
qemuTablet ? "qemu-tablet" : (bootKeyboard ? "keyboard" : "mouse"));
return STATUS_SUCCESS;
}
-20
View File
@@ -764,26 +764,6 @@ KSTATUS UsbStorageDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
return STATUS_INVALID_PARAMETER;
}
bool UsbStorageMatch(const IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || pub->BusType != IoBusUsb)
return false;
if (pub->u.Usb.InterfaceClass != USB_CLASS_MASS_STORAGE)
return false;
if (pub->u.Usb.InterfaceSubclass != USB_MASS_SUBCLASS_SCSI)
return false;
if (pub->u.Usb.InterfaceProtocol != USB_MASS_PROTOCOL_BOT)
return false;
return UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_BULK, true) &&
UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_BULK, false);
}
KSTATUS UsbStorageBind(IO_PUBLISHED_DEVICE* pub, void* context) {
(void)pub;
(void)context;
return STATUS_NOT_SUPPORTED;
}
KSTATUS UsbStorageAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) {
if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical)
+4 -1
View File
@@ -1667,6 +1667,7 @@ static KSTATUS XhciHcdSubmitInterruptUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev
urb->Cancelled = false;
urb->Status = STATUS_PENDING;
urb->ActualLength = 0;
urb->HcdCompletionCode = 0;
XhciBarrier();
XhciWrite32(xhci->Doorbells, (uint32_t)dev->SlotId * 4u, ctx->EndpointId);
@@ -1699,7 +1700,8 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys,
KSTATUS st = STATUS_SUCCESS;
if (urb->Cancelled) {
st = STATUS_CANCELLED;
} else if (completionCode != XHCI_CC_SUCCESS) {
} else if (completionCode != XHCI_CC_SUCCESS &&
completionCode != XHCI_CC_SHORT_PACKET) {
st = STATUS_DEVICE_ERROR;
}
@@ -1711,6 +1713,7 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys,
urb->Pending = false;
urb->Status = st;
urb->ActualLength = actual;
urb->HcdCompletionCode = completionCode;
IRP* completeIrp = urb->Irp;
urb->Irp = (IRP*)0;
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,215 @@
#pragma once
// vmwaresvga.h - VMware SVGA-II display provider internals.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <intrin.h>
#include <ntlite/status.h>
#include <ntlite/ddi/hal_api.h>
#include <ntlite/ddi/io_driver.h>
#include <ntlite/ddi/pci.h>
#include <ntlite/ddi/display.h>
#include <kernel/ke_display.h>
#include <kernel/ke_debug.h>
#include <kernel/mm_virt.h>
#include <kernel/display_cursor.h>
#define VMWSVGA_VENDOR_VMWARE 0x15ADu
#define VMWSVGA_DEVICE_SVGA2 0x0405u
#define VMWSVGA_DEVICE_MAGIC 0x564D5356u /* VMSV */
#define SVGA_ID_INVALID 0xFFFFFFFFu
#define SVGA_ID_0 0x90000000u
#define SVGA_ID_1 0x90000001u
#define SVGA_ID_2 0x90000002u
#define SVGA_INDEX_PORT 0u
#define SVGA_VALUE_PORT 1u
#define SVGA_REG_ID 0u
#define SVGA_REG_ENABLE 1u
#define SVGA_REG_WIDTH 2u
#define SVGA_REG_HEIGHT 3u
#define SVGA_REG_MAX_WIDTH 4u
#define SVGA_REG_MAX_HEIGHT 5u
#define SVGA_REG_DEPTH 6u
#define SVGA_REG_BITS_PER_PIXEL 7u
#define SVGA_REG_BYTES_PER_LINE 12u
#define SVGA_REG_FB_START 13u
#define SVGA_REG_FB_OFFSET 14u
#define SVGA_REG_VRAM_SIZE 15u
#define SVGA_REG_FB_SIZE 16u
#define SVGA_REG_CAPABILITIES 17u
#define SVGA_REG_MEM_START 18u
#define SVGA_REG_MEM_SIZE 19u
#define SVGA_REG_CONFIG_DONE 20u
#define SVGA_REG_SYNC 21u
#define SVGA_REG_BUSY 22u
#define SVGA_REG_GUEST_ID 23u
#define SVGA_REG_CURSOR_ID 24u
#define SVGA_REG_CURSOR_X 25u
#define SVGA_REG_CURSOR_Y 26u
#define SVGA_REG_CURSOR_ON 27u
#define SVGA_REG_HOST_BITS_PER_PIXEL 28u
#define SVGA_REG_MEM_REGS 30u
#define SVGA_REG_NUM_GUEST_DISPLAYS 34u
#define SVGA_REG_DISPLAY_ID 35u
#define SVGA_REG_DISPLAY_IS_PRIMARY 36u
#define SVGA_REG_DISPLAY_POSITION_X 37u
#define SVGA_REG_DISPLAY_POSITION_Y 38u
#define SVGA_REG_DISPLAY_WIDTH 39u
#define SVGA_REG_DISPLAY_HEIGHT 40u
#define SVGA_REG_PITCHLOCK 32u
#define SVGA_CMD_INVALID_CMD 0u
#define SVGA_CMD_UPDATE 1u
#define SVGA_CMD_RECT_FILL 2u
#define SVGA_CMD_RECT_COPY 3u
#define SVGA_CMD_DEFINE_CURSOR 19u
#define SVGA_CMD_DISPLAY_CURSOR 20u
#define SVGA_CMD_DEFINE_ALPHA_CURSOR 22u
#define SVGA_CMD_DEFINE_SCREEN 34u
#define SVGA_CMD_DESTROY_SCREEN 35u
#define SVGA_CMD_DEFINE_GMRFB 36u
#define SVGA_CMD_BLIT_GMRFB_TO_SCREEN 37u
#define SVGA_FIFO_MIN 0u
#define SVGA_FIFO_MAX 1u
#define SVGA_FIFO_NEXT_CMD 2u
#define SVGA_FIFO_STOP 3u
#define SVGA_FIFO_CAPABILITIES 4u
#define SVGA_FIFO_FLAGS 5u
#define SVGA_FIFO_FENCE 6u
#define SVGA_FIFO_3D_HWVERSION 7u
#define SVGA_FIFO_PITCHLOCK 8u
#define SVGA_FIFO_CURSOR_ON 9u
#define SVGA_FIFO_CURSOR_X 10u
#define SVGA_FIFO_CURSOR_Y 11u
#define SVGA_FIFO_CURSOR_COUNT 12u
#define SVGA_FIFO_CURSOR_LAST_UPDATED 13u
#define SVGA_FIFO_RESERVED 14u
#define SVGA_FIFO_CURSOR_SCREEN_ID 15u
#define SVGA_FIFO_3D_CAPS 32u
#define SVGA_FIFO_3D_CAPS_LAST (SVGA_FIFO_3D_CAPS + 255u)
#define SVGA_FIFO_GUEST_3D_HWVERSION (SVGA_FIFO_3D_CAPS_LAST + 1u)
#define SVGA_FIFO_FENCE_GOAL (SVGA_FIFO_3D_CAPS_LAST + 2u)
#define SVGA_FIFO_BUSY (SVGA_FIFO_3D_CAPS_LAST + 3u)
#define SVGA_FIFO_NUM_LEGACY_REGS 4u
#define SVGA_FIFO_NUM_REGS_FALLBACK (SVGA_FIFO_BUSY + 3u)
#define SVGA_CAP_CURSOR 0x00000020u
#define SVGA_CAP_CURSOR_BYPASS 0x00000040u
#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080u
#define SVGA_CAP_ALPHA_CURSOR 0x00000200u
#define SVGA_CAP_EXTENDED_FIFO 0x00008000u
#define SVGA_CAP_MULTIMON 0x00010000u
#define SVGA_CAP_PITCHLOCK 0x00020000u
#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000u
#define SVGA_CAP_GMR 0x00100000u
#define SVGA_CAP_GMR2 0x00400000u
#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000u
#define SVGA_CURSOR_ON_HIDE 0u
#define SVGA_CURSOR_ON_SHOW 1u
#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 0x00000010u
#define SVGA_FIFO_CAP_SCREEN_OBJECT 0x00000080u
#define SVGA_FIFO_CAP_SCREEN_OBJECT_2 0x00000200u
#define SVGA_GMR_FRAMEBUFFER 0xFFFFFFFEu
#define SVGA_SCREEN_MUST_BE_SET 0x00000001u
#define SVGA_SCREEN_IS_PRIMARY 0x00000002u
#define SVGA_SCREEN_OBJECT_ID_PRIMARY 0u
#define SVGA_GMRFB_FORMAT_32BPP_24DEPTH ((32u) | (24u << 8))
/*
* The production path is legacy GFB + UPDATE. Screen objects are kept behind
* an opt-in switch until the SO/GMRFB path is independently validated on real
* VMware hosts.
*/
#ifndef VMWSVGA_ENABLE_SCREEN_OBJECTS
#define VMWSVGA_ENABLE_SCREEN_OBJECTS 0
#endif
#define VMWSVGA_MAX_WAIT_ITERS 1000000u
#define VMWSVGA_CURSOR_W DISPLAY_DEFAULT_CURSOR_W
#define VMWSVGA_CURSOR_H DISPLAY_DEFAULT_CURSOR_H
#define VMWSVGA_CAPS_MINIMAL (DISPLAY_CAP_FRAMEBUFFER | DISPLAY_CAP_SOFTWARE_CURSOR | DISPLAY_CAP_PRESENT_SYNC)
#define VMWSVGA_CAPS_HW_CURSOR (DISPLAY_CAP_FRAMEBUFFER | DISPLAY_CAP_HARDWARE_CURSOR | DISPLAY_CAP_PRESENT_SYNC)
typedef struct VMWSVGA_DEVICE {
uint32_t Magic;
DEVICE_OBJECT* Fdo;
DEVICE_OBJECT* Pdo;
DEVICE_OBJECT* LowerDevice;
PCI_DEVICE_INFO PciInfo;
PCI_BAR IoBar;
PCI_BAR FramebufferBar;
PCI_BAR FifoBar;
uint16_t IoBase;
volatile uint8_t* FramebufferMapping;
volatile uint8_t* Framebuffer;
volatile uint32_t* Fifo;
uint64_t FramebufferBytes;
uint32_t FramebufferOffset;
uint64_t FifoBytes;
uint32_t FifoDeviceBytes;
uint32_t DeviceId;
uint32_t Capabilities;
uint32_t Width;
uint32_t Height;
uint32_t Stride;
uint32_t BytesPerLine;
uint32_t BitsPerPixel;
uint32_t* Backbuffer;
size_t BackbufferBytes;
uint32_t FifoRegCount;
uint32_t FifoCaps;
bool UseScreenObject;
uint32_t ScreenId;
uint32_t ScreenSourceOffset;
uint32_t ScreenSourceBytes;
uint32_t ScreenBackingOffset;
uint32_t ScreenBackingBytes;
bool FifoReady;
bool HardwareCursor;
bool AlphaCursor;
bool CursorBypass3;
bool CursorImageDefined;
bool CursorVisible;
uint32_t* CursorImageArgb;
size_t CursorImageBytes;
int CursorImageWidth;
int CursorImageHeight;
int CursorHotX;
int CursorHotY;
bool Started;
bool Removed;
bool SurpriseRemoved;
int CursorX;
int CursorY;
int CursorDrawX;
int CursorDrawY;
bool CursorDrawn;
DISPLAY_STATS Stats;
DISPLAY_DEVICE DisplayDevice;
} VMWSVGA_DEVICE;
extern const HAL_API* gVmwSvgaHal;
KSTATUS VmwSvgaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
+1
View File
@@ -8,5 +8,6 @@ fat32.sys
[runtime]
lwip.sys
vmwaresvga.sys
rtl8139.sys
rtl816x.sys