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 <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza 2022-08-09 16:04:50 -07:00 committed by Anas Nashif
commit edd524b4e3
6 changed files with 105 additions and 0 deletions

View file

@ -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);

View file

@ -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);
/**
* @}
*/

View file

@ -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)

View file

@ -0,0 +1,3 @@
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
CONFIG_MM_DRV=y

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/drivers/mm/system_mm.h>
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);

View file

@ -0,0 +1,3 @@
tests:
drivers.mm.sys_mm_drv_api:
tags: drivers