Refactored interrupt system and got rid of old not-mine code.

This commit is contained in:
Jonas 'Sortie' Termansen 2011-09-07 18:45:07 +02:00
parent 4e05eb33d8
commit 3859e1f566
11 changed files with 162 additions and 153 deletions

View File

@ -47,7 +47,7 @@ CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib
OBJS=$(CPUOBJS) \
kernel.o \
descriptor_tables.o \
isr.o \
interrupt.o \
time.o \
log.o \
panic.o \

View File

@ -23,10 +23,8 @@
******************************************************************************/
#include "platform.h"
#include "iirqhandler.h"
#include <libmaxsi/memory.h>
#include "descriptor_tables.h"
#include "isr.h"
#include "panic.h"
using namespace Maxsi;

123
sortix/interrupt.cpp Normal file
View File

@ -0,0 +1,123 @@
/******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with Sortix. If not, see <http://www.gnu.org/licenses/>.
interrupt.cpp
High level interrupt service routines and interrupt request handlers.
******************************************************************************/
#include "platform.h"
#include "log.h"
#include "interrupt.h"
#include "panic.h"
#include "process.h" // Hack for SIGSEGV
#include "sound.h" // Hack for SIGSEGV
namespace Sortix
{
namespace Interrupt
{
size_t numknownexceptions = 19;
const char* exceptions[] =
{ "Divide by zero", "Debug", "Non maskable interrupt", "Breakpoint",
"Into detected overflow", "Out of bounds", "Invalid opcode",
"No coprocessor", "Double fault", "Coprocessor segment overrun",
"Bad TSS", "Segment not present", "Stack fault",
"General protection fault", "Page fault", "Unknown interrupt",
"Coprocessor fault", "Alignment check", "Machine check" };
Handler interrupthandlers[256];
void RegisterHandler(uint8_t n, Interrupt::Handler handler)
{
interrupthandlers[n] = handler;
}
// This gets called from our ASM interrupt handler stub.
extern "C" void ISRHandler(Sortix::CPU::InterruptRegisters* regs)
{
#ifdef PLATFORM_X86
if ( regs->int_no < 32 )
{
const char* message = ( regs->int_no < numknownexceptions )
? exceptions[regs->int_no] : "Unknown";
// Halt and catch fire if we are the kernel.
if ( (regs->cs & (0x4-1)) == 0 )
{
PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx "
"(cr2=0x%p, err_code=0x%p)", regs->int_no, message,
regs->eip, regs->cr2, regs->err_code);
}
Log::Print("The current program has crashed and was terminated:\n");
Log::PrintF("%s exception at eip=0x%zx (cr2=0x%p, err_code=0x%p)\n",
message, regs->eip, regs->cr2, regs->err_code);
Sound::Mute();
const char* programname = "sh";
regs->ebx = (uint32_t) programname;
SysExecute(regs);
return;
}
if ( interrupthandlers[regs->int_no] != NULL )
{
interrupthandlers[regs->int_no](regs);
}
#else
#warning "ISR handlers are not supported on this arch"
while(true);
#endif
}
// This gets called from our ASM interrupt handler stub.
extern "C" void IRQHandler(Sortix::CPU::InterruptRegisters* regs)
{
#ifdef PLATFORM_X86
// TODO! IRQ 7 and 15 might be spurious and might need to be ignored.
// See http://wiki.osdev.org/PIC for details (section Spurious IRQs).
if ( regs->int_no == 32 + 7 || regs->int_no == 32 + 15 ) { return; }
if ( regs->int_no < 32 || 48 < regs->int_no )
{
PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!",
regs->eax, regs->int_no, regs->err_code, regs->eip);
}
// Send an EOI (end of interrupt) signal to the PICs.
// Send reset signal to slave if this interrupt involved the slave.
if (regs->int_no >= 40) { X86::OutPortB(0xA0, 0x20); }
// Send reset signal to master.
X86::OutPortB(0x20, 0x20);
if ( interrupthandlers[regs->int_no] != NULL )
{
interrupthandlers[regs->int_no](regs);
}
#else
#warning "IRQ handlers are not supported on this arch"
while(true);
#endif
}
}
}

View File

