|
|
/*****************************************************************************
* name: PCI acces module * * description: Acces the PCI functions in the BIOS * * designed: Christian Toutant, august 26, 1993 * last modified: * * version: $Id: * * function in modul: * ******************************************************************************/
#include "switches.h"
#ifdef WINDOWS_NT
#include "dderror.h"
#include <string.h>
#endif /* #ifdef WINDOWS_NT */
#include "bind.h"
#include "defbind.h"
#include "def.h"
#include "mga.h"
#include "mgai_c.h"
#include "mgai.h"
#include "mtxpci.h"
/* GLOBAL */ word pciBoardInfo = 0;
/* Prototypes */
#ifdef WINDOWS_NT
//HACK!!!
typedef struct _MULTI_MODE { ULONG MulModeNumber; // unique mode Id
ULONG MulWidth; // total width of mode
ULONG MulHeight; // total height of mode
ULONG MulPixWidth; // pixel depth of mode
ULONG MulRefreshRate; // refresh rate of mode
USHORT MulArrayWidth; // number of boards arrayed along X
USHORT MulArrayHeight; // number of boards arrayed along Y
UCHAR MulBoardNb[NB_BOARD_MAX]; // board numbers of required boards
USHORT MulBoardMode[NB_BOARD_MAX]; // mode required from each board
HwModeData *MulHwModes[NB_BOARD_MAX]; // pointers to required HwModeData
} MULTI_MODE, *PMULTI_MODE;
/*--------------------------------------------------------------------------*\
| HW_DEVICE_EXTENSION | | Define device extension structure. This is device dependant/private | information. | \*--------------------------------------------------------------------------*/ typedef struct _MGA_DEVICE_EXTENSION { ULONG SuperModeNumber; // Current mode number
ULONG NumberOfSuperModes; // Total number of modes
PMULTI_MODE pSuperModes; // Array of super-modes structures
// For each board:
ULONG NumberOfModes[NB_BOARD_MAX]; // Number of available modes
ULONG NumberOfValidModes[NB_BOARD_MAX]; // Number of valid modes
ULONG ModeFlags2D[NB_BOARD_MAX]; // 2D modes supported by each board
ULONG ModeFlags3D[NB_BOARD_MAX]; // 3D modes supported by each board
USHORT ModeFreqs[NB_BOARD_MAX][64]; // Refresh rates bit fields
UCHAR ModeList[NB_BOARD_MAX][64]; // Valid hardware modes list
HwModeData *pMgaHwModes[NB_BOARD_MAX]; // Array of mode information structs.
BOOLEAN bUsingInt10; // May need this later
PVOID KernelModeMappedBaseAddress[NB_BOARD_MAX]; // Kern-mode virt addr base of MGA regs
PVOID UserModeMappedBaseAddress[NB_BOARD_MAX]; // User-mode virt addr base of MGA regs
PVOID MappedAddress[]; // NUM_MGA_COMMON_ACCESS_RANGES elements
} MGA_DEVICE_EXTENSION, *PMGA_DEVICE_EXTENSION;
void initConfigAddress( void ); int nextDevice( void ); dword getConfigData( int reg ); void setConfigData( int reg, dword donnee); dword pciFindFirstMGA_1(); dword pciFindNextMGA_1(); void setAthenaRevision_1(void); PUCHAR pciBiosCallAddr();
extern byte NbBoard; extern HwData Hw[];
#endif /* #ifdef WINDOWS_NT */
bool pciBiosCall( union _REGS *r ); bool pciBiosPresent( PciBiosInfo *info); dword pciFindFirstMGA(); dword pciFindNextMGA(); void setPciOptionReg(); void disPostedWFeature(); dword pciFindFirstMGA_2(); dword pciFindNextMGA_2();
#ifdef WINDOWS_NT
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,initConfigAddress)
#pragma alloc_text(PAGE,getConfigData)
#pragma alloc_text(PAGE,setConfigData)
#pragma alloc_text(PAGE,pciFindFirstMGA_1)
#pragma alloc_text(PAGE,pciFindNextMGA_1)
#pragma alloc_text(PAGE,pciBiosCall)
#pragma alloc_text(PAGE,pciBiosPresent)
#pragma alloc_text(PAGE,setAthenaRevision_1)
#pragma alloc_text(PAGE,pciFindFirstMGA)
#pragma alloc_text(PAGE,pciFindNextMGA)
#pragma alloc_text(PAGE,pciBiosCallAddr)
#pragma alloc_text(PAGE,setPciOptionReg)
#pragma alloc_text(PAGE,disPostedWFeature)
#pragma alloc_text(PAGE,pciFindFirstMGA_2)
#pragma alloc_text(PAGE,pciFindNextMGA_2)
#endif
#endif /* #ifdef WINDOWS_NT */
#if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES))
/* The only part of this file required for Alpha under WinNT3.5 is setPciOptionReg */
word errorCode = 0; static word currentMgaIndexATL = 0; currentMgaIndexATH = 0; word configSpace = 0xffff;
/* Extern parameter */ extern dword MgaSel; extern dword getmgasel(void);
#ifndef WINDOWS_NT
#else
extern PUCHAR pMgaBaseAddr; extern PUCHAR setmgasel(dword MgaSel, dword phyadr, dword limit); #endif
#ifdef WINDOWS_NT
#define SET_EAX(r,d) (r).e.reax = d
#define SET_EBX(r,d) (r).e.rebx = d
#define SET_ECX(r,d) (r).e.recx = d
#define SET_EDX(r,d) (r).e.redx = d
#define SET_AX(r,d) (r).x.ax = d
#define SET_BX(r,d) (r).x.bx = d
#define SET_CX(r,d) (r).x.cx = d
#define SET_DX(r,d) (r).x.dx = d
#define SET_SI(r,d) (r).x.si = d
#define SET_DI(r,d) (r).x.di = d
#define GET_EAX(r) ((r).e.reax)
#define GET_EBX(r) ((r).e.rebx)
#define GET_ECX(r) ((r).e.recx)
#define GET_EDX(r) ((r).e.redx)
#define GET_ESI(r) ((r).e.resi)
#define GET_EDI(r) ((r).e.redi)
#define GET_AX(r) ((r).x.ax)
#define GET_BX(r) ((r).x.bx)
#define GET_CX(r) ((r).x.cx)
#define GET_DX(r) ((r).x.dx)
#define GET_SI(r) ((r).x.si)
#define GET_DI(r) ((r).x.di)
VOID (*pciBiosRoutine)();
#define inp _inp
#define outp _outp
#define CONFIG_SPACE 0x0000c000
extern PUCHAR pMgaPciIo, pMgaPciConfigSpace; extern PVOID pMgaDeviceExtension; extern VIDEO_ACCESS_RANGE MgaPciConfigAccessRange, MgaPciCseAccessRange;
#define TITAN_PEL_ADDR_RD (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c7 - 0x3c0))
#define TITAN_PEL_ADDR_WR (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c8 - 0x3c0))
#define TITAN_PEL_DATA (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c9 - 0x3c0))
// Mechanism 1 is used this way only for Windows NT.
/* Mechanism #1 interface */
#define CONFIG_ADDRESS 0xcf8
#define CONFIG_DATA 0xcfc
#define BUS_NUMBER_M 0x00ff0000h
#define DEV_NUMBER_M 0x0000f800h
#define BUS_NUMBER_A 16
#define DEV_NUMBER_A 11
#define REG_NUMBER_M 0xfc
#define MAGIG_ATLAS_NUMBER 0x0518102b
#define MAGIG_ATHENA_NUMBER 0x0D10102b
static dword currentBUS = 0; static dword currentDEV = 0;
/*-------- Mechanism #1 */
void initConfigAddress() { dword adresse;
currentDEV = (dword)-1; currentBUS = 0; adresse = 0x80000000; outdw(CONFIG_ADDRESS, adresse); }
int nextDevice( void ) { int trouve = 0; dword magicID; currentDEV++; while ( !trouve && (currentBUS < 256) ) { while ( !trouve && (currentDEV < 32 ) ) { magicID = getConfigData( 0 ); trouve = ( magicID == MAGIG_ATLAS_NUMBER) || ( magicID == MAGIG_ATHENA_NUMBER);
if (trouve)return -1; currentDEV++; } currentDEV = 0; currentBUS++; }
return trouve; }
dword getConfigData( int reg ) { dword retVal, adresse; adresse = 0x80000000 | (currentBUS << BUS_NUMBER_A) | (currentDEV << DEV_NUMBER_A);
adresse |= reg & REG_NUMBER_M; outdw(CONFIG_ADDRESS, adresse); retVal = indw(CONFIG_DATA); outdw(CONFIG_ADDRESS, 0);
return retVal; }
void setConfigData( int reg, dword donnee) {
dword adresse; adresse = 0x80000000 | (currentBUS << BUS_NUMBER_A) | (currentDEV << DEV_NUMBER_A);
adresse |= reg & REG_NUMBER_M; outdw(CONFIG_ADDRESS, adresse); outdw(CONFIG_DATA, donnee); outdw(CONFIG_ADDRESS, 0); }
/*----------------------------------------------------------------------------
| name: setAthenaRevision_1 | | description: test acces to DAC in vgamode with snopping enabled | if snooping not supporting, set pciBoardInfo to | PCI_FLAG_ATHENA_REV1 | | designed: Christian Toutant, octobre 14, 1994 | last modified: | | | parameters: PciDevice *dev | byte command | | modifies: pciBoardInfo | calls: pciReadConfigByte, pciWriteConfigByte | returns: | -----------------------------------------------------------------------------*/ void setAthenaRevision_1() { dword command; dword classe; dword baseAddress; byte btmp;
command = getConfigData( 0x4 ); classe = getConfigData( 0x8 ); baseAddress = getConfigData( 0x10 );
if ( !(classe & 0x00800000) && !(command & (dword)3) ) { command |= (dword)2; setConfigData( 0x4, command); if ((pMgaBaseAddr = setmgasel(MgaSel, baseAddress, 4)) != NULL) { mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),btmp); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),btmp & ~(byte)4); VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr); } }
if ( !(classe & 0x00800000) && !(command & (dword)PCI_SNOOPING) ) { /* assume athena rev > 1 */ pciBoardInfo &= ~(word)PCI_FLAG_ATHENA_REV1;
/* init location 64 at 0 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */
/* empty fifo */ VideoPortReadPortUchar(TITAN_PEL_ADDR_RD);
/* active snooping */ setConfigData( 0x4, command | (dword)PCI_SNOOPING);
/* write to DAC in snooping mode */ VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x11); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x22); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x33);
/* restore snooping */ setConfigData( 0x4, command );
/* now if the acces fail, we assume athena rev 1 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_RD, (UCHAR)64); /* init read addr to loc 64 */ if ( (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x11) || (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x22) || (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x33) ) pciBoardInfo |= PCI_FLAG_ATHENA_REV1;
/* init location 64 at 0 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */ } }
/*----------------------------------------------------------------------------
| name: pciFindFirstMGA_1 | | description: Find the first MGA device in the system and return the base | address of the device in the system (a succesive call to the | function pciFindNextMGA give the address of other mga device | in the system). Use harware mechanisme #1. | | designed: Christian Toutant, march 26, 1994 | last modified: | | | parameters: none | modifies: static variable currentIndex set to 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindFirstMGA_1() { initConfigAddress(); return pciFindNextMGA_1(); }
/*----------------------------------------------------------------------------
| name: pciFindNextMGA_1 | | description: Find the next MGA device in the system and return the base | address of the device the function pciFindFirstMGA must me call | before call to this function. Use harware mechanisme #1. | | | designed: Christian Toutant, march 26, 1994 | last modified: | | | parameters: none | modifies: static variable currentIndex is incremented by 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindNextMGA_1() {
dword address = 0;
if ( nextDevice() ) { setAthenaRevision_1(); address = getConfigData( 0x10 ); } else address = (dword)-1;
return address; }
#endif /* #ifdef WINDOWS_NT */
/*----------------------------------------------------------------------------
| name: pciBiosCall | | description: call PCI BIOS function. The parameters is passed by register. | reel mode | 16 bit protected mode: The call is make via int 1aH | | | 32 protected mode: The protected mode PCI BIOS is accessed by | calling through a protected mode entry point | in the PCI BIOS. The entry point and information | needed for building segment descriptors are provided | by teh BIOS32 Service Directory. | see PCI BIOS SPECIFICATION rev 2.0 section 3.3. | | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: union _REGS *r_in register need for the PCI Bus Specific Operation | (AH must forced PCI_FUNCTION_ID (B1h)) | | modifies: *r_out is modified to reflect the register state after the BIOS Call. | calls: int 1ah | | returns: bool | mtxOK int 1ah succes | mtxFAIL int 1ah failed (see register for more information) | | note1: This implementation is compiler dependant, a different way for | genarate interrupt may be use. | | note2: For now, we use the reel mode int 1ah. | The entry point and structure initialisation needed for use | the BIOS32 Service Directory we be implemented with the function | pciBiosPresent. | ref. PCI BIOS SPECIFICATION rev 2.0 section 3.3. -----------------------------------------------------------------------------*/ bool pciBiosCall( union _REGS *r ) { #ifdef WINDOWS_NT
return mtxFAIL; #endif /* #ifdef WINDOWS_NT */
}
/*----------------------------------------------------------------------------
| name: pciBiosPresent | | description: Check if the PCI BIOS is present in the system. This function | must be call before any call to PCI BIOS function. | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: PciBiosInfo *info information about the bios | modifies: *info updated to bios found information | calls: | returns: bool | mtxOK PCI bios found | mtxFAIL otherwise | | note: if the BIOS32 Service Directory is implemented, this function | must find the entry point and initialise all structure needed | for call to BIOS function. | ref. PCI BIOS SPECIFICATION rev 2.0 section 3.3. -----------------------------------------------------------------------------*/ bool pciBiosPresent( PciBiosInfo *info) {
#ifdef WINDOWS_NT
// We're not using this for now.
return mtxFAIL; #endif /* #ifdef WINDOWS_NT */
}
/*----------------------------------------------------------------------------
| name: pciFindFirstMGA | | description: Find the first MGA device in the system and return the base | address of the device in the system (a succesive call to the | function pciFindNextMGA give the address of other mga device | in the system). | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: none | modifies: global variable MgaSel and pMgaBaseAddress | static variable currentIndex set to 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindFirstMGA() {
#ifdef WINDOWS_NT
return (dword)-1; #endif /* #ifdef WINDOWS_NT */
}
/*----------------------------------------------------------------------------
| name: pciFindNextMGA | | description: Find the next MGA device in the system and return the base | address of the device the function pciFindFirstMGA must me call | before call to this function. This function search a mga device | a currentIndex and increment the current index by 1. A call to | pciFindFirstMGA set the currentIndex to 1. | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: none | modifies: global variable MgaSel and pMgaBaseAddress | static variable currentIndex is incremented by 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindNextMGA() { #ifdef WINDOWS_NT
return (dword)-1; #endif /* #ifdef WINDOWS_NT */
}
#ifdef WINDOWS_NT
PUCHAR pciBiosCallAddr() { return((PUCHAR)NULL); }
#endif /* #ifdef WINDOWS_NT */
#endif /* #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES)) */
#if (USE_VP_GET_ACCESS_RANGES)
extern PVOID pMgaDeviceExtension; extern ULONG PciSlot; #endif
#if 0
/*----------------------------------------------------------------------------
| name: setPciOptionReg | | description: set the option register of all mga to 1 | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: none | modifies: | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: void | -----------------------------------------------------------------------------*/ void setPciOptionReg() { #if (USE_VP_GET_ACCESS_RANGES)
UCHAR ConfigBuf = 0x01; ULONG ConfigOffset = 0x40; ULONG ConfigLength = 0x01;
VideoPortSetBusData(pMgaDeviceExtension, //PVOID HwDeviceExtension,
PCIConfiguration, //IN BUS_DATA_TYPE BusDataType,
PciSlot, //IN ULONG SlotNumber,
&ConfigBuf, //IN PVOID Buffer,
ConfigOffset, //IN ULONG Offset,
ConfigLength); //IN ULONG Length
#else /* #if (USE_VP_GET_ACCESS_RANGES) */
byte i;
// Use mechanism #1 also!!!
// Get access to ports before trying to map I/O configuration space.
if ((pMgaPciIo = VideoPortGetDeviceBase(pMgaDeviceExtension, MgaPciCseAccessRange.RangeStart, MgaPciCseAccessRange.RangeLength, MgaPciCseAccessRange.RangeInIoSpace)) != NULL) { // Map I/O Configuration Space.
outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x80); outp(pMgaPciIo+PCI_FORWARD-PCI_CSE, 0x00);
for (i = 0; i < NbBoard; i++) { if (Hw[i].ConfigSpace != 0) { MgaPciConfigAccessRange.RangeStart.LowPart = (ULONG)Hw[i].ConfigSpace; if ((pMgaPciConfigSpace = VideoPortGetDeviceBase(pMgaDeviceExtension, MgaPciConfigAccessRange.RangeStart, MgaPciConfigAccessRange.RangeLength, MgaPciConfigAccessRange.RangeInIoSpace)) != NULL) { outp(pMgaPciConfigSpace + 0x40, 0x01); VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciConfigSpace); } } outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00); VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciIo); }
#endif /* #if (USE_VP_GET_ACCESS_RANGES) */
}
#endif //#if 0
#if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES))
/*----------------------------------------------------------------------------
| name: pciFindFirstMGA_2 | | description: Find the first MGA device in the system and return the base | address of the device in the system (a succesive call to the | function pciFindNextMGA give the address of other mga device | in the system). | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: none | modifies: global variable MgaSel and pMgaBaseAddress | static variable currentIndex set to 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindFirstMGA_2() { dword address;
configSpace = 0x0000; address = pciFindFirstMGA_1(); if (address == (dword)-1 ) { configSpace = 0xc000; return pciFindNextMGA_2(); } else { return address; } }
/*----------------------------------------------------------------------------
| name: pciFindNextMGA_2 | | description: Find the next MGA device in the system and return the base | address of the device the function pciFindFirstMGA must me call | before call to this function. This function search a mga device | a currentIndex and increment the current index by 1. A call to | pciFindFirstMGA set the currentIndex to 1. | | designed: Christian Toutant, august 26, 1993 | last modified: | | | parameters: none | modifies: global variable MgaSel and pMgaBaseAddress | static variable currentIndex is incremented by 1. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord | returns: dword base address of the first mga found. | -1 if no mga found (or no PCI BIOS found). | -----------------------------------------------------------------------------*/ dword pciFindNextMGA_2() { byte command, subClass; dword address = 0;
/* Map I/O Configuration Space */ address = pciFindNextMGA_1(); if (address != (dword)-1 ) return address;
// Restore this before going on, or you'll be sorry!
address = 0; outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x80);
while (!address) { if (configSpace > 0xcf00) { address = (dword)-1; outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00); } else { // Get access to the current I/O space.
MgaPciConfigAccessRange.RangeStart.LowPart = (ULONG)configSpace; if (VideoPortVerifyAccessRanges(pMgaDeviceExtension, 1, &MgaPciConfigAccessRange) == NO_ERROR && (pMgaPciConfigSpace = VideoPortGetDeviceBase(pMgaDeviceExtension, MgaPciConfigAccessRange.RangeStart, MgaPciConfigAccessRange.RangeLength, MgaPciConfigAccessRange.RangeInIoSpace)) != NULL) { if (( (inp(pMgaPciConfigSpace ) == 0x2b) && (inp(pMgaPciConfigSpace + 1) == 0x10) && (inp(pMgaPciConfigSpace + 2) == 0x18) && (inp(pMgaPciConfigSpace + 3) == 0x05) ) || ( (inp(pMgaPciConfigSpace ) == 0x2b) && (inp(pMgaPciConfigSpace + 1) == 0x10) && (inp(pMgaPciConfigSpace + 2) == 0x10) && (inp(pMgaPciConfigSpace + 3) == 0x0D) ) ) { address = (dword)inp(pMgaPciConfigSpace + 0x13) << 24; address |= (dword)inp(pMgaPciConfigSpace + 0x12) << 16; address |= (dword)inp(pMgaPciConfigSpace + 0x11) << 8; address |= (dword)(inp(pMgaPciConfigSpace + 0x10) & 0x0c); command = inp(pMgaPciConfigSpace + PCI_COMMAND); subClass = inp(pMgaPciConfigSpace + PCI_CLASS_CODE + 1);
/*--- Detect ATHENA revision < 2
If MGA board is in VGA mode and the snooping test fail, set ATHENA rev 1 flag ---*/ /* Test if we are in vga mode & snooping disabled*/ if ( !subClass && !(command & PCI_SNOOPING) ) { /* assume athena rev > 1 */ pciBoardInfo &= ~(word)PCI_FLAG_ATHENA_REV1;
/* init location 64 at 0 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
/* empty fifo */ VideoPortReadPortUchar(TITAN_PEL_ADDR_RD);
/* active snooping */ outp(pMgaPciConfigSpace + PCI_COMMAND, (byte)(command | PCI_SNOOPING));
/* write to DAC in snooping mode */ VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x11); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x22); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x33);
/* restore snooping */ outp(pMgaPciConfigSpace + PCI_COMMAND, (byte)command);
/* now if the acces fail, we assume athena rev 1 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_RD, (UCHAR)64); if ( (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x11) || (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x22) || (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x33) ) pciBoardInfo |= PCI_FLAG_ATHENA_REV1;
/* init location 64 at 0 */ VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00); VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */ }
/*---- END Detect ATHENA revision < 2 */
/* If MGA board is in VGA mode and the MEM/IO space is not
enabled, enable it. */ if (!subClass && !(command & 0x03)) { outp(pMgaPciConfigSpace + PCI_COMMAND, (byte)(command | 2)); if ((pMgaBaseAddr = setmgasel(MgaSel, address, 4)) != NULL) { mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1), command); mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1), command & ~(byte)4); VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaBaseAddr); } } } VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciConfigSpace); } } configSpace += 0x100; } outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00);
return address; }
#endif /* #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES)) */
|