Files
zephyr/subsys/mem_mgmt/mem_attr.c
Firas Sammoura 6834cd5dae mem_mgmt: add mem_attr_get_region_index_by_name()
Add a new API to look up a memory region's index using its DeviceTree
node name. This allows callers to identify specific regions within the
internal regions array.

Includes unit tests for successful lookups and error handling for
non-existent names.

Signed-off-by: Firas Sammoura <fsammoura@google.com>
2026-01-14 09:56:53 +01:00

81 lines
2.0 KiB
C

/*
* Copyright (c) 2023 Carlo Caione, <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/mem_mgmt/mem_attr.h>
#include <string.h>
#define _BUILD_MEM_ATTR_REGION(node_id) \
{ \
.dt_name = DT_NODE_FULL_NAME(node_id), \
.dt_addr = DT_REG_ADDR(node_id), \
.dt_size = DT_REG_SIZE(node_id), \
.dt_attr = DT_PROP(node_id, zephyr_memory_attr), \
},
static const struct mem_attr_region_t mem_attr_region[] = {
DT_MEMORY_ATTR_FOREACH_STATUS_OKAY_NODE(_BUILD_MEM_ATTR_REGION)
};
size_t mem_attr_get_regions(const struct mem_attr_region_t **region)
{
*region = mem_attr_region;
return ARRAY_SIZE(mem_attr_region);
}
int mem_attr_check_buf(void *v_addr, size_t size, uint32_t attr)
{
uintptr_t addr = (uintptr_t) v_addr;
/*
* If MMU is enabled the address of the buffer is a virtual address
* while the addresses in the DT are physical addresses. Given that we
* have no way of knowing whether a mapping exists, we simply bail out.
*/
if (IS_ENABLED(CONFIG_MMU)) {
return -ENOSYS;
}
if (size == 0) {
return -ENOTSUP;
}
for (size_t idx = 0; idx < ARRAY_SIZE(mem_attr_region); idx++) {
const struct mem_attr_region_t *region = &mem_attr_region[idx];
size_t region_end = region->dt_addr + region->dt_size;
/* Check if the buffer is in the region */
if ((addr >= region->dt_addr) && (addr < region_end)) {
/* Check if the buffer is entirely contained in the region */
if ((addr + size) <= region_end) {
/* check if the attribute is correct */
return (region->dt_attr & attr) == attr ? 0 : -EINVAL;
}
return -ENOSPC;
}
}
return -ENOBUFS;
}
int mem_attr_get_region_index_by_name(const char *target_name)
{
const struct mem_attr_region_t *regions;
size_t num_regions;
num_regions = mem_attr_get_regions(&regions);
for (int i = 0; i < num_regions; ++i) {
if (regions[i].dt_name != NULL &&
strcmp(regions[i].dt_name, target_name) == 0) {
return i;
}
}
return -ENOENT;
}