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.

327 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. spsproc.c
  5. Abstract:
  6. SystemPro Start Next Processor c code.
  7. This module implements the initialization of the system dependent
  8. functions that define the Hardware Architecture Layer (HAL) for an
  9. MP Compaq SystemPro
  10. Author:
  11. Ken Reneris (kenr) 22-Jan-1991
  12. Environment:
  13. Kernel mode only.
  14. Revision History:
  15. --*/
  16. #include "halp.h"
  17. const UCHAR HalName[] = "SystemPro or compatible MP Hal"; // This is placed in .text for debugging
  18. #define HalName L"SystemPro or compatible MP Hal"
  19. #ifdef ALLOC_DATA_PRAGMA
  20. #pragma data_seg("INITCONST")
  21. #endif // ALLOC_DATA_PRAGMA
  22. WCHAR HalHardwareIdString[] = L"syspro_mp\0";
  23. ADDRESS_USAGE HalpSystemProIoSpace = {
  24. NULL, CmResourceTypePort, InternalUsage,
  25. {
  26. 0xC70, 1, // WhoAmI
  27. 0xC6A, 1, // P0 Processor control register
  28. 0xFC6A, 1, // P1 Processor control register
  29. 0xFC67, 2, // P1 cache control, interrupt vector
  30. 0,0
  31. }
  32. };
  33. ADDRESS_USAGE HalpAcerIoSpace = {
  34. NULL, CmResourceTypePort, InternalUsage,
  35. {
  36. 0xCC67, 2, // P2 cache control, interrupt vector
  37. 0xCC6A, 1, // P2 Processor control register
  38. 0xDC67, 2, // P3 cache control, interrupt vector
  39. 0xDC6A, 1, // P3 Processor control register
  40. 0,0
  41. }
  42. };
  43. ADDRESS_USAGE HalpBelizeIoSpace = {
  44. NULL, CmResourceTypePort, InternalUsage,
  45. {
  46. 0xC67, 1, // Mode Select
  47. 0xC71, 6, // CPU assignment, reserverd[2], CPU index, address, data
  48. 0xCB0, 36, // IRQx Control/Status
  49. 0xCC9, 1, // INT13 Extended control/status port
  50. 0,0
  51. }
  52. };
  53. #ifdef ALLOC_DATA_PRAGMA
  54. #pragma data_seg()
  55. #endif // ALLOC_DATA_PRAGMA
  56. VOID
  57. HalpNonPrimaryClockInterrupt(
  58. VOID
  59. );
  60. BOOLEAN
  61. HalpInitMP (
  62. IN ULONG Phase,
  63. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  64. );
  65. VOID HalpInitOtherBuses (VOID);
  66. VOID HalpInitializePciBus (VOID);
  67. VOID HalpInitializePciStubs (VOID);
  68. #define LOW_MEMORY 0x000100000
  69. #define MAX_PT 8
  70. extern VOID StartPx_PMStub(VOID);
  71. #ifdef ALLOC_PRAGMA
  72. #pragma alloc_text(INIT,HalpInitMP)
  73. #pragma alloc_text(INIT,HalAllProcessorsStarted)
  74. #pragma alloc_text(INIT,HalReportResourceUsage)
  75. #pragma alloc_text(INIT,HalReportResourceUsage)
  76. #pragma alloc_text(INIT,HalpInitOtherBuses)
  77. #endif
  78. ULONG MpCount; // zero based. 0 = 1, 1 = 2, ...
  79. PUCHAR MpLowStub; // pointer to low memory bootup stub
  80. PVOID MpLowStubPhysicalAddress; // pointer to low memory bootup stub
  81. PUCHAR MppIDT; // pointer to physical memory 0:0
  82. extern ULONG HalpIpiClock; // bitmask of processors to ipi
  83. extern UCHAR SpCpuCount;
  84. extern UCHAR Sp8259PerProcessorMode;
  85. extern UCHAR SpType;
  86. extern PKPCR HalpProcessorPCR[];
  87. BOOLEAN
  88. HalpInitMP (
  89. IN ULONG Phase,
  90. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  91. )
  92. /*++
  93. Routine Description:
  94. Allows MP initialization from HalInitSystem.
  95. Arguments:
  96. Same as HalInitSystem
  97. Return Value:
  98. none.
  99. --*/
  100. {
  101. ULONG paddress;
  102. ULONG adjust;
  103. PKPCR pPCR;
  104. pPCR = KeGetPcr();
  105. if (Phase == 0) {
  106. //
  107. // Register the IO space used by the SystemPro
  108. //
  109. HalpRegisterAddressUsage (&HalpSystemProIoSpace);
  110. switch (SpType) {
  111. case 2:
  112. HalpRegisterAddressUsage (&HalpBelizeIoSpace);
  113. break;
  114. case 3:
  115. HalpRegisterAddressUsage (&HalpAcerIoSpace);
  116. break;
  117. }
  118. #if 0
  119. //
  120. // Register IPI vector
  121. //
  122. HalpRegisterVector (
  123. DeviceUsage,
  124. 13,
  125. 13 + PRIMARY_VECTOR_BASE,
  126. IPI_LEVEL );
  127. #endif
  128. //
  129. // Get pointer to real-mode idt table
  130. //
  131. MppIDT = HalpMapPhysicalMemory (0, 1);
  132. //
  133. // Allocate some low memory for processor bootup stub
  134. //
  135. MpLowStubPhysicalAddress = (PVOID)HalpAllocPhysicalMemory (LoaderBlock,
  136. LOW_MEMORY, 1, FALSE);
  137. if (!MpLowStubPhysicalAddress)
  138. return TRUE;
  139. MpLowStub = (PCHAR) HalpMapPhysicalMemory (MpLowStubPhysicalAddress, 1);
  140. MpCount = SpCpuCount-1;
  141. return TRUE;
  142. } else {
  143. //
  144. // Phase 1 for another processor
  145. //
  146. if (pPCR->Prcb->Number != 0) {
  147. if (Sp8259PerProcessorMode & 1) {
  148. //
  149. // Each processor has it's own pics - we broadcast profile
  150. // interrupts to each processor by enabling it on each
  151. // processor
  152. //
  153. HalpInitializeStallExecution( pPCR->Prcb->Number );
  154. HalpEnableInterruptHandler (
  155. DeviceUsage, // Report as device vector
  156. V2I (PROFILE_VECTOR), // Bus interrupt level
  157. PROFILE_VECTOR, // System IDT
  158. PROFILE_LEVEL, // System Irql
  159. HalpProfileInterrupt, // ISR
  160. Latched );
  161. } else {
  162. //
  163. // Without a profile interrupt we can not callibrate
  164. // KeStallExecutionProcessor, so we inherrit the value from P0.
  165. //
  166. pPCR->StallScaleFactor = HalpProcessorPCR[0]->StallScaleFactor;
  167. }
  168. if (Sp8259PerProcessorMode & 4) {
  169. //
  170. // Each processor can get it's own clock device - we
  171. // program each processor's 8254 and enable to interrupt
  172. // on each processor
  173. //
  174. HalpInitializeClock ();
  175. HalpEnableInterruptHandler (
  176. DeviceUsage, // Report as device vector
  177. V2I (CLOCK_VECTOR), // Bus interrupt level
  178. CLOCK_VECTOR, // System IDT
  179. CLOCK2_LEVEL, // System Irql
  180. HalpNonPrimaryClockInterrupt, // ISR
  181. Latched );
  182. } else {
  183. //
  184. // This processor doesn't have a clock, so we emulate it by
  185. // sending an ipi at clock intervals.
  186. //
  187. HalpIpiClock |= 1 << pPCR->Prcb->Number;
  188. }
  189. }
  190. }
  191. return TRUE;
  192. }
  193. BOOLEAN
  194. HalAllProcessorsStarted (
  195. VOID
  196. )
  197. {
  198. if (HalpFeatureBits & HAL_NO_SPECULATION) {
  199. //
  200. // Processor doesn't perform speculative execeution,
  201. // remove fences in critical code paths
  202. //
  203. HalpRemoveFences ();
  204. }
  205. return TRUE;
  206. }
  207. VOID
  208. HalReportResourceUsage (
  209. VOID
  210. )
  211. /*++
  212. Routine Description:
  213. The registery is now enabled - time to report resources which are
  214. used by the HAL.
  215. Arguments:
  216. Return Value:
  217. --*/
  218. {
  219. UNICODE_STRING UHalName;
  220. HalInitSystemPhase2();
  221. RtlInitUnicodeString (&UHalName, HalName);
  222. HalpReportResourceUsage (
  223. &UHalName, // descriptive name
  224. Eisa // SystemPro's are Eisa machines
  225. );
  226. //
  227. // Turn on MCA support if present
  228. //
  229. HalpMcaInit();
  230. //
  231. // Registry is now intialized, see if there are any PCI buses
  232. //
  233. HalpInitializePciBus ();
  234. HalpInitializePciStubs ();
  235. }
  236. VOID
  237. HalpInitOtherBuses (
  238. VOID
  239. )
  240. {
  241. // no other buses
  242. }