Leaked source code of windows server 2003
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.

321 lines
7.4 KiB

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