From 1d298b547d23f9869688be4522327200a6905550 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Feb 2025 18:27:35 +0100 Subject: [PATCH] startup works, stepping works --- .gitignore | 1 + Cargo.toml | 2 +- memory.x | 4 +- src/main.rs | 3 +- vscode/launch.json | 19 +++++ vscode/tasks.json | 43 +++++++++++ zynq7000-rt/src/rt.rs | 164 +++++++++++++++++++++++++++--------------- 7 files changed, 174 insertions(+), 62 deletions(-) create mode 100644 vscode/launch.json create mode 100644 vscode/tasks.json diff --git a/.gitignore b/.gitignore index 91b46fa..8e05caf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /app.map /xsct-output.log +/.vscode diff --git a/Cargo.toml b/Cargo.toml index d266929..b03c04d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["zynq7000-rt"] [package] name = "zedboard-blinky-rs" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] cortex-r-a = { path = "../cortex-r-a/cortex-r-a" } diff --git a/memory.x b/memory.x index c2400f8..8a65966 100644 --- a/memory.x +++ b/memory.x @@ -1,8 +1,8 @@ MEMORY { - /* Zedboard: 512 MB DDR3. */ - CODE(rx) : ORIGIN = 0x00100000, LENGTH = 512M + /* Zedboard: 512 MB DDR3. Only use 256 MB for now, should be plenty for a bare-metal app. */ + CODE(rx) : ORIGIN = 0x00100000, LENGTH = 256M } REGION_ALIAS("DATA", CODE); diff --git a/src/main.rs b/src/main.rs index c413e57..9be9b97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use cortex_r_a::asm::nop; use zynq7000_rt as _; /// Entry point (not called like a normal main function) -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn boot_core(cpu_id: u32) -> ! { if cpu_id != 0 { panic!("unexpected CPU ID {}", cpu_id); @@ -14,6 +14,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! { main(); } +#[unsafe(export_name = "main")] pub fn main() -> ! { loop { nop(); diff --git a/vscode/launch.json b/vscode/launch.json new file mode 100644 index 0000000..5d849de --- /dev/null +++ b/vscode/launch.json @@ -0,0 +1,19 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Zedboard", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/target/armv7a-none-eabihf/debug/zedboard-blinky-rs", + "miDebuggerServerAddress": "localhost:3000", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "stopAtEntry": false, + "useExtendedRemote": true, + "cwd": "${workspaceFolder}", + "externalConsole": false, + "MIMode": "gdb", + "preLaunchTask": "zedboard-init-and-flash" + }, + ] +} \ No newline at end of file diff --git a/vscode/tasks.json b/vscode/tasks.json new file mode 100644 index 0000000..9f7a9bf --- /dev/null +++ b/vscode/tasks.json @@ -0,0 +1,43 @@ +{ + "version": "2.0.0", + "options": { + "env": { + "XLNX_TOOLS": "/tools/Xilinx/Vitis/2024.1", + "TCL_SCRIPT": "~/ROMEO/romeo-fpga-designs/zedboard/zed_sdt/ps7_init.tcl", + "BITSTREAM": "~/ROMEO/romeo-fpga-designs/zedboard/zed_sdt/zedboard_wrapper.bit" + } + }, + "tasks": [ + { + "label": "zedboard-init-and-flash", + "type": "shell", + "command": "${workspaceFolder}/scripts/zynq7000-ps-pl-init.py", + "args": [ + "--tools", + "${XLNX_TOOLS}", + "--itcl", + "${TCL_SCRIPT}", + "--bit", + "${BITSTREAM}", + "-a", + "${workspaceFolder}/target//armv7a-none-eabihf/debug/zedboard-blinky-rs" + ], + "dependsOn": [ + "cargo-build-zedboard" + ], + "problemMatcher": [], + }, + { + "label": "cargo-build-zedboard", + "type": "shell", + "command": "~/.cargo/bin/cargo", // note: full path to the cargo + "args": [ + "build", + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + ] +} \ No newline at end of file diff --git a/zynq7000-rt/src/rt.rs b/zynq7000-rt/src/rt.rs index 94152cf..648a553 100644 --- a/zynq7000-rt/src/rt.rs +++ b/zynq7000-rt/src/rt.rs @@ -4,7 +4,7 @@ //! [provided by Xilinx](https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexa9/gcc/boot.S) //! as possible. The boot routine includes stack, MMU, cache and .bss/.data section initialization. use cortex_a_rt as _; -use cortex_r_a::register::{Cpsr, cpsr::ProcessorMode}; +use cortex_r_a::register::{cpsr::ProcessorMode, Cpsr}; // Start-up code for Armv7-A // @@ -52,10 +52,10 @@ core::arch::global_asm!( .global _start .type _start, %function _start: - /* only allow cpu0 through */ - /* Read MPIDR */ + // only allow cpu0 through + // Read MPIDR mrc p15,0,r1,c0,c0,5 - /* Extract CPU ID bits. For single-core systems, this should always be 0 */ + // Extract CPU ID bits. For single-core systems, this should always be 0 and r1, r1, #0x3 cmp r1, #0 beq check_efuse @@ -108,57 +108,71 @@ initialize: bic r0, r0, #0x1 /* clear bit 0 */ mcr p15, 0, r0, c1, c0, 0 /* write value back */ - /* Set up stacks first, might be required for MMU loader function */ + // Set up stacks first. + ldr r3, =_stack_top - // Set stack pointer (as the top) and mask interrupts for for FIQ mode (Mode 0x11) - ldr r0, =_stack_top - msr cpsr, {fiq_mode} - mov sp, r0 - ldr r1, =_fiq_stack_size - sub r0, r0, r1 - // Set stack pointer (right after) and mask interrupts for for IRQ mode (Mode 0x12) - msr cpsr, {irq_mode} - mov sp, r0 - ldr r1, =_irq_stack_size - sub r0, r0, r1 - // Set stack pointer (right after) and mask interrupts for for SVC mode (Mode 0x13) - msr cpsr, {svc_mode} - mov sp, r0 - ldr r1, =_svc_stack_size - sub r0, r0, r1 - // Set stack pointer (right after) and mask interrupts for for System mode (Mode 0x1F) - msr cpsr, {sys_mode} - mov sp, r0 - // Clear the Thumb Exception bit because we're in Arm mode - mrc p15, 0, r0, c1, c0, 0 - bic r0, #{te_bit} - mcr p15, 0, r0, c1, c0, 0 + // get the current PSR + mrs r0, cpsr + // mask for mode bits + mvn r1, #0x1f + and r2, r1, r0 + // IRQ mode + orr r2, r2, {irq_mode} + msr cpsr, r2 + // IRQ stack pointer + mov sp, r3 + ldr r1, =_irq_stack_size + sub r3, r3, r1 - /* Zero BSS and initialize data before calling any function which might require them. */ + mrs r0, cpsr + and r2, r1, r0 + // Supervisor mode + orr r2, r2, {svc_mode} + msr cpsr, r2 + // Supervisor stack pointer + mov sp, r3 + ldr r1, =_svc_stack_size + sub r3, r3, r1 - // Initialise .bss - ldr r0, =__sbss - ldr r1, =__ebss - mov r2, 0 -0: - cmp r1, r0 - beq 1f - stm r0!, {{r2}} - b 0b -1: - // Initialise .data - ldr r0, =__sdata - ldr r1, =__edata - ldr r2, =__sidata -0: - cmp r1, r0 - beq 1f - ldm r2!, {{r3}} - stm r0!, {{r3}} - b 0b -1: + mrs r0, cpsr + and r2, r1, r0 + // Abort mode + orr r2, r2, {abt_mode} + msr cpsr, r2 + // Abort stack pointer + mov sp, r3 + ldr r1, =_abt_stack_size + sub r3, r3, r1 - /* set scu enable bit in scu */ + mrs r0, cpsr + and r2, r1, r0 + // FIQ mode + orr r2, r2, {fiq_mode} + msr cpsr, r2 + // FIQ stack pointer + mov sp, r3 + ldr r1, =_fiq_stack_size + sub r3, r3, r1 + + mrs r0, cpsr + and r2, r1, r0 + // Undefined mode + orr r2, r2, {und_mode} + msr cpsr, r2 + // Undefined stack pointer + mov sp, r3 + ldr r1, =_und_stack_size + sub r3, r3, r1 + + mrs r0, cpsr + and r2, r1, r0 + // System mode + orr r2, r2, {sys_mode} + msr cpsr, r2 + // System stack pointer (main stack) + mov sp, r3 + + // set scu enable bit in scu ldr r7, =0xf8f00000 ldr r0, [r7] orr r0, r0, #0x1 @@ -166,7 +180,7 @@ initialize: /* enable MMU and cache */ bl load_mmu_table - + mvn r0,#0 /* Load MMU domains -- all ones=manager */ mcr p15,0,r0,c3,c0,0 @@ -209,7 +223,7 @@ initialize: ldr r0,=L2CCSync /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */ /* Load L2CC base address base + sync register*/ /* poll for completion */ -Sync: +Sync: ldr r1, [r0] cmp r1, #0 bne Sync @@ -260,6 +274,29 @@ Sync: 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. */ + + // Initialise .bss + ldr r0, =__sbss + ldr r1, =__ebss + mov r2, 0 +0: + cmp r1, r0 + beq 1f + stm r0!, {{r2}} + b 0b +1: + // Initialise .data + ldr r0, =__sdata + ldr r1, =__edata + ldr r2, =__sidata +0: + cmp r1, r0 + beq 1f + ldm r2!, {{r3}} + stm r0!, {{r3}} + b 0b +1: // Jump to application // Load CPU ID 0, which will be used as a function argument to the boot_core function. mov r0, #0x0 @@ -268,6 +305,7 @@ Sync: b . .size _start, . - _start +.type _invalidate_dcache, %function invalidate_dcache: mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */ ands r3, r0, #0x7000000 @@ -311,6 +349,7 @@ finished: dsb isb bx lr +.size invalidate_dcache, . - invalidate_dcache "#, fiq_mode = const { Cpsr::new_with_raw_value(0) @@ -333,6 +372,20 @@ finished: .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) @@ -340,9 +393,4 @@ finished: .with_f(true) .raw_value() }, - te_bit = const { - cortex_r_a::register::Sctlr::new_with_raw_value(0) - .with_te(true) - .raw_value() - } );