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