diff options
| author | 2015-07-27 21:40:48 -0400 | |
|---|---|---|
| committer | 2015-07-27 22:06:59 -0400 | |
| commit | a507ea23c157abfc490cbb0c85154b23c4b079b9 (patch) | |
| tree | 910750e7ce0cca0da06820b992175d3bf12ad872 /src/core/arm/dyncom | |
| parent | dyncom: Remove duplicated typedef and extern (diff) | |
| download | yuzu-a507ea23c157abfc490cbb0c85154b23c4b079b9.tar.gz yuzu-a507ea23c157abfc490cbb0c85154b23c4b079b9.tar.xz yuzu-a507ea23c157abfc490cbb0c85154b23c4b079b9.zip | |
dyncom: Migrate exclusive memory access control into armstate
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 60 |
1 files changed, 13 insertions, 47 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index e855a4487..69228180e 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -47,27 +47,6 @@ enum { | |||
| 47 | 47 | ||
| 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); | 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); |
| 49 | 49 | ||
| 50 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 51 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 52 | // support LDR/STREXD. | ||
| 53 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 54 | |||
| 55 | // Exclusive memory access | ||
| 56 | static int exclusive_detect(ARMul_State* state, u32 addr) { | ||
| 57 | if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) | ||
| 58 | return 0; | ||
| 59 | else | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void add_exclusive_addr(ARMul_State* state, u32 addr){ | ||
| 64 | state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void remove_exclusive(ARMul_State* state, u32 addr){ | ||
| 68 | state->exclusive_tag = 0xFFFFFFFF; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { | 50 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { |
| 72 | const u32 NFLAG = cpu->NFlag; | 51 | const u32 NFLAG = cpu->NFlag; |
| 73 | const u32 ZFLAG = cpu->ZFlag; | 52 | const u32 ZFLAG = cpu->ZFlag; |
| @@ -4170,9 +4149,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4170 | 4149 | ||
| 4171 | CLREX_INST: | 4150 | CLREX_INST: |
| 4172 | { | 4151 | { |
| 4173 | remove_exclusive(cpu, 0); | 4152 | cpu->UnsetExclusiveMemoryAddress(); |
| 4174 | cpu->exclusive_state = 0; | ||
| 4175 | |||
| 4176 | cpu->Reg[15] += cpu->GetInstructionSize(); | 4153 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4177 | INC_PC(sizeof(clrex_inst)); | 4154 | INC_PC(sizeof(clrex_inst)); |
| 4178 | FETCH_INST; | 4155 | FETCH_INST; |
| @@ -4539,8 +4516,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4539 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4516 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4540 | unsigned int read_addr = RN; | 4517 | unsigned int read_addr = RN; |
| 4541 | 4518 | ||
| 4542 | add_exclusive_addr(cpu, read_addr); | 4519 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4543 | cpu->exclusive_state = 1; | ||
| 4544 | 4520 | ||
| 4545 | RD = cpu->ReadMemory32(read_addr); | 4521 | RD = cpu->ReadMemory32(read_addr); |
| 4546 | if (inst_cream->Rd == 15) { | 4522 | if (inst_cream->Rd == 15) { |
| @@ -4559,8 +4535,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4559 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4535 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4560 | unsigned int read_addr = RN; | 4536 | unsigned int read_addr = RN; |
| 4561 | 4537 | ||
| 4562 | add_exclusive_addr(cpu, read_addr); | 4538 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4563 | cpu->exclusive_state = 1; | ||
| 4564 | 4539 | ||
| 4565 | RD = Memory::Read8(read_addr); | 4540 | RD = Memory::Read8(read_addr); |
| 4566 | if (inst_cream->Rd == 15) { | 4541 | if (inst_cream->Rd == 15) { |
| @@ -4579,8 +4554,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4579 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4554 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4580 | unsigned int read_addr = RN; | 4555 | unsigned int read_addr = RN; |
| 4581 | 4556 | ||
| 4582 | add_exclusive_addr(cpu, read_addr); | 4557 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4583 | cpu->exclusive_state = 1; | ||
| 4584 | 4558 | ||
| 4585 | RD = cpu->ReadMemory16(read_addr); | 4559 | RD = cpu->ReadMemory16(read_addr); |
| 4586 | if (inst_cream->Rd == 15) { | 4560 | if (inst_cream->Rd == 15) { |
| @@ -4599,8 +4573,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4599 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4573 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4600 | unsigned int read_addr = RN; | 4574 | unsigned int read_addr = RN; |
| 4601 | 4575 | ||
| 4602 | add_exclusive_addr(cpu, read_addr); | 4576 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4603 | cpu->exclusive_state = 1; | ||
| 4604 | 4577 | ||
| 4605 | RD = cpu->ReadMemory32(read_addr); | 4578 | RD = cpu->ReadMemory32(read_addr); |
| 4606 | RD2 = cpu->ReadMemory32(read_addr + 4); | 4579 | RD2 = cpu->ReadMemory32(read_addr + 4); |
| @@ -6085,10 +6058,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6085 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6058 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6086 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6059 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6087 | 6060 | ||
| 6088 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6061 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6089 | remove_exclusive(cpu, write_addr); | 6062 | cpu->UnsetExclusiveMemoryAddress(); |
| 6090 | cpu->exclusive_state = 0; | ||
| 6091 | |||
| 6092 | cpu->WriteMemory32(write_addr, RM); | 6063 | cpu->WriteMemory32(write_addr, RM); |
| 6093 | RD = 0; | 6064 | RD = 0; |
| 6094 | } else { | 6065 | } else { |
| @@ -6107,10 +6078,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6107 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6078 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6108 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6079 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6109 | 6080 | ||
| 6110 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6081 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6111 | remove_exclusive(cpu, write_addr); | 6082 | cpu->UnsetExclusiveMemoryAddress(); |
| 6112 | cpu->exclusive_state = 0; | ||
| 6113 | |||
| 6114 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); | 6083 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); |
| 6115 | RD = 0; | 6084 | RD = 0; |
| 6116 | } else { | 6085 | } else { |
| @@ -6129,9 +6098,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6129 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6098 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6130 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6099 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6131 | 6100 | ||
| 6132 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6101 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6133 | remove_exclusive(cpu, write_addr); | 6102 | cpu->UnsetExclusiveMemoryAddress(); |
| 6134 | cpu->exclusive_state = 0; | ||
| 6135 | 6103 | ||
| 6136 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; | 6104 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; |
| 6137 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; | 6105 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; |
| @@ -6161,10 +6129,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6161 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6129 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6162 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6130 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6163 | 6131 | ||
| 6164 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6132 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6165 | remove_exclusive(cpu, write_addr); | 6133 | cpu->UnsetExclusiveMemoryAddress(); |
| 6166 | cpu->exclusive_state = 0; | ||
| 6167 | |||
| 6168 | cpu->WriteMemory16(write_addr, RM); | 6134 | cpu->WriteMemory16(write_addr, RM); |
| 6169 | RD = 0; | 6135 | RD = 0; |
| 6170 | } else { | 6136 | } else { |