Пример #1
0
BOOLEAN NTAPI
XboxVmpInitialize(PVOID HwDeviceExtension)
{
  PXBOXVMP_DEVICE_EXTENSION XboxVmpDeviceExtension;
  ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
  ULONG Length;

  VideoPortDebugPrint(Trace, "XboxVmpInitialize\n");

  XboxVmpDeviceExtension = (PXBOXVMP_DEVICE_EXTENSION) HwDeviceExtension;

  Length = XboxVmpDeviceExtension->ControlLength;
  XboxVmpDeviceExtension->VirtControlStart = NULL;
  if (NO_ERROR != VideoPortMapMemory(HwDeviceExtension,
                                     XboxVmpDeviceExtension->PhysControlStart,
                                     &Length, &inIoSpace,
                                     &XboxVmpDeviceExtension->VirtControlStart))
    {
      VideoPortDebugPrint(Error, "Failed to map control memory\n");
      return FALSE;
    }
  VideoPortDebugPrint(Info, "Mapped 0x%x bytes of control mem at 0x%x to virt addr 0x%x\n",
         XboxVmpDeviceExtension->ControlLength,
         XboxVmpDeviceExtension->PhysControlStart.u.LowPart,
         XboxVmpDeviceExtension->VirtControlStart);

  return TRUE;
}
Пример #2
0
VP_STATUS QueryPublicAccessRanges_m(PVIDEO_REQUEST_PACKET RequestPacket)
{
    PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
    PHYSICAL_ADDRESS physicalPortBase;
    ULONG physicalPortLength;

    if ( RequestPacket->OutputBufferLength <
        (RequestPacket->StatusBlock->Information =
        sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
        {
        return ERROR_INSUFFICIENT_BUFFER;
        }

    portAccess = RequestPacket->OutputBuffer;
	   
    portAccess->VirtualAddress  = (PVOID) NULL;    // Requested VA
    portAccess->InIoSpace       = 1;               // In IO space
    portAccess->MappedInIoSpace = portAccess->InIoSpace;

    physicalPortBase.HighPart   = 0x00000000;
    physicalPortBase.LowPart    = 0x00000000;
//    physicalPortLength          = LINEDRAW+2 - physicalPortBase.LowPart;
    physicalPortLength = 0x10000;


// *SANITIZE* If MM available, give MM ports instead.

    return VideoPortMapMemory(phwDeviceExtension,
                              physicalPortBase,
                              &physicalPortLength,
                              &(portAccess->MappedInIoSpace),
                              &(portAccess->VirtualAddress));

}   /* QueryPublicAccessRanges_m() */
Пример #3
0
BOOLEAN  VGAMapVideoMemory(IN PVOID DeviceExtension,
                           IN PVIDEO_MEMORY  RequestedAddress,
                           OUT PVIDEO_MEMORY_INFORMATION  MapInformation,
                           OUT PSTATUS_BLOCK  StatusBlock)
{
    ULONG ReturnedLength;
    PVOID ReturnedAddress;
    ULONG IoSpace;
    PHYSICAL_ADDRESS FrameBufferBase;
    ReturnedAddress = RequestedAddress->RequestedVirtualAddress;
    ReturnedLength = 256 * 1024;
    FrameBufferBase.QuadPart = 0xA0000;
    IoSpace = VIDEO_MEMORY_SPACE_MEMORY;
    StatusBlock->Status = VideoPortMapMemory(DeviceExtension,
                          FrameBufferBase,
                          &ReturnedLength,
                          &IoSpace,
                          &ReturnedAddress);
    if (StatusBlock->Status != 0)
    {
        StatusBlock->Information = 0;
        return TRUE;
    }
    MapInformation->VideoRamBase = MapInformation->FrameBufferBase =
                                       ReturnedAddress;
    MapInformation->VideoRamLength = MapInformation->FrameBufferLength =
                                         ReturnedLength;
    StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
    return TRUE;
}
Пример #4
0
BOOLEAN FASTCALL
XboxVmpMapVideoMemory(
   PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MEMORY RequestedAddress,
   PVIDEO_MEMORY_INFORMATION MapInformation,
   PSTATUS_BLOCK StatusBlock)
{
  PHYSICAL_ADDRESS FrameBuffer;
  ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
  SYSTEM_BASIC_INFORMATION BasicInfo;
  ULONG Length;

  /* FIXME: this should probably be done differently, without native API */
  StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);

  FrameBuffer.u.HighPart = 0;
  if (ZwQuerySystemInformation(SystemBasicInformation,
                                          (PVOID) &BasicInfo,
                                          sizeof(SYSTEM_BASIC_INFORMATION),
                                          &Length) == NO_ERROR)
    {
      FrameBuffer.u.LowPart = BasicInfo.HighestPhysicalPageNumber * PAGE_SIZE;
    }
  else
    {
      VideoPortDebugPrint(Error, "ZwQueryBasicInformation failed, assuming 64MB total memory\n");
      FrameBuffer.u.LowPart = 60 * 1024 * 1024;
    }

  FrameBuffer.QuadPart += DeviceExtension->PhysFrameBufferStart.QuadPart;
  MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
  MapInformation->VideoRamLength = 4 * 1024 * 1024;
  VideoPortMapMemory(DeviceExtension, FrameBuffer,
      &MapInformation->VideoRamLength, &inIoSpace,
      &MapInformation->VideoRamBase);

  MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
  MapInformation->FrameBufferLength = MapInformation->VideoRamLength;

  /* Tell the nVidia controller about the framebuffer */
  *((PULONG)((char *) DeviceExtension->VirtControlStart + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = FrameBuffer.u.LowPart;

  VideoPortDebugPrint(Info, "Mapped 0x%x bytes of phys mem at 0x%lx to virt addr 0x%p\n",
          MapInformation->VideoRamLength, FrameBuffer.u.LowPart, MapInformation->VideoRamBase);

  return TRUE;
}
int VBoxMPCmnMapAdapterMemory(PVBOXMP_COMMON pCommon, void **ppv, uint32_t ulOffset, uint32_t ulSize)
{
    PVBOXMP_DEVEXT pPEXT = VBoxCommonToPrimaryExt(pCommon);

    LOGF(("0x%08X[0x%X]", ulOffset, ulSize));

    if (!ulSize)
    {
        WARN(("Illegal length 0!"));
        return ERROR_INVALID_PARAMETER;
    }

    PHYSICAL_ADDRESS FrameBuffer;
    FrameBuffer.QuadPart = VBoxCommonFromDeviceExt(pPEXT)->phVRAM.QuadPart + ulOffset;

    PVOID VideoRamBase = NULL;
    ULONG VideoRamLength = ulSize;
    VP_STATUS Status;
#ifndef VBOX_WITH_WDDM
    ULONG inIoSpace = 0;

    Status = VideoPortMapMemory(pPEXT, FrameBuffer, &VideoRamLength, &inIoSpace, &VideoRamBase);
#else
    NTSTATUS ntStatus = pPEXT->u.primary.DxgkInterface.DxgkCbMapMemory(pPEXT->u.primary.DxgkInterface.DeviceHandle,
            FrameBuffer,
            VideoRamLength,
            FALSE, /* IN BOOLEAN InIoSpace */
            FALSE, /* IN BOOLEAN MapToUserMode */
            MmNonCached, /* IN MEMORY_CACHING_TYPE CacheType */
            &VideoRamBase /*OUT PVOID *VirtualAddress*/
            );
    Assert(ntStatus == STATUS_SUCCESS);
    /* this is what VideoPortMapMemory returns according to the docs */
    Status = ntStatus == STATUS_SUCCESS ? NO_ERROR : ERROR_INVALID_PARAMETER;
#endif

    if (Status == NO_ERROR)
    {
        *ppv = VideoRamBase;
    }

    LOGF(("rc = %d", Status));

    return (Status==NO_ERROR) ? VINF_SUCCESS:VERR_INVALID_PARAMETER;
}
Пример #6
0
/* Called for IOCTL_VIDEO_SHARE_VIDEO_MEMORY.
 * Maps FrameBuffer as a linear frame buffer to a caller's virtual adress space. (obsolete).
 */
BOOLEAN VBoxMPShareVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_SHARE_MEMORY pShareMem,
                               PVIDEO_SHARE_MEMORY_INFORMATION pShareMemInfo, PSTATUS_BLOCK pStatus)
{
    PHYSICAL_ADDRESS shareAddress;
    ULONG inIoSpace = 0;
    ULONG offset, size;
    PVOID virtualAddress;
    ULONG ulMaxFBSize;

    LOGF_ENTER();

    ulMaxFBSize = pExt->pPrimary->u.primary.ulMaxFrameBufferSize;
    offset = pShareMem->ViewOffset;
    size = pShareMem->ViewSize;
    virtualAddress = pShareMem->ProcessHandle;
    VBOXMPIOCTL_HIDE(pShareMem);

    if ((offset>ulMaxFBSize) || ((offset+size)>ulMaxFBSize))
    {
        WARN(("share failed offset:size(%#x:%#x) > %#x fb size.", offset, size, ulMaxFBSize));
        pStatus->Status = ERROR_INVALID_PARAMETER;
        return FALSE;
    }

    shareAddress.QuadPart = VBoxCommonFromDeviceExt(pExt)->phVRAM.QuadPart + pExt->ulFrameBufferOffset;

    pStatus->Status = VideoPortMapMemory(pExt, shareAddress, &size, &inIoSpace, &virtualAddress);

    if (NO_ERROR == pStatus->Status)
    {
        pShareMemInfo->SharedViewOffset = offset;
        pShareMemInfo->SharedViewSize = size;
        pShareMemInfo->VirtualAddress = virtualAddress;

        pStatus->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION);
    }

    VBOXMPIOCTL_UNHIDE();
    LOGF_LEAVE();
    return NO_ERROR == pStatus->Status;
}
Пример #7
0
/* Called for IOCTL_VIDEO_MAP_VIDEO_MEMORY.
 * Maps FrameBuffer and video RAM to a caller's virtual adress space.
 */
BOOLEAN VBoxMPMapVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_MEMORY pRequestedAddress,
                             PVIDEO_MEMORY_INFORMATION pMapInfo, PSTATUS_BLOCK pStatus)
{
    PHYSICAL_ADDRESS framebuffer;
    ULONG inIoSpace = 0;

    LOGF(("framebuffer offset %#x", pExt->ulFrameBufferOffset));

    framebuffer.QuadPart = VBoxCommonFromDeviceExt(pExt)->phVRAM.QuadPart + pExt->ulFrameBufferOffset;

    pMapInfo->VideoRamBase = pRequestedAddress->RequestedVirtualAddress;
    VBOXMPIOCTL_HIDE(pRequestedAddress);
    pMapInfo->VideoRamLength = pExt->pPrimary->u.primary.ulMaxFrameBufferSize;

    pStatus->Status = VideoPortMapMemory(pExt, framebuffer, &pMapInfo->VideoRamLength,
                                         &inIoSpace, &pMapInfo->VideoRamBase);

    if (NO_ERROR == pStatus->Status)
    {
        pMapInfo->FrameBufferBase = (PUCHAR)pMapInfo->VideoRamBase;
        pMapInfo->FrameBufferLength =
            VBoxMPXpdmCurrentVideoMode(pExt)->VisScreenHeight*
            VBoxMPXpdmCurrentVideoMode(pExt)->ScreenStride;

        pStatus->Information = sizeof(VIDEO_MEMORY_INFORMATION);

        /* Save the new framebuffer size */
        pExt->ulFrameBufferSize = pMapInfo->FrameBufferLength;
        HGSMIAreaInitialize(&pExt->areaDisplay, pMapInfo->FrameBufferBase,
                            pMapInfo->FrameBufferLength, pExt->ulFrameBufferOffset);
    }

    VBOXMPIOCTL_UNHIDE();
    LOGF_LEAVE();
    return NO_ERROR == pStatus->Status;
}
Пример #8
0
BOOLEAN
DGXStartIO(
    PVOID HwDeviceExtension,
    PVIDEO_REQUEST_PACKET RequestPacket
    )

