# 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

import os

from m5.defines import buildEnv
import _m5.arm_fast_model

def set_armlmd_license_file(force=False):
    '''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
       environment. The value it's set to is the one gem5 was built with.
       '''
    key = 'ARMLMD_LICENSE_FILE'
    license_file = buildEnv[key]
    if force or key not in os.environ:
        os.environ[key] = license_file

# These methods wrap much of the SystemC Export API described in section
# 7.6 of the Fast Models User Guide.

def scx_initialize(id):
    # Change our working directory to where the simulation engine library
    # is so that the fast model code can find it. It looks in the binary
    # directory and in the current working directory, and we can change
    # the later. This avoids having to make copies of that library all
    # over the place.
    cwd = os.getcwd()
    os.chdir(os.path.join(buildEnv['PVLIB_HOME'], 'lib',
                          buildEnv['PVLIB_FLAVOR']))

    # Actually run scx_initialize.
    _m5.arm_fast_model.scx_initialize(id)

    # Restore the previous working directory.
    os.chdir(cwd)

def scx_load_application(instance, application):
    _m5.arm_fast_model.scx_load_application(instance, application)

def scx_load_application_all(application):
    _m5.arm_fast_model.scx_load_application_all(application)

def scx_load_data(instance, data, address):
    _m5.arm_fast_model.scx_load_data(instance, data, address)

def scx_load_data_all(data, address):
    _m5.arm_fast_model.scx_load_data_all(data, address)

def scx_set_parameter(name, value):
    _m5.arm_fast_model.scx_set_parameter(name, value)

def scx_get_parameter(name):
    value = ""
    _m5.arm_fast_model.scx_get_parameter(name, value)
    return value

def scx_get_parameter_list(self):
    return _m5.arm_fast_model.scx_get_parameter_list()

def scx_set_cpi_file(cpi_file_path):
    _m5.arm_fast_model.scx_set_cpi_file(cpi_file_path)

def scx_cpulimit(t):
    _m5.arm_fast_model.scx_cpulimit(t)

def scx_timelimit(t):
    _m5.arm_fast_model.scx_timelimit(t)

def scx_simlimit(t):
    _m5.arm_fast_model.scx_simlimit(t)

def scx_parse_and_configure(
        self, argc, argv, trailer=None, sig_handler=True):
    _m5.arm_fast_model.scx_parse_and_configure(
            argc, argv, trailer, sig_handler)

def scx_start_cadi_server(start=True, run=True, debug=False):
    _m5.arm_fast_model.scx_start_cadi_server(start, run, debug)

def scx_enable_cadi_log(log=True):
    _m5.arm_fast_model.scx_enable_cadi_log(log)

def scx_prefix_appli_output(prefix=True):
    _m5.arm_fast_model.scx_prefix_appli_output(prefix)

def scx_print_port_number(print_=True):
    _m5.arm_fast_model.scx_print_port_number(print_)

def scx_print_statistics(print_=True):
    _m5.arm_fast_model.scx_print_statistics(print_)

def scx_load_plugin(file_):
    _m5.arm_fast_model.scx_load_plugin(file_)

def scx_sync(sync_time):
    _m5.arm_fast_model.scx_sync(sync_time)

def scx_set_min_sync_latency(latency):
    _m5.arm_fast_model.scx_set_min_sync_latency(latency)

def scx_get_min_sync_latency(arg=None):
    if arg:
        return _m5.arm_fast_model.scx_get_min_sync_latency(arg)
    else:
        return _m5.arm_fast_model.scx_get_min_sync_latency()

# This should be called once per simulation
def setup_simulation(sim_name, min_sync_latency=100.0 / 100000000):
    set_armlmd_license_file()
    scx_initialize(sim_name)
    scx_set_min_sync_latency(min_sync_latency)
