FileSystemConfig.py revision 13883:f44e21d3aaa7
1# Copyright (c) 2015 Advanced Micro Devices, Inc.
2# All rights reserved
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: David Hashe
28
29from __future__ import print_function
30
31import m5
32from m5.objects import *
33from m5.util.convert import *
34
35import operator, os, platform, getpass
36from os import mkdir, makedirs, getpid, listdir, stat, access
37from pwd import getpwuid
38from os.path import join as joinpath
39from os.path import isdir
40from shutil import rmtree, copyfile
41
42def hex_mask(terms):
43    dec_mask = reduce(operator.or_, [2**i for i in terms], 0)
44    return "%08x" % dec_mask
45
46def file_append(path, contents):
47    with open(joinpath(*path), 'a') as f:
48        f.write(str(contents))
49
50def replace_tree(path):
51    if isdir(path):
52        rmtree(path)
53    mkdir(path)
54
55def config_filesystem(options):
56    fsdir = joinpath(m5.options.outdir, 'fs')
57    replace_tree(fsdir)
58
59    # Set up /proc
60    procdir = joinpath(fsdir, 'proc')
61    mkdir(procdir)
62
63    for i in xrange(options.num_cpus):
64        one_cpu = 'processor       : 0\n'                         + \
65                  'vendor_id       : Generic\n'                   + \
66                  'cpu family      : 0\n'                         + \
67                  'model           : 0\n'                         + \
68                  'model name      : Generic\n'                   + \
69                  'stepping        : 0\n'                         + \
70                  'cpu MHz         : %0.3d\n'                       \
71                        % (toFrequency(options.cpu_clock)/mega)   + \
72                  'cache size:     : %dK\n'                         \
73                        % (toMemorySize(options.l2_size)/kibi)    + \
74                  'physical id     : 0\n'                         + \
75                  'siblings        : %s\n'                          \
76                        % options.num_cpus                        + \
77                  'core id         : %d\n'                          \
78                        % i                                       + \
79                  'cpu cores       : %d\n'                          \
80                        % options.num_cpus                        + \
81                  'fpu             : yes\n'                       + \
82                  'fpu exception   : yes\n'                       + \
83                  'cpuid level     : 1\n'                         + \
84                  'wp              : yes\n'                       + \
85                  'flags           : fpu\n'                       + \
86                  'cache alignment : %d\n'                          \
87                        % options.cacheline_size                  + \
88                  '\n'
89        file_append((procdir, 'cpuinfo'), one_cpu)
90
91    file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n')
92    for i in xrange(options.num_cpus):
93        file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i)
94
95    # Set up /sys
96    sysdir = joinpath(fsdir, 'sys')
97    mkdir(sysdir)
98
99    # Set up /sys/devices/system/cpu
100    cpudir = joinpath(sysdir, 'devices', 'system', 'cpu')
101    makedirs(cpudir)
102
103    file_append((cpudir, 'online'), '0-%d' % (options.num_cpus-1))
104    file_append((cpudir, 'possible'), '0-%d' % (options.num_cpus-1))
105
106    # Set up /tmp
107    tmpdir = joinpath(fsdir, 'tmp')
108    replace_tree(tmpdir)
109
110def register_node(cpu_list, mem, node_number):
111    nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
112                           'system', 'node')
113
114    nodedir = joinpath(nodebasedir,'node%d' % node_number)
115    makedirs(nodedir)
116
117    file_append((nodedir, 'cpumap'), hex_mask(cpu_list))
118    file_append((nodedir, 'meminfo'),
119                'Node %d MemTotal: %dkB' % (node_number,
120                toMemorySize(str(mem))/kibi))
121
122def register_cpu(physical_package_id, core_siblings,
123                 core_id, thread_siblings):
124    cpudir = joinpath(m5.options.outdir, 'fs',  'sys', 'devices', 'system',
125                      'cpu', 'cpu%d' % core_id)
126
127    if not isdir(joinpath(cpudir, 'topology')):
128        makedirs(joinpath(cpudir, 'topology'))
129    if not isdir(joinpath(cpudir, 'cache')):
130        makedirs(joinpath(cpudir, 'cache'))
131
132    file_append((cpudir, 'online'), '1')
133    file_append((cpudir, 'topology', 'physical_package_id'),
134                physical_package_id)
135    file_append((cpudir, 'topology', 'core_siblings'),
136                hex_mask(core_siblings))
137    file_append((cpudir, 'topology', 'core_id'), core_id)
138    file_append((cpudir, 'topology', 'thread_siblings'),
139                hex_mask(thread_siblings))
140
141def register_cache(level, idu_type, size, line_size, assoc, cpus):
142    fsdir = joinpath(m5.options.outdir, 'fs')
143    for i in cpus:
144        cachedir = joinpath(fsdir, 'sys', 'devices', 'system', 'cpu',
145                            'cpu%d' % i, 'cache')
146
147        j = 0
148        while isdir(joinpath(cachedir, 'index%d' % j)):
149            j += 1
150        indexdir = joinpath(cachedir, 'index%d' % j)
151        makedirs(indexdir)
152
153        file_append((indexdir, 'level'), level)
154        file_append((indexdir, 'type'), idu_type)
155        file_append((indexdir, 'size'), "%dK" % (toMemorySize(size)/kibi))
156        file_append((indexdir, 'coherency_line_size'), line_size)
157
158        # Since cache size = number of indices * associativity * block size
159        num_sets = toMemorySize(size) / int(assoc) * int(line_size)
160
161        file_append((indexdir, 'number_of_sets'), num_sets)
162        file_append((indexdir, 'physical_line_partition'), '1')
163        file_append((indexdir, 'shared_cpu_map'), hex_mask(cpus))
164
165def redirect_paths(chroot):
166    # Redirect filesystem syscalls from src to the first matching dests
167    redirect_paths = [RedirectPath(app_path = "/proc",
168                          host_paths = ["%s/fs/proc" % m5.options.outdir]),
169                      RedirectPath(app_path = "/sys",
170                          host_paths = ["%s/fs/sys"  % m5.options.outdir]),
171                      RedirectPath(app_path = "/tmp",
172                          host_paths = ["%s/fs/tmp"  % m5.options.outdir]),
173                      RedirectPath(app_path = "/",
174                          host_paths = ["%s"         % chroot])]
175    return redirect_paths
176