Source code of Windows XP (NT5)
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.

832 lines
29 KiB

  1. /*****************************************************************************
  2. * name: PCI acces module
  3. *
  4. * description: Acces the PCI functions in the BIOS
  5. *
  6. * designed: Christian Toutant, august 26, 1993
  7. * last modified:
  8. *
  9. * version: $Id:
  10. *
  11. * function in modul:
  12. *
  13. ******************************************************************************/
  14. #include "switches.h"
  15. #ifdef WINDOWS_NT
  16. #include "dderror.h"
  17. #include <string.h>
  18. #endif /* #ifdef WINDOWS_NT */
  19. #include "bind.h"
  20. #include "defbind.h"
  21. #include "def.h"
  22. #include "mga.h"
  23. #include "mgai_c.h"
  24. #include "mgai.h"
  25. #include "mtxpci.h"
  26. /* GLOBAL */
  27. word pciBoardInfo = 0;
  28. /* Prototypes */
  29. #ifdef WINDOWS_NT
  30. //HACK!!!
  31. typedef struct _MULTI_MODE
  32. {
  33. ULONG MulModeNumber; // unique mode Id
  34. ULONG MulWidth; // total width of mode
  35. ULONG MulHeight; // total height of mode
  36. ULONG MulPixWidth; // pixel depth of mode
  37. ULONG MulRefreshRate; // refresh rate of mode
  38. USHORT MulArrayWidth; // number of boards arrayed along X
  39. USHORT MulArrayHeight; // number of boards arrayed along Y
  40. UCHAR MulBoardNb[NB_BOARD_MAX]; // board numbers of required boards
  41. USHORT MulBoardMode[NB_BOARD_MAX]; // mode required from each board
  42. HwModeData *MulHwModes[NB_BOARD_MAX]; // pointers to required HwModeData
  43. } MULTI_MODE, *PMULTI_MODE;
  44. /*--------------------------------------------------------------------------*\
  45. | HW_DEVICE_EXTENSION
  46. |
  47. | Define device extension structure. This is device dependant/private
  48. | information.
  49. |
  50. \*--------------------------------------------------------------------------*/
  51. typedef struct _MGA_DEVICE_EXTENSION {
  52. ULONG SuperModeNumber; // Current mode number
  53. ULONG NumberOfSuperModes; // Total number of modes
  54. PMULTI_MODE pSuperModes; // Array of super-modes structures
  55. // For each board:
  56. ULONG NumberOfModes[NB_BOARD_MAX]; // Number of available modes
  57. ULONG NumberOfValidModes[NB_BOARD_MAX];
  58. // Number of valid modes
  59. ULONG ModeFlags2D[NB_BOARD_MAX]; // 2D modes supported by each board
  60. ULONG ModeFlags3D[NB_BOARD_MAX]; // 3D modes supported by each board
  61. USHORT ModeFreqs[NB_BOARD_MAX][64]; // Refresh rates bit fields
  62. UCHAR ModeList[NB_BOARD_MAX][64]; // Valid hardware modes list
  63. HwModeData *pMgaHwModes[NB_BOARD_MAX]; // Array of mode information structs.
  64. BOOLEAN bUsingInt10; // May need this later
  65. PVOID KernelModeMappedBaseAddress[NB_BOARD_MAX];
  66. // Kern-mode virt addr base of MGA regs
  67. PVOID UserModeMappedBaseAddress[NB_BOARD_MAX];
  68. // User-mode virt addr base of MGA regs
  69. PVOID MappedAddress[]; // NUM_MGA_COMMON_ACCESS_RANGES elements
  70. } MGA_DEVICE_EXTENSION, *PMGA_DEVICE_EXTENSION;
  71. void initConfigAddress( void );
  72. int nextDevice( void );
  73. dword getConfigData( int reg );
  74. void setConfigData( int reg, dword donnee);
  75. dword pciFindFirstMGA_1();
  76. dword pciFindNextMGA_1();
  77. void setAthenaRevision_1(void);
  78. PUCHAR pciBiosCallAddr();
  79. extern byte NbBoard;
  80. extern HwData Hw[];
  81. #endif /* #ifdef WINDOWS_NT */
  82. bool pciBiosCall( union _REGS *r );
  83. bool pciBiosPresent( PciBiosInfo *info);
  84. dword pciFindFirstMGA();
  85. dword pciFindNextMGA();
  86. void setPciOptionReg();
  87. void disPostedWFeature();
  88. dword pciFindFirstMGA_2();
  89. dword pciFindNextMGA_2();
  90. #ifdef WINDOWS_NT
  91. #if defined(ALLOC_PRAGMA)
  92. #pragma alloc_text(PAGE,initConfigAddress)
  93. #pragma alloc_text(PAGE,getConfigData)
  94. #pragma alloc_text(PAGE,setConfigData)
  95. #pragma alloc_text(PAGE,pciFindFirstMGA_1)
  96. #pragma alloc_text(PAGE,pciFindNextMGA_1)
  97. #pragma alloc_text(PAGE,pciBiosCall)
  98. #pragma alloc_text(PAGE,pciBiosPresent)
  99. #pragma alloc_text(PAGE,setAthenaRevision_1)
  100. #pragma alloc_text(PAGE,pciFindFirstMGA)
  101. #pragma alloc_text(PAGE,pciFindNextMGA)
  102. #pragma alloc_text(PAGE,pciBiosCallAddr)
  103. #pragma alloc_text(PAGE,setPciOptionReg)
  104. #pragma alloc_text(PAGE,disPostedWFeature)
  105. #pragma alloc_text(PAGE,pciFindFirstMGA_2)
  106. #pragma alloc_text(PAGE,pciFindNextMGA_2)
  107. #endif
  108. #endif /* #ifdef WINDOWS_NT */
  109. #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES))
  110. /* The only part of this file required for Alpha under WinNT3.5 is setPciOptionReg */
  111. word errorCode = 0;
  112. static word
  113. currentMgaIndexATL = 0;
  114. currentMgaIndexATH = 0;
  115. word configSpace = 0xffff;
  116. /* Extern parameter */
  117. extern dword MgaSel;
  118. extern dword getmgasel(void);
  119. #ifndef WINDOWS_NT
  120. #else
  121. extern PUCHAR pMgaBaseAddr;
  122. extern PUCHAR setmgasel(dword MgaSel, dword phyadr, dword limit);
  123. #endif
  124. #ifdef WINDOWS_NT
  125. #define SET_EAX(r,d) (r).e.reax = d
  126. #define SET_EBX(r,d) (r).e.rebx = d
  127. #define SET_ECX(r,d) (r).e.recx = d
  128. #define SET_EDX(r,d) (r).e.redx = d
  129. #define SET_AX(r,d) (r).x.ax = d
  130. #define SET_BX(r,d) (r).x.bx = d
  131. #define SET_CX(r,d) (r).x.cx = d
  132. #define SET_DX(r,d) (r).x.dx = d
  133. #define SET_SI(r,d) (r).x.si = d
  134. #define SET_DI(r,d) (r).x.di = d
  135. #define GET_EAX(r) ((r).e.reax)
  136. #define GET_EBX(r) ((r).e.rebx)
  137. #define GET_ECX(r) ((r).e.recx)
  138. #define GET_EDX(r) ((r).e.redx)
  139. #define GET_ESI(r) ((r).e.resi)
  140. #define GET_EDI(r) ((r).e.redi)
  141. #define GET_AX(r) ((r).x.ax)
  142. #define GET_BX(r) ((r).x.bx)
  143. #define GET_CX(r) ((r).x.cx)
  144. #define GET_DX(r) ((r).x.dx)
  145. #define GET_SI(r) ((r).x.si)
  146. #define GET_DI(r) ((r).x.di)
  147. VOID (*pciBiosRoutine)();
  148. #define inp _inp
  149. #define outp _outp
  150. #define CONFIG_SPACE 0x0000c000
  151. extern PUCHAR pMgaPciIo, pMgaPciConfigSpace;
  152. extern PVOID pMgaDeviceExtension;
  153. extern VIDEO_ACCESS_RANGE MgaPciConfigAccessRange, MgaPciCseAccessRange;
  154. #define TITAN_PEL_ADDR_RD (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c7 - 0x3c0))
  155. #define TITAN_PEL_ADDR_WR (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c8 - 0x3c0))
  156. #define TITAN_PEL_DATA (PVOID) ((ULONG)(((PMGA_DEVICE_EXTENSION)pMgaDeviceExtension)->MappedAddress[3]) + (0x3c9 - 0x3c0))
  157. // Mechanism 1 is used this way only for Windows NT.
  158. /* Mechanism #1 interface */
  159. #define CONFIG_ADDRESS 0xcf8
  160. #define CONFIG_DATA 0xcfc
  161. #define BUS_NUMBER_M 0x00ff0000h
  162. #define DEV_NUMBER_M 0x0000f800h
  163. #define BUS_NUMBER_A 16
  164. #define DEV_NUMBER_A 11
  165. #define REG_NUMBER_M 0xfc
  166. #define MAGIG_ATLAS_NUMBER 0x0518102b
  167. #define MAGIG_ATHENA_NUMBER 0x0D10102b
  168. static dword currentBUS = 0;
  169. static dword currentDEV = 0;
  170. /*-------- Mechanism #1 */
  171. void initConfigAddress()
  172. {
  173. dword adresse;
  174. currentDEV = (dword)-1;
  175. currentBUS = 0;
  176. adresse = 0x80000000;
  177. outdw(CONFIG_ADDRESS, adresse);
  178. }
  179. int nextDevice( void )
  180. {
  181. int trouve = 0;
  182. dword magicID;
  183. currentDEV++;
  184. while ( !trouve && (currentBUS < 256) )
  185. {
  186. while ( !trouve && (currentDEV < 32 ) )
  187. {
  188. magicID = getConfigData( 0 );
  189. trouve = ( magicID == MAGIG_ATLAS_NUMBER) ||
  190. ( magicID == MAGIG_ATHENA_NUMBER);
  191. if (trouve)return -1;
  192. currentDEV++;
  193. }
  194. currentDEV = 0;
  195. currentBUS++;
  196. }
  197. return trouve;
  198. }
  199. dword getConfigData( int reg )
  200. {
  201. dword retVal, adresse;
  202. adresse = 0x80000000 | (currentBUS << BUS_NUMBER_A)
  203. | (currentDEV << DEV_NUMBER_A);
  204. adresse |= reg & REG_NUMBER_M;
  205. outdw(CONFIG_ADDRESS, adresse);
  206. retVal = indw(CONFIG_DATA);
  207. outdw(CONFIG_ADDRESS, 0);
  208. return retVal;
  209. }
  210. void setConfigData( int reg, dword donnee)
  211. {
  212. dword adresse;
  213. adresse = 0x80000000 | (currentBUS << BUS_NUMBER_A)
  214. | (currentDEV << DEV_NUMBER_A);
  215. adresse |= reg & REG_NUMBER_M;
  216. outdw(CONFIG_ADDRESS, adresse);
  217. outdw(CONFIG_DATA, donnee);
  218. outdw(CONFIG_ADDRESS, 0);
  219. }
  220. /*----------------------------------------------------------------------------
  221. | name: setAthenaRevision_1
  222. |
  223. | description: test acces to DAC in vgamode with snopping enabled
  224. | if snooping not supporting, set pciBoardInfo to
  225. | PCI_FLAG_ATHENA_REV1
  226. |
  227. | designed: Christian Toutant, octobre 14, 1994
  228. | last modified:
  229. |
  230. |
  231. | parameters: PciDevice *dev
  232. | byte command
  233. |
  234. | modifies: pciBoardInfo
  235. | calls: pciReadConfigByte, pciWriteConfigByte
  236. | returns:
  237. |
  238. -----------------------------------------------------------------------------*/
  239. void setAthenaRevision_1()
  240. {
  241. dword command;
  242. dword classe;
  243. dword baseAddress;
  244. byte btmp;
  245. command = getConfigData( 0x4 );
  246. classe = getConfigData( 0x8 );
  247. baseAddress = getConfigData( 0x10 );
  248. if ( !(classe & 0x00800000) && !(command & (dword)3) )
  249. {
  250. command |= (dword)2;
  251. setConfigData( 0x4, command);
  252. if ((pMgaBaseAddr = setmgasel(MgaSel, baseAddress, 4)) != NULL)
  253. {
  254. mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),btmp);
  255. mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),btmp & ~(byte)4);
  256. VideoPortFreeDeviceBase(pMgaDeviceExtension, pMgaBaseAddr);
  257. }
  258. }
  259. if ( !(classe & 0x00800000) && !(command & (dword)PCI_SNOOPING) )
  260. {
  261. /* assume athena rev > 1 */
  262. pciBoardInfo &= ~(word)PCI_FLAG_ATHENA_REV1;
  263. /* init location 64 at 0 */
  264. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
  265. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  266. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  267. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  268. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */
  269. /* empty fifo */
  270. VideoPortReadPortUchar(TITAN_PEL_ADDR_RD);
  271. /* active snooping */
  272. setConfigData( 0x4, command | (dword)PCI_SNOOPING);
  273. /* write to DAC in snooping mode */
  274. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x11);
  275. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x22);
  276. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x33);
  277. /* restore snooping */
  278. setConfigData( 0x4, command );
  279. /* now if the acces fail, we assume athena rev 1 */
  280. VideoPortWritePortUchar(TITAN_PEL_ADDR_RD, (UCHAR)64); /* init read addr to loc 64 */
  281. if (
  282. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x11) ||
  283. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x22) ||
  284. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x33)
  285. ) pciBoardInfo |= PCI_FLAG_ATHENA_REV1;
  286. /* init location 64 at 0 */
  287. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
  288. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  289. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  290. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  291. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */
  292. }
  293. }
  294. /*----------------------------------------------------------------------------
  295. | name: pciFindFirstMGA_1
  296. |
  297. | description: Find the first MGA device in the system and return the base
  298. | address of the device in the system (a succesive call to the
  299. | function pciFindNextMGA give the address of other mga device
  300. | in the system). Use harware mechanisme #1.
  301. |
  302. | designed: Christian Toutant, march 26, 1994
  303. | last modified:
  304. |
  305. |
  306. | parameters: none
  307. | modifies: static variable currentIndex set to 1.
  308. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  309. | returns: dword base address of the first mga found.
  310. | -1 if no mga found (or no PCI BIOS found).
  311. |
  312. -----------------------------------------------------------------------------*/
  313. dword pciFindFirstMGA_1()
  314. {
  315. initConfigAddress();
  316. return pciFindNextMGA_1();
  317. }
  318. /*----------------------------------------------------------------------------
  319. | name: pciFindNextMGA_1
  320. |
  321. | description: Find the next MGA device in the system and return the base
  322. | address of the device the function pciFindFirstMGA must me call
  323. | before call to this function. Use harware mechanisme #1.
  324. |
  325. |
  326. | designed: Christian Toutant, march 26, 1994
  327. | last modified:
  328. |
  329. |
  330. | parameters: none
  331. | modifies: static variable currentIndex is incremented by 1.
  332. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  333. | returns: dword base address of the first mga found.
  334. | -1 if no mga found (or no PCI BIOS found).
  335. |
  336. -----------------------------------------------------------------------------*/
  337. dword pciFindNextMGA_1()
  338. {
  339. dword address = 0;
  340. if ( nextDevice() )
  341. {
  342. setAthenaRevision_1();
  343. address = getConfigData( 0x10 );
  344. }
  345. else
  346. address = (dword)-1;
  347. return address;
  348. }
  349. #endif /* #ifdef WINDOWS_NT */
  350. /*----------------------------------------------------------------------------
  351. | name: pciBiosCall
  352. |
  353. | description: call PCI BIOS function. The parameters is passed by register.
  354. | reel mode
  355. | 16 bit protected mode: The call is make via int 1aH
  356. |
  357. |
  358. | 32 protected mode: The protected mode PCI BIOS is accessed by
  359. | calling through a protected mode entry point
  360. | in the PCI BIOS. The entry point and information
  361. | needed for building segment descriptors are provided
  362. | by teh BIOS32 Service Directory.
  363. | see PCI BIOS SPECIFICATION rev 2.0 section 3.3.
  364. |
  365. |
  366. | designed: Christian Toutant, august 26, 1993
  367. | last modified:
  368. |
  369. |
  370. | parameters: union _REGS *r_in register need for the PCI Bus Specific Operation
  371. | (AH must forced PCI_FUNCTION_ID (B1h))
  372. |
  373. | modifies: *r_out is modified to reflect the register state after the BIOS Call.
  374. | calls: int 1ah
  375. |
  376. | returns: bool
  377. | mtxOK int 1ah succes
  378. | mtxFAIL int 1ah failed (see register for more information)
  379. |
  380. | note1: This implementation is compiler dependant, a different way for
  381. | genarate interrupt may be use.
  382. |
  383. | note2: For now, we use the reel mode int 1ah.
  384. | The entry point and structure initialisation needed for use
  385. | the BIOS32 Service Directory we be implemented with the function
  386. | pciBiosPresent.
  387. | ref. PCI BIOS SPECIFICATION rev 2.0 section 3.3.
  388. -----------------------------------------------------------------------------*/
  389. bool pciBiosCall( union _REGS *r )
  390. {
  391. #ifdef WINDOWS_NT
  392. return mtxFAIL;
  393. #endif /* #ifdef WINDOWS_NT */
  394. }
  395. /*----------------------------------------------------------------------------
  396. | name: pciBiosPresent
  397. |
  398. | description: Check if the PCI BIOS is present in the system. This function
  399. | must be call before any call to PCI BIOS function.
  400. |
  401. | designed: Christian Toutant, august 26, 1993
  402. | last modified:
  403. |
  404. |
  405. | parameters: PciBiosInfo *info information about the bios
  406. | modifies: *info updated to bios found information
  407. | calls:
  408. | returns: bool
  409. | mtxOK PCI bios found
  410. | mtxFAIL otherwise
  411. |
  412. | note: if the BIOS32 Service Directory is implemented, this function
  413. | must find the entry point and initialise all structure needed
  414. | for call to BIOS function.
  415. | ref. PCI BIOS SPECIFICATION rev 2.0 section 3.3.
  416. -----------------------------------------------------------------------------*/
  417. bool pciBiosPresent( PciBiosInfo *info)
  418. {
  419. #ifdef WINDOWS_NT
  420. // We're not using this for now.
  421. return mtxFAIL;
  422. #endif /* #ifdef WINDOWS_NT */
  423. }
  424. /*----------------------------------------------------------------------------
  425. | name: pciFindFirstMGA
  426. |
  427. | description: Find the first MGA device in the system and return the base
  428. | address of the device in the system (a succesive call to the
  429. | function pciFindNextMGA give the address of other mga device
  430. | in the system).
  431. |
  432. | designed: Christian Toutant, august 26, 1993
  433. | last modified:
  434. |
  435. |
  436. | parameters: none
  437. | modifies: global variable MgaSel and pMgaBaseAddress
  438. | static variable currentIndex set to 1.
  439. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  440. | returns: dword base address of the first mga found.
  441. | -1 if no mga found (or no PCI BIOS found).
  442. |
  443. -----------------------------------------------------------------------------*/
  444. dword pciFindFirstMGA()
  445. {
  446. #ifdef WINDOWS_NT
  447. return (dword)-1;
  448. #endif /* #ifdef WINDOWS_NT */
  449. }
  450. /*----------------------------------------------------------------------------
  451. | name: pciFindNextMGA
  452. |
  453. | description: Find the next MGA device in the system and return the base
  454. | address of the device the function pciFindFirstMGA must me call
  455. | before call to this function. This function search a mga device
  456. | a currentIndex and increment the current index by 1. A call to
  457. | pciFindFirstMGA set the currentIndex to 1.
  458. |
  459. | designed: Christian Toutant, august 26, 1993
  460. | last modified:
  461. |
  462. |
  463. | parameters: none
  464. | modifies: global variable MgaSel and pMgaBaseAddress
  465. | static variable currentIndex is incremented by 1.
  466. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  467. | returns: dword base address of the first mga found.
  468. | -1 if no mga found (or no PCI BIOS found).
  469. |
  470. -----------------------------------------------------------------------------*/
  471. dword pciFindNextMGA()
  472. {
  473. #ifdef WINDOWS_NT
  474. return (dword)-1;
  475. #endif /* #ifdef WINDOWS_NT */
  476. }
  477. #ifdef WINDOWS_NT
  478. PUCHAR pciBiosCallAddr()
  479. {
  480. return((PUCHAR)NULL);
  481. }
  482. #endif /* #ifdef WINDOWS_NT */
  483. #endif /* #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES)) */
  484. #if (USE_VP_GET_ACCESS_RANGES)
  485. extern PVOID pMgaDeviceExtension;
  486. extern ULONG PciSlot;
  487. #endif
  488. #if 0
  489. /*----------------------------------------------------------------------------
  490. | name: setPciOptionReg
  491. |
  492. | description: set the option register of all mga to 1
  493. |
  494. | designed: Christian Toutant, august 26, 1993
  495. | last modified:
  496. |
  497. |
  498. | parameters: none
  499. | modifies:
  500. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  501. | returns: void
  502. |
  503. -----------------------------------------------------------------------------*/
  504. void setPciOptionReg()
  505. {
  506. #if (USE_VP_GET_ACCESS_RANGES)
  507. UCHAR ConfigBuf = 0x01;
  508. ULONG ConfigOffset = 0x40;
  509. ULONG ConfigLength = 0x01;
  510. VideoPortSetBusData(pMgaDeviceExtension, //PVOID HwDeviceExtension,
  511. PCIConfiguration, //IN BUS_DATA_TYPE BusDataType,
  512. PciSlot, //IN ULONG SlotNumber,
  513. &ConfigBuf, //IN PVOID Buffer,
  514. ConfigOffset, //IN ULONG Offset,
  515. ConfigLength); //IN ULONG Length
  516. #else /* #if (USE_VP_GET_ACCESS_RANGES) */
  517. byte i;
  518. // Use mechanism #1 also!!!
  519. // Get access to ports before trying to map I/O configuration space.
  520. if ((pMgaPciIo = VideoPortGetDeviceBase(pMgaDeviceExtension,
  521. MgaPciCseAccessRange.RangeStart,
  522. MgaPciCseAccessRange.RangeLength,
  523. MgaPciCseAccessRange.RangeInIoSpace)) != NULL)
  524. {
  525. // Map I/O Configuration Space.
  526. outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x80);
  527. outp(pMgaPciIo+PCI_FORWARD-PCI_CSE, 0x00);
  528. for (i = 0; i < NbBoard; i++)
  529. {
  530. if (Hw[i].ConfigSpace != 0)
  531. {
  532. MgaPciConfigAccessRange.RangeStart.LowPart = (ULONG)Hw[i].ConfigSpace;
  533. if ((pMgaPciConfigSpace = VideoPortGetDeviceBase(pMgaDeviceExtension,
  534. MgaPciConfigAccessRange.RangeStart,
  535. MgaPciConfigAccessRange.RangeLength,
  536. MgaPciConfigAccessRange.RangeInIoSpace)) != NULL)
  537. {
  538. outp(pMgaPciConfigSpace + 0x40, 0x01);
  539. VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciConfigSpace);
  540. }
  541. }
  542. outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00);
  543. VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciIo);
  544. }
  545. #endif /* #if (USE_VP_GET_ACCESS_RANGES) */
  546. }
  547. #endif //#if 0
  548. #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES))
  549. /*----------------------------------------------------------------------------
  550. | name: pciFindFirstMGA_2
  551. |
  552. | description: Find the first MGA device in the system and return the base
  553. | address of the device in the system (a succesive call to the
  554. | function pciFindNextMGA give the address of other mga device
  555. | in the system).
  556. |
  557. | designed: Christian Toutant, august 26, 1993
  558. | last modified:
  559. |
  560. |
  561. | parameters: none
  562. | modifies: global variable MgaSel and pMgaBaseAddress
  563. | static variable currentIndex set to 1.
  564. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  565. | returns: dword base address of the first mga found.
  566. | -1 if no mga found (or no PCI BIOS found).
  567. |
  568. -----------------------------------------------------------------------------*/
  569. dword pciFindFirstMGA_2()
  570. {
  571. dword address;
  572. configSpace = 0x0000;
  573. address = pciFindFirstMGA_1();
  574. if (address == (dword)-1 )
  575. {
  576. configSpace = 0xc000;
  577. return pciFindNextMGA_2();
  578. }
  579. else
  580. {
  581. return address;
  582. }
  583. }
  584. /*----------------------------------------------------------------------------
  585. | name: pciFindNextMGA_2
  586. |
  587. | description: Find the next MGA device in the system and return the base
  588. | address of the device the function pciFindFirstMGA must me call
  589. | before call to this function. This function search a mga device
  590. | a currentIndex and increment the current index by 1. A call to
  591. | pciFindFirstMGA set the currentIndex to 1.
  592. |
  593. | designed: Christian Toutant, august 26, 1993
  594. | last modified:
  595. |
  596. |
  597. | parameters: none
  598. | modifies: global variable MgaSel and pMgaBaseAddress
  599. | static variable currentIndex is incremented by 1.
  600. | calls: pciBiosPresent, pciFindDevice, pciReadConfigDWord
  601. | returns: dword base address of the first mga found.
  602. | -1 if no mga found (or no PCI BIOS found).
  603. |
  604. -----------------------------------------------------------------------------*/
  605. dword pciFindNextMGA_2()
  606. {
  607. byte command, subClass;
  608. dword address = 0;
  609. /* Map I/O Configuration Space */
  610. address = pciFindNextMGA_1();
  611. if (address != (dword)-1 )
  612. return address;
  613. // Restore this before going on, or you'll be sorry!
  614. address = 0;
  615. outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x80);
  616. while (!address)
  617. {
  618. if (configSpace > 0xcf00)
  619. {
  620. address = (dword)-1;
  621. outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00);
  622. }
  623. else
  624. {
  625. // Get access to the current I/O space.
  626. MgaPciConfigAccessRange.RangeStart.LowPart = (ULONG)configSpace;
  627. if (VideoPortVerifyAccessRanges(pMgaDeviceExtension,
  628. 1,
  629. &MgaPciConfigAccessRange) == NO_ERROR &&
  630. (pMgaPciConfigSpace = VideoPortGetDeviceBase(pMgaDeviceExtension,
  631. MgaPciConfigAccessRange.RangeStart,
  632. MgaPciConfigAccessRange.RangeLength,
  633. MgaPciConfigAccessRange.RangeInIoSpace)) != NULL)
  634. {
  635. if ((
  636. (inp(pMgaPciConfigSpace ) == 0x2b) &&
  637. (inp(pMgaPciConfigSpace + 1) == 0x10) &&
  638. (inp(pMgaPciConfigSpace + 2) == 0x18) &&
  639. (inp(pMgaPciConfigSpace + 3) == 0x05)
  640. ) ||
  641. (
  642. (inp(pMgaPciConfigSpace ) == 0x2b) &&
  643. (inp(pMgaPciConfigSpace + 1) == 0x10) &&
  644. (inp(pMgaPciConfigSpace + 2) == 0x10) &&
  645. (inp(pMgaPciConfigSpace + 3) == 0x0D)
  646. )
  647. )
  648. {
  649. address = (dword)inp(pMgaPciConfigSpace + 0x13) << 24;
  650. address |= (dword)inp(pMgaPciConfigSpace + 0x12) << 16;
  651. address |= (dword)inp(pMgaPciConfigSpace + 0x11) << 8;
  652. address |= (dword)(inp(pMgaPciConfigSpace + 0x10) & 0x0c);
  653. command = inp(pMgaPciConfigSpace + PCI_COMMAND);
  654. subClass = inp(pMgaPciConfigSpace + PCI_CLASS_CODE + 1);
  655. /*--- Detect ATHENA revision < 2
  656. If MGA board is in VGA mode and the snooping test fail, set
  657. ATHENA rev 1 flag
  658. ---*/
  659. /* Test if we are in vga mode & snooping disabled*/
  660. if ( !subClass && !(command & PCI_SNOOPING) )
  661. {
  662. /* assume athena rev > 1 */
  663. pciBoardInfo &= ~(word)PCI_FLAG_ATHENA_REV1;
  664. /* init location 64 at 0 */
  665. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
  666. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  667. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  668. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  669. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
  670. /* empty fifo */
  671. VideoPortReadPortUchar(TITAN_PEL_ADDR_RD);
  672. /* active snooping */
  673. outp(pMgaPciConfigSpace + PCI_COMMAND,
  674. (byte)(command | PCI_SNOOPING));
  675. /* write to DAC in snooping mode */
  676. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x11);
  677. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x22);
  678. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)0x33);
  679. /* restore snooping */
  680. outp(pMgaPciConfigSpace + PCI_COMMAND, (byte)command);
  681. /* now if the acces fail, we assume athena rev 1 */
  682. VideoPortWritePortUchar(TITAN_PEL_ADDR_RD, (UCHAR)64);
  683. if (
  684. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x11) ||
  685. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x22) ||
  686. (VideoPortReadPortUchar(TITAN_PEL_DATA) != 0x33)
  687. ) pciBoardInfo |= PCI_FLAG_ATHENA_REV1;
  688. /* init location 64 at 0 */
  689. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64);
  690. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  691. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  692. VideoPortWritePortUchar(TITAN_PEL_DATA, (UCHAR)00);
  693. VideoPortWritePortUchar(TITAN_PEL_ADDR_WR, (UCHAR)64); /* reinit write addr */
  694. }
  695. /*---- END Detect ATHENA revision < 2 */
  696. /* If MGA board is in VGA mode and the MEM/IO space is not
  697. enabled, enable it.
  698. */
  699. if (!subClass && !(command & 0x03))
  700. {
  701. outp(pMgaPciConfigSpace + PCI_COMMAND,
  702. (byte)(command | 2));
  703. if ((pMgaBaseAddr = setmgasel(MgaSel, address, 4)) != NULL)
  704. {
  705. mgaReadBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),
  706. command);
  707. mgaWriteBYTE(*(pMgaBaseAddr+TITAN_OFFSET+TITAN_CONFIG+1),
  708. command & ~(byte)4);
  709. VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaBaseAddr);
  710. }
  711. }
  712. }
  713. VideoPortFreeDeviceBase(pMgaDeviceExtension,pMgaPciConfigSpace);
  714. }
  715. }
  716. configSpace += 0x100;
  717. }
  718. outp(pMgaPciIo+PCI_CSE-PCI_CSE, 0x00);
  719. return address;
  720. }
  721. #endif /* #if (!defined(WINDOWS_NT) || defined(MGA_WINNT31) || (!USE_VP_GET_ACCESS_RANGES)) */