# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2018 Google, Inc
# Written by Simon Glass <sjg@chromium.org>

"""# Entry-type module for a full map of the firmware image

This handles putting an FDT into the image with just the information about the
image.
"""

import libfdt

from entry import Entry
from fdt import Fdt
import state
import tools
import tout

FDTMAP_MAGIC   = b'_FDTMAP_'
FDTMAP_HDR_LEN = 16

def LocateFdtmap(data):
    """Search an image for an fdt map

    Args:
        data: Data to search

    Returns:
        Position of fdt map in data, or None if not found. Note that the
            position returned is of the FDT header, i.e. before the FDT data
    """
    hdr_pos = data.find(FDTMAP_MAGIC)
    size = len(data)
    if hdr_pos != -1:
        hdr = data[hdr_pos:hdr_pos + FDTMAP_HDR_LEN]
        if len(hdr) == FDTMAP_HDR_LEN:
            return hdr_pos
    return None

class Entry_fdtmap(Entry):
    """An entry which contains an FDT map

    Properties / Entry arguments:
        None

    An FDT map is just a header followed by an FDT containing a list of all the
    entries in the image. The root node corresponds to the image node in the
    original FDT, and an image-name property indicates the image name in that
    original tree.

    The header is the string _FDTMAP_ followed by 8 unused bytes.

    When used, this entry will be populated with an FDT map which reflects the
    entries in the current image. Hierarchy is preserved, and all offsets and
    sizes are included.

    Note that the -u option must be provided to ensure that binman updates the
    FDT with the position of each entry.

    Example output for a simple image with U-Boot and an FDT map:

    / {
        image-name = "binman";
        size = <0x00000112>;
        image-pos = <0x00000000>;
        offset = <0x00000000>;
        u-boot {
            size = <0x00000004>;
            image-pos = <0x00000000>;
            offset = <0x00000000>;
        };
        fdtmap {
            size = <0x0000010e>;
            image-pos = <0x00000004>;
            offset = <0x00000004>;
        };
    };

    If allow-repack is used then 'orig-offset' and 'orig-size' properties are
    added as necessary. See the binman README.
    """
    def __init__(self, section, etype, node):
        Entry.__init__(self, section, etype, node)

    def _GetFdtmap(self):
        """Build an FDT map from the entries in the current image

        Returns:
            FDT map binary data
        """
        def _AddNode(node):
            """Add a node to the FDT map"""
            for pname, prop in node.props.items():
                fsw.property(pname, prop.bytes)
            for subnode in node.subnodes:
                with fsw.add_node(subnode.name):
                    _AddNode(subnode)

        data = state.GetFdtContents('fdtmap')[1]
        # If we have an fdtmap it means that we are using this as the
        # fdtmap for this image.
        if data is None:
            # Get the FDT data into an Fdt object
            data = state.GetFdtContents()[1]
            infdt = Fdt.FromData(data)
            infdt.Scan()

            # Find the node for the image containing the Fdt-map entry
            path = self.section.GetPath()
            self.Detail("Fdtmap: Using section '%s' (path '%s')" %
                        (self.section.name, path))
            node = infdt.GetNode(path)
            if not node:
                self.Raise("Internal error: Cannot locate node for path '%s'" %
                           path)

            # Build a new tree with all nodes and properties starting from that
            # node
            fsw = libfdt.FdtSw()
            fsw.finish_reservemap()
            with fsw.add_node(''):
                fsw.property_string('image-node', node.name)
                _AddNode(node)
            fdt = fsw.as_fdt()

            # Pack this new FDT and return its contents
            fdt.pack()
            outfdt = Fdt.FromData(fdt.as_bytearray())
            data = outfdt.GetContents()
        data = FDTMAP_MAGIC + tools.GetBytes(0, 8) + data
        return data

    def ObtainContents(self):
        """Obtain a placeholder for the fdt-map contents"""
        self.SetContents(self._GetFdtmap())
        return True

    def ProcessContents(self):
        """Write an updated version of the FDT map to this entry

        This is necessary since new data may have been written back to it during
        processing, e.g. the image-pos properties.
        """
        return self.ProcessContentsUpdate(self._GetFdtmap())
