hw/ppc/ppc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
HDEC interrupts are edge-triggered on HDECR underflow (notably different
from DEC which is level-triggered).
HDEC interrupts already clear the irq on delivery so that does not need
to be changed.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/ppc/ppc.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 7b7db30f95..f4fe1767d6 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -789,8 +789,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
QEMUTimer *timer,
void (*raise_excp)(void *),
void (*lower_excp)(PowerPCCPU *),
- target_ulong decr, target_ulong value,
- int nr_bits)
+ uint32_t flags, target_ulong decr,
+ target_ulong value, int nr_bits)
{
CPUPPCState *env = &cpu->env;
ppc_tb_t *tb_env = env->tb_env;
@@ -820,15 +820,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
* On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers
* an edge interrupt, so raise it here too.
*/
- if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
- ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0
+ if (((flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
+ ((flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0
&& signed_decr >= 0)) {
(*raise_excp)(cpu);
return;
}
/* On MSB level based systems a 0 for the MSB stops interrupt delivery */
- if (signed_value >= 0 && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
+ if (signed_value >= 0 && (flags & PPC_DECR_UNDERFLOW_LEVEL)) {
(*lower_excp)(cpu);
}
@@ -847,8 +847,8 @@ static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr,
ppc_tb_t *tb_env = cpu->env.tb_env;
__cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
- tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr,
- value, nr_bits);
+ tb_env->decr_timer->cb, &cpu_ppc_decr_lower,
+ tb_env->flags, decr, value, nr_bits);
}
void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value)
@@ -877,8 +877,10 @@ static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr,
ppc_tb_t *tb_env = cpu->env.tb_env;
if (tb_env->hdecr_timer != NULL) {
+ /* HDECR (Book3S 64bit) is edge-based, not level like DECR */
__cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower,
+ PPC_DECR_UNDERFLOW_TRIGGERED,
hdecr, value, nr_bits);
}
}
--
2.40.1
On 6/25/23 09:20, Nicholas Piggin wrote: > HDEC interrupts are edge-triggered on HDECR underflow (notably different > from DEC which is level-triggered). > > HDEC interrupts already clear the irq on delivery so that does not need > to be changed. > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- Queued in gitlab.com/danielhb/qemu/tree/ppc-next. Thanks, Daniel > hw/ppc/ppc.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c > index 7b7db30f95..f4fe1767d6 100644 > --- a/hw/ppc/ppc.c > +++ b/hw/ppc/ppc.c > @@ -789,8 +789,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, > QEMUTimer *timer, > void (*raise_excp)(void *), > void (*lower_excp)(PowerPCCPU *), > - target_ulong decr, target_ulong value, > - int nr_bits) > + uint32_t flags, target_ulong decr, > + target_ulong value, int nr_bits) > { > CPUPPCState *env = &cpu->env; > ppc_tb_t *tb_env = env->tb_env; > @@ -820,15 +820,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, > * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers > * an edge interrupt, so raise it here too. > */ > - if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || > - ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 > + if (((flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || > + ((flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 > && signed_decr >= 0)) { > (*raise_excp)(cpu); > return; > } > > /* On MSB level based systems a 0 for the MSB stops interrupt delivery */ > - if (signed_value >= 0 && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) { > + if (signed_value >= 0 && (flags & PPC_DECR_UNDERFLOW_LEVEL)) { > (*lower_excp)(cpu); > } > > @@ -847,8 +847,8 @@ static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr, > ppc_tb_t *tb_env = cpu->env.tb_env; > > __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, > - tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr, > - value, nr_bits); > + tb_env->decr_timer->cb, &cpu_ppc_decr_lower, > + tb_env->flags, decr, value, nr_bits); > } > > void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value) > @@ -877,8 +877,10 @@ static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr, > ppc_tb_t *tb_env = cpu->env.tb_env; > > if (tb_env->hdecr_timer != NULL) { > + /* HDECR (Book3S 64bit) is edge-based, not level like DECR */ > __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, > tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower, > + PPC_DECR_UNDERFLOW_TRIGGERED, > hdecr, value, nr_bits); > } > }
On 6/25/23 14:20, Nicholas Piggin wrote: > HDEC interrupts are edge-triggered on HDECR underflow (notably different > from DEC which is level-triggered). yes. > HDEC interrupts already clear the irq on delivery so that does not need > to be changed. > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Thanks, C. > --- > hw/ppc/ppc.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c > index 7b7db30f95..f4fe1767d6 100644 > --- a/hw/ppc/ppc.c > +++ b/hw/ppc/ppc.c > @@ -789,8 +789,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, > QEMUTimer *timer, > void (*raise_excp)(void *), > void (*lower_excp)(PowerPCCPU *), > - target_ulong decr, target_ulong value, > - int nr_bits) > + uint32_t flags, target_ulong decr, > + target_ulong value, int nr_bits) > { > CPUPPCState *env = &cpu->env; > ppc_tb_t *tb_env = env->tb_env; > @@ -820,15 +820,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, > * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers > * an edge interrupt, so raise it here too. > */ > - if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || > - ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 > + if (((flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || > + ((flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 > && signed_decr >= 0)) { > (*raise_excp)(cpu); > return; > } > > /* On MSB level based systems a 0 for the MSB stops interrupt delivery */ > - if (signed_value >= 0 && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) { > + if (signed_value >= 0 && (flags & PPC_DECR_UNDERFLOW_LEVEL)) { > (*lower_excp)(cpu); > } > > @@ -847,8 +847,8 @@ static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr, > ppc_tb_t *tb_env = cpu->env.tb_env; > > __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, > - tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr, > - value, nr_bits); > + tb_env->decr_timer->cb, &cpu_ppc_decr_lower, > + tb_env->flags, decr, value, nr_bits); > } > > void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value) > @@ -877,8 +877,10 @@ static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr, > ppc_tb_t *tb_env = cpu->env.tb_env; > > if (tb_env->hdecr_timer != NULL) { > + /* HDECR (Book3S 64bit) is edge-based, not level like DECR */ > __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, > tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower, > + PPC_DECR_UNDERFLOW_TRIGGERED, > hdecr, value, nr_bits); > } > }
© 2016 - 2024 Red Hat, Inc.