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<h2>Syntax</h2> 17<dl><dd><pre class="construction"> 18#include <revolution/os.h> 19 20u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes); 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 transfer destination in memory. Must be 32-byte aligned.</TD> 29 </TR> 30 <TR> 31<TH>srcAddr</TH> 32<TD>Start address of 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>nBytes</TH> 36<TD>Transfer size. Must be 32-byte aligned.</TD> 37 </TR> 38 </TBODY> 39</TABLE> 40 41<H2>Return Values</H2> 42<P>Returns the number of transactions added to the DMA queue.</P> 43 44<h2>Description</h2> 45<p>Enqueues DMA transactions that transfer data from the locked cache at <SPAN class="argument">srcAddr</SPAN> to main memory at <SPAN class="argument">destAddr</SPAN>. The range of valid source addresses is the 16KB region starting at the value returned by the <A href="LCGetBase.html"><code>LCGetBase</code></A> function. The number of transactions issued is returned as the return value.</p> 46 47<p>The only methods to determine whether the transaction has completed are 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> 48 49<p>The largest transfer allowed in a single DMA transaction is 128 cache blocks (4 KB). Thus, the number of transactions added (to the DMA queue) is always (<SPAN class="argument">nBytes</SPAN> / 4 KB), rounded up. The <A href="LCStoreBlocks.html"><code>LCStoreBlocks</code></A> function is a more efficient function that creates a single DMA transaction. However, its arguments are restricted and it does not provide error checking.</p> 50 51<p>Note that a maximum of 15 DMA requests can be issued to the DMA queue. If the queue overflows, a machine check exception will occur.</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 2 buffers, and ping-pongs between them to process a large array in main memory. The code is structured so that each buffer has no more than 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 2 8k buffers in locked cache region 61// note that NUMBUFFERS * BUFFER_SIZE <= 16k 62#define BUFFER_SIZE (8*1024) 63#define NUM_BUFFERS (2) 64 65#define DATA_ELEMENTS (10*1024*1024) 66: 67 68// real mem loc of Buffers[i] is at BufAddr[i] 69u8* Buffers[NUM_BUFFERS]; 70u8* BufAddr[NUM_BUFFERS]; 71: 72 73void main () 74{ 75 u8* data; 76 u8* currDataPtr; // offset into data 77 u32 i; 78 void* arenaLo; 79 void* arenaHi; 80 u32 numTransactions; 81</pre></dd></dl> 82<dl><dd><pre class="construction"> 83 OSInit(); 84 LCEnable(); 85 86 arenaLo = OSGetArenaLo(); 87 arenaHi = OSGetArenaHi(); 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 1 : using high 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 numTransactions = LCLoadData(Buffers[i], BufAddr[i], BUFFER_SIZE); 110 } 111 112 currDataPtr = data + BUFFER_SIZE * NUM_BUFFERS; 113 114 LCQueueWait((NUM_BUFFERS-1) * 4); 115 116 while (currDataPtr <= data+DATA_ELEMENTS) 117 { 118 for (i = 0; i < NUM_BUFFERS; i++) 119 { 120 LCQueueWait((NUM_BUFFERS-1)*numTransactions); // prevstore + prevload, each takes 2 121 ProcessBuf(Buffers[i]); 122 LCStoreData(BufAddr[i], Buffers[i], BUFFER_SIZE); 123 BufAddr[i] = currDataPtr; // move to next unprocessed buffer 124 LCLoadData(Buffers[i], BufAddr[i], BUFFER_SIZE); 125</pre></dd></dl> 126<dl><dd><pre class="construction"> 127 // advance the next block to be read 128 currDataPtr += BUFFER_SIZE; 129 } 130 } 131 LCQueueWait(numTransactions); // don't care about last dma's 132 : 133 134 OSHalt("Test complete"); 135} 136</pre></dd></dl> 137 138<h2>See Also</h2> 139<P class="reference"> 140<a href="../toc.html#Cache" target="contents">Cache Functions</a>, 141<a href="LCEnable.html">LCEnable</a>, 142<a href="LCLoadData.html">LCLoadData</a>, 143<a href="LCQueueLength.html">LCQueueLength</a>, 144<a href="LCQueueWait.html">LCQueueWait</a>, 145<a href="LCStoreBlocks.html">LCStoreBlocks</a> 146</p> 147 148<h2>Revision History</h2> 149<P> 1502006/03/01 Initial version.<br> 151</P> 152 153<hr><p>CONFIDENTIAL</p></body> 154</html>