| /* | 
 |  * Copyright (c) 2009 The Regents of the University of California | 
 |  * Barret Rhoden <brho@cs.berkeley.edu> | 
 |  * See LICENSE for details. | 
 |  */ | 
 |  | 
 |  | 
 | #include <ros/common.h> | 
 | #include <smp.h> | 
 | #include <arch/init.h> | 
 | #include <mm.h> | 
 | #include <elf.h> | 
 |  | 
 | #include <kmalloc.h> | 
 | #include <assert.h> | 
 | #include <manager.h> | 
 | #include <process.h> | 
 | #include <schedule.h> | 
 | #include <syscall.h> | 
 | #include <ktest.h> | 
 | #include <stdio.h> | 
 | #include <time.h> | 
 | #include <monitor.h> | 
 | #include <string.h> | 
 | #include <pmap.h> | 
 | #include <arch/console.h> | 
 | #include <time.h> | 
 |  | 
 | /* | 
 |  * Currently, if you leave this function by way of proc_run (process_workqueue | 
 |  * that proc_runs), you will never come back to where you left off, and the | 
 |  * function will start from the top.  Hence the hack 'progress'. | 
 |  */ | 
 | void manager(void) | 
 | { | 
 | 	// LoL | 
 | 	#define MANAGER_FUNC(dev) PASTE(manager_,dev) | 
 |  | 
 | 	#if !defined(DEVELOPER_NAME) && \ | 
 | 	    (defined(CONFIG_KERNEL_TESTING) || \ | 
 | 	     defined(CONFIG_USERSPACE_TESTING)) | 
 | 		#define DEVELOPER_NAME jenkins | 
 | 	#endif | 
 |  | 
 | 	#ifndef DEVELOPER_NAME | 
 | 		#define DEVELOPER_NAME brho | 
 | 	#endif | 
 |  | 
 | 	void MANAGER_FUNC(DEVELOPER_NAME)(void); | 
 | 	MANAGER_FUNC(DEVELOPER_NAME)(); | 
 | } | 
 |  | 
 | char *p_argv[] = {0, 0, 0}; | 
 | /* Helper macro for quickly running a process.  Pass it a string, *file, and a | 
 |  * *proc. */ | 
 | #define quick_proc_run(x, p, f)                                              \ | 
 | 	(f) = do_file_open((x), O_READ, 0);                                  \ | 
 | 	assert((f));                                                         \ | 
 | 	p_argv[0] = file_name((f));                                          \ | 
 | 	(p) = proc_create((f), p_argv, NULL);                                \ | 
 | 	kref_put(&(f)->f_kref);                                              \ | 
 | 	spin_lock(&(p)->proc_lock);                                          \ | 
 | 	__proc_set_state((p), PROC_RUNNABLE_S);                              \ | 
 | 	spin_unlock(&(p)->proc_lock);                                        \ | 
 | 	proc_run_s((p));                                                     \ | 
 | 	proc_decref((p)); | 
 |  | 
 | #define quick_proc_create(x, p, f)                                           \ | 
 | 	(f) = do_file_open((x), O_READ, 0);                                  \ | 
 | 	assert((f));                                                         \ | 
 | 	p_argv[0] = file_name((f));                                          \ | 
 | 	(p) = proc_create((f), p_argv, NULL);                                \ | 
 | 	kref_put(&(f)->f_kref);                                              \ | 
 | 	spin_lock(&(p)->proc_lock);                                          \ | 
 | 	__proc_set_state((p), PROC_RUNNABLE_S);                              \ | 
 | 	spin_unlock(&(p)->proc_lock); | 
 |  | 
 | #define quick_proc_color_run(x, p, c, f)                                     \ | 
 | 	(f) = do_file_open((x), O_READ, 0);                                  \ | 
 | 	assert((f));                                                         \ | 
 | 	p_argv[0] = file_name((f));                                          \ | 
 | 	(p) = proc_create((f), p_argv, NULL);                                \ | 
 | 	kref_put(&(f)->f_kref);                                              \ | 
 | 	spin_lock(&(p)->proc_lock);                                          \ | 
 | 	__proc_set_state((p), PROC_RUNNABLE_S);                              \ | 
 | 	spin_unlock(&(p)->proc_lock);                                        \ | 
 | 	p->cache_colors_map = cache_colors_map_alloc();                      \ | 
 | 	for (int i = 0; i < (c); i++)                                        \ | 
 | 		cache_color_alloc(llc_cache, p->cache_colors_map);           \ | 
 | 	proc_run_s((p));                                                     \ | 
 | 	proc_decref((p)); | 
 |  | 
 | #define quick_proc_color_create(x, p, c, f)                                  \ | 
 | 	(f) = do_file_open((x), O_READ, 0);                                  \ | 
 | 	assert((f));                                                         \ | 
 | 	p_argv[0] = file_name((f));                                          \ | 
 | 	(p) = proc_create((f), p_argv, NULL);                                \ | 
 | 	kref_put(&(f)->f_kref);                                              \ | 
 | 	spin_lock(&(p)->proc_lock);                                          \ | 
 | 	__proc_set_state((p), PROC_RUNNABLE_S);                              \ | 
 | 	spin_unlock(&(p)->proc_lock);                                        \ | 
 | 	p->cache_colors_map = cache_colors_map_alloc();                      \ | 
 | 	for (int i = 0; i < (c); i++)                                        \ | 
 | 		cache_color_alloc(llc_cache, p->cache_colors_map); | 
 |  | 
 | void manager_brho(void) | 
 | { | 
 | 	static bool first = TRUE; | 
 | 	struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; | 
 |  | 
 | 	if (first) { | 
 | 		printk("*** IRQs must be enabled for input emergency codes ***\n"); | 
 | 		#ifdef CONFIG_X86 | 
 | 		printk("*** Hit ctrl-g to enter the monitor. ***\n"); | 
 | 		printk("*** Hit ctrl-q to force-enter the monitor. ***\n"); | 
 | 		printk("*** Hit ctrl-b for a backtrace of core 0 ***\n"); | 
 | 		#else | 
 | 		printk("*** Hit ctrl-g to enter the monitor. ***\n"); | 
 | 		#warning "***** ctrl-g untested on riscv, check k/a/r/trap.c *****" | 
 | 		#endif | 
 | 		first = FALSE; | 
 | 	} | 
 | 	/* just idle, and deal with things via interrupts.  or via face. */ | 
 | 	smp_idle(); | 
 | 	/* whatever we do in the manager, keep in mind that we need to not do | 
 | 	 * anything too soon (like make processes), since we'll drop in here | 
 | 	 * during boot if the boot sequence required any I/O (like EXT2), and we | 
 | 	 * need to PRKM() */ | 
 | 	assert(0); | 
 |  | 
 | } | 
 |  | 
 | void manager_jenkins() | 
 | { | 
 | 	#ifdef CONFIG_KERNEL_TESTING | 
 | 		printk("<-- BEGIN_KERNEL_TESTS -->\n"); | 
 | 		run_registered_ktest_suites(); | 
 | 		printk("<-- END_KERNEL_TESTS -->\n"); | 
 | 	#endif | 
 |  | 
 | 	// Run userspace tests (from config specified path). | 
 | 	#ifdef CONFIG_USERSPACE_TESTING | 
 | 	if (strlen(CONFIG_USERSPACE_TESTING_SCRIPT) != 0) { | 
 | 		char exec[] = "/bin/ash"; | 
 | 		char *p_argv[] = {exec, CONFIG_USERSPACE_TESTING_SCRIPT, 0}; | 
 |  | 
 | 		struct file *program = do_file_open(exec, O_READ, 0); | 
 | 		struct proc *p = proc_create(program, p_argv, NULL); | 
 | 		proc_wakeup(p); | 
 | 		/* let go of the reference created in proc_create() */ | 
 | 		proc_decref(p); | 
 | 		kref_put(&program->f_kref); | 
 | 		run_scheduler(); | 
 | 	    // Need a way to wait for p to finish | 
 | 	} else { | 
 | 		printk("No user-space launcher file specified.\n"); | 
 | 	} | 
 | 	#endif | 
 | 	smp_idle(); | 
 | 	assert(0); | 
 | } | 
 |  | 
 | void manager_klueska() | 
 | { | 
 | 	static struct proc *envs[256]; | 
 | 	static volatile uint8_t progress = 0; | 
 |  | 
 | 	if (progress == 0) { | 
 | 		progress++; | 
 | 		panic("what do you want to do?"); | 
 | 		//envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup")); | 
 | 		__proc_set_state(envs[0], PROC_RUNNABLE_S); | 
 | 		proc_run_s(envs[0]); | 
 | 		warn("DEPRECATED"); | 
 | 	} | 
 | 	run_scheduler(); | 
 |  | 
 | 	panic("DON'T PANIC"); | 
 | } | 
 |  | 
 | void manager_waterman() | 
 | { | 
 | 	static bool first = true; | 
 |  | 
 | 	if (first) | 
 | 		mon_shell(0, 0, 0); | 
 | 	smp_idle(); | 
 | 	assert(0); | 
 | } | 
 |  | 
 | void manager_yuzhu() | 
 | { | 
 |  | 
 | 	static uint8_t progress = 0; | 
 | 	static struct proc *p; | 
 |  | 
 | 	// for testing taking cores, check in case 1 for usage | 
 | 	uint32_t corelist[MAX_NUM_CORES]; | 
 | 	uint32_t num = 3; | 
 |  | 
 | 	//create_server(init_num_cores, loop); | 
 |  | 
 | 	monitor(0); | 
 |  | 
 | 	// quick_proc_run("hello", p); | 
 |  | 
 | } |