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