Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Jul 18, 2024
0 parents commit 78686a7
Show file tree
Hide file tree
Showing 23 changed files with 1,507 additions and 0 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: CI

on: [push, pull_request]

jobs:
ci:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust-toolchain: [nightly]
targets: [x86_64-unknown-linux-gnu, x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none-softfloat]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: ${{ matrix.rust-toolchain }}
components: rust-src, clippy, rustfmt
targets: ${{ matrix.targets }}
- name: Check rust version
run: rustc --version --verbose
- name: Check code format
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --target ${{ matrix.targets }} --all-features -- -A clippy::new_without_default
- name: Build
run: cargo build --target ${{ matrix.targets }} --all-features
- name: Unit test
if: ${{ matrix.targets == 'x86_64-unknown-linux-gnu' }}
run: cargo test --target ${{ matrix.targets }} -- --nocapture

doc:
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
contents: write
env:
default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }}
RUSTDOCFLAGS: -Zunstable-options --enable-index-page -D rustdoc::broken_intra_doc_links -D missing-docs
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: |
for crate in axdriver_base axdriver_block axdriver_net axdriver_display axdriver_pci axdriver_virtio;
do
cargo rustdoc --all-features -p $crate
done
- name: Deploy to Github Pages
if: ${{ github.ref == env.default-branch }}
uses: JamesIves/github-pages-deploy-action@v4
with:
single-commit: true
branch: gh-pages
folder: target/doc
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/target
/.vscode
.DS_Store
Cargo.lock
28 changes: 28 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[workspace]
resolver = "2"

members = [
"axdriver_base",
"axdriver_block",
"axdriver_net",
"axdriver_display",
"axdriver_pci",
"axdriver_virtio",
]

[workspace.package]
version = "0.1.0"
authors = ["Yuekai Jia <[email protected]>"]
license = "GPL-3.0-or-later OR Apache-2.0 OR MulanPSL-2.0"
homepage = "https://github.com/arceos-org/arceos"
documentation = "https://arceos-org.github.io/axdriver_crates"
repository = "https://github.com/arceos-org/axdriver_crates"
categories = ["os", "no-std", "hardware-support"]

[workspace.dependencies]
axdriver_base = { path = "axdriver_base", version = "0.1" }
axdriver_block = { path = "axdriver_block", version = "0.1" }
axdriver_net = { path = "axdriver_net", version = "0.1" }
axdriver_display = { path = "axdriver_display", version = "0.1" }
axdriver_pci = { path = "axdriver_pci", version = "0.1" }
axdriver_virtio = { path = "axdriver_virtio", version = "0.1" }
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# axdriver_crates

Crates for building device driver subsystems in the `no_std` environment:

- [axdriver_base](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_base): Common interfaces for all kinds of device drivers.
- [axdriver_block](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_block): Common traits and types for block storage drivers.
- [axdriver_net](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_net): Common traits and types for network device (NIC) drivers.
- [axdriver_display](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_display): Common traits and types for graphics device drivers.
- [axdriver_pci](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_pci): Structures and functions for PCI bus operations.
- [axdriver_virtio](https://github.com/arceos-org/axdriver_crates/tree/main/axdriver_virtio): Wrappers of some devices in the [virtio-drivers](https://docs.rs/virtio-drivers) crate, that implement traits in the `axdriver`-series crates.
14 changes: 14 additions & 0 deletions axdriver_base/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "axdriver_base"
edition = "2021"
description = "Common interfaces for all kinds of device drivers"
documentation = "https://arceos-org.github.io/axdriver_crates/axdriver_base"
keywords = ["arceos", "dirver"]
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true

[dependencies]
62 changes: 62 additions & 0 deletions axdriver_base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//! Device driver interfaces used by [ArceOS][1]. It provides common traits and
//! types for implementing a device driver.
//!
//! You have to use this crate with the following crates for corresponding
//! device types:
//!
//! - [`axdriver_block`][2]: Common traits for block storage drivers.
//! - [`axdriver_display`][3]: Common traits and types for graphics display drivers.
//! - [`axdriver_net`][4]: Common traits and types for network (NIC) drivers.
//!
//! [1]: https://github.com/arceos-org/arceos
//! [2]: ../axdriver_block/index.html
//! [3]: ../axdriver_display/index.html
//! [4]: ../axdriver_net/index.html
#![no_std]

/// All supported device types.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum DeviceType {
/// Block storage device (e.g., disk).
Block,
/// Character device (e.g., serial port).
Char,
/// Network device (e.g., ethernet card).
Net,
/// Graphic display device (e.g., GPU)
Display,
}

/// The error type for device operation failures.
#[derive(Debug)]
pub enum DevError {
/// An entity already exists.
AlreadyExists,
/// Try again, for non-blocking APIs.
Again,
/// Bad internal state.
BadState,
/// Invalid parameter/argument.
InvalidParam,
/// Input/output error.
Io,
/// Not enough space/cannot allocate memory (DMA).
NoMemory,
/// Device or resource is busy.
ResourceBusy,
/// This operation is unsupported or unimplemented.
Unsupported,
}

/// A specialized `Result` type for device operations.
pub type DevResult<T = ()> = Result<T, DevError>;

