Skip to content

Commit

Permalink
Merge pull request #109 from lhw2002426/main
Browse files Browse the repository at this point in the history
add sd card driver for raspi4
  • Loading branch information
equation314 authored Aug 2, 2023
2 parents 26fc1a0 + 955b661 commit 907c60d
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 24 deletions.
63 changes: 41 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/driver_block/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ documentation = "https://rcore-os.github.io/arceos/driver_common/index.html"

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

[dependencies]
log = "0.4"
driver_common = { path = "../driver_common" }
bcm2835-sdhci = { git = "https://github.com/lhw2002426/bcm2835-sdhci.git", rev = "e974f16", optional = true }
88 changes: 88 additions & 0 deletions crates/driver_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 bcm2835_sdhci::Bcm2835SDhci::{EmmcCtl, BLOCK_SIZE};
use bcm2835_sdhci::SDHCIError;
use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType};

/// 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()
}
}
3 changes: 3 additions & 0 deletions crates/driver_block/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#[cfg(feature = "ramdisk")]
pub mod ramdisk;

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

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

Expand Down
1 change: 1 addition & 0 deletions modules/axdriver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ virtio-blk = ["block", "virtio", "driver_virtio/block"]
virtio-net = ["net", "virtio", "driver_virtio/net"]
virtio-gpu = ["display", "virtio", "driver_virtio/gpu"]
ramdisk = ["block", "driver_block/ramdisk"]
bcm2835-sdhci = ["block", "driver_block/bcm2835-sdhci"]
ixgbe = ["net", "driver_net/ixgbe", "dep:axalloc", "dep:axhal"]
# more devices example: e1000 = ["net", "driver_net/e1000"]

Expand Down
2 changes: 1 addition & 1 deletion modules/axdriver/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const NET_DEV_FEATURES: &[&str] = &["ixgbe", "virtio-net"];
const BLOCK_DEV_FEATURES: &[&str] = &["ramdisk", "virtio-blk"];
const BLOCK_DEV_FEATURES: &[&str] = &["ramdisk", "bcm2835-sdhci", "virtio-blk"];
const DISPLAY_DEV_FEATURES: &[&str] = &["virtio-gpu"];

fn has_feature(feature: &str) -> bool {
Expand Down
14 changes: 14 additions & 0 deletions modules/axdriver/src/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ cfg_if::cfg_if! {
}
}

cfg_if::cfg_if! {
if #[cfg(block_dev = "bcm2835-sdhci")]{
pub struct BcmSdhciDriver;
register_block_driver!(MmckDriver, driver_block::bcm2835sdhci::SDHCIDriver);

impl DriverProbe for BcmSdhciDriver {
fn probe_global() -> Option<AxDeviceEnum> {
debug!("mmc probe");
driver_block::bcm2835sdhci::SDHCIDriver::try_new().ok().map(AxDeviceEnum::from_block)
}
}
}
}

cfg_if::cfg_if! {
if #[cfg(net_dev = "ixgbe")] {
use crate::ixgbe::IxgbeHalImpl;
Expand Down
5 changes: 5 additions & 0 deletions modules/axdriver/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ macro_rules! for_each_drivers {
type $drv_type = crate::drivers::RamDiskDriver;
$code
}
#[cfg(block_dev = "bcm2835-sdhci")]
{
type $drv_type = crate::drivers::BcmSdhciDriver;
$code
}
#[cfg(net_dev = "ixgbe")]
{
type $drv_type = crate::drivers::IxgbeDriver;
Expand Down
2 changes: 1 addition & 1 deletion scripts/make/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ else
rust_elf := $(rust_target_dir)/$(rust_package)
endif

ifeq ($(filter $(MAKECMDGOALS),build run debug),$(MAKECMDGOALS))
ifeq ($(filter $(MAKECMDGOALS),build run debug chainboot),$(MAKECMDGOALS))
ifneq ($(V),)
$(info APP: "$(APP)")
$(info APP_TYPE: "$(APP_TYPE)")
Expand Down
3 changes: 3 additions & 0 deletions scripts/make/raspi4.mk
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,6 @@ openocd:
## Start GDB session
##------------------------------------------------------------------------------
gdb: RUSTC_MISC_ARGS += -C debuginfo=2
gdb: $(KERNEL_ELF)
$(call color_header, "Launching GDB")
@$(DOCKER_GDB) gdb-multiarch -q $(KERNEL_ELF)

0 comments on commit 907c60d

Please sign in to comment.