forked from M-Labs/artiq
artiq_flash: unify flash handling in XC7 and Sayma programmers.
This commit is contained in:
parent
1ffabac06f
commit
94592c7a4c
|
@ -85,9 +85,24 @@ def proxy_path():
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
def find_proxy_bitfile(filename):
|
||||||
|
for p in [proxy_path(), os.path.expanduser("~/.migen"),
|
||||||
|
"/usr/local/share/migen", "/usr/share/migen"]:
|
||||||
|
full_path = os.path.join(p, filename)
|
||||||
|
if os.access(full_path, os.R_OK):
|
||||||
|
return full_path
|
||||||
|
raise FileNotFoundError("proxy bitstream {} not found"
|
||||||
|
.format(filename))
|
||||||
|
|
||||||
|
|
||||||
|
def add_commands(script, *commands, **substs):
|
||||||
|
script += [command.format(**substs) for command in commands]
|
||||||
|
|
||||||
|
|
||||||
class Programmer:
|
class Programmer:
|
||||||
def __init__(self, client, preinit_script):
|
def __init__(self, client, preinit_script):
|
||||||
self._client = client
|
self._client = client
|
||||||
|
self._board_script = []
|
||||||
self._preinit_script = preinit_script
|
self._preinit_script = preinit_script
|
||||||
self._script = []
|
self._script = []
|
||||||
|
|
||||||
|
@ -103,8 +118,39 @@ class Programmer:
|
||||||
script = os.path.join(scripts_path(), script)
|
script = os.path.join(scripts_path(), script)
|
||||||
return self._client.transfer_file(script, rewriter)
|
return self._client.transfer_file(script, rewriter)
|
||||||
|
|
||||||
|
def add_flash_bank(self, name, tap, index):
|
||||||
|
add_commands(self._board_script,
|
||||||
|
"target create {tap}.{name}.proxy testee -chain-position {tap}.tap",
|
||||||
|
"flash bank {name} jtagspi 0 0 0 0 {tap}.{name}.proxy {ir:#x}",
|
||||||
|
tap=tap, name=name, ir=0x02 + index)
|
||||||
|
|
||||||
|
def load(self, bitfile, pld):
|
||||||
|
bitfile = self._client.transfer_file(bitfile)
|
||||||
|
add_commands(self._script,
|
||||||
|
"pld load {pld} {filename}",
|
||||||
|
pld=pld, filename=bitfile)
|
||||||
|
|
||||||
|
def load_proxy(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def flash_binary(self, bankname, address, filename):
|
||||||
|
size = os.path.getsize(filename)
|
||||||
|
filename = self._client.transfer_file(filename)
|
||||||
|
add_commands(self._script,
|
||||||
|
"flash probe {bankname}",
|
||||||
|
"flash erase_sector {bankname} {firstsector} {lastsector}",
|
||||||
|
"flash write_bank {bankname} {filename} {address:#x}",
|
||||||
|
"flash verify_bank {bankname} {filename} {address:#x}",
|
||||||
|
bankname=bankname, address=address, filename=filename,
|
||||||
|
firstsector=address // self._sector_size,
|
||||||
|
lastsector=(address + size - 1) // self._sector_size)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def script(self):
|
def script(self):
|
||||||
return [
|
return [
|
||||||
|
*self._board_script,
|
||||||
*self._preinit_script,
|
*self._preinit_script,
|
||||||
"init",
|
"init",
|
||||||
*self._script,
|
*self._script,
|
||||||
|
@ -120,52 +166,34 @@ class Programmer:
|
||||||
cmdline = [arg.replace("{", "{{").replace("}", "}}") for arg in cmdline]
|
cmdline = [arg.replace("{", "{{").replace("}", "}}") for arg in cmdline]
|
||||||
self._client.run_command(cmdline)
|
self._client.run_command(cmdline)
|
||||||
|
|
||||||
def load(self, bitfile, pld):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def proxy(self, proxy_bitfile, pld):
|
class ProgrammerXC7(Programmer):
|
||||||
raise NotImplementedError
|
_sector_size = 0x10000
|
||||||
|
|
||||||
def flash_binary(self, flashno, address, filename):
|
def __init__(self, client, preinit_script, board, proxy):
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
class ProgrammerJtagSpi7(Programmer):
|
|
||||||
def __init__(self, client, target, preinit_script):
|
|
||||||
Programmer.__init__(self, client, preinit_script)
|
Programmer.__init__(self, client, preinit_script)
|
||||||
|
self._proxy = proxy
|
||||||
|
|
||||||
target_file = self._transfer_script(os.path.join("board", target + ".cfg"))
|
add_commands(self._board_script,
|
||||||
self._preinit_script.append("source {}".format(target_file))
|
"source {boardfile}",
|
||||||
|
boardfile=self._transfer_script("board/{}.cfg".format(board)))
|
||||||
|
self.add_flash_bank("spi0", "xc7", index=0)
|
||||||
|
|
||||||
def load(self, bitfile, pld=0):
|
def load_proxy(self):
|
||||||
bitfile = self._client.transfer_file(bitfile)
|
self.load(find_proxy_bitfile(self._proxy), pld=0)
|
||||||
self._script.append("pld load {} {{{}}}".format(pld, bitfile))
|
|
||||||
|
|
||||||
def proxy(self, proxy_bitfile, pld=0):
|
|
||||||
proxy_bitfile = self._client.transfer_file(proxy_bitfile)
|
|
||||||
self._script.append("jtagspi_init {} {{{}}}".format(pld, proxy_bitfile))
|
|
||||||
|
|
||||||
def flash_binary(self, flashno, address, filename):
|
|
||||||
assert flashno == 0 # jtagspi_program supports only one flash
|
|
||||||
|
|
||||||
filename = self._client.transfer_file(filename)
|
|
||||||
self._script.append("jtagspi_program {{{}}} 0x{:x}".format(
|
|
||||||
filename, address))
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._script.append("xc7_program xc7.tap")
|
add_commands(self._script,
|
||||||
|
"xc7_program xc7.tap")
|
||||||
|
|
||||||
|
|
||||||
class ProgrammerSayma(Programmer):
|
class ProgrammerSayma(Programmer):
|
||||||
sector_size = 0x10000
|
_sector_size = 0x10000
|
||||||
|
|
||||||
def __init__(self, client, preinit_script):
|
def __init__(self, client, preinit_script):
|
||||||
Programmer.__init__(self, client, [])
|
Programmer.__init__(self, client, preinit_script)
|
||||||
|
|
||||||
self._preinit_script += [
|
add_commands(self._board_script,
|
||||||
"interface ftdi",
|
"interface ftdi",
|
||||||
"ftdi_device_desc \"Quad RS232-HS\"",
|
"ftdi_device_desc \"Quad RS232-HS\"",
|
||||||
"ftdi_vid_pid 0x0403 0x6011",
|
"ftdi_vid_pid 0x0403 0x6011",
|
||||||
|
@ -174,47 +202,22 @@ class ProgrammerSayma(Programmer):
|
||||||
# nTRST on ADBUS4: out, high, but R46 is DNP
|
# nTRST on ADBUS4: out, high, but R46 is DNP
|
||||||
"ftdi_layout_init 0x0098 0x008b",
|
"ftdi_layout_init 0x0098 0x008b",
|
||||||
"reset_config none",
|
"reset_config none",
|
||||||
|
|
||||||
"adapter_khz 5000",
|
"adapter_khz 5000",
|
||||||
"transport select jtag",
|
"transport select jtag",
|
||||||
|
|
||||||
*preinit_script,
|
|
||||||
|
|
||||||
# tap 0, pld 0
|
# tap 0, pld 0
|
||||||
"source {}".format(self._transfer_script("cpld/xilinx-xc7.cfg")),
|
"source {}".format(self._transfer_script("cpld/xilinx-xc7.cfg")),
|
||||||
# tap 1, pld 1
|
# tap 1, pld 1
|
||||||
"set CHIP XCKU040",
|
"set CHIP XCKU040",
|
||||||
"source {}".format(self._transfer_script("cpld/xilinx-xcu.cfg")),
|
"source {}".format(self._transfer_script("cpld/xilinx-xcu.cfg")))
|
||||||
|
self.add_flash_bank("spi0", "xcu", index=0)
|
||||||
|
self.add_flash_bank("spi1", "xcu", index=1)
|
||||||
|
|
||||||
"target create xcu.proxy testee -chain-position xcu.tap",
|
def load_proxy(self):
|
||||||
"set XILINX_USER1 0x02",
|
self.load(find_proxy_bitfile("bscan_spi_xcku040-sayma.bit"), pld=1)
|
||||||
"set XILINX_USER2 0x03",
|
|
||||||
"flash bank xcu.spi0 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER1",
|
|
||||||
"flash bank xcu.spi1 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER2"
|
|
||||||
]
|
|
||||||
|
|
||||||
def load(self, bitfile, pld=1):
|
|
||||||
bitfile = self._client.transfer_file(bitfile)
|
|
||||||
self._script.append("pld load {} {{{}}}".format(pld, bitfile))
|
|
||||||
|
|
||||||
def proxy(self, proxy_bitfile, pld=1):
|
|
||||||
self.load(proxy_bitfile, pld)
|
|
||||||
self._script.append("reset halt")
|
|
||||||
|
|
||||||
def flash_binary(self, flashno, address, filename):
|
|
||||||
sector_first = address // self.sector_size
|
|
||||||
size = os.path.getsize(filename)
|
|
||||||
sector_last = sector_first + (size - 1) // self.sector_size
|
|
||||||
filename = self._client.transfer_file(filename)
|
|
||||||
self._script += [
|
|
||||||
"flash probe xcu.spi{}".format(flashno),
|
|
||||||
"flash erase_sector {} {} {}".format(flashno, sector_first, sector_last),
|
|
||||||
"flash write_bank {} {{{}}} 0x{:x}".format(flashno, filename, address),
|
|
||||||
"flash verify_bank {} {{{}}} 0x{:x}".format(flashno, filename, address),
|
|
||||||
]
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._script.append("xcu_program xcu.tap")
|
add_commands(self._script,
|
||||||
|
"xcu_program xcu.tap")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -223,36 +226,32 @@ def main():
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"kc705": {
|
"kc705": {
|
||||||
"programmer_factory": partial(ProgrammerJtagSpi7, target="kc705"),
|
"programmer": partial(ProgrammerXC7, board="kc705", proxy="bscan_spi_xc7k325t.bit"),
|
||||||
"proxy_bitfile": "bscan_spi_xc7k325t.bit",
|
"variants": ["nist_clock", "nist_qc2"],
|
||||||
"variants": ["nist_clock", "nist_qc2"],
|
"gateware": ("spi0", 0x000000),
|
||||||
"gateware": (0, 0x000000),
|
"bootloader": ("spi0", 0xaf0000),
|
||||||
"bootloader": (0, 0xaf0000),
|
"storage": ("spi0", 0xb30000),
|
||||||
"storage": (0, 0xb30000),
|
"firmware": ("spi0", 0xb40000),
|
||||||
"firmware": (0, 0xb40000),
|
|
||||||
},
|
},
|
||||||
"kasli": {
|
"kasli": {
|
||||||
"programmer_factory": partial(ProgrammerJtagSpi7, target="kasli"),
|
"programmer": partial(ProgrammerXC7, board="kasli", proxy="bscan_spi_xc7a100t.bit"),
|
||||||
"proxy_bitfile": "bscan_spi_xc7a100t.bit",
|
"variants": ["opticlock"],
|
||||||
"variants": ["opticlock"],
|
"gateware": ("spi0", 0x000000),
|
||||||
"gateware": (0, 0x000000),
|
"bootloader": ("spi0", 0x400000),
|
||||||
"bootloader": (0, 0x400000),
|
"storage": ("spi0", 0x440000),
|
||||||
"storage": (0, 0x440000),
|
"firmware": ("spi0", 0x450000),
|
||||||
"firmware": (0, 0x450000),
|
|
||||||
},
|
},
|
||||||
"sayma_amc": {
|
"sayma_amc": {
|
||||||
"programmer_factory": ProgrammerSayma,
|
"programmer": ProgrammerSayma,
|
||||||
"proxy_bitfile": "bscan_spi_xcku040-sayma.bit",
|
"variants": ["standalone", "master", "satellite"],
|
||||||
"variants": ["standalone", "master", "satellite"],
|
"gateware": ("spi0", 0x000000),
|
||||||
"gateware": (0, 0x000000),
|
"bootloader": ("spi1", 0x000000),
|
||||||
"bootloader": (1, 0x000000),
|
"storage": ("spi1", 0x040000),
|
||||||
"storage": (1, 0x040000),
|
"firmware": ("spi1", 0x050000),
|
||||||
"firmware": (1, 0x050000),
|
|
||||||
},
|
},
|
||||||
"sayma_rtm": {
|
"sayma_rtm": {
|
||||||
"programmer_factory": ProgrammerSayma,
|
"programmer": ProgrammerSayma,
|
||||||
"proxy_bitfile": "bscan_spi_xcku040-sayma.bit",
|
"gateware": ("spi1", 0x150000),
|
||||||
"gateware": (1, 0x150000),
|
|
||||||
},
|
},
|
||||||
}[args.target]
|
}[args.target]
|
||||||
|
|
||||||
|
@ -262,13 +261,14 @@ def main():
|
||||||
raise SystemExit("Invalid variant for this board")
|
raise SystemExit("Invalid variant for this board")
|
||||||
if variant is None:
|
if variant is None:
|
||||||
variant = config["variants"][0]
|
variant = config["variants"][0]
|
||||||
|
|
||||||
bin_dir = args.dir
|
bin_dir = args.dir
|
||||||
if bin_dir is None:
|
if bin_dir is None:
|
||||||
|
bin_name = args.target
|
||||||
if variant:
|
if variant:
|
||||||
bin_name = "{}-{}".format(args.target, variant)
|
bin_name += "-" + variant
|
||||||
else:
|
|
||||||
bin_name = args.target
|
|
||||||
bin_dir = os.path.join(artiq_dir, "binaries", bin_name)
|
bin_dir = os.path.join(artiq_dir, "binaries", bin_name)
|
||||||
|
|
||||||
if args.srcbuild is None and not os.path.exists(bin_dir) and args.action != ["start"]:
|
if args.srcbuild is None and not os.path.exists(bin_dir) and args.action != ["start"]:
|
||||||
raise SystemExit("Binaries directory '{}' does not exist"
|
raise SystemExit("Binaries directory '{}' does not exist"
|
||||||
.format(bin_dir))
|
.format(bin_dir))
|
||||||
|
@ -278,21 +278,14 @@ def main():
|
||||||
else:
|
else:
|
||||||
client = SSHClient(args.host)
|
client = SSHClient(args.host)
|
||||||
|
|
||||||
programmer = config["programmer_factory"](client, preinit_script=args.preinit_command)
|
programmer = config["programmer"](client, preinit_script=args.preinit_command)
|
||||||
|
|
||||||
for action in args.action:
|
for action in args.action:
|
||||||
if action == "proxy":
|
if action == "proxy":
|
||||||
proxy_found = False
|
try:
|
||||||
for p in [bin_dir, proxy_path(), os.path.expanduser("~/.migen"),
|
programmer.load_proxy()
|
||||||
"/usr/local/share/migen", "/usr/share/migen"]:
|
except FileNotFoundError as e:
|
||||||
proxy_bitfile = os.path.join(p, config["proxy_bitfile"])
|
raise SystemExit(e)
|
||||||
if os.access(proxy_bitfile, os.R_OK):
|
|
||||||
programmer.proxy(proxy_bitfile)
|
|
||||||
proxy_found = True
|
|
||||||
break
|
|
||||||
if not proxy_found:
|
|
||||||
raise SystemExit(
|
|
||||||
"proxy gateware bitstream {} not found".format(config["proxy_bitfile"]))
|
|
||||||
elif action == "gateware":
|
elif action == "gateware":
|
||||||
if args.srcbuild is None:
|
if args.srcbuild is None:
|
||||||
path = bin_dir
|
path = bin_dir
|
||||||
|
|
Loading…
Reference in New Issue