mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-10 17:43:21 +00:00
2004-07-15 Jay Monkman
* ChangeLog, Makefile.am, arm920/mmu.c, include/mmu.h: New files.
This commit is contained in:
4
c/src/lib/libcpu/arm/shared/ChangeLog
Normal file
4
c/src/lib/libcpu/arm/shared/ChangeLog
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
2004-07-15 Jay Monkman
|
||||||
|
|
||||||
|
* ChangeLog, Makefile.am, arm920/mmu.c, include/mmu.h: New files.
|
||||||
|
|
||||||
54
c/src/lib/libcpu/arm/shared/Makefile.am
Normal file
54
c/src/lib/libcpu/arm/shared/Makefile.am
Normal file
@@ -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
|
||||||
242
c/src/lib/libcpu/arm/shared/arm920/mmu.c
Normal file
242
c/src/lib/libcpu/arm/shared/arm920/mmu.c
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* ARM920 MMU functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004 by Cogent Computer Systems
|
||||||
|
* Written by Jay Monkman <jtm@lopingdog.com>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
#include <libcpu/mmu.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)
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
c/src/lib/libcpu/arm/shared/include/mmu.h
Normal file
30
c/src/lib/libcpu/arm/shared/include/mmu.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* ARM MMU header file
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004 by Cogent Computer Systems
|
||||||
|
* Written by Jay Monkman <jtm@lopingdog.com>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
#ifndef __MMU_H__
|
||||||
|
#define __MMU_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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__ */
|
||||||
Reference in New Issue
Block a user