[SHELL-EXPERIMENTS]
[reactos.git] / hal / halx86 / generic / reboot.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/generic/reboot.c
5 * PURPOSE: Reboot functions
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <hal.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 #define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000)
17
18 /* PRIVATE FUNCTIONS *********************************************************/
19
20 VOID
21 NTAPI
22 HalpWriteResetCommand(VOID)
23 {
24 /* Generate RESET signal via keyboard controller */
25 WRITE_PORT_UCHAR((PUCHAR)0x64, 0xFE);
26 };
27
28 VOID
29 NTAPI
30 HalpReboot(VOID)
31 {
32 UCHAR Data;
33 PVOID ZeroPageMapping;
34 PHARDWARE_PTE Pte;
35
36 /* Get a PTE in the HAL reserved region */
37 ZeroPageMapping = (PVOID)(0xFFC00000 + PAGE_SIZE);
38 Pte = GetPteAddress(ZeroPageMapping);
39
40 /* Make it valid and map it to the first physical page */
41 Pte->Valid = 1;
42 Pte->Write = 1;
43 Pte->Owner = 1;
44 Pte->PageFrameNumber = 0;
45
46 /* Flush the TLB by resetting CR3 */
47 __writecr3(__readcr3());
48
49 /* Enable warm reboot */
50 ((PUSHORT)ZeroPageMapping)[0x239] = 0x1234;
51
52 /* Lock CMOS Access (and disable interrupts) */
53 HalpAcquireCmosSpinLock();
54
55 /* Setup control register B */
56 WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0B);
57 KeStallExecutionProcessor(1);
58
59 /* Read periodic register and clear the interrupt enable */
60 Data = READ_PORT_UCHAR((PUCHAR)0x71);
61 WRITE_PORT_UCHAR((PUCHAR)0x71, Data & ~0x40);
62 KeStallExecutionProcessor(1);
63
64 /* Setup control register A */
65 WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0A);
66 KeStallExecutionProcessor(1);
67
68 /* Read divider rate and reset it */
69 Data = READ_PORT_UCHAR((PUCHAR)0x71);
70 WRITE_PORT_UCHAR((PUCHAR)0x71, (Data & ~0x9) | 0x06);
71 KeStallExecutionProcessor(1);
72
73 /* Reset neutral CMOS address */
74 WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
75 KeStallExecutionProcessor(1);
76
77 /* Flush write buffers and send the reset command */
78 KeFlushWriteBuffer();
79 HalpWriteResetCommand();
80
81 /* Halt the CPU */
82 __halt();
83 }
84
85 /* PUBLIC FUNCTIONS **********************************************************/
86
87 /*
88 * @implemented
89 */
90 VOID
91 NTAPI
92 HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
93 {
94 /* Check what kind of action this is */
95 switch (Action)
96 {
97 /* All recognized actions */
98 case HalHaltRoutine:
99 case HalRebootRoutine:
100
101 #ifndef _MINIHAL_
102 /* Acquire the display */
103 InbvAcquireDisplayOwnership();
104 #endif
105
106 /* Call the internal reboot function */
107 HalpReboot();
108
109 /* Anything else */
110 default:
111
112 /* Print message and break */
113 DbgPrint("HalReturnToFirmware called!\n");
114 DbgBreakPoint();
115 }
116 }
117
118 /* EOF */