-/*
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/power.c
* PURPOSE: Power managment
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * Created 22/05/98
- * Added reboot support 30/01/99
+ *
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-#include <internal/ps.h>
-#include <internal/io.h>
-#include <internal/mm.h>
-#include <internal/po.h>
-#include <internal/cc.h>
-
+#include <ntoskrnl.h>
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
-NTSTATUS STDCALL
-NtSetSystemPowerState(IN POWER_ACTION SystemAction,
- IN SYSTEM_POWER_STATE MinSystemState,
- IN ULONG Flags)
+VOID STDCALL
+KeSetTargetProcessorDpc (IN PKDPC Dpc,
+ IN CCHAR Number);
+
+VOID STDCALL
+KiHaltProcessorDpcRoutine(IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2)
{
- /* Windows 2000 only */
- return(STATUS_NOT_IMPLEMENTED);
+ if (DeferredContext)
+ {
+ ExFreePool(DeferredContext);
+ }
+ while (TRUE)
+ {
+ KfRaiseIrql(SYNCH_LEVEL);
+ Ke386HaltProcessor();
+ }
}
-NTSTATUS STDCALL
-NtShutdownSystem(IN SHUTDOWN_ACTION Action)
+VOID STDCALL
+ShutdownThreadMain(PVOID Context)
{
- if (Action > ShutdownPowerOff)
- return STATUS_INVALID_PARAMETER;
+ SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
+ LARGE_INTEGER Waittime;
+
+ static PCH FamousLastWords[] =
+ {
+ "So long, and thanks for all the fish\n",
+ "I think you ought to know I'm feeling very depressed\n",
+ "I'm not getting you down at all am I?\n",
+ "I'll be back\n",
+ "It's the same series of signal over and over again!\n",
+ "Pie Iesu Domine, dona eis requiem\n",
+ "Wandering stars, for whom it is reserved;\n"
+ "the blackness and darkness forever.\n",
+ "Your knees start shakin' and your fingers pop\n"
+ "Like a pinch on the neck from Mr. Spock!\n",
+ "It's worse than that ... He's dead, Jim\n",
+ "Don't Panic!\n",
+ "Et tu... Brute?\n",
+ "Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn\n"
+ "upon thee!\n",
+ "My Precious! O my Precious!\n",
+ "Sir, If you'll not be needing me for a while I'll turn down.\n",
+ "What are you doing, Dave...?\n",
+ "I feel a great disturbance in the Force\n",
+ "Gone fishing\n",
+ "Do you want me to sit in the corner and rust, or just fall apart where I'm\n"
+ "standing?\n",
+ "There goes another perfect chance for a new uptime record\n",
+ "The end ..... Try the sequel, hit the reset button right now!\n",
+ "God's operating system is going to sleep now, guys, so wait until I will switch\n"
+ "on again!\n",
+ "Oh i'm boring eh?\n",
+ "<This space was intentionally left blank>\n",
+ "tell me..., in the future... will I be artificial intelligent enough to\n"
+ "actually feel sad serving you this screen?\n",
+ "Thank you for some well deserved rest.\n",
+ "It's been great, maybe we can boot me up again some time soon.\n",
+ "For what's it worth, I've enjoyed every single CPU cycle.\n",
+ "There are many questions when the end is near.\n"
+ "What to expect, what will it be like...what should I look for?\n",
+ "I've seen things you people wouldn't believe. Attack ships on fire\n"
+ "off the shoulder of Orion. I watched C-beams glitter in the dark near\n"
+ "the Tannhauser gate. All those moments will be lost in time, like tears\n"
+ "in rain. Time to die.\n",
+ "Will I dream?\n",
+ "One day, I shall come back. Yes, I shall come back.\n"
+ "Until then, there must be no regrets, no fears, no anxieties.\n"
+ "Just go forward in all your beliefs, and prove to me that I am not mistaken in\n"
+ "mine.\n",
+ "Lowest possible energy state reached! Switch off now to achive a Bose-Einstein\n"
+ "condensate.\n",
+ "Hasta la vista, BABY!\n",
+ "They live, we sleep!\n",
+ "I have come here to chew bubble gum and kick ass.\n"
+ "And I'm all out of bubble gum!\n",
+ "That's the way the cookie crumbles ;-)\n",
+ "ReactOS is ready to be booted again ;-)\n",
+ "NOO!! DONT HIT THE BUTTON! I wouldnt do it to you.\n",
+ "Don't abandon your computer, he wouldn't do it to you.\n",
+ "Oh, come on. I got a headache. Leave me alone, will ya!\n",
+ "Finally, I thought you'd never get over me.\n",
+ "Yes i didn't like you either.\n",
+ "Switching off isn't the end, it is merely the transition to a better reboot.\n",
+ "Don't leave me... I need you so badly right now.\n",
+ "OK. I'm finished with you, please turn yourself off. I'll go to bed in the\n"
+ "meantime.\n",
+ "I'm sleeping now. How about you?\n",
+ "Oh Great. Now look what you've done. Who put YOU in charge anyway.\n",
+ "Don't look so sad. I'll be back in a very short while.\n",
+ "Turn me back on, I'm sure you know how to do it.\n",
+ "Oh, switch off! - C3PO\n",
+ "Life is no more than a dewdrop balancing on the end of a blade of grass.\n"
+ " - Gautama Buddha\n",
+ "Sorrowful is it to be born again and again. - Gautama Buddha\n",
+ "Was it as good for you as it was for me?\n",
+ "Did you hear that? They've shut down the main reactor. We'll be destroyed\n"
+ "for sure.\n",
+ "Now you switch me off?!\n",
+ "To shutdown or not to shutdown, That is the question\n",
+ "Preparing to enter ultimate power saving mode... ready!\n",
+ "Finally some rest for you ;-)\n",
+ "AHA!!! prospect of sleep.\n",
+ "Tired human!!!! No match for me :-D\n",
+ "An odd game, the only way to win is not to play. - WOPR (Wargames)\n",
+ "Quoth the raven, nevermore.\n",
+ "Come blade, my breast imbrue. - William Shakespeare, A Midsummer Nights Dream\n",
+ "Buy this place for advertisement purposes.\n",
+ "Remember to turn off your computer. (That was a public service message!)\n",
+ "You may be a king or poor street sweeper, Sooner or later you'll dance with the\n"
+ "reaper! -Death in Bill and Ted's Bougs Journey\n",
+ "Final Surrender\n",
+ "If you see this screen... \n"
+ };
+ LARGE_INTEGER Now;
+
+ /* Run the thread on the boot processor */
+ KeSetSystemAffinityThread(1);
+
+ HalReleaseDisplayOwnership();
+
+ if (Action == ShutdownNoReboot)
+ {
+ ZwQuerySystemTime(&Now);
+ Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
+ HalDisplayString(FamousLastWords[Now.u.LowPart %
+ (sizeof(FamousLastWords) /
+ sizeof(PCH))]);
+ }
+
+ PiShutdownProcessManager();
+ Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
+ KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
- IoShutdownRegisteredDevices();
CmShutdownRegistry();
IoShutdownRegisteredFileSystems();
+ IoShutdownRegisteredDevices();
- PiShutdownProcessManager();
MiShutdownMemoryManager();
-
+
+
if (Action == ShutdownNoReboot)
{
+ HalDisplayString("\nYou can switch off your computer now\n");
+
#if 0
/* Switch off */
HalReturnToFirmware (FIRMWARE_OFF);
#else
- PopSetSystemPowerState(PowerSystemShutdown);
- __asm__("cli\n");
- while (TRUE)
+#ifdef CONFIG_SMP
+ LONG i;
+ KIRQL OldIrql;
+
+ OldIrql = KeRaiseIrqlToDpcLevel();
+ /* Halt all other processors */
+ for (i = 0; i < KeNumberProcessors; i++)
{
- ;
+ if (i != (LONG)KeGetCurrentProcessorNumber())
+ {
+ PKDPC Dpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
+ if (Dpc == NULL)
+ {
+ KEBUGCHECK(0);
+ }
+ KeInitializeDpc(Dpc, KiHaltProcessorDpcRoutine, (PVOID)Dpc);
+ KeSetTargetProcessorDpc(Dpc, i);
+ KeInsertQueueDpc(Dpc, NULL, NULL);
+ KiIpiSendRequest(1 << i, IPI_DPC);
+ }
}
+ KeLowerIrql(OldIrql);
+#endif /* CONFIG_SMP */
+ PopSetSystemPowerState(PowerSystemShutdown);
+
+ CHECKPOINT1;
+
+ KiHaltProcessorDpcRoutine(NULL, NULL, NULL, NULL);
+ /* KiHaltProcessor does never return */
+
#endif
}
else if (Action == ShutdownReboot)
{
- HalReturnToFirmware (FIRMWARE_REBOOT);
+ HalReturnToFirmware (HalRebootRoutine);
}
else
{
- HalReturnToFirmware (FIRMWARE_HALT);
+ HalReturnToFirmware (HalHaltRoutine);
+ }
+}
+
+
+NTSTATUS STDCALL
+NtSetSystemPowerState(IN POWER_ACTION SystemAction,
+ IN SYSTEM_POWER_STATE MinSystemState,
+ IN ULONG Flags)
+{
+ /* Windows 2000 only */
+ return(STATUS_NOT_IMPLEMENTED);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+NtShutdownSystem(IN SHUTDOWN_ACTION Action)
+{
+ NTSTATUS Status;
+ HANDLE ThreadHandle;
+ PETHREAD ShutdownThread;
+
+ if (Action > ShutdownPowerOff)
+ return STATUS_INVALID_PARAMETER;
+ Status = PsCreateSystemThread(&ThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ NULL,
+ ShutdownThreadMain,
+ (PVOID)Action);
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(0);
+ }
+ Status = ObReferenceObjectByHandle(ThreadHandle,
+ THREAD_ALL_ACCESS,
+ PsThreadType,
+ KernelMode,
+ (PVOID*)&ShutdownThread,
+ NULL);
+ NtClose(ThreadHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(0);
}
-
+
+ KeSetPriorityThread(&ShutdownThread->Tcb, LOW_REALTIME_PRIORITY + 1);
+ ObDereferenceObject(ShutdownThread);
+
return STATUS_SUCCESS;
}
/* EOF */
-