diff options
Diffstat (limited to 'src/arch/arm/fastmodel/SConscript')
-rw-r--r-- | src/arch/arm/fastmodel/SConscript | 368 |
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') |