OSDev.org
https://forum.osdev.org/

General Protection Fault for timer IRQ
https://forum.osdev.org/viewtopic.php?f=1&t=47600
Page 1 of 1

Author:  Rakhyvel [ Wed Jul 28, 2021 4:19 pm ]
Post subject:  General Protection Fault for timer IRQ

I am following a tutorial and am getting stuck with my timer's IRQ routine, and getting some super weird behaviour.

Basically, I have a function in a file called VGA.c that puts a character at a certain location on the screen. When I call the function in my timer callback handler, I get a general protection fault.
Code:
/* Called after IRQ0 is raised */
void Timer_callback(registers_t regs) {
   VGA_TerminalPutEntryAt('X', VGA_COLOR_WHITE, 2, 2); // This call causes a GPF
}


However, when I copy and paste the exact same function into my timer.c file, and call that function, there is no GPF.
Code:
void TerminalPutEntryAt(char c, uint8_t color, size_t x, size_t y)
{
   const size_t index = y * VGA_WIDTH + x;
   terminal_buffer[index] = VGA_Entry(c, color); // Put the character and color byte in the VGA memory map, which starts at 0xC00B8000
}

void Timer_callback(registers_t regs) {
   TerminalPutEntryAt('X', VGA_COLOR_WHITE, 2, 2); // This call does not
}


I feel like this rules out any paging or stack issues.

Any time an IRQ is raised, I have the IDT point to a stub defined in assembly. This pushes the IRQ and ISR number, and then calls a more general IRQ stub, which calls a dispatch, which calls the actual callback function.
Code:

global irq0

; ...

irq0:
   cli
   push byte 0
   push byte 32
   jmp irq_common_stub

; ...


; Called by IRQ stubs below
irq_common_stub:
    pusha
    mov ax, ds
    push eax

    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
   
    call Interrupt_IRQHandler ; Different than the ISR code

    pop ebx  ; Different than the ISR code
    mov ds, bx
    mov es, bx
    mov fs, bx
    mov gs, bx

    popa
    add esp, 0x8

    sti
    iret


Code:
/* Called by irq_common_stub, sends acknowledge to PIC, and then calls IRQ handler */
void Interrupt_IRQHandler(registers_t r) {
   // Need to send EOI to PICs or they will not send another interrupt
   if (r.int_no >= 40) {
      IO_OutByte(0xA0, 0x20); // slave
   }
   IO_OutByte(0x20, 0x20); // master

   // Handle the interrupt in a more modular way
   if (interrupt_handlers[r.int_no] != 0) {
      isr_t handler = interrupt_handlers[r.int_no];
        if(handler) {
          handler(r);
        }
   }
}


I know the whole dispatch process works because the timer callback does get called. I'm really at a loss for what could be going on, please let me know if you need to see any other code, any help is appreciated! Thanks

Author:  Octocontrabass [ Wed Jul 28, 2021 4:31 pm ]
Post subject:  Re: General Protection Fault for timer IRQ

OS development tutorials are full of bugs. It looks like you might be running into this bug.

Author:  Rakhyvel [ Wed Jul 28, 2021 4:49 pm ]
Post subject:  Re: General Protection Fault for timer IRQ

That makes a lot of sense actually, thanks!

Author:  Rakhyvel [ Wed Jul 28, 2021 7:29 pm ]
Post subject:  Re: General Protection Fault for timer IRQ

Octocontrabass wrote:
OS development tutorials are full of bugs. It looks like you might be running into this bug.

I went ahead and corrected the code to pass in a pointer to the register struct instead. However, I still got a GPF whenever I tried to call a function outside of the timer.c file.

I know it's cliche to blame the optimizer, but when I removed the optimizer flags, it worked as intended.

Is this a sign I'm just not understanding how the code should be structured?

Author:  Octocontrabass [ Wed Jul 28, 2021 9:10 pm ]
Post subject:  Re: General Protection Fault for timer IRQ

No, it's a sign there's another bug in your code.

If it's not one of the bugs listed in that page, you might have to give us a bit more information to find it.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/