Exemplo n.º 1
0
def execute(wb):
    depth = wb.mems.payload.size // 4  # bytes to 32-bit instructions

    program = [w for w in PAYLOAD]
    program += [0] * (wb.mems.payload.size // 4 - len(program)
                      )  # fill with NOOPs

    # Write some data to the column we are reading to check that scratchpad gets filled
    converter = DRAMAddressConverter.load()
    data = list(itertools.islice(word_gen(3), 128))
    memwrite(wb, data, base=converter.encode_bus(bank=0, row=100, col=200))

    print('\nTransferring the payload ...')
    memwrite(wb, program, base=wb.mems.payload.base)

    def ready():
        status = wb.regs.payload_executor_status.read()
        return (status & 1) != 0

    print('\nExecuting ...')
    assert ready()
    wb.regs.payload_executor_start.write(1)
    while not ready():
        time.sleep(0.001)

    print('Finished')

    print('\nScratchpad contents:')
    scratchpad = memread(wb, n=512 // 4, base=wb.mems.scratchpad.base)
    memdump(scratchpad, base=0)
Exemplo n.º 2
0
 def runner():
     if profile:
         cProfile.runctx(command, {}, ctx, fname)
     else:
         if is_write:
             memwrite(wb, datas, burst=burst)
         else:
             x = len(memread(wb, n, burst=burst))
 def runner():
     if profile:
         cProfile.runctx(command, {}, ctx, fname)
     else:
         if rw == 'memread':
             x = len(memread(wb, n, burst=burst))
             print(x)
         else:
             memwrite(wb, datas, burst=burst)
Exemplo n.º 4
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"))
    def attack(self, row_tuple, read_count, progress_header=''):
        addresses = [
            self.converter.encode_dma(bank=self.bank, col=self.column, row=r)
            for r in row_tuple
        ]
        row_strw = len(str(2**self.settings.geom.rowbits - 1))

        # FIXME: ------------------ move to utils ----------------------------
        # Flush error fifo
        self.wb.regs.reader_skip_fifo.write(1)
        time.sleep(0.1)
        # Enable error FIFO
        self.wb.regs.reader_skip_fifo.write(0)

        assert self.wb.regs.reader_ready.read() == 1

        # Skip errors fifo
        self.wb.regs.reader_skip_fifo.write(1)

        # Do not increment memory address
        self.wb.regs.reader_mem_mask.write(0x00000000)
        self.wb.regs.reader_data_mask.write(len(row_tuple) - 1)

        # Attacked addresses
        memwrite(self.wb, addresses, base=self.wb.mems.pattern_addr.base)

        # how many
        print('read_count: ' + str(int(read_count)))
        self.wb.regs.reader_count.write(int(read_count))

        self.wb.regs.reader_start.write(1)
        self.wb.regs.reader_start.write(0)

        # FIXME: --------------------------- move to utils ------------------

        def progress(count):
            s = '  {}'.format(progress_header + ' ' if progress_header else '')
            s += 'Rows = {}, Count = {:5.2f}M / {:5.2f}M'.format(row_tuple,
                                                                 count / 1e6,
                                                                 read_count /
                                                                 1e6,
                                                                 n=row_strw)
            print(s, end='  \r')

        while True:
            r_count = self.wb.regs.reader_done.read()
            progress(r_count)
            if self.wb.regs.reader_ready.read():
                break
            else:
                time.sleep(10 / 1e3)

        progress(self.wb.regs.reader_done.read())  # also clears the value
        print()
Exemplo n.º 6
0
    def payload_executor_attack(self, read_count, row):
        # FIXME: read from dedicated status registers
        tras = 5
        trp = 3
        encoder = Encoder(bankbits=self.bankbits)
        payload = [
            encoder(OpCode.NOOP, timeslice=30),
        ]

        # fill payload so that we have >= desired read_count
        count_max = 2**Decoder.LOOP_COUNT - 1
        n_loops = ceil(read_count / (count_max + 1))
        for _ in range(n_loops):
            payload.extend([
                encoder(OpCode.ACT,  timeslice=tras, address=encoder.address(bank=self.bank, row=row)),
                encoder(OpCode.PRE,  timeslice=trp, address=encoder.address(col=1 << 10)),  # all
                encoder(OpCode.LOOP, count=count_max, jump=2),
            ])
        payload.append(encoder(OpCode.NOOP, timeslice=30))

        toggle_count = (count_max + 1) * n_loops
        print('  Payload size = {:5.2f}KB / {:5.2f}KB'.format(4*len(payload)/2**10, self.wb.mems.payload.size/2**10))
        print('  Payload row toggle count = {:5.2f}M'.format(toggle_count/1e6))
        assert len(payload) < self.wb.mems.payload.size//4
        payload += [0] * (self.wb.mems.payload.size//4 - len(payload))  # fill with NOOPs

        print('\nTransferring the payload ...')
        memwrite(self.wb, payload, base=self.wb.mems.payload.base)

        def ready():
            status = self.wb.regs.payload_executor_status.read()
            return (status & 1) != 0

        print('\nExecuting ...')
        assert ready()
        self.wb.regs.payload_executor_start.write(1)
        while not ready():
            time.sleep(0.001)
Exemplo n.º 7
0
    def payload_executor_attack(self, read_count, row_tuple):
        tras = self.settings.timing.tRAS
        trp = self.settings.timing.tRP
        trefi = self.settings.timing.tREFI
        trfc = self.settings.timing.tRFC
        print(' tras: {} trp: {} trefi: {} trfc: {}'.format(
            tras, trp, trefi, trfc))
        accum = 0
        encoder = Encoder(bankbits=self.settings.geom.bankbits)
        payload = [
            encoder(OpCode.NOOP, timeslice=30),
        ]

        # fill payload so that we have >= desired read_count
        count_max = 2**Decoder.LOOP_COUNT - 1
        n_loops = ceil(read_count / (count_max + 1))

        assert len(row_tuple) * 2 < 2**Decoder.LOOP_JUMP

        refreshes = 0
        for outer_idx in range(n_loops):
            local_refreshes = 0
            payload.append(encoder(OpCode.REF, timeslice=trfc))
            accum = trfc
            for row in row_tuple:
                if accum + tras + trp > trefi and not self.no_refresh:
                    payload.append(encoder(OpCode.REF, timeslice=trfc))
                    # Invariant: time between the beginning of two refreshes
                    # is is less than tREFI.
                    accum = trfc
                    local_refreshes += 1
                accum += tras + trp
                payload.extend([
                    encoder(OpCode.ACT,
                            timeslice=tras,
                            address=encoder.address(bank=self.bank, row=row)),
                    encoder(OpCode.PRE,
                            timeslice=trp,
                            address=encoder.address(col=1 << 10)),  # all
                ])
            if outer_idx == 0:
                loop_count = ceil(read_count) % (count_max + 1)
            else:
                loop_count = count_max
            refreshes += local_refreshes * loop_count
            payload.append(
                encoder(OpCode.LOOP, count=loop_count,
                        jump=2 * len(row_tuple)))

        # TODO: improve synchronization when connecting/disconnecting memory controller
        payload.append(encoder(OpCode.NOOP, timeslice=30))

        toggle_count = (count_max + 1) * n_loops
        print('  Payload size = {:5.2f}KB / {:5.2f}KB'.format(
            4 * len(payload) / 2**10, self.wb.mems.payload.size / 2**10))
        print('  Payload per-row toggle count = {:5.2f}M  x{} rows'.format(
            toggle_count / 1e6, len(row_tuple)))
        print('  Payload refreshes = {}'.format(refreshes))
        assert len(payload) < self.wb.mems.payload.size // 4
        payload += [0] * (self.wb.mems.payload.size // 4 - len(payload)
                          )  # fill with NOOPs

        print('\nTransferring the payload ...')
        memwrite(self.wb, payload, base=self.wb.mems.payload.base)

        def ready():
            status = self.wb.regs.payload_executor_status.read()
            return (status & 1) != 0

        print('\nExecuting ...')
        assert ready()
        start = time.time()
        self.wb.regs.payload_executor_start.write(1)
        while not ready():
            time.sleep(0.001)
        print('Time taken: {}\n'.format(time.time() - start))