diff --git a/src/omv/alloc/fb_alloc.c b/src/omv/alloc/fb_alloc.c index bef12bad3..3d088e3bf 100644 --- a/src/omv/alloc/fb_alloc.c +++ b/src/omv/alloc/fb_alloc.c @@ -132,7 +132,15 @@ void *fb_alloc(uint32_t size, int hints) return NULL; } - size=((size+sizeof(uint32_t)-1)/sizeof(uint32_t))*sizeof(uint32_t);// Round Up + size = ((size + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t); // Round Up + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + size = ((size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; + size += __SCB_DCACHE_LINE_SIZE; + } + #endif + char *result = pointer - size; char *new_pointer = result - sizeof(uint32_t); @@ -144,6 +152,7 @@ void *fb_alloc(uint32_t size, int hints) // size is always 4/8/12/etc. so the value below must be 8 or more. *((uint32_t *) new_pointer) = size + sizeof(uint32_t); // Save size. pointer = new_pointer; + #if defined(FB_ALLOC_STATS) alloc_bytes += size; if (alloc_bytes > alloc_bytes_peak) { @@ -151,6 +160,7 @@ void *fb_alloc(uint32_t size, int hints) } printf("fb_alloc %lu bytes\n", size); #endif + #if defined(OMV_FB_OVERLAY_MEMORY) if ((!(hints & FB_ALLOC_PREFER_SIZE)) && (((uint32_t) (pointer_overlay - OMV_FB_OVERLAY_MEMORY_ORIGIN)) >= size)) { @@ -160,6 +170,16 @@ void *fb_alloc(uint32_t size, int hints) *new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag. } #endif + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + int offset = ((uint32_t) result) % __SCB_DCACHE_LINE_SIZE; + if (offset) { + result += __SCB_DCACHE_LINE_SIZE - offset; + } + } + #endif + return result; } @@ -186,13 +206,23 @@ void *fb_alloc_all(uint32_t *size, int hints) temp = IM_MIN(temp, *size); } #endif + *size = (temp / sizeof(uint32_t)) * sizeof(uint32_t); // Round Down + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + *size = ((*size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; + *size += __SCB_DCACHE_LINE_SIZE; + } + #endif + char *result = pointer - *size; char *new_pointer = result - sizeof(uint32_t); // size is always 4/8/12/etc. so the value below must be 8 or more. *((uint32_t *) new_pointer) = *size + sizeof(uint32_t); // Save size. pointer = new_pointer; + #if defined(FB_ALLOC_STATS) alloc_bytes += *size; if (alloc_bytes > alloc_bytes_peak) { @@ -200,6 +230,7 @@ void *fb_alloc_all(uint32_t *size, int hints) } printf("fb_alloc_all %lu bytes\n", *size); #endif + #if defined(OMV_FB_OVERLAY_MEMORY) if (!(hints & FB_ALLOC_PREFER_SIZE)) { // Return overlay memory instead. @@ -208,6 +239,16 @@ void *fb_alloc_all(uint32_t *size, int hints) *new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag. } #endif + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + int offset = ((uint32_t) result) % __SCB_DCACHE_LINE_SIZE; + if (offset) { + result += __SCB_DCACHE_LINE_SIZE - offset; + } + } + #endif + return result; } diff --git a/src/omv/alloc/fb_alloc.h b/src/omv/alloc/fb_alloc.h index 7d799eef5..4935d04a0 100644 --- a/src/omv/alloc/fb_alloc.h +++ b/src/omv/alloc/fb_alloc.h @@ -35,6 +35,19 @@ * mark. * * Note that fb_free() and fb_free_all() do not respect any marks and permanent regions. + * + * Regardings the flags below: + * - FB_ALLOC_NO_HINT - fb_alloc doesn't do anything special. + * - FB_ALLOC_PREFER_SPEED - fb_alloc will make sure the allocated region is in the fatest possible + * memory. E.g. allocs will be in SRAM versus SDRAM if SDRAM is available. + * Setting this flag affects where fb_alloc_all() gets RAM from. If this + * flag is set then fb_alloc_all() will not use the SDRAM. + * - FB_ALLOC_PREFER_SIZE - fb_alloc will make sure the allocated region is the largest possible + * memory. E.g. allocs will be in SDRAM versus SRAM if SDRAM is available. + * Setting this flag affects where fb_alloc_all() gets RAM from. If this + * flag is set then fb_alloc_all() will use the SDRAM (default). + * - FB_ALLOC_CACHE_ALIGN - Aligns the starting address returned to a cache line and makes sure + * the amount of memory allocated is padded to the end of a cache line. */ #ifndef __FB_ALLOC_H__ #define __FB_ALLOC_H__ @@ -42,6 +55,7 @@ #define FB_ALLOC_NO_HINT 0 #define FB_ALLOC_PREFER_SPEED 1 #define FB_ALLOC_PREFER_SIZE 2 +#define FB_ALLOC_CACHE_ALIGN 4 char *fb_alloc_stack_pointer(); void fb_alloc_fail(); void fb_alloc_init0();