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/>. */
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;
92 /* Check an access to a register. */
95 check_cp15_access (ARMul_State * state,
101 /* Do not allow access to these register in USER mode. */
102 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
105 /* Opcode_1should be zero. */
109 /* Different register have different access requirements. */
114 /* CRm must be 0. Opcode_2 can be anything. */
120 /* CRm must be 0. Opcode_2 must be zero. */
121 if ((CRm != 0) || (opcode_2 != 0))
125 /* Access not allowed. */
129 /* Opcode_2 must be zero. CRm must be 0. */
130 if ((CRm != 0) || (opcode_2 != 0))
134 /* Permissable combinations:
147 default: return ARMul_CANT;
148 case 6: if (CRm != 5) return ARMul_CANT; break;
149 case 5: if (CRm != 2) return ARMul_CANT; break;
150 case 4: if (CRm != 10) return ARMul_CANT; break;
151 case 1: if ((CRm != 5) && (CRm != 6) && (CRm != 10)) return ARMul_CANT; break;
152 case 0: if ((CRm < 5) || (CRm > 7)) return ARMul_CANT; break;
157 /* Permissable combinations:
166 if ((CRm < 5) || (CRm > 7))
168 if (opcode_2 == 1 && CRm == 7)
172 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
173 if ( ((CRm != 0) && (CRm != 1))
174 || ((opcode_2 != 1) && (opcode_2 != 2)))
178 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
179 if ( ((CRm != 0) && (CRm != 1))
180 || ((opcode_2 != 4) && (opcode_2 != 8)))
184 /* Access not allowed. */
187 /* Access not allowed. */
190 /* Opcode_2 must be zero. CRm must be 0. */
191 if ((CRm != 0) || (opcode_2 != 0))
195 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
199 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) && (CRm != 9))
203 /* Opcode_2 must be zero. CRm must be 1. */
204 if ((CRm != 1) || (opcode_2 != 0))
208 /* Should never happen. */
215 /* Store a value into one of coprocessor 15's registers. */
218 write_cp15_reg (ARMul_State * state,
228 case 0: /* Cache Type. */
229 /* Writes are not allowed. */
232 case 1: /* Auxillary Control. */
233 /* Only BITS (5, 4) and BITS (1, 0) can be written. */
241 XScale_cp15_opcode_2_is_not_0_Regs [reg] = value;
248 /* Writes are not allowed. */
251 case 1: /* ARM Control. */
252 /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.
253 BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one. */
257 /* Change the endianness if necessary. */
258 if ((value & ARMul_CP15_R1_ENDIAN) !=
259 (XScale_cp15_opcode_2_is_0_Regs [reg] & ARMul_CP15_R1_ENDIAN))
261 state->bigendSig = value & ARMul_CP15_R1_ENDIAN;
262 /* Force ARMulator to notice these now. */
263 state->Emulate = CHANGEMODE;
267 case 2: /* Translation Table Base. */
268 /* Only BITS (31, 14) can be written. */
272 case 3: /* Domain Access Control. */
273 /* All bits writable. */
276 case 5: /* Fault Status Register. */
277 /* BITS (10, 9) and BITS (7, 0) can be written. */
281 case 6: /* Fault Address Register. */
282 /* All bits writable. */
285 case 7: /* Cache Functions. */
286 case 8: /* TLB Operations. */
287 case 10: /* TLB Lock Down. */
291 case 9: /* Data Cache Lock. */
292 /* Only BIT (0) can be written. */
296 case 13: /* Process ID. */
297 /* Only BITS (31, 25) are writable. */
301 case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */
302 /* All bits can be written. Which register is accessed is
303 dependent upon CRm. */
309 XScale_cp15_DBR1 = value;
312 XScale_cp15_DBCON = value;
315 XScale_cp15_IBCR0 = value;
318 XScale_cp15_IBCR1 = value;
325 case 15: /* Coprpcessor Access Register. */
326 /* Access is only valid if CRm == 1. */
330 /* Only BITS (13, 0) may be written. */
338 XScale_cp15_opcode_2_is_0_Regs [reg] = value;
344 /* Return the value in a cp15 register. */
347 read_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm)
351 if (reg == 15 && CRm != 1)
358 case 3: return XScale_cp15_DBR1;
359 case 4: return XScale_cp15_DBCON;
360 case 8: return XScale_cp15_IBCR0;
361 case 9: return XScale_cp15_IBCR1;
367 return XScale_cp15_opcode_2_is_0_Regs [reg];
370 return XScale_cp15_opcode_2_is_not_0_Regs [reg];
376 XScale_cp15_MRC (ARMul_State * state,
377 unsigned type ATTRIBUTE_UNUSED,
381 unsigned opcode_2 = BITS (5, 7);
382 unsigned CRm = BITS (0, 3);
383 unsigned reg = BITS (16, 19);
386 result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
388 if (result == ARMul_DONE)
389 * value = read_cp15_reg (reg, opcode_2, CRm);
395 XScale_cp15_MCR (ARMul_State * state,
396 unsigned type ATTRIBUTE_UNUSED,
400 unsigned opcode_2 = BITS (5, 7);
401 unsigned CRm = BITS (0, 3);
402 unsigned reg = BITS (16, 19);
405 result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
407 if (result == ARMul_DONE)
408 write_cp15_reg (state, reg, opcode_2, CRm, value);
414 XScale_cp15_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
418 /* FIXME: Not sure what to do about the alternative register set
419 here. For now default to just accessing CRm == 0 registers. */
420 * value = read_cp15_reg (reg, 0, 0);
426 XScale_cp15_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,
430 /* FIXME: Not sure what to do about the alternative register set
431 here. For now default to just accessing CRm == 0 registers. */
432 write_cp15_reg (state, reg, 0, 0, value);
437 /* Check for special XScale memory access features. */
440 XScale_check_memacc (ARMul_State * state, ARMword * address, int store)
442 ARMword dbcon, r0, r1;
445 if (!state->is_XScale)
448 /* Check for PID-ification.
449 XXX BTB access support will require this test failing. */
450 r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000);
451 if (r0 && (* address & 0xfe000000) == 0)
454 /* Check alignment fault enable/disable. */
455 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3))
457 /* Set the FSR and FAR.
458 Do not use XScale_set_fsr_far as this checks the DCSR register. */
459 write_cp15_reg (state, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT);
460 write_cp15_reg (state, 6, 0, 0, * address);
462 ARMul_Abort (state, ARMul_DataAbortV);
465 if (XScale_debug_moe (state, -1))
468 /* Check the data breakpoint registers. */
469 dbcon = read_cp15_reg (14, 0, 4);
470 r0 = read_cp15_reg (14, 0, 0);
471 r1 = read_cp15_reg (14, 0, 3);
472 e0 = dbcon & ARMul_CP15_DBCON_E0;
474 if (dbcon & ARMul_CP15_DBCON_M)
476 /* r1 is a inverse mask. */
477 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
478 && ((* address & ~r1) == (r0 & ~r1)))
480 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
481 ARMul_OSHandleSWI (state, SWI_Breakpoint);
486 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
487 && ((* address & ~3) == (r0 & ~3)))
489 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
490 ARMul_OSHandleSWI (state, SWI_Breakpoint);
493 e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2;
494 if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1))
495 && ((* address & ~3) == (r1 & ~3)))
497 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
498 ARMul_OSHandleSWI (state, SWI_Breakpoint);
503 /* Set the XScale FSR and FAR registers. */
506 XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far)
508 if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
511 write_cp15_reg (state, 5, 0, 0, fsr);
512 write_cp15_reg (state, 6, 0, 0, far);
515 /* Set the XScale debug `method of entry' if it is enabled. */
518 XScale_debug_moe (ARMul_State * state, int moe)
522 if (!state->is_XScale)
525 value = read_cp14_reg (10);
526 if (value & (1UL << 31))
533 write_cp14_reg (10, value);
540 /* Coprocessor 13: Interrupt Controller and Bus Controller. */
542 /* There are two sets of registers for copro 13.
543 One set (of three registers) is available when CRm is 0
544 and the other set (of six registers) when CRm is 1. */
546 static ARMword XScale_cp13_CR0_Regs[16];
547 static ARMword XScale_cp13_CR1_Regs[16];
550 XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED)
556 XScale_cp13_CR0_Regs[i] = 0;
557 XScale_cp13_CR1_Regs[i] = 0;
563 /* Check an access to a register. */
566 check_cp13_access (ARMul_State * state,
572 /* Do not allow access to these registers in USER mode. */
573 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
576 /* The opcodes should be zero. */
577 if ((opcode_1 != 0) || (opcode_2 != 0))
580 /* Do not allow access to these register if bit
581 13 of coprocessor 15's register 15 is zero. */
582 if (! CP_ACCESS_ALLOWED (state, 13))
585 /* Registers 0, 4 and 8 are defined when CRm == 0.
586 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
587 For all other CRm values undefined behaviour results. */
590 if (reg == 0 || reg == 4 || reg == 8)
595 if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
602 /* Store a value into one of coprocessor 13's registers. */
605 write_cp13_reg (unsigned reg, unsigned CRm, ARMword value)
613 /* Only BITS (3:0) can be written. */
618 /* No bits may be written. */
622 /* Only BITS (1:0) can be written. */
627 /* Should not happen. Ignore any writes to unimplemented registers. */
631 XScale_cp13_CR0_Regs [reg] = value;
638 /* Only BITS (30:28) and BITS (3:0) can be written.
639 BIT(31) is write ignored. */
641 value |= XScale_cp13_CR1_Regs[0] & (1UL << 31);
645 /* Only bit 0 is accecssible. */
647 value |= XScale_cp13_CR1_Regs[1] & ~ 1;
654 /* No bits can be written. */
658 /* Only BITS (7:0) can be written. */
663 /* Should not happen. Ignore any writes to unimplemented registers. */
667 XScale_cp13_CR1_Regs [reg] = value;
671 /* Should not happen. */
678 /* Return the value in a cp13 register. */
681 read_cp13_reg (unsigned reg, unsigned CRm)
684 return XScale_cp13_CR0_Regs [reg];
686 return XScale_cp13_CR1_Regs [reg];
692 XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
694 unsigned reg = BITS (12, 15);
697 result = check_cp13_access (state, reg, 0, 0, 0);
699 if (result == ARMul_DONE && type == ARMul_DATA)
700 write_cp13_reg (reg, 0, data);
706 XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
708 unsigned reg = BITS (12, 15);
711 result = check_cp13_access (state, reg, 0, 0, 0);
713 if (result == ARMul_DONE && type == ARMul_DATA)
714 * data = read_cp13_reg (reg, 0);
720 XScale_cp13_MRC (ARMul_State * state,
721 unsigned type ATTRIBUTE_UNUSED,
725 unsigned CRm = BITS (0, 3);
726 unsigned reg = BITS (16, 19);
729 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
731 if (result == ARMul_DONE)
732 * value = read_cp13_reg (reg, CRm);
738 XScale_cp13_MCR (ARMul_State * state,
739 unsigned type ATTRIBUTE_UNUSED,
743 unsigned CRm = BITS (0, 3);
744 unsigned reg = BITS (16, 19);
747 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
749 if (result == ARMul_DONE)
750 write_cp13_reg (reg, CRm, value);
756 XScale_cp13_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
760 /* FIXME: Not sure what to do about the alternative register set
761 here. For now default to just accessing CRm == 0 registers. */
762 * value = read_cp13_reg (reg, 0);
768 XScale_cp13_write_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 write_cp13_reg (reg, 0, value);
779 /* Coprocessor 14: Performance Monitoring, Clock and Power management,
782 static ARMword XScale_cp14_Regs[16];
785 XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED)
790 XScale_cp14_Regs[i] = 0;
795 /* Check an access to a register. */
798 check_cp14_access (ARMul_State * state,
804 /* Not allowed to access these register in USER mode. */
805 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
808 /* CRm should be zero. */
812 /* OPcodes should be zero. */
813 if (opcode1 != 0 || opcode2 != 0)
816 /* Accessing registers 4 or 5 has unpredicatable results. */
817 if (reg >= 4 && reg <= 5)
823 /* Store a value into one of coprocessor 14's registers. */
826 write_cp14_reg (unsigned reg, ARMword value)
831 /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */
834 /* Reset the clock counter if necessary. */
835 if (value & ARMul_CP14_R0_CLKRST)
836 XScale_cp14_Regs [1] = 0;
841 /* We should not normally reach this code. The debugger interface
842 can bypass the normal checks though, so it could happen. */
846 case 6: /* CCLKCFG */
847 /* Only BITS (3:0) can be written. */
851 case 7: /* PWRMODE */
852 /* Although BITS (1:0) can be written with non-zero values, this would
853 have the side effect of putting the processor to sleep. Thus in
854 order for the register to be read again, it would have to go into
855 ACTIVE mode, which means that any read will see these bits as zero.
857 Rather than trying to implement complex reset-to-zero-upon-read logic
858 we just override the write value with zero. */
863 /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
869 /* No writes are permitted. */
873 case 14: /* TXRXCTRL */
874 /* Only BITS (31:30) can be written. */
879 /* All bits can be written. */
883 XScale_cp14_Regs [reg] = value;
886 /* Return the value in a cp14 register. Not a static function since
887 it is used by the code to emulate the BKPT instruction in armemu.c. */
890 read_cp14_reg (unsigned reg)
892 return XScale_cp14_Regs [reg];
896 XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
898 unsigned reg = BITS (12, 15);
901 result = check_cp14_access (state, reg, 0, 0, 0);
903 if (result == ARMul_DONE && type == ARMul_DATA)
904 write_cp14_reg (reg, data);
910 XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
912 unsigned reg = BITS (12, 15);
915 result = check_cp14_access (state, reg, 0, 0, 0);
917 if (result == ARMul_DONE && type == ARMul_DATA)
918 * data = read_cp14_reg (reg);
927 unsigned type ATTRIBUTE_UNUSED,
932 unsigned reg = BITS (16, 19);
935 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
937 if (result == ARMul_DONE)
938 * value = read_cp14_reg (reg);
947 unsigned type ATTRIBUTE_UNUSED,
952 unsigned reg = BITS (16, 19);
955 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
957 if (result == ARMul_DONE)
958 write_cp14_reg (reg, value);
966 ARMul_State * state ATTRIBUTE_UNUSED,
971 * value = read_cp14_reg (reg);
977 XScale_cp14_write_reg
979 ARMul_State * state ATTRIBUTE_UNUSED,
984 write_cp14_reg (reg, value);
989 /* Here's ARMulator's MMU definition. A few things to note:
990 1) It has eight registers, but only two are defined.
991 2) You can only access its registers with MCR and MRC.
992 3) MMU Register 0 (ID) returns 0x41440110
993 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
994 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
995 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
997 static ARMword MMUReg[8];
1000 MMUInit (ARMul_State * state)
1002 MMUReg[1] = state->prog32Sig << 4 |
1003 state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
1005 ARMul_ConsolePrint (state, ", MMU present");
1011 MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1012 unsigned type ATTRIBUTE_UNUSED,
1016 int reg = BITS (16, 19) & 7;
1019 *value = 0x41440110;
1021 *value = MMUReg[reg];
1027 MMUMCR (ARMul_State * state,
1028 unsigned type ATTRIBUTE_UNUSED,
1032 int reg = BITS (16, 19) & 7;
1034 MMUReg[reg] = value;
1040 p = state->prog32Sig;
1041 d = state->data32Sig;
1042 l = state->lateabtSig;
1043 b = state->bigendSig;
1045 state->prog32Sig = value >> 4 & 1;
1046 state->data32Sig = value >> 5 & 1;
1047 state->lateabtSig = value >> 6 & 1;
1048 state->bigendSig = value >> 7 & 1;
1050 if ( p != state->prog32Sig
1051 || d != state->data32Sig
1052 || l != state->lateabtSig
1053 || b != state->bigendSig)
1054 /* Force ARMulator to notice these now. */
1055 state->Emulate = CHANGEMODE;
1062 MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value)
1065 *value = 0x41440110;
1067 *value = MMUReg[reg];
1073 MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
1076 MMUReg[reg] = value;
1082 p = state->prog32Sig;
1083 d = state->data32Sig;
1084 l = state->lateabtSig;
1085 b = state->bigendSig;
1087 state->prog32Sig = value >> 4 & 1;
1088 state->data32Sig = value >> 5 & 1;
1089 state->lateabtSig = value >> 6 & 1;
1090 state->bigendSig = value >> 7 & 1;
1092 if ( p != state->prog32Sig
1093 || d != state->data32Sig
1094 || l != state->lateabtSig
1095 || b != state->bigendSig)
1096 /* Force ARMulator to notice these now. */
1097 state->Emulate = CHANGEMODE;
1104 /* What follows is the Validation Suite Coprocessor. It uses two
1105 co-processor numbers (4 and 5) and has the follwing functionality.
1106 Sixteen registers. Both co-processor nuimbers can be used in an MCR
1107 and MRC to access these registers. CP 4 can LDC and STC to and from
1108 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
1109 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
1110 number of cycles (specified in a CP register), CDP 2 issues an IRQW
1111 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1112 stores a 32 bit time value in a CP register (actually it's the total
1113 number of N, S, I, C and F cyles). */
1115 static ARMword ValReg[16];
1118 ValLDC (ARMul_State * state ATTRIBUTE_UNUSED,
1123 static unsigned words;
1125 if (type != ARMul_DATA)
1129 ValReg[BITS (12, 15)] = data;
1132 /* It's a long access, get two words. */
1141 ValSTC (ARMul_State * state ATTRIBUTE_UNUSED,
1146 static unsigned words;
1148 if (type != ARMul_DATA)
1152 * data = ValReg[BITS (12, 15)];
1155 /* It's a long access, get two words. */
1164 ValMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1165 unsigned type ATTRIBUTE_UNUSED,
1169 *value = ValReg[BITS (16, 19)];
1175 ValMCR (ARMul_State * state ATTRIBUTE_UNUSED,
1176 unsigned type ATTRIBUTE_UNUSED,
1180 ValReg[BITS (16, 19)] = value;
1186 ValCDP (ARMul_State * state, unsigned type, ARMword instr)
1188 static unsigned long finish = 0;
1190 if (BITS (20, 23) != 0)
1193 if (type == ARMul_FIRST)
1197 howlong = ValReg[BITS (0, 3)];
1199 /* First cycle of a busy wait. */
1200 finish = ARMul_Time (state) + howlong;
1202 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1204 else if (type == ARMul_BUSY)
1206 if (ARMul_Time (state) >= finish)
1216 DoAFIQ (ARMul_State * state)
1218 state->NfiqSig = LOW;
1224 DoAIRQ (ARMul_State * state)
1226 state->NirqSig = LOW;
1232 IntCDP (ARMul_State * state, unsigned type, ARMword instr)
1234 static unsigned long finish;
1237 howlong = ValReg[BITS (0, 3)];
1239 switch ((int) BITS (20, 23))
1242 if (type == ARMul_FIRST)
1244 /* First cycle of a busy wait. */
1245 finish = ARMul_Time (state) + howlong;
1247 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1249 else if (type == ARMul_BUSY)
1251 if (ARMul_Time (state) >= finish)
1260 ARMul_Abort (state, ARMul_FIQV);
1262 ARMul_ScheduleEvent (state, howlong, DoAFIQ);
1267 ARMul_Abort (state, ARMul_IRQV);
1269 ARMul_ScheduleEvent (state, howlong, DoAIRQ);
1273 state->NfiqSig = HIGH;
1278 state->NirqSig = HIGH;
1283 ValReg[BITS (0, 3)] = ARMul_Time (state);
1290 /* Install co-processor instruction handlers in this routine. */
1293 ARMul_CoProInit (ARMul_State * state)
1297 /* Initialise tham all first. */
1298 for (i = 0; i < 16; i++)
1299 ARMul_CoProDetach (state, i);
1301 /* Install CoPro Instruction handlers here.
1303 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
1304 LDC routine, STC routine, MRC routine, MCR routine,
1305 CDP routine, Read Reg routine, Write Reg routine). */
1306 if (state->is_ep9312)
1308 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4,
1309 DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL);
1310 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5,
1311 DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL);
1312 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL,
1313 DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL);
1317 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC,
1318 ValMRC, ValMCR, ValCDP, NULL, NULL);
1320 ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
1321 ValMRC, ValMCR, IntCDP, NULL, NULL);
1324 if (state->is_XScale)
1326 ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
1327 XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
1328 XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
1329 XScale_cp13_write_reg);
1331 ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
1332 XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
1333 XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
1334 XScale_cp14_write_reg);
1336 ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
1337 NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
1338 NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
1342 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
1343 MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
1346 if (state->is_iWMMXt)
1348 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
1349 NULL, NULL, IwmmxtCDP, NULL, NULL);
1351 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
1352 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL);
1355 /* No handlers below here. */
1357 /* Call all the initialisation routines. */
1358 for (i = 0; i < 16; i++)
1359 if (state->CPInit[i])
1360 (state->CPInit[i]) (state);
1365 /* Install co-processor finalisation routines in this routine. */
1368 ARMul_CoProExit (ARMul_State * state)
1370 register unsigned i;
1372 for (i = 0; i < 16; i++)
1373 if (state->CPExit[i])
1374 (state->CPExit[i]) (state);
1376 for (i = 0; i < 16; i++) /* Detach all handlers. */
1377 ARMul_CoProDetach (state, i);
1380 /* Routines to hook Co-processors into ARMulator. */
1383 ARMul_CoProAttach (ARMul_State * state,
1385 ARMul_CPInits * init,
1386 ARMul_CPExits * exit,
1392 ARMul_CPReads * read,
1393 ARMul_CPWrites * write)
1396 state->CPInit[number] = init;
1398 state->CPExit[number] = exit;
1400 state->LDC[number] = ldc;
1402 state->STC[number] = stc;
1404 state->MRC[number] = mrc;
1406 state->MCR[number] = mcr;
1408 state->CDP[number] = cdp;
1410 state->CPRead[number] = read;
1412 state->CPWrite[number] = write;
1416 ARMul_CoProDetach (ARMul_State * state, unsigned number)
1418 ARMul_CoProAttach (state, number, NULL, NULL,
1419 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
1420 NoCoPro3R, NULL, NULL);
1422 state->CPInit[number] = NULL;
1423 state->CPExit[number] = NULL;
1424 state->CPRead[number] = NULL;
1425 state->CPWrite[number] = NULL;