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;
}