def run(args, builder, build_kwargs, target_name): # Generate files in the build directory configure_generated_files(builder, args, target_name) # Build & run if not args.sim: # hardware builder.build(**build_kwargs, run=args.build) else: # simulation sim_kwargs = get_sim_kwargs(args) builder.build(**build_kwargs, run=args.build, **sim_kwargs) if args.docs: doc.generate_docs(builder.soc, base_dir="build/documentation", project_name="LiteX Row Hammer Tester", author="Antmicro") if args.load: prog = builder.soc.platform.create_programmer() prog.load_bitstream( os.path.join(builder.gateware_dir, builder.soc.build_name + ".bit")) if args.load_bios: assert args.rw_bios_mem, 'BIOS memory must be writible' from rowhammer_tester.scripts.utils import RemoteClient, memwrite wb = RemoteClient() wb.open() from litex.soc.integration.common import get_mem_data bios_bin = os.path.join(builder.software_dir, "bios", "bios.bin") rom_data = get_mem_data(bios_bin, "little") print( f"Loading BIOS from: {bios_bin} starting at 0x{wb.mems.rom.base:08x} ..." ) print('Stopping CPU') wb.regs.ctrl_reset.write(0b10) # cpu_rst memwrite(wb, rom_data, base=wb.mems.rom.base) wb.read(wb.mems.rom.base) print('Rebooting CPU') wb.regs.ctrl_reset.write(0) wb.close() if args.flash: prog = builder.soc.platform.create_programmer() prog.flash( 0, os.path.join(builder.gateware_dir, builder.soc.build_name + ".bin"))
def main(): valid_keys = set( [ "payload_generator", "payload_generator_config", "inversion_divisor", "inversion_mask", "row_pattern" ]) parser = argparse.ArgumentParser() parser.add_argument("config_file", type=open) args = parser.parse_args() config_string = "" config_lines = args.config_file.readlines() for line in config_lines: index = line.find('#') if index >= 0: line = line[0:index] line += '\n' config_string += line config = json.loads(config_string) assert validate_keys(config, valid_keys) args.config_file.close() pg = PayloadGenerator.get_by_name(config["payload_generator"]) pg.initialize(config) wb = RemoteClient() wb.open() settings = get_litedram_settings() inversion_divisor = 0 inversion_mask = 0 inversion_divisor = config.get("inversion_divisor", 0) inversion_mask = int(config.get("inversion_mask", "0"), 0) row_pattern = config.get("row_pattern", 0) setup_inverters(wb, inversion_divisor, inversion_mask) while not pg.done(): offset, size = pg.get_memset_range(wb, settings) hw_memset(wb, offset, size, [row_pattern]) converter = DRAMAddressConverter.load() bank = 0 sys_clk_freq = float(get_generated_defs()['SYS_CLK_FREQ']) payload = pg.get_payload( settings=settings, bank=bank, payload_mem_size=wb.mems.payload.size, sys_clk_freq=sys_clk_freq) execute_payload(wb, payload) offset, size = pg.get_memtest_range(wb, settings) errors = hw_memtest(wb, offset, size, [row_pattern]) row_errors = decode_errors(wb, settings, converter, bank, errors) pg.process_errors(settings, row_errors) pg.summarize() wb.close()
elapsed = time.time() - start bytes_per_sec = nbytes / elapsed print('Elapsed = {:.3f} sec'.format(elapsed)) def human(val): if val > 2**20: return (val / 2**20, 'M') elif val > 2**10: return (val / 2**10, 'K') return (val, '') print('Size = {:.3f} {}B'.format(*human(nbytes))) print('Speed = {:.3f} {}Bps'.format(*human(bytes_per_sec))) if __name__ == "__main__": parser = argparse.ArgumentParser(description='Measure EtherBone bridge performance') parser.add_argument('rw', choices=['memread', 'memwrite'], help='Transfer type') parser.add_argument('n', help='Number of 32-bit words transfered') parser.add_argument('--burst', required=True, help='Burst size') parser.add_argument('--profile', action='store_true', help='Profile the code with cProfile') args = parser.parse_args() wb = RemoteClient() wb.open() run(wb, args.rw, int(args.n, 0), burst=int(args.burst, 0), profile=args.profile) wb.close()
def main(row_hammer_cls): parser = argparse.ArgumentParser() parser.add_argument('--nrows', type=int, default=0, help='Number of rows to consider') parser.add_argument('--bank', type=int, default=0, help='Bank number') parser.add_argument('--column', type=int, default=512, help='Column to read from') parser.add_argument('--start-row', type=int, default=0, help='Starting row (range = (start, start+nrows))') parser.add_argument( '--read_count', type=float, default=10e6, help='How many reads to perform for single address pair') parser.add_argument('--hammer-only', nargs=2, type=int, help='Run only the row hammer attack') parser.add_argument('--no-refresh', action='store_true', help='Disable refresh commands during the attacks') parser.add_argument( '--pattern', default='01_per_row', choices=['all_0', 'all_1', '01_in_row', '01_per_row', 'rand_per_row'], help='Pattern written to DRAM before running attacks') parser.add_argument( '--row-pairs', choices=['sequential', 'const', 'random'], default='sequential', help='How the rows for subsequent attacks are selected') parser.add_argument('--const-rows-pair', type=int, nargs='+', required=False, help='When using --row-pairs constant') parser.add_argument('--plot', action='store_true', help='Plot errors distribution' ) # requiers matplotlib and pyqt5 packages parser.add_argument( '--payload-executor', action='store_true', help='Do the attack using Payload Executor (1st row only)') parser.add_argument('-v', '--verbose', action='store_true', help='Be more verbose') parser.add_argument("--srv", action="store_true", help='Start LiteX server') parser.add_argument("--experiment-no", type=int, default=0, help='Run preconfigured experiment #no') args = parser.parse_args() if args.experiment_no == 1: args.nrows = 512 args.read_count = 15e6 args.pattern = '01_in_row' args.row_pairs = 'const' args.const_rows_pair = 88, 99 args.no_refresh = True if args.srv: litex_server() wb = RemoteClient() wb.open() row_hammer = row_hammer_cls( wb, nrows=args.nrows, settings=get_litedram_settings(), column=args.column, bank=args.bank, rows_start=args.start_row, verbose=args.verbose, plot=args.plot, no_refresh=args.no_refresh, payload_executor=args.payload_executor, ) if args.hammer_only: row_hammer.attack(*args.hammer_only, read_count=args.read_count) else: rng = random.Random(42) def rand_row(): return rng.randint(args.start_row, args.start_row + args.nrows) assert not (args.row_pairs == 'const' and not args.const_rows_pair), 'Specify --const-rows-pair' row_pairs = { 'sequential': [(0 + args.start_row, i + args.start_row) for i in range(args.nrows)], 'const': [tuple(args.const_rows_pair)], 'random': [(rand_row(), rand_row()) for i in range(args.nrows)], }[args.row_pairs] pattern = { 'all_0': lambda rows: patterns_const(rows, 0x00000000), 'all_ones': lambda rows: patterns_const(rows, 0xffffffff), '01_in_row': lambda rows: patterns_const(rows, 0xaaaaaaaa), '01_per_row': patterns_alternating_per_row, 'rand_per_row': patterns_random_per_row, }[args.pattern] row_hammer.run(row_pairs=row_pairs, read_count=args.read_count, pattern_generator=pattern) wb.close()