[rtems commit] arm: Add _AArch32_PMSA_Map_sections_to_regions()

Sebastian Huber sebh at rtems.org
Fri Mar 11 08:15:19 UTC 2022


Module:    rtems
Branch:    master
Commit:    ca74566f7e28c1835393b3e1bc86a305a8976cc7
Changeset: http://git.rtems.org/rtems/commit/?id=ca74566f7e28c1835393b3e1bc86a305a8976cc7

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jan 17 13:32:39 2022 +0100

arm: Add _AArch32_PMSA_Map_sections_to_regions()

This simplifies unit testing.

---

 cpukit/score/cpu/arm/aarch32-psma-init.c           | 56 ++++++++++++++--------
 .../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 f5792e9..350252a 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 47b0348..d724413 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).
  *



More information about the vc mailing list