Manager change: Hit Shift-G to get to the monitor
[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 <testing.h>
26 #include <kfs.h>
27 #include <stdio.h>
28 #include <time.h>
29 #include <resource.h>
30 #include <monitor.h>
31 #include <colored_caches.h>
32 #include <string.h>
33 #include <pmap.h>
34 #include <arch/console.h>
35 #include <ros/time.h>
36 #include <ros/arch/membar.h>
37
38 /*
39  * Currently, if you leave this function by way of proc_run (process_workqueue
40  * that proc_runs), you will never come back to where you left off, and the
41  * function will start from the top.  Hence the hack 'progress'.
42  */
43 void manager(void)
44 {
45         #ifndef DEVELOPER_NAME
46                 #define DEVELOPER_NAME brho
47         #endif
48
49         // LoL
50         #define PASTE(s1,s2) s1 ## s2
51         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
52
53         void MANAGER_FUNC(DEVELOPER_NAME)(void);
54         MANAGER_FUNC(DEVELOPER_NAME)();
55 }
56
57 char *p_argv[] = {0, 0, 0};
58 char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
59 /* Helper macro for quickly running a process.  Pass it a string, *file, and a
60  * *proc. */
61 #define quick_proc_run(x, p, f)                                                  \
62         (f) = do_file_open((x), 0, 0);                                               \
63         assert((f));                                                                 \
64         p_argv[0] = file_name((f));                                                  \
65         (p) = proc_create((f), p_argv, p_envp);                                      \
66         kref_put(&(f)->f_kref);                                                      \
67         spin_lock(&(p)->proc_lock);                                                  \
68         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
69         spin_unlock(&(p)->proc_lock);                                                \
70         proc_run((p));                                                               \
71         proc_decref((p));
72
73 #define quick_proc_create(x, p, f)                                               \
74         (f) = do_file_open((x), 0, 0);                                               \
75         assert((f));                                                                 \
76         p_argv[0] = file_name((f));                                                  \
77         (p) = proc_create((f), p_argv, p_envp);                                      \
78         kref_put(&(f)->f_kref);                                                      \
79         spin_lock(&(p)->proc_lock);                                                  \
80         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
81         spin_unlock(&(p)->proc_lock);
82
83 #define quick_proc_color_run(x, p, c, f)                                         \
84         (f) = do_file_open((x), 0, 0);                                               \
85         assert((f));                                                                 \
86         p_argv[0] = file_name((f));                                                  \
87         (p) = proc_create((f), p_argv, p_envp);                                      \
88         kref_put(&(f)->f_kref);                                                      \
89         spin_lock(&(p)->proc_lock);                                                  \
90         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
91         spin_unlock(&(p)->proc_lock);                                                \
92         p->cache_colors_map = cache_colors_map_alloc();                              \
93         for (int i = 0; i < (c); i++)                                                \
94                 cache_color_alloc(llc_cache, p->cache_colors_map);                       \
95         proc_run((p));                                                               \
96         proc_decref((p));
97
98 #define quick_proc_color_create(x, p, c, f)                                      \
99         (f) = do_file_open((x), 0, 0);                                               \
100         assert((f));                                                                 \
101         p_argv[0] = file_name((f));                                                  \
102         (p) = proc_create((f), p_argv, p_envp);                                      \
103         kref_put(&(f)->f_kref);                                                      \
104         spin_lock(&(p)->proc_lock);                                                  \
105         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
106         spin_unlock(&(p)->proc_lock);                                                \
107         p->cache_colors_map = cache_colors_map_alloc();                              \
108         for (int i = 0; i < (c); i++)                                                \
109                 cache_color_alloc(llc_cache, p->cache_colors_map);
110
111 void manager_brho(void)
112 {
113         static uint8_t RACY progress = 0;       /* this will wrap around. */
114         static struct proc *p;
115         struct file *temp_f;
116         static bool first = TRUE;
117
118         if (first) {    
119                 printk("*** Hit shift-g to get into the monitor. ***\n");
120                 first = FALSE;
121         }
122         while (1) {
123                 enable_irq();
124                 /* one time keyboard / serial check for some magic, then monitor */
125                 if (cons_getc() == 'G') {
126                         printk("Heard the call of the giraffe!\n");
127                         monitor(0);
128                 }
129                 process_routine_kmsg(0);
130                 schedule();
131         }
132         /* whatever we do in the manager, keep in mind that we need to not do
133          * anything too soon (like make processes), since we'll drop in here during
134          * boot if the boot sequence required any I/O (like EXT2), and we need to
135          * PRKM() */
136
137         assert(0);
138         /* ancient tests below: */
139
140         // for testing taking cores, check in case 1 for usage
141         uint32_t corelist[MAX_NUM_CPUS];
142         uint32_t num = 3;
143
144         switch (progress++) {
145                 case 0:
146                         printk("Top of the manager to ya!\n");
147                         /* 124 is half of the available boxboro colors (with the kernel
148                          * getting 8) */
149                         //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
150                         quick_proc_run("/bin/hello", p, temp_f);
151                         #if 0
152                         // this is how you can transition to a parallel process manually
153                         // make sure you don't proc run first
154                         __proc_set_state(p, PROC_RUNNING_S);
155                         __proc_set_state(p, PROC_RUNNABLE_M);
156                         p->resources[RES_CORES].amt_wanted = 5;
157                         spin_unlock(&p->proc_lock);
158                         core_request(p);
159                         panic("This is okay");
160                         #endif
161                         break;
162                 case 1:
163                         #if 0
164                         udelay(10000000);
165                         // this is a ghetto way to test restarting an _M
166                                 printk("\nattempting to ghetto preempt...\n");
167                                 spin_lock(&p->proc_lock);
168                                 proc_take_allcores(p, __death);
169                                 __proc_set_state(p, PROC_RUNNABLE_M);
170                                 spin_unlock(&p->proc_lock);
171                                 udelay(5000000);
172                                 printk("\nattempting to restart...\n");
173                                 core_request(p); // proc still wants the cores
174                         panic("This is okay");
175                         // this tests taking some cores, and later killing an _M
176                                 printk("taking 3 cores from p\n");
177                                 for (int i = 0; i < num; i++)
178                                         corelist[i] = 7-i; // 7, 6, and 5
179                                 spin_lock(&p->proc_lock);
180                                 proc_take_cores(p, corelist, &num, __death);
181                                 spin_unlock(&p->proc_lock);
182                                 udelay(5000000);
183                                 printk("Killing p\n");
184                                 proc_destroy(p);
185                                 printk("Killed p\n");
186                         panic("This is okay");
187
188                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
189                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
190                         proc_run(envs[0]);
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                         schedule();
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 }
221
222 void manager_klueska()
223 {
224         static struct proc *envs[256];
225         static volatile uint8_t progress = 0;
226
227         if (progress == 0) {
228                 progress++;
229                 panic("what do you want to do?");
230                 //envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
231                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
232                 proc_run(envs[0]);
233         }
234         schedule();
235
236         panic("DON'T PANIC");
237 }
238
239 void manager_waterman()
240 {
241         schedule();
242         monitor(0);
243         assert(0);
244 }
245
246 void manager_pearce()
247 {
248         static struct proc *envs[256];
249         static volatile uint8_t progress = 0;
250
251         if (progress == 0) {
252                 progress++;
253                 panic("what do you want to do?");
254                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_httpserver_integrated"));
255                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_lock_test"));
256                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
257                 proc_run(envs[0]);
258         }
259         schedule();
260
261         panic("DON'T PANIC");
262
263 }
264
265 void manager_yuzhu()
266 {
267         
268         static uint8_t RACY progress = 0;
269         static struct proc *p;
270
271         // for testing taking cores, check in case 1 for usage
272         uint32_t corelist[MAX_NUM_CPUS];
273         uint32_t num = 3;
274
275         //create_server(init_num_cores, loop);
276
277         monitor(0);
278
279         // quick_proc_run("hello", p);
280
281 }
282
283 #ifdef __sparc_v8__
284
285 static char*
286 itoa(int num, char* buf0, size_t base)
287 {
288         if(base > 16)
289                 return NULL;
290
291         char* buf = buf0;
292         int len = 0, i;
293
294         if(num < 0)
295         {
296                 *buf++ = '-';
297                 num = -num;
298         }
299
300         do {
301                 buf[len++] = "0123456789abcdef"[num%base];
302                 num /= base;
303         } while(num);
304
305         for(i = 0; i < len/2; i++)
306         {
307                 char temp = buf[i];
308                 buf[i] = buf[len-i-1];
309                 buf[len-i-1] = temp;
310         }
311         buf[len] = 0;
312
313         return buf0;
314 }
315
316 void gsf_set_frame_cycles(int cycles)
317 {
318         store_alternate(26*4,2,cycles);
319 }
320
321 void gsf_set_partition_credits(int partition, int credits)
322 {
323         store_alternate((32+partition)*4,2,credits);
324 }
325
326 void gsf_set_core_partition(int core, int partition)
327 {
328         store_alternate((64+core)*4,2,partition);
329 }
330
331 #endif
332