From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MZ93C-0002ix-69 for qemu-devel@nongnu.org; Thu, 06 Aug 2009 15:54:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MZ93B-0002iY-KS for qemu-devel@nongnu.org; Thu, 06 Aug 2009 15:54:57 -0400 Received: from [199.232.76.173] (port=48829 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MZ93B-0002iQ-GH for qemu-devel@nongnu.org; Thu, 06 Aug 2009 15:54:57 -0400 Received: from fg-out-1718.google.com ([72.14.220.159]:4262) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MZ93A-0005bn-Rv for qemu-devel@nongnu.org; Thu, 06 Aug 2009 15:54:57 -0400 Received: by fg-out-1718.google.com with SMTP id d23so321631fga.8 for ; Thu, 06 Aug 2009 12:54:55 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: From: Blue Swirl Date: Thu, 6 Aug 2009 22:54:33 +0300 Message-ID: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] Re: sparc32 double "Set CPU IRQ 14" List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Artyom Tarasenko Cc: qemu-devel On Thu, Aug 6, 2009 at 12:35 PM, Artyom Tarasenko wrote: > I observe double "Set CPU IRQ 14" in the log. =C2=A0I don't see how =C2= =A0the > real harware would be able to generate the same irq twice, without > resetting it. I put a printf in cpuexec.c: > > #elif defined(TARGET_SPARC) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (= (interrupt_request & CPU_INTERRUPT_HARD) && > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0cpu_interrupts_enabled(env)) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int pil =3D env->interrupt_index & 15; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int type =3D env->interrupt_index & 0xf0; > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (((type =3D=3D TT_EXTINT) && > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (pil =3D=3D 15 || pil > env->psrpil)) || > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0type !=3D TT_EXTINT) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0env->interrupt_request &=3D ~CPU_INTERRUPT_HARD; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0env->exception_index =3D env->interrupt_index; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0do_interrupt(env); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0env->interrupt_index =3D 0; > #if !defined(CONFIG_USER_ONLY) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("cpuexec calls cp= u_check_irqs\n"); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0cpu_check_irqs(env); > #endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0next_tb =3D 0; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0} > > > And now my log looks like this: > > CPUIRQ: Raise CPU IRQ 14 > CPUIRQ: Set CPU IRQ 14 > cpuexec calls cpu_check_irqs > CPUIRQ: Set CPU IRQ 14 > > Does it look like cpuexec does an unnecessary call of cpu_check_irqs ? > > I've removed this call, and see no difference: OBP works the same, > OpenBIOS too, NetBSD boot log also seems to be the same. > > What this call is needed for? IIRC it's there to handle this situation: 1) interrupts are masked by the CPU up to some level (e.g. 12) 2) some lower level interrupts are active (level 10), but due to the mask CPU ignores them 3) a higher level interrupt arrives (level 14) and is delivered to the CPU 4) after the trap handling has started, the lower level (10) interrupt should be active again but it's still being ignored 5) when the interrupt mask is lowered, the lower level interrupt (10) should generate a trap But step #4 does not look correct, especially the call to cpu_check_irqs. The use of env->interrupt_index should be redesigned, maybe the interrupt mask could be recalculated in helper_wrpsr instead. Then step #4 would happen at the right time.