Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alloc: access to the memory map through uncached addresses #253

Merged
merged 1 commit into from
Aug 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/include/sof/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,12 @@ int mm_pm_context_restore(struct dma_copy *dc, struct dma_sg_config *sg);

/* heap initialisation */
void init_heap(struct sof *sof);

/* flush block map from cache to sram */
static inline void flush_block_map(struct block_map *map)
{
dcache_writeback_invalidate_region(map->block,
sizeof(*map->block) * map->count);
dcache_writeback_invalidate_region(map, sizeof(*map));
}
#endif
101 changes: 49 additions & 52 deletions src/lib/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static inline uint32_t heap_get_size(struct mm_heap *heap)
int i;

for (i = 0; i < heap->blocks; i++) {
size += block_get_size(&heap->map[i]);
size += block_get_size(cache_to_uncache(&heap->map[i]));
}

return size;
Expand Down Expand Up @@ -141,8 +141,8 @@ static void *rmalloc_sys(int zone, size_t bytes)
static void *alloc_block(struct mm_heap *heap, int level,
uint32_t caps)
{
struct block_map *map = &heap->map[level];
struct block_hdr *hdr = &map->block[map->first_free];
struct block_map *map = cache_to_uncache(&heap->map[level]);
struct block_hdr *hdr = cache_to_uncache(&map->block[map->first_free]);
void *ptr;
int i;

Expand All @@ -152,12 +152,11 @@ static void *alloc_block(struct mm_heap *heap, int level,
hdr->used = 1;
heap->info.used += map->block_size;
heap->info.free -= map->block_size;
dcache_writeback_invalidate_region(hdr, sizeof(*hdr));

/* find next free */
for (i = map->first_free; i < map->count; ++i) {

hdr = &map->block[i];
hdr = cache_to_uncache(&map->block[i]);

if (hdr->used == 0) {
map->first_free = i;
Expand All @@ -169,18 +168,15 @@ static void *alloc_block(struct mm_heap *heap, int level,
alloc_memset_region(ptr, map->block_size, DEBUG_BLOCK_ALLOC_VALUE);
#endif

dcache_writeback_invalidate_region(map, sizeof(*map));
dcache_writeback_invalidate_region(heap, sizeof(*heap));

return ptr;
}

/* allocates continuous blocks */
static void *alloc_cont_blocks(struct mm_heap *heap, int level,
uint32_t caps, size_t bytes)
{
struct block_map *map = &heap->map[level];
struct block_hdr *hdr = &map->block[map->first_free];
struct block_map *map = cache_to_uncache(&heap->map[level]);
struct block_hdr *hdr;
void *ptr;
unsigned int start;
unsigned int current;
Expand All @@ -198,7 +194,7 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level,
/* check that we have enough free blocks from start pos */
end = start + count;
for (current = start; current < end; current++) {
hdr = &map->block[current];
hdr = cache_to_uncache(&map->block[current]);

/* is block used */
if (hdr->used)
Expand All @@ -218,17 +214,15 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level,
/* found some free blocks */
map->free_count -= count;
ptr = (void *)(map->base + start * map->block_size);
hdr = &map->block[start];
hdr = cache_to_uncache(&map->block[start]);
hdr->size = count;
heap->info.used += count * map->block_size;
heap->info.free -= count * map->block_size;
dcache_writeback_invalidate_region(hdr, sizeof(*hdr));

/* allocate each block */
for (current = start; current < end; current++) {
hdr = &map->block[current];
hdr = cache_to_uncache(&map->block[current]);
hdr->used = 1;
dcache_writeback_invalidate_region(hdr, sizeof(*hdr));
}

/* do we need to find a new first free block ? */
Expand All @@ -237,7 +231,7 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level,
/* find next free */
for (i = map->first_free + count; i < map->count; ++i) {

hdr = &map->block[i];
hdr = cache_to_uncache(&map->block[i]);

if (hdr->used == 0) {
map->first_free = i;
Expand All @@ -250,9 +244,6 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level,
alloc_memset_region(ptr, bytes, DEBUG_BLOCK_ALLOC_VALUE);
#endif

dcache_writeback_invalidate_region(map, sizeof(*map));
dcache_writeback_invalidate_region(heap, sizeof(*heap));

return ptr;
}

Expand All @@ -263,15 +254,15 @@ static struct mm_heap *get_heap_from_ptr(void *ptr)

/* find mm_heap that ptr belongs to */
for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
heap = &memmap.runtime[i];
heap = cache_to_uncache(&memmap.runtime[i]);

if ((uint32_t)ptr >= heap->heap &&
(uint32_t)ptr < heap->heap + heap->size)
return heap;
}

for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
heap = &memmap.buffer[i];
heap = cache_to_uncache(&memmap.buffer[i]);

if ((uint32_t)ptr >= heap->heap &&
(uint32_t)ptr < heap->heap + heap->size)
Expand All @@ -289,7 +280,7 @@ static struct mm_heap *get_runtime_heap_from_caps(uint32_t caps)

/* find first heap that support type */
for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
heap = &memmap.runtime[i];
heap = cache_to_uncache(&memmap.runtime[i]);
mask = heap->caps & caps;
if (mask == caps)
return heap;
Expand All @@ -306,7 +297,7 @@ static struct mm_heap *get_buffer_heap_from_caps(uint32_t caps)

/* find first heap that support type */
for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
heap = &memmap.buffer[i];
heap = cache_to_uncache(&memmap.buffer[i]);
mask = heap->caps & caps;
if (mask == caps)
return heap;
Expand Down Expand Up @@ -334,9 +325,10 @@ static void free_block(void *ptr)

/* find block that ptr belongs to */
for (i = 0; i < heap->blocks - 1; i++) {
block_map = cache_to_uncache(&heap->map[i + 1]);

/* is ptr in this block */
if ((uint32_t)ptr < heap->map[i + 1].base)
if ((uint32_t)ptr < block_map->base)
goto found;
}

Expand All @@ -346,21 +338,20 @@ static void free_block(void *ptr)

found:
/* the block i is it */
block_map = &heap->map[i];
block_map = cache_to_uncache(&heap->map[i]);

/* calculate block header */
block = ((uint32_t)ptr - block_map->base) / block_map->block_size;
hdr = &block_map->block[block];
hdr = cache_to_uncache(&block_map->block[block]);

/* free block header and continuous blocks */
for (i = block; i < block + hdr->size; i++) {
hdr = &block_map->block[i];
hdr = cache_to_uncache(&block_map->block[i]);
hdr->size = 0;
hdr->used = 0;
block_map->free_count++;
heap->info.used -= block_map->block_size;
heap->info.free += block_map->block_size;
dcache_writeback_invalidate_region(hdr, sizeof(*hdr));
}

/* set first free block */
Expand All @@ -370,15 +361,13 @@ static void free_block(void *ptr)
#if DEBUG_BLOCK_FREE
alloc_memset_region(ptr, block_map->block_size * (i - 1), DEBUG_BLOCK_FREE_VALUE);
#endif

dcache_writeback_invalidate_region(block_map, sizeof(*block_map));
dcache_writeback_invalidate_region(heap, sizeof(*heap));
}

/* allocate single block for runtime */
static void *rmalloc_runtime(int zone, uint32_t caps, size_t bytes)
{
struct mm_heap *heap;
struct block_map *map;
int i;
void *ptr = NULL;

Expand All @@ -394,13 +383,14 @@ static void *rmalloc_runtime(int zone, uint32_t caps, size_t bytes)

find:
for (i = 0; i < heap->blocks; i++) {
map = cache_to_uncache(&heap->map[i]);

/* is block big enough */
if (heap->map[i].block_size < bytes)
if (map->block_size < bytes)
continue;

/* does block have free space */
if (heap->map[i].free_count == 0)
if (map->free_count == 0)
continue;

/* free block space exists */
Expand Down Expand Up @@ -460,6 +450,7 @@ void *rzalloc(int zone, uint32_t caps, size_t bytes)
void *rballoc(int zone, uint32_t caps, size_t bytes)
{
struct mm_heap *heap;
struct block_map *map;
int i;
uint32_t flags;
void *ptr = NULL;
Expand All @@ -472,13 +463,14 @@ void *rballoc(int zone, uint32_t caps, size_t bytes)

/* will request fit in single block */
for (i = 0; i < heap->blocks; i++) {
map = cache_to_uncache(&heap->map[i]);

/* is block big enough */
if (heap->map[i].block_size < bytes)
if (map->block_size < bytes)
continue;

/* does block have free space */
if (heap->map[i].free_count == 0)
if (map->free_count == 0)
continue;

/* allocate block */
Expand All @@ -496,9 +488,10 @@ void *rballoc(int zone, uint32_t caps, size_t bytes)

/* find best block size for request */
for (i = 0; i < heap->blocks; i++) {
map = cache_to_uncache(&heap->map[i]);

/* allocate is block size smaller than request */
if (heap->map[i].block_size < bytes)
if (map->block_size < bytes)
alloc_cont_blocks(heap, i, caps, bytes);
}
}
Expand Down Expand Up @@ -529,30 +522,34 @@ uint32_t mm_pm_context_size(void)

/* calc context size for each area */
for (i = 0; i < PLATFORM_HEAP_BUFFER; i++)
size += memmap.buffer[i].info.used;
size += cache_to_uncache(&memmap.buffer[i])->info.used;
for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++)
size += memmap.runtime[i].info.used;
size += cache_to_uncache(&memmap.runtime[i])->info.used;
size += memmap.system.info.used;

/* add memory maps */
for (i = 0; i < PLATFORM_HEAP_BUFFER; i++)
size += heap_get_size(&memmap.buffer[i]);
size += heap_get_size(cache_to_uncache(&memmap.buffer[i]));
for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++)
size += heap_get_size(&memmap.runtime[i]);
size += heap_get_size(cache_to_uncache(&memmap.runtime[i]));
size += heap_get_size(&memmap.system);

/* recalc totals */
memmap.total.free = memmap.system.info.free;
memmap.total.used = memmap.system.info.used;

for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
memmap.total.free += memmap.buffer[i].info.free;
memmap.total.used += memmap.buffer[i].info.used;
memmap.total.free +=
cache_to_uncache(&memmap.buffer[i])->info.free;
memmap.total.used +=
cache_to_uncache(&memmap.buffer[i])->info.used;
}

for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
memmap.total.free = memmap.runtime[i].info.free;
memmap.total.used = memmap.runtime[i].info.used;
memmap.total.free =
cache_to_uncache(&memmap.runtime[i])->info.free;
memmap.total.used =
cache_to_uncache(&memmap.runtime[i])->info.used;
}

return size;
Expand Down Expand Up @@ -653,19 +650,19 @@ void init_heap(struct sof *sof)

current_map = &heap->map[j];
current_map->base = heap->heap;
dcache_writeback_region(current_map,
sizeof(*current_map));
flush_block_map(current_map);

for (k = 1; k < heap->blocks; k++) {
next_map = &heap->map[k];
next_map->base = current_map->base +
current_map->block_size *
current_map->count;
current_map = &heap->map[k];
dcache_writeback_region(current_map,
sizeof(*current_map));
flush_block_map(current_map);
}
}

dcache_writeback_invalidate_region(heap, sizeof(*heap));
}

/* initialise runtime map */
Expand All @@ -676,18 +673,18 @@ void init_heap(struct sof *sof)

current_map = &heap->map[j];
current_map->base = heap->heap;
dcache_writeback_region(current_map,
sizeof(*current_map));
flush_block_map(current_map);

for (k = 1; k < heap->blocks; k++) {
next_map = &heap->map[k];
next_map->base = current_map->base +
current_map->block_size *
current_map->count;
current_map = &heap->map[k];
dcache_writeback_region(current_map,
sizeof(*current_map));
flush_block_map(current_map);
}
}

dcache_writeback_invalidate_region(heap, sizeof(*heap));
}
}