Can't get IRQs to work

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
VMGP
Posts: 6
Joined: Wed Sep 18, 2019 9:35 am

Can't get IRQs to work

Post by VMGP »

I am developing a real mode operating system and I can't get IRQs to work, but the exceptions work. What is happening?

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();
}
The "set_idt_gate()" and "set_idt()" functions:

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));
}
And the IRQ code:

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
}
And the PIT controller:

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);
}
Octocontrabass
Member
Member
Posts: 5575
Joined: Mon Mar 25, 2013 7:01 pm

Re: Can't get IRQs to work

Post by Octocontrabass »

If you are developing a real-mode operating system, there is no IDT and all of the functions you've copied to set up an IDT are wrong.

Are you sure you're developing a real-mode operating system?
VMGP
Posts: 6
Joined: Wed Sep 18, 2019 9:35 am

Re: Can't get IRQs to work

Post by VMGP »

Yes
sunnysideup
Member
Member
Posts: 106
Joined: Sat Feb 08, 2020 11:11 am
Libera.chat IRC: sunnysideup

Re: Can't get IRQs to work

Post by sunnysideup »

In real mode, there isn't an IDT, it's an IVT that starts at address 0. IIRC, the size of this table is 256 * 4 bytes
VMGP
Posts: 6
Joined: Wed Sep 18, 2019 9:35 am

Re: Can't get IRQs to work

Post by VMGP »

Ok. Thanks! Found it out and made IRQs to work!
Post Reply