|
|
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 */
1.1.1.4 root 81: extern char *kernel_cmdline;
1.1 root 82:
83: /*
84: * Running in virtual memory, on the interrupt stack.
85: * Does not return. Dispatches initial thread.
86: *
87: * Assumes that master_cpu is set.
88: */
1.1.1.5 root 89: void setup_main(void)
1.1 root 90: {
91: thread_t startup_thread;
92:
1.1.1.4 root 93: #if MACH_KDB
94: /*
95: * Cause a breakpoint trap to the debugger before proceeding
96: * any further if the proper option flag was specified
97: * on the kernel's command line.
98: * XXX check for surrounding spaces.
99: */
100: if (strstr(kernel_cmdline, "-d ")) {
101: cninit(); /* need console for debugger */
102: SoftDebugger("init");
103: }
104: #else /* MACH_KDB */
105: if (strstr (kernel_cmdline, "-H ")) {
1.1.1.5 root 106: reboot_on_panic = FALSE;
1.1.1.4 root 107: }
108: #endif /* MACH_KDB */
109:
1.1 root 110: panic_init();
111:
112: sched_init();
113: vm_mem_bootstrap();
1.1.1.6 root 114: rdxtree_cache_init();
1.1 root 115: ipc_bootstrap();
116: vm_mem_init();
117: ipc_init();
118:
119: /*
120: * As soon as the virtual memory system is up, we record
121: * that this CPU is using the kernel pmap.
122: */
123: PMAP_ACTIVATE_KERNEL(master_cpu);
124:
125: init_timers();
126: init_timeout();
127:
128: #if XPR_DEBUG
129: xprbootstrap();
1.1.1.3 root 130: #endif /* XPR_DEBUG */
1.1 root 131:
132: timestamp_init();
133:
134: machine_init();
135:
1.1.1.4 root 136: mapable_time_init();
137:
1.1 root 138: machine_info.max_cpus = NCPUS;
1.1.1.7 root 139: machine_info.memory_size = vm_page_mem_size(); /* XXX phys_addr_t -> vm_size_t */
1.1 root 140: machine_info.avail_cpus = 0;
141: machine_info.major_version = KERNEL_MAJOR_VERSION;
142: machine_info.minor_version = KERNEL_MINOR_VERSION;
143:
144: /*
145: * Initialize the IPC, task, and thread subsystems.
146: */
147: task_init();
148: thread_init();
149: swapper_init();
150: #if MACH_HOST
151: pset_sys_init();
1.1.1.3 root 152: #endif /* MACH_HOST */
1.1 root 153:
154: /*
155: * Kick off the time-out driven routines by calling
156: * them the first time.
157: */
1.1.1.5 root 158: recompute_priorities(NULL);
1.1 root 159: compute_mach_factor();
1.1.1.2 root 160:
1.1.1.7 root 161: gsync_setup ();
162:
1.1 root 163: /*
164: * Create a kernel thread to start the other kernel
165: * threads. Thread_resume (from kernel_thread) calls
166: * thread_setrun, which may look at current thread;
167: * we must avoid this, since there is no current thread.
168: */
169:
170: /*
171: * Create the thread, and point it at the routine.
172: */
173: (void) thread_create(kernel_task, &startup_thread);
174: thread_start(startup_thread, start_kernel_threads);
175:
176: /*
177: * Give it a kernel stack.
178: */
179: thread_doswapin(startup_thread);
180:
181: /*
182: * Pretend it is already running, and resume it.
183: * Since it looks as if it is running, thread_resume
184: * will not try to put it on the run queues.
185: *
186: * We can do all of this without locking, because nothing
187: * else is running yet.
188: */
189: startup_thread->state |= TH_RUN;
190: (void) thread_resume(startup_thread);
191:
192: /*
193: * Start the thread.
194: */
195: cpu_launch_first_thread(startup_thread);
196: /*NOTREACHED*/
197: }
198:
199: /*
200: * Now running in a thread. Create the rest of the kernel threads
201: * and the bootstrap task.
202: */
1.1.1.5 root 203: void start_kernel_threads(void)
1.1 root 204: {
1.1.1.5 root 205: int i;
1.1 root 206:
207: /*
208: * Create the idle threads and the other
209: * service threads.
210: */
211: for (i = 0; i < NCPUS; i++) {
212: if (machine_slot[i].is_cpu) {
213: thread_t th;
214:
215: (void) thread_create(kernel_task, &th);
216: thread_bind(th, cpu_to_processor(i));
217: thread_start(th, idle_thread);
218: thread_doswapin(th);
219: (void) thread_resume(th);
220: }
221: }
222:
223: (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
224: (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
225: (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
226:
227: #if NCPUS > 1
228: /*
229: * Create the shutdown thread.
230: */
231: (void) kernel_thread(kernel_task, action_thread, (char *) 0);
232:
233: /*
234: * Allow other CPUs to run.
235: */
236: start_other_cpus();
1.1.1.3 root 237: #endif /* NCPUS > 1 */
1.1 root 238:
239: /*
240: * Create the device service.
241: */
242: device_service_create();
243:
244: /*
1.1.1.2 root 245: * Initialize kernel task's creation time.
246: * When we created the kernel task in task_init, the mapped
247: * time was not yet available. Now, last thing before starting
248: * the user bootstrap, record the current time as the kernel
249: * task's creation time.
250: */
251: record_time_stamp (&kernel_task->creation_time);
252:
1.1 root 253: /*
254: * Start the user bootstrap.
255: */
256: bootstrap_create();
257:
258: #if XPR_DEBUG
259: xprinit(); /* XXX */
1.1.1.3 root 260: #endif /* XPR_DEBUG */
1.1 root 261:
262: /*
263: * Become the pageout daemon.
264: */
265: (void) spl0();
266: vm_pageout();
267: /*NOTREACHED*/
268: }
269:
270: #if NCPUS > 1
1.1.1.5 root 271: void slave_main(void)
1.1 root 272: {
273: cpu_launch_first_thread(THREAD_NULL);
274: }
1.1.1.3 root 275: #endif /* NCPUS > 1 */
1.1 root 276:
277: /*
278: * Start up the first thread on a CPU.
279: * First thread is specified for the master CPU.
280: */
1.1.1.5 root 281: void cpu_launch_first_thread(thread_t th)
1.1 root 282: {
1.1.1.5 root 283: int mycpu;
1.1 root 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: PMAP_ACTIVATE_KERNEL(mycpu);
302:
303: active_threads[mycpu] = th;
304: active_stacks[mycpu] = th->kernel_stack;
305: thread_lock(th);
306: th->state &= ~TH_UNINT;
307: thread_unlock(th);
308: timer_switch(&th->system_timer);
309:
310: PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
311:
1.1.1.4 root 312: startrtclock(); /* needs an active thread */
313:
1.1 root 314: load_context(th);
315: /*NOTREACHED*/
316: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.