185c51c51SRalf Baechle #include <linux/cpumask.h> 285c51c51SRalf Baechle #include <linux/debugfs.h> 385c51c51SRalf Baechle #include <linux/fs.h> 485c51c51SRalf Baechle #include <linux/init.h> 585c51c51SRalf Baechle #include <linux/percpu.h> 685c51c51SRalf Baechle #include <linux/types.h> 7*75dcfc1dSPaul Burton #include <asm/debug.h> 885c51c51SRalf Baechle #include <asm/fpu_emulator.h> 985c51c51SRalf Baechle #include <asm/local.h> 1085c51c51SRalf Baechle 1185c51c51SRalf Baechle DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); 1285c51c51SRalf Baechle 1385c51c51SRalf Baechle static int fpuemu_stat_get(void *data, u64 *val) 1485c51c51SRalf Baechle { 1585c51c51SRalf Baechle int cpu; 1685c51c51SRalf Baechle unsigned long sum = 0; 1785c51c51SRalf Baechle 1885c51c51SRalf Baechle for_each_online_cpu(cpu) { 1985c51c51SRalf Baechle struct mips_fpu_emulator_stats *ps; 2085c51c51SRalf Baechle local_t *pv; 2185c51c51SRalf Baechle 2285c51c51SRalf Baechle ps = &per_cpu(fpuemustats, cpu); 2385c51c51SRalf Baechle pv = (void *)ps + (unsigned long)data; 2485c51c51SRalf Baechle sum += local_read(pv); 2585c51c51SRalf Baechle } 2685c51c51SRalf Baechle *val = sum; 2785c51c51SRalf Baechle return 0; 2885c51c51SRalf Baechle } 2985c51c51SRalf Baechle DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); 3085c51c51SRalf Baechle 3185c51c51SRalf Baechle static int __init debugfs_fpuemu(void) 3285c51c51SRalf Baechle { 3385c51c51SRalf Baechle struct dentry *d, *dir; 3485c51c51SRalf Baechle 3585c51c51SRalf Baechle if (!mips_debugfs_dir) 3685c51c51SRalf Baechle return -ENODEV; 3785c51c51SRalf Baechle dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); 3885c51c51SRalf Baechle if (!dir) 3985c51c51SRalf Baechle return -ENOMEM; 4085c51c51SRalf Baechle 4147fa0c02SRalf Baechle #define FPU_EMU_STAT_OFFSET(m) \ 4247fa0c02SRalf Baechle offsetof(struct mips_fpu_emulator_stats, m) 4347fa0c02SRalf Baechle 4447fa0c02SRalf Baechle #define FPU_STAT_CREATE(m) \ 4585c51c51SRalf Baechle do { \ 4647fa0c02SRalf Baechle d = debugfs_create_file(#m , S_IRUGO, dir, \ 4747fa0c02SRalf Baechle (void *)FPU_EMU_STAT_OFFSET(m), \ 4885c51c51SRalf Baechle &fops_fpuemu_stat); \ 4985c51c51SRalf Baechle if (!d) \ 5085c51c51SRalf Baechle return -ENOMEM; \ 5185c51c51SRalf Baechle } while (0) 5285c51c51SRalf Baechle 5385c51c51SRalf Baechle FPU_STAT_CREATE(emulated); 5485c51c51SRalf Baechle FPU_STAT_CREATE(loads); 5585c51c51SRalf Baechle FPU_STAT_CREATE(stores); 5685c51c51SRalf Baechle FPU_STAT_CREATE(cp1ops); 5785c51c51SRalf Baechle FPU_STAT_CREATE(cp1xops); 5885c51c51SRalf Baechle FPU_STAT_CREATE(errors); 59c4103526SDeng-Cheng Zhu FPU_STAT_CREATE(ieee754_inexact); 60c4103526SDeng-Cheng Zhu FPU_STAT_CREATE(ieee754_underflow); 61c4103526SDeng-Cheng Zhu FPU_STAT_CREATE(ieee754_overflow); 62c4103526SDeng-Cheng Zhu FPU_STAT_CREATE(ieee754_zerodiv); 63c4103526SDeng-Cheng Zhu FPU_STAT_CREATE(ieee754_invalidop); 642707cd29SDavid Daney FPU_STAT_CREATE(ds_emul); 6585c51c51SRalf Baechle 6685c51c51SRalf Baechle return 0; 6785c51c51SRalf Baechle } 681249ed35SRalf Baechle arch_initcall(debugfs_fpuemu); 69