From 8824dd7a4f8fb5ebb6c37eea51a90e86d3119d12 Mon Sep 17 00:00:00 2001 From: Jay Monkman Date: Thu, 15 Jul 2004 06:26:30 +0000 Subject: 2004-07-15 Jay Monkman * ChangeLog, Makefile.am, arm920/mmu.c, include/mmu.h: New files. --- c/src/lib/libcpu/arm/shared/ChangeLog | 4 + c/src/lib/libcpu/arm/shared/Makefile.am | 54 +++++++ c/src/lib/libcpu/arm/shared/arm920/mmu.c | 242 ++++++++++++++++++++++++++++++ c/src/lib/libcpu/arm/shared/include/mmu.h | 30 ++++ 4 files changed, 330 insertions(+) create mode 100644 c/src/lib/libcpu/arm/shared/ChangeLog create mode 100644 c/src/lib/libcpu/arm/shared/Makefile.am create mode 100644 c/src/lib/libcpu/arm/shared/arm920/mmu.c create mode 100644 c/src/lib/libcpu/arm/shared/include/mmu.h diff --git a/c/src/lib/libcpu/arm/shared/ChangeLog b/c/src/lib/libcpu/arm/shared/ChangeLog new file mode 100644 index 0000000000..abba1d722e --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/ChangeLog @@ -0,0 +1,4 @@ +2004-07-15 Jay Monkman + + * ChangeLog, Makefile.am, arm920/mmu.c, include/mmu.h: New files. + diff --git a/c/src/lib/libcpu/arm/shared/Makefile.am b/c/src/lib/libcpu/arm/shared/Makefile.am new file mode 100644 index 0000000000..6bec3d14e9 --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/Makefile.am @@ -0,0 +1,54 @@ +## +## $Id$ +## + +EXTRA_PROGRAMS = +CLEANFILES = +noinst_DATA = + +include $(top_srcdir)/../../../automake/compile.am + +# include +if shared +include_libcpudir = $(includedir)/libcpu + +include_libcpu_HEADERS = include/mmu.h + +## arm920 +EXTRA_PROGRAMS += arm920.rel +CLEANFILES += arm920.rel +arm920_rel_SOURCES = arm920/mmu.c +arm920_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V) -I$(srcdir)/src +arm920_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +EXTRA_PROGRAMS += arm920_g.rel +CLEANFILES += arm920_g.rel +arm920_g_rel_SOURCES = $(arm920_rel_SOURCES) +arm920_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V) -I$(srcdir)/src +arm920_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_DATA += arm920$(LIB_VARIANT).rel + +endif + +all-local: $(PREINSTALL_FILES) + +PREINSTALL_DIRS = +PREINSTALL_FILES = + +if shared +$(PROJECT_INCLUDE)/libcpu/$(dirstamp): + @$(mkdir_p) $(PROJECT_INCLUDE)/libcpu + @: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + +$(PROJECT_INCLUDE)/libcpu/mmu.h: include/mmu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h + +endif + +CLEANFILES += $(PREINSTALL_FILES) +DISTCLEANFILES = $(PREINSTALL_DIRS) + +include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libcpu/arm/shared/arm920/mmu.c b/c/src/lib/libcpu/arm/shared/arm920/mmu.c new file mode 100644 index 0000000000..967768d911 --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/arm920/mmu.c @@ -0,0 +1,242 @@ +/* + * ARM920 MMU functions + * + * Copyright (c) 2004 by Cogent Computer Systems + * Written by Jay Monkman + * + * $Id$ + */ +#include + +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) +#define MMU_CTRL_ALIGN_FAULT_EN (1 << 1) +#define MMU_CTRL_D_CACHE_EN (1 << 2) +#define MMU_CTRL_DEFAULT (0xf << 3) +#define MMU_CTRL_LITTLE_ENDIAN (0 << 7) +#define MMU_CTRL_BIG_ENDIAN (1 << 7) +#define MMU_CTRL_SYS_PROT (1 << 8) +#define MMU_CTRL_ROM_PROT (1 << 9) +#define MMU_CTRL_I_CACHE_EN (1 << 12) +#define MMU_CTRL_LOW_VECT (0 << 13) +#define MMU_CTRL_HIGH_VECT (1 << 13) + + +#define MMU_SET_LVL1_SECT(addr, ap, dom, ce, be) \ + (((addr) & 0xfff00000) | \ + (ap) | \ + (dom) | \ + ((ce) << 3) | \ + ((be) << 2) | \ + 0x12) + +#define MMU_SET_LVL1_INVAL (0x0) + +#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(); + + /* set manage mode access for all domains */ + mmu_set_domain_ctrl(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); + + /* create a 1:1 mapping of the entire address space */ + i = 0; + while(map[i].size != 0) { + int c; + int b; + int pbase; + int vbase; + int sects; + + switch (map[i].cache_flags) { + case MMU_CACHE_NONE: + c = 0; + b = 0; + break; + case MMU_CACHE_BUFFERED: + c = 0; + b = 1; + break; + case MMU_CACHE_WTHROUGH: + c = 1; + b = 0; + break; + case MMU_CACHE_WBACK: + c = 1; + b = 1; + break; + } + + pbase = (map[i].paddr & 0xfff00000) >> 20; + vbase = (map[i].vaddr & 0xfff00000) >> 20; + sects = map[i].size; + + while (sects > 0) { + lvl1_base[vbase] = MMU_SET_LVL1_SECT(pbase << 20, + MMU_SECT_AP_ALL, + 0, + c, + b); + pbase++; + vbase++; + sects--; + } + i++; + } + + /* flush the cache and TLB */ + mmu_set_cache_inval(); + mmu_set_tlb_inval(); + + NOP; + NOP; + + /* 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; + + 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 ("msr 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) +{ + int i; + for (i = 0; i < (0x4000 / 4); i++) { + base[i] = MMU_SET_LVL1_INVAL; + } +} diff --git a/c/src/lib/libcpu/arm/shared/include/mmu.h b/c/src/lib/libcpu/arm/shared/include/mmu.h new file mode 100644 index 0000000000..d298a93e2b --- /dev/null +++ b/c/src/lib/libcpu/arm/shared/include/mmu.h @@ -0,0 +1,30 @@ +/* + * ARM MMU header file + * + * Copyright (c) 2004 by Cogent Computer Systems + * Written by Jay Monkman + * + * $Id$ + */ +#ifndef __MMU_H__ +#define __MMU_H__ + +#include + +#define MMU_SECT_SIZE 0x100000 + +#define MMU_CACHE_NONE 0x0 +#define MMU_CACHE_BUFFERED 0x1 +#define MMU_CACHE_WTHROUGH 0x2 +#define MMU_CACHE_WBACK 0x3 + +typedef struct { + uint32_t paddr; + uint32_t vaddr; + uint32_t size; /* in MB */ + uint8_t cache_flags; +} mmu_sect_map_t; + +void mmu_init(mmu_sect_map_t *map); + +#endif /* __MMU_H__ */ -- cgit v1.2.3