Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ add_library(${STLIB_LIBRARY} OBJECT
$<$<AND:$<BOOL:${CMAKE_CROSSCOMPILING}>,$<BOOL:${USE_ETHERNET}>>:${HALAL_C_ETH_PHY}>


$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CMAKE_CURRENT_LIST_DIR}/System.c>
$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CPP_UTILITIES_C}>
$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CPP_UTILITIES_CPP}>

Expand Down
164 changes: 102 additions & 62 deletions Inc/HALAL/Models/MPU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,41 +42,81 @@
#include "HALAL/Models/MPUManager/MPUManager.hpp"

// Defines for attributes
// Note1: Variables declared with these attributes will likely not be initialized by the startup
// Note2: These attributes can only be used for static/global variables
#define D1_NC __attribute__((section(".mpu_ram_d1_nc.user")))
#define D2_NC __attribute__((section(".mpu_ram_d2_nc.user")))
#define D3_NC __attribute__((section(".mpu_ram_d3_nc.user")))
#define D1_C __attribute__((section(".ram_d1.user")))
#define D2_C __attribute__((section(".ram_d2.user")))
#define D3_C __attribute__((section(".ram_d3.user")))

// Define for RAM code

// Initialized data in non-cached D1 RAM
#define D1_NC_DATA __attribute__((section(".ram_d1_nc.user.data")))
// Uninitialized data in non-cached D1 RAM
#define D1_NC_BSS __attribute__((section(".ram_d1_nc.user.bss")))
// Read-only data in non-cached D1 RAM (mainly for rx buffers) @note Not protected by MPU
#define D1_NC_RODATA __attribute__((section(".ram_d1_nc.user.rodata"))) const
// Initialized data in non-cached D2 RAM
#define D2_NC_DATA __attribute__((section(".ram_d2_nc.user.data")))
// Uninitialized data in non-cached D2 RAM
#define D2_NC_BSS __attribute__((section(".ram_d2_nc.user.bss")))
// Read-only data in non-cached D2 RAM (mainly for rx buffers) @note Not protected by MPU
#define D2_NC_RODATA __attribute__((section(".ram_d2_nc.user.rodata"))) const
// Initialized data in non-cached D3 RAM
#define D3_NC_DATA __attribute__((section(".ram_d3_nc.user.data")))
// Uninitialized data in non-cached D3 RAM
#define D3_NC_BSS __attribute__((section(".ram_d3_nc.user.bss")))
// Read-only data in non-cached D3 RAM (mainly for rx buffers) @note Not protected by MPU
#define D3_NC_RODATA __attribute__((section(".ram_d3_nc.user.rodata"))) const
// Initialized data in cached D1 RAM
#define D1_C_DATA __attribute__((section(".ram_d1.user.data")))
// Uninitialized data in cached D1 RAM
#define D1_C_BSS __attribute__((section(".ram_d1.user.bss")))
// Read-only data in cached D1 RAM (mainly for rx buffers) @note Not protected by MPU
#define D1_C_RODATA __attribute__((section(".ram_d1.user.rodata"))) const
// Initialized data in cached D2 RAM
#define D2_C_DATA __attribute__((section(".ram_d2.user.data")))
// Uninitialized data in cached D2 RAM
#define D2_C_BSS __attribute__((section(".ram_d2.user.bss")))
// Read-only data in cached D2 RAM (mainly for rx buffers) @note Not protected by MPU
#define D2_C_RODATA __attribute__((section(".ram_d2.user.rodata"))) const
// Initialized data in cached D3 RAM
#define D3_C_DATA __attribute__((section(".ram_d3.user.data")))
// Uninitialized data in cached D3 RAM
#define D3_C_BSS __attribute__((section(".ram_d3.user.bss")))
// Read-only data in cached D3 RAM (mainly for rx buffers) @note Not protected by MPU
#define D3_C_RODATA __attribute__((section(".ram_d3.user.rodata"))) const

