Module Name:    src
Committed By:   simonb
Date:           Tue Feb 16 06:06:58 UTC 2021

Modified Files:
        src/sys/arch/mips/include: asm.h profile.h
        src/sys/arch/mips/mips: mipsX_subr.S mips_fixup.c

Log Message:
Working kernel profiling for n32/n64:
 - Different MCOUNT and _KERN_MCOUNT macros for n32/n64.
 - Don't profile mipsXX_lwp_trampoline().
 - Allow a few new instructions in the stub fixups.


To generate a diff of this commit:
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/mips/include/asm.h
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/mips/include/profile.h
cvs rdiff -u -r1.112 -r1.113 src/sys/arch/mips/mips/mipsX_subr.S
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/mips/mips/mips_fixup.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/mips/include/asm.h
diff -u src/sys/arch/mips/include/asm.h:1.63 src/sys/arch/mips/include/asm.h:1.64
--- src/sys/arch/mips/include/asm.h:1.63	Thu Feb  4 08:51:42 2021
+++ src/sys/arch/mips/include/asm.h	Tue Feb 16 06:06:58 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: asm.h,v 1.63 2021/02/04 08:51:42 skrll Exp $	*/
+/*	$NetBSD: asm.h,v 1.64 2021/02/16 06:06:58 simonb Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -57,6 +57,10 @@
 #include <sys/cdefs.h>		/* for API selection */
 #include <mips/regdef.h>
 
+#if defined(_KERNEL_OPT)
+#include "opt_gprof.h"
+#endif
+
 #define	__BIT(n)	(1 << (n))
 #define	__BITS(hi,lo)	((~((~0)<<((hi)+1)))&((~0)<<(lo)))
 
@@ -66,24 +70,45 @@
 
 /*
  * Define -pg profile entry code.
- * Must always be noreorder, must never use a macro instruction
- * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
+ * Must always be noreorder, must never use a macro instruction.
+ */
+#if defined(__mips_o32)		/* Old 32-bit ABI */
+/*
+ * The old ABI version must also decrement two less words off the
+ * stack and the final addiu to t9 must always equal the size of this
+ * _KERN_MCOUNT.
  */
 #define	_KERN_MCOUNT						\
 	.set	push;						\
 	.set	noreorder;					\
 	.set	noat;						\
-	subu	sp,sp,16;					\
+	subu	sp,16;						\
 	sw	t9,12(sp);					\
 	move	AT,ra;						\
 	lui	t9,%hi(_mcount); 				\
 	addiu	t9,t9,%lo(_mcount);				\
 	jalr	t9;						\
-	nop;							\
+	 nop;							\
 	lw	t9,4(sp);					\
-	addiu	sp,sp,8;					\
-	addiu	t9,t9,40;					\
+	addiu	sp,8;						\
+	addiu	t9,40;						\
+	.set	pop;
+#elif defined(__mips_o64)	/* Old 64-bit ABI */
+# error yeahnah
+#else				/* New (n32/n64) ABI */
+/*
+ * The new ABI version just needs to put the return address in AT and
+ * call _mcount().
+ */
+#define	_KERN_MCOUNT						\
+	.set	push;						\
+	.set	noreorder;					\
+	.set	noat;						\
+	move	AT,ra;						\
+	jal	_mcount;					\
+	 nop;							\
 	.set	pop;
+#endif /* n32/n64 */
 
 #ifdef GPROF
 #define	MCOUNT _KERN_MCOUNT

