qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit


From: Philippe Mathieu-Daudé
Subject: Re: [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit
Date: Wed, 12 Feb 2020 08:14:16 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1

On 2/11/20 6:37 PM, Peter Maydell wrote:
The LC bit in the PMCR_EL0 register is supposed to be:
  * read/write
  * RES1 on an AArch64-only implementation
  * an architecturally UNKNOWN value on reset
(and use of LC==0 by software is deprecated).

We were implementing it incorrectly as read-only always zero,
though we do have all the code needed to test it and behave
accordingly.

Instead make it a read-write bit which resets to 1 always, which
satisfies all the architectural requirements above.

Signed-off-by: Peter Maydell <address@hidden>
---
  target/arm/helper.c | 13 +++++++++----
  1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index c6758bfbeb5..1d8eafceda8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1023,6 +1023,11 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
  #define PMCRC   0x4
  #define PMCRP   0x2
  #define PMCRE   0x1
+/*
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
+ */
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
#define PMXEVTYPER_P 0x80000000
  #define PMXEVTYPER_U          0x40000000
@@ -1577,9 +1582,8 @@ static void pmcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
          }
      }
- /* only the DP, X, D and E bits are writable */
-    env->cp15.c9_pmcr &= ~0x39;
-    env->cp15.c9_pmcr |= (value & 0x39);

Ah this was missing PMCRLC indeed.

I was tempted to use 'Fixes: 74594c9d813' but the PMCRLC is "Reserved, UNK/SBZP" in the ARMv7 reference manual.
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>

+    env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
+    env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
pmu_op_finish(env);
  }
@@ -5886,7 +5890,8 @@ static void define_pmu_regs(ARMCPU *cpu)
          .access = PL0_RW, .accessfn = pmreg_access,
          .type = ARM_CP_IO,
          .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
-        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
+        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
+                      PMCRLC,
          .writefn = pmcr_write, .raw_writefn = raw_write,
      };
      define_one_arm_cp_reg(cpu, &pmcr);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]