@ -17,21 +17,39 @@
You should have received a copy of the GNU General Public License along
with Sortix. If not, see <http://www.gnu.org/licenses/>.
iirqhandler.h
An interface for classes able to handle IRQs.
TODO: This is stupid. Get rid of this header and put the declaration
someplace more intelligent.
interrupt.h
High level interrupt service routines and interrupt request handlers.
******************************************************************************/
#ifndef SORTIX_IIRQHANDLER_H
#define SORTIX_IIRQHANDLER_H
#ifndef SORTIX_ISR_H
#define SORTIX_ISR_H
namespace Sortix
{
typedef void (*InterruptHandler)(CPU::InterruptRegisters* Registers);
namespace Interrupt
{
const unsigned IRQ0 = 32;
const unsigned IRQ1 = 33;
const unsigned IRQ2 = 34;
const unsigned IRQ3 = 35;
const unsigned IRQ4 = 36;
const unsigned IRQ5 = 37;
const unsigned IRQ6 = 38;
const unsigned IRQ7 = 39;
const unsigned IRQ8 = 30;
const unsigned IRQ9 = 41;
const unsigned IRQ10 = 42;
const unsigned IRQ11 = 43;
const unsigned IRQ12 = 44;
const unsigned IRQ13 = 45;
const unsigned IRQ14 = 46;
const unsigned IRQ15 = 47;
typedef void (*Handler)(CPU::InterruptRegisters* Registers);
void RegisterHandler(uint8_t n, Handler handler);
}
}
#endif

View File

@ -1,100 +0,0 @@
//
// isr.c -- High level interrupt service routines and interrupt request handlers.
// Part of this code is modified from Bran's kernel development tutorials.
// Rewritten for JamesM's kernel development tutorials.
//
#include "platform.h"
#include "iirqhandler.h"
#include "log.h"
#include "isr.h"
#include "panic.h"
#include "process.h" // Hack for SIGSEGV
#include "sound.h" // Hack for SIGSEGV
using namespace Sortix;
size_t numknownexceptions = 19;
const char* exceptions[] = { "Divide by zero", "Debug", "Non maskable interrupt", "Breakpoint",
"Into detected overflow", "Out of bounds", "Invalid opcode",
"No coprocessor", "Double fault", "Coprocessor segment overrun",
"Bad TSS", "Segment not present", "Stack fault",
"General protection fault", "Page fault", "Unknown interrupt",
"Coprocessor fault", "Alignment check", "Machine check" };
Sortix::InterruptHandler interrupt_handlers[256];
void register_interrupt_handler(uint8_t n, Sortix::InterruptHandler handler)
{
interrupt_handlers[n] = handler;
}
// This gets called from our ASM interrupt handler stub.
extern "C" void isr_handler(Sortix::CPU::InterruptRegisters* Regs)
{
#ifdef PLATFORM_X86
if ( Regs->int_no < 32 )
{
const char* message = ( Regs->int_no < numknownexceptions )
? exceptions[Regs->int_no] : "Unknown";
// Halt and catch fire if we are the kernel.
if ( (Regs->cs & (0x4-1)) == 0 )
{
PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx "
"(cr2=0x%p, err_code=0x%p)", Regs->int_no, message,
Regs->eip, Regs->cr2, Regs->err_code);
}
Log::Print("The current program has crashed and was terminated:\n");
Log::PrintF("%s exception at eip=0x%zx (cr2=0x%p, err_code=0x%p)\n",
message, Regs->eip, Regs->cr2, Regs->err_code);
Sound::Mute();
const char* programname = "sh";
Regs->ebx = (uint32_t) programname;
SysExecute(Regs);
return;
}
if ( interrupt_handlers[Regs->int_no] != NULL )
{
interrupt_handlers[Regs->int_no](Regs);
}
#else
#warning "ISR handlers are not supported on this arch"
while(true);
#endif
}
// This gets called from our ASM interrupt handler stub.
extern "C" void irq_handler(Sortix::CPU::InterruptRegisters* Regs)
{
#ifdef PLATFORM_X86
if ( Regs->int_no != 32 && Regs->int_no != 33 )
{
//Sortix::Log::PrintF("IRQ eax=%u, int_no=%u, err_code=%u, eip=0x%x!\n", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip);
}
// TODO! IRQ 7 and 15 might be spurious and might need to be ignored.
// See http://wiki.osdev.org/PIC for details (section Spurious IRQs).
if ( Regs->int_no == 32 + 7 || Regs->int_no == 32 + 15 ) { return; }
if ( Regs->int_no < 32 || 48 < Regs->int_no ) { Sortix::PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); }
// Send an EOI (end of interrupt) signal to the PICs.
if (Regs->int_no >= 40) { Sortix::X86::OutPortB(0xA0, 0x20); } // Send reset signal to slave if this interrupt involved the slave.
Sortix::X86::OutPortB(0x20, 0x20); // Send reset signal to master.
if ( interrupt_handlers[Regs->int_no] != NULL )
{
interrupt_handlers[Regs->int_no](Regs);
}
#else
#warning "IRQ handlers are not supported on this arch"
while(true);
#endif
}

