# Copyright (c) 2016 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# 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.
#
# Author: Glenn Bergmans

from m5.ext.pyfdt import pyfdt
import re
import os
from m5.SimObject import SimObject

class FdtProperty(pyfdt.FdtProperty):
    """Create a property without values."""
    pass

class FdtPropertyWords(pyfdt.FdtPropertyWords):
    """Create a property with word (32-bit unsigned) values."""
    def __init__(self, name, words):
        if type(words) != list:
            words = [words]
        # Make sure all values are ints (use automatic base detection if the
        # type is str)
        words = [long(w, base=0) if type(w) == str else long(w) for w in words]
        super(FdtPropertyWords, self).__init__(name, words)

class FdtPropertyStrings(pyfdt.FdtPropertyStrings):
    """Create a property with string values."""

    def __init__(self, name, strings):
        if type(strings) == str:
            strings = [strings]
        strings = [str(string) for string in strings] # Make all values strings
        super(FdtPropertyStrings, self).__init__(name, strings)

class FdtPropertyBytes(pyfdt.FdtPropertyBytes):
    """Create a property with integer (8-bit signed) values."""

    def __init__(self, name, values):
        if type(values) != list:
            values = [values]
        # Make sure all values are ints (use automatic base detection if the
        # type is str)
        values = [int(v, base=0)
                   if isinstance(v, str) else int(v) for v in values]
        super(FdtPropertyBytes, self).__init__(name, values)

class FdtState(object):
    """Class for maintaining state while recursively generating a flattened
    device tree. The state tracks address, size and CPU address cell sizes, and
    maintains a dictionary of allocated phandles."""

    phandle_counter = 0
    phandles = dict()

    def __init__(self, addr_cells, size_cells, cpu_cells):
        """Instantiate values of this state. The state can only be initialized
        once."""

        self.addr_cells = addr_cells
        self.size_cells = size_cells
        self.cpu_cells = cpu_cells

    def phandle(self, obj):
        """Return a unique phandle number for a key. The key can be a SimObject
        or any value that is castable to a string. If the phandle doesn't exist
        a new one is created, otherwise the existing one is returned."""

        if isinstance(obj, SimObject):
            key = str(id(obj))
        else:
            try:
                key = str(obj)
            except ValueError:
                raise ValueError('Phandle keys must be castable to str')

        if not key in FdtState.phandles:
            FdtState.phandle_counter += 1

        return FdtState.phandles.setdefault(key, FdtState.phandle_counter)

    def resetPhandles(self):
        FdtState.phandle_counter = 0
        FdtState.phandles = dict()

    def int_to_cells(self, value, cells):
        """Helper function for: generates a list of 32 bit cells from an int,
        used to split up addresses in appropriate 32 bit chunks."""
        value = long(value)

        if (value >> (32 * cells)) != 0:
            fatal("Value %d doesn't fit in %d cells" % (value, cells))

        return [(value >> 32*(x-1)) & 0xFFFFFFFF for x in range(cells, 0, -1)]

    def addrCells(self, addr):
        """Format an integer type according to the address_cells value of this
        state."""
        return self.int_to_cells(addr, self.addr_cells)

    def CPUAddrCells(self, addr):
        """Format an integer type according to the cpu_cells value of this
        state."""
        return self.int_to_cells(addr, self.cpu_cells)

    def sizeCells(self, size):
        """Format an integer type according to the size_cells value of this
        state."""
        return self.int_to_cells(size, self.size_cells)

    def addrCellsProperty(self):
        """Return an #address-cells property with the value of this state."""
        return FdtPropertyWords("#address-cells", self.addr_cells)

    def sizeCellsProperty(self):
        """Return an #size-cells property with the value of this state."""
        return FdtPropertyWords("#size-cells", self.size_cells)

    def CPUCellsProperty(self):
        """Return an #address-cells property for cpu nodes with the value
        of this state."""
        return FdtPropertyWords("#address-cells", self.cpu_cells)

class FdtNop(pyfdt.FdtNop):
    """Create an empty node."""
    pass

class FdtNode(pyfdt.FdtNode):
    def __init__(self, name, obj=None):
        """Create a new node and immediately set the phandle property, if obj
        is supplied"""
        super(FdtNode, self).__init__(name)
        if obj != None:
            self.appendPhandle(obj)

    def append(self, subnodes):
        """Change the behavior of the normal append to override if a node with
        the same name already exists or merge if the name exists and is a node
        type. Can also take a list of subnodes, that each get appended."""
        if not hasattr(subnodes, '__iter__'):
            subnodes = [subnodes]

        for subnode in subnodes:
            try:
                if not issubclass(type(subnode), pyfdt.FdtNop):
                    index = self.index(subnode.name)
                    item = self.pop(index)
                else:
                    item = None
            except ValueError:
                item = None

            if isinstance(item,  pyfdt.FdtNode) and \
               isinstance(subnode,  pyfdt.FdtNode):
                item.merge(subnode)
                subnode = item

            super(FdtNode, self).append(subnode)

    def appendList(self, subnode_list):
        """Append all properties/nodes in the iterable."""
        for subnode in subnode_list:
            self.append(subnode)

    def appendCompatible(self, compatible):
        """Append a compatible property with the supplied compatibility
        strings."""
        if isinstance(compatible, str):
            compatible = [compatible]
        self.append(FdtPropertyStrings('compatible', compatible))

    def appendPhandle(self, obj):
        """Append a phandle property to this node with the phandle of the
        supplied object."""
        # Create a bogus state because we only need the Phandle dictionary
        state = FdtState(addr_cells=1, size_cells=1, cpu_cells=1)

        phandle = state.phandle(obj)
        self.append(FdtPropertyWords("phandle", [phandle]))

class Fdt(pyfdt.Fdt):
    def sortNodes(self, node):
        """Move all properties to the beginning and subnodes to the end
        while maintaining the order of the subnodes. DTB files require the
        properties to go before the nodes, but the PyFdt doesn't account for
        defining nodes and properties in a random order."""
        properties = FdtNode(node.name)
        subnodes = FdtNode(node.name)

        while len(node):
            subnode = node.pop(0)
            if issubclass(type(subnode), pyfdt.FdtNode):
                subnode = self.sortNodes(subnode)
                subnodes.append(subnode)
            else:
                properties.append(subnode)

        properties.merge(subnodes)

        return properties

    def add_rootnode(self, rootnode, prenops=None, postnops=None):
        """First sort the device tree, so that properties are before nodes."""
        rootnode = self.sortNodes(rootnode)
        super(Fdt, self).add_rootnode(rootnode, prenops, postnops)

    def writeDtbFile(self, filename):
        """Convert the device tree to DTB and write to a file."""
        filename = os.path.realpath(filename)
        try:
            with open(filename, 'wb') as f:
                f.write(self.to_dtb())
            return filename
        except IOError:
            raise RuntimeError("Failed to open DTB output file")

    def writeDtsFile(self, filename):
        """Convert the device tree to DTS and write to a file."""
        filename = os.path.realpath(filename)
        try:
            with open(filename, 'w') as f:
                f.write(self.to_dts())
            return filename
        except IOError:
            raise RuntimeError("Failed to open DTS output file")
