Ethernet and smoltcp/embassy-net support
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled

This commit is contained in:
2025-05-27 12:02:57 +02:00
committed by Robin Mueller
parent 037668e5a9
commit 602b8915e4
39 changed files with 8531 additions and 4239 deletions

View File

@@ -12,10 +12,13 @@ categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
cortex-a-rt = { version = "0.1", optional = true, features = ["vfp-dp"] }
cortex-ar = "0.2"
# cortex-ar = "0.2"
cortex-ar = { version = "0.2", path = "../../../Rust/cortex-ar/cortex-ar" }
arbitrary-int = "1.3"
zynq-mmu = { path = "../zynq-mmu", version = "0.1.0", default-features = false }
[features]
default = ["rt"]
default = ["rt", "zynq-mmu/cortex-ar"]
tools = []
rt = ["dep:cortex-a-rt"]

View File

@@ -4,6 +4,17 @@ use std::process::Command;
use zynq7000_rt::mmu::ONE_MB;
pub use zynq7000_rt::mmu::segments::*;
macro_rules! write_l1_section {
($writer:expr, $offset:expr, $attr:expr) => {
writeln!(
$writer,
"L1Section::new({:#010x}, {}).raw_value(),",
$offset, $attr
)
.unwrap();
};
}
fn main() {
let file_path = "src/mmu_table.rs";
let file = File::create(file_path).expect("Failed to create file");
@@ -35,14 +46,17 @@ fn main() {
+ OCM_MAPPED_HIGH,
4096
);
let mut buf_writer = std::io::BufWriter::new(file);
writeln!(
buf_writer,
"//! This file was auto-generated by table-gen.rs"
)
.unwrap();
writeln!(buf_writer, "use crate::mmu::section_attrs;").unwrap();
writeln!(buf_writer, "use cortex_ar::mmu::L1Section;").unwrap();
writeln!(buf_writer, "use crate::mmu::{{section_attrs, L1Table}};").unwrap();
writeln!(buf_writer, "use zynq_mmu::L1Table;").unwrap();
writeln!(buf_writer, "").unwrap();
writeln!(buf_writer, "/// MMU Level 1 Page table.").unwrap();
@@ -54,7 +68,7 @@ fn main() {
.unwrap();
writeln!(
buf_writer,
"pub const MMU_L1_PAGE_TABLE: L1Table = L1Table(["
"pub static MMU_L1_PAGE_TABLE: L1Table = L1Table::new(["
)
.unwrap();
@@ -63,44 +77,24 @@ fn main() {
"// First DDR segment, OCM memory (0x0000_0000 - 0x0010_0000)"
)
.unwrap();
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_ddr
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_ddr);
offset += ONE_MB;
writeln!(buf_writer, "// DDR memory (0x00100000 - 0x4000_0000)").unwrap();
for _ in 0..DDR_FULL_ACCESSIBLE {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_ddr
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_ddr);
offset += ONE_MB;
}
writeln!(buf_writer, "// FPGA slave 0 (0x4000_0000 - 0x8000_0000)").unwrap();
for _ in 0..FPGA_SLAVE {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_fpga_slaves
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_fpga_slaves);
offset += ONE_MB;
}
writeln!(buf_writer, "// FPGA slave 1 (0x8000_0000 - 0xC000_0000)").unwrap();
for _ in 0..FPGA_SLAVE {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_fpga_slaves
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_fpga_slaves);
offset += ONE_MB;
}
@@ -110,12 +104,7 @@ fn main() {
)
.unwrap();
for _ in 0..UNASSIGNED_0 {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_unassigned
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_unassigned);
offset += ONE_MB;
}
@@ -125,12 +114,7 @@ fn main() {
)
.unwrap();
for _ in 0..IO_PERIPHS {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_shared_dev
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_shared_dev);
offset += ONE_MB;
}
@@ -140,45 +124,25 @@ fn main() {
)
.unwrap();
for _ in 0..UNASSIGNED_1 {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_unassigned
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_unassigned);
offset += ONE_MB;
}
writeln!(buf_writer, "// NAND (0xE100_0000 - 0xE200_0000)").unwrap();
for _ in 0..NAND {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_shared_dev
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_shared_dev);
offset += ONE_MB;
}
writeln!(buf_writer, "// NOR (0xE200_0000 - 0xE400_0000)").unwrap();
for _ in 0..NOR {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_shared_dev
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_shared_dev);
offset += ONE_MB;
}
writeln!(buf_writer, "// SRAM (0xE400_0000 - 0xE600_0000)").unwrap();
for _ in 0..SRAM {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_sram
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_sram);
offset += ONE_MB;
}
@@ -188,12 +152,7 @@ fn main() {
)
.unwrap();
for _ in 0..SEGMENTS_UNASSIGNED_2 {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_unassigned
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_unassigned);
offset += ONE_MB;
}
@@ -203,12 +162,7 @@ fn main() {
)
.unwrap();
for _ in 0..AMBA_APB {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_shared_dev
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_shared_dev);
offset += ONE_MB;
}
@@ -218,23 +172,13 @@ fn main() {
)
.unwrap();
for _ in 0..UNASSIGNED_3 {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_unassigned
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_unassigned);
offset += ONE_MB;
}
writeln!(buf_writer, "// QSPI XIP (0xFC00_0000 - 0xFE00_0000)").unwrap();
for _ in 0..QSPI_XIP {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_qspi
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_qspi);
offset += ONE_MB;
}
@@ -244,24 +188,14 @@ fn main() {
)
.unwrap();
for _ in 0..UNASSIGNED_4 {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_unassigned
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_unassigned);
offset += ONE_MB;
}
writeln!(buf_writer, "// OCM High (0xFFF0_0000 - 0xFFFF_FFFF)").unwrap();
let mut offset_u64 = offset as u64;
for _ in 0..OCM_MAPPED_HIGH {
writeln!(
buf_writer,
"L1Section::new({}, {}).raw_value(),",
offset, attr_ocm_high
)
.unwrap();
write_l1_section!(buf_writer, offset, attr_ocm_high);
offset_u64 += ONE_MB as u64;
}

