Adaptation/GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita
changeset 15 307f4279f433
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adaptation/GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita	Fri Oct 15 14:32:18 2010 +0100
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D" xml:lang="en"><title>Controllable
+Power Resources</title><shortdesc>This topic explains how power resources were controlled in older
+releases of Symbian platform. For later releases see the Power Resource Manager
+documentation.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>This documentation is retained for reference for those working with hardware
+or software that is based on older versions of Symbian platform version (in
+particular old release 9.5). For later releases see the <xref href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita">Porting
+the Power Resource Manager</xref> documentation.</p>
+<p>Controllable power resources are defined as being any device resource,
+such as voltages on power-lines or clocks, which can be independently enabled,
+disabled or modified under software control. </p>
+<p>The following hardware block diagram is an example of the way power resources
+might be arranged: </p>
+<fig id="GUID-41113C18-2C87-5DEA-9D05-31083F51269A">
+<title>Example power resource arrangement</title>
+<image href="GUID-622D6337-E60A-5252-8B2B-BA8232927453_d0e29152_href.png" placement="inline"/>
+</fig>
+<p>There is no default support or default implementation for controllable
+power resources in the generic layers of Symbian platform. They must be managed
+by the base port. </p>
+<p>We suggest that the management of controllable power resources (the resource
+manager) be implemented in the Variant DLL or the ASSP DLL. This allows the
+resource manager to be up and running by the time peripheral drivers, which
+might also be kernel extensions, are loaded. See the <xref href="GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF.dita#GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF/GUID-95C34114-F986-5428-9D40-5CF64429CDBD">ASSP/Variant Architecture</xref> and the <xref href="GUID-ECAC3FF3-CDB2-5153-AD76-90732BA83726.dita#GUID-ECAC3FF3-CDB2-5153-AD76-90732BA83726/GUID-F55D88DB-7DE1-5069-BAE7-A7FE3750D065">ASSP/Variant
+Tutorials</xref>. </p>
+<p>A suggested implementation has the instance of the <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref> derived
+class owning a pointer to the resource manager object. The interface class
+for the ASSP or Variant could then have an exported or an inline member function
+to return a pointer to this resource manager object. Peripheral drivers are
+expected to link against either the ASSP DLL, or the Variant DLL, or both. </p>
+<p>For example, for a device that has a Variant and an ASSP: </p>
+<codeblock id="GUID-049CEE21-944A-589A-9F1B-8F031D681198" xml:space="preserve">class MyVariant : public MyASSP
+    {
+public:
+    Init1();
+    Init3();
+    // Other mandatory Asic-derived member functions
+    ...
+public:
+    ResourceManager* myResMgrPtr;
+    ...
+    };
+      </codeblock>
+<p>where class <codeph>MyASSP</codeph> is derived from class <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref>. </p>
+<codeblock id="GUID-E8346FFB-1B0F-5482-9DF7-207B1B1948F8" xml:space="preserve">GLREF_D MyVariant TheVariant;</codeblock>
+<codeblock id="GUID-CEF1F0C7-62E4-52B1-9830-DBD32B2BE8CE" xml:space="preserve">class TMyVariant
+    {
+public:
+    inline static ResourceManager* ResourceManager()
+        {return(TheVariant.myResMgrPtr);}
+    // other exported methods
+    ...
+    };
+      </codeblock>
+<p>where <codeph>TMyvariant</codeph> is the Variant interface class, and <codeph>ResourceManager</codeph> is
+the resource manager class. </p>
+<p>The resource manager can be declared as a global object at the Variant
+(or ASSP) scope and can therefore be created when this component is first
+loaded. In this case, the <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-FE55E398-7F08-384F-9E74-2CC2E45002B6"><apiname>Asic::Init3()</apiname></xref> function would
+initialise the <codeph>ResourceManager</codeph> object, and set up <codeph>myResMgrPtr</codeph>.
+Alternatively, if the Variant (or ASSP) were to need the resource manager
+up and running, then you would initialise <codeph>ResourceManager</codeph> in <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-63F2135B-4264-3B3B-9B68-656A89BF7EE9"><apiname>Asic::Init1()</apiname></xref>. </p>
+<p>In this implementation, the Variant would export a header file(s) publishing
+a list of controllable power resources. </p>
+<section id="GUID-CC741BCC-D96E-4FB7-AA8C-7635D4131DE0"><title>Shared controllable
+power resources</title> <p>Some controllable power resources can be shared
+between groups of peripherals and therefore may require usage tracking. </p> <p>We
+recommend that shared power resources be represented by a class derived from <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref>.
+This class offers the <codeph>Use()</codeph> and <codeph>Release()</codeph> interface
+that encapsulates resource counting behaviour. This mechanism should turn
+the resource on when the count becomes non-zero, and turn the resource off
+when the count becomes zero. </p> <p>We suggest that your <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
+class defines and implements a <codeph>GetCount()</codeph> function that returns
+the usage count on the shared resource. </p> </section>
+<section id="GUID-37A4098A-5E44-5744-BCE1-CDC8B876E654"><title>A suggested
+implementation of a resource manager</title> <p>While we have implied that
+a resource manager is a single class, which we have called <codeph>ResourceManager</codeph>,
+the resource manager is a notional concept for controlling power resources. <i>Symbian
+neither mandates a format for a ResourceManager class, nor even its existence</i>.
+In practice, it may be more useful to embed resource manager functions and
+data in the Variant interface class (or the ASSP interface class, if appropriate). </p> <p>However,
+for the purpose of explaining what a resource manager can do, it is easier
+to assume that this behaviour is handled by a resource manager class. This
+is the outline definition of such a class. </p> <codeblock id="GUID-BB326270-B8C6-5398-AB36-FA50011004CA" xml:space="preserve">class ResourceManager
+    {
+public:    
+    void InitResources();                            // called by your Asic::Init3()/Asic::Init1()
+    void Modify(TUint aSetMask, TUint aClrMask);    // only 32 simple Resources can be managed
+    TBool GetResourceState(TUint aResBitMask);    // only 1 bit set on this mask, returns On/Off
+public:
+    (MPowerInput-derived) iSharedResource1;        // 1 per shared resource
+    (MPowerInput-derived) iSharedResource2;
+    ...
+    };
+      </codeblock> <p>The <codeph>InitResources()</codeph> function would
+do at least two things: </p> <ul>
+<li id="GUID-29FA1D5C-0691-5EB2-A45A-5925D5C58A56"><p>enable an appropriate
+set of simple resources at boot time </p> </li>
+<li id="GUID-6F0D4084-48E9-585B-857B-F67B7B453DC7"><p>initialise the shared
+power resource tracking objects, i.e. the instances of your <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
+class(es). </p> </li>
+</ul> <p>The function would be called by the Variant or ASSP implementation
+of <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-FE55E398-7F08-384F-9E74-2CC2E45002B6"><apiname>Asic::Init3()</apiname></xref> or <xref href="GUID-21641835-7103-374B-9FBB-FAB1875D59A5.dita"><apiname>Asic:Init1()</apiname></xref>. </p> <p>The <codeph>Modify()</codeph> function
+is an example of how to deal with power resources that are either on or off.
+The function would take bit masks, where a bit represents a separate controllable
+power resource. The first bit mask would represent the set of power resources
+to be turned on, while the second would represent the set of power resources
+to be turned off. This assumes that the function could behave synchronously.
+Drivers for peripherals that use a set of these controllable power resources,
+would call <codeph>Modify()</codeph> to turn the relevant controllable power
+resources on or off. </p> <p>As an example, the most common method of switching
+clock resources on or off is by setting and clearing bits in a hardware register.
+A base port could choose to implement common code for setting bits in registers. </p> <p>A
+shared power resource is further represented by a <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
+class. The implementations of <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita#GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A/GUID-2BCA5312-43D9-3763-9636-3B2EB046D2C1"><apiname>MPowerInput::Use()</apiname></xref> and <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita#GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A/GUID-606ECD77-A5F7-3408-9B63-C68C0A7B73C6"><apiname>MPowerInput::Release()</apiname></xref> would
+call <codeph>Modify()</codeph> to turn on the shared resource when the usage
+count becomes non zero, or turn it off when the usage count reaches zero.
+Peripheral drivers would have access to shared resources, and also to the
+member functions of the <codeph>ResourceManager</codeph> class, through the
+ASSP or Variant Interface class function that returns a pointer to it. </p> <p>The
+resource manager, or its functions and members, could be offered as part of
+a power controller interface class, the <codeph>TPowerController</codeph> class
+suggested when we discussed the implementation of the <xref href="GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita">Power
+Controller</xref>'s <xref href="GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita#GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703/GUID-5A0CAD08-AA12-56EE-B0A3-75548D1896C9">EnableWakeupEvents()</xref> function.
+The class would provide an exported function that would give access to the
+resource manager. The resource manager class would be made part of the power
+controller kernel extension. Peripheral drivers needing access to shared power
+resources would then link to the power controller DLL. If the Variant or ASSP
+were also to need access to the resource manager, then the resource manager
+would have to be initialised much earlier in the kernel start-up sequence.
+In this case, we would suggest that the standard power controller kernel extension
+entry point defined by <xref href="GUID-7964FC46-4641-3BDD-92C9-50FA22C3321A.dita"><apiname>DECLARE_STANDARD_EXTENSION()</apiname></xref> be
+replaced with a custom entry point that might look like this: </p> <codeblock id="GUID-B5262624-C7B8-51E4-AE14-1D905DFC0A99" xml:space="preserve">GLDEF_C TInt KernelModuleEntry(TInt aReason)
+    {
+    if(aReason==KModuleEntryReasonVariantInit0)
+        {
+        ResourceManager* c = new ResourceManager ();    // create Resource Manager
+        return c ? KErrNone : KErrNoMemory;    
+        }
+    else if(aReason==KModuleEntryReasonExtensionInit0)
+        {
+        (create DPowerController and Battery Monitor and Power HAL handler)
+        }
+    return KErrNone;         // gets here from calling with KModuleEntryReasonExtensionInit1
+    }
+        </codeblock> <p>The Variant or ASSP would also need to link to the
+power controller DLL. </p> <p>The following base port software architecture
+could be applied to the power supply arrangement as illustrated in the hardware
+block diagram above (see the beginning of this section at <xref href="GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita">Controllable
+Power Resources</xref>): </p> <fig id="GUID-309A6C5E-A347-5E04-B2C8-426A81755226">
+<title>Base port software architecture</title>
+<image href="GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36_d0e29378_href.png" placement="inline"/>
+</fig> </section>
+<section id="GUID-C4C67612-C5CD-5D64-B257-259FD12443C9"><title>Multi-level,
+composite and asynchronous power resources</title> <p>Some power resources
+may have more than one operational level. For example, it is possible that
+an input clock to a peripheral can be operated at a nominal value corresponding
+to the fully active state, and may be lowered to another level corresponding
+to the power saving state. </p> <p>The same could apply to the input voltages
+that the peripheral can operate on. The control model suggested above for
+simple resources may not be appropriate. A suggested alternative would have
+these multi-Level resources implementing an interface that offers a public
+enumeration to cover all possible usage levels at which the resource can be
+used, and APIs such as: </p> <codeblock id="GUID-44492A89-C7DC-5C97-928C-549BEAD38161" xml:space="preserve">class MultiLevelResource
+    {
+    enum TResourceLevel
+        {
+        EOperationalLevel1,
+        EOperationalLevel2,
+        . . .
+        ELowPowerLevel1,
+        ELowPowerLevel2,
+        . . .
+        };
+    void UseToLevel();
+    void ReleaseToLevel();
+    TResourceLevel GetCurrentLevel();
+    . . . 
+    };</codeblock> <p>More importantly, it is possible that resources may
+have to be operated in combination with other resources. For example, some
+peripherals may have more than one input clock, and on transition between
+power states, these clocks may have to be changed simultaneously. </p> <p>If
+the resources to be actuated simultaneously are simple resources, then the
+model above with a <codeph>Modify()</codeph> call that takes a bit mask and
+allows more than one resource to be changed at a time may be appropriate.
+If the resources to be actuated are shared or multi-level, or have to be represented
+individually, then another interface will have to be defined to allow modifying
+more than one of them simultaneously. </p> <p>Modifying some resources may
+not be an instantaneous operation. For example, it may take a non-negligible
+amount of time to stabilise an input clock that has just been modified. </p> <p>The
+nature of EKA2 strongly discourages actively waiting (or “spinning”) inside
+drivers; instead it is suggested that the multithreading capabilities of EKA2
+kernel side code and the synchronisation mechanisms available be used to solve
+the problem of having the driver code having to wait for a resource to stabilise
+before proceeding with its use. </p> <p>As an example, let us assume that
+the multi-level resource mentioned above has a non-negligible delay associated
+with any level changes: </p> <ul>
+<li id="GUID-0549E815-BB6E-55C7-84DB-FB6A2ACA11AC"><p>If the length of time
+to wait for a power resource to stabilise is known, and is the order of a
+few milliseconds or less, or the driver executes on its unique kernel thread
+(not used by any other kernel-side code), then the best solution would be
+to sleep the driver thread, by calling <codeph>NKern::Sleep(aTime)</codeph> for
+the specified length of time after issuing a call to <codeph>UseToLevel()</codeph> (or <codeph>ReleaseToLevel()</codeph>). </p> </li>
+<li id="GUID-9F0FCB9F-2827-528A-B3D0-FEE6CF8470CD"><p>When the length of time
+to wait for a power resource to stabilise increases, then sleeping the driver
+thread may become a problem if the driver executes in a DFC queue used by
+other drivers, which is often the case. This is because blocking that thread
+means that no other drivers can run. Here, the best solution is for the driver
+to create another thread and DFC queue, by calling <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-B9D637A1-4EB9-39F7-8C5C-2C546994C4B8"><apiname>Kern::DfcQInit()</apiname></xref>,
+and whenever it needs to change the resource, queue a DFC on that queue, which
+will issue the calls to <codeph>UseToLevel()</codeph> (or <codeph>ReleaseToLevel()</codeph>)
+and then sleep the thread. </p> </li>
+<li id="GUID-C8472B27-FC27-5C72-B6C2-A0DA681EA3C6"><p>If the length of time
+to change a power resource cannot be known in advance, but the hardware provides
+an indication of completion of the change, for example, in the form of an
+interrupt, then the solution may involve the driver code waiting on a Fast
+Mutex, which is signalled by the completion event (in code belonging to the <codeph>MultiLevelResource</codeph> derived
+object). </p> </li>
+</ul> </section>
+</conbody></concept>
\ No newline at end of file