diff -r ebc84c812384 -r 46218c8b8afa Symbian3/PDK/Source/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita --- a/Symbian3/PDK/Source/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita Thu Mar 11 15:24:26 2010 +0000 +++ b/Symbian3/PDK/Source/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita Thu Mar 11 18:02:22 2010 +0000 @@ -1,336 +1,336 @@ - - - - - -Implement -the PSL for the targetThis document describes how to implement the Platform Specific -Layer for the Power Resource Manager. -
Purpose

The PSL must be implemented in order for -the PRM and the hardware to be able to communicate.

Introduction

The -PSL side of the Resource Controller should be derived from the class DPowerResourceController.

-
Implementing the PSL

The following tasks are -covered in this tutorial:

    -
  • Create an entry point,

  • -
  • Override the pure virtual functions,

  • -
  • Create static resources that support dependencies,

  • -
  • Initialise the pools,

  • -
  • Registering with the Power Controller.

  • -

Create an entry -Point

The PIL layer of the PRM offers the following macro. This -needs to be invoked from the PSL. The macro calls the DoInitController() and DoInitResources() functions -implemented by the PSL.

/** -Extension entry point -*/ -DECLARE_RESOURCE_MANAGER_EXTENSION() - { - __KTRACE_OPT(KBOOT, Kern::Printf("CreateController called")); - return new DH4PowerResourceController; - }

If the PRM is a PDD the entry point -is as follows:

static DH4PowerResourceController TheController; -DECLARE_STANDARD_PDD() - { - TInt r = DPowerResourceController::InitController(); - if® == KErrNone) - r = TheController->InitResources(); - if® == KErrNone) - return new DResConPddFactory; - return NULL; - }

Override -the pure virtual functions

Override the virtual functions of the DPowerResourceController base -class:

    -
  • DoInitController(),

  • -
  • DoRegisterStaticResources().

  • -

Here is an example H4 HRP implementation:

class DH4PowerResourceController : DPowerResourceController - { -public: - DH4PowerResourceController(); - TInt DoInitController(); - TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount); -private: - static DStaticPowerResource* iResources[];

DoInitController()

Override DPowerResourceController::DoInitController() so that it creates -a DFC queue and then invokes the base class function DPowerResourceController::SetDfcQ(). DoInitController() should -also initialise the pools by invoking DPowerResourceController::InitPools() passing -the platform defined sizes for the pools of clients, client levels and request -objects. DoInitController() is called by the PSL -during its initialisation. Below is the reference implementation code.

#define KERNEL_CLIENTS 0x2 // Expected number of kernel clients (MMC and Sound_SC) -#define USER_CLIENTS 0x0 // No user side clients expected. -#define CLIENT_LEVELS 0x8 // Expected resource state change of 8 resources -#define REQUESTS 0x0 // No asynchronous operation (state change or read) expected. - -TInt DH4PowerResourceController::DoInitController() - { - // Create a DFC queue and then invoke SetDfcQ() -__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoInitController\n")); - - // NKern::ThreadEnterCS(); // Not needed, as this is executed during kernel boot which is done within a critical section. - TInt r = Kern::DfcQCreate(iDfcQ,28,&KResThreadName); - - // NKern::ThreadLeaveCS(); - if (KErrNone!=r) return r; - SetDfcQ(iDfcQ); - r = InitPools(KERNEL_CLIENTS,USER_CLIENTS,CLIENT_LEVELS,REQUESTS); -__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoInitController\n")); - return r; - }

DoRegisterStaticResources()

DoRegisterStaticResources() is called by the PIL during its initialisation. Override the pure virtual -function DPowerResourceController::DoRegisterStaticResources() so -that it:

    -
  • creates all the static -resources in the kernel heap,

  • -
  • creates an array of -pointers to the static resources (indexed by their id),

  • -
  • sets the passed pointer -(aStaticResourceArray) to point to the created array of pointers,

  • -
  • updates the count of -the static resources (in aStaticResourceCount).

  • -

The reference implementation is below:

