diff --git a/drivers/ahcid/src/ahci/hba.rs b/drivers/ahcid/src/ahci/hba.rs index 5180d3b..e64afa3 100644 --- a/drivers/ahcid/src/ahci/hba.rs +++ b/drivers/ahcid/src/ahci/hba.rs @@ -18,7 +18,7 @@ const HBA_PORT_CMD_CR: u32 = 1 << 15; const HBA_PORT_CMD_FR: u32 = 1 << 14; const HBA_PORT_CMD_FRE: u32 = 1 << 4; const HBA_PORT_CMD_ST: u32 = 1; -const HBA_PORT_IS_TFES: u32 = 1 << 30; +const HBA_PORT_IS_ERR: u32 = 1 << 30 | 1 << 29 | 1 << 28 | 1 << 27; const HBA_SSTS_PRESENT: u32 = 0x3; const HBA_SIG_ATA: u32 = 0x00000101; const HBA_SIG_ATAPI: u32 = 0xEB140101; @@ -41,12 +41,12 @@ pub enum HbaPortType { #[repr(packed)] pub struct HbaPort { - pub clb: Mmio, // 0x00, command list base address, 1K-byte aligned - pub fb: Mmio, // 0x08, FIS base address, 256-byte aligned + pub clb: [Mmio; 2], // 0x00, command list base address, 1K-byte aligned + pub fb: [Mmio; 2], // 0x08, FIS base address, 256-byte aligned pub is: Mmio, // 0x10, interrupt status pub ie: Mmio, // 0x14, interrupt enable pub cmd: Mmio, // 0x18, command and status - pub rsv0: Mmio, // 0x1C, Reserved + pub _rsv0: Mmio, // 0x1C, Reserved pub tfd: Mmio, // 0x20, task file data pub sig: Mmio, // 0x24, signature pub ssts: Mmio, // 0x28, SATA status (SCR0:SStatus) @@ -56,7 +56,7 @@ pub struct HbaPort { pub ci: Mmio, // 0x38, command issue pub sntf: Mmio, // 0x3C, SATA notification (SCR4:SNotification) pub fbs: Mmio, // 0x40, FIS-based switch control - pub rsv1: [Mmio; 11], // 0x44 ~ 0x6F, Reserved + pub _rsv1: [Mmio; 11], // 0x44 ~ 0x6F, Reserved pub vendor: [Mmio; 4], // 0x70 ~ 0x7F, vendor specific } @@ -76,21 +76,54 @@ impl HbaPort { } } + pub fn start(&mut self) { + while self.cmd.readf(HBA_PORT_CMD_CR) { + pause(); + } + + self.cmd.writef(HBA_PORT_CMD_FRE | HBA_PORT_CMD_ST, true); + } + + pub fn stop(&mut self) { + self.cmd.writef(HBA_PORT_CMD_ST, false); + + while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) { + pause(); + } + + self.cmd.writef(HBA_PORT_CMD_FRE, false); + } + + pub fn slot(&self) -> Option { + let slots = self.sact.read() | self.ci.read(); + for i in 0..32 { + if slots & 1 << i == 0 { + return Some(i); + } + } + None + } + pub fn init(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], fb: &mut Dma<[u8; 256]>) { self.stop(); - self.clb.write(clb.physical() as u64); - self.fb.write(fb.physical() as u64); - let is = self.is.read(); - self.is.write(is); - for i in 0..32 { let cmdheader = &mut clb[i]; cmdheader.ctba.write(ctbas[i].physical() as u64); cmdheader.prdtl.write(0); } - self.start(); + self.clb[0].write(clb.physical() as u32); + self.clb[1].write((clb.physical() >> 32) as u32); + self.fb[0].write(fb.physical() as u32); + self.fb[1].write((fb.physical() >> 32) as u32); + let is = self.is.read(); + self.is.write(is); + self.ie.write(0); + let serr = self.serr.read(); + self.serr.write(serr); + + print!("{}", format!(" - AHCI init {:X}\n", self.cmd.read())); } pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32]) -> Option { @@ -129,14 +162,16 @@ impl HbaPort { self.ci.writef(1 << slot, true); - while self.ci.readf(1 << slot) { - if self.is.readf(HBA_PORT_IS_TFES) { - return None; - } + self.start(); + + while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 { pause(); } - if self.is.readf(HBA_PORT_IS_TFES) { + self.stop(); + + if self.is.read() & HBA_PORT_IS_ERR != 0 { + print!("{}", format!("ERROR IS {:X} TFD {:X} SERR {:X}\n", self.is.read(), self.tfd.read(), self.serr.read())); return None; } @@ -200,43 +235,20 @@ impl HbaPort { } } - pub fn start(&mut self) { - while self.cmd.readf(HBA_PORT_CMD_CR) { - pause(); - } - - self.cmd.writef(HBA_PORT_CMD_FRE, true); - self.cmd.writef(HBA_PORT_CMD_ST, true); - } - - pub fn stop(&mut self) { - self.cmd.writef(HBA_PORT_CMD_ST, false); - - while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) { - pause(); - } - - self.cmd.writef(HBA_PORT_CMD_FRE, false); - } - - pub fn slot(&self) -> Option { - let slots = self.sact.read() | self.ci.read(); - for i in 0..32 { - if slots & 1 << i == 0 { - return Some(i); - } - } - None - } - pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result { - //print!("{}", format!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}\n", (self as *mut HbaPort) as usize, block, sectors, write)); + if write { + print!("{}", format!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}\n", (self as *mut HbaPort) as usize, block, sectors, write)); + } assert!(sectors > 0 && sectors < 256); self.is.write(u32::MAX); if let Some(slot) = self.slot() { + if write { + print!("{}", format!("SLOT {}\n", slot)); + } + let cmdheader = &mut clb[slot as usize]; cmdheader.cfl.write(((size_of::() / size_of::()) as u8)); @@ -278,25 +290,40 @@ impl HbaPort { cmdfis.counth.write((sectors >> 8) as u8); } + if write { + print!("WAIT ATA_DEV_BUSY | ATA_DEV_DRQ\n"); + } while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) { pause(); } + if write { + print!("{}", format!("WRITE CI {:X} in {:X}\n", 1 << slot, self.ci.read())); + } self.ci.writef(1 << slot, true); - while self.ci.readf(1 << slot) { - if self.is.readf(HBA_PORT_IS_TFES) { - print!("{}", format!("IS_TFES set in CI loop TFS {:X} SERR {:X}\n", self.tfd.read(), self.serr.read())); - return Err(Error::new(EIO)); - } + self.start(); + + if write { + print!("{}", format!("WAIT CI {:X} in {:X}\n", 1 << slot, self.ci.read())); + } + while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 { pause(); + if write { + print!("{}", format!("WAIT CI {:X} TFD {:X} IS {:X} CMD {:X} SERR {:X}\n", self.ci.read(), self.tfd.read(), self.is.read(), self.cmd.read(), self.serr.read())); + } } - if self.is.readf(HBA_PORT_IS_TFES) { - print!("{}", format!("IS_TFES set after CI loop TFS {:X} SERR {:X}\n", self.tfd.read(), self.serr.read())); + self.stop(); + + if self.is.read() & HBA_PORT_IS_ERR != 0 { + print!("{}", format!("ERROR IS {:X} TFD {:X} SERR {:X}\n", self.is.read(), self.tfd.read(), self.serr.read())); return Err(Error::new(EIO)); } + if write { + print!("{}", format!("SUCCESS {}\n", sectors)); + } Ok(sectors * 512) } else { print!("No Command Slots\n"); @@ -318,24 +345,31 @@ pub struct HbaMem { pub em_ctl: Mmio, // 0x20, Enclosure management control pub cap2: Mmio, // 0x24, Host capabilities extended pub bohc: Mmio, // 0x28, BIOS/OS handoff control and status - pub rsv: [Mmio; 116], // 0x2C - 0x9F, Reserved + pub _rsv: [Mmio; 116], // 0x2C - 0x9F, Reserved pub vendor: [Mmio; 96], // 0xA0 - 0xFF, Vendor specific registers pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers } impl HbaMem { - pub fn reset(&mut self) { + pub fn init(&mut self) { + /* self.ghc.writef(1, true); while self.ghc.readf(1) { pause(); } + */ + self.ghc.write(1 << 31 | 1 << 1); + + print!("{}", format!(" - AHCI CAP {:X} GHC {:X} IS {:X} PI {:X} VS {:X} CAP2 {:X} BOHC {:X}", + self.cap.read(), self.ghc.read(), self.is.read(), self.pi.read(), + self.vs.read(), self.cap2.read(), self.bohc.read())); } } #[repr(packed)] pub struct HbaPrdtEntry { dba: Mmio, // Data base address - rsv0: Mmio, // Reserved + _rsv0: Mmio, // Reserved dbc: Mmio, // Byte count, 4M max, interrupt = 1 } @@ -348,7 +382,7 @@ pub struct HbaCmdTable { acmd: [Mmio; 16], // ATAPI command, 12 or 16 bytes // 0x50 - rsv: [Mmio; 48], // Reserved + _rsv: [Mmio; 48], // Reserved // 0x80 prdt_entry: [HbaPrdtEntry; 65536], // Physical region descriptor table entries, 0 ~ 65535 @@ -369,5 +403,5 @@ pub struct HbaCmdHeader { ctba: Mmio, // Command table descriptor base address // DW4 - 7 - rsv1: [Mmio; 4], // Reserved + _rsv1: [Mmio; 4], // Reserved } diff --git a/drivers/ahcid/src/ahci/mod.rs b/drivers/ahcid/src/ahci/mod.rs index 36207f0..90f334a 100644 --- a/drivers/ahcid/src/ahci/mod.rs +++ b/drivers/ahcid/src/ahci/mod.rs @@ -7,7 +7,8 @@ pub mod disk; pub mod fis; pub mod hba; -pub fn disks(base: usize, irq: u8) -> Vec { +pub fn disks(base: usize) -> Vec { + unsafe { &mut *(base as *mut HbaMem) }.init(); let pi = unsafe { &mut *(base as *mut HbaMem) }.pi.read(); let ret: Vec = (0..32) .filter(|&i| pi & 1 << i as i32 == 1 << i as i32) diff --git a/drivers/ahcid/src/main.rs b/drivers/ahcid/src/main.rs index 1c806c9..e7aa816 100644 --- a/drivers/ahcid/src/main.rs +++ b/drivers/ahcid/src/main.rs @@ -47,7 +47,7 @@ fn main() { let mut event_file = File::open("event:").expect("ahcid: failed to open event file"); - let scheme = DiskScheme::new(ahci::disks(address, irq)); + let scheme = DiskScheme::new(ahci::disks(address)); loop { let mut event = Event::default(); event_file.read(&mut event).expect("ahcid: failed to read event file"); diff --git a/drivers/rtl8168d/src/device.rs b/drivers/rtl8168d/src/device.rs index f270c1a..6bf3613 100644 --- a/drivers/rtl8168d/src/device.rs +++ b/drivers/rtl8168d/src/device.rs @@ -206,7 +206,7 @@ impl Rtl8168 { (mac_low >> 24) as u8, mac_high as u8, (mac_high >> 8) as u8]; - print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); + print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); let _ = setcfg("mac", &format!("{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value diff --git a/drivers/rtl8168d/src/main.rs b/drivers/rtl8168d/src/main.rs index 5dbf703..83a02e9 100644 --- a/drivers/rtl8168d/src/main.rs +++ b/drivers/rtl8168d/src/main.rs @@ -28,7 +28,7 @@ fn main() { let irq_str = args.next().expect("rtl8168d: no irq provided"); let irq = irq_str.parse::().expect("rtl8168d: failed to parse irq"); - print!("{}", format!(" + RTL8168 on: {:X}, IRQ: {}", bar, irq)); + print!("{}", format!(" + RTL8168 on: {:X}, IRQ: {}\n", bar, irq)); thread::spawn(move || { unsafe {