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<h2>Syntax</h2>
17<dl><dd><pre class="construction">
18#include &lt;revolution/os/OSLC.h&gt;
19
20void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks);
21</pre></dd></dl>
22
23<H2>Arguments</H2>
24<TABLE class="arguments" border="1" >
25  <TBODY>
26    <TR>
27<TH>destAddr</TH>
28<TD>Start address of the destination in memory. Must be 32-byte aligned.</TD>
29    </TR>
30    <TR>
31<TH>srcTag</TH>
32<TD>Start address for the locked cache address to be copied to <SPAN class="argument">destAddr</SPAN>. Must be 32-byte aligned.</TD>
33    </TR>
34    <TR>
35<TH>numBlocks</TH>
36<TD>Transfer size. (Number of cache blocks.) Must be specified as a value between 0 to 127. If 0 is specified, the transaction size used is 128 blocks (4KB).</TD>
37    </TR>
38  </TBODY>
39</TABLE>
40
41<H2>Return Values</H2>
42<P>None.</P>
43
44<h2>Description</h2>
45<p>Enqueues a single DMA transfer for moving data in a locked cache to main memory. Using this function is more efficient than calling the <A href="LCStoreData.html"><code>LCStoreData</code></A> function, but it is limited to a maximum transaction 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 <SPAN class="argument">numBlocks</SPAN> indicates a transaction size of 128 blocks.</strong>The range of valid source addresses is the 16KB region starting from the value returned by <a href="LCGetBase.html"><code>LCGetBase</code></a>.</p>
46
47<p>See the following example code that performs quadruple buffering within a locked cache region with this function.&nbsp;This sample code example is the same as the sample code for the <A href="LCStoreData.html"><code>LCStoreData</code></A> function.</p>
48
49<p>The only methods to determine whether a transaction has completed are either to poll the length of the DMA queue with the <A href="LCQueueLength.html"><code>LCQueueLength</code></A> function or to wait until the queue length reaches a fixed value with the <A href="LCQueueWait.html"><code>LCQueueWait</code></A> function. See the following example.</p>
50
51<p>Note that a maximum of 15 DMA transactions can be issued in the DMA queue.&nbsp;If the queue overflows, a machine check exception occurs.</p>
52
53<p>The locked cache must be enabled throughout the transfer; or else a machine exception will occur during the DMA.</p>
54
55<p>If the DMA finds a source address in normal cache, a machine check exception occurs.</p>
56
57<h3>Example</h3>
58<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 unsent load and store at any given time. This fact is used to ensure that a buffer completed storing its old (just now processed) data and then completed loading the block of data to process next.</p>
59<dl><dd><pre class="construction">
60// define 4 4k buffers in locked cache region
61// note that NUMBUFFERS * BUFFER_SIZE &lt;= 16k
62#define BUFFER_SIZE (4*1024)
63#define NUM_BUFFERS (4)
64
65#define DATA_ELEMENTS (10*1024*1024)
66:
67</pre></dd></dl>
68<dl><dd><pre class="construction">
69// real mem loc of Buffers[i] is at BufAddr[i]
70u8* Buffers[NUM_BUFFERS];
71u8* BufAddr[NUM_BUFFERS];
72:
73
74void main ()
75{
76    u8* data;
77    u8* currDataPtr; // offset into data
78    u32 i;
79    void* arenaLo;
80    void* arenaHi;
81
82    OSInit();
83    LCEnable();
84
85    arenaLo = OSGetArenaLo();
86    arenaHi = OSGetArenaHi();
87    :
88
89    OSReport(&quot;Splitting locked cache into %d buffers\n&quot;, NUM_BUFFERS);
90
91    for (i = 0; i &lt; NUM_BUFFERS; i++)
92    {
93        Buffers[i] = (u8*) ((u32)LCGetBase() + BUFFER_SIZE*i);
94        OSReport(&quot;Locked Cache : Allocated %d bytes at 0x%x\n&quot;,
95                    BUFFER_SIZE,
96                    Buffers[i]);
97    }
98
99    // Initialize source data
100    data = (u8*)OSAlloc(DATA_ELEMENTS * sizeof(u8));
101    :
102    DCFlushRange(data, DATA_ELEMENTS);
103
104    OSReport(&quot; Test 2 : using low level interface for DMA load/store\n&quot;);
105
106    for (i = 0; i &lt; NUM_BUFFERS; i++)
107    {
108        BufAddr[i] = data + BUFFER_SIZE*i;
109        LCLoadBlocks(Buffers[i], BufAddr[i], 0);
110    }
111
112    currDataPtr = data + BUFFER_SIZE * NUM_BUFFERS;
113
114    LCQueueWait((NUM_BUFFERS-1));
115
116    while (currDataPtr &lt;= data+DATA_ELEMENTS)
117    {
118        for (i = 0; i &lt; NUM_BUFFERS; i++)
119        {
120            LCQueueWait((NUM_BUFFERS-1)*2);
121            ProcessBuf(Buffers[i]);
122            LCStoreBlocks(BufAddr[i], Buffers[i], 0);
123            LCLoadBlocks(Buffers[i], currDataPtr, 0);
124            BufAddr[i] = currDataPtr; // move to next unprocessed buffer
125
126            // advance the next block to be read
127            currDataPtr += BUFFER_SIZE;
128        }
129    }
130    LCQueueWait(NUM_BUFFERS); // don't care about last dma's
131    :
132    OSHalt(&quot;Test complete&quot;);
133}
134</pre></dd></dl>
135
136<h2>See Also</h2>
137<P class="reference">
138<A href="../toc.html#Cache" target="contents">Cache Functions</A>,
139<a href="LCEnable.html">LCEnable</a>,
140<a href="LCStoreData.html">LCStoreData</a>,
141<a href="LCLoadBlocks.html">LCLoadBlocks</a>,
142<a href="LCQueueLength.html">LCQueueLength</a>,
143<a href="LCQueueWait.html">LCQueueWait</a>
144</p>
145
146<h2>Revision History</h2>
147<P>
1482006/03/01 Initial version.<br>
149</P>
150
151<hr><p>CONFIDENTIAL</p></body>
152</html>