OSDev.org

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

All times are UTC - 6 hours




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Timer IRQ doesn't work but keyboard does? [SOLVED]
PostPosted: Sun Apr 30, 2023 11:01 am 
Offline

Joined: Sun Apr 30, 2023 10:37 am
Posts: 1
EDIT: solved, i messed up the registers struct, entirely forgetting ebx


I've been trying to get IRQs working following this https://github.com/cfenollosa/os-tutorial (based on James Molloy) and I've encountered some strange errors. I got the IDT set up and remapped PIC to spaces 32-47, and i also have an assembly routine which handles IRQ and ISR requests. Im using a pointer to a struct to represent the register state as the tutorial suggests.

Code:
irq_common_stub:
   pusha

   mov ax,ds
   push eax

   mov ax,0x10
   mov ds,ax
   mov es,ax
   mov fs,ax
   mov gs,ax

   push esp
   cld

   call irq_handler
   pop ebx
   pop ebx
   mov ds,bx
   mov es,bx
   mov fs,bx
   mov gs,bx
   popa
   add esp, 8
   iret

; ......
irq0:   
   push byte 0
   push byte 32
   jmp irq_common_stub
; etc ...



And a similar thing for ISRs and for irq/isr codes. And the actual handler is as follows:
Code:
extern "C" void irq_handler(registers_t *r){
   // send end of interrupt to pics after each interrupt
   // or they wont send another one
   //kprint("recevied irq\n");
   if(r->int_no > 33){
      kprint("error: ");
      char st[3];
      int_to_ascii(r->int_no,st);
      kprint(st);
      kprint("\n");
      return;
   }

   if(r->int_no >= 40) port_byte_out(0xA0, 0x20); //slave
   port_byte_out(0x20,0x20); //master

   if(interrupt_handlers[r->int_no] != 0){
      isr_t handler = interrupt_handlers[r->int_no];
      handler(r);
   }
}


Currently I just have it print an error if it attempts to access anything beside keyboard or timer. If I initialize the keyboard like this:

Code:
void init_keyboard(){
   register_interrupt_handler(IRQ1, keyboard_callback);
}


Where IRQ1 is just "#define IRQ1 33", and then the appropriate function. This works flawlessly. But if I try to do a similar thing for the timer:

Code:
void init_timer(uint32_t freq){
   //register handler
   register_interrupt_handler(IRQ0, timer_callback);

   //get the PIT value, hardware clock is 1193180 Hz
   uint32_t divisor = 1193180 / freq;
   uint8_t low = (uint8_t) (divisor & 0xFF);
   uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF);
   //send the command
   port_byte_out(0x43, 0x36);
   port_byte_out(0x40,low);
   port_byte_out(0x40,high);

   //port_byte_out(0x20,0x20);
}


I get "error 93" printed to the window, which I tried looking up, but it seems like a garbage value to me. If I uncommented the last line in "init_timer", essentially sending EOI twice, I still get the same error but immediately afterwards the PIT starts working (I set up a print utility which prints each new tick). However this workaround breaks if I enable both the keyboard and timer, giving the same error code, the keyboard works fine.
The tutorial I'm following is aware of the "irq_common_stub" problem in Molloy's code and tries to fix it, but I can't tell if it's successful in doing that. I read https://wiki.osdev.org/James_Molloy's_Tutorial_Known_Bugs to see for myself but I was unsuccesful.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 87 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