mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactored interrupt system and got rid of old not-mine code.
This commit is contained in:
parent
4e05eb33d8
commit
3859e1f566
11 changed files with 162 additions and 153 deletions
|
@ -47,7 +47,7 @@ CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib
|
||||||
OBJS=$(CPUOBJS) \
|
OBJS=$(CPUOBJS) \
|
||||||
kernel.o \
|
kernel.o \
|
||||||
descriptor_tables.o \
|
descriptor_tables.o \
|
||||||
isr.o \
|
interrupt.o \
|
||||||
time.o \
|
time.o \
|
||||||
log.o \
|
log.o \
|
||||||
panic.o \
|
panic.o \
|
||||||
|
|
|
@ -23,10 +23,8 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "iirqhandler.h"
|
|
||||||
#include <libmaxsi/memory.h>
|
#include <libmaxsi/memory.h>
|
||||||
#include "descriptor_tables.h"
|
#include "descriptor_tables.h"
|
||||||
#include "isr.h"
|
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
|
|
||||||
using namespace Maxsi;
|
using namespace Maxsi;
|
||||||
|
|
123
sortix/interrupt.cpp
Normal file
123
sortix/interrupt.cpp
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,21 +17,39 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
iirqhandler.h
|
interrupt.h
|
||||||
An interface for classes able to handle IRQs.
|
High level interrupt service routines and interrupt request handlers.
|
||||||
|
|
||||||
TODO: This is stupid. Get rid of this header and put the declaration
|
|
||||||
someplace more intelligent.
|
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef SORTIX_IIRQHANDLER_H
|
#ifndef SORTIX_ISR_H
|
||||||
#define SORTIX_IIRQHANDLER_H
|
#define SORTIX_ISR_H
|
||||||
|
|
||||||
namespace Sortix
|
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
|
#endif
|
||||||
|
|
100
sortix/isr.cpp
100
sortix/isr.cpp
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
26
sortix/isr.h
26
sortix/isr.h
|
@ -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);
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "descriptor_tables.h"
|
#include "descriptor_tables.h"
|
||||||
#include "iirqhandler.h"
|
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
|
|
|
@ -25,11 +25,10 @@
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <libmaxsi/memory.h>
|
#include <libmaxsi/memory.h>
|
||||||
#include <libmaxsi/keyboard.h>
|
#include <libmaxsi/keyboard.h>
|
||||||
#include "iirqhandler.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "isr.h"
|
#include "interrupt.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
|
||||||
|
@ -634,7 +633,7 @@ namespace Sortix
|
||||||
LEDs = 0;
|
LEDs = 0;
|
||||||
|
|
||||||
// Register our keystroke callback.
|
// Register our keystroke callback.
|
||||||
register_interrupt_handler(IRQ1, OnIRQ1);
|
Interrupt::RegisterHandler(Interrupt::IRQ1, OnIRQ1);
|
||||||
|
|
||||||
// If any scancodes were already pending, our interrupt handler
|
// If any scancodes were already pending, our interrupt handler
|
||||||
// will never be called. Let's just discard anything pending.
|
// will never be called. Let's just discard anything pending.
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "iirqhandler.h"
|
#include "interrupt.h"
|
||||||
#include "isr.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
@ -69,7 +68,7 @@ namespace Sortix
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
register_interrupt_handler(0x80, &OnCall);
|
Interrupt::RegisterHandler(0x80, &OnCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnCall(CPU::InterruptRegisters* registers)
|
void OnCall(CPU::InterruptRegisters* registers)
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "iirqhandler.h"
|
#include "interrupt.h"
|
||||||
#include "isr.h"
|
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
@ -81,8 +80,8 @@ namespace Sortix
|
||||||
Miliseconds = 0;
|
Miliseconds = 0;
|
||||||
|
|
||||||
// First, register our timer callback.
|
// First, register our timer callback.
|
||||||
register_interrupt_handler(IRQ0, &OnIRQ0);
|
Interrupt::RegisterHandler(Interrupt::IRQ0, &OnIRQ0);
|
||||||
register_interrupt_handler(177, &OnInt177);
|
Interrupt::RegisterHandler(177, &OnInt177);
|
||||||
|
|
||||||
didUglyIRQ0Hack = false;
|
didUglyIRQ0Hack = false;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ IRQ 14, 46
|
||||||
IRQ 15, 47
|
IRQ 15, 47
|
||||||
|
|
||||||
; In isr.c
|
; In isr.c
|
||||||
extern isr_handler
|
extern ISRHandler
|
||||||
|
|
||||||
; This is our common ISR stub. It saves the processor state, sets
|
; This is our common ISR stub. It saves the processor state, sets
|
||||||
; up for kernel mode segments, calls the C-level fault handler,
|
; up for kernel mode segments, calls the C-level fault handler,
|
||||||
|
@ -108,7 +108,7 @@ isr_common_stub:
|
||||||
|
|
||||||
push esp
|
push esp
|
||||||
|
|
||||||
call isr_handler
|
call ISRHandler
|
||||||
|
|
||||||
add esp, 8
|
add esp, 8
|
||||||
pop ebx ; reload the original data segment descriptor
|
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
|
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
; In isr.c
|
; In isr.c
|
||||||
extern irq_handler
|
extern IRQHandler
|
||||||
|
|
||||||
; This is our common IRQ stub. It saves the processor state, sets
|
; This is our common IRQ stub. It saves the processor state, sets
|
||||||
; up for kernel mode segments, calls the C-level fault handler,
|
; up for kernel mode segments, calls the C-level fault handler,
|
||||||
|
@ -144,7 +144,7 @@ irq_common_stub:
|
||||||
|
|
||||||
push esp
|
push esp
|
||||||
|
|
||||||
call irq_handler
|
call IRQHandler
|
||||||
|
|
||||||
add esp, 8
|
add esp, 8
|
||||||
pop ebx ; reload the original data segment descriptor
|
pop ebx ; reload the original data segment descriptor
|
||||||
|
|
Loading…
Reference in a new issue