Adaptation/GUID-43782364-0865-43D0-BC89-D63BA9912FB6.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-43782364-0865-43D0-BC89-D63BA9912FB6" xml:lang="en"><title>Basic Management</title><shortdesc>This document describes how device drivers should manage shared
       
    13 chunks.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <section id="GUID-A30FD089-100B-44A3-B174-A68C7BC00372"><title>Creation</title> <p>A
       
    15 shared chunk is created in kernel space. The user is given a handle to the
       
    16 shared chunk to access it, and can pass the handle to other process or other
       
    17 drivers. Chunks are represented by <xref href="GUID-85454082-6734-3F1D-983F-734D4C2AB12D.dita"><apiname>DChunk</apiname></xref> objects on the
       
    18 kernel side and by <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> on the user side. </p> <p>A shared
       
    19 chunk is created by using <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-F8D1FB29-7238-3438-951A-6F853C7CF817"><apiname>Kern::ChunkCreate()</apiname></xref>, which takes
       
    20 a <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita"><apiname>TChunkCreateInfo</apiname></xref> argument that sets the chunk properties. </p> <p>Chunk
       
    21 creation should be done in a critical section, created using <xref href="GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02.dita#GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02/GUID-841D587C-E9E6-34EE-8ED0-E9A206F64379"><apiname>NKern::ThreadEnterCS()</apiname></xref> and <xref href="GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02.dita#GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02/GUID-2C897BA5-2BD7-3ABA-9F2B-F0B1AC14D1AE"><apiname>NKern::ThreadLeaveCS()</apiname></xref>. The size of the chunk should be in multiples of MMU pages, which can be
       
    22 calculated using <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-B37D12CF-449A-3EC3-9C4F-854A35E98CE3"><apiname>Kern::RoundToSize(n)</apiname></xref>, where <varname>n</varname> is
       
    23 the actual size that needs to be rounded. </p> <codeblock id="GUID-5F307D2C-517B-505D-A8D3-A4820B612E53" xml:space="preserve">/**
       
    24  Create a transmit shared chunk of specified size.
       
    25  
       
    26  @param    aChunkSize
       
    27          size of the chunk to be created
       
    28              
       
    29  @return    KErrNone on success, standard error code on failure
       
    30  */    
       
    31 TInt DExUartPhysicalChannel::CreateTxChunk(TUint aChunkSize)
       
    32     {
       
    33     ...
       
    34     // Round up the transmit chunk size to the page size. 
       
    35     // Kern::RoundToPageSize() rounds up the argument to the size 
       
    36     // of a MMU page. The size of one MMU page can be found out by 
       
    37     // calling Kern::RoundToPageSize(1). 
       
    38  
       
    39     size=Kern::RoundToPageSize(aChunkSize);
       
    40         
       
    41     // Thread must be in critical section 
       
    42     NKern::ThreadEnterCS();
       
    43     ...
       
    44     // Create the chunk. Example is given in next code snippet
       
    45     ...
       
    46     // Commit the chunk. Example is given in following sections
       
    47     ...
       
    48     // Thread can leave the critical section 
       
    49     NKern::ThreadLeaveCS();
       
    50     }
       
    51 
       
    52 TInt DExUartPhysicalChannel::CreateTxChunk(TUint aChunkSize)
       
    53     {
       
    54     ...
       
    55     NKern::ThreadLeaveCS(); // Enter the critical section
       
    56         
       
    57     // TChunkCreateInfo holds the parameters required to create a 
       
    58     // chunk and is used by Kern::ChunkCreate()
       
    59     TChunkCreateInfo info;
       
    60     
       
    61     // ESharedKernelMultiple specifies that a chunk which may be opened by 
       
    62     // any number of user side processes
       
    63     info.iType=TChunkCreateInfo::ESharedKernelMultiple;        
       
    64     info.iMaxSize= size;        // Chunk size
       
    65     
       
    66     // This specifies the caching attributes for the chunk. It can 
       
    67     // be no caching or fully caching (TMappingAttributes enum 
       
    68     // type). If the MMU does not support the requested attributes,  
       
    69     // then a lesser cached attribute will be used. The actual 
       
    70     // value used is returned in aMapAttr of Kern::ChunkCreate() 
       
    71     info.iMapAttr=EMapAttrFullyBlocking; // No Caching, suitable for DMA
       
    72     
       
    73     // Set to true if the chunk is to own its committed memory. 
       
    74     // In this case all memory committed to the chunk will come 
       
    75     // from the system's free pool and will be returned there when 
       
    76     // the chunk is destroyed. If the chunk will be committed to 
       
    77     // physical address, then EFalse can be set.
       
    78     info.iOwnsMemory=ETrue;            // using RAM pages
       
    79     
       
    80     // As chunk destruction is asynchronous we can have 
       
    81     // a DFC, if required, specifying a callback function to get 
       
    82     // the chunk destroy notification exactly. This is used if any 
       
    83     // follow up cleaning has to be done after chunk destruction.
       
    84     info.iDestroyedDfc=NULL;    // No chunk destroy DFC.
       
    85     
       
    86     DChunk* chunk;
       
    87     TUint32 mapAttr;
       
    88     // Creates a chunk that can be shared between a user thread and a 
       
    89     // kernel thread. This will be the initial step for a shared 
       
    90     // chunk. Once created, the chunk owns a region of linear 
       
    91     // address space of the requested size. This region is empty 
       
    92     // (uncommitted) so before it can be used either RAM or I/O 
       
    93     // devices must be mapped into it. This is achieved with the 
       
    94     // Commit functions.
       
    95     // Here iTxChunkKernAddr returns the linear address of the 
       
    96     // chunk created.
       
    97     //
       
    98     TInt r=Kern::ChunkCreate(info,chunk,iTxChunkKernAddr, mapAttr);
       
    99     if (r!=KErrNone)
       
   100         {
       
   101         // Thread can leave the critical section
       
   102         NKern::ThreadLeaveCS();
       
   103         return r;
       
   104         }
       
   105     ...
       
   106     }</codeblock> </section>
       
   107 <section id="GUID-84D1C7D6-5EFE-4D88-BC87-1D8897693B8A"><title>Destruction</title> <p>To allow a chunk to be properly cleaned
       
   108 up, a driver should close the chunk when it is no longer required. When a
       
   109 chunk is closed, the reference count is decremented by one. The chunk gets
       
   110 destroyed when the reference count becomes zero. Closing the chunk should
       
   111 be done within a critical section. </p> <p>The destruction of the chunk happens
       
   112 asynchronously, and a notification of this can be requested. This is done
       
   113 using a DFC, by initialising <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-F6394BC5-16A9-383B-8E5D-446FB3136762"><apiname>TChunkCreateInfo::iDestroyDfc()</apiname></xref> with
       
   114 the DFC object. </p> <codeblock id="GUID-14F48A69-FCDF-5D5A-A6C6-42E4D57CB497" xml:space="preserve">/**
       
   115  Close the transmit chunk, that was already created. This is 
       
   116  called while closing the logical channel
       
   117  */
       
   118 void DExUartPhysicalChannel::CloseTxChunk()
       
   119     {
       
   120     // Thread must be in critical section
       
   121     NKern::ThreadEnterCS();
       
   122     
       
   123     // Atomically get pointer to our chunk and NULL the iChunk 
       
   124     // member. Nkern::SafeSwap() atomically replaces the word 
       
   125     // referenced by aPtr with aNewValue, here NULL.
       
   126     //
       
   127  DChunk* chunk = (DChunk*)NKern::SafeSwap(NULL,(TAny*&amp;)iTxChunk);
       
   128     
       
   129     if (chunk)
       
   130         {
       
   131         // Close the chunk that was created. This should be 
       
   132         // done in a critical section. This function decrements 
       
   133         // a chunk's access count, and, if the count reaches 
       
   134         // zero, the chunk is scheduled for destruction.
       
   135         // ChunkClose() has to be called the same number of times 
       
   136         // as chunk creation. A mismatch in this will result 
       
   137         // in either a memory leak or a panic.
       
   138         //
       
   139         Kern::ChunkClose(chunk);
       
   140         }
       
   141     // Thread can leave the critical section    
       
   142     NKern::ThreadLeaveCS();        
       
   143     }</codeblock></section>
       
   144 <section id="GUID-2CCEB305-03D7-44A4-A489-3B00680383F9"><title>Mapping</title> <p>Shared chunks must be mapped to memory,
       
   145 which means that either RAM or an I/O device must be committed to a shared
       
   146 chunk before it can be used. This maps the chunk to a certain address. The
       
   147 memory can be physical contiguous RAM pages, an arbitrary set of RAM pages,
       
   148 a physical region, or a physical region with a list of physical addresses.
       
   149 The Kernel provides the following APIs for committing these types of memory: </p> <codeblock id="GUID-256A14F7-D9D8-528A-8E8A-C573A492F803" xml:space="preserve">// Commit RAM to a shared chunk. The memory pages to commit are 
       
   150 // obtained from the system's free pool
       
   151 TInt Kern::ChunkCommit(DChunk *aChunk, TInt aOffset, TInt aSize);
       
   152 
       
   153 // Commit RAM to a shared chunk. The memory pages to commit are 
       
   154 // obtained from the system's free pool and will have physically 
       
   155 // contiguous addresses. Used when TChunkCreateInfo::iOwnsMemory 
       
   156 // is ETrue
       
   157 TInt Kern::ChunkCommitContiguous(DChunk *aChunk, TInt aOffset, 
       
   158                 TInt aSize, TUint32 &amp;aPhysicalAddress);
       
   159 
       
   160 // Commit memory to a shared chunk. The physical region committed 
       
   161 // is that which starts at the supplied physical address. 
       
   162 // Typically, this region either represents memory mapped I/O, or 
       
   163 // RAM that was set aside for special use at system boot time. 
       
   164 // This is used when TChunkCreateInfo::iOwnsMemory is EFalse.
       
   165 TInt Kern::ChunkCommitPhysical(DChunk *aChunk, TInt aOffset, 
       
   166                 TInt aSize, TUint32 aPhysicalAddress);
       
   167 
       
   168 // Commit memory to a shared chunk. The physical region committed
       
   169 // is determined by the list of physical addresses supplied to 
       
   170 // this function
       
   171 TInt Kern::ChunkCommitPhysical(DChunk *aChunk, TInt aOffset, 
       
   172         TInt aSize, const TUint32 *aPhysicalAddressList);
       
   173 </codeblock></section>
       
   174 </conbody></concept>