1 /* armcopro.c -- co-processor interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994, 2000 Advanced RISC Machines Ltd.
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /* This must come before any other includes. */
26 /* Dummy Co-processors. */
29 NoCoPro3R (ARMul_State
* state ATTRIBUTE_UNUSED
,
30 unsigned a ATTRIBUTE_UNUSED
,
31 ARMword b ATTRIBUTE_UNUSED
)
37 NoCoPro4R (ARMul_State
* state ATTRIBUTE_UNUSED
,
38 unsigned a ATTRIBUTE_UNUSED
,
39 ARMword b ATTRIBUTE_UNUSED
,
40 ARMword c ATTRIBUTE_UNUSED
)
46 NoCoPro4W (ARMul_State
* state ATTRIBUTE_UNUSED
,
47 unsigned a ATTRIBUTE_UNUSED
,
48 ARMword b ATTRIBUTE_UNUSED
,
49 ARMword
* c ATTRIBUTE_UNUSED
)
54 /* The XScale Co-processors. */
56 /* Coprocessor 15: System Control. */
57 static void write_cp14_reg (unsigned, ARMword
);
58 static ARMword
read_cp14_reg (unsigned);
60 /* There are two sets of registers for copro 15.
61 One set is available when opcode_2 is 0 and
62 the other set when opcode_2 >= 1. */
63 static ARMword XScale_cp15_opcode_2_is_0_Regs
[16];
64 static ARMword XScale_cp15_opcode_2_is_not_0_Regs
[16];
65 /* There are also a set of breakpoint registers
66 which are accessed via CRm instead of opcode_2. */
67 static ARMword XScale_cp15_DBR1
;
68 static ARMword XScale_cp15_DBCON
;
69 static ARMword XScale_cp15_IBCR0
;
70 static ARMword XScale_cp15_IBCR1
;
73 XScale_cp15_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
79 XScale_cp15_opcode_2_is_0_Regs
[i
] = 0;
80 XScale_cp15_opcode_2_is_not_0_Regs
[i
] = 0;
83 /* Initialise the processor ID. */
84 XScale_cp15_opcode_2_is_0_Regs
[0] = 0x69052000;
86 /* Initialise the cache type. */
87 XScale_cp15_opcode_2_is_not_0_Regs
[0] = 0x0B1AA1AA;
89 /* Initialise the ARM Control Register. */
90 XScale_cp15_opcode_2_is_0_Regs
[1] = 0x00000078;
95 /* Check an access to a register. */
98 check_cp15_access (ARMul_State
* state
,
104 /* Do not allow access to these register in USER mode. */
105 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
108 /* Opcode_1should be zero. */
112 /* Different register have different access requirements. */
117 /* CRm must be 0. Opcode_2 can be anything. */
123 /* CRm must be 0. Opcode_2 must be zero. */
124 if ((CRm
!= 0) || (opcode_2
!= 0))
128 /* Access not allowed. */
132 /* Opcode_2 must be zero. CRm must be 0. */
133 if ((CRm
!= 0) || (opcode_2
!= 0))
137 /* Permissable combinations:
150 default: return ARMul_CANT
;
151 case 6: if (CRm
!= 5) return ARMul_CANT
; break;
152 case 5: if (CRm
!= 2) return ARMul_CANT
; break;
153 case 4: if (CRm
!= 10) return ARMul_CANT
; break;
154 case 1: if ((CRm
!= 5) && (CRm
!= 6) && (CRm
!= 10)) return ARMul_CANT
; break;
155 case 0: if ((CRm
< 5) || (CRm
> 7)) return ARMul_CANT
; break;
160 /* Permissable combinations:
169 if ((CRm
< 5) || (CRm
> 7))
171 if (opcode_2
== 1 && CRm
== 7)
175 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
176 if ( ((CRm
!= 0) && (CRm
!= 1))
177 || ((opcode_2
!= 1) && (opcode_2
!= 2)))
181 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
182 if ( ((CRm
!= 0) && (CRm
!= 1))
183 || ((opcode_2
!= 4) && (opcode_2
!= 8)))
187 /* Access not allowed. */
190 /* Access not allowed. */
193 /* Opcode_2 must be zero. CRm must be 0. */
194 if ((CRm
!= 0) || (opcode_2
!= 0))
198 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
202 if ((CRm
!= 0) && (CRm
!= 3) && (CRm
!= 4) && (CRm
!= 8) && (CRm
!= 9))
206 /* Opcode_2 must be zero. CRm must be 1. */
207 if ((CRm
!= 1) || (opcode_2
!= 0))
211 /* Should never happen. */
218 /* Store a value into one of coprocessor 15's registers. */
221 write_cp15_reg (ARMul_State
* state
,
231 case 0: /* Cache Type. */
232 /* Writes are not allowed. */
235 case 1: /* Auxillary Control. */
236 /* Only BITS (5, 4) and BITS (1, 0) can be written. */
244 XScale_cp15_opcode_2_is_not_0_Regs
[reg
] = value
;
251 /* Writes are not allowed. */
254 case 1: /* ARM Control. */
255 /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.
256 BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one. */
260 /* Change the endianness if necessary. */
261 if ((value
& ARMul_CP15_R1_ENDIAN
) !=
262 (XScale_cp15_opcode_2_is_0_Regs
[reg
] & ARMul_CP15_R1_ENDIAN
))
264 state
->bigendSig
= value
& ARMul_CP15_R1_ENDIAN
;
265 /* Force ARMulator to notice these now. */
266 state
->Emulate
= CHANGEMODE
;
270 case 2: /* Translation Table Base. */
271 /* Only BITS (31, 14) can be written. */
275 case 3: /* Domain Access Control. */
276 /* All bits writable. */
279 case 5: /* Fault Status Register. */
280 /* BITS (10, 9) and BITS (7, 0) can be written. */
284 case 6: /* Fault Address Register. */
285 /* All bits writable. */
288 case 7: /* Cache Functions. */
289 case 8: /* TLB Operations. */
290 case 10: /* TLB Lock Down. */
294 case 9: /* Data Cache Lock. */
295 /* Only BIT (0) can be written. */
299 case 13: /* Process ID. */
300 /* Only BITS (31, 25) are writable. */
304 case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */
305 /* All bits can be written. Which register is accessed is
306 dependent upon CRm. */
312 XScale_cp15_DBR1
= value
;
315 XScale_cp15_DBCON
= value
;
318 XScale_cp15_IBCR0
= value
;
321 XScale_cp15_IBCR1
= value
;
328 case 15: /* Coprpcessor Access Register. */
329 /* Access is only valid if CRm == 1. */
333 /* Only BITS (13, 0) may be written. */
341 XScale_cp15_opcode_2_is_0_Regs
[reg
] = value
;
347 /* Return the value in a cp15 register. */
350 read_cp15_reg (unsigned reg
, unsigned opcode_2
, unsigned CRm
)
354 if (reg
== 15 && CRm
!= 1)
361 case 3: return XScale_cp15_DBR1
;
362 case 4: return XScale_cp15_DBCON
;
363 case 8: return XScale_cp15_IBCR0
;
364 case 9: return XScale_cp15_IBCR1
;
370 return XScale_cp15_opcode_2_is_0_Regs
[reg
];
373 return XScale_cp15_opcode_2_is_not_0_Regs
[reg
];
379 XScale_cp15_MRC (ARMul_State
* state
,
380 unsigned type ATTRIBUTE_UNUSED
,
384 unsigned opcode_2
= BITS (5, 7);
385 unsigned CRm
= BITS (0, 3);
386 unsigned reg
= BITS (16, 19);
389 result
= check_cp15_access (state
, reg
, CRm
, BITS (21, 23), opcode_2
);
391 if (result
== ARMul_DONE
)
392 * value
= read_cp15_reg (reg
, opcode_2
, CRm
);
398 XScale_cp15_MCR (ARMul_State
* state
,
399 unsigned type ATTRIBUTE_UNUSED
,
403 unsigned opcode_2
= BITS (5, 7);
404 unsigned CRm
= BITS (0, 3);
405 unsigned reg
= BITS (16, 19);
408 result
= check_cp15_access (state
, reg
, CRm
, BITS (21, 23), opcode_2
);
410 if (result
== ARMul_DONE
)
411 write_cp15_reg (state
, reg
, opcode_2
, CRm
, value
);
417 XScale_cp15_read_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
421 /* FIXME: Not sure what to do about the alternative register set
422 here. For now default to just accessing CRm == 0 registers. */
423 * value
= read_cp15_reg (reg
, 0, 0);
429 XScale_cp15_write_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
433 /* FIXME: Not sure what to do about the alternative register set
434 here. For now default to just accessing CRm == 0 registers. */
435 write_cp15_reg (state
, reg
, 0, 0, value
);
440 /* Check for special XScale memory access features. */
443 XScale_check_memacc (ARMul_State
* state
, ARMword
* address
, int store
)
445 ARMword dbcon
, r0
, r1
;
448 if (!state
->is_XScale
)
451 /* Check for PID-ification.
452 XXX BTB access support will require this test failing. */
453 r0
= (read_cp15_reg (13, 0, 0) & 0xfe000000);
454 if (r0
&& (* address
& 0xfe000000) == 0)
457 /* Check alignment fault enable/disable. */
458 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
) && (* address
& 3))
460 /* Set the FSR and FAR.
461 Do not use XScale_set_fsr_far as this checks the DCSR register. */
462 write_cp15_reg (state
, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT
);
463 write_cp15_reg (state
, 6, 0, 0, * address
);
465 ARMul_Abort (state
, ARMul_DataAbortV
);
468 if (XScale_debug_moe (state
, -1))
471 /* Check the data breakpoint registers. */
472 dbcon
= read_cp15_reg (14, 0, 4);
473 r0
= read_cp15_reg (14, 0, 0);
474 r1
= read_cp15_reg (14, 0, 3);
475 e0
= dbcon
& ARMul_CP15_DBCON_E0
;
477 if (dbcon
& ARMul_CP15_DBCON_M
)
479 /* r1 is a inverse mask. */
480 if (e0
!= 0 && ((store
&& e0
!= 3) || (!store
&& e0
!= 1))
481 && ((* address
& ~r1
) == (r0
& ~r1
)))
483 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
484 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
489 if (e0
!= 0 && ((store
&& e0
!= 3) || (!store
&& e0
!= 1))
490 && ((* address
& ~3) == (r0
& ~3)))
492 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
493 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
496 e1
= (dbcon
& ARMul_CP15_DBCON_E1
) >> 2;
497 if (e1
!= 0 && ((store
&& e1
!= 3) || (!store
&& e1
!= 1))
498 && ((* address
& ~3) == (r1
& ~3)))
500 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
501 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
506 /* Set the XScale FSR and FAR registers. */
509 XScale_set_fsr_far (ARMul_State
* state
, ARMword fsr
, ARMword far
)
511 if (!state
->is_XScale
|| (read_cp14_reg (10) & (1UL << 31)) == 0)
514 write_cp15_reg (state
, 5, 0, 0, fsr
);
515 write_cp15_reg (state
, 6, 0, 0, far
);
518 /* Set the XScale debug `method of entry' if it is enabled. */
521 XScale_debug_moe (ARMul_State
* state
, int moe
)
525 if (!state
->is_XScale
)
528 value
= read_cp14_reg (10);
529 if (value
& (1UL << 31))
536 write_cp14_reg (10, value
);
543 /* Coprocessor 13: Interrupt Controller and Bus Controller. */
545 /* There are two sets of registers for copro 13.
546 One set (of three registers) is available when CRm is 0
547 and the other set (of six registers) when CRm is 1. */
549 static ARMword XScale_cp13_CR0_Regs
[16];
550 static ARMword XScale_cp13_CR1_Regs
[16];
553 XScale_cp13_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
559 XScale_cp13_CR0_Regs
[i
] = 0;
560 XScale_cp13_CR1_Regs
[i
] = 0;
566 /* Check an access to a register. */
569 check_cp13_access (ARMul_State
* state
,
575 /* Do not allow access to these registers in USER mode. */
576 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
579 /* The opcodes should be zero. */
580 if ((opcode_1
!= 0) || (opcode_2
!= 0))
583 /* Do not allow access to these register if bit
584 13 of coprocessor 15's register 15 is zero. */
585 if (! CP_ACCESS_ALLOWED (state
, 13))
588 /* Registers 0, 4 and 8 are defined when CRm == 0.
589 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
590 For all other CRm values undefined behaviour results. */
593 if (reg
== 0 || reg
== 4 || reg
== 8)
598 if (reg
== 0 || reg
== 1 || (reg
>= 4 && reg
<= 8))
605 /* Store a value into one of coprocessor 13's registers. */
608 write_cp13_reg (unsigned reg
, unsigned CRm
, ARMword value
)
616 /* Only BITS (3:0) can be written. */
621 /* No bits may be written. */
625 /* Only BITS (1:0) can be written. */
630 /* Should not happen. Ignore any writes to unimplemented registers. */
634 XScale_cp13_CR0_Regs
[reg
] = value
;
641 /* Only BITS (30:28) and BITS (3:0) can be written.
642 BIT(31) is write ignored. */
644 value
|= XScale_cp13_CR1_Regs
[0] & (1UL << 31);
648 /* Only bit 0 is accecssible. */
650 value
|= XScale_cp13_CR1_Regs
[1] & ~ 1;
657 /* No bits can be written. */
661 /* Only BITS (7:0) can be written. */
666 /* Should not happen. Ignore any writes to unimplemented registers. */
670 XScale_cp13_CR1_Regs
[reg
] = value
;
674 /* Should not happen. */
681 /* Return the value in a cp13 register. */
684 read_cp13_reg (unsigned reg
, unsigned CRm
)
687 return XScale_cp13_CR0_Regs
[reg
];
689 return XScale_cp13_CR1_Regs
[reg
];
695 XScale_cp13_LDC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword data
)
697 unsigned reg
= BITS (12, 15);
700 result
= check_cp13_access (state
, reg
, 0, 0, 0);
702 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
703 write_cp13_reg (reg
, 0, data
);
709 XScale_cp13_STC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword
* data
)
711 unsigned reg
= BITS (12, 15);
714 result
= check_cp13_access (state
, reg
, 0, 0, 0);
716 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
717 * data
= read_cp13_reg (reg
, 0);
723 XScale_cp13_MRC (ARMul_State
* state
,
724 unsigned type ATTRIBUTE_UNUSED
,
728 unsigned CRm
= BITS (0, 3);
729 unsigned reg
= BITS (16, 19);
732 result
= check_cp13_access (state
, reg
, CRm
, BITS (21, 23), BITS (5, 7));
734 if (result
== ARMul_DONE
)
735 * value
= read_cp13_reg (reg
, CRm
);
741 XScale_cp13_MCR (ARMul_State
* state
,
742 unsigned type ATTRIBUTE_UNUSED
,
746 unsigned CRm
= BITS (0, 3);
747 unsigned reg
= BITS (16, 19);
750 result
= check_cp13_access (state
, reg
, CRm
, BITS (21, 23), BITS (5, 7));
752 if (result
== ARMul_DONE
)
753 write_cp13_reg (reg
, CRm
, value
);
759 XScale_cp13_read_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
763 /* FIXME: Not sure what to do about the alternative register set
764 here. For now default to just accessing CRm == 0 registers. */
765 * value
= read_cp13_reg (reg
, 0);
771 XScale_cp13_write_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
775 /* FIXME: Not sure what to do about the alternative register set
776 here. For now default to just accessing CRm == 0 registers. */
777 write_cp13_reg (reg
, 0, value
);
782 /* Coprocessor 14: Performance Monitoring, Clock and Power management,
785 static ARMword XScale_cp14_Regs
[16];
788 XScale_cp14_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
793 XScale_cp14_Regs
[i
] = 0;
798 /* Check an access to a register. */
801 check_cp14_access (ARMul_State
* state
,
807 /* Not allowed to access these register in USER mode. */
808 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
811 /* CRm should be zero. */
815 /* OPcodes should be zero. */
816 if (opcode1
!= 0 || opcode2
!= 0)
819 /* Accessing registers 4 or 5 has unpredicatable results. */
820 if (reg
>= 4 && reg
<= 5)
826 /* Store a value into one of coprocessor 14's registers. */
829 write_cp14_reg (unsigned reg
, ARMword value
)
834 /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */
837 /* Reset the clock counter if necessary. */
838 if (value
& ARMul_CP14_R0_CLKRST
)
839 XScale_cp14_Regs
[1] = 0;
844 /* We should not normally reach this code. The debugger interface
845 can bypass the normal checks though, so it could happen. */
849 case 6: /* CCLKCFG */
850 /* Only BITS (3:0) can be written. */
854 case 7: /* PWRMODE */
855 /* Although BITS (1:0) can be written with non-zero values, this would
856 have the side effect of putting the processor to sleep. Thus in
857 order for the register to be read again, it would have to go into
858 ACTIVE mode, which means that any read will see these bits as zero.
860 Rather than trying to implement complex reset-to-zero-upon-read logic
861 we just override the write value with zero. */
866 /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
872 /* No writes are permitted. */
876 case 14: /* TXRXCTRL */
877 /* Only BITS (31:30) can be written. */
882 /* All bits can be written. */
886 XScale_cp14_Regs
[reg
] = value
;
889 /* Return the value in a cp14 register. Not a static function since
890 it is used by the code to emulate the BKPT instruction in armemu.c. */
893 read_cp14_reg (unsigned reg
)
895 return XScale_cp14_Regs
[reg
];
899 XScale_cp14_LDC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword data
)
901 unsigned reg
= BITS (12, 15);
904 result
= check_cp14_access (state
, reg
, 0, 0, 0);
906 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
907 write_cp14_reg (reg
, data
);
913 XScale_cp14_STC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword
* data
)
915 unsigned reg
= BITS (12, 15);
918 result
= check_cp14_access (state
, reg
, 0, 0, 0);
920 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
921 * data
= read_cp14_reg (reg
);
930 unsigned type ATTRIBUTE_UNUSED
,
935 unsigned reg
= BITS (16, 19);
938 result
= check_cp14_access (state
, reg
, BITS (0, 3), BITS (21, 23), BITS (5, 7));
940 if (result
== ARMul_DONE
)
941 * value
= read_cp14_reg (reg
);
950 unsigned type ATTRIBUTE_UNUSED
,
955 unsigned reg
= BITS (16, 19);
958 result
= check_cp14_access (state
, reg
, BITS (0, 3), BITS (21, 23), BITS (5, 7));
960 if (result
== ARMul_DONE
)
961 write_cp14_reg (reg
, value
);
969 ARMul_State
* state ATTRIBUTE_UNUSED
,
974 * value
= read_cp14_reg (reg
);
980 XScale_cp14_write_reg
982 ARMul_State
* state ATTRIBUTE_UNUSED
,
987 write_cp14_reg (reg
, value
);
992 /* Here's ARMulator's MMU definition. A few things to note:
993 1) It has eight registers, but only two are defined.
994 2) You can only access its registers with MCR and MRC.
995 3) MMU Register 0 (ID) returns 0x41440110
996 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
997 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
998 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
1000 static ARMword MMUReg
[8];
1003 MMUInit (ARMul_State
* state
)
1005 MMUReg
[1] = state
->prog32Sig
<< 4 |
1006 state
->data32Sig
<< 5 | state
->lateabtSig
<< 6 | state
->bigendSig
<< 7;
1008 ARMul_ConsolePrint (state
, ", MMU present");
1014 MMUMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1015 unsigned type ATTRIBUTE_UNUSED
,
1019 int reg
= BITS (16, 19) & 7;
1022 *value
= 0x41440110;
1024 *value
= MMUReg
[reg
];
1030 MMUMCR (ARMul_State
* state
,
1031 unsigned type ATTRIBUTE_UNUSED
,
1035 int reg
= BITS (16, 19) & 7;
1037 MMUReg
[reg
] = value
;
1043 p
= state
->prog32Sig
;
1044 d
= state
->data32Sig
;
1045 l
= state
->lateabtSig
;
1046 b
= state
->bigendSig
;
1048 state
->prog32Sig
= value
>> 4 & 1;
1049 state
->data32Sig
= value
>> 5 & 1;
1050 state
->lateabtSig
= value
>> 6 & 1;
1051 state
->bigendSig
= value
>> 7 & 1;
1053 if ( p
!= state
->prog32Sig
1054 || d
!= state
->data32Sig
1055 || l
!= state
->lateabtSig
1056 || b
!= state
->bigendSig
)
1057 /* Force ARMulator to notice these now. */
1058 state
->Emulate
= CHANGEMODE
;
1065 MMURead (ARMul_State
* state ATTRIBUTE_UNUSED
, unsigned reg
, ARMword
* value
)
1068 *value
= 0x41440110;
1070 *value
= MMUReg
[reg
];
1076 MMUWrite (ARMul_State
* state
, unsigned reg
, ARMword value
)
1079 MMUReg
[reg
] = value
;
1085 p
= state
->prog32Sig
;
1086 d
= state
->data32Sig
;
1087 l
= state
->lateabtSig
;
1088 b
= state
->bigendSig
;
1090 state
->prog32Sig
= value
>> 4 & 1;
1091 state
->data32Sig
= value
>> 5 & 1;
1092 state
->lateabtSig
= value
>> 6 & 1;
1093 state
->bigendSig
= value
>> 7 & 1;
1095 if ( p
!= state
->prog32Sig
1096 || d
!= state
->data32Sig
1097 || l
!= state
->lateabtSig
1098 || b
!= state
->bigendSig
)
1099 /* Force ARMulator to notice these now. */
1100 state
->Emulate
= CHANGEMODE
;
1107 /* What follows is the Validation Suite Coprocessor. It uses two
1108 co-processor numbers (4 and 5) and has the follwing functionality.
1109 Sixteen registers. Both co-processor nuimbers can be used in an MCR
1110 and MRC to access these registers. CP 4 can LDC and STC to and from
1111 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
1112 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
1113 number of cycles (specified in a CP register), CDP 2 issues an IRQW
1114 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1115 stores a 32 bit time value in a CP register (actually it's the total
1116 number of N, S, I, C and F cyles). */
1118 static ARMword ValReg
[16];
1121 ValLDC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1126 static unsigned words
;
1128 if (type
!= ARMul_DATA
)
1132 ValReg
[BITS (12, 15)] = data
;
1135 /* It's a long access, get two words. */
1144 ValSTC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1149 static unsigned words
;
1151 if (type
!= ARMul_DATA
)
1155 * data
= ValReg
[BITS (12, 15)];
1158 /* It's a long access, get two words. */
1167 ValMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1168 unsigned type ATTRIBUTE_UNUSED
,
1172 *value
= ValReg
[BITS (16, 19)];
1178 ValMCR (ARMul_State
* state ATTRIBUTE_UNUSED
,
1179 unsigned type ATTRIBUTE_UNUSED
,
1183 ValReg
[BITS (16, 19)] = value
;
1189 ValCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
1191 static unsigned long finish
= 0;
1193 if (BITS (20, 23) != 0)
1196 if (type
== ARMul_FIRST
)
1200 howlong
= ValReg
[BITS (0, 3)];
1202 /* First cycle of a busy wait. */
1203 finish
= ARMul_Time (state
) + howlong
;
1205 return howlong
== 0 ? ARMul_DONE
: ARMul_BUSY
;
1207 else if (type
== ARMul_BUSY
)
1209 if (ARMul_Time (state
) >= finish
)
1219 DoAFIQ (ARMul_State
* state
)
1221 state
->NfiqSig
= LOW
;
1227 DoAIRQ (ARMul_State
* state
)
1229 state
->NirqSig
= LOW
;
1235 IntCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
1237 static unsigned long finish
;
1240 howlong
= ValReg
[BITS (0, 3)];
1242 switch ((int) BITS (20, 23))
1245 if (type
== ARMul_FIRST
)
1247 /* First cycle of a busy wait. */
1248 finish
= ARMul_Time (state
) + howlong
;
1250 return howlong
== 0 ? ARMul_DONE
: ARMul_BUSY
;
1252 else if (type
== ARMul_BUSY
)
1254 if (ARMul_Time (state
) >= finish
)
1263 ARMul_Abort (state
, ARMul_FIQV
);
1265 ARMul_ScheduleEvent (state
, howlong
, DoAFIQ
);
1270 ARMul_Abort (state
, ARMul_IRQV
);
1272 ARMul_ScheduleEvent (state
, howlong
, DoAIRQ
);
1276 state
->NfiqSig
= HIGH
;
1281 state
->NirqSig
= HIGH
;
1286 ValReg
[BITS (0, 3)] = ARMul_Time (state
);
1293 /* Install co-processor instruction handlers in this routine. */
1296 ARMul_CoProInit (ARMul_State
* state
)
1300 /* Initialise tham all first. */
1301 for (i
= 0; i
< 16; i
++)
1302 ARMul_CoProDetach (state
, i
);
1304 /* Install CoPro Instruction handlers here.
1306 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
1307 LDC routine, STC routine, MRC routine, MCR routine,
1308 CDP routine, Read Reg routine, Write Reg routine). */
1309 if (state
->is_ep9312
)
1311 ARMul_CoProAttach (state
, 4, NULL
, NULL
, DSPLDC4
, DSPSTC4
,
1312 DSPMRC4
, DSPMCR4
, DSPCDP4
, NULL
, NULL
);
1313 ARMul_CoProAttach (state
, 5, NULL
, NULL
, DSPLDC5
, DSPSTC5
,
1314 DSPMRC5
, DSPMCR5
, DSPCDP5
, NULL
, NULL
);
1315 ARMul_CoProAttach (state
, 6, NULL
, NULL
, NULL
, NULL
,
1316 DSPMRC6
, DSPMCR6
, DSPCDP6
, NULL
, NULL
);
1320 ARMul_CoProAttach (state
, 4, NULL
, NULL
, ValLDC
, ValSTC
,
1321 ValMRC
, ValMCR
, ValCDP
, NULL
, NULL
);
1323 ARMul_CoProAttach (state
, 5, NULL
, NULL
, NULL
, NULL
,
1324 ValMRC
, ValMCR
, IntCDP
, NULL
, NULL
);
1327 if (state
->is_XScale
)
1329 ARMul_CoProAttach (state
, 13, XScale_cp13_init
, NULL
,
1330 XScale_cp13_LDC
, XScale_cp13_STC
, XScale_cp13_MRC
,
1331 XScale_cp13_MCR
, NULL
, XScale_cp13_read_reg
,
1332 XScale_cp13_write_reg
);
1334 ARMul_CoProAttach (state
, 14, XScale_cp14_init
, NULL
,
1335 XScale_cp14_LDC
, XScale_cp14_STC
, XScale_cp14_MRC
,
1336 XScale_cp14_MCR
, NULL
, XScale_cp14_read_reg
,
1337 XScale_cp14_write_reg
);
1339 ARMul_CoProAttach (state
, 15, XScale_cp15_init
, NULL
,
1340 NULL
, NULL
, XScale_cp15_MRC
, XScale_cp15_MCR
,
1341 NULL
, XScale_cp15_read_reg
, XScale_cp15_write_reg
);
1345 ARMul_CoProAttach (state
, 15, MMUInit
, NULL
, NULL
, NULL
,
1346 MMUMRC
, MMUMCR
, NULL
, MMURead
, MMUWrite
);
1349 if (state
->is_iWMMXt
)
1351 ARMul_CoProAttach (state
, 0, NULL
, NULL
, IwmmxtLDC
, IwmmxtSTC
,
1352 NULL
, NULL
, IwmmxtCDP
, NULL
, NULL
);
1354 ARMul_CoProAttach (state
, 1, NULL
, NULL
, NULL
, NULL
,
1355 IwmmxtMRC
, IwmmxtMCR
, IwmmxtCDP
, NULL
, NULL
);
1358 /* No handlers below here. */
1360 /* Call all the initialisation routines. */
1361 for (i
= 0; i
< 16; i
++)
1362 if (state
->CPInit
[i
])
1363 (state
->CPInit
[i
]) (state
);
1368 /* Install co-processor finalisation routines in this routine. */
1371 ARMul_CoProExit (ARMul_State
* state
)
1373 register unsigned i
;
1375 for (i
= 0; i
< 16; i
++)
1376 if (state
->CPExit
[i
])
1377 (state
->CPExit
[i
]) (state
);
1379 for (i
= 0; i
< 16; i
++) /* Detach all handlers. */
1380 ARMul_CoProDetach (state
, i
);
1383 /* Routines to hook Co-processors into ARMulator. */
1386 ARMul_CoProAttach (ARMul_State
* state
,
1388 ARMul_CPInits
* init
,
1389 ARMul_CPExits
* exit
,
1395 ARMul_CPReads
* read
,
1396 ARMul_CPWrites
* write
)
1399 state
->CPInit
[number
] = init
;
1401 state
->CPExit
[number
] = exit
;
1403 state
->LDC
[number
] = ldc
;
1405 state
->STC
[number
] = stc
;
1407 state
->MRC
[number
] = mrc
;
1409 state
->MCR
[number
] = mcr
;
1411 state
->CDP
[number
] = cdp
;
1413 state
->CPRead
[number
] = read
;
1415 state
->CPWrite
[number
] = write
;
1419 ARMul_CoProDetach (ARMul_State
* state
, unsigned number
)
1421 ARMul_CoProAttach (state
, number
, NULL
, NULL
,
1422 NoCoPro4R
, NoCoPro4W
, NoCoPro4W
, NoCoPro4R
,
1423 NoCoPro3R
, NULL
, NULL
);
1425 state
->CPInit
[number
] = NULL
;
1426 state
->CPExit
[number
] = NULL
;
1427 state
->CPRead
[number
] = NULL
;
1428 state
->CPWrite
[number
] = NULL
;