View File

@@ -3,9 +3,22 @@
//! This includes basic low-level startup code similar to the bare-metal boot routines
//! [provided by Xilinx](https://github.com/Xilinx/embeddedsw/tree/master/lib/bsp/standalone/src/arm/cortexa9/gcc).
#![no_std]
#[cfg(feature = "rt")]
pub use cortex_a_rt::*;
#[cfg(feature = "rt")]
use zynq_mmu::L1TableWrapper;
pub mod mmu;
#[cfg(feature = "rt")]
mod mmu_table;
#[cfg(feature = "rt")]
pub mod rt;
/// Retrieves a mutable reference to the MMU L1 page table.
#[cfg(feature = "rt")]
pub fn mmu_l1_table_mut() -> L1TableWrapper<'static> {
let mmu_table = mmu_table::MMU_L1_PAGE_TABLE.0.get();
// Safety: We retrieve a reference to the MMU page table singleton.
L1TableWrapper::new(unsafe { &mut *mmu_table })
}

View File

@@ -84,17 +84,23 @@ pub mod segments {
}
pub mod section_attrs {
use arbitrary_int::u4;
use cortex_ar::mmu::{
AccessPermissions, CacheableMemoryAttribute, MemoryRegionAttributes, SectionAttributes,
};
pub const DEFAULT_DOMAIN: u4 = u4::new(0b0000);
// DDR is in different domain, but all domains are set as manager domains during run-time
// initialization.
pub const DDR_DOMAIN: u4 = u4::new(0b1111);
pub const DDR: SectionAttributes = SectionAttributes {
non_global: false,
p_bit: false,
shareable: true,
access: AccessPermissions::FullAccess,
// Manager domain
domain: 0b1111,
domain: DDR_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::CacheableMemory {
inner: CacheableMemoryAttribute::WriteBackWriteAlloc,
@@ -107,7 +113,7 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::FullAccess,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::StronglyOrdered.as_raw(),
};
@@ -116,7 +122,7 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::FullAccess,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::ShareableDevice.as_raw(),
};
@@ -125,7 +131,7 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::FullAccess,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::OuterAndInnerWriteBackNoWriteAlloc.as_raw(),
};
@@ -134,7 +140,7 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::FullAccess,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::OuterAndInnerWriteThroughNoWriteAlloc.as_raw(),
};
@@ -143,7 +149,7 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::FullAccess,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::CacheableMemory {
inner: CacheableMemoryAttribute::WriteThroughNoWriteAlloc,
@@ -156,18 +162,12 @@ pub mod section_attrs {
p_bit: false,
shareable: false,
access: AccessPermissions::PermissionFault,
domain: 0b0000,
domain: DEFAULT_DOMAIN,
execute_never: false,
memory_attrs: MemoryRegionAttributes::StronglyOrdered.as_raw(),
};
}
pub const NUM_L1_PAGE_TABLE_ENTRIES: usize = 4096;
#[repr(C, align(16384))]
#[cfg(feature = "rt")]
pub struct L1Table(pub(crate) [u32; NUM_L1_PAGE_TABLE_ENTRIES]);
/// Load the MMU translation table base address into the MMU.
///
/// # Safety
@@ -178,7 +178,7 @@ pub struct L1Table(pub(crate) [u32; NUM_L1_PAGE_TABLE_ENTRIES]);
#[unsafe(no_mangle)]
#[cfg(feature = "rt")]
unsafe extern "C" fn load_mmu_table() {
let table_base = &crate::mmu_table::MMU_L1_PAGE_TABLE.0 as *const _ as u32;
let table_base = crate::mmu_table::MMU_L1_PAGE_TABLE.0.get() as u32;
unsafe {
core::arch::asm!(

File diff suppressed because it is too large Load Diff