Major overhaul to testing infrastructure
[akaros.git] / kern / src / manager.c
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  */
6
7
8 #ifdef __SHARC__
9 #pragma nosharc
10 #endif
11
12 #include <ros/common.h>
13 #include <smp.h>
14 #include <arch/init.h>
15 #include <mm.h>
16 #include <elf.h>
17 #include <frontend.h>
18
19 #include <kmalloc.h>
20 #include <assert.h>
21 #include <manager.h>
22 #include <process.h>
23 #include <schedule.h>
24 #include <syscall.h>
25 #include <ktest.h>
26 #include <kfs.h>
27 #include <stdio.h>
28 #include <time.h>
29 #include <monitor.h>
30 #include <colored_caches.h>
31 #include <string.h>
32 #include <pmap.h>
33 #include <arch/console.h>
34 #include <time.h>
35 #include <ros/arch/membar.h>
36
37 /*
38  * Currently, if you leave this function by way of proc_run (process_workqueue
39  * that proc_runs), you will never come back to where you left off, and the
40  * function will start from the top.  Hence the hack 'progress'.
41  */
42 void manager(void)
43 {
44         // LoL
45         #define PASTE(s1,s2) s1 ## s2
46         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
47
48         #if !defined(DEVELOPER_NAME) && \
49             (defined(CONFIG_KERNEL_POSTBOOT_TESTING) || \
50              defined(CONFIG_USERSPACE_TESTING))
51                 #define DEVELOPER_NAME jenkins
52         #endif
53
54         #ifndef DEVELOPER_NAME
55                 #define DEVELOPER_NAME brho
56         #endif
57
58         void MANAGER_FUNC(DEVELOPER_NAME)(void);
59         MANAGER_FUNC(DEVELOPER_NAME)();
60 }
61
62 char *p_argv[] = {0, 0, 0};
63 char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
64 /* Helper macro for quickly running a process.  Pass it a string, *file, and a
65  * *proc. */
66 #define quick_proc_run(x, p, f)                                                  \
67         (f) = do_file_open((x), 0, 0);                                               \
68         assert((f));                                                                 \
69         p_argv[0] = file_name((f));                                                  \
70         (p) = proc_create((f), p_argv, p_envp);                                      \
71         kref_put(&(f)->f_kref);                                                      \
72         spin_lock(&(p)->proc_lock);                                                  \
73         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
74         spin_unlock(&(p)->proc_lock);                                                \
75         proc_run_s((p));                                                             \
76         proc_decref((p));
77
78 #define quick_proc_create(x, p, f)                                               \
79         (f) = do_file_open((x), 0, 0);                                               \
80         assert((f));                                                                 \
81         p_argv[0] = file_name((f));                                                  \
82         (p) = proc_create((f), p_argv, p_envp);                                      \
83         kref_put(&(f)->f_kref);                                                      \
84         spin_lock(&(p)->proc_lock);                                                  \
85         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
86         spin_unlock(&(p)->proc_lock);
87
88 #define quick_proc_color_run(x, p, c, f)                                         \
89         (f) = do_file_open((x), 0, 0);                                               \
90         assert((f));                                                                 \
91         p_argv[0] = file_name((f));                                                  \
92         (p) = proc_create((f), p_argv, p_envp);                                      \
93         kref_put(&(f)->f_kref);                                                      \
94         spin_lock(&(p)->proc_lock);                                                  \
95         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
96         spin_unlock(&(p)->proc_lock);                                                \
97         p->cache_colors_map = cache_colors_map_alloc();                              \
98         for (int i = 0; i < (c); i++)                                                \
99                 cache_color_alloc(llc_cache, p->cache_colors_map);                       \
100         proc_run_s((p));                                                             \
101         proc_decref((p));
102
103 #define quick_proc_color_create(x, p, c, f)                                      \
104         (f) = do_file_open((x), 0, 0);                                               \
105         assert((f));                                                                 \
106         p_argv[0] = file_name((f));                                                  \
107         (p) = proc_create((f), p_argv, p_envp);                                      \
108         kref_put(&(f)->f_kref);                                                      \
109         spin_lock(&(p)->proc_lock);                                                  \
110         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
111         spin_unlock(&(p)->proc_lock);                                                \
112         p->cache_colors_map = cache_colors_map_alloc();                              \
113         for (int i = 0; i < (c); i++)                                                \
114                 cache_color_alloc(llc_cache, p->cache_colors_map);
115
116 void manager_brho(void)
117 {
118         static bool first = TRUE;
119         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
120
121         if (first) {    
122                 printk("*** IRQs must be enabled for input emergency codes ***\n");
123                 #ifdef CONFIG_X86
124                 printk("*** Hit ctrl-g to enter the monitor. ***\n");
125                 printk("*** Hit ctrl-q to force-enter the monitor. ***\n");
126                 printk("*** Hit ctrl-b for a backtrace of core 0 ***\n");
127                 #else
128                 printk("*** Hit ctrl-g to enter the monitor. ***\n");
129                 #warning "***** ctrl-g untested on riscv, check k/a/r/trap.c *****"
130                 #endif
131                 first = FALSE;
132         }
133         /* just idle, and deal with things via interrupts.  or via face. */
134         smp_idle();
135         /* whatever we do in the manager, keep in mind that we need to not do
136          * anything too soon (like make processes), since we'll drop in here during
137          * boot if the boot sequence required any I/O (like EXT2), and we need to
138          * PRKM() */
139         assert(0);
140
141 #if 0 /* ancient tests below: (keeping around til we ditch the manager) */
142         // for testing taking cores, check in case 1 for usage
143         uint32_t corelist[MAX_NUM_CPUS];
144         uint32_t num = 3;
145         struct file *temp_f;
146         static struct proc *p;
147
148         static uint8_t RACY progress = 0;       /* this will wrap around. */
149         switch (progress++) {
150                 case 0:
151                         printk("Top of the manager to ya!\n");
152                         /* 124 is half of the available boxboro colors (with the kernel
153                          * getting 8) */
154                         //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
155                         quick_proc_run("/bin/hello", p, temp_f);
156                         #if 0
157                         // this is how you can transition to a parallel process manually
158                         // make sure you don't proc run first
159                         __proc_set_state(p, PROC_RUNNING_S);
160                         __proc_set_state(p, PROC_RUNNABLE_M);
161                         p->resources[RES_CORES].amt_wanted = 5;
162                         spin_unlock(&p->proc_lock);
163                         core_request(p);
164                         panic("This is okay");
165                         #endif
166                         break;
167                 case 1:
168                         #if 0
169                         udelay(10000000);
170                         // this is a ghetto way to test restarting an _M
171                                 printk("\nattempting to ghetto preempt...\n");
172                                 spin_lock(&p->proc_lock);
173                                 proc_take_allcores(p, __death);
174                                 __proc_set_state(p, PROC_RUNNABLE_M);
175                                 spin_unlock(&p->proc_lock);
176                                 udelay(5000000);
177                                 printk("\nattempting to restart...\n");
178                                 core_request(p); // proc still wants the cores
179                         panic("This is okay");
180                         // this tests taking some cores, and later killing an _M
181                                 printk("taking 3 cores from p\n");
182                                 for (int i = 0; i < num; i++)
183                                         corelist[i] = 7-i; // 7, 6, and 5
184                                 spin_lock(&p->proc_lock);
185                                 proc_take_cores(p, corelist, &num, __death);
186                                 spin_unlock(&p->proc_lock);
187                                 udelay(5000000);
188                                 printk("Killing p\n");
189                                 enable_irq();
190                                 proc_destroy(p);
191                                 printk("Killed p\n");
192                         panic("This is okay");
193
194                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
195                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
196                         proc_run(envs[0]);
197                         warn("DEPRECATED");
198                         break;
199                         #endif
200                 case 2:
201                         /*
202                         test_smp_call_functions();
203                         test_checklists();
204                         test_barrier();
205                         test_print_info();
206                         test_lapic_status_bit();
207                         test_ipi_sending();
208                         test_pit();
209                         */
210                 default:
211                         printd("Manager Progress: %d\n", progress);
212                         // delay if you want to test rescheduling an MCP that yielded
213                         //udelay(15000000);
214                         run_scheduler();
215         }
216         panic("If you see me, then you probably screwed up");
217         monitor(0);
218
219         /*
220         printk("Servicing syscalls from Core 0:\n\n");
221         while (1) {
222                 process_generic_syscalls(&envs[0], 1);
223                 cpu_relax();
224         }
225         */
226         return;
227 #endif
228 }
229
230 void manager_jenkins()
231 {
232         #ifdef CONFIG_KERNEL_POSTBOOT_TESTING
233                 extern struct ktest pb_ktests[];
234                 extern int num_pb_ktests;
235                 run_ktests("POSTBOOT", pb_ktests, num_pb_ktests);
236         #endif
237         // Run userspace tests (from config specified path).
238         #ifdef CONFIG_USERSPACE_TESTING
239         if (strlen(CONFIG_USERSPACE_TESTING_SCRIPT) != 0) {
240                 char exec[] = "/bin/ash";
241                 char *p_argv[] = {exec, CONFIG_USERSPACE_TESTING_SCRIPT, 0};
242                 char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
243
244                 struct file *program = do_file_open(exec, 0, 0);
245                 struct proc *p = proc_create(program, p_argv, p_envp);
246                 proc_wakeup(p);
247                 proc_decref(p); /* let go of the reference created in proc_create() */
248                 kref_put(&program->f_kref);
249                 run_scheduler();
250             // Need a way to wait for p to finish
251         } else {
252                 printk("No user-space launcher file specified.\n");
253         }
254         #endif
255         smp_idle();
256         assert(0);
257 }
258
259 void manager_klueska()
260 {
261         static struct proc *envs[256];
262         static volatile uint8_t progress = 0;
263
264         if (progress == 0) {
265                 progress++;
266                 panic("what do you want to do?");
267                 //envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
268                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
269                 proc_run_s(envs[0]);
270                 warn("DEPRECATED");
271         }
272         run_scheduler();
273
274         panic("DON'T PANIC");
275 }
276
277 void manager_waterman()
278 {
279         static bool first = true;
280         if (first)
281                 mon_bb(0, 0, 0);
282         smp_idle();
283         assert(0);
284 }
285
286 void manager_yuzhu()
287 {
288         
289         static uint8_t RACY progress = 0;
290         static struct proc *p;
291
292         // for testing taking cores, check in case 1 for usage
293         uint32_t corelist[MAX_NUM_CPUS];
294         uint32_t num = 3;
295
296         //create_server(init_num_cores, loop);
297
298         monitor(0);
299
300         // quick_proc_run("hello", p);
301
302 }