f812086c6f131bdf438030ae774669e9cf06c1b4
[reactos.git] / reactos / ntoskrnl / ex / power.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/power.c
6 * PURPOSE: Power managment
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #include <internal/debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 VOID STDCALL
19 KeSetTargetProcessorDpc (IN PKDPC Dpc,
20 IN CCHAR Number);
21
22 VOID STDCALL
23 KiHaltProcessorDpcRoutine(IN PKDPC Dpc,
24 IN PVOID DeferredContext,
25 IN PVOID SystemArgument1,
26 IN PVOID SystemArgument2)
27 {
28 if (DeferredContext)
29 {
30 ExFreePool(DeferredContext);
31 }
32 while (TRUE)
33 {
34 KfRaiseIrql(SYNCH_LEVEL);
35 Ke386HaltProcessor();
36 }
37 }
38
39 VOID STDCALL
40 ShutdownThreadMain(PVOID Context)
41 {
42 SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
43 LARGE_INTEGER Waittime;
44
45 static PCH FamousLastWords[] =
46 {
47 "So long, and thanks for all the fish\n",
48 "I think you ought to know I'm feeling very depressed\n",
49 "I'm not getting you down at all am I?\n",
50 "I'll be back\n",
51 "It's the same series of signal over and over again!\n",
52 "Pie Iesu Domine, dona eis requiem\n",
53 "Wandering stars, for whom it is reserved;\n"
54 "the blackness and darkness forever.\n",
55 "Your knees start shakin' and your fingers pop\n"
56 "Like a pinch on the neck from Mr. Spock!\n",
57 "It's worse than that ... He's dead, Jim\n",
58 "Don't Panic!\n",
59 "Et tu... Brute?\n",
60 "Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn\n"
61 "upon thee!\n",
62 "My Precious! O my Precious!\n",
63 "Sir, If you'll not be needing me for a while I'll turn down.\n",
64 "What are you doing, Dave...?\n",
65 "I feel a great disturbance in the Force\n",
66 "Gone fishing\n",
67 "Do you want me to sit in the corner and rust, or just fall apart where I'm\n"
68 "standing?\n",
69 "There goes another perfect chance for a new uptime record\n",
70 "The end ..... Try the sequel, hit the reset button right now!\n",
71 "God's operating system is going to sleep now, guys, so wait until I will switch\n"
72 "on again!\n",
73 "Oh i'm boring eh?\n",
74 "<This space was intentionally left blank>\n",
75 "tell me..., in the future... will I be artificial intelligent enough to\n"
76 "actually feel sad serving you this screen?\n",
77 "Thank you for some well deserved rest.\n",
78 "It's been great, maybe we can boot me up again some time soon.\n",
79 "For what's it worth, I've enjoyed every single CPU cycle.\n",
80 "There are many questions when the end is near.\n"
81 "What to expect, what will it be like...what should I look for?\n",
82 "I've seen things you people wouldn't believe. Attack ships on fire\n"
83 "off the shoulder of Orion. I watched C-beams glitter in the dark near\n"
84 "the Tannhauser gate. All those moments will be lost in time, like tears\n"
85 "in rain. Time to die.\n",
86 "Will I dream?\n",
87 "One day, I shall come back. Yes, I shall come back.\n"
88 "Until then, there must be no regrets, no fears, no anxieties.\n"
89 "Just go forward in all your beliefs, and prove to me that I am not mistaken in\n"
90 "mine.\n",
91 "Lowest possible energy state reached! Switch off now to achive a Bose-Einstein\n"
92 "condensate.\n",
93 "Hasta la vista, BABY!\n",
94 "They live, we sleep!\n",
95 "I have come here to chew bubble gum and kick ass.\n"
96 "And I'm all out of bubble gum!\n",
97 "That's the way the cookie crumbles ;-)\n",
98 "ReactOS is ready to be booted again ;-)\n",
99 "NOO!! DONT HIT THE BUTTON! I wouldnt do it to you.\n",
100 "Don't abandon your computer, he wouldnt to it to you.\n",
101 "Oh, come on. I got a headache. Leave me alone, will ya!\n",
102 "Finally, I thought you'd never get over me.\n",
103 "Yes i didn't like you either.\n",
104 "Switching off isn't the end, it is merely the transition to a better reboot.\n",
105 "Don't leave me... I need you so badly right now.\n",
106 "OK. I'm finished with you, please turn yourself off. I'll go to bed in the\n"
107 "meantime.\n",
108 "I'm sleeping now. How about you?\n",
109 "Oh Great. Now look what you've done. Who put YOU in charge anyway.\n",
110 "Don't look so sad. I'll be back in a very short while.\n",
111 "Turn me back on, I'm sure you know how to do it.\n",
112 "Oh, switch off! - C3PO\n",
113 "Life is no more than a dewdrop balancing on the end of a blade of grass.\n"
114 " - Gautama Buddha\n",
115 "Sorrowful is it to be born again and again. - Gautama Buddha\n",
116 "Was it as good for you as it was for me?\n",
117 "Did you hear that? They've shut down the main reactor. We'll be destroyed\n"
118 "for sure.\n",
119 "Now you switch me off?!\n",
120 "To shutdown or not to shutdown, That is the question\n",
121 "Preparing to enter ultimate power saving mode... ready!\n",
122 "Finally some rest for you ;-)\n",
123 "AHA!!! prospect of sleep.\n",
124 "Tired human!!!! No match for me :-D\n",
125 "An odd game, the only way to win is not to play. - WOPR (Wargames)\n",
126 "Quoth the raven, nevermore.\n",
127 "Come blade, my breast imbrue. - William Shakespeare, A Midsummer Nights Dream\n",
128 "Buy this place for advertisment purposes.\n",
129 "Remember to turn of your computer. (That was a public service message!)\n",
130 "You may be a king or poor street sweeper, Sooner or later you'll dance with the\n"
131 "reaper! -Death in Bill and Ted's Bougs Journey\n",
132 "Final Surrender\n",
133 "If you see this screen... \n"
134 };
135 LARGE_INTEGER Now;
136
137 /* Run the thread on the boot processor */
138 KeSetSystemAffinityThread(1);
139
140 HalReleaseDisplayOwnership();
141
142 if (Action == ShutdownNoReboot)
143 {
144 ZwQuerySystemTime(&Now);
145 Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
146 HalDisplayString(FamousLastWords[Now.u.LowPart %
147 (sizeof(FamousLastWords) /
148 sizeof(PCH))]);
149 }
150
151 CmShutdownRegistry();
152 IoShutdownRegisteredFileSystems();
153 IoShutdownRegisteredDevices();
154
155 PiShutdownProcessManager();
156 MiShutdownMemoryManager();
157
158 Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
159 KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
160
161 if (Action == ShutdownNoReboot)
162 {
163 HalDisplayString("\nYou can switch off your computer now\n");
164
165 #if 0
166 /* Switch off */
167 HalReturnToFirmware (FIRMWARE_OFF);
168 #else
169 #ifdef CONFIG_SMP
170 LONG i;
171 KIRQL OldIrql;
172
173 OldIrql = KeRaiseIrqlToDpcLevel();
174 /* Halt all other processors */
175 for (i = 0; i < KeNumberProcessors; i++)
176 {
177 if (i != (LONG)KeGetCurrentProcessorNumber())
178 {
179 PKDPC Dpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
180 if (Dpc == NULL)
181 {
182 KEBUGCHECK(0);
183 }
184 KeInitializeDpc(Dpc, KiHaltProcessorDpcRoutine, (PVOID)Dpc);
185 KeSetTargetProcessorDpc(Dpc, i);
186 KeInsertQueueDpc(Dpc, NULL, NULL);
187 KiIpiSendRequest(1 << i, IPI_DPC);
188 }
189 }
190 KeLowerIrql(OldIrql);
191 #endif /* CONFIG_SMP */
192 PopSetSystemPowerState(PowerSystemShutdown);
193
194 CHECKPOINT1;
195
196 KiHaltProcessorDpcRoutine(NULL, NULL, NULL, NULL);
197 /* KiHaltProcessor does never return */
198
199 #endif
200 }
201 else if (Action == ShutdownReboot)
202 {
203 HalReturnToFirmware (HalRebootRoutine);
204 }
205 else
206 {
207 HalReturnToFirmware (HalHaltRoutine);
208 }
209 }
210
211
212 NTSTATUS STDCALL
213 NtSetSystemPowerState(IN POWER_ACTION SystemAction,
214 IN SYSTEM_POWER_STATE MinSystemState,
215 IN ULONG Flags)
216 {
217 /* Windows 2000 only */
218 return(STATUS_NOT_IMPLEMENTED);
219 }
220
221 /*
222 * @implemented
223 */
224 NTSTATUS STDCALL
225 NtShutdownSystem(IN SHUTDOWN_ACTION Action)
226 {
227 NTSTATUS Status;
228 HANDLE ThreadHandle;
229 PETHREAD ShutdownThread;
230
231 if (Action > ShutdownPowerOff)
232 return STATUS_INVALID_PARAMETER;
233 Status = PsCreateSystemThread(&ThreadHandle,
234 THREAD_ALL_ACCESS,
235 NULL,
236 NULL,
237 NULL,
238 ShutdownThreadMain,
239 (PVOID)Action);
240 if (!NT_SUCCESS(Status))
241 {
242 KEBUGCHECK(0);
243 }
244 Status = ObReferenceObjectByHandle(ThreadHandle,
245 THREAD_ALL_ACCESS,
246 PsThreadType,
247 KernelMode,
248 (PVOID*)&ShutdownThread,
249 NULL);
250 NtClose(ThreadHandle);
251 if (!NT_SUCCESS(Status))
252 {
253 KEBUGCHECK(0);
254 }
255
256 KeSetPriorityThread(&ShutdownThread->Tcb, LOW_REALTIME_PRIORITY + 1);
257 ObDereferenceObject(ShutdownThread);
258
259 return STATUS_SUCCESS;
260 }
261
262 /* EOF */