good_os_framework/drivers/nvme/
mod.rs

1mod cmd;
2mod memory;
3mod nvme;
4mod queues;
5
6use crate::drivers::pci::{get_pci_device_structure_mut, PCI_DEVICE_LINKEDLIST};
7use alloc::{collections::btree_map::BTreeMap, vec::Vec};
8use memory::Dma;
9pub use nvme::{NvmeDevice, NvmeQueuePair};
10pub use queues::QUEUE_LENGTH;
11use spin::Mutex;
12
13static NVME_CONS: Mutex<Vec<NvmeDevice>> = Mutex::new(Vec::new());
14static NVME_SIZES: Mutex<BTreeMap<usize, usize>> = Mutex::new(BTreeMap::new());
15
16pub fn init() {
17    let mut list = PCI_DEVICE_LINKEDLIST.write();
18    let pci_devices = get_pci_device_structure_mut(&mut list, 0x01, 0x08);
19    let mut nvme_cons = NVME_CONS.lock();
20    let mut nvme_sizes = NVME_SIZES.lock();
21
22    let mut idx = 0;
23    for pci_device in pci_devices {
24        if let None = pci_device.bar_init() {
25            continue;
26        }
27
28        if let Ok(bar) = pci_device
29            .as_standard_device()
30            .unwrap()
31            .standard_device_bar
32            .get_bar(0)
33        {
34            if let Some((_, len)) = bar.memory_address_size() {
35                let header = bar.virtual_address().unwrap() as usize;
36
37                pci_device.as_mut().enable_master();
38
39                log::info!("NVMe OK");
40                let mut nvme_device =
41                    NvmeDevice::init(header, len as usize).expect("Cannot init NVMe device");
42
43                nvme_device
44                    .identify_controller()
45                    .expect("Cannot identify controller");
46                let ns = nvme_device.identify_namespace_list(0);
47
48                let mut nvmcap = 0;
49                for n in ns {
50                    let cap = nvme_device.identify_namespace(n).1 as usize;
51                    nvmcap += cap;
52                }
53
54                nvme_cons.push(nvme_device);
55                log::info!("NVM capacity = {}", nvmcap);
56                nvme_sizes.insert(idx, nvmcap);
57            }
58        }
59
60        idx += 1;
61    }
62}
63
64#[derive(Debug, Clone, Copy)]
65pub struct NvmeNamespace {
66    pub id: u32,
67    pub blocks: u64,
68    pub block_size: u64,
69}
70
71#[derive(Debug, Clone, Default)]
72pub struct NvmeStats {
73    pub completions: u64,
74    pub submissions: u64,
75}
76
77/// Reads a block from the NVMe driver at block block_id
78pub fn read_block(hd: usize, block_id: u64, buf: &mut [u8]) {
79    let dma: Dma<u8> = Dma::allocate(buf.len()).expect("Cannot allocate frame");
80    let mut cons = NVME_CONS.lock();
81    let nvme = cons.get_mut(hd).expect("Cannot get hd");
82    nvme.read(&dma, block_id).expect("Cannot read");
83    unsafe { buf.as_mut_ptr().copy_from(dma.virt, 512) };
84}
85
86/// Writes a block to the NVMe driver at block block_id
87pub fn write_block(hd: usize, block_id: u64, buf: &[u8]) {
88    let dma: Dma<u8> = Dma::allocate(buf.len()).expect("Cannot allocate frame");
89    unsafe { dma.virt.copy_from(buf.as_ptr(), 512) };
90    let mut cons = NVME_CONS.lock();
91    let nvme = cons.get_mut(hd).expect("Cannot get hd");
92    nvme.write(&dma, block_id).expect("Cannot write");
93}
94
95/// Gets the number of NVMe drives
96pub fn get_hd_num() -> usize {
97    let cons = NVME_CONS.lock();
98    cons.len()
99}
100
101/// Get the driver size of the NVMe driver.
102pub fn get_hd_size(hd: usize) -> Option<usize> {
103    let cons = NVME_SIZES.lock();
104    cons.get(&hd).copied()
105}