From 316ea6170228f1ab3c6f5af07b3c4c09b8dfd1df Mon Sep 17 00:00:00 2001 From: Astro Date: Wed, 10 Jun 2020 00:38:59 +0200 Subject: [PATCH] sdio: move ADMA2_DESCR32_TABLE into SdCard --- libboard_zynq/src/sdio/adma.rs | 86 ++++++++++++++++--------------- libboard_zynq/src/sdio/sd_card.rs | 10 ++-- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/libboard_zynq/src/sdio/adma.rs b/libboard_zynq/src/sdio/adma.rs index fd85101..9669f42 100644 --- a/libboard_zynq/src/sdio/adma.rs +++ b/libboard_zynq/src/sdio/adma.rs @@ -14,10 +14,6 @@ pub struct Adma2Desc32 { address: VolatileCell, } -// Default::default() cannot be used as it is not a constant function... -static mut ADMA2_DESCR32_TABLE: MaybeUninit<[Adma2Desc32; 32]> = MaybeUninit::uninit(); - -#[allow(unused)] const DESC_MAX_LENGTH: u32 = 65536; register!(desc32_attribute, Desc32Attribute, VolatileCell, u16); @@ -26,45 +22,53 @@ register_bit!(desc32_attribute, int, 2); register_bit!(desc32_attribute, end, 1); register_bit!(desc32_attribute, valid, 0); -/// Initialize `ADMA2_DESCR32_TABLE` and setup `adma_system_address` -pub fn setup_adma2_descr32(sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) { - let descr_table = unsafe { &mut *ADMA2_DESCR32_TABLE.as_mut_ptr() }; - let blk_size = sdio - .regs - .block_size_block_count - .read() - .transfer_block_size() as u32; +pub struct Adma2DescTable(MaybeUninit<[Adma2Desc32; 32]>); - let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH { - 1 - } else { - blk_size * blk_cnt / DESC_MAX_LENGTH - + if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 { - 0 - } else { - 1 - } - } as usize; +impl Adma2DescTable { + pub fn new() -> Self { + Adma2DescTable(MaybeUninit::uninit()) + } - let ptr = buffer.as_ptr() as u32; - for desc_num in 0..total_desc_lines { - descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH); - descr_table[desc_num].attribute.write( - Desc32Attribute::zeroed() - .trans(true) - .valid(true) + /// Initialize the table and setup `adma_system_address` + pub fn setup(&mut self, sdio: &mut SDIO, blk_cnt: u32, buffer: &[u8]) { + let descr_table = unsafe { &mut *self.0.as_mut_ptr() }; + let blk_size = sdio + .regs + .block_size_block_count + .read() + .transfer_block_size() as u32; + + let total_desc_lines = if blk_size * blk_cnt < DESC_MAX_LENGTH { + 1 + } else { + blk_size * blk_cnt / DESC_MAX_LENGTH + + if (blk_size * blk_cnt) % DESC_MAX_LENGTH == 0 { + 0 + } else { + 1 + } + } as usize; + + let ptr = buffer.as_ptr() as u32; + for desc_num in 0..total_desc_lines { + descr_table[desc_num].address.set(ptr + (desc_num as u32) * DESC_MAX_LENGTH); + descr_table[desc_num].attribute.write( + Desc32Attribute::zeroed() + .trans(true) + .valid(true) + ); + // 0 is the max length (65536) + descr_table[desc_num].length.set(0); + } + descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true)); + descr_table[total_desc_lines - 1].length.set( + (blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16, ); - // 0 is the max length (65536) - descr_table[desc_num].length.set(0); + unsafe { + sdio.regs + .adma_system_address + .write(descr_table.as_ptr() as u32); + } + cache::dcci_slice(descr_table); } - descr_table[total_desc_lines - 1].attribute.modify(|_, w| w.end(true)); - descr_table[total_desc_lines - 1].length.set( - (blk_cnt * blk_size - ((total_desc_lines as u32) - 1) * DESC_MAX_LENGTH) as u16, - ); - unsafe { - sdio.regs - .adma_system_address - .write(descr_table.as_ptr() as u32); - } - cache::dcci_slice(descr_table); } diff --git a/libboard_zynq/src/sdio/sd_card.rs b/libboard_zynq/src/sdio/sd_card.rs index 0826574..d817f27 100644 --- a/libboard_zynq/src/sdio/sd_card.rs +++ b/libboard_zynq/src/sdio/sd_card.rs @@ -1,4 +1,4 @@ -use super::{adma::setup_adma2_descr32, cmd, CardType, CmdTransferError, SDIO}; +use super::{adma::Adma2DescTable, cmd, CardType, CmdTransferError, SDIO}; use libcortex_a9::cache; use libregister::{RegisterR, RegisterRW, RegisterW}; use log::debug; @@ -25,6 +25,7 @@ enum CardVersion { pub struct SdCard { sdio: SDIO, + adma2_desc_table: Adma2DescTable, card_version: CardVersion, hcs: bool, card_id: [u32; 4], @@ -165,6 +166,7 @@ impl SdCard { }; let mut _self = SdCard { sdio, + adma2_desc_table: Adma2DescTable::new(), card_version: CardVersion::SdVer1, hcs: false, card_id: [0, 0, 0, 0], @@ -203,7 +205,7 @@ impl SdCard { self.sdio.set_block_size(512)?; } - setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer); + self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer); // invalidate D cache, required for ZC706, not sure for Cora Z7 10 cache::dcci_slice(buffer); @@ -256,7 +258,7 @@ impl SdCard { self.sdio.set_block_size(512)?; } - setup_adma2_descr32(&mut self.sdio, block_cnt as u32, buffer); + self.adma2_desc_table.setup(&mut self.sdio, block_cnt as u32, buffer); // invalidate D cache, required for ZC706, not sure for Cora Z7 10 cache::dcci_slice(buffer); @@ -303,7 +305,7 @@ impl SdCard { .block_size_block_count .modify(|_, w| w.transfer_block_size(blk_size)); - setup_adma2_descr32(&mut self.sdio, blk_cnt as u32, buf); + self.adma2_desc_table.setup(&mut self.sdio, blk_cnt as u32, buf); cache::dcci_slice(buf); self.sdio.cmd_transfer_with_mode( ACMD51,