This is the interrupts setup code:
Code: Select all
void isr_install() {
setupirqs();
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
outportb(0x21, 0x20);
outportb(0xA1, 0x28);
outportb(0x21, 0x00);
outportb(0xA1, 0x00);
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0xff);
outportb(0xA1, 0xff);
set_idt_gate(0, (uint32)isr0);
set_idt_gate(1, (uint32)isr1);
set_idt_gate(2, (uint32)isr2);
set_idt_gate(3, (uint32)isr3);
set_idt_gate(4, (uint32)isr4);
set_idt_gate(5, (uint32)isr5);
set_idt_gate(6, (uint32)isr6);
set_idt_gate(7, (uint32)isr7);
set_idt_gate(8, (uint32)isr8);
set_idt_gate(9, (uint32)isr9);
set_idt_gate(10, (uint32)isr10);
set_idt_gate(11, (uint32)isr11);
set_idt_gate(12, (uint32)isr12);
set_idt_gate(13, (uint32)isr13);
set_idt_gate(14, (uint32)isr14);
set_idt_gate(15, (uint32)isr15);
set_idt_gate(16, (uint32)isr16);
set_idt_gate(17, (uint32)isr17);
set_idt_gate(18, (uint32)isr18);
set_idt_gate(19, (uint32)isr19);
set_idt_gate(20, (uint32)isr20);
set_idt_gate(21, (uint32)isr21);
set_idt_gate(22, (uint32)isr22);
set_idt_gate(23, (uint32)isr23);
set_idt_gate(24, (uint32)isr24);
set_idt_gate(25, (uint32)isr25);
set_idt_gate(26, (uint32)isr26);
set_idt_gate(27, (uint32)isr27);
set_idt_gate(28, (uint32)isr28);
set_idt_gate(29, (uint32)isr29);
set_idt_gate(30, (uint32)isr30);
set_idt_gate(31, (uint32)isr31);
set_idt();
}
Code: Select all
#define KERNEL_CS 0x08
typedef struct {
uint16 low_offset;
uint16 sel;
uint8 always0;
uint8 flags;
uint16 high_offset;
} __attribute__((packed)) idt_gate_t ;
typedef struct {
uint16 limit;
uint32 base;
} __attribute__((packed)) idt_register_t;
#define low_16(address) (uint16)((address) & 0xFFFF)
#define high_16(address) (uint16)(((address) >> 16) & 0xFFFF)
#define IDT_ENTRIES 256
idt_gate_t idt[IDT_ENTRIES];
idt_register_t idt_reg;
void set_idt_gate(int n, uint32 handler) {
idt[n].low_offset = low_16(handler);
idt[n].sel = KERNEL_CS;
idt[n].always0 = 0;
idt[n].flags = 0x8E;
idt[n].high_offset = high_16(handler);
}
void set_idt() {
idt_reg.base = (uint32) &idt;
idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
}
Code: Select all
void unassigned_IRQ1(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ2(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ3(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ4(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ5(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ6(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ7(void) {
outportb(0x20, 0x20);
}
void unassigned_IRQ8(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ9(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ10(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ11(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ12(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ13(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ14(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void unassigned_IRQ15(void) {
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
void setupirqs() {
set_idt_gate(32, (uint32)PIT_irq); //Install IRQ 0
PIT_setup();
set_idt_gate(33, (uint32)unassigned_IRQ1); //Install IRQ 1
set_idt_gate(34, (uint32)unassigned_IRQ2); //Install IRQ 2
set_idt_gate(35, (uint32)unassigned_IRQ3); //Install IRQ 3
set_idt_gate(36, (uint32)unassigned_IRQ4); //Install IRQ 4
set_idt_gate(37, (uint32)unassigned_IRQ5); //Install IRQ 5
set_idt_gate(38, (uint32)unassigned_IRQ6); //Install IRQ 6
set_idt_gate(39, (uint32)unassigned_IRQ7); //Install IRQ 7
set_idt_gate(40, (uint32)unassigned_IRQ8); //Install IRQ 8
set_idt_gate(41, (uint32)unassigned_IRQ9); //Install IRQ 9
set_idt_gate(42, (uint32)unassigned_IRQ10); //Install IRQ 10
set_idt_gate(43, (uint32)unassigned_IRQ11); //Install IRQ 11
set_idt_gate(44, (uint32)unassigned_IRQ12); //Install IRQ 12
set_idt_gate(45, (uint32)unassigned_IRQ13); //Install IRQ 13
set_idt_gate(46, (uint32)unassigned_IRQ14); //Install IRQ 14
set_idt_gate(47, (uint32)unassigned_IRQ15); //Install IRQ 15
}
Code: Select all
int timer_ticks = 0;
void PIT_irq(void) {
timer_ticks++; //Incrmements ticks value
print_serial("Tick");
outportb(0x20, 0x20);
}
void timer_phase(int hz)
{
int divisor = 1193180 / hz;
outportb(0x43, 0x36);
outportb(0x40, divisor & 0xFF);
outportb(0x40, divisor >> 8);
}
int get_ticks() {
return timer_ticks; //Returns how many ticks have passed
}
void PIT_setup() {
timer_phase(100);
}