Compare commits
2 Commits
f199ac68b4
...
7cdf6c0918
Author | SHA1 | Date |
---|---|---|
Astro | 7cdf6c0918 | |
Astro | fc39885d3b |
11
src/main.rs
11
src/main.rs
|
@ -20,6 +20,7 @@ mod regs;
|
|||
mod cortex_a9;
|
||||
mod stdio;
|
||||
mod zynq;
|
||||
mod ram;
|
||||
|
||||
use crate::regs::{RegisterR, RegisterW};
|
||||
use crate::cortex_a9::{asm, regs::*, mmu};
|
||||
|
@ -87,16 +88,6 @@ const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
|
|||
fn main() {
|
||||
println!("Main.");
|
||||
|
||||
zynq::clocks::CpuClocks::enable_ddr(1_066_666_666);
|
||||
let pll_status = zynq::slcr::RegisterBlock::new().pll_status.read();
|
||||
println!("PLLs: {}", pll_status);
|
||||
let clocks = zynq::clocks::CpuClocks::get();
|
||||
println!("Clocks: {:?}", clocks);
|
||||
println!("CPU speeds: {}/{}/{}/{} MHz",
|
||||
clocks.cpu_6x4x() / 1_000_000,
|
||||
clocks.cpu_3x2x() / 1_000_000,
|
||||
clocks.cpu_2x() / 1_000_000,
|
||||
clocks.cpu_1x() / 1_000_000);
|
||||
let mut ddr = zynq::ddr::DdrRam::new();
|
||||
println!("DDR: {:?}", ddr.status());
|
||||
ddr.memtest();
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
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() }
|
||||
}
|
||||
}
|
|
@ -10,8 +10,8 @@ mod regs;
|
|||
const DDR_FREQ: u32 = 666_666_666;
|
||||
|
||||
#[cfg(feature = "target_cora_z7_10")]
|
||||
/// Micron MT41K256M16HA-125: 800 MHz DDR3L
|
||||
const DDR_FREQ: u32 = 800_000_000;
|
||||
/// Micron MT41K256M16HA-125: 800 MHz DDR3L, max supported 533 MHz
|
||||
const DDR_FREQ: u32 = 533_333_333;
|
||||
|
||||
/// MT41K256M16HA-125
|
||||
const DCI_FREQ: u32 = 10_000_000;
|
||||
|
@ -22,8 +22,7 @@ pub struct DdrRam {
|
|||
|
||||
impl DdrRam {
|
||||
pub fn new() -> Self {
|
||||
let clocks = CpuClocks::get();
|
||||
Self::clock_setup(&clocks);
|
||||
let clocks = Self::clock_setup();
|
||||
Self::calibrate_iob_impedance(&clocks);
|
||||
Self::configure_iob();
|
||||
|
||||
|
@ -35,8 +34,10 @@ impl DdrRam {
|
|||
|
||||
/// Zynq-7000 AP SoC Technical Reference Manual:
|
||||
/// 10.6.1 DDR Clock Initialization
|
||||
fn clock_setup(clocks: &CpuClocks) {
|
||||
CpuClocks::enable_ddr(1_066_666_666);
|
||||
fn clock_setup() -> CpuClocks {
|
||||
let clocks = CpuClocks::get();
|
||||
CpuClocks::enable_ddr(clocks.cpu);
|
||||
let clocks = CpuClocks::get();
|
||||
|
||||
let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8;
|
||||
let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2;
|
||||
|
@ -50,6 +51,7 @@ impl DdrRam {
|
|||
.ddr_3xclk_divisor(ddr3x_clk_divisor)
|
||||
);
|
||||
});
|
||||
clocks
|
||||
}
|
||||
|
||||
/// Zynq-7000 AP SoC Technical Reference Manual:
|
||||
|
@ -57,7 +59,7 @@ impl DdrRam {
|
|||
fn calibrate_iob_impedance(clocks: &CpuClocks) {
|
||||
let divisor0 = (clocks.ddr / DCI_FREQ)
|
||||
.max(1).min(63) as u8;
|
||||
let divisor1 = (clocks.ddr / DCI_FREQ / u32::from(divisor0))
|
||||
let divisor1 = 1 + (clocks.ddr / DCI_FREQ / u32::from(divisor0))
|
||||
.max(1).min(63) as u8;
|
||||
|
||||
slcr::RegisterBlock::unlocked(|slcr| {
|
||||
|
@ -76,7 +78,7 @@ impl DdrRam {
|
|||
slcr.ddriob_dci_ctrl.modify(|_, w|
|
||||
w.reset(true)
|
||||
);
|
||||
// Step 3.b. for DDR3
|
||||
// Step 3.b. for DDR3/DDR3L
|
||||
slcr.ddriob_dci_ctrl.modify(|_, w|
|
||||
w.nref_opt1(0)
|
||||
.nref_opt2(0)
|
||||
|
|
Loading…
Reference in New Issue