TInt DH4PowerResourceController::DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount) - { - aStaticResourceCount = 0; - __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoRegisterStaticResources\n")); - aStaticResourceArray = (DStaticPowerResource**) new (DStaticPowerResource*[EH4ResourceCount]); - if(!aStaticResourceArray) - return KErrNoMemory; - - DH4MmcFclkResource *pMmcFclk = new (DH4MmcFclkResource); - if (!pMmcFclk) - return KErrNoMemory; - aStaticResourceArray[EMmcFclkRes] = pMmcFclk; - - DH4MmcIclkResource *pMmcIclk = new (DH4MmcIclkResource); - if (!pMmcIclk) - CLEAN_AND_RETURN(KErrNoMemory, EMmcIclkRes) - aStaticResourceArray[EMmcIclkRes] = pMmcIclk; - - DH4MmcClkResource *pMmcBusClk = new (DH4MmcClkResource); - if (!pMmcBusClk) - CLEAN_AND_RETURN(KErrNoMemory, EMmcClkRes) - aStaticResourceArray[EMmcClkRes] = pMmcBusClk; - - DH4MmcCtrllerPwrResource *pMmcCtrlrPwr = new (DH4MmcCtrllerPwrResource); - if (!pMmcCtrlrPwr) - CLEAN_AND_RETURN(KErrNoMemory, EMmcCtrlrPwrRes) - aStaticResourceArray[EMmcCtrlrPwrRes] = pMmcCtrlrPwr; - - DH4MmcPowerResource *pMmcPwr = new (DH4MmcPowerResource); - if (!pMmcPwr) - CLEAN_AND_RETURN(KErrNoMemory, EMmcPwrRes) - aStaticResourceArray[EMmcPwrRes] = pMmcPwr; - - DH4SndFclkResource *pSndFclk = new (DH4SndFclkResource); - if (!pSndFclk) - CLEAN_AND_RETURN(KErrNoMemory, ESndFclkRes) - aStaticResourceArray[ESndFclkRes] = pSndFclk; - - DH4SndIclkResource *pSndIclk = new (DH4SndIclkResource); - if (!pSndIclk) - CLEAN_AND_RETURN(KErrNoMemory ,ESndIclkRes) - aStaticResourceArray[ESndIclkRes] = pSndIclk; - - DH4SndMClkResource *pSndMclk = new (DH4SndMClkResource); - if (!pSndMclk) - CLEAN_AND_RETURN(KErrNoMemory, ESndMClkRes) - aStaticResourceArray[ESndMClkRes] = pSndMclk; - - aStaticResourceCount = EH4ResourceCount; - - __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoRegisterStaticResources, Total resources:%d\n", EH4ResourceCount)); - - return KErrNone; - }

Create -static resources that support dependencies

If there are static -resources that support dependencies then the PSL must implement the function DPowerResourceController::DoRegisterStaticResourcesDependency(). Note: Static resources that support dependencies are only available -in the extended version of the library. See setup -and configuration.

