Adaptation/GUID-E7E67A52-0725-446B-A49C-CF571C4A0C64.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-E7E67A52-0725-446B-A49C-CF571C4A0C64" xml:lang="en"><title>DMA
       
    13 Buffer Operations</title><shortdesc>This document describes how a device driver allocates and deallocates
       
    14 DMA buffers.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <section id="GUID-74A2C413-DF2C-4DB6-917B-A4B6CD05612F"><title> Allocation</title> <p>DMA
       
    16 requires contiguous memory chunks to be allocated to do copy and read operations.
       
    17 A driver can do this by using the Symbian Kernel API. A contiguous block of
       
    18 memory can be allocated using <xref href="GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680.dita#GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680/GUID-B506D835-505D-3D89-A840-475F291908DC"><apiname>Epoc::AllocPhysicalRam()</apiname></xref>,
       
    19 which provides the physical address of the contiguous memory block allocated. </p> <p>After
       
    20 allocating the buffer, a global hardware chunk must be created, and its attributes
       
    21 set. The attributes define chunk properties such as whether it is non-cacheable,
       
    22 or whether it can be accessed only in supervisor mode, and so on. </p> <codeblock id="GUID-69AB812C-2497-5005-9BA4-F78BA6DB5A52" xml:space="preserve">TInt DExDriverUartTxDma::Init()
       
    23     {
       
    24     // Round up the transmit chunk size to the page size.     
       
    25     // Kern::RoundToPageSize() rounds up the argument to the size of 
       
    26     // a MMU page. The size of one MMU page can be found out by calling 
       
    27     // Kern::RoundToPageSize(1).
       
    28     //
       
    29     iTxBufSize = Kern::RoundToPageSize (KRxTxDMABufferSize);
       
    30 
       
    31     // Epoc::AllocPhysicalRam() allocate contiguous physical memory 
       
    32     // for the transmit buffer of the specified size, and returns the physical address 
       
    33     // of the buffer. We need contiguous block of memory and its 
       
    34     // physical address for DMA.
       
    35     //
       
    36     TInt r = Epoc::AllocPhysicalRam (iTxBufSize, iTxPhysAddr);
       
    37     if (r != KErrNone)
       
    38         {
       
    39         return r;
       
    40         }
       
    41 
       
    42     // Create a global hardware chunk for the buffer allocated using 
       
    43     // Epoc::AllocPhysicalRam() and set attributes to make it 
       
    44     // uncached and accessible only by kernel-side code. 
       
    45     // Contiguous, uncached, unbuffereable RAM pages avoids 
       
    46     // coherency and fragmentation issues while using DMA.
       
    47     // However, in case of making buffers cacheable other APIs are     
       
    48     // provided to synch, i.e. flush cache before doing a DMA 
       
    49     // transfer 
       
    50     // 
       
    51     r = DPlatChunkHw::New(iTxChunk, iTxPhysAddr, iTxBufSize,
       
    52     EMapAttrSupRw // Supervisor mode, user has no access
       
    53     |EMapAttrFullyBlocking); // uncached, unbuffered    
       
    54     if (r != KErrNone)
       
    55         {
       
    56         // Free the allocated RAM, that was earlier allocated by         
       
    57         // Epoc::AllocPhysicalRam(). 
       
    58         Epoc::FreePhysicalRam(iTxPhysAddr, iTxBufSize);
       
    59         return r;
       
    60         }
       
    61     ...
       
    62     }</codeblock> <p>Buffers can also be made cacheable, in which case, the
       
    63 driver has to ensure to synchronise by flushing the cache before writing and
       
    64 after reading. </p> <codeblock id="GUID-8C452D9B-6674-5B2F-931B-7C671F9E60DC" xml:space="preserve">// Synchronises cache(s) prior to a DMA write operation. i.e. 
       
    65 // before DMA is used write to a peripheral data which is read 
       
    66 // from RAM.
       
    67 void Cache::SyncMemoryBeforeDmaWrite(TLinAddr aBase, 
       
    68                 TUint aSize, TUint32 aMapAttr)
       
    69 
       
    70 // Synchronizes cache(s) prior to a DMA read operation.
       
    71 // i.e. before DMA is used read from a peripheral data which is 
       
    72 // written to RAM.
       
    73 void Cache::SyncMemoryBeforeDmaRead(TLinAddr aBase, 
       
    74                 TUint aSize, TUint32 aMapAttr)
       
    75 
       
    76 // Synchronises cache(s) after a DMA read operation.
       
    77 void Cache::SyncMemoryAfterDmaRead(TLinAddr aBase, TUint aSize)</codeblock> <p>However,
       
    78 unless required by design, DMA chunks are used in non-cacheable and non-buffered
       
    79 mode. </p></section>
       
    80 <section id="GUID-76E909F6-65D5-41BB-8B86-03801F42C8D6"><title>Deallocation</title> <p>DMA buffers have to be deallocated
       
    81 when they are no longer used. Buffers are deallocated in the physical channel
       
    82 destructor. </p> <p>Like allocation, deallocation is performed in two stages.
       
    83 When you allocate, the contiguous buffer is allocated and a hardware chunk
       
    84 is created; when you de-allocate, the contiguous buffer is deallocated and
       
    85 the chunk is closed. </p></section>
       
    86 </conbody></concept>