コード例 #1
0
        public static bool Create(byte irqNum,
                                  out InterruptHandle handle)
        {
            bool ret = false;

            handle = new InterruptHandle();

            //
            // Create an IoIrq, and a handle in the current process to hold it.
            //
            IoConfig config = Thread.CurrentProcess.IoConfig;

            for (int i = 0; i < config.DynamicRanges.Length; i++)
            {
                IoIrqRange iir = config.DynamicRanges[i] as IoIrqRange;
                if (iir != null && iir.Irq <= irqNum && irqNum < iir.Irq + iir.Size)
                {
                    IoIrq irq = iir.IrqAtOffset((byte)(irqNum - iir.Irq));

                    handle = new InterruptHandle(
                        Thread.CurrentProcess.AllocateHandle(irq));
                    irq.RegisterInterrupt();
                    ret = true;
                    break;
                }
            }

            Tracing.Log(Tracing.Debug,
                        "InterruptHandle.Create(irq={0:x2}, out id={0:x8})",
                        irqNum, handle.id);
            return(ret);
        }
コード例 #2
0
        public static void Pulse(InterruptHandle handle)
        {
            if (handle.id == UIntPtr.Zero)
            {
                Tracing.Log(Tracing.Error,
                            "InterruptHandle.Wait(id={0:x8}) on bad handle",
                            handle.id);
                return;
            }
            IoIrq irq = HandleTable.GetHandle(handle.id) as IoIrq;

            irq.Pulse();
            Tracing.Log(Tracing.Debug, "InterruptHandle.Pulse(id={0:x8})",
                        handle.id);
        }
コード例 #3
0
        public static bool Dispose(InterruptHandle handle)
        {
            Tracing.Log(Tracing.Debug, "InterruptHandle.Dispose(id={0:x8})",
                        handle.id);

            bool ret = false;

            if (handle.id != UIntPtr.Zero)
            {
                //
                // Releasing the handle will allow the IoIrq event to be
                // garbage-collected.
                //
                IoIrq irq = HandleTable.GetHandle(handle.id) as IoIrq;
                ret = irq.ReleaseInterrupt();
                Thread.CurrentProcess.ReleaseHandle(handle.id);
            }
            return(ret);
        }
コード例 #4
0
        public static bool Ack(InterruptHandle handle)
        {
            if (handle.id == UIntPtr.Zero)
            {
                Tracing.Log(Tracing.Error,
                            "InterruptHandle.Ack(id={0:x8}) on bad handle",
                            handle.id);
                return(false);
            }

            //
            // Convert the handle to an auto-reset event; set the event.
            //
            IoIrq irq = HandleTable.GetHandle(handle.id) as IoIrq;
            bool  ret = irq.AckInterrupt();

            Tracing.Log(Tracing.Debug, "InterruptHandle.Ack(id={0:x8})", handle.id);
            return(ret);
        }
コード例 #5
0
        public static bool Wait(InterruptHandle handle)
        {
            if (handle.id == UIntPtr.Zero)
            {
                Tracing.Log(Tracing.Error,
                            "InterruptHandle.Wait(id={0:x8}) on bad handle",
                            handle.id);
                return(false);
            }

            //
            // Convert the handle to a IoIrq and wait on it.
            //
            IoIrq irq = HandleTable.GetHandle(handle.id) as IoIrq;
            bool  ret = irq.WaitForInterrupt();

            Tracing.Log(Tracing.Debug, "InterruptHandle.Wait(id={0:x8})", handle.id);

            return(ret);
        }
