WIP: Use the enhanced pcid IPC.

This commit is contained in:
4lDO2
2020-04-22 21:21:39 +02:00
parent 07d4ae0e60
commit 7b69d5b9b5
10 changed files with 125 additions and 116 deletions
Generated
+6 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
}
+5
View File
@@ -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
View File
@@ -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];
+1
View File
@@ -27,4 +27,5 @@ serde_json = "1"
smallvec = { version = "1", features = ["serde"] }
thiserror = "1"
toml = "0.5"
pcid = { path = "../pcid" }
+3 -5
View File
@@ -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),