Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1428 lines
38 KiB

/*++
Copyright (c) 1990-1992 Microsoft Corporation
Module Name:
jazzg300.c
Abstract:
This module contains the code that implements the Jazz kernel
video driver.
Environment:
Kernel mode
Revision History:
--*/
#include "dderror.h"
#include "devioctl.h"
#include "miniport.h"
#include "ntddvdeo.h"
#include "video.h"
#include "jazzvdeo.h"
//
// Define macros to access video control, video memory, and cursor control
// addresses.
//
#define G300_VIDEO_CONTROL ((PG300_VIDEO_REGISTERS)(hwDeviceExtension->VideoAddress))
#define CURSOR_CONTROL ((PCURSOR_REGISTERS)(hwDeviceExtension->CursorAddress))
//
// Define device extension structure.
//
typedef struct _HW_DEVICE_EXTENSION {
PVOID CursorAddress;
PVOID VideoAddress;
PVOID FrameAddress;
PHYSICAL_ADDRESS PhysicalFrameAddress;
ULONG FrameLength;
PVIDEO_CLUT SynchronizeClutBuffer;
union {
VIDEO_CLUTDATA RgbData;
ULONG RgbLong;
} ColorMap[NUMBER_OF_COLORS];
USHORT FirstEntry;
USHORT LastEntry;
USHORT CursorControlOn;
USHORT CursorControlOff;
USHORT CursorWidth;
USHORT CursorHeight;
SHORT CursorColumn;
SHORT CursorRow;
USHORT CursorPixels[CURSOR_MAXIMUM];
USHORT CursorXOrigin;
USHORT CursorYOrigin;
USHORT HorizontalResolution;
USHORT HorizontalDisplayTime;
USHORT HorizontalBackPorch;
USHORT HorizontalFrontPorch;
USHORT HorizontalSync;
USHORT HorizontalScreenSize;
USHORT VerticalResolution;
USHORT VerticalBackPorch;
USHORT VerticalFrontPorch;
USHORT VerticalSync;
USHORT VerticalScreenSize;
UCHAR CursorEnable;
UCHAR UpdateColorMap;
UCHAR UpdateCursorPosition;
UCHAR UpdateCursorPixels;
UCHAR UpdateController;
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
//
// Function Prototypes
//
// Functions that start with 'G300' are entry points for the OS port driver.
//
VP_STATUS
G300FindAdapter(
PVOID HwDeviceExtension,
PVOID HwContext,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again
);
BOOLEAN
JazzG300SetColorRegisters(
PVOID Context
);
BOOLEAN
G300Initialize(
PVOID HwDeviceExtension
);
BOOLEAN
G300InterruptService (
PVOID HwDeviceExtension
);
BOOLEAN
G300StartIO(
PVOID HwDeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket
);
//
// Define device driver procedure prototypes.
//
VP_STATUS
G300GetDeviceDataCallback(
PVOID HwDeviceExtension,
PVOID Context,
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
PVOID Identifier,
ULONG IdentifierLength,
PVOID ConfigurationData,
ULONG ConfigurationDataLength,
PVOID ComponentInformation,
ULONG ComponentInformationLength
);
VOID
G300AttributesSetup (
PHW_DEVICE_EXTENSION HwDeviceExtension
);
VOID
G300ControllerSetup (
PHW_DEVICE_EXTENSION HwDeviceExtension
);
ULONG
DriverEntry (
PVOID Context1,
PVOID Context2
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
Context1 - First context value passed by the operating system. This is
the value with which the miniport driver calls VideoPortInitialize().
Context2 - Second context value passed by the operating system. This is
the value with which the miniport driver calls VideoPortInitialize().
Return Value:
Status from VideoPortInitialize()
--*/
{
VIDEO_HW_INITIALIZATION_DATA hwInitData;
//
// Zero out structure.
//
VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
//
// Specify sizes of structure and extension.
//
hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
//
// Set entry points.
//
hwInitData.HwFindAdapter = G300FindAdapter;
hwInitData.HwInitialize = G300Initialize;
hwInitData.HwInterrupt = G300InterruptService;
hwInitData.HwStartIO = G300StartIO;
//
// Determine the size we require for the device extension.
//
hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
//
// Always start with parameters for device0 in this case.
//
// hwInitData.StartingDeviceNumber = 0;
//
// This device only supports the internal bus type. So return the status
// value directly to the operating system.
//
hwInitData.AdapterInterfaceType = Internal;
return VideoPortInitialize(Context1,
Context2,
&hwInitData,
NULL);
} // end DriverEntry()
VP_STATUS
G300FindAdapter(
PVOID HwDeviceExtension,
PVOID HwContext,
PWSTR ArgumentString,
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
PUCHAR Again
)
/*++
Routine Description:
This routine is called to determine if the adapter for this driver
is present in the system.
If it is present, the function fills out some information describing
the adapter.
Arguments:
HwDeviceExtension - Supplies the miniport driver's adapter storage. This
storage is initialized to zero before this call.
HwContext - Supplies the context value which was passed to
VideoPortInitialize().
ArgumentString - Suuplies a NULL terminated ASCII string. This string
originates from the user.
ConfigInfo - Returns the configuration information structure which is
filled by the miniport driver. This structure is initialized with
any knwon configuration information (such as SystemIoBusNumber) by
the port driver. Where possible, drivers should have one set of
defaults which do not require any supplied configuration information.
Again - Indicates if the miniport driver wants the port driver to call
its VIDEO_HW_FIND_ADAPTER function again with a new device extension
and the same config info. This is used by the miniport drivers which
can search for several adapters on a bus.
Return Value:
This routine must return:
NO_ERROR - Indicates a host adapter was found and the
configuration information was successfully determined.
ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
error obtaining the configuration information. If possible an error
should be logged.
ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
supplied configuration information.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
//
// Make sure the size of the structure is at least as large as what we
// are expecting (check version of the config info structure).
//
if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
return ERROR_INVALID_PARAMETER;
}
if (NO_ERROR != VideoPortGetDeviceData(hwDeviceExtension,
VpControllerData,
&G300GetDeviceDataCallback,
ConfigInfo)) {
VideoDebugPrint((2, "G300: VideoPort get controller info failed\n"));
return ERROR_INVALID_PARAMETER;
}
if (NO_ERROR != VideoPortGetDeviceData(hwDeviceExtension,
VpMonitorData,
&G300GetDeviceDataCallback,
NULL)) {
VideoDebugPrint((2, "G300: VideoPort get monitor info failed\n"));
return ERROR_INVALID_PARAMETER;
}
//
// Clear out the Emulator entries and the state size since this driver
// does not support them.
//
ConfigInfo->NumEmulatorAccessEntries = 0;
ConfigInfo->EmulatorAccessEntries = NULL;
ConfigInfo->EmulatorAccessEntriesContext = 0;
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
ConfigInfo->HardwareStateSize = 0;
//
// Initialize the color map update information.
//
hwDeviceExtension->FirstEntry = 0;
hwDeviceExtension->LastEntry = 0;
hwDeviceExtension->UpdateController = FALSE;
//
// Set cursor enable FALSE.
//
hwDeviceExtension->CursorEnable = FALSE;
//
// Indicate we do not wish to be called over
//
*Again = 0;
//
// Indicate a successful completion status.
//
return NO_ERROR;
} // end G300FindAdapter()
VP_STATUS
G300GetDeviceDataCallback(
PVOID HwDeviceExtension,
PVOID Context,
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
PVOID Identifier,
ULONG IdentifierLength,
PVOID ConfigurationData,
ULONG ConfigurationDataLength,
PVOID ComponentInformation,
ULONG ComponentInformationLength
)
/*++
Routine Description:
Callback routine for the VideoPortGetDeviceData function.
Arguments:
HwDeviceExtension - Pointer to the miniport drivers device extension.
Context - Context value passed to the VideoPortGetDeviceData function.
DeviceDataType - The type of data that was requested in
VideoPortGetDeviceData.
Identifier - Pointer to a string that contains the name of the device,
as setup by the ROM or ntdetect.
IdentifierLength - Length of the Identifier string.
ConfigurationData - Pointer to the configuration data for the device or
BUS.
ConfigurationDataLength - Length of the data in the configurationData
field.
ComponentInformation - Undefined.
ComponentInformationLength - Undefined.
Return Value:
Returns NO_ERROR if the function completed properly.
Returns ERROR_DEV_NOT_EXIST if we did not find the device.
Returns ERROR_INVALID_PARAMETER otherwise.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
PVIDEO_PORT_CONFIG_INFO ConfigInfo = Context;
PWCHAR identifier = Identifier;
PVIDEO_HARDWARE_CONFIGURATION_DATA g300ConfigData = ConfigurationData;
PMONITOR_CONFIG_DATA monitorConfigData = ConfigurationData;
VIDEO_ACCESS_RANGE accessRanges[3];
VP_STATUS status;
switch (DeviceDataType) {
case VpControllerData:
VideoDebugPrint((2, "G300: getting controller information\n"));
VideoDebugPrint((2, "G300: controller identifier is %ws\n", Identifier));
//
// Compare the name to what is should be. If it is wrong, then return
// an error and initialization will fail.
// What is the right way of doing this??
//
if ( VideoPortCompareMemory(identifier, L"Jazz G300", 20) != 20) {
return ERROR_DEV_NOT_EXIST;
}
//
// Fill up the device extension and the configuration information
// with the appropriate data.
//
ConfigInfo->BusInterruptLevel = g300ConfigData->Irql;
ConfigInfo->BusInterruptVector = g300ConfigData->Vector;
//
// Save the ranges in the range buffer allocated for us.
//
accessRanges[0].RangeStart.HighPart = 0;
accessRanges[0].RangeStart.LowPart = g300ConfigData->ControlBase;
accessRanges[0].RangeLength = g300ConfigData->ControlSize;
accessRanges[0].RangeInIoSpace = 0;
accessRanges[0].RangeVisible = 0;
accessRanges[0].RangeShareable = 0;
accessRanges[1].RangeStart.HighPart = 0;
accessRanges[1].RangeStart.LowPart = g300ConfigData->CursorBase;
accessRanges[1].RangeLength = g300ConfigData->CursorSize;
accessRanges[1].RangeInIoSpace = 0;
accessRanges[1].RangeVisible = 0;
accessRanges[1].RangeShareable = 0;
accessRanges[2].RangeStart.HighPart = 0;
accessRanges[2].RangeStart.LowPart = g300ConfigData->FrameBase;
accessRanges[2].RangeLength = g300ConfigData->FrameSize;
accessRanges[2].RangeInIoSpace = 0;
accessRanges[2].RangeVisible = 0;
accessRanges[2].RangeShareable = 0;
//
// Check to see if there is a hardware resource conflict.
//
status = VideoPortVerifyAccessRanges(HwDeviceExtension,
3,
accessRanges);
if (status != NO_ERROR) {
return status;
}
//
// Frame buffer information
//
hwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
hwDeviceExtension->PhysicalFrameAddress.LowPart = g300ConfigData->FrameBase;
hwDeviceExtension->FrameLength = g300ConfigData->FrameSize;
//
// Map the video controller into the system virtual address space.
//
if ( (hwDeviceExtension->VideoAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[0].RangeStart, // Control
accessRanges[0].RangeLength,
FALSE)) == NULL) {
return ERROR_INVALID_PARAMETER;
}
//
// Map the cursor memory into the system virtual address space so we
// can talk to it.
//
if ( (hwDeviceExtension->CursorAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[1].RangeStart, // cursor
accessRanges[1].RangeLength,
FALSE)) == NULL) {
return ERROR_INVALID_PARAMETER;
}
//
// Map the video memory into the system virtual address space so we
// can clear it out.
//
if ( (hwDeviceExtension->FrameAddress =
VideoPortGetDeviceBase(hwDeviceExtension,
accessRanges[2].RangeStart, // Frame
accessRanges[2].RangeLength,
FALSE)) == NULL) {
return ERROR_INVALID_PARAMETER;
}
return NO_ERROR;
break;
case VpMonitorData:
VideoDebugPrint((2, "G300: getting monitor information\n"));
//
// NOTE: because we had a RESOURCE LIST header at the top.
// + 8 should be the offset of the paertial resource descriptor
// in a full resource descriptor.
//
monitorConfigData = (PMONITOR_CONFIG_DATA)
( ((PUCHAR)monitorConfigData) + 8);
//
// Initialize the monitor parameters.
//
hwDeviceExtension->HorizontalResolution =
monitorConfigData->HorizontalResolution;
hwDeviceExtension->HorizontalDisplayTime =
monitorConfigData->HorizontalDisplayTime;
hwDeviceExtension->HorizontalBackPorch =
monitorConfigData->HorizontalBackPorch;
hwDeviceExtension->HorizontalFrontPorch =
monitorConfigData->HorizontalFrontPorch;
hwDeviceExtension->HorizontalSync =
monitorConfigData->HorizontalSync;
hwDeviceExtension->HorizontalScreenSize =
monitorConfigData->HorizontalScreenSize;
hwDeviceExtension->VerticalResolution =
monitorConfigData->VerticalResolution;
hwDeviceExtension->VerticalBackPorch =
monitorConfigData->VerticalBackPorch;
hwDeviceExtension->VerticalFrontPorch =
monitorConfigData->VerticalFrontPorch;
hwDeviceExtension->VerticalSync =
monitorConfigData->VerticalSync;
hwDeviceExtension->VerticalScreenSize =
monitorConfigData->VerticalScreenSize;
return NO_ERROR;
break;
default:
VideoDebugPrint((2, "G300: callback has bad device type\n"));
return ERROR_INVALID_PARAMETER;
}
} //end G300GetDeviceDataCallback()
BOOLEAN
G300Initialize(
PVOID HwDeviceExtension
)
/*++
Routine Description:
This routine does one time initialization of the device.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Return Value:
Always returns TRUE since this routine can never fail.
--*/
{
G300AttributesSetup((PHW_DEVICE_EXTENSION) HwDeviceExtension);
G300ControllerSetup((PHW_DEVICE_EXTENSION) HwDeviceExtension);
return TRUE;
} // end G300Initialize()
BOOLEAN
G300StartIO(
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:
--*/
{
VP_STATUS status;
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
ULONG inIoSpace;
PVIDEO_MODE_INFORMATION modeInformation;
PVIDEO_MEMORY_INFORMATION memoryInformation;
PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
PVIDEO_POINTER_POSITION pointerPostion;
PVIDEO_CLUT clutBuffer;
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, "G300StartIO - 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, "G300StartIO - MapVideoMemory\n"));
if ( (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_MEMORY_INFORMATION))) ||
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
status = ERROR_INSUFFICIENT_BUFFER;
}
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, "G300StartIO - UnMapVideoMemory\n"));
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
status = ERROR_INSUFFICIENT_BUFFER;
}
status = VideoPortUnmapMemory(hwDeviceExtension,
((PVIDEO_MEMORY)
(RequestPacket->InputBuffer))->
RequestedVirtualAddress,
0);
break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
VideoDebugPrint((2, "G300StartIO - Query(Available/Current)Modes\n"));
modeInformation = RequestPacket->OutputBuffer;
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_MODE_INFORMATION)) ) {
status = ERROR_INSUFFICIENT_BUFFER;
} else {
modeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
modeInformation->ModeIndex = 0;
modeInformation->VisScreenWidth =
modeInformation->ScreenStride = hwDeviceExtension->HorizontalResolution;
modeInformation->VisScreenHeight = hwDeviceExtension->VerticalResolution;
modeInformation->NumberOfPlanes = 1;
modeInformation->BitsPerPlane = DISPLAY_BITS_PER_PIXEL;
modeInformation->Frequency = 1;
modeInformation->XMillimeter = 320;
modeInformation->YMillimeter = 240;
modeInformation->NumberRedBits = 8;
modeInformation->NumberGreenBits = 8;
modeInformation->NumberBlueBits = 8;
modeInformation->RedMask = 0;
modeInformation->GreenMask = 0;
modeInformation->BlueMask = 0;
modeInformation->AttributeFlags = VIDEO_MODE_COLOR |
VIDEO_MODE_GRAPHICS | VIDEO_MODE_PALETTE_DRIVEN |
VIDEO_MODE_MANAGED_PALETTE;
status = NO_ERROR;
}
break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
VideoDebugPrint((2, "G300StartIO - 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.
//
if (RequestPacket->OutputBufferLength <
(RequestPacket->StatusBlock->Information =
sizeof(VIDEO_NUM_MODES)) ) {
status = ERROR_INSUFFICIENT_BUFFER;
} else {
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = 1;
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
sizeof(VIDEO_MODE_INFORMATION);
status = NO_ERROR;
}
break;
case IOCTL_VIDEO_SET_CURRENT_MODE:
VideoDebugPrint((2, "G300StartIO - SetCurrentMode\n"));
status = NO_ERROR;
break;
case IOCTL_VIDEO_RESET_DEVICE:
//
// Just make sure we return success for this IOCTL so we do not
// fail it, and display driver does no break on failiure.
//
// This IOCTL does not do anything on this machine because there
// is no basic mode to return to ...
//
status = NO_ERROR;
break;
case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
VideoDebugPrint((2, "G300StartIO - SetPaletteRegs\n"));
status = NO_ERROR;
break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
VideoDebugPrint((2, "G300StartIO - 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)) ) ) {
ASSERT(FALSE);
status = ERROR_INSUFFICIENT_BUFFER;
break;
}
//
// Check to see if the parameters are valid.
//
if ( (clutBuffer->NumEntries == 0) ||
(clutBuffer->FirstEntry >= NUMBER_OF_COLORS) ||
(clutBuffer->FirstEntry + clutBuffer->NumEntries >
NUMBER_OF_COLORS) ) {
ASSERT(FALSE);
status = ERROR_INVALID_PARAMETER;
break;
}
hwDeviceExtension->SynchronizeClutBuffer = clutBuffer;
if (VideoPortSynchronizeExecution(hwDeviceExtension,
VpMediumPriority,
(PMINIPORT_SYNCHRONIZE_ROUTINE)
JazzG300SetColorRegisters,
hwDeviceExtension)) {
status = NO_ERROR;
} else {
ASSERT(FALSE);
status = ERROR_INVALID_PARAMETER;
}
break;
//
// if we get here, an invalid IoControlCode was specified.
//
default:
VideoDebugPrint((1, "Fell through G300 startIO routine - invalid command\n"));
status = ERROR_INVALID_FUNCTION;
break;
}
RequestPacket->StatusBlock->Status = status;
return TRUE;
} // end G300StartIO()
BOOLEAN
JazzG300SetColorRegisters(
PVOID Context
)
/*++
Routine Description:
This routine is the interrupt service routine for the Jazz kernel video
driver.
Arguments:
Context - Pointer to a context parameter.
Return Value:
NO_ERROR.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = Context;
PVIDEO_CLUT clutBuffer = hwDeviceExtension->SynchronizeClutBuffer;
USHORT index1;
PULONG colorSource;
index1 = clutBuffer->FirstEntry;
hwDeviceExtension->FirstEntry = index1;
hwDeviceExtension->LastEntry = index1 + clutBuffer->NumEntries;
colorSource = (PULONG)&(clutBuffer->LookupTable[0]);
while (index1 < hwDeviceExtension->LastEntry) {
hwDeviceExtension->ColorMap[index1++].RgbLong = *colorSource++;
}
//
// Enable the verticle retrace interrupt to perform the update.
//
hwDeviceExtension->UpdateColorMap = TRUE;
VideoPortEnableInterrupt(hwDeviceExtension);
return TRUE;
} // end JazzG300SetColorRegisters()
BOOLEAN
G300InterruptService(
PVOID HwDeviceExtension
)
/*++
Routine Description:
This routine is the interrupt service routine for the Jazz kernel video
driver.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's adapter information.
Return Value:
TRUE since the interrupt is always serviced.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
ULONG index;
SHORT x;
SHORT y;
PG300_VIDEO_REGISTERS videoRegisters = hwDeviceExtension->VideoAddress;
//
// Disable the verticle retrace interrupt.
//
VideoPortDisableInterrupt(hwDeviceExtension);
//
// If the color map should be updated, then load the color map into the
// G300B Display controller.
//
if (hwDeviceExtension->UpdateColorMap != FALSE) {
for (index = hwDeviceExtension->FirstEntry;
index < hwDeviceExtension->LastEntry; index += 1) {
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->ColorMapData[index].Long,
hwDeviceExtension->ColorMap[index].RgbLong);
}
hwDeviceExtension->UpdateColorMap = FALSE;
}
return TRUE;
} // end G300InterruptService()
VOID
G300AttributesSetup(
PHW_DEVICE_EXTENSION HwDeviceExtension
)
/*++
Routine Description:
This routine initializes the color map and the hardware cursor.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Return Value:
None.
--*/
{
PULONG buffer;
ULONG index;
ULONG limit;
/* SHOULD NOT BE MADE UNTIL DISPLAY CALLS TO DO IT.
//
// Initialize the color map copy in the device extension.
//
for (index = 0; index < NUMBER_OF_COLORS; index++) {
HwDeviceExtension->ColorMap[index].RgbData.Red =
((index & 0x7) << 2) | ((index & 0x7) << 5);
HwDeviceExtension->ColorMap[index].RgbData.Green =
((index & 0x38) >> 1) | ((index & 0x38) << 2);
HwDeviceExtension->ColorMap[index].RgbData.Blue =
((index & 0xc0) >> 6) | ((index & 0xc0) >> 4) |
((index & 0xc0) >> 2) | (index & 0xc0);
}
//
// Set colors for map entries 0 and 1 which are used by text output
// and the hardware cursor.
//
HwDeviceExtension->ColorMap[0].RgbData.Red = 255;
HwDeviceExtension->ColorMap[0].RgbData.Green = 255;
HwDeviceExtension->ColorMap[0].RgbData.Blue = 255;
HwDeviceExtension->ColorMap[1].RgbData.Red = 0;
HwDeviceExtension->ColorMap[1].RgbData.Green = 0;
HwDeviceExtension->ColorMap[1].RgbData.Blue = 0x90;
*/
//
// Set color map update parameters and enable update on next vertical
// retrace interrupt.
//
HwDeviceExtension->FirstEntry = 0;
HwDeviceExtension->LastEntry = NUMBER_OF_COLORS;
HwDeviceExtension->UpdateColorMap = FALSE;
//
// Set the hardware cursor width, height, column, and row values.
//
HwDeviceExtension->CursorWidth = CURSOR_WIDTH;
HwDeviceExtension->CursorHeight = CURSOR_HEIGHT;
HwDeviceExtension->CursorColumn = 0;
HwDeviceExtension->CursorRow = 0;
//
// Set the device extension copy of the hardware cursor ram memory.
//
for (index = 0; index < CURSOR_MAXIMUM; index++) {
HwDeviceExtension->CursorPixels[index] = 0x00ff;
}
//
// Leave the cursor disabled until it is explicitly enabled
// attributes. This is the default values in the device extension.
//
HwDeviceExtension->CursorEnable = FALSE;
HwDeviceExtension->UpdateCursorPixels = FALSE;
HwDeviceExtension->UpdateCursorPosition = FALSE;
//
// Enable the vertical retrace interrupt to set up color map.
//
/* VideoPortEnableInterrupt(HwDeviceExtension); */
return;
} // end G300AttributesSetup()
VOID
G300ControllerSetup(
PHW_DEVICE_EXTENSION HwDeviceExtension
)
/*++
Routine Description:
This routine initializes the G300B display controller chip.
Arguments:
HwDeviceExtension - Supplies a pointer to the miniport's device extension.
Return Value:
None.
--*/
{
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
ULONG backPorch;
ULONG dataLong;
USHORT dataShort;
ULONG frontPorch;
ULONG halfLineTime;
ULONG halfSync;
ULONG index;
ULONG multiplierValue;
ULONG screenUnitRate;
ULONG shortDisplay;
ULONG transferDelay;
ULONG verticalBlank;
//
// Disable the G300B display controller.
//
dataLong = 0;
((PG300_VIDEO_PARAMETERS)(&dataLong))->PlainWave = 1;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->Parameters.Long,
dataLong);
//
// Initialize the BT431 cursor control register.
//
VideoPortWriteRegisterUshort(&CURSOR_CONTROL->AddressPointer0.Short,
CURSOR_CONTROL_ADDRESS);
for (index = 0; index < 13; index++) {
VideoPortWriteRegisterUshort(&CURSOR_CONTROL->CursorControl.Short,
0);
}
VideoPortWriteRegisterUshort(&CURSOR_CONTROL->AddressPointer0.Short,
CURSOR_CONTROL_ADDRESS);
dataShort = 0;
((PCURSOR_COMMAND)(&dataShort))->CrossHairThickness1 = ONE_PIXEL_THICK;
((PCURSOR_COMMAND)(&dataShort))->CrossHairThickness2 = ONE_PIXEL_THICK;
((PCURSOR_COMMAND)(&dataShort))->MultiplexControl1 = FOUR_TO_ONE;
((PCURSOR_COMMAND)(&dataShort))->MultiplexControl2 = FOUR_TO_ONE;
((PCURSOR_COMMAND)(&dataShort))->CursorFormat1 = 0;
((PCURSOR_COMMAND)(&dataShort))->CursorFormat2 = 0;
((PCURSOR_COMMAND)(&dataShort))->CrossHairEnable1 = 0;
((PCURSOR_COMMAND)(&dataShort))->CrossHairEnable2 = 0;
VideoPortWriteRegisterUshort(&CURSOR_CONTROL->CursorControl.Short,
dataShort);
HwDeviceExtension->CursorControlOff = dataShort;
((PCURSOR_COMMAND)(&dataShort))->CursorEnable1 = 1;
((PCURSOR_COMMAND)(&dataShort))->CursorEnable2 = 1;
HwDeviceExtension->CursorControlOn = dataShort;
//
// Initialize the G300B boot register value.
//
screenUnitRate = (HwDeviceExtension->HorizontalDisplayTime * 1000 * 4) /
(HwDeviceExtension->HorizontalResolution);
multiplierValue = 125000 / (screenUnitRate / 4);
dataLong = 0;
((PG300_VIDEO_BOOT)(&dataLong))->Multiplier = multiplierValue;
((PG300_VIDEO_BOOT)(&dataLong))->ClockSelect = 1;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->Boot.Long,
dataLong);
//
// Wait for phase locked loop to stablize.
//
VideoPortStallExecution(50);
//
// Initialize the G300B operational values.
//
halfSync = (HwDeviceExtension->HorizontalSync * 1000) / screenUnitRate / 2;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->HorizonalSync.Long,
halfSync);
backPorch = (HwDeviceExtension->HorizontalBackPorch * 1000) /
screenUnitRate;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->BackPorch.Long,
backPorch);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->Display.Long,
HwDeviceExtension->HorizontalResolution / 4);
halfLineTime = ((HwDeviceExtension->HorizontalSync +
HwDeviceExtension->HorizontalFrontPorch +
HwDeviceExtension->HorizontalBackPorch +
HwDeviceExtension->HorizontalDisplayTime) * 1000) /
screenUnitRate / 2;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->LineTime.Long,
halfLineTime * 2);
frontPorch = (HwDeviceExtension->HorizontalFrontPorch * 1000) /
screenUnitRate;
shortDisplay = halfLineTime - ((halfSync * 2) + backPorch + frontPorch);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->ShortDisplay.Long,
shortDisplay);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->BroadPulse.Long,
halfLineTime - frontPorch);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->VerticalSync.Long,
HwDeviceExtension->VerticalSync * 2);
verticalBlank = (HwDeviceExtension->VerticalFrontPorch +
HwDeviceExtension->VerticalBackPorch -
(HwDeviceExtension->VerticalSync * 2)) * 2;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->VerticalBlank.Long,
verticalBlank);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->VerticalDisplay.Long,
HwDeviceExtension->VerticalResolution * 2);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->LineStart.Long,
LINE_START_VALUE);
if (backPorch < shortDisplay) {
transferDelay = backPorch - 1;
} else {
transferDelay = shortDisplay - 1;
}
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->TransferDelay.Long,
transferDelay);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->DmaDisplay.Long,
1024 - transferDelay);
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->PixelMask.Long,
G300_PIXEL_MASK_VALUE);
//
// Initialize the G300B control parameters.
//
dataLong = 0;
((PG300_VIDEO_PARAMETERS)(&dataLong))->EnableVideo = 1;
((PG300_VIDEO_PARAMETERS)(&dataLong))->PlainWave = 1;
((PG300_VIDEO_PARAMETERS)(&dataLong))->SeparateSync = 1;
((PG300_VIDEO_PARAMETERS)(&dataLong))->DelaySync = G300_DELAY_SYNC_CYCLES;
((PG300_VIDEO_PARAMETERS)(&dataLong))->BlankOutput = 1;
((PG300_VIDEO_PARAMETERS)(&dataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL;
((PG300_VIDEO_PARAMETERS)(&dataLong))->AddressStep = 2;
VideoPortWriteRegisterUlong(&G300_VIDEO_CONTROL->Parameters.Long,
dataLong );
//
// Compute the X and Y origin values for the cursor.
//
HwDeviceExtension->CursorXOrigin = (USHORT)((((halfSync * 2) + backPorch) * 4) - 36);
HwDeviceExtension->CursorYOrigin = 24;
return;
} // end G300ControllerSetup()