source: svn/trunk/newcon3bcm2_21bu/nexus/modules/dma/7552/include/nexus_dma.h

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 20.2 KB
Line 
1/***************************************************************************
2*     (c)2004-2011 Broadcom Corporation
3*
4*  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5*  and may only be used, duplicated, modified or distributed pursuant to the terms and
6*  conditions of a separate, written license agreement executed between you and Broadcom
7*  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8*  no license (express or implied), right to use, or waiver of any kind with respect to the
9*  Software, and Broadcom expressly reserves all rights in and to the Software and all
10*  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11*  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12*  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13*
14*  Except as expressly set forth in the Authorized License,
15*
16*  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17*  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18*  and to use this information only in connection with your use of Broadcom integrated circuit products.
19*
20*  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21*  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22*  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23*  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24*  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25*  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26*  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27*  USE OR PERFORMANCE OF THE SOFTWARE.
28*
29*  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30*  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31*  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32*  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33*  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34*  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35*  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36*  ANY LIMITED REMEDY.
37*
38* $brcm_Workfile: nexus_dma.h $
39* $brcm_Revision: 22 $
40* $brcm_Date: 6/2/11 4:30p $
41*
42* API Description:
43*   API name: Dma
44*    Specific APIs related to memory to memory DMA.
45*
46* Revision History:
47*
48* $brcm_Log: /nexus/modules/dma/7420/include/nexus_dma.h $
49*
50* 22   6/2/11 4:30p jtna
51* SW7405-5344: add NEXUS_DmaJobBlockOffsetSettings and related functions
52*
53* 21   5/13/11 12:24p jtna
54* SW7400-3026: add NEXUS_DmaJob_GetSettings() and SetSettings()
55*
56* 20   5/12/11 2:52p jtna
57* SW7550-739: merge SHARF support
58*
59* 19   4/22/11 6:49p jtna
60* SW7420-420: merge BMMD-based Nexus DMA module
61*
62***************************************************************************/
63
64#ifndef NEXUS_DMA_H__
65#define NEXUS_DMA_H__
66
67#include "nexus_dma_types.h"
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73/*=************************************************************************
74The Nexus Dma interface provides M2M (mem-to-mem) DMA functionality to applications.
75
76The caller is responsible to maintain cache coherency using NEXUS_FlushCache.
77All nexus memory pointers provided to the caller are cached addresses, so you should assume that cache coherency is an issue.
78
79There are potentially three CPU caches you should be aware of:
80    1) L1 cache - this is a write-back cache
81    2) L2 cache - this is a write-back cache
82    3) RAC (read ahead cache) - this is a read-only cache which are "read ahead" up to a 4K boundary
83
84NEXUS_FlushCache will do a wback_invalidate of the L1 and L2 caches and an invalidate of the RAC.
85
86The following cache flush rules will allow your app to maintain cache coherency.
87
88Rule 1: After DMA writes to RAM, you must flush the cache before the CPU reads from that memory. That is:
89
90    1. DMA writes to RAM
91    2. flush cache for that RAM
92    3. CPU reads from that RAM
93
94Rule 2: After the CPU writes to RAM, you must flush the cache before DMA does any access to that memory. That is:
95
96    1. CPU writes to RAM
97    2. flush cache for that RAM
98    3. DMA reads from that RAM
99
100There is a danger created by the RAC's 4K-bounded prefetch that requires special attention.
101The danger is in reversing the order of steps 1 & 2 in Rule 1 if an allocation is not front and back aligned to 4K boundaries
102(i.e. no adjacent allocation shares addresses within a 4K block of the front or back of this allocation).
103If an allocation is not so aligned, then a cached read in an adjacent allocation may populate the RAC before DMA updates it.
104The RAC will then contain stale data that the application does not invalidate. A critical error could easily result.
105By default, the magnum MEM heap (which underlies all nexus heaps) is aligned to the max of the L1 and L2 cache line size (e.g. 64
106or 128 bytes). So there is no "adjacent allocation" danger for these caches.
107However, the MEM heap is not aligned to the RAC's 4K prefetch. So the "adjacent allocation" danger does occur for the RAC.
108
109This danger can appear in a variety of ways. One basic scenario is:
110
111    1. CPU writes to RAM
112    2. flush cache for that RAM
113    3. DMA reads from that RAM
114    4. a CPU read from an adjacent allocation (within the 4K boundary) occurs in another thread; the RAC is populated for both the adjacent
115       allocation and the memory about to be written to in step 5
116    5. DMA writes to RAM
117       >>app mistakenly thinks that it doesn't need to flush here because it already flushed in step 2.
118    6. CPU reads stale data from the RAC for that RAM
119
120Even though the multiple accesses make the scenario more complicated, the root of this problem is that the application mistakenly believed
121that steps 1 & 2 in Rule 1 could be reversed. They cannot. In this case, a flush before the DMA read and another flush after the DMA write are both required.
122
123In nexus, interfaces like Recpump and Message fall into Rule 1. Nexus internally flushes the cache in the GetBuffer call.
124Interfaces like Playpump fall into Rule 2. Nexus internally flushes the cache in the ReadComplete call.
125Interfaces like Surface typically combine both CPU reads and writes and DMA reads and writes. Nexus cannot efficiently flush before and after all DMA transactions.
126Therefore, Nexus defaults all surface allocations to 4K alignment so that the RAC coherency danger does not spill over from a surface
127to an adjacent allocation or from an adjacent allocation into the surface. However, any combination of blits and CPU writes/reads within the surface need to follow
128both cache flush rules to avoid problems.
129
130See nexus/examples/graphics/bad_rac_blit.c for a demonstration of the problem and the recommended solutions.
131**************************************************************************/
132
133/***************************************************************************
134Summary:
135DMA channel settings
136
137Description:
138See NEXUS_Dma_Open for restrictions on changing these settings if you are using more than one instance of a NEXUS_Dma channel.
139***************************************************************************/
140typedef struct NEXUS_DmaSettings
141{
142    NEXUS_DmaEndianMode endianMode; /* endian mode */
143    NEXUS_DmaSwapMode swapMode;     /* byteswap mode */
144    NEXUS_DmaCoreType coreType;     /* which DMA core to use */
145
146    unsigned totalBlocks;           /* deprecated */
147    unsigned maxBlocksPerTransfer;  /* deprecated */
148} NEXUS_DmaSettings;
149
150/***************************************************************************
151Summary:
152Get default settings for the structure.
153***************************************************************************/
154void NEXUS_Dma_GetDefaultSettings(
155    NEXUS_DmaSettings *pSettings /* [out] */
156    );
157
158/***************************************************************************
159Summary:
160Open a DMA channel
161
162Description:
163Nexus DMA supports virtualization by allowing NEXUS_Dma_Open to be
164called more than once with the same index.
165***************************************************************************/
166NEXUS_DmaHandle NEXUS_Dma_Open(  /* attr{destructor=NEXUS_Dma_Close}  */
167    unsigned index, /* M2M_DMA controller index */
168    const NEXUS_DmaSettings *pSettings  /* attr{null_allowed=y} may be NULL for default settings */
169    );
170
171/***************************************************************************
172Summary:
173Close a DMA channel
174***************************************************************************/
175void NEXUS_Dma_Close(
176    NEXUS_DmaHandle handle
177    );
178
179/***************************************************************************
180Summary:
181Get current settings from a DMA channel
182***************************************************************************/
183NEXUS_Error NEXUS_Dma_GetSettings(
184    NEXUS_DmaHandle handle,
185    NEXUS_DmaSettings *pSettings    /* [out] */
186    );
187
188/***************************************************************************
189Summary:
190Set the current settings of a DMA channel
191
192Description:
193See NEXUS_Dma_Open for restrictions on changing these settings if you are using more than one instance of a NEXUS_Dma channel.
194***************************************************************************/
195NEXUS_Error NEXUS_Dma_SetSettings(
196    NEXUS_DmaHandle handle,
197    const NEXUS_DmaSettings *pSettings
198    );
199
200/**
201Summary:
202Handle for a DMA job.
203**/
204typedef struct NEXUS_DmaJob *NEXUS_DmaJobHandle;
205
206/***************************************************************************
207Summary:
208DMA Job Settings
209
210Description:
211See Also:
212NEXUS_Dma_GetDefaultJobSettings
213NEXUS_DmaJob_Create
214***************************************************************************/
215typedef struct NEXUS_DmaJobSettings
216{
217    unsigned numBlocks;             /* maximum number of blocks in this job. for scatter-gather jobs, this can be > 1 */
218    unsigned busyWait;              /* NEXUS_DmaJob_ProcessBlocks waits for DMA completion, up to specified number of microseconds, 0 - no wait */
219    unsigned busyWaitThreshold;        /* maximum size of transaction to engage busyWait */
220    NEXUS_KeySlotHandle keySlot;    /* key slot for security.  NULL(default) if not encrypting or decrypting data */
221    NEXUS_DmaDataFormat dataFormat; /* applies if keyslot is non-NULL */
222    NEXUS_CallbackDesc completionCallback; /* if set, this callback will fire when the job completes */
223
224    /* SHARF-specific settings. in SHARF mode, keySlot and dataFormat have
225       no effect and are replaced by SHARF-specific settings */
226    struct {
227        bool useBspKey; /* if true, SHARF will use a secure key supplied by BSP directly
228                           for data encryption/decryption. if false, SHARF will use the key
229                           that prepends the descriptor data */
230        NEXUS_DmaSharfMode mode;
231        unsigned shaContext; /* SHARF HW can hold the intermediate or final SHA-1 digest
232                                for up to 3 contexts across all SHARF DMA channels. This
233                                allows interleaving SHARF DMA operations.
234                                Valid values are 0,1 or 2. */
235    } sharf;
236} NEXUS_DmaJobSettings;
237
238/***************************************************************************
239Summary:
240Get default settings for the structure.
241
242Description:
243This is required in order to make application code resilient to the addition of new strucutre members in the future.
244
245See Also:
246NEXUS_DmaJob_Create
247***************************************************************************/
248void NEXUS_DmaJob_GetDefaultSettings(
249    NEXUS_DmaJobSettings *pSettings
250    );
251
252/***************************************************************************
253Summary:
254Create a DMA Job
255
256Description:
257A DMA Job is a context of DMA descriptors and its assocatied completion callback & status.
258You can have more than one active job on a DMA channel.
259***************************************************************************/
260NEXUS_DmaJobHandle NEXUS_DmaJob_Create( /* attr{destructor=NEXUS_DmaJob_Destroy} */
261    NEXUS_DmaHandle dmaHandle,
262    const NEXUS_DmaJobSettings *pSettings /* attr{null_allowed=y} may be NULL for default settings */
263    );
264
265/***************************************************************************
266Summary:
267Destroy a DMA Job
268***************************************************************************/
269void NEXUS_DmaJob_Destroy(
270    NEXUS_DmaJobHandle handle
271    );
272
273/***************************************************************************
274Summary:
275Get current settings from a DMA job
276***************************************************************************/
277void NEXUS_DmaJob_GetSettings(
278    NEXUS_DmaJobHandle handle,
279    NEXUS_DmaJobSettings *pSettings /* [out] */
280    );
281
282/***************************************************************************
283Summary:
284Set new settings for a DMA job
285
286Description:
287Some DmaJobSettings (e.g. numBlocks) cannot be changed and require a new job to be created
288***************************************************************************/
289NEXUS_Error NEXUS_DmaJob_SetSettings(
290    NEXUS_DmaJobHandle handle,
291    const NEXUS_DmaJobSettings *pSettings
292    );
293
294/***************************************************************************
295Summary:
296DMA Job Block Descriptor
297***************************************************************************/
298typedef struct NEXUS_DmaJobBlockSettings
299{
300    const void *pSrcAddr;   /* attr{memory=cached} Source address */
301    void *pDestAddr;        /* attr{memory=cached} Destination address - may be the same as source address */
302    size_t blockSize;       /* in bytes */
303
304    bool cached;            /* use cache flush on source and destination addresses */
305    bool resetCrypto;       /* Should the crypto operation reset on this block? */
306
307    bool scatterGatherCryptoStart; /* If true, this block starts a scatter-gather crypto op */
308    bool scatterGatherCryptoEnd;   /* If true, this block ends a scatter-gather crypto op */
309
310    struct {
311        bool keyPresent;    /* if true, a crypto key prepends the data */
312        bool digestPresent; /* if true, a hash digest or MAC prepends the data */
313    } sharf;
314} NEXUS_DmaJobBlockSettings;
315
316/***************************************************************************
317Summary:
318Get default settings for the structure.
319
320Description:
321This is required in order to make application code resilient to the addition of new structure members in the future.
322***************************************************************************/
323void NEXUS_DmaJob_GetDefaultBlockSettings(
324    NEXUS_DmaJobBlockSettings *pSettings /* [out] */
325    );
326
327/***************************************************************************
328Summary:
329DEPRECATED: Set a DMA block descriptor settings
330This functionality has been removed.
331
332Description:
333Random-access configuration of blocks. Used in conjuction with NEXUS_DmaJob_Start.
334
335This function is deprecated. Use NEXUS_DmaJob_ProcessBlocks instead.
336***************************************************************************/
337NEXUS_Error NEXUS_DmaJob_SetBlockSettings(
338    NEXUS_DmaJobHandle handle,
339    unsigned blockIndex,            /* Must be < NEXUS_DmaJobSettings.numBlocks */
340    const NEXUS_DmaJobBlockSettings *pSettings
341    );
342
343
344/***************************************************************************
345Summary:
346DEPRECATED: Start a DMA Job
347This functionality has been removed.
348
349Description:
350This function starts a DMA job operation using blocks configured by NEXUS_DmaJob_SetBlockSettings.
351
352The caller should wait for the completion callback or poll the current status with
353NEXUS_DmaJob_GetStatus to ensure the transfer is complete before starting the same job a second time.
354
355This function is deprecated. Use NEXUS_DmaJob_ProcessBlocks instead.
356***************************************************************************/
357NEXUS_Error NEXUS_DmaJob_Start(
358    NEXUS_DmaJobHandle handle
359    );
360
361#define NEXUS_DMA_QUEUED NEXUS_MAKE_ERR_CODE(0x100, 1)
362
363/***************************************************************************
364Summary:
365Prepare and run a DMA transaction
366
367Description:
368This function prepares and starts a DMA job operation.  If function returns NEXUS_SUCCESS, then
369DMA transaction is completed and new transaction could be started right away.
370However if function returns NEXUS_DMA_QUEUED, then caller should wait
371for the completion callback or poll the current status with NEXUS_DmaJob_GetStatus
372to ensure the transfer is complete before using the same job a second
373time.
374
375NEXUS_DmaJob_ProcessBlocks is used for fast batch DMA processing. It should be used
376instead of multiple calls to NEXUS_DmaJob_SetBlockSettings and NEXUS_Error NEXUS_DmaJob_Start.
377
378See Also:
379    NEXUS_DmaJob_GetStatus
380Returns:
381  On Success
382    NEXUS_SUCCESS - DMA completed
383    NEXUS_DMA_QUEUED - DMA job queued for processing
384***************************************************************************/
385NEXUS_Error NEXUS_DmaJob_ProcessBlocks(
386    NEXUS_DmaJobHandle handle,
387    const NEXUS_DmaJobBlockSettings *pSettings, /* attr{nelem=nBlocks;reserved=2} pointer to array of DMA blocks */
388    unsigned nBlocks                            /* Must be < NEXUS_DmaJobSettings.numBlocks */
389    );
390
391/***************************************************************************
392Summary:
393DMA Job Block Descriptor that uses offsets (physical addresses) for source and destination
394***************************************************************************/
395typedef struct NEXUS_DmaJobBlockOffsetSettings
396{
397    uint32_t srcOffset;     /* source offset */
398    uint32_t destOffset;    /* destination offset - may be the same as source offset */
399    size_t blockSize;       /* in bytes */
400
401    bool resetCrypto;       /* Should the crypto operation reset on this block? */
402
403    bool scatterGatherCryptoStart; /* If true, this block starts a scatter-gather crypto op */
404    bool scatterGatherCryptoEnd;   /* If true, this block ends a scatter-gather crypto op */
405
406    struct {
407        bool keyPresent;    /* if true, a crypto key prepends the data */
408        bool digestPresent; /* if true, a hash digest or MAC prepends the data */
409    } sharf;
410} NEXUS_DmaJobBlockOffsetSettings;
411
412/***************************************************************************
413Summary:
414Offset-version of NEXUS_DmaJob_GetDefaultBlockSettings()
415***************************************************************************/
416void NEXUS_DmaJob_GetDefaultBlockOffsetSettings(
417    NEXUS_DmaJobBlockOffsetSettings *pSettings /* [out] */
418    );
419
420/***************************************************************************
421Summary:
422Offset-version of NEXUS_DmaJob_ProcessBlocks()
423***************************************************************************/
424NEXUS_Error NEXUS_DmaJob_ProcessBlocksOffset(
425    NEXUS_DmaJobHandle handle,
426    const NEXUS_DmaJobBlockOffsetSettings *pSettings, /* attr{nelem=nBlocks;reserved=2} pointer to array of DMA blocks */
427    unsigned nBlocks                                  /* Must be < NEXUS_DmaJobSettings.numBlocks */
428    );
429
430/***************************************************************************
431Summary:
432DMA Job State returned by NEXUS_DmaJobStatus
433***************************************************************************/
434typedef enum NEXUS_DmaJobState
435{
436    NEXUS_DmaJobState_eComplete,   /* completed */
437    NEXUS_DmaJobState_eFailed,     /* deprecated */
438    NEXUS_DmaJobState_eInProgress, /* queued in HW */
439    NEXUS_DmaJobState_ePending,    /* deprecated */
440    NEXUS_DmaJobState_eIdle,       /* not yet started */
441    NEXUS_DmaJobState_eUnknown,
442    NEXUS_DmaJobState_eMax
443} NEXUS_DmaJobState;
444
445/***************************************************************************
446Summary:
447Status returned by NEXUS_DmaJob_GetStatus
448***************************************************************************/
449typedef struct NEXUS_DmaJobStatus
450{
451    NEXUS_DmaJobState currentState;
452} NEXUS_DmaJobStatus;
453
454/***************************************************************************
455Summary:
456Get the status of a DMA job
457
458Description:
459This is only required if you are polling and not using NEXUS_DmaJobSettings.completionCallback.
460***************************************************************************/
461NEXUS_Error NEXUS_DmaJob_GetStatus(
462    NEXUS_DmaJobHandle handle,
463    NEXUS_DmaJobStatus *pStatus /* [out] */
464    );
465
466#ifdef __cplusplus
467}
468#endif
469
470#endif /* #ifndef NEXUS_DMA_H__ */
471
Note: See TracBrowser for help on using the repository browser.