diff options
| author | 2015-01-06 12:42:10 -0500 | |
|---|---|---|
| committer | 2015-01-06 12:42:10 -0500 | |
| commit | 89bb0ecbd534527898a836e8565702364906cdb9 (patch) | |
| tree | 47dd582f543e140b356be9df4813f644f4f29740 /src/core/arm/dyncom | |
| parent | Merge pull request #419 from linkmauve/no-x86-specifics (diff) | |
| parent | Added exclusive reservation granule from ARMv7 spec to dyncom to protect LDR/... (diff) | |
| download | yuzu-89bb0ecbd534527898a836e8565702364906cdb9.tar.gz yuzu-89bb0ecbd534527898a836e8565702364906cdb9.tar.xz yuzu-89bb0ecbd534527898a836e8565702364906cdb9.zip | |
Merge pull request #417 from kevinhartman/exclusive-tag-fix
Added exclusive reservation granule from ARMv7 spec to dyncom...
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 12 |
1 files changed, 7 insertions, 5 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]); |