Synced up SPARC port
[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
15 #include <assert.h>
16 #include <manager.h>
17 #include <process.h>
18 #include <schedule.h>
19 #include <workqueue.h>
20 #include <syscall.h>
21 #include <testing.h>
22 #include <kfs.h>
23 #include <stdio.h>
24 #include <timing.h>
25 #include <resource.h>
26 #include <monitor.h>
27 #include <colored_caches.h>
28 #include <string.h>
29
30 /*
31  * Currently, if you leave this function by way of proc_run (process_workqueue
32  * that proc_runs), you will never come back to where you left off, and the
33  * function will start from the top.  Hence the hack 'progress'.
34  */
35 void manager(void)
36 {
37         #ifndef DEVELOPER_NAME
38                 #define DEVELOPER_NAME brho
39         #endif
40
41         // LoL
42         #define PASTE(s1,s2) s1 ## s2
43         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
44
45         void MANAGER_FUNC(DEVELOPER_NAME)(void);
46         MANAGER_FUNC(DEVELOPER_NAME)();
47 }
48
49 void manager_brho(void)
50 {
51         static uint8_t RACY progress = 0;
52
53         static struct proc *envs[256];
54         static struct proc *p ;
55
56         // for testing taking cores, check in case 1 for usage
57         uint32_t corelist[MAX_NUM_CPUS];
58         uint32_t num = 3;
59
60         switch (progress++) {
61                 case 0:
62                         // TODO: need to store the pid for future manager runs, not the *p
63                         //p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
64                         p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
65                         //p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
66                         // being proper and all:
67                         spin_lock_irqsave(&p->proc_lock);
68                         __proc_set_state(p, PROC_RUNNABLE_S);
69                         // normal single-cored way
70                         spin_unlock_irqsave(&p->proc_lock);
71                         proc_run(p);
72                         proc_decref(p, 1);
73                         #if 0
74                         // this is how you can transition to a parallel process manually
75                         // make sure you don't proc run first
76                         __proc_set_state(p, PROC_RUNNING_S);
77                         __proc_set_state(p, PROC_RUNNABLE_M);
78                         p->resources[RES_CORES].amt_wanted = 5;
79                         spin_unlock_irqsave(&p->proc_lock);
80                         core_request(p);
81                         panic("This is okay");
82                         #endif
83                         break;
84                 case 1:
85                         monitor(0);
86                         #if 0
87                         udelay(10000000);
88                         // this is a ghetto way to test restarting an _M
89                                 printk("\nattempting to ghetto preempt...\n");
90                                 spin_lock_irqsave(&p->proc_lock);
91                                 proc_take_allcores(p, __death);
92                                 __proc_set_state(p, PROC_RUNNABLE_M);
93                                 spin_unlock_irqsave(&p->proc_lock);
94                                 udelay(5000000);
95                                 printk("\nattempting to restart...\n");
96                                 core_request(p); // proc still wants the cores
97                         panic("This is okay");
98                         // this tests taking some cores, and later killing an _M
99                                 printk("taking 3 cores from p\n");
100                                 for (int i = 0; i < num; i++)
101                                         corelist[i] = 7-i; // 7, 6, and 5
102                                 spin_lock_irqsave(&p->proc_lock);
103                                 proc_take_cores(p, corelist, &num, __death);
104                                 spin_unlock_irqsave(&p->proc_lock);
105                                 udelay(5000000);
106                                 printk("Killing p\n");
107                                 proc_destroy(p);
108                                 printk("Killed p\n");
109                         panic("This is okay");
110
111                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
112                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
113                         proc_run(envs[0]);
114                         break;
115                         #endif
116                 case 2:
117                         #if 0
118                         panic("Do not panic");
119                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
120                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
121                         smp_call_function_single(1, run_env_handler, envs[0], 0);
122                         smp_call_function_single(2, run_env_handler, envs[1], 0);
123                         break;
124                         #endif
125                 case 3:
126                 #if 0
127                 case 4:
128                         printk("Beginning Tests\n");
129                         test_run_measurements(progress-1);  // should never return
130                         break;
131                 case 5:
132                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
133                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
134                         smp_call_function_single(1, run_env_handler, envs[0], 0);
135                         smp_call_function_single(2, run_env_handler, envs[1], 0);
136                 case 6:
137                 #endif
138                 case 4:
139                         /*
140                         test_smp_call_functions();
141                         test_checklists();
142                         test_barrier();
143                         test_print_info();
144                         test_lapic_status_bit();
145                         test_ipi_sending();
146                         test_pit();
147                         */
148                 case 5:
149                 case 6:
150                 case 7:
151                 case 8:
152                 case 9:
153                 case 10:
154                 case 11:
155                 case 12:
156                 case 13:
157                 case 14:
158                         //test_run_measurements(progress-1);
159                 default:
160                         printk("Manager Progress: %d\n", progress);
161                         // delay if you want to test rescheduling an MCP that yielded
162                         //udelay(15000000);
163                         schedule();
164         }
165         panic("If you see me, then you probably screwed up");
166
167         /*
168         printk("Servicing syscalls from Core 0:\n\n");
169         while (1) {
170                 process_generic_syscalls(&envs[0], 1);
171                 cpu_relax();
172         }
173         */
174         return;
175 }
176
177 void manager_klueska()
178 {
179         static struct proc *envs[256];
180         static uint8_t progress = 0;
181
182         if (progress++ == 0) {
183                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
184                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
185                 proc_run(envs[0]);
186         }
187         schedule();
188
189         panic("DON'T PANIC");
190 }
191
192 #ifdef __sparc_v8__
193
194 static char*
195 itoa(int num, char* buf0, size_t base)
196 {
197         if(base > 16)
198                 return NULL;
199
200         char* buf = buf0;
201         int len = 0, i;
202
203         if(num < 0)
204         {
205                 *buf++ = '-';
206                 num = -num;
207         }
208
209         do {
210                 buf[len++] = "0123456789abcdef"[num%base];
211                 num /= base;
212         } while(num);
213
214         for(i = 0; i < len/2; i++)
215         {
216                 char temp = buf[i];
217                 buf[i] = buf[len-i-1];
218                 buf[len-i-1] = temp;
219         }
220         buf[len] = 0;
221
222         return buf0;
223 }
224
225 void gsf_set_frame_cycles(int cycles)
226 {
227         store_alternate(26*4,2,cycles);
228 }
229
230 void gsf_set_partition_credits(int partition, int credits)
231 {
232         store_alternate((32+partition)*4,2,credits);
233 }
234
235 void gsf_set_core_partition(int core, int partition)
236 {
237         store_alternate((64+core)*4,2,partition);
238 }
239
240 #endif
241
242 void manager_waterman()
243 {
244 #if 0
245
246         static uint8_t progress = 0;
247         if(progress > 0)
248                 goto run_some_apps;     
249
250         #define MAX_APPS 2
251         struct app
252         {
253                 int threads;
254                 int colors;
255                 int credits;
256                 int argc;
257                 char** argv;
258         };
259
260         static struct app apps[MAX_APPS];
261         static int napps = 0;
262
263         // arg format:
264         // #apps [#threads #colors #credits name args] - [#threads ...] - ...
265         assert(argc > 0);
266         napps = atoi(argv[0]);
267         assert(napps <= MAX_APPS);
268         argc--; argv++;
269         for(int a = 0; a < napps; a++)
270         {
271                 assert(argc >= 4);
272                 apps[a].threads = atoi(argv[0]);
273                 apps[a].colors = atoi(argv[1]);
274                 apps[a].credits = atoi(argv[2]);
275                 argc -= 3; argv += 3;
276
277                 apps[a].argc = 0;
278                 apps[a].argv = argv;
279                 while(argc)
280                 {
281                         argc--;
282                         if(strcmp(*argv++,"-") != 0)
283                                 apps[a].argc++;
284                         else
285                                 break;
286                 }
287
288                 printk("app %d: %d threads, %d colors, %d credits\ncommand line: ",a,apps[a].threads,apps[a].colors,apps[a].credits);
289                 for(int i = 0; i < apps[a].argc; i++)
290                         printk("%s ",apps[a].argv[i]);
291                 printk("\n");
292         }
293
294         // DRAM can process requests every 40 cycles.
295         // In a 480-cycle window, this gives us 12 total credits.
296         gsf_set_frame_cycles(482);
297         for(int a = 0, cores_used = 0; a < napps; a++)
298         {
299                 gsf_set_partition_credits(a,apps[a].credits);
300                 for(int i = 0; i < apps[a].threads; i++, cores_used++)
301                         gsf_set_core_partition(num_cpus-cores_used-1,a);
302         }
303
304 run_some_apps:
305         ;
306
307         static struct proc *envs[MAX_APPS];
308         int apps_running = napps;
309         int envs_free[MAX_APPS] = {0};
310         if(progress == napps)
311         {
312                 while(apps_running)
313                 {
314                         for(int i = 0; i < napps; i++)
315                         {
316                                 if(*(volatile uint32_t*)&envs[i]->state == ENV_FREE && !envs_free[i])
317                                 {
318                                         envs_free[i] = 1;
319                                         apps_running--;
320                                         printk("Finished application %d at cycle %lld\n", i, read_tsc()); 
321                                 }
322                         }
323                 }
324                 reboot();
325         }
326         else
327         {
328                 envs[progress] = kfs_proc_create(kfs_lookup_path(apps[progress].argv[0]));
329
330                 envs[progress]->cache_colors_map = cache_colors_map_alloc();
331                 for(int i = 0; i < apps[progress].colors; i++)
332                         assert(cache_color_alloc(llc_cache, envs[progress]->cache_colors_map) == ESUCCESS);
333
334                 proc_set_state(envs[progress], PROC_RUNNABLE_S);
335
336                 if(apps[progress].argc)
337                         proc_init_argc_argv(envs[progress],apps[progress].argc,(const char**)apps[progress].argv);
338
339                 proc_run(envs[progress++]);
340
341                 schedule();
342         }
343 #endif
344         panic("professional bomb technician at work.  if you see me running, try to keep up!");
345 }