Пример #1
0
def on_configure(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    check_arg_count('configure', 1, args)

    enable = read_word('secure_wipe_en', args[0], 1) != 0
    sim.configure(enable)

    return None
Пример #2
0
def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('elf')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('--dmem-dump')

    args = parser.parse_args()

    sim = OTBNSim()
    load_elf(sim, args.elf)

    sim.state.pc = 0
    sim.state.start()
    sim.run(verbose=args.verbose)

    if args.dmem_dump is not None:
        try:
            with open(args.dmem_dump, 'wb') as dmem_file:
                dmem_file.write(sim.dump_data())
        except OSError as err:
            sys.stderr.write('Failed to write DMEM to {!r}: {}.'
                             .format(args.dmem_dump, err))
            return 1

    return 0
Пример #3
0
def _run_sim_for_stats(sim: OTBNSim) -> ExecutionStats:
    sim.run(verbose=False, collect_stats=True)

    # Ensure that the execution was successful.
    assert sim.state.ext_regs.read('ERR_BITS', False) == 0

    assert sim.stats
    return sim.stats
Пример #4
0
def on_load_i(sim: OTBNSim, args: List[str]) -> None:
    '''Load contents of insn memory from file at path given by only argument'''
    if len(args) != 1:
        raise ValueError(
            'load_i expects exactly 1 argument. Got {}.'.format(args))
    path = args[0]

    print('LOAD_I {!r}'.format(path))
    sim.load_program(decode_file(0, path))
Пример #5
0
def on_start(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Jump to an address given as the (only) argument and start running'''
    check_arg_count('start', 0, args)

    print('START')
    sim.state.ext_regs.commit()
    sim.start(collect_stats=False)

    return None
Пример #6
0
def on_start(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Jump to an address given as the (only) argument and start running'''
    if len(args) != 0:
        raise ValueError('start expects zero arguments. Got {}.'.format(args))

    print('START')
    sim.state.ext_regs.commit()
    sim.start(collect_stats=False)

    return None
Пример #7
0
def on_load_i(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Load contents of insn memory from file at path given by only argument'''
    check_arg_count('load_i', 1, args)

    path = args[0]

    print('LOAD_I {!r}'.format(path))
    sim.load_program(decode_file(0, path))

    return None
Пример #8
0
def on_load_d(sim: OTBNSim, args: List[str]) -> None:
    '''Load contents of data memory from file at path given by only argument'''
    if len(args) != 1:
        raise ValueError(
            'load_d expects exactly 1 argument. Got {}.'.format(args))
    path = args[0]

    print('LOAD_D {!r}'.format(path))
    with open(path, 'rb') as handle:
        sim.load_data(handle.read())
Пример #9
0
def on_load_d(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Load contents of data memory from file at path given by only argument'''
    check_arg_count('load_d', 1, args)

    path = args[0]

    print('LOAD_D {!r}'.format(path))
    with open(path, 'rb') as handle:
        sim.load_data(handle.read(), has_validity=True)

    return None
Пример #10
0
def _run_sim_for_stats(asm_file: str, tmpdir: str) -> ExecutionStats:
    """ Run the OTBN simulator, collect statistics, and return them. """

    assert os.path.exists(asm_file)
    elf_file = testutil.asm_and_link_one_file(asm_file, tmpdir)

    sim = OTBNSim()
    load_elf(sim, elf_file)

    sim.state.start(0)
    sim.run(verbose=False, collect_stats=True)

    return sim.stats
Пример #11
0
def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("imem_words", type=int)
    parser.add_argument("imem_file")
    parser.add_argument("dmem_words", type=int)
    parser.add_argument("dmem_file")
    parser.add_argument("cycles_file")
    parser.add_argument("trace_file")
    parser.add_argument("start_addr", type=int)

    args = parser.parse_args()
    sim = OTBNSim(OTBNModel(verbose=args.trace_file))

    sim.load_program(decode_file(args.imem_file))
    with open(args.dmem_file, "rb") as f:
        sim.load_data(f.read())

    cycles = sim.run(start_addr=args.start_addr)

    with open(args.dmem_file, "wb") as f:
        f.write(sim.dump_data())

    with open(args.cycles_file, "wb") as f:
        f.write(struct.pack("<L", cycles))

    return 0
Пример #12
0
def on_start(sim: OTBNSim, args: List[str]) -> None:
    '''Jump to an address given as the (only) argument and start running'''
    if len(args) != 1:
        raise ValueError('start expects exactly 1 argument. Got {}.'
                         .format(args))

    addr = read_word('addr', args[0], 32)
    if addr & 3:
        raise ValueError('start address must be word-aligned. Got {:#08x}.'
                         .format(addr))
    print('START {:#08x}'.format(addr))
    sim.state.ext_regs.write('START_ADDR', addr, False)
    sim.state.ext_regs.commit()
    sim.start()
Пример #13
0
def on_clear_loop_warps(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Run until ecall or error'''
    check_arg_count('clear_loop_warps', 0, args)

    sim.loop_warps = {}

    return None
Пример #14
0
def on_run(sim: OTBNSim, args: List[str]) -> None:
    '''Run until ecall or error'''
    if len(args):
        raise ValueError('run expects zero arguments. Got {}.'.format(args))

    num_cycles = sim.run(verbose=False)
    print(' ran for {} cycles'.format(num_cycles))
Пример #15
0
def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('elf')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument(
        '--dump-dmem',
        metavar="FILE",
        type=argparse.FileType('wb'),
        help=("after execution, write the data memory contents to this file. "
              "Use '-' to write to STDOUT."))
    parser.add_argument(
        '--dump-regs',
        metavar="FILE",
        type=argparse.FileType('w'),
        help=("after execution, write the GPR and WDR contents to this file. "
              "Use '-' to write to STDOUT."))
    parser.add_argument(
        '--dump-stats',
        metavar="FILE",
        type=argparse.FileType('w'),
        help=("after execution, write execution statistics to this file. "
              "Use '-' to write to STDOUT."))

    args = parser.parse_args()

    collect_stats = args.dump_stats is not None

    sim = OTBNSim()
    load_elf(sim, args.elf)

    sim.state.start(0)
    sim.run(verbose=args.verbose, collect_stats=collect_stats)

    if args.dump_dmem is not None:
        args.dump_dmem.write(sim.dump_data())

    if args.dump_regs is not None:
        for idx, value in enumerate(sim.state.gprs.peek_unsigned_values()):
            args.dump_regs.write(' x{:<2} = 0x{:08x}\n'.format(idx, value))
        for idx, value in enumerate(sim.state.wdrs.peek_unsigned_values()):
            args.dump_regs.write(' w{:<2} = 0x{:064x}\n'.format(idx, value))

    if collect_stats:
        stat_analyzer = ExecutionStatAnalyzer(sim.stats, args.elf)
        args.dump_stats.write(stat_analyzer.dump())

    return 0
Пример #16
0
def main() -> int:
    sim = OTBNSim()
    try:
        for line in sys.stdin:
            on_input(sim, line)
    except KeyboardInterrupt:
        print("Received shutdown request, ending OTBN simulation.")
        return 0
    return 0
Пример #17
0
def on_clear_loop_warps(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Run until ecall or error'''
    if len(args):
        raise ValueError(
            'clear_loop_warps expects zero arguments. Got {}.'.format(args))

    sim.loop_warps = {}

    return None
Пример #18
0
def prepare_sim_for_asm_file(asm_file: str,
                             tmpdir: py.path.local,
                             start_addr: int = 0) -> OTBNSim:
    '''Set up the simulation of a single assembly file.

    The returned simulation is ready to be run through the run() method.

    '''
    assert os.path.exists(asm_file)
    elf_file = asm_and_link_one_file(asm_file, tmpdir)

    sim = OTBNSim()
    load_elf(sim, elf_file)

    sim.state.ext_regs.write('START_ADDR', start_addr, False)
    sim.state.ext_regs.commit()
    sim.start()
    return sim
Пример #19
0
def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('elf')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument(
        '--dump-dmem',
        metavar="FILE",
        type=argparse.FileType('wb'),
        help=("after execution, write the data memory contents to this file. "
              "Use '-' to write to STDOUT."))
    parser.add_argument(
        '--dump-regs',
        metavar="FILE",
        type=argparse.FileType('w'),
        help=("after execution, write the GPR and WDR contents to this file. "
              "Use '-' to write to STDOUT."))
    parser.add_argument(
        '--dump-stats',
        metavar="FILE",
        type=argparse.FileType('w'),
        help=("after execution, write execution statistics to this file. "
              "Use '-' to write to STDOUT."))

    args = parser.parse_args()

    collect_stats = args.dump_stats is not None

    sim = OTBNSim()
    exp_end_addr = load_elf(sim, args.elf)

    sim.state.ext_regs.write('START_ADDR', 0, False)
    sim.state.ext_regs.commit()

    sim.start()
    sim.run(verbose=args.verbose, collect_stats=collect_stats)

    if exp_end_addr is not None:
        if sim.state.pc != exp_end_addr:
            print('Run stopped at PC {:#x}, but _expected_end_addr was {:#x}.'.
                  format(sim.state.pc, exp_end_addr),
                  file=sys.stderr)
            return 1

    if args.dump_dmem is not None:
        args.dump_dmem.write(sim.dump_data())

    if args.dump_regs is not None:
        for idx, value in enumerate(sim.state.gprs.peek_unsigned_values()):
            args.dump_regs.write(' x{:<2} = 0x{:08x}\n'.format(idx, value))
        for idx, value in enumerate(sim.state.wdrs.peek_unsigned_values()):
            args.dump_regs.write(' w{:<2} = 0x{:064x}\n'.format(idx, value))

    if collect_stats:
        assert sim.stats is not None
        stat_analyzer = ExecutionStatAnalyzer(sim.stats, args.elf)
        args.dump_stats.write(stat_analyzer.dump())

    return 0
Пример #20
0
def on_step(sim: OTBNSim, args: List[str]) -> None:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'.format(args))

    pc = int(sim.model.state.pc)

    assert 0 == pc & 3
    print('EXEC {:#08x}'.format(pc))
    done, changes = sim.step()
    for trace in changes:
        print('  {}'.format(trace))
Пример #21
0
def on_step(sim: OTBNSim, args: List[str]) -> None:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'.format(args))

    pc = int(sim.state.pc)

    assert 0 == pc & 3
    insn, changes = sim.step(verbose=False)
    disasm = '(not running)' if insn is None else insn.disassemble(pc)
    print('EXEC {:#08x}:     {}'.format(pc, disasm))
    for trace in changes:
        print('  {}'.format(trace))
Пример #22
0
def on_add_loop_warp(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Add a loop warp to the simulation'''
    check_arg_count('add_loop_warp', 3, args)

    try:
        addr = int(args[0], 0)
        if addr < 0:
            raise ValueError('addr is negative')
        from_cnt = int(args[1], 0)
        if from_cnt < 0:
            raise ValueError('from_cnt is negative')
        to_cnt = int(args[2], 0)
        if to_cnt < 0:
            raise ValueError('to_cnt is negative')
    except ValueError as err:
        raise ValueError(
            'Bad argument to add_loop_warp: {}'.format(err)) from None

    print('ADD_LOOP_WARP {:#x} {} {}'.format(addr, from_cnt, to_cnt))
    sim.add_loop_warp(addr, from_cnt, to_cnt)

    return None
Пример #23
0
def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('elf')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument(
        '--dump-dmem',
        metavar="FILE",
        type=argparse.FileType('wb'),
        help="after execution, write the data memory contents to this file")
    parser.add_argument(
        '--dump-regs',
        metavar="FILE",
        type=argparse.FileType('w'),
        default=sys.stdout,
        help=
        "after execution, write the GPR and WDR contents to this file (default: STDOUT)"
    )

    args = parser.parse_args()

    sim = OTBNSim()
    load_elf(sim, args.elf)

    sim.state.pc = 0
    sim.state.start()
    sim.run(verbose=args.verbose)

    if args.dump_dmem is not None:
        args.dump_dmem.write(sim.dump_data())

    if args.dump_regs is not None:
        for idx, value in enumerate(sim.state.gprs.peek_unsigned_values()):
            args.dump_regs.write(' x{:<2} = 0x{:08x}\n'.format(idx, value))
        for idx, value in enumerate(sim.state.wdrs.peek_unsigned_values()):
            args.dump_regs.write(' w{:<2} = 0x{:064x}\n'.format(idx, value))

    return 0
Пример #24
0
def on_step(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Step one instruction'''
    check_arg_count('step', 0, args)

    pc = sim.state.pc
    assert 0 == pc & 3

    insn, changes = sim.step(verbose=False)

    print('STALL' if insn is None else insn.rtl_trace(pc))
    for change in changes:
        entry = change.rtl_trace()
        if entry is not None:
            print(entry)

    return None
Пример #25
0
def on_step(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'.format(args))

    pc = sim.state.pc
    assert 0 == pc & 3

    insn, changes = sim.step(verbose=False)

    print('STALL' if insn is None else insn.rtl_trace(pc))
    for change in changes:
        entry = change.rtl_trace()
        if entry is not None:
            print(entry)

    return None
Пример #26
0
def on_step(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Step one instruction'''
    check_arg_count('step', 0, args)

    pc = sim.state.pc
    assert 0 == pc & 3

    was_wiping = sim.state.wiping() and sim.state.secure_wipe_enabled

    insn, changes = sim.step(verbose=False)
    if insn is not None:
        hdr = insn.rtl_trace(pc)  # type: Optional[str]
    elif was_wiping:
        # The trailing space is a bit naff but matches the behaviour in the RTL
        # tracer, where it's rather difficult to change.
        hdr = 'U ' if sim.state.wiping() else 'V '
    elif (sim.state.executing() or
          (changes and not sim.state.secure_wipe_enabled)):
        hdr = 'STALL'
    else:
        hdr = None

    rtl_changes = []
    for c in changes:
        rt = c.rtl_trace()
        if rt is not None:
            rtl_changes.append(rt)

    # This is a bit of a hack. Very occasionally, we'll see traced changes when
    # there's not actually an instruction in flight. For example, this happens
    # if there's a RND request still pending when an operation stops. In this
    # case, we might see a change where we drop the REQ signal after the secure
    # wipe has finished. Rather than define a special "do-nothing" trace entry
    # format for this situation, we cheat and use STALL.
    if hdr is None and rtl_changes:
        hdr = 'STALL'

    if hdr is not None:
        print(hdr)
        for rt in rtl_changes:
            print(rt)

    return None
Пример #27
0
def on_step(sim: OTBNSim, args: List[str]) -> None:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'.format(args))

    pc = sim.state.pc
    assert 0 == pc & 3

    insn, changes = sim.step(verbose=False)

    if insn is None:
        hdr = 'STALL'
    else:
        hdr = 'E PC: {:#010x}, insn: {:#010x}'.format(pc, insn.raw)
    print(hdr)
    for change in changes:
        entry = change.rtl_trace()
        if entry is not None:
            print(entry)
Пример #28
0
def on_step(sim: OTBNSim, args: List[str]) -> None:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'
                         .format(args))

    pc = sim.state.pc
    assert 0 == pc & 3

    insn, changes = sim.step(verbose=False, collect_stats=False)

    if insn is None:
        print('STALL')
    else:
        print(f'E PC: {pc:#010x}, insn: {insn.raw:#010x}')
        print(f'# @{pc:#010x}: {insn.insn.mnemonic}')

    for change in changes:
        entry = change.rtl_trace()
        if entry is not None:
            print(entry)
Пример #29
0
def on_step(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    '''Step one instruction'''
    check_arg_count('step', 0, args)

    pc = sim.state.pc
    assert 0 == pc & 3

    was_wiping = sim.state.wiping() and sim.state.secure_wipe_enabled

    insn, changes = sim.step(verbose=False)
    if insn is not None:
        hdr = insn.rtl_trace(pc)  # type: Optional[str]
    elif was_wiping:
        # The trailing space is a bit naff but matches the behaviour in the RTL
        # tracer, where it's rather difficult to change.
        hdr = 'U ' if sim.state.wiping() else 'V '
    elif (sim.state.running()
          or (changes and not sim.state.secure_wipe_enabled)):
        hdr = 'STALL'
    else:
        hdr = None

    rtl_changes = []
    for c in changes:
        rt = c.rtl_trace()
        if rt is not None:
            rtl_changes.append(rt)

    if hdr is None:
        assert not rtl_changes
    else:
        print(hdr)
        for rt in rtl_changes:
            print(rt)

    return None
Пример #30
0
def on_reset(sim: OTBNSim, args: List[str]) -> Optional[OTBNSim]:
    if args:
        raise ValueError('reset expects zero arguments. Got {}.'.format(args))

    return OTBNSim()