Added demand paging support
[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 #ifdef __SHARC__
8 #pragma nosharc
9 #endif
10
11 #include <ros/common.h>
12 #include <smp.h>
13 #include <arch/init.h>
14 #include <mm.h>
15 #include <elf.h>
16 #include <frontend.h>
17
18 #include <kmalloc.h>
19 #include <assert.h>
20 #include <manager.h>
21 #include <process.h>
22 #include <schedule.h>
23 #include <workqueue.h>
24 #include <syscall.h>
25 #include <testing.h>
26 #include <kfs.h>
27 #include <stdio.h>
28 #include <timing.h>
29 #include <resource.h>
30 #include <monitor.h>
31 #include <colored_caches.h>
32 #include <string.h>
33 #include <pmap.h>
34
35 /*
36  * Currently, if you leave this function by way of proc_run (process_workqueue
37  * that proc_runs), you will never come back to where you left off, and the
38  * function will start from the top.  Hence the hack 'progress'.
39  */
40 void manager(void)
41 {
42         #ifndef DEVELOPER_NAME
43                 #define DEVELOPER_NAME brho
44         #endif
45
46         // LoL
47         #define PASTE(s1,s2) s1 ## s2
48         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
49
50         void MANAGER_FUNC(DEVELOPER_NAME)(void);
51         MANAGER_FUNC(DEVELOPER_NAME)();
52 }
53
54 void manager_brho(void)
55 {
56         static uint8_t RACY progress = 0;
57
58         static struct proc *envs[256];
59         static struct proc *p ;
60
61         // for testing taking cores, check in case 1 for usage
62         uint32_t corelist[MAX_NUM_CPUS];
63         uint32_t num = 3;
64
65         switch (progress++) {
66                 case 0:
67                         // TODO: need to store the pid for future manager runs, not the *p
68                         p = kfs_proc_create(kfs_lookup_path("parlib_mhello"));
69                         //p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
70                         //p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
71                         //p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
72                         // being proper and all:
73                         spin_lock_irqsave(&p->proc_lock);
74                         __proc_set_state(p, PROC_RUNNABLE_S);
75                         // normal single-cored way
76                         spin_unlock_irqsave(&p->proc_lock);
77                         proc_run(p);
78                         proc_decref(p, 1);
79                         #if 0
80                         // this is how you can transition to a parallel process manually
81                         // make sure you don't proc run first
82                         __proc_set_state(p, PROC_RUNNING_S);
83                         __proc_set_state(p, PROC_RUNNABLE_M);
84                         p->resources[RES_CORES].amt_wanted = 5;
85                         spin_unlock_irqsave(&p->proc_lock);
86                         core_request(p);
87                         panic("This is okay");
88                         #endif
89                         break;
90                 case 1:
91                         monitor(0);
92                         #if 0
93                         udelay(10000000);
94                         // this is a ghetto way to test restarting an _M
95                                 printk("\nattempting to ghetto preempt...\n");
96                                 spin_lock_irqsave(&p->proc_lock);
97                                 proc_take_allcores(p, __death);
98                                 __proc_set_state(p, PROC_RUNNABLE_M);
99                                 spin_unlock_irqsave(&p->proc_lock);
100                                 udelay(5000000);
101                                 printk("\nattempting to restart...\n");
102                                 core_request(p); // proc still wants the cores
103                         panic("This is okay");
104                         // this tests taking some cores, and later killing an _M
105                                 printk("taking 3 cores from p\n");
106                                 for (int i = 0; i < num; i++)
107                                         corelist[i] = 7-i; // 7, 6, and 5
108                                 spin_lock_irqsave(&p->proc_lock);
109                                 proc_take_cores(p, corelist, &num, __death);
110                                 spin_unlock_irqsave(&p->proc_lock);
111                                 udelay(5000000);
112                                 printk("Killing p\n");
113                                 proc_destroy(p);
114                                 printk("Killed p\n");
115                         panic("This is okay");
116
117                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
118                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
119                         proc_run(envs[0]);
120                         break;
121                         #endif
122                 case 2:
123                         #if 0
124                         panic("Do not panic");
125                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
126                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
127                         smp_call_function_single(1, run_env_handler, envs[0], 0);
128                         smp_call_function_single(2, run_env_handler, envs[1], 0);
129                         break;
130                         #endif
131                 case 3:
132                 #if 0
133                 case 4:
134                         printk("Beginning Tests\n");
135                         test_run_measurements(progress-1);  // should never return
136                         break;
137                 case 5:
138                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
139                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
140                         smp_call_function_single(1, run_env_handler, envs[0], 0);
141                         smp_call_function_single(2, run_env_handler, envs[1], 0);
142                 case 6:
143                 #endif
144                 case 4:
145                         /*
146                         test_smp_call_functions();
147                         test_checklists();
148                         test_barrier();
149                         test_print_info();
150                         test_lapic_status_bit();
151                         test_ipi_sending();
152                         test_pit();
153                         */
154                 case 5:
155                 case 6:
156                 case 7:
157                 case 8:
158                 case 9:
159                 case 10:
160                 case 11:
161                 case 12:
162                 case 13:
163                 case 14:
164                         //test_run_measurements(progress-1);
165                 default:
166                         printk("Manager Progress: %d\n", progress);
167                         // delay if you want to test rescheduling an MCP that yielded
168                         //udelay(15000000);
169                         schedule();
170         }
171         panic("If you see me, then you probably screwed up");
172
173         /*
174         printk("Servicing syscalls from Core 0:\n\n");
175         while (1) {
176                 process_generic_syscalls(&envs[0], 1);
177                 cpu_relax();
178         }
179         */
180         return;
181 }
182
183 void manager_klueska()
184 {
185         static struct proc *envs[256];
186         static volatile uint8_t progress = 0;
187
188         if (progress == 0) {
189                 progress++;
190                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
191                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
192                 proc_run(envs[0]);
193         }
194         schedule();
195
196         panic("DON'T PANIC");
197 }
198
199 struct elf_info
200 {
201         long entry;
202         long phdr;
203         int phnum;
204         int dynamic;
205         char interp[256];
206 };
207
208 void manager_waterman()
209 {
210         static int init = 0;
211         if(!init)
212         {
213                 init = 1;
214                 struct proc* p = proc_create(NULL,0);
215
216                 char* argv[] = {"/bin/sh","-l",0};
217                 char* envp[] = {"LD_LIBRARY_PATH=/lib",0};
218                 procinfo_pack_args(p->env_procinfo,argv,envp);
219
220                 struct file* f = file_open("/bin/busybox",0,0);
221                 assert(f != NULL);
222                 assert(load_elf(p,f) == 0);
223                 file_decref(f);
224
225                 __proc_set_state(p, PROC_RUNNABLE_S);
226                 proc_run(p);
227         }
228         schedule();
229 }
230
231 void manager_pearce()
232 {
233         static struct proc *envs[256];
234         static volatile uint8_t progress = 0;
235
236         if (progress == 0) {
237                 progress++;
238                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_httpserver"));
239                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_lock_test"));
240                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
241                 proc_run(envs[0]);
242         }
243         schedule();
244
245         panic("DON'T PANIC");
246
247 }
248
249
250 #ifdef __sparc_v8__
251
252 static char*
253 itoa(int num, char* buf0, size_t base)
254 {
255         if(base > 16)
256                 return NULL;
257
258         char* buf = buf0;
259         int len = 0, i;
260
261         if(num < 0)
262         {
263                 *buf++ = '-';
264                 num = -num;
265         }
266
267         do {
268                 buf[len++] = "0123456789abcdef"[num%base];
269                 num /= base;
270         } while(num);
271
272         for(i = 0; i < len/2; i++)
273         {
274                 char temp = buf[i];
275                 buf[i] = buf[len-i-1];
276                 buf[len-i-1] = temp;
277         }
278         buf[len] = 0;
279
280         return buf0;
281 }
282
283 void gsf_set_frame_cycles(int cycles)
284 {
285         store_alternate(26*4,2,cycles);
286 }
287
288 void gsf_set_partition_credits(int partition, int credits)
289 {
290         store_alternate((32+partition)*4,2,credits);
291 }
292
293 void gsf_set_core_partition(int core, int partition)
294 {
295         store_alternate((64+core)*4,2,partition);
296 }
297
298 #endif
299