def discover_boards(rsu_config, args): """discover_boards discover FPGA devices in sysfs given a config :param rsu_config(dict): A dictionary describing the product to discover. This config should be made up of a product name and a list of files to flash. The product will be mapped to a PCI identifer to match. This file will be passed to 'fpgaboard' for loading flash binaries. """ product_name = rsu_config.get('product') if product_name is None: LOG.warning("RSU config file missing 'product' key") return [] product_vendor = rsu_config.get('vendor') if product_vendor is None: LOG.warning("RSU config file missing 'vendor' key") return [] product_device = rsu_config.get('device') if product_device is None: LOG.warning("RSU config file missing 'device' key") return [] boards = [] enum_filter = {'pci_node.device_id': int(product_device, 0), 'pci_node.vendor_id': int(product_vendor, 0)} if args.bus: enum_filter['pci_node.bus'] = args.bus for device in fpga_device.enum([enum_filter]): boards.append(make_pac(device.pci_node, device)) return boards
def find_config(program='super-rsu', configuration=None): candidates = [] for root, dirs, files in os.walk('/usr/share/opae'): for f in glob.glob(os.path.join(root, '*.json')): try: with open(f, 'r') as fp: data = json.load(fp) cfg_pgm = data.get('program') cfg_vid = int(data.get('vendor', '0'), 0) cfg_did = int(data.get('device', '0'), 0) cfg_cfg = data.get('configuration') except IOError: LOG.warning('could not open file: %s', f) except ValueError as err: LOG.warning('could not decode JSON file, %s: %s', f, err) except AttributeError: # not a recognized schema pass else: # check if program is either in the manifest data # or at least it is in the file path if cfg_pgm == program or (cfg_pgm is None and program in f): if fpga_device.enum([{'pci_node.vendor_id': cfg_vid, 'pci_node.device_id': cfg_did}]): LOG.debug('found possible config: %s', f) if configuration is None or (cfg_cfg == configuration): candidates.append(f) if len(candidates) == 1: try: return open(candidates[0], 'r') except IOError: pass LOG.warning('could not find or open suitable super-rsu manifest')
def test_enum_fpga(): for o in fpga.enum([{'pci_node.device_id': 0xb30}]): print(o.pci_node) print(o.pci_node.root.tree()) print(o.fme.devpath) print(o.fme.i2c_bus.sysfs_path) print(o.fme.spi_bus.sysfs_path) print(o.port.devpath)
def main(): actions = {'assign': assign, 'release': release} # parse command line arguments parser = argparse.ArgumentParser() parser.add_argument('action', action='store', choices=sorted(actions.keys()), help='Action to perform - {}'.format( list(actions.keys()))) parser.add_argument('device', help=('The FPGA (FME) device. ' 'Can be identified by dev path (/dev/dfl-fme.0) ' 'or by PCIe address: ' '([<segment>:]<bus>:<device>.<function>')) parser.add_argument('port', type=int, default=0, nargs='?', help='The port number.') parser.add_argument('-N', '--numvfs', type=int, help='Create VFs from the argument given.') parser.add_argument('-X', '--destroy-vfs', action='store_true', default=False, help='Destroy all VFs prior to assigning.') parser.add_argument('--debug', action='store_true', default=False, help='Set logging to DEBUG if verbose selected') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level, format=('[%(asctime)-15s] [%(levelname)-8s] ' '%(message)s')) devices = fpga.enum([fpga_filter(args.device)]) if not devices: LOG.error('Could not find device using pattern: "%s"', args.device) sys.exit(os.EX_USAGE) for device in devices: actions[args.action](args, device)
def main(): args = parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level, format='%(asctime)s - %(message)s') compatible = fpga.enum([{'supports_rsu': True}]) if not compatible: sys.stderr.write('No compatible devices found\n') raise SystemExit(os.EX_USAGE) if args.bdf is None: if len(compatible) == 1: args.bdf = compatible[0].pci_node.pci_address elif len(compatible) > 1: prog = os.path.basename(sys.argv[0]) sys.stderr.write(('Please specify PCIe address as ' '[<segment>:]<bus>:<device>.<function>\n')) sys.stderr.write('Acceptable commands:\n') for dev in compatible: sys.stderr.write('>{} {} {}\n'.format(prog, args.type, dev.pci_node.bdf)) raise SystemExit(os.EX_USAGE) bdf = normalize_bdf(args.bdf) Path(RSU_LOCK_DIR).mkdir(parents=True, exist_ok=True) for device in compatible: if device.pci_node.pci_address == bdf: exit_code = os.EX_IOERR with open(RSU_LOCK_FILE, 'w') as flock: fcntl.flock(flock.fileno(), fcntl.LOCK_EX) try: do_rsu(args.type, device, args.factory) except IOError: logging.error('RSU operation failed') else: exit_code = os.EX_OK logging.info('RSU operation complete') finally: fcntl.flock(flock.fileno(), fcntl.LOCK_UN) raise SystemExit(exit_code) logging.error(('PCIe address (%s) is invalid or does not identify a' 'compatible device'), args.bdf)
def main(): """The main entry point.""" parser, args = parse_args() if args.file is None: print('Error: file is a required argument\n') parser.print_help(sys.stderr) sys.exit(1) LOG.setLevel(logging.NOTSET) log_fmt = ('[%(asctime)-15s] [%(levelname)-8s] ' '%(message)s') log_hndlr = logging.StreamHandler(sys.stdout) log_hndlr.setFormatter(logging.Formatter(log_fmt)) log_hndlr.setLevel(LOG_NAMES_TO_LEVELS[args.log_level]) LOG.addHandler(log_hndlr) signal.signal(signal.SIGTERM, sig_handler) LOG.debug('fw file: %s', args.file.name) LOG.debug('addr: %s', args.bdf) stat = 1 mesg = 'Secure update failed' gbs_hdr = None blk0 = decode_auth_block0(args.file, not args.yes) if blk0 is None: gbs_hdr = decode_gbs_header(args.file) if gbs_hdr is None: LOG.error('Unknown file format in %s', args.file.name) sys.exit(1) pac = None if args.bdf == DEFAULT_BDF: # Address wasn't specified. Enumerate all PAC's. if gbs_hdr: pr_guid = gbs_hdr['interface-uuid'].replace('-', '') pacs = fpga.enum([{'fme.pr_interface_id': pr_guid}]) else: pacs = fpga.enum() if not pacs: LOG.error('No suitable PAC found.') sys.exit(1) elif len(pacs) > 1: LOG.error('More than one PAC found. ' 'Please specify an %s', DEFAULT_BDF) sys.exit(1) pac = pacs[0] else: # Enumerate for a specific device. canon_bdf = canonicalize_bdf(args.bdf) if not canon_bdf: LOG.error('%s is not a valid PCIe address. ' 'Use %s', args.bdf, DEFAULT_BDF) sys.exit(1) pacs = fpga.enum([{'pci_node.pci_address': canon_bdf}]) if not pacs: LOG.error('Failed to find PAC at %s', canon_bdf) sys.exit(1) pac = pacs[0] if gbs_hdr: # verify the PR interface uuid fme = pac.fme if fme: pr_guid = gbs_hdr['interface-uuid'].replace('-', '') if fme.pr_interface_id.replace('-', '') != pr_guid: LOG.error('PR interface uuid mismatch.') sys.exit(1) LOG.warning('Update starting. Please do not interrupt.') start = datetime.now() if gbs_hdr is not None: args.file.close() stat, mesg = do_partial_reconf(pac.pci_node.pci_address, args.file.name) elif blk0 is not None: sec_dev = pac.secure_dev if not sec_dev: LOG.error('Failed to find secure ' 'device for PAC %s', pac.pci_node.pci_address) sys.exit(1) LOG.debug('Found secure device for PAC ' '%s', pac.pci_node.pci_address) try: stat, mesg = update_fw(args, pac) except SecureUpdateError as exc: stat, mesg = exc.errno, exc.strerror except KeyboardInterrupt: if TMPFILE and os.path.isfile(TMPFILE): os.remove(TMPFILE) cancel = sec_dev.find_one(os.path.join('update', 'cancel')) cancel.value = 1 stat, mesg = 1, 'Interrupted' if stat and mesg == 'flash_wearout': mesg = ('Secure update is delayed due to excessive flash counts.\n' 'Please wait 30 seconds and try again.') if stat: LOG.error(mesg) else: LOG.info(mesg) LOG.info('Total time: %s', datetime.now() - start) sys.exit(stat)
def main(): """The main entry point""" parser, args = parse_args() if args.manifest is None: print('Error: manifest is a required argument\n') parser.print_help(sys.stderr) sys.exit(1) LOG.setLevel(logging.NOTSET) log_fmt = ('[%(asctime)-15s] [%(levelname)-8s] ' '[%(threadName)s] %(message)s') log_hndlr = logging.StreamHandler(sys.stdout) log_hndlr.setFormatter(logging.Formatter(log_fmt)) log_hndlr.setLevel(logging.getLevelName(args.log_level.upper())) LOG.addHandler(log_hndlr) signal.signal(signal.SIGINT, sig_handler) signal.signal(signal.SIGTERM, sig_handler) loader = otsu_manifest_loader(args.manifest) json_cfg = loader.load() if json_cfg is None: LOG.error('Failed to process manifest: %s', args.manifest.name) sys.exit(1) # Find the PAC described by the manifest. enum_filter = { 'pci_node.vendor_id': to_int(json_cfg['vendor'])[1], 'pci_node.device_id': to_int(json_cfg['device'])[1] } pacs = fpga.enum([enum_filter]) if not pacs: LOG.error('failed to find any suitable PAC: %s:%s', json_cfg['vendor'], json_cfg['device']) sys.exit(1) errors = 0 updaters = [] for pac in pacs: if pac.secure_dev: LOG.info('%s %s is already secure.', json_cfg['product'], pac.pci_node.pci_address) continue LOG.info('%s %s is not secure.', json_cfg['product'], pac.pci_node.pci_address) updater = otsu_updater(os.path.dirname(args.manifest.name), pac, json_cfg) if updater.check_requires(): updaters.append(updater) else: errors += 1 LOG.warning( '%s %s one or more prerequisite checks ' 'failed. Skipping this device.', json_cfg['product'], pac.pci_node.pci_address) LOG.warning('Update starting. Please do not interrupt.') start = datetime.now() if not args.verify: errors += run_updaters(updaters) else: errors += len(updaters) if args.rsu: for updater in updaters: if updater.error_count == 0: updater.pac.safe_rsu_boot() LOG.info('Total time: %s', datetime.now() - start) if errors > 0: for updater in updaters: updater.log_errors(LOG.error) LOG.error('One-Time Secure Update failed') else: LOG.info('One-Time Secure Update OK') sys.exit(errors)