1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<html> 3 4<head> 5<META http-equiv="Content-Type" content="text/html; charset=windows-1252"> 6<META name="GENERATOR" content="Microsoft FrontPage 5.0"> 7<META http-equiv="Content-Style-Type" content="text/css"> 8<LINK rel="stylesheet" type="text/css" href="../../CSS/revolution.css"> 9<title>LCStoreBlocks</title> 10</head> 11 12<body> 13 14<h1>LCStoreBlocks</h1> 15 16 17<h2>C Specification</h2> 18 19<dl> 20<dd><pre><code>#include <revolution/os/OSLC.h></code></pre> 21 </dd> 22<dd><pre><code>void LCStoreBlocks(void* <em>destAddr</em>, void* <em>srcTag</em>, u32 <em>numBlocks</em>);</code></pre> 23 </dd> 24</dl> 25<H2>Arguments</H2> 26<TABLE border="1" cellpadding="3" cellspacing="0.1"> 27 <TBODY> 28 <TR> 29<TD width="120" bgcolor="#ffffe8"><EM><STRONG><CODE><STRONG><EM><CODE>destAddr</CODE></EM></STRONG></CODE></STRONG></EM></TD> 30<TD width="520">Start address of the transfer destination in memory. Must be 32 byte-aligned.</TD> 31 </TR> 32 <TR> 33<TD width="120" bgcolor="#ffffe8"><EM><STRONG><CODE><STRONG><EM><CODE>srcTag</CODE></EM></STRONG></CODE></STRONG></EM></TD> 34<TD width="520">Start address for the locked cache address to copy to <CODE><EM><STRONG>destAddr</STRONG></EM></CODE>. Must be 32 byte-aligned.</TD> 35 </TR> 36 <TR> 37<TD width="120" bgcolor="#ffffe8"><STRONG><EM><CODE><STRONG><EM><CODE>numBlocks</CODE></EM></STRONG></CODE></EM></STRONG></TD> 38<TD width="520">Transfer size (number of cache blocks). Must be a value from 0 to 127. If zero is specified, the transfer size is 128 blocks (4 KB).</TD> 39 </TR> 40 </TBODY> 41</TABLE> 42<H2>Return Values</H2> 43<P>None.</P> 44<h2>Description</h2> 45 46<p>Enqueues a single DMA transfer for moving data in a locked cache to main memory. This function is more efficient than calling the <code><a href="LCStoreData.html">LCStoreData</a></code> function, but has a maximum transfer limit of 128 cache blocks (4 KB) and performs no error checking. Addresses are assumed to be 32-byte aligned, and <code><em><strong>numBlocks</strong></em></code> is assumed to be a value from 0 to 127. Note that a value of zero for <STRONG><EM><CODE>numBlocks</CODE></EM></STRONG> implies a transfer size of 128 blocks. The range of valid transfer source addresses is the 16KB region starting from the value returned by the <a href="LCGetBase.html"><code>LCGetBase</code></a> function.</p> 47 48<p>See the following example code that performs quadruple buffering within a locked cache region with this function. This code example is similar to the example for <code><a href="LCStoreData.html">LCStoreData</a></code>.</p> 49 50<p>The only ways to determine if the transfers are complete are to poll the length of the DMA queue with the <code><a href="LCQueueLength.html">LCQueueLength</a></code> function or to wait until the queue length reaches a certain value with the <code><a href="LCQueueWait.html">LCQueueWait</a></code> function. See the following example. </p> 51 52<p>A maximum of 15 outstanding DMA transfers in the DMA queue is allowed. If the queue overflows, a machine check exception occurs.</p> 53 54<p>The locked cache must be enabled throughout the transfer, otherwise a machine check exception will occur during the DMA.</p> 55 56<p>If the DMA finds source data in the normal cache, a machine check exception occurs.</p> 57 58<h3>Example</h3> 59 60<p>The following code example splits the locked cache into 4 buffers, and ping pongs between them to process a large array in main memory. The code is structured so that each buffer at most has one outstanding load and store at any given time. When a buffer has finished storing its old (just processed) data, this information can be used to ensure that loading the next block of data to process has been completed.</p> 61<BLOCKQUOTE><code>// define 4 4k buffers in locked cache region<br> // note that NUMBUFFERS * BUFFER_SIZE <= 16k<br> #define BUFFER_SIZE (4*1024)<br> #define NUM_BUFFERS (4)<br> <br> #define DATA_ELEMENTS (10*1024*1024)<br> :</code></BLOCKQUOTE> 62<BLOCKQUOTE><code>// real mem loc of Buffers[i] is at BufAddr[i]<br> u8* Buffers[NUM_BUFFERS];<br> u8* BufAddr[NUM_BUFFERS]; <br> :<br><br> void main ()<br> {<br> u8* data;<br> u8* currDataPtr; // offset into data<br> u32 i;<br> void* arenaLo;<br> void* arenaHi;<br> <br> OSInit();<br> LCEnable();<br> <br> arenaLo = OSGetArenaLo();<br> arenaHi = OSGetArenaHi();<br> :<br><br> OSReport("Splitting locked cache into %d buffers\n", NUM_BUFFERS);<br> <br> for (i = 0; i < NUM_BUFFERS; i++)<br> {<br> Buffers[i] = (u8*) ((u32)LCGetBase() + BUFFER_SIZE*i);<br> OSReport("Locked Cache : Allocated %d bytes at 0x%x\n",<br> BUFFER_SIZE,<br> Buffers[i]);<br> }<br> <br> // Initialize source data<br> data = (u8*)OSAlloc(DATA_ELEMENTS * sizeof(u8));<br> :<br> DCFlushRange(data, DATA_ELEMENTS);<br> <br> OSReport(" Test 2 : using low level interface for DMA load/store \n");<br> <br> for (i = 0; i < NUM_BUFFERS; i++)<br> {<br> BufAddr[i] = data + BUFFER_SIZE*i;<br> LCLoadBlocks(Buffers[i], BufAddr[i], 0);<br> }<br> <br> currDataPtr = data + BUFFER_SIZE * NUM_BUFFERS;<br> <br> LCQueueWait((NUM_BUFFERS-1));<br> <br> while (currDataPtr <= data+DATA_ELEMENTS)<br> { <br> for (i = 0; i < NUM_BUFFERS; i++)<br> {<br> LCQueueWait((NUM_BUFFERS-1)*2); <br> ProcessBuf(Buffers[i]);<br> LCStoreBlocks(BufAddr[i], Buffers[i], 0);<br> LCLoadBlocks(Buffers[i], currDataPtr, 0);<br> BufAddr[i] = currDataPtr; // move to next unprocessed buffer<br> // advance the next block to be read<br> currDataPtr += BUFFER_SIZE;<br> }<br> }<br> LCQueueWait(NUM_BUFFERS); // don't care about last dma's<br> :<br> OSHalt("Test complete");<br> }<br></code></BLOCKQUOTE> 63 64 65 66<h2>See Also</h2> 67 68<p><a href="../list.html#Cache" target="contents">Cache Functions</a>, <br> <code><a href="LCEnable.html">LCEnable</a>, <a href="LCStoreData.html">LCStoreData</a>, <a href="LCLoadBlocks.html">LCLoadBlocks</a>, <a href="LCQueueLength.html">LCQueueLength</a>, <a href="LCQueueWait.html">LCQueueWait</a></code></p> 69 70<h2>Revision History</h2> 71<P>03/01/2006 Initial version.</P> 72</body> 73</html>