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