FileSystemConfig.py revision 13952
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    cpu_clock = '0'
64    if hasattr(options, 'cpu_clock'):
65        cpu_clock = options.cpu_clock
66    cpu_clock = toFrequency(cpu_clock)/mega
67
68    l2_size = '0'
69    if hasattr(options, 'l2_size'):
70        l2_size = options.l2_size
71    l2_size = toMemorySize(l2_size)/kibi
72
73    cacheline_size = '0'
74    if hasattr(options, 'cacheline_size'):
75        cacheline_size = options.cacheline_size
76
77    for i in xrange(options.num_cpus):
78        one_cpu = 'processor       : %d\n' % (i)                  + \
79                  'vendor_id       : Generic\n'                   + \
80                  'cpu family      : 0\n'                         + \
81                  'model           : 0\n'                         + \
82                  'model name      : Generic\n'                   + \
83                  'stepping        : 0\n'                         + \
84                  'cpu MHz         : %0.3d\n'                       \
85                        % cpu_clock                               + \
86                  'cache size:     : %dK\n'                         \
87                        % l2_size                                 + \
88                  'physical id     : 0\n'                         + \
89                  'siblings        : %s\n'                          \
90                        % options.num_cpus                        + \
91                  'core id         : %d\n'                          \
92                        % i                                       + \
93                  'cpu cores       : %d\n'                          \
94                        % options.num_cpus                        + \
95                  'fpu             : yes\n'                       + \
96                  'fpu exception   : yes\n'                       + \
97                  'cpuid level     : 1\n'                         + \
98                  'wp              : yes\n'                       + \
99                  'flags           : fpu\n'                       + \
100                  'cache alignment : %d\n'                          \
101                        % cacheline_size                          + \
102                  '\n'
103        file_append((procdir, 'cpuinfo'), one_cpu)
104
105    file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n')
106    for i in xrange(options.num_cpus):
107        file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i)
108
109    # Set up /sys
110    sysdir = joinpath(fsdir, 'sys')
111    mkdir(sysdir)
112
113    # Set up /sys/devices/system/cpu
114    cpudir = joinpath(sysdir, 'devices', 'system', 'cpu')
115    makedirs(cpudir)
116
117    file_append((cpudir, 'online'), '0-%d' % (options.num_cpus-1))
118    file_append((cpudir, 'possible'), '0-%d' % (options.num_cpus-1))
119
120    # Set up /tmp
121    tmpdir = joinpath(fsdir, 'tmp')
122    replace_tree(tmpdir)
123
124def register_node(cpu_list, mem, node_number):
125    nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
126                           'system', 'node')
127
128    nodedir = joinpath(nodebasedir,'node%d' % node_number)
129    makedirs(nodedir)
130
131    file_append((nodedir, 'cpumap'), hex_mask(cpu_list))
132    file_append((nodedir, 'meminfo'),
133                'Node %d MemTotal: %dkB' % (node_number,
134                toMemorySize(str(mem))/kibi))
135
136def register_cpu(physical_package_id, core_siblings,
137                 core_id, thread_siblings):
138    cpudir = joinpath(m5.options.outdir, 'fs',  'sys', 'devices', 'system',
139                      'cpu', 'cpu%d' % core_id)
140
141    if not isdir(joinpath(cpudir, 'topology')):
142        makedirs(joinpath(cpudir, 'topology'))
143    if not isdir(joinpath(cpudir, 'cache')):
144        makedirs(joinpath(cpudir, 'cache'))
145
146    file_append((cpudir, 'online'), '1')
147    file_append((cpudir, 'topology', 'physical_package_id'),
148                physical_package_id)
149    file_append((cpudir, 'topology', 'core_siblings'),
150                hex_mask(core_siblings))
151    file_append((cpudir, 'topology', 'core_id'), core_id)
152    file_append((cpudir, 'topology', 'thread_siblings'),
153                hex_mask(thread_siblings))
154
155def register_cache(level, idu_type, size, line_size, assoc, cpus):
156    fsdir = joinpath(m5.options.outdir, 'fs')
157    for i in cpus:
158        cachedir = joinpath(fsdir, 'sys', 'devices', 'system', 'cpu',
159                            'cpu%d' % i, 'cache')
160
161        j = 0
162        while isdir(joinpath(cachedir, 'index%d' % j)):
163            j += 1
164        indexdir = joinpath(cachedir, 'index%d' % j)
165        makedirs(indexdir)
166
167        file_append((indexdir, 'level'), level)
168        file_append((indexdir, 'type'), idu_type)
169        file_append((indexdir, 'size'), "%dK" % (toMemorySize(size)/kibi))
170        file_append((indexdir, 'coherency_line_size'), line_size)
171
172        # Since cache size = number of indices * associativity * block size
173        num_sets = toMemorySize(size) / int(assoc) * int(line_size)
174
175        file_append((indexdir, 'number_of_sets'), num_sets)
176        file_append((indexdir, 'physical_line_partition'), '1')
177        file_append((indexdir, 'shared_cpu_map'), hex_mask(cpus))
178
179def redirect_paths(chroot):
180    # Redirect filesystem syscalls from src to the first matching dests
181    redirect_paths = [RedirectPath(app_path = "/proc",
182                          host_paths = ["%s/fs/proc" % m5.options.outdir]),
183                      RedirectPath(app_path = "/sys",
184                          host_paths = ["%s/fs/sys"  % m5.options.outdir]),
185                      RedirectPath(app_path = "/tmp",
186                          host_paths = ["%s/fs/tmp"  % m5.options.outdir]),
187                      RedirectPath(app_path = "/",
188                          host_paths = ["%s"         % chroot])]
189    return redirect_paths
190