[PATCH 04/13] arm: Add support for Arm PMSAv8-32

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Dec 22 13:01:01 UTC 2020


Update #4202.
---
 .../score/cpu/arm/aarch32-psma-init-default.c |  60 ++++
 cpukit/score/cpu/arm/aarch32-psma-init.c      | 194 +++++++++++
 .../arm/include/rtems/score/aarch32-pmsa.h    | 314 ++++++++++++++++++
 spec/build/cpukit/cpuarm.yml                  |   2 +
 4 files changed, 570 insertions(+)
 create mode 100644 cpukit/score/cpu/arm/aarch32-psma-init-default.c
 create mode 100644 cpukit/score/cpu/arm/aarch32-psma-init.c
 create mode 100644 cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h

diff --git a/cpukit/score/cpu/arm/aarch32-psma-init-default.c b/cpukit/score/cpu/arm/aarch32-psma-init-default.c
new file mode 100644
index 0000000000..da710d77fc
--- /dev/null
+++ b/cpukit/score/cpu/arm/aarch32-psma-init-default.c
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUARMPMSAv8
+ *
+ * @brief This source file contains the implementation of
+ *   _AArch32_PMSA_Initialize_default().
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/aarch32-pmsa.h>
+
+#if __ARM_ARCH >= 8 && __ARM_ARCH_PROFILE == 'R'
+
+void _AArch32_PMSA_Initialize_default( void )
+{
+  _AArch32_PMSA_Initialize(
+    AARCH32_PMSA_MEM_ATTR(
+      AARCH32_PMSA_MEM_ATTR_DEFAULT_CACHED,
+      AARCH32_PMSA_MEM_ATTR_DEFAULT_UNCACHED,
+      AARCH32_PMSA_MEM_ATTR_DEFAULT_DEVICE,
+      0
+    ),
+    0,
+    _AArch32_PMSA_Sections,
+    _AArch32_PMSA_Section_count
+  );
+}
+
+#endif
diff --git a/cpukit/score/cpu/arm/aarch32-psma-init.c b/cpukit/score/cpu/arm/aarch32-psma-init.c
new file mode 100644
index 0000000000..de75d2a733
--- /dev/null
+++ b/cpukit/score/cpu/arm/aarch32-psma-init.c
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUARMPMSAv8
+ *
+ * @brief This source file contains the implementation of
+ *   _AArch32_PMSA_Initialize().
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/aarch32-pmsa.h>
+
+#if __ARM_ARCH >= 8 && __ARM_ARCH_PROFILE == 'R'
+
+#include <rtems/score/aarch32-system-registers.h>
+#include <rtems/score/cpu.h>
+
+#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,
+  size_t                     region_max
+)
+{
+  size_t   ri;
+  uint32_t sctlr;
+
+  for ( ri = 0 ; ri < region_used; ++ri ) {
+    uint32_t prbar;
+    uint32_t prlar;
+    uint32_t attr;
+
+    prbar = regions[ ri ].base;
+    prlar = regions[ ri ].limit;
+    attr = regions[ ri ].attributes;
+
+    prbar |= ( attr >> 6 ) & 0x3fU;
+    prlar |= attr & 0x3fU;
+
+    _AArch32_Write_prselr( ri );
+    _ARM_Instruction_synchronization_barrier();
+    _AArch32_Write_prbar( prbar );
+    _AArch32_Write_prlar( prlar );
+  }
+
+  for ( ri = region_used ; ri < region_max; ++ri ) {
+    _AArch32_Write_prselr( ri );
+    _ARM_Instruction_synchronization_barrier();
+    _AArch32_Write_prbar( 0 );
+    _AArch32_Write_prlar( 0 );
+  }
+
+  _ARM_Data_synchronization_barrier();
+  sctlr = _AArch32_Read_sctlr();
+  sctlr |= AARCH32_SCTLR_M | AARCH32_SCTLR_I | AARCH32_SCTLR_C;
+  sctlr &= ~AARCH32_SCTLR_BR;
+  _AArch32_Write_sctlr( sctlr );
+  _ARM_Instruction_synchronization_barrier();
+}
+
+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 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 ) {
+    uint32_t base;
+    uint32_t limit;
+    uint32_t attr;
+
+    base = sections[ si ].begin;
+    limit = sections[ si ].end;
+    attr = sections[ si ].attributes;
+
+    if ( base == limit ) {
+      continue;
+    }
+
+    base = RTEMS_ALIGN_DOWN( base, AARCH32_PMSA_MIN_REGION_ALIGN );
+    limit = RTEMS_ALIGN_DOWN( limit - 1, AARCH32_PMSA_MIN_REGION_ALIGN );
+
+    for ( ri = 0; ri < region_used; ++ri ) {
+      uint32_t region_base;
+      uint32_t region_limit;
+      uint32_t region_attr;
+
+      region_base = regions[ ri ].base;
+      region_limit = regions[ ri ].limit;
+      region_attr = regions[ ri ].attributes;
+
+      if (
+        limit + AARCH32_PMSA_MIN_REGION_ALIGN == region_base &&
+          attr == region_attr
+      ) {
+        /* Merge section with existing region */
+        regions[ ri ].base = base;
+        break;
+      } else if (
+        base == region_limit + AARCH32_PMSA_MIN_REGION_ALIGN &&
+          attr == region_attr
+      ) {
+        /* Merge section with existing region */
+        regions[ ri ].limit = limit;
+        break;
+      } else if ( limit < region_base ) {
+        size_t i;
+
+        if ( region_used >= region_max ) {
+          return;
+        }
+
+        for ( i = ri; i < region_used; ++i ) {
+          regions[ i + 1 ] = regions[ i ];
+        }
+
+        /* New first region */
+        ++region_used;
+        regions[ ri ].base = base;
+        regions[ ri ].limit = limit;
+        regions[ ri ].attributes = attr;
+        break;
+      }
+    }
+
+    if ( ri == region_used ) {
+      if ( region_used >= region_max ) {
+        return;
+      }
+
+      /* New last region */
+      regions[ ri ].base = base;
+      regions[ ri ].limit = limit;
+      regions[ ri ].attributes = attr;
+      ++region_used;
+    }
+  }
+
+  _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
new file mode 100644
index 0000000000..ea25828bb6
--- /dev/null
+++ b/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUARMPMSAv8
+ *
+ * @brief This header file provides the API to manage an Arm PMSAv8-32 based
+ *   Memory Protection Unit (MPU).
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_AARCH32_PMSA_H
+#define _RTEMS_SCORE_AARCH32_PMSA_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup RTEMSScoreCPUARMPMSAv8 PMSAv8-32 Support
+ *
+ * @ingroup RTEMSScoreCPUARM
+ *
+ * @brief This group provides support functions to manage an Arm PMSAv8-32
+ *   (Protected Memory System Architecture) based Memory Protection Unit (MPU).
+ *
+ * @{
+ */
+
+#define AARCH32_PMSA_MIN_REGION_ALIGN 64
+
+#define AARCH32_PMSA_ATTR_EN 0x1U
+
+#define AARCH32_PMSA_ATTR_IDX_SHIFT 1
+#define AARCH32_PMSA_ATTR_IDX_MASK 0xeU
+#define AARCH32_PMSA_ATTR_IDX( _idx ) \
+  ( ( _idx ) << AARCH32_PMSA_ATTR_IDX_SHIFT )
+
+#define AARCH32_PMSA_ATTR_XN 0x6U
+
+#define AARCH32_PMSA_ATTR_AP_SHIFT 7
+#define AARCH32_PMSA_ATTR_AP_MASK 0x18U
+#define AARCH32_PMSA_ATTR_AP( _ap ) \
+  ( ( _ap ) << AARCH32_PMSA_ATTR_AP_SHIFT )
+#define AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO 0x0U
+#define AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_RW 0x1U
+#define AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO 0x2U
+#define AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_RO 0x3U
+
+#define AARCH32_PMSA_ATTR_SH_SHIFT 9
+#define AARCH32_PMSA_ATTR_SH_MASK 0x600U
+#define AARCH32_PMSA_ATTR_SH( _sh ) \
+  ( ( _sh ) << AARCH32_PMSA_ATTR_SH_SHIFT )
+#define AARCH32_PMSA_ATTR_SH_NO 0x0U
+#define AARCH32_PMSA_ATTR_SH_RES 0x1U
+#define AARCH32_PMSA_ATTR_SH_OUTER 0x2U
+#define AARCH32_PMSA_ATTR_SH_INNER 0x3U
+
+#define AARCH32_PMSA_MEM_DEVICE_NG_NR_NE 0x00U
+#define AARCH32_PMSA_MEM_DEVICE_NG_NR_E  0x04U
+#define AARCH32_PMSA_MEM_DEVICE_NG_R_E   0x08U
+#define AARCH32_PMSA_MEM_DEVICE_G_R_E    0x0cU
+
+#define AARCH32_PMSA_MEM_OUTER_WTT  0x00U
+#define AARCH32_PMSA_MEM_OUTER_NC   0x40U
+#define AARCH32_PMSA_MEM_OUTER_WBT  0x40U
+#define AARCH32_PMSA_MEM_OUTER_WTNT 0x80U
+#define AARCH32_PMSA_MEM_OUTER_WBNT 0xc0U
+
+#define AARCH32_PMSA_MEM_OUTER_RA 0x20U
+#define AARCH32_PMSA_MEM_OUTER_WA 0x10U
+
+#define AARCH32_PMSA_MEM_INNER_WTT  0x00U
+#define AARCH32_PMSA_MEM_INNER_NC   0x40U
+#define AARCH32_PMSA_MEM_INNER_WBT  0x40U
+#define AARCH32_PMSA_MEM_INNER_WTNT 0x80U
+#define AARCH32_PMSA_MEM_INNER_WBNT 0xc0U
+
+#define AARCH32_PMSA_MEM_INNER_RA 0x02U
+#define AARCH32_PMSA_MEM_INNER_WA 0x01U
+
+#define AARCH32_PMSA_MEM_ATTR( _ma0, _ma1, _ma2, _ma3 ) \
+  ( ( _ma0 ) | ( ( _ma1 ) << 8 ) | ( ( _ma1 ) << 16 ) | ( ( _ma1 ) << 24 ) )
+
+#define AARCH32_PMSA_MEM_ATTR_DEFAULT_CACHED \
+  ( AARCH32_PMSA_MEM_OUTER_WBNT | \
+    AARCH32_PMSA_MEM_OUTER_RA | \
+    AARCH32_PMSA_MEM_OUTER_WA | \
+    AARCH32_PMSA_MEM_INNER_WBNT | \
+    AARCH32_PMSA_MEM_INNER_RA | \
+    AARCH32_PMSA_MEM_INNER_WA )
+
+#define AARCH32_PMSA_MEM_ATTR_DEFAULT_UNCACHED \
+  ( AARCH32_PMSA_MEM_OUTER_NC | \
+    AARCH32_PMSA_MEM_INNER_NC )
+
+#define AARCH32_PMSA_MEM_ATTR_DEFAULT_DEVICE \
+  AARCH32_PMSA_MEM_DEVICE_NG_NR_NE
+
+#define AARCH32_PMSA_CODE_CACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
+    AARCH32_PMSA_ATTR_IDX( 0U ) )
+
+#define AARCH32_PMSA_CODE_UNCACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
+    AARCH32_PMSA_ATTR_IDX( 1U ) )
+
+#define AARCH32_PMSA_DATA_READ_ONLY_CACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_XN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) |  \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_OUTER ) | \
+    AARCH32_PMSA_ATTR_IDX( 0U ) )
+
+#define AARCH32_PMSA_DATA_READ_ONLY_UNCACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_XN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
+    AARCH32_PMSA_ATTR_IDX( 1U ) )
+
+#define AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_XN | \
+    AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_OUTER ) | \
+    AARCH32_PMSA_ATTR_IDX( 0U ) )
+
+#define AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_XN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO ) | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
+    AARCH32_PMSA_ATTR_IDX( 1U ) )
+
+#define AARCH32_PMSA_DEVICE \
+  ( AARCH32_PMSA_ATTR_EN | \
+    AARCH32_PMSA_ATTR_XN | \
+    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO ) | \
+    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
+    AARCH32_PMSA_ATTR_IDX( 2U ) )
+
+/**
+ * @brief The default section definitions shall be used by the BSP to define
+ *   ::_AArch32_PMSA_Sections.
+ *
+ * In addition to the default section definitions, the BSP should provide
+ * section definitions for the memory-mapped devices and other memory areas.
+ */
+#define AARCH32_PMSA_DEFAULT_SECTIONS \
+  { \
+    .begin = (uint32_t) bsp_section_fast_text_begin, \
+    .end = (uint32_t) bsp_section_fast_text_end, \
+    .attributes = AARCH32_PMSA_CODE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_fast_data_begin, \
+    .end = (uint32_t) bsp_section_fast_data_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_start_begin, \
+    .end = (uint32_t) bsp_section_start_end, \
+    .attributes = AARCH32_PMSA_CODE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_vector_begin, \
+    .end = (uint32_t) bsp_section_vector_end, \
+    .attributes = AARCH32_PMSA_CODE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_text_begin, \
+    .end = (uint32_t) bsp_section_text_end, \
+    .attributes = AARCH32_PMSA_CODE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_rodata_begin, \
+    .end = (uint32_t) bsp_section_rodata_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_ONLY_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_data_begin, \
+    .end = (uint32_t) bsp_section_data_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_bss_begin, \
+    .end = (uint32_t) bsp_section_bss_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_rtemsstack_begin, \
+    .end = (uint32_t) bsp_section_rtemsstack_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_work_begin, \
+    .end = (uint32_t) bsp_section_work_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_stack_begin, \
+    .end = (uint32_t) bsp_section_stack_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_nocache_begin, \
+    .end = (uint32_t) bsp_section_nocache_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
+  }, { \
+    .begin = (uint32_t) bsp_section_nocachenoload_begin, \
+    .end = (uint32_t) bsp_section_nocachenoload_end, \
+    .attributes = AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
+  }
+
+/**
+ * @brief The section definition is used to initialize the Memory Protection
+ *   Unit (MPU).
+ *
+ * A section is empty if the begin address is equal to the end address.
+ */
+typedef struct {
+  /**
+   * @brief This member defines the begin address of the section.
+   */
+  uint32_t begin;
+
+  /**
+   * @brief This member defines the end address of the section.
+   */
+  uint32_t end;
+
+  /**
+   * @brief This member defines the attributes of the section.
+   */
+  uint32_t attributes;
+} AArch32_PMSA_Section;
+
+/**
+ * @brief Initializes the Memory Protection Unit (MPU).
+ *
+ * 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 the MPU is not enabled.  Overlapping section
+ * definitions result in undefined system behaviour.
+ *
+ * @param memory_attributes_0 are the memory attributes for MAIR0.
+ *
+ * @param memory_attributes_1 are the memory attributes for MAIR1.
+ *
+ * @param sections is the array with section definitions.
+ *
+ * @param section_count is the count of section definitions.
+ */
+void _AArch32_PMSA_Initialize(
+  uint32_t                    memory_attributes_0,
+  uint32_t                    memory_attributes_1,
+  const AArch32_PMSA_Section *sections,
+  size_t                      section_count
+);
+
+/**
+ * @brief This array provides section definitions to initialize the memory
+ *   protection unit (MPU).
+ *
+ * The BSP shall provide the section definitions with the help of
+ * ::AARCH32_PMSA_DEFAULT_SECTIONS.  The section count is provided by
+ * ::_AArch32_PMSA_Section_count.
+ */
+extern const AArch32_PMSA_Section _AArch32_PMSA_Sections[];
+
+/**
+ * @brief This constant provides the count of elements in
+ * ::_AArch32_PMSA_Sections.
+ */
+extern const size_t _AArch32_PMSA_Section_count;
+
+/**
+ * @brief Initializes the Memory Protection Unit (MPU) using the section
+ *   definitions with default memory attributes.
+ *
+ * Calls _AArch32_PMSA_Initialize() using ::_AArch32_PMSA_Sections and
+ * ::_AArch32_PMSA_Section_count and the default memory attributes.
+ */
+void _AArch32_PMSA_Initialize_default( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_AARCH32_PMSA_H */
diff --git a/spec/build/cpukit/cpuarm.yml b/spec/build/cpukit/cpuarm.yml
index 6bbbb08c36..0861fb1118 100644
--- a/spec/build/cpukit/cpuarm.yml
+++ b/spec/build/cpukit/cpuarm.yml
@@ -30,6 +30,8 @@ install:
   - cpukit/score/cpu/arm/include/rtems/score/paravirt.h
 links: []
 source:
+- cpukit/score/cpu/arm/aarch32-psma-init.c
+- cpukit/score/cpu/arm/aarch32-psma-init-default.c
 - cpukit/score/cpu/arm/__aeabi_read_tp.c
 - cpukit/score/cpu/arm/arm-context-validate.S
 - cpukit/score/cpu/arm/arm-context-volatile-clobber.S
-- 
2.26.2



More information about the devel mailing list