-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
575 additions
and
185 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Useage | ||
|
||
## Example | ||
|
||
use nvme as block device. | ||
|
||
```bash | ||
make disk_img | ||
make A=examples/shell ARCH=x86_64 LOG=info SMP=4 ACCEL=N FEATURES=driver-nvme APP_FEATURES=use-ramfs BLK=y run | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use core::ptr::NonNull; | ||
|
||
use axhal::mem::phys_to_virt; | ||
use nvme_driver::{Config, Namespace}; | ||
use pcie::{Chip, CommandRegister, DeviceType, Endpoint, RootComplex}; | ||
|
||
use crate::{BaseDriverOps, BlockDriverOps}; | ||
|
||
pub struct Nvme { | ||
inner: nvme_driver::Nvme, | ||
ns: Namespace, | ||
} | ||
|
||
unsafe impl Send for Nvme {} | ||
unsafe impl Sync for Nvme {} | ||
|
||
impl Nvme { | ||
pub fn new<C: Chip>(root: &mut RootComplex<C>, ep: Endpoint) -> Option<Self> { | ||
info!("probe: {:?}", ep); | ||
|
||
ep.update_command(root, |cmd| { | ||
cmd | CommandRegister::IO_ENABLE | ||
| CommandRegister::MEMORY_ENABLE | ||
| CommandRegister::BUS_MASTER_ENABLE | ||
}); | ||
|
||
if ep.device_type() == DeviceType::NvmeController { | ||
let bar_addr = match ep.bar { | ||
pcie::BarVec::Memory32(bar_vec_t) => { | ||
let bar0 = bar_vec_t[0].as_ref().unwrap(); | ||
bar0.address as usize | ||
} | ||
pcie::BarVec::Memory64(bar_vec_t) => { | ||
let bar0 = bar_vec_t[0].as_ref().unwrap(); | ||
bar0.address as usize | ||
} | ||
pcie::BarVec::Io(_bar_vec_t) => return None, | ||
}; | ||
|
||
let addr = phys_to_virt(bar_addr.into()); | ||
|
||
let mut nvme = nvme_driver::Nvme::new( | ||
unsafe { NonNull::new_unchecked(addr.as_mut_ptr()) }, | ||
Config { | ||
page_size: 0x1000, | ||
io_queue_pair_count: 1, | ||
}, | ||
) | ||
.inspect_err(|e| error!("{:?}", e)) | ||
.unwrap(); | ||
let ns_list = nvme.namespace_list().ok()?; | ||
let ns = ns_list.first()?; | ||
|
||
return Some(Self { | ||
inner: nvme, | ||
ns: *ns, | ||
}); | ||
} | ||
|
||
None | ||
} | ||
} | ||
|
||
impl BaseDriverOps for Nvme { | ||
fn device_name(&self) -> &str { | ||
"NVME" | ||
} | ||
|
||
fn device_type(&self) -> crate::DeviceType { | ||
crate::DeviceType::Block | ||
} | ||
} | ||
|
||
impl BlockDriverOps for Nvme { | ||
fn num_blocks(&self) -> u64 { | ||
self.ns.lba_count as _ | ||
} | ||
|
||
fn block_size(&self) -> usize { | ||
self.ns.lba_size | ||
} | ||
|
||
fn read_block(&mut self, block_id: u64, buf: &mut [u8]) -> crate::DevResult { | ||
self.inner | ||
.block_read_sync(&self.ns, block_id as _, buf) | ||
.map_err(|_e| crate::DevError::Io) | ||
} | ||
|
||
fn write_block(&mut self, block_id: u64, buf: &[u8]) -> crate::DevResult { | ||
self.inner | ||
.block_write_sync(&self.ns, block_id, buf) | ||
.map_err(|_e| crate::DevError::Io) | ||
} | ||
|
||
fn flush(&mut self) -> crate::DevResult { | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#![allow(unused)] | ||
|
||
use core::{arch::asm, ptr::NonNull}; | ||
|
||
fn dcache_line_size() -> usize { | ||
unsafe { | ||
let result; | ||
asm!( | ||
"mrs x8, CTR_EL0", | ||
"ubfm x8, x8, #16, #19", // cache line size encoding | ||
"mov {0}, #4", // bytes per word | ||
"lsl {0}, {0}, x8", // actual cache line size""", | ||
out(reg) result); | ||
|
||
result | ||
} | ||
} | ||
|
||
/// Invalidate data cache | ||
pub fn dcache_invalidate_range(addr: NonNull<u8>, size: usize) { | ||
let addr = addr.as_ptr() as usize; | ||
unsafe { | ||
let line_size = dcache_line_size(); | ||
let start = addr & !(line_size - 1); | ||
let end = (addr + size + line_size - 1) & !(line_size - 1); | ||
|
||
for addr in (start..end).step_by(line_size) { | ||
asm!("dc ivac, {0}", in(reg) addr); | ||
} | ||
|
||
asm!("dsb sy"); | ||
} | ||
} | ||
|
||
/// Clean data cache | ||
pub fn dcache_clean_range(addr: NonNull<u8>, size: usize) { | ||
let addr = addr.as_ptr() as usize; | ||
unsafe { | ||
let line_size = dcache_line_size(); | ||
let start = addr & !(line_size - 1); | ||
let end = (addr + size + line_size - 1) & !(line_size - 1); | ||
|
||
for addr in (start..end).step_by(line_size) { | ||
asm!("dc cvac, {0}", in(reg) addr); | ||
} | ||
|
||
asm!("dsb sy"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub(crate) mod cache; | ||
mod context; | ||
pub(crate) mod trap; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#![allow(unused)] | ||
|
||
use core::ptr::NonNull; | ||
|
||
/// Invalidate data cache | ||
pub fn dcache_invalidate_range(_addr: NonNull<u8>, _size: usize) { | ||
//TODO | ||
} | ||
|
||
/// Clean data cache | ||
pub fn dcache_clean_range(_addr: NonNull<u8>, _size: usize) { | ||
//TODO | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
#[macro_use] | ||
mod macros; | ||
|
||
pub mod cache; | ||
mod context; | ||
mod trap; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#![allow(unused)] | ||
|
||
use core::ptr::NonNull; | ||
|
||
/// Invalidate data cache | ||
pub fn dcache_invalidate_range(_addr: NonNull<u8>, _size: usize) { | ||
//TODO | ||
} | ||
|
||
/// Clean data cache | ||
pub fn dcache_clean_range(_addr: NonNull<u8>, _size: usize) { | ||
//TODO | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub(crate) mod cache; | ||
mod context; | ||
mod gdt; | ||
mod idt; | ||
|
Oops, something went wrong.