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