Exemplo n.º 1
0
def run_io_interrupt(_, target):
    test_harness.build_program(['io_interrupt.S'])
    result = test_harness.run_program(target)
    lines = result.split('\n')
    output = None

    for line in lines:
        start = line.find('!')
        if start != -1:
            output = line[start + 1:]

    if output is None:
        raise test_harness.TestException(
            'Could not find output string:\n' + result)

    # Make sure enough interrupts were triggered
    if output.count('*') < 2:
        raise test_harness.TestException(
            'Not enough interrupts triggered:\n' + result)

    # Make sure we see at least some of the base string printed after an
    # interrupt
    if output.find('*') >= len(output) - 1:
        raise test_harness.TestException(
            'No instances of interrupt return:\n' + result)

    # Remove all asterisks (interrupts) and make sure string is intact
    stripped = output.replace('*', '')
    if stripped != '0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`' \
            'abcdefghijklmnopqrstuvwxyz' * 10:
        raise test_harness.TestException(
            'Base string does not match:\n' + stripped)
Exemplo n.º 2
0
def shared_memory(_, target):
    """See coprocessor.c for an explanation of this test"""

    test_harness.build_program(['coprocessor.c'])

    # Start the emulator
    memory_file = tempfile.NamedTemporaryFile()
    args = [test_harness.BIN_DIR + 'emulator', '-s',
            memory_file.name, test_harness.HEX_FILE]
    process = subprocess.Popen(args, stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT)

    try:
        # Hack: Need to wait for the emulator to create the shared memory
        # file and initialize it. There's currently no way for the emulator
        # to signal that this has completed, so just sleep a bit and hope
        # it's done.
        time.sleep(1.0)
        memory = mmap.mmap(memory_file.fileno(), 0)
        testvalues = [random.randint(0, 0xffffffff) for __ in range(10)]
        for value in testvalues:
            computed = sharedmem_transact(memory, value)
            if computed != (value ^ 0xffffffff):
                raise test_harness.TestException('Incorrect value from coprocessor expected ' +
                                                 hex(value ^ 0xffffffff) +
                                                 ' got ' + hex(computed))
    finally:
        process.kill()
Exemplo n.º 3
0
def send_host_interrupt(_, target):
    try:
        os.remove(SEND_PIPE_NAME)
    except OSError:
        pass    # Ignore if pipe doesn't exist

    test_harness.build_program(['send_host_interrupt.S'])

    os.mknod(SEND_PIPE_NAME, stat.S_IFIFO | 0o666)

    args = [test_harness.BIN_DIR + 'emulator',
            '-o', SEND_PIPE_NAME, test_harness.HEX_FILE]
    emulator_process = subprocess.Popen(args, stdout=subprocess.PIPE,
                                        stderr=subprocess.STDOUT)

    try:
        interrupt_pipe = os.open(SEND_PIPE_NAME, os.O_RDONLY | os.O_NONBLOCK)
        test_harness.TimedProcessRunner().communicate(emulator_process, 60)

        # Interrupts should be in pipe now
        interrupts = os.read(interrupt_pipe, 5)
        if interrupts != b'\x05\x06\x07\x08\x09':
            raise test_harness.TestException(
                'Did not receive proper host interrupts')
    finally:
        os.close(interrupt_pipe)
        os.unlink(SEND_PIPE_NAME)
Exemplo n.º 4
0
def random_access_mmu_stress(_, target):
    test_harness.build_program(['random_access.S'])
    test_harness.run_program(
        target=target,
        dump_file='obj/vmem.bin',
        dump_base=DUMP_BASE,
        dump_length=MEMORY_SIZE * NUM_THREADS,
        timeout=240,
        flush_l2=True)

    # Check that threads have written proper values
    with open('obj/vmem.bin', 'rb') as memfile:
        for page_num in range(int(MEMORY_SIZE / PAGE_SIZE)):
            for thread_id in range(NUM_THREADS):
                for page_offset in range(0, PAGE_SIZE, 4):
                    val = memfile.read(4)
                    if len(val) < 4:
                        raise test_harness.TestException(
                            'output file is truncated')

                    num_val, = struct.unpack('<L', val)
                    va = page_num * PAGE_SIZE + \
                        page_offset + int(DUMP_BASE / 4)
                    expected = (thread_id << 24) | va
                    if num_val != expected:
                        raise test_harness.TestException(
                            'FAIL: mismatch @{:x} : got {:x} expected {:x}'.format((page_num * 4 + thread_id) * PAGE_SIZE,
                                                                                   num_val, expected))
Exemplo n.º 5
0
def sdmmc_write(_, target):
    with open(SOURCE_BLOCK_DEV, 'wb') as fsimage:
        fsimage.write(b'\xcc' * 1536)

    test_harness.build_program(['sdmmc_write.c'])
    result = test_harness.run_program(
        target=target,
        block_device=SOURCE_BLOCK_DEV)
    if 'FAIL' in result:
        raise test_harness.TestException('Test failed ' + result)

    with open(SOURCE_BLOCK_DEV, 'rb') as fsimage:
        end_contents = fsimage.read()

    # Check contents. First block is not modified
    for index in range(512):
        if end_contents[index] != 0xcc:
            raise test_harness.TestException('mismatch at {} expected 0xcc got 0x{:02x}'
                .format(index, end_contents[index]))

    # Second block has a pattern in it
    for index in range(512):
        expected = (index ^ (index >> 3)) & 0xff
        if end_contents[index + 512] != expected:
            raise test_harness.TestException('mismatch at {} expected 0x{:02x} got 0x{:02x}'
                .format(index + 512, expected, end_contents[index + 512]))

    # Third block is not modified
    for index in range(512):
        if end_contents[index + 1024] != 0xcc:
            raise test_harness.TestException('mismatch at {} expected 0xcc got 0x{:02x}'
                .format(index + 1024, end_contents[index + 1024]))
Exemplo n.º 6
0
def run_compiler_test(source_file, target):
    if target == 'host':
        subprocess.check_call(['cc', source_file, '-o', 'obj/a.out'],
                              stderr=subprocess.STDOUT)
        result = subprocess.check_output('obj/a.out')
        test_harness.check_result(source_file, result.decode())
    else:
        test_harness.build_program([source_file])
        result = test_harness.run_program(target)
        test_harness.check_result(source_file, result)
Exemplo n.º 7
0
def kernel_globalinit(name):
    underscore = name.rfind('_')
    if underscore == -1:
        raise test_harness.TestException(
            'Internal error: unknown environment')

    environment = name[underscore + 1:]
    test_harness.build_program(['constructor.cpp'], image_type='user')
    result = test_harness.run_kernel(environment=environment, timeout=120)
    test_harness.check_result('constructor.cpp', result)
