* [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8
@ 2014-08-18 8:11 Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit Peter Crosthwaite
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
This patch series continues on from Alistairs original PMCCNTR patch
work. The counter is extended to 64-bit. Also adds support for the
PMCCFILTR_EL0 register which allows the counter to be
disabled based on the current EL
V3:
-Tidy up the arm_ccnt_enabled()
-Fixed an old commit message refering to the CCNT_ENABLED
macro
-Do EL change sync in pstate_write instead of in multiple
code paths.
-Addressed PMM V2 review
V2:
-Fix some typos identified by Christopher Covington
-Convert the CCNT_ENABLED macro to the arm_ccnt_enabled
function
Alistair Francis (6):
target-arm: Make the ARM PMCCNTR register 64-bit
target-arm: Implement PMCCNTR_EL0 and related registers
target-arm: Add arm_ccnt_enabled function
target-arm: Implement pmccntr_sync function
target-arm: Remove old code and replace with new functions
target-arm: Implement pmccfiltr_write function
Peter Crosthwaite (2):
arm: Implement PMCCNTR 32b read-modify-write
target-arm: Call pmccntr_sync() when swapping ELs
target-arm/cpu.h | 30 +++++++++-
target-arm/helper.c | 166 +++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 159 insertions(+), 37 deletions(-)
--
2.0.1.1.gfbfc394
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
@ 2014-08-18 8:12 ` Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 2/8] arm: Implement PMCCNTR 32b read-modify-write Peter Crosthwaite
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:12 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
This makes the PMCCNTR register 64-bit to allow for the
64-bit ARMv8 version.
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
---
changed since v2:
Fixed indentation of muldiv64s
target-arm/cpu.h | 2 +-
target-arm/helper.c | 19 +++++++++----------
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 79205ba..b903558 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -223,7 +223,7 @@ typedef struct CPUARMState {
/* If the counter is enabled, this stores the last time the counter
* was reset. Otherwise it stores the counter value
*/
- uint32_t c15_ccnt;
+ uint64_t c15_ccnt;
} cp15;
struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f630d96..42368db 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -550,11 +550,10 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
- /* Don't computer the number of ticks in user mode */
- uint32_t temp_ticks;
+ uint64_t temp_ticks;
- temp_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
- get_ticks_per_sec() / 1000000;
+ temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+ get_ticks_per_sec(), 1000000);
if (env->cp15.c9_pmcr & PMCRE) {
/* If the counter is enabled */
@@ -586,15 +585,15 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- uint32_t total_ticks;
+ uint64_t total_ticks;
if (!(env->cp15.c9_pmcr & PMCRE)) {
/* Counter is disabled, do not change value */
return env->cp15.c15_ccnt;
}
- total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
- get_ticks_per_sec() / 1000000;
+ total_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+ get_ticks_per_sec(), 1000000);
if (env->cp15.c9_pmcr & PMCRD) {
/* Increment once every 64 processor clock cycles */
@@ -606,7 +605,7 @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
- uint32_t total_ticks;
+ uint64_t total_ticks;
if (!(env->cp15.c9_pmcr & PMCRE)) {
/* Counter is disabled, set the absolute value */
@@ -614,8 +613,8 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
return;
}
- total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
- get_ticks_per_sec() / 1000000;
+ total_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+ get_ticks_per_sec(), 1000000);
if (env->cp15.c9_pmcr & PMCRD) {
/* Increment once every 64 processor clock cycles */
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 2/8] arm: Implement PMCCNTR 32b read-modify-write
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit Peter Crosthwaite
@ 2014-08-18 8:12 ` Peter Crosthwaite
2014-08-18 8:13 ` [Qemu-devel] [PATCH target-arm v3 3/8] target-arm: Implement PMCCNTR_EL0 and related registers Peter Crosthwaite
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:12 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
The register is now 64bit, however a 32 bit write to the register
should leave the higher bits unchanged. The open coded write handler
does not implement this, so we need to read-modify-write accordingly.
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
target-arm/helper.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 42368db..99e8e97 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -622,6 +622,15 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
env->cp15.c15_ccnt = total_ticks - value;
}
+
+static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ uint64_t cur_val = pmccntr_read(env, NULL);
+
+ pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
+}
+
#endif
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -760,7 +769,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
{ .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
.access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
- .readfn = pmccntr_read, .writefn = pmccntr_write,
+ .readfn = pmccntr_read, .writefn = pmccntr_write32,
.accessfn = pmreg_access },
#endif
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 3/8] target-arm: Implement PMCCNTR_EL0 and related registers
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 2/8] arm: Implement PMCCNTR 32b read-modify-write Peter Crosthwaite
@ 2014-08-18 8:13 ` Peter Crosthwaite
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 4/8] target-arm: Add arm_ccnt_enabled function Peter Crosthwaite
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:13 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
This patch adds support for the ARMv8 version of the PMCCNTR and
related registers. It also starts to implement the PMCCFILTR_EL0
register.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
Changed since v2:
Widen cpu state fields as needed
Reorder CP def fields
Add NO_MIGRATES to CP dups.
target-arm/cpu.h | 5 +++--
target-arm/helper.c | 45 +++++++++++++++++++++++++++++++++++++++------
2 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b903558..b84fff7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -191,8 +191,8 @@ typedef struct CPUARMState {
uint64_t par_el1; /* Translation result. */
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
- uint32_t c9_pmcr; /* performance monitor control register */
- uint32_t c9_pmcnten; /* perf monitor counter enables */
+ uint64_t c9_pmcr; /* performance monitor control register */
+ uint64_t c9_pmcnten; /* perf monitor counter enables */
uint32_t c9_pmovsr; /* perf monitor overflow status */
uint32_t c9_pmxevtyper; /* perf monitor event type */
uint32_t c9_pmuserenr; /* perf monitor user enable */
@@ -224,6 +224,7 @@ typedef struct CPUARMState {
* was reset. Otherwise it stores the counter value
*/
uint64_t c15_ccnt;
+ uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
} cp15;
struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 99e8e97..7363c8d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -742,16 +742,28 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
* or PL0_RO as appropriate and then check PMUSERENR in the helper fn.
*/
{ .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
- .access = PL0_RW, .resetvalue = 0,
- .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+ .access = PL0_RW, .type = ARM_CP_NO_MIGRATE,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
.writefn = pmcntenset_write,
.accessfn = pmreg_access,
.raw_writefn = raw_write },
+ { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
+ .access = PL0_RW, .accessfn = pmreg_access,
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
+ .writefn = pmcntenset_write, .raw_writefn = raw_write },
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
- .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+ .access = PL0_RW,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
.accessfn = pmreg_access,
.writefn = pmcntenclr_write,
.type = ARM_CP_NO_MIGRATE },
+ { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
+ .access = PL0_RW, .accessfn = pmreg_access,
+ .type = ARM_CP_NO_MIGRATE,
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+ .writefn = pmcntenclr_write },
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
.accessfn = pmreg_access,
@@ -771,7 +783,18 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
.readfn = pmccntr_read, .writefn = pmccntr_write32,
.accessfn = pmreg_access },
+ { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
+ .access = PL0_RW, .accessfn = pmreg_access,
+ .type = ARM_CP_IO,
+ .readfn = pmccntr_read, .writefn = pmccntr_write, },
#endif
+ { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
+ .access = PL0_RW, .accessfn = pmreg_access,
+ .type = ARM_CP_IO,
+ .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
+ .resetvalue = 0, },
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
.access = PL0_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
@@ -2346,13 +2369,23 @@ void register_cp_regs_for_features(ARMCPU *cpu)
#ifndef CONFIG_USER_ONLY
ARMCPRegInfo pmcr = {
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
- .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
- .type = ARM_CP_IO,
- .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
+ .access = PL0_RW,
+ .type = ARM_CP_IO | ARM_CP_NO_MIGRATE,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
.accessfn = pmreg_access, .writefn = pmcr_write,
.raw_writefn = raw_write,
};
+ ARMCPRegInfo pmcr64 = {
+ .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
+ .access = PL0_RW, .accessfn = pmreg_access,
+ .type = ARM_CP_IO,
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
+ .resetvalue = cpu->midr & 0xff000000,
+ .writefn = pmcr_write, .raw_writefn = raw_write,
+ };
define_one_arm_cp_reg(cpu, &pmcr);
+ define_one_arm_cp_reg(cpu, &pmcr64);
#endif
ARMCPRegInfo clidr = {
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 4/8] target-arm: Add arm_ccnt_enabled function
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
` (2 preceding siblings ...)
2014-08-18 8:13 ` [Qemu-devel] [PATCH target-arm v3 3/8] target-arm: Implement PMCCNTR_EL0 and related registers Peter Crosthwaite
@ 2014-08-18 8:14 ` Peter Crosthwaite
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function Peter Crosthwaite
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:14 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
Include a helper function to determine if the CCNT counter
is enabled as well as the constants used to mask the pmccfiltr_el0
and c9_pmxevtyper registers.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
Changed since v2 (PMM review):
Blank line for readability
Use switch instead of cascading ifs.
Use true and false.
Drop extraneous #endif #if
target-arm/helper.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7363c8d..0318816 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -547,6 +547,50 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
}
#ifndef CONFIG_USER_ONLY
+
+#define PMCCFILTR_NSH 0x8000000
+#define PMCCFILTR_P 0x80000000
+#define PMCCFILTR_U 0x40000000
+
+#define PMXEVTYPER_P 0x80000000
+#define PMXEVTYPER_U 0x40000000
+
+static inline bool arm_ccnt_enabled(CPUARMState *env)
+{
+ /* This does not support checking for the secure/non-secure
+ * components of the PMCCFILTR_EL0 register
+ */
+
+ if (!(env->cp15.c9_pmcr & PMCRE)) {
+ return false;
+ }
+
+ switch (arm_current_pl(env)) {
+ case 2:
+ if (!(env->cp15.pmccfiltr_el0 & PMCCFILTR_NSH)) {
+ return false;
+ } else {
+ break;
+ }
+ case 1:
+ if (env->cp15.pmccfiltr_el0 & PMCCFILTR_P ||
+ env->cp15.c9_pmxevtyper & PMXEVTYPER_P) {
+ return false;
+ } else {
+ break;
+ }
+ case 0:
+ if (env->cp15.pmccfiltr_el0 & PMCCFILTR_U ||
+ env->cp15.c9_pmxevtyper & PMXEVTYPER_U) {
+ return false;
+ } else {
+ break;
+ }
+ }
+
+ return true;
+}
+
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
` (3 preceding siblings ...)
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 4/8] target-arm: Add arm_ccnt_enabled function Peter Crosthwaite
@ 2014-08-18 8:14 ` Peter Crosthwaite
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 6/8] target-arm: Remove old code and replace with new functions Peter Crosthwaite
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:14 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
This is used to synchronise the PMCCNTR counter and swap its
state between enabled and disabled if required. It must always
be called twice, both before and after any logic that could
change the state of the PMCCNTR counter.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
Changed since v2:
Move prototype further up cpu.h
Remembering that the c15_ccnt register stores the last time
the counter was reset if enabled. If disabled it stores the
counter value (when it was disabled).
The three use cases are as below:
--
Starts enabled/disabled and is staying enabled/disabled
--
The two calls to pmccntr_sync cancel each other out.
Each call implements this logic:
env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt
Which expands to:
env->cp15.c15_ccnt = temp_ticks -
(temp_ticks - env->cp15.c15_ccnt)
env->cp15.c15_ccnt = env->cp15.c15_ccnt
--
Starts enabled, gets disabled
--
The logic is run during the first call while during
the second call it is not. That means that c15_ccnt
changes from storing the last time the counter was
reset, to storing the absolute value of the counter.
--
Starts disabled, gets enabled
--
During the fist call no changes are made, while during
the second call the register is changed. This changes it
from storing the absolute value to storing the last time
the counter was reset.
target-arm/cpu.h | 11 +++++++++++
target-arm/helper.c | 23 +++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b84fff7..5bc2afe 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -352,6 +352,17 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
+/**
+ * pmccntr_sync
+ * @cpu: ARMCPU
+ *
+ * Syncronises the counter in the PMCCNTR. This must always be called twice,
+ * once before any action that might effect the timer and again afterwards.
+ * The function is used to swap the state of the register if required.
+ * This only happens when not in user mode (!CONFIG_USER_ONLY)
+ */
+void pmccntr_sync(CPUARMState *env);
+
/* SCTLR bit meanings. Several bits have been reused in newer
* versions of the architecture; in that case we define constants
* for both old and new bit meanings. Code which tests against those
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0318816..60b8310 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -591,6 +591,23 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
return true;
}
+void pmccntr_sync(CPUARMState *env)
+{
+ uint64_t temp_ticks;
+
+ temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+ get_ticks_per_sec(), 1000000);
+
+ if (env->cp15.c9_pmcr & PMCRD) {
+ /* Increment once every 64 processor clock cycles */
+ temp_ticks /= 64;
+ }
+
+ if (arm_ccnt_enabled(env)) {
+ env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
+ }
+}
+
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -675,6 +692,12 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
}
+#else /* CONFIG_USER_ONLY */
+
+void pmccntr_sync(CPUARMState *env)
+{
+}
+
#endif
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 6/8] target-arm: Remove old code and replace with new functions
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
` (4 preceding siblings ...)
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function Peter Crosthwaite
@ 2014-08-18 8:15 ` Peter Crosthwaite
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 7/8] target-arm: Implement pmccfiltr_write function Peter Crosthwaite
2014-08-18 8:16 ` [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs Peter Crosthwaite
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:15 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
Remove the old PMCCNTR code and replace it with calls to the new
pmccntr_sync() and arm_ccnt_enabled() functions.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
Changed since v2:
Commit msg tweaks.
target-arm/helper.c | 27 ++++-----------------------
1 file changed, 4 insertions(+), 23 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 60b8310..4f23f7c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -611,20 +611,7 @@ void pmccntr_sync(CPUARMState *env)
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
- uint64_t temp_ticks;
-
- temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
- get_ticks_per_sec(), 1000000);
-
- if (env->cp15.c9_pmcr & PMCRE) {
- /* If the counter is enabled */
- if (env->cp15.c9_pmcr & PMCRD) {
- /* Increment once every 64 processor clock cycles */
- env->cp15.c15_ccnt = (temp_ticks/64) - env->cp15.c15_ccnt;
- } else {
- env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
- }
- }
+ pmccntr_sync(env);
if (value & PMCRC) {
/* The counter has been reset */
@@ -635,20 +622,14 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->cp15.c9_pmcr &= ~0x39;
env->cp15.c9_pmcr |= (value & 0x39);
- if (env->cp15.c9_pmcr & PMCRE) {
- if (env->cp15.c9_pmcr & PMCRD) {
- /* Increment once every 64 processor clock cycles */
- temp_ticks /= 64;
- }
- env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
- }
+ pmccntr_sync(env);
}
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
uint64_t total_ticks;
- if (!(env->cp15.c9_pmcr & PMCRE)) {
+ if (!arm_ccnt_enabled(env)) {
/* Counter is disabled, do not change value */
return env->cp15.c15_ccnt;
}
@@ -668,7 +649,7 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
{
uint64_t total_ticks;
- if (!(env->cp15.c9_pmcr & PMCRE)) {
+ if (!arm_ccnt_enabled(env)) {
/* Counter is disabled, set the absolute value */
env->cp15.c15_ccnt = value;
return;
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 7/8] target-arm: Implement pmccfiltr_write function
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
` (5 preceding siblings ...)
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 6/8] target-arm: Remove old code and replace with new functions Peter Crosthwaite
@ 2014-08-18 8:15 ` Peter Crosthwaite
2014-08-18 8:16 ` [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs Peter Crosthwaite
7 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:15 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
From: Alistair Francis <alistair.francis@xilinx.com>
This is the function that is called when writing to the
PMCCFILTR_EL0 register
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
target-arm/helper.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 4f23f7c..dd2a2dd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -681,6 +681,14 @@ void pmccntr_sync(CPUARMState *env)
#endif
+static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ pmccntr_sync(env);
+ env->cp15.pmccfiltr_el0 = value & 0x7E000000;
+ pmccntr_sync(env);
+}
+
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -839,6 +847,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
#endif
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
+ .writefn = pmccfiltr_write,
.access = PL0_RW, .accessfn = pmreg_access,
.type = ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
` (6 preceding siblings ...)
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 7/8] target-arm: Implement pmccfiltr_write function Peter Crosthwaite
@ 2014-08-18 8:16 ` Peter Crosthwaite
2014-08-18 8:32 ` Peter Maydell
7 siblings, 1 reply; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:16 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, cov, alistair23
Call the pmccntr_sync() when the EL changes. All Runtime changes
of EL are done as a pstate_write so we can catch these EL-change side
effects here.
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
target-arm/cpu.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5bc2afe..2533fc0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -503,12 +503,24 @@ static inline uint32_t pstate_read(CPUARMState *env)
static inline void pstate_write(CPUARMState *env, uint32_t val)
{
+#ifndef CONFIG_USER_ONLY
+ bool pmccntr_need_sync = (env->pstate ^ val) & PSTATE_M;
+
+ if (pmccntr_need_sync) {
+ pmccntr_sync(env);
+ }
+#endif
env->ZF = (~val) & PSTATE_Z;
env->NF = val;
env->CF = (val >> 29) & 1;
env->VF = (val << 3) & 0x80000000;
env->daif = val & PSTATE_DAIF;
env->pstate = val & ~CACHED_PSTATE_BITS;
+#ifndef CONFIG_USER_ONLY
+ if (pmccntr_need_sync) {
+ pmccntr_sync(env);
+ }
+#endif
}
/* Return the current CPSR value. */
--
2.0.1.1.gfbfc394
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs
2014-08-18 8:16 ` [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs Peter Crosthwaite
@ 2014-08-18 8:32 ` Peter Maydell
2014-08-18 8:36 ` Peter Crosthwaite
0 siblings, 1 reply; 11+ messages in thread
From: Peter Maydell @ 2014-08-18 8:32 UTC (permalink / raw)
To: Peter Crosthwaite
Cc: Alistair Francis, Alex Bennée, QEMU Developers,
Christopher Covington
On 18 August 2014 09:16, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
> Call the pmccntr_sync() when the EL changes. All Runtime changes
> of EL are done as a pstate_write so we can catch these EL-change side
> effects here.
Hmm. This probably clashes badly with Alex's cleanup of how we
handle pstate writes... I'm not sure I really want more side
effects in pstate_write(), either; the ones we have in cpsr_write()
are pretty annoying (makes migration load awkward).
> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> ---
>
> target-arm/cpu.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 5bc2afe..2533fc0 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -503,12 +503,24 @@ static inline uint32_t pstate_read(CPUARMState *env)
>
> static inline void pstate_write(CPUARMState *env, uint32_t val)
> {
> +#ifndef CONFIG_USER_ONLY
> + bool pmccntr_need_sync = (env->pstate ^ val) & PSTATE_M;
> +
> + if (pmccntr_need_sync) {
> + pmccntr_sync(env);
> + }
> +#endif
> env->ZF = (~val) & PSTATE_Z;
> env->NF = val;
> env->CF = (val >> 29) & 1;
> env->VF = (val << 3) & 0x80000000;
> env->daif = val & PSTATE_DAIF;
> env->pstate = val & ~CACHED_PSTATE_BITS;
> +#ifndef CONFIG_USER_ONLY
> + if (pmccntr_need_sync) {
> + pmccntr_sync(env);
> + }
> +#endif
> }
>
> /* Return the current CPSR value. */
> --
> 2.0.1.1.gfbfc394
thanks
-- PMM
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs
2014-08-18 8:32 ` Peter Maydell
@ 2014-08-18 8:36 ` Peter Crosthwaite
0 siblings, 0 replies; 11+ messages in thread
From: Peter Crosthwaite @ 2014-08-18 8:36 UTC (permalink / raw)
To: Peter Maydell
Cc: Alistair Francis, Alex Bennée, QEMU Developers,
Christopher Covington
On Mon, Aug 18, 2014 at 6:32 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 18 August 2014 09:16, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
>> Call the pmccntr_sync() when the EL changes. All Runtime changes
>> of EL are done as a pstate_write so we can catch these EL-change side
>> effects here.
>
> Hmm. This probably clashes badly with Alex's cleanup of how we
> handle pstate writes... I'm not sure I really want more side
> effects in pstate_write(), either; the ones we have in cpsr_write()
> are pretty annoying (makes migration load awkward).
>
Well what exactly can we do then? Do we need another fn between el
change logic and pstate_write where we can dump el change side
effects?
At the end of the day, changing EL does have side effects so we need a
common place for this stuff.
Regards,
Peter
>> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>> ---
>>
>> target-arm/cpu.h | 12 ++++++++++++
>> 1 file changed, 12 insertions(+)
>>
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index 5bc2afe..2533fc0 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -503,12 +503,24 @@ static inline uint32_t pstate_read(CPUARMState *env)
>>
>> static inline void pstate_write(CPUARMState *env, uint32_t val)
>> {
>> +#ifndef CONFIG_USER_ONLY
>> + bool pmccntr_need_sync = (env->pstate ^ val) & PSTATE_M;
>> +
>> + if (pmccntr_need_sync) {
>> + pmccntr_sync(env);
>> + }
>> +#endif
>> env->ZF = (~val) & PSTATE_Z;
>> env->NF = val;
>> env->CF = (val >> 29) & 1;
>> env->VF = (val << 3) & 0x80000000;
>> env->daif = val & PSTATE_DAIF;
>> env->pstate = val & ~CACHED_PSTATE_BITS;
>> +#ifndef CONFIG_USER_ONLY
>> + if (pmccntr_need_sync) {
>> + pmccntr_sync(env);
>> + }
>> +#endif
>> }
>>
>> /* Return the current CPSR value. */
>> --
>> 2.0.1.1.gfbfc394
>
> thanks
> -- PMM
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-08-18 8:36 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-18 8:11 [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8 Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit Peter Crosthwaite
2014-08-18 8:12 ` [Qemu-devel] [PATCH target-arm v3 2/8] arm: Implement PMCCNTR 32b read-modify-write Peter Crosthwaite
2014-08-18 8:13 ` [Qemu-devel] [PATCH target-arm v3 3/8] target-arm: Implement PMCCNTR_EL0 and related registers Peter Crosthwaite
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 4/8] target-arm: Add arm_ccnt_enabled function Peter Crosthwaite
2014-08-18 8:14 ` [Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function Peter Crosthwaite
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 6/8] target-arm: Remove old code and replace with new functions Peter Crosthwaite
2014-08-18 8:15 ` [Qemu-devel] [PATCH target-arm v3 7/8] target-arm: Implement pmccfiltr_write function Peter Crosthwaite
2014-08-18 8:16 ` [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs Peter Crosthwaite
2014-08-18 8:32 ` Peter Maydell
2014-08-18 8:36 ` Peter Crosthwaite
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).