Index: src/sys/arch/mips/include/profile.h
diff -u src/sys/arch/mips/include/profile.h:1.22 src/sys/arch/mips/include/profile.h:1.23
--- src/sys/arch/mips/include/profile.h:1.22	Sun Jul 26 08:08:41 2020
+++ src/sys/arch/mips/include/profile.h	Tue Feb 16 06:06:58 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: profile.h,v 1.22 2020/07/26 08:08:41 simonb Exp $	*/
+/*	$NetBSD: profile.h,v 1.23 2021/02/16 06:06:58 simonb Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -37,6 +37,10 @@
 #ifndef _MIPS_PROFILE_H_
 #define	_MIPS_PROFILE_H_
 
+#if defined(_KERNEL_OPT)
+#include "opt_gprof.h"
+#endif
+
 #ifdef _KERNEL
  /*
   *  Declare non-profiled _splhigh() /_splx() entrypoints for _mcount.
@@ -61,35 +65,78 @@
     _KERNEL_MCOUNT_DECL \
     void __attribute__((unused)) __mcount
 
+#ifdef __mips_o32	/* 32-bit version */
+#define	MCOUNT \
+	__asm(".globl _mcount;" \
+	      ".type _mcount,@function;" \
+	      "_mcount:;" \
+	      ".set noreorder;" \
+	      ".set noat;" \
+	      _PROF_CPLOAD \
+	      "addu $29,$29,-16;" \
+	      "sw $4,8($29);" \
+	      "sw $5,12($29);" \
+	      "sw $6,16($29);" \
+	      "sw $7,20($29);" \
+	      "sw $1,0($29);" \
+	      "sw $31,4($29);" \
+	      "move $5,$31;" \
+	      "move $4,$1;" \
+	      "jal __mcount;" \
+	      " nop;" \
+	      "lw $4,8($29);" \
+	      "lw $5,12($29);" \
+	      "lw $6,16($29);" \
+	      "lw $7,20($29);" \
+	      "lw $31,4($29);" \
+	      "lw $1,0($29);" \
+	      "addu $29,$29,24;" \
+	      "j $31;" \
+	      " move $31,$1;" \
+	      ".set reorder;" \
+	      ".set at");
+#else /* 64-bit */
+#ifdef __mips_o64
+# error yeahnah
+#endif
 #define	MCOUNT \
 	__asm(".globl _mcount;" \
-	".type _mcount,@function;" \
-	"_mcount:;" \
-	".set noreorder;" \
-	".set noat;" \
-	_PROF_CPLOAD \
-	"addu $29,$29,-16;" \
-	"sw $4,8($29);" \
-	"sw $5,12($29);" \
-	"sw $6,16($29);" \
-	"sw $7,20($29);" \
-	"sw $1,0($29);" \
-	"sw $31,4($29);" \
-	"move $5,$31;" \
-	"move $4,$1;" \
-	"jal __mcount;" \
-	"nop;" \
-	"lw $4,8($29);" \
-	"lw $5,12($29);" \
-	"lw $6,16($29);" \
-	"lw $7,20($29);" \
-	"lw $31,4($29);" \
-	"lw $1,0($29);" \
-	"addu $29,$29,24;" \
-	"j $31;" \
-	"move $31,$1;" \
-	".set reorder;" \
-	".set at");
+	      ".type _mcount,@function;" \
+	      "_mcount:;" \
+	      ".set noreorder;" \
+	      ".set noat;" \
+	      _PROF_CPLOAD \
+	      "daddu $29,$29,-80;"\
+	      "sd $4,16($29);" \
+	      "sd $5,24($29);" \
+	      "sd $6,32($29);" \
+	      "sd $7,40($29);" \
+	      "sd $8,48($29);" \
+	      "sd $9,56($29);" \
+	      "sd $10,64($29);" \
+	      "sd $11,72($29);" \
+	      "sd $1,0($29);" \
+	      "sd $31,8($29);" \
+	      "move $5,$31;" \
+	      "move $4,$1;" \
+	      "jal __mcount;" \
+	      " nop;" \
+	      "ld $4,16($29);" \
+	      "ld $5,24($29);" \
+	      "ld $6,32($29);" \
+	      "ld $7,40($29);" \
+	      "ld $8,48($29);" \
+	      "ld $9,56($29);" \
+	      "ld $10,64($29);" \
+	      "ld $11,72($29);" \
+	      "ld $31,8($29);" \
+	      "ld $1,0($29);" \
+	      "daddu $29,$29,80;" \
+	      "j $31;" \
+	      " move $31,$1;" \
+	      ".set reorder;" \
+	      ".set at");
+#endif /* 64-bit */
 
 #ifdef _KERNEL
 /*

Index: src/sys/arch/mips/mips/mipsX_subr.S
diff -u src/sys/arch/mips/mips/mipsX_subr.S:1.112 src/sys/arch/mips/mips/mipsX_subr.S:1.113
--- src/sys/arch/mips/mips/mipsX_subr.S:1.112	Sun Sep 27 10:35:57 2020
+++ src/sys/arch/mips/mips/mipsX_subr.S	Tue Feb 16 06:06:58 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: mipsX_subr.S,v 1.112 2020/09/27 10:35:57 mrg Exp $	*/
+/*	$NetBSD: mipsX_subr.S,v 1.113 2021/02/16 06:06:58 simonb Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -117,7 +117,7 @@
  */
 
 #include <mips/asm.h>
