diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 12 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 22 |
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); | |||
| 63 | typedef arm_core_t arm_processor; | 63 | typedef arm_core_t arm_processor; |
| 64 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); | 64 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); |
| 65 | 65 | ||
| 66 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 67 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 68 | // support LDR/STREXD. | ||
| 69 | static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 70 | |||
| 66 | // Exclusive memory access | 71 | // Exclusive memory access |
| 67 | static int exclusive_detect(ARMul_State* state, ARMword addr){ | 72 | static int exclusive_detect(ARMul_State* state, ARMword addr){ |
| 68 | if(state->exclusive_tag == addr) | 73 | if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) |
| 69 | return 0; | 74 | return 0; |
| 70 | else | 75 | else |
| 71 | return -1; | 76 | return -1; |
| 72 | } | 77 | } |
| 73 | 78 | ||
| 74 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | 79 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ |
| 75 | state->exclusive_tag = addr; | 80 | state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; |
| 76 | return; | 81 | return; |
| 77 | } | 82 | } |
| 78 | 83 | ||
| @@ -80,7 +85,6 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){ | |||
| 80 | state->exclusive_tag = 0xFFFFFFFF; | 85 | state->exclusive_tag = 0xFFFFFFFF; |
| 81 | } | 86 | } |
| 82 | 87 | ||
| 83 | |||
| 84 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { | 88 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 85 | unsigned int immed_8 = BITS(sht_oper, 0, 7); | 89 | unsigned int immed_8 = BITS(sht_oper, 0, 7); |
| 86 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); | 90 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); |
| @@ -4613,7 +4617,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4613 | 4617 | ||
| 4614 | add_exclusive_addr(cpu, read_addr); | 4618 | add_exclusive_addr(cpu, read_addr); |
| 4615 | cpu->exclusive_state = 1; | 4619 | cpu->exclusive_state = 1; |
| 4616 | // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive? | ||
| 4617 | 4620 | ||
| 4618 | RD = Memory::Read32(read_addr); | 4621 | RD = Memory::Read32(read_addr); |
| 4619 | RD2 = Memory::Read32(read_addr + 4); | 4622 | RD2 = Memory::Read32(read_addr + 4); |
| @@ -6133,7 +6136,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6133 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6136 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { |
| 6134 | remove_exclusive(cpu, write_addr); | 6137 | remove_exclusive(cpu, write_addr); |
| 6135 | cpu->exclusive_state = 0; | 6138 | cpu->exclusive_state = 0; |
| 6136 | // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD | ||
| 6137 | 6139 | ||
| 6138 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); | 6140 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); |
| 6139 | Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); | 6141 | 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 | |||
| 165 | unsigned ErrorCode; /* type of illegal instruction */ | 165 | unsigned ErrorCode; /* type of illegal instruction */ |
| 166 | 166 | ||
| 167 | /* Order of the following register should not be modified */ | 167 | /* Order of the following register should not be modified */ |
| 168 | ARMword Reg[16]; /* the current register file */ | 168 | ARMword Reg[16]; /* the current register file */ |
| 169 | ARMword Cpsr; /* the current psr */ | 169 | ARMword Cpsr; /* the current psr */ |
| 170 | ARMword Spsr_copy; | 170 | ARMword Spsr_copy; |
| 171 | ARMword phys_pc; | 171 | ARMword phys_pc; |
| 172 | ARMword Reg_usr[2]; | 172 | ARMword Reg_usr[2]; |
| 173 | ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ | 173 | ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ |
| 174 | ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ | 174 | ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ |
| 175 | ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ | 175 | ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ |
| 176 | ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ | 176 | ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ |
| 177 | ARMword Reg_firq[7]; /* R8---R14 FIRQ */ | 177 | ARMword Reg_firq[7]; /* R8---R14 FIRQ */ |
| 178 | ARMword Spsr[7]; /* the exception psr's */ | 178 | ARMword Spsr[7]; /* the exception psr's */ |
| 179 | ARMword Mode; /* the current mode */ | 179 | ARMword Mode; /* the current mode */ |
| 180 | ARMword Bank; /* the current register bank */ | 180 | ARMword Bank; /* the current register bank */ |
| 181 | ARMword exclusive_tag; | 181 | ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */ |
| 182 | ARMword exclusive_state; | 182 | ARMword exclusive_state; |
| 183 | ARMword exclusive_result; | 183 | ARMword exclusive_result; |
| 184 | ARMword CP15[VFP_BASE - CP15_BASE]; | 184 | ARMword CP15[VFP_BASE - CP15_BASE]; |