Add cache alignment support to fb_alloc

This commit is contained in:
Kwabena W. Agyeman 2021-02-14 15:41:10 -08:00
parent 5c49066508
commit 900477383e
2 changed files with 56 additions and 1 deletions

View File

@ -133,6 +133,14 @@ void *fb_alloc(uint32_t size, int hints)
}
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;
}

View File

@ -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();