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; }
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; }
USHORT NTAPI VideoPortReadPortUshort( PUSHORT Port) { return READ_PORT_USHORT(Port); }
USHORT ScsiPortReadPortUshort( IN PUSHORT Port ) /*++ Routine Description: Read from the specified port address. Arguments: Port - Supplies a pointer to the port address. Return Value: Returns the value read from the specified port address. --*/ { return(READ_PORT_USHORT(Port)); }
ACPI_STATUS AcpiOsReadPort ( ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width) { DPRINT("AcpiOsReadPort %p, width %d\n",Address,Width); switch (Width) { case 8: *Value = READ_PORT_UCHAR((PUCHAR)Address); break; case 16: *Value = READ_PORT_USHORT((PUSHORT)Address); break; case 32: *Value = READ_PORT_ULONG((PULONG)Address); break; default: DPRINT1("AcpiOsReadPort got bad width: %d\n",Width); return (AE_BAD_PARAMETER); break; } return (AE_OK); }
USHORT NTAPI ScsiPortReadPortUshort( IN PUSHORT Port) { return READ_PORT_USHORT(Port); }
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; }
/* * @implemented */ VOID EXPORT NdisImmediateReadPortUshort( IN NDIS_HANDLE WrapperConfigurationContext, IN ULONG Port, OUT PUSHORT Data) { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); *Data = READ_PORT_USHORT(UlongToPtr(Port)); // FIXME: What to do with WrapperConfigurationContext? }
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; }
BOOLEAN NTAPI XenGfxVbeInitialize(UCHAR *pShadowPortBase) { ULONG Addr; PHYSICAL_ADDRESS PhysAddr = {0}; UCHAR *pVirtAddr; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); if (g_VbeInfoInitialized) { TraceVerbose(("VBE support already initialized?\n")); return FALSE; } // Pull up the VBE table information from the VBE BIOS area. Addr = (READ_PORT_USHORT((USHORT*)(pShadowPortBase + VGA_PORT_VBE_XVTSEG)) & (0x0000FFFF)) << 4; Addr = Addr | (READ_PORT_USHORT((USHORT*)(pShadowPortBase + VGA_PORT_VBE_XVTADDR)) & (0x0000FFFF)); PhysAddr.LowPart = Addr; pVirtAddr = (UCHAR*)MmMapIoSpace(PhysAddr, sizeof(VBE_XENVESA_TABLE), MmNonCached); if (pVirtAddr == NULL) { TraceError(("Could not MAP in VBE info table!\n")); return FALSE; } RtlCopyMemory(&g_VbeTable, pVirtAddr, sizeof(VBE_XENVESA_TABLE)); MmUnmapIoSpace(pVirtAddr, sizeof(VBE_XENVESA_TABLE)); // Sanity check the tag for the table if (RtlCompareMemory(g_VbeTable.Tag, VBE_XENVESA_TAG, sizeof(g_VbeTable.Tag)) != sizeof(g_VbeTable.Tag)) { TraceError(("Invalid VBE info tag?? Tag value: %.*s\n", sizeof(g_VbeTable.Tag) - 1, g_VbeTable.Tag)); return FALSE; } // Pull up the Vesa mode information once up front. if (!XenGfxPullUpModeInfo()) { // Errors traced in call return FALSE; } g_VbeInfoInitialized = TRUE; TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return TRUE; }
USHORT wInpW(BYTE* pjIoBase, ULONG p) { if (((p == CRTC_INDEX) || (p == CRTC_DATA)) && (!gbCrtcCriticalSection)) { RIP("Must have acquired CRTC critical section to access CRTC register"); } CP_EIEIO(); return(READ_PORT_USHORT(pjIoBase + (p))); }
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; }
USHORT EISAReadPortUSHORT ( IN ULONG BusNumber, IN ULONG Offset ) /*++ Routine Description: This reads EISA I/O space using a word read. On Alpha, this is identical to reading EISA memory space. On Alpha/Jensen we check for a read to 0C80--0C83, and manually return the EISA System Board ID bytes. 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. Return Value: This returns the word read. On an error, 0 is returned. --*/ { // // Check for illegal values for Jensen. // if ((BusNumber != 0) || ((Offset & 0x3) == 0x3)) { return (0); } // // Trap reads to System Board ID bytes and return Jensen ID bytes. // which correspond to the EISA identifier "DEC2400". // switch (Offset & 0xffff) { case 0x0c80: return 0xa310; case 0x0c82: return 0x0024; } // // Call HAL library function with QVA bit or'd in. // return (READ_PORT_USHORT((PUSHORT)Offset)); }
u16 ReadVirtIODeviceWord(ULONG_PTR ulRegister) { return READ_PORT_USHORT((PUSHORT)(ulRegister)); }
BOOLEAN IOReadCommand( IN PCHAR Argv[], IN PFW_EXCEPTION_FRAME Frame ) /*++ Routine Description: This implements the IORead command given the arguments in the argc,Argv form. This reads 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; UCHAR Message[32]; if (Argc!=2) { 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 ((Start & 0xf0000000) == 0xa0000000) && (DataSize != BYTE) ) ) { FwPrint(MON_UNALIGNED_ADDRESS_MSG); return FALSE; } // // Do the I/O space read. // switch (DataSize) { // Byte case BYTE: sprintf(Message,"0x%08lx: 0x%02x\r\n", Start, READ_PORT_UCHAR((PUCHAR)Start)); FwPrint(Message); break; // Word case HALF: sprintf(Message,"0x%08lx: 0x%04x\r\n", Start, READ_PORT_USHORT((PUSHORT)Start)); FwPrint(Message); break; // Longword case MON_LONGWORD: sprintf(Message,"0x%08lx: 0x%08x\r\n", Start, READ_PORT_ULONG((PULONG)Start)); FwPrint(Message); 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); }
VOID KdpReadIoSpaceExtended ( 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; 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; // // Zero the return data value. // a->DataValue = 0; // // Translate the bus address to the physical system address // or QVA. // if( !HalTranslateBusAddress( InterfaceType, BusNumber, IoAddress, &AddressSpace, &TranslatedAddress ) ){ m->ReturnStatus = STATUS_INVALID_PARAMETER; goto SendReadIoSpaceExtendedResponse; } // // 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 SendReadIoSpaceExtendedResponse; } // // 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: a->DataValue = READ_REGISTER_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart ); break; case 2: a->DataValue = READ_REGISTER_USHORT((PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart ); break; case 4: a->DataValue = READ_REGISTER_ULONG((PULONG)(ULONG_PTR) TranslatedAddress.QuadPart ); break; default: m->ReturnStatus = STATUS_INVALID_PARAMETER; } } else { // // I/O space on the bus // switch( DataSize ){ case 1: a->DataValue = READ_PORT_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart ); break; case 2: a->DataValue = READ_PORT_USHORT( (PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart ); break; case 4: a->DataValue = READ_PORT_ULONG( (PULONG)(ULONG_PTR) TranslatedAddress.QuadPart ); break; default: m->ReturnStatus = STATUS_INVALID_PARAMETER; } } SendReadIoSpaceExtendedResponse: KdpSendPacket( PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, NULL ); }
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; }
STDMETHODIMP_(UInt16) CCMIAdapter::readUInt16(UInt8 reg) { return READ_PORT_USHORT((PUSHORT)(reinterpret_cast<PUCHAR>(cm.IOBase) + reg)); }
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 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; }