From d992a5a2760159dfa28d8284c53f49aa7d1a3664 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 28 Feb 2025 14:37:00 +0100 Subject: [PATCH] continue --- .gitignore | 1 + Cargo.lock | 160 -------------------------------------- zynq-examples/src/main.rs | 2 +- zynq7000/Cargo.toml | 3 +- zynq7000/src/gpio.rs | 9 ++- zynq7000/src/gtc.rs | 42 ++++++++++ zynq7000/src/lib.rs | 4 + zynq7000/src/sclr.rs | 11 +++ zynq7000/src/uart.rs | 66 ++++++++++++++++ 9 files changed, 134 insertions(+), 164 deletions(-) delete mode 100644 Cargo.lock create mode 100644 zynq7000/src/gtc.rs create mode 100644 zynq7000/src/sclr.rs create mode 100644 zynq7000/src/uart.rs diff --git a/.gitignore b/.gitignore index 8e05caf..7369a67 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /app.map /xsct-output.log /.vscode +/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index dbc67be..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,160 +0,0 @@ -# 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 = "arm-targets" -version = "0.1.0" - -[[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 = "cortex-a-rt" -version = "0.1.0" -dependencies = [ - "arm-targets", - "cortex-ar", - "semihosting", -] - -[[package]] -name = "cortex-ar" -version = "0.1.0" -dependencies = [ - "arbitrary-int", - "arm-targets", - "bitbybit", -] - -[[package]] -name = "derive-mmio" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d102578147eb74f297190842998dff79a70c1c242886e6c01f0b2194f8afc" -dependencies = [ - "derive-mmio-macro", -] - -[[package]] -name = "derive-mmio-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a42cb29e2388869429bcd293f8fd37218e98cce4bb8381b10993de0ddab4928" -dependencies = [ - "proc-macro-error2", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[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 = "rustversion" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" - -[[package]] -name = "semihosting" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "407ec8d274cd77556e9c2bef886df91eb3447b4059e603d6fb19f85e6452e275" - -[[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 = "unicode-ident" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" - -[[package]] -name = "zynq-examples" -version = "0.1.0" -dependencies = [ - "cortex-ar", - "zynq7000", - "zynq7000-rt", -] - -[[package]] -name = "zynq7000" -version = "0.1.0" -dependencies = [ - "arbitrary-int", - "bitbybit", - "derive-mmio", -] - -[[package]] -name = "zynq7000-rt" -version = "0.1.0" -dependencies = [ - "cortex-a-rt", - "cortex-ar", -] diff --git a/zynq-examples/src/main.rs b/zynq-examples/src/main.rs index 31abe6a..4d7f567 100644 --- a/zynq-examples/src/main.rs +++ b/zynq-examples/src/main.rs @@ -19,7 +19,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! { #[unsafe(export_name = "main")] pub fn main() -> ! { - let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() }; + let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio() }; gpio.modify_dirm_0(|v| v | ZEDBOARD_LED_MASK); gpio.modify_out_en_0(|v| v | ZEDBOARD_LED_MASK); loop { diff --git a/zynq7000/Cargo.toml b/zynq7000/Cargo.toml index 3ba8ec0..c3eba1c 100644 --- a/zynq7000/Cargo.toml +++ b/zynq7000/Cargo.toml @@ -11,7 +11,8 @@ keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] categories = ["embedded", "no-std", "hardware-support"] [dependencies] -derive-mmio = "0.2" +static_assertions = "1.1" +derive-mmio = { path = "../../derive-mmio" } bitbybit = "1.3" arbitrary-int = "1.3" # cortex-r diff --git a/zynq7000/src/gpio.rs b/zynq7000/src/gpio.rs index 0c70c56..5b9b05a 100644 --- a/zynq7000/src/gpio.rs +++ b/zynq7000/src/gpio.rs @@ -8,6 +8,7 @@ pub struct MaskedOutput { } #[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] #[repr(C)] pub struct Gpio { /// Maskable output data (GPIO bank 0, MIO, lower 16 bits) @@ -134,6 +135,8 @@ pub struct Gpio { int_any_3: u32, } +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x2E8); + impl Gpio { /// Create a new XGPIOPS GPIO MMIO instance. /// @@ -142,7 +145,9 @@ 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 unsafe fn new_mmio_fixed() -> MmioGpio { - unsafe { Self::new_mmio_at(0xE000A000) } + pub const unsafe fn new_mmio() -> MmioGpio { + MmioGpio { + ptr: 0xE000A000 as *mut Gpio, + } } } diff --git a/zynq7000/src/gtc.rs b/zynq7000/src/gtc.rs new file mode 100644 index 0000000..7606748 --- /dev/null +++ b/zynq7000/src/gtc.rs @@ -0,0 +1,42 @@ +//! Global timer counter module. + +pub const GTC_BASE_ADDR: usize = super::MPCORE_BASE_ADDR + 0x0000_0200; + +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct GlobalTimerCounter { + /// Count register 0, lower 32 bits + count_lower: u32, + /// Count register 1, upper 32 bits + count_upper: u32, + /// Control register + ctrl: u32, + /// Interrupt status register + isr: u32, + /// Comparator 0, lower 32 bits + comparator_lower: u32, + /// Comparator 1, upper 32 bits + comparator_upper: u32, + /// Auto-increment register + auto_increment: u32 +} + +pub type Gtc = GlobalTimerCounter; + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x1C); + +pub type MmioGtc = MmioGlobalTimerCounter; + +impl GlobalTimerCounter { + /// Create a new GTC MMIO instance. + /// + /// # Safety + /// + /// 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() -> MmioGtc { + MmioGtc { ptr: GTC_BASE_ADDR as *mut Gtc } + } +} diff --git a/zynq7000/src/lib.rs b/zynq7000/src/lib.rs index 45b7a36..d23f38c 100644 --- a/zynq7000/src/lib.rs +++ b/zynq7000/src/lib.rs @@ -1,4 +1,8 @@ //! Rust peripheral acess crate to the AMD Zynq 7000 SoCs #![no_std] +pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000; + pub mod gpio; +pub mod uart; +pub mod gtc; diff --git a/zynq7000/src/sclr.rs b/zynq7000/src/sclr.rs new file mode 100644 index 0000000..22ca5d4 --- /dev/null +++ b/zynq7000/src/sclr.rs @@ -0,0 +1,11 @@ +//! 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/uart.rs b/zynq7000/src/uart.rs new file mode 100644 index 0000000..a75189d --- /dev/null +++ b/zynq7000/src/uart.rs @@ -0,0 +1,66 @@ +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct Uart { + /// Control Register + cr: u32, + /// Mode register + mr: u32, + /// Interrupt enable register + ier: u32, + /// Interrupt disable register + idr: u32, + /// Interrupt mask register + imr: u32, + /// Interrupt status register + isr: u32, + /// Baudgen register + baudgen: u32, + /// RX timeout register + rx_tout: u32, + /// RX FIFO trigger level register + rx_fifo_trigger: u32, + /// Modem control register + modem_cr: u32, + /// Modem status register + modem_sr: u32, + /// Channel status register + sr: u32, + /// FIFO register + fifo: u32, + /// Baud rate divider register + baud_rate_div: u32, + /// Flow control delay register + flow_delay: u32, + + _reserved: [u32; 2], + + /// TX fifo trigger level + tx_fifo_trigger: u32, +} + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x48); + +impl Uart { + /// Create a new UART MMIO instance for uart0 at address 0xE000_0000. + /// + /// # Safety + /// + /// 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 } + } + + /// Create a new UART MMIO instance for uart1 at address 0xE000_1000. + /// + /// # Safety + /// + /// 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 } + } +}