xref: /minix3/sys/arch/i386/include/profile.h (revision f6aac1c3b5ca21b829888677e8ee6bc9cda07e52)
1*f6aac1c3SLionel Sambuc /*	$NetBSD: profile.h,v 1.33 2007/12/20 23:46:13 ad Exp $	*/
2*f6aac1c3SLionel Sambuc 
3*f6aac1c3SLionel Sambuc /*
4*f6aac1c3SLionel Sambuc  * Copyright (c) 1992, 1993
5*f6aac1c3SLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
6*f6aac1c3SLionel Sambuc  *
7*f6aac1c3SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
8*f6aac1c3SLionel Sambuc  * modification, are permitted provided that the following conditions
9*f6aac1c3SLionel Sambuc  * are met:
10*f6aac1c3SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
11*f6aac1c3SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
12*f6aac1c3SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
13*f6aac1c3SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
14*f6aac1c3SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
15*f6aac1c3SLionel Sambuc  * 3. Neither the name of the University nor the names of its contributors
16*f6aac1c3SLionel Sambuc  *    may be used to endorse or promote products derived from this software
17*f6aac1c3SLionel Sambuc  *    without specific prior written permission.
18*f6aac1c3SLionel Sambuc  *
19*f6aac1c3SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*f6aac1c3SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*f6aac1c3SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*f6aac1c3SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*f6aac1c3SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*f6aac1c3SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*f6aac1c3SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*f6aac1c3SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*f6aac1c3SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*f6aac1c3SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*f6aac1c3SLionel Sambuc  * SUCH DAMAGE.
30*f6aac1c3SLionel Sambuc  *
31*f6aac1c3SLionel Sambuc  *	@(#)profile.h	8.1 (Berkeley) 6/11/93
32*f6aac1c3SLionel Sambuc  */
33*f6aac1c3SLionel Sambuc 
34*f6aac1c3SLionel Sambuc #ifdef _KERNEL_OPT
35*f6aac1c3SLionel Sambuc #include "opt_multiprocessor.h"
36*f6aac1c3SLionel Sambuc #endif
37*f6aac1c3SLionel Sambuc 
38*f6aac1c3SLionel Sambuc #ifdef _KERNEL
39*f6aac1c3SLionel Sambuc #include <machine/cpufunc.h>
40*f6aac1c3SLionel Sambuc #include <machine/lock.h>
41*f6aac1c3SLionel Sambuc #endif
42*f6aac1c3SLionel Sambuc 
43*f6aac1c3SLionel Sambuc #define	_MCOUNT_DECL static __inline void _mcount
44*f6aac1c3SLionel Sambuc 
45*f6aac1c3SLionel Sambuc #ifdef __ELF__
46*f6aac1c3SLionel Sambuc #define MCOUNT_ENTRY	"__mcount"
47*f6aac1c3SLionel Sambuc #define MCOUNT_COMPAT	__weak_alias(mcount, __mcount)
48*f6aac1c3SLionel Sambuc #else
49*f6aac1c3SLionel Sambuc #define MCOUNT_ENTRY	"mcount"
50*f6aac1c3SLionel Sambuc #define MCOUNT_COMPAT	/* nothing */
51*f6aac1c3SLionel Sambuc #endif
52*f6aac1c3SLionel Sambuc 
53*f6aac1c3SLionel Sambuc #define	MCOUNT \
54*f6aac1c3SLionel Sambuc MCOUNT_COMPAT								\
55*f6aac1c3SLionel Sambuc extern void mcount(void) __asm(MCOUNT_ENTRY)				\
56*f6aac1c3SLionel Sambuc 	__attribute__((__no_instrument_function__));			\
57*f6aac1c3SLionel Sambuc void									\
58*f6aac1c3SLionel Sambuc mcount(void)								\
59*f6aac1c3SLionel Sambuc {									\
60*f6aac1c3SLionel Sambuc 	int selfpc, frompcindex;					\
61*f6aac1c3SLionel Sambuc 	int eax, ecx, edx;						\
62*f6aac1c3SLionel Sambuc 									\
63*f6aac1c3SLionel Sambuc 	__asm volatile("movl %%eax,%0" : "=g" (eax));			\
64*f6aac1c3SLionel Sambuc 	__asm volatile("movl %%ecx,%0" : "=g" (ecx));			\
65*f6aac1c3SLionel Sambuc 	__asm volatile("movl %%edx,%0" : "=g" (edx));			\
66*f6aac1c3SLionel Sambuc 	/*								\
67*f6aac1c3SLionel Sambuc 	 * find the return address for mcount,				\
68*f6aac1c3SLionel Sambuc 	 * and the return address for mcount's caller.			\
69*f6aac1c3SLionel Sambuc 	 *								\
70*f6aac1c3SLionel Sambuc 	 * selfpc = pc pushed by mcount call				\
71*f6aac1c3SLionel Sambuc 	 */								\
72*f6aac1c3SLionel Sambuc 	__asm volatile("movl 4(%%ebp),%0" : "=r" (selfpc));		\
73*f6aac1c3SLionel Sambuc 	/*								\
74*f6aac1c3SLionel Sambuc 	 * frompcindex = pc pushed by call into self.			\
75*f6aac1c3SLionel Sambuc 	 */								\
76*f6aac1c3SLionel Sambuc 	__asm volatile("movl (%%ebp),%0;movl 4(%0),%0"			\
77*f6aac1c3SLionel Sambuc 	    : "=r" (frompcindex));					\
78*f6aac1c3SLionel Sambuc 	_mcount((u_long)frompcindex, (u_long)selfpc);			\
79*f6aac1c3SLionel Sambuc 									\
80*f6aac1c3SLionel Sambuc 	__asm volatile("movl %0,%%edx" : : "g" (edx));			\
81*f6aac1c3SLionel Sambuc 	__asm volatile("movl %0,%%ecx" : : "g" (ecx));			\
82*f6aac1c3SLionel Sambuc 	__asm volatile("movl %0,%%eax" : : "g" (eax));			\
83*f6aac1c3SLionel Sambuc }
84*f6aac1c3SLionel Sambuc 
85*f6aac1c3SLionel Sambuc #ifdef _KERNEL
86*f6aac1c3SLionel Sambuc #ifdef MULTIPROCESSOR
87*f6aac1c3SLionel Sambuc __cpu_simple_lock_t __mcount_lock;
88*f6aac1c3SLionel Sambuc 
89*f6aac1c3SLionel Sambuc static inline void
MCOUNT_ENTER_MP(void)90*f6aac1c3SLionel Sambuc MCOUNT_ENTER_MP(void)
91*f6aac1c3SLionel Sambuc {
92*f6aac1c3SLionel Sambuc 	__cpu_simple_lock(&__mcount_lock);
93*f6aac1c3SLionel Sambuc 	__insn_barrier();
94*f6aac1c3SLionel Sambuc }
95*f6aac1c3SLionel Sambuc 
96*f6aac1c3SLionel Sambuc static inline void
MCOUNT_EXIT_MP(void)97*f6aac1c3SLionel Sambuc MCOUNT_EXIT_MP(void)
98*f6aac1c3SLionel Sambuc {
99*f6aac1c3SLionel Sambuc 	__insn_barrier();
100*f6aac1c3SLionel Sambuc 	__mcount_lock = __SIMPLELOCK_UNLOCKED;
101*f6aac1c3SLionel Sambuc }
102*f6aac1c3SLionel Sambuc #else
103*f6aac1c3SLionel Sambuc #define MCOUNT_ENTER_MP()
104*f6aac1c3SLionel Sambuc #define MCOUNT_EXIT_MP()
105*f6aac1c3SLionel Sambuc #endif
106*f6aac1c3SLionel Sambuc 
107*f6aac1c3SLionel Sambuc static inline void
mcount_disable_intr(void)108*f6aac1c3SLionel Sambuc mcount_disable_intr(void)
109*f6aac1c3SLionel Sambuc {
110*f6aac1c3SLionel Sambuc 	__asm volatile("cli");
111*f6aac1c3SLionel Sambuc }
112*f6aac1c3SLionel Sambuc 
113*f6aac1c3SLionel Sambuc static inline u_long
mcount_read_psl(void)114*f6aac1c3SLionel Sambuc mcount_read_psl(void)
115*f6aac1c3SLionel Sambuc {
116*f6aac1c3SLionel Sambuc 	u_long	ef;
117*f6aac1c3SLionel Sambuc 
118*f6aac1c3SLionel Sambuc 	__asm volatile("pushfl; popl %0" : "=r" (ef));
119*f6aac1c3SLionel Sambuc 	return (ef);
120*f6aac1c3SLionel Sambuc }
121*f6aac1c3SLionel Sambuc 
122*f6aac1c3SLionel Sambuc static inline void
mcount_write_psl(u_long ef)123*f6aac1c3SLionel Sambuc mcount_write_psl(u_long ef)
124*f6aac1c3SLionel Sambuc {
125*f6aac1c3SLionel Sambuc 	__asm volatile("pushl %0; popfl" : : "r" (ef));
126*f6aac1c3SLionel Sambuc }
127*f6aac1c3SLionel Sambuc 
128*f6aac1c3SLionel Sambuc #define	MCOUNT_ENTER							\
129*f6aac1c3SLionel Sambuc 	s = (int)mcount_read_psl();					\
130*f6aac1c3SLionel Sambuc 	mcount_disable_intr();						\
131*f6aac1c3SLionel Sambuc 	MCOUNT_ENTER_MP();
132*f6aac1c3SLionel Sambuc 
133*f6aac1c3SLionel Sambuc #define	MCOUNT_EXIT							\
134*f6aac1c3SLionel Sambuc 	MCOUNT_EXIT_MP();						\
135*f6aac1c3SLionel Sambuc 	mcount_write_psl(s);
136*f6aac1c3SLionel Sambuc 
137*f6aac1c3SLionel Sambuc #endif /* _KERNEL */
138