multi_heap: Introduce shared multi-heap memory pool manager
The shared multi-heap memory pool manager uses the multi-heap allocator to manage a set of reserved memory regions with different capabilities / attributes (cacheable, non-cacheable, etc...) defined in the DT. The user can request allocation from the shared pool specifying the capability / attribute of interest for the memory (cacheable / non-cacheable memory, etc...) Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
863600cd0e
commit
43cb00df08
|
@ -9,3 +9,4 @@ The following contains various topics regarding memory management.
|
|||
:maxdepth: 1
|
||||
|
||||
demand_paging.rst
|
||||
shared_multi_heap.rst
|
||||
|
|
84
doc/reference/memory_management/shared_multi_heap.rst
Normal file
84
doc/reference/memory_management/shared_multi_heap.rst
Normal file
|
@ -0,0 +1,84 @@
|
|||
.. _memory_management_shared_multi_heap:
|
||||
|
||||
Shared Multi Heap
|
||||
#################
|
||||
|
||||
The shared multi-heap memory pool manager uses the multi-heap allocator to
|
||||
manage a set of reserved memory regions with different capabilities /
|
||||
attributes (cacheable, non-cacheable, etc...) defined in the DT.
|
||||
|
||||
The user can request allocation from the shared pool specifying the capability
|
||||
/ attribute of interest for the memory (cacheable / non-cacheable memory,
|
||||
etc...).
|
||||
|
||||
The different heaps with their attributes available in the shared pool are
|
||||
defined into the DT file leveraging the ``reserved-memory`` nodes.
|
||||
|
||||
This is a DT example declaring three different memory regions with different
|
||||
cacheability attributes: ``cacheable`` and ``non-cacheable``
|
||||
|
||||
.. code-block:: devicetree
|
||||
|
||||
/ {
|
||||
reserved-memory {
|
||||
compatible = "reserved-memory";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
res0: reserved@42000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x42000000 0x1000>;
|
||||
capability = "cacheable";
|
||||
label = "res0";
|
||||
};
|
||||
|
||||
res1: reserved@43000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x43000000 0x2000>;
|
||||
capability = "non-cacheable";
|
||||
label = "res1";
|
||||
};
|
||||
|
||||
res2: reserved2@44000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x44000000 0x3000>;
|
||||
capability = "cacheable";
|
||||
label = "res2";
|
||||
};
|
||||
};
|
||||
|
||||
The user can then request 4K from heap memory ``cacheable`` or
|
||||
``non-cacheable`` using the provided APIs:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Allocate 4K from cacheable memory
|
||||
shared_multi_heap_alloc(SMH_REG_ATTR_CACHEABLE, 0x1000);
|
||||
|
||||
// Allocate 4K from non-cacheable
|
||||
shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0x1000);
|
||||
|
||||
The backend implementation will allocate the memory region from the heap with
|
||||
the correct attribute and using the region able to accommodate the required size.
|
||||
|
||||
Special handling for MMU/MPU
|
||||
****************************
|
||||
|
||||
For MMU/MPU enabled platform sometimes it is required to setup and configure
|
||||
the memory regions before these are added to the managed pool. This is done at
|
||||
init time using the :c:func:`shared_multi_heap_pool_init()` function that is
|
||||
accepting a :c:type:`smh_init_reg_fn_t` callback function. This callback will
|
||||
be called for each memory region at init time and it can be used to correctly
|
||||
map the region before this is considered valid and accessible.
|
||||
|
||||
Adding new attributes
|
||||
*********************
|
||||
|
||||
Currently only two memory attributes are supported: ``cacheable`` and
|
||||
``non-cacheable``. To add a new attribute:
|
||||
|
||||
1. Add the new ``enum`` for the attribute in the :c:enum:`smh_reg_attr`
|
||||
2. Add the corresponding attribute name in :file:`shared-multi-heap.yaml`
|
||||
|
||||
.. doxygengroup:: shared_multi_heap
|
||||
:project: Zephyr
|
20
dts/bindings/multi_heap_manager/shared-multi-heap.yaml
Normal file
20
dts/bindings/multi_heap_manager/shared-multi-heap.yaml
Normal file
|
@ -0,0 +1,20 @@
|
|||
description: Shared multi-heap memory pool manager
|
||||
|
||||
compatible: "shared-multi-heap"
|
||||
|
||||
include:
|
||||
- name: base.yaml
|
||||
property-allowlist: ['reg', 'label']
|
||||
|
||||
properties:
|
||||
# Keep this is sync with shared_multi_heap.h
|
||||
capability:
|
||||
type: string
|
||||
required: false
|
||||
description: memory region capability
|
||||
enum:
|
||||
- "cacheable"
|
||||
- "non-cacheable"
|
||||
|
||||
label:
|
||||
required: true
|
122
include/multi_heap/shared_multi_heap.h
Normal file
122
include/multi_heap/shared_multi_heap.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Carlo Caione, <ccaione@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_MULTI_HEAP_MANAGER_SMH_H_
|
||||
#define ZEPHYR_INCLUDE_MULTI_HEAP_MANAGER_SMH_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Shared multi-heap interface
|
||||
* @defgroup shared_multi_heap Shared multi-heap interface
|
||||
* @ingroup multi_heap
|
||||
* @{
|
||||
*
|
||||
* The shared multi-heap manager uses the multi-heap allocator to manage a set
|
||||
* of reserved memory regions with different capabilities / attributes
|
||||
* (cacheable, non-cacheable, etc...) defined in the DT.
|
||||
*
|
||||
* The user can request allocation from the shared pool specifying the
|
||||
* capability / attribute of interest for the memory (cacheable / non-cacheable
|
||||
* memory, etc...)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Memory region attributes / capabilities
|
||||
*
|
||||
* ** This list needs to be kept in sync with shared-multi-heap.yaml **
|
||||
*/
|
||||
enum smh_reg_attr {
|
||||
/** cacheable */
|
||||
SMH_REG_ATTR_CACHEABLE,
|
||||
|
||||
/** non-cacheable */
|
||||
SMH_REG_ATTR_NON_CACHEABLE,
|
||||
|
||||
/** must be the last item */
|
||||
SMH_REG_ATTR_NUM,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SMH region struct
|
||||
*
|
||||
* This struct is carrying information about the memory region to be added in
|
||||
* the multi-heap pool. This is filled by the manager with the information
|
||||
* coming from the reserved memory children nodes in the DT.
|
||||
*/
|
||||
struct shared_multi_heap_region {
|
||||
enum smh_reg_attr attr;
|
||||
uintptr_t addr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Region init function
|
||||
*
|
||||
* This is a user-provided function whose responsibility is to setup or
|
||||
* initialize the memory region passed in input before this is added to the
|
||||
* heap pool by the shared multi-heap manager. This function can be used by
|
||||
* architectures using MMU / MPU that must correctly map the region before this
|
||||
* is considered valid and accessible.
|
||||
*
|
||||
* @param reg Pointer to the SMH region structure.
|
||||
* @param v_addr Virtual address obtained after mapping. For non-MMU
|
||||
* architectures this value is the physical address of the
|
||||
* region.
|
||||
* @param size Size of the region after mapping.
|
||||
*
|
||||
* @return True if the region is ready to be added to the heap pool.
|
||||
* False if the region must be skipped.
|
||||
*/
|
||||
typedef bool (*smh_init_reg_fn_t)(struct shared_multi_heap_region *reg,
|
||||
uint8_t **v_addr, size_t *size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Init the pool
|
||||
*
|
||||
* Initialize the shared multi-heap pool and hook-up the region init function.
|
||||
*
|
||||
* @param smh_init_reg_fn The function pointer to the region init function. Can
|
||||
* be NULL for non-MPU / non-MMU architectures.
|
||||
*/
|
||||
int shared_multi_heap_pool_init(smh_init_reg_fn_t smh_init_reg_fn);
|
||||
|
||||
/**
|
||||
* @brief Allocate memory from the memory shared multi-heap pool
|
||||
*
|
||||
* Allocate a block of memory of the specified size in bytes and with a
|
||||
* specified capability / attribute.
|
||||
*
|
||||
* @param attr Capability / attribute requested for the memory block.
|
||||
* @param bytes Requested size of the allocation in bytes.
|
||||
*
|
||||
* @return A valid pointer to heap memory or NULL if no memory is available.
|
||||
*/
|
||||
void *shared_multi_heap_alloc(enum smh_reg_attr attr, size_t bytes);
|
||||
|
||||
/**
|
||||
* @brief Free memory from the shared multi-heap pool
|
||||
*
|
||||
* Free the passed block of memory.
|
||||
*
|
||||
* @param block Block to free.
|
||||
*/
|
||||
void shared_multi_heap_free(void *block);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_MULTI_HEAP_MANAGER_SMH_H_ */
|
|
@ -43,6 +43,8 @@ zephyr_sources_ifdef(CONFIG_SCHED_DEADLINE p4wq.c)
|
|||
|
||||
zephyr_sources_ifdef(CONFIG_REBOOT reboot.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_SHARED_MULTI_HEAP shared_multi_heap.c)
|
||||
|
||||
zephyr_library_include_directories(
|
||||
${ZEPHYR_BASE}/kernel/include
|
||||
${ZEPHYR_BASE}/arch/${ARCH}/include
|
||||
|
|
|
@ -63,6 +63,14 @@ config MPSC_PBUF
|
|||
storing variable length packets in a circular way and operate directly
|
||||
on the buffer memory.
|
||||
|
||||
config SHARED_MULTI_HEAP
|
||||
bool "Shared multi-heap manager"
|
||||
help
|
||||
Enable support for a shared multi-heap manager that uses the
|
||||
multi-heap allocator to manage a set of reserved memory regions with
|
||||
different capabilities / attributes (cacheable, non-cacheable,
|
||||
etc...) defined in the DT.
|
||||
|
||||
if MPSC_PBUF
|
||||
config MPSC_CLEAR_ALLOCATED
|
||||
bool "Clear allocated packet"
|
||||
|
|
117
lib/os/shared_multi_heap.c
Normal file
117
lib/os/shared_multi_heap.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Carlo Caione, <ccaione@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <device.h>
|
||||
#include <sys/sys_heap.h>
|
||||
#include <sys/multi_heap.h>
|
||||
#include <linker/linker-defs.h>
|
||||
|
||||
#include <multi_heap/shared_multi_heap.h>
|
||||
|
||||
#define DT_DRV_COMPAT shared_multi_heap
|
||||
|
||||
#define NUM_REGIONS DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static struct sys_multi_heap shared_multi_heap;
|
||||
static struct sys_heap heap_pool[SMH_REG_ATTR_NUM][NUM_REGIONS];
|
||||
|
||||
static smh_init_reg_fn_t smh_init_reg;
|
||||
|
||||
#define FOREACH_REG(n) \
|
||||
{ .addr = (uintptr_t) LINKER_DT_RESERVED_MEM_GET_PTR(DT_DRV_INST(n)), \
|
||||
.size = LINKER_DT_RESERVED_MEM_GET_SIZE(DT_DRV_INST(n)), \
|
||||
.attr = DT_ENUM_IDX(DT_DRV_INST(n), capability), \
|
||||
},
|
||||
|
||||
static struct shared_multi_heap_region dt_region[NUM_REGIONS] = {
|
||||
DT_INST_FOREACH_STATUS_OKAY(FOREACH_REG)
|
||||
};
|
||||
|
||||
static void *smh_choice(struct sys_multi_heap *mheap, void *cfg, size_t align, size_t size)
|
||||
{
|
||||
enum smh_reg_attr attr;
|
||||
struct sys_heap *h;
|
||||
void *block;
|
||||
|
||||
attr = (enum smh_reg_attr) cfg;
|
||||
|
||||
if (attr >= SMH_REG_ATTR_NUM || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t reg = 0; reg < NUM_REGIONS; reg++) {
|
||||
h = &heap_pool[attr][reg];
|
||||
|
||||
if (h->heap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block = sys_heap_aligned_alloc(h, align, size);
|
||||
if (block != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static void smh_init_with_attr(enum smh_reg_attr attr)
|
||||
{
|
||||
unsigned int slot = 0;
|
||||
uint8_t *mapped;
|
||||
size_t size;
|
||||
|
||||
for (size_t reg = 0; reg < NUM_REGIONS; reg++) {
|
||||
if (dt_region[reg].attr == attr) {
|
||||
|
||||
if (smh_init_reg != NULL) {
|
||||
smh_init_reg(&dt_region[reg], &mapped, &size);
|
||||
} else {
|
||||
mapped = (uint8_t *) dt_region[reg].addr;
|
||||
size = dt_region[reg].size;
|
||||
}
|
||||
|
||||
sys_heap_init(&heap_pool[attr][slot], mapped, size);
|
||||
sys_multi_heap_add_heap(&shared_multi_heap, &heap_pool[attr][slot]);
|
||||
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void shared_multi_heap_free(void *block)
|
||||
{
|
||||
sys_multi_heap_free(&shared_multi_heap, block);
|
||||
}
|
||||
|
||||
void *shared_multi_heap_alloc(enum smh_reg_attr attr, size_t bytes)
|
||||
{
|
||||
return sys_multi_heap_alloc(&shared_multi_heap, (void *) attr, bytes);
|
||||
}
|
||||
|
||||
int shared_multi_heap_pool_init(smh_init_reg_fn_t smh_init_reg_fn)
|
||||
{
|
||||
smh_init_reg = smh_init_reg_fn;
|
||||
|
||||
sys_multi_heap_init(&shared_multi_heap, smh_choice);
|
||||
|
||||
for (size_t attr = 0; attr < SMH_REG_ATTR_NUM; attr++) {
|
||||
smh_init_with_attr(attr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shared_multi_heap_init(const struct device *dev)
|
||||
{
|
||||
__ASSERT_NO_MSG(NUM_REGIONS <= MAX_MULTI_HEAPS);
|
||||
|
||||
/* Nothing to do here. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
SYS_INIT(shared_multi_heap_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
8
tests/kernel/mem_heap/shared_multi_heap/CMakeLists.txt
Normal file
8
tests/kernel/mem_heap/shared_multi_heap/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(shared_multi_heap_pool)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
reserved-memory {
|
||||
compatible = "reserved-memory";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
res0: reserved@42000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x42000000 0x1000>;
|
||||
capability = "cacheable";
|
||||
label = "res0";
|
||||
};
|
||||
|
||||
res1: reserved@43000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x43000000 0x2000>;
|
||||
capability = "non-cacheable";
|
||||
label = "res1";
|
||||
};
|
||||
|
||||
res2: reserved2@44000000 {
|
||||
compatible = "shared-multi-heap";
|
||||
reg = <0x44000000 0x3000>;
|
||||
capability = "cacheable";
|
||||
label = "res2";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) Carlo Caione <ccaione@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <autoconf.h>
|
||||
#include <linker/sections.h>
|
||||
#include <devicetree.h>
|
||||
|
||||
#include <linker/linker-defs.h>
|
||||
#include <linker/linker-tool.h>
|
||||
|
||||
MEMORY
|
||||
{
|
||||
LINKER_DT_RESERVED_MEM_REGIONS()
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
LINKER_DT_RESERVED_MEM_SECTIONS()
|
||||
}
|
||||
|
||||
#include <arch/arm64/scripts/linker.ld>
|
7
tests/kernel/mem_heap/shared_multi_heap/prj.conf
Normal file
7
tests/kernel/mem_heap/shared_multi_heap/prj.conf
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright 2021 Carlo Caione <ccaione@baylibre.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
|
||||
CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm64_shared_pool.ld"
|
||||
CONFIG_SHARED_MULTI_HEAP=y
|
129
tests/kernel/mem_heap/shared_multi_heap/src/main.c
Normal file
129
tests/kernel/mem_heap/shared_multi_heap/src/main.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <ztest.h>
|
||||
#include <linker/linker-defs.h>
|
||||
#include <sys/mem_manage.h>
|
||||
|
||||
#include <multi_heap/shared_multi_heap.h>
|
||||
|
||||
#define MAX_REGIONS (3)
|
||||
|
||||
static struct {
|
||||
struct shared_multi_heap_region *reg;
|
||||
uint8_t *v_addr;
|
||||
} map[MAX_REGIONS];
|
||||
|
||||
static bool smh_reg_init(struct shared_multi_heap_region *reg, uint8_t **v_addr, size_t *size)
|
||||
{
|
||||
static int reg_idx;
|
||||
uint32_t mem_attr;
|
||||
|
||||
mem_attr = (reg->attr == SMH_REG_ATTR_CACHEABLE) ? K_MEM_CACHE_WB : K_MEM_CACHE_NONE;
|
||||
mem_attr |= K_MEM_PERM_RW;
|
||||
|
||||
z_phys_map(v_addr, reg->addr, reg->size, mem_attr);
|
||||
|
||||
*size = reg->size;
|
||||
|
||||
/* Save the mapping to retrieve the region from the vaddr */
|
||||
map[reg_idx].reg = reg;
|
||||
map[reg_idx].v_addr = *v_addr;
|
||||
|
||||
reg_idx++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct shared_multi_heap_region *get_reg_addr(uint8_t *v_addr)
|
||||
{
|
||||
for (size_t reg = 0; reg < MAX_REGIONS; reg++) {
|
||||
if (v_addr >= map[reg].v_addr &&
|
||||
v_addr < map[reg].v_addr + map[reg].reg->size) {
|
||||
return map[reg].reg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void test_shared_multi_heap(void)
|
||||
{
|
||||
struct shared_multi_heap_region *reg;
|
||||
uint8_t *block;
|
||||
|
||||
shared_multi_heap_pool_init(smh_reg_init);
|
||||
|
||||
/*
|
||||
* Request a small cacheable chunk. It should be allocated in the
|
||||
* smaller region (@ 0x42000000)
|
||||
*/
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_CACHEABLE, 0x40);
|
||||
reg = get_reg_addr(block);
|
||||
|
||||
zassert_equal(reg->addr, 0x42000000, "block in the wrong memory region");
|
||||
zassert_equal(reg->attr, SMH_REG_ATTR_CACHEABLE, "wrong memery attribute");
|
||||
|
||||
/*
|
||||
* Request another small cacheable chunk. It should be allocated in the
|
||||
* smaller cacheable region (@ 0x42000000)
|
||||
*/
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_CACHEABLE, 0x80);
|
||||
reg = get_reg_addr(block);
|
||||
|
||||
zassert_equal(reg->addr, 0x42000000, "block in the wrong memory region");
|
||||
zassert_equal(reg->attr, SMH_REG_ATTR_CACHEABLE, "wrong memory attribute");
|
||||
|
||||
/*
|
||||
* Request a big cacheable chunk. It should be allocated in the
|
||||
* bigger cacheable region (@ 0x44000000)
|
||||
*/
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_CACHEABLE, 0x1200);
|
||||
reg = get_reg_addr(block);
|
||||
|
||||
zassert_equal(reg->addr, 0x44000000, "block in the wrong memory region");
|
||||
zassert_equal(reg->attr, SMH_REG_ATTR_CACHEABLE, "wrong memory attribute");
|
||||
|
||||
/*
|
||||
* Request a non-cacheable chunk. It should be allocated in the
|
||||
* non-cacheable region (@ 0x43000000)
|
||||
*/
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0x100);
|
||||
reg = get_reg_addr(block);
|
||||
|
||||
zassert_equal(reg->addr, 0x43000000, "block in the wrong memory region");
|
||||
zassert_equal(reg->attr, SMH_REG_ATTR_NON_CACHEABLE, "wrong memory attribute");
|
||||
|
||||
/*
|
||||
* Request again a non-cacheable chunk. It should be allocated in the
|
||||
* non-cacheable region (@ 0x43000000)
|
||||
*/
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0x100);
|
||||
reg = get_reg_addr(block);
|
||||
|
||||
zassert_equal(reg->addr, 0x43000000, "block in the wrong memory region");
|
||||
zassert_equal(reg->attr, SMH_REG_ATTR_NON_CACHEABLE, "wrong memory attribute");
|
||||
|
||||
/* Request a block too big */
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0x10000);
|
||||
zassert_is_null(block, "allocated buffer too big for the region");
|
||||
|
||||
/* Request a 0-sized block */
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0);
|
||||
zassert_is_null(block, "0 size accepted as valid");
|
||||
|
||||
/* Request a non-existent attribute */
|
||||
block = shared_multi_heap_alloc(SMH_REG_ATTR_NUM + 1, 0x100);
|
||||
zassert_is_null(block, "wrong attribute accepted as valid");
|
||||
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(shared_multi_heap,
|
||||
ztest_1cpu_unit_test(test_shared_multi_heap));
|
||||
ztest_run_test_suite(shared_multi_heap);
|
||||
}
|
8
tests/kernel/mem_heap/shared_multi_heap/testcase.yaml
Normal file
8
tests/kernel/mem_heap/shared_multi_heap/testcase.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright 2021 Carlo Caione <ccaione@baylibre.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
tests:
|
||||
kernel.shared_multi_heap:
|
||||
platform_allow: qemu_cortex_a53
|
||||
tags: board multi_heap
|
||||
harness: ztest
|
Loading…
Reference in a new issue