Exemplo n.º 8
0
def kernel_ucf(name):
    underscore = name.rfind('_')
    if underscore == -1:
        raise test_harness.TestException(
            'Internal error: unknown environment')

    environment = name[underscore + 1:]
    test_harness.build_program(['user_copy_fault.c'], image_type='user')
    result = test_harness.run_kernel(environment=environment, timeout=120)
    test_harness.check_result('user_copy_fault.c', result)
Exemplo n.º 9
0
def sdmmc_read(name, target):
    # Create random file
    with open(SOURCE_BLOCK_DEV, 'wb') as randfile:
        randfile.write(os.urandom(FILE_SIZE))

    test_harness.build_program(['sdmmc_read.c'])
    test_harness.run_program(
        target=target,
        block_device=SOURCE_BLOCK_DEV,
        dump_file=MEMDUMP,
        dump_base=0x200000,
        dump_length=FILE_SIZE,
        flush_l2=True)

    test_harness.assert_files_equal(SOURCE_BLOCK_DEV, MEMDUMP, 'file mismatch')
Exemplo n.º 10
0
def sdmmc_read(name):
    # Create random file
    with open(SOURCE_BLOCK_DEV, 'wb') as randfile:
        randfile.write(os.urandom(FILE_SIZE))

    test_harness.build_program(['sdmmc_read.c'])
    test_harness.run_program(
        environment='emulator' if name.endswith('_emulator') else 'verilator',
        block_device=SOURCE_BLOCK_DEV,
        dump_file=MEMDUMP,
        dump_base=0x200000,
        dump_length=FILE_SIZE,
        flush_l2=True)

    test_harness.assert_files_equal(SOURCE_BLOCK_DEV, MEMDUMP, 'file mismatch')
Exemplo n.º 11
0
def filesystem(_):
    '''
    Filesystem tests. This creates a filesystem image with the test file fstest.txt
    in it, the compiles the program fs.c to perform operations on it. The program
    will print 'PASS' if it is successful.
    '''

    test_harness.build_program(['fs.c'])
    subprocess.check_output(
        [test_harness.PROJECT_TOP + '/bin/mkfs', 'obj/fsimage.bin',
         'fstest.txt'], stderr=subprocess.STDOUT)
    result = test_harness.run_program(environment='emulator',
                                      block_device='obj/fsimage.bin')
    if 'PASS' not in result:
        raise test_harness.TestException(
            'test program did not indicate pass\n' + result)
Exemplo n.º 12
0
def lldb(_):
    """This mainly validates that LLDB is reading symbols correctly."""

    hexfile = test_harness.build_program(
        ['test_program.c'], opt_level='-O0', cflags=['-g'])
    with EmulatorProcess(hexfile) as conn:
        conn.send_command('file "obj/test.elf"')
        conn.send_command('gdb-remote 8000\n')
        response = conn.send_command(
            'breakpoint set --file test_program.c --line 27')
        if 'Breakpoint 1: where = test.elf`func2 + 96 at test_program.c:27' not in response:
            raise test_harness.TestException(
                'breakpoint: did not find expected value ' + response)

        conn.send_command('c')
        conn.wait_stop()

        expected_stack = [
            ('func2', 'test_program.c', 27),
            ('func1', 'test_program.c', 35),
            ('main', 'test_program.c', 41),
            ('do_main', '', 0)
        ]

        response = conn.send_command('bt')
        crawl = parse_stack_crawl(response)
        if crawl != expected_stack:
            raise test_harness.TestException(
                'stack crawl mismatch ' + str(crawl))

        response = conn.send_command('print value')
        if '= 67' not in response:
            raise test_harness.TestException(
                'print value: Did not find expected value ' + response)

        response = conn.send_command('print result')
        if '= 128' not in response:
            raise test_harness.TestException(
                'print result: Did not find expected value ' + response)

        # Up to previous frame
        conn.send_command('frame select --relative=1')

        response = conn.send_command('print a')
        if '= 12' not in response:
            raise test_harness.TestException(
                'print a: Did not find expected value ' + response)

        response = conn.send_command('print b')
        if '= 67' not in response:
            raise test_harness.TestException(
                'print b: Did not find expected value ' + response)

        conn.send_command('step')
        conn.wait_stop()

        response = conn.send_command('print result')
        if '= 64' not in response:
            raise test_harness.TestException(
                'print b: Did not find expected value ' + response)
