Introduce Rust FSBL
Some checks failed
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
Some checks failed
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
This commit is contained in:
22
scripts/memory_ddr.x
Normal file
22
scripts/memory_ddr.x
Normal file
@@ -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
|
||||
}
|
||||
24
scripts/memory_ocm.x
Normal file
24
scripts/memory_ocm.x
Normal file
@@ -0,0 +1,24 @@
|
||||
MEMORY
|
||||
{
|
||||
/* The Zynq7000 has 192 kB of OCM memory which can be used for the FSBL */
|
||||
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 192K
|
||||
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
|
||||
to configuring the page at address 0x400_0000 accordingly */
|
||||
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
|
||||
}
|
||||
144
scripts/xsct-flasher.tcl
Normal file
144
scripts/xsct-flasher.tcl
Normal file
@@ -0,0 +1,144 @@
|
||||
if {[info exists env(ip_address_hw_server)]} {
|
||||
set ip $env(ip_address_hw_server)
|
||||
} else {
|
||||
set ip "localhost"
|
||||
}
|
||||
|
||||
# Defaults
|
||||
set init_tcl ""
|
||||
set app ""
|
||||
set bitstream ""
|
||||
|
||||
# Usage helper
|
||||
proc usage {} {
|
||||
puts "Usage: xsct xsct-helper.tcl <init.tcl> \[-a|--app app.elf\] \[-b|--bit design.bit]"
|
||||
puts "Options:"
|
||||
puts " -a, --app Path to application ELF to download"
|
||||
puts " -b, --bit Path to FPGA bitstream (.bit) to program"
|
||||
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 "-a" || $arg eq "--app"} { set expecting app; continue }
|
||||
if {$arg eq "-b" || $arg eq "--bit"} { set expecting bitstream; continue }
|
||||
puts "error: unknown option: $arg"; usage; exit 1
|
||||
}
|
||||
|
||||
# Positional: expect only <init.tcl>
|
||||
if {$init_tcl eq ""} {
|
||||
set init_tcl $arg
|
||||
} else {
|
||||
puts "error: unexpected positional argument: $arg"
|
||||
usage
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# 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 {$app ne ""} {
|
||||
if {![file exists $app]} {
|
||||
puts "error: the app file '$app' does not exist"
|
||||
exit 1
|
||||
}
|
||||
} elseif {[info exists env(APP)]} {
|
||||
if {[file exists $env(APP)]} {
|
||||
set app $env(APP)
|
||||
} else {
|
||||
puts "warning: APP environment variable is set but file does not exist: $env(APP)"
|
||||
}
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
# Check if bitstream is set and the file exists before programming FPGA
|
||||
if {$bitstream eq ""} {
|
||||
puts "Skipping bitstream programming (bitstream argument not set)"
|
||||
} elseif {![file exists $bitstream]} {
|
||||
puts "Error: The bitstream file '$bitstream' does not exist"
|
||||
} else {
|
||||
puts "Set FPGA target with number: $fpga_device_num"
|
||||
target $fpga_device_num
|
||||
|
||||
# Without this delay, the FPGA programming may fail
|
||||
after 1500
|
||||
|
||||
puts "Programming FPGA with bitstream: $bitstream"
|
||||
fpga -f $bitstream
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if {$app ne ""} {
|
||||
puts "Download app $app to target"
|
||||
dow $app
|
||||
puts "Starting app"
|
||||
con
|
||||
}
|
||||
|
||||
puts "Success"
|
||||
@@ -1,86 +0,0 @@
|
||||
if {[info exists env(ip_address_hw_server)]} {
|
||||
set ip $env(ip_address_hw_server)
|
||||
} else {
|
||||
set ip "localhost"
|
||||
}
|
||||
|
||||
set init_tcl ""
|
||||
if {[llength $argv] >= 1} {
|
||||
set init_tcl [lindex $argv 0]
|
||||
} else {
|
||||
puts "error: missing required first argument pointing to initialization TCL script"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if {![file exists $init_tcl]} {
|
||||
puts "the ps init tcl script '$init_tcl' does not exist"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# parse command-line arguments
|
||||
set bitstream ""
|
||||
if {[llength $argv] >= 2} {
|
||||
set bitstream [lindex $argv 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
|
||||
|
||||
# Check if bitstream is set and the file exists before programming FPGA
|
||||
if {$bitstream eq ""} {
|
||||
puts "Skipping bitstream programming (bitstream argument not set)"
|
||||
} elseif {![file exists $bitstream]} {
|
||||
puts "Error: The bitstream file '$bitstream' does not exist"
|
||||
} else {
|
||||
puts "Set FPGA target with number: $fpga_device_num"
|
||||
target $fpga_device_num
|
||||
|
||||
# Without this delay, the FPGA programming may fail
|
||||
after 1500
|
||||
|
||||
puts "Programming FPGA with bitstream: $bitstream"
|
||||
fpga -f $bitstream
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if {[info exists env(APP)] && [file exists $env(APP)]} {
|
||||
puts "Download app $env(APP) to target"
|
||||
dow $env(APP)
|
||||
}
|
||||
|
||||
puts "Successful"
|
||||
@@ -7,7 +7,7 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Define the default values
|
||||
TCL_SCRIPT_NAME = "xsct-init.tcl"
|
||||
TCL_SCRIPT_NAME = "xsct-flasher.tcl"
|
||||
SCRIPTS_DIR = "scripts"
|
||||
DEFAULT_IP_ADDRESS_HW_SERVER = "localhost"
|
||||
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
default=os.getenv("TCL_INIT_SCRIPT"),
|
||||
help="Path to the ps7 initialization TCL file to prepare the processing system.\n"
|
||||
"You can also set the TCL_INIT_SCRIPT env variable to set this.\n"
|
||||
"It is also set implicitely when specifying the SDT folder with --sdt"
|
||||
"It is also set implicitely when specifying the SDT folder with --sdt",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-b",
|
||||
@@ -63,7 +63,7 @@ def main():
|
||||
dest="bit",
|
||||
default=os.getenv("ZYNQ_BITSTREAM"),
|
||||
help="Optional path to the bitstream which will also be programed to the device. It is"
|
||||
" also searched automatically if the --sdt option is used.\n"
|
||||
" also searched automatically if the --sdt option is used.\n",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -91,9 +91,6 @@ def main():
|
||||
print(f"The app '{args.app}' does not exist")
|
||||
sys.exit(1)
|
||||
|
||||
# Export environment variables
|
||||
if args.app:
|
||||
os.environ["APP"] = args.app
|
||||
os.environ["IP_ADDRESS_HW_SERVER"] = args.ip
|
||||
init_tcl = None
|
||||
bitstream = None
|
||||
@@ -136,7 +133,11 @@ def main():
|
||||
# Prepare tcl_args as a list to avoid manual string concatenation issues
|
||||
cmd_list = ["xsct", str(xsct_script), init_tcl]
|
||||
if bitstream:
|
||||
cmd_list.append("--bit")
|
||||
cmd_list.append(bitstream)
|
||||
if args.app:
|
||||
cmd_list.append("--app")
|
||||
cmd_list.append(args.app)
|
||||
|
||||
# Join safely for shell execution
|
||||
xsct_cmd = shlex.join(cmd_list)
|
||||
|
||||
Reference in New Issue
Block a user