xref: /reactos/hal/halx86/generic/reboot.c (revision 10e7643c)
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 
14 /* PRIVATE FUNCTIONS *********************************************************/
15 
16 static VOID
17 HalpWriteResetCommand(VOID)
18 {
19     /* Generate RESET signal via keyboard controller */
20     WRITE_PORT_UCHAR((PUCHAR)0x64, 0xFE);
21 };
22 
23 DECLSPEC_NORETURN
24 VOID
25 HalpReboot(VOID)
26 {
27     PHYSICAL_ADDRESS PhysicalAddress;
28     UCHAR Data;
29     PVOID ZeroPageMapping;
30 
31     /* Map the first physical page */
32     PhysicalAddress.QuadPart = 0;
33     ZeroPageMapping = HalpMapPhysicalMemory64(PhysicalAddress, 1);
34 
35     /* Enable warm reboot */
36     ((PUSHORT)ZeroPageMapping)[0x239] = 0x1234;
37 
38     /* Lock CMOS Access (and disable interrupts) */
39     HalpAcquireCmosSpinLock();
40 
41     /* Setup control register B */
42     WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0B);
43     KeStallExecutionProcessor(1);
44 
45     /* Read periodic register and clear the interrupt enable */
46     Data = READ_PORT_UCHAR((PUCHAR)0x71);
47     WRITE_PORT_UCHAR((PUCHAR)0x71, Data & ~0x40);
48     KeStallExecutionProcessor(1);
49 
50     /* Setup control register A */
51     WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0A);
52     KeStallExecutionProcessor(1);
53 
54     /* Read divider rate and reset it */
55     Data = READ_PORT_UCHAR((PUCHAR)0x71);
56     WRITE_PORT_UCHAR((PUCHAR)0x71, (Data & ~0x9) | 0x06);
57     KeStallExecutionProcessor(1);
58 
59     /* Reset neutral CMOS address */
60     WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
61     KeStallExecutionProcessor(1);
62 
63     /* Flush write buffers and send the reset command */
64     KeFlushWriteBuffer();
65     HalpWriteResetCommand();
66 
67     /* Halt the CPU */
68     __halt();
69     UNREACHABLE;
70 }
71 
72 /* PUBLIC FUNCTIONS **********************************************************/
73 
74 #ifndef _MINIHAL_
75 /*
76  * @implemented
77  */
78 VOID
79 NTAPI
80 HalReturnToFirmware(
81     _In_ FIRMWARE_REENTRY Action)
82 {
83     /* Check what kind of action this is */
84     switch (Action)
85     {
86         /* All recognized actions */
87         case HalHaltRoutine:
88         case HalPowerDownRoutine:
89         case HalRestartRoutine:
90         case HalRebootRoutine:
91         {
92             /* Acquire the display */
93             InbvAcquireDisplayOwnership();
94 
95             /* Call the internal reboot function */
96             HalpReboot();
97         }
98 
99         /* Anything else */
100         default:
101         {
102             /* Print message and break */
103             DbgPrint("HalReturnToFirmware called!\n");
104             DbgBreakPoint();
105         }
106     }
107 }
108 #endif // _MINIHAL_
109 
110 /* EOF */
111