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.

569 lines
17 KiB

  1. /*++
  2. Copyright (c) 1991-2000 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. #include "pci.h"
  14. #include "pcip.h"
  15. #ifdef _PNP_POWER_
  16. HAL_CALLBACKS HalCallback;
  17. extern WCHAR rgzSuspendCallbackName[];
  18. VOID
  19. HalInitSystemPhase2 (
  20. VOID
  21. );
  22. VOID
  23. HalpLockSuspendCode (
  24. IN PVOID CallbackContext,
  25. IN PVOID Argument1,
  26. IN PVOID Argument2
  27. );
  28. #endif
  29. NTSTATUS
  30. HalpQueryInstalledBusInformation (
  31. OUT PVOID Buffer,
  32. IN ULONG BufferLength,
  33. OUT PULONG ReturnedLength
  34. );
  35. #ifdef ALLOC_PRAGMA
  36. #pragma alloc_text(PAGE,HaliQuerySystemInformation)
  37. #pragma alloc_text(PAGE,HaliSetSystemInformation)
  38. #pragma alloc_text(INIT,HalInitSystemPhase2)
  39. #ifdef _PNP_POWER_
  40. #pragma alloc_text(PAGE,HalpLockSuspendCode)
  41. #endif
  42. #endif
  43. //
  44. // HalQueryMcaInterface
  45. //
  46. VOID
  47. HalpMcaLockInterface(
  48. VOID
  49. );
  50. VOID
  51. HalpMcaUnlockInterface(
  52. VOID
  53. );
  54. NTSTATUS
  55. HalpMcaReadRegisterInterface(
  56. IN UCHAR BankNumber,
  57. IN OUT PMCA_EXCEPTION Exception
  58. );
  59. #ifdef ACPI_HAL
  60. extern PHYSICAL_ADDRESS HalpMaxHotPlugMemoryAddress;
  61. #endif
  62. #if defined(ACPI_HAL) && defined(_HALPAE_) && !defined(NT_UP)
  63. extern PVOID HalpAcpiSrat;
  64. NTSTATUS
  65. HalpGetAcpiStaticNumaTopology(
  66. HAL_NUMA_TOPOLOGY_INTERFACE * NumaInfo
  67. );
  68. #endif
  69. HAL_AMLI_BAD_IO_ADDRESS_LIST BadIOAddrList[] =
  70. {
  71. {0x000, 0x10, 0x1, NULL }, // ISA DMA
  72. {0x020, 0x2, 0x0, NULL }, // PIC
  73. {0x040, 0x4, 0x1, NULL }, // Timer1, Referesh, Speaker, Control Word
  74. {0x048, 0x4, 0x1, NULL }, // Timer2, Failsafe
  75. {0x070, 0x2, 0x1, NULL }, // Cmos/NMI enable
  76. {0x074, 0x3, 0x1, NULL }, // Extended Cmos
  77. {0x081, 0x3, 0x1, NULL }, // DMA
  78. {0x087, 0x1, 0x1, NULL }, // DMA
  79. {0x089, 0x1, 0x1, NULL }, // DMA
  80. {0x08a, 0x2, 0x1, NULL }, // DMA
  81. {0x08f, 0x1, 0x1, NULL }, // DMA
  82. {0x090, 0x2, 0x1, NULL }, // Arbritration Control Port, Card Select Feedback
  83. {0x093, 0x2, 0x1, NULL }, // Reserved, System board setup
  84. {0x096, 0x2, 0x1, NULL }, // POS channel select
  85. {0x0A0, 0x2, 0x0, NULL }, // Cascaded PIC
  86. {0x0C0, 0x20, 0x1, NULL }, // ISA DMA
  87. {0x4D0, 0x2, 0x0, NULL }, // Edge, level control registers for PIC
  88. {0xCF8, 0x8, 0x1, &HaliHandlePCIConfigSpaceAccess}, // PCI Config Space Access Pair
  89. {0x0, 0x0, 0x0, NULL }
  90. };
  91. VOID
  92. HalInitSystemPhase2 (
  93. VOID
  94. )
  95. {
  96. #ifdef _PNP_POWER_
  97. OBJECT_ATTRIBUTES ObjectAttributes;
  98. NTSTATUS Status;
  99. UNICODE_STRING unicodeString;
  100. PCALLBACK_OBJECT CallbackObject;
  101. //
  102. // Create hal callbacks
  103. //
  104. InitializeObjectAttributes(
  105. &ObjectAttributes,
  106. NULL,
  107. OBJ_CASE_INSENSITIVE,
  108. NULL,
  109. NULL
  110. );
  111. ExCreateCallback (&HalCallback.SetSystemInformation, &ObjectAttributes, TRUE, TRUE);
  112. ExCreateCallback (&HalCallback.BusCheck, &ObjectAttributes, TRUE, TRUE);
  113. //
  114. // Connect to suspend callback to lock hal hibaration code
  115. //
  116. RtlInitUnicodeString(&unicodeString, rgzSuspendCallbackName);
  117. InitializeObjectAttributes(
  118. &ObjectAttributes,
  119. &unicodeString,
  120. OBJ_CASE_INSENSITIVE,
  121. NULL,
  122. NULL
  123. );
  124. Status = ExCreateCallback (&CallbackObject, &ObjectAttributes, FALSE, FALSE);
  125. if (NT_SUCCESS(Status)) {
  126. ExRegisterCallback (
  127. CallbackObject,
  128. HalpLockSuspendCode,
  129. NULL
  130. );
  131. ObDereferenceObject (CallbackObject);
  132. }
  133. #endif
  134. }
  135. NTSTATUS
  136. HaliQuerySystemInformation(
  137. IN HAL_QUERY_INFORMATION_CLASS InformationClass,
  138. IN ULONG BufferSize,
  139. OUT PVOID Buffer,
  140. OUT PULONG ReturnedLength
  141. )
  142. {
  143. NTSTATUS Status;
  144. PVOID InternalBuffer;
  145. ULONG Length;
  146. union {
  147. HAL_POWER_INFORMATION PowerInf;
  148. HAL_PROCESSOR_SPEED_INFORMATION ProcessorInf;
  149. MCA_EXCEPTION McaException;
  150. HAL_ERROR_INFO ErrorInfo;
  151. HAL_DISPLAY_BIOS_INFORMATION DisplayBiosInf;
  152. } U;
  153. BOOLEAN bUseFrameBufferCaching;
  154. PAGED_CODE();
  155. Status = STATUS_SUCCESS;
  156. *ReturnedLength = 0;
  157. Length = 0;
  158. switch (InformationClass) {
  159. #ifndef ACPI_HAL
  160. case HalInstalledBusInformation:
  161. Status = HalpQueryInstalledBusInformation (
  162. Buffer,
  163. BufferSize,
  164. ReturnedLength
  165. );
  166. break;
  167. #endif
  168. case HalFrameBufferCachingInformation:
  169. // Note - we want to return TRUE here to enable USWC in all
  170. // cases except in a "Shared Memory Cluster" machine.
  171. bUseFrameBufferCaching = TRUE;
  172. InternalBuffer = &bUseFrameBufferCaching;
  173. Length = sizeof (BOOLEAN);
  174. break;
  175. case HalMcaLogInformation:
  176. case HalCmcLogInformation:
  177. InternalBuffer = &U.McaException;
  178. Status = HalpGetMcaLog ((PMCA_EXCEPTION)Buffer,
  179. BufferSize,
  180. ReturnedLength);
  181. break;
  182. case HalErrorInformation:
  183. InternalBuffer = &U.ErrorInfo;
  184. Length = sizeof(HAL_ERROR_INFO);
  185. U.ErrorInfo.Version = ((PHAL_ERROR_INFO)Buffer)->Version;
  186. Status = HalpGetMceInformation( &U.ErrorInfo, &Length );
  187. break;
  188. case HalDisplayBiosInformation:
  189. InternalBuffer = &U.DisplayBiosInf;
  190. Length = sizeof(U.DisplayBiosInf);
  191. U.DisplayBiosInf = HalpGetDisplayBiosInformation ();
  192. break;
  193. #ifdef _PNP_POWER_
  194. case HalPowerInformation:
  195. RtlZeroMemory (&U.PowerInf, sizeof(HAL_POWER_INFORMATION));
  196. InternalBuffer = &U.PowerInf;
  197. Length = sizeof (HAL_POWER_INFORMATION);
  198. break;
  199. case HalProcessorSpeedInformation:
  200. RtlZeroMemory (&U.ProcessorInf, sizeof(HAL_POWER_INFORMATION));
  201. U.ProcessorInf.MaximumProcessorSpeed = 100;
  202. U.ProcessorInf.CurrentAvailableSpeed = 100;
  203. U.ProcessorInf.ConfiguredSpeedLimit = 100;
  204. InternalBuffer = &U.PowerInf;
  205. Length = sizeof (HAL_PROCESSOR_SPEED_INFORMATION);
  206. break;
  207. case HalCallbackInformation:
  208. InternalBuffer = &HalCallback;
  209. Length = sizeof (HAL_CALLBACKS);
  210. break;
  211. #endif
  212. #if defined(_HALPAE_) && !defined(NT_UP)
  213. case HalNumaTopologyInterface:
  214. if ((BufferSize == sizeof(HAL_NUMA_TOPOLOGY_INTERFACE)) &&
  215. (HalPaeEnabled() == TRUE)) {
  216. Status = STATUS_INVALID_LEVEL;
  217. #if defined(ACPI_HAL)
  218. if (HalpAcpiSrat) {
  219. Status = HalpGetAcpiStaticNumaTopology(Buffer);
  220. if (NT_SUCCESS(Status)) {
  221. *ReturnedLength = sizeof(HAL_NUMA_TOPOLOGY_INTERFACE);
  222. }
  223. break;
  224. }
  225. #endif
  226. } else {
  227. //
  228. // Buffer size is wrong, we could return valid data
  229. // if the buffer is too big,.... but instead we will
  230. // use this as an indication that we're not compatible
  231. // with the kernel.
  232. //
  233. Status = STATUS_INFO_LENGTH_MISMATCH;
  234. }
  235. break;
  236. #endif
  237. #if 0
  238. //
  239. // [ChuckL 2002/08/12] This code was used by the kernel to read MCA information
  240. // from a previous bugcheck and write it to the event log. This is now done
  241. // through WMI, so this code is disabled.
  242. //
  243. case HalQueryMcaInterface:
  244. if (BufferSize == sizeof(HAL_MCA_INTERFACE)) {
  245. HAL_MCA_INTERFACE *McaInterface;
  246. McaInterface = (HAL_MCA_INTERFACE *)Buffer;
  247. McaInterface->Lock = HalpMcaLockInterface;
  248. McaInterface->Unlock = HalpMcaUnlockInterface;
  249. McaInterface->ReadRegister = HalpMcaReadRegisterInterface;
  250. *ReturnedLength = sizeof(HAL_MCA_INTERFACE);
  251. Status = STATUS_SUCCESS;
  252. } else {
  253. Status = STATUS_INFO_LENGTH_MISMATCH;
  254. }
  255. break;
  256. #endif
  257. #if defined(_AMD64_)
  258. case HalProfileSourceInformation:
  259. Status = HalpQueryProfileInformation(InformationClass,
  260. BufferSize,
  261. Buffer,
  262. ReturnedLength);
  263. break;
  264. #endif
  265. case HalQueryMaxHotPlugMemoryAddress:
  266. if (BufferSize == sizeof(PHYSICAL_ADDRESS)) {
  267. #ifdef ACPI_HAL
  268. *((PPHYSICAL_ADDRESS) Buffer) = HalpMaxHotPlugMemoryAddress;
  269. *ReturnedLength = sizeof(PHYSICAL_ADDRESS);
  270. Status = STATUS_SUCCESS;
  271. #else
  272. Status = STATUS_NOT_IMPLEMENTED;
  273. #endif
  274. } else {
  275. Status = STATUS_INFO_LENGTH_MISMATCH;
  276. }
  277. break;
  278. case HalQueryAMLIIllegalIOPortAddresses:
  279. {
  280. static HAL_AMLI_BAD_IO_ADDRESS_LIST BadIOAddrList[] =
  281. {
  282. {0x000, 0x10, 0x1, NULL }, // ISA DMA
  283. {0x020, 0x2, 0x0, NULL }, // PIC
  284. {0x040, 0x4, 0x1, NULL }, // Timer1, Referesh, Speaker, Control Word
  285. {0x048, 0x4, 0x1, NULL }, // Timer2, Failsafe
  286. {0x070, 0x2, 0x1, NULL }, // Cmos/NMI enable
  287. {0x074, 0x3, 0x1, NULL }, // Extended Cmos
  288. {0x081, 0x3, 0x1, NULL }, // DMA
  289. {0x087, 0x1, 0x1, NULL }, // DMA
  290. {0x089, 0x1, 0x1, NULL }, // DMA
  291. {0x08a, 0x2, 0x1, NULL }, // DMA
  292. {0x08f, 0x1, 0x1, NULL }, // DMA
  293. {0x090, 0x2, 0x1, NULL }, // Arbritration Control Port, Card Select Feedback
  294. {0x093, 0x2, 0x1, NULL }, // Reserved, System board setup
  295. {0x096, 0x2, 0x1, NULL }, // POS channel select
  296. {0x0A0, 0x2, 0x0, NULL }, // Cascaded PIC
  297. {0x0C0, 0x20, 0x1, NULL }, // ISA DMA
  298. {0x4D0, 0x2, 0x0, NULL }, // Edge, level control registers for PIC
  299. {0xCF8, 0x8, 0x1, &HaliHandlePCIConfigSpaceAccess}, // PCI Config Space Access Pair
  300. {0x0, 0x0, 0x0, NULL }
  301. };
  302. if(BufferSize < sizeof(BadIOAddrList))
  303. {
  304. *ReturnedLength = sizeof(BadIOAddrList);
  305. Status = STATUS_INFO_LENGTH_MISMATCH;
  306. }
  307. else
  308. {
  309. Length = sizeof(BadIOAddrList);
  310. InternalBuffer = BadIOAddrList;
  311. Status = STATUS_SUCCESS;
  312. }
  313. break;
  314. }
  315. default:
  316. Status = STATUS_INVALID_LEVEL;
  317. break;
  318. }
  319. //
  320. // If non-zero Length copy data to callers buffer
  321. //
  322. if (Length) {
  323. if (BufferSize < Length) {
  324. Length = BufferSize;
  325. }
  326. *ReturnedLength = Length;
  327. RtlCopyMemory (Buffer, InternalBuffer, Length);
  328. }
  329. return Status;
  330. }
  331. NTSTATUS
  332. HaliSetSystemInformation (
  333. IN HAL_SET_INFORMATION_CLASS InformationClass,
  334. IN ULONG BufferSize,
  335. IN PVOID Buffer
  336. )
  337. {
  338. NTSTATUS Status;
  339. PAGED_CODE();
  340. Status = STATUS_SUCCESS;
  341. switch (InformationClass) {
  342. case HalKernelErrorHandler:
  343. Status = HalpMceRegisterKernelDriver( (PKERNEL_ERROR_HANDLER_INFO) Buffer, BufferSize );
  344. break;
  345. case HalMcaRegisterDriver:
  346. Status = HalpMcaRegisterDriver(
  347. (PMCA_DRIVER_INFO) Buffer // Info about registering driver
  348. );
  349. break;
  350. default:
  351. Status = STATUS_INVALID_LEVEL;
  352. break;
  353. }
  354. return Status;
  355. }
  356. #ifdef _PNP_POWER_
  357. VOID
  358. HalpLockSuspendCode (
  359. IN PVOID CallbackContext,
  360. IN PVOID Argument1,
  361. IN PVOID Argument2
  362. )
  363. {
  364. static PVOID CodeLock;
  365. switch ((ULONG) Argument1) {
  366. case 0:
  367. //
  368. // Lock code down which might be needed to perform a suspend
  369. //
  370. ASSERT (CodeLock == NULL);
  371. CodeLock = MmLockPagableCodeSection (&HaliSuspendHibernateSystem);
  372. break;
  373. case 1:
  374. //
  375. // Release the code lock
  376. //
  377. MmUnlockPagableImageSection (CodeLock);
  378. CodeLock = NULL;
  379. break;
  380. }
  381. }
  382. #endif
  383. /*** HaliHandlePCIConfigSpaceAccess - Check to see if the Firmware is attempting to
  384. * access to PCI Config space. If so, intercept
  385. * the read/write call and do it using HAL API's.
  386. * This way we can make these calls sync.
  387. *
  388. * ENTRY
  389. * BOOLEAN Read - TRUE iff read
  390. * ULONG Addr - Address to do the operation on
  391. * ULONG Size - Size of data
  392. * PULONG pData - Pointer to the data buffer.
  393. *
  394. * EXIT
  395. * STATUS_SUCCESS if we do the PCI config space access.
  396. */
  397. NTSTATUS HaliHandlePCIConfigSpaceAccess( BOOLEAN Read,
  398. ULONG Addr,
  399. ULONG Size,
  400. PULONG pData
  401. )
  402. {
  403. static PCI_TYPE1_CFG_BITS CF8_Data = {0};
  404. static BOOLEAN CF8_Called = FALSE;
  405. NTSTATUS Status = STATUS_SUCCESS;
  406. if(Addr == 0xCF8)
  407. {
  408. CF8_Data.u.AsULONG = *pData;
  409. CF8_Called = TRUE;
  410. }
  411. else if(Addr >= 0xCFC && Addr <= 0xCFF)
  412. {
  413. if(CF8_Called)
  414. {
  415. ULONG Offset = 0;
  416. ULONG Return = 0;
  417. PCI_SLOT_NUMBER SlotNumber = {0};
  418. Offset = (CF8_Data.u.bits.RegisterNumber << 2) + (Addr - 0xCFC);
  419. SlotNumber.u.bits.FunctionNumber = CF8_Data.u.bits.FunctionNumber;
  420. SlotNumber.u.bits.DeviceNumber = CF8_Data.u.bits.DeviceNumber;
  421. if (Read)
  422. {
  423. //
  424. // Do PCI config space read through HAL
  425. //
  426. Return = HaliPciInterfaceReadConfig( NULL,
  427. (UCHAR)CF8_Data.u.bits.BusNumber,
  428. SlotNumber.u.AsULONG,
  429. pData,
  430. Offset,
  431. Size
  432. );
  433. }
  434. else
  435. {
  436. //
  437. // Do PCI config space write through HAL
  438. //
  439. Return = HaliPciInterfaceWriteConfig( NULL,
  440. (UCHAR)CF8_Data.u.bits.BusNumber,
  441. SlotNumber.u.AsULONG,
  442. pData,
  443. Offset,
  444. Size
  445. );
  446. }
  447. }
  448. else
  449. {
  450. Status = STATUS_UNSUCCESSFUL;
  451. }
  452. }
  453. else
  454. {
  455. Status = STATUS_UNSUCCESSFUL;
  456. }
  457. return Status;
  458. }