[rtems commit] bsps/arm: Add support for small pages MMU

Sebastian Huber sebh at rtems.org
Thu Oct 31 11:04:17 UTC 2019


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Oct 28 10:15:28 2019 +0100

bsps/arm: Add support for small pages MMU

The small page MMU support reduces the granularity for memory settings
through the MMU from 1MiB sections to 4KiB small pages.

Enable it by default on the realview_pbx_a9_qemu BSP.

---

 bsps/arm/include/bsp/arm-cp15-start.h              | 57 +++++++++++++++---
 .../start/linkcmds.realview_pbx_a9_qemu            |  4 +-
 bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c    | 70 ++++++++++++++++------
 c/src/lib/libbsp/arm/realview-pbx-a9/configure.ac  |  2 +
 4 files changed, 103 insertions(+), 30 deletions(-)

diff --git a/bsps/arm/include/bsp/arm-cp15-start.h b/bsps/arm/include/bsp/arm-cp15-start.h
index a749f7d..220423f 100644
--- a/bsps/arm/include/bsp/arm-cp15-start.h
+++ b/bsps/arm/include/bsp/arm-cp15-start.h
@@ -9,7 +9,7 @@
 
 /*
  * Copyright (c) 2013 Hesham AL-Matary.
- * Copyright (c) 2009-2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2009-2019 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -28,6 +28,7 @@
 #include <libcpu/arm-cp15.h>
 #include <bsp/start.h>
 #include <bsp/linker-symbols.h>
+#include <bspopts.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -106,16 +107,35 @@ arm_cp15_start_set_translation_table_entries(
   const arm_cp15_start_section_config *config
 )
 {
-  uint32_t i = ARM_MMU_SECT_GET_INDEX(config->begin);
-  uint32_t iend =
-    ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
-  uint32_t index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
-
   if (config->begin != config->end) {
+    uint32_t i;
+    uint32_t iend;
+    uint32_t index_mask;
+    uint32_t flags;
+#ifdef ARM_MMU_USE_SMALL_PAGES
+    uint32_t *pt;
+
+    pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
+    i = ARM_MMU_SMALL_PAGE_GET_INDEX(config->begin);
+    iend = ARM_MMU_SMALL_PAGE_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
+    index_mask = (1U << (32 - ARM_MMU_SMALL_PAGE_BASE_SHIFT)) - 1U;
+    flags = ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(config->flags);
+
+    while (i != iend) {
+      pt[i] = (i << ARM_MMU_SMALL_PAGE_BASE_SHIFT) | flags;
+      i = (i + 1U) & index_mask;
+    }
+#else
+    i = ARM_MMU_SECT_GET_INDEX(config->begin);
+    iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
+    index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
+    flags = config->flags;
+
     while (i != iend) {
-      ttb [i] = (i << ARM_MMU_SECT_BASE_SHIFT) | config->flags;
+      ttb[i] = (i << ARM_MMU_SECT_BASE_SHIFT) | flags;
       i = (i + 1U) & index_mask;
     }
+#endif
   }
 }
 
@@ -127,16 +147,35 @@ arm_cp15_start_setup_translation_table(
   size_t config_count
 )
 {
-  uint32_t dac = ARM_CP15_DAC_DOMAIN(client_domain, ARM_CP15_DAC_CLIENT);
+#ifdef ARM_MMU_USE_SMALL_PAGES
+  uint32_t *pt;
+#endif
+  uint32_t dac;
   size_t i;
 
+  dac = ARM_CP15_DAC_DOMAIN(client_domain, ARM_CP15_DAC_CLIENT);
   arm_cp15_set_domain_access_control(dac);
   arm_cp15_set_translation_table_base(ttb);
 
   /* Initialize translation table with invalid entries */
+#ifdef ARM_MMU_USE_SMALL_PAGES
+  pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
+  for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
+    size_t j;
+
+    for (j = 0; j < ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT; ++j) {
+      pt[j] = 0;
+    }
+
+    ttb[i] = (uint32_t) pt | (client_domain << ARM_MMU_SECT_DOMAIN_SHIFT)
+      | ARM_MMU_PAGE_TABLE_DEFAULT;
+    pt += ARM_MMU_SMALL_PAGE_TABLE_ENTRY_COUNT;
+  }
+#else
   for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
-    ttb [i] = 0;
+    ttb[i] = 0;
   }
