* [Qemu-devel] [PULL 1/7] target-arm: fix write helper for TLBI ALLE1IS
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 2/7] Fix interval interrupt of cadence ttc when timer is in decrement mode Peter Maydell
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
From: Sergey Fedorov <serge.fdrv@gmail.com>
TLBI ALLE1IS is an operation that does invalidate TLB entries on all PEs
in the same Inner Sharable domain, not just on the current CPU. So we
must use tlbiall_is_write() here.
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Message-id: 1435676538-31345-1-git-send-email-serge.fdrv@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index aa34159..b87afe7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2441,7 +2441,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
.access = PL2_W, .type = ARM_CP_NO_RAW,
- .writefn = tlbiall_write },
+ .writefn = tlbiall_is_write },
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
.access = PL1_W, .type = ARM_CP_NO_RAW,
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 2/7] Fix interval interrupt of cadence ttc when timer is in decrement mode
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 1/7] target-arm: fix write helper for TLBI ALLE1IS Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 3/7] target-arm: Split DISAS_YIELD from DISAS_WFE Peter Maydell
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
From: Johannes Schlatow <schlatow@ida.ing.tu-bs.de>
The interval interrupt is not set if the timer is in decrement mode.
This is because x >=0 and x < interval after leaving the while-loop.
Signed-off-by: Johannes Schlatow <schlatow@ida.ing.tu-bs.de>
Message-id: 20150630135821.51f3b4fd@johanness-latitude
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/timer/cadence_ttc.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index d46db3c..35bc880 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -208,15 +208,14 @@ static void cadence_timer_sync(CadenceTimerState *s)
s->reg_intr |= (2 << i);
}
}
+ if ((x < 0) || (x >= interval)) {
+ s->reg_intr |= (s->reg_count & COUNTER_CTRL_INT) ?
+ COUNTER_INTR_IV : COUNTER_INTR_OV;
+ }
while (x < 0) {
x += interval;
}
s->reg_value = (uint32_t)(x % interval);
-
- if (s->reg_value != x) {
- s->reg_intr |= (s->reg_count & COUNTER_CTRL_INT) ?
- COUNTER_INTR_IV : COUNTER_INTR_OV;
- }
cadence_timer_update(s);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 3/7] target-arm: Split DISAS_YIELD from DISAS_WFE
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 1/7] target-arm: fix write helper for TLBI ALLE1IS Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 2/7] Fix interval interrupt of cadence ttc when timer is in decrement mode Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 4/7] target-arm: Implement YIELD insn to yield in ARM and Thumb translators Peter Maydell
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
Currently we use DISAS_WFE for both WFE and YIELD instructions.
This is functionally correct because at the moment both of them
are implemented as "yield this CPU back to the top level loop so
another CPU has a chance to run". However it's rather confusing
that YIELD ends up calling HELPER(wfe), and if we ever want to
implement real behaviour for WFE and SEV it's likely to trip us up.
Split out the yield codepath to use DISAS_YIELD and a new
HELPER(yield) function, and have HELPER(wfe) call HELPER(yield).
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1435672316-3311-2-git-send-email-peter.maydell@linaro.org
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
target-arm/helper.h | 1 +
target-arm/op_helper.c | 18 +++++++++++++++---
target-arm/translate-a64.c | 6 ++++++
target-arm/translate.h | 1 +
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/target-arm/helper.h b/target-arm/helper.h
index fc885de..827b33d 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -50,6 +50,7 @@ DEF_HELPER_2(exception_internal, void, env, i32)
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
DEF_HELPER_1(wfi, void, env)
DEF_HELPER_1(wfe, void, env)
+DEF_HELPER_1(yield, void, env)
DEF_HELPER_1(pre_hvc, void, env)
DEF_HELPER_2(pre_smc, void, env, i32)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 7fa32c4..663c05d 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -323,13 +323,25 @@ void HELPER(wfi)(CPUARMState *env)
void HELPER(wfe)(CPUARMState *env)
{
- CPUState *cs = CPU(arm_env_get_cpu(env));
-
- /* Don't actually halt the CPU, just yield back to top
+ /* This is a hint instruction that is semantically different
+ * from YIELD even though we currently implement it identically.
+ * Don't actually halt the CPU, just yield back to top
* level loop. This is not going into a "low power state"
* (ie halting until some event occurs), so we never take
* a configurable trap to a different exception level.
*/
+ HELPER(yield)(env);
+}
+
+void HELPER(yield)(CPUARMState *env)
+{
+ ARMCPU *cpu = arm_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
+
+ /* This is a non-trappable hint instruction that generally indicates
+ * that the guest is currently busy-looping. Yield control back to the
+ * top level loop so that a more deserving VCPU has a chance to run.
+ */
cs->exception_index = EXCP_YIELD;
cpu_loop_exit(cs);
}
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e077f2d..689f2be 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1199,6 +1199,8 @@ static void handle_hint(DisasContext *s, uint32_t insn,
s->is_jmp = DISAS_WFI;
return;
case 1: /* YIELD */
+ s->is_jmp = DISAS_YIELD;
+ return;
case 2: /* WFE */
s->is_jmp = DISAS_WFE;
return;
@@ -11107,6 +11109,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
gen_a64_set_pc_im(dc->pc);
gen_helper_wfe(cpu_env);
break;
+ case DISAS_YIELD:
+ gen_a64_set_pc_im(dc->pc);
+ gen_helper_yield(cpu_env);
+ break;
case DISAS_WFI:
/* This is a special case because we don't want to just halt the CPU
* if trying to debug across a WFI.
diff --git a/target-arm/translate.h b/target-arm/translate.h
index bcdcf11..9ab978f 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -103,6 +103,7 @@ static inline int default_exception_el(DisasContext *s)
#define DISAS_WFE 7
#define DISAS_HVC 8
#define DISAS_SMC 9
+#define DISAS_YIELD 10
#ifdef TARGET_AARCH64
void a64_translate_init(void);
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 4/7] target-arm: Implement YIELD insn to yield in ARM and Thumb translators
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2015-07-06 9:59 ` [Qemu-devel] [PULL 3/7] target-arm: Split DISAS_YIELD from DISAS_WFE Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 5/7] hw/intc/arm_gic_common.c: Reset all registers Peter Maydell
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
Implement the YIELD instruction in the ARM and Thumb translators to
actually yield control back to the top level loop rather than being
a simple no-op. (We already do this for A64.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1435672316-3311-3-git-send-email-peter.maydell@linaro.org
---
target-arm/translate.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 971b6db..69ac18c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4080,6 +4080,10 @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
static void gen_nop_hint(DisasContext *s, int val)
{
switch (val) {
+ case 1: /* yield */
+ gen_set_pc_im(s, s->pc);
+ s->is_jmp = DISAS_YIELD;
+ break;
case 3: /* wfi */
gen_set_pc_im(s, s->pc);
s->is_jmp = DISAS_WFI;
@@ -11459,6 +11463,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
case DISAS_WFE:
gen_helper_wfe(cpu_env);
break;
+ case DISAS_YIELD:
+ gen_helper_yield(cpu_env);
+ break;
case DISAS_SWI:
gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
default_exception_el(dc));
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 5/7] hw/intc/arm_gic_common.c: Reset all registers
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2015-07-06 9:59 ` [Qemu-devel] [PULL 4/7] target-arm: Implement YIELD insn to yield in ARM and Thumb translators Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 6/7] arm_mptimer: Fix timer shutdown and mode change Peter Maydell
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
The arm_gic_common reset function was missing reset code for
several of the GIC's state fields:
* bpr[]
* abpr[]
* priority1[]
* priority2[]
* sgi_pending[]
* irq_target[] (SMP configurations only)
These probably went unnoticed because most guests will either
never touch them, or will write to them in the process of
configuring the GIC before enabling interrupts.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1435602345-32210-1-git-send-email-peter.maydell@linaro.org
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
hw/intc/arm_gic_common.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 044ad66..a64d071 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -123,7 +123,7 @@ static void arm_gic_common_realize(DeviceState *dev, Error **errp)
static void arm_gic_common_reset(DeviceState *dev)
{
GICState *s = ARM_GIC_COMMON(dev);
- int i;
+ int i, j;
memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
for (i = 0 ; i < s->num_cpu; i++) {
if (s->revision == REV_11MPCORE) {
@@ -135,15 +135,30 @@ static void arm_gic_common_reset(DeviceState *dev)
s->running_irq[i] = 1023;
s->running_priority[i] = 0x100;
s->cpu_ctlr[i] = 0;
+ s->bpr[i] = GIC_MIN_BPR;
+ s->abpr[i] = GIC_MIN_ABPR;
+ for (j = 0; j < GIC_INTERNAL; j++) {
+ s->priority1[j][i] = 0;
+ }
+ for (j = 0; j < GIC_NR_SGIS; j++) {
+ s->sgi_pending[j][i] = 0;
+ }
}
for (i = 0; i < GIC_NR_SGIS; i++) {
GIC_SET_ENABLED(i, ALL_CPU_MASK);
GIC_SET_EDGE_TRIGGER(i);
}
- if (s->num_cpu == 1) {
+
+ for (i = 0; i < ARRAY_SIZE(s->priority2); i++) {
+ s->priority2[i] = 0;
+ }
+
+ for (i = 0; i < GIC_MAXIRQ; i++) {
/* For uniprocessor GICs all interrupts always target the sole CPU */
- for (i = 0; i < GIC_MAXIRQ; i++) {
+ if (s->num_cpu == 1) {
s->irq_target[i] = 1;
+ } else {
+ s->irq_target[i] = 0;
}
}
s->ctlr = 0;
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 6/7] arm_mptimer: Fix timer shutdown and mode change
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2015-07-06 9:59 ` [Qemu-devel] [PULL 5/7] hw/intc/arm_gic_common.c: Reset all registers Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 9:59 ` [Qemu-devel] [PULL 7/7] arm_mptimer: Respect IT bit state Peter Maydell
2015-07-06 11:51 ` [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
From: Dmitry Osipenko <digetx@gmail.com>
The running timer can't be stopped because timer control code just
doesn't handle disabling the timer. Fix it by deleting the timer if
the enable bit is cleared.
The timer won't start periodic ticking if a ONE-SHOT -> PERIODIC mode
change happens after a one-shot tick was completed. Fix it by
re-starting ticking if the timer isn't ticking right now.
To avoid code churning, these two fixes are squashed in one commit.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/timer/arm_mptimer.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 8b93b3c..0e132b1 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -122,11 +122,18 @@ static void timerblock_write(void *opaque, hwaddr addr,
case 8: /* Control. */
old = tb->control;
tb->control = value;
- if (((old & 1) == 0) && (value & 1)) {
- if (tb->count == 0 && (tb->control & 2)) {
+ if (value & 1) {
+ if ((old & 1) && (tb->count != 0)) {
+ /* Do nothing if timer is ticking right now. */
+ break;
+ }
+ if (tb->control & 2) {
tb->count = tb->load;
}
timerblock_reload(tb, 1);
+ } else if (old & 1) {
+ /* Shutdown the timer. */
+ timer_del(tb->timer);
}
break;
case 12: /* Interrupt status. */
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 7/7] arm_mptimer: Respect IT bit state
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2015-07-06 9:59 ` [Qemu-devel] [PULL 6/7] arm_mptimer: Fix timer shutdown and mode change Peter Maydell
@ 2015-07-06 9:59 ` Peter Maydell
2015-07-06 11:51 ` [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 9:59 UTC (permalink / raw)
To: qemu-devel
From: Dmitry Osipenko <digetx@gmail.com>
The timer should fire the interrupt only if the IT (interrupt enable) bit
state of the control register is enabled.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/timer/arm_mptimer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 0e132b1..3e59c2a 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -38,7 +38,7 @@ static inline int get_current_cpu(ARMMPTimerState *s)
static inline void timerblock_update_irq(TimerBlock *tb)
{
- qemu_set_irq(tb->irq, tb->status);
+ qemu_set_irq(tb->irq, tb->status && (tb->control & 4));
}
/* Return conversion factor from mpcore timer ticks to qemu timer ticks. */
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PULL 0/7] target-arm queue
2015-07-06 9:59 [Qemu-devel] [PULL 0/7] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2015-07-06 9:59 ` [Qemu-devel] [PULL 7/7] arm_mptimer: Respect IT bit state Peter Maydell
@ 2015-07-06 11:51 ` Peter Maydell
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2015-07-06 11:51 UTC (permalink / raw)
To: QEMU Developers
On 6 July 2015 at 10:59, Peter Maydell <peter.maydell@linaro.org> wrote:
> target-arm queue before hardfreeze: these are pretty much all
> bugfixes.
>
> -- PMM
>
> The following changes since commit f50a1640fb82708a5d528dee1ace42a224b95b15:
>
> Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (2015-07-05 20:35:47 +0100)
>
> are available in the git repository at:
>
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150706
>
> for you to fetch changes up to 257621a9566054472d1d55a819880d0f9da02bda:
>
> arm_mptimer: Respect IT bit state (2015-07-06 10:26:35 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
> * TLBI ALLEI1IS should operate on all CPUs, not just this one
> * Fix interval interrupt of cadence ttc in decrement mode
> * Implement YIELD insn to yield in ARM and Thumb translators
> * ARM GIC: reset all registers
> * arm_mptimer: fix timer shutdown and mode change
> * arm_mptimer: respect IT bit state
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 9+ messages in thread