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.

306 lines
7.0 KiB

  1. /*
  2. * EAGLE.C - VLSI Eagle PCI chipset routines.
  3. *
  4. * Notes:
  5. * Algorithms from VLSI VL82C534 Spec
  6. *
  7. */
  8. #include "local.h"
  9. #define NUM_EAGLE_LINKS 8
  10. const UCHAR rgbIRQToBit[16] = {
  11. // IRQ= 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  12. 0xFF, 8, 0xFF, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 0xFF, 6, 7,
  13. };
  14. const UCHAR rgbBitToIRQ[16] = {
  15. // Bit=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  16. 7, 8, 9, 10, 11, 12, 14, 15, 1, 3, 4, 5, 6, 0xFF, 0xFF, 0xFF,
  17. };
  18. /****************************************************************************
  19. *
  20. * EagleUpdateSerialIRQ - Set or Reset the Eagle Serial IRQ registers
  21. *
  22. * Not exported.
  23. *
  24. * ENTRY: bIRQ is the IRQ to modify.
  25. *
  26. * fSet is TRUE to set bit, FALSE to reset bit.
  27. *
  28. * EXIT: None.
  29. *
  30. ***************************************************************************/
  31. static void CDECL
  32. EagleUpdateSerialIRQ(UCHAR bIRQ, ULONG fSet)
  33. {
  34. UCHAR bBitIndex, bReg;
  35. USHORT wBit, wSerialIRQConnection;
  36. //
  37. // Validate bIRQ as a serial IRQ.
  38. //
  39. if (!bIRQ)
  40. return;
  41. bBitIndex=rgbIRQToBit[bIRQ];
  42. if (bBitIndex==0xFF)
  43. return;
  44. wBit=1<<bBitIndex;
  45. for (bReg=0x70; bReg<=0x72; bReg+=2) {
  46. wSerialIRQConnection=ReadConfigUshort( bBusPIC, bDevFuncPIC,
  47. bReg);
  48. if (fSet)
  49. wSerialIRQConnection|=wBit;
  50. else
  51. wSerialIRQConnection&=~wBit;
  52. WriteConfigUshort( bBusPIC, bDevFuncPIC, bReg,
  53. wSerialIRQConnection);
  54. }
  55. }
  56. /****************************************************************************
  57. *
  58. * VLSIEagleSetIRQ - Set an Eagle PCI link to a specific IRQ
  59. *
  60. * Exported.
  61. *
  62. * ENTRY: bIRQNumber is the new IRQ to be used.
  63. *
  64. * bLink is the Link to be set.
  65. *
  66. * EXIT: Standard PCIMP return value.
  67. *
  68. ***************************************************************************/
  69. PCIMPRET CDECL
  70. VLSIEagleSetIRQ(UCHAR bIRQNumber, UCHAR bLink)
  71. {
  72. ULONG ulEagleRegister;
  73. UCHAR bOldIRQ;
  74. ULONG fUsingOldIRQ;
  75. ULONG i;
  76. //
  77. // Make link number 0 based, and validate.
  78. //
  79. bLink--;
  80. if (bLink >= NUM_EAGLE_LINKS) {
  81. return(PCIMP_INVALID_LINK);
  82. }
  83. //
  84. // First, set the Eagle Interrupt Connection Register.
  85. //
  86. ulEagleRegister=ReadConfigUlong(bBusPIC, bDevFuncPIC, 0x74);
  87. bOldIRQ=(UCHAR)((ulEagleRegister >> (bLink*4))&0xF);
  88. ulEagleRegister&=~(0xF << (bLink*4));
  89. ulEagleRegister|=(bIRQNumber << (bLink*4));
  90. WriteConfigUlong(bBusPIC, bDevFuncPIC, 0x74, ulEagleRegister);
  91. //
  92. // Determine if we are still using the old IRQ.
  93. //
  94. fUsingOldIRQ=FALSE;
  95. for (i=0; i<NUM_EAGLE_LINKS; i++) {
  96. if ((ulEagleRegister >> (bLink*4))==bOldIRQ) {
  97. fUsingOldIRQ=TRUE;
  98. }
  99. }
  100. //
  101. // If not using old IRQ, enable the serial IRQs.
  102. //
  103. if (!fUsingOldIRQ) {
  104. EagleUpdateSerialIRQ(bOldIRQ, FALSE);
  105. }
  106. //
  107. // Prevent serial IRQs on the new IRQ.
  108. //
  109. EagleUpdateSerialIRQ(bIRQNumber, TRUE);
  110. return(PCIMP_SUCCESS);
  111. }
  112. /****************************************************************************
  113. *
  114. * VLSIEagleGetIRQ - Get the IRQ of an Eagle PCI link
  115. *
  116. * Exported.
  117. *
  118. * ENTRY: pbIRQNumber is the buffer to fill.
  119. *
  120. * bLink is the Link to be read.
  121. *
  122. * EXIT: Standard PCIMP return value.
  123. *
  124. ***************************************************************************/
  125. PCIMPRET CDECL
  126. VLSIEagleGetIRQ(PUCHAR pbIRQNumber, UCHAR bLink)
  127. {
  128. ULONG ulEagleRegister;
  129. //
  130. // Make link number 0 based, and validate.
  131. //
  132. bLink--;
  133. if (bLink >= NUM_EAGLE_LINKS) {
  134. return(PCIMP_INVALID_LINK);
  135. }
  136. //
  137. // Read in the Eagle Interrupt Connection Register.
  138. //
  139. ulEagleRegister=ReadConfigUlong(bBusPIC, bDevFuncPIC, 0x74);
  140. //
  141. // Find the link's IRQ value.
  142. //
  143. *pbIRQNumber=(UCHAR)((ulEagleRegister >> (bLink*4)) & 0xF);
  144. return(PCIMP_SUCCESS);
  145. }
  146. /****************************************************************************
  147. *
  148. * VLSIEagleSetTrigger - Set the IRQ triggering values for the Eagle.
  149. *
  150. * Exported.
  151. *
  152. * ENTRY: ulTrigger has bits set for Level triggered IRQs.
  153. *
  154. * EXIT: Standard PCIMP return value.
  155. *
  156. ***************************************************************************/
  157. PCIMPRET CDECL
  158. VLSIEagleSetTrigger(ULONG ulTrigger)
  159. {
  160. USHORT wAssertionRegister;
  161. ULONG i;
  162. UCHAR bBitIndex;
  163. wAssertionRegister=0;
  164. //
  165. // For each IRQ...
  166. //
  167. for (i=0; i<16; i++)
  168. {
  169. //
  170. // If this is to be set level...
  171. //
  172. if (ulTrigger & (1<<i)) {
  173. //
  174. // If this is not a levelable IRQ, bail.
  175. //
  176. bBitIndex=rgbIRQToBit[i];
  177. if (bBitIndex==0xFF)
  178. return(PCIMP_INVALID_IRQ);
  179. //
  180. // Set the corresponding bit in our new mask.
  181. //
  182. wAssertionRegister|=1<<bBitIndex;
  183. }
  184. }
  185. //
  186. // Set the Assertion Register.
  187. //
  188. WriteConfigUshort(bBusPIC, bDevFuncPIC, 0x88, wAssertionRegister);
  189. return(PCIMP_SUCCESS);
  190. }
  191. /****************************************************************************
  192. *
  193. * VLSIEagleGetTrigger - Get the IRQ triggering values for the Eagle.
  194. *
  195. * Exported.
  196. *
  197. * ENTRY: pulTrigger will have bits set for Level triggered IRQs.
  198. *
  199. * EXIT: TRUE if successful.
  200. *
  201. ***************************************************************************/
  202. PCIMPRET CDECL
  203. VLSIEagleGetTrigger(PULONG pulTrigger)
  204. {
  205. USHORT wAssertionRegister;
  206. ULONG i;
  207. //
  208. // Read in the Interrupt Assertion Level register.
  209. //
  210. wAssertionRegister=ReadConfigUshort(bBusPIC, bDevFuncPIC, 0x88);
  211. //
  212. // Clear the return buffer.
  213. //
  214. *pulTrigger = 0;
  215. //
  216. // For each bit...
  217. //
  218. for (i=0; i<16; i++)
  219. {
  220. //
  221. // If the bit set, and this bit corresponds to an IRQ...
  222. //
  223. if ( (wAssertionRegister & (1 << i)) &&
  224. (rgbBitToIRQ[i]!=0xFF))
  225. {
  226. //
  227. // Set the corresponding bit in the
  228. // return buffer.
  229. //
  230. *pulTrigger |= 1 << rgbBitToIRQ[i];
  231. }
  232. }
  233. return(PCIMP_SUCCESS);
  234. }
  235. /****************************************************************************
  236. *
  237. * VLSIEagleValidateTable - Validate an IRQ table
  238. *
  239. * Exported.
  240. *
  241. * ENTRY: piihIRQInfoHeader points to an IRQInfoHeader followed
  242. * by an IRQ Routing Table.
  243. *
  244. * ulFlags are PCIMP_VALIDATE flags.
  245. *
  246. * EXIT: Standard PCIMP return value.
  247. *
  248. ***************************************************************************/
  249. #ifdef ALLOC_PRAGMA
  250. PCIMPRET CDECL
  251. VLSIEagleValidateTable(PIRQINFOHEADER piihIRQInfoHeader, ULONG ulFlags);
  252. #pragma alloc_text(PAGE, VLSIEagleValidateTable)
  253. #endif //ALLOC_PRAGMA
  254. PCIMPRET CDECL
  255. VLSIEagleValidateTable(PIRQINFOHEADER piihIRQInfoHeader, ULONG ulFlags)
  256. {
  257. PAGED_CODE();
  258. if (GetMaxLink(piihIRQInfoHeader)>NUM_EAGLE_LINKS) {
  259. return(PCIMP_FAILURE);
  260. }
  261. return(PCIMP_SUCCESS);
  262. }