Skip to content

Commit ecb6fbc

Browse files
nordic-krchnordicjm
authored andcommitted
[nrf fromtree] soc: nordic: common: dmm: Optimize memcpy
Default memcpy used in zephyr is not optimized and performs simple byte by byte copying. Using double word or word access can significantly reduce copying time especially for RAM3 (slow peripheral RAM). Signed-off-by: Krzysztof Chruściński <[email protected]> (cherry picked from commit ff3e018)
1 parent 59779a4 commit ecb6fbc

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

soc/nordic/common/dmm.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,27 @@ static void dmm_buffer_free(struct dmm_heap *dh, void *buffer)
136136
k_spin_unlock(&dh->lock, key);
137137
}
138138

139+
static void dmm_memcpy(void *dst, const void *src, size_t len)
140+
{
141+
#define IS_ALIGNED32(x) IS_ALIGNED(x, sizeof(uint32_t))
142+
#define IS_ALIGNED64(x) IS_ALIGNED(x, sizeof(uint64_t))
143+
if (IS_ALIGNED64(len) && IS_ALIGNED64(dst) && IS_ALIGNED64(src)) {
144+
for (uint32_t i = 0; i < len / sizeof(uint64_t); i++) {
145+
((uint64_t *)dst)[i] = ((uint64_t *)src)[i];
146+
}
147+
return;
148+
}
149+
150+
if (IS_ALIGNED32(len) && IS_ALIGNED32(dst) && IS_ALIGNED32(src)) {
151+
for (uint32_t i = 0; i < len / sizeof(uint32_t); i++) {
152+
((uint32_t *)dst)[i] = ((uint32_t *)src)[i];
153+
}
154+
return;
155+
}
156+
157+
memcpy(dst, src, len);
158+
}
159+
139160
int dmm_buffer_out_prepare(void *region, void const *user_buffer, size_t user_length,
140161
void **buffer_out)
141162
{
@@ -172,7 +193,7 @@ int dmm_buffer_out_prepare(void *region, void const *user_buffer, size_t user_le
172193
return -ENOMEM;
173194
}
174195
/* - copy user buffer contents into allocated buffer */
175-
memcpy(*buffer_out, user_buffer, user_length);
196+
dmm_memcpy(*buffer_out, user_buffer, user_length);
176197
}
177198

178199
/* Check if device memory region is cacheable
@@ -281,7 +302,7 @@ int dmm_buffer_in_release(void *region, void *user_buffer, size_t user_length, v
281302
* If no, copy allocated buffer to the user buffer
282303
*/
283304
if (buffer_in != user_buffer) {
284-
memcpy(user_buffer, buffer_in, user_length);
305+
dmm_memcpy(user_buffer, buffer_in, user_length);
285306
}
286307
/* If yes, no action is needed */
287308

soc/nordic/common/dmm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ extern "C" {
3535
* Cache line alignment is required if region is cacheable and data cache is enabled.
3636
*/
3737
#define DMM_REG_ALIGN_SIZE(node_id) \
38-
(DMM_IS_REG_CACHEABLE(node_id) ? CONFIG_DCACHE_LINE_SIZE : sizeof(uint8_t))
38+
(DMM_IS_REG_CACHEABLE(node_id) ? CONFIG_DCACHE_LINE_SIZE : sizeof(uint32_t))
3939

4040
#else
4141

4242
#define DMM_IS_REG_CACHEABLE(node_id) 0
43-
#define DMM_REG_ALIGN_SIZE(node_id) (sizeof(uint8_t))
43+
#define DMM_REG_ALIGN_SIZE(node_id) (sizeof(uint32_t))
4444

4545
#endif /* CONFIG_DCACHE */
4646

0 commit comments

Comments
 (0)