diff --git a/tools/legacy/usb_update.py b/tools/legacy/usb_update.py deleted file mode 100755 index 2673d296b..000000000 --- a/tools/legacy/usb_update.py +++ /dev/null @@ -1,739 +0,0 @@ -#! /usr/bin/env python3 - -import argparse - -import usb.core -import usb.util -import array -import sys -import hashlib -import csv -import urllib.request - -from progressbar.bar import ProgressBar - -class PrecursorUsb: - def __init__(self, dev): - self.dev = dev - self.RDSR = 0x05 - self.RDSCUR = 0x2B - self.RDID = 0x9F - self.WREN = 0x06 - self.WRDI = 0x04 - self.SE4B = 0x21 - self.BE4B = 0xDC - self.PP4B = 0x12 - self.registers = {} - self.regions = {} - self.gitrev = '' - - def register(self, name): - return int(self.registers[name], 0) - - def peek(self, addr, display=False): - _dummy_s = '\x00'.encode('utf-8') - data = array.array('B', _dummy_s * 4) - - numread = self.dev.ctrl_transfer(bmRequestType=(0x80 | 0x43), bRequest=0, - wValue=(addr & 0xffff), wIndex=((addr >> 16) & 0xffff), - data_or_wLength=data, timeout=500) - - read_data = int.from_bytes(data.tobytes(), byteorder='little', signed=False) - if display == True: - print("0x{:08x}".format(read_data)) - return read_data - - def poke(self, addr, wdata, check=False, display=False): - if check == True: - _dummy_s = '\x00'.encode('utf-8') - data = array.array('B', _dummy_s * 4) - - numread = self.dev.ctrl_transfer(bmRequestType=(0x80 | 0x43), bRequest=0, - wValue=(addr & 0xffff), wIndex=((addr >> 16) & 0xffff), - data_or_wLength=data, timeout=500) - - read_data = int.from_bytes(data.tobytes(), byteorder='little', signed=False) - print("before poke: 0x{:08x}".format(read_data)) - - data = array.array('B', wdata.to_bytes(4, 'little')) - numwritten = self.dev.ctrl_transfer(bmRequestType=(0x00 | 0x43), bRequest=0, - wValue=(addr & 0xffff), wIndex=((addr >> 16) & 0xffff), - data_or_wLength=data, timeout=500) - - if check == True: - _dummy_s = '\x00'.encode('utf-8') - data = array.array('B', _dummy_s * 4) - - numread = self.dev.ctrl_transfer(bmRequestType=(0x80 | 0x43), bRequest=0, - wValue=(addr & 0xffff), wIndex=((addr >> 16) & 0xffff), - data_or_wLength=data, timeout=500) - - read_data = int.from_bytes(data.tobytes(), byteorder='little', signed=False) - print("after poke: 0x{:08x}".format(read_data)) - if display == True: - print("wrote 0x{:08x} to 0x{:08x}".format(wdata, addr)) - - def burst_read(self, addr, len): - _dummy_s = '\x00'.encode('utf-8') - maxlen = 4096 - - ret = bytearray() - packet_count = len // maxlen - if (len % maxlen) != 0: - packet_count += 1 - - for pkt_num in range(packet_count): - cur_addr = addr + pkt_num * maxlen - if pkt_num == packet_count - 1: - if len % maxlen != 0: - bufsize = len % maxlen - else: - bufsize = maxlen - else: - bufsize = maxlen - - data = array.array('B', _dummy_s * bufsize) - numread = self.dev.ctrl_transfer(bmRequestType=(0x80 | 0x43), bRequest=0, - wValue=(cur_addr & 0xffff), wIndex=((cur_addr >> 16) & 0xffff), - data_or_wLength=data, timeout=500) - - if numread != bufsize: - print("Burst read error: {} bytes requested, {} bytes read at 0x{:08x}".format(bufsize, numread, cur_addr)) - exit(1) - - ret = ret + data - - return ret - - def burst_write(self, addr, data): - if len(data) == 0: - return - - # the actual "addr" doesn't matter for a burst_write, because it's specified - # as an argument to the flash_pp4b command. We lock out access to the base of - # SPINOR because it's part of the gateware, so, we pick a "safe" address to - # write to instead. The page write responder will aggregate any write data - # to anywhere in the SPINOR address range. - writebuf_addr = 0x2098_0000 # the current start address of the kernel, for example - - maxlen = 4096 - packet_count = len(data) // maxlen - if (len(data) % maxlen) != 0: - packet_count += 1 - - for pkt_num in range(packet_count): - cur_addr = addr + pkt_num * maxlen - if pkt_num == packet_count - 1: - if len(data) % maxlen != 0: - bufsize = len(data) % maxlen - else: - bufsize = maxlen - else: - bufsize = maxlen - - wdata = array.array('B', data[(pkt_num * maxlen):(pkt_num * maxlen) + bufsize]) - numwritten = self.dev.ctrl_transfer(bmRequestType=(0x00 | 0x43), bRequest=0, - # note use of writebuf_addr instead of cur_addr -> see comment above about the quirk of write addressing - wValue=(writebuf_addr & 0xffff), wIndex=((writebuf_addr >> 16) & 0xffff), - data_or_wLength=wdata, timeout=500) - - if numwritten != bufsize: - print("Burst write error: {} bytes requested, {} bytes written at 0x{:08x}".format(bufsize, numwritten, cur_addr)) - exit(1) - - def ping_wdt(self): - self.poke(self.register('wdt_watchdog'), 1, display=False) - self.poke(self.register('wdt_watchdog'), 1, display=False) - - def spinor_command_value(self, exec=0, lock_reads=0, cmd_code=0, dummy_cycles=0, data_words=0, has_arg=0): - return ((exec & 1) << 1 | - (lock_reads & 1) << 24 | - (cmd_code & 0xff) << 2 | - (dummy_cycles & 0x1f) << 11 | - (data_words & 0xff) << 16 | - (has_arg & 1) << 10 - ) - - def flash_rdsr(self, lock_reads): - self.poke(self.register('spinor_cmd_arg'), 0) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=lock_reads, cmd_code=self.RDSR, dummy_cycles=4, data_words=1, has_arg=1) - ) - return self.peek(self.register('spinor_cmd_rbk_data'), display=False) - - def flash_rdscur(self): - self.poke(self.register('spinor_cmd_arg'), 0) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.RDSCUR, dummy_cycles=4, data_words=1, has_arg=1) - ) - return self.peek(self.register('spinor_cmd_rbk_data'), display=False) - - def flash_rdid(self, offset): - self.poke(self.register('spinor_cmd_arg'), 0) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, cmd_code=self.RDID, dummy_cycles=4, data_words=offset, has_arg=1) - ) - return self.peek(self.register('spinor_cmd_rbk_data'), display=False) - - def flash_wren(self): - self.poke(self.register('spinor_cmd_arg'), 0) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.WREN) - ) - - def flash_wrdi(self): - self.poke(self.register('spinor_cmd_arg'), 0) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.WRDI) - ) - - def flash_se4b(self, sector_address): - self.poke(self.register('spinor_cmd_arg'), sector_address) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.SE4B, has_arg=1) - ) - - def flash_be4b(self, block_address): - self.poke(self.register('spinor_cmd_arg'), block_address) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.BE4B, has_arg=1) - ) - - def flash_pp4b(self, address, data_bytes): - self.poke(self.register('spinor_cmd_arg'), address) - self.poke(self.register('spinor_command'), - self.spinor_command_value(exec=1, lock_reads=1, cmd_code=self.PP4B, has_arg=1, data_words=(data_bytes//2)) - ) - - def load_csrs(self, fname=None): - LOC_CSRCSV = 0x20277000 # this address shouldn't change because it's how we figure out our version number - # CSR extraction: - # dd if=soc_csr.bin of=csr_data_0.9.6.bin skip=2524 count=32 bs=1024 - if fname == None: - csr_data = self.burst_read(LOC_CSRCSV, 0x8000) - else: - with open(fname, "rb") as f: - csr_data = f.read(0x8000) - - hasher = hashlib.sha512() - hasher.update(csr_data[:0x7FC0]) - digest = hasher.digest() - if digest != csr_data[0x7fc0:]: - print("Could not find a valid csr.csv descriptor on the device, aborting!") - exit(1) - - csr_len = int.from_bytes(csr_data[:4], 'little') - csr_extracted = csr_data[4:4+csr_len] - decoded = csr_extracted.decode('utf-8') - # strip comments - stripped = [] - for line in decoded.split('\n'): - if line.startswith('#') == False: - stripped.append(line) - # create database - csr_db = csv.reader(stripped) - for row in csr_db: - if len(row) > 1: - if 'csr_register' in row[0]: - self.registers[row[1]] = row[2] - if 'memory_region' in row[0]: - self.regions[row[1]] = [row[2], row[3]] - if 'git_rev' in row[0]: - self.gitrev = row[1] - print("Using SoC {} registers".format(self.gitrev)) - - def erase_region(self, addr, length): - # ID code check - code = self.flash_rdid(1) - print("ID code bytes 1-2: 0x{:08x}".format(code)) - if code != 0x8080c2c2: - print("ID code mismatch") - exit(1) - code = self.flash_rdid(2) - print("ID code bytes 2-3: 0x{:08x}".format(code)) - if code != 0x3b3b8080: - print("ID code mismatch") - exit(1) - - # block erase - progress = ProgressBar(min_value=0, max_value=length, prefix='Erasing ').start() - erased = 0 - while erased < length: - self.ping_wdt() - if (length - erased >= 65536) and ((addr & 0xFFFF) == 0): - blocksize = 65536 - else: - blocksize = 4096 - - while True: - self.flash_wren() - status = self.flash_rdsr(1) - if status & 0x02 != 0: - break - - if blocksize == 4096: - self.flash_se4b(addr + erased) - else: - self.flash_be4b(addr + erased) - erased += blocksize - - while (self.flash_rdsr(1) & 0x01) != 0: - pass - - result = self.flash_rdscur() - if result & 0x60 != 0: - print("E_FAIL/P_FAIL set on erase, programming may fail, but trying anyways...") - - if self.flash_rdsr(1) & 0x02 != 0: - self.flash_wrdi() - while (self.flash_rdsr(1) & 0x02) != 0: - pass - if erased < length: - progress.update(erased) - progress.finish() - print("Erase finished") - - # addr is relative to the base of FLASH (not absolute) - def flash_program(self, addr, data, verify=True): - flash_region = int(self.regions['spiflash'][0], 0) - flash_len = int(self.regions['spiflash'][1], 0) - - if (addr + len(data) > flash_len): - print("Write data out of bounds! Aborting.") - exit(1) - - # ID code check - code = self.flash_rdid(1) - print("ID code bytes 1-2: 0x{:08x}".format(code)) - if code != 0x8080c2c2: - print("ID code mismatch") - exit(1) - code = self.flash_rdid(2) - print("ID code bytes 2-3: 0x{:08x}".format(code)) - if code != 0x3b3b8080: - print("ID code mismatch") - exit(1) - - # block erase - progress = ProgressBar(min_value=0, max_value=len(data), prefix='Erasing ').start() - erased = 0 - while erased < len(data): - self.ping_wdt() - if (len(data) - erased >= 65536) and ((addr & 0xFFFF) == 0): - blocksize = 65536 - else: - blocksize = 4096 - - while True: - self.flash_wren() - status = self.flash_rdsr(1) - if status & 0x02 != 0: - break - - if blocksize == 4096: - self.flash_se4b(addr + erased) - else: - self.flash_be4b(addr + erased) - erased += blocksize - - while (self.flash_rdsr(1) & 0x01) != 0: - pass - - result = self.flash_rdscur() - if result & 0x60 != 0: - print("E_FAIL/P_FAIL set on erase, programming may fail, but trying anyways...") - - if self.flash_rdsr(1) & 0x02 != 0: - self.flash_wrdi() - while (self.flash_rdsr(1) & 0x02) != 0: - pass - if erased < len(data): - progress.update(erased) - progress.finish() - print("Erase finished") - - # program - # pad out to the nearest word length - if len(data) % 4 != 0: - data += bytearray([0xff] * (4 - (len(data) % 4))) - written = 0 - progress = ProgressBar(min_value=0, max_value=len(data), prefix='Writing ').start() - while written < len(data): - self.ping_wdt() - if len(data) - written > 256: - chunklen = 256 - else: - chunklen = len(data) - written - - while True: - self.flash_wren() - status = self.flash_rdsr(1) - if status & 0x02 != 0: - break - - self.burst_write(self.register('spinor_wdata'), data[written:(written+chunklen)]) - self.flash_pp4b(addr + written, chunklen) - - written += chunklen - if written < len(data): - progress.update(written) - progress.finish() - print("Write finished") - - if self.flash_rdsr(1) & 0x02 != 0: - self.flash_wrdi() - while (self.flash_rdsr(1) & 0x02) != 0: - pass - - # dummy reads to clear the "read lock" bit - self.flash_rdsr(0) - - # verify - self.ping_wdt() - if verify: - print("Performing readback for verification...") - self.ping_wdt() - rbk_data = self.burst_read(addr + flash_region, len(data)) - if rbk_data != data: - errs = 0 - err_thresh = 64 - for i in range(0, len(rbk_data)): - if rbk_data[i] != data[i]: - if errs < err_thresh: - print("Error at 0x{:x}: {:x}->{:x}".format(i, data[i], rbk_data[i])) - errs += 1 - if errs == err_thresh: - print("Too many errors, stopping print...") - print("Errors were found in verification, programming failed") - print("Total byte errors: {}".format(errs)) - exit(1) - else: - print("Verification passed.") - else: - print("Skipped verification at user request") - - self.ping_wdt() - -def auto_int(x): - return int(x, 0) - -def main(): - parser = argparse.ArgumentParser(description="Update/upload to a Precursor device running Xous 0.8/0.9") - parser.add_argument( - "--soc", required=False, help="'Factory Reset' the SoC gateware. Note: this will overwrite any secret keys stored in your device!", type=str, nargs='?', metavar=('SoC gateware file'), const='../precursors/soc_csr.bin' - ) - parser.add_argument( - "-s", "--staging", required=False, help="Stage an update to apply", type=str, nargs='?', metavar=('SoC gateware file'), const='../precursors/soc_csr.bin' - ) - parser.add_argument( - "-l", "--loader", required=False, help="Loader", type=str, nargs='?', metavar=('loader file'), const='../target/riscv32imac-unknown-xous-elf/release/loader.bin' - ) - parser.add_argument( - "--disable-boot", required=False, action='store_true', help="Disable system boot (for use in multi-stage updates)" - ) - parser.add_argument( - "--enable-boot-wipe", required=False, action='store_true', help="Re-enable system boot for factory reset. Requires both a loader (-l) and a soc (--soc) spec. Overwrites root keys." - ) - parser.add_argument( - "--enable-boot-update", required=False, action='store_true', help="Re-enable system boot for updates. Requires both a loader (-l) and a staging (-s) spec. Stages SOC without overwriting root keys." - ) - parser.add_argument( - "-k", "--kernel", required=False, help="Kernel", type=str, nargs='?', metavar=('kernel file'), const='../target/riscv32imac-unknown-xous-elf/release/xous.img' - ) - parser.add_argument( - "-e", "--ec", required=False, help="EC gateware", type=str, nargs='?', metavar=('EC gateware package'), const='ec_fw.bin' - ) - parser.add_argument( - "-w", "--wf200", required=False, help="WF200 firmware", type=str, nargs='?', metavar=('WF200 firmware package'), const='wf200_fw.bin' - ) - parser.add_argument( - "--erase-pddb", help="Erase the PDDB area", action="store_true" - ) - parser.add_argument( - "--audiotest", required=False, help="Test audio clip (must be 8kHz WAV)", type=str, nargs='?', metavar=('Test audio clip'), const="testaudio.wav" - ) - parser.add_argument( - "--peek", required=False, help="Inspect an address", type=auto_int, metavar=('ADDR') - ) - parser.add_argument( - "--poke", required=False, help="Write to an address", type=auto_int, nargs=2, metavar=('ADDR', 'DATA') - ) - parser.add_argument( - "--check-poke", required=False, action='store_true', help="Read data before and after the poke" - ) - parser.add_argument( - "--config", required=False, help="Print the descriptor", action='store_true' - ) - parser.add_argument( - "-i", "--image", required=False, help="Manually specify an image and address. Offset is relative to bottom of flash.", type=str, nargs=2, metavar=('IMAGEFILE', 'ADDR') - ) - parser.add_argument( - "--verify", help="Readback verification. May fail for large files due to WDT timeout.", default=False, action='store_true' - ) - parser.add_argument( - "--force", help="Ignore gitrev version on SoC and try to burn an image anyways", action="store_true" - ) - parser.add_argument( - "--bounce", help="cycle the device through a reset", action="store_true" - ) - parser.add_argument( - "--factory-new", help="reset the entire image to mimic exactly what comes out of the factory, including temp files for testing. Warning: this will take a long time.", action="store_true" - ) - parser.add_argument( - "--override-csr", required=False, help="CSR file to use instead of CSR values stored with the image. Used to recover in case of partial update of soc_csr.bin", type=str, - ) - args = parser.parse_args() - - if not len(sys.argv) > 1: - print("No arguments specified, doing nothing. Use --help for more information.") - exit(1) - - dev = usb.core.find(idProduct=0x5bf0, idVendor=0x1209) - - if dev is None: - raise ValueError('Precursor device not found') - - dev.set_configuration() - if args.config: - cfg = dev.get_active_configuration() - print(cfg) - - pc_usb = PrecursorUsb(dev) - - if args.verify: - verify = True - else: - verify = False - - if args.peek: - pc_usb.peek(args.peek, display=True) - # print(burst_read(dev, args.peek, 256).hex()) - exit(0) - - if args.poke: - addr, data = args.poke - pc_usb.poke(addr, data, check=args.check_poke, display=True) - # import os - # d = bytearray(os.urandom(8000)) - # burst_write(dev, addr, d) - # r = burst_read(dev, addr, 8000) - # print(r.hex()) - # if d != r: - # print("mismatch") - # else: - # print("match") - exit(0) - - pc_usb.load_csrs(args.override_csr) # prime the CSR values - if "v0.8" in pc_usb.gitrev: - locs = { - "LOC_SOC" : [0x0000_0000, "soc_csr.bin"], - "LOC_STAGING": [0x0028_0000, "pass"], - "LOC_LOADER" : [0x0050_0000, "loader.bin"], - "LOC_KERNEL" : [0x0098_0000, "xous.img"], - "LOC_WF200" : [0x07F8_0000, "pass"], - "LOC_EC" : [0x07FC_E000, "pass"], - "LOC_AUDIO" : [0x0634_0000, "short_8khz.wav"], - "LEN_AUDIO" : [0x01C4_0000, "pass"], - "LOC_PDDB" : [0x0100_0000, "pass"], - } - elif "v0.9" in pc_usb.gitrev: - locs = { - "LOC_SOC" : [0x0000_0000, "soc_csr.bin"], - "LOC_STAGING": [0x0028_0000, "pass"], - "LOC_LOADER" : [0x0050_0000, "loader.bin"], - "LOC_KERNEL" : [0x0098_0000, "xous.img"], - "LOC_WF200" : [0x07F8_0000, "pass"], - "LOC_EC" : [0x07FC_E000, "pass"], - "LOC_AUDIO" : [0x0634_0000, "short_8khz.wav"], - "LEN_AUDIO" : [0x01C4_0000, "pass"], - "LOC_PDDB" : [0x01D8_0000, "pass"], - } - elif args.force == True: - # try the v0.9 offsets - locs = { - "LOC_SOC" : [0x00000000, "soc_csr.bin"], - "LOC_STAGING": [0x00280000, "pass"], - "LOC_LOADER" : [0x00500000, "loader.bin"], - "LOC_KERNEL" : [0x00980000, "xous.img"], - "LOC_WF200" : [0x07F80000, "pass"], - "LOC_EC" : [0x07FCE000, "pass"], - "LOC_AUDIO" : [0x06340000, "short_8khz.wav"], - "LEN_AUDIO" : [0x01C40000, "pass"], - "LOC_PDDB" : [0x01D80000, "pass"], - } - else: - print("SoC is from an unknow rev '{}', use --force to continue anyways with v0.9 firmware offsets".format(pc_usb.load_csrs())) - exit(1) - - vexdbg_addr = int(pc_usb.regions['vexriscv_debug'][0], 0) - pc_usb.ping_wdt() - print("Halting CPU.") - pc_usb.poke(vexdbg_addr, 0x00020000) - - if args.erase_pddb: - print("Erasing PDDB region") - pc_usb.erase_region(locs['LOC_PDDB'][0], locs['LOC_EC'][0] - locs['LOC_PDDB'][0]) - - if args.disable_boot: - print("Disabling boot") - pc_usb.erase_region(locs['LOC_LOADER'][0], 1024 * 256) - - if args.enable_boot_wipe: - if args.loader == None: - print("Must provide both a loader and soc image") - if args.soc == None: - print("Must provide both a soc and loader image") - print("Enabling boot with {} and {}".format(args.loader, args.soc)) - print("Programming loader image {}".format(args.loader)) - with open(args.loader, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_LOADER'][0], image, verify=verify) - print("Programming SoC gateware".format(args.soc)) - with open(args.soc, "rb") as f: - image = f.read() - if verify == True: - print("Note: SoC verification is not possible as readback is locked for security purposes") - pc_usb.flash_program(locs['LOC_SOC'][0], image, verify=False) - - print("Erasing PDDB root structures") - pc_usb.erase_region(locs['LOC_PDDB'][0], 1024 * 1024) - - print("Resuming CPU.") - pc_usb.poke(vexdbg_addr, 0x02000000) - - print("Resetting SOC...") - try: - pc_usb.poke(pc_usb.register('reboot_soc_reset'), 0xac, display=False) - except usb.core.USBError: - pass # we expect an error because we reset the SOC and that includes the USB core - exit(0) - - if args.enable_boot_update: - if args.loader == None: - print("Must provide both a loader and soc image") - if args.staging == None: - print("Must provide both a soc and loader image") - print("Enabling boot with {} and {}".format(args.loader, args.staging)) - print("Programming loader image {}".format(args.loader)) - with open(args.loader, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_LOADER'][0], image, verify=verify) - print("Staging SoC gateware".format(args.staging)) - with open(args.staging, "rb") as f: - image = f.read() - if verify == True: - print("Note: staging area verification is not possible as readback is locked for security purposes") - pc_usb.flash_program(locs['LOC_STAGING'][0], image, verify=verify) - - print("Resuming CPU.") - pc_usb.poke(vexdbg_addr, 0x02000000) - - print("Resetting SOC...") - try: - pc_usb.poke(pc_usb.register('reboot_soc_reset'), 0xac, display=False) - except usb.core.USBError: - pass # we expect an error because we reset the SOC and that includes the USB core - exit(0) - - if args.image: - image_file, addr_str = args.image - addr = int(addr_str, 0) - print("Burning manually specified image '{}' to address 0x{:08x} relative to bottom of FLASH".format(image_file, addr)) - with open(image_file, "rb") as f: - image_data = f.read() - pc_usb.flash_program(addr, image_data, verify=verify) - - if args.ec != None: - print("Staging EC firmware package '{}' in SOC memory space...".format(args.ec)) - with open(args.ec, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_EC'][0], image, verify=verify) - - if args.wf200 != None: - print("Staging WF200 firmware package '{}' in SOC memory space...".format(args.wf200)) - with open(args.wf200, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_WF200'][0], image, verify=verify) - - if args.staging != None: - print("Staging SoC gateware {}".format(args.soc)) - with open(args.staging, "rb") as f: - image = f.read() - if verify == True: - print("Note: staging area verification is not possible as readback is locked for security purposes") - pc_usb.flash_program(locs['LOC_STAGING'][0], image, verify=verify) - - if args.kernel != None: - print("Programming kernel image {}".format(args.kernel)) - with open(args.kernel, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_KERNEL'][0], image, verify=verify) - - if args.loader != None: - print("Programming loader image {}".format(args.loader)) - with open(args.loader, "rb") as f: - image = f.read() - pc_usb.flash_program(locs['LOC_LOADER'][0], image, verify=verify) - - if args.soc != None: - if args.force == True: - print("Programming SoC gateware {}".format(args.soc)) - with open(args.soc, "rb") as f: - image = f.read() - if verify == True: - print("Note: SoC verification is not possible as readback is locked for security purposes") - pc_usb.flash_program(locs['LOC_SOC'][0], image, verify=False) - print("Erasing PDDB root structures") - pc_usb.erase_region(locs['LOC_PDDB'][0], 1024 * 1024) - else: - print("This will overwrite any secret keys in your device and erase PDDB keys. Continue? (y/n)") - confirm = input() - if len(confirm) > 0 and confirm.lower()[:1] == 'y': - print("Programming SoC gateware {}".format(args.soc)) - with open(args.soc, "rb") as f: - image = f.read() - if verify == True: - print("Note: SoC verification is not possible as readback is locked for security purposes") - pc_usb.flash_program(locs['LOC_SOC'][0], image, verify=False) - print("Erasing PDDB root structures") - pc_usb.erase_region(locs['LOC_PDDB'][0], 1024 * 1024) - - - if args.audiotest != None: - print("Loading audio test clip {}".format(args.audiotest)) - with open(args.audiotest, "rb") as f: - image = f.read() - if len(image) >= locs['LEN_AUDIO'][0]: - print("audio file is too long, aborting audio burn!") - else: - pc_usb.flash_program(locs['LOC_AUDIO'][0], image, verify=verify) - - if args.factory_new: - base_url = "https://ci.betrusted.io/releases/v0.9.5/" - # erase the entire flash - pc_usb.erase_region(0, 0x800_0000) - # burn the gateware - for sections in locs.values(): - if sections[1] != 'pass': - print('retrieving {}'.format(base_url + sections[1])) - with urllib.request.urlopen(base_url + sections[1]) as f: - print('burning at {:x}'.format(sections[0])) - image = f.read() - pc_usb.flash_program(sections[0], image, verify=False) - - - print("Resuming CPU.") - pc_usb.poke(vexdbg_addr, 0x02000000) - - print("Resetting SOC...") - try: - pc_usb.poke(pc_usb.register('reboot_soc_reset'), 0xac, display=False) - except usb.core.USBError: - pass # we expect an error because we reset the SOC and that includes the USB core - - # print("If you need to run more commands, please unplug and re-plug your device in, as the Precursor USB core was just reset") - -if __name__ == "__main__": - main() - exit(0) diff --git a/tools/legacy/usb_update.py b/tools/legacy/usb_update.py new file mode 120000 index 000000000..df25fb3c7 --- /dev/null +++ b/tools/legacy/usb_update.py @@ -0,0 +1 @@ +../usb_update.py \ No newline at end of file