FileSystemConfig.py (13952:197e72db5ab0) FileSystemConfig.py (13980:62a28c423e91)
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
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):
55def config_filesystem(system, options = None):
56 """ This function parses the system object to create the pseudo file system
57 @param system: The system to create the config for
58 @param options: An optional argument which contains an Options.py options
59 object. This is useful if when use se.py and will set the L2 cache
60 size and the clock in /proc/cpuinfo if provided.
61
62 First, this function walks the system object to find all CPUs.
63 Then, this function creates the following files with the CPU information
64 - /proc/cpuinfo which contains the clock and the L2 size
65 (assumes all L2s private and the same size)
66 - /proc/stat simply lists all CPUs
67 - /sys/devices/system/cpu/online and /sys/devices/system/cpu/possible
68 These files list all of the CPUs in this system.
69 - /tmp
70
71 These files are created in the `fs` directory in the outdir path.
72 """
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
73 fsdir = joinpath(m5.options.outdir, 'fs')
74 replace_tree(fsdir)
75
76 # Set up /proc
77 procdir = joinpath(fsdir, 'proc')
78 mkdir(procdir)
79
63 cpu_clock = '0'
80 cpus = [obj for obj in system.descendants() if isinstance(obj, BaseCPU)]
81
82 cpu_clock = 0
64 if hasattr(options, 'cpu_clock'):
83 if hasattr(options, 'cpu_clock'):
65 cpu_clock = options.cpu_clock
66 cpu_clock = toFrequency(cpu_clock)/mega
84 cpu_clock = toFrequency(options.cpu_clock) / mega
67
85
68 l2_size = '0'
86 l2_size = 0
69 if hasattr(options, 'l2_size'):
87 if hasattr(options, 'l2_size'):
70 l2_size = options.l2_size
71 l2_size = toMemorySize(l2_size)/kibi
88 l2_size = toMemorySize(options.l2_size) / kibi
72
89
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) + \
90 for i,cpu in enumerate(cpus):
91 one_cpu = 'processor : {proc}\n' + \
79 'vendor_id : Generic\n' + \
80 'cpu family : 0\n' + \
81 'model : 0\n' + \
82 'model name : Generic\n' + \
83 'stepping : 0\n' + \
92 'vendor_id : Generic\n' + \
93 'cpu family : 0\n' + \
94 'model : 0\n' + \
95 'model name : Generic\n' + \
96 'stepping : 0\n' + \
84 'cpu MHz : %0.3d\n' \
85 % cpu_clock + \
86 'cache size: : %dK\n' \
87 % l2_size + \
97 'cpu MHz : {clock:0.3f}\n' + \
98 'cache size: : {l2_size}K\n' + \
88 'physical id : 0\n' + \
99 '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 + \
100 'siblings : {num_cpus}\n' + \
101 'core id : {proc}\n' + \
102 'cpu cores : {num_cpus}\n' + \
95 'fpu : yes\n' + \
96 'fpu exception : yes\n' + \
97 'cpuid level : 1\n' + \
98 'wp : yes\n' + \
99 'flags : fpu\n' + \
103 'fpu : yes\n' + \
104 'fpu exception : yes\n' + \
105 'cpuid level : 1\n' + \
106 'wp : yes\n' + \
107 'flags : fpu\n' + \
100 'cache alignment : %d\n' \
101 % cacheline_size + \
108 'cache alignment : {cacheline_size}\n' + \
102 '\n'
109 '\n'
110 one_cpu = one_cpu.format(proc = i, num_cpus = len(cpus),
111 # Note: it would be nice to use cpu.clock, but it hasn't
112 # been finalized yet since m5.instantiate() isn't done.
113 clock = cpu_clock,
114 # Note: this assumes the L2 is private to each core
115 l2_size = l2_size,
116 cacheline_size=system.cache_line_size.getValue())
103 file_append((procdir, 'cpuinfo'), one_cpu)
104
105 file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n')
117 file_append((procdir, 'cpuinfo'), one_cpu)
118
119 file_append((procdir, 'stat'), 'cpu 0 0 0 0 0 0 0\n')
106 for i in xrange(options.num_cpus):
120 for i in xrange(len(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
121 file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i)
122
123 # Set up /sys
124 sysdir = joinpath(fsdir, 'sys')
125 mkdir(sysdir)
126
127 # Set up /sys/devices/system/cpu
128 cpudir = joinpath(sysdir, 'devices', 'system', 'cpu')
129 makedirs(cpudir)
130
117 file_append((cpudir, 'online'), '0-%d' % (options.num_cpus-1))
118 file_append((cpudir, 'possible'), '0-%d' % (options.num_cpus-1))
131 file_append((cpudir, 'online'), '0-%d' % (len(cpus) - 1))
132 file_append((cpudir, 'possible'), '0-%d' % (len(cpus) - 1))
119
120 # Set up /tmp
121 tmpdir = joinpath(fsdir, 'tmp')
122 replace_tree(tmpdir)
123
133
134 # Set up /tmp
135 tmpdir = joinpath(fsdir, 'tmp')
136 replace_tree(tmpdir)
137
138 if options and hasattr(options, 'chroot'):
139 chroot = os.path.expanduser(options.chroot)
140 else:
141 chroot = '/'
142 system.redirect_paths = _redirect_paths(chroot)
143
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
144def register_node(cpu_list, mem, node_number):
145 nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
146 'system', 'node')
147
148 nodedir = joinpath(nodebasedir,'node%d' % node_number)
149 makedirs(nodedir)
150
151 file_append((nodedir, 'cpumap'), hex_mask(cpu_list))
152 file_append((nodedir, 'meminfo'),
153 'Node %d MemTotal: %dkB' % (node_number,
154 toMemorySize(str(mem))/kibi))
155
156def register_cpu(physical_package_id, core_siblings,
157 core_id, thread_siblings):
158 cpudir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices', 'system',
159 'cpu', 'cpu%d' % core_id)
160
161 if not isdir(joinpath(cpudir, 'topology')):
162 makedirs(joinpath(cpudir, 'topology'))
163 if not isdir(joinpath(cpudir, 'cache')):
164 makedirs(joinpath(cpudir, 'cache'))
165
166 file_append((cpudir, 'online'), '1')
167 file_append((cpudir, 'topology', 'physical_package_id'),
168 physical_package_id)
169 file_append((cpudir, 'topology', 'core_siblings'),
170 hex_mask(core_siblings))
171 file_append((cpudir, 'topology', 'core_id'), core_id)
172 file_append((cpudir, 'topology', 'thread_siblings'),
173 hex_mask(thread_siblings))
174
175def register_cache(level, idu_type, size, line_size, assoc, cpus):
176 fsdir = joinpath(m5.options.outdir, 'fs')
177 for i in cpus:
178 cachedir = joinpath(fsdir, 'sys', 'devices', 'system', 'cpu',
179 'cpu%d' % i, 'cache')
180
181 j = 0
182 while isdir(joinpath(cachedir, 'index%d' % j)):
183 j += 1
184 indexdir = joinpath(cachedir, 'index%d' % j)
185 makedirs(indexdir)
186
187 file_append((indexdir, 'level'), level)
188 file_append((indexdir, 'type'), idu_type)
189 file_append((indexdir, 'size'), "%dK" % (toMemorySize(size)/kibi))
190 file_append((indexdir, 'coherency_line_size'), line_size)
191
192 # Since cache size = number of indices * associativity * block size
193 num_sets = toMemorySize(size) / int(assoc) * int(line_size)
194
195 file_append((indexdir, 'number_of_sets'), num_sets)
196 file_append((indexdir, 'physical_line_partition'), '1')
197 file_append((indexdir, 'shared_cpu_map'), hex_mask(cpus))
198
179def redirect_paths(chroot):
199def _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
200 # Redirect filesystem syscalls from src to the first matching dests
201 redirect_paths = [RedirectPath(app_path = "/proc",
202 host_paths = ["%s/fs/proc" % m5.options.outdir]),
203 RedirectPath(app_path = "/sys",
204 host_paths = ["%s/fs/sys" % m5.options.outdir]),
205 RedirectPath(app_path = "/tmp",
206 host_paths = ["%s/fs/tmp" % m5.options.outdir]),
207 RedirectPath(app_path = "/",
208 host_paths = ["%s" % chroot])]
209 return redirect_paths