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.

276 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ixreboot.c
  5. Abstract:
  6. Provides the interface to the firmware for x86. Since there is no
  7. firmware to speak of on x86, this is just reboot support.
  8. Author:
  9. John Vert (jvert) 12-Aug-1991
  10. Revision History:
  11. --*/
  12. //
  13. // This module is compatible with PAE mode and therefore treats physical
  14. // addresses as 64-bit entities.
  15. //
  16. #if !defined(_PHYS64_)
  17. #define _PHYS64_
  18. #endif
  19. #include "halp.h"
  20. #include "pci.h"
  21. #ifdef ACPI_HAL
  22. #include "acpitabl.h"
  23. #include "xxacpi.h"
  24. extern UCHAR HalpPiix4;
  25. #endif
  26. //
  27. // Defines to let us diddle the CMOS clock and the keyboard
  28. //
  29. #define CMOS_CTRL (PUCHAR )0x70
  30. #define CMOS_DATA (PUCHAR )0x71
  31. #define RESET 0xfe
  32. #define KEYBPORT (PUCHAR )0x64
  33. //
  34. // Private function prototypes
  35. //
  36. VOID
  37. HalpWriteResetCommand(
  38. VOID
  39. )
  40. /*++
  41. Routine Description:
  42. This procedure issues a reset command to the system to cause a warm boot.
  43. It either uses the ACPI defined reset register or the keyboard controller.
  44. N.B.
  45. Will NOT return.
  46. --*/
  47. {
  48. #ifdef ACPI_HAL
  49. PCI_SLOT_NUMBER slot;
  50. PUCHAR ResetAddress;
  51. //
  52. // if the system supports the ACPI specified RESET_REG capability we
  53. // will use that.
  54. //
  55. if ((HalpFixedAcpiDescTable.Header.Revision > 1) &&
  56. (HalpFixedAcpiDescTable.flags & RESET_CAP)
  57. #if !defined(NT_UP)
  58. //
  59. // to be safer on MP systems, we will only use RESET_REG if the
  60. // system is legacy free. On UP systems this is not necessary
  61. // because we've already tested systems with this functionality.
  62. // MP systems have not been tested extensively and we don't want
  63. // false positives where systems are using this functionality and
  64. // failing. in the next major release this change can be removed.
  65. //
  66. && (!(HalpFixedAcpiDescTable.boot_arch & I8042))
  67. #endif
  68. ) {
  69. switch (HalpFixedAcpiDescTable.reset_reg.AddressSpaceID) {
  70. case 0: // Memory
  71. ResetAddress =
  72. HalpMapPhysicalMemoryWriteThrough(HalpFixedAcpiDescTable.reset_reg.Address, 1);
  73. WRITE_REGISTER_UCHAR(ResetAddress,
  74. HalpFixedAcpiDescTable.reset_val);
  75. break;
  76. case 1: // I/O
  77. WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)HalpFixedAcpiDescTable.reset_reg.Address.LowPart,
  78. HalpFixedAcpiDescTable.reset_val);
  79. break;
  80. case 2: // PCI Config
  81. slot.u.AsULONG = 0;
  82. slot.u.bits.DeviceNumber =
  83. HalpFixedAcpiDescTable.reset_reg.Address.HighPart;
  84. slot.u.bits.FunctionNumber =
  85. HalpFixedAcpiDescTable.reset_reg.Address.LowPart >> 16;
  86. HalSetBusDataByOffset(PCIBus,
  87. 0,
  88. slot.u.AsULONG,
  89. &HalpFixedAcpiDescTable.reset_val,
  90. HalpFixedAcpiDescTable.reset_reg.Address.LowPart & 0xff,
  91. 1);
  92. break;
  93. }
  94. }
  95. #endif
  96. //
  97. // If we return, send the reset command to the keyboard controller
  98. //
  99. WRITE_PORT_UCHAR(KEYBPORT, RESET);
  100. }
  101. VOID
  102. HalpReboot (
  103. VOID
  104. )
  105. /*++
  106. Routine Description:
  107. This procedure resets the CMOS clock to the standard timer settings
  108. so the bios will work, and then issues a reset command to the keyboard
  109. to cause a warm boot.
  110. It is very machine dependent, this implementation is intended for
  111. PC-AT like machines.
  112. This code copied from the "old debugger" sources.
  113. N.B.
  114. Will NOT return.
  115. --*/
  116. {
  117. UCHAR Scratch;
  118. PUSHORT Magic;
  119. PHYSICAL_ADDRESS zeroPhysical;
  120. //
  121. // By sticking 0x1234 at physical location 0x472, we can bypass the
  122. // memory check after a reboot.
  123. //
  124. zeroPhysical.QuadPart = 0;
  125. Magic = HalpMapPhysicalMemoryWriteThrough(zeroPhysical, 1);
  126. if (Magic) {
  127. Magic[0x472 / sizeof(USHORT)] = 0x1234;
  128. }
  129. //
  130. // Turn off interrupts
  131. //
  132. HalpAcquireCmosSpinLock();
  133. HalpDisableInterrupts();
  134. //
  135. // Reset the cmos clock to a standard value
  136. // (We are setting the periodic interrupt control on the MC147818)
  137. //
  138. //
  139. // Disable periodic interrupt
  140. //
  141. WRITE_PORT_UCHAR(CMOS_CTRL, 0x0b); // Set up for control reg B.
  142. KeStallExecutionProcessor(1);
  143. Scratch = READ_PORT_UCHAR(CMOS_DATA);
  144. KeStallExecutionProcessor(1);
  145. Scratch &= 0xbf; // Clear periodic interrupt enable
  146. WRITE_PORT_UCHAR(CMOS_DATA, Scratch);
  147. KeStallExecutionProcessor(1);
  148. //
  149. // Set "standard" divider rate
  150. //
  151. WRITE_PORT_UCHAR(CMOS_CTRL, 0x0a); // Set up for control reg A.
  152. KeStallExecutionProcessor(1);
  153. Scratch = READ_PORT_UCHAR(CMOS_DATA);
  154. KeStallExecutionProcessor(1);
  155. Scratch &= 0xf0; // Clear rate setting
  156. Scratch |= 6; // Set default rate and divider
  157. WRITE_PORT_UCHAR(CMOS_DATA, Scratch);
  158. KeStallExecutionProcessor(1);
  159. //
  160. // Set a "neutral" cmos address to prevent weirdness
  161. // (Why is this needed? Source this was copied from doesn't say)
  162. //
  163. WRITE_PORT_UCHAR(CMOS_CTRL, 0x15);
  164. KeStallExecutionProcessor(1);
  165. HalpResetAllProcessors();
  166. HalpWriteResetCommand();
  167. HalpHalt();
  168. }
  169. #ifndef ACPI_HAL
  170. VOID
  171. HaliHaltSystem (
  172. VOID
  173. )
  174. /*++
  175. Routine Description:
  176. This procedure is called when the machine has crashed and is to be
  177. halted
  178. N.B.
  179. Will NOT return.
  180. --*/
  181. {
  182. _asm {
  183. cli
  184. hlt
  185. }
  186. }
  187. VOID
  188. HalpCheckPowerButton (
  189. VOID
  190. )
  191. {
  192. }
  193. #endif