|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
4: * All Rights Reserved.
5: *
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.
11: *
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.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
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 <cpus.h>
32: #include <mach_host.h>
33: #include <norma_ipc.h>
34: #include <norma_vm.h>
35:
36: #include <mach/boolean.h>
37: #include <mach/machine.h>
38: #include <mach/task_special_ports.h>
39: #include <mach/vm_param.h>
40: #include <ipc/ipc_init.h>
41: #include <kern/cpu_number.h>
42: #include <kern/processor.h>
43: #include <kern/sched_prim.h>
44: #include <kern/task.h>
45: #include <kern/thread.h>
46: #include <kern/thread_swap.h>
47: #include <kern/time_out.h>
48: #include <kern/timer.h>
49: #include <kern/zalloc.h>
50: #include <vm/vm_kern.h>
51: #include <vm/vm_map.h>
52: #include <vm/vm_object.h>
53: #include <vm/vm_page.h>
54: #include <machine/machspl.h>
55: #include <machine/pmap.h>
56: #include <mach/version.h>
57:
58:
59:
60: extern void vm_mem_init();
61: extern void vm_mem_bootstrap();
62: extern void init_timeout();
63: extern void machine_init();
64:
65: extern void idle_thread();
66: extern void vm_pageout();
67: extern void reaper_thread();
68: extern void swapin_thread();
69: extern void sched_thread();
70:
71: extern void bootstrap_create();
72: extern void device_service_create();
73:
74: void cpu_launch_first_thread(); /* forward */
75: void start_kernel_threads(); /* forward */
76:
77: #if NCPUS > 1
78: extern void start_other_cpus();
79: extern void action_thread();
80: #endif /* NCPUS > 1 */
81:
82: #include <oskit/machine/physmem.h>
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: */
90: void setup_main()
91: {
92: thread_t startup_thread;
93:
94: sched_init();
95: vm_mem_bootstrap();
96: ipc_bootstrap();
97: vm_mem_init();
98: ipc_init();
99:
100: /*
101: * As soon as the virtual memory system is up, we record
102: * that this CPU is using the kernel pmap.
103: */
104: PMAP_ACTIVATE_KERNEL(master_cpu);
105:
106: init_timers();
107: init_timeout();
108:
109: timestamp_init();
110:
111: mapable_time_init();
112:
113: machine_init();
114:
115: machine_info.max_cpus = NCPUS;
116: machine_info.memory_size = phys_mem_max - phys_mem_min; /* XXX mem_size */
117: machine_info.avail_cpus = 0;
118: machine_info.major_version = KERNEL_MAJOR_VERSION;
119: machine_info.minor_version = KERNEL_MINOR_VERSION;
120:
121: /*
122: * Initialize the IPC, task, and thread subsystems.
123: */
124: task_init();
125: thread_init();
126: swapper_init();
127: #if MACH_HOST
128: pset_sys_init();
129: #endif /* MACH_HOST */
130:
131: /*
132: * Kick off the time-out driven routines by calling
133: * them the first time.
134: */
135: recompute_priorities();
136: compute_mach_factor();
137:
138: /*
139: * Create a kernel thread to start the other kernel
140: * threads. Thread_resume (from kernel_thread) calls
141: * thread_setrun, which may look at current thread;
142: * we must avoid this, since there is no current thread.
143: */
144:
145: /*
146: * Create the thread, and point it at the routine.
147: */
148: (void) thread_create(kernel_task, &startup_thread);
149: thread_start(startup_thread, start_kernel_threads);
150:
151: /*
152: * Give it a kernel stack.
153: */
154: thread_doswapin(startup_thread);
155:
156: /*
157: * Pretend it is already running, and resume it.
158: * Since it looks as if it is running, thread_resume
159: * will not try to put it on the run queues.
160: *
161: * We can do all of this without locking, because nothing
162: * else is running yet.
163: */
164: startup_thread->state |= TH_RUN;
165: (void) thread_resume(startup_thread);
166:
167: /*
168: * Start the thread.
169: */
170: cpu_launch_first_thread(startup_thread);
171: /*NOTREACHED*/
172: }
173:
174: /*
175: * Now running in a thread. Create the rest of the kernel threads
176: * and the bootstrap task.
177: */
178: void start_kernel_threads()
179: {
180: register int i;
181:
182: /*
183: * Create the idle threads and the other
184: * service threads.
185: */
186: for (i = 0; i < NCPUS; i++) {
187: if (machine_slot[i].is_cpu) {
188: thread_t th;
189:
190: (void) thread_create(kernel_task, &th);
191: thread_bind(th, cpu_to_processor(i));
192: thread_start(th, idle_thread);
193: thread_doswapin(th);
194: (void) thread_resume(th);
195: }
196: }
197:
198: (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
199: (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
200: (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
201:
202: #if NCPUS > 1
203: /*
204: * Create the shutdown thread.
205: */
206: (void) kernel_thread(kernel_task, action_thread, (char *) 0);
207:
208: /*
209: * Allow other CPUs to run.
210: */
211: start_other_cpus();
212: #endif /* NCPUS > 1 */
213:
214: /*
215: * Create the device service.
216: */
217: device_service_create();
218:
219: /*
220: * Initialize NORMA ipc system.
221: */
222: #if NORMA_IPC
223: norma_ipc_init();
224: #endif /* NORMA_IPC */
225:
226: /*
227: * Initialize NORMA vm system.
228: */
229: #if NORMA_VM
230: norma_vm_init();
231: #endif /* NORMA_VM */
232:
233:
234: /*
235: * Initialize kernel task's creation time.
236: * When we created the kernel task in task_init, the mapped
237: * time was not yet available. Now, last thing before starting
238: * the user bootstrap, record the current time as the kernel
239: * task's creation time.
240: */
241: record_time_stamp (&kernel_task->creation_time);
242:
243: /*
244: * Start the user bootstrap.
245: */
246: bootstrap_create();
247:
248: /*
249: * Become the pageout daemon.
250: */
251: (void) spl0();
252: vm_pageout();
253: /*NOTREACHED*/
254: }
255:
256: #if NCPUS > 1
257: void slave_main()
258: {
259: cpu_launch_first_thread(THREAD_NULL);
260: }
261: #endif /* NCPUS > 1 */
262:
263: /*
264: * Start up the first thread on a CPU.
265: * First thread is specified for the master CPU.
266: */
267: void cpu_launch_first_thread(th)
268: register thread_t th;
269: {
270: register int mycpu;
271:
272: mycpu = cpu_number();
273:
274: cpu_up(mycpu);
275:
276: start_timer(&kernel_timer[mycpu]);
277:
278: /*
279: * Block all interrupts for choose_thread.
280: */
281: (void) splhigh();
282:
283: if (th == THREAD_NULL)
284: th = choose_thread(cpu_to_processor(mycpu));
285: if (th == THREAD_NULL)
286: panic("cpu_launch_first_thread");
287:
288: startrtclock(); /* needs an active thread */
289: PMAP_ACTIVATE_KERNEL(mycpu);
290:
291: active_threads[mycpu] = th;
292: active_stacks[mycpu] = th->kernel_stack;
293: thread_lock(th);
294: th->state &= ~TH_UNINT;
295: thread_unlock(th);
296: timer_switch(&th->system_timer);
297:
298: PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
299:
300: load_context(th);
301: /*NOTREACHED*/
302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.