summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/CMakeLists.txt15
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp1
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp1
-rw-r--r--src/core/arm/interpreter/armcopro.cpp1000
-rw-r--r--src/core/arm/interpreter/armmmu.cpp238
-rw-r--r--src/core/arm/interpreter/armvirt.cpp683
-rw-r--r--src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp1132
-rw-r--r--src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h37
-rw-r--r--src/core/arm/interpreter/mmu/cache.cpp370
-rw-r--r--src/core/arm/interpreter/mmu/cache.h168
-rw-r--r--src/core/arm/interpreter/mmu/maverick.cpp1206
-rw-r--r--src/core/arm/interpreter/mmu/rb.cpp126
-rw-r--r--src/core/arm/interpreter/mmu/rb.h55
-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.h87
-rw-r--r--src/core/arm/interpreter/mmu/wb.cpp149
-rw-r--r--src/core/arm/interpreter/mmu/wb.h63
-rw-r--r--src/core/arm/interpreter/mmu/xscale_copro.cpp1391
-rw-r--r--src/core/arm/skyeye_common/armdefs.h1
-rw-r--r--src/core/arm/skyeye_common/armmmu.h117
22 files changed, 326 insertions, 7743 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cc0deb004..aefbe3375 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -6,19 +6,10 @@ set(SRCS
6 arm/dyncom/arm_dyncom_interpreter.cpp 6 arm/dyncom/arm_dyncom_interpreter.cpp
7 arm/dyncom/arm_dyncom_run.cpp 7 arm/dyncom/arm_dyncom_run.cpp
8 arm/dyncom/arm_dyncom_thumb.cpp 8 arm/dyncom/arm_dyncom_thumb.cpp
9 arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
10 arm/interpreter/mmu/cache.cpp
11 arm/interpreter/mmu/maverick.cpp
12 arm/interpreter/mmu/rb.cpp
13 arm/interpreter/mmu/sa_mmu.cpp
14 arm/interpreter/mmu/tlb.cpp
15 arm/interpreter/mmu/wb.cpp
16 arm/interpreter/mmu/xscale_copro.cpp
17 arm/interpreter/arm_interpreter.cpp 9 arm/interpreter/arm_interpreter.cpp
18 arm/interpreter/armcopro.cpp 10 arm/interpreter/armcopro.cpp
19 arm/interpreter/armemu.cpp 11 arm/interpreter/armemu.cpp
20 arm/interpreter/arminit.cpp 12 arm/interpreter/arminit.cpp
21 arm/interpreter/armmmu.cpp
22 arm/interpreter/armsupp.cpp 13 arm/interpreter/armsupp.cpp
23 arm/interpreter/armvirt.cpp 14 arm/interpreter/armvirt.cpp
24 arm/interpreter/thumbemu.cpp 15 arm/interpreter/thumbemu.cpp
@@ -72,12 +63,6 @@ set(HEADERS
72 arm/dyncom/arm_dyncom_run.h 63 arm/dyncom/arm_dyncom_run.h
73 arm/dyncom/arm_dyncom_thumb.h 64 arm/dyncom/arm_dyncom_thumb.h
74 arm/interpreter/arm_interpreter.h 65 arm/interpreter/arm_interpreter.h
75 arm/interpreter/mmu/arm1176jzf_s_mmu.h
76 arm/interpreter/mmu/cache.h
77 arm/interpreter/mmu/rb.h
78 arm/interpreter/mmu/sa_mmu.h
79 arm/interpreter/mmu/tlb.h
80 arm/interpreter/mmu/wb.h
81 arm/skyeye_common/arm_regformat.h 66 arm/skyeye_common/arm_regformat.h
82 arm/skyeye_common/armcpu.h 67 arm/skyeye_common/armcpu.h
83 arm/skyeye_common/armdefs.h 68 arm/skyeye_common/armdefs.h
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 7a65669ef..669b612fc 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -27,7 +27,6 @@ ARM_DynCom::ARM_DynCom() : ticks(0) {
27 27
28 ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); 28 ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
29 state->lateabtSig = LOW; 29 state->lateabtSig = LOW;
30 mmu_init(state);
31 30
32 // Reset the core to initial state 31 // Reset the core to initial state
33 ARMul_CoProInit(state.get()); 32 ARMul_CoProInit(state.get());
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index 6f6a5913c..ed4415082 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -22,7 +22,6 @@ ARM_Interpreter::ARM_Interpreter() {
22 22
23 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); 23 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
24 state->lateabtSig = LOW; 24 state->lateabtSig = LOW;
25 mmu_init(state);
26 25
27 // Reset the core to initial state 26 // Reset the core to initial state
28 ARMul_CoProInit(state); 27 ARMul_CoProInit(state);
diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp
index 9de6651d4..b4ddc3d96 100644
--- a/src/core/arm/interpreter/armcopro.cpp
+++ b/src/core/arm/interpreter/armcopro.cpp
@@ -15,7 +15,6 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18
19#include "core/arm/skyeye_common/armdefs.h" 18#include "core/arm/skyeye_common/armdefs.h"
20#include "core/arm/skyeye_common/armemu.h" 19#include "core/arm/skyeye_common/armemu.h"
21#include "core/arm/skyeye_common/vfp/vfp.h" 20#include "core/arm/skyeye_common/vfp/vfp.h"
@@ -25,817 +24,302 @@
25//chy ------- 24//chy -------
26//#include "iwmmxt.h" 25//#include "iwmmxt.h"
27 26
28
29//chy 2005-09-19 add CP6 MRC support (for get irq number and base)
30extern unsigned xscale_cp6_mrc (ARMul_State * state, unsigned type,
31 ARMword instr, ARMword * data);
32//chy 2005-09-19---------------
33
34extern unsigned xscale_cp13_init (ARMul_State * state);
35extern unsigned xscale_cp13_exit (ARMul_State * state);
36extern unsigned xscale_cp13_ldc (ARMul_State * state, unsigned type,
37 ARMword instr, ARMword data);
38extern unsigned xscale_cp13_stc (ARMul_State * state, unsigned type,
39 ARMword instr, ARMword * data);
40extern unsigned xscale_cp13_mrc (ARMul_State * state, unsigned type,
41 ARMword instr, ARMword * data);
42extern unsigned xscale_cp13_mcr (ARMul_State * state, unsigned type,
43 ARMword instr, ARMword data);
44extern unsigned xscale_cp13_cdp (ARMul_State * state, unsigned type,
45 ARMword instr);
46extern unsigned xscale_cp13_read_reg (ARMul_State * state, unsigned reg,
47 ARMword * data);
48extern unsigned xscale_cp13_write_reg (ARMul_State * state, unsigned reg,
49 ARMword data);
50extern unsigned xscale_cp14_init (ARMul_State * state);
51extern unsigned xscale_cp14_exit (ARMul_State * state);
52extern unsigned xscale_cp14_ldc (ARMul_State * state, unsigned type,
53 ARMword instr, ARMword data);
54extern unsigned xscale_cp14_stc (ARMul_State * state, unsigned type,
55 ARMword instr, ARMword * data);
56extern unsigned xscale_cp14_mrc (ARMul_State * state, unsigned type,
57 ARMword instr, ARMword * data);
58extern unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type,
59 ARMword instr, ARMword data);
60extern unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type,
61 ARMword instr);
62extern unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
63 ARMword * data);
64extern unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
65 ARMword data);
66extern unsigned xscale_cp15_init (ARMul_State * state);
67extern unsigned xscale_cp15_exit (ARMul_State * state);
68extern unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type,
69 ARMword instr, ARMword data);
70extern unsigned xscale_cp15_stc (ARMul_State * state, unsigned type,
71 ARMword instr, ARMword * data);
72extern unsigned xscale_cp15_mrc (ARMul_State * state, unsigned type,
73 ARMword instr, ARMword * data);
74extern unsigned xscale_cp15_mcr (ARMul_State * state, unsigned type,
75 ARMword instr, ARMword data);
76extern unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type,
77 ARMword instr);
78extern unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
79 ARMword * data);
80extern unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
81 ARMword data);
82extern unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
83 unsigned cpnum);
84
85/* Dummy Co-processors. */ 27/* Dummy Co-processors. */
86 28
87static unsigned 29static unsigned
88NoCoPro3R (ARMul_State * state, 30NoCoPro3R(ARMul_State * state,
89 unsigned a, ARMword b) 31unsigned a, ARMword b)
90{ 32{
91 return ARMul_CANT; 33 return ARMul_CANT;
92} 34}
93 35
94static unsigned 36static unsigned
95NoCoPro4R (ARMul_State * state, 37NoCoPro4R(ARMul_State * state,
96 unsigned a, 38unsigned a,
97 ARMword b, ARMword c) 39ARMword b, ARMword c)
98{ 40{
99 return ARMul_CANT; 41 return ARMul_CANT;
100} 42}
101 43
102static unsigned 44static unsigned
103NoCoPro4W (ARMul_State * state, 45NoCoPro4W(ARMul_State * state,
104 unsigned a, 46unsigned a,
105 ARMword b, ARMword * c) 47ARMword b, ARMword * c)
106{ 48{
107 return ARMul_CANT; 49 return ARMul_CANT;
108} 50}
109 51
110static unsigned 52static unsigned
111NoCoPro5R (ARMul_State * state, 53NoCoPro5R(ARMul_State * state,
112 unsigned a, 54unsigned a,
113 ARMword b, 55ARMword b,
114 ARMword c, ARMword d) 56ARMword c, ARMword d)
115{ 57{
116 return ARMul_CANT; 58 return ARMul_CANT;
117} 59}
118 60
119static unsigned 61static unsigned
120NoCoPro5W (ARMul_State * state, 62NoCoPro5W(ARMul_State * state,
121 unsigned a, 63unsigned a,
122 ARMword b, 64ARMword b,
123 ARMword * c, ARMword * d ) 65ARMword * c, ARMword * d)
124{ 66{
125 return ARMul_CANT; 67 return ARMul_CANT;
126} 68}
127 69
128/* The XScale Co-processors. */ 70/* The XScale Co-processors. */
129 71
130/* Coprocessor 15: System Control. */ 72/* Coprocessor 15: System Control. */
131static void write_cp14_reg (unsigned, ARMword); 73static void write_cp14_reg(unsigned, ARMword);
132static ARMword read_cp14_reg (unsigned); 74static ARMword read_cp14_reg(unsigned);
133
134/* There are two sets of registers for copro 15.
135 One set is available when opcode_2 is 0 and
136 the other set when opcode_2 >= 1. */
137static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
138static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];
139/* There are also a set of breakpoint registers
140 which are accessed via CRm instead of opcode_2. */
141static ARMword XScale_cp15_DBR1;
142static ARMword XScale_cp15_DBCON;
143static ARMword XScale_cp15_IBCR0;
144static ARMword XScale_cp15_IBCR1;
145
146static unsigned
147XScale_cp15_init (ARMul_State * state)
148{
149 int i;
150
151 for (i = 16; i--;) {
152 XScale_cp15_opcode_2_is_0_Regs[i] = 0;
153 XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;
154 }
155
156 /* Initialise the processor ID. */
157 //chy 2003-03-24, is same as cpu id in skyeye_options.c
158 //XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;
159 XScale_cp15_opcode_2_is_0_Regs[0] = 0x69050000;
160
161 /* Initialise the cache type. */
162 XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;
163
164 /* Initialise the ARM Control Register. */
165 XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
166
167 return No_exp;
168}
169
170/* Check an access to a register. */
171
172static unsigned
173check_cp15_access (ARMul_State * state,
174 unsigned reg,
175 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
176{
177 /* Do not allow access to these register in USER mode. */
178 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
179 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
180 return ARMul_CANT;
181
182 /* Opcode_1should be zero. */
183 if (opcode_1 != 0)
184 return ARMul_CANT;
185
186 /* Different register have different access requirements. */
187 switch (reg) {
188 case 0:
189 case 1:
190 /* CRm must be 0. Opcode_2 can be anything. */
191 if (CRm != 0)
192 return ARMul_CANT;
193 break;
194 case 2:
195 case 3:
196 /* CRm must be 0. Opcode_2 must be zero. */
197 if ((CRm != 0) || (opcode_2 != 0))
198 return ARMul_CANT;
199 break;
200 case 4:
201 /* Access not allowed. */
202 return ARMul_CANT;
203 case 5:
204 case 6:
205 /* Opcode_2 must be zero. CRm must be 0. */
206 if ((CRm != 0) || (opcode_2 != 0))
207 return ARMul_CANT;
208 break;
209 case 7:
210 /* Permissable combinations:
211 Opcode_2 CRm
212 0 5
213 0 6
214 0 7
215 1 5
216 1 6
217 1 10
218 4 10
219 5 2
220 6 5 */
221 switch (opcode_2) {
222 default:
223 return ARMul_CANT;
224 case 6:
225 if (CRm != 5)
226 return ARMul_CANT;
227 break;
228 case 5:
229 if (CRm != 2)
230 return ARMul_CANT;
231 break;
232 case 4:
233 if (CRm != 10)
234 return ARMul_CANT;
235 break;
236 case 1:
237 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
238 return ARMul_CANT;
239 break;
240 case 0:
241 if ((CRm < 5) || (CRm > 7))
242 return ARMul_CANT;
243 break;
244 }
245 break;
246
247 case 8:
248 /* Permissable combinations:
249 Opcode_2 CRm
250 0 5
251 0 6
252 0 7
253 1 5
254 1 6 */
255 if (opcode_2 > 1)
256 return ARMul_CANT;
257 if ((CRm < 5) || (CRm > 7))
258 return ARMul_CANT;
259 if (opcode_2 == 1 && CRm == 7)
260 return ARMul_CANT;
261 break;
262 case 9:
263 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
264 if (((CRm != 0) && (CRm != 1))
265 || ((opcode_2 != 1) && (opcode_2 != 2)))
266 return ARMul_CANT;
267 break;
268 case 10:
269 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
270 if (((CRm != 0) && (CRm != 1))
271 || ((opcode_2 != 4) && (opcode_2 != 8)))
272 return ARMul_CANT;
273 break;
274 case 11:
275 /* Access not allowed. */
276 return ARMul_CANT;
277 case 12:
278 /* Access not allowed. */
279 return ARMul_CANT;
280 case 13:
281 /* Opcode_2 must be zero. CRm must be 0. */
282 if ((CRm != 0) || (opcode_2 != 0))
283 return ARMul_CANT;
284 break;
285 case 14:
286 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
287 if (opcode_2 != 0)
288 return ARMul_CANT;
289
290 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
291 && (CRm != 9))
292 return ARMul_CANT;
293 break;
294 case 15:
295 /* Opcode_2 must be zero. CRm must be 1. */
296 if ((CRm != 1) || (opcode_2 != 0))
297 return ARMul_CANT;
298 break;
299 default:
300 /* Should never happen. */
301 return ARMul_CANT;
302 }
303
304 return ARMul_DONE;
305}
306
307/* Coprocessor 13: Interrupt Controller and Bus Controller. */
308
309/* There are two sets of registers for copro 13.
310 One set (of three registers) is available when CRm is 0
311 and the other set (of six registers) when CRm is 1. */
312
313static ARMword XScale_cp13_CR0_Regs[16];
314static ARMword XScale_cp13_CR1_Regs[16];
315
316static unsigned
317XScale_cp13_init (ARMul_State * state)
318{
319 int i;
320
321 for (i = 16; i--;) {
322 XScale_cp13_CR0_Regs[i] = 0;
323 XScale_cp13_CR1_Regs[i] = 0;
324 }
325
326 return No_exp;
327}
328
329/* Check an access to a register. */
330
331static unsigned
332check_cp13_access (ARMul_State * state,
333 unsigned reg,
334 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
335{
336 /* Do not allow access to these registers in USER mode. */
337 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
338 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
339 return ARMul_CANT;
340
341 /* The opcodes should be zero. */
342 if ((opcode_1 != 0) || (opcode_2 != 0))
343 return ARMul_CANT;
344
345 /* Do not allow access to these register if bit
346 13 of coprocessor 15's register 15 is zero. */
347 if (!CP_ACCESS_ALLOWED (state, 13))
348 return ARMul_CANT;
349
350 /* Registers 0, 4 and 8 are defined when CRm == 0.
351 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
352 For all other CRm values undefined behaviour results. */
353 if (CRm == 0) {
354 if (reg == 0 || reg == 4 || reg == 8)
355 return ARMul_DONE;
356 }
357 else if (CRm == 1) {
358 if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
359 return ARMul_DONE;
360 }
361
362 return ARMul_CANT;
363}
364
365/* Coprocessor 14: Performance Monitoring, Clock and Power management,
366 Software Debug. */
367
368static ARMword XScale_cp14_Regs[16];
369
370static unsigned
371XScale_cp14_init (ARMul_State * state)
372{
373 int i;
374
375 for (i = 16; i--;)
376 XScale_cp14_Regs[i] = 0;
377
378 return No_exp;
379}
380 75
381/* Check an access to a register. */ 76/* Check an access to a register. */
382 77
383static unsigned 78static unsigned
384check_cp14_access (ARMul_State * state, 79check_cp15_access(ARMul_State * state,
385 unsigned reg, 80unsigned reg,
386 unsigned CRm, unsigned opcode1, unsigned opcode2) 81unsigned CRm, unsigned opcode_1, unsigned opcode_2)
387{
388 /* Not allowed to access these register in USER mode. */
389 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
390 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
391 return ARMul_CANT;
392
393 /* CRm should be zero. */
394 if (CRm != 0)
395 return ARMul_CANT;
396
397 /* OPcodes should be zero. */
398 if (opcode1 != 0 || opcode2 != 0)
399 return ARMul_CANT;
400
401 /* Accessing registers 4 or 5 has unpredicatable results. */
402 if (reg >= 4 && reg <= 5)
403 return ARMul_CANT;
404
405 return ARMul_DONE;
406}
407
408/* Here's ARMulator's MMU definition. A few things to note:
409 1) It has eight registers, but only two are defined.
410 2) You can only access its registers with MCR and MRC.
411 3) MMU Register 0 (ID) returns 0x41440110
412 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
413 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
414 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
415
416static ARMword MMUReg[8];
417
418static unsigned
419MMUInit (ARMul_State * state)
420{
421/* 2004-05-09 chy
422-------------------------------------------------------------
423read ARM Architecture Reference Manual
4242.6.5 Data Abort
425There are three Abort Model in ARM arch.
426
427Early Abort Model: used in some ARMv3 and earlier implementations. In this
428model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
429the base register was unchanged for all other instructions. (oldest)
430
431Base Restored Abort Model: If a Data Abort occurs in an instruction which
432specifies base register writeback, the value in the base register is
433unchanged. (strongarm, xscale)
434
435Base Updated Abort Model: If a Data Abort occurs in an instruction which
436specifies base register writeback, the base register writeback still occurs.
437(arm720T)
438
439read PART B
440chap2 The System Control Coprocessor CP15
4412.4 Register1:control register
442L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
443processor could be configured:
4440=early Abort Model Selected(now obsolete)
4451=Late Abort Model selceted(same as Base Updated Abort Model)
446
447on later processors, this bit reads as 1 and ignores writes.
448-------------------------------------------------------------
449So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
450 if lateabtSig=0, then it means Base Restored Abort Model
451because the ARMs which skyeye simulates are all belonged to ARMv4,
452so I think MMUReg[1]'s bit 6 should always be 1
453
454*/
455
456 MMUReg[1] = state->prog32Sig << 4 |
457 state->data32Sig << 5 | 1 << 6 | state->bigendSig << 7;
458 //state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
459
460
461 NOTICE_LOG(ARM11, "ARMul_ConsolePrint: MMU present");
462
463 return TRUE;
464}
465
466static unsigned
467MMUMRC (ARMul_State * state, unsigned type,
468 ARMword instr, ARMword * value)
469{
470 mmu_mrc (state, instr, value);
471 return (ARMul_DONE);
472}
473
474static unsigned
475MMUMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
476{
477 mmu_mcr (state, instr, value);
478 return (ARMul_DONE);
479}
480
481/* What follows is the Validation Suite Coprocessor. It uses two
482 co-processor numbers (4 and 5) and has the follwing functionality.
483 Sixteen registers. Both co-processor nuimbers can be used in an MCR
484 and MRC to access these registers. CP 4 can LDC and STC to and from
485 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
486 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
487 number of cycles (specified in a CP register), CDP 2 issues an IRQW
488 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
489 stores a 32 bit time value in a CP register (actually it's the total
490 number of N, S, I, C and F cyles). */
491
492static ARMword ValReg[16];
493
494static unsigned
495ValLDC (ARMul_State * state,
496 unsigned type, ARMword instr, ARMword data)
497{
498 static unsigned words;
499
500 if (type != ARMul_DATA)
501 words = 0;
502 else {
503 ValReg[BITS (12, 15)] = data;
504
505 if (BIT (22))
506 /* It's a long access, get two words. */
507 if (words++ != 4)
508 return ARMul_INC;
509 }
510
511 return ARMul_DONE;
512}
513
514static unsigned
515ValSTC (ARMul_State * state,
516 unsigned type, ARMword instr, ARMword * data)
517{
518 static unsigned words;
519
520 if (type != ARMul_DATA)
521 words = 0;
522 else {
523 *data = ValReg[BITS (12, 15)];
524
525 if (BIT (22))
526 /* It's a long access, get two words. */
527 if (words++ != 4)
528 return ARMul_INC;
529 }
530
531 return ARMul_DONE;
532}
533
534static unsigned
535ValMRC (ARMul_State * state,
536 unsigned type, ARMword instr, ARMword * value)
537{
538 *value = ValReg[BITS (16, 19)];
539
540 return ARMul_DONE;
541}
542
543static unsigned
544ValMCR (ARMul_State * state,
545 unsigned type, ARMword instr, ARMword value)
546{
547 ValReg[BITS (16, 19)] = value;
548
549 return ARMul_DONE;
550}
551
552static unsigned
553ValCDP (ARMul_State * state, unsigned type, ARMword instr)
554{
555 static unsigned int finish = 0;
556
557 if (BITS (20, 23) != 0)
558 return ARMul_CANT;
559
560 if (type == ARMul_FIRST) {
561 ARMword howlong;
562
563 howlong = ValReg[BITS (0, 3)];
564
565 /* First cycle of a busy wait. */
566 finish = ARMul_Time (state) + howlong;
567
568 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
569 }
570 else if (type == ARMul_BUSY) {
571 if (ARMul_Time (state) >= finish)
572 return ARMul_DONE;
573 else
574 return ARMul_BUSY;
575 }
576
577 return ARMul_CANT;
578}
579
580static unsigned
581DoAFIQ (ARMul_State * state)
582{
583 state->NfiqSig = LOW;
584 return 0;
585}
586
587static unsigned
588DoAIRQ (ARMul_State * state)
589{
590 state->NirqSig = LOW;
591 return 0;
592}
593
594static unsigned
595IntCDP (ARMul_State * state, unsigned type, ARMword instr)
596{ 82{
597 static unsigned int finish; 83 /* Do not allow access to these register in USER mode. */
598 ARMword howlong; 84 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
599 85 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
600 howlong = ValReg[BITS (0, 3)]; 86 return ARMul_CANT;
601 87
602 switch ((int) BITS (20, 23)) { 88 /* Opcode_1should be zero. */
603 case 0: 89 if (opcode_1 != 0)
604 if (type == ARMul_FIRST) { 90 return ARMul_CANT;
605 /* First cycle of a busy wait. */ 91
606 finish = ARMul_Time (state) + howlong; 92 /* Different register have different access requirements. */
607 93 switch (reg) {
608 return howlong == 0 ? ARMul_DONE : ARMul_BUSY; 94 case 0:
609 } 95 case 1:
610 else if (type == ARMul_BUSY) { 96 /* CRm must be 0. Opcode_2 can be anything. */
611 if (ARMul_Time (state) >= finish) 97 if (CRm != 0)
612 return ARMul_DONE; 98 return ARMul_CANT;
613 else 99 break;
614 return ARMul_BUSY; 100 case 2:
615 } 101 case 3:
616 return ARMul_DONE; 102 /* CRm must be 0. Opcode_2 must be zero. */
617 103 if ((CRm != 0) || (opcode_2 != 0))
618 case 1: 104 return ARMul_CANT;
619 if (howlong == 0) 105 break;
620 ARMul_Abort (state, ARMul_FIQV); 106 case 4:
621 else 107 /* Access not allowed. */
622 ARMul_ScheduleEvent (state, howlong, DoAFIQ); 108 return ARMul_CANT;
623 return ARMul_DONE; 109 case 5:
624 110 case 6:
625 case 2: 111 /* Opcode_2 must be zero. CRm must be 0. */
626 if (howlong == 0) 112 if ((CRm != 0) || (opcode_2 != 0))
627 ARMul_Abort (state, ARMul_IRQV); 113 return ARMul_CANT;
628 else 114 break;
629 ARMul_ScheduleEvent (state, howlong, DoAIRQ); 115 case 7:
630 return ARMul_DONE; 116 /* Permissable combinations:
631 117 Opcode_2 CRm
632 case 3: 118 0 5
633 state->NfiqSig = HIGH; 119 0 6
634 return ARMul_DONE; 120 0 7
635 121 1 5
636 case 4: 122 1 6
637 state->NirqSig = HIGH; 123 1 10
638 return ARMul_DONE; 124 4 10
639 125 5 2
640 case 5: 126 6 5 */
641 ValReg[BITS (0, 3)] = ARMul_Time (state); 127 switch (opcode_2) {
642 return ARMul_DONE; 128 default:
643 } 129 return ARMul_CANT;
644 130 case 6:
645 return ARMul_CANT; 131 if (CRm != 5)
132 return ARMul_CANT;
133 break;
134 case 5:
135 if (CRm != 2)
136 return ARMul_CANT;
137 break;
138 case 4:
139 if (CRm != 10)
140 return ARMul_CANT;
141 break;
142 case 1:
143 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
144 return ARMul_CANT;
145 break;
146 case 0:
147 if ((CRm < 5) || (CRm > 7))
148 return ARMul_CANT;
149 break;
150 }
151 break;
152
153 case 8:
154 /* Permissable combinations:
155 Opcode_2 CRm
156 0 5
157 0 6
158 0 7
159 1 5
160 1 6 */
161 if (opcode_2 > 1)
162 return ARMul_CANT;
163 if ((CRm < 5) || (CRm > 7))
164 return ARMul_CANT;
165 if (opcode_2 == 1 && CRm == 7)
166 return ARMul_CANT;
167 break;
168 case 9:
169 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
170 if (((CRm != 0) && (CRm != 1))
171 || ((opcode_2 != 1) && (opcode_2 != 2)))
172 return ARMul_CANT;
173 break;
174 case 10:
175 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
176 if (((CRm != 0) && (CRm != 1))
177 || ((opcode_2 != 4) && (opcode_2 != 8)))
178 return ARMul_CANT;
179 break;
180 case 11:
181 /* Access not allowed. */
182 return ARMul_CANT;
183 case 12:
184 /* Access not allowed. */
185 return ARMul_CANT;
186 case 13:
187 /* Opcode_2 must be zero. CRm must be 0. */
188 if ((CRm != 0) || (opcode_2 != 0))
189 return ARMul_CANT;
190 break;
191 case 14:
192 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
193 if (opcode_2 != 0)
194 return ARMul_CANT;
195
196 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
197 && (CRm != 9))
198 return ARMul_CANT;
199 break;
200 case 15:
201 /* Opcode_2 must be zero. CRm must be 1. */
202 if ((CRm != 1) || (opcode_2 != 0))
203 return ARMul_CANT;
204 break;
205 default:
206 /* Should never happen. */
207 return ARMul_CANT;
208 }
209
210 return ARMul_DONE;
646} 211}
647 212
648/* Install co-processor instruction handlers in this routine. */ 213/* Install co-processor instruction handlers in this routine. */
649 214
650unsigned 215unsigned
651ARMul_CoProInit (ARMul_State * state) 216ARMul_CoProInit(ARMul_State * state)
652{ 217{
653 unsigned int i; 218 unsigned int i;
654 219
655 /* Initialise tham all first. */ 220 /* Initialise tham all first. */
656 for (i = 0; i < 16; i++) 221 for (i = 0; i < 16; i++)
657 ARMul_CoProDetach (state, i); 222 ARMul_CoProDetach(state, i);
658 223
659 /* Install CoPro Instruction handlers here. 224 /* Install CoPro Instruction handlers here.
660 The format is: 225 The format is:
661 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine 226 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
662 LDC routine, STC routine, MRC routine, MCR routine, 227 LDC routine, STC routine, MRC routine, MCR routine,
663 CDP routine, Read Reg routine, Write Reg routine). */ 228 CDP routine, Read Reg routine, Write Reg routine). */
664 if (state->is_ep9312) { 229 if (state->is_v6) {
665 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, 230 ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
666 DSPMRC4, DSPMCR4, NULL, NULL, DSPCDP4, NULL, NULL); 231 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
667 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, 232 ARMul_CoProAttach(state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
668 DSPMRC5, DSPMCR5, NULL, NULL, DSPCDP5, NULL, NULL); 233 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
669 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, 234
670 DSPMRC6, DSPMCR6, NULL, NULL, DSPCDP6, NULL, NULL); 235 /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
671 } 236 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/
672 else { 237 }
673 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, 238 //chy 2003-09-03 do it in future!!!!????
674 ValMRC, ValMCR, NULL, NULL, ValCDP, NULL, NULL);
675
676 ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
677 ValMRC, ValMCR, NULL, NULL, IntCDP, NULL, NULL);
678 }
679
680 if (state->is_XScale) {
681 //chy 2005-09-19, for PXA27x's CP6
682 if (state->is_pxa27x) {
683 ARMul_CoProAttach (state, 6, NULL, NULL,
684 NULL, NULL, xscale_cp6_mrc,
685 NULL, NULL, NULL, NULL, NULL, NULL);
686 }
687 //chy 2005-09-19 end-------------
688 ARMul_CoProAttach (state, 13, xscale_cp13_init,
689 xscale_cp13_exit, xscale_cp13_ldc,
690 xscale_cp13_stc, xscale_cp13_mrc,
691 xscale_cp13_mcr, NULL, NULL, xscale_cp13_cdp,
692 xscale_cp13_read_reg,
693 xscale_cp13_write_reg);
694
695 ARMul_CoProAttach (state, 14, xscale_cp14_init,
696 xscale_cp14_exit, xscale_cp14_ldc,
697 xscale_cp14_stc, xscale_cp14_mrc,
698 xscale_cp14_mcr, NULL, NULL, xscale_cp14_cdp,
699 xscale_cp14_read_reg,
700 xscale_cp14_write_reg);
701 //chy: 2003-08-24.
702 ARMul_CoProAttach (state, 15, xscale_cp15_init,
703 xscale_cp15_exit, xscale_cp15_ldc,
704 xscale_cp15_stc, xscale_cp15_mrc,
705 xscale_cp15_mcr, NULL, NULL, xscale_cp15_cdp,
706 xscale_cp15_read_reg,
707 xscale_cp15_write_reg);
708 }
709 else if (state->is_v6) {
710 ARMul_CoProAttach (state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
711 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
712 ARMul_CoProAttach (state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
713 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
714
715 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
716 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
717 }
718 else { //all except xscale
719 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
720 // MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
721 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
722 }
723//chy 2003-09-03 do it in future!!!!????
724#if 0 239#if 0
725 if (state->is_iWMMXt) { 240 if (state->is_iWMMXt) {
726 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, 241 ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
727 NULL, NULL, IwmmxtCDP, NULL, NULL); 242 NULL, NULL, IwmmxtCDP, NULL, NULL);
728 243
729 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 244 ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL,
730 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, 245 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL,
731 NULL); 246 NULL);
732 } 247 }
733#endif 248#endif
734 //----------------------------------------------------------------------------- 249 /* No handlers below here. */
735 //chy 2004-05-25, found the user/system code visit CP 1,2, so I add below code. 250
736 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 251 /* Call all the initialisation routines. */
737 ValMRC, ValMCR, NULL, NULL, NULL, NULL, NULL); 252 for (i = 0; i < 16; i++)
738 ARMul_CoProAttach (state, 2, NULL, NULL, ValLDC, ValSTC, 253 if (state->CPInit[i])
739 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 254 (state->CPInit[i]) (state);
740 //------------------------------------------------------------------------------ 255
741 /* No handlers below here. */ 256 return TRUE;
742
743 /* Call all the initialisation routines. */
744 for (i = 0; i < 16; i++)
745 if (state->CPInit[i])
746 (state->CPInit[i]) (state);
747
748 return TRUE;
749} 257}
750 258
751/* Install co-processor finalisation routines in this routine. */ 259/* Install co-processor finalisation routines in this routine. */
752 260
753void 261void
754ARMul_CoProExit (ARMul_State * state) 262ARMul_CoProExit(ARMul_State * state)
755{ 263{
756 register unsigned i; 264 register unsigned i;
757 265
758 for (i = 0; i < 16; i++) 266 for (i = 0; i < 16; i++)
759 if (state->CPExit[i]) 267 if (state->CPExit[i])
760 (state->CPExit[i]) (state); 268 (state->CPExit[i]) (state);
761 269
762 for (i = 0; i < 16; i++) /* Detach all handlers. */ 270 for (i = 0; i < 16; i++) /* Detach all handlers. */
763 ARMul_CoProDetach (state, i); 271 ARMul_CoProDetach(state, i);
764} 272}
765 273
766/* Routines to hook Co-processors into ARMulator. */ 274/* Routines to hook Co-processors into ARMulator. */
767 275
768void 276void
769ARMul_CoProAttach (ARMul_State * state, 277ARMul_CoProAttach(ARMul_State * state,
770 unsigned number, 278unsigned number,
771 ARMul_CPInits * init, 279ARMul_CPInits * init,
772 ARMul_CPExits * exit, 280ARMul_CPExits * exit,
773 ARMul_LDCs * ldc, 281ARMul_LDCs * ldc,
774 ARMul_STCs * stc, 282ARMul_STCs * stc,
775 ARMul_MRCs * mrc, 283ARMul_MRCs * mrc,
776 ARMul_MCRs * mcr, 284ARMul_MCRs * mcr,
777 ARMul_MRRCs * mrrc, 285ARMul_MRRCs * mrrc,
778 ARMul_MCRRs * mcrr, 286ARMul_MCRRs * mcrr,
779 ARMul_CDPs * cdp, 287ARMul_CDPs * cdp,
780 ARMul_CPReads * read, ARMul_CPWrites * write) 288ARMul_CPReads * read, ARMul_CPWrites * write)
781{
782 if (init != NULL)
783 state->CPInit[number] = init;
784 if (exit != NULL)
785 state->CPExit[number] = exit;
786 if (ldc != NULL)
787 state->LDC[number] = ldc;
788 if (stc != NULL)
789 state->STC[number] = stc;
790 if (mrc != NULL)
791 state->MRC[number] = mrc;
792 if (mcr != NULL)
793 state->MCR[number] = mcr;
794 if (mrrc != NULL)
795 state->MRRC[number] = mrrc;
796 if (mcrr != NULL)
797 state->MCRR[number] = mcrr;
798 if (cdp != NULL)
799 state->CDP[number] = cdp;
800 if (read != NULL)
801 state->CPRead[number] = read;
802 if (write != NULL)
803 state->CPWrite[number] = write;
804}
805
806void
807ARMul_CoProDetach (ARMul_State * state, unsigned number)
808{ 289{
809 ARMul_CoProAttach (state, number, NULL, NULL, 290 if (init != NULL)
810 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, 291 state->CPInit[number] = init;
811 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL); 292 if (exit != NULL)
812 293 state->CPExit[number] = exit;
813 state->CPInit[number] = NULL; 294 if (ldc != NULL)
814 state->CPExit[number] = NULL; 295 state->LDC[number] = ldc;
815 state->CPRead[number] = NULL; 296 if (stc != NULL)
816 state->CPWrite[number] = NULL; 297 state->STC[number] = stc;
298 if (mrc != NULL)
299 state->MRC[number] = mrc;
300 if (mcr != NULL)
301 state->MCR[number] = mcr;
302 if (mrrc != NULL)
303 state->MRRC[number] = mrrc;
304 if (mcrr != NULL)
305 state->MCRR[number] = mcrr;
306 if (cdp != NULL)
307 state->CDP[number] = cdp;
308 if (read != NULL)
309 state->CPRead[number] = read;
310 if (write != NULL)
311 state->CPWrite[number] = write;
817} 312}
818 313
819//chy 2003-09-03:below funs just replace the old ones
820
821/* Set the XScale FSR and FAR registers. */
822
823void 314void
824XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far) 315ARMul_CoProDetach(ARMul_State * state, unsigned number)
825{
826 //if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
827 if (!state->is_XScale)
828 return;
829 //assume opcode2=0 crm =0
830 xscale_cp15_write_reg (state, 5, fsr);
831 xscale_cp15_write_reg (state, 6, _far);
832}
833
834//chy 2003-09-03 seems 0 is CANT, 1 is DONE ????
835int
836XScale_debug_moe (ARMul_State * state, int moe)
837{ 316{
838 //chy 2003-09-03 , W/R CP14 reg, now it's no use ???? 317 ARMul_CoProAttach(state, number, NULL, NULL,
839 printf ("SKYEYE: XScale_debug_moe called !!!!\n"); 318 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
840 return 1; 319 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL);
320
321 state->CPInit[number] = NULL;
322 state->CPExit[number] = NULL;
323 state->CPRead[number] = NULL;
324 state->CPWrite[number] = NULL;
841} 325}
diff --git a/src/core/arm/interpreter/armmmu.cpp b/src/core/arm/interpreter/armmmu.cpp
deleted file mode 100644
index 98fc17ddb..000000000
--- a/src/core/arm/interpreter/armmmu.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
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#include "core/arm/skyeye_common/armdefs.h"
24/* two header for arm disassemble */
25//#include "skyeye_arch.h"
26#include "core/arm/skyeye_common/armcpu.h"
27
28
29extern mmu_ops_t xscale_mmu_ops;
30exception_t arm_mmu_write(short size, u32 addr, uint32_t *value);
31exception_t arm_mmu_read(short size, u32 addr, uint32_t *value);
32#define MMU_OPS (state->mmu.ops)
33ARMword skyeye_cachetype = -1;
34
35int
36mmu_init (ARMul_State * state)
37{
38 int ret;
39
40 state->mmu.control = 0x70;
41 state->mmu.translation_table_base = 0xDEADC0DE;
42 state->mmu.domain_access_control = 0xDEADC0DE;
43 state->mmu.fault_status = 0;
44 state->mmu.fault_address = 0;
45 state->mmu.process_id = 0;
46
47 switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
48 //case SA1100:
49 //case SA1110:
50 // NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n");
51 // state->mmu.ops = sa_mmu_ops;
52 // break;
53 //case PXA250:
54 //case PXA270: //xscale
55 // NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n");
56 // state->mmu.ops = xscale_mmu_ops;
57 // break;
58 //case 0x41807200: //arm720t
59 //case 0x41007700: //arm7tdmi
60 //case 0x41007100: //arm7100
61 // NOTICE_LOG(ARM11, "SKYEYE: use arm7100 mmu ops\n");
62 // state->mmu.ops = arm7100_mmu_ops;
63 // break;
64 //case 0x41009200:
65 // NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n");
66 // state->mmu.ops = arm920t_mmu_ops;
67 // break;
68 //case 0x41069260:
69 // NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n");
70 // state->mmu.ops = arm926ejs_mmu_ops;
71 // break;
72 /* case 0x560f5810: */
73 case 0x0007b000:
74 NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
75 state->mmu.ops = arm1176jzf_s_mmu_ops;
76 break;
77
78 default:
79 ERROR_LOG (ARM11,
80 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
81 state->cpu->cpu_val & state->cpu->cpu_mask);
82 break;
83
84 };
85 ret = state->mmu.ops.init (state);
86 state->mmu_inited = (ret == 0);
87 /* initialize mmu_read and mmu_write for disassemble */
88 //skyeye_config_t *config = get_current_config();
89 //generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name);
90 //arch_instance->mmu_read = arm_mmu_read;
91 //arch_instance->mmu_write = arm_mmu_write;
92
93 return ret;
94}
95
96int
97mmu_reset (ARMul_State * state)
98{
99 if (state->mmu_inited)
100 mmu_exit (state);
101 return mmu_init (state);
102}
103
104void
105mmu_exit (ARMul_State * state)
106{
107 MMU_OPS.exit (state);
108 state->mmu_inited = 0;
109}
110
111fault_t
112mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
113{
114 return MMU_OPS.read_byte (state, virt_addr, data);
115};
116
117fault_t
118mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
119{
120 return MMU_OPS.read_halfword (state, virt_addr, data);
121};
122
123fault_t
124mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
125{
126 return MMU_OPS.read_word (state, virt_addr, data);
127};
128
129fault_t
130mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
131{
132 fault_t fault;
133 //static int count = 0;
134 //count ++;
135 fault = MMU_OPS.write_byte (state, virt_addr, data);
136 return fault;
137}
138
139fault_t
140mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
141{
142 fault_t fault;
143 //static int count = 0;
144 //count ++;
145 fault = MMU_OPS.write_halfword (state, virt_addr, data);
146 return fault;
147}
148
149fault_t
150mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
151{
152 fault_t fault;
153 fault = MMU_OPS.write_word (state, virt_addr, data);
154
155 /*used for debug for MMU*
156
157 if (!fault){
158 ARMword tmp;
159
160 if (mmu_read_word(state, virt_addr, &tmp)){
161 err_msg("load back\n");
162 exit(-1);
163 }else{
164 if (tmp != data){
165 err_msg("load back not equal %d %x\n", count, virt_addr);
166 }
167 }
168 }
169 */
170
171 return fault;
172};
173
174fault_t
175mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr)
176{
177 return MMU_OPS.load_instr (state, virt_addr, instr);
178}
179
180ARMword
181mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
182{
183 return MMU_OPS.mrc (state, instr, value);
184}
185
186void
187mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
188{
189 MMU_OPS.mcr (state, instr, value);
190}
191
192/*ywc 20050416*/
193int
194mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
195{
196 return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr));
197}
198
199//
200//
201///* dis_mmu_read for disassemble */
202//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value)
203//{
204// ARMul_State *state;
205// ARM_CPU_State *cpu = get_current_cpu();
206// state = &cpu->core[0];
207// switch(size){
208// case 8:
209// MMU_OPS.read_byte (state, addr, value);
210// break;
211// case 16:
212// case 32:
213// break;
214// default:
215// ERROR_LOG(ARM11, "Error size %d", size);
216// break;
217// }
218// return No_exp;
219//}
220///* dis_mmu_write for disassemble */
221//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value)
222//{
223// ARMul_State *state;
224// ARM_CPU_State *cpu = get_current_cpu();
225// state = &cpu->core[0];
226// switch(size){
227// case 8:
228// MMU_OPS.write_byte (state, addr, value);
229// break;
230// case 16:
231// case 32:
232// break;
233// default:
234// printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
235// break;
236// }
237// return No_exp;
238//}
diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp
index eb3c86cb4..7845d1042 100644
--- a/src/core/arm/interpreter/armvirt.cpp
+++ b/src/core/arm/interpreter/armvirt.cpp
@@ -24,657 +24,142 @@ freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */ 24defined to generate aborts. */
25 25
26#include "core/arm/skyeye_common/armdefs.h" 26#include "core/arm/skyeye_common/armdefs.h"
27#include "core/arm/skyeye_common/skyeye_defs.h" 27#include "core/arm/skyeye_common/armemu.h"
28//#include "code_cov.h"
29 28
30#ifdef VALIDATE /* for running the validate suite */ 29#include "core/mem_map.h"
31#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
32#define ABORTS 1
33#endif
34
35/* #define ABORTS */
36
37#ifdef ABORTS /* the memory system will abort */
38/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39 For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40/* #define LOWABORT 32 * 1024
41#define HIGHABORT 32 * 1024 * 1024 */
42#define LOWABORT 8 * 1024 * 1024
43#define HIGHABORT 26 * 1024 * 1024
44
45#endif
46
47#define NUMPAGES 64 * 1024
48#define PAGESIZE 64 * 1024
49#define PAGEBITS 16
50#define OFFSETBITS 0xffff
51//chy 2003-08-19: seems no use ????
52int SWI_vector_installed = FALSE;
53extern ARMword skyeye_cachetype;
54
55/***************************************************************************\
56* Get a byte into Virtual Memory, maybe allocating the page *
57\***************************************************************************/
58static fault_t
59GetByte (ARMul_State * state, ARMword address, ARMword * data)
60{
61 fault_t fault;
62
63 fault = mmu_read_byte (state, address, data);
64 if (fault) {
65//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
66// printf("SKYEYE: GetByte fault %d \n", fault);
67 }
68 return fault;
69}
70
71/***************************************************************************\
72* Get a halfword into Virtual Memory, maybe allocating the page *
73\***************************************************************************/
74static fault_t
75GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
76{
77 fault_t fault;
78
79 fault = mmu_read_halfword (state, address, data);
80 if (fault) {
81//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
82// printf("SKYEYE: GetHalfWord fault %d \n", fault);
83 }
84 return fault;
85}
86
87/***************************************************************************\
88* Get a Word from Virtual Memory, maybe allocating the page *
89\***************************************************************************/
90 30
91static fault_t 31#define dumpstack 1
92GetWord (ARMul_State * state, ARMword address, ARMword * data) 32#define dumpstacksize 0x10
93{ 33#define maxdmupaddr 0x0033a850
94 fault_t fault;
95 34
96 fault = mmu_read_word (state, address, data); 35/*ARMword ARMul_GetCPSR (ARMul_State * state) {
97 if (fault) { 36return 0;
98//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
99#if 0
100/* XXX */ extern int hack;
101 hack = 1;
102#endif
103#if 0
104 printf ("mmu_read_word at 0x%08x: ", address);
105 switch (fault) {
106 case ALIGNMENT_FAULT:
107 printf ("ALIGNMENT_FAULT");
108 break;
109 case SECTION_TRANSLATION_FAULT:
110 printf ("SECTION_TRANSLATION_FAULT");
111 break;
112 case PAGE_TRANSLATION_FAULT:
113 printf ("PAGE_TRANSLATION_FAULT");
114 break;
115 case SECTION_DOMAIN_FAULT:
116 printf ("SECTION_DOMAIN_FAULT");
117 break;
118 case SECTION_PERMISSION_FAULT:
119 printf ("SECTION_PERMISSION_FAULT");
120 break;
121 case SUBPAGE_PERMISSION_FAULT:
122 printf ("SUBPAGE_PERMISSION_FAULT");
123 break;
124 default:
125 printf ("Unrecognized fault number!");
126 }
127 printf ("\tpc = 0x%08x\n", state->Reg[15]);
128#endif
129 }
130 return fault;
131} 37}
132 38ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode) {
133//2003-07-10 chy: lyh change 39return 0;
134/****************************************************************************\
135 * Load a Instrion Word into Virtual Memory *
136\****************************************************************************/
137static fault_t
138LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
139{
140 fault_t fault;
141 fault = mmu_load_instr (state, address, instr);
142 return fault;
143 //if (fault)
144 // log_msg("load_instr fault = %d, address = %x\n", fault, address);
145} 40}
41void ARMul_SetCPSR (ARMul_State * state, ARMword value) {
146 42
147/***************************************************************************\
148* Put a byte into Virtual Memory, maybe allocating the page *
149\***************************************************************************/
150static fault_t
151PutByte (ARMul_State * state, ARMword address, ARMword data)
152{
153 fault_t fault;
154
155 fault = mmu_write_byte (state, address, data);
156 if (fault) {
157//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
158// printf("SKYEYE: PutByte fault %d \n", fault);
159 }
160 return fault;
161} 43}
44void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) {
162 45
163/***************************************************************************\ 46}*/
164* Put a halfword into Virtual Memory, maybe allocating the page *
165\***************************************************************************/
166static fault_t
167PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
168{
169 fault_t fault;
170 47
171 fault = mmu_write_halfword (state, address, data); 48void ARMul_Icycles(ARMul_State * state, unsigned number, ARMword address) {
172 if (fault) {
173//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
174// printf("SKYEYE: PutHalfWord fault %d \n", fault);
175 }
176 return fault;
177} 49}
178 50
179/***************************************************************************\ 51void ARMul_Ccycles(ARMul_State * state, unsigned number, ARMword address) {
180* Put a Word into Virtual Memory, maybe allocating the page *
181\***************************************************************************/
182
183static fault_t
184PutWord (ARMul_State * state, ARMword address, ARMword data)
185{
186 fault_t fault;
187
188 fault = mmu_write_word (state, address, data);
189 if (fault) {
190//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
191#if 0
192/* XXX */ extern int hack;
193 hack = 1;
194#endif
195#if 0
196 printf ("mmu_write_word at 0x%08x: ", address);
197 switch (fault) {
198 case ALIGNMENT_FAULT:
199 printf ("ALIGNMENT_FAULT");
200 break;
201 case SECTION_TRANSLATION_FAULT:
202 printf ("SECTION_TRANSLATION_FAULT");
203 break;
204 case PAGE_TRANSLATION_FAULT:
205 printf ("PAGE_TRANSLATION_FAULT");
206 break;
207 case SECTION_DOMAIN_FAULT:
208 printf ("SECTION_DOMAIN_FAULT");
209 break;
210 case SECTION_PERMISSION_FAULT:
211 printf ("SECTION_PERMISSION_FAULT");
212 break;
213 case SUBPAGE_PERMISSION_FAULT:
214 printf ("SUBPAGE_PERMISSION_FAULT");
215 break;
216 default:
217 printf ("Unrecognized fault number!");
218 }
219 printf ("\tpc = 0x%08x\n", state->Reg[15]);
220#endif
221 }
222 return fault;
223} 52}
224 53
225/***************************************************************************\ 54ARMword ARMul_LoadInstrS(ARMul_State * state, ARMword address, ARMword isize) {
226* Initialise the memory interface * 55 state->NumScycles++;
227\***************************************************************************/
228
229unsigned
230ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
231{
232 return TRUE;
233}
234
235/***************************************************************************\
236* Remove the memory interface *
237\***************************************************************************/
238
239void
240ARMul_MemoryExit (ARMul_State * state)
241{
242}
243
244/***************************************************************************\
245* ReLoad Instruction *
246\***************************************************************************/
247
248ARMword
249ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
250{
251 ARMword data;
252 fault_t fault;
253
254#ifdef ABORTS
255 if (address >= LOWABORT && address < HIGHABORT) {
256 ARMul_PREFETCHABORT (address);
257 return ARMul_ABORTWORD;
258 }
259 else {
260 ARMul_CLEARABORT;
261 }
262#endif
263#if 0
264 /* do profiling for code coverage */
265 if (skyeye_config.code_cov.prof_on)
266 cov_prof(EXEC_FLAG, address);
267#endif
268#if 1
269 if ((isize == 2) && (address & 0x2)) {
270 ARMword lo, hi;
271 if (!(skyeye_cachetype == INSTCACHE))
272 fault = GetHalfWord (state, address, &lo);
273 else
274 fault = LoadInstr (state, address, &lo);
275#if 0
276 if (!fault) {
277 if (!(skyeye_cachetype == INSTCACHE))
278 fault = GetHalfWord (state, address + isize, &hi);
279 else
280 fault = LoadInstr (state, address + isize, &hi);
281
282 }
283#endif
284 if (fault) {
285 ARMul_PREFETCHABORT (address);
286 return ARMul_ABORTWORD;
287 }
288 else {
289 ARMul_CLEARABORT;
290 }
291 return lo;
292#if 0
293 if (state->bigendSig == HIGH)
294 return (lo << 16) | (hi >> 16);
295 else
296 return ((hi & 0xFFFF) << 16) | (lo >> 16);
297#endif
298 }
299#endif
300 if (!(skyeye_cachetype == INSTCACHE))
301 fault = GetWord (state, address, &data);
302 else
303 fault = LoadInstr (state, address, &data);
304
305 if (fault) {
306
307 /* dyf add for s3c6410 no instcache temporary 2010.9.17 */
308 if (!(skyeye_cachetype == INSTCACHE)) {
309 /* set translation fault on prefetch abort */
310 state->mmu.fault_statusi = fault & 0xFF;
311 state->mmu.fault_address = address;
312 }
313 /* add end */
314
315 ARMul_PREFETCHABORT (address);
316 return ARMul_ABORTWORD;
317 }
318 else {
319 ARMul_CLEARABORT;
320 }
321
322 return data;
323}
324
325/***************************************************************************\
326* Load Instruction, Sequential Cycle *
327\***************************************************************************/
328
329ARMword
330ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
331{
332 state->NumScycles++;
333 56
334#ifdef HOURGLASS 57#ifdef HOURGLASS
335 if ((state->NumScycles & HOURGLASS_RATE) == 0) { 58 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
336 HOURGLASS; 59 HOURGLASS;
337 } 60 }
338#endif 61#endif
339 62 if (isize == 2)
340 return ARMul_ReLoadInstr (state, address, isize); 63 return (u16)Memory::Read16(address);
64 else
65 return (u32)Memory::Read32(address);
341} 66}
342 67
343/***************************************************************************\ 68ARMword ARMul_LoadInstrN(ARMul_State * state, ARMword address, ARMword isize) {
344* Load Instruction, Non Sequential Cycle * 69 state->NumNcycles++;
345\***************************************************************************/
346
347ARMword
348ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
349{
350 state->NumNcycles++;
351 70
352 return ARMul_ReLoadInstr (state, address, isize); 71 if (isize == 2)
72 return (u16)Memory::Read16(address);
73 else
74 return (u32)Memory::Read32(address);
353} 75}
354 76
355/***************************************************************************\ 77ARMword ARMul_ReLoadInstr(ARMul_State * state, ARMword address, ARMword isize) {
356* Read Word (but don't tell anyone!) * 78 ARMword data;
357\***************************************************************************/
358 79
359ARMword 80 if ((isize == 2) && (address & 0x2)) {
360ARMul_ReadWord (ARMul_State * state, ARMword address) 81 ARMword lo;
361{ 82 lo = (u16)Memory::Read16(address);
362 ARMword data; 83 return lo;
363 fault_t fault; 84 }
364
365#ifdef ABORTS
366 if (address >= LOWABORT && address < HIGHABORT) {
367 ARMul_DATAABORT (address);
368 return ARMul_ABORTWORD;
369 }
370 else {
371 ARMul_CLEARABORT;
372 }
373#endif
374 85
375 fault = GetWord (state, address, &data); 86 data = (u32)Memory::Read32(address);
376 if (fault) { 87 return data;
377 state->mmu.fault_status =
378 (fault | (state->mmu.last_domain << 4)) & 0xFF;
379 state->mmu.fault_address = address;
380 ARMul_DATAABORT (address);
381 return ARMul_ABORTWORD;
382 }
383 else {
384 ARMul_CLEARABORT;
385 }
386 return data;
387} 88}
388 89
389/***************************************************************************\ 90ARMword ARMul_ReadWord(ARMul_State * state, ARMword address) {
390* Load Word, Sequential Cycle * 91 ARMword data;
391\***************************************************************************/ 92 data = Memory::Read32(address);
392 93 return data;
393ARMword
394ARMul_LoadWordS (ARMul_State * state, ARMword address)
395{
396 state->NumScycles++;
397
398 return ARMul_ReadWord (state, address);
399} 94}
400 95
401/***************************************************************************\ 96ARMword ARMul_LoadWordS(ARMul_State * state, ARMword address) {
402* Load Word, Non Sequential Cycle * 97 state->NumScycles++;
403\***************************************************************************/ 98 return ARMul_ReadWord(state, address);
404
405ARMword
406ARMul_LoadWordN (ARMul_State * state, ARMword address)
407{
408 state->NumNcycles++;
409
410 return ARMul_ReadWord (state, address);
411} 99}
412 100
413/***************************************************************************\ 101ARMword ARMul_LoadWordN(ARMul_State * state, ARMword address) {
414* Load Halfword, (Non Sequential Cycle) * 102 state->NumNcycles++;
415\***************************************************************************/ 103 return ARMul_ReadWord(state, address);
416
417ARMword
418ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
419{
420 ARMword data;
421 fault_t fault;
422
423 state->NumNcycles++;
424 fault = GetHalfWord (state, address, &data);
425
426 if (fault) {
427 state->mmu.fault_status =
428 (fault | (state->mmu.last_domain << 4)) & 0xFF;
429 state->mmu.fault_address = address;
430 ARMul_DATAABORT (address);
431 return ARMul_ABORTWORD;
432 }
433 else {
434 ARMul_CLEARABORT;
435 }
436
437 return data;
438
439} 104}
440 105
441/***************************************************************************\ 106ARMword ARMul_LoadHalfWord(ARMul_State * state, ARMword address) {
442* Read Byte (but don't tell anyone!) * 107 state->NumNcycles++;
443\***************************************************************************/ 108 return (u16)Memory::Read16(address);;
444int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
445{
446 ARMword data;
447 fault_t fault;
448 fault = GetByte (state, address, &data);
449 if (fault) {
450 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
451 }else{
452 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
453 }
454} 109}
455
456
457ARMword
458ARMul_ReadByte (ARMul_State * state, ARMword address)
459{
460 ARMword data;
461 fault_t fault;
462
463 fault = GetByte (state, address, &data);
464
465 if (fault) {
466 state->mmu.fault_status =
467 (fault | (state->mmu.last_domain << 4)) & 0xFF;
468 state->mmu.fault_address = address;
469 ARMul_DATAABORT (address);
470 return ARMul_ABORTWORD;
471 }
472 else {
473 ARMul_CLEARABORT;
474 }
475
476 return data;
477
478}
479
480/***************************************************************************\
481* Load Byte, (Non Sequential Cycle) *
482\***************************************************************************/
483
484ARMword
485ARMul_LoadByte (ARMul_State * state, ARMword address)
486{
487 state->NumNcycles++;
488
489 return ARMul_ReadByte (state, address);
490}
491
492/***************************************************************************\
493* Write Word (but don't tell anyone!) *
494\***************************************************************************/
495
496void
497ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
498{
499 fault_t fault;
500
501#ifdef ABORTS
502 if (address >= LOWABORT && address < HIGHABORT) {
503 ARMul_DATAABORT (address);
504 return;
505 }
506 else {
507 ARMul_CLEARABORT;
508 }
509#endif
510 110
511 fault = PutWord (state, address, data); 111ARMword ARMul_ReadByte(ARMul_State * state, ARMword address) {
512 if (fault) { 112 return (u8)Memory::Read8(address);
513 state->mmu.fault_status =
514 (fault | (state->mmu.last_domain << 4)) & 0xFF;
515 state->mmu.fault_address = address;
516 ARMul_DATAABORT (address);
517 return;
518 }
519 else {
520 ARMul_CLEARABORT;
521 }
522} 113}
523 114
524/***************************************************************************\ 115ARMword ARMul_LoadByte(ARMul_State * state, ARMword address) {
525* Store Word, Sequential Cycle * 116 state->NumNcycles++;
526\***************************************************************************/ 117 return ARMul_ReadByte(state, address);
527
528void
529ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
530{
531 state->NumScycles++;
532
533 ARMul_WriteWord (state, address, data);
534} 118}
535 119
536/***************************************************************************\ 120void ARMul_StoreHalfWord(ARMul_State * state, ARMword address, ARMword data) {
537* Store Word, Non Sequential Cycle * 121 state->NumNcycles++;
538\***************************************************************************/ 122 Memory::Write16(address, data);
539
540void
541ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
542{
543 state->NumNcycles++;
544
545 ARMul_WriteWord (state, address, data);
546} 123}
547 124
548/***************************************************************************\ 125void ARMul_StoreByte(ARMul_State * state, ARMword address, ARMword data) {
549* Store HalfWord, (Non Sequential Cycle) * 126 state->NumNcycles++;
550\***************************************************************************/ 127 ARMul_WriteByte(state, address, data);
551
552void
553ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
554{
555 fault_t fault;
556 state->NumNcycles++;
557 fault = PutHalfWord (state, address, data);
558 if (fault) {
559 state->mmu.fault_status =
560 (fault | (state->mmu.last_domain << 4)) & 0xFF;
561 state->mmu.fault_address = address;
562 ARMul_DATAABORT (address);
563 return;
564 }
565 else {
566 ARMul_CLEARABORT;
567 }
568} 128}
569 129
570//chy 2006-04-15 130ARMword ARMul_SwapWord(ARMul_State * state, ARMword address, ARMword data) {
571int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data) 131 ARMword temp;
572{ 132 state->NumNcycles++;
573 fault_t fault; 133 temp = ARMul_ReadWord(state, address);
574 fault = PutByte (state, address, data); 134 state->NumNcycles++;
575 if (fault) 135 Memory::Write32(address, data);
576 return 1; 136 return temp;
577 else
578 return 0;
579}
580/***************************************************************************\
581* Write Byte (but don't tell anyone!) *
582\***************************************************************************/
583//chy 2003-07-10, add real write byte fun
584void
585ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
586{
587 fault_t fault;
588 fault = PutByte (state, address, data);
589 if (fault) {
590 state->mmu.fault_status =
591 (fault | (state->mmu.last_domain << 4)) & 0xFF;
592 state->mmu.fault_address = address;
593 ARMul_DATAABORT (address);
594 return;
595 }
596 else {
597 ARMul_CLEARABORT;
598 }
599} 137}
600 138
601/***************************************************************************\ 139ARMword ARMul_SwapByte(ARMul_State * state, ARMword address, ARMword data) {
602* Store Byte, (Non Sequential Cycle) * 140 ARMword temp;
603\***************************************************************************/ 141 temp = ARMul_LoadByte(state, address);
604 142 Memory::Write8(address, data);
605void 143 return temp;
606ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
607{
608 state->NumNcycles++;
609
610#ifdef VALIDATE
611 if (address == TUBE) {
612 if (data == 4)
613 state->Emulate = FALSE;
614 else
615 (void) putc ((char) data, stderr); /* Write Char */
616 return;
617 }
618#endif
619
620 ARMul_WriteByte (state, address, data);
621} 144}
622 145
623/***************************************************************************\ 146void ARMul_WriteWord(ARMul_State * state, ARMword address, ARMword data) {
624* Swap Word, (Two Non Sequential Cycles) * 147 Memory::Write32(address, data);
625\***************************************************************************/
626
627ARMword
628ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
629{
630 ARMword temp;
631
632 state->NumNcycles++;
633
634 temp = ARMul_ReadWord (state, address);
635
636 state->NumNcycles++;
637
638 PutWord (state, address, data);
639
640 return temp;
641} 148}
642 149
643/***************************************************************************\ 150void ARMul_WriteByte(ARMul_State * state, ARMword address, ARMword data)
644* Swap Byte, (Two Non Sequential Cycles) *
645\***************************************************************************/
646
647ARMword
648ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
649{ 151{
650 ARMword temp; 152 Memory::Write8(address, data);
651
652 temp = ARMul_LoadByte (state, address);
653 ARMul_StoreByte (state, address, data);
654
655 return temp;
656} 153}
657 154
658/***************************************************************************\ 155void ARMul_StoreWordS(ARMul_State * state, ARMword address, ARMword data)
659* Count I Cycles *
660\***************************************************************************/
661
662void
663ARMul_Icycles (ARMul_State * state, unsigned number,
664 ARMword address)
665{ 156{
666 state->NumIcycles += number; 157 state->NumScycles++;
667 ARMul_CLEARABORT; 158 ARMul_WriteWord(state, address, data);
668} 159}
669 160
670/***************************************************************************\ 161void ARMul_StoreWordN(ARMul_State * state, ARMword address, ARMword data)
671* Count C Cycles *
672\***************************************************************************/
673
674void
675ARMul_Ccycles (ARMul_State * state, unsigned number,
676 ARMword address)
677{ 162{
678 state->NumCcycles += number; 163 state->NumNcycles++;
679 ARMul_CLEARABORT; 164 ARMul_WriteWord(state, address, data);
680} 165}
diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
deleted file mode 100644
index 07951e0e6..000000000
--- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
+++ /dev/null
@@ -1,1132 +0,0 @@
1/*
2 arm1176jzf_s_mmu.c - ARM920T Memory Management Unit emulation.
3 Copyright (C) 2003 Skyeye Develop Group
4 for help please send mail to <skyeye-developer@lists.gro.clinux.org>
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#include <stdint.h>
24
25#include "core/mem_map.h"
26
27#include "core/arm/skyeye_common/skyeye_defs.h"
28
29#include "core/arm/skyeye_common/armdefs.h"
30//#include "bank_defs.h"
31#if 0
32#define TLB_SIZE 1024 * 1024
33#define ASID 255
34static uint32_t tlb_entry_array[TLB_SIZE][ASID];
35static inline void invalidate_all_tlb(ARMul_State *state){
36 memset(&tlb_entry_array[0], 0xFF, sizeof(uint32_t) * TLB_SIZE * ASID);
37}
38static inline void invalidate_by_mva(ARMul_State *state, ARMword va){
39 memset(&tlb_entry_array[va >> 12][va & 0xFF], 0xFF, sizeof(uint32_t));
40 return;
41}
42static inline void invalidate_by_asid(ARMul_State *state, ARMword asid){
43 int i;
44 for(i = 0; i < TLB_SIZE; i++)
45 memset(&tlb_entry_array[i][asid & 0xFF], 0xFF, sizeof(uint32_t));
46 return;
47}
48
49static uint32_t get_phys_page(ARMul_State* state, ARMword va){
50 uint32_t phys_page = tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF];
51 //printf("In %s, for va=0x%x, page=0x%x\n", __func__, va, phys_page);
52 return phys_page;
53}
54
55static inline void insert_tlb(ARMul_State* state, ARMword va, ARMword pa){
56 //printf("In %s, insert va=0x%x, pa=0x%x\n", __FUNCTION__, va, pa);
57 //printf("In %s, insert va=0x%x, va>>12=0x%x, pa=0x%x, pa>>12=0x%x\n", __FUNCTION__, va, va >> 12, pa, pa >> 12);
58 tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF] = pa >> 12;
59
60 return;
61}
62#endif
63#define BANK0_START 0x50000000
64static void* mem_ptr = NULL;
65
66static int exclusive_detect(ARMul_State* state, ARMword addr){
67 #if 0
68 for(int i = 0; i < 128; i++){
69 if(state->exclusive_tag_array[i] == addr)
70 return 0;
71 }
72 #endif
73 if(state->exclusive_tag_array[0] == addr)
74 return 0;
75 else
76 return -1;
77}
78
79static void add_exclusive_addr(ARMul_State* state, ARMword addr){
80 #if 0
81 for(int i = 0; i < 128; i++){
82 if(state->exclusive_tag_array[i] == 0xffffffff){
83 state->exclusive_tag_array[i] = addr;
84 //printf("In %s, add addr 0x%x\n", __func__, addr);
85 return;
86 }
87 }
88 printf("In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
89 #endif
90 state->exclusive_tag_array[0] = addr;
91 return;
92}
93
94static void remove_exclusive(ARMul_State* state, ARMword addr){
95 #if 0
96 int i;
97 for(i = 0; i < 128; i++){
98 if(state->exclusive_tag_array[i] == addr){
99 state->exclusive_tag_array[i] = 0xffffffff;
100 //printf("In %s, remove addr 0x%x\n", __func__, addr);
101 return;
102 }
103 }
104 #endif
105 state->exclusive_tag_array[0] = 0xFFFFFFFF;
106}
107
108/* This function encodes table 8-2 Interpreting AP bits,
109 returning non-zero if access is allowed. */
110static int
111check_perms (ARMul_State *state, int ap, int read)
112{
113 int s, r, user;
114
115 s = state->mmu.control & CONTROL_SYSTEM;
116 r = state->mmu.control & CONTROL_ROM;
117 /* chy 2006-02-15 , should consider system mode, don't conside 26bit mode */
118// printf("ap is %x, user is %x, s is %x, read is %x\n", ap, user, s, read);
119// printf("mode is %x\n", state->Mode);
120 user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE);
121
122 switch (ap) {
123 case 0:
124 return read && ((s && !user) || r);
125 case 1:
126 return !user;
127 case 2:
128 return read || !user;
129 case 3:
130 return 1;
131 }
132 return 0;
133}
134
135#if 0
136fault_t
137check_access (ARMul_State *state, ARMword virt_addr, tlb_entry_t *tlb,
138 int read)
139{
140 int access;
141
142 state->mmu.last_domain = tlb->domain;
143 access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3;
144 if ((access == 0) || (access == 2)) {
145 /* It's unclear from the documentation whether this
146 should always raise a section domain fault, or if
147 it should be a page domain fault in the case of an
148 L1 that describes a page table. In the ARM710T
149 datasheets, "Figure 8-9: Sequence for checking faults"
150 seems to indicate the former, while "Table 8-4: Priority
151 encoding of fault status" gives a value for FS[3210] in
152 the event of a domain fault for a page. Hmm. */
153 return SECTION_DOMAIN_FAULT;
154 }
155 if (access == 1) {
156 /* client access - check perms */
157 int subpage, ap;
158#if 0
159 switch (tlb->mapping) {
160 /*ks 2004-05-09
161 * only for XScale
162 * Extend Small Page(ESP) Format
163 * 31-12 bits the base addr of ESP
164 * 11-10 bits SBZ
165 * 9-6 bits TEX
166 * 5-4 bits AP
167 * 3 bit C
168 * 2 bit B
169 * 1-0 bits 11
170 * */
171 case TLB_ESMALLPAGE: /* xj */
172 subpage = 0;
173 /* printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr ); */
174 break;
175
176 case TLB_TINYPAGE:
177 subpage = 0;
178 /* printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr ); */
179 break;
180
181 case TLB_SMALLPAGE:
182 subpage = (virt_addr >> 10) & 3;
183 break;
184 case TLB_LARGEPAGE:
185 subpage = (virt_addr >> 14) & 3;
186 break;
187 case TLB_SECTION:
188 subpage = 3;
189 break;
190 default:
191 assert (0);
192 subpage = 0; /* cleans a warning */
193 }
194 ap = (tlb->perms >> (subpage * 2 + 4)) & 3;
195 if (!check_perms (state, ap, read)) {
196 if (tlb->mapping == TLB_SECTION) {
197 return SECTION_PERMISSION_FAULT;
198 } else {
199 return SUBPAGE_PERMISSION_FAULT;
200 }
201 }
202#endif
203 } else { /* access == 3 */
204 /* manager access - don't check perms */
205 }
206 return NO_FAULT;
207}
208#endif
209
210#if 0
211fault_t
212mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr)
213#endif
214
215/* ap: AP bits value.
216 * sop: section or page description 0:section 1:page
217 */
218fault_t
219mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr, int *ap, int *sop)
220{
221 {
222 /* walk the translation tables */
223 ARMword l1addr, l1desc;
224 if (state->mmu.translation_table_ctrl && virt_addr << state->mmu.translation_table_ctrl >> (32 - state->mmu.translation_table_ctrl - 1)) {
225 l1addr = state->mmu.translation_table_base1;
226 l1addr = (((l1addr >> 14) << 14) | (virt_addr >> 18)) & ~3;
227 } else {
228 l1addr = state->mmu.translation_table_base0;
229 l1addr = (((l1addr >> (14 - state->mmu.translation_table_ctrl)) << (14 - state->mmu.translation_table_ctrl)) | (virt_addr << state->mmu.translation_table_ctrl) >> (18 + state->mmu.translation_table_ctrl)) & ~3;
230 }
231
232 /* l1desc = mem_read_word (state, l1addr); */
233 if (state->space.conf_obj != NULL)
234 state->space.read(state->space.conf_obj, l1addr, &l1desc, 4);
235 else
236 l1desc = Memory::Read32(l1addr); //mem_read_raw(32, l1addr, &l1desc);
237
238 #if 0
239 if (virt_addr == 0xc000d2bc) {
240 printf("mmu_control is %x\n", state->mmu.translation_table_ctrl);
241 printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0);
242 printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1);
243 printf("l1addr is %x l1desc is %x\n", l1addr, l1desc);
244 // exit(-1);
245 }
246 #endif
247 switch (l1desc & 3) {
248 case 0:
249 case 3:
250 /*
251 * according to Figure 3-9 Sequence for checking faults in arm manual,
252 * section translation fault should be returned here.
253 */
254 {
255 return SECTION_TRANSLATION_FAULT;
256 }
257 case 1:
258 /* coarse page table */
259 {
260 ARMword l2addr, l2desc;
261
262
263 l2addr = l1desc & 0xFFFFFC00;
264 l2addr = (l2addr |
265 ((virt_addr & 0x000FF000) >> 10)) &
266 ~3;
267 if(state->space.conf_obj != NULL)
268 state->space.read(state->space.conf_obj, l2addr, &l2desc, 4);
269 else
270 l2desc = Memory::Read32(l2addr); //mem_read_raw(32, l2addr, &l2desc);
271
272 /* chy 2003-09-02 for xscale */
273 *ap = (l2desc >> 4) & 0x3;
274 *sop = 1; /* page */
275
276 switch (l2desc & 3) {
277 case 0:
278 return PAGE_TRANSLATION_FAULT;
279 break;
280 case 1:
281 *phys_addr = (l2desc & 0xFFFF0000) | (virt_addr & 0x0000FFFF);
282 break;
283 case 2:
284 case 3:
285 *phys_addr = (l2desc & 0xFFFFF000) | (virt_addr & 0x00000FFF);
286 break;
287
288 }
289 }
290 break;
291 case 2:
292 /* section */
293
294 *ap = (l1desc >> 10) & 3;
295 *sop = 0; /* section */
296 #if 0
297 if (virt_addr == 0xc000d2bc) {
298 printf("mmu_control is %x\n", state->mmu.translation_table_ctrl);
299 printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0);
300 printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1);
301 printf("l1addr is %x l1desc is %x\n", l1addr, l1desc);
302// printf("l2addr is %x l2desc is %x\n", l2addr, l2desc);
303 printf("ap is %x, sop is %x\n", *ap, *sop);
304 printf("mode is %d\n", state->Mode);
305// exit(-1);
306 }
307 #endif
308
309 if (l1desc & 0x30000)
310 *phys_addr = (l1desc & 0xFF000000) | (virt_addr & 0x00FFFFFF);
311 else
312 *phys_addr = (l1desc & 0xFFF00000) | (virt_addr & 0x000FFFFF);
313 break;
314 }
315 }
316 return NO_FAULT;
317}
318
319
320static fault_t arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va,
321 ARMword data, ARMword datatype);
322static fault_t arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va,
323 ARMword *data, ARMword datatype);
324
325int
326arm1176jzf_s_mmu_init (ARMul_State *state)
327{
328 state->mmu.control = 0x50078;
329 state->mmu.translation_table_base = 0xDEADC0DE;
330 state->mmu.domain_access_control = 0xDEADC0DE;
331 state->mmu.fault_status = 0;
332 state->mmu.fault_address = 0;
333 state->mmu.process_id = 0;
334 state->mmu.context_id = 0;
335 state->mmu.thread_uro_id = 0;
336 //invalidate_all_tlb(state);
337
338 return No_exp;
339}
340
341void
342arm1176jzf_s_mmu_exit (ARMul_State *state)
343{
344}
345
346
347static fault_t
348arm1176jzf_s_mmu_load_instr (ARMul_State *state, ARMword va, ARMword *instr)
349{
350 fault_t fault;
351 int c; /* cache bit */
352 ARMword pa; /* physical addr */
353 ARMword perm; /* physical addr access permissions */
354 int ap, sop;
355
356 static int debug_count = 0; /* used for debug */
357
358 //DEBUG_LOG(ARM11, "va = %x\n", va);
359
360 va = mmu_pid_va_map (va);
361 if (MMU_Enabled) {
362// printf("MMU enabled.\n");
363// sleep(1);
364 /* align check */
365 if ((va & (WORD_SIZE - 1)) && MMU_Aligned) {
366 DEBUG_LOG(ARM11, "align\n");
367 return ALIGNMENT_FAULT;
368 } else
369 va &= ~(WORD_SIZE - 1);
370
371 /* translate tlb */
372 fault = mmu_translate (state, va, &pa, &ap, &sop);
373 if (fault) {
374 DEBUG_LOG(ARM11, "translate\n");
375 printf("va=0x%x, icounter=%lld, fault=%d\n", va, state->NumInstrs, fault);
376 return fault;
377 }
378
379
380 /* no tlb, only check permission */
381 if (!check_perms(state, ap, 1)) {
382 if (sop == 0) {
383 return SECTION_PERMISSION_FAULT;
384 } else {
385 return SUBPAGE_PERMISSION_FAULT;
386 }
387 }
388
389#if 0
390 /*check access */
391 fault = check_access (state, va, tlb, 1);
392 if (fault) {
393 DEBUG_LOG(ARM11, "check_fault\n");
394 return fault;
395 }
396#endif
397 }
398
399 /*if MMU disabled or C flag is set alloc cache */
400 if (MMU_Disabled) {
401// printf("MMU disabled.\n");
402// sleep(1);
403 pa = va;
404 }
405 if(state->space.conf_obj == NULL)
406 state->space.read(state->space.conf_obj, pa, instr, 4);
407 else
408 *instr = Memory::Read32(pa); //mem_read_raw(32, pa, instr);
409
410 return NO_FAULT;
411}
412
413static fault_t
414arm1176jzf_s_mmu_read_byte (ARMul_State *state, ARMword virt_addr, ARMword *data)
415{
416 /* ARMword temp,offset; */
417 fault_t fault;
418 fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
419 return fault;
420}
421
422static fault_t
423arm1176jzf_s_mmu_read_halfword (ARMul_State *state, ARMword virt_addr,
424 ARMword *data)
425{
426 /* ARMword temp,offset; */
427 fault_t fault;
428 fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
429 return fault;
430}
431
432static fault_t
433arm1176jzf_s_mmu_read_word (ARMul_State *state, ARMword virt_addr, ARMword *data)
434{
435 return arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
436}
437
438static fault_t
439arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va, ARMword *data,
440 ARMword datatype)
441{
442 fault_t fault;
443 ARMword pa, real_va, temp, offset;
444 ARMword perm; /* physical addr access permissions */
445 int ap, sop;
446
447 //DEBUG_LOG(ARM11, "va = %x\n", va);
448
449 va = mmu_pid_va_map (va);
450 real_va = va;
451 /* if MMU disabled, memory_read */
452 if (MMU_Disabled) {
453// printf("MMU disabled cpu_id:%x addr:%x.\n", state->mmu.process_id, va);
454// sleep(1);
455
456 /* *data = mem_read_word(state, va); */
457 if (datatype == ARM_BYTE_TYPE)
458 /* *data = mem_read_byte (state, va); */
459 if(state->space.conf_obj != NULL)
460 state->space.read(state->space.conf_obj, va, data, 1);
461 else
462 *data = Memory::Read8(va); //mem_read_raw(8, va, data);
463 else if (datatype == ARM_HALFWORD_TYPE)
464 /* *data = mem_read_halfword (state, va); */
465 if(state->space.conf_obj != NULL)
466 state->space.read(state->space.conf_obj, va, data, 2);
467 else
468 *data = Memory::Read16(va); //mem_read_raw(16, va, data);
469 else if (datatype == ARM_WORD_TYPE)
470 /* *data = mem_read_word (state, va); */
471 if(state->space.conf_obj != NULL)
472 state->space.read(state->space.conf_obj, va, data, 4);
473 else
474 *data = Memory::Read32(va); //mem_read_raw(32, va, data);
475 else {
476 ERROR_LOG(ARM11, "SKYEYE:1 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype);
477 }
478
479 return NO_FAULT;
480 }
481// printf("MMU enabled.\n");
482// sleep(1);
483
484 /* align check */
485 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
486 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
487 DEBUG_LOG(ARM11, "align\n");
488 return ALIGNMENT_FAULT;
489 }
490
491 /* va &= ~(WORD_SIZE - 1); */
492 #if 0
493 uint32_t page_base;
494 page_base = get_phys_page(state, va);
495 if((page_base & 0xFFF) == 0){
496 pa = (page_base << 12) | (va & 0xFFF);
497 goto skip_translation;
498 }
499 #endif
500 /*translate va to tlb */
501#if 0
502 fault = mmu_translate (state, va, ARM920T_D_TLB (), &tlb);
503#endif
504 fault = mmu_translate (state, va, &pa, &ap, &sop);
505#if 0
506 if(va ==0xbebb1774 || state->Reg[15] == 0x400ff594){
507 //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]);
508 printf("In %s, ap is %d, sop is %d, va=0x%x, pa=0x%x, fault=%d, data=0x%x\n", __FUNCTION__, ap, sop, va, pa, fault, data);
509 int i;
510 for(i = 0; i < 16; i++)
511 printf("Reg[%d]=0x%x\t", i, state->Reg[i]);
512 printf("\n");
513 }
514#endif
515 if (fault) {
516 DEBUG_LOG(ARM11, "translate\n");
517 //printf("mmu read fault at %x\n", va);
518 //printf("fault is %d\n", fault);
519 return fault;
520 }
521// printf("va is %x pa is %x\n", va, pa);
522
523 /* no tlb, only check permission */
524 if (!check_perms(state, ap, 1)) {
525 if (sop == 0) {
526 return SECTION_PERMISSION_FAULT;
527 } else {
528 return SUBPAGE_PERMISSION_FAULT;
529 }
530 }
531#if 0
532 /*check access permission */
533 fault = check_access (state, va, tlb, 1);
534 if (fault)
535 return fault;
536#endif
537
538 //insert_tlb(state, va, pa);
539skip_translation:
540 /* *data = mem_read_word(state, pa); */
541 if (datatype == ARM_BYTE_TYPE) {
542 /* *data = mem_read_byte (state, pa | (real_va & 3)); */
543 if(state->space.conf_obj != NULL)
544 state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 1);
545 else
546 *data = Memory::Read8(pa | (real_va & 3)); //mem_read_raw(8, pa | (real_va & 3), data);
547 /* mem_read_raw(32, pa | (real_va & 3), data); */
548 } else if (datatype == ARM_HALFWORD_TYPE) {
549 /* *data = mem_read_halfword (state, pa | (real_va & 2)); */
550 if(state->space.conf_obj != NULL)
551 state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 2);
552 else
553 *data = Memory::Read16(pa | (real_va & 3)); //mem_read_raw(16, pa | (real_va & 3), data);
554 /* mem_read_raw(32, pa | (real_va & 2), data); */
555 } else if (datatype == ARM_WORD_TYPE)
556 /* *data = mem_read_word (state, pa); */
557 if(state->space.conf_obj != NULL)
558 state->space.read(state->space.conf_obj, pa , data, 4);
559 else
560 *data = Memory::Read32(pa); //mem_read_raw(32, pa, data);
561 else {
562 ERROR_LOG(ARM11, "SKYEYE:2 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype);
563 }
564 if(0 && (va == 0x2869c)){
565 printf("In %s, pa is %x va=0x%x, value is %x pc %x, instr=0x%x\n", __FUNCTION__, pa, va, *data, state->Reg[15], state->CurrInstr);
566 }
567
568 /* ldrex or ldrexb */
569 if(((state->CurrInstr & 0x0FF000F0) == 0x01900090) ||
570 ((state->CurrInstr & 0x0FF000F0) == 0x01d00090)){
571 int rn = (state->CurrInstr & 0xF0000) >> 16;
572 if(state->Reg[rn] == va){
573 add_exclusive_addr(state, pa | (real_va & 3));
574 state->exclusive_access_state = 1;
575 }
576 }
577#if 0
578 if (state->pc == 0xc011a868) {
579 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
580 printf("icounter is %lld\n", state->NumInstrs);
581// exit(-1);
582 }
583#endif
584
585 return NO_FAULT;
586}
587
588
589static fault_t
590arm1176jzf_s_mmu_write_byte (ARMul_State *state, ARMword virt_addr, ARMword data)
591{
592 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
593}
594
595static fault_t
596arm1176jzf_s_mmu_write_halfword (ARMul_State *state, ARMword virt_addr,
597 ARMword data)
598{
599 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
600}
601
602static fault_t
603arm1176jzf_s_mmu_write_word (ARMul_State *state, ARMword virt_addr, ARMword data)
604{
605 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
606}
607
608
609
610static fault_t
611arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va, ARMword data,
612 ARMword datatype)
613{
614 int b;
615 ARMword pa, real_va;
616 ARMword perm; /* physical addr access permissions */
617 fault_t fault;
618 int ap, sop;
619
620#if 0
621 /8 for sky_printk debugger.*/
622 if (va == 0xffffffff) {
623 putchar((char)data);
624 return 0;
625 }
626 if (va == 0xBfffffff) {
627 putchar((char)data);
628 return 0;
629 }
630#endif
631
632 //DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
633 va = mmu_pid_va_map (va);
634 real_va = va;
635
636 if (MMU_Disabled) {
637 /* mem_write_word(state, va, data); */
638 if (datatype == ARM_BYTE_TYPE)
639 /* mem_write_byte (state, va, data); */
640 if(state->space.conf_obj != NULL)
641 state->space.write(state->space.conf_obj, va, &data, 1);
642 else
643 Memory::Write8(va, data);
644 else if (datatype == ARM_HALFWORD_TYPE)
645 /* mem_write_halfword (state, va, data); */
646 if(state->space.conf_obj != NULL)
647 state->space.write(state->space.conf_obj, va, &data, 2);
648 else
649 Memory::Write16(va, data);
650 else if (datatype == ARM_WORD_TYPE)
651 /* mem_write_word (state, va, data); */
652 if(state->space.conf_obj != NULL)
653 state->space.write(state->space.conf_obj, va, &data, 4);
654 else
655 Memory::Write32(va, data);
656 else {
657 ERROR_LOG (ARM11, "SKYEYE:1 arm1176jzf_s_mmu_write error: unknown data type %d\n", datatype);
658 }
659 goto finished_write;
660 //return 0;
661 }
662 /*align check */
663 /* if ((va & (WORD_SIZE - 1)) && MMU_Aligned){ */
664 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
665 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
666 DEBUG_LOG(ARM11, "align\n");
667 return ALIGNMENT_FAULT;
668 }
669 va &= ~(WORD_SIZE - 1);
670 #if 0
671 uint32_t page_base;
672 page_base = get_phys_page(state, va);
673 if((page_base & 0xFFF) == 0){
674 pa = (page_base << 12) | (va & 0xFFF);
675 goto skip_translation;
676 }
677 #endif
678 /*tlb translate */
679 fault = mmu_translate (state, va, &pa, &ap, &sop);
680#if 0
681 if(va ==0xbebb1774 || state->Reg[15] == 0x40102334){
682 //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]);
683 printf("In %s, ap is %d, sop is %d, va=0x%x, pa=0x%x, fault=%d, data=0x%x\n", __FUNCTION__, ap, sop, va, pa, fault, data);
684 int i;
685 for(i = 0; i < 16; i++)
686 printf("Reg[%d]=0x%x\t", i, state->Reg[i]);
687 printf("\n");
688 }
689#endif
690 if (fault) {
691 DEBUG_LOG(ARM11, "translate\n");
692 //printf("mmu write fault at %x\n", va);
693 return fault;
694 }
695// printf("va is %x pa is %x\n", va, pa);
696
697 /* no tlb, only check permission */
698 if (!check_perms(state, ap, 0)) {
699 if (sop == 0) {
700 return SECTION_PERMISSION_FAULT;
701 } else {
702 return SUBPAGE_PERMISSION_FAULT;
703 }
704 }
705
706#if 0
707 /* tlb check access */
708 fault = check_access (state, va, tlb, 0);
709 if (fault) {
710 DEBUG_LOG(ARM11, "check_access\n");
711 return fault;
712 }
713#endif
714#if 0
715 if (pa <= 0x502860ff && (pa + 1 << datatype) > 0x502860ff) {
716 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
717 }
718#endif
719#if 0
720 if (state->pc == 0xc011a878) {
721 printf("write pa is %x value is %x size is %x\n", pa, data, datatype);
722 printf("icounter is %lld\n", state->NumInstrs);
723 exit(-1);
724 }
725#endif
726 //insert_tlb(state, va, pa);
727skip_translation:
728 /* strex */
729 if(((state->CurrInstr & 0x0FF000F0) == 0x01800090) ||
730 ((state->CurrInstr & 0x0FF000F0) == 0x01c00090)){
731 /* failed , the address is monitord now. */
732 int dest_reg = (state->CurrInstr & 0xF000) >> 12;
733 if((exclusive_detect(state, pa | (real_va & 3)) == 0) && (state->exclusive_access_state == 1)){
734 remove_exclusive(state, pa | (real_va & 3));
735 state->Reg[dest_reg] = 0;
736 state->exclusive_access_state = 0;
737 }
738 else{
739 state->Reg[dest_reg] = 1;
740 //printf("In %s, try to strex a monitored address 0x%x\n", __FUNCTION__, pa);
741 return NO_FAULT;
742 }
743 }
744
745 if (datatype == ARM_BYTE_TYPE) {
746 /* mem_write_byte (state,
747 (pa | (real_va & 3)),
748 data);
749 */
750 if(state->space.conf_obj != NULL)
751 state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 1);
752 else
753 Memory::Write8((pa | (real_va & 3)), data);
754
755 } else if (datatype == ARM_HALFWORD_TYPE)
756 /* mem_write_halfword (state,
757 (pa |
758 (real_va & 2)),
759 data);
760 */
761 if(state->space.conf_obj != NULL)
762 state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 2);
763 else
764 Memory::Write16((pa | (real_va & 3)), data);
765 else if (datatype == ARM_WORD_TYPE)
766 /* mem_write_word (state, pa, data); */
767 if(state->space.conf_obj != NULL)
768 state->space.write(state->space.conf_obj, pa, &data, 4);
769 else
770 Memory::Write32(pa, data);
771#if 0
772 if (state->NumInstrs > 236403) {
773 printf("write memory\n");
774 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
775 printf("icounter is %lld\n", state->NumInstrs);
776 }
777#endif
778finished_write:
779#if DIFF_WRITE
780 if(state->icounter > state->debug_icounter){
781 if(state->CurrWrite >= 17 ){
782 printf("Wrong write array, 0x%x", state->CurrWrite);
783 exit(-1);
784 }
785 uint32 record_data = data;
786 if(datatype == ARM_BYTE_TYPE)
787 record_data &= 0xFF;
788 if(datatype == ARM_HALFWORD_TYPE)
789 record_data &= 0xFFFF;
790
791 state->WriteAddr[state->CurrWrite] = pa | (real_va & 3);
792 state->WriteData[state->CurrWrite] = record_data;
793 state->WritePc[state->CurrWrite] = state->Reg[15];
794 state->CurrWrite++;
795 //printf("In %s, pc=0x%x, addr=0x%x, data=0x%x, CFlag=%d\n", __FUNCTION__, state->Reg[15], pa | (real_va & 3), record_data, state->CFlag);
796 }
797#endif
798
799 return NO_FAULT;
800}
801
802ARMword
803arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value)
804{
805 int creg = BITS (16, 19) & 0xf;
806 int OPC_1 = BITS (21, 23) & 0x7;
807 int OPC_2 = BITS (5, 7) & 0x7;
808 ARMword data;
809
810 switch (creg) {
811 case MMU_ID:
812 if (OPC_2 == 0) {
813 data = state->cpu->cpu_val;
814 } else if (OPC_2 == 1) {
815 /* Cache type:
816 * 000 0110 1 000 101 110 0 10 000 101 110 0 10
817 * */
818 data = 0x0D172172;
819 }
820 break;
821 case MMU_CONTROL:
822 /*
823 * 6:3 read as 1
824 * 10 read as 0
825 * 18,16 read as 1
826 * */
827 data = (state->mmu.control | 0x50078) & 0xFFFFFBFF;
828 break;
829 case MMU_TRANSLATION_TABLE_BASE:
830#if 0
831 data = state->mmu.translation_table_base;
832#endif
833 switch (OPC_2) {
834 case 0:
835 data = state->mmu.translation_table_base0;
836 break;
837 case 1:
838 data = state->mmu.translation_table_base1;
839 break;
840 case 2:
841 data = state->mmu.translation_table_ctrl;
842 break;
843 default:
844 printf ("mmu_mrc read UNKNOWN - p15 c2 opcode2 %d\n", OPC_2);
845 break;
846 }
847 break;
848 case MMU_DOMAIN_ACCESS_CONTROL:
849 data = state->mmu.domain_access_control;
850 break;
851 case MMU_FAULT_STATUS:
852 /* OPC_2 = 0: data FSR value
853 * */
854 if (OPC_2 == 0)
855 data = state->mmu.fault_status;
856 if (OPC_2 == 1)
857 data = state->mmu.fault_statusi;
858 break;
859 case MMU_FAULT_ADDRESS:
860 data = state->mmu.fault_address;
861 break;
862 case MMU_PID:
863 //data = state->mmu.process_id;
864 if(OPC_2 == 0)
865 data = state->mmu.process_id;
866 else if(OPC_2 == 1)
867 data = state->mmu.context_id;
868 else if(OPC_2 == 3){
869 data = state->mmu.thread_uro_id;
870 }
871 else{
872 printf ("mmu_mcr read UNKNOWN - reg %d\n", creg);
873 }
874 //printf("SKYEYE In %s, read pid 0x%x, OPC_2 %d, instr=0x%x\n", __FUNCTION__, data, OPC_2, instr);
875 //exit(-1);
876 break;
877 default:
878 printf ("mmu_mrc read UNKNOWN - reg %d\n", creg);
879 data = 0;
880 break;
881 }
882/* printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]); */
883 *value = data;
884 return data;
885}
886
887
888static ARMword
889arm1176jzf_s_mmu_mcr (ARMul_State *state, ARMword instr, ARMword value)
890{
891 int creg = BITS (16, 19) & 0xf;
892 int CRm = BITS (0, 3) & 0xf;
893 int OPC_1 = BITS (21, 23) & 0x7;
894 int OPC_2 = BITS (5, 7) & 0x7;
895 if (!strncmp (state->cpu->cpu_arch_name, "armv6", 5)) {
896 switch (creg) {
897 case MMU_CONTROL:
898 /*
899 * 6:3 read as 1
900 * 10 read as 0
901 * 18,16 read as 1
902 * */
903 if(OPC_2 == 0)
904 state->mmu.control = (value | 0x50078) & 0xFFFFFBFF;
905 else if(OPC_2 == 1)
906 state->mmu.auxiliary_control = value;
907 else if(OPC_2 == 2)
908 state->mmu.coprocessor_access_control = value;
909 else
910 fprintf(stderr, "In %s, wrong OPC_2 %d\n", __FUNCTION__, OPC_2);
911 break;
912 case MMU_TRANSLATION_TABLE_BASE:
913 switch (OPC_2) {
914 /* int i; */
915 case 0:
916#if 0
917 /* TTBR0 */
918 if (state->mmu.translation_table_ctrl & 0x7) {
919 for (i = 0; i <= state->mmu.translation_table_ctrl; i++)
920 state->mmu.translation_table_base0 &= ~(1 << (5 + i));
921 }
922#endif
923 state->mmu.translation_table_base0 = (value);
924 break;
925 case 1:
926#if 0
927 /* TTBR1 */
928 if (state->mmu.translation_table_ctrl & 0x7) {
929 for (i = 0; i <= state->mmu.translation_table_ctrl; i++)
930 state->mmu.translation_table_base1 &= 1 << (5 + i);
931 }
932#endif
933 state->mmu.translation_table_base1 = (value);
934 break;
935 case 2:
936 /* TTBC */
937 state->mmu.translation_table_ctrl = value & 0x7;
938 break;
939 default:
940 printf ("mmu_mcr wrote UNKNOWN - cp15 c2 opcode2 %d\n", OPC_2);
941 break;
942 }
943 //printf("SKYEYE In %s, write TLB_BASE 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
944 //invalidate_all_tlb(state);
945 break;
946 case MMU_DOMAIN_ACCESS_CONTROL:
947 /* printf("mmu_mcr wrote DACR "); */
948 state->mmu.domain_access_control = value;
949 break;
950
951 case MMU_FAULT_STATUS:
952 if (OPC_2 == 0)
953 state->mmu.fault_status = value & 0xFF;
954 if (OPC_2 == 1) {
955 printf("set fault status instr\n");
956 }
957 break;
958 case MMU_FAULT_ADDRESS:
959 state->mmu.fault_address = value;
960 break;
961
962 case MMU_CACHE_OPS:
963 break;
964 case MMU_TLB_OPS:
965 {
966 switch(CRm){
967 case 5: /* ITLB */
968 {
969 switch(OPC_2){
970 case 0: /* invalidate all */
971 //invalidate_all_tlb(state);
972 break;
973 case 1: /* invalidate by MVA */
974 //invalidate_by_mva(state, value);
975 break;
976 case 2: /* invalidate by asid */
977 //invalidate_by_asid(state, value);
978 break;
979 default:
980 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
981 break;
982 }
983 break;
984 }
985 case 6: /* DTLB */
986 {
987 switch(OPC_2){
988 case 0: /* invalidate all */
989 //invalidate_all_tlb(state);
990 break;
991 case 1: /* invalidate by MVA */
992 //invalidate_by_mva(state, value);
993 break;
994 case 2: /* invalidate by asid */
995 //invalidate_by_asid(state, value);
996 break;
997 default:
998 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
999 break;
1000 }
1001 break;
1002 }
1003 case 7: /* Unified TLB */
1004 {
1005 switch(OPC_2){
1006 case 0: /* invalidate all */
1007 //invalidate_all_tlb(state);
1008 break;
1009 case 1: /* invalidate by MVA */
1010 //invalidate_by_mva(state, value);
1011 break;
1012 case 2: /* invalidate by asid */
1013 //invalidate_by_asid(state, value);
1014 break;
1015 default:
1016 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1017 break;
1018 }
1019 break;
1020 }
1021
1022 default:
1023 printf ("mmu_mcr wrote UNKNOWN - reg %d, CRm=%d\n", creg, CRm);
1024 break;
1025 }
1026 //printf("SKYEYE In %s, write TLB 0x%x OPC_1=%d, OPC_2=%d , CRm=%d instr=0x%x\n", __FUNCTION__, value, OPC_1, OPC_2, CRm, instr);
1027 }
1028 break;
1029 case MMU_CACHE_LOCKDOWN:
1030 /*
1031 * FIXME: cache lock down*/
1032 break;
1033 case MMU_TLB_LOCKDOWN:
1034 printf("SKYEYE In %s, write TLB_LOCKDOWN 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
1035 /* FIXME:tlb lock down */
1036 break;
1037 case MMU_PID:
1038 //printf("SKYEYE In %s, write pid 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
1039 //state->mmu.process_id = value;
1040 /*0:24 should be zero. */
1041 //state->mmu.process_id = value & 0xfe000000;
1042 if(OPC_2 == 0)
1043 state->mmu.process_id = value;
1044 else if(OPC_2 == 1)
1045 state->mmu.context_id = value;
1046 else if(OPC_2 == 3){
1047 state->mmu.thread_uro_id = value;
1048 }
1049 else{
1050 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1051 }
1052 break;
1053
1054 default:
1055 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1056 break;
1057 }
1058 }
1059
1060 return No_exp;
1061}
1062
1063///* teawater add for arm2x86 2005.06.19------------------------------------------- */
1064//static int
1065//arm1176jzf_s_mmu_v2p_dbct (ARMul_State *state, ARMword virt_addr,
1066// ARMword *phys_addr)
1067//{
1068// fault_t fault;
1069// int ap, sop;
1070//
1071// ARMword perm; /* physical addr access permissions */
1072// virt_addr = mmu_pid_va_map (virt_addr);
1073// if (MMU_Enabled) {
1074//
1075// /*align check */
1076// if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
1077// DEBUG_LOG(ARM11, "align\n");
1078// return ALIGNMENT_FAULT;
1079// } else
1080// virt_addr &= ~(WORD_SIZE - 1);
1081//
1082// /*translate tlb */
1083// fault = mmu_translate (state, virt_addr, phys_addr, &ap, &sop);
1084// if (fault) {
1085// DEBUG_LOG(ARM11, "translate\n");
1086// return fault;
1087// }
1088//
1089// /* permission check */
1090// if (!check_perms(state, ap, 1)) {
1091// if (sop == 0) {
1092// return SECTION_PERMISSION_FAULT;
1093// } else {
1094// return SUBPAGE_PERMISSION_FAULT;
1095// }
1096// }
1097//#if 0
1098// /*check access */
1099// fault = check_access (state, virt_addr, tlb, 1);
1100// if (fault) {
1101// DEBUG_LOG(ARM11, "check_fault\n");
1102// return fault;
1103// }
1104//#endif
1105// }
1106//
1107// if (MMU_Disabled) {
1108// *phys_addr = virt_addr;
1109// }
1110//
1111// return 0;
1112//}
1113
1114/* AJ2D-------------------------------------------------------------------------- */
1115
1116/*arm1176jzf-s mmu_ops_t*/
1117mmu_ops_t arm1176jzf_s_mmu_ops = {
1118 arm1176jzf_s_mmu_init,
1119 arm1176jzf_s_mmu_exit,
1120 arm1176jzf_s_mmu_read_byte,
1121 arm1176jzf_s_mmu_write_byte,
1122 arm1176jzf_s_mmu_read_halfword,
1123 arm1176jzf_s_mmu_write_halfword,
1124 arm1176jzf_s_mmu_read_word,
1125 arm1176jzf_s_mmu_write_word,
1126 arm1176jzf_s_mmu_load_instr,
1127 arm1176jzf_s_mmu_mcr,
1128 arm1176jzf_s_mmu_mrc
1129/* teawater add for arm2x86 2005.06.19------------------------------------------- */
1130/* arm1176jzf_s_mmu_v2p_dbct, */
1131/* AJ2D-------------------------------------------------------------------------- */
1132};
diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h
deleted file mode 100644
index 299c6b46b..000000000
--- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 arm1176JZF-S_mmu.h - ARM1176JZF-S Memory Management Unit emulation.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#ifndef _ARM1176JZF_S_MMU_H_
20#define _ARM1176JZF_S_MMU_H_
21
22#if 0
23typedef struct arm1176jzf-s_mmu_s
24{
25 tlb_t i_tlb;
26 cache_t i_cache;
27
28 tlb_t d_tlb;
29 cache_t d_cache;
30 wb_t wb_t;
31} arm1176jzf-s_mmu_t;
32#endif
33extern mmu_ops_t arm1176jzf_s_mmu_ops;
34
35ARMword
36arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value);
37#endif /*_ARM1176JZF_S_MMU_H_*/
diff --git a/src/core/arm/interpreter/mmu/cache.cpp b/src/core/arm/interpreter/mmu/cache.cpp
deleted file mode 100644
index cfbc31f1e..000000000
--- a/src/core/arm/interpreter/mmu/cache.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
1#include "core/arm/skyeye_common/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/cache.h b/src/core/arm/interpreter/mmu/cache.h
deleted file mode 100644
index d308d9b87..000000000
--- a/src/core/arm/interpreter/mmu/cache.h
+++ /dev/null
@@ -1,168 +0,0 @@
1#ifndef _MMU_CACHE_H_
2#define _MMU_CACHE_H_
3
4typedef struct cache_line_t
5{
6 ARMword tag; /* cache line align address |
7 bit2: last half dirty
8 bit1: first half dirty
9 bit0: cache valid flag
10 */
11 ARMword pa; /*physical address */
12 ARMword *data; /*array of cached data */
13} cache_line_t;
14#define TAG_VALID_FLAG 0x00000001
15#define TAG_FIRST_HALF_DIRTY 0x00000002
16#define TAG_LAST_HALF_DIRTY 0x00000004
17
18/*cache set association*/
19typedef struct cache_set_s
20{
21 cache_line_t *lines;
22 int cycle;
23} cache_set_t;
24
25enum
26{
27 CACHE_WRITE_BACK,
28 CACHE_WRITE_THROUGH,
29};
30
31typedef struct cache_s
32{
33 int width; /*bytes in a line */
34 int way; /*way of set asscociate */
35 int set; /*num of set */
36 int w_mode; /*write back or write through */
37 //int a_mode; /*alloc mode: random or round-bin*/
38 cache_set_t *sets;
39 /**/} cache_s;
40
41typedef struct cache_desc_s
42{
43 int width;
44 int way;
45 int set;
46 int w_mode;
47// int a_mode;
48} cache_desc_t;
49
50
51/*virtual address to cache set index*/
52#define va_cache_set(va, cache_t) \
53 (((va) / (cache_t)->width) & ((cache_t)->set - 1))
54/*virtual address to cahce line aligned*/
55#define va_cache_align(va, cache_t) \
56 ((va) & ~((cache_t)->width - 1))
57/*virtaul address to cache line word index*/
58#define va_cache_index(va, cache_t) \
59 (((va) & ((cache_t)->width - 1)) >> WORD_SHT)
60
61/*see Page 558 in arm manual*/
62/*set/index format value to cache set value*/
63#define index_cache_set(index, cache_t) \
64 (((index) / (cache_t)->width) & ((cache_t)->set - 1))
65
66/*************************cache********************/
67/* mmu cache init
68 *
69 * @cache_t :cache_t to init
70 * @width :cache line width in byte
71 * @way :way of each cache set
72 * @set :cache set num
73 * @w_mode :cache w_mode
74 *
75 * $ -1: error
76 * 0: sucess
77 */
78int
79mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode);
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 */
88void mmu_cache_exit (cache_s * cache_t);
89
90/* mmu cache search
91 *
92 * @state :ARMul_State
93 * @cache_t :cache_t to search
94 * @va :virtual address
95 *
96 * $ NULL: no cache match
97 * cache :cache matched
98 * */
99cache_line_t *mmu_cache_search (ARMul_State * state, cache_s * cache_t,
100 ARMword va);
101
102/* mmu cache search by set/index
103 *
104 * @state :ARMul_State
105 * @cache_t :cache_t to search
106 * @index :set/index value.
107 *
108 * $ NULL: no cache match
109 * cache :cache matched
110 * */
111
112cache_line_t *mmu_cache_search_by_index (ARMul_State * state,
113 cache_s * cache_t, ARMword index);
114
115/* mmu cache alloc
116 *
117 * @state :ARMul_State
118 * @cache_t :cache_t to alloc from
119 * @va :virtual address that require cache alloc, need not cache aligned
120 * @pa :physical address of va
121 *
122 * $ cache_alloced, always alloc OK
123 */
124cache_line_t *mmu_cache_alloc (ARMul_State * state, cache_s * cache_t,
125 ARMword va, ARMword pa);
126
127/* mmu_cache_write_back write cache data to memory
128 *
129 * @state:
130 * @cache_t :cache_t of the cache line
131 * @cache : cache line
132 */
133void
134mmu_cache_write_back (ARMul_State * state, cache_s * cache_t,
135 cache_line_t * cache);
136
137/* mmu_cache_clean: clean a cache of va in cache_t
138 *
139 * @state :ARMul_State
140 * @cache_t :cache_t to clean
141 * @va :virtaul address
142 */
143void mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va);
144void
145mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t,
146 ARMword index);
147
148/* mmu_cache_invalidate : invalidate a cache of va
149 *
150 * @state :ARMul_State
151 * @cache_t :cache_t to invalid
152 * @va :virt_addr to invalid
153 */
154void
155mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va);
156
157void
158mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t,
159 ARMword index);
160
161void mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t);
162
163void
164mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa);
165
166cache_line_t* mmu_cache_dirty_cache(ARMul_State * state, cache_s * cache_t);
167
168#endif /*_MMU_CACHE_H_*/
diff --git a/src/core/arm/interpreter/mmu/maverick.cpp b/src/core/arm/interpreter/mmu/maverick.cpp
deleted file mode 100644
index a07d4742b..000000000
--- a/src/core/arm/interpreter/mmu/maverick.cpp
+++ /dev/null
@@ -1,1206 +0,0 @@
1/* maverick.c -- Cirrus/DSP co-processor interface.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez (aldyh@redhat.com).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19#include <assert.h>
20
21#include "core/arm/skyeye_common/armdefs.h"
22#include "core/arm/skyeye_common/armemu.h"
23
24
25/*#define CIRRUS_DEBUG 1 */
26#if CIRRUS_DEBUG
27# define printfdbg printf
28#else
29# define printfdbg printf_nothing
30#endif
31
32#define POS64(i) ( (~(i)) >> 63 )
33#define NEG64(i) ( (i) >> 63 )
34
35/* Define Co-Processor instruction handlers here. */
36
37/* Here's ARMulator's DSP definition. A few things to note:
38 1) it has 16 64-bit registers and 4 72-bit accumulators
39 2) you can only access its registers with MCR and MRC. */
40
41/* We can't define these in here because this file might not be linked
42 unless the target is arm9e-*. They are defined in wrapper.c.
43 Eventually the simulator should be made to handle any coprocessor
44 at run time. */
45struct maverick_regs
46{
47 union
48 {
49 int i;
50 float f;
51 } upper;
52
53 union
54 {
55 int i;
56 float f;
57 } lower;
58};
59
60union maverick_acc_regs
61{
62 long double ld; /* Acc registers are 72-bits. */
63};
64
65struct maverick_regs DSPregs[16];
66union maverick_acc_regs DSPacc[4];
67ARMword DSPsc;
68
69#define DEST_REG (BITS (12, 15))
70#define SRC1_REG (BITS (16, 19))
71#define SRC2_REG (BITS (0, 3))
72
73static int lsw_int_index, msw_int_index;
74static int lsw_float_index, msw_float_index;
75
76static double mv_getRegDouble (int);
77static long long mv_getReg64int (int);
78static void mv_setRegDouble (int, double val);
79static void mv_setReg64int (int, long long val);
80
81static union
82{
83 double d;
84 long long ll;
85 int ints[2];
86} reg_conv;
87
88static void
89printf_nothing (const char *foo, ...)
90{
91}
92
93static void
94cirrus_not_implemented (const char *insn)
95{
96 fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
97 fprintf (stderr, "aborting!\n");
98
99 // skyeye_exit (1);
100}
101
102static unsigned
103DSPInit (ARMul_State * state)
104{
105 NOTICE_LOG(ARM11, "ARMul_ConsolePrint: DSP present");
106 return TRUE;
107}
108
109unsigned
110DSPMRC4 (ARMul_State * state,
111 unsigned type, ARMword instr, ARMword * value)
112{
113 switch (BITS (5, 7)) {
114 case 0: /* cfmvrdl */
115 /* Move lower half of a DF stored in a DSP reg into an Arm reg. */
116 printfdbg ("cfmvrdl\n");
117 printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
118 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
119
120 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
121 break;
122
123 case 1: /* cfmvrdh */
124 /* Move upper half of a DF stored in a DSP reg into an Arm reg. */
125 printfdbg ("cfmvrdh\n");
126 printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
127 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
128
129 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
130 break;
131
132 case 2: /* cfmvrs */
133 /* Move SF from upper half of a DSP register to an Arm register. */
134 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
135 printfdbg ("cfmvrs = mvf%d <-- %f\n",
136 SRC1_REG, DSPregs[SRC1_REG].upper.f);
137 break;
138
139#ifdef doesnt_work
140 case 4: /* cfcmps */
141 {
142 float a, b;
143 int n, z, c, v;
144
145 a = DSPregs[SRC1_REG].upper.f;
146 b = DSPregs[SRC2_REG].upper.f;
147
148 printfdbg ("cfcmps\n");
149 printfdbg ("\tcomparing %f and %f\n", a, b);
150
151 z = a == b; /* zero */
152 n = a != b; /* negative */
153 v = a > b; /* overflow */
154 c = 0; /* carry */
155 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
156 28);
157 break;
158 }
159
160 case 5: /* cfcmpd */
161 {
162 double a, b;
163 int n, z, c, v;
164
165 a = mv_getRegDouble (SRC1_REG);
166 b = mv_getRegDouble (SRC2_REG);
167
168 printfdbg ("cfcmpd\n");
169 printfdbg ("\tcomparing %g and %g\n", a, b);
170
171 z = a == b; /* zero */
172 n = a != b; /* negative */
173 v = a > b; /* overflow */
174 c = 0; /* carry */
175 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
176 28);
177 break;
178 }
179#else
180 case 4: /* cfcmps */
181 {
182 float a, b;
183 int n, z, c, v;
184
185 a = DSPregs[SRC1_REG].upper.f;
186 b = DSPregs[SRC2_REG].upper.f;
187
188 printfdbg ("cfcmps\n");
189 printfdbg ("\tcomparing %f and %f\n", a, b);
190
191 z = a == b; /* zero */
192 n = a < b; /* negative */
193 c = a > b; /* carry */
194 v = 0; /* fixme */
195 printfdbg ("\tz = %d, n = %d\n", z, n);
196 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
197 28);
198 break;
199 }
200
201 case 5: /* cfcmpd */
202 {
203 double a, b;
204 int n, z, c, v;
205
206 a = mv_getRegDouble (SRC1_REG);
207 b = mv_getRegDouble (SRC2_REG);
208
209 printfdbg ("cfcmpd\n");
210 printfdbg ("\tcomparing %g and %g\n", a, b);
211
212 z = a == b; /* zero */
213 n = a < b; /* negative */
214 c = a > b; /* carry */
215 v = 0; /* fixme */
216 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
217 28);
218 break;
219 }
220#endif
221 default:
222 fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);
223 cirrus_not_implemented ("unknown");
224 break;
225 }
226
227 return ARMul_DONE;
228}
229
230unsigned
231DSPMRC5 (ARMul_State * state,
232 unsigned type, ARMword instr, ARMword * value)
233{
234 switch (BITS (5, 7)) {
235 case 0: /* cfmvr64l */
236 /* Move lower half of 64bit int from Cirrus to Arm. */
237 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
238 printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",
239 DEST_REG, (int) *value);
240 break;
241
242 case 1: /* cfmvr64h */
243 /* Move upper half of 64bit int from Cirrus to Arm. */
244 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
245 printfdbg ("cfmvr64h <-- %d\n", (int) *value);
246 break;
247
248 case 4: /* cfcmp32 */
249 {
250 int res;
251 int n, z, c, v;
252 unsigned int a, b;
253
254 printfdbg ("cfcmp32 mvfx%d - mvfx%d\n", SRC1_REG,
255 SRC2_REG);
256
257 /* FIXME: see comment for cfcmps. */
258 a = DSPregs[SRC1_REG].lower.i;
259 b = DSPregs[SRC2_REG].lower.i;
260
261 res = DSPregs[SRC1_REG].lower.i -
262 DSPregs[SRC2_REG].lower.i;
263 /* zero */
264 z = res == 0;
265 /* negative */
266 n = res < 0;
267 /* overflow */
268 v = SubOverflow (DSPregs[SRC1_REG].lower.i,
269 DSPregs[SRC2_REG].lower.i, res);
270 /* carry */
271 c = (NEG (a) && POS (b) ||
272 (NEG (a) && POS (res)) || (POS (b)
273 && POS (res)));
274
275 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
276 28);
277 break;
278 }
279
280 case 5: /* cfcmp64 */
281 {
282 long long res;
283 int n, z, c, v;
284 unsigned long long a, b;
285
286 printfdbg ("cfcmp64 mvdx%d - mvdx%d\n", SRC1_REG,
287 SRC2_REG);
288
289 /* fixme: see comment for cfcmps. */
290
291 a = mv_getReg64int (SRC1_REG);
292 b = mv_getReg64int (SRC2_REG);
293
294 res = mv_getReg64int (SRC1_REG) -
295 mv_getReg64int (SRC2_REG);
296 /* zero */
297 z = res == 0;
298 /* negative */
299 n = res < 0;
300 /* overflow */
301 v = ((NEG64 (a) && POS64 (b) && POS64 (res))
302 || (POS64 (a) && NEG64 (b) && NEG64 (res)));
303 /* carry */
304 c = (NEG64 (a) && POS64 (b) ||
305 (NEG64 (a) && POS64 (res)) || (POS64 (b)
306 && POS64 (res)));
307
308 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
309 28);
310 break;
311 }
312
313 default:
314 fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
315 cirrus_not_implemented ("unknown");
316 break;
317 }
318
319 return ARMul_DONE;
320}
321
322unsigned
323DSPMRC6 (ARMul_State * state,
324 unsigned type, ARMword instr, ARMword * value)
325{
326 switch (BITS (5, 7)) {
327 case 0: /* cfmval32 */
328 cirrus_not_implemented ("cfmval32");
329 break;
330
331 case 1: /* cfmvam32 */
332 cirrus_not_implemented ("cfmvam32");
333 break;
334
335 case 2: /* cfmvah32 */
336 cirrus_not_implemented ("cfmvah32");
337 break;
338
339 case 3: /* cfmva32 */
340 cirrus_not_implemented ("cfmva32");
341 break;
342
343 case 4: /* cfmva64 */
344 cirrus_not_implemented ("cfmva64");
345 break;
346
347 case 5: /* cfmvsc32 */
348 cirrus_not_implemented ("cfmvsc32");
349 break;
350
351 default:
352 fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
353 cirrus_not_implemented ("unknown");
354 break;
355 }
356
357 return ARMul_DONE;
358}
359
360unsigned
361DSPMCR4 (ARMul_State * state,
362 unsigned type, ARMword instr, ARMword value)
363{
364 switch (BITS (5, 7)) {
365 case 0: /* cfmvdlr */
366 /* Move the lower half of a DF value from an Arm register into
367 the lower half of a Cirrus register. */
368 printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
369 DSPregs[SRC1_REG].lower.i = (int) value;
370 break;
371
372 case 1: /* cfmvdhr */
373 /* Move the upper half of a DF value from an Arm register into
374 the upper half of a Cirrus register. */
375 printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
376 DSPregs[SRC1_REG].upper.i = (int) value;
377 break;
378
379 case 2: /* cfmvsr */
380 /* Move SF from Arm register into upper half of Cirrus register. */
381 printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
382 DSPregs[SRC1_REG].upper.i = (int) value;
383 break;
384
385 default:
386 fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
387 cirrus_not_implemented ("unknown");
388 break;
389 }
390
391 return ARMul_DONE;
392}
393
394unsigned
395DSPMCR5 (ARMul_State * state,
396 unsigned type, ARMword instr, ARMword value)
397{
398 union
399 {
400 int s;
401 unsigned int us;
402 } val;
403
404 switch (BITS (5, 7)) {
405 case 0: /* cfmv64lr */
406 /* Move lower half of a 64bit int from an ARM register into the
407 lower half of a DSP register and sign extend it. */
408 printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG,
409 (int) value);
410 DSPregs[SRC1_REG].lower.i = (int) value;
411 break;
412
413 case 1: /* cfmv64hr */
414 /* Move upper half of a 64bit int from an ARM register into the
415 upper half of a DSP register. */
416 printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",
417 SRC1_REG, (int) value);
418 DSPregs[SRC1_REG].upper.i = (int) value;
419 break;
420
421 case 2: /* cfrshl32 */
422 printfdbg ("cfrshl32\n");
423 val.us = value;
424 if (val.s > 0)
425 DSPregs[SRC2_REG].lower.i =
426 DSPregs[SRC1_REG].lower.i << value;
427 else
428 DSPregs[SRC2_REG].lower.i =
429 DSPregs[SRC1_REG].lower.i >> -value;
430 break;
431
432 case 3: /* cfrshl64 */
433 printfdbg ("cfrshl64\n");
434 val.us = value;
435 if (val.s > 0)
436 mv_setReg64int (SRC2_REG,
437 mv_getReg64int (SRC1_REG) << value);
438 else
439 mv_setReg64int (SRC2_REG,
440 mv_getReg64int (SRC1_REG) >> -value);
441 break;
442
443 default:
444 fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
445 cirrus_not_implemented ("unknown");
446 break;
447 }
448
449 return ARMul_DONE;
450}
451
452unsigned
453DSPMCR6 (ARMul_State * state,
454 unsigned type, ARMword instr, ARMword value)
455{
456 switch (BITS (5, 7)) {
457 case 0: /* cfmv32al */
458 cirrus_not_implemented ("cfmv32al");
459 break;
460
461 case 1: /* cfmv32am */
462 cirrus_not_implemented ("cfmv32am");
463 break;
464
465 case 2: /* cfmv32ah */
466 cirrus_not_implemented ("cfmv32ah");
467 break;
468
469 case 3: /* cfmv32a */
470 cirrus_not_implemented ("cfmv32a");
471 break;
472
473 case 4: /* cfmv64a */
474 cirrus_not_implemented ("cfmv64a");
475 break;
476
477 case 5: /* cfmv32sc */
478 cirrus_not_implemented ("cfmv32sc");
479 break;
480
481 default:
482 fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
483 cirrus_not_implemented ("unknown");
484 break;
485 }
486
487 return ARMul_DONE;
488}
489
490unsigned
491DSPLDC4 (ARMul_State * state,
492 unsigned type, ARMword instr, ARMword data)
493{
494 static unsigned words;
495
496 if (type != ARMul_DATA) {
497 words = 0;
498 return ARMul_DONE;
499 }
500
501 if (BIT (22)) { /* it's a long access, get two words */
502 /* cfldrd */
503
504 printfdbg
505 ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
506 data, words, state->bigendSig, DEST_REG);
507
508 if (words == 0) {
509 if (state->bigendSig)
510 DSPregs[DEST_REG].upper.i = (int) data;
511 else
512 DSPregs[DEST_REG].lower.i = (int) data;
513 }
514 else {
515 if (state->bigendSig)
516 DSPregs[DEST_REG].lower.i = (int) data;
517 else
518 DSPregs[DEST_REG].upper.i = (int) data;
519 }
520
521 ++words;
522
523 if (words == 2) {
524 printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
525 mv_getRegDouble (DEST_REG));
526
527 return ARMul_DONE;
528 }
529 else
530 return ARMul_INC;
531 }
532 else {
533 /* Get just one word. */
534
535 /* cfldrs */
536 printfdbg ("cfldrs\n");
537
538 DSPregs[DEST_REG].upper.i = (int) data;
539
540 printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,
541 DSPregs[DEST_REG].upper.f);
542
543 return ARMul_DONE;
544 }
545}
546
547unsigned
548DSPLDC5 (ARMul_State * state,
549 unsigned type, ARMword instr, ARMword data)
550{
551 static unsigned words;
552
553 if (type != ARMul_DATA) {
554 words = 0;
555 return ARMul_DONE;
556 }
557
558 if (BIT (22)) {
559 /* It's a long access, get two words. */
560
561 /* cfldr64 */
562 printfdbg ("cfldr64: %d\n", data);
563
564 if (words == 0) {
565 if (state->bigendSig)
566 DSPregs[DEST_REG].upper.i = (int) data;
567 else
568 DSPregs[DEST_REG].lower.i = (int) data;
569 }
570 else {
571 if (state->bigendSig)
572 DSPregs[DEST_REG].lower.i = (int) data;
573 else
574 DSPregs[DEST_REG].upper.i = (int) data;
575 }
576
577 ++words;
578
579 if (words == 2) {
580 printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
581 mv_getReg64int (DEST_REG));
582
583 return ARMul_DONE;
584 }
585 else
586 return ARMul_INC;
587 }
588 else {
589 /* Get just one word. */
590
591 /* cfldr32 */
592 printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
593
594 /* 32bit ints should be sign extended to 64bits when loaded. */
595 mv_setReg64int (DEST_REG, (long long) data);
596
597 return ARMul_DONE;
598 }
599}
600
601unsigned
602DSPSTC4 (ARMul_State * state,
603 unsigned type, ARMword instr, ARMword * data)
604{
605 static unsigned words;
606
607 if (type != ARMul_DATA) {
608 words = 0;
609 return ARMul_DONE;
610 }
611
612 if (BIT (22)) {
613 /* It's a long access, get two words. */
614 /* cfstrd */
615 printfdbg ("cfstrd\n");
616
617 if (words == 0) {
618 if (state->bigendSig)
619 *data = (ARMword) DSPregs[DEST_REG].upper.i;
620 else
621 *data = (ARMword) DSPregs[DEST_REG].lower.i;
622 }
623 else {
624 if (state->bigendSig)
625 *data = (ARMword) DSPregs[DEST_REG].lower.i;
626 else
627 *data = (ARMword) DSPregs[DEST_REG].upper.i;
628 }
629
630 ++words;
631
632 if (words == 2) {
633 printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
634 mv_getRegDouble (DEST_REG));
635
636 return ARMul_DONE;
637 }
638 else
639 return ARMul_INC;
640 }
641 else {
642 /* Get just one word. */
643 /* cfstrs */
644 printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
645 DSPregs[DEST_REG].upper.f);
646
647 *data = (ARMword) DSPregs[DEST_REG].upper.i;
648
649 return ARMul_DONE;
650 }
651}
652
653unsigned
654DSPSTC5 (ARMul_State * state,
655 unsigned type, ARMword instr, ARMword * data)
656{
657 static unsigned words;
658
659 if (type != ARMul_DATA) {
660 words = 0;
661 return ARMul_DONE;
662 }
663
664 if (BIT (22)) {
665 /* It's a long access, store two words. */
666 /* cfstr64 */
667 printfdbg ("cfstr64\n");
668
669 if (words == 0) {
670 if (state->bigendSig)
671 *data = (ARMword) DSPregs[DEST_REG].upper.i;
672 else
673 *data = (ARMword) DSPregs[DEST_REG].lower.i;
674 }
675 else {
676 if (state->bigendSig)
677 *data = (ARMword) DSPregs[DEST_REG].lower.i;
678 else
679 *data = (ARMword) DSPregs[DEST_REG].upper.i;
680 }
681
682 ++words;
683
684 if (words == 2) {
685 printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
686 mv_getReg64int (DEST_REG));
687
688 return ARMul_DONE;
689 }
690 else
691 return ARMul_INC;
692 }
693 else {
694 /* Store just one word. */
695 /* cfstr32 */
696 *data = (ARMword) DSPregs[DEST_REG].lower.i;
697
698 printfdbg ("cfstr32 MEM = %d\n", (int) *data);
699
700 return ARMul_DONE;
701 }
702}
703
704unsigned
705DSPCDP4 (ARMul_State * state, unsigned type, ARMword instr)
706{
707 int opcode2;
708
709 opcode2 = BITS (5, 7);
710
711 switch (BITS (20, 21)) {
712 case 0:
713 switch (opcode2) {
714 case 0: /* cfcpys */
715 printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
716 DEST_REG, SRC1_REG,
717 DSPregs[SRC1_REG].upper.f);
718 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
719 break;
720
721 case 1: /* cfcpyd */
722 printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
723 DEST_REG, SRC1_REG,
724 mv_getRegDouble (SRC1_REG));
725 mv_setRegDouble (DEST_REG,
726 mv_getRegDouble (SRC1_REG));
727 break;
728
729 case 2: /* cfcvtds */
730 printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
731 DEST_REG, SRC1_REG,
732 (float) mv_getRegDouble (SRC1_REG));
733 DSPregs[DEST_REG].upper.f =
734 (float) mv_getRegDouble (SRC1_REG);
735 break;
736
737 case 3: /* cfcvtsd */
738 printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
739 DEST_REG, SRC1_REG,
740 (double) DSPregs[SRC1_REG].upper.f);
741 mv_setRegDouble (DEST_REG,
742 (double) DSPregs[SRC1_REG].upper.f);
743 break;
744
745 case 4: /* cfcvt32s */
746 printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
747 DEST_REG, SRC1_REG,
748 (float) DSPregs[SRC1_REG].lower.i);
749 DSPregs[DEST_REG].upper.f =
750 (float) DSPregs[SRC1_REG].lower.i;
751 break;
752
753 case 5: /* cfcvt32d */
754 printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
755 DEST_REG, SRC1_REG,
756 (double) DSPregs[SRC1_REG].lower.i);
757 mv_setRegDouble (DEST_REG,
758 (double) DSPregs[SRC1_REG].lower.i);
759 break;
760
761 case 6: /* cfcvt64s */
762 printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
763 DEST_REG, SRC1_REG,
764 (float) mv_getReg64int (SRC1_REG));
765 DSPregs[DEST_REG].upper.f =
766 (float) mv_getReg64int (SRC1_REG);
767 break;
768
769 case 7: /* cfcvt64d */
770 printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
771 DEST_REG, SRC1_REG,
772 (double) mv_getReg64int (SRC1_REG));
773 mv_setRegDouble (DEST_REG,
774 (double) mv_getReg64int (SRC1_REG));
775 break;
776 }
777 break;
778
779 case 1:
780 switch (opcode2) {
781 case 0: /* cfmuls */
782 printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
783 DEST_REG,
784 SRC1_REG,
785 DSPregs[SRC1_REG].upper.f *
786 DSPregs[SRC2_REG].upper.f);
787
788 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
789 * DSPregs[SRC2_REG].upper.f;
790 break;
791
792 case 1: /* cfmuld */
793 printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
794 DEST_REG,
795 SRC1_REG,
796 mv_getRegDouble (SRC1_REG) *
797 mv_getRegDouble (SRC2_REG));
798
799 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
800 * mv_getRegDouble (SRC2_REG));
801 break;
802
803 default:
804 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n",
805 instr);
806 cirrus_not_implemented ("unknown");
807 break;
808 }
809 break;
810
811 case 3:
812 switch (opcode2) {
813 case 0: /* cfabss */
814 DSPregs[DEST_REG].upper.f =
815 (DSPregs[SRC1_REG].upper.f <
816 0.0F ? -DSPregs[SRC1_REG].upper.
817 f : DSPregs[SRC1_REG].upper.f);
818 printfdbg ("cfabss mvf%d = |mvf%d| = %f\n", DEST_REG,
819 SRC1_REG, DSPregs[DEST_REG].upper.f);
820 break;
821
822 case 1: /* cfabsd */
823 mv_setRegDouble (DEST_REG,
824 (mv_getRegDouble (SRC1_REG) < 0.0 ?
825 -mv_getRegDouble (SRC1_REG)
826 : mv_getRegDouble (SRC1_REG)));
827 printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
828 DEST_REG, SRC1_REG,
829 mv_getRegDouble (DEST_REG));
830 break;
831
832 case 2: /* cfnegs */
833 DSPregs[DEST_REG].upper.f =
834 -DSPregs[SRC1_REG].upper.f;
835 printfdbg ("cfnegs mvf%d = -mvf%d = %f\n", DEST_REG,
836 SRC1_REG, DSPregs[DEST_REG].upper.f);
837 break;
838
839 case 3: /* cfnegd */
840 mv_setRegDouble (DEST_REG,
841 -mv_getRegDouble (SRC1_REG));
842 printfdbg ("cfnegd mvd%d = -mvd%d = %g\n", DEST_REG,
843 mv_getRegDouble (DEST_REG));
844 break;
845
846 case 4: /* cfadds */
847 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
848 + DSPregs[SRC2_REG].upper.f;
849 printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
850 DEST_REG, SRC1_REG, SRC2_REG,
851 DSPregs[DEST_REG].upper.f);
852 break;
853
854 case 5: /* cfaddd */
855 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
856 + mv_getRegDouble (SRC2_REG));
857 printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
858 DEST_REG,
859 SRC1_REG, SRC2_REG,
860 mv_getRegDouble (DEST_REG));
861 break;
862
863 case 6: /* cfsubs */
864 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
865 - DSPregs[SRC2_REG].upper.f;
866 printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
867 DEST_REG, SRC1_REG, SRC2_REG,
868 DSPregs[DEST_REG].upper.f);
869 break;
870
871 case 7: /* cfsubd */
872 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
873 - mv_getRegDouble (SRC2_REG));
874 printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
875 DEST_REG,
876 SRC1_REG, SRC2_REG,
877 mv_getRegDouble (DEST_REG));
878 break;
879 }
880 break;
881
882 default:
883 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
884 cirrus_not_implemented ("unknown");
885 break;
886 }
887
888 return ARMul_DONE;
889}
890
891unsigned
892DSPCDP5 (ARMul_State * state, unsigned type, ARMword instr)
893{
894 int opcode2;
895 char shift;
896
897 opcode2 = BITS (5, 7);
898
899 /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */
900 shift = BITS (0, 3) | (BITS (5, 7)) << 4;
901 if (shift & 0x40)
902 shift |= 0xc0;
903
904 switch (BITS (20, 21)) {
905 case 0:
906 /* cfsh32 */
907 printfdbg ("cfsh32 %s amount=%d\n",
908 shift < 0 ? "right" : "left", shift);
909 if (shift < 0)
910 /* Negative shift is a right shift. */
911 DSPregs[DEST_REG].lower.i =
912 DSPregs[SRC1_REG].lower.i >> -shift;
913 else
914 /* Positive shift is a left shift. */
915 DSPregs[DEST_REG].lower.i =
916 DSPregs[SRC1_REG].lower.i << shift;
917 break;
918
919 case 1:
920 switch (opcode2) {
921 case 0: /* cfmul32 */
922 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
923 * DSPregs[SRC2_REG].lower.i;
924 printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
925 DEST_REG, SRC1_REG, SRC2_REG,
926 DSPregs[DEST_REG].lower.i);
927 break;
928
929 case 1: /* cfmul64 */
930 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
931 * mv_getReg64int (SRC2_REG));
932 printfdbg
933 ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
934 DEST_REG, SRC1_REG, SRC2_REG,
935 mv_getReg64int (DEST_REG));
936 break;
937
938 case 2: /* cfmac32 */
939 DSPregs[DEST_REG].lower.i
940 +=
941 DSPregs[SRC1_REG].lower.i *
942 DSPregs[SRC2_REG].lower.i;
943 printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
944 DEST_REG, SRC1_REG, SRC2_REG,
945 DSPregs[DEST_REG].lower.i);
946 break;
947
948 case 3: /* cfmsc32 */
949 DSPregs[DEST_REG].lower.i
950 -=
951 DSPregs[SRC1_REG].lower.i *
952 DSPregs[SRC2_REG].lower.i;
953 printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
954 DEST_REG, SRC1_REG, SRC2_REG,
955 DSPregs[DEST_REG].lower.i);
956 break;
957
958 case 4: /* cfcvts32 */
959 /* fixme: this should round */
960 DSPregs[DEST_REG].lower.i =
961 (int) DSPregs[SRC1_REG].upper.f;
962 printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n", DEST_REG,
963 SRC1_REG, DSPregs[DEST_REG].lower.i);
964 break;
965
966 case 5: /* cfcvtd32 */
967 /* fixme: this should round */
968 DSPregs[DEST_REG].lower.i =
969 (int) mv_getRegDouble (SRC1_REG);
970 printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n", DEST_REG,
971 SRC1_REG, DSPregs[DEST_REG].lower.i);
972 break;
973
974 case 6: /* cftruncs32 */
975 DSPregs[DEST_REG].lower.i =
976 (int) DSPregs[SRC1_REG].upper.f;
977 printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
978 DEST_REG, SRC1_REG,
979 DSPregs[DEST_REG].lower.i);
980 break;
981
982 case 7: /* cftruncd32 */
983 DSPregs[DEST_REG].lower.i =
984 (int) mv_getRegDouble (SRC1_REG);
985 printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
986 DEST_REG, SRC1_REG,
987 DSPregs[DEST_REG].lower.i);
988 break;
989 }
990 break;
991
992 case 2:
993 /* cfsh64 */
994 printfdbg ("cfsh64\n");
995
996 if (shift < 0)
997 /* Negative shift is a right shift. */
998 mv_setReg64int (DEST_REG,
999 mv_getReg64int (SRC1_REG) >> -shift);
1000 else
1001 /* Positive shift is a left shift. */
1002 mv_setReg64int (DEST_REG,
1003 mv_getReg64int (SRC1_REG) << shift);
1004 printfdbg ("\t%llx\n", mv_getReg64int (DEST_REG));
1005 break;
1006
1007 case 3:
1008 switch (opcode2) {
1009 case 0: /* cfabs32 */
1010 DSPregs[DEST_REG].lower.i =
1011 (DSPregs[SRC1_REG].lower.i <
1012 0 ? -DSPregs[SRC1_REG].lower.
1013 i : DSPregs[SRC1_REG].lower.i);
1014 printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",
1015 DEST_REG, SRC1_REG, SRC2_REG,
1016 DSPregs[DEST_REG].lower.i);
1017 break;
1018
1019 case 1: /* cfabs64 */
1020 mv_setReg64int (DEST_REG,
1021 (mv_getReg64int (SRC1_REG) < 0
1022 ? -mv_getReg64int (SRC1_REG)
1023 : mv_getReg64int (SRC1_REG)));
1024 printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
1025 DEST_REG, SRC1_REG, SRC2_REG,
1026 mv_getReg64int (DEST_REG));
1027 break;
1028
1029 case 2: /* cfneg32 */
1030 DSPregs[DEST_REG].lower.i =
1031 -DSPregs[SRC1_REG].lower.i;
1032 printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
1033 DEST_REG, SRC1_REG, SRC2_REG,
1034 DSPregs[DEST_REG].lower.i);
1035 break;
1036
1037 case 3: /* cfneg64 */
1038 mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
1039 printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
1040 DEST_REG, SRC1_REG, SRC2_REG,
1041 mv_getReg64int (DEST_REG));
1042 break;
1043
1044 case 4: /* cfadd32 */
1045 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1046 + DSPregs[SRC2_REG].lower.i;
1047 printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
1048 DEST_REG, SRC1_REG, SRC2_REG,
1049 DSPregs[DEST_REG].lower.i);
1050 break;
1051
1052 case 5: /* cfadd64 */
1053 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
1054 + mv_getReg64int (SRC2_REG));
1055 printfdbg
1056 ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
1057 DEST_REG, SRC1_REG, SRC2_REG,
1058 mv_getReg64int (DEST_REG));
1059 break;
1060
1061 case 6: /* cfsub32 */
1062 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1063 - DSPregs[SRC2_REG].lower.i;
1064 printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
1065 DEST_REG, SRC1_REG, SRC2_REG,
1066 DSPregs[DEST_REG].lower.i);
1067 break;
1068
1069 case 7: /* cfsub64 */
1070 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
1071 - mv_getReg64int (SRC2_REG));
1072 printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
1073 DEST_REG, SRC1_REG, SRC2_REG,
1074 mv_getReg64int (DEST_REG));
1075 break;
1076 }
1077 break;
1078
1079 default:
1080 fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
1081 cirrus_not_implemented ("unknown");
1082 break;
1083 }
1084
1085 return ARMul_DONE;
1086}
1087
1088unsigned
1089DSPCDP6 (ARMul_State * state, unsigned type, ARMword instr)
1090{
1091 int opcode2;
1092
1093 opcode2 = BITS (5, 7);
1094
1095 switch (BITS (20, 21)) {
1096 case 0:
1097 /* cfmadd32 */
1098 cirrus_not_implemented ("cfmadd32");
1099 break;
1100
1101 case 1:
1102 /* cfmsub32 */
1103 cirrus_not_implemented ("cfmsub32");
1104 break;
1105
1106 case 2:
1107 /* cfmadda32 */
1108 cirrus_not_implemented ("cfmadda32");
1109 break;
1110
1111 case 3:
1112 /* cfmsuba32 */
1113 cirrus_not_implemented ("cfmsuba32");
1114 break;
1115
1116 default:
1117 fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
1118 }
1119
1120 return ARMul_DONE;
1121}
1122
1123/* Conversion functions.
1124
1125 32-bit integers are stored in the LOWER half of a 64-bit physical
1126 register.
1127
1128 Single precision floats are stored in the UPPER half of a 64-bit
1129 physical register. */
1130
1131static double
1132mv_getRegDouble (int regnum)
1133{
1134 reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
1135 reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
1136 return reg_conv.d;
1137}
1138
1139static void
1140mv_setRegDouble (int regnum, double val)
1141{
1142 reg_conv.d = val;
1143 DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
1144 DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
1145}
1146
1147static long long
1148mv_getReg64int (int regnum)
1149{
1150 reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
1151 reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
1152 return reg_conv.ll;
1153}
1154
1155static void
1156mv_setReg64int (int regnum, long long val)
1157{
1158 reg_conv.ll = val;
1159 DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
1160 DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
1161}
1162
1163/* Compute LSW in a double and a long long. */
1164
1165void
1166mv_compute_host_endianness (ARMul_State * state)
1167{
1168 static union
1169 {
1170 long long ll;
1171 int ints[2];
1172 int i;
1173 double d;
1174 float floats[2];
1175 float f;
1176 } conv;
1177
1178 /* Calculate where's the LSW in a 64bit int. */
1179 conv.ll = 45;
1180
1181 if (conv.ints[0] == 0) {
1182 msw_int_index = 0;
1183 lsw_int_index = 1;
1184 }
1185 else {
1186 assert (conv.ints[1] == 0);
1187 msw_int_index = 1;
1188 lsw_int_index = 0;
1189 }
1190
1191 /* Calculate where's the LSW in a double. */
1192 conv.d = 3.0;
1193
1194 if (conv.ints[0] == 0) {
1195 msw_float_index = 0;
1196 lsw_float_index = 1;
1197 }
1198 else {
1199 assert (conv.ints[1] == 0);
1200 msw_float_index = 1;
1201 lsw_float_index = 0;
1202 }
1203
1204 printfdbg ("lsw_int_index %d\n", lsw_int_index);
1205 printfdbg ("lsw_float_index %d\n", lsw_float_index);
1206}
diff --git a/src/core/arm/interpreter/mmu/rb.cpp b/src/core/arm/interpreter/mmu/rb.cpp
deleted file mode 100644
index 600c9d8c8..000000000
--- a/src/core/arm/interpreter/mmu/rb.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
1#include "core/arm/skyeye_common/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/rb.h b/src/core/arm/interpreter/mmu/rb.h
deleted file mode 100644
index 7bf0ebb26..000000000
--- a/src/core/arm/interpreter/mmu/rb.h
+++ /dev/null
@@ -1,55 +0,0 @@
1#ifndef _MMU_RB_H
2#define _MMU_RB_H
3
4enum rb_type_t
5{
6 RB_INVALID = 0, //invalid
7 RB_1, //1 word
8 RB_4, //4 word
9 RB_8, //8 word
10};
11
12/*bytes of each rb_type*/
13extern ARMword rb_masks[];
14
15#define RB_WORD_NUM 8
16typedef struct rb_entry_s
17{
18 ARMword data[RB_WORD_NUM]; //array to store data
19 ARMword va; //first word va
20 int type; //rb type
21 fault_t fault; //fault set by rb alloc
22} rb_entry_t;
23
24typedef struct rb_s
25{
26 int num;
27 rb_entry_t *entrys;
28} rb_s;
29
30/*mmu_rb_init
31 * @rb_t :rb_t to init
32 * @num :number of entry
33 * */
34int mmu_rb_init (rb_s * rb_t, int num);
35
36/*mmu_rb_exit*/
37void mmu_rb_exit (rb_s * rb_t);
38
39
40/*mmu_rb_search
41 * @rb_t :rb_t to serach
42 * @va :va address to math
43 *
44 * $ NULL :not match
45 * NO-NULL:
46 * */
47rb_entry_t *mmu_rb_search (rb_s * rb_t, ARMword va);
48
49
50void mmu_rb_invalidate_entry (rb_s * rb_t, int i);
51void mmu_rb_invalidate_all (rb_s * rb_t);
52void mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb,
53 int type, ARMword va);
54
55#endif /*_MMU_RB_H_*/
diff --git a/src/core/arm/interpreter/mmu/sa_mmu.cpp b/src/core/arm/interpreter/mmu/sa_mmu.cpp
deleted file mode 100644
index 27f9ec8e0..000000000
--- a/src/core/arm/interpreter/mmu/sa_mmu.cpp
+++ /dev/null
@@ -1,864 +0,0 @@
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/skyeye_common/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
deleted file mode 100644
index 64b1c5470..000000000
--- a/src/core/arm/interpreter/mmu/sa_mmu.h
+++ /dev/null
@@ -1,58 +0,0 @@
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
deleted file mode 100644
index 88c2a8bc5..000000000
--- a/src/core/arm/interpreter/mmu/tlb.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
1#include <assert.h>
2
3#include "core/arm/skyeye_common/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
deleted file mode 100644
index 40856567b..000000000
--- a/src/core/arm/interpreter/mmu/tlb.h
+++ /dev/null
@@ -1,87 +0,0 @@
1#ifndef _MMU_TLB_H_
2#define _MMU_TLB_H_
3
4typedef enum tlb_mapping_t
5{
6 TLB_INVALID = 0,
7 TLB_SMALLPAGE = 1,
8 TLB_LARGEPAGE = 2,
9 TLB_SECTION = 3,
10 TLB_ESMALLPAGE = 4,
11 TLB_TINYPAGE = 5
12} tlb_mapping_t;
13
14extern ARMword tlb_masks[];
15
16/* Permissions bits in a TLB entry:
17 *
18 * 31 12 11 10 9 8 7 6 5 4 3 2 1 0
19 * +-------------+-----+-----+-----+-----+---+---+-------+
20 * Page:| | ap3 | ap2 | ap1 | ap0 | C | B | |
21 * +-------------+-----+-----+-----+-----+---+---+-------+
22 *
23 * 31 12 11 10 9 4 3 2 1 0
24 * +-------------+-----+-----------------+---+---+-------+
25 * Section: | | AP | | C | B | |
26 * +-------------+-----+-----------------+---+---+-------+
27 */
28
29/*
30section:
31 section base address [31:20]
32 AP - table 8-2, page 8-8
33 domain
34 C,B
35
36page:
37 page base address [31:16] or [31:12]
38 ap[3:0]
39 domain (from L1)
40 C,B
41*/
42
43
44typedef struct tlb_entry_t
45{
46 ARMword virt_addr;
47 ARMword phys_addr;
48 ARMword perms;
49 ARMword domain;
50 tlb_mapping_t mapping;
51} tlb_entry_t;
52
53typedef struct tlb_s
54{
55 int num; /*num of tlb entry */
56 int cycle; /*current tlb cycle */
57 tlb_entry_t *entrys;
58} tlb_s;
59
60
61#define tlb_c_flag(tlb) \
62 ((tlb)->perms & 0x8)
63#define tlb_b_flag(tlb) \
64 ((tlb)->perms & 0x4)
65
66#define tlb_va_to_pa(tlb, va) ((tlb->phys_addr & tlb_masks[tlb->mapping]) | (va & ~tlb_masks[tlb->mapping]))
67fault_t
68check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
69 int read);
70
71fault_t
72translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
73 tlb_entry_t ** tlb);
74
75int mmu_tlb_init (tlb_s * tlb_t, int num);
76
77void mmu_tlb_exit (tlb_s * tlb_t);
78
79void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t);
80
81void
82mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr);
83
84tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t,
85 ARMword virt_addr);
86
87#endif /*_MMU_TLB_H_*/
diff --git a/src/core/arm/interpreter/mmu/wb.cpp b/src/core/arm/interpreter/mmu/wb.cpp
deleted file mode 100644
index 5ddda41ee..000000000
--- a/src/core/arm/interpreter/mmu/wb.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
1#include "core/arm/skyeye_common/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/wb.h b/src/core/arm/interpreter/mmu/wb.h
deleted file mode 100644
index 8fb7de946..000000000
--- a/src/core/arm/interpreter/mmu/wb.h
+++ /dev/null
@@ -1,63 +0,0 @@
1#ifndef _MMU_WB_H_
2#define _MMU_WB_H_
3
4typedef struct wb_entry_s
5{
6 ARMword pa; //phy_addr
7 ARMbyte *data; //data
8 int nb; //number byte to write
9} wb_entry_t;
10
11typedef struct wb_s
12{
13 int num; //number of wb_entry
14 int nb; //number of byte of each entry
15 int first; //
16 int last; //
17 int used; //
18 wb_entry_t *entrys;
19} wb_s;
20
21typedef struct wb_desc_s
22{
23 int num;
24 int nb;
25} wb_desc_t;
26
27/* wb_init
28 * @wb_t :wb_t to init
29 * @num :num of entrys
30 * @nw :num of word of each entry
31 *
32 * $ -1:error
33 * 0:ok
34 * */
35int mmu_wb_init (wb_s * wb_t, int num, int nb);
36
37
38/* wb_exit
39 * @wb_t :wb_t to exit
40 * */
41void mmu_wb_exit (wb_s * wb);
42
43
44/* wb_write_bytes :put bytess in Write Buffer
45 * @state: ARMul_State
46 * @wb_t: write buffer
47 * @pa: physical address
48 * @data: data ptr
49 * @n number of byte to write
50 *
51 * Note: write buffer merge is not implemented, can be done late
52 * */
53void
54mmu_wb_write_bytess (ARMul_State * state, wb_s * wb_t, ARMword pa,
55 ARMbyte * data, int n);
56
57
58/* wb_drain_all
59 * @wb_t wb_t to drain
60 * */
61void mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t);
62
63#endif /*_MMU_WB_H_*/
diff --git a/src/core/arm/interpreter/mmu/xscale_copro.cpp b/src/core/arm/interpreter/mmu/xscale_copro.cpp
deleted file mode 100644
index cf91fd933..000000000
--- a/src/core/arm/interpreter/mmu/xscale_copro.cpp
+++ /dev/null
@@ -1,1391 +0,0 @@
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/skyeye_common/armdefs.h"
25#include "core/arm/skyeye_common/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
87unsigned
88xscale_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, (uint32_t*)&icmr);
105 bus_read(32, PXA270_ICPR, (uint32_t*)&icpr);
106 bus_read(32, PXA270_ICLR, (uint32_t*)&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, (uint32_t*)&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 ----------------------------------------------------
130unsigned
131xscale_cp13_init (ARMul_State * state)
132{
133 //printf("SKYEYE: xscale_cp13_init: begin\n");
134 return 0;
135}
136
137unsigned
138xscale_cp13_exit (ARMul_State * state)
139{
140 //printf("SKYEYE: xscale_cp13_exit: begin\n");
141 return 0;
142}
143
144unsigned
145xscale_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
155unsigned
156xscale_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
166unsigned
167xscale_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
177unsigned
178xscale_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
188unsigned
189xscale_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
198unsigned
199xscale_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
208unsigned
209xscale_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 ----------------------------------------------------
220unsigned
221xscale_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
229unsigned
230xscale_cp14_exit (ARMul_State * state)
231{
232 //printf("SKYEYE: xscale_cp14_exit: begin\n");
233 return 0;
234}
235
236unsigned
237xscale_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
247unsigned
248xscale_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
258unsigned
259xscale_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}
286unsigned 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}
311unsigned 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}
319unsigned 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}
327unsigned 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
415unsigned
416xscale_cp15_init (ARMul_State * state)
417{
418 xscale_mmu_desc_t *desc;
419 cache_desc_t *c_desc;
420
421 state->mmu.control = 0;
422 state->mmu.translation_table_base = 0xDEADC0DE;
423 state->mmu.domain_access_control = 0xDEADC0DE;
424 state->mmu.fault_status = 0;
425 state->mmu.fault_address = 0;
426 state->mmu.process_id = 0;
427 state->mmu.cache_type = 0xB1AA1AA; //0000 1011 0001 1010 1010 0001 1010 1010
428 state->mmu.aux_control = 0;
429
430 desc = &pxa_mmu_desc;
431
432 if (mmu_tlb_init (I_TLB (), desc->i_tlb)) {
433 ERROR_LOG(ARM11, "i_tlb init %d\n", -1);
434 goto i_tlb_init_error;
435 }
436
437 c_desc = &desc->i_cache;
438 if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
439 c_desc->set, c_desc->w_mode)) {
440 ERROR_LOG(ARM11, "i_cache init %d\n", -1);
441 goto i_cache_init_error;
442 }
443
444 if (mmu_tlb_init (D_TLB (), desc->d_tlb)) {
445 ERROR_LOG(ARM11, "d_tlb init %d\n", -1);
446 goto d_tlb_init_error;
447 }
448
449 c_desc = &desc->main_d_cache;
450 if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
451 c_desc->set, c_desc->w_mode)) {
452 ERROR_LOG(ARM11, "main_d_cache init %d\n", -1);
453 goto main_d_cache_init_error;
454 }
455
456 c_desc = &desc->mini_d_cache;
457 if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
458 c_desc->set, c_desc->w_mode)) {
459 ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1);
460 goto mini_d_cache_init_error;
461 }
462
463 if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) {
464 ERROR_LOG(ARM11, "wb init %d\n", -1);
465 goto wb_init_error;
466 }
467#if 0
468 if (mmu_rb_init (RB (), desc->rb)) {
469 ERROR_LOG(ARM11, "rb init %d\n", -1);
470 goto rb_init_error;
471 }
472#endif
473
474 return 0;
475#if 0
476 rb_init_error:
477 mmu_wb_exit (WB ());
478#endif
479 wb_init_error:
480 mmu_cache_exit (MINI_D_CACHE ());
481 mini_d_cache_init_error:
482 mmu_cache_exit (MAIN_D_CACHE ());
483 main_d_cache_init_error:
484 mmu_tlb_exit (D_TLB ());
485 d_tlb_init_error:
486 mmu_cache_exit (I_CACHE ());
487 i_cache_init_error:
488 mmu_tlb_exit (I_TLB ());
489 i_tlb_init_error:
490 return -1;
491}
492
493unsigned
494xscale_cp15_exit (ARMul_State * state)
495{
496 //mmu_rb_exit(RB());
497 mmu_wb_exit (WB ());
498 mmu_cache_exit (MINI_D_CACHE ());
499 mmu_cache_exit (MAIN_D_CACHE ());
500 mmu_tlb_exit (D_TLB ());
501 mmu_cache_exit (I_CACHE ());
502 mmu_tlb_exit (I_TLB ());
503 return 0;
504};
505
506
507static fault_t
508 xscale_mmu_load_instr (ARMul_State * state, ARMword va,
509 ARMword * instr)
510{
511 fault_t fault;
512 tlb_entry_t *tlb;
513 cache_line_t *cache;
514 int c; //cache bit
515 ARMword pa; //physical addr
516
517 static int debug_count = 0; //used for debug
518
519 DEBUG_LOG(ARM11, "va = %x\n", va);
520
521 va = mmu_pid_va_map (va);
522 if (MMU_Enabled) {
523 /*align check */
524 if ((va & (INSN_SIZE - 1)) && MMU_Aligned) {
525 DEBUG_LOG(ARM11, "align\n");
526 return ALIGNMENT_FAULT;
527 }
528 else
529 va &= ~(INSN_SIZE - 1);
530
531 /*translate tlb */
532 fault = translate (state, va, I_TLB (), &tlb);
533 if (fault) {
534 DEBUG_LOG(ARM11, "translate\n");
535 return fault;
536 }
537
538 /*check access */
539 fault = check_access (state, va, tlb, 1);
540 if (fault) {
541 DEBUG_LOG(ARM11, "check_fault\n");
542 return fault;
543 }
544 }
545 //chy 2003-09-02 for test, don't use cache ?????
546#if 0
547 /*search cache no matter MMU enabled/disabled */
548 cache = mmu_cache_search (state, I_CACHE (), va);
549 if (cache) {
550 *instr = cache->data[va_cache_index (va, I_CACHE ())];
551 return 0;
552 }
553#endif
554 /*if MMU disabled or C flag is set alloc cache */
555 if (MMU_Disabled) {
556 c = 1;
557 pa = va;
558 }
559 else {
560 c = tlb_c_flag (tlb);
561 pa = tlb_va_to_pa (tlb, va);
562 }
563
564 //chy 2003-09-03 only read mem, don't use cache now,will change later ????
565 //*instr = mem_read_word (state, pa);
566 bus_read(32, pa, instr);
567#if 0
568//-----------------------------------------------------------
569 //chy 2003-09-02 for test????
570 if (pa >= 0xa01c8000 && pa <= 0xa01c8020) {
571 printf ("SKYEYE:load_instr: pa %x, va %x,instr %x, R15 %x\n",
572 pa, va, *instr, state->Reg[15]);
573 }
574
575//----------------------------------------------------------------------
576#endif
577 return NO_FAULT;
578
579 if (c) {
580 int index;
581
582 debug_count++;
583 cache = mmu_cache_alloc (state, I_CACHE (), va, pa);
584 index = va_cache_index (va, I_CACHE ());
585 *instr = cache->data[va_cache_index (va, I_CACHE ())];
586 }
587 else
588 //*instr = mem_read_word (state, pa);
589 bus_read(32, pa, instr);
590
591 return NO_FAULT;
592};
593
594
595
596static fault_t
597 xscale_mmu_read_byte (ARMul_State * state, ARMword virt_addr,
598 ARMword * data)
599{
600 //ARMword temp,offset;
601 fault_t fault;
602 fault = xscale_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
603 return fault;
604}
605
606static fault_t
607 xscale_mmu_read_halfword (ARMul_State * state, ARMword virt_addr,
608 ARMword * data)
609{
610 //ARMword temp,offset;
611 fault_t fault;
612 fault = xscale_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
613 return fault;
614}
615
616static fault_t
617 xscale_mmu_read_word (ARMul_State * state, ARMword virt_addr,
618 ARMword * data)
619{
620 return xscale_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
621}
622
623
624
625
626static fault_t
627 xscale_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
628 ARMword datatype)
629{
630 fault_t fault;
631// rb_entry_t *rb;
632 tlb_entry_t *tlb;
633 cache_line_t *cache;
634 ARMword pa, real_va, temp, offset;
635 //chy 2003-09-02 for test ????
636 static unsigned chyst1 = 0, chyst2 = 0;
637
638 DEBUG_LOG(ARM11, "va = %x\n", va);
639
640 va = mmu_pid_va_map (va);
641 real_va = va;
642 /*if MMU disabled, memory_read */
643 if (MMU_Disabled) {
644 //*data = mem_read_word(state, va);
645 if (datatype == ARM_BYTE_TYPE)
646 //*data = mem_read_byte (state, va);
647 bus_read(8, va, data);
648 else if (datatype == ARM_HALFWORD_TYPE)
649 //*data = mem_read_halfword (state, va);
650 bus_read(16, va, data);
651 else if (datatype == ARM_WORD_TYPE)
652 //*data = mem_read_word (state, va);
653 bus_read(32, va, data);
654 else {
655 printf ("SKYEYE:1 xscale_mmu_read error: unknown data type %d\n", datatype);
656 // skyeye_exit (-1);
657 }
658
659 return NO_FAULT;
660 }
661
662 /*align check */
663 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
664 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
665 DEBUG_LOG(ARM11, "align\n");
666 return ALIGNMENT_FAULT;
667 } // else
668
669 va &= ~(WORD_SIZE - 1);
670
671 /*translate va to tlb */
672 fault = translate (state, va, D_TLB (), &tlb);
673 if (fault) {
674 DEBUG_LOG(ARM11, "translate\n");
675 return fault;
676 }
677 /*check access permission */
678 fault = check_access (state, va, tlb, 1);
679 if (fault)
680 return fault;
681
682#if 0
683//------------------------------------------------
684//chy 2003-09-02 for test only ,should commit ????
685 if (datatype == ARM_WORD_TYPE) {
686 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
687 pa = tlb_va_to_pa (tlb, va);
688 *data = mem_read_word (state, pa);
689 chyst1++;
690 printf ("**SKYEYE:mmu_read word %d: pa %x, va %x, data %x, R15 %x\n", chyst1, pa, real_va, *data, state->Reg[15]);
691 /*
692 cache==mmu_cache_search(state,MAIN_D_CACHE(),va);
693 if(cache){
694 *data = cache->data[va_cache_index(va, MAIN_D_CACHE())];
695 printf("cached data %x\n",*data);
696 }else printf("no cached data\n");
697 */
698 }
699 }
700//-------------------------------------------------
701#endif
702#if 0
703 /*search in read buffer */
704 rb = mmu_rb_search (RB (), va);
705 if (rb) {
706 if (rb->fault)
707 return rb->fault;
708 *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT];
709 goto datatrans;
710 //return 0;
711 };
712#endif
713
714 /*2004-07-19 chy: add support of xscale MMU CacheDisabled option */
715 if (MMU_CacheDisabled) {
716 //if(1){ can be used to test cache error
717 /*get phy_addr */
718 pa = tlb_va_to_pa (tlb, real_va);
719 if (datatype == ARM_BYTE_TYPE)
720 //*data = mem_read_byte (state, pa);
721 bus_read(8, pa, data);
722 else if (datatype == ARM_HALFWORD_TYPE)
723 //*data = mem_read_halfword (state, pa);
724 bus_read(16, pa, data);
725 else if (datatype == ARM_WORD_TYPE)
726 //*data = mem_read_word (state, pa);
727 bus_read(32, pa, data);
728 else {
729 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_read error: unknown data type %d\n", datatype);
730 // skyeye_exit (-1);
731 }
732 return NO_FAULT;
733 }
734
735
736 /*search main cache */
737 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
738 if (cache) {
739 *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())];
740#if 0
741//------------------------------------------------------------------------
742//chy 2003-09-02 for test only ,should commit ????
743 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
744 pa = tlb_va_to_pa (tlb, va);
745 chyst2++;
746 printf ("**SKYEYE:mmu_read wordk:cache %d: pa %x, va %x, data %x, R15 %x\n", chyst2, pa, real_va, *data, state->Reg[15]);
747 }
748//-------------------------------------------------------------------
749#endif
750 goto datatrans;
751 //return 0;
752 }
753 //chy 2003-08-24, now maybe we don't need minidcache ????
754#if 0
755 /*search mini cache */
756 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
757 if (cache) {
758 *data = cache->data[va_cache_index (va, MINI_D_CACHE ())];
759 goto datatrans;
760 //return 0;
761 }
762#endif
763 /*get phy_addr */
764 pa = tlb_va_to_pa (tlb, va);
765 //chy 2003-08-24 , in xscale it means what ?????
766#if 0
767 if ((pa >= 0xe0000000) && (pa < 0xe8000000)) {
768
769 if (tlb_c_flag (tlb)) {
770 if (tlb_b_flag (tlb)) {
771 mmu_cache_soft_flush (state, MAIN_D_CACHE (),
772 pa);
773 }
774 else {
775 mmu_cache_soft_flush (state, MINI_D_CACHE (),
776 pa);
777 }
778 }
779 return 0;
780 }
781#endif
782 //chy 2003-08-24, check phy addr
783 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
784 /*
785 if(pa >= 0xb0000000){
786 printf("SKYEYE:xscale_mmu_read: phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
787 return 0;
788 }
789 */
790
791 //chy 2003-08-24, now maybe we don't need wb ????
792#if 0
793 /*if Buffer, drain Write Buffer first */
794 if (tlb_b_flag (tlb))
795 mmu_wb_drain_all (state, WB ());
796#endif
797 /*alloc cache or mem_read */
798 if (tlb_c_flag (tlb) && MMU_DCacheEnabled) {
799 cache_s *cache_t;
800
801 if (tlb_b_flag (tlb))
802 cache_t = MAIN_D_CACHE ();
803 else
804 cache_t = MINI_D_CACHE ();
805 cache = mmu_cache_alloc (state, cache_t, va, pa);
806 *data = cache->data[va_cache_index (va, cache_t)];
807 }
808 else {
809 //*data = mem_read_word(state, pa);
810 if (datatype == ARM_BYTE_TYPE)
811 //*data = mem_read_byte (state, pa | (real_va & 3));
812 bus_read(8, pa | (real_va & 3), data);
813 else if (datatype == ARM_HALFWORD_TYPE)
814 //*data = mem_read_halfword (state, pa | (real_va & 2));
815 bus_read(16, pa | (real_va & 2), data);
816 else if (datatype == ARM_WORD_TYPE)
817 //*data = mem_read_word (state, pa);
818 bus_read(32, pa, data);
819 else {
820 printf ("SKYEYE:2 xscale_mmu_read error: unknown data type %d\n", datatype);
821 // skyeye_exit (-1);
822 }
823 return NO_FAULT;
824 }
825
826
827 datatrans:
828 if (datatype == ARM_HALFWORD_TYPE) {
829 temp = *data;
830 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
831 *data = (temp >> offset) & 0xffff;
832 }
833 else if (datatype == ARM_BYTE_TYPE) {
834 temp = *data;
835 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
836 *data = (temp >> offset & 0xffL);
837 }
838 end:
839 return NO_FAULT;
840}
841
842
843static fault_t
844 xscale_mmu_write_byte (ARMul_State * state, ARMword virt_addr,
845 ARMword data)
846{
847 return xscale_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
848}
849
850static fault_t
851 xscale_mmu_write_halfword (ARMul_State * state, ARMword virt_addr,
852 ARMword data)
853{
854 return xscale_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
855}
856
857static fault_t
858 xscale_mmu_write_word (ARMul_State * state, ARMword virt_addr,
859 ARMword data)
860{
861 return xscale_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
862}
863
864
865
866static fault_t
867 xscale_mmu_write (ARMul_State * state, ARMword va, ARMword data,
868 ARMword datatype)
869{
870 tlb_entry_t *tlb;
871 cache_line_t *cache;
872 cache_s *cache_t;
873 int b;
874 ARMword pa, real_va, temp, offset;
875 fault_t fault;
876
877 ARMword index;
878//chy 2003-09-02 for test ????
879// static unsigned chyst1=0,chyst2=0;
880
881 DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
882 va = mmu_pid_va_map (va);
883 real_va = va;
884
885 if (MMU_Disabled) {
886 //mem_write_word(state, va, data);
887 if (datatype == ARM_BYTE_TYPE)
888 //mem_write_byte (state, va, data);
889 bus_write(8, va, data);
890 else if (datatype == ARM_HALFWORD_TYPE)
891 //mem_write_halfword (state, va, data);
892 bus_write(16, va, data);
893 else if (datatype == ARM_WORD_TYPE)
894 //mem_write_word (state, va, data);
895 bus_write(32, va, data);
896 else {
897 printf ("SKYEYE:1 xscale_mmu_write error: unknown data type %d\n", datatype);
898 // skyeye_exit (-1);
899 }
900
901 return NO_FAULT;
902 }
903 /*align check */
904 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
905 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
906 DEBUG_LOG(ARM11, "align\n");
907 return ALIGNMENT_FAULT;
908 } //else
909 va &= ~(WORD_SIZE - 1);
910 /*tlb translate */
911 fault = translate (state, va, D_TLB (), &tlb);
912 if (fault) {
913 DEBUG_LOG(ARM11, "translate\n");
914 return fault;
915 }
916 /*tlb check access */
917 fault = check_access (state, va, tlb, 0);
918 if (fault) {
919 DEBUG_LOG(ARM11, "check_access\n");
920 return fault;
921 }
922
923 /*2004-07-19 chy: add support for xscale MMU_CacheDisabled */
924 if (MMU_CacheDisabled) {
925 //if(1){ can be used to test the cache error
926 /*get phy_addr */
927 pa = tlb_va_to_pa (tlb, real_va);
928 if (datatype == ARM_BYTE_TYPE)
929 //mem_write_byte (state, pa, data);
930 bus_write(8, pa, data);
931 else if (datatype == ARM_HALFWORD_TYPE)
932 //mem_write_halfword (state, pa, data);
933 bus_write(16, pa, data);
934 else if (datatype == ARM_WORD_TYPE)
935 //mem_write_word (state, pa, data);
936 bus_write(32, pa , data);
937 else {
938 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_write error: unknown data type %d\n", datatype);
939 // skyeye_exit (-1);
940 }
941
942 return NO_FAULT;
943 }
944
945 /*search main cache */
946 b = tlb_b_flag (tlb);
947 pa = tlb_va_to_pa (tlb, va);
948 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
949 if (cache) {
950 cache_t = MAIN_D_CACHE ();
951 goto has_cache;
952 }
953 //chy 2003-08-24, now maybe we don't need minidcache ????
954#if 0
955 /*search mini cache */
956 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
957 if (cache) {
958 cache_t = MINI_D_CACHE ();
959 goto has_cache;
960 }
961#endif
962 b = tlb_b_flag (tlb);
963 pa = tlb_va_to_pa (tlb, va);
964 //chy 2003-08-24, check phy addr 0xa0000000, size 0x04000000
965 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
966 /*
967 if(pa >= 0xb0000000){
968 printf("SKYEYE:xscale_mmu_write phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
969 return 0;
970 }
971 */
972
973 //chy 2003-08-24, now maybe we don't need WB ????
974#if 0
975 if (b) {
976 if (MMU_WBEnabled) {
977 if (datatype == ARM_WORD_TYPE)
978 mmu_wb_write_bytes (state, WB (), pa, &data,
979 4);
980 else if (datatype == ARM_HALFWORD_TYPE)
981 mmu_wb_write_bytes (state, WB (),
982 (pa | (real_va & 2)),
983 &data, 2);
984 else if (datatype == ARM_BYTE_TYPE)
985 mmu_wb_write_bytes (state, WB (),
986 (pa | (real_va & 3)),
987 &data, 1);
988
989 }
990 else {
991 if (datatype == ARM_WORD_TYPE)
992 mem_write_word (state, pa, data);
993 else if (datatype == ARM_HALFWORD_TYPE)
994 mem_write_halfword (state,
995 (pa | (real_va & 2)),
996 data);
997 else if (datatype == ARM_BYTE_TYPE)
998 mem_write_byte (state, (pa | (real_va & 3)),
999 data);
1000 }
1001 }
1002 else {
1003
1004 mmu_wb_drain_all (state, WB ());
1005
1006 if (datatype == ARM_WORD_TYPE)
1007 mem_write_word (state, pa, data);
1008 else if (datatype == ARM_HALFWORD_TYPE)
1009 mem_write_halfword (state, (pa | (real_va & 2)),
1010 data);
1011 else if (datatype == ARM_BYTE_TYPE)
1012 mem_write_byte (state, (pa | (real_va & 3)), data);
1013 }
1014#endif
1015 //chy 2003-08-24, just write phy addr
1016 if (datatype == ARM_WORD_TYPE)
1017 //mem_write_word (state, pa, data);
1018 bus_write(32, pa, data);
1019 else if (datatype == ARM_HALFWORD_TYPE)
1020 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1021 bus_write(16, pa | (real_va & 2), data);
1022 else if (datatype == ARM_BYTE_TYPE)
1023 //mem_write_byte (state, (pa | (real_va & 3)), data);
1024 bus_write(8, (pa | (real_va & 3)), data);
1025#if 0
1026//-------------------------------------------------------------
1027//chy 2003-09-02 for test ????
1028 if (datatype == ARM_WORD_TYPE) {
1029 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1030 printf ("**SKYEYE:mmu_write word: pa %x, va %x, data %x, R15 %x \n", pa, real_va, data, state->Reg[15]);
1031 }
1032 }
1033//--------------------------------------------------------------
1034#endif
1035 return NO_FAULT;
1036
1037 has_cache:
1038 index = va_cache_index (va, cache_t);
1039 //cache->data[index] = data;
1040
1041 if (datatype == ARM_WORD_TYPE)
1042 cache->data[index] = data;
1043 else if (datatype == ARM_HALFWORD_TYPE) {
1044 temp = cache->data[index];
1045 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
1046 cache->data[index] =
1047 (temp & ~(0xffffL << offset)) | ((data & 0xffffL) <<
1048 offset);
1049 }
1050 else if (datatype == ARM_BYTE_TYPE) {
1051 temp = cache->data[index];
1052 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
1053 cache->data[index] =
1054 (temp & ~(0xffL << offset)) | ((data & 0xffL) <<
1055 offset);
1056 }
1057
1058 if (index < (cache_t->width >> (WORD_SHT + 1)))
1059 cache->tag |= TAG_FIRST_HALF_DIRTY;
1060 else
1061 cache->tag |= TAG_LAST_HALF_DIRTY;
1062//-------------------------------------------------------------
1063//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
1064#if 0
1065 {
1066 if (datatype == ARM_WORD_TYPE)
1067 mem_write_word (state, pa, data);
1068 else if (datatype == ARM_HALFWORD_TYPE)
1069 mem_write_halfword (state, (pa | (real_va & 2)),
1070 data);
1071 else if (datatype == ARM_BYTE_TYPE)
1072 mem_write_byte (state, (pa | (real_va & 3)), data);
1073 }
1074#endif
1075#if 0
1076//chy 2003-09-02 for test ????
1077 if (datatype == ARM_WORD_TYPE) {
1078 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1079 printf ("**SKYEYE:mmu_write word:cache: pa %x, va %x, data %x, R15 %x\n", pa, real_va, data, state->Reg[15]);
1080 }
1081 }
1082//-------------------------------------------------------------
1083#endif
1084 if (datatype == ARM_WORD_TYPE)
1085 //mem_write_word (state, pa, data);
1086 bus_write(32, pa, data);
1087 else if (datatype == ARM_HALFWORD_TYPE)
1088 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1089 bus_write(16, pa | (real_va & 2), data);
1090 else if (datatype == ARM_BYTE_TYPE)
1091 //mem_write_byte (state, (pa | (real_va & 3)), data);
1092 bus_write(8, (pa | (real_va & 3)), data);
1093 return NO_FAULT;
1094}
1095
1096ARMword xscale_cp15_mrc (ARMul_State * state,
1097 unsigned type, ARMword instr, ARMword * value)
1098{
1099 return xscale_mmu_mrc (state, instr, value);
1100}
1101
1102ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
1103{
1104 ARMword data;
1105 unsigned opcode_2 = BITS (5, 7);
1106 unsigned CRm = BITS (0, 3);
1107 unsigned reg = BITS (16, 19);
1108 unsigned result;
1109 mmu_regnum_t creg = (mmu_regnum_t)reg;
1110
1111/*
1112 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,\
1113 state->Reg[15], instr);
1114*/
1115 switch (creg) {
1116 case MMU_ID: //XSCALE_CP15
1117 //printf("mmu_mrc read ID \n");
1118 data = (opcode_2 ? state->mmu.cache_type : state->cpu->
1119 cpu_val);
1120 break;
1121 case MMU_CONTROL: //XSCALE_CP15_AUX_CONTROL
1122 //printf("mmu_mrc read CONTROL \n");
1123 data = (opcode_2 ? state->mmu.aux_control : state->mmu.
1124 control);
1125 break;
1126 case MMU_TRANSLATION_TABLE_BASE:
1127 //printf("mmu_mrc read TTB \n");
1128 data = state->mmu.translation_table_base;
1129 break;
1130 case MMU_DOMAIN_ACCESS_CONTROL:
1131 //printf("mmu_mrc read DACR \n");
1132 data = state->mmu.domain_access_control;
1133 break;
1134 case MMU_FAULT_STATUS:
1135 //printf("mmu_mrc read FSR \n");
1136 data = state->mmu.fault_status;
1137 break;
1138 case MMU_FAULT_ADDRESS:
1139 //printf("mmu_mrc read FAR \n");
1140 data = state->mmu.fault_address;
1141 break;
1142 case MMU_PID:
1143 //printf("mmu_mrc read PID \n");
1144 data = state->mmu.process_id;
1145 case XSCALE_CP15_COPRO_ACCESS:
1146 //printf("xscale cp15 read coprocessor access\n");
1147 data = state->mmu.copro_access;
1148 break;
1149 default:
1150 data = 0;
1151 printf ("SKYEYE: xscale_cp15_mrc read UNKNOWN - reg %d, pc 0x%x\n", creg, state->Reg[15]);
1152 // skyeye_exit (-1);
1153 break;
1154 }
1155 *value = data;
1156 //printf("SKYEYE: xscale_cp15_mrc:end value 0x%x\n",data);
1157 return ARMul_DONE;
1158}
1159
1160void xscale_cp15_cache_ops (ARMul_State * state, ARMword instr, ARMword value)
1161{
1162//chy: 2003-08-24 now, the BTB isn't simualted ....????
1163
1164 unsigned CRm, OPC_2;
1165
1166 CRm = BITS (0, 3);
1167 OPC_2 = BITS (5, 7);
1168 //err_msg("SKYEYE: xscale cp15_cache_ops:OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm,state->Reg[15]);
1169
1170 if (OPC_2 == 0 && CRm == 7) {
1171 mmu_cache_invalidate_all (state, I_CACHE ());
1172 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1173 return;
1174 }
1175
1176 if (OPC_2 == 0 && CRm == 5) {
1177 mmu_cache_invalidate_all (state, I_CACHE ());
1178 return;
1179 }
1180 if (OPC_2 == 1 && CRm == 5) {
1181 mmu_cache_invalidate (state, I_CACHE (), value);
1182 return;
1183 }
1184
1185 if (OPC_2 == 0 && CRm == 6) {
1186 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1187 return;
1188 }
1189
1190 if (OPC_2 == 1 && CRm == 6) {
1191 mmu_cache_invalidate (state, MAIN_D_CACHE (), value);
1192 return;
1193 }
1194
1195 if (OPC_2 == 1 && CRm == 0xa) {
1196 mmu_cache_clean (state, MAIN_D_CACHE (), value);
1197 return;
1198 }
1199
1200 if (OPC_2 == 4 && CRm == 0xa) {
1201 mmu_wb_drain_all (state, WB ());
1202 return;
1203 }
1204
1205 if (OPC_2 == 6 && CRm == 5) {
1206 //chy 2004-07-19 shoud fix in the future????!!!!
1207 //printf("SKYEYE: xscale_cp15_cache_ops:invalidate BTB CANT!!!!!!!!!!\n");
1208 //exit(-1);
1209 return;
1210 }
1211
1212 if (OPC_2 == 5 && CRm == 2) {
1213 //printf("SKYEYE: cp15_c_o: A L in D C, value %x, reg15 %x\n",value, state->Reg[15]);
1214 //exit(-1);
1215 //chy 2003-09-01 for test
1216 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1217 return;
1218 }
1219
1220 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]);
1221 // skyeye_exit (-1);
1222}
1223
1224static void
1225 xscale_cp15_tlb_ops (ARMul_State * state, ARMword instr,
1226 ARMword value)
1227{
1228 int CRm, OPC_2;
1229
1230 CRm = BITS (0, 3);
1231 OPC_2 = BITS (5, 7);
1232
1233
1234 //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]);
1235 if (OPC_2 == 0 && CRm == 0x7) {
1236 mmu_tlb_invalidate_all (state, I_TLB ());
1237 mmu_tlb_invalidate_all (state, D_TLB ());
1238 return;
1239 }
1240
1241 if (OPC_2 == 0 && CRm == 0x5) {
1242 mmu_tlb_invalidate_all (state, I_TLB ());
1243 return;
1244 }
1245
1246 if (OPC_2 == 1 && CRm == 0x5) {
1247 mmu_tlb_invalidate_entry (state, I_TLB (), value);
1248 return;
1249 }
1250
1251 if (OPC_2 == 0 && CRm == 0x6) {
1252 mmu_tlb_invalidate_all (state, D_TLB ());
1253 return;
1254 }
1255
1256 if (OPC_2 == 1 && CRm == 0x6) {
1257 mmu_tlb_invalidate_entry (state, D_TLB (), value);
1258 return;
1259 }
1260
1261 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]);
1262 // skyeye_exit (-1);
1263}
1264
1265
1266ARMword xscale_cp15_mcr (ARMul_State * state,
1267 unsigned type, ARMword instr, ARMword value)
1268{
1269 return xscale_mmu_mcr (state, instr, value);
1270}
1271
1272ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
1273{
1274 ARMword data;
1275 unsigned opcode_2 = BITS (5, 7);
1276 unsigned CRm = BITS (0, 3);
1277 unsigned reg = BITS (16, 19);
1278 unsigned result;
1279 mmu_regnum_t creg = (mmu_regnum_t)reg;
1280
1281 //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);
1282
1283 switch (creg) {
1284 case MMU_CONTROL:
1285 //printf("mmu_mcr wrote CONTROL val 0x%x \n",value);
1286 state->mmu.control =
1287 (opcode_2 ? (value & 0x33) : (value & 0x3FFF));
1288 break;
1289 case MMU_TRANSLATION_TABLE_BASE:
1290 //printf("mmu_mcr wrote TTB val 0x%x \n",value);
1291 state->mmu.translation_table_base = value & 0xFFFFC000;
1292 break;
1293 case MMU_DOMAIN_ACCESS_CONTROL:
1294 //printf("mmu_mcr wrote DACR val 0x%x \n",value);
1295 state->mmu.domain_access_control = value;
1296 break;
1297
1298 case MMU_FAULT_STATUS:
1299 //printf("mmu_mcr wrote FS val 0x%x \n",value);
1300 state->mmu.fault_status = value & 0x6FF;
1301 break;
1302 case MMU_FAULT_ADDRESS:
1303 //printf("mmu_mcr wrote FA val 0x%x \n",value);
1304 state->mmu.fault_address = value;
1305 break;
1306
1307 case MMU_CACHE_OPS:
1308// printf("mmu_mcr wrote CO val 0x%x \n",value);
1309 xscale_cp15_cache_ops (state, instr, value);
1310 break;
1311 case MMU_TLB_OPS:
1312 //printf("mmu_mcr wrote TO val 0x%x \n",value);
1313 xscale_cp15_tlb_ops (state, instr, value);
1314 break;
1315 case MMU_PID:
1316 //printf("mmu_mcr wrote PID val 0x%x \n",value);
1317 state->mmu.process_id = value & 0xfe000000;
1318 break;
1319 case XSCALE_CP15_COPRO_ACCESS:
1320 //printf("xscale cp15 write coprocessor access val 0x %x\n",value);
1321 state->mmu.copro_access = value & 0x3ff;
1322 break;
1323
1324 default:
1325 printf ("SKYEYE: xscale_cp15_mcr wrote UNKNOWN - reg %d, reg15 0x%x\n", creg, state->Reg[15]);
1326 break;
1327 }
1328 //printf("SKYEYE: xscale_cp15_mcr wrote val 0x%x\n", value);
1329 return 0;
1330}
1331
1332//teawater add for arm2x86 2005.06.24-------------------------------------------
1333static int xscale_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
1334 ARMword * phys_addr)
1335{
1336 fault_t fault;
1337 tlb_entry_t *tlb;
1338
1339 virt_addr = mmu_pid_va_map (virt_addr);
1340 if (MMU_Enabled) {
1341
1342 /*align check */
1343 if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
1344 DEBUG_LOG(ARM11, "align\n");
1345 return ALIGNMENT_FAULT;
1346 }
1347 else
1348 virt_addr &= ~(WORD_SIZE - 1);
1349
1350 /*translate tlb */
1351 fault = translate (state, virt_addr, I_TLB (), &tlb);
1352 if (fault) {
1353 DEBUG_LOG(ARM11, "translate\n");
1354 return fault;
1355 }
1356
1357 /*check access */
1358 fault = check_access (state, virt_addr, tlb, 1);
1359 if (fault) {
1360 DEBUG_LOG(ARM11, "check_fault\n");
1361 return fault;
1362 }
1363 }
1364
1365 if (MMU_Disabled) {
1366 *phys_addr = virt_addr;
1367 }
1368 else {
1369 *phys_addr = tlb_va_to_pa (tlb, virt_addr);
1370 }
1371
1372 return (0);
1373}
1374
1375//AJ2D--------------------------------------------------------------------------
1376
1377/*xscale mmu_ops_t*/
1378//mmu_ops_t xscale_mmu_ops = {
1379// xscale_cp15_init,
1380// xscale_cp15_exit,
1381// xscale_mmu_read_byte,
1382// xscale_mmu_write_byte,
1383// xscale_mmu_read_halfword,
1384// xscale_mmu_write_halfword,
1385// xscale_mmu_read_word,
1386// xscale_mmu_write_word,
1387// xscale_mmu_load_instr, xscale_mmu_mcr, xscale_mmu_mrc,
1388////teawater add for arm2x86 2005.06.24-------------------------------------------
1389// xscale_mmu_v2p_dbct,
1390////AJ2D--------------------------------------------------------------------------
1391//};
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index fd574a7a1..8e71948c6 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -367,7 +367,6 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
367 367
368 int verbose; /* non-zero means print various messages like the banner */ 368 int verbose; /* non-zero means print various messages like the banner */
369 369
370 mmu_state_t mmu;
371 int mmu_inited; 370 int mmu_inited;
372 //mem_state_t mem; 371 //mem_state_t mem;
373 /*remove io_state to skyeye_mach_*.c files */ 372 /*remove io_state to skyeye_mach_*.c files */
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
index 818108c9c..30858f9ba 100644
--- a/src/core/arm/skyeye_common/armmmu.h
+++ b/src/core/arm/skyeye_common/armmmu.h
@@ -134,121 +134,4 @@ typedef enum fault_t
134 134
135} fault_t; 135} fault_t;
136 136
137typedef struct mmu_ops_s
138{
139 /*initilization */
140 int (*init) (ARMul_State * state);
141 /*free on exit */
142 void (*exit) (ARMul_State * state);
143 /*read byte data */
144 fault_t (*read_byte) (ARMul_State * state, ARMword va,
145 ARMword * data);
146 /*write byte data */
147 fault_t (*write_byte) (ARMul_State * state, ARMword va,
148 ARMword data);
149 /*read halfword data */
150 fault_t (*read_halfword) (ARMul_State * state, ARMword va,
151 ARMword * data);
152 /*write halfword data */
153 fault_t (*write_halfword) (ARMul_State * state, ARMword va,
154 ARMword data);
155 /*read word data */
156 fault_t (*read_word) (ARMul_State * state, ARMword va,
157 ARMword * data);
158 /*write word data */
159 fault_t (*write_word) (ARMul_State * state, ARMword va,
160 ARMword data);
161 /*load instr */
162 fault_t (*load_instr) (ARMul_State * state, ARMword va,
163 ARMword * instr);
164 /*mcr */
165 ARMword (*mcr) (ARMul_State * state, ARMword instr, ARMword val);
166 /*mrc */
167 ARMword (*mrc) (ARMul_State * state, ARMword instr, ARMword * val);
168
169 /*ywc 2005-04-16 convert virtual address to physics address */
170 int (*v2p_dbct) (ARMul_State * state, ARMword virt_addr,
171 ARMword * phys_addr);
172} mmu_ops_t;
173
174
175#include "core/arm/interpreter/mmu/tlb.h"
176#include "core/arm/interpreter/mmu/rb.h"
177#include "core/arm/interpreter/mmu/wb.h"
178#include "core/arm/interpreter/mmu/cache.h"
179
180/*special process mmu.h*/
181#include "core/arm/interpreter/mmu/sa_mmu.h"
182//#include "core/arm/interpreter/mmu/arm7100_mmu.h"
183//#include "core/arm/interpreter/mmu/arm920t_mmu.h"
184//#include "core/arm/interpreter/mmu/arm926ejs_mmu.h"
185#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h"
186//#include "core/arm/interpreter/mmu/cortex_a9_mmu.h"
187
188typedef struct mmu_state_t
189{
190 ARMword control;
191 ARMword translation_table_base;
192/* dyf 201-08-11 for arm1176 */
193 ARMword auxiliary_control;
194 ARMword coprocessor_access_control;
195 ARMword translation_table_base0;
196 ARMword translation_table_base1;
197 ARMword translation_table_ctrl;
198/* arm1176 end */
199
200 ARMword domain_access_control;
201 ARMword fault_status;
202 ARMword fault_statusi; /* prefetch fault status */
203 ARMword fault_address;
204 ARMword last_domain;
205 ARMword process_id;
206 ARMword context_id;
207 ARMword thread_uro_id;
208 ARMword cache_locked_down;
209 ARMword tlb_locked_down;
210//chy 2003-08-24 for xscale
211 ARMword cache_type; // 0
212 ARMword aux_control; // 1
213 ARMword copro_access; // 15
214
215 mmu_ops_t ops;
216 union
217 {
218 sa_mmu_t sa_mmu;
219 //arm7100_mmu_t arm7100_mmu;
220 //arm920t_mmu_t arm920t_mmu;
221 //arm926ejs_mmu_t arm926ejs_mmu;
222 } u;
223} mmu_state_t;
224
225int mmu_init (ARMul_State * state);
226int mmu_reset (ARMul_State * state);
227void mmu_exit (ARMul_State * state);
228
229fault_t mmu_read_word (ARMul_State * state, ARMword virt_addr,
230 ARMword * data);
231fault_t mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
232fault_t mmu_load_instr (ARMul_State * state, ARMword virt_addr,
233 ARMword * instr);
234
235ARMword mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
236void mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);
237
238/*ywc 20050416*/
239int mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
240 ARMword * phys_addr);
241
242fault_t
243mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data);
244fault_t
245mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data);
246fault_t
247mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data);
248fault_t
249mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data);
250fault_t
251mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data);
252fault_t
253mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
254#endif /* _ARMMMU_H_ */ 137#endif /* _ARMMMU_H_ */