0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/smp.h>
0009 #include <linux/spinlock.h>
0010 #include <linux/sysrq.h>
0011 #include <linux/workqueue.h>
0012
0013 #include <asm/cpu-features.h>
0014 #include <asm/mipsregs.h>
0015 #include <asm/tlbdebug.h>
0016
0017
0018
0019
0020
0021 static DEFINE_SPINLOCK(show_lock);
0022
0023 static void sysrq_tlbdump_single(void *dummy)
0024 {
0025 unsigned long flags;
0026
0027 spin_lock_irqsave(&show_lock, flags);
0028
0029 pr_info("CPU%d:\n", smp_processor_id());
0030 dump_tlb_regs();
0031 pr_info("\n");
0032 dump_tlb_all();
0033 pr_info("\n");
0034
0035 spin_unlock_irqrestore(&show_lock, flags);
0036 }
0037
0038 #ifdef CONFIG_SMP
0039 static void sysrq_tlbdump_othercpus(struct work_struct *dummy)
0040 {
0041 smp_call_function(sysrq_tlbdump_single, NULL, 0);
0042 }
0043
0044 static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus);
0045 #endif
0046
0047 static void sysrq_handle_tlbdump(int key)
0048 {
0049 sysrq_tlbdump_single(NULL);
0050 #ifdef CONFIG_SMP
0051 schedule_work(&sysrq_tlbdump);
0052 #endif
0053 }
0054
0055 static const struct sysrq_key_op sysrq_tlbdump_op = {
0056 .handler = sysrq_handle_tlbdump,
0057 .help_msg = "show-tlbs(x)",
0058 .action_msg = "Show TLB entries",
0059 .enable_mask = SYSRQ_ENABLE_DUMP,
0060 };
0061
0062 static int __init mips_sysrq_init(void)
0063 {
0064 return register_sysrq_key('x', &sysrq_tlbdump_op);
0065 }
0066 arch_initcall(mips_sysrq_init);