123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #!/usr/bin/env python3
- # SPDX-License-Identifier: Apache-2.0
- import subprocess
- import tempfile
- import argparse
- import os
- import string
- import sys
- 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:
- sys.exit(cpe.output.decode("utf-8") +
- "\nFailed to create POF file")
- 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:
- sys.exit(cpe.output.decode("utf-8") +
- "\nFailed to flash image")
- 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()
|