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>LCStoreData</title>
10</head>
11
12<body>
13
14<h1>LCStoreData</h1>
15
16
17<h2>C Specification</h2>
18
19<dl>
20<dd><pre><code>#include &lt;revolution/os.h&gt;</code></pre>
21  </dd>
22<dd><pre><code>u32 LCStoreData(void* <em>destAddr</em>, void* <em>srcAddr</em>, u32 <em>nBytes</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>destAddr</CODE></STRONG></EM></TD>
30<TD width="520">Start address of the destination in memory. Must be 32-byte aligned.</TD>
31    </TR>
32    <TR>
33<TD width="120" bgcolor="#ffffe8"><EM><STRONG><CODE>srcAddr</CODE></STRONG></EM></TD>
34<TD width="520">Start address for the locked cache address to be copied 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>nBytes</CODE></EM></STRONG></CODE></EM></STRONG></TD>
38<TD width="520">Transfer size. Must be 32-byte aligned.</TD>
39    </TR>
40  </TBODY>
41</TABLE>
42<H2>Return Values</H2>
43<P>Returns the number of transactions added to the DMA queue.</P>
44<h2>Description</h2>
45
46<p>Enqueues DMA transactions to send data from the locked cache at <code><em><strong>srcAddr</strong></em></code> to main memory at <code><em><strong>destAddr</strong></em></code>. The range of valid source addresses is the 16KB region starting from the value returned by <a href="LCGetBase.html"><code>LCGetBase</code></a>.&nbsp;The number of transactions issued is returned.</p>
47
48<p>The only way to determine if the transactions are complete is to poll the length of the DMA queue with <code><a href="LCQueueLength.html">LCQueueLength</a></code>, or to wait until the queue length reaches a certain value with <code><a href="LCQueueWait.html">LCQueueWait</a></code>. See the example below.&nbsp;</p>
49
50<p>The largest allowed single DMA transfer is 128 cache blocks (4 KB).&nbsp;Thus, the number of transfers added (to DMA queue) is always rounded up <code>(nBytes/4 KB)</code> . <a href="LCStoreBlocks.html">LCStoreBlocks</a></code> is a more efficient function that creates a single DMA transfer. However, it does not provide error checking or argument restrictions.</p>
51
52<p>No more than 15 outstanding DMA transfers are allowed in the DMA queue.&nbsp;If the queue overflows, a machine check exception will occur.</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 the source address 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 2 buffers, and ping pongs between them to process a large array in main memory.&nbsp;The code is structured so that each buffer has no more than one outstanding load and store at any given time.&nbsp;When a buffer finishes storing its old (freshly processed) data, this information can be used to ensure the next block of data to process loads correctly.</p>
61<BLOCKQUOTE><code>// define 2 8k buffers in locked cache region<br> // note that NUMBUFFERS * BUFFER_SIZE &lt;= 16k<br> #define BUFFER_SIZE (8*1024)<br> #define NUM_BUFFERS (2)<br> <br> #define DATA_ELEMENTS (10*1024*1024)<br> :<br><br>// 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> &nbsp;&nbsp;&nbsp; u8* data;<br> &nbsp;&nbsp;&nbsp; u8* currDataPtr; // offset into data<br> &nbsp;&nbsp;&nbsp; u32 i;<br> &nbsp;&nbsp;&nbsp; void* arenaLo;<br> &nbsp;&nbsp;&nbsp; void* arenaHi;<br> &nbsp;&nbsp;&nbsp; u32 numTransactions;</code></BLOCKQUOTE>
62<BLOCKQUOTE><code>&nbsp;&nbsp;&nbsp; OSInit();<br> &nbsp;&nbsp;&nbsp; LCEnable();<br> <br> &nbsp;&nbsp;&nbsp; arenaLo = OSGetArenaLo();<br> &nbsp;&nbsp;&nbsp; arenaHi = OSGetArenaHi();<br> &nbsp;&nbsp;&nbsp; :<br>&nbsp;&nbsp;&nbsp; OSReport(&quot;Splitting locked cache into %d buffers\n&quot;, NUM_BUFFERS);<br> <br> &nbsp;&nbsp;&nbsp; for (i = 0; i &lt; NUM_BUFFERS; i++)<br> &nbsp;&nbsp;&nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Buffers[i] = (u8*) ((u32)LCGetBase() + BUFFER_SIZE*i);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OSReport(&quot;Locked Cache : Allocated %d bytes at 0x%x\n&quot;,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BUFFER_SIZE,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Buffers[i]);<br> &nbsp;&nbsp;&nbsp; }<br> <br> &nbsp;&nbsp;&nbsp; // Initialize source data<br> &nbsp;&nbsp;&nbsp; data = (u8*)OSAlloc(DATA_ELEMENTS * sizeof(u8));<br> &nbsp;&nbsp;&nbsp; :<br>&nbsp;&nbsp;&nbsp; DCFlushRange(data, DATA_ELEMENTS);<br> <br> &nbsp;&nbsp;&nbsp; OSReport(&quot; Test 1 : using high level interface for DMA load/store \n&quot;);<br> <br> &nbsp;&nbsp;&nbsp; for (i = 0; i &lt; NUM_BUFFERS; i++)<br> &nbsp;&nbsp;&nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufAddr[i] = data + BUFFER_SIZE*i;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTransactions = LCLoadData(Buffers[i], BufAddr[i], BUFFER_SIZE);<br> &nbsp;&nbsp;&nbsp; }<br> <br> &nbsp;&nbsp;&nbsp; currDataPtr = data + BUFFER_SIZE * NUM_BUFFERS;<br> <br> &nbsp;&nbsp;&nbsp; LCQueueWait((NUM_BUFFERS-1) * 4);<br> <br> &nbsp;&nbsp;&nbsp; while (currDataPtr &lt;= data+DATA_ELEMENTS)<br> &nbsp;&nbsp;&nbsp; { <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; NUM_BUFFERS; i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LCQueueWait((NUM_BUFFERS-1)*numTransactions); // prevstore + prevload, each takes 2<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProcessBuf(Buffers[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LCStoreData(BufAddr[i], Buffers[i], BUFFER_SIZE);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufAddr[i] = currDataPtr; // move to next unprocessed buffer<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LCLoadData(Buffers[i], BufAddr[i], BUFFER_SIZE);<br></code></BLOCKQUOTE>
63<BLOCKQUOTE><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // advance the next block to be read<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currDataPtr += BUFFER_SIZE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br> &nbsp;&nbsp;&nbsp; }<br> &nbsp;&nbsp;&nbsp; LCQueueWait(numTransactions); // don't care about last dma's<br> &nbsp;&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp; <br> <br> &nbsp;&nbsp;&nbsp; OSHalt(&quot;Test complete&quot;);<br> }<br> <br></code></BLOCKQUOTE>
64
65
66
67<h2>See Also</h2>
68
69<p><a href="../toc.html#Cache" target="contents">Cache Functions</a>, <br> <code><a href="LCEnable.html">LCEnable</a>, <a href="LCLoadData.html">LCLoadData</a>, <a href="LCQueueLength.html">LCQueueLength</a>, <a href="LCQueueWait.html">LCQueueWait</a>, <a href="LCStoreBlocks.html">LCStoreBlocks</a></code></p>
70
71<h2>Revision History</h2>
72<P>03/01/2006 Initial version.</P>
73</body>
74</html>