From c1b429267551da85c39b1ccb34152e01cc274dd6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Feb 2020 19:46:28 -0700 Subject: [PATCH] Improve ahcid interrupt handling --- ahcid/src/ahci/hba.rs | 10 +++++----- ahcid/src/main.rs | 2 +- ahcid/src/scheme.rs | 28 ++++++++++++++-------------- ihdad/src/hda/device.rs | 4 +--- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/ahcid/src/ahci/hba.rs b/ahcid/src/ahci/hba.rs index fec4e0c574..86764ec767 100644 --- a/ahcid/src/ahci/hba.rs +++ b/ahcid/src/ahci/hba.rs @@ -1,6 +1,6 @@ use std::mem::size_of; use std::ops::DerefMut; -use std::{ptr, u32, thread}; +use std::{ptr, u32}; use syscall::io::{Dma, Io, Mmio}; use syscall::error::{Error, Result, EIO}; @@ -75,7 +75,7 @@ impl HbaPort { pub fn start(&mut self) { while self.cmd.readf(HBA_PORT_CMD_CR) { - thread::yield_now(); + unsafe { asm!("pause"); } } self.cmd.writef(HBA_PORT_CMD_FRE | HBA_PORT_CMD_ST, true); @@ -85,7 +85,7 @@ impl HbaPort { self.cmd.writef(HBA_PORT_CMD_ST, false); while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) { - thread::yield_now(); + unsafe { asm!("pause"); } } self.cmd.writef(HBA_PORT_CMD_FRE, false); @@ -305,7 +305,7 @@ impl HbaPort { } while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) { - thread::yield_now(); + unsafe { asm!("pause"); } } self.ci.writef(1 << slot, true); @@ -325,7 +325,7 @@ impl HbaPort { pub fn ata_stop(&mut self, slot: u32) -> Result<()> { while self.ata_running(slot) { - thread::yield_now(); + unsafe { asm!("pause"); } } self.stop(); diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index 5e261cc2d0..513cf81a57 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -1,4 +1,4 @@ -//#![deny(warnings)] +#![feature(asm)] extern crate syscall; extern crate byteorder; diff --git a/ahcid/src/scheme.rs b/ahcid/src/scheme.rs index f2e523c37a..48d0721d61 100644 --- a/ahcid/src/scheme.rs +++ b/ahcid/src/scheme.rs @@ -95,7 +95,7 @@ impl DiskWrapper { impl std::ops::Deref for DiskWrapper { type Target = dyn Disk; - + fn deref(&self) -> &Self::Target { &*self.disk } @@ -128,22 +128,22 @@ impl DiskScheme { impl DiskScheme { pub fn irq(&mut self) -> bool { - let pi = self.hba_mem.pi.read(); let is = self.hba_mem.is.read(); - let pi_is = pi & is; - - for i in 0..self.hba_mem.ports.len() { - if pi_is & 1 << i > 0 { - let port = &mut self.hba_mem.ports[i]; - let is = port.is.read(); - //println!("IRQ Port {}: {:#>08x}", i, is); - //TODO: Handle requests for only this port here - port.is.write(is); + if is > 0 { + let pi = self.hba_mem.pi.read(); + let pi_is = pi & is; + for i in 0..self.hba_mem.ports.len() { + if pi_is & 1 << i > 0 { + let port = &mut self.hba_mem.ports[i]; + let is = port.is.read(); + port.is.write(is); + } } + self.hba_mem.is.write(is); + true + } else { + false } - - self.hba_mem.is.write(is); - is != 0 } } diff --git a/ihdad/src/hda/device.rs b/ihdad/src/hda/device.rs index ae77fe5b98..78a8e61062 100755 --- a/ihdad/src/hda/device.rs +++ b/ihdad/src/hda/device.rs @@ -764,18 +764,16 @@ impl IntelHDA { pub fn handle_interrupts(&mut self) -> bool { let intsts = self.regs.intsts.read(); - let sis = intsts & 0x3FFFFFFF; - //print!("IHDA INTSTS: {:08X}\n", intsts); if ((intsts >> 31) & 1) == 1 { // Global Interrupt Status if ((intsts >> 30) & 1) == 1 { // Controller Interrupt Status self.handle_controller_interrupt(); } + let sis = intsts & 0x3FFFFFFF; if sis != 0 { self.handle_stream_interrupts(sis); } } - intsts != 0 }