Snitch Runtime
Loading...
Searching...
No Matches
alloc.h
1// Copyright 2023 ETH Zurich and University of Bologna.
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#pragma once
6
7//================================================================================
8// Alignment
9//================================================================================
10
11#define MIN_CHUNK_SIZE 8
12
23inline uintptr_t snrt_align_up(uintptr_t addr, size_t size,
24 uintptr_t base = 0) {
25 return (((addr - base) + size - 1) / size) * size + base;
26}
27
28inline void *snrt_align_up(void *addr, size_t size, void *base = 0) {
29 return (void *)snrt_align_up((uintptr_t)addr, size, (uintptr_t)base);
30}
31
32inline uintptr_t snrt_align_up_hyperbank(uintptr_t addr) {
33 return snrt_align_up(addr, SNRT_TCDM_HYPERBANK_WIDTH, SNRT_TCDM_START_ADDR);
34}
35
36inline void *snrt_align_up_hyperbank(void *addr) {
37 return (void *)snrt_align_up_hyperbank((uintptr_t)addr);
38}
39
40//================================================================================
41// Allocation
42//================================================================================
43
44extern snrt_allocator_t l3_allocator;
45
46inline snrt_allocator_t *snrt_l1_allocator() {
47 return (snrt_allocator_t *)&(cls()->l1_allocator);
48}
49
50inline snrt_allocator_t *snrt_l3_allocator() { return &l3_allocator; }
51
52inline void *snrt_l1_next() { return (void *)snrt_l1_allocator()->next; }
53
54inline void *snrt_l3_next() { return (void *)snrt_l3_allocator()->next; }
55
63inline void *snrt_l1_alloc(size_t size) {
64 snrt_allocator_t *alloc = snrt_l1_allocator();
65
66 // TODO colluca: do we need this? What does it imply?
67 // one more instruction, TCDM consumption...
68 size = snrt_align_up(size, MIN_CHUNK_SIZE);
69
70 // TODO colluca
71 // if (alloc->next + size > alloc->base + alloc->size) {
72 // snrt_trace(
73 // SNRT_TRACE_ALLOC,
74 // "Not enough memory to allocate: base %#x size %#x next %#x\n",
75 // alloc->base, alloc->size, alloc->next);
76 // return 0;
77 // }
78
79 void *ret = (void *)alloc->next;
80 alloc->next += size;
81 return ret;
82}
83
87inline void snrt_l1_update_next(void *next) {
88 snrt_allocator_t *alloc = snrt_l1_allocator();
89 alloc->next = (uint32_t)next;
90}
91
99inline void *snrt_l3_alloc(size_t size) {
100 snrt_allocator_t *alloc = snrt_l3_allocator();
101
102 size = snrt_align_up(size, MIN_CHUNK_SIZE);
103
104 // TODO: L3 alloc size check
105
106 void *ret = (void *)alloc->next;
107 alloc->next += size;
108 return ret;
109}
110
111inline void snrt_alloc_init() {
112 // Only one core per cluster has to initialize the L1 allocator
113 if (snrt_is_dm_core()) {
114 // Initialize L1 allocator
115 // Note: at the moment the allocator assumes all of the TCDM is
116 // available for allocation. However, the CLS, TLS and stack already
117 // occupy a possibly significant portion.
118 snrt_l1_allocator()->base =
119 snrt_align_up(snrt_l1_start_addr(), MIN_CHUNK_SIZE);
120 snrt_l1_allocator()->end = snrt_l1_end_addr();
121 snrt_l1_allocator()->next = snrt_l1_allocator()->base;
122 // Initialize L3 allocator
123 extern uint32_t _edram;
124 snrt_l3_allocator()->base =
125 snrt_align_up((uint32_t)&_edram, MIN_CHUNK_SIZE);
126 snrt_l3_allocator()->end = snrt_l3_allocator()->base;
127 snrt_l3_allocator()->next = snrt_l3_allocator()->base;
128 }
129 // Synchronize with other cores
130 snrt_cluster_hw_barrier();
131}
Definition alloc_decls.h:10