コード例 #6
0
ファイル: Cpu.cs プロジェクト: vmkc/research-environment
        public unsafe void DispatchInterrupt(InterruptContext *context)
        {
            Processor p         = Processor.CurrentProcessor;
            int       interrupt = context->ExceptionId;

            // Indicate that we are in an interrupt context.
            Thread target  = null;
            Thread current = Processor.GetCurrentThread();

            Kernel.Waypoint(801);

            // Don't generate loads of output for debugger-related interrupts
#if DEBUG_INTERRUPTS
            DebugStub.WriteLine("Int{0:x2}", __arglist(interrupt));
            context->Display();
#endif

            if (Processor.IsSamplingEnabled)
            {
                if (p.nextSampleIdle == false)
                {
                    p.Profiler.LogStackTrace(context->InstructionPointer,
                                             context->StackPointer);
                }
                p.nextSampleIdle = false;
            }

            if (halted)
            {
                p.clock.CpuResumeFromHaltEvent();
                halted = false;
            }

            unchecked {
                if (interrupt != p.clockInterrupt &&
                    interrupt != p.timerInterrupt)
                {
                    // We don't log the clockInterrupt because of all the spew.
                    Tracing.Log(Tracing.Debug, "Interrupt 0x{0:x}, count={1:x}, eip={2:x} [CC={3:x8}]",
                                (UIntPtr)(uint)interrupt,
                                (UIntPtr)p.interruptCounts[interrupt],
                                (UIntPtr)context->InstructionPointer,
                                (UIntPtr)(uint)Processor.CycleCount);
                }
            }

            Monitoring.Log(Monitoring.Provider.Processor,
                           (ushort)ProcessorEvent.Interrupt, 0,
                           (uint)interrupt, 0, 0, 0, 0);

            if (interrupt == Kernel.HalIpiInterrupt)
            {
#if DEBUG_IPI
                DebugStub.WriteLine("IPI received 0x{0:x2} on processor {1}",
                                    __arglist(interrupt, p.Id));
#endif // DEBUG_DISPATCH_TIMER
                Platform.ClearFixedIPI(interrupt);
                //p.dispatcher.HandlePreemptionReschedule();
            }
            else if (interrupt == p.timerInterrupt)
            {
                // Polling on every timer interrupt is EXCEEDINGLY costly
                p.timer.ClearInterrupt();
                p.dispatcher.HandlePreemptionReschedule(p.timer);
            }
            else if (interrupt == p.clockInterrupt)
            {
                p.clock.ClearInterrupt();
#if DEBUG
                // Check for a debug break.
                if (DebugStub.PollForBreak())
                {
                    DebugStub.WriteLine("Debugger ctrl-break after interrupt 0x{0:x2}",
                                        __arglist(interrupt));
                    DebugStub.Break();
                }
#endif // DEBUG
            }
#if ISA_IX
            else if (interrupt == EVectors.GCSynchronization)
            {
                Platform.ClearFixedIPI(interrupt);

                MpExecution.GCSynchronizationInterrupt();
            }
            else if (interrupt == EVectors.SpuriousInterrupt)
            {
                // FIXME: identify the source of these isolated interrupts after the
                // warmboot. Ignore them for now.
                DebugStub.WriteLine("Spurious interrupt");
            }
#endif // ISA_IX
            else
            {
                if (!Platform.InternalInterrupt((byte)interrupt))
                {
                    HalPic pic = p.GetPic();

                    DebugStub.Assert(pic != null);

                    pic.ClearInterrupt((byte)interrupt);
                    IoIrq.SignalInterrupt(pic.InterruptToIrq((byte)interrupt));

#if DEBUG_DISPATCH_IO
                    DebugStub.WriteLine("++DispatchInterruptEvent Irq={0:x2}, Thread={1:x8}",
                                        __arglist(pic.InterruptToIrq((byte)interrupt),
                                                  Kernel.AddressOf(target)));
#endif // DEBUG_DISPATCH_IO

                    p.dispatcher.HandleIOReschedule();
                }
                else
                {
                    // Potentially missed interrupt
                    DebugStub.Break();
                }
            }

#if DEBUG_INTERRUPTS
            DebugStub.WriteLine("(2nd)Int{0:x2}", __arglist(interrupt));
            context->Display();
            if (!Processor.InterruptsDisabled())
            {
                DebugStub.WriteLine("        interrupts enabled!!!!!!!");
                DebugStub.Break();
            }
#if DEBUG_DEEPER
            DebugStub.WriteLine("Int{0:x2}", __arglist(interrupt));
            Thread.DisplayAbbrev(ref context, " int end");
#endif
#endif

            // Now swap in the resulting current thread. (Note that this call will not return.)
            Isa.GetCurrentThread()->spill.Resume();
        }