hw/sparc*: Move cpu_check_irqs() to target/sparc/

Since cpu_check_irqs() doesn't reference to anything outside
of CPUSPARCState, it better belongs to the architectural code
in target/, rather than the hardware specific code in hw/.

Note: while we moved the trace events, we don't rename them.

Remark: this allows us to build the leon3 machine stand alone,
fixing this link failure (because cpu_check_irqs is defined in
hw/sparc/sun4m.c which is only built when CONFIG_SUN4M is selected):

  /usr/bin/ld: target_sparc_win_helper.c.o: in function `cpu_put_psr':
  target/sparc/win_helper.c:91: undefined reference to `cpu_check_irqs'

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210428141655.387430-5-f4bug@amsat.org>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
Philippe Mathieu-Daudé 2021-04-28 16:16:54 +02:00 committed by Mark Cave-Ayland
parent 5aa7f68a2d
commit 10fb1340b1
7 changed files with 107 additions and 104 deletions

View File

@ -170,38 +170,6 @@ static void nvram_init(Nvram *nvram, uint8_t *macaddr,
}
}
void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
/* We should be holding the BQL before we mess with IRQs */
g_assert(qemu_mutex_iothread_locked());
if (env->pil_in && (env->interrupt_index == 0 ||
(env->interrupt_index & ~15) == TT_EXTINT)) {
unsigned int i;
for (i = 15; i > 0; i--) {
if (env->pil_in & (1 << i)) {
int old_interrupt = env->interrupt_index;
env->interrupt_index = TT_EXTINT | i;
if (old_interrupt != env->interrupt_index) {
cs = env_cpu(env);
trace_sun4m_cpu_interrupt(i);
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
cs = env_cpu(env);
trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
static void cpu_kick_irq(SPARCCPU *cpu)
{
CPUSPARCState *env = &cpu->env;

View File

@ -1,8 +1,6 @@
# See docs/devel/tracing.txt for syntax documentation.
# sun4m.c
sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"

View File

@ -34,72 +34,6 @@
#define TICK_MAX 0x7fffffffffffffffULL
void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
uint32_t pil = env->pil_in |
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
/* We should be holding the BQL before we mess with IRQs */
g_assert(qemu_mutex_iothread_locked());
/* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
if (env->ivec_status & 0x20) {
return;
}
cs = env_cpu(env);
/*
* check if TM or SM in SOFTINT are set
* setting these also causes interrupt 14
*/
if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
pil |= 1 << 14;
}
/*
* The bit corresponding to psrpil is (1<< psrpil),
* the next bit is (2 << psrpil).
*/
if (pil < (2 << env->psrpil)) {
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
trace_sparc64_cpu_check_irqs_reset_irq(env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
return;
}
if (cpu_interrupts_enabled(env)) {
unsigned int i;
for (i = 15; i > env->psrpil; i--) {
if (pil & (1 << i)) {
int old_interrupt = env->interrupt_index;
int new_interrupt = TT_EXTINT | i;
if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
&& ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
trace_sparc64_cpu_check_irqs_noset_irq(env->tl,
cpu_tsptr(env)->tt,
new_interrupt);
} else if (old_interrupt != new_interrupt) {
env->interrupt_index = new_interrupt;
trace_sparc64_cpu_check_irqs_set_irq(i, old_interrupt,
new_interrupt);
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
trace_sparc64_cpu_check_irqs_disabled(pil, env->pil_in, env->softint,
env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
static void cpu_kick_irq(SPARCCPU *cpu)
{
CPUState *cs = CPU(cpu);

View File

@ -9,10 +9,6 @@ sun4u_iommu_mem_write(uint64_t addr, uint64_t val, int size) "addr: 0x%"PRIx64"
sun4u_iommu_translate(uint64_t addr, uint64_t trans_addr, uint64_t tte) "xlate 0x%"PRIx64" => pa 0x%"PRIx64" tte: 0x%"PRIx64
# sparc64.c
sparc64_cpu_check_irqs_reset_irq(int intno) "Reset CPU IRQ (current interrupt 0x%x)"
sparc64_cpu_check_irqs_noset_irq(uint32_t tl, uint32_t tt, int intno) "Not setting CPU IRQ: TL=%d current 0x%x >= pending 0x%x"
sparc64_cpu_check_irqs_set_irq(unsigned int i, int old, int new) "Set CPU IRQ %d old=0x%x new=0x%x"
sparc64_cpu_check_irqs_disabled(uint32_t pil, uint32_t pil_in, uint32_t softint, int intno) "Interrupts disabled, pil=0x%08x pil_in=0x%08x softint=0x%08x current interrupt 0x%x"
sparc64_cpu_ivec_raise_irq(int irq) "Raise IVEC IRQ %d"
sparc64_cpu_ivec_lower_irq(int irq) "Lower IVEC IRQ %d"
sparc64_cpu_tick_irq_disabled(void) "tick_irq: softint disabled"

View File

@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "cpu.h"
#include "trace.h"
#include "exec/log.h"
@ -64,6 +65,38 @@ static const char *excp_name_str(int32_t exception_index)
return excp_names[exception_index];
}
void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
/* We should be holding the BQL before we mess with IRQs */
g_assert(qemu_mutex_iothread_locked());
if (env->pil_in && (env->interrupt_index == 0 ||
(env->interrupt_index & ~15) == TT_EXTINT)) {
unsigned int i;
for (i = 15; i > 0; i--) {
if (env->pil_in & (1 << i)) {
int old_interrupt = env->interrupt_index;
env->interrupt_index = TT_EXTINT | i;
if (old_interrupt != env->interrupt_index) {
cs = env_cpu(env);
trace_sun4m_cpu_interrupt(i);
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
cs = env_cpu(env);
trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
void sparc_cpu_do_interrupt(CPUState *cs)
{
SPARCCPU *cpu = SPARC_CPU(cs);

View File

@ -62,6 +62,72 @@ static const char * const excp_names[0x80] = {
};
#endif
void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
uint32_t pil = env->pil_in |
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
/* We should be holding the BQL before we mess with IRQs */
g_assert(qemu_mutex_iothread_locked());
/* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
if (env->ivec_status & 0x20) {
return;
}
cs = env_cpu(env);
/*
* check if TM or SM in SOFTINT are set
* setting these also causes interrupt 14
*/
if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
pil |= 1 << 14;
}
/*
* The bit corresponding to psrpil is (1<< psrpil),
* the next bit is (2 << psrpil).
*/
if (pil < (2 << env->psrpil)) {
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
trace_sparc64_cpu_check_irqs_reset_irq(env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
return;
}
if (cpu_interrupts_enabled(env)) {
unsigned int i;
for (i = 15; i > env->psrpil; i--) {
if (pil & (1 << i)) {
int old_interrupt = env->interrupt_index;
int new_interrupt = TT_EXTINT | i;
if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
&& ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
trace_sparc64_cpu_check_irqs_noset_irq(env->tl,
cpu_tsptr(env)->tt,
new_interrupt);
} else if (old_interrupt != new_interrupt) {
env->interrupt_index = new_interrupt;
trace_sparc64_cpu_check_irqs_set_irq(i, old_interrupt,
new_interrupt);
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
trace_sparc64_cpu_check_irqs_disabled(pil, env->pil_in, env->softint,
env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
void sparc_cpu_do_interrupt(CPUState *cs)
{
SPARCCPU *cpu = SPARC_CPU(cs);

View File

@ -10,10 +10,18 @@ mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, u
mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=0x%"PRIx64" secondary context=0x%"PRIx64" address=0x%"PRIx64
mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at 0x%"PRIx64" -> 0x%"PRIx64", mmu_idx=%d tl=%d primary context=0x%"PRIx64" secondary context=0x%"PRIx64
# int32_helper.c
sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
# int64_helper.c
int_helper_set_softint(uint32_t softint) "new 0x%08x"
int_helper_clear_softint(uint32_t softint) "new 0x%08x"
int_helper_write_softint(uint32_t softint) "new 0x%08x"
sparc64_cpu_check_irqs_reset_irq(int intno) "Reset CPU IRQ (current interrupt 0x%x)"
sparc64_cpu_check_irqs_noset_irq(uint32_t tl, uint32_t tt, int intno) "Not setting CPU IRQ: TL=%d current 0x%x >= pending 0x%x"
sparc64_cpu_check_irqs_set_irq(unsigned int i, int old, int new) "Set CPU IRQ %d old=0x%x new=0x%x"
sparc64_cpu_check_irqs_disabled(uint32_t pil, uint32_t pil_in, uint32_t softint, int intno) "Interrupts disabled, pil=0x%08x pil_in=0x%08x softint=0x%08x current interrupt 0x%x"
# win_helper.c
win_helper_gregset_error(uint32_t pstate) "ERROR in get_gregset: active pstate bits=0x%x"