use std::fs::File; use std::io::Write; use std::process::Command; use zynq7000_rt::mmu::ONE_MB; pub use zynq7000_rt::mmu::segments::*; fn main() { let file_path = "src/mmu_table.rs"; let file = File::create(file_path).expect("Failed to create file"); let mut offset = 0; let attr_ddr = stringify!(section_attrs::DDR); let attr_unassigned = stringify!(section_attrs::UNASSIGNED_RESERVED); let attr_fpga_slaves = stringify!(section_attrs::FPGA_SLAVES); let attr_shared_dev = stringify!(section_attrs::SHAREABLE_DEVICE); let attr_sram = stringify!(section_attrs::SRAM); let attr_qspi = stringify!(section_attrs::QSPI_XIP); let attr_ocm_high = stringify!(section_attrs::OCM_MAPPED_HIGH); assert_eq!( 1 + DDR_FULL_ACCESSIBLE + FPGA_SLAVE + FPGA_SLAVE + UNASSIGNED_0 + IO_PERIPHS + UNASSIGNED_1 + NAND + NOR + SRAM + SEGMENTS_UNASSIGNED_2 + AMBA_APB + UNASSIGNED_3 + QSPI_XIP + UNASSIGNED_4 + 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 cortex_ar::mmu::L1Section;").unwrap(); writeln!(buf_writer, "use crate::mmu::{{section_attrs, L1Table}};").unwrap(); writeln!(buf_writer, "").unwrap(); writeln!(buf_writer, "/// MMU Level 1 Page table.").unwrap(); writeln!(buf_writer, "///").unwrap(); writeln!( buf_writer, "/// 4096 entries, each covering 1MB of the address space." ) .unwrap(); writeln!( buf_writer, "pub const MMU_L1_PAGE_TABLE: L1Table = L1Table([" ) .unwrap(); writeln!( buf_writer, "// First DDR segment, OCM memory (0x0000_0000 - 0x0010_0000)" ) .unwrap(); writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_ddr ) .unwrap(); 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(); 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(); 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(); offset += ONE_MB; } writeln!( buf_writer, "// Unassigned/Reserved (0xC000_0000 - 0xE000_0000)" ) .unwrap(); for _ in 0..UNASSIGNED_0 { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_unassigned ) .unwrap(); offset += ONE_MB; } writeln!( buf_writer, "// Segments IO peripherals (0xE000_0000 - 0xE030_0000)" ) .unwrap(); for _ in 0..IO_PERIPHS { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_shared_dev ) .unwrap(); offset += ONE_MB; } writeln!( buf_writer, "// Unassigned/Reserved (0xE030_0000 - 0xE100_0000)" ) .unwrap(); for _ in 0..UNASSIGNED_1 { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_unassigned ) .unwrap(); 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(); 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(); 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(); offset += ONE_MB; } writeln!( buf_writer, "// Unassigned/Reserved (0xE600_0000 - 0xF800_0000)" ) .unwrap(); for _ in 0..SEGMENTS_UNASSIGNED_2 { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_unassigned ) .unwrap(); offset += ONE_MB; } writeln!( buf_writer, "// AMBA APB peripherals (0xF800_0000 - 0xF900_0000)" ) .unwrap(); for _ in 0..AMBA_APB { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_shared_dev ) .unwrap(); offset += ONE_MB; } writeln!( buf_writer, "// Unassigned/Reserved (0xF900_0000 - 0xFC00_0000)" ) .unwrap(); for _ in 0..UNASSIGNED_3 { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_unassigned ) .unwrap(); 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(); offset += ONE_MB; } writeln!( buf_writer, "// Unassiged/Reserved (0xFE00_0000 - 0xFFF0_0000)" ) .unwrap(); for _ in 0..UNASSIGNED_4 { writeln!( buf_writer, "L1Section::new({}, {}).raw_value(),", offset, attr_unassigned ) .unwrap(); 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(); offset_u64 += ONE_MB as u64; } // Check that the full 4 GB were covered (not too much, or less) assert_eq!(offset_u64, 0x1_0000_0000 as u64); writeln!(buf_writer, "]);").unwrap(); // Finish the file. drop(buf_writer); println!("Generated mmu_table.rs"); // Run rustfmt on the generated file let output = Command::new("rustfmt") .arg(file_path) .output() .expect("Failed to run rustfmt"); if !output.status.success() { eprintln!("rustfmt failed: {:?}", output); } }