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 <revolution/os/OSLC.h> 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. 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. 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 <= 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("Splitting locked cache into %d buffers\n", NUM_BUFFERS); 90 91 for (i = 0; i < NUM_BUFFERS; i++) 92 { 93 Buffers[i] = (u8*) ((u32)LCGetBase() + BUFFER_SIZE*i); 94 OSReport("Locked Cache : Allocated %d bytes at 0x%x\n", 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(" Test 2 : using low level interface for DMA load/store\n"); 105 106 for (i = 0; i < 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 <= data+DATA_ELEMENTS) 117 { 118 for (i = 0; i < 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("Test complete"); 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>