startup.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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 Software.Distribution@CS.CMU.EDU
  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. #include <string.h>
  30. #include <mach/boolean.h>
  31. #include <mach/machine.h>
  32. #include <mach/task_special_ports.h>
  33. #include <mach/vm_param.h>
  34. #include <ipc/ipc_init.h>
  35. #include <kern/cpu_number.h>
  36. #include <kern/debug.h>
  37. #include <kern/gsync.h>
  38. #include <kern/machine.h>
  39. #include <kern/mach_factor.h>
  40. #include <kern/mach_clock.h>
  41. #include <kern/processor.h>
  42. #include <kern/rdxtree.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/timer.h>
  48. #include <kern/xpr.h>
  49. #include <kern/bootstrap.h>
  50. #include <kern/time_stamp.h>
  51. #include <kern/startup.h>
  52. #include <vm/vm_kern.h>
  53. #include <vm/vm_map.h>
  54. #include <vm/vm_object.h>
  55. #include <vm/vm_page.h>
  56. #include <vm/vm_init.h>
  57. #include <vm/vm_pageout.h>
  58. #include <machine/machspl.h>
  59. #include <machine/pcb.h>
  60. #include <machine/pmap.h>
  61. #include <machine/model_dep.h>
  62. #include <mach/version.h>
  63. #include <device/device_init.h>
  64. #if MACH_KDB
  65. #include <device/cons.h>
  66. #endif /* MACH_KDB */
  67. #if ! MACH_KBD
  68. boolean_t reboot_on_panic = TRUE;
  69. #endif
  70. #if NCPUS > 1
  71. #include <machine/mp_desc.h>
  72. #include <kern/machine.h>
  73. #endif /* NCPUS > 1 */
  74. /* XX */
  75. extern char *kernel_cmdline;
  76. /*
  77. * Running in virtual memory, on the interrupt stack.
  78. * Does not return. Dispatches initial thread.
  79. *
  80. * Assumes that master_cpu is set.
  81. */
  82. void setup_main(void)
  83. {
  84. thread_t startup_thread;
  85. #if MACH_KDB
  86. /*
  87. * Cause a breakpoint trap to the debugger before proceeding
  88. * any further if the proper option flag was specified
  89. * on the kernel's command line.
  90. * XXX check for surrounding spaces.
  91. */
  92. if (strstr(kernel_cmdline, "-d ")) {
  93. cninit(); /* need console for debugger */
  94. SoftDebugger("init");
  95. }
  96. #else /* MACH_KDB */
  97. if (strstr (kernel_cmdline, "-H ")) {
  98. reboot_on_panic = FALSE;
  99. }
  100. #endif /* MACH_KDB */
  101. panic_init();
  102. sched_init();
  103. vm_mem_bootstrap();
  104. rdxtree_cache_init();
  105. ipc_bootstrap();
  106. vm_mem_init();
  107. ipc_init();
  108. /*
  109. * As soon as the virtual memory system is up, we record
  110. * that this CPU is using the kernel pmap.
  111. */
  112. PMAP_ACTIVATE_KERNEL(master_cpu);
  113. init_timers();
  114. init_timeout();
  115. #if XPR_DEBUG
  116. xprbootstrap();
  117. #endif /* XPR_DEBUG */
  118. timestamp_init();
  119. machine_init();
  120. mapable_time_init();
  121. machine_info.max_cpus = NCPUS;
  122. machine_info.memory_size = vm_page_mem_size(); /* XXX phys_addr_t -> vm_size_t */
  123. machine_info.avail_cpus = 0;
  124. machine_info.major_version = KERNEL_MAJOR_VERSION;
  125. machine_info.minor_version = KERNEL_MINOR_VERSION;
  126. /*
  127. * Initialize the IPC, task, and thread subsystems.
  128. */
  129. task_init();
  130. thread_init();
  131. swapper_init();
  132. #if MACH_HOST
  133. pset_sys_init();
  134. #endif /* MACH_HOST */
  135. /*
  136. * Kick off the time-out driven routines by calling
  137. * them the first time.
  138. */
  139. recompute_priorities(NULL);
  140. compute_mach_factor();
  141. gsync_setup ();
  142. /*
  143. * Create a kernel thread to start the other kernel
  144. * threads. Thread_resume (from kernel_thread) calls
  145. * thread_setrun, which may look at current thread;
  146. * we must avoid this, since there is no current thread.
  147. */
  148. /*
  149. * Create the thread, and point it at the routine.
  150. */
  151. (void) thread_create(kernel_task, &startup_thread);
  152. thread_start(startup_thread, start_kernel_threads);
  153. /*
  154. * Give it a kernel stack.
  155. */
  156. thread_doswapin(startup_thread);
  157. /*
  158. * Pretend it is already running, and resume it.
  159. * Since it looks as if it is running, thread_resume
  160. * will not try to put it on the run queues.
  161. *
  162. * We can do all of this without locking, because nothing
  163. * else is running yet.
  164. */
  165. startup_thread->state |= TH_RUN;
  166. (void) thread_resume(startup_thread);
  167. /*
  168. * Start the thread.
  169. */
  170. cpu_launch_first_thread(startup_thread);
  171. /*NOTREACHED*/
  172. }
  173. /*
  174. * Now running in a thread. Create the rest of the kernel threads
  175. * and the bootstrap task.
  176. */
  177. void start_kernel_threads(void)
  178. {
  179. int i;
  180. /*
  181. * Create the idle threads and the other
  182. * service threads.
  183. */
  184. for (i = 0; i < NCPUS; i++) {
  185. if (machine_slot[i].is_cpu) {
  186. thread_t th;
  187. (void) thread_create(kernel_task, &th);
  188. thread_bind(th, cpu_to_processor(i));
  189. thread_start(th, idle_thread);
  190. thread_doswapin(th);
  191. (void) thread_resume(th);
  192. }
  193. }
  194. (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
  195. (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
  196. (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
  197. #if NCPUS > 1
  198. /*
  199. * Create the shutdown thread.
  200. */
  201. (void) kernel_thread(kernel_task, action_thread, (char *) 0);
  202. /*
  203. * Allow other CPUs to run.
  204. */
  205. start_other_cpus();
  206. #endif /* NCPUS > 1 */
  207. /*
  208. * Create the device service.
  209. */
  210. device_service_create();
  211. //APPLE starts IOKit here
  212. /*
  213. * Initialize kernel task's creation time.
  214. * When we created the kernel task in task_init, the mapped
  215. * time was not yet available. Now, last thing before starting
  216. * the user bootstrap, record the current time as the kernel
  217. * task's creation time.
  218. */
  219. record_time_stamp (&kernel_task->creation_time);
  220. /*
  221. * Start the user bootstrap.
  222. */
  223. bootstrap_create();
  224. #if XPR_DEBUG
  225. xprinit(); /* XXX */
  226. #endif /* XPR_DEBUG */
  227. /*
  228. * Become the pageout daemon.
  229. */
  230. (void) spl0();
  231. vm_pageout();
  232. /*NOTREACHED*/
  233. }
  234. #if NCPUS > 1
  235. void slave_main(void)
  236. {
  237. cpu_launch_first_thread(THREAD_NULL);
  238. }
  239. #endif /* NCPUS > 1 */
  240. /*
  241. * Start up the first thread on a CPU.
  242. * First thread is specified for the master CPU.
  243. */
  244. void cpu_launch_first_thread(thread_t th)
  245. {
  246. int mycpu;
  247. mycpu = cpu_number();
  248. cpu_up(mycpu);
  249. start_timer(&kernel_timer[mycpu]);
  250. /*
  251. * Block all interrupts for choose_thread.
  252. */
  253. (void) splhigh();
  254. if (th == THREAD_NULL)
  255. th = choose_thread(cpu_to_processor(mycpu));
  256. if (th == THREAD_NULL)
  257. panic("cpu_launch_first_thread");
  258. PMAP_ACTIVATE_KERNEL(mycpu);
  259. active_threads[mycpu] = th;
  260. active_stacks[mycpu] = th->kernel_stack;
  261. thread_lock(th);
  262. th->state &= ~TH_UNINT;
  263. thread_unlock(th);
  264. timer_switch(&th->system_timer);
  265. PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
  266. startrtclock(); /* needs an active thread */
  267. load_context(th);
  268. /*NOTREACHED*/
  269. }