-RCSID("$NetBSD: mipsX_subr.S,v 1.112 2020/09/27 10:35:57 mrg Exp $")
+RCSID("$NetBSD: mipsX_subr.S,v 1.113 2021/02/16 06:06:58 simonb Exp $")
 
 #include "opt_cputype.h"
 #include "opt_ddb.h"
@@ -2627,8 +2627,10 @@ END(MIPSX(tlb_record_asids))
  * Arrange for a function to be invoked neatly, after a cpu_switch().
  * Call the service function with one argument, specified by the s0
  * and s1 respectively.  There is no need register save operation.
+ * XXX - Not profiled because we pass an arg in with v0 which isn't
+ *       preserved by _mcount()
  */
-LEAF(MIPSX(lwp_trampoline))
+LEAF_NOPROFILE(MIPSX(lwp_trampoline))
 	PTR_ADDU sp, -CALLFRAME_SIZ
 
 	# Call lwp_startup(), with args from cpu_switchto()/cpu_lwp_fork()

Index: src/sys/arch/mips/mips/mips_fixup.c
diff -u src/sys/arch/mips/mips/mips_fixup.c:1.20 src/sys/arch/mips/mips/mips_fixup.c:1.21
--- src/sys/arch/mips/mips/mips_fixup.c:1.20	Sat Apr  6 03:06:26 2019
+++ src/sys/arch/mips/mips/mips_fixup.c	Tue Feb 16 06:06:58 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_fixup.c,v 1.20 2019/04/06 03:06:26 thorpej Exp $	*/
+/*	$NetBSD: mips_fixup.c,v 1.21 2021/02/16 06:06:58 simonb Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.20 2019/04/06 03:06:26 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_fixup.c,v 1.21 2021/02/16 06:06:58 simonb Exp $");
 
 #include "opt_mips3_wired.h"
 #include "opt_multiprocessor.h"
@@ -286,11 +286,25 @@ mips_fixup_addr(const uint32_t *stubp)
 	 *	dmtc0	at, $22
 	 *	jr	t9
 	 *	nop
+	 *
+	 * A profiled n32/n64 stub will start with:
+	 *	move	ta, ra
+	 *	jal	_mcount
+	 *	 nop
 	 */
 	mips_reg_t regs[32];
 	uint32_t used = 1 |__BIT(_R_A0)|__BIT(_R_A1)|__BIT(_R_A2)|__BIT(_R_A3);
 	size_t n;
 	const char *errstr = "mips";
+
+#ifdef GPROF
+	static uint32_t mcount_addr = 0;
+	extern void _mcount(u_long, u_long);	/* XXX decl */
+
+	if (mcount_addr == 0)
+		mcount_addr = (uint32_t)(uintptr_t)_mcount & 0x0fffffff;
+#endif /* GPROF */
+
 	/*
 	 * This is basically a small MIPS emulator for those instructions
 	 * that might be in a stub routine.
@@ -361,6 +375,14 @@ mips_fixup_addr(const uint32_t *stubp)
 				goto out;
 			}
 			break;
+#ifdef GPROF
+		case OP_JAL:
+			if (insn.JType.target << 2 != mcount_addr) {
+				errstr = "JAL-non-_mcount";
+				goto out;
+			}
+			break;
+#endif /* GPROF */
 		case OP_SPECIAL:
 			switch (insn.RType.func) {
 			case OP_JALR:
@@ -404,6 +426,19 @@ mips_fixup_addr(const uint32_t *stubp)
 					goto out;
 				}
 				break;
+#ifdef GPROF
+			case OP_OR:
+				if (insn.RType.rt != 0) {
+					errstr = "NON-MOVE OR";
+					goto out;
+				}
+				if (insn.RType.rd != 1 ||
+				    insn.RType.rs != 31) {
+					errstr = "NON at,ra MOVE";
+					goto out;
+				}
+				break;
+#endif /* GPROF */
 			case OP_DSLL:
 			default:
 				errstr = "SPECIAL";

Reply via email to