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.

349 lines
10 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ixinfo.c
  5. Abstract:
  6. Author:
  7. Ken Reneris (kenr) 08-Aug-1994
  8. Environment:
  9. Kernel mode only.
  10. Revision History:
  11. --*/
  12. #include "halp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE,HaliQuerySystemInformation)
  15. #pragma alloc_text(PAGE,HaliSetSystemInformation)
  16. #pragma alloc_text(INIT,HalInitSystemPhase2)
  17. #endif
  18. //
  19. // NUMA Information.
  20. //
  21. extern PVOID HalpAcpiSrat;
  22. NTSTATUS
  23. HalpGetAcpiStaticNumaTopology(
  24. HAL_NUMA_TOPOLOGY_INTERFACE * NumaInfo
  25. );
  26. NTSTATUS
  27. HaliQuerySystemInformation(
  28. IN HAL_QUERY_INFORMATION_CLASS InformationClass,
  29. IN ULONG BufferSize,
  30. OUT PVOID Buffer,
  31. OUT PULONG ReturnedLength
  32. )
  33. {
  34. NTSTATUS Status;
  35. PVOID InternalBuffer;
  36. ULONG Length, PlatformProperties;
  37. union {
  38. HAL_POWER_INFORMATION PowerInf;
  39. HAL_PROCESSOR_SPEED_INFORMATION ProcessorInf;
  40. HAL_ERROR_INFO ErrorInfo;
  41. HAL_DISPLAY_BIOS_INFORMATION DisplayBiosInf;
  42. HAL_PLATFORM_INFORMATION PlatformInfo;
  43. } U;
  44. BOOLEAN bUseFrameBufferCaching;
  45. PAGED_CODE();
  46. Status = STATUS_SUCCESS;
  47. *ReturnedLength = 0;
  48. Length = 0;
  49. switch (InformationClass) {
  50. case HalFrameBufferCachingInformation:
  51. Status = HalpGetPlatformProperties(&PlatformProperties);
  52. if (NT_SUCCESS(Status) &&
  53. (PlatformProperties & IPPT_DISABLE_WRITE_COMBINING)) {
  54. bUseFrameBufferCaching = FALSE;
  55. } else {
  56. //
  57. // Note - we want to return TRUE here to enable USWC in all
  58. // cases except in a "Shared Memory Cluster" machine.
  59. //
  60. Status = STATUS_SUCCESS;
  61. bUseFrameBufferCaching = TRUE;
  62. }
  63. InternalBuffer = &bUseFrameBufferCaching;
  64. Length = sizeof (BOOLEAN);
  65. break;
  66. case HalMcaLogInformation:
  67. Status = HalpGetMcaLog( Buffer, BufferSize, ReturnedLength );
  68. break;
  69. case HalCmcLogInformation:
  70. Status = HalpGetCmcLog( Buffer, BufferSize, ReturnedLength );
  71. break;
  72. case HalCpeLogInformation:
  73. Status = HalpGetCpeLog( Buffer, BufferSize, ReturnedLength );
  74. break;
  75. case HalErrorInformation:
  76. InternalBuffer = &U.ErrorInfo;
  77. if ( Buffer && (BufferSize > sizeof(U.ErrorInfo.Version)) ) {
  78. U.ErrorInfo.Version = ((PHAL_ERROR_INFO)Buffer)->Version;
  79. Status = HalpGetMceInformation(&U.ErrorInfo, &Length);
  80. }
  81. else {
  82. Status = STATUS_INVALID_PARAMETER;
  83. }
  84. break;
  85. case HalDisplayBiosInformation:
  86. InternalBuffer = &U.DisplayBiosInf;
  87. Length = sizeof(U.DisplayBiosInf);
  88. U.DisplayBiosInf = HalpGetDisplayBiosInformation ();
  89. break;
  90. case HalProcessorSpeedInformation:
  91. RtlZeroMemory (&U.ProcessorInf, sizeof(HAL_PROCESSOR_SPEED_INFORMATION));
  92. // U.ProcessorInf.MaximumProcessorSpeed = HalpCPUMHz;
  93. // U.ProcessorInf.CurrentAvailableSpeed = HalpCPUMHz;
  94. // U.ProcessorInf.ConfiguredSpeedLimit = HalpCPUMHz;
  95. U.ProcessorInf.ProcessorSpeed = HalpCPUMHz;
  96. InternalBuffer = &U.ProcessorInf;
  97. Length = sizeof (HAL_PROCESSOR_SPEED_INFORMATION);
  98. break;
  99. case HalProfileSourceInformation:
  100. Status = HalpProfileSourceInformation (
  101. Buffer,
  102. BufferSize,
  103. ReturnedLength);
  104. return Status;
  105. break;
  106. case HalNumaTopologyInterface:
  107. if (BufferSize == sizeof(HAL_NUMA_TOPOLOGY_INTERFACE)) {
  108. Status = STATUS_INVALID_LEVEL;
  109. if (HalpAcpiSrat) {
  110. Status = HalpGetAcpiStaticNumaTopology(Buffer);
  111. if (NT_SUCCESS(Status)) {
  112. *ReturnedLength = sizeof(HAL_NUMA_TOPOLOGY_INTERFACE);
  113. }
  114. break;
  115. }
  116. } else {
  117. //
  118. // Buffer size is wrong, we could return valid data
  119. // if the buffer is too big,.... but instead we will
  120. // use this as an indication that we're not compatible
  121. // with the kernel.
  122. //
  123. Status = STATUS_INFO_LENGTH_MISMATCH;
  124. }
  125. break;
  126. case HalPartitionIpiInterface:
  127. //
  128. // Some platforms generate interrupts in remote partitions
  129. // as part of their shared memory implementation. This is
  130. // accomplished by targetting an IPI at a processor/vector
  131. // in that remote partition. Provide interfaces to enable
  132. // this but make them conditional on presence of IPPT
  133. // table and appropriate bit explicitly enabling this
  134. // functionality. OEM is responsible for ensuring that an
  135. // interrupt isn't sent to a logical processor that isn't
  136. // present.
  137. //
  138. if (BufferSize >= sizeof(HAL_CROSS_PARTITION_IPI_INTERFACE)) {
  139. Status = HalpGetPlatformProperties(&PlatformProperties);
  140. if (NT_SUCCESS(Status) &&
  141. (PlatformProperties & IPPT_ENABLE_CROSS_PARTITION_IPI)) {
  142. Status = HalpGetCrossPartitionIpiInterface(Buffer);
  143. if (NT_SUCCESS(Status)) {
  144. *ReturnedLength = sizeof(HAL_CROSS_PARTITION_IPI_INTERFACE);
  145. }
  146. } else {
  147. Status = STATUS_UNSUCCESSFUL;
  148. }
  149. } else {
  150. Status = STATUS_INFO_LENGTH_MISMATCH;
  151. }
  152. break;
  153. case HalPlatformInformation:
  154. //
  155. // Any platform information that must be exposed to the kernel.
  156. //
  157. if (BufferSize >= sizeof(HAL_PLATFORM_INFORMATION)) {
  158. Status = HalpGetPlatformProperties(&PlatformProperties);
  159. if (NT_SUCCESS(Status)) {
  160. InternalBuffer = &U.PlatformInfo;
  161. Length = sizeof(U.PlatformInfo);
  162. U.PlatformInfo.PlatformFlags = PlatformProperties;
  163. }
  164. } else {
  165. Status = STATUS_INFO_LENGTH_MISMATCH;
  166. }
  167. break;
  168. default:
  169. Status = STATUS_INVALID_LEVEL;
  170. break;
  171. }
  172. //
  173. // If non-zero Length copy data to callers buffer
  174. //
  175. if (Length) {
  176. if (BufferSize < Length) {
  177. Length = BufferSize;
  178. }
  179. *ReturnedLength = Length;
  180. RtlCopyMemory (Buffer, InternalBuffer, Length);
  181. }
  182. return Status;
  183. } // HaliQuerySystemInformation()
  184. #if !defined(MmIsFunctionPointerValid)
  185. #define MmIsFunctionPointerValid( _Va ) ( MmIsAddressValid((PVOID)(_Va)) && MmIsAddressValid((PVOID)(*((PULONG_PTR)(_Va)))) )
  186. #endif // !MmIsFunctionPointerValid
  187. NTSTATUS
  188. HaliSetSystemInformation (
  189. IN HAL_SET_INFORMATION_CLASS InformationClass,
  190. IN ULONG BufferSize,
  191. IN PVOID Buffer
  192. )
  193. /*++
  194. Routine Description:
  195. The function allows setting of various fields return by
  196. HalQuerySystemInformation.
  197. Arguments:
  198. InformationClass - Information class of the request.
  199. BufferSize - Size of buffer supplied by the caller.
  200. Buffer - Supplies the data to be set.
  201. Return Value:
  202. STATUS_SUCCESS or error.
  203. --*/
  204. {
  205. NTSTATUS Status;
  206. PAGED_CODE();
  207. Status = STATUS_SUCCESS;
  208. switch (InformationClass) {
  209. case HalProfileSourceInterval:
  210. if (BufferSize == sizeof(HAL_PROFILE_SOURCE_INTERVAL)) {
  211. PHAL_PROFILE_SOURCE_INTERVAL sourceInterval =
  212. (PHAL_PROFILE_SOURCE_INTERVAL)Buffer;
  213. Status = HalSetProfileSourceInterval( sourceInterval->Source,
  214. &sourceInterval->Interval
  215. );
  216. }
  217. else {
  218. Status = STATUS_INFO_LENGTH_MISMATCH;
  219. }
  220. break;
  221. case HalProfileSourceInterruptHandler:
  222. //
  223. // Register an Profiling Interrupt Handler.
  224. //
  225. Status = STATUS_INFO_LENGTH_MISMATCH;
  226. if (BufferSize == sizeof(ULONG_PTR)) {
  227. if ( !(HalpFeatureBits & HAL_PERF_EVENTS) ) {
  228. Status = STATUS_NO_SUCH_DEVICE;
  229. }
  230. else if ( !MmIsFunctionPointerValid(Buffer) ) {
  231. Status = STATUS_INVALID_ADDRESS;
  232. }
  233. else {
  234. Status = (NTSTATUS)KiIpiGenericCall( HalpSetProfileInterruptHandler, *(PULONG_PTR)Buffer );
  235. }
  236. }
  237. break;
  238. case HalKernelErrorHandler:
  239. Status = HalpMceRegisterKernelDriver( (PKERNEL_ERROR_HANDLER_INFO) Buffer, BufferSize );
  240. break;
  241. case HalMcaRegisterDriver:
  242. Status = HalpMcaRegisterDriver(
  243. (PMCA_DRIVER_INFO) Buffer // Info about registering driver
  244. );
  245. break;
  246. case HalCmcRegisterDriver:
  247. Status = HalpCmcRegisterDriver(
  248. (PCMC_DRIVER_INFO) Buffer // Info about registering driver
  249. );
  250. break;
  251. case HalCpeRegisterDriver:
  252. Status = HalpCpeRegisterDriver(
  253. (PCPE_DRIVER_INFO) Buffer // Info about registering driver
  254. );
  255. break;
  256. case HalMcaLog: // Class requested by MS Machine Check Event Test Team.
  257. Status = HalpSetMcaLog( (PMCA_EXCEPTION) Buffer, BufferSize );
  258. break;
  259. case HalCmcLog: // Class requested by MS Machine Check Event Test Team.
  260. Status = HalpSetCmcLog( (PCMC_EXCEPTION) Buffer, BufferSize );
  261. break;
  262. case HalCpeLog: // Class requested by MS Machine Check Event Test Team.
  263. Status = HalpSetCpeLog( (PCPE_EXCEPTION) Buffer, BufferSize );
  264. break;
  265. default:
  266. Status = STATUS_INVALID_LEVEL;
  267. break;
  268. }
  269. return Status;
  270. } // HaliSetSystemInformation()