Separated user-space config variable into two.
[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 <test_infrastructure.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 char *kern_test_msg; // Variable defined in test_infrastructure.h.
38
39
40 void postboot_kernel_tests(void)
41 {
42         printk("\nRunning %d postboot Kernel tests:\n", 
43                    num_pb_kernel_tests);
44
45         // Do not remove this line, it is being used by Jenkins.
46         printk("<-- BEGIN_KERNEL_POSTBOOT_TESTS -->\n");
47         for (int i=0; i<num_pb_kernel_tests; i++) {
48                 struct pb_kernel_test *test = &pb_kernel_tests[i];
49                 if (test->enabled) {
50                         uint64_t start = read_tsc();
51                         bool result = test->func();
52                         uint64_t end = read_tsc();
53                         uint64_t et_us = tsc2usec(end - start) % 1000000;
54                         uint64_t et_s = tsc2sec(end - start);
55
56                         if (result) {
57                                 printk("\tPASSED   [%s](%llu.%06llus)\n", test->name, et_s, 
58                                        et_us);
59                         } else {
60                                 printk("\tFAILED   [%s](%llu.%06llus)  %s\n", test->name, et_s, 
61                                        et_us, kern_test_msg);
62                                 kfree(kern_test_msg);
63                         }
64                 } else {
65                         printk("\tDISABLED [%s]\n", test->name);
66                 }
67         }
68         // Do not remove this line, it is being used by Jenkins.
69         printk("<-- END_KERNEL_POSTBOOT_TESTS -->\n");
70 }
71
72 /*
73  * Currently, if you leave this function by way of proc_run (process_workqueue
74  * that proc_runs), you will never come back to where you left off, and the
75  * function will start from the top.  Hence the hack 'progress'.
76  */
77 void manager(void)
78 {
79         #ifndef DEVELOPER_NAME
80                 #define DEVELOPER_NAME brho
81         #endif
82
83         // LoL
84         #define PASTE(s1,s2) s1 ## s2
85         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
86
87         // Run Kernel post boot tests (from tests_postboot_kernel.c).
88         #ifdef CONFIG_POSTBOOT_KERNEL_TESTING
89                 postboot_kernel_tests();
90         #endif
91         // Run userspace tests (from config specified path).
92         #ifdef CONFIG_USERSPACE_TESTING
93         if (strlen(CONFIG_USERSPACE_TESTING_SCRIPT) != 0)
94         {
95                 char *usp_args[] = {"bin_run", "ash", CONFIG_USERSPACE_TESTING_SCRIPT};
96                 mon_bin_run(3, usp_args, NULL);
97         } else {
98                 printk("No user-space launcher file specified.\n");
99         }
100         #endif
101
102         void MANAGER_FUNC(DEVELOPER_NAME)(void);
103         MANAGER_FUNC(DEVELOPER_NAME)();
104 }
105
106 char *p_argv[] = {0, 0, 0};
107 char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
108 /* Helper macro for quickly running a process.  Pass it a string, *file, and a
109  * *proc. */
110 #define quick_proc_run(x, p, f)                                                  \
111         (f) = do_file_open((x), 0, 0);                                               \
112         assert((f));                                                                 \
113         p_argv[0] = file_name((f));                                                  \
114         (p) = proc_create((f), p_argv, p_envp);                                      \
115         kref_put(&(f)->f_kref);                                                      \
116         spin_lock(&(p)->proc_lock);                                                  \
117         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
118         spin_unlock(&(p)->proc_lock);                                                \
119         proc_run_s((p));                                                             \
120         proc_decref((p));
121
122 #define quick_proc_create(x, p, f)                                               \
123         (f) = do_file_open((x), 0, 0);                                               \
124         assert((f));                                                                 \
125         p_argv[0] = file_name((f));                                                  \
126         (p) = proc_create((f), p_argv, p_envp);                                      \
127         kref_put(&(f)->f_kref);                                                      \
128         spin_lock(&(p)->proc_lock);                                                  \
129         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
130         spin_unlock(&(p)->proc_lock);
131
132 #define quick_proc_color_run(x, p, c, f)                                         \
133         (f) = do_file_open((x), 0, 0);                                               \
134         assert((f));                                                                 \
135         p_argv[0] = file_name((f));                                                  \
136         (p) = proc_create((f), p_argv, p_envp);                                      \
137         kref_put(&(f)->f_kref);                                                      \
138         spin_lock(&(p)->proc_lock);                                                  \
139         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
140         spin_unlock(&(p)->proc_lock);                                                \
141         p->cache_colors_map = cache_colors_map_alloc();                              \
142         for (int i = 0; i < (c); i++)                                                \
143                 cache_color_alloc(llc_cache, p->cache_colors_map);                       \
144         proc_run_s((p));                                                             \
145         proc_decref((p));
146
147 #define quick_proc_color_create(x, p, c, f)                                      \
148         (f) = do_file_open((x), 0, 0);                                               \
149         assert((f));                                                                 \
150         p_argv[0] = file_name((f));                                                  \
151         (p) = proc_create((f), p_argv, p_envp);                                      \
152         kref_put(&(f)->f_kref);                                                      \
153         spin_lock(&(p)->proc_lock);                                                  \
154         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
155         spin_unlock(&(p)->proc_lock);                                                \
156         p->cache_colors_map = cache_colors_map_alloc();                              \
157         for (int i = 0; i < (c); i++)                                                \
158                 cache_color_alloc(llc_cache, p->cache_colors_map);
159
160 void manager_brho(void)
161 {
162         static bool first = TRUE;
163         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
164
165         if (first) {    
166                 printk("*** IRQs must be enabled for input emergency codes ***\n");
167                 #ifdef CONFIG_X86
168                 printk("*** Hit ctrl-g to enter the monitor. ***\n");
169                 printk("*** Hit ctrl-q to force-enter the monitor. ***\n");
170                 printk("*** Hit ctrl-b for a backtrace of core 0 ***\n");
171                 #else
172                 printk("*** Hit ctrl-g to enter the monitor. ***\n");
173                 #warning "***** ctrl-g untested on riscv, check k/a/r/trap.c *****"
174                 #endif
175                 first = FALSE;
176         }
177         /* just idle, and deal with things via interrupts.  or via face. */
178         smp_idle();
179         /* whatever we do in the manager, keep in mind that we need to not do
180          * anything too soon (like make processes), since we'll drop in here during
181          * boot if the boot sequence required any I/O (like EXT2), and we need to
182          * PRKM() */
183         assert(0);
184
185 #if 0 /* ancient tests below: (keeping around til we ditch the manager) */
186         // for testing taking cores, check in case 1 for usage
187         uint32_t corelist[MAX_NUM_CPUS];
188         uint32_t num = 3;
189         struct file *temp_f;
190         static struct proc *p;
191
192         static uint8_t RACY progress = 0;       /* this will wrap around. */
193         switch (progress++) {
194                 case 0:
195                         printk("Top of the manager to ya!\n");
196                         /* 124 is half of the available boxboro colors (with the kernel
197                          * getting 8) */
198                         //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
199                         quick_proc_run("/bin/hello", p, temp_f);
200                         #if 0
201                         // this is how you can transition to a parallel process manually
202                         // make sure you don't proc run first
203                         __proc_set_state(p, PROC_RUNNING_S);
204                         __proc_set_state(p, PROC_RUNNABLE_M);
205                         p->resources[RES_CORES].amt_wanted = 5;
206                         spin_unlock(&p->proc_lock);
207                         core_request(p);
208                         panic("This is okay");
209                         #endif
210                         break;
211                 case 1:
212                         #if 0
213                         udelay(10000000);
214                         // this is a ghetto way to test restarting an _M
215                                 printk("\nattempting to ghetto preempt...\n");
216                                 spin_lock(&p->proc_lock);
217                                 proc_take_allcores(p, __death);
218                                 __proc_set_state(p, PROC_RUNNABLE_M);
219                                 spin_unlock(&p->proc_lock);
220                                 udelay(5000000);
221                                 printk("\nattempting to restart...\n");
222                                 core_request(p); // proc still wants the cores
223                         panic("This is okay");
224                         // this tests taking some cores, and later killing an _M
225                                 printk("taking 3 cores from p\n");
226                                 for (int i = 0; i < num; i++)
227                                         corelist[i] = 7-i; // 7, 6, and 5
228                                 spin_lock(&p->proc_lock);
229                                 proc_take_cores(p, corelist, &num, __death);
230                                 spin_unlock(&p->proc_lock);
231                                 udelay(5000000);
232                                 printk("Killing p\n");
233                                 enable_irq();
234                                 proc_destroy(p);
235                                 printk("Killed p\n");
236                         panic("This is okay");
237
238                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
239                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
240                         proc_run(envs[0]);
241                         warn("DEPRECATED");
242                         break;
243                         #endif
244                 case 2:
245                         /*
246                         test_smp_call_functions();
247                         test_checklists();
248                         test_barrier();
249                         test_print_info();
250                         test_lapic_status_bit();
251                         test_ipi_sending();
252                         test_pit();
253                         */
254                 default:
255                         printd("Manager Progress: %d\n", progress);
256                         // delay if you want to test rescheduling an MCP that yielded
257                         //udelay(15000000);
258                         run_scheduler();
259         }
260         panic("If you see me, then you probably screwed up");
261         monitor(0);
262
263         /*
264         printk("Servicing syscalls from Core 0:\n\n");
265         while (1) {
266                 process_generic_syscalls(&envs[0], 1);
267                 cpu_relax();
268         }
269         */
270         return;
271 #endif
272 }
273
274 void manager_klueska()
275 {
276         static struct proc *envs[256];
277         static volatile uint8_t progress = 0;
278
279         if (progress == 0) {
280                 progress++;
281                 panic("what do you want to do?");
282                 //envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
283                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
284                 proc_run_s(envs[0]);
285                 warn("DEPRECATED");
286         }
287         run_scheduler();
288
289         panic("DON'T PANIC");
290 }
291
292 void manager_waterman()
293 {
294         static bool first = true;
295         if (first)
296                 mon_bb(0, 0, 0);
297         smp_idle();
298         assert(0);
299 }
300
301 void manager_yuzhu()
302 {
303         
304         static uint8_t RACY progress = 0;
305         static struct proc *p;
306
307         // for testing taking cores, check in case 1 for usage
308         uint32_t corelist[MAX_NUM_CPUS];
309         uint32_t num = 3;
310
311         //create_server(init_num_cores, loop);
312
313         monitor(0);
314
315         // quick_proc_run("hello", p);
316
317 }