[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH] Mehrere ISRs pro IRQ
From: Max Reitz <max@xxxxxxxxxx>
Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
src/kernel/src/intr.c | 76 +++++++++++++++++++++++++++++++------------------
1 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/src/kernel/src/intr.c b/src/kernel/src/intr.c
index 9fa3ff3..be90e8c 100644
--- a/src/kernel/src/intr.c
+++ b/src/kernel/src/intr.c
@@ -38,6 +38,7 @@
*/
#include "cpu.h"
+#include <collections.h>
#include "ports.h"
#include "types.h"
#include "kernel.h"
@@ -65,8 +66,8 @@ typedef struct {
gate_descriptor idt[IDT_SIZE];
-pfIrqHandler irq_handlers[16] = { 0 }; // für jeden IRQ genau ein Handler. Wenn es keinen Handler gibt, ist der entsprechende Wert 0.
-struct task * intr_handling_task[256] = { NULL };
+static list_t* irq_handlers[16] = { NULL };
+list_t* intr_handling_task[256] = { NULL };
void handle_irq(int irq, dword* esp);
@@ -120,7 +121,7 @@ dword irqs_to_send[16];
extern dword kernel_pd_id;
/*
- * gibt einen neuen Wert für esp zurck
+ * gibt einen neuen Wert fuer esp zurck
*/
dword handle_int(dword esp)
{
@@ -146,7 +147,7 @@ dword handle_int(dword esp)
}
else
{
- // TODO: Abstürzen, denn diese Interrupts dürften nicht aufgerufen werden
+ // TODO: Abstuerzen, denn diese Interrupts duerften nicht aufgerufen werden
}
send_irqs(&esp);
@@ -186,11 +187,11 @@ dword handle_int(dword esp)
/**
* Legt eine IDT an und installiert die Exception Handler. Nicht genutzte
- * Einträge werden mit Verweisen auf den Null-Handler initalisiert.
- * Anschließend wird die IDT geladen.
+ * Eintraege werden mit Verweisen auf den Null-Handler initalisiert.
+ * Anschliessend wird die IDT geladen.
*/
void init_idt() {
- int i;
+ int i;
// Tabelle initialisieren
for (i = 0; i < IDT_SIZE; i++)
@@ -198,7 +199,7 @@ void init_idt() {
set_intr(i, 0x08, &null_handler, 0, IDT_INTERRUPT_GATE);
}
- // Register befllen
+ // Register befuellen
struct {
word size;
dword base;
@@ -265,9 +266,9 @@ void init_idt() {
outb_wait(PIC1_DATA, 0x00);
outb_wait(PIC2_DATA, 0x00);
- // Handler für den System Call installieren
+ // Handler fuer den System Call installieren
// TODO: SOllte eigentlich ein IDT_TRAP_GATE sein, aber irgendwo ist da
- // noch ein Problem, das dann für einen Page Fault sorgt, wenn ich zu
+ // noch ein Problem, das dann fuer einen Page Fault sorgt, wenn ich zu
// schnell tippe...
set_intr(SYSCALL_INTERRUPT, 0x08, syscall_stub, 3, IDT_INTERRUPT_GATE);
//set_intr(SYSCALL_INTERRUPT, 0x08, syscall_stub, 3, IDT_TRAP_GATE);
@@ -323,26 +324,29 @@ int request_irq(int irq, void * handler)
return 1;
}
- if(irq_handlers[irq] != 0)
- {
- return 1;
+ if (irq_handlers[irq] == NULL) {
+ irq_handlers[irq] = list_create();
}
- irq_handlers[irq] = handler;
+ list_push(irq_handlers[irq], handler);
return 0;
}
int release_irq(int irq)
{
- if(irq < 0 || irq > 15)
+ /*if(irq < 0 || irq > 15)
{
return 1;
}
irq_handlers[irq] = 0;
- return 0;
+ return 0;*/
+
+ //FIXME Ich weiss ja nicht, wer das braucht. Aber wenn es noetig ist, dann
+ //muesste man das in release_irq(int irq, void* handler) oder sowas aendern
+ return 1;
}
@@ -361,7 +365,7 @@ void handle_irq(int irq, dword* esp)
}
}*/
- // IRQs 7 und 15 können unabsichtlich aufgerufen werden
+ // IRQs 7 und 15 koennen unabsichtlich aufgerufen werden
// In diesem Fall beim PIC nachschauen, ob wirklich was zu verarbeiten
// ist, ansonsten gleich wieder abbrechen.
if ((irq == 7) || (irq == 15))
@@ -386,9 +390,16 @@ void handle_irq(int irq, dword* esp)
//printf("disable IRQ %d\n", irq);
disable_irq(irq);
}
- else if (irq_handlers[irq] != 0)
+ else if (irq_handlers[irq] != NULL)
{
- irq_handlers[irq](irq, esp);
+ int i;
+ pfIrqHandler handler;
+
+ for (i = 0; (handler = list_get_element_at(irq_handlers[irq], i))
+ != NULL; i++)
+ {
+ handler(irq, esp);
+ }
}
send_eoi:
@@ -402,7 +413,10 @@ send_eoi:
void set_intr_handling_task(byte intr, struct task * task)
{
//kprintf("Interrupt %d wird jetzt von Task %d behandelt\n", intr, task->pid);
- intr_handling_task[intr] = task;
+ if (intr_handling_task[intr] == NULL) {
+ intr_handling_task[intr] = list_create();
+ }
+ list_push(intr_handling_task[intr], task);
}
void handle_exception(dword* esp)
@@ -426,7 +440,7 @@ void handle_exception(dword* esp)
case 14:
cr2 = read_cr2();
diff = (cr2 >> PAGE_SHIFT) - (isf->esp >> PAGE_SHIFT);
- // Ueberprüfen ob der Pagefault durch einen Stackoverflow
+ // Ueberpruefen, ob der Pagefault durch einen Stackoverflow
// hervorgerufen wurde
if ((diff >= -2) && (diff <= 2)
&& (current_task != NULL)
@@ -440,7 +454,7 @@ void handle_exception(dword* esp)
break;
}
- // Prüfen, ob ein VM86-Task die Exception ausgelöst hat, und evtl reagieren
+ // Pruefen, ob ein VM86-Task die Exception ausgeloest hat, und evtl reagieren
if (isf->eflags & 0x20000) {
if (vm86_exception(esp)) {
return;
@@ -512,19 +526,25 @@ void handle_exception(dword* esp)
void send_irqs(dword* esp)
{
+ int i;
+ struct task* tsk;
dword irq;
for (irq = 0; irq < 16; irq++)
{
dword rpc_data = irq + IRQ_BASE;
while (irqs_to_send[irq] > 0) {
- schedule_to_task(intr_handling_task[irq + IRQ_BASE], esp);
- if (!fastrpc_irq(intr_handling_task[irq + IRQ_BASE], 0, 0, 4,
- (char*) &rpc_data, irq))
+ for (i = 0; (tsk = list_get_element_at(
+ intr_handling_task[irq + IRQ_BASE], i)) != NULL; i++)
{
- //kprintf("SYSCALL_RPC = FALSE");
- break;
+ schedule_to_task(tsk, esp);
+ if (!fastrpc_irq(tsk, 0, 0, 4,
+ (char*) &rpc_data, irq))
+ {
+ //kprintf("SYSCALL_RPC = FALSE");
+ break;
+ }
+ //kprintf("IRQ-Handler aufgerufen");
}
- //kprintf("IRQ-Handler aufgerufen");
irqs_to_send[irq]--;
}
}
--
1.6.3.3