zephyr/scripts/support/quartus-flash.py
Andrew Boie 9280e71ea4 nios2: add flashing/debug scripts
For the moment, NIOS2_CPU_SOF must be set with the path to the
CPU configuration. We are checking with Altera on whether we
can directly check in the binary to the source tree.

These scripts depend on tools provided by the Altera Quartus
Prime Lite Edition. This is available for free but requires
registration on Altera's website to obtain.

Change-Id: Ia6cb6c9e43c3e141807a887cb25c47b370a7d8e9
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2016-06-10 15:22:40 +00:00

141 lines
4.3 KiB
Python
Executable file

#!/usr/bin/env python3
import subprocess
import tempfile
import argparse
import os
import string
import sys
import shutil
quartus_cpf_template = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<cof>
<output_filename>${OUTPUT_FILENAME}</output_filename>
<n_pages>1</n_pages>
<width>1</width>
<mode>14</mode>
<sof_data>
<user_name>Page_0</user_name>
<page_flags>1</page_flags>
<bit0>
<sof_filename>${SOF_FILENAME}<compress_bitstream>1</compress_bitstream></sof_filename>
</bit0>
</sof_data>
<version>10</version>
<create_cvp_file>0</create_cvp_file>
<create_hps_iocsr>0</create_hps_iocsr>
<auto_create_rpd>0</auto_create_rpd>
<rpd_little_endian>1</rpd_little_endian>
<options>
<map_file>1</map_file>
</options>
<MAX10_device_options>
<por>0</por>
<io_pullup>1</io_pullup>
<config_from_cfm0_only>0</config_from_cfm0_only>
<isp_source>0</isp_source>
<verify_protect>0</verify_protect>
<epof>0</epof>
<ufm_source>2</ufm_source>
<ufm_filepath>${KERNEL_FILENAME}</ufm_filepath>
</MAX10_device_options>
<advanced_options>
<ignore_epcs_id_check>2</ignore_epcs_id_check>
<ignore_condone_check>2</ignore_condone_check>
<plc_adjustment>0</plc_adjustment>
<post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes>
<post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes>
<bitslice_pre_padding>1</bitslice_pre_padding>
</advanced_options>
</cof>
"""
# XXX Do we care about FileRevision, DefaultMfr, PartName? Do they need
# to be parameters? So far seems to work across 2 different boards, leave
# this alone for now.
quartus_pgm_template = """/* Quartus Prime Version 16.0.0 Build 211 04/27/2016 SJ Lite Edition */
JedecChain;
FileRevision(JESD32A);
DefaultMfr(6E);
P ActionCode(Cfg)
Device PartName(10M50DAF484ES) Path("${POF_DIR}/") File("${POF_FILE}") MfrSpec(OpMask(1));
ChainEnd;
AlteraBegin;
ChainType(JTAG);
AlteraEnd;"""
def create_pof(input_sof, kernel_hex):
"""given an input CPU .sof file and a kernel binary, return a file-like
object containing .pof data suitable for flashing onto the device"""
t = string.Template(quartus_cpf_template)
output_pof = tempfile.NamedTemporaryFile(suffix=".pof")
input_sof = os.path.abspath(input_sof)
kernel_hex = os.path.abspath(kernel_hex)
# These tools are very stupid and freak out if the desired filename
# extensions are used. The kernel image must have extension .hex
with tempfile.NamedTemporaryFile(suffix=".cof") as temp_xml:
xml = t.substitute(SOF_FILENAME=input_sof,
OUTPUT_FILENAME=output_pof.name,
KERNEL_FILENAME=kernel_hex)
temp_xml.write(bytes(xml, 'UTF-8'))
temp_xml.flush()
cmd = ["quartus_cpf", "-c", temp_xml.name]
try:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as cpe:
print(cpe.output.decode("UTF-8"))
print("Failed to create POF file")
sys.exit(1)
return output_pof
def flash_kernel(device_id, input_sof, kernel_hex):
pof_file = create_pof(input_sof, kernel_hex)
with tempfile.NamedTemporaryFile(suffix=".cdf") as temp_cdf:
dname, fname = os.path.split(pof_file.name)
t = string.Template(quartus_pgm_template)
cdf = t.substitute(POF_DIR=dname, POF_FILE=fname)
temp_cdf.write(bytes(cdf, 'UTF-8'))
temp_cdf.flush()
cmd = ["quartus_pgm", "-c", device_id, temp_cdf.name]
try:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as cpe:
print(cpe.output.decode("UTF-8"))
print("Failed to flash image")
sys.exit(1)
pof_file.close()
def main():
parser = argparse.ArgumentParser(description="Flash zephyr onto Altera boards")
parser.add_argument("-s", "--sof",
help=".sof file with Nios II CPU configuration")
parser.add_argument("-k", "--kernel",
help="Zephyr kernel image to place into UFM in Intel HEX format")
parser.add_argument("-d", "--device",
help="Remote device identifier / cable name. Default is "
"USB-BlasterII. Run jtagconfig -n if unsure.",
default="USB-BlasterII")
args = parser.parse_args()
flash_kernel(args.device, args.sof, args.kernel)
if __name__ == "__main__":
main()