Skip to content
Merged
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ jobs:
- profile: dev
hermit-careful: 1
- arch: x86_64
packages: qemu-system-x86 libcap-ng-dev libseccomp-dev uftrace
packages: qemu-system-x86 uftrace
qemu_flags: --accel --sudo
- arch: aarch64
packages: qemu-system-aarch64 ipxe-qemu
Expand All @@ -185,7 +185,7 @@ jobs:
- name: Install QEMU
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends ${{ matrix.packages }}
sudo apt-get install --no-install-recommends libcap-ng-dev libseccomp-dev ${{ matrix.packages }}
- uses: dtolnay/rust-toolchain@stable
- uses: mkroening/rust-toolchain-toml@main
- run: rustup component add llvm-tools
Expand Down Expand Up @@ -216,7 +216,6 @@ jobs:
- run: cargo +stable install --locked uhyve
if: matrix.arch == 'x86_64'
- run: cargo +stable install --locked virtiofsd
if: matrix.arch == 'x86_64'
- run: cargo +stable install cargo-careful
if: matrix.profile == 'dev'
- run: FIRECRACKER=$HOME/.local/bin/firecracker cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo --no-default-features firecracker --sudo
Expand Down Expand Up @@ -262,6 +261,11 @@ jobs:
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo --features fs --smp 4 qemu ${{ matrix.qemu_flags }} --devices virtio-fs-pci --no-default-virtio-features
if: matrix.arch == 'x86_64'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo --no-default-features --features fs qemu ${{ matrix.qemu_flags }} --devices virtio-fs-mmio --microvm
if: matrix.arch == 'x86_64'
# FIXME: enable on aarch64_be, once it works
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo --no-default-features --features fs qemu ${{ matrix.qemu_flags }} --devices virtio-fs-mmio
if: matrix.arch != 'x86_64' && matrix.arch != 'aarch64_be'
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo qemu ${{ matrix.qemu_flags }}
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.rs_flags }} --package rusty_demo --smp 4 qemu ${{ matrix.qemu_flags }}
# https://github.com/hermit-os/kernel/issues/1286
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ udp = ["net", "smoltcp", "smoltcp/socket-udp"]
vga = []
virtio = ["dep:virtio", "dep:mem-barrier"]
virtio-console = ["virtio"]
virtio-fs = ["virtio", "pci", "dep:fuse-abi", "fuse-abi/num_enum"]
virtio-fs = ["virtio", "dep:fuse-abi", "fuse-abi/num_enum"]
virtio-net = ["net", "virtio"]
virtio-vsock = ["virtio", "pci"]
warn-prebuilt = []
Expand Down
167 changes: 78 additions & 89 deletions src/arch/aarch64/kernel/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::ptr::NonNull;

use align_address::Align;
use arm_gic::{IntId, Trigger};
#[cfg(feature = "virtio-console")]
#[cfg(any(feature = "virtio-console", feature = "virtio-fs"))]
use hermit_sync::InterruptTicketMutex;
use hermit_sync::without_interrupts;
use virtio::mmio::{DeviceRegisters, DeviceRegistersVolatileFieldAccess};
Expand All @@ -17,9 +17,17 @@ use crate::console::IoDevice;
use crate::drivers::console::VirtioConsoleDriver;
#[cfg(feature = "virtio-console")]
use crate::drivers::console::VirtioUART;
#[cfg(feature = "virtio-fs")]
use crate::drivers::fs::VirtioFsDriver;
#[cfg(feature = "virtio-net")]
use crate::drivers::net::virtio::VirtioNetDriver;
use crate::drivers::virtio::transport::mmio::{self as mmio_virtio, VirtioDriver};
use crate::drivers::virtio::transport::mmio as mmio_virtio;
#[cfg(any(
feature = "virtio-console",
feature = "virtio-fs",
feature = "virtio-net",
))]
use crate::drivers::virtio::transport::mmio::VirtioDriver;
#[cfg(feature = "virtio-net")]
use crate::executor::device::NETWORK_DEVICE;
use crate::init_cell::InitCell;
Expand All @@ -30,6 +38,8 @@ pub(crate) static MMIO_DRIVERS: InitCell<Vec<MmioDriver>> = InitCell::new(Vec::n
pub(crate) enum MmioDriver {
#[cfg(feature = "virtio-console")]
VirtioConsole(InterruptTicketMutex<VirtioConsoleDriver>),
#[cfg(feature = "virtio-fs")]
VirtioFs(InterruptTicketMutex<VirtioFsDriver>),
}

impl MmioDriver {
Expand All @@ -39,9 +49,16 @@ impl MmioDriver {
Self::VirtioConsole(drv) => Some(drv),
}
}

#[cfg(feature = "virtio-fs")]
fn get_filesystem_driver(&self) -> Option<&InterruptTicketMutex<VirtioFsDriver>> {
match self {
Self::VirtioFs(drv) => Some(drv),
}
}
}

#[cfg(feature = "virtio-console")]
#[cfg(any(feature = "virtio-console", feature = "virtio-fs"))]
pub(crate) fn register_driver(drv: MmioDriver) {
MMIO_DRIVERS.with(|mmio_drivers| mmio_drivers.unwrap().push(drv));
}
Expand All @@ -57,6 +74,14 @@ pub(crate) fn get_console_driver() -> Option<&'static InterruptTicketMutex<Virti
.find_map(|drv| drv.get_console_driver())
}

#[cfg(feature = "virtio-fs")]
pub(crate) fn get_filesystem_driver() -> Option<&'static InterruptTicketMutex<VirtioFsDriver>> {
MMIO_DRIVERS
.get()?
.iter()
.find_map(|drv| drv.get_filesystem_driver())
}

pub fn init_drivers() {
without_interrupts(|| {
if let Some(fdt) = crate::env::fdt() {
Expand Down Expand Up @@ -118,94 +143,58 @@ pub fn init_drivers() {
let id = mmio.as_ptr().device_id().read();
let cpu_id: usize = 0;

match id {
#[cfg(feature = "virtio-net")]
virtio::Id::Net => {
debug!(
"Found network card at {mmio:p}, irq: {irq}, type: {irqtype}, flags: {irqflags}"
);
if let Ok(VirtioDriver::Net(drv)) =
mmio_virtio::init_device(mmio, irq.try_into().unwrap())
&& let Some(gic) = GIC.lock().as_mut()
{
// enable timer interrupt
let virtio_irqid = if irqtype == 1 {
IntId::ppi(irq)
} else if irqtype == 0 {
IntId::spi(irq)
} else {
panic!("Invalid interrupt type");
};
gic.set_interrupt_priority(
virtio_irqid,
Some(cpu_id),
0x00,
);
if (irqflags & 0xf) == 4 || (irqflags & 0xf) == 8 {
gic.set_trigger(
virtio_irqid,
Some(cpu_id),
Trigger::Level,
);
} else if (irqflags & 0xf) == 2 || (irqflags & 0xf) == 1 {
gic.set_trigger(
virtio_irqid,
Some(cpu_id),
Trigger::Edge,
);
} else {
panic!("Invalid interrupt level!");
}
gic.enable_interrupt(virtio_irqid, Some(cpu_id), true);

*NETWORK_DEVICE.lock() = Some(*drv);
}
if id == virtio::Id::Reserved {
continue;
}

debug!(
"Found {id:?} card at {mmio:p}, irq: {irq}, type: {irqtype}, flags: {irqflags}"
);

let drv = match mmio_virtio::init_device(mmio, irq.try_into().unwrap())
{
Ok(drv) => drv,
Err(err) => {
error!("{err}");
continue;
}
};

let mut gic = GIC.lock();
let Some(gic) = gic.as_mut() else {
error!("No GIC found");
continue;
};

// enable timer interrupt
let virtio_irqid = if irqtype == 1 {
IntId::ppi(irq)
} else if irqtype == 0 {
IntId::spi(irq)
} else {
panic!("Invalid interrupt type");
};
gic.set_interrupt_priority(virtio_irqid, Some(cpu_id), 0x00);
if (irqflags & 0xf) == 4 || (irqflags & 0xf) == 8 {
gic.set_trigger(virtio_irqid, Some(cpu_id), Trigger::Level);
} else if (irqflags & 0xf) == 2 || (irqflags & 0xf) == 1 {
gic.set_trigger(virtio_irqid, Some(cpu_id), Trigger::Edge);
} else {
panic!("Invalid interrupt level!");
}
gic.enable_interrupt(virtio_irqid, Some(cpu_id), true);

match drv {
#[cfg(feature = "virtio-console")]
virtio::Id::Console => {
debug!(
"Found console at {mmio:p}, irq: {irq}, type: {irqtype}, flags: {irqflags}"
);
if let Ok(VirtioDriver::Console(drv)) =
mmio_virtio::init_device(mmio, irq.try_into().unwrap())
&& let Some(gic) = GIC.lock().as_mut()
{
// enable timer interrupt
let virtio_irqid = if irqtype == 1 {
IntId::ppi(irq)
} else if irqtype == 0 {
IntId::spi(irq)
} else {
panic!("Invalid interrupt type");
};
gic.set_interrupt_priority(
virtio_irqid,
Some(cpu_id),
0x00,
);
if (irqflags & 0xf) == 4 || (irqflags & 0xf) == 8 {
gic.set_trigger(
virtio_irqid,
Some(cpu_id),
Trigger::Level,
);
} else if (irqflags & 0xf) == 2 || (irqflags & 0xf) == 1 {
gic.set_trigger(
virtio_irqid,
Some(cpu_id),
Trigger::Edge,
);
} else {
panic!("Invalid interrupt level!");
}
gic.enable_interrupt(virtio_irqid, Some(cpu_id), true);

register_driver(MmioDriver::VirtioConsole(
hermit_sync::InterruptTicketMutex::new(*drv),
));
}
}
_ => {}
VirtioDriver::Console(drv) => register_driver(MmioDriver::VirtioConsole(
InterruptTicketMutex::new(*drv),
)),
#[cfg(feature = "virtio-fs")]
VirtioDriver::FileSystem(drv) => register_driver(MmioDriver::VirtioFs(
hermit_sync::InterruptTicketMutex::new(*drv),
)),
#[cfg(feature = "virtio-net")]
VirtioDriver::Net(drv) => *NETWORK_DEVICE.lock() = Some(*drv),
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/arch/aarch64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ pub mod core_local;
pub mod interrupts;
#[cfg(feature = "kernel-stack")]
pub mod kernel_stack;
#[cfg(all(
not(feature = "pci"),
any(feature = "virtio-net", feature = "virtio-console")
))]
#[cfg(all(not(feature = "pci"), feature = "virtio"))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
Loading