The function DoRegisterStaticResourcesDependency():

    -
  • creates all static resources -that support dependencies in kernel heap,

  • -
  • creates an array of -pointers to them,

  • -
  • establishes the dependencies -between them (using the resource's DStaticPowerResourceD::AddNode() function), -See creating -dependencies between static resources for a description of AddNode() and -the SNode structure.

  • -
  • sets the passed pointer -(aStaticResourceDArray) to point to the array of pointers -to static resource with dependency,

  • -
  • updates the count of -the static resource that supports dependency in aStaticResourceDCount.

  • -

This function is called by the PIL during PRM initialisation. Below -is an example:

/** -This function creates all static resources that support dependencies and establishes the dependencies between them. This is called by the PIL. -This is the dependency tree input: - ResourceA <---------> ResourceD <-------> ResourceE <--------> ResourceC - | | - | | - | | - ResourceF ResourceG -*/ -TInt DSimulatedPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount) - { - aStaticResourceDArray = (DStaticPowerResourceD**) new (DStaticPowerResourceD*[MAX_DEPENDENT_RESOURCE_COUNT]); - if(!aStaticResourceDArray) - return KErrNoMemory; - - DStaticPowerResourceD* pR = NULL; - - pR = new DMLSLGLSPDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - pR = new DMLSIGLSNDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - pR = new DBSIGLSPDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - pR = new DMLSHIGLSPDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - pR = new DBSHLGLSNDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - pR = new DMLSHLGLSNDependResource(); - if(!pR) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - aStaticResourceDArray[iStaticResDependencyCount++] = pR; - - // Establish resource dependencies - if(CreateResourceDependency(aStaticResourceDArray)) - CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) - - iDependencyResources = aStaticResourceDArray; - - aStaticResourceDCount = iStaticResDependencyCount; - return KErrNone; - } - -// This function establishes above dependency between static dependent resource -TInt DSimulatedPowerResourceController::CreateResourceDependency(DStaticPowerResourceD** pResArray) - { - iNodeArray = new SNode[10]; - SNode* pN1; - SNode* pN2; - iNodeCount = 0; - - if(!iNodeArray) - return KErrNoMemory; - // Create Dependency between Resource A and Resource D - pN1 = &iNodeArray[iNodeCount++]; - pN2 = &iNodeArray[iNodeCount++]; - CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[1], 1, 1) - - // Create Dependency between Resource D and Resource F - pN1 = &iNodeArray[iNodeCount++]; - pN2 = &iNodeArray[iNodeCount++]; - CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[2], 1, 3) - - // Create Dependency between Resource D and Resource E - pN1 = &iNodeArray[iNodeCount++]; - pN2 = &iNodeArray[iNodeCount++]; - CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[3], 3, 2) - - // Create Dependency between Resource E and Resource C - pN1 = &iNodeArray[iNodeCount++]; - pN2 = &iNodeArray[iNodeCount++]; - CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[4], 1, 1) - - // Create Dependency between Resource E and Resource G - pN1 = &iNodeArray[iNodeCount++]; - pN2 = &iNodeArray[iNodeCount++]; - CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[5], 1, 2) - - return KErrNone; - } - -#define CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pRes1, pRes2, priRes1, priRes2) \ - pN1->iPriority = priRes1; \ - pN1->iResource = pRes1; \ - pN1->iPropagatedLevel = 0; \ - pN1->iVisited = EFalse; \ - pN2->iPriority = priRes2; \ - pN2->iResource = pRes2; \ - pN2->iPropagatedLevel = 0; \ - pN2->iVisited = EFalse; \ - pN1->iResource->AddNode(pN2); \ - pN2->iResource->AddNode(pN1);

Creating -dependencies between static resources

DStaticPowerResourceD::AddNode() is -used to establish a dependency between static resources. Dependencies between -static resources cannot be removed.

AddNode() takes -a pointer to an SNode object that contains the dependent -resource information. This passed node pointed is added to the resource dependency -list within the class DStaticPowerResourceD. Note: -the kernel panics if the specified dependency priority is already in use.

Information -within SNode includes:

    -
  • iResource is -a pointer to dependent resource,

  • -
  • iPriority is -the priority of the dependency resource. This is used by the PRM when propagating -the resource change,

  • -
  • iSpare is -reserved for future use,

  • -
  • iNext is -a pointer to next node in the list.

  • -

The members iPropagatedLevel, iRequiresChange and iVisited are -used internally by the PRM.

To link to dynamic resources that support -dependency use the PRM function RegisterResourceDependency() as -described in creating -resource dependencies.

Initialise -the pools

Pools are implemented as singly linked lists during -the initialisation of the PRM. The PSL initialises the pools by invoking DPowerResourceController::InitPools() and -passing the platform defined sizes for the pools of kernel side clients, user -side clients, client levels and requests. See the example DoInitController() implementation.

The PRM has three -types of pools:

    -
  • client pools to store -client information,

  • -
  • request pools to send requests for operation on long latency resource -to the Resource Controller thread,

  • -
  • client level pools to capture the resource level request by each client -for a resource.

  • -

If the client pool is set to zero, then the PRM will not allow a -client of that type to register. For example, if the kernel side clients pool -is set to zero, then the PIL will not allow any kernel side clients to register. -The size of the client pools to specify depends on how many kernel side device -drivers (clients) and user side clients will access PRM and size of request -pool depends on the number of long latency resource available in the system. -Size of client level pool depends on number of clients that will request a -resource state change. If the client pools are exhausted the PIL will try -to increase the size of the pool. The size of the pool never decreases.

Registering with the Power -Controller

The Resource Controller must call DPowerController::RegisterResourceController() to -register itself with the Power Controller. RegisterResourceController() sets -the iResourceControllerData.iResourceController data member -within DPowerController to the passed Resource Controller -pointer and sets iResouceControllerData.iClientId to the -client ID used by the Power Controller when calling the Resource Controller's -APIs.

The platform specific implementation of the Power Controller -overrides the RegisterResourceController() function. See DPowerController::RegisterResourceController().

Idle power management

The resource controller's APIs -cannot be called from a NULL thread. However, the PSL may need to know the -state of the resources from a NULL thread to take the system to appropriate -power states. To allow access to this information the PRM provides the virtual -function DPowerResourceController::RegisterResourcesForIdle().

-
-Porting the -Power Resource Manager -Implement -the controllable power resources -Port client -drivers to use the PRM -Debugging -the PRM -Testing the -PRM PSL + + + + + +Implement +the PSL for the targetThis document describes how to implement the Platform Specific +Layer for the Power Resource Manager. +
Purpose

The PSL must be implemented in order for +the PRM and the hardware to be able to communicate.

Introduction

The +PSL side of the Resource Controller should be derived from the class DPowerResourceController.

+
Implementing the PSL

The following tasks are +covered in this tutorial:

    +
  • Create an entry point,

  • +
  • Override the pure virtual functions,

  • +
  • Create static resources that support dependencies,

  • +
  • Initialise the pools,

  • +
  • Registering with the Power Controller.

  • +

Create an entry +Point

The PIL layer of the PRM offers the following macro. This +needs to be invoked from the PSL. The macro calls the DoInitController() and DoInitResources() functions +implemented by the PSL.

/** +Extension entry point +*/ +DECLARE_RESOURCE_MANAGER_EXTENSION() + { + __KTRACE_OPT(KBOOT, Kern::Printf("CreateController called")); + return new DH4PowerResourceController; + }

If the PRM is a PDD the entry point +is as follows:

static DH4PowerResourceController TheController; +DECLARE_STANDARD_PDD() + { + TInt r = DPowerResourceController::InitController(); + if® == KErrNone) + r = TheController->InitResources(); + if® == KErrNone) + return new DResConPddFactory; + return NULL; + }

