summaryrefslogtreecommitdiffstats
path: root/src/core/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp12
-rw-r--r--src/core/arm/skyeye_common/armdefs.h22
2 files changed, 18 insertions, 16 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 593e0eabd..9b291862c 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -63,16 +63,21 @@ extern void switch_mode(arm_core_t *core, uint32_t mode);
typedef arm_core_t arm_processor;
typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
+// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
+// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
+// support LDR/STREXD.
+static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
+
// Exclusive memory access
static int exclusive_detect(ARMul_State* state, ARMword addr){
- if(state->exclusive_tag == addr)
+ if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK))
return 0;
else
return -1;
}
static void add_exclusive_addr(ARMul_State* state, ARMword addr){
- state->exclusive_tag = addr;
+ state->exclusive_tag = addr & RESERVATION_GRANULE_MASK;
return;
}
@@ -80,7 +85,6 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){
state->exclusive_tag = 0xFFFFFFFF;
}
-
unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) {
unsigned int immed_8 = BITS(sht_oper, 0, 7);
unsigned int rotate_imm = BITS(sht_oper, 8, 11);
@@ -4613,7 +4617,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive?
RD = Memory::Read32(read_addr);
RD2 = Memory::Read32(read_addr + 4);
@@ -6133,7 +6136,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD
Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 3100d7adc..1b2cef451 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -165,20 +165,20 @@ struct ARMul_State
unsigned ErrorCode; /* type of illegal instruction */
/* Order of the following register should not be modified */
- ARMword Reg[16]; /* the current register file */
- ARMword Cpsr; /* the current psr */
+ ARMword Reg[16]; /* the current register file */
+ ARMword Cpsr; /* the current psr */
ARMword Spsr_copy;
ARMword phys_pc;
ARMword Reg_usr[2];
- ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
- ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
- ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
- ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
- ARMword Reg_firq[7]; /* R8---R14 FIRQ */
- ARMword Spsr[7]; /* the exception psr's */
- ARMword Mode; /* the current mode */
- ARMword Bank; /* the current register bank */
- ARMword exclusive_tag;
+ ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
+ ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
+ ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
+ ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
+ ARMword Reg_firq[7]; /* R8---R14 FIRQ */
+ ARMword Spsr[7]; /* the exception psr's */
+ ARMword Mode; /* the current mode */
+ ARMword Bank; /* the current register bank */
+ ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */
ARMword exclusive_state;
ARMword exclusive_result;
ARMword CP15[VFP_BASE - CP15_BASE];