Exemplo n.º 13
0
def gdb_register_info(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Scalar registers
        for idx in range(28):
            regid = str(idx + 1)
            conn.expect('qRegisterInfo' + hex(idx + 1)[2:], 'name:s' + regid +
                        ';bitsize:32;encoding:uint;format:hex;'
                        'set:General Purpose Scalar Registers;gcc:' + regid +
                        ';dwarf:' + regid + ';')

        # These registers (sp, fp, ra) are special and have additional
        # information.
        names = ['fp', 'sp', 'ra']
        for idx, name in zip(range(28, 32), names):
            regid = str(idx + 1)
            conn.expect('qRegisterInfo' + hex(idx + 1)[2:], 'name:s' + regid +
                        ';bitsize:32;encoding:uint;format:hex;'
                        'set:General Purpose Scalar Registers;gcc:' + regid +
                        ';dwarf:' + regid + ';generic:' + name + ';')

        # Vector registers
        for idx in range(32, 63):
            regid = str(idx + 1)
            conn.expect('qRegisterInfo' + hex(idx + 1)[2:], 'name:v' + str(idx - 31) +
                        ';bitsize:512;encoding:uint;format:vector-uint32;'
                        'set:General Purpose Vector Registers;gcc:' + regid +
                        ';dwarf:' + regid + ';')

        conn.expect('qRegisterInfo65', '')
Exemplo n.º 14
0
def gdb_breakpoint(_, target):
    """
    Validate stopping at a breakpoint and continuing after stopping.
    This sets two breakpoints
    """

    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set breakpoint
        conn.expect('Z0,0000000c', 'OK')

        # Set second breakpoint at next instruction
        conn.expect('Z0,00000010', 'OK')

        # Continue
        conn.expect('C', 'S05')

        # Read last signal
        conn.expect('?', 'S05')

        # Read PC register. Should be 0x000000c, but endian swapped
        conn.expect('g40', '0c000000')

        # Read s0, which should be 3
        conn.expect('g00', '03000000')

        # Continue again.
        conn.expect('C', 'S05')

        # Ensure the instruction it stopped at is
        # executed and it breaks on the next instruction
        conn.expect('g40', '10000000')

        # Read s0, which should be 4
        conn.expect('g00', '04000000')
Exemplo n.º 15
0
def run_cosimulation_test(source_file):
    hexfile = test_harness.build_program([source_file])
    p1 = subprocess.Popen(
        verilator_args + ['+bin=' + hexfile], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(
        emulator_args + [hexfile], stdin=p1.stdout, stdout=subprocess.PIPE)
    output = ''
    while True:
        got = p2.stdout.read(0x1000)
        if not got:
            break

        if verbose:
            print(str(got))
        else:
            output += str(got)

    p2.wait()
    time.sleep(1)  # Give verilator a chance to clean up
    p1.kill() 	# Make sure verilator has exited
    if p2.returncode:
        raise test_harness.TestException(
            'FAIL: cosimulation mismatch\n' + output)

    test_harness.assert_files_equal(VERILATOR_MEM_DUMP, EMULATOR_MEM_DUMP,
                                    'final memory contents to not match')
Exemplo n.º 16
0
def gdb_read_write_register(_, target):
    hexfile = test_harness.build_program(['register_values.S'])
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Run code to load registers
        conn.expect('C', 'S05')

        # Check values set by program (remote GDB returns in swapped byte
        # order...)
        conn.expect('g1', '7d7f3e85')
        conn.expect('g20', 'f13403ef9d08309993f7819954ae4b3f7aeaa28f538fecbd95'
                    '36f59c6d7251269525ee70d26e8d34f48912639c86ae5dba426c83aa8455e1e2dbba4b41a4f321')

        tests = [
            (0, 'd3839b18'),
            (1, '7b53cc78'),
            (30, '0904c47d'),
            (32, 'aef331bc7dbd6f1d042be4d6f1e1649855d864387eb8f0fd49c205c37790'
                'd1874078516c1a05c74f67678456679ba7e05bb5aed7303c5aeeeba6e619accf702a'),
            (36, 'cb7e3668a97ef8ea55902658b62a682406f7206f75e5438ff95b4519fed1'
                'e73e16ce5a29b4385fa2560820f0c8f42227709387dbad3a8208b57c381e268ffe38'),
            (63, '9e2d89afb0633c2f64b2eb4fdbba4663401ee673753a66d6d899e4a4101a'
                'e4920b0b16f0e716e4f7d62d83b5784740c138ac6ab94fa14256ebb468e25f20e02f')
        ]

        for reg, value in tests:
            conn.expect('G' + hex(reg)[2:] + ',' + value, 'OK')

        for reg, value in tests:
            conn.expect('g' + hex(reg)[2:], value)

        # Read invalid register index
        conn.expect('g41', '')

        # Write invalid register index
        conn.expect('G41,12345678', '')
Exemplo n.º 17
0
def filesystem(_, target):
    '''
    Filesystem tests. This creates a filesystem image with the test file fstest.txt
    in it, the compiles the program fs.c to perform operations on it. The program
    will print 'PASS' if it is successful.
    '''

    test_harness.build_program(['fs.c'])
    subprocess.check_output(
        [test_harness.BIN_DIR + 'mkfs', test_harness.WORK_DIR + '/fsimage.bin',
         'fstest.txt'], stderr=subprocess.STDOUT)
    result = test_harness.run_program(target=target,
                                      block_device=test_harness.WORK_DIR + '/fsimage.bin')
    if 'PASS' not in result or 'FAIL' in result:
        raise test_harness.TestException(
            'test program did not indicate pass\n' + result)
Exemplo n.º 18
0
def run_cosimulation_test(source_file, *unused):
    random_seed = random.randint(0, 0xffffffff)
    if test_harness.DEBUG:
        print('random seed is {}'.format(random_seed))

    verilator_args = [
        test_harness.VSIM_PATH,
        '+trace',
        '+memdumpfile=' + VERILATOR_MEM_DUMP,
        '+memdumpbase=800000',
        '+memdumplen=400000',
        '+autoflushl2',
        '+verilator+rand+reset+2',
        '+verilator+seed+{}'.format(random_seed)
    ]

    # XXX this should probably be a command line option in test_harness.py
    if 'RANDSEED' in os.environ:
        verilator_args += ['+randseed=' + os.environ['RANDSEED']]

    emulator_args = [
        test_harness.EMULATOR_PATH,
        '-m',
        'cosim',
        '-d',
        EMULATOR_MEM_DUMP + ',0x800000,0x400000'
    ]

    if test_harness.DEBUG:
        emulator_args += ['-v']

    hexfile = test_harness.build_program([source_file])
    try:
        p1 = subprocess.Popen(
            verilator_args + ['+bin=' + hexfile], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(
            emulator_args + [hexfile], stdin=p1.stdout, stdout=subprocess.PIPE)
        output = ''
        while True:
            got = p2.stdout.read(0x1000)
            if not got:
                break

            if test_harness.DEBUG:
                print(got.decode())
            else:
                output += got.decode()

        p2.wait()
        time.sleep(1)  # Give verilator a chance to clean up
    finally:
        p1.kill()
        p2.kill()

    if p2.returncode:
        raise test_harness.TestException(
            'FAIL: cosimulation mismatch\n' + output)

    test_harness.assert_files_equal(VERILATOR_MEM_DUMP, EMULATOR_MEM_DUMP,
                                    'final memory contents to not match')
Exemplo n.º 19
0
def gdb_read_write_memory(_):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Read program code at address 0. This should match values
        # in count.hex
        conn.expect('m0,10', '0004800700088007000c800700108007')

        # (address, data)
        tests = [
            (0x1000, '523c66b3'),
            (0x1234, '22'),
            (0x2242, '45f280397a5a3255fa19238693ff13c729'),
            (0x100000, '55483c091aac1e8c6db4bed1'),
            (0x200000, '16e1d56029e912a04121ce41a635155f3442355533703fafcb57f8295dd6330f82f9ffc40edb589fac1523665dc2f6e80c1e2de9718d253fcbce1c8a52c9dc21'),
        ]

        # Write memory
        for addr, data in tests:
            conn.expect('M' + hex(addr)[2:] + ',' +
                        hex(int(len(data) / 2))[2:] + ':' + data, 'OK')

        # Read and verify
        for addr, data in tests:
            conn.expect('m' + hex(addr)[2:] + ',' +
                        hex(int(len(data) / 2))[2:], data)

        # Try to write a bad address (out of range)
        # Doesn't return an error, test just ensures it
        # doesn't crash
        conn.expect('M10000000,4,12345678', 'OK')

        # Try to read a bad address (out of range)
        # As above, doesn't return error (returns 0xff...),
        # but ensure it doesn't crash.
        conn.expect('m10000000,4', 'ffffffff')
Exemplo n.º 20
0
def run_csmith_test(_, target):
    # Find version of csmith
    result = subprocess.check_output(['csmith', '-v']).decode()
    got = VERSION_RE.search(result)
    if not got:
        raise test_harness.TestException(
            'Could not determine csmith version ' + result)

    version_str = got.group('version')
    csmith_include = '-I/usr/local/include/csmith-' + version_str

    for x in range(100):
        source_file = 'test%04d.c' % x
        print('running ' + source_file)

        # Disable packed structs because we don't support unaligned accesses.
        # Disable longlong to avoid incompatibilities between 32-bit Nyuzi
        # and 64-bit hosts.
        subprocess.check_call(['csmith', '-o', source_file, '--no-longlong',
                               '--no-packed-struct'])

        # Compile and run on host
        subprocess.check_call(
            ['cc', '-w', source_file, '-o', test_harness.WORK_DIR + '/a.out', csmith_include])
        result = subprocess.check_output(
            test_harness.WORK_DIR + '/a.out').decode()

        got = CHECKSUM_RE.search(result)
        if not got:
            raise test_harness.TestException('no checksum in host output')

        host_checksum = int(got.group('checksum'), 16)
        print('host checksum %08x' % host_checksum)

        # Compile and run under emulator
        test_harness.build_program([source_file], cflags=[csmith_include])
        result = test_harness.run_program(target)
        got = CHECKSUM_RE.search(result)
        if not got:
            raise test_harness.TestException('no checksum in host output')

        emulator_checksum = int(got.group('checksum'), 16)
        print('emulator checksum %08x' % emulator_checksum)
        if host_checksum != emulator_checksum:
            raise test_harness.TestException('checksum mismatch')

        print('PASS')
Exemplo n.º 21
0
def gdb_select_thread(_, target):
    hexfile = test_harness.build_program(['multithreaded.S'], image_type='raw')
    with EmulatorProcess(hexfile, num_cores=2), DebugConnection() as conn:
        # Read thread ID
        conn.expect('qC', 'QC01')

        # Each line is one thread
        tests = [
            (7, 0xc7733c56),
            (5, 0xf54adec3),
            (1, 0x5afaf01e),
            (2, 0x1964682e),
            (3, 0x16cc6be1),
            (8, 0xcbff923),
            (4, 0x4596de2),
            (6, 0xcd920ca6),
        ]

        # Step all threads through initialization code (5 instructions)
        for thid in range(len(tests)):
            # Switch to thread
            conn.expect('Hg' + str(thid + 1), 'OK')

            # Read thread ID
            conn.expect('qC', 'QC0' + str(thid + 1))

            for index in range(5):
                conn.expect('S', 'S05')

                # Read PC register
                conn.expect('g40', '{:08x}'.format(
                    test_harness.endian_swap((index + 1) * 4)))

        # Now all threads are at the same instruction:
        # 00000014 move s0, 1

        # Step each thread independently some number of steps and
        # write a value to register 1
        for index, (num_steps, regval) in enumerate(tests):
            conn.expect('Hg' + str(index + 1), 'OK')  # Switch to thread
            for _ in range(num_steps):
                conn.expect('S', 'S05')

            conn.expect('G01,{:08x}'.format(regval), 'OK')

        # Read back PC and register values
        for index, (num_steps, regval) in enumerate(tests):
            conn.expect('Hg' + str(index + 1), 'OK')   # Switch to thread
            conn.expect('g40', '{:08x}'.format(
                test_harness.endian_swap(0x14 + num_steps * 4)))
            conn.expect('g01', '{:08x}'.format(regval))

        # Try to switch to an invalid thread ID
        conn.expect('Hgfe', '')

        # Ensure still on thread 8
        conn.expect('qC', 'QC08')
Exemplo n.º 22
0
def gdb_big_command(_, target):
    """ Check for buffer overflows by sending a very large command"""
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Big, invalid command. this should return an error (empty response)
        conn.expect('x' * 0x10000, '')

        # Now send a valid request to ensure it is still alive.
        conn.expect('qC', 'QC01')
Exemplo n.º 23
0
def gdb_thread_info(_, target):
    # Run with one core, four threads
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        conn.expect('qfThreadInfo', 'm1,2,3,4')

    # Run with two cores, eight threads
    with EmulatorProcess(hexfile, num_cores=2), DebugConnection() as conn:
        conn.expect('qfThreadInfo', 'm1,2,3,4,5,6,7,8')
Exemplo n.º 24
0
def dflush(_):
    test_harness.build_program(['dflush.S'])
    test_harness.run_program(
        environment='verilator',
        dump_file='obj/vmem.bin',
        dump_base=BASE_ADDRESS,
        dump_length=0x40000)
    with open('obj/vmem.bin', 'rb') as memfile:
        for index in range(4096):
            val = memfile.read(4)
            if len(val) < 4:
                raise test_harness.TestException('output file is truncated')

            num_val, = struct.unpack('<L', val)
            expected = 0x1f0e6231 + (index // 16)
            if num_val != expected:
                raise test_harness.TestException('FAIL: mismatch at ' + hex(
                    BASE_ADDRESS + (index * 4)) + ' want ' + str(expected) + ' got ' + str(num_val))
Exemplo n.º 25
0
def jtag_inject(*unused):
    """
    Test instruction injection, with multiple threads
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Halt
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)

        # Load register values in thread 0
        # First value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x3b643e9a)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000b2)  # getcr s5, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        # Second value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xd1dc20a3)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000d2)  # getcr s6, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        # Load register values in thread 1
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        # First value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xa6532328)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000b2)  # getcr s5, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        # Second value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xf01839a0)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000d2)  # getcr s6, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        # Perform operation on thread 0
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)
        fixture.jtag_transfer(INST_INJECT_INST, 32,
                              0xc03300e5)  # xor s7, s5, s6
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0000f2)  # setcr s7, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0xeab81e39)

        # Perform operation on thread 1
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        fixture.jtag_transfer(INST_INJECT_INST, 32,
                              0xc03300e5)  # xor s7, s5, s6
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0000f2)  # setcr s7, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)

        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0x564b1a88)
Exemplo n.º 26
0
def atomic(_, target):
    test_harness.build_program(['atomic.S'])
    test_harness.run_program(
        target=target,
        dump_file=test_harness.WORK_DIR + '/vmem.bin',
        dump_base=0x100000,
        dump_length=0x800,
        flush_l2=True)

    with open(test_harness.WORK_DIR + '/vmem.bin', 'rb') as memfile:
        for _ in range(512):
            val = memfile.read(4)
            if len(val) < 4:
                raise test_harness.TestException('output file is truncated')

            num_val, = struct.unpack('<L', val)
            if num_val != 10:
                raise test_harness.TestException(
                    'FAIL: mismatch: ' + str(num_val))
Exemplo n.º 27
0
def jtag_bypass(*unused):
    """
    Validate BYPASS instruction, which is a single bit data register
    We should get what we send, shifted by one bit.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        value = 0x267521cf
        fixture.jtag_transfer(INST_BYPASS, 32, value)
        fixture.expect_data(value << 1)
Exemplo n.º 28
0
def dinvalidate(_):
    test_harness.build_program(['dinvalidate.S'])
    result = test_harness.run_program(
        environment='verilator',
        dump_file='obj/vmem.bin',
        dump_base=0x2000,
        dump_length=4,
        flush_l2=True,
        trace=True)

    # 1. Check that the proper value was read into s2
    if '02 deadbeef' not in result:
        raise test_harness.TestException(
            'incorrect value was written back ' + result)

    # 2. Read the memory dump to ensure the proper value is flushed from the
    # L2 cache
    with open('obj/vmem.bin', 'rb') as memfile:
        num_val, = struct.unpack('<L', memfile.read(4))
        if num_val != 0xdeadbeef:
            raise test_harness.TestException(
                'memory contents were incorrect: ' + hex(num_val))
Exemplo n.º 29
0
def dinvalidate(_, target):
    test_harness.build_program(['dinvalidate.S'])
    result = test_harness.run_program(
        target=target,
        dump_file='obj/vmem.bin',
        dump_base=0x2000,
        dump_length=4,
        flush_l2=True,
        trace=True)

    # 1. Check that the proper value was read into s2
    if '02 deadbeef' not in result:
        raise test_harness.TestException(
            'incorrect value was written back ' + result)

    # 2. Read the memory dump to ensure the proper value is flushed from the
    # L2 cache
    with open('obj/vmem.bin', 'rb') as memfile:
        num_val, = struct.unpack('<L', memfile.read(4))
        if num_val != 0xdeadbeef:
            raise test_harness.TestException(
                'memory contents were incorrect: ' + hex(num_val))
Exemplo n.º 30
0
def jtag_instruction_shift(*unused):
    """Ensure instruction bits shifted into TDI come out TDO.

    This is necessary to properly chain JTAG devices together.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        fixture.test_instruction_shift(0xf)
        fixture.test_instruction_shift(0xa)
        fixture.test_instruction_shift(0x5)
        fixture.test_instruction_shift(0x3)
        fixture.test_instruction_shift(0xc)
        fixture.test_instruction_shift(0)
Exemplo n.º 31
0
def gdb_vcont(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set breakpoint
        conn.expect('Z0,00000010', 'OK')

        # Step
        conn.expect('vCont;s:0001', 'S05')
        conn.expect('g40', '04000000')

        # Continue
        conn.expect('vCont;c', 'S05')
        conn.expect('g40', '10000000')
Exemplo n.º 32
0
def recv_host_interrupt(*unused):
    try:
        os.remove(RECV_PIPE_NAME)
    except OSError:
        pass  # Ignore if pipe doesn't exist

    test_harness.build_program(['recv_host_interrupt.S'])

    os.mknod(RECV_PIPE_NAME, stat.S_IFIFO | 0o666)

    args = [
        test_harness.EMULATOR_PATH, '-i', RECV_PIPE_NAME, test_harness.HEX_FILE
    ]
    emulator_process = subprocess.Popen(args,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.STDOUT)

    try:
        interrupt_pipe = os.open(RECV_PIPE_NAME, os.O_WRONLY)

        # Send periodic interrupts to process
        try:
            for intnum in range(5):
                os.write(interrupt_pipe, str.encode(chr(intnum)))
                time.sleep(0.2)
        except OSError:
            # Broken pipe will occur if the emulator exits early.
            # We'll flag an error after communicate if we don't see a PASS.
            pass

        # Wait for completion
        result, _ = test_harness.TimedProcessRunner().communicate(
            emulator_process, 60)
        strresult = str(result)
        if 'PASS' not in strresult or 'FAIL' in strresult:
            raise test_harness.TestException('Test failed ' + strresult)
    finally:
        os.close(interrupt_pipe)
        os.unlink(RECV_PIPE_NAME)
Exemplo n.º 33
0
def gdb_vcont(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set breakpoint
        conn.expect('Z0,00000010', 'OK')

        # Step
        conn.expect('vCont;s:0001', 'S05')
        conn.expect('g40', '04000000')

        # Continue
        conn.expect('vCont;c', 'S05')
        conn.expect('g40', '10000000')
Exemplo n.º 34
0
def jtag_instruction_shift(*unused):
    """
    Ensure instruction bits shifted into TDI come out TDO. This is necessary
    to properly chain JTAG devices together.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        fixture.test_instruction_shift(0xf)
        fixture.test_instruction_shift(0xa)
        fixture.test_instruction_shift(0x5)
        fixture.test_instruction_shift(0x3)
        fixture.test_instruction_shift(0xc)
        fixture.test_instruction_shift(0)
Exemplo n.º 35
0
def run_io_interrupt(name):
    underscore = name.rfind('_')
    if underscore == -1:
        raise test_harness.TestException(
            'Internal error: run_io_interrupt did not have type')

    environment = name[underscore + 1:]
    test_harness.build_program(['io_interrupt.S'])
    result = test_harness.run_program(environment=environment)
    lines = result.split('\n')
    output = None

    for line in lines:
        start = line.find('!')
        if start != -1:
            output = line[start + 1:]

    if output is None:
        raise test_harness.TestException('Could not find output string:\n' +
                                         result)

    # Make sure enough interrupts were triggered
    if output.count('*') < 2:
        raise test_harness.TestException('Not enough interrupts triggered:\n' +
                                         result)

    # Make sure we see at least some of the base string printed after an
    # interrupt
    if output.find('*') >= len(output) - 1:
        raise test_harness.TestException(
            'No instances of interrupt return:\n' + result)

    # Remove all asterisks (interrupts) and make sure string is intact
    stripped = output.replace('*', '')
    if stripped != '0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`' \
        'abcdefghijklmnopqrstuvwxyz' * 10:
        raise test_harness.TestException('Base string does not match:\n' +
                                         stripped)
Exemplo n.º 36
0
def jtag_data_transfer(*unused):
    """Validate bi-directional transfer.

    The TRANSFER_DATA instruction returns the old value of the control
    register while shifting a new one in, so we should see the previous
    value come out each time we write a new one.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x4be49e7c)
        fixture.jtag_transfer(INST_SAME, 32, 0xb282dc16)
        fixture.expect_data(0x4be49e7c)
        fixture.jtag_transfer(INST_SAME, 32, 0x7ee4838)
        fixture.expect_data(0xb282dc16)
Exemplo n.º 37
0
def jtag_idcode(*unused):
    """
    Validate response to IDCODE request
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Ensure the default instruction after reset is IDCODE
        fixture.jtag_transfer(INST_SAME, 32, 0xffffffff)
        fixture.expect_data(EXPECTED_IDCODE)

        # Explicitly shift the IDCODE instruction to make sure it is
        # correct.
        fixture.jtag_transfer(INST_IDCODE, 32, 0xffffffff)
        fixture.expect_data(EXPECTED_IDCODE)
Exemplo n.º 38
0
def gdb_queries(_, target):
    """Miscellaneous query commands not covered in other tests"""

    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        conn.expect('qLaunchSuccess', 'OK')
        conn.expect('qHostInfo', 'triple:nyuzi;endian:little;ptrsize:4')
        conn.expect('qProcessInfo', 'pid:1')
        conn.expect('qsThreadInfo', 'l')  # No active threads
        conn.expect('qThreadStopInfo', 'S00')
        conn.expect('qC', 'QC01')

        # Should be invalid
        conn.expect('qZ', '')
Exemplo n.º 39
0
def run_cosimulation_test(source_file, *unused):
    verilator_args = [
        test_harness.VSIM_PATH,
        '+trace',
        '+memdumpfile=' + VERILATOR_MEM_DUMP,
        '+memdumpbase=800000',
        '+memdumplen=400000',
        '+autoflushl2'
    ]

    # XXX this should probably be a command line option in test_harness.py
    if 'RANDSEED' in os.environ:
        verilator_args += ['+randseed=' + os.environ['RANDSEED']]

    emulator_args = [
        test_harness.EMULATOR_PATH,
        '-m',
        'cosim',
        '-d',
        EMULATOR_MEM_DUMP + ',0x800000,0x400000'
    ]

    if test_harness.DEBUG:
        emulator_args += ['-v']

    hexfile = test_harness.build_program([source_file])
    p1 = subprocess.Popen(
        verilator_args + ['+bin=' + hexfile], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(
        emulator_args + [hexfile], stdin=p1.stdout, stdout=subprocess.PIPE)
    output = ''
    while True:
        got = p2.stdout.read(0x1000)
        if not got:
            break

        if test_harness.DEBUG:
            print(got.decode())
        else:
            output += got.decode()

    p2.wait()
    time.sleep(1)  # Give verilator a chance to clean up
    test_harness.kill_gently(p2) # Make sure verilator has exited
    if p2.returncode:
        raise test_harness.TestException(
            'FAIL: cosimulation mismatch\n' + output)

    test_harness.assert_files_equal(VERILATOR_MEM_DUMP, EMULATOR_MEM_DUMP,
                                    'final memory contents to not match')
Exemplo n.º 40
0
def jtag_reset(*unused):
    """Test transition to reset state."""
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Load a different instruction
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x3b643e9a)

        # Perform a reset (setting zero lengths)
        fixture.jtag_transfer(INST_SAME, 0, 0)

        # Perform data-only transfer. Ensure we get the idcode back.
        # If we hadn't performed a reset, we would get data value
        # that was shifted above.
        fixture.jtag_transfer(INST_SAME, 32, 0xffffffff)
        fixture.expect_data(EXPECTED_IDCODE)
Exemplo n.º 41
0
def sdmmc_read(_, target):
    # Create random file
    with open(SOURCE_BLOCK_DEV, 'wb') as fsimage:
        fsimage.write(os.urandom(FILE_SIZE))

    hex_file = test_harness.build_program(['sdmmc_read.c'])
    test_harness.run_program(hex_file,
                             target,
                             block_device=SOURCE_BLOCK_DEV,
                             dump_file=MEMDUMP,
                             dump_base=0x200000,
                             dump_length=FILE_SIZE,
                             flush_l2=True)

    test_harness.assert_files_equal(SOURCE_BLOCK_DEV, MEMDUMP, 'file mismatch')
Exemplo n.º 42
0
def gdb_breakpoint_errors(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set invalid breakpoint (memory out of range)
        conn.expect('Z0,20000000', '')

        # Set invalid breakpoint (unaligned)
        conn.expect('Z0,00000003', '')

        # Set a valid breakpoint, then try to set the same address again
        conn.expect('Z0,00000008', 'OK')
        conn.expect('Z0,00000008', '')

        # Remove invalid breakpoint (doesn't exist)
        conn.expect('z0,00000004', '')
Exemplo n.º 43
0
def run_csmith_test(_, target):
    # Find version of csmith
    result = subprocess.check_output(['csmith', '-v']).decode()
    got = VERSION_RE.search(result)
    if not got:
        raise test_harness.TestException(
            'Could not determine csmith version ' + result)

    version_str = got.group('version')
    csmith_include = '-I/usr/local/include/csmith-' + version_str

    for x in range(100):
        source_file = os.path.join(test_harness.WORK_DIR, 'test%04d.c' % x)
        print('running ' + source_file)

        # Disable packed structs because we don't support unaligned accesses.
        # Disable longlong to avoid incompatibilities between 32-bit Nyuzi
        # and 64-bit hosts.
        subprocess.check_call([
            'csmith', '-o', source_file, '--no-longlong', '--no-packed-struct'
        ])

        # Compile and run on host
        subprocess.check_call(
            ['cc', '-w', source_file, '-o', HOST_EXE, csmith_include])
        result = subprocess.check_output(HOST_EXE).decode()

        got = CHECKSUM_RE.search(result)
        if not got:
            raise test_harness.TestException('no checksum in host output')

        host_checksum = int(got.group('checksum'), 16)
        print('host checksum %08x' % host_checksum)

        # Compile and run under emulator
        hex_file = test_harness.build_program([source_file],
                                              cflags=[csmith_include])
        result = test_harness.run_program(hex_file, target)
        got = CHECKSUM_RE.search(result)
        if not got:
            raise test_harness.TestException('no checksum in host output')

        emulator_checksum = int(got.group('checksum'), 16)
        print('emulator checksum %08x' % emulator_checksum)
        if host_checksum != emulator_checksum:
            raise test_harness.TestException('checksum mismatch')

        print('PASS')
Exemplo n.º 44
0
def jtag(_):
    hexfile = test_harness.build_program(['test_program.S'])

    with VerilatorProcess(hexfile), DebugConnection() as conn:
        conn.jtag_transfer(4, INST_CONTROL, 7, 0x1)
        conn.jtag_transfer(4, INST_WRITE_DATA, 32,
                           0x3b643e9a)  # First value to transfer
        conn.jtag_transfer(4, INST_INJECT_INST, 32, 0xac0000b2)  # getcr s5, 18
        conn.jtag_transfer(4, INST_WRITE_DATA, 32,
                           0xd1dc20a3)  # Second value to transfer
        conn.jtag_transfer(4, INST_INJECT_INST, 32, 0xac0000d2)  # getcr s6, 18
        conn.jtag_transfer(4, INST_INJECT_INST, 32,
                           0xc03300e5)  # xor s7, s5, s6
        conn.jtag_transfer(4, INST_INJECT_INST, 32, 0x8c0000f2)  # setcr s7, 18
        if conn.jtag_transfer(4, INST_READ_DATA, 32, 0) != 0xeab81e39:
            raise test_harness.TestException('read value mismatch')
Exemplo n.º 45
0
def jtag_read_write_pc(*unused):
    """Use the call instruction to read the program counter.

    The injection logic is supposed to simulate each instruction having the
    PC of the interrupted thread. Then ensure performing a branch will
    properly update the PC of the selected thread. This then resumes the
    thread to ensure it operates properly.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Switch to thread 1, branch to new address
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x10e4)  # `jump_target`
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac000012)  # getcr s0, 18
        fixture.jtag_transfer(INST_SAME, 32, 0xf0000000)  # b s0

        # Switch to thread 0, read PC to ensure it is read correctly
        # and that the branch didn't affect it.
        # (the return address will be the branch location + 4)
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xf8000000)  # call 0
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0003f2)  # setcr ra, 18
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0x10d8)

        # Switch back to thread 1, read back PC to ensure it is in the new
        # location
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xf8000000)  # call 0
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0003f2)  # setcr ra, 18
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0x10e8)

        # Resume the thread. It should now execute the instruction to
        # load a new value into s0
        fixture.jtag_transfer(INST_CONTROL, 7, 0x0)

        # Dummy transaction that ensures the processor has time to execute
        # the instructions
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)

        # Halt again and verify register value.
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0x8c000012)  # setcr s0, 18
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0x6bee68ca)
Exemplo n.º 46
0
def uart_echo_test(*unused):
    '''
    The emulator direct all UART traffic through the terminal that
    it is launched from. This validates transfers in both directions.
    '''
    executable = test_harness.build_program(['uart_echo_test.c'])

    args = [test_harness.EMULATOR_PATH, executable]

    in_str = 'THE QUICK brOwn FOX jumPED Over THE LAZY DOG\n'
    process = subprocess.Popen(args,
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE)
    out_str, _ = test_harness.TimedProcessRunner().communicate(
        process=process, timeout=10, input=in_str.encode('ascii'))
    out_str = out_str.decode()
    if 'the quick brown fox jumped over the lazy dog' not in out_str:
        raise test_harness.TestException(
            'Subprocess returned incorrect result \"' + out_str + '"')
Exemplo n.º 47
0
def dflush(_, target):
    hex_file = test_harness.build_program(['dflush.S'])
    test_harness.run_program(hex_file,
                             target,
                             dump_file=MEM_DUMP_FILE,
                             dump_base=BASE_ADDRESS,
                             dump_length=0x40000)
    with open(MEM_DUMP_FILE, 'rb') as memfile:
        for index in range(4096):
            val = memfile.read(4)
            if len(val) < 4:
                raise test_harness.TestException('output file is truncated')

            num_val, = struct.unpack('<L', val)
            expected = 0x1f0e6231 + (index // 16)
            if num_val != expected:
                raise test_harness.TestException(
                    'FAIL: mismatch at 0x{:x} want {} got {}'.format(
                        BASE_ADDRESS + (index * 4), expected, num_val))
Exemplo n.º 48
0
def jtag_inject_rollback(_, target):
    """
    Test reading status register. I put in an instruction that will miss the
    cache, so I know it will roll back.
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Halt
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)

        # Load register values in thread 0
        # First value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x10000)  # High address, not cached
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac000012)  # getcr s0, 18
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_READY)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xa8000000)  # load_32 s0, (s0)
        fixture.jtag_transfer(INST_STATUS, 2, 0)
        fixture.expect_data(STATUS_ROLLED_BACK)
Exemplo n.º 49
0
def filesystem(_, target):
    """Test the filesystem implementation in libos.

    This creates a filesystem image with the test file fstest.txt
    in it, the compiles the program fs.c to perform operations on it. The program
    will print 'PASS' if it is successful.
    """

    hex_file = test_harness.build_program(['fs.c'])
    subprocess.check_output([
        os.path.join(test_harness.TOOL_BIN_DIR, 'mkfs'), FS_IMAGE_PATH,
        'fstest.txt'
    ],
                            stderr=subprocess.STDOUT)
    result = test_harness.run_program(hex_file,
                                      target,
                                      block_device=FS_IMAGE_PATH)
    if 'PASS' not in result or 'FAIL' in result:
        raise test_harness.TestException(
            'test program did not indicate pass\n' + result)
Exemplo n.º 50
0
def atomic(_, target):
    hex_file = test_harness.build_program(['atomic.S'])
    test_harness.run_program(
        hex_file,
        target,
        dump_file=MEM_DUMP_FILE,
        dump_base=0x100000,
        dump_length=0x800,
        flush_l2=True)

    with open(MEM_DUMP_FILE, 'rb') as memfile:
        for _ in range(512):
            val = memfile.read(4)
            if len(val) < 4:
                raise test_harness.TestException('output file is truncated')

            num_val, = struct.unpack('<L', val)
            if num_val != 10:
                raise test_harness.TestException(
                    'FAIL: mismatch: ' + str(num_val))
Exemplo n.º 51
0
def gdb_remove_breakpoint(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set breakpoint
        conn.expect('Z0,0000000c', 'OK')

        # Set second breakpoint
        conn.expect('Z0,00000014', 'OK')

        # Clear first breakpoint
        conn.expect('z0,0000000c', 'OK')

        # Continue
        conn.expect('C', 'S05')

        # Read PC register. Should be at second breakpoint
        conn.expect('g40', '14000000')

        # Read s0, which should be 5
        conn.expect('g00', '05000000')
Exemplo n.º 52
0
def jtag_inject(_, target):
    """
    Test instruction injection, with multiple threads
    """
    hexfile = test_harness.build_program(['test_program.S'])
    with JTAGTestFixture(hexfile) as fixture:
        # Halt
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)

        # Load register values in thread 0
        # First value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0x3b643e9a)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000b2)  # getcr s5, 18
        # Second value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xd1dc20a3)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000d2)  # getcr s6, 18

        # Load register values in thread 1
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        # First value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xa6532328)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000b2)  # getcr s5, 18
        # Second value to transfer
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0xf01839a0)
        fixture.jtag_transfer(INST_INJECT_INST, 32, 0xac0000d2)  # getcr s6, 18

        # Perform operation on thread 0
        fixture.jtag_transfer(INST_CONTROL, 7, 0x1)
        fixture.jtag_transfer(INST_INJECT_INST, 32,
                              0xc03300e5)  # xor s7, s5, s6
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0000f2)  # setcr s7, 18
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0xeab81e39)

        # Perform operation on thread 1
        fixture.jtag_transfer(INST_CONTROL, 7, 0x3)
        fixture.jtag_transfer(INST_INJECT_INST, 32,
                              0xc03300e5)  # xor s7, s5, s6
        fixture.jtag_transfer(INST_SAME, 32, 0x8c0000f2)  # setcr s7, 18
        fixture.jtag_transfer(INST_TRANSFER_DATA, 32, 0)
        fixture.expect_data(0x564b1a88)
