CTAOS v3
This commit is contained in:
19
SysCore/hal/irq/compile.bat
Normal file
19
SysCore/hal/irq/compile.bat
Normal file
@ -0,0 +1,19 @@
|
||||
@echo off
|
||||
rem The name of the loader assembly file (without extension, must be .asm):
|
||||
set loader_name=loader
|
||||
|
||||
rem NASM and DJGPP executable paths:
|
||||
set nasm_path=C:\nasm
|
||||
set djgpp_path=C:\DJGPP\bin
|
||||
set objpath=../../objects
|
||||
set incpath=../../include
|
||||
|
||||
@echo on
|
||||
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
|
||||
|
||||
@echo off
|
||||
@echo .
|
||||
@echo Done!
|
||||
|
||||
@pause
|
159
SysCore/hal/irq/irq.asm
Normal file
159
SysCore/hal/irq/irq.asm
Normal 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_irq_handler
|
||||
|
||||
; 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_irq_handler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
79
SysCore/hal/irq/irq.c
Normal file
79
SysCore/hal/irq/irq.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include <system.h>
|
||||
#include "../idt/idt.h"
|
||||
#include "../pic/pic.h"
|
||||
#include "irq.h"
|
||||
/* This array is actually an array of function pointers. We use
|
||||
* this to handle custom IRQ handlers for a given IRQ */
|
||||
void *irq_routines[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_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r))
|
||||
{
|
||||
irq_routines[irq] = handler;
|
||||
}
|
||||
|
||||
void i86_irq_uninstall_handler (int irq)
|
||||
{
|
||||
irq_routines[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_irq_install()
|
||||
{
|
||||
i86_pic_remap(32,40);
|
||||
|
||||
i86_idt_set_gate(32, (unsigned)i86_irq0, 0x08, 0x8E);
|
||||
i86_idt_set_gate(33, (unsigned)i86_irq1, 0x08, 0x8E);
|
||||
i86_idt_set_gate(34, (unsigned)i86_irq2, 0x08, 0x8E);
|
||||
i86_idt_set_gate(35, (unsigned)i86_irq3, 0x08, 0x8E);
|
||||
i86_idt_set_gate(36, (unsigned)i86_irq4, 0x08, 0x8E);
|
||||
i86_idt_set_gate(37, (unsigned)i86_irq5, 0x08, 0x8E);
|
||||
i86_idt_set_gate(38, (unsigned)i86_irq6, 0x08, 0x8E);
|
||||
i86_idt_set_gate(39, (unsigned)i86_irq7, 0x08, 0x8E);
|
||||
i86_idt_set_gate(40, (unsigned)i86_irq8, 0x08, 0x8E);
|
||||
i86_idt_set_gate(41, (unsigned)i86_irq9, 0x08, 0x8E);
|
||||
i86_idt_set_gate(42, (unsigned)i86_irq10, 0x08, 0x8E);
|
||||
i86_idt_set_gate(43, (unsigned)i86_irq11, 0x08, 0x8E);
|
||||
i86_idt_set_gate(44, (unsigned)i86_irq12, 0x08, 0x8E);
|
||||
i86_idt_set_gate(45, (unsigned)i86_irq13, 0x08, 0x8E);
|
||||
i86_idt_set_gate(46, (unsigned)i86_irq14, 0x08, 0x8E);
|
||||
i86_idt_set_gate(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_irq_handler (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 = irq_routines[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);
|
||||
}
|
29
SysCore/hal/irq/irq.h
Normal file
29
SysCore/hal/irq/irq.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __IRQ_H
|
||||
#define __IRQ_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();
|
||||
|
||||
extern void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r));
|
||||
extern void i86_irq_uninstall_handler (int irq);
|
||||
extern void i86_irq_install();
|
||||
extern void i86_irq_handler (ISR_stack_regs *r);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user