|
|
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:
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();
1.1.1.3 ! root 81: #endif /* NCPUS > 1 */
1.1 root 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();
1.1.1.3 ! root 116: #endif /* XPR_DEBUG */
1.1 root 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();
1.1.1.3 ! root 138: #endif /* MACH_HOST */
1.1 root 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();
1.1.1.2 root 146:
1.1 root 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();
1.1.1.3 ! root 221: #endif /* NCPUS > 1 */
1.1 root 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();
1.1.1.3 ! root 233: #endif /* NORMA_IPC */
1.1 root 234:
235: /*
236: * Initialize NORMA vm system.
237: */
238: #if NORMA_VM
239: norma_vm_init();
1.1.1.3 ! root 240: #endif /* NORMA_VM */
1.1 root 241:
1.1.1.2 root 242:
243: /*
244: * Initialize kernel task's creation time.
245: * When we created the kernel task in task_init, the mapped
246: * time was not yet available. Now, last thing before starting
247: * the user bootstrap, record the current time as the kernel
248: * task's creation time.
249: */
250: record_time_stamp (&kernel_task->creation_time);
251:
1.1 root 252: /*
253: * Start the user bootstrap.
254: */
255: bootstrap_create();
256:
257: #if XPR_DEBUG
258: xprinit(); /* XXX */
1.1.1.3 ! root 259: #endif /* XPR_DEBUG */
1.1 root 260:
261: /*
262: * Become the pageout daemon.
263: */
264: (void) spl0();
265: vm_pageout();
266: /*NOTREACHED*/
267: }
268:
269: #if NCPUS > 1
270: void slave_main()
271: {
272: cpu_launch_first_thread(THREAD_NULL);
273: }
1.1.1.3 ! root 274: #endif /* NCPUS > 1 */
1.1 root 275:
276: /*
277: * Start up the first thread on a CPU.
278: * First thread is specified for the master CPU.
279: */
280: void cpu_launch_first_thread(th)
281: register thread_t th;
282: {
283: register int mycpu;
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: startrtclock(); /* needs an active thread */
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:
313: load_context(th);
314: /*NOTREACHED*/
315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.