#include "armos.h"
#include "armemu.h"
#include "ansidecl.h"
+#include "iwmmxt.h"
/* Dummy Co-processors. */
/* Initialise the ARM Control Register. */
XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
-
}
/* Check an access to a register. */
value &= 0x00003b87;
value |= 0x00000078;
- /* Change the endianness if necessary */
+ /* Change the endianness if necessary. */
if ((value & ARMul_CP15_R1_ENDIAN) !=
(XScale_cp15_opcode_2_is_0_Regs [reg] & ARMul_CP15_R1_ENDIAN))
{
/* Check for PID-ification.
XXX BTB access support will require this test failing. */
r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000);
- if (r0 && (*address & 0xfe000000) == 0)
- *address |= r0;
+ if (r0 && (* address & 0xfe000000) == 0)
+ * address |= r0;
/* Check alignment fault enable/disable. */
- if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (*address & 3))
- ARMul_Abort (state, ARMul_DataAbortV);
+ if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3))
+ {
+ /* Set the FSR and FAR.
+ Do not use XScale_set_fsr_far as this checks the DCSR register. */
+ write_cp15_reg (state, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT);
+ write_cp15_reg (state, 6, 0, 0, * address);
+
+ ARMul_Abort (state, ARMul_DataAbortV);
+ }
if (XScale_debug_moe (state, -1))
return;
{
/* r1 is a inverse mask. */
if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
- && ((*address & ~r1) == (r0 & ~r1)))
+ && ((* address & ~r1) == (r0 & ~r1)))
{
XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
ARMul_OSHandleSWI (state, SWI_Breakpoint);
else
{
if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
- && ((*address & ~3) == (r0 & ~3)))
+ && ((* address & ~3) == (r0 & ~3)))
{
XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
ARMul_OSHandleSWI (state, SWI_Breakpoint);
e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2;
if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1))
- && ((*address & ~3) == (r1 & ~3)))
+ && ((* address & ~3) == (r1 & ~3)))
{
XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
ARMul_OSHandleSWI (state, SWI_Breakpoint);
}
}
-/* Check set. */
+/* Set the XScale FSR and FAR registers. */
void
XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far)
unsigned opcode_1,
unsigned opcode_2)
{
- /* Do not allow access to these register in USER mode. */
+ /* Do not allow access to these registers in USER mode. */
if (state->Mode == USER26MODE || state->Mode == USER32MODE)
return ARMul_CANT;
return ARMul_CANT;
/* Registers 0, 4 and 8 are defined when CRm == 0.
- Registers 0, 4, 5, 6, 7, 8 are defined when CRm == 1.
+ Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
For all other CRm values undefined behaviour results. */
if (CRm == 0)
{
}
else if (CRm == 1)
{
- if (reg == 0 || (reg >= 4 && reg <= 8))
+ if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
return ARMul_DONE;
}
value |= XScale_cp13_CR1_Regs[0] & (1UL << 31);
break;
+ case 1: /* BCUMOD */
+ /* Only bit 0 is accecssible. */
+ value &= 1;
+ value |= XScale_cp13_CR1_Regs[1] & ~ 1;
+ break;
+
case 4: /* ELOG0 */
case 5: /* ELOG1 */
case 6: /* ECAR0 */
/* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */
value &= 0x0ffff77f;
- /* Reset the clock counter if necessary */
+ /* Reset the clock counter if necessary. */
if (value & ARMul_CP14_R0_CLKRST)
XScale_cp14_Regs [1] = 0;
break;
/* Install CoPro Instruction handlers here.
The format is:
- ARMul_CoProAttach (state, CP Number,
- Init routine, Exit routine
- LDC routine, STC routine,
- MRC routine, MCR routine,
- CDP routine,
- Read Reg routine, Write Reg routine). */
- ARMul_CoProAttach (state, 4, NULL, NULL,
- ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
-
- ARMul_CoProAttach (state, 5, NULL, NULL,
- NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
-
- ARMul_CoProAttach (state, 15, MMUInit, NULL,
- NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
-
- ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
- XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
- XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
- XScale_cp13_write_reg);
-
- ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
- XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
- XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
- XScale_cp14_write_reg);
-
- ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
- NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
- NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
+ ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
+ LDC routine, STC routine, MRC routine, MCR routine,
+ CDP routine, Read Reg routine, Write Reg routine). */
+ if (state->is_ep9312)
+ {
+ ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4,
+ DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL);
+ ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5,
+ DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL);
+ ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL,
+ DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL);
+ }
+ else
+ {
+ ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC,
+ ValMRC, ValMCR, ValCDP, NULL, NULL);
+
+ ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
+ ValMRC, ValMCR, IntCDP, NULL, NULL);
+ }
+
+ if (state->is_XScale)
+ {
+ ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
+ XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
+ XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
+ XScale_cp13_write_reg);
+
+ ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
+ XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
+ XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
+ XScale_cp14_write_reg);
+
+ ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
+ NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
+ NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
+ }
+ else
+ {
+ ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
+ MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
+ }
+
+ if (state->is_iWMMXt)
+ {
+ ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
+ NULL, NULL, IwmmxtCDP, NULL, NULL);
+
+ ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
+ IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL);
+ }
/* No handlers below here. */