summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armcopro.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-10-07 18:56:40 -0400
committerGravatar bunnei2014-10-25 14:11:41 -0400
commit818ba32746072af65a7b5ac0f1712bde3388f641 (patch)
treee11104887d1a680e3aa33bddc4ad3ca764ead696 /src/core/arm/interpreter/armcopro.cpp
parentARM: Removed unused armos code from SkyEye. (diff)
downloadyuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.gz
yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.tar.xz
yuzu-818ba32746072af65a7b5ac0f1712bde3388f641.zip
ARM: Removed unnecessary and unused SkyEye MMU code.
Added license header back in. I originally removed this because I mostly rewrote the file, but meh
Diffstat (limited to 'src/core/arm/interpreter/armcopro.cpp')
-rw-r--r--src/core/arm/interpreter/armcopro.cpp1000
1 files changed, 242 insertions, 758 deletions
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}