Message ID | c0eb1605817385139c6c8619a4b62e44bcab21cd.1434339500.git.crosthwaite.peter@gmail.com |
---|---|
State | New |
Headers | show |
On 15 June 2015 at 04:48, Peter Crosthwaite <crosthwaitepeter@gmail.com> wrote: > ARM program counters are always at least 16b aligned with the LSB > being only used the indicate thumb mode in exchange situations. Mask > this bit off in set_pc to ignore the exchange semantic (which must > still be managed by the caller). > > Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> > --- > --- > target-arm/cpu.c | 2 +- > target-arm/cpu64.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/target-arm/cpu.c b/target-arm/cpu.c > index 6181f28..5bb08a6 100644 > --- a/target-arm/cpu.c > +++ b/target-arm/cpu.c > @@ -35,7 +35,7 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value) > { > ARMCPU *cpu = ARM_CPU(cs); > > - cpu->env.regs[15] = value; > + cpu->env.regs[15] = value & 0xfffffffe; > } This doesn't look right to me. There are two semantics that make sense for setting an ARM PC value: (1) interworking-aware, where we set the Thumb bit from the LS bit and r15 from everything else (2) interworking-unaware, where we just set r15 (and it's the caller's job to not pass us a misaligned value) This seems to be an odd mix of both. -- PMM
On Mon, Jun 15, 2015 at 12:36 AM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 15 June 2015 at 04:48, Peter Crosthwaite <crosthwaitepeter@gmail.com> wrote: >> ARM program counters are always at least 16b aligned with the LSB >> being only used the indicate thumb mode in exchange situations. Mask >> this bit off in set_pc to ignore the exchange semantic (which must >> still be managed by the caller). >> >> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> >> --- >> --- >> target-arm/cpu.c | 2 +- >> target-arm/cpu64.c | 2 +- >> 2 files changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/target-arm/cpu.c b/target-arm/cpu.c >> index 6181f28..5bb08a6 100644 >> --- a/target-arm/cpu.c >> +++ b/target-arm/cpu.c >> @@ -35,7 +35,7 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value) >> { >> ARMCPU *cpu = ARM_CPU(cs); >> >> - cpu->env.regs[15] = value; >> + cpu->env.regs[15] = value & 0xfffffffe; >> } > > > This doesn't look right to me. There are two semantics that > make sense for setting an ARM PC value: > > (1) interworking-aware, where we set the Thumb bit from the > LS bit and r15 from everything else > (2) interworking-unaware, where we just set r15 (and it's > the caller's job to not pass us a misaligned value) > Actually I am just going to leave as-is and mask off in the caller. What I am really trying to do is remove usage of r[15] from boot.c and I can do that using strategy (2) still. Regards, Peter > This seems to be an odd mix of both. > > -- PMM >
diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 6181f28..5bb08a6 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -35,7 +35,7 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value) { ARMCPU *cpu = ARM_CPU(cs); - cpu->env.regs[15] = value; + cpu->env.regs[15] = value & 0xfffffffe; } static bool arm_cpu_has_work(CPUState *cs) diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c index bf7dd68..1e26a48 100644 --- a/target-arm/cpu64.c +++ b/target-arm/cpu64.c @@ -279,7 +279,7 @@ static void aarch64_cpu_set_pc(CPUState *cs, vaddr value) if (is_a64(&cpu->env)) { cpu->env.pc = value; } else { - cpu->env.regs[15] = value; + cpu->env.regs[15] = value & 0xfffffffe; } }
ARM program counters are always at least 16b aligned with the LSB being only used the indicate thumb mode in exchange situations. Mask this bit off in set_pc to ignore the exchange semantic (which must still be managed by the caller). Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> --- --- target-arm/cpu.c | 2 +- target-arm/cpu64.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)