Module Name:    src
Committed By:   matt
Date:           Mon Apr 11 23:12:41 UTC 2011

Modified Files:
        src/sys/arch/evbmips/rmixl: machdep.c

Log Message:
Add code to fixup the text segment to replace loads
from L_CPU(MIPS_CURLWP) or curlwp->l_cpu with
loads from COP0 register OSSCRATCH.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbmips/rmixl/machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbmips/rmixl/machdep.c
diff -u src/sys/arch/evbmips/rmixl/machdep.c:1.7 src/sys/arch/evbmips/rmixl/machdep.c:1.8
--- src/sys/arch/evbmips/rmixl/machdep.c:1.7	Sun Feb 20 07:48:35 2011
+++ src/sys/arch/evbmips/rmixl/machdep.c	Mon Apr 11 23:12:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.7 2011/02/20 07:48:35 matt Exp $	*/
+/*	$NetBSD: machdep.c,v 1.8 2011/04/11 23:12:41 matt Exp $	*/
 
 /*
  * Copyright 2001, 2002 Wasabi Systems, Inc.
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.7 2011/02/20 07:48:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.8 2011/04/11 23:12:41 matt Exp $");
 
 #define __INTR_PRIVATE
 
@@ -108,12 +108,14 @@
 #include "ksyms.h"
 
 #if NKSYMS || defined(DDB) || defined(LKM)
-#include <machine/db_machdep.h>
+#include <mips/db_machdep.h>
 #include <ddb/db_extern.h>
 #endif
 
-#include <machine/cpu.h>
-#include <machine/psl.h>
+#include <mips/cpu.h>
+#include <mips/psl.h>
+#include <mips/cache.h>
+#include <mips/mips_opcode.h>
 
 #include "com.h"
 #if NCOM == 0
@@ -228,6 +230,7 @@
 static void rmixl_wakeup_info_print(volatile rmixlfw_cpu_wakeup_info_t *);
 #endif	/* MACHDEP_DEBUG */
 #endif	/* MULTIPROCESSOR */
+static void rmixl_fixup_curcpu(void);
 
 /*
  * Do all the stuff that locore normally does before calling main().
@@ -414,6 +417,7 @@
 		:: "r"(&cpu_info_store), "n"(MIPS_COP_0_OSSCRATCH));
 	mips_fixup_exceptions(rmixl_fixup_cop0_oscratch);
 #endif
+	rmixl_fixup_curcpu();
 }
 
 /*
@@ -483,6 +487,43 @@
 #endif /* MULTIPROCESSOR */
 
 /*
+ * The following changes all	lX	rN, L_CPU(MIPS_CURLWP) [curlwp->l_cpu]
+ * to			     	[d]mfc0	rN, $22 [MIPS_COP_0_OSSCRATCH]
+ *
+ * the mfc0 is 3 cycles shorter than the load.
+ */
+#define	LOAD_CURCPU_0	((MIPS_CURLWP_REG << 21) | offsetof(lwp_t, l_cpu))
+#define	MFC0_CURCPU_0	((OP_COP0 << 26) | (MIPS_COP_0_OSSCRATCH << 11))
+#ifdef _LP64
+#define	LOAD_CURCPU	((uint32_t)(OP_LD << 26) | LOAD_CURCPU_0)
+#define	MFC0_CURCPU	((uint32_t)(OP_DMF << 21) | MFC0_CURCPU_0)
+#else
+#define	LOAD_CURCPU	((uint32_t)(OP_LW << 26) | LOAD_CURCPU_0)
+#define	MFC0_CURCPU	((uint32_t)(OP_MF << 21) | MFC0_CURCPU_0)
+#endif
+#define	LOAD_CURCPU_MASK	0xffe0ffff
+
+static void
+rmixl_fixup_curcpu(void)
+{
+	extern uint32_t _ftext[];
+	extern uint32_t _etext[];
+
+	for (uint32_t *insnp = _ftext; insnp < _etext; insnp++) {
+		const uint32_t insn = *insnp;
+		if (__predict_false((insn & LOAD_CURCPU_MASK) == LOAD_CURCPU)) {
+			/*
+			 * Since the register to loaded is located in bits
+			 * 16-20 for the mfc0 and the load instruction we can
+			 * just change the instruction bits around it.
+			 */
+			*insnp = insn ^ LOAD_CURCPU ^ MFC0_CURCPU;
+			mips_icache_sync_range((vaddr_t)insnp, 4);
+		}
+	}
+}
+
+/*
  * ram_seg_resv - cut reserved regions out of segs, fragmenting as needed
  *
  * we simply build a new table of segs, then copy it back over the given one

Reply via email to