summaryrefslogtreecommitdiffstats
path: root/hw/sparc/leon3.c
diff options
context:
space:
mode:
authorPeter Maydell2021-05-10 13:34:05 +0200
committerPeter Maydell2021-05-10 13:34:05 +0200
commit74e31681ba05ed1876818df30c581bc530554fb3 (patch)
tree5f0f240a917d226c47907960e1047bca7dfacf87 /hw/sparc/leon3.c
parentMerge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into ... (diff)
parenthw/sparc*: Move cpu_check_irqs() to target/sparc/ (diff)
downloadqemu-74e31681ba05ed1876818df30c581bc530554fb3.tar.gz
qemu-74e31681ba05ed1876818df30c581bc530554fb3.tar.xz
qemu-74e31681ba05ed1876818df30c581bc530554fb3.zip
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 'hw/sparc/leon3.c')
-rw-r--r--hw/sparc/leon3.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index eb5d2a6792..7b4dec1721 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -136,7 +136,36 @@ static void main_cpu_reset(void *opaque)
env->regbase[6] = s->sp;
}
-void leon3_irq_ack(void *irq_manager, int intno)
+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);
+ }
+}
+
+static void leon3_irq_ack(void *irq_manager, int intno)
{
grlib_irqmp_ack((DeviceState *)irq_manager, intno);
}
@@ -180,6 +209,12 @@ static void leon3_set_pil_in(void *opaque, int n, int level)
}
}
+static void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno)
+{
+ leon3_irq_ack(irq_manager, intno);
+ leon3_cache_control_int(env);
+}
+
static void leon3_generic_hw_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;