singrdk/base/Kernel/Singularity/Isal/InterruptContext.cs

172 lines
4.9 KiB
C#

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This file defines an architecture-neutral encapsulation of the low-level information
// saved during an interrupt dispatch.
//
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
#if ISA_IX
using Microsoft.Singularity.Isal.IX;
#elif ISA_ARM
using Microsoft.Singularity.Isal.Arm;
#endif
namespace Microsoft.Singularity.Isal
{
// InterruptContext is the lightweight context which is pushed on the stack
// during interrupt generation. This is the minimal context save we will
// perform for any interrupt processing. (Note that it includes caller
// saved registers so we can use C code.)
[NoCCtor]
[AccessedByRuntime("referenced in c++", AllFields = true)]
[CLSCompliant(false)]
[StructLayout(LayoutKind.Sequential)]
public struct InterruptContext
{
#if ISA_IX
// Vector constants
public const int VectorExceptionMax = 0x20;
public const int VectorSchedulerMin = 0x21;
#if ISA_IX64
// Caller-saved registers (which get saved by our handler routine)
public UIntPtr r11;
public UIntPtr r10;
public UIntPtr r9;
public UIntPtr r8;
#endif //ISA_IX64
// Caller-saved registers (which get saved by our handler routine)
public UIntPtr dx;
public UIntPtr cx;
public UIntPtr ax;
// Interrupt information pushed as part of interrupt dispatch
public UIntPtr vector;
public UIntPtr err;
// Interruption context
public UIntPtr ip;
public UIntPtr cs;
public UIntPtr fl;
// This stack info is valid only in cases of cross-ring interrupts; otherwise
// we stay on the same stack and pop to this level (ignoring these two fields.)
public UIntPtr sp;
public UIntPtr ss;
#elif ISA_ARM
// Unbanked caller-saved registers.
public uint r0;
public uint r1;
public uint r2;
public uint r3;
public uint r12;
public uint pc; // aka r15
// Banked caller-saved registers.
public uint sp; // aka r13
public uint lr; // aka r14
// Resume proessor status register.
public uint cpsr;
// Interrupt information.
public uint vector;
public uint instruction;
#endif
[NoHeapAllocation]
public bool IsException()
{
#if ISA_IX
return (vector < 0x20);
#elif ISA_ARM
return (vector < ExceptionVector.Irq);
#endif
}
public byte ExceptionId
{
[NoHeapAllocation]
get {
return (byte)vector;
}
}
public UIntPtr InstructionPointer
{
[NoHeapAllocation]
get {
#if ISA_IX
return (UIntPtr)ip;
#elif ISA_ARM
return (UIntPtr)pc;
#endif
}
}
public UIntPtr StackPointer
{
[NoHeapAllocation]
get {
#if ISA_IX86
if ((cs & 0x3) == (Isa.GetCs() & 0x3)) {
unsafe {
fixed (UIntPtr *p = &sp) {
return *p;
}
}
}
else {
return sp;
}
#elif ISA_IX64
return sp;
#elif ISA_ARM
return sp;
#endif
}
}
[NoHeapAllocation]
public unsafe void Display()
{
#if ISA_IX86
DebugStub.WriteLine(" eax={0:x8} ecx={1:x8} edx={2:x8}",
__arglist(ax, cx, dx));
DebugStub.WriteLine(" esp[x-ring only]={0:x8}",
__arglist(sp));
DebugStub.WriteLine(" eip={0:x8} efl={1:x8}",
__arglist(ip, fl));
#elif ISA_IX64
DebugStub.WriteLine(" rax={0:x16} rcx={1:x16} rdx={2:x16}",
__arglist(ax, cx, dx));
DebugStub.WriteLine(" rsp={0:x16}",
__arglist(sp));
DebugStub.WriteLine(" rip={0:x16} rfl={1:x16}",
__arglist(ip, fl));
#elif ISA_ARM
DebugStub.WriteLine("pc={0:x8} sp={1:x8} lr={2:x8} sr={3:x8}",
__arglist(pc, sp, lr, cpsr));
DebugStub.WriteLine("r0={0:x8} r1={1:x8} r2={2:x8} r3={3:x8}",
__arglist(r0, r1, r2, r3));
#endif
}
}
}