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