Merge pull request #1173 from kwagyeman/kwabena/cache_alignment

Kwabena/cache alignment
This commit is contained in:
Ibrahim Abd Elkader 2021-02-15 20:08:02 +02:00 committed by GitHub
commit f48ba98893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 20 deletions

View File

@ -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 - sizeof(uint32_t);
}
#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,16 @@ 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
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 +223,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 +232,19 @@ 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) {
int inc = __SCB_DCACHE_LINE_SIZE - offset;
result += inc;
*size -= inc;
}
*size = (*size / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE;
}
#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();

View File

@ -21,8 +21,8 @@ typedef struct framebuffer {
int32_t u,v;
int32_t bpp;
int32_t streaming_enabled;
// NOTE: This buffer must be aligned on a 16 byte boundary
OMV_ATTR_ALIGNED(uint8_t pixels[], 16);
// NOTE: This buffer must be aligned on a 32 byte boundary
OMV_ATTR_ALIGNED(uint8_t pixels[], 32);
} framebuffer_t;
extern framebuffer_t *framebuffer;
@ -33,7 +33,8 @@ typedef struct jpegbuffer {
int32_t enabled;
int32_t quality;
mutex_t lock;
uint8_t pixels[];
// NOTE: This buffer must be aligned on a 32 byte boundary
OMV_ATTR_ALIGNED(uint8_t pixels[], 32);
} jpegbuffer_t;
extern jpegbuffer_t *jpeg_framebuffer;

View File

@ -455,22 +455,8 @@ int fir_lepton_init(cambus_t *bus, int *w, int *h, int *refresh, int *resolution
FB_ALLOC_NO_HINT);
}
size_t size = VOSPI_BUFFER_SIZE * sizeof(uint16_t);
// The DMA buffer must not start/end partially on a cache line.
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
size = ((size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE;
size += __SCB_DCACHE_LINE_SIZE;
#endif
fir_lepton_spi_rx_cb_dma_buffer = (uint16_t *) fb_alloc(size, FB_ALLOC_PREFER_SPEED);
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
int offset = ((uint32_t) fir_lepton_spi_rx_cb_dma_buffer) % __SCB_DCACHE_LINE_SIZE;
if (offset) {
fir_lepton_spi_rx_cb_dma_buffer += __SCB_DCACHE_LINE_SIZE - offset;
}
#endif
fir_lepton_spi_rx_cb_dma_buffer = (uint16_t *) fb_alloc(VOSPI_BUFFER_SIZE * sizeof(uint16_t),
FB_ALLOC_PREFER_SPEED | FB_ALLOC_CACHE_ALIGN);
dma_init(&fir_lepton_spi_rx_dma,
OMV_FIR_LEPTON_CONTROLLER->rx_dma_descr,