123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- /*++
- Copyright (c) 2014 Minoca Corp. All Rights Reserved
- Module Name:
- reset.c
- Abstract:
- This module implements support for rebooting the system.
- Author:
- Evan Green 16-Apr-2014
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/kernel.h>
- #include "hlp.h"
- #include "efi.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- /*++
- Structure Description:
- This structure defines the context passed to a reset system DPC.
- Members:
- ResetType - Stores the reset type to perform.
- Status - Stores the resulting status code.
- --*/
- typedef struct _RESET_SYSTEM_DPC_DATA {
- SYSTEM_RESET_TYPE ResetType;
- KSTATUS Status;
- } RESET_SYSTEM_DPC_DATA, *PRESET_SYSTEM_DPC_DATA;
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- VOID
- HlpResetSystemDpc (
- PDPC Dpc
- );
- KSTATUS
- HlpResetSystem (
- SYSTEM_RESET_TYPE ResetType
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- KSTATUS
- HlResetSystem (
- SYSTEM_RESET_TYPE ResetType
- )
- /*++
- Routine Description:
- This routine resets the system.
- Arguments:
- ResetType - Supplies the desired reset type. If the desired reset type is
- not supported, a cold reset will be attempted.
- Return Value:
- Does not return on success, the system is reset.
- STATUS_INVALID_PARAMETER if an invalid reset type was supplied.
- STATUS_NOT_SUPPORTED if the system cannot be reset.
- STATUS_UNSUCCESSFUL if the system did not reset.
- --*/
- {
- PDPC Dpc;
- RESET_SYSTEM_DPC_DATA DpcData;
- //
- // If this is being called from a hostile environment, just attempt the
- // reset directly.
- //
- if ((ArAreInterruptsEnabled() == FALSE) ||
- (KeGetRunLevel() != RunLevelLow)) {
- return HlpResetSystem(ResetType);
- }
- //
- // Create a DPC so that the reset code runs on processor zero.
- //
- RtlZeroMemory(&DpcData, sizeof(RESET_SYSTEM_DPC_DATA));
- DpcData.ResetType = ResetType;
- DpcData.Status = STATUS_NOT_STARTED;
- Dpc = KeCreateDpc(HlpResetSystemDpc, &DpcData);
- //
- // If DPC creation failed, the system is in a bad way. Skip the niceties
- // go for the reset directly.
- //
- if (Dpc == NULL) {
- return HlpResetSystem(ResetType);
- }
- KeQueueDpcOnProcessor(Dpc, 0);
- //
- // Wait for the DPC to finish.
- //
- KeFlushDpc(Dpc);
- KeDestroyDpc(Dpc);
- return DpcData.Status;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- HlpResetSystemDpc (
- PDPC Dpc
- )
- /*++
- Routine Description:
- This routine implements the reset system DPC that is run on processor zero.
- Arguments:
- Dpc - Supplies a pointer to the DPC that is running.
- Return Value:
- None.
- --*/
- {
- PRESET_SYSTEM_DPC_DATA Data;
- ASSERT((KeGetRunLevel() == RunLevelDispatch) &&
- (KeGetCurrentProcessorNumber() == 0));
- Data = Dpc->UserData;
- Data->Status = HlpResetSystem(Data->ResetType);
- return;
- }
- KSTATUS
- HlpResetSystem (
- SYSTEM_RESET_TYPE ResetType
- )
- /*++
- Routine Description:
- This routine resets the system.
- Arguments:
- ResetType - Supplies the desired reset type. If the desired reset type is
- not supported, a cold reset will be attempted.
- Return Value:
- Does not return on success, the system is reset.
- STATUS_INVALID_PARAMETER if an invalid reset type was supplied.
- STATUS_NOT_SUPPORTED if the system cannot be reset.
- STATUS_UNSUCCESSFUL if the system did not reset.
- --*/
- {
- KSTATUS ArchStatus;
- KSTATUS Status;
- if ((ResetType == SystemResetInvalid) ||
- (ResetType >= SystemResetTypeCount)) {
- return STATUS_INVALID_PARAMETER;
- }
- //
- // If this is an EFI system, try to use firmware services to shut down.
- //
- Status = HlpEfiResetSystem(ResetType);
- //
- // Try some innate tricks to reset. PCs have several of these tricks, other
- // systems have none.
- //
- ArchStatus = HlpArchResetSystem(ResetType);
- if (Status == STATUS_NOT_SUPPORTED) {
- Status = ArchStatus;
- }
- return Status;
- }
|