summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armcopro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter/armcopro.cpp')
-rw-r--r--src/core/arm/interpreter/armcopro.cpp842
1 files changed, 842 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp
new file mode 100644
index 000000000..6a75e6601
--- /dev/null
+++ b/src/core/arm/interpreter/armcopro.cpp
@@ -0,0 +1,842 @@
1/* armcopro.c -- co-processor interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994, 2000 Advanced RISC Machines Ltd.
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#include "core/arm/interpreter/armdefs.h"
20#include "core/arm/interpreter/armos.h"
21#include "core/arm/interpreter/armemu.h"
22#include "core/arm/interpreter/vfp/vfp.h"
23
24//chy 2005-07-08
25//#include "ansidecl.h"
26//chy -------
27//#include "iwmmxt.h"
28
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. */
87
88static unsigned
89NoCoPro3R (ARMul_State * state,
90 unsigned a, ARMword b)
91{
92 return ARMul_CANT;
93}
94
95static unsigned
96NoCoPro4R (ARMul_State * state,
97 unsigned a,
98 ARMword b, ARMword c)
99{
100 return ARMul_CANT;
101}
102
103static unsigned
104NoCoPro4W (ARMul_State * state,
105 unsigned a,
106 ARMword b, ARMword * c)
107{
108 return ARMul_CANT;
109}
110
111static unsigned
112NoCoPro5R (ARMul_State * state,
113 unsigned a,
114 ARMword b,
115 ARMword c, ARMword d)
116{
117 return ARMul_CANT;
118}
119
120static unsigned
121NoCoPro5W (ARMul_State * state,
122 unsigned a,
123 ARMword b,
124 ARMword * c, ARMword * d )
125{
126 return ARMul_CANT;
127}
128
129/* The XScale Co-processors. */
130
131/* Coprocessor 15: System Control. */
132static void write_cp14_reg (unsigned, ARMword);
133static 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
382/* Check an access to a register. */
383
384static unsigned
385check_cp14_access (ARMul_State * state,
386 unsigned reg,
387 unsigned CRm, unsigned opcode1, unsigned opcode2)
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{
598 static unsigned int finish;
599 ARMword howlong;
600
601 howlong = ValReg[BITS (0, 3)];
602
603 switch ((int) BITS (20, 23)) {
604 case 0:
605 if (type == ARMul_FIRST) {
606 /* First cycle of a busy wait. */
607 finish = ARMul_Time (state) + howlong;
608
609 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
610 }
611 else if (type == ARMul_BUSY) {
612 if (ARMul_Time (state) >= finish)
613 return ARMul_DONE;
614 else
615 return ARMul_BUSY;
616 }
617 return ARMul_DONE;
618
619 case 1:
620 if (howlong == 0)
621 ARMul_Abort (state, ARMul_FIQV);
622 else
623 ARMul_ScheduleEvent (state, howlong, DoAFIQ);
624 return ARMul_DONE;
625
626 case 2:
627 if (howlong == 0)
628 ARMul_Abort (state, ARMul_IRQV);
629 else
630 ARMul_ScheduleEvent (state, howlong, DoAIRQ);
631 return ARMul_DONE;
632
633 case 3:
634 state->NfiqSig = HIGH;
635 return ARMul_DONE;
636
637 case 4:
638 state->NirqSig = HIGH;
639 return ARMul_DONE;
640
641 case 5:
642 ValReg[BITS (0, 3)] = ARMul_Time (state);
643 return ARMul_DONE;
644 }
645
646 return ARMul_CANT;
647}
648
649/* Install co-processor instruction handlers in this routine. */
650
651unsigned
652ARMul_CoProInit (ARMul_State * state)
653{
654 unsigned int i;
655
656 /* Initialise tham all first. */
657 for (i = 0; i < 16; i++)
658 ARMul_CoProDetach (state, i);
659
660 /* Install CoPro Instruction handlers here.
661 The format is:
662 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
663 LDC routine, STC routine, MRC routine, MCR routine,
664 CDP routine, Read Reg routine, Write Reg routine). */
665 if (state->is_ep9312) {
666 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4,
667 DSPMRC4, DSPMCR4, NULL, NULL, DSPCDP4, NULL, NULL);
668 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5,
669 DSPMRC5, DSPMCR5, NULL, NULL, DSPCDP5, NULL, NULL);
670 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL,
671 DSPMRC6, DSPMCR6, NULL, NULL, DSPCDP6, NULL, NULL);
672 }
673 else {
674 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC,
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
726 if (state->is_iWMMXt) {
727 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
728 NULL, NULL, IwmmxtCDP, NULL, NULL);
729
730 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
731 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL,
732 NULL);
733 }
734#endif
735 //-----------------------------------------------------------------------------
736 //chy 2004-05-25, found the user/system code visit CP 1,2, so I add below code.
737 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
738 ValMRC, ValMCR, NULL, NULL, NULL, NULL, NULL);
739 ARMul_CoProAttach (state, 2, NULL, NULL, ValLDC, ValSTC,
740 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
741 //------------------------------------------------------------------------------
742 /* No handlers below here. */
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}
751
752/* Install co-processor finalisation routines in this routine. */
753
754void
755ARMul_CoProExit (ARMul_State * state)
756{
757 register unsigned i;
758
759 for (i = 0; i < 16; i++)
760 if (state->CPExit[i])
761 (state->CPExit[i]) (state);
762
763 for (i = 0; i < 16; i++) /* Detach all handlers. */
764 ARMul_CoProDetach (state, i);
765}
766
767/* Routines to hook Co-processors into ARMulator. */
768
769void
770ARMul_CoProAttach (ARMul_State * state,
771 unsigned number,
772 ARMul_CPInits * init,
773 ARMul_CPExits * exit,
774 ARMul_LDCs * ldc,
775 ARMul_STCs * stc,
776 ARMul_MRCs * mrc,
777 ARMul_MCRs * mcr,
778 ARMul_MRRCs * mrrc,
779 ARMul_MCRRs * mcrr,
780 ARMul_CDPs * cdp,
781 ARMul_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{
810 ARMul_CoProAttach (state, number, NULL, NULL,
811 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
812 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL);
813
814 state->CPInit[number] = NULL;
815 state->CPExit[number] = NULL;
816 state->CPRead[number] = NULL;
817 state->CPWrite[number] = NULL;
818}
819
820//chy 2003-09-03:below funs just replace the old ones
821
822/* Set the XScale FSR and FAR registers. */
823
824void
825XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far)
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{
839 //chy 2003-09-03 , W/R CP14 reg, now it's no use ????
840 printf ("SKYEYE: XScale_debug_moe called !!!!\n");
841 return 1;
842}