/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: DriverResourceTransform.sg // // Creates startup boilerplate code from Resource descriptions. // using Microsoft.Contracts; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Extending; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Io; using Microsoft.Singularity.Configuration; using System; namespace Microsoft.Singularity.Drivers{ transform DriverResourceTransform where $IoRangeType : IoRange where $IoFixedRangeType : IoRange where $IoRangeAttribute : IoRangeAttribute where $IoFixedRangeAttribute : IoFixedRangeAttribute where $EndpointType : unmanaged struct, Endpoint, ITracked { [Signature($signature)] internal class $$DriverResources : DriverCategoryDeclaration { [$IoRangeAttribute($index, *)] internal $IoRangeType $$ioranges; [$IoFixedRangeAttribute(*)] internal $IoFixedRangeType $$iofixedranges; [ExtensionEndpoint(*)] internal TRef $$extensions; [ServiceEndpoint(*)] internal TRef $$providers; [Endpoint(*)] TRef<$EndpointType,$State> $$endpoints; internal int DriverMain(); // TODO: Move initialization // into a common routine rather than duplicating it // in all driver resource classes. generate public $$DriverResources(IoConfig! config) { Tracing.Log(Tracing.Debug, "Config: {0}", config.ToPrint()); int index = 0; forall ( ; $e in $$extensions; ){ ExtensionContract.Exp:Start ep = Process.GetStartupEndpoint(index) as ExtensionContract.Exp; if (ep == null) { throw new ArgumentException(String.Format("missing startup endpoint {0}", index)); } $e = new TRef (ep); ++index; } forall ( ; $sp in $$providers ; ) { ServiceProviderContract.Exp:Start ep = Process.GetStartupEndpoint(index) as ServiceProviderContract.Exp; if (ep == null) { throw new ArgumentException(String.Format("missing startup endpoint {0}", index)); } $sp = new TRef (ep); ++index; } assume config.DynamicRanges != null; forall ($cindex = 0; $f in $$ioranges; $cindex++) { $f = ($f.$IoRangeType) config.DynamicRanges[(int)(object)$f.$index]; } assume config.FixedRanges != null; forall ($cindex = 0; $f in $$iofixedranges; $cindex++) { $f = ($f.$IoFixedRangeType) config.FixedRanges[$cindex]; } index = 0; forall ( ; $e in $$endpoints; ){ if ( index == 0 || index == 1) { DebugStub.WriteLine("transform skipping pipe at {0}",__arglist(index)); } else { $e.$EndpointType* in ExHeap opt($e.$State) ep = Process.GetStartupEndpoint(index) as $e.$EndpointType* in ExHeap opt($e.$State); if (ep == null) { throw new ArgumentException(String.Format("missing startup endpoint {0}", index)); } $e = new TRef<$e.$EndpointType, $e.$State> (ep); DebugStub.WriteLine("getting endpoint at {0}",__arglist(index)); } ++index; } } } generate internal class DriverEntry { static int Main(string [] args) { if (args == null) { DebugStub.WriteLine("DriverTransform: args are null?!"); DebugStub.Break(); return -1; } if (args.Length < 5) { DebugStub.WriteLine("DriverTransform: too few arguments!"); DebugStub.Break(); return -1; } IoConfig! config = (!)IoConfig.GetConfig(); DebugStub.Assert((!)args[3] == "-signature"); string! signature = (!)args[4]; // DebugStub.WriteLine("DriverTransform: searching for resources matching signature: " + signature); forall( ; $DriverResource in $$DriverResources; ) { if ($DriverResource.$signature == signature || String.Compare($DriverResource.$signature, signature, true) == 0) { // DebugStub.WriteLine("DriverTransform: selected implementation in class " + typeof($DriverResource).FullName); $DriverResource d = new $DriverResource(config); return d.DriverMain(); } } DebugStub.WriteLine("ERROR: Process driver was started, but the device ID provided did not match any implementation in this executable."); DebugStub.WriteLine(" Device ID selected: " + signature); DebugStub.WriteLine("This executable contains implementations matching the following device IDs:"); forall( ; $DriverResource in $$DriverResources; ) { DebugStub.WriteLine(" " + $DriverResource.$signature + " in class " + typeof($DriverResource).FullName); } DebugStub.Break(); return -1; } } } }