/*++

Routine Description:

    This routine is the main execution routine for the miniport driver. It
    acceptss a Video Request Packet, performs the request, and then returns
    with the appropriate status.

Arguments:

    HwDeviceExtension - Supplies a pointer to the miniport's device extension.

    RequestPacket - Pointer to the video request packet. This structure
        contains all the parameters passed to the VideoIoControl function.

Return Value:


--*/

{
    PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
    VP_STATUS status;
    PVIDEO_MODE_INFORMATION modeInformation;
    PVIDEO_MEMORY_INFORMATION memoryInformation;
    ULONG inIoSpace, ulTemp;
    PVIDEO_CLUT clutBuffer;
    ULONG modeNumber;
    PVIDEO_SHARE_MEMORY pShareMemory;
    PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation;
    PHYSICAL_ADDRESS shareAddress;
    PVOID virtualAddress;
    ULONG sharedViewSize;

    //
    // Switch on the IoContolCode in the RequestPacket. It indicates which
    // function must be performed by the driver.
    //

    switch (RequestPacket->IoControlCode) {


    case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:

        VideoDebugPrint((2, "DGXStartIO - ShareVideoMemory\n"));

        if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) ||
             (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;

        }

        pShareMemory = RequestPacket->InputBuffer;

        if ( (pShareMemory->ViewOffset > hwDeviceExtension->FrameLength) ||
             ((pShareMemory->ViewOffset + pShareMemory->ViewSize) >
                  hwDeviceExtension->FrameLength) ) {

            status = ERROR_INVALID_PARAMETER;
            break;

        }

        RequestPacket->StatusBlock->Information =
                                    sizeof(VIDEO_SHARE_MEMORY_INFORMATION);

        //
        // Beware: the input buffer and the output buffer are the same
        // buffer, and therefore data should not be copied from one to the
        // other
        //

        virtualAddress = pShareMemory->ProcessHandle;
        sharedViewSize = pShareMemory->ViewSize;

        inIoSpace = 0;

        //
        // NOTE:  we are ignoring ViewOffset
        //

        shareAddress.QuadPart =
            hwDeviceExtension->PhysicalFrameAddress.QuadPart;

        status = VideoPortMapMemory(hwDeviceExtension,
                                    shareAddress,
                                    &sharedViewSize,
                                    &inIoSpace,
                                    &virtualAddress);

        pShareMemoryInformation = RequestPacket->OutputBuffer;

        pShareMemoryInformation->SharedViewOffset = pShareMemory->ViewOffset;
        pShareMemoryInformation->VirtualAddress = virtualAddress;
        pShareMemoryInformation->SharedViewSize = sharedViewSize;


        break;


    case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:

        VideoDebugPrint((2, "DGXStartIO - UnshareVideoMemory\n"));

        if (RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY)) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;

        }

        pShareMemory = RequestPacket->InputBuffer;

        status = VideoPortUnmapMemory(hwDeviceExtension,
                                      pShareMemory->RequestedVirtualAddress,
                                      pShareMemory->ProcessHandle);

        break;


    case IOCTL_VIDEO_MAP_VIDEO_MEMORY:

        VideoDebugPrint((2, "DGXStartIO - MapVideoMemory\n"));

        if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION)) ||
             (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;

        }

        RequestPacket->StatusBlock->Information =  sizeof(VIDEO_MEMORY_INFORMATION);

        memoryInformation = RequestPacket->OutputBuffer;

        memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
                (RequestPacket->InputBuffer))->RequestedVirtualAddress;

        memoryInformation->VideoRamLength = hwDeviceExtension->FrameLength;

        inIoSpace = 0;

        status = VideoPortMapMemory(hwDeviceExtension,
                                    hwDeviceExtension->PhysicalFrameAddress,
                                    &(memoryInformation->VideoRamLength),
                                    &inIoSpace,
                                    &(memoryInformation->VideoRamBase));

        //
        // The frame buffer and virtual memory and equivalent in this
        // case.
        //

        memoryInformation->FrameBufferBase = memoryInformation->VideoRamBase;
        memoryInformation->FrameBufferLength = memoryInformation->VideoRamLength;

        break;


    case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:

        VideoDebugPrint((2, "DGXStartIO - UnMapVideoMemory\n"));

        if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {

            status = ERROR_INSUFFICIENT_BUFFER;

        } else {

            status = VideoPortUnmapMemory(hwDeviceExtension,
                                          ((PVIDEO_MEMORY)
                                           (RequestPacket->InputBuffer))->
                                               RequestedVirtualAddress,
                                          0);
        }

        break;


    case IOCTL_VIDEO_QUERY_CURRENT_MODE:

        VideoDebugPrint((2, "DGXStartIO - QueryCurrentModes\n"));

        modeInformation = RequestPacket->OutputBuffer;

        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) {

            status = ERROR_INSUFFICIENT_BUFFER;

        } else {

            RequestPacket->StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);

            *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
                DGXModes[hwDeviceExtension->CurrentModeNumber].modeInformation;

            status = NO_ERROR;
        }

        break;

    case IOCTL_VIDEO_QUERY_AVAIL_MODES:

    {
        UCHAR i;

        VideoDebugPrint((2, "DGXStartIO - QueryAvailableModes\n"));

        if (RequestPacket->OutputBufferLength <
                hwDeviceExtension->NumValidModes * sizeof(VIDEO_MODE_INFORMATION)) {

            status = ERROR_INSUFFICIENT_BUFFER;

        } else {

            RequestPacket->StatusBlock->Information =
                 hwDeviceExtension->NumValidModes * sizeof(VIDEO_MODE_INFORMATION);

            modeInformation = RequestPacket->OutputBuffer;

            for (i = 0; i < NumDGXModes; i++) {

                if (DGXModes[i].bValid) {

                    *modeInformation = DGXModes[i].modeInformation;
                    modeInformation++;

                }
            }

            status = NO_ERROR;
        }

        break;
    }


    case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:

        VideoDebugPrint((2, "DGXStartIO - QueryNumAvailableModes\n"));

        //
        // Find out the size of the data to be put in the the buffer and
        // return that in the status information (whether or not the
        // information is there). If the buffer passed in is not large
        // enough return an appropriate error code.
        //
        // WARNING: This must be changed to take into account which monitor
        // is present on the machine.
        //

        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) {

            status = ERROR_INSUFFICIENT_BUFFER;

        } else {

            RequestPacket->StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
            ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
                hwDeviceExtension->NumValidModes;
            ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
                sizeof(VIDEO_MODE_INFORMATION);

            status = NO_ERROR;
        }

        break;


    case IOCTL_VIDEO_SET_CURRENT_MODE:

        VideoDebugPrint((2, "DGXStartIO - SetCurrentMode\n"));

        //
        // verify data
        // WARNING: Make sure it is one of the valid modes on the list
        // calculated using the monitor information.
        //

        modeNumber = ((PVIDEO_MODE)(RequestPacket->InputBuffer))->RequestedMode;

        if ( (modeNumber >= hwDeviceExtension->NumValidModes) ||
             (!DGXModes[modeNumber].bValid) ) {

            status = ERROR_INVALID_PARAMETER;
            break;
        }

        DevInitDGX(hwDeviceExtension,
                   (PULONG)DGXModes[modeNumber].pVData,
                   DGXModes[modeNumber].Count);

        if (DGXModes[modeNumber].modeInformation.BitsPerPlane == 16) {

            DevSet16BppPalette(hwDeviceExtension);

        }

        hwDeviceExtension->CurrentModeNumber = modeNumber;

        status = NO_ERROR;

        break;


    case IOCTL_VIDEO_SET_COLOR_REGISTERS:

        VideoDebugPrint((2, "DGXStartIO - SetColorRegs\n"));

        clutBuffer = RequestPacket->InputBuffer;

        //
        // Check if the size of the data in the input buffer is large enough.
        //

        if ( (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) -
                    sizeof(ULONG)) ||
             (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) +
                    (sizeof(ULONG) * (clutBuffer->NumEntries - 1)) ) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;

        }

        if (DGXModes[hwDeviceExtension->CurrentModeNumber].
                modeInformation.BitsPerPlane == 8) {

            DevSetPalette(hwDeviceExtension,
                          (PULONG)clutBuffer->LookupTable,
                          clutBuffer->FirstEntry,
                          clutBuffer->NumEntries);

            status = NO_ERROR;
        }
        break;

    case IOCTL_VIDEO_ENABLE_POINTER:

        VideoDebugPrint((2, "DGXStartIO - EnablePointer\n"));

        ulTemp = *hwDeviceExtension->pControlRegA;
        ulTemp &= ~DAC_DISABLEPOINTER;
        DacDelay();
        *hwDeviceExtension->pControlRegA = ulTemp;

        status = NO_ERROR;

        break;


    case IOCTL_VIDEO_DISABLE_POINTER:

        VideoDebugPrint((2, "DGXStartIO - DisablePointer\n"));

        DevPointerOff(hwDeviceExtension);

        status = NO_ERROR;

        break;


    case IOCTL_VIDEO_SET_POINTER_POSITION:
    {
        PVIDEO_POINTER_POSITION pointerPosition;

        VideoDebugPrint((2, "DGXStartIO - SetpointerPostion\n"));

        pointerPosition = RequestPacket->InputBuffer;

        //
        // Check if the size of the data in the input buffer is large enough.
        //

        if (RequestPacket->InputBufferLength < sizeof(VIDEO_POINTER_POSITION)) {

            status = ERROR_INSUFFICIENT_BUFFER;

        } else {

            hwDeviceExtension->ulPointerX = (ULONG)pointerPosition->Row;
            hwDeviceExtension->ulPointerY = (ULONG)pointerPosition->Column;

            DevSetPointerPos(hwDeviceExtension,
                             (ULONG)pointerPosition->Column,
                             (ULONG)pointerPosition->Row);

            status = NO_ERROR;
        }

        break;
    }


    case IOCTL_VIDEO_QUERY_POINTER_POSITION:
    {
        PVIDEO_POINTER_POSITION pPointerPosition = RequestPacket->OutputBuffer;

        VideoDebugPrint((2, "DGXStartIO - QuerypointerPostion\n"));

        //
        // Make sure the output buffer is big enough.
        //

        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_POSITION)) {

            RequestPacket->StatusBlock->Information = 0;
            return ERROR_INSUFFICIENT_BUFFER;

        }

        //
        // Return the pointer position
        //

        RequestPacket->StatusBlock->Information = sizeof(VIDEO_POINTER_POSITION);

        pPointerPosition->Row = (SHORT)hwDeviceExtension->ulPointerX;
        pPointerPosition->Column = (SHORT)hwDeviceExtension->ulPointerY;

        status = NO_ERROR;

        break;
    }

    case IOCTL_VIDEO_SET_POINTER_ATTR:
    {
        PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
        USHORT *pHWCursorShape;           // Temp Buffer
        USHORT *pHWCursorAddr;           // DAC buffer
        ULONG iCount = 512;

        VideoDebugPrint((2, "DGXStartIO - SetPointerAttributes\n"));

        pointerAttributes = RequestPacket->InputBuffer;

        //
        // Check if the size of the data in the input buffer is large enough.
        //

        if (RequestPacket->InputBufferLength <
                (sizeof(VIDEO_POINTER_ATTRIBUTES) + ((sizeof(UCHAR) *
                (CURSOR_WIDTH/8) * CURSOR_HEIGHT) * 2))) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;

        }

        //
        // If the specified cursor width or height is not valid, then
        // return an invalid parameter error.
        //

        if ((pointerAttributes->Width > CURSOR_WIDTH) ||
            (pointerAttributes->Height > CURSOR_HEIGHT)) {

            status = ERROR_INVALID_PARAMETER;
            break;

        }
        //
        // Try to copy the pointer to our buffer. When we copy it
        // we convert it to our 2bpp format. If sucessfull, then
        // copy it to the DAC and set the position.
        //

        if (!(pointerAttributes->Flags & VIDEO_MODE_ANIMATE_UPDATE)) {

            DevPointerOff(hwDeviceExtension);

        }

        if (pointerAttributes->Flags & VIDEO_MODE_MONO_POINTER) {

            if (CopyMonoCursor(hwDeviceExtension,
                               (PUCHAR)&pointerAttributes->Pixels[0])) {


                pHWCursorAddr = (USHORT *)hwDeviceExtension->pHardWareCursorAddr;
                pHWCursorShape = (USHORT *)&hwDeviceExtension->HardwareCursorShape[0];

                while (iCount--) {

                    *pHWCursorAddr++ = *pHWCursorShape++;
                    pHWCursorAddr++;
                    DacDelay();

                }

                DevSetPointerPos(hwDeviceExtension,
                                 (ULONG)pointerAttributes->Column,
                                 (ULONG)pointerAttributes->Row);

                status = NO_ERROR;

                break;

            }
        }

        //
        // Something failed. Remove the current HW Cursor.
        //

        DevPointerOff(hwDeviceExtension);

        status = ERROR_INVALID_PARAMETER;

        break;
    }

    case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:

    {
        PVIDEO_POINTER_CAPABILITIES pointerCaps = RequestPacket->OutputBuffer;

        VideoDebugPrint((2, "DGXStartIO - QueryPointerCapabilities\n"));

        if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_CAPABILITIES)) {

            RequestPacket->StatusBlock->Information = 0;
            status = ERROR_INSUFFICIENT_BUFFER;

        }

        pointerCaps->Flags = VIDEO_MODE_ASYNC_POINTER | VIDEO_MODE_MONO_POINTER;
        pointerCaps->MaxWidth = CURSOR_WIDTH;
        pointerCaps->MaxHeight = CURSOR_HEIGHT;
        pointerCaps->HWPtrBitmapStart = 0;        // No VRAM storage for pointer
        pointerCaps->HWPtrBitmapEnd = 0;

        //
        // Number of bytes we're returning.
        //

        RequestPacket->StatusBlock->Information = sizeof(VIDEO_POINTER_CAPABILITIES);

        status = NO_ERROR;

        break;

    }

    case IOCTL_VIDEO_RESET_DEVICE:

        VideoDebugPrint((2, "DGXStartIO - RESET_DEVICE\n"));

        DevDisableDGX(hwDeviceExtension);

        status = NO_ERROR;

        break;

    //
    // if we get here, an invalid IoControlCode was specified.
    //

    default:

        VideoDebugPrint((1, "Fell through DGX startIO routine - invalid command\n"));

        status = ERROR_INVALID_FUNCTION;

        break;

    }

    RequestPacket->StatusBlock->Status = status;

    return TRUE;

} // end DGXStartIO()                                                        z
Пример #9
0
VP_STATUS MapVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_MEMORY_INFORMATION memoryInformation;
    ULONG inIoSpace;        /* Scratch variable used by VideoPortMapMemory() */
    VP_STATUS status;       /* Error code obtained from O/S calls */

    memoryInformation = RequestPacket->OutputBuffer;

    memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
        (RequestPacket->InputBuffer))->RequestedVirtualAddress;

    /*
     * The VideoRamLength field contains the amount of video memory
     * on the card. The FrameBufferLength field contains the
     * size of the aperture in bytes
     *
     * Initially assume that the linear aperture is available.
     * For our 8514/A-compatible cards, we always enable a 4M aperture
     * if the LFB is available, so map the full 4M even if the
     * aperture size is greater than the amount of video memory.
     */
    memoryInformation->VideoRamLength    = phwDeviceExtension->VideoRamSize;
    memoryInformation->FrameBufferLength = 4 * ONE_MEG;

    /*
     * If the linear aperture is not available (==0), and we are 
     * dealing with a card which can use the VGA 64k aperture,
     * map it in.
     */
    if (QueryPtr->q_aperture_cfg == 0)
        {
        if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
            (QueryPtr->q_VGA_type == 1))
            {
            phwDeviceExtension->FrameLength = 0x10000;
            phwDeviceExtension->PhysicalFrameAddress.LowPart = 0x0A0000;
            memoryInformation->FrameBufferLength = phwDeviceExtension->FrameLength;
            }
        else{
            /*
             * This card can't use either linear or VGA aperture.
             * Set frame buffer size to zero and return.
             */
            memoryInformation->VideoRamBase      = 0;
            memoryInformation->FrameBufferLength = 0;
            memoryInformation->FrameBufferBase   = 0;
            return NO_ERROR;
            }
        }
    inIoSpace = 0;
