Compare commits

...

21 Commits

Author SHA1 Message Date
muellerr a58d398d82 Merge pull request 'prepare zedboard BSP release' (#44) from prepare-zedboard-bsp-release into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #44
2026-02-14 19:37:31 +01:00
muellerr fd178e1d3b prepare zedboard BSP release
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-14 19:30:13 +01:00
muellerr e8a6c88e2b Merge pull request 'prepare zynq7000-embassy release' (#43) from prepare-zynq7000-embassy-release into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #43
2026-02-14 19:23:53 +01:00
muellerr 8606bcbd63 prepare zynq7000-embassy release
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
2026-02-14 19:23:38 +01:00
muellerr 2b6e27875f re-generate lock file
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
2026-02-14 19:15:43 +01:00
muellerr fa6f7d836e Merge pull request 'prepare zynq-mmu v0.1.2' (#42) from zynq-mmu-release into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #42
2026-02-14 19:10:59 +01:00
muellerr b7093706f5 prepare zynq-mmu v0.1.2
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-14 19:10:32 +01:00
Robin Mueller 56131100e7 Merge pull request #2 from us-irs/prep-rt-patch-release
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
zynq7000-rt v0.2.0
2026-02-14 18:56:23 +01:00
Robin Mueller 9357464db0 zynq7000-rt v0.2.0
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
2026-02-14 18:54:23 +01:00
muellerr 79161ffe58 Merge pull request 'try allowing hw server ip' (#41) from try-allowing-setting-hw-server-ip into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #41
2026-02-14 17:49:09 +01:00
muellerr 7c3051db46 try allowing hw server ip
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-14 17:48:56 +01:00
muellerr 89ee6d7451 Merge pull request 'improve SPI implemenetation' (#40) from improve-spi-implementation into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #40
2026-02-14 17:45:36 +01:00
muellerr 3b23e9be05 Merge pull request 'division by zero check to avoid panic' (#39) from mohr/div_zero into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #39
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2026-02-14 17:45:20 +01:00
muellerr d34143ceef improve SPI implemenetation
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-12 16:56:13 +01:00
mohr 1abbe7b9c9 division by zero check to avoid panic
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-11 12:06:21 +01:00
muellerr 802ba665c7 Merge pull request 'bugfix for PL programming routine' (#38) from pl-programming-bugfix into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #38
2026-02-07 01:36:05 +01:00
muellerr 3ba6c63554 bugfix for PL programming routine
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-07 01:35:27 +01:00
Robin Mueller e3a05cc650 Merge pull request #1 from adamgreig/fixes
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Fix typos in zynq7000-hal
2026-02-04 14:04:41 +01:00
Adam Greig 0583c9231d Fix typos in zynq7000-hal 2026-02-03 22:39:23 +00:00
muellerr 4ec2f2bae3 Merge pull request 'bumped aarch32 dependencies' (#37) from bump-aarch32-crates into main
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
Reviewed-on: #37
2026-02-02 15:40:03 +01:00
muellerr 0d6713f248 bumped aarch32 dependencies
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
2026-02-02 15:39:18 +01:00
36 changed files with 275 additions and 300 deletions
+1
View File
@@ -10,3 +10,4 @@
# running the application. You only need to do this once for unchanged bitstream as long as you
# do not reset the whole board.
# ZYNQ_BITSTREAM = "/home/$user/$project/$sdt_dir/bitstream.bit"
# HW_SERVER_IP = "localhost"
+1 -1
View File
@@ -9,7 +9,7 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
license = "MIT OR Apache-2.0"
[dependencies]
aarch32-cpu = { version = "0.1" }
aarch32-cpu = { version = "0.2" }
zynq7000-rt = { path = "../../zynq7000-rt" }
zynq7000 = { path = "../../zynq7000" }
zynq7000-hal = { path = "../../zynq7000-hal", features = ["defmt"] }
+5
View File
@@ -4,12 +4,17 @@ MEMORY
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*/
/* CODE(rx) : ORIGIN = 0x00100000, LENGTH = 62M */
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 192K
/* STACK: ORIGIN = 0x3F00000, LENGTH = 1M */
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
}
REGION_ALIAS("VECTORS", CODE);
REGION_ALIAS("DATA", CODE);
/* Use the upper OCM as the stack */
REGION_ALIAS("STACKS", OCM_UPPER);
SECTIONS
{
+1 -1
View File
@@ -11,7 +11,7 @@ keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"]
categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
aarch32-cpu = { version = "0.1", features = ["critical-section-single-core"] }
aarch32-cpu = { version = "0.2", features = ["critical-section-single-core"] }
zynq7000-rt = { path = "../../zynq7000-rt" }
zynq7000 = { path = "../../zynq7000" }
zynq7000-hal = { path = "../../zynq7000-hal" }
+6 -4
View File
@@ -1,10 +1,12 @@
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
/* Zedboard: 512 MB DDR3. Only use 62 MB for now, should be plenty for a bare-metal app.
1 MB stack memory and 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 = 62M
STACKS : ORIGIN = 0x3F00000, LENGTH = 1M
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
}
REGION_ALIAS("VECTORS", CODE);
+1 -1
View File
@@ -9,7 +9,7 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
license = "MIT OR Apache-2.0"
[dependencies]
aarch32-cpu = { version = "0.1" }
aarch32-cpu = { version = "0.2" }
zynq7000-rt = { path = "../../zynq7000-rt" }
zynq7000 = { path = "../../zynq7000" }
zynq7000-hal = { path = "../../zynq7000-hal" }
+6 -4
View File
@@ -1,10 +1,12 @@
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
/* Zedboard: 512 MB DDR3. Only use 62 MB for now, should be plenty for a bare-metal app.
1 MB stack memory and 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 = 62M
STACKS : ORIGIN = 0x3F00000, LENGTH = 1M
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
}
REGION_ALIAS("VECTORS", CODE);
+5 -5
View File
@@ -11,7 +11,7 @@ keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"]
categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
aarch32-cpu = { version = "0.1" }
aarch32-cpu = { version = "0.2" }
zynq7000-rt = { path = "../../zynq7000-rt" }
zynq7000 = { path = "../../zynq7000" }
zynq7000-hal = { path = "../../zynq7000-hal" }
@@ -22,23 +22,23 @@ l3gd20 = { git = "https://github.com/us-irs/l3gd20.git", branch = "add-async-if"
embedded-io = "0.7"
bitbybit = "1.4"
arbitrary-int = "2"
embedded-io-async = "0.6"
embedded-io-async = "0.7"
critical-section = "1"
static_cell = "2"
embedded-alloc = "0.6"
embedded-alloc = "0.7"
embedded-hal = "1"
embedded-hal-async = "1"
fugit = "0.3"
log = "0.4"
rand = { version = "0.9", default-features = false, features = ["small_rng"] }
embassy-executor = { git = "https://github.com/us-irs/embassy.git", branch = "cortex-ar-update", features = [
embassy-executor = { git = "https://github.com/us-irs/embassy.git", rev = "fd40f3e2f2efb67434a9e7d90eb35a30e30d1736", 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"] }
embassy-net = { version = "0.7", features = ["dhcpv4", "packet-trace", "medium-ethernet", "icmp", "tcp", "udp"] }
embassy-net = { version = "0.8", features = ["dhcpv4", "packet-trace", "medium-ethernet", "icmp", "tcp", "udp"] }
embassy-sync = { version = "0.7" }
# TODO: Bump as soon as new compatible smoltcp/embassy-net version is released.
heapless = "0.8"
+6 -4
View File
@@ -1,10 +1,12 @@
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
/* Zedboard: 512 MB DDR3. Only use 62 MB for now, should be plenty for a bare-metal app.
1 MB stack memory and 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 = 62M
STACKS : ORIGIN = 0x3F00000, LENGTH = 1M
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
}
REGION_ALIAS("VECTORS", CODE);
@@ -373,9 +373,9 @@ async fn main(spawner: Spawner) -> ! {
let tcp_socket = TcpSocket::new(stack, RX_TCP_BUFS.take(), TX_TCP_BUFS.take());
// Spawn all embassy tasks.
spawner.spawn(embassy_net_task(runner)).unwrap();
spawner.spawn(udp_task(udp_socket)).unwrap();
spawner.spawn(tcp_task(tcp_socket)).unwrap();
spawner.spawn(embassy_net_task(runner).unwrap());
spawner.spawn(udp_task(udp_socket).unwrap());
spawner.spawn(tcp_task(tcp_socket).unwrap());
let mut mio_led = Output::new_for_mio(gpio_pins.mio.mio7, PinState::Low);
@@ -155,7 +155,7 @@ async fn main(spawner: Spawner) -> ! {
}
}
spawner.spawn(logger_task(uart)).unwrap();
spawner.spawn(logger_task(uart).unwrap());
if BLOCKING {
blocking_application(mio_led, emio_leds, spi).await;
} else {
@@ -284,20 +284,20 @@ async fn main(spawner: Spawner) -> ! {
.replace(uart16550_prod);
RX_UART_0.borrow(cs).borrow_mut().replace(uart_0_rx);
});
spawner.spawn(led_task(mio_led, emio_leds)).unwrap();
spawner.spawn(led_task(mio_led, emio_leds).unwrap());
match UART_MODE {
UartMode::Uart0ToUartlite => {
spawner.spawn(uartlite_task(uartlite_tx)).unwrap();
spawner.spawn(uart_0_task(uart_0_tx)).unwrap();
spawner.spawn(uartlite_task(uartlite_tx).unwrap());
spawner.spawn(uart_0_task(uart_0_tx).unwrap());
}
UartMode::Uart0ToUart16550 => {
spawner.spawn(uart_0_task(uart_0_tx)).unwrap();
spawner.spawn(uart_16550_task(uart_16550_tx)).unwrap();
spawner.spawn(uart_0_task(uart_0_tx).unwrap());
spawner.spawn(uart_16550_task(uart_16550_tx).unwrap());
}
UartMode::UartliteToUart16550 => {
spawner.spawn(uartlite_task(uartlite_tx)).unwrap();
spawner.spawn(uart_16550_task(uart_16550_tx)).unwrap();
spawner.spawn(uartlite_task(uartlite_tx).unwrap());
spawner.spawn(uart_16550_task(uart_16550_tx).unwrap());
}
}
let mut read_buf: [u8; RB_SIZE] = [0; RB_SIZE];
+1 -1
View File
@@ -12,7 +12,7 @@ categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
zynq7000 = { path = "../zynq7000", version = "0.1" }
zynq7000-hal = { path = "../zynq7000-hal", version = "0.1" }
bitbybit = "1.4"
bitbybit = "2"
arbitrary-int = "2"
num_enum = { version = "0.7", default-features = false }
thiserror = { version = "2", default-features = false }
+1 -1
View File
@@ -9,7 +9,7 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
license = "MIT OR Apache-2.0"
[dependencies]
aarch32-cpu = { version = "0.1", features = ["critical-section-single-core"] }
aarch32-cpu = { version = "0.2", features = ["critical-section-single-core"] }
zynq7000-rt = { path = "../zynq7000-rt" }
zynq7000 = { path = "../zynq7000" }
zynq7000-hal = { path = "../zynq7000-hal" }
+4 -2
View File
@@ -1,7 +1,7 @@
MEMORY
{
/* The Zynq7000 has 192 kB of OCM memory which can be used for the FSBL */
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 192K
/* The Zynq7000 has 256 kB of OCM memory of which 196 kB can be used for the FSBL */
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 196K
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
/* Leave 1 MB of memory which will be configured as uncached device memory by the MMU. This can
be used for something like DMA descriptors, but the DDR needs to be set up first in addition
@@ -11,6 +11,8 @@ MEMORY
REGION_ALIAS("VECTORS", CODE);
REGION_ALIAS("DATA", CODE);
/* Use the upper OCM as the stack */
REGION_ALIAS("STACKS", OCM_UPPER);
SECTIONS
{
+1 -1
View File
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
aarch32-cpu = { version = "0.1", features = ["critical-section-single-core"] }
aarch32-cpu = { version = "0.2", features = ["critical-section-single-core"] }
zynq7000-rt = { path = "../zynq7000-rt" }
zynq7000 = { path = "../zynq7000" }
zynq7000-hal = { path = "../zynq7000-hal" }
+6 -4
View File
@@ -1,9 +1,11 @@
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
/* Zedboard: 512 MB DDR3. Only use 62 MB for now, should be plenty for a bare-metal app.
1 MB stack memory and 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 = 62M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
STACKS : ORIGIN = 0x3F00000, LENGTH = 1M
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
}
+2 -2
View File
@@ -8,9 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v0.1.0] 2025-10-09
# [v0.1.0] 2026-02-14
Initial release
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/v0.1.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-embassy-v0.1.0...HEAD
[v0.1.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/tag/zynq7000-embassy-v0.1.0
+1
View File
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Changed
- Added division by zero check in gtc frequency_to_ticks to avoid runtime panic
- Increased UART type safety by providing dedicated MIO constructors for UART 0 and UART 1
respectively.
- Several bugfixes and improvements for GIC module. Some of the registers previously were
+2 -2
View File
@@ -11,12 +11,12 @@ keywords = ["no-std", "hal", "amd", "zynq7000", "bare-metal"]
categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
aarch32-cpu = { version = "0.1" }
aarch32-cpu = { version = "0.2" }
zynq7000 = { path = "../zynq7000", version = "0.1" }
zynq7000-mmu = { path = "../zynq7000-mmu", version = "0.1" }
static_assertions = "1.1"
bitbybit = "1.4"
bitbybit = "2"
arbitrary-int = "2"
thiserror = { version = "2", default-features = false }
num_enum = { version = "0.7", default-features = false }
+2 -2
View File
@@ -209,7 +209,7 @@ pub fn configure_io_pll(boot_mode: BootMode, pll_config: PllConfig) {
return;
}
// Safety: This will only run at most once because of the atomic boolean check.
unsafe { configure_arm_pll_unchecked(boot_mode, pll_config) };
unsafe { configure_io_pll_unchecked(boot_mode, pll_config) };
}
/// This function configures the DDR PLL based on the provided [PllConfig].
@@ -218,7 +218,7 @@ pub fn configure_ddr_pll(boot_mode: BootMode, pll_config: PllConfig) {
return;
}
// Safety: This will only run at most once because of the atomic boolean check.
unsafe { configure_arm_pll_unchecked(boot_mode, pll_config) };
unsafe { configure_ddr_pll_unchecked(boot_mode, pll_config) };
}
/// This function configures the ARM PLL based on the provided [PllConfig].
+1 -1
View File
@@ -129,7 +129,7 @@ pub mod memtest {
/// This tests writes and reads on a memory block starting at the base address
/// with the size `words` times 4.
pub unsafe fn walking_one_test(base_addr: usize, words: usize) -> Result<(), MemTestError> {
unsafe { walking_value_test(true, base_addr, words) }
unsafe { walking_value_test(false, base_addr, words) }
}
/// # Safety
+7 -3
View File
@@ -53,10 +53,14 @@ pub fn configure_bitstream_non_secure(
val.set_pcap_rate_enable(false);
val
});
devcfg.write_dma_source_addr(bitstream.as_ptr() as u32);
// As specified in the TMR,
// Setting the two LSBs of the source and destination address to 2'b01 indicates to the DevC
// DMA module the last DMA command of an overall transfer
devcfg.write_dma_source_addr(bitstream.as_ptr() as u32 | 0b01);
devcfg.write_dma_dest_addr(0xFFFF_FFFF);
devcfg.write_dma_source_len(bitstream.len() as u32);
devcfg.write_dma_dest_len(bitstream.len() as u32);
devcfg.write_dma_source_len(bitstream.len() as u32 / 4);
devcfg.write_dma_dest_len(bitstream.len() as u32 / 4);
while !devcfg.read_interrupt_status().dma_done() {}
// TODO: Check for errors.
+5 -1
View File
@@ -18,7 +18,11 @@ unsafe impl Send for GlobalTimerCounter {}
/// Convert a frequency to GTC ticks given a clock frequency.
pub const fn frequency_to_ticks(clock: Hertz, frequency: Hertz) -> u32 {
clock.raw().div_ceil(frequency.raw())
if frequency.raw() != 0 {
clock.raw().div_ceil(frequency.raw())
} else {
0
}
}
impl GlobalTimerCounter {
+48 -31
View File
@@ -18,7 +18,6 @@ use crate::{clocks::IoClocks, slcr::Slcr, time::Hertz};
use arbitrary_int::{prelude::*, u3, u4, u6};
use embedded_hal::delay::DelayNs;
pub use embedded_hal::spi::Mode;
use embedded_hal::spi::SpiBus as _;
use zynq7000::slcr::reset::DualRefAndClockReset;
use zynq7000::spi::{
BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus,
@@ -874,7 +873,7 @@ impl Spi {
fn prepare_generic_blocking_transfer(&mut self, words: &[u8]) -> usize {
// We want to ensure the FIFO is empty for a new transfer. This is the simpler
// implementation for now.
self.flush().unwrap();
self.flush();
// Write this to 1 in any case to allow polling, defensive programming.
self.inner.regs.write_rx_trig(1);
@@ -886,20 +885,14 @@ impl Spi {
self.issue_manual_start_for_manual_cfg();
written
}
}
impl embedded_hal::spi::ErrorType for Spi {
type Error = Infallible;
}
impl embedded_hal::spi::SpiBus for Spi {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
fn read(&mut self, words: &mut [u8]) {
if words.is_empty() {
return Ok(());
return;
}
// We want to ensure the FIFO is empty for a new transfer. This is the simpler
// implementation for now.
self.flush()?;
self.flush();
// Write this to 1 in any case to allow polling, defensive programming.
self.regs().write_rx_trig(1);
@@ -926,13 +919,11 @@ impl embedded_hal::spi::SpiBus for Spi {
write_idx += 1;
}
}
Ok(())
}
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
fn write(&mut self, words: &[u8]) {
if words.is_empty() {
return Ok(());
return;
}
let mut written = self.prepare_generic_blocking_transfer(words);
let mut read_idx = 0;
@@ -954,12 +945,11 @@ impl embedded_hal::spi::SpiBus for Spi {
// We use the FIFO trigger mechanism to determine when we can read all the remaining bytes.
self.regs().write_rx_trig((words.len() - read_idx) as u32);
self.outstanding_rx = true;
Ok(())
}
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
fn transfer(&mut self, read: &mut [u8], write: &[u8]) {
if read.is_empty() {
return Ok(());
return;
}
let mut write_idx = self.prepare_generic_blocking_transfer(write);
let mut read_idx = 0;
@@ -991,13 +981,11 @@ impl embedded_hal::spi::SpiBus for Spi {
writes_finished = write_idx == max_idx;
reads_finished = read_idx == max_idx;
}
Ok(())
}
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
fn transfer_in_place(&mut self, words: &mut [u8]) {
if words.is_empty() {
return Ok(());
return;
}
let mut write_idx = self.prepare_generic_blocking_transfer(words);
let mut read_idx = 0;
@@ -1018,14 +1006,12 @@ impl embedded_hal::spi::SpiBus for Spi {
writes_finished = write_idx == words.len();
reads_finished = read_idx == words.len();
}
Ok(())
}
/// Blocking flush implementation.
fn flush(&mut self) -> Result<(), Self::Error> {
fn flush(&mut self) {
if !self.outstanding_rx {
return Ok(());
return;
}
let rx_trig = self.inner.read_rx_not_empty_threshold();
while !self.inner.read_isr().rx_not_empty() {}
@@ -1034,6 +1020,37 @@ impl embedded_hal::spi::SpiBus for Spi {
});
self.inner.set_rx_fifo_trigger(1).unwrap();
self.outstanding_rx = false;
}
}
impl embedded_hal::spi::ErrorType for Spi {
type Error = Infallible;
}
impl embedded_hal::spi::SpiBus for Spi {
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
Self::read(self, words);
Ok(())
}
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
Self::write(self, words);
Ok(())
}
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
Self::transfer(self, read, write);
Ok(())
}
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
Self::transfer_in_place(self, words);
Ok(())
}
/// Blocking flush implementation.
fn flush(&mut self) -> Result<(), Self::Error> {
Self::flush(self);
Ok(())
}
}
@@ -1067,23 +1084,23 @@ impl<Delay: DelayNs> embedded_hal::spi::SpiDevice for SpiWithHwCs<Delay> {
for op in operations {
match op {
embedded_hal::spi::Operation::Read(items) => {
self.spi.read(items)?;
self.spi.read(items);
}
embedded_hal::spi::Operation::Write(items) => {
self.spi.write(items)?;
self.spi.write(items);
}
embedded_hal::spi::Operation::Transfer(read, write) => {
self.spi.transfer(read, write)?;
self.spi.transfer(read, write);
}
embedded_hal::spi::Operation::TransferInPlace(items) => {
self.spi.transfer_in_place(items)?;
self.spi.transfer_in_place(items);
}
embedded_hal::spi::Operation::DelayNs(delay) => {
self.delay.delay_ns(*delay);
}
}
}
self.spi.flush()?;
self.spi.flush();
self.spi.inner.no_hw_cs();
Ok(())
}
+6 -1
View File
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v0.1.2] 2026-02-14
Bumped `aarch32-cpu` to v0.2
# [v0.1.1] 2025-10-10
Documentation fixes.
@@ -16,6 +20,7 @@ Documentation fixes.
Initial release
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-mmu-v0.1.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-mmu-v0.1.2...HEAD
[v0.1.2]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-mmu-v0.1.1...zynq7000-mmu-v0.1.2
[v0.1.1]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-mmu-v0.1.0...zynq7000-mmu-v0.1.1
[v0.1.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/tag/zynq7000-mmu-v0.1.0
+2 -2
View File
@@ -1,7 +1,7 @@
[package]
name = "zynq7000-mmu"
description = "Zynq7000 MMU structures"
version = "0.1.1"
version = "0.1.2"
edition = "2024"
license = "MIT OR Apache-2.0"
homepage = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
@@ -11,7 +11,7 @@ categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
thiserror = { version = "2", default-features = false }
aarch32-cpu = { version = "0.1" }
aarch32-cpu = { version = "0.2" }
[build-dependencies]
arm-targets = { version = "0.4" }
+5 -1
View File
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v0.2.0] 2026-02-14
Bugfixes in startup assembler code.
## Changed
@@ -17,6 +19,7 @@ Bugfixes in startup assembler code.
- Runtime now calls a `kmain` method similar to the re-export `aarch32-rt` crate.
Former `boot_core` method must be renamed to `kmain`, but it is recommended to use
the `zynq7000-rt::entry` proc macro to annotate the main method.
- Bumped `aarch32-rt` to v0.2 which now requires the `memory.x` file to place the `STACKS` segment
## Fixed
@@ -32,6 +35,7 @@ Documentation fixes.
Initial release
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-rt-v0.1.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-rt-v0.2.0...HEAD
[v0.2.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-rt-v0.1.1...zynq7000-rt-v0.2.0
[v0.1.1]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-rt-v0.1.0...zynq7000-rt-v0.1.1
[v0.1.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/tag/zynq7000-rt-v0.1.0
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "zynq7000-rt"
version = "0.1.1"
version = "0.2.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2024"
description = "Run-time support for the Zynq7000 family of SoCs for running bare-metal applications"
@@ -11,8 +11,8 @@ keywords = ["no-std", "rt", "cortex-a", "amd", "zynq7000"]
categories = ["embedded", "no-std", "hardware-support"]
[dependencies]
aarch32-rt = { version = "0.1", optional = true, features = ["fpu-d32"] }
aarch32-cpu = { version = "0.1" }
aarch32-rt = { version = "0.2", optional = true, features = ["fpu-d32"] }
aarch32-cpu = { version = "0.2" }
arbitrary-int = "2"
zynq7000-mmu = { path = "../zynq7000-mmu", version = "0.1" }
+112 -194
View File
@@ -5,7 +5,6 @@
//! but does NOT provide the L2 cache initialization.
//!
//! The boot routine includes stack, MMU and .bss/.data section initialization.
use aarch32_cpu::register::{Cpsr, cpsr::ProcessorMode};
use aarch32_rt as _;
// Start-up code for Armv7-A
@@ -13,23 +12,23 @@ use aarch32_rt as _;
// We set up our stacks and `kmain` in system mode.
core::arch::global_asm!(
r#"
.set PSS_L2CC_BASE_ADDR, 0xF8F02000
.set PSS_SLCR_BASE_ADDR, 0xF8000000
.set PSS_L2CC_BASE_ADDR, 0xF8F02000
.set PSS_SLCR_BASE_ADDR, 0xF8000000
.set SLCRlockReg, (PSS_SLCR_BASE_ADDR + 0x04) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_LOCK_OFFSET)*/
.set SLCRUnlockReg, (PSS_SLCR_BASE_ADDR + 0x08) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_UNLOCK_OFFSET)*/
.set SLCRL2cRamReg, (PSS_SLCR_BASE_ADDR + 0xA1C) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_L2C_RAM_OFFSET)*/
.set SLCRCPURSTReg, (0xF8000000 + 0x244) /*(XPS_SYS_CTRL_BASEADDR + A9_CPU_RST_CTRL_OFFSET)*/
.set EFUSEStatus, (0xF800D000 + 0x10) /*(XPS_EFUSE_BASEADDR + EFUSE_STATUS_OFFSET)*/
.set SLCRlockReg, (PSS_SLCR_BASE_ADDR + 0x04) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_LOCK_OFFSET)*/
.set SLCRUnlockReg, (PSS_SLCR_BASE_ADDR + 0x08) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_UNLOCK_OFFSET)*/
.set SLCRL2cRamReg, (PSS_SLCR_BASE_ADDR + 0xA1C) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_L2C_RAM_OFFSET)*/
.set SLCRCPURSTReg, (0xF8000000 + 0x244) /*(XPS_SYS_CTRL_BASEADDR + A9_CPU_RST_CTRL_OFFSET)*/
.set EFUSEStatus, (0xF800D000 + 0x10) /*(XPS_EFUSE_BASEADDR + EFUSE_STATUS_OFFSET)*/
.set CRValMmuCac, 0b01000000000101 /* Enable IDC, and MMU */
.set CRValHiVectorAddr, 0b10000000000000 /* Set the Vector address to high, 0xFFFF0000 */
.set CRValMmuCac, 0b01000000000101 /* Enable IDC, and MMU */
.set CRValHiVectorAddr, 0b10000000000000 /* Set the Vector address to high, 0xFFFF0000 */
.set SLCRlockKey, 0x767B /* SLCR lock key */
.set SLCRUnlockKey, 0xDF0D /* SLCR unlock key */
.set SLCRlockKey, 0x767B /* SLCR lock key */
.set SLCRUnlockKey, 0xDF0D /* SLCR unlock key */
.set SLCRL2cRamConfig, 0x00020202 /* SLCR L2C ram configuration */
.set FPEXC_EN, 0x40000000 /* FPU enable bit, (1 << 30) */
.set FPEXC_EN, 0x40000000 /* FPU enable bit, (1 << 30) */
.section .text.startup
.align 0
@@ -39,137 +38,98 @@ core::arch::global_asm!(
_start:
// only allow cpu0 through
// Read MPIDR
mrc p15,0,r1,c0,c0,5
mrc p15,0,r1,c0,c0,5
// Extract CPU ID bits. For single-core systems, this should always be 0
and r1, r1, #0x3
cmp r1, #0
beq check_efuse
b initialize
and r1, r1, #0x3
cmp r1, #0
beq check_efuse
b initialize
// Zynq specific code. It is recommended to reset CPU1 according to page 160 of the datasheet
check_efuse:
ldr r0,=EFUSEStatus
ldr r1,[r0] /* Read eFuse setting */
ands r1,r1,#0x80 /* Check whether device is having single core */
beq initialize
ldr r0, =EFUSEStatus
// Read eFuse setting
ldr r1, [r0]
// Check whether device is having single core
ands r1,r1,#0x80
beq initialize
/* single core device, reset cpu1 */
ldr r0,=SLCRUnlockReg /* Load SLCR base address base + unlock register */
ldr r1,=SLCRUnlockKey /* set unlock key */
str r1, [r0] /* Unlock SLCR */
ldr r0,=SLCRCPURSTReg
ldr r1,[r0] /* Read CPU Software Reset Control register */
orr r1,r1,#0x22
str r1,[r0] /* Reset CPU1 */
ldr r0,=SLCRCPURSTReg
ldr r1,[r0] /* Read CPU Software Reset Control register */
orr r1,r1,#0x22
str r1,[r0] /* Reset CPU1 */
ldr r0,=SLCRlockReg /* Load SLCR base address base + lock register */
ldr r1,=SLCRlockKey /* set lock key */
str r1, [r0] /* lock SLCR */
ldr r0,=SLCRlockReg /* Load SLCR base address base + lock register */
ldr r1,=SLCRlockKey /* set lock key */
str r1, [r0] /* lock SLCR */
initialize:
mrc p15, 0, r0, c0, c0, 0 /* Get the revision */
mrc p15, 0, r0, c0, c0, 0 /* Get the revision */
and r5, r0, #0x00f00000
and r6, r0, #0x0000000f
orr r6, r6, r5, lsr #20-4
/* set VBAR to the _vector_table address in linker script */
ldr r0, =_vector_table
mcr p15, 0, r0, c12, c0, 0
ldr r0, =_vector_table
mcr p15, 0, r0, c12, c0, 0
/* Invalidate scu */
ldr r7, =0xf8f0000c
ldr r6, =0xffff
str r6, [r7]
ldr r7, =0xf8f0000c
ldr r6, =0xffff
str r6, [r7]
/* Invalidate caches and TLBs */
mov r0,#0 /* r0 = 0 */
mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */
mcr p15, 0, r0, c7, c5, 0 /* invalidate icache */
mcr p15, 0, r0, c7, c5, 6 /* Invalidate branch predictor array */
bl invalidate_dcache /* invalidate dcache */
mov r0,#0 /* r0 = 0 */
mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */
mcr p15, 0, r0, c7, c5, 0 /* invalidate icache */
mcr p15, 0, r0, c7, c5, 6 /* Invalidate branch predictor array */
bl invalidate_dcache /* invalidate dcache */
/* Disable MMU, if enabled */
mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 */
bic r0, r0, #0x1 /* clear bit 0 */
mcr p15, 0, r0, c1, c0, 0 /* write value back */
mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 */
bic r0, r0, #0x1 /* clear bit 0 */
mcr p15, 0, r0, c1, c0, 0 /* write value back */
// Set up stacks first.
ldr r3, =_stack_top
// Set stack pointer (right after) and mask interrupts for IRQ mode (Mode 0x12)
msr cpsr_c, {irq_mode}
// IRQ stack pointer
mov sp, r3
ldr r1, =_irq_stack_size
sub r3, r3, r1
// Set stack pointer (right after) and mask interrupts for Supervisor/SVC mode (Mode 0x13)
msr cpsr_c, {svc_mode}
// Supervisor stack pointer
mov sp, r3
ldr r1, =_svc_stack_size
sub r3, r3, r1
// Set stack pointer (right after) and mask interrupts for Abort/ABT mode (Mode 0x17)
msr cpsr_c, {abt_mode}
// Abort stack pointer
mov sp, r3
ldr r1, =_abt_stack_size
sub r3, r3, r1
// Set stack pointer (right after) and mask interrupts for FIQ mode (Mode 0x11)
msr cpsr_c, {fiq_mode}
// FIQ stack pointer
mov sp, r3
ldr r1, =_fiq_stack_size
sub r3, r3, r1
// Set stack pointer (right after) and mask interrupts for Undefined/UND mode (Mode 0x1B)
msr cpsr_c, {und_mode}
// Undefined stack pointer
mov sp, r3
ldr r1, =_und_stack_size
sub r3, r3, r1
// Set stack pointer (right after) and mask interrupts for System/SYS mode (Mode 0x1F)
msr cpsr_c, {sys_mode}
// System stack pointer (main stack)
mov sp, r3
bl _stack_setup_preallocated
// set scu enable bit in scu
ldr r7, =0xf8f00000
ldr r0, [r7]
orr r0, r0, #0x1
str r0, [r7]
ldr r7, =0xf8f00000
ldr r0, [r7]
orr r0, r0, #0x1
str r0, [r7]
/* Write to ACTLR */
mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR*/
orr r0, r0, #(0x01 << 6) /* set SMP bit */
orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */
mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/
mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR*/
orr r0, r0, #(0x01 << 6) /* set SMP bit */
orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */
mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/
mov r0, r0
mrc p15, 0, r1, c1, c0, 2 /* read cp access control register (CACR) into r1 */
orr r1, r1, #(0xf << 20) /* enable full access for p10 & p11 */
mcr p15, 0, r1, c1, c0, 2 /* write back into CACR */
mov r0, r0
mrc p15, 0, r1, c1, c0, 2 /* read cp access control register (CACR) into r1 */
orr r1, r1, #(0xf << 20) /* enable full access for p10 & p11 */
mcr p15, 0, r1, c1, c0, 2 /* write back into CACR */
/* enable vfp */
fmrx r1, FPEXC /* read the exception register */
orr r1,r1, #FPEXC_EN /* set VFP enable bit, leave the others in orig state */
fmxr FPEXC, r1 /* write back the exception register */
fmrx r1, FPEXC /* read the exception register */
orr r1,r1, #FPEXC_EN /* set VFP enable bit, leave the others in orig state */
fmxr FPEXC, r1 /* write back the exception register */
mrc p15,0,r0,c1,c0,0 /* flow prediction enable */
orr r0, r0, #(0x01 << 11) /* #0x8000 */
mcr p15,0,r0,c1,c0,0
mrc p15,0,r0,c1,c0,0 /* flow prediction enable */
orr r0, r0, #(0x01 << 11) /* #0x8000 */
mcr p15,0,r0,c1,c0,0
mrc p15,0,r0,c1,c0,1 /* read Auxiliary Control Register */
orr r0, r0, #(0x1 << 2) /* enable Dside prefetch */
orr r0, r0, #(0x1 << 1) /* enable L2 Prefetch hint */
mcr p15,0,r0,c1,c0,1 /* write Auxiliary Control Register */
mrc p15,0,r0,c1,c0,1 /* read Auxiliary Control Register */
orr r0, r0, #(0x1 << 2) /* enable Dside prefetch */
orr r0, r0, #(0x1 << 1) /* enable L2 Prefetch hint */
mcr p15,0,r0,c1,c0,1 /* write Auxiliary Control Register */
mrs r0, cpsr /* get the current PSR */
bic r0, r0, #0x100 /* enable asynchronous abort exception */
msr cpsr_xsf, r0
mrs r0, cpsr /* get the current PSR */
bic r0, r0, #0x100 /* enable asynchronous abort exception */
msr cpsr_xsf, r0
/* Zero BSS and initialize data before calling any function which might require them. */
@@ -199,20 +159,20 @@ data_init_done:
/* enable MMU and cache */
/* MMU Table is in .data, so this needs to be performed after .data is relocated */
/* (Even if in most cases, .data is already in RAM and relocation is a no-op) */
bl load_mmu_table
bl load_mmu_table
mvn r0,#0 /* Load MMU domains -- all ones=manager */
mcr p15,0,r0,c3,c0,0
mvn r0,#0 /* Load MMU domains -- all ones=manager */
mcr p15,0,r0,c3,c0,0
/* Enable mmu, icache and dcache */
ldr r0,=CRValMmuCac
mcr p15,0,r0,c1,c0,0 /* Enable cache and MMU */
dsb /* dsb allow the MMU to start up */
isb /* isb flush prefetch buffer */
ldr r0,=CRValMmuCac
mcr p15,0,r0,c1,c0,0 /* Enable cache and MMU */
dsb /* dsb allow the MMU to start up */
isb /* isb flush prefetch buffer */
// Jump to application
// Load CPU ID 0, which will be used as a function argument to the boot_core function.
mov r0, #0x0
mov r0, #0x0
bl kmain
// In case the application returns, loop forever
b .
@@ -220,90 +180,48 @@ data_init_done:
.type _invalidate_dcache, %function
invalidate_dcache:
mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */
ands r3, r0, #0x7000000
mov r3, r3, lsr #23 /* cache level value (naturally aligned) */
beq finished
mov r10, #0 /* start with level 0 */
mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */
ands r3, r0, #0x7000000
mov r3, r3, lsr #23 /* cache level value (naturally aligned) */
beq finished
mov r10, #0 /* start with level 0 */
loop1:
add r2, r10, r10, lsr #1 /* work out 3xcachelevel */
mov r1, r0, lsr r2 /* bottom 3 bits are the Cache type for this level */
and r1, r1, #7 /* get those 3 bits alone */
cmp r1, #2
blt skip /* no cache or only instruction cache at this level */
mcr p15, 2, r10, c0, c0, 0 /* write the Cache Size selection register */
isb /* isb to sync the change to the CacheSizeID reg */
mrc p15, 1, r1, c0, c0, 0 /* reads current Cache Size ID register */
and r2, r1, #7 /* extract the line length field */
add r2, r2, #4 /* add 4 for the line length offset (log2 16 bytes) */
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 /* r4 is the max number on the way size (right aligned) */
clz r5, r4 /* r5 is the bit position of the way size increment */
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 /* r7 is the max number of the index size (right aligned) */
add r2, r10, r10, lsr #1 /* work out 3xcachelevel */
mov r1, r0, lsr r2 /* bottom 3 bits are the Cache type for this level */
and r1, r1, #7 /* get those 3 bits alone */
cmp r1, #2
blt skip /* no cache or only instruction cache at this level */
mcr p15, 2, r10, c0, c0, 0 /* write the Cache Size selection register */
isb /* isb to sync the change to the CacheSizeID reg */
mrc p15, 1, r1, c0, c0, 0 /* reads current Cache Size ID register */
and r2, r1, #7 /* extract the line length field */
add r2, r2, #4 /* add 4 for the line length offset (log2 16 bytes) */
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 /* r4 is the max number on the way size (right aligned) */
clz r5, r4 /* r5 is the bit position of the way size increment */
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 /* r7 is the max number of the index size (right aligned) */
loop2:
mov r9, r4 /* r9 working copy of the max way size (right aligned) */
mov r9, r4 /* r9 working copy of the max way size (right aligned) */
loop3:
orr r11, r10, r9, lsl r5 /* factor in the way number and cache number into r11 */
orr r11, r11, r7, lsl r2 /* factor in the index number */
mcr p15, 0, r11, c7, c6, 2 /* invalidate by set/way */
subs r9, r9, #1 /* decrement the way number */
bge loop3
subs r7, r7, #1 /* decrement the index */
bge loop2
orr r11, r10, r9, lsl r5 /* factor in the way number and cache number into r11 */
orr r11, r11, r7, lsl r2 /* factor in the index number */
mcr p15, 0, r11, c7, c6, 2 /* invalidate by set/way */
subs r9, r9, #1 /* decrement the way number */
bge loop3
subs r7, r7, #1 /* decrement the index */
bge loop2
skip:
add r10, r10, #2 /* increment the cache number */
cmp r3, r10
bgt loop1
add r10, r10, #2 /* increment the cache number */
cmp r3, r10
bgt loop1
finished:
mov r10, #0 /* switch back to cache level 0 */
mcr p15, 2, r10, c0, c0, 0 /* select current cache level in cssr */
mov r10, #0 /* switch back to cache level 0 */
mcr p15, 2, r10, c0, c0, 0 /* select current cache level in cssr */
dsb
isb
bx lr
bx lr
.size invalidate_dcache, . - invalidate_dcache
"#,
fiq_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Fiq)
.with_i(true)
.with_f(true)
.raw_value()
},
irq_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Irq)
.with_i(true)
.with_f(true)
.raw_value()
},
svc_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Svc)
.with_i(true)
.with_f(true)
.raw_value()
},
und_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Und)
.with_i(true)
.with_f(true)
.raw_value()
},
abt_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Abt)
.with_i(true)
.with_f(true)
.raw_value()
},
sys_mode = const {
Cpsr::new_with_raw_value(0)
.with_mode(ProcessorMode::Sys)
.with_i(true)
.with_f(true)
.raw_value()
},
);
+4 -4
View File
@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "aarch32-cpu"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db6700cf01549520abec199376115e1ceb6fde1d1de30064f0f230be8a0c305"
checksum = "1417bbf608824a44cb2fa2ad74b5ec28c0ae4c83df62a4bd2b532bf04c241ade"
dependencies = [
"arbitrary-int 2.0.0",
"arm-targets",
@@ -702,7 +702,7 @@ dependencies = [
[[package]]
name = "zynq7000-mmu"
version = "0.1.1"
version = "0.1.2"
dependencies = [
"aarch32-cpu",
"arm-targets",
@@ -725,7 +725,7 @@ dependencies = [
[[package]]
name = "zynq7000-rt"
version = "0.1.1"
version = "0.2.0"
dependencies = [
"aarch32-cpu",
"arbitrary-int 2.0.0",
+1 -1
View File
@@ -56,4 +56,4 @@ run binary:
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
gdb-multiarch -q -x {{justfile_directory()}}/firmware/gdb.gdb {{binary}} -tui
+6 -4
View File
@@ -1,10 +1,12 @@
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
/* Zedboard: 512 MB DDR3. Only use 62 MB for now, should be plenty for a bare-metal app.
1 MB stack memory and 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 = 62M
STACKS : ORIGIN = 0x3F00000, LENGTH = 1M
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
}
REGION_ALIAS("DATA", CODE);
+5 -2
View File
@@ -1,7 +1,7 @@
MEMORY
{
/* The Zynq7000 has 192 kB of OCM memory which can be used for the FSBL */
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 192K
/* The Zynq7000 has 256 kB of OCM memory of which 196 kB can be used for the FSBL */
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 196K
OCM_UPPER(rx): ORIGIN = 0xFFFF0000, LENGTH = 64K
/* Leave 1 MB of memory which will be configured as uncached device memory by the MMU. This can
be used for something like DMA descriptors, but the DDR needs to be set up first in addition
@@ -9,7 +9,10 @@ MEMORY
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
}
REGION_ALIAS("VECTORS", CODE);
REGION_ALIAS("DATA", CODE);
/* Use the upper OCM as the stack */
REGION_ALIAS("STACKS", OCM_UPPER);
SECTIONS
{
+2 -2
View File
@@ -1,5 +1,5 @@
if {[info exists env(ip_address_hw_server)]} {
set ip $env(ip_address_hw_server)
if {[info exists env(XSCT_HW_SERVER_IP)]} {
set ip $env(XSCT_HW_SERVER_IP)
} else {
set ip "localhost"
}
+5 -4
View File
@@ -22,8 +22,6 @@ def main():
parser.add_argument(
"-t",
"--tools",
# Required only if env var is not set
required=not bool(os.getenv("AMD_TOOLS")),
# Use env var if set
default=os.getenv("AMD_TOOLS"),
help="The path to the tool to use. Must point to a valid Vivado tools installation which"
@@ -43,10 +41,13 @@ def main():
help="No bitstream flashing for initialization with SDT.",
)
parser.add_argument("-a", "--app", dest="app", help="Path to the app to program")
default_ip = os.getenv("HW_SERVER_IP")
if not default_ip:
default_ip = DEFAULT_IP_ADDRESS_HW_SERVER
parser.add_argument(
"-i",
"--ip",
default=DEFAULT_IP_ADDRESS_HW_SERVER,
default=default_ip,
help="The IP address of the hardware server (default: localhost)",
)
parser.add_argument(
@@ -91,7 +92,7 @@ def main():
print(f"The app '{args.app}' does not exist")
sys.exit(1)
os.environ["IP_ADDRESS_HW_SERVER"] = args.ip
os.environ["XSCT_HW_SERVER_IP"] = args.ip
init_tcl = None
bitstream = None
if args.bit: