Skip to content

Commit 14f2be6

Browse files
committed
update
1 parent 7b6fba3 commit 14f2be6

File tree

10 files changed

+72
-54
lines changed

10 files changed

+72
-54
lines changed

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/axfeat/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ display = ["alloc", "paging", "axdriver/virtio-gpu", "dep:axdisplay", "axruntime
5252
rtc = ["axhal/rtc", "axruntime/rtc"]
5353

5454
# Device drivers
55-
driver-dyn = ["axruntime/driver","axdriver?/dyn"]
55+
driver-dyn = ["axruntime/driver-dyn","axdriver?/dyn"]
5656
bus-mmio = ["axdriver?/bus-mmio"]
5757
bus-pci = ["axdriver?/bus-pci"]
5858
driver-ramdisk = ["axdriver?/ramdisk", "axfs?/use-ramdisk"]

modules/axdriver/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository = "https://github.com/arceos-org/arceos/tree/main/modules/axdriver"
1010
documentation = "https://arceos-org.github.io/arceos/axdriver/index.html"
1111

1212
[features]
13-
dyn = ["dep:rdrive", "dep:axmm", "dep:arm-gic-driver"]
13+
dyn = ["dep:rdrive", "dep:arm-gic-driver"]
1414
bus-mmio = []
1515
bus-pci = ["dep:axdriver_pci", "dep:axhal", "dep:axconfig"]
1616
net = ["axdriver_net"]
@@ -47,7 +47,8 @@ axhal = { workspace = true, optional = true }
4747
axconfig = { workspace = true, optional = true }
4848
axdma = { workspace = true, optional = true }
4949
rdrive = { version = "0.15", optional = true }
50-
axmm = { workspace = true, optional = true }
50+
axerrno = "0.1"
51+
lazyinit = "0.2"
5152

5253
[target.'cfg(target_arch = "aarch64")'.dependencies]
5354
arm-gic-driver = { version = "0.14", optional = true }

modules/axdriver/src/bus/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#[cfg(bus = "mmio")]
2-
#[allow(unused)]
32
mod mmio;
43
#[cfg(bus = "pci")]
5-
#[allow(unused)]
64
mod pci;

modules/axdriver/src/dyn_drivers/blk/virtio.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use alloc::format;
44
use axdriver_base::DeviceType;
55
use axdriver_block::BlockDriverOps;
66
use axdriver_virtio::MmioTransport;
7-
use axhal::mem::{MemoryAddr, PhysAddr};
8-
use core::ptr::NonNull;
7+
use axhal::mem::PhysAddr;
98
use rdrive::{
109
DriverGeneric, PlatformDevice, driver::block::*, module_driver, probe::OnProbeError,
1110
register::FdtInfo,
@@ -30,27 +29,19 @@ module_driver!(
3029
);
3130

3231
fn probe(info: FdtInfo<'_>, plat_dev: PlatformDevice) -> Result<(), OnProbeError> {
33-
let mut reg = info.node.reg().ok_or(OnProbeError::other(alloc::format!(
34-
"[{}] has no reg",
35-
info.node.name()
36-
)))?;
32+
let base_reg = info
33+
.node
34+
.reg()
35+
.and_then(|mut regs| regs.next())
36+
.ok_or(OnProbeError::other(alloc::format!(
37+
"[{}] has no reg",
38+
info.node.name()
39+
)))?;
3740

38-
let base_reg = reg.next().unwrap();
3941
let mmio_size = base_reg.size.unwrap_or(0x1000);
4042
let mmio_base = PhysAddr::from_usize(base_reg.address as usize);
41-
let aligned_base = mmio_base.align_down_4k();
42-
let offset = mmio_base - aligned_base;
4343

44-
let aligned_end = (mmio_base + mmio_size).align_up_4k();
45-
let aligned_mmio_size = aligned_end - aligned_base;
46-
47-
let aligned_mmio_base: NonNull<u8> = iomap(aligned_base, aligned_mmio_size)?;
48-
let mmio_base = unsafe { aligned_mmio_base.as_ptr().add(offset) };
49-
50-
debug!(
51-
"virtio block device MMIO base address: {:?}, size: {}",
52-
mmio_base, mmio_size
53-
);
44+
let mmio_base = iomap(mmio_base, mmio_size)?.as_ptr();
5445

5546
let (ty, transport) =
5647
axdriver_virtio::probe_mmio_device(mmio_base, mmio_size).ok_or(OnProbeError::NotMatch)?;
@@ -67,11 +58,8 @@ fn probe(info: FdtInfo<'_>, plat_dev: PlatformDevice) -> Result<(), OnProbeError
6758
})?;
6859

6960
let dev = BlockDivce(dev);
70-
7161
plat_dev.register_block(dev);
72-
7362
debug!("virtio block device registered successfully");
74-
7563
Ok(())
7664
}
7765

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
use core::{error::Error, ptr::NonNull};
22

33
use alloc::{boxed::Box, format};
4-
use axhal::{
5-
mem::{MemoryAddr, PhysAddr, phys_to_virt},
6-
paging::MappingFlags,
7-
};
8-
use axmm::AxError;
4+
use axerrno::AxError;
5+
use axhal::mem::{MemoryAddr, PhysAddr, phys_to_virt};
96

107
mod intc;
118

@@ -15,23 +12,25 @@ pub mod blk;
1512
#[allow(unused)]
1613
/// maps a mmio physical address to a virtual address.
1714
fn iomap(addr: PhysAddr, size: usize) -> Result<NonNull<u8>, Box<dyn Error>> {
18-
let end = (addr.as_usize() + size).align_up_4k();
15+
let end = (addr + size).align_up_4k();
1916
let start = addr.align_down_4k();
20-
let size = end - start.as_usize();
17+
let offset = addr - start;
18+
let size = end - start;
19+
let iomap = *crate::IO_MAP_FUNC
20+
.get()
21+
.ok_or_else(|| format!("IO map function not initialized"))?;
2122

22-
let start_virt = phys_to_virt(start);
23-
24-
match axmm::kernel_aspace().lock().map_linear(
25-
start_virt,
26-
addr,
27-
size,
28-
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::DEVICE,
29-
) {
30-
Ok(_) | Err(AxError::AlreadyExists) => {}
23+
let virt = match iomap(start, size) {
24+
Ok(val) => val,
25+
Err(AxError::AlreadyExists) => phys_to_virt(start),
3126
Err(e) => {
32-
Err(format!("Failed to map MMIO region {:?}: {}", start_virt, e))?;
27+
return Err(format!(
28+
"Failed to map MMIO region: {:?} (addr: {:?}, size: {:#x})",
29+
e, start, size
30+
)
31+
.into());
3332
}
34-
}
35-
33+
};
34+
let start_virt = virt + offset;
3635
Ok(NonNull::new(start_virt.as_mut_ptr()).unwrap())
3736
}

modules/axdriver/src/lib.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ extern crate alloc;
6767
#[macro_use]
6868
mod macros;
6969

70+
#[cfg(not(feature = "dyn"))]
7071
mod bus;
7172
mod drivers;
7273
mod dummy;
@@ -83,11 +84,13 @@ mod dyn_drivers;
8384

8485
pub mod prelude;
8586

86-
use axhal::mem::phys_to_virt;
87-
8887
#[allow(unused_imports)]
8988
use self::prelude::*;
9089
pub use self::structs::{AxDeviceContainer, AxDeviceEnum};
90+
use axerrno::AxResult;
91+
use axhal::mem::phys_to_virt;
92+
use axhal::mem::{PhysAddr, VirtAddr};
93+
use lazyinit::LazyInit;
9194

9295
#[cfg(feature = "block")]
9396
pub use self::structs::AxBlockDevice;
@@ -96,6 +99,9 @@ pub use self::structs::AxDisplayDevice;
9699
#[cfg(feature = "net")]
97100
pub use self::structs::AxNetDevice;
98101

102+
pub type IoMapFunc = fn(PhysAddr, usize) -> AxResult<VirtAddr>;
103+
static IO_MAP_FUNC: LazyInit<IoMapFunc> = LazyInit::new();
104+
99105
/// A structure that contains all device drivers, organized by their category.
100106
#[derive(Default)]
101107
pub struct AllDevices {
@@ -160,7 +166,13 @@ impl AllDevices {
160166
}
161167

162168
/// Sets up the device driver subsystem.
163-
pub fn setup(dtb: usize) {
169+
pub fn setup(dtb: usize, io_map_func: IoMapFunc) {
170+
IO_MAP_FUNC.init_once(io_map_func);
171+
if dtb == 0 {
172+
warn!("Device tree base address is 0, skipping device driver setup.");
173+
return;
174+
}
175+
164176
let dtb_virt = phys_to_virt(dtb.into());
165177
if let Some(dtb) = core::ptr::NonNull::new(dtb_virt.as_mut_ptr()) {
166178
structs::setup(dtb);

modules/axmm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod backend;
1212
pub use self::aspace::AddrSpace;
1313
pub use self::backend::Backend;
1414

15-
pub use axerrno::{AxError, AxResult};
15+
use axerrno::{AxError, AxResult};
1616
use axhal::mem::phys_to_virt;
1717
use kspin::SpinNoIrq;
1818
use lazyinit::LazyInit;

modules/axruntime/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ irq = ["axhal/irq", "axtask?/irq", "percpu", "kernel_guard"]
1717
tls = ["axhal/tls", "axtask?/tls"]
1818
alloc = ["axalloc"]
1919
paging = ["axhal/paging", "axmm"]
20-
driver = ["axdriver"]
20+
driver-dyn = ["axdriver"]
2121

2222
multitask = ["axtask/multitask"]
2323
fs = ["axdriver", "axfs"]
@@ -36,6 +36,7 @@ axfs = { workspace = true, optional = true }
3636
axnet = { workspace = true, optional = true }
3737
axdisplay = { workspace = true, optional = true }
3838
axtask = { workspace = true, optional = true }
39+
axerrno = "0.1"
3940

4041
crate_interface = "0.1"
4142
percpu = { version = "0.2", optional = true }

modules/axruntime/src/lib.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ pub extern "C" fn rust_main(cpu_id: usize, dtb: usize) -> ! {
147147
#[cfg(feature = "paging")]
148148
axmm::init_memory_management();
149149

150-
#[cfg(feature = "driver")]
151-
axdriver::setup(dtb);
150+
#[cfg(feature = "driver-dyn")]
151+
axdriver::setup(dtb, iomap);
152152

153153
info!("Initialize platform devices...");
154154
axhal::platform_init();
@@ -273,3 +273,20 @@ fn init_tls() {
273273
unsafe { axhal::asm::write_thread_pointer(main_tls.tls_ptr() as usize) };
274274
core::mem::forget(main_tls);
275275
}
276+
277+
#[cfg(feature = "driver-dyn")]
278+
fn iomap(addr: axhal::mem::PhysAddr, size: usize) -> axerrno::AxResult<axhal::mem::VirtAddr> {
279+
let virt = axhal::mem::phys_to_virt(addr);
280+
#[cfg(feature = "paging")]
281+
{
282+
use axhal::paging::MappingFlags;
283+
284+
axmm::kernel_aspace().lock().map_linear(
285+
virt,
286+
addr,
287+
size,
288+
MappingFlags::DEVICE | MappingFlags::READ | MappingFlags::WRITE,
289+
)?;
290+
}
291+
Ok(virt)
292+
}

0 commit comments

Comments
 (0)