PageRenderTime 66ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/base/Kernel/Singularity/Kernel.cs

https://bitbucket.org/MpDzik/singularity-bus-drivers
C# | 1050 lines | 756 code | 167 blank | 127 comment | 61 complexity | 992edb42e0f5cf6d954831c7f6a544b9 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note:
  8. //
  9. // This file was modified since RDK 2.0 version.
  10. // Modifications:
  11. // 2011-06-11: Marek Dzikiewicz
  12. //
  13. #define MEASURE_INIT_IO_PERFORMANCE
  14. using System;
  15. using System.Collections;
  16. using System.Diagnostics;
  17. using System.Reflection;
  18. using System.Runtime.CompilerServices;
  19. using System.Runtime.InteropServices;
  20. using System.Threading;
  21. using Microsoft.Bartok.Runtime;
  22. using Microsoft.SingSharp;
  23. using Microsoft.Singularity.Channels;
  24. using Microsoft.Singularity.Directory;
  25. using Microsoft.Singularity.Drivers;
  26. using Microsoft.Singularity.Eventing;
  27. using Microsoft.Singularity.Hal;
  28. using Microsoft.Singularity.Io;
  29. using Microsoft.Singularity.Loader;
  30. using Microsoft.Singularity.Memory;
  31. using Microsoft.Singularity.Scheduling;
  32. using Microsoft.Singularity.Security;
  33. using Microsoft.Singularity.V1.Services;
  34. using Microsoft.Singularity.Xml;
  35. [assembly: AssemblyTitle("Microsoft.Singularity")]
  36. [assembly: AssemblyProduct("Microsoft Research Singularity Operating System")]
  37. [assembly: AssemblyCompany("Microsoft Corporation")]
  38. [assembly: AssemblyVersion("1.0.0.0")]
  39. [assembly: AssemblyKeyFile("public.snk")]
  40. [assembly: AssemblyDelaySign(true)]
  41. namespace Microsoft.Singularity
  42. {
  43. [NoCCtor]
  44. [CLSCompliant(false)]
  45. [AccessedByRuntime("referenced from hal.cpp/hal.cpp")]
  46. public class Kernel
  47. {
  48. private static string[] args;
  49. private static ManualResetEvent mpEndEvent;
  50. private static int bootReturnCode;
  51. // sample profiler kernel data
  52. public static uint ProfilerBufferSize;
  53. #region Waypoints
  54. public static long[] Waypoints;
  55. public static int[] WaypointSeq;
  56. public static int[] WaypointThd;
  57. public static int WaypointNumber;// = 0;
  58. public static long WaypointSamples;// = 0;
  59. public static bool WaypointSuspicious;
  60. public static uint WaypointInterrupt;
  61. public const int NWP = 2048; // XXX PBAR if this is readonly then it seems to read as 0!
  62. // This is temporary, until we get a HAL-based plug-and-play system going.
  63. public const byte HalIpiInterrupt = 249;
  64. /// <summary> Flag indicating if kernel has succesfully booted </summary>
  65. private static bool hasBooted;
  66. private static Scheduler scheduler;
  67. ///
  68. /// <summary>
  69. /// Property to find out if kernel finished booting
  70. /// </summary>
  71. ///
  72. public static bool HasBooted
  73. {
  74. [NoHeapAllocation]
  75. get
  76. {
  77. return hasBooted;
  78. }
  79. }
  80. /// <summary>
  81. /// Get a default kernel scheduler
  82. /// </summary>
  83. internal static Scheduler TheScheduler
  84. {
  85. [Inline]
  86. [NoHeapAllocation]
  87. get
  88. {
  89. return scheduler;
  90. }
  91. }
  92. [Conditional("WAYPOINTS")]
  93. [NoHeapAllocation]
  94. public static void Waypoint0()
  95. {
  96. WaypointSamples++;
  97. Waypoints[0] = (long)Processor.CycleCount;
  98. WaypointNumber = 1;
  99. WaypointSuspicious = false;
  100. WaypointInterrupt = Processor.CurrentProcessor.NumInterrupts;
  101. }
  102. [Conditional("WAYPOINTS")]
  103. [NoHeapAllocation]
  104. public static void Waypoint(int num)
  105. {
  106. if (Waypoints == null || Waypoints[0] == 0 || WaypointNumber > NWP - 1) {
  107. return;
  108. }
  109. long delta = (long)Processor.CycleCount - Waypoints[0];
  110. if (delta > 7000000) {
  111. WaypointSuspicious = true;
  112. }
  113. WaypointSeq[WaypointNumber] = num;
  114. WaypointThd[WaypointNumber] = Thread.GetCurrentThreadIndex();
  115. Waypoints[WaypointNumber++] = delta;
  116. }
  117. [Conditional("WAYPOINTS")]
  118. [NoHeapAllocation]
  119. public static void WaypointDone()
  120. {
  121. Waypoints[0] = 0;
  122. }
  123. #if false
  124. [Conditional("WAYPOINTS")]
  125. [NoHeapAllocation]
  126. public static void WaypointDump()
  127. {
  128. WaypointDump(NWP);
  129. }
  130. #endif
  131. [Conditional("WAYPOINTS")]
  132. public static void WaypointDump()
  133. {
  134. bool iflag = Processor.DisableInterrupts();
  135. DebugStub.WriteLine("Interrupts: {0}",
  136. __arglist(Processor.CurrentProcessor.NumInterrupts
  137. - WaypointInterrupt));
  138. DebugStub.WriteLine("WPT Waypoint Sequence THD Diff");
  139. for (int i = 1; i < WaypointNumber; i++) {
  140. DebugStub.WriteLine("{0,3:d} {1,10:d} {2,10:d} {3,3:d} {4,10:d}",
  141. __arglist(
  142. i,
  143. Waypoints[i],
  144. WaypointSeq[i],
  145. WaypointThd[i].GetHashCode(),
  146. Waypoints[i] - Kernel.Waypoints[i-1]));
  147. }
  148. Processor.RestoreInterrupts(iflag);
  149. }
  150. [Conditional("WAYPOINTS")]
  151. [NoHeapAllocation]
  152. public static void WaypointReset()
  153. {
  154. for (int i = 0; i < NWP; i++) {
  155. Waypoints[i] = 0;
  156. }
  157. WaypointSamples = 0;
  158. }
  159. #endregion // Waypoints
  160. internal static DateTime BootTime;
  161. // [System.Diagnostics.Conditional("ISA_ARM")]
  162. private static void ARM_PROGRESS(string msg)
  163. {
  164. DebugStub.WriteLine(msg);
  165. }
  166. [System.Diagnostics.Conditional("ISA_ARM")]
  167. private static void ARM_SPIN_FOREVER(string msg)
  168. {
  169. DebugStub.Assert(!Processor.InterruptsDisabled());
  170. Processor p = Processor.CurrentProcessor;
  171. DebugStub.WriteLine(msg);
  172. DateTime last = DateTime.Now;
  173. uint n = 0;
  174. while (true) {
  175. Thread.Sleep(1000);
  176. }
  177. }
  178. // Note: This function is called by Hal.cpp.
  179. [AccessedByRuntime("referenced from hal.cpp")]
  180. internal static int Main()
  181. {
  182. bootReturnCode = Platform.EXIT_AND_RESTART;
  183. InitPreMonitoring();
  184. try {
  185. InitServices();
  186. // Consider boot successful at this stage.
  187. bootReturnCode = Platform.EXIT_AND_SHUTDOWN;
  188. ARM_SPIN_FOREVER("kernel.arm Spinning forever");
  189. bootReturnCode = SpawnAndWaitForShell();
  190. // The shell has exited when we get here
  191. FinalizeServices();
  192. }
  193. catch (Exception e) {
  194. System.Console.WriteLine("EXCEPTION:: " + e.Message);
  195. Tracing.Log(Tracing.Fatal, "Caught exception {0}", e.Message);
  196. DebugStub.WriteLine("Caught {0}", __arglist(e.Message));
  197. bootReturnCode = -1;
  198. DebugStub.Break();
  199. }
  200. DebugStub.WriteLine("Kernel exiting with 0x{0:x4}", __arglist(bootReturnCode));
  201. FinalizePreMonitoring();
  202. if (bootReturnCode != Platform.EXIT_AND_WARMBOOT) {
  203. Kill(bootReturnCode);
  204. }
  205. return bootReturnCode;
  206. }
  207. private static void InitPreMonitoring()
  208. {
  209. Tracing.Log(0);
  210. Tracing.Log(1);
  211. Tracing.Log(2);
  212. Tracing.Log(3);
  213. DebugStub.WriteLine("-------------------------------------------------------------------------------");
  214. ARM_PROGRESS("Kernel!001");
  215. // Indicate that we are not booted yet
  216. hasBooted = false;
  217. // Rather than mark all bootstrap code with [NoBarriers], perform a mini-
  218. // initialization that gives us a working WriteBarrier.
  219. System.GCs.Barrier.PreInitialize();
  220. ARM_PROGRESS("Kernel!002");
  221. // Initialize the memory subsystem. If enabled this turns on paging
  222. MemoryManager.Initialize();
  223. // Note for Monitoring early boot process:
  224. // if you ever want to monitor stuff before this point, you should
  225. // allocate a static memory area in BootInit.cs, init the
  226. // monitoring system earlier, hold the system at this point here,
  227. // copy over all the collected data up to now to the new
  228. // dynamically created buffer and continue
  229. Monitoring.Initialize(); // uses page memory
  230. ARM_PROGRESS("Kernel!003");
  231. HandleTable.Initialize();
  232. }
  233. private static void InitGCSupport()
  234. {
  235. ARM_PROGRESS("Kernel!004");
  236. // Initialize the rest of the primitive runtime.
  237. VTable.Initialize((RuntimeType)typeof(Kernel));
  238. ARM_PROGRESS("Kernel!005");
  239. // Must occur before MemoryManager.PostGCInitialize()
  240. ProtectionDomain.Initialize();
  241. ARM_PROGRESS("Kernel!006");
  242. // Must occur before SharedHeap.Initialize()
  243. MemoryManager.PostGCInitialize();
  244. ARM_PROGRESS("Kernel!007");
  245. // Allocates callback objects for stack growth
  246. Stacks.Initialize();
  247. ARM_PROGRESS("Kernel!008");
  248. // Initialize the HAL parts which require GC allocation
  249. Platform.ThePlatform.InitializeServices();
  250. ARM_PROGRESS("Kernel!009");
  251. SharedHeap.Initialize();
  252. ARM_PROGRESS("Kernel!010");
  253. // Must occur after SharedHeap.Initialize();
  254. ProtectionDomain.DefaultDomain.InitHook();
  255. }
  256. private static void InitServices()
  257. {
  258. InitGCSupport();
  259. args = GetCommandLine();
  260. VTable.ParseArgs(args);
  261. ARM_PROGRESS("Kernel!011");
  262. InitSchedulerTypes();
  263. ARM_PROGRESS("Kernel!018");
  264. Controller.InitializeSystem();
  265. Tracing.InitializeSystem();
  266. ARM_PROGRESS("Kernel!019");
  267. // Read the profiler settings. The values are assumed in kbytes
  268. // convert them to bytes for direct consumption
  269. ProfilerBufferSize = (uint)GetIntegerArgument("profiler", 0);
  270. ProfilerBufferSize *= 1024;
  271. ARM_PROGRESS("Kernel!020");
  272. SpinLock.StaticInitialize();
  273. int cpusLength;
  274. int cpuCount = GetCpuCount(out cpusLength);
  275. Processor.InitializeProcessorTable(cpusLength);
  276. ARM_PROGRESS("Kernel!021");
  277. Tracing.Log(Tracing.Audit, "processor");
  278. Processor processor = Processor.EnableProcessor(0);
  279. PEImage.Initialize();
  280. ARM_PROGRESS("Kernel!034");
  281. // Initialize the sample profiling for the processor
  282. // after the initial breakpoint in kd in the call
  283. // PEImage.Initialize(). This will allow enabling profiling
  284. // from kd, by overwriting the ProfilerBufferSize value
  285. processor.EnableProfiling();
  286. ARM_PROGRESS("Kernel!035");
  287. FlatPages.InitializeMemoryMonitoring();
  288. // initialize endpoints
  289. InitType(typeof(Microsoft.Singularity.Channels.EndpointCore));
  290. // TODO Bug 59: Currently broken, need to review paging build.
  291. //#if PAGING
  292. // Microsoft.Singularity.Channels.EndpointTrusted.StaticInitialize();
  293. //#endif
  294. ARM_PROGRESS("Kernel!036");
  295. // get the system manifest
  296. IoMemory systemManifest = GetSystemManifest();
  297. ARM_PROGRESS("Kernel!037");
  298. XmlReader xmlReader = new XmlReader(systemManifest);
  299. XmlNode xmlData = xmlReader.Parse();
  300. XmlNode manifestRoot = xmlData.GetChild("system");
  301. XmlNode initConfig = manifestRoot.GetChild("initConfig");
  302. ARM_PROGRESS("Kernel!038");
  303. PerfCounters.Initialize();
  304. // need to have processed the manifest before we can call Process initialize
  305. ARM_PROGRESS("Kernel!039");
  306. PrincipalImpl.Initialize(initConfig);
  307. ARM_PROGRESS("Kernel!040");
  308. Process.Initialize(manifestRoot.GetChild("processConfig"));
  309. InitIO(processor, initConfig, manifestRoot.GetChild("drivers"));
  310. InitBootTime();
  311. ARM_PROGRESS("Kernel!045");
  312. // From here on, we want lazy type initialization to worry about
  313. // competing threads.
  314. VTable.InitializeForMultipleThread();
  315. ARM_PROGRESS("Kernel!046");
  316. Console.WriteLine("Running C# Kernel of {0}", GetLinkDate());
  317. Console.WriteLine();
  318. // TODO: remove this
  319. Console.WriteLine("Current time: {0}", SystemClock.GetUtcTime().ToString("r"));
  320. ARM_PROGRESS("Kernel!047");
  321. InitScheduling();
  322. DirectoryService.StartNotificationThread();
  323. Console.WriteLine("Initializing Shared Heap Walker");
  324. ProtectionDomain.InitializeSharedHeapWalker();
  325. ARM_PROGRESS("Kernel!050");
  326. Console.WriteLine("Initializing Service Thread");
  327. ServiceThread.Initialize();
  328. ARM_PROGRESS("Kernel!051");
  329. GC.EnableHeap();
  330. GCProfilerLogger.StartProfiling();
  331. ARM_PROGRESS("Kernel!052");
  332. Tracing.Log(Tracing.Audit, "Waypoints init");
  333. Waypoints = new long[2048];
  334. WaypointSeq = new int[2048];
  335. WaypointThd = new int[2048];
  336. Tracing.Log(Tracing.Audit, "Interrupts ON.");
  337. Processor.RestoreInterrupts(true);
  338. ARM_PROGRESS("Kernel!053");
  339. #if ISA_ARM && TEST_GC
  340. for (int i = 0; i < 1000; i++) {
  341. DebugStub.WriteLine("Iteration {0}", __arglist(i));
  342. ArrayList a = new ArrayList();
  343. for (int j = 0; j < 128; j++) {
  344. int size = 1024 * 1024;
  345. a.Add(new byte [size]);
  346. }
  347. }
  348. #endif // ISA_ARM
  349. ARM_PROGRESS("Kernel!054");
  350. Tracing.Log(Tracing.Audit, "Binder");
  351. Binder.Initialize(manifestRoot.GetChild("namingConventions"));
  352. #if ISA_ARM
  353. DebugStub.WriteLine("Exporting local namespace to BSP\n");
  354. DirectoryService.ExportArmNamespace();
  355. DebugStub.WriteLine("Export complete...redirecting binder\n");
  356. Binder.RedirectRootRef();
  357. DebugStub.WriteLine("Binder redirect complete\n");
  358. #endif
  359. #if false
  360. Tracing.Log(Tracing.Audit, "Starting Security Service channels");
  361. PrincipalImpl.Export();
  362. ARM_PROGRESS("Kernel!055");
  363. #endif
  364. Tracing.Log(Tracing.Audit, "Creating Root Directory.");
  365. //This can be moved below
  366. IoSystem.InitializeDirectoryService();
  367. ARM_PROGRESS("Kernel!055");
  368. #if false
  369. // Start User space namespace manager
  370. Console.WriteLine("Starting Directory Service SIP");
  371. DirectoryService.StartUserSpaceDirectoryService();
  372. #endif
  373. ARM_PROGRESS("Kernel!055.5");
  374. #if !ISA_ARM
  375. Tracing.Log(Tracing.Audit, "Starting Security Service channels");
  376. PrincipalImpl.Export();
  377. #endif
  378. ARM_PROGRESS("Kernel!056");
  379. Console.WriteLine("Initializing system channels");
  380. // starting channels services
  381. DebugStub.Print("Initializing Channel Services\n");
  382. ChannelDeliveryImplService.Initialize();
  383. ARM_PROGRESS("Kernel!057");
  384. ConsoleOutput.Initialize();
  385. ARM_PROGRESS("Kernel!058");
  386. // Initialize MP after Binder and ConsoleOutput
  387. // are initialized so there are no
  388. // initialization races if the additional
  389. // threads try to use them.
  390. Tracing.Log(Tracing.Audit, "Starting additional processors");
  391. // For ABI to ARM support
  392. MpExecution.Initialize();
  393. ARM_PROGRESS("Kernel!059");
  394. mpEndEvent = new ManualResetEvent(false);
  395. Tracing.Log(Tracing.Audit, "Initializing Volume Manager.");
  396. #if !ISA_ARM
  397. IoSystem.InitializeVolumeManager();
  398. #endif // ISA_ARM
  399. ARM_PROGRESS("Kernel!060");
  400. #if MEASURE_INIT_IO_PERFORMANCE
  401. PerfSnap snap = new PerfSnap();
  402. snap.Start();
  403. #endif
  404. InitDrivers();
  405. #if MEASURE_INIT_IO_PERFORMANCE
  406. snap.Finish(1);
  407. snap.DisplaySimple();
  408. #endif
  409. if (cpuCount > 1) {
  410. unsafe {
  411. Console.WriteLine("Enabling {0} cpus out of {1} real cpus\n", cpuCount, Platform.ThePlatform.CpuRealCount);
  412. }
  413. Processor.EnableMoreProcessors(cpuCount);
  414. ARM_PROGRESS("Kernel!064");
  415. }
  416. Tracing.Log(Tracing.Audit, "Initializing Service Manager.");
  417. IoSystem.InitializeServiceManager(manifestRoot.GetChild("serviceConfig"));
  418. ARM_PROGRESS("Kernel!065");
  419. InitDiagnostics();
  420. #if !ISA_ARM
  421. // At this point consider kernel finshed booting
  422. hasBooted = true;
  423. #endif // ISA_ARM
  424. Processor.StartSampling();
  425. ARM_PROGRESS("Kernel!069");
  426. Microsoft.Singularity.KernelDebugger.KdFilesNamespace.StartNamespaceThread();
  427. ARM_PROGRESS("Kernel!070");
  428. }
  429. private static void InitSchedulerTypes()
  430. {
  431. InitType(typeof(Processor));
  432. InitType(typeof(Scheduler));
  433. InitType(typeof(ProcessorDispatcher));
  434. // InitType(typeof(AffinityScheduler));
  435. InitType(typeof(MinScheduler));
  436. ARM_PROGRESS("Kernel!013");
  437. // Create scheduler before initializing processes
  438. scheduler = new MinScheduler();
  439. ARM_PROGRESS("Kernel!017");
  440. // Initialize processor dispatcher
  441. ProcessorDispatcher.StaticInitialize(scheduler);
  442. }
  443. private static void InitScheduling()
  444. {
  445. Console.WriteLine("Initializing Scheduler");
  446. ARM_PROGRESS("Kernel!047");
  447. // Finish scheduler initialization:
  448. scheduler.Initialize();
  449. ARM_PROGRESS("Kernel!048");
  450. // Initialize initial dispatcher
  451. Processor.InitializeDispatcher(0);
  452. Processor.ActivateTimer(0);
  453. ARM_PROGRESS("Kernel!049");
  454. }
  455. private static void InitIO(Processor p, XmlNode initConfig, XmlNode driverConfig)
  456. {
  457. // obtain the configuration for the namespace service
  458. // and initialize the namespace service
  459. ARM_PROGRESS("Kernel!041");
  460. DirectoryService.Initialize(initConfig);
  461. Tracing.Log(Tracing.Audit, "IoSystem");
  462. ARM_PROGRESS("Kernel!042");
  463. IoSystem.Initialize(driverConfig);
  464. Tracing.Log(Tracing.Audit, "Registering HAL Drivers.");
  465. ARM_PROGRESS("Kernel!043");
  466. Devices.RegisterPnpResources(); // add the root devices
  467. ARM_PROGRESS("Kernel!044");
  468. Platform.InitializeHal(p);
  469. }
  470. private static int SpawnAndWaitForShell()
  471. {
  472. #if ISA_ARM
  473. // spin here for now
  474. while (true) {
  475. Thread.Yield();
  476. }
  477. #else
  478. Tracing.Log(Tracing.Audit, "Creating Shell Process");
  479. ARM_PROGRESS("Kernel!071");
  480. int exit = -10000;
  481. Manifest manifest;
  482. #if KERNEL_USE_LOGIN
  483. IoMemory memory;
  484. if (args[0] == "bvt") {
  485. memory = Binder.LoadImage(Thread.CurrentProcess, "tty", out manifest);
  486. }
  487. else{
  488. // TODO: The login app needs to be fixed to setup stdin and stdout pipes for
  489. // the shell and pump the data back and forth.
  490. memory = Binder.LoadImage(Thread.CurrentProcess, "login", out manifest);
  491. }
  492. #else
  493. IoMemory memory = Binder.LoadImage(Thread.CurrentProcess, "tty", out manifest);
  494. #endif
  495. ARM_PROGRESS("Kernel!073");
  496. if (memory == null || memory.Length > 0) {
  497. String[] shellArgs = new String[args.Length + 2];
  498. shellArgs[0] = "tty";
  499. shellArgs[1] = "shell";
  500. for (int i = 0; i < args.Length; i++) {
  501. shellArgs[i + 2] = args[i];
  502. }
  503. Process process = new Process(Thread.CurrentProcess, memory, null, shellArgs, manifest);
  504. if (process != null) {
  505. PrintBootTime();
  506. process.Start();
  507. process.Join();
  508. exit = process.ExitCode;
  509. }
  510. ARM_PROGRESS("Kernel!074");
  511. }
  512. return DetermineShutdown(exit);
  513. #endif
  514. }
  515. private static int DetermineShutdown(int exit)
  516. {
  517. switch (exit) {
  518. case -10000:
  519. Tracing.Log(Tracing.Audit, "Failed to start shell process.");
  520. return Platform.EXIT_AND_RESTART;
  521. case Platform.EXIT_AND_WARMBOOT:
  522. case Platform.EXIT_AND_RESTART:
  523. case Platform.EXIT_AND_SHUTDOWN:
  524. return exit;
  525. default:
  526. DebugStub.WriteLine("Shell process terminated improperly (0x{0:x4})",
  527. __arglist(exit));
  528. Tracing.Log(Tracing.Audit, "Shell process terminated improperly");
  529. DebugStub.Break();
  530. return Platform.EXIT_AND_SHUTDOWN;
  531. }
  532. }
  533. private static void InitBootTime()
  534. {
  535. if (Platform.ThePlatform.BootYear != 0) {
  536. BootTime = new DateTime((int)Platform.ThePlatform.BootYear,
  537. (int)Platform.ThePlatform.BootMonth,
  538. (int)Platform.ThePlatform.BootDay,
  539. (int)Platform.ThePlatform.BootHour,
  540. (int)Platform.ThePlatform.BootMinute,
  541. (int)Platform.ThePlatform.BootSecond,
  542. 0);
  543. // There is no time zone support in Singularity, the clock assumes GMT
  544. // but the CMOS reports it in local time. Hardcode the correction here for now
  545. BootTime = BootTime.AddHours(8);
  546. }
  547. else {
  548. // Other HALs do not capture the load time. Make the best effort to
  549. // capture now, after the devices are initialized.
  550. BootTime = DateTime.Now;
  551. }
  552. }
  553. private static void InitDrivers()
  554. {
  555. // Register drivers who depend on scheduling and resource management.
  556. DebugStub.WriteLine("--- Registering Drivers ---------------------------");
  557. Console.WriteLine("Registering Non-HAL Drivers.");
  558. // register the metadata-based drivers
  559. IoSystem.RegisterDrivers();
  560. ARM_PROGRESS("Kernel!061");
  561. // register the internal kernel drivers
  562. Devices.RegisterInternalDrivers();
  563. ARM_PROGRESS("Kernel!062");
  564. #if DEBUG
  565. // and output the results
  566. IoSystem.Dump(false);
  567. #endif
  568. DebugStub.WriteLine("--- Activating Devices ----------------------------");
  569. // now do device initialization
  570. IoSystem.ActivateDrivers();
  571. ARM_PROGRESS("Kernel!063");
  572. #if DEBUG
  573. // and output the results
  574. // IoSystem.Dump(true);
  575. #endif
  576. }
  577. private static void InitDiagnostics()
  578. {
  579. // Start up the kernel's diagnostics module
  580. Console.WriteLine("Starting diagnostics module...");
  581. Diagnostics.DiagnosticsModule.Initialize();
  582. ARM_PROGRESS("Kernel!066");
  583. // Start up the kernel's stress test module
  584. Console.WriteLine("Initializing stress module...");
  585. Stress.StressService.Initialize();
  586. ARM_PROGRESS("Kernel!067");
  587. }
  588. private static IoMemory GetSystemManifest()
  589. {
  590. IoMemory res = Binder.GetSystemManifest();
  591. if (res == null) {
  592. DebugStub.WriteLine("Failed to load system manifest.");
  593. DebugStub.Break();
  594. throw new Exception("The system manifest could not be loaded.");
  595. }
  596. return res;
  597. }
  598. private static void FinalizeServices()
  599. {
  600. ARM_PROGRESS("Kernel!075");
  601. Tracing.Log(Tracing.Audit, "Shutting down AP processors");
  602. Processor.StopApProcessors();
  603. Tracing.Log(Tracing.Audit, "Shutting down I/O system");
  604. Console.WriteLine("Shutting down I/O system");
  605. IoSystem.Finalize();
  606. Tracing.Log(Tracing.Audit, "Interrupts OFF.");
  607. Processor.DisableInterrupts();
  608. Tracing.Log(Tracing.Audit, "Shutting down scheduler");
  609. Console.WriteLine("Shutting down scheduler");
  610. for (int i = 0; i < Processor.processorTable.Length; i++) {
  611. Processor p = Processor.processorTable[i];
  612. if (p != null) {
  613. Console.WriteLine(" cpu {0}: {1} context switches, {2} interrupts", i, p.NumContextSwitches, p.NumInterrupts);
  614. }
  615. }
  616. // Finalize the scheduler
  617. scheduler.Finalize();
  618. // We should turn off interrupts here!
  619. Platform.ReleaseResources();
  620. PEImage.Finalize();
  621. DebugStub.WriteLine("Kernel Exiting [{0}]",
  622. __arglist(bootReturnCode));
  623. }
  624. private static void FinalizePreMonitoring()
  625. {
  626. Stacks.Finalize();
  627. HandleTable.Finalize();
  628. SharedHeap.Finalize();
  629. MemoryManager.Finalize();
  630. }
  631. private static int GetCpuCount(out int cpusLength)
  632. {
  633. int cpuReal = Platform.ThePlatform.CpuRealCount;
  634. int cpuLimit = Platform.ThePlatform.CpuMaxCount;
  635. DebugStub.Assert(cpuReal <= cpuLimit);
  636. // See if the command line argument limits our processor count
  637. int cpuCount = GetIntegerArgument("mp", cpuReal);
  638. cpusLength = cpuReal;
  639. #if !SINGULARITY_MP
  640. if (cpuCount > 1) {
  641. Console.WriteLine("Limiting processors to 1 due to SP build");
  642. cpuCount = 1;
  643. }
  644. #endif
  645. return cpuCount;
  646. }
  647. // Note: This function is entry point to the managed
  648. // kernel for CPU's other than the bootstrap processor.
  649. // It is called from the Hal or Hal.
  650. [AccessedByRuntime("referenced from hal.cpp")]
  651. internal static int MpMain(int cpu)
  652. {
  653. Tracing.Log(Tracing.Audit, "processor");
  654. Processor processor = Processor.EnableProcessor(cpu);
  655. // Initialize dispatcher
  656. Processor.InitializeDispatcher(cpu);
  657. // Initialize the HAL processor services
  658. // Note that this must occur after EnableProcessor, as the kernel
  659. // thread does not get bound until then. (It gets bound much
  660. // earlier in the boot processor case -- need to decide if this difference is
  661. // really appropriate.)
  662. Platform.Cpu(cpu).InitializeServices();
  663. Platform.InitializeHal(processor);
  664. Thread.CurrentThread.Affinity = cpu;
  665. Processor.ActivateTimer(cpu);
  666. #if DEBUG_SYSTEM_LOCKUP
  667. // Spin one CPU on debugger. For instance with a quad-proc
  668. // box, spin CPU 3.
  669. while (cpu == 3) {
  670. if (DebugStub.PollForBreak() == true) {
  671. DebugStub.Break();
  672. }
  673. }
  674. #endif // DEBUG_SYSTEM_LOCKUP
  675. Processor.RestoreInterrupts(true);
  676. Tracing.Log(Tracing.Audit,
  677. "Looping in processor's kernel thread.");
  678. //while (cpu > 0) {
  679. // Thread.Yield();
  680. //}
  681. // This probably won't be the
  682. // ultimate way of dissociating kernel entry threads
  683. // from the kernel.
  684. DebugStub.Print("AP Processor started, about to wait\n");
  685. mpEndEvent.WaitOne();
  686. return 0;
  687. }
  688. // This function is called by the GC to locate all non-static object
  689. // references allocated somewhere other than the stack.
  690. internal static
  691. void VisitSpecialData(System.GCs.DirectReferenceVisitor visitor)
  692. {
  693. Platform.ThePlatform.VisitSpecialData(visitor);
  694. Process.VisitSpecialData(visitor);
  695. visitor.VisitReferenceFields(Processor.processorTable);
  696. }
  697. // This function is called by GCs that move object to update all
  698. // object references contained in non-objects (i.e. unsafe structs).
  699. internal static void UpdateAfterGC(Thread currentThread)
  700. {
  701. Processor.UpdateAfterGC(currentThread);
  702. }
  703. [AccessedByRuntime("defined in HAL.cpp")]
  704. [MethodImpl(MethodImplOptions.InternalCall)]
  705. [StackBound(256)]
  706. [NoHeapAllocation]
  707. private static unsafe extern char * HalGetLinkDate();
  708. internal static unsafe string GetLinkDate()
  709. {
  710. return new String(HalGetLinkDate());
  711. }
  712. internal static unsafe string[] GetCommandLine()
  713. {
  714. String[] args =
  715. (new String((char *)(Platform.ThePlatform.CommandLine),
  716. 0, Platform.ThePlatform.CommandLineCount)).Split(null);
  717. int dst = 0;
  718. for (int src = 0; src < args.Length; src++) {
  719. if (args[src] != null && args[src].Length > 0) {
  720. args[dst++] = args[src];
  721. }
  722. }
  723. if (dst < args.Length) {
  724. String[] list = new String[dst];
  725. for (int i = 0; i < dst; i++) {
  726. list[i] = args[i];
  727. }
  728. return list;
  729. }
  730. return args;
  731. }
  732. // kind the argument "key" and extract the string value following a colon.
  733. internal static string
  734. GetStringArgument(string key, string defaultValue)
  735. {
  736. key = key + ":";
  737. for (int i = 0; i < args.Length; i++) {
  738. string arg = args[i];
  739. if ((arg.StartsWith("-") || arg.StartsWith("/")) &&
  740. 0 == String.Compare(arg, 1, key, 0, key.Length, true)) {
  741. string result = arg.Substring(key.Length+1);
  742. string[] newargs = new string[args.Length - 1];
  743. Array.Copy(args, 0, newargs, 0, i);
  744. Array.Copy(args, i + 1, newargs, i, args.Length - i - 1);
  745. args = newargs;
  746. return result;
  747. }
  748. }
  749. return defaultValue;
  750. }
  751. internal static int GetIntegerArgument(string key, int defaultValue)
  752. {
  753. key = key + ":";
  754. for (int i = 0; i < args.Length; i++) {
  755. string arg = args[i];
  756. if ((arg.StartsWith("-") || arg.StartsWith("/")) &&
  757. 0 == String.Compare(arg, 1, key, 0, key.Length, true)) {
  758. string result = arg.Substring(key.Length+1);
  759. string[] newargs = new string[args.Length - 1];
  760. Array.Copy(args, 0, newargs, 0, i);
  761. Array.Copy(args, i + 1, newargs, i, args.Length - i - 1);
  762. args = newargs;
  763. // TODO this should be try-parse
  764. return Int32.Parse(result);
  765. }
  766. }
  767. return defaultValue;
  768. }
  769. [NoHeapAllocation]
  770. public static void RequestWarmBoot()
  771. {
  772. bootReturnCode = Platform.EXIT_AND_WARMBOOT;
  773. }
  774. [NoHeapAllocation]
  775. public static void RequestRestart()
  776. {
  777. bootReturnCode = Platform.EXIT_AND_RESTART;
  778. }
  779. [NoHeapAllocation]
  780. public static void RequestShutdown()
  781. {
  782. bootReturnCode = Platform.EXIT_AND_SHUTDOWN;
  783. }
  784. private static void Kill(int exitCode)
  785. {
  786. Platform.ThePlatform.Kill(exitCode);
  787. }
  788. internal static void Shutdown(int exitCode)
  789. {
  790. unchecked {
  791. Tracing.Log(Tracing.Audit, "Kernel.Shutdown({0})", (UIntPtr)(uint)exitCode);
  792. }
  793. DebugStub.WriteLine("Kernel.Shutdown(0x{0:x4})",
  794. __arglist(exitCode));
  795. DebugStub.Break();
  796. VTable.Shutdown(exitCode);
  797. }
  798. // Rationale for cutting the fact that no stack probes are permitted in this
  799. // tree of calls:
  800. //
  801. // * We are already hosed.
  802. // * Without this cut, places that cannot (transitively) tolerate stack link extensions
  803. // * cannot call Panic.
  804. [NoStackLinkCheckTransCut][IgnoreLockRank]
  805. internal static void Panic(string why)
  806. {
  807. DebugStub.WriteLine("KERNEL PANIC: {0}", __arglist(why));
  808. Shutdown(Platform.EXIT_AND_HALT);
  809. }
  810. //////////////////////////////////////////////////////////////////////
  811. //
  812. [NoHeapAllocation]
  813. public static UIntPtr AddressOf(Object o)
  814. {
  815. return Magic.addressOf(o);
  816. }
  817. [NoHeapAllocation]
  818. public static UIntPtr SizeOf(Object o)
  819. {
  820. return System.GCs.ObjectLayout.Sizeof(o);
  821. }
  822. [NoHeapAllocation]
  823. public static UIntPtr AddressOf(ITracked tracked)
  824. {
  825. return Magic.addressOf(tracked);
  826. }
  827. [NoHeapAllocation]
  828. unsafe public static UIntPtr AddressOf(void * ptr)
  829. {
  830. return (UIntPtr)ptr;
  831. }
  832. public static void InitType(Type ty)
  833. {
  834. VTable.initType((RuntimeType) ty);
  835. }
  836. [NoHeapAllocation]
  837. public static string TypeName(Object o)
  838. {
  839. if (o == null) {
  840. return "null";
  841. }
  842. else {
  843. Type t = o.GetType();
  844. RuntimeType r = (RuntimeType)t;
  845. return r.Name;
  846. }
  847. }
  848. [NoHeapAllocation]
  849. public static string TypeNameSpace(Object o)
  850. {
  851. if (o == null) {
  852. return "null";
  853. }
  854. else {
  855. Type t = o.GetType();
  856. RuntimeType r = (RuntimeType)t;
  857. return r.Namespace;
  858. }
  859. }
  860. public static string FullTypeName(Object o)
  861. {
  862. if (o == null) {
  863. return "null";
  864. }
  865. else {
  866. Type t = o.GetType();
  867. RuntimeType r = (RuntimeType)t;
  868. return r.Namespace + "." + r.Name;
  869. }
  870. }
  871. public static void DumpPageTable()
  872. {
  873. System.GCs.PageTable.Dump("PageTable");
  874. }
  875. internal static void PrintBootTime()
  876. {
  877. // Console.WriteLine("Current time: {0}", SystemClock.GetUtcTime().ToString("r"));
  878. // Console.WriteLine("Boot time: {0}", BootTime.ToString("r"));
  879. TimeSpan delta = SystemClock.GetUtcTime() - BootTime;
  880. DebugStub.WriteLine("Elapsed boot time = {0} msec.", __arglist(delta.TotalMilliseconds));
  881. }
  882. }
  883. }