pmudll.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 667 行 · 第 1/2 页
CPP
667 行
* 91000, 104000, 117000, 130000, 143000,
* 156000, 169000, 182000, 195000,
* 208000, 377000, 390000, 403000};
*/
static unsigned long FreqArray[MAXFREQS] =
{104000, 117000, 130000, 143000,
156000, 169000, 182000, 195000};
unsigned int i;
if (numberfreqs > MAXFREQS)
{
return FAILURE_PMU;
}
//
// Calculate possible frequencies
//
for (i=0; i < numberfreqs; i++)
{
FrequencyArray[i] = FreqArray[i];
}
return SUCCESS_PMU;
}
//------------------------------------------------------------------------------
//
// Function: GetNominalCoreClockFrequency
//
// Returns the nominal or default runtime frequency (in KHz).
//
unsigned long WINAPI GetNominalCoreClockFrequency(void)
{
return 208000;
}
//------------------------------------------------------------------------------
//
// Function: GetCurrentCoreClockFrequency
//
// Returns the current core clock frequency (in KHz).
//
unsigned long WINAPI GetCurrentCoreClockFrequency(void)
{
PMUCCFInfo PMUCCFBuffer;
unsigned long CurFrequency,
nOutBytes;
BOOL rtnvalue = FALSE;
//
// This API calls KernelIoControl to access to get
// the current core clock frequency.
// This in turn calls the OEMIoControl routine.
// Note, the system is fully preemptible when this
// routine is called.
//
//
// Set the subcode for get ccf
//
PMUCCFBuffer.subcode = PMU_CCF_GETCURRENT;
rtnvalue =
KernelIoControl (IOCTL_PMU_CCF, (void *)&PMUCCFBuffer, sizeof(PMUCCFInfo),
&CurFrequency, sizeof(CurFrequency), &nOutBytes);
if (rtnvalue && (nOutBytes == sizeof(unsigned long)))
{
return CurFrequency;
}
else
{
return 0;
}
}
//------------------------------------------------------------------------------
//
// Function: SaveSetAndLockCoreClockFrequency
//
// This function acquires ownership of the core clock frequency,
// sets a new core clock frequency, and requests that the OS not change
// the core clock until after the UnlockandRestoreCoreClockFrequency is called.
//
// A callback routine is registered with the OS. If the OS must change the
// core clock frequency, then it needs to invoke the callback routine before
// changing it. The will notify VTune to gracefully stop the data collection.
//
STATUS_PMU WINAPI SaveSetAndLockCoreClockFrequency(
PMUHandle handle,
unsigned long NewFrequency,
void (*pCallBack)(void))
{
PMUCCFInfo PMUCCFBuffer;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return INVALIDHANDLE_PMU;
}
//
// Map callback address to virtual address slot of current process
//
PVTuneReleaseCCF = MapPtrToProcess(pCallBack, GetCurrentProcess());
//
// This API calls KernelIoControl to save, set, and
// lock the core clock frequency.
//
// Note, the system is fully preemptible when this
// routine is called.
//
//
// Set the subcode for save, set, and lock CCF
//
PMUCCFBuffer.subcode = PMU_CCF_SETLOCK;
PMUCCFBuffer.newFreq = NewFrequency;
PMUCCFBuffer.pCallback = PVTuneReleaseCCF;
rtnvalue =
KernelIoControl (IOCTL_PMU_CCF, (void *)&PMUCCFBuffer, sizeof(PMUCCFInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
if (rtnvalue == FALSE)
{
return KERNELIOFAILED_PMU;
}
return SUCCESS_PMU;
}
//------------------------------------------------------------------------------
//
// Function: UnlockAndRestoreCoreClockFrequency
//
// Unregister the callback routine, relinquishes core clock resource ownership,
// and requests that the OS restore the core clock frequency as it was before
// the SaveSetandLock... call
//
unsigned long WINAPI UnlockAndRestoreCoreClockFrequency(
PMUHandle handle
)
{
PMUCCFInfo PMUCCFBuffer;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return 0;
}
PVTuneReleaseCCF = NULL;
//
// This API calls KernelIoControl to unlock and
// restore the previous core clock frequency.
//
// Note, the system is fully preemptible when this
// routine is called.
//
//
// Set the subcode for unlock CCF
//
PMUCCFBuffer.subcode = PMU_CCF_UNLOCK;
rtnvalue =
KernelIoControl (IOCTL_PMU_CCF, (void *)&PMUCCFBuffer, sizeof(PMUCCFInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
if (rtnvalue)
{
// Returns the restored core clock frequency (in KHz).
//
return GetCurrentCoreClockFrequency();
}
else
{
return 0;
}
}
//------------------------------------------------------------------------------
//
// Function: AccessPMUReg
//
// This API calls KernelIoControl to access the PMU Register.
// This in turn calls the OEMIoControl routine.
// Note, the system is fully preemptible when this
// routine is called.
//
BOOL WINAPI AccessPMUReg(
PMUHandle handle,
enum PMURegAccessType Access,
unsigned long RegisterNumber,
unsigned long *pValue)
{
PMURegInfo PMURegBuffer;
unsigned long PMURegResults,
nOutBytes;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return FALSE;
}
PMURegBuffer.PMUReg = RegisterNumber;
switch (Access)
{
case READ:
PMURegBuffer.subcode = PMU_READ_REG;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
&PMURegResults, sizeof(PMURegResults), &nOutBytes);
if (rtnvalue && (nOutBytes == sizeof(unsigned long)))
{
*pValue = PMURegResults;
}
else
{
rtnvalue = FALSE;
}
break;
case WRITE:
PMURegBuffer.subcode = PMU_WRITE_REG;
PMURegBuffer.PMUValue = *pValue;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
&PMURegResults, sizeof(PMURegResults), &nOutBytes);
break;
default:
return FALSE;
break;
}
return rtnvalue;
}
//------------------------------------------------------------------------------
//
// Function: GetCPUId
//
// This API calls KernelIoControl to retrieve the CPU Id.
// This in turn calls the OEMIoControl routine.
// Note, the system is fully preemptible when this
// routine is called.
//
BOOL WINAPI GetCPUId(
unsigned long *CPUId)
{
CPUIdInfo CPUIdBuffer;
unsigned long CPUIdResults,
nOutBytes;
BOOL rtnvalue = FALSE;
rtnvalue =
KernelIoControl (IOCTL_GET_CPU_ID, (void *)&CPUIdBuffer, sizeof(CPUIdInfo),
&CPUIdResults, sizeof(CPUIdResults), &nOutBytes);
if (rtnvalue && (nOutBytes == sizeof(unsigned long)))
{
*CPUId = CPUIdResults;
}
else
{
rtnvalue = FALSE;
}
return rtnvalue;
}
//------------------------------------------------------------------------------
//
// Function: GetOEMConfigData
//
// This API calls KernelIoControl to retrieve the OEM
// configuration data. This in turn calls the OEMIoControl routine.
// Note, the system is fully preemptible when this
// routine is called.
//
// Currently, the OEM configuration data retrieved consists
// of two items: the system interrupt ID assigned by the OEM,
// and the address to the VTune PMU driver globals area.
//
BOOL WINAPI GetOEMConfigData (
unsigned long *configArray,
unsigned long maxItems,
unsigned long *nOutItems)
{
OEMInfo OEMBuffer;
PMURegInfo PMURegBuffer;
unsigned long nOutBytes;
BOOL rtnvalue = FALSE;
PMURegBuffer.subcode = PMU_OEM_INFO;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
&OEMBuffer, sizeof(OEMInfo), &nOutBytes);
if (rtnvalue && ((nOutBytes != sizeof(OEMInfo) ||
(nOutBytes > (maxItems*sizeof(unsigned long))))))
{
rtnvalue = FALSE;
*nOutItems = 0;
}
else
{
configArray[0] = OEMBuffer.sysintrID;
configArray[1] = OEMBuffer.PMUglobals;
*nOutItems = 2;
}
return rtnvalue;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?