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 2 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, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 /* Dummy Co-processors. */
26 NoCoPro3R (ARMul_State
* state ATTRIBUTE_UNUSED
,
27 unsigned a ATTRIBUTE_UNUSED
,
28 ARMword b ATTRIBUTE_UNUSED
)
34 NoCoPro4R (ARMul_State
* state ATTRIBUTE_UNUSED
,
35 unsigned a ATTRIBUTE_UNUSED
,
36 ARMword b ATTRIBUTE_UNUSED
,
37 ARMword c ATTRIBUTE_UNUSED
)
43 NoCoPro4W (ARMul_State
* state ATTRIBUTE_UNUSED
,
44 unsigned a ATTRIBUTE_UNUSED
,
45 ARMword b ATTRIBUTE_UNUSED
,
46 ARMword
* c ATTRIBUTE_UNUSED
)
51 /* The XScale Co-processors. */
53 /* Coprocessor 15: System Control. */
54 static void write_cp14_reg (unsigned, ARMword
);
55 static ARMword
read_cp14_reg (unsigned);
57 /* There are two sets of registers for copro 15.
58 One set is available when opcode_2 is 0 and
59 the other set when opcode_2 >= 1. */
60 static ARMword XScale_cp15_opcode_2_is_0_Regs
[16];
61 static ARMword XScale_cp15_opcode_2_is_not_0_Regs
[16];
62 /* There are also a set of breakpoint registers
63 which are accessed via CRm instead of opcode_2. */
64 static ARMword XScale_cp15_DBR1
;
65 static ARMword XScale_cp15_DBCON
;
66 static ARMword XScale_cp15_IBCR0
;
67 static ARMword XScale_cp15_IBCR1
;
70 XScale_cp15_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
76 XScale_cp15_opcode_2_is_0_Regs
[i
] = 0;
77 XScale_cp15_opcode_2_is_not_0_Regs
[i
] = 0;
80 /* Initialise the processor ID. */
81 XScale_cp15_opcode_2_is_0_Regs
[0] = 0x69052000;
83 /* Initialise the cache type. */
84 XScale_cp15_opcode_2_is_not_0_Regs
[0] = 0x0B1AA1AA;
86 /* Initialise the ARM Control Register. */
87 XScale_cp15_opcode_2_is_0_Regs
[1] = 0x00000078;
91 /* Check an access to a register. */
94 check_cp15_access (ARMul_State
* state
,
100 /* Do not allow access to these register in USER mode. */
101 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
104 /* Opcode_1should be zero. */
108 /* Different register have different access requirements. */
113 /* CRm must be 0. Opcode_2 can be anything. */
119 /* CRm must be 0. Opcode_2 must be zero. */
120 if ((CRm
!= 0) || (opcode_2
!= 0))
124 /* Access not allowed. */
128 /* Opcode_2 must be zero. CRm must be 0. */
129 if ((CRm
!= 0) || (opcode_2
!= 0))
133 /* Permissable combinations:
146 default: return ARMul_CANT
;
147 case 6: if (CRm
!= 5) return ARMul_CANT
; break;
148 case 5: if (CRm
!= 2) return ARMul_CANT
; break;
149 case 4: if (CRm
!= 10) return ARMul_CANT
; break;
150 case 1: if ((CRm
!= 5) && (CRm
!= 6) && (CRm
!= 10)) return ARMul_CANT
; break;
151 case 0: if ((CRm
< 5) || (CRm
> 7)) return ARMul_CANT
; break;
156 /* Permissable combinations:
165 if ((CRm
< 5) || (CRm
> 7))
167 if (opcode_2
== 1 && CRm
== 7)
171 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
172 if ( ((CRm
!= 0) && (CRm
!= 1))
173 || ((opcode_2
!= 1) && (opcode_2
!= 2)))
177 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
178 if ( ((CRm
!= 0) && (CRm
!= 1))
179 || ((opcode_2
!= 4) && (opcode_2
!= 8)))
183 /* Access not allowed. */
186 /* Access not allowed. */
189 /* Opcode_2 must be zero. CRm must be 0. */
190 if ((CRm
!= 0) || (opcode_2
!= 0))
194 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
198 if ((CRm
!= 0) && (CRm
!= 3) && (CRm
!= 4) && (CRm
!= 8) && (CRm
!= 9))
202 /* Opcode_2 must be zero. CRm must be 1. */
203 if ((CRm
!= 1) || (opcode_2
!= 0))
207 /* Should never happen. */
214 /* Store a value into one of coprocessor 15's registers. */
217 write_cp15_reg (ARMul_State
* state
,
227 case 0: /* Cache Type. */
228 /* Writes are not allowed. */
231 case 1: /* Auxillary Control. */
232 /* Only BITS (5, 4) and BITS (1, 0) can be written. */
240 XScale_cp15_opcode_2_is_not_0_Regs
[reg
] = value
;
247 /* Writes are not allowed. */
250 case 1: /* ARM Control. */
251 /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.
252 BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one. */
256 /* Change the endianness if necessary */
257 if ((value
& ARMul_CP15_R1_ENDIAN
) !=
258 (XScale_cp15_opcode_2_is_0_Regs
[reg
] & ARMul_CP15_R1_ENDIAN
))
260 state
->bigendSig
= value
& ARMul_CP15_R1_ENDIAN
;
261 /* Force ARMulator to notice these now. */
262 state
->Emulate
= CHANGEMODE
;
266 case 2: /* Translation Table Base. */
267 /* Only BITS (31, 14) can be written. */
271 case 3: /* Domain Access Control. */
272 /* All bits writable. */
275 case 5: /* Fault Status Register. */
276 /* BITS (10, 9) and BITS (7, 0) can be written. */
280 case 6: /* Fault Address Register. */
281 /* All bits writable. */
284 case 7: /* Cache Functions. */
285 case 8: /* TLB Operations. */
286 case 10: /* TLB Lock Down. */
290 case 9: /* Data Cache Lock. */
291 /* Only BIT (0) can be written. */
295 case 13: /* Process ID. */
296 /* Only BITS (31, 25) are writable. */
300 case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */
301 /* All bits can be written. Which register is accessed is
302 dependent upon CRm. */
308 XScale_cp15_DBR1
= value
;
311 XScale_cp15_DBCON
= value
;
314 XScale_cp15_IBCR0
= value
;
317 XScale_cp15_IBCR1
= value
;
324 case 15: /* Coprpcessor Access Register. */
325 /* Access is only valid if CRm == 1. */
329 /* Only BITS (13, 0) may be written. */
337 XScale_cp15_opcode_2_is_0_Regs
[reg
] = value
;
343 /* Return the value in a cp15 register. */
346 read_cp15_reg (unsigned reg
, unsigned opcode_2
, unsigned CRm
)
350 if (reg
== 15 && CRm
!= 1)
357 case 3: return XScale_cp15_DBR1
;
358 case 4: return XScale_cp15_DBCON
;
359 case 8: return XScale_cp15_IBCR0
;
360 case 9: return XScale_cp15_IBCR1
;
366 return XScale_cp15_opcode_2_is_0_Regs
[reg
];
369 return XScale_cp15_opcode_2_is_not_0_Regs
[reg
];
375 XScale_cp15_LDC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword data
)
377 unsigned reg
= BITS (12, 15);
380 result
= check_cp15_access (state
, reg
, 0, 0, 0);
382 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
383 write_cp15_reg (state
, reg
, 0, 0, data
);
389 XScale_cp15_STC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword
* data
)
391 unsigned reg
= BITS (12, 15);
394 result
= check_cp15_access (state
, reg
, 0, 0, 0);
396 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
397 * data
= read_cp15_reg (reg
, 0, 0);
403 XScale_cp15_MRC (ARMul_State
* state
,
404 unsigned type ATTRIBUTE_UNUSED
,
408 unsigned opcode_2
= BITS (5, 7);
409 unsigned CRm
= BITS (0, 3);
410 unsigned reg
= BITS (16, 19);
413 result
= check_cp15_access (state
, reg
, CRm
, BITS (21, 23), opcode_2
);
415 if (result
== ARMul_DONE
)
416 * value
= read_cp15_reg (reg
, opcode_2
, CRm
);
422 XScale_cp15_MCR (ARMul_State
* state
,
423 unsigned type ATTRIBUTE_UNUSED
,
427 unsigned opcode_2
= BITS (5, 7);
428 unsigned CRm
= BITS (0, 3);
429 unsigned reg
= BITS (16, 19);
432 result
= check_cp15_access (state
, reg
, CRm
, BITS (21, 23), opcode_2
);
434 if (result
== ARMul_DONE
)
435 write_cp15_reg (state
, reg
, opcode_2
, CRm
, value
);
441 XScale_cp15_read_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
445 /* FIXME: Not sure what to do about the alternative register set
446 here. For now default to just accessing CRm == 0 registers. */
447 * value
= read_cp15_reg (reg
, 0, 0);
453 XScale_cp15_write_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
457 /* FIXME: Not sure what to do about the alternative register set
458 here. For now default to just accessing CRm == 0 registers. */
459 write_cp15_reg (state
, reg
, 0, 0, value
);
464 /* Check for special XScale memory access features. */
467 XScale_check_memacc (ARMul_State
* state
, ARMword
* address
, int store
)
469 ARMword dbcon
, r0
, r1
;
472 if (!state
->is_XScale
)
475 /* Check for PID-ification.
476 XXX BTB access support will require this test failing. */
477 r0
= (read_cp15_reg (13, 0, 0) & 0xfe000000);
478 if (r0
&& (*address
& 0xfe000000) == 0)
481 /* Check alignment fault enable/disable. */
482 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
) && (*address
& 3))
483 ARMul_Abort (state
, ARMul_DataAbortV
);
485 if (XScale_debug_moe (state
, -1))
488 /* Check the data breakpoint registers. */
489 dbcon
= read_cp15_reg (14, 0, 4);
490 r0
= read_cp15_reg (14, 0, 0);
491 r1
= read_cp15_reg (14, 0, 3);
492 e0
= dbcon
& ARMul_CP15_DBCON_E0
;
494 if (dbcon
& ARMul_CP15_DBCON_M
)
496 /* r1 is a inverse mask. */
497 if (e0
!= 0 && ((store
&& e0
!= 3) || (!store
&& e0
!= 1))
498 && ((*address
& ~r1
) == (r0
& ~r1
)))
500 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
501 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
506 if (e0
!= 0 && ((store
&& e0
!= 3) || (!store
&& e0
!= 1))
507 && ((*address
& ~3) == (r0
& ~3)))
509 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
510 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
513 e1
= (dbcon
& ARMul_CP15_DBCON_E1
) >> 2;
514 if (e1
!= 0 && ((store
&& e1
!= 3) || (!store
&& e1
!= 1))
515 && ((*address
& ~3) == (r1
& ~3)))
517 XScale_debug_moe (state
, ARMul_CP14_R10_MOE_DB
);
518 ARMul_OSHandleSWI (state
, SWI_Breakpoint
);
526 XScale_set_fsr_far (ARMul_State
* state
, ARMword fsr
, ARMword far
)
528 if (!state
->is_XScale
|| (read_cp14_reg (10) & (1UL << 31)) == 0)
531 write_cp15_reg (state
, 5, 0, 0, fsr
);
532 write_cp15_reg (state
, 6, 0, 0, far
);
535 /* Set the XScale debug `method of entry' if it is enabled. */
538 XScale_debug_moe (ARMul_State
* state
, int moe
)
542 if (!state
->is_XScale
)
545 value
= read_cp14_reg (10);
546 if (value
& (1UL << 31))
553 write_cp14_reg (10, value
);
560 /* Coprocessor 13: Interrupt Controller and Bus Controller. */
562 /* There are two sets of registers for copro 13.
563 One set (of three registers) is available when CRm is 0
564 and the other set (of six registers) when CRm is 1. */
566 static ARMword XScale_cp13_CR0_Regs
[16];
567 static ARMword XScale_cp13_CR1_Regs
[16];
570 XScale_cp13_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
576 XScale_cp13_CR0_Regs
[i
] = 0;
577 XScale_cp13_CR1_Regs
[i
] = 0;
581 /* Check an access to a register. */
584 check_cp13_access (ARMul_State
* state
,
590 /* Do not allow access to these register in USER mode. */
591 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
594 /* The opcodes should be zero. */
595 if ((opcode_1
!= 0) || (opcode_2
!= 0))
598 /* Do not allow access to these register if bit
599 13 of coprocessor 15's register 15 is zero. */
600 if (! CP_ACCESS_ALLOWED (state
, 13))
603 /* Registers 0, 4 and 8 are defined when CRm == 0.
604 Registers 0, 4, 5, 6, 7, 8 are defined when CRm == 1.
605 For all other CRm values undefined behaviour results. */
608 if (reg
== 0 || reg
== 4 || reg
== 8)
613 if (reg
== 0 || (reg
>= 4 && reg
<= 8))
620 /* Store a value into one of coprocessor 13's registers. */
623 write_cp13_reg (unsigned reg
, unsigned CRm
, ARMword value
)
631 /* Only BITS (3:0) can be written. */
636 /* No bits may be written. */
640 /* Only BITS (1:0) can be written. */
645 /* Should not happen. Ignore any writes to unimplemented registers. */
649 XScale_cp13_CR0_Regs
[reg
] = value
;
656 /* Only BITS (30:28) and BITS (3:0) can be written.
657 BIT(31) is write ignored. */
659 value
|= XScale_cp13_CR1_Regs
[0] & (1UL << 31);
666 /* No bits can be written. */
670 /* Only BITS (7:0) can be written. */
675 /* Should not happen. Ignore any writes to unimplemented registers. */
679 XScale_cp13_CR1_Regs
[reg
] = value
;
683 /* Should not happen. */
690 /* Return the value in a cp13 register. */
693 read_cp13_reg (unsigned reg
, unsigned CRm
)
696 return XScale_cp13_CR0_Regs
[reg
];
698 return XScale_cp13_CR1_Regs
[reg
];
704 XScale_cp13_LDC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword data
)
706 unsigned reg
= BITS (12, 15);
709 result
= check_cp13_access (state
, reg
, 0, 0, 0);
711 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
712 write_cp13_reg (reg
, 0, data
);
718 XScale_cp13_STC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword
* data
)
720 unsigned reg
= BITS (12, 15);
723 result
= check_cp13_access (state
, reg
, 0, 0, 0);
725 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
726 * data
= read_cp13_reg (reg
, 0);
732 XScale_cp13_MRC (ARMul_State
* state
,
733 unsigned type ATTRIBUTE_UNUSED
,
737 unsigned CRm
= BITS (0, 3);
738 unsigned reg
= BITS (16, 19);
741 result
= check_cp13_access (state
, reg
, CRm
, BITS (21, 23), BITS (5, 7));
743 if (result
== ARMul_DONE
)
744 * value
= read_cp13_reg (reg
, CRm
);
750 XScale_cp13_MCR (ARMul_State
* state
,
751 unsigned type ATTRIBUTE_UNUSED
,
755 unsigned CRm
= BITS (0, 3);
756 unsigned reg
= BITS (16, 19);
759 result
= check_cp13_access (state
, reg
, CRm
, BITS (21, 23), BITS (5, 7));
761 if (result
== ARMul_DONE
)
762 write_cp13_reg (reg
, CRm
, value
);
768 XScale_cp13_read_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
772 /* FIXME: Not sure what to do about the alternative register set
773 here. For now default to just accessing CRm == 0 registers. */
774 * value
= read_cp13_reg (reg
, 0);
780 XScale_cp13_write_reg (ARMul_State
* state ATTRIBUTE_UNUSED
,
784 /* FIXME: Not sure what to do about the alternative register set
785 here. For now default to just accessing CRm == 0 registers. */
786 write_cp13_reg (reg
, 0, value
);
791 /* Coprocessor 14: Performance Monitoring, Clock and Power management,
794 static ARMword XScale_cp14_Regs
[16];
797 XScale_cp14_init (ARMul_State
* state ATTRIBUTE_UNUSED
)
802 XScale_cp14_Regs
[i
] = 0;
805 /* Check an access to a register. */
808 check_cp14_access (ARMul_State
* state
,
814 /* Not allowed to access these register in USER mode. */
815 if (state
->Mode
== USER26MODE
|| state
->Mode
== USER32MODE
)
818 /* CRm should be zero. */
822 /* OPcodes should be zero. */
823 if (opcode1
!= 0 || opcode2
!= 0)
826 /* Accessing registers 4 or 5 has unpredicatable results. */
827 if (reg
>= 4 && reg
<= 5)
833 /* Store a value into one of coprocessor 14's registers. */
836 write_cp14_reg (unsigned reg
, ARMword value
)
841 /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */
844 /* Reset the clock counter if necessary */
845 if (value
& ARMul_CP14_R0_CLKRST
)
846 XScale_cp14_Regs
[1] = 0;
851 /* We should not normally reach this code. The debugger interface
852 can bypass the normal checks though, so it could happen. */
856 case 6: /* CCLKCFG */
857 /* Only BITS (3:0) can be written. */
861 case 7: /* PWRMODE */
862 /* Although BITS (1:0) can be written with non-zero values, this would
863 have the side effect of putting the processor to sleep. Thus in
864 order for the register to be read again, it would have to go into
865 ACTIVE mode, which means that any read will see these bits as zero.
867 Rather than trying to implement complex reset-to-zero-upon-read logic
868 we just override the write value with zero. */
873 /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
879 /* No writes are permitted. */
883 case 14: /* TXRXCTRL */
884 /* Only BITS (31:30) can be written. */
889 /* All bits can be written. */
893 XScale_cp14_Regs
[reg
] = value
;
896 /* Return the value in a cp14 register. Not a static function since
897 it is used by the code to emulate the BKPT instruction in armemu.c. */
900 read_cp14_reg (unsigned reg
)
902 return XScale_cp14_Regs
[reg
];
906 XScale_cp14_LDC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword data
)
908 unsigned reg
= BITS (12, 15);
911 result
= check_cp14_access (state
, reg
, 0, 0, 0);
913 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
914 write_cp14_reg (reg
, data
);
920 XScale_cp14_STC (ARMul_State
* state
, unsigned type
, ARMword instr
, ARMword
* data
)
922 unsigned reg
= BITS (12, 15);
925 result
= check_cp14_access (state
, reg
, 0, 0, 0);
927 if (result
== ARMul_DONE
&& type
== ARMul_DATA
)
928 * data
= read_cp14_reg (reg
);
937 unsigned type ATTRIBUTE_UNUSED
,
942 unsigned reg
= BITS (16, 19);
945 result
= check_cp14_access (state
, reg
, BITS (0, 3), BITS (21, 23), BITS (5, 7));
947 if (result
== ARMul_DONE
)
948 * value
= read_cp14_reg (reg
);
957 unsigned type ATTRIBUTE_UNUSED
,
962 unsigned reg
= BITS (16, 19);
965 result
= check_cp14_access (state
, reg
, BITS (0, 3), BITS (21, 23), BITS (5, 7));
967 if (result
== ARMul_DONE
)
968 write_cp14_reg (reg
, value
);
976 ARMul_State
* state ATTRIBUTE_UNUSED
,
981 * value
= read_cp14_reg (reg
);
987 XScale_cp14_write_reg
989 ARMul_State
* state ATTRIBUTE_UNUSED
,
994 write_cp14_reg (reg
, value
);
999 /* Here's ARMulator's MMU definition. A few things to note:
1000 1) It has eight registers, but only two are defined.
1001 2) You can only access its registers with MCR and MRC.
1002 3) MMU Register 0 (ID) returns 0x41440110
1003 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
1004 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
1005 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
1007 static ARMword MMUReg
[8];
1010 MMUInit (ARMul_State
* state
)
1012 MMUReg
[1] = state
->prog32Sig
<< 4 |
1013 state
->data32Sig
<< 5 | state
->lateabtSig
<< 6 | state
->bigendSig
<< 7;
1015 ARMul_ConsolePrint (state
, ", MMU present");
1021 MMUMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1022 unsigned type ATTRIBUTE_UNUSED
,
1026 int reg
= BITS (16, 19) & 7;
1029 *value
= 0x41440110;
1031 *value
= MMUReg
[reg
];
1037 MMUMCR (ARMul_State
* state
,
1038 unsigned type ATTRIBUTE_UNUSED
,
1042 int reg
= BITS (16, 19) & 7;
1044 MMUReg
[reg
] = value
;
1050 p
= state
->prog32Sig
;
1051 d
= state
->data32Sig
;
1052 l
= state
->lateabtSig
;
1053 b
= state
->bigendSig
;
1055 state
->prog32Sig
= value
>> 4 & 1;
1056 state
->data32Sig
= value
>> 5 & 1;
1057 state
->lateabtSig
= value
>> 6 & 1;
1058 state
->bigendSig
= value
>> 7 & 1;
1060 if ( p
!= state
->prog32Sig
1061 || d
!= state
->data32Sig
1062 || l
!= state
->lateabtSig
1063 || b
!= state
->bigendSig
)
1064 /* Force ARMulator to notice these now. */
1065 state
->Emulate
= CHANGEMODE
;
1072 MMURead (ARMul_State
* state ATTRIBUTE_UNUSED
, unsigned reg
, ARMword
* value
)
1075 *value
= 0x41440110;
1077 *value
= MMUReg
[reg
];
1083 MMUWrite (ARMul_State
* state
, unsigned reg
, ARMword value
)
1086 MMUReg
[reg
] = value
;
1092 p
= state
->prog32Sig
;
1093 d
= state
->data32Sig
;
1094 l
= state
->lateabtSig
;
1095 b
= state
->bigendSig
;
1097 state
->prog32Sig
= value
>> 4 & 1;
1098 state
->data32Sig
= value
>> 5 & 1;
1099 state
->lateabtSig
= value
>> 6 & 1;
1100 state
->bigendSig
= value
>> 7 & 1;
1102 if ( p
!= state
->prog32Sig
1103 || d
!= state
->data32Sig
1104 || l
!= state
->lateabtSig
1105 || b
!= state
->bigendSig
)
1106 /* Force ARMulator to notice these now. */
1107 state
->Emulate
= CHANGEMODE
;
1114 /* What follows is the Validation Suite Coprocessor. It uses two
1115 co-processor numbers (4 and 5) and has the follwing functionality.
1116 Sixteen registers. Both co-processor nuimbers can be used in an MCR
1117 and MRC to access these registers. CP 4 can LDC and STC to and from
1118 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
1119 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
1120 number of cycles (specified in a CP register), CDP 2 issues an IRQW
1121 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1122 stores a 32 bit time value in a CP register (actually it's the total
1123 number of N, S, I, C and F cyles). */
1125 static ARMword ValReg
[16];
1128 ValLDC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1133 static unsigned words
;
1135 if (type
!= ARMul_DATA
)
1139 ValReg
[BITS (12, 15)] = data
;
1142 /* It's a long access, get two words. */
1151 ValSTC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1156 static unsigned words
;
1158 if (type
!= ARMul_DATA
)
1162 * data
= ValReg
[BITS (12, 15)];
1165 /* It's a long access, get two words. */
1174 ValMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
1175 unsigned type ATTRIBUTE_UNUSED
,
1179 *value
= ValReg
[BITS (16, 19)];
1185 ValMCR (ARMul_State
* state ATTRIBUTE_UNUSED
,
1186 unsigned type ATTRIBUTE_UNUSED
,
1190 ValReg
[BITS (16, 19)] = value
;
1196 ValCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
1198 static unsigned long finish
= 0;
1200 if (BITS (20, 23) != 0)
1203 if (type
== ARMul_FIRST
)
1207 howlong
= ValReg
[BITS (0, 3)];
1209 /* First cycle of a busy wait. */
1210 finish
= ARMul_Time (state
) + howlong
;
1212 return howlong
== 0 ? ARMul_DONE
: ARMul_BUSY
;
1214 else if (type
== ARMul_BUSY
)
1216 if (ARMul_Time (state
) >= finish
)
1226 DoAFIQ (ARMul_State
* state
)
1228 state
->NfiqSig
= LOW
;
1234 DoAIRQ (ARMul_State
* state
)
1236 state
->NirqSig
= LOW
;
1242 IntCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
1244 static unsigned long finish
;
1247 howlong
= ValReg
[BITS (0, 3)];
1249 switch ((int) BITS (20, 23))
1252 if (type
== ARMul_FIRST
)
1254 /* First cycle of a busy wait. */
1255 finish
= ARMul_Time (state
) + howlong
;
1257 return howlong
== 0 ? ARMul_DONE
: ARMul_BUSY
;
1259 else if (type
== ARMul_BUSY
)
1261 if (ARMul_Time (state
) >= finish
)
1270 ARMul_Abort (state
, ARMul_FIQV
);
1272 ARMul_ScheduleEvent (state
, howlong
, DoAFIQ
);
1277 ARMul_Abort (state
, ARMul_IRQV
);
1279 ARMul_ScheduleEvent (state
, howlong
, DoAIRQ
);
1283 state
->NfiqSig
= HIGH
;
1288 state
->NirqSig
= HIGH
;
1293 ValReg
[BITS (0, 3)] = ARMul_Time (state
);
1300 /* Install co-processor instruction handlers in this routine. */
1303 ARMul_CoProInit (ARMul_State
* state
)
1307 /* Initialise tham all first. */
1308 for (i
= 0; i
< 16; i
++)
1309 ARMul_CoProDetach (state
, i
);
1311 /* Install CoPro Instruction handlers here.
1313 ARMul_CoProAttach (state, CP Number,
1314 Init routine, Exit routine
1315 LDC routine, STC routine,
1316 MRC routine, MCR routine,
1318 Read Reg routine, Write Reg routine). */
1319 ARMul_CoProAttach (state
, 4, NULL
, NULL
,
1320 ValLDC
, ValSTC
, ValMRC
, ValMCR
, ValCDP
, NULL
, NULL
);
1322 ARMul_CoProAttach (state
, 5, NULL
, NULL
,
1323 NULL
, NULL
, ValMRC
, ValMCR
, IntCDP
, NULL
, NULL
);
1325 ARMul_CoProAttach (state
, 15, MMUInit
, NULL
,
1326 NULL
, NULL
, MMUMRC
, MMUMCR
, NULL
, MMURead
, MMUWrite
);
1328 ARMul_CoProAttach (state
, 13, XScale_cp13_init
, NULL
,
1329 XScale_cp13_LDC
, XScale_cp13_STC
, XScale_cp13_MRC
,
1330 XScale_cp13_MCR
, NULL
, XScale_cp13_read_reg
,
1331 XScale_cp13_write_reg
);
1333 ARMul_CoProAttach (state
, 14, XScale_cp14_init
, NULL
,
1334 XScale_cp14_LDC
, XScale_cp14_STC
, XScale_cp14_MRC
,
1335 XScale_cp14_MCR
, NULL
, XScale_cp14_read_reg
,
1336 XScale_cp14_write_reg
);
1338 ARMul_CoProAttach (state
, 15, XScale_cp15_init
, NULL
,
1339 NULL
, NULL
, XScale_cp15_MRC
, XScale_cp15_MCR
,
1340 NULL
, XScale_cp15_read_reg
, XScale_cp15_write_reg
);
1342 /* No handlers below here. */
1344 /* Call all the initialisation routines. */
1345 for (i
= 0; i
< 16; i
++)
1346 if (state
->CPInit
[i
])
1347 (state
->CPInit
[i
]) (state
);
1352 /* Install co-processor finalisation routines in this routine. */
1355 ARMul_CoProExit (ARMul_State
* state
)
1357 register unsigned i
;
1359 for (i
= 0; i
< 16; i
++)
1360 if (state
->CPExit
[i
])
1361 (state
->CPExit
[i
]) (state
);
1363 for (i
= 0; i
< 16; i
++) /* Detach all handlers. */
1364 ARMul_CoProDetach (state
, i
);
1367 /* Routines to hook Co-processors into ARMulator. */
1370 ARMul_CoProAttach (ARMul_State
* state
,
1372 ARMul_CPInits
* init
,
1373 ARMul_CPExits
* exit
,
1379 ARMul_CPReads
* read
,
1380 ARMul_CPWrites
* write
)
1383 state
->CPInit
[number
] = init
;
1385 state
->CPExit
[number
] = exit
;
1387 state
->LDC
[number
] = ldc
;
1389 state
->STC
[number
] = stc
;
1391 state
->MRC
[number
] = mrc
;
1393 state
->MCR
[number
] = mcr
;
1395 state
->CDP
[number
] = cdp
;
1397 state
->CPRead
[number
] = read
;
1399 state
->CPWrite
[number
] = write
;
1403 ARMul_CoProDetach (ARMul_State
* state
, unsigned number
)
1405 ARMul_CoProAttach (state
, number
, NULL
, NULL
,
1406 NoCoPro4R
, NoCoPro4W
, NoCoPro4W
, NoCoPro4R
,
1407 NoCoPro3R
, NULL
, NULL
);
1409 state
->CPInit
[number
] = NULL
;
1410 state
->CPExit
[number
] = NULL
;
1411 state
->CPRead
[number
] = NULL
;
1412 state
->CPWrite
[number
] = NULL
;