Override +the pure virtual functions

Override the virtual functions of the DPowerResourceController base +class:

    +
  • DoInitController(),

  • +
  • DoRegisterStaticResources().

  • +

Here is an example H4 HRP implementation:

class DH4PowerResourceController : DPowerResourceController + { +public: + DH4PowerResourceController(); + TInt DoInitController(); + TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount); +private: + static DStaticPowerResource* iResources[];

DoInitController()

Override DPowerResourceController::DoInitController() so that it creates +a DFC queue and then invokes the base class function DPowerResourceController::SetDfcQ(). DoInitController() should +also initialise the pools by invoking DPowerResourceController::InitPools() passing +the platform defined sizes for the pools of clients, client levels and request +objects. DoInitController() is called by the PSL +during its initialisation. Below is the reference implementation code.

#define KERNEL_CLIENTS 0x2 // Expected number of kernel clients (MMC and Sound_SC) +#define USER_CLIENTS 0x0 // No user side clients expected. +#define CLIENT_LEVELS 0x8 // Expected resource state change of 8 resources +#define REQUESTS 0x0 // No asynchronous operation (state change or read) expected. + +TInt DH4PowerResourceController::DoInitController() + { + // Create a DFC queue and then invoke SetDfcQ() +__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoInitController\n")); + + // NKern::ThreadEnterCS(); // Not needed, as this is executed during kernel boot which is done within a critical section. + TInt r = Kern::DfcQCreate(iDfcQ,28,&KResThreadName); + + // NKern::ThreadLeaveCS(); + if (KErrNone!=r) return r; + SetDfcQ(iDfcQ); + r = InitPools(KERNEL_CLIENTS,USER_CLIENTS,CLIENT_LEVELS,REQUESTS); +__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoInitController\n")); + return r; + }

DoRegisterStaticResources()

DoRegisterStaticResources() is called by the PIL during its initialisation. Override the pure virtual +function DPowerResourceController::DoRegisterStaticResources() so +that it:

    +
  • creates all the static +resources in the kernel heap,

  • +
  • creates an array of +pointers to the static resources (indexed by their id),

  • +
  • sets the passed pointer +(aStaticResourceArray) to point to the created array of pointers,

  • +
  • updates the count of +the static resources (in aStaticResourceCount).

  • +

The reference implementation is below:

