Move to a queue-based system call tracing
[akaros.git] / kern / src / monitor.c
1 // Simple command-line kernel monitor useful for
2 // controlling the kernel and exploring the system interactively.
3
4 #ifdef __SHARC__
5 #pragma nosharc
6 #endif
7
8 #include <arch/arch.h>
9 #include <stab.h>
10 #include <smp.h>
11 #include <console.h>
12 #include <arch/console.h>
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <assert.h>
17 #include <monitor.h>
18 #include <trap.h>
19 #include <pmap.h>
20 #include <kdebug.h>
21 #include <testing.h>
22 #include <manager.h>
23 #include <schedule.h>
24 #include <kdebug.h>
25 #include <syscall.h>
26 #include <kmalloc.h>
27 #include <elf.h>
28 #include <event.h>
29 #include <trap.h>
30 #include <time.h>
31
32 #include <ros/memlayout.h>
33 #include <ros/event.h>
34
35 #define CMDBUF_SIZE     80      // enough for one VGA text line
36
37 typedef struct command {
38         const char *NTS name;
39         const char *NTS desc;
40         // return -1 to force monitor to exit
41         int (*func)(int argc, char **argv, struct hw_trapframe *hw_tf);
42 } command_t;
43
44 static command_t (RO commands)[] = {
45         { "help", "Display this list of commands", mon_help },
46         { "kerninfo", "Display information about the kernel", mon_kerninfo },
47         { "backtrace", "Dump a backtrace", mon_backtrace },
48         { "bt", "Dump a backtrace", mon_bt },
49         { "reboot", "Take a ride to the South Bay", mon_reboot },
50         { "showmapping", "Shows VA->PA mappings", mon_showmapping},
51         { "sm", "Shows VA->PA mappings", mon_sm},
52         { "setmapperm", "Sets permissions on a VA->PA mapping", mon_setmapperm},
53         { "cpuinfo", "Prints CPU diagnostics", mon_cpuinfo},
54         { "ps", "Prints process list", mon_ps},
55         { "nanwan", "Meet Nanwan!!", mon_nanwan},
56         { "bin_ls", "List files in /bin", mon_bin_ls},
57         { "bin_run", "Create and run a program from /bin", mon_bin_run},
58         { "manager", "Run the manager", mon_manager},
59         { "procinfo", "Show information about processes", mon_procinfo},
60         { "pip", "Shorthand for procinfo pid", mon_pip},
61         { "kill", "Kills a process", mon_kill},
62         { "exit", "Leave the monitor", mon_exit},
63         { "kfunc", "Run a kernel function directly (!!!)", mon_kfunc},
64         { "notify", "Notify a process.  Vcoreid will skip their prefs", mon_notify},
65         { "measure", "Run a specific measurement", mon_measure},
66         { "trace", "Run some tracing functions", mon_trace},
67         { "monitor", "Run the monitor on another core", mon_monitor},
68         { "fs", "Filesystem Diagnostics", mon_fs},
69         { "bb", "Try to run busybox (ash)", mon_bb},
70         { "alarm", "Alarm Diagnostics", mon_alarm},
71         { "msr", "read/write msr: msr msr [value]", mon_msr},
72         { "db", "Misc debugging", mon_db},
73 };
74 #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
75
76 /***** Implementations of basic kernel monitor commands *****/
77
78 int mon_help(int argc, char **argv, struct hw_trapframe *hw_tf)
79 {
80         int i;
81
82         for (i = 0; i < NCOMMANDS; i++)
83                 cprintf("%s - %s\n", commands[i].name, commands[i].desc);
84         return 0;
85 }
86
87 int mon_ps(int argc, char** argv, struct hw_trapframe *hw_tf)
88 {
89         print_allpids();
90         return 0;
91 }
92
93 int mon_kerninfo(int argc, char **argv, struct hw_trapframe *hw_tf)
94 {
95         extern char (RO SNT _start)[], (RO SNT etext)[], (RO SNT edata)[], (RO SNT end)[];
96
97         cprintf("Special kernel symbols:\n");
98         cprintf("  _start %016x (virt)  %016x (phys)\n", _start, (uintptr_t)(_start - KERNBASE));
99         cprintf("  etext  %016x (virt)  %016x (phys)\n", etext, (uintptr_t)(etext - KERNBASE));
100         cprintf("  edata  %016x (virt)  %016x (phys)\n", edata, (uintptr_t)(edata - KERNBASE));
101         cprintf("  end    %016x (virt)  %016x (phys)\n", end, (uintptr_t)(end - KERNBASE));
102         cprintf("Kernel executable memory footprint: %dKB\n",
103                 (uint32_t)(end-_start+1023)/1024);
104         return 0;
105 }
106
107 #if 0
108 zra: not called
109 static char RO* function_of(uint32_t address)
110 {
111         extern stab_t (RO stab)[], (RO estab)[];
112         extern char (RO stabstr)[];
113         stab_t* symtab;
114         stab_t* best_symtab = 0;
115         uint32_t best_func = 0;
116
117         // ugly and unsorted
118         for (symtab = stab; symtab < estab; symtab++) {
119                 // only consider functions, type = N_FUN
120                 if ((symtab->n_type == N_FUN) &&
121                     (symtab->n_value <= address) &&
122                         (symtab->n_value > best_func)) {
123                         best_func = symtab->n_value;
124                         best_symtab = symtab;
125                 }
126         }
127         // maybe the first stab really is the right one...  we'll see.
128         if (best_symtab == 0)
129                 return "Function not found!";
130         return stabstr + best_symtab->n_strx;
131 }
132 #endif
133
134 static int __backtrace(int argc, char **argv, struct hw_trapframe *hw_tf)
135 {
136         uintptr_t pc, fp;
137         if (argc == 1) {
138                 backtrace();
139                 return 0;
140         }
141         if (argc != 3) {
142                 printk("Need either no arguments, or two (PC and FP) in hex\n");
143                 return 1;
144         }
145         pc = strtol(argv[1], 0, 16);
146         fp = strtol(argv[2], 0, 16);
147         printk("Backtrace from instruction %p, with frame pointer %p\n", pc, fp);
148         backtrace_frame(pc, fp);
149         return 0;
150 }
151
152 int mon_backtrace(int argc, char **argv, struct hw_trapframe *hw_tf)
153 {
154         return __backtrace(argc, argv, hw_tf);
155 }
156
157 int mon_bt(int argc, char **argv, struct hw_trapframe *hw_tf)
158 {
159         return __backtrace(argc, argv, hw_tf);
160 }
161
162 int mon_reboot(int argc, char **argv, struct hw_trapframe *hw_tf)
163 {
164         cprintf("[Scottish Accent]: She's goin' down, Cap'n!\n");
165         reboot();
166
167         // really, should never see this
168         cprintf("Sigh....\n");
169         return 0;
170 }
171
172 static int __showmapping(int argc, char **argv, struct hw_trapframe *hw_tf)
173 {
174         struct proc *p;
175         uintptr_t start;
176         size_t size;
177         pde_t *pgdir;
178         pid_t pid;
179         if (argc < 3) {
180                 printk("Shows virtual -> physical mappings for a virt addr range.\n");
181                 printk("Usage: showmapping PID START_ADDR [END_ADDR]\n");
182                 printk("    PID == 0 for the boot pgdir\n");
183                 return 1;
184         }
185         pid = strtol(argv[1], 0, 10);
186         if (!pid) {
187                 pgdir = boot_pgdir;
188         } else {
189                 p = pid2proc(pid);
190                 if (!p) {
191                         printk("No proc with pid %d\n", pid);
192                         return 1;
193                 }
194                 pgdir = p->env_pgdir;
195         }
196         start = ROUNDDOWN(strtol(argv[2], 0, 16), PGSIZE);
197         size = (argc == 3) ? 1 : strtol(argv[3], 0, 16) - start;
198         if (size/PGSIZE > 512) {
199                 cprintf("Not going to do this for more than 512 items\n");
200                 return 1;
201         }
202         show_mapping(pgdir, start, size);
203         return 0;
204 }
205
206 int mon_showmapping(int argc, char **argv, struct hw_trapframe *hw_tf)
207 {
208         return __showmapping(argc, argv, hw_tf);
209 }
210
211 int mon_sm(int argc, char **argv, struct hw_trapframe *hw_tf)
212 {
213         return __showmapping(argc, argv, hw_tf);
214 }
215
216 int mon_setmapperm(int argc, char **argv, struct hw_trapframe *hw_tf)
217 {
218 #ifndef CONFIG_X86_32
219         cprintf("I don't support this call yet!\n");
220         return 1;
221 #else
222         if (argc < 3) {
223                 cprintf("Sets VIRT_ADDR's mapping's permissions to PERMS (in hex)\n");
224                 cprintf("Only affects the lowest level PTE.  To adjust the PDE, do the math.\n");
225                 cprintf("Be careful with this around UVPT, VPT, and friends.\n");
226                 cprintf("Usage: setmapperm VIRT_ADDR PERMS\n");
227                 return 1;
228         }
229         pde_t*COUNT(PTSIZE) pgdir = (pde_t*COUNT(PTSIZE))vpd;
230         pte_t *pte, *pde;
231         page_t* page;
232         uintptr_t va;
233         va = ROUNDDOWN(strtol(argv[1], 0, 16), PGSIZE);
234         page = page_lookup(pgdir, (void*SNT)va, &pte);
235         if (!page) {
236                 cprintf("No such mapping\n");
237                 return 1;
238         }
239         pde = &pgdir[PDX(va)];
240         cprintf("   Virtual    Physical  Ps Dr Ac CD WT U W\n");
241         cprintf("------------------------------------------\n");
242         cprintf("%p  %p  %1d  %1d  %1d  %1d  %1d  %1d %1d\n", va, page2pa(page),
243                (*pte & PTE_PS) >> 7, (*pte & PTE_D) >> 6, (*pte & PTE_A) >> 5,
244                (*pte & PTE_PCD) >> 4, (*pte & PTE_PWT) >> 3, (*pte & *pde & PTE_U) >> 2,
245                (*pte & *pde & PTE_W) >> 1);
246         *pte = PTE_ADDR(*pte) | (*pte & PTE_PS) |
247                (PGOFF(strtol(argv[2], 0, 16)) & ~PTE_PS ) | PTE_P;
248         cprintf("%p  %p  %1d  %1d  %1d  %1d  %1d  %1d %1d\n", va, page2pa(page),
249                (*pte & PTE_PS) >> 7, (*pte & PTE_D) >> 6, (*pte & PTE_A) >> 5,
250                (*pte & PTE_PCD) >> 4, (*pte & PTE_PWT) >> 3, (*pte & *pde & PTE_U) >> 2,
251                (*pte & *pde & PTE_W) >> 1);
252         return 0;
253 #endif
254 }
255
256 static spinlock_t print_info_lock = SPINLOCK_INITIALIZER_IRQSAVE;
257
258 static void print_info_handler(struct hw_trapframe *hw_tf, void *data)
259 {
260         uint64_t tsc = read_tsc();
261
262         spin_lock_irqsave(&print_info_lock);
263         cprintf("----------------------------\n");
264         cprintf("This is Core %d\n", core_id());
265         cprintf("Timestamp = %lld\n", tsc);
266 #ifdef CONFIG_X86
267         cprintf("Hardware core %d\n", hw_core_id());
268         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
269         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
270                 read_msr(0x200), read_msr(0x201));
271         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
272                 read_msr(0x202), read_msr(0x203));
273         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
274                 read_msr(0x204), read_msr(0x205));
275         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
276                 read_msr(0x206), read_msr(0x207));
277         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
278                 read_msr(0x208), read_msr(0x209));
279         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
280                 read_msr(0x20a), read_msr(0x20b));
281         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
282                 read_msr(0x20c), read_msr(0x20d));
283         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
284                 read_msr(0x20e), read_msr(0x20f));
285 #endif // CONFIG_X86
286         cprintf("----------------------------\n");
287         spin_unlock_irqsave(&print_info_lock);
288 }
289
290 static bool print_all_info(void)
291 {
292         cprintf("\nCORE 0 asking all cores to print info:\n");
293         smp_call_function_all(print_info_handler, NULL, 0);
294         cprintf("\nDone!\n");
295         return true;
296 }
297
298 int mon_cpuinfo(int argc, char **argv, struct hw_trapframe *hw_tf)
299 {
300         cprintf("Number of CPUs detected: %d\n", num_cpus);
301         cprintf("Calling CPU's ID: 0x%08x\n", core_id());
302
303         if (argc < 2)
304                 smp_call_function_self(print_info_handler, NULL, 0);
305         else
306                 smp_call_function_single(strtol(argv[1], 0, 10),
307                                          print_info_handler, NULL, 0);
308         return 0;
309 }
310
311 int mon_manager(int argc, char** argv, struct hw_trapframe *hw_tf)
312 {
313         manager();
314         panic("should never get here");
315         return 0;
316 }
317
318 int mon_nanwan(int argc, char **argv, struct hw_trapframe *hw_tf)
319 {
320         /* Borrowed with love from http://www.geocities.com/SoHo/7373/zoo.htm
321          * (http://www.ascii-art.com/).  Slightly modified to make it 25 lines tall.
322          */
323         printk("\n");
324         printk("             .-.  .-.\n");
325         printk("             |  \\/  |\n");
326         printk("            /,   ,_  `'-.\n");
327         printk("          .-|\\   /`\\     '. \n");
328         printk("        .'  0/   | 0\\  \\_  `\".  \n");
329         printk("     .-'  _,/    '--'.'|#''---'\n");
330         printk("      `--'  |       /   \\#\n");
331         printk("            |      /     \\#\n");
332         printk("            \\     ;|\\    .\\#\n");
333         printk("            |' ' //  \\   ::\\# \n");
334         printk("            \\   /`    \\   ':\\#\n");
335         printk("             `\"`       \\..   \\#\n");
336         printk("                        \\::.  \\#\n");
337         printk("                         \\::   \\#\n");
338         printk("                          \\'  .:\\#\n");
339         printk("                           \\  :::\\#\n");
340         printk("                            \\  '::\\#\n");
341         printk("                             \\     \\#\n");
342         printk("                              \\:.   \\#\n");
343         printk("                               \\::   \\#\n");
344         printk("                                \\'   .\\#\n");
345         printk("                             jgs \\   ::\\#\n");
346         printk("                                  \\      \n");
347         return 0;
348 }
349
350 int mon_bin_ls(int argc, char **argv, struct hw_trapframe *hw_tf)
351 {
352         struct dirent dir = {0};
353         struct file *bin_dir;
354         int retval = 0;
355
356         bin_dir = do_file_open("/bin", 0, 0);
357         if (!bin_dir) {
358                 printk("No /bin directory!\n");
359                 return 1;
360         }
361         printk("Files in /bin:\n-------------------------------\n");
362         do {
363                 retval = bin_dir->f_op->readdir(bin_dir, &dir); 
364                 printk("%s\n", dir.d_name);
365         } while (retval == 1);
366         kref_put(&bin_dir->f_kref);
367         return 0;
368 }
369
370 int mon_bin_run(int argc, char **argv, struct hw_trapframe *hw_tf)
371 {
372         if (argc < 2) {
373                 printk("Usage: bin_run FILENAME\n");
374                 return 1;
375         }
376         struct file *program;
377         int retval = 0;
378         char buf[6 + MAX_FILENAME_SZ] = "/bin/";        /* /bin/ + max + \0 */
379         strncpy(buf + 5, argv[1], MAX_FILENAME_SZ);
380         program = do_file_open(buf, 0, 0);
381         if (!program) {
382                 printk("No such program!\n");
383                 return 1;
384         }
385         char **p_argv = kmalloc(sizeof(char*) * argc, 0);       /* bin_run's argc */
386         for (int i = 0; i < argc - 1; i++)
387                 p_argv[i] = argv[i + 1];
388         p_argv[argc - 1] = 0;
389         /* super ugly: we need to stash current, so that proc_create doesn't pick up
390          * on random processes running here and assuming they are the parent */
391         struct proc *old_cur = current;
392         current = 0;
393         struct proc *p = proc_create(program, p_argv, NULL);
394         current = old_cur;
395         kfree(p_argv);
396         proc_wakeup(p);
397         proc_decref(p); /* let go of the reference created in proc_create() */
398         kref_put(&program->f_kref);
399         /* Make a scheduling decision.  You might not get the process you created,
400          * in the event there are others floating around that are runnable */
401         run_scheduler();
402         /* want to idle, so we un the process we just selected.  this is a bit
403          * hackish, but so is the monitor. */
404         smp_idle();
405         assert(0);
406         return 0;
407 }
408
409 int mon_procinfo(int argc, char **argv, struct hw_trapframe *hw_tf)
410 {
411         int8_t irq_state = 0;
412         if (argc < 2) {
413                 printk("Usage: procinfo OPTION\n");
414                 printk("\tidlecores: show idle core map\n");
415                 printk("\tall: show all active pids\n");
416                 printk("\tsched: scheduler diagnostic report\n");
417                 printk("\tresources: show resources wanted/granted for all procs\n");
418                 printk("\tpid NUM: show a lot of info for proc NUM\n");
419                 printk("\tunlock: unlock the lock for the ADDR (OMG!!!)\n");
420                 printk("\tkill NUM: destroy proc NUM\n");
421                 return 1;
422         }
423         if (!strcmp(argv[1], "idlecores")) {
424                 print_idlecoremap();
425         } else if (!strcmp(argv[1], "all")) {
426                 print_allpids();
427         } else if (!strcmp(argv[1], "sched")) {
428                 sched_diag();
429         } else if (!strcmp(argv[1], "resources")) {
430                 print_all_resources();
431         } else if (!strcmp(argv[1], "pid")) {
432                 if (argc != 3) {
433                         printk("Give me a pid number.\n");
434                         return 1;
435                 }
436                 print_proc_info(strtol(argv[2], 0, 0));
437         } else if (!strcmp(argv[1], "unlock")) {
438                 if (argc != 3) {
439                         printk("Gimme lock address!  Me want lock address!.\n");
440                         return 1;
441                 }
442                 spinlock_t *lock = (spinlock_t*)strtol(argv[2], 0, 16);
443                 if (!lock) {
444                         printk("Null address...\n");
445                         return 1;
446                 }
447                 spin_unlock(lock);
448         } else if (!strcmp(argv[1], "kill")) {
449                 if (argc != 3) {
450                         printk("Give me a pid number.\n");
451                         return 1;
452                 }
453                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
454                 if (!p) {
455                         printk("No such proc\n");
456                         return 1;
457                 }
458                 enable_irqsave(&irq_state);
459                 proc_destroy(p);
460                 disable_irqsave(&irq_state);
461                 proc_decref(p);
462         } else {
463                 printk("Bad option\n");
464                 return 1;
465         }
466         return 0;
467 }
468
469 int mon_pip(int argc, char **argv, struct hw_trapframe *hw_tf)
470 {
471         if (argc != 2) {
472                 printk("Give me a pid number.\n");
473                 return 1;
474         }
475         print_proc_info(strtol(argv[1], 0, 0));
476         return 0;
477 }
478
479 int mon_kill(int argc, char **argv, struct hw_trapframe *hw_tf)
480 {
481         struct proc *p;
482         int8_t irq_state = 0;
483         if (argc < 2) {
484                 printk("Usage: kill PID\n");
485                 return 1;
486         }
487         p = pid2proc(strtol(argv[1], 0, 0));
488         if (!p) {
489                 printk("No such proc\n");
490                 return 1;
491         }
492         enable_irqsave(&irq_state);
493         proc_destroy(p);
494         disable_irqsave(&irq_state);
495         proc_decref(p);
496         return 0;
497 }
498
499 int mon_exit(int argc, char **argv, struct hw_trapframe *hw_tf)
500 {
501         return -1;
502 }
503
504 int mon_kfunc(int argc, char **argv, struct hw_trapframe *hw_tf)
505 {
506         void (*func)(void *arg, ...);
507
508         if (argc < 2) {
509                 printk("Usage: kfunc FUNCTION [arg1] [arg2] [etc]\n");
510                 printk("Arguments must be in hex.  Can take 6 args.\n");
511                 return 1;
512         }
513         func = (void*)get_symbol_addr(argv[1]);
514         if (!func) {
515                 printk("Function not found.\n");
516                 return 1;
517         }
518         /* Not elegant, but whatever.  maybe there's a better syntax, or we can do
519          * it with asm magic. */
520         switch (argc) {
521                 case 2: /* have to fake one arg */
522                         func((void*)0);
523                         break;
524                 case 3: /* the real first arg */
525                         func((void*)strtol(argv[2], 0, 16));
526                         break;
527                 case 4:
528                         func((void*)strtol(argv[2], 0, 16),
529                                     strtol(argv[3], 0, 16));
530                         break;
531                 case 5:
532                         func((void*)strtol(argv[2], 0, 16),
533                                     strtol(argv[3], 0, 16),
534                                     strtol(argv[4], 0, 16));
535                         break;
536                 case 6:
537                         func((void*)strtol(argv[2], 0, 16),
538                                     strtol(argv[3], 0, 16),
539                                     strtol(argv[4], 0, 16),
540                                     strtol(argv[5], 0, 16));
541                         break;
542                 case 7:
543                         func((void*)strtol(argv[2], 0, 16),
544                                     strtol(argv[3], 0, 16),
545                                     strtol(argv[4], 0, 16),
546                                     strtol(argv[5], 0, 16),
547                                     strtol(argv[6], 0, 16));
548                         break;
549                 case 8:
550                         func((void*)strtol(argv[2], 0, 16),
551                                     strtol(argv[3], 0, 16),
552                                     strtol(argv[4], 0, 16),
553                                     strtol(argv[5], 0, 16),
554                                     strtol(argv[6], 0, 16),
555                                     strtol(argv[7], 0, 16));
556                         break;
557                 default:
558                         printk("Bad number of arguments.\n");
559                         return -1;
560         }
561         return 0;
562 }
563
564 /* Sending a vcoreid forces an event and an IPI/notification */
565 int mon_notify(int argc, char **argv, struct hw_trapframe *hw_tf)
566 {
567         struct proc *p;
568         uint32_t vcoreid;
569         struct event_msg msg = {0};
570
571         if (argc < 3) {
572                 printk("Usage: notify PID NUM [VCOREID]\n");
573                 return 1;
574         }
575         p = pid2proc(strtol(argv[1], 0, 0));
576         if (!p) {
577                 printk("No such proc\n");
578                 return 1;
579         }
580         msg.ev_type = strtol(argv[2], 0, 0);
581         if (argc == 4) {
582                 vcoreid = strtol(argv[3], 0, 0);
583                 /* This will go to the private mbox */
584                 post_vcore_event(p, &msg, vcoreid, EVENT_VCORE_PRIVATE);
585                 proc_notify(p, vcoreid);
586         } else {
587                 /* o/w, try and do what they want */
588                 send_kernel_event(p, &msg, 0);
589         }
590         proc_decref(p);
591         return 0;
592 }
593
594 /* Micro-benchmarky Measurements.  This is really fragile code that probably
595  * won't work perfectly, esp as the kernel evolves. */
596 int mon_measure(int argc, char **argv, struct hw_trapframe *hw_tf)
597 {
598         uint64_t begin = 0, diff = 0;
599         uint32_t end_refcnt = 0;
600         int8_t irq_state = 0;
601
602         if (argc < 2) {
603                 printk("Usage: measure OPTION\n");
604                 printk("\tkill PID : kill proc PID\n");
605                 printk("\tpreempt PID : preempt proc PID (no delay)\n");
606                 printk("\tpreempt PID [pcore] : preempt PID's pcore (no delay)\n");
607                 printk("\tpreempt-warn PID : warn-preempt proc PID (pending)\n");
608                 printk("\tpreempt-warn PID [pcore] : warn-preempt proc PID's pcore\n");
609                 printk("\tpreempt-raw PID : raw-preempt proc PID\n");
610                 printk("\tpreempt-raw PID [pcore] : raw-preempt proc PID's pcore\n");
611                 return 1;
612         }
613         if (!strcmp(argv[1], "kill")) {
614                 if (argc < 3) {
615                         printk("Give me a pid number.\n");
616                         return 1;
617                 }
618                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
619                 if (!p) {
620                         printk("No such proc\n");
621                         return 1;
622                 }
623                 begin = start_timing();
624 #ifdef CONFIG_APPSERVER
625                 printk("Warning: this will be inaccurate due to the appserver.\n");
626                 end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores - 1;
627 #endif /* CONFIG_APPSERVER */
628                 enable_irqsave(&irq_state);
629                 proc_destroy(p);
630                 disable_irqsave(&irq_state);
631                 proc_decref(p);
632 #ifdef CONFIG_APPSERVER
633                 /* Won't be that accurate, since it's not actually going through the
634                  * __proc_free() path. */
635                 spin_on(kref_refcnt(&p->p_kref) != end_refcnt); 
636 #else
637                 /* this is a little ghetto. it's not fully free yet, but we are also
638                  * slowing it down by messing with it, esp with the busy waiting on a
639                  * hyperthreaded core. */
640                 spin_on(p->env_cr3);
641 #endif /* CONFIG_APPSERVER */
642                 /* No noticeable difference using stop_timing instead of read_tsc() */
643                 diff = stop_timing(begin);
644         } else if (!strcmp(argv[1], "preempt")) {
645                 if (argc < 3) {
646                         printk("Give me a pid number.\n");
647                         return 1;
648                 }
649                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
650                 if (!p) {
651                         printk("No such proc\n");
652                         return 1;
653                 }
654                 if (argc == 4) { /* single core being preempted, warned but no delay */
655                         uint32_t pcoreid = strtol(argv[3], 0, 0);
656                         begin = start_timing();
657                         if (proc_preempt_core(p, pcoreid, 1000000)) {
658                                 __sched_put_idle_core(p, pcoreid);
659                                 /* done when unmapped (right before abandoning) */
660                                 spin_on(p->procinfo->pcoremap[pcoreid].valid);
661                         } else {
662                                 printk("Core %d was not mapped to proc\n", pcoreid);
663                         }
664                         diff = stop_timing(begin);
665                 } else { /* preempt all cores, warned but no delay */
666                         end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
667                         begin = start_timing();
668                         proc_preempt_all(p, 1000000);
669                         /* a little ghetto, implies no one is using p */
670                         spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
671                         diff = stop_timing(begin);
672                 }
673                 proc_decref(p);
674         } else if (!strcmp(argv[1], "preempt-warn")) {
675                 if (argc < 3) {
676                         printk("Give me a pid number.\n");
677                         return 1;
678                 }
679                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
680                 if (!p) {
681                         printk("No such proc\n");
682                         return 1;
683                 }
684                 printk("Careful: if this hangs, then the process isn't responding.\n");
685                 if (argc == 4) { /* single core being preempted-warned */
686                         uint32_t pcoreid = strtol(argv[3], 0, 0);
687                         spin_lock(&p->proc_lock);
688                         uint32_t vcoreid = p->procinfo->pcoremap[pcoreid].vcoreid;
689                         if (!p->procinfo->pcoremap[pcoreid].valid) {
690                                 printk("Pick a mapped pcore\n");
691                                 spin_unlock(&p->proc_lock);
692                                 return 1;
693                         }
694                         begin = start_timing();
695                         __proc_preempt_warn(p, vcoreid, 1000000); // 1 sec
696                         spin_unlock(&p->proc_lock);
697                         /* done when unmapped (right before abandoning) */
698                         spin_on(p->procinfo->pcoremap[pcoreid].valid);
699                         diff = stop_timing(begin);
700                 } else { /* preempt-warn all cores */
701                         printk("Warning, this won't work if they can't yield their "
702                                "last vcore, will stop at 1!\n");
703                         spin_lock(&p->proc_lock);
704                         begin = start_timing();
705                         __proc_preempt_warnall(p, 1000000);
706                         spin_unlock(&p->proc_lock);
707                         /* target cores do the unmapping / changing of the num_vcores */
708                         spin_on(p->procinfo->num_vcores > 1);
709                         diff = stop_timing(begin);
710                 }
711                 proc_decref(p);
712         } else if (!strcmp(argv[1], "preempt-raw")) {
713                 if (argc < 3) {
714                         printk("Give me a pid number.\n");
715                         return 1;
716                 }
717                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
718                 if (!p) {
719                         printk("No such proc\n");
720                         return 1;
721                 }
722                 if (argc == 4) { /* single core preempted, no warning or waiting */
723                         uint32_t pcoreid = strtol(argv[3], 0, 0);
724                         spin_lock(&p->proc_lock);
725                         if (!p->procinfo->pcoremap[pcoreid].valid) {
726                                 printk("Pick a mapped pcore\n");
727                                 spin_unlock(&p->proc_lock);
728                                 return 1;
729                         }
730                         begin = start_timing();
731                         __proc_preempt_core(p, pcoreid);
732                         if (!p->procinfo->num_vcores)
733                                 __proc_set_state(p, PROC_RUNNABLE_M);
734                         spin_unlock(&p->proc_lock);
735                         /* ghetto, since the ksched should be calling all of this */
736                         __sched_put_idle_core(p, pcoreid);
737                         /* done when unmapped (right before abandoning) */
738                         spin_on(p->procinfo->pcoremap[pcoreid].valid);
739                         diff = stop_timing(begin);
740                 } else { /* preempt all cores, no warning or waiting */
741                         spin_lock(&p->proc_lock);
742                         uint32_t pc_arr[p->procinfo->num_vcores];
743                         uint32_t num_revoked;
744                         end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
745                         begin = start_timing();
746                         num_revoked = __proc_preempt_all(p, pc_arr);
747                         __proc_set_state(p, PROC_RUNNABLE_M);
748                         spin_unlock(&p->proc_lock);
749                         if (num_revoked)
750                                 __sched_put_idle_cores(p, pc_arr, num_revoked);
751                         /* a little ghetto, implies no one else is using p */
752                         spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
753                         diff = stop_timing(begin);
754                 }
755                 proc_decref(p);
756         } else {
757                 printk("Bad option\n");
758                 return 1;
759         }
760         printk("[Tired Giraffe Accent] Took %llu usec (%llu nsec) to finish.\n",
761                tsc2usec(diff), tsc2nsec(diff));
762         return 0;
763 }
764
765 /* Used in various debug locations.  Not a kernel API or anything. */
766 bool mon_verbose_trace = FALSE;
767
768 int mon_trace(int argc, char **argv, struct hw_trapframe *hw_tf)
769 {
770         int core;
771         if (argc < 2) {
772                 printk("Usage: trace OPTION\n");
773                 printk("\tsyscall start [silent (0 or non-zero, NOT the word silent)] [pid]: starts tracing\n");
774                 printk("\tsyscall stop: stops tracing.\n");
775                 printk("\tcoretf COREID: prints PC, -1 for all cores, verbose => TF\n");
776                 printk("\tpcpui [type [coreid]]: runs pcpui trace ring handlers\n");
777                 printk("\tpcpui-reset [noclear]: resets/clears pcpui trace ring\n");
778                 printk("\tverbose: toggles verbosity, depends on trace command\n");
779                 return 1;
780         }
781         if (!strcmp(argv[1], "syscall")) {
782                 if (argc < 3) {
783                         printk("Need a start or stop.\n");
784                         return 1;
785                 }
786                 if (!strcmp(argv[2], "start")) {
787                         bool all = TRUE;
788                         bool silent = FALSE;
789                         struct proc *p = NULL;
790                         if (argc >= 4) {
791                                 silent = (bool)strtol(argv[3], 0, 0);
792                         }
793                         if (argc >= 5) {
794                                 all = FALSE;
795                                 p = pid2proc(strtol(argv[4], 0, 0));
796                                 if (!p) {
797                                         printk("No such process\n");
798                                         return 1;
799                                 }
800                         }
801                         systrace_start(silent);
802                         if (systrace_reg(all, p))
803                                 printk("No room to trace more processes\n");
804                 } else if (!strcmp(argv[2], "stop")) {
805                         /* Stop. To see the output, kfunc systrace_print and systrace_clear */
806                         /* or cat #K/kptrace or /prof/kptrace */
807                         systrace_stop();
808                 }
809         } else if (!strcmp(argv[1], "coretf")) {
810                 if (argc != 3) {
811                         printk("Need a coreid, fool.\n");
812                         return 1;
813                 }
814                 core = strtol(argv[2], 0, 0);
815                 if (core < 0) {
816                         printk("Sending NMIs to all cores:\n");
817                         for (int i = 0; i < num_cpus; i++)
818                                 send_nmi(i);
819                 } else {
820                         printk("Sending NMI core %d:\n", core);
821                         if (core >= num_cpus) {
822                                 printk("No such core!  Maybe it's in another cell...\n");
823                                 return 1;
824                         }
825                         send_nmi(core);
826                 }
827                 udelay(1000000);
828         } else if (!strcmp(argv[1], "pcpui")) {
829                 int pcpui_type, pcpui_coreid;
830                 if (argc >= 3)
831                         pcpui_type = strtol(argv[2], 0, 0);
832                 else
833                         pcpui_type = 0;
834                 printk("\nRunning PCPUI Trace Ring handlers for type %d\n", pcpui_type);
835                 if (argc >= 4) {
836                         pcpui_coreid = strtol(argv[3], 0, 0); 
837                         pcpui_tr_foreach(pcpui_coreid, pcpui_type);
838                 } else {
839                         pcpui_tr_foreach_all(pcpui_type);
840                 }
841         } else if (!strcmp(argv[1], "pcpui-reset")) {
842                 if (argc >= 3) {
843                         printk("\nResetting all PCPUI Trace Rings\n");
844                         pcpui_tr_reset_all();
845                 } else {
846                         printk("\nResetting and clearing all PCPUI Trace Rings\n");
847                         pcpui_tr_reset_and_clear_all();
848                 }
849         } else if (!strcmp(argv[1], "verbose")) {
850                 if (mon_verbose_trace) {
851                         printk("Turning trace verbosity off\n");
852                         mon_verbose_trace = FALSE;
853                 } else {
854                         printk("Turning trace verbosity on\n");
855                         mon_verbose_trace = TRUE;
856                 }
857         } else if (!strcmp(argv[1], "opt2")) {
858                 if (argc != 3) {
859                         printk("ERRRRRRRRRR.\n");
860                         return 1;
861                 }
862                 print_proc_info(strtol(argv[2], 0, 0));
863         } else {
864                 printk("Bad option\n");
865                 return 1;
866         }
867         return 0;
868 }
869
870 int mon_monitor(int argc, char **argv, struct hw_trapframe *hw_tf)
871 {
872         if (argc < 2) {
873                 printk("Usage: monitor COREID\n");
874                 return 1;
875         }
876         uint32_t core = strtol(argv[1], 0, 0);
877         if (core >= num_cpus) {
878                 printk("No such core!  Maybe it's in another cell...\n");
879                 return 1;
880         }
881         send_kernel_message(core, __run_mon, 0, 0, 0, KMSG_ROUTINE);
882         return 0;
883 }
884
885 /***** Kernel monitor command interpreter *****/
886
887 #define WHITESPACE "\t\r\n "
888 #define MAXARGS 16
889
890 static int runcmd(char *NTS real_buf, struct hw_trapframe *hw_tf) {
891         char * buf = NTEXPAND(real_buf);
892         int argc;
893         char *NTS argv[MAXARGS];
894         int i;
895
896         // Parse the command buffer into whitespace-separated arguments
897         argc = 0;
898         argv[argc] = 0;
899         while (1) {
900                 // gobble whitespace
901                 while (*buf && strchr(WHITESPACE, *buf))
902                         *buf++ = 0;
903                 if (*buf == 0)
904                         break;
905
906                 // save and scan past next arg
907                 if (argc == MAXARGS-1) {
908                         cprintf("Too many arguments (max %d)\n", MAXARGS);
909                         return 0;
910                 }
911                 //This will get fucked at runtime..... in the ASS
912                 argv[argc++] = buf;
913                 while (*buf && !strchr(WHITESPACE, *buf))
914                         buf++;
915         }
916         argv[argc] = 0;
917
918         // Lookup and invoke the command
919         if (argc == 0)
920                 return 0;
921         for (i = 0; i < NCOMMANDS; i++) {
922                 if (strcmp(argv[0], commands[i].name) == 0)
923                         return commands[i].func(argc, argv, hw_tf);
924         }
925         cprintf("Unknown command '%s'\n", argv[0]);
926         return 0;
927 }
928
929 void monitor(struct hw_trapframe *hw_tf)
930 {
931         #define MON_CMD_LENGTH 256
932         char buf[MON_CMD_LENGTH];
933         int cnt;
934         int coreid = core_id_early();
935
936         /* they are always disabled, since we have this irqsave lock */
937         if (irq_is_enabled())
938                 printk("Entering Nanwan's Dungeon on Core %d (Ints on):\n", coreid);
939         else
940                 printk("Entering Nanwan's Dungeon on Core %d (Ints off):\n", coreid);
941         printk("Type 'help' for a list of commands.\n");
942
943         if (hw_tf != NULL)
944                 print_trapframe(hw_tf);
945
946         while (1) {
947                 /* on occasion, the kernel monitor can migrate (like if you run
948                  * something that blocks / syncs and wakes up on another core) */
949                 cmb();
950                 cnt = readline(buf, MON_CMD_LENGTH, "ROS(Core %d)> ", core_id_early());
951                 if (cnt > 0) {
952                         buf[cnt] = 0;
953                         if (runcmd(buf, hw_tf) < 0)
954                                 break;
955                 }
956         }
957 }
958
959 static void pm_flusher(void *unused)
960 {
961         struct super_block *sb;
962         struct inode *inode;
963         unsigned long nr_pages;
964
965         /* could also put the delay between calls, or even within remove, during the
966          * WB phase. */
967         while (1) {
968                 udelay_sched(5000);
969                 TAILQ_FOREACH(sb, &super_blocks, s_list) {
970                         TAILQ_FOREACH(inode, &sb->s_inodes, i_sb_list) {
971                                 nr_pages = ROUNDUP(inode->i_size, PGSIZE) >> PGSHIFT;
972                                 if (nr_pages)
973                                         pm_remove_contig(inode->i_mapping, 0, nr_pages);
974                         }
975                 }
976         }
977 }
978
979 int mon_fs(int argc, char **argv, struct hw_trapframe *hw_tf)
980 {
981         /* this assumes one mounted FS at the NS root */
982         struct super_block *sb;
983         struct file *file;
984         struct inode *inode;
985         struct dentry *dentry;
986         if (argc < 2) {
987                 printk("Usage: fs OPTION\n");
988                 printk("\topen: show all open files\n");
989                 printk("\tinodes: show all inodes\n");
990                 printk("\tdentries [lru|prune]: show all dentries, opt LRU/prune\n");
991                 printk("\tls DIR: print the dir tree starting with DIR\n");
992                 printk("\tpid: proc PID's fs crap placeholder\n");
993                 printk("\tpmflusher: start a ktask to keep flushing all PMs\n");
994                 return 1;
995         }
996         if (!strcmp(argv[1], "open")) {
997                 printk("Open Files:\n----------------------------\n");
998                 TAILQ_FOREACH(sb, &super_blocks, s_list) {
999                         printk("Superblock for %s\n", sb->s_name);
1000                         TAILQ_FOREACH(file, &sb->s_files, f_list)
1001                                 printk("File: %p, %s, Refs: %d, Drefs: %d, Irefs: %d PM: %p\n",
1002                                        file, file_name(file), kref_refcnt(&file->f_kref),
1003                                        kref_refcnt(&file->f_dentry->d_kref),
1004                                        kref_refcnt(&file->f_dentry->d_inode->i_kref),
1005                                            file->f_mapping);
1006                 }
1007         } else if (!strcmp(argv[1], "inodes")) {
1008                 printk("Mounted FS Inodes:\n----------------------------\n");
1009                 TAILQ_FOREACH(sb, &super_blocks, s_list) {
1010                         printk("Superblock for %s\n", sb->s_name);
1011                         TAILQ_FOREACH(inode, &sb->s_inodes, i_sb_list) {
1012                                 printk("Inode: %p, Refs: %d, Nlinks: %d, Size(B): %d\n",
1013                                        inode, kref_refcnt(&inode->i_kref), inode->i_nlink,
1014                                        inode->i_size);
1015                                 TAILQ_FOREACH(dentry, &inode->i_dentry, d_alias)
1016                                         printk("\t%s: Dentry: %p, Refs: %d\n",
1017                                                dentry->d_name.name, dentry,
1018                                                kref_refcnt(&dentry->d_kref));
1019                         }
1020                 }
1021         } else if (!strcmp(argv[1], "dentries")) {
1022                 printk("Dentry Cache:\n----------------------------\n");
1023                 TAILQ_FOREACH(sb, &super_blocks, s_list) {
1024                         printk("Superblock for %s\n", sb->s_name);
1025                         printk("DENTRY     FLAGS      REFCNT NAME\n");
1026                         printk("--------------------------------\n");
1027                         /* Hash helper */
1028                         void print_dcache_entry(void *item)
1029                         {
1030                                 struct dentry *d_i = (struct dentry*)item;
1031                                 printk("%p %p %02d     %s\n", d_i, d_i->d_flags,
1032                                        kref_refcnt(&d_i->d_kref), d_i->d_name.name);
1033                         }
1034                         hash_for_each(sb->s_dcache, print_dcache_entry);
1035                 }
1036                 if (argc < 3)
1037                         return 0;
1038                 if (!strcmp(argv[2], "lru")) {
1039                         printk("LRU lists:\n");
1040                         TAILQ_FOREACH(sb, &super_blocks, s_list) {
1041                                 printk("Superblock for %s\n", sb->s_name);
1042                                 TAILQ_FOREACH(dentry, &sb->s_lru_d, d_lru)
1043                                         printk("Dentry: %p, Name: %s\n", dentry,
1044                                                dentry->d_name.name);
1045                         }
1046                 } else if (!strcmp(argv[2], "prune")) {
1047                         printk("Pruning unused dentries\n");
1048                         TAILQ_FOREACH(sb, &super_blocks, s_list)
1049                                 dcache_prune(sb, FALSE);
1050                 }
1051         } else if (!strcmp(argv[1], "ls")) {
1052                 if (argc != 3) {
1053                         printk("Give me a dir.\n");
1054                         return 1;
1055                 }
1056                 if (argv[2][0] != '/') {
1057                         printk("Dear fellow giraffe lover, Use absolute paths.\n");
1058                         return 1;
1059                 }
1060                 ls_dash_r(argv[2]);
1061                 /* whatever.  placeholder. */
1062         } else if (!strcmp(argv[1], "pid")) {
1063                 if (argc != 3) {
1064                         printk("Give me a pid number.\n");
1065                         return 1;
1066                 }
1067                 /* whatever.  placeholder. */
1068         } else if (!strcmp(argv[1], "pmflusher")) {
1069                 ktask("pm_flusher", pm_flusher, 0);
1070         } else {
1071                 printk("Bad option\n");
1072                 return 1;
1073         }
1074         return 0;
1075 }
1076
1077 int mon_bb(int argc, char **argv, struct hw_trapframe *hw_tf)
1078 {
1079         char *l_argv[3] = {"", "busybox", "ash"};
1080         return mon_bin_run(3, l_argv, hw_tf);
1081 }
1082
1083 int mon_alarm(int argc, char **argv, struct hw_trapframe *hw_tf)
1084 {
1085         if (argc < 2) {
1086                 printk("Usage: alarm OPTION\n");
1087                 printk("\tpcpu: print full alarm tchains from every core\n");
1088                 return 1;
1089         }
1090         if (!strcmp(argv[1], "pcpu")) {
1091                 print_pcpu_chains();
1092         } else {
1093                 printk("Bad option\n");
1094                 return 1;
1095         }
1096         return 0;
1097 }
1098
1099 static void show_msr(struct hw_trapframe *unused, void *v)
1100 {
1101         int core = core_id();
1102         uint64_t val;
1103         uint32_t msr = *(uint32_t *)v;
1104         val = read_msr(msr);
1105         printk("%d: %08x: %016llx\n", core, msr, val);
1106 }
1107
1108 struct set {
1109         uint32_t msr;
1110         uint64_t val;
1111 };
1112
1113 static void set_msr(struct hw_trapframe *unused, void *v)
1114 {
1115         int core = core_id();
1116         struct set *s = v;
1117         uint32_t msr = s->msr;
1118         uint64_t val = s->val;
1119         write_msr(msr, val);
1120         val = read_msr(msr);
1121         printk("%d: %08x: %016llx\n", core, msr, val);
1122 }
1123
1124 int mon_msr(int argc, char **argv, struct hw_trapframe *hw_tf)
1125 {
1126 #ifndef CONFIG_X86
1127         cprintf("Not on this architecture\n");
1128         return 1;
1129 #else
1130         uint64_t val;
1131         uint32_t msr;
1132         if (argc < 2 || argc > 3) {
1133                 printk("Usage: msr register [value]\n");
1134                 return 1;
1135         }
1136         msr = strtoul(argv[1], 0, 16);
1137         handler_wrapper_t *w;
1138         smp_call_function_all(show_msr, &msr, &w);
1139         smp_call_wait(w);
1140
1141         if (argc < 3)
1142                 return 0;
1143         /* somewhat bogus on 32 bit. */
1144         val = strtoul(argv[2], 0, 16);
1145
1146         struct set set;
1147         set.msr = msr;
1148         set.val = val;
1149         smp_call_function_all(set_msr, &set, &w);
1150         smp_call_wait(w);
1151         return 0;
1152 #endif
1153 }
1154
1155 int mon_db(int argc, char **argv, struct hw_trapframe *hw_tf)
1156 {
1157         if (argc < 2) {
1158                 printk("Usage: db OPTION\n");
1159                 printk("\tsem: print all semaphore info\n");
1160                 return 1;
1161         }
1162         if (!strcmp(argv[1], "sem")) {
1163                 print_all_sem_info();
1164         } else {
1165                 printk("Bad option\n");
1166                 return 1;
1167         }
1168         return 0;
1169 }