Skip to content

Commit 5f32265

Browse files
nordic-krchnashif
authored andcommitted
soc: nordic: common: dmm: Fix memory utilization
DMM was enforcing cache line alignment all memory regions, including those which were not cacheable. Fixing it by using memory attribute from the device tree to determine if alignment needs to be applied. Because of that memory usage was significantly increased because even 1 byte buffers (e.g. for uart_poll_out) was consuming 32 bytes (cache line size). Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 19c1f9f commit 5f32265

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

soc/nordic/common/dmm.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
{.dt_addr = DT_REG_ADDR(node_id), \
2424
.dt_size = DT_REG_SIZE(node_id), \
2525
.dt_attr = DT_PROP(node_id, zephyr_memory_attr), \
26+
.dt_align = DMM_ALIGN_SIZE(node_id), \
2627
.dt_allc = &_BUILD_LINKER_END_VAR(node_id)},
2728

2829
/* Generate declarations of linker variables used to determine size of preallocated variables
@@ -36,6 +37,7 @@ struct dmm_region {
3637
uintptr_t dt_addr;
3738
size_t dt_size;
3839
uint32_t dt_attr;
40+
uint32_t dt_align;
3941
void *dt_allc;
4042
};
4143

@@ -91,7 +93,7 @@ static bool is_user_buffer_correctly_preallocated(void const *user_buffer, size_
9193
return true;
9294
}
9395

94-
if (IS_ALIGNED(addr, DMM_DCACHE_LINE_SIZE)) {
96+
if (IS_ALIGNED(addr, region->dt_align)) {
9597
/* If buffer is in cacheable region it must be aligned to data cache line size. */
9698
return true;
9799
}
@@ -101,7 +103,7 @@ static bool is_user_buffer_correctly_preallocated(void const *user_buffer, size_
101103

102104
static size_t dmm_heap_start_get(struct dmm_heap *dh)
103105
{
104-
return ROUND_UP(dh->region->dt_allc, DMM_DCACHE_LINE_SIZE);
106+
return ROUND_UP(dh->region->dt_allc, dh->region->dt_align);
105107
}
106108

107109
static size_t dmm_heap_size_get(struct dmm_heap *dh)
@@ -111,8 +113,8 @@ static size_t dmm_heap_size_get(struct dmm_heap *dh)
111113

112114
static void *dmm_buffer_alloc(struct dmm_heap *dh, size_t length)
113115
{
114-
length = ROUND_UP(length, DMM_DCACHE_LINE_SIZE);
115-
return sys_heap_aligned_alloc(&dh->heap, DMM_DCACHE_LINE_SIZE, length);
116+
length = ROUND_UP(length, dh->region->dt_align);
117+
return sys_heap_aligned_alloc(&dh->heap, dh->region->dt_align, length);
116118
}
117119

118120
static void dmm_buffer_free(struct dmm_heap *dh, void *buffer)

soc/nordic/common/dmm.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <stdint.h>
1515
#include <zephyr/devicetree.h>
1616
#include <zephyr/linker/devicetree_regions.h>
17+
#include <zephyr/mem_mgmt/mem_attr.h>
1718
#include <zephyr/sys/util.h>
1819

1920
#ifdef __cplusplus
@@ -22,8 +23,18 @@ extern "C" {
2223

2324
/** @cond INTERNAL_HIDDEN */
2425

25-
#define DMM_DCACHE_LINE_SIZE \
26-
COND_CODE_1(IS_ENABLED(CONFIG_DCACHE), (CONFIG_DCACHE_LINE_SIZE), (sizeof(uint8_t)))
26+
/* Determine if memory region for the peripheral is cacheable. */
27+
#define DMM_IS_REG_CACHEABLE(node_id) \
28+
COND_CODE_1(CONFIG_DCACHE, \
29+
(COND_CODE_1(DT_NODE_HAS_PROP(DT_PHANDLE(node_id, memory_regions), zephyr_memory_attr), \
30+
(DT_PROP(DT_PHANDLE(node_id, memory_regions), zephyr_memory_attr) & DT_MEM_CACHEABLE), \
31+
(0))), (0))
32+
33+
/* Determine required alignment of the static buffers in memory regions. Cache line alignment is
34+
* required if region is cacheable and data cache is enabled.
35+
*/
36+
#define DMM_ALIGN_SIZE(node_id) \
37+
(DMM_IS_REG_CACHEABLE(node_id) ? CONFIG_DCACHE_LINE_SIZE : sizeof(uint8_t))
2738

2839
/**
2940
* @brief Get reference to memory region associated with the specified device node
@@ -35,7 +46,6 @@ extern "C" {
3546
#define DMM_DEV_TO_REG(node_id) \
3647
COND_CODE_1(DT_NODE_HAS_PROP(node_id, memory_regions), \
3748
((void *)DT_REG_ADDR(DT_PHANDLE(node_id, memory_regions))), (NULL))
38-
3949
/**
4050
* @brief Preallocate buffer in memory region associated with the specified device node
4151
*
@@ -45,7 +55,7 @@ extern "C" {
4555
COND_CODE_1(DT_NODE_HAS_PROP(node_id, memory_regions), \
4656
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
4757
DT_PHANDLE(node_id, memory_regions))))) \
48-
__aligned(DMM_DCACHE_LINE_SIZE)), \
58+
__aligned(DMM_ALIGN_SIZE(node_id))), \
4959
())
5060

5161
#ifdef CONFIG_HAS_NORDIC_DMM

0 commit comments

Comments
 (0)