summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armcopro.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-10-25 14:35:31 -0400
committerGravatar bunnei2014-10-25 14:35:31 -0400
commit4615c73d15f6f27c5e275c57dcafcb56355b9c2d (patch)
treee11104887d1a680e3aa33bddc4ad3ca764ead696 /src/core/arm/interpreter/armcopro.cpp
parentMerge pull request #149 from linkmauve/open-file-directly-fix (diff)
parentARM: Removed unnecessary and unused SkyEye MMU code. (diff)
downloadyuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.tar.gz
yuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.tar.xz
yuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.zip
Merge pull request #112 from bunnei/skyeye-dyncom-interpreter
SkyEye dyncom interpreter
Diffstat (limited to 'src/core/arm/interpreter/armcopro.cpp')
-rw-r--r--src/core/arm/interpreter/armcopro.cpp1007
1 files changed, 245 insertions, 762 deletions
diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp
index 6a75e6601..b4ddc3d96 100644
--- a/src/core/arm/interpreter/armcopro.cpp
+++ b/src/core/arm/interpreter/armcopro.cpp
@@ -15,828 +15,311 @@
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 18#include "core/arm/skyeye_common/armdefs.h"
19#include "core/arm/interpreter/armdefs.h" 19#include "core/arm/skyeye_common/armemu.h"
20#include "core/arm/interpreter/armos.h" 20#include "core/arm/skyeye_common/vfp/vfp.h"
21#include "core/arm/interpreter/armemu.h"
22#include "core/arm/interpreter/vfp/vfp.h"
23 21
24//chy 2005-07-08 22//chy 2005-07-08
25//#include "ansidecl.h" 23//#include "ansidecl.h"
26//chy ------- 24//chy -------
27//#include "iwmmxt.h" 25//#include "iwmmxt.h"
28 26
29
30//chy 2005-09-19 add CP6 MRC support (for get irq number and base)
31extern unsigned xscale_cp6_mrc (ARMul_State * state, unsigned type,
32 ARMword instr, ARMword * data);
33//chy 2005-09-19---------------
34
35extern unsigned xscale_cp13_init (ARMul_State * state);
36extern unsigned xscale_cp13_exit (ARMul_State * state);
37extern unsigned xscale_cp13_ldc (ARMul_State * state, unsigned type,
38 ARMword instr, ARMword data);
39extern unsigned xscale_cp13_stc (ARMul_State * state, unsigned type,
40 ARMword instr, ARMword * data);
41extern unsigned xscale_cp13_mrc (ARMul_State * state, unsigned type,
42 ARMword instr, ARMword * data);
43extern unsigned xscale_cp13_mcr (ARMul_State * state, unsigned type,
44 ARMword instr, ARMword data);
45extern unsigned xscale_cp13_cdp (ARMul_State * state, unsigned type,
46 ARMword instr);
47extern unsigned xscale_cp13_read_reg (ARMul_State * state, unsigned reg,
48 ARMword * data);
49extern unsigned xscale_cp13_write_reg (ARMul_State * state, unsigned reg,
50 ARMword data);
51extern unsigned xscale_cp14_init (ARMul_State * state);
52extern unsigned xscale_cp14_exit (ARMul_State * state);
53extern unsigned xscale_cp14_ldc (ARMul_State * state, unsigned type,
54 ARMword instr, ARMword data);
55extern unsigned xscale_cp14_stc (ARMul_State * state, unsigned type,
56 ARMword instr, ARMword * data);
57extern unsigned xscale_cp14_mrc (ARMul_State * state, unsigned type,
58 ARMword instr, ARMword * data);
59extern unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type,
60 ARMword instr, ARMword data);
61extern unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type,
62 ARMword instr);
63extern unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
64 ARMword * data);
65extern unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
66 ARMword data);
67extern unsigned xscale_cp15_init (ARMul_State * state);
68extern unsigned xscale_cp15_exit (ARMul_State * state);
69extern unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type,
70 ARMword instr, ARMword data);
71extern unsigned xscale_cp15_stc (ARMul_State * state, unsigned type,
72 ARMword instr, ARMword * data);
73extern unsigned xscale_cp15_mrc (ARMul_State * state, unsigned type,
74 ARMword instr, ARMword * data);
75extern unsigned xscale_cp15_mcr (ARMul_State * state, unsigned type,
76 ARMword instr, ARMword data);
77extern unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type,
78 ARMword instr);
79extern unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
80 ARMword * data);
81extern unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
82 ARMword data);
83extern unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
84 unsigned cpnum);
85
86/* Dummy Co-processors. */ 27/* Dummy Co-processors. */
87 28
88static unsigned 29static unsigned
89NoCoPro3R (ARMul_State * state, 30NoCoPro3R(ARMul_State * state,
90 unsigned a, ARMword b) 31unsigned a, ARMword b)
91{ 32{
92 return ARMul_CANT; 33 return ARMul_CANT;
93} 34}
94 35
95static unsigned 36static unsigned
96NoCoPro4R (ARMul_State * state, 37NoCoPro4R(ARMul_State * state,
97 unsigned a, 38unsigned a,
98 ARMword b, ARMword c) 39ARMword b, ARMword c)
99{ 40{
100 return ARMul_CANT; 41 return ARMul_CANT;
101} 42}
102 43
103static unsigned 44static unsigned
104NoCoPro4W (ARMul_State * state, 45NoCoPro4W(ARMul_State * state,
105 unsigned a, 46unsigned a,
106 ARMword b, ARMword * c) 47ARMword b, ARMword * c)
107{ 48{
108 return ARMul_CANT; 49 return ARMul_CANT;
109} 50}
110 51
111static unsigned 52static unsigned
112NoCoPro5R (ARMul_State * state, 53NoCoPro5R(ARMul_State * state,
113 unsigned a, 54unsigned a,
114 ARMword b, 55ARMword b,
115 ARMword c, ARMword d) 56ARMword c, ARMword d)
116{ 57{
117 return ARMul_CANT; 58 return ARMul_CANT;
118} 59}
119 60
120static unsigned 61static unsigned
121NoCoPro5W (ARMul_State * state, 62NoCoPro5W(ARMul_State * state,
122 unsigned a, 63unsigned a,
123 ARMword b, 64ARMword b,
124 ARMword * c, ARMword * d ) 65ARMword * c, ARMword * d)
125{ 66{
126 return ARMul_CANT; 67 return ARMul_CANT;
127} 68}
128 69
129/* The XScale Co-processors. */ 70/* The XScale Co-processors. */
130 71
131/* Coprocessor 15: System Control. */ 72/* Coprocessor 15: System Control. */
132static void write_cp14_reg (unsigned, ARMword); 73static void write_cp14_reg(unsigned, ARMword);
133static ARMword read_cp14_reg (unsigned); 74static ARMword read_cp14_reg(unsigned);
134
135/* There are two sets of registers for copro 15.
136 One set is available when opcode_2 is 0 and
137 the other set when opcode_2 >= 1. */
138static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
139static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];
140/* There are also a set of breakpoint registers
141 which are accessed via CRm instead of opcode_2. */
142static ARMword XScale_cp15_DBR1;
143static ARMword XScale_cp15_DBCON;
144static ARMword XScale_cp15_IBCR0;
145static ARMword XScale_cp15_IBCR1;
146
147static unsigned
148XScale_cp15_init (ARMul_State * state)
149{
150 int i;
151
152 for (i = 16; i--;) {
153 XScale_cp15_opcode_2_is_0_Regs[i] = 0;
154 XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;
155 }
156
157 /* Initialise the processor ID. */
158 //chy 2003-03-24, is same as cpu id in skyeye_options.c
159 //XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;
160 XScale_cp15_opcode_2_is_0_Regs[0] = 0x69050000;
161
162 /* Initialise the cache type. */
163 XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;
164
165 /* Initialise the ARM Control Register. */
166 XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
167
168 return No_exp;
169}
170
171/* Check an access to a register. */
172
173static unsigned
174check_cp15_access (ARMul_State * state,
175 unsigned reg,
176 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
177{
178 /* Do not allow access to these register in USER mode. */
179 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
180 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
181 return ARMul_CANT;
182
183 /* Opcode_1should be zero. */
184 if (opcode_1 != 0)
185 return ARMul_CANT;
186
187 /* Different register have different access requirements. */
188 switch (reg) {
189 case 0:
190 case 1:
191 /* CRm must be 0. Opcode_2 can be anything. */
192 if (CRm != 0)
193 return ARMul_CANT;
194 break;
195 case 2:
196 case 3:
197 /* CRm must be 0. Opcode_2 must be zero. */
198 if ((CRm != 0) || (opcode_2 != 0))
199 return ARMul_CANT;
200 break;
201 case 4:
202 /* Access not allowed. */
203 return ARMul_CANT;
204 case 5:
205 case 6:
206 /* Opcode_2 must be zero. CRm must be 0. */
207 if ((CRm != 0) || (opcode_2 != 0))
208 return ARMul_CANT;
209 break;
210 case 7:
211 /* Permissable combinations:
212 Opcode_2 CRm
213 0 5
214 0 6
215 0 7
216 1 5
217 1 6
218 1 10
219 4 10
220 5 2
221 6 5 */
222 switch (opcode_2) {
223 default:
224 return ARMul_CANT;
225 case 6:
226 if (CRm != 5)
227 return ARMul_CANT;
228 break;
229 case 5:
230 if (CRm != 2)
231 return ARMul_CANT;
232 break;
233 case 4:
234 if (CRm != 10)
235 return ARMul_CANT;
236 break;
237 case 1:
238 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
239 return ARMul_CANT;
240 break;
241 case 0:
242 if ((CRm < 5) || (CRm > 7))
243 return ARMul_CANT;
244 break;
245 }
246 break;
247
248 case 8:
249 /* Permissable combinations:
250 Opcode_2 CRm
251 0 5
252 0 6
253 0 7
254 1 5
255 1 6 */
256 if (opcode_2 > 1)
257 return ARMul_CANT;
258 if ((CRm < 5) || (CRm > 7))
259 return ARMul_CANT;
260 if (opcode_2 == 1 && CRm == 7)
261 return ARMul_CANT;
262 break;
263 case 9:
264 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
265 if (((CRm != 0) && (CRm != 1))
266 || ((opcode_2 != 1) && (opcode_2 != 2)))
267 return ARMul_CANT;
268 break;
269 case 10:
270 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
271 if (((CRm != 0) && (CRm != 1))
272 || ((opcode_2 != 4) && (opcode_2 != 8)))
273 return ARMul_CANT;
274 break;
275 case 11:
276 /* Access not allowed. */
277 return ARMul_CANT;
278 case 12:
279 /* Access not allowed. */
280 return ARMul_CANT;
281 case 13:
282 /* Opcode_2 must be zero. CRm must be 0. */
283 if ((CRm != 0) || (opcode_2 != 0))
284 return ARMul_CANT;
285 break;
286 case 14:
287 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
288 if (opcode_2 != 0)
289 return ARMul_CANT;
290
291 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
292 && (CRm != 9))
293 return ARMul_CANT;
294 break;
295 case 15:
296 /* Opcode_2 must be zero. CRm must be 1. */
297 if ((CRm != 1) || (opcode_2 != 0))
298 return ARMul_CANT;
299 break;
300 default:
301 /* Should never happen. */
302 return ARMul_CANT;
303 }
304
305 return ARMul_DONE;
306}
307
308/* Coprocessor 13: Interrupt Controller and Bus Controller. */
309
310/* There are two sets of registers for copro 13.
311 One set (of three registers) is available when CRm is 0
312 and the other set (of six registers) when CRm is 1. */
313
314static ARMword XScale_cp13_CR0_Regs[16];
315static ARMword XScale_cp13_CR1_Regs[16];
316
317static unsigned
318XScale_cp13_init (ARMul_State * state)
319{
320 int i;
321
322 for (i = 16; i--;) {
323 XScale_cp13_CR0_Regs[i] = 0;
324 XScale_cp13_CR1_Regs[i] = 0;
325 }
326
327 return No_exp;
328}
329
330/* Check an access to a register. */
331
332static unsigned
333check_cp13_access (ARMul_State * state,
334 unsigned reg,
335 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
336{
337 /* Do not allow access to these registers in USER mode. */
338 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
339 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
340 return ARMul_CANT;
341
342 /* The opcodes should be zero. */
343 if ((opcode_1 != 0) || (opcode_2 != 0))
344 return ARMul_CANT;
345
346 /* Do not allow access to these register if bit
347 13 of coprocessor 15's register 15 is zero. */
348 if (!CP_ACCESS_ALLOWED (state, 13))
349 return ARMul_CANT;
350
351 /* Registers 0, 4 and 8 are defined when CRm == 0.
352 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
353 For all other CRm values undefined behaviour results. */
354 if (CRm == 0) {
355 if (reg == 0 || reg == 4 || reg == 8)
356 return ARMul_DONE;
357 }
358 else if (CRm == 1) {
359 if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
360 return ARMul_DONE;
361 }
362
363 return ARMul_CANT;
364}
365
366/* Coprocessor 14: Performance Monitoring, Clock and Power management,
367 Software Debug. */
368
369static ARMword XScale_cp14_Regs[16];
370
371static unsigned
372XScale_cp14_init (ARMul_State * state)
373{
374 int i;
375
376 for (i = 16; i--;)
377 XScale_cp14_Regs[i] = 0;
378
379 return No_exp;
380}
381 75
382/* Check an access to a register. */ 76/* Check an access to a register. */
383 77
384static unsigned 78static unsigned
385check_cp14_access (ARMul_State * state, 79check_cp15_access(ARMul_State * state,
386 unsigned reg, 80unsigned reg,
387 unsigned CRm, unsigned opcode1, unsigned opcode2) 81unsigned CRm, unsigned opcode_1, unsigned opcode_2)
388{
389 /* Not allowed to access these register in USER mode. */
390 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
391 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
392 return ARMul_CANT;
393
394 /* CRm should be zero. */
395 if (CRm != 0)
396 return ARMul_CANT;
397
398 /* OPcodes should be zero. */
399 if (opcode1 != 0 || opcode2 != 0)
400 return ARMul_CANT;
401
402 /* Accessing registers 4 or 5 has unpredicatable results. */
403 if (reg >= 4 && reg <= 5)
404 return ARMul_CANT;
405
406 return ARMul_DONE;
407}
408
409/* Here's ARMulator's MMU definition. A few things to note:
410 1) It has eight registers, but only two are defined.
411 2) You can only access its registers with MCR and MRC.
412 3) MMU Register 0 (ID) returns 0x41440110
413 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
414 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
415 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
416
417static ARMword MMUReg[8];
418
419static unsigned
420MMUInit (ARMul_State * state)
421{
422/* 2004-05-09 chy
423-------------------------------------------------------------
424read ARM Architecture Reference Manual
4252.6.5 Data Abort
426There are three Abort Model in ARM arch.
427
428Early Abort Model: used in some ARMv3 and earlier implementations. In this
429model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
430the base register was unchanged for all other instructions. (oldest)
431
432Base Restored Abort Model: If a Data Abort occurs in an instruction which
433specifies base register writeback, the value in the base register is
434unchanged. (strongarm, xscale)
435
436Base Updated Abort Model: If a Data Abort occurs in an instruction which
437specifies base register writeback, the base register writeback still occurs.
438(arm720T)
439
440read PART B
441chap2 The System Control Coprocessor CP15
4422.4 Register1:control register
443L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
444processor could be configured:
4450=early Abort Model Selected(now obsolete)
4461=Late Abort Model selceted(same as Base Updated Abort Model)
447
448on later processors, this bit reads as 1 and ignores writes.
449-------------------------------------------------------------
450So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
451 if lateabtSig=0, then it means Base Restored Abort Model
452because the ARMs which skyeye simulates are all belonged to ARMv4,
453so I think MMUReg[1]'s bit 6 should always be 1
454
455*/
456
457 MMUReg[1] = state->prog32Sig << 4 |
458 state->data32Sig << 5 | 1 << 6 | state->bigendSig << 7;
459 //state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
460
461
462 NOTICE_LOG(ARM11, "ARMul_ConsolePrint: MMU present");
463
464 return TRUE;
465}
466
467static unsigned
468MMUMRC (ARMul_State * state, unsigned type,
469 ARMword instr, ARMword * value)
470{
471 mmu_mrc (state, instr, value);
472 return (ARMul_DONE);
473}
474
475static unsigned
476MMUMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
477{
478 mmu_mcr (state, instr, value);
479 return (ARMul_DONE);
480}
481
482/* What follows is the Validation Suite Coprocessor. It uses two
483 co-processor numbers (4 and 5) and has the follwing functionality.
484 Sixteen registers. Both co-processor nuimbers can be used in an MCR
485 and MRC to access these registers. CP 4 can LDC and STC to and from
486 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
487 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
488 number of cycles (specified in a CP register), CDP 2 issues an IRQW
489 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
490 stores a 32 bit time value in a CP register (actually it's the total
491 number of N, S, I, C and F cyles). */
492
493static ARMword ValReg[16];
494
495static unsigned
496ValLDC (ARMul_State * state,
497 unsigned type, ARMword instr, ARMword data)
498{
499 static unsigned words;
500
501 if (type != ARMul_DATA)
502 words = 0;
503 else {
504 ValReg[BITS (12, 15)] = data;
505
506 if (BIT (22))
507 /* It's a long access, get two words. */
508 if (words++ != 4)
509 return ARMul_INC;
510 }
511
512 return ARMul_DONE;
513}
514
515static unsigned
516ValSTC (ARMul_State * state,
517 unsigned type, ARMword instr, ARMword * data)
518{
519 static unsigned words;
520
521 if (type != ARMul_DATA)
522 words = 0;
523 else {
524 *data = ValReg[BITS (12, 15)];
525
526 if (BIT (22))
527 /* It's a long access, get two words. */
528 if (words++ != 4)
529 return ARMul_INC;
530 }
531
532 return ARMul_DONE;
533}
534
535static unsigned
536ValMRC (ARMul_State * state,
537 unsigned type, ARMword instr, ARMword * value)
538{
539 *value = ValReg[BITS (16, 19)];
540
541 return ARMul_DONE;
542}
543
544static unsigned
545ValMCR (ARMul_State * state,
546 unsigned type, ARMword instr, ARMword value)
547{
548 ValReg[BITS (16, 19)] = value;
549
550 return ARMul_DONE;
551}
552
553static unsigned
554ValCDP (ARMul_State * state, unsigned type, ARMword instr)
555{
556 static unsigned int finish = 0;
557
558 if (BITS (20, 23) != 0)
559 return ARMul_CANT;
560
561 if (type == ARMul_FIRST) {
562 ARMword howlong;
563
564 howlong = ValReg[BITS (0, 3)];
565
566 /* First cycle of a busy wait. */
567 finish = ARMul_Time (state) + howlong;
568
569 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
570 }
571 else if (type == ARMul_BUSY) {
572 if (ARMul_Time (state) >= finish)
573 return ARMul_DONE;
574 else
575 return ARMul_BUSY;
576 }
577
578 return ARMul_CANT;
579}
580
581static unsigned
582DoAFIQ (ARMul_State * state)
583{
584 state->NfiqSig = LOW;
585 return 0;
586}
587
588static unsigned
589DoAIRQ (ARMul_State * state)
590{
591 state->NirqSig = LOW;
592 return 0;
593}
594
595static unsigned
596IntCDP (ARMul_State * state, unsigned type, ARMword instr)
597{ 82{
598 static unsigned int finish; 83 /* Do not allow access to these register in USER mode. */
599 ARMword howlong; 84 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
600 85 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
601 howlong = ValReg[BITS (0, 3)]; 86 return ARMul_CANT;
602 87
603 switch ((int) BITS (20, 23)) { 88 /* Opcode_1should be zero. */
604 case 0: 89 if (opcode_1 != 0)
605 if (type == ARMul_FIRST) { 90 return ARMul_CANT;
606 /* First cycle of a busy wait. */ 91
607 finish = ARMul_Time (state) + howlong; 92 /* Different register have different access requirements. */
608 93 switch (reg) {
609 return howlong == 0 ? ARMul_DONE : ARMul_BUSY; 94 case 0:
610 } 95 case 1:
611 else if (type == ARMul_BUSY) { 96 /* CRm must be 0. Opcode_2 can be anything. */
612 if (ARMul_Time (state) >= finish) 97 if (CRm != 0)
613 return ARMul_DONE; 98 return ARMul_CANT;
614 else 99 break;
615 return ARMul_BUSY; 100 case 2:
616 } 101 case 3:
617 return ARMul_DONE; 102 /* CRm must be 0. Opcode_2 must be zero. */
618 103 if ((CRm != 0) || (opcode_2 != 0))
619 case 1: 104 return ARMul_CANT;
620 if (howlong == 0) 105 break;
621 ARMul_Abort (state, ARMul_FIQV); 106 case 4:
622 else 107 /* Access not allowed. */
623 ARMul_ScheduleEvent (state, howlong, DoAFIQ); 108 return ARMul_CANT;
624 return ARMul_DONE; 109 case 5:
625 110 case 6:
626 case 2: 111 /* Opcode_2 must be zero. CRm must be 0. */
627 if (howlong == 0) 112 if ((CRm != 0) || (opcode_2 != 0))
628 ARMul_Abort (state, ARMul_IRQV); 113 return ARMul_CANT;
629 else 114 break;
630 ARMul_ScheduleEvent (state, howlong, DoAIRQ); 115 case 7:
631 return ARMul_DONE; 116 /* Permissable combinations:
632 117 Opcode_2 CRm
633 case 3: 118 0 5
634 state->NfiqSig = HIGH; 119 0 6
635 return ARMul_DONE; 120 0 7
636 121 1 5
637 case 4: 122 1 6
638 state->NirqSig = HIGH; 123 1 10
639 return ARMul_DONE; 124 4 10
640 125 5 2
641 case 5: 126 6 5 */
642 ValReg[BITS (0, 3)] = ARMul_Time (state); 127 switch (opcode_2) {
643 return ARMul_DONE; 128 default:
644 } 129 return ARMul_CANT;
645 130 case 6:
646 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;
647} 211}
648 212
649/* Install co-processor instruction handlers in this routine. */ 213/* Install co-processor instruction handlers in this routine. */
650 214
651unsigned 215unsigned
652ARMul_CoProInit (ARMul_State * state) 216ARMul_CoProInit(ARMul_State * state)
653{ 217{
654 unsigned int i; 218 unsigned int i;
655 219
656 /* Initialise tham all first. */ 220 /* Initialise tham all first. */
657 for (i = 0; i < 16; i++) 221 for (i = 0; i < 16; i++)
658 ARMul_CoProDetach (state, i); 222 ARMul_CoProDetach(state, i);
659 223
660 /* Install CoPro Instruction handlers here. 224 /* Install CoPro Instruction handlers here.
661 The format is: 225 The format is:
662 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine 226 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
663 LDC routine, STC routine, MRC routine, MCR routine, 227 LDC routine, STC routine, MRC routine, MCR routine,
664 CDP routine, Read Reg routine, Write Reg routine). */ 228 CDP routine, Read Reg routine, Write Reg routine). */
665 if (state->is_ep9312) { 229 if (state->is_v6) {
666 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, 230 ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
667 DSPMRC4, DSPMCR4, NULL, NULL, DSPCDP4, NULL, NULL); 231 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
668 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, 232 ARMul_CoProAttach(state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
669 DSPMRC5, DSPMCR5, NULL, NULL, DSPCDP5, NULL, NULL); 233 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
670 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, 234
671 DSPMRC6, DSPMCR6, NULL, NULL, DSPCDP6, NULL, NULL); 235 /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
672 } 236 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/
673 else { 237 }
674 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, 238 //chy 2003-09-03 do it in future!!!!????
675 ValMRC, ValMCR, NULL, NULL, ValCDP, NULL, NULL);
676
677 ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
678 ValMRC, ValMCR, NULL, NULL, IntCDP, NULL, NULL);
679 }
680
681 if (state->is_XScale) {
682 //chy 2005-09-19, for PXA27x's CP6
683 if (state->is_pxa27x) {
684 ARMul_CoProAttach (state, 6, NULL, NULL,
685 NULL, NULL, xscale_cp6_mrc,
686 NULL, NULL, NULL, NULL, NULL, NULL);
687 }
688 //chy 2005-09-19 end-------------
689 ARMul_CoProAttach (state, 13, xscale_cp13_init,
690 xscale_cp13_exit, xscale_cp13_ldc,
691 xscale_cp13_stc, xscale_cp13_mrc,
692 xscale_cp13_mcr, NULL, NULL, xscale_cp13_cdp,
693 xscale_cp13_read_reg,
694 xscale_cp13_write_reg);
695
696 ARMul_CoProAttach (state, 14, xscale_cp14_init,
697 xscale_cp14_exit, xscale_cp14_ldc,
698 xscale_cp14_stc, xscale_cp14_mrc,
699 xscale_cp14_mcr, NULL, NULL, xscale_cp14_cdp,
700 xscale_cp14_read_reg,
701 xscale_cp14_write_reg);
702 //chy: 2003-08-24.
703 ARMul_CoProAttach (state, 15, xscale_cp15_init,
704 xscale_cp15_exit, xscale_cp15_ldc,
705 xscale_cp15_stc, xscale_cp15_mrc,
706 xscale_cp15_mcr, NULL, NULL, xscale_cp15_cdp,
707 xscale_cp15_read_reg,
708 xscale_cp15_write_reg);
709 }
710 else if (state->is_v6) {
711 ARMul_CoProAttach (state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
712 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
713 ARMul_CoProAttach (state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
714 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
715
716 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
717 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
718 }
719 else { //all except xscale
720 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
721 // MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
722 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
723 }
724//chy 2003-09-03 do it in future!!!!????
725#if 0 239#if 0
726 if (state->is_iWMMXt) { 240 if (state->is_iWMMXt) {
727 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, 241 ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
728 NULL, NULL, IwmmxtCDP, NULL, NULL); 242 NULL, NULL, IwmmxtCDP, NULL, NULL);
729 243
730 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 244 ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL,
731 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, 245 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL,
732 NULL); 246 NULL);
733 } 247 }
734#endif 248#endif
735 //----------------------------------------------------------------------------- 249 /* No handlers below here. */
736 //chy 2004-05-25, found the user/system code visit CP 1,2, so I add below code. 250
737 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 251 /* Call all the initialisation routines. */
738 ValMRC, ValMCR, NULL, NULL, NULL, NULL, NULL); 252 for (i = 0; i < 16; i++)
739 ARMul_CoProAttach (state, 2, NULL, NULL, ValLDC, ValSTC, 253 if (state->CPInit[i])
740 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 254 (state->CPInit[i]) (state);
741 //------------------------------------------------------------------------------ 255
742 /* No handlers below here. */ 256 return TRUE;
743
744 /* Call all the initialisation routines. */
745 for (i = 0; i < 16; i++)
746 if (state->CPInit[i])
747 (state->CPInit[i]) (state);
748
749 return TRUE;
750} 257}
751 258
752/* Install co-processor finalisation routines in this routine. */ 259/* Install co-processor finalisation routines in this routine. */
753 260
754void 261void
755ARMul_CoProExit (ARMul_State * state) 262ARMul_CoProExit(ARMul_State * state)
756{ 263{
757 register unsigned i; 264 register unsigned i;
758 265
759 for (i = 0; i < 16; i++) 266 for (i = 0; i < 16; i++)
760 if (state->CPExit[i]) 267 if (state->CPExit[i])
761 (state->CPExit[i]) (state); 268 (state->CPExit[i]) (state);
762 269
763 for (i = 0; i < 16; i++) /* Detach all handlers. */ 270 for (i = 0; i < 16; i++) /* Detach all handlers. */
764 ARMul_CoProDetach (state, i); 271 ARMul_CoProDetach(state, i);
765} 272}
766 273
767/* Routines to hook Co-processors into ARMulator. */ 274/* Routines to hook Co-processors into ARMulator. */
768 275
769void 276void
770ARMul_CoProAttach (ARMul_State * state, 277ARMul_CoProAttach(ARMul_State * state,
771 unsigned number, 278unsigned number,
772 ARMul_CPInits * init, 279ARMul_CPInits * init,
773 ARMul_CPExits * exit, 280ARMul_CPExits * exit,
774 ARMul_LDCs * ldc, 281ARMul_LDCs * ldc,
775 ARMul_STCs * stc, 282ARMul_STCs * stc,
776 ARMul_MRCs * mrc, 283ARMul_MRCs * mrc,
777 ARMul_MCRs * mcr, 284ARMul_MCRs * mcr,
778 ARMul_MRRCs * mrrc, 285ARMul_MRRCs * mrrc,
779 ARMul_MCRRs * mcrr, 286ARMul_MCRRs * mcrr,
780 ARMul_CDPs * cdp, 287ARMul_CDPs * cdp,
781 ARMul_CPReads * read, ARMul_CPWrites * write) 288ARMul_CPReads * read, ARMul_CPWrites * write)
782{
783 if (init != NULL)
784 state->CPInit[number] = init;
785 if (exit != NULL)
786 state->CPExit[number] = exit;
787 if (ldc != NULL)
788 state->LDC[number] = ldc;
789 if (stc != NULL)
790 state->STC[number] = stc;
791 if (mrc != NULL)
792 state->MRC[number] = mrc;
793 if (mcr != NULL)
794 state->MCR[number] = mcr;
795 if (mrrc != NULL)
796 state->MRRC[number] = mrrc;
797 if (mcrr != NULL)
798 state->MCRR[number] = mcrr;
799 if (cdp != NULL)
800 state->CDP[number] = cdp;
801 if (read != NULL)
802 state->CPRead[number] = read;
803 if (write != NULL)
804 state->CPWrite[number] = write;
805}
806
807void
808ARMul_CoProDetach (ARMul_State * state, unsigned number)
809{ 289{
810 ARMul_CoProAttach (state, number, NULL, NULL, 290 if (init != NULL)
811 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, 291 state->CPInit[number] = init;
812 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL); 292 if (exit != NULL)
813 293 state->CPExit[number] = exit;
814 state->CPInit[number] = NULL; 294 if (ldc != NULL)
815 state->CPExit[number] = NULL; 295 state->LDC[number] = ldc;
816 state->CPRead[number] = NULL; 296 if (stc != NULL)
817 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;
818} 312}
819 313
820//chy 2003-09-03:below funs just replace the old ones
821
822/* Set the XScale FSR and FAR registers. */
823
824void 314void
825XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far) 315ARMul_CoProDetach(ARMul_State * state, unsigned number)
826{
827 //if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
828 if (!state->is_XScale)
829 return;
830 //assume opcode2=0 crm =0
831 xscale_cp15_write_reg (state, 5, fsr);
832 xscale_cp15_write_reg (state, 6, _far);
833}
834
835//chy 2003-09-03 seems 0 is CANT, 1 is DONE ????
836int
837XScale_debug_moe (ARMul_State * state, int moe)
838{ 316{
839 //chy 2003-09-03 , W/R CP14 reg, now it's no use ???? 317 ARMul_CoProAttach(state, number, NULL, NULL,
840 printf ("SKYEYE: XScale_debug_moe called !!!!\n"); 318 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
841 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;
842} 325}