block/nvme: move nvme driver to its own crate
This commit is contained in:
parent
e78784d96d
commit
8b7a7b9295
@ -11,6 +11,7 @@ opt-level = 3
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
vfs = { path = "lib/vfs" }
|
||||
# TODO move to drivers
|
||||
memfs = { path = "lib/memfs" }
|
||||
device-api = { path = "lib/device-api", features = ["derive"] }
|
||||
kernel-util = { path = "lib/kernel-util" }
|
||||
@ -20,6 +21,8 @@ device-api-macros = { path = "lib/device-api/macros" }
|
||||
|
||||
# Drivers
|
||||
ygg_driver_pci = { path = "driver/bus/pci" }
|
||||
ygg_driver_nvme = { path = "driver/block/nvme" }
|
||||
kernel-fs = { path = "driver/fs/kernel-fs" }
|
||||
|
||||
atomic_enum = "0.2.0"
|
||||
bitflags = "2.3.3"
|
||||
|
21
driver/block/nvme/Cargo.toml
Normal file
21
driver/block/nvme/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "ygg_driver_nvme"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
kernel-util = { path = "../../../lib/kernel-util" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
vfs = { path = "../../../lib/vfs" }
|
||||
|
||||
ygg_driver_pci = { path = "../../bus/pci" }
|
||||
kernel-fs = { path = "../../fs/kernel-fs" }
|
||||
|
||||
log = "0.4.20"
|
||||
futures-util = { version = "0.3.28", default-features = false, features = ["alloc", "async-await"] }
|
||||
static_assertions = "1.1.0"
|
||||
tock-registers = "0.8.1"
|
||||
bytemuck = { version = "1.14.0", features = ["derive"] }
|
@ -5,7 +5,7 @@ use core::fmt::{self, Write};
|
||||
use kernel_util::mem::address::PhysicalAddress;
|
||||
use tock_registers::{interfaces::Readable, register_structs, registers::ReadOnly, UIntLike};
|
||||
|
||||
use crate::device::nvme::queue::PhysicalRegionPage;
|
||||
use crate::queue::PhysicalRegionPage;
|
||||
|
||||
use super::queue::SubmissionQueueEntry;
|
||||
|
@ -1,8 +1,9 @@
|
||||
use abi::{error::Error, io::DeviceRequest};
|
||||
use alloc::{boxed::Box, format};
|
||||
use kernel_fs::devfs;
|
||||
use vfs::BlockDevice;
|
||||
use yggdrasil_abi::{error::Error, io::DeviceRequest};
|
||||
|
||||
use crate::{device::nvme::command::IdentifyNamespaceRequest, fs::devfs};
|
||||
use crate::command::IdentifyNamespaceRequest;
|
||||
|
||||
use super::{error::NvmeError, NvmeController};
|
||||
|
||||
@ -27,7 +28,7 @@ impl NvmeDrive {
|
||||
let lba_size = current_lba_format.lba_data_size().unwrap();
|
||||
let total_lba_count = identify.total_lba_count();
|
||||
|
||||
debugln!(
|
||||
log::debug!(
|
||||
"ns = {}, lba = {}B, size = {}M",
|
||||
nsid,
|
||||
lba_size,
|
||||
@ -41,7 +42,6 @@ impl NvmeDrive {
|
||||
lba_size,
|
||||
}));
|
||||
|
||||
// TODO add the drive as a block device
|
||||
let node_name = format!("nvme{}n{}", controller.controller_id.get(), nsid);
|
||||
devfs::add_named_block_device(dev, node_name).ok();
|
||||
|
@ -1,4 +1,4 @@
|
||||
use abi::error::Error;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use super::queue::CommandError;
|
||||
|
@ -1,15 +1,21 @@
|
||||
#![feature(strict_provenance, const_trait_impl)]
|
||||
#![allow(missing_docs)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use core::{mem::size_of, time::Duration};
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{boxed::Box, collections::BTreeMap, vec::Vec};
|
||||
use command::{IdentifyActiveNamespaceIdListRequest, IdentifyControllerRequest};
|
||||
use device_api::{interrupt::MsiHandler, Device};
|
||||
use drive::NvmeDrive;
|
||||
use kernel_util::{
|
||||
mem::{
|
||||
address::{FromRaw, IntoRaw, PhysicalAddress},
|
||||
device::{DeviceMemoryIo, DeviceMemoryIoMut},
|
||||
},
|
||||
runtime,
|
||||
message_interrupt_controller, runtime,
|
||||
sync::IrqSafeSpinlock,
|
||||
util::OneTimeInit,
|
||||
};
|
||||
@ -22,16 +28,11 @@ use ygg_driver_pci::{
|
||||
capability::{MsiXCapability, MsiXEntry},
|
||||
PciBaseAddress, PciCommandRegister, PciConfigurationSpace, PciDeviceInfo,
|
||||
};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{
|
||||
arch::{Architecture, ARCHITECTURE},
|
||||
device::nvme::{
|
||||
command::{
|
||||
IdentifyActiveNamespaceIdListRequest, IdentifyControllerRequest, IoRead, IoWrite,
|
||||
},
|
||||
drive::NvmeDrive,
|
||||
command::{IoRead, IoWrite},
|
||||
queue::{CompletionQueueEntry, SubmissionQueueEntry},
|
||||
},
|
||||
};
|
||||
|
||||
use self::{
|
||||
@ -199,7 +200,7 @@ impl NvmeController {
|
||||
self.drive_table.lock().insert(nsid, drive);
|
||||
}
|
||||
Err(error) => {
|
||||
warnln!("Could not create nvme drive, nsid={}: {:?}", nsid, error);
|
||||
log::warn!("Could not create nvme drive, nsid={}: {:?}", nsid, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,7 +218,7 @@ impl NvmeController {
|
||||
) -> Result<(), NvmeError> {
|
||||
let ioq = &self.ioqs.get()[0];
|
||||
|
||||
debugln!("{:?} nsid={}, lba={:#x}", direction, nsid, lba);
|
||||
log::debug!("{:?} nsid={}, lba={:#x}", direction, nsid, lba);
|
||||
let cmd_id = match direction {
|
||||
IoDirection::Read => ioq.submit(
|
||||
IoRead {
|
||||
@ -276,7 +277,7 @@ impl Device for NvmeController {
|
||||
}
|
||||
|
||||
let timeout = Duration::from_millis(regs.CAP.read(CAP::TO) * 500);
|
||||
debugln!("Worst-case timeout: {:?}", timeout);
|
||||
log::debug!("Worst-case timeout: {:?}", timeout);
|
||||
|
||||
while regs.CSTS.matches_any(CSTS::RDY::SET) {
|
||||
core::hint::spin_loop();
|
||||
@ -293,7 +294,7 @@ impl Device for NvmeController {
|
||||
// Setup the admin queue (index 0)
|
||||
let admin_sq_doorbell = unsafe { regs.doorbell_ptr(self.doorbell_shift, false, 0) };
|
||||
let admin_cq_doorbell = unsafe { regs.doorbell_ptr(self.doorbell_shift, true, 0) };
|
||||
debugln!("sq_doorbell for adminq = {:p}", admin_sq_doorbell);
|
||||
log::debug!("sq_doorbell for adminq = {:p}", admin_sq_doorbell);
|
||||
let admin_q = QueuePair::new(
|
||||
0,
|
||||
0,
|
||||
@ -322,7 +323,7 @@ impl Device for NvmeController {
|
||||
// Enable the controller
|
||||
regs.CC.modify(CC::ENABLE::SET);
|
||||
|
||||
debugln!("Reset the controller");
|
||||
log::debug!("Reset the controller");
|
||||
|
||||
while !regs.CSTS.matches_any(CSTS::RDY::SET + CSTS::CFS::SET) {
|
||||
core::hint::spin_loop();
|
||||
@ -340,7 +341,7 @@ impl Device for NvmeController {
|
||||
|
||||
// Register vector 0
|
||||
vt[0]
|
||||
.register(ARCHITECTURE.message_interrupt_controller(), self)
|
||||
.register(message_interrupt_controller(), self)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use core::{
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
vec::Vec,
|
||||
@ -21,6 +20,7 @@ use kernel_util::{
|
||||
sync::IrqSafeSpinlock,
|
||||
};
|
||||
use static_assertions::const_assert;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use super::{
|
||||
command::{Command, Request},
|
||||
@ -252,7 +252,7 @@ impl QueuePair {
|
||||
let sq_base = unsafe { sq_data.as_physical_address() };
|
||||
let cq_base = unsafe { cq_data.as_physical_address() };
|
||||
|
||||
debugln!("Allocated queue pair: sq={:p}, cq={:p}", sq_data, cq_data);
|
||||
log::debug!("Allocated queue pair: sq={:p}, cq={:p}", sq_data, cq_data);
|
||||
|
||||
let sq = Queue::new(sq_data, null_mut(), sq_doorbell, true);
|
||||
let cq = Queue::new(cq_data, cq_doorbell, null_mut(), true);
|
13
driver/fs/kernel-fs/Cargo.toml
Normal file
13
driver/fs/kernel-fs/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "kernel-fs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
vfs = { path = "../../../lib/vfs" }
|
||||
kernel-util = { path = "../../../lib/kernel-util" }
|
||||
|
||||
log = "0.4.20"
|
@ -1,15 +1,10 @@
|
||||
//! Device virtual file system
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use abi::error::Error;
|
||||
use alloc::{format, string::String};
|
||||
use kernel_util::util::OneTimeInit;
|
||||
use vfs::{
|
||||
impls::{read_fn_node, MemoryDirectory},
|
||||
BlockDevice, CharDevice, Node, NodeFlags, NodeRef,
|
||||
};
|
||||
|
||||
use crate::proc::random;
|
||||
use vfs::{impls::MemoryDirectory, BlockDevice, CharDevice, Node, NodeFlags, NodeRef};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
/// Describes the kind of a character device
|
||||
#[derive(Debug)]
|
||||
@ -39,7 +34,7 @@ pub fn root() -> &'static NodeRef {
|
||||
|
||||
/// Adds a character device with a custom name
|
||||
pub fn add_named_char_device(dev: &'static dyn CharDevice, name: String) -> Result<(), Error> {
|
||||
infoln!("Add char device: {}", name);
|
||||
log::info!("Add char device: {}", name);
|
||||
|
||||
let node = Node::char(dev, NodeFlags::IN_MEMORY_PROPS);
|
||||
|
||||
@ -52,7 +47,7 @@ pub fn add_named_block_device<S: Into<String>>(
|
||||
name: S,
|
||||
) -> Result<(), Error> {
|
||||
let name = name.into();
|
||||
infoln!("Add block device: {}", name);
|
||||
log::info!("Add block device: {}", name);
|
||||
|
||||
let node = Node::block(dev, NodeFlags::IN_MEMORY_PROPS);
|
||||
|
||||
@ -74,16 +69,3 @@ pub fn add_char_device(dev: &'static dyn CharDevice, kind: CharDeviceType) -> Re
|
||||
|
||||
add_named_char_device(dev, name)
|
||||
}
|
||||
|
||||
/// Adds "pseudo"-devices to the filesystem (i.e. /dev/random)
|
||||
pub fn add_pseudo_devices() -> Result<(), Error> {
|
||||
let random = read_fn_node(move |_, buf| {
|
||||
random::read(buf);
|
||||
Ok(buf.len())
|
||||
});
|
||||
|
||||
let root = root();
|
||||
root.add_child("random", random)?;
|
||||
|
||||
Ok(())
|
||||
}
|
5
driver/fs/kernel-fs/src/lib.rs
Normal file
5
driver/fs/kernel-fs/src/lib.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub mod devfs;
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
device-api = { path = "../device-api", features = ["derive"] }
|
||||
|
||||
log = "0.4.20"
|
||||
futures-util = { version = "0.3.28", default-features = false, features = ["alloc", "async-await"] }
|
||||
|
@ -1,6 +1,7 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use alloc::{string::String, sync::Arc};
|
||||
use device_api::interrupt::MessageInterruptController;
|
||||
use yggdrasil_abi::{error::Error, process::ExitCode};
|
||||
|
||||
use crate::{
|
||||
@ -39,4 +40,6 @@ extern "Rust" {
|
||||
pub fn __exit_current(t: &CurrentThread, code: ExitCode) -> !;
|
||||
|
||||
pub fn __monotonic_timestamp() -> Result<Duration, Error>;
|
||||
|
||||
pub fn __message_interrupt_controller() -> &'static dyn MessageInterruptController;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
let_chains
|
||||
)]
|
||||
|
||||
use device_api::interrupt::MessageInterruptController;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub(crate) mod api;
|
||||
@ -20,6 +22,11 @@ pub mod sync;
|
||||
pub mod thread;
|
||||
pub mod util;
|
||||
|
||||
#[inline]
|
||||
pub fn message_interrupt_controller() -> &'static dyn MessageInterruptController {
|
||||
unsafe { api::__message_interrupt_controller() }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AlignedTo<Align, Bytes: ?Sized> {
|
||||
pub align: [Align; 0],
|
||||
|
@ -271,3 +271,8 @@ fn __unmap_device_pages(mapping: &RawDeviceMemoryMapping) {
|
||||
fn __monotonic_timestamp() -> Result<Duration, Error> {
|
||||
ARCHITECTURE.monotonic_timer().monotonic_timestamp()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __message_interrupt_controller() -> &'static dyn MessageInterruptController {
|
||||
ARCHITECTURE.message_interrupt_controller()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! x86-64 boot and entry functions
|
||||
use core::{arch::global_asm, sync::atomic::Ordering};
|
||||
|
||||
use kernel_fs::devfs;
|
||||
use kernel_util::runtime;
|
||||
use tock_registers::interfaces::Writeable;
|
||||
use yboot_proto::{
|
||||
@ -10,7 +11,6 @@ use yboot_proto::{
|
||||
|
||||
use crate::{
|
||||
arch::x86_64::{registers::MSR_IA32_KERNEL_GS_BASE, smp::CPU_COUNT},
|
||||
fs::devfs,
|
||||
kernel_main, kernel_secondary_main,
|
||||
mem::KERNEL_VIRT_OFFSET,
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ use device_api::{
|
||||
Device,
|
||||
};
|
||||
use git_version::git_version;
|
||||
use kernel_fs::devfs::{self, CharDeviceType};
|
||||
use kernel_util::{
|
||||
mem::{
|
||||
address::{FromRaw, IntoRaw, PhysicalAddress},
|
||||
@ -51,13 +52,9 @@ use crate::{
|
||||
device::{
|
||||
self,
|
||||
display::{console, fb_console::FramebufferConsole, linear_fb::LinearFramebuffer},
|
||||
nvme,
|
||||
tty::CombinedTerminal,
|
||||
},
|
||||
fs::{
|
||||
devfs::{self, CharDeviceType},
|
||||
Initrd, INITRD_DATA,
|
||||
},
|
||||
fs::{Initrd, INITRD_DATA},
|
||||
mem::{
|
||||
heap,
|
||||
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
||||
@ -392,7 +389,7 @@ impl X86_64 {
|
||||
0x01,
|
||||
Some(0x08),
|
||||
Some(0x02),
|
||||
nvme::probe,
|
||||
ygg_driver_nvme::probe,
|
||||
);
|
||||
|
||||
match self.boot_data.get() {
|
||||
|
@ -10,8 +10,6 @@ pub mod devtree;
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
pub mod bus;
|
||||
|
||||
pub mod nvme;
|
||||
|
||||
pub mod display;
|
||||
pub mod power;
|
||||
pub mod serial;
|
||||
|
@ -2,14 +2,15 @@
|
||||
|
||||
use core::ptr::NonNull;
|
||||
|
||||
use kernel_fs::devfs;
|
||||
use kernel_util::{mem::address::PhysicalAddress, util::OneTimeInit};
|
||||
use memfs::block::{self, BlockAllocator};
|
||||
use vfs::NodeRef;
|
||||
use vfs::{impls::read_fn_node, NodeRef};
|
||||
use yggdrasil_abi::{error::Error, io::MountOptions};
|
||||
|
||||
use crate::mem::phys;
|
||||
use crate::{mem::phys, proc::random};
|
||||
|
||||
pub mod devfs;
|
||||
// pub mod devfs;
|
||||
pub mod sysfs;
|
||||
|
||||
/// Describes in-memory filesystem image used as initial root
|
||||
@ -53,3 +54,16 @@ pub fn create_filesystem(options: &MountOptions) -> Result<NodeRef, Error> {
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds "pseudo"-devices to the filesystem (i.e. /dev/random)
|
||||
pub fn add_pseudo_devices() -> Result<(), Error> {
|
||||
let random = read_fn_node(move |_, buf| {
|
||||
random::read(buf);
|
||||
Ok(buf.len())
|
||||
});
|
||||
|
||||
let root = devfs::root();
|
||||
root.add_child("random", random)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3,11 +3,12 @@ use abi::{
|
||||
error::Error,
|
||||
io::{OpenOptions, RawFd},
|
||||
};
|
||||
use kernel_fs::devfs;
|
||||
use memfs::MemoryFilesystem;
|
||||
use vfs::{Action, IoContext, NodeRef};
|
||||
|
||||
use crate::{
|
||||
fs::{devfs, FileBlockAllocator, INITRD_DATA},
|
||||
fs::{FileBlockAllocator, INITRD_DATA},
|
||||
proc,
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ use kernel_util::sync::SpinFence;
|
||||
|
||||
use crate::{
|
||||
arch::{ArchitectureImpl, ARCHITECTURE},
|
||||
fs::{devfs, sysfs},
|
||||
fs::sysfs,
|
||||
mem::heap,
|
||||
proc::random,
|
||||
task::{spawn_kernel_closure, Cpu},
|
||||
@ -96,7 +96,7 @@ pub fn kernel_main() -> ! {
|
||||
|
||||
// Setup the sysfs
|
||||
sysfs::init();
|
||||
devfs::add_pseudo_devices().unwrap();
|
||||
fs::add_pseudo_devices().unwrap();
|
||||
|
||||
unsafe {
|
||||
ARCHITECTURE.start_application_processors();
|
||||
|
Loading…
x
Reference in New Issue
Block a user