/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: DriverAttributes.cs // // Warning: This file is compiled into the kernel, and into the runtime. // In order to get the visibility correct in all cases, some #ifs // are needed // // New Design: // This now conforms with the ideas presented in the Genesis papers, // chapter 3. In particular, a device driver is simply a Category, // and anything that is in an app manifest is either intrinsic to // apps/installations (and hence not a decoration), or else a // PropertySet or Category. using System; using Microsoft.Singularity.Configuration; namespace Microsoft.Singularity.Io { // // The Driver Category // // Drivers are apps that run in a special Category. We will designate this // by deriving a new class from CategoryDeclaration to represent this // special Category, and then creating special field annotations that only // apply to this Category. // public class DriverCategoryDeclaration : CategoryDeclaration { } ////////////////////////////////////////////////////////////////////////// // // DriverCategoryAttribute // // Purpose: Top-level metadata indicating that an assembly implements the // Driver Category // // Usage: Must be applied to a class derived from // DriverCategoryDeclaration // [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class DriverCategoryAttribute : System.Attribute { public DriverCategoryAttribute() { } } ////////////////////////////////////////////////////////////////////////// // // SignatureAttribute // // Purpose: Declare the signature of the device served by this driver // // Usage: Must be applied to a class derived from // DriverCategoryDeclaration // [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class SignatureAttribute : System.Attribute { // <> is the prefix of the device signature served by // this driver private string deviceIdentifier; public SignatureAttribute(string deviceIdentifier) { this.deviceIdentifier = deviceIdentifier; } } ////////////////////////////////////////////////////////////////////////// // // EnumeratesDeviceAttribute // // Purpose: Declare the signature of a device enumerated by this driver // // Usage: Must be applied to a class derived from // DriverCategoryDeclaration // [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class EnumeratesDeviceAttribute : System.Attribute { // <> is the prefix of the device signature served by // this driver private string deviceIdentifier; public EnumeratesDeviceAttribute(string deviceIdentifier) { this.deviceIdentifier = deviceIdentifier; } } ////////////////////////////////////////////////////////////////////////// // // IoRangeAttribute // // Purpose: All of the Io*RangeAttributes inherit from this one so they // can be processed together using link-time reflection (LTR). // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public abstract class IoRangeAttribute : System.Attribute { // <> defaults to -1 (unassigned). It is the index of the // port range in the list of dynamic driver resources. private int index; internal IoRangeAttribute(int index) { this.index = index; this.shared = false; } // <> defaults to false. To set it true, use the property // Sharable private bool shared; public bool Shared { get { return shared; } set { shared = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoFixedRangeAttribute // // Purpose: All of the IoFixed*RangeAttributes inherit from this one so they // can be processed together using link-time reflection (LTR). // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public abstract class IoFixedRangeAttribute : System.Attribute { public IoFixedRangeAttribute() { this.shared = false; } // <> defaults to false. To set it true, use the property // Sharable private bool shared; public bool Shared { get { return shared; } set { shared = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoPortRangeAttribute // // Purpose: Decorates a IoPortRange to indicate that the runtime should // preconfigure a PortRange based on the results of PnP // enumeration. The default is for the IoPortRange to be // read/write. This can be changed via properties. // // Usage: Must decorate an IoPortRange field of a class decorated with // [DriverCategory] // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public class IoPortRangeAttribute : IoRangeAttribute { // <> is required. It is the expected base address of the // PortRange private uint baseAddress; // <> is required. It is the expected length of the // port range that this driver wants to use. private uint rangeLength; public IoPortRangeAttribute(int index) : base(index) { this.baseAddress = 0; this.rangeLength = 0; this.read = true; this.write = true; } public uint Default { get { return baseAddress; } set { baseAddress = value; } } public uint Length { get { return rangeLength; } set { rangeLength = value; } } // <> and <> default to true. To set them false, the // Properties AllowRead and AllowWrite can be used private bool read; public bool AllowRead { get { return read; } set { read = value; } } private bool write; public bool AllowWrite { get { return write; } set { write = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoFixedPortRangeAttribute // // Purpose: Decorates a IoPortRange to indicate that the runtime should // preconfigure a PortRange based on the these static values. // // Usage: Must decorate an IoPortRange field of a class decorated with // [DriverCategory] // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public class IoFixedPortRangeAttribute : IoFixedRangeAttribute { // <> is required. It is the expected base address of the // PortRange private uint baseAddress; // <> is required. It is the expected length of the // port range that this driver wants to use. private uint rangeLength; public IoFixedPortRangeAttribute() { this.baseAddress = baseAddress; this.rangeLength = rangeLength; this.read = true; this.write = true; } public uint Base { get { return baseAddress; } set { baseAddress = value; } } public uint Length { get { return rangeLength; } set { rangeLength = value; } } // <> and <> default to true. To set them false, the // Properties AllowRead and AllowWrite can be used private bool read; public bool AllowRead { get { return read; } set { read = value; } } private bool write; public bool AllowWrite { get { return write; } set { write = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoIrqRangeAttribute // // Purpose: Decorates an IoIrqRange object to indicate that the runtime // should preconfigure an IrqRange based on the results of Pnp. // // Usage: Must decorate an IoIrqRange field of a class decorated with // [DriverCategory] // //[TODO] should these really be byte, or should they be ushort? [CLSCompliant(false)] [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class IoIrqRangeAttribute : IoRangeAttribute { // <> is the default Irq for the device. It is a required // parameter to the constructor. private byte baseAddress; // <> is the default length of the Irq range. It is also // a required parameter private byte rangeLength; public IoIrqRangeAttribute(int index) : base(index) { this.baseAddress = 0; this.rangeLength = 1; } public byte Default { get { return baseAddress; } set { baseAddress = value; } } public byte Length { get { return rangeLength; } set { rangeLength = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoIrqRangeAttribute // // Purpose: Decorates an IoIrqRange object to indicate that the runtime // should preconfigure an IrqRange based on the results of Pnp. // // Usage: Must decorate an IoIrqRange field of a class decorated with // [DriverCategory] // //[TODO] should these really be byte, or should they be ushort? [CLSCompliant(false)] [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class IoFixedIrqRangeAttribute : IoFixedRangeAttribute { // <> is the default Irq for the device. It is a required // parameter to the constructor. private byte baseAddress; // <> is the default length of the Irq range. It is also // a required parameter private byte rangeLength; public IoFixedIrqRangeAttribute() : base() { this.baseAddress = 0; this.rangeLength = 1; } public byte Base { get { return baseAddress; } set { baseAddress = value; } } public byte Length { get { return rangeLength; } set { rangeLength = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoDmaRangeAttribute // // Purpose: Decorates an IoDma object to indicate that the runtime should // preconfigure a Dma channel based on the results of Pnp. // // Usage: Must decorate an IoDmaRange field of a class decorated with // [DriverCategory] // [CLSCompliant(false)] [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class IoDmaRangeAttribute : IoRangeAttribute { // <> is the default Dma for the device private byte baseAddress; // <> is the default length of the Dma range private byte rangeLength; public IoDmaRangeAttribute(int index) : base(index) { this.baseAddress = 0; this.rangeLength = 1; } public byte Default { get { return baseAddress; } set { baseAddress = value; } } public byte Length { get { return rangeLength; } set { rangeLength = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoMemoryRangeAttribute // // Purpose: Decorates an IoMemory object to indicate that the runtime should // preconfigure some memory based on the results of Pnp. The // memory region is assumed to be read/write, unless these // values are changed via properties. // // Usage: Must decorate an IoMemoryRange field of a class decorated with // [DriverCategory] // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public class IoMemoryRangeAttribute : IoRangeAttribute { // <> is required. It is the expected base address of this // memory range. Use 0 if unsure. private uint baseAddress; // <> is required. It is the minimum acceptable size of // the region. private uint rangeLength; // <> and <> default to true. To set them false, use the // Properties AllowRead and AllowWrite private bool read; private bool write; public IoMemoryRangeAttribute(int index) : base(index) { this.baseAddress = baseAddress; this.rangeLength = rangeLength; this.read = true; this.write = true; } public bool AllowRead { get { return read; } set { read = value; } } public bool AllowWrite { get { return write; } set { write = value; } } public uint Default { get { return baseAddress; } set { baseAddress = value; } } public uint Length { get { return rangeLength; } set { rangeLength = value; } } } ////////////////////////////////////////////////////////////////////////// // // IoMemoryRangeAttribute // // Purpose: Decorates an IoMemory object to indicate that the runtime should // preconfigure are static memory region. The // memory region is assumed to be read/write, unless these // values are changed via properties. // // Usage: Must decorate an IoMemoryRange field of a class decorated with // [DriverCategory] // [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] [CLSCompliant(false)] public class IoFixedMemoryRangeAttribute : IoFixedRangeAttribute { // <> defaults to 0, any base. It is the expected base // address of this memory range. private uint baseAddress; // <> defaults to 0. It is the expected alignment. private uint alignment; // <> is required. It is the minimum acceptable size of // the region. private uint rangeLength; // <> defaults to 32. It is the # of address bits // supported by the hardware. Used to mark memory that must fit in // low 24 bits for legacy ISA devices, or low 32 bits for legacy PCI // devices. private int addressBits; // <> and <> default to true. To set them false, use the // Properties AllowRead and AllowWrite private bool read; private bool write; public IoFixedMemoryRangeAttribute() { this.addressBits = 32; this.alignment = 0; this.baseAddress = 0; this.rangeLength = 0; this.read = true; this.write = true; } public int AddressBits { get { return addressBits; } set { addressBits = value; } } public uint Alignment { get { return alignment; } set { alignment = value; } } public bool AllowRead { get { return read; } set { read = value; } } public bool AllowWrite { get { return write; } set { write = value; } } public uint Base { get { return baseAddress; } set { baseAddress = value; } } public uint Length { get { return rangeLength; } set { rangeLength = value; } } } }