#if 0   /* defined(ALPHA) if display driver can handle dense LFB */
    if (QueryPtr->q_bus_type == BUS_PCI)
        inIoSpace = 4;
#endif

    status = VideoPortMapMemory(phwDeviceExtension,
                    	        phwDeviceExtension->PhysicalFrameAddress,
                                &(memoryInformation->FrameBufferLength),
                                &inIoSpace,
                                &(memoryInformation->VideoRamBase));

    memoryInformation->FrameBufferBase    = memoryInformation->VideoRamBase;

    return status;

}   /* MapVideoMemory_m() */
Пример #10
0
VP_STATUS ShareVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_SHARE_MEMORY InputPtr;               /* Pointer to input structure */
    PVIDEO_SHARE_MEMORY_INFORMATION OutputPtr;  /* Pointer to output structure */
    PHYSICAL_ADDRESS ShareAddress;              /* Physical address of video memory */
    PVOID VirtualAddress;                       /* Virtual address to map video memory at */
    ULONG SharedViewSize;                       /* Size of block to share */
    ULONG SpaceType;                            /* Sparse or dense space? */
    VP_STATUS Status;                           /* Status to return */

    /*
     * We can only share the aperture with application programs if there
     * is an aperture available. If both the LFB and the on-board VGA
     * and therefore the VGA aperture) are disabled, report that we
     * can't share the aperture.
     */
    if ((QueryPtr->q_aperture_cfg == 0) && (QueryPtr->q_VGA_type == 0))
        return ERROR_INVALID_FUNCTION;

    InputPtr = RequestPacket->InputBuffer;

    if ((InputPtr->ViewOffset > phwDeviceExtension->VideoRamSize) ||
        ((InputPtr->ViewOffset + InputPtr->ViewSize) > phwDeviceExtension->VideoRamSize))
        {
        VideoDebugPrint((DEBUG_ERROR, "ShareVideoMemory_m() - access beyond video memory\n"));
        return ERROR_INVALID_PARAMETER;
        }

    RequestPacket->StatusBlock->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION);

    /*
     * Beware: the input buffer and the output buffer are the same buffer,
     * and therefore data should not be copied from one to the other.
     */
    VirtualAddress = InputPtr->ProcessHandle;
    SharedViewSize = InputPtr->ViewSize;

    SpaceType = 0;
