113883Sdavid.hashe@amd.com# Copyright (c) 2015 Advanced Micro Devices, Inc.
213883Sdavid.hashe@amd.com# All rights reserved
313883Sdavid.hashe@amd.com#
413883Sdavid.hashe@amd.com# Redistribution and use in source and binary forms, with or without
513883Sdavid.hashe@amd.com# modification, are permitted provided that the following conditions are
613883Sdavid.hashe@amd.com# met: redistributions of source code must retain the above copyright
713883Sdavid.hashe@amd.com# notice, this list of conditions and the following disclaimer;
813883Sdavid.hashe@amd.com# redistributions in binary form must reproduce the above copyright
913883Sdavid.hashe@amd.com# notice, this list of conditions and the following disclaimer in the
1013883Sdavid.hashe@amd.com# documentation and/or other materials provided with the distribution;
1113883Sdavid.hashe@amd.com# neither the name of the copyright holders nor the names of its
1213883Sdavid.hashe@amd.com# contributors may be used to endorse or promote products derived from
1313883Sdavid.hashe@amd.com# this software without specific prior written permission.
1413883Sdavid.hashe@amd.com#
1513883Sdavid.hashe@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613883Sdavid.hashe@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713883Sdavid.hashe@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813883Sdavid.hashe@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913883Sdavid.hashe@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013883Sdavid.hashe@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113883Sdavid.hashe@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213883Sdavid.hashe@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313883Sdavid.hashe@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413883Sdavid.hashe@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513883Sdavid.hashe@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613883Sdavid.hashe@amd.com#
2713883Sdavid.hashe@amd.com# Authors: David Hashe
2813883Sdavid.hashe@amd.com
2913883Sdavid.hashe@amd.comfrom __future__ import print_function
3013883Sdavid.hashe@amd.com
3113883Sdavid.hashe@amd.comimport m5
3213883Sdavid.hashe@amd.comfrom m5.objects import *
3313883Sdavid.hashe@amd.comfrom m5.util.convert import *
3413883Sdavid.hashe@amd.com
3513883Sdavid.hashe@amd.comimport operator, os, platform, getpass
3613883Sdavid.hashe@amd.comfrom os import mkdir, makedirs, getpid, listdir, stat, access
3713883Sdavid.hashe@amd.comfrom pwd import getpwuid
3813883Sdavid.hashe@amd.comfrom os.path import join as joinpath
3913883Sdavid.hashe@amd.comfrom os.path import isdir
4013883Sdavid.hashe@amd.comfrom shutil import rmtree, copyfile
4113883Sdavid.hashe@amd.com
4213883Sdavid.hashe@amd.comdef hex_mask(terms):
4313883Sdavid.hashe@amd.com    dec_mask = reduce(operator.or_, [2**i for i in terms], 0)
4413883Sdavid.hashe@amd.com    return "%08x" % dec_mask
4513883Sdavid.hashe@amd.com
4613883Sdavid.hashe@amd.comdef file_append(path, contents):
4713883Sdavid.hashe@amd.com    with open(joinpath(*path), 'a') as f:
4813883Sdavid.hashe@amd.com        f.write(str(contents))
4913883Sdavid.hashe@amd.com
5013883Sdavid.hashe@amd.comdef replace_tree(path):
5113883Sdavid.hashe@amd.com    if isdir(path):
5213883Sdavid.hashe@amd.com        rmtree(path)
5313883Sdavid.hashe@amd.com    mkdir(path)
5413883Sdavid.hashe@amd.com
5513980Sjason@lowepower.comdef config_filesystem(system, options = None):
5613980Sjason@lowepower.com    """ This function parses the system object to create the pseudo file system
5713980Sjason@lowepower.com    @param system: The system to create the config for
5813980Sjason@lowepower.com    @param options: An optional argument which contains an Options.py options
5913980Sjason@lowepower.com           object. This is useful if when use se.py and will set the L2 cache
6013980Sjason@lowepower.com           size and the clock in /proc/cpuinfo if provided.
6113980Sjason@lowepower.com
6213980Sjason@lowepower.com    First, this function walks the system object to find all CPUs.
6313980Sjason@lowepower.com    Then, this function creates the following files with the CPU information
6413980Sjason@lowepower.com      - /proc/cpuinfo which contains the clock  and the L2 size
6513980Sjason@lowepower.com        (assumes all L2s private and the same size)
6613980Sjason@lowepower.com      - /proc/stat simply lists all CPUs
6713980Sjason@lowepower.com      - /sys/devices/system/cpu/online and /sys/devices/system/cpu/possible
6813980Sjason@lowepower.com        These files list all of the CPUs in this system.
6913980Sjason@lowepower.com      - /tmp
7013980Sjason@lowepower.com
7113980Sjason@lowepower.com    These files are created in the `fs` directory in the outdir path.
7213980Sjason@lowepower.com    """
7313883Sdavid.hashe@amd.com    fsdir = joinpath(m5.options.outdir, 'fs')
7413883Sdavid.hashe@amd.com    replace_tree(fsdir)
7513883Sdavid.hashe@amd.com
7613883Sdavid.hashe@amd.com    # Set up /proc
7713883Sdavid.hashe@amd.com    procdir = joinpath(fsdir, 'proc')
7813883Sdavid.hashe@amd.com    mkdir(procdir)
7913883Sdavid.hashe@amd.com
8013980Sjason@lowepower.com    cpus = [obj for obj in system.descendants() if isinstance(obj, BaseCPU)]
8113980Sjason@lowepower.com
8213980Sjason@lowepower.com    cpu_clock = 0
8313952Sbrandon.potter@amd.com    if hasattr(options, 'cpu_clock'):
8413980Sjason@lowepower.com        cpu_clock = toFrequency(options.cpu_clock) / mega
8513952Sbrandon.potter@amd.com
8613980Sjason@lowepower.com    l2_size = 0
8713952Sbrandon.potter@amd.com    if hasattr(options, 'l2_size'):
8813980Sjason@lowepower.com        l2_size = toMemorySize(options.l2_size) / kibi
8913952Sbrandon.potter@amd.com
9013980Sjason@lowepower.com    for i,cpu in enumerate(cpus):
9113980Sjason@lowepower.com        one_cpu = 'processor       : {proc}\n'                    + \
9213883Sdavid.hashe@amd.com                  'vendor_id       : Generic\n'                   + \
9313883Sdavid.hashe@amd.com                  'cpu family      : 0\n'                         + \
9413883Sdavid.hashe@amd.com                  'model           : 0\n'                         + \
9513883Sdavid.hashe@amd.com                  'model name      : Generic\n'                   + \
9613883Sdavid.hashe@amd.com                  'stepping        : 0\n'                         + \
9713980Sjason@lowepower.com                  'cpu MHz         : {clock:0.3f}\n'              + \
9813980Sjason@lowepower.com                  'cache size:     : {l2_size}K\n'                + \
9913883Sdavid.hashe@amd.com                  'physical id     : 0\n'                         + \
10013980Sjason@lowepower.com                  'siblings        : {num_cpus}\n'                + \
10113980Sjason@lowepower.com                  'core id         : {proc}\n'                    + \
10213980Sjason@lowepower.com                  'cpu cores       : {num_cpus}\n'                + \
10313883Sdavid.hashe@amd.com                  'fpu             : yes\n'                       + \
10413883Sdavid.hashe@amd.com                  'fpu exception   : yes\n'                       + \
10513883Sdavid.hashe@amd.com                  'cpuid level     : 1\n'                         + \
10613883Sdavid.hashe@amd.com                  'wp              : yes\n'                       + \
10713883Sdavid.hashe@amd.com                  'flags           : fpu\n'                       + \
10813980Sjason@lowepower.com                  'cache alignment : {cacheline_size}\n'          + \
10913883Sdavid.hashe@amd.com                  '\n'
11013980Sjason@lowepower.com        one_cpu = one_cpu.format(proc = i, num_cpus = len(cpus),
11113980Sjason@lowepower.com                       # Note: it would be nice to use cpu.clock, but it hasn't
11213980Sjason@lowepower.com                       # been finalized yet since m5.instantiate() isn't done.
11313980Sjason@lowepower.com                       clock = cpu_clock,
11413980Sjason@lowepower.com                       # Note: this assumes the L2 is private to each core
11513980Sjason@lowepower.com                       l2_size = l2_size,
11613980Sjason@lowepower.com                       cacheline_size=system.cache_line_size.getValue())
11713883Sdavid.hashe@amd.com        file_append((procdir, 'cpuinfo'), one_cpu)
11813883Sdavid.hashe@amd.com
11913883Sdavid.hashe@amd.com    file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n')
12013980Sjason@lowepower.com    for i in xrange(len(cpus)):
12113883Sdavid.hashe@amd.com        file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i)
12213883Sdavid.hashe@amd.com
12313883Sdavid.hashe@amd.com    # Set up /sys
12413883Sdavid.hashe@amd.com    sysdir = joinpath(fsdir, 'sys')
12513883Sdavid.hashe@amd.com    mkdir(sysdir)
12613883Sdavid.hashe@amd.com
12713883Sdavid.hashe@amd.com    # Set up /sys/devices/system/cpu
12813883Sdavid.hashe@amd.com    cpudir = joinpath(sysdir, 'devices', 'system', 'cpu')
12913883Sdavid.hashe@amd.com    makedirs(cpudir)
13013883Sdavid.hashe@amd.com
13113980Sjason@lowepower.com    file_append((cpudir, 'online'), '0-%d' % (len(cpus) - 1))
13213980Sjason@lowepower.com    file_append((cpudir, 'possible'), '0-%d' % (len(cpus) - 1))
13313883Sdavid.hashe@amd.com
13413883Sdavid.hashe@amd.com    # Set up /tmp
13513883Sdavid.hashe@amd.com    tmpdir = joinpath(fsdir, 'tmp')
13613883Sdavid.hashe@amd.com    replace_tree(tmpdir)
13713883Sdavid.hashe@amd.com
13813980Sjason@lowepower.com    if options and hasattr(options, 'chroot'):
13913980Sjason@lowepower.com        chroot = os.path.expanduser(options.chroot)
14013980Sjason@lowepower.com    else:
14113980Sjason@lowepower.com        chroot = '/'
14213980Sjason@lowepower.com    system.redirect_paths = _redirect_paths(chroot)
14313980Sjason@lowepower.com
14413883Sdavid.hashe@amd.comdef register_node(cpu_list, mem, node_number):
14513883Sdavid.hashe@amd.com    nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
14613883Sdavid.hashe@amd.com                           'system', 'node')
14713883Sdavid.hashe@amd.com
14813883Sdavid.hashe@amd.com    nodedir = joinpath(nodebasedir,'node%d' % node_number)
14913883Sdavid.hashe@amd.com    makedirs(nodedir)
15013883Sdavid.hashe@amd.com
15113883Sdavid.hashe@amd.com    file_append((nodedir, 'cpumap'), hex_mask(cpu_list))
15213883Sdavid.hashe@amd.com    file_append((nodedir, 'meminfo'),
15313883Sdavid.hashe@amd.com                'Node %d MemTotal: %dkB' % (node_number,
15413883Sdavid.hashe@amd.com                toMemorySize(str(mem))/kibi))
15513883Sdavid.hashe@amd.com
15613883Sdavid.hashe@amd.comdef register_cpu(physical_package_id, core_siblings,
15713883Sdavid.hashe@amd.com                 core_id, thread_siblings):
15813883Sdavid.hashe@amd.com    cpudir = joinpath(m5.options.outdir, 'fs',  'sys', 'devices', 'system',
15913883Sdavid.hashe@amd.com                      'cpu', 'cpu%d' % core_id)
16013883Sdavid.hashe@amd.com
16113883Sdavid.hashe@amd.com    if not isdir(joinpath(cpudir, 'topology')):
16213883Sdavid.hashe@amd.com        makedirs(joinpath(cpudir, 'topology'))
16313883Sdavid.hashe@amd.com    if not isdir(joinpath(cpudir, 'cache')):
16413883Sdavid.hashe@amd.com        makedirs(joinpath(cpudir, 'cache'))
16513883Sdavid.hashe@amd.com
16613883Sdavid.hashe@amd.com    file_append((cpudir, 'online'), '1')
16713883Sdavid.hashe@amd.com    file_append((cpudir, 'topology', 'physical_package_id'),
16813883Sdavid.hashe@amd.com                physical_package_id)
16913883Sdavid.hashe@amd.com    file_append((cpudir, 'topology', 'core_siblings'),
17013883Sdavid.hashe@amd.com                hex_mask(core_siblings))
17113883Sdavid.hashe@amd.com    file_append((cpudir, 'topology', 'core_id'), core_id)
17213883Sdavid.hashe@amd.com    file_append((cpudir, 'topology', 'thread_siblings'),
17313883Sdavid.hashe@amd.com                hex_mask(thread_siblings))
17413883Sdavid.hashe@amd.com
17513883Sdavid.hashe@amd.comdef register_cache(level, idu_type, size, line_size, assoc, cpus):
17613883Sdavid.hashe@amd.com    fsdir = joinpath(m5.options.outdir, 'fs')
17713883Sdavid.hashe@amd.com    for i in cpus:
17813883Sdavid.hashe@amd.com        cachedir = joinpath(fsdir, 'sys', 'devices', 'system', 'cpu',
17913883Sdavid.hashe@amd.com                            'cpu%d' % i, 'cache')
18013883Sdavid.hashe@amd.com
18113883Sdavid.hashe@amd.com        j = 0
18213883Sdavid.hashe@amd.com        while isdir(joinpath(cachedir, 'index%d' % j)):
18313883Sdavid.hashe@amd.com            j += 1
18413883Sdavid.hashe@amd.com        indexdir = joinpath(cachedir, 'index%d' % j)
18513883Sdavid.hashe@amd.com        makedirs(indexdir)
18613883Sdavid.hashe@amd.com
18713883Sdavid.hashe@amd.com        file_append((indexdir, 'level'), level)
18813883Sdavid.hashe@amd.com        file_append((indexdir, 'type'), idu_type)
18913883Sdavid.hashe@amd.com        file_append((indexdir, 'size'), "%dK" % (toMemorySize(size)/kibi))
19013883Sdavid.hashe@amd.com        file_append((indexdir, 'coherency_line_size'), line_size)
19113883Sdavid.hashe@amd.com
19213883Sdavid.hashe@amd.com        # Since cache size = number of indices * associativity * block size
19313883Sdavid.hashe@amd.com        num_sets = toMemorySize(size) / int(assoc) * int(line_size)
19413883Sdavid.hashe@amd.com
19513883Sdavid.hashe@amd.com        file_append((indexdir, 'number_of_sets'), num_sets)
19613883Sdavid.hashe@amd.com        file_append((indexdir, 'physical_line_partition'), '1')
19713883Sdavid.hashe@amd.com        file_append((indexdir, 'shared_cpu_map'), hex_mask(cpus))
19813883Sdavid.hashe@amd.com
19913980Sjason@lowepower.comdef _redirect_paths(chroot):
20013883Sdavid.hashe@amd.com    # Redirect filesystem syscalls from src to the first matching dests
20113883Sdavid.hashe@amd.com    redirect_paths = [RedirectPath(app_path = "/proc",
20213883Sdavid.hashe@amd.com                          host_paths = ["%s/fs/proc" % m5.options.outdir]),
20313883Sdavid.hashe@amd.com                      RedirectPath(app_path = "/sys",
20413883Sdavid.hashe@amd.com                          host_paths = ["%s/fs/sys"  % m5.options.outdir]),
20513883Sdavid.hashe@amd.com                      RedirectPath(app_path = "/tmp",
20613883Sdavid.hashe@amd.com                          host_paths = ["%s/fs/tmp"  % m5.options.outdir]),
20713883Sdavid.hashe@amd.com                      RedirectPath(app_path = "/",
20813883Sdavid.hashe@amd.com                          host_paths = ["%s"         % chroot])]
20913883Sdavid.hashe@amd.com    return redirect_paths
210