From edd524b4e31ebab21d31e71af16a764a4b4063b1 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Tue, 9 Aug 2022 16:04:50 -0700 Subject: [PATCH] drivers/mm: Add API to query memory regions Some systems may need to query the available memory regions in runtime. For those, this patch adds a simple API that memory management drivers can implement to provide such discovery. A small test also added to exercise the default, empty implementation. Signed-off-by: Ederson de Souza --- drivers/mm/mm_drv_common.c | 21 +++++++++ include/zephyr/drivers/mm/system_mm.h | 47 +++++++++++++++++++ .../drivers/mm/sys_mm_drv_api/CMakeLists.txt | 7 +++ tests/drivers/mm/sys_mm_drv_api/prj.conf | 3 ++ tests/drivers/mm/sys_mm_drv_api/src/main.c | 24 ++++++++++ tests/drivers/mm/sys_mm_drv_api/testcase.yaml | 3 ++ 6 files changed, 105 insertions(+) create mode 100644 tests/drivers/mm/sys_mm_drv_api/CMakeLists.txt create mode 100644 tests/drivers/mm/sys_mm_drv_api/prj.conf create mode 100644 tests/drivers/mm/sys_mm_drv_api/src/main.c create mode 100644 tests/drivers/mm/sys_mm_drv_api/testcase.yaml diff --git a/drivers/mm/mm_drv_common.c b/drivers/mm/mm_drv_common.c index b7c8bdc4c8a..c2336ed9286 100644 --- a/drivers/mm/mm_drv_common.c +++ b/drivers/mm/mm_drv_common.c @@ -469,3 +469,24 @@ out: __weak FUNC_ALIAS(sys_mm_drv_simple_update_region_flags, sys_mm_drv_update_region_flags, int); + +const struct sys_mm_drv_region *sys_mm_drv_simple_query_memory_regions(void) +{ + const static struct sys_mm_drv_region empty[] = { + { } + }; + + return empty; +} + +__weak FUNC_ALIAS(sys_mm_drv_simple_query_memory_regions, + sys_mm_drv_query_memory_regions, + const struct sys_mm_drv_region *); + +void sys_mm_drv_simple_query_memory_regions_free(const struct sys_mm_drv_region *regions) +{ + ARG_UNUSED(regions); +} + +__weak FUNC_ALIAS(sys_mm_drv_simple_query_memory_regions_free, + sys_mm_drv_query_memory_regions_free, void); diff --git a/include/zephyr/drivers/mm/system_mm.h b/include/zephyr/drivers/mm/system_mm.h index 8f5719abaf6..e407041889e 100644 --- a/include/zephyr/drivers/mm/system_mm.h +++ b/include/zephyr/drivers/mm/system_mm.h @@ -340,6 +340,53 @@ int sys_mm_drv_update_page_flags(void *virt, uint32_t flags); int sys_mm_drv_update_region_flags(void *virt, size_t size, uint32_t flags); +/** + * @brief Represents an available memory region. + * + * A memory region that can be used by allocators. Driver defined + * attributes can be used to guide the proper usage of each region. + */ +struct sys_mm_drv_region { + void *addr; /**< @brief Address of the memory region */ + size_t size; /**< @brief Size of the memory region */ + uint32_t attr; /**< @brief Driver defined attributes of the memory region */ +}; + +/* TODO is it safe to assume no valid region has size == 0? */ +/** + * @brief Iterates over an array of regions returned by #sys_mm_drv_query_memory_regions + * + * Note that a sentinel item marking the end of the array is expected for + * this macro to work. + */ +#define SYS_MM_DRV_MEMORY_REGION_FOREACH(regions, iter) \ + for (iter = regions; iter->size; iter++) + +/** + * @brief Query available memory regions + * + * Returns an array of available memory regions. One can iterate over + * the array using #SYS_MM_DRV_MEMORY_REGION_FOREACH. Note that the last + * item of the array is a sentinel marking the end, and it's identified + * by it's size attribute, which is zero. + * + * @retval regions A possibly empty array - i.e. containing only the sentinel + * marking at the end - of memory regions. + */ +const struct sys_mm_drv_region *sys_mm_drv_query_memory_regions(void); + +/** + * @brief Free the memory array returned by #sys_mm_drv_query_memory_regions + * + * The driver may have dynamically allocated the memory for the array of + * regions returned by #sys_mm_drv_query_memory_regions. This method provides + * it the opportunity to free any related resources. + * + * @param regions Array of regions previously returned by + * #sys_mm_drv_query_memory_regions + */ +void sys_mm_drv_query_memory_regions_free(const struct sys_mm_drv_region *regions); + /** * @} */ diff --git a/tests/drivers/mm/sys_mm_drv_api/CMakeLists.txt b/tests/drivers/mm/sys_mm_drv_api/CMakeLists.txt new file mode 100644 index 00000000000..242c2940264 --- /dev/null +++ b/tests/drivers/mm/sys_mm_drv_api/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(sys_mm_drv_api) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/mm/sys_mm_drv_api/prj.conf b/tests/drivers/mm/sys_mm_drv_api/prj.conf new file mode 100644 index 00000000000..7ccdfd1ddf2 --- /dev/null +++ b/tests/drivers/mm/sys_mm_drv_api/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_MM_DRV=y diff --git a/tests/drivers/mm/sys_mm_drv_api/src/main.c b/tests/drivers/mm/sys_mm_drv_api/src/main.c new file mode 100644 index 00000000000..30b625b9531 --- /dev/null +++ b/tests/drivers/mm/sys_mm_drv_api/src/main.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +ZTEST(sys_mm_drv_api, test_query_memory_region_sanity) +{ + const struct sys_mm_drv_region *regions, *region; + + regions = sys_mm_drv_query_memory_regions(); + zassert_not_null(regions, NULL); + + SYS_MM_DRV_MEMORY_REGION_FOREACH(regions, region) + ; /* just iterate, do nothing */ + + zassert_equal(region->size, 0, NULL); + + sys_mm_drv_query_memory_regions_free(regions); +} + +ZTEST_SUITE(sys_mm_drv_api, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/mm/sys_mm_drv_api/testcase.yaml b/tests/drivers/mm/sys_mm_drv_api/testcase.yaml new file mode 100644 index 00000000000..347571af33c --- /dev/null +++ b/tests/drivers/mm/sys_mm_drv_api/testcase.yaml @@ -0,0 +1,3 @@ +tests: + drivers.mm.sys_mm_drv_api: + tags: drivers