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…).

All the different regions can be added at run-time to the shared multi-heap pool providing an opaque “attribute” value (an integer or enum value) that can be used by drivers or applications to request memory with certain capabilities.

This framework is commonly used as follow:

  1. At boot time some platform code initialize the shared multi-heap framework using shared_multi_heap_pool_init() and add the memory regions to the pool with shared_multi_heap_add(), possibly gathering the needed information for the regions from the DT.

  2. Each memory region encoded in a shared_multi_heap_region structure. This structure is also carrying an opaque and user-defined integer value that is used to define the region capabilities (for example: cacheability, cpu affinity, etc…)

// Init the shared multi-heap pool
shared_multi_heap_pool_init()

// Fill the struct with the data for cacheable memory
struct shared_multi_heap_region cacheable_r0 = {
     .addr = addr_r0,
     .size = size_r0,
     .attr = SMH_REG_ATTR_CACHEABLE,
};

// Add the region to the pool
shared_multi_heap_add(&cacheable_r0, NULL);

// Add another cacheable region
struct shared_multi_heap_region cacheable_r1 = {
     .addr = addr_r1,
     .size = size_r1,
     .attr = SMH_REG_ATTR_CACHEABLE,
};

shared_multi_heap_add(&cacheable_r0, NULL);

// Add a non-cacheable region
struct shared_multi_heap_region non_cacheable_r2 = {
     .addr = addr_r2,
     .size = size_r2,
     .attr = SMH_REG_ATTR_NON_CACHEABLE,
};

shared_multi_heap_add(&non_cacheable_r2, NULL);
  1. When a driver or application needs some dynamic memory with a certain capability, it can use shared_multi_heap_alloc() (or the aligned version) to request the memory by using the opaque parameter to select the correct set of attributes for the needed memory. The framework will take care of selecting the correct heap (thus memory region) to carve memory from, based on the opaque parameter and the runtime state of the heaps (available memory, heap state, etc…)

// Allocate 4K from cacheable memory
shared_multi_heap_alloc(SMH_REG_ATTR_CACHEABLE, 0x1000);

// Allocate 4K from non-cacheable memory
shared_multi_heap_alloc(SMH_REG_ATTR_NON_CACHEABLE, 0x1000);

Adding new attributes

The API does not enforce any attributes, but at least it defines the two most common ones: SMH_REG_ATTR_CACHEABLE and SMH_REG_ATTR_NON_CACHEABLE

group shared_multi_heap

Shared Multi-Heap (SMH) interface.

The shared multi-heap manager uses the multi-heap allocator to manage a set of memory regions with different capabilities / attributes (cacheable, non-cacheable, etc…).

All the different regions can be added at run-time to the shared multi-heap pool providing an opaque “attribute” value (an integer or enum value) that can be used by drivers or applications to request memory with certain capabilities.

This framework is commonly used as follow:

  • At boot time some platform code initialize the shared multi-heap framework using shared_multi_heap_pool_init and add the memory regions to the pool with shared_multi_heap_add, possibly gathering the needed information for the regions from the DT.

  • Each memory region encoded in a shared_multi_heap_region structure. This structure is also carrying an opaque and user-defined integer value that is used to define the region capabilities (for example: cacheability, cpu affinity, etc…)

  • When a driver or application needs some dynamic memory with a certain capability, it can use shared_multi_heap_alloc (or the aligned version) to request the memory by using the opaque parameter to select the correct set of attributes for the needed memory. The framework will take care of selecting the correct heap (thus memory region) to carve memory from, based on the opaque parameter and the runtime state of the heaps (available memory, heap state, etc…)

Defines

MAX_SHARED_MULTI_HEAP_ATTR

Maximum number of standard attributes.

Enums

enum shared_multi_heap_attr

SMH region attributes enumeration type.

Enumeration type for some common memory region attributes.

Values:

enumerator SMH_REG_ATTR_CACHEABLE

cacheable

enumerator SMH_REG_ATTR_NON_CACHEABLE

non-cacheable

enumerator SMH_REG_ATTR_NUM

must be the last item

Functions

int shared_multi_heap_pool_init(void)

Init the pool.

This must be the first function to be called to initialize the shared multi-heap pool. All the individual heaps must be added later with shared_multi_heap_add.

Note

As for the generic multi-heap allocator the expectation is that this function will be called at soc- or board-level.

Return values:
  • 0 – on success.

  • -EALREADY – when the pool was already inited.

  • other – errno codes

void *shared_multi_heap_alloc(enum shared_multi_heap_attr attr, size_t bytes)

Allocate memory from the memory shared multi-heap pool.

Allocates a block of memory of the specified size in bytes and with a specified capability / attribute. The opaque attribute parameter is used by the backend to select the correct heap to allocate memory from.

Parameters:
  • attr – capability / attribute requested for the memory block.

  • bytes – requested size of the allocation in bytes.

Return values:
  • ptr – a valid pointer to heap memory.

  • err – NULL if no memory is available.

void *shared_multi_heap_aligned_alloc(enum shared_multi_heap_attr attr, size_t align, size_t bytes)

Allocate aligned memory from the memory shared multi-heap pool.

Allocates a block of memory of the specified size in bytes and with a specified capability / attribute. Takes an additional parameter specifying a power of two alignment in bytes.

Parameters:
  • attr – capability / attribute requested for the memory block.

  • align – power of two alignment for the returned pointer, in bytes.

  • bytes – requested size of the allocation in bytes.

Return values:
  • ptr – a valid pointer to heap memory.

  • err – NULL if no memory is available.

void shared_multi_heap_free(void *block)

Free memory from the shared multi-heap pool.

Used to free the passed block of memory that must be the return value of a previously call to shared_multi_heap_alloc or shared_multi_heap_aligned_alloc.

Parameters:
  • block – block to free, must be a pointer to a block allocated by shared_multi_heap_alloc or shared_multi_heap_aligned_alloc.

int shared_multi_heap_add(struct shared_multi_heap_region *region, void *user_data)

Add an heap region to the shared multi-heap pool.

This adds a shared multi-heap region to the multi-heap pool.

Parameters:
  • user_data – pointer to any data for the heap.

  • region – pointer to the memory region to be added.

Return values:
  • 0 – on success.

  • -EINVAL – when the region attribute is out-of-bound.

  • -ENOMEM – when there are no more heaps available.

  • other – errno codes

struct shared_multi_heap_region
#include <shared_multi_heap.h>

SMH region struct.

This struct is carrying information about the memory region to be added in the multi-heap pool.

Public Members

unsigned int attr

Memory heap attribute.

uintptr_t addr

Memory heap starting virtual address.

size_t size

Memory heap size in bytes.