From f5af939c043fd665315e4653ff3353b7b680d16f Mon Sep 17 00:00:00 2001 From: AndreiGrozav Date: Mon, 26 Nov 2018 16:09:48 +0200 Subject: [PATCH] Add adi make(build) scripts adi_make.tcl -adi_make::lib -adi_make::boot_bin (executes the script adi_make_boot_bin in xsct) adi_make_boot_bin.tcl --- projects/scripts/adi_make.tcl | 293 +++++++++++++++++++++++++ projects/scripts/adi_make_boot_bin.tcl | 201 +++++++++++++++++ 2 files changed, 494 insertions(+) create mode 100644 projects/scripts/adi_make.tcl create mode 100644 projects/scripts/adi_make_boot_bin.tcl diff --git a/projects/scripts/adi_make.tcl b/projects/scripts/adi_make.tcl new file mode 100644 index 000000000..15b67dc87 --- /dev/null +++ b/projects/scripts/adi_make.tcl @@ -0,0 +1,293 @@ +## *************************************************************************** +## *************************************************************************** +## Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +## +## In this HDL repository, there are many different and unique modules, consisting +## of various HDL (Verilog or VHDL) components. The individual modules are +## developed independently, and may be accompanied by separate and unique license +## terms. +## +## The user should read each of these license terms, and understand the +## freedoms and responsibilities that he or she has by using this source/core. +## +## This core is distributed in the hope that it will be useful, but WITHOUT ANY +## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +## A PARTICULAR PURPOSE. +## +## Redistribution and use of source or resulting binaries, with or without modification +## of this file, are permitted under one of the following two license terms: +## +## 1. The GNU General Public License version 2 as published by the +## Free Software Foundation, which can be found in the top level directory +## of this repository (LICENSE_GPL2), and also online at: +## +## +## OR +## +## 2. An ADI specific BSD license, which can be found in the top level directory +## of this repository (LICENSE_ADIBSD), and also on-line at: +## https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +## This will allow to generate bit files and not release the source code, +## as long as it attaches to an ADI device. +## +## *************************************************************************** +## *************************************************************************** + +############################################################################## +## The folowing procedures are available: +## +## adi_make::lib +## -"all"(project libraries) +## -"library name to build (plus path to it relative to library folder) +## e.g.: adi_make_lib xilinx/util_adxcvr +## adi_make::boot_bin - expected that u-boot*.elf (plus bl31.elf for zynq_mp) +## files are in the project folder" +## For more info please see: https://wiki.analog.com/resources/fpga/docs/build + + + +namespace eval adi_make { + ############################################################################## + # to print debug step messages "set debug_msg=1" (set adi_make::debug_msg 1) + variable debug_msg 0 + ############################################################################## + + variable library_dir + variable PWD [pwd] + variable root_hdl_folder + variable done_list "" + variable indent_level "" + + # get library absolute path + set root_hdl_folder "" + set glb_path $PWD + if { [regexp projects $glb_path] } { + regsub {/projects.*$} $glb_path "" root_hdl_folder + } else { + puts "ERROR: Not in hdl/* folder" + return + } + + set library_dir "$root_hdl_folder/library" + + #---------------------------------------------------------------------------- + # have debug messages + proc puts_msg { message } { + variable debug_msg + variable indent_level + if { $debug_msg == 1 } { + puts $indent_level$message + } + } + + #---------------------------------------------------------------------------- + # returns the projects required set of libraries + proc get_libraries {} { + + set build_list "" + + set search_pattern "LIB_DEPS.*=" + set fp1 [open ./Makefile r] + set file_data [read $fp1] + close $fp1 + + set lines [split $file_data \n] + foreach line $lines { + if { [regexp $search_pattern $line] } { + regsub -all $search_pattern $line "" library + set library [string trim $library] + puts_msg "\t- project dep: $library" + append build_list "$library " + } + } + return $build_list + } + + #---------------------------------------------------------------------------- + proc lib { libraries } { + + variable library_dir + variable PWD + variable done_list + + set build_list $libraries + if { $libraries == "all" } { + set build_list "[get_libraries]" + } + + set libraries "" + puts "Building:" + foreach b_lib $build_list { + puts "- $b_lib" + append libraries "$library_dir/$b_lib " + } + + puts "Please wait, this might take a few minutes" + + # searching for subdir libraries in path of the given args + set first_lib [lindex $libraries 0] + if { $first_lib == "" } { + set first_lib "." + } + # getting all (libraries) + set index 0 + set library_element(1) $first_lib + foreach argument $libraries { + incr index 1 + set library_element($index) $argument + } + + # search for all possible IPs in the given argument paths + set makefiles "" + if { $index == 0 } { + set index 1 + } + for {set y 1} {$y<=$index} {incr y} { + set dir "$library_element($y)/" + #search 4 level subdirectories for Makefiles + for {set x 1} {$x<=4} {incr x} { + catch { append makefiles " [glob "${dir}Makefile"]" } err + append dir "*/" + } + } + + if { $makefiles == "" } { + puts "ERROR: Wrong path to IP or the IP does not have a Makefile starting from \"$library_element(1)\"" + } + + # filter out non buildable libs (non *_ip.tcl) + set buildable "" + foreach fs $makefiles { + set lib_dir [file dirname $fs] + set lib_name "[file tail $lib_dir]_ip.tcl" + if { [file exists $lib_dir/$lib_name] } { + append buildable "$fs " + } + } + set makefiles $buildable + + # build all detected IPs + foreach fs $makefiles { + regsub /Makefile $fs "" fs + if { $fs == "." } { + set fs [string trim [file tail [file normalize $fs]]] + } + regsub .*library/ $fs "" fs + build_lib $fs + } + + cd $PWD + set done_list "" + } + + #---------------------------------------------------------------------------- + # IP build procedure + proc build_lib { library } { + + variable done_list + variable library_dir + variable indent_level + + append indent_level "\t" ;# debug messages + + puts_msg "DEBUG build_lib proc (recursive called)" + + # determine if the IP was previously built in the current adi_make_lib.tcl call + if { [regexp $library $done_list] } { + puts_msg "> Build previously done on $library" + regsub . $indent_level "" indent_level + return + } else { + puts_msg "- Start build of $library" + } + puts_msg "- Search dependencies for $library" + + # search for current IP dependencies + + # define library dependency search (Makefiles) + set serch_pattern "XILINX_.*_DEPS.*=" + set dep_list "" + + set fp1 [open $library_dir/$library/Makefile r] + set file_data [read $fp1] + close $fp1 + + set lines [split $file_data \n] + foreach line $lines { + if { [regexp $serch_pattern $line] } { + regsub -all $serch_pattern $line "" lib_dep + set lib_dep [string trim $lib_dep] + puts_msg "\t$library is dependent on $lib_dep" + append dep_list "$lib_dep " + } + } + + foreach lib $dep_list { + build_lib $lib + } + + puts_msg "- Continue build on $library" + set lib_name "[file tail $library]_ip" + + cd $library_dir/${library} + exec vivado -mode batch -source "$library_dir/${library}/${lib_name}.tcl" + file copy -force ./vivado.log ./${lib_name}.log + puts "- Done building $library" + append done_list $library + regsub . $indent_level "" indent_level + } + + #---------------------------------------------------------------------------- + # boot_bin build procedure + proc boot_bin {} { + + variable root_hdl_folder + + set arm_tr_sw_elf "bl31.elf" + set boot_bin_folder "boot_bin" + if {[catch {set hdf_file "[glob "./*.sdk/system_top.hdf"]"} fid]} { + puts stderr "ERROR: $fid\n\rNOTE: you must have built hdl project\n\ + \rSee: https://wiki.analog.com/resources/fpga/docs/build\n" + return + } + if {[catch {set uboot_elf "[glob "./u-boot*.elf"]" } fid]} { + puts stderr "ERROR: $fid\n\rNOTE: you must have a the u-boot.elf in [pwd]\n\ + \rSee: https://wiki.analog.com/resources/fpga/docs/build\n" + return + } + + puts "root_hdl_folder $root_hdl_folder" + puts "uboot_elf $uboot_elf" + puts "hdf_file $hdf_file" + + # determine if Xilinx SDK tools are set in the enviroment + package require platform + set os_type [platform::generic] + if { [regexp ^win $os_type] } { + set w_cmd where + } elseif { [regexp ^linux $os_type] } { + set w_cmd which + } else { + puts "ERROR: Unknown OS: $os_type" + exit 1 + } + set xsct_loc [exec $w_cmd xsct] + + # search for Xilinx Command Line Tool (SDK) + if { $xsct_loc == "" } { + puts $env(PATH) + puts "ERROR: SDK not installed or it is not defined in the enviroment path" + exit 1 + } + + set xsct_script "exec xsct $root_hdl_folder/projects/scripts/adi_make_boot_bin.tcl" + set build_args "$hdf_file $uboot_elf $boot_bin_folder $arm_tr_sw_elf" + puts "Please wait, this may take a few minutes." + eval $xsct_script $build_args + } + +} ;# ad_make namespace + + +############################################################################# +############################################################################# diff --git a/projects/scripts/adi_make_boot_bin.tcl b/projects/scripts/adi_make_boot_bin.tcl new file mode 100644 index 000000000..5b18b6a8c --- /dev/null +++ b/projects/scripts/adi_make_boot_bin.tcl @@ -0,0 +1,201 @@ +## *************************************************************************** +## *************************************************************************** +## Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +## +## In this HDL repository, there are many different and unique modules, consisting +## of various HDL (Verilog or VHDL) components. The individual modules are +## developed independently, and may be accompanied by separate and unique license +## terms. +## +## The user should read each of these license terms, and understand the +## freedoms and responsibilities that he or she has by using this source/core. +## +## This core is distributed in the hope that it will be useful, but WITHOUT ANY +## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +## A PARTICULAR PURPOSE. +## +## Redistribution and use of source or resulting binaries, with or without modification +## of this file, are permitted under one of the following two license terms: +## +## 1. The GNU General Public License version 2 as published by the +## Free Software Foundation, which can be found in the top level directory +## of this repository (LICENSE_GPL2), and also online at: +## +## +## OR +## +## 2. An ADI specific BSD license, which can be found in the top level directory +## of this repository (LICENSE_ADIBSD), and also on-line at: +## https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +## This will allow to generate bit files and not release the source code, +## as long as it attaches to an ADI device. +## +## *************************************************************************** +## *************************************************************************** + +# script name adi_make_boot_bin.tcl + +# -- HELP SECTION -- +# +# This script was designed to work within the Xilinx tool command line interface +# Script arguments: +# 1 - hdf file location (default: ./system_top.hdf) +# 2 - u-boot.elf file location/name (default: ./u-boot.elf) +# 3 - build location (default: pwd: $PWD)" +# 4 - bl31.elf(mp soc projects only) file location +# +# The order of script arguments is mandatory. +# +# Examples: +# - adi_make_boot_bin.tcl +# - adi_make_boot_bin.tcl $hdf_path/system_top.hdf $uboot_path/u-boot.elf +# - adi_make_boot_bin.tcl $hdf_path/system_top.hdf $uboot_path/u-boot.elf $workspace +# - adi_make_boot_bin.tcl $hdf_path/system_top.hdf $uboot_path/u-boot.elf $workspace $arm_trf_repo/bl31.elf + +set PWD [pwd] + +# getting parsed arguments +set app_type "" +set hdf_file "" +set uboot_file "" + +set hdf_file [lindex $argv 0] +set uboot_file [lindex $argv 1] +set build_dir [lindex $argv 2] +set arm_tr_frm_file [lindex $argv 3] + +# hdf file exists +if { $hdf_file == "" } { + set hdf_file system_top.hdf +} +if { ![file exists $hdf_file] } { + puts "ERROR: hdf file is not defined or located in $PWD" + return +} + +# uboot file exists +if { $uboot_file == "" } { + set uboot_file u-boot.elf +} +if { ![file exists $uboot_file] } { + puts "ERROR: uboot file is not defined or located in $PWD" + return +} + +# build dir defined +if { $build_dir == "" } { + set build_dir "boot_bin" +} + +catch { file mkdir $build_dir } err +if { ![file exists $build_dir] } { + puts "ERROR: Failed to create \"$build_dir\" dir" + return +} +file copy -force $hdf_file $build_dir/system_top.hdf +file copy -force $uboot_file $build_dir + +# Zynq MP arm trusted firwmware +if { $app_type == "Zynq MP FSBL" } { + if { $arm_tr_frm_file == "" } { + set arm_tr_frm_file bl31.elf + } + if { ![file exists $arm_tr_frm_file] } { + puts "ERROR: arm trusted firmware (bl31.el) file is not defined or located in $PWD" + } +} + +# get cpu(app_type) +set cpu_name "" +set app_type "" +hsi open_hw_design $build_dir/system_top.hdf +set cpu_name [lindex [hsi get_cells -filter {IP_TYPE==PROCESSOR}] 0] + +if { $cpu_name == ""} { + puts "ERROR: cpu name could not be determine from hdf file" + return +} else { + if { [regexp psu_cortexa53.. $cpu_name] } { + set app_type "Zynq MP FSBL" + } elseif { [regexp ps7_cortexa9.. $cpu_name] } { + set app_type "Zynq FSBL" + } elseif { $cpu_name == "sys_mb" } { + puts "ERROR: boot_bin (first stage boot loader + ...) is design for arm processors" + return + } else { + puts "ERROR: unknown processor \"$cpu_name\" detected in $build_dir/system_top.hdf" + return + } +} +puts "Using CPU $cpu_name" + +# create zynq.bif for target app + +set l_sq_bracket "\[" +set r_sq_bracket "\]" +if { $app_type == "Zynq FSBL" } { + + file delete -force $build_dir/zynq.bif + set zynq_bif [open "$build_dir/zynq.bif" a+] + puts $zynq_bif "the_ROM_image:" + puts $zynq_bif "{" + puts $zynq_bif "${l_sq_bracket}bootloader${r_sq_bracket} ./fsbl_prj/fsbl/Debug/fsbl.elf" + puts $zynq_bif "./system_top.bit" + puts $zynq_bif "$uboot_file" + puts $zynq_bif "}" + close $zynq_bif + +} elseif { $app_type == "Zynq MP FSBL" } { + + file delete -force $build_dir/zynqmp.bif + set zynqmp_bif [open "$build_dir/zynqmp.bif" a+] + puts $zynqmp_bif "the_ROM_image:" + puts $zynqmp_bif "{" + puts $zynqmp_bif "${l_sq_bracket}fsbl_config${r_sq_bracket} a53_x64" + puts $zynqmp_bif "${l_sq_bracket}bootloader${r_sq_bracket} ./fsbl_prj/fsbl/Debug/fsbl.elf" + puts $zynqmp_bif "${l_sq_bracket}pmufw_image${r_sq_bracket} ./pmufw/executable.elf" + puts $zynqmp_bif "${l_sq_bracket}destination_device=pl${r_sq_bracket} ./system_top.bit" + puts $zynqmp_bif "${l_sq_bracket}destination_cpu=a53-0,exception_level=el-3,trustzone${r_sq_bracket} $arm_tr_frm_file" + puts $zynqmp_bif "${l_sq_bracket}destination_cpu=a53-0,exception_level=el-2${r_sq_bracket} $uboot_file" + puts $zynqmp_bif "}" + close $zynqmp_bif + + file delete -force $build_dir/create_pmufw_project.tcl + set pmufw_proj [open "$build_dir/create_pmufw_project.tcl" a+] + puts $pmufw_proj "set hwdsgn ${l_sq_bracket}open_hw_design ./system_top.hdf${r_sq_bracket}" + puts $pmufw_proj "generate_app -hw \$hwdsgn -os standalone -proc psu_pmu_0 -app zynqmp_pmufw -compile -sw pmufw -dir pmufw" + puts $pmufw_proj "quit" + close $pmufw_proj + +} else { + puts "ERROR: unknown \"$app_type\" when creating zynqx.bif " + return -level 0 -code error +} + +# create fsbl_build.tcl script +file delete -force $build_dir/fsbl_build.tcl +set fsbl_build [open "$build_dir/fsbl_build.tcl" a+] +puts $fsbl_build "hsi open_hw_design system_top.hdf" +puts $fsbl_build "setws ./fsbl_prj" +puts $fsbl_build "createhw -name hw -hwspec system_top.hdf" +puts $fsbl_build "createapp -name fsbl -app \"$app_type\" -proc $cpu_name -bsp bsp -hwproject hw -os standalone -lang C" +puts $fsbl_build "projects -build -type all\n" +close $fsbl_build + +cd $build_dir +file delete -force fsbl_prj +file delete -force pmufw + +exec xsdk -batch -source fsbl_build.tcl -wait + +if { $app_type == "Zynq FSBL" } { + exec bootgen -image zynq.bif -w -o i BOOT.BIN +} elseif { $app_type == "Zynq MP FSBL" } { + exec hsi -source create_pmufw_project.tcl + exec bootgen -image zynqmp.bif -arch zynqmp -o BOOT.BIN -w +} + +puts "adi_make_boot_bin.tcl done: $build_dir/BOOT.BIN" + +## *************************************************************************** +## ***************************************************************************