Module: xenomai-gch Branch: fpu-tracer Commit: 3b498899c9de6bd1909977d57d9a10debc29e445 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=3b498899c9de6bd1909977d57d9a10debc29e445
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Tue Aug 11 23:50:47 2009 +0200 Add missing files --- include/asm-powerpc/fp_dump.h | 108 ++++++++++++++++------------------------- include/nucleus/fpu_trace.h | 32 ++++++------ ksrc/nucleus/fpu_trace.c | 83 +++++++++++++++++++++----------- 3 files changed, 114 insertions(+), 109 deletions(-) diff --git a/include/asm-powerpc/fp_dump.h b/include/asm-powerpc/fp_dump.h index 1c15389..a09a68c 100644 --- a/include/asm-powerpc/fp_dump.h +++ b/include/asm-powerpc/fp_dump.h @@ -1,112 +1,88 @@ #ifndef FP_DUMP_PPC_H #define FP_DUMP_PPC_H -#define flnzul(word) \ -({ \ - unsigned long out; \ - /* Derived from bitops.h's ffs() */ \ - __asm__ ("cntlzw %0, %1" : "=r" (out) : "r" (word)); \ - 31 - out; \ -}) - -#if defined(__KERNEL__) && BITS_PER_LONG == 32 -#include <asm/div64.h> - -#define ulldiv(ull, uld) __div64_32(&ull, uld) -#else /* !__KERNEL__ || BITS_PER_LONG == 64 */ -#define ulldiv(ull, uld) \ -({ \ - unsigned long _r = (ull) % (uld); \ - ull /= uld; \ - _r; \ -}) -#endif /* __KERNEL__ */ - -static inline unsigned long flnzull(unsigned long long ull) -{ - unsigned long h = (ull >> 32); - if(h) - return 32 + flnzul(h); - return flnzul((unsigned long) ull); -} +#include <asm-generic/xenomai/fp_dump.h> /* For fp_disp */ #include <fp_dump_inner.h> -typedef struct fpreg { - unsigned long fractionh; - unsigned long fractionl : 20; - unsigned short exp : 11; /* signed, but not using 2's complement. */ - unsigned short sign : 1; -} fpreg_t; - typedef struct fpenv { - /* This layout must follow exactely the definition of the FPU - backup area in a PPC thread struct available from - <asm-ppc/processor.h>. Specifically, fpr[] an fpscr words must - be contiguous in memory (see arch/ppc/hal/fpu.S). */ - fpreg_t fpr[32]; unsigned long fpscr_pad; /* <= Hi-word of the FPR used to */ unsigned long fpscr; /* retrieve the FPSCR. */ + void *fprs; /* address of original fprs - must be last */ } fpenv_t; -void rthal_save_fpu(fpenv_t *fpuenv); +#define DECLARE_FPENV(__var__) \ + unsigned char __var__ ## _buf [sizeof(fpenv_t) + 15]; \ + fpenv_t *__var__ = ALIGN_FPENV(&__var__ ## _buf[0]); -void rthal_restore_fpu(fpenv_t *fpuenv); +#define ALIGN_FPENV(ptr) \ + (fpenv_t *) (((unsigned long) (ptr) + 15) & ~15) -#define fpenv_save rthal_save_fpu +void rthal_save_fpu_trace(fpenv_t *fpuenv); -static inline void fpenv_dump(fpenv_t *fpenv) +static inline void fpenv_save(fpenv_t *ctxt, void *fprs) +{ + rthal_save_fpu_trace(ctxt); + ctxt->fprs = fprs; +} + +#define fp_get_lfprs(p) ((p)->thread.fpr) +#define fp_get_xfprs(t) (xnarch_fpu_ptr(t)) + +static inline void fpenv_dump(void *cookie, fpenv_t *fpenv) { unsigned i; - fp_print("FPU state:\n"); - fp_print("fpscr: 0x%08lx\n", fpenv->fpscr); + fp_print(cookie, " FPU state @%p [fpscr=0x%08lx]\n", fpenv->fprs, fpenv->fpscr); for(i = 0; i < 32; i++) { - fpreg_t *reg = &fpenv->fpr[i]; - fp_conv_t fp = { - significand: ( (1ULL << 63) - + (((unsigned long long) reg->fractionh) << 31) - + (((unsigned long long) reg->fractionl) << 11)), - exp: (int) (reg->exp - 1023) - 11, - pow10: 0, - }; - - fp_print("R%2u: ", i); - - switch(reg->exp) + unsigned long long fraction, *reg = (unsigned long long *)&fpenv->fpr[i]; + unsigned exp, sign; + fp_conv_t fp; + + fraction = ((*reg) & ((1ULL << 52) - 1)) << 11; + exp = ((*reg) & ((1ULL << 63) - (1ULL << 52))) >> 52; + sign = ((*reg) & (1ULL << 63)) >> 63; + + fp.significand = (1ULL << 63) + fraction; + fp.exp = (int) exp - 1023; + fp.pow10 = 0; + + fp_print(cookie, " R%2u[raw=0x%.16Lx]: ", i, *reg); + + switch(exp) { case 0: /* zero or denormalized. */ - if(!reg->fractionh && !reg->fractionl) + if(!fraction) { - fp_print("0"); + fp_print(cookie, "0"); break; } - fp_print("(DEN) "); + fp_print(cookie, "(DEN) "); fp.significand <<= 1; fp.exp--; /* Fall through normalized. */ default: /* normalized. */ - disp(&fp, reg->sign); + fp_disp(cookie, &fp, sign); break; case 2047: /* infinities or nans. */ - if(!reg->fractionh && !reg->fractionl) - fp_print("%c inf.", reg->sign ? '-' : '+'); + if(fraction) + fp_print(cookie, "%c inf.", sign ? '-' : '+'); else - fp_print("%cnan.", ( reg->fractionh & (1UL << 31) + fp_print(cookie, "%cnan.", ( fraction & (1ULL << 63) ? 'Q' : 'S' )); break; } - fp_print(" %c", i % 2 ? '\n' : ' '); + fp_print(cookie, "\n"); } } diff --git a/include/nucleus/fpu_trace.h b/include/nucleus/fpu_trace.h index 0daef95..f5be21a 100644 --- a/include/nucleus/fpu_trace.h +++ b/include/nucleus/fpu_trace.h @@ -3,10 +3,9 @@ struct task_struct; struct xnthread; +struct xnarchtcb; -#define FPU_TRACE_ENABLED - -#ifdef FPU_TRACE_ENABLED +#ifdef CONFIG_XENO_HW_FPU_TRACER void fp_trace_switch(struct task_struct *from, struct task_struct *to); @@ -14,19 +13,21 @@ void fp_trace_kernel_start(void); void fp_trace_kernel_end(void); -void fp_trace_save(void); +void fp_trace_save(struct task_struct *p); -void fp_trace_restore(void); +void fp_trace_restore(struct task_struct *p); -void fp_trace_xeno_init(unsigned branch); +void fp_trace_xeno_init(unsigned branch, struct xnarchtcb *tcb); void fp_trace_xeno_switch(struct xnthread *from, struct xnthread *to); -void fp_trace_xeno_save(unsigned branch, unsigned do_save); +void fp_trace_xeno_save(unsigned branch, unsigned do_save, struct xnarchtcb *tcb); + +void fp_trace_xeno_restore(unsigned branch, unsigned do_save, struct xnarchtcb *tcb); -void fp_trace_xeno_restore(unsigned branch, unsigned do_save); +void fp_trace_xeno_enable(unsigned branch, unsigned do_save, struct xnarchtcb *tcb); -void fp_trace_xeno_enable(unsigned branch, unsigned do_save); +void fp_trace_xeno_leave_root(unsigned branch); void fp_trace_freeze(void); @@ -35,13 +36,14 @@ void fp_trace_freeze(void); #define fp_trace_switch(from, to) do { } while(0) #define fp_trace_kernel_start() do { } while(0) #define fp_trace_kernel_end() do { } while (0) -#define fp_trace_save() do { } while(0) -#define fp_trace_restore() do { } while(0) -#define fp_trace_xeno_init(branch) do { } while (0) +#define fp_trace_save(p) do { } while(0) +#define fp_trace_restore(p) do { } while(0) +#define fp_trace_xeno_init(branch, tcb) do { } while (0) #define fp_trace_xeno_switch(from, to) do { } while(0) -#define fp_trace_xeno_save(branch, do_save) do { } while(0) -#define fp_trace_xeno_restore(branch, do_save) do { } while(0) -#define fp_trace_xeno_enable(branch, do_save) do { } while(0) +#define fp_trace_xeno_save(branch, do_save, tcb) do { } while(0) +#define fp_trace_xeno_restore(branch, do_save, tcb) do { } while(0) +#define fp_trace_xeno_enable(branch, do_save, tcb) do { } while(0) +#define fp_trace_xeno_leave_root(branch) do { } while(0) #define fp_trace_freeze() do { } while(0) #endif diff --git a/ksrc/nucleus/fpu_trace.c b/ksrc/nucleus/fpu_trace.c index ea1f8b2..9347acc 100644 --- a/ksrc/nucleus/fpu_trace.c +++ b/ksrc/nucleus/fpu_trace.c @@ -9,14 +9,10 @@ #include <asm/xenomai/fp_dump.h> -#ifdef FPU_TRACE_ENABLED +#ifdef CONFIG_XENO_HW_FPU_TRACER -#if 1 -#define STORAGE_SIZE (128 * 1024 * 1024) -#else -#define STORAGE_SIZE (16 * 1024 * 2024) -#endif -#define SIZE_MASK (STORAGE_SIZE - 1) +#define STORAGE_SIZE (8 * 1024 * 1024) +#define SIZE_MASK (STORAGE_SIZE - 1) enum fp_trace_event { FP_TRACE_LTHR = 0, @@ -29,6 +25,7 @@ enum fp_trace_event { FP_TRACE_XFPS, FP_TRACE_XFPR, FP_TRACE_XFPEN, + FP_TRACE_LVROOT, FP_TRACE_STOP, FP_TRACE_MAX, }; @@ -41,6 +38,8 @@ struct fp_trace_type { struct fp_trace_switch { char from[64]; char to[64]; + void *from_fprs; + void *to_fprs; }; static unsigned event_hit[FP_TRACE_MAX]; @@ -63,6 +62,8 @@ void fp_trace_switch(struct task_struct *from, struct task_struct *to) fp_trace_print_task(&buf.from[0], sizeof(buf.from), NULL, from); fp_trace_print_task(&buf.to[0], sizeof(buf.to), NULL, to); + buf.from_fprs = fp_get_lfprs(from); + buf.to_fprs = fp_get_lfprs(to); fp_trace_push(FP_TRACE_LTHR, 0, &buf, sizeof(buf)); } @@ -76,23 +77,28 @@ void fp_trace_kernel_end(void) fp_trace_push(FP_TRACE_LKFPEND, 0, NULL, 0); } -void fp_trace_save(void) +void fp_trace_save(struct task_struct *p) { DECLARE_FPENV(ctxt); - fpenv_save(ctxt); + fpenv_save(ctxt, fp_get_lfprs(p)); fp_trace_push(FP_TRACE_LFPS, 0, ctxt, sizeof(*ctxt)); } -void fp_trace_restore(void) +void fp_trace_restore(struct task_struct *p) { DECLARE_FPENV(ctxt); - fpenv_save(ctxt); + fpenv_save(ctxt, fp_get_lfprs(p)); fp_trace_push(FP_TRACE_LFPR, 0, ctxt, sizeof(*ctxt)); } -void fp_trace_xeno_init(unsigned branch) +void fp_trace_xeno_init(unsigned branch, xnarchtcb_t *tcb) { - fp_trace_push(FP_TRACE_XINI, branch, NULL, 0); + if (tcb) { + DECLARE_FPENV(ctxt); + fpenv_save(ctxt, fp_get_xfprs(tcb)); + fp_trace_push(FP_TRACE_XINI, branch | (1 << 15), ctxt, sizeof(*ctxt)); + } else + fp_trace_push(FP_TRACE_XINI, branch, NULL, 0); } void fp_trace_xeno_switch(xnthread_t *from, xnthread_t *to) @@ -101,42 +107,49 @@ void fp_trace_xeno_switch(xnthread_t *from, xnthread_t *to) fp_trace_print_task(&buf.from[0], sizeof(buf.from), from, NULL); fp_trace_print_task(&buf.to[0], sizeof(buf.to), to, NULL); + buf.from_fprs = fp_get_xfprs(xnthread_archtcb(from)); + buf.to_fprs = fp_get_xfprs(xnthread_archtcb(to)); fp_trace_push(FP_TRACE_XTHR, 0, &buf, sizeof(buf)); } -void fp_trace_xeno_save(unsigned branch, unsigned do_save) +void fp_trace_xeno_save(unsigned branch, unsigned do_save, xnarchtcb_t *tcb) { if (do_save) { DECLARE_FPENV(ctxt); - fpenv_save(ctxt); + fpenv_save(ctxt, fp_get_xfprs(tcb)); fp_trace_push(FP_TRACE_XFPS, branch | (1 << 15), ctxt, sizeof(*ctxt)); } else fp_trace_push(FP_TRACE_XFPS, branch, NULL, 0); } -void fp_trace_xeno_restore(unsigned branch, unsigned do_save) +void fp_trace_xeno_restore(unsigned branch, unsigned do_save, xnarchtcb_t *tcb) { if (do_save) { DECLARE_FPENV(ctxt); - fpenv_save(ctxt); + fpenv_save(ctxt, fp_get_xfprs(tcb)); fp_trace_push(FP_TRACE_XFPR, branch | (1 << 15), ctxt, sizeof(*ctxt)); } else fp_trace_push(FP_TRACE_XFPR, branch, NULL, 0); } -void fp_trace_xeno_enable(unsigned branch, unsigned do_save) +void fp_trace_xeno_enable(unsigned branch, unsigned do_save, xnarchtcb_t *tcb) { if (do_save) { DECLARE_FPENV(ctxt); - fpenv_save(ctxt); + fpenv_save(ctxt, fp_get_xfprs(tcb)); fp_trace_push(FP_TRACE_XFPEN, branch | (1 << 15), ctxt, sizeof(*ctxt)); } else fp_trace_push(FP_TRACE_XFPEN,branch, NULL, 0); } +void fp_trace_xeno_leave_root(unsigned branch) +{ + fp_trace_push(FP_TRACE_LVROOT, branch, NULL, 0); +} + void fp_trace_freeze(void) { fp_trace_push(FP_TRACE_STOP, 0, NULL, 0); @@ -170,6 +183,7 @@ static unsigned long fp_trace_next_entry(unsigned long cur) case FP_TRACE_XFPS: case FP_TRACE_XFPR: case FP_TRACE_XFPEN: + case FP_TRACE_LVROOT: case FP_TRACE_STOP: if (type->branch & (1 << 15)) cur += sizeof(fpenv_t); @@ -222,7 +236,7 @@ static void fp_trace_push(enum fp_trace_event type, end = (end + len) & SIZE_MASK; if (fp_trace_next_entry((char *) t - storage) != end) { spin_unlock_irqrestore(&lock, flags); - printk("Trace, type: %d, entry: %lx, len: %x, next: %lx," + printk("Trace, type: %d, entry: %x, len: %x, next: %lx," " end: %lx\n", t->type, (char *) t - storage, len, fp_trace_next_entry((char *) t - storage), end); BUG(); @@ -307,8 +321,8 @@ static int fp_trace_seq_show(struct seq_file *seq, void *v) switch(type->type) { case FP_TRACE_LTHR: cpy_buf(&swtch, sizeof(swtch), type + 1); - seq_printf(seq, "Linux switch from %s to %s\n", - swtch.from, swtch.to); + seq_printf(seq, "Linux switch from %s to %s (fprs @%p -> @%p)\n", + swtch.from, swtch.to, swtch.from_fprs, swtch.to_fprs); break; case FP_TRACE_LKFPBEG: @@ -332,13 +346,18 @@ static int fp_trace_seq_show(struct seq_file *seq, void *v) break; case FP_TRACE_XINI: - seq_printf(seq, "Xeno init fpu (branch %d)\n", type->branch); + seq_printf(seq, "Xeno init fpu (branch %d)\n", + type->branch & ~(1 << 15)); + if (type->branch & (1 << 15)) { + cpy_buf(ctxt, sizeof(*ctxt), type + 1); + fpenv_dump(seq, ctxt); + } break; case FP_TRACE_XTHR: cpy_buf(&swtch, sizeof(swtch), type + 1); - seq_printf(seq, "Xeno switch from %s to %s\n", - swtch.from, swtch.to); + seq_printf(seq, "Xeno switch from %s to %s (fprs @%p -> @%p)\n", + swtch.from, swtch.to, swtch.from_fprs, swtch.to_fprs); break; case FP_TRACE_XFPS: @@ -368,6 +387,10 @@ static int fp_trace_seq_show(struct seq_file *seq, void *v) } break; + case FP_TRACE_LVROOT: + seq_printf(seq, "Xeno leaving root (branch %d)\n", type->branch); + break; + case FP_TRACE_STOP: seq_printf(seq, "Capture stopped\n"); if (type->branch & (1 << 15)) { @@ -377,7 +400,7 @@ static int fp_trace_seq_show(struct seq_file *seq, void *v) break; default: - printk("type: 0x%04x, cur: 0x%08lx\n", + printk("type: 0x%04x, cur: 0x%08x\n", type->type, (char *) type - storage); BUG(); } @@ -479,6 +502,10 @@ static int fp_trace_cov_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "Xeno enabling fpu: "); break; + case FP_TRACE_LVROOT: + seq_printf(seq, "Xeno leaving root: "); + break; + case FP_TRACE_STOP: seq_printf(seq, "Capture stopped: "); break; @@ -547,14 +574,14 @@ int __init fp_trace_init(void) return -EINVAL; entry->proc_fops = &fp_trace_seq_operations; - entry->owner = THIS_MODULE; + wrap_proc_dir_entry_owner(entry); entry = create_proc_entry("fp_trace_cov", 0, rthal_proc_root); if (!entry) return -EINVAL; entry->proc_fops = &fp_trace_cov_seq_operations; - entry->owner = THIS_MODULE; + wrap_proc_dir_entry_owner(entry); points = begin = end = 0; starting = ready = 1; _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git