| # Copyright (c) 2015 Advanced Micro Devices, Inc. |
| # All rights reserved |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer; |
| # redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution; |
| # neither the name of the copyright holders nor the names of its |
| # contributors may be used to endorse or promote products derived from |
| # this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| # |
| # Authors: David Hashe |
| |
| from __future__ import print_function |
| |
| import m5 |
| from m5.objects import * |
| from m5.util.convert import * |
| |
| import operator, os, platform, getpass |
| from os import mkdir, makedirs, getpid, listdir, stat, access |
| from pwd import getpwuid |
| from os.path import join as joinpath |
| from os.path import isdir |
| from shutil import rmtree, copyfile |
| |
| def hex_mask(terms): |
| dec_mask = reduce(operator.or_, [2**i for i in terms], 0) |
| return "%08x" % dec_mask |
| |
| def file_append(path, contents): |
| with open(joinpath(*path), 'a') as f: |
| f.write(str(contents)) |
| |
| def replace_tree(path): |
| if isdir(path): |
| rmtree(path) |
| mkdir(path) |
| |
| def config_filesystem(options): |
| fsdir = joinpath(m5.options.outdir, 'fs') |
| replace_tree(fsdir) |
| |
| # Set up /proc |
| procdir = joinpath(fsdir, 'proc') |
| mkdir(procdir) |
| |
| cpu_clock = '0' |
| if hasattr(options, 'cpu_clock'): |
| cpu_clock = options.cpu_clock |
| cpu_clock = toFrequency(cpu_clock)/mega |
| |
| l2_size = '0' |
| if hasattr(options, 'l2_size'): |
| l2_size = options.l2_size |
| l2_size = toMemorySize(l2_size)/kibi |
| |
| cacheline_size = '0' |
| if hasattr(options, 'cacheline_size'): |
| cacheline_size = options.cacheline_size |
| |
| for i in xrange(options.num_cpus): |
| one_cpu = 'processor : %d\n' % (i) + \ |
| 'vendor_id : Generic\n' + \ |
| 'cpu family : 0\n' + \ |
| 'model : 0\n' + \ |
| 'model name : Generic\n' + \ |
| 'stepping : 0\n' + \ |
| 'cpu MHz : %0.3d\n' \ |
| % cpu_clock + \ |
| 'cache size: : %dK\n' \ |
| % l2_size + \ |
| 'physical id : 0\n' + \ |
| 'siblings : %s\n' \ |
| % options.num_cpus + \ |
| 'core id : %d\n' \ |
| % i + \ |
| 'cpu cores : %d\n' \ |
| % options.num_cpus + \ |
| 'fpu : yes\n' + \ |
| 'fpu exception : yes\n' + \ |
| 'cpuid level : 1\n' + \ |
| 'wp : yes\n' + \ |
| 'flags : fpu\n' + \ |
| 'cache alignment : %d\n' \ |
| % cacheline_size + \ |
| '\n' |
| file_append((procdir, 'cpuinfo'), one_cpu) |
| |
| file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n') |
| for i in xrange(options.num_cpus): |
| file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i) |
| |
| # Set up /sys |
| sysdir = joinpath(fsdir, 'sys') |
| mkdir(sysdir) |
| |
| # Set up /sys/devices/system/cpu |
| cpudir = joinpath(sysdir, 'devices', 'system', 'cpu') |
| makedirs(cpudir) |
| |
| file_append((cpudir, 'online'), '0-%d' % (options.num_cpus-1)) |
| file_append((cpudir, 'possible'), '0-%d' % (options.num_cpus-1)) |
| |
| # Set up /tmp |
| tmpdir = joinpath(fsdir, 'tmp') |
| replace_tree(tmpdir) |
| |
| def register_node(cpu_list, mem, node_number): |
| nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices', |
| 'system', 'node') |
| |
| nodedir = joinpath(nodebasedir,'node%d' % node_number) |
| makedirs(nodedir) |
| |
| file_append((nodedir, 'cpumap'), hex_mask(cpu_list)) |
| file_append((nodedir, 'meminfo'), |
| 'Node %d MemTotal: %dkB' % (node_number, |
| toMemorySize(str(mem))/kibi)) |
| |
| def register_cpu(physical_package_id, core_siblings, |
| core_id, thread_siblings): |
| cpudir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices', 'system', |
| 'cpu', 'cpu%d' % core_id) |
| |
| if not isdir(joinpath(cpudir, 'topology')): |
| makedirs(joinpath(cpudir, 'topology')) |
| if not isdir(joinpath(cpudir, 'cache')): |
| makedirs(joinpath(cpudir, 'cache')) |
| |
| file_append((cpudir, 'online'), '1') |
| file_append((cpudir, 'topology', 'physical_package_id'), |
| physical_package_id) |
| file_append((cpudir, 'topology', 'core_siblings'), |
| hex_mask(core_siblings)) |
| file_append((cpudir, 'topology', 'core_id'), core_id) |
| file_append((cpudir, 'topology', 'thread_siblings'), |
| hex_mask(thread_siblings)) |
| |
| def register_cache(level, idu_type, size, line_size, assoc, cpus): |
| fsdir = joinpath(m5.options.outdir, 'fs') |
| for i in cpus: |
| cachedir = joinpath(fsdir, 'sys', 'devices', 'system', 'cpu', |
| 'cpu%d' % i, 'cache') |
| |
| j = 0 |
| while isdir(joinpath(cachedir, 'index%d' % j)): |
| j += 1 |
| indexdir = joinpath(cachedir, 'index%d' % j) |
| makedirs(indexdir) |
| |
| file_append((indexdir, 'level'), level) |
| file_append((indexdir, 'type'), idu_type) |
| file_append((indexdir, 'size'), "%dK" % (toMemorySize(size)/kibi)) |
| file_append((indexdir, 'coherency_line_size'), line_size) |
| |
| # Since cache size = number of indices * associativity * block size |
| num_sets = toMemorySize(size) / int(assoc) * int(line_size) |
| |
| file_append((indexdir, 'number_of_sets'), num_sets) |
| file_append((indexdir, 'physical_line_partition'), '1') |
| file_append((indexdir, 'shared_cpu_map'), hex_mask(cpus)) |
| |
| def redirect_paths(chroot): |
| # Redirect filesystem syscalls from src to the first matching dests |
| redirect_paths = [RedirectPath(app_path = "/proc", |
| host_paths = ["%s/fs/proc" % m5.options.outdir]), |
| RedirectPath(app_path = "/sys", |
| host_paths = ["%s/fs/sys" % m5.options.outdir]), |
| RedirectPath(app_path = "/tmp", |
| host_paths = ["%s/fs/tmp" % m5.options.outdir]), |
| RedirectPath(app_path = "/", |
| host_paths = ["%s" % chroot])] |
| return redirect_paths |