From 79042a68dd2962ee32024a688d75f06459d52d5e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 27 Sep 2025 15:53:20 +0200 Subject: [PATCH] finished QSPI flasher --- .cargo/config.toml.template | 21 - .github/workflows/ci.yml | 50 +- .gitignore | 3 +- Cargo.toml | 33 - README.md | 28 +- justfile | 40 + scripts/runner.sh | 20 - scripts/unittest.sh | 3 - scripts/zynq7000-init.py | 4 +- tools/Cargo.lock | 796 ++++++++++++++++++ tools/Cargo.toml | 7 + .../boot-image-test}/.gitignore | 0 .../boot-image-test}/Cargo.lock | 0 .../boot-image-test}/Cargo.toml | 6 +- .../boot-image-test}/src/main.rs | 2 +- tools/mmu-table-gen/Cargo.toml | 8 + .../mmu-table-gen/src/main.rs | 4 +- tools/zynq7000-ps7init-extract/.gitignore | 2 + tools/zynq7000-ps7init-extract/Cargo.lock | 251 ++++++ tools/zynq7000-ps7init-extract/Cargo.toml | 14 + tools/zynq7000-ps7init-extract/README.md | 26 + tools/zynq7000-ps7init-extract/src/main.rs | 341 ++++++++ zedboard-bsp/src/lib.rs | 4 - zedboard-fpga-design/README.md | 22 + zedboard-fsbl/src/ddr_cfg.rs | 503 ----------- zynq-mmu/Cargo.toml | 12 - zynq/.cargo/config.toml | 20 + zynq/.gitignore | 1 + zynq/Cargo.toml | 21 + .../examples}/embassy/Cargo.toml | 28 +- {examples => zynq/examples}/embassy/build.rs | 0 {examples => zynq/examples}/embassy/memory.x | 0 .../embassy/src/bin/dht22-open-drain-pins.rs | 0 .../embassy/src/bin/logger-non-blocking.rs | 2 +- .../examples}/embassy/src/bin/pwm.rs | 0 .../examples}/embassy/src/main.rs | 2 +- {examples => zynq/examples}/simple/Cargo.toml | 4 +- {examples => zynq/examples}/simple/build.rs | 0 {examples => zynq/examples}/simple/memory.x | 0 .../examples}/simple/src/bin/gtc-ticks.rs | 0 .../examples}/simple/src/bin/logger.rs | 0 .../examples}/simple/src/main.rs | 0 .../examples}/zedboard/Cargo.toml | 4 +- {examples => zynq/examples}/zedboard/build.rs | 0 {examples => zynq/examples}/zedboard/memory.x | 0 .../examples}/zedboard/src/bin/ethernet.rs | 0 .../zedboard/src/bin/l3gd20h-i2c-mio.rs | 0 .../zedboard/src/bin/l3gd20h-spi-mio.rs | 0 .../examples}/zedboard/src/bin/qspi.rs | 2 +- .../zedboard/src/bin/uart-blocking.rs | 0 .../zedboard/src/bin/uart-non-blocking.rs | 0 .../examples}/zedboard/src/lib.rs | 0 .../examples}/zedboard/src/main.rs | 2 +- gdb.gdb => zynq/gdb.gdb | 0 .../rust-toolchain.toml | 1 - .../zedboard-bsp}/Cargo.toml | 1 + zynq/zedboard-bsp/src/ddrc_config_autogen.rs | 101 +++ .../zedboard-bsp/src/ddriob_config_autogen.rs | 16 + zynq/zedboard-bsp/src/lib.rs | 6 + .../zedboard-bsp}/src/phy_marvell.rs | 0 .../zedboard-bsp}/src/qspi_spansion.rs | 67 +- .../zedboard-fsbl}/Cargo.toml | 6 +- .../zedboard-fsbl}/build.rs | 0 .../zedboard-fsbl}/memory.x | 0 .../zedboard-fsbl}/src/main.rs | 172 +++- .../zedboard-qspi-flasher}/Cargo.toml | 6 +- zynq/zedboard-qspi-flasher/build.rs | 31 + zynq/zedboard-qspi-flasher/memory.x | 22 + zynq/zedboard-qspi-flasher/qspi-flasher.tcl | 151 ++++ .../zedboard-qspi-flasher}/src/main.rs | 94 ++- .../zynq7000-embassy}/Cargo.toml | 0 .../zynq7000-embassy}/LICENSE-APACHE | 0 .../zynq7000-embassy}/LICENSE-MIT | 0 .../zynq7000-embassy}/README.md | 0 .../zynq7000-embassy}/src/lib.rs | 0 .../zynq7000-hal}/Cargo.toml | 8 +- .../zynq7000-hal}/LICENSE-APACHE | 0 .../zynq7000-hal}/LICENSE-MIT | 0 {zynq7000-hal => zynq/zynq7000-hal}/README.md | 0 {zynq7000-hal => zynq/zynq7000-hal}/docs.sh | 0 .../zynq7000-hal}/src/cache.rs | 0 .../zynq7000-hal}/src/clocks/mod.rs | 0 .../zynq7000-hal}/src/clocks/pll.rs | 0 .../zynq7000-hal}/src/ddr/ll.rs | 1 + .../zynq7000-hal}/src/ddr/mod.rs | 0 .../zynq7000-hal}/src/devcfg.rs | 0 .../zynq7000-hal}/src/eth/embassy_net.rs | 0 .../zynq7000-hal}/src/eth/ll.rs | 0 .../zynq7000-hal}/src/eth/mdio.rs | 0 .../zynq7000-hal}/src/eth/mod.rs | 0 .../zynq7000-hal}/src/eth/rx_descr.rs | 0 .../zynq7000-hal}/src/eth/smoltcp.rs | 0 .../zynq7000-hal}/src/eth/tx_descr.rs | 0 .../zynq7000-hal}/src/gic.rs | 0 .../zynq7000-hal}/src/gpio/emio.rs | 0 .../zynq7000-hal}/src/gpio/ll.rs | 0 .../zynq7000-hal}/src/gpio/mio.rs | 0 .../zynq7000-hal}/src/gpio/mod.rs | 0 .../zynq7000-hal}/src/gtc.rs | 0 .../zynq7000-hal}/src/i2c.rs | 0 .../zynq7000-hal}/src/l2_cache.rs | 0 .../zynq7000-hal}/src/lib.rs | 2 +- .../zynq7000-hal}/src/log.rs | 72 +- .../zynq7000-hal}/src/prelude.rs | 0 .../zynq7000-hal}/src/priv_tim.rs | 0 .../zynq7000-hal}/src/qspi/lqspi_configs.rs | 0 .../zynq7000-hal}/src/qspi/mod.rs | 0 .../zynq7000-hal}/src/slcr.rs | 0 .../zynq7000-hal}/src/spi/asynch.rs | 0 .../zynq7000-hal}/src/spi/mod.rs | 0 .../zynq7000-hal}/src/time.rs | 0 .../zynq7000-hal}/src/ttc.rs | 0 .../zynq7000-hal}/src/uart/mod.rs | 5 +- .../zynq7000-hal}/src/uart/rx.rs | 0 .../zynq7000-hal}/src/uart/tx.rs | 13 +- .../zynq7000-hal}/src/uart/tx_async.rs | 5 + zynq/zynq7000-mmu/Cargo.toml | 12 + {zynq-mmu => zynq/zynq7000-mmu}/src/lib.rs | 0 {zynq7000-rt => zynq/zynq7000-rt}/Cargo.toml | 11 +- {zynq7000-rt => zynq/zynq7000-rt}/README.md | 0 {zynq7000-rt => zynq/zynq7000-rt}/docs.sh | 0 .../zynq7000-rt}/regen-table.sh | 0 {zynq7000-rt => zynq/zynq7000-rt}/src/lib.rs | 2 +- {zynq7000-rt => zynq/zynq7000-rt}/src/mmu.rs | 0 .../zynq7000-rt}/src/mmu_table.rs | 2 +- {zynq7000-rt => zynq/zynq7000-rt}/src/rt.rs | 0 {zynq7000 => zynq/zynq7000}/Cargo.toml | 0 {zynq7000 => zynq/zynq7000}/LICENSE-APACHE | 0 {zynq7000 => zynq/zynq7000}/LICENSE-MIT | 0 {zynq7000 => zynq/zynq7000}/README.md | 0 {zynq7000 => zynq/zynq7000}/build.rs | 0 {zynq7000 => zynq/zynq7000}/docs.sh | 0 {zynq7000 => zynq/zynq7000}/src/ddrc.rs | 108 +-- {zynq7000 => zynq/zynq7000}/src/devcfg.rs | 0 {zynq7000 => zynq/zynq7000}/src/eth.rs | 28 +- {zynq7000 => zynq/zynq7000}/src/gic.rs | 11 +- {zynq7000 => zynq/zynq7000}/src/gpio.rs | 4 +- {zynq7000 => zynq/zynq7000}/src/gtc.rs | 4 +- {zynq7000 => zynq/zynq7000}/src/i2c.rs | 16 +- {zynq7000 => zynq/zynq7000}/src/l2_cache.rs | 19 +- {zynq7000 => zynq/zynq7000}/src/lib.rs | 0 {zynq7000 => zynq/zynq7000}/src/mpcore.rs | 0 {zynq7000 => zynq/zynq7000}/src/priv_tim.rs | 4 +- {zynq7000 => zynq/zynq7000}/src/qspi.rs | 16 +- .../zynq7000}/src/slcr/clocks.rs | 0 .../zynq7000}/src/slcr/ddriob.rs | 9 +- {zynq7000 => zynq/zynq7000}/src/slcr/mio.rs | 6 +- {zynq7000 => zynq/zynq7000}/src/slcr/mod.rs | 3 +- {zynq7000 => zynq/zynq7000}/src/slcr/reset.rs | 15 +- {zynq7000 => zynq/zynq7000}/src/spi.rs | 10 +- {zynq7000 => zynq/zynq7000}/src/ttc.rs | 22 +- {zynq7000 => zynq/zynq7000}/src/uart.rs | 23 +- {zynq7000 => zynq/zynq7000}/src/xadc.rs | 0 zynq7000-boot-image/.gitignore | 1 + .../Cargo.toml | 2 +- .../src/lib.rs | 0 .../staging/.gitignore | 0 .../staging/README.md | 0 .../staging/boot.bif | 0 zynq7000-rt/Cargo.lock | 7 - 160 files changed, 2477 insertions(+), 924 deletions(-) delete mode 100644 Cargo.toml delete mode 100755 scripts/runner.sh delete mode 100755 scripts/unittest.sh create mode 100644 tools/Cargo.lock create mode 100644 tools/Cargo.toml rename {zynq-boot-image/tester => tools/boot-image-test}/.gitignore (100%) rename {zynq-boot-image/tester => tools/boot-image-test}/Cargo.lock (100%) rename {zynq-boot-image/tester => tools/boot-image-test}/Cargo.toml (56%) rename {zynq-boot-image/tester => tools/boot-image-test}/src/main.rs (98%) create mode 100644 tools/mmu-table-gen/Cargo.toml rename zynq7000-rt/src/bin/table-gen.rs => tools/mmu-table-gen/src/main.rs (98%) create mode 100644 tools/zynq7000-ps7init-extract/.gitignore create mode 100644 tools/zynq7000-ps7init-extract/Cargo.lock create mode 100644 tools/zynq7000-ps7init-extract/Cargo.toml create mode 100644 tools/zynq7000-ps7init-extract/README.md create mode 100644 tools/zynq7000-ps7init-extract/src/main.rs delete mode 100644 zedboard-bsp/src/lib.rs delete mode 100644 zedboard-fsbl/src/ddr_cfg.rs delete mode 100644 zynq-mmu/Cargo.toml create mode 100644 zynq/.cargo/config.toml create mode 100644 zynq/.gitignore create mode 100644 zynq/Cargo.toml rename {examples => zynq/examples}/embassy/Cargo.toml (62%) rename {examples => zynq/examples}/embassy/build.rs (100%) rename {examples => zynq/examples}/embassy/memory.x (100%) rename {examples => zynq/examples}/embassy/src/bin/dht22-open-drain-pins.rs (100%) rename {examples => zynq/examples}/embassy/src/bin/logger-non-blocking.rs (99%) rename {examples => zynq/examples}/embassy/src/bin/pwm.rs (100%) rename {examples => zynq/examples}/embassy/src/main.rs (97%) rename {examples => zynq/examples}/simple/Cargo.toml (74%) rename {examples => zynq/examples}/simple/build.rs (100%) rename {examples => zynq/examples}/simple/memory.x (100%) rename {examples => zynq/examples}/simple/src/bin/gtc-ticks.rs (100%) rename {examples => zynq/examples}/simple/src/bin/logger.rs (100%) rename {examples => zynq/examples}/simple/src/main.rs (100%) rename {examples => zynq/examples}/zedboard/Cargo.toml (90%) rename {examples => zynq/examples}/zedboard/build.rs (100%) rename {examples => zynq/examples}/zedboard/memory.x (100%) rename {examples => zynq/examples}/zedboard/src/bin/ethernet.rs (100%) rename {examples => zynq/examples}/zedboard/src/bin/l3gd20h-i2c-mio.rs (100%) rename {examples => zynq/examples}/zedboard/src/bin/l3gd20h-spi-mio.rs (100%) rename {examples => zynq/examples}/zedboard/src/bin/qspi.rs (98%) rename {examples => zynq/examples}/zedboard/src/bin/uart-blocking.rs (100%) rename {examples => zynq/examples}/zedboard/src/bin/uart-non-blocking.rs (100%) rename {examples => zynq/examples}/zedboard/src/lib.rs (100%) rename {examples => zynq/examples}/zedboard/src/main.rs (98%) rename gdb.gdb => zynq/gdb.gdb (100%) rename rust-toolchain.toml => zynq/rust-toolchain.toml (60%) rename {zedboard-bsp => zynq/zedboard-bsp}/Cargo.toml (88%) create mode 100644 zynq/zedboard-bsp/src/ddrc_config_autogen.rs create mode 100644 zynq/zedboard-bsp/src/ddriob_config_autogen.rs create mode 100644 zynq/zedboard-bsp/src/lib.rs rename {zedboard-bsp => zynq/zedboard-bsp}/src/phy_marvell.rs (100%) rename {zedboard-bsp => zynq/zedboard-bsp}/src/qspi_spansion.rs (91%) rename {zedboard-fsbl => zynq/zedboard-fsbl}/Cargo.toml (70%) rename {zedboard-fsbl => zynq/zedboard-fsbl}/build.rs (100%) rename {zedboard-fsbl => zynq/zedboard-fsbl}/memory.x (100%) rename {zedboard-fsbl => zynq/zedboard-fsbl}/src/main.rs (50%) rename {zedboard-qspi-flasher => zynq/zedboard-qspi-flasher}/Cargo.toml (69%) create mode 100644 zynq/zedboard-qspi-flasher/build.rs create mode 100644 zynq/zedboard-qspi-flasher/memory.x create mode 100644 zynq/zedboard-qspi-flasher/qspi-flasher.tcl rename {zedboard-qspi-flasher => zynq/zedboard-qspi-flasher}/src/main.rs (50%) rename {zynq7000-embassy => zynq/zynq7000-embassy}/Cargo.toml (100%) rename {zynq7000-embassy => zynq/zynq7000-embassy}/LICENSE-APACHE (100%) rename {zynq7000-embassy => zynq/zynq7000-embassy}/LICENSE-MIT (100%) rename {zynq7000-embassy => zynq/zynq7000-embassy}/README.md (100%) rename {zynq7000-embassy => zynq/zynq7000-embassy}/src/lib.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/Cargo.toml (85%) rename {zynq7000-hal => zynq/zynq7000-hal}/LICENSE-APACHE (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/LICENSE-MIT (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/README.md (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/docs.sh (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/cache.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/clocks/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/clocks/pll.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/ddr/ll.rs (99%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/ddr/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/devcfg.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/embassy_net.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/ll.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/mdio.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/rx_descr.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/smoltcp.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/eth/tx_descr.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gic.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gpio/emio.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gpio/ll.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gpio/mio.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gpio/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/gtc.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/i2c.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/l2_cache.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/lib.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/log.rs (80%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/prelude.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/priv_tim.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/qspi/lqspi_configs.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/qspi/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/slcr.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/spi/asynch.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/spi/mod.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/time.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/ttc.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/uart/mod.rs (99%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/uart/rx.rs (100%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/uart/tx.rs (96%) rename {zynq7000-hal => zynq/zynq7000-hal}/src/uart/tx_async.rs (97%) create mode 100644 zynq/zynq7000-mmu/Cargo.toml rename {zynq-mmu => zynq/zynq7000-mmu}/src/lib.rs (100%) rename {zynq7000-rt => zynq/zynq7000-rt}/Cargo.toml (67%) rename {zynq7000-rt => zynq/zynq7000-rt}/README.md (100%) rename {zynq7000-rt => zynq/zynq7000-rt}/docs.sh (100%) rename {zynq7000-rt => zynq/zynq7000-rt}/regen-table.sh (100%) rename {zynq7000-rt => zynq/zynq7000-rt}/src/lib.rs (96%) rename {zynq7000-rt => zynq/zynq7000-rt}/src/mmu.rs (100%) rename {zynq7000-rt => zynq/zynq7000-rt}/src/mmu_table.rs (99%) rename {zynq7000-rt => zynq/zynq7000-rt}/src/rt.rs (100%) rename {zynq7000 => zynq/zynq7000}/Cargo.toml (100%) rename {zynq7000 => zynq/zynq7000}/LICENSE-APACHE (100%) rename {zynq7000 => zynq/zynq7000}/LICENSE-MIT (100%) rename {zynq7000 => zynq/zynq7000}/README.md (100%) rename {zynq7000 => zynq/zynq7000}/build.rs (100%) rename {zynq7000 => zynq/zynq7000}/docs.sh (100%) rename {zynq7000 => zynq/zynq7000}/src/ddrc.rs (87%) rename {zynq7000 => zynq/zynq7000}/src/devcfg.rs (100%) rename {zynq7000 => zynq/zynq7000}/src/eth.rs (97%) rename {zynq7000 => zynq/zynq7000}/src/gic.rs (96%) rename {zynq7000 => zynq/zynq7000}/src/gpio.rs (98%) rename {zynq7000 => zynq/zynq7000}/src/gtc.rs (95%) rename {zynq7000 => zynq/zynq7000}/src/i2c.rs (93%) rename {zynq7000 => zynq/zynq7000}/src/l2_cache.rs (95%) rename {zynq7000 => zynq/zynq7000}/src/lib.rs (100%) rename {zynq7000 => zynq/zynq7000}/src/mpcore.rs (100%) rename {zynq7000 => zynq/zynq7000}/src/priv_tim.rs (93%) rename {zynq7000 => zynq/zynq7000}/src/qspi.rs (94%) rename {zynq7000 => zynq/zynq7000}/src/slcr/clocks.rs (100%) rename {zynq7000 => zynq/zynq7000}/src/slcr/ddriob.rs (94%) rename {zynq7000 => zynq/zynq7000}/src/slcr/mio.rs (89%) rename {zynq7000 => zynq/zynq7000}/src/slcr/mod.rs (98%) rename {zynq7000 => zynq/zynq7000}/src/slcr/reset.rs (88%) rename {zynq7000 => zynq/zynq7000}/src/spi.rs (96%) rename {zynq7000 => zynq/zynq7000}/src/ttc.rs (94%) rename {zynq7000 => zynq/zynq7000}/src/uart.rs (95%) rename {zynq7000 => zynq/zynq7000}/src/xadc.rs (100%) create mode 100644 zynq7000-boot-image/.gitignore rename {zynq-boot-image => zynq7000-boot-image}/Cargo.toml (84%) rename {zynq-boot-image => zynq7000-boot-image}/src/lib.rs (100%) rename {zynq-boot-image => zynq7000-boot-image}/staging/.gitignore (100%) rename {zynq-boot-image => zynq7000-boot-image}/staging/README.md (100%) rename {zynq-boot-image => zynq7000-boot-image}/staging/boot.bif (100%) delete mode 100644 zynq7000-rt/Cargo.lock diff --git a/.cargo/config.toml.template b/.cargo/config.toml.template index a2dd61b..5092f1a 100644 --- a/.cargo/config.toml.template +++ b/.cargo/config.toml.template @@ -1,24 +1,3 @@ -[target.armv7a-none-eabihf] -runner = "./scripts/runner.sh" - -rustflags = [ - "-Ctarget-cpu=cortex-a9", - "-Ctarget-feature=+vfp3", - "-Ctarget-feature=+neon", - "-Clink-arg=-Tlink.x", - # If this is not enabled, debugging / stepping can become problematic. - "-Cforce-frame-pointers=yes", - # Can be useful for debugging. - # "-Clink-args=-Map=app.map" -] - -# Tier 3 target, so no pre-compiled artifacts included. -[unstable] -build-std = ["core", "alloc"] - -[build] -target = "armv7a-none-eabihf" - [env] # The following two env variables need to be set for the supplied runner.sh script to work. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46698e7..900e867 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,41 +7,69 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v3 - uses: dtolnay/rust-toolchain@nightly with: components: rust-src - # Copy config file for rustflags and to build core/alloc. - - run: cp .cargo/def-config.toml .cargo/config.toml - - run: cargo check --target armv7a-none-eabihf -p zynq7000 - - run: cargo check --target armv7a-none-eabihf -p zynq7000-rt + - run: just check zynq + + - uses: dtolnay/rust-toolchain@stable + - run: just check tools + - run: just check zynq7000-boot-image + + build: + name: Check build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: extractions/setup-just@v3 + + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - run: just build zynq + + - uses: dtolnay/rust-toolchain@stable + - run: just build tools + - run: just build zynq7000-boot-image fmt: name: Check formatting runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly + - uses: extractions/setup-just@v3 + - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - - run: cargo fmt --all -- --check + - run: just fmt zynq + - run: just fmt tools + - run: just fmt zynq7000-boot-image docs: name: Check Documentation Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v3 - uses: dtolnay/rust-toolchain@nightly - - run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000-rt --all-features - - run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000 --all-features + with: + components: rust-src + - run: just docs-zynq clippy: name: Clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v3 - uses: dtolnay/rust-toolchain@nightly with: components: clippy, rust-src - # Copy config file for rustflags and to build core/alloc. - - run: cp .cargo/def-config.toml .cargo/config.toml - - run: cargo clippy --target armv7a-none-eabihf -- -D warnings + - run: just clippy zynq + + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - run: just clippy tools + - run: just clippy zynq7000-boot-image diff --git a/.gitignore b/.gitignore index cad995a..a2e6b44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/target +target + /app.map /xsct-output.log /.vscode diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 5c9db71..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[workspace] -resolver = "3" -members = [ - "zynq7000-rt", - "zynq7000", - "zynq7000-hal", - "zynq7000-embassy", - "examples/simple", - "examples/embassy", - "examples/zedboard", - "zynq-mmu", - "zedboard-fsbl", - "zedboard-bsp", - "zynq-boot-image", "zedboard-qspi-flasher", -] - -exclude = [ - "zynq-boot-image/tester", -] - -# cargo build/run --release -[profile.release] -codegen-units = 1 -debug = 2 -debug-assertions = false # <- -incremental = false -lto = true -opt-level = 3 # <- -overflow-checks = false # <- - -[profile.small] -inherits = "release" -opt-level = "z" diff --git a/README.md b/README.md index 373294b..4b6e89e 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,23 @@ family of SoCs. # List of crates -This workspace contains the following crates: +This project contains the following crates: + +## Zynq Workspace + +This workspace contains libraries and application which can only be run on the target system. - The [`zynq7000-rt`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-rt) run-time crate containing basic low-level startup code necessary to boot a Rust app on the Zynq7000. - The [`zynq7000`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000) PAC - crate containing basic low-level register definition. + crate containing basic low-level register definitions. +- The [`zynq7000-mmu`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-hal) + crate containing common MMU abstractions used by both the HAL and the run-time crate. - The [`zynq7000-hal`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-hal) HAL crate containing higher-level abstractions on top of the PAC register crate. - The [`zynq7000-embassy`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-embassy) - crate containing support for running the embassy-rs RTOS. + crate containing support for running the embassy-rs asynchronous run-time. It also contains the following helper crates: @@ -25,13 +31,21 @@ It also contains the following helper crates: This folder also contains dedicated example applications using the [`embassy`](https://github.com/embassy-rs/embassy) native Rust RTOS. -The [`zedboard-fpga-design`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zedboard-fpga-design) -folder contains a sample FPGA design and block design which was used in -some of the provided software examples. The project was created with Vivado version 2024.1. -The folder contains a README with all the steps required to load this project from a TCL script. +## Other libraries and tools + +- The [`zedboard-fpga-design`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zedboard-fpga-design) + folder contains a sample FPGA design and block design which was used in some of the provided software examples. The project was created with Vivado version 2024.1. + The folder contains a README with all the steps required to load this project from a TCL script. +- The [`zynq7000-boot-image`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-boot-image) + library contains generic helpers to interface with the AMD + [boot binary](https://docs.amd.com/r/en-US/ug1283-bootgen-user-guide). +- The [`tools/zynq7000-ps7init-extract`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) + tool allows extracting configuration from the AMD generated `ps7init.tcl` file which contains + static configuration parameters for DDR initialization. # Using the `.cargo/config.toml` file +This is mostly relevant for development directly inside this repostiory. Use the following command to have a starting `config.toml` file ```sh diff --git a/justfile b/justfile index a761458..fe226d9 100644 --- a/justfile +++ b/justfile @@ -1,5 +1,45 @@ +all: check-all build-all clean-all fmt-all clippy-all docs-zynq + +check-all: (check "zynq") (check "tools") (check "zynq7000-boot-image") +clean-all: (clean "zynq") (clean "tools") (clean "zynq7000-boot-image") +build-all: build-zynq (build "tools") (build "zynq7000-boot-image") +fmt-all: (fmt "zynq") (fmt "tools") (fmt "zynq7000-boot-image") +clippy-all: (clippy "zynq") (clippy "tools") (clippy "zynq7000-boot-image") + +check target: + cd {{target}} && cargo check + +build target: + cd {{target}} && cargo build + +build-zynq: (build "zynq") + cd "zynq/zedboard-fsbl" && cargo build --release + +clean target: + cd {{target}} && cargo clean + +fmt target: + cd {{target}} && cargo +stable fmt --all -- --check + +clippy target: + cd {{target}} && cargo clippy -- -D warnings + +[working-directory: 'zynq'] +docs-zynq: + RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000 + RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000-hal --features alloc + RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000-mmu + RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p zynq7000-rt [working-directory: 'zynq-boot-image/staging'] bootgen: bootgen -arch zynq -image boot.bif -o boot.bin -w on echo "Generated boot.bin at zynq-boot-image/staging" + +[no-cd] +run binary: + # Run the initialization script. It needs to be run inside the justfile directory. + python3 {{justfile_directory()}}/scripts/zynq7000-init.py + + # Run the GDB debugger in GUI mode. + gdb-multiarch -q -x {{justfile_directory()}}/zynq/gdb.gdb {{binary}} -tui diff --git a/scripts/runner.sh b/scripts/runner.sh deleted file mode 100755 index 49e7049..0000000 --- a/scripts/runner.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Exit if no arguments are provided -if [ "$#" -eq 0 ]; then - echo "Error: No arguments provided." - echo "Usage: run.sh " - exit 1 -fi - -# Get the absolute path to the `scripts/` directory -SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" - -# Get the absolute path to the project root -ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" - -# Run the initialization script -"$SCRIPT_DIR/zynq7000-init.py" - -# Run the GDB debugger in GUI mode. -gdb-multiarch -q -x gdb.gdb "$@" -tui \ No newline at end of file diff --git a/scripts/unittest.sh b/scripts/unittest.sh deleted file mode 100755 index f3dab7d..0000000 --- a/scripts/unittest.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -cargo +stable test --target $(rustc -vV | grep host | cut -d ' ' -f2) -p zynq7000-hal -cargo +stable test --target $(rustc -vV | grep host | cut -d ' ' -f2) -p zynq7000 diff --git a/scripts/zynq7000-init.py b/scripts/zynq7000-init.py index 1de220d..fdcae84 100755 --- a/scripts/zynq7000-init.py +++ b/scripts/zynq7000-init.py @@ -121,7 +121,9 @@ def main(): bitstream = args.bit init_tcl = args.init_tcl - xsct_script = Path(TCL_SCRIPT_NAME) + # Get the script's directory + script_dir = Path(__file__).resolve().parent + xsct_script = script_dir / TCL_SCRIPT_NAME if not xsct_script.exists(): xsct_script = Path(os.path.join(SCRIPTS_DIR, TCL_SCRIPT_NAME)) diff --git a/tools/Cargo.lock b/tools/Cargo.lock new file mode 100644 index 0000000..ecb2c06 --- /dev/null +++ b/tools/Cargo.lock @@ -0,0 +1,796 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "arbitrary-int" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825297538d77367557b912770ca3083f778a196054b3ee63b22673c4a3cae0a5" + +[[package]] +name = "arbitrary-int" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c858caffa49edfc4ecc45a4bec37abd3e88041a2903816f10f990b7b41abc281" + +[[package]] +name = "arm-targets" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3371884971a96d71d8bd4e781188a7d327d7e5e455d07ef4c352922c66695e9e" + +[[package]] +name = "bitbybit" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec187a89ab07e209270175faf9e07ceb2755d984954e58a2296e325ddece2762" +dependencies = [ + "arbitrary-int 1.3.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "boot-image-test" +version = "0.1.0" +dependencies = [ + "clap", + "zynq7000-boot-image", +] + +[[package]] +name = "clap" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "cortex-ar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ea2a354642e242870bc43b57a517359b0be6e96d302b2811cd0644c979c54e" +dependencies = [ + "arbitrary-int 2.0.0", + "arm-targets", + "bitbybit", + "num_enum", + "thiserror", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive-mmio" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005a6dabf68a87a460d3cb9b8e2fd5de3f474fc34e8d9451f5a1b6db518da143" +dependencies = [ + "derive-mmio-macro", + "rustversion", +] + +[[package]] +name = "derive-mmio-macro" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "584dc8e12e4aeb88000c2be8ef7db15657c817fba3e77999a24807d1efcdeefa" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mmu-table-gen" +version = "0.1.0" +dependencies = [ + "zynq7000-mmu", + "zynq7000-rt", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[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.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "simple_logger" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c5dfa5e08767553704aa0ffd9d9794d527103c736aba9854773851fd7497eb" +dependencies = [ + "colored", + "log", + "time", + "windows-sys 0.48.0", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "zynq7000" +version = "0.1.0" +dependencies = [ + "arbitrary-int 2.0.0", + "bitbybit", + "derive-mmio", + "once_cell", + "rustversion", + "static_assertions", + "thiserror", +] + +[[package]] +name = "zynq7000-boot-image" +version = "0.1.0" +dependencies = [ + "arbitrary-int 2.0.0", + "bitbybit", + "thiserror", +] + +[[package]] +name = "zynq7000-mmu" +version = "0.1.0" +dependencies = [ + "cortex-ar", + "thiserror", +] + +[[package]] +name = "zynq7000-ps7init-extract" +version = "0.1.0" +dependencies = [ + "clap", + "log", + "proc-macro2", + "quote", + "regex", + "simple_logger", + "syn", + "zynq7000", +] + +[[package]] +name = "zynq7000-rt" +version = "0.1.0" +dependencies = [ + "arbitrary-int 2.0.0", + "cortex-ar", + "zynq7000-mmu", +] diff --git a/tools/Cargo.toml b/tools/Cargo.toml new file mode 100644 index 0000000..c3e5666 --- /dev/null +++ b/tools/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +resolver = "3" +members = [ + "boot-image-test", + "mmu-table-gen", + "zynq7000-ps7init-extract", +] diff --git a/zynq-boot-image/tester/.gitignore b/tools/boot-image-test/.gitignore similarity index 100% rename from zynq-boot-image/tester/.gitignore rename to tools/boot-image-test/.gitignore diff --git a/zynq-boot-image/tester/Cargo.lock b/tools/boot-image-test/Cargo.lock similarity index 100% rename from zynq-boot-image/tester/Cargo.lock rename to tools/boot-image-test/Cargo.lock diff --git a/zynq-boot-image/tester/Cargo.toml b/tools/boot-image-test/Cargo.toml similarity index 56% rename from zynq-boot-image/tester/Cargo.toml rename to tools/boot-image-test/Cargo.toml index 4cc3de7..cdca892 100644 --- a/zynq-boot-image/tester/Cargo.toml +++ b/tools/boot-image-test/Cargo.toml @@ -1,10 +1,8 @@ -[workspace] - [package] -name = "tester" +name = "boot-image-test" version = "0.1.0" edition = "2024" [dependencies] -zynq-boot-image= { path = ".." } +zynq7000-boot-image= { path = "../../zynq7000-boot-image" } clap = { version = "4", features = ["derive"] } diff --git a/zynq-boot-image/tester/src/main.rs b/tools/boot-image-test/src/main.rs similarity index 98% rename from zynq-boot-image/tester/src/main.rs rename to tools/boot-image-test/src/main.rs index bff0c55..c793ef5 100644 --- a/zynq-boot-image/tester/src/main.rs +++ b/tools/boot-image-test/src/main.rs @@ -2,7 +2,7 @@ use std::{io::Read, path::Path}; use clap::Parser as _; -use zynq_boot_image::{BootHeader, FIXED_BOOT_HEADER_SIZE}; +use zynq7000_boot_image::{BootHeader, FIXED_BOOT_HEADER_SIZE}; #[derive(clap::Parser, Debug)] #[command(version, about)] diff --git a/tools/mmu-table-gen/Cargo.toml b/tools/mmu-table-gen/Cargo.toml new file mode 100644 index 0000000..9736709 --- /dev/null +++ b/tools/mmu-table-gen/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "mmu-table-gen" +version = "0.1.0" +edition = "2024" + +[dependencies] +zynq7000-rt = { path = "../../zynq/zynq7000-rt", default-features = false } +zynq7000-mmu = { path = "../../zynq/zynq7000-mmu", features = ["tools"] } diff --git a/zynq7000-rt/src/bin/table-gen.rs b/tools/mmu-table-gen/src/main.rs similarity index 98% rename from zynq7000-rt/src/bin/table-gen.rs rename to tools/mmu-table-gen/src/main.rs index dccfb0e..faa3504 100644 --- a/zynq7000-rt/src/bin/table-gen.rs +++ b/tools/mmu-table-gen/src/main.rs @@ -16,7 +16,7 @@ macro_rules! write_l1_section { } fn main() { - let file_path = "src/mmu_table.rs"; + let file_path = "mmu_table.rs"; let file = File::create(file_path).expect("Failed to create file"); let mut offset = 0; @@ -56,7 +56,7 @@ fn main() { writeln!(buf_writer, "use crate::mmu::section_attrs;").unwrap(); writeln!(buf_writer, "use cortex_ar::mmu::L1Section;").unwrap(); - writeln!(buf_writer, "use zynq_mmu::L1Table;").unwrap(); + writeln!(buf_writer, "use zynq7000_mmu::L1Table;").unwrap(); writeln!(buf_writer, "").unwrap(); writeln!(buf_writer, "/// MMU Level 1 Page table.").unwrap(); diff --git a/tools/zynq7000-ps7init-extract/.gitignore b/tools/zynq7000-ps7init-extract/.gitignore new file mode 100644 index 0000000..f632ad1 --- /dev/null +++ b/tools/zynq7000-ps7init-extract/.gitignore @@ -0,0 +1,2 @@ +/ddrc_config_autogen.rs +/ddriob_config_autogen.rs diff --git a/tools/zynq7000-ps7init-extract/Cargo.lock b/tools/zynq7000-ps7init-extract/Cargo.lock new file mode 100644 index 0000000..074b1ff --- /dev/null +++ b/tools/zynq7000-ps7init-extract/Cargo.lock @@ -0,0 +1,251 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "clap" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "zynq7000-ps7init-extract" +version = "0.1.0" +dependencies = [ + "clap", +] diff --git a/tools/zynq7000-ps7init-extract/Cargo.toml b/tools/zynq7000-ps7init-extract/Cargo.toml new file mode 100644 index 0000000..27b5b51 --- /dev/null +++ b/tools/zynq7000-ps7init-extract/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "zynq7000-ps7init-extract" +version = "0.1.0" +edition = "2024" + +[dependencies] +clap = { version = "4", features = ["derive"] } +zynq7000 = { path = "../../zynq/zynq7000" } +log = "0.4" +simple_logger = "5" +regex = "1" +quote = "1" +syn = "2" +proc-macro2 = "1" diff --git a/tools/zynq7000-ps7init-extract/README.md b/tools/zynq7000-ps7init-extract/README.md new file mode 100644 index 0000000..37179e6 --- /dev/null +++ b/tools/zynq7000-ps7init-extract/README.md @@ -0,0 +1,26 @@ +Zynq7000 PS7 Init Extractor +========= + +AMD provides tooling to auto-generate some of the hardware initialization for the external DDR +as native Rust code. + +The AMD tooling generates these files as `ps7init.tcl`, `ps7init.c`, `ps7init.h` files but not as +Rust files. The specific parameters required for different DDR chips are proprietary, so that +portion is required for Rust programs as well. Do avoid the need of compiling the PS7 initialization +scripts with a C compiler, this tool extracts all required configuration parameters for DDR and +DDRIOB initialization and configuration and exports them as native Rust constants. + +The generates files can be placed in individual projects or board support packages to initialize +the DDR in conjunction with the [Zynq7000 HAL library](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/fsbl-rs/zynq/zynq7000-hal). + +Right now, the script expects the `ps7init.tcl` file to be passed as a command line argument +for `-p` or `--path`. It then generates the configuration as a `ddrc_config_autogen.rs` and +`ddrc_config_autogen.rs` file. + +For example, assuming that there is a `ps7init.tcl` script in the current directory, you can use + +```sh +cargo run -- --path ./ps7init.tcl +``` + +to generate the configuration files. diff --git a/tools/zynq7000-ps7init-extract/src/main.rs b/tools/zynq7000-ps7init-extract/src/main.rs new file mode 100644 index 0000000..49e62f9 --- /dev/null +++ b/tools/zynq7000-ps7init-extract/src/main.rs @@ -0,0 +1,341 @@ +use std::{collections::HashMap, ops::RangeInclusive, path::Path}; + +use clap::Parser as _; +use simple_logger::SimpleLogger; + +const DDRC_ADDR_RANGE: RangeInclusive = 0xf800_6000..=0xf800_62b4; +const DDRIOB_ADDR_RANGE: RangeInclusive = 0xf800_0b40..=0xf800_0b68; + +const DDRC_FILE_NAME: &str = "ddrc_config_autogen.rs"; +const DDRIOB_FILE_NAME: &str = "ddriob_config_autogen.rs"; + +#[derive(clap::Parser, Debug)] +#[command(version, about)] +pub struct Cli { + /// Path to ps7init.tcl file. + #[arg(short, long)] + path: String, +} + +fn extract_hex_values(line: &str) -> Option<(u32, u32, u32)> { + let re = regex::Regex::new(r"0[xX]([0-9A-Fa-f]+)").unwrap(); + + let captures: Vec = re + .captures_iter(line) + .filter_map(|cap| u32::from_str_radix(&cap[1], 16).ok()) + .collect(); + + if captures.len() == 3 { + Some((captures[0], captures[1], captures[2])) + } else { + None + } +} + +#[derive(Default)] +pub struct RegisterToValueMap(pub HashMap); + +impl RegisterToValueMap { + fn val_as_token(&self, reg_name: &str, addr: u32) -> proc_macro2::TokenStream { + let val = self.0.get(&addr).unwrap_or_else(|| { + panic!( + "failed to retrieve register value for register {}", + reg_name + ) + }); + format!("{:#010x}", val) + .parse::() + .unwrap() + } +} + +enum ParsingMode { + DdrRev3, + MioRev3, +} + +fn main() -> std::io::Result<()> { + SimpleLogger::new().init().unwrap(); + let cli = Cli::parse(); + let ps7init_tcl = Path::new(&cli.path); + if !ps7init_tcl.exists() { + log::error!("File not found: {}", ps7init_tcl.display()); + std::process::exit(1); + } + let mut parsing_mode = None; + + let mut reg_to_values = RegisterToValueMap::default(); + + for line in std::fs::read_to_string(ps7init_tcl)?.lines() { + match parsing_mode { + None => { + if line.contains("ps7_ddr_init_data_3_0") { + parsing_mode = Some(ParsingMode::DdrRev3); + } else if line.contains("ps7_mio_init_data_3_0") { + parsing_mode = Some(ParsingMode::MioRev3); + } + continue; + } + Some(ParsingMode::MioRev3) => { + if line.contains("}") { + parsing_mode = None; + continue; + } + } + Some(ParsingMode::DdrRev3) => { + if line.contains("}") { + parsing_mode = None; + continue; + } + } + } + + if let Some((addr, _mask, value)) = extract_hex_values(line) + && (DDRC_ADDR_RANGE.contains(&addr) || DDRIOB_ADDR_RANGE.contains(&addr)) + && addr % 4 == 0 + { + // Only use first value. + if reg_to_values.0.contains_key(&addr) { + if addr != 0xF800_6000 { + log::warn!("detected duplicate register value for address {}", addr); + } + continue; + } + reg_to_values.0.insert(addr, value); + } + } + + log::info!("generating DDRC config files: {}", DDRC_FILE_NAME); + generate_ddrc_config(®_to_values, DDRC_FILE_NAME)?; + + log::info!("generating DDRIOB config files: {}", DDRIOB_FILE_NAME); + generate_ddriob_config(®_to_values, DDRIOB_FILE_NAME)?; + + Ok(()) +} + +fn generate_ddrc_config( + reg_to_values: &RegisterToValueMap, + file_name: &str, +) -> std::io::Result<()> { + // Format as hex strings + let ddrc = reg_to_values.val_as_token("DDRC Control", 0xF800_6000); + let two_rank = reg_to_values.val_as_token("Two Rank", 0xF800_6004); + let hpr = reg_to_values.val_as_token("HPR", 0xF800_6008); + let lpr = reg_to_values.val_as_token("LPR", 0xF800_600C); + let wr = reg_to_values.val_as_token("WR", 0xF800_6010); + let dram_param_0 = reg_to_values.val_as_token("DRAM Reg0", 0xF800_6014); + let dram_param_1 = reg_to_values.val_as_token("DRAM Reg1", 0xF800_6018); + let dram_param_2 = reg_to_values.val_as_token("DRAM Reg2", 0xF800_601C); + let dram_param_3 = reg_to_values.val_as_token("DRAM Reg3", 0xF800_6020); + let dram_param_4 = reg_to_values.val_as_token("DRAM Reg4", 0xF800_6024); + let dram_init_param = reg_to_values.val_as_token("DRAM Init Param", 0xF800_6028); + let dram_emr = reg_to_values.val_as_token("DRAM EMR", 0xF800_602C); + let dram_emr_mr = reg_to_values.val_as_token("DRAM EMR MR", 0xF800_6030); + let dram_burst8_rdwr = reg_to_values.val_as_token("DRAM Burst8 RDWR", 0xF800_6034); + let dram_disable_dq = reg_to_values.val_as_token("DRAM Disable DQ", 0xF800_6038); + let dram_addr_map_bank = reg_to_values.val_as_token("DRAM Addr Map Bank", 0xF800_603C); + let dram_addr_map_col = reg_to_values.val_as_token("DRAM Addr Map Col", 0xF800_6040); + let dram_addr_map_row = reg_to_values.val_as_token("DRAM Addr Map Row", 0xF800_6044); + let dram_odt = reg_to_values.val_as_token("DRAM ODT", 0xF800_6048); + let phy_cmd_timeout_rddata_cpt = reg_to_values.val_as_token("PHY CMD Timeout", 0xF800_6050); + let dll_calib = reg_to_values.val_as_token("DLL Calib", 0xF800_6058); + let odt_delay_hold = reg_to_values.val_as_token("ODT Delay Hold", 0xF800_605C); + let ctrl_reg1 = reg_to_values.val_as_token("CTRL Reg 1", 0xF800_6060); + let ctrl_reg2 = reg_to_values.val_as_token("CTRL Reg 2", 0xF800_6064); + let ctrl_reg3 = reg_to_values.val_as_token("CTRL Reg 3", 0xF800_6068); + let ctrl_reg4 = reg_to_values.val_as_token("CTRL Reg 4", 0xF800_606C); + let ctrl_reg5 = reg_to_values.val_as_token("CTRL Reg 5", 0xF800_6078); + let ctrl_reg6 = reg_to_values.val_as_token("CTRL Reg 6", 0xF800_607C); + let che_t_zq = reg_to_values.val_as_token("CHE T ZQ", 0xF800_60A4); + let che_t_zq_short_interval_reg = + reg_to_values.val_as_token("CHE T ZQ Short Interval", 0xF800_60A4); + let deep_powerdown = reg_to_values.val_as_token("Deep Powerdown", 0xF800_60AC); + let reg_2c = reg_to_values.val_as_token("Reg 2C", 0xF800_60B0); + let reg_2d = reg_to_values.val_as_token("Reg 2D", 0xF800_60B4); + let dfi_timing = reg_to_values.val_as_token("DFI Timing", 0xF800_60B8); + let che_ecc_ctrl = reg_to_values.val_as_token("CHE ECC CTRL", 0xF800_60C4); + let ecc_scrub = reg_to_values.val_as_token("ECC Scrub", 0xF800_60F4); + let phy_receiver_enable = reg_to_values.val_as_token("PHY Receiver Enable", 0xF800_6114); + let phy_config_0 = reg_to_values.val_as_token("PHY Config 0", 0xF800_6118); + let phy_config_1 = reg_to_values.val_as_token("PHY Config 1", 0xF800_611C); + let phy_config_2 = reg_to_values.val_as_token("PHY Config 2", 0xF800_6120); + let phy_config_3 = reg_to_values.val_as_token("PHY Config 3", 0xF800_6124); + let phy_init_ratio_0 = reg_to_values.val_as_token("PHY Init Ratio 0", 0xF800_612C); + let phy_init_ratio_1 = reg_to_values.val_as_token("PHY Init Ratio 1", 0xF800_6130); + let phy_init_ratio_2 = reg_to_values.val_as_token("PHY Init Ratio 2", 0xF800_6134); + let phy_init_ratio_3 = reg_to_values.val_as_token("PHY Init Ratio 3", 0xF800_6138); + let phy_rd_dqs_config_0 = reg_to_values.val_as_token("PHY RD DQS Config 0", 0xF800_6140); + let phy_rd_dqs_config_1 = reg_to_values.val_as_token("PHY RD DQS Config 1", 0xF800_6144); + let phy_rd_dqs_config_2 = reg_to_values.val_as_token("PHY RD DQS Config 2", 0xF800_6148); + let phy_rd_dqs_config_3 = reg_to_values.val_as_token("PHY RD DQS Config 3", 0xF800_614C); + let phy_wr_dqs_config_0 = reg_to_values.val_as_token("PHY WR DQS Config 0", 0xF800_6154); + let phy_wr_dqs_config_1 = reg_to_values.val_as_token("PHY WR DQS Config 1", 0xF800_6158); + let phy_wr_dqs_config_2 = reg_to_values.val_as_token("PHY WR DQS Config 2", 0xF800_615C); + let phy_wr_dqs_config_3 = reg_to_values.val_as_token("PHY WR DQS Config 3", 0xF800_6160); + let phy_we_cfg_0 = reg_to_values.val_as_token("PHY WE Config 0", 0xF800_6168); + let phy_we_cfg_1 = reg_to_values.val_as_token("PHY WE Config 1", 0xF800_616C); + let phy_we_cfg_2 = reg_to_values.val_as_token("PHY WE Config 2", 0xF800_6170); + let phy_we_cfg_3 = reg_to_values.val_as_token("PHY WE Config 3", 0xF800_6174); + let phy_wr_data_slv_0 = reg_to_values.val_as_token("PHY WR Data Slv 0", 0xF800_617C); + let phy_wr_data_slv_1 = reg_to_values.val_as_token("PHY WR Data Slv 1", 0xF800_6180); + let phy_wr_data_slv_2 = reg_to_values.val_as_token("PHY WR Data Slv 2", 0xF800_6184); + let phy_wr_data_slv_3 = reg_to_values.val_as_token("PHY WR Data Slv 3", 0xF800_6188); + let reg64 = reg_to_values.val_as_token("Reg64", 0xF800_6190); + let reg65 = reg_to_values.val_as_token("Reg65", 0xF800_6194); + let page_mask = reg_to_values.val_as_token("Page Mask", 0xF800_6204); + let axi_priority_wr_port_0 = reg_to_values.val_as_token("AXI Priority WR Port 0", 0xF800_6208); + let axi_priority_wr_port_1 = reg_to_values.val_as_token("AXI Priority WR Port 1", 0xF800_620C); + let axi_priority_wr_port_2 = reg_to_values.val_as_token("AXI Priority WR Port 2", 0xF800_6210); + let axi_priority_wr_port_3 = reg_to_values.val_as_token("AXI Priority WR Port 3", 0xF800_6214); + let axi_priority_rd_port_0 = reg_to_values.val_as_token("AXI Priority RD Port 0", 0xF800_6218); + let axi_priority_rd_port_1 = reg_to_values.val_as_token("AXI Priority RD Port 1", 0xF800_621C); + let axi_priority_rd_port_2 = reg_to_values.val_as_token("AXI Priority RD Port 2", 0xF800_6220); + let axi_priority_rd_port_3 = reg_to_values.val_as_token("AXI Priority RD Port 3", 0xF800_6224); + let lpddr_ctrl_0 = reg_to_values.val_as_token("LPDDR CTRL 0", 0xF800_62A8); + let lpddr_ctrl_1 = reg_to_values.val_as_token("LPDDR CTRL 1", 0xF800_62AC); + let lpddr_ctrl_2 = reg_to_values.val_as_token("LPDDR CTRL 2", 0xF800_62B0); + let lpddr_ctrl_3 = reg_to_values.val_as_token("LPDDR CTRL 3", 0xF800_62B4); + + let generated = quote::quote! { + //!This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program. + //! + //!This configuration file contains static DDR configuration parameters extracted from the + //!AMD ps7init.tcl file + use zynq7000::ddrc::regs; + use zynq7000_hal::ddr::DdrcConfigSet; + + pub const DDRC_CONFIG_ZEDBOARD: DdrcConfigSet = DdrcConfigSet { + ctrl: regs::DdrcControl::new_with_raw_value(#ddrc), + two_rank: regs::TwoRankConfig::new_with_raw_value(#two_rank), + hpr: regs::LprHprQueueControl::new_with_raw_value(#hpr), + lpr: regs::LprHprQueueControl::new_with_raw_value(#lpr), + wr: regs::WriteQueueControl::new_with_raw_value(#wr), + dram_param_0: regs::DramParamReg0::new_with_raw_value(#dram_param_0), + dram_param_1: regs::DramParamReg1::new_with_raw_value(#dram_param_1), + dram_param_2: regs::DramParamReg2::new_with_raw_value(#dram_param_2), + dram_param_3: regs::DramParamReg3::new_with_raw_value(#dram_param_3), + dram_param_4: regs::DramParamReg4::new_with_raw_value(#dram_param_4), + dram_init_param: regs::DramInitParam::new_with_raw_value(#dram_init_param), + dram_emr: regs::DramEmr::new_with_raw_value(#dram_emr), + dram_emr_mr: regs::DramEmrMr::new_with_raw_value(#dram_emr_mr), + dram_burst8_rdwr: regs::DramBurst8ReadWrite::new_with_raw_value(#dram_burst8_rdwr), + disable_dq: regs::DisableDq::new_with_raw_value(#dram_disable_dq), + dram_addr_map_bank: regs::DramAddrMapBank::new_with_raw_value(#dram_addr_map_bank), + dram_addr_map_col: regs::DramAddrMapColumn::new_with_raw_value(#dram_addr_map_col), + dram_addr_map_row: regs::DramAddrMapRow::new_with_raw_value(#dram_addr_map_row), + dram_odt: regs::DramOdt::new_with_raw_value(#dram_odt), + phy_cmd_timeout_rddata_cpt: regs::PhyCmdTimeoutRdDataCpt::new_with_raw_value(#phy_cmd_timeout_rddata_cpt), + dll_calib: regs::DllCalib::new_with_raw_value(#dll_calib), + odt_delay_hold: regs::OdtDelayHold::new_with_raw_value(#odt_delay_hold), + ctrl_reg1: regs::CtrlReg1::new_with_raw_value(#ctrl_reg1), + ctrl_reg2: regs::CtrlReg2::new_with_raw_value(#ctrl_reg2), + ctrl_reg3: regs::CtrlReg3::new_with_raw_value(#ctrl_reg3), + ctrl_reg4: regs::CtrlReg4::new_with_raw_value(#ctrl_reg4), + ctrl_reg5: regs::CtrlReg5::new_with_raw_value(#ctrl_reg5), + ctrl_reg6: regs::CtrlReg6::new_with_raw_value(#ctrl_reg6), + che_t_zq: regs::CheTZq::new_with_raw_value(#che_t_zq), + che_t_zq_short_interval_reg: regs::CheTZqShortInterval::new_with_raw_value(#che_t_zq_short_interval_reg), + deep_powerdown: regs::DeepPowerdown::new_with_raw_value(#deep_powerdown), + reg_2c: regs::Reg2c::new_with_raw_value(#reg_2c), + reg_2d: regs::Reg2d::new_with_raw_value(#reg_2d), + dfi_timing: regs::DfiTiming::new_with_raw_value(#dfi_timing), + che_ecc_ctrl: regs::CheEccControl::new_with_raw_value(#che_ecc_ctrl), + ecc_scrub: regs::EccScrub::new_with_raw_value(#ecc_scrub), + phy_receiver_enable: regs::PhyReceiverEnable::new_with_raw_value(#phy_receiver_enable), + phy_config: [ + regs::PhyConfig::new_with_raw_value(#phy_config_0), + regs::PhyConfig::new_with_raw_value(#phy_config_1), + regs::PhyConfig::new_with_raw_value(#phy_config_2), + regs::PhyConfig::new_with_raw_value(#phy_config_3), + ], + phy_init_ratio: [ + regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_0), + regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_1), + regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_2), + regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_3), + ], + phy_rd_dqs_config: [ + regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_0), + regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_1), + regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_2), + regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_3), + ], + phy_wr_dqs_config: [ + regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_0), + regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_1), + regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_2), + regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_3), + ], + phy_we_cfg: [ + regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_0), + regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_1), + regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_2), + regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_3), + ], + phy_wr_data_slv: [ + regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_0), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_1), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_2), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_3), + ], + reg64: regs::Reg64::new_with_raw_value(#reg64), + reg65: regs::Reg65::new_with_raw_value(#reg65), + page_mask: #page_mask, + axi_priority_wr_port: [ + regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_0), + regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_1), + regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_2), + regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_3), + ], + axi_priority_rd_port: [ + regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_0), + regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_1), + regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_2), + regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_3), + ], + lpddr_ctrl_0: regs::LpddrControl0::new_with_raw_value(#lpddr_ctrl_0), + lpddr_ctrl_1: regs::LpddrControl1::new_with_raw_value(#lpddr_ctrl_1), + lpddr_ctrl_2: regs::LpddrControl2::new_with_raw_value(#lpddr_ctrl_2), + lpddr_ctrl_3: regs::LpddrControl3::new_with_raw_value(#lpddr_ctrl_3), + }; + }; + + std::fs::write(file_name, generated.to_string())?; + Ok(()) +} + +fn generate_ddriob_config( + reg_to_values: &RegisterToValueMap, + file_name: &str, +) -> std::io::Result<()> { + // Format as hex strings + let addr0 = reg_to_values.val_as_token("DDRIOB Addr 0", 0xF800_0B40); + let addr1 = reg_to_values.val_as_token("DDRIOB Addr 1", 0xF800_0B44); + let data0 = reg_to_values.val_as_token("DDRIOB Data 0", 0xF800_0B48); + let data1 = reg_to_values.val_as_token("DDRIOB Data 1", 0xF800_0B4C); + let diff0 = reg_to_values.val_as_token("DDRIOB Diff 0", 0xF800_0B50); + let diff1 = reg_to_values.val_as_token("DDRIOB Diff 1", 0xF800_0B54); + let clock = reg_to_values.val_as_token("DDRIOB Clock", 0xF800_0B58); + let generated = quote::quote! { + //!This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program. + //! + //!This configuration file contains static DDRIOB configuration parameters extracted from the + //!AMD ps7init.tcl file + use zynq7000::ddrc::regs; + use zynq7000_hal::ddr::DdriobConfigSet; + + pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet { + addr0: regs::DdriobConfig::new_with_raw_value(#addr0), + addr1: regs::DdriobConfig::new_with_raw_value(#addr1), + data0: regs::DdriobConfig::new_with_raw_value(#data0), + data1: regs::DdriobConfig::new_with_raw_value(#data1), + diff0: regs::DdriobConfig::new_with_raw_value(#diff0), + diff1: regs::DdriobConfig::new_with_raw_value(#diff1), + clock: regs::DdriobConfig::new_with_raw_value(#clock), + }; + }; + + std::fs::write(file_name, generated.to_string())?; + Ok(()) +} diff --git a/zedboard-bsp/src/lib.rs b/zedboard-bsp/src/lib.rs deleted file mode 100644 index 719c662..0000000 --- a/zedboard-bsp/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] - -pub mod phy_marvell; -pub mod qspi_spansion; diff --git a/zedboard-fpga-design/README.md b/zedboard-fpga-design/README.md index 2e4d5f6..2533876 100644 --- a/zedboard-fpga-design/README.md +++ b/zedboard-fpga-design/README.md @@ -38,3 +38,25 @@ vivado zedboard-rust.xpr You can perform all the steps specified in the Vivado GUI as well using `Execute TCL script` and `Load Project`. + +# Generating the SDT folder from a hardware description + +You can generate a hardware description by building the block design by using `Generate Bitstream` +inside the Vivado GUI and then exporting the hardware description via +`File -> Export -> Export Hardware`. This allows to generate a `*.xsa` file which describes the +hardware. + +After that, you can generate the SDT output folder which contains various useful files like +the `ps7_init.tcl` script. The provided ` sdtgen.tcl` and `stdgen.py` script simplify this process. + +For example, the following command generates the SDT output folder inside a folder +named `sdt_out` for a hardware description files `zedboard-rust/zedboard-rust.xsa`, +assuming that the Vitis tool suite is installed at `/tools/Xilinx/Vitis/2024.1`: + +```sh +export AMD_TOOLS="/tools/Xilinx/Vitis/2024.1" +./sdtgen.py -x ./zedboard-rust/zedboard-rust.xsa +``` + +Run `stdgen.py -h` for more information and configuration options. The `stdgen.py` is a helper +script which will invoke `sdtgen.tcl` to generate the SDT. diff --git a/zedboard-fsbl/src/ddr_cfg.rs b/zedboard-fsbl/src/ddr_cfg.rs deleted file mode 100644 index 52d2dd0..0000000 --- a/zedboard-fsbl/src/ddr_cfg.rs +++ /dev/null @@ -1,503 +0,0 @@ -use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20}; -use zynq7000::{ - ddrc::regs::{ - AxiPriorityReadPort, AxiPriorityWritePort, CheEccControl, CheTZq, CheTZqShortInterval, - CtrlReg1, CtrlReg2, CtrlReg3, CtrlReg4, CtrlReg5, CtrlReg6, DataBusWidth, DdrcControl, - DeepPowerdown, DfiTiming, DisableDq, DllCalib, DllCalibSel, DramAddrMapBank, - DramAddrMapColumn, DramAddrMapRow, DramBurst8ReadWrite, DramEmr, DramEmrMr, DramInitParam, - DramOdt, DramParamReg0, DramParamReg1, DramParamReg2, DramParamReg3, DramParamReg4, - EccMode, EccScrub, LpddrBit, LpddrControl0, LpddrControl1, LpddrControl2, LpddrControl3, - LprHprQueueControl, MobileSetting, ModeRegisterType, OdtDelayHold, PhyCmdTimeoutRdDataCpt, - PhyConfig, PhyDqsConfig, PhyInitRatio, PhyReceiverEnable, PhyWriteDataSlaveConfig, - PhyWriteEnableConfig, Reg2c, Reg2d, Reg64, Reg65, SoftReset, TwoRankConfig, - WriteQueueControl, - }, - slcr::ddriob::{DciType, DdriobConfig, InputType, OutputEnable}, -}; -use zynq7000_hal::ddr::{DdrcConfigSet, DdriobConfigSet}; - -const DDRIOB_ADDR_CFG: DdriobConfig = DdriobConfig::builder() - .with_pullup_enable(false) - .with_output_enable(OutputEnable::OBuf) - .with_term_disable_mode(false) - .with_ibuf_disable_mode(false) - .with_dci_type(DciType::Disabled) - .with_termination_enable(false) - .with_dci_update_enable(false) - .with_inp_type(InputType::Off) - .build(); - -const DDRIOB_DATA_CFG: DdriobConfig = DdriobConfig::builder() - .with_pullup_enable(false) - .with_output_enable(OutputEnable::OBuf) - .with_term_disable_mode(false) - .with_ibuf_disable_mode(false) - .with_dci_type(DciType::DciTermination) - .with_termination_enable(true) - .with_dci_update_enable(false) - .with_inp_type(InputType::VRefBasedDifferentialReceiverForSstlHstl) - .build(); - -const DDRIOB_DIFF_CFG: DdriobConfig = DdriobConfig::builder() - .with_pullup_enable(false) - .with_output_enable(OutputEnable::OBuf) - .with_term_disable_mode(false) - .with_ibuf_disable_mode(false) - .with_dci_type(DciType::DciTermination) - .with_termination_enable(true) - .with_dci_update_enable(false) - .with_inp_type(InputType::DifferentialInputReceiver) - .build(); - -const DDRIOB_CLOCK_CFG: DdriobConfig = DdriobConfig::builder() - .with_pullup_enable(false) - .with_output_enable(OutputEnable::OBuf) - .with_term_disable_mode(false) - .with_ibuf_disable_mode(false) - .with_dci_type(DciType::Disabled) - .with_termination_enable(false) - .with_dci_update_enable(false) - .with_inp_type(InputType::Off) - .build(); - -// TODO: Auto-generate from ps7init.tcl -pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet { - addr0: DDRIOB_ADDR_CFG, - addr1: DDRIOB_ADDR_CFG, - data0: DDRIOB_DATA_CFG, - data1: DDRIOB_DATA_CFG, - diff0: DDRIOB_DIFF_CFG, - diff1: DDRIOB_DIFF_CFG, - clock: DDRIOB_CLOCK_CFG, -}; - -// TODO: Auto-generate from ps7init.tcl -pub const DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS: DdrcConfigSet = DdrcConfigSet { - ctrl: DdrcControl::builder() - .with_disable_auto_refresh(false) - .with_disable_active_bypass(false) - .with_disable_read_bypass(false) - .with_read_write_idle_gap(u7::new(1)) - .with_burst8_refresh(u3::new(0)) - .with_data_bus_width(DataBusWidth::_32Bit) - .with_power_down_enable(false) - .with_soft_reset(SoftReset::Reset) - .build(), - two_rank: TwoRankConfig::builder() - .with_addrmap_cs_bit0(u5::new(0)) - .with_ddrc_active_ranks(u2::new(1)) - .with_rfc_nom_x32(u12::new(0x82)) - .build(), - hpr: LprHprQueueControl::builder() - .with_xact_run_length(u4::new(0xf)) - .with_max_starve_x32(u11::new(0xf)) - .with_min_non_critical_x32(u11::new(0xf)) - .build(), - lpr: LprHprQueueControl::builder() - .with_xact_run_length(u4::new(0x8)) - .with_max_starve_x32(u11::new(0x2)) - .with_min_non_critical_x32(u11::new(0x1)) - .build(), - wr: WriteQueueControl::builder() - .with_max_starve_x32(u11::new(0x2)) - .with_xact_run_length(u4::new(0x8)) - .with_min_non_critical_x32(u11::new(0x1)) - .build(), - dram_param_0: DramParamReg0::builder() - .with_post_selfref_gap_x32(u7::new(0x10)) - .with_t_rfc_min(0x56) - .with_t_rc(u6::new(0x1b)) - .build(), - dram_param_1: DramParamReg1::builder() - .with_t_cke(u4::new(0x4)) - .with_t_ras_min(u5::new(0x13)) - .with_t_ras_max(u6::new(0x24)) - .with_t_faw(u6::new(0x16)) - .with_powerdown_to_x32(u5::new(0x6)) - .with_wr2pre(u5::new(0x13)) - .build(), - dram_param_2: DramParamReg2::builder() - .with_t_rcd(u4::new(0x7)) - .with_rd2pre(u5::new(0x5)) - .with_pad_pd(u3::new(0x0)) - .with_t_xp(u5::new(0x5)) - .with_wr2rd(u5::new(0xf)) - .with_rd2wr(u5::new(0x7)) - .with_write_latency(u5::new(0x5)) - .build(), - dram_param_3: DramParamReg3::builder() - .with_disable_pad_pd_feature(false) - .with_read_latency(u5::new(0x7)) - .with_enable_dfi_dram_clk_disable(false) - .with_mobile(MobileSetting::Ddr2Ddr3) - .with_sdram(false) - .with_refresh_to_x32(u5::new(0x8)) - .with_t_rp(u4::new(0x7)) - .with_refresh_margin(u4::new(0x2)) - .with_t_rrd(u3::new(0x6)) - .with_t_ccd(u3::new(0x4)) - .build(), - dram_param_4: DramParamReg4::builder() - .with_mr_rdata_valid(false) - .with_mr_type(ModeRegisterType::Write) - .with_mr_wr_busy(false) - .with_mr_data(0x0) - .with_mr_addr(u2::new(0x0)) - .with_mr_wr(false) - .with_prefer_write(false) - .with_enable_2t_timing_mode(false) - .build(), - dram_init_param: DramInitParam::builder() - .with_t_mrd(u3::new(0x4)) - .with_pre_ocd_x32(u4::new(0x0)) - .with_final_wait_x32(u7::new(0x7)) - .build(), - dram_emr: DramEmr::builder().with_emr3(0x0).with_emr2(0x8).build(), - dram_emr_mr: DramEmrMr::builder().with_emr(0x4).with_mr(0xb30).build(), - dram_burst8_rdwr: DramBurst8ReadWrite::builder() - .with_burst_rdwr(u4::new(0x4)) - .with_pre_cke_x1024(u10::new(0x16d)) - .with_post_cke_x1024(u10::new(0x1)) - .with_burstchop(false) - .build(), - disable_dq: DisableDq::builder() - .with_dis_dq(false) - .with_force_low_pri_n(false) - .build(), - dram_addr_map_bank: DramAddrMapBank::builder() - .with_addrmap_bank_b6(u4::new(0)) - .with_addrmap_bank_b5(u4::new(0)) - .with_addrmap_bank_b2(u4::new(0x7)) - .with_addrmap_bank_b1(u4::new(0x7)) - .with_addrmap_bank_b0(u4::new(0x7)) - .build(), - dram_addr_map_col: DramAddrMapColumn::builder() - .with_addrmap_col_b11(u4::new(0xf)) - .with_addrmap_col_b10(u4::new(0xf)) - .with_addrmap_col_b9(u4::new(0xf)) - .with_addrmap_col_b8(u4::new(0x0)) - .with_addrmap_col_b7(u4::new(0x0)) - .with_addrmap_col_b4(u4::new(0x0)) - .with_addrmap_col_b3(u4::new(0x0)) - .with_addrmap_col_b2(u4::new(0x0)) - .build(), - dram_addr_map_row: DramAddrMapRow::builder() - .with_addrmap_row_b15(u4::new(0xf)) - .with_addrmap_row_b14(u4::new(0xf)) - .with_addrmap_row_b13(u4::new(0x6)) - .with_addrmap_row_b12(u4::new(0x6)) - .with_addrmap_row_b2_11(u4::new(0x6)) - .with_addrmap_row_b1(u4::new(0x6)) - .with_addrmap_row_b0(u4::new(0x4)) - .build(), - dram_odt: DramOdt::builder() - .with_phy_idle_local_odt(u2::new(0x0)) - .with_phy_write_local_odt(u2::new(0x3)) - .with_phy_read_local_odt(u2::new(0x0)) - .with_rank0_wr_odt(u3::new(0x1)) - .with_rank0_rd_odt(u3::new(0x0)) - .build(), - phy_cmd_timeout_rddata_cpt: PhyCmdTimeoutRdDataCpt::builder() - .with_wrlvl_num_of_dq0(u4::new(0x7)) - .with_gatelvl_num_of_dq0(u4::new(0x7)) - .with_clk_stall_level(false) - .with_dis_phy_ctrl_rstn(false) - .with_rdc_fifo_rst_err_cnt_clr(false) - .with_use_fixed_re(true) - .with_rdc_we_to_re_delay(u4::new(0x8)) - .with_wr_cmd_to_data(u4::new(0x0)) - .with_rd_cmd_to_data(u4::new(0x0)) - .build(), - dll_calib: DllCalib::builder().with_sel(DllCalibSel::Periodic).build(), - odt_delay_hold: OdtDelayHold::builder() - .with_wr_odt_hold(u4::new(0x5)) - .with_rd_odt_hold(u4::new(0x0)) - .with_wr_odt_delay(u4::new(0x0)) - .with_rd_odt_delay(u4::new(0x3)) - .build(), - ctrl_reg1: CtrlReg1::builder() - .with_selfref_enable(false) - .with_dis_collision_page_opt(false) - .with_dis_wc(false) - .with_refresh_update_level(false) - .with_auto_pre_en(false) - .with_lpr_num_entries(u6::new(0x1f)) - .with_pageclose(false) - .build(), - ctrl_reg2: CtrlReg2::builder() - .with_go_2_critcal_enable(true) - .with_go_2_critical_hysteresis(0x0) - .build(), - ctrl_reg3: CtrlReg3::builder() - .with_dfi_t_wlmrd(u10::new(0x28)) - .with_rdlvl_rr(0x41) - .with_wrlvl_ww(0x41) - .build(), - ctrl_reg4: CtrlReg4::builder() - .with_dfi_t_ctrlupd_interval_max_x1024(0x16) - .with_dfi_t_ctrlupd_interval_min_x1024(0x10) - .build(), - ctrl_reg5: CtrlReg5::builder() - .with_t_ckesr(u6::new(0x4)) - .with_t_cksrx(u4::new(0x6)) - .with_t_ckrse(u4::new(0x6)) - .with_dfi_t_dram_clk_enable(u4::new(0x1)) - .with_dfi_t_dram_clk_disable(u4::new(0x1)) - .with_dfi_t_ctrl_delay(u4::new(0x1)) - .build(), - ctrl_reg6: CtrlReg6::builder() - .with_t_cksx(u4::new(0x3)) - .with_t_ckdpdx(u4::new(0x2)) - .with_t_ckdpde(u4::new(0x2)) - .with_t_ckpdx(u4::new(0x2)) - .with_t_ckpde(u4::new(0x2)) - .build(), - che_t_zq: CheTZq::builder() - .with_t_zq_short_nop(u10::new(0x40)) - .with_t_zq_long_nop(u10::new(0x200)) - .with_t_mode(u10::new(0x200)) - .with_ddr3(true) - .with_dis_auto_zq(false) - .build(), - che_t_zq_short_interval_reg: CheTZqShortInterval::builder() - .with_dram_rstn_x1024(0x69) - .with_t_zq_short_interval(u20::new(0xcb73)) - .build(), - deep_powerdown: DeepPowerdown::builder() - .with_deep_powerdown_to_x1024(0xff) - .with_enable(false) - .build(), - reg_2c: Reg2c::builder() - .with_dfi_rd_data_eye_train(true) - .with_dfi_rd_dqs_gate_level(true) - .with_dfi_wr_level_enable(true) - .with_trdlvl_max_error(false) - .with_twrlvl_max_error(false) - .with_dfi_rdlvl_max_x1024(u12::new(0xfff)) - .with_dfi_wrlvl_max_x1024(u12::new(0xfff)) - .build(), - reg_2d: Reg2d::builder().with_skip_ocd(true).build(), - dfi_timing: DfiTiming::builder() - .with_dfi_t_ctrlup_max(u10::new(0x40)) - .with_dfi_t_ctrlup_min(u10::new(0x3)) - .with_dfi_t_rddata_enable(u5::new(0x6)) - .build(), - che_ecc_ctrl: CheEccControl::builder() - .with_clear_correctable_errors(false) - .with_clear_uncorrectable_errors(false) - .build(), - ecc_scrub: EccScrub::builder() - .with_disable_scrub(true) - .with_ecc_mode(EccMode::NoEcc) - .build(), - phy_receiver_enable: PhyReceiverEnable::builder() - .with_phy_dif_off(u4::new(0)) - .with_phy_dif_on(u4::new(0)) - .build(), - phy_config: [PhyConfig::builder() - .with_dq_offset(u7::new(0x40)) - .with_wrlvl_inc_mode(false) - .with_gatelvl_inc_mode(false) - .with_rdlvl_inc_mode(false) - .with_data_slice_in_use(true) - .build(); 4], - phy_init_ratio: [ - PhyInitRatio::builder() - .with_gatelvl_init_ratio(u10::new(0xcf)) - .with_wrlvl_init_ratio(u10::new(0x3)) - .build(), - PhyInitRatio::builder() - .with_gatelvl_init_ratio(u10::new(0xd0)) - .with_wrlvl_init_ratio(u10::new(0x3)) - .build(), - PhyInitRatio::builder() - .with_gatelvl_init_ratio(u10::new(0xbd)) - .with_wrlvl_init_ratio(u10::new(0x0)) - .build(), - PhyInitRatio::builder() - .with_gatelvl_init_ratio(u10::new(0xc1)) - .with_wrlvl_init_ratio(u10::new(0x0)) - .build(), - ], - phy_rd_dqs_config: [ - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x35)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x35)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x35)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x35)) - .build(), - ], - phy_wr_dqs_config: [ - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x83)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x83)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x7f)) - .build(), - PhyDqsConfig::builder() - .with_dqs_slave_delay(u9::new(0x0)) - .with_dqs_slave_force(false) - .with_dqs_slave_ratio(u10::new(0x78)) - .build(), - ], - phy_we_cfg: [ - PhyWriteEnableConfig::builder() - .with_fifo_we_in_delay(u9::new(0x0)) - .with_fifo_we_in_force(false) - .with_fifo_we_slave_ratio(u11::new(0x124)) - .build(), - PhyWriteEnableConfig::builder() - .with_fifo_we_in_delay(u9::new(0x0)) - .with_fifo_we_in_force(false) - .with_fifo_we_slave_ratio(u11::new(0x125)) - .build(), - PhyWriteEnableConfig::builder() - .with_fifo_we_in_delay(u9::new(0x0)) - .with_fifo_we_in_force(false) - .with_fifo_we_slave_ratio(u11::new(0x112)) - .build(), - PhyWriteEnableConfig::builder() - .with_fifo_we_in_delay(u9::new(0x0)) - .with_fifo_we_in_force(false) - .with_fifo_we_slave_ratio(u11::new(0x116)) - .build(), - ], - phy_wr_data_slv: [ - PhyWriteDataSlaveConfig::builder() - .with_wr_data_slave_delay(u9::new(0x0)) - .with_wr_data_slave_force(false) - .with_wr_data_slave_ratio(u10::new(0xc3)) - .build(), - PhyWriteDataSlaveConfig::builder() - .with_wr_data_slave_delay(u9::new(0x0)) - .with_wr_data_slave_force(false) - .with_wr_data_slave_ratio(u10::new(0xc3)) - .build(), - PhyWriteDataSlaveConfig::builder() - .with_wr_data_slave_delay(u9::new(0x0)) - .with_wr_data_slave_force(false) - .with_wr_data_slave_ratio(u10::new(0xbf)) - .build(), - PhyWriteDataSlaveConfig::builder() - .with_wr_data_slave_delay(u9::new(0x0)) - .with_wr_data_slave_force(false) - .with_wr_data_slave_ratio(u10::new(0xb8)) - .build(), - ], - reg64: Reg64::builder() - .with_cmd_latency(false) - .with_lpddr(false) - .with_ctrl_slave_delay(u7::new(0x0)) - .with_ctrl_slave_force(false) - .with_ctrl_slave_ratio(u10::new(0x100)) - .with_sel_logic(false) - .with_invert_clkout(true) - .with_bl2(false) - .build(), - reg65: Reg65::builder() - .with_ctrl_slave_delay(u2::new(0x0)) - .with_dis_calib_rst(false) - .with_use_rd_data_eye_level(true) - .with_use_rd_dqs_gate_level(true) - .with_use_wr_level(true) - .with_dll_lock_diff(u4::new(0xf)) - .with_rd_rl_delay(u5::new(0x4)) - .with_wr_rl_delay(u5::new(0x2)) - .build(), - page_mask: 0x0, - axi_priority_wr_port: [ - AxiPriorityWritePort::builder() - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_wr_port(u10::new(0x3ff)) - .build(), - AxiPriorityWritePort::builder() - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_wr_port(u10::new(0x3ff)) - .build(), - AxiPriorityWritePort::builder() - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_wr_port(u10::new(0x3ff)) - .build(), - AxiPriorityWritePort::builder() - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_wr_port(u10::new(0x3ff)) - .build(), - ], - axi_priority_rd_port: [ - AxiPriorityReadPort::builder() - .with_enable_hpr(false) - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_rd_port_n(u10::new(0x3ff)) - .build(), - AxiPriorityReadPort::builder() - .with_enable_hpr(false) - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_rd_port_n(u10::new(0x3ff)) - .build(), - AxiPriorityReadPort::builder() - .with_enable_hpr(false) - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_rd_port_n(u10::new(0x3ff)) - .build(), - AxiPriorityReadPort::builder() - .with_enable_hpr(false) - .with_disable_page_match(false) - .with_disable_urgent(false) - .with_disable_aging(false) - .with_pri_rd_port_n(u10::new(0x3ff)) - .build(), - ], - lpddr_ctrl_0: LpddrControl0::builder() - .with_mr4_margin(0x0) - .with_derate_enable(false) - .with_per_bank_refresh(false) - .with_lpddr2(LpddrBit::Ddr2Ddr3) - .build(), - lpddr_ctrl_1: LpddrControl1::builder().with_mr4_read_interval(0x0).build(), - lpddr_ctrl_2: LpddrControl2::builder() - .with_t_mrw(u10::new(0x5)) - .with_idle_after_reset_x32(0x12) - .with_min_stable_clock_x1(u4::new(0x5)) - .build(), - lpddr_ctrl_3: LpddrControl3::builder() - .with_dev_zqinit_x32(u10::new(0x12)) - .with_max_auto_init_x1024(0xa8) - .build(), -}; diff --git a/zynq-mmu/Cargo.toml b/zynq-mmu/Cargo.toml deleted file mode 100644 index 7bf07b0..0000000 --- a/zynq-mmu/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "zynq-mmu" -description = "Zynq MMU structures" -version = "0.1.0" -edition = "2024" - -[dependencies] -thiserror = { version = "2", default-features = false } -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", branch = "bump-arbitrary-int" } - -[features] -tools = [] diff --git a/zynq/.cargo/config.toml b/zynq/.cargo/config.toml new file mode 100644 index 0000000..2a4d3aa --- /dev/null +++ b/zynq/.cargo/config.toml @@ -0,0 +1,20 @@ +[target.armv7a-none-eabihf] +runner = "just run" + +rustflags = [ + "-Ctarget-cpu=cortex-a9", + "-Ctarget-feature=+vfp3", + "-Ctarget-feature=+neon", + "-Clink-arg=-Tlink.x", + # If this is not enabled, debugging / stepping can become problematic. + "-Cforce-frame-pointers=yes", + # Can be useful for debugging. + # "-Clink-args=-Map=app.map" +] + +# Tier 3 target, so no pre-compiled artifacts included. +[unstable] +build-std = ["core", "alloc"] + +[build] +target = "armv7a-none-eabihf" diff --git a/zynq/.gitignore b/zynq/.gitignore new file mode 100644 index 0000000..03314f7 --- /dev/null +++ b/zynq/.gitignore @@ -0,0 +1 @@ +Cargo.lock diff --git a/zynq/Cargo.toml b/zynq/Cargo.toml new file mode 100644 index 0000000..9101e86 --- /dev/null +++ b/zynq/Cargo.toml @@ -0,0 +1,21 @@ +[workspace] +resolver = "3" +members = [ + "zynq7000-rt", + "zynq7000-mmu", + "zynq7000", + "zynq7000-hal", + "zynq7000-embassy", + + "examples/simple", + "examples/embassy", + "examples/zedboard", + + "zedboard-bsp", + "zedboard-qspi-flasher", +] + +exclude = [ + # Exclude, can not be built with debug optimization level, too large. + "zedboard-fsbl", +] diff --git a/examples/embassy/Cargo.toml b/zynq/examples/embassy/Cargo.toml similarity index 62% rename from examples/embassy/Cargo.toml rename to zynq/examples/embassy/Cargo.toml index c17151b..f32f638 100644 --- a/examples/embassy/Cargo.toml +++ b/zynq/examples/embassy/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] categories = ["embedded", "no-std", "hardware-support"] [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", rev = "79dba7000d2090d13823bfb783d9d64be8b778d2", features = ["critical-section-single-core"] } +cortex-ar = { version = "0.3", features = ["critical-section-single-core"] } zynq7000-rt = { path = "../../zynq7000-rt" } zynq7000 = { path = "../../zynq7000" } zynq7000-hal = { path = "../../zynq7000-hal" } @@ -20,19 +20,35 @@ dht-sensor = { git = "https://github.com/michaelbeaumont/dht-sensor.git", rev = static_cell = "2" critical-section = "1" heapless = "0.9" -embedded-io = "0.6" +embedded-io = "0.7" embedded-hal = "1" fugit = "0.3" log = "0.4" -embassy-executor = { git = "https://github.com/us-irs/embassy.git", branch = "cortex-ar-update", features = [ +embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", features = [ "arch-cortex-ar", "executor-thread", ]} # TODO: Remove generic-queue-16 feature as soon as upstream executor is used again. embassy-time = { version = "0.5", features = ["tick-hz-1_000_000", "generic-queue-16"] } -[profile.release] +# cargo build/run +[profile.dev] +# default is opt-level = '0', but that makes very +# verbose machine code +opt-level = 's' +# trade compile speed for slightly better optimisations codegen-units = 1 -debug = true -lto = true + +# cargo build/run --release +[profile.release] +# default is opt-level = '3', but that makes quite +# verbose machine code +opt-level = 's' +# trade compile speed for slightly better optimisations +codegen-units = 1 +# Use Link Time Optimisations to further inline things across +# crates +lto = 'fat' +# Leave the debug symbols in (default is no debug info) +debug = 2 diff --git a/examples/embassy/build.rs b/zynq/examples/embassy/build.rs similarity index 100% rename from examples/embassy/build.rs rename to zynq/examples/embassy/build.rs diff --git a/examples/embassy/memory.x b/zynq/examples/embassy/memory.x similarity index 100% rename from examples/embassy/memory.x rename to zynq/examples/embassy/memory.x diff --git a/examples/embassy/src/bin/dht22-open-drain-pins.rs b/zynq/examples/embassy/src/bin/dht22-open-drain-pins.rs similarity index 100% rename from examples/embassy/src/bin/dht22-open-drain-pins.rs rename to zynq/examples/embassy/src/bin/dht22-open-drain-pins.rs diff --git a/examples/embassy/src/bin/logger-non-blocking.rs b/zynq/examples/embassy/src/bin/logger-non-blocking.rs similarity index 99% rename from examples/embassy/src/bin/logger-non-blocking.rs rename to zynq/examples/embassy/src/bin/logger-non-blocking.rs index 3c09354..1fd3eac 100644 --- a/examples/embassy/src/bin/logger-non-blocking.rs +++ b/zynq/examples/embassy/src/bin/logger-non-blocking.rs @@ -79,7 +79,7 @@ async fn main(spawner: Spawner) -> ! { info!("Boot mode: {:?}", boot_mode); let led = Output::new_for_mio(mio_pins.mio7, PinState::Low); - spawner.spawn(led_task(led)).unwrap(); + spawner.spawn(led_task(led).unwrap()); let mut log_buf: [u8; 2048] = [0; 2048]; let frame_queue = zynq7000_hal::log::rb::get_frame_queue(); loop { diff --git a/examples/embassy/src/bin/pwm.rs b/zynq/examples/embassy/src/bin/pwm.rs similarity index 100% rename from examples/embassy/src/bin/pwm.rs rename to zynq/examples/embassy/src/bin/pwm.rs diff --git a/examples/embassy/src/main.rs b/zynq/examples/embassy/src/main.rs similarity index 97% rename from examples/embassy/src/main.rs rename to zynq/examples/embassy/src/main.rs index afbdfe4..1047373 100644 --- a/examples/embassy/src/main.rs +++ b/zynq/examples/embassy/src/main.rs @@ -8,7 +8,7 @@ use embassy_time::{Duration, Ticker}; use embedded_hal::digital::StatefulOutputPin; use embedded_io::Write; use log::{error, info}; -use zynq7000_hal::{clocks, gic, gpio, gtc, time::Hertz, uart, BootMode, InteruptConfig}; +use zynq7000_hal::{BootMode, InteruptConfig, clocks, gic, gpio, gtc, time::Hertz, uart}; use zynq7000_rt as _; diff --git a/examples/simple/Cargo.toml b/zynq/examples/simple/Cargo.toml similarity index 74% rename from examples/simple/Cargo.toml rename to zynq/examples/simple/Cargo.toml index 64354b6..fdec76d 100644 --- a/examples/simple/Cargo.toml +++ b/zynq/examples/simple/Cargo.toml @@ -9,11 +9,11 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" license = "MIT OR Apache-2.0" [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", rev = "79dba7000d2090d13823bfb783d9d64be8b778d2", features = ["critical-section-single-core"] } +cortex-ar = "0.3" zynq7000-rt = { path = "../../zynq7000-rt" } zynq7000 = { path = "../../zynq7000" } zynq7000-hal = { path = "../../zynq7000-hal" } -embedded-io = "0.6" +embedded-io = "0.7" embedded-hal = "1" fugit = "0.3" log = "0.4" diff --git a/examples/simple/build.rs b/zynq/examples/simple/build.rs similarity index 100% rename from examples/simple/build.rs rename to zynq/examples/simple/build.rs diff --git a/examples/simple/memory.x b/zynq/examples/simple/memory.x similarity index 100% rename from examples/simple/memory.x rename to zynq/examples/simple/memory.x diff --git a/examples/simple/src/bin/gtc-ticks.rs b/zynq/examples/simple/src/bin/gtc-ticks.rs similarity index 100% rename from examples/simple/src/bin/gtc-ticks.rs rename to zynq/examples/simple/src/bin/gtc-ticks.rs diff --git a/examples/simple/src/bin/logger.rs b/zynq/examples/simple/src/bin/logger.rs similarity index 100% rename from examples/simple/src/bin/logger.rs rename to zynq/examples/simple/src/bin/logger.rs diff --git a/examples/simple/src/main.rs b/zynq/examples/simple/src/main.rs similarity index 100% rename from examples/simple/src/main.rs rename to zynq/examples/simple/src/main.rs diff --git a/examples/zedboard/Cargo.toml b/zynq/examples/zedboard/Cargo.toml similarity index 90% rename from examples/zedboard/Cargo.toml rename to zynq/examples/zedboard/Cargo.toml index 279562c..34cd460 100644 --- a/examples/zedboard/Cargo.toml +++ b/zynq/examples/zedboard/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] categories = ["embedded", "no-std", "hardware-support"] [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", rev = "79dba7000d2090d13823bfb783d9d64be8b778d2", features = ["critical-section-single-core"] } +cortex-ar = "0.3" zynq7000-rt = { path = "../../zynq7000-rt" } zynq7000 = { path = "../../zynq7000" } zynq7000-hal = { path = "../../zynq7000-hal" } @@ -19,7 +19,7 @@ zynq7000-embassy = { path = "../../zynq7000-embassy" } zedboard-bsp = { path = "../../zedboard-bsp" } num_enum = { version = "0.7", default-features = false } l3gd20 = { git = "https://github.com/us-irs/l3gd20.git", branch = "add-async-if" } -embedded-io = "0.6" +embedded-io = "0.7" bitbybit = "1.4" arbitrary-int = "2" embedded-io-async = "0.6" diff --git a/examples/zedboard/build.rs b/zynq/examples/zedboard/build.rs similarity index 100% rename from examples/zedboard/build.rs rename to zynq/examples/zedboard/build.rs diff --git a/examples/zedboard/memory.x b/zynq/examples/zedboard/memory.x similarity index 100% rename from examples/zedboard/memory.x rename to zynq/examples/zedboard/memory.x diff --git a/examples/zedboard/src/bin/ethernet.rs b/zynq/examples/zedboard/src/bin/ethernet.rs similarity index 100% rename from examples/zedboard/src/bin/ethernet.rs rename to zynq/examples/zedboard/src/bin/ethernet.rs diff --git a/examples/zedboard/src/bin/l3gd20h-i2c-mio.rs b/zynq/examples/zedboard/src/bin/l3gd20h-i2c-mio.rs similarity index 100% rename from examples/zedboard/src/bin/l3gd20h-i2c-mio.rs rename to zynq/examples/zedboard/src/bin/l3gd20h-i2c-mio.rs diff --git a/examples/zedboard/src/bin/l3gd20h-spi-mio.rs b/zynq/examples/zedboard/src/bin/l3gd20h-spi-mio.rs similarity index 100% rename from examples/zedboard/src/bin/l3gd20h-spi-mio.rs rename to zynq/examples/zedboard/src/bin/l3gd20h-spi-mio.rs diff --git a/examples/zedboard/src/bin/qspi.rs b/zynq/examples/zedboard/src/bin/qspi.rs similarity index 98% rename from examples/zedboard/src/bin/qspi.rs rename to zynq/examples/zedboard/src/bin/qspi.rs index 7c1e30f..89fd2e8 100644 --- a/examples/zedboard/src/bin/qspi.rs +++ b/zynq/examples/zedboard/src/bin/qspi.rs @@ -10,7 +10,7 @@ use embedded_io::Write; use log::{error, info}; use zedboard::PS_CLOCK_FREQUENCY; use zedboard_bsp::qspi_spansion; -use zynq7000_hal::{clocks, gic, gpio, gtc, prelude::*, qspi, uart, BootMode}; +use zynq7000_hal::{BootMode, clocks, gic, gpio, gtc, prelude::*, qspi, uart}; use zynq7000_rt as _; diff --git a/examples/zedboard/src/bin/uart-blocking.rs b/zynq/examples/zedboard/src/bin/uart-blocking.rs similarity index 100% rename from examples/zedboard/src/bin/uart-blocking.rs rename to zynq/examples/zedboard/src/bin/uart-blocking.rs diff --git a/examples/zedboard/src/bin/uart-non-blocking.rs b/zynq/examples/zedboard/src/bin/uart-non-blocking.rs similarity index 100% rename from examples/zedboard/src/bin/uart-non-blocking.rs rename to zynq/examples/zedboard/src/bin/uart-non-blocking.rs diff --git a/examples/zedboard/src/lib.rs b/zynq/examples/zedboard/src/lib.rs similarity index 100% rename from examples/zedboard/src/lib.rs rename to zynq/examples/zedboard/src/lib.rs diff --git a/examples/zedboard/src/main.rs b/zynq/examples/zedboard/src/main.rs similarity index 98% rename from examples/zedboard/src/main.rs rename to zynq/examples/zedboard/src/main.rs index b08c435..59c4962 100644 --- a/examples/zedboard/src/main.rs +++ b/zynq/examples/zedboard/src/main.rs @@ -9,7 +9,7 @@ use embedded_hal::digital::StatefulOutputPin; use embedded_io::Write; use log::{error, info}; use zedboard::PS_CLOCK_FREQUENCY; -use zynq7000_hal::{clocks, gic, gpio, gtc, uart, BootMode}; +use zynq7000_hal::{BootMode, clocks, gic, gpio, gtc, uart}; use zynq7000_rt as _; diff --git a/gdb.gdb b/zynq/gdb.gdb similarity index 100% rename from gdb.gdb rename to zynq/gdb.gdb diff --git a/rust-toolchain.toml b/zynq/rust-toolchain.toml similarity index 60% rename from rust-toolchain.toml rename to zynq/rust-toolchain.toml index 0e3c7a9..5d56faf 100644 --- a/rust-toolchain.toml +++ b/zynq/rust-toolchain.toml @@ -1,3 +1,2 @@ [toolchain] -# channel = "stable" channel = "nightly" diff --git a/zedboard-bsp/Cargo.toml b/zynq/zedboard-bsp/Cargo.toml similarity index 88% rename from zedboard-bsp/Cargo.toml rename to zynq/zedboard-bsp/Cargo.toml index f8fa030..249959f 100644 --- a/zedboard-bsp/Cargo.toml +++ b/zynq/zedboard-bsp/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] +zynq7000 = { path = "../zynq7000" } zynq7000-hal = { path = "../zynq7000-hal" } bitbybit = "1.4" arbitrary-int = "2" diff --git a/zynq/zedboard-bsp/src/ddrc_config_autogen.rs b/zynq/zedboard-bsp/src/ddrc_config_autogen.rs new file mode 100644 index 0000000..e1edb93 --- /dev/null +++ b/zynq/zedboard-bsp/src/ddrc_config_autogen.rs @@ -0,0 +1,101 @@ +#![doc = r"This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program."] +#![doc = r""] +#![doc = r"This configuration file contains static DDR configuration parameters extracted from the"] +#![doc = r"AMD ps7init.tcl file"] +use zynq7000::ddrc::regs; +use zynq7000_hal::ddr::DdrcConfigSet; +pub const DDRC_CONFIG_ZEDBOARD: DdrcConfigSet = DdrcConfigSet { + ctrl: regs::DdrcControl::new_with_raw_value(0x00000080), + two_rank: regs::TwoRankConfig::new_with_raw_value(0x00001082), + hpr: regs::LprHprQueueControl::new_with_raw_value(0x03c0780f), + lpr: regs::LprHprQueueControl::new_with_raw_value(0x02001001), + wr: regs::WriteQueueControl::new_with_raw_value(0x00014001), + dram_param_0: regs::DramParamReg0::new_with_raw_value(0x0004159b), + dram_param_1: regs::DramParamReg1::new_with_raw_value(0x44e458d3), + dram_param_2: regs::DramParamReg2::new_with_raw_value(0x7282bce5), + dram_param_3: regs::DramParamReg3::new_with_raw_value(0x270872d0), + dram_param_4: regs::DramParamReg4::new_with_raw_value(0x00000000), + dram_init_param: regs::DramInitParam::new_with_raw_value(0x00002007), + dram_emr: regs::DramEmr::new_with_raw_value(0x00000008), + dram_emr_mr: regs::DramEmrMr::new_with_raw_value(0x00040b30), + dram_burst8_rdwr: regs::DramBurst8ReadWrite::new_with_raw_value(0x000116d4), + disable_dq: regs::DisableDq::new_with_raw_value(0x00000000), + dram_addr_map_bank: regs::DramAddrMapBank::new_with_raw_value(0x00000777), + dram_addr_map_col: regs::DramAddrMapColumn::new_with_raw_value(0xfff00000), + dram_addr_map_row: regs::DramAddrMapRow::new_with_raw_value(0x0ff66666), + dram_odt: regs::DramOdt::new_with_raw_value(0x0003c008), + phy_cmd_timeout_rddata_cpt: regs::PhyCmdTimeoutRdDataCpt::new_with_raw_value(0x77010800), + dll_calib: regs::DllCalib::new_with_raw_value(0x00000000), + odt_delay_hold: regs::OdtDelayHold::new_with_raw_value(0x00005003), + ctrl_reg1: regs::CtrlReg1::new_with_raw_value(0x0000003e), + ctrl_reg2: regs::CtrlReg2::new_with_raw_value(0x00020000), + ctrl_reg3: regs::CtrlReg3::new_with_raw_value(0x00284141), + ctrl_reg4: regs::CtrlReg4::new_with_raw_value(0x00001610), + ctrl_reg5: regs::CtrlReg5::new_with_raw_value(0x00466111), + ctrl_reg6: regs::CtrlReg6::new_with_raw_value(0x00032222), + che_t_zq: regs::CheTZq::new_with_raw_value(0x10200802), + che_t_zq_short_interval_reg: regs::CheTZqShortInterval::new_with_raw_value(0x10200802), + deep_powerdown: regs::DeepPowerdown::new_with_raw_value(0x000001fe), + reg_2c: regs::Reg2c::new_with_raw_value(0x1cffffff), + reg_2d: regs::Reg2d::new_with_raw_value(0x00000200), + dfi_timing: regs::DfiTiming::new_with_raw_value(0x00200066), + che_ecc_ctrl: regs::CheEccControl::new_with_raw_value(0x00000000), + ecc_scrub: regs::EccScrub::new_with_raw_value(0x00000008), + phy_receiver_enable: regs::PhyReceiverEnable::new_with_raw_value(0x00000000), + phy_config: [ + regs::PhyConfig::new_with_raw_value(0x40000001), + regs::PhyConfig::new_with_raw_value(0x40000001), + regs::PhyConfig::new_with_raw_value(0x40000001), + regs::PhyConfig::new_with_raw_value(0x40000001), + ], + phy_init_ratio: [ + regs::PhyInitRatio::new_with_raw_value(0x00033c03), + regs::PhyInitRatio::new_with_raw_value(0x00034003), + regs::PhyInitRatio::new_with_raw_value(0x0002f400), + regs::PhyInitRatio::new_with_raw_value(0x00030400), + ], + phy_rd_dqs_config: [ + regs::PhyDqsConfig::new_with_raw_value(0x00000035), + regs::PhyDqsConfig::new_with_raw_value(0x00000035), + regs::PhyDqsConfig::new_with_raw_value(0x00000035), + regs::PhyDqsConfig::new_with_raw_value(0x00000035), + ], + phy_wr_dqs_config: [ + regs::PhyDqsConfig::new_with_raw_value(0x00000083), + regs::PhyDqsConfig::new_with_raw_value(0x00000083), + regs::PhyDqsConfig::new_with_raw_value(0x0000007f), + regs::PhyDqsConfig::new_with_raw_value(0x00000078), + ], + phy_we_cfg: [ + regs::PhyWriteEnableConfig::new_with_raw_value(0x00000124), + regs::PhyWriteEnableConfig::new_with_raw_value(0x00000125), + regs::PhyWriteEnableConfig::new_with_raw_value(0x00000112), + regs::PhyWriteEnableConfig::new_with_raw_value(0x00000116), + ], + phy_wr_data_slv: [ + regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000c3), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000c3), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000bf), + regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000b8), + ], + reg64: regs::Reg64::new_with_raw_value(0x00040080), + reg65: regs::Reg65::new_with_raw_value(0x0001fc82), + page_mask: 0x00000000, + axi_priority_wr_port: [ + regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff), + regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff), + regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff), + regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff), + ], + axi_priority_rd_port: [ + regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff), + regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff), + regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff), + regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff), + ], + lpddr_ctrl_0: regs::LpddrControl0::new_with_raw_value(0x00000000), + lpddr_ctrl_1: regs::LpddrControl1::new_with_raw_value(0x00000000), + lpddr_ctrl_2: regs::LpddrControl2::new_with_raw_value(0x00005125), + lpddr_ctrl_3: regs::LpddrControl3::new_with_raw_value(0x000012a8), +}; + diff --git a/zynq/zedboard-bsp/src/ddriob_config_autogen.rs b/zynq/zedboard-bsp/src/ddriob_config_autogen.rs new file mode 100644 index 0000000..74f1ea1 --- /dev/null +++ b/zynq/zedboard-bsp/src/ddriob_config_autogen.rs @@ -0,0 +1,16 @@ +#![doc = r"This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program."] +#![doc = r""] +#![doc = r"This configuration file contains static DDRIOB configuration parameters extracted from the"] +#![doc = r"AMD ps7init.tcl file"] +use zynq7000::ddrc::regs; +use zynq7000_hal::ddr::DdriobConfigSet; +pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet { + addr0: regs::DdriobConfig::new_with_raw_value(0x00000600), + addr1: regs::DdriobConfig::new_with_raw_value(0x00000600), + data0: regs::DdriobConfig::new_with_raw_value(0x00000672), + data1: regs::DdriobConfig::new_with_raw_value(0x00000672), + diff0: regs::DdriobConfig::new_with_raw_value(0x00000674), + diff1: regs::DdriobConfig::new_with_raw_value(0x00000674), + clock: regs::DdriobConfig::new_with_raw_value(0x00000600), +}; + diff --git a/zynq/zedboard-bsp/src/lib.rs b/zynq/zedboard-bsp/src/lib.rs new file mode 100644 index 0000000..1b4cd7d --- /dev/null +++ b/zynq/zedboard-bsp/src/lib.rs @@ -0,0 +1,6 @@ +#![no_std] + +pub mod ddrc_config_autogen; +pub mod ddriob_config_autogen; +pub mod phy_marvell; +pub mod qspi_spansion; diff --git a/zedboard-bsp/src/phy_marvell.rs b/zynq/zedboard-bsp/src/phy_marvell.rs similarity index 100% rename from zedboard-bsp/src/phy_marvell.rs rename to zynq/zedboard-bsp/src/phy_marvell.rs diff --git a/zedboard-bsp/src/qspi_spansion.rs b/zynq/zedboard-bsp/src/qspi_spansion.rs similarity index 91% rename from zedboard-bsp/src/qspi_spansion.rs rename to zynq/zedboard-bsp/src/qspi_spansion.rs index 31258d6..9eafd3b 100644 --- a/zedboard-bsp/src/qspi_spansion.rs +++ b/zynq/zedboard-bsp/src/qspi_spansion.rs @@ -64,6 +64,8 @@ pub enum SectorArchictecture { Hybrid = 0x01, } +pub const PAGE_SIZE: usize = 256; + #[derive(Debug, Clone, Copy)] pub struct BaseDeviceId { manufacturer_id: u8, @@ -221,6 +223,8 @@ pub enum ProgramPageError { ProgrammingErrorBitSet, #[error("address error: {0}")] Addr(#[from] AddrError), + #[error("data is larger than page size {PAGE_SIZE}")] + DataLargerThanPage, } pub struct QspiSpansionS25Fl256SIoMode(RefCell); @@ -428,14 +432,17 @@ impl QspiSpansionS25Fl256SIoMode { /// This function also takes care of enabling writes before programming the page. /// This function will block until the operation has completed. /// - /// TODO: Allow smaller write size - pub fn program_page(&mut self, addr: u32, data: &[u8; 256]) -> Result<(), ProgramPageError> { + /// The data length max not exceed the page size [PAGE_SIZE]. + pub fn program_page(&mut self, addr: u32, data: &[u8]) -> Result<(), ProgramPageError> { if addr + data.len() as u32 > u24::MAX.as_u32() { return Err(AddrError::OutOfRange.into()); } if !addr.is_multiple_of(0x100) { return Err(AddrError::Alignment.into()); } + if data.len() > PAGE_SIZE { + return Err(ProgramPageError::DataLargerThanPage); + } self.write_enable(); let qspi = self.0.get_mut(); let mut transfer = qspi.transfer_guard(); @@ -448,8 +455,9 @@ impl QspiSpansionS25Fl256SIoMode { transfer.write_word_txd_00(u32::from_ne_bytes(raw_word)); let mut read_index: u32 = 0; let mut current_byte_index = 0; + let fifo_writes = data.len().div_ceil(4); // Fill the FIFO until it is full. - for _ in 0..FIFO_DEPTH - 1 { + for _ in 0..core::cmp::min(fifo_writes, FIFO_DEPTH - 1) { transfer.write_word_txd_00(u32::from_ne_bytes( data[current_byte_index..current_byte_index + 4] .try_into() @@ -470,25 +478,38 @@ impl QspiSpansionS25Fl256SIoMode { } }; - // Immediately fill the FIFO again with the remaining 8 bytes. - wait_for_tx_slot(&mut transfer); + while current_byte_index < data.len() { + // Immediately fill the FIFO again with the remaining 8 bytes. + wait_for_tx_slot(&mut transfer); - transfer.write_word_txd_00(u32::from_ne_bytes( - data[current_byte_index..current_byte_index + 4] - .try_into() - .unwrap(), - )); - current_byte_index += 4; + let word = match core::cmp::min(4, data.len() - current_byte_index) { + 1 => { + let mut bytes = [0; 4]; + bytes[0] = data[current_byte_index]; + u32::from_ne_bytes(bytes) + } + 2 => { + let mut bytes = [0; 4]; + bytes[0..2].copy_from_slice(&data[current_byte_index..current_byte_index + 2]); + u32::from_ne_bytes(bytes) + } + 3 => { + let mut bytes = [0; 4]; + bytes[0..3].copy_from_slice(&data[current_byte_index..current_byte_index + 3]); + u32::from_ne_bytes(bytes) + } + 4 => u32::from_ne_bytes( + data[current_byte_index..current_byte_index + 4] + .try_into() + .unwrap(), + ), + _ => unreachable!(), + }; + transfer.write_word_txd_00(word); + current_byte_index += 4; + } - wait_for_tx_slot(&mut transfer); - - transfer.write_word_txd_00(u32::from_ne_bytes( - data[current_byte_index..current_byte_index + 4] - .try_into() - .unwrap(), - )); - - while read_index < 256 { + while read_index < data.len() as u32 { if transfer.read_status().rx_above_threshold() { transfer.read_rx_data(); read_index = read_index.wrapping_add(4); @@ -528,11 +549,7 @@ impl QspiSpansionS25Fl256SIoMode { if dummy_byte { bytes_to_write += 1; } - let fifo_writes = if bytes_to_write.is_multiple_of(4) { - bytes_to_write / 4 - } else { - (bytes_to_write / 4) + 1 - }; + let fifo_writes = bytes_to_write.div_ceil(4); // Fill the FIFO until it is full or all 0 bytes have been written. for _ in 0..core::cmp::min(fifo_writes, FIFO_DEPTH - 1) { transfer.write_word_txd_00(0); diff --git a/zedboard-fsbl/Cargo.toml b/zynq/zedboard-fsbl/Cargo.toml similarity index 70% rename from zedboard-fsbl/Cargo.toml rename to zynq/zedboard-fsbl/Cargo.toml index 00a44e2..6065e88 100644 --- a/zedboard-fsbl/Cargo.toml +++ b/zynq/zedboard-fsbl/Cargo.toml @@ -9,13 +9,13 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" license = "MIT OR Apache-2.0" [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", rev = "79dba7000d2090d13823bfb783d9d64be8b778d2", features = ["critical-section-single-core"] } +cortex-ar = { version = "0.3", features = ["critical-section-single-core"] } zynq7000-rt = { path = "../zynq7000-rt" } zynq7000 = { path = "../zynq7000" } zynq7000-hal = { path = "../zynq7000-hal" } +zynq7000-boot-image = { path = "../../zynq7000-boot-image" } zedboard-bsp = { path = "../zedboard-bsp" } -zynq-boot-image = { path = "../zynq-boot-image" } -embedded-io = "0.6" +embedded-io = "0.7" embedded-hal = "1" fugit = "0.3" log = "0.4" diff --git a/zedboard-fsbl/build.rs b/zynq/zedboard-fsbl/build.rs similarity index 100% rename from zedboard-fsbl/build.rs rename to zynq/zedboard-fsbl/build.rs diff --git a/zedboard-fsbl/memory.x b/zynq/zedboard-fsbl/memory.x similarity index 100% rename from zedboard-fsbl/memory.x rename to zynq/zedboard-fsbl/memory.x diff --git a/zedboard-fsbl/src/main.rs b/zynq/zedboard-fsbl/src/main.rs similarity index 50% rename from zedboard-fsbl/src/main.rs rename to zynq/zedboard-fsbl/src/main.rs index a7e1d68..fdc252a 100644 --- a/zedboard-fsbl/src/main.rs +++ b/zynq/zedboard-fsbl/src/main.rs @@ -8,7 +8,8 @@ use cortex_ar::asm::nop; use embedded_io::Write as _; use log::{error, info}; use zedboard_bsp::qspi_spansion::{self, QspiSpansionS25Fl256SLinearMode}; -use zynq_boot_image::DestinationDevice; +use zynq7000_boot_image::DestinationDevice; +use zynq7000_hal::priv_tim; use zynq7000_hal::{ BootMode, clocks::{ @@ -16,18 +17,14 @@ use zynq7000_hal::{ pll::{PllConfig, configure_arm_pll, configure_io_pll}, }, ddr::{DdrClockSetupConfig, configure_ddr_for_ddr3, memtest}, - gic, gpio, l2_cache, + devcfg, gic, gpio, l2_cache, prelude::*, - qspi, + qspi::{self, QSPI_START_ADDRESS}, time::Hertz, uart::{ClockConfig, Config, Uart}, }; use zynq7000_rt as _; -use crate::ddr_cfg::{DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS, DDRIOB_CONFIG_SET_ZEDBOARD}; - -pub mod ddr_cfg; - // PS clock input frequency. const PS_CLK: Hertz = Hertz::from_raw(33_333_333); @@ -80,35 +77,37 @@ pub fn main() -> ! { PllConfig::new_from_target_clock(PS_CLK, IO_CLK).unwrap(), ); - let mut dp = zynq7000::Peripherals::take().unwrap(); + let mut periphs = zynq7000::Peripherals::take().unwrap(); // Clock was already initialized by PS7 Init TCL script or FSBL, we just read it. let clocks = Clocks::new_from_regs(PS_CLK).unwrap(); - let gpio_pins = gpio::GpioPins::new(dp.gpio); + let gpio_pins = gpio::GpioPins::new(periphs.gpio); let mio_pins = gpio_pins.mio; // Set up the UART, we are logging with it. let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200) .unwrap() .0; - let mut uart = Uart::new_with_mio( - dp.uart_1, + let mut logger_uart = Uart::new_with_mio( + periphs.uart_1, Config::new_with_clk_config(uart_clk_config), (mio_pins.mio48, mio_pins.mio49), ) .unwrap(); - uart.write_all(b"-- Zedboard Rust FSBL --\n\r").unwrap(); + logger_uart + .write_all(b"-- Zedboard Rust FSBL --\n\r") + .unwrap(); // Safety: We are not multi-threaded yet. unsafe { zynq7000_hal::log::uart_blocking::init_unsafe_single_core( - uart, + logger_uart, log::LevelFilter::Trace, false, ) }; // Set up the global interrupt controller. - let mut gic = gic::GicConfigurator::new_with_init(dp.gicc, dp.gicd); + let mut gic = gic::GicConfigurator::new_with_init(periphs.gicc, periphs.gicd); gic.enable_all_interrupts(); gic.set_all_spi_interrupt_targets_cpu0(); gic.enable(); @@ -117,7 +116,7 @@ pub fn main() -> ! { info!("Configuring DDR.."); configure_ddr_for_ddr3( - dp.ddrc, + periphs.ddrc, boot_mode, DdrClockSetupConfig { ps_clk: PS_CLK, @@ -125,16 +124,18 @@ pub fn main() -> ! { ddr_3x_div: u6::new(2), ddr_2x_div: u6::new(3), }, - &DDRIOB_CONFIG_SET_ZEDBOARD, - &DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS, + &zedboard_bsp::ddriob_config_autogen::DDRIOB_CONFIG_SET_ZEDBOARD, + &zedboard_bsp::ddrc_config_autogen::DDRC_CONFIG_ZEDBOARD, ); info!("DDR init done."); info!("L2 cache init.."); // Set up the L2 cache now that the DDR is in normal operation mode. - l2_cache::init_with_defaults(&mut dp.l2c); + l2_cache::init_with_defaults(&mut periphs.l2c); info!("L2 cache init done."); + let priv_tim = priv_tim::CpuPrivateTimer::take(clocks.arm_clocks()).unwrap(); + if PERFORM_DDR_MEMTEST { let ddr_base_addr = 0x100000; info!("performing DDR memory test.."); @@ -154,7 +155,7 @@ pub fn main() -> ! { ) .expect("QSPI clock calculation failed"); let qspi = qspi::Qspi::new_single_qspi_with_feedback( - dp.qspi, + periphs.qspi, qspi_clock_config, embedded_hal::spi::MODE_0, qspi::IoType::LvCmos33, @@ -168,19 +169,19 @@ pub fn main() -> ! { let spansion_qspi = qspi_spansion::QspiSpansionS25Fl256SIoMode::new(qspi_io_mode, true); let spansion_lqspi = spansion_qspi.into_linear_addressed(qspi_spansion::QSPI_DEV_COMBINATION_REV_F.into()); - qspi_boot(spansion_lqspi); + qspi_boot(spansion_lqspi, priv_tim); } loop { cortex_ar::asm::nop(); } } -fn qspi_boot(mut qspi: QspiSpansionS25Fl256SLinearMode) -> ! { +fn qspi_boot(mut qspi: QspiSpansionS25Fl256SLinearMode, _priv_tim: priv_tim::CpuPrivateTimer) -> ! { let boot_bin_base_addr = ELF_BASE_ADDR + BOOT_BIN_STAGING_OFFSET; let mut boot_header_slice = unsafe { core::slice::from_raw_parts_mut( boot_bin_base_addr as *mut u8, - zynq_boot_image::FIXED_BOOT_HEADER_SIZE, + zynq7000_boot_image::FIXED_BOOT_HEADER_SIZE, ) }; let read_guard = qspi.read_guard(); @@ -189,12 +190,12 @@ fn qspi_boot(mut qspi: QspiSpansionS25Fl256SLinearMode) -> ! { core::ptr::copy_nonoverlapping( QspiSpansionS25Fl256SLinearMode::BASE_ADDR as *mut u8, boot_header_slice.as_mut_ptr(), - zynq_boot_image::FIXED_BOOT_HEADER_SIZE, + zynq7000_boot_image::FIXED_BOOT_HEADER_SIZE, ); } drop(read_guard); - let boot_header = zynq_boot_image::BootHeader::new(boot_header_slice).unwrap(); + let boot_header = zynq7000_boot_image::BootHeader::new(boot_header_slice).unwrap(); let fsbl_offset = boot_header.source_offset(); boot_header_slice = unsafe { core::slice::from_raw_parts_mut(boot_bin_base_addr as *mut u8, fsbl_offset) }; @@ -203,45 +204,126 @@ fn qspi_boot(mut qspi: QspiSpansionS25Fl256SLinearMode) -> ! { let read_guard = qspi.read_guard(); unsafe { core::ptr::copy_nonoverlapping( - (QspiSpansionS25Fl256SLinearMode::BASE_ADDR + zynq_boot_image::FIXED_BOOT_HEADER_SIZE) - as *mut u8, - boot_header_slice[zynq_boot_image::FIXED_BOOT_HEADER_SIZE..].as_mut_ptr(), - fsbl_offset - zynq_boot_image::FIXED_BOOT_HEADER_SIZE, + (QspiSpansionS25Fl256SLinearMode::BASE_ADDR + + zynq7000_boot_image::FIXED_BOOT_HEADER_SIZE) as *mut u8, + boot_header_slice[zynq7000_boot_image::FIXED_BOOT_HEADER_SIZE..].as_mut_ptr(), + fsbl_offset - zynq7000_boot_image::FIXED_BOOT_HEADER_SIZE, ); } drop(read_guard); - let boot_header = zynq_boot_image::BootHeader::new_unchecked(boot_header_slice); + let boot_header = zynq7000_boot_image::BootHeader::new_unchecked(boot_header_slice); let mut name_buf: [u8; 256] = [0; 256]; - for image_header in boot_header.image_header_iterator().unwrap() { + let mut opt_jump_addr = None; + for (index, image_header) in boot_header.image_header_iterator().unwrap().enumerate() { let name = image_header.image_name(&mut name_buf).unwrap(); - for partition in image_header + if index == 0 { + if !name.contains("fsbl") { + log::warn!("first image name did not contain FSBL string"); + } + // Skip the FSBL. It is probably currently running, and we do not want to re-flash it, + // which would also lead to a self-overwrite. + log::info!("skipping FSBL image"); + continue; + } + + let _read_guard = qspi.read_guard(); + + for (partition_index, partition) in image_header .partition_header_iterator(boot_header_slice) .unwrap() + .enumerate() { let section_attrs = partition.section_attributes(); - if let Ok(dest_dev) = section_attrs.destination_device() { - match dest_dev { - DestinationDevice::Pl => { - info!("Loading image '{name}' to PL (FPGA).."); - // TODO: Load the bitstream. + if section_attrs.destination_device().is_err() { + log::error!( + "invalid destination device ID {}", + section_attrs.destination_device().unwrap_err() + ); + continue; + } + let dest_dev = section_attrs.destination_device().unwrap(); + match dest_dev { + DestinationDevice::Pl => { + info!("Loading image '{name}' to PL (FPGA).."); + // Load the bitstream directly from linear mapped QSPI memory. + let boot_bin_slice = unsafe { + core::slice::from_raw_parts( + (QSPI_START_ADDRESS + + partition + .data_offset() + .expect("invalid PL partition data offset")) + as *const _, + partition.total_partition_length().unwrap(), + ) + }; + // The DMA will read from the linear mapped QSPI directly, so it + // has to be configured for reads using the guard! + devcfg::configure_bitstream_non_secure(true, boot_bin_slice) + .expect("unexpected unaligned address"); + log::info!("loaded bitstream successfully"); + } + DestinationDevice::Ps => { + // Load the bitstream directly from linear mapped QSPI memory. + let load_addr = partition.destination_load_address(); + if load_addr < 0x10_0000 { + panic!("invalid load address which is not located in DDR memory"); } - DestinationDevice::Ps => { - // TODO: Load the binary into DDR. Jump at lowest load address after all - // partitions were parsed. - } - _ => { - error!("Unsupported destination device {dest_dev:?}"); - continue; + log::info!( + "Loading partition {partition_index} for '{name}' to PS with load address {load_addr}.." + ); + + let source_slice = unsafe { + core::slice::from_raw_parts( + (QSPI_START_ADDRESS + + partition + .data_offset() + .expect("invalid PS partition data offset")) + as *const _, + partition.total_partition_length().unwrap(), + ) + }; + let target_slice = unsafe { + core::slice::from_raw_parts_mut( + load_addr as *mut u8, + partition.total_partition_length().unwrap(), + ) + }; + + // Copy from the linear mapped QSPI to DDR, + target_slice.copy_from_slice(source_slice); + + match &mut opt_jump_addr { + Some(current) => *current = core::cmp::min(*current, load_addr), + None => opt_jump_addr = Some(load_addr), } + log::info!("load success"); + } + _ => { + error!("Unsupported destination device {dest_dev:?}"); + continue; } } } } - loop { - cortex_ar::asm::nop(); + match opt_jump_addr { + Some(jump_addr) => { + log::info!("jumping to address {}", jump_addr); + zynq7000_hal::log::uart_blocking::flush(); + + // Some clean up and preparation for jumping to the user application. + zynq7000_hal::cache::clean_and_invalidate_data_cache(); + cortex_ar::register::TlbIAll::write(); + cortex_ar::register::BpIAll::write(); + cortex_ar::asm::dsb(); + cortex_ar::asm::isb(); + + let jump_func: extern "C" fn() -> ! = unsafe { core::mem::transmute(jump_addr) }; + jump_func(); + } + None => panic!("did not find application elf to boot inside boot binary!"), } } diff --git a/zedboard-qspi-flasher/Cargo.toml b/zynq/zedboard-qspi-flasher/Cargo.toml similarity index 69% rename from zedboard-qspi-flasher/Cargo.toml rename to zynq/zedboard-qspi-flasher/Cargo.toml index 77d7669..11eb7ab 100644 --- a/zedboard-qspi-flasher/Cargo.toml +++ b/zynq/zedboard-qspi-flasher/Cargo.toml @@ -4,11 +4,13 @@ version = "0.1.0" edition = "2024" [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", branch = "main" } +cortex-ar = { version = "0.3" } zynq7000-rt = { path = "../zynq7000-rt" } zynq7000 = { path = "../zynq7000" } zynq7000-hal = { path = "../zynq7000-hal" } +zynq7000-boot-image = { path = "../../zynq7000-boot-image" } zedboard-bsp = { path = "../zedboard-bsp" } -embedded-io = "0.6" +embedded-io = "0.7" embedded-hal = "1" log = "0.4" +libm = "0.2" diff --git a/zynq/zedboard-qspi-flasher/build.rs b/zynq/zedboard-qspi-flasher/build.rs new file mode 100644 index 0000000..d534cc3 --- /dev/null +++ b/zynq/zedboard-qspi-flasher/build.rs @@ -0,0 +1,31 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/zynq/zedboard-qspi-flasher/memory.x b/zynq/zedboard-qspi-flasher/memory.x new file mode 100644 index 0000000..11faa59 --- /dev/null +++ b/zynq/zedboard-qspi-flasher/memory.x @@ -0,0 +1,22 @@ +MEMORY +{ + /* Zedboard: 512 MB DDR3. Only use 63 MB for now, should be plenty for a bare-metal app. + Leave 1 MB of memory which will be configured as uncached device memory by the MMU. This is + recommended for something like DMA descriptors. */ + CODE(rx) : ORIGIN = 0x00100000, LENGTH = 63M + UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M +} + +REGION_ALIAS("DATA", CODE); + +SECTIONS +{ + /* Uncached memory */ + .uncached (NOLOAD) : ALIGN(4) { + . = ALIGN(4); + _sbss_uncached = .; + *(.uncached .uncached.*); + . = ALIGN(4); + _ebss_uncached = .; + } > UNCACHED +} diff --git a/zynq/zedboard-qspi-flasher/qspi-flasher.tcl b/zynq/zedboard-qspi-flasher/qspi-flasher.tcl new file mode 100644 index 0000000..5c49727 --- /dev/null +++ b/zynq/zedboard-qspi-flasher/qspi-flasher.tcl @@ -0,0 +1,151 @@ +if {[info exists env(ip_address_hw_server)]} { + set ip $env(ip_address_hw_server) +} else { + set ip "localhost" +} + +# absolute directory that contains *this* script +set script_dir [file dirname [info script]] + +# Defaults +set boot_bin_addr 0x10000000 +set boot_bin_size_addr 0x900000 +set init_tcl "" +set bin "" +set bitstream "" + +# Usage helper +proc usage {} { + puts "Usage: xsct qspi-flasher.tcl \[-b|--bin \]" + puts "Options:" + puts " -b, --bin Path to boot binary to flash" + puts " -h, --help Show this help" +} + +# Compact, robust parser +set expecting "" +set endopts 0 +foreach arg $argv { + # If previous option expects a value, take this arg + if {$expecting ne ""} { + set $expecting $arg + set expecting "" + continue + } + + # Option handling (until we see --) + if {!$endopts && [string match "-*" $arg]} { + if {$arg eq "--"} { set endopts 1; continue } + if {$arg eq "-h" || $arg eq "--help"} { usage; exit 0 } + if {$arg eq "-b" || $arg eq "--bin"} { set expecting bin; continue } + puts "error: unknown option: $arg"; usage; exit 1 + } + + # Positional: expect only + if {$init_tcl eq ""} { + set init_tcl $arg + } else { + puts "error: unexpected positional argument: $arg" + usage + exit 1 + } +} + +# Check that QSPI flasher app exists. +set flasher_app [file join $script_dir .. target armv7a-none-eabihf release zedboard-qspi-flasher] +if {![file exists $flasher_app]} { + error "QSPI flasher application not found at path: $flasher_app" +} +set flasher_app [file normalize $flasher_app] + +# Validate required init script +if {$init_tcl eq ""} { + puts "error: missing required first argument pointing to initialization TCL script" + usage + exit 1 +} +if {![file exists $init_tcl]} { + puts "error: the PS init tcl script '$init_tcl' does not exist" + exit 1 +} + +# Resolve app: CLI takes precedence over env(APP) +if {$bin ne ""} { + if {![file exists $bin]} { + puts "error: the boot binary file '$bin' does not exist" + exit 1 + } +} elseif {[info exists env(BOOTBIN)]} { + if {[file exists $env(BOOTBIN)]} { + set bin $env(BOOTBIN) + } else { + puts "warning: BOOTBIN environment variable is set but file does not exist: $env(BOOTBIN)" + } +} + +if {$bin eq ""} { + puts "error: boot.bin binary required" + usage + exit 1 +} + +# Validate bitstream if provided +if {$bitstream ne "" && ![file exists $bitstream]} { + puts "error: the bitstream file '$bitstream' does not exist" + exit 1 +} + +puts "Hardware server IP address: $ip" +connect -url tcp:$ip:3121 + +set devices [targets] + +set apu_line [string trim [targets -nocase -filter {name =~ "APU"}]] +set arm_core_0_line [string trim [targets -nocase -filter {name =~ "ARM Cortex-A9 MPCore #0"}]] +set fpga_line [string trim [targets -nocase -filter {name =~ "xc7z020"}]] + +set apu_device_num [string index $apu_line 0] +set arm_core_0_num [string index $arm_core_0_line 0] +set fpga_device_num [string index $fpga_line 0] + +puts "Select ps target with number: $apu_device_num" + +# Select the target +target $apu_device_num + +# Resetting the target involved problems when an image is stored on the flash. +# It has turned out that it is not essential to reset the system before loading +# the software components into the device. +puts "Reset target" +# TODO: Make the reset optional/configurable via input argument. +# Reset the target +rst + +puts "Set ps target with device number: $arm_core_0_num" +targets $arm_core_0_num + +puts "Initialize processing system" +# Init processing system +source $init_tcl + +ps7_init +ps7_post_config + +puts "Set arm core 0 target with number: $arm_core_0_num" +target $arm_core_0_num + +puts "Download boot.bin $bin to target DDR at address $boot_bin_addr" +dow -data $bin $boot_bin_addr + +# Write boot.bin binary size to specific address. +set boot_bin_size [file size $bin] +puts "Writing boot.bin size $boot_bin_size to target DDR at address $boot_bin_size_addr" +mwr ${boot_bin_size_addr} ${boot_bin_size} + +puts "Flashing QSPI flasher app" +dow $flasher_app + +puts "Starting QSPI flasher app" +con + +puts "Success" diff --git a/zedboard-qspi-flasher/src/main.rs b/zynq/zedboard-qspi-flasher/src/main.rs similarity index 50% rename from zedboard-qspi-flasher/src/main.rs rename to zynq/zedboard-qspi-flasher/src/main.rs index e43c3f7..eff2638 100644 --- a/zedboard-qspi-flasher/src/main.rs +++ b/zynq/zedboard-qspi-flasher/src/main.rs @@ -7,10 +7,11 @@ use core::panic::PanicInfo; use cortex_ar::asm::nop; use embedded_hal::{delay::DelayNs as _, digital::StatefulOutputPin as _}; use embedded_io::Write as _; -use log::info; +use log::{error, info}; use zedboard_bsp::qspi_spansion; +use zynq7000_boot_image::BootHeader; use zynq7000_hal::{ - clocks, gpio, prelude::*, priv_tim, qspi, time::Hertz, uart, BootMode, LevelShifterConfig, + BootMode, LevelShifterConfig, clocks, gpio, prelude::*, priv_tim, qspi, time::Hertz, uart, }; use zynq7000_rt as _; @@ -19,6 +20,15 @@ use zynq7000_rt as _; // Not required for the PAC mode, is required for clean delays in HAL mode. const PS_CLOCK_FREQUENCY: Hertz = Hertz::from_raw(33_333_333); +// TODO: Make this configurable somehow? +const BOOT_BIN_BASE_ADDR: usize = 0x1000_0000; +const BOOT_BIN_SIZE_ADDR: usize = 0x900_000; + +// Maximum of 16 MB is allowed for now. +const MAX_BOOT_BIN_SIZE: usize = 16 * 1024 * 1024; + +const VERIFY_PROGRAMMING: bool = true; + #[allow(dead_code)] const QSPI_DEV_COMBINATION: qspi::QspiDeviceCombination = qspi::QspiDeviceCombination { vendor: qspi::QspiVendor::WinbondAndSpansion, @@ -67,7 +77,7 @@ pub fn main() -> ! { unsafe { zynq7000_hal::log::uart_blocking::init_unsafe_single_core( uart, - log::LevelFilter::Trace, + log::LevelFilter::Info, false, ) }; @@ -96,7 +106,83 @@ pub fn main() -> ! { let qspi_io_mode = qspi.into_io_mode(false); - let _spansion_qspi = qspi_spansion::QspiSpansionS25Fl256SIoMode::new(qspi_io_mode, true); + let mut spansion_qspi = qspi_spansion::QspiSpansionS25Fl256SIoMode::new(qspi_io_mode, true); + + let mut boot_bin_slice = unsafe { + core::slice::from_raw_parts(BOOT_BIN_BASE_ADDR as *const _, BootHeader::FIXED_SIZED_PART) + }; + // This perform some basic validity checks. + let _boot_header = BootHeader::new(&boot_bin_slice[0..BootHeader::FIXED_SIZED_PART]) + .expect("failed to parse boot header"); + let boot_bin_size = + unsafe { core::ptr::read_volatile(BOOT_BIN_SIZE_ADDR as *const u32) as usize }; + if boot_bin_size == 0 || boot_bin_size > MAX_BOOT_BIN_SIZE { + panic!( + "boot binary size read at address {:#x} is invalid: found {}, must be in range [0, {}]", + BOOT_BIN_SIZE_ADDR, boot_bin_size, MAX_BOOT_BIN_SIZE + ); + } + boot_bin_slice = + unsafe { core::slice::from_raw_parts(BOOT_BIN_BASE_ADDR as *const _, boot_bin_size) }; + info!( + "flashing boot binary with {} bytes to QSPI address 0x0", + boot_bin_size + ); + + let mut current_addr = 0; + let mut read_buf = [0u8; 256]; + let mut next_checkpoint = 0.05; + while current_addr < boot_bin_size { + if current_addr % 0x10000 == 0 { + log::debug!("Erasing sector at address {:#x}", current_addr); + match spansion_qspi.erase_sector(current_addr as u32) { + Ok(()) => {} + Err(e) => { + error!( + "failed to erase sector at address {:#x}: {:?}", + current_addr, e + ); + panic!("QSPI erase failed"); + } + } + } + let write_size = core::cmp::min(256, boot_bin_size - current_addr); + let write_slice = &boot_bin_slice[current_addr..current_addr + write_size]; + log::debug!("Programming address {:#x}", current_addr); + match spansion_qspi.program_page(current_addr as u32, write_slice) { + Ok(()) => {} + Err(e) => { + log::error!( + "failed to write data to QSPI at address {:#x}: {:?}", + current_addr, + e + ); + panic!("QSPI write failed"); + } + } + if VERIFY_PROGRAMMING { + spansion_qspi.read_page_fast_read( + current_addr as u32, + &mut read_buf[0..write_size], + true, + ); + if &read_buf[0..write_size] != write_slice { + error!( + "data verification failed at address {:#x}: wrote {:x?}, read {:x?}", + current_addr, + &write_slice[0..core::cmp::min(16, write_size)], + &read_buf[0..core::cmp::min(16, write_size)] + ); + panic!("QSPI data verification failed"); + } + } + current_addr += write_size; + if current_addr as f32 / boot_bin_size as f32 >= next_checkpoint { + log::info!("Write progress {} %", libm::roundf(next_checkpoint * 100.0)); + next_checkpoint += 0.05; + } + } + info!("flashing done"); let mut mio_led = gpio::Output::new_for_mio(gpio_pins.mio.mio7, gpio::PinState::Low); loop { diff --git a/zynq7000-embassy/Cargo.toml b/zynq/zynq7000-embassy/Cargo.toml similarity index 100% rename from zynq7000-embassy/Cargo.toml rename to zynq/zynq7000-embassy/Cargo.toml diff --git a/zynq7000-embassy/LICENSE-APACHE b/zynq/zynq7000-embassy/LICENSE-APACHE similarity index 100% rename from zynq7000-embassy/LICENSE-APACHE rename to zynq/zynq7000-embassy/LICENSE-APACHE diff --git a/zynq7000-embassy/LICENSE-MIT b/zynq/zynq7000-embassy/LICENSE-MIT similarity index 100% rename from zynq7000-embassy/LICENSE-MIT rename to zynq/zynq7000-embassy/LICENSE-MIT diff --git a/zynq7000-embassy/README.md b/zynq/zynq7000-embassy/README.md similarity index 100% rename from zynq7000-embassy/README.md rename to zynq/zynq7000-embassy/README.md diff --git a/zynq7000-embassy/src/lib.rs b/zynq/zynq7000-embassy/src/lib.rs similarity index 100% rename from zynq7000-embassy/src/lib.rs rename to zynq/zynq7000-embassy/src/lib.rs diff --git a/zynq7000-hal/Cargo.toml b/zynq/zynq7000-hal/Cargo.toml similarity index 85% rename from zynq7000-hal/Cargo.toml rename to zynq/zynq7000-hal/Cargo.toml index 8e8e74d..f5ffc47 100644 --- a/zynq7000-hal/Cargo.toml +++ b/zynq/zynq7000-hal/Cargo.toml @@ -11,9 +11,9 @@ keywords = ["no-std", "hal", "amd", "zynq7000", "xilinx", "bare-metal"] categories = ["embedded", "no-std", "hardware-support"] [dependencies] -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", branch = "bump-arbitrary-int" } +cortex-ar = { version = "0.3" } zynq7000 = { path = "../zynq7000" } -zynq-mmu = { path = "../zynq-mmu", version = "0.1.0" } +zynq7000-mmu = { path = "../zynq7000-mmu", version = "0.1.0" } static_assertions = "1.1" bitbybit = "1.4" @@ -22,7 +22,7 @@ thiserror = { version = "2", default-features = false } num_enum = { version = "0.7", default-features = false } ringbuf = { version = "0.4.8", default-features = false } embedded-hal-nb = "1" -embedded-io = "0.6" +embedded-io = "0.7" embedded-hal = "1" embedded-hal-async = "1" heapless = "0.9" @@ -39,7 +39,7 @@ embassy-net-driver = "0.2" smoltcp = { version = "0.12", default-features = false, features = ["proto-ipv4", "medium-ethernet", "socket-raw"] } vcell = "0.1" raw-slicee = "0.1" -embedded-io-async = "0.6" +embedded-io-async = "0.7" [features] std = ["thiserror/std", "alloc"] diff --git a/zynq7000-hal/LICENSE-APACHE b/zynq/zynq7000-hal/LICENSE-APACHE similarity index 100% rename from zynq7000-hal/LICENSE-APACHE rename to zynq/zynq7000-hal/LICENSE-APACHE diff --git a/zynq7000-hal/LICENSE-MIT b/zynq/zynq7000-hal/LICENSE-MIT similarity index 100% rename from zynq7000-hal/LICENSE-MIT rename to zynq/zynq7000-hal/LICENSE-MIT diff --git a/zynq7000-hal/README.md b/zynq/zynq7000-hal/README.md similarity index 100% rename from zynq7000-hal/README.md rename to zynq/zynq7000-hal/README.md diff --git a/zynq7000-hal/docs.sh b/zynq/zynq7000-hal/docs.sh similarity index 100% rename from zynq7000-hal/docs.sh rename to zynq/zynq7000-hal/docs.sh diff --git a/zynq7000-hal/src/cache.rs b/zynq/zynq7000-hal/src/cache.rs similarity index 100% rename from zynq7000-hal/src/cache.rs rename to zynq/zynq7000-hal/src/cache.rs diff --git a/zynq7000-hal/src/clocks/mod.rs b/zynq/zynq7000-hal/src/clocks/mod.rs similarity index 100% rename from zynq7000-hal/src/clocks/mod.rs rename to zynq/zynq7000-hal/src/clocks/mod.rs diff --git a/zynq7000-hal/src/clocks/pll.rs b/zynq/zynq7000-hal/src/clocks/pll.rs similarity index 100% rename from zynq7000-hal/src/clocks/pll.rs rename to zynq/zynq7000-hal/src/clocks/pll.rs diff --git a/zynq7000-hal/src/ddr/ll.rs b/zynq/zynq7000-hal/src/ddr/ll.rs similarity index 99% rename from zynq7000-hal/src/ddr/ll.rs rename to zynq/zynq7000-hal/src/ddr/ll.rs index b7a3c62..f5618a0 100644 --- a/zynq7000-hal/src/ddr/ll.rs +++ b/zynq/zynq7000-hal/src/ddr/ll.rs @@ -212,6 +212,7 @@ pub unsafe fn configure_iob(cfg_set: &DdriobConfigSet) { } /// Full static DDRC configuration set. +#[derive(Debug)] pub struct DdrcConfigSet { pub ctrl: DdrcControl, pub two_rank: TwoRankConfig, diff --git a/zynq7000-hal/src/ddr/mod.rs b/zynq/zynq7000-hal/src/ddr/mod.rs similarity index 100% rename from zynq7000-hal/src/ddr/mod.rs rename to zynq/zynq7000-hal/src/ddr/mod.rs diff --git a/zynq7000-hal/src/devcfg.rs b/zynq/zynq7000-hal/src/devcfg.rs similarity index 100% rename from zynq7000-hal/src/devcfg.rs rename to zynq/zynq7000-hal/src/devcfg.rs diff --git a/zynq7000-hal/src/eth/embassy_net.rs b/zynq/zynq7000-hal/src/eth/embassy_net.rs similarity index 100% rename from zynq7000-hal/src/eth/embassy_net.rs rename to zynq/zynq7000-hal/src/eth/embassy_net.rs diff --git a/zynq7000-hal/src/eth/ll.rs b/zynq/zynq7000-hal/src/eth/ll.rs similarity index 100% rename from zynq7000-hal/src/eth/ll.rs rename to zynq/zynq7000-hal/src/eth/ll.rs diff --git a/zynq7000-hal/src/eth/mdio.rs b/zynq/zynq7000-hal/src/eth/mdio.rs similarity index 100% rename from zynq7000-hal/src/eth/mdio.rs rename to zynq/zynq7000-hal/src/eth/mdio.rs diff --git a/zynq7000-hal/src/eth/mod.rs b/zynq/zynq7000-hal/src/eth/mod.rs similarity index 100% rename from zynq7000-hal/src/eth/mod.rs rename to zynq/zynq7000-hal/src/eth/mod.rs diff --git a/zynq7000-hal/src/eth/rx_descr.rs b/zynq/zynq7000-hal/src/eth/rx_descr.rs similarity index 100% rename from zynq7000-hal/src/eth/rx_descr.rs rename to zynq/zynq7000-hal/src/eth/rx_descr.rs diff --git a/zynq7000-hal/src/eth/smoltcp.rs b/zynq/zynq7000-hal/src/eth/smoltcp.rs similarity index 100% rename from zynq7000-hal/src/eth/smoltcp.rs rename to zynq/zynq7000-hal/src/eth/smoltcp.rs diff --git a/zynq7000-hal/src/eth/tx_descr.rs b/zynq/zynq7000-hal/src/eth/tx_descr.rs similarity index 100% rename from zynq7000-hal/src/eth/tx_descr.rs rename to zynq/zynq7000-hal/src/eth/tx_descr.rs diff --git a/zynq7000-hal/src/gic.rs b/zynq/zynq7000-hal/src/gic.rs similarity index 100% rename from zynq7000-hal/src/gic.rs rename to zynq/zynq7000-hal/src/gic.rs diff --git a/zynq7000-hal/src/gpio/emio.rs b/zynq/zynq7000-hal/src/gpio/emio.rs similarity index 100% rename from zynq7000-hal/src/gpio/emio.rs rename to zynq/zynq7000-hal/src/gpio/emio.rs diff --git a/zynq7000-hal/src/gpio/ll.rs b/zynq/zynq7000-hal/src/gpio/ll.rs similarity index 100% rename from zynq7000-hal/src/gpio/ll.rs rename to zynq/zynq7000-hal/src/gpio/ll.rs diff --git a/zynq7000-hal/src/gpio/mio.rs b/zynq/zynq7000-hal/src/gpio/mio.rs similarity index 100% rename from zynq7000-hal/src/gpio/mio.rs rename to zynq/zynq7000-hal/src/gpio/mio.rs diff --git a/zynq7000-hal/src/gpio/mod.rs b/zynq/zynq7000-hal/src/gpio/mod.rs similarity index 100% rename from zynq7000-hal/src/gpio/mod.rs rename to zynq/zynq7000-hal/src/gpio/mod.rs diff --git a/zynq7000-hal/src/gtc.rs b/zynq/zynq7000-hal/src/gtc.rs similarity index 100% rename from zynq7000-hal/src/gtc.rs rename to zynq/zynq7000-hal/src/gtc.rs diff --git a/zynq7000-hal/src/i2c.rs b/zynq/zynq7000-hal/src/i2c.rs similarity index 100% rename from zynq7000-hal/src/i2c.rs rename to zynq/zynq7000-hal/src/i2c.rs diff --git a/zynq7000-hal/src/l2_cache.rs b/zynq/zynq7000-hal/src/l2_cache.rs similarity index 100% rename from zynq7000-hal/src/l2_cache.rs rename to zynq/zynq7000-hal/src/l2_cache.rs diff --git a/zynq7000-hal/src/lib.rs b/zynq/zynq7000-hal/src/lib.rs similarity index 100% rename from zynq7000-hal/src/lib.rs rename to zynq/zynq7000-hal/src/lib.rs index c04ea6e..56390bf 100644 --- a/zynq7000-hal/src/lib.rs +++ b/zynq/zynq7000-hal/src/lib.rs @@ -14,8 +14,8 @@ extern crate alloc; use slcr::Slcr; use zynq7000::{ - slcr::{BootModeRegister, BootPllConfig, LevelShifterRegister}, SpiClockPhase, SpiClockPolarity, + slcr::{BootModeRegister, BootPllConfig, LevelShifterRegister}, }; pub mod cache; diff --git a/zynq7000-hal/src/log.rs b/zynq/zynq7000-hal/src/log.rs similarity index 80% rename from zynq7000-hal/src/log.rs rename to zynq/zynq7000-hal/src/log.rs index 06e698a..6593365 100644 --- a/zynq7000-hal/src/log.rs +++ b/zynq/zynq7000-hal/src/log.rs @@ -1,13 +1,23 @@ //! # Simple logging providers. +use core::sync::atomic::{AtomicBool, AtomicU8}; + +static LOGGER_INIT_DONE: AtomicBool = AtomicBool::new(false); + +const LOG_SEL_LOCKED: u8 = 1; +const LOG_SEL_UNSAFE_SINGLE_CORE: u8 = 2; + +static LOG_SEL: AtomicU8 = AtomicU8::new(0); + /// Blocking UART loggers. pub mod uart_blocking { + use super::*; use core::cell::{Cell, RefCell, UnsafeCell}; use embedded_io::Write as _; use cortex_ar::register::Cpsr; use critical_section::Mutex; - use log::{LevelFilter, set_logger, set_max_level}; + use log::{LevelFilter, Log, set_logger, set_max_level}; use crate::uart::Uart; @@ -27,7 +37,10 @@ pub mod uart_blocking { /// For async applications, it is strongly recommended to use the asynchronous ring buffer /// logger instead. pub fn init_with_locks(uart: Uart, level: LevelFilter) { - // TODO: Impl debug for Uart + if LOGGER_INIT_DONE.swap(true, core::sync::atomic::Ordering::Relaxed) { + return; + } + LOG_SEL.swap(LOG_SEL_LOCKED, core::sync::atomic::Ordering::Relaxed); critical_section::with(|cs| { let inner = UART_LOGGER_BLOCKING.0.borrow(cs); inner.replace(Some(uart)); @@ -53,7 +66,16 @@ pub mod uart_blocking { }) } - fn flush(&self) {} + fn flush(&self) { + critical_section::with(|cs| { + let mut opt_logger = self.0.borrow(cs).borrow_mut(); + if opt_logger.is_none() { + return; + } + let logger = opt_logger.as_mut().unwrap(); + logger.flush().unwrap(); + }); + } } pub struct UartLoggerUnsafeSingleThread { @@ -70,23 +92,6 @@ pub mod uart_blocking { uart: UnsafeCell::new(None), }; - /// Initialize the logger with a blocking UART instance. - /// - /// For async applications, it is strongly recommended to use the asynchronous ring buffer - /// logger instead. - /// - /// # Safety - /// - /// This is a blocking logger which performs a write WITHOUT a critical section. This logger is - /// NOT thread-safe. Users must ensure that this logger is not used inside a pre-emptive - /// multi-threading context and interrupt handlers. - pub unsafe fn create_unsafe_single_thread_logger(uart: Uart) -> UartLoggerUnsafeSingleThread { - UartLoggerUnsafeSingleThread { - skip_in_isr: Cell::new(false), - uart: UnsafeCell::new(Some(uart)), - } - } - /// Initialize the logger with a blocking UART instance which does not use locks. /// /// # Safety @@ -95,6 +100,13 @@ pub mod uart_blocking { /// NOT thread-safe, which might lead to garbled output. Log output in ISRs can optionally be /// surpressed. pub unsafe fn init_unsafe_single_core(uart: Uart, level: LevelFilter, skip_in_isr: bool) { + if LOGGER_INIT_DONE.swap(true, core::sync::atomic::Ordering::Relaxed) { + return; + } + LOG_SEL.swap( + LOG_SEL_UNSAFE_SINGLE_CORE, + core::sync::atomic::Ordering::Relaxed, + ); let opt_uart = unsafe { &mut *UART_LOGGER_UNSAFE_SINGLE_THREAD.uart.get() }; opt_uart.replace(uart); UART_LOGGER_UNSAFE_SINGLE_THREAD @@ -134,7 +146,22 @@ pub mod uart_blocking { .unwrap(); } - fn flush(&self) {} + fn flush(&self) { + let uart_mut = unsafe { &mut *self.uart.get() }.as_mut(); + if uart_mut.is_none() { + return; + } + uart_mut.unwrap().flush().unwrap(); + } + } + + // Flush the selected logger instance. + pub fn flush() { + match LOG_SEL.load(core::sync::atomic::Ordering::Relaxed) { + val if val == LOG_SEL_LOCKED => UART_LOGGER_BLOCKING.flush(), + val if val == LOG_SEL_UNSAFE_SINGLE_CORE => UART_LOGGER_UNSAFE_SINGLE_THREAD.flush(), + _ => (), + } } } @@ -205,6 +232,9 @@ pub mod rb { } pub fn init(level: LevelFilter) { + if super::LOGGER_INIT_DONE.swap(true, core::sync::atomic::Ordering::Relaxed) { + return; + } critical_section::with(|cs| { let rb = StaticRb::::default(); let rb_ref = LOGGER_RB.ring_buf.borrow(cs); diff --git a/zynq7000-hal/src/prelude.rs b/zynq/zynq7000-hal/src/prelude.rs similarity index 100% rename from zynq7000-hal/src/prelude.rs rename to zynq/zynq7000-hal/src/prelude.rs diff --git a/zynq7000-hal/src/priv_tim.rs b/zynq/zynq7000-hal/src/priv_tim.rs similarity index 100% rename from zynq7000-hal/src/priv_tim.rs rename to zynq/zynq7000-hal/src/priv_tim.rs diff --git a/zynq7000-hal/src/qspi/lqspi_configs.rs b/zynq/zynq7000-hal/src/qspi/lqspi_configs.rs similarity index 100% rename from zynq7000-hal/src/qspi/lqspi_configs.rs rename to zynq/zynq7000-hal/src/qspi/lqspi_configs.rs diff --git a/zynq7000-hal/src/qspi/mod.rs b/zynq/zynq7000-hal/src/qspi/mod.rs similarity index 100% rename from zynq7000-hal/src/qspi/mod.rs rename to zynq/zynq7000-hal/src/qspi/mod.rs diff --git a/zynq7000-hal/src/slcr.rs b/zynq/zynq7000-hal/src/slcr.rs similarity index 100% rename from zynq7000-hal/src/slcr.rs rename to zynq/zynq7000-hal/src/slcr.rs diff --git a/zynq7000-hal/src/spi/asynch.rs b/zynq/zynq7000-hal/src/spi/asynch.rs similarity index 100% rename from zynq7000-hal/src/spi/asynch.rs rename to zynq/zynq7000-hal/src/spi/asynch.rs diff --git a/zynq7000-hal/src/spi/mod.rs b/zynq/zynq7000-hal/src/spi/mod.rs similarity index 100% rename from zynq7000-hal/src/spi/mod.rs rename to zynq/zynq7000-hal/src/spi/mod.rs diff --git a/zynq7000-hal/src/time.rs b/zynq/zynq7000-hal/src/time.rs similarity index 100% rename from zynq7000-hal/src/time.rs rename to zynq/zynq7000-hal/src/time.rs diff --git a/zynq7000-hal/src/ttc.rs b/zynq/zynq7000-hal/src/ttc.rs similarity index 100% rename from zynq7000-hal/src/ttc.rs rename to zynq/zynq7000-hal/src/ttc.rs diff --git a/zynq7000-hal/src/uart/mod.rs b/zynq/zynq7000-hal/src/uart/mod.rs similarity index 99% rename from zynq7000-hal/src/uart/mod.rs rename to zynq/zynq7000-hal/src/uart/mod.rs index 2d3c6fd..ba9e99d 100644 --- a/zynq7000-hal/src/uart/mod.rs +++ b/zynq/zynq7000-hal/src/uart/mod.rs @@ -578,7 +578,7 @@ impl embedded_hal_nb::serial::Write for Uart { } fn flush(&mut self) -> nb::Result<(), Self::Error> { - self.tx.flush() + embedded_hal_nb::serial::Write::flush(&mut self.tx) } } @@ -604,7 +604,8 @@ impl embedded_io::Write for Uart { } fn flush(&mut self) -> Result<(), Self::Error> { - self.tx.flush() + self.tx.flush(); + Ok(()) } } diff --git a/zynq7000-hal/src/uart/rx.rs b/zynq/zynq7000-hal/src/uart/rx.rs similarity index 100% rename from zynq7000-hal/src/uart/rx.rs rename to zynq/zynq7000-hal/src/uart/rx.rs diff --git a/zynq7000-hal/src/uart/tx.rs b/zynq/zynq7000-hal/src/uart/tx.rs similarity index 96% rename from zynq7000-hal/src/uart/tx.rs rename to zynq/zynq7000-hal/src/uart/tx.rs index 9433174..984e0f8 100644 --- a/zynq7000-hal/src/uart/tx.rs +++ b/zynq/zynq7000-hal/src/uart/tx.rs @@ -78,6 +78,10 @@ impl Tx { } } + pub fn flush(&mut self) { + while !self.regs.read_sr().tx_empty() {} + } + #[inline] pub fn write_fifo_unchecked(&mut self, word: u8) { self.regs.write_fifo(Fifo::new_with_raw_value(word as u32)); @@ -161,11 +165,10 @@ impl embedded_hal_nb::serial::Write for Tx { } fn flush(&mut self) -> nb::Result<(), Self::Error> { - loop { - if self.regs.read_sr().tx_empty() { - return Ok(()); - } + if self.regs.read_sr().tx_empty() { + return Ok(()); } + Err(nb::Error::WouldBlock) } } @@ -195,7 +198,7 @@ impl embedded_io::Write for Tx { } fn flush(&mut self) -> Result<(), Self::Error> { - >::flush(self).ok(); + self.flush(); Ok(()) } } diff --git a/zynq7000-hal/src/uart/tx_async.rs b/zynq/zynq7000-hal/src/uart/tx_async.rs similarity index 97% rename from zynq7000-hal/src/uart/tx_async.rs rename to zynq/zynq7000-hal/src/uart/tx_async.rs index f349e71..3033123 100644 --- a/zynq7000-hal/src/uart/tx_async.rs +++ b/zynq/zynq7000-hal/src/uart/tx_async.rs @@ -202,4 +202,9 @@ impl embedded_io_async::Write for TxAsync { async fn write(&mut self, buf: &[u8]) -> Result { Ok(self.write(buf).await) } + + /// This implementation does not do anything. + async fn flush(&mut self) -> Result<(), Self::Error> { + Ok(()) + } } diff --git a/zynq/zynq7000-mmu/Cargo.toml b/zynq/zynq7000-mmu/Cargo.toml new file mode 100644 index 0000000..06946cf --- /dev/null +++ b/zynq/zynq7000-mmu/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "zynq7000-mmu" +description = "Zynq7000 MMU structures" +version = "0.1.0" +edition = "2024" + +[dependencies] +thiserror = { version = "2", default-features = false } +cortex-ar = { version = "0.3" } + +[features] +tools = [] diff --git a/zynq-mmu/src/lib.rs b/zynq/zynq7000-mmu/src/lib.rs similarity index 100% rename from zynq-mmu/src/lib.rs rename to zynq/zynq7000-mmu/src/lib.rs diff --git a/zynq7000-rt/Cargo.toml b/zynq/zynq7000-rt/Cargo.toml similarity index 67% rename from zynq7000-rt/Cargo.toml rename to zynq/zynq7000-rt/Cargo.toml index fd2df97..944fa4c 100644 --- a/zynq7000-rt/Cargo.toml +++ b/zynq/zynq7000-rt/Cargo.toml @@ -12,17 +12,10 @@ categories = ["embedded", "no-std", "hardware-support"] [dependencies] cortex-a-rt = { version = "0.1", optional = true, features = ["vfp-dp"] } -cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", branch = "bump-arbitrary-int" } +cortex-ar = { version = "0.3" } arbitrary-int = "2" -zynq-mmu = { path = "../zynq-mmu", version = "0.1.0" } +zynq7000-mmu = { path = "../zynq7000-mmu", version = "0.1.0" } [features] default = ["rt"] -tools = ["zynq-mmu/tools"] rt = ["dep:cortex-a-rt"] - -[[bin]] -name = "table-gen" -path = "src/bin/table-gen.rs" -# Prevents default build -required-features = ["tools"] diff --git a/zynq7000-rt/README.md b/zynq/zynq7000-rt/README.md similarity index 100% rename from zynq7000-rt/README.md rename to zynq/zynq7000-rt/README.md diff --git a/zynq7000-rt/docs.sh b/zynq/zynq7000-rt/docs.sh similarity index 100% rename from zynq7000-rt/docs.sh rename to zynq/zynq7000-rt/docs.sh diff --git a/zynq7000-rt/regen-table.sh b/zynq/zynq7000-rt/regen-table.sh similarity index 100% rename from zynq7000-rt/regen-table.sh rename to zynq/zynq7000-rt/regen-table.sh diff --git a/zynq7000-rt/src/lib.rs b/zynq/zynq7000-rt/src/lib.rs similarity index 96% rename from zynq7000-rt/src/lib.rs rename to zynq/zynq7000-rt/src/lib.rs index baec7fd..6ae917e 100644 --- a/zynq7000-rt/src/lib.rs +++ b/zynq/zynq7000-rt/src/lib.rs @@ -12,7 +12,7 @@ pub use cortex_a_rt::*; #[cfg(feature = "rt")] -use zynq_mmu::L1TableWrapper; +use zynq7000_mmu::L1TableWrapper; pub mod mmu; #[cfg(feature = "rt")] diff --git a/zynq7000-rt/src/mmu.rs b/zynq/zynq7000-rt/src/mmu.rs similarity index 100% rename from zynq7000-rt/src/mmu.rs rename to zynq/zynq7000-rt/src/mmu.rs diff --git a/zynq7000-rt/src/mmu_table.rs b/zynq/zynq7000-rt/src/mmu_table.rs similarity index 99% rename from zynq7000-rt/src/mmu_table.rs rename to zynq/zynq7000-rt/src/mmu_table.rs index 4ecd507..c4f82ff 100644 --- a/zynq7000-rt/src/mmu_table.rs +++ b/zynq/zynq7000-rt/src/mmu_table.rs @@ -1,7 +1,7 @@ //! This file was auto-generated by table-gen.rs use crate::mmu::section_attrs; use cortex_ar::mmu::L1Section; -use zynq_mmu::L1Table; +use zynq7000_mmu::L1Table; /// MMU Level 1 Page table. /// diff --git a/zynq7000-rt/src/rt.rs b/zynq/zynq7000-rt/src/rt.rs similarity index 100% rename from zynq7000-rt/src/rt.rs rename to zynq/zynq7000-rt/src/rt.rs diff --git a/zynq7000/Cargo.toml b/zynq/zynq7000/Cargo.toml similarity index 100% rename from zynq7000/Cargo.toml rename to zynq/zynq7000/Cargo.toml diff --git a/zynq7000/LICENSE-APACHE b/zynq/zynq7000/LICENSE-APACHE similarity index 100% rename from zynq7000/LICENSE-APACHE rename to zynq/zynq7000/LICENSE-APACHE diff --git a/zynq7000/LICENSE-MIT b/zynq/zynq7000/LICENSE-MIT similarity index 100% rename from zynq7000/LICENSE-MIT rename to zynq/zynq7000/LICENSE-MIT diff --git a/zynq7000/README.md b/zynq/zynq7000/README.md similarity index 100% rename from zynq7000/README.md rename to zynq/zynq7000/README.md diff --git a/zynq7000/build.rs b/zynq/zynq7000/build.rs similarity index 100% rename from zynq7000/build.rs rename to zynq/zynq7000/build.rs diff --git a/zynq7000/docs.sh b/zynq/zynq7000/docs.sh similarity index 100% rename from zynq7000/docs.sh rename to zynq/zynq7000/docs.sh diff --git a/zynq7000/src/ddrc.rs b/zynq/zynq7000/src/ddrc.rs similarity index 87% rename from zynq7000/src/ddrc.rs rename to zynq/zynq7000/src/ddrc.rs index 567e0af..fd4e1cc 100644 --- a/zynq7000/src/ddrc.rs +++ b/zynq/zynq7000/src/ddrc.rs @@ -2,6 +2,7 @@ pub const DDRC_BASE_ADDR: usize = 0xF800_6000; pub mod regs { use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20}; + pub use crate::slcr::ddriob::DdriobConfig; #[bitbybit::bitenum(u2)] #[derive(Debug, PartialEq, Eq)] @@ -16,7 +17,7 @@ pub mod regs { Reset = 0, Active = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DdrcControl { #[bit(16, rw)] disable_auto_refresh: bool, @@ -36,7 +37,7 @@ pub mod regs { soft_reset: SoftReset, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct TwoRankConfig { #[bits(14..=18, rw)] addrmap_cs_bit0: u5, @@ -49,7 +50,7 @@ pub mod regs { } /// Queue control for the low priority and high priority read queues. - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LprHprQueueControl { #[bits(22..=25, rw)] xact_run_length: u4, @@ -59,7 +60,7 @@ pub mod regs { min_non_critical_x32: u11, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct WriteQueueControl { #[bits(15..=25, rw)] max_starve_x32: u11, @@ -69,7 +70,7 @@ pub mod regs { min_non_critical_x32: u11, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramParamReg0 { /// Minimum time to wait after coming out of self refresh before doing anything. This must be /// bigger than all the constraints that exist. @@ -84,7 +85,7 @@ pub mod regs { t_rc: u6, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramParamReg1 { #[bits(28..=31, rw)] t_cke: u4, @@ -100,7 +101,7 @@ pub mod regs { wr2pre: u5, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramParamReg2 { #[bits(28..=31, rw)] t_rcd: u4, @@ -120,11 +121,12 @@ pub mod regs { /// Weird naming. #[bitbybit::bitenum(u1, exhaustive = true)] + #[derive(Debug)] pub enum MobileSetting { Ddr2Ddr3 = 0, Lpddr2 = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramParamReg3 { #[bit(30, rw)] disable_pad_pd_feature: bool, @@ -151,12 +153,13 @@ pub mod regs { } #[bitbybit::bitenum(u1, exhaustive = true)] + #[derive(Debug)] pub enum ModeRegisterType { Write = 0, Read = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramParamReg4 { #[bit(27, rw)] mr_rdata_valid: bool, @@ -176,7 +179,7 @@ pub mod regs { enable_2t_timing_mode: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramInitParam { #[bits(11..=13, rw)] t_mrd: u3, @@ -186,7 +189,7 @@ pub mod regs { final_wait_x32: u7, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramEmr { #[bits(16..=31, rw)] emr3: u16, @@ -194,7 +197,7 @@ pub mod regs { emr2: u16, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramEmrMr { #[bits(16..=31, rw)] emr: u16, @@ -202,7 +205,7 @@ pub mod regs { mr: u16, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramBurst8ReadWrite { #[bits(0..=3, rw)] burst_rdwr: u4, @@ -214,7 +217,7 @@ pub mod regs { burstchop: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DisableDq { #[bit(1, rw)] dis_dq: bool, @@ -222,7 +225,7 @@ pub mod regs { force_low_pri_n: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramAddrMapBank { #[bits(16..=19, rw)] addrmap_bank_b6: u4, @@ -236,7 +239,7 @@ pub mod regs { addrmap_bank_b0: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramAddrMapColumn { #[bits(28..=31, rw)] addrmap_col_b11: u4, @@ -256,7 +259,7 @@ pub mod regs { addrmap_col_b2: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramAddrMapRow { #[bits(24..=27, rw)] addrmap_row_b15: u4, @@ -274,7 +277,7 @@ pub mod regs { addrmap_row_b0: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DramOdt { #[bits(16..=17, rw)] phy_idle_local_odt: u2, @@ -288,7 +291,7 @@ pub mod regs { rank0_rd_odt: u3, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyCmdTimeoutRdDataCpt { #[bits(28..=31, rw)] wrlvl_num_of_dq0: u4, @@ -311,18 +314,19 @@ pub mod regs { } #[bitbybit::bitenum(u1, exhaustive = true)] + #[derive(Debug)] pub enum DllCalibSel { Periodic = 0, Manual = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DllCalib { #[bit(16, rw)] sel: DllCalibSel, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct OdtDelayHold { #[bits(12..=15, rw)] wr_odt_hold: u4, @@ -334,7 +338,7 @@ pub mod regs { rd_odt_delay: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg1 { #[bit(12, rw)] selfref_enable: bool, @@ -352,7 +356,7 @@ pub mod regs { pageclose: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg2 { #[bit(17, rw)] go_2_critcal_enable: bool, @@ -360,7 +364,7 @@ pub mod regs { go_2_critical_hysteresis: u8, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg3 { #[bits(16..=25, rw)] dfi_t_wlmrd: u10, @@ -370,7 +374,7 @@ pub mod regs { wrlvl_ww: u8, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg4 { #[bits(8..=15, rw)] dfi_t_ctrlupd_interval_max_x1024: u8, @@ -378,7 +382,7 @@ pub mod regs { dfi_t_ctrlupd_interval_min_x1024: u8, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg5 { #[bits(20..=25, rw)] t_ckesr: u6, @@ -394,7 +398,7 @@ pub mod regs { dfi_t_ctrl_delay: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CtrlReg6 { #[bits(16..=19, rw)] t_cksx: u4, @@ -408,7 +412,7 @@ pub mod regs { t_ckpde: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CheTZq { #[bits(22..=31, rw)] t_zq_short_nop: u10, @@ -422,7 +426,7 @@ pub mod regs { dis_auto_zq: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CheTZqShortInterval { #[bits(20..=27, rw)] dram_rstn_x1024: u8, @@ -430,7 +434,7 @@ pub mod regs { t_zq_short_interval: u20, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DeepPowerdown { #[bits(1..=8, rw)] deep_powerdown_to_x1024: u8, @@ -438,7 +442,7 @@ pub mod regs { enable: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Reg2c { #[bit(28, rw)] dfi_rd_data_eye_train: bool, @@ -456,13 +460,13 @@ pub mod regs { dfi_wrlvl_max_x1024: u12, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Reg2d { #[bit(9, rw)] skip_ocd: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DfiTiming { #[bits(15..=24, rw)] dfi_t_ctrlup_max: u10, @@ -472,7 +476,7 @@ pub mod regs { dfi_t_rddata_enable: u5, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CheEccControl { #[bit(1, rw)] clear_correctable_errors: bool, @@ -481,12 +485,13 @@ pub mod regs { } #[bitbybit::bitenum(u3, exhaustive = false)] + #[derive(Debug)] pub enum EccMode { NoEcc = 0b000, SecDecOverOneBeat = 0b100, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct EccScrub { #[bit(3, rw)] disable_scrub: bool, @@ -494,7 +499,7 @@ pub mod regs { ecc_mode: Option, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyReceiverEnable { #[bits(4..=7, rw)] phy_dif_off: u4, @@ -502,7 +507,7 @@ pub mod regs { phy_dif_on: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyConfig { #[bits(24..=30, rw)] dq_offset: u7, @@ -516,7 +521,7 @@ pub mod regs { data_slice_in_use: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyInitRatio { #[bits(10..=19, rw)] gatelvl_init_ratio: u10, @@ -524,7 +529,7 @@ pub mod regs { wrlvl_init_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyDqsConfig { #[bits(11..=19, rw)] dqs_slave_delay: u9, @@ -534,7 +539,7 @@ pub mod regs { dqs_slave_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyWriteEnableConfig { #[bits(12..=20, rw)] fifo_we_in_delay: u9, @@ -544,7 +549,7 @@ pub mod regs { fifo_we_slave_ratio: u11, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyWriteDataSlaveConfig { #[bits(11..=19, rw)] wr_data_slave_delay: u9, @@ -554,7 +559,7 @@ pub mod regs { wr_data_slave_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Reg64 { #[bit(30, rw)] cmd_latency: bool, @@ -574,7 +579,7 @@ pub mod regs { bl2: bool, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Reg65 { #[bits(18..=19, rw)] ctrl_slave_delay: u2, @@ -594,7 +599,7 @@ pub mod regs { wr_rl_delay: u5, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct AxiPriorityWritePort { #[bit(18, rw)] disable_page_match: bool, @@ -606,7 +611,7 @@ pub mod regs { pri_wr_port: u10, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct AxiPriorityReadPort { #[bit(19, rw)] enable_hpr: bool, @@ -620,7 +625,7 @@ pub mod regs { pri_rd_port_n: u10, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct ExclusiveAccessConfig { #[bits(9..=17, rw)] access_id1_port: u9, @@ -629,12 +634,13 @@ pub mod regs { } #[bitbybit::bitenum(u1, exhaustive = true)] + #[derive(Debug)] pub enum LpddrBit { Ddr2Ddr3 = 0, Lpddr2 = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LpddrControl0 { #[bits(4..=11, rw)] mr4_margin: u8, @@ -646,13 +652,13 @@ pub mod regs { lpddr2: LpddrBit, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LpddrControl1 { #[bits(0..=31, rw)] mr4_read_interval: u32, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LpddrControl2 { #[bits(12..=21, rw)] t_mrw: u10, @@ -662,7 +668,7 @@ pub mod regs { min_stable_clock_x1: u4, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LpddrControl3 { #[bits(8..=17, rw)] dev_zqinit_x32: u10, @@ -702,7 +708,7 @@ pub mod regs { CommandsNotAccepted = 1, } - #[bitbybit::bitfield(u32, default = 0x0)] + #[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct ModeStatus { #[bits(16..=20, r)] dbg_hpr_queue_depth: u5, diff --git a/zynq7000/src/devcfg.rs b/zynq/zynq7000/src/devcfg.rs similarity index 100% rename from zynq7000/src/devcfg.rs rename to zynq/zynq7000/src/devcfg.rs diff --git a/zynq7000/src/eth.rs b/zynq/zynq7000/src/eth.rs similarity index 97% rename from zynq7000/src/eth.rs rename to zynq/zynq7000/src/eth.rs index 62cb959..38ab358 100644 --- a/zynq7000/src/eth.rs +++ b/zynq/zynq7000/src/eth.rs @@ -82,8 +82,7 @@ impl MdcClockDivisor { } } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct NetworkConfig { #[bit(30, rw)] ignore_ipg_rx_error: bool, @@ -141,8 +140,7 @@ pub struct NetworkConfig { } /// PHY management status information. -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct NetworkStatus { #[bit(6, r)] pfc_pri_pause_neg: bool, @@ -215,8 +213,7 @@ impl DmaRxBufSize { } } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct DmaConfig { #[bit(24, rw)] discard_when_ahb_full: bool, @@ -244,8 +241,7 @@ pub struct DmaConfig { burst_length: u5, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct TxStatus { #[bit(8, rw)] hresp_not_ok: bool, @@ -276,8 +272,7 @@ impl TxStatus { } } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct RxStatus { #[bit(3, rw)] hresp_not_ok: bool, @@ -295,8 +290,7 @@ impl RxStatus { } } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct InterruptStatus { #[bit(26, rw)] tsu_sec_incr: bool, @@ -387,13 +381,13 @@ impl InterruptControl { } #[bitbybit::bitenum(u2, exhaustive = false)] +#[derive(Debug)] pub enum PhyOperation { Read = 0b10, Write = 0b01, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct PhyMaintenance { /// Must be 1 for Clause 22 operations. #[bit(30, rw)] @@ -410,15 +404,13 @@ pub struct PhyMaintenance { data: u16, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct PauseQuantum { #[bits(0..=15, rw)] value: u16, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct MatchRegister { #[bit(31, rw)] copy_enable: bool, diff --git a/zynq7000/src/gic.rs b/zynq/zynq7000/src/gic.rs similarity index 96% rename from zynq7000/src/gic.rs rename to zynq/zynq7000/src/gic.rs index b1b8514..28ddb07 100644 --- a/zynq7000/src/gic.rs +++ b/zynq/zynq7000/src/gic.rs @@ -4,7 +4,7 @@ use arbitrary_int::{u3, u5, u10}; use static_assertions::const_assert_eq; /// Distributor Control Register -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DistributorControlRegister { #[bit(1, rw)] enable_non_secure: bool, @@ -13,7 +13,7 @@ pub struct DistributorControlRegister { } /// Read only bit. This register only returns fixed constants. -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct TypeRegister { #[bits(11..=15, r)] lspi: u5, @@ -127,7 +127,7 @@ impl GicDistributor { } /// CPU interface control register. -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct InterfaceControl { #[bit(4, rw)] sbpr: bool, @@ -142,15 +142,14 @@ pub struct InterfaceControl { } /// Priority Mask Register -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct PriorityRegister { #[bits(0..=7, rw)] priority: u8, } /// Interrupt acknowledge register. -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptSignalRegister { #[bits(10..=12, rw)] cpu_id: u3, diff --git a/zynq7000/src/gpio.rs b/zynq/zynq7000/src/gpio.rs similarity index 98% rename from zynq7000/src/gpio.rs rename to zynq/zynq7000/src/gpio.rs index 34773de..5decc98 100644 --- a/zynq7000/src/gpio.rs +++ b/zynq/zynq7000/src/gpio.rs @@ -3,9 +3,9 @@ #[derive(Debug)] pub struct MaskedOutput { #[bits(16..=31, w)] - pub mask: u16, + mask: u16, #[bits(0..=15, rw)] - pub output: u16, + output: u16, } #[derive(derive_mmio::Mmio)] diff --git a/zynq7000/src/gtc.rs b/zynq/zynq7000/src/gtc.rs similarity index 95% rename from zynq7000/src/gtc.rs rename to zynq/zynq7000/src/gtc.rs index cc089c0..3e29b12 100644 --- a/zynq7000/src/gtc.rs +++ b/zynq/zynq7000/src/gtc.rs @@ -2,7 +2,7 @@ pub const GTC_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0200; -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct GtcControl { #[bits(8..=15, rw)] prescaler: u8, @@ -16,7 +16,7 @@ pub struct GtcControl { enable: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptStatus { #[bit(0, rw)] event_flag: bool, diff --git a/zynq7000/src/i2c.rs b/zynq/zynq7000/src/i2c.rs similarity index 93% rename from zynq7000/src/i2c.rs rename to zynq/zynq7000/src/i2c.rs index 3d3ca78..8ea7663 100644 --- a/zynq7000/src/i2c.rs +++ b/zynq/zynq7000/src/i2c.rs @@ -18,7 +18,7 @@ pub enum Mode { Master = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Control { /// Divides the input PCLK frequency by this value + 1 #[bits(14..=15, rw)] @@ -47,7 +47,7 @@ pub struct Control { dir: Direction, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Status { #[bit(8, r)] bus_active: bool, @@ -65,19 +65,19 @@ pub struct Status { rx_rw: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Address { #[bits(0..=9, rw)] addr: u10, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Fifo { #[bits(0..=7, rw)] data: u8, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptStatus { #[bit(9, rw)] arbitration_lost: bool, @@ -99,7 +99,7 @@ pub struct InterruptStatus { complete: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptMask { #[bit(9, r)] arbitration_lost: bool, @@ -143,14 +143,14 @@ pub struct InterruptControl { complete: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Timeout { /// Reset value: 0x1F. #[bits(0..=7, rw)] timeout: u8, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct TransferSize { #[bits(0..=7, rw)] size: u8, diff --git a/zynq7000/src/l2_cache.rs b/zynq/zynq7000/src/l2_cache.rs similarity index 95% rename from zynq7000/src/l2_cache.rs rename to zynq/zynq7000/src/l2_cache.rs index 98238ee..46d090a 100644 --- a/zynq7000/src/l2_cache.rs +++ b/zynq/zynq7000/src/l2_cache.rs @@ -9,15 +9,13 @@ pub struct LockdownRegisters { instruction: u32, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct CacheSync { #[bit(0, r)] busy: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DebugControl { #[bit(2, rw)] spniden: bool, @@ -27,8 +25,7 @@ pub struct DebugControl { disable_cache_linefill: bool, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct CacheId { #[bits(24..=31, r)] implementer: u8, @@ -59,6 +56,7 @@ impl Control { } #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug)] pub enum ReplacementPolicy { PseudoRandomWithLfsr = 0, RoundRobin = 1, @@ -86,7 +84,7 @@ pub enum Associativity { _16Way = 1, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct AuxControl { #[bit(30, rw)] early_bresp_enable: bool, @@ -125,8 +123,8 @@ pub struct AuxControl { full_line_zero_enable: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug, PartialEq, Eq)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[derive(PartialEq, Eq)] pub struct LatencyConfig { /// Latency is the numerical value + 1 cycles. #[bits(8..=10, rw)] @@ -139,8 +137,7 @@ pub struct LatencyConfig { setup_latency: u3, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptStatus { #[bit(8, r)] dec_error_l3: bool, diff --git a/zynq7000/src/lib.rs b/zynq/zynq7000/src/lib.rs similarity index 100% rename from zynq7000/src/lib.rs rename to zynq/zynq7000/src/lib.rs diff --git a/zynq7000/src/mpcore.rs b/zynq/zynq7000/src/mpcore.rs similarity index 100% rename from zynq7000/src/mpcore.rs rename to zynq/zynq7000/src/mpcore.rs diff --git a/zynq7000/src/priv_tim.rs b/zynq/zynq7000/src/priv_tim.rs similarity index 93% rename from zynq7000/src/priv_tim.rs rename to zynq/zynq7000/src/priv_tim.rs index dc6b1a0..cc86ede 100644 --- a/zynq7000/src/priv_tim.rs +++ b/zynq/zynq7000/src/priv_tim.rs @@ -2,7 +2,7 @@ pub const CPU_PRIV_TIM_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0600; -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Control { #[bits(8..=15, rw)] prescaler: u8, @@ -14,7 +14,7 @@ pub struct Control { enable: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct InterruptStatus { /// Cleared by writing a one. #[bit(0, rw)] diff --git a/zynq7000/src/qspi.rs b/zynq/zynq7000/src/qspi.rs similarity index 94% rename from zynq7000/src/qspi.rs rename to zynq/zynq7000/src/qspi.rs index 46ba719..d963991 100644 --- a/zynq7000/src/qspi.rs +++ b/zynq/zynq7000/src/qspi.rs @@ -48,7 +48,9 @@ impl BaudRateDivisor { } } +// TODO: Use bitbybit debug support as soon as support for write fields has been implemented. #[bitbybit::bitfield(u32, default = 0x0)] +#[derive(Debug)] pub struct Config { #[bit(31, rw)] interface_mode: InterfaceMode, @@ -79,7 +81,7 @@ pub struct Config { mode_select: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptStatus { /// Write-to-clear bit. #[bit(6, rw)] @@ -113,7 +115,7 @@ pub struct InterruptControl { rx_overrun: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptMask { #[bit(6, r)] tx_underflow: bool, @@ -129,14 +131,14 @@ pub struct InterruptMask { rx_overrun: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct SpiEnable { #[bit(0, rw)] enable: bool, } /// All the delays are in SPI reference block or external clock cycles. -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Delay { /// Length of the master mode chip select output de-asserts between words when CPHA = 0. #[bits(24..=31, rw)] @@ -159,7 +161,7 @@ pub struct Gpio { write_protect_n: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LoopbackMasterClockDelay { /// Use internal loopback master clock for read data capturing when the baud rate divisor /// is 2. @@ -182,7 +184,7 @@ pub enum InstructionCode { FastReadQuadIo = 0xEB, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct LinearQspiConfig { #[bit(31, rw)] enable_linear_mode: bool, @@ -210,7 +212,7 @@ pub struct LinearQspiConfig { instruction_code: Option, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct LinearQspiStatus { #[bit(2, rw)] data_fsm_error: bool, diff --git a/zynq7000/src/slcr/clocks.rs b/zynq/zynq7000/src/slcr/clocks.rs similarity index 100% rename from zynq7000/src/slcr/clocks.rs rename to zynq/zynq7000/src/slcr/clocks.rs diff --git a/zynq7000/src/slcr/ddriob.rs b/zynq/zynq7000/src/slcr/ddriob.rs similarity index 94% rename from zynq7000/src/slcr/ddriob.rs rename to zynq/zynq7000/src/slcr/ddriob.rs index b88e395..28ae5bb 100644 --- a/zynq7000/src/slcr/ddriob.rs +++ b/zynq/zynq7000/src/slcr/ddriob.rs @@ -1,6 +1,7 @@ use arbitrary_int::{u2, u3}; #[bitbybit::bitenum(u4, exhaustive = false)] +#[derive(Debug)] pub enum VRefSel { /// VREF = 0.6 V Lpddr2 = 0b0001, @@ -12,7 +13,7 @@ pub enum VRefSel { Ddr2 = 0b1000, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct DdrControl { /// Enables VRP/VRN. #[bit(9, rw)] @@ -27,7 +28,7 @@ pub struct DdrControl { vref_int_en: bool, } -#[bitbybit::bitfield(u32, default = 0x00)] +#[bitbybit::bitfield(u32, default = 0x00, debug)] pub struct DciControl { #[bit(20, rw)] update_control: bool, @@ -48,7 +49,7 @@ pub struct DciControl { reset: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct DciStatus { #[bit(13, rw)] done: bool, @@ -83,7 +84,7 @@ pub enum DciType { DciTermination = 0b11, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DdriobConfig { #[bit(11, rw)] pullup_enable: bool, diff --git a/zynq7000/src/slcr/mio.rs b/zynq/zynq7000/src/slcr/mio.rs similarity index 89% rename from zynq7000/src/slcr/mio.rs rename to zynq/zynq7000/src/slcr/mio.rs index f37ec10..4116a39 100644 --- a/zynq7000/src/slcr/mio.rs +++ b/zynq/zynq7000/src/slcr/mio.rs @@ -4,12 +4,14 @@ use arbitrary_int::{u2, u3}; #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug)] pub enum Speed { SlowCmosEdge = 0b0, FastCmosEdge = 0b1, } #[bitbybit::bitenum(u3)] +#[derive(Debug)] pub enum IoType { LvCmos18 = 0b001, LvCmos25 = 0b010, @@ -17,8 +19,8 @@ pub enum IoType { Hstl = 0b100, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[derive(PartialEq, Eq)] pub struct Config { #[bit(13, rw)] disable_hstl_rcvr: bool, diff --git a/zynq7000/src/slcr/mod.rs b/zynq/zynq7000/src/slcr/mod.rs similarity index 98% rename from zynq7000/src/slcr/mod.rs rename to zynq/zynq7000/src/slcr/mod.rs index ffd4cea..5bbdc60 100644 --- a/zynq7000/src/slcr/mod.rs +++ b/zynq/zynq7000/src/slcr/mod.rs @@ -17,6 +17,7 @@ pub mod mio; pub mod reset; #[bitbybit::bitenum(u3, exhaustive = false)] +#[derive(Debug)] pub enum VrefSel { Disabled = 0b000, Vref0_9V = 0b001, @@ -84,7 +85,7 @@ pub enum LevelShifterConfig { EnableAll = 0xF, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct LevelShifterRegister { #[bits(0..=3, rw)] user_lvl_shftr_en: Option, diff --git a/zynq7000/src/slcr/reset.rs b/zynq/zynq7000/src/slcr/reset.rs similarity index 88% rename from zynq7000/src/slcr/reset.rs rename to zynq/zynq7000/src/slcr/reset.rs index 4e409ce..8275ad5 100644 --- a/zynq7000/src/slcr/reset.rs +++ b/zynq/zynq7000/src/slcr/reset.rs @@ -1,7 +1,6 @@ use super::{RESET_BLOCK_OFFSET, SLCR_BASE_ADDR}; -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DualClockReset { /// Peripheral 1 AMBA software reset. #[bit(1, rw)] @@ -11,8 +10,7 @@ pub struct DualClockReset { periph0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DualRefAndClockReset { /// Periperal 1 Reference software reset. #[bit(3, rw)] @@ -28,15 +26,13 @@ pub struct DualRefAndClockReset { periph0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct GpioClockReset { #[bit(0, rw)] gpio_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct EthernetReset { #[bit(5, rw)] gem1_ref_rst: bool, @@ -52,8 +48,7 @@ pub struct EthernetReset { gem0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct QspiResetControl { #[bit(2, rw)] qspi_ref_reset: bool, diff --git a/zynq7000/src/spi.rs b/zynq/zynq7000/src/spi.rs similarity index 96% rename from zynq7000/src/spi.rs rename to zynq/zynq7000/src/spi.rs index 13bc3f3..dbb5ae4 100644 --- a/zynq7000/src/spi.rs +++ b/zynq/zynq7000/src/spi.rs @@ -33,6 +33,7 @@ impl BaudDivSel { } } +// TODO: Use bitbybit debug support as soon as it was added. #[bitbybit::bitfield(u32, default = 0x0)] #[derive(Debug)] pub struct Config { @@ -67,8 +68,7 @@ pub struct Config { master_ern: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct InterruptStatus { #[bit(6, rw)] tx_underflow: bool, @@ -107,8 +107,7 @@ pub struct InterruptControl { rx_ovr: bool, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptMask { #[bit(6, r)] tx_underflow: bool, @@ -163,8 +162,7 @@ impl FifoRead { } /// The numbers specified in the register fields are always specified in number of -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct DelayControl { /// Number of cycles the chip select is de-asserted between words when CPHA = 0 #[bits(24..=31, rw)] diff --git a/zynq7000/src/ttc.rs b/zynq/zynq7000/src/ttc.rs similarity index 94% rename from zynq7000/src/ttc.rs rename to zynq/zynq7000/src/ttc.rs index 76fe4d8..58a1cd5 100644 --- a/zynq7000/src/ttc.rs +++ b/zynq/zynq7000/src/ttc.rs @@ -13,7 +13,7 @@ pub enum ClockSource { External = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct ClockControl { /// When this bit is set and the external clock is selected, the counter clocks on the /// negative edge of the external clock input. @@ -27,15 +27,15 @@ pub struct ClockControl { prescale_enable: bool, } -#[derive(Debug)] #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug)] pub enum Mode { Overflow = 0b0, Interval = 0b1, } -#[derive(Debug, Default)] #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug, Default)] pub enum WavePolarity { /// The waveform output goes from high to low on a match 0 interrupt and returns high on /// overflow or interval interrupt. @@ -46,14 +46,14 @@ pub enum WavePolarity { LowToHighOnMatch1 = 0b1, } -#[derive(Debug)] #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug)] pub enum WaveEnable { Enable = 0b0, Disable = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct CounterControl { #[bit(6, rw)] wave_polarity: WavePolarity, @@ -76,19 +76,19 @@ pub struct CounterControl { disable: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct Counter { #[bits(0..=15, r)] count: u16, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct RwValue { #[bits(0..=15, rw)] value: u16, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptStatus { /// Even timer overflow interrupt. #[bit(5, r)] @@ -105,7 +105,7 @@ pub struct InterruptStatus { interval: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct InterruptControl { /// Even timer overflow interrupt. #[bit(5, rw)] @@ -122,7 +122,7 @@ pub struct InterruptControl { interval: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct EventControl { /// E_Ov bit. When set to 0, the event timer is disabled and set to 0 when an event timer /// register overflow occurs. Otherwise, continue counting on overflow. @@ -136,7 +136,7 @@ pub struct EventControl { enable: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, debug)] pub struct EventCount { #[bits(0..=15, r)] count: u16, diff --git a/zynq7000/src/uart.rs b/zynq/zynq7000/src/uart.rs similarity index 95% rename from zynq7000/src/uart.rs rename to zynq/zynq7000/src/uart.rs index bedb2f2..de94ff7 100644 --- a/zynq7000/src/uart.rs +++ b/zynq/zynq7000/src/uart.rs @@ -5,6 +5,7 @@ pub const UART_0_BASE: usize = 0xE000_0000; pub const UART_1_BASE: usize = 0xE000_1000; #[bitbybit::bitenum(u3, exhaustive = true)] +#[derive(Debug)] pub enum Parity { Even = 0b000, Odd = 0b001, @@ -55,8 +56,7 @@ pub enum ChMode { RemoteLoopback = 0b11, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct Control { /// Stop transmitter break. #[bit(8, rw)] @@ -87,8 +87,7 @@ pub struct Control { rx_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct Mode { #[bits(8..=9, rw)] chmode: ChMode, @@ -103,35 +102,32 @@ pub struct Mode { clksel: ClockSelect, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0, debug)] pub struct Baudgen { #[bits(0..=15, rw)] cd: u16, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0, debug)] pub struct BaudRateDivisor { #[bits(0..=7, rw)] bdiv: u8, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct Fifo { #[bits(0..=7, rw)] fifo: u8, } #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug)] pub enum Ttrig { LessThanTTrig = 0b0, GreaterEqualTTrig = 0b1, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug)] pub struct Status { #[bit(14, r)] tx_near_full: bool, @@ -230,8 +226,7 @@ pub struct InterruptMask { rx_trg: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug)] pub struct InterruptStatus { #[bit(12, rw)] tx_over: bool, diff --git a/zynq7000/src/xadc.rs b/zynq/zynq7000/src/xadc.rs similarity index 100% rename from zynq7000/src/xadc.rs rename to zynq/zynq7000/src/xadc.rs diff --git a/zynq7000-boot-image/.gitignore b/zynq7000-boot-image/.gitignore new file mode 100644 index 0000000..5a44eef --- /dev/null +++ b/zynq7000-boot-image/.gitignore @@ -0,0 +1 @@ +/Cargo.lock diff --git a/zynq-boot-image/Cargo.toml b/zynq7000-boot-image/Cargo.toml similarity index 84% rename from zynq-boot-image/Cargo.toml rename to zynq7000-boot-image/Cargo.toml index 922b69b..f72493a 100644 --- a/zynq-boot-image/Cargo.toml +++ b/zynq7000-boot-image/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "zynq-boot-image" +name = "zynq7000-boot-image" version = "0.1.0" edition = "2024" diff --git a/zynq-boot-image/src/lib.rs b/zynq7000-boot-image/src/lib.rs similarity index 100% rename from zynq-boot-image/src/lib.rs rename to zynq7000-boot-image/src/lib.rs diff --git a/zynq-boot-image/staging/.gitignore b/zynq7000-boot-image/staging/.gitignore similarity index 100% rename from zynq-boot-image/staging/.gitignore rename to zynq7000-boot-image/staging/.gitignore diff --git a/zynq-boot-image/staging/README.md b/zynq7000-boot-image/staging/README.md similarity index 100% rename from zynq-boot-image/staging/README.md rename to zynq7000-boot-image/staging/README.md diff --git a/zynq-boot-image/staging/boot.bif b/zynq7000-boot-image/staging/boot.bif similarity index 100% rename from zynq-boot-image/staging/boot.bif rename to zynq7000-boot-image/staging/boot.bif diff --git a/zynq7000-rt/Cargo.lock b/zynq7000-rt/Cargo.lock deleted file mode 100644 index d536135..0000000 --- a/zynq7000-rt/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "zynq-rt" -version = "0.1.0"