misc: Run pre-commit run on all files in repo
The following command was run: ``` pre-commit run --all-files ``` This ensures all the files in the repository are formatted to pass our checks. Change-Id: Ia2fe3529a50ad925d1076a612d60a4280adc40de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62572 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
committed by
Bobby Bruce
parent
64add0e04d
commit
2bc5a8b71a
1
.mailmap
1
.mailmap
@@ -331,4 +331,3 @@ Marjan Fariborz <mfariborz@ucdavis.edu> marjanfariborz <mfariborz@ucdavis.edu>
|
|||||||
Mike Upton <michaelupton@gmail.com>
|
Mike Upton <michaelupton@gmail.com>
|
||||||
seanzw <seanyukigeek@gmail.com>
|
seanzw <seanyukigeek@gmail.com>
|
||||||
Trivikram Reddy <tvreddy@ucdavis.edu> tv-reddy <tvreddy@ucdavis.edu>
|
Trivikram Reddy <tvreddy@ucdavis.edu> tv-reddy <tvreddy@ucdavis.edu>
|
||||||
|
|
||||||
|
|||||||
@@ -246,10 +246,9 @@ maintainer (see MAINTAINERS).*
|
|||||||
## Running Tests in Parallel
|
## Running Tests in Parallel
|
||||||
|
|
||||||
Whimsy has support for parallel testing baked in. This system supports
|
Whimsy has support for parallel testing baked in. This system supports
|
||||||
running multiple suites at the same time on the same computer. To run
|
running multiple suites at the same time on the same computer. To run
|
||||||
suites in parallel, supply the `-t <number-tests>` flag to the run command.
|
suites in parallel, supply the `-t <number-tests>` flag to the run command.
|
||||||
|
|
||||||
For example, to run up to three test suites at the same time::
|
For example, to run up to three test suites at the same time::
|
||||||
|
|
||||||
./main.py run --skip-build -t 3
|
./main.py run --skip-build -t 3
|
||||||
|
|
||||||
|
|||||||
@@ -26,16 +26,17 @@
|
|||||||
import array
|
import array
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
|
||||||
def bytesToCppArray(code, symbol, data):
|
def bytesToCppArray(code, symbol, data):
|
||||||
'''
|
"""
|
||||||
Output an array of bytes to a code formatter as a c++ array declaration.
|
Output an array of bytes to a code formatter as a c++ array declaration.
|
||||||
'''
|
"""
|
||||||
code('const std::uint8_t ${symbol}[] = {')
|
code("const std::uint8_t ${symbol}[] = {")
|
||||||
code.indent()
|
code.indent()
|
||||||
step = 16
|
step = 16
|
||||||
for i in range(0, len(data), step):
|
for i in range(0, len(data), step):
|
||||||
x = array.array('B', data[i:i+step])
|
x = array.array("B", data[i : i + step])
|
||||||
strs = map(lambda i: f'{i},', x)
|
strs = map(lambda i: f"{i},", x)
|
||||||
code(functools.reduce(lambda x, y: x + y, strs))
|
code(functools.reduce(lambda x, y: x + y, strs))
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('};')
|
code("};")
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import inspect
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class lookup(object):
|
class lookup(object):
|
||||||
def __init__(self, formatter, frame, *args, **kwargs):
|
def __init__(self, formatter, frame, *args, **kwargs):
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
@@ -64,10 +65,10 @@ class lookup(object):
|
|||||||
if item in self.kwargs:
|
if item in self.kwargs:
|
||||||
return self.kwargs[item]
|
return self.kwargs[item]
|
||||||
|
|
||||||
if item == '__file__':
|
if item == "__file__":
|
||||||
return self.frame.f_code.co_filename
|
return self.frame.f_code.co_filename
|
||||||
|
|
||||||
if item == '__line__':
|
if item == "__line__":
|
||||||
return self.frame.f_lineno
|
return self.frame.f_lineno
|
||||||
|
|
||||||
if self.formatter.locals and item in self.frame.f_locals:
|
if self.formatter.locals and item in self.frame.f_locals:
|
||||||
@@ -89,6 +90,7 @@ class lookup(object):
|
|||||||
pass
|
pass
|
||||||
raise IndexError("Could not find '%s'" % item)
|
raise IndexError("Could not find '%s'" % item)
|
||||||
|
|
||||||
|
|
||||||
class code_formatter_meta(type):
|
class code_formatter_meta(type):
|
||||||
pattern = r"""
|
pattern = r"""
|
||||||
(?:
|
(?:
|
||||||
@@ -102,44 +104,48 @@ class code_formatter_meta(type):
|
|||||||
%(delim)s(?P<invalid>) # ill-formed delimiter exprs
|
%(delim)s(?P<invalid>) # ill-formed delimiter exprs
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(cls, name, bases, dct):
|
def __init__(cls, name, bases, dct):
|
||||||
super(code_formatter_meta, cls).__init__(name, bases, dct)
|
super(code_formatter_meta, cls).__init__(name, bases, dct)
|
||||||
if 'pattern' in dct:
|
if "pattern" in dct:
|
||||||
pat = cls.pattern
|
pat = cls.pattern
|
||||||
else:
|
else:
|
||||||
# tuple expansion to ensure strings are proper length
|
# tuple expansion to ensure strings are proper length
|
||||||
lb,rb = cls.braced
|
lb, rb = cls.braced
|
||||||
lb1,lb2,rb2,rb1 = cls.double_braced
|
lb1, lb2, rb2, rb1 = cls.double_braced
|
||||||
pat = code_formatter_meta.pattern % {
|
pat = code_formatter_meta.pattern % {
|
||||||
'delim' : re.escape(cls.delim),
|
"delim": re.escape(cls.delim),
|
||||||
'ident' : cls.ident,
|
"ident": cls.ident,
|
||||||
'pos' : cls.pos,
|
"pos": cls.pos,
|
||||||
'lb' : re.escape(lb),
|
"lb": re.escape(lb),
|
||||||
'rb' : re.escape(rb),
|
"rb": re.escape(rb),
|
||||||
'ldb' : re.escape(lb1+lb2),
|
"ldb": re.escape(lb1 + lb2),
|
||||||
'rdb' : re.escape(rb2+rb1),
|
"rdb": re.escape(rb2 + rb1),
|
||||||
}
|
}
|
||||||
cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE)
|
cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
class code_formatter(object, metaclass=code_formatter_meta):
|
class code_formatter(object, metaclass=code_formatter_meta):
|
||||||
delim = r'$'
|
delim = r"$"
|
||||||
ident = r'[_A-z]\w*'
|
ident = r"[_A-z]\w*"
|
||||||
pos = r'[0-9]+'
|
pos = r"[0-9]+"
|
||||||
braced = r'{}'
|
braced = r"{}"
|
||||||
double_braced = r'{{}}'
|
double_braced = r"{{}}"
|
||||||
|
|
||||||
globals = True
|
globals = True
|
||||||
locals = True
|
locals = True
|
||||||
fix_newlines = True
|
fix_newlines = True
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._data = []
|
self._data = []
|
||||||
self._dict = {}
|
self._dict = {}
|
||||||
self._indent_level = 0
|
self._indent_level = 0
|
||||||
self._indent_spaces = 4
|
self._indent_spaces = 4
|
||||||
self.globals = kwargs.pop('globals', type(self).globals)
|
self.globals = kwargs.pop("globals", type(self).globals)
|
||||||
self.locals = kwargs.pop('locals', type(self).locals)
|
self.locals = kwargs.pop("locals", type(self).locals)
|
||||||
self._fix_newlines = \
|
self._fix_newlines = kwargs.pop(
|
||||||
kwargs.pop('fix_newlines', type(self).fix_newlines)
|
"fix_newlines", type(self).fix_newlines
|
||||||
|
)
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
self.__call__(args)
|
self.__call__(args)
|
||||||
@@ -171,38 +177,44 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
|||||||
# Add a comment to inform which file generated the generated file
|
# Add a comment to inform which file generated the generated file
|
||||||
# to make it easier to backtrack and modify generated code
|
# to make it easier to backtrack and modify generated code
|
||||||
frame = inspect.currentframe().f_back
|
frame = inspect.currentframe().f_back
|
||||||
if re.match(r'^\.(cc|hh|c|h)$', extension) is not None:
|
if re.match(r"^\.(cc|hh|c|h)$", extension) is not None:
|
||||||
f.write(f'''/**
|
f.write(
|
||||||
|
f"""/**
|
||||||
* DO NOT EDIT THIS FILE!
|
* DO NOT EDIT THIS FILE!
|
||||||
* File automatically generated by
|
* File automatically generated by
|
||||||
* {frame.f_code.co_filename}:{frame.f_lineno}
|
* {frame.f_code.co_filename}:{frame.f_lineno}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
''')
|
"""
|
||||||
elif re.match(r'^\.py$', extension) is not None:
|
)
|
||||||
f.write(f'''#
|
elif re.match(r"^\.py$", extension) is not None:
|
||||||
|
f.write(
|
||||||
|
f"""#
|
||||||
# DO NOT EDIT THIS FILE!
|
# DO NOT EDIT THIS FILE!
|
||||||
# File automatically generated by
|
# File automatically generated by
|
||||||
# {frame.f_code.co_filename}:{frame.f_lineno}
|
# {frame.f_code.co_filename}:{frame.f_lineno}
|
||||||
#
|
#
|
||||||
|
|
||||||
''')
|
"""
|
||||||
elif re.match(r'^\.html$', extension) is not None:
|
)
|
||||||
f.write(f'''<!--
|
elif re.match(r"^\.html$", extension) is not None:
|
||||||
|
f.write(
|
||||||
|
f"""<!--
|
||||||
DO NOT EDIT THIS FILE!
|
DO NOT EDIT THIS FILE!
|
||||||
File automatically generated by
|
File automatically generated by
|
||||||
{frame.f_code.co_filename}:{frame.f_lineno}
|
{frame.f_code.co_filename}:{frame.f_lineno}
|
||||||
-->
|
-->
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
for data in self._data:
|
for data in self._data:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
data = ''.join(self._data)
|
data = "".join(self._data)
|
||||||
self._data = [ data ]
|
self._data = [data]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
@@ -231,21 +243,21 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
|||||||
self._data.append(data)
|
self._data.append(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
initial_newline = not self._data or self._data[-1] == '\n'
|
initial_newline = not self._data or self._data[-1] == "\n"
|
||||||
for line in data.splitlines():
|
for line in data.splitlines():
|
||||||
if line:
|
if line:
|
||||||
if self._indent_level:
|
if self._indent_level:
|
||||||
self._data.append(' ' * self._indent_level)
|
self._data.append(" " * self._indent_level)
|
||||||
self._data.append(line)
|
self._data.append(line)
|
||||||
|
|
||||||
if line or not initial_newline:
|
if line or not initial_newline:
|
||||||
self._data.append('\n')
|
self._data.append("\n")
|
||||||
|
|
||||||
initial_newline = False
|
initial_newline = False
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
if not args:
|
if not args:
|
||||||
self._data.append('\n')
|
self._data.append("\n")
|
||||||
return
|
return
|
||||||
|
|
||||||
format = args[0]
|
format = args[0]
|
||||||
@@ -254,51 +266,56 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
|||||||
frame = inspect.currentframe().f_back
|
frame = inspect.currentframe().f_back
|
||||||
|
|
||||||
l = lookup(self, frame, *args, **kwargs)
|
l = lookup(self, frame, *args, **kwargs)
|
||||||
|
|
||||||
def convert(match):
|
def convert(match):
|
||||||
ident = match.group('lone')
|
ident = match.group("lone")
|
||||||
# check for a lone identifier
|
# check for a lone identifier
|
||||||
if ident:
|
if ident:
|
||||||
indent = match.group('indent') # must be spaces
|
indent = match.group("indent") # must be spaces
|
||||||
lone = '%s' % (l[ident], )
|
lone = "%s" % (l[ident],)
|
||||||
|
|
||||||
def indent_lines(gen):
|
def indent_lines(gen):
|
||||||
for line in gen:
|
for line in gen:
|
||||||
yield indent
|
yield indent
|
||||||
yield line
|
yield line
|
||||||
return ''.join(indent_lines(lone.splitlines(True)))
|
|
||||||
|
return "".join(indent_lines(lone.splitlines(True)))
|
||||||
|
|
||||||
# check for an identifier, braced or not
|
# check for an identifier, braced or not
|
||||||
ident = match.group('ident') or match.group('b_ident')
|
ident = match.group("ident") or match.group("b_ident")
|
||||||
if ident is not None:
|
if ident is not None:
|
||||||
return '%s' % (l[ident], )
|
return "%s" % (l[ident],)
|
||||||
|
|
||||||
# check for a positional parameter, braced or not
|
# check for a positional parameter, braced or not
|
||||||
pos = match.group('pos') or match.group('b_pos')
|
pos = match.group("pos") or match.group("b_pos")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos = int(pos)
|
pos = int(pos)
|
||||||
if pos > len(args):
|
if pos > len(args):
|
||||||
raise ValueError \
|
raise ValueError(
|
||||||
('Positional parameter #%d not found in pattern' % pos,
|
"Positional parameter #%d not found in pattern" % pos,
|
||||||
code_formatter.pattern)
|
code_formatter.pattern,
|
||||||
return '%s' % (args[int(pos)], )
|
)
|
||||||
|
return "%s" % (args[int(pos)],)
|
||||||
|
|
||||||
# check for a double braced expression
|
# check for a double braced expression
|
||||||
eval_expr = match.group('eval')
|
eval_expr = match.group("eval")
|
||||||
if eval_expr is not None:
|
if eval_expr is not None:
|
||||||
result = eval(eval_expr, {}, l)
|
result = eval(eval_expr, {}, l)
|
||||||
return '%s' % (result, )
|
return "%s" % (result,)
|
||||||
|
|
||||||
# check for an escaped delimiter
|
# check for an escaped delimiter
|
||||||
if match.group('escaped') is not None:
|
if match.group("escaped") is not None:
|
||||||
return '$'
|
return "$"
|
||||||
|
|
||||||
# At this point, we have to match invalid
|
# At this point, we have to match invalid
|
||||||
if match.group('invalid') is None:
|
if match.group("invalid") is None:
|
||||||
# didn't match invalid!
|
# didn't match invalid!
|
||||||
raise ValueError('Unrecognized named group in pattern',
|
raise ValueError(
|
||||||
code_formatter.pattern)
|
"Unrecognized named group in pattern",
|
||||||
|
code_formatter.pattern,
|
||||||
|
)
|
||||||
|
|
||||||
i = match.start('invalid')
|
i = match.start("invalid")
|
||||||
if i == 0:
|
if i == 0:
|
||||||
colno = 1
|
colno = 1
|
||||||
lineno = 1
|
lineno = 1
|
||||||
@@ -307,52 +324,64 @@ class code_formatter(object, metaclass=code_formatter_meta):
|
|||||||
colno = i - sum(len(z) for z in lines)
|
colno = i - sum(len(z) for z in lines)
|
||||||
lineno = len(lines)
|
lineno = len(lines)
|
||||||
|
|
||||||
raise ValueError('Invalid format string: line %d, col %d' %
|
raise ValueError(
|
||||||
(lineno, colno))
|
"Invalid format string: line %d, col %d" % (lineno, colno)
|
||||||
|
)
|
||||||
|
|
||||||
d = code_formatter.pattern.sub(convert, format)
|
d = code_formatter.pattern.sub(convert, format)
|
||||||
self._append(d)
|
self._append(d)
|
||||||
|
|
||||||
__all__ = [ "code_formatter" ]
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
__all__ = ["code_formatter"]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
from .code_formatter import code_formatter
|
from .code_formatter import code_formatter
|
||||||
|
|
||||||
f = code_formatter()
|
f = code_formatter()
|
||||||
|
|
||||||
class Foo(dict):
|
class Foo(dict):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.update(kwargs)
|
self.update(kwargs)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
return self[attr]
|
return self[attr]
|
||||||
|
|
||||||
x = "this is a test"
|
x = "this is a test"
|
||||||
l = [ [Foo(x=[Foo(y=9)])] ]
|
l = [[Foo(x=[Foo(y=9)])]]
|
||||||
|
|
||||||
y = code_formatter()
|
y = code_formatter()
|
||||||
y('''
|
y(
|
||||||
|
"""
|
||||||
{
|
{
|
||||||
this_is_a_test();
|
this_is_a_test();
|
||||||
}
|
}
|
||||||
''')
|
"""
|
||||||
f(' $y')
|
)
|
||||||
f('''$__file__:$__line__
|
f(" $y")
|
||||||
{''')
|
f(
|
||||||
|
"""$__file__:$__line__
|
||||||
|
{"""
|
||||||
|
)
|
||||||
f("${{', '.join(str(x) for x in range(4))}}")
|
f("${{', '.join(str(x) for x in range(4))}}")
|
||||||
f('${x}')
|
f("${x}")
|
||||||
f('$x')
|
f("$x")
|
||||||
f.indent()
|
f.indent()
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
f('$x')
|
f("$x")
|
||||||
f('$i')
|
f("$i")
|
||||||
f('$0', "zero")
|
f("$0", "zero")
|
||||||
f('$1 $0', "zero", "one")
|
f("$1 $0", "zero", "one")
|
||||||
f('${0}', "he went")
|
f("${0}", "he went")
|
||||||
f('${0}asdf', "he went")
|
f("${0}asdf", "he went")
|
||||||
f.dedent()
|
f.dedent()
|
||||||
|
|
||||||
f('''
|
f(
|
||||||
|
"""
|
||||||
${{l[0][0]["x"][0].y}}
|
${{l[0][0]["x"][0].y}}
|
||||||
}
|
}
|
||||||
''', 1, 9)
|
""",
|
||||||
|
1,
|
||||||
|
9,
|
||||||
|
)
|
||||||
|
|
||||||
print(f, end=' ')
|
print(f, end=" ")
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||||
parser.add_argument('cxx_config_cc', help='cxx config cc file to generate')
|
parser.add_argument("cxx_config_cc", help="cxx config cc file to generate")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -63,22 +63,25 @@ import m5.params
|
|||||||
|
|
||||||
code = code_formatter()
|
code = code_formatter()
|
||||||
|
|
||||||
entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
|
entry_class = "CxxConfigDirectoryEntry_%s" % sim_object_name
|
||||||
param_class = '%sCxxConfigParams' % sim_object_name
|
param_class = "%sCxxConfigParams" % sim_object_name
|
||||||
|
|
||||||
|
|
||||||
def cxx_bool(b):
|
def cxx_bool(b):
|
||||||
return 'true' if b else 'false'
|
return "true" if b else "false"
|
||||||
|
|
||||||
|
|
||||||
code('#include "params/%s.hh"' % sim_object_name)
|
code('#include "params/%s.hh"' % sim_object_name)
|
||||||
|
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
if isSimObjectClass(param.ptype):
|
if isSimObjectClass(param.ptype):
|
||||||
code('#include "%s"' % param.ptype._value_dict['cxx_header'])
|
code('#include "%s"' % param.ptype._value_dict["cxx_header"])
|
||||||
code('#include "params/%s.hh"' % param.ptype.__name__)
|
code('#include "params/%s.hh"' % param.ptype.__name__)
|
||||||
else:
|
else:
|
||||||
param.ptype.cxx_ini_predecls(code)
|
param.ptype.cxx_ini_predecls(code)
|
||||||
|
|
||||||
code('''#include "${{sim_object._value_dict['cxx_header']}}"
|
code(
|
||||||
|
"""#include "${{sim_object._value_dict['cxx_header']}}"
|
||||||
#include "base/str.hh"
|
#include "base/str.hh"
|
||||||
#include "cxx_config/${sim_object_name}.hh"
|
#include "cxx_config/${sim_object_name}.hh"
|
||||||
|
|
||||||
@@ -87,34 +90,39 @@ namespace gem5
|
|||||||
|
|
||||||
${param_class}::DirectoryEntry::DirectoryEntry()
|
${param_class}::DirectoryEntry::DirectoryEntry()
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
code.indent()
|
code.indent()
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
is_vector = isinstance(param, m5.params.VectorParamDesc)
|
is_vector = isinstance(param, m5.params.VectorParamDesc)
|
||||||
is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
|
is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
|
||||||
|
|
||||||
code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
|
code(
|
||||||
(param.name, param.name, cxx_bool(is_vector),
|
'parameters["%s"] = new ParamDesc("%s", %s, %s);'
|
||||||
cxx_bool(is_simobj)));
|
% (param.name, param.name, cxx_bool(is_vector), cxx_bool(is_simobj))
|
||||||
|
)
|
||||||
|
|
||||||
for port in sim_object._ports.values():
|
for port in sim_object._ports.values():
|
||||||
is_vector = isinstance(port, m5.params.VectorPort)
|
is_vector = isinstance(port, m5.params.VectorPort)
|
||||||
is_requestor = port.role == 'GEM5 REQUESTOR'
|
is_requestor = port.role == "GEM5 REQUESTOR"
|
||||||
|
|
||||||
code('ports["%s"] = new PortDesc("%s", %s, %s);' %
|
code(
|
||||||
(port.name, port.name, cxx_bool(is_vector),
|
'ports["%s"] = new PortDesc("%s", %s, %s);'
|
||||||
cxx_bool(is_requestor)))
|
% (port.name, port.name, cxx_bool(is_vector), cxx_bool(is_requestor))
|
||||||
|
)
|
||||||
|
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''}
|
code(
|
||||||
|
"""}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
${param_class}::setSimObject(const std::string &name, SimObject *simObject)
|
${param_class}::setSimObject(const std::string &name, SimObject *simObject)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
if (false) {
|
if (false) {
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
@@ -124,14 +132,17 @@ for param in sim_object._params.values():
|
|||||||
if is_simobj and not is_vector:
|
if is_simobj and not is_vector:
|
||||||
code('} else if (name == "${{param.name}}") {')
|
code('} else if (name == "${{param.name}}") {')
|
||||||
code.indent()
|
code.indent()
|
||||||
code('this->${{param.name}} = '
|
code(
|
||||||
'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
|
"this->${{param.name}} = "
|
||||||
code('if (simObject && !this->${{param.name}})')
|
"dynamic_cast<${{param.ptype.cxx_type}}>(simObject);"
|
||||||
code(' ret = false;')
|
)
|
||||||
|
code("if (simObject && !this->${{param.name}})")
|
||||||
|
code(" ret = false;")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -146,7 +157,8 @@ ${param_class}::setSimObjectVector(const std::string &name,
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
@@ -156,23 +168,28 @@ for param in sim_object._params.values():
|
|||||||
if is_simobj and is_vector:
|
if is_simobj and is_vector:
|
||||||
code('} else if (name == "${{param.name}}") {')
|
code('} else if (name == "${{param.name}}") {')
|
||||||
code.indent()
|
code.indent()
|
||||||
code('this->${{param.name}}.clear();')
|
code("this->${{param.name}}.clear();")
|
||||||
code('for (auto i = simObjects.begin(); '
|
code(
|
||||||
'ret && i != simObjects.end(); i ++)')
|
"for (auto i = simObjects.begin(); "
|
||||||
code('{')
|
"ret && i != simObjects.end(); i ++)"
|
||||||
|
)
|
||||||
|
code("{")
|
||||||
code.indent()
|
code.indent()
|
||||||
code('${{param.ptype.cxx_type}} object = '
|
code(
|
||||||
'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
|
"${{param.ptype.cxx_type}} object = "
|
||||||
code('if (*i && !object)')
|
"dynamic_cast<${{param.ptype.cxx_type}}>(*i);"
|
||||||
code(' ret = false;')
|
)
|
||||||
code('else')
|
code("if (*i && !object)")
|
||||||
code(' this->${{param.name}}.push_back(object);')
|
code(" ret = false;")
|
||||||
|
code("else")
|
||||||
|
code(" this->${{param.name}}.push_back(object);")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('}')
|
code("}")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -193,7 +210,8 @@ ${param_class}::setParam(const std::string &name,
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
@@ -203,12 +221,14 @@ for param in sim_object._params.values():
|
|||||||
if not is_simobj and not is_vector:
|
if not is_simobj and not is_vector:
|
||||||
code('} else if (name == "${{param.name}}") {')
|
code('} else if (name == "${{param.name}}") {')
|
||||||
code.indent()
|
code.indent()
|
||||||
param.ptype.cxx_ini_parse(code,
|
param.ptype.cxx_ini_parse(
|
||||||
'value', 'this->%s' % param.name, 'ret =')
|
code, "value", "this->%s" % param.name, "ret ="
|
||||||
|
)
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -223,7 +243,8 @@ ${param_class}::setParamVector(const std::string &name,
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
for param in sim_object._params.values():
|
for param in sim_object._params.values():
|
||||||
@@ -233,22 +254,23 @@ for param in sim_object._params.values():
|
|||||||
if not is_simobj and is_vector:
|
if not is_simobj and is_vector:
|
||||||
code('} else if (name == "${{param.name}}") {')
|
code('} else if (name == "${{param.name}}") {')
|
||||||
code.indent()
|
code.indent()
|
||||||
code('${{param.name}}.clear();')
|
code("${{param.name}}.clear();")
|
||||||
code('for (auto i = values.begin(); '
|
code(
|
||||||
'ret && i != values.end(); i ++)')
|
"for (auto i = values.begin(); " "ret && i != values.end(); i ++)"
|
||||||
code('{')
|
)
|
||||||
|
code("{")
|
||||||
code.indent()
|
code.indent()
|
||||||
code('${{param.ptype.cxx_type}} elem;')
|
code("${{param.ptype.cxx_type}} elem;")
|
||||||
param.ptype.cxx_ini_parse(code,
|
param.ptype.cxx_ini_parse(code, "*i", "elem", "ret =")
|
||||||
'*i', 'elem', 'ret =')
|
code("if (ret)")
|
||||||
code('if (ret)')
|
code(" this->${{param.name}}.push_back(elem);")
|
||||||
code(' this->${{param.name}}.push_back(elem);')
|
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('}')
|
code("}")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -263,15 +285,17 @@ ${param_class}::setPortConnectionCount(const std::string &name,
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
for port in sim_object._ports.values():
|
for port in sim_object._ports.values():
|
||||||
code('} else if (name == "${{port.name}}") {')
|
code('} else if (name == "${{port.name}}") {')
|
||||||
code(' this->port_${{port.name}}_connection_count = count;')
|
code(" this->port_${{port.name}}_connection_count = count;")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -282,18 +306,21 @@ code('''
|
|||||||
SimObject *
|
SimObject *
|
||||||
${param_class}::simObjectCreate()
|
${param_class}::simObjectCreate()
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
if hasattr(sim_object, 'abstract') and sim_object.abstract:
|
if hasattr(sim_object, "abstract") and sim_object.abstract:
|
||||||
code('return nullptr;')
|
code("return nullptr;")
|
||||||
else:
|
else:
|
||||||
code('return this->create();')
|
code("return this->create();")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('''}
|
code(
|
||||||
|
"""}
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(args.cxx_config_cc)
|
code.write(args.cxx_config_cc)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||||
parser.add_argument('cxx_config_hh', help='cxx config header file to generate')
|
parser.add_argument("cxx_config_hh", help="cxx config header file to generate")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -60,10 +60,11 @@ sim_object = getattr(module, sim_object_name)
|
|||||||
|
|
||||||
code = code_formatter()
|
code = code_formatter()
|
||||||
|
|
||||||
entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
|
entry_class = "CxxConfigDirectoryEntry_%s" % sim_object_name
|
||||||
param_class = '%sCxxConfigParams' % sim_object_name
|
param_class = "%sCxxConfigParams" % sim_object_name
|
||||||
|
|
||||||
code('''#include "params/${sim_object_name}.hh"
|
code(
|
||||||
|
"""#include "params/${sim_object_name}.hh"
|
||||||
|
|
||||||
#include "sim/cxx_config.hh"
|
#include "sim/cxx_config.hh"
|
||||||
|
|
||||||
@@ -110,6 +111,7 @@ class ${param_class} : public CxxConfigParams, public ${sim_object_name}Params
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(args.cxx_config_hh)
|
code.write(args.cxx_config_hh)
|
||||||
|
|||||||
@@ -44,35 +44,41 @@ parser = argparse.ArgumentParser()
|
|||||||
parser.add_argument("hh", help="the path of the debug flag header file")
|
parser.add_argument("hh", help="the path of the debug flag header file")
|
||||||
parser.add_argument("name", help="the name of the debug flag")
|
parser.add_argument("name", help="the name of the debug flag")
|
||||||
parser.add_argument("desc", help="a description of the debug flag")
|
parser.add_argument("desc", help="a description of the debug flag")
|
||||||
parser.add_argument("fmt",
|
parser.add_argument(
|
||||||
help="whether the flag is a format flag (True or False)")
|
"fmt", help="whether the flag is a format flag (True or False)"
|
||||||
parser.add_argument("components",
|
)
|
||||||
help="components of a compound flag, if applicable, joined with :")
|
parser.add_argument(
|
||||||
|
"components",
|
||||||
|
help="components of a compound flag, if applicable, joined with :",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
fmt = args.fmt.lower()
|
fmt = args.fmt.lower()
|
||||||
if fmt == 'true':
|
if fmt == "true":
|
||||||
fmt = True
|
fmt = True
|
||||||
elif fmt == 'false':
|
elif fmt == "false":
|
||||||
fmt = False
|
fmt = False
|
||||||
else:
|
else:
|
||||||
print(f'Unrecognized "FMT" value {fmt}', file=sys.stderr)
|
print(f'Unrecognized "FMT" value {fmt}', file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
components = args.components.split(':') if args.components else []
|
components = args.components.split(":") if args.components else []
|
||||||
|
|
||||||
code = code_formatter()
|
code = code_formatter()
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
#ifndef __DEBUG_${{args.name}}_HH__
|
#ifndef __DEBUG_${{args.name}}_HH__
|
||||||
#define __DEBUG_${{args.name}}_HH__
|
#define __DEBUG_${{args.name}}_HH__
|
||||||
|
|
||||||
#include "base/compiler.hh" // For namespace deprecation
|
#include "base/compiler.hh" // For namespace deprecation
|
||||||
#include "base/debug.hh"
|
#include "base/debug.hh"
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
for flag in components:
|
for flag in components:
|
||||||
code('#include "debug/${flag}.hh"')
|
code('#include "debug/${flag}.hh"')
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -82,14 +88,16 @@ namespace debug
|
|||||||
|
|
||||||
namespace unions
|
namespace unions
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
# Use unions to prevent debug flags from being destructed. It's the
|
# Use unions to prevent debug flags from being destructed. It's the
|
||||||
# responsibility of the programmer to handle object destruction for members
|
# responsibility of the programmer to handle object destruction for members
|
||||||
# of the union. We purposefully leave that destructor empty so that we can
|
# of the union. We purposefully leave that destructor empty so that we can
|
||||||
# use debug flags even in the destructors of other objects.
|
# use debug flags even in the destructors of other objects.
|
||||||
if components:
|
if components:
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
inline union ${{args.name}}
|
inline union ${{args.name}}
|
||||||
{
|
{
|
||||||
~${{args.name}}() {}
|
~${{args.name}}() {}
|
||||||
@@ -100,9 +108,11 @@ inline union ${{args.name}}
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
} ${{args.name}};
|
} ${{args.name}};
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
inline union ${{args.name}}
|
inline union ${{args.name}}
|
||||||
{
|
{
|
||||||
~${{args.name}}() {}
|
~${{args.name}}() {}
|
||||||
@@ -110,18 +120,21 @@ inline union ${{args.name}}
|
|||||||
"${{args.name}}", "${{args.desc}}", ${{"true" if fmt else "false"}}
|
"${{args.name}}", "${{args.desc}}", ${{"true" if fmt else "false"}}
|
||||||
};
|
};
|
||||||
} ${{args.name}};
|
} ${{args.name}};
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
} // namespace unions
|
} // namespace unions
|
||||||
|
|
||||||
inline constexpr const auto& ${{args.name}} =
|
inline constexpr const auto& ${{args.name}} =
|
||||||
::gem5::debug::unions::${{args.name}}.${{args.name}};
|
::gem5::debug::unions::${{args.name}}.${{args.name}};
|
||||||
|
|
||||||
} // namespace debug
|
} // namespace debug
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
#endif // __DEBUG_${{args.name}}_HH__
|
#endif // __DEBUG_${{args.name}}_HH__
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(args.hh)
|
code.write(args.hh)
|
||||||
|
|||||||
@@ -46,17 +46,18 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the enum belongs to')
|
parser.add_argument("modpath", help="module the enum belongs to")
|
||||||
parser.add_argument('enum_cc', help='enum cc file to generate')
|
parser.add_argument("enum_cc", help="enum cc file to generate")
|
||||||
parser.add_argument('use_python',
|
parser.add_argument(
|
||||||
help='whether python is enabled in gem5 (True or False)')
|
"use_python", help="whether python is enabled in gem5 (True or False)"
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
use_python = args.use_python.lower()
|
use_python = args.use_python.lower()
|
||||||
if use_python == 'true':
|
if use_python == "true":
|
||||||
use_python = True
|
use_python = True
|
||||||
elif use_python == 'false':
|
elif use_python == "false":
|
||||||
use_python = False
|
use_python = False
|
||||||
else:
|
else:
|
||||||
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
||||||
@@ -75,41 +76,46 @@ wrapper_name = enum.wrapper_name
|
|||||||
file_name = enum.__name__
|
file_name = enum.__name__
|
||||||
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||||
|
|
||||||
code('''#include "base/compiler.hh"
|
code(
|
||||||
|
"""#include "base/compiler.hh"
|
||||||
#include "enums/$file_name.hh"
|
#include "enums/$file_name.hh"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
if enum.wrapper_is_struct:
|
if enum.wrapper_is_struct:
|
||||||
code('const char *${wrapper_name}::${name}Strings'
|
code("const char *${wrapper_name}::${name}Strings" "[Num_${name}] =")
|
||||||
'[Num_${name}] =')
|
|
||||||
else:
|
else:
|
||||||
if enum.is_class:
|
if enum.is_class:
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
const char *${name}Strings[static_cast<int>(${name}::Num_${name})] =
|
const char *${name}Strings[static_cast<int>(${name}::Num_${name})] =
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('''GEM5_DEPRECATED_NAMESPACE(Enums, enums);
|
code(
|
||||||
|
"""GEM5_DEPRECATED_NAMESPACE(Enums, enums);
|
||||||
namespace enums
|
namespace enums
|
||||||
{''')
|
{"""
|
||||||
|
)
|
||||||
code.indent(1)
|
code.indent(1)
|
||||||
code('const char *${name}Strings[Num_${name}] =')
|
code("const char *${name}Strings[Num_${name}] =")
|
||||||
|
|
||||||
code('{')
|
code("{")
|
||||||
code.indent(1)
|
code.indent(1)
|
||||||
for val in enum.vals:
|
for val in enum.vals:
|
||||||
code('"$val",')
|
code('"$val",')
|
||||||
code.dedent(1)
|
code.dedent(1)
|
||||||
code('};')
|
code("};")
|
||||||
|
|
||||||
if not enum.wrapper_is_struct and not enum.is_class:
|
if not enum.wrapper_is_struct and not enum.is_class:
|
||||||
code.dedent(1)
|
code.dedent(1)
|
||||||
code('} // namespace enums')
|
code("} // namespace enums")
|
||||||
|
|
||||||
code('} // namespace gem5')
|
code("} // namespace gem5")
|
||||||
|
|
||||||
|
|
||||||
if use_python:
|
if use_python:
|
||||||
@@ -118,7 +124,8 @@ if use_python:
|
|||||||
enum_name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
enum_name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||||
wrapper_name = enum_name if enum.is_class else enum.wrapper_name
|
wrapper_name = enum_name if enum.is_class else enum.wrapper_name
|
||||||
|
|
||||||
code('''#include "pybind11/pybind11.h"
|
code(
|
||||||
|
"""#include "pybind11/pybind11.h"
|
||||||
#include "pybind11/stl.h"
|
#include "pybind11/stl.h"
|
||||||
|
|
||||||
#include <sim/init.hh>
|
#include <sim/init.hh>
|
||||||
@@ -133,7 +140,8 @@ module_init(py::module_ &m_internal)
|
|||||||
{
|
{
|
||||||
py::module_ m = m_internal.def_submodule("enum_${name}");
|
py::module_ m = m_internal.def_submodule("enum_${name}");
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
if enum.is_class:
|
if enum.is_class:
|
||||||
code('py::enum_<${enum_name}>(m, "enum_${name}")')
|
code('py::enum_<${enum_name}>(m, "enum_${name}")')
|
||||||
else:
|
else:
|
||||||
@@ -145,16 +153,18 @@ module_init(py::module_ &m_internal)
|
|||||||
code('.value("${val}", ${wrapper_name}::${val})')
|
code('.value("${val}", ${wrapper_name}::${val})')
|
||||||
code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})')
|
code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})')
|
||||||
if not enum.is_class:
|
if not enum.is_class:
|
||||||
code('.export_values()')
|
code(".export_values()")
|
||||||
code(';')
|
code(";")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
code('}')
|
code("}")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
static EmbeddedPyBind embed_enum("enum_${name}", module_init);
|
static EmbeddedPyBind embed_enum("enum_${name}", module_init);
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(args.enum_cc)
|
code.write(args.enum_cc)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the enum belongs to')
|
parser.add_argument("modpath", help="module the enum belongs to")
|
||||||
parser.add_argument('enum_hh', help='enum header file to generate')
|
parser.add_argument("enum_hh", help="enum header file to generate")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -64,53 +64,61 @@ code = code_formatter()
|
|||||||
# Note that we wrap the enum in a class/struct to act as a namespace,
|
# Note that we wrap the enum in a class/struct to act as a namespace,
|
||||||
# so that the enum strings can be brief w/o worrying about collisions.
|
# so that the enum strings can be brief w/o worrying about collisions.
|
||||||
wrapper_name = enum.wrapper_name
|
wrapper_name = enum.wrapper_name
|
||||||
wrapper = 'struct' if enum.wrapper_is_struct else 'namespace'
|
wrapper = "struct" if enum.wrapper_is_struct else "namespace"
|
||||||
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
name = enum.__name__ if enum.enum_name is None else enum.enum_name
|
||||||
idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name)
|
idem_macro = "__ENUM__%s__%s__" % (wrapper_name, name)
|
||||||
|
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
#ifndef $idem_macro
|
#ifndef $idem_macro
|
||||||
#define $idem_macro
|
#define $idem_macro
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
if enum.is_class:
|
if enum.is_class:
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
enum class $name
|
enum class $name
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
$wrapper $wrapper_name {
|
$wrapper $wrapper_name {
|
||||||
enum $name
|
enum $name
|
||||||
{
|
{
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
code.indent(1)
|
code.indent(1)
|
||||||
code.indent(1)
|
code.indent(1)
|
||||||
for val in enum.vals:
|
for val in enum.vals:
|
||||||
code('$val = ${{enum.map[val]}},')
|
code("$val = ${{enum.map[val]}},")
|
||||||
code('Num_$name = ${{len(enum.vals)}}')
|
code("Num_$name = ${{len(enum.vals)}}")
|
||||||
code.dedent(1)
|
code.dedent(1)
|
||||||
code('};')
|
code("};")
|
||||||
|
|
||||||
if enum.is_class:
|
if enum.is_class:
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
extern const char *${name}Strings[static_cast<int>(${name}::Num_${name})];
|
extern const char *${name}Strings[static_cast<int>(${name}::Num_${name})];
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
elif enum.wrapper_is_struct:
|
elif enum.wrapper_is_struct:
|
||||||
code('static const char *${name}Strings[Num_${name}];')
|
code("static const char *${name}Strings[Num_${name}];")
|
||||||
else:
|
else:
|
||||||
code('extern const char *${name}Strings[Num_${name}];')
|
code("extern const char *${name}Strings[Num_${name}];")
|
||||||
|
|
||||||
if not enum.is_class:
|
if not enum.is_class:
|
||||||
code.dedent(1)
|
code.dedent(1)
|
||||||
code('}; // $wrapper_name')
|
code("}; // $wrapper_name")
|
||||||
|
|
||||||
code()
|
code()
|
||||||
code('} // namespace gem5')
|
code("} // namespace gem5")
|
||||||
|
|
||||||
code()
|
code()
|
||||||
code('#endif // $idem_macro')
|
code("#endif // $idem_macro")
|
||||||
|
|
||||||
code.write(args.enum_hh)
|
code.write(args.enum_hh)
|
||||||
|
|||||||
@@ -29,73 +29,77 @@ import os
|
|||||||
import ply.lex
|
import ply.lex
|
||||||
import ply.yacc
|
import ply.yacc
|
||||||
|
|
||||||
|
|
||||||
class ParseError(Exception):
|
class ParseError(Exception):
|
||||||
def __init__(self, message, token=None):
|
def __init__(self, message, token=None):
|
||||||
Exception.__init__(self, message)
|
Exception.__init__(self, message)
|
||||||
self.token = token
|
self.token = token
|
||||||
|
|
||||||
|
|
||||||
class Grammar(object):
|
class Grammar(object):
|
||||||
def setupLexerFactory(self, **kwargs):
|
def setupLexerFactory(self, **kwargs):
|
||||||
if 'module' in kwargs:
|
if "module" in kwargs:
|
||||||
raise AttributeError("module is an illegal attribute")
|
raise AttributeError("module is an illegal attribute")
|
||||||
self.lex_kwargs = kwargs
|
self.lex_kwargs = kwargs
|
||||||
|
|
||||||
def setupParserFactory(self, **kwargs):
|
def setupParserFactory(self, **kwargs):
|
||||||
if 'module' in kwargs:
|
if "module" in kwargs:
|
||||||
raise AttributeError("module is an illegal attribute")
|
raise AttributeError("module is an illegal attribute")
|
||||||
|
|
||||||
if 'output' in kwargs:
|
if "output" in kwargs:
|
||||||
dir,tab = os.path.split(output)
|
dir, tab = os.path.split(output)
|
||||||
if not tab.endswith('.py'):
|
if not tab.endswith(".py"):
|
||||||
raise AttributeError('The output file must end with .py')
|
raise AttributeError("The output file must end with .py")
|
||||||
kwargs['outputdir'] = dir
|
kwargs["outputdir"] = dir
|
||||||
kwargs['tabmodule'] = tab[:-3]
|
kwargs["tabmodule"] = tab[:-3]
|
||||||
|
|
||||||
self.yacc_kwargs = kwargs
|
self.yacc_kwargs = kwargs
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr == 'lexers':
|
if attr == "lexers":
|
||||||
self.lexers = []
|
self.lexers = []
|
||||||
return self.lexers
|
return self.lexers
|
||||||
|
|
||||||
if attr == 'lex_kwargs':
|
if attr == "lex_kwargs":
|
||||||
self.setupLexerFactory()
|
self.setupLexerFactory()
|
||||||
return self.lex_kwargs
|
return self.lex_kwargs
|
||||||
|
|
||||||
if attr == 'yacc_kwargs':
|
if attr == "yacc_kwargs":
|
||||||
self.setupParserFactory()
|
self.setupParserFactory()
|
||||||
return self.yacc_kwargs
|
return self.yacc_kwargs
|
||||||
|
|
||||||
if attr == 'lex':
|
if attr == "lex":
|
||||||
self.lex = ply.lex.lex(module=self, **self.lex_kwargs)
|
self.lex = ply.lex.lex(module=self, **self.lex_kwargs)
|
||||||
return self.lex
|
return self.lex
|
||||||
|
|
||||||
if attr == 'yacc':
|
if attr == "yacc":
|
||||||
self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs)
|
self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs)
|
||||||
return self.yacc
|
return self.yacc
|
||||||
|
|
||||||
if attr == 'current_lexer':
|
if attr == "current_lexer":
|
||||||
if not self.lexers:
|
if not self.lexers:
|
||||||
return None
|
return None
|
||||||
return self.lexers[-1][0]
|
return self.lexers[-1][0]
|
||||||
|
|
||||||
if attr == 'current_source':
|
if attr == "current_source":
|
||||||
if not self.lexers:
|
if not self.lexers:
|
||||||
return '<none>'
|
return "<none>"
|
||||||
return self.lexers[-1][1]
|
return self.lexers[-1][1]
|
||||||
|
|
||||||
if attr == 'current_line':
|
if attr == "current_line":
|
||||||
if not self.lexers:
|
if not self.lexers:
|
||||||
return -1
|
return -1
|
||||||
return self.current_lexer.lineno
|
return self.current_lexer.lineno
|
||||||
|
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
"'%s' object has no attribute '%s'" % (type(self), attr))
|
"'%s' object has no attribute '%s'" % (type(self), attr)
|
||||||
|
)
|
||||||
|
|
||||||
def parse_string(self, data, source='<string>', debug=None, tracking=0):
|
def parse_string(self, data, source="<string>", debug=None, tracking=0):
|
||||||
if not isinstance(data, str):
|
if not isinstance(data, str):
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
"argument must be a string, was '%s'" % type(f))
|
"argument must be a string, was '%s'" % type(f)
|
||||||
|
)
|
||||||
|
|
||||||
lexer = self.lex.clone()
|
lexer = self.lex.clone()
|
||||||
lexer.input(data)
|
lexer.input(data)
|
||||||
@@ -114,24 +118,32 @@ class Grammar(object):
|
|||||||
def parse_file(self, f, **kwargs):
|
def parse_file(self, f, **kwargs):
|
||||||
if isinstance(f, str):
|
if isinstance(f, str):
|
||||||
source = f
|
source = f
|
||||||
f = open(f, 'r')
|
f = open(f, "r")
|
||||||
elif isinstance(f, file):
|
elif isinstance(f, file):
|
||||||
source = f.name
|
source = f.name
|
||||||
else:
|
else:
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
"argument must be either a string or file, was '%s'" % type(f))
|
"argument must be either a string or file, was '%s'" % type(f)
|
||||||
|
)
|
||||||
|
|
||||||
return self.parse_string(f.read(), source, **kwargs)
|
return self.parse_string(f.read(), source, **kwargs)
|
||||||
|
|
||||||
def p_error(self, t):
|
def p_error(self, t):
|
||||||
if t:
|
if t:
|
||||||
msg = "Syntax error at %s:%d:%d\n>>%s<<" % \
|
msg = "Syntax error at %s:%d:%d\n>>%s<<" % (
|
||||||
(self.current_source, t.lineno, t.lexpos + 1, t.value)
|
self.current_source,
|
||||||
|
t.lineno,
|
||||||
|
t.lexpos + 1,
|
||||||
|
t.value,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
msg = "Syntax error at end of %s" % (self.current_source, )
|
msg = "Syntax error at end of %s" % (self.current_source,)
|
||||||
raise ParseError(msg, t)
|
raise ParseError(msg, t)
|
||||||
|
|
||||||
def t_error(self, t):
|
def t_error(self, t):
|
||||||
msg = "Illegal character %s @ %d:%d" % \
|
msg = "Illegal character %s @ %d:%d" % (
|
||||||
(repr(t.value[0]), t.lineno, t.lexpos)
|
repr(t.value[0]),
|
||||||
|
t.lineno,
|
||||||
|
t.lexpos,
|
||||||
|
)
|
||||||
raise ParseError(msg, t)
|
raise ParseError(msg, t)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ import sys
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('info_py', help='info.py file path')
|
parser.add_argument("info_py", help="info.py file path")
|
||||||
parser.add_argument('files', help='file to include in info.py', nargs='*')
|
parser.add_argument("files", help="file to include in info.py", nargs="*")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ code = code_formatter()
|
|||||||
|
|
||||||
for source in args.files:
|
for source in args.files:
|
||||||
src = os.path.basename(source)
|
src = os.path.basename(source)
|
||||||
with open(source, 'r') as f:
|
with open(source, "r") as f:
|
||||||
data = ''.join(f)
|
data = "".join(f)
|
||||||
code('${src} = ${{repr(data)}}')
|
code("${src} = ${{repr(data)}}")
|
||||||
|
|
||||||
code.write(args.info_py)
|
code.write(args.info_py)
|
||||||
|
|||||||
@@ -67,16 +67,17 @@ if len(sys.argv) < 4:
|
|||||||
|
|
||||||
_, cpp, python, modpath, abspath = sys.argv
|
_, cpp, python, modpath, abspath = sys.argv
|
||||||
|
|
||||||
with open(python, 'r') as f:
|
with open(python, "r") as f:
|
||||||
src = f.read()
|
src = f.read()
|
||||||
|
|
||||||
compiled = compile(src, python, 'exec')
|
compiled = compile(src, python, "exec")
|
||||||
marshalled = marshal.dumps(compiled)
|
marshalled = marshal.dumps(compiled)
|
||||||
|
|
||||||
compressed = zlib.compress(marshalled)
|
compressed = zlib.compress(marshalled)
|
||||||
|
|
||||||
code = code_formatter()
|
code = code_formatter()
|
||||||
code('''\
|
code(
|
||||||
|
"""\
|
||||||
#include "python/embedded.hh"
|
#include "python/embedded.hh"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
@@ -84,14 +85,16 @@ namespace gem5
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
bytesToCppArray(code, 'embedded_module_data', compressed)
|
bytesToCppArray(code, "embedded_module_data", compressed)
|
||||||
|
|
||||||
# The name of the EmbeddedPython object doesn't matter since it's in an
|
# The name of the EmbeddedPython object doesn't matter since it's in an
|
||||||
# anonymous namespace, and it's constructor takes care of installing it into a
|
# anonymous namespace, and it's constructor takes care of installing it into a
|
||||||
# global list.
|
# global list.
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
EmbeddedPython embedded_module_info(
|
EmbeddedPython embedded_module_info(
|
||||||
"${abspath}",
|
"${abspath}",
|
||||||
"${modpath}",
|
"${modpath}",
|
||||||
@@ -101,6 +104,7 @@ EmbeddedPython embedded_module_info(
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(cpp)
|
code.write(cpp)
|
||||||
|
|||||||
@@ -46,17 +46,18 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||||
parser.add_argument('param_cc', help='parameter cc file to generate')
|
parser.add_argument("param_cc", help="parameter cc file to generate")
|
||||||
parser.add_argument('use_python',
|
parser.add_argument(
|
||||||
help='whether python is enabled in gem5 (True or False)')
|
"use_python", help="whether python is enabled in gem5 (True or False)"
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
use_python = args.use_python.lower()
|
use_python = args.use_python.lower()
|
||||||
if use_python == 'true':
|
if use_python == "true":
|
||||||
use_python = True
|
use_python = True
|
||||||
elif use_python == 'false':
|
elif use_python == "false":
|
||||||
use_python = False
|
use_python = False
|
||||||
else:
|
else:
|
||||||
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
print(f'Unrecognized "use_python" value {use_python}', file=sys.stderr)
|
||||||
@@ -64,7 +65,7 @@ else:
|
|||||||
|
|
||||||
basename = os.path.basename(args.param_cc)
|
basename = os.path.basename(args.param_cc)
|
||||||
no_ext = os.path.splitext(basename)[0]
|
no_ext = os.path.splitext(basename)[0]
|
||||||
sim_object_name = '_'.join(no_ext.split('_')[1:])
|
sim_object_name = "_".join(no_ext.split("_")[1:])
|
||||||
|
|
||||||
importer.install()
|
importer.install()
|
||||||
module = importlib.import_module(args.modpath)
|
module = importlib.import_module(args.modpath)
|
||||||
@@ -80,14 +81,16 @@ py_class_name = sim_object.pybind_class
|
|||||||
# the object itself, not including inherited params (which
|
# the object itself, not including inherited params (which
|
||||||
# will also be inherited from the base class's param struct
|
# will also be inherited from the base class's param struct
|
||||||
# here). Sort the params based on their key
|
# here). Sort the params based on their key
|
||||||
params = list(map(lambda k_v: k_v[1],
|
params = list(
|
||||||
sorted(sim_object._params.local.items())))
|
map(lambda k_v: k_v[1], sorted(sim_object._params.local.items()))
|
||||||
|
)
|
||||||
ports = sim_object._ports.local
|
ports = sim_object._ports.local
|
||||||
|
|
||||||
# only include pybind if python is enabled in the build
|
# only include pybind if python is enabled in the build
|
||||||
if use_python:
|
if use_python:
|
||||||
|
|
||||||
code('''#include "pybind11/pybind11.h"
|
code(
|
||||||
|
"""#include "pybind11/pybind11.h"
|
||||||
#include "pybind11/stl.h"
|
#include "pybind11/stl.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -99,9 +102,11 @@ if use_python:
|
|||||||
|
|
||||||
#include "${{sim_object.cxx_header}}"
|
#include "${{sim_object.cxx_header}}"
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "base/compiler.hh"
|
#include "base/compiler.hh"
|
||||||
@@ -109,13 +114,15 @@ else:
|
|||||||
|
|
||||||
#include "${{sim_object.cxx_header}}"
|
#include "${{sim_object.cxx_header}}"
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
# only include the python params code if python is enabled.
|
# only include the python params code if python is enabled.
|
||||||
if use_python:
|
if use_python:
|
||||||
for param in params:
|
for param in params:
|
||||||
param.pybind_predecls(code)
|
param.pybind_predecls(code)
|
||||||
|
|
||||||
code('''namespace py = pybind11;
|
code(
|
||||||
|
"""namespace py = pybind11;
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
@@ -124,39 +131,48 @@ static void
|
|||||||
module_init(py::module_ &m_internal)
|
module_init(py::module_ &m_internal)
|
||||||
{
|
{
|
||||||
py::module_ m = m_internal.def_submodule("param_${sim_object}");
|
py::module_ m = m_internal.def_submodule("param_${sim_object}");
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
code.indent()
|
code.indent()
|
||||||
if sim_object._base:
|
if sim_object._base:
|
||||||
code('py::class_<${sim_object}Params, ' \
|
code(
|
||||||
'${{sim_object._base.type}}Params, ' \
|
"py::class_<${sim_object}Params, "
|
||||||
'std::unique_ptr<${{sim_object}}Params, py::nodelete>>(' \
|
"${{sim_object._base.type}}Params, "
|
||||||
'm, "${sim_object}Params")')
|
"std::unique_ptr<${{sim_object}}Params, py::nodelete>>("
|
||||||
|
'm, "${sim_object}Params")'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('py::class_<${sim_object}Params, ' \
|
code(
|
||||||
'std::unique_ptr<${sim_object}Params, py::nodelete>>(' \
|
"py::class_<${sim_object}Params, "
|
||||||
'm, "${sim_object}Params")')
|
"std::unique_ptr<${sim_object}Params, py::nodelete>>("
|
||||||
|
'm, "${sim_object}Params")'
|
||||||
|
)
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||||
code('.def(py::init<>())')
|
code(".def(py::init<>())")
|
||||||
code('.def("create", &${sim_object}Params::create)')
|
code('.def("create", &${sim_object}Params::create)')
|
||||||
|
|
||||||
param_exports = sim_object.cxx_param_exports + [
|
param_exports = (
|
||||||
PyBindProperty(k)
|
sim_object.cxx_param_exports
|
||||||
for k, v in sorted(sim_object._params.local.items())
|
+ [
|
||||||
] + [
|
PyBindProperty(k)
|
||||||
PyBindProperty(f"port_{port.name}_connection_count")
|
for k, v in sorted(sim_object._params.local.items())
|
||||||
for port in ports.values()
|
]
|
||||||
]
|
+ [
|
||||||
|
PyBindProperty(f"port_{port.name}_connection_count")
|
||||||
|
for port in ports.values()
|
||||||
|
]
|
||||||
|
)
|
||||||
for exp in param_exports:
|
for exp in param_exports:
|
||||||
exp.export(code, f"{sim_object}Params")
|
exp.export(code, f"{sim_object}Params")
|
||||||
|
|
||||||
code(';')
|
code(";")
|
||||||
code()
|
code()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
|
|
||||||
bases = []
|
bases = []
|
||||||
if 'cxx_base' in sim_object._value_dict:
|
if "cxx_base" in sim_object._value_dict:
|
||||||
# If the c++ base class implied by python inheritance was
|
# If the c++ base class implied by python inheritance was
|
||||||
# overridden, use that value.
|
# overridden, use that value.
|
||||||
if sim_object.cxx_base:
|
if sim_object.cxx_base:
|
||||||
@@ -170,32 +186,39 @@ py::module_ m = m_internal.def_submodule("param_${sim_object}");
|
|||||||
|
|
||||||
if bases:
|
if bases:
|
||||||
base_str = ", ".join(bases)
|
base_str = ", ".join(bases)
|
||||||
code('py::class_<${{sim_object.cxx_class}}, ${base_str}, ' \
|
code(
|
||||||
'std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>(' \
|
"py::class_<${{sim_object.cxx_class}}, ${base_str}, "
|
||||||
'm, "${py_class_name}")')
|
"std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>("
|
||||||
|
'm, "${py_class_name}")'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
code('py::class_<${{sim_object.cxx_class}}, ' \
|
code(
|
||||||
'std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>(' \
|
"py::class_<${{sim_object.cxx_class}}, "
|
||||||
'm, "${py_class_name}")')
|
"std::unique_ptr<${{sim_object.cxx_class}}, py::nodelete>>("
|
||||||
|
'm, "${py_class_name}")'
|
||||||
|
)
|
||||||
code.indent()
|
code.indent()
|
||||||
for exp in sim_object.cxx_exports:
|
for exp in sim_object.cxx_exports:
|
||||||
exp.export(code, sim_object.cxx_class)
|
exp.export(code, sim_object.cxx_class)
|
||||||
code(';')
|
code(";")
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code()
|
code()
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('}')
|
code("}")
|
||||||
code()
|
code()
|
||||||
code('static EmbeddedPyBind '
|
code(
|
||||||
'embed_obj("${0}", module_init, "${1}");',
|
"static EmbeddedPyBind " 'embed_obj("${0}", module_init, "${1}");',
|
||||||
sim_object, sim_object._base.type if sim_object._base else "")
|
sim_object,
|
||||||
|
sim_object._base.type if sim_object._base else "",
|
||||||
|
)
|
||||||
code()
|
code()
|
||||||
code('} // namespace gem5')
|
code("} // namespace gem5")
|
||||||
|
|
||||||
# include the create() methods whether or not python is enabled.
|
# include the create() methods whether or not python is enabled.
|
||||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||||
if 'type' in sim_object.__dict__:
|
if "type" in sim_object.__dict__:
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -268,6 +291,7 @@ Dummy${sim_object}Shunt<${{sim_object.cxx_class}}>::Params::create() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
code.write(args.param_cc)
|
code.write(args.param_cc)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import importer
|
|||||||
from code_formatter import code_formatter
|
from code_formatter import code_formatter
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('modpath', help='module the simobject belongs to')
|
parser.add_argument("modpath", help="module the simobject belongs to")
|
||||||
parser.add_argument('param_hh', help='parameter header file to generate')
|
parser.add_argument("param_hh", help="parameter header file to generate")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -67,8 +67,9 @@ code = code_formatter()
|
|||||||
# the object itself, not including inherited params (which
|
# the object itself, not including inherited params (which
|
||||||
# will also be inherited from the base class's param struct
|
# will also be inherited from the base class's param struct
|
||||||
# here). Sort the params based on their key
|
# here). Sort the params based on their key
|
||||||
params = list(map(lambda k_v: k_v[1],
|
params = list(
|
||||||
sorted(sim_object._params.local.items())))
|
map(lambda k_v: k_v[1], sorted(sim_object._params.local.items()))
|
||||||
|
)
|
||||||
ports = sim_object._ports.local
|
ports = sim_object._ports.local
|
||||||
try:
|
try:
|
||||||
ptypes = [p.ptype for p in params]
|
ptypes = [p.ptype for p in params]
|
||||||
@@ -79,41 +80,44 @@ except:
|
|||||||
|
|
||||||
warned_about_nested_templates = False
|
warned_about_nested_templates = False
|
||||||
|
|
||||||
|
|
||||||
class CxxClass(object):
|
class CxxClass(object):
|
||||||
def __init__(self, sig, template_params=[]):
|
def __init__(self, sig, template_params=[]):
|
||||||
# Split the signature into its constituent parts. This could
|
# Split the signature into its constituent parts. This could
|
||||||
# potentially be done with regular expressions, but
|
# potentially be done with regular expressions, but
|
||||||
# it's simple enough to pick appart a class signature
|
# it's simple enough to pick appart a class signature
|
||||||
# manually.
|
# manually.
|
||||||
parts = sig.split('<', 1)
|
parts = sig.split("<", 1)
|
||||||
base = parts[0]
|
base = parts[0]
|
||||||
t_args = []
|
t_args = []
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
# The signature had template arguments.
|
# The signature had template arguments.
|
||||||
text = parts[1].rstrip(' \t\n>')
|
text = parts[1].rstrip(" \t\n>")
|
||||||
arg = ''
|
arg = ""
|
||||||
# Keep track of nesting to avoid splitting on ","s embedded
|
# Keep track of nesting to avoid splitting on ","s embedded
|
||||||
# in the arguments themselves.
|
# in the arguments themselves.
|
||||||
depth = 0
|
depth = 0
|
||||||
for c in text:
|
for c in text:
|
||||||
if c == '<':
|
if c == "<":
|
||||||
depth = depth + 1
|
depth = depth + 1
|
||||||
if depth > 0 and not warned_about_nested_templates:
|
if depth > 0 and not warned_about_nested_templates:
|
||||||
warned_about_nested_templates = True
|
warned_about_nested_templates = True
|
||||||
print('Nested template argument in cxx_class.'
|
print(
|
||||||
' This feature is largely untested and '
|
"Nested template argument in cxx_class."
|
||||||
' may not work.')
|
" This feature is largely untested and "
|
||||||
elif c == '>':
|
" may not work."
|
||||||
|
)
|
||||||
|
elif c == ">":
|
||||||
depth = depth - 1
|
depth = depth - 1
|
||||||
elif c == ',' and depth == 0:
|
elif c == "," and depth == 0:
|
||||||
t_args.append(arg.strip())
|
t_args.append(arg.strip())
|
||||||
arg = ''
|
arg = ""
|
||||||
else:
|
else:
|
||||||
arg = arg + c
|
arg = arg + c
|
||||||
if arg:
|
if arg:
|
||||||
t_args.append(arg.strip())
|
t_args.append(arg.strip())
|
||||||
# Split the non-template part on :: boundaries.
|
# Split the non-template part on :: boundaries.
|
||||||
class_path = base.split('::')
|
class_path = base.split("::")
|
||||||
|
|
||||||
# The namespaces are everything except the last part of the class path.
|
# The namespaces are everything except the last part of the class path.
|
||||||
self.namespaces = class_path[:-1]
|
self.namespaces = class_path[:-1]
|
||||||
@@ -125,7 +129,7 @@ class CxxClass(object):
|
|||||||
# Iterate through the template arguments and their values. This
|
# Iterate through the template arguments and their values. This
|
||||||
# will likely break if parameter packs are used.
|
# will likely break if parameter packs are used.
|
||||||
for arg, param in zip(t_args, template_params):
|
for arg, param in zip(t_args, template_params):
|
||||||
type_keys = ('class', 'typename')
|
type_keys = ("class", "typename")
|
||||||
# If a parameter is a type, parse it recursively. Otherwise
|
# If a parameter is a type, parse it recursively. Otherwise
|
||||||
# assume it's a constant, and store it verbatim.
|
# assume it's a constant, and store it verbatim.
|
||||||
if any(param.strip().startswith(kw) for kw in type_keys):
|
if any(param.strip().startswith(kw) for kw in type_keys):
|
||||||
@@ -140,21 +144,24 @@ class CxxClass(object):
|
|||||||
arg.declare(code)
|
arg.declare(code)
|
||||||
# Re-open the target namespace.
|
# Re-open the target namespace.
|
||||||
for ns in self.namespaces:
|
for ns in self.namespaces:
|
||||||
code('namespace $ns {')
|
code("namespace $ns {")
|
||||||
# If this is a class template...
|
# If this is a class template...
|
||||||
if self.template_params:
|
if self.template_params:
|
||||||
code('template <${{", ".join(self.template_params)}}>')
|
code('template <${{", ".join(self.template_params)}}>')
|
||||||
# The actual class declaration.
|
# The actual class declaration.
|
||||||
code('class ${{self.name}};')
|
code("class ${{self.name}};")
|
||||||
# Close the target namespaces.
|
# Close the target namespaces.
|
||||||
for ns in reversed(self.namespaces):
|
for ns in reversed(self.namespaces):
|
||||||
code('} // namespace $ns')
|
code("} // namespace $ns")
|
||||||
|
|
||||||
code('''\
|
|
||||||
|
code(
|
||||||
|
"""\
|
||||||
#ifndef __PARAMS__${sim_object}__
|
#ifndef __PARAMS__${sim_object}__
|
||||||
#define __PARAMS__${sim_object}__
|
#define __PARAMS__${sim_object}__
|
||||||
|
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# The base SimObject has a couple of params that get
|
# The base SimObject has a couple of params that get
|
||||||
@@ -162,10 +169,12 @@ code('''\
|
|||||||
# the normal Param mechanism; we slip them in here (needed
|
# the normal Param mechanism; we slip them in here (needed
|
||||||
# predecls now, actual declarations below)
|
# predecls now, actual declarations below)
|
||||||
if sim_object == SimObject:
|
if sim_object == SimObject:
|
||||||
code('''#include <string>''')
|
code("""#include <string>""")
|
||||||
|
|
||||||
cxx_class = CxxClass(sim_object._value_dict['cxx_class'],
|
cxx_class = CxxClass(
|
||||||
sim_object._value_dict['cxx_template_params'])
|
sim_object._value_dict["cxx_class"],
|
||||||
|
sim_object._value_dict["cxx_template_params"],
|
||||||
|
)
|
||||||
|
|
||||||
# A forward class declaration is sufficient since we are just
|
# A forward class declaration is sufficient since we are just
|
||||||
# declaring a pointer.
|
# declaring a pointer.
|
||||||
@@ -186,27 +195,29 @@ for ptype in ptypes:
|
|||||||
code('#include "enums/${{ptype.__name__}}.hh"')
|
code('#include "enums/${{ptype.__name__}}.hh"')
|
||||||
code()
|
code()
|
||||||
|
|
||||||
code('namespace gem5')
|
code("namespace gem5")
|
||||||
code('{')
|
code("{")
|
||||||
code('')
|
code("")
|
||||||
|
|
||||||
# now generate the actual param struct
|
# now generate the actual param struct
|
||||||
code("struct ${sim_object}Params")
|
code("struct ${sim_object}Params")
|
||||||
if sim_object._base:
|
if sim_object._base:
|
||||||
code(" : public ${{sim_object._base.type}}Params")
|
code(" : public ${{sim_object._base.type}}Params")
|
||||||
code("{")
|
code("{")
|
||||||
if not hasattr(sim_object, 'abstract') or not sim_object.abstract:
|
if not hasattr(sim_object, "abstract") or not sim_object.abstract:
|
||||||
if 'type' in sim_object.__dict__:
|
if "type" in sim_object.__dict__:
|
||||||
code(" ${{sim_object.cxx_type}} create() const;")
|
code(" ${{sim_object.cxx_type}} create() const;")
|
||||||
|
|
||||||
code.indent()
|
code.indent()
|
||||||
if sim_object == SimObject:
|
if sim_object == SimObject:
|
||||||
code('''
|
code(
|
||||||
|
"""
|
||||||
SimObjectParams() {}
|
SimObjectParams() {}
|
||||||
virtual ~SimObjectParams() {}
|
virtual ~SimObjectParams() {}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
for param in params:
|
for param in params:
|
||||||
param.cxx_decl(code)
|
param.cxx_decl(code)
|
||||||
@@ -214,11 +225,11 @@ for port in ports.values():
|
|||||||
port.cxx_decl(code)
|
port.cxx_decl(code)
|
||||||
|
|
||||||
code.dedent()
|
code.dedent()
|
||||||
code('};')
|
code("};")
|
||||||
code()
|
code()
|
||||||
code('} // namespace gem5')
|
code("} // namespace gem5")
|
||||||
|
|
||||||
code()
|
code()
|
||||||
code('#endif // __PARAMS__${sim_object}__')
|
code("#endif // __PARAMS__${sim_object}__")
|
||||||
|
|
||||||
code.write(args.param_hh)
|
code.write(args.param_hh)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ from shutil import rmtree, copyfile
|
|||||||
|
|
||||||
|
|
||||||
def hex_mask(terms):
|
def hex_mask(terms):
|
||||||
dec_mask = reduce(operator.or_, [2 ** i for i in terms], 0)
|
dec_mask = reduce(operator.or_, [2**i for i in terms], 0)
|
||||||
return "%08x" % dec_mask
|
return "%08x" % dec_mask
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ def replace_tree(path):
|
|||||||
|
|
||||||
|
|
||||||
def config_filesystem(system, options=None):
|
def config_filesystem(system, options=None):
|
||||||
""" This function parses the system object to create the pseudo file system
|
"""This function parses the system object to create the pseudo file system
|
||||||
@param system: The system to create the config for
|
@param system: The system to create the config for
|
||||||
@param options: An optional argument which contains an Options.py options
|
@param options: An optional argument which contains an Options.py options
|
||||||
object. This is useful if when use se.py and will set the L2 cache
|
object. This is useful if when use se.py and will set the L2 cache
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ def config_mem(options, system):
|
|||||||
from m5.util import fatal
|
from m5.util import fatal
|
||||||
|
|
||||||
intlv_bits = int(math.log(nbr_mem_ctrls, 2))
|
intlv_bits = int(math.log(nbr_mem_ctrls, 2))
|
||||||
if 2 ** intlv_bits != nbr_mem_ctrls:
|
if 2**intlv_bits != nbr_mem_ctrls:
|
||||||
fatal("Number of memory channels must be a power of 2")
|
fatal("Number of memory channels must be a power of 2")
|
||||||
|
|
||||||
if opt_mem_type:
|
if opt_mem_type:
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ from textwrap import TextWrapper
|
|||||||
|
|
||||||
|
|
||||||
class ObjectList(object):
|
class ObjectList(object):
|
||||||
""" Creates a list of objects that are sub-classes of a given class. """
|
"""Creates a list of objects that are sub-classes of a given class."""
|
||||||
|
|
||||||
def _is_obj_class(self, cls):
|
def _is_obj_class(self, cls):
|
||||||
"""Determine if a class is a a sub class of the provided base class
|
"""Determine if a class is a a sub class of the provided base class
|
||||||
that can be instantiated.
|
that can be instantiated.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# We can't use the normal inspect.isclass because the ParamFactory
|
# We can't use the normal inspect.isclass because the ParamFactory
|
||||||
@@ -161,10 +161,10 @@ class CPUList(ObjectList):
|
|||||||
|
|
||||||
|
|
||||||
class EnumList(ObjectList):
|
class EnumList(ObjectList):
|
||||||
""" Creates a list of possible values for a given enum class. """
|
"""Creates a list of possible values for a given enum class."""
|
||||||
|
|
||||||
def _add_objects(self):
|
def _add_objects(self):
|
||||||
""" Add all enum values to the ObjectList """
|
"""Add all enum values to the ObjectList"""
|
||||||
self._sub_classes = {}
|
self._sub_classes = {}
|
||||||
for (key, value) in list(self.base_cls.__members__.items()):
|
for (key, value) in list(self.base_cls.__members__.items()):
|
||||||
# All Enums have a value Num_NAME at the end which we
|
# All Enums have a value Num_NAME at the end which we
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ parser = ArgumentParser()
|
|||||||
|
|
||||||
|
|
||||||
def add_option(*args, **kwargs):
|
def add_option(*args, **kwargs):
|
||||||
"""Call "add_option" to the global options parser
|
"""Call "add_option" to the global options parser"""
|
||||||
"""
|
|
||||||
|
|
||||||
if called_parse_args:
|
if called_parse_args:
|
||||||
m5.fatal("Can't add an option after calling SimpleOpts.parse_args")
|
m5.fatal("Can't add an option after calling SimpleOpts.parse_args")
|
||||||
|
|||||||
33
configs/dist/sw.py
vendored
33
configs/dist/sw.py
vendored
@@ -35,33 +35,39 @@ from m5.defines import buildEnv
|
|||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
from m5.util import addToPath, fatal
|
from m5.util import addToPath, fatal
|
||||||
|
|
||||||
addToPath('../')
|
addToPath("../")
|
||||||
|
|
||||||
from common import Simulation
|
from common import Simulation
|
||||||
from common import Options
|
from common import Options
|
||||||
|
|
||||||
|
|
||||||
def build_switch(args):
|
def build_switch(args):
|
||||||
# instantiate an EtherSwitch
|
# instantiate an EtherSwitch
|
||||||
switch = EtherSwitch()
|
switch = EtherSwitch()
|
||||||
# instantiate distEtherLinks to connect switch ports
|
# instantiate distEtherLinks to connect switch ports
|
||||||
# to other gem5 instances
|
# to other gem5 instances
|
||||||
switch.portlink = [DistEtherLink(speed = args.ethernet_linkspeed,
|
switch.portlink = [
|
||||||
delay = args.ethernet_linkdelay,
|
DistEtherLink(
|
||||||
dist_rank = args.dist_rank,
|
speed=args.ethernet_linkspeed,
|
||||||
dist_size = args.dist_size,
|
delay=args.ethernet_linkdelay,
|
||||||
server_name = args.dist_server_name,
|
dist_rank=args.dist_rank,
|
||||||
server_port = args.dist_server_port,
|
dist_size=args.dist_size,
|
||||||
sync_start = args.dist_sync_start,
|
server_name=args.dist_server_name,
|
||||||
sync_repeat = args.dist_sync_repeat,
|
server_port=args.dist_server_port,
|
||||||
is_switch = True,
|
sync_start=args.dist_sync_start,
|
||||||
num_nodes = args.dist_size)
|
sync_repeat=args.dist_sync_repeat,
|
||||||
for i in range(args.dist_size)]
|
is_switch=True,
|
||||||
|
num_nodes=args.dist_size,
|
||||||
|
)
|
||||||
|
for i in range(args.dist_size)
|
||||||
|
]
|
||||||
|
|
||||||
for (i, link) in enumerate(switch.portlink):
|
for (i, link) in enumerate(switch.portlink):
|
||||||
link.int0 = switch.interface[i]
|
link.int0 = switch.interface[i]
|
||||||
|
|
||||||
return switch
|
return switch
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Add options
|
# Add options
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
@@ -70,8 +76,9 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
system = build_switch(args)
|
system = build_switch(args)
|
||||||
root = Root(full_system = True, system = system)
|
root = Root(full_system=True, system=system)
|
||||||
Simulation.run(args, root, None, None)
|
Simulation.run(args, root, None, None)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__m5_main__":
|
if __name__ == "__m5_main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ def create_cow_image(name):
|
|||||||
|
|
||||||
|
|
||||||
def create(args):
|
def create(args):
|
||||||
""" Create and configure the system object. """
|
"""Create and configure the system object."""
|
||||||
|
|
||||||
if args.readfile and not os.path.isfile(args.readfile):
|
if args.readfile and not os.path.isfile(args.readfile):
|
||||||
print("Error: Bootscript %s does not exist" % args.readfile)
|
print("Error: Bootscript %s does not exist" % args.readfile)
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ def config_ruby(system, args):
|
|||||||
|
|
||||||
|
|
||||||
def create(args):
|
def create(args):
|
||||||
""" Create and configure the system object. """
|
"""Create and configure the system object."""
|
||||||
|
|
||||||
if args.script and not os.path.isfile(args.script):
|
if args.script and not os.path.isfile(args.script):
|
||||||
print("Error: Bootscript %s does not exist" % args.script)
|
print("Error: Bootscript %s does not exist" % args.script)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ def create_cow_image(name):
|
|||||||
|
|
||||||
|
|
||||||
def create(args):
|
def create(args):
|
||||||
""" Create and configure the system object. """
|
"""Create and configure the system object."""
|
||||||
|
|
||||||
if args.script and not os.path.isfile(args.script):
|
if args.script and not os.path.isfile(args.script):
|
||||||
print("Error: Bootscript %s does not exist" % args.script)
|
print("Error: Bootscript %s does not exist" % args.script)
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ def get_processes(cmd):
|
|||||||
|
|
||||||
|
|
||||||
def create(args):
|
def create(args):
|
||||||
""" Create and configure the system object. """
|
"""Create and configure the system object."""
|
||||||
|
|
||||||
system = SimpleSeSystem(args)
|
system = SimpleSeSystem(args)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ from common.SysPaths import binary, disk
|
|||||||
|
|
||||||
|
|
||||||
class ArmBaremetal(ArmFsWorkload):
|
class ArmBaremetal(ArmFsWorkload):
|
||||||
""" Baremetal workload """
|
"""Baremetal workload"""
|
||||||
|
|
||||||
dtb_addr = 0
|
dtb_addr = 0
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ board.set_se_binary_workload(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Lastly we run the simulation.
|
# Lastly we run the simulation.
|
||||||
max_ticks = 10 ** 6
|
max_ticks = 10**6
|
||||||
simulator = Simulator(board=board, full_system=False)
|
simulator = Simulator(board=board, full_system=False)
|
||||||
simulator.run(max_ticks=max_ticks)
|
simulator.run(max_ticks=max_ticks)
|
||||||
|
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ m5term localhost 3456
|
|||||||
```
|
```
|
||||||
|
|
||||||
This should allow you to run busybox, in which you can see the LupIO device at
|
This should allow you to run busybox, in which you can see the LupIO device at
|
||||||
work!
|
work!
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class L1Cache(Cache):
|
|||||||
|
|
||||||
def connectCPU(self, cpu):
|
def connectCPU(self, cpu):
|
||||||
"""Connect this cache's port to a CPU-side port
|
"""Connect this cache's port to a CPU-side port
|
||||||
This must be defined in a subclass"""
|
This must be defined in a subclass"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ class MyCacheSystem(RubySystem):
|
|||||||
|
|
||||||
def setup(self, system, cpus, mem_ctrls):
|
def setup(self, system, cpus, mem_ctrls):
|
||||||
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
||||||
constructor because many of these items require a pointer to the
|
constructor because many of these items require a pointer to the
|
||||||
ruby system (self). This causes infinite recursion in initialize()
|
ruby system (self). This causes infinite recursion in initialize()
|
||||||
if we do this in the __init__.
|
if we do this in the __init__.
|
||||||
"""
|
"""
|
||||||
# Ruby's global network.
|
# Ruby's global network.
|
||||||
self.network = MyNetwork(self)
|
self.network = MyNetwork(self)
|
||||||
@@ -120,7 +120,7 @@ class L1Cache(L1Cache_Controller):
|
|||||||
|
|
||||||
def __init__(self, system, ruby_system, cpu):
|
def __init__(self, system, ruby_system, cpu):
|
||||||
"""CPUs are needed to grab the clock domain and system is needed for
|
"""CPUs are needed to grab the clock domain and system is needed for
|
||||||
the cache block size.
|
the cache block size.
|
||||||
"""
|
"""
|
||||||
super(L1Cache, self).__init__()
|
super(L1Cache, self).__init__()
|
||||||
|
|
||||||
@@ -136,24 +136,23 @@ class L1Cache(L1Cache_Controller):
|
|||||||
|
|
||||||
def getBlockSizeBits(self, system):
|
def getBlockSizeBits(self, system):
|
||||||
bits = int(math.log(system.cache_line_size, 2))
|
bits = int(math.log(system.cache_line_size, 2))
|
||||||
if 2 ** bits != system.cache_line_size.value:
|
if 2**bits != system.cache_line_size.value:
|
||||||
panic("Cache line size not a power of 2!")
|
panic("Cache line size not a power of 2!")
|
||||||
return bits
|
return bits
|
||||||
|
|
||||||
def sendEvicts(self, cpu):
|
def sendEvicts(self, cpu):
|
||||||
"""True if the CPU model or ISA requires sending evictions from caches
|
"""True if the CPU model or ISA requires sending evictions from caches
|
||||||
to the CPU. Two scenarios warrant forwarding evictions to the CPU:
|
to the CPU. Two scenarios warrant forwarding evictions to the CPU:
|
||||||
1. The O3 model must keep the LSQ coherent with the caches
|
1. The O3 model must keep the LSQ coherent with the caches
|
||||||
2. The x86 mwait instruction is built on top of coherence
|
2. The x86 mwait instruction is built on top of coherence
|
||||||
3. The local exclusive monitor in ARM systems
|
3. The local exclusive monitor in ARM systems
|
||||||
"""
|
"""
|
||||||
if type(cpu) is DerivO3CPU or buildEnv["TARGET_ISA"] in ("x86", "arm"):
|
if type(cpu) is DerivO3CPU or buildEnv["TARGET_ISA"] in ("x86", "arm"):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def connectQueues(self, ruby_system):
|
def connectQueues(self, ruby_system):
|
||||||
"""Connect all of the queues for this controller.
|
"""Connect all of the queues for this controller."""
|
||||||
"""
|
|
||||||
# mandatoryQueue is a special variable. It is used by the sequencer to
|
# mandatoryQueue is a special variable. It is used by the sequencer to
|
||||||
# send RubyRequests from the CPU (or other processor). It isn't
|
# send RubyRequests from the CPU (or other processor). It isn't
|
||||||
# explicitly connected to anything.
|
# explicitly connected to anything.
|
||||||
@@ -184,8 +183,7 @@ class DirController(Directory_Controller):
|
|||||||
return cls._version - 1
|
return cls._version - 1
|
||||||
|
|
||||||
def __init__(self, ruby_system, ranges, mem_ctrls):
|
def __init__(self, ruby_system, ranges, mem_ctrls):
|
||||||
"""ranges are the memory ranges assigned to this controller.
|
"""ranges are the memory ranges assigned to this controller."""
|
||||||
"""
|
|
||||||
if len(mem_ctrls) > 1:
|
if len(mem_ctrls) > 1:
|
||||||
panic("This cache system can only be connected to one mem ctrl")
|
panic("This cache system can only be connected to one mem ctrl")
|
||||||
super(DirController, self).__init__()
|
super(DirController, self).__init__()
|
||||||
@@ -217,8 +215,7 @@ class DirController(Directory_Controller):
|
|||||||
|
|
||||||
|
|
||||||
class MyNetwork(SimpleNetwork):
|
class MyNetwork(SimpleNetwork):
|
||||||
"""A simple point-to-point network. This doesn't not use garnet.
|
"""A simple point-to-point network. This doesn't not use garnet."""
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, ruby_system):
|
def __init__(self, ruby_system):
|
||||||
super(MyNetwork, self).__init__()
|
super(MyNetwork, self).__init__()
|
||||||
@@ -227,7 +224,7 @@ class MyNetwork(SimpleNetwork):
|
|||||||
|
|
||||||
def connectControllers(self, controllers):
|
def connectControllers(self, controllers):
|
||||||
"""Connect all of the controllers to routers and connec the routers
|
"""Connect all of the controllers to routers and connec the routers
|
||||||
together in a point-to-point network.
|
together in a point-to-point network.
|
||||||
"""
|
"""
|
||||||
# Create one router/switch per controller in the system
|
# Create one router/switch per controller in the system
|
||||||
self.routers = [Switch(router_id=i) for i in range(len(controllers))]
|
self.routers = [Switch(router_id=i) for i in range(len(controllers))]
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ class MyCacheSystem(RubySystem):
|
|||||||
|
|
||||||
def setup(self, system, cpus, mem_ctrls):
|
def setup(self, system, cpus, mem_ctrls):
|
||||||
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
||||||
constructor because many of these items require a pointer to the
|
constructor because many of these items require a pointer to the
|
||||||
ruby system (self). This causes infinite recursion in initialize()
|
ruby system (self). This causes infinite recursion in initialize()
|
||||||
if we do this in the __init__.
|
if we do this in the __init__.
|
||||||
"""
|
"""
|
||||||
# Ruby's global network.
|
# Ruby's global network.
|
||||||
self.network = MyNetwork(self)
|
self.network = MyNetwork(self)
|
||||||
@@ -118,7 +118,7 @@ class L1Cache(L1Cache_Controller):
|
|||||||
|
|
||||||
def __init__(self, system, ruby_system, cpu):
|
def __init__(self, system, ruby_system, cpu):
|
||||||
"""CPUs are needed to grab the clock domain and system is needed for
|
"""CPUs are needed to grab the clock domain and system is needed for
|
||||||
the cache block size.
|
the cache block size.
|
||||||
"""
|
"""
|
||||||
super(L1Cache, self).__init__()
|
super(L1Cache, self).__init__()
|
||||||
|
|
||||||
@@ -134,24 +134,23 @@ class L1Cache(L1Cache_Controller):
|
|||||||
|
|
||||||
def getBlockSizeBits(self, system):
|
def getBlockSizeBits(self, system):
|
||||||
bits = int(math.log(system.cache_line_size, 2))
|
bits = int(math.log(system.cache_line_size, 2))
|
||||||
if 2 ** bits != system.cache_line_size.value:
|
if 2**bits != system.cache_line_size.value:
|
||||||
panic("Cache line size not a power of 2!")
|
panic("Cache line size not a power of 2!")
|
||||||
return bits
|
return bits
|
||||||
|
|
||||||
def sendEvicts(self, cpu):
|
def sendEvicts(self, cpu):
|
||||||
"""True if the CPU model or ISA requires sending evictions from caches
|
"""True if the CPU model or ISA requires sending evictions from caches
|
||||||
to the CPU. Two scenarios warrant forwarding evictions to the CPU:
|
to the CPU. Two scenarios warrant forwarding evictions to the CPU:
|
||||||
1. The O3 model must keep the LSQ coherent with the caches
|
1. The O3 model must keep the LSQ coherent with the caches
|
||||||
2. The x86 mwait instruction is built on top of coherence
|
2. The x86 mwait instruction is built on top of coherence
|
||||||
3. The local exclusive monitor in ARM systems
|
3. The local exclusive monitor in ARM systems
|
||||||
"""
|
"""
|
||||||
if type(cpu) is DerivO3CPU or buildEnv["TARGET_ISA"] in ("x86", "arm"):
|
if type(cpu) is DerivO3CPU or buildEnv["TARGET_ISA"] in ("x86", "arm"):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def connectQueues(self, ruby_system):
|
def connectQueues(self, ruby_system):
|
||||||
"""Connect all of the queues for this controller.
|
"""Connect all of the queues for this controller."""
|
||||||
"""
|
|
||||||
self.mandatoryQueue = MessageBuffer()
|
self.mandatoryQueue = MessageBuffer()
|
||||||
self.requestFromCache = MessageBuffer(ordered=True)
|
self.requestFromCache = MessageBuffer(ordered=True)
|
||||||
self.requestFromCache.out_port = ruby_system.network.in_port
|
self.requestFromCache.out_port = ruby_system.network.in_port
|
||||||
@@ -173,8 +172,7 @@ class DirController(Directory_Controller):
|
|||||||
return cls._version - 1
|
return cls._version - 1
|
||||||
|
|
||||||
def __init__(self, ruby_system, ranges, mem_ctrls):
|
def __init__(self, ruby_system, ranges, mem_ctrls):
|
||||||
"""ranges are the memory ranges assigned to this controller.
|
"""ranges are the memory ranges assigned to this controller."""
|
||||||
"""
|
|
||||||
if len(mem_ctrls) > 1:
|
if len(mem_ctrls) > 1:
|
||||||
panic("This cache system can only be connected to one mem ctrl")
|
panic("This cache system can only be connected to one mem ctrl")
|
||||||
super(DirController, self).__init__()
|
super(DirController, self).__init__()
|
||||||
@@ -203,8 +201,7 @@ class DirController(Directory_Controller):
|
|||||||
|
|
||||||
|
|
||||||
class MyNetwork(SimpleNetwork):
|
class MyNetwork(SimpleNetwork):
|
||||||
"""A simple point-to-point network. This doesn't not use garnet.
|
"""A simple point-to-point network. This doesn't not use garnet."""
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, ruby_system):
|
def __init__(self, ruby_system):
|
||||||
super(MyNetwork, self).__init__()
|
super(MyNetwork, self).__init__()
|
||||||
@@ -213,7 +210,7 @@ class MyNetwork(SimpleNetwork):
|
|||||||
|
|
||||||
def connectControllers(self, controllers):
|
def connectControllers(self, controllers):
|
||||||
"""Connect all of the controllers to routers and connec the routers
|
"""Connect all of the controllers to routers and connec the routers
|
||||||
together in a point-to-point network.
|
together in a point-to-point network.
|
||||||
"""
|
"""
|
||||||
# Create one router/switch per controller in the system
|
# Create one router/switch per controller in the system
|
||||||
self.routers = [Switch(router_id=i) for i in range(len(controllers))]
|
self.routers = [Switch(router_id=i) for i in range(len(controllers))]
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ class TestCacheSystem(RubySystem):
|
|||||||
|
|
||||||
def setup(self, system, tester, mem_ctrls):
|
def setup(self, system, tester, mem_ctrls):
|
||||||
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
"""Set up the Ruby cache subsystem. Note: This can't be done in the
|
||||||
constructor because many of these items require a pointer to the
|
constructor because many of these items require a pointer to the
|
||||||
ruby system (self). This causes infinite recursion in initialize()
|
ruby system (self). This causes infinite recursion in initialize()
|
||||||
if we do this in the __init__.
|
if we do this in the __init__.
|
||||||
Setting up for running the RubyRandomTester is a little different
|
Setting up for running the RubyRandomTester is a little different
|
||||||
than when we're using CPUs.
|
than when we're using CPUs.
|
||||||
"""
|
"""
|
||||||
num_testers = tester.num_cpus
|
num_testers = tester.num_cpus
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def define_options(parser):
|
|||||||
|
|
||||||
|
|
||||||
def read_config_file(file):
|
def read_config_file(file):
|
||||||
""" Read file as a module and return it """
|
"""Read file as a module and return it"""
|
||||||
import types
|
import types
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
|
|
||||||
|
|||||||
@@ -200,10 +200,10 @@ def setup_memory_controllers(system, ruby, dir_cntrls, options):
|
|||||||
|
|
||||||
|
|
||||||
def create_topology(controllers, options):
|
def create_topology(controllers, options):
|
||||||
""" Called from create_system in configs/ruby/<protocol>.py
|
"""Called from create_system in configs/ruby/<protocol>.py
|
||||||
Must return an object which is a subclass of BaseTopology
|
Must return an object which is a subclass of BaseTopology
|
||||||
found in configs/topologies/BaseTopology.py
|
found in configs/topologies/BaseTopology.py
|
||||||
This is a wrapper for the legacy topologies.
|
This is a wrapper for the legacy topologies.
|
||||||
"""
|
"""
|
||||||
exec("import topologies.%s as Topo" % options.topology)
|
exec("import topologies.%s as Topo" % options.topology)
|
||||||
topology = eval("Topo.%s(controllers)" % options.topology)
|
topology = eval("Topo.%s(controllers)" % options.topology)
|
||||||
|
|||||||
@@ -31,37 +31,37 @@ class BaseTopology(object):
|
|||||||
description = "BaseTopology"
|
description = "BaseTopology"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""" When overriding place any objects created in
|
"""When overriding place any objects created in
|
||||||
configs/ruby/<protocol>.py that are needed in
|
configs/ruby/<protocol>.py that are needed in
|
||||||
makeTopology (below) here. The minimum is usually
|
makeTopology (below) here. The minimum is usually
|
||||||
all of the controllers created in the above file.
|
all of the controllers created in the above file.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def makeTopology(self, options, network, IntLink, ExtLink, Router):
|
def makeTopology(self, options, network, IntLink, ExtLink, Router):
|
||||||
""" Called from configs/ruby/Ruby.py
|
"""Called from configs/ruby/Ruby.py
|
||||||
The return value is ( list(Router), list(IntLink), list(ExtLink))
|
The return value is ( list(Router), list(IntLink), list(ExtLink))
|
||||||
The API of this function cannot change when subclassing!!
|
The API of this function cannot change when subclassing!!
|
||||||
Any additional information needed to create this topology should
|
Any additional information needed to create this topology should
|
||||||
be passed into the constructor when it's instantiated in
|
be passed into the constructor when it's instantiated in
|
||||||
configs/ruby/<protocol>.py
|
configs/ruby/<protocol>.py
|
||||||
"""
|
"""
|
||||||
m5.util.fatal("BaseTopology should have been overridden!!")
|
m5.util.fatal("BaseTopology should have been overridden!!")
|
||||||
|
|
||||||
def registerTopology(self, options):
|
def registerTopology(self, options):
|
||||||
""" Called from configs/ruby/Ruby.py
|
"""Called from configs/ruby/Ruby.py
|
||||||
There is no return value. This should only be called in
|
There is no return value. This should only be called in
|
||||||
SE mode. It is used by some topology objects to populate
|
SE mode. It is used by some topology objects to populate
|
||||||
the faux filesystem with accurate file contents.
|
the faux filesystem with accurate file contents.
|
||||||
No need to implement if not using FilesystemRegister
|
No need to implement if not using FilesystemRegister
|
||||||
functionality.
|
functionality.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class SimpleTopology(BaseTopology):
|
class SimpleTopology(BaseTopology):
|
||||||
""" Provides methods needed for the topologies included in Ruby before
|
"""Provides methods needed for the topologies included in Ruby before
|
||||||
topology changes.
|
topology changes.
|
||||||
These topologies are "simple" in the sense that they only use a flat
|
These topologies are "simple" in the sense that they only use a flat
|
||||||
list of controllers to construct the topology.
|
list of controllers to construct the topology.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
description = "SimpleTopology"
|
description = "SimpleTopology"
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ from topologies.BaseTopology import BaseTopology
|
|||||||
|
|
||||||
|
|
||||||
class Cluster(BaseTopology):
|
class Cluster(BaseTopology):
|
||||||
""" A cluster is a group of nodes which are all one hop from eachother
|
"""A cluster is a group of nodes which are all one hop from eachother
|
||||||
Clusters can also contain other clusters
|
Clusters can also contain other clusters
|
||||||
When creating this kind of topology, return a single cluster (usually
|
When creating this kind of topology, return a single cluster (usually
|
||||||
the root cluster) from create_system in configs/ruby/<protocol>.py
|
the root cluster) from create_system in configs/ruby/<protocol>.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_num_int_links = 0
|
_num_int_links = 0
|
||||||
@@ -55,13 +55,13 @@ class Cluster(BaseTopology):
|
|||||||
return cls._num_routers - 1
|
return cls._num_routers - 1
|
||||||
|
|
||||||
def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0):
|
def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0):
|
||||||
""" internalBandwidth is bandwidth of all links within the cluster
|
"""internalBandwidth is bandwidth of all links within the cluster
|
||||||
externalBandwidth is bandwidth from this cluster to any cluster
|
externalBandwidth is bandwidth from this cluster to any cluster
|
||||||
connecting to it.
|
connecting to it.
|
||||||
internal/externalLatency are similar
|
internal/externalLatency are similar
|
||||||
**** When creating a cluster with sub-clusters, the sub-cluster
|
**** When creating a cluster with sub-clusters, the sub-cluster
|
||||||
external bandwidth overrides the internal bandwidth of the
|
external bandwidth overrides the internal bandwidth of the
|
||||||
super cluster
|
super cluster
|
||||||
"""
|
"""
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
self.router = None # created in makeTopology
|
self.router = None # created in makeTopology
|
||||||
@@ -74,8 +74,7 @@ class Cluster(BaseTopology):
|
|||||||
self.nodes.append(node)
|
self.nodes.append(node)
|
||||||
|
|
||||||
def makeTopology(self, options, network, IntLink, ExtLink, Router):
|
def makeTopology(self, options, network, IntLink, ExtLink, Router):
|
||||||
""" Recursively make all of the links and routers
|
"""Recursively make all of the links and routers"""
|
||||||
"""
|
|
||||||
|
|
||||||
# make a router to connect all of the nodes
|
# make a router to connect all of the nodes
|
||||||
self.router = Router(router_id=self.num_routers())
|
self.router = Router(router_id=self.num_routers())
|
||||||
|
|||||||
@@ -41,13 +41,13 @@
|
|||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
|
|
||||||
fs = SCons.Node.FS.get_default_fs()
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
root = fs.Dir('#')
|
root = fs.Dir("#")
|
||||||
extra_python_nodes = [
|
extra_python_nodes = [
|
||||||
root.Dir('src').Dir('python').srcnode(), # gem5 includes
|
root.Dir("src").Dir("python").srcnode(), # gem5 includes
|
||||||
root.Dir('ext').Dir('ply').srcnode(), # ply is used by several files
|
root.Dir("ext").Dir("ply").srcnode(), # ply is used by several files
|
||||||
root.Dir('ext').Dir('Kconfiglib').Dir('import').srcnode(), # kconfiglib
|
root.Dir("ext").Dir("Kconfiglib").Dir("import").srcnode(), # kconfiglib
|
||||||
]
|
]
|
||||||
|
|
||||||
extra_python_paths = [ node.abspath for node in extra_python_nodes ]
|
extra_python_paths = [node.abspath for node in extra_python_nodes]
|
||||||
|
|
||||||
__all__ = ['extra_python_paths']
|
__all__ = ["extra_python_paths"]
|
||||||
|
|||||||
@@ -52,34 +52,38 @@ import SCons.Script
|
|||||||
|
|
||||||
termcap = get_termcap()
|
termcap = get_termcap()
|
||||||
|
|
||||||
|
|
||||||
def strip_build_path(path, env):
|
def strip_build_path(path, env):
|
||||||
path = str(path)
|
path = str(path)
|
||||||
build_base = 'build/'
|
build_base = "build/"
|
||||||
variant_base = env['BUILDROOT'] + os.path.sep
|
variant_base = env["BUILDROOT"] + os.path.sep
|
||||||
if path.startswith(variant_base):
|
if path.startswith(variant_base):
|
||||||
path = path[len(variant_base):]
|
path = path[len(variant_base) :]
|
||||||
elif path.startswith(build_base):
|
elif path.startswith(build_base):
|
||||||
path = path[len(build_base):]
|
path = path[len(build_base) :]
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
def TempFileSpawn(scons_env):
|
def TempFileSpawn(scons_env):
|
||||||
old_pspawn = scons_env['PSPAWN']
|
old_pspawn = scons_env["PSPAWN"]
|
||||||
old_spawn = scons_env['SPAWN']
|
old_spawn = scons_env["SPAWN"]
|
||||||
|
|
||||||
def wrapper(old, sh, esc, cmd, sh_args, *py_args):
|
def wrapper(old, sh, esc, cmd, sh_args, *py_args):
|
||||||
with tempfile.NamedTemporaryFile() as temp:
|
with tempfile.NamedTemporaryFile() as temp:
|
||||||
temp.write(' '.join(sh_args).encode())
|
temp.write(" ".join(sh_args).encode())
|
||||||
temp.flush()
|
temp.flush()
|
||||||
sh_args = [sh, esc(temp.name)]
|
sh_args = [sh, esc(temp.name)]
|
||||||
return old(sh, esc, sh, sh_args, *py_args)
|
return old(sh, esc, sh, sh_args, *py_args)
|
||||||
|
|
||||||
def new_pspawn(sh, esc, cmd, args, sh_env, stdout, stderr):
|
def new_pspawn(sh, esc, cmd, args, sh_env, stdout, stderr):
|
||||||
return wrapper(old_pspawn, sh, esc, cmd, args, sh_env, stdout, stderr)
|
return wrapper(old_pspawn, sh, esc, cmd, args, sh_env, stdout, stderr)
|
||||||
|
|
||||||
def new_spawn(sh, esc, cmd, args, sh_env):
|
def new_spawn(sh, esc, cmd, args, sh_env):
|
||||||
return wrapper(old_spawn, sh, esc, cmd, args, sh_env)
|
return wrapper(old_spawn, sh, esc, cmd, args, sh_env)
|
||||||
|
|
||||||
scons_env['PSPAWN'] = new_pspawn
|
scons_env["PSPAWN"] = new_pspawn
|
||||||
scons_env['SPAWN'] = new_spawn
|
scons_env["SPAWN"] = new_spawn
|
||||||
|
|
||||||
|
|
||||||
# Generate a string of the form:
|
# Generate a string of the form:
|
||||||
# common/path/prefix/src1, src2 -> tgt1, tgt2
|
# common/path/prefix/src1, src2 -> tgt1, tgt2
|
||||||
@@ -93,23 +97,32 @@ class Transform(object):
|
|||||||
tgts_color = termcap.Yellow + termcap.Bold
|
tgts_color = termcap.Yellow + termcap.Bold
|
||||||
|
|
||||||
def __init__(self, tool, max_sources=99):
|
def __init__(self, tool, max_sources=99):
|
||||||
self.format = self.tool_color + (" [%8s] " % tool) \
|
self.format = (
|
||||||
+ self.pfx_color + "%s" \
|
self.tool_color
|
||||||
+ self.srcs_color + "%s" \
|
+ (" [%8s] " % tool)
|
||||||
+ self.arrow_color + " -> " \
|
+ self.pfx_color
|
||||||
+ self.tgts_color + "%s" \
|
+ "%s"
|
||||||
+ termcap.Normal
|
+ self.srcs_color
|
||||||
|
+ "%s"
|
||||||
|
+ self.arrow_color
|
||||||
|
+ " -> "
|
||||||
|
+ self.tgts_color
|
||||||
|
+ "%s"
|
||||||
|
+ termcap.Normal
|
||||||
|
)
|
||||||
self.max_sources = max_sources
|
self.max_sources = max_sources
|
||||||
|
|
||||||
def __call__(self, target, source, env, for_signature=None):
|
def __call__(self, target, source, env, for_signature=None):
|
||||||
# truncate source list according to max_sources param
|
# truncate source list according to max_sources param
|
||||||
source = source[0:self.max_sources]
|
source = source[0 : self.max_sources]
|
||||||
|
|
||||||
def strip(f):
|
def strip(f):
|
||||||
return strip_build_path(str(f), env)
|
return strip_build_path(str(f), env)
|
||||||
|
|
||||||
if len(source) > 0:
|
if len(source) > 0:
|
||||||
srcs = list(map(strip, source))
|
srcs = list(map(strip, source))
|
||||||
else:
|
else:
|
||||||
srcs = ['']
|
srcs = [""]
|
||||||
tgts = list(map(strip, target))
|
tgts = list(map(strip, target))
|
||||||
# surprisingly, os.path.commonprefix is a dumb char-by-char string
|
# surprisingly, os.path.commonprefix is a dumb char-by-char string
|
||||||
# operation that has nothing to do with paths.
|
# operation that has nothing to do with paths.
|
||||||
@@ -137,20 +150,23 @@ class Transform(object):
|
|||||||
if sep_idx != -1:
|
if sep_idx != -1:
|
||||||
com_pfx = com_pfx[0:sep_idx]
|
com_pfx = com_pfx[0:sep_idx]
|
||||||
else:
|
else:
|
||||||
com_pfx = ''
|
com_pfx = ""
|
||||||
elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".":
|
elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".":
|
||||||
# still splitting at file extension: ok
|
# still splitting at file extension: ok
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# probably a fluke; ignore it
|
# probably a fluke; ignore it
|
||||||
com_pfx = ''
|
com_pfx = ""
|
||||||
# recalculate length in case com_pfx was modified
|
# recalculate length in case com_pfx was modified
|
||||||
com_pfx_len = len(com_pfx)
|
com_pfx_len = len(com_pfx)
|
||||||
|
|
||||||
def fmt(files):
|
def fmt(files):
|
||||||
f = list(map(lambda s: s[com_pfx_len:], files))
|
f = list(map(lambda s: s[com_pfx_len:], files))
|
||||||
return ', '.join(f)
|
return ", ".join(f)
|
||||||
|
|
||||||
return self.format % (com_pfx, fmt(srcs), fmt(tgts))
|
return self.format % (com_pfx, fmt(srcs), fmt(tgts))
|
||||||
|
|
||||||
|
|
||||||
# The width warning and error messages should be wrapped at.
|
# The width warning and error messages should be wrapped at.
|
||||||
text_width = None
|
text_width = None
|
||||||
|
|
||||||
@@ -162,6 +178,7 @@ if not sys.stdout.isatty():
|
|||||||
if text_width is None:
|
if text_width is None:
|
||||||
try:
|
try:
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
text_width = shutil.get_terminal_size().columns
|
text_width = shutil.get_terminal_size().columns
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -170,6 +187,7 @@ if text_width is None:
|
|||||||
if text_width is None:
|
if text_width is None:
|
||||||
try:
|
try:
|
||||||
import curses
|
import curses
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_, text_width = curses.initscr().getmaxyx()
|
_, text_width = curses.initscr().getmaxyx()
|
||||||
finally:
|
finally:
|
||||||
@@ -181,21 +199,22 @@ if text_width is None:
|
|||||||
if text_width is None:
|
if text_width is None:
|
||||||
text_width = 80
|
text_width = 80
|
||||||
|
|
||||||
|
|
||||||
def print_message(prefix, color, message, **kwargs):
|
def print_message(prefix, color, message, **kwargs):
|
||||||
prefix_len = len(prefix)
|
prefix_len = len(prefix)
|
||||||
if text_width > prefix_len:
|
if text_width > prefix_len:
|
||||||
wrap_width = text_width - prefix_len
|
wrap_width = text_width - prefix_len
|
||||||
padding = ' ' * prefix_len
|
padding = " " * prefix_len
|
||||||
|
|
||||||
# First split on newlines.
|
# First split on newlines.
|
||||||
lines = message.split('\n')
|
lines = message.split("\n")
|
||||||
# Then wrap each line to the required width.
|
# Then wrap each line to the required width.
|
||||||
wrapped_lines = []
|
wrapped_lines = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
wrapped_lines.extend(textwrap.wrap(line, wrap_width))
|
wrapped_lines.extend(textwrap.wrap(line, wrap_width))
|
||||||
# Finally add the prefix and padding on extra lines, and glue it all
|
# Finally add the prefix and padding on extra lines, and glue it all
|
||||||
# back together.
|
# back together.
|
||||||
message = prefix + ('\n' + padding).join(wrapped_lines)
|
message = prefix + ("\n" + padding).join(wrapped_lines)
|
||||||
else:
|
else:
|
||||||
# We have very small terminal, indent formatting doesn't help.
|
# We have very small terminal, indent formatting doesn't help.
|
||||||
message = prefix + message
|
message = prefix + message
|
||||||
@@ -205,27 +224,36 @@ def print_message(prefix, color, message, **kwargs):
|
|||||||
print(message, **kwargs)
|
print(message, **kwargs)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
all_warnings = []
|
all_warnings = []
|
||||||
|
|
||||||
|
|
||||||
def summarize_warnings():
|
def summarize_warnings():
|
||||||
if not all_warnings:
|
if not all_warnings:
|
||||||
return
|
return
|
||||||
print(termcap.Yellow + termcap.Bold +
|
print(
|
||||||
'*** Summary of Warnings ***' +
|
termcap.Yellow
|
||||||
termcap.Normal)
|
+ termcap.Bold
|
||||||
|
+ "*** Summary of Warnings ***"
|
||||||
|
+ termcap.Normal
|
||||||
|
)
|
||||||
list(map(print, all_warnings))
|
list(map(print, all_warnings))
|
||||||
|
|
||||||
|
|
||||||
def warning(*args, **kwargs):
|
def warning(*args, **kwargs):
|
||||||
message = ' '.join(args)
|
message = " ".join(args)
|
||||||
printed = print_message('Warning: ', termcap.Yellow, message, **kwargs)
|
printed = print_message("Warning: ", termcap.Yellow, message, **kwargs)
|
||||||
all_warnings.append(printed)
|
all_warnings.append(printed)
|
||||||
|
|
||||||
|
|
||||||
def error(*args, **kwargs):
|
def error(*args, **kwargs):
|
||||||
message = ' '.join(args)
|
message = " ".join(args)
|
||||||
print_message('Error: ', termcap.Red, message, **kwargs)
|
print_message("Error: ", termcap.Red, message, **kwargs)
|
||||||
SCons.Script.Exit(1)
|
SCons.Script.Exit(1)
|
||||||
|
|
||||||
|
|
||||||
def parse_build_path(target):
|
def parse_build_path(target):
|
||||||
path_dirs = target.split('/')
|
path_dirs = target.split("/")
|
||||||
|
|
||||||
# Pop off the target file.
|
# Pop off the target file.
|
||||||
path_dirs.pop()
|
path_dirs.pop()
|
||||||
@@ -233,40 +261,55 @@ def parse_build_path(target):
|
|||||||
# Search backwards for the "build" directory. Whatever was just before it
|
# Search backwards for the "build" directory. Whatever was just before it
|
||||||
# was the name of the variant.
|
# was the name of the variant.
|
||||||
variant_dir = path_dirs.pop()
|
variant_dir = path_dirs.pop()
|
||||||
while path_dirs and path_dirs[-1] != 'build':
|
while path_dirs and path_dirs[-1] != "build":
|
||||||
variant_dir = path_dirs.pop()
|
variant_dir = path_dirs.pop()
|
||||||
if not path_dirs:
|
if not path_dirs:
|
||||||
error("No non-leaf 'build' dir found on target path.", t)
|
error("No non-leaf 'build' dir found on target path.", t)
|
||||||
|
|
||||||
return os.path.join('/', *path_dirs), variant_dir
|
return os.path.join("/", *path_dirs), variant_dir
|
||||||
|
|
||||||
|
|
||||||
# The MakeAction wrapper, and a SCons tool to set up the *COMSTR variables.
|
# The MakeAction wrapper, and a SCons tool to set up the *COMSTR variables.
|
||||||
if SCons.Script.GetOption('verbose'):
|
if SCons.Script.GetOption("verbose"):
|
||||||
|
|
||||||
def MakeAction(action, string, *args, **kwargs):
|
def MakeAction(action, string, *args, **kwargs):
|
||||||
return SCons.Script.Action(action, *args, **kwargs)
|
return SCons.Script.Action(action, *args, **kwargs)
|
||||||
|
|
||||||
def MakeActionTool(env):
|
def MakeActionTool(env):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
MakeAction = SCons.Script.Action
|
MakeAction = SCons.Script.Action
|
||||||
|
|
||||||
def MakeActionTool(env):
|
def MakeActionTool(env):
|
||||||
env['CCCOMSTR'] = Transform("CC")
|
env["CCCOMSTR"] = Transform("CC")
|
||||||
env['CXXCOMSTR'] = Transform("CXX")
|
env["CXXCOMSTR"] = Transform("CXX")
|
||||||
env['ASCOMSTR'] = Transform("AS")
|
env["ASCOMSTR"] = Transform("AS")
|
||||||
env['ARCOMSTR'] = Transform("AR", 0)
|
env["ARCOMSTR"] = Transform("AR", 0)
|
||||||
env['LINKCOMSTR'] = Transform("LINK", 0)
|
env["LINKCOMSTR"] = Transform("LINK", 0)
|
||||||
env['SHLINKCOMSTR'] = Transform("SHLINK", 0)
|
env["SHLINKCOMSTR"] = Transform("SHLINK", 0)
|
||||||
env['RANLIBCOMSTR'] = Transform("RANLIB", 0)
|
env["RANLIBCOMSTR"] = Transform("RANLIB", 0)
|
||||||
env['M4COMSTR'] = Transform("M4")
|
env["M4COMSTR"] = Transform("M4")
|
||||||
env['SHCCCOMSTR'] = Transform("SHCC")
|
env["SHCCCOMSTR"] = Transform("SHCC")
|
||||||
env['SHCXXCOMSTR'] = Transform("SHCXX")
|
env["SHCXXCOMSTR"] = Transform("SHCXX")
|
||||||
|
|
||||||
|
|
||||||
def ToValue(obj):
|
def ToValue(obj):
|
||||||
return SCons.Node.Python.Value(pickle.dumps(obj))
|
return SCons.Node.Python.Value(pickle.dumps(obj))
|
||||||
|
|
||||||
|
|
||||||
def FromValue(node):
|
def FromValue(node):
|
||||||
return pickle.loads(node.read())
|
return pickle.loads(node.read())
|
||||||
|
|
||||||
__all__ = ['Configure', 'EnvDefaults', 'Transform', 'warning', 'error',
|
|
||||||
'MakeAction', 'MakeActionTool', 'ToValue', 'FromValue']
|
__all__ = [
|
||||||
|
"Configure",
|
||||||
|
"EnvDefaults",
|
||||||
|
"Transform",
|
||||||
|
"warning",
|
||||||
|
"error",
|
||||||
|
"MakeAction",
|
||||||
|
"MakeActionTool",
|
||||||
|
"ToValue",
|
||||||
|
"FromValue",
|
||||||
|
]
|
||||||
|
|||||||
@@ -43,26 +43,23 @@ import sys
|
|||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
|
|
||||||
|
|
||||||
def AddLocalRPATH(env):
|
def AddLocalRPATH(env):
|
||||||
def add_local_rpath(env, *targets):
|
def add_local_rpath(env, *targets):
|
||||||
'''Set up an RPATH for a library which lives in the build directory.
|
"""Set up an RPATH for a library which lives in the build directory.
|
||||||
|
|
||||||
The construction environment variable BIN_RPATH_PREFIX should be set
|
The construction environment variable BIN_RPATH_PREFIX should be set
|
||||||
to the relative path of the build directory starting from the location
|
to the relative path of the build directory starting from the location
|
||||||
of the binary.'''
|
of the binary."""
|
||||||
for target in targets:
|
for target in targets:
|
||||||
target = env.Entry(target)
|
target = env.Entry(target)
|
||||||
if not isinstance(target, SCons.Node.FS.Dir):
|
if not isinstance(target, SCons.Node.FS.Dir):
|
||||||
target = target.dir
|
target = target.dir
|
||||||
relpath = os.path.relpath(target.abspath, env['BUILDDIR'])
|
relpath = os.path.relpath(target.abspath, env["BUILDDIR"])
|
||||||
components = [
|
components = ["\\$$ORIGIN", "${BIN_RPATH_PREFIX}", relpath]
|
||||||
'\\$$ORIGIN',
|
|
||||||
'${BIN_RPATH_PREFIX}',
|
|
||||||
relpath
|
|
||||||
]
|
|
||||||
env.Append(RPATH=[env.Literal(os.path.join(*components))])
|
env.Append(RPATH=[env.Literal(os.path.join(*components))])
|
||||||
|
|
||||||
if sys.platform != "darwin":
|
if sys.platform != "darwin":
|
||||||
env.Append(LINKFLAGS=env.Split('-z origin'))
|
env.Append(LINKFLAGS=env.Split("-z origin"))
|
||||||
|
|
||||||
env.AddMethod(add_local_rpath, 'AddLocalRPATH')
|
env.AddMethod(add_local_rpath, "AddLocalRPATH")
|
||||||
|
|||||||
@@ -46,19 +46,21 @@ from code_formatter import code_formatter
|
|||||||
|
|
||||||
import SCons.Node.Python
|
import SCons.Node.Python
|
||||||
|
|
||||||
|
|
||||||
def build_blob(target, source, env):
|
def build_blob(target, source, env):
|
||||||
'''
|
"""
|
||||||
Embed an arbitrary blob into the gem5 executable,
|
Embed an arbitrary blob into the gem5 executable,
|
||||||
and make it accessible to C++ as a byte array.
|
and make it accessible to C++ as a byte array.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
with open(str(source[0]), 'rb') as f:
|
with open(str(source[0]), "rb") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
symbol = str(source[1])
|
symbol = str(source[1])
|
||||||
cc, hh = target
|
cc, hh = target
|
||||||
|
|
||||||
hh_code = code_formatter()
|
hh_code = code_formatter()
|
||||||
hh_code('''\
|
hh_code(
|
||||||
|
"""\
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -72,13 +74,15 @@ extern const std::uint8_t ${symbol}[];
|
|||||||
|
|
||||||
} // namespace Blobs
|
} // namespace Blobs
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
hh_code.write(str(hh))
|
hh_code.write(str(hh))
|
||||||
|
|
||||||
include_path = os.path.relpath(hh.abspath, env['BUILDDIR'])
|
include_path = os.path.relpath(hh.abspath, env["BUILDDIR"])
|
||||||
|
|
||||||
cc_code = code_formatter()
|
cc_code = code_formatter()
|
||||||
cc_code('''\
|
cc_code(
|
||||||
|
"""\
|
||||||
#include "${include_path}"
|
#include "${include_path}"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
@@ -87,22 +91,28 @@ namespace Blobs
|
|||||||
{
|
{
|
||||||
|
|
||||||
const std::size_t ${symbol}_len = ${{len(data)}};
|
const std::size_t ${symbol}_len = ${{len(data)}};
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
bytesToCppArray(cc_code, symbol, data)
|
bytesToCppArray(cc_code, symbol, data)
|
||||||
cc_code('''
|
cc_code(
|
||||||
|
"""
|
||||||
} // namespace Blobs
|
} // namespace Blobs
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
''')
|
"""
|
||||||
|
)
|
||||||
cc_code.write(str(cc))
|
cc_code.write(str(cc))
|
||||||
|
|
||||||
|
|
||||||
blob_action = MakeAction(build_blob, Transform("EMBED BLOB"))
|
blob_action = MakeAction(build_blob, Transform("EMBED BLOB"))
|
||||||
|
|
||||||
|
|
||||||
def blob_emitter(target, source, env):
|
def blob_emitter(target, source, env):
|
||||||
symbol = str(target[0])
|
symbol = str(target[0])
|
||||||
cc_file = env.File(symbol + '.cc')
|
cc_file = env.File(symbol + ".cc")
|
||||||
hh_file = env.File(symbol + '.hh')
|
hh_file = env.File(symbol + ".hh")
|
||||||
return [cc_file, hh_file], [source, SCons.Node.Python.Value(symbol)]
|
return [cc_file, hh_file], [source, SCons.Node.Python.Value(symbol)]
|
||||||
|
|
||||||
|
|
||||||
def Blob(env):
|
def Blob(env):
|
||||||
blob_builder = env.Builder(action=blob_action, emitter=blob_emitter)
|
blob_builder = env.Builder(action=blob_action, emitter=blob_emitter)
|
||||||
env.Append(BUILDERS={'Blob': blob_builder})
|
env.Append(BUILDERS={"Blob": blob_builder})
|
||||||
|
|||||||
@@ -46,15 +46,16 @@ from gem5_scons import Transform, MakeAction
|
|||||||
#
|
#
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
|
|
||||||
def ConfigFile(env):
|
def ConfigFile(env):
|
||||||
# This function generates a config header file that #defines the
|
# This function generates a config header file that #defines the
|
||||||
# variable symbol to the current variable setting (0 or 1). The source
|
# variable symbol to the current variable setting (0 or 1). The source
|
||||||
# operands are the name of the variable and a Value node containing the
|
# operands are the name of the variable and a Value node containing the
|
||||||
# value of the variable.
|
# value of the variable.
|
||||||
def build_config_file(target, source, env):
|
def build_config_file(target, source, env):
|
||||||
(variable, value) = [s.get_contents().decode('utf-8') for s in source]
|
(variable, value) = [s.get_contents().decode("utf-8") for s in source]
|
||||||
with open(str(target[0].abspath), 'w') as f:
|
with open(str(target[0].abspath), "w") as f:
|
||||||
print('#define', variable, value, file=f)
|
print("#define", variable, value, file=f)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Combine the two functions into a scons Action object.
|
# Combine the two functions into a scons Action object.
|
||||||
@@ -66,8 +67,8 @@ def ConfigFile(env):
|
|||||||
# extract variable name from Builder arg
|
# extract variable name from Builder arg
|
||||||
variable = str(target[0])
|
variable = str(target[0])
|
||||||
# True target is config header file
|
# True target is config header file
|
||||||
target = env.Dir('config').File(variable.lower() + '.hh')
|
target = env.Dir("config").File(variable.lower() + ".hh")
|
||||||
val = env['CONF'][variable]
|
val = env["CONF"][variable]
|
||||||
if isinstance(val, bool):
|
if isinstance(val, bool):
|
||||||
# Force value to 0/1
|
# Force value to 0/1
|
||||||
val = str(int(val))
|
val = str(int(val))
|
||||||
@@ -79,4 +80,4 @@ def ConfigFile(env):
|
|||||||
|
|
||||||
config_builder = env.Builder(emitter=config_emitter, action=config_action)
|
config_builder = env.Builder(emitter=config_emitter, action=config_action)
|
||||||
|
|
||||||
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
|
env.Append(BUILDERS={"ConfigFile": config_builder})
|
||||||
|
|||||||
@@ -51,27 +51,32 @@ from gem5_scons import Transform, MakeAction
|
|||||||
#
|
#
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
|
|
||||||
def SwitchingHeaders(env):
|
def SwitchingHeaders(env):
|
||||||
def build_switching_header(target, source, env):
|
def build_switching_header(target, source, env):
|
||||||
path = str(target[0])
|
path = str(target[0])
|
||||||
subdir = str(source[0])
|
subdir = str(source[0])
|
||||||
dp, fp = os.path.split(path)
|
dp, fp = os.path.split(path)
|
||||||
dp = os.path.relpath(os.path.realpath(dp),
|
dp = os.path.relpath(
|
||||||
os.path.realpath(env['BUILDDIR']))
|
os.path.realpath(dp), os.path.realpath(env["BUILDDIR"])
|
||||||
with open(path, 'w') as hdr:
|
)
|
||||||
|
with open(path, "w") as hdr:
|
||||||
print('#include "%s/%s/%s"' % (dp, subdir, fp), file=hdr)
|
print('#include "%s/%s/%s"' % (dp, subdir, fp), file=hdr)
|
||||||
|
|
||||||
switching_header_action = MakeAction(build_switching_header,
|
switching_header_action = MakeAction(
|
||||||
Transform('GENERATE'))
|
build_switching_header, Transform("GENERATE")
|
||||||
|
)
|
||||||
|
|
||||||
switching_header_builder = env.Builder(action=switching_header_action,
|
switching_header_builder = env.Builder(
|
||||||
source_factory=env.Value,
|
action=switching_header_action,
|
||||||
single_source=True)
|
source_factory=env.Value,
|
||||||
|
single_source=True,
|
||||||
|
)
|
||||||
|
|
||||||
env.Append(BUILDERS = { 'SwitchingHeader': switching_header_builder })
|
env.Append(BUILDERS={"SwitchingHeader": switching_header_builder})
|
||||||
|
|
||||||
def switching_headers(self, headers, source):
|
def switching_headers(self, headers, source):
|
||||||
for header in headers:
|
for header in headers:
|
||||||
self.SwitchingHeader(header, source)
|
self.SwitchingHeader(header, source)
|
||||||
|
|
||||||
env.AddMethod(switching_headers, 'SwitchingHeaders')
|
env.AddMethod(switching_headers, "SwitchingHeaders")
|
||||||
|
|||||||
@@ -44,39 +44,41 @@ import os
|
|||||||
import SCons.Script
|
import SCons.Script
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
def CheckCxxFlag(context, flag, autoadd=True):
|
def CheckCxxFlag(context, flag, autoadd=True):
|
||||||
context.Message("Checking for compiler %s support... " % flag)
|
context.Message("Checking for compiler %s support... " % flag)
|
||||||
last_cxxflags = context.env['CXXFLAGS']
|
last_cxxflags = context.env["CXXFLAGS"]
|
||||||
context.env.Append(CXXFLAGS=[flag])
|
context.env.Append(CXXFLAGS=[flag])
|
||||||
pre_werror = context.env['CXXFLAGS']
|
pre_werror = context.env["CXXFLAGS"]
|
||||||
context.env.Append(CXXFLAGS=['-Werror'])
|
context.env.Append(CXXFLAGS=["-Werror"])
|
||||||
ret = context.TryCompile('// CheckCxxFlag DO NOTHING', '.cc')
|
ret = context.TryCompile("// CheckCxxFlag DO NOTHING", ".cc")
|
||||||
context.env['CXXFLAGS'] = pre_werror
|
context.env["CXXFLAGS"] = pre_werror
|
||||||
if not (ret and autoadd):
|
if not (ret and autoadd):
|
||||||
context.env['CXXFLAGS'] = last_cxxflags
|
context.env["CXXFLAGS"] = last_cxxflags
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def CheckLinkFlag(context, flag, autoadd=True, set_for_shared=True):
|
def CheckLinkFlag(context, flag, autoadd=True, set_for_shared=True):
|
||||||
context.Message("Checking for linker %s support... " % flag)
|
context.Message("Checking for linker %s support... " % flag)
|
||||||
last_linkflags = context.env['LINKFLAGS']
|
last_linkflags = context.env["LINKFLAGS"]
|
||||||
context.env.Append(LINKFLAGS=[flag])
|
context.env.Append(LINKFLAGS=[flag])
|
||||||
pre_werror = context.env['LINKFLAGS']
|
pre_werror = context.env["LINKFLAGS"]
|
||||||
context.env.Append(LINKFLAGS=['-Werror'])
|
context.env.Append(LINKFLAGS=["-Werror"])
|
||||||
ret = context.TryLink('int main(int, char *[]) { return 0; }', '.cc')
|
ret = context.TryLink("int main(int, char *[]) { return 0; }", ".cc")
|
||||||
context.env['LINKFLAGS'] = pre_werror
|
context.env["LINKFLAGS"] = pre_werror
|
||||||
if not (ret and autoadd):
|
if not (ret and autoadd):
|
||||||
context.env['LINKFLAGS'] = last_linkflags
|
context.env["LINKFLAGS"] = last_linkflags
|
||||||
if (ret and set_for_shared):
|
if ret and set_for_shared:
|
||||||
assert(autoadd)
|
assert autoadd
|
||||||
context.env.Append(SHLINKFLAGS=[flag])
|
context.env.Append(SHLINKFLAGS=[flag])
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
# Add a custom Check function to test for structure members.
|
# Add a custom Check function to test for structure members.
|
||||||
def CheckMember(context, include, decl, member, include_quotes="<>"):
|
def CheckMember(context, include, decl, member, include_quotes="<>"):
|
||||||
context.Message("Checking for member %s in %s..." %
|
context.Message("Checking for member %s in %s..." % (member, decl))
|
||||||
(member, decl))
|
|
||||||
text = """
|
text = """
|
||||||
#include %(header)s
|
#include %(header)s
|
||||||
int main(){
|
int main(){
|
||||||
@@ -84,18 +86,21 @@ int main(){
|
|||||||
(void)test.%(member)s;
|
(void)test.%(member)s;
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
""" % { "header" : include_quotes[0] + include + include_quotes[1],
|
""" % {
|
||||||
"decl" : decl,
|
"header": include_quotes[0] + include + include_quotes[1],
|
||||||
"member" : member,
|
"decl": decl,
|
||||||
}
|
"member": member,
|
||||||
|
}
|
||||||
|
|
||||||
ret = context.TryCompile(text, extension=".cc")
|
ret = context.TryCompile(text, extension=".cc")
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def CheckPythonLib(context):
|
def CheckPythonLib(context):
|
||||||
context.Message('Checking Python version... ')
|
context.Message("Checking Python version... ")
|
||||||
ret = context.TryRun(r"""
|
ret = context.TryRun(
|
||||||
|
r"""
|
||||||
#include <pybind11/embed.h>
|
#include <pybind11/embed.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -107,21 +112,24 @@ main(int argc, char **argv) {
|
|||||||
"sys.stdout.write('%i.%i.%i' % (vi.major, vi.minor, vi.micro));\n");
|
"sys.stdout.write('%i.%i.%i' % (vi.major, vi.minor, vi.micro));\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
""", extension=".cc")
|
""",
|
||||||
|
extension=".cc",
|
||||||
|
)
|
||||||
context.Result(ret[1] if ret[0] == 1 else 0)
|
context.Result(ret[1] if ret[0] == 1 else 0)
|
||||||
if ret[0] == 0:
|
if ret[0] == 0:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return tuple(map(int, ret[1].split(".")))
|
return tuple(map(int, ret[1].split(".")))
|
||||||
|
|
||||||
|
|
||||||
def CheckPkgConfig(context, pkgs, *args):
|
def CheckPkgConfig(context, pkgs, *args):
|
||||||
if not SCons.Util.is_List(pkgs):
|
if not SCons.Util.is_List(pkgs):
|
||||||
pkgs = [pkgs]
|
pkgs = [pkgs]
|
||||||
assert(pkgs)
|
assert pkgs
|
||||||
|
|
||||||
for pkg in pkgs:
|
for pkg in pkgs:
|
||||||
context.Message('Checking for pkg-config package %s... ' % pkg)
|
context.Message("Checking for pkg-config package %s... " % pkg)
|
||||||
ret = context.TryAction('pkg-config %s' % pkg)[0]
|
ret = context.TryAction("pkg-config %s" % pkg)[0]
|
||||||
if not ret:
|
if not ret:
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
continue
|
continue
|
||||||
@@ -129,7 +137,7 @@ def CheckPkgConfig(context, pkgs, *args):
|
|||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
cmd = ' '.join(['pkg-config'] + list(args) + [pkg])
|
cmd = " ".join(["pkg-config"] + list(args) + [pkg])
|
||||||
try:
|
try:
|
||||||
context.env.ParseConfig(cmd)
|
context.env.ParseConfig(cmd)
|
||||||
ret = 1
|
ret = 1
|
||||||
@@ -141,20 +149,25 @@ def CheckPkgConfig(context, pkgs, *args):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def Configure(env, *args, **kwargs):
|
def Configure(env, *args, **kwargs):
|
||||||
kwargs.setdefault('conf_dir',
|
kwargs.setdefault(
|
||||||
os.path.join(env['GEM5BUILD'], 'scons_config'))
|
"conf_dir", os.path.join(env["GEM5BUILD"], "scons_config")
|
||||||
kwargs.setdefault('log_file',
|
)
|
||||||
os.path.join(env['GEM5BUILD'], 'scons_config.log'))
|
kwargs.setdefault(
|
||||||
kwargs.setdefault('custom_tests', {})
|
"log_file", os.path.join(env["GEM5BUILD"], "scons_config.log")
|
||||||
kwargs['custom_tests'].update({
|
)
|
||||||
'CheckCxxFlag' : CheckCxxFlag,
|
kwargs.setdefault("custom_tests", {})
|
||||||
'CheckLinkFlag' : CheckLinkFlag,
|
kwargs["custom_tests"].update(
|
||||||
'CheckMember' : CheckMember,
|
{
|
||||||
'CheckPkgConfig' : CheckPkgConfig,
|
"CheckCxxFlag": CheckCxxFlag,
|
||||||
'CheckPythonLib' : CheckPythonLib,
|
"CheckLinkFlag": CheckLinkFlag,
|
||||||
})
|
"CheckMember": CheckMember,
|
||||||
|
"CheckPkgConfig": CheckPkgConfig,
|
||||||
|
"CheckPythonLib": CheckPythonLib,
|
||||||
|
}
|
||||||
|
)
|
||||||
conf = SCons.Script.Configure(env, *args, **kwargs)
|
conf = SCons.Script.Configure(env, *args, **kwargs)
|
||||||
|
|
||||||
# Recent versions of scons substitute a "Null" object for Configure()
|
# Recent versions of scons substitute a "Null" object for Configure()
|
||||||
@@ -163,14 +176,17 @@ def Configure(env, *args, **kwargs):
|
|||||||
# breaking all our configuration checks. We replace it with our own
|
# breaking all our configuration checks. We replace it with our own
|
||||||
# more optimistic null object that returns True instead.
|
# more optimistic null object that returns True instead.
|
||||||
if not conf:
|
if not conf:
|
||||||
|
|
||||||
def NullCheck(*args, **kwargs):
|
def NullCheck(*args, **kwargs):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class NullConf:
|
class NullConf:
|
||||||
def __init__(self, env):
|
def __init__(self, env):
|
||||||
self.env = env
|
self.env = env
|
||||||
|
|
||||||
def Finish(self):
|
def Finish(self):
|
||||||
return self.env
|
return self.env
|
||||||
|
|
||||||
def __getattr__(self, mname):
|
def __getattr__(self, mname):
|
||||||
return NullCheck
|
return NullCheck
|
||||||
|
|
||||||
|
|||||||
@@ -42,56 +42,76 @@ import os
|
|||||||
|
|
||||||
from gem5_python_paths import extra_python_paths
|
from gem5_python_paths import extra_python_paths
|
||||||
|
|
||||||
|
|
||||||
def EnvDefaults(env):
|
def EnvDefaults(env):
|
||||||
# export TERM so that clang reports errors in color
|
# export TERM so that clang reports errors in color
|
||||||
use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH',
|
use_vars = set(
|
||||||
'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PROTOC',
|
[
|
||||||
'PYTHONPATH', 'RANLIB', 'TERM', 'PYTHON_CONFIG',
|
"AS",
|
||||||
'CCFLAGS_EXTRA', 'GEM5PY_CCFLAGS_EXTRA',
|
"AR",
|
||||||
'GEM5PY_LINKFLAGS_EXTRA', 'LINKFLAGS_EXTRA', 'LANG'])
|
"CC",
|
||||||
|
"CXX",
|
||||||
|
"HOME",
|
||||||
|
"LD_LIBRARY_PATH",
|
||||||
|
"LIBRARY_PATH",
|
||||||
|
"PATH",
|
||||||
|
"PKG_CONFIG_PATH",
|
||||||
|
"PROTOC",
|
||||||
|
"PYTHONPATH",
|
||||||
|
"RANLIB",
|
||||||
|
"TERM",
|
||||||
|
"PYTHON_CONFIG",
|
||||||
|
"CCFLAGS_EXTRA",
|
||||||
|
"GEM5PY_CCFLAGS_EXTRA",
|
||||||
|
"GEM5PY_LINKFLAGS_EXTRA",
|
||||||
|
"LINKFLAGS_EXTRA",
|
||||||
|
"LANG",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
use_prefixes = [
|
use_prefixes = [
|
||||||
"ASAN_", # address sanitizer symbolizer path and settings
|
"ASAN_", # address sanitizer symbolizer path and settings
|
||||||
"CCACHE_", # ccache (caching compiler wrapper) configuration
|
"CCACHE_", # ccache (caching compiler wrapper) configuration
|
||||||
"CCC_", # clang static analyzer configuration
|
"CCC_", # clang static analyzer configuration
|
||||||
"DISTCC_", # distcc (distributed compiler wrapper) config
|
"DISTCC_", # distcc (distributed compiler wrapper) config
|
||||||
"INCLUDE_SERVER_", # distcc pump server settings
|
"INCLUDE_SERVER_", # distcc pump server settings
|
||||||
"M5", # M5 configuration (e.g., path to kernels)
|
"M5", # M5 configuration (e.g., path to kernels)
|
||||||
"NIX_", # wrapped binaries if using nix package manager
|
"NIX_", # wrapped binaries if using nix package manager
|
||||||
]
|
]
|
||||||
|
|
||||||
for key,val in sorted(os.environ.items()):
|
for key, val in sorted(os.environ.items()):
|
||||||
if key in use_vars or \
|
if key in use_vars or any(
|
||||||
any([key.startswith(prefix) for prefix in use_prefixes]):
|
[key.startswith(prefix) for prefix in use_prefixes]
|
||||||
env['ENV'][key] = val
|
):
|
||||||
|
env["ENV"][key] = val
|
||||||
|
|
||||||
# These variables from the environment override/become SCons variables,
|
# These variables from the environment override/become SCons variables,
|
||||||
# with a default if they weren't in the host environment.
|
# with a default if they weren't in the host environment.
|
||||||
var_overrides = {
|
var_overrides = {
|
||||||
'CC': env['CC'],
|
"CC": env["CC"],
|
||||||
'CXX': env['CXX'],
|
"CXX": env["CXX"],
|
||||||
'PROTOC': 'protoc',
|
"PROTOC": "protoc",
|
||||||
'PYTHON_CONFIG': [ 'python3-config', 'python-config' ],
|
"PYTHON_CONFIG": ["python3-config", "python-config"],
|
||||||
'CCFLAGS_EXTRA': '',
|
"CCFLAGS_EXTRA": "",
|
||||||
'GEM5PY_CCFLAGS_EXTRA': '',
|
"GEM5PY_CCFLAGS_EXTRA": "",
|
||||||
'GEM5PY_LINKFLAGS_EXTRA': '',
|
"GEM5PY_LINKFLAGS_EXTRA": "",
|
||||||
'LINKFLAGS_EXTRA': '',
|
"LINKFLAGS_EXTRA": "",
|
||||||
}
|
}
|
||||||
for key,default in var_overrides.items():
|
for key, default in var_overrides.items():
|
||||||
env[key] = env['ENV'].get(key, default)
|
env[key] = env["ENV"].get(key, default)
|
||||||
|
|
||||||
# Tell scons to avoid implicit command dependencies to avoid issues
|
# Tell scons to avoid implicit command dependencies to avoid issues
|
||||||
# with the param wrappes being compiled twice (see
|
# with the param wrappes being compiled twice (see
|
||||||
# https://github.com/SCons/scons/issues/2811
|
# https://github.com/SCons/scons/issues/2811
|
||||||
env['IMPLICIT_COMMAND_DEPENDENCIES'] = 0
|
env["IMPLICIT_COMMAND_DEPENDENCIES"] = 0
|
||||||
env.Decider('MD5-timestamp')
|
env.Decider("MD5-timestamp")
|
||||||
|
|
||||||
# add useful python code PYTHONPATH so it can be used by subprocesses
|
# add useful python code PYTHONPATH so it can be used by subprocesses
|
||||||
# as well
|
# as well
|
||||||
env.AppendENVPath('PYTHONPATH', extra_python_paths)
|
env.AppendENVPath("PYTHONPATH", extra_python_paths)
|
||||||
|
|
||||||
# Default duplicate option is to use hard links, but this messes up
|
# Default duplicate option is to use hard links, but this messes up
|
||||||
# when you use emacs to edit a file in the target dir, as emacs moves
|
# when you use emacs to edit a file in the target dir, as emacs moves
|
||||||
# file to file~ then copies to file, breaking the link. Symbolic
|
# file to file~ then copies to file, breaking the link. Symbolic
|
||||||
# (soft) links work better.
|
# (soft) links work better.
|
||||||
env.SetOption('duplicate', 'soft-copy')
|
env.SetOption("duplicate", "soft-copy")
|
||||||
|
|||||||
@@ -47,8 +47,9 @@ import SCons.Script
|
|||||||
# When specifying a source file of some type, a set of tags can be
|
# When specifying a source file of some type, a set of tags can be
|
||||||
# specified for that file.
|
# specified for that file.
|
||||||
|
|
||||||
|
|
||||||
def tag_implies(env, tag, tag_list):
|
def tag_implies(env, tag, tag_list):
|
||||||
'''
|
"""
|
||||||
Associates a tag X to a list of tags which are implied by X.
|
Associates a tag X to a list of tags which are implied by X.
|
||||||
|
|
||||||
For example, assume:
|
For example, assume:
|
||||||
@@ -72,10 +73,10 @@ def tag_implies(env, tag, tag_list):
|
|||||||
|
|
||||||
So that any use of a tag will automatically include its transitive tags
|
So that any use of a tag will automatically include its transitive tags
|
||||||
after being resolved.
|
after being resolved.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
env.SetDefault(_tag_implies={})
|
env.SetDefault(_tag_implies={})
|
||||||
implications = env['_tag_implies']
|
implications = env["_tag_implies"]
|
||||||
|
|
||||||
if isinstance(tag_list, str):
|
if isinstance(tag_list, str):
|
||||||
tag_list = frozenset([tag_list])
|
tag_list = frozenset([tag_list])
|
||||||
@@ -95,21 +96,23 @@ def tag_implies(env, tag, tag_list):
|
|||||||
|
|
||||||
# Check if another tag depends on this tag. If so, add this tag's
|
# Check if another tag depends on this tag. If so, add this tag's
|
||||||
# implications to that tag.
|
# implications to that tag.
|
||||||
for t,implied in implications.items():
|
for t, implied in implications.items():
|
||||||
if tag in implied:
|
if tag in implied:
|
||||||
implications[t] |= implications[tag]
|
implications[t] |= implications[tag]
|
||||||
|
|
||||||
|
|
||||||
def TagImpliesTool(env):
|
def TagImpliesTool(env):
|
||||||
env.AddMethod(tag_implies, 'TagImplies')
|
env.AddMethod(tag_implies, "TagImplies")
|
||||||
|
|
||||||
|
|
||||||
def resolve_tags(env, tags):
|
def resolve_tags(env, tags):
|
||||||
'''
|
"""
|
||||||
Returns the complete set of tags implied (dependencies) by the
|
Returns the complete set of tags implied (dependencies) by the
|
||||||
supplied tags.
|
supplied tags.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
implications = env.SetDefault(_tag_implies={})
|
implications = env.SetDefault(_tag_implies={})
|
||||||
implications = env['_tag_implies']
|
implications = env["_tag_implies"]
|
||||||
|
|
||||||
if isinstance(tags, str):
|
if isinstance(tags, str):
|
||||||
tags = frozenset([tags])
|
tags = frozenset([tags])
|
||||||
@@ -122,53 +125,71 @@ def resolve_tags(env, tags):
|
|||||||
tags |= implications[tag]
|
tags |= implications[tag]
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
|
||||||
class SourceFilter(object):
|
class SourceFilter(object):
|
||||||
factories = {}
|
factories = {}
|
||||||
|
|
||||||
def __init__(self, predicate):
|
def __init__(self, predicate):
|
||||||
self.predicate = predicate
|
self.predicate = predicate
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
return SourceFilter(lambda env, tags: self.predicate(env, tags) or
|
return SourceFilter(
|
||||||
other.predicate(env, tags))
|
lambda env, tags: self.predicate(env, tags)
|
||||||
|
or other.predicate(env, tags)
|
||||||
|
)
|
||||||
|
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
return SourceFilter(lambda env, tags: self.predicate(env, tags) and
|
return SourceFilter(
|
||||||
other.predicate(env, tags))
|
lambda env, tags: self.predicate(env, tags)
|
||||||
|
and other.predicate(env, tags)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def with_any_tags(*tags):
|
def with_any_tags(*tags):
|
||||||
'''Return a list of sources with any of the supplied tags.'''
|
"""Return a list of sources with any of the supplied tags."""
|
||||||
return SourceFilter(lambda env, stags: \
|
return SourceFilter(
|
||||||
len(resolve_tags(env, tags) & stags) > 0)
|
lambda env, stags: len(resolve_tags(env, tags) & stags) > 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def with_all_tags(*tags):
|
def with_all_tags(*tags):
|
||||||
'''Return a list of sources with all of the supplied tags.'''
|
"""Return a list of sources with all of the supplied tags."""
|
||||||
return SourceFilter(lambda env, stags: resolve_tags(env, tags) <= stags)
|
return SourceFilter(lambda env, stags: resolve_tags(env, tags) <= stags)
|
||||||
|
|
||||||
|
|
||||||
def with_tag(tag):
|
def with_tag(tag):
|
||||||
'''Return a list of sources with the supplied tag.'''
|
"""Return a list of sources with the supplied tag."""
|
||||||
return with_any_tags(*[tag])
|
return with_any_tags(*[tag])
|
||||||
|
|
||||||
|
|
||||||
def without_tags(*tags):
|
def without_tags(*tags):
|
||||||
'''Return a list of sources without any of the supplied tags.'''
|
"""Return a list of sources without any of the supplied tags."""
|
||||||
return SourceFilter(lambda env, stags: \
|
return SourceFilter(
|
||||||
len(resolve_tags(env, tags) & stags) == 0)
|
lambda env, stags: len(resolve_tags(env, tags) & stags) == 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def without_tag(tag):
|
def without_tag(tag):
|
||||||
'''Return a list of sources without the supplied tag.'''
|
"""Return a list of sources without the supplied tag."""
|
||||||
return without_tags(*[tag])
|
return without_tags(*[tag])
|
||||||
|
|
||||||
SourceFilter.factories.update({
|
|
||||||
'with_any_tags': with_any_tags,
|
SourceFilter.factories.update(
|
||||||
'with_all_tags': with_all_tags,
|
{
|
||||||
'with_tag': with_tag,
|
"with_any_tags": with_any_tags,
|
||||||
'without_tags': without_tags,
|
"with_all_tags": with_all_tags,
|
||||||
'without_tag': without_tag,
|
"with_tag": with_tag,
|
||||||
})
|
"without_tags": without_tags,
|
||||||
|
"without_tag": without_tag,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SourceList(list):
|
class SourceList(list):
|
||||||
def apply_filter(self, env, f):
|
def apply_filter(self, env, f):
|
||||||
def match(source):
|
def match(source):
|
||||||
return f.predicate(env, resolve_tags(env, source.tags))
|
return f.predicate(env, resolve_tags(env, source.tags))
|
||||||
|
|
||||||
return SourceList(filter(match, self))
|
return SourceList(filter(match, self))
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
@@ -179,33 +200,38 @@ class SourceList(list):
|
|||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(env, *args, **kwargs):
|
def wrapper(env, *args, **kwargs):
|
||||||
return self.apply_filter(env, func(*args, **kwargs))
|
return self.apply_filter(env, func(*args, **kwargs))
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class SourceMeta(type):
|
class SourceMeta(type):
|
||||||
'''Meta class for source files that keeps track of all files of a
|
"""Meta class for source files that keeps track of all files of a
|
||||||
particular type.'''
|
particular type."""
|
||||||
|
|
||||||
def __init__(cls, name, bases, dict):
|
def __init__(cls, name, bases, dict):
|
||||||
super(SourceMeta, cls).__init__(name, bases, dict)
|
super(SourceMeta, cls).__init__(name, bases, dict)
|
||||||
cls.all = SourceList()
|
cls.all = SourceList()
|
||||||
|
|
||||||
|
|
||||||
class SourceItem(object, metaclass=SourceMeta):
|
class SourceItem(object, metaclass=SourceMeta):
|
||||||
'''Base object that encapsulates the notion of a source component for
|
"""Base object that encapsulates the notion of a source component for
|
||||||
gem5. This specifies a set of tags which help group components into groups
|
gem5. This specifies a set of tags which help group components into groups
|
||||||
based on arbitrary properties.'''
|
based on arbitrary properties."""
|
||||||
|
|
||||||
def __init__(self, source, tags=None, add_tags=None, append=None):
|
def __init__(self, source, tags=None, add_tags=None, append=None):
|
||||||
self.source = source
|
self.source = source
|
||||||
|
|
||||||
if tags is None:
|
if tags is None:
|
||||||
tags='gem5 lib'
|
tags = "gem5 lib"
|
||||||
if isinstance(tags, str):
|
if isinstance(tags, str):
|
||||||
tags = { tags }
|
tags = {tags}
|
||||||
if not isinstance(tags, set):
|
if not isinstance(tags, set):
|
||||||
tags = set(tags)
|
tags = set(tags)
|
||||||
self.tags = tags.copy()
|
self.tags = tags.copy()
|
||||||
|
|
||||||
if add_tags:
|
if add_tags:
|
||||||
if isinstance(add_tags, str):
|
if isinstance(add_tags, str):
|
||||||
add_tags = { add_tags }
|
add_tags = {add_tags}
|
||||||
if not isinstance(add_tags, set):
|
if not isinstance(add_tags, set):
|
||||||
add_tags = set(add_tags)
|
add_tags = set(add_tags)
|
||||||
self.tags |= add_tags
|
self.tags |= add_tags
|
||||||
@@ -216,10 +242,11 @@ class SourceItem(object, metaclass=SourceMeta):
|
|||||||
if issubclass(base, SourceItem):
|
if issubclass(base, SourceItem):
|
||||||
base.all.append(self)
|
base.all.append(self)
|
||||||
|
|
||||||
|
|
||||||
class SourceFile(SourceItem):
|
class SourceFile(SourceItem):
|
||||||
'''Base object that encapsulates the notion of a source file.
|
"""Base object that encapsulates the notion of a source file.
|
||||||
This includes, the source node, target node, various manipulations
|
This includes, the source node, target node, various manipulations
|
||||||
of those.'''
|
of those."""
|
||||||
|
|
||||||
def __init__(self, source, tags=None, add_tags=None, append=None):
|
def __init__(self, source, tags=None, add_tags=None, append=None):
|
||||||
super().__init__(source, tags=tags, add_tags=add_tags, append=append)
|
super().__init__(source, tags=tags, add_tags=add_tags, append=append)
|
||||||
@@ -243,6 +270,15 @@ class SourceFile(SourceItem):
|
|||||||
return env.SharedObject(self.tnode)
|
return env.SharedObject(self.tnode)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['TagImpliesTool', 'SourceFilter', 'SourceList', 'SourceFile',
|
__all__ = [
|
||||||
'SourceItem', 'with_any_tags', 'with_all_tags', 'with_tag',
|
"TagImpliesTool",
|
||||||
'without_tags', 'without_tag']
|
"SourceFilter",
|
||||||
|
"SourceList",
|
||||||
|
"SourceFile",
|
||||||
|
"SourceItem",
|
||||||
|
"with_any_tags",
|
||||||
|
"with_all_tags",
|
||||||
|
"with_tag",
|
||||||
|
"without_tags",
|
||||||
|
"without_tag",
|
||||||
|
]
|
||||||
|
|||||||
@@ -46,12 +46,15 @@ import SCons.Script
|
|||||||
|
|
||||||
import m5.util.terminal
|
import m5.util.terminal
|
||||||
|
|
||||||
|
|
||||||
def ignore_style():
|
def ignore_style():
|
||||||
"""Determine whether we should ignore style checks"""
|
"""Determine whether we should ignore style checks"""
|
||||||
return SCons.Script.GetOption('ignore_style') or not sys.stdin.isatty()
|
return SCons.Script.GetOption("ignore_style") or not sys.stdin.isatty()
|
||||||
|
|
||||||
|
|
||||||
def get_termcap():
|
def get_termcap():
|
||||||
return m5.util.terminal.get_termcap(SCons.Script.GetOption('use_colors'))
|
return m5.util.terminal.get_termcap(SCons.Script.GetOption("use_colors"))
|
||||||
|
|
||||||
|
|
||||||
def readCommand(cmd, **kwargs):
|
def readCommand(cmd, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -68,13 +71,13 @@ def readCommand(cmd, **kwargs):
|
|||||||
if isinstance(cmd, str):
|
if isinstance(cmd, str):
|
||||||
cmd = cmd.split()
|
cmd = cmd.split()
|
||||||
|
|
||||||
no_exception = 'exception' in kwargs
|
no_exception = "exception" in kwargs
|
||||||
exception = kwargs.pop('exception', None)
|
exception = kwargs.pop("exception", None)
|
||||||
|
|
||||||
kwargs.setdefault('shell', False)
|
kwargs.setdefault("shell", False)
|
||||||
kwargs.setdefault('stdout', PIPE)
|
kwargs.setdefault("stdout", PIPE)
|
||||||
kwargs.setdefault('stderr', STDOUT)
|
kwargs.setdefault("stderr", STDOUT)
|
||||||
kwargs.setdefault('close_fds', True)
|
kwargs.setdefault("close_fds", True)
|
||||||
try:
|
try:
|
||||||
subp = Popen(cmd, **kwargs)
|
subp = Popen(cmd, **kwargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -82,20 +85,23 @@ def readCommand(cmd, **kwargs):
|
|||||||
return -1, exception
|
return -1, exception
|
||||||
raise
|
raise
|
||||||
|
|
||||||
output = subp.communicate()[0].decode('utf-8')
|
output = subp.communicate()[0].decode("utf-8")
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def compareVersions(v1, v2):
|
def compareVersions(v1, v2):
|
||||||
"""helper function: compare arrays or strings of version numbers.
|
"""helper function: compare arrays or strings of version numbers.
|
||||||
E.g., compare_version((1,3,25), (1,4,1)')
|
E.g., compare_version((1,3,25), (1,4,1)')
|
||||||
returns -1, 0, 1 if v1 is <, ==, > v2
|
returns -1, 0, 1 if v1 is <, ==, > v2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def make_version_list(v):
|
def make_version_list(v):
|
||||||
if isinstance(v, (list,tuple)):
|
if isinstance(v, (list, tuple)):
|
||||||
return v
|
return v
|
||||||
elif isinstance(v, str):
|
elif isinstance(v, str):
|
||||||
return list(map(lambda x: int(re.match('\d+', x).group()),
|
return list(
|
||||||
v.split('.')))
|
map(lambda x: int(re.match("\d+", x).group()), v.split("."))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
@@ -104,8 +110,10 @@ def compareVersions(v1, v2):
|
|||||||
|
|
||||||
# Compare corresponding elements of lists
|
# Compare corresponding elements of lists
|
||||||
# The shorter list is filled with 0 till the lists have the same length
|
# The shorter list is filled with 0 till the lists have the same length
|
||||||
for n1,n2 in itertools.zip_longest(v1, v2, fillvalue=0):
|
for n1, n2 in itertools.zip_longest(v1, v2, fillvalue=0):
|
||||||
if n1 < n2: return -1
|
if n1 < n2:
|
||||||
if n1 > n2: return 1
|
return -1
|
||||||
|
if n1 > n2:
|
||||||
|
return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -44,10 +44,12 @@ from __future__ import print_function
|
|||||||
try:
|
try:
|
||||||
EnsureSConsVersion(3, 0, 0)
|
EnsureSConsVersion(3, 0, 0)
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
print("""
|
print(
|
||||||
|
"""
|
||||||
For more details, see:
|
For more details, see:
|
||||||
http://gem5.org/documentation/general_docs/building
|
http://gem5.org/documentation/general_docs/building
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +57,8 @@ For more details, see:
|
|||||||
try:
|
try:
|
||||||
EnsurePythonVersion(3, 6)
|
EnsurePythonVersion(3, 6)
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
print("""\033[93m
|
print(
|
||||||
|
"""\033[93m
|
||||||
Python 3 is now required.
|
Python 3 is now required.
|
||||||
|
|
||||||
The following are steps to compile gem5 in Python 3 environment,
|
The following are steps to compile gem5 in Python 3 environment,
|
||||||
@@ -81,7 +84,8 @@ Python 3 environment,
|
|||||||
|
|
||||||
(Optional) For convenience reasons, you can set up an alias for the Python3 \
|
(Optional) For convenience reasons, you can set up an alias for the Python3 \
|
||||||
scons phrase in your environment. \033[0m
|
scons phrase in your environment. \033[0m
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
from gem5_python_paths import extra_python_paths
|
from gem5_python_paths import extra_python_paths
|
||||||
|
|||||||
@@ -50,15 +50,20 @@ to ensure that your code follows gem5's style rules on git commit.
|
|||||||
This script will now install the hook in your .git/hooks/ directory.
|
This script will now install the hook in your .git/hooks/ directory.
|
||||||
Press enter to continue, or ctrl-c to abort: """
|
Press enter to continue, or ctrl-c to abort: """
|
||||||
|
|
||||||
|
|
||||||
def install_style_hooks(env):
|
def install_style_hooks(env):
|
||||||
try:
|
try:
|
||||||
gitdir = env.Dir(gem5_scons.util.readCommand(
|
gitdir = env.Dir(
|
||||||
["git", "rev-parse", "--git-dir"]).strip("\n"))
|
gem5_scons.util.readCommand(
|
||||||
|
["git", "rev-parse", "--git-dir"]
|
||||||
|
).strip("\n")
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Warning: Failed to find git repo directory: %s" % e)
|
print("Warning: Failed to find git repo directory: %s" % e)
|
||||||
return
|
return
|
||||||
|
|
||||||
git_hooks = gitdir.Dir("hooks")
|
git_hooks = gitdir.Dir("hooks")
|
||||||
|
|
||||||
def hook_exists(hook_name):
|
def hook_exists(hook_name):
|
||||||
hook = git_hooks.File(hook_name)
|
hook = git_hooks.File(hook_name)
|
||||||
return hook.exists()
|
return hook.exists()
|
||||||
@@ -66,8 +71,9 @@ def install_style_hooks(env):
|
|||||||
def hook_install(hook_name, script):
|
def hook_install(hook_name, script):
|
||||||
hook = git_hooks.File(hook_name)
|
hook = git_hooks.File(hook_name)
|
||||||
if hook.exists():
|
if hook.exists():
|
||||||
print("Warning: Can't install %s, hook already exists." %
|
print(
|
||||||
hook_name)
|
"Warning: Can't install %s, hook already exists." % hook_name
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if hook.islink():
|
if hook.islink():
|
||||||
@@ -78,15 +84,17 @@ def install_style_hooks(env):
|
|||||||
os.mkdir(git_hooks.get_abspath())
|
os.mkdir(git_hooks.get_abspath())
|
||||||
git_hooks.clear()
|
git_hooks.clear()
|
||||||
|
|
||||||
abs_symlink_hooks = git_hooks.islink() and \
|
abs_symlink_hooks = git_hooks.islink() and os.path.isabs(
|
||||||
os.path.isabs(os.readlink(git_hooks.get_abspath()))
|
os.readlink(git_hooks.get_abspath())
|
||||||
|
)
|
||||||
|
|
||||||
# Use a relative symlink if the hooks live in the source directory,
|
# Use a relative symlink if the hooks live in the source directory,
|
||||||
# and the hooks directory is not a symlink to an absolute path.
|
# and the hooks directory is not a symlink to an absolute path.
|
||||||
if hook.is_under(env.Dir("#")) and not abs_symlink_hooks:
|
if hook.is_under(env.Dir("#")) and not abs_symlink_hooks:
|
||||||
script_path = os.path.relpath(
|
script_path = os.path.relpath(
|
||||||
os.path.realpath(script.get_abspath()),
|
os.path.realpath(script.get_abspath()),
|
||||||
os.path.realpath(hook.Dir(".").get_abspath()))
|
os.path.realpath(hook.Dir(".").get_abspath()),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
script_path = script.get_abspath()
|
script_path = script.get_abspath()
|
||||||
|
|
||||||
@@ -99,8 +107,8 @@ def install_style_hooks(env):
|
|||||||
if hook_exists("pre-commit") and hook_exists("commit-msg"):
|
if hook_exists("pre-commit") and hook_exists("commit-msg"):
|
||||||
return
|
return
|
||||||
|
|
||||||
print(git_style_message, end=' ')
|
print(git_style_message, end=" ")
|
||||||
if SCons.Script.GetOption('install_hooks'):
|
if SCons.Script.GetOption("install_hooks"):
|
||||||
print("Installing revision control hooks automatically.")
|
print("Installing revision control hooks automatically.")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -115,9 +123,11 @@ def install_style_hooks(env):
|
|||||||
hook_install("pre-commit", git_style_script)
|
hook_install("pre-commit", git_style_script)
|
||||||
hook_install("commit-msg", git_msg_script)
|
hook_install("commit-msg", git_msg_script)
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if exists(env) and not gem5_scons.util.ignore_style():
|
if exists(env) and not gem5_scons.util.ignore_style():
|
||||||
install_style_hooks(env)
|
install_style_hooks(env)
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Entry('#.git').exists()
|
return env.Entry("#.git").exists()
|
||||||
|
|||||||
@@ -865,7 +865,7 @@ class FastModelGIC(BaseGic):
|
|||||||
return [int(r.split("=")[1], 16) for r in redists]
|
return [int(r.split("=")[1], 16) for r in redists]
|
||||||
|
|
||||||
def get_addr_ranges(self):
|
def get_addr_ranges(self):
|
||||||
""" Return address ranges that should be served by this GIC """
|
"""Return address ranges that should be served by this GIC"""
|
||||||
sc_gic = self.sc_gic
|
sc_gic = self.sc_gic
|
||||||
gic_frame_size = 0x10000
|
gic_frame_size = 0x10000
|
||||||
# Add range of distributor
|
# Add range of distributor
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ import _m5.arm_fast_model
|
|||||||
|
|
||||||
def set_armlmd_license_file(force=False):
|
def set_armlmd_license_file(force=False):
|
||||||
"""Set the ARMLMD_LICENSE_FILE environment variable. If "force" is
|
"""Set the ARMLMD_LICENSE_FILE environment variable. If "force" is
|
||||||
False, then it will only be set if it wasn't already set in the
|
False, then it will only be set if it wasn't already set in the
|
||||||
environment. The value it's set to is the one gem5 was built with.
|
environment. The value it's set to is the one gem5 was built with.
|
||||||
"""
|
"""
|
||||||
key = "ARMLMD_LICENSE_FILE"
|
key = "ARMLMD_LICENSE_FILE"
|
||||||
license_file = buildEnv[key]
|
license_file = buildEnv[key]
|
||||||
if force or key not in os.environ:
|
if force or key not in os.environ:
|
||||||
|
|||||||
@@ -35,4 +35,3 @@
|
|||||||
// ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
// ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
||||||
// IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
|
// IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
// DAMAGES.
|
// DAMAGES.
|
||||||
|
|
||||||
|
|||||||
@@ -43,4 +43,3 @@
|
|||||||
|
|
||||||
|
|
||||||
Aarch64::aarch64();
|
Aarch64::aarch64();
|
||||||
|
|
||||||
|
|||||||
@@ -132,4 +132,3 @@ format DataOp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,4 +56,3 @@ def format ArmBkptHlt() {{
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -1154,4 +1154,3 @@ def format Thumb16MemLit() {{
|
|||||||
}
|
}
|
||||||
''' % loadImmClassName(False, True, False)
|
''' % loadImmClassName(False, True, False)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -202,4 +202,3 @@ def format PredImmOp(code, *opt_flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = PredOpExecute.subst(iop)
|
exec_output = PredOpExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -167,4 +167,3 @@ let {{
|
|||||||
cryptoRegRegRegInst("sha256su1", "SHA256SU164", "SimdShaSigma3Op",
|
cryptoRegRegRegInst("sha256su1", "SHA256SU164", "SimdShaSigma3Op",
|
||||||
sha2_enabled, sha256_su1Code)
|
sha2_enabled, sha256_su1Code)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -229,4 +229,3 @@ let {{
|
|||||||
raise Exception("Illegal combination of post and writeback")
|
raise Exception("Illegal combination of post and writeback")
|
||||||
return base
|
return base
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -186,5 +186,3 @@ def template BranchTarget {{
|
|||||||
return std::unique_ptr<PCStateBase>{pc_ptr};
|
return std::unique_ptr<PCStateBase>{pc_ptr};
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1288,4 +1288,3 @@ def template LoadImmConstructor {{
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -112,12 +112,11 @@ class Template(object):
|
|||||||
|
|
||||||
operands = SubOperandList(self.parser, compositeCode, d.operands)
|
operands = SubOperandList(self.parser, compositeCode, d.operands)
|
||||||
|
|
||||||
myDict["reg_idx_arr_decl"] = (
|
myDict[
|
||||||
"RegId srcRegIdxArr[%d]; RegId destRegIdxArr[%d]"
|
"reg_idx_arr_decl"
|
||||||
% (
|
] = "RegId srcRegIdxArr[%d]; RegId destRegIdxArr[%d]" % (
|
||||||
d.operands.numSrcRegs + d.srcRegIdxPadding,
|
d.operands.numSrcRegs + d.srcRegIdxPadding,
|
||||||
d.operands.numDestRegs + d.destRegIdxPadding,
|
d.operands.numDestRegs + d.destRegIdxPadding,
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# The reinterpret casts are largely because an array with a known
|
# The reinterpret casts are largely because an array with a known
|
||||||
@@ -960,15 +959,15 @@ class ISAParser(Grammar):
|
|||||||
# They are all processed as they are seen.
|
# They are all processed as they are seen.
|
||||||
def p_def_or_output(self, t):
|
def p_def_or_output(self, t):
|
||||||
"""def_or_output : name_decl
|
"""def_or_output : name_decl
|
||||||
| def_format
|
| def_format
|
||||||
| def_bitfield
|
| def_bitfield
|
||||||
| def_bitfield_struct
|
| def_bitfield_struct
|
||||||
| def_template
|
| def_template
|
||||||
| def_operand_types
|
| def_operand_types
|
||||||
| def_operands
|
| def_operands
|
||||||
| output
|
| output
|
||||||
| global_let
|
| global_let
|
||||||
| split"""
|
| split"""
|
||||||
|
|
||||||
# Utility function used by both invocations of splitting - explicit
|
# Utility function used by both invocations of splitting - explicit
|
||||||
# 'split' keyword and split() function inside "let {{ }};" blocks.
|
# 'split' keyword and split() function inside "let {{ }};" blocks.
|
||||||
@@ -992,8 +991,8 @@ class ISAParser(Grammar):
|
|||||||
|
|
||||||
def p_output_type(self, t):
|
def p_output_type(self, t):
|
||||||
"""output_type : DECODER
|
"""output_type : DECODER
|
||||||
| HEADER
|
| HEADER
|
||||||
| EXEC"""
|
| EXEC"""
|
||||||
t[0] = t[1]
|
t[0] = t[1]
|
||||||
|
|
||||||
# ISA name declaration looks like "namespace <foo>;"
|
# ISA name declaration looks like "namespace <foo>;"
|
||||||
@@ -1175,7 +1174,7 @@ del wrap
|
|||||||
|
|
||||||
def p_param_list_1(self, t):
|
def p_param_list_1(self, t):
|
||||||
"""param_list : positional_param_list
|
"""param_list : positional_param_list
|
||||||
| nonpositional_param_list"""
|
| nonpositional_param_list"""
|
||||||
t[0] = t[1]
|
t[0] = t[1]
|
||||||
|
|
||||||
def p_positional_param_list_0(self, t):
|
def p_positional_param_list_0(self, t):
|
||||||
@@ -1196,7 +1195,7 @@ del wrap
|
|||||||
|
|
||||||
def p_nonpositional_param_list_1(self, t):
|
def p_nonpositional_param_list_1(self, t):
|
||||||
"""nonpositional_param_list : keyword_param_list
|
"""nonpositional_param_list : keyword_param_list
|
||||||
| excess_args_param"""
|
| excess_args_param"""
|
||||||
t[0] = t[1]
|
t[0] = t[1]
|
||||||
|
|
||||||
def p_keyword_param_list_0(self, t):
|
def p_keyword_param_list_0(self, t):
|
||||||
@@ -1360,7 +1359,7 @@ StaticInstPtr
|
|||||||
t[0] = ["default:"]
|
t[0] = ["default:"]
|
||||||
|
|
||||||
def prep_int_lit_case_label(self, lit):
|
def prep_int_lit_case_label(self, lit):
|
||||||
if lit >= 2 ** 32:
|
if lit >= 2**32:
|
||||||
return "case %#xULL: " % lit
|
return "case %#xULL: " % lit
|
||||||
else:
|
else:
|
||||||
return "case %#x: " % lit
|
return "case %#x: " % lit
|
||||||
@@ -1468,9 +1467,9 @@ StaticInstPtr
|
|||||||
#
|
#
|
||||||
def p_expr_0(self, t):
|
def p_expr_0(self, t):
|
||||||
"""expr : ID
|
"""expr : ID
|
||||||
| INTLIT
|
| INTLIT
|
||||||
| STRLIT
|
| STRLIT
|
||||||
| CODELIT"""
|
| CODELIT"""
|
||||||
t[0] = t[1]
|
t[0] = t[1]
|
||||||
|
|
||||||
def p_expr_1(self, t):
|
def p_expr_1(self, t):
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ def p_file(t):
|
|||||||
|
|
||||||
|
|
||||||
def p_opt_rom_or_macros_0(t):
|
def p_opt_rom_or_macros_0(t):
|
||||||
"opt_rom_or_macros : "
|
"opt_rom_or_macros :"
|
||||||
|
|
||||||
|
|
||||||
def p_opt_rom_or_macros_1(t):
|
def p_opt_rom_or_macros_1(t):
|
||||||
@@ -392,7 +392,7 @@ def p_rom_or_macros_1(t):
|
|||||||
|
|
||||||
def p_rom_or_macro_0(t):
|
def p_rom_or_macro_0(t):
|
||||||
"""rom_or_macro : rom_block
|
"""rom_or_macro : rom_block
|
||||||
| macroop_def"""
|
| macroop_def"""
|
||||||
|
|
||||||
|
|
||||||
# Defines a section of microcode that should go in the current ROM
|
# Defines a section of microcode that should go in the current ROM
|
||||||
@@ -466,20 +466,20 @@ def p_statement(t):
|
|||||||
# A statement can be a microop or an assembler directive
|
# A statement can be a microop or an assembler directive
|
||||||
def p_content_of_statement_0(t):
|
def p_content_of_statement_0(t):
|
||||||
"""content_of_statement : microop
|
"""content_of_statement : microop
|
||||||
| directive"""
|
| directive"""
|
||||||
t[0] = t[1]
|
t[0] = t[1]
|
||||||
|
|
||||||
|
|
||||||
# Ignore empty statements
|
# Ignore empty statements
|
||||||
def p_content_of_statement_1(t):
|
def p_content_of_statement_1(t):
|
||||||
"content_of_statement : "
|
"content_of_statement :"
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Statements are ended by newlines or a semi colon
|
# Statements are ended by newlines or a semi colon
|
||||||
def p_end_of_statement(t):
|
def p_end_of_statement(t):
|
||||||
"""end_of_statement : NEWLINE
|
"""end_of_statement : NEWLINE
|
||||||
| SEMI"""
|
| SEMI"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,4 +145,3 @@ output decoder {{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -2545,5 +2545,3 @@ decode OPCODE_HI default Unknown::unknown() {
|
|||||||
0x6: CP2Unimpl::sdc2();
|
0x6: CP2Unimpl::sdc2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -326,7 +326,3 @@ def format Jump(code, *opt_flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = BasicExecute.subst(iop)
|
exec_output = BasicExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -241,5 +241,3 @@ def format CP1Control(code, *flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = CP1Execute.subst(iop)
|
exec_output = CP1Execute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,3 @@ def format DspHiLoOp(code, *opt_flags) {{
|
|||||||
exec_output = DspHiLoExecute.subst(iop)
|
exec_output = DspHiLoExecute.subst(iop)
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -363,4 +363,3 @@ def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = BasicExecute.subst(iop)
|
exec_output = BasicExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -134,4 +134,3 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
|
|||||||
def format Nop() {{
|
def format Nop() {{
|
||||||
decode_block = 'return new Nop(\"\",machInst);\n'
|
decode_block = 'return new Nop(\"\",machInst);\n'
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -273,4 +273,3 @@ def format WarnUnimpl() {{
|
|||||||
iop = InstObjParams(name, 'WarnUnimplemented')
|
iop = InstObjParams(name, 'WarnUnimplemented')
|
||||||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -77,4 +77,3 @@ output exec {{
|
|||||||
def format Unknown() {{
|
def format Unknown() {{
|
||||||
decode_block = 'return new Unknown(machInst);\n'
|
decode_block = 'return new Unknown(machInst);\n'
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -141,4 +141,3 @@ def format WarnUnimpl() {{
|
|||||||
iop = InstObjParams(name, 'WarnUnimplemented')
|
iop = InstObjParams(name, 'WarnUnimplemented')
|
||||||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -82,4 +82,3 @@ output exec {{
|
|||||||
def format Unknown() {{
|
def format Unknown() {{
|
||||||
decode_block = 'return new Unknown(machInst);\n'
|
decode_block = 'return new Unknown(machInst);\n'
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -224,5 +224,3 @@ output decoder {{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,4 +45,4 @@
|
|||||||
<reg name="t5" bitsize="64" type="int"/>
|
<reg name="t5" bitsize="64" type="int"/>
|
||||||
<reg name="t6" bitsize="64" type="int"/>
|
<reg name="t6" bitsize="64" type="int"/>
|
||||||
<reg name="pc" bitsize="64" type="code_ptr"/>
|
<reg name="pc" bitsize="64" type="code_ptr"/>
|
||||||
</feature>
|
</feature>
|
||||||
|
|||||||
@@ -245,4 +245,4 @@
|
|||||||
<reg name="mucounteren" bitsize="64"/>
|
<reg name="mucounteren" bitsize="64"/>
|
||||||
<reg name="mscounteren" bitsize="64"/>
|
<reg name="mscounteren" bitsize="64"/>
|
||||||
<reg name="mhcounteren" bitsize="64"/> -->
|
<reg name="mhcounteren" bitsize="64"/> -->
|
||||||
</feature>
|
</feature>
|
||||||
|
|||||||
@@ -55,4 +55,4 @@
|
|||||||
<reg name="frm" bitsize="32" type="int" regnum="67"/>
|
<reg name="frm" bitsize="32" type="int" regnum="67"/>
|
||||||
<reg name="fcsr" bitsize="32" type="int" regnum="68"/>
|
<reg name="fcsr" bitsize="32" type="int" regnum="68"/>
|
||||||
<reg name="placeholder" bitsize="32" type="int" regnum="69"/>
|
<reg name="placeholder" bitsize="32" type="int" regnum="69"/>
|
||||||
</feature>
|
</feature>
|
||||||
|
|||||||
@@ -10,4 +10,4 @@
|
|||||||
<xi:include href="riscv-64bit-cpu.xml"/>
|
<xi:include href="riscv-64bit-cpu.xml"/>
|
||||||
<xi:include href="riscv-64bit-fpu.xml"/>
|
<xi:include href="riscv-64bit-fpu.xml"/>
|
||||||
<xi:include href="riscv-64bit-csr.xml"/>
|
<xi:include href="riscv-64bit-csr.xml"/>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -128,4 +128,4 @@ def bitfield M5FUNC <31:25>;
|
|||||||
def bitfield BIT24 <24>;
|
def bitfield BIT24 <24>;
|
||||||
def bitfield RNUM <23:20>;
|
def bitfield RNUM <23:20>;
|
||||||
def bitfield KFUNCT5 <29:25>;
|
def bitfield KFUNCT5 <29:25>;
|
||||||
def bitfield BS <31:30>;
|
def bitfield BS <31:30>;
|
||||||
|
|||||||
@@ -132,5 +132,3 @@ output exec {{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -187,4 +187,3 @@ def format BranchSplit(code=default_branch_code,
|
|||||||
decode_block) = doUncondBranch(name, Name,
|
decode_block) = doUncondBranch(name, Name,
|
||||||
"BranchSplit", code, annul_code, opt_flags)
|
"BranchSplit", code, annul_code, opt_flags)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,3 @@
|
|||||||
|
|
||||||
// Include the branch format
|
// Include the branch format
|
||||||
##include "branch.isa"
|
##include "branch.isa"
|
||||||
|
|
||||||
|
|||||||
@@ -162,4 +162,3 @@ def format SetHi(code, *opt_flags) {{
|
|||||||
exec_output = IntOpExecute.subst(iop)
|
exec_output = IntOpExecute.subst(iop)
|
||||||
decode_block = SetHiDecode.subst(iop)
|
decode_block = SetHiDecode.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -166,4 +166,3 @@ def format TwinLoad(code, *opt_flags) {{
|
|||||||
AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck,
|
AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck,
|
||||||
name, Name, "EXT_ASI", opt_flags)
|
name, Name, "EXT_ASI", opt_flags)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -174,5 +174,3 @@ def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
|
|||||||
decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
|
decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
|
||||||
name, Name, flags, ["IsStoreConditional"], postacc_code)
|
name, Name, flags, ["IsStoreConditional"], postacc_code)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -133,4 +133,3 @@ def format HPriv(code, check_tl=false, *opt_flags) {{
|
|||||||
doPrivFormat(code, check_code, name, Name, opt_flags,
|
doPrivFormat(code, check_code, name, Name, opt_flags,
|
||||||
check_tl=(check_tl != 'false'))
|
check_tl=(check_tl != 'false'))
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -40,4 +40,3 @@ def format WarnUnimpl() {{
|
|||||||
iop = InstObjParams(name, 'WarnUnimplemented')
|
iop = InstObjParams(name, 'WarnUnimplemented')
|
||||||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -85,4 +85,3 @@ def format CPUIDInst(code, *opt_flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = CPUIDExecute.subst(iop)
|
exec_output = CPUIDExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -54,4 +54,3 @@ def format M5InternalError(error_message) {{
|
|||||||
iop.message = error_message
|
iop.message = error_message
|
||||||
decode_block = ErrorDecode.subst(iop)
|
decode_block = ErrorDecode.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -122,4 +122,3 @@ def format MwaitInst(code, *opt_flags) {{
|
|||||||
exec_output += MwaitInitiateAcc.subst(iop)
|
exec_output += MwaitInitiateAcc.subst(iop)
|
||||||
exec_output += MwaitCompleteAcc.subst(iop)
|
exec_output += MwaitCompleteAcc.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -84,4 +84,3 @@ def format NopInst(*opt_flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = NopExecute.subst(iop)
|
exec_output = NopExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -88,4 +88,3 @@ def format SyscallInst(code, *opt_flags) {{
|
|||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = SyscallExecute.subst(iop)
|
exec_output = SyscallExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -149,4 +149,3 @@ def format WarnUnimpl() {{
|
|||||||
iop = InstObjParams(name, 'WarnUnimplemented')
|
iop = InstObjParams(name, 'WarnUnimplemented')
|
||||||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -456,4 +456,3 @@ TEST(BitfieldTest, CountLeadingZero64AllZeros)
|
|||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
EXPECT_EQ(64, clz64(value));
|
EXPECT_EQ(64, clz64(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,4 +100,3 @@ MultiBitSel::hash(Addr addr, int hash_number) const
|
|||||||
|
|
||||||
} // namespace bloom_filter
|
} // namespace bloom_filter
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
|
|||||||
@@ -124,4 +124,4 @@ For more detail, please see the following paper:
|
|||||||
T. Ta, X. Zhang, A. Gutierrez and B. M. Beckmann, "Autonomous Data-Race-Free
|
T. Ta, X. Zhang, A. Gutierrez and B. M. Beckmann, "Autonomous Data-Race-Free
|
||||||
GPU Testing," 2019 IEEE International Symposium on Workload Characterization
|
GPU Testing," 2019 IEEE International Symposium on Workload Characterization
|
||||||
(IISWC), Orlando, FL, USA, 2019, pp. 81-92, doi:
|
(IISWC), Orlando, FL, USA, 2019, pp. 81-92, doi:
|
||||||
10.1109/IISWC47752.2019.9042019.
|
10.1109/IISWC47752.2019.9042019.
|
||||||
|
|||||||
@@ -68,4 +68,3 @@ if env['USE_PYTHON']:
|
|||||||
SimObject('TrafficGen.py', sim_objects=['TrafficGen'], tags='protobuf')
|
SimObject('TrafficGen.py', sim_objects=['TrafficGen'], tags='protobuf')
|
||||||
Source('trace_gen.cc', tags='protobuf')
|
Source('trace_gen.cc', tags='protobuf')
|
||||||
Source('traffic_gen.cc', tags='protobuf')
|
Source('traffic_gen.cc', tags='protobuf')
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ from m5.objects.BaseCPU import BaseCPU
|
|||||||
|
|
||||||
class TraceCPU(BaseCPU):
|
class TraceCPU(BaseCPU):
|
||||||
"""Trace CPU model which replays traces generated in a prior simulation
|
"""Trace CPU model which replays traces generated in a prior simulation
|
||||||
using DerivO3CPU or its derived classes. It interfaces with L1 caches.
|
using DerivO3CPU or its derived classes. It interfaces with L1 caches.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "TraceCPU"
|
type = "TraceCPU"
|
||||||
|
|||||||
@@ -72,4 +72,3 @@ enum amdgpu_hwreg
|
|||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
#endif // __DEV_GPU_HWREG_DEFINES_H__
|
#endif // __DEV_GPU_HWREG_DEFINES_H__
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ from m5.util.fdthelper import FdtNode, FdtProperty, FdtPropertyWords, FdtState
|
|||||||
|
|
||||||
class SystemCounter(SimObject):
|
class SystemCounter(SimObject):
|
||||||
"""
|
"""
|
||||||
Shared by both PE-implementations and memory-mapped timers. It provides a
|
Shared by both PE-implementations and memory-mapped timers. It provides a
|
||||||
uniform view of system time through its counter value.
|
uniform view of system time through its counter value.
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
Arm ARM (ARM DDI 0487E.a)
|
Arm ARM (ARM DDI 0487E.a)
|
||||||
D11.1.2 - The system counter
|
D11.1.2 - The system counter
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "SystemCounter"
|
type = "SystemCounter"
|
||||||
@@ -71,14 +71,14 @@ Reference:
|
|||||||
|
|
||||||
class GenericTimer(SimObject):
|
class GenericTimer(SimObject):
|
||||||
"""
|
"""
|
||||||
Architected timers per PE in the system. Each of them provides a physical
|
Architected timers per PE in the system. Each of them provides a physical
|
||||||
counter, a virtual counter and several timers accessible from different
|
counter, a virtual counter and several timers accessible from different
|
||||||
exception levels and security states.
|
exception levels and security states.
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
Arm ARM (ARM DDI 0487E.a)
|
Arm ARM (ARM DDI 0487E.a)
|
||||||
D11.2 - The AArch64 view of the Generic Timer
|
D11.2 - The AArch64 view of the Generic Timer
|
||||||
G6.2 - The AArch32 view of the Generic Timer
|
G6.2 - The AArch32 view of the Generic Timer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "GenericTimer"
|
type = "GenericTimer"
|
||||||
@@ -135,12 +135,12 @@ Reference:
|
|||||||
|
|
||||||
class GenericTimerFrame(PioDevice):
|
class GenericTimerFrame(PioDevice):
|
||||||
"""
|
"""
|
||||||
Memory-mapped timer frame implementation. Controlled from GenericTimerMem,
|
Memory-mapped timer frame implementation. Controlled from GenericTimerMem,
|
||||||
may be used by peripherals without a system register interface.
|
may be used by peripherals without a system register interface.
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
Arm ARM (ARM DDI 0487E.a)
|
Arm ARM (ARM DDI 0487E.a)
|
||||||
I2.3.2 - The CNTBaseN and CNTEL0BaseN frames
|
I2.3.2 - The CNTBaseN and CNTEL0BaseN frames
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "GenericTimerFrame"
|
type = "GenericTimerFrame"
|
||||||
@@ -178,16 +178,16 @@ Reference:
|
|||||||
|
|
||||||
class GenericTimerMem(PioDevice):
|
class GenericTimerMem(PioDevice):
|
||||||
"""
|
"""
|
||||||
System level implementation. It provides three main components:
|
System level implementation. It provides three main components:
|
||||||
- Memory-mapped counter module: controls the system timer through the
|
- Memory-mapped counter module: controls the system timer through the
|
||||||
CNTControlBase frame, and provides its value through the CNTReadBase frame
|
CNTControlBase frame, and provides its value through the CNTReadBase frame
|
||||||
- Memory-mapped timer control module: controls the memory-mapped timers
|
- Memory-mapped timer control module: controls the memory-mapped timers
|
||||||
- Memory-mapped timers: implementations of the GenericTimer for system
|
- Memory-mapped timers: implementations of the GenericTimer for system
|
||||||
peripherals
|
peripherals
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
Arm ARM (ARM DDI 0487E.a)
|
Arm ARM (ARM DDI 0487E.a)
|
||||||
I2 - System Level Implementation of the Generic Timer
|
I2 - System Level Implementation of the Generic Timer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "GenericTimerMem"
|
type = "GenericTimerMem"
|
||||||
|
|||||||
@@ -339,9 +339,9 @@ class RealViewTemperatureSensor(SimObject):
|
|||||||
class VExpressMCC(SubSystem):
|
class VExpressMCC(SubSystem):
|
||||||
"""ARM V2M-P1 Motherboard Configuration Controller
|
"""ARM V2M-P1 Motherboard Configuration Controller
|
||||||
|
|
||||||
This subsystem describes a subset of the devices that sit behind the
|
This subsystem describes a subset of the devices that sit behind the
|
||||||
motherboard configuration controller on the the ARM Motherboard
|
motherboard configuration controller on the the ARM Motherboard
|
||||||
Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
|
Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Osc(RealViewOsc):
|
class Osc(RealViewOsc):
|
||||||
@@ -380,9 +380,9 @@ Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
|
|||||||
class CoreTile2A15DCC(SubSystem):
|
class CoreTile2A15DCC(SubSystem):
|
||||||
"""ARM CoreTile Express A15x2 Daughterboard Configuration Controller
|
"""ARM CoreTile Express A15x2 Daughterboard Configuration Controller
|
||||||
|
|
||||||
This subsystem describes a subset of the devices that sit behind the
|
This subsystem describes a subset of the devices that sit behind the
|
||||||
daughterboard configuration controller on a CoreTile Express A15x2. See
|
daughterboard configuration controller on a CoreTile Express A15x2. See
|
||||||
ARM DUI 0604E for details.
|
ARM DUI 0604E for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Osc(RealViewOsc):
|
class Osc(RealViewOsc):
|
||||||
@@ -491,10 +491,10 @@ class Sp804(AmbaPioDevice):
|
|||||||
|
|
||||||
class Sp805(AmbaIntDevice):
|
class Sp805(AmbaIntDevice):
|
||||||
"""
|
"""
|
||||||
Arm Watchdog Module (SP805)
|
Arm Watchdog Module (SP805)
|
||||||
Reference:
|
Reference:
|
||||||
Arm Watchdog Module (SP805) - Technical Reference Manual - rev. r1p0
|
Arm Watchdog Module (SP805) - Technical Reference Manual - rev. r1p0
|
||||||
Doc. ID: ARM DDI 0270B
|
Doc. ID: ARM DDI 0270B
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "Sp805"
|
type = "Sp805"
|
||||||
@@ -746,10 +746,10 @@ class MmioSRAM(ParentMem):
|
|||||||
|
|
||||||
class FVPBasePwrCtrl(BasicPioDevice):
|
class FVPBasePwrCtrl(BasicPioDevice):
|
||||||
"""
|
"""
|
||||||
Based on Fast Models Base_PowerController v11.8
|
Based on Fast Models Base_PowerController v11.8
|
||||||
Reference:
|
Reference:
|
||||||
Fast Models Reference Manual - Section 7.7.2 - Version 11.8
|
Fast Models Reference Manual - Section 7.7.2 - Version 11.8
|
||||||
Document ID: 100964_1180_00_en
|
Document ID: 100964_1180_00_en
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = "FVPBasePwrCtrl"
|
type = "FVPBasePwrCtrl"
|
||||||
@@ -1100,148 +1100,148 @@ class VExpress_EMM64(VExpress_EMM):
|
|||||||
|
|
||||||
class VExpress_GEM5_Base(RealView):
|
class VExpress_GEM5_Base(RealView):
|
||||||
"""
|
"""
|
||||||
The VExpress gem5 memory map is loosely based on a modified
|
The VExpress gem5 memory map is loosely based on a modified
|
||||||
Versatile Express RS1 memory map.
|
Versatile Express RS1 memory map.
|
||||||
|
|
||||||
The gem5 platform has been designed to implement a subset of the
|
The gem5 platform has been designed to implement a subset of the
|
||||||
original Versatile Express RS1 memory map. Off-chip peripherals should,
|
original Versatile Express RS1 memory map. Off-chip peripherals should,
|
||||||
when possible, adhere to the Versatile Express memory map. Non-PCI
|
when possible, adhere to the Versatile Express memory map. Non-PCI
|
||||||
off-chip devices that are gem5-specific should live in the CS5 memory
|
off-chip devices that are gem5-specific should live in the CS5 memory
|
||||||
space to avoid conflicts with existing devices that we might want to
|
space to avoid conflicts with existing devices that we might want to
|
||||||
model in the future. Such devices should normally have interrupts in
|
model in the future. Such devices should normally have interrupts in
|
||||||
the gem5-specific SPI range.
|
the gem5-specific SPI range.
|
||||||
|
|
||||||
On-chip peripherals are loosely modeled after the ARM CoreTile Express
|
On-chip peripherals are loosely modeled after the ARM CoreTile Express
|
||||||
A15x2 memory and interrupt map. In particular, the GIC and
|
A15x2 memory and interrupt map. In particular, the GIC and
|
||||||
Generic Timer have the same interrupt lines and base addresses. Other
|
Generic Timer have the same interrupt lines and base addresses. Other
|
||||||
on-chip devices are gem5 specific.
|
on-chip devices are gem5 specific.
|
||||||
|
|
||||||
Unlike the original Versatile Express RS2 extended platform, gem5 implements a
|
Unlike the original Versatile Express RS2 extended platform, gem5 implements a
|
||||||
large contigious DRAM space, without aliases or holes, starting at the
|
large contigious DRAM space, without aliases or holes, starting at the
|
||||||
2GiB boundary. This means that PCI memory is limited to 1GiB.
|
2GiB boundary. This means that PCI memory is limited to 1GiB.
|
||||||
|
|
||||||
References:
|
References:
|
||||||
|
|
||||||
Technical Reference Manuals:
|
Technical Reference Manuals:
|
||||||
Arm Motherboard Express uATX (V2M-P1) - ARM DUI 0447J
|
Arm Motherboard Express uATX (V2M-P1) - ARM DUI 0447J
|
||||||
Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
|
Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
|
||||||
|
|
||||||
Official Linux device tree specifications:
|
Official Linux device tree specifications:
|
||||||
V2M-P1 - arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
|
V2M-P1 - arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
|
||||||
V2P-CA15 - arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
|
V2P-CA15 - arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
|
||||||
|
|
||||||
|
Memory map:
|
||||||
|
Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
|
||||||
|
Daughterboard (global)
|
||||||
|
Section 3.2.1 - Table 3-1 - Daughterboard memory map
|
||||||
|
On-chip
|
||||||
|
Section 3.2.3 - Table 3-2 - Cortex-A15 MPCore on-chip peripheral
|
||||||
|
memory map
|
||||||
|
|
||||||
|
Interrupts:
|
||||||
|
Armv8-A Foundation Platform - User Guide - Version 11.8
|
||||||
|
Document ID: 100961_1180_00_en
|
||||||
|
|
||||||
Memory map:
|
Memory map:
|
||||||
Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
|
0x00000000-0x03ffffff: Boot memory (CS0)
|
||||||
Daughterboard (global)
|
0x04000000-0x07ffffff: Trusted Memory/Reserved
|
||||||
Section 3.2.1 - Table 3-1 - Daughterboard memory map
|
0x04000000-0x0403FFFF: 256kB Trusted SRAM
|
||||||
On-chip
|
0x06000000-0x07ffffff: 32MB Trusted DRAM
|
||||||
Section 3.2.3 - Table 3-2 - Cortex-A15 MPCore on-chip peripheral
|
0x08000000-0x0bffffff: NOR FLASH0 (CS0 alias)
|
||||||
memory map
|
0x0c000000-0x0fffffff: NOR FLASH1 (Off-chip, CS4)
|
||||||
|
0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
|
||||||
|
0x10000000-0x1000ffff: gem5 energy controller
|
||||||
|
0x10010000-0x1001ffff: gem5 pseudo-ops
|
||||||
|
0x10020000-0x1002ffff: gem5 MHU
|
||||||
|
|
||||||
|
0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
|
||||||
|
|
||||||
|
0x18000000-0x1bffffff: Off-chip, Peripherals, CS2
|
||||||
|
0x18000000-0x19ffffff: VRAM
|
||||||
|
0x1a000000-0x1bffffff: Reserved
|
||||||
|
|
||||||
|
0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
|
||||||
|
0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
|
||||||
|
0x1c060000-0x1c06ffff: KMI0 (keyboard)
|
||||||
|
0x1c070000-0x1c07ffff: KMI1 (mouse)
|
||||||
|
0x1c090000-0x1c09ffff: UART0
|
||||||
|
0x1c0a0000-0x1c0affff: UART1
|
||||||
|
0x1c0b0000-0x1c0bffff: UART2
|
||||||
|
0x1c0c0000-0x1c0cffff: UART3
|
||||||
|
0x1c0f0000-0x1c0fffff: Watchdog (SP805)
|
||||||
|
0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
|
||||||
|
0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
|
||||||
|
0x1c170000-0x1c17ffff: RTC
|
||||||
|
|
||||||
|
0x20000000-0x3fffffff: On-chip peripherals:
|
||||||
|
0x2a430000-0x2a43ffff: System Counter (control)
|
||||||
|
0x2a490000-0x2a49ffff: Trusted Watchdog (SP805)
|
||||||
|
0x2a800000-0x2a800fff: System Counter (read)
|
||||||
|
0x2a810000-0x2a810fff: System Timer (control)
|
||||||
|
|
||||||
|
0x2a820000-0x2a820fff: System Timer (frame 0)
|
||||||
|
0x2a830000-0x2a830fff: System Timer (frame 1)
|
||||||
|
|
||||||
|
0x2b000000-0x2b00ffff: HDLCD
|
||||||
|
|
||||||
|
0x2b060000-0x2b060fff: System Watchdog (SP805)
|
||||||
|
|
||||||
|
0x2b400000-0x2b41ffff: SMMUv3
|
||||||
|
|
||||||
|
0x2c001000-0x2c001fff: GIC (distributor)
|
||||||
|
0x2c002000-0x2c003fff: GIC (CPU interface)
|
||||||
|
0x2c004000-0x2c005fff: vGIC (HV)
|
||||||
|
0x2c006000-0x2c007fff: vGIC (VCPU)
|
||||||
|
0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
|
||||||
|
|
||||||
|
0x2d000000-0x2d00ffff: GPU (reserved)
|
||||||
|
|
||||||
|
0x2e000000-0x2e007fff: Non-trusted SRAM
|
||||||
|
|
||||||
|
0x2f000000-0x2fffffff: PCI IO space
|
||||||
|
0x30000000-0x3fffffff: PCI config space
|
||||||
|
|
||||||
|
0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
|
||||||
|
|
||||||
|
0x80000000-X: DRAM
|
||||||
|
|
||||||
Interrupts:
|
Interrupts:
|
||||||
Armv8-A Foundation Platform - User Guide - Version 11.8
|
0- 15: Software generated interrupts (SGIs)
|
||||||
Document ID: 100961_1180_00_en
|
16- 31: On-chip private peripherals (PPIs)
|
||||||
|
19 : generic_timer (virt sec EL2)
|
||||||
Memory map:
|
20 : generic_timer (phys sec EL2)
|
||||||
0x00000000-0x03ffffff: Boot memory (CS0)
|
25 : vgic
|
||||||
0x04000000-0x07ffffff: Trusted Memory/Reserved
|
26 : generic_timer (phys non-sec EL2)
|
||||||
0x04000000-0x0403FFFF: 256kB Trusted SRAM
|
27 : generic_timer (virt EL1)
|
||||||
0x06000000-0x07ffffff: 32MB Trusted DRAM
|
28 : generic_timer (virt non-sec EL2)
|
||||||
0x08000000-0x0bffffff: NOR FLASH0 (CS0 alias)
|
29 : generic_timer (phys EL3)
|
||||||
0x0c000000-0x0fffffff: NOR FLASH1 (Off-chip, CS4)
|
30 : generic_timer (phys EL1)
|
||||||
0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
|
31 : Reserved (Legacy IRQ)
|
||||||
0x10000000-0x1000ffff: gem5 energy controller
|
32- 95: Mother board peripherals (SPIs)
|
||||||
0x10010000-0x1001ffff: gem5 pseudo-ops
|
32 : Watchdog (SP805)
|
||||||
0x10020000-0x1002ffff: gem5 MHU
|
33 : Reserved (IOFPGA SW int)
|
||||||
|
34-35: Reserved (SP804)
|
||||||
0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
|
36 : RTC
|
||||||
|
37-40: uart0-uart3
|
||||||
0x18000000-0x1bffffff: Off-chip, Peripherals, CS2
|
41-42: Reserved (PL180)
|
||||||
0x18000000-0x19ffffff: VRAM
|
43 : Reserved (AACI)
|
||||||
0x1a000000-0x1bffffff: Reserved
|
44-45: kmi0-kmi1
|
||||||
|
46 : Reserved (CLCD)
|
||||||
0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
|
47 : Reserved (Ethernet)
|
||||||
0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
|
48 : Reserved (USB)
|
||||||
0x1c060000-0x1c06ffff: KMI0 (keyboard)
|
56 : Trusted Watchdog (SP805)
|
||||||
0x1c070000-0x1c07ffff: KMI1 (mouse)
|
57 : System timer0 (phys)
|
||||||
0x1c090000-0x1c09ffff: UART0
|
58 : System timer1 (phys)
|
||||||
0x1c0a0000-0x1c0affff: UART1
|
95-255: On-chip interrupt sources (we use these for
|
||||||
0x1c0b0000-0x1c0bffff: UART2
|
gem5-specific devices, SPIs)
|
||||||
0x1c0c0000-0x1c0cffff: UART3
|
74 : VirtIO (gem5/FM extension)
|
||||||
0x1c0f0000-0x1c0fffff: Watchdog (SP805)
|
75 : VirtIO (gem5/FM extension)
|
||||||
0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
|
95 : HDLCD
|
||||||
0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
|
96- 98: GPU (reserved)
|
||||||
0x1c170000-0x1c17ffff: RTC
|
100-103: PCI
|
||||||
|
130 : System Watchdog (SP805)
|
||||||
0x20000000-0x3fffffff: On-chip peripherals:
|
256-319: MSI frame 0 (gem5-specific, SPIs)
|
||||||
0x2a430000-0x2a43ffff: System Counter (control)
|
320-511: Unused
|
||||||
0x2a490000-0x2a49ffff: Trusted Watchdog (SP805)
|
|
||||||
0x2a800000-0x2a800fff: System Counter (read)
|
|
||||||
0x2a810000-0x2a810fff: System Timer (control)
|
|
||||||
|
|
||||||
0x2a820000-0x2a820fff: System Timer (frame 0)
|
|
||||||
0x2a830000-0x2a830fff: System Timer (frame 1)
|
|
||||||
|
|
||||||
0x2b000000-0x2b00ffff: HDLCD
|
|
||||||
|
|
||||||
0x2b060000-0x2b060fff: System Watchdog (SP805)
|
|
||||||
|
|
||||||
0x2b400000-0x2b41ffff: SMMUv3
|
|
||||||
|
|
||||||
0x2c001000-0x2c001fff: GIC (distributor)
|
|
||||||
0x2c002000-0x2c003fff: GIC (CPU interface)
|
|
||||||
0x2c004000-0x2c005fff: vGIC (HV)
|
|
||||||
0x2c006000-0x2c007fff: vGIC (VCPU)
|
|
||||||
0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
|
|
||||||
|
|
||||||
0x2d000000-0x2d00ffff: GPU (reserved)
|
|
||||||
|
|
||||||
0x2e000000-0x2e007fff: Non-trusted SRAM
|
|
||||||
|
|
||||||
0x2f000000-0x2fffffff: PCI IO space
|
|
||||||
0x30000000-0x3fffffff: PCI config space
|
|
||||||
|
|
||||||
0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
|
|
||||||
|
|
||||||
0x80000000-X: DRAM
|
|
||||||
|
|
||||||
Interrupts:
|
|
||||||
0- 15: Software generated interrupts (SGIs)
|
|
||||||
16- 31: On-chip private peripherals (PPIs)
|
|
||||||
19 : generic_timer (virt sec EL2)
|
|
||||||
20 : generic_timer (phys sec EL2)
|
|
||||||
25 : vgic
|
|
||||||
26 : generic_timer (phys non-sec EL2)
|
|
||||||
27 : generic_timer (virt EL1)
|
|
||||||
28 : generic_timer (virt non-sec EL2)
|
|
||||||
29 : generic_timer (phys EL3)
|
|
||||||
30 : generic_timer (phys EL1)
|
|
||||||
31 : Reserved (Legacy IRQ)
|
|
||||||
32- 95: Mother board peripherals (SPIs)
|
|
||||||
32 : Watchdog (SP805)
|
|
||||||
33 : Reserved (IOFPGA SW int)
|
|
||||||
34-35: Reserved (SP804)
|
|
||||||
36 : RTC
|
|
||||||
37-40: uart0-uart3
|
|
||||||
41-42: Reserved (PL180)
|
|
||||||
43 : Reserved (AACI)
|
|
||||||
44-45: kmi0-kmi1
|
|
||||||
46 : Reserved (CLCD)
|
|
||||||
47 : Reserved (Ethernet)
|
|
||||||
48 : Reserved (USB)
|
|
||||||
56 : Trusted Watchdog (SP805)
|
|
||||||
57 : System timer0 (phys)
|
|
||||||
58 : System timer1 (phys)
|
|
||||||
95-255: On-chip interrupt sources (we use these for
|
|
||||||
gem5-specific devices, SPIs)
|
|
||||||
74 : VirtIO (gem5/FM extension)
|
|
||||||
75 : VirtIO (gem5/FM extension)
|
|
||||||
95 : HDLCD
|
|
||||||
96- 98: GPU (reserved)
|
|
||||||
100-103: PCI
|
|
||||||
130 : System Watchdog (SP805)
|
|
||||||
256-319: MSI frame 0 (gem5-specific, SPIs)
|
|
||||||
320-511: Unused
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -84,4 +84,3 @@ class A9SCU : public BasicPioDevice
|
|||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
#endif // __DEV_ARM_A9SCU_HH__
|
#endif // __DEV_ARM_A9SCU_HH__
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user