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.

285 lines
5.9 KiB

  1. /*
  2. *
  3. * Copyright (c) Microsoft Corporation. All rights reserved.
  4. *
  5. * VESUVIUS.C - NS VESUVIUS PCI chipset routines.
  6. *
  7. * Notes:
  8. * Algorithms from NS VESUVIUS Data Sheet
  9. *
  10. */
  11. #include "local.h"
  12. UCHAR
  13. ReadIndexRegisterByte(
  14. IN UCHAR bIndex
  15. );
  16. VOID
  17. WriteIndexRegisterByte(
  18. IN UCHAR bIndex,
  19. IN UCHAR bValue
  20. );
  21. #ifdef ALLOC_DATA_PRAGMA
  22. #pragma data_seg()
  23. #pragma const_seg()
  24. #endif
  25. LOCAL_DATA PIRQINFOHEADER gpiihIRQInfoHeader=NULL;
  26. #ifdef ALLOC_PRAGMA
  27. #pragma alloc_text(INIT, VESUVIUSValidateTable)
  28. #endif //ALLOC_PRAGMA
  29. UCHAR
  30. ReadIndexRegisterByte(
  31. IN UCHAR bIndex
  32. )
  33. {
  34. UCHAR bOldIndex, bResult;
  35. bOldIndex=READ_PORT_UCHAR((PUCHAR)0x24);
  36. WRITE_PORT_UCHAR((PUCHAR)0x24, bIndex);
  37. bResult=READ_PORT_UCHAR((PUCHAR)0x26);
  38. WRITE_PORT_UCHAR((PUCHAR)0x24, bOldIndex);
  39. return(bResult);
  40. }
  41. VOID
  42. WriteIndexRegisterByte(
  43. IN UCHAR bIndex,
  44. IN UCHAR bValue
  45. )
  46. {
  47. UCHAR bOldIndex;
  48. bOldIndex=READ_PORT_UCHAR((PUCHAR)0x24);
  49. WRITE_PORT_UCHAR((PUCHAR)0x24, bIndex);
  50. WRITE_PORT_UCHAR((PUCHAR)0x26, bValue);
  51. WRITE_PORT_UCHAR((PUCHAR)0x24, bOldIndex);
  52. }
  53. /****************************************************************************
  54. *
  55. * VESUVIUSSetIRQ - Set a VESUVIUS PCI link to a specific IRQ
  56. *
  57. * Exported.
  58. *
  59. * ENTRY: bIRQNumber is the new IRQ to be used.
  60. *
  61. * bLink is the Link to be set.
  62. *
  63. * EXIT: Standard PCIMP return value.
  64. *
  65. ***************************************************************************/
  66. PCIMPRET CDECL
  67. VESUVIUSSetIRQ(UCHAR bIRQNumber, UCHAR bLink)
  68. {
  69. UCHAR bIndex, bOldValue;
  70. //
  71. // Validate link number.
  72. //
  73. if (bLink > 4) {
  74. return(PCIMP_INVALID_LINK);
  75. }
  76. //
  77. // Zero based.
  78. //
  79. bLink--;
  80. //
  81. // Set various values.
  82. //
  83. bIndex=(bLink/2)+0x10;
  84. //
  85. // Read the old VESUVIUS IRQ register.
  86. //
  87. bOldValue=ReadIndexRegisterByte(bIndex);
  88. if (bLink&1) {
  89. bOldValue&=0x0f;
  90. bOldValue|=(bIRQNumber<<4);
  91. }
  92. else {
  93. bOldValue&=0xf0;
  94. bOldValue|=bIRQNumber;
  95. }
  96. //
  97. // Set the VESUVIUS IRQ register.
  98. //
  99. WriteIndexRegisterByte(bIndex, bOldValue);
  100. return(PCIMP_SUCCESS);
  101. }
  102. /****************************************************************************
  103. *
  104. * VESUVIUSGetIRQ - Get the IRQ of a VESUVIUS PCI link
  105. *
  106. * Exported.
  107. *
  108. * ENTRY: pbIRQNumber is the buffer to fill.
  109. *
  110. * bLink is the Link to be read.
  111. *
  112. * EXIT: Standard PCIMP return value.
  113. *
  114. ***************************************************************************/
  115. PCIMPRET CDECL
  116. VESUVIUSGetIRQ(PUCHAR pbIRQNumber, UCHAR bLink)
  117. {
  118. UCHAR bIndex, bOldValue;
  119. //
  120. // Validate link number.
  121. //
  122. if (bLink > 4) {
  123. return(PCIMP_INVALID_LINK);
  124. }
  125. //
  126. // Zero based.
  127. //
  128. bLink--;
  129. //
  130. // Set various values.
  131. //
  132. bIndex=(bLink/2)+0x10;
  133. //
  134. // Read the old VESUVIUS IRQ register.
  135. //
  136. bOldValue=ReadIndexRegisterByte(bIndex);
  137. if (bLink&1)
  138. bOldValue>>=4;
  139. *pbIRQNumber=bOldValue&0x0f;
  140. return(PCIMP_SUCCESS);
  141. }
  142. /****************************************************************************
  143. *
  144. * VESUVIUSSetTrigger - Set the IRQ triggering values for the VESUVIUS
  145. *
  146. * Exported.
  147. *
  148. * ENTRY: ulTrigger has bits set for Level triggered IRQs.
  149. *
  150. * EXIT: Standard PCIMP return value.
  151. *
  152. ***************************************************************************/
  153. PCIMPRET CDECL
  154. VESUVIUSSetTrigger(ULONG ulTrigger)
  155. {
  156. ULONG i;
  157. UCHAR bMask;
  158. bMask=(UCHAR)(ReadIndexRegisterByte(0x12)&0x0f);
  159. for (i=0; i<4; i++)
  160. {
  161. UCHAR bIRQ=ReadIndexRegisterByte((UCHAR)((i/2)+0x10));
  162. if (i&1)
  163. bIRQ>>=4;
  164. bIRQ&=0x0f;
  165. //
  166. // PCI interrupts go through L-E conversion.
  167. //
  168. if(bIRQ && (ulTrigger & (1<<bIRQ)))
  169. {
  170. bMask&=~(1<<i);
  171. ulTrigger&=~(1<<bIRQ);
  172. }
  173. }
  174. //
  175. // Return error if PCI is goofing up.
  176. //
  177. if (ulTrigger)
  178. return (PCIMP_FAILURE);
  179. WriteIndexRegisterByte(0x12, bMask);
  180. return(PCIMP_SUCCESS);
  181. }
  182. /****************************************************************************
  183. *
  184. * VESUVIUSGetTrigger - Get the IRQ triggering values for the VESUVIUS
  185. *
  186. * Exported.
  187. *
  188. * ENTRY: pulTrigger will have bits set for Level triggered IRQs.
  189. *
  190. * EXIT: Standard PCIMP return value.
  191. *
  192. ***************************************************************************/
  193. PCIMPRET CDECL
  194. VESUVIUSGetTrigger(PULONG pulTrigger)
  195. {
  196. UCHAR bMask;
  197. ULONG i;
  198. *pulTrigger=0;
  199. bMask=(UCHAR)(ReadIndexRegisterByte(0x12)&0x0f);
  200. for (i=0; i<4; i++)
  201. {
  202. if (!(bMask&(1<<i)))
  203. {
  204. UCHAR bIRQ=ReadIndexRegisterByte((UCHAR)((i/2)+0x10));
  205. if (i&1)
  206. bIRQ>>=4;
  207. bIRQ&=0x0f;
  208. if (bIRQ)
  209. *pulTrigger|=(1<<bIRQ);
  210. }
  211. }
  212. return(PCIMP_SUCCESS);
  213. }
  214. /****************************************************************************
  215. *
  216. * VESUVIUSValidateTable - Validate an IRQ table
  217. *
  218. * Exported.
  219. *
  220. * ENTRY: piihIRQInfoHeader points to an IRQInfoHeader followed
  221. * by an IRQ Routing Table.
  222. *
  223. * ulFlags are PCIMP_VALIDATE flags.
  224. *
  225. * EXIT: Standard PCIMP return value.
  226. *
  227. ***************************************************************************/
  228. PCIMPRET CDECL
  229. VESUVIUSValidateTable(PIRQINFOHEADER piihIRQInfoHeader, ULONG ulFlags)
  230. {
  231. PAGED_CODE();
  232. gpiihIRQInfoHeader=piihIRQInfoHeader;
  233. //
  234. // If any link is above 4, it is an error.
  235. //
  236. if (GetMaxLink(piihIRQInfoHeader)>4)
  237. return(PCIMP_FAILURE);
  238. return(PCIMP_SUCCESS);
  239. }