startup works, stepping works
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
/app.map
|
/app.map
|
||||||
/xsct-output.log
|
/xsct-output.log
|
||||||
|
/.vscode
|
||||||
|
@ -4,7 +4,7 @@ members = ["zynq7000-rt"]
|
|||||||
[package]
|
[package]
|
||||||
name = "zedboard-blinky-rs"
|
name = "zedboard-blinky-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-r-a = { path = "../cortex-r-a/cortex-r-a" }
|
cortex-r-a = { path = "../cortex-r-a/cortex-r-a" }
|
||||||
|
4
memory.x
4
memory.x
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
/* Zedboard: 512 MB DDR3. */
|
/* Zedboard: 512 MB DDR3. Only use 256 MB for now, should be plenty for a bare-metal app. */
|
||||||
CODE(rx) : ORIGIN = 0x00100000, LENGTH = 512M
|
CODE(rx) : ORIGIN = 0x00100000, LENGTH = 256M
|
||||||
}
|
}
|
||||||
|
|
||||||
REGION_ALIAS("DATA", CODE);
|
REGION_ALIAS("DATA", CODE);
|
||||||
|
@ -6,7 +6,7 @@ use cortex_r_a::asm::nop;
|
|||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
/// Entry point (not called like a normal main function)
|
/// Entry point (not called like a normal main function)
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
||||||
if cpu_id != 0 {
|
if cpu_id != 0 {
|
||||||
panic!("unexpected CPU ID {}", cpu_id);
|
panic!("unexpected CPU ID {}", cpu_id);
|
||||||
@ -14,6 +14,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(export_name = "main")]
|
||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
loop {
|
loop {
|
||||||
nop();
|
nop();
|
||||||
|
19
vscode/launch.json
Normal file
19
vscode/launch.json
Normal file
@ -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"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
43
vscode/tasks.json
Normal file
43
vscode/tasks.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
//! [provided by Xilinx](https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexa9/gcc/boot.S)
|
//! [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.
|
//! as possible. The boot routine includes stack, MMU, cache and .bss/.data section initialization.
|
||||||
use cortex_a_rt as _;
|
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
|
// Start-up code for Armv7-A
|
||||||
//
|
//
|
||||||
@ -52,10 +52,10 @@ core::arch::global_asm!(
|
|||||||
.global _start
|
.global _start
|
||||||
.type _start, %function
|
.type _start, %function
|
||||||
_start:
|
_start:
|
||||||
/* only allow cpu0 through */
|
// only allow cpu0 through
|
||||||
/* Read MPIDR */
|
// 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 */
|
// Extract CPU ID bits. For single-core systems, this should always be 0
|
||||||
and r1, r1, #0x3
|
and r1, r1, #0x3
|
||||||
cmp r1, #0
|
cmp r1, #0
|
||||||
beq check_efuse
|
beq check_efuse
|
||||||
@ -108,57 +108,71 @@ initialize:
|
|||||||
bic r0, r0, #0x1 /* clear bit 0 */
|
bic r0, r0, #0x1 /* clear bit 0 */
|
||||||
mcr p15, 0, r0, c1, c0, 0 /* write value back */
|
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)
|
// get the current PSR
|
||||||
ldr r0, =_stack_top
|
mrs r0, cpsr
|
||||||
msr cpsr, {fiq_mode}
|
// mask for mode bits
|
||||||
mov sp, r0
|
mvn r1, #0x1f
|
||||||
ldr r1, =_fiq_stack_size
|
and r2, r1, r0
|
||||||
sub r0, r0, r1
|
// IRQ mode
|
||||||
// Set stack pointer (right after) and mask interrupts for for IRQ mode (Mode 0x12)
|
orr r2, r2, {irq_mode}
|
||||||
msr cpsr, {irq_mode}
|
msr cpsr, r2
|
||||||
mov sp, r0
|
// IRQ stack pointer
|
||||||
ldr r1, =_irq_stack_size
|
mov sp, r3
|
||||||
sub r0, r0, r1
|
ldr r1, =_irq_stack_size
|
||||||
// Set stack pointer (right after) and mask interrupts for for SVC mode (Mode 0x13)
|
sub r3, r3, r1
|
||||||
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
|
|
||||||
|
|
||||||
/* 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
|
mrs r0, cpsr
|
||||||
ldr r0, =__sbss
|
and r2, r1, r0
|
||||||
ldr r1, =__ebss
|
// Abort mode
|
||||||
mov r2, 0
|
orr r2, r2, {abt_mode}
|
||||||
0:
|
msr cpsr, r2
|
||||||
cmp r1, r0
|
// Abort stack pointer
|
||||||
beq 1f
|
mov sp, r3
|
||||||
stm r0!, {{r2}}
|
ldr r1, =_abt_stack_size
|
||||||
b 0b
|
sub r3, r3, r1
|
||||||
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:
|
|
||||||
|
|
||||||
/* 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 r7, =0xf8f00000
|
||||||
ldr r0, [r7]
|
ldr r0, [r7]
|
||||||
orr r0, r0, #0x1
|
orr r0, r0, #0x1
|
||||||
@ -166,7 +180,7 @@ initialize:
|
|||||||
|
|
||||||
/* enable MMU and cache */
|
/* enable MMU and cache */
|
||||||
bl load_mmu_table
|
bl load_mmu_table
|
||||||
|
|
||||||
mvn r0,#0 /* Load MMU domains -- all ones=manager */
|
mvn r0,#0 /* Load MMU domains -- all ones=manager */
|
||||||
mcr p15,0,r0,c3,c0,0
|
mcr p15,0,r0,c3,c0,0
|
||||||
|
|
||||||
@ -209,7 +223,7 @@ initialize:
|
|||||||
ldr r0,=L2CCSync /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */
|
ldr r0,=L2CCSync /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */
|
||||||
/* Load L2CC base address base + sync register*/
|
/* Load L2CC base address base + sync register*/
|
||||||
/* poll for completion */
|
/* poll for completion */
|
||||||
Sync:
|
Sync:
|
||||||
ldr r1, [r0]
|
ldr r1, [r0]
|
||||||
cmp r1, #0
|
cmp r1, #0
|
||||||
bne Sync
|
bne Sync
|
||||||
@ -260,6 +274,29 @@ Sync:
|
|||||||
bic r0, r0, #0x100 /* enable asynchronous abort exception */
|
bic r0, r0, #0x100 /* enable asynchronous abort exception */
|
||||||
msr cpsr_xsf, r0
|
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
|
// Jump to application
|
||||||
// Load CPU ID 0, which will be used as a function argument to the boot_core function.
|
// Load CPU ID 0, which will be used as a function argument to the boot_core function.
|
||||||
mov r0, #0x0
|
mov r0, #0x0
|
||||||
@ -268,6 +305,7 @@ Sync:
|
|||||||
b .
|
b .
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
||||||
|
|
||||||
|
.type _invalidate_dcache, %function
|
||||||
invalidate_dcache:
|
invalidate_dcache:
|
||||||
mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */
|
mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */
|
||||||
ands r3, r0, #0x7000000
|
ands r3, r0, #0x7000000
|
||||||
@ -311,6 +349,7 @@ finished:
|
|||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
.size invalidate_dcache, . - invalidate_dcache
|
||||||
"#,
|
"#,
|
||||||
fiq_mode = const {
|
fiq_mode = const {
|
||||||
Cpsr::new_with_raw_value(0)
|
Cpsr::new_with_raw_value(0)
|
||||||
@ -333,6 +372,20 @@ finished:
|
|||||||
.with_f(true)
|
.with_f(true)
|
||||||
.raw_value()
|
.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 {
|
sys_mode = const {
|
||||||
Cpsr::new_with_raw_value(0)
|
Cpsr::new_with_raw_value(0)
|
||||||
.with_mode(ProcessorMode::Sys)
|
.with_mode(ProcessorMode::Sys)
|
||||||
@ -340,9 +393,4 @@ finished:
|
|||||||
.with_f(true)
|
.with_f(true)
|
||||||
.raw_value()
|
.raw_value()
|
||||||
},
|
},
|
||||||
te_bit = const {
|
|
||||||
cortex_r_a::register::Sctlr::new_with_raw_value(0)
|
|
||||||
.with_te(true)
|
|
||||||
.raw_value()
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user