|
|
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>
39: #include <kern/machine.h>
40: #include <kern/mach_factor.h>
41: #include <kern/mach_clock.h>
42: #include <kern/printf.h>
1.1 root 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/timer.h>
1.1.1.4 root 49: #include <kern/xpr.h>
1.1.1.5 ! root 50: #include <kern/bootstrap.h>
1.1.1.4 root 51: #include <kern/time_stamp.h>
1.1.1.5 ! root 52: #include <kern/startup.h>
1.1 root 53: #include <vm/vm_kern.h>
54: #include <vm/vm_map.h>
55: #include <vm/vm_object.h>
56: #include <vm/vm_page.h>
1.1.1.5 ! root 57: #include <vm/vm_init.h>
! 58: #include <vm/vm_pageout.h>
1.1 root 59: #include <machine/machspl.h>
1.1.1.4 root 60: #include <machine/pcb.h>
1.1 root 61: #include <machine/pmap.h>
1.1.1.4 root 62: #include <machine/model_dep.h>
1.1 root 63: #include <mach/version.h>
1.1.1.5 ! root 64: #include <device/device_init.h>
1.1 root 65:
1.1.1.5 ! root 66: #if MACH_KDB
! 67: #include <device/cons.h>
! 68: #endif /* MACH_KDB */
1.1 root 69:
1.1.1.4 root 70: #if ! MACH_KBD
1.1.1.5 ! root 71: boolean_t reboot_on_panic = TRUE;
1.1.1.4 root 72: #endif
73:
1.1 root 74: #if NCPUS > 1
1.1.1.5 ! root 75: #include <machine/mp_desc.h>
! 76: #include <kern/machine.h>
1.1.1.3 root 77: #endif /* NCPUS > 1 */
1.1 root 78:
79: /* XX */
80: extern vm_offset_t phys_first_addr, phys_last_addr;
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: printf_init();
112:
113: sched_init();
114: vm_mem_bootstrap();
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;
139: machine_info.memory_size = phys_last_addr - phys_first_addr; /* XXX mem_size */
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 root 161: /*
162: * Create a kernel thread to start the other kernel
163: * threads. Thread_resume (from kernel_thread) calls
164: * thread_setrun, which may look at current thread;
165: * we must avoid this, since there is no current thread.
166: */
167:
168: /*
169: * Create the thread, and point it at the routine.
170: */
171: (void) thread_create(kernel_task, &startup_thread);
172: thread_start(startup_thread, start_kernel_threads);
173:
174: /*
175: * Give it a kernel stack.
176: */
177: thread_doswapin(startup_thread);
178:
179: /*
180: * Pretend it is already running, and resume it.
181: * Since it looks as if it is running, thread_resume
182: * will not try to put it on the run queues.
183: *
184: * We can do all of this without locking, because nothing
185: * else is running yet.
186: */
187: startup_thread->state |= TH_RUN;
188: (void) thread_resume(startup_thread);
189:
190: /*
191: * Start the thread.
192: */
193: cpu_launch_first_thread(startup_thread);
194: /*NOTREACHED*/
195: }
196:
197: /*
198: * Now running in a thread. Create the rest of the kernel threads
199: * and the bootstrap task.
200: */
1.1.1.5 ! root 201: void start_kernel_threads(void)
1.1 root 202: {
1.1.1.5 ! root 203: int i;
1.1 root 204:
205: /*
206: * Create the idle threads and the other
207: * service threads.
208: */
209: for (i = 0; i < NCPUS; i++) {
210: if (machine_slot[i].is_cpu) {
211: thread_t th;
212:
213: (void) thread_create(kernel_task, &th);
214: thread_bind(th, cpu_to_processor(i));
215: thread_start(th, idle_thread);
216: thread_doswapin(th);
217: (void) thread_resume(th);
218: }
219: }
220:
221: (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
222: (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
223: (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
224:
225: #if NCPUS > 1
226: /*
227: * Create the shutdown thread.
228: */
229: (void) kernel_thread(kernel_task, action_thread, (char *) 0);
230:
231: /*
232: * Allow other CPUs to run.
233: */
234: start_other_cpus();
1.1.1.3 root 235: #endif /* NCPUS > 1 */
1.1 root 236:
237: /*
238: * Create the device service.
239: */
240: device_service_create();
241:
242: /*
1.1.1.2 root 243: * Initialize kernel task's creation time.
244: * When we created the kernel task in task_init, the mapped
245: * time was not yet available. Now, last thing before starting
246: * the user bootstrap, record the current time as the kernel
247: * task's creation time.
248: */
249: record_time_stamp (&kernel_task->creation_time);
250:
1.1 root 251: /*
252: * Start the user bootstrap.
253: */
254: bootstrap_create();
255:
256: #if XPR_DEBUG
257: xprinit(); /* XXX */
1.1.1.3 root 258: #endif /* XPR_DEBUG */
1.1 root 259:
260: /*
261: * Become the pageout daemon.
262: */
263: (void) spl0();
264: vm_pageout();
265: /*NOTREACHED*/
266: }
267:
268: #if NCPUS > 1
1.1.1.5 ! root 269: void slave_main(void)
1.1 root 270: {
271: cpu_launch_first_thread(THREAD_NULL);
272: }
1.1.1.3 root 273: #endif /* NCPUS > 1 */
1.1 root 274:
275: /*
276: * Start up the first thread on a CPU.
277: * First thread is specified for the master CPU.
278: */
1.1.1.5 ! root 279: void cpu_launch_first_thread(thread_t th)
1.1 root 280: {
1.1.1.5 ! root 281: int mycpu;
1.1 root 282:
283: mycpu = cpu_number();
284:
285: cpu_up(mycpu);
286:
287: start_timer(&kernel_timer[mycpu]);
288:
289: /*
290: * Block all interrupts for choose_thread.
291: */
292: (void) splhigh();
293:
294: if (th == THREAD_NULL)
295: th = choose_thread(cpu_to_processor(mycpu));
296: if (th == THREAD_NULL)
297: panic("cpu_launch_first_thread");
298:
299: PMAP_ACTIVATE_KERNEL(mycpu);
300:
301: active_threads[mycpu] = th;
302: active_stacks[mycpu] = th->kernel_stack;
303: thread_lock(th);
304: th->state &= ~TH_UNINT;
305: thread_unlock(th);
306: timer_switch(&th->system_timer);
307:
308: PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
309:
1.1.1.4 root 310: startrtclock(); /* needs an active thread */
311:
1.1 root 312: load_context(th);
313: /*NOTREACHED*/
314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.