|
|
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:
1.1.1.4 root 30: #include <string.h>
1.1 root 31:
32: #include <mach/boolean.h>
33: #include <mach/machine.h>
34: #include <mach/task_special_ports.h>
35: #include <mach/vm_param.h>
36: #include <ipc/ipc_init.h>
37: #include <kern/cpu_number.h>
1.1.1.4 root 38: #include <kern/debug.h>
1.1.1.7 ! root 39: #include <kern/gsync.h>
1.1.1.4 root 40: #include <kern/machine.h>
41: #include <kern/mach_factor.h>
42: #include <kern/mach_clock.h>
1.1 root 43: #include <kern/processor.h>
1.1.1.6 root 44: #include <kern/rdxtree.h>
1.1 root 45: #include <kern/sched_prim.h>
46: #include <kern/task.h>
47: #include <kern/thread.h>
48: #include <kern/thread_swap.h>
49: #include <kern/timer.h>
1.1.1.4 root 50: #include <kern/xpr.h>
1.1.1.5 root 51: #include <kern/bootstrap.h>
1.1.1.4 root 52: #include <kern/time_stamp.h>
1.1.1.5 root 53: #include <kern/startup.h>
1.1 root 54: #include <vm/vm_kern.h>
55: #include <vm/vm_map.h>
56: #include <vm/vm_object.h>
57: #include <vm/vm_page.h>
1.1.1.5 root 58: #include <vm/vm_init.h>
59: #include <vm/vm_pageout.h>
1.1 root 60: #include <machine/machspl.h>
1.1.1.4 root 61: #include <machine/pcb.h>
1.1 root 62: #include <machine/pmap.h>
1.1.1.4 root 63: #include <machine/model_dep.h>
1.1 root 64: #include <mach/version.h>
1.1.1.5 root 65: #include <device/device_init.h>
1.1 root 66:
1.1.1.5 root 67: #if MACH_KDB
68: #include <device/cons.h>
69: #endif /* MACH_KDB */
1.1 root 70:
1.1.1.4 root 71: #if ! MACH_KBD
1.1.1.5 root 72: boolean_t reboot_on_panic = TRUE;
1.1.1.4 root 73: #endif
74:
1.1 root 75: #if NCPUS > 1
1.1.1.5 root 76: #include <machine/mp_desc.h>
77: #include <kern/machine.h>
1.1.1.3 root 78: #endif /* NCPUS > 1 */
1.1 root 79:
80: /* XX */
81: extern vm_offset_t phys_first_addr, phys_last_addr;
1.1.1.4 root 82: extern char *kernel_cmdline;
1.1 root 83:
84: /*
85: * Running in virtual memory, on the interrupt stack.
86: * Does not return. Dispatches initial thread.
87: *
88: * Assumes that master_cpu is set.
89: */
1.1.1.5 root 90: void setup_main(void)
1.1 root 91: {
92: thread_t startup_thread;
93:
1.1.1.4 root 94: #if MACH_KDB
95: /*
96: * Cause a breakpoint trap to the debugger before proceeding
97: * any further if the proper option flag was specified
98: * on the kernel's command line.
99: * XXX check for surrounding spaces.
100: */
101: if (strstr(kernel_cmdline, "-d ")) {
102: cninit(); /* need console for debugger */
103: SoftDebugger("init");
104: }
105: #else /* MACH_KDB */
106: if (strstr (kernel_cmdline, "-H ")) {
1.1.1.5 root 107: reboot_on_panic = FALSE;
1.1.1.4 root 108: }
109: #endif /* MACH_KDB */
110:
1.1 root 111: panic_init();
112:
113: sched_init();
114: vm_mem_bootstrap();
1.1.1.6 root 115: rdxtree_cache_init();
1.1 root 116: ipc_bootstrap();
117: vm_mem_init();
118: ipc_init();
119:
120: /*
121: * As soon as the virtual memory system is up, we record
122: * that this CPU is using the kernel pmap.
123: */
124: PMAP_ACTIVATE_KERNEL(master_cpu);
125:
126: init_timers();
127: init_timeout();
128:
129: #if XPR_DEBUG
130: xprbootstrap();
1.1.1.3 root 131: #endif /* XPR_DEBUG */
1.1 root 132:
133: timestamp_init();
134:
135: machine_init();
136:
1.1.1.4 root 137: mapable_time_init();
138:
1.1 root 139: machine_info.max_cpus = NCPUS;
1.1.1.7 ! root 140: machine_info.memory_size = vm_page_mem_size(); /* XXX phys_addr_t -> vm_size_t */
1.1 root 141: machine_info.avail_cpus = 0;
142: machine_info.major_version = KERNEL_MAJOR_VERSION;
143: machine_info.minor_version = KERNEL_MINOR_VERSION;
144:
145: /*
146: * Initialize the IPC, task, and thread subsystems.
147: */
148: task_init();
149: thread_init();
150: swapper_init();
151: #if MACH_HOST
152: pset_sys_init();
1.1.1.3 root 153: #endif /* MACH_HOST */
1.1 root 154:
155: /*
156: * Kick off the time-out driven routines by calling
157: * them the first time.
158: */
1.1.1.5 root 159: recompute_priorities(NULL);
1.1 root 160: compute_mach_factor();
1.1.1.2 root 161:
1.1.1.7 ! root 162: gsync_setup ();
! 163:
1.1 root 164: /*
165: * Create a kernel thread to start the other kernel
166: * threads. Thread_resume (from kernel_thread) calls
167: * thread_setrun, which may look at current thread;
168: * we must avoid this, since there is no current thread.
169: */
170:
171: /*
172: * Create the thread, and point it at the routine.
173: */
174: (void) thread_create(kernel_task, &startup_thread);
175: thread_start(startup_thread, start_kernel_threads);
176:
177: /*
178: * Give it a kernel stack.
179: */
180: thread_doswapin(startup_thread);
181:
182: /*
183: * Pretend it is already running, and resume it.
184: * Since it looks as if it is running, thread_resume
185: * will not try to put it on the run queues.
186: *
187: * We can do all of this without locking, because nothing
188: * else is running yet.
189: */
190: startup_thread->state |= TH_RUN;
191: (void) thread_resume(startup_thread);
192:
193: /*
194: * Start the thread.
195: */
196: cpu_launch_first_thread(startup_thread);
197: /*NOTREACHED*/
198: }
199:
200: /*
201: * Now running in a thread. Create the rest of the kernel threads
202: * and the bootstrap task.
203: */
1.1.1.5 root 204: void start_kernel_threads(void)
1.1 root 205: {
1.1.1.5 root 206: int i;
1.1 root 207:
208: /*
209: * Create the idle threads and the other
210: * service threads.
211: */
212: for (i = 0; i < NCPUS; i++) {
213: if (machine_slot[i].is_cpu) {
214: thread_t th;
215:
216: (void) thread_create(kernel_task, &th);
217: thread_bind(th, cpu_to_processor(i));
218: thread_start(th, idle_thread);
219: thread_doswapin(th);
220: (void) thread_resume(th);
221: }
222: }
223:
224: (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
225: (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
226: (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
227:
228: #if NCPUS > 1
229: /*
230: * Create the shutdown thread.
231: */
232: (void) kernel_thread(kernel_task, action_thread, (char *) 0);
233:
234: /*
235: * Allow other CPUs to run.
236: */
237: start_other_cpus();
1.1.1.3 root 238: #endif /* NCPUS > 1 */
1.1 root 239:
240: /*
241: * Create the device service.
242: */
243: device_service_create();
244:
245: /*
1.1.1.2 root 246: * Initialize kernel task's creation time.
247: * When we created the kernel task in task_init, the mapped
248: * time was not yet available. Now, last thing before starting
249: * the user bootstrap, record the current time as the kernel
250: * task's creation time.
251: */
252: record_time_stamp (&kernel_task->creation_time);
253:
1.1 root 254: /*
255: * Start the user bootstrap.
256: */
257: bootstrap_create();
258:
259: #if XPR_DEBUG
260: xprinit(); /* XXX */
1.1.1.3 root 261: #endif /* XPR_DEBUG */
1.1 root 262:
263: /*
264: * Become the pageout daemon.
265: */
266: (void) spl0();
267: vm_pageout();
268: /*NOTREACHED*/
269: }
270:
271: #if NCPUS > 1
1.1.1.5 root 272: void slave_main(void)
1.1 root 273: {
274: cpu_launch_first_thread(THREAD_NULL);
275: }
1.1.1.3 root 276: #endif /* NCPUS > 1 */
1.1 root 277:
278: /*
279: * Start up the first thread on a CPU.
280: * First thread is specified for the master CPU.
281: */
1.1.1.5 root 282: void cpu_launch_first_thread(thread_t th)
1.1 root 283: {
1.1.1.5 root 284: int mycpu;
1.1 root 285:
286: mycpu = cpu_number();
287:
288: cpu_up(mycpu);
289:
290: start_timer(&kernel_timer[mycpu]);
291:
292: /*
293: * Block all interrupts for choose_thread.
294: */
295: (void) splhigh();
296:
297: if (th == THREAD_NULL)
298: th = choose_thread(cpu_to_processor(mycpu));
299: if (th == THREAD_NULL)
300: panic("cpu_launch_first_thread");
301:
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:
1.1.1.4 root 313: startrtclock(); /* needs an active thread */
314:
1.1 root 315: load_context(th);
316: /*NOTREACHED*/
317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.