]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/startup.c
xnu-792.6.61.tar.gz
[apple/xnu.git] / osfmk / kern / startup.c
CommitLineData
1c79356b 1/*
91447636 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
37839358
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
37839358
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
37839358
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * @OSF_COPYRIGHT@
24 */
25/*
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
28 * All Rights Reserved.
29 *
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
35 *
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39 *
40 * Carnegie Mellon requests users of this software to return to
41 *
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
46 *
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
49 */
50/*
51 */
52
53/*
54 * Mach kernel startup.
55 */
56
57#include <debug.h>
58#include <xpr_debug.h>
59#include <mach_kdp.h>
1c79356b
A
60#include <mach_host.h>
61#include <norma_vm.h>
1c79356b
A
62
63#include <mach/boolean.h>
64#include <mach/machine.h>
91447636 65#include <mach/thread_act.h>
1c79356b
A
66#include <mach/task_special_ports.h>
67#include <mach/vm_param.h>
68#include <ipc/ipc_init.h>
69#include <kern/assert.h>
70#include <kern/misc_protos.h>
71#include <kern/clock.h>
72#include <kern/cpu_number.h>
91447636 73#include <kern/ledger.h>
1c79356b
A
74#include <kern/machine.h>
75#include <kern/processor.h>
76#include <kern/sched_prim.h>
1c79356b
A
77#include <kern/startup.h>
78#include <kern/task.h>
79#include <kern/thread.h>
80#include <kern/timer.h>
1c79356b
A
81#include <kern/xpr.h>
82#include <kern/zalloc.h>
91447636 83#include <kern/locks.h>
55e303ae 84#include <vm/vm_shared_memory_server.h>
1c79356b
A
85#include <vm/vm_kern.h>
86#include <vm/vm_init.h>
87#include <vm/vm_map.h>
88#include <vm/vm_object.h>
89#include <vm/vm_page.h>
90#include <vm/vm_pageout.h>
91#include <machine/pmap.h>
43866e37 92#include <machine/commpage.h>
91447636 93#include <libkern/version.h>
1c79356b
A
94
95#ifdef __ppc__
96#include <ppc/Firmware.h>
97#include <ppc/mappings.h>
91447636 98#include <ppc/serial_io.h>
1c79356b
A
99#endif
100
91447636 101static void kernel_bootstrap_thread(void);
1c79356b 102
91447636
A
103static void load_context(
104 thread_t thread);
1c79356b
A
105
106/*
107 * Running in virtual memory, on the interrupt stack.
1c79356b
A
108 */
109void
91447636 110kernel_bootstrap(void)
1c79356b 111{
91447636
A
112 kern_return_t result;
113 thread_t thread;
1c79356b 114
91447636 115 lck_mod_init();
1c79356b
A
116 sched_init();
117 vm_mem_bootstrap();
118 ipc_bootstrap();
119 vm_mem_init();
120 ipc_init();
1c79356b
A
121
122 /*
123 * As soon as the virtual memory system is up, we record
124 * that this CPU is using the kernel pmap.
125 */
126 PMAP_ACTIVATE_KERNEL(master_cpu);
127
1c79356b 128 mapping_free_prime(); /* Load up with temporary mapping blocks */
1c79356b
A
129
130 machine_init();
131 kmod_init();
132 clock_init();
133
1c79356b 134 machine_info.memory_size = mem_size;
91447636
A
135 machine_info.max_mem = max_mem;
136 machine_info.major_version = version_major;
137 machine_info.minor_version = version_minor;
1c79356b
A
138
139 /*
140 * Initialize the IPC, task, and thread subsystems.
141 */
142 ledger_init();
1c79356b 143 task_init();
1c79356b 144 thread_init();
1c79356b
A
145
146 /*
91447636 147 * Create a kernel thread to execute the kernel bootstrap.
1c79356b 148 */
91447636
A
149 result = kernel_thread_create((thread_continue_t)kernel_bootstrap_thread, NULL, MAXPRI_KERNEL, &thread);
150 if (result != KERN_SUCCESS)
151 panic("kernel_bootstrap");
9bccf70c 152
91447636
A
153 thread->state = TH_RUN;
154 thread_deallocate(thread);
55e303ae 155
91447636 156 load_context(thread);
1c79356b 157 /*NOTREACHED*/
1c79356b
A
158}
159
160/*
91447636
A
161 * Now running in a thread. Kick off other services,
162 * invoke user bootstrap, enter pageout loop.
1c79356b 163 */
91447636
A
164static void
165kernel_bootstrap_thread(void)
1c79356b 166{
91447636
A
167 processor_t processor = current_processor();
168 thread_t self = current_thread();
1c79356b
A
169
170 /*
91447636 171 * Create the idle processor thread.
1c79356b 172 */
91447636 173 idle_thread_create(processor);
0b4e3aa0
A
174
175 /*
91447636
A
176 * N.B. Do not stick anything else
177 * before this point.
178 *
179 * Start up the scheduler services.
0b4e3aa0 180 */
91447636 181 sched_startup();
0b4e3aa0 182
1c79356b 183 /*
91447636
A
184 * Remain on current processor as
185 * additional processors come online.
1c79356b 186 */
91447636 187 thread_bind(self, processor);
1c79356b
A
188
189 /*
91447636 190 * Kick off memory mapping adjustments.
1c79356b 191 */
1c79356b 192 mapping_adjust();
1c79356b 193
1c79356b
A
194 /*
195 * Create the clock service.
196 */
197 clock_service_create();
198
199 /*
200 * Create the device service.
201 */
202 device_service_create();
203
91447636 204 shared_file_boot_time_init(ENV_DEFAULT_ROOT, cpu_type());
1c79356b
A
205
206#ifdef IOKIT
207 {
208 PE_init_iokit();
209 }
210#endif
43866e37
A
211
212 (void) spllo(); /* Allow interruptions */
213
214 /*
215 * Fill in the comm area (mapped into every task address space.)
216 */
217 commpage_populate();
1c79356b
A
218
219 /*
220 * Start the user bootstrap.
221 */
1c79356b
A
222#ifdef MACH_BSD
223 {
1c79356b
A
224 bsd_init();
225 }
226#endif
227
55e303ae
A
228#if __ppc__
229 serial_keyboard_init(); /* Start serial keyboard if wanted */
230#endif
231
91447636 232 thread_bind(self, PROCESSOR_NULL);
1c79356b
A
233
234 /*
235 * Become the pageout daemon.
236 */
1c79356b
A
237 vm_pageout();
238 /*NOTREACHED*/
239}
240
91447636
A
241/*
242 * slave_main:
243 *
244 * Load the first thread to start a processor.
245 */
1c79356b
A
246void
247slave_main(void)
248{
91447636 249 processor_t processor = current_processor();
1c79356b
A
250 thread_t thread;
251
91447636
A
252 /*
253 * Use the idle processor thread if there
254 * is no dedicated start up thread.
255 */
256 if (processor->next_thread == THREAD_NULL) {
257 thread = processor->idle_thread;
258 thread->continuation = (thread_continue_t)processor_start_thread;
259 thread->parameter = NULL;
260 }
261 else {
262 thread = processor->next_thread;
263 processor->next_thread = THREAD_NULL;
1c79356b 264 }
9bccf70c 265
91447636 266 load_context(thread);
1c79356b 267 /*NOTREACHED*/
1c79356b
A
268}
269
270/*
91447636
A
271 * processor_start_thread:
272 *
273 * First thread to execute on a started processor.
274 *
275 * Called at splsched.
1c79356b
A
276 */
277void
91447636 278processor_start_thread(void)
1c79356b 279{
91447636
A
280 processor_t processor = current_processor();
281 thread_t self = current_thread();
282
1c79356b
A
283 slave_machine_init();
284
91447636
A
285 /*
286 * If running the idle processor thread,
287 * reenter the idle loop, else terminate.
288 */
289 if (self == processor->idle_thread)
290 thread_block((thread_continue_t)idle_thread);
291
292 thread_terminate(self);
293 /*NOTREACHED*/
1c79356b
A
294}
295
296/*
91447636
A
297 * load_context:
298 *
299 * Start the first thread on a processor.
1c79356b 300 */
91447636
A
301static void
302load_context(
1c79356b
A
303 thread_t thread)
304{
91447636 305 processor_t processor = current_processor();
1c79356b 306
91447636
A
307 machine_set_current_thread(thread);
308 processor_up(processor);
1c79356b 309
91447636
A
310 PMAP_ACTIVATE_KERNEL(PROCESSOR_DATA(processor, slot_num));
311
312 /*
313 * Acquire a stack if none attached. The panic
314 * should never occur since the thread is expected
315 * to have reserved stack.
316 */
317 if (!thread->kernel_stack) {
318 if (!stack_alloc_try(thread))
319 panic("load_context");
320 }
321
322 /*
323 * The idle processor threads are not counted as
324 * running for load calculations.
325 */
326 if (!(thread->state & TH_IDLE))
327 pset_run_incr(thread->processor_set);
1c79356b 328
55e303ae 329 processor->active_thread = thread;
9bccf70c 330 processor->current_pri = thread->sched_pri;
91447636
A
331 processor->deadline = UINT64_MAX;
332 thread->last_processor = processor;
333
334 processor->last_dispatch = mach_absolute_time();
335 timer_switch((uint32_t)processor->last_dispatch,
336 &PROCESSOR_DATA(processor, offline_timer));
1c79356b 337
91447636 338 PMAP_ACTIVATE_USER(thread, PROCESSOR_DATA(processor, slot_num));
1c79356b 339
55e303ae 340 machine_load_context(thread);
1c79356b
A
341 /*NOTREACHED*/
342}