implement exercise 04 interrupts
This commit is contained in:
@ -12,43 +12,41 @@
|
||||
#ifndef __CPU_include__
|
||||
#define __CPU_include__
|
||||
|
||||
|
||||
class CPU {
|
||||
|
||||
|
||||
private:
|
||||
CPU(const CPU ©); // Verhindere Kopieren
|
||||
CPU(const CPU& copy); // Verhindere Kopieren
|
||||
|
||||
public:
|
||||
CPU() {}
|
||||
|
||||
// Erlauben von (Hardware-)Interrupts
|
||||
inline void enable_int () {
|
||||
asm volatile ( "sti" );
|
||||
inline void enable_int() {
|
||||
asm volatile("sti");
|
||||
}
|
||||
|
||||
|
||||
// Interrupts werden ignoriert/verboten
|
||||
inline void disable_int () {
|
||||
asm volatile ( "cli" );
|
||||
inline void disable_int() {
|
||||
asm volatile("cli");
|
||||
}
|
||||
|
||||
|
||||
// Prozessor bis zum naechsten Interrupt anhalten
|
||||
inline void idle () {
|
||||
asm volatile ( "sti;"
|
||||
"hlt"
|
||||
);
|
||||
inline void idle() {
|
||||
asm volatile("sti;"
|
||||
"hlt");
|
||||
}
|
||||
|
||||
|
||||
// Prozessor anhalten
|
||||
inline void halt () {
|
||||
asm volatile ( "cli;"
|
||||
"hlt"
|
||||
);
|
||||
inline void halt() {
|
||||
asm volatile("cli;"
|
||||
"hlt");
|
||||
}
|
||||
|
||||
|
||||
// Time-Stamp-Counter auslesen
|
||||
inline unsigned long long int rdtsc() {
|
||||
unsigned long long int ret;
|
||||
asm volatile ( "rdtsc" : "=A"(ret) );
|
||||
unsigned long long int ret;
|
||||
asm volatile("rdtsc"
|
||||
: "=A"(ret));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
@ -10,13 +10,11 @@
|
||||
* *
|
||||
* Autor: Michael Schoettner, 31.8.2016 *
|
||||
*****************************************************************************/
|
||||
#include "kernel/interrupts/IntDispatcher.h"
|
||||
#include "kernel/CPU.h"
|
||||
#include "kernel/Globals.h"
|
||||
#include "kernel/interrupts/IntDispatcher.h"
|
||||
|
||||
|
||||
extern "C" void int_disp (unsigned int slot);
|
||||
|
||||
extern "C" void int_disp(unsigned int slot);
|
||||
|
||||
/*****************************************************************************
|
||||
* Prozedur: int_disp *
|
||||
@ -30,26 +28,25 @@ extern "C" void int_disp (unsigned int slot);
|
||||
* Parameter: *
|
||||
* vector: Vektor-Nummer der Unterbrechung *
|
||||
*****************************************************************************/
|
||||
void int_disp (unsigned int vector) {
|
||||
void int_disp(unsigned int vector) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
kout << "Ein Interrupt ist aufgetreten" << slot << endl;
|
||||
|
||||
// kout << "Ein Interrupt ist aufgetreten (vector: " << vector << ")" << endl;
|
||||
intdis.report(vector);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Konstruktor: IntDispatcher::IntDispatcher *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Initialisierung der ISR map mit einer Default-ISR. *
|
||||
*****************************************************************************/
|
||||
IntDispatcher::IntDispatcher () {
|
||||
for (unsigned int slot=0; slot<size; slot++)
|
||||
IntDispatcher::IntDispatcher() {
|
||||
for (unsigned int slot = 0; slot < size; slot++) {
|
||||
map[slot] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: IntDispatcher::assign *
|
||||
*---------------------------------------------------------------------------*
|
||||
@ -61,12 +58,20 @@ IntDispatcher::IntDispatcher () {
|
||||
* *
|
||||
* Rueckgabewert: 0 = Erfolg, -1 = Fehler *
|
||||
*****************************************************************************/
|
||||
int IntDispatcher::assign (unsigned int vector, ISR& isr) {
|
||||
int IntDispatcher::assign(unsigned int vector, ISR& isr) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
}
|
||||
if (vector >= this->size) {
|
||||
kout << "Invalid vector number when assigning" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->map[vector] = &isr;
|
||||
kout << "Registered ISR for vector " << dec << vector << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: IntDispatcher::report *
|
||||
@ -78,8 +83,22 @@ int IntDispatcher::assign (unsigned int vector, ISR& isr) {
|
||||
* *
|
||||
* Rueckgabewert: 0 = ISR wurde aufgerufen, -1 = unbekannte Vektor-Nummer *
|
||||
*****************************************************************************/
|
||||
int IntDispatcher::report (unsigned int vector) {
|
||||
int IntDispatcher::report(unsigned int vector) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
if (vector >= this->size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ISR* isr = this->map[vector];
|
||||
|
||||
if (isr == 0) {
|
||||
kout << "No ISR registered for vector " << vector << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
isr->trigger();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -15,13 +15,11 @@
|
||||
* Autor: Olaf Spinczyk, TU Dortmund *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "kernel/PIC.h"
|
||||
#include "kernel/interrupts/PIC.h"
|
||||
#include "kernel/IOport.h"
|
||||
|
||||
|
||||
static IOport IMR1 (0x21); // interrupt mask register von PIC 1
|
||||
static IOport IMR2 (0xa1); // interrupt mask register von PIC 2
|
||||
|
||||
static IOport IMR1(0x21); // interrupt mask register von PIC 1
|
||||
static IOport IMR2(0xa1); // interrupt mask register von PIC 2
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: PIC::allow *
|
||||
@ -34,12 +32,24 @@ static IOport IMR2 (0xa1); // interrupt mask register von PIC 2
|
||||
* Parameter: *
|
||||
* irq: IRQ der erlaubt werden soll *
|
||||
*****************************************************************************/
|
||||
void PIC::allow (int irq) {
|
||||
void PIC::allow(int irq) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
}
|
||||
|
||||
// NOTE: allow sets the bit to 0
|
||||
|
||||
unsigned char IMR;
|
||||
unsigned char mask = ~(0x1 << (irq % 8));
|
||||
if (irq < 8) {
|
||||
// PIC 1
|
||||
IMR = IMR1.inb(); // We don't want to change the other interrupt masks so use this as start value
|
||||
IMR1.outb(IMR & mask);
|
||||
} else {
|
||||
// PIC 2
|
||||
IMR = IMR2.inb();
|
||||
IMR2.outb(IMR & mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: PIC::forbid *
|
||||
@ -49,12 +59,24 @@ void PIC::allow (int irq) {
|
||||
* Parameter: *
|
||||
* interrupt: IRQ der maskiert werden soll *
|
||||
*****************************************************************************/
|
||||
void PIC::forbid (int irq) {
|
||||
void PIC::forbid(int irq) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
}
|
||||
// NOTE: forbid sets the bit to 1
|
||||
|
||||
unsigned char IMR;
|
||||
unsigned char mask = 0x1 << (irq % 8);
|
||||
if (irq < 8) {
|
||||
// PIC 1
|
||||
IMR = IMR1.inb(); // We don't want to change the other interrupt masks so use this as start value
|
||||
IMR1.outb(IMR | mask);
|
||||
} else {
|
||||
// PIC 2
|
||||
IMR = IMR2.inb();
|
||||
IMR2.outb(IMR | mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: PIC::status *
|
||||
@ -65,9 +87,23 @@ void PIC::forbid (int irq) {
|
||||
* Parameter: *
|
||||
* irq: IRQ dessen Status erfragt werden soll *
|
||||
*****************************************************************************/
|
||||
bool PIC::status (int irq) {
|
||||
bool PIC::status(int irq) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
// TODO: How is IRQ2 handled (Slave PIC)?
|
||||
// Does masking IRQ2 disable the whole slave?
|
||||
|
||||
unsigned char IMR;
|
||||
if (irq < 8) {
|
||||
// PIC 1
|
||||
IMR = IMR1.inb();
|
||||
} else {
|
||||
// PIC 2
|
||||
IMR = IMR2.inb();
|
||||
}
|
||||
|
||||
// Use % 8 to account for two PICs
|
||||
unsigned char mask = 0x1 << (irq % 8);
|
||||
return IMR & mask;
|
||||
}
|
||||
|
||||
|
||||
@ -18,27 +18,28 @@
|
||||
#define __PIC_include__
|
||||
|
||||
class PIC {
|
||||
|
||||
|
||||
private:
|
||||
PIC(const PIC ©); // Verhindere Kopieren
|
||||
PIC(const PIC& copy); // Verhindere Kopieren
|
||||
|
||||
public:
|
||||
PIC() {}
|
||||
|
||||
|
||||
public:
|
||||
// IRQ-Nummern von Geraeten
|
||||
enum {
|
||||
timer = 0, // Programmable Interrupt Timer (PIT)
|
||||
keyboard = 1 // Tastatur
|
||||
timer = 0, // Programmable Interrupt Timer (PIT)
|
||||
keyboard = 1 // Tastatur
|
||||
};
|
||||
|
||||
// Freischalten der Weiterleitung eines IRQs durch den PIC an die CPU
|
||||
void allow (int irq);
|
||||
void allow(int irq);
|
||||
|
||||
// Unterdruecken der Weiterleitung eines IRQs durch den PIC an die CPU
|
||||
void forbid (int irq);
|
||||
void forbid(int irq);
|
||||
|
||||
// Abfragen, ob die Weiterleitung fuer einen bestimmten IRQ unterdrueckt ist
|
||||
bool status (int interrupt_device);
|
||||
};
|
||||
bool status(int interrupt_device);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user