target/ppc: Decrementer fix BookE semantics
The decrementer store function has logic that short-cuts the timer if a
very small value is stored (0, 1, or 2) and raises an interrupt
directly. There are two problem with this on BookE.
First is that BookE says a decrementer interrupt should not be raised
on a store of 0, only of a decrement from 1. Second is that raising
the irq directly will bypass the auto-reload logic in the booke decr
timer function, breaking autoreload when 1 or 2 is stored.
Fix this by removing that small-value special case. It makes this
tricky logic even more difficult to reason about, and it hardly matters
for performance.
Cc: sdicaro@DDCI.com
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230530131214.373524-2-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 17dd1354c1
)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
parent
8cfe6d241b
commit
e916d29608
@ -843,11 +843,7 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
|
||||
}
|
||||
|
||||
/*
|
||||
* Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC
|
||||
* interrupt.
|
||||
*
|
||||
* If we get a really small DEC value, we can assume that by the time we
|
||||
* handled it we should inject an interrupt already.
|
||||
* Going from 1 -> 0 or 0 -> -1 is the event to generate a DEC interrupt.
|
||||
*
|
||||
* On MSB level based DEC implementations the MSB always means the interrupt
|
||||
* is pending, so raise it on those.
|
||||
@ -855,8 +851,7 @@ 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 ((value < 3) ||
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
|
||||
if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0
|
||||
&& signed_decr >= 0)) {
|
||||
(*raise_excp)(cpu);
|
||||
|
Loading…
Reference in New Issue
Block a user