source: rtems/c/src/lib/libcpu/arm/shared/arm920/mmu.c @ 15ebe58b

4.104.114.84.95
Last change on this file since 15ebe58b was 8824dd7a, checked in by Jay Monkman <jtm@…>, on 07/15/04 at 06:26:30

2004-07-15 Jay Monkman

  • ChangeLog?, Makefile.am, arm920/mmu.c, include/mmu.h: New files.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  ARM920 MMU functions
3 *
4 *  Copyright (c) 2004 by Cogent Computer Systems
5 *  Written by Jay Monkman <jtm@lopingdog.com>
6 *
7 *  $Id$
8 */
9#include <libcpu/mmu.h>
10
11typedef uint32_t mmu_lvl1_t;
12
13extern uint32_t _ttbl_base;
14
15static inline uint32_t mmu_get_id(void);
16static inline uint32_t mmu_get_ctrl(void);
17static inline void mmu_set_ctrl(uint32_t val);
18static inline uint32_t mmu_get_trans_tbl(void);
19static inline void mmu_set_trans_tbl(uint32_t val);
20static inline uint32_t mmu_get_domain_ctrl(void);
21static inline void mmu_set_domain_ctrl(uint32_t val);
22static inline uint32_t mmu_get_fault_stat(void);
23static inline void mmu_set_fault_stat(uint32_t val);
24static inline uint32_t mmu_get_fault_addr(void);
25static inline void mmu_set_fault_addr(uint32_t val);
26static inline void mmu_set_cache_inval(void);
27static inline void mmu_set_tlb_inval(void);
28static inline uint32_t mmu_get_proc_id(void);
29static inline void mmu_set_proc_id(uint32_t val);
30static void mmu_set_map_inval(mmu_lvl1_t *base);
31
32#define MMU_CTRL_MMU_EN             (1 << 0)
33#define MMU_CTRL_ALIGN_FAULT_EN     (1 << 1)
34#define MMU_CTRL_D_CACHE_EN         (1 << 2)
35#define MMU_CTRL_DEFAULT            (0xf << 3)
36#define MMU_CTRL_LITTLE_ENDIAN      (0 << 7)
37#define MMU_CTRL_BIG_ENDIAN         (1 << 7)
38#define MMU_CTRL_SYS_PROT           (1 << 8)
39#define MMU_CTRL_ROM_PROT           (1 << 9)
40#define MMU_CTRL_I_CACHE_EN         (1 << 12)
41#define MMU_CTRL_LOW_VECT           (0 << 13)
42#define MMU_CTRL_HIGH_VECT          (1 << 13)
43
44
45#define MMU_SET_LVL1_SECT(addr, ap, dom, ce, be) \
46          (((addr) & 0xfff00000) |     \
47           (ap)                  |     \
48           (dom)                 |     \
49           ((ce) << 3)           |     \
50           ((be) << 2)           |     \
51           0x12)
52
53#define MMU_SET_LVL1_INVAL (0x0)
54
55#define MMU_SECT_AP_ALL (0x3 << 10)
56
57#define NOP ( { asm volatile ("nop\n" ); } )
58
59void mmu_init(mmu_sect_map_t *map)
60{
61    mmu_lvl1_t *lvl1_base;
62    int i;
63
64    /* flush the cache and TLB */
65    mmu_set_cache_inval();
66    mmu_set_tlb_inval();
67
68    /* set manage mode access for all domains */
69    mmu_set_domain_ctrl(0xffffffff);
70
71    lvl1_base = (mmu_lvl1_t *)&_ttbl_base;
72
73    /* set up the trans table */
74    mmu_set_map_inval(lvl1_base);
75    mmu_set_trans_tbl((uint32_t) lvl1_base);
76
77    /* create a 1:1 mapping of the entire address space */
78    i = 0;
79    while(map[i].size != 0) {
80        int c;
81        int b;
82        int pbase;
83        int vbase;
84        int sects;
85
86        switch (map[i].cache_flags) {
87        case MMU_CACHE_NONE:
88            c = 0;
89            b = 0;
90            break;
91        case MMU_CACHE_BUFFERED:
92            c = 0;
93            b = 1;
94            break;
95        case MMU_CACHE_WTHROUGH:
96            c = 1;
97            b = 0;
98            break;
99        case MMU_CACHE_WBACK:
100            c = 1;
101            b = 1;
102            break;
103        }
104
105        pbase = (map[i].paddr & 0xfff00000) >> 20;
106        vbase = (map[i].vaddr & 0xfff00000) >> 20;
107        sects = map[i].size;
108
109        while (sects > 0) {
110            lvl1_base[vbase] = MMU_SET_LVL1_SECT(pbase << 20,
111                                                 MMU_SECT_AP_ALL,
112                                                 0,
113                                                 c,
114                                                 b);
115            pbase++;
116            vbase++;
117            sects--;
118        }
119        i++;
120    }
121
122    /* flush the cache and TLB */
123    mmu_set_cache_inval();
124    mmu_set_tlb_inval();
125
126    NOP;
127    NOP;
128
129    /*  I & D caches turned on */
130    mmu_set_ctrl(MMU_CTRL_DEFAULT |
131                 MMU_CTRL_D_CACHE_EN |
132                 MMU_CTRL_I_CACHE_EN |
133                 MMU_CTRL_ALIGN_FAULT_EN |
134                 MMU_CTRL_LITTLE_ENDIAN |
135                 MMU_CTRL_MMU_EN);
136
137    NOP;
138    NOP;
139
140    return;
141}
142
143
144static inline uint32_t mmu_get_id(void)
145{
146    uint32_t val;
147    asm volatile ("msr 15, 0, %0, cr0, cr0\n" : "=r" (val));
148    return val;
149}
150
151static inline uint32_t mmu_get_ctrl(void)
152{
153    uint32_t val;
154    asm volatile ("msr 15, 0, %0, cr1, cr0\n" : "=r" (val));
155    return val;
156}
157
158static inline void mmu_set_ctrl(uint32_t val)
159{
160    asm volatile ("mcr 15, 0, %0, cr1, cr0, 0\n" : :"r" (val));
161}
162
163static inline uint32_t mmu_get_trans_tbl(void)
164{
165    uint32_t val;
166    asm volatile ("msr 15, 0, %0, cr2, cr0\n" : "=r" (val));
167    return val;
168}
169
170static inline void mmu_set_trans_tbl(uint32_t val)
171{
172    asm volatile ("mcr 15, 0, %0, cr2, cr0, 0\n" : :"r" (val));
173}
174
175static inline uint32_t mmu_get_domain_ctrl(void)
176{
177    uint32_t val;
178    asm volatile ("msr 15, 0, %0, cr3, cr0\n" : "=r" (val));
179    return val;
180}
181
182static inline void mmu_set_domain_ctrl(uint32_t val)
183{
184    asm volatile ("mcr 15, 0, %0, cr3, cr0, 0\n" : :"r" (val));
185}
186
187static inline uint32_t mmu_get_fault_stat(void)
188{
189    uint32_t val;
190    asm volatile ("msr 15, 0, %0, cr5, cr0\n" : "=r" (val));
191    return val;
192}
193
194static inline void mmu_set_fault_stat(uint32_t val)
195{
196    asm volatile ("mcr 15, 0, %0, cr5, cr0, 0\n" : :"r" (val));
197}
198
199static inline uint32_t mmu_get_fault_addr(void)
200{
201    uint32_t val;
202    asm volatile ("msr 15, 0, %0, cr6, cr0\n" : "=r" (val));
203    return val;
204}
205
206static inline void mmu_set_fault_addr(uint32_t val)
207{
208    asm volatile ("mcr 15, 0, %0, cr6, cr0, 0\n" : :"r" (val));
209}
210
211static inline void mmu_set_cache_inval(void)
212{
213    uint32_t val = 0;
214    asm volatile ("mcr 15, 0, %0, cr7, cr7, 0\n" : :"r" (val));
215}
216
217static inline void mmu_set_tlb_inval(void)
218{
219    uint32_t val = 0;
220    asm volatile ("mcr 15, 0, %0, cr8, cr7, 0\n" : :"r" (val));
221}
222
223static inline uint32_t mmu_get_proc_id(void)
224{
225    uint32_t val;
226    asm volatile ("msr 15, 0, %0, cr13, cr0\n" : "=r" (val));
227    return val;
228}
229
230static inline void mmu_set_proc_id(uint32_t val)
231{
232    asm volatile ("mcr 15, 0, %0, cr13, cr0, 0\n" : :"r" (val));
233}
234
235/* set all the level 1 entrys to be invalid descriptors */
236static void mmu_set_map_inval(mmu_lvl1_t *base)
237{
238    int i;
239    for (i = 0; i < (0x4000 / 4); i++) {
240        base[i] = MMU_SET_LVL1_INVAL;
241    }
242}
Note: See TracBrowser for help on using the repository browser.