diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2010-01-12 15:03:22 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2010-01-12 15:03:22 +0000 |
commit | 39c8fdb416327c5ec0c23807ae701798a5739cdf (patch) | |
tree | 0f2bb4acb60e60d74b7ef08e345a21d7896aba20 /c/src/lib/libcpu/arm | |
parent | 2010-01-11 Marc Pignat <marc.pignat@hevs.ch> (diff) | |
download | rtems-39c8fdb416327c5ec0c23807ae701798a5739cdf.tar.bz2 |
add support for lpc32xx
Diffstat (limited to 'c/src/lib/libcpu/arm')
-rw-r--r-- | c/src/lib/libcpu/arm/ChangeLog | 7 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/Makefile.am | 1 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/preinstall.am | 4 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/shared/arm920/mmu.c | 146 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/shared/include/arm-cp15.h | 644 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/shared/include/cache.h | 132 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/shared/include/cache_.h | 27 |
7 files changed, 830 insertions, 131 deletions
diff --git a/c/src/lib/libcpu/arm/ChangeLog b/c/src/lib/libcpu/arm/ChangeLog index 4c3a2707ba..cf99f1646a 100644 --- a/c/src/lib/libcpu/arm/ChangeLog +++ b/c/src/lib/libcpu/arm/ChangeLog @@ -1,3 +1,10 @@ +2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de> + + * shared/include/arm-cp15.h, shared/include/cache.h, + shared/include/cache_.h: New files. + * Makefile.am, preinstall.am: Update for new files. + * shared/arm920/mmu.c: Include and use <libcpu/arm-cp15.h>. + 2009-11-30 Fernando Nicodemos <fgnicodemos@terra.com.br> * at91rm9200/include/at91rm9200.h: Update to match development version. diff --git a/c/src/lib/libcpu/arm/Makefile.am b/c/src/lib/libcpu/arm/Makefile.am index 59d8ad1c6c..8ad15ed4b9 100644 --- a/c/src/lib/libcpu/arm/Makefile.am +++ b/c/src/lib/libcpu/arm/Makefile.am @@ -15,6 +15,7 @@ if shared include_libcpudir = $(includedir)/libcpu include_libcpu_HEADERS = shared/include/mmu.h +include_libcpu_HEADERS += shared/include/arm-cp15.h ## shared/arm920 noinst_PROGRAMS += shared/arm920.rel diff --git a/c/src/lib/libcpu/arm/preinstall.am b/c/src/lib/libcpu/arm/preinstall.am index 4ae225666a..a40ee5d945 100644 --- a/c/src/lib/libcpu/arm/preinstall.am +++ b/c/src/lib/libcpu/arm/preinstall.am @@ -27,6 +27,10 @@ PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp) $(PROJECT_INCLUDE)/libcpu/mmu.h: shared/include/mmu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h + +$(PROJECT_INCLUDE)/libcpu/arm-cp15.h: shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h endif if pxa255 $(PROJECT_INCLUDE)/pxa255.h: pxa255/include/pxa255.h $(PROJECT_INCLUDE)/$(dirstamp) diff --git a/c/src/lib/libcpu/arm/shared/arm920/mmu.c b/c/src/lib/libcpu/arm/shared/arm920/mmu.c index 752314723d..a9f90a8fa6 100644 --- a/c/src/lib/libcpu/arm/shared/arm920/mmu.c +++ b/c/src/lib/libcpu/arm/shared/arm920/mmu.c @@ -7,26 +7,12 @@ * $Id$ */ #include <libcpu/mmu.h> +#include <libcpu/arm-cp15.h> typedef uint32_t mmu_lvl1_t; extern uint32_t _ttbl_base; -static inline uint32_t mmu_get_id(void); -static inline uint32_t mmu_get_ctrl(void); -static inline void mmu_set_ctrl(uint32_t val); -static inline uint32_t mmu_get_trans_tbl(void); -static inline void mmu_set_trans_tbl(uint32_t val); -static inline uint32_t mmu_get_domain_ctrl(void); -static inline void mmu_set_domain_ctrl(uint32_t val); -static inline uint32_t mmu_get_fault_stat(void); -static inline void mmu_set_fault_stat(uint32_t val); -static inline uint32_t mmu_get_fault_addr(void); -static inline void mmu_set_fault_addr(uint32_t val); -static inline void mmu_set_cache_inval(void); -static inline void mmu_set_tlb_inval(void); -static inline uint32_t mmu_get_proc_id(void); -static inline void mmu_set_proc_id(uint32_t val); static void mmu_set_map_inval(mmu_lvl1_t *base); #define MMU_CTRL_MMU_EN (1 << 0) @@ -54,25 +40,23 @@ static void mmu_set_map_inval(mmu_lvl1_t *base); #define MMU_SECT_AP_ALL (0x3 << 10) -#define NOP ( { asm volatile ("nop\n" ); } ) - void mmu_init(mmu_sect_map_t *map) { mmu_lvl1_t *lvl1_base; int i; /* flush the cache and TLB */ - mmu_set_cache_inval(); - mmu_set_tlb_inval(); + arm_cp15_cache_invalidate(); + arm_cp15_tlb_invalidate(); /* set manage mode access for all domains */ - mmu_set_domain_ctrl(0xffffffff); + arm_cp15_set_domain_access_control(0xffffffff); lvl1_base = (mmu_lvl1_t *)&_ttbl_base; /* set up the trans table */ mmu_set_map_inval(lvl1_base); - mmu_set_trans_tbl((uint32_t) lvl1_base); + arm_cp15_set_translation_table_base(lvl1_base); /* create a 1:1 mapping of the entire address space */ i = 0; @@ -120,118 +104,20 @@ void mmu_init(mmu_sect_map_t *map) } /* flush the cache and TLB */ - mmu_set_cache_inval(); - mmu_set_tlb_inval(); - - NOP; - NOP; + arm_cp15_cache_invalidate(); + arm_cp15_tlb_invalidate(); /* I & D caches turned on */ - mmu_set_ctrl(MMU_CTRL_DEFAULT | - MMU_CTRL_D_CACHE_EN | - MMU_CTRL_I_CACHE_EN | - MMU_CTRL_ALIGN_FAULT_EN | - MMU_CTRL_LITTLE_ENDIAN | - MMU_CTRL_MMU_EN); - - NOP; - NOP; + arm_cp15_set_control(MMU_CTRL_DEFAULT | + MMU_CTRL_D_CACHE_EN | + MMU_CTRL_I_CACHE_EN | + MMU_CTRL_ALIGN_FAULT_EN | + MMU_CTRL_LITTLE_ENDIAN | + MMU_CTRL_MMU_EN); return; } - -static inline uint32_t mmu_get_id(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr0, cr0\n" : "=r" (val)); - return val; -} - -static inline uint32_t mmu_get_ctrl(void) -{ - uint32_t val; - asm volatile ("mrc 15, 0, %0, cr1, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_ctrl(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr1, cr0, 0\n" : :"r" (val)); -} - -static inline uint32_t mmu_get_trans_tbl(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr2, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_trans_tbl(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr2, cr0, 0\n" : :"r" (val)); -} - -static inline uint32_t mmu_get_domain_ctrl(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr3, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_domain_ctrl(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr3, cr0, 0\n" : :"r" (val)); -} - -static inline uint32_t mmu_get_fault_stat(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr5, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_fault_stat(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr5, cr0, 0\n" : :"r" (val)); -} - -static inline uint32_t mmu_get_fault_addr(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr6, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_fault_addr(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr6, cr0, 0\n" : :"r" (val)); -} - -static inline void mmu_set_cache_inval(void) -{ - uint32_t val = 0; - asm volatile ("mcr 15, 0, %0, cr7, cr7, 0\n" : :"r" (val)); -} - -static inline void mmu_set_tlb_inval(void) -{ - uint32_t val = 0; - asm volatile ("mcr 15, 0, %0, cr8, cr7, 0\n" : :"r" (val)); -} - -static inline uint32_t mmu_get_proc_id(void) -{ - uint32_t val; - asm volatile ("msr 15, 0, %0, cr13, cr0\n" : "=r" (val)); - return val; -} - -static inline void mmu_set_proc_id(uint32_t val) -{ - asm volatile ("mcr 15, 0, %0, cr13, cr0, 0\n" : :"r" (val)); -} - /* set all the level 1 entrys to be invalid descriptors */ static void mmu_set_map_inval(mmu_lvl1_t *base) { @@ -241,12 +127,10 @@ static void mmu_set_map_inval(mmu_lvl1_t *base) } } - void mmu_set_cpu_async_mode(void) { uint32_t reg; - reg = mmu_get_ctrl(); + reg = arm_cp15_get_control(); reg |= 0xc0000000; - mmu_set_ctrl(reg); + arm_cp15_set_control(reg); } - diff --git a/c/src/lib/libcpu/arm/shared/include/arm-cp15.h b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h new file mode 100644 index 0000000000..3f0036f6c6 --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/include/arm-cp15.h @@ -0,0 +1,644 @@ +/** + * @file + * + * @ingroup arm + * + * @brief ARM co-processor 15 (CP15) API. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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_SHARED_ARM_CP15_H +#define LIBCPU_SHARED_ARM_CP15_H + +#include <rtems.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define ARM_MMU_SECT_BASE_SHIFT 20 +#define ARM_MMU_SECT_BASE_MASK 0xfffU +#define ARM_MMU_SECT_DOMAIN_SHIFT 5 +#define ARM_MMU_SECT_DOMAIN_MASK 0xfU +#define ARM_MMU_SECT_AP_1 (1U << 11) +#define ARM_MMU_SECT_AP_0 (1U << 10) +#define ARM_MMU_SECT_AP_SHIFT 10 +#define ARM_MMU_SECT_AP_MASK 0x3U +#define ARM_MMU_SECT_C (1U << 3) +#define ARM_MMU_SECT_B (1U << 2) +#define ARM_MMU_SECT_DEFAULT 0x12U +#define ARM_MMU_SECT_GET_INDEX(mva) \ + (((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT) +#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \ + ((1U << ARM_MMU_SECT_BASE_SHIFT) \ + + ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U))) + +#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U +#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U + +static inline uint32_t arm_cp15_get_id_code(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c0, c0, 0\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline uint32_t arm_cp15_get_cache_type(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c0, c0, 1\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline uint32_t arm_cp15_get_tcm_status(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c0, c0, 2\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +#define ARM_CP15_CTRL_L4 (1U << 15) +#define ARM_CP15_CTRL_RR (1U << 14) +#define ARM_CP15_CTRL_V (1U << 13) +#define ARM_CP15_CTRL_I (1U << 12) +#define ARM_CP15_CTRL_R (1U << 9) +#define ARM_CP15_CTRL_S (1U << 8) +#define ARM_CP15_CTRL_B (1U << 7) +#define ARM_CP15_CTRL_C (1U << 2) +#define ARM_CP15_CTRL_A (1U << 1) +#define ARM_CP15_CTRL_M (1U << 0) + +static inline uint32_t arm_cp15_get_control(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c1, c0, 0\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline void arm_cp15_set_control(uint32_t val) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[val], c1, c0, 0\n" + "nop\n" + "nop\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [val] "r" (val) + : "memory" + ); +} + +static inline uint32_t *arm_cp15_get_translation_table_base(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t *base; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[base], c2, c0, 0\n" + ARM_SWITCH_BACK + : [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return base; +} + +static inline void arm_cp15_set_translation_table_base(uint32_t *base) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[base], c2, c0, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [base] "r" (base) + ); +} + +#define ARM_CP15_DAC_NO_ACCESS 0x0U +#define ARM_CP15_DAC_CLIENT 0x1U +#define ARM_CP15_DAC_MANAGER 0x3U +#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index)) + +static inline uint32_t arm_cp15_get_domain_access_control(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c3, c0, 0\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline void arm_cp15_set_domain_access_control(uint32_t val) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[val], c3, c0, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [val] "r" (val) + ); +} + +static inline uint32_t arm_cp15_get_data_fault_status(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c5, c0, 0\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline void arm_cp15_set_data_fault_status(uint32_t val) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[val], c5, c0, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [val] "r" (val) + ); +} + +static inline uint32_t arm_cp15_get_instruction_fault_status(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t val; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[val], c5, c0, 1\n" + ARM_SWITCH_BACK + : [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return val; +} + +static inline void arm_cp15_set_instruction_fault_status(uint32_t val) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[val], c5, c0, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [val] "r" (val) + ); +} + +static inline void *arm_cp15_get_fault_address(void) +{ + ARM_SWITCH_REGISTERS; + void *mva; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mrc p15, 0, %[mva], c6, c0, 0\n" + ARM_SWITCH_BACK + : [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT + ); + + return mva; +} + +static inline void arm_cp15_set_fault_address(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c6, c0, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + ); +} + +#define ARM_CP15_CACHE_PREPARE_MVA(mva) \ + ((const void *) (((uint32_t) (mva)) & ~0x1fU)) + +static inline void arm_cp15_cache_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c7, c7, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + : "memory" + ); +} + +static inline void arm_cp15_instruction_cache_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c7, c5, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + : "memory" + ); +} + +static inline void arm_cp15_instruction_cache_invalidate_line(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_CACHE_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c7, c5, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + : "memory" + ); +} + +static inline void arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[set_and_way], c7, c5, 2\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [set_and_way] "r" (set_and_way) + : "memory" + ); +} + +static inline void arm_cp15_instruction_cache_prefetch_line(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_CACHE_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c7, c13, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + ); +} + +static inline void arm_cp15_data_cache_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c7, c6, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_invalidate_line(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_CACHE_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c7, c6, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[set_and_way], c7, c6, 2\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [set_and_way] "r" (set_and_way) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_clean_line(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_CACHE_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c7, c10, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[set_and_way], c7, c10, 2\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [set_and_way] "r" (set_and_way) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_test_and_clean(void) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "1:\n" + "mrc p15, 0, r15, c7, c10, 3\n" + "bne 1b\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : + : "memory" + ); +} + +static inline void arm_cp15_data_cache_clean_and_invalidate_line(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_CACHE_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c7, c14, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[set_and_way], c7, c14, 2\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [set_and_way] "r" (set_and_way) + : "memory" + ); +} + +static inline void arm_cp15_data_cache_test_and_clean_and_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "1:\n" + "mrc p15, 0, r15, c7, c14, 3\n" + "bne 1b\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : + : "memory" + ); +} + +static inline void arm_cp15_drain_write_buffer(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c7, c10, 4\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + : "memory" + ); +} + +static inline void arm_cp15_wait_for_interrupt(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c7, c0, 4\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + : "memory" + ); +} + +#define ARM_CP15_TLB_PREPARE_MVA(mva) \ + ((const void *) (((uint32_t) (mva)) & ~0x3fU)) + +static inline void arm_cp15_tlb_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c8, c7, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + ); +} + +static inline void arm_cp15_tlb_invalidate_entry(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_TLB_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c8, c7, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + ); +} + +static inline void arm_cp15_tlb_instruction_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c8, c5, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + ); +} + +static inline void arm_cp15_tlb_instruction_invalidate_entry(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_TLB_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c8, c5, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + ); +} + +static inline void arm_cp15_tlb_data_invalidate(void) +{ + ARM_SWITCH_REGISTERS; + uint32_t sbz = 0; + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[sbz], c8, c6, 0\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [sbz] "r" (sbz) + ); +} + +static inline void arm_cp15_tlb_data_invalidate_entry(const void *mva) +{ + ARM_SWITCH_REGISTERS; + + mva = ARM_CP15_TLB_PREPARE_MVA(mva); + + asm volatile ( + ARM_SWITCH_TO_ARM + "mcr p15, 0, %[mva], c8, c6, 1\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [mva] "r" (mva) + ); +} + +static inline void arm_cp15_tlb_lockdown_entry(const void *mva) +{ + uint32_t arm_switch_reg; + + asm volatile ( + ARM_SWITCH_TO_ARM + "add %[arm_switch_reg], pc, #16\n" + "mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n" + "mcr p15, 0, %[mva], c8, c7, 1\n" + "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n" + "orr %[arm_switch_reg], #0x1\n" + "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n" + "ldr %[mva], [%[mva]]\n" + "mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n" + "bic %[arm_switch_reg], #0x1\n" + "mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n" + ARM_SWITCH_BACK + : [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg) + : "[mva]" (mva) + ); +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBCPU_SHARED_ARM_CP15_H */ diff --git a/c/src/lib/libcpu/arm/shared/include/cache.h b/c/src/lib/libcpu/arm/shared/include/cache.h new file mode 100644 index 0000000000..3e6784f765 --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/include/cache.h @@ -0,0 +1,132 @@ +/** + * @file + * + * @ingroup arm + * + * @brief ARM cache defines and implementation. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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_CACHE_H +#define LIBCPU_ARM_CACHE_H + +#ifdef __ARM_ARCH_5TEJ__ + #include <libcpu/arm-cp15.h> + + #define CPU_DATA_CACHE_ALIGNMENT 32 + #define CPU_INSTRUCTION_CACHE_ALIGNMENT 32 + + static inline void _CPU_cache_flush_1_data_line(const void *d_addr) + { + arm_cp15_data_cache_clean_line(d_addr); + } + + static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr) + { + arm_cp15_data_cache_invalidate_line(d_addr); + } + + static inline void _CPU_cache_freeze_data(void) + { + /* TODO */ + } + + static inline void _CPU_cache_unfreeze_data(void) + { + /* TODO */ + } + + static inline void _CPU_cache_invalidate_1_instruction_line(const void *d_addr) + { + arm_cp15_instruction_cache_invalidate_line(d_addr); + } + + static inline void _CPU_cache_freeze_instruction(void) + { + /* TODO */ + } + + static inline void _CPU_cache_unfreeze_instruction(void) + { + /* TODO */ + } + + static inline void _CPU_cache_flush_entire_data(void) + { + arm_cp15_data_cache_test_and_clean(); + } + + static inline void _CPU_cache_invalidate_entire_data(void) + { + arm_cp15_data_cache_invalidate(); + } + + static inline void _CPU_cache_enable_data(void) + { + rtems_interrupt_level level; + uint32_t ctrl; + + rtems_interrupt_disable(level); + ctrl = arm_cp15_get_control(); + ctrl |= ARM_CP15_CTRL_C; + arm_cp15_set_control(ctrl); + rtems_interrupt_enable(level); + } + + static inline void _CPU_cache_disable_data(void) + { + rtems_interrupt_level level; + uint32_t ctrl; + + rtems_interrupt_disable(level); + ctrl = arm_cp15_get_control(); + ctrl &= ~ARM_CP15_CTRL_C; + arm_cp15_set_control(ctrl); + rtems_interrupt_enable(level); + + arm_cp15_data_cache_test_and_clean_and_invalidate(); + } + + static inline void _CPU_cache_invalidate_entire_instruction(void) + { + arm_cp15_instruction_cache_invalidate(); + } + + static inline void _CPU_cache_enable_instruction(void) + { + rtems_interrupt_level level; + uint32_t ctrl; + + rtems_interrupt_disable(level); + ctrl = arm_cp15_get_control(); + ctrl |= ARM_CP15_CTRL_I; + arm_cp15_set_control(ctrl); + rtems_interrupt_enable(level); + } + + static inline void _CPU_cache_disable_instruction(void) + { + rtems_interrupt_level level; + uint32_t ctrl; + + rtems_interrupt_disable(level); + ctrl = arm_cp15_get_control(); + ctrl &= ~ARM_CP15_CTRL_I; + arm_cp15_set_control(ctrl); + rtems_interrupt_enable(level); + } +#endif + +#endif /* LIBCPU_ARM_CACHE_H */ diff --git a/c/src/lib/libcpu/arm/shared/include/cache_.h b/c/src/lib/libcpu/arm/shared/include/cache_.h new file mode 100644 index 0000000000..b617b65ace --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/include/cache_.h @@ -0,0 +1,27 @@ +/** + * @file + * + * @ingroup arm + * + * @brief Empty file. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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_CACHE__H +#define LIBCPU_ARM_CACHE__H + +/* Empty */ + +#endif /* LIBCPU_ARM_CACHE__H */ |