/// Common operations that require all device drivers to implement.
pub trait BaseDriverOps: Send + Sync {
/// The name of the device.
fn device_name(&self) -> &str;

/// The type of the device.
fn device_type(&self) -> DeviceType;
}
22 changes: 22 additions & 0 deletions axdriver_block/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "axdriver_block"
edition = "2021"
description = "Common traits and types for block storage drivers"
documentation = "https://arceos-org.github.io/axdriver_crates/axdriver_block"
keywords = ["arceos", "dirver", "blk"]
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true

[features]
ramdisk = []
bcm2835-sdhci = ["dep:bcm2835-sdhci"]
default = []

[dependencies]
log = "0.4"
axdriver_base = { workspace = true }
bcm2835-sdhci = { git = "https://github.com/lhw2002426/bcm2835-sdhci.git", rev = "e974f16", optional = true }
88 changes: 88 additions & 0 deletions axdriver_block/src/bcm2835sdhci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! SD card driver for raspi4
extern crate alloc;
use crate::BlockDriverOps;
use axdriver_base::{BaseDriverOps, DevError, DevResult, DeviceType};
use bcm2835_sdhci::Bcm2835SDhci::{EmmcCtl, BLOCK_SIZE};
use bcm2835_sdhci::SDHCIError;

/// BCM2835 SDHCI driver (Raspberry Pi SD card).
pub struct SDHCIDriver(EmmcCtl);

impl SDHCIDriver {
/// Initialize the SDHCI driver, returns `Ok` if successful.
pub fn try_new() -> DevResult<SDHCIDriver> {
let mut ctrl = EmmcCtl::new();
if ctrl.init() == 0 {
log::info!("BCM2835 sdhci: successfully initialized");
Ok(SDHCIDriver(ctrl))
} else {
log::warn!("BCM2835 sdhci: init failed");
Err(DevError::Io)
}
}
}

fn deal_sdhci_err(err: SDHCIError) -> DevError {
match err {
SDHCIError::Io => DevError::Io,
SDHCIError::AlreadyExists => DevError::AlreadyExists,
SDHCIError::Again => DevError::Again,
SDHCIError::BadState => DevError::BadState,
SDHCIError::InvalidParam => DevError::InvalidParam,
SDHCIError::NoMemory => DevError::NoMemory,
SDHCIError::ResourceBusy => DevError::ResourceBusy,
SDHCIError::Unsupported => DevError::Unsupported,
}
}

impl BaseDriverOps for SDHCIDriver {
fn device_type(&self) -> DeviceType {
DeviceType::Block
}

fn device_name(&self) -> &str {
"bcm2835_sdhci"
}
}

impl BlockDriverOps for SDHCIDriver {
fn read_block(&mut self, block_id: u64, buf: &mut [u8]) -> DevResult {
if buf.len() < BLOCK_SIZE {
return Err(DevError::InvalidParam);
}
let (prefix, aligned_buf, suffix) = unsafe { buf.align_to_mut::<u32>() };
if !prefix.is_empty() || !suffix.is_empty() {
return Err(DevError::InvalidParam);
}
self.0
.read_block(block_id as u32, 1, aligned_buf)
.map_err(deal_sdhci_err)
}

fn write_block(&mut self, block_id: u64, buf: &[u8]) -> DevResult {
if buf.len() < BLOCK_SIZE {
return Err(DevError::Io);
}
let (prefix, aligned_buf, suffix) = unsafe { buf.align_to::<u32>() };
if !prefix.is_empty() || !suffix.is_empty() {
return Err(DevError::InvalidParam);
}
self.0
.write_block(block_id as u32, 1, aligned_buf)
.map_err(deal_sdhci_err)
}
fn flush(&mut self) -> DevResult {
Ok(())
}

#[inline]
fn num_blocks(&self) -> u64 {
self.0.get_block_num()
}

#[inline]
fn block_size(&self) -> usize {
self.0.get_block_size()
}
}
38 changes: 38 additions & 0 deletions axdriver_block/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! Common traits and types for block storage device drivers (i.e. disk).
#![no_std]
#![feature(doc_auto_cfg)]

#[cfg(feature = "ramdisk")]
pub mod ramdisk;

#[cfg(feature = "bcm2835-sdhci")]
pub mod bcm2835sdhci;

#[doc(no_inline)]
pub use axdriver_base::{BaseDriverOps, DevError, DevResult, DeviceType};

/// Operations that require a block storage device driver to implement.
pub trait BlockDriverOps: BaseDriverOps {
/// The number of blocks in this storage device.
///
/// The total size of the device is `num_blocks() * block_size()`.
fn num_blocks(&self) -> u64;
/// The size of each block in bytes.
fn block_size(&self) -> usize;

/// Reads blocked data from the given block.
///
/// The size of the buffer may exceed the block size, in which case multiple
/// contiguous blocks will be read.
fn read_block(&mut self, block_id: u64, buf: &mut [u8]) -> DevResult;

/// Writes blocked data to the given block.
///
/// The size of the buffer may exceed the block size, in which case multiple
/// contiguous blocks will be written.
fn write_block(&mut self, block_id: u64, buf: &[u8]) -> DevResult;

/// Flushes the device to write all pending data to the storage.
fn flush(&mut self) -> DevResult;
}
Loading

0 comments on commit 78686a7

Please sign in to comment.