OSDev.org

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

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: [SOLVED] Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 8:01 pm 
Offline

Joined: Fri Mar 17, 2017 9:37 pm
Posts: 22
I'm working on an RTC driver, and am only receiving one interrupt from it immediately after setting the IF flag. I've set the rate in CMOS RTC status register A and enabled RTC periodic interrupts in CMOS RTC status register B. I've unmasked IRQ2 and IRQ8, and have a valid IDT entry for IRQ8. I receive IRQ0 and IRQ1 just fine. I am reading the CMOS RTC status register C before enabling interrupts, and then again in my IRQ8 handler (before PIC EOI).

Here is the relevant code:
RTC configuration: https://github.com/Izzette/izix/blob/rtc/kernel/arch/x86/drivers/cmos/rtc.c
CMOS read/write functions: https://github.com/Izzette/izix/blob/rtc/kernel/arch/x86/drivers/cmos/cmos.c
IRQ8 hook (and other stuff): https://github.com/Izzette/izix/blob/rtc/kernel/arch/x86/time/clock_tick.c

Thanks for your help! I'll add any code or debugging info you'd like to see.


Last edited by Izzette on Mon May 29, 2017 6:05 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 8:57 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Do you send an End of Interrupt (EOI) to the appropriate PIC before doing the IRET from your timer handler?


Last edited by MichaelPetch on Sat May 27, 2017 9:22 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 9:13 pm 
Offline

Joined: Fri Mar 17, 2017 9:37 pm
Posts: 22
Yeah, I send an EOI to the master in the IRQ0,1,3-7 handlers, and one to the slave in IRQ8-15 handlers, after re-enabling interrupts (I'm using interrupt gates not trap gates), but before IRET.


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 9:25 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

MichaelPetch wrote:
Do you send an End of Interrupt (EOI) to the master PIC (Since you are dealing with IRQ0) before doing the IRET from your timer handler?


I think you're right.

Specifically, in pic_8259.c, this:

Code:
void pic_8259_send_eoi (irq_t irq) {
   outb (PIC_EOI, pic_8259_get_pic_cmd_port (irq));
}


Probably needs to be more like this:

Code:
void pic_8259_send_eoi (irq_t irq) {
    if (pic_8259_is_slave_irq (irq)) {
        outb (PIC_EOI, PIC_SLAVE_CMD);
    }
    outb (PIC_EOI, PIC_MASTER_CMD);
}



Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 9:38 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

Izzette wrote:
Yeah, I send an EOI to the master in the IRQ0,1,3-7 handlers, and one to the slave in IRQ8-15 handlers, after re-enabling interrupts (I'm using interrupt gates not trap gates), but before IRET.


If the slave sees an IRQ, then it's a little bit like the slave triggers "IRQ2" on the master (except the master doesn't send the "interrupt vector" to the CPU and lets the slave send it); which means that you need to send an EOI to the slave (to clear its IRQ8) and then send an EOI to the master (to clear its IRQ2).

If you don't send EOI to master, then the PIC chip's "IRQ priorities" prevent lower priority IRQs (IRQs 8, 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, 6 and 7) from being sent to the CPU, but higher priority IRQs (IRQs 0 and 1) do keep working.

Note: While browsing your code I also noticed that you don't handle spurious IRQs properly. If IRQ7 occurs you should ask the master PIC if it's a spurious IRQ and ignore it (without sending EOI) if it is; and if IRQ15 occurs you should ask the slave PIC if it's a spurious IRQ and if it is only send EOI to the master PIC but not the slave PIC.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 9:42 pm 
Offline

Joined: Fri Mar 17, 2017 9:37 pm
Posts: 22
It's strange, I'm still receiving IRQ0 and IRQ1, I'd think if I needed to send EOI to the master PIC I wouldn't receive those ... But, I'll make that change *fingers crossed*.
Yeah, I know I don't handle spurious IRQs, but I'm just using QEMU for now and they don't happen on virtual hardware (right?)


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sat May 27, 2017 9:47 pm 
Offline

Joined: Fri Mar 17, 2017 9:37 pm
Posts: 22
That was it, I needed to send EOI to master and slave for IRQs from the slave PIC. I get my RTC interrupts now. Thanks so much for your time!


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sun May 28, 2017 2:57 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
It's probably not necessary, at least initially, to detect spurious IRQs. It's unlikely that anyone will be using either printer ports or ATA hard disks.

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sun May 28, 2017 4:18 pm 
Offline
Member
Member

Joined: Thu May 19, 2011 5:13 am
Posts: 228
onlyonemac wrote:
It's probably not necessary, at least initially, to detect spurious IRQs. It's unlikely that anyone will be using either printer ports or ATA hard disks.
A spurious interrupt is caused by electrical noise from the activity (usually high activity) of other interrupts and just happens (due to technical reasons)
to end up on IRQ 7 and has little to do with printers.

_________________
Mike Gonta
look and see - many look but few see

https://mikegonta.com


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Sun May 28, 2017 9:50 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

onlyonemac wrote:
It's probably not necessary, at least initially, to detect spurious IRQs. It's unlikely that anyone will be using either printer ports or ATA hard disks.


The problem is that if an OS doesn't support spurious IRQs properly nasty things can happen (depending on how the OS is written). Some OSs could simply crash because IRQ7 or IRQ15 was masked in the PIC and there's no IRQ handler or IDT entry for IRQ7 or IRQ15. Some (most?) OSs would send an EOI for the spurious IRQ where the PIC thinks the EOI is for a completely unrelated IRQ, which can mean that the unrelated IRQ is "ended" before it's ever sent to the CPU (which can cause an unrelated device to get stuck in a "driver waiting for IRQ that never arrives" state where the device no longer works); or can cause an unrelated IRQ to be sent a second time causing further problems.

Fortunately it's easy to support spurious IRQs properly, for example maybe something like:

Code:
IRQ7:
    push eax
    mov al,0x0B           ;al = "read ISR" command
    out 0x20,al           ;Send "read ISR" command
    in al,0x20            ;al = ISR for master PIC
    test al,0x80          ;Is it a spurious IRQ7?
    je .spuriousIRQ7      ; yes
    pop eax
    push dword 7          ;Put "IRQ number" on stack
    jmp commonIRQhandler

.spuriousIRQ7:
    inc dword [spuriousIRQ7counter]
    pop eax
    iret

IRQ15:
    push eax
    mov al,0x0B           ;al = "read ISR" command
    out 0xA0,al           ;Send "read ISR" command
    in al,0xA0            ;al = ISR for slave PIC
    test al,0x80          ;Is it a spurious IRQ15?
    je .spuriousIRQ15     ; yes
    pop eax
    push dword 15         ;Put "IRQ number" on stack
    jmp commonIRQhandler

.spuriousIRQ15:
    inc dword [spuriousIRQ15counter]
    mov al,0x20
    out 0x20,al           ;Send EOI to master PIC (but not slave)
    pop eax
    iret



Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Only receiving one RTC interrupt ...
PostPosted: Mon May 29, 2017 5:07 pm 
Offline

Joined: Fri Mar 17, 2017 9:37 pm
Posts: 22
Thanks, I'll make sure to handle spurious IRQs properly before I figure out why my bootloader is triple faulting on the one real computers I've tried it on ...


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 88 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