singrdk/base/Drivers/Transforms/DriverTransform.sg

149 lines
6.2 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// 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<ExtensionContract.Exp:Start> $$extensions;
[ServiceEndpoint(*)]
internal TRef<ServiceProviderContract.Exp:Start> $$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<ExtensionContract.Exp:Start> (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<ServiceProviderContract.Exp:Start> (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;
}
}
}
}