summaryrefslogtreecommitdiff
path: root/src/arch/arm/fastmodel/SConscript
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/fastmodel/SConscript')
-rw-r--r--src/arch/arm/fastmodel/SConscript368
1 files changed, 368 insertions, 0 deletions
diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript
new file mode 100644
index 000000000..17d931f4b
--- /dev/null
+++ b/src/arch/arm/fastmodel/SConscript
@@ -0,0 +1,368 @@
+# Copyright 2019 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from __future__ import print_function
+
+Import('*')
+
+from m5.util.terminal import termcap
+from m5.util.grammar import Grammar
+
+from gem5_scons import Transform
+
+import os.path
+
+if env['USE_ARM_FASTMODEL']:
+ if not env['USE_SYSTEMC']:
+ print(termcap.Yellow + termcap.Bold +
+ 'Warning: ARM Fast Models require systemc support' +
+ termcap.Normal)
+ env['USE_ARM_FASTMODEL'] = False
+ Return()
+
+if not env['USE_ARM_FASTMODEL']:
+ Return()
+
+
+systemc_home = Dir('#/src/systemc/ext/systemc_home')
+env['ENV']['SYSTEMC_HOME'] = systemc_home.abspath
+
+def extract_var(name):
+ if name not in env:
+ print(termcap.Red + termcap.Bold +
+ ('Error: %s is not set' % name) +
+ termcap.Normal)
+ Exit(1)
+ print('%s = %s' % (name, env[name]))
+ # Make sure the value of this variable shows up as an environment variable
+ # for commands scons runs.
+ env['ENV'][name] = env[name]
+ return env[name]
+
+pvlib_home, maxcore_home, armlmd_license_file = \
+ list(map(extract_var, ('PVLIB_HOME', 'MAXCORE_HOME',
+ 'ARMLMD_LICENSE_FILE')))
+
+pvlib_home = Dir(pvlib_home)
+maxcore_home = Dir(maxcore_home)
+armlmd_license_file = File(armlmd_license_file)
+
+
+pvlib_flavor = env['PVLIB_FLAVOR']
+pvlib_lib_dir = pvlib_home.Dir('lib').Dir(pvlib_flavor)
+
+simulation_engine_name = 'libMAXCOREInitSimulationEngine.3.so'
+simulation_engine_lib = pvlib_lib_dir.File(simulation_engine_name)
+
+
+def staticify(env, name):
+ ''' Check for a static version of the library named 'name', and if it
+ exists return a File node for it explicitly. Otherwise pass 'name'
+ through for normal processing.'''
+
+ static_name = env.subst('${LIBPREFIX}' + name + '${LIBSUFFIX}')
+
+ for path in env.Flatten(env['LIBPATH']):
+ full_name = Dir(path).File(static_name).get_abspath()
+ if os.path.isfile(full_name):
+ return File(full_name)
+
+ return name
+
+
+# Adjust the build environment to support building in Fast Models.
+
+env.Append(CCFLAGS='-pthread')
+
+cpppaths = (
+ pvlib_home.Dir('include/fmruntime'),
+ pvlib_home.Dir('include/fmruntime/eslapi'),
+ pvlib_home.Dir('Iris/include'),
+
+ systemc_home.Dir('include'),
+
+ maxcore_home.Dir('AMBA-PV/include'),
+)
+env.Append(CPPPATH=cpppaths)
+
+lib_paths = (
+ pvlib_lib_dir,
+ pvlib_home.Dir('Iris').Dir(pvlib_flavor),
+)
+env.Append(LIBPATH=lib_paths)
+env.Append(RPATH=lib_paths)
+
+libs = (
+ 'components',
+ 'pvbus',
+ 'armctmodel',
+ 'fmruntime',
+ 'IrisSupport',
+ 'dl',
+ 'rt',
+)
+env.Append(LIBS=list(staticify(env, lib) for lib in libs))
+
+
+class ProjectFileParser(Grammar):
+ class Param(object):
+ def __init__(self, is_object):
+ self.is_object = is_object
+
+ def __str__(self):
+ return self._to_str(0)
+
+ class StringParam(Param):
+ def __init__(self, name, value):
+ super(ProjectFileParser.StringParam, self).__init__(
+ is_object=False)
+ self.name = name
+ self.value = value
+
+ def _to_str(self, indent):
+ indent_str = " " * indent
+ return indent_str + self.name + ' = \"' + self.value + '\"'
+
+ class ObjectParam(Param):
+ def __init__(self, type_name, name, params):
+ super(ProjectFileParser.ObjectParam, self).__init__(
+ is_object=True)
+ self.type_name = type_name
+ self.name = name
+ self.params = params
+
+ def _to_str(self, indent):
+ indent_str = " " * indent
+ val = indent_str + self.type_name
+ if self.name is not None:
+ val += ' "' + self.name + '"'
+ val += "\n" + indent_str + "{\n"
+ for param in self.params:
+ val += param._to_str(indent + 1) + "\n"
+ val += indent_str + "}"
+ return val
+
+ #########
+ # Lexer #
+ #########
+
+ tokens = (
+ # identifier
+ 'ID',
+
+ # string literal
+ 'STRLIT',
+
+ # = { } ;
+ 'EQUALS',
+ 'LBRACE',
+ 'RBRACE',
+ 'SEMI',
+ )
+
+ t_ID = r'[A-Za-z_]\w*'
+
+ def t_STRLIT(self, t):
+ r'(?m)"([^"])*"'
+ # strip off quotes
+ t.value = t.value[1:-1]
+ t.lexer.lineno += t.value.count('\n')
+ return t
+
+ t_EQUALS = r'='
+ t_LBRACE = r'\{'
+ t_RBRACE = r'\}'
+ t_SEMI = r';'
+
+ def t_NEWLINE(self, t):
+ r'\n+'
+ t.lexer.lineno += t.value.count('\n')
+
+ t_ignore = ' \t\x0c'
+
+ ##########
+ # Parser #
+ ##########
+
+ def p_object(self, t):
+ 'object : object_heading LBRACE params RBRACE'
+ t[0] = self.ObjectParam(t[1][0], t[1][1], t[3])
+
+ def p_object_heading_0(self, t):
+ 'object_heading : ID STRLIT'
+ t[0] = (t[1], t[2])
+
+ def p_object_heading_1(self, t):
+ 'object_heading : ID'
+ t[0] = (t[1], None)
+
+ def p_params_0(self, t):
+ 'params : '
+ t[0] = []
+
+ def p_params_1(self, t):
+ 'params : param params'
+ t[0] = [t[1]] + t[2]
+
+ def p_param_0(self, t):
+ 'param : ID EQUALS STRLIT SEMI'
+ t[0] = self.StringParam(t[1], t[3])
+
+ def p_param_1(self, t):
+ 'param : object'
+ t[0] = t[1]
+
+
+class ArmFastModelComponent(object):
+ def __init__(self, project_file, *extra_deps):
+ project_file = File(project_file)
+ project_file_dir = project_file.Dir('.')
+
+ parser = ProjectFileParser()
+ proj = parser.parse_file(project_file.srcnode().abspath)
+
+ # Top level component.
+ tlc = None
+ # Config name.
+ config_name = None
+
+ # Scan for particular properties of the project.
+ for param in proj.params:
+ if not param.is_object:
+ if param.name == 'TOP_LEVEL_COMPONENT':
+ tlc = param.value
+ elif param.name == 'ACTIVE_CONFIG_LINUX':
+ config_name = param.value
+
+ assert tlc is not None and config_name is not None
+
+ simgen_dir = project_file_dir.Dir(config_name)
+
+ def simgen_static(name):
+ return simgen_dir.File(env.subst(
+ '${LIBPREFIX}%s${LIBSUFFIX}' % name))
+
+ def simgen_shared(name):
+ return simgen_dir.File(env.subst(
+ '${SHLIBPREFIX}%s${SHLIBSUFFIX}' % name))
+
+ static_libs = [
+ 'scx-%s-%s' % (tlc, config_name),
+ 'scx',
+ ]
+ shared_libs = [
+ '%s-%s' % (tlc, config_name),
+ ]
+
+ static_lib_nodes = map(simgen_static, static_libs)
+ shared_lib_nodes = map(simgen_shared, shared_libs)
+ # We need to use the static libraries as files so that the linker
+ # doesn't use the shared versions of them instead. We need to use
+ # the shared libraries by name so that the linker will apply RPATH
+ # and be able to find them at run time. If a shared libary includes
+ # a path, the dynamic linker will apparently ignore RPATH when looking
+ # for it.
+ lib_nodes = static_lib_nodes + shared_lib_nodes
+
+ gen_dir = simgen_dir.Dir('gen')
+
+ header = gen_dir.File('scx_evs_%s.h' % tlc)
+
+ self.headers = [header]
+ self.headerpaths = [gen_dir]
+ self.libs = static_lib_nodes + shared_libs
+ self.libpaths = [simgen_dir]
+ self.rpaths = [simgen_dir]
+
+ simgen_cmd = env.subst('${SIMGEN} -p %s --configuration %s -b ' +
+ '--verbose off --num-build-cpus 100 --build-dir %s') % \
+ (project_file.srcnode().abspath, config_name, simgen_dir.abspath)
+ if not GetOption('verbose'):
+ simgen_cmd += ' > /dev/null'
+ simgen_action = MakeAction(simgen_cmd, Transform('SIMGEN'))
+ sources = [project_file]
+ sources.extend(extra_deps)
+ env.Command(lib_nodes + self.headers, sources, simgen_action)
+
+ def prepare_env(self, env):
+ env.Append(LIBPATH=self.libpaths)
+ env.AddLocalRPATH(*self.rpaths)
+ env.Append(CPPPATH=self.headerpaths)
+ env.Prepend(LIBS=self.libs)
+
+
+class ArmFastModelBin(Executable):
+ def __init__(self, target, *components_and_sources):
+ def is_component(x):
+ return isinstance(x, ArmFastModelComponent)
+
+ def not_component(x):
+ return not is_component(x)
+
+ components = list(filter(is_component, components_and_sources))
+ sources = list(filter(not_component, components_and_sources))
+
+ self.components = components
+ super(ArmFastModelBin, self).__init__(target, *sources)
+
+ @classmethod
+ def declare_all(cls, env):
+ env = env.Clone()
+ env.Prepend(LIBS=env['STATIC_LIB'][0])
+ super(ArmFastModelBin, cls).declare_all(env)
+
+ def declare(self, env):
+ env = env.Clone()
+
+ sources = list(self.sources)
+ for f in self.filters:
+ sources += Source.all.apply_filter(f)
+
+ objs = self.srcs_to_objs(env, sources)
+ objs = objs + env['MAIN_OBJS']
+
+ for component in self.components:
+ component.prepare_env(env)
+
+ binary = super(ArmFastModelBin, self).declare(env, objs)[0]
+
+ # We need a copy of the simulation engine lib alongside the executable
+ # so that the license check works properly.
+ local_engine = binary.File(simulation_engine_name)
+ Depends(binary, local_engine)
+ main.Command(local_engine, simulation_engine_lib,
+ MakeAction("cp ${SOURCE} ${TARGET}", Transform('COPY')))
+
+Export('ArmFastModelComponent')
+Export('ArmFastModelBin')
+
+PySource('m5', 'arm_fast_model.py')
+Source('fastmodel.cc')
+
+SimObject('FastModel.py')
+Source('amba_to_tlm_bridge.cc')
+Source('amba_from_tlm_bridge.cc')