#https://www.xilinx.com/support/answers/71921.html
proc copy_psu_init_files {src_folder} {
file mkdir $src_folder
file copy -force psu_init.h $src_folder
file copy -force psu_init.c $src_folder
}
proc package_files {app} {
if {[file isdirectory $app] == 1} {
file mkdir packaged_files/${app}
file copy -force ${app}/executable.elf packaged_files/${app}
}
}
proc boot_files {app} {
if {[file isdirectory $app] == 1} {
file mkdir boot_files/${app}
file copy -force ${app}/executable.elf boot_files/${app}
}
}
#Generate ZynqMP FSBL
proc generate_zynqmp_fsbl {} {
set proc [lindex [get_processor] 0]
set repo [glob -nocomplain -type d repo]
if {$repo != ""} {
hsi::set_repo_path ./repo
}
set fsbl_design [hsi::create_sw_design fsbl_1 -proc $proc -app zynqmp_fsbl]
common::set_property APP_COMPILER "aarch64-none-elf-gcc" $fsbl_design
if {[dev_board] != ""} {
common::set_property -name APP_COMPILER_FLAGS -value "-DRSA_SUPPORT -DFSBL_DEBUG_INFO -DXPS_BOARD_[dev_board]" -objects $fsbl_design
} else {
common::set_property -name APP_COMPILER_FLAGS -value "-DRSA_SUPPORT -DFSBL_DEBUG_INFO" -objects $fsbl_design
}
if {[get_project_info FAMILY] == "zynquplusRFSOC"} {
hsi::add_library libmetal
}
copy_psu_init_files zynqmp_fsbl
hsi::generate_app -dir zynqmp_fsbl -compile
return "zynqmp_fsbl/executable.elf"
}
#Generate Hello World
proc generate_hello_world {} {
set proc [lindex [get_processor] 0]
set repo [glob -nocomplain -type d repo]
if {$repo != ""} {
hsi::set_repo_path ./repo
}
set hello_design [hsi::create_sw_design hello_1 -proc $proc -app hello_world]
if {[get_project_info FAMILY] == "zynquplusRFSOC"} {
hsi::add_library libmetal
}
hsi::generate_app -dir hello_world -compile
return "hello_world/executable.elf"
}
#Generate ZynqMP DRAM test
proc generate_zynqmp_dram_test {} {
if {[ps_ddr_enabled] == 1} {
set proc [lindex [get_processor] 0]
set repo [glob -nocomplain -type d repo]
if {$repo != ""} {
hsi::set_repo_path ./repo
}
set zynqmp_dram_test [hsi::create_sw_design zynqmp_dram_test_1 -proc $proc -app zynqmp_dram_test]
if {[get_project_info FAMILY] == "zynquplusRFSOC"} {
hsi::add_library libmetal
}
hsi::generate_app -dir zynqmp_dram_test -compile
return "zynqmp_dram_test/executable.elf"
} else {
puts "DDRC is not enabled in the PCW \n"
}
}
#Generate ZynqMP PMUFW
proc generate_zynqmp_pmufw {} {
set proc [lindex [get_processor] 1]
set repo [glob -nocomplain -type d repo]
if {$repo != ""} {
hsi::set_repo_path ./repo
}
hsi::generate_app -app zynqmp_pmufw -proc $proc -dir zynqmp_pmufw -compile
return "zynqmp_pmufw/executable.elf"
}
proc dev_board {} {
set board [split [get_project_info BOARD] ":"]
if {[llength $board] > 0} {
return [string toupper [string range [lindex $board 1] 0 5]]
}
}
#to do: update supported apps
proc verify_apps {app} {
set sup_apps ""
foreach supported_app [supported_apps] {
lappend sup_apps $supported_app
}
for {set i 0} {$i < [llength $sup_apps]} {incr i} {
if {$app == [lindex $sup_apps $i]} {
return 1
}
}
return 0
}
proc supported_apps {} {
set apps ""
foreach proc [get_processor] {
foreach temp_app [split [hsi::generate_app -proc $proc -os standalone -sapp] " "] {
lappend apps $temp_app
}
}
return $apps
}
proc is_app {app} {
foreach exist_app [glob -nocomplain -types d *] {
if {$exist_app == $app} {
return 1
}
}
return 0
}
proc get_project_info {info} {
return [common::get_property $info [hsi::current_hw_design]]
}
proc ps_ddr_enabled {} {
if {[get_project_info FAMILY] == "zynquplus" || [get_project_info FAMILY] == "zynquplusRFSOC"} {
return [common::get_property CONFIG.PSU__DDRC__ENABLE [hsi::get_cells -filter {IP_NAME==zynq_ultra_ps_e}]]
} else {
return 0
}
}
proc get_processor {} {
set ret_procs ""
set procs [hsi::get_cells -filter {IP_TYPE==PROCESSOR}]
if {[get_project_info FAMILY] == "zynquplus" || [get_project_info FAMILY] == "zynquplusRFSOC"} {
foreach proc $procs {
if {$proc == "psu_cortexa53_0"} {
lappend ret_procs $proc
} elseif {$proc == "psu_pmu_0"} {
lappend ret_procs $proc
}
}
}
return $ret_procs
}
proc is_enabled {app_list app_test} {
foreach app $app_list {
if {$app == $app_test} {
return 1
}
}
return 0
}
#assumes the target proc is the cortexa53
proc gen_bif {} {
cd boot_files
set apps ""
foreach dir [glob -type d *] {
if {$dir != "zynqmp_fsbl" || $dir != "zynqmp_pmufw"} {
lappend apps $dir
}
}
set fsbl [glob -nocomplain -directory zynqmp_fsbl *.elf]
set bit [glob -nocomplain -directory [pwd] *.bit]
set pmufw [glob -nocomplain -directory zynqmp_pmufw *.elf]
if {$fsbl == ""} {
puts "Error: BIF needs at least the FSBL"
return 0
}
set outputFile [open bootgen.bif w]
puts $outputFile "the_ROM_image:"
puts $outputFile "{"
puts $outputFile "\t\[fsbl_config\] a53_x64"
puts $outputFile "\t\[bootloader\] $fsbl"
if {$pmufw != ""} {
puts $outputFile "\t\[pmufw_image\] $pmufw"
}
if {$bit != ""} {
puts $outputFile "\t\[destination_device = pl\] $bit"
}
puts $outputFile "}"
close $outputFile
exec bootgen -arch zynqmp -image bootgen.bif -o i BOOT.BIN -w on
cd ..
puts "BOOT.BIN file created successfully"
}
#Open HW
proc open_hw {hdf} {
hsi::open_hw_design $hdf
}
#Close HW
proc close_hw {} {
hsi::close_hw_design [hsi::current_hw_design]
}
#Close SW
proc close_sw {} {
hsi::close_sw_design [hsi::current_sw_design]
}
proc build_script {args} {
set filename jtag_boot.tcl
set outputFile [open $filename w]
set apps ""
set force 0
set package 0
set boot 0
for {set i 0} {$i < [llength $args]} {incr i} {
if {[lindex $args $i] == "-hw" } {
set hdf [lindex $args [expr {$i + 1}]]
} elseif {[lindex $args $i] == "-apps" } {
for {set j [expr {$i + 1}]} {$j < [llength $args]} {incr j} {
if {[string range [lindex $args $j] 0 0] != "-"} {
lappend apps [lindex $args $j]
}
}
} elseif {[lindex $args $i] == "-force" } {
set force 1
} elseif {[lindex $args $i] == "-package" } {
set package 1
file mkdir packaged_files
} elseif {[lindex $args $i] == "-boot" } {
set boot 1
file mkdir boot_files
}
}
open_hw $hdf
foreach app $apps {
if {[verify_apps $app] == 1} {
if {[is_app $app] == 1 && $force == 1} {
file delete -force $app
generate_${app}
} elseif {[is_app $app] == 0} {
generate_${app}
} else {
puts "$app already exits, and the -force option not enabled"
}
} else {
puts "$app provided is not supported. No app will be created for this"
puts "Run the supported_apps proc to get a list of all the supported apps for your HDF"
}
}
puts $outputFile "# Set up connection \n"
puts $outputFile "#if this is a remote connection. Then use something like:"
puts $outputFile "#connect -url TCP:XIRSTEPHENM32:3121"
puts $outputFile "#or, if local, then just use"
puts $outputFile "connect"
if {[is_app zynqmp_pmufw] == 1 && [is_enabled $apps zynqmp_pmufw] == 1} {
if {$package == 1} {
package_files zynqmp_pmufw
}
if {$boot == 1} {
boot_files zynqmp_pmufw
}
puts $outputFile "\n# Add the Microblaze PMU to target"
puts $outputFile "targets -set -nocase -filter {name =~ \"PSU\"}"
puts $outputFile "mwr 0xFFCA0038 0x1FF"
puts $outputFile "# Download PMUFW to PMU"
puts $outputFile "target -set -filter {name =~ \"MicroBlaze PMU\"}"
puts $outputFile "dow zynqmp_pmufw/executable.elf"
puts $outputFile "con"
}
set bit [glob -nocomplain -directory [pwd] [file rootname $hdf].bit]
if {$bit != ""} {
if {$package == 1} {
file copy -force $bit packaged_files
}
if {$boot == 1} {
file copy -force $bit boot_files
}
puts $outputFile "\n# Programming PL"
puts $outputFile "fpga -f [file tail $bit]"
}
set fsbl 0
if {[is_app zynqmp_fsbl] == 1 && [is_enabled $apps zynqmp_fsbl] == 1} {
set fsbl 1
if {$package == 1} {
package_files zynqmp_fsbl
}
if {$boot == 1} {
boot_files zynqmp_fsbl
}
puts $outputFile "\n# Download ZYNQMP FSBL to A53 #0"
puts $outputFile "targets -set -nocase -filter {name =~ \"PSU\"}"
puts $outputFile "# write bootloop and release A53-0 reset"
puts $outputFile "mwr 0xffff0000 0x14000000"
puts $outputFile "mwr 0xFD1A0104 0x380E"
puts $outputFile "targets -set -filter {name =~ \"Cortex-A53 #0\"}"
puts $outputFile "dow zynqmp_fsbl/executable.elf"
puts $outputFile "con"
puts $outputFile "after 500"
puts $outputFile "stop"
} else {
if {$package == 1} {
file copy -force psu_init.tcl packaged_files
}
puts $outputFile "\n# Configuring PSU"
puts $outputFile "targets -set -nocase -filter {name =~ \"PSU\"}"
puts $outputFile "source psu_init.tcl"
puts $outputFile "psu_init"
puts $outputFile "after 500"
puts $outputFile "psu_post_config"
puts $outputFile "after 500"
puts $outputFile "psu_ps_pl_reset_config"
puts $outputFile "after 500"
puts $outputFile "psu_ps_pl_isolation_removal"
puts $outputFile "after 500"
}
if {[is_app hello_world] == 1 && [is_enabled $apps hello_world] == 1} {
if {$fsbl == 0} {
set fsbl 1
puts $outputFile "\n# write bootloop and release A53-0 reset"
puts $outputFile "targets -set -nocase -filter {name =~ \"PSU\"}"
puts $outputFile "mwr 0xffff0000 0x14000000"
puts $outputFile "mwr 0xFD1A0104 0x380E"
}
if {$package == 1} {
package_files hello_world
}
puts $outputFile "\n# Download Hello World to A53 #0"
puts $outputFile "targets -set -filter {name =~ \"Cortex-A53 #0\"}"
puts $outputFile "dow hello_world/executable.elf"
puts $outputFile "con"
puts $outputFile "after 500"
puts $outputFile "stop"
}
if {[is_app zynqmp_dram_test] == 1 && [is_enabled $apps zynqmp_dram_test] == 1} {
if {$fsbl == 0} {
set fsbl 1
puts $outputFile "\n# write bootloop and release A53-0 reset"
puts $outputFile "targets -set -nocase -filter {name =~ \"PSU\"}"
puts $outputFile "mwr 0xffff0000 0x14000000"
puts $outputFile "mwr 0xFD1A0104 0x380E"
}
if {$package == 1} {
package_files zynqmp_dram_test
}
puts $outputFile "\n# Download ZYNQMP DRAM Test to A53 #0"
puts $outputFile "targets -set -filter {name =~ \"Cortex-A53 #0\"}"
puts $outputFile "dow zynqmp_dram_test/executable.elf"
puts $outputFile "con"
}
close $outputFile
puts "$filename created successfully"
if {$package == 1} {
file copy -force $filename packaged_files
}
if {$boot == 1} {
gen_bif
}
close_hw
}