// Functions living in ITCM for maximum performance (default is FLASH)
#define RAM_CODE __attribute__((section(".ram_code")))

// Constants in DTCM (default is FLASH because DTCM is small) @note Not protected by MPU
#define DTCM_RODATA __attribute__((section(".dtcm.rodata"))) const

// Retrocompatibility macros
#define D1_NC D1_NC_BSS
#define D2_NC D2_NC_BSS
#define D3_NC D3_NC_BSS
#define D1_C D1_C_BSS
#define D2_C D2_C_BSS
#define D3_C D3_C_BSS

// Memory Bank Symbols from Linker
extern "C" const char __itcm_base;
extern "C" const char __itcm_size;
extern "C" const char __dtcm_base;
extern "C" const char __dtcm_size;
extern "C" const char __flash_base;
extern "C" const char __flash_size;
extern "C" const char __ram_d1_base;
extern "C" const char __ram_d1_size;
extern "C" const char __ram_d2_base;
extern "C" const char __ram_d2_size;
extern "C" const char __ram_d3_base;
extern "C" const char __ram_d3_size;
extern "C" const char __peripheral_base;
extern "C" const char __peripheral_size;
extern "C" const char _itcm_base;
extern "C" const char _itcm_size;
extern "C" const char _dtcm_base;
extern "C" const char _dtcm_size;
extern "C" const char _flash_base;
extern "C" const char _flash_size;
extern "C" const char _ram_d1_base;
extern "C" const char _ram_d1_size;
extern "C" const char _ram_d2_base;
extern "C" const char _ram_d2_size;
extern "C" const char _ram_d3_base;
extern "C" const char _ram_d3_size;
extern "C" const char _peripheral_base;
extern "C" const char _peripheral_size;

// MPU Non-Cached Section Symbols from Linker
extern "C" const char __mpu_d1_nc_start;
extern "C" const char __mpu_d1_nc_end;
extern "C" const char __mpu_d2_nc_start;
extern "C" const char __mpu_d2_nc_end;
extern "C" const char __mpu_d3_nc_start;
extern "C" const char __mpu_d3_nc_end;
extern "C" const char _ram_d1_nc_start;
extern "C" const char _ram_d1_nc_end;
extern "C" const char _ram_d2_nc_start;
extern "C" const char _ram_d2_nc_end;
extern "C" const char _ram_d3_nc_start;
extern "C" const char _ram_d3_nc_end;

