Programmable Interrupt Controller (PIC)
예제 #1
0
        public static void Setup()
        {
            // At this stage, allocating memory does not work, so you are only allowed to use ValueTypes or static classes.
            IDT.SetInterruptHandler(null);
            Panic.Setup();
            Debugger.Setup(Serial.COM1);

            // Initialize interrupts
            PIC.Setup();
            IDT.Setup();

            // Initializing the memory management
            Multiboot.Setup();
            GDT.Setup();
            PageFrameAllocator.Setup();
            PageTable.Setup();
            VirtualPageAllocator.Setup();
            GC.Setup();

            // At this point we can use objects
            Scheduler.Setup();
            SmbiosManager.Setup();
            ConsoleManager.Setup();
            Internal.Setup();
        }
예제 #2
0
        public static void Setup()
        {
            // Initialize GDT before IDT, because IDT Entries requires a valid Segment Selector
            Multiboot.Setup();
            GDT.Setup();

            // At this stage, allocating memory does not work, so you are only allowed to use ValueTypes or static classes.
            IDT.SetInterruptHandler(null);
            Panic.Setup();

            // Initialize interrupts
            PIC.Setup();
            IDT.Setup();

            // Initializing the memory management
            PageFrameAllocator.Setup();
            PageTable.Setup();
            VirtualPageAllocator.Setup();
            GC.Setup();

            // At this point we can use objects
            Scheduler.Setup();
            SmbiosManager.Setup();
            ConsoleManager.Setup();

            Logger.Log("Kernel initialized");
        }
예제 #3
0
        public static void Setup()
        {
            // Initialize GDT before IDT, because IDT Entries requies a valid Segment Selector
            // This never happend before, because on fast computers GDT.Setup() was called
            // before a Interrupt,for example clock, got triggered.
            Multiboot.Setup();
            GDT.Setup();

            // At this stage, allocating memory does not work, so you are only allowed to use ValueTypes or static classes.
            IDT.SetInterruptHandler(null);
            Panic.Setup();
            Debugger.Setup(Serial.COM1);

            // Initialize interrupts
            PIC.Setup();
            IDT.Setup();

            // Initializing the memory management
            PageFrameAllocator.Setup();
            PageTable.Setup();
            VirtualPageAllocator.Setup();
            GC.Setup();

            // At this point we can use objects
            Scheduler.Setup();
            SmbiosManager.Setup();
            ConsoleManager.Setup();
            Internal.Setup();
        }
예제 #4
0
        private static void SwitchToThread(uint threadID)
        {
            var thread = Threads[threadID];

            //Assert.True(thread != null, "invalid thread id");

            thread.Ticks++;

            SetThreadID(threadID);

            PIC.SendEndOfInterrupt(ClockIRQ);

            Native.InterruptReturn((uint)thread.StackStatePointer.ToInt32());
        }
예제 #5
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="stackStatePointer">The stack state pointer.</param>
        private unsafe static void ProcessInterrupt(uint stackStatePointer)
        {
            //KernelMessage.WriteLine("Interrupt occured");

            var stack = (IDTStack *)stackStatePointer;
            var irq   = stack->Interrupt;
            var info  = IDTManager.handlers[irq];

            IDTManager.RaisedCount++;

            if (info.CountStatistcs)
            {
                IDTManager.RaisedCountCustom++;
            }
            if (info.Trace)
            {
                KernelMessage.WriteLine("Interrupt: {0}", irq);
            }

            var col = Screen.column;
            var row = Screen.row;

            Screen.column = 0;
            Screen.Goto(2, 35);
            Screen.Write("Interrupts: ");
            Screen.Write(IDTManager.RaisedCount);
            Screen.Goto(3, 35);
            Screen.Write("IntNoClock: ");
            Screen.Write(IDTManager.RaisedCountCustom);
            Screen.row    = row;
            Screen.column = col;

            if (irq < 0 || irq > 255)
            {
                Panic.Error("Invalid Interrupt");
            }

            if (info.Handler == null)
            {
                //Panic.Error("Handlr is null");
            }
            else
            {
            }

            info.Handler(stack);

            PIC.SendEndOfInterrupt(irq);
        }
