From dc9d16844c13cbe99ea9cdd0057b048e5b5a68bf Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 27 Oct 2008 02:36:03 +0000 Subject: [PATCH] Add support for kernel profiling for both AIM and BookE. Obtained from: Juniper Networks, Inc (BookE support). --- sys/powerpc/aim/locore.S | 5 +- sys/powerpc/booke/locore.S | 5 +- sys/powerpc/include/profile.h | 124 ++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 51 deletions(-) diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index ed5c7b87a560..cfe75d9208ed 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -111,11 +111,14 @@ openfirmware_entry: srsave: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .text + .globl btext +btext: + /* * This symbol is here for the benefit of kvm_mkdb, and is supposed to * mark the start of kernel text. */ - .text .globl kernel_text kernel_text: diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index e4d8714b2f5a..a6335e6fd22a 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -41,11 +41,14 @@ #define TMPSTACKSZ 16384 + .text + .globl btext +btext: + /* * This symbol is here for the benefit of kvm_mkdb, and is supposed to * mark the start of kernel text. */ - .text .globl kernel_text kernel_text: diff --git a/sys/powerpc/include/profile.h b/sys/powerpc/include/profile.h index 96f3825e1dc4..388feb191741 100644 --- a/sys/powerpc/include/profile.h +++ b/sys/powerpc/include/profile.h @@ -81,61 +81,87 @@ typedef u_int fptrdiff_t; #define _PLT #endif -#define MCOUNT \ -__asm(" .globl _mcount \n" \ -" .type _mcount,@function \n" \ -"_mcount: \n" \ -" stwu %r1,-64(%r1) /* alloca for reg save space */ \n" \ -" stw %r3,16(%r1) /* save parameter registers, */ \n" \ -" stw %r4,20(%r1) /* r3-10 */ \n" \ -" stw %r5,24(%r1) \n" \ -" stw %r6,28(%r1) \n" \ -" stw %r7,32(%r1) \n" \ -" stw %r8,36(%r1) \n" \ -" stw %r9,40(%r1) \n" \ -" stw %r10,44(%r1) \n" \ -" \n" \ -" mflr %r4 /* link register is 'selfpc' */ \n" \ -" stw %r4,48(%r1) /* save since bl will scrub */ \n" \ -" lwz %r3,68(%r1) /* get 'frompc' from LR-save */ \n" \ -" bl __mcount" _PLT " /* __mcount(frompc, selfpc)*/ \n" \ -" lwz %r3,68(%r1) \n" \ -" mtlr %r3 /* restore caller's lr */ \n" \ -" lwz %r4,48(%r1) \n" \ -" mtctr %r4 /* set up ctr for call back */ \n" \ -" /* note that blr is not used!*/ \n" \ -" lwz %r3,16(%r1) /* restore r3-10 parameters */ \n" \ -" lwz %r4,20(%r1) \n" \ -" lwz %r5,24(%r1) \n" \ -" lwz %r6,28(%r1) \n" \ -" lwz %r7,32(%r1) \n" \ -" lwz %r8,36(%r1) \n" \ -" lwz %r9,40(%r1) \n" \ -" lwz %r10,44(%r1) \n" \ -" addi %r1,%r1,64 /* blow away alloca save area */ \n" \ -" bctr /* return with indirect call */ \n" \ -"_mcount_end: \n" \ -" .size _mcount,_mcount_end-_mcount"); - +#define MCOUNT \ +__asm( " .globl _mcount \n" \ + " .type _mcount,@function \n" \ + " .align 4 \n" \ + "_mcount: \n" \ + " stwu %r1,-64(%r1) \n" \ + " stw %r3,16(%r1) \n" \ + " stw %r4,20(%r1) \n" \ + " stw %r5,24(%r1) \n" \ + " stw %r6,28(%r1) \n" \ + " stw %r7,32(%r1) \n" \ + " stw %r8,36(%r1) \n" \ + " stw %r9,40(%r1) \n" \ + " stw %r10,44(%r1) \n" \ + " mflr %r4 \n" \ + " stw %r4,48(%r1) \n" \ + " lwz %r3,68(%r1) \n" \ + " bl __mcount" _PLT " \n" \ + " lwz %r3,68(%r1) \n" \ + " mtlr %r3 \n" \ + " lwz %r4,48(%r1) \n" \ + " mtctr %r4 \n" \ + " lwz %r3,16(%r1) \n" \ + " lwz %r4,20(%r1) \n" \ + " lwz %r5,24(%r1) \n" \ + " lwz %r6,28(%r1) \n" \ + " lwz %r7,32(%r1) \n" \ + " lwz %r8,36(%r1) \n" \ + " lwz %r9,40(%r1) \n" \ + " lwz %r10,44(%r1) \n" \ + " addi %r1,%r1,64 \n" \ + " bctr \n" \ + "_mcount_end: \n" \ + " .size _mcount,_mcount_end-_mcount"); #ifdef _KERNEL -#define MCOUNT_ENTER(s) s = intr_disable(); -#define MCOUNT_EXIT(s) intr_restore(s); -#define MCOUNT_DECL(s) register_t s +#define MCOUNT_ENTER(s) s = intr_disable() +#define MCOUNT_EXIT(s) intr_restore(s) +#define MCOUNT_DECL(s) register_t s; -void bintr(void); -void btrap(void); -void eintr(void); -void user(void); +#ifndef COMPILING_LINT +#ifdef AIM +#include +#define __PROFILE_VECTOR_BASE EXC_RST +#define __PROFILE_VECTOR_TOP (EXC_LAST + 0x100) +#endif /* AIM */ +#ifdef E500 +extern char interrupt_vector_base[]; +extern char interrupt_vector_top[]; +#define __PROFILE_VECTOR_BASE (uintfptr_t)interrupt_vector_base +#define __PROFILE_VECTOR_TOP (uintfptr_t)interrupt_vector_top +#endif /* E500 */ +#endif /* !COMPILING_LINT */ -#define MCOUNT_FROMPC_USER(pc) \ - ((pc < (uintfptr_t)VM_MAXUSER_ADDRESS) ? (uintfptr_t)user : pc) +#ifndef __PROFILE_VECTOR_BASE +#define __PROFILE_VECTOR_BASE 0 +#endif +#ifndef __PROFILE_VECTOR_TOP +#define __PROFILE_VECTOR_TOP 1 +#endif -#define MCOUNT_FROMPC_INTR(pc) \ - ((pc >= (uintfptr_t)btrap && pc < (uintfptr_t)eintr) ? \ - ((pc >= (uintfptr_t)bintr) ? (uintfptr_t)bintr : \ - (uintfptr_t)btrap) : ~0U) +static __inline void +powerpc_profile_interrupt(void) +{ +} +static __inline void +powerpc_profile_userspace(void) +{ +} + +#define MCOUNT_FROMPC_USER(pc) \ + ((pc < (uintfptr_t)VM_MAXUSER_ADDRESS) ? \ + (uintfptr_t)powerpc_profile_userspace : pc) + +#define MCOUNT_FROMPC_INTR(pc) \ + ((pc >= __PROFILE_VECTOR_BASE && \ + pc < __PROFILE_VECTOR_TOP) ? \ + (uintfptr_t)powerpc_profile_interrupt : ~0U) + +void __mcount(uintfptr_t frompc, uintfptr_t selfpc); #else /* !_KERNEL */