summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2014-05-15 23:39:06 -0400
committerGravatar bunnei2014-05-15 23:39:06 -0400
commit9a642caee770db2632f4daa842b10801b47ffbfc (patch)
tree5a1c63014d08d7200bc69c96549c49ba75553f2d /src
parentfixed armmmu imports (diff)
downloadyuzu-9a642caee770db2632f4daa842b10801b47ffbfc.tar.gz
yuzu-9a642caee770db2632f4daa842b10801b47ffbfc.tar.xz
yuzu-9a642caee770db2632f4daa842b10801b47ffbfc.zip
added missing skyeye mmu code
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt6
-rw-r--r--src/core/arm/interpreter/armmmu.h18
-rw-r--r--src/core/arm/interpreter/mmu/cache.cpp370
-rw-r--r--src/core/arm/interpreter/mmu/rb.cpp126
-rw-r--r--src/core/arm/interpreter/mmu/sa_mmu.cpp864
-rw-r--r--src/core/arm/interpreter/mmu/sa_mmu.h58
-rw-r--r--src/core/arm/interpreter/mmu/tlb.cpp307
-rw-r--r--src/core/arm/interpreter/mmu/tlb.h9
-rw-r--r--src/core/arm/interpreter/mmu/wb.cpp149
-rw-r--r--src/core/arm/interpreter/mmu/xscale_copro.cpp1388
-rw-r--r--src/core/core.vcxproj19
-rw-r--r--src/core/core.vcxproj.filters63
12 files changed, 3333 insertions, 44 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 0d4a0ca7a..35ef1c7b3 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -19,6 +19,12 @@ set(SRCS core.cpp
19 arm/interpreter/vfp/vfpinsr.cpp 19 arm/interpreter/vfp/vfpinsr.cpp
20 arm/interpreter/vfp/vfpsingle.cpp 20 arm/interpreter/vfp/vfpsingle.cpp
21 arm/interpreter/mmu/arm1176jzf_s_mmu.cpp 21 arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
22 arm/interpreter/mmu/cache.cpp
23 arm/interpreter/mmu/sa_mmu.cpp
24 arm/interpreter/mmu/rb.cpp
25 arm/interpreter/mmu/tlb.cpp
26 arm/interpreter/mmu/wb.cpp
27 arm/interpreter/mmu/xscale_copro.cpp
22 elf/elf_reader.cpp 28 elf/elf_reader.cpp
23 file_sys/directory_file_system.cpp 29 file_sys/directory_file_system.cpp
24 file_sys/meta_file_system.cpp 30 file_sys/meta_file_system.cpp
diff --git a/src/core/arm/interpreter/armmmu.h b/src/core/arm/interpreter/armmmu.h
index 2ceaa7c64..818108c9c 100644
--- a/src/core/arm/interpreter/armmmu.h
+++ b/src/core/arm/interpreter/armmmu.h
@@ -178,12 +178,12 @@ typedef struct mmu_ops_s
178#include "core/arm/interpreter/mmu/cache.h" 178#include "core/arm/interpreter/mmu/cache.h"
179 179
180/*special process mmu.h*/ 180/*special process mmu.h*/
181//#include "core/arm/mmu/sa_mmu.h" 181#include "core/arm/interpreter/mmu/sa_mmu.h"
182//#include "core/arm/mmu/arm7100_mmu.h" 182//#include "core/arm/interpreter/mmu/arm7100_mmu.h"
183//#include "core/arm/mmu/arm920t_mmu.h" 183//#include "core/arm/interpreter/mmu/arm920t_mmu.h"
184//#include "core/arm/mmu/arm926ejs_mmu.h" 184//#include "core/arm/interpreter/mmu/arm926ejs_mmu.h"
185#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h" 185#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h"
186//#include "core/arm/mmu/cortex_a9_mmu.h" 186//#include "core/arm/interpreter/mmu/cortex_a9_mmu.h"
187 187
188typedef struct mmu_state_t 188typedef struct mmu_state_t
189{ 189{
@@ -213,13 +213,13 @@ typedef struct mmu_state_t
213 ARMword copro_access; // 15 213 ARMword copro_access; // 15
214 214
215 mmu_ops_t ops; 215 mmu_ops_t ops;
216 //union 216 union
217 //{ 217 {
218 //sa_mmu_t sa_mmu; 218 sa_mmu_t sa_mmu;
219 //arm7100_mmu_t arm7100_mmu; 219 //arm7100_mmu_t arm7100_mmu;
220 //arm920t_mmu_t arm920t_mmu; 220 //arm920t_mmu_t arm920t_mmu;
221 //arm926ejs_mmu_t arm926ejs_mmu; 221 //arm926ejs_mmu_t arm926ejs_mmu;
222 //} u; 222 } u;
223} mmu_state_t; 223} mmu_state_t;
224 224
225int mmu_init (ARMul_State * state); 225int mmu_init (ARMul_State * state);
diff --git a/src/core/arm/interpreter/mmu/cache.cpp b/src/core/arm/interpreter/mmu/cache.cpp
new file mode 100644
index 000000000..f3c4e0531
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/cache.cpp
@@ -0,0 +1,370 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/* mmu cache init
4 *
5 * @cache_t :cache_t to init
6 * @width :cache line width in byte
7 * @way :way of each cache set
8 * @set :cache set num
9 *
10 * $ -1: error
11 * 0: sucess
12 */
13int
14mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode)
15{
16 int i, j;
17 cache_set_t *sets;
18 cache_line_t *lines;
19
20 /*alloc cache set */
21 sets = NULL;
22 lines = NULL;
23 //fprintf(stderr, "mmu_cache_init: mallloc beg size %d,sets 0x%x\n", sizeof(cache_set_t) * set,sets);
24 //exit(-1);
25 sets = (cache_set_t *) malloc (sizeof (cache_set_t) * set);
26 if (sets == NULL) {
27 ERROR_LOG(ARM11, "set malloc size %d\n", sizeof (cache_set_t) * set);
28 goto sets_error;
29 }
30 //fprintf(stderr, "mmu_cache_init: mallloc end sets 0x%x\n", sets);
31 cache_t->sets = sets;
32
33 /*init cache set */
34 for (i = 0; i < set; i++) {
35 /*alloc cache line */
36 lines = (cache_line_t *) malloc (sizeof (cache_line_t) * way);
37 if (lines == NULL) {
38 ERROR_LOG(ARM11, "line malloc size %d\n",
39 sizeof (cache_line_t) * way);
40 goto lines_error;
41 }
42 /*init cache line */
43 for (j = 0; j < way; j++) {
44 lines[j].tag = 0; //invalid
45 lines[j].data = (ARMword *) malloc (width);
46 if (lines[j].data == NULL) {
47 ERROR_LOG(ARM11, "data alloc size %d\n", width);
48 goto data_error;
49 }
50 }
51
52 sets[i].lines = lines;
53 sets[i].cycle = 0;
54
55 }
56 cache_t->width = width;
57 cache_t->set = set;
58 cache_t->way = way;
59 cache_t->w_mode = w_mode;
60 return 0;
61
62 data_error:
63 /*free data */
64 while (j-- > 0)
65 free (lines[j].data);
66 /*free data error line */
67 free (lines);
68 lines_error:
69 /*free lines already alloced */
70 while (i-- > 0) {
71 for (j = 0; j < way; j++)
72 free (sets[i].lines[j].data);
73 free (sets[i].lines);
74 }
75 /*free sets */
76 free (sets);
77 sets_error:
78 return -1;
79};
80
81/* free a cache_t's inner data, the ptr self is not freed,
82 * when needed do like below:
83 * mmu_cache_exit(cache);
84 * free(cache_t);
85 *
86 * @cache_t : the cache_t to free
87 */
88
89void
90mmu_cache_exit (cache_s * cache_t)
91{
92 int i, j;
93 cache_set_t *sets, *set;
94 cache_line_t *lines, *line;
95
96 /*free all set */
97 sets = cache_t->sets;
98 for (set = sets, i = 0; i < cache_t->set; i++, set++) {
99 /*free all line */
100 lines = set->lines;
101 for (line = lines, j = 0; j < cache_t->way; j++, line++)
102 free (line->data);
103 free (lines);
104 }
105 free (sets);
106}
107
108/* mmu cache search
109 *
110 * @state :ARMul_State
111 * @cache_t :cache_t to search
112 * @va :virtual address
113 *
114 * $ NULL: no cache match
115 * cache :cache matched
116 */
117cache_line_t *
118mmu_cache_search (ARMul_State * state, cache_s * cache_t, ARMword va)
119{
120 int i;
121 int set = va_cache_set (va, cache_t);
122 ARMword tag = va_cache_align (va, cache_t);
123 cache_line_t *cache;
124
125 cache_set_t *cache_set = cache_t->sets + set;
126 for (i = 0, cache = cache_set->lines; i < cache_t->way; i++, cache++) {
127 if ((cache->tag & TAG_VALID_FLAG)
128 && (tag == va_cache_align (cache->tag, cache_t)))
129 return cache;
130 }
131 return NULL;
132}
133
134/* mmu cache search by set/index
135 *
136 * @state :ARMul_State
137 * @cache_t :cache_t to search
138 * @index :set/index value.
139 *
140 * $ NULL: no cache match
141 * cache :cache matched
142 */
143cache_line_t *
144mmu_cache_search_by_index (ARMul_State * state, cache_s * cache_t,
145 ARMword index)
146{
147 int way = cache_t->way;
148 int set_v = index_cache_set (index, cache_t);
149 int i = 0, index_v = 0;
150 cache_set_t *set;
151
152 while ((way >>= 1) >= 1)
153 i++;
154 index_v = index >> (32 - i);
155 set = cache_t->sets + set_v;
156
157 return set->lines + index_v;
158}
159
160
161/* mmu cache alloc
162 *
163 * @state :ARMul_State
164 * @cache_t :cache_t to alloc from
165 * @va :virtual address that require cache alloc, need not cache aligned
166 * @pa :physical address of va
167 *
168 * $ cache_alloced, always alloc OK
169 */
170cache_line_t *
171mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, ARMword va,
172 ARMword pa)
173{
174 cache_line_t *cache;
175 cache_set_t *set;
176 int i;
177
178 va = va_cache_align (va, cache_t);
179 pa = va_cache_align (pa, cache_t);
180
181 set = &cache_t->sets[va_cache_set (va, cache_t)];
182
183 /*robin-round */
184 cache = &set->lines[set->cycle++];
185 if (set->cycle == cache_t->way)
186 set->cycle = 0;
187
188 if (cache_t->w_mode == CACHE_WRITE_BACK) {
189 ARMword t;
190
191 /*if cache valid, try to write back */
192 if (cache->tag & TAG_VALID_FLAG) {
193 mmu_cache_write_back (state, cache_t, cache);
194 }
195 /*read in cache_line */
196 t = pa;
197 for (i = 0; i < (cache_t->width >> WORD_SHT);
198 i++, t += WORD_SIZE) {
199 //cache->data[i] = mem_read_word (state, t);
200 bus_read(32, t, &cache->data[i]);
201 }
202 }
203 /*store tag and pa */
204 cache->tag = va | TAG_VALID_FLAG;
205 cache->pa = pa;
206
207 return cache;
208};
209
210/* mmu_cache_write_back write cache data to memory
211 * @state
212 * @cache_t :cache_t of the cache line
213 * @cache : cache line
214 */
215void
216mmu_cache_write_back (ARMul_State * state, cache_s * cache_t,
217 cache_line_t * cache)
218{
219 ARMword pa = cache->pa;
220 int nw = cache_t->width >> WORD_SHT;
221 ARMword *data = cache->data;
222 int i;
223 int t0, t1, t2;
224
225 if ((cache->tag & 1) == 0)
226 return;
227
228 switch (cache->
229 tag & ~1 & (TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY)) {
230 case 0:
231 return;
232 case TAG_FIRST_HALF_DIRTY:
233 nw /= 2;
234 break;
235 case TAG_LAST_HALF_DIRTY:
236 nw /= 2;
237 pa += nw << WORD_SHT;
238 data += nw;
239 break;
240 case TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY:
241 break;
242 }
243 for (i = 0; i < nw; i++, data++, pa += WORD_SIZE)
244 //mem_write_word (state, pa, *data);
245 bus_write(32, pa, *data);
246
247 cache->tag &= ~(TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY);
248};
249
250
251/* mmu_cache_clean: clean a cache of va in cache_t
252 *
253 * @state :ARMul_State
254 * @cache_t :cache_t to clean
255 * @va :virtaul address
256 */
257void
258mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va)
259{
260 cache_line_t *cache;
261
262 cache = mmu_cache_search (state, cache_t, va);
263 if (cache)
264 mmu_cache_write_back (state, cache_t, cache);
265}
266
267/* mmu_cache_clean_by_index: clean a cache by set/index format value
268 *
269 * @state :ARMul_State
270 * @cache_t :cache_t to clean
271 * @va :set/index format value
272 */
273void
274mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t,
275 ARMword index)
276{
277 cache_line_t *cache;
278
279 cache = mmu_cache_search_by_index (state, cache_t, index);
280 if (cache)
281 mmu_cache_write_back (state, cache_t, cache);
282}
283
284/* mmu_cache_invalidate : invalidate a cache of va
285 *
286 * @state :ARMul_State
287 * @cache_t :cache_t to invalid
288 * @va :virt_addr to invalid
289 */
290void
291mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va)
292{
293 cache_line_t *cache;
294
295 cache = mmu_cache_search (state, cache_t, va);
296 if (cache) {
297 mmu_cache_write_back (state, cache_t, cache);
298 cache->tag = 0;
299 }
300}
301
302/* mmu_cache_invalidate_by_index : invalidate a cache by index format
303 *
304 * @state :ARMul_State
305 * @cache_t :cache_t to invalid
306 * @index :set/index data
307 */
308void
309mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t,
310 ARMword index)
311{
312 cache_line_t *cache;
313
314 cache = mmu_cache_search_by_index (state, cache_t, index);
315 if (cache) {
316 mmu_cache_write_back (state, cache_t, cache);
317 cache->tag = 0;
318 }
319}
320
321/* mmu_cache_invalidate_all
322 *
323 * @state:
324 * @cache_t
325 * */
326void
327mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t)
328{
329 int i, j;
330 cache_set_t *set;
331 cache_line_t *cache;
332
333 set = cache_t->sets;
334 for (i = 0; i < cache_t->set; i++, set++) {
335 cache = set->lines;
336 for (j = 0; j < cache_t->way; j++, cache++) {
337 mmu_cache_write_back (state, cache_t, cache);
338 cache->tag = 0;
339 }
340 }
341};
342
343void
344mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa)
345{
346 ARMword set, way;
347 cache_line_t *cache;
348 pa = (pa / cache_t->width);
349 way = pa & (cache_t->way - 1);
350 set = (pa / cache_t->way) & (cache_t->set - 1);
351 cache = &cache_t->sets[set].lines[way];
352
353 mmu_cache_write_back (state, cache_t, cache);
354 cache->tag = 0;
355}
356
357cache_line_t* mmu_cache_dirty_cache(ARMul_State *state,cache_s *cache){
358 int i;
359 int j;
360 cache_line_t *cache_line = NULL;
361 cache_set_t *cache_set = cache->sets;
362 int sets = cache->set;
363 for (i = 0; i < sets; i++){
364 for(j = 0,cache_line = &cache_set[i].lines[0]; j < cache->way; j++,cache_line++){
365 if((cache_line->tag & TAG_FIRST_HALF_DIRTY) || (cache_line->tag & TAG_LAST_HALF_DIRTY))
366 return cache_line;
367 }
368 }
369 return NULL;
370}
diff --git a/src/core/arm/interpreter/mmu/rb.cpp b/src/core/arm/interpreter/mmu/rb.cpp
new file mode 100644
index 000000000..07b11e311
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/rb.cpp
@@ -0,0 +1,126 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu*/
4ARMword rb_masks[] = {
5 0x0, //RB_INVALID
6 4, //RB_1
7 16, //RB_4
8 32, //RB_8
9};
10
11/*mmu_rb_init
12 * @rb_t :rb_t to init
13 * @num :number of entry
14 * */
15int
16mmu_rb_init (rb_s * rb_t, int num)
17{
18 int i;
19 rb_entry_t *entrys;
20
21 entrys = (rb_entry_t *) malloc (sizeof (*entrys) * num);
22 if (entrys == NULL) {
23 printf ("SKYEYE:mmu_rb_init malloc error\n");
24 return -1;
25 }
26 for (i = 0; i < num; i++) {
27 entrys[i].type = RB_INVALID;
28 entrys[i].fault = NO_FAULT;
29 }
30
31 rb_t->entrys = entrys;
32 rb_t->num = num;
33 return 0;
34}
35
36/*mmu_rb_exit*/
37void
38mmu_rb_exit (rb_s * rb_t)
39{
40 free (rb_t->entrys);
41};
42
43/*mmu_rb_search
44 * @rb_t :rb_t to serach
45 * @va :va address to math
46 *
47 * $ NULL :not match
48 * NO-NULL:
49 * */
50rb_entry_t *
51mmu_rb_search (rb_s * rb_t, ARMword va)
52{
53 int i;
54 rb_entry_t *rb = rb_t->entrys;
55
56 DEBUG_LOG(ARM11, "va = %x\n", va);
57 for (i = 0; i < rb_t->num; i++, rb++) {
58 //2004-06-06 lyh bug from wenye@cs.ucsb.edu
59 if (rb->type) {
60 if ((va >= rb->va)
61 && (va < (rb->va + rb_masks[rb->type])))
62 return rb;
63 }
64 }
65 return NULL;
66};
67
68void
69mmu_rb_invalidate_entry (rb_s * rb_t, int i)
70{
71 rb_t->entrys[i].type = RB_INVALID;
72}
73
74void
75mmu_rb_invalidate_all (rb_s * rb_t)
76{
77 int i;
78
79 for (i = 0; i < rb_t->num; i++)
80 mmu_rb_invalidate_entry (rb_t, i);
81};
82
83void
84mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb, int type, ARMword va)
85{
86 rb_entry_t *rb;
87 int i;
88 ARMword max_start, min_end;
89 fault_t fault;
90 tlb_entry_t *tlb;
91
92 /*align va according to type */
93 va &= ~(rb_masks[type] - 1);
94 /*invalidate all RB match [va, va + rb_masks[type]] */
95 for (rb = rb_t->entrys, i = 0; i < rb_t->num; i++, rb++) {
96 if (rb->type) {
97 max_start = max (va, rb->va);
98 min_end =
99 min (va + rb_masks[type],
100 rb->va + rb_masks[rb->type]);
101 if (max_start < min_end)
102 rb->type = RB_INVALID;
103 }
104 }
105 /*load word */
106 rb = &rb_t->entrys[i_rb];
107 rb->type = type;
108 fault = translate (state, va, D_TLB (), &tlb);
109 if (fault) {
110 rb->fault = fault;
111 return;
112 }
113 fault = check_access (state, va, tlb, 1);
114 if (fault) {
115 rb->fault = fault;
116 return;
117 }
118
119 rb->fault = NO_FAULT;
120 va = tlb_va_to_pa (tlb, va);
121 //2004-06-06 lyh bug from wenye@cs.ucsb.edu
122 for (i = 0; i < (rb_masks[type] / 4); i++, va += WORD_SIZE) {
123 //rb->data[i] = mem_read_word (state, va);
124 bus_read(32, va, &rb->data[i]);
125 };
126}
diff --git a/src/core/arm/interpreter/mmu/sa_mmu.cpp b/src/core/arm/interpreter/mmu/sa_mmu.cpp
new file mode 100644
index 000000000..eff5002de
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/sa_mmu.cpp
@@ -0,0 +1,864 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#include <assert.h>
22#include <string.h>
23
24#include "core/arm/interpreter/armdefs.h"
25
26/**
27 * The interface of read data from bus
28 */
29int bus_read(short size, int addr, uint32_t * value) {
30 ERROR_LOG(ARM11, "unimplemented bus_read");
31 return 0;
32}
33
34/**
35 * The interface of write data from bus
36 */
37int bus_write(short size, int addr, uint32_t value) {
38 ERROR_LOG(ARM11, "unimplemented bus_write");
39 return 0;
40}
41
42
43typedef struct sa_mmu_desc_s
44{
45 int i_tlb;
46 cache_desc_t i_cache;
47
48 int d_tlb;
49 cache_desc_t main_d_cache;
50 cache_desc_t mini_d_cache;
51 int rb;
52 wb_desc_t wb;
53} sa_mmu_desc_t;
54
55static sa_mmu_desc_t sa11xx_mmu_desc = {
56 32,
57 {32, 32, 16, CACHE_WRITE_BACK},
58
59 32,
60 {32, 32, 8, CACHE_WRITE_BACK},
61 {32, 2, 8, CACHE_WRITE_BACK},
62 4,
63 //{8, 4}, for word size
64 {8, 16}, //for byte size, chy 2003-07-11
65};
66
67static fault_t sa_mmu_write (ARMul_State * state, ARMword va, ARMword data,
68 ARMword datatype);
69static fault_t sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
70 ARMword datatype);
71static fault_t update_cache (ARMul_State * state, ARMword va, ARMword data,
72 ARMword datatype, cache_line_t * cache,
73 cache_s * cache_t, ARMword real_va);
74
75void
76mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa,
77 ARMbyte * data, int n);
78int
79sa_mmu_init (ARMul_State * state)
80{
81 sa_mmu_desc_t *desc;
82 cache_desc_t *c_desc;
83
84 state->mmu.control = 0x70;
85 state->mmu.translation_table_base = 0xDEADC0DE;
86 state->mmu.domain_access_control = 0xDEADC0DE;
87 state->mmu.fault_status = 0;
88 state->mmu.fault_address = 0;
89 state->mmu.process_id = 0;
90
91 desc = &sa11xx_mmu_desc;
92 if (mmu_tlb_init (I_TLB (), desc->i_tlb)) {
93 ERROR_LOG(ARM11, "i_tlb init %d\n", -1);
94 goto i_tlb_init_error;
95 }
96
97 c_desc = &desc->i_cache;
98 if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
99 c_desc->set, c_desc->w_mode)) {
100 ERROR_LOG(ARM11, "i_cache init %d\n", -1);
101 goto i_cache_init_error;
102 }
103
104 if (mmu_tlb_init (D_TLB (), desc->d_tlb)) {
105 ERROR_LOG(ARM11, "d_tlb init %d\n", -1);
106 goto d_tlb_init_error;
107 }
108
109 c_desc = &desc->main_d_cache;
110 if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
111 c_desc->set, c_desc->w_mode)) {
112 ERROR_LOG(ARM11, "main_d_cache init %d\n", -1);
113 goto main_d_cache_init_error;
114 }
115
116 c_desc = &desc->mini_d_cache;
117 if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
118 c_desc->set, c_desc->w_mode)) {
119 ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1);
120 goto mini_d_cache_init_error;
121 }
122
123 if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) {
124 ERROR_LOG(ARM11, "wb init %d\n", -1);
125 goto wb_init_error;
126 }
127
128 if (mmu_rb_init (RB (), desc->rb)) {
129 ERROR_LOG(ARM11, "rb init %d\n", -1);
130 goto rb_init_error;
131 }
132 return 0;
133
134 rb_init_error:
135 mmu_wb_exit (WB ());
136 wb_init_error:
137 mmu_cache_exit (MINI_D_CACHE ());
138 mini_d_cache_init_error:
139 mmu_cache_exit (MAIN_D_CACHE ());
140 main_d_cache_init_error:
141 mmu_tlb_exit (D_TLB ());
142 d_tlb_init_error:
143 mmu_cache_exit (I_CACHE ());
144 i_cache_init_error:
145 mmu_tlb_exit (I_TLB ());
146 i_tlb_init_error:
147 return -1;
148}
149
150void
151sa_mmu_exit (ARMul_State * state)
152{
153 mmu_rb_exit (RB ());
154 mmu_wb_exit (WB ());
155 mmu_cache_exit (MINI_D_CACHE ());
156 mmu_cache_exit (MAIN_D_CACHE ());
157 mmu_tlb_exit (D_TLB ());
158 mmu_cache_exit (I_CACHE ());
159 mmu_tlb_exit (I_TLB ());
160};
161
162
163static fault_t
164sa_mmu_load_instr (ARMul_State * state, ARMword va, ARMword * instr)
165{
166 fault_t fault;
167 tlb_entry_t *tlb;
168 cache_line_t *cache;
169 int c; //cache bit
170 ARMword pa; //physical addr
171
172 static int debug_count = 0; //used for debug
173
174 DEBUG_LOG(ARM11, "va = %x\n", va);
175
176 va = mmu_pid_va_map (va);
177 if (MMU_Enabled) {
178 /*align check */
179 if ((va & (WORD_SIZE - 1)) && MMU_Aligned) {
180 DEBUG_LOG(ARM11, "align\n");
181 return ALIGNMENT_FAULT;
182 }
183 else
184 va &= ~(WORD_SIZE - 1);
185
186 /*translate tlb */
187 fault = translate (state, va, I_TLB (), &tlb);
188 if (fault) {
189 DEBUG_LOG(ARM11, "translate\n");
190 return fault;
191 }
192
193 /*check access */
194 fault = check_access (state, va, tlb, 1);
195 if (fault) {
196 DEBUG_LOG(ARM11, "check_fault\n");
197 return fault;
198 }
199 }
200
201 /*search cache no matter MMU enabled/disabled */
202 cache = mmu_cache_search (state, I_CACHE (), va);
203 if (cache) {
204 *instr = cache->data[va_cache_index (va, I_CACHE ())];
205 return NO_FAULT;
206 }
207
208 /*if MMU disabled or C flag is set alloc cache */
209 if (MMU_Disabled) {
210 c = 1;
211 pa = va;
212 }
213 else {
214 c = tlb_c_flag (tlb);
215 pa = tlb_va_to_pa (tlb, va);
216 }
217
218 if (c) {
219 int index;
220
221 debug_count++;
222 cache = mmu_cache_alloc (state, I_CACHE (), va, pa);
223 index = va_cache_index (va, I_CACHE ());
224 *instr = cache->data[va_cache_index (va, I_CACHE ())];
225 }
226 else
227 //*instr = mem_read_word (state, pa);
228 bus_read(32, pa, instr);
229
230 return NO_FAULT;
231};
232
233
234
235static fault_t
236sa_mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
237{
238 //ARMword temp,offset;
239 fault_t fault;
240 fault = sa_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
241 return fault;
242}
243
244static fault_t
245sa_mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
246{
247 //ARMword temp,offset;
248 fault_t fault;
249 fault = sa_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
250 return fault;
251}
252
253static fault_t
254sa_mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
255{
256 return sa_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
257}
258
259
260
261
262static fault_t
263sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
264 ARMword datatype)
265{
266 fault_t fault;
267 rb_entry_t *rb;
268 tlb_entry_t *tlb;
269 cache_line_t *cache;
270 ARMword pa, real_va, temp, offset;
271
272 DEBUG_LOG(ARM11, "va = %x\n", va);
273
274 va = mmu_pid_va_map (va);
275 real_va = va;
276 /*if MMU disabled, memory_read */
277 if (MMU_Disabled) {
278 //*data = mem_read_word(state, va);
279 if (datatype == ARM_BYTE_TYPE)
280 //*data = mem_read_byte (state, va);
281 bus_read(8, va, data);
282 else if (datatype == ARM_HALFWORD_TYPE)
283 //*data = mem_read_halfword (state, va);
284 bus_read(16, va, data);
285 else if (datatype == ARM_WORD_TYPE)
286 //*data = mem_read_word (state, va);
287 bus_read(32, va, data);
288 else {
289 printf ("SKYEYE:1 sa_mmu_read error: unknown data type %d\n", datatype);
290 // skyeye_exit (-1);
291 }
292
293 return NO_FAULT;
294 }
295
296 /*align check */
297 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
298 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
299 DEBUG_LOG(ARM11, "align\n");
300 return ALIGNMENT_FAULT;
301 } // else
302
303 va &= ~(WORD_SIZE - 1);
304
305 /*translate va to tlb */
306 fault = translate (state, va, D_TLB (), &tlb);
307 if (fault) {
308 DEBUG_LOG(ARM11, "translate\n");
309 return fault;
310 }
311 /*check access permission */
312 fault = check_access (state, va, tlb, 1);
313 if (fault)
314 return fault;
315 /*search in read buffer */
316 rb = mmu_rb_search (RB (), va);
317 if (rb) {
318 if (rb->fault)
319 return rb->fault;
320 *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT];
321 goto datatrans;
322 //return 0;
323 };
324 /*search main cache */
325 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
326 if (cache) {
327 *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())];
328 goto datatrans;
329 //return 0;
330 }
331 /*search mini cache */
332 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
333 if (cache) {
334 *data = cache->data[va_cache_index (va, MINI_D_CACHE ())];
335 goto datatrans;
336 //return 0;
337 }
338
339 /*get phy_addr */
340 pa = tlb_va_to_pa (tlb, va);
341 if ((pa >= 0xe0000000) && (pa < 0xe8000000)) {
342 if (tlb_c_flag (tlb)) {
343 if (tlb_b_flag (tlb)) {
344 mmu_cache_soft_flush (state, MAIN_D_CACHE (),
345 pa);
346 }
347 else {
348 mmu_cache_soft_flush (state, MINI_D_CACHE (),
349 pa);
350 }
351 }
352 return NO_FAULT;
353 }
354
355 /*if Buffer, drain Write Buffer first */
356 if (tlb_b_flag (tlb))
357 mmu_wb_drain_all (state, WB ());
358
359 /*alloc cache or mem_read */
360 if (tlb_c_flag (tlb) && MMU_DCacheEnabled) {
361 cache_s *cache_t;
362
363 if (tlb_b_flag (tlb))
364 cache_t = MAIN_D_CACHE ();
365 else
366 cache_t = MINI_D_CACHE ();
367 cache = mmu_cache_alloc (state, cache_t, va, pa);
368 *data = cache->data[va_cache_index (va, cache_t)];
369 }
370 else {
371 //*data = mem_read_word(state, pa);
372 if (datatype == ARM_BYTE_TYPE)
373 //*data = mem_read_byte (state, pa | (real_va & 3));
374 bus_read(8, pa | (real_va & 3), data);
375 else if (datatype == ARM_HALFWORD_TYPE)
376 //*data = mem_read_halfword (state, pa | (real_va & 2));
377 bus_read(16, pa | (real_va & 2), data);
378 else if (datatype == ARM_WORD_TYPE)
379 //*data = mem_read_word (state, pa);
380 bus_read(32, pa, data);
381 else {
382 printf ("SKYEYE:2 sa_mmu_read error: unknown data type %d\n", datatype);
383 // skyeye_exit (-1);
384 }
385 return NO_FAULT;
386 }
387
388
389 datatrans:
390 if (datatype == ARM_HALFWORD_TYPE) {
391 temp = *data;
392 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
393 *data = (temp >> offset) & 0xffff;
394 }
395 else if (datatype == ARM_BYTE_TYPE) {
396 temp = *data;
397 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
398 *data = (temp >> offset & 0xffL);
399 }
400 end:
401 return NO_FAULT;
402}
403
404
405static fault_t
406sa_mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
407{
408 return sa_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
409}
410
411static fault_t
412sa_mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
413{
414 return sa_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
415}
416
417static fault_t
418sa_mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
419{
420 return sa_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
421}
422
423
424
425static fault_t
426sa_mmu_write (ARMul_State * state, ARMword va, ARMword data, ARMword datatype)
427{
428 tlb_entry_t *tlb;
429 cache_line_t *cache;
430 int b;
431 ARMword pa, real_va;
432 fault_t fault;
433
434 DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
435 va = mmu_pid_va_map (va);
436 real_va = va;
437
438 /*search instruction cache */
439 cache = mmu_cache_search (state, I_CACHE (), va);
440 if (cache) {
441 update_cache (state, va, data, datatype, cache, I_CACHE (),
442 real_va);
443 }
444
445 if (MMU_Disabled) {
446 //mem_write_word(state, va, data);
447 if (datatype == ARM_BYTE_TYPE)
448 //mem_write_byte (state, va, data);
449 bus_write(8, va, data);
450 else if (datatype == ARM_HALFWORD_TYPE)
451 //mem_write_halfword (state, va, data);
452 bus_write(16, va, data);
453 else if (datatype == ARM_WORD_TYPE)
454 //mem_write_word (state, va, data);
455 bus_write(32, va, data);
456 else {
457 printf ("SKYEYE:1 sa_mmu_write error: unknown data type %d\n", datatype);
458 // skyeye_exit (-1);
459 }
460
461 return NO_FAULT;
462 }
463 /*align check */
464 //if ((va & (WORD_SIZE - 1)) && MMU_Aligned){
465 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
466 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
467 DEBUG_LOG(ARM11, "align\n");
468 return ALIGNMENT_FAULT;
469 } //else
470 va &= ~(WORD_SIZE - 1);
471 /*tlb translate */
472 fault = translate (state, va, D_TLB (), &tlb);
473 if (fault) {
474 DEBUG_LOG(ARM11, "translate\n");
475 return fault;
476 }
477 /*tlb check access */
478 fault = check_access (state, va, tlb, 0);
479 if (fault) {
480 DEBUG_LOG(ARM11, "check_access\n");
481 return fault;
482 }
483 /*search main cache */
484 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
485 if (cache) {
486 update_cache (state, va, data, datatype, cache,
487 MAIN_D_CACHE (), real_va);
488 }
489 else {
490 /*search mini cache */
491 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
492 if (cache) {
493 update_cache (state, va, data, datatype, cache,
494 MINI_D_CACHE (), real_va);
495 }
496 }
497
498 if (!cache) {
499 b = tlb_b_flag (tlb);
500 pa = tlb_va_to_pa (tlb, va);
501 if (b) {
502 if (MMU_WBEnabled) {
503 if (datatype == ARM_WORD_TYPE)
504 mmu_wb_write_bytes (state, WB (), pa,
505 (ARMbyte*)&data, 4);
506 else if (datatype == ARM_HALFWORD_TYPE)
507 mmu_wb_write_bytes (state, WB (),
508 (pa |
509 (real_va & 2)),
510 (ARMbyte*)&data, 2);
511 else if (datatype == ARM_BYTE_TYPE)
512 mmu_wb_write_bytes (state, WB (),
513 (pa |
514 (real_va & 3)),
515 (ARMbyte*)&data, 1);
516
517 }
518 else {
519 if (datatype == ARM_WORD_TYPE)
520 //mem_write_word (state, pa, data);
521 bus_write(32, pa, data);
522 else if (datatype == ARM_HALFWORD_TYPE)
523 /*
524 mem_write_halfword (state,
525 (pa |
526 (real_va & 2)),
527 data);
528 */
529 bus_write(16, pa | (real_va & 2), data);
530 else if (datatype == ARM_BYTE_TYPE)
531 /*
532 mem_write_byte (state,
533 (pa | (real_va & 3)),
534 data);
535 */
536 bus_write(8, pa | (real_va & 3), data);
537 }
538 }
539 else {
540 mmu_wb_drain_all (state, WB ());
541
542 if (datatype == ARM_WORD_TYPE)
543 //mem_write_word (state, pa, data);
544 bus_write(32, pa, data);
545 else if (datatype == ARM_HALFWORD_TYPE)
546 /*
547 mem_write_halfword (state,
548 (pa | (real_va & 2)),
549 data);
550 */
551 bus_write(16, pa | (real_va & 2), data);
552 else if (datatype == ARM_BYTE_TYPE)
553 /*
554 mem_write_byte (state, (pa | (real_va & 3)),
555 data);
556 */
557 bus_write(8, pa | (real_va & 3), data);
558 }
559 }
560 return NO_FAULT;
561}
562
563static fault_t
564update_cache (ARMul_State * state, ARMword va, ARMword data, ARMword datatype,
565 cache_line_t * cache, cache_s * cache_t, ARMword real_va)
566{
567 ARMword temp, offset;
568
569 ARMword index = va_cache_index (va, cache_t);
570
571 //cache->data[index] = data;
572
573 if (datatype == ARM_WORD_TYPE)
574 cache->data[index] = data;
575 else if (datatype == ARM_HALFWORD_TYPE) {
576 temp = cache->data[index];
577 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
578 cache->data[index] =
579 (temp & ~(0xffffL << offset)) | ((data & 0xffffL) <<
580 offset);
581 }
582 else if (datatype == ARM_BYTE_TYPE) {
583 temp = cache->data[index];
584 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
585 cache->data[index] =
586 (temp & ~(0xffL << offset)) | ((data & 0xffL) <<
587 offset);
588 }
589
590 if (index < (cache_t->width >> (WORD_SHT + 1)))
591 cache->tag |= TAG_FIRST_HALF_DIRTY;
592 else
593 cache->tag |= TAG_LAST_HALF_DIRTY;
594
595 return NO_FAULT;
596}
597
598ARMword
599sa_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
600{
601 mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15);
602 ARMword data;
603
604 switch (creg) {
605 case MMU_ID:
606// printf("mmu_mrc read ID ");
607 data = 0x41007100; /* v3 */
608 data = state->cpu->cpu_val;
609 break;
610 case MMU_CONTROL:
611// printf("mmu_mrc read CONTROL");
612 data = state->mmu.control;
613 break;
614 case MMU_TRANSLATION_TABLE_BASE:
615// printf("mmu_mrc read TTB ");
616 data = state->mmu.translation_table_base;
617 break;
618 case MMU_DOMAIN_ACCESS_CONTROL:
619// printf("mmu_mrc read DACR ");
620 data = state->mmu.domain_access_control;
621 break;
622 case MMU_FAULT_STATUS:
623// printf("mmu_mrc read FSR ");
624 data = state->mmu.fault_status;
625 break;
626 case MMU_FAULT_ADDRESS:
627// printf("mmu_mrc read FAR ");
628 data = state->mmu.fault_address;
629 break;
630 case MMU_PID:
631 data = state->mmu.process_id;
632 default:
633 printf ("mmu_mrc read UNKNOWN - reg %d\n", creg);
634 data = 0;
635 break;
636 }
637// printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]);
638 *value = data;
639 return data;
640}
641
642void
643sa_mmu_cache_ops (ARMul_State * state, ARMword instr, ARMword value)
644{
645 int CRm, OPC_2;
646
647 CRm = BITS (0, 3);
648 OPC_2 = BITS (5, 7);
649
650 if (OPC_2 == 0 && CRm == 7) {
651 mmu_cache_invalidate_all (state, I_CACHE ());
652 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
653 mmu_cache_invalidate_all (state, MINI_D_CACHE ());
654 return;
655 }
656
657 if (OPC_2 == 0 && CRm == 5) {
658 mmu_cache_invalidate_all (state, I_CACHE ());
659 return;
660 }
661
662 if (OPC_2 == 0 && CRm == 6) {
663 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
664 mmu_cache_invalidate_all (state, MINI_D_CACHE ());
665 return;
666 }
667
668 if (OPC_2 == 1 && CRm == 6) {
669 mmu_cache_invalidate (state, MAIN_D_CACHE (), value);
670 mmu_cache_invalidate (state, MINI_D_CACHE (), value);
671 return;
672 }
673
674 if (OPC_2 == 1 && CRm == 0xa) {
675 mmu_cache_clean (state, MAIN_D_CACHE (), value);
676 mmu_cache_clean (state, MINI_D_CACHE (), value);
677 return;
678 }
679
680 if (OPC_2 == 4 && CRm == 0xa) {
681 mmu_wb_drain_all (state, WB ());
682 return;
683 }
684 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
685}
686
687static void
688sa_mmu_tlb_ops (ARMul_State * state, ARMword instr, ARMword value)
689{
690 int CRm, OPC_2;
691
692 CRm = BITS (0, 3);
693 OPC_2 = BITS (5, 7);
694
695
696 if (OPC_2 == 0 && CRm == 0x7) {
697 mmu_tlb_invalidate_all (state, I_TLB ());
698 mmu_tlb_invalidate_all (state, D_TLB ());
699 return;
700 }
701
702 if (OPC_2 == 0 && CRm == 0x5) {
703 mmu_tlb_invalidate_all (state, I_TLB ());
704 return;
705 }
706
707 if (OPC_2 == 0 && CRm == 0x6) {
708 mmu_tlb_invalidate_all (state, D_TLB ());
709 return;
710 }
711
712 if (OPC_2 == 1 && CRm == 0x6) {
713 mmu_tlb_invalidate_entry (state, D_TLB (), value);
714 return;
715 }
716
717 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
718}
719
720static void
721sa_mmu_rb_ops (ARMul_State * state, ARMword instr, ARMword value)
722{
723 int CRm, OPC_2;
724
725 CRm = BITS (0, 3);
726 OPC_2 = BITS (5, 7);
727
728 if (OPC_2 == 0x0 && CRm == 0x0) {
729 mmu_rb_invalidate_all (RB ());
730 return;
731 }
732
733 if (OPC_2 == 0x2) {
734 int idx = CRm & 0x3;
735 int type = ((CRm >> 2) & 0x3) + 1;
736
737 if ((idx < 4) && (type < 4))
738 mmu_rb_load (state, RB (), idx, type, value);
739 return;
740 }
741
742 if ((OPC_2 == 1) && (CRm < 4)) {
743 mmu_rb_invalidate_entry (RB (), CRm);
744 return;
745 }
746
747 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
748}
749
750static ARMword
751sa_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
752{
753 mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15);
754 if (!strncmp (state->cpu->cpu_arch_name, "armv4", 5)) {
755 switch (creg) {
756 case MMU_CONTROL:
757// printf("mmu_mcr wrote CONTROL ");
758 state->mmu.control = (value | 0x70) & 0xFFFD;
759 break;
760 case MMU_TRANSLATION_TABLE_BASE:
761// printf("mmu_mcr wrote TTB ");
762 state->mmu.translation_table_base =
763 value & 0xFFFFC000;
764 break;
765 case MMU_DOMAIN_ACCESS_CONTROL:
766// printf("mmu_mcr wrote DACR ");
767 state->mmu.domain_access_control = value;
768 break;
769
770 case MMU_FAULT_STATUS:
771 state->mmu.fault_status = value & 0xFF;
772 break;
773 case MMU_FAULT_ADDRESS:
774 state->mmu.fault_address = value;
775 break;
776
777 case MMU_CACHE_OPS:
778 sa_mmu_cache_ops (state, instr, value);
779 break;
780 case MMU_TLB_OPS:
781 sa_mmu_tlb_ops (state, instr, value);
782 break;
783 case MMU_SA_RB_OPS:
784 sa_mmu_rb_ops (state, instr, value);
785 break;
786 case MMU_SA_DEBUG:
787 break;
788 case MMU_SA_CP15_R15:
789 break;
790 case MMU_PID:
791 //2004-06-06 lyh, bug provided by wen ye wenye@cs.ucsb.edu
792 state->mmu.process_id = value & 0x7e000000;
793 break;
794
795 default:
796 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
797 break;
798 }
799 }
800 return 0;
801}
802
803//teawater add for arm2x86 2005.06.24-------------------------------------------
804static int
805sa_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
806{
807 fault_t fault;
808 tlb_entry_t *tlb;
809
810 virt_addr = mmu_pid_va_map (virt_addr);
811 if (MMU_Enabled) {
812
813 /*align check */
814 if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
815 DEBUG_LOG(ARM11, "align\n");
816 return ALIGNMENT_FAULT;
817 }
818 else
819 virt_addr &= ~(WORD_SIZE - 1);
820
821 /*translate tlb */
822 fault = translate (state, virt_addr, I_TLB (), &tlb);
823 if (fault) {
824 DEBUG_LOG(ARM11, "translate\n");
825 return fault;
826 }
827
828 /*check access */
829 fault = check_access (state, virt_addr, tlb, 1);
830 if (fault) {
831 DEBUG_LOG(ARM11, "check_fault\n");
832 return fault;
833 }
834 }
835
836 if (MMU_Disabled) {
837 *phys_addr = virt_addr;
838 }
839 else {
840 *phys_addr = tlb_va_to_pa (tlb, virt_addr);
841 }
842
843 return (0);
844}
845
846//AJ2D--------------------------------------------------------------------------
847
848/*sa mmu_ops_t*/
849mmu_ops_t sa_mmu_ops = {
850 sa_mmu_init,
851 sa_mmu_exit,
852 sa_mmu_read_byte,
853 sa_mmu_write_byte,
854 sa_mmu_read_halfword,
855 sa_mmu_write_halfword,
856 sa_mmu_read_word,
857 sa_mmu_write_word,
858 sa_mmu_load_instr,
859 sa_mmu_mcr,
860 sa_mmu_mrc,
861//teawater add for arm2x86 2005.06.24-------------------------------------------
862 sa_mmu_v2p_dbct,
863//AJ2D--------------------------------------------------------------------------
864};
diff --git a/src/core/arm/interpreter/mmu/sa_mmu.h b/src/core/arm/interpreter/mmu/sa_mmu.h
new file mode 100644
index 000000000..64b1c5470
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/sa_mmu.h
@@ -0,0 +1,58 @@
1/*
2 sa_mmu.h - StrongARM Memory Management Unit emulation.
3 ARMulator extensions for SkyEye.
4 <lyhost@263.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#ifndef _SA_MMU_H_
22#define _SA_MMU_H_
23
24
25/**
26 * The interface of read data from bus
27 */
28int bus_read(short size, int addr, uint32_t * value);
29
30/**
31 * The interface of write data from bus
32 */
33int bus_write(short size, int addr, uint32_t value);
34
35
36typedef struct sa_mmu_s
37{
38 tlb_s i_tlb;
39 cache_s i_cache;
40
41 tlb_s d_tlb;
42 cache_s main_d_cache;
43 cache_s mini_d_cache;
44 rb_s rb_t;
45 wb_s wb_t;
46} sa_mmu_t;
47
48#define I_TLB() (&state->mmu.u.sa_mmu.i_tlb)
49#define I_CACHE() (&state->mmu.u.sa_mmu.i_cache)
50
51#define D_TLB() (&state->mmu.u.sa_mmu.d_tlb)
52#define MAIN_D_CACHE() (&state->mmu.u.sa_mmu.main_d_cache)
53#define MINI_D_CACHE() (&state->mmu.u.sa_mmu.mini_d_cache)
54#define WB() (&state->mmu.u.sa_mmu.wb_t)
55#define RB() (&state->mmu.u.sa_mmu.rb_t)
56
57extern mmu_ops_t sa_mmu_ops;
58#endif /*_SA_MMU_H_*/
diff --git a/src/core/arm/interpreter/mmu/tlb.cpp b/src/core/arm/interpreter/mmu/tlb.cpp
new file mode 100644
index 000000000..ca60ac1a1
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/tlb.cpp
@@ -0,0 +1,307 @@
1#include <assert.h>
2
3#include "core/arm/interpreter/armdefs.h"
4
5ARMword tlb_masks[] = {
6 0x00000000, /* TLB_INVALID */
7 0xFFFFF000, /* TLB_SMALLPAGE */
8 0xFFFF0000, /* TLB_LARGEPAGE */
9 0xFFF00000, /* TLB_SECTION */
10 0xFFFFF000, /*TLB_ESMALLPAGE, have TEX attirbute, only for XScale */
11 0xFFFFFC00 /* TLB_TINYPAGE */
12};
13
14/* This function encodes table 8-2 Interpreting AP bits,
15 returning non-zero if access is allowed. */
16static int
17check_perms (ARMul_State * state, int ap, int read)
18{
19 int s, r, user;
20
21 s = state->mmu.control & CONTROL_SYSTEM;
22 r = state->mmu.control & CONTROL_ROM;
23 //chy 2006-02-15 , should consider system mode, don't conside 26bit mode
24 user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE);
25
26 switch (ap) {
27 case 0:
28 return read && ((s && !user) || r);
29 case 1:
30 return !user;
31 case 2:
32 return read || !user;
33 case 3:
34 return 1;
35 }
36 return 0;
37}
38
39fault_t
40check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
41 int read)
42{
43 int access;
44
45 state->mmu.last_domain = tlb->domain;
46 access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3;
47 if ((access == 0) || (access == 2)) {
48 /* It's unclear from the documentation whether this
49 should always raise a section domain fault, or if
50 it should be a page domain fault in the case of an
51 L1 that describes a page table. In the ARM710T
52 datasheets, "Figure 8-9: Sequence for checking faults"
53 seems to indicate the former, while "Table 8-4: Priority
54 encoding of fault status" gives a value for FS[3210] in
55 the event of a domain fault for a page. Hmm. */
56 return SECTION_DOMAIN_FAULT;
57 }
58 if (access == 1) {
59 /* client access - check perms */
60 int subpage, ap;
61
62 switch (tlb->mapping) {
63 /*ks 2004-05-09
64 * only for XScale
65 * Extend Small Page(ESP) Format
66 * 31-12 bits the base addr of ESP
67 * 11-10 bits SBZ
68 * 9-6 bits TEX
69 * 5-4 bits AP
70 * 3 bit C
71 * 2 bit B
72 * 1-0 bits 11
73 * */
74 case TLB_ESMALLPAGE: //xj
75 subpage = 0;
76 //printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr );
77 break;
78
79 case TLB_TINYPAGE:
80 subpage = 0;
81 //printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr );
82 break;
83
84 case TLB_SMALLPAGE:
85 subpage = (virt_addr >> 10) & 3;
86 break;
87 case TLB_LARGEPAGE:
88 subpage = (virt_addr >> 14) & 3;
89 break;
90 case TLB_SECTION:
91 subpage = 3;
92 break;
93 default:
94 assert (0);
95 subpage = 0; /* cleans a warning */
96 }
97 ap = (tlb->perms >> (subpage * 2 + 4)) & 3;
98 if (!check_perms (state, ap, read)) {
99 if (tlb->mapping == TLB_SECTION) {
100 return SECTION_PERMISSION_FAULT;
101 }
102 else {
103 return SUBPAGE_PERMISSION_FAULT;
104 }
105 }
106 }
107 else { /* access == 3 */
108 /* manager access - don't check perms */
109 }
110 return NO_FAULT;
111}
112
113fault_t
114translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
115 tlb_entry_t ** tlb)
116{
117 *tlb = mmu_tlb_search (state, tlb_t, virt_addr);
118 if (!*tlb) {
119 /* walk the translation tables */
120 ARMword l1addr, l1desc;
121 tlb_entry_t entry;
122
123 l1addr = state->mmu.translation_table_base & 0xFFFFC000;
124 l1addr = (l1addr | (virt_addr >> 18)) & ~3;
125 //l1desc = mem_read_word (state, l1addr);
126 bus_read(32, l1addr, &l1desc);
127 switch (l1desc & 3) {
128 case 0:
129 /*
130 * according to Figure 3-9 Sequence for checking faults in arm manual,
131 * section translation fault should be returned here.
132 */
133 {
134 return SECTION_TRANSLATION_FAULT;
135 }
136 case 3:
137 /* fine page table */
138 // dcl 2006-01-08
139 {
140 ARMword l2addr, l2desc;
141
142 l2addr = l1desc & 0xFFFFF000;
143 l2addr = (l2addr |
144 ((virt_addr & 0x000FFC00) >> 8)) &
145 ~3;
146 //l2desc = mem_read_word (state, l2addr);
147 bus_read(32, l2addr, &l2desc);
148
149 entry.virt_addr = virt_addr;
150 entry.phys_addr = l2desc;
151 entry.perms = l2desc & 0x00000FFC;
152 entry.domain = (l1desc >> 5) & 0x0000000F;
153 switch (l2desc & 3) {
154 case 0:
155 state->mmu.last_domain = entry.domain;
156 return PAGE_TRANSLATION_FAULT;
157 case 3:
158 entry.mapping = TLB_TINYPAGE;
159 break;
160 case 1:
161 // this is untested
162 entry.mapping = TLB_LARGEPAGE;
163 break;
164 case 2:
165 // this is untested
166 entry.mapping = TLB_SMALLPAGE;
167 break;
168 }
169 }
170 break;
171 case 1:
172 /* coarse page table */
173 {
174 ARMword l2addr, l2desc;
175
176 l2addr = l1desc & 0xFFFFFC00;
177 l2addr = (l2addr |
178 ((virt_addr & 0x000FF000) >> 10)) &
179 ~3;
180 //l2desc = mem_read_word (state, l2addr);
181 bus_read(32, l2addr, &l2desc);
182
183 entry.virt_addr = virt_addr;
184 entry.phys_addr = l2desc;
185 entry.perms = l2desc & 0x00000FFC;
186 entry.domain = (l1desc >> 5) & 0x0000000F;
187 //printf("SKYEYE:PAGE virt_addr = %x,l1desc=%x,phys_addr=%x\n",virt_addr,l1desc,entry.phys_addr);
188 //chy 2003-09-02 for xscale
189 switch (l2desc & 3) {
190 case 0:
191 state->mmu.last_domain = entry.domain;
192 return PAGE_TRANSLATION_FAULT;
193 case 3:
194 if (!state->is_XScale) {
195 state->mmu.last_domain =
196 entry.domain;
197 return PAGE_TRANSLATION_FAULT;
198 };
199 //ks 2004-05-09 xscale shold use Extend Small Page
200 //entry.mapping = TLB_SMALLPAGE;
201 entry.mapping = TLB_ESMALLPAGE; //xj
202 break;
203 case 1:
204 entry.mapping = TLB_LARGEPAGE;
205 break;
206 case 2:
207 entry.mapping = TLB_SMALLPAGE;
208 break;
209 }
210 }
211 break;
212 case 2:
213 /* section */
214 //printf("SKYEYE:WARNING: not implement section mapping incompletely\n");
215 //printf("SKYEYE:SECTION virt_addr = %x,l1desc=%x\n",virt_addr,l1desc);
216 //return SECTION_DOMAIN_FAULT;
217 //#if 0
218 entry.virt_addr = virt_addr;
219 entry.phys_addr = l1desc;
220 entry.perms = l1desc & 0x00000C0C;
221 entry.domain = (l1desc >> 5) & 0x0000000F;
222 entry.mapping = TLB_SECTION;
223 break;
224 //#endif
225 }
226 entry.virt_addr &= tlb_masks[entry.mapping];
227 entry.phys_addr &= tlb_masks[entry.mapping];
228
229 /* place entry in the tlb */
230 *tlb = &tlb_t->entrys[tlb_t->cycle];
231 tlb_t->cycle = (tlb_t->cycle + 1) % tlb_t->num;
232 **tlb = entry;
233 }
234 state->mmu.last_domain = (*tlb)->domain;
235 return NO_FAULT;
236}
237
238int
239mmu_tlb_init (tlb_s * tlb_t, int num)
240{
241 tlb_entry_t *e;
242 int i;
243
244 e = (tlb_entry_t *) malloc (sizeof (*e) * num);
245 if (e == NULL) {
246 ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*e) * num);
247 goto tlb_malloc_error;
248 }
249 tlb_t->entrys = e;
250 for (i = 0; i < num; i++, e++)
251 e->mapping = TLB_INVALID;
252 tlb_t->cycle = 0;
253 tlb_t->num = num;
254 return 0;
255
256 tlb_malloc_error:
257 return -1;
258}
259
260void
261mmu_tlb_exit (tlb_s * tlb_t)
262{
263 free (tlb_t->entrys);
264};
265
266void
267mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t)
268{
269 int entry;
270
271 for (entry = 0; entry < tlb_t->num; entry++) {
272 tlb_t->entrys[entry].mapping = TLB_INVALID;
273 }
274 tlb_t->cycle = 0;
275}
276
277void
278mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr)
279{
280 tlb_entry_t *tlb;
281
282 tlb = mmu_tlb_search (state, tlb_t, addr);
283 if (tlb) {
284 tlb->mapping = TLB_INVALID;
285 }
286}
287
288tlb_entry_t *
289mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t, ARMword virt_addr)
290{
291 int entry;
292
293 for (entry = 0; entry < tlb_t->num; entry++) {
294 tlb_entry_t *tlb;
295 ARMword mask;
296
297 tlb = &(tlb_t->entrys[entry]);
298 if (tlb->mapping == TLB_INVALID) {
299 continue;
300 }
301 mask = tlb_masks[tlb->mapping];
302 if ((virt_addr & mask) == (tlb->virt_addr & mask)) {
303 return tlb;
304 }
305 }
306 return NULL;
307}
diff --git a/src/core/arm/interpreter/mmu/tlb.h b/src/core/arm/interpreter/mmu/tlb.h
index 938c01786..40856567b 100644
--- a/src/core/arm/interpreter/mmu/tlb.h
+++ b/src/core/arm/interpreter/mmu/tlb.h
@@ -63,14 +63,7 @@ typedef struct tlb_s
63#define tlb_b_flag(tlb) \ 63#define tlb_b_flag(tlb) \
64 ((tlb)->perms & 0x4) 64 ((tlb)->perms & 0x4)
65 65
66#define tlb_va_to_pa(tlb, va) \ 66#define tlb_va_to_pa(tlb, va) ((tlb->phys_addr & tlb_masks[tlb->mapping]) | (va & ~tlb_masks[tlb->mapping]))
67(\
68 {\
69 ARMword mask = tlb_masks[tlb->mapping]; \
70 (tlb->phys_addr & mask) | (va & ~mask);\
71 }\
72)
73
74fault_t 67fault_t
75check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb, 68check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
76 int read); 69 int read);
diff --git a/src/core/arm/interpreter/mmu/wb.cpp b/src/core/arm/interpreter/mmu/wb.cpp
new file mode 100644
index 000000000..82c0cec02
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/wb.cpp
@@ -0,0 +1,149 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/* wb_init
4 * @wb_t :wb_t to init
5 * @num :num of entrys
6 * @nb :num of byte of each entry
7 *
8 * $ -1:error
9 * 0:ok
10 * */
11int
12mmu_wb_init (wb_s * wb_t, int num, int nb)
13{
14 int i;
15 wb_entry_t *entrys, *wb;
16
17 entrys = (wb_entry_t *) malloc (sizeof (*entrys) * num);
18 if (entrys == NULL) {
19 ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*entrys) * num);
20 goto entrys_malloc_error;
21 }
22
23 for (wb = entrys, i = 0; i < num; i++, wb++) {
24 /*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu */
25 //wb->data = (ARMword *)malloc(sizeof(ARMword) * nb);
26 wb->data = (ARMbyte *) malloc (nb);
27 if (wb->data == NULL) {
28 ERROR_LOG(ARM11, "malloc size of %d\n", nb);
29 goto data_malloc_error;
30 }
31
32 };
33
34 wb_t->first = wb_t->last = wb_t->used = 0;
35 wb_t->num = num;
36 wb_t->nb = nb;
37 wb_t->entrys = entrys;
38 return 0;
39
40 data_malloc_error:
41 while (--i >= 0)
42 free (entrys[i].data);
43 free (entrys);
44 entrys_malloc_error:
45 return -1;
46};
47
48/* wb_exit
49 * @wb_t :wb_t to exit
50 * */
51void
52mmu_wb_exit (wb_s * wb_t)
53{
54 int i;
55 wb_entry_t *wb;
56
57 wb = wb_t->entrys;
58 for (i = 0; i < wb_t->num; i++, wb++) {
59 free (wb->data);
60 }
61 free (wb_t->entrys);
62};
63
64/* wb_write_words :put words in Write Buffer
65 * @state: ARMul_State
66 * @wb_t: write buffer
67 * @pa: physical address
68 * @data: data ptr
69 * @n number of word to write
70 *
71 * Note: write buffer merge is not implemented, can be done late
72 * */
73void
74mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa,
75 ARMbyte * data, int n)
76{
77 int i;
78 wb_entry_t *wb;
79
80 while (n) {
81 if (wb_t->num == wb_t->used) {
82 /*clean the last wb entry */
83 ARMword t;
84
85 wb = &wb_t->entrys[wb_t->last];
86 t = wb->pa;
87 for (i = 0; i < wb->nb; i++) {
88 //mem_write_byte (state, t, wb->data[i]);
89 bus_write(8, t, wb->data[i]);
90 //t += WORD_SIZE;
91 t++;
92 }
93 wb_t->last++;
94 if (wb_t->last == wb_t->num)
95 wb_t->last = 0;
96 wb_t->used--;
97 }
98
99 wb = &wb_t->entrys[wb_t->first];
100 i = (n < wb_t->nb) ? n : wb_t->nb;
101
102 wb->pa = pa;
103 //pa += i << WORD_SHT;
104 pa += i;
105
106 wb->nb = i;
107 //memcpy(wb->data, data, i << WORD_SHT);
108 memcpy (wb->data, data, i);
109 data += i;
110 n -= i;
111 wb_t->first++;
112 if (wb_t->first == wb_t->num)
113 wb_t->first = 0;
114 wb_t->used++;
115 };
116//teawater add for set_dirty fflash cache function 2005.07.18-------------------
117#ifdef DBCT
118 if (!skyeye_config.no_dbct) {
119 tb_setdirty (state, pa, NULL);
120 }
121#endif
122//AJ2D--------------------------------------------------------------------------
123}
124
125/* wb_drain_all
126 * @wb_t wb_t to drain
127 * */
128void
129mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t)
130{
131 ARMword pa;
132 wb_entry_t *wb;
133 int i;
134
135 while (wb_t->used) {
136 wb = &wb_t->entrys[wb_t->last];
137 pa = wb->pa;
138 for (i = 0; i < wb->nb; i++) {
139 //mem_write_byte (state, pa, wb->data[i]);
140 bus_write(8, pa, wb->data[i]);
141 //pa += WORD_SIZE;
142 pa++;
143 }
144 wb_t->last++;
145 if (wb_t->last == wb_t->num)
146 wb_t->last = 0;
147 wb_t->used--;
148 };
149}
diff --git a/src/core/arm/interpreter/mmu/xscale_copro.cpp b/src/core/arm/interpreter/mmu/xscale_copro.cpp
new file mode 100644
index 000000000..99cd77737
--- /dev/null
+++ b/src/core/arm/interpreter/mmu/xscale_copro.cpp
@@ -0,0 +1,1388 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#include <assert.h>
22#include <string.h>
23
24#include "core/arm/interpreter/armdefs.h"
25#include "core/arm/interpreter/armemu.h"
26
27/*#include "pxa.h" */
28
29/* chy 2005-09-19 */
30
31/* extern pxa270_io_t pxa270_io; */
32/* chy 2005-09-19 -----end */
33
34typedef struct xscale_mmu_desc_s
35{
36 int i_tlb;
37 cache_desc_t i_cache;
38
39 int d_tlb;
40 cache_desc_t main_d_cache;
41 cache_desc_t mini_d_cache;
42 //int rb; xscale has no read buffer
43 wb_desc_t wb;
44} xscale_mmu_desc_t;
45
46static xscale_mmu_desc_t pxa_mmu_desc = {
47 32,
48 {32, 32, 32, CACHE_WRITE_BACK},
49
50 32,
51 {32, 32, 32, CACHE_WRITE_BACK},
52 {32, 2, 8, CACHE_WRITE_BACK},
53 {8, 16}, //for byte size,
54};
55
56//chy 2005-09-19 for cp6
57#define CR0_ICIP 0
58#define CR1_ICMR 1
59//chy 2005-09-19 ---end
60//----------- for cp14-----------------
61#define CCLKCFG 6
62#define PWRMODE 7
63typedef struct xscale_cp14_reg_s
64{
65 unsigned cclkcfg; //reg6
66 unsigned pwrmode; //reg7
67} xscale_cp14_reg_s;
68
69xscale_cp14_reg_s pxa_cp14_regs;
70
71//--------------------------------------
72
73static fault_t xscale_mmu_write (ARMul_State * state, ARMword va,
74 ARMword data, ARMword datatype);
75static fault_t xscale_mmu_read (ARMul_State * state, ARMword va,
76 ARMword * data, ARMword datatype);
77
78ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
79ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);
80
81
82/* jeff add 2010.9.26 for pxa270 cp6*/
83#define PXA270_ICMR 0x40D00004
84#define PXA270_ICPR 0x40D00010
85#define PXA270_ICLR 0x40D00008
86//chy 2005-09-19 for xscale pxa27x cp6
87//unsigned
88//xscale_cp6_mrc (ARMul_State * state, unsigned type, ARMword instr,
89// ARMword * data)
90//{
91// unsigned opcode_2 = BITS (5, 7);
92// unsigned CRm = BITS (0, 3);
93// unsigned reg = BITS (16, 19);
94// unsigned result;
95//
96// //printf("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,state->Reg[15], instr);
97//
98// switch (reg) {
99// case CR0_ICIP: { // cp 6 reg 0
100// //printf("cp6_mrc cr0 ICIP \n");
101// /* *data = (pxa270_io.icmr & pxa270_io.icpr) & ~pxa270_io.iclr; */
102// /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/
103// int icmr, icpr, iclr;
104// bus_read(32, PXA270_ICMR, &icmr);
105// bus_read(32, PXA270_ICPR, &icpr);
106// bus_read(32, PXA270_ICLR, &iclr);
107// *data = (icmr & icpr) & ~iclr;
108// }
109// break;
110// case CR1_ICMR: { // cp 6 reg 1
111// //printf("cp6_mrc cr1 ICMR\n");
112// /* *data = pxa270_io.icmr; */
113// int icmr;
114// /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/
115// bus_read(32, PXA270_ICMR, &icmr);
116// *data = icmr;
117// }
118// break;
119// default:
120// *data = 0;
121// printf ("SKYEYE:cp6_mrc unknown cp6 regs!!!!!!\n");
122// printf ("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n", opcode_2, CRm, reg, state->Reg[15], instr);
123// break;
124// }
125// return 0;
126//}
127//
128////chy 2005-09-19 end
129////xscale cp13 ----------------------------------------------------
130//unsigned
131//xscale_cp13_init (ARMul_State * state)
132//{
133// //printf("SKYEYE: xscale_cp13_init: begin\n");
134// return 0;
135//}
136//
137//unsigned
138//xscale_cp13_exit (ARMul_State * state)
139//{
140// //printf("SKYEYE: xscale_cp13_exit: begin\n");
141// return 0;
142//}
143//
144//unsigned
145//xscale_cp13_ldc (ARMul_State * state, unsigned type, ARMword instr,
146// ARMword data)
147//{
148// printf ("SKYEYE: xscale_cp13_ldc: ERROR isn't existed,");
149// SKYEYE_OUTREGS (stderr);
150// fprintf (stderr, "\n");
151// // skyeye_exit (-1);
152// return 0; //No matter return value, only for compiler.
153//}
154//
155//unsigned
156//xscale_cp13_stc (ARMul_State * state, unsigned type, ARMword instr,
157// ARMword * data)
158//{
159// printf ("SKYEYE: xscale_cp13_stc: ERROR isn't existed,");
160// SKYEYE_OUTREGS (stderr);
161// fprintf (stderr, "\n");
162// // skyeye_exit (-1);
163// return 0; //No matter return value, only for compiler.
164//}
165//
166//unsigned
167//xscale_cp13_mrc (ARMul_State * state, unsigned type, ARMword instr,
168// ARMword * data)
169//{
170// printf ("SKYEYE: xscale_cp13_mrc: ERROR isn't existed,");
171// SKYEYE_OUTREGS (stderr);
172// fprintf (stderr, "\n");
173// // skyeye_exit (-1);
174// return 0; //No matter return value, only for compiler.
175//}
176//
177//unsigned
178//xscale_cp13_mcr (ARMul_State * state, unsigned type, ARMword instr,
179// ARMword data)
180//{
181// printf ("SKYEYE: xscale_cp13_mcr: ERROR isn't existed,");
182// SKYEYE_OUTREGS (stderr);
183// fprintf (stderr, "\n");
184// // skyeye_exit (-1);
185// return 0; //No matter return value, only for compiler.
186//}
187//
188//unsigned
189//xscale_cp13_cdp (ARMul_State * state, unsigned type, ARMword instr)
190//{
191// printf ("SKYEYE: xscale_cp13_cdp: ERROR isn't existed,");
192// SKYEYE_OUTREGS (stderr);
193// fprintf (stderr, "\n");
194// // skyeye_exit (-1);
195// return 0; //No matter return value, only for compiler.
196//}
197//
198//unsigned
199//xscale_cp13_read_reg (ARMul_State * state, unsigned reg, ARMword * data)
200//{
201// printf ("SKYEYE: xscale_cp13_read_reg: ERROR isn't existed,");
202// SKYEYE_OUTREGS (stderr);
203// fprintf (stderr, "\n");
204// return 0;
205// //exit(-1);
206//}
207//
208//unsigned
209//xscale_cp13_write_reg (ARMul_State * state, unsigned reg, ARMword data)
210//{
211// printf ("SKYEYE: xscale_cp13_write_reg: ERROR isn't existed,");
212// SKYEYE_OUTREGS (stderr);
213// fprintf (stderr, "\n");
214// // skyeye_exit (-1);
215// return 0; //No matter return value, only for compiler.
216//}
217//
218////------------------------------------------------------------------
219////xscale cp14 ----------------------------------------------------
220//unsigned
221//xscale_cp14_init (ARMul_State * state)
222//{
223// //printf("SKYEYE: xscale_cp14_init: begin\n");
224// pxa_cp14_regs.cclkcfg = 0;
225// pxa_cp14_regs.pwrmode = 0;
226// return 0;
227//}
228//
229//unsigned
230//xscale_cp14_exit (ARMul_State * state)
231//{
232// //printf("SKYEYE: xscale_cp14_exit: begin\n");
233// return 0;
234//}
235//
236//unsigned
237//xscale_cp14_ldc (ARMul_State * state, unsigned type, ARMword instr,
238// ARMword data)
239//{
240// printf ("SKYEYE: xscale_cp14_ldc: ERROR isn't existed, reg15 0x%x\n",
241// state->Reg[15]);
242// SKYEYE_OUTREGS (stderr);
243// // skyeye_exit (-1);
244// return 0; //No matter return value, only for compiler.
245//}
246//
247//unsigned
248//xscale_cp14_stc (ARMul_State * state, unsigned type, ARMword instr,
249// ARMword * data)
250//{
251// printf ("SKYEYE: xscale_cp14_stc: ERROR isn't existed, reg15 0x%x\n",
252// state->Reg[15]);
253// SKYEYE_OUTREGS (stderr);
254// // skyeye_exit (-1);
255// return 0; //No matter return value, only for compiler.
256//}
257//
258//unsigned
259//xscale_cp14_mrc (ARMul_State * state, unsigned type, ARMword instr,
260// ARMword * data)
261//{
262// unsigned opcode_2 = BITS (5, 7);
263// unsigned CRm = BITS (0, 3);
264// unsigned reg = BITS (16, 19);
265// unsigned result;
266//
267// //printf("SKYEYE: xscale_cp14_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
268// state->Reg[15], instr);
269//
270// switch (reg) {
271// case CCLKCFG: // cp 14 reg 6
272// //printf("cp14_mrc cclkcfg \n");
273// *data = pxa_cp14_regs.cclkcfg;
274// break;
275// case PWRMODE: // cp 14 reg 7
276// //printf("cp14_mrc pwrmode \n");
277// *data = pxa_cp14_regs.pwrmode;
278// break;
279// default:
280// *data = 0;
281// printf ("SKYEYE:cp14_mrc unknown cp14 regs!!!!!!\n");
282// break;
283// }
284// return 0;
285//}
286//unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type, ARMword instr,
287// ARMword data)
288//{
289// unsigned opcode_2 = BITS (5, 7);
290// unsigned CRm = BITS (0, 3);
291// unsigned reg = BITS (16, 19);
292// unsigned result;
293//
294// //printf("SKYEYE: xscale_cp14_mcr:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
295// state->Reg[15], instr);
296//
297// switch (reg) {
298// case CCLKCFG: // cp 14 reg 6
299// //printf("cp14_mcr cclkcfg \n");
300// pxa_cp14_regs.cclkcfg = data & 0xf;
301// break;
302// case PWRMODE: // cp 14 reg 7
303// //printf("cp14_mcr pwrmode \n");
304// pxa_cp14_regs.pwrmode = data & 0x3;
305// break;
306// default:printf ("SKYEYE: cp14_mcr unknown cp14 regs!!!!!!\n");
307// break;
308// }
309// return 0;
310//}
311//unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type, ARMword instr)
312//{
313// printf ("SKYEYE: xscale_cp14_cdp: ERROR isn't existed, reg15 0x%x\n",
314// state->Reg[15]);
315// SKYEYE_OUTREGS (stderr);
316// // skyeye_exit (-1);
317// return 0; //No matter return value, only for compiler.
318//}
319//unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
320// ARMword * data)
321//{
322// printf ("SKYEYE: xscale_cp14_read_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]);
323// SKYEYE_OUTREGS (stderr);
324// // skyeye_exit (-1);
325// return 0; //No matter return value, only for compiler.
326//}
327//unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
328// ARMword data)
329//{
330// printf ("SKYEYE: xscale_cp14_write_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]);
331// SKYEYE_OUTREGS (stderr);
332// // skyeye_exit (-1);
333//
334// return 0; //No matter return value, only for compiler.
335//}
336
337//------------------------------------------------------------------
338//cp15 -------------------------------------
339unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type, ARMword instr,
340 ARMword data)
341{
342 printf ("SKYEYE: xscale_cp15_ldc: ERROR isn't existed\n");
343 SKYEYE_OUTREGS (stderr);
344 // skyeye_exit (-1);
345
346 return 0; //No matter return value, only for compiler.
347}
348unsigned xscale_cp15_stc (ARMul_State * state, unsigned type, ARMword instr,
349 ARMword * data)
350{
351 printf ("SKYEYE: xscale_cp15_stc: ERROR isn't existed\n");
352 SKYEYE_OUTREGS (stderr);
353 // skyeye_exit (-1);
354
355 return 0; //No matter return value, only for compiler.
356}
357unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type, ARMword instr)
358{
359 printf ("SKYEYE: xscale_cp15_cdp: ERROR isn't existed\n");
360 SKYEYE_OUTREGS (stderr);
361 // skyeye_exit (-1);
362
363 return 0; //No matter return value, only for compiler.
364}
365unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
366 ARMword * data)
367{
368//chy 2003-09-03: for xsacle_cp15_cp_access_allowed
369 if (reg == 15) {
370 *data = state->mmu.copro_access;
371 //printf("SKYEYE: xscale_cp15_read_reg: reg 0x%x,data %x\n",reg,*data);
372 return 0;
373 }
374 printf ("SKYEYE: xscale_cp15_read_reg: reg 0x%x, ERROR isn't existed\n", reg);
375 SKYEYE_OUTREGS (stderr);
376 // skyeye_exit (-1);
377
378 return 0; //No matter return value, only for compiler.
379}
380
381//chy 2003-09-03 used by macro CP_ACCESS_ALLOWED in armemu.h
382unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
383 unsigned cpnum)
384{
385 unsigned data;
386
387 xscale_cp15_read_reg (state, reg, &data);
388 //printf("SKYEYE: cp15_cp_access_allowed data %x, cpnum %x, result %x\n", data, cpnum, (data & 1<<cpnum));
389 if (data & 1 << cpnum)
390 return 1;
391 else
392 return 0;
393}
394
395unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
396 ARMword value)
397{
398 switch (reg) {
399 case MMU_FAULT_STATUS:
400 //printf("SKYEYE:cp15_write_reg wrote FS val 0x%x \n",value);
401 state->mmu.fault_status = value & 0x6FF;
402 break;
403 case MMU_FAULT_ADDRESS:
404 //printf("SKYEYE:cp15_write_reg wrote FA val 0x%x \n",value);
405 state->mmu.fault_address = value;
406 break;
407 default:
408 printf ("SKYEYE: xscale_cp15_write_reg: reg 0x%x R15 %x ERROR isn't existed\n", reg, state->Reg[15]);
409 SKYEYE_OUTREGS (stderr);
410 // skyeye_exit (-1);
411 }
412 return 0;
413}
414
415int xscale_cp15_init (ARMul_State * state)
416{
417 xscale_mmu_desc_t *desc;
418 cache_desc_t *c_desc;
419
420 state->mmu.control = 0;
421 state->mmu.translation_table_base = 0xDEADC0DE;
422 state->mmu.domain_access_control = 0xDEADC0DE;
423 state->mmu.fault_status = 0;
424 state->mmu.fault_address = 0;
425 state->mmu.process_id = 0;
426 state->mmu.cache_type = 0xB1AA1AA; //0000 1011 0001 1010 1010 0001 1010 1010
427 state->mmu.aux_control = 0;
428
429 desc = &pxa_mmu_desc;
430
431 if (mmu_tlb_init (I_TLB (), desc->i_tlb)) {
432 ERROR_LOG(ARM11, "i_tlb init %d\n", -1);
433 goto i_tlb_init_error;
434 }
435
436 c_desc = &desc->i_cache;
437 if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
438 c_desc->set, c_desc->w_mode)) {
439 ERROR_LOG(ARM11, "i_cache init %d\n", -1);
440 goto i_cache_init_error;
441 }
442
443 if (mmu_tlb_init (D_TLB (), desc->d_tlb)) {
444 ERROR_LOG(ARM11, "d_tlb init %d\n", -1);
445 goto d_tlb_init_error;
446 }
447
448 c_desc = &desc->main_d_cache;
449 if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
450 c_desc->set, c_desc->w_mode)) {
451 ERROR_LOG(ARM11, "main_d_cache init %d\n", -1);
452 goto main_d_cache_init_error;
453 }
454
455 c_desc = &desc->mini_d_cache;
456 if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
457 c_desc->set, c_desc->w_mode)) {
458 ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1);
459 goto mini_d_cache_init_error;
460 }
461
462 if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) {
463 ERROR_LOG(ARM11, "wb init %d\n", -1);
464 goto wb_init_error;
465 }
466#if 0
467 if (mmu_rb_init (RB (), desc->rb)) {
468 ERROR_LOG(ARM11, "rb init %d\n", -1);
469 goto rb_init_error;
470 }
471#endif
472
473 return 0;
474#if 0
475 rb_init_error:
476 mmu_wb_exit (WB ());
477#endif
478 wb_init_error:
479 mmu_cache_exit (MINI_D_CACHE ());
480 mini_d_cache_init_error:
481 mmu_cache_exit (MAIN_D_CACHE ());
482 main_d_cache_init_error:
483 mmu_tlb_exit (D_TLB ());
484 d_tlb_init_error:
485 mmu_cache_exit (I_CACHE ());
486 i_cache_init_error:
487 mmu_tlb_exit (I_TLB ());
488 i_tlb_init_error:
489 return -1;
490}
491
492void xscale_cp15_exit (ARMul_State * state)
493{
494 //mmu_rb_exit(RB());
495 mmu_wb_exit (WB ());
496 mmu_cache_exit (MINI_D_CACHE ());
497 mmu_cache_exit (MAIN_D_CACHE ());
498 mmu_tlb_exit (D_TLB ());
499 mmu_cache_exit (I_CACHE ());
500 mmu_tlb_exit (I_TLB ());
501};
502
503
504static fault_t
505 xscale_mmu_load_instr (ARMul_State * state, ARMword va,
506 ARMword * instr)
507{
508 fault_t fault;
509 tlb_entry_t *tlb;
510 cache_line_t *cache;
511 int c; //cache bit
512 ARMword pa; //physical addr
513
514 static int debug_count = 0; //used for debug
515
516 DEBUG_LOG(ARM11, "va = %x\n", va);
517
518 va = mmu_pid_va_map (va);
519 if (MMU_Enabled) {
520 /*align check */
521 if ((va & (INSN_SIZE - 1)) && MMU_Aligned) {
522 DEBUG_LOG(ARM11, "align\n");
523 return ALIGNMENT_FAULT;
524 }
525 else
526 va &= ~(INSN_SIZE - 1);
527
528 /*translate tlb */
529 fault = translate (state, va, I_TLB (), &tlb);
530 if (fault) {
531 DEBUG_LOG(ARM11, "translate\n");
532 return fault;
533 }
534
535 /*check access */
536 fault = check_access (state, va, tlb, 1);
537 if (fault) {
538 DEBUG_LOG(ARM11, "check_fault\n");
539 return fault;
540 }
541 }
542 //chy 2003-09-02 for test, don't use cache ?????
543#if 0
544 /*search cache no matter MMU enabled/disabled */
545 cache = mmu_cache_search (state, I_CACHE (), va);
546 if (cache) {
547 *instr = cache->data[va_cache_index (va, I_CACHE ())];
548 return 0;
549 }
550#endif
551 /*if MMU disabled or C flag is set alloc cache */
552 if (MMU_Disabled) {
553 c = 1;
554 pa = va;
555 }
556 else {
557 c = tlb_c_flag (tlb);
558 pa = tlb_va_to_pa (tlb, va);
559 }
560
561 //chy 2003-09-03 only read mem, don't use cache now,will change later ????
562 //*instr = mem_read_word (state, pa);
563 bus_read(32, pa, instr);
564#if 0
565//-----------------------------------------------------------
566 //chy 2003-09-02 for test????
567 if (pa >= 0xa01c8000 && pa <= 0xa01c8020) {
568 printf ("SKYEYE:load_instr: pa %x, va %x,instr %x, R15 %x\n",
569 pa, va, *instr, state->Reg[15]);
570 }
571
572//----------------------------------------------------------------------
573#endif
574 return NO_FAULT;
575
576 if (c) {
577 int index;
578
579 debug_count++;
580 cache = mmu_cache_alloc (state, I_CACHE (), va, pa);
581 index = va_cache_index (va, I_CACHE ());
582 *instr = cache->data[va_cache_index (va, I_CACHE ())];
583 }
584 else
585 //*instr = mem_read_word (state, pa);
586 bus_read(32, pa, instr);
587
588 return NO_FAULT;
589};
590
591
592
593static fault_t
594 xscale_mmu_read_byte (ARMul_State * state, ARMword virt_addr,
595 ARMword * data)
596{
597 //ARMword temp,offset;
598 fault_t fault;
599 fault = xscale_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
600 return fault;
601}
602
603static fault_t
604 xscale_mmu_read_halfword (ARMul_State * state, ARMword virt_addr,
605 ARMword * data)
606{
607 //ARMword temp,offset;
608 fault_t fault;
609 fault = xscale_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
610 return fault;
611}
612
613static fault_t
614 xscale_mmu_read_word (ARMul_State * state, ARMword virt_addr,
615 ARMword * data)
616{
617 return xscale_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
618}
619
620
621
622
623static fault_t
624 xscale_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
625 ARMword datatype)
626{
627 fault_t fault;
628// rb_entry_t *rb;
629 tlb_entry_t *tlb;
630 cache_line_t *cache;
631 ARMword pa, real_va, temp, offset;
632 //chy 2003-09-02 for test ????
633 static unsigned chyst1 = 0, chyst2 = 0;
634
635 DEBUG_LOG(ARM11, "va = %x\n", va);
636
637 va = mmu_pid_va_map (va);
638 real_va = va;
639 /*if MMU disabled, memory_read */
640 if (MMU_Disabled) {
641 //*data = mem_read_word(state, va);
642 if (datatype == ARM_BYTE_TYPE)
643 //*data = mem_read_byte (state, va);
644 bus_read(8, va, data);
645 else if (datatype == ARM_HALFWORD_TYPE)
646 //*data = mem_read_halfword (state, va);
647 bus_read(16, va, data);
648 else if (datatype == ARM_WORD_TYPE)
649 //*data = mem_read_word (state, va);
650 bus_read(32, va, data);
651 else {
652 printf ("SKYEYE:1 xscale_mmu_read error: unknown data type %d\n", datatype);
653 // skyeye_exit (-1);
654 }
655
656 return NO_FAULT;
657 }
658
659 /*align check */
660 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
661 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
662 DEBUG_LOG(ARM11, "align\n");
663 return ALIGNMENT_FAULT;
664 } // else
665
666 va &= ~(WORD_SIZE - 1);
667
668 /*translate va to tlb */
669 fault = translate (state, va, D_TLB (), &tlb);
670 if (fault) {
671 DEBUG_LOG(ARM11, "translate\n");
672 return fault;
673 }
674 /*check access permission */
675 fault = check_access (state, va, tlb, 1);
676 if (fault)
677 return fault;
678
679#if 0
680//------------------------------------------------
681//chy 2003-09-02 for test only ,should commit ????
682 if (datatype == ARM_WORD_TYPE) {
683 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
684 pa = tlb_va_to_pa (tlb, va);
685 *data = mem_read_word (state, pa);
686 chyst1++;
687 printf ("**SKYEYE:mmu_read word %d: pa %x, va %x, data %x, R15 %x\n", chyst1, pa, real_va, *data, state->Reg[15]);
688 /*
689 cache==mmu_cache_search(state,MAIN_D_CACHE(),va);
690 if(cache){
691 *data = cache->data[va_cache_index(va, MAIN_D_CACHE())];
692 printf("cached data %x\n",*data);
693 }else printf("no cached data\n");
694 */
695 }
696 }
697//-------------------------------------------------
698#endif
699#if 0
700 /*search in read buffer */
701 rb = mmu_rb_search (RB (), va);
702 if (rb) {
703 if (rb->fault)
704 return rb->fault;
705 *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT];
706 goto datatrans;
707 //return 0;
708 };
709#endif
710
711 /*2004-07-19 chy: add support of xscale MMU CacheDisabled option */
712 if (MMU_CacheDisabled) {
713 //if(1){ can be used to test cache error
714 /*get phy_addr */
715 pa = tlb_va_to_pa (tlb, real_va);
716 if (datatype == ARM_BYTE_TYPE)
717 //*data = mem_read_byte (state, pa);
718 bus_read(8, pa, data);
719 else if (datatype == ARM_HALFWORD_TYPE)
720 //*data = mem_read_halfword (state, pa);
721 bus_read(16, pa, data);
722 else if (datatype == ARM_WORD_TYPE)
723 //*data = mem_read_word (state, pa);
724 bus_read(32, pa, data);
725 else {
726 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_read error: unknown data type %d\n", datatype);
727 // skyeye_exit (-1);
728 }
729 return NO_FAULT;
730 }
731
732
733 /*search main cache */
734 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
735 if (cache) {
736 *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())];
737#if 0
738//------------------------------------------------------------------------
739//chy 2003-09-02 for test only ,should commit ????
740 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
741 pa = tlb_va_to_pa (tlb, va);
742 chyst2++;
743 printf ("**SKYEYE:mmu_read wordk:cache %d: pa %x, va %x, data %x, R15 %x\n", chyst2, pa, real_va, *data, state->Reg[15]);
744 }
745//-------------------------------------------------------------------
746#endif
747 goto datatrans;
748 //return 0;
749 }
750 //chy 2003-08-24, now maybe we don't need minidcache ????
751#if 0
752 /*search mini cache */
753 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
754 if (cache) {
755 *data = cache->data[va_cache_index (va, MINI_D_CACHE ())];
756 goto datatrans;
757 //return 0;
758 }
759#endif
760 /*get phy_addr */
761 pa = tlb_va_to_pa (tlb, va);
762 //chy 2003-08-24 , in xscale it means what ?????
763#if 0
764 if ((pa >= 0xe0000000) && (pa < 0xe8000000)) {
765
766 if (tlb_c_flag (tlb)) {
767 if (tlb_b_flag (tlb)) {
768 mmu_cache_soft_flush (state, MAIN_D_CACHE (),
769 pa);
770 }
771 else {
772 mmu_cache_soft_flush (state, MINI_D_CACHE (),
773 pa);
774 }
775 }
776 return 0;
777 }
778#endif
779 //chy 2003-08-24, check phy addr
780 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
781 /*
782 if(pa >= 0xb0000000){
783 printf("SKYEYE:xscale_mmu_read: phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
784 return 0;
785 }
786 */
787
788 //chy 2003-08-24, now maybe we don't need wb ????
789#if 0
790 /*if Buffer, drain Write Buffer first */
791 if (tlb_b_flag (tlb))
792 mmu_wb_drain_all (state, WB ());
793#endif
794 /*alloc cache or mem_read */
795 if (tlb_c_flag (tlb) && MMU_DCacheEnabled) {
796 cache_s *cache_t;
797
798 if (tlb_b_flag (tlb))
799 cache_t = MAIN_D_CACHE ();
800 else
801 cache_t = MINI_D_CACHE ();
802 cache = mmu_cache_alloc (state, cache_t, va, pa);
803 *data = cache->data[va_cache_index (va, cache_t)];
804 }
805 else {
806 //*data = mem_read_word(state, pa);
807 if (datatype == ARM_BYTE_TYPE)
808 //*data = mem_read_byte (state, pa | (real_va & 3));
809 bus_read(8, pa | (real_va & 3), data);
810 else if (datatype == ARM_HALFWORD_TYPE)
811 //*data = mem_read_halfword (state, pa | (real_va & 2));
812 bus_read(16, pa | (real_va & 2), data);
813 else if (datatype == ARM_WORD_TYPE)
814 //*data = mem_read_word (state, pa);
815 bus_read(32, pa, data);
816 else {
817 printf ("SKYEYE:2 xscale_mmu_read error: unknown data type %d\n", datatype);
818 // skyeye_exit (-1);
819 }
820 return NO_FAULT;
821 }
822
823
824 datatrans:
825 if (datatype == ARM_HALFWORD_TYPE) {
826 temp = *data;
827 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
828 *data = (temp >> offset) & 0xffff;
829 }
830 else if (datatype == ARM_BYTE_TYPE) {
831 temp = *data;
832 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
833 *data = (temp >> offset & 0xffL);
834 }
835 end:
836 return NO_FAULT;
837}
838
839
840static fault_t
841 xscale_mmu_write_byte (ARMul_State * state, ARMword virt_addr,
842 ARMword data)
843{
844 return xscale_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
845}
846
847static fault_t
848 xscale_mmu_write_halfword (ARMul_State * state, ARMword virt_addr,
849 ARMword data)
850{
851 return xscale_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
852}
853
854static fault_t
855 xscale_mmu_write_word (ARMul_State * state, ARMword virt_addr,
856 ARMword data)
857{
858 return xscale_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
859}
860
861
862
863static fault_t
864 xscale_mmu_write (ARMul_State * state, ARMword va, ARMword data,
865 ARMword datatype)
866{
867 tlb_entry_t *tlb;
868 cache_line_t *cache;
869 cache_s *cache_t;
870 int b;
871 ARMword pa, real_va, temp, offset;
872 fault_t fault;
873
874 ARMword index;
875//chy 2003-09-02 for test ????
876// static unsigned chyst1=0,chyst2=0;
877
878 DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
879 va = mmu_pid_va_map (va);
880 real_va = va;
881
882 if (MMU_Disabled) {
883 //mem_write_word(state, va, data);
884 if (datatype == ARM_BYTE_TYPE)
885 //mem_write_byte (state, va, data);
886 bus_write(8, va, data);
887 else if (datatype == ARM_HALFWORD_TYPE)
888 //mem_write_halfword (state, va, data);
889 bus_write(16, va, data);
890 else if (datatype == ARM_WORD_TYPE)
891 //mem_write_word (state, va, data);
892 bus_write(32, va, data);
893 else {
894 printf ("SKYEYE:1 xscale_mmu_write error: unknown data type %d\n", datatype);
895 // skyeye_exit (-1);
896 }
897
898 return NO_FAULT;
899 }
900 /*align check */
901 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
902 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
903 DEBUG_LOG(ARM11, "align\n");
904 return ALIGNMENT_FAULT;
905 } //else
906 va &= ~(WORD_SIZE - 1);
907 /*tlb translate */
908 fault = translate (state, va, D_TLB (), &tlb);
909 if (fault) {
910 DEBUG_LOG(ARM11, "translate\n");
911 return fault;
912 }
913 /*tlb check access */
914 fault = check_access (state, va, tlb, 0);
915 if (fault) {
916 DEBUG_LOG(ARM11, "check_access\n");
917 return fault;
918 }
919
920 /*2004-07-19 chy: add support for xscale MMU_CacheDisabled */
921 if (MMU_CacheDisabled) {
922 //if(1){ can be used to test the cache error
923 /*get phy_addr */
924 pa = tlb_va_to_pa (tlb, real_va);
925 if (datatype == ARM_BYTE_TYPE)
926 //mem_write_byte (state, pa, data);
927 bus_write(8, pa, data);
928 else if (datatype == ARM_HALFWORD_TYPE)
929 //mem_write_halfword (state, pa, data);
930 bus_write(16, pa, data);
931 else if (datatype == ARM_WORD_TYPE)
932 //mem_write_word (state, pa, data);
933 bus_write(32, pa , data);
934 else {
935 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_write error: unknown data type %d\n", datatype);
936 // skyeye_exit (-1);
937 }
938
939 return NO_FAULT;
940 }
941
942 /*search main cache */
943 b = tlb_b_flag (tlb);
944 pa = tlb_va_to_pa (tlb, va);
945 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
946 if (cache) {
947 cache_t = MAIN_D_CACHE ();
948 goto has_cache;
949 }
950 //chy 2003-08-24, now maybe we don't need minidcache ????
951#if 0
952 /*search mini cache */
953 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
954 if (cache) {
955 cache_t = MINI_D_CACHE ();
956 goto has_cache;
957 }
958#endif
959 b = tlb_b_flag (tlb);
960 pa = tlb_va_to_pa (tlb, va);
961 //chy 2003-08-24, check phy addr 0xa0000000, size 0x04000000
962 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
963 /*
964 if(pa >= 0xb0000000){
965 printf("SKYEYE:xscale_mmu_write phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
966 return 0;
967 }
968 */
969
970 //chy 2003-08-24, now maybe we don't need WB ????
971#if 0
972 if (b) {
973 if (MMU_WBEnabled) {
974 if (datatype == ARM_WORD_TYPE)
975 mmu_wb_write_bytes (state, WB (), pa, &data,
976 4);
977 else if (datatype == ARM_HALFWORD_TYPE)
978 mmu_wb_write_bytes (state, WB (),
979 (pa | (real_va & 2)),
980 &data, 2);
981 else if (datatype == ARM_BYTE_TYPE)
982 mmu_wb_write_bytes (state, WB (),
983 (pa | (real_va & 3)),
984 &data, 1);
985
986 }
987 else {
988 if (datatype == ARM_WORD_TYPE)
989 mem_write_word (state, pa, data);
990 else if (datatype == ARM_HALFWORD_TYPE)
991 mem_write_halfword (state,
992 (pa | (real_va & 2)),
993 data);
994 else if (datatype == ARM_BYTE_TYPE)
995 mem_write_byte (state, (pa | (real_va & 3)),
996 data);
997 }
998 }
999 else {
1000
1001 mmu_wb_drain_all (state, WB ());
1002
1003 if (datatype == ARM_WORD_TYPE)
1004 mem_write_word (state, pa, data);
1005 else if (datatype == ARM_HALFWORD_TYPE)
1006 mem_write_halfword (state, (pa | (real_va & 2)),
1007 data);
1008 else if (datatype == ARM_BYTE_TYPE)
1009 mem_write_byte (state, (pa | (real_va & 3)), data);
1010 }
1011#endif
1012 //chy 2003-08-24, just write phy addr
1013 if (datatype == ARM_WORD_TYPE)
1014 //mem_write_word (state, pa, data);
1015 bus_write(32, pa, data);
1016 else if (datatype == ARM_HALFWORD_TYPE)
1017 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1018 bus_write(16, pa | (real_va & 2), data);
1019 else if (datatype == ARM_BYTE_TYPE)
1020 //mem_write_byte (state, (pa | (real_va & 3)), data);
1021 bus_write(8, (pa | (real_va & 3)), data);
1022#if 0
1023//-------------------------------------------------------------
1024//chy 2003-09-02 for test ????
1025 if (datatype == ARM_WORD_TYPE) {
1026 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1027 printf ("**SKYEYE:mmu_write word: pa %x, va %x, data %x, R15 %x \n", pa, real_va, data, state->Reg[15]);
1028 }
1029 }
1030//--------------------------------------------------------------
1031#endif
1032 return NO_FAULT;
1033
1034 has_cache:
1035 index = va_cache_index (va, cache_t);
1036 //cache->data[index] = data;
1037
1038 if (datatype == ARM_WORD_TYPE)
1039 cache->data[index] = data;
1040 else if (datatype == ARM_HALFWORD_TYPE) {
1041 temp = cache->data[index];
1042 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
1043 cache->data[index] =
1044 (temp & ~(0xffffL << offset)) | ((data & 0xffffL) <<
1045 offset);
1046 }
1047 else if (datatype == ARM_BYTE_TYPE) {
1048 temp = cache->data[index];
1049 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
1050 cache->data[index] =
1051 (temp & ~(0xffL << offset)) | ((data & 0xffL) <<
1052 offset);
1053 }
1054
1055 if (index < (cache_t->width >> (WORD_SHT + 1)))
1056 cache->tag |= TAG_FIRST_HALF_DIRTY;
1057 else
1058 cache->tag |= TAG_LAST_HALF_DIRTY;
1059//-------------------------------------------------------------
1060//chy 2003-09-03 be sure the changed value will be in memory as soon as possible, so I cache can get the newest value
1061#if 0
1062 {
1063 if (datatype == ARM_WORD_TYPE)
1064 mem_write_word (state, pa, data);
1065 else if (datatype == ARM_HALFWORD_TYPE)
1066 mem_write_halfword (state, (pa | (real_va & 2)),
1067 data);
1068 else if (datatype == ARM_BYTE_TYPE)
1069 mem_write_byte (state, (pa | (real_va & 3)), data);
1070 }
1071#endif
1072#if 0
1073//chy 2003-09-02 for test ????
1074 if (datatype == ARM_WORD_TYPE) {
1075 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1076 printf ("**SKYEYE:mmu_write word:cache: pa %x, va %x, data %x, R15 %x\n", pa, real_va, data, state->Reg[15]);
1077 }
1078 }
1079//-------------------------------------------------------------
1080#endif
1081 if (datatype == ARM_WORD_TYPE)
1082 //mem_write_word (state, pa, data);
1083 bus_write(32, pa, data);
1084 else if (datatype == ARM_HALFWORD_TYPE)
1085 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1086 bus_write(16, pa | (real_va & 2), data);
1087 else if (datatype == ARM_BYTE_TYPE)
1088 //mem_write_byte (state, (pa | (real_va & 3)), data);
1089 bus_write(8, (pa | (real_va & 3)), data);
1090 return NO_FAULT;
1091}
1092
1093ARMword xscale_cp15_mrc (ARMul_State * state,
1094 unsigned type, ARMword instr, ARMword * value)
1095{
1096 return xscale_mmu_mrc (state, instr, value);
1097}
1098
1099ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
1100{
1101 ARMword data;
1102 unsigned opcode_2 = BITS (5, 7);
1103 unsigned CRm = BITS (0, 3);
1104 unsigned reg = BITS (16, 19);
1105 unsigned result;
1106 mmu_regnum_t creg = (mmu_regnum_t)reg;
1107
1108/*
1109 printf("SKYEYE: xscale_cp15_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
1110 state->Reg[15], instr);
1111*/
1112 switch (creg) {
1113 case MMU_ID: //XSCALE_CP15
1114 //printf("mmu_mrc read ID \n");
1115 data = (opcode_2 ? state->mmu.cache_type : state->cpu->
1116 cpu_val);
1117 break;
1118 case MMU_CONTROL: //XSCALE_CP15_AUX_CONTROL
1119 //printf("mmu_mrc read CONTROL \n");
1120 data = (opcode_2 ? state->mmu.aux_control : state->mmu.
1121 control);
1122 break;
1123 case MMU_TRANSLATION_TABLE_BASE:
1124 //printf("mmu_mrc read TTB \n");
1125 data = state->mmu.translation_table_base;
1126 break;
1127 case MMU_DOMAIN_ACCESS_CONTROL:
1128 //printf("mmu_mrc read DACR \n");
1129 data = state->mmu.domain_access_control;
1130 break;
1131 case MMU_FAULT_STATUS:
1132 //printf("mmu_mrc read FSR \n");
1133 data = state->mmu.fault_status;
1134 break;
1135 case MMU_FAULT_ADDRESS:
1136 //printf("mmu_mrc read FAR \n");
1137 data = state->mmu.fault_address;
1138 break;
1139 case MMU_PID:
1140 //printf("mmu_mrc read PID \n");
1141 data = state->mmu.process_id;
1142 case XSCALE_CP15_COPRO_ACCESS:
1143 //printf("xscale cp15 read coprocessor access\n");
1144 data = state->mmu.copro_access;
1145 break;
1146 default:
1147 data = 0;
1148 printf ("SKYEYE: xscale_cp15_mrc read UNKNOWN - reg %d, pc 0x%x\n", creg, state->Reg[15]);
1149 // skyeye_exit (-1);
1150 break;
1151 }
1152 *value = data;
1153 //printf("SKYEYE: xscale_cp15_mrc:end value 0x%x\n",data);
1154 return ARMul_DONE;
1155}
1156
1157void xscale_cp15_cache_ops (ARMul_State * state, ARMword instr, ARMword value)
1158{
1159//chy: 2003-08-24 now, the BTB isn't simualted ....????
1160
1161 unsigned CRm, OPC_2;
1162
1163 CRm = BITS (0, 3);
1164 OPC_2 = BITS (5, 7);
1165 //err_msg("SKYEYE: xscale cp15_cache_ops:OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm,state->Reg[15]);
1166
1167 if (OPC_2 == 0 && CRm == 7) {
1168 mmu_cache_invalidate_all (state, I_CACHE ());
1169 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1170 return;
1171 }
1172
1173 if (OPC_2 == 0 && CRm == 5) {
1174 mmu_cache_invalidate_all (state, I_CACHE ());
1175 return;
1176 }
1177 if (OPC_2 == 1 && CRm == 5) {
1178 mmu_cache_invalidate (state, I_CACHE (), value);
1179 return;
1180 }
1181
1182 if (OPC_2 == 0 && CRm == 6) {
1183 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1184 return;
1185 }
1186
1187 if (OPC_2 == 1 && CRm == 6) {
1188 mmu_cache_invalidate (state, MAIN_D_CACHE (), value);
1189 return;
1190 }
1191
1192 if (OPC_2 == 1 && CRm == 0xa) {
1193 mmu_cache_clean (state, MAIN_D_CACHE (), value);
1194 return;
1195 }
1196
1197 if (OPC_2 == 4 && CRm == 0xa) {
1198 mmu_wb_drain_all (state, WB ());
1199 return;
1200 }
1201
1202 if (OPC_2 == 6 && CRm == 5) {
1203 //chy 2004-07-19 shoud fix in the future????!!!!
1204 //printf("SKYEYE: xscale_cp15_cache_ops:invalidate BTB CANT!!!!!!!!!!\n");
1205 //exit(-1);
1206 return;
1207 }
1208
1209 if (OPC_2 == 5 && CRm == 2) {
1210 //printf("SKYEYE: cp15_c_o: A L in D C, value %x, reg15 %x\n",value, state->Reg[15]);
1211 //exit(-1);
1212 //chy 2003-09-01 for test
1213 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1214 return;
1215 }
1216
1217 ERROR_LOG(ARM11, "SKYEYE: xscale cp15_cache_ops:Unknown OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm, state->Reg[15]);
1218 // skyeye_exit (-1);
1219}
1220
1221static void
1222 xscale_cp15_tlb_ops (ARMul_State * state, ARMword instr,
1223 ARMword value)
1224{
1225 int CRm, OPC_2;
1226
1227 CRm = BITS (0, 3);
1228 OPC_2 = BITS (5, 7);
1229
1230
1231 //err_msg("SKYEYE:xscale_cp15_tlb_ops:OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm,state->Reg[15]);
1232 if (OPC_2 == 0 && CRm == 0x7) {
1233 mmu_tlb_invalidate_all (state, I_TLB ());
1234 mmu_tlb_invalidate_all (state, D_TLB ());
1235 return;
1236 }
1237
1238 if (OPC_2 == 0 && CRm == 0x5) {
1239 mmu_tlb_invalidate_all (state, I_TLB ());
1240 return;
1241 }
1242
1243 if (OPC_2 == 1 && CRm == 0x5) {
1244 mmu_tlb_invalidate_entry (state, I_TLB (), value);
1245 return;
1246 }
1247
1248 if (OPC_2 == 0 && CRm == 0x6) {
1249 mmu_tlb_invalidate_all (state, D_TLB ());
1250 return;
1251 }
1252
1253 if (OPC_2 == 1 && CRm == 0x6) {
1254 mmu_tlb_invalidate_entry (state, D_TLB (), value);
1255 return;
1256 }
1257
1258 ERROR_LOG(ARM11, "SKYEYE:xscale_cp15_tlb_ops:Unknow OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm, state->Reg[15]);
1259 // skyeye_exit (-1);
1260}
1261
1262
1263ARMword xscale_cp15_mcr (ARMul_State * state,
1264 unsigned type, ARMword instr, ARMword value)
1265{
1266 return xscale_mmu_mcr (state, instr, value);
1267}
1268
1269ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
1270{
1271 ARMword data;
1272 unsigned opcode_2 = BITS (5, 7);
1273 unsigned CRm = BITS (0, 3);
1274 unsigned reg = BITS (16, 19);
1275 unsigned result;
1276 mmu_regnum_t creg = (mmu_regnum_t)reg;
1277
1278 //printf("SKYEYE: xscale_cp15_mcr: opcode_2 0x%x, CRm 0x%x, reg ox%x, value 0x%x, reg[15] 0x%x, instr 0x%x\n",opcode_2,CRm,reg, value, state->Reg[15], instr);
1279
1280 switch (creg) {
1281 case MMU_CONTROL:
1282 //printf("mmu_mcr wrote CONTROL val 0x%x \n",value);
1283 state->mmu.control =
1284 (opcode_2 ? (value & 0x33) : (value & 0x3FFF));
1285 break;
1286 case MMU_TRANSLATION_TABLE_BASE:
1287 //printf("mmu_mcr wrote TTB val 0x%x \n",value);
1288 state->mmu.translation_table_base = value & 0xFFFFC000;
1289 break;
1290 case MMU_DOMAIN_ACCESS_CONTROL:
1291 //printf("mmu_mcr wrote DACR val 0x%x \n",value);
1292 state->mmu.domain_access_control = value;
1293 break;
1294
1295 case MMU_FAULT_STATUS:
1296 //printf("mmu_mcr wrote FS val 0x%x \n",value);
1297 state->mmu.fault_status = value & 0x6FF;
1298 break;
1299 case MMU_FAULT_ADDRESS:
1300 //printf("mmu_mcr wrote FA val 0x%x \n",value);
1301 state->mmu.fault_address = value;
1302 break;
1303
1304 case MMU_CACHE_OPS:
1305// printf("mmu_mcr wrote CO val 0x%x \n",value);
1306 xscale_cp15_cache_ops (state, instr, value);
1307 break;
1308 case MMU_TLB_OPS:
1309 //printf("mmu_mcr wrote TO val 0x%x \n",value);
1310 xscale_cp15_tlb_ops (state, instr, value);
1311 break;
1312 case MMU_PID:
1313 //printf("mmu_mcr wrote PID val 0x%x \n",value);
1314 state->mmu.process_id = value & 0xfe000000;
1315 break;
1316 case XSCALE_CP15_COPRO_ACCESS:
1317 //printf("xscale cp15 write coprocessor access val 0x %x\n",value);
1318 state->mmu.copro_access = value & 0x3ff;
1319 break;
1320
1321 default:
1322 printf ("SKYEYE: xscale_cp15_mcr wrote UNKNOWN - reg %d, reg15 0x%x\n", creg, state->Reg[15]);
1323 break;
1324 }
1325 //printf("SKYEYE: xscale_cp15_mcr wrote val 0x%x\n", value);
1326 return 0;
1327}
1328
1329//teawater add for arm2x86 2005.06.24-------------------------------------------
1330static int xscale_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
1331 ARMword * phys_addr)
1332{
1333 fault_t fault;
1334 tlb_entry_t *tlb;
1335
1336 virt_addr = mmu_pid_va_map (virt_addr);
1337 if (MMU_Enabled) {
1338
1339 /*align check */
1340 if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
1341 DEBUG_LOG(ARM11, "align\n");
1342 return ALIGNMENT_FAULT;
1343 }
1344 else
1345 virt_addr &= ~(WORD_SIZE - 1);
1346
1347 /*translate tlb */
1348 fault = translate (state, virt_addr, I_TLB (), &tlb);
1349 if (fault) {
1350 DEBUG_LOG(ARM11, "translate\n");
1351 return fault;
1352 }
1353
1354 /*check access */
1355 fault = check_access (state, virt_addr, tlb, 1);
1356 if (fault) {
1357 DEBUG_LOG(ARM11, "check_fault\n");
1358 return fault;
1359 }
1360 }
1361
1362 if (MMU_Disabled) {
1363 *phys_addr = virt_addr;
1364 }
1365 else {
1366 *phys_addr = tlb_va_to_pa (tlb, virt_addr);
1367 }
1368
1369 return (0);
1370}
1371
1372//AJ2D--------------------------------------------------------------------------
1373
1374/*xscale mmu_ops_t*/
1375mmu_ops_t xscale_mmu_ops = {
1376 xscale_cp15_init,
1377 xscale_cp15_exit,
1378 xscale_mmu_read_byte,
1379 xscale_mmu_write_byte,
1380 xscale_mmu_read_halfword,
1381 xscale_mmu_write_halfword,
1382 xscale_mmu_read_word,
1383 xscale_mmu_write_word,
1384 xscale_mmu_load_instr, xscale_mmu_mcr, xscale_mmu_mrc,
1385//teawater add for arm2x86 2005.06.24-------------------------------------------
1386 xscale_mmu_v2p_dbct,
1387//AJ2D--------------------------------------------------------------------------
1388};
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 1aaf28eee..02d0387af 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -146,12 +146,18 @@
146 <ClCompile Include="arm\interpreter\armsupp.cpp" /> 146 <ClCompile Include="arm\interpreter\armsupp.cpp" />
147 <ClCompile Include="arm\interpreter\armvirt.cpp" /> 147 <ClCompile Include="arm\interpreter\armvirt.cpp" />
148 <ClCompile Include="arm\interpreter\arm_interpreter.cpp" /> 148 <ClCompile Include="arm\interpreter\arm_interpreter.cpp" />
149 <ClCompile Include="arm\interpreter\mmu\arm1176jzf_s_mmu.cpp" />
150 <ClCompile Include="arm\interpreter\mmu\cache.cpp" />
151 <ClCompile Include="arm\interpreter\mmu\rb.cpp" />
152 <ClCompile Include="arm\interpreter\mmu\sa_mmu.cpp" />
153 <ClCompile Include="arm\interpreter\mmu\tlb.cpp" />
154 <ClCompile Include="arm\interpreter\mmu\wb.cpp" />
155 <ClCompile Include="arm\interpreter\mmu\xscale_copro.cpp" />
149 <ClCompile Include="arm\interpreter\thumbemu.cpp" /> 156 <ClCompile Include="arm\interpreter\thumbemu.cpp" />
150 <ClCompile Include="arm\interpreter\vfp\vfp.cpp" /> 157 <ClCompile Include="arm\interpreter\vfp\vfp.cpp" />
151 <ClCompile Include="arm\interpreter\vfp\vfpdouble.cpp" /> 158 <ClCompile Include="arm\interpreter\vfp\vfpdouble.cpp" />
152 <ClCompile Include="arm\interpreter\vfp\vfpinstr.cpp" /> 159 <ClCompile Include="arm\interpreter\vfp\vfpinstr.cpp" />
153 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp" /> 160 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp" />
154 <ClCompile Include="arm\mmu\arm1176jzf_s_mmu.cpp" />
155 <ClCompile Include="core.cpp" /> 161 <ClCompile Include="core.cpp" />
156 <ClCompile Include="core_timing.cpp" /> 162 <ClCompile Include="core_timing.cpp" />
157 <ClCompile Include="elf\elf_reader.cpp" /> 163 <ClCompile Include="elf\elf_reader.cpp" />
@@ -185,15 +191,16 @@
185 <ClInclude Include="arm\interpreter\armos.h" /> 191 <ClInclude Include="arm\interpreter\armos.h" />
186 <ClInclude Include="arm\interpreter\arm_interpreter.h" /> 192 <ClInclude Include="arm\interpreter\arm_interpreter.h" />
187 <ClInclude Include="arm\interpreter\arm_regformat.h" /> 193 <ClInclude Include="arm\interpreter\arm_regformat.h" />
194 <ClInclude Include="arm\interpreter\mmu\arm1176jzf_s_mmu.h" />
195 <ClInclude Include="arm\interpreter\mmu\cache.h" />
196 <ClInclude Include="arm\interpreter\mmu\rb.h" />
197 <ClInclude Include="arm\interpreter\mmu\sa_mmu.h" />
198 <ClInclude Include="arm\interpreter\mmu\tlb.h" />
199 <ClInclude Include="arm\interpreter\mmu\wb.h" />
188 <ClInclude Include="arm\interpreter\skyeye_defs.h" /> 200 <ClInclude Include="arm\interpreter\skyeye_defs.h" />
189 <ClInclude Include="arm\interpreter\vfp\asm_vfp.h" /> 201 <ClInclude Include="arm\interpreter\vfp\asm_vfp.h" />
190 <ClInclude Include="arm\interpreter\vfp\vfp.h" /> 202 <ClInclude Include="arm\interpreter\vfp\vfp.h" />
191 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h" /> 203 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h" />
192 <ClInclude Include="arm\mmu\arm1176jzf_s_mmu.h" />
193 <ClInclude Include="arm\mmu\cache.h" />
194 <ClInclude Include="arm\mmu\rb.h" />
195 <ClInclude Include="arm\mmu\tlb.h" />
196 <ClInclude Include="arm\mmu\wb.h" />
197 <ClInclude Include="core.h" /> 204 <ClInclude Include="core.h" />
198 <ClInclude Include="core_timing.h" /> 205 <ClInclude Include="core_timing.h" />
199 <ClInclude Include="elf\elf_reader.h" /> 206 <ClInclude Include="elf\elf_reader.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 7436b9ed0..dba6b6f67 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -7,9 +7,6 @@
7 <Filter Include="arm\disassembler"> 7 <Filter Include="arm\disassembler">
8 <UniqueIdentifier>{61100188-a726-4024-ab16-95ee242b446e}</UniqueIdentifier> 8 <UniqueIdentifier>{61100188-a726-4024-ab16-95ee242b446e}</UniqueIdentifier>
9 </Filter> 9 </Filter>
10 <Filter Include="arm\mmu">
11 <UniqueIdentifier>{a64d3c8a-747a-491b-b782-6e2622bedf24}</UniqueIdentifier>
12 </Filter>
13 <Filter Include="file_sys"> 10 <Filter Include="file_sys">
14 <UniqueIdentifier>{7f618562-73d1-4f55-9628-887497c27654}</UniqueIdentifier> 11 <UniqueIdentifier>{7f618562-73d1-4f55-9628-887497c27654}</UniqueIdentifier>
15 </Filter> 12 </Filter>
@@ -31,6 +28,9 @@
31 <Filter Include="arm\interpreter\vfp"> 28 <Filter Include="arm\interpreter\vfp">
32 <UniqueIdentifier>{de62238f-a28e-4a33-8495-23fed6784588}</UniqueIdentifier> 29 <UniqueIdentifier>{de62238f-a28e-4a33-8495-23fed6784588}</UniqueIdentifier>
33 </Filter> 30 </Filter>
31 <Filter Include="arm\interpreter\mmu">
32 <UniqueIdentifier>{13ef9860-2ba0-47e9-a93d-b4052adab269}</UniqueIdentifier>
33 </Filter>
34 </ItemGroup> 34 </ItemGroup>
35 <ItemGroup> 35 <ItemGroup>
36 <ClCompile Include="arm\disassembler\arm_disasm.cpp"> 36 <ClCompile Include="arm\disassembler\arm_disasm.cpp">
@@ -60,9 +60,6 @@
60 <ClCompile Include="arm\interpreter\thumbemu.cpp"> 60 <ClCompile Include="arm\interpreter\thumbemu.cpp">
61 <Filter>arm\interpreter</Filter> 61 <Filter>arm\interpreter</Filter>
62 </ClCompile> 62 </ClCompile>
63 <ClCompile Include="arm\mmu\arm1176jzf_s_mmu.cpp">
64 <Filter>arm\mmu</Filter>
65 </ClCompile>
66 <ClCompile Include="file_sys\directory_file_system.cpp"> 63 <ClCompile Include="file_sys\directory_file_system.cpp">
67 <Filter>file_sys</Filter> 64 <Filter>file_sys</Filter>
68 </ClCompile> 65 </ClCompile>
@@ -129,6 +126,27 @@
129 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp"> 126 <ClCompile Include="arm\interpreter\vfp\vfpsingle.cpp">
130 <Filter>arm\interpreter\vfp</Filter> 127 <Filter>arm\interpreter\vfp</Filter>
131 </ClCompile> 128 </ClCompile>
129 <ClCompile Include="arm\interpreter\mmu\arm1176jzf_s_mmu.cpp">
130 <Filter>arm\interpreter\mmu</Filter>
131 </ClCompile>
132 <ClCompile Include="arm\interpreter\mmu\xscale_copro.cpp">
133 <Filter>arm\interpreter\mmu</Filter>
134 </ClCompile>
135 <ClCompile Include="arm\interpreter\mmu\sa_mmu.cpp">
136 <Filter>arm\interpreter\mmu</Filter>
137 </ClCompile>
138 <ClCompile Include="arm\interpreter\mmu\cache.cpp">
139 <Filter>arm\interpreter\mmu</Filter>
140 </ClCompile>
141 <ClCompile Include="arm\interpreter\mmu\rb.cpp">
142 <Filter>arm\interpreter\mmu</Filter>
143 </ClCompile>
144 <ClCompile Include="arm\interpreter\mmu\tlb.cpp">
145 <Filter>arm\interpreter\mmu</Filter>
146 </ClCompile>
147 <ClCompile Include="arm\interpreter\mmu\wb.cpp">
148 <Filter>arm\interpreter\mmu</Filter>
149 </ClCompile>
132 </ItemGroup> 150 </ItemGroup>
133 <ItemGroup> 151 <ItemGroup>
134 <ClInclude Include="arm\disassembler\arm_disasm.h"> 152 <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -158,21 +176,6 @@
158 <ClInclude Include="arm\interpreter\skyeye_defs.h"> 176 <ClInclude Include="arm\interpreter\skyeye_defs.h">
159 <Filter>arm\interpreter</Filter> 177 <Filter>arm\interpreter</Filter>
160 </ClInclude> 178 </ClInclude>
161 <ClInclude Include="arm\mmu\arm1176jzf_s_mmu.h">
162 <Filter>arm\mmu</Filter>
163 </ClInclude>
164 <ClInclude Include="arm\mmu\cache.h">
165 <Filter>arm\mmu</Filter>
166 </ClInclude>
167 <ClInclude Include="arm\mmu\rb.h">
168 <Filter>arm\mmu</Filter>
169 </ClInclude>
170 <ClInclude Include="arm\mmu\tlb.h">
171 <Filter>arm\mmu</Filter>
172 </ClInclude>
173 <ClInclude Include="arm\mmu\wb.h">
174 <Filter>arm\mmu</Filter>
175 </ClInclude>
176 <ClInclude Include="file_sys\directory_file_system.h"> 179 <ClInclude Include="file_sys\directory_file_system.h">
177 <Filter>file_sys</Filter> 180 <Filter>file_sys</Filter>
178 </ClInclude> 181 </ClInclude>
@@ -247,6 +250,24 @@
247 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h"> 250 <ClInclude Include="arm\interpreter\vfp\vfp_helper.h">
248 <Filter>arm\interpreter\vfp</Filter> 251 <Filter>arm\interpreter\vfp</Filter>
249 </ClInclude> 252 </ClInclude>
253 <ClInclude Include="arm\interpreter\mmu\arm1176jzf_s_mmu.h">
254 <Filter>arm\interpreter\mmu</Filter>
255 </ClInclude>
256 <ClInclude Include="arm\interpreter\mmu\cache.h">
257 <Filter>arm\interpreter\mmu</Filter>
258 </ClInclude>
259 <ClInclude Include="arm\interpreter\mmu\rb.h">
260 <Filter>arm\interpreter\mmu</Filter>
261 </ClInclude>
262 <ClInclude Include="arm\interpreter\mmu\tlb.h">
263 <Filter>arm\interpreter\mmu</Filter>
264 </ClInclude>
265 <ClInclude Include="arm\interpreter\mmu\wb.h">
266 <Filter>arm\interpreter\mmu</Filter>
267 </ClInclude>
268 <ClInclude Include="arm\interpreter\mmu\sa_mmu.h">
269 <Filter>arm\interpreter\mmu</Filter>
270 </ClInclude>
250 </ItemGroup> 271 </ItemGroup>
251 <ItemGroup> 272 <ItemGroup>
252 <Text Include="CMakeLists.txt" /> 273 <Text Include="CMakeLists.txt" />