예제 #6
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="edi">The edi.</param>
        /// <param name="esi">The esi.</param>
        /// <param name="ebp">The ebp.</param>
        /// <param name="esp">The esp.</param>
        /// <param name="ebx">The ebx.</param>
        /// <param name="edx">The edx.</param>
        /// <param name="ecx">The ecx.</param>
        /// <param name="eax">The eax.</param>
        /// <param name="interrupt">The interrupt.</param>
        /// <param name="errorcode">The errorcode.</param>
        private static void InterruptHandler(uint edi, uint esi, uint ebp, uint esp, uint ebx, uint edx, uint ecx, uint eax, uint interrupt, uint errorCode)
        {
            uint c   = Screen.Column;
            uint r   = Screen.Row;
            byte col = Screen.Color;

            Screen.Column = 30;
            Screen.Row    = 0;
            Screen.Color  = 3;

            _counter++;
            Screen.Write(_counter, 10, 8);
            Screen.Write(':');
            Screen.Write(interrupt, 16, 2);

            if (interrupt == 14)
            {
                // Page Fault!
                PageFaultHandler.Fault(errorCode);
            }
            if (interrupt == 0x20)
            {
                // Timer Interrupt! Switch Tasks!
            }
            else
            {
                Screen.Write(':');
                Screen.Write(_counter, 10, 8);
                Screen.Write(':');
                Screen.Write(interrupt, 16, 2);
                Screen.Write('-');
                Screen.Write(errorCode, 16, 2);

                if (interrupt == 0x21)
                {
                    byte scancode = Keyboard.ReadScanCode();
                    Screen.Write('-');
                    Screen.Write(scancode, 16, 2);
                }
            }

            Screen.Column = c;
            Screen.Row    = r;
            Screen.Color  = col;

            PIC.SendEndOfInterrupt((byte)interrupt);
        }
예제 #7
0
        /// <summary>
        /// Switches the specified esp.
        /// </summary>
        /// <param name="nexttask">The nexttask.</param>
        public static void Switch(uint nexttask)
        {
            PIC.SendEndOfInterrupt(0x20);

            // Update current task
            currenttask = nexttask;

            // Get Stack Slot Location
            uint task = GetTaskLocation(currenttask);

            // Get Stack location
            uint esp = Native.Get32(task + Offset.ESP);

            // Switch task
            Native.SwitchTask(esp);

            // will never reach here
        }
예제 #8
0
 public static void Setup()
 {
     SmbiosManager.Setup();
     Screen.Clear();
     Screen.Color = 0x0E;
     Screen.Goto(24, 0);
     Screen.Write('1');
     Multiboot.Setup();
     Screen.Goto(24, 1);
     Screen.Write('2');
     PIC.Setup();
     Screen.Goto(24, 2);
     Screen.Write('3');
     GDT.Setup();
     Screen.Goto(24, 3);
     Screen.Write('4');
     IDT.Setup();
     Screen.Goto(24, 4);
     Screen.Write('5');
     PageFrameAllocator.Setup();
     Screen.Goto(24, 5);
     Screen.Write('6');
     PageTable.Setup();
     Screen.Goto(24, 6);
     Screen.Write('7');
     VirtualPageAllocator.Setup();
     Screen.Goto(24, 7);
     Screen.Write('8');
     Screen.Goto(24, 8);
     ProcessManager.Setup();
     Screen.Write('9');
     Screen.Goto(24, 9);
     TaskManager.Setup();
     Screen.Write('A');
     Screen.Goto(24, 10);
     SmbiosManager.Setup();
 }
예제 #9
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="stackStatePointer">The stack state pointer.</param>
        private unsafe static void ProcessInterrupt(uint stackStatePointer)
        {
            var stack = (IDTStack *)stackStatePointer;

            Debugger.Process(stack);

            switch (stack->Interrupt)
            {
            case 0:
                Error(stack, "Divide Error");
                break;

            case 4:
                Error(stack, "Arithmetic Overflow Exception");
                break;

            case 5:
                Error(stack, "Bound Check Error");
                break;

            case 6:
                Error(stack, "Invalid Opcode");
                break;

            case 7:
                Error(stack, "Co-processor Not Available");
                break;

            case 8:

                //TODO: Analyze the double fault
                Error(stack, "Double Fault");
                break;

            case 9:
                Error(stack, "Co-processor Segment Overrun");
                break;

            case 10:
                Error(stack, "Invalid TSS");
                break;

            case 11:
                Error(stack, "Segment Not Present");
                break;

            case 12:
                Error(stack, "Stack Exception");
                break;

            case 13:
                Error(stack, "General Protection Exception");
                break;

            case 14:

                // Check if Null Pointer Exception
                // Otherwise handle as Page Fault

                var cr2 = Native.GetCR2();

                if ((cr2 >> 5) < 0x1000)
                {
                    Error(stack, "Null Pointer Exception");
                }

                if (cr2 >= 0xF0000000u)
                {
                    Error(stack, "Invalid Access Above 0xF0000000");
                    break;
                }

                var physicalpage = PageFrameAllocator.Allocate();

                if (physicalpage == IntPtr.Zero)
                {
                    Error(stack, "Out of Memory");
                    break;
                }

                PageTable.MapVirtualAddressToPhysical(cr2, (uint)physicalpage.ToInt32());

                break;

            case 16:
                Error(stack, "Co-processor Error");
                break;

            case 19:
                Error(stack, "SIMD Floating-Point Exception");
                break;

            case Scheduler.ClockIRQ:
                Interrupt?.Invoke(stack->Interrupt, stack->ErrorCode);
                Scheduler.ClockInterrupt(new IntPtr(stackStatePointer));
                break;

            case Scheduler.ThreadTerminationSignalIRQ:
                Scheduler.TerminateCurrentThread();
                break;

            default:
            {
                Interrupt?.Invoke(stack->Interrupt, stack->ErrorCode);
                break;
            }
            }

            PIC.SendEndOfInterrupt(stack->Interrupt);
        }
