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