[PATCH 3/5] Shared libmm implemenation for ARM BSPs
Hesham AL-Matary
heshamelmatary at gmail.com
Mon Aug 26 00:14:53 UTC 2013
---
c/src/lib/libcpu/arm/shared/include/arm-cp15.h | 17 ++++
.../libcpu/arm/shared/include/arm_cp15_print_fsr.h | 84 ++++++++++++++++
c/src/lib/libcpu/arm/shared/src/armv7-mm-mpu.c | 108 +++++++++++++++++++++
c/src/lib/libcpu/arm/shared/src/mm.c | 83 ++++++++++++++++
5 files changed, 306 insertions(+), 1 deletion(-)
create mode 100644 c/src/lib/libcpu/arm/shared/include/arm_cp15_print_fsr.h
create mode 100644 c/src/lib/libcpu/arm/shared/src/armv7-mm-mpu.c
create mode 100644 c/src/lib/libcpu/arm/shared/src/mm.c
diff --git a/c/src/lib/libcpu/arm/shared/include/arm-cp15.h b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h
index 0117a5e..20eccbb 100644
--- a/c/src/lib/libcpu/arm/shared/include/arm-cp15.h
+++ b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h
@@ -7,6 +7,7 @@
*/
/*
+ * Copyright (c) 2013 Hesham AL-Matary
* Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
@@ -139,6 +140,7 @@ extern "C" {
#define ARM_CP15_CTRL_NMFI (1U << 27)
#define ARM_CP15_CTRL_EE (1U << 25)
#define ARM_CP15_CTRL_VE (1U << 24)
+#define ARM_CP15_CTRL_XP (1U << 23) // ARMv6
#define ARM_CP15_CTRL_U (1U << 22)
#define ARM_CP15_CTRL_FI (1U << 21)
#define ARM_CP15_CTRL_UWXN (1U << 20)
@@ -250,6 +252,7 @@ static inline void arm_cp15_set_control(uint32_t val)
*
* @return The current control register value.
*/
+
static inline uint32_t arm_cp15_mmu_disable(uint32_t cls)
{
ARM_SWITCH_REGISTERS;
@@ -1022,11 +1025,25 @@ uint32_t arm_cp15_set_translation_table_entries(
uint32_t section_flags
);
+/**
+ * @brief Unsets the @a sections entry for the address range [@a begin, @a end).
+ * Unset section entry by set its value to Zero
+ */
+uint32_t arm_cp15_unset_translation_table_entries(
+ const void *begin,
+ const void *end
+);
+
void arm_cp15_set_exception_handler(
Arm_symbolic_exception_name exception,
void (*handler)(void)
);
+/**
+ * @brief dummy exception handler for data aborts to help in debugging
+ */
+void dummy_data_abort_exception_handler(void);
+
/** @} */
#ifdef __cplusplus
diff --git a/c/src/lib/libcpu/arm/shared/include/arm_cp15_print_fsr.h b/c/src/lib/libcpu/arm/shared/include/arm_cp15_print_fsr.h
new file mode 100644
index 0000000..5755a31
--- /dev/null
+++ b/c/src/lib/libcpu/arm/shared/include/arm_cp15_print_fsr.h
@@ -0,0 +1,84 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreCPUARMCP15
+ *
+ * @brief ARM co-processor 15 (CP15) API.
+ */
+
+/*
+ * Copyright (c) 2013 Hesham AL-Matary
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LICPU_SHARED_ARM_CP15_DATA_FAULT_INFO
+#define LICPU_SHARED_ARM_CP15_DATA_FAULT_INFO
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Define mask for ARM CP15 fault status register */
+#define ARM_CP15_FAULT_STATUS_MASK 0x040F
+
+/* Error States for ARM CP15 fault status register */
+#define ARM_CP15_ALIGNMENT_FAULT 0x00000001
+#define ARM_CP15_BACKGROUND_FAULT 0x0000
+#define ARM_CP15_ACCESS_PERMISSION_FAULT 0x000D
+#define ARM_CP15_PRECISE_EXTERNAL_ABORT_FAULT 0x0008
+#define ARM_CP15_IMPRECISE_EXTERNAL_ABORT_FAULT 0x0406
+#define ARM_CP15_PRECISE_PARITY_ERROR_EXCEPTION 0x0006
+#define ARM_CP15_IMPRECISE_PARITY_ERROR_EXCEPTION 0x0408
+#define ARM_CP15_DEBUG_EVENT 0x0002
+
+/* print error description */
+
+void arm_cp15_print_fault_status_description(uint32_t fsr)
+{
+
+ uint32_t error = fsr & ARM_CP15_FAULT_STATUS_MASK;
+ //printk("fsr before mask is 0x%x and after mask is 0x%x\n",fsr,error);
+ switch(error)
+ {
+ case ARM_CP15_ALIGNMENT_FAULT:
+ printk("Fault Status : Alignment fault !\n");
+ break;
+
+ case ARM_CP15_BACKGROUND_FAULT:
+ printk("Fault Status : Background fault !\n");
+ break;
+
+ case ARM_CP15_ACCESS_PERMISSION_FAULT:
+ printk("Fault Status : Memory Access Permission fault !\n");
+ break;
+ case ARM_CP15_PRECISE_EXTERNAL_ABORT_FAULT:
+ printk("Fault Status : Precise external abort !\n");
+ break;
+
+ case ARM_CP15_IMPRECISE_EXTERNAL_ABORT_FAULT:
+ printk("Fault Status : Imprecise external abort !\n");
+ break;
+
+ case ARM_CP15_PRECISE_PARITY_ERROR_EXCEPTION:
+ printk("Fault Status : Precise parity error excpetion !\n");
+ break;
+
+ case ARM_CP15_IMPRECISE_PARITY_ERROR_EXCEPTION:
+ printk("Fault Status : Imprecise parity error excpetion !\n");
+ break;
+
+ case ARM_CP15_DEBUG_EVENT:
+ printk("Fault Status : Debug event !\n");
+ break;
+
+ default:
+ printk("Unknown Error !\n");
+ }
+}
+
+#ifdef __cplusplus
+#endif /* LICPU_SHARED_ARM_CP15_DATA_FAULT_INFO */
diff --git a/c/src/lib/libcpu/arm/shared/src/armv7-mm-mpu.c b/c/src/lib/libcpu/arm/shared/src/armv7-mm-mpu.c
new file mode 100644
index 0000000..f4db385
--- /dev/null
+++ b/c/src/lib/libcpu/arm/shared/src/armv7-mm-mpu.c
@@ -0,0 +1,108 @@
+/**
+ * @file
+ *
+ * @ingroup libmm
+ *
+ * @brief Wrapper for ARMv7 MPU API.
+ */
+
+/*
+ * Copyright (c) 2013 Hesham AL-Matary.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBCPU_ARM_MPU_LIBMM
+#define LIBCPU_ARM_MPU_LIBMM
+
+#include <rtems/score/armv7m.h>
+#include <libcpu/mm.h>
+#include <bsp/start-config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ALIGN_REGION_START_ADDRESS(addr,size) \
+ addr &= (2<<size)
+
+static void translate_attributes(
+ uint32_t high_level_attr,
+ uint32_t *ARM_CPU_ATTR
+)
+{
+#ifdef ARM_MULTILIB_ARCH_V7M
+ /* Clear flags attributes */
+ *ARM_CPU_ATTR = 0;
+
+ if( high_level_attr & 0x1 )
+ *ARM_CPU_ATTR |= ARMV7M_MPU_AP_PRIV_RO_USER_RO;
+
+ /* Write access */
+ if ( high_level_attr & 0x2 )
+ *ARM_CPU_ATTR |= ARMV7M_MPU_AP_PRIV_RW_USER_RW;
+#endif /* ARM_MULTILIB_ARCH_V7M */
+}
+
+
+void _CPU_Memory_management_Initialize(void)
+{
+#ifdef ARM_MULTILIB_ARCH_V7M
+ volatile ARMV7M_MPU *mpu = _ARMV7M_MPU;
+ size_t region_count = arm_start_config_mpu_region_count;
+ size_t i = 0;
+
+ for (i = 0; i < region_count; ++i) {
+ mpu->rbar = arm_start_config_mpu_region [i].rbar;
+ mpu->rasr = arm_start_config_mpu_region [i].rasr;
+ }
+
+ if (region_count > 0) {
+ mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE;
+ }
+#endif /* ARM_MULTILIB_ARCH_V7M */
+}
+
+_CPU_Memory_management_Set_attributes(
+ uintptr_t base,
+ size_t size,
+ uint32_t attr
+)
+{
+#ifdef ARM_MULTILIB_ARCH_V7M
+ volatile ARMV7M_MPU *mpu = _ARMV7M_MPU;
+ rtems_interrupt_level level;
+
+ uint32_t mpu_attr;
+
+ translate_attributes(attr, &mpu_attr);
+
+
+ /* Disable MPU and interrupts */
+ rtems_interrupt_disable(level);
+ mpu-> = 0;
+
+ ARMV7M_MPU_Region region =
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 0,
+ base,
+ size,
+ mpu_attr
+ );
+
+ mpu->rbar = region.basr;
+ mpu->rasr = region.rasr;
+
+ /* Enable MPU and interrupts */
+ mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE;
+ rtems_interrupt_enable(level);
+#endif /* ARM_MULTILIB_ARCH_V7M */
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBCPU_ARM_MPU_LIBMM */
diff --git a/c/src/lib/libcpu/arm/shared/src/mm.c b/c/src/lib/libcpu/arm/shared/src/mm.c
new file mode 100644
index 0000000..f0be25f
--- /dev/null
+++ b/c/src/lib/libcpu/arm/shared/src/mm.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 Hesham AL-Matary.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp/arm-cp15-start.h>
+#include <libcpu/arm-cp15.h>
+#include <libcpu/mm.h>
+#include <bsp/start.h>
+#include <bsp/linker-symbols.h>
+#include <libcpu/arm_cp15_print_fsr.h>
+#include <bsp/mm_config_table.h>
+
+void _CPU_Memory_management_Initialize(void)
+{
+ uint32_t ctrl = 0;
+ uint32_t client_domain = 15;
+ uint32_t *ttb;
+ ctrl = arm_cp15_get_control();
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &_cpu_mmu_config_table[0],
+ RTEMS_ARRAY_SIZE(&_cpu_mmu_config_table)
+ );
+
+ arm_cp15_set_exception_handler(ARM_EXCEPTION_DATA_ABORT,
+ dummy_data_abort_exception_handler
+ );
+}
+
+void _CPU_Memory_management_Set_attributes(
+ uintptr_t base,
+ size_t size,
+ uint32_t attr
+)
+{
+ uint32_t end = (uint32_t)base + (uint32_t)size;
+ uint32_t section_flags;
+ uint32_t cl_size = arm_cp15_get_min_cache_line_size();
+ uint32_t i = ARM_MMU_SECT_GET_INDEX(base);
+ uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
+ uint32_t ctrl;
+ uint32_t cpsr = 0;
+ uint32_t *ttb = arm_cp15_get_translation_table_base();
+ uint32_t *table = (uint32_t *) bsp_section_vector_begin;
+ uint32_t *vend = (uint32_t *) bsp_section_vector_end;
+
+ section_flags = translation_table[attr];
+ arm_cp15_set_translation_table_entries(base, end, section_flags);
+}
+
+void dummy_data_abort_exception_handler(void)
+{
+ uint32_t cpsr;
+#if DEBUG
+ printf("Entered exception handler \n");
+
+ __asm__ volatile (
+ ARM_SWITCH_TO_ARM
+ "mrs %[cpsr], cpsr\n"
+ ARM_SWITCH_BACK
+ : [cpsr] "=&r" (cpsr)
+ );
+
+ printf("CPSR after enable MMU is 0x%x \n",cpsr);
+
+ uint32_t address_fault = (uint32_t)arm_cp15_get_fault_address();
+ printk("Data fault address at 0x%x\n",address_fault);
+
+ uint32_t fsr = (uint32_t) arm_cp15_get_data_fault_status();
+ arm_cp15_print_fault_status_description(fsr);
+#endif
+
+ //TODO: Call rtems_fatal
+ exit(0);
+}
+
--
1.8.3.1
More information about the devel
mailing list