diff --git a/.cargo/config.toml b/.cargo/config.toml index 985e46a..af4177d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -10,7 +10,7 @@ rustflags = [ # Tier 3 target, so no pre-compiled artifacts included. [unstable] -build-std = ["core", "alloc"] +# build-std = ["core", "alloc"] [build] -target = "armv7a-none-eabihf" +# target = "armv7a-none-eabihf" diff --git a/Cargo.toml b/Cargo.toml index 7206954..fb60b28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ members = [ "zynq7000-rt", "zynq-examples" ] +exclude = ["experiments"] diff --git a/experiments/.cargo/config.toml b/experiments/.cargo/config.toml new file mode 100644 index 0000000..a7b19c9 --- /dev/null +++ b/experiments/.cargo/config.toml @@ -0,0 +1 @@ +[build] diff --git a/experiments/.gitignore b/experiments/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/experiments/.gitignore @@ -0,0 +1 @@ +/target diff --git a/experiments/Cargo.lock b/experiments/Cargo.lock new file mode 100644 index 0000000..fa6a82f --- /dev/null +++ b/experiments/Cargo.lock @@ -0,0 +1,141 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "arbitrary-int" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825297538d77367557b912770ca3083f778a196054b3ee63b22673c4a3cae0a5" + +[[package]] +name = "bitbybit" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d317eeca82e7d88d606419a430590d83552bdceb899cb29904f63d694344b7fc" +dependencies = [ + "arbitrary-int", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive-mmio" +version = "0.3.0" +dependencies = [ + "derive-mmio-macro", + "thiserror", +] + +[[package]] +name = "derive-mmio-macro" +version = "0.3.0" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "experiments" +version = "0.1.0" +dependencies = [ + "derive-mmio", + "static_assertions", + "zynq7000", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" + +[[package]] +name = "zynq7000" +version = "0.1.0" +dependencies = [ + "arbitrary-int", + "bitbybit", + "derive-mmio", + "static_assertions", +] diff --git a/experiments/Cargo.toml b/experiments/Cargo.toml new file mode 100644 index 0000000..a19b1e7 --- /dev/null +++ b/experiments/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "experiments" +version = "0.1.0" +edition = "2024" + +[dependencies] +static_assertions = "1.1" +derive-mmio = { path = "../../derive-mmio", default-features = false } +zynq7000 = { path = "../zynq7000", default-features = false } diff --git a/experiments/src/main.rs b/experiments/src/main.rs new file mode 100644 index 0000000..3249366 --- /dev/null +++ b/experiments/src/main.rs @@ -0,0 +1,11 @@ +use zynq7000::slcr::{ClockControl, Slcr}; + + +fn main() { + let size = core::mem::size_of::(); + println!("Size of ClockControl: {}", size); + let size = core::mem::size_of::(); + println!("Size of SLCR: {}", size); + + println!("Hello, world!"); +} diff --git a/zynq7000/Cargo.toml b/zynq7000/Cargo.toml index c3eba1c..8c3f858 100644 --- a/zynq7000/Cargo.toml +++ b/zynq7000/Cargo.toml @@ -12,7 +12,7 @@ categories = ["embedded", "no-std", "hardware-support"] [dependencies] static_assertions = "1.1" -derive-mmio = { path = "../../derive-mmio" } +derive-mmio = { path = "../../derive-mmio", default-features = false } bitbybit = "1.3" arbitrary-int = "1.3" # cortex-r diff --git a/zynq7000/src/gpio.rs b/zynq7000/src/gpio.rs index 5b9b05a..2baa835 100644 --- a/zynq7000/src/gpio.rs +++ b/zynq7000/src/gpio.rs @@ -145,9 +145,10 @@ impl Gpio { /// This API can be used to potentially create a driver to the same peripheral structure /// from multiple threads. The user must ensure that concurrent accesses are safe and do not /// interfere with each other. - pub const unsafe fn new_mmio() -> MmioGpio { + pub const unsafe fn new_mmio() -> MmioGpio<'static> { MmioGpio { ptr: 0xE000A000 as *mut Gpio, + phantom: core::marker::PhantomData, } } } diff --git a/zynq7000/src/gtc.rs b/zynq7000/src/gtc.rs index 7606748..d5235a2 100644 --- a/zynq7000/src/gtc.rs +++ b/zynq7000/src/gtc.rs @@ -26,7 +26,7 @@ pub type Gtc = GlobalTimerCounter; static_assertions::const_assert_eq!(core::mem::size_of::(), 0x1C); -pub type MmioGtc = MmioGlobalTimerCounter; +pub type MmioGtc = MmioGlobalTimerCounter<'static>; impl GlobalTimerCounter { /// Create a new GTC MMIO instance. @@ -37,6 +37,6 @@ impl GlobalTimerCounter { /// from multiple threads. The user must ensure that concurrent accesses are safe and do not /// interfere with each other. pub const unsafe fn new_mmio() -> MmioGtc { - MmioGtc { ptr: GTC_BASE_ADDR as *mut Gtc } + MmioGtc { ptr: GTC_BASE_ADDR as *mut Gtc, phantom: core::marker::PhantomData } } } diff --git a/zynq7000/src/lib.rs b/zynq7000/src/lib.rs index d23f38c..85282f6 100644 --- a/zynq7000/src/lib.rs +++ b/zynq7000/src/lib.rs @@ -6,3 +6,4 @@ pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000; pub mod gpio; pub mod uart; pub mod gtc; +pub mod slcr; diff --git a/zynq7000/src/sclr.rs b/zynq7000/src/sclr.rs deleted file mode 100644 index 22ca5d4..0000000 --- a/zynq7000/src/sclr.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! System Level Control Registers (slcr) - -#[derive(derive_mmio::Mmio)] -#[mmio(no_ctors)] -#[repr(C)] -pub struct Slcr { - scl: u32, -} - -pub type SystemLevelControlRegisters = Slcr; - diff --git a/zynq7000/src/slcr.rs b/zynq7000/src/slcr.rs new file mode 100644 index 0000000..265018b --- /dev/null +++ b/zynq7000/src/slcr.rs @@ -0,0 +1,237 @@ +//! System Level Control Registers (slcr) + +const SLCR_BASE_ADDR: usize = 0xF8000000; +const CLOCK_CONTROL_OFFSET: usize = 0x100; +const RESET_BLOCK_OFFSET: usize = 0x200; + +#[derive(derive_mmio::Mmio)] +#[repr(C)] +pub struct FpgaClkCtrl { + clk_ctrl: u32, + thr_ctrl: u32, + thr_cnt: u32, + thr_status: u32, +} + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x10); + +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct ResetControl { + /// PS Software reset control + pss: u32, + ddr: u32, + /// Central interconnect reset control + topsw: u32, + dmac: u32, + usb: u32, + gem: u32, + sdio: u32, + spi: u32, + can: u32, + i2c: u32, + uart: u32, + gpio: u32, + lqspi: u32, + smc: u32, + ocm: u32, + _gap0: u32, + fpga: u32, + a9_cpu: u32, + _gap1: u32, + rs_awdt: u32, +} + +impl ResetControl { + pub fn new_mmio_fixed() -> MmioResetControl<'static> { + MmioResetControl { + ptr: (SLCR_BASE_ADDR + RESET_BLOCK_OFFSET) as *mut ResetControl, + phantom: core::marker::PhantomData, + } + } + + fn new_mmio(block: *mut ResetControl) -> MmioResetControl<'static> { + MmioResetControl { + ptr: block, + phantom: core::marker::PhantomData, + } + } +} + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x50); + +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct ClockControl { + arm_pll: u32, + ddr_pll: u32, + io_pll: u32, + pll_status: u32, + arm_pll_cfg: u32, + ddr_pll_cfg: u32, + io_pll_cfg: u32, + _gap0: u32, + arm_clk_ctrl: u32, + ddr_clk_ctrl: u32, + dci_clk_ctrl: u32, + /// AMBA peripheral clock control + aper_clk_ctrl: u32, + usb_0_clk_ctrl: u32, + usb_1_clk_ctrl: u32, + gem_0_rclk_ctrl: u32, + gem_1_rclk_ctrl: u32, + gem_0_clk_ctrl: u32, + gem_1_clk_ctrl: u32, + smc_clk_ctrl: u32, + lqspi_clk_ctrl: u32, + sdio_clk_ctrl: u32, + uart_clk_ctrl: u32, + spi_clk_ctrl: u32, + can_clk_ctrl: u32, + can_mioclk_ctrl: u32, + dbg_clk_ctrl: u32, + pcap_clk_ctrl: u32, + topsw_clk_ctrl: u32, + #[mmio(inner)] + fpga_0_clk_ctrl: FpgaClkCtrl, + #[mmio(inner)] + fpga_1_clk_ctrl: FpgaClkCtrl, + #[mmio(inner)] + fpga_2_clk_ctrl: FpgaClkCtrl, + #[mmio(inner)] + fpga_3_clk_ctrl: FpgaClkCtrl, + _gap1: [u32; 5], + clk_621_true: u32, +} + +impl ClockControl { + pub fn new_mmio_fixed() -> MmioClockControl<'static> { + MmioClockControl { + ptr: (SLCR_BASE_ADDR + CLOCK_CONTROL_OFFSET) as *mut ClockControl, + phantom: core::marker::PhantomData, + } + } + + fn new_mmio(clk_ctrl: *mut ClockControl) -> MmioClockControl<'static> { + MmioClockControl { + ptr: clk_ctrl, + phantom: core::marker::PhantomData, + } + } +} + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0xC8); + +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct Slcr { + /// Secure configuration lock. + scl: u32, + /// SLCR write protection lock + lock: u32, + /// SLCR write protection unlock + unlock: u32, + /// SLCR write protection status + lock_status: u32, + + _gap0: [u32; 60], + + #[mmio(inner)] + clk_ctrl: ClockControl, + + _gap1: [u32; 14], + + #[mmio(inner)] + reset_ctrl: ResetControl, + + _gap2: [u32; 2], + + reboot_status: u32, + boot_mode: u32, + + _gap3: [u32; 40], + + apu_ctrl: u32, + wdt_clk_set: u32, + + _gap4: [u32; 78], + + tz_dma_ns: u32, + tz_dma_irq_ns: u32, + tz_dma_periph_ns: u32, + + _gap5: [u32; 57], + + pss_idcode: u32, + + _gap6: [u32; 51], + + ddr_urgent: u32, + _gap7: [u32; 2], + ddr_cal_start: u32, + _gap8: u32, + ddr_ref_start: u32, + ddr_cmd_status: u32, + ddr_urgent_sel: u32, + ddr_dfi_status: u32, + + _gap9: [u32; 56], + + mio_pins: [u32; 54], + + _gap10: [u32; 11], + + mio_loopback: u32, + _gap11: u32, + mio_mst_tri_0: u32, + mio_mst_tri_1: u32, + _gap12: [u32; 8], + sd_0_wp_cd_sel: u32, + sd_1_wp_cd_sel: u32, + + _gap13: [u32; 51], + + lvl_shftr_en: u32, + + _gap14: [u32; 4], + + ocm_cfg: u32, + + _gap15: [u32; 66], + + reserved: u32, + + _gap16: [u32; 56], + + gpiob_ctrl: u32, + gpiob_cfg_cmos18: u32, + gpiob_cfg_cmos25: u32, + gpiob_cfg_cmos33: u32, + _gap17: u32, + gpiob_cfg_hstl: u32, + gpiob_drvr_bias_ctrl: u32, + + _gap18: [u32; 9], + + ddriob_addr0: u32, + ddriob_addr1: u32, + ddriob_data0: u32, + ddriob_data1: u32, + ddriob_diff0: u32, + ddriob_diff1: u32, + ddriob_clock: u32, + ddriob_drive_slew_addr: u32, + ddriob_drive_slew_data: u32, + ddriob_drive_slew_diff: u32, + ddriob_drive_slew_clock: u32, + ddriob_ddr_ctrl: u32, + ddriob_dci_ctrl: u32, + ddriob_dci_status: u32, +} + +//static_assertions::const_assert_eq!(core::mem::size_of::(), 0xB78); + +pub type SystemLevelControlRegisters = Slcr; diff --git a/zynq7000/src/uart.rs b/zynq7000/src/uart.rs index a75189d..c96ece9 100644 --- a/zynq7000/src/uart.rs +++ b/zynq7000/src/uart.rs @@ -1,3 +1,6 @@ +const UART0_BASE: u32 = 0xE000_0000; +const UART1_BASE: u32 = 0xE000_1000; + #[derive(derive_mmio::Mmio)] #[mmio(no_ctors)] #[repr(C)] @@ -49,8 +52,8 @@ impl Uart { /// This API can be used to potentially create a driver to the same peripheral structure /// from multiple threads. The user must ensure that concurrent accesses are safe and do not /// interfere with each other. - pub const unsafe fn new_mmio_0() -> MmioUart { - MmioUart { ptr: 0xE000_0000 as *mut Uart } + pub const unsafe fn new_mmio_0() -> MmioUart<'static> { + MmioUart { ptr: 0xE000_0000 as *mut Uart, phantom: core::marker::PhantomData } } /// Create a new UART MMIO instance for uart1 at address 0xE000_1000. @@ -60,7 +63,7 @@ impl Uart { /// This API can be used to potentially create a driver to the same peripheral structure /// from multiple threads. The user must ensure that concurrent accesses are safe and do not /// interfere with each other. - pub const unsafe fn new_mmio_1() -> MmioUart { - MmioUart { ptr: 0xE000_1000 as *mut Uart } + pub const unsafe fn new_mmio_1() -> MmioUart<'static> { + MmioUart { ptr: 0xE000_1000 as *mut Uart, phantom: core::marker::PhantomData } } }