Exemplo n.º 53
0
def profile(*unused):
    hexfile = test_harness.build_program(['test_program.c'])

    # XXX hack: this is currently not returned from build_program, but I
    # know what the name is.
    elffile = hexfile.replace('.hex', '.elf')
    profile_file = os.path.join(test_harness.WORK_DIR, 'profile.out')

    test_harness.run_program(hexfile, 'verilator', profile_file=profile_file)

    symbol_file = os.path.join(test_harness.WORK_DIR, 'symbols.txt')
    objdump_args = [
        os.path.join(test_harness.COMPILER_BIN_DIR, 'llvm-objdump'),
        '-t', elffile
    ]
    symbols = subprocess.check_output(objdump_args)
    with open(symbol_file, 'w') as f:
        f.write(symbols.decode())

    profile_args = [
        os.path.join(test_harness.TOOL_BIN_DIR, 'profile.py'),
        symbol_file,
        profile_file
    ]
    profile_output = subprocess.check_output(' '.join(profile_args), shell=True)
    profile_lines = profile_output.decode().split('\n')
    profile_tuples = [line.split() for line in profile_lines if line]
    profile_map = {func: int(count) for count, _, func in profile_tuples}

    # These tests don't end up being exactly 2x the number of samples. Because
    # the system samples randomly, it can vary. I could have ran the test longer
    # to get more samples, but this is really just a smoke test and I didn't want
    # to bloat the test time unnecessarily.
    loop5k = profile_map['loop5000']
    loop10k = profile_map['loop10000']
    loop20k = profile_map['loop20000']
    test_harness.assert_greater(loop5k, 0)
    test_harness.assert_greater(loop10k, loop5k * 1.75)
    test_harness.assert_greater(loop20k, loop10k * 1.75)
