Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 May 2009 06:20:50 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r192794 - projects/mips/sys/mips/mips
Message-ID:  <200905260620.n4Q6KoWH048651@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Tue May 26 06:20:50 2009
New Revision: 192794
URL: http://svn.freebsd.org/changeset/base/192794

Log:
  - Preserve INT_MASK fields in Status register across
      context switches. They should be modified only by
      interrupt setup/teardown and pre_ithread/post_ithread
      functions

Modified:
  projects/mips/sys/mips/mips/exception.S
  projects/mips/sys/mips/mips/pm_machdep.c
  projects/mips/sys/mips/mips/swtch.S
  projects/mips/sys/mips/mips/vm_machdep.c

Modified: projects/mips/sys/mips/mips/exception.S
==============================================================================
--- projects/mips/sys/mips/mips/exception.S	Tue May 26 06:02:38 2009	(r192793)
+++ projects/mips/sys/mips/mips/exception.S	Tue May 26 06:20:50 2009	(r192794)
@@ -593,6 +593,19 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_S
 	jalr	k0
 	sw	a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp)
 	/* Why no AST processing here? */
+
+	/*
+	 * Update interrupt mask in saved status register
+	 * Some of interrupts could be disabled by
+	 * intr filters
+	 */
+	mfc0	a0, COP_0_STATUS_REG
+	and	a0, a0, SR_INT_MASK
+	RESTORE_REG(a1, SR, sp)
+	and	a1, a1, ~SR_INT_MASK
+	or	a1, a1, a0
+	SAVE_REG(a1, SR, sp)
+
 /*
  * Restore registers and return from the interrupt.
  */

Modified: projects/mips/sys/mips/mips/pm_machdep.c
==============================================================================
--- projects/mips/sys/mips/mips/pm_machdep.c	Tue May 26 06:02:38 2009	(r192793)
+++ projects/mips/sys/mips/mips/pm_machdep.c	Tue May 26 06:20:50 2009	(r192794)
@@ -482,7 +482,8 @@ exec_setregs(struct thread *td, u_long e
 //	td->td_frame->sr = SR_KSU_USER | SR_EXL | SR_INT_ENAB;
 //?	td->td_frame->sr |=  idle_mask & ALL_INT_MASK;
 #else
-	td->td_frame->sr = SR_KSU_USER | SR_EXL;// mips2 also did COP_0_BIT
+	td->td_frame->sr = SR_KSU_USER | SR_EXL | SR_INT_ENAB |
+	    (mips_rd_status() & ALL_INT_MASK);
 #endif
 #ifdef TARGET_OCTEON
 	td->td_frame->sr |= MIPS_SR_COP_2_BIT | MIPS32_SR_PX | MIPS_SR_UX |

Modified: projects/mips/sys/mips/mips/swtch.S
==============================================================================
--- projects/mips/sys/mips/mips/swtch.S	Tue May 26 06:02:38 2009	(r192793)
+++ projects/mips/sys/mips/mips/swtch.S	Tue May 26 06:20:50 2009	(r192794)
@@ -224,6 +224,11 @@ LEAF(fork_trampoline)
 	RESTORE_U_PCB_REG(s8, S8, k1)
 	RESTORE_U_PCB_REG(ra, RA, k1)
 	RESTORE_U_PCB_REG(sp, SP, k1)
+	li	k1, ~SR_INT_MASK
+	and	k0, k0, k1
+	mfc0	k1, COP_0_STATUS_REG
+	and	k1, k1, SR_INT_MASK
+	or	k0, k0, k1
 	mtc0	k0, COP_0_STATUS_REG	# switch to user mode (when eret...)
 	HAZARD_DELAY
 	sync
@@ -410,6 +415,10 @@ sw2:
 	 * In case there are CPU-specific registers that need
 	 * to be restored with the other registers do so here.
 	 */
+	mfc0	t0, COP_0_STATUS_REG
+	and	t0, t0, SR_INT_MASK
+	and	v0, v0, ~SR_INT_MASK
+	or	v0, v0, t0
 	mtc0	v0, COP_0_STATUS_REG
 	ITLBNOPFIX
 

Modified: projects/mips/sys/mips/mips/vm_machdep.c
==============================================================================
--- projects/mips/sys/mips/mips/vm_machdep.c	Tue May 26 06:02:38 2009	(r192793)
+++ projects/mips/sys/mips/mips/vm_machdep.c	Tue May 26 06:20:50 2009	(r192794)
@@ -148,7 +148,7 @@ cpu_fork(register struct thread *td1,reg
 	pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return;
 	pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td2;
 	pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td2->td_frame;
-	pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK;
+	pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status();
 	/*
 	 * FREEBSD_DEVELOPERS_FIXME:
 	 * Setup any other CPU-Specific registers (Not MIPS Standard)
@@ -298,11 +298,9 @@ cpu_set_upcall(struct thread *td, struct
 	pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return;
 	pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td;
 	pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td->td_frame;
-
-
 	/* Dont set IE bit in SR. sched lock release will take care of it */
-/* idle_mask is jmips pcb2->pcb_context.val[11] = (ALL_INT_MASK & idle_mask); */
-	pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK;
+	pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status();
+
 #ifdef TARGET_OCTEON
 	pcb2->pcb_context.val[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT |
 	  MIPS32_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905260620.n4Q6KoWH048651>