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:
1 parent
e41bf6e2c0
commit
6260de0085
38 files changed
+4011
-467
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user