/*++ Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved Module Name: Processor.h Abstract: Header file for the processor driver modules. Environment: Kernel mode Revision History: Eliyas Yakub Oct 6, 1998 --*/ #ifndef _PROCESSOR_H_ #define _PROCESSOR_H_ #include #include #include #include #include #include #define _NTPOAPI_ #include #undef _NTPOAPI_ #include #include "dbgsys.h" #include "eventlog.h" #include "wmi.h" NTSYSAPI NTSTATUS NTAPI ZwPowerInformation( IN POWER_INFORMATION_LEVEL InformationLevel, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength ); // // CStateFlags // #define CSTATE_FLAGS_REG_KEY L"CStateFlags" #define CSTATE_FLAG_DISABLE_C2 0x2 #define CSTATE_FLAG_DISABLE_C3 0x4 #define CSTATE_FLAG_WIN2K_COMPAT 0x8 // // Definition of Global Flags // #define DISABLE_LEGACY_INTERFACE_FLAG 0x1 #define DISABLE_ACPI20_INTERFACE_FLAG 0x2 #define DISABLE_THROTTLE_STATES 0x4 #define PROCESSOR_GLOBAL_FLAGS_REG_KEY L"HackFlags" #define PROCESSOR_PARAMETERS_REG_PATH L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Processor" #define CPU0_REG_KEY L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0" #define PROCESSOR_POOL_TAG (ULONG) 'rcrP' #define MAX_SUPPORTED_PROCESSORS (sizeof(KAFFINITY) * 8) #define MIN(_a_,_b_) ((_a_) < (_b_) ? (_a_) : (_b_)) #define MAX(_a_,_b_) ((_a_) > (_b_) ? (_a_) : (_b_)) #define MAX_PROCESSOR_VALUE 256 // max uchar #define INVALID_PERF_STATE MAXULONG typedef struct _PROCESSOR_INFO { ULONG ActiveProcessors; ULONG TotalProcessors; UCHAR ProcIdToApicId[MAX_PROCESSOR_VALUE]; UCHAR ApicIdToDevExtIndex[MAX_PROCESSOR_VALUE]; } PROCESSOR_INFO, *PPROCESSOR_INFO; typedef struct _GLOBALS { // // Path to the driver's Services Key in the registry // UNICODE_STRING RegistryPath; PVOID CallbackRegistration; BOOLEAN SingleProcessorProfile; ULONG HackFlags; ULONG CStateFlags; PDRIVER_OBJECT DriverObject; PROCESSOR_INFO ProcInfo; PWCHAR ProcessorBrandString; } GLOBALS; extern GLOBALS Globals; // // These are the states FDO transition to upon // receiving a specific PnP Irp. Refer to the PnP Device States // diagram in DDK documentation for better understanding. // typedef enum _DEVICE_PNP_STATE { NotStarted = 0, // Not started yet Started, // Device has received the START_DEVICE IRP StopPending, // Device has received the QUERY_STOP IRP Stopped, // Device has received the STOP_DEVICE IRP RemovePending, // Device has received the QUERY_REMOVE IRP SurpriseRemovePending, // Device has received the SURPRISE_REMOVE IRP Deleted // Device has received the REMOVE_DEVICE IRP } DEVICE_PNP_STATE; #define INITIALIZE_PNP_STATE(_Data_) \ (_Data_)->DevicePnPState = NotStarted;\ (_Data_)->PreviousPnPState = NotStarted; #define SET_NEW_PNP_STATE(_Data_, _state_) \ (_Data_)->PreviousPnPState = (_Data_)->DevicePnPState;\ (_Data_)->DevicePnPState = (_state_); #define RESTORE_PREVIOUS_PNP_STATE(_Data_) \ (_Data_)->DevicePnPState = (_Data_)->PreviousPnPState;\ typedef enum _QUEUE_STATE { HoldRequests = 0, // Device is not started yet, temporarily // stopped for resource rebalancing, or // entering a sleep state. AllowRequests, // Device is ready to process pending requests // and take in new requests. FailRequests // Fail both existing and queued up requests. } QUEUE_STATE; #pragma pack (push, 1) typedef struct { UCHAR Type; USHORT Length; UCHAR AddressSpaceID; UCHAR BitWidth; UCHAR BitOffset; UCHAR Reserved; PHYSICAL_ADDRESS Address; } ACPI_GENERIC_REGISTER_DESC, *PACPI_GENERIC_REGISTER_DESC; #pragma pack (pop) typedef struct { ULONG Frequency; // in megahertz ULONG Flags; ULONG PercentFrequency; // for quick lookup } PROCESSOR_PERFORMANCE_STATE, *PPROCESSOR_PERFORMANCE_STATE; typedef struct { PSET_PROCESSOR_THROTTLE2 TransitionFunction; ULONG TransitionLatency; // in microseconds ULONG Current; ULONG Count; PROCESSOR_PERFORMANCE_STATE State[1]; // sorted from fastest to slowest } PROCESSOR_PERFORMANCE_STATES, *PPROCESSOR_PERFORMANCE_STATES; typedef struct { GEN_ADDR Register; UCHAR StateType; USHORT Latency; // in microseconds ULONG PowerConsumption; // in milliwatts } ACPI_CST_DESCRIPTOR, *PACPI_CST_DESCRIPTOR; typedef struct { UCHAR NumCStates; ACPI_CST_DESCRIPTOR State[ANYSIZE_ARRAY]; } ACPI_CST_PACKAGE, *PACPI_CST_PACKAGE; typedef struct { UCHAR StateType; USHORT Latency; // in microseconds GEN_ADDR Register; PPROCESSOR_IDLE_HANDLER IdleHandler; } PROCESSOR_IDLE_STATE, *PPROCESSOR_IDLE_STATE; typedef struct { UCHAR Count; PROCESSOR_IDLE_STATE State[1]; } PROCESSOR_IDLE_STATES, *PPROCESSOR_IDLE_STATES; typedef struct { GEN_ADDR Control; GEN_ADDR Status; } ACPI_PCT_PACKAGE, *PACPI_PCT_PACKAGE; typedef struct { ULONG CoreFrequency; // in megahertz ULONG Power; // in milliwatts ULONG Latency; // in microseconds ULONG BmLatency; // in microseconds - BUGBUG ULONG Control; ULONG Status; } ACPI_PSS_DESCRIPTOR, *PACPI_PSS_DESCRIPTOR; typedef struct { UCHAR NumPStates; ACPI_PSS_DESCRIPTOR State[ANYSIZE_ARRAY]; } ACPI_PSS_PACKAGE, *PACPI_PSS_PACKAGE; typedef struct _EVENT_LOG_CONTEXT { PIO_WORKITEM WorkItem; ULONG EventErrorCode; ULONG EventValue; ULONG BufferSize; PUCHAR Buffer; } EVENT_LOG_CONTEXT, *PEVENT_LOG_CONTEXT; // // The device extension for the device object // typedef struct _FDO_DATA { PIO_WORKITEM WorkItem; PDEVICE_OBJECT Self; // back pointer to the DeviceObject. PDEVICE_OBJECT UnderlyingPDO; // The underlying PDO PDEVICE_OBJECT NextLowerDriver; // top of the device stack (beneath this device object) DEVICE_PNP_STATE DevicePnPState; // Track the state of the device DEVICE_PNP_STATE PreviousPnPState;// Remembers the previous pnp state QUEUE_STATE QueueState; // This flag is set whenever the // device needs to queue incoming // requests (when it receives a // QUERY_STOP or QUERY_REMOVE). LIST_ENTRY NewRequestsQueue; // The queue where the incoming // requests are held when // QueueState is set to HoldRequest // or the device is busy. KSPIN_LOCK QueueLock; // The spin lock that protects // the queue KEVENT RemoveEvent; // an event to sync outstandingIO to zero. KEVENT StopEvent; // an event to sync outstandingIO to 1. ULONG OutstandingIO; // 1-biased count of reasons why // this object should stick around. SYSTEM_POWER_STATE SystemPowerState; // The general system power state DEVICE_POWER_STATE DevicePowerState; // The state of the device(D0 or D3) UNICODE_STRING InterfaceName; // The name returned from IoRegisterDeviceInterface() DEVICE_CAPABILITIES DeviceCaps; // Copy of the device capability (S->D mappings) WMILIB_CONTEXT WmiLibInfo; // WMI Information KEVENT PerfStateLock; PPROCESSOR_PERFORMANCE_STATES PerfStates; PPROCESSOR_IDLE_STATES CStates; PROCESSOR_OBJECT_INFO ProcObjInfo; PACPI_PSS_PACKAGE PssPackage; ACPI_PCT_PACKAGE PctPackage; ULONG PpcResult; ULONG LowestPerfState; BOOLEAN LegacyInterface; BOOLEAN CstPresent; ULONG CurrentPerfState; ULONG ThrottleValue; ULONG LastRequestedThrottle; ULONG LastTransitionResult; ULONG SavedState; PACPI_INTERFACE_STANDARD AcpiInterfaces; ULONG CurrentPssState; } FDO_DATA, *PFDO_DATA; typedef struct _PROCESSOR_WMI_STATUS_DATA { UINT32 CurrentPerfState; UINT32 LastRequestedThrottle; UINT32 LastTransitionResult; UINT32 ThrottleValue; UINT32 LowestPerfState; UINT32 UsingLegacyInterface; PROCESSOR_PERFORMANCE_STATES PerfStates; } PROCESSOR_WMI_STATUS_DATA, *PPROCESSOR_WMI_STATUS_DATA; typedef NTSTATUS (*PPERF_TRANSITION)( IN PFDO_DATA, IN ULONG ); NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); NTSTATUS ProcessorAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ); NTSTATUS ProcessorDispatchPnp ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorDispatchPower ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorDispatchIoctl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorCreateClose ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorReadWrite ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorCleanup ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorStartDevice ( IN PFDO_DATA FdoData, IN PIRP Irp ); NTSTATUS ProcessorDispatchPnpComplete ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); VOID ProcessorUnload( IN PDRIVER_OBJECT DriverObject ); VOID ProcessorCancelQueued ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); LONG ProcessorIoIncrement ( IN OUT PFDO_DATA FdoData ); LONG ProcessorIoDecrement ( IN OUT PFDO_DATA FdoData ); // // wmi.c // NTSTATUS ProcessorSystemControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorSendIrpSynchronously ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS ProcessorSetWmiDataItem( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer ); NTSTATUS ProcessorSetWmiDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG BufferSize, IN PUCHAR Buffer ); NTSTATUS ProcessorQueryWmiDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG BufferAvail, OUT PUCHAR Buffer ); NTSTATUS ProcessorQueryWmiRegInfo( IN PDEVICE_OBJECT DeviceObject, OUT PULONG RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING* RegistryPath, OUT PUNICODE_STRING ResourceName, OUT PDEVICE_OBJECT* Pdo ); NTSTATUS ProcessorExecuteWmiMethod( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN PUCHAR Buffer ); NTSTATUS ProcessorWmiFunctionControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN WMIENABLEDISABLECONTROL Function, IN BOOLEAN Enable ); NTSTATUS ProcessorWmiRegistration( IN PFDO_DATA FdoData ); NTSTATUS ProcessorWmiDeRegistration( IN PFDO_DATA FdoData ); NTSTATUS _cdecl ProcessorWmiLogEvent( IN ULONG LogLevel, IN ULONG LogType, IN LPGUID TraceGuid, IN PUCHAR Format, ... ); NTSTATUS ProcessorFireWmiEvent( IN PFDO_DATA DeviceExtension, IN PWMI_EVENT Event, IN PVOID Data ); VOID ProcessorEnableGlobalLogging( VOID ); NTSTATUS ProcessorReturnResources ( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS ProcessorQueueRequest ( IN OUT PFDO_DATA FdoData, IN PIRP Irp ); VOID ProcessorProcessQueuedRequests ( IN OUT PFDO_DATA FdoData ); NTSTATUS ProcessorCanRemoveDevice ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID ProcessorPowerStateCallback( IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2 ); NTSTATUS RegisterStateHandlers( IN PFDO_DATA DeviceExtension ); NTSTATUS FASTCALL SetPerfLevel ( IN UCHAR Throttle ); UCHAR GetNumThrottleSettings( IN PFDO_DATA DeviceExtension ); // // Define Interface reference/dereference routines for // Interfaces exported by IRP_MN_QUERY_INTERFACE // typedef VOID (*PINTERFACE_REFERENCE)(PVOID Context); typedef VOID (*PINTERFACE_DEREFERENCE)(PVOID Context); // // Definitions for ACPI-defined objects and operations. // NTSTATUS AcquireAcpiInterfaces( PFDO_DATA DeviceExtension ); NTSTATUS ReleaseAcpiInterfaces( PFDO_DATA DeviceExtension ); VOID AcpiNotifyCallback( PVOID Context, ULONG NotifyCode ); NTSTATUS AcpiEvaluateMethod ( IN PFDO_DATA DeviceExtension, IN PCHAR MethodName, IN PVOID InputBuffer OPTIONAL, OUT PVOID *OutputBuffer ); NTSTATUS AcpiEvaluateProcessorObject ( IN PFDO_DATA DeviceExtension, OUT PVOID *OutputBuffer ); NTSTATUS AcpiEvaluatePtc( IN PFDO_DATA DeviceExtension, OUT PGEN_ADDR *Address ); NTSTATUS AcpiEvaluateCst( IN PFDO_DATA DeviceExtension, OUT PACPI_CST_PACKAGE *CStates ); NTSTATUS AcpiEvaluatePct( IN PFDO_DATA DeviceExtension, OUT PACPI_PCT_PACKAGE *Address ); NTSTATUS AcpiEvaluatePss( IN PFDO_DATA DeviceExtension, OUT PACPI_PSS_PACKAGE *Address ); NTSTATUS AcpiEvaluatePpc( IN PFDO_DATA DeviceExtension, OUT ULONG *AvailablePerformanceStates ); NTSTATUS InitializeAcpi2PStatesGeneric( IN PFDO_DATA DeviceExtension ); NTSTATUS InitializeAcpi2PStates( IN PFDO_DATA DeviceExtension ); PVOID GetAcpiTable( IN ULONG Signature ); NTSTATUS InitializeAcpi1Cstates( PFDO_DATA DeviceExtension ); NTSTATUS InitializeAcpi1TStates( PFDO_DATA DeviceExtension ); NTSTATUS InitializeAcpi2Cstates( PFDO_DATA DeviceExtension ); NTSTATUS RegisterPerfStateHandlers( PFDO_DATA DeviceExtension ); BOOLEAN FASTCALL AcpiC1Idle( OUT PPROCESSOR_IDLE_TIMES IdleTimes ); BOOLEAN FASTCALL AcpiC2Idle( OUT PPROCESSOR_IDLE_TIMES IdleTimes ); BOOLEAN FASTCALL AcpiC3ArbdisIdle( OUT PPROCESSOR_IDLE_TIMES IdleTimes ); BOOLEAN FASTCALL Acpi2C2Idle( OUT PPROCESSOR_IDLE_TIMES IdleTimes ); BOOLEAN FASTCALL Acpi2C3ArbdisIdle( OUT PPROCESSOR_IDLE_TIMES IdleTimes ); VOID FASTCALL ProcessorThrottle ( IN UCHAR Throttle ); NTSTATUS FASTCALL SetThrottleLevel ( IN UCHAR Throttle ); NTSTATUS AcpiPerfStateTransition ( IN PFDO_DATA DeviceExtension, IN ULONG State ); NTSTATUS Acpi2PerfStateTransition ( IN PFDO_DATA DeviceExtension, IN ULONG State ); NTSTATUS AcpiLegacyPerfStateTransition ( IN PFDO_DATA DeviceExtension, IN ULONG State ); NTSTATUS MergePerformanceStates( IN PFDO_DATA DeviceExtension ); NTSTATUS InitializeAcpi2IoSpaceCstates( IN PFDO_DATA DeviceExtension ); VOID AssumeProcessorPerformanceControl ( VOID ); VOID AssumeCStateControl ( VOID ); NTSTATUS GetRegistryDwordValue ( IN PWCHAR RegKey, IN PWCHAR ValueName, OUT PULONG RegData ); NTSTATUS SetRegistryStringValue ( IN PWCHAR RegKey, IN PWCHAR ValueName, IN PWCHAR String ); NTSTATUS GetRegistryStringValue ( IN PWCHAR RegKey, IN PWCHAR ValueName, OUT PUNICODE_STRING RegString ); // // Functions that must be implemented by each driver. // NTSTATUS InitializeDriver( PUNICODE_STRING ServiceKeyRegPath ); NTSTATUS InitializeNonAcpiPerformanceStates( IN PFDO_DATA DeviceExtension ); NTSTATUS GetLegacyMaxProcFrequency ( OUT PULONG CpuSpeed ); NTSTATUS ProcessResumeFromSleepState( SYSTEM_POWER_STATE PreviousState, PFDO_DATA DeviceExtension ); NTSTATUS ProcessSuspendToSleepState( SYSTEM_POWER_STATE TargetState, PFDO_DATA DeviceExtension ); NTSTATUS GetProcessorBrandString ( PUCHAR BrandString, PULONG Size ); typedef struct { USHORT Signature; USHORT CommandPortAddress; USHORT EventPortAddress; USHORT PollInterval; UCHAR CommandDataValue; UCHAR EventPortBitmask; UCHAR MaxLevelAc; UCHAR MaxLevelDc; } LEGACY_GEYSERVILLE_INT15, *PLEGACY_GEYSERVILLE_INT15; // // method.c // NTSTATUS Acpi2PerfStateTransitionGeneric( IN PFDO_DATA DeviceExtension, IN ULONG State ); NTSTATUS FASTCALL SetPerfLevelGeneric( IN UCHAR Throttle, IN PFDO_DATA DeviceExtension ); NTSTATUS MergePerformanceStatesGeneric( IN PFDO_DATA DeviceExtension ); NTSTATUS FASTCALL SetThrottleLevelGeneric ( IN UCHAR Throttle, IN PFDO_DATA DeviceExtension ); NTSTATUS BuildAvailablePerfStatesFromPss ( PFDO_DATA DeviceExtension ); ULONG GetMaxProcFrequency( PFDO_DATA DeviceExtension ); NTSTATUS SaveCurrentStateGoToLowVolts( IN PFDO_DATA DeviceExtension ); NTSTATUS RestoreToSavedPerformanceState( IN PFDO_DATA DeviceExtension ); NTSTATUS SetProcessorPerformanceState( IN ULONG TargetPerfState, IN PFDO_DATA DeviceExtension ); NTSTATUS QueueEventLogWrite( IN PFDO_DATA DeviceExtension, IN ULONG EventErrorCode, IN ULONG EventValue ); VOID ProcessEventLogEntry ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); NTSTATUS PowerStateHandlerNotificationRegistration ( IN PENTER_STATE_NOTIFY_HANDLER NotifyHandler, IN PVOID Context, IN BOOLEAN Register ); NTSTATUS ProcessMultipleApicDescTable( PPROCESSOR_INFO ProcInfo ); extern __inline ULONG GetApicId( VOID ); extern __inline NTSTATUS AcquireProcessorPerfStateLock ( IN PFDO_DATA DevExt ); extern __inline NTSTATUS ReleaseProcessorPerfStateLock ( IN PFDO_DATA DevExt ); extern __inline CPUID( IN ULONG CpuIdType, OUT PULONG EaxReg, OUT PULONG EbxReg, OUT PULONG EcxReg, OUT PULONG EdxReg ); extern __inline ULONGLONG ReadMSR( IN ULONG MSR ); extern __inline WriteMSR( IN ULONG MSR, IN ULONG64 MSRInfo ); NTSTATUS SetProcessorFriendlyName ( PFDO_DATA DeviceExtension ); NTSTATUS GetHardwareId( PFDO_DATA DeviceExtension ); NTSTATUS GetInstanceId( PFDO_DATA DeviceExtension, PWCHAR *InstanceId ); NTSTATUS GetRegistryValue( IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_PARTIAL_INFORMATION *Information ); // // i386\util.c // NTSTATUS CalculateCpuFrequency( OUT PULONG Freq ); NTSTATUS GetCPUIDProcessorBrandString ( PUCHAR BrandString, PULONG Size ); ULONG GetCheckSum ( IN PUCHAR Address, IN ULONG Length ); ULONG Bcd8ToUlong( IN ULONG BcdValue ); ULONG ReadGenAddr( IN PGEN_ADDR GenAddr ); VOID WriteGenAddr( IN PGEN_ADDR GenAddr, IN ULONG Value ); // // power.c // typedef NTSTATUS (*PAC_DC_NOTIFY_HANDLER)( IN PVOID Context, IN BOOLEAN AC ); NTSTATUS RegisterAcDcTransitionNotifyHandler ( IN PAC_DC_NOTIFY_HANDLER NewHandler, IN PVOID Context ); // end power.c // // method.c // NTSTATUS GetRegistryValue( IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_PARTIAL_INFORMATION *Information ); // // misc debug routines // #if DBG VOID DumpProcessorPerfStates ( PPROCESSOR_PERFORMANCE_STATES PerfStates ); VOID DumpProcessorStateHandler2Info ( PPROCESSOR_STATE_HANDLER2 StateInfo ); #else #define DumpProcessorPerfStates(_x_) #define DumpProcessorStateHandler2Info(_x_) #endif // // shared.c // NTSTATUS ValidatePssLatencyValues ( IN PFDO_DATA DeviceExtension ); #if DBG VOID DumpPSS( IN PACPI_PSS_PACKAGE PStates ); #else #define DumpPSS(_x_) #endif #endif // _PROCESSOR_H_