# 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.

from m5.params import *
from m5.SimObject import SimObject

from m5.objects.SimpleMemory import *

class Workload(SimObject):
    type = 'Workload'
    cxx_header = "sim/workload.hh"
    cxx_class = 'gem5::Workload'
    abstract = True

    wait_for_remote_gdb = Param.Bool(False,
        "Wait for a remote GDB connection");

class StubWorkload(Workload):
    type = 'StubWorkload'
    cxx_header = "sim/workload.hh"
    cxx_class = 'gem5::StubWorkload'

    entry = Param.Addr(0, 'Dummy entry point for this workload.')
    byte_order = Param.ByteOrder('little',
            'Dummy byte order for this workload.')

class KernelWorkload(Workload):
    type = 'KernelWorkload'
    cxx_header = "sim/kernel_workload.hh"
    cxx_class = 'gem5::KernelWorkload'

    object_file = Param.String("", "File that contains the kernel code")
    extras = VectorParam.String([], "Additional object files to load")
    extras_addrs = VectorParam.Addr([],
            "Load addresses for additional object files")

    addr_check = Param.Bool(True,
        "whether to bounds check kernel addresses (disable for baremetal)")
    load_addr_mask = Param.UInt64(0xffffffffffffffff,
            "Mask to apply to kernel addresses. If zero, "
            "auto-calculated to be the most restrictive.")
    load_addr_offset = Param.UInt64(0, "Address to offset the kernel with")

    command_line = Param.String("a", "boot flags to pass to the kernel")

class SEWorkloadMeta(type(Workload)):
    all_se_workload_classes = []
    def __new__(mcls, name, bases, dct):
        cls = super().__new__(mcls, name, bases, dct)
        SEWorkloadMeta.all_se_workload_classes.append(cls)
        return cls

class SEWorkload(Workload, metaclass=SEWorkloadMeta):
    type = 'SEWorkload'
    cxx_header = "sim/se_workload.hh"
    cxx_class = 'gem5::SEWorkload'
    abstract = True

    @classmethod
    def _is_compatible_with(cls, obj):
        return False

    @classmethod
    def find_compatible(cls, path):
        '''List the SE workloads compatible with the binary at path'''

        from _m5 import object_file
        obj = object_file.create(path)
        options = list(filter(lambda wld: wld._is_compatible_with(obj),
                              SEWorkloadMeta.all_se_workload_classes))

        return options

    @classmethod
    def init_compatible(cls, path, *args, **kwargs):
        '''Construct the only SE workload compatible with the binary at path'''

        options = SEWorkload.find_compatible(path)

        if len(options) > 1:
            raise ValueError("More than one SE workload is compatible with %s")
        elif len(options) < 1:
            raise ValueError("No SE workload is compatible with %s", path)

        return options[0](*args, **kwargs)
