WIP: Use the enhanced pcid IPC.
This commit is contained in:
Generated
+6
-4
@@ -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)" = "<none>"
|
||||
"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"
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+4
-1
@@ -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" }
|
||||
|
||||
+97
-98
@@ -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::<u8>().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); }
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,5 +19,5 @@ pub struct DriverConfig {
|
||||
pub device: Option<u16>,
|
||||
pub device_id_range: Option<Range<u16>>,
|
||||
pub command: Option<Vec<String>>,
|
||||
pub channel_name: Option<String>,
|
||||
pub use_channel: bool,
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+2
-2
@@ -408,7 +408,7 @@ fn handle_parsed_header(state: Arc<State>, 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<State>, 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];
|
||||
|
||||
|
||||
@@ -27,4 +27,5 @@ serde_json = "1"
|
||||
smallvec = { version = "1", features = ["serde"] }
|
||||
thiserror = "1"
|
||||
toml = "0.5"
|
||||
|
||||
pcid = { path = "../pcid" }
|
||||
|
||||
+3
-5
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user