template <typename T>
concept mpu_buffer_request = requires(typename T::domain d) {
Expand Down Expand Up @@ -289,39 +329,39 @@ struct MPUDomain {
static constexpr auto Sizes = calculate_total_sizes(cfgs);

// Sections defined in Linker Script (aligned to 32 bytes just in case)
__attribute__((section(".mpu_ram_d1_nc.buffer"))) alignas(32
) static inline uint8_t d1_nc_buffer[Sizes.d1_nc_total > 0 ? Sizes.d1_nc_total : 1];
__attribute__((section(".ram_d1.buffer"))) alignas(32
) static inline uint8_t d1_c_buffer[Sizes.d1_c_total > 0 ? Sizes.d1_c_total : 1];
__attribute__((section(".ram_d1_nc.buffer"))) alignas(32)
static inline uint8_t d1_nc_buffer[Sizes.d1_nc_total > 0 ? Sizes.d1_nc_total : 1];
__attribute__((section(".ram_d1.buffer"))) alignas(32)
static inline uint8_t d1_c_buffer[Sizes.d1_c_total > 0 ? Sizes.d1_c_total : 1];

__attribute__((section(".mpu_ram_d2_nc.buffer"))) alignas(32
) static inline uint8_t d2_nc_buffer[Sizes.d2_nc_total > 0 ? Sizes.d2_nc_total : 1];
__attribute__((section(".ram_d2.buffer"))) alignas(32
) static inline uint8_t d2_c_buffer[Sizes.d2_c_total > 0 ? Sizes.d2_c_total : 1];
__attribute__((section(".ram_d2_nc.buffer"))) alignas(32)
static inline uint8_t d2_nc_buffer[Sizes.d2_nc_total > 0 ? Sizes.d2_nc_total : 1];
__attribute__((section(".ram_d2.buffer"))) alignas(32)
static inline uint8_t d2_c_buffer[Sizes.d2_c_total > 0 ? Sizes.d2_c_total : 1];

__attribute__((section(".mpu_ram_d3_nc.buffer"))) alignas(32
) static inline uint8_t d3_nc_buffer[Sizes.d3_nc_total > 0 ? Sizes.d3_nc_total : 1];
__attribute__((section(".ram_d3.buffer"))) alignas(32
) static inline uint8_t d3_c_buffer[Sizes.d3_c_total > 0 ? Sizes.d3_c_total : 1];
__attribute__((section(".ram_d3_nc.buffer"))) alignas(32)
static inline uint8_t d3_nc_buffer[Sizes.d3_nc_total > 0 ? Sizes.d3_nc_total : 1];
__attribute__((section(".ram_d3.buffer"))) alignas(32)
static inline uint8_t d3_c_buffer[Sizes.d3_c_total > 0 ? Sizes.d3_c_total : 1];

static void init() {
HAL_MPU_Disable();
configure_static_regions();

// Dynamic Configuration based on Linker Symbols
configure_dynamic_region(
reinterpret_cast<uintptr_t>(&__mpu_d1_nc_start),
reinterpret_cast<uintptr_t>(&__mpu_d1_nc_end),
reinterpret_cast<uintptr_t>(&_ram_d1_nc_start),
reinterpret_cast<uintptr_t>(&_ram_d1_nc_end),
MPU_REGION_NUMBER3
);
configure_dynamic_region(
reinterpret_cast<uintptr_t>(&__mpu_d2_nc_start),
reinterpret_cast<uintptr_t>(&__mpu_d2_nc_end),
reinterpret_cast<uintptr_t>(&_ram_d2_nc_start),
reinterpret_cast<uintptr_t>(&_ram_d2_nc_end),
MPU_REGION_NUMBER5
);
configure_dynamic_region(
reinterpret_cast<uintptr_t>(&__mpu_d3_nc_start),
reinterpret_cast<uintptr_t>(&__mpu_d3_nc_end),
reinterpret_cast<uintptr_t>(&_ram_d3_nc_start),
reinterpret_cast<uintptr_t>(&_ram_d3_nc_end),
MPU_REGION_NUMBER7
);

Expand Down Expand Up @@ -395,8 +435,8 @@ struct MPUDomain {
// Peripherals (Device, Buffered)
// Guarded against speculative execution and cache
configure_region(
reinterpret_cast<uintptr_t>(&__peripheral_base),
reinterpret_cast<size_t>(&__peripheral_size),
reinterpret_cast<uintptr_t>(&_peripheral_base),
reinterpret_cast<size_t>(&_peripheral_size),
MPU_REGION_NUMBER8,
MPU_TEX_LEVEL0,
MPU_REGION_FULL_ACCESS,
Expand All @@ -410,8 +450,8 @@ struct MPUDomain {
// TEX=0, C=1, B=0: Normal, Write-Through, No Read-Allocate (Read optimized)
// Not Shareable to allow full caching
configure_region(
reinterpret_cast<uintptr_t>(&__flash_base),
reinterpret_cast<size_t>(&__flash_size),
reinterpret_cast<uintptr_t>(&_flash_base),
reinterpret_cast<size_t>(&_flash_size),
MPU_REGION_NUMBER1,
MPU_TEX_LEVEL0,
MPU_REGION_FULL_ACCESS,
Expand All @@ -425,8 +465,8 @@ struct MPUDomain {
// TEX=1, C=1, B=1: Normal, Write-Back, Write and Read Allocate
// TCMs are like Cache, so they are not really cacheable, and the MPU settings are ignored
configure_region(
reinterpret_cast<uintptr_t>(&__dtcm_base),
reinterpret_cast<size_t>(&__dtcm_size),
reinterpret_cast<uintptr_t>(&_dtcm_base),
reinterpret_cast<size_t>(&_dtcm_size),
MPU_REGION_NUMBER10,
MPU_TEX_LEVEL1,
MPU_REGION_FULL_ACCESS,
Expand All @@ -440,8 +480,8 @@ struct MPUDomain {
// TEX=0, C=1, B=0: Normal, Write-Through, No Read-Allocate (Read optimized)
// TCMs are like Cache, so they are not really cacheable, and the MPU settings are ignored
configure_region(
reinterpret_cast<uintptr_t>(&__itcm_base),
reinterpret_cast<size_t>(&__itcm_size),
reinterpret_cast<uintptr_t>(&_itcm_base),
reinterpret_cast<size_t>(&_itcm_size),
MPU_REGION_NUMBER11,
MPU_TEX_LEVEL0,
MPU_REGION_FULL_ACCESS,
Expand All @@ -455,8 +495,8 @@ struct MPUDomain {
// TEX=1, C=1, B=1: Normal, Write-Back, Write-Allocate
// Shareable since it can be accessed by multiple masters (CPU, DMA, etc)
configure_region(
reinterpret_cast<uintptr_t>(&__ram_d1_base),
reinterpret_cast<size_t>(&__ram_d1_size),
reinterpret_cast<uintptr_t>(&_ram_d1_base),
reinterpret_cast<size_t>(&_ram_d1_size),
MPU_REGION_NUMBER2,
MPU_TEX_LEVEL1,
MPU_REGION_FULL_ACCESS,
Expand All @@ -470,8 +510,8 @@ struct MPUDomain {
// TEX=1, C=1, B=1: Normal, Write-Back, Write-Allocate
// Shareable since it can be accessed by multiple masters (CPU, DMA, etc)
configure_region(
reinterpret_cast<uintptr_t>(&__ram_d2_base),
reinterpret_cast<size_t>(&__ram_d2_size),
reinterpret_cast<uintptr_t>(&_ram_d2_base),
reinterpret_cast<size_t>(&_ram_d2_size),
MPU_REGION_NUMBER4,
MPU_TEX_LEVEL1,
MPU_REGION_FULL_ACCESS,
Expand All @@ -485,8 +525,8 @@ struct MPUDomain {
// TEX=1, C=1, B=1: Normal, Write-Back, Write-Allocate
// Shareable since it can be accessed by multiple masters (CPU, DMA, etc)
configure_region(
reinterpret_cast<uintptr_t>(&__ram_d3_base),
reinterpret_cast<size_t>(&__ram_d3_size),
reinterpret_cast<uintptr_t>(&_ram_d3_base),
reinterpret_cast<size_t>(&_ram_d3_size),
MPU_REGION_NUMBER6,
MPU_TEX_LEVEL1,
MPU_REGION_FULL_ACCESS,
Expand Down
17 changes: 16 additions & 1 deletion Inc/ST-LIB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ template <auto&... devs> struct Board {
}
}

template <auto& Target> static auto& instance_of() {
template <auto& Target> static constexpr auto& instance_of() {
using DevT = std::remove_cvref_t<decltype(Target)>;
using Domain = typename DevT::domain;

Expand All @@ -342,3 +342,18 @@ template <auto&... devs> struct Board {
};

} // namespace ST_LIB

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief This is a function that gets called early in the startup process,
* before the global constructors and main() are called.
* It is responsible for initializing the hardware and peripherals
*/
void BoardInit(void);

#ifdef __cplusplus
}
#endif
Loading
Loading