static FORCEINLINE VOID __UnplugDisksLocked( IN PXENFILT_UNPLUG_CONTEXT Context ) { if (Context->BootEmulated) { WRITE_PORT_USHORT((PUSHORT)0x10, 0x0004); LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: AUX DISKS\n"); } else { WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001); LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n"); } }
BOOLEAN NTAPI XenGfxVbeGetEdid(UCHAR *pChildDescriptor, ULONG Length) { ULONG Addr; PHYSICAL_ADDRESS PhysAddr = {0}; UCHAR *pVirtAddr; USHORT XRes, YRes; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); if (!g_VbeInfoInitialized) { return FALSE; } if ((pChildDescriptor == NULL)||(Length < VBE_EDID_SIZE)) { return FALSE; } // Find the EDID and map it in. The spinlock is not needed since the // EDID is a static/ro chunk (after initialization). Addr = ((ULONG)g_VbeTable.EdidSeg & (0x0000FFFF)); Addr = Addr << 4; Addr = Addr | ((ULONG)g_VbeTable.EdidAddr & (0x0000FFFF)); PhysAddr.LowPart = Addr; pVirtAddr = (UCHAR*)MmMapIoSpace(PhysAddr, VBE_EDID_SIZE, MmNonCached); if (pVirtAddr == NULL) { TraceError(("Could not MAP in EDID virtual address!\n")); return FALSE; } RtlCopyMemory(pChildDescriptor, pVirtAddr, VBE_EDID_SIZE); MmUnmapIoSpace(pVirtAddr, VBE_EDID_SIZE); // Fix up EDID with resolution on this system. WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_EDID_XRES); XRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_EDID_YRES); YRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); *(pChildDescriptor + 0x38) = (UCHAR)(XRes & 0x00FF); *(pChildDescriptor + 0x3A) = (UCHAR)(((XRes >> 8) & 0x000F) << 4); *(pChildDescriptor + 0x3B) = (UCHAR)(YRes & 0x00FF); *(pChildDescriptor + 0x3D) = (UCHAR)(((YRes >> 8) & 0x000F) << 4); TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return TRUE; }
VOID ScsiPortWritePortUshort( IN PUSHORT Port, IN USHORT Value ) /*++ Routine Description: Write to the specificed port address. Arguments: Port - Supplies a pointer to the port address. Value - Supplies the value to be written. Return Value: None --*/ { WRITE_PORT_USHORT(Port, Value); }
ACPI_STATUS AcpiOsWritePort ( ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width) { DPRINT("AcpiOsWritePort %p, width %d\n",Address,Width); switch (Width) { case 8: WRITE_PORT_UCHAR((PUCHAR)Address, Value); break; case 16: WRITE_PORT_USHORT((PUSHORT)Address, Value); break; case 32: WRITE_PORT_ULONG((PULONG)Address, Value); break; default: DPRINT1("AcpiOsWritePort got bad width: %d\n",Width); return (AE_BAD_PARAMETER); break; } return (AE_OK); }
static FORCEINLINE NTSTATUS __UnplugPreamble( IN PXENFILT_UNPLUG_CONTEXT Context, IN BOOLEAN Locked ) { KIRQL Irql = PASSIVE_LEVEL; USHORT Magic; UCHAR Version; NTSTATUS status; if (!Locked) AcquireHighLock(&Context->Lock, &Irql); // See docs/misc/hvm-emulated-unplug.markdown for details of the // protocol in use here Magic = READ_PORT_USHORT((PUSHORT)0x10); if (Magic == 0xd249) { Context->BlackListed = TRUE; goto done; } status = STATUS_NOT_SUPPORTED; if (Magic != 0x49d2) goto fail1; Version = READ_PORT_UCHAR((PUCHAR)0x12); if (Version != 0) { WRITE_PORT_USHORT((PUSHORT)0x12, 0xFFFF); // FIXME WRITE_PORT_ULONG((PULONG)0x10, (MAJOR_VERSION << 16) | (MINOR_VERSION << 8) | MICRO_VERSION); Magic = READ_PORT_USHORT((PUSHORT)0x10); if (Magic == 0xd249) Context->BlackListed = TRUE; } done: LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: PRE-AMBLE (DRIVERS %s)\n", (Context->BlackListed) ? "BLACKLISTED" : "NOT BLACKLISTED"); if (!Locked) ReleaseHighLock(&Context->Lock, Irql); return STATUS_SUCCESS; fail1: Error("fail1 (%08x)\n", status); if (!Locked) ReleaseHighLock(&Context->Lock, Irql); return status; }
static FORCEINLINE VOID __UnplugNicsLocked( ) { WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002); LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n"); }
VOID NTAPI ScsiPortWritePortUshort( IN PUSHORT Port, IN USHORT Value) { WRITE_PORT_USHORT(Port, Value); }
VOID NTAPI VideoPortWritePortUshort( PUSHORT Port, USHORT Value) { WRITE_PORT_USHORT(Port, Value); }
USHORT XenGfxVbeGetAlignedStride( const WORD CurrentModeStride) { USHORT strideAlign, alignedStride; WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_STRIDE_ALIGN); strideAlign = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA) -1; alignedStride = (CurrentModeStride + (strideAlign)) & ~strideAlign; return alignedStride; }
BOOLEAN NTAPI XenGfxVbeGetCurrentMode(USHORT *XRes, USHORT *YRes, USHORT * bpp) { if (!g_VbeInfoInitialized) { return FALSE; } if (XRes == NULL || YRes == NULL || bpp == NULL) { return FALSE; } // Get VBE values WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_XRES); *XRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_YRES); *YRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA) - 1; WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_BPP); *bpp = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); return TRUE; }
/* * @implemented */ VOID EXPORT NdisImmediateWritePortUshort( IN NDIS_HANDLE WrapperConfigurationContext, IN ULONG Port, IN USHORT Data) { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); WRITE_PORT_USHORT(UlongToPtr(Port), Data); // FIXME: What to do with WrapperConfigurationContext? }
VOID vOutpW(BYTE* pjIoBase, ULONG p, ULONG v) { if (((p == CRTC_INDEX) || (p == CRTC_DATA)) && (!gbCrtcCriticalSection)) { RIP("Must have acquired CRTC critical section to access CRTC register"); } CP_EIEIO(); WRITE_PORT_USHORT(pjIoBase + (p), (v)); CP_EIEIO(); }
VOID vOutFifoW( VOID* p, ULONG v) { gcFifo--; if (gcFifo < 0) { gcFifo = 0; RIP("Incorrect FIFO wait count"); } WRITE_PORT_USHORT(p, v); }
VOID EISAWritePortUSHORT ( IN ULONG BusNumber, IN ULONG Offset, IN USHORT Datum ) /*++ Routine Description: This writes EISA I/O space using a word write. On Alpha, this is identical to writing EISA memory space. Arguments: BusNumber EISA bus number, starting with 0. Offset Byte offset from the beginning of EISA space for this bus. This must be based off the .IoStart value in the EISA adapter's ConfigurationData, which is held in the Component Data Structure node. Therefore, this will already have the EISA QVA bits set up. Datum The short to be written. Return Value: None. Errors will cause either a no-op or a bugcheck. --*/ { // // Check for illegal values for Jensen. // if ((BusNumber != 0) || ((Offset & 0x3) == 0x3)) { return; } // // Call HAL library function with QVA bit or'd in. // WRITE_PORT_USHORT((PUSHORT)Offset, Datum); return; }
void __stdcall __FAKE_WRITE_PORT_USHORT(PUSHORT Port, USHORT Value) { ULONG caller; _asm { mov eax,dword ptr [ebp+4] mov dword ptr [caller],eax } if ((caller >= fltCallerEntry) && (caller < (fltCallerEntry + fltCallerSize))) DbgPrint("__FAKE_WRITE_PORT_USHORT: port %#x value %u", (ULONG)Port, (ULONG)Value); splice_uninstall(&b_wpshort); WRITE_PORT_USHORT(Port, Value); splice_install(&b_wpshort, WRITE_PORT_USHORT, __FAKE_WRITE_PORT_USHORT); }
BOOLEAN NTAPI XenGfxVbeGetModeInfo(USHORT ModeNumber, VBE_MODE_INFO* pVbeModeInfo) { const MODE_INFO_ITEM *pCurrentMode; BOOLEAN UsingLFB; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); if (!g_VbeInfoInitialized) { return FALSE; } if (pVbeModeInfo == NULL) { return FALSE; } RtlZeroMemory(pVbeModeInfo, sizeof(VBE_MODE_INFO)); UsingLFB = ((ModeNumber & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER) ? TRUE : FALSE; ModeNumber &= 0x1ff; // The spinlock is not needed since this routine just reads values from the // local mode table or from vbe ports. pCurrentMode = XenGfxFindMode(ModeNumber, UsingLFB); if (pCurrentMode == NULL) { TraceWarning(("VBE mode %04x NOT FOUND??\n", ModeNumber)); return FALSE; } TraceVerbose(("Found VBE mode 0x%04x\n", ModeNumber)); RtlCopyMemory(pVbeModeInfo, &pCurrentMode->ModeInfo, sizeof(VBE_MODE_INFO)); // Fix it up a bit. Setting WinFuncPtr for VBE_WINDOW_ATTRIBUTE_RELOCATABLE is probably not so useful... if (UsingLFB) { pVbeModeInfo->NumberOfBanks = 1; } WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_LFB_ADDRESS_H); pVbeModeInfo->PhysBasePtr = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); pVbeModeInfo->PhysBasePtr = pVbeModeInfo->PhysBasePtr << 16; TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return TRUE; }
VOID KeyboardInitialize ( IN OUT PDRIVER_LOOKUP_ENTRY LookupTableEntry, IN ULONG Entries ) /*++ Routine Description: This routine initializes the keyboard control registers, clears the fifo, and initializes the keyboard entry in the driver lookup table. Arguments: LookupTableEntry - Supplies a pointer to the first free location in the driver lookup table. Entries - Supplies the number of free entries in the driver lookup table. Return Value: None. --*/ { UCHAR Byte; // // Initialize the driver lookup table. // LookupTableEntry->DevicePath = FW_KEYBOARD_IN_DEVICE_PATH; LookupTableEntry->DispatchTable = &KeyboardEntryTable; // // Initialize static data. // FwLeftShift = FALSE; FwRightShift = FALSE; FwControl = FALSE; FwAlt = FALSE; FwCapsLock = FALSE; KbdBuffer.ReadIndex = KbdBuffer.WriteIndex = 0; // // Call the selftest keyboard initialization routine. If the keyboard // is OK, enable interrupts. // if (!InitKeyboard()) { // // Enable kbd interrupts in the keyboard controller. // SendKbdCommand(KBD_CTR_READ_COMMAND); GetKbdData(&Byte,100); // // Clear translation mode and enable Kbd interrupt. // Byte = (Byte & 0xBF) | KbdCommandEnableKbdInt; SendKbdCommand(KBD_CTR_WRITE_COMMAND); SendKbdData(Byte); #ifndef ALPHA // // Not needed for Alpha. // // // Enable keyboard interrupts in the interrupt enable register. // WRITE_PORT_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable, (1 << (KEYBOARD_VECTOR - DEVICE_VECTORS - 1))); #endif } return; }
void WriteVirtIODeviceWord(ULONG_PTR ulRegister, u16 wValue) { WRITE_PORT_USHORT((PUSHORT)(ulRegister), (USHORT)(wValue)); }
BOOLEAN IOWriteCommand( IN PCHAR Argv[], IN PFW_EXCEPTION_FRAME Frame ) /*++ Routine Description: This implements the IOWrite command given the arguments in the argc,Argv form. This writes I/O space. Arguments: Argv - array of zero terminated argument strings. Frame - the saved register & exception state. Return Value: Returns TRUE if the command is valid, FALSE otherwise. --*/ { ULONG Start; ULONG Value; UCHAR Message[32]; PCHAR Terminator; if (Argc!=3) { FwPrint(MON_INVALID_ARGUMENT_COUNT_MSG); return FALSE; } if (GetAddress(Argv[1],Frame,&Start) == FALSE) { return FALSE; } // // Check for proper alignment in I/O space. // if (// combo space check ((Start & 0xf0000000) == 0xa0000000) && (DataSize != BYTE) ) { FwPrint(MON_UNALIGNED_ADDRESS_MSG); return FALSE; } // // Convert deposit value to integer // Value = strtoul(Argv[2],&Terminator,16); if (*Terminator != '\0') { // // Not the whole string was converted. // FwPrint(Terminator); FwPrint(MON_INVALID_VALUE_MSG); return FALSE; } else { // // Do the I/O space write // switch (DataSize) { // Byte case BYTE: WRITE_PORT_UCHAR((PUCHAR)Start, Value); break; // Word case HALF: WRITE_PORT_USHORT((PUSHORT)Start, Value); break; // Longword case MON_LONGWORD: WRITE_PORT_ULONG((PULONG)Start, Value); break; // bad data size default: FwPrint(MON_BAD_IO_OPERATION_MSG); return FALSE; } } // // Set new default addresses // DefaultAddress = Start+DataSize; return TRUE; }
static VOID NTAPI XenGfxVbeVgaCompatibility(VOID) { USHORT XRes, YRes, Bpp; UCHAR Value; // Get VBE values WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_XRES); XRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_YRES); YRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA) - 1; WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_BPP); Bpp = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); // -- CRTC -- // Disable write protection for CRTC (Address=0x11, Data=0x00) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x11); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, 0x00); // Set End Horizontal Display (Address=0x01, Data=<character clocks - 1>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x01); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, (UCHAR)((XRes >> 3) - 1)); // Set Offset Register (Address=0x13, Data=<vertical width for BPP > 4>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x13); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, (UCHAR)(XRes >> 3)); // Set Vertical Display End Register (Address=0x12, Data=<end scanline counter bits 0-7>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x12); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, (UCHAR)(YRes & 0x00FF)); // Set Overflow (Address=0x07, Data=<end scanline counter bits 8-9>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x07); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA); // Clear VDE8 VDE9 and set if present in YRes Value &= 0xBD; // 10111101 mask off VDE bits Value |= (YRes & 0x100) ? 0x02 : 0x00; Value |= (YRes & 0x200) ? 0x40 : 0x00; WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, Value); // Clear Maximum Scan Line Register (Address=0x09, Data=0x00) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x09); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, 0x00); // Get CRTC Mode Control Register (Address=0x17, Data=<mode control bits>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x17); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, (Value | 0x03)); // + MAP14|MAP13 // Bpp >= 8... // Get Underline Location Register (Address=0x14, Data=<underline loc and ctrl>) WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_ADDRESS, 0x14); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA); WRITE_PORT_UCHAR((UCHAR*)VGABIOS_PORT_CRTC_DATA, (Value | 0x40)); // + DW // -- ACTL -- // Reset Attribute Control Flip-Flop rubbish (VOID)READ_PORT_UCHAR((UCHAR*)VGABIOS_PORT_ACTL_RESET); // N.B. normally a READ_PORT_UCHAR((UCHAR*)VGABIOS_ACTL_ADDRESS) would be saved to restore // at the end of reading/writing but our virtual BIOS does not need this. // Get Attribute Mode Control Register WRITE_PORT_UCHAR((UCHAR*)VGABIOS_ACTL_ADDRESS, 0x10); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_ACTL_READ_DATA); // In write mode Value |= 0x01|0x40; // + ATGE | + 8BIT WRITE_PORT_UCHAR((UCHAR*)VGABIOS_ACTL_ADDRESS, Value); // -- GRDC -- // Set Miscellaneous Graphics Register WRITE_PORT_UCHAR((UCHAR*)VGABIOS_GRDC_ADDRESS, 0x06); Value = 0x05; // <A0000h-AFFFFh (64K region) and Alpha Dis.> WRITE_PORT_UCHAR((UCHAR*)VGABIOS_GRDC_DATA, Value); // Bpp >= 8... // Set Graphics Mode Register WRITE_PORT_UCHAR((UCHAR*)VGABIOS_GRDC_ADDRESS, 0x05); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_GRDC_DATA); Value &= 0x9f; // Clear Shift256 and Shift Reg. Value |= 0x40; // + Shift256 WRITE_PORT_UCHAR((UCHAR*)VGABIOS_GRDC_DATA, Value); // -- SEQU -- // Set Map Mask Register WRITE_PORT_UCHAR((UCHAR*)VGABIOS_SEQU_ADDRESS, 0x02); Value = 0x0F; // <Write VGA display planes 3-0> WRITE_PORT_UCHAR((UCHAR*)VGABIOS_SEQU_DATA, Value); // Bpp >= 8... // Set Sequencer Memory Mode WRITE_PORT_UCHAR((UCHAR*)VGABIOS_SEQU_ADDRESS, 0x04); Value = READ_PORT_UCHAR((UCHAR*)VGABIOS_SEQU_DATA); Value |= 0x08; // + Chain 4 WRITE_PORT_UCHAR((UCHAR*)VGABIOS_SEQU_DATA, Value); }
BOOLEAN NTAPI XenGfxVbeGetExtInfo(VBE_EXT_INFO *pVbeExtInfo, ULONG *pModeCount) { USHORT XRes, YRes; ULONG Count = 0; USHORT *pModeNumbers; MODE_INFO_ITEM *pCurrentMode; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); if (!g_VbeInfoInitialized) { return FALSE; } if ((pVbeExtInfo == NULL)||(pModeCount == NULL)) { return FALSE; } RtlZeroMemory(pVbeExtInfo, sizeof(VBE_EXT_INFO)); *pModeCount = 0; // The spinlock is not needed since this routine just reads values from the // local mode table or from vbe ports. // VBE Signature pVbeExtInfo->Signature[0] = 'V'; pVbeExtInfo->Signature[1] = 'E'; pVbeExtInfo->Signature[2] = 'S'; pVbeExtInfo->Signature[3] = 'A'; // VBE Version supported pVbeExtInfo->Version = 0x0200; // Capabilities (only 1) pVbeExtInfo->Capabilities[0] = VBE_CAPABILITY_8BIT_DAC; // VBE Video Mode Pointer - this isn't really used since we are not making // int10 calls but for convenience, stick the offset in there. At this offset // each of the mode numbers from the table will be stored. pVbeExtInfo->VideoModeSeg = g_VbeTable.ModesSeg; pVbeExtInfo->VideoModeOffset = VBE_VESA_MODE_POINTER_OFFSET; // VBE Total Memory (in 64b blocks) WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); pVbeExtInfo->TotalMemory = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); // Setup to load mode values WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_EDID_XRES); XRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_EDID_YRES); YRes = READ_PORT_USHORT((USHORT*)VBE_PORT_DATA); pModeNumbers = (USHORT*)(((UCHAR*)pVbeExtInfo) + VBE_VESA_MODE_POINTER_OFFSET); pCurrentMode = (MODE_INFO_ITEM*)g_ModeInfoList; // Now load the mode numbers while (pCurrentMode->ModeNumber != XENVBE_MODE_END_OF_LIST) { if ((pCurrentMode->ModeInfo.XResolution <= XRes)&& (pCurrentMode->ModeInfo.YResolution <= YRes)&& (pCurrentMode->ModeInfo.BitsPerPixel == XENVBE_BITS_PER_PIXEL)) { *pModeNumbers = pCurrentMode->ModeNumber; TraceVerbose(("VBE mode 0x%04x (xres=0x%04x / yres=0x%04x / bpp=0x%02x) stored @index=%d\n", pCurrentMode->ModeNumber, pCurrentMode->ModeInfo.XResolution, pCurrentMode->ModeInfo.YResolution, pCurrentMode->ModeInfo.BitsPerPixel, Count)); pModeNumbers++; Count++; } else { TraceVerbose(("VBE mode 0x%04x (xres=0x%04x / yres=0x%04x / bpp=0x%02x) not supported.\n", pCurrentMode->ModeNumber, pCurrentMode->ModeInfo.XResolution, pCurrentMode->ModeInfo.YResolution, pCurrentMode->ModeInfo.BitsPerPixel)); } pCurrentMode++; } // Terminate the mode number list *(pModeNumbers + 1) = XENVBE_MODE_END_OF_LIST; *pModeCount = Count; TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return TRUE; }
NTSTATUS hwinterfaceDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp) { PIO_STACK_LOCATION stkloc; NTSTATUS ntStatus = STATUS_SUCCESS; struct tagPhys32Struct Phys32Struct; PUCHAR cData; PUSHORT sData; PULONG lData; PUSHORT address; ULONG inBuffersize; ULONG outBuffersize; ULONG inBuf; PVOID CtrlBuff; stkloc = IoGetCurrentIrpStackLocation( pIrp ); inBuffersize = stkloc->Parameters.DeviceIoControl.InputBufferLength; outBuffersize = stkloc->Parameters.DeviceIoControl.OutputBufferLength; CtrlBuff = pIrp->AssociatedIrp.SystemBuffer; cData = (PUCHAR) CtrlBuff; sData = (PUSHORT) CtrlBuff; lData = (PULONG) CtrlBuff; address = (PUSHORT) CtrlBuff; switch ( stkloc->Parameters.DeviceIoControl.IoControlCode ) { case IOCTL_READ_PORT_UCHAR: if ((inBuffersize >= 2) && (outBuffersize >= 1)) { UCHAR value; value = READ_PORT_UCHAR((PUCHAR)address[0]); cData[0] = value; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; } pIrp->IoStatus.Information = sizeof(UCHAR); ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_UCHAR: if (inBuffersize >= 3) { WRITE_PORT_UCHAR((PUCHAR)address[0], cData[2]); //Byte 0,1=Address Byte 2=Value pIrp->IoStatus.Information = 10; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; ntStatus = STATUS_SUCCESS; } break; case IOCTL_READ_PORT_USHORT: if ((inBuffersize >= 2) && (outBuffersize >= 2)) { USHORT value; value = READ_PORT_USHORT((PUSHORT)address[0]); sData[0] = value; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; } pIrp->IoStatus.Information = sizeof(USHORT); ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_USHORT: if (inBuffersize >= 4) { WRITE_PORT_USHORT((PUSHORT)address[0], sData[1]); //Short 0=Address Short 1=Value pIrp->IoStatus.Information = 10; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; ntStatus = STATUS_SUCCESS; } break; case IOCTL_READ_PORT_ULONG: if ((inBuffersize >= 4) && (outBuffersize >= 4)) { ULONG value; value = READ_PORT_ULONG((PULONG)address[0]); lData[0] = value; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; } pIrp->IoStatus.Information = sizeof(ULONG); ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_ULONG: if (inBuffersize >= 8) { WRITE_PORT_ULONG(&(lData[0]), lData[1]); //Short 0=Address long 1=Value pIrp->IoStatus.Information = 10; } else { ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; ntStatus = STATUS_SUCCESS; } break; case IOCTL_WINIO_MAPPHYSTOLIN: if (inBuffersize) { memcpy (&Phys32Struct, CtrlBuff, inBuffersize); ntStatus = MapPhysicalMemoryToLinearSpace(Phys32Struct.pvPhysAddress, Phys32Struct.dwPhysMemSizeInBytes, &Phys32Struct.pvPhysMemLin, &Phys32Struct.PhysicalMemoryHandle); if (NT_SUCCESS(ntStatus)) { memcpy (CtrlBuff, &Phys32Struct, inBuffersize); pIrp->IoStatus.Information = inBuffersize; } pIrp->IoStatus.Status = ntStatus; } else pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; case IOCTL_WINIO_UNMAPPHYSADDR: if (inBuffersize) { memcpy (&Phys32Struct, CtrlBuff, inBuffersize); ntStatus = UnmapPhysicalMemory(Phys32Struct.PhysicalMemoryHandle, Phys32Struct.pvPhysMemLin); pIrp->IoStatus.Status = ntStatus; } else pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; default: ntStatus = STATUS_UNSUCCESSFUL; pIrp->IoStatus.Information = 0; break; } pIrp->IoStatus.Status = ntStatus; IoCompleteRequest( pIrp, IO_NO_INCREMENT ); return ntStatus; }
VOID KdpWriteIoSpaceExtended ( IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context ) /*++ Routine Description: This function is called in response of a read io space extended state manipulation message. Its function is to read system io locations. Arguments: m - Supplies the state manipulation message. AdditionalData - Supplies any additional data for the message. Context - Supplies the current context. Return Value: None. --*/ { PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended; ULONG Length; STRING MessageHeader; PUCHAR b; PUSHORT s; PULONG l; ULONG BusNumber; ULONG AddressSpace; ULONG SavedAddressSpace; PHYSICAL_ADDRESS IoAddress; ULONG DataSize; PHYSICAL_ADDRESS TranslatedAddress; INTERFACE_TYPE InterfaceType; ULONG Value; MessageHeader.Length = sizeof(*m); MessageHeader.Buffer = (PCHAR)m; ASSERT(AdditionalData->Length == 0); m->ReturnStatus = STATUS_SUCCESS; InterfaceType = a->InterfaceType; BusNumber = a->BusNumber; AddressSpace = SavedAddressSpace = a->AddressSpace; IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; DataSize = a->DataSize; Value = a->DataValue; // // Translate the bus address to the physical system address // or QVA. // if( !HalTranslateBusAddress( InterfaceType, BusNumber, IoAddress, &AddressSpace, &TranslatedAddress ) ){ m->ReturnStatus = STATUS_INVALID_PARAMETER; goto SendWriteIoSpaceExtendedResponse; } // // N.B. - for the moment we will only support QVAs ie. when AddressSpace // is one. It may be in later systems that we will have to // check the address space, map it, perform the virtual read // unmap, and then return the data - only we will have to be // careful about what Irql we are to make sure the memory mgmt // stuff will all work // if( !AddressSpace ){ m->ReturnStatus = STATUS_INVALID_PARAMETER; goto SendWriteIoSpaceExtendedResponse; } // // Do the IO space read using the appropriate HAL routines based upon // the original address space and the data size requested. // if( !SavedAddressSpace ){ // // Memory (buffer) space on the bus // switch( DataSize ){ case 1: WRITE_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); break; case 2: WRITE_REGISTER_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value ); break; case 4: WRITE_REGISTER_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); break; default: m->ReturnStatus = STATUS_INVALID_PARAMETER; } } else { // // I/O space on the bus // switch( DataSize ){ case 1: WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); break; case 2: WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value); break; case 4: WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); break; default: m->ReturnStatus = STATUS_INVALID_PARAMETER; } } SendWriteIoSpaceExtendedResponse: KdpSendPacket( PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, NULL ); }
STDMETHODIMP_(void) CCMIAdapter::writeUInt16(UInt8 cmd, UInt16 value) { WRITE_PORT_USHORT((PUSHORT)(reinterpret_cast<PUCHAR>(cm.IOBase) + cmd), value); }
NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter HelloDDKDeviceIOControl\n")); //得到当前堆栈 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); //得到输入缓冲区大小 ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; //得到输出缓冲区大小 ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; //得到IOCTL码 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; ULONG info = 0; switch (code) { // process request case READ_PORT: { KdPrint(("READ_PORT\n")); //缓冲区方式IOCTL //显示输入缓冲区数据 PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; ULONG port = (ULONG)(*InputBuffer); InputBuffer++; UCHAR method = (UCHAR)(*InputBuffer); KdPrint(("port:%x\n",port)); KdPrint(("method:%x\n",method)); //操作输出缓冲区 PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; if (method==1)//8位操作 { *OutputBuffer = READ_PORT_UCHAR((PUCHAR)port); }else if(method==2)//16位操作 { *OutputBuffer = READ_PORT_USHORT((PUSHORT)port); }else if(method==4)//32位操作 { *OutputBuffer = READ_PORT_ULONG((PULONG)port); } //设置实际操作输出缓冲区长度 info = 4; break; } case WRITE_PORT: { KdPrint(("WRITE_PORT\n")); //缓冲区方式IOCTL //显示输入缓冲区数据 PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; ULONG port = (ULONG)(*InputBuffer); InputBuffer++; UCHAR method = (UCHAR)(*InputBuffer); InputBuffer++; ULONG value = (ULONG)(*InputBuffer); KdPrint(("port:%x\n",port)); KdPrint(("method:%x\n",method)); KdPrint(("value:%x\n",value)); //操作输出缓冲区 PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; if (method==1)//8位操作 { WRITE_PORT_UCHAR((PUCHAR)port,(UCHAR)value); }else if(method==2)//16位操作 { WRITE_PORT_USHORT((PUSHORT)port,(USHORT)value); }else if(method==4)//32位操作 { WRITE_PORT_ULONG((PULONG)port,(ULONG)value); } //设置实际操作输出缓冲区长度 info = 0; break; } default: status = STATUS_INVALID_VARIANT; } // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = info; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDeviceIOControl\n")); return status; }
BOOLEAN NTAPI VgaInterpretCmdStream(IN PUSHORT CmdStream) { PUCHAR Base = (PUCHAR)VgaRegisterBase; USHORT Cmd; UCHAR Major, Minor; USHORT Count; UCHAR Index; PUSHORT Buffer; PUSHORT ShortPort; PUCHAR Port; UCHAR Value; USHORT ShortValue; /* First make sure that we have a Command Stream */ if (!CmdStream) return TRUE; /* Loop as long as we have commands */ while (*CmdStream) { /* Get the Major and Minor Function */ Cmd = *CmdStream; Major = Cmd & 0xF0; Minor = Cmd & 0x0F; /* Move to the next command */ CmdStream++; /* Check which major function this was */ if (Major == 0x10) { /* Now let's see the minor function */ if (Minor & CMD_STREAM_READ) { /* Now check the sub-type */ if (Minor & CMD_STREAM_USHORT) { /* The port is what is in the stream right now */ ShortPort = UlongToPtr((ULONG)*CmdStream); /* Move to the next command */ CmdStream++; /* Read USHORT from the port */ READ_PORT_USHORT(PtrToUlong(Base) + ShortPort); } else { /* The port is what is in the stream right now */ Port = UlongToPtr((ULONG)*CmdStream); /* Move to the next command */ CmdStream++; /* Read UCHAR from the port */ READ_PORT_UCHAR(PtrToUlong(Base) + Port); } } else if (Minor & CMD_STREAM_WRITE_ARRAY) { /* Now check the sub-type */ if (Minor & CMD_STREAM_USHORT) { /* The port is what is in the stream right now */ ShortPort = UlongToPtr(Cmd); /* Move to the next command and get the count */ Count = *(CmdStream++); /* The buffer is what's next in the command stream */ Buffer = CmdStream++; /* Write USHORT to the port */ WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base) + ShortPort, Buffer, Count); /* Move past the buffer in the command stream */ CmdStream += Count; } else { /* The port is what is in the stream right now */ Port = UlongToPtr(Cmd); /* Move to the next command and get the count */ Count = *(CmdStream++); /* Add the base to the port */ Port = PtrToUlong(Port) + Base; /* Move to next command */ CmdStream++; /* Loop the cmd array */ for (; Count; Count--, CmdStream++) { /* Get the byte we're writing */ Value = (UCHAR)*CmdStream; /* Write UCHAR to the port */ WRITE_PORT_UCHAR(Port, Value); } } } else if (Minor & CMD_STREAM_USHORT) { /* Get the ushort we're writing and advance in the stream */ ShortValue = *CmdStream; CmdStream++; /* Write USHORT to the port (which is in cmd) */ WRITE_PORT_USHORT((PUSHORT)Base + Cmd, ShortValue); } else { /* The port is what is in the stream right now */ Port = UlongToPtr((ULONG)*CmdStream); /* Get the uchar we're writing */ Value = (UCHAR)*++CmdStream; /* Move to the next command */ CmdStream++; /* Write UCHAR to the port (which is in cmd) */ WRITE_PORT_UCHAR(PtrToUlong(Base) + Port, Value); } } else if (Major == 0x20) { /* Check the minor function. Note these are not flags anymore. */ switch (Minor) { case 0: /* The port is what is in the stream right now */ ShortPort = UlongToPtr(*CmdStream); /* Move to the next command and get the count */ Count = *(CmdStream++); /* Move to the next command and get the value to write */ ShortValue = *(CmdStream++); /* Add the base to the port */ ShortPort = PtrToUlong(ShortPort) + (PUSHORT)Base; /* Move to next command */ CmdStream++; /* Make sure we have data */ if (!ShortValue) continue; /* Loop the cmd array */ for (; Count; Count--, CmdStream++) { /* Get the byte we're writing */ ShortValue += (*CmdStream) << 8; /* Write USHORT to the port */ WRITE_PORT_USHORT(ShortPort, ShortValue); } break; case 1: /* The port is what is in the stream right now. Add the base too */ Port = *CmdStream + Base; /* Move to the next command and get the count */ Count = *++CmdStream; /* Move to the next command and get the index to write */ Index = (UCHAR)*++CmdStream; /* Move to next command */ CmdStream++; /* Loop the cmd array */ for (; Count; Count--, Index++) { /* Write the index */ WRITE_PORT_UCHAR(Port, Index); /* Get the byte we're writing */ Value = (UCHAR)*CmdStream; /* Move to next command */ CmdStream++; /* Write UCHAR value to the port */ WRITE_PORT_UCHAR(Port, Value); } break; case 2: /* The port is what is in the stream right now. Add the base too */ Port = *CmdStream + Base; /* Read the current value and add the stream data */ Value = READ_PORT_UCHAR(Port); Value &= *CmdStream++; Value ^= *CmdStream++; /* Write the value */ WRITE_PORT_UCHAR(Port, Value); break; default: /* Unknown command, fail */ return FALSE; } } else if (Major != 0xF0) { /* Unknown major function, fail */ return FALSE; } /* Get the next command */ Cmd = *CmdStream; } /* If we got here, return success */ return TRUE; }
BOOLEAN NTAPI VgaIsPresent(VOID) { UCHAR VgaReg, VgaReg2, VgaReg3; UCHAR SeqReg, SeqReg2; UCHAR i; /* Read the VGA Address Register */ VgaReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE); /* Select Read Map Select Register */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); /* Read it back...it should be 4 */ if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 4) return FALSE; /* Read the VGA Data Register */ VgaReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF); /* Enable all planes */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 3); /* Read it back...it should be 3 */ if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 0x3) { /* Reset the registers and fail */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); return FALSE; } /* Select Bit Mask Register */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); /* Read it back...it should be 8 */ if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 8) { /* Reset the registers and fail */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); return FALSE; } /* Read the VGA Data Register */ VgaReg3 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF); /* Loop bitmasks */ for (i = 0xBB; i; i >>= 1) { /* Set bitmask */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, i); /* Read it back...it should be the same */ if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != i) { /* Reset the registers and fail */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); return FALSE; } } /* Select Read Map Select Register */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); /* Read it back...it should be 3 */ if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 3) { /* Reset the registers and fail */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); return FALSE; } /* Write the registers we read earlier */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg2); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg3); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, VgaReg); /* Read sequencer address */ SeqReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4); /* Select memory mode register */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, 4); /* Read it back...it should still be 4 */ if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4)) & 7) != 4) { /* Fail */ return FALSE; } /* Read sequencer Data */ SeqReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5); /* Write null plane */ WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x100); /* Write sequencer flag */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2 ^ 8); /* Read it back */ if ((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5)) != (SeqReg2 ^ 8)) { /* Not the same value...restore registers and fail */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, 2); WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); return FALSE; } /* Now write the registers we read */ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2); WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, SeqReg); /* VGA is present! */ return TRUE; }
BOOLEAN NTAPI XenGfxVbeSetMode(USHORT ModeNumber) { const MODE_INFO_ITEM *pCurrentMode; BOOLEAN UsingLFB; USHORT FlagLFB, FlagNoClear; USHORT StrideAlign; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); if (!g_VbeInfoInitialized) { return FALSE; } ModeNumber &= 0x1FF; if (ModeNumber < VBE_MODE_VESA_DEFINED) { TraceError(("Could not set non-VBE mode!\n")); return FALSE; } // Get mode attributes UsingLFB = ((ModeNumber & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER) ? TRUE : FALSE; FlagLFB = (UsingLFB) ? VBE_DISPI_LFB_ENABLED : 0; FlagNoClear = ((ModeNumber & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY) ? VBE_DISPI_NOCLEARMEM : 0; pCurrentMode = XenGfxFindMode(ModeNumber, UsingLFB); if (pCurrentMode == NULL) { TraceWarning(("VBE mode %04x NOT FOUND (and not set)??\n", ModeNumber)); return FALSE; } TraceVerbose(("Set VBE mode 0x%04x (xres=0x%04x / yres=0x%04x / bpp=0x%02x) found.\n", pCurrentMode->ModeNumber, pCurrentMode->ModeInfo.XResolution, pCurrentMode->ModeInfo.YResolution, pCurrentMode->ModeInfo.BitsPerPixel)); // Need to lock here - this is going to change the mode and the state of the // emulated video card. XenGfxInt10SpinLock((UCHAR*)VGA_PORT_RANGE_BASE); // Disable while setting VESA modes. WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_ENABLE); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, VBE_DISPI_DISABLED); // N.B. don't need to worry about setting up 4 BPP modes for XenVesa // Set BPP, X and Y res, stride, bank WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_BPP); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, pCurrentMode->ModeInfo.BitsPerPixel); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_XRES); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, pCurrentMode->ModeInfo.XResolution); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_YRES); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, pCurrentMode->ModeInfo.YResolution); //New feature... StrideAlign = XenGfxVbeGetAlignedStride(pCurrentMode->ModeInfo.BytesPerScanLine); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_STRIDE); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, StrideAlign); WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_BANK); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, 0); // Store some of the VGA port values as in the vBIOS. Note we only need to write our shadow // ports at this point since we switched to exclusive shadow use. WRITE_PORT_USHORT((USHORT*)VGA_PORT_VBE_MODE, ModeNumber); WRITE_PORT_USHORT((USHORT*)VGA_PORT_VIDEO_CTL, (0x60|FlagNoClear)); // Enable new VESA mode WRITE_PORT_USHORT((USHORT*)VBE_PORT_INDEX, VBE_DISPI_INDEX_ENABLE); WRITE_PORT_USHORT((USHORT*)VBE_PORT_DATA, VBE_DISPI_ENABLED|FlagLFB|FlagNoClear); XenGfxInt10SpinUnlock((UCHAR*)VGA_PORT_RANGE_BASE); TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return TRUE; }