|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 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. ! 11: * ! 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. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 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(); ! 146: ! 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: ! 242: /* ! 243: * Start the user bootstrap. ! 244: */ ! 245: bootstrap_create(); ! 246: ! 247: #if XPR_DEBUG ! 248: xprinit(); /* XXX */ ! 249: #endif XPR_DEBUG ! 250: ! 251: /* ! 252: * Become the pageout daemon. ! 253: */ ! 254: (void) spl0(); ! 255: vm_pageout(); ! 256: /*NOTREACHED*/ ! 257: } ! 258: ! 259: #if NCPUS > 1 ! 260: void slave_main() ! 261: { ! 262: cpu_launch_first_thread(THREAD_NULL); ! 263: } ! 264: #endif NCPUS > 1 ! 265: ! 266: /* ! 267: * Start up the first thread on a CPU. ! 268: * First thread is specified for the master CPU. ! 269: */ ! 270: void cpu_launch_first_thread(th) ! 271: register thread_t th; ! 272: { ! 273: register int mycpu; ! 274: ! 275: mycpu = cpu_number(); ! 276: ! 277: cpu_up(mycpu); ! 278: ! 279: start_timer(&kernel_timer[mycpu]); ! 280: ! 281: /* ! 282: * Block all interrupts for choose_thread. ! 283: */ ! 284: (void) splhigh(); ! 285: ! 286: if (th == THREAD_NULL) ! 287: th = choose_thread(cpu_to_processor(mycpu)); ! 288: if (th == THREAD_NULL) ! 289: panic("cpu_launch_first_thread"); ! 290: ! 291: startrtclock(); /* needs an active thread */ ! 292: PMAP_ACTIVATE_KERNEL(mycpu); ! 293: ! 294: active_threads[mycpu] = th; ! 295: active_stacks[mycpu] = th->kernel_stack; ! 296: thread_lock(th); ! 297: th->state &= ~TH_UNINT; ! 298: thread_unlock(th); ! 299: timer_switch(&th->system_timer); ! 300: ! 301: PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu); ! 302: ! 303: load_context(th); ! 304: /*NOTREACHED*/ ! 305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.