577 lines
12 KiB
C
577 lines
12 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1993 Weitek Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
viper.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains OEM specific functions for the Diamond Viper
|
|||
|
board.
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode
|
|||
|
|
|||
|
Revision History may be found at the end of this file.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "p9.h"
|
|||
|
#include "p9gbl.h"
|
|||
|
#include "p9000.h"
|
|||
|
#include "viper.h"
|
|||
|
#include "vga.h"
|
|||
|
#include "p9errlog.h"
|
|||
|
|
|||
|
|
|||
|
#define REJECT_ON_BIOS_VERSION 0
|
|||
|
|
|||
|
//
|
|||
|
// OEM specific static data.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// This structure is used to match the possible physical address
|
|||
|
// mappings with the value to be written to the sequencer control
|
|||
|
// register.
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
PHYSICAL_ADDRESS BaseMemAddr;
|
|||
|
USHORT RegValue;
|
|||
|
} MEM_RANGE;
|
|||
|
|
|||
|
MEM_RANGE ViperMemRange[] =
|
|||
|
{
|
|||
|
{ 0x0A0000000, 0L, MEM_AXXX },
|
|||
|
{ 0x080000000, 0L, MEM_8XXX },
|
|||
|
{ 0x020000000, 0L, MEM_2XXX },
|
|||
|
{ 0x01D000000, 0L, MEM_AXXX }
|
|||
|
};
|
|||
|
|
|||
|
LONG NumMemRanges = sizeof(ViperMemRange) / sizeof(MEM_RANGE);
|
|||
|
|
|||
|
|
|||
|
#ifdef REJECT_ON_BIOS_VERSION
|
|||
|
|
|||
|
/*++
|
|||
|
** bRejectOnBiosVersion
|
|||
|
*
|
|||
|
* FILENAME: D:\nt351.nc\weitek\p9x\mini\viper.c
|
|||
|
*
|
|||
|
* PARAMETERS: PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
* PUCHAR pjBios linear address of the BIOS
|
|||
|
* ULONG ulBiosLength lengh of the BIOS
|
|||
|
*
|
|||
|
* DESCRIPTION: Scan the Bios,
|
|||
|
*
|
|||
|
* RETURNS: TRUE to reject supporting this card.
|
|||
|
* FALSE to support this card.
|
|||
|
*
|
|||
|
*
|
|||
|
--*/
|
|||
|
BOOLEAN
|
|||
|
bRejectOnBiosVersion(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
|||
|
PUCHAR pjBiosAddr,
|
|||
|
ULONG ulBiosLength)
|
|||
|
{
|
|||
|
|
|||
|
// Add the strings you want to detect for rejection to this array
|
|||
|
|
|||
|
static PUCHAR aszBiosVersion[] = {
|
|||
|
"VIPER VLB Vers. 1",
|
|||
|
"VIPER VLB Vers. 2",
|
|||
|
NULL
|
|||
|
};
|
|||
|
|
|||
|
LONG i;
|
|||
|
BOOLEAN bFound = FALSE;
|
|||
|
|
|||
|
for (i = 0; aszBiosVersion[i] != 0; i++)
|
|||
|
{
|
|||
|
|
|||
|
if (VideoPortScanRom(HwDeviceExtension,
|
|||
|
(PUCHAR) pjBiosAddr,
|
|||
|
VGA_BIOS_LEN,
|
|||
|
aszBiosVersion[i]))
|
|||
|
{
|
|||
|
bFound = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (bFound == TRUE)
|
|||
|
{
|
|||
|
VideoPortLogError(HwDeviceExtension,
|
|||
|
NULL,
|
|||
|
P9_DOWN_LEVEL_BIOS,
|
|||
|
i);
|
|||
|
VideoDebugPrint((0, "P9X - Down Level Bios\n"));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// We will always boot, we'll just warn the user that bad things may happen
|
|||
|
|
|||
|
return (FALSE);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endif // REJECT_ON_BIOS_VERSION
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ViperGetBaseAddr(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Perform board detection and if present return the P9000 base address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE - Board found, P9 and Frame buffer address info was placed in
|
|||
|
the device extension.
|
|||
|
|
|||
|
FALSE - Board not found.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
VP_STATUS status;
|
|||
|
SHORT i;
|
|||
|
ULONG ulBiosAddr;
|
|||
|
BOOLEAN bValid = FALSE;
|
|||
|
|
|||
|
VIDEO_ACCESS_RANGE BiosAccessRange =
|
|||
|
{
|
|||
|
VGA_BIOS_ADDR, // Low address
|
|||
|
0x00000000, // Hi address
|
|||
|
VGA_BIOS_LEN, // length
|
|||
|
0, // Is range in i/o space?
|
|||
|
1, // Range should be visible
|
|||
|
1 // Range should be shareable
|
|||
|
};
|
|||
|
|
|||
|
if (HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Determine if a Viper card is installed by scanning the VGA BIOS ROM
|
|||
|
// memory space.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Map in the BIOS' memory space. If it can't be mapped,
|
|||
|
// return an error.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->MachineType == SIEMENS)
|
|||
|
{
|
|||
|
BiosAccessRange.RangeStart.LowPart += 0x10000000L;
|
|||
|
}
|
|||
|
|
|||
|
if (VideoPortVerifyAccessRanges(HwDeviceExtension,
|
|||
|
1,
|
|||
|
&BiosAccessRange) != NO_ERROR)
|
|||
|
{
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
if ((ulBiosAddr = (ULONG)
|
|||
|
VideoPortGetDeviceBase(HwDeviceExtension,
|
|||
|
BiosAccessRange.RangeStart,
|
|||
|
BiosAccessRange.RangeLength,
|
|||
|
FALSE)) == 0)
|
|||
|
{
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
if (!VideoPortScanRom(HwDeviceExtension,
|
|||
|
(PUCHAR) ulBiosAddr,
|
|||
|
VGA_BIOS_LEN,
|
|||
|
VIPER_VL_ID_STR))
|
|||
|
{
|
|||
|
VideoPortFreeDeviceBase(HwDeviceExtension, (PVOID) ulBiosAddr);
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
#ifdef REJECT_ON_BIOS_VERSION
|
|||
|
|
|||
|
if (bRejectOnBiosVersion(HwDeviceExtension, (PUCHAR) ulBiosAddr, VGA_BIOS_LEN))
|
|||
|
return (FALSE);
|
|||
|
|
|||
|
#endif // REJECT_ON_BIOS_VERSION
|
|||
|
|
|||
|
VideoPortFreeDeviceBase(HwDeviceExtension, (PVOID) ulBiosAddr);
|
|||
|
|
|||
|
//
|
|||
|
// For now, pretend we have a Weitek 5x86 VGA. Later we may call the
|
|||
|
// Viper BIOS to determine which type of BIOS is installed.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Copy the DAC register access ranges to the global access range
|
|||
|
// structure.
|
|||
|
//
|
|||
|
|
|||
|
VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES],
|
|||
|
VLDefDACRegRange,
|
|||
|
HwDeviceExtension->Dac.cDacRegs *
|
|||
|
sizeof(VIDEO_ACCESS_RANGE));
|
|||
|
|
|||
|
//
|
|||
|
// A value for the P9 base address may have beens found in the registry,
|
|||
|
// and it is now stored in the device extension. Ensure the address
|
|||
|
// value is valid for the Viper card. Then use it to compute
|
|||
|
// the starting address of the P9000 registers and frame buffer,
|
|||
|
// and store it in the device extension.
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < NumMemRanges; i++)
|
|||
|
{
|
|||
|
if (HwDeviceExtension->P9PhysAddr.LowPart ==
|
|||
|
ViperMemRange[i].BaseMemAddr.LowPart)
|
|||
|
{
|
|||
|
bValid = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the address value is invalid, or was not found in the registry,
|
|||
|
// use the default.
|
|||
|
//
|
|||
|
|
|||
|
if (!bValid)
|
|||
|
{
|
|||
|
HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
|
|||
|
}
|
|||
|
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ViperEnableP9(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Perform the OEM specific tasks necessary to enable the P9000. These
|
|||
|
include memory mapping, setting the sync polarities, and enabling the
|
|||
|
P9000 video output.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
USHORT holdit;
|
|||
|
|
|||
|
//
|
|||
|
// Select external frequency.
|
|||
|
//
|
|||
|
|
|||
|
VGA_WR_REG(MISCOUT, VGA_RD_REG(MISCIN) | (MISCD | MISCC));
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, unlock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
UnlockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
|
|||
|
holdit = VGA_RD_REG(SEQ_DATA_PORT);
|
|||
|
|
|||
|
//
|
|||
|
// Set the sync polarity. First clear the sync polarity bits.
|
|||
|
//
|
|||
|
|
|||
|
holdit &= ~POL_MASK;
|
|||
|
|
|||
|
//
|
|||
|
// Viper controls h and v sync polarities independently. Set the
|
|||
|
// vertical sync polarity.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->VideoData.vp == POSITIVE)
|
|||
|
{
|
|||
|
holdit |= VSYNC_POL_MASK;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Disable VGA video output.
|
|||
|
//
|
|||
|
|
|||
|
holdit &= VGA_VIDEO_DIS;
|
|||
|
|
|||
|
if (HwDeviceExtension->VideoData.hp == POSITIVE)
|
|||
|
{
|
|||
|
holdit |= HSYNC_POL_MASK;
|
|||
|
}
|
|||
|
|
|||
|
holdit |= P9_VIDEO_ENB;
|
|||
|
VGA_WR_REG(SEQ_DATA_PORT, holdit);
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, lock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
LockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ViperDisableP9(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
pPal - Pointer to the array of pallete entries.
|
|||
|
StartIndex - Specifies the first pallete entry provided in pPal.
|
|||
|
Count - Number of palette entries in pPal
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE, indicating *no* int10 is needed to complete the switch
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
USHORT holdit;
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, unlock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
UnlockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
|
|||
|
holdit = VGA_RD_REG(SEQ_DATA_PORT);
|
|||
|
|
|||
|
//
|
|||
|
// Disable P9000 video output.
|
|||
|
//
|
|||
|
|
|||
|
holdit &= P9_VIDEO_DIS;
|
|||
|
|
|||
|
//
|
|||
|
// VGA output enable is a seperate register bit for the Viper board.
|
|||
|
//
|
|||
|
|
|||
|
holdit |= VGA_VIDEO_ENB;
|
|||
|
|
|||
|
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
|
|||
|
VGA_WR_REG(SEQ_DATA_PORT, holdit);
|
|||
|
|
|||
|
//
|
|||
|
// Restore clock select bits.
|
|||
|
//
|
|||
|
|
|||
|
VGA_WR_REG(MISCOUT, HwDeviceExtension->MiscRegState);
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, lock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
LockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
ViperEnableMem(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Enables the P9000 memory at the physical base address stored in the
|
|||
|
device extension.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
USHORT holdit;
|
|||
|
SHORT i;
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, unlock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
UnlockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read the contents of the sequencer memory address register.
|
|||
|
//
|
|||
|
|
|||
|
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
|
|||
|
holdit = VGA_RD_REG(SEQ_DATA_PORT);
|
|||
|
|
|||
|
//
|
|||
|
// Clear out any address bits which are set.
|
|||
|
//
|
|||
|
|
|||
|
holdit &= ADDR_SLCT_MASK;
|
|||
|
|
|||
|
//
|
|||
|
// Map the P9000 to the address specified in the device extension.
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < NumMemRanges; i++ )
|
|||
|
{
|
|||
|
if (ViperMemRange[i].BaseMemAddr.LowPart ==
|
|||
|
HwDeviceExtension->P9PhysAddr.LowPart)
|
|||
|
{
|
|||
|
holdit |= ViperMemRange[i].RegValue;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VGA_WR_REG(SEQ_DATA_PORT, holdit);
|
|||
|
|
|||
|
//
|
|||
|
// If this is a Weitek VGA, lock it.
|
|||
|
//
|
|||
|
|
|||
|
if (HwDeviceExtension->AdapterDesc.bWtk5x86)
|
|||
|
{
|
|||
|
LockVGARegs(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
return(TRUE);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ViperSetMode(
|
|||
|
PHW_DEVICE_EXTENSION HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine sets the video mode. Different OEM adapter implementations
|
|||
|
require that initialization operations be performed in a certain
|
|||
|
order. This routine uses the standard order which addresses most
|
|||
|
implementations (Viper VL and VIPER PCI).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Save the value in the VGA's Misc Output register.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->MiscRegState = VGA_RD_REG(MISCIN);
|
|||
|
|
|||
|
//
|
|||
|
// Enable the Vipers Memory Map.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->AdapterDesc.P9EnableMem(HwDeviceExtension);
|
|||
|
|
|||
|
//
|
|||
|
// Enable P9000 video.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the DAC.
|
|||
|
//
|
|||
|
|
|||
|
HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set the dot clock.
|
|||
|
//
|
|||
|
|
|||
|
DevSetClock(HwDeviceExtension,
|
|||
|
(USHORT) HwDeviceExtension->VideoData.dotfreq1,
|
|||
|
FALSE,
|
|||
|
TRUE);
|
|||
|
|
|||
|
//
|
|||
|
// If this mode uses the palette, clear it to all 0s.
|
|||
|
//
|
|||
|
|
|||
|
if (P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.AttributeFlags
|
|||
|
&& VIDEO_MODE_PALETTE_DRIVEN)
|
|||
|
{
|
|||
|
HwDeviceExtension->Dac.DACClearPalette(HwDeviceExtension);
|
|||
|
}
|
|||
|
|
|||
|
}
|