OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:31 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: PIT not triggering interupt
PostPosted: Mon Jul 16, 2018 11:32 pm 
Offline

Joined: Mon Jul 16, 2018 10:23 pm
Posts: 6
For some reason, I can't seem to get my timer interrupt to trigger. I'm following James Molloy's tutorial and trying to keep in mind the standard known issues listed on the wiki. It might just be some dumb C bug but I can't seem to find it.

I expect this code to print out a ton of "Tick" messages but instead, it just prints out the following

Quote:
setting up timer
registering interrupt handler


Unhandled Interupt: 0x03


Unhandled Interupt: 0x04


The first two show that I made it past the timer init. The fact that printing works (even for manually triggered interrupts) and that I should be printing "irq hit" if I was getting to irq_handle indicates to me that I'm not managing to get into irq0 like I wanted. I'm not particularlly sure why I'm not getting there though. Any idea what I might be doing wrong?

(Chunks of my code that I think are relevant posted below)

kernel_main
Code:
void kernel_main(void) {
  gdt_init();
  idt_init();
  t_init();
  timer_init(100);
  asm volatile ("int $0x3");
  asm volatile ("int $0x4");
}


The relevant assembly for irq1-15
Code:
.global irq_handler
.type irq_handler, @function

irq_common_stub:
        pusha
        mov %ds, %ax
        push %eax
        push %esp
        mov $0x10, %ax
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        call irq_handler
        add $0x04, %esp
        pop %eax
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        popa
        add $0x08,%esp
        iret

.macro make_iqr n irqn
.global irq\n
.type irq\n, @function
irq\n:
        cli
        push $0
        push $\irqn
        jmp irq_common_stub
.endm

make_iqr 0,32
...
make_iqr 15,47


isr_init
Code:
void idt_init() {
  idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
  idt_ptr.base = (uint32_t)&idt_entries;

  kmemset((void *)&idt_entries, 0, sizeof(idt_entry_t) * 256);
  kmemset((void *)&interrupt_handlers, 0, sizeof(isr_t) * 256);

  // Remap the irq tables
  outb(0x20, 0x11);
  outb(0xA0, 0x11);
  outb(0x21, 0x20);
  outb(0xA1, 0x28);
  outb(0x21, 0x04);
  outb(0xA1, 0x02);
  outb(0x21, 0x01);
  outb(0xA1, 0x01);
  outb(0x21, 0x0);
  outb(0xA1, 0x0);

  idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E);
  ...
idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E);
  idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E);
  idt_set_gate(34, (uint32_t)irq2, 0x08, 0x8E);
  idt_set_gate(35, (uint32_t)irq3, 0x08, 0x8E);
  idt_set_gate(36, (uint32_t)irq4, 0x08, 0x8E);
  idt_set_gate(37, (uint32_t)irq5, 0x08, 0x8E);
  idt_set_gate(38, (uint32_t)irq6, 0x08, 0x8E);
  idt_set_gate(39, (uint32_t)irq7, 0x08, 0x8E);
  idt_set_gate(40, (uint32_t)irq8, 0x08, 0x8E);
  idt_set_gate(41, (uint32_t)irq9, 0x08, 0x8E);
  idt_set_gate(42, (uint32_t)irq10, 0x08, 0x8E);
  idt_set_gate(43, (uint32_t)irq11, 0x08, 0x8E);
  idt_set_gate(44, (uint32_t)irq12, 0x08, 0x8E);
  idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E);
  idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E);
  idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E);

  idt_flush((uint32_t)&idt_ptr);
}


some other irq related functions form the tutorial
Code:
void isr_handler(registers_t *regs) {
  if (interrupt_handlers[regs->int_no])
    interrupt_handlers[regs->int_no](regs);
  else {
    term_t *term = t_curterm();
    static const char *lookup = "0123456789ABCDEF";
    t_print(term, "\n\nUnhandled interrupt: 0x");
    t_putchar(term, lookup[(regs->int_no >> 4) & 0xF]);
    t_putchar(term, lookup[regs->int_no & 0xF]);
    t_print(term, "\n");
  }
}

void register_interrupt_handler(uint8_t n, isr_t h) {
  t_print(t_curterm(), "registering interrupt handler\n");
  interrupt_handlers[n] = h;
}

void irq_handler(registers_t *regs);

void irq_handler(registers_t *regs) {
  t_print(t_curterm(), "irq hit\n");
  if (regs->int_no >= 40) {
    outb(0xA0, 0x20);
  }
  outb(0x20, 0x20);

  if (interrupt_handlers[regs->int_no] != 0)
    interrupt_handlers[regs->int_no](regs);
}


and finally the timer code from the tutorial (as I've written/copied it)
Code:
static void timer_callback(registers_t* regs) {
  term_t *term = t_curterm();
  t_print(term, "Tick\n");
  tick++;
}

void timer_init(uint16_t frequency) {
  t_print(t_curterm(), "setting up timer\n");
  // Firstly, register our timer callback.
  register_interrupt_handler(IRQ0, &timer_callback);

  // The value we send to the PIT is the value to divide it's input clock
  // (1193180 Hz) by, to get our required frequency. Important to note is
  // that the divisor must be small enough to fit into 16-bits.
  uint32_t divisor = 1193180 / frequency;

  // Send the command byte.
  outb(0x43, 0x36);

  // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
  uint8_t l = (uint8_t)(divisor & 0xFF);
  uint8_t h = (uint8_t)((divisor >> 8) & 0xFF);

  // Send the frequency divisor.
  outb(0x40, l);
  outb(0x40, h);
}


Top
 Profile  
 
 Post subject: Re: PIT not triggering interupt
PostPosted: Tue Jul 17, 2018 12:25 am 
Offline

Joined: Mon Jul 16, 2018 10:23 pm
Posts: 6
Ah well I made some progress by randomlly trying things out

1) I was following bare-bones initially and thus a) had hardware interrupts disabled it would seem and
2) I wasn't looping over a halt at the end like I should have been. Consequently, I was disabling interrupts too soon to see anything.

the PIT is now triggering my desired function correctly!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 55 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group