Leaked source code of windows server 2003
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.

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