[PATCH 2/2] bsps/arm: Add support for small pages MMU
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon Oct 28 14:29:36 UTC 2019
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 | 55 ++++++++++++++---
.../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, 101 insertions(+), 30 deletions(-)
diff --git a/bsps/arm/include/bsp/arm-cp15-start.h b/bsps/arm/include/bsp/arm-cp15-start.h
index a749f7dc98..5e46d54e80 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,33 @@ arm_cp15_start_setup_translation_table(
size_t config_count
)
{
- uint32_t dac = ARM_CP15_DAC_DOMAIN(client_domain, ARM_CP15_DAC_CLIENT);
+ uint32_t dac;
+ uint32_t *pt;
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 00d8bba972..3bf5b4f161 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 fae6a6ba79..507277dca1 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 9d0679b59b..0718865a69 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
--
2.16.4
More information about the devel
mailing list