Skip to content

Commit

Permalink
snRuntime: Document fundamental modules
Browse files Browse the repository at this point in the history
  • Loading branch information
colluca committed Aug 26, 2024
1 parent 8fc4fcf commit 3afc796
Show file tree
Hide file tree
Showing 5 changed files with 520 additions and 115 deletions.
102 changes: 85 additions & 17 deletions sw/snRuntime/src/alloc_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,61 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

/**
* @file
* @brief Defines functions to dynamically allocate the cluster's L1 memory.
*
* This file provides functions to dynamically allocate the cluster's L1
* memory. It includes functions for allocating memory for cluster-local
* variables, compute core-local variables, and for manipulating pointers to
* variables allocated by different cores or clusters.
*/

extern __thread snrt_allocator_t l1_allocator_v2;

/**
* @brief Get a pointer to the L1 allocator.
*
* @return Pointer to the L1 allocator.
*/
inline snrt_allocator_t *snrt_l1_allocator_v2() { return &l1_allocator_v2; }

/**
* @brief Get the next pointer of the L1 allocator.
*
* @return The next pointer of the L1 allocator.
*/
inline void *snrt_l1_next_v2() { return (void *)snrt_l1_allocator_v2()->next; }

/**
* @brief Override the L1 allocator next pointer
* @brief Override the L1 allocator next pointer.
*
* @param next The new value for the next pointer.
*/
inline void snrt_l1_update_next_v2(void *next) {
snrt_l1_allocator_v2()->next = (uint32_t)next;
}

// Check that allocation doesn't exceed allocator bounds, and raise an
// exception otherwise
/**
* @brief Check if the allocation exceeds the allocator bounds and raise an
* exception if it does.
*/
inline void snrt_l1_alloc_check_bounds() {
if (snrt_l1_allocator_v2()->next > snrt_l1_allocator_v2()->end)
asm volatile("ecall \n");
}

// Dynamically allocate space for a variable of size `size` in the cluster's L1
// memory. This function should be invoked by every core in a cluster. Every
// core receives a pointer to the allocated variable.
/**
* @brief Allocate space for a variable in the cluster's L1 memory.
*
* This function dynamically allocates space for a variable of size `size` in
* the cluster's L1 memory.
* The allocation is aligned to the specified `alignment`.
*
* @param size The size of the variable to allocate.
* @param alignment The alignment of the allocation.
* @return Pointer to the allocated variable.
*/
inline void *snrt_l1_alloc_cluster_local(size_t size, const size_t alignment) {
snrt_l1_allocator_v2()->next =
ALIGN_UP(snrt_l1_allocator_v2()->next, alignment);
Expand All @@ -34,11 +66,19 @@ inline void *snrt_l1_alloc_cluster_local(size_t size, const size_t alignment) {
return retval;
}

// Dynamically allocate space for N variables of size `size` in the cluster's
// L1 memory, N being the number of compute cores in the cluster. This function
// should be invoked by every core in a cluster. Every compute core receives a
// pointer to a unique variable among the N which have been allocated. The
// return value for the DM core is undefined.
/**
* @brief Allocate space for N variables in the cluster's L1 memory.
*
* This function dynamically allocates space for N variables of size `size` in
* the cluster's L1 memory, where N is the number of compute cores in the
* cluster. The variables are allocated in a contiguous block of memory.
* The whole block is aligned to the specified `alignment`.
*
* @param size The size of each variable to allocate.
* @param alignment The alignment of the allocation.
* @return Pointer to the allocated variable for each compute core.
* The return value for the DM core is undefined.
*/
inline void *snrt_l1_alloc_compute_core_local(size_t size,
const size_t alignment) {
snrt_l1_allocator_v2()->next =
Expand All @@ -49,24 +89,52 @@ inline void *snrt_l1_alloc_compute_core_local(size_t size,
return retval;
}

// Takes a pointer to a variable allocated using
// `snrt_l1_alloc_compute_core_local` and returns a pointer to the same
// variable allocated by another core, as specified by `core_idx`.
// The `size` argument should be the same used during allocation.
/**
* @brief Get a pointer to the same variable allocated by another core.
*
* This function takes a pointer to a variable allocated using
* `snrt_l1_alloc_compute_core_local` and returns a pointer to the same
* variable allocated by another core, as specified by `core_idx`.
* The `size` argument should be the same used during allocation.
*
* @param ptr Pointer to the variable allocated by the current core.
* @param core_idx Index of the core that allocated the variable.
* @param size The size of the variable.
* @return Pointer to the same variable allocated by the specified core.
*/
inline void *snrt_compute_core_local_ptr(void *ptr, uint32_t core_idx,
size_t size) {
size_t offset = (core_idx - snrt_cluster_core_idx()) * size;
return (void *)((uintptr_t)ptr + offset);
}

// Takes a pointer to a variable in the source cluster's L1 memory and returns
// a pointer to the same offset in the destination cluster's L1 memory.
/**
* @brief Get a pointer to the same offset in another cluster's L1 memory.
*
* This function takes a pointer to a variable in the calling (source)
* cluster's L1 memory and returns a pointer to the same offset in the target
* (destination) cluster's L1 memory.
*
* @param ptr Pointer to the variable in the source cluster's L1 memory.
* @param src_cluster_idx Index of the source cluster.
* @param dst_cluster_idx Index of the destination cluster.
* @return Pointer to the same offset in the destination cluster's L1 memory.
*/
inline void *snrt_remote_l1_ptr(void *ptr, uint32_t src_cluster_idx,
uint32_t dst_cluster_idx) {
return (void *)((uintptr_t)ptr +
(dst_cluster_idx - src_cluster_idx) * SNRT_CLUSTER_OFFSET);
}

/**
* @brief Initialize the L1 allocator.
*
* This function initializes the L1 allocator by calculating the end address
* of the heap and setting the base, end, and next pointers of the allocator.
*
* @note This function should be called before using any of the allocation
* functions.
*/
inline void snrt_alloc_init_v2() {
// Calculate end address of the heap. The top of the TCDM address space is
// reserved for the cluster-local storage (CLS) and the stack of every
Expand Down
Loading

0 comments on commit 3afc796

Please sign in to comment.