diff mbox

[3/5] arm: Support thumb in set_pc routines

Message ID c0eb1605817385139c6c8619a4b62e44bcab21cd.1434339500.git.crosthwaite.peter@gmail.com
State New
Headers show

Commit Message

Peter Crosthwaite June 15, 2015, 3:48 a.m. UTC
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(-)

Comments

Peter Maydell June 15, 2015, 7:36 a.m. UTC | #1
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
Peter Crosthwaite June 15, 2015, 10:41 p.m. UTC | #2
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 mbox

Patch

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;
     }
 }