Added exclusive reservation granule from ARMv7 spec to dyncom to protect LDR/STREX.
This commit is contained in:
parent
9ac2272e25
commit
8132c01830
@ -63,16 +63,21 @@ extern void switch_mode(arm_core_t *core, uint32_t mode);
|
|||||||
typedef arm_core_t arm_processor;
|
typedef arm_core_t arm_processor;
|
||||||
typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
|
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
|
// Exclusive memory access
|
||||||
static int exclusive_detect(ARMul_State* state, ARMword addr){
|
static int exclusive_detect(ARMul_State* state, ARMword addr){
|
||||||
if(state->exclusive_tag == addr)
|
if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_exclusive_addr(ARMul_State* state, ARMword addr){
|
static void add_exclusive_addr(ARMul_State* state, ARMword addr){
|
||||||
state->exclusive_tag = addr;
|
state->exclusive_tag = addr & RESERVATION_GRANULE_MASK;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +85,6 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){
|
|||||||
state->exclusive_tag = 0xFFFFFFFF;
|
state->exclusive_tag = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) {
|
unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) {
|
||||||
unsigned int immed_8 = BITS(sht_oper, 0, 7);
|
unsigned int immed_8 = BITS(sht_oper, 0, 7);
|
||||||
unsigned int rotate_imm = BITS(sht_oper, 8, 11);
|
unsigned int rotate_imm = BITS(sht_oper, 8, 11);
|
||||||
@ -4551,7 +4555,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
|
|||||||
|
|
||||||
add_exclusive_addr(cpu, read_addr);
|
add_exclusive_addr(cpu, read_addr);
|
||||||
cpu->exclusive_state = 1;
|
cpu->exclusive_state = 1;
|
||||||
// TODO(bunnei): Do we need to also make [read_addr + 4] exclusive?
|
|
||||||
|
|
||||||
RD = Memory::Read32(read_addr);
|
RD = Memory::Read32(read_addr);
|
||||||
RD2 = Memory::Read32(read_addr + 4);
|
RD2 = Memory::Read32(read_addr + 4);
|
||||||
@ -5978,7 +5981,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
|
|||||||
if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
|
if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
|
||||||
remove_exclusive(cpu, write_addr);
|
remove_exclusive(cpu, write_addr);
|
||||||
cpu->exclusive_state = 0;
|
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, cpu->Reg[inst_cream->Rm]);
|
||||||
Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
|
Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
|
||||||
|
@ -162,20 +162,20 @@ struct ARMul_State
|
|||||||
unsigned ErrorCode; /* type of illegal instruction */
|
unsigned ErrorCode; /* type of illegal instruction */
|
||||||
|
|
||||||
/* Order of the following register should not be modified */
|
/* Order of the following register should not be modified */
|
||||||
ARMword Reg[16]; /* the current register file */
|
ARMword Reg[16]; /* the current register file */
|
||||||
ARMword Cpsr; /* the current psr */
|
ARMword Cpsr; /* the current psr */
|
||||||
ARMword Spsr_copy;
|
ARMword Spsr_copy;
|
||||||
ARMword phys_pc;
|
ARMword phys_pc;
|
||||||
ARMword Reg_usr[2];
|
ARMword Reg_usr[2];
|
||||||
ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
|
ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
|
||||||
ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
|
ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
|
||||||
ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
|
ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
|
||||||
ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
|
ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
|
||||||
ARMword Reg_firq[7]; /* R8---R14 FIRQ */
|
ARMword Reg_firq[7]; /* R8---R14 FIRQ */
|
||||||
ARMword Spsr[7]; /* the exception psr's */
|
ARMword Spsr[7]; /* the exception psr's */
|
||||||
ARMword Mode; /* the current mode */
|
ARMword Mode; /* the current mode */
|
||||||
ARMword Bank; /* the current register bank */
|
ARMword Bank; /* the current register bank */
|
||||||
ARMword exclusive_tag;
|
ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */
|
||||||
ARMword exclusive_state;
|
ARMword exclusive_state;
|
||||||
ARMword exclusive_result;
|
ARMword exclusive_result;
|
||||||
ARMword CP15[VFP_BASE - CP15_BASE];
|
ARMword CP15[VFP_BASE - CP15_BASE];
|
||||||
|
Loading…
Reference in New Issue
Block a user