--- 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 _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel