mirror of https://github.com/tongzx/nt5src
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.
2650 lines
69 KiB
2650 lines
69 KiB
/*++
|
|
|
|
Copyright (c) 1993 Weitek Corporation
|
|
|
|
Module Name:
|
|
|
|
p9.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that implements the Weitek P9 miniport
|
|
device driver.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History may be found at the end of this file.
|
|
|
|
--*/
|
|
|
|
#include "p9.h"
|
|
#include "p9gbl.h"
|
|
#include "vga.h"
|
|
#include "string.h"
|
|
#include "p91regs.h"
|
|
#include "p9errlog.h"
|
|
|
|
//
|
|
// This global is used as an error flag to error out quickly on the multiple
|
|
// calls to P9FindAdapter when a board is not supported.
|
|
//
|
|
|
|
extern VP_STATUS vpP91AdapterStatus;
|
|
extern BOOLEAN bFoundPCI;
|
|
|
|
extern ULONG P91_Bt485_DAC_Regs[];
|
|
|
|
BOOLEAN gMadeAdjustments=FALSE;
|
|
|
|
extern BOOLEAN
|
|
bIntergraphBoard(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
extern VOID SetVgaMode3(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
extern VOID
|
|
WriteP9ConfigRegister(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
UCHAR regnum,
|
|
UCHAR jValue
|
|
);
|
|
|
|
extern VOID
|
|
InitP9100(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
|
|
extern VOID
|
|
P91_SysConf(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
|
|
extern VOID
|
|
P91_WriteTiming(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
extern VOID vDumpPCIConfig(PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PUCHAR psz);
|
|
|
|
extern
|
|
VOID
|
|
P91RestoreVGAregs(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
VGA_REGS * SaveVGARegisters);
|
|
|
|
extern
|
|
VOID
|
|
P91SaveVGARegs(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
VGA_REGS * SaveVGARegisters);
|
|
|
|
//
|
|
// Local function Prototypes
|
|
//
|
|
// Functions that start with 'P9' are entry points for the OS port driver.
|
|
//
|
|
|
|
VP_STATUS
|
|
GetCPUIdCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
);
|
|
|
|
VP_STATUS
|
|
GetDeviceDataCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
);
|
|
|
|
VOID
|
|
DevSetRegistryParams(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
);
|
|
|
|
|
|
VP_STATUS
|
|
FindAdapter(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PP9ADAPTER pCurAdapter
|
|
);
|
|
|
|
VP_STATUS
|
|
P9FindAdapter(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PUCHAR Again
|
|
);
|
|
|
|
BOOLEAN
|
|
P9Initialize(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
P9StartIO(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|
);
|
|
|
|
VOID
|
|
DevInitP9(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
VOID
|
|
DevDisableP9(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
BOOLEAN BugCheck
|
|
);
|
|
|
|
VP_STATUS
|
|
P9QueryNamedValueCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
PWSTR ValueName,
|
|
PVOID ValueData,
|
|
ULONG ValueLength
|
|
);
|
|
|
|
BOOLEAN
|
|
P9ResetVideo(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG Columns,
|
|
IN ULONG Rows
|
|
);
|
|
|
|
VOID
|
|
InitializeModes(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
);
|
|
|
|
|
|
//
|
|
// New entry points added for NT 5.0.
|
|
//
|
|
|
|
#if (_WIN32_WINNT >= 500)
|
|
|
|
//
|
|
// Routine to set a desired DPMS power management state.
|
|
//
|
|
VP_STATUS
|
|
WP9SetPower50(
|
|
PHW_DEVICE_EXTENSION phwDeviceExtension,
|
|
ULONG HwDeviceId,
|
|
PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
|
|
);
|
|
|
|
//
|
|
// Routine to retrieve possible DPMS power management states.
|
|
//
|
|
VP_STATUS
|
|
WP9GetPower50(
|
|
PHW_DEVICE_EXTENSION phwDeviceExtension,
|
|
ULONG HwDeviceId,
|
|
PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
|
|
);
|
|
|
|
//
|
|
// Routine to retrieve the Enhanced Display ID structure via DDC
|
|
//
|
|
ULONG
|
|
WP9GetVideoChildDescriptor(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
|
|
PVIDEO_CHILD_TYPE pChildType,
|
|
PVOID pvChildDescriptor,
|
|
PULONG pHwId,
|
|
PULONG pUnused
|
|
);
|
|
#endif // _WIN32_WINNT >= 500
|
|
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
#pragma alloc_text(PAGE,DriverEntry)
|
|
#pragma alloc_text(PAGE,GetCPUIdCallback)
|
|
#pragma alloc_text(PAGE,GetDeviceDataCallback)
|
|
#pragma alloc_text(PAGE,DevSetRegistryParams)
|
|
#pragma alloc_text(PAGE,P9FindAdapter)
|
|
#pragma alloc_text(PAGE,FindAdapter)
|
|
#pragma alloc_text(PAGE,P9Initialize)
|
|
#pragma alloc_text(PAGE,P9StartIO)
|
|
#if (_WIN32_WINNT >= 500)
|
|
#pragma alloc_text(PAGE_COM, WP9SetPower50)
|
|
#pragma alloc_text(PAGE_COM, WP9GetPower50)
|
|
#pragma alloc_text(PAGE_COM, WP9GetVideoChildDescriptor)
|
|
#endif // _WIN32_WINNT >= 500
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* IMPORTANT:
|
|
*
|
|
* Some routines, like DevDisable, can not be paged since they are called
|
|
* when the system is bugchecking
|
|
*
|
|
****************************************************************************/
|
|
|
|
// #pragma alloc_text(PAGE, DevDisableP9)
|
|
#endif
|
|
|
|
|
|
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;
|
|
ULONG status = ERROR_DEV_NOT_EXIST;
|
|
|
|
VideoDebugPrint((2, "DriverEntry ----------\n"));
|
|
|
|
//
|
|
// 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 = P9FindAdapter;
|
|
hwInitData.HwInitialize = P9Initialize;
|
|
hwInitData.HwInterrupt = NULL;
|
|
hwInitData.HwStartIO = P9StartIO;
|
|
hwInitData.HwResetHw = P9ResetVideo;
|
|
|
|
#if (_WIN32_WINNT >= 500)
|
|
|
|
//
|
|
// Set new entry points added for NT 5.0.
|
|
//
|
|
|
|
hwInitData.HwSetPowerState = WP9SetPower50;
|
|
hwInitData.HwGetPowerState = WP9GetPower50;
|
|
hwInitData.HwGetVideoChildDescriptor = WP9GetVideoChildDescriptor;
|
|
|
|
#endif // _WIN32_WINNT >= 500
|
|
|
|
|
|
//
|
|
// Determine the size we require for the device extension.
|
|
//
|
|
|
|
//
|
|
// Compute the size of the device extension by adding in the
|
|
// number of DAC Registers.
|
|
//
|
|
|
|
hwInitData.HwDeviceExtensionSize =
|
|
sizeof(HW_DEVICE_EXTENSION) +
|
|
(17) * sizeof(PVOID);
|
|
|
|
//
|
|
// This driver accesses one range of memory one range of control
|
|
// register and a last range for cursor control.
|
|
//
|
|
|
|
// hwInitData.NumberOfAccessRanges = 0;
|
|
|
|
//
|
|
// There is no support for the V86 emulator in this driver so this field
|
|
// is ignored.
|
|
//
|
|
|
|
// hwInitData.NumEmulatorAccessEntries = 0;
|
|
|
|
//
|
|
// This device supports many bus types.
|
|
//
|
|
// SNI has implemented machines with both VL and PCI versions of the
|
|
// weitek chipset. Don't bother with the other buses since the
|
|
// detection code may actually crash some MIPS boxes.
|
|
//
|
|
|
|
hwInitData.AdapterInterfaceType = PCIBus;
|
|
|
|
status = VideoPortInitialize(Context1,
|
|
Context2,
|
|
&hwInitData,
|
|
NULL);
|
|
|
|
if (status == NO_ERROR)
|
|
{
|
|
VideoDebugPrint((2, "DriverEntry SUCCESS for PCI\n"));
|
|
bFoundPCI = TRUE;
|
|
return(status);
|
|
}
|
|
|
|
|
|
//
|
|
// As of NT5, we won't support weitek PCI with any other weitek on
|
|
// the same machine.
|
|
//
|
|
|
|
if (bFoundPCI)
|
|
return ERROR_DEV_NOT_EXIST;
|
|
|
|
hwInitData.AdapterInterfaceType = Isa;
|
|
|
|
status = VideoPortInitialize(Context1,
|
|
Context2,
|
|
&hwInitData,
|
|
NULL);
|
|
|
|
if ((status == NO_ERROR))
|
|
{
|
|
VideoDebugPrint((2, "DriverEntry SUCCESS for ISA\n"));
|
|
return(status);
|
|
}
|
|
|
|
hwInitData.AdapterInterfaceType = Eisa;
|
|
|
|
status = VideoPortInitialize(Context1,
|
|
Context2,
|
|
&hwInitData,
|
|
NULL);
|
|
|
|
if ((status == NO_ERROR))
|
|
{
|
|
VideoDebugPrint((2, "DriverEntry SUCCESS for EISA\n"));
|
|
return(status);
|
|
}
|
|
|
|
hwInitData.AdapterInterfaceType = Internal;
|
|
|
|
status = VideoPortInitialize(Context1,
|
|
Context2,
|
|
&hwInitData,
|
|
NULL);
|
|
|
|
if ((status == NO_ERROR))
|
|
{
|
|
VideoDebugPrint((2, "DriverEntry SUCCESS at for Internal\n"));
|
|
return(status);
|
|
}
|
|
|
|
return(status);
|
|
|
|
} // end DriverEntry()
|
|
|
|
VP_STATUS
|
|
P9FindAdapter (
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PUCHAR Again
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Status from FindAdapter()
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
ULONG status;
|
|
UCHAR i;
|
|
*Again = TRUE;
|
|
|
|
VideoDebugPrint((2, "P9FindAdapter entry\n"));
|
|
|
|
//
|
|
// Loop through the table of types of cards. DriverEntry() loops through
|
|
// the bus types.
|
|
//
|
|
|
|
for (i = 0; i < NUM_OEM_ADAPTERS; i++)
|
|
{
|
|
VideoDebugPrint((2, "Loop %d in P9FindAdapter\n", i));
|
|
|
|
status = FindAdapter(HwDeviceExtension,
|
|
HwContext,
|
|
ArgumentString,
|
|
ConfigInfo,
|
|
&(OEMAdapter[i]));
|
|
|
|
if (status == NO_ERROR)
|
|
{
|
|
VideoDebugPrint((2, "P9FindAdapter SUCCESS at loop %d\n", i));
|
|
|
|
//
|
|
// Indicate we do not wish to be called over
|
|
//
|
|
|
|
*Again = FALSE;
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// If we've exhausted the table, request to not be recalled.
|
|
//
|
|
|
|
if ( i == NUM_OEM_ADAPTERS)
|
|
{
|
|
VideoDebugPrint((1, "P9FindAdapter FAILED\n", i));
|
|
*Again = FALSE;
|
|
}
|
|
|
|
return(status);
|
|
|
|
} // end P9FindAdapter()
|
|
|
|
|
|
VP_STATUS
|
|
pVlCardDetect(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
PWSTR ValueName,
|
|
PVOID ValueData,
|
|
ULONG ValueLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine determines if the driver is the ForceVga.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
return STATUS_SUCCESS if we are in DEADMAN_KEY state
|
|
return failiure otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
#ifdef _X86_
|
|
|
|
if (ValueData &&
|
|
ValueLength &&
|
|
(*((PULONG)ValueData) == 1)) {
|
|
|
|
VideoDebugPrint((2, "doing VL card detection\n"));
|
|
|
|
return NO_ERROR;
|
|
|
|
} else {
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
//
|
|
// we never have a VL bus on non-x86 systems
|
|
//
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
VP_STATUS
|
|
GetCPUIdCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
)
|
|
{
|
|
VideoDebugPrint((2, "Weitek: Check the SNI CPU ID\n"));
|
|
|
|
//
|
|
// We do not want to try to detect the weitekp9 if there isn't one present.
|
|
// (Kind of a paradox?)
|
|
//
|
|
|
|
if (Identifier) {
|
|
|
|
if (VideoPortCompareMemory(Context,
|
|
Identifier,
|
|
IdentifierLength) == IdentifierLength)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
return ERROR_DEV_NOT_EXIST;
|
|
|
|
} //end GetCPUIdCallback()
|
|
|
|
VP_STATUS
|
|
GetDeviceDataCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
|
PVOID Identifier,
|
|
ULONG IdentifierLength,
|
|
PVOID ConfigurationData,
|
|
ULONG ConfigurationDataLength,
|
|
PVOID ComponentInformation,
|
|
ULONG ComponentInformationLength
|
|
)
|
|
{
|
|
PVIDEO_HARDWARE_CONFIGURATION_DATA configData = ConfigurationData;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension;
|
|
ULONG i;
|
|
|
|
hwDeviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
|
|
|
VideoDebugPrint((2, "Weitek: controller information is present\n"));
|
|
|
|
//
|
|
// We do not want to try to detect the weitekp9 if there isn't one present.
|
|
// (Kind of a paradox?)
|
|
//
|
|
|
|
if (Identifier) {
|
|
|
|
if (VideoPortCompareMemory(L"DIAMOND P9000 VLBUS",
|
|
Identifier,
|
|
sizeof(L"DIAMOND P9000 VLBUS")) ==
|
|
sizeof(L"DIAMOND P9000 VLBUS"))
|
|
{
|
|
hwDeviceExtension->MachineType = SIEMENS;
|
|
}
|
|
else if (VideoPortCompareMemory(L"DIAMOND P9100 VLBUS",
|
|
Identifier,
|
|
sizeof(L"DIAMOND P9100 VLBUS")) ==
|
|
sizeof(L"DIAMOND P9100 VLBUS"))
|
|
|
|
{
|
|
hwDeviceExtension->MachineType = SIEMENS_P9100_VLB;
|
|
}
|
|
else
|
|
{
|
|
return ERROR_DEV_NOT_EXIST;
|
|
}
|
|
|
|
VideoDebugPrint((1, "Siemens Nixdorf RM400 VL with Weitek P9%d00\n",
|
|
hwDeviceExtension->MachineType == SIEMENS ? 0:1));
|
|
|
|
hwDeviceExtension->P9PhysAddr.LowPart = 0x1D000000;
|
|
|
|
//
|
|
// adjust DriverAccessRanges for Siemens box
|
|
//
|
|
// This routine may be called several times, but we
|
|
// only want to do this once!
|
|
//
|
|
|
|
if (!gMadeAdjustments)
|
|
{
|
|
ULONG adjust;
|
|
|
|
if ((hwDeviceExtension->MachineType == SIEMENS_P9100_VLB) &&
|
|
(VideoPortIsCpu(L"RM400-MT") || VideoPortIsCpu(L"RM400-T")
|
|
||VideoPortIsCpu(L"RM400-T MP")))
|
|
{
|
|
//
|
|
// If we have a P9100 VLB and it's *not* on a RM200
|
|
// then use the new address.
|
|
//
|
|
// Otherwise, use the old address.
|
|
//
|
|
|
|
adjust = 0x1E000000;
|
|
}
|
|
else if (hwDeviceExtension->MachineType == SIEMENS
|
|
|| VideoPortIsCpu(L"RM200"))
|
|
{
|
|
adjust = 0x14000000;
|
|
}
|
|
else return ERROR_DEV_NOT_EXIST;
|
|
|
|
DriverAccessRanges[1].RangeStart.LowPart += adjust;
|
|
|
|
for(i=0; i<0x10; i++)
|
|
{
|
|
VLDefDACRegRange[i].RangeStart.LowPart += adjust;
|
|
}
|
|
|
|
gMadeAdjustments = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
return NO_ERROR;
|
|
|
|
} //end GetDeviceDataCallback()
|
|
|
|
VP_STATUS
|
|
P9QueryNamedValueCallback(
|
|
PVOID HwDeviceExtension,
|
|
PVOID Context,
|
|
PWSTR ValueName,
|
|
PVOID ValueData,
|
|
ULONG ValueLength
|
|
)
|
|
{
|
|
if (ValueLength == 4)
|
|
{
|
|
*((PULONG) Context) = *((PULONG)ValueData);
|
|
return(NO_ERROR);
|
|
}
|
|
else
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
WeitekP91NapTime(
|
|
VOID
|
|
)
|
|
{
|
|
ULONG count;
|
|
|
|
for (count=0; count<100; count) {
|
|
|
|
VideoPortStallExecution(1000);
|
|
++count;
|
|
}
|
|
}
|
|
|
|
|
|
VP_STATUS
|
|
FindAdapter(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
PVOID HwContext,
|
|
PWSTR ArgumentString,
|
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|
PP9ADAPTER pCurAdapter
|
|
)
|
|
|
|
/*++
|
|
|
|
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(). Must be NULL for PnP drivers.
|
|
|
|
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
|
|
and the same config info. This is used by the miniport drivers which
|
|
can search for several adapters on a bus.
|
|
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PULONG pVirtAddr;
|
|
SHORT i;
|
|
ULONG TotalRanges;
|
|
|
|
ULONG CoProcId;
|
|
VP_STATUS vpCurrStatus = NO_ERROR;
|
|
VGA_REGS VGAregs;
|
|
BOOLEAN bRetryP9100 = TRUE;
|
|
|
|
VideoDebugPrint((2, "FindAdapter: enter\n"));
|
|
|
|
//
|
|
// NOTE:
|
|
// Important workaround for detection:
|
|
//
|
|
// We can not always autodetect Weitek VL designs because many machines
|
|
// will NMI if we try to access the high memory locations at which the
|
|
// card is present.
|
|
//
|
|
// We will only "detect" the Weitek VL cards if the user specifically
|
|
// installed the weitek driver using the video applet.
|
|
//
|
|
// We will only autodetect the PCI and Viper VL designs. The bAutoDetect
|
|
// field in the adapter info structure indicates if a design can be
|
|
// autodetected.
|
|
//
|
|
|
|
if ((!pCurAdapter->pAdapterDesc->bAutoDetect) &&
|
|
!bFoundPCI &&
|
|
VideoPortGetRegistryParameters(HwDeviceExtension,
|
|
L"DetectVLCards",
|
|
FALSE,
|
|
pVlCardDetect,
|
|
NULL) != NO_ERROR)
|
|
{
|
|
VideoDebugPrint((1, "FindAdapter: failed to autodetect\n"));
|
|
return(ERROR_DEV_NOT_EXIST);
|
|
}
|
|
|
|
//
|
|
// If the bus type in pCurAdapter->pAdapterDesc is PCI, but
|
|
// the AdapterInterfaceType in ConfigInfo is not PCI, return
|
|
// ERROR_DEV_NOT_EXIST.
|
|
//
|
|
|
|
if ((ConfigInfo->AdapterInterfaceType == PCIBus) &&
|
|
(!pCurAdapter->pAdapterDesc->bPCIAdapter))
|
|
return ERROR_DEV_NOT_EXIST;
|
|
|
|
|
|
HwDeviceExtension->P9PhysAddr.HighPart = 0;
|
|
HwDeviceExtension->P9PhysAddr.LowPart = 0;
|
|
|
|
VideoPortGetRegistryParameters((PVOID) HwDeviceExtension,
|
|
L"Membase",
|
|
FALSE,
|
|
P9QueryNamedValueCallback,
|
|
(PVOID) &(HwDeviceExtension->P9PhysAddr.LowPart));
|
|
|
|
|
|
// SNI is shipping MIPS machine with Internal and PCI versions of the
|
|
// weitek chips. For other buses, don't try to load
|
|
// For MIPS machine with an Internal Bus, check the ID
|
|
// for PPC, we just go through normal detection
|
|
//
|
|
|
|
#if defined(_MIPS_)
|
|
|
|
if (ConfigInfo->AdapterInterfaceType == Internal)
|
|
{
|
|
//
|
|
// Let get the hardware information from the hardware description
|
|
// part of the registry.
|
|
//
|
|
// Check if there is a video adapter on the internal bus.
|
|
// Exit right away if there is not.
|
|
//
|
|
|
|
if (NO_ERROR != VideoPortGetDeviceData(HwDeviceExtension,
|
|
VpControllerData,
|
|
&GetDeviceDataCallback,
|
|
pCurAdapter))
|
|
{
|
|
|
|
VideoDebugPrint((1, "Weitek: VideoPort get controller info failed\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
}
|
|
else if(ConfigInfo->AdapterInterfaceType != PCIBus)
|
|
return ERROR_INVALID_PARAMETER;
|
|
#endif
|
|
|
|
//
|
|
// Move the various Hw component structures for this board into the
|
|
// device extension.
|
|
//
|
|
|
|
VideoPortMoveMemory(&HwDeviceExtension->P9CoprocInfo,
|
|
pCurAdapter->pCoprocInfo,
|
|
sizeof(P9_COPROC));
|
|
|
|
VideoPortMoveMemory(&HwDeviceExtension->AdapterDesc,
|
|
pCurAdapter->pAdapterDesc,
|
|
sizeof(ADAPTER_DESC));
|
|
|
|
VideoPortMoveMemory(&HwDeviceExtension->Dac,
|
|
pCurAdapter->pDac,
|
|
sizeof(DAC));
|
|
|
|
//
|
|
// Set up the array of register ptrs in the device extension:
|
|
// the OEMGetBaseAddr routine will need them if a board is found.
|
|
// The arrays are kept at the very end of the device extension and
|
|
// are order dependent.
|
|
//
|
|
|
|
(PUCHAR) HwDeviceExtension->pDACRegs = (PUCHAR) HwDeviceExtension +
|
|
sizeof(HW_DEVICE_EXTENSION);
|
|
|
|
//
|
|
// Call the OEMGetBaseAddr routine to determine if the board is
|
|
// installed.
|
|
//
|
|
VideoDebugPrint((2, "AdapterInterfaceType:%d\n", ConfigInfo->AdapterInterfaceType));
|
|
|
|
if (!pCurAdapter->pAdapterDesc->OEMGetBaseAddr(HwDeviceExtension))
|
|
{
|
|
VideoDebugPrint((1, "FindAdapter, GetBaseAddr Failed, line %d\n", __LINE__));
|
|
return(ERROR_DEV_NOT_EXIST);
|
|
}
|
|
|
|
//
|
|
// We found an adapter, pickup a local for the chip type.
|
|
//
|
|
|
|
CoProcId = pCurAdapter->pCoprocInfo->CoprocId;
|
|
|
|
//
|
|
// 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))
|
|
{
|
|
VideoDebugPrint((1, "FindAdapter Failed, wrong version, line %d\n", __LINE__));
|
|
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->HardwareStateSize = 0;
|
|
|
|
if ((CoProcId == P9000_ID) && !(pCurAdapter->pAdapterDesc->bPCIAdapter))
|
|
{
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0L;
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0L;
|
|
ConfigInfo->VdmPhysicalVideoMemoryLength = 0L;
|
|
}
|
|
else
|
|
{
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = MEM_VGA_ADDR;
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0L;
|
|
ConfigInfo->VdmPhysicalVideoMemoryLength = MEM_VGA_SIZE;
|
|
if(HwDeviceExtension->MachineType == SIEMENS_P9100_PCi)
|
|
ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart |= 0x10000000;
|
|
}
|
|
//
|
|
// The OEMGetBaseAddr routine should have initialized the following
|
|
// data structures:
|
|
//
|
|
// 1) The DAC access ranges in DriverAccessRanges.
|
|
// 2) The P9PhysAddr field in the device extension.
|
|
//
|
|
|
|
//
|
|
// Initialize the physical address for the registers and frame buffer.
|
|
//
|
|
|
|
HwDeviceExtension->CoprocPhyAddr = HwDeviceExtension->P9PhysAddr;
|
|
HwDeviceExtension->CoprocPhyAddr.LowPart +=
|
|
HwDeviceExtension->P9CoprocInfo.CoprocRegOffset;
|
|
|
|
HwDeviceExtension->PhysicalFrameAddr = HwDeviceExtension->P9PhysAddr;
|
|
HwDeviceExtension->PhysicalFrameAddr.LowPart +=
|
|
HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
|
|
|
|
//
|
|
// Initialize the access range structure with the base address values
|
|
// so the driver can register its memory usage.
|
|
//
|
|
|
|
DriverAccessRanges[0].RangeStart =
|
|
HwDeviceExtension->P9PhysAddr;
|
|
DriverAccessRanges[0].RangeLength =
|
|
HwDeviceExtension->P9CoprocInfo.AddrSpace;
|
|
|
|
if (CoProcId == P9000_ID)
|
|
{
|
|
//
|
|
// Init the total number of standard access ranges.
|
|
//
|
|
|
|
TotalRanges = NUM_DRIVER_ACCESS_RANGES + NUM_DAC_ACCESS_RANGES + 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
TotalRanges = NUM_DRIVER_ACCESS_RANGES;
|
|
}
|
|
|
|
//
|
|
// Check to see if another miniport driver has allocated any of the
|
|
// coprocessor's memory space.
|
|
//
|
|
|
|
if (VideoPortVerifyAccessRanges(HwDeviceExtension,
|
|
TotalRanges,
|
|
DriverAccessRanges) != NO_ERROR)
|
|
{
|
|
if (HwDeviceExtension->AdapterDesc.bRequiresIORanges)
|
|
{
|
|
//
|
|
// If we need more then just the coproc ranges, and couldn't get
|
|
// then we need to fail.
|
|
//
|
|
|
|
VideoDebugPrint((1, "FindAdapter : (ERROR) VideoPortVerifyAccessRanges - Failed 1\n"));
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We couldn't claim all of the access ranges. However, this is a
|
|
// card which really only needs the coproc and frame buffer range.
|
|
//
|
|
|
|
if (DriverAccessRanges[0].RangeStart.LowPart &&
|
|
VideoPortVerifyAccessRanges(HwDeviceExtension,
|
|
1,
|
|
DriverAccessRanges) != NO_ERROR)
|
|
{
|
|
//
|
|
// This access range we can't do without
|
|
//
|
|
|
|
VideoDebugPrint((1, "FindAdapter : (ERROR) VideoPortVerifyAccessRanges - Failed 2\n"));
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If we get here, then we must have successfully claimed
|
|
// the VGA access ranges. Lets map them in.
|
|
//
|
|
|
|
HwDeviceExtension->Vga =
|
|
VideoPortGetDeviceBase(HwDeviceExtension,
|
|
DriverAccessRanges[1].RangeStart,
|
|
DriverAccessRanges[1].RangeLength,
|
|
DriverAccessRanges[1].RangeInIoSpace);
|
|
}
|
|
|
|
//
|
|
// map coproc, frame buffer, and vga ports
|
|
//
|
|
|
|
{
|
|
PHYSICAL_ADDRESS Base;
|
|
|
|
Base = DriverAccessRanges[0].RangeStart;
|
|
Base.QuadPart += HwDeviceExtension->P9CoprocInfo.CoprocRegOffset;
|
|
|
|
HwDeviceExtension->Coproc =
|
|
VideoPortGetDeviceBase(HwDeviceExtension,
|
|
Base,
|
|
0x100000,
|
|
DriverAccessRanges[0].RangeInIoSpace);
|
|
|
|
Base = DriverAccessRanges[0].RangeStart;
|
|
Base.QuadPart += HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
|
|
|
|
HwDeviceExtension->FrameAddress =
|
|
VideoPortGetDeviceBase(HwDeviceExtension,
|
|
Base,
|
|
HwDeviceExtension->P9CoprocInfo.AddrSpace -
|
|
HwDeviceExtension->P9CoprocInfo.FrameBufOffset,
|
|
DriverAccessRanges[0].RangeInIoSpace);
|
|
}
|
|
|
|
if( HwDeviceExtension->Coproc == NULL ||
|
|
HwDeviceExtension->FrameAddress == NULL ||
|
|
(HwDeviceExtension->Vga == NULL &&
|
|
HwDeviceExtension->AdapterDesc.bRequiresIORanges))
|
|
{
|
|
VideoDebugPrint((1, "weitekp9: VideoPortGetDeviceBase failed.\n"));
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (CoProcId == P9000_ID)
|
|
{
|
|
//
|
|
// Map all of the DAC registers into system virtual address space.
|
|
// These registers are mapped seperately from the coprocessor and DAC
|
|
// registers since their virtual addresses must be kept in an array
|
|
// at the end of the device extension.
|
|
//
|
|
|
|
for (i = 0; i < NUM_DAC_ACCESS_RANGES; i++)
|
|
{
|
|
if ( (HwDeviceExtension->pDACRegs[i] =
|
|
(ULONG)(ULONG_PTR) VideoPortGetDeviceBase(HwDeviceExtension,
|
|
DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeStart,
|
|
DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeLength,
|
|
DriverAccessRanges[i + NUM_DRIVER_ACCESS_RANGES].RangeInIoSpace)) == 0)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
for (i = 0; i < NUM_DAC_ACCESS_RANGES; i++)
|
|
{
|
|
HwDeviceExtension->pDACRegs[i] = P91_Bt485_DAC_Regs[i];
|
|
}
|
|
}
|
|
|
|
// NOTE: !!! jn 1294
|
|
// On the P9100 we will always allocate the a full 12 meg
|
|
// of address space...
|
|
|
|
if (CoProcId == P9000_ID)
|
|
{
|
|
//
|
|
// Enable the video memory so it can be sized.
|
|
//
|
|
|
|
if (HwDeviceExtension->AdapterDesc.P9EnableMem)
|
|
{
|
|
if (!HwDeviceExtension->AdapterDesc.P9EnableMem(HwDeviceExtension))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Determine the amount of video memory installed.
|
|
//
|
|
|
|
HwDeviceExtension->P9CoprocInfo.SizeMem(HwDeviceExtension);
|
|
}
|
|
|
|
//
|
|
// Detect the DAC type.
|
|
// !!!
|
|
// On the X86, This requires switching into native mode, so the screen
|
|
// will be dark for the remainder of boot.
|
|
//
|
|
|
|
if (CoProcId == P9100_ID)
|
|
{
|
|
ULONG ulPuConfig;
|
|
|
|
|
|
/*
|
|
** SNI-Od: Save all VGA registers before we switch
|
|
** to native mode
|
|
*/
|
|
VideoDebugPrint((2, "Before save\n"));
|
|
|
|
P91SaveVGARegs(HwDeviceExtension,&VGAregs);
|
|
VideoDebugPrint((2, "After save\n"));
|
|
WeitekP91NapTime();
|
|
|
|
// If we have found a serious error, don't go any further. We have already
|
|
// logged the error if the status is set in HwDeviceExtension
|
|
|
|
if ( vpP91AdapterStatus != NO_ERROR )
|
|
{
|
|
P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
|
|
return (ERROR_DEV_NOT_EXIST);
|
|
}
|
|
|
|
// Get into Native mode
|
|
|
|
if (HwDeviceExtension->usBusType == VESA)
|
|
{
|
|
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_CONFIGURATION, 3);
|
|
VideoDebugPrint((2, "WroteConfig 1\n"));
|
|
}
|
|
|
|
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0);
|
|
VideoDebugPrint((2, "WroteConfig 2\n"));
|
|
WeitekP91NapTime();
|
|
|
|
HwDeviceExtension->p91State.ulPuConfig = P9_RD_REG(P91_PU_CONFIG);
|
|
|
|
// Look to see if it is an Intergraph board - if so, we want to error out
|
|
|
|
if ( bIntergraphBoard(HwDeviceExtension) == TRUE )
|
|
{
|
|
vpCurrStatus = P9_INTERGRAPH_FOUND;
|
|
goto error1;
|
|
}
|
|
|
|
// Determine the VRAM type:
|
|
|
|
HwDeviceExtension->p91State.bVram256 =
|
|
(HwDeviceExtension->p91State.ulPuConfig & P91_PUC_MEMORY_DEPTH)
|
|
? FALSE : TRUE;
|
|
|
|
// Size the memory
|
|
|
|
P91SizeVideoMemory(HwDeviceExtension);
|
|
VideoDebugPrint((2, "Sized mem\n"));
|
|
WeitekP91NapTime();
|
|
|
|
// Setup the Hardware Device Extension.
|
|
// So the mode counter will work.
|
|
|
|
HwDeviceExtension->FrameLength = HwDeviceExtension->p91State.ulFrameBufferSize;
|
|
|
|
// Make sure we are supporting the correct DAC.
|
|
|
|
ulPuConfig = HwDeviceExtension->p91State.ulPuConfig;
|
|
|
|
if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_IBM525)
|
|
{
|
|
if (HwDeviceExtension->Dac.ulDacId != DAC_ID_IBM525)
|
|
{
|
|
VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an IBM525 DAC, Expected a Bt485 DAC\n"));
|
|
goto error1;
|
|
}
|
|
}
|
|
else if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_BT485)
|
|
{
|
|
if (HwDeviceExtension->Dac.ulDacId != DAC_ID_BT485)
|
|
{
|
|
VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an BT485 DAC, Expected an IBM525 DAC\n"));
|
|
goto error1;
|
|
}
|
|
}
|
|
else if ((ulPuConfig & P91_PUC_RAMDAC_TYPE) == P91_PUC_DAC_BT489)
|
|
{
|
|
if (HwDeviceExtension->Dac.ulDacId != DAC_ID_BT489)
|
|
{
|
|
VideoDebugPrint((1, "WEITEKP9! WARNING - Detected an BT489 DAC, Expected an IBM525 DAC\n"));
|
|
goto error1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vpCurrStatus = P9_UNSUPPORTED_DAC;
|
|
VideoDebugPrint((1, "WEITEKP9! ERROR - Found P9100, detected an unsupported DAC\n"));
|
|
goto error1;
|
|
}
|
|
|
|
/*
|
|
** SNI-Od: Restore all VGA registers
|
|
** after we switch back to VGA mode
|
|
*/
|
|
VideoDebugPrint((2, "Before 1st write config"));
|
|
WeitekP91NapTime();
|
|
|
|
WriteP9ConfigRegister(HwDeviceExtension,P91_CONFIG_MODE,0x2);
|
|
VideoDebugPrint((2, "After wrote config\n"));
|
|
|
|
VideoDebugPrint((2, "Before restore\n"));
|
|
WeitekP91NapTime();
|
|
|
|
P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
|
|
VideoDebugPrint((2, "After restore\n"));
|
|
WeitekP91NapTime();
|
|
|
|
}
|
|
|
|
//
|
|
// Set the Chip, Adapter, DAC, and Memory information in the registry.
|
|
//
|
|
|
|
DevSetRegistryParams(HwDeviceExtension);
|
|
|
|
|
|
//
|
|
// Initialize the monitor parameters.
|
|
//
|
|
|
|
HwDeviceExtension->CurrentModeNumber = 0;
|
|
|
|
//
|
|
// Initialize the pointer state flags.
|
|
//
|
|
|
|
HwDeviceExtension->flPtrState = 0;
|
|
|
|
//
|
|
// NOTE:
|
|
// Should we free up all the address map we allocated to ourselves ?
|
|
// Do we use them after initialization ???
|
|
//
|
|
// VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Coproc);
|
|
// VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Vga);
|
|
|
|
//
|
|
// Indicate a successful completion status.
|
|
//
|
|
|
|
VideoDebugPrint((2, "FindAdapter: succeeded\n"));
|
|
|
|
if_Not_SIEMENS_P9100_VLB()
|
|
VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
|
|
|
|
InitializeModes(HwDeviceExtension);
|
|
|
|
WeitekP91NapTime();
|
|
VideoDebugPrint((2, "return\n"));
|
|
|
|
return(NO_ERROR);
|
|
|
|
//
|
|
// We get here if we really detected a problem, not a mismatch of configuration
|
|
//
|
|
|
|
error1:
|
|
|
|
if (CoProcId == P9100_ID)
|
|
{
|
|
P91RestoreVGAregs(HwDeviceExtension,&VGAregs);
|
|
VideoDebugPrint((2, "restored vga\n"));
|
|
WeitekP91NapTime();
|
|
}
|
|
|
|
if ( vpCurrStatus != NO_ERROR && vpCurrStatus != vpP91AdapterStatus )
|
|
{
|
|
vpP91AdapterStatus = vpCurrStatus;
|
|
|
|
VideoPortLogError(HwDeviceExtension,
|
|
NULL,
|
|
vpCurrStatus,
|
|
__LINE__);
|
|
}
|
|
|
|
#if defined(i386)
|
|
// Switch back to VGA emulation mode
|
|
//
|
|
// We need to do this so that the VGA miniport can start up.
|
|
//
|
|
|
|
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0x2);
|
|
#endif
|
|
|
|
VideoDebugPrint((1, "returning ERROR_DEV_NOT_EXIST\n"));
|
|
|
|
return (ERROR_DEV_NOT_EXIST);
|
|
|
|
} // end FindAdapter()
|
|
|
|
VOID
|
|
DevSetRegistryParams(PHW_DEVICE_EXTENSION hwDeviceExtension)
|
|
{
|
|
PUSHORT pwszChip,
|
|
pwszDAC,
|
|
pwszAdapterString;
|
|
|
|
ULONG cbChip,
|
|
cbDAC,
|
|
cbAdapterString,
|
|
AdapterMemorySize;
|
|
|
|
//
|
|
// First set the string for the chip type, and set the
|
|
// memory configuration if available.
|
|
//
|
|
|
|
if (hwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
|
|
{
|
|
pwszChip = L"Weitek P9000";
|
|
cbChip = sizeof (L"Weitek P9000");
|
|
}
|
|
else
|
|
{
|
|
pwszChip = L"Weitek P9100";
|
|
cbChip = sizeof (L"Weitek P9100");
|
|
}
|
|
|
|
//
|
|
// Set the memory size
|
|
//
|
|
|
|
AdapterMemorySize = hwDeviceExtension->FrameLength;
|
|
|
|
//
|
|
// Now, set the string for the DAC type.
|
|
//
|
|
|
|
if (hwDeviceExtension->Dac.ulDacId == DAC_ID_BT485)
|
|
{
|
|
pwszDAC = L"Brooktree Bt485";
|
|
cbDAC = sizeof (L"Brooktree Bt485");
|
|
}
|
|
else if (hwDeviceExtension->Dac.ulDacId == DAC_ID_BT489)
|
|
{
|
|
pwszDAC = L"Brooktree Bt489";
|
|
cbDAC = sizeof (L"Brooktree Bt489");
|
|
}
|
|
else
|
|
{
|
|
pwszDAC = L"IBM IBM525";
|
|
cbDAC = sizeof (L"IBM IBM525");
|
|
}
|
|
|
|
//
|
|
// Now just pickup the adapter information from the adapter description.
|
|
//
|
|
|
|
//
|
|
// Use the length of the longest string !
|
|
//
|
|
|
|
pwszAdapterString = hwDeviceExtension->AdapterDesc.ausAdapterIDString;
|
|
cbAdapterString = sizeof(L"Generic Weitek P9000 VL Adapter");
|
|
|
|
//
|
|
// We now have a complete hardware description of the hardware.
|
|
// Save the information to the registry so it can be used by
|
|
// configuration programs - such as the display applet
|
|
//
|
|
|
|
VideoPortSetRegistryParameters(hwDeviceExtension,
|
|
L"HardwareInformation.ChipType",
|
|
pwszChip,
|
|
cbChip);
|
|
|
|
VideoPortSetRegistryParameters(hwDeviceExtension,
|
|
L"HardwareInformation.DacType",
|
|
pwszDAC,
|
|
cbDAC);
|
|
|
|
VideoPortSetRegistryParameters(hwDeviceExtension,
|
|
L"HardwareInformation.MemorySize",
|
|
&AdapterMemorySize,
|
|
sizeof(ULONG));
|
|
|
|
VideoPortSetRegistryParameters(hwDeviceExtension,
|
|
L"HardwareInformation.AdapterString",
|
|
pwszAdapterString,
|
|
cbAdapterString);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
P9Initialize(
|
|
PHW_DEVICE_EXTENSION 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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
VideoDebugPrint((2, "P9Initialize ----------\n"));
|
|
return(TRUE);
|
|
|
|
} // end P9Initialize()
|
|
|
|
|
|
BOOLEAN
|
|
P9StartIO(
|
|
PHW_DEVICE_EXTENSION 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;
|
|
PVIDEO_MODE_INFORMATION modeInformation;
|
|
PVIDEO_MEMORY_INFORMATION memoryInformation;
|
|
ULONG inIoSpace;
|
|
PVIDEO_CLUT clutBuffer;
|
|
PVOID virtualAddr;
|
|
UCHAR i;
|
|
ULONG numValidModes;
|
|
ULONG ulMemoryUsage;
|
|
|
|
// VideoDebugPrint((2, "StartIO ----------\n"));
|
|
|
|
//
|
|
// Switch on the IoContolCode in the RequestPacket. It indicates which
|
|
// function must be performed by the driver.
|
|
//
|
|
|
|
switch (RequestPacket->IoControlCode)
|
|
{
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - IOCTL_QUERY_PUBLIC_ACCESS_RANGES\n"));
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
|
|
{
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
#if 0
|
|
vDumpPCIConfig(HwDeviceExtension,
|
|
"P9StartIo - IOCTL_QUERY_PUBLIC_ACCESS_RANGES");
|
|
#endif
|
|
|
|
// map the coproc to a virtual address
|
|
|
|
//
|
|
// Note that on the Alpha we have to map this in sparse-space
|
|
// because dense-space requires all reads to be 64 bits, which
|
|
// would give us unintended side effects using the Weitek
|
|
// registers.
|
|
//
|
|
|
|
{
|
|
PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
|
|
ULONG CoprocSize = 0x100000;
|
|
|
|
portAccess = RequestPacket->OutputBuffer;
|
|
|
|
portAccess->InIoSpace = FALSE;
|
|
portAccess->MappedInIoSpace = portAccess->InIoSpace;
|
|
portAccess->VirtualAddress = NULL;
|
|
|
|
status = VideoPortMapMemory(HwDeviceExtension,
|
|
HwDeviceExtension->CoprocPhyAddr,
|
|
&CoprocSize,
|
|
&(portAccess->MappedInIoSpace),
|
|
&(portAccess->VirtualAddress));
|
|
|
|
HwDeviceExtension->CoprocVirtAddr = portAccess->VirtualAddress;
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - FreePublicAccessRanges\n"));
|
|
|
|
{
|
|
PVIDEO_MEMORY mappedMemory;
|
|
|
|
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
|
|
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
mappedMemory = RequestPacket->InputBuffer;
|
|
status = NO_ERROR;
|
|
|
|
if (mappedMemory->RequestedVirtualAddress != NULL)
|
|
{
|
|
status = VideoPortUnmapMemory(HwDeviceExtension,
|
|
mappedMemory->
|
|
RequestedVirtualAddress,
|
|
0);
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - 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;
|
|
|
|
#ifdef ALPHA
|
|
|
|
//
|
|
// On the Alpha, we map the frame buffer in dense-space so that
|
|
// we can have GDI draw directly on the surface when we need it
|
|
// to.
|
|
//
|
|
|
|
inIoSpace = 4;
|
|
|
|
#else
|
|
|
|
inIoSpace = 0;
|
|
|
|
#endif
|
|
|
|
status = VideoPortMapMemory(HwDeviceExtension,
|
|
HwDeviceExtension->PhysicalFrameAddr,
|
|
&(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, "P9StartIO - 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_CURRENT_MODE:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - QueryCurrentModes\n"));
|
|
|
|
modeInformation = RequestPacket->OutputBuffer;
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MODE_INFORMATION)) )
|
|
{
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
else
|
|
{
|
|
|
|
*((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
|
|
P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation;
|
|
|
|
((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->Frequency =
|
|
HwDeviceExtension->VideoData.vlr;
|
|
|
|
if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
|
|
{
|
|
((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->DriverSpecificAttributeFlags =
|
|
CAPS_WEITEK_CHIPTYPE_IS_P9000;
|
|
}
|
|
else
|
|
{
|
|
((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer)->DriverSpecificAttributeFlags =
|
|
0;
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - QueryAvailableModes\n"));
|
|
|
|
numValidModes = HwDeviceExtension->ulNumAvailModes;
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
numValidModes * sizeof(VIDEO_MODE_INFORMATION)) )
|
|
{
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
}
|
|
else
|
|
{
|
|
ULONG Flags=0;
|
|
|
|
if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
|
|
{
|
|
Flags = CAPS_WEITEK_CHIPTYPE_IS_P9000;
|
|
}
|
|
|
|
modeInformation = RequestPacket->OutputBuffer;
|
|
|
|
for (i = 0; i < mP9ModeCount; i++)
|
|
{
|
|
if (P9Modes[i].valid == TRUE)
|
|
{
|
|
*modeInformation = P9Modes[i].modeInformation;
|
|
modeInformation->DriverSpecificAttributeFlags = Flags;
|
|
modeInformation++;
|
|
}
|
|
}
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - 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.
|
|
//
|
|
// !!! This must be changed to take into account which monitor
|
|
// is present on the machine.
|
|
//
|
|
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_NUM_MODES)) )
|
|
{
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
else
|
|
{
|
|
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
|
|
HwDeviceExtension->ulNumAvailModes;
|
|
|
|
((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
|
|
sizeof(VIDEO_MODE_INFORMATION);
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_CURRENT_MODE:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - SetCurrentMode\n"));
|
|
|
|
//
|
|
// verify data
|
|
// !!! Make sure it is one of the valid modes on the list
|
|
// calculated using the monitor information.
|
|
//
|
|
|
|
if (((PVIDEO_MODE)(RequestPacket->InputBuffer))->RequestedMode
|
|
>= mP9ModeCount)
|
|
{
|
|
status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
HwDeviceExtension->CurrentModeNumber =
|
|
*(ULONG *)(RequestPacket->InputBuffer);
|
|
|
|
DevInitP9(HwDeviceExtension);
|
|
|
|
#if 0
|
|
vDumpPCIConfig(HwDeviceExtension,
|
|
"P9StartIo - IOCTL_VIDEO_SET_CURRENT_MODE");
|
|
#endif
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
|
|
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - 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 (P9Modes[HwDeviceExtension->CurrentModeNumber].
|
|
modeInformation.BitsPerPlane == 8)
|
|
{
|
|
|
|
HwDeviceExtension->Dac.DACSetPalette(HwDeviceExtension,
|
|
(PULONG)clutBuffer->LookupTable,
|
|
clutBuffer->FirstEntry,
|
|
clutBuffer->NumEntries);
|
|
|
|
status = NO_ERROR;
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
case IOCTL_VIDEO_ENABLE_POINTER:
|
|
{
|
|
|
|
ULONG iCount = (CURSOR_WIDTH * CURSOR_HEIGHT * 2) / 8;
|
|
ULONG xInitPos, yInitPos;
|
|
|
|
VideoDebugPrint((2, "P9StartIO - EnablePointer\n"));
|
|
|
|
xInitPos = P9Modes[HwDeviceExtension->CurrentModeNumber].
|
|
modeInformation.VisScreenWidth / 2;
|
|
yInitPos = P9Modes[HwDeviceExtension->CurrentModeNumber].
|
|
modeInformation.VisScreenHeight / 2;
|
|
|
|
HwDeviceExtension->Dac.HwPointerSetPos(HwDeviceExtension, xInitPos, yInitPos);
|
|
HwDeviceExtension->Dac.HwPointerOn(HwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
break;
|
|
|
|
case IOCTL_VIDEO_DISABLE_POINTER:
|
|
|
|
VideoDebugPrint((2, "P9StartIO - DisablePointer\n"));
|
|
|
|
HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_POSITION:
|
|
{
|
|
|
|
PVIDEO_POINTER_POSITION pointerPosition;
|
|
|
|
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;
|
|
|
|
HwDeviceExtension->Dac.HwPointerSetPos(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, "P9StartIO - 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
|
|
//
|
|
|
|
pPointerPosition->Row = (SHORT)HwDeviceExtension->ulPointerX;
|
|
pPointerPosition->Column = (SHORT)HwDeviceExtension->ulPointerY;
|
|
|
|
RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_POINTER_POSITION);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case IOCTL_VIDEO_SET_POINTER_ATTR: // Set pointer shape
|
|
{
|
|
|
|
PVIDEO_POINTER_ATTRIBUTES pointerAttributes;
|
|
UCHAR *pHWCursorShape; // Temp Buffer
|
|
|
|
VideoDebugPrint((2, "P9StartIO - 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;
|
|
}
|
|
|
|
//
|
|
// If the specified cursor width or height is not valid, then
|
|
// return an invalid parameter error.
|
|
//
|
|
|
|
else if ((pointerAttributes->Width > CURSOR_WIDTH) ||
|
|
(pointerAttributes->Height > CURSOR_HEIGHT))
|
|
{
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
else if (pointerAttributes->Flags & VIDEO_MODE_MONO_POINTER)
|
|
{
|
|
pHWCursorShape = (PUCHAR) &pointerAttributes->Pixels[0];
|
|
|
|
//
|
|
// If this is an animated pointer, don't turn the hw
|
|
// pointer off. This will eliminate cursor blinking.
|
|
// Since GDI currently doesn't pass the ANIMATE_START
|
|
// flag, also check to see if the state of the
|
|
// ANIMATE_UPDATE flag has changed from the last call.
|
|
// If it has, turn the pointer off to eliminate ptr
|
|
// "jumping" when the ptr shape is changed.
|
|
//
|
|
|
|
if (!(pointerAttributes->Flags & VIDEO_MODE_ANIMATE_UPDATE) ||
|
|
((HwDeviceExtension->flPtrState ^
|
|
pointerAttributes->Flags) & VIDEO_MODE_ANIMATE_UPDATE))
|
|
{
|
|
HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
|
|
}
|
|
|
|
//
|
|
// Update the cursor state flags in the Device Extension.
|
|
//
|
|
|
|
HwDeviceExtension->flPtrState = pointerAttributes->Flags;
|
|
|
|
HwDeviceExtension->Dac.HwPointerSetShape(HwDeviceExtension,
|
|
pHWCursorShape);
|
|
HwDeviceExtension->Dac.HwPointerSetPos(HwDeviceExtension,
|
|
(ULONG)pointerAttributes->Column,
|
|
(ULONG)pointerAttributes->Row);
|
|
|
|
|
|
HwDeviceExtension->Dac.HwPointerOn(HwDeviceExtension);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// This cursor is unsupported. Return an error.
|
|
//
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
//
|
|
// Couldn't set the new cursor shape. Ensure that any existing HW
|
|
// cursor is disabled.
|
|
//
|
|
|
|
HwDeviceExtension->Dac.HwPointerOff(HwDeviceExtension);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
|
|
{
|
|
|
|
PVIDEO_POINTER_CAPABILITIES pointerCaps = RequestPacket->OutputBuffer;
|
|
|
|
VideoDebugPrint((2, "P9StartIO - QueryPointerCapabilities\n"));
|
|
|
|
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_POINTER_CAPABILITIES))
|
|
{
|
|
RequestPacket->StatusBlock->Information = 0;
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
pointerCaps->Flags = 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, "P9StartIO - RESET_DEVICE\n"));
|
|
|
|
DevDisableP9(HwDeviceExtension, FALSE);
|
|
|
|
status = NO_ERROR;
|
|
|
|
break;
|
|
|
|
case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
|
|
{
|
|
PVIDEO_SHARE_MEMORY pShareMemory;
|
|
PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation;
|
|
PHYSICAL_ADDRESS shareAddress;
|
|
PVOID virtualAddress;
|
|
ULONG sharedViewSize;
|
|
|
|
VideoDebugPrint((2, "P9StartIo - ShareVideoMemory\n"));
|
|
|
|
if ( (RequestPacket->OutputBufferLength < sizeof(VIDEO_SHARE_MEMORY_INFORMATION)) ||
|
|
(RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
|
|
|
|
VideoDebugPrint((1, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INSUFFICIENT_BUFFER\n"));
|
|
status = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
pShareMemory = RequestPacket->InputBuffer;
|
|
|
|
if ( (pShareMemory->ViewOffset > HwDeviceExtension->FrameLength) ||
|
|
((pShareMemory->ViewOffset + pShareMemory->ViewSize) >
|
|
HwDeviceExtension->FrameLength) ) {
|
|
|
|
VideoDebugPrint((1, "IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INVALID_PARAMETER\n"));
|
|
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;
|
|
|
|
#ifdef ALPHA
|
|
|
|
//
|
|
// On the Alpha, we map the frame buffer in dense-space so that
|
|
// we can have GDI draw directly on the surface when we need it
|
|
// to.
|
|
//
|
|
|
|
inIoSpace = 4;
|
|
|
|
#else
|
|
|
|
inIoSpace = 0;
|
|
|
|
#endif
|
|
|
|
//
|
|
// NOTE: we are ignoring ViewOffset
|
|
//
|
|
|
|
shareAddress.QuadPart =
|
|
HwDeviceExtension->PhysicalFrameAddr.QuadPart;
|
|
|
|
//
|
|
// The frame buffer is always mapped linearly.
|
|
//
|
|
|
|
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:
|
|
{
|
|
PVIDEO_SHARE_MEMORY pShareMemory;
|
|
|
|
VideoDebugPrint((2, "P9StartIo - 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;
|
|
|
|
}
|
|
|
|
//
|
|
// if we get here, an invalid IoControlCode was specified.
|
|
//
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((1, "Fell through P9 startIO routine - invalid command\n"));
|
|
|
|
status = ERROR_INVALID_FUNCTION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
RequestPacket->StatusBlock->Status = status;
|
|
|
|
return(TRUE);
|
|
|
|
} // end P9StartIO()
|
|
|
|
|
|
VOID
|
|
DevInitP9(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the video mode described in the device extension.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
VideoDebugPrint((2, "DevInitP9 ----------\n"));
|
|
|
|
//
|
|
// Copy the default parameters for this resolution mode into the
|
|
// device extension.
|
|
//
|
|
|
|
VideoPortMoveMemory((PVOID) &(HwDeviceExtension->VideoData),
|
|
(PVOID) P9Modes[HwDeviceExtension->CurrentModeNumber].pvData,
|
|
sizeof(VDATA));
|
|
|
|
//
|
|
// Store the requested Bits/Pixel value in the video parms structure
|
|
// in the Device Extension.
|
|
//
|
|
|
|
HwDeviceExtension->usBitsPixel =
|
|
P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.BitsPerPlane *
|
|
P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.NumberOfPlanes;
|
|
|
|
HwDeviceExtension->AdapterDesc.OEMSetMode(HwDeviceExtension);
|
|
|
|
if (HwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID)
|
|
{
|
|
Init8720(HwDeviceExtension);
|
|
|
|
//
|
|
// Initialize the P9000 system configuration register.
|
|
//
|
|
|
|
SysConf(HwDeviceExtension);
|
|
|
|
//
|
|
// Set the P9000 Crtc timing registers.
|
|
//
|
|
|
|
WriteTiming(HwDeviceExtension);
|
|
}
|
|
else
|
|
{
|
|
InitP9100(HwDeviceExtension);
|
|
P91_SysConf(HwDeviceExtension);
|
|
P91_WriteTiming(HwDeviceExtension);
|
|
}
|
|
|
|
|
|
VideoDebugPrint((2, "DevInitP9 ---done---\n"));
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
P9ResetVideo(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG Columns,
|
|
IN ULONG Rows
|
|
)
|
|
|
|
/*++
|
|
|
|
routine description:
|
|
|
|
disables the P9 and turns on vga pass-thru.
|
|
|
|
This function is exported as the HwResetHw entry point so that it may be
|
|
called by the Video Port driver
|
|
at bugcheck time so that VGA video may be enabled.
|
|
|
|
arguments:
|
|
|
|
hwdeviceextension - pointer to the miniport driver's device extension.
|
|
Columns - Number of columns for text mode (not used).
|
|
Rows - Number of rows for text mode (not used).
|
|
|
|
return value:
|
|
|
|
Always returns FALSE so that the Video Port driver will call Int 10 to
|
|
set the desired video mode.
|
|
|
|
--*/
|
|
|
|
{
|
|
DevDisableP9(HwDeviceExtension, TRUE);
|
|
|
|
//
|
|
// Tell the Video Port driver to do an Int 10 mode set.
|
|
//
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
VOID
|
|
DevDisableP9(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|
BOOLEAN BugCheck
|
|
)
|
|
{
|
|
PHYSICAL_ADDRESS Base;
|
|
BOOLEAN bResetComplete;
|
|
|
|
//
|
|
// Clean up the DAC.
|
|
//
|
|
|
|
HwDeviceExtension->Dac.DACRestore(HwDeviceExtension);
|
|
|
|
//
|
|
// If we are not about to "bugcheck", then clear out
|
|
// video memory.
|
|
//
|
|
// NOTE: On the alpha, the attempt to clear video memory causes
|
|
// the machine to hang. So, we just won't clear the memory
|
|
// on the alpha.
|
|
//
|
|
|
|
#if !defined(_ALPHA_)
|
|
|
|
if (BugCheck == FALSE)
|
|
{
|
|
Base = DriverAccessRanges[0].RangeStart;
|
|
Base.QuadPart += HwDeviceExtension->P9CoprocInfo.FrameBufOffset;
|
|
|
|
HwDeviceExtension->FrameAddress =
|
|
VideoPortGetDeviceBase(HwDeviceExtension,
|
|
Base,
|
|
HwDeviceExtension->P9CoprocInfo.AddrSpace -
|
|
HwDeviceExtension->P9CoprocInfo.FrameBufOffset,
|
|
DriverAccessRanges[0].RangeInIoSpace);
|
|
|
|
if (HwDeviceExtension->FrameAddress != NULL)
|
|
{
|
|
VideoDebugPrint((2, "Weitekp9: Clearing video memory.\n"));
|
|
|
|
VideoPortZeroMemory(HwDeviceExtension->FrameAddress,
|
|
HwDeviceExtension->FrameLength);
|
|
|
|
VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
// NOTE: On the P9100 we must take care of the DAC before
|
|
// we change the mode to emulation.
|
|
// !!! This must be tested on the P9000
|
|
|
|
bResetComplete = HwDeviceExtension->AdapterDesc.P9DisableVideo(HwDeviceExtension);
|
|
|
|
//
|
|
// We only want to call int10 if the reset function needs some help and
|
|
// we are not in bugcheck mode, because int10 does not work in bugcheck
|
|
// mode.
|
|
//
|
|
|
|
if ((bResetComplete == FALSE) &&
|
|
(BugCheck == FALSE))
|
|
{
|
|
|
|
#ifndef PPC
|
|
|
|
VIDEO_X86_BIOS_ARGUMENTS biosArguments;
|
|
|
|
//
|
|
// Now simply do an int10 and switch to mode 3. The video BIOS
|
|
// will do the work.
|
|
//
|
|
|
|
VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
|
|
biosArguments.Eax = 0x0003;
|
|
|
|
VideoPortInt10(HwDeviceExtension, &biosArguments);
|
|
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
VOID
|
|
InitializeModes(
|
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine walks through the list of modes, and determines which
|
|
modes will work with our hardware. It sets a flag for each mode
|
|
which will work, and places the number of valid modes in the
|
|
HwDeviceExtension.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension - pointer to the miniport driver's device extension.
|
|
Columns - Number of columns for text mode (not used).
|
|
Rows - Number of rows for text mode (not used).
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
|
|
{
|
|
int i;
|
|
ULONG numValidModes=0;
|
|
|
|
for(i=0; i<mP9ModeCount; i++)
|
|
{
|
|
if ((HwDeviceExtension->FrameLength >=
|
|
P9Modes[i].modeInformation.ScreenStride *
|
|
P9Modes[i].modeInformation.VisScreenHeight) &&
|
|
(HwDeviceExtension->P9CoprocInfo.CoprocId &
|
|
P9Modes[i].ulChips) &&
|
|
((P9Modes[i].modeInformation.BitsPerPlane != 24) ||
|
|
(HwDeviceExtension->Dac.bRamdac24BPP)) )
|
|
{
|
|
|
|
if_SIEMENS_VLB()
|
|
{
|
|
P9Modes[i].modeInformation.AttributeFlags |=
|
|
VIDEO_MODE_NO_64_BIT_ACCESS;
|
|
}
|
|
|
|
P9Modes[i].valid = TRUE;
|
|
numValidModes++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// store the number of valid modes in the HwDeviceExtension
|
|
// so we can quickly look it up later when we need it.
|
|
//
|
|
|
|
HwDeviceExtension->ulNumAvailModes = numValidModes;
|
|
}
|
|
|
|
//
|
|
// Global Functions.
|
|
//
|
|
|
|
long mul32(
|
|
short op1,
|
|
short op2
|
|
)
|
|
{
|
|
return ( ((long) op1) * ((long) op2));
|
|
}
|
|
|
|
int div32(
|
|
long op1,
|
|
short op2
|
|
)
|
|
{
|
|
return ( (int) (op1 / (long) op2));
|
|
}
|
|
|
|
#if (_WIN32_WINNT >= 500)
|
|
|
|
//
|
|
// Routine to set a desired DPMS power management state.
|
|
//
|
|
VP_STATUS
|
|
WP9SetPower50(
|
|
PHW_DEVICE_EXTENSION phwDeviceExtension,
|
|
ULONG HwDeviceId,
|
|
PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
|
|
)
|
|
{
|
|
if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
|
|
(pVideoPowerMgmt->PowerState == VideoPowerHibernate) ||
|
|
(pVideoPowerMgmt->PowerState == VideoPowerStandBy)
|
|
) {
|
|
|
|
return NO_ERROR;
|
|
|
|
} else {
|
|
|
|
return ERROR_INVALID_FUNCTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Routine to retrieve possible DPMS power management states.
|
|
//
|
|
VP_STATUS
|
|
WP9GetPower50(
|
|
PHW_DEVICE_EXTENSION phwDeviceExtension,
|
|
ULONG HwDeviceId,
|
|
PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
|
|
)
|
|
{
|
|
if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
|
|
(pVideoPowerMgmt->PowerState == VideoPowerHibernate)) {
|
|
|
|
return NO_ERROR;
|
|
|
|
} else {
|
|
|
|
return ERROR_INVALID_FUNCTION;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Routine to retrieve the Enhanced Display ID structure via DDC
|
|
//
|
|
ULONG
|
|
WP9GetVideoChildDescriptor(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
|
|
PVIDEO_CHILD_TYPE pChildType,
|
|
PVOID pvChildDescriptor,
|
|
PULONG pHwId,
|
|
PULONG pUnused
|
|
)
|
|
{
|
|
PHW_DEVICE_EXTENSION pHwDeviceExtension = HwDeviceExtension;
|
|
ULONG Status;
|
|
|
|
ASSERT(pHwDeviceExtension != NULL && pMoreChildren != NULL);
|
|
|
|
VideoDebugPrint((2, "weitekp9 GetVideoChildDescriptor: *** Entry point ***\n"));
|
|
|
|
//
|
|
// Determine if the graphics adapter in the system supports
|
|
// DDC2 (our miniport only supports DDC2, not DDC1). This has
|
|
// the side effect (assuming both monitor and card support
|
|
// DDC2) of switching the monitor from DDC1 mode (repeated
|
|
// "blind" broadcast of EDID clocked by the vertical sync
|
|
// signal) to DDC2 mode (query/response not using any of the
|
|
// normal video lines - can transfer information rapidly
|
|
// without first disrupting the screen by switching into
|
|
// a pseudo-mode with a high vertical sync frequency).
|
|
//
|
|
// Since we must support hot-plugging of monitors, and our
|
|
// routine to obtain the EDID structure via DDC2 assumes that
|
|
// the monitor is in DDC2 mode, we must make this test each
|
|
// time this entry point is called.
|
|
//
|
|
|
|
switch (ChildEnumInfo->ChildIndex) {
|
|
case 0:
|
|
|
|
//
|
|
// Case 0 is used to enumerate devices found by the ACPI firmware.
|
|
//
|
|
// Since we do not support ACPI devices yet, we must return failure.
|
|
//
|
|
|
|
Status = ERROR_NO_MORE_DEVICES;
|
|
break;
|
|
|
|
case 1:
|
|
|
|
//
|
|
// We do not support monitor enumeration
|
|
//
|
|
|
|
Status = ERROR_NO_MORE_DEVICES;
|
|
break;
|
|
|
|
case DISPLAY_ADAPTER_HW_ID:
|
|
{
|
|
|
|
PUSHORT pPnpDeviceDescription = NULL;
|
|
ULONG stringSize = sizeof(L"*PNPXXXX");
|
|
|
|
|
|
//
|
|
// Special ID to handle return legacy PnP IDs for root enumerated
|
|
// devices.
|
|
//
|
|
|
|
*pChildType = VideoChip;
|
|
*pHwId = DISPLAY_ADAPTER_HW_ID;
|
|
|
|
//
|
|
// Figure out which card type and set pPnpDeviceDescription at
|
|
// associated string.
|
|
//
|
|
|
|
// WTK_9100_ID 0x0002
|
|
if (pHwDeviceExtension->P9CoprocInfo.CoprocId == P9100_ID)
|
|
pPnpDeviceDescription = L"*PNP0002";
|
|
|
|
// WTK_9002_ID 0x9002
|
|
else if (pHwDeviceExtension->P9CoprocInfo.CoprocId == P9000_ID )
|
|
pPnpDeviceDescription = L"*PNP9002";
|
|
|
|
else {
|
|
VideoDebugPrint((1, "weitekp9.sys coprocId:%x\n",
|
|
pHwDeviceExtension->P9CoprocInfo.CoprocId));
|
|
}
|
|
//
|
|
// Now just copy the string into memory provided.
|
|
//
|
|
|
|
if (pPnpDeviceDescription)
|
|
memcpy(pvChildDescriptor, pPnpDeviceDescription, stringSize);
|
|
|
|
Status = ERROR_MORE_DATA;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
|
|
Status = ERROR_NO_MORE_DEVICES;
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
#endif // _WIN32_WINNT >= 500
|