TInt DH4PowerResourceController::DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount) + { + aStaticResourceCount = 0; + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoRegisterStaticResources\n")); + aStaticResourceArray = (DStaticPowerResource**) new (DStaticPowerResource*[EH4ResourceCount]); + if(!aStaticResourceArray) + return KErrNoMemory; + + DH4MmcFclkResource *pMmcFclk = new (DH4MmcFclkResource); + if (!pMmcFclk) + return KErrNoMemory; + aStaticResourceArray[EMmcFclkRes] = pMmcFclk; + + DH4MmcIclkResource *pMmcIclk = new (DH4MmcIclkResource); + if (!pMmcIclk) + CLEAN_AND_RETURN(KErrNoMemory, EMmcIclkRes) + aStaticResourceArray[EMmcIclkRes] = pMmcIclk; + + DH4MmcClkResource *pMmcBusClk = new (DH4MmcClkResource); + if (!pMmcBusClk) + CLEAN_AND_RETURN(KErrNoMemory, EMmcClkRes) + aStaticResourceArray[EMmcClkRes] = pMmcBusClk; + + DH4MmcCtrllerPwrResource *pMmcCtrlrPwr = new (DH4MmcCtrllerPwrResource); + if (!pMmcCtrlrPwr) + CLEAN_AND_RETURN(KErrNoMemory, EMmcCtrlrPwrRes) + aStaticResourceArray[EMmcCtrlrPwrRes] = pMmcCtrlrPwr; + + DH4MmcPowerResource *pMmcPwr = new (DH4MmcPowerResource); + if (!pMmcPwr) + CLEAN_AND_RETURN(KErrNoMemory, EMmcPwrRes) + aStaticResourceArray[EMmcPwrRes] = pMmcPwr; + + DH4SndFclkResource *pSndFclk = new (DH4SndFclkResource); + if (!pSndFclk) + CLEAN_AND_RETURN(KErrNoMemory, ESndFclkRes) + aStaticResourceArray[ESndFclkRes] = pSndFclk; + + DH4SndIclkResource *pSndIclk = new (DH4SndIclkResource); + if (!pSndIclk) + CLEAN_AND_RETURN(KErrNoMemory ,ESndIclkRes) + aStaticResourceArray[ESndIclkRes] = pSndIclk; + + DH4SndMClkResource *pSndMclk = new (DH4SndMClkResource); + if (!pSndMclk) + CLEAN_AND_RETURN(KErrNoMemory, ESndMClkRes) + aStaticResourceArray[ESndMClkRes] = pSndMclk; + + aStaticResourceCount = EH4ResourceCount; + + __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoRegisterStaticResources, Total resources:%d\n", EH4ResourceCount)); + + return KErrNone; + }

Create +static resources that support dependencies

If there are static +resources that support dependencies then the PSL must implement the function DPowerResourceController::DoRegisterStaticResourcesDependency(). Note: Static resources that support dependencies are only available +in the extended version of the library. See setup +and configuration.

