diff --git a/Cargo.lock b/Cargo.lock index 7e3c14e7d4..f27f4203eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,7 +355,7 @@ dependencies = [ "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -729,9 +729,11 @@ version = "0.1.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "block-io-wrapper 0.1.0", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "partitionlib 0.1.0 (git+https://gitlab.redox-os.org/redox-os/partitionlib.git)", + "pcid 0.1.0", + "redox-log 0.1.0 (git+https://gitlab.redox-os.org/redox-os/redox-log.git?tag=v0.1.0)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -860,7 +862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pin-utils" -version = "0.1.0-alpha.4" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1799,7 +1801,7 @@ dependencies = [ "checksum pbr 1.0.2 (git+https://github.com/a8m/pb)" = "" "checksum pbr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4403eb718d70c03ee279e51737782902c68cca01e870a33b6a2f9dfb50b9cd83" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" +"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" "checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" "checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" "checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" diff --git a/initfs.toml b/initfs.toml index 6861491750..9d95b91f9f 100644 --- a/initfs.toml +++ b/initfs.toml @@ -28,6 +28,7 @@ name = "NVME storage" class = 1 subclass = 8 command = ["nvmed", "$NAME", "$BAR0", "$BARSIZE0", "$IRQ"] +use_channel = true # vboxd [[drivers]] @@ -43,5 +44,5 @@ name = "XHCI" class = 12 subclass = 3 interface = 48 -command = ["xhcid", "$NAME", "$BAR0", "$IRQ"] -channel_name = "pcid-xhcid" +command = ["xhcid"] +use_channel = true diff --git a/nvmed/Cargo.toml b/nvmed/Cargo.toml index b0bbfee4b2..92a180f585 100644 --- a/nvmed/Cargo.toml +++ b/nvmed/Cargo.toml @@ -5,7 +5,10 @@ edition = "2018" [dependencies] bitflags = "0.7" -spin = "0.4" +log = "0.4" +redox-log = { git = "https://gitlab.redox-os.org/redox-os/redox-log.git", tag = "v0.1.0" } redox_syscall = "0.1" partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" } block-io-wrapper = { path = "../block-io-wrapper" } + +pcid = { path = "../pcid" } diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index fb37c0f6b9..7e6178840a 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -1,16 +1,14 @@ -#![feature(asm)] - -extern crate bitflags; -extern crate spin; -extern crate syscall; - use std::{env, usize}; use std::fs::File; use std::io::{ErrorKind, Read, Write}; use std::os::unix::io::{RawFd, FromRawFd}; +use pcid_interface::{PcidServerHandle, PciBar}; + use syscall::{EVENT_READ, PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Event, Packet, Result, SchemeBlockMut}; +use log::{debug, error, info, warn, trace}; + use self::nvme::Nvme; use self::scheme::DiskScheme; @@ -18,108 +16,109 @@ mod nvme; mod scheme; fn main() { - let mut args = env::args().skip(1); + // Daemonize + if unsafe { syscall::clone(0).unwrap() } != 0 { + return; + } - let mut name = args.next().expect("nvmed: no name provided"); + let mut pcid_handle = PcidServerHandle::connect_default().expect("nvmed: failed to setup channel to pcid"); + let pci_config = pcid_handle.fetch_config().expect("nvmed: failed to fetch config"); + + let bar = match pci_config.func.bars[0] { + PciBar::Memory(mem) => mem, + other => panic!("received a non-memory BAR ({:?})", other), + }; + let bar_size = pci_config.func.bar_sizes[0]; + let irq = pci_config.func.legacy_interrupt_line; + + let mut name = pci_config.func.name(); name.push_str("_nvme"); - let bar_str = args.next().expect("nvmed: no address provided"); - let bar = usize::from_str_radix(&bar_str, 16).expect("nvmed: failed to parse address"); + info!("NVME PCI CONFIG: {:?}", pci_config); - let bar_size_str = args.next().expect("nvmed: no address size provided"); - let bar_size = usize::from_str_radix(&bar_size_str, 16).expect("nvmed: failed to parse address size"); + let address = unsafe { + syscall::physmap(bar as usize, bar_size as usize, PHYSMAP_WRITE | PHYSMAP_NO_CACHE) + .expect("nvmed: failed to map address") + }; + { + let event_fd = syscall::open("event:", syscall::O_RDWR | syscall::O_CLOEXEC) + .expect("nvmed: failed to open event queue"); + let mut event_file = unsafe { File::from_raw_fd(event_fd as RawFd) }; - let irq_str = args.next().expect("nvmed: no irq provided"); - let irq = irq_str.parse::().expect("nvmed: failed to parse irq"); + let irq_fd = syscall::open( + &format!("irq:{}", irq), + syscall::O_RDWR | syscall::O_NONBLOCK | syscall::O_CLOEXEC + ).expect("nvmed: failed to open irq file"); + syscall::write(event_fd, &syscall::Event { + id: irq_fd, + flags: syscall::EVENT_READ, + data: 0, + }).expect("nvmed: failed to watch irq file events"); + let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; - print!("{}", format!(" + NVME {} on: {:X} size: {} IRQ: {}\n", name, bar, bar_size, irq)); + let scheme_name = format!("disk/{}", name); + let socket_fd = syscall::open( + &format!(":{}", scheme_name), + syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK | syscall::O_CLOEXEC + ).expect("nvmed: failed to create disk scheme"); + syscall::write(event_fd, &syscall::Event { + id: socket_fd, + flags: syscall::EVENT_READ, + data: 1, + }).expect("nvmed: failed to watch disk scheme events"); + let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) }; - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let address = unsafe { - syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE) - .expect("nvmed: failed to map address") - }; - { - let event_fd = syscall::open("event:", syscall::O_RDWR | syscall::O_CLOEXEC) - .expect("nvmed: failed to open event queue"); - let mut event_file = unsafe { File::from_raw_fd(event_fd as RawFd) }; + syscall::setrens(0, 0).expect("nvmed: failed to enter null namespace"); - let irq_fd = syscall::open( - &format!("irq:{}", irq), - syscall::O_RDWR | syscall::O_NONBLOCK | syscall::O_CLOEXEC - ).expect("nvmed: failed to open irq file"); - syscall::write(event_fd, &syscall::Event { - id: irq_fd, - flags: syscall::EVENT_READ, - data: 0, - }).expect("nvmed: failed to watch irq file events"); - let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; - - let scheme_name = format!("disk/{}", name); - let socket_fd = syscall::open( - &format!(":{}", scheme_name), - syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK | syscall::O_CLOEXEC - ).expect("nvmed: failed to create disk scheme"); - syscall::write(event_fd, &syscall::Event { - id: socket_fd, - flags: syscall::EVENT_READ, - data: 1, - }).expect("nvmed: failed to watch disk scheme events"); - let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) }; - - syscall::setrens(0, 0).expect("nvmed: failed to enter null namespace"); - - let mut nvme = Nvme::new(address).expect("nvmed: failed to allocate driver data"); - let namespaces = unsafe { nvme.init() }; - let mut scheme = DiskScheme::new(scheme_name, nvme, namespaces); - let mut todo = Vec::new(); - 'events: loop { - let mut event = Event::default(); - if event_file.read(&mut event).expect("nvmed: failed to read event queue") == 0 { - break; - } - - match event.data { - 0 => { - let mut irq = [0; 8]; - if irq_file.read(&mut irq).expect("nvmed: failed to read irq file") >= irq.len() { - if scheme.irq() { - irq_file.write(&irq).expect("nvmed: failed to write irq file"); - } - } - }, - 1 => loop { - let mut packet = Packet::default(); - match socket_file.read(&mut packet) { - Ok(0) => break 'events, - Ok(_) => (), - Err(err) => match err.kind() { - ErrorKind::WouldBlock => break, - _ => Err(err).expect("nvmed: failed to read disk scheme"), - } - } - todo.push(packet); - }, - unknown => { - panic!("nvmed: unknown event data {}", unknown); - }, - } - - let mut i = 0; - while i < todo.len() { - if let Some(a) = scheme.handle(&todo[i]) { - let mut packet = todo.remove(i); - packet.a = a; - socket_file.write(&packet).expect("nvmed: failed to write disk scheme"); - } else { - i += 1; - } - } + let mut nvme = Nvme::new(address).expect("nvmed: failed to allocate driver data"); + let namespaces = unsafe { nvme.init() }; + let mut scheme = DiskScheme::new(scheme_name, nvme, namespaces); + let mut todo = Vec::new(); + 'events: loop { + let mut event = Event::default(); + if event_file.read(&mut event).expect("nvmed: failed to read event queue") == 0 { + break; } - //TODO: destroy NVMe stuff + match event.data { + 0 => { + let mut irq = [0; 8]; + if irq_file.read(&mut irq).expect("nvmed: failed to read irq file") >= irq.len() { + if scheme.irq() { + irq_file.write(&irq).expect("nvmed: failed to write irq file"); + } + } + }, + 1 => loop { + let mut packet = Packet::default(); + match socket_file.read(&mut packet) { + Ok(0) => break 'events, + Ok(_) => (), + Err(err) => match err.kind() { + ErrorKind::WouldBlock => break, + _ => Err(err).expect("nvmed: failed to read disk scheme"), + } + } + todo.push(packet); + }, + unknown => { + panic!("nvmed: unknown event data {}", unknown); + }, + } + + let mut i = 0; + while i < todo.len() { + if let Some(a) = scheme.handle(&todo[i]) { + let mut packet = todo.remove(i); + packet.a = a; + socket_file.write(&packet).expect("nvmed: failed to write disk scheme"); + } else { + i += 1; + } + } } - unsafe { let _ = syscall::physunmap(address); } + + //TODO: destroy NVMe stuff } + unsafe { let _ = syscall::physunmap(address); } } diff --git a/nvmed/src/nvme.rs b/nvmed/src/nvme.rs index 8754ded99b..9b74892f65 100644 --- a/nvmed/src/nvme.rs +++ b/nvmed/src/nvme.rs @@ -259,7 +259,7 @@ impl NvmeCompQueue { if let Some(some) = self.complete() { return some; } else { - unsafe { asm!("pause"); } + unsafe { std::arch::x86_64::_mm_pause() } } } } @@ -324,7 +324,7 @@ impl Nvme { let csts = self.regs.csts.read(); // println!("CSTS: {:X}", csts); if csts & 1 == 1 { - asm!("pause"); + unsafe { std::arch::x86_64::_mm_pause() } } else { break; } @@ -365,7 +365,7 @@ impl Nvme { let csts = self.regs.csts.read(); // println!("CSTS: {:X}", csts); if csts & 1 == 0 { - asm!("pause"); + unsafe { std::arch::x86_64::_mm_pause() } } else { break; } diff --git a/pcid/src/config.rs b/pcid/src/config.rs index 3c79746816..7481955dc6 100644 --- a/pcid/src/config.rs +++ b/pcid/src/config.rs @@ -19,5 +19,5 @@ pub struct DriverConfig { pub device: Option, pub device_id_range: Option>, pub command: Option>, - pub channel_name: Option, + pub use_channel: bool, } diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index e301bbe597..3716574c10 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -55,6 +55,11 @@ pub struct PciFunction { /// Device ID pub devid: u16, } +impl PciFunction { + pub fn name(&self) -> String { + format!("pci-{:>02X}.{:>02X}.{:>02X}", self.bus_num, self.dev_num, self.func_num) + } +} #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SubdriverArguments { diff --git a/pcid/src/main.rs b/pcid/src/main.rs index f8b02b1c4d..e039bd1272 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -408,7 +408,7 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, "$BUS" => format!("{:>02X}", bus_num), "$DEV" => format!("{:>02X}", dev_num), "$FUNC" => format!("{:>02X}", func_num), - "$NAME" => format!("pci-{:>02X}.{:>02X}.{:>02X}", bus_num, dev_num, func_num), + "$NAME" => func.name(), "$BAR0" => format!("{}", bars[0]), "$BAR1" => format!("{}", bars[1]), "$BAR2" => format!("{}", bars[2]), @@ -431,7 +431,7 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, info!("PCID SPAWN {:?}", command); - let (pcid_to_client_write, pcid_from_client_read, envs) = if driver.channel_name.is_some() { + let (pcid_to_client_write, pcid_from_client_read, envs) = if driver.use_channel { let mut fds1 = [0usize; 2]; let mut fds2 = [0usize; 2]; diff --git a/xhcid/Cargo.toml b/xhcid/Cargo.toml index 10072dd3c4..3817f5f8af 100644 --- a/xhcid/Cargo.toml +++ b/xhcid/Cargo.toml @@ -27,4 +27,5 @@ serde_json = "1" smallvec = { version = "1", features = ["serde"] } thiserror = "1" toml = "0.5" + pcid = { path = "../pcid" } diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 5c365aabac..6e8befb546 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -81,11 +81,6 @@ fn setup_logging() -> Option<&'static RedoxLogger> { } fn main() { - let mut args = env::args().skip(1); - - let mut name = args.next().expect("xhcid: no name provided"); - name.push_str("_xhci"); - // Daemonize if unsafe { syscall::clone(CloneFlags::empty()).unwrap() } != 0 { return; @@ -100,6 +95,9 @@ fn main() { let bar = pci_config.func.bars[0]; let irq = pci_config.func.legacy_interrupt_line; + let mut name = pci_config.func.name(); + name.push_str("_xhci"); + let bar_ptr = match bar { pcid_interface::PciBar::Memory(ptr) => ptr, other => panic!("Expected memory bar, found {}", other),