diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-01-17 13:32:39 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-03-11 09:24:57 +0100 |
commit | ca74566f7e28c1835393b3e1bc86a305a8976cc7 (patch) | |
tree | aca3ba51a0727995ababd920ca0b66c41a335994 /cpukit | |
parent | bsp/fvp: Use only vector table of start section (diff) | |
download | rtems-ca74566f7e28c1835393b3e1bc86a305a8976cc7.tar.bz2 |
arm: Add _AArch32_PMSA_Map_sections_to_regions()
This simplifies unit testing.
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/score/cpu/arm/aarch32-psma-init.c | 56 | ||||
-rw-r--r-- | cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h | 54 |
2 files changed, 90 insertions, 20 deletions
diff --git a/cpukit/score/cpu/arm/aarch32-psma-init.c b/cpukit/score/cpu/arm/aarch32-psma-init.c index f5792e9c24..350252a008 100644 --- a/cpukit/score/cpu/arm/aarch32-psma-init.c +++ b/cpukit/score/cpu/arm/aarch32-psma-init.c @@ -48,12 +48,6 @@ #define AARCH32_PSMA_REGION_MAX \ ( ( AARCH32_MPUIR_REGION_MASK >> AARCH32_MPUIR_REGION_SHIFT ) + 1 ) -typedef struct { - uint32_t base; - uint32_t limit; - uint32_t attributes; -} AArch32_PMSA_Region; - static void _AArch32_PMSA_Configure( const AArch32_PMSA_Region *regions, size_t region_used, @@ -96,24 +90,17 @@ static void _AArch32_PMSA_Configure( _ARM_Instruction_synchronization_barrier(); } -void _AArch32_PMSA_Initialize( - uint32_t memory_attributes_0, - uint32_t memory_attributes_1, +size_t _AArch32_PMSA_Map_sections_to_regions( const AArch32_PMSA_Section *sections, - size_t section_count + size_t section_count, + AArch32_PMSA_Region *regions, + size_t region_max ) { - AArch32_PMSA_Region regions[ AARCH32_PSMA_REGION_MAX ]; size_t ri; size_t si; size_t region_used; - size_t region_max; - _AArch32_Write_mair0( memory_attributes_0 ); - _AArch32_Write_mair1( memory_attributes_1 ); - - region_max = ( _AArch32_Read_mpuir() & AARCH32_MPUIR_REGION_MASK ) >> - AARCH32_MPUIR_REGION_SHIFT; region_used = 0; for ( si = 0; si < section_count; ++si ) { @@ -159,7 +146,7 @@ void _AArch32_PMSA_Initialize( size_t i; if ( region_used >= region_max ) { - return; + return 0; } for ( i = ri; i < region_used; ++i ) { @@ -177,7 +164,7 @@ void _AArch32_PMSA_Initialize( if ( ri == region_used ) { if ( region_used >= region_max ) { - return; + return 0; } /* New last region */ @@ -188,7 +175,36 @@ void _AArch32_PMSA_Initialize( } } - _AArch32_PMSA_Configure( regions, region_used, region_max ); + return region_used; +} + +void _AArch32_PMSA_Initialize( + uint32_t memory_attributes_0, + uint32_t memory_attributes_1, + const AArch32_PMSA_Section *sections, + size_t section_count +) +{ + AArch32_PMSA_Region regions[ AARCH32_PSMA_REGION_MAX ]; + size_t region_max; + size_t region_used; + + _AArch32_Write_mair0( memory_attributes_0 ); + _AArch32_Write_mair1( memory_attributes_1 ); + + region_max = ( _AArch32_Read_mpuir() & AARCH32_MPUIR_REGION_MASK ) >> + AARCH32_MPUIR_REGION_SHIFT; + + region_used = _AArch32_PMSA_Map_sections_to_regions( + sections, + section_count, + regions, + region_max + ); + + if ( region_used > 0 ) { + _AArch32_PMSA_Configure( regions, region_used, region_max ); + } } #endif diff --git a/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h b/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h index 47b034813c..d7244138ca 100644 --- a/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h +++ b/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h @@ -278,6 +278,33 @@ typedef struct { } AArch32_PMSA_Section; /** + * @brief The region definition is used to configure the Memory Protection + * Unit (MPU). + * + * A region cannot be empty. + */ +typedef struct { + /** + * @brief This member defines the base address of the region. + * + * The limit address is this the address of the first byte of the region. + */ + uint32_t base; + + /** + * @brief This member defines the limit address of the region. + * + * The limit address is this the address of the last byte of the region. + */ + uint32_t limit; + + /** + * @brief This member defines the attributes of the region. + */ + uint32_t attributes; +} AArch32_PMSA_Region; + +/** * @brief Initializes the Memory Protection Unit (MPU). * * The section definitions are used to define the regions of the MPU. Sections @@ -285,6 +312,8 @@ typedef struct { * regions are used, then the MPU is not enabled. Overlapping section * definitions result in undefined system behaviour. * + * The function shall be called while the MPU is disabled. + * * @param memory_attributes_0 are the memory attributes for MAIR0. * * @param memory_attributes_1 are the memory attributes for MAIR1. @@ -301,6 +330,31 @@ void _AArch32_PMSA_Initialize( ); /** + * @brief Maps the section definitions to region definitions. + * + * The section definitions are used to define the regions of the MPU. Sections + * are merged if possible to reduce the count of used regions. If too many + * regions are used, then zero is returned. Overlapping section definitions + * result in undefined system behaviour. + * + * @param sections is the array with section definitions to map to regions. + * + * @param section_count is the count of section definitions. + * + * @param regions is the array with usable region definitions. + * + * @param region_max is the count of usable region definitions. + * + * @return Returns the count of actually used regions. + */ +size_t _AArch32_PMSA_Map_sections_to_regions( + const AArch32_PMSA_Section *sections, + size_t section_count, + AArch32_PMSA_Region *regions, + size_t region_max +); + +/** * @brief This array provides section definitions to initialize the memory * protection unit (MPU). * |