The function DoRegisterStaticResourcesDependency():

    +
  • creates all static resources +that support dependencies in kernel heap,

  • +
  • creates an array of +pointers to them,

  • +
  • establishes the dependencies +between them (using the resource's DStaticPowerResourceD::AddNode() function), +See creating +dependencies between static resources for a description of AddNode() and +the SNode structure.

  • +
  • sets the passed pointer +(aStaticResourceDArray) to point to the array of pointers +to static resource with dependency,

  • +
  • updates the count of +the static resource that supports dependency in aStaticResourceDCount.

  • +

This function is called by the PIL during PRM initialisation. Below +is an example:

/** +This function creates all static resources that support dependencies and establishes the dependencies between them. This is called by the PIL. +This is the dependency tree input: + ResourceA <---------> ResourceD <-------> ResourceE <--------> ResourceC + | | + | | + | | + ResourceF ResourceG +*/ +TInt DSimulatedPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount) + { + aStaticResourceDArray = (DStaticPowerResourceD**) new (DStaticPowerResourceD*[MAX_DEPENDENT_RESOURCE_COUNT]); + if(!aStaticResourceDArray) + return KErrNoMemory; + + DStaticPowerResourceD* pR = NULL; + + pR = new DMLSLGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSIGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DBSIGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSHIGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DBSHLGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSHLGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + // Establish resource dependencies + if(CreateResourceDependency(aStaticResourceDArray)) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + + iDependencyResources = aStaticResourceDArray; + + aStaticResourceDCount = iStaticResDependencyCount; + return KErrNone; + } + +// This function establishes above dependency between static dependent resource +TInt DSimulatedPowerResourceController::CreateResourceDependency(DStaticPowerResourceD** pResArray) + { + iNodeArray = new SNode[10]; + SNode* pN1; + SNode* pN2; + iNodeCount = 0; + + if(!iNodeArray) + return KErrNoMemory; + // Create Dependency between Resource A and Resource D + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[1], 1, 1) + + // Create Dependency between Resource D and Resource F + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[2], 1, 3) + + // Create Dependency between Resource D and Resource E + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[3], 3, 2) + + // Create Dependency between Resource E and Resource C + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[4], 1, 1) + + // Create Dependency between Resource E and Resource G + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[5], 1, 2) + + return KErrNone; + } + +#define CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pRes1, pRes2, priRes1, priRes2) \ + pN1->iPriority = priRes1; \ + pN1->iResource = pRes1; \ + pN1->iPropagatedLevel = 0; \ + pN1->iVisited = EFalse; \ + pN2->iPriority = priRes2; \ + pN2->iResource = pRes2; \ + pN2->iPropagatedLevel = 0; \ + pN2->iVisited = EFalse; \ + pN1->iResource->AddNode(pN2); \ + pN2->iResource->AddNode(pN1);

Creating +dependencies between static resources

DStaticPowerResourceD::AddNode() is +used to establish a dependency between static resources. Dependencies between +static resources cannot be removed.

AddNode() takes +a pointer to an SNode object that contains the dependent +resource information. This passed node pointed is added to the resource dependency +list within the class DStaticPowerResourceD. Note: +the kernel panics if the specified dependency priority is already in use.

Information +within SNode includes:

    +
  • iResource is +a pointer to dependent resource,

  • +
  • iPriority is +the priority of the dependency resource. This is used by the PRM when propagating +the resource change,

  • +
  • iSpare is +reserved for future use,

  • +
  • iNext is +a pointer to next node in the list.

  • +

The members iPropagatedLevel, iRequiresChange and iVisited are +used internally by the PRM.

To link to dynamic resources that support +dependency use the PRM function RegisterResourceDependency() as +described in creating +resource dependencies.

Initialise +the pools

Pools are implemented as singly linked lists during +the initialisation of the PRM. The PSL initialises the pools by invoking DPowerResourceController::InitPools() and +passing the platform defined sizes for the pools of kernel side clients, user +side clients, client levels and requests. See the example DoInitController() implementation.

The PRM has three +types of pools:

    +
  • client pools to store +client information,

  • +
  • request pools to send requests for operation on long latency resource +to the Resource Controller thread,

  • +
  • client level pools to capture the resource level request by each client +for a resource.

  • +

If the client pool is set to zero, then the PRM will not allow a +client of that type to register. For example, if the kernel side clients pool +is set to zero, then the PIL will not allow any kernel side clients to register. +The size of the client pools to specify depends on how many kernel side device +drivers (clients) and user side clients will access PRM and size of request +pool depends on the number of long latency resource available in the system. +Size of client level pool depends on number of clients that will request a +resource state change. If the client pools are exhausted the PIL will try +to increase the size of the pool. The size of the pool never decreases.

Registering with the Power +Controller

The Resource Controller must call DPowerController::RegisterResourceController() to +register itself with the Power Controller. RegisterResourceController() sets +the iResourceControllerData.iResourceController data member +within DPowerController to the passed Resource Controller +pointer and sets iResouceControllerData.iClientId to the +client ID used by the Power Controller when calling the Resource Controller's +APIs.

The platform specific implementation of the Power Controller +overrides the RegisterResourceController() function. See DPowerController::RegisterResourceController().

Idle power management

The resource controller's APIs +cannot be called from a NULL thread. However, the PSL may need to know the +state of the resources from a NULL thread to take the system to appropriate +power states. To allow access to this information the PRM provides the virtual +function DPowerResourceController::RegisterResourcesForIdle().

+
+Porting the +Power Resource Manager +Implement +the controllable power resources +Port client +drivers to use the PRM +Debugging +the PRM +Testing the +PRM PSL
\ No newline at end of file