pmudll.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 667 行 · 第 1/2 页
CPP
667 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.
** Title to the Material remains with Intel Corporation or its suppliers and licensors.
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
*/
/*++
Module Name: PMUdll.cpp
Abstract:
Defines the entry points for the VTune PMU DLL.
Functions:
Notes:
--*/
#include "stdafx.h"
#include <stdlib.h>
#include <ceddk.h>
#include <malloc.h>
#include <pmu.h>
#include <pmuioctl.h>
#include "pmudll.h"
#define MAXFREQS 8
static HANDLE trySemaphore = 0; // Semaphore for PMU resource allocation
static HANDLE semHandle = 0; // Semaphore for PMU resource allocation
// Local copies of callback ptrs
//
LPVOID PVTuneInterrupt = NULL;
LPVOID PVTuneReleasePMU = NULL;
LPVOID PVTuneReleaseCCF = NULL;
//------------------------------------------------------------------------------
//
// Function: AllocatePMU
//
// Returns a handle identifying the PMU resource
// If PMU not available, returns 0.
//
PMUHandle WINAPI AllocatePMU(void (*pCallBack)(void))
{
PMUHandle handle = 0;
PMURegInfo PMURegBuffer;
BOOL rtnvalue = FALSE;
LPCTSTR semName = TEXT("XSC_PMU_ALLOC");
// Allocate a system resource, initialize to unsignalled state.
// If it's already allocated, return NULL handle.
//
trySemaphore = CreateSemaphore (NULL, 1, 1, semName);
if (trySemaphore == NULL)
{
return 0;
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
//
// Invalidate this handle
//
CloseHandle(trySemaphore);
return 0;
}
semHandle = trySemaphore;
// Map callback address to virtual address slot of current process
//
PVTuneReleasePMU = MapPtrToProcess(pCallBack, GetCurrentProcess());
// Register callback with kernel
//
PMURegBuffer.subcode = PMU_ALLOCATE;
PMURegBuffer.pCallback = PVTuneReleasePMU;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
if (rtnvalue == FALSE)
{
return 0;
}
// Null other callbacks
//
PVTuneInterrupt = NULL;
PVTuneReleaseCCF = NULL;
// Allocate a PMUHandle
//
handle = (PMUHandle) malloc (sizeof (PMUHResource));
return handle;
}
//------------------------------------------------------------------------------
//
// Function: ReleasePMUResources
//
// Release the PMU Resources
// So far this releases the PMU resource and
// NULLs the handle.
//
BOOL WINAPI ReleasePMUResources(PMUHandle handle)
{
PMURegInfo PMURegBuffer;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return FALSE;
}
//
// Remove Interrupt callback
//
RemovePMUInterruptCallback(handle);
//
// Remove lock, if any, and release CCF callback
//
UnlockAndRestoreCoreClockFrequency(handle);
//
// Null local copy
//
PVTuneReleasePMU = NULL;
//
// Unregister ReleasePMU callback in kernel
//
PMURegBuffer.subcode = PMU_RELEASE;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
//
// Release resource, NULL handle
//
ReleaseSemaphore(semHandle, 1, NULL);
CloseHandle(semHandle);
free ((PMUHResource*) handle);
handle = 0;
return rtnvalue;
}
//------------------------------------------------------------------------------
//
// Function: SetPMUInterruptCallback
//
// Registers the PMU Callback routine that is called
// from the OS when the PMU interrupt occurs.
//
// Note: The FIQ_or_IRQ parameter is ignored. We're
// only implementing IRQs for the Cotulla WinCE kernel.
//
STATUS_PMU WINAPI SetPMUInterruptCallback(
PMUHandle handle,
enum PMUIntType FIQ_or_IRQ,
BOOL (*pCallBack)(SampleInput *))
{
PMURegInfo PMURegBuffer;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return INVALIDHANDLE_PMU;
}
//
// Check the callback routine pointer.
// If already set, then return an error
//
if (PVTuneInterrupt)
{
return ACTIVECALLBACK_PMU;
}
//
// Map callback address to virtual address slot of current process
//
PVTuneInterrupt = MapPtrToProcess(pCallBack, GetCurrentProcess());
//
// Interrupt callback not implemented yet.
// PMU ISR still a part of the kernel, pmu.c
//
//
// Call KernelIoControl call to enable IRQ or FIQ interrupts
//
switch (FIQ_or_IRQ)
{
case IRQ:
PMURegBuffer.subcode = PMU_ENABLE_IRQ;
PMURegBuffer.pCallback = PVTuneInterrupt;
break;
case FIQ:
//
// Not yet implemented...
//
PMURegBuffer.subcode = PMU_ENABLE_FIQ;
PMURegBuffer.pCallback = PVTuneInterrupt;
return KERNELIOFAILED_PMU;
break;
default:
return KERNELIOFAILED_PMU;
break;
}
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
if (rtnvalue == FALSE)
{
return KERNELIOFAILED_PMU;
}
return SUCCESS_PMU;
}
//------------------------------------------------------------------------------
//
// Function: RemovePMUInterruptCallback
//
// Unregisters the PMU interrupt callback routine.
//
STATUS_PMU WINAPI RemovePMUInterruptCallback(
PMUHandle handle )
{
PMURegInfo PMURegBuffer;
BOOL rtnvalue = FALSE;
if (handle == 0)
{
return INVALIDHANDLE_PMU;
}
//
// Remove the interrupt callback
//
if (PVTuneInterrupt == NULL)
{
return NOCALLBACK_PMU;
}
PVTuneInterrupt = NULL;
//
// Disable the interrupt (IRQ for now...) and
// unregister the callback in the kernel
//
PMURegBuffer.subcode = PMU_DISABLE_IRQ;
rtnvalue =
KernelIoControl (IOCTL_PMU_CONFIG, (void *)&PMURegBuffer, sizeof(PMURegInfo),
(LPVOID)NULL, 0, (LPDWORD)NULL);
if (rtnvalue == FALSE)
{
return KERNELIOFAILED_PMU;
}
return SUCCESS_PMU;
}
//------------------------------------------------------------------------------
//
// Function: GetNumberOfPossibleCoreClockFrequencies
//
// Returns the number of frequency values that
// can be set by the OS.
//
unsigned int WINAPI GetNumberOfPossibleCoreClockFrequencies(void)
{
return MAXFREQS;
}
//------------------------------------------------------------------------------
//
// Function: GetPossibleCoreClockFrequencies
//
// Write the possible frequencies as unsigned ints in the buffer provided.
// FrequencyArray buffer is allocated by the caller.
//
// Frequencies expressed in KHz
//
STATUS_PMU WINAPI GetPossibleCoreClockFrequencies(
unsigned int numberfreqs,
unsigned long *FrequencyArray)
{
/*
* Restrict frequencies between the same LCD Frequency
* (K) range until LCD controller can be disabled
*
* static unsigned long FreqArray[MAXFREQS] =
* {26000, 39000, 52000, 65000, 78000,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?