Exemplo n.º 54
0
def gdb_single_step_breakpoint(_, target):
    """
    Ensure that if you single step through a breakpoint, it doesn't
    trigger and get stuck
    """
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Set breakpoint at second instruction (address 0x8)
        conn.expect('Z0,00000004', 'OK')

        # Single step over first instruction
        conn.expect('S', 'S05')

        # Single step. This one has a breakpoint, but we won't
        # stop at it.
        conn.expect('S', 'S05')

        # Read PC register
        conn.expect('g40', '08000000')

        # Read s0
        conn.expect('g00', '02000000')
Exemplo n.º 55
0
def gdb_read_write_register(_, target):
    hexfile = test_harness.build_program(['register_values.S'])
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Run code to load registers
        conn.expect('C', 'S05')

        # Check values set by program (remote GDB returns in swapped byte
        # order...)
        conn.expect('g1', '7d7f3e85')
        conn.expect(
            'g20', 'f13403ef9d08309993f7819954ae4b3f7aeaa28f538fecbd95'
            '36f59c6d7251269525ee70d26e8d34f48912639c86ae5dba426c83aa8455e1e2dbba4b41a4f321'
        )

        tests = [
            (0, 'd3839b18'), (1, '7b53cc78'), (30, '0904c47d'),
            (32, 'aef331bc7dbd6f1d042be4d6f1e1649855d864387eb8f0fd49c205c37790'
             'd1874078516c1a05c74f67678456679ba7e05bb5aed7303c5aeeeba6e619accf702a'
             ),
            (36, 'cb7e3668a97ef8ea55902658b62a682406f7206f75e5438ff95b4519fed1'
             'e73e16ce5a29b4385fa2560820f0c8f42227709387dbad3a8208b57c381e268ffe38'
             ),
            (63, '9e2d89afb0633c2f64b2eb4fdbba4663401ee673753a66d6d899e4a4101a'
             'e4920b0b16f0e716e4f7d62d83b5784740c138ac6ab94fa14256ebb468e25f20e02f'
             )
        ]

        for reg, value in tests:
            conn.expect('G' + hex(reg)[2:] + ',' + value, 'OK')

        for reg, value in tests:
            conn.expect('g' + hex(reg)[2:], value)

        # Read invalid register index
        conn.expect('g41', '')

        # Write invalid register index
        conn.expect('G41,12345678', '')
