Commit 46a6d51c authored by Anton staaf's avatar Anton staaf Committed by Wolfgang Denk
Browse files


This macro is used to allocate cache line size aligned stack
buffers for use with DMA hardware.
Signed-off-by: default avatarAnton Staaf <>
Cc: Lukasz Majewski <>
Cc: Kyungmin Park <>
Cc: Mike Frysinger <>
Cc: Aneesh V <>
Cc: Albert ARIBAUD <>
Cc: Wolfgang Denk <>
parent d47031e6
......@@ -40,6 +40,8 @@ Buffer Requirements:
- If the buffer is not cache-line aligned invalidation will be restricted
to the aligned part. That is, one cache-line at the respective boundary
may be left out while doing invalidation.
- A suitable buffer can be alloced on the stack using the
Cleanup Before Linux:
- cleanup_before_linux() should flush the D-cache, invalidate I-cache, and
......@@ -843,6 +843,64 @@ int cpu_release(int nr, int argc, char * const argv[]);
#include <asm/cache.h>
* The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
* stack that meets the minimum architecture alignment requirements for DMA.
* Such a buffer is useful for DMA operations where flushing and invalidating
* the cache before and after a read and/or write operation is required for
* correct operations.
* When called the macro creates an array on the stack that is sized such
* that:
* 1) The beginning of the array can be advanced enough to be aligned.
* 2) The size of the aligned portion of the array is a multiple of the minimum
* architecture alignment required for DMA.
* 3) The aligned portion contains enough space for the original number of
* elements requested.
* The macro then creates a pointer to the aligned portion of this array and
* assigns to the pointer the address of the first element in the aligned
* portion of the array.
* Calling the macro as:
* ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
* Will result in something similar to saying:
* uint32_t buffer[1024];
* The following differences exist:
* 1) The resulting buffer is guaranteed to be aligned to the value of
* 2) The buffer variable created by the macro is a pointer to the specified
* type, and NOT an array of the specified type. This can be very important
* if you want the address of the buffer, which you probably do, to pass it
* to the DMA hardware. The value of &buffer is different in the two cases.
* In the macro case it will be the address of the pointer, not the address
* of the space reserved for the buffer. However, in the second case it
* would be the address of the buffer. So if you are replacing hard coded
* stack buffers with this macro you need to make sure you remove the & from
* the locations where you are taking the address of the buffer.
* Note that the size parameter is the number of array elements to allocate,
* not the number of bytes.
* This macro can not be used outside of function scope, or for the creation
* of a function scoped static buffer. It can not be used to create a cache
* line aligned global buffer.
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \
type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
/* Pull in stuff for the build system */
# include <environment.h>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment