93 lines
2.7 KiB
C#
93 lines
2.7 KiB
C#
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 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);
|
||
|
}
|
||
|
}
|
||
|
}
|