|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 6: * Permission to use, copy, modify and distribute this software and its 7: * documentation is hereby granted, provided that both the copyright 8: * notice and this permission notice appear in all copies of the 9: * software, derivative works or modified versions, and any portions 10: * thereof, and that both notices appear in supporting documentation. 1.1.1.2 ! root 11: * 1.1 root 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon 24: * the rights to redistribute these changes. 25: */ 26: /* 27: * Mach kernel startup. 28: */ 29: 30: 31: #include <xpr_debug.h> 32: #include <cpus.h> 33: #include <mach_host.h> 34: #include <norma_ipc.h> 35: #include <norma_vm.h> 36: 37: #include <mach/boolean.h> 38: #include <mach/machine.h> 39: #include <mach/task_special_ports.h> 40: #include <mach/vm_param.h> 41: #include <ipc/ipc_init.h> 42: #include <kern/cpu_number.h> 43: #include <kern/processor.h> 44: #include <kern/sched_prim.h> 45: #include <kern/task.h> 46: #include <kern/thread.h> 47: #include <kern/thread_swap.h> 48: #include <kern/time_out.h> 49: #include <kern/timer.h> 50: #include <kern/zalloc.h> 51: #include <vm/vm_kern.h> 52: #include <vm/vm_map.h> 53: #include <vm/vm_object.h> 54: #include <vm/vm_page.h> 55: #include <machine/machspl.h> 56: #include <machine/pmap.h> 57: #include <mach/version.h> 58: 59: 60: 61: extern void vm_mem_init(); 62: extern void vm_mem_bootstrap(); 63: extern void init_timeout(); 64: extern void machine_init(); 65: 66: extern void idle_thread(); 67: extern void vm_pageout(); 68: extern void reaper_thread(); 69: extern void swapin_thread(); 70: extern void sched_thread(); 71: 72: extern void bootstrap_create(); 73: extern void device_service_create(); 74: 75: void cpu_launch_first_thread(); /* forward */ 76: void start_kernel_threads(); /* forward */ 77: 78: #if NCPUS > 1 79: extern void start_other_cpus(); 80: extern void action_thread(); 81: #endif NCPUS > 1 82: 83: /* XX */ 84: extern vm_offset_t phys_first_addr, phys_last_addr; 85: 86: /* 87: * Running in virtual memory, on the interrupt stack. 88: * Does not return. Dispatches initial thread. 89: * 90: * Assumes that master_cpu is set. 91: */ 92: void setup_main() 93: { 94: thread_t startup_thread; 95: 96: panic_init(); 97: printf_init(); 98: 99: sched_init(); 100: vm_mem_bootstrap(); 101: ipc_bootstrap(); 102: vm_mem_init(); 103: ipc_init(); 104: 105: /* 106: * As soon as the virtual memory system is up, we record 107: * that this CPU is using the kernel pmap. 108: */ 109: PMAP_ACTIVATE_KERNEL(master_cpu); 110: 111: init_timers(); 112: init_timeout(); 113: 114: #if XPR_DEBUG 115: xprbootstrap(); 116: #endif XPR_DEBUG 117: 118: timestamp_init(); 119: 120: mapable_time_init(); 121: 122: machine_init(); 123: 124: machine_info.max_cpus = NCPUS; 125: machine_info.memory_size = phys_last_addr - phys_first_addr; /* XXX mem_size */ 126: machine_info.avail_cpus = 0; 127: machine_info.major_version = KERNEL_MAJOR_VERSION; 128: machine_info.minor_version = KERNEL_MINOR_VERSION; 129: 130: /* 131: * Initialize the IPC, task, and thread subsystems. 132: */ 133: task_init(); 134: thread_init(); 135: swapper_init(); 136: #if MACH_HOST 137: pset_sys_init(); 138: #endif MACH_HOST 139: 140: /* 141: * Kick off the time-out driven routines by calling 142: * them the first time. 143: */ 144: recompute_priorities(); 145: compute_mach_factor(); 1.1.1.2 ! root 146: 1.1 root 147: /* 148: * Create a kernel thread to start the other kernel 149: * threads. Thread_resume (from kernel_thread) calls 150: * thread_setrun, which may look at current thread; 151: * we must avoid this, since there is no current thread. 152: */ 153: 154: /* 155: * Create the thread, and point it at the routine. 156: */ 157: (void) thread_create(kernel_task, &startup_thread); 158: thread_start(startup_thread, start_kernel_threads); 159: 160: /* 161: * Give it a kernel stack. 162: */ 163: thread_doswapin(startup_thread); 164: 165: /* 166: * Pretend it is already running, and resume it. 167: * Since it looks as if it is running, thread_resume 168: * will not try to put it on the run queues. 169: * 170: * We can do all of this without locking, because nothing 171: * else is running yet. 172: */ 173: startup_thread->state |= TH_RUN; 174: (void) thread_resume(startup_thread); 175: 176: /* 177: * Start the thread. 178: */ 179: cpu_launch_first_thread(startup_thread); 180: /*NOTREACHED*/ 181: } 182: 183: /* 184: * Now running in a thread. Create the rest of the kernel threads 185: * and the bootstrap task. 186: */ 187: void start_kernel_threads() 188: { 189: register int i; 190: 191: /* 192: * Create the idle threads and the other 193: * service threads. 194: */ 195: for (i = 0; i < NCPUS; i++) { 196: if (machine_slot[i].is_cpu) { 197: thread_t th; 198: 199: (void) thread_create(kernel_task, &th); 200: thread_bind(th, cpu_to_processor(i)); 201: thread_start(th, idle_thread); 202: thread_doswapin(th); 203: (void) thread_resume(th); 204: } 205: } 206: 207: (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); 208: (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); 209: (void) kernel_thread(kernel_task, sched_thread, (char *) 0); 210: 211: #if NCPUS > 1 212: /* 213: * Create the shutdown thread. 214: */ 215: (void) kernel_thread(kernel_task, action_thread, (char *) 0); 216: 217: /* 218: * Allow other CPUs to run. 219: */ 220: start_other_cpus(); 221: #endif NCPUS > 1 222: 223: /* 224: * Create the device service. 225: */ 226: device_service_create(); 227: 228: /* 229: * Initialize NORMA ipc system. 230: */ 231: #if NORMA_IPC 232: norma_ipc_init(); 233: #endif NORMA_IPC 234: 235: /* 236: * Initialize NORMA vm system. 237: */ 238: #if NORMA_VM 239: norma_vm_init(); 240: #endif NORMA_VM 241: 1.1.1.2 ! root 242: ! 243: /* ! 244: * Initialize kernel task's creation time. ! 245: * When we created the kernel task in task_init, the mapped ! 246: * time was not yet available. Now, last thing before starting ! 247: * the user bootstrap, record the current time as the kernel ! 248: * task's creation time. ! 249: */ ! 250: record_time_stamp (&kernel_task->creation_time); ! 251: 1.1 root 252: /* 253: * Start the user bootstrap. 254: */ 255: bootstrap_create(); 256: 257: #if XPR_DEBUG 258: xprinit(); /* XXX */ 259: #endif XPR_DEBUG 260: 261: /* 262: * Become the pageout daemon. 263: */ 264: (void) spl0(); 265: vm_pageout(); 266: /*NOTREACHED*/ 267: } 268: 269: #if NCPUS > 1 270: void slave_main() 271: { 272: cpu_launch_first_thread(THREAD_NULL); 273: } 274: #endif NCPUS > 1 275: 276: /* 277: * Start up the first thread on a CPU. 278: * First thread is specified for the master CPU. 279: */ 280: void cpu_launch_first_thread(th) 281: register thread_t th; 282: { 283: register int mycpu; 284: 285: mycpu = cpu_number(); 286: 287: cpu_up(mycpu); 288: 289: start_timer(&kernel_timer[mycpu]); 290: 291: /* 292: * Block all interrupts for choose_thread. 293: */ 294: (void) splhigh(); 295: 296: if (th == THREAD_NULL) 297: th = choose_thread(cpu_to_processor(mycpu)); 298: if (th == THREAD_NULL) 299: panic("cpu_launch_first_thread"); 300: 301: startrtclock(); /* needs an active thread */ 302: PMAP_ACTIVATE_KERNEL(mycpu); 303: 304: active_threads[mycpu] = th; 305: active_stacks[mycpu] = th->kernel_stack; 306: thread_lock(th); 307: th->state &= ~TH_UNINT; 308: thread_unlock(th); 309: timer_switch(&th->system_timer); 310: 311: PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu); 312: 313: load_context(th); 314: /*NOTREACHED*/ 315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.