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.

593 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. generic.c
  5. Abstract:
  6. This module implements code that works on any processor.
  7. Author:
  8. Jake Oshins (3/23/00) - create file
  9. Environment:
  10. Kernel mode
  11. Notes:
  12. Revision History:
  13. --*/
  14. #include "..\lib\processor.h"
  15. //
  16. // Must define for debug output
  17. //
  18. #if DBG
  19. PUCHAR DebugName = "Processr.sys";
  20. #endif
  21. PFDO_DATA DeviceExtensions[MAX_SUPPORTED_PROCESSORS];
  22. UCHAR DevExtIndex;
  23. extern GLOBALS Globals;
  24. #ifdef ALLOC_PRAGMA
  25. #pragma alloc_text (PAGE, InitializeNonAcpiPerformanceStates)
  26. #pragma alloc_text (PAGE, InitializeAcpi2PStates)
  27. #pragma alloc_text (PAGE, InitializeAcpi2Cstates)
  28. #pragma alloc_text (PAGE, MergePerformanceStates)
  29. #endif
  30. NTSTATUS
  31. InitializeDriver(
  32. PUNICODE_STRING ServiceKeyRegPath
  33. )
  34. /*++
  35. Routine Description:
  36. Arguments:
  37. Return Value:
  38. --*/
  39. {
  40. //
  41. // Register for power state change notification
  42. //
  43. //PowerStateHandlerNotificationRegistration(ProcessSleepStateNotification,
  44. // NULL,
  45. // TRUE);
  46. return STATUS_SUCCESS;
  47. }
  48. #ifdef _X86_
  49. NTSTATUS
  50. FASTCALL
  51. SetPerfLevel(
  52. IN UCHAR Throttle
  53. )
  54. /*++
  55. Routine Description:
  56. Arguments:
  57. Return Value:
  58. --*/
  59. {
  60. PFDO_DATA DeviceExtension;
  61. ULONG apicId;
  62. ULONG index = 0;
  63. DebugEnter();
  64. //
  65. // Get APIC Id and retrieve Device Extension index
  66. //
  67. if (!Globals.SingleProcessorProfile) {
  68. apicId = GetApicId();
  69. index = Globals.ProcInfo.ApicIdToDevExtIndex[apicId];
  70. }
  71. //
  72. // Get the DeviceExtension.
  73. //
  74. DeviceExtension = DeviceExtensions[index];
  75. //
  76. // Since this driver does not support Functional Fixed Hardware, we
  77. // use generic method.
  78. //
  79. return SetPerfLevelGeneric(Throttle, DeviceExtension);
  80. }
  81. NTSTATUS
  82. FASTCALL
  83. SetThrottleLevel(
  84. IN UCHAR Throttle
  85. )
  86. /*++
  87. Routine Description:
  88. Arguments:
  89. Return Value:
  90. --*/
  91. {
  92. PFDO_DATA DeviceExtension;
  93. ULONG apicId;
  94. ULONG index = 0;
  95. DebugEnter();
  96. //
  97. // Get APIC Id and retrieve Device Extension index
  98. //
  99. if (!Globals.SingleProcessorProfile) {
  100. apicId = GetApicId();
  101. index = Globals.ProcInfo.ApicIdToDevExtIndex[apicId];
  102. }
  103. //
  104. // Get the DeviceExtension.
  105. //
  106. DeviceExtension = DeviceExtensions[index];
  107. //
  108. // Since this driver does not support Functional Fixed Hardware, we
  109. // use generic method.
  110. //
  111. return SetThrottleLevelGeneric(Throttle, DeviceExtension);
  112. }
  113. NTSTATUS
  114. GetProcessorBrandString (
  115. PUCHAR BrandString,
  116. PULONG Size
  117. )
  118. /*++
  119. Routine Description:
  120. Arguments:
  121. Return Value:
  122. --*/
  123. {
  124. //
  125. // With the generic driver we only try to find the Processor Brand String
  126. // via the CPUID
  127. //
  128. return GetCPUIDProcessorBrandString(BrandString, Size);
  129. }
  130. #else
  131. NTSTATUS
  132. FASTCALL
  133. SetPerfLevel(
  134. IN UCHAR Throttle
  135. )
  136. {
  137. TRAP();
  138. return STATUS_SUCCESS;
  139. }
  140. NTSTATUS
  141. GetProcessorBrandString (
  142. PUCHAR BrandString,
  143. PULONG Size
  144. )
  145. /*++
  146. Routine Description:
  147. Arguments:
  148. Return Value:
  149. --*/
  150. {
  151. DebugAssert(Size);
  152. *Size = 0;
  153. return STATUS_NOT_SUPPORTED;
  154. }
  155. #endif
  156. NTSTATUS
  157. InitializeAcpi2PStates(
  158. IN PFDO_DATA DevExt
  159. )
  160. /*++
  161. Routine Description:
  162. Arguments:
  163. Return Value:
  164. --*/
  165. {
  166. NTSTATUS status;
  167. status = InitializeAcpi2PStatesGeneric(DevExt);
  168. //
  169. // Make sure we didn't find any NON I/O or MEM addresses
  170. //
  171. if (NT_SUCCESS(status)) {
  172. if (((DevExt->PctPackage.Control.AddressSpaceID != AcpiGenericSpaceIO) &&
  173. (DevExt->PctPackage.Control.AddressSpaceID != AcpiGenericSpaceMemory)) ||
  174. ((DevExt->PctPackage.Status.AddressSpaceID != AcpiGenericSpaceIO) &&
  175. (DevExt->PctPackage.Status.AddressSpaceID != AcpiGenericSpaceMemory))) {
  176. DebugPrint((WARN, "ONLY Memory & I/O _PCT addresses are supported\n"));
  177. DebugPrint((WARN, "NOT using Acpi 2.0 Performance States\n"));
  178. //
  179. // Undo what InitializeAcpi2PStatesGeneric() did
  180. //
  181. if (DevExt->PssPackage) {
  182. ExFreePool(DevExt->PssPackage);
  183. DevExt->PssPackage = NULL;
  184. }
  185. return STATUS_NOT_SUPPORTED;
  186. }
  187. //
  188. // Walk through _PSS states to calculate latency values
  189. //
  190. ValidatePssLatencyValues(DevExt);
  191. //
  192. // Need to merge this new data with our perfstates
  193. //
  194. MergePerformanceStates(DevExt);
  195. }
  196. return status;
  197. }
  198. NTSTATUS
  199. InitializeAcpi2Cstates(
  200. PFDO_DATA DevExt
  201. )
  202. /*++
  203. Routine Description:
  204. This function looks to see if there is an ACPI 2.0 _CST object in the
  205. namespace, and, if there is, it replaces the functions found by
  206. InitializeAcpi1Cstates.
  207. Further note: This function leaves the filling in of throttling functions
  208. to the InitializePerformanceStates functions.
  209. Arguments:
  210. DeviceExtension
  211. Return Value:
  212. A NTSTATUS code to indicate the result of the initialization.
  213. --*/
  214. {
  215. ULONG apicId;
  216. ULONG index = 0;
  217. DebugEnter();
  218. //
  219. // Record the address of this processor's DeviceExtension, as the
  220. // throttling API doesn't give it to us.
  221. //
  222. if (!Globals.SingleProcessorProfile) {
  223. //
  224. // save the index into the DeviceExtension[] for later retrieval based
  225. // on APIC Id.
  226. //
  227. apicId = Globals.ProcInfo.ProcIdToApicId[DevExt->ProcObjInfo.PhysicalID];
  228. Globals.ProcInfo.ApicIdToDevExtIndex[apicId] = DevExtIndex;
  229. index = DevExtIndex++;
  230. }
  231. //
  232. // save Device Extension pointer
  233. //
  234. DeviceExtensions[index] = DevExt;
  235. //
  236. // This processor driver only supports I/O Space based Cstates.
  237. // InitializeAcpi2IoSpaceCstates() will fail if it finds Cstates with
  238. // non AcpiGenericSpaceIO type addresses.
  239. //
  240. return InitializeAcpi2IoSpaceCstates(DevExt);
  241. }
  242. NTSTATUS
  243. MergePerformanceStates(
  244. IN PFDO_DATA DeviceExtension
  245. )
  246. /*++
  247. Routine Description:
  248. This routine looks at the performance states stored in the device extension.
  249. Arguments:
  250. DeviceExtension
  251. Return Value:
  252. A NTSTATUS code to indicate the result of the initialization.
  253. NOTE:
  254. - The caller must hold PerfStateLock.
  255. - This is called during START_DEVICE, and after recieving a Notify(0x80)
  256. on the processor.
  257. --*/
  258. {
  259. DebugEnter();
  260. //
  261. // Since this driver does not support Functional Fixed Hardware, we
  262. // use generic method.
  263. //
  264. return MergePerformanceStatesGeneric(DeviceExtension);
  265. }
  266. NTSTATUS
  267. Acpi2PerfStateTransition(
  268. IN PFDO_DATA DeviceExtension,
  269. IN ULONG State
  270. )
  271. /*++
  272. Routine Description:
  273. This routine changes the performance state of the processor
  274. based on ACPI 2.0 performance state objects.
  275. Arguments:
  276. State - Index into _PSS object
  277. Return Value:
  278. none
  279. --*/
  280. {
  281. //
  282. // Since this driver does not support Functional Fixed Hardware, we
  283. // use generic method.
  284. //
  285. return Acpi2PerfStateTransitionGeneric(DeviceExtension, State);
  286. }
  287. NTSTATUS
  288. ProcessResumeFromSleepState(
  289. SYSTEM_POWER_STATE PreviousState,
  290. PFDO_DATA DeviceExtension
  291. )
  292. /*++
  293. Routine Description:
  294. Arguments:
  295. Return Value:
  296. --*/
  297. {
  298. DebugEnter();
  299. //
  300. // if we are resuming from Hibernate, and this is an Acpi 2.0 system,
  301. // we must re-claim perf state and cstate control from the bios.
  302. //
  303. if (PreviousState == PowerSystemHibernate) {
  304. if (DeviceExtension->PssPackage) {
  305. AssumeProcessorPerformanceControl();
  306. }
  307. if (DeviceExtension->CstPresent) {
  308. AssumeCStateControl();
  309. }
  310. }
  311. //
  312. // restore previous state
  313. //
  314. return RestoreToSavedPerformanceState(DeviceExtension);
  315. }
  316. NTSTATUS
  317. ProcessSuspendToSleepState(
  318. SYSTEM_POWER_STATE TargetState,
  319. PFDO_DATA DeviceExtension
  320. )
  321. /*++
  322. Routine Description:
  323. Arguments:
  324. Return Value:
  325. --*/
  326. {
  327. DebugEnter();
  328. //
  329. // save current state, transition to lowest non-throttled perf state
  330. //
  331. return SaveCurrentStateGoToLowVolts(DeviceExtension);
  332. }
  333. //
  334. // Legacy function that must have a stub.
  335. //
  336. NTSTATUS
  337. InitializeNonAcpiPerformanceStates(
  338. IN PFDO_DATA DeviceExtension
  339. )
  340. /*++
  341. Routine Description:
  342. The generic processor driver doesn't have non-ACPI performance states.
  343. Arguments:
  344. FdoData - pointer to the device extension
  345. Return Value:
  346. NT status code
  347. --*/
  348. {
  349. return STATUS_NOT_FOUND;
  350. }
  351. NTSTATUS
  352. AcpiLegacyPerfStateTransition(
  353. IN PFDO_DATA DeviceExtension,
  354. IN ULONG State
  355. )
  356. /*++
  357. Routine Description:
  358. The generic processor driver doesn't have non-ACPI performance states.
  359. Arguments:
  360. State - Target State
  361. Return Value:
  362. NT Status
  363. --*/
  364. {
  365. TRAP();
  366. return STATUS_NOT_FOUND;
  367. }
  368. NTSTATUS
  369. GetLegacyMaxProcFrequency(
  370. OUT PULONG CpuSpeed
  371. )
  372. /*++
  373. Routine Description:
  374. Arguments:
  375. Return Value:
  376. --*/
  377. {
  378. TRAP();
  379. return STATUS_NOT_FOUND;
  380. }