This commit is contained in:
Robin Müller 2025-02-28 14:37:00 +01:00
parent 9a8f50d496
commit d992a5a276
Signed by: muellerr
GPG Key ID: A649FB78196E3849
9 changed files with 134 additions and 164 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/app.map
/xsct-output.log
/.vscode
/Cargo.lock

160
Cargo.lock generated
View File

@ -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",
]

View File

@ -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 {

View File

@ -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

View File

@ -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::<Gpio>(), 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,
}
}
}

42
zynq7000/src/gtc.rs Normal file
View File

@ -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::<Gtc>(), 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 }
}
}

View File

@ -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;

11
zynq7000/src/sclr.rs Normal file
View File

@ -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;

66
zynq7000/src/uart.rs Normal file
View File

@ -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::<Uart>(), 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 }
}
}