Exemplo n.º 1
0
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"))
Exemplo n.º 2
0
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()
Exemplo n.º 4
0
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()