#if defined(_ALPHA_)
    /*
     * Use dense space mapping whenever we can, because that will
     * allow us to support DCI and direct GDI access.
     *
     * Dense space is extremely slow with ISA cards on the newer Alphas,
     * because any byte- or word-write requires a read/modify/write
     * operation, and the ALpha can only ever do 64-bit reads when in
     * dense mode. As a result, these operations would always require
     * 4 reads and 2 writes on the ISA bus. Also, some older Alphas
     * don't support dense space mapping.
     *
     * Any Alpha that supports PCI can support dense space mapping, and
     * because the bus is wider and faster, the read/modify/write has
     * less of an impact on performance.
     */
    if (QueryPtr->q_bus_type == BUS_PCI)
        SpaceType = 4;
#endif

    /*
     * NOTE: we are ignoring ViewOffset
     */
    ShareAddress.QuadPart = phwDeviceExtension->PhysicalFrameAddress.QuadPart;


    /*
     * If the LFB is enabled, use ordinary mapping. If we have only
     * the paged aperture, we must map to banked memory. Since the
     * LFB is always aligned on a 1M boundary (4M boundary for 4M
     * aperture), this check for the paged aperture will never falsely
     * detect a LFB as paged.
     */
    if (phwDeviceExtension->PhysicalFrameAddress.LowPart == 0x0A0000)
        {
        /*
         * On some versions of the DDK, VideoPortMapBankedMemory() is
         * not available. If this is the case, force an error.
         * This routine should be available in all versions of
         * the DDK which support DCI, since it is used for DCI
         * support on cards with banked apertures.
         */
#if defined(IOCTL_VIDEO_SHARE_VIDEO_MEMORY)
        Status = VideoPortMapBankedMemory(
            phwDeviceExtension,
            ShareAddress,
            &SharedViewSize,
            &SpaceType,
            &VirtualAddress,
            0x10000,            /* 64k VGA aperture */
            FALSE,              /* No separate read/write banks */
            BankMap_m,          /* Our bank-mapping routine */
            (PVOID) phwDeviceExtension);
#else
        Status = ERROR_INVALID_FUNCTION;
#endif
        }
    else    /* LFB */
        {
        Status = VideoPortMapMemory(phwDeviceExtension,
                                    ShareAddress,
                                    &SharedViewSize,
                                    &SpaceType,
                                    &VirtualAddress);
        }

    OutputPtr = RequestPacket->OutputBuffer;
    OutputPtr->SharedViewOffset = InputPtr->ViewOffset;
    OutputPtr->VirtualAddress = VirtualAddress;
    OutputPtr->SharedViewSize = SharedViewSize;

    return Status;

}   /* ShareVideoMemory_m() */
Пример #11
0
/* Main I/O request handler routine. */
BOOLEAN HwVidStartIO( PVOID HwDevExt, PVIDEO_REQUEST_PACKET ReqPkt )
{
    PHW_DEV_EXT                         pExt = HwDevExt;
    VP_STATUS                           status = NO_ERROR;
    PVIDEO_MODE_INFORMATION             modeInfo;
    PVIDEO_MEMORY                       vidMem;
    PVIDEO_SHARE_MEMORY                 pShrMem;
    PVOID                               virtualAddress;
    ULONG                               inIoSpace;
    ULONG                               modeNumber;
    ULONG                               ulLen;
    ULONG                               i;

    VideoDebugPrint( (2, "videomp: HwVidStartIO: ") );

    /* Process the VRP. Required requests are handled first. */
    switch( ReqPkt->IoControlCode ) {
    case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
    {
        PVIDEO_NUM_MODES        numModes;

        VideoDebugPrint( (2, "QUERY_NUM_AVAIL_MODES\n") );        
        if( ReqPkt->OutputBufferLength < sizeof( VIDEO_NUM_MODES ) ) {
            status = ERROR_INSUFFICIENT_BUFFER;
        } else {
            ReqPkt->StatusBlock->Information = sizeof( VIDEO_NUM_MODES );
            numModes = (PVIDEO_NUM_MODES)ReqPkt->OutputBuffer;
            numModes->ModeInformationLength = sizeof( VIDEO_MODE_INFORMATION );
            numModes->NumModes = pExt->NumValidModes;
        }
        break;
    }

    case IOCTL_VIDEO_QUERY_AVAIL_MODES:
        VideoDebugPrint( (2, "QUERY_AVAIL_MODES\n") );
        ulLen = pExt->NumValidModes * sizeof( VIDEO_MODE_INFORMATION );
        if( ReqPkt->OutputBufferLength < ulLen ) {
            status = ERROR_INSUFFICIENT_BUFFER;
        } else {
            ReqPkt->StatusBlock->Information = ulLen;
            modeInfo = ReqPkt->OutputBuffer;
            for( i = 0; i < ulAllModes; ++i ) {
                if( VideoModes[i].bValid ) {
                    vmpFillModeInfo( modeInfo, VideoModes[i].HorzRes,
                                     VideoModes[i].VertRes, VideoModes[i].Bpp );
                    modeInfo->ModeIndex = i; //VideoModes[i].modeInformation.ModeIndex;

                    modeInfo++;
                }
            }
        }
        break;

    case IOCTL_VIDEO_QUERY_CURRENT_MODE:
        VideoDebugPrint( (2, "QUERY_CURRENT_MODE\n") );
        if( ReqPkt->OutputBufferLength < sizeof( VIDEO_MODE_INFORMATION ) ) {
            status = ERROR_INSUFFICIENT_BUFFER;
        } else {
            ReqPkt->StatusBlock->Information = sizeof( VIDEO_MODE_INFORMATION );
            modeInfo  = ReqPkt->OutputBuffer;
            vmpFillModeInfo( modeInfo, 
                             VideoModes[pExt->CurrentModeNumber].HorzRes,
                             VideoModes[pExt->CurrentModeNumber].VertRes,
                             VideoModes[pExt->CurrentModeNumber].Bpp );
            modeInfo->ModeIndex = pExt->CurrentModeNumber; //VideoModes[pExt->CurrentModeNumber].modeInformation.ModeIndex;
        }

        break;

    case IOCTL_VIDEO_SET_CURRENT_MODE:
        VideoDebugPrint( (2, "SET_CURRENT_MODE\n") );

        /* Ensure the mode is valid. */
        modeNumber = ((PVIDEO_MODE)(ReqPkt->InputBuffer))->RequestedMode;

        if( (modeNumber > ulAllModes) || (!VideoModes[modeNumber].bValid) ) {
            status = ERROR_INVALID_PARAMETER;
            break;
        }

        BOXV_ext_mode_set( pExt, VideoModes[modeNumber].HorzRes, 
                           VideoModes[modeNumber].VertRes, VideoModes[modeNumber].Bpp,
                           VideoModes[modeNumber].HorzRes, VideoModes[modeNumber].VertRes );

        pExt->CurrentModeNumber = modeNumber;
        break;

    case IOCTL_VIDEO_RESET_DEVICE:
        VideoDebugPrint( (2, "RESET_DEVICE\n") );
	/* Not calling the following routine avoids some visual glitches. */
        /* BOXV_ext_disable( pExt ); */
        break;

    case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
    {
        PVIDEO_MEMORY_INFORMATION           memInfo;

        VideoDebugPrint( (2, "MAP_VIDEO_MEMORY\n") );
        if( (ReqPkt->OutputBufferLength < sizeof( VIDEO_MEMORY_INFORMATION )) ||
            (ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY )) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;
        }

        ReqPkt->StatusBlock->Information =  sizeof( VIDEO_MEMORY_INFORMATION );

        vidMem    = (PVIDEO_MEMORY)ReqPkt->InputBuffer;
        memInfo   = ReqPkt->OutputBuffer;
        inIoSpace = FALSE;

        memInfo->VideoRamBase   = vidMem->RequestedVirtualAddress;
        memInfo->VideoRamLength = pExt->FramebufLen;

        status = VideoPortMapMemory( pExt, pExt->PhysicalFrameAddress,
                                     &memInfo->VideoRamLength, &inIoSpace,
                                     &memInfo->VideoRamBase );

        /* The framebuffer covers the entire video memory. */
        memInfo->FrameBufferBase   = memInfo->VideoRamBase;
        memInfo->FrameBufferLength = memInfo->VideoRamLength;
        break;
    }

    case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
        VideoDebugPrint( (2, "UNMAP_VIDEO_MEMORY\n") );
        if( ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY ) ) {
            status = ERROR_INSUFFICIENT_BUFFER;
        } else {
            vidMem  = (PVIDEO_MEMORY)ReqPkt->InputBuffer;
            status = VideoPortUnmapMemory( pExt,
                                           vidMem->RequestedVirtualAddress,
                                           0 );
        }
        break;

    /* The following request is required for palettized modes. */
    case IOCTL_VIDEO_SET_COLOR_REGISTERS:
    {
        PVIDEO_CLUT     clutBuffer;

        VideoDebugPrint( (2, "SET_COLOR_REGISTERS\n") );
        clutBuffer = ReqPkt->InputBuffer;

        if( (ReqPkt->InputBufferLength < sizeof( VIDEO_CLUT ) - sizeof( ULONG )) ||
            (ReqPkt->InputBufferLength < sizeof( VIDEO_CLUT ) +
                    (sizeof( ULONG ) * (clutBuffer->NumEntries - 1)) ) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;
        }

        if( VideoModes[pExt->CurrentModeNumber].Bpp == 8 ) {
            BOXV_dac_set( pExt, clutBuffer->FirstEntry, clutBuffer->NumEntries,
                          clutBuffer->LookupTable );
        }
        break;
    }

    /* The following requests are optional. */
    case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
    {
        PVIDEO_POINTER_CAPABILITIES     ptrCaps = ReqPkt->OutputBuffer;

        VideoDebugPrint( (2, "QUERY_POINTER_CAPABILITIES\n") );
        if( ReqPkt->OutputBufferLength < sizeof( VIDEO_POINTER_CAPABILITIES ) ) {
            ReqPkt->StatusBlock->Information = 0;
            status = ERROR_INSUFFICIENT_BUFFER;
        }

        ptrCaps->Flags = 0;     /* Indicate no pointer support. */
        ptrCaps->MaxWidth = ptrCaps->MaxHeight = 0;
        /* Documentation and sample code disagree on whether no display
         * memory for cursor is indicated by 0 or -1.
         */
        ptrCaps->HWPtrBitmapStart = ptrCaps->HWPtrBitmapEnd = ~0;

        ReqPkt->StatusBlock->Information = sizeof( VIDEO_POINTER_CAPABILITIES );
        break;
    }

    /* The share/unshare IOCTLs are new for NT 3.51. */
    case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
    {
        PVIDEO_SHARE_MEMORY_INFORMATION     pShrMemInfo;
        PHYSICAL_ADDRESS                    shareAddress;
        ULONG                               sharedViewSize;

        VideoDebugPrint( (2, "SHARE_VIDEO_MEMORY\n") );
        if( (ReqPkt->OutputBufferLength < sizeof( VIDEO_SHARE_MEMORY_INFORMATION )) ||
            (ReqPkt->InputBufferLength < sizeof( VIDEO_MEMORY )) ) {

            status = ERROR_INSUFFICIENT_BUFFER;
            break;
        }

        pShrMem = ReqPkt->InputBuffer;

        if( (pShrMem->ViewOffset > pExt->FramebufLen) ||
            ((pShrMem->ViewOffset + pShrMem->ViewSize) > pExt->FramebufLen) ) {

            status = ERROR_INVALID_PARAMETER;
            break;
        }

        ReqPkt->StatusBlock->Information = sizeof( VIDEO_SHARE_MEMORY_INFORMATION );

        /* The input buffer is also the output buffer; remember the input. */
        virtualAddress = pShrMem->ProcessHandle;
        sharedViewSize = pShrMem->ViewSize;

        inIoSpace = FALSE;

        /* NB: ViewOffset is not being taken into account. */
        shareAddress.QuadPart = pExt->PhysicalFrameAddress.QuadPart;

        status = VideoPortMapMemory( pExt, shareAddress,
                                     &sharedViewSize, &inIoSpace,
                                     &virtualAddress );

        pShrMemInfo = ReqPkt->OutputBuffer;
        pShrMemInfo->SharedViewOffset = pShrMem->ViewOffset;
        pShrMemInfo->VirtualAddress   = virtualAddress;
        pShrMemInfo->SharedViewSize   = sharedViewSize;
        break;
    }

    case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
        VideoDebugPrint( (2, "UNSHARE_VIDEO_MEMORY\n") );
        if( ReqPkt->InputBufferLength < sizeof( VIDEO_SHARE_MEMORY ) ) {
            status = ERROR_INSUFFICIENT_BUFFER;
            break;
        }

        pShrMem = ReqPkt->InputBuffer;
        status = VideoPortUnmapMemory( pExt, pShrMem->RequestedVirtualAddress,
                                       pShrMem->ProcessHandle );
        break;


    /* The child state IOCTLs are new for NT 5.0 (Windows 2000). */
    case IOCTL_VIDEO_GET_CHILD_STATE:
    {
        PULONG      pChildIndex;
        PULONG      pChildState;

        VideoDebugPrint( (2, "GET_CHILD_STATE\n") );
        if( ReqPkt->InputBufferLength < sizeof( ULONG ) ||
            ReqPkt->OutputBufferLength < sizeof( ULONG ) ) {
            status = ERROR_INSUFFICIENT_BUFFER;
            break;
        }

        pChildIndex = ReqPkt->InputBuffer;
        pChildState = ReqPkt->OutputBuffer;

        /* Always say the child is active. */
        *pChildState = VIDEO_CHILD_ACTIVE;
        break;
    }

    /* Any other request is invalid and fails. */
    default:
        VideoDebugPrint( (1, "Unhandled IoControlCode %08x!\n", ReqPkt->IoControlCode) );
        status = ERROR_INVALID_FUNCTION;
        break;
    }

    ReqPkt->StatusBlock->Status = status;
    return( TRUE );
}