Exemplo n.º 56
0
def gdb_read_write_memory(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Read program code at address 0. This should match values
        # in count.hex
        conn.expect('m0,10', '0004000f0008000f000c000f0010000f')

        # (address, data)
        tests = [
            (0x1000, '523c66b3'),
            (0x1234, '22'),
            (0x2242, '45f280397a5a3255fa19238693ff13c729'),
            (0x100000, '55483c091aac1e8c6db4bed1'),
            (0x200000, '16e1d56029e912a04121ce41a635155f3442355533703fafcb57f8'
             '295dd6330f82f9ffc40edb589fac1523665dc2f6e80c1e2de9718d253fcbc'
             'e1c8a52c9dc21'),
        ]

        # Write memory
        for addr, data in tests:
            conn.expect(
                'M' + hex(addr)[2:] + ',' + hex(int(len(data) / 2))[2:] + ':' +
                data, 'OK')

        # Read and verify
        for addr, data in tests:
            conn.expect(
                'm' + hex(addr)[2:] + ',' + hex(int(len(data) / 2))[2:], data)

        # Try to write a bad address (out of range)
        # Doesn't return an error, test just ensures it
        # doesn't crash
        conn.expect('M10000000,4,12345678', 'OK')

        # Try to read a bad address (out of range)
        # As above, doesn't return error (returns 0xff...),
        # but ensure it doesn't crash.
        conn.expect('m10000000,4', 'ffffffff')
Exemplo n.º 57
0
def gdb_single_step(_, target):
    hexfile = test_harness.build_program(['count.S'], image_type='raw')
    with EmulatorProcess(hexfile), DebugConnection() as conn:
        # Read PC register
        conn.expect('g40', '00000000')

        # Single step
        conn.expect('S', 'S05')

        # Read PC register
        conn.expect('g40', '04000000')

        # Read s0
        conn.expect('g00', '01000000')

        # Single step (note here I use the lowercase version)
        conn.expect('s', 'S05')

        # Read PC register
        conn.expect('g40', '08000000')

        # Read s0
        conn.expect('g00', '02000000')
Exemplo n.º 58
0
def perf_counters(_):
    test_harness.build_program(['perf_counters.c'])
    result = test_harness.run_program(environment='verilator')
    if 'PASS' not in result:
        raise test_harness.TestException(
            'test program did not indicate pass\n' + result)
Exemplo n.º 59
0
def run_emulator_test(source_file):
    test_harness.build_program([source_file])
    result = test_harness.run_program(environment='emulator')
    test_harness.check_result(source_file, result)
Exemplo n.º 60
0
def ps2(_, target):
    test_harness.build_program(['ps2.c'])
    result = test_harness.run_program(target)
    if 'PASS' not in result:
        raise test_harness.TestException('program did not indicate pass\n' +
                                         result)