Windows NT 4.0 source code leak
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.

369 lines
11 KiB

4 years ago
  1. #pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk35/src/hal/halsni/mips/RCS/xxinitnt.c,v 1.6 1995/04/07 10:08:17 flo Exp $")
  2. /*++
  3. Copyright (c) 1993 - 1994 Siemens Nixdorf Informationssysteme AG
  4. Copyright (c) 1991 Microsoft Corporation
  5. Module Name:
  6. xxinitnt.c
  7. Abstract:
  8. This module implements the interrupt initialization for a MIPS R3000
  9. or R4000 system.
  10. Environment:
  11. Kernel mode only.
  12. --*/
  13. #include "halp.h"
  14. #include "eisa.h"
  15. extern BOOLEAN HalpProcPc;
  16. extern BOOLEAN HalpCountCompareInterrupt;
  17. //
  18. // Define forward referenced prototypes.
  19. //
  20. VOID
  21. HalpAckExtraClockInterrupt(
  22. VOID
  23. );
  24. VOID
  25. HalpCountInterrupt (
  26. VOID
  27. );
  28. VOID
  29. HalpProgramIntervalTimer (
  30. IN ULONG Interval
  31. );
  32. VOID
  33. HalpProgramExtraTimer (
  34. IN ULONG Interval
  35. );
  36. //
  37. // Put all code for HAL initialization in the INIT section. It will be
  38. // deallocated by memory management when phase 1 initialization is
  39. // completed.
  40. //
  41. #if defined(ALLOC_PRAGMA)
  42. #pragma alloc_text(INIT, HalpInitializeInterrupts)
  43. #pragma alloc_text(INIT, HalpCountInterrupt)
  44. #endif
  45. //
  46. // Define the IRQL mask and level mapping table.
  47. //
  48. // These tables are transfered to the PCR and determine the priority of
  49. // interrupts.
  50. //
  51. // N.B. The two software interrupt levels MUST be the lowest levels.
  52. /*+++
  53. The interrupts bits in the cause Register have the following Hardware Interrupts:
  54. 7 6 5 4 3 2 1 0
  55. +-------------------------------+
  56. | x | x | x | x | x | x | x | x |
  57. +-------------------------------+
  58. | | | | | | | |
  59. | | | | | | | +-------- APC LEVEL (Software)
  60. | | | | | | +------------ Dispatch LEVEL (Software)
  61. | | | | | +---------------- central Int0 for R4x00 SC machines
  62. | | | | +-------------------- SCSI_EISA LEVEL
  63. | | | +------------------------ DUART (Console)
  64. | | +---------------------------- TIMER (82C54 in the local I/O part)
  65. | +-------------------------------- Ethernet (intel 82596 onboard)
  66. +------------------------------------ CountCompare (Profiling) or PushButton Int.
  67. ---*/
  68. //
  69. // On an R4x00SC, the processor has only 1 central interrupt pin, so all
  70. // should be directed to this interrupt, except the (internal) CountCompare interrupt
  71. // This is also true for the oncomming SNI Desktop model, which has only the
  72. // central interrupt connected
  73. //
  74. UCHAR
  75. HalpIrqlMask_SC[] = {3, 3, 3, 3, 3, 3, 3, 3, // 0000 - 0111 high 4-bits
  76. 8, 8, 8, 8, 8, 8, 8, 8, // 1000 - 1111 high 4-bits (CountCompare only!)
  77. 0, 1, 2, 2, 3, 3, 3, 3, // 0000 - 0111 low 4-bits
  78. 3, 3, 3, 3, 3, 3, 3, 3}; // 1000 - 1111 low 4-bits
  79. UCHAR
  80. HalpIrqlTable_SC[] = {0x87, // IRQL 0
  81. 0x86, // IRQL 1
  82. 0x84, // IRQL 2
  83. 0x80, // Int0Dispatch Level
  84. // allow only Irql 8 (profiling & HIGH_LEVEL) ?!
  85. 0x80, // IRQL 4
  86. 0x80, // IRQL 5
  87. 0x80, // IRQL 6
  88. 0x80, // IRQL 7
  89. 0x00}; // IRQL 8
  90. //
  91. // On an R4x00MC, all the interrupts enable/disable per processor is managed by the MPagent
  92. //
  93. /*+++ Note from Dave Cutler "Mr. NT"
  94. | How can this happen ?
  95. |
  96. You cannot use the interrupt mask field of the status register to
  97. enable/disable per processor interrupts. In fact, the IRQL mask table
  98. that is initialized by the HAL must be the same for all processors.
  99. When threads start execution they have all interrupts in the
  100. interrupt mask field set according to the PASSIVE_LEVEL entry in the
  101. interrupt mapping table of the processor they start on. They are
  102. immediately context switchable. If per processor interrupts weere
  103. controlled by the interrupt mask field of the status register, then
  104. as soon as the thread got scheduled on another processor, the enables
  105. would no longer be correct.
  106. d
  107. ---*/
  108. UCHAR HalpIrqlMask_MC[] = {4, 7, 6, 7, 5, 7, 6, 7, // 0000 - 0111 high 4-bits
  109. 8, 8, 8, 8, 8, 8, 8, 8, // 1000 - 1111 high 4-bits
  110. 0, 1, 2, 2, 3, 3, 3, 3, // 0000 - 0111 low 4-bits
  111. 4, 4, 4, 4, 4, 4, 4, 4}; // 1000 - 1111 low 4-bits
  112. UCHAR HalpIrqlTable_MC[] = {0xff, // IRQL 0
  113. 0xfe, // IRQL 1
  114. 0xfc, // IRQL 2
  115. 0xf8, // IRQL 3
  116. 0xf0, // IRQL 4
  117. 0xb0, // IRQL 5 NET
  118. 0x90, // IRQL 6 CLOCK
  119. 0x80, // IRQL 7 IPI
  120. 0x00}; // IRQL 8
  121. UCHAR
  122. HalpIrqlMask_PC[] = {4, 5, 6, 6, 7, 7, 7, 7, // 0000 - 0111 high 4-bits
  123. 8, 8, 8, 8, 8, 8, 8, 8, // 1000 - 1111 high 4-bits
  124. 0, 1, 2, 2, 3, 3, 3, 3, // 0000 - 0111 low 4-bits
  125. 4, 4, 4, 4, 4, 4, 4, 4}; // 1000 - 1111 low 4-bits
  126. UCHAR
  127. HalpIrqlTable_PC[] = {0xfb, // IRQL 0 1111 1011
  128. 0xfa, // IRQL 1 1111 1010
  129. 0xf8, // IRQL 2 1111 1000
  130. 0xf8, // IRQL 3 1111 1000
  131. 0xf0, // IRQL 4 1111 0000
  132. 0xe0, // IRQL 5 1110 0000
  133. 0xc0, // IRQL 6 1100 0000
  134. 0x80, // IRQL 7 1000 0000
  135. 0x00}; // IRQL 8 0000 0000
  136. VOID
  137. HalpCountInterrupt (
  138. VOID
  139. )
  140. /*++
  141. Routine Description:
  142. This function serves as the R4000 count/compare interrupt service
  143. routine early in the system initialization. Its only function is
  144. to field and acknowledge count/compare interrupts during the system
  145. boot process.
  146. Arguments:
  147. None.
  148. Return Value:
  149. None.
  150. --*/
  151. {
  152. extern ULONG HalpProfileInterval;
  153. //
  154. // Acknowledge the R4000 count/compare interrupt.
  155. //
  156. HalpProfileInterval = DEFAULT_PROFILE_INTERVAL;
  157. HalpCountCompareInterrupt = TRUE;
  158. HalpWriteCompareRegisterAndClear(DEFAULT_PROFILE_COUNT);
  159. return;
  160. }
  161. BOOLEAN
  162. HalpInitializeInterrupts (
  163. VOID
  164. )
  165. /*++
  166. Routine Description:
  167. This function initializes interrupts for a MIPS R3000 or R4000 system.
  168. Arguments:
  169. None.
  170. Return Value:
  171. A value of TRUE is returned if the initialization is successfully
  172. completed. Otherwise a value of FALSE is returned.
  173. --*/
  174. {
  175. ULONG Index;
  176. PKPRCB Prcb;
  177. //
  178. // Get the address of the processor control block for the current
  179. // processor.
  180. //
  181. Prcb = PCR->Prcb;
  182. if (Prcb->Number == 0) {
  183. //
  184. // Initialize the IRQL translation tables in the PCR. These tables are
  185. // used by the interrupt dispatcher to determine the new IRQL and the
  186. // mask value that is to be loaded into the PSR. They are also used by
  187. // the routines that raise and lower IRQL to load a new mask value into
  188. // the PSR.
  189. //
  190. if (HalpIsRM200) {
  191. //
  192. // On an RM200 (Desktop) we have only 1 interrupt, which is like
  193. // the central Interrupt for R4x00SC machines
  194. //
  195. for (Index = 0; Index < sizeof(HalpIrqlMask_SC); Index += 1)
  196. PCR->IrqlMask[Index] = HalpIrqlMask_SC[Index];
  197. for (Index = 0; Index < sizeof(HalpIrqlTable_SC); Index += 1)
  198. PCR->IrqlTable[Index] = HalpIrqlTable_SC[Index];
  199. } else {
  200. //
  201. // if this is not a Desktop, we have to check if this is an
  202. // R4x00 SC model or a R4x00 MC (multiprocessor model)
  203. //
  204. if (HalpProcessorId == MPAGENT) {
  205. //
  206. // this is the boot processor in an MultiProcessor Environment
  207. //
  208. for (Index = 0; Index < sizeof(HalpIrqlMask_MC); Index += 1)
  209. PCR->IrqlMask[Index] = HalpIrqlMask_MC[Index];
  210. for (Index = 0; Index < sizeof(HalpIrqlTable_MC); Index += 1)
  211. PCR->IrqlTable[Index] = HalpIrqlTable_MC[Index];
  212. } else {
  213. if ((HalpProcPc) || (HalpProcessorId == ORIONSC)) {
  214. //
  215. // this is an R4000PC or a R4600 model in an UniProcessor Environment
  216. //
  217. for (Index = 0; Index < sizeof(HalpIrqlMask_PC); Index += 1)
  218. PCR->IrqlMask[Index] = HalpIrqlMask_PC[Index];
  219. for (Index = 0; Index < sizeof(HalpIrqlTable_PC); Index += 1)
  220. PCR->IrqlTable[Index] = HalpIrqlTable_PC[Index];
  221. } else {
  222. //
  223. // this is an R4x00SC model in an UniProcessor Environment
  224. //
  225. for (Index = 0; Index < sizeof(HalpIrqlMask_SC); Index += 1)
  226. PCR->IrqlMask[Index] = HalpIrqlMask_SC[Index];
  227. for (Index = 0; Index < sizeof(HalpIrqlTable_SC); Index += 1)
  228. PCR->IrqlTable[Index] = HalpIrqlTable_SC[Index];
  229. }
  230. }
  231. }
  232. //
  233. // the main system clock is always in the onboard PC core
  234. //
  235. PCR->InterruptRoutine[CLOCK2_LEVEL] = (PKINTERRUPT_ROUTINE)HalpStallInterrupt;
  236. //
  237. // If processor 0 is being initialized, then connect the count/compare
  238. // interrupt to the count interrupt routine to handle early count/compare
  239. // interrupts during phase 1 initialization. Otherwise, connect the
  240. // count\compare interrupt to the appropriate interrupt service routine.
  241. //
  242. //
  243. // force a CountCompare interrupt
  244. //
  245. HalpWriteCompareRegisterAndClear(100);
  246. PCR->InterruptRoutine[PROFILE_LEVEL] = HalpCountInterrupt;
  247. HalpProgramIntervalTimer (MAXIMUM_INCREMENT);
  248. HalpEnableOnboardInterrupt(CLOCK2_LEVEL,Latched); // Enable Timer1,Counter0 interrupt
  249. } else {
  250. //
  251. // MultiProcessorEnvironment Processor N
  252. //
  253. for (Index = 0; Index < sizeof(HalpIrqlMask_MC); Index += 1)
  254. PCR->IrqlMask[Index] = HalpIrqlMask_MC[Index];
  255. for (Index = 0; Index < sizeof(HalpIrqlTable_MC); Index += 1)
  256. PCR->IrqlTable[Index] = HalpIrqlTable_MC[Index];
  257. HalpProgramExtraTimer (MAXIMUM_INCREMENT);
  258. PCR->InterruptRoutine[EXTRA_CLOCK_LEVEL] = HalpClockInterrupt1;
  259. PCR->InterruptRoutine[PROFILE_LEVEL] = HalpProfileInterrupt;
  260. PCR->StallScaleFactor = HalpStallScaleFactor;
  261. }
  262. return TRUE;
  263. }