aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-05-10 12:34:05 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-05-10 12:34:05 +0100
commit74e31681ba05ed1876818df30c581bc530554fb3 (patch)
tree5f0f240a917d226c47907960e1047bca7dfacf87 /target
parent4cc10cae64c51e17844dc4358481c393d7bf1ed4 (diff)
parent10fb1340b161682d64320a5976f88f68472410bf (diff)
downloadqemu-74e31681ba05ed1876818df30c581bc530554fb3.zip
qemu-74e31681ba05ed1876818df30c581bc530554fb3.tar.gz
qemu-74e31681ba05ed1876818df30c581bc530554fb3.tar.bz2
Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-20210505' into staging
qemu-sparc queue # gpg: Signature made Wed 05 May 2021 08:29:13 BST # gpg: using RSA key CC621AB98E82200D915CC9C45BC2C56FAE0F321F # gpg: issuer "mark.cave-ayland@ilande.co.uk" # gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" [full] # Primary key fingerprint: CC62 1AB9 8E82 200D 915C C9C4 5BC2 C56F AE0F 321F * remotes/mcayland/tags/qemu-sparc-20210505: hw/sparc*: Move cpu_check_irqs() to target/sparc/ hw/sparc64: Fix code style for checkpatch.pl hw/sparc64: Remove unused "hw/char/serial.h" header hw/sparc: Allow building without the leon3 machine hw/sparc/sun4m: Move each sun4m_hwdef definition in its class_init hw/sparc/sun4m: Fix code style for checkpatch.pl hw/sparc/sun4m: Register machine types in sun4m_machine_types[] hw/sparc/sun4m: Factor out sun4m_machine_class_init() hw/sparc/sun4m: Introduce Sun4mMachineClass hw/sparc/sun4m: Have sun4m machines inherit new TYPE_SUN4M_MACHINE Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/sparc/cpu.h6
-rw-r--r--target/sparc/int32_helper.c70
-rw-r--r--target/sparc/int64_helper.c66
-rw-r--r--target/sparc/trace-events12
4 files changed, 107 insertions, 47 deletions
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 4b22906..ff8ae73 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -615,15 +615,9 @@ int cpu_cwp_inc(CPUSPARCState *env1, int cwp);
int cpu_cwp_dec(CPUSPARCState *env1, int cwp);
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
-/* int_helper.c */
-void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno);
-
/* sun4m.c, sun4u.c */
void cpu_check_irqs(CPUSPARCState *env);
-/* leon3.c */
-void leon3_irq_ack(void *irq_manager, int intno);
-
#if defined (TARGET_SPARC64)
static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index 817a463..82e8418 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -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);
@@ -136,40 +169,3 @@ void sparc_cpu_do_interrupt(CPUState *cs)
}
#endif
}
-
-#if !defined(CONFIG_USER_ONLY)
-static void leon3_cache_control_int(CPUSPARCState *env)
-{
- uint32_t state = 0;
-
- if (env->cache_control & CACHE_CTRL_IF) {
- /* Instruction cache state */
- state = env->cache_control & CACHE_STATE_MASK;
- if (state == CACHE_ENABLED) {
- state = CACHE_FROZEN;
- trace_int_helper_icache_freeze();
- }
-
- env->cache_control &= ~CACHE_STATE_MASK;
- env->cache_control |= state;
- }
-
- if (env->cache_control & CACHE_CTRL_DF) {
- /* Data cache state */
- state = (env->cache_control >> 2) & CACHE_STATE_MASK;
- if (state == CACHE_ENABLED) {
- state = CACHE_FROZEN;
- trace_int_helper_dcache_freeze();
- }
-
- env->cache_control &= ~(CACHE_STATE_MASK << 2);
- env->cache_control |= (state << 2);
- }
-}
-
-void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno)
-{
- leon3_irq_ack(irq_manager, intno);
- leon3_cache_control_int(env);
-}
-#endif
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index 7fb8ab2..793e57c 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -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);
diff --git a/target/sparc/trace-events b/target/sparc/trace-events
index 6a064e2..75e7093 100644
--- a/target/sparc/trace-events
+++ b/target/sparc/trace-events
@@ -10,14 +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"
-
-# int32_helper.c
-int_helper_icache_freeze(void) "Instruction cache: freeze"
-int_helper_dcache_freeze(void) "Data cache: freeze"
+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"