From df2327b175ef40835c1938a06c4e60b6c7216d8a Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Oct 2016 19:00:36 -0600 Subject: [PATCH 1/5] Do not throw pcid into background - this prevents ethernetd from exiting if it tries to open network: too early --- drivers/pcid/src/main.rs | 209 +++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 106 deletions(-) diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs index cfc3e6d..7eca6d7 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -8,7 +8,6 @@ use std::env; use std::fs::File; use std::io::Read; use std::process::Command; -use std::thread; use syscall::iopl; use config::Config; @@ -18,131 +17,129 @@ mod config; mod pci; fn main() { - thread::spawn(|| { - let mut config = Config::default(); + let mut config = Config::default(); - let mut args = env::args().skip(1); - if let Some(config_path) = args.next() { - if let Ok(mut config_file) = File::open(&config_path) { - let mut config_data = String::new(); - if let Ok(_) = config_file.read_to_string(&mut config_data) { - config = toml::decode_str(&config_data).unwrap_or(Config::default()); - } + let mut args = env::args().skip(1); + if let Some(config_path) = args.next() { + if let Ok(mut config_file) = File::open(&config_path) { + let mut config_data = String::new(); + if let Ok(_) = config_file.read_to_string(&mut config_data) { + config = toml::decode_str(&config_data).unwrap_or(Config::default()); } } + } - unsafe { iopl(3).unwrap() }; + unsafe { iopl(3).unwrap() }; - println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); + println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); - let pci = Pci::new(); - for bus in pci.buses() { - for dev in bus.devs() { - for func in dev.funcs() { - if let Some(header) = func.header() { - print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", - bus.num, dev.num, func.num, - header.vendor_id, header.device_id, - header.class, header.subclass, header.interface, header.revision); + let pci = Pci::new(); + for bus in pci.buses() { + for dev in bus.devs() { + for func in dev.funcs() { + if let Some(header) = func.header() { + print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", + bus.num, dev.num, func.num, + header.vendor_id, header.device_id, + header.class, header.subclass, header.interface, header.revision); - let pci_class = PciClass::from(header.class); - print!(" {:?}", pci_class); - match pci_class { - PciClass::Storage => match header.subclass { - 0x01 => { - print!(" IDE"); - }, - 0x06 => { - print!(" SATA"); - }, - _ => () + let pci_class = PciClass::from(header.class); + print!(" {:?}", pci_class); + match pci_class { + PciClass::Storage => match header.subclass { + 0x01 => { + print!(" IDE"); }, - PciClass::SerialBus => match header.subclass { - 0x03 => match header.interface { - 0x00 => { - print!(" UHCI"); - }, - 0x10 => { - print!(" OHCI"); - }, - 0x20 => { - print!(" EHCI"); - }, - 0x30 => { - print!(" XHCI"); - }, - _ => () + 0x06 => { + print!(" SATA"); + }, + _ => () + }, + PciClass::SerialBus => match header.subclass { + 0x03 => match header.interface { + 0x00 => { + print!(" UHCI"); + }, + 0x10 => { + print!(" OHCI"); + }, + 0x20 => { + print!(" EHCI"); + }, + 0x30 => { + print!(" XHCI"); }, _ => () }, _ => () + }, + _ => () + } + + for i in 0..header.bars.len() { + match PciBar::from(header.bars[i]) { + PciBar::None => (), + PciBar::Memory(address) => print!(" {}={:>08X}", i, address), + PciBar::Port(address) => print!(" {}={:>04X}", i, address) + } + } + + print!("\n"); + + for driver in config.drivers.iter() { + if let Some(class) = driver.class { + if class != header.class { continue; } } - for i in 0..header.bars.len() { - match PciBar::from(header.bars[i]) { - PciBar::None => (), - PciBar::Memory(address) => print!(" {}={:>08X}", i, address), - PciBar::Port(address) => print!(" {}={:>04X}", i, address) - } + if let Some(subclass) = driver.subclass { + if subclass != header.subclass { continue; } } - print!("\n"); + if let Some(vendor) = driver.vendor { + if vendor != header.vendor_id { continue; } + } - for driver in config.drivers.iter() { - if let Some(class) = driver.class { - if class != header.class { continue; } + if let Some(device) = driver.device { + if device != header.device_id { continue; } + } + + if let Some(ref args) = driver.command { + // Enable bus mastering + unsafe { + let cmd = pci.read(bus.num, dev.num, func.num, 0x04); + pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4); } - if let Some(subclass) = driver.subclass { - if subclass != header.subclass { continue; } - } - - if let Some(vendor) = driver.vendor { - if vendor != header.vendor_id { continue; } - } - - if let Some(device) = driver.device { - if device != header.device_id { continue; } - } - - if let Some(ref args) = driver.command { - // Enable bus mastering - unsafe { - let cmd = pci.read(bus.num, dev.num, func.num, 0x04); - pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4); + let mut args = args.iter(); + if let Some(program) = args.next() { + let mut command = Command::new(program); + for arg in args { + let bar_arg = |i| -> String { + match PciBar::from(header.bars[i]) { + PciBar::None => String::new(), + PciBar::Memory(address) => format!("{:>08X}", address), + PciBar::Port(address) => format!("{:>04X}", address) + } + }; + let arg = match arg.as_str() { + "$BAR0" => bar_arg(0), + "$BAR1" => bar_arg(1), + "$BAR2" => bar_arg(2), + "$BAR3" => bar_arg(3), + "$BAR4" => bar_arg(4), + "$BAR5" => bar_arg(5), + "$IRQ" => format!("{}", header.interrupt_line), + _ => arg.clone() + }; + command.arg(&arg); } - let mut args = args.iter(); - if let Some(program) = args.next() { - let mut command = Command::new(program); - for arg in args { - let bar_arg = |i| -> String { - match PciBar::from(header.bars[i]) { - PciBar::None => String::new(), - PciBar::Memory(address) => format!("{:>08X}", address), - PciBar::Port(address) => format!("{:>04X}", address) - } - }; - let arg = match arg.as_str() { - "$BAR0" => bar_arg(0), - "$BAR1" => bar_arg(1), - "$BAR2" => bar_arg(2), - "$BAR3" => bar_arg(3), - "$BAR4" => bar_arg(4), - "$BAR5" => bar_arg(5), - "$IRQ" => format!("{}", header.interrupt_line), - _ => arg.clone() - }; - command.arg(&arg); - } - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(_status) => (), //println!("pcid: waited for {}: {:?}", line, status.code()), - Err(err) => println!("pcid: failed to wait for {:?}: {}", command, err) - }, - Err(err) => println!("pcid: failed to execute {:?}: {}", command, err) - } + match command.spawn() { + Ok(mut child) => match child.wait() { + Ok(_status) => (), //println!("pcid: waited for {}: {:?}", line, status.code()), + Err(err) => println!("pcid: failed to wait for {:?}: {}", command, err) + }, + Err(err) => println!("pcid: failed to execute {:?}: {}", command, err) } } } @@ -150,5 +147,5 @@ fn main() { } } } - }); + } } From 7e12dea0fe3fcebe1cfc2d3ebf1f63d4a689a44e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Oct 2016 19:13:57 -0600 Subject: [PATCH 2/5] Set mac address on boot --- drivers/e1000d/Cargo.toml | 2 +- drivers/e1000d/src/device.rs | 2 ++ drivers/e1000d/src/main.rs | 1 + drivers/rtl8168d/Cargo.toml | 2 +- drivers/rtl8168d/src/device.rs | 2 ++ drivers/rtl8168d/src/main.rs | 1 + 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/e1000d/Cargo.toml b/drivers/e1000d/Cargo.toml index 6261f65..9a9f2ab 100644 --- a/drivers/e1000d/Cargo.toml +++ b/drivers/e1000d/Cargo.toml @@ -7,5 +7,5 @@ bitflags = "*" dma = { path = "../../crates/dma/" } event = { path = "../../crates/event/" } io = { path = "../../crates/io/" } -spin = "*" +netutils = { path = "../../programs/netutils/" } syscall = { path = "../../syscall/" } diff --git a/drivers/e1000d/src/device.rs b/drivers/e1000d/src/device.rs index 257369c..d8c518b 100644 --- a/drivers/e1000d/src/device.rs +++ b/drivers/e1000d/src/device.rs @@ -1,6 +1,7 @@ use std::{cmp, mem, ptr, slice}; use dma::Dma; +use netutils::setcfg; use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; use syscall::scheme::Scheme; @@ -272,6 +273,7 @@ impl Intel8254x { mac_high as u8, (mac_high >> 8) as u8]; println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", 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])); // // MTA => 0; diff --git a/drivers/e1000d/src/main.rs b/drivers/e1000d/src/main.rs index fbec102..9dbcf79 100644 --- a/drivers/e1000d/src/main.rs +++ b/drivers/e1000d/src/main.rs @@ -2,6 +2,7 @@ extern crate dma; extern crate event; +extern crate netutils; extern crate syscall; use std::cell::RefCell; diff --git a/drivers/rtl8168d/Cargo.toml b/drivers/rtl8168d/Cargo.toml index 394f156..a4243e7 100644 --- a/drivers/rtl8168d/Cargo.toml +++ b/drivers/rtl8168d/Cargo.toml @@ -7,5 +7,5 @@ bitflags = "*" dma = { path = "../../crates/dma/" } event = { path = "../../crates/event/" } io = { path = "../../crates/io/" } -spin = "*" +netutils = { path = "../../programs/netutils/" } syscall = { path = "../../syscall/" } diff --git a/drivers/rtl8168d/src/device.rs b/drivers/rtl8168d/src/device.rs index 4e8f53c..e0b8998 100644 --- a/drivers/rtl8168d/src/device.rs +++ b/drivers/rtl8168d/src/device.rs @@ -2,6 +2,7 @@ use std::mem; use dma::Dma; use io::{Mmio, Io, ReadOnly}; +use netutils::setcfg; use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; use syscall::scheme::SchemeMut; @@ -221,6 +222,7 @@ impl Rtl8168 { mac_high as u8, (mac_high >> 8) as u8]; println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", 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 self.regs.cmd.writef(1 << 4, true); diff --git a/drivers/rtl8168d/src/main.rs b/drivers/rtl8168d/src/main.rs index 4460903..ddfa9e0 100644 --- a/drivers/rtl8168d/src/main.rs +++ b/drivers/rtl8168d/src/main.rs @@ -3,6 +3,7 @@ extern crate dma; extern crate event; extern crate io; +extern crate netutils; extern crate syscall; use std::cell::RefCell; From d71081110e5a72d00dfd5289b110a8dbbbdd3bbd Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Oct 2016 19:16:03 -0600 Subject: [PATCH 3/5] Clear initial net settings, use dhcpd on boot --- filesystem/etc/init.rc | 1 + filesystem/etc/net/dns | 2 +- filesystem/etc/net/ip | 2 +- filesystem/etc/net/ip_router | 2 +- filesystem/etc/net/ip_subnet | 2 +- filesystem/etc/net/mac | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/filesystem/etc/init.rc b/filesystem/etc/init.rc index 91ac88b..56c3752 100644 --- a/filesystem/etc/init.rc +++ b/filesystem/etc/init.rc @@ -7,6 +7,7 @@ ethernetd ipd tcpd udpd +dhcpd -b getty display:2 getty display:3 #orbital display:4 diff --git a/filesystem/etc/net/dns b/filesystem/etc/net/dns index ddc18da..d690dc0 100644 --- a/filesystem/etc/net/dns +++ b/filesystem/etc/net/dns @@ -1 +1 @@ -10.85.85.1 +0.0.0.0 diff --git a/filesystem/etc/net/ip b/filesystem/etc/net/ip index e3be50b..d690dc0 100644 --- a/filesystem/etc/net/ip +++ b/filesystem/etc/net/ip @@ -1 +1 @@ -10.85.85.2 +0.0.0.0 diff --git a/filesystem/etc/net/ip_router b/filesystem/etc/net/ip_router index ddc18da..d690dc0 100644 --- a/filesystem/etc/net/ip_router +++ b/filesystem/etc/net/ip_router @@ -1 +1 @@ -10.85.85.1 +0.0.0.0 diff --git a/filesystem/etc/net/ip_subnet b/filesystem/etc/net/ip_subnet index d30f9e9..d690dc0 100644 --- a/filesystem/etc/net/ip_subnet +++ b/filesystem/etc/net/ip_subnet @@ -1 +1 @@ -255.255.255.0 +0.0.0.0 diff --git a/filesystem/etc/net/mac b/filesystem/etc/net/mac index 6d2055d..f02dd3e 100644 --- a/filesystem/etc/net/mac +++ b/filesystem/etc/net/mac @@ -1 +1 @@ -08.9E.01.DD.45.AF +00.00.00.00.00.00 From 418149bb073b26b108b68e3d9a272388ded2649e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Oct 2016 19:35:23 -0600 Subject: [PATCH 4/5] Debug all driver activity to display:1, use format to avoid line splitting --- Makefile | 6 +++--- drivers/ahcid/src/ahci/hba.rs | 12 ++++++------ drivers/ahcid/src/ahci/mod.rs | 6 ++---- drivers/ahcid/src/main.rs | 2 ++ drivers/e1000d/src/device.rs | 8 ++------ drivers/e1000d/src/main.rs | 4 +++- drivers/pcid/src/main.rs | 31 +++++++++++++++++-------------- drivers/rtl8168d/src/device.rs | 32 ++------------------------------ drivers/rtl8168d/src/main.rs | 6 +++--- filesystem/etc/init.rc | 3 --- initfs/etc/init.rc | 3 +++ 11 files changed, 43 insertions(+), 70 deletions(-) diff --git a/Makefile b/Makefile index 8b1717d..474eece 100644 --- a/Makefile +++ b/Makefile @@ -246,7 +246,9 @@ $(BUILD)/initfs.rs: \ initfs/bin/init \ initfs/bin/ahcid \ initfs/bin/pcid \ + initfs/bin/ps2d \ initfs/bin/redoxfs \ + initfs/bin/vesad \ initfs/etc/** echo 'use collections::BTreeMap;' > $@ echo 'pub fn gen() -> BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> {' >> $@ @@ -321,9 +323,7 @@ filesystem/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib drivers: \ filesystem/bin/e1000d \ - filesystem/bin/ps2d \ - filesystem/bin/rtl8168d \ - filesystem/bin/vesad + filesystem/bin/rtl8168d coreutils: \ filesystem/bin/basename \ diff --git a/drivers/ahcid/src/ahci/hba.rs b/drivers/ahcid/src/ahci/hba.rs index e5ff7ca..5180d3b 100644 --- a/drivers/ahcid/src/ahci/hba.rs +++ b/drivers/ahcid/src/ahci/hba.rs @@ -191,8 +191,8 @@ impl HbaPort { 48 }; - println!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB", - serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048); + print!("{}", format!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB\n", + serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048)); Some(sectors * 512) } else { @@ -230,7 +230,7 @@ impl HbaPort { } 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 { - //println!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, 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); @@ -286,20 +286,20 @@ impl HbaPort { while self.ci.readf(1 << slot) { if self.is.readf(HBA_PORT_IS_TFES) { - println!("IS_TFES set in CI loop TFS {:X} SERR {:X}", self.tfd.read(), self.serr.read()); + print!("{}", format!("IS_TFES set in CI loop TFS {:X} SERR {:X}\n", self.tfd.read(), self.serr.read())); return Err(Error::new(EIO)); } pause(); } if self.is.readf(HBA_PORT_IS_TFES) { - println!("IS_TFES set after CI loop TFS {:X} SERR {:X}", self.tfd.read(), self.serr.read()); + print!("{}", format!("IS_TFES set after CI loop TFS {:X} SERR {:X}\n", self.tfd.read(), self.serr.read())); return Err(Error::new(EIO)); } Ok(sectors * 512) } else { - println!("No Command Slots"); + print!("No Command Slots\n"); Err(Error::new(EIO)) } } diff --git a/drivers/ahcid/src/ahci/mod.rs b/drivers/ahcid/src/ahci/mod.rs index b4e1465..36207f0 100644 --- a/drivers/ahcid/src/ahci/mod.rs +++ b/drivers/ahcid/src/ahci/mod.rs @@ -8,21 +8,19 @@ pub mod fis; pub mod hba; pub fn disks(base: usize, irq: u8) -> Vec { - println!(" + AHCI on: {:X} IRQ: {}", base as usize, irq); - 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) .filter_map(|i| { let port = &mut unsafe { &mut *(base as *mut HbaMem) }.ports[i]; let port_type = port.probe(); - println!("{}: {:?}", i, port_type); + print!("{}", format!("{}: {:?}\n", i, port_type)); match port_type { HbaPortType::SATA => { match Disk::new(i, port) { Ok(disk) => Some(disk), Err(err) => { - println!("{}: {}", i, err); + print!("{}", format!("{}: {}\n", i, err)); None } } diff --git a/drivers/ahcid/src/main.rs b/drivers/ahcid/src/main.rs index f14955c..1c806c9 100644 --- a/drivers/ahcid/src/main.rs +++ b/drivers/ahcid/src/main.rs @@ -27,6 +27,8 @@ fn main() { let irq_str = args.next().expect("ahcid: no irq provided"); let irq = irq_str.parse::().expect("ahcid: failed to parse irq"); + print!("{}", format!(" + AHCI on: {:X} IRQ: {}\n", bar, irq)); + thread::spawn(move || { unsafe { syscall::iopl(3).expect("ahcid: failed to get I/O permission"); diff --git a/drivers/e1000d/src/device.rs b/drivers/e1000d/src/device.rs index d8c518b..8604728 100644 --- a/drivers/e1000d/src/device.rs +++ b/drivers/e1000d/src/device.rs @@ -93,7 +93,6 @@ const TD_DD: u8 = 1; pub struct Intel8254x { base: usize, - irq: u8, receive_buffer: [Dma<[u8; 16384]>; 16], receive_ring: Dma<[Rd; 16]>, transmit_buffer: [Dma<[u8; 16384]>; 16], @@ -201,10 +200,9 @@ impl Scheme for Intel8254x { } impl Intel8254x { - pub unsafe fn new(base: usize, irq: u8) -> Result { + pub unsafe fn new(base: usize) -> Result { let mut module = Intel8254x { base: base, - irq: irq, receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, @@ -245,8 +243,6 @@ impl Intel8254x { } pub unsafe fn init(&mut self) { - println!(" + Intel 8254x on: {:X}, IRQ: {}", self.base, self.irq); - // Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true); self.flag(CTRL, CTRL_LRST, false); @@ -272,7 +268,7 @@ impl Intel8254x { (mac_low >> 24) as u8, mac_high as u8, (mac_high >> 8) as u8]; - println!(" - 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])); // diff --git a/drivers/e1000d/src/main.rs b/drivers/e1000d/src/main.rs index 9dbcf79..a80303b 100644 --- a/drivers/e1000d/src/main.rs +++ b/drivers/e1000d/src/main.rs @@ -27,6 +27,8 @@ fn main() { let irq_str = args.next().expect("e1000d: no irq provided"); let irq = irq_str.parse::().expect("e1000d: failed to parse irq"); + print!("{}", format!(" + E1000 on: {:X}, IRQ: {}\n", bar, irq)); + thread::spawn(move || { unsafe { syscall::iopl(3).expect("e1000d: failed to get I/O permission"); @@ -38,7 +40,7 @@ fn main() { let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") }; { - let device = Arc::new(unsafe { device::Intel8254x::new(address, irq).expect("e1000d: failed to allocate device") }); + let device = Arc::new(unsafe { device::Intel8254x::new(address).expect("e1000d: failed to allocate device") }); let mut event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs index 7eca6d7..b732277 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -31,43 +31,44 @@ fn main() { unsafe { iopl(3).unwrap() }; - println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); + print!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV\n"); let pci = Pci::new(); for bus in pci.buses() { for dev in bus.devs() { for func in dev.funcs() { if let Some(header) = func.header() { - print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", + let pci_class = PciClass::from(header.class); + + let mut string = format!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}", bus.num, dev.num, func.num, header.vendor_id, header.device_id, - header.class, header.subclass, header.interface, header.revision); + header.class, header.subclass, header.interface, header.revision, + pci_class); - let pci_class = PciClass::from(header.class); - print!(" {:?}", pci_class); match pci_class { PciClass::Storage => match header.subclass { 0x01 => { - print!(" IDE"); + string.push_str(" IDE"); }, 0x06 => { - print!(" SATA"); + string.push_str(" SATA"); }, _ => () }, PciClass::SerialBus => match header.subclass { 0x03 => match header.interface { 0x00 => { - print!(" UHCI"); + string.push_str(" UHCI"); }, 0x10 => { - print!(" OHCI"); + string.push_str(" OHCI"); }, 0x20 => { - print!(" EHCI"); + string.push_str(" EHCI"); }, 0x30 => { - print!(" XHCI"); + string.push_str(" XHCI"); }, _ => () }, @@ -79,12 +80,14 @@ fn main() { for i in 0..header.bars.len() { match PciBar::from(header.bars[i]) { PciBar::None => (), - PciBar::Memory(address) => print!(" {}={:>08X}", i, address), - PciBar::Port(address) => print!(" {}={:>04X}", i, address) + PciBar::Memory(address) => string.push_str(&format!(" {}={:>08X}", i, address)), + PciBar::Port(address) => string.push_str(&format!(" {}={:>04X}", i, address)) } } - print!("\n"); + string.push('\n'); + + print!("{}", string); for driver in config.drivers.iter() { if let Some(class) = driver.class { diff --git a/drivers/rtl8168d/src/device.rs b/drivers/rtl8168d/src/device.rs index e0b8998..f270c1a 100644 --- a/drivers/rtl8168d/src/device.rs +++ b/drivers/rtl8168d/src/device.rs @@ -66,7 +66,6 @@ struct Td { pub struct Rtl8168 { regs: &'static mut Regs, - irq: u8, receive_buffer: [Dma<[u8; 0x1FF8]>; 16], receive_ring: Dma<[Rd; 16]>, transmit_buffer: [Dma<[u8; 7552]>; 16], @@ -89,13 +88,10 @@ impl SchemeMut for Rtl8168 { } fn read(&mut self, _id: usize, buf: &mut [u8]) -> Result { - println!("Try Receive {}", buf.len()); for (rd_i, rd) in self.receive_ring.iter_mut().enumerate() { if ! rd.ctrl.readf(OWN) { let rd_len = rd.ctrl.read() & 0x3FFF; - println!("Receive {}: {}", rd_i, rd_len); - let data = &self.receive_buffer[rd_i as usize]; let mut i = 0; @@ -115,11 +111,9 @@ impl SchemeMut for Rtl8168 { } fn write(&mut self, _id: usize, buf: &[u8]) -> Result { - println!("Try Transmit {}", buf.len()); loop { for (td_i, td) in self.transmit_ring.iter_mut().enumerate() { if ! td.ctrl.readf(OWN) { - println!("Transmit {}: Setup {}", td_i, buf.len()); let mut data = &mut self.transmit_buffer[td_i as usize]; @@ -129,21 +123,15 @@ impl SchemeMut for Rtl8168 { i += 1; } - println!("Transmit {}: Before: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read()); - let eor = td.ctrl.read() & EOR; td.ctrl.write(OWN | eor | FS | LS | i as u32); self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet - println!("Transmit {}: During: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read()); - while self.regs.tppoll.readf(1 << 6) { unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } } - println!("Transmit {}: After: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read()); - return Ok(i); } } @@ -166,7 +154,7 @@ impl SchemeMut for Rtl8168 { } impl Rtl8168 { - pub unsafe fn new(base: usize, irq: u8) -> Result { + pub unsafe fn new(base: usize) -> Result { assert_eq!(mem::size_of::(), 256); let regs = &mut *(base as *mut Regs); @@ -182,7 +170,6 @@ impl Rtl8168 { let mut module = Rtl8168 { regs: regs, - irq: irq, receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, @@ -211,8 +198,6 @@ impl Rtl8168 { } pub unsafe fn init(&mut self) { - println!(" + RTL8168 on: {:X}, IRQ: {}", self.regs as *mut Regs as usize, self.irq); - let mac_low = self.regs.mac[0].read(); let mac_high = self.regs.mac[1].read(); let mac = [mac_low as u8, @@ -221,7 +206,7 @@ impl Rtl8168 { (mac_low >> 24) as u8, mac_high as u8, (mac_high >> 8) as u8]; - println!(" - 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}", 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 @@ -294,18 +279,5 @@ impl Rtl8168 { // Lock config self.regs.cmd_9346.write(0); - - println!(" - Ready CMD {:X} ISR {:X} IMR {:X} PHYS {:X} RMS {:X} MTPS {:X} RCR {:X} TCR {:X} RDSAR {:X} TNPDS {:X} THPDS {:X}", - self.regs.cmd.read(), - self.regs.isr.read(), - self.regs.imr.read(), - self.regs.phys_sts.read(), - self.regs.rms.read(), - self.regs.mtps.read(), - self.regs.rcr.read(), - self.regs.tcr.read(), - self.regs.rdsar[0].read(), - self.regs.tnpds[0].read(), - self.regs.thpds[0].read()); } } diff --git a/drivers/rtl8168d/src/main.rs b/drivers/rtl8168d/src/main.rs index ddfa9e0..5dbf703 100644 --- a/drivers/rtl8168d/src/main.rs +++ b/drivers/rtl8168d/src/main.rs @@ -28,6 +28,8 @@ 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)); + thread::spawn(move || { unsafe { syscall::iopl(3).expect("rtl8168d: failed to get I/O permission"); @@ -41,7 +43,7 @@ fn main() { let address = unsafe { syscall::physmap(bar, 256, MAP_WRITE).expect("rtl8168d: failed to map address") }; { - let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address, irq).expect("rtl8168d: failed to allocate device") })); + let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address).expect("rtl8168d: failed to allocate device") })); let mut event_queue = EventQueue::::new().expect("rtl8168d: failed to create event queue"); @@ -56,8 +58,6 @@ fn main() { let isr = unsafe { device_irq.borrow_mut().irq() }; if isr != 0 { - println!("RTL8168 ISR {:X}", isr); - irq_file.write(&mut irq)?; let mut todo = todo_irq.borrow_mut(); diff --git a/filesystem/etc/init.rc b/filesystem/etc/init.rc index 56c3752..ed78e17 100644 --- a/filesystem/etc/init.rc +++ b/filesystem/etc/init.rc @@ -1,6 +1,3 @@ -vesad T T T G -stdio display:1 -ps2d initfs:bin/pcid /etc/pcid.toml ethernetd #arpd diff --git a/initfs/etc/init.rc b/initfs/etc/init.rc index b20a62b..5a34dd2 100644 --- a/initfs/etc/init.rc +++ b/initfs/etc/init.rc @@ -1,3 +1,6 @@ +initfs:bin/vesad T T T G +stdio display:1 +initfs:bin/ps2d initfs:bin/pcid initfs:etc/pcid.toml initfs:bin/redoxfs disk:0 cd file: From e66acb949b311556c2a2ee0fec8ef1b84389eb3f Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 22 Oct 2016 22:23:09 -0600 Subject: [PATCH 5/5] More debugging of writes in ahcid --- drivers/ahcid/src/ahci/hba.rs | 150 ++++++++++++++++++++------------- drivers/ahcid/src/ahci/mod.rs | 3 +- drivers/ahcid/src/main.rs | 2 +- drivers/rtl8168d/src/device.rs | 2 +- drivers/rtl8168d/src/main.rs | 2 +- 5 files changed, 97 insertions(+), 62 deletions(-) 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 {