149 lines
6.2 KiB
Plaintext
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|