+#endif
 
   for (i = 0; i < config_count; ++i) {
     arm_cp15_start_set_translation_table_entries(ttb, &config_table [i]);
diff --git a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
index 00d8bba..3bf5b4f 100644
--- a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
+++ b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
@@ -1,7 +1,7 @@
 MEMORY {
 	/* Waste the first 1MiB for NULL pointer protection */
-	RAM : ORIGIN = 0x00100000, LENGTH = 255M - 16k
-	RAM_MMU : ORIGIN = 0x0fffc000, LENGTH = 16k
+	RAM : ORIGIN = 0x00100000, LENGTH = 0x0fafc000
+	RAM_MMU : ORIGIN = 0x0fbfc000, LENGTH = 0x404000
 }
 
 REGION_ALIAS ("REGION_START", RAM);
diff --git a/bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c b/bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c
index fae6a6b..507277d 100644
--- a/bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c
+++ b/bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2010-2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2010-2019 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
- *  Obere Lagerstr. 30
+ *  Dornierstr. 4
  *  82178 Puchheim
  *  Germany
  *  <rtems at embedded-brains.de>
@@ -14,6 +14,7 @@
 
 #include <rtems.h>
 #include <libcpu/arm-cp15.h>
+#include <bspopts.h>
 
 /*
  * Translation table modification requires to propagate
@@ -35,36 +36,67 @@ static uint32_t set_translation_table_entries(
   uint32_t section_flags
 )
 {
-  uint32_t *ttb = arm_cp15_get_translation_table_base();
-  uint32_t istart = ARM_MMU_SECT_GET_INDEX(begin);
-  uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
-  uint32_t index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
-  uint32_t ctrl;
+  uint32_t *ttb;
+#ifdef ARM_MMU_USE_SMALL_PAGES
+  uint32_t *pt;
+  uint32_t flags;
+#endif
+  uint32_t istart;
+  uint32_t iend;
+  uint32_t index_mask;
   uint32_t section_flags_of_first_entry;
   uint32_t i;
-  void *first_ttb_addr;
-  void *last_ttb_end;
+  uint32_t *modified_begin;
+  size_t modified_size;
 
-  ctrl = arm_cp15_get_control();
-  section_flags_of_first_entry = ttb [istart];
-  last_ttb_end = first_ttb_addr = ttb + istart;
+  ttb = arm_cp15_get_translation_table_base();
+#ifdef ARM_MMU_USE_SMALL_PAGES
+  pt = &ttb[ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT];
+  istart = ARM_MMU_SMALL_PAGE_GET_INDEX(begin);
+  iend = ARM_MMU_SMALL_PAGE_GET_INDEX(ARM_MMU_SMALL_PAGE_MVA_ALIGN_UP(end));
+  index_mask = (1U << (32 - ARM_MMU_SMALL_PAGE_BASE_SHIFT)) - 1U;
+  section_flags_of_first_entry = ARM_MMU_SMALL_PAGE_FLAGS_TO_SECT(pt[istart])
+    | ARM_MMU_PAGE_TABLE_FLAGS_TO_SECT(ttb[ARM_MMU_SECT_GET_INDEX(begin)]);
+  modified_begin = &pt[istart];
+  flags = ARM_MMU_SECT_FLAGS_TO_SMALL_PAGE(section_flags);
+#else
+  istart = ARM_MMU_SECT_GET_INDEX(begin);
+  iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
+  index_mask = (1U << (32 - ARM_MMU_SECT_BASE_SHIFT)) - 1U;
+  section_flags_of_first_entry = ttb[istart];
+  modified_begin = &ttb[istart];
+#endif
+  modified_size = 0;
 
   for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
-    uint32_t addr = i << ARM_MMU_SECT_BASE_SHIFT;
+    uint32_t pa;
 
-    ttb [i] = addr | section_flags;
-    last_ttb_end = ttb + i + 1;
+#ifdef ARM_MMU_USE_SMALL_PAGES
+    pa = i << ARM_MMU_SMALL_PAGE_BASE_SHIFT;
+    pt[i] = pa | flags;
+    modified_size += ARM_MMU_SMALL_PAGE_TABLE_ENTRY_SIZE;
+#else
+    pa = i << ARM_MMU_SECT_BASE_SHIFT;
+    ttb[i] = pa | section_flags;
+    modified_size += ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE;
+#endif
   }
 
-  if ( ctrl & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M ) ) {
-    rtems_cache_flush_multiple_data_lines(first_ttb_addr,
-                last_ttb_end - first_ttb_addr);
+  if ((arm_cp15_get_control() & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M)) != 0) {
+    rtems_cache_flush_multiple_data_lines(modified_begin, modified_size);
   }
 
   _ARM_Data_synchronization_barrier();
 
   for ( i = istart; i != iend; i = (i + 1U) & index_mask ) {
-    void *mva = (void *) (i << ARM_MMU_SECT_BASE_SHIFT);
+    void *mva;
+
+#ifdef ARM_MMU_USE_SMALL_PAGES
+    mva = (void *) (i << ARM_MMU_SMALL_PAGE_BASE_SHIFT);
+#else
+    mva = (void *) (i << ARM_MMU_SECT_BASE_SHIFT);
+#endif
+
 #if defined(__ARM_ARCH_7A__)
     /*
      * Bit 31 needs to be 1 to indicate the register implements the
diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/configure.ac b/c/src/lib/libbsp/arm/realview-pbx-a9/configure.ac
index 9d0679b..0718865 100644
--- a/c/src/lib/libbsp/arm/realview-pbx-a9/configure.ac
+++ b/c/src/lib/libbsp/arm/realview-pbx-a9/configure.ac
@@ -43,6 +43,8 @@ RTEMS_BSPOPTS_HELP([CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR],
 [If defined, then do the clock tick processing on the boot processor on behalf
 of all other processors.])
 
+RTEMS_BSPOPTS_SET([ARM_MMU_USE_SMALL_PAGES],[*],[1])
+RTEMS_BSPOPTS_HELP([ARM_MMU_USE_SMALL_PAGES],[use MMU with small pages (4KiB)])
 
 RTEMS_BSP_CLEANUP_OPTIONS
 



More information about the vc mailing list