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.

260 lines
5.4 KiB

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