This commit is contained in:
2021-09-14 18:46:50 +03:00
parent d605c6a016
commit b6ddeca1c3
180 changed files with 5909 additions and 2039 deletions

View File

@@ -0,0 +1,159 @@
bits 32
; !!! IRQ !!!
global _i86_irq0
global _i86_irq1
global _i86_irq2
global _i86_irq3
global _i86_irq4
global _i86_irq5
global _i86_irq6
global _i86_irq7
global _i86_irq8
global _i86_irq9
global _i86_irq10
global _i86_irq11
global _i86_irq12
global _i86_irq13
global _i86_irq14
global _i86_irq15
; 32: IRQ0
_i86_irq0:
cli
push byte 0
push byte 32; Note that these don't push an error code on the stack:
; We need to push a dummy error code
jmp irq_common_stub
; 33: IRQ1
_i86_irq1:
cli
push byte 0
push byte 33
jmp irq_common_stub
; 34: IRQ2
_i86_irq2:
cli
push byte 0
push byte 34
jmp irq_common_stub
; 35: IRQ3
_i86_irq3:
cli
push byte 0
push byte 35
jmp irq_common_stub
; 36: IRQ4
_i86_irq4:
cli
push byte 0
push byte 36
jmp irq_common_stub
; 37: IRQ5
_i86_irq5:
cli
push byte 0
push byte 37
jmp irq_common_stub
; 38: IRQ6
_i86_irq6:
cli
push byte 0
push byte 38
jmp irq_common_stub
; 39: IRQ7
_i86_irq7:
cli
push byte 0
push byte 39
jmp irq_common_stub
; 40: IRQ8
_i86_irq8:
cli
push byte 0
push byte 40
jmp irq_common_stub
; 41: IRQ9
_i86_irq9:
cli
push byte 0
push byte 41
jmp irq_common_stub
; 42: IRQ10
_i86_irq10:
cli
push byte 0
push byte 42
jmp irq_common_stub
; 43: IRQ11
_i86_irq11:
cli
push byte 0
push byte 43
jmp irq_common_stub
; 44: IRQ12
_i86_irq12:
cli
push byte 0
push byte 44
jmp irq_common_stub
; 45: IRQ13
_i86_irq13:
cli
push byte 0
push byte 45
jmp irq_common_stub
; 46: IRQ14
_i86_irq14:
cli
push byte 0
push byte 46
jmp irq_common_stub
; 47: IRQ15
_i86_irq15:
cli
push byte 0
push byte 47
jmp irq_common_stub
extern _i86_IrqHandler
; This is a stub that we have created for IRQ based ISRs. This calls
; '_i86_irq_handler' in our C code. We need to create this in an 'irq.c'
irq_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, _i86_IrqHandler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret

View File

@@ -0,0 +1,99 @@
#include <system.h>
#include "pic.h"
#include "irq.h"
#include "../idt/idt.h"
/* These are own ISRs that point to our special IRQ handler
* instead of the regular 'fault_handler' function */
extern void i86_irq0();
extern void i86_irq1();
extern void i86_irq2();
extern void i86_irq3();
extern void i86_irq4();
extern void i86_irq5();
extern void i86_irq6();
extern void i86_irq7();
extern void i86_irq8();
extern void i86_irq9();
extern void i86_irq10();
extern void i86_irq11();
extern void i86_irq12();
extern void i86_irq13();
extern void i86_irq14();
extern void i86_irq15();
/* This array is actually an array of function pointers. We use
* this to handle custom IRQ handlers for a given IRQ */
void *IrqRoutines[16] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* This installs a custom IRQ handler for the given IRQ */
void i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r))
{
IrqRoutines[irq] = handler;
}
void i86_IrqUninstallHandler (int irq)
{
IrqRoutines[irq] = 0;
}
/* We first remap the interrupt controllers, and then we install
* the appropriate ISRs to the correct entries in the IDT. This
* is just like installing the exception handlers */
void i86_IrqInstall()
{
i86_PicRemap(32,40);
i86_IdtSetGate(32, (unsigned)i86_irq0, 0x08, 0x8E);
i86_IdtSetGate(33, (unsigned)i86_irq1, 0x08, 0x8E);
i86_IdtSetGate(34, (unsigned)i86_irq2, 0x08, 0x8E);
i86_IdtSetGate(35, (unsigned)i86_irq3, 0x08, 0x8E);
i86_IdtSetGate(36, (unsigned)i86_irq4, 0x08, 0x8E);
i86_IdtSetGate(37, (unsigned)i86_irq5, 0x08, 0x8E);
i86_IdtSetGate(38, (unsigned)i86_irq6, 0x08, 0x8E);
i86_IdtSetGate(39, (unsigned)i86_irq7, 0x08, 0x8E);
i86_IdtSetGate(40, (unsigned)i86_irq8, 0x08, 0x8E);
i86_IdtSetGate(41, (unsigned)i86_irq9, 0x08, 0x8E);
i86_IdtSetGate(42, (unsigned)i86_irq10, 0x08, 0x8E);
i86_IdtSetGate(43, (unsigned)i86_irq11, 0x08, 0x8E);
i86_IdtSetGate(44, (unsigned)i86_irq12, 0x08, 0x8E);
i86_IdtSetGate(45, (unsigned)i86_irq13, 0x08, 0x8E);
i86_IdtSetGate(46, (unsigned)i86_irq14, 0x08, 0x8E);
i86_IdtSetGate(47, (unsigned)i86_irq15, 0x08, 0x8E);
}
/* Each of the IRQ ISRs point to this function, rather than
* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
* to be told when you are done servicing them, so you need
* to send them an "End of Interrupt" command (0x20). There
* are two 8259 chips: The first exists at 0x20, the second
* exists at 0xA0. If the second controller (an IRQ from 8 to
* 15) gets an interrupt, you need to acknowledge the
* interrupt at BOTH controllers, otherwise, you only send
* an EOI command to the first controller. If you don't send
* an EOI, you won't raise any more IRQs */
void i86_IrqHandler (ISR_stack_regs *r)
{
/* This is a blank function pointer */
void (*handler)(ISR_stack_regs *r);
/* Find out if we have a custom handler to run for this
* IRQ, and then finally, run it */
handler = IrqRoutines[r->int_no - 32];
if (handler) handler(r);
/* If the IDT entry that was invoked was greater than 40
* (meaning IRQ8 - 15), then we need to send an EOI to
* the slave controller */
if (r->int_no >=40) outportb(0x0A, 0x20);
/* In either case, we need to send an EOI to the master
* interrupt controller too */
outportb(0x20, 0x20);
}

View File

@@ -0,0 +1,10 @@
#ifndef __IRQ_H
#define __IRQ_H
#include <regs.h>
extern void i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r));
extern void i86_IrqUninstallHandler (int irq);
extern void i86_IrqInstall();
#endif

View File

@@ -0,0 +1,23 @@
#include <system.h>
#include "pic.h"
void i86_PicRemap(int pic1, int pic2)
{
// Send ICW1
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
// send ICW2
outportb(0x21, pic1); // remap pics
outportb(0xA1, pic2);
// send ICW3
outportb(0x21, 4);
outportb(0xA1, 2);
// Send ICW4
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x00);
}

View File

@@ -0,0 +1,6 @@
#ifndef _PIC_H
#define _PIC_H
extern void i86_PicRemap(int pic1, int pic2);
#endif