singrdk/base/Kernel/Singularity/Isal/ix/InterruptTable.cs

93 lines
2.7 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace Microsoft.Singularity.Isal.IX
{
[NoCCtor]
[AccessedByRuntime("referenced in c++")]
[CLSCompliant(false)]
[StructAlign(16)]
[StructLayout(LayoutKind.Sequential, Pack=1,
#if ISA_IX86
Size=256*8 // sizeof(Idte)
#else
Size=256*16 // sizeof(Idte)
#endif
)]
public struct InterruptTable
{
// Dispatcher is an opaque declaration of a code fragment which normalizes
// the stack with the interrupt id, then dispatches to the centralized dispatch routine.
[AccessedByRuntime("referenced in asm")]
[StructLayout(LayoutKind.Sequential, Pack=1, Size=16)]
private struct Dispatcher
{
byte first;
}
// There are a total of 256 entries; this is controled by the StructLayout attribute above.
Idte entry0;
unsafe Idte *GetStart()
{
fixed (Idte *p = &entry0)
return p;
}
unsafe Idte *GetEnd()
{
fixed (Idte *p = &entry0)
return p+256;
}
[AccessedByRuntime("defined in idt.asm")]
[MethodImpl(MethodImplOptions.InternalCall)]
[GCAnnotation(GCOption.NOGC)]
[StackBound(16)]
[NoHeapAllocation]
private extern unsafe static Dispatcher *GetDispatchers();
[NoHeapAllocation]
public void Initialize()
{
unsafe {
Dispatcher *d = GetDispatchers();
fixed (Idte *first = &entry0) {
Idte *p = first;
Idte *pEnd = p + 256;
while (p < pEnd) {
InitializeEntry(ref *p, (UIntPtr) d);
p++;
d++;
}
}
}
}
[NoHeapAllocation]
public static void InitializeEntry(ref Idte entry, UIntPtr address)
{
entry.offset_0_15 = (ushort) address;
entry.offset_16_31 = (ushort) (((uint) address) >> 16);
#if ISA_IX64
entry.offset_32_63 = (uint) (((ulong)address) >> 32);
#endif
entry.selector = (ushort) Isa.GetCs();
entry.flags = 0;
entry.access = (byte) (Idte.PRESENT | Idte.DPL_RING0 | Idte.INT_GATE);
}
}
}