forked from Imagelibrary/rtems
add support for lpc32xx
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
644
c/src/lib/libcpu/arm/shared/include/arm-cp15.h
Normal file
644
c/src/lib/libcpu/arm/shared/include/arm-cp15.h
Normal file
@@ -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 */
|
||||
132
c/src/lib/libcpu/arm/shared/include/cache.h
Normal file
132
c/src/lib/libcpu/arm/shared/include/cache.h
Normal file
@@ -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 */
|
||||
27
c/src/lib/libcpu/arm/shared/include/cache_.h
Normal file
27
c/src/lib/libcpu/arm/shared/include/cache_.h
Normal file
@@ -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 */
|
||||
Reference in New Issue
Block a user