|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
generic.c
Abstract:
This module implements code that works on any processor.
Author:
Jake Oshins (3/23/00) - create file
Environment:
Kernel mode
Notes:
Revision History:
--*/ #include "..\lib\processor.h"
//
// Must define for debug output
//
#if DBG
PUCHAR DebugName = "Processr.sys"; #endif
PFDO_DATA DeviceExtensions[MAX_SUPPORTED_PROCESSORS]; UCHAR DevExtIndex; extern GLOBALS Globals;
#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, InitializeNonAcpiPerformanceStates)
#pragma alloc_text (PAGE, InitializeAcpi2PStates)
#pragma alloc_text (PAGE, InitializeAcpi2Cstates)
#pragma alloc_text (PAGE, MergePerformanceStates)
#endif
NTSTATUS InitializeDriver( PUNICODE_STRING ServiceKeyRegPath ) /*++
Routine Description:
Arguments:
Return Value:
--*/ {
//
// Register for power state change notification
//
//PowerStateHandlerNotificationRegistration(ProcessSleepStateNotification,
// NULL,
// TRUE);
return STATUS_SUCCESS; }
#ifdef _X86_
NTSTATUS FASTCALL SetPerfLevel( IN UCHAR Throttle ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { PFDO_DATA DeviceExtension; ULONG apicId; ULONG index = 0;
DebugEnter();
//
// Get APIC Id and retrieve Device Extension index
//
if (!Globals.SingleProcessorProfile) { apicId = GetApicId(); index = Globals.ProcInfo.ApicIdToDevExtIndex[apicId]; } //
// Get the DeviceExtension.
//
DeviceExtension = DeviceExtensions[index];
//
// Since this driver does not support Functional Fixed Hardware, we
// use generic method.
//
return SetPerfLevelGeneric(Throttle, DeviceExtension);
}
NTSTATUS FASTCALL SetThrottleLevel( IN UCHAR Throttle ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { PFDO_DATA DeviceExtension; ULONG apicId; ULONG index = 0;
DebugEnter();
//
// Get APIC Id and retrieve Device Extension index
//
if (!Globals.SingleProcessorProfile) { apicId = GetApicId(); index = Globals.ProcInfo.ApicIdToDevExtIndex[apicId]; }
//
// Get the DeviceExtension.
//
DeviceExtension = DeviceExtensions[index];
//
// Since this driver does not support Functional Fixed Hardware, we
// use generic method.
//
return SetThrottleLevelGeneric(Throttle, DeviceExtension);
}
NTSTATUS GetProcessorBrandString ( PUCHAR BrandString, PULONG Size ) /*++
Routine Description: Arguments: Return Value:
--*/ { //
// With the generic driver we only try to find the Processor Brand String
// via the CPUID
//
return GetCPUIDProcessorBrandString(BrandString, Size); }
#else
NTSTATUS FASTCALL SetPerfLevel( IN UCHAR Throttle ) { TRAP(); return STATUS_SUCCESS; }
NTSTATUS GetProcessorBrandString ( PUCHAR BrandString, PULONG Size ) /*++
Routine Description: Arguments: Return Value:
--*/ { DebugAssert(Size);
*Size = 0; return STATUS_NOT_SUPPORTED; } #endif
NTSTATUS InitializeAcpi2PStates( IN PFDO_DATA DevExt ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { NTSTATUS status;
status = InitializeAcpi2PStatesGeneric(DevExt);
//
// Make sure we didn't find any NON I/O or MEM addresses
//
if (NT_SUCCESS(status)) { if (((DevExt->PctPackage.Control.AddressSpaceID != AcpiGenericSpaceIO) && (DevExt->PctPackage.Control.AddressSpaceID != AcpiGenericSpaceMemory)) || ((DevExt->PctPackage.Status.AddressSpaceID != AcpiGenericSpaceIO) && (DevExt->PctPackage.Status.AddressSpaceID != AcpiGenericSpaceMemory))) {
DebugPrint((WARN, "ONLY Memory & I/O _PCT addresses are supported\n")); DebugPrint((WARN, "NOT using Acpi 2.0 Performance States\n"));
//
// Undo what InitializeAcpi2PStatesGeneric() did
//
if (DevExt->PssPackage) { ExFreePool(DevExt->PssPackage); DevExt->PssPackage = NULL; } return STATUS_NOT_SUPPORTED; }
//
// Walk through _PSS states to calculate latency values
//
ValidatePssLatencyValues(DevExt);
//
// Need to merge this new data with our perfstates
//
MergePerformanceStates(DevExt);
}
return status; }
NTSTATUS InitializeAcpi2Cstates( PFDO_DATA DevExt ) /*++
Routine Description:
This function looks to see if there is an ACPI 2.0 _CST object in the namespace, and, if there is, it replaces the functions found by InitializeAcpi1Cstates.
Further note: This function leaves the filling in of throttling functions to the InitializePerformanceStates functions.
Arguments:
DeviceExtension
Return Value:
A NTSTATUS code to indicate the result of the initialization.
--*/ { ULONG apicId; ULONG index = 0;
DebugEnter();
//
// Record the address of this processor's DeviceExtension, as the
// throttling API doesn't give it to us.
//
if (!Globals.SingleProcessorProfile) {
//
// save the index into the DeviceExtension[] for later retrieval based
// on APIC Id.
//
apicId = Globals.ProcInfo.ProcIdToApicId[DevExt->ProcObjInfo.PhysicalID]; Globals.ProcInfo.ApicIdToDevExtIndex[apicId] = DevExtIndex;
index = DevExtIndex++; }
//
// save Device Extension pointer
//
DeviceExtensions[index] = DevExt;
//
// This processor driver only supports I/O Space based Cstates.
// InitializeAcpi2IoSpaceCstates() will fail if it finds Cstates with
// non AcpiGenericSpaceIO type addresses.
//
return InitializeAcpi2IoSpaceCstates(DevExt);
}
NTSTATUS MergePerformanceStates( IN PFDO_DATA DeviceExtension ) /*++
Routine Description:
This routine looks at the performance states stored in the device extension.
Arguments:
DeviceExtension
Return Value:
A NTSTATUS code to indicate the result of the initialization.
NOTE:
- The caller must hold PerfStateLock.
- This is called during START_DEVICE, and after recieving a Notify(0x80) on the processor.
--*/ {
DebugEnter();
//
// Since this driver does not support Functional Fixed Hardware, we
// use generic method.
//
return MergePerformanceStatesGeneric(DeviceExtension);
}
NTSTATUS Acpi2PerfStateTransition( IN PFDO_DATA DeviceExtension, IN ULONG State ) /*++
Routine Description:
This routine changes the performance state of the processor based on ACPI 2.0 performance state objects.
Arguments:
State - Index into _PSS object
Return Value:
none
--*/ {
//
// Since this driver does not support Functional Fixed Hardware, we
// use generic method.
//
return Acpi2PerfStateTransitionGeneric(DeviceExtension, State);
}
NTSTATUS ProcessResumeFromSleepState( SYSTEM_POWER_STATE PreviousState, PFDO_DATA DeviceExtension ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { DebugEnter();
//
// if we are resuming from Hibernate, and this is an Acpi 2.0 system,
// we must re-claim perf state and cstate control from the bios.
//
if (PreviousState == PowerSystemHibernate) {
if (DeviceExtension->PssPackage) { AssumeProcessorPerformanceControl(); } if (DeviceExtension->CstPresent) { AssumeCStateControl(); } }
//
// restore previous state
//
return RestoreToSavedPerformanceState(DeviceExtension);
}
NTSTATUS ProcessSuspendToSleepState( SYSTEM_POWER_STATE TargetState, PFDO_DATA DeviceExtension ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { DebugEnter();
//
// save current state, transition to lowest non-throttled perf state
//
return SaveCurrentStateGoToLowVolts(DeviceExtension); }
//
// Legacy function that must have a stub.
//
NTSTATUS InitializeNonAcpiPerformanceStates( IN PFDO_DATA DeviceExtension ) /*++
Routine Description:
The generic processor driver doesn't have non-ACPI performance states.
Arguments:
FdoData - pointer to the device extension
Return Value:
NT status code
--*/ {
return STATUS_NOT_FOUND;
}
NTSTATUS AcpiLegacyPerfStateTransition( IN PFDO_DATA DeviceExtension, IN ULONG State ) /*++
Routine Description:
The generic processor driver doesn't have non-ACPI performance states.
Arguments:
State - Target State
Return Value:
NT Status
--*/ {
TRAP(); return STATUS_NOT_FOUND;
}
NTSTATUS GetLegacyMaxProcFrequency( OUT PULONG CpuSpeed ) /*++
Routine Description:
Arguments:
Return Value:
--*/ {
TRAP(); return STATUS_NOT_FOUND;
}
|