Add spurious IRQ handling, using a visible counter.

This commit is contained in:
4lDO2
2020-04-20 20:52:31 +02:00
parent dd4e82f4ce
commit 1165445602
3 changed files with 40 additions and 8 deletions

View File

@@ -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
}
}

View File

@@ -1,5 +1,7 @@
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);
});

View File

@@ -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),