From 5c62716a996c45b1e70b4ea1df5a932e0994f363 Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 31 Oct 2019 03:15:13 +0100 Subject: [PATCH] zynq::eth: switch rx and tx descriptor words to vcell vcell can be initialized cleanly. --- Cargo.lock | 1 + Cargo.toml | 1 + src/regs.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- src/zynq/eth/rx.rs | 14 ++++++++++++-- src/zynq/eth/tx.rs | 14 ++++++++++++-- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d458b0d..996bb70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,7 @@ dependencies = [ "linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index c5b98f9..7255169 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ default = ["target_zc706"] [dependencies] r0 = "0.2" +vcell = "0.1" volatile-register = "0.2" bit_field = "0.10" compiler_builtins = { version = "~0.1", default-features = false, features = ["mem", "no-lang-items"]} diff --git a/src/regs.rs b/src/regs.rs index 39732b9..760acf9 100644 --- a/src/regs.rs +++ b/src/regs.rs @@ -2,6 +2,7 @@ //! svd2rust generates. #![allow(unused)] +use vcell::VolatileCell; use volatile_register::{RO, WO, RW}; use bit_field::BitField; @@ -64,7 +65,7 @@ macro_rules! register_r { #[macro_export] macro_rules! register_w { ($mod_name: ident, $struct_name: ident) => ( - impl crate::regs::RegisterW for $struct_name { + impl crate::regs::RegisterW for $struct_name { type W = $mod_name::Write; fn zeroed() -> $mod_name::Write { @@ -96,6 +97,40 @@ macro_rules! register_rw { ); } +#[doc(hidden)] +#[macro_export] +macro_rules! register_vcell { + ($mod_name: ident, $struct_name: ident) => ( + impl crate::regs::RegisterR for $struct_name { + type R = $mod_name::Read; + + fn read(&self) -> Self::R { + let inner = self.inner.get(); + $mod_name::Read { inner } + } + } + impl crate::regs::RegisterW for $struct_name { + type W = $mod_name::Write; + + fn zeroed() -> $mod_name::Write { + $mod_name::Write { inner: 0 } + } + + fn write(&mut self, w: Self::W) { + self.inner.set(w.inner); + } + } + impl crate::regs::RegisterRW for $struct_name { + fn modify Self::W>(&mut self, f: F) { + let r = self.read(); + let w = $mod_name::Write { inner: r.inner }; + let w = f(r, w); + self.write(w); + } + } + ); +} + /// Main macro for register definition #[macro_export] macro_rules! register { @@ -118,6 +153,12 @@ macro_rules! register { crate::register_w!($mod_name, $struct_name); crate::register_rw!($mod_name, $struct_name); ); + + // Define read-write register + ($mod_name: ident, $struct_name: ident, VolatileCell, $inner: ty) => ( + crate::register_common!($mod_name, $struct_name, VolatileCell<$inner>, $inner); + crate::register_vcell!($mod_name, $struct_name); + ); } /// Define a 1-bit field of a register diff --git a/src/zynq/eth/rx.rs b/src/zynq/eth/rx.rs index 940f28b..21c8622 100644 --- a/src/zynq/eth/rx.rs +++ b/src/zynq/eth/rx.rs @@ -1,4 +1,5 @@ use core::ops::Deref; +use vcell::VolatileCell; use crate::{register, register_bit, register_bits, regs::*}; use super::MTU; @@ -19,7 +20,16 @@ pub struct DescEntry { word1: DescWord1, } -register!(desc_word0, DescWord0, RW, u32); +impl DescEntry { + pub fn zeroed() -> Self { + DescEntry { + word0: DescWord0 { inner: VolatileCell::new(0) }, + word1: DescWord1 { inner: VolatileCell::new(0) }, + } + } +} + +register!(desc_word0, DescWord0, VolatileCell, u32); register_bit!(desc_word0, /// true if owned by software, false if owned by hardware used, 0); @@ -28,7 +38,7 @@ register_bit!(desc_word0, wrap, 1); register_bits!(desc_word0, address, u32, 2, 31); -register!(desc_word1, DescWord1, RW, u32); +register!(desc_word1, DescWord1, VolatileCell, u32); register_bits!(desc_word1, frame_length_lsbs, u16, 0, 12); register_bit!(desc_word1, bad_fcs, 13); register_bit!(desc_word1, start_of_frame, 14); diff --git a/src/zynq/eth/tx.rs b/src/zynq/eth/tx.rs index 5685340..8f506b0 100644 --- a/src/zynq/eth/tx.rs +++ b/src/zynq/eth/tx.rs @@ -1,4 +1,5 @@ use core::ops::{Deref, DerefMut}; +use vcell::VolatileCell; use crate::{register, register_bit, register_bits, regs::*}; use crate::cortex_a9::asm; use super::{MTU, regs}; @@ -10,10 +11,10 @@ pub struct DescEntry { word1: DescWord1, } -register!(desc_word0, DescWord0, RW, u32); +register!(desc_word0, DescWord0, VolatileCell, u32); register_bits!(desc_word0, address, u32, 0, 31); -register!(desc_word1, DescWord1, RW, u32); +register!(desc_word1, DescWord1, VolatileCell, u32); register_bits!(desc_word1, length, u16, 0, 13); register_bit!(desc_word1, last_buffer, 15); register_bit!(desc_word1, no_crc_append, 16); @@ -28,6 +29,15 @@ register_bit!(desc_word1, /// true if owned by software, false if owned by hardware used, 31); +impl DescEntry { + pub fn zeroed() -> Self { + DescEntry { + word0: DescWord0 { inner: VolatileCell::new(0) }, + word1: DescWord1 { inner: VolatileCell::new(0) }, + } + } +} + /// Number of descriptors pub const DESCS: usize = 8;