windows-nt/Source/XPSP1/NT/base/ntos/inc/po.h
2020-09-26 16:20:57 +08:00

606 lines
15 KiB
C

/*++ BUILD Version: 0001 // Increment this if a change has global effects
Copyright (c) 1994 Microsoft Corporation
Copyright (c) 1994 International Business Machines Corporation
Module Name:
po.h
Abstract:
This module contains the internal structure definitions and APIs used by
the NT Power Management.
Author:
Ken Reneris (kenr) 19-July-1994
N. Yoshiyama [IBM Corp.] 01-Mar-1994
Revision History:
--*/
#ifndef _PO_
#define _PO_
#include "xpress.h" // XPRESS declarations
//
// XPRESS compression header (LZNT1 will treat it as erroneous block)
//
#define XPRESS_HEADER_STRING "\x81\x81xpress"
#define XPRESS_HEADER_STRING_SIZE 8
//
// size of header (shall be at least 16 and be multiple of XPRESS_ALIGNMENT)
//
#define XPRESS_HEADER_SIZE 32
//
// max # of pages Xpress may handle at once
//
#define XPRESS_MAX_PAGES (XPRESS_MAX_BLOCK >> PAGE_SHIFT)
//
// max size of block aligned on page boundary
//
#define XPRESS_MAX_SIZE (XPRESS_MAX_PAGES << PAGE_SHIFT)
#if DBG
VOID
PoPowerTracePrint(
ULONG TracePoint,
ULONG_PTR Caller,
ULONG_PTR CallerCaller,
ULONG_PTR DeviceObject,
ULONG_PTR Irp,
ULONG_PTR Ios
);
#define PoPowerTrace(TracePoint,DevObj,Arg1,Arg2) \
{\
PVOID pptcCaller; \
PVOID pptcCallerCaller; \
RtlGetCallersAddress(&pptcCaller, &pptcCallerCaller); \
PoPowerTracePrint(TracePoint, (ULONG_PTR)pptcCaller, (ULONG_PTR)pptcCallerCaller, (ULONG_PTR)DevObj, (ULONG_PTR)Arg1, (ULONG_PTR)Arg2); \
}
#else
#define PoPowerTrace(TracePoint,DevObj,Arg1,Arg2)
#endif
#define POWERTRACE_CALL 0x1
#define POWERTRACE_PRESENT 0x2
#define POWERTRACE_STARTNEXT 0x4
#define POWERTRACE_SETSTATE 0x8
#define POWERTRACE_COMPLETE 0x10
VOID
FASTCALL
PoInitializePrcb (
PKPRCB Prcb
);
BOOLEAN
PoInitSystem (
IN ULONG Phase
);
VOID
PoInitDriverServices (
IN ULONG Phase
);
VOID
PoInitHiberServices (
IN BOOLEAN Setup
);
VOID
PoGetDevicePowerState (
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT DEVICE_POWER_STATE *DevicePowerState
);
VOID
PoInitializeDeviceObject (
IN PDEVOBJ_EXTENSION DeviceObjectExtension
);
VOID
PoRunDownDeviceObject (
IN PDEVICE_OBJECT DeviceObject
);
NTKERNELAPI
VOID
PopCleanupPowerState (
IN OUT PUCHAR PowerState
);
#define PoRundownThread(Thread) \
PopCleanupPowerState(&Thread->Tcb.PowerState)
#define PoRundownProcess(Process) \
PopCleanupPowerState(&Process->Pcb.PowerState)
VOID
PoNotifySystemTimeSet (
VOID
);
VOID
PoInvalidateDevicePowerRelations(
PDEVICE_OBJECT DeviceObject
);
VOID
PoShutdownBugCheck (
IN BOOLEAN AllowCrashDump,
IN ULONG BugCheckCode,
IN ULONG_PTR BugCheckParameter1,
IN ULONG_PTR BugCheckParameter2,
IN ULONG_PTR BugCheckParameter3,
IN ULONG_PTR BugCheckParameter4
);
// begin_nthal
NTKERNELAPI
VOID
PoSetHiberRange (
IN PVOID MemoryMap,
IN ULONG Flags,
IN PVOID Address,
IN ULONG_PTR Length,
IN ULONG Tag
);
// memory_range.Type
#define PO_MEM_PRESERVE 0x00000001 // memory range needs preserved
#define PO_MEM_CLONE 0x00000002 // Clone this range
#define PO_MEM_CL_OR_NCHK 0x00000004 // Either clone or do not checksum
#define PO_MEM_DISCARD 0x00008000 // This range to be removed
#define PO_MEM_PAGE_ADDRESS 0x00004000 // Arguments passed are physical pages
// end_nthal
#define PoWakeTimerSupported() \
(PopCapabilities.RtcWake >= PowerSystemSleeping1)
ULONG
PoSimpleCheck (
IN ULONG PatialSum,
IN PVOID StartVa,
IN ULONG_PTR Length
);
BOOLEAN
PoSystemIdleWorker (
IN BOOLEAN IdleWorker
);
VOID
PoVolumeDevice(
IN PDEVICE_OBJECT DeviceObject
);
VOID
PoSetWarmEjectDevice(
IN PDEVICE_OBJECT DeviceObject
) ;
NTSTATUS
PoGetLightestSystemStateForEject(
IN BOOLEAN DockBeingEjected,
IN BOOLEAN HotEjectSupported,
IN BOOLEAN WarmEjectSupported,
OUT PSYSTEM_POWER_STATE LightestSleepState
);
// begin_ntddk begin_wdm begin_ntosp
NTKERNELAPI
VOID
PoSetSystemState (
IN EXECUTION_STATE Flags
);
// begin_ntifs
NTKERNELAPI
PVOID
PoRegisterSystemState (
IN PVOID StateHandle,
IN EXECUTION_STATE Flags
);
// end_ntifs
typedef
VOID
(*PREQUEST_POWER_COMPLETE) (
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus
);
NTKERNELAPI
NTSTATUS
PoRequestPowerIrp (
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PREQUEST_POWER_COMPLETE CompletionFunction,
IN PVOID Context,
OUT PIRP *Irp OPTIONAL
);
NTKERNELAPI
NTSTATUS
PoRequestShutdownEvent (
OUT PVOID *Event
);
NTKERNELAPI
NTSTATUS
PoRequestShutdownWait (
IN PETHREAD Thread
);
// begin_ntifs
NTKERNELAPI
VOID
PoUnregisterSystemState (
IN PVOID StateHandle
);
// begin_nthal
NTKERNELAPI
POWER_STATE
PoSetPowerState (
IN PDEVICE_OBJECT DeviceObject,
IN POWER_STATE_TYPE Type,
IN POWER_STATE State
);
NTKERNELAPI
NTSTATUS
PoCallDriver (
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
);
NTKERNELAPI
VOID
PoStartNextPowerIrp(
IN PIRP Irp
);
NTKERNELAPI
PULONG
PoRegisterDeviceForIdleDetection (
IN PDEVICE_OBJECT DeviceObject,
IN ULONG ConservationIdleTime,
IN ULONG PerformanceIdleTime,
IN DEVICE_POWER_STATE State
);
#define PoSetDeviceBusy(IdlePointer) \
*IdlePointer = 0
//
// \Callback\PowerState values
//
#define PO_CB_SYSTEM_POWER_POLICY 0
#define PO_CB_AC_STATUS 1
#define PO_CB_BUTTON_COLLISION 2
#define PO_CB_SYSTEM_STATE_LOCK 3
#define PO_CB_LID_SWITCH_STATE 4
#define PO_CB_PROCESSOR_POWER_POLICY 5
// end_ntddk end_wdm end_nthal
// Used for queuing work items to be performed at shutdown time. Same
// rules apply as per Ex work queues.
NTKERNELAPI
NTSTATUS
PoQueueShutdownWorkItem(
IN PWORK_QUEUE_ITEM WorkItem
);
// end_ntosp end_ntifs
//
// Broken functions we don't intend to keep supporting. The code backing these
// should be ripped out in NT5.1
//
typedef
VOID
(*PPO_NOTIFY) (
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context,
IN ULONG Type,
IN ULONG Reserved
);
#define PO_NOTIFY_D0 0x00000001
#define PO_NOTIFY_TRANSITIONING_FROM_D0 0x00000002
#define PO_NOTIFY_INVALID 0x80000000
NTKERNELAPI
NTSTATUS
PoRegisterDeviceNotify (
IN PDEVICE_OBJECT DeviceObject,
IN PPO_NOTIFY NotificationFunction,
IN PVOID NotificationContext,
IN ULONG NotificationType,
OUT PDEVICE_POWER_STATE DeviceState,
OUT PVOID *NotificationHandle
);
NTKERNELAPI
NTSTATUS
PoCancelDeviceNotify (
IN PVOID NotificationHandle
);
//
// Callout set state failure notification
//
typedef struct {
NTSTATUS Status;
POWER_ACTION PowerAction;
SYSTEM_POWER_STATE MinState;
ULONG Flags;
} PO_SET_STATE_FAILURE, *PPO_SET_STATE_FAILURE;
//
// Hibernation file layout:
// Page 0 - PO_MEMORY_IMAGE
// Page 1 - Free page array
// Page 2 - KPROCESSOR_CONTEXT
// Page 3 - first memory_range_array page
//
// PO_MEMORY_IMAGE:
// Header in file which contains some information to identify
// the hibernation, as well as a couple of checksums.
//
// Free page array:
// A page full of page numbers which identify 4MBs worth of
// system pages that are not in the restoration image. These
// pages are used by the loader (to keep itself out of the way)
// when restoring the memory image.
//
// KPROCESSOR_CONTEST
// The context of the processor which hibernated the system.
// Rest of page is empty.
//
// memory_range_array
// A page which contains an array of memory_range_array elements
// where element 0 is a Link entry, and all other elements are
// Range entries. The Link entry is used to link to the next
// such page, and to supply a count of the number of Range entries
// in the current page. The range entries each describe one
// physical memory range which needs restoration and its location
// in the file.
//
typedef struct _PO_MEMORY_RANGE_ARRAY {
union {
struct {
PFN_NUMBER PageNo;
PFN_NUMBER StartPage;
PFN_NUMBER EndPage;
ULONG CheckSum;
} Range;
struct {
struct _PO_MEMORY_RANGE_ARRAY *Next;
PFN_NUMBER NextTable;
ULONG CheckSum;
ULONG EntryCount;
} Link;
};
} PO_MEMORY_RANGE_ARRAY, *PPO_MEMORY_RANGE_ARRAY;
#define PO_MAX_RANGE_ARRAY (PAGE_SIZE / sizeof(PO_MEMORY_RANGE_ARRAY))
#define PO_ENTRIES_PER_PAGE (PO_MAX_RANGE_ARRAY-1)
#define PO_IMAGE_SIGNATURE 'rbih'
#define PO_IMAGE_SIGNATURE_WAKE 'ekaw'
#define PO_IMAGE_SIGNATURE_BREAK 'pkrb'
#define PO_IMAGE_SIGNATURE_LINK 'knil'
#define PO_IMAGE_HEADER_PAGE 0
#define PO_FREE_MAP_PAGE 1
#define PO_PROCESSOR_CONTEXT_PAGE 2
#define PO_FIRST_RANGE_TABLE_PAGE 3
#define PO_COMPRESS_CHUNK_SIZE 4096
//
// Perf information
//
typedef struct _PO_HIBER_PERF {
ULONGLONG IoTicks;
ULONGLONG InitTicks;
ULONGLONG CopyTicks;
ULONGLONG StartCount;
ULONG ElapsedTime;
ULONG IoTime;
ULONG CopyTime;
ULONG InitTime;
ULONG PagesWritten;
ULONG PagesProcessed;
ULONG BytesCopied;
ULONG DumpCount;
ULONG FileRuns;
} PO_HIBER_PERF, *PPO_HIBER_PERF;
//
// Define various HiberFlags to control the behavior when restoring
//
#define PO_HIBER_APM_RECONNECT 1
typedef struct {
ULONG Signature;
ULONG Version;
ULONG CheckSum;
ULONG LengthSelf;
PFN_NUMBER PageSelf;
ULONG PageSize;
ULONG ImageType;
LARGE_INTEGER SystemTime;
ULONGLONG InterruptTime;
ULONG FeatureFlags;
UCHAR HiberFlags;
UCHAR spare[3];
ULONG NoHiberPtes;
ULONG_PTR HiberVa;
PHYSICAL_ADDRESS HiberPte;
ULONG NoFreePages;
ULONG FreeMapCheck;
ULONG WakeCheck;
PFN_NUMBER TotalPages;
PFN_NUMBER FirstTablePage;
PFN_NUMBER LastFilePage;
//
// Perf stuff
//
PO_HIBER_PERF PerfInfo;
} PO_MEMORY_IMAGE, *PPO_MEMORY_IMAGE;
typedef struct {
ULONG Signature;
WCHAR Name[1];
} PO_IMAGE_LINK, *PPO_IMAGE_LINK;
//
// Returned by Io system
//
typedef struct _PO_DEVICE_NOTIFY {
LIST_ENTRY Link;
PDEVICE_OBJECT TargetDevice;
BOOLEAN WakeNeeded;
UCHAR OrderLevel;
PDEVICE_OBJECT DeviceObject;
PVOID Node;
PWCHAR DeviceName;
PWCHAR DriverName;
ULONG ChildCount;
ULONG ActiveChild;
} PO_DEVICE_NOTIFY, *PPO_DEVICE_NOTIFY;
//
// A PO_DEVICE_NOTIFY_LEVEL structure holds all the PO_DEVICE_NOTIFY
// structures for a given level. Every PO_DEVICE_NOTIFY is on one of
// the lists. As we send power irps, the notify structure progresses
// through all the lists.
//
typedef struct _PO_NOTIFY_ORDER_LEVEL {
KEVENT LevelReady;
ULONG DeviceCount; // number of devices on this notify level
ULONG ActiveCount; // number of devices until this level is complete
LIST_ENTRY WaitSleep; // waiting for children to complete their Sx irps
LIST_ENTRY ReadySleep; // ready to receive a Sx irp
LIST_ENTRY Pending; // A Sx or S0 irp is outstanding
LIST_ENTRY Complete; // Fully awake.
LIST_ENTRY ReadyS0; // Ready to receive a S0 irp
LIST_ENTRY WaitS0; // waiting for parent to complete their S0 irp
} PO_NOTIFY_ORDER_LEVEL, *PPO_NOTIFY_ORDER_LEVEL;
#define PO_ORDER_NOT_VIDEO 0x0001
#define PO_ORDER_ROOT_ENUM 0x0002
#define PO_ORDER_PAGABLE 0x0004
#define PO_ORDER_MAXIMUM 0x0007
// notify GDI before this order level
#define PO_ORDER_GDI_NOTIFICATION (PO_ORDER_PAGABLE)
typedef struct _PO_DEVICE_NOTIFY_ORDER {
ULONG DevNodeSequence;
PDEVICE_OBJECT *WarmEjectPdoPointer;
PO_NOTIFY_ORDER_LEVEL OrderLevel[PO_ORDER_MAXIMUM+1];
} PO_DEVICE_NOTIFY_ORDER, *PPO_DEVICE_NOTIFY_ORDER;
extern KAFFINITY PoSleepingSummary;
extern BOOLEAN PoEnabled;
extern ULONG PoPowerSequence;
extern BOOLEAN PoPageLockData;
extern KTIMER PoSystemIdleTimer;
extern BOOLEAN PoHiberInProgress;
// PopCapabilities used by some internal macros
extern SYSTEM_POWER_CAPABILITIES PopCapabilities;
extern ULONG PopShutdownCleanly;
// Set this flag to make general clean shutdown-related things happen
// without setting any of the more specific things.
#define PO_CLEAN_SHUTDOWN_GENERAL (0x1)
// PO_CLEAN_SHUTDOWN_PAGING forces unlocked pageable data to become
// unavailable once paging is shut down.
#define PO_CLEAN_SHUTDOWN_PAGING (0x2)
// PO_CLEAN_SHUTDOWN_WORKERS causes the Ex worker threads to be torn
// down at shutdown time (ensuring that their queues are flushed and
// no more work items are posted).
#define PO_CLEAN_SHUTDOWN_WORKERS (0x4)
// PO_CLEAN_SHUTDOWN_REGISTRY causes all open registry keys to be
// dumped to the debugger at shutdown time.
#define PO_CLEAN_SHUTDOWN_REGISTRY (0x8)
// PO_CLEAN_SHUTDOWN_OB causes the object manager namespace to be
// flushed of all permanent objects, and causes ob cleanup to occur.
#define PO_CLEAN_SHUTDOWN_OB (0x10)
// PO_CLEAN_SHUTDOWN_PNP causes PNP to QueryRemove/Remove all the PNP devices
// in the system.
#define PO_CLEAN_SHUTDOWN_PNP (0x20)
// This function returns non-zero if the system should be shut down cleanly.
ULONG
FORCEINLINE
PoCleanShutdownEnabled(
VOID
)
{
return PopShutdownCleanly;
}
// This is the worker queue which po will use for shutdown
#define PO_SHUTDOWN_QUEUE (CriticalWorkQueue)
#endif