Compare commits

..

5 Commits

Author SHA1 Message Date
Astro 5c62716a99 zynq::eth: switch rx and tx descriptor words to vcell
vcell can be initialized cleanly.
2019-10-31 03:15:13 +01:00
Astro 1f728686ff rm ram, add linked_list_allocator on ddr 2019-10-31 01:41:10 +01:00
Astro e248d3d3b1 zynq::ddr: optimize memtest 2019-10-31 01:32:45 +01:00
Astro 91bab76ab6 zynq::ddr: fix usable ram size 2019-10-31 01:27:49 +01:00
Astro 43501003f9 openocd/zc706: decimate `adapter_khz` for reliability 2019-10-31 00:28:19 +01:00
9 changed files with 119 additions and 102 deletions

17
Cargo.lock generated
View File

@ -20,6 +20,14 @@ name = "compiler_builtins"
version = "0.1.19" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "linked_list_allocator"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "managed" name = "managed"
version = "0.7.1" version = "0.7.1"
@ -40,6 +48,11 @@ dependencies = [
"managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "vcell" name = "vcell"
version = "0.1.0" version = "0.1.0"
@ -59,8 +72,10 @@ version = "0.0.0"
dependencies = [ dependencies = [
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compiler_builtins 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"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)", "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)", "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)", "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -69,8 +84,10 @@ dependencies = [
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum compiler_builtins 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "4e32b9fc11fdb3aefbd0a4761a8d3a2b7419608b759fa14a26525df4ea5deaba" "checksum compiler_builtins 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "4e32b9fc11fdb3aefbd0a4761a8d3a2b7419608b759fa14a26525df4ea5deaba"
"checksum linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "47314ec1d29aa869ee7cb5a5be57be9b1055c56567d59c3fb6689926743e0bea"
"checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6" "checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" "checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34" "checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34"
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d" "checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d"
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" "checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"

View File

@ -19,7 +19,9 @@ default = ["target_zc706"]
[dependencies] [dependencies]
r0 = "0.2" r0 = "0.2"
vcell = "0.1"
volatile-register = "0.2" volatile-register = "0.2"
bit_field = "0.10" bit_field = "0.10"
compiler_builtins = { version = "~0.1", default-features = false, features = ["mem", "no-lang-items"]} compiler_builtins = { version = "~0.1", default-features = false, features = ["mem", "no-lang-items"]}
smoltcp = { version = "0.5", default-features = false, features = ["proto-ipv4", "socket-tcp"] } smoltcp = { version = "0.5", default-features = false, features = ["proto-ipv4", "socket-tcp"] }
linked_list_allocator = "0.6"

View File

@ -1,5 +1,5 @@
source ./digilent_jtag_smt2_nc.cfg source ./digilent_jtag_smt2_nc.cfg
adapter_khz 10000 adapter_khz 1000
set PL_TAPID 0x23731093 set PL_TAPID 0x23731093
set SMP 1 set SMP 1

View File

@ -5,6 +5,7 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(compiler_builtins_lib)] #![feature(compiler_builtins_lib)]
#![feature(never_type)] #![feature(never_type)]
#![feature(alloc_error_handler)]
// TODO: disallow unused/dead_code when code moves into a lib crate // TODO: disallow unused/dead_code when code moves into a lib crate
#![allow(dead_code)] #![allow(dead_code)]
@ -15,12 +16,12 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface};
use smoltcp::time::Instant; use smoltcp::time::Instant;
use smoltcp::socket::SocketSet; use smoltcp::socket::SocketSet;
use linked_list_allocator::LockedHeap;
mod regs; mod regs;
mod cortex_a9; mod cortex_a9;
mod stdio; mod stdio;
mod zynq; mod zynq;
mod ram;
use crate::regs::{RegisterR, RegisterW}; use crate::regs::{RegisterR, RegisterW};
use crate::cortex_a9::{asm, regs::*, mmu}; use crate::cortex_a9::{asm, regs::*, mmu};
@ -83,6 +84,9 @@ fn l1_cache_init() {
dciall(); dciall();
} }
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
fn main() { fn main() {
@ -92,6 +96,10 @@ fn main() {
println!("DDR: {:?}", ddr.status()); println!("DDR: {:?}", ddr.status());
ddr.memtest(); ddr.memtest();
unsafe {
ALLOCATOR.lock().init(ddr.ptr::<u8>() as usize, ddr.size());
}
let eth = zynq::eth::Eth::default(HWADDR.clone()); let eth = zynq::eth::Eth::default(HWADDR.clone());
println!("Eth on"); println!("Eth on");
@ -176,6 +184,11 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
loop {} loop {}
} }
#[alloc_error_handler]
fn alloc_error(_: core::alloc::Layout) -> ! {
panic!("alloc_error")
}
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PrefetchAbort() { pub unsafe extern "C" fn PrefetchAbort() {
println!("PrefetchAbort"); println!("PrefetchAbort");

View File

@ -1,75 +0,0 @@
use core::mem::{align_of, size_of};
pub trait RAM {
#[inline(always)]
fn addr(&self) -> usize;
#[inline(always)]
fn size(&self) -> usize;
#[inline(always)]
fn into_memory_region(&self) -> MemoryRegion {
MemoryRegion {
addr: self.addr(),
size: self.size(),
}
}
}
pub struct MemoryRegion {
addr: usize,
size: usize,
}
impl MemoryRegion {
#[inline(always)]
fn split(&mut self, offset: usize) -> MemoryRegion {
if offset > self.size {
panic!("StaticAllocator: unable to split {}/{} bytes", offset, self.size);
}
let result = MemoryRegion {
addr: self.addr,
size: offset,
};
self.addr += offset;
self.size -= offset;
result
}
unsafe fn clear<T>(self) -> *mut T {
let result = self.addr as *mut T;
for b in core::slice::from_raw_parts_mut::<u8>(result as *mut u8, self.size) {
*b = 0;
}
result
}
pub fn align(&mut self, alignment: usize) {
let mask = alignment - 1;
let addr = (self.addr | mask) + 1;
self.size -= addr - self.addr;
self.addr = addr;
}
}
pub struct StaticAllocator {
free: MemoryRegion,
}
impl StaticAllocator {
pub fn new<R: RAM>(r: R) -> Self {
StaticAllocator {
free: r.into_memory_region(),
}
}
pub fn alloc<'a: 'b, 'b, T: Sized>(&'a mut self) -> &'b mut T {
self.free.align(align_of::<T>());
let size = size_of::<T>();
let region = self.free.split(size);
unsafe { &mut *region.clear() }
}
}

View File

@ -2,6 +2,7 @@
//! svd2rust generates. //! svd2rust generates.
#![allow(unused)] #![allow(unused)]
use vcell::VolatileCell;
use volatile_register::{RO, WO, RW}; use volatile_register::{RO, WO, RW};
use bit_field::BitField; use bit_field::BitField;
@ -64,7 +65,7 @@ macro_rules! register_r {
#[macro_export] #[macro_export]
macro_rules! register_w { macro_rules! register_w {
($mod_name: ident, $struct_name: ident) => ( ($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; type W = $mod_name::Write;
fn zeroed() -> $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<F: FnOnce(Self::R, Self::W) -> 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 /// Main macro for register definition
#[macro_export] #[macro_export]
macro_rules! register { macro_rules! register {
@ -118,6 +153,12 @@ macro_rules! register {
crate::register_w!($mod_name, $struct_name); crate::register_w!($mod_name, $struct_name);
crate::register_rw!($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 /// Define a 1-bit field of a register

View File

@ -1,5 +1,5 @@
use crate::regs::{RegisterR, RegisterW, RegisterRW}; use crate::regs::{RegisterR, RegisterW, RegisterRW};
use crate::println; use crate::{print, println};
use super::slcr; use super::slcr;
use super::clocks::CpuClocks; use super::clocks::CpuClocks;
@ -178,15 +178,15 @@ impl DdrRam {
} }
// TODO: move into trait // TODO: move into trait
pub fn ptr(&mut self) -> *mut u8 { pub fn ptr<T>(&mut self) -> *mut T {
0x0010_0000 as *mut _ 0x0010_0000 as *mut _
} }
pub fn size(&self) -> usize { pub fn size(&self) -> usize {
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
let megabytes = 1024; let megabytes = 511;
#[cfg(feature = "target_cora_z7_10")] #[cfg(feature = "target_cora_z7_10")]
let megabytes = 512; let megabytes = 511;
megabytes * 1024 * 1024 megabytes * 1024 * 1024
} }
@ -195,28 +195,27 @@ impl DdrRam {
let slice = unsafe { let slice = unsafe {
core::slice::from_raw_parts_mut(self.ptr(), self.size()) core::slice::from_raw_parts_mut(self.ptr(), self.size())
}; };
let patterns: &'static [u8] = &[0, 0xff, 0x55, 0xaa, 0]; let patterns: &'static [u32] = &[0xffff_ffff, 0x5555_5555, 0xaaaa_aaaa, 0];
let mut expected = None; let mut expected = None;
for (i, pattern) in patterns.iter().enumerate() { for (i, pattern) in patterns.iter().enumerate() {
println!("memtest phase {} (status: {:?})", i, self.status()); println!("memtest phase {} (status: {:?})", i, self.status());
// shift by 7 bits to be able to multiply with 100 (%) for megabyte in 0..=(slice.len() / (1024 * 1024)) {
let progress_max = (slice.len() >> 7) - 1; let start = megabyte * 1024 * 1024 / 4;
let mut progress = 0; let end = ((megabyte + 1) * 1024 * 1024 / 4).min(slice.len());
for (j, b) in slice.iter_mut().enumerate() { for b in slice[start..end].iter_mut() {
expected.map(|expected| { expected.map(|expected| {
let read: u8 = *b; let read: u32 = *b;
if read != expected { if read != expected {
println!("{:08X}: expected {:02X}, read {:02X}", b as *mut u8 as usize, expected, read); println!("{:08X}: expected {:08X}, read {:08X}", b as *mut _ as usize, expected, read);
} }
}); });
*b = *pattern; *b = *pattern;
let new_progress = 100 * (j >> 7) / progress_max;
if new_progress != progress {
progress = new_progress;
println!("{}%", progress);
} }
print!("\r{} MB", megabyte);
} }
println!(" Ok");
expected = Some(*pattern); expected = Some(*pattern);
} }

View File

@ -1,4 +1,5 @@
use core::ops::Deref; use core::ops::Deref;
use vcell::VolatileCell;
use crate::{register, register_bit, register_bits, regs::*}; use crate::{register, register_bit, register_bits, regs::*};
use super::MTU; use super::MTU;
@ -19,7 +20,16 @@ pub struct DescEntry {
word1: DescWord1, 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, register_bit!(desc_word0,
/// true if owned by software, false if owned by hardware /// true if owned by software, false if owned by hardware
used, 0); used, 0);
@ -28,7 +38,7 @@ register_bit!(desc_word0,
wrap, 1); wrap, 1);
register_bits!(desc_word0, address, u32, 2, 31); 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_bits!(desc_word1, frame_length_lsbs, u16, 0, 12);
register_bit!(desc_word1, bad_fcs, 13); register_bit!(desc_word1, bad_fcs, 13);
register_bit!(desc_word1, start_of_frame, 14); register_bit!(desc_word1, start_of_frame, 14);

View File

@ -1,4 +1,5 @@
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use vcell::VolatileCell;
use crate::{register, register_bit, register_bits, regs::*}; use crate::{register, register_bit, register_bits, regs::*};
use crate::cortex_a9::asm; use crate::cortex_a9::asm;
use super::{MTU, regs}; use super::{MTU, regs};
@ -10,10 +11,10 @@ pub struct DescEntry {
word1: DescWord1, word1: DescWord1,
} }
register!(desc_word0, DescWord0, RW, u32); register!(desc_word0, DescWord0, VolatileCell, u32);
register_bits!(desc_word0, address, u32, 0, 31); 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_bits!(desc_word1, length, u16, 0, 13);
register_bit!(desc_word1, last_buffer, 15); register_bit!(desc_word1, last_buffer, 15);
register_bit!(desc_word1, no_crc_append, 16); 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 /// true if owned by software, false if owned by hardware
used, 31); used, 31);
impl DescEntry {
pub fn zeroed() -> Self {
DescEntry {
word0: DescWord0 { inner: VolatileCell::new(0) },
word1: DescWord1 { inner: VolatileCell::new(0) },
}
}
}
/// Number of descriptors /// Number of descriptors
pub const DESCS: usize = 8; pub const DESCS: usize = 8;