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. */
55 /* There are two sets of registers for copro 15.
56 One set is available when opcode_2 is 0 and
57 the other set when opcode_2 >= 1. */
58 static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
59 static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];
60 /* There are also a set of breakpoint registers
61 which are accessed via CRm instead of opcode_2. */
62 static ARMword XScale_cp15_DBR1;
63 static ARMword XScale_cp15_DBCON;
64 static ARMword XScale_cp15_IBCR0;
65 static ARMword XScale_cp15_IBCR1;
68 XScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED)
74 XScale_cp15_opcode_2_is_0_Regs[i] = 0;
75 XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;
78 /* Initialise the processor ID. */
79 XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;
81 /* Initialise the cache type. */
82 XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;
84 /* Initialise the ARM Control Register. */
85 XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
89 /* Check an access to a register. */
92 check_cp15_access (ARMul_State * state,
98 /* Do not allow access to these register in USER mode. */
99 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
102 /* Opcode_1should be zero. */
106 /* Different register have different access requirements. */
111 /* CRm must be 0. Opcode_2 can be anything. */
117 /* CRm must be 0. Opcode_2 must be zero. */
118 if ((CRm != 0) || (opcode_2 != 0))
122 /* Access not allowed. */
126 /* Opcode_2 must be zero. CRm must be 0. */
127 if ((CRm != 0) || (opcode_2 != 0))
131 /* Permissable combinations:
144 default: return ARMul_CANT;
145 case 6: if (CRm != 5) return ARMul_CANT; break;
146 case 5: if (CRm != 2) return ARMul_CANT; break;
147 case 4: if (CRm != 10) return ARMul_CANT; break;
148 case 1: if ((CRm != 5) && (CRm != 6) && (CRm != 10)) return ARMul_CANT; break;
149 case 0: if ((CRm < 5) || (CRm > 7)) return ARMul_CANT; break;
154 /* Permissable combinations:
163 if ((CRm < 5) || (CRm > 7))
165 if (opcode_2 == 1 && CRm == 7)
169 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
170 if ( ((CRm != 0) && (CRm != 1))
171 || ((opcode_2 != 1) && (opcode_2 != 2)))
175 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
176 if ( ((CRm != 0) && (CRm != 1))
177 || ((opcode_2 != 4) && (opcode_2 != 8)))
181 /* Access not allowed. */
184 /* Access not allowed. */
187 /* Opcode_2 must be zero. CRm must be 0. */
188 if ((CRm != 0) || (opcode_2 != 0))
192 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
196 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) && (CRm != 9))
200 /* Opcode_2 must be zero. CRm must be 1. */
201 if ((CRm != 1) || (opcode_2 != 0))
205 /* Should never happen. */
212 /* Store a value into one of coprocessor 15's registers. */
215 write_cp15_reg (ARMul_State * state, unsigned reg, unsigned opcode_2, unsigned CRm, ARMword value)
221 case 0: /* Cache Type. */
222 /* Writes are not allowed. */
225 case 1: /* Auxillary Control. */
226 /* Only BITS (5, 4) and BITS (1, 0) can be written. */
234 XScale_cp15_opcode_2_is_not_0_Regs [reg] = value;
241 /* Writes are not allowed. */
244 case 1: /* ARM Control. */
245 /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.
246 BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one. */
250 /* Change the endianness if necessary */
251 if ((value & ARMul_CP15_R1_ENDIAN) !=
252 (XScale_cp15_opcode_2_is_0_Regs [reg] & ARMul_CP15_R1_ENDIAN))
254 state->bigendSig = value & ARMul_CP15_R1_ENDIAN;
255 /* Force ARMulator to notice these now. */
256 state->Emulate = CHANGEMODE;
260 case 2: /* Translation Table Base. */
261 /* Only BITS (31, 14) can be written. */
265 case 3: /* Domain Access Control. */
266 /* All bits writable. */
269 case 5: /* Fault Status Register. */
270 /* BITS (10, 9) and BITS (7, 0) can be written. */
274 case 6: /* Fault Address Register. */
275 /* All bits writable. */
278 case 7: /* Cache Functions. */
279 case 8: /* TLB Operations. */
280 case 10: /* TLB Lock Down. */
284 case 9: /* Data Cache Lock. */
285 /* Only BIT (0) can be written. */
289 case 13: /* Process ID. */
290 /* Only BITS (31, 25) are writable. */
294 case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */
295 /* All bits can be written. Which register is accessed is
296 dependent upon CRm. */
302 XScale_cp15_DBR1 = value;
305 XScale_cp15_DBCON = value;
308 XScale_cp15_IBCR0 = value;
311 XScale_cp15_IBCR1 = value;
318 case 15: /* Coprpcessor Access Register. */
319 /* Access is only valid if CRm == 1. */
323 /* Only BITS (13, 0) may be written. */
331 XScale_cp15_opcode_2_is_0_Regs [reg] = value;
337 /* Return the value in a cp15 register. */
340 read_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm)
344 if (reg == 15 && CRm != 1)
351 case 3: return XScale_cp15_DBR1;
352 case 4: return XScale_cp15_DBCON;
353 case 8: return XScale_cp15_IBCR0;
354 case 9: return XScale_cp15_IBCR1;
360 return XScale_cp15_opcode_2_is_0_Regs [reg];
363 return XScale_cp15_opcode_2_is_not_0_Regs [reg];
369 XScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
371 unsigned reg = BITS (12, 15);
374 result = check_cp15_access (state, reg, 0, 0, 0);
376 if (result == ARMul_DONE && type == ARMul_DATA)
377 write_cp15_reg (state, reg, 0, 0, data);
383 XScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
385 unsigned reg = BITS (12, 15);
388 result = check_cp15_access (state, reg, 0, 0, 0);
390 if (result == ARMul_DONE && type == ARMul_DATA)
391 * data = read_cp15_reg (reg, 0, 0);
397 XScale_cp15_MRC (ARMul_State * state,
398 unsigned type ATTRIBUTE_UNUSED,
402 unsigned opcode_2 = BITS (5, 7);
403 unsigned CRm = BITS (0, 3);
404 unsigned reg = BITS (16, 19);
407 result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
409 if (result == ARMul_DONE)
410 * value = read_cp15_reg (reg, opcode_2, CRm);
416 XScale_cp15_MCR (ARMul_State * state,
417 unsigned type ATTRIBUTE_UNUSED,
421 unsigned opcode_2 = BITS (5, 7);
422 unsigned CRm = BITS (0, 3);
423 unsigned reg = BITS (16, 19);
426 result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
428 if (result == ARMul_DONE)
429 write_cp15_reg (state, reg, opcode_2, CRm, value);
435 XScale_cp15_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
439 /* FIXME: Not sure what to do about the alternative register set
440 here. For now default to just accessing CRm == 0 registers. */
441 * value = read_cp15_reg (reg, 0, 0);
447 XScale_cp15_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,
451 /* FIXME: Not sure what to do about the alternative register set
452 here. For now default to just accessing CRm == 0 registers. */
453 write_cp15_reg (state, reg, 0, 0, value);
458 /***************************************************************************\
459 * Check for special XScale memory access features *
460 \***************************************************************************/
462 XScale_check_memacc (ARMul_State * state, ARMword * address, int store)
464 ARMword dbcon, r0, r1;
467 if (!state->is_XScale)
470 /* Check for PID-ification.
471 XXX BTB access support will require this test failing. */
472 r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000);
473 if (r0 && (*address & 0xfe000000) == 0)
476 /* Check alignment fault enable/disable. */
477 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (*address & 3))
478 ARMul_Abort (state, ARMul_DataAbortV);
480 if (XScale_debug_moe (state, -1))
483 /* Check the data breakpoint registers. */
484 dbcon = read_cp15_reg (14, 0, 4);
485 r0 = read_cp15_reg (14, 0, 0);
486 r1 = read_cp15_reg (14, 0, 3);
487 e0 = dbcon & ARMul_CP15_DBCON_E0;
489 if (dbcon & ARMul_CP15_DBCON_M)
491 /* r1 is a inverse mask. */
492 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
493 && ((*address & ~r1) == (r0 & ~r1)))
495 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
496 ARMul_OSHandleSWI (state, SWI_Breakpoint);
501 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
502 && ((*address & ~3) == (r0 & ~3)))
504 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
505 ARMul_OSHandleSWI (state, SWI_Breakpoint);
508 e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2;
509 if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1))
510 && ((*address & ~3) == (r1 & ~3)))
512 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
513 ARMul_OSHandleSWI (state, SWI_Breakpoint);
518 /***************************************************************************\
520 \***************************************************************************/
522 XScale_set_fsr_far(ARMul_State * state, ARMword fsr, ARMword far)
524 if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
527 write_cp15_reg (state, 5, 0, 0, fsr);
528 write_cp15_reg (state, 6, 0, 0, far);
531 /* Set the XScale debug `method of entry' if it is enabled. */
533 XScale_debug_moe (ARMul_State * state, int moe)
537 if (!state->is_XScale)
540 value = read_cp14_reg (10);
541 if (value & (1UL << 31))
548 write_cp14_reg (10, value);
555 /* Coprocessor 13: Interrupt Controller and Bus Controller. */
557 /* There are two sets of registers for copro 13.
558 One set (of three registers) is available when CRm is 0
559 and the other set (of six registers) when CRm is 1. */
561 static ARMword XScale_cp13_CR0_Regs[16];
562 static ARMword XScale_cp13_CR1_Regs[16];
565 XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED)
571 XScale_cp13_CR0_Regs[i] = 0;
572 XScale_cp13_CR1_Regs[i] = 0;
576 /* Check an access to a register. */
579 check_cp13_access (ARMul_State * state,
585 /* Do not allow access to these register in USER mode. */
586 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
589 /* The opcodes should be zero. */
590 if ((opcode_1 != 0) || (opcode_2 != 0))
593 /* Do not allow access to these register if bit 13 of coprocessor
594 15's register 15 is zero. */
595 if ((XScale_cp15_opcode_2_is_0_Regs[15] & (1 << 13)) == 0)
598 /* Registers 0, 4 and 8 are defined when CRm == 0.
599 Registers 0, 4, 5, 6, 7, 8 are defined when CRm == 1.
600 For all other CRm values undefined behaviour results. */
603 if (reg == 0 || reg == 4 || reg == 8)
608 if (reg == 0 || (reg >= 4 && reg <= 8))
615 /* Store a value into one of coprocessor 13's registers. */
618 write_cp13_reg (unsigned reg, unsigned CRm, ARMword value)
626 /* Only BITS (3:0) can be written. */
631 /* No bits may be written. */
635 /* Only BITS (1:0) can be written. */
640 /* Should not happen. Ignore any writes to unimplemented registers. */
644 XScale_cp13_CR0_Regs [reg] = value;
651 /* Only BITS (30:28) and BITS (3:0) can be written.
652 BIT(31) is write ignored. */
654 value |= XScale_cp13_CR1_Regs[0] & (1UL << 31);
661 /* No bits can be written. */
665 /* Only BITS (7:0) can be written. */
670 /* Should not happen. Ignore any writes to unimplemented registers. */
674 XScale_cp13_CR1_Regs [reg] = value;
678 /* Should not happen. */
685 /* Return the value in a cp13 register. */
688 read_cp13_reg (unsigned reg, unsigned CRm)
691 return XScale_cp13_CR0_Regs [reg];
693 return XScale_cp13_CR1_Regs [reg];
699 XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
701 unsigned reg = BITS (12, 15);
704 result = check_cp13_access (state, reg, 0, 0, 0);
706 if (result == ARMul_DONE && type == ARMul_DATA)
707 write_cp13_reg (reg, 0, data);
713 XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
715 unsigned reg = BITS (12, 15);
718 result = check_cp13_access (state, reg, 0, 0, 0);
720 if (result == ARMul_DONE && type == ARMul_DATA)
721 * data = read_cp13_reg (reg, 0);
727 XScale_cp13_MRC (ARMul_State * state,
728 unsigned type ATTRIBUTE_UNUSED,
732 unsigned CRm = BITS (0, 3);
733 unsigned reg = BITS (16, 19);
736 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
738 if (result == ARMul_DONE)
739 * value = read_cp13_reg (reg, CRm);
745 XScale_cp13_MCR (ARMul_State * state,
746 unsigned type ATTRIBUTE_UNUSED,
750 unsigned CRm = BITS (0, 3);
751 unsigned reg = BITS (16, 19);
754 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
756 if (result == ARMul_DONE)
757 write_cp13_reg (reg, CRm, value);
765 ARMul_State * state ATTRIBUTE_UNUSED,
770 /* FIXME: Not sure what to do about the alternative register set
771 here. For now default to just accessing CRm == 0 registers. */
772 * value = read_cp13_reg (reg, 0);
778 XScale_cp13_write_reg
780 ARMul_State * state ATTRIBUTE_UNUSED,
785 /* FIXME: Not sure what to do about the alternative register set
786 here. For now default to just accessing CRm == 0 registers. */
787 write_cp13_reg (reg, 0, value);
792 /* Coprocessor 14: Performance Monitoring, Clock and Power management,
795 static ARMword XScale_cp14_Regs[16];
798 XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED)
803 XScale_cp14_Regs[i] = 0;
806 /* Check an access to a register. */
809 check_cp14_access (ARMul_State * state,
815 /* Not allowed to access these register in USER mode. */
816 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
819 /* CRm should be zero. */
823 /* OPcodes should be zero. */
824 if (opcode1 != 0 || opcode2 != 0)
827 /* Accessing registers 4 or 5 has unpredicatable results. */
828 if (reg >= 4 && reg <= 5)
834 /* Store a value into one of coprocessor 14's registers. */
837 write_cp14_reg (unsigned reg, ARMword value)
842 /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */
845 /* Reset the clock counter if necessary */
846 if (value & ARMul_CP14_R0_CLKRST)
847 XScale_cp14_Regs [1] = 0;
852 /* We should not normally reach this code. The debugger interface
853 can bypass the normal checks though, so it could happen. */
857 case 6: /* CCLKCFG */
858 /* Only BITS (3:0) can be written. */
862 case 7: /* PWRMODE */
863 /* Although BITS (1:0) can be written with non-zero values, this would
864 have the side effect of putting the processor to sleep. Thus in
865 order for the register to be read again, it would have to go into
866 ACTIVE mode, which means that any read will see these bits as zero.
868 Rather than trying to implement complex reset-to-zero-upon-read logic
869 we just override the write value with zero. */
874 /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
880 /* No writes are permitted. */
884 case 14: /* TXRXCTRL */
885 /* Only BITS (31:30) can be written. */
890 /* All bits can be written. */
894 XScale_cp14_Regs [reg] = value;
897 /* Return the value in a cp14 register. Not a static function since
898 it is used by the code to emulate the BKPT instruction in armemu.c. */
901 read_cp14_reg (unsigned reg)
903 return XScale_cp14_Regs [reg];
907 XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
909 unsigned reg = BITS (12, 15);
912 result = check_cp14_access (state, reg, 0, 0, 0);
914 if (result == ARMul_DONE && type == ARMul_DATA)
915 write_cp14_reg (reg, data);
921 XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
923 unsigned reg = BITS (12, 15);
926 result = check_cp14_access (state, reg, 0, 0, 0);
928 if (result == ARMul_DONE && type == ARMul_DATA)
929 * data = read_cp14_reg (reg);
938 unsigned type ATTRIBUTE_UNUSED,
943 unsigned reg = BITS (16, 19);
946 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
948 if (result == ARMul_DONE)
949 * value = read_cp14_reg (reg);
958 unsigned type ATTRIBUTE_UNUSED,
963 unsigned reg = BITS (16, 19);
966 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
968 if (result == ARMul_DONE)
969 write_cp14_reg (reg, value);
977 ARMul_State * state ATTRIBUTE_UNUSED,
982 * value = read_cp14_reg (reg);
988 XScale_cp14_write_reg
990 ARMul_State * state ATTRIBUTE_UNUSED,
995 write_cp14_reg (reg, value);
1000 /* Here's ARMulator's MMU definition. A few things to note:
1001 1) It has eight registers, but only two are defined.
1002 2) You can only access its registers with MCR and MRC.
1003 3) MMU Register 0 (ID) returns 0x41440110
1004 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
1005 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
1006 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
1008 static ARMword MMUReg[8];
1011 MMUInit (ARMul_State * state)
1013 MMUReg[1] = state->prog32Sig << 4 |
1014 state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
1016 ARMul_ConsolePrint (state, ", MMU present");
1022 MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1023 unsigned type ATTRIBUTE_UNUSED,
1027 int reg = BITS (16, 19) & 7;
1030 *value = 0x41440110;
1032 *value = MMUReg[reg];
1038 MMUMCR (ARMul_State * state,
1039 unsigned type ATTRIBUTE_UNUSED,
1043 int reg = BITS (16, 19) & 7;
1045 MMUReg[reg] = value;
1051 p = state->prog32Sig;
1052 d = state->data32Sig;
1053 l = state->lateabtSig;
1054 b = state->bigendSig;
1056 state->prog32Sig = value >> 4 & 1;
1057 state->data32Sig = value >> 5 & 1;
1058 state->lateabtSig = value >> 6 & 1;
1059 state->bigendSig = value >> 7 & 1;
1061 if ( p != state->prog32Sig
1062 || d != state->data32Sig
1063 || l != state->lateabtSig
1064 || b != state->bigendSig)
1065 /* Force ARMulator to notice these now. */
1066 state->Emulate = CHANGEMODE;
1073 MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value)
1076 *value = 0x41440110;
1078 *value = MMUReg[reg];
1084 MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
1087 MMUReg[reg] = value;
1093 p = state->prog32Sig;
1094 d = state->data32Sig;
1095 l = state->lateabtSig;
1096 b = state->bigendSig;
1098 state->prog32Sig = value >> 4 & 1;
1099 state->data32Sig = value >> 5 & 1;
1100 state->lateabtSig = value >> 6 & 1;
1101 state->bigendSig = value >> 7 & 1;
1103 if ( p != state->prog32Sig
1104 || d != state->data32Sig
1105 || l != state->lateabtSig
1106 || b != state->bigendSig)
1107 /* Force ARMulator to notice these now. */
1108 state->Emulate = CHANGEMODE;
1115 /* What follows is the Validation Suite Coprocessor. It uses two
1116 co-processor numbers (4 and 5) and has the follwing functionality.
1117 Sixteen registers. Both co-processor nuimbers can be used in an MCR
1118 and MRC to access these registers. CP 4 can LDC and STC to and from
1119 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
1120 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
1121 number of cycles (specified in a CP register), CDP 2 issues an IRQW
1122 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1123 stores a 32 bit time value in a CP register (actually it's the total
1124 number of N, S, I, C and F cyles). */
1126 static ARMword ValReg[16];
1129 ValLDC (ARMul_State * state ATTRIBUTE_UNUSED,
1134 static unsigned words;
1136 if (type != ARMul_DATA)
1140 ValReg[BITS (12, 15)] = data;
1143 /* It's a long access, get two words. */
1152 ValSTC (ARMul_State * state ATTRIBUTE_UNUSED,
1157 static unsigned words;
1159 if (type != ARMul_DATA)
1163 * data = ValReg[BITS (12, 15)];
1166 /* It's a long access, get two words. */
1175 ValMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1176 unsigned type ATTRIBUTE_UNUSED,
1180 *value = ValReg[BITS (16, 19)];
1186 ValMCR (ARMul_State * state ATTRIBUTE_UNUSED,
1187 unsigned type ATTRIBUTE_UNUSED,
1191 ValReg[BITS (16, 19)] = value;
1197 ValCDP (ARMul_State * state, unsigned type, ARMword instr)
1199 static unsigned long finish = 0;
1201 if (BITS (20, 23) != 0)
1204 if (type == ARMul_FIRST)
1208 howlong = ValReg[BITS (0, 3)];
1210 /* First cycle of a busy wait. */
1211 finish = ARMul_Time (state) + howlong;
1213 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1215 else if (type == ARMul_BUSY)
1217 if (ARMul_Time (state) >= finish)
1227 DoAFIQ (ARMul_State * state)
1229 state->NfiqSig = LOW;
1235 DoAIRQ (ARMul_State * state)
1237 state->NirqSig = LOW;
1243 IntCDP (ARMul_State * state, unsigned type, ARMword instr)
1245 static unsigned long finish;
1248 howlong = ValReg[BITS (0, 3)];
1250 switch ((int) BITS (20, 23))
1253 if (type == ARMul_FIRST)
1255 /* First cycle of a busy wait. */
1256 finish = ARMul_Time (state) + howlong;
1258 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1260 else if (type == ARMul_BUSY)
1262 if (ARMul_Time (state) >= finish)
1271 ARMul_Abort (state, ARMul_FIQV);
1273 ARMul_ScheduleEvent (state, howlong, DoAFIQ);
1278 ARMul_Abort (state, ARMul_IRQV);
1280 ARMul_ScheduleEvent (state, howlong, DoAIRQ);
1284 state->NfiqSig = HIGH;
1289 state->NirqSig = HIGH;
1294 ValReg[BITS (0, 3)] = ARMul_Time (state);
1301 /***************************************************************************\
1302 * Install co-processor instruction handlers in this routine *
1303 \***************************************************************************/
1306 ARMul_CoProInit (ARMul_State * state)
1310 /* Initialise tham all first. */
1311 for (i = 0; i < 16; i++)
1312 ARMul_CoProDetach (state, i);
1314 /* Install CoPro Instruction handlers here.
1316 ARMul_CoProAttach (state, CP Number,
1317 Init routine, Exit routine
1318 LDC routine, STC routine,
1319 MRC routine, MCR routine,
1321 Read Reg routine, Write Reg routine). */
1322 ARMul_CoProAttach (state, 4, NULL, NULL,
1323 ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
1325 ARMul_CoProAttach (state, 5, NULL, NULL,
1326 NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
1328 ARMul_CoProAttach (state, 15, MMUInit, NULL,
1329 NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
1331 ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
1332 XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
1333 XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
1334 XScale_cp13_write_reg);
1336 ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
1337 XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
1338 XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
1339 XScale_cp14_write_reg);
1341 ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
1342 NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
1343 NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
1345 /* No handlers below here. */
1347 /* Call all the initialisation routines. */
1348 for (i = 0; i < 16; i++)
1349 if (state->CPInit[i])
1350 (state->CPInit[i]) (state);
1355 /***************************************************************************\
1356 * Install co-processor finalisation routines in this routine *
1357 \***************************************************************************/
1360 ARMul_CoProExit (ARMul_State * state)
1362 register unsigned i;
1364 for (i = 0; i < 16; i++)
1365 if (state->CPExit[i])
1366 (state->CPExit[i]) (state);
1368 for (i = 0; i < 16; i++) /* Detach all handlers. */
1369 ARMul_CoProDetach (state, i);
1372 /***************************************************************************\
1373 * Routines to hook Co-processors into ARMulator *
1374 \***************************************************************************/
1377 ARMul_CoProAttach (ARMul_State * state,
1379 ARMul_CPInits * init,
1380 ARMul_CPExits * exit,
1386 ARMul_CPReads * read,
1387 ARMul_CPWrites * write)
1390 state->CPInit[number] = init;
1392 state->CPExit[number] = exit;
1394 state->LDC[number] = ldc;
1396 state->STC[number] = stc;
1398 state->MRC[number] = mrc;
1400 state->MCR[number] = mcr;
1402 state->CDP[number] = cdp;
1404 state->CPRead[number] = read;
1406 state->CPWrite[number] = write;
1410 ARMul_CoProDetach (ARMul_State * state, unsigned number)
1412 ARMul_CoProAttach (state, number, NULL, NULL,
1413 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
1414 NoCoPro3R, NULL, NULL);
1416 state->CPInit[number] = NULL;
1417 state->CPExit[number] = NULL;
1418 state->CPRead[number] = NULL;
1419 state->CPWrite[number] = NULL;