View File

@ -1,26 +0,0 @@
//
// isr.h -- Interface and structures for high level interrupt service routines.
// Part of this code is modified from Bran's kernel development tutorials.
// Rewritten for JamesM's kernel development tutorials.
//
// A few defines to make life a little easier
#define IRQ0 32
#define IRQ1 33
#define IRQ2 34
#define IRQ3 35
#define IRQ4 36
#define IRQ5 37
#define IRQ6 38
#define IRQ7 39
#define IRQ8 40
#define IRQ9 41
#define IRQ10 42
#define IRQ11 43
#define IRQ12 44
#define IRQ13 45
#define IRQ14 46
#define IRQ15 47
void register_interrupt_handler(uint8_t n, Sortix::InterruptHandler handler);

View File

@ -29,7 +29,6 @@
#include "log.h"
#include "panic.h"
#include "descriptor_tables.h"
#include "iirqhandler.h"
#include "time.h"
#include "keyboard.h"
#include "multiboot.h"

View File

@ -25,11 +25,10 @@
#include "platform.h"
#include <libmaxsi/memory.h>
#include <libmaxsi/keyboard.h>
#include "iirqhandler.h"
#include "log.h"
#include "panic.h"
#include "keyboard.h"
#include "isr.h"
#include "interrupt.h"
#include "process.h"
#include "scheduler.h"
@ -634,7 +633,7 @@ namespace Sortix
LEDs = 0;
// Register our keystroke callback.
register_interrupt_handler(IRQ1, OnIRQ1);
Interrupt::RegisterHandler(Interrupt::IRQ1, OnIRQ1);
// If any scancodes were already pending, our interrupt handler
// will never be called. Let's just discard anything pending.

View File

@ -25,8 +25,7 @@
#include "platform.h"
#include "syscall.h"
#include "scheduler.h"
#include "iirqhandler.h"
#include "isr.h"
#include "interrupt.h"
#include "log.h"
#include "panic.h"
#include "vga.h"
@ -69,7 +68,7 @@ namespace Sortix
void Init()
{
register_interrupt_handler(0x80, &OnCall);
Interrupt::RegisterHandler(0x80, &OnCall);
}
void OnCall(CPU::InterruptRegisters* registers)

View File

@ -25,8 +25,7 @@
#include "platform.h"
#include "time.h"
#include "iirqhandler.h"
#include "isr.h"
#include "interrupt.h"
#include "scheduler.h"
#include "log.h"
@ -81,8 +80,8 @@ namespace Sortix
Miliseconds = 0;
// First, register our timer callback.
register_interrupt_handler(IRQ0, &OnIRQ0);
register_interrupt_handler(177, &OnInt177);
Interrupt::RegisterHandler(Interrupt::IRQ0, &OnIRQ0);
Interrupt::RegisterHandler(177, &OnInt177);
didUglyIRQ0Hack = false;

View File

@ -87,7 +87,7 @@ IRQ 14, 46
IRQ 15, 47
; In isr.c
extern isr_handler
extern ISRHandler
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
@ -108,7 +108,7 @@ isr_common_stub:
push esp
call isr_handler
call ISRHandler
add esp, 8
pop ebx ; reload the original data segment descriptor
@ -123,7 +123,7 @@ isr_common_stub:
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
; In isr.c
extern irq_handler
extern IRQHandler
; This is our common IRQ stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
@ -144,7 +144,7 @@ irq_common_stub:
push esp
call irq_handler
call IRQHandler
add esp, 8
pop ebx ; reload the original data segment descriptor