예제 #10
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="stack">The stack.</param>
        private unsafe static void ProcessInterrupt(IDTStack *stack)
        {
            DebugClient.Process();

            switch (stack->Interrupt)
            {
            case 0:
                Error(stack->EBP, stack->EIP, "Divide Error");
                break;

            case 4:
                Error(stack->EBP, stack->EIP, "Arithmetic Overflow Exception");
                break;

            case 5:
                Error(stack->EBP, stack->EIP, "Bound Check Error");
                break;

            case 6:
                Error(stack->EBP, stack->EIP, "Invalid Opcode");
                break;

            case 7:
                Error(stack->EBP, stack->EIP, "Co-processor Not Available");
                break;

            case 8:

                //TODO: Analyze the double fault
                Error(stack->EBP, stack->EIP, "Double Fault");
                break;

            case 9:
                Error(stack->EBP, stack->EIP, "Co-processor Segment Overrun");
                break;

            case 10:
                Error(stack->EBP, stack->EIP, "Invalid TSS");
                break;

            case 11:
                Error(stack->EBP, stack->EIP, "Segment Not Present");
                break;

            case 12:
                Error(stack->EBP, stack->EIP, "Stack Exception");
                break;

            case 13:
                Error(stack->EBP, stack->EIP, "General Protection Exception");
                break;

            case 14:

                // Check if Null Pointer Exception
                // Otherwise handle as Page Fault

                var cr2 = Native.GetCR2() >> 5;
                if (cr2 < 0x1000)
                {
                    Error(stack->EBP, stack->EIP, "Null Pointer Exception");
                }

                //spinLock.Enter(ref taken);

                uint physicalpage = PageFrameAllocator.Allocate();

                if (physicalpage == 0x0)
                {
                    // Panic! Out of memory
                    Panic.SetStackPointer(stack->EBP, stack->EIP);
                    Panic.Error(cr2);
                }

                PageTable.MapVirtualAddressToPhysical(Native.GetCR2(), physicalpage);

                //spinLock.Exit();

                break;

            case 16:
                Error(stack->EBP, stack->EIP, "Co-processor Error");
                break;

            case 19:
                Error(stack->EBP, stack->EIP, "SIMD Floating-Point Exception");
                break;

            default:
                if (interruptHandler != null)
                {
                    interruptHandler(stack->Interrupt, stack->ErrorCode);
                }
                break;
            }

            PIC.SendEndOfInterrupt(stack->Interrupt);
        }
예제 #11
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="stack">The stack.</param>
        private unsafe static void ProcessInterrupt(IDTStack *stack)
        {
            Debugger.Process(stack);

            switch (stack->Interrupt)
            {
            case 0:
                Error(stack, "Divide Error");
                break;

            case 4:
                Error(stack, "Arithmetic Overflow Exception");
                break;

            case 5:
                Error(stack, "Bound Check Error");
                break;

            case 6:
                Error(stack, "Invalid Opcode");
                break;

            case 7:
                Error(stack, "Co-processor Not Available");
                break;

            case 8:

                //TODO: Analyze the double fault
                Error(stack, "Double Fault");
                break;

            case 9:
                Error(stack, "Co-processor Segment Overrun");
                break;

            case 10:
                Error(stack, "Invalid TSS");
                break;

            case 11:
                Error(stack, "Segment Not Present");
                break;

            case 12:
                Error(stack, "Stack Exception");
                break;

            case 13:
                Error(stack, "General Protection Exception");
                break;

            case 14:

                // Check if Null Pointer Exception
                // Otherwise handle as Page Fault

                var cr2 = Native.GetCR2();

                if ((cr2 >> 5) < 0x1000)
                {
                    Error(stack, "Null Pointer Exception");
                }

                uint physicalpage = PageFrameAllocator.Allocate();

                if (physicalpage == 0x0)
                {
                    Error(stack, "Out of Memory");
                }

                PageTable.MapVirtualAddressToPhysical(cr2, physicalpage);

                break;

            case 16:
                Error(stack, "Co-processor Error");
                break;

            case 19:
                Error(stack, "SIMD Floating-Point Exception");
                break;

            default:
                interruptHandler?.Invoke(stack->Interrupt, stack->ErrorCode);
                break;
            }

            PIC.SendEndOfInterrupt(stack->Interrupt);
        }
예제 #12
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="stack">The stack.</param>
        private unsafe static void ProcessInterrupt(IDTStack *stack)
        {
            DebugClient.Process();

            switch (stack->Interrupt)
            {
            case 0:
                Error(stack->EBP, stack->EIP, "Divide Error");
                break;

            case 4:
                Error(stack->EBP, stack->EIP, "Arithmetic Overflow Exception");
                break;

            case 5:
                Error(stack->EBP, stack->EIP, "Bound Check Error");
                break;

            case 6:
                Error(stack->EBP, stack->EIP, "Invalid Opcode");
                break;

            case 7:
                Error(stack->EBP, stack->EIP, "Coprocessor Not Available");
                break;

            case 8:

                //TODO: Analyze the double fault
                Error(stack->EBP, stack->EIP, "Double Fault");
                break;

            case 9:
                Error(stack->EBP, stack->EIP, "Coprocessor Segment Overrun");
                break;

            case 10:
                Error(stack->EBP, stack->EIP, "Invalid TSS");
                break;

            case 11:
                Error(stack->EBP, stack->EIP, "Segment Not Present");
                break;

            case 12:
                Error(stack->EBP, stack->EIP, "Stack Exception");
                break;

            case 13:
                Error(stack->EBP, stack->EIP, "General Protection Exception");
                break;

            case 14:

                // Page Fault!
                var cr2 = Native.GetCR2() >> 5;
                if (cr2 < 0x1000)
                {
                    Error(stack->EBP, stack->EIP, "Null Pointer Exception");
                    break;
                }

                //PageFaultHandler.Fault(errorCode);
                Panic.SetStackPointer(stack->EBP, stack->EIP);
                Panic.Error(cr2);
                break;

            case 16:
                Error(stack->EBP, stack->EIP, "Coprocessor Error");
                break;

            case 19:
                Error(stack->EBP, stack->EIP, "SIMD Floating-Point Exception");
                break;

            default:
                if (interruptHandler != null)
                {
                    interruptHandler(stack->Interrupt, stack->ErrorCode);
                }
                break;
            }

            PIC.SendEndOfInterrupt(stack->Interrupt);
        }
예제 #13
0
        /// <summary>
        /// Interrupts the handler.
        /// </summary>
        /// <param name="edi">The edi.</param>
        /// <param name="esi">The esi.</param>
        /// <param name="ebp">The ebp.</param>
        /// <param name="esp">The esp.</param>
        /// <param name="ebx">The ebx.</param>
        /// <param name="edx">The edx.</param>
        /// <param name="ecx">The ecx.</param>
        /// <param name="eax">The eax.</param>
        /// <param name="interrupt">The interrupt.</param>
        /// <param name="errorCode">The error code.</param>
        private static void ProcessInterrupt(uint edi, uint esi, uint ebp, uint esp, uint ebx, uint edx, uint ecx, uint eax, uint interrupt, uint errorCode, uint eip, uint cs, uint eflags)
        {
            DebugClient.Process();

            switch (interrupt)
            {
            case 0:
                Error(ebp, eip, "Divide Error");
                break;

            case 4:
                Error(ebp, eip, "Arithmetic Overflow Exception");
                break;

            case 5:
                Error(ebp, eip, "Bound Check Error");
                break;

            case 6:
                Error(ebp, eip, "Invalid Opcode");
                break;

            case 7:
                Error(ebp, eip, "Coprocessor Not Available");
                break;

            case 8:
                //TODO: Analyze the double fault
                Error(ebp, eip, "Double Fault");
                break;

            case 9:
                Error(ebp, eip, "Coprocessor Segment Overrun");
                break;

            case 10:
                Error(ebp, eip, "Invalid TSS");
                break;

            case 11:
                Error(ebp, eip, "Segment Not Present");
                break;

            case 12:
                Error(ebp, eip, "Stack Exception");
                break;

            case 13:
                Error(ebp, eip, "General Protection Exception");
                break;

            case 14:
                // Page Fault!
                var cr2 = Native.GetCR2() >> 5;
                if (cr2 < 0x1000)
                {
                    Error(ebp, eip, "Null Pointer Exception");
                    break;
                }

                PageFaultHandler.Fault(errorCode);
                break;

            case 16:
                Error(ebp, eip, "Coprocessor Error");
                break;

            case 19:
                Error(ebp, eip, "SIMD Floating-Point Exception");
                break;

            default:
                if (interruptHandler != null)
                {
                    interruptHandler(interrupt, errorCode);
                }
                break;
            }

            PIC.SendEndOfInterrupt(interrupt);
        }