Skip to content
Snippets Groups Projects
Verified Commit 11654456 authored by Jacob Lorentzon's avatar Jacob Lorentzon
Browse files

Add spurious IRQ handling, using a visible counter.

parent dd4e82f4
No related branches found
No related tags found
2 merge requests!120WIP: Separate IDT for each processor,!119Add spurious IRQ handling, using a visible counter.
......@@ -70,4 +70,9 @@ impl Pic {
mask &= !(1 << irq);
self.data.write(mask);
}
/// A bitmap of all currently servicing IRQs. Spurious IRQs will not have this bit set
pub fn isr(&mut self) -> u8 {
self.cmd.write(0x0A);
self.cmd.read() // note that cmd is read, rather than data
}
}
use core::sync::atomic::{AtomicUsize, Ordering};
use alloc::vec::Vec;
use crate::context::timeout;
use crate::device::{local_apic, ioapic, pic};
use crate::device::serial::{COM1, COM2};
......@@ -53,6 +55,27 @@ pub enum IrqMethod {
Apic = 1,
}
static SPURIOUS_COUNT_IRQ7: AtomicUsize = AtomicUsize::new(0);
static SPURIOUS_COUNT_IRQ15: AtomicUsize = AtomicUsize::new(0);
pub fn spurious_count_irq7() -> usize {
SPURIOUS_COUNT_IRQ7.load(Ordering::Relaxed)
}
pub fn spurious_count_irq15() -> usize {
SPURIOUS_COUNT_IRQ15.load(Ordering::Relaxed)
}
pub fn spurious_count() -> usize {
spurious_count_irq7() + spurious_count_irq15()
}
pub fn spurious_irq_resource() -> syscall::Result<Vec<u8>> {
match irq_method() {
IrqMethod::Apic => Ok(Vec::from(&b"(not implemented for APIC yet)"[..])),
IrqMethod::Pic => {
Ok(format!("{}\tIRQ7\n{}\tIRQ15\n{}\ttotal\n", spurious_count_irq7(), spurious_count_irq15(), spurious_count()).into_bytes())
}
}
}
static IRQ_METHOD: AtomicUsize = AtomicUsize::new(IrqMethod::Pic as usize);
pub fn set_irq_method(method: IrqMethod) {
......@@ -120,16 +143,8 @@ unsafe fn pic_eoi(irq: u8) {
if irq >= 8 {
pic::MASTER.ack();
if irq == 15 {
//TODO: check spurious
return;
}
pic::SLAVE.ack();
} else {
if irq == 7 {
//TODO: check spurious
return;
}
pic::MASTER.ack();
}
}
......@@ -213,6 +228,11 @@ interrupt!(floppy, {
});
interrupt!(lpt1, {
if pic::MASTER.isr() & (1 << 7) == 0 {
// the IRQ was spurious, ignore it but increment a counter.
SPURIOUS_COUNT_IRQ7.fetch_add(1, Ordering::Relaxed);
return;
}
trigger(7);
eoi(7);
});
......@@ -253,6 +273,11 @@ interrupt!(ata1, {
});
interrupt!(ata2, {
if pic::SLAVE.isr() & (1 << 7) == 0 {
SPURIOUS_COUNT_IRQ15.fetch_add(1, Ordering::Relaxed);
pic::MASTER.ack();
return
}
trigger(15);
eoi(15);
});
......
......@@ -9,6 +9,7 @@ use crate::syscall::data::Stat;
use crate::syscall::error::{Error, EBADF, EINVAL, ENOENT, Result};
use crate::syscall::flag::{MODE_DIR, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
use crate::syscall::scheme::Scheme;
use crate::arch::interrupt::irq;
mod block;
mod context;
......@@ -51,6 +52,7 @@ impl SysScheme {
files.insert(b"scheme_num", Box::new(scheme_num::resource));
files.insert(b"syscall", Box::new(syscall::resource));
files.insert(b"uname", Box::new(uname::resource));
files.insert(b"spurious_irq", Box::new(irq::spurious_irq_resource));
SysScheme {
next_id: AtomicUsize::new(0),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment