good_os_framework/drivers/nvme/
mod.rs1mod 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
77pub 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
86pub 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
95pub fn get_hd_num() -> usize {
97 let cons = NVME_CONS.lock();
98 cons.len()
99}
100
101pub fn get_hd_size(hd: usize) -> Option<usize> {
103 let cons = NVME_SIZES.lock();
104 cons.get(&hd).copied()
105}