#!/usr/bin/python3
# Copyright (c) 2025, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

import struct

EFI_HOB_HANDOFF_TABLE_VERSION = 0x000A

PAGE_SIZE_SHIFT = 12  # TODO assuming 4K page size

# HobType values of EFI_HOB_GENERIC_HEADER.

EFI_HOB_TYPE_HANDOFF = 0x0001
EFI_HOB_TYPE_MEMORY_ALLOCATION = 0x0002
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR = 0x0003
EFI_HOB_TYPE_GUID_EXTENSION = 0x0004
EFI_HOB_TYPE_FV = 0x0005
EFI_HOB_TYPE_CPU = 0x0006
EFI_HOB_TYPE_MEMORY_POOL = 0x0007
EFI_HOB_TYPE_FV2 = 0x0009
EFI_HOB_TYPE_LOAD_PEIM_UNUSED = 0x000A
EFI_HOB_TYPE_UEFI_CAPSULE = 0x000B
EFI_HOB_TYPE_FV3 = 0x000C
EFI_HOB_TYPE_UNUSED = 0xFFFE
EFI_HOB_TYPE_END_OF_HOB_LIST = 0xFFFF

# GUID values
"""struct efi_guid {
         uint32_t time_low;
         uint16_t time_mid;
         uint16_t time_hi_and_version;
         uint8_t clock_seq_and_node[8];
}"""

MM_PEI_MMRAM_MEMORY_RESERVE_GUID = (
    0x0703F912,
    0xBF8D,
    0x4E2A,
    (0xBE, 0x07, 0xAB, 0x27, 0x25, 0x25, 0xC5, 0x92),
)
MM_NS_BUFFER_GUID = (
    0xF00497E3,
    0xBFA2,
    0x41A1,
    (0x9D, 0x29, 0x54, 0xC2, 0xE9, 0x37, 0x21, 0xC5),
)

# MMRAM states and capabilities
# See UEFI Platform Initialization Specification Version 1.8, IV-5.3.5
EFI_MMRAM_OPEN = 0x00000001
EFI_MMRAM_CLOSED = 0x00000002
EFI_MMRAM_LOCKED = 0x00000004
EFI_CACHEABLE = 0x00000008
EFI_ALLOCATED = 0x00000010
EFI_NEEDS_TESTING = 0x00000020
EFI_NEEDS_ECC_INITIALIZATION = 0x00000040

EFI_SMRAM_OPEN = EFI_MMRAM_OPEN
EFI_SMRAM_CLOSED = EFI_MMRAM_CLOSED
EFI_SMRAM_LOCKED = EFI_MMRAM_LOCKED

# EFI boot mode.
EFI_BOOT_WITH_FULL_CONFIGURATION = 0x00
EFI_BOOT_WITH_MINIMAL_CONFIGURATION = 0x01
EFI_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES = 0x02
EFI_BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS = 0x03
EFI_BOOT_WITH_DEFAULT_SETTINGS = 0x04
EFI_BOOT_ON_S4_RESUME = 0x05
EFI_BOOT_ON_S5_RESUME = 0x06
EFI_BOOT_WITH_MFG_MODE_SETTINGS = 0x07
EFI_BOOT_ON_S2_RESUME = 0x10
EFI_BOOT_ON_S3_RESUME = 0x11
EFI_BOOT_ON_FLASH_UPDATE = 0x12
EFI_BOOT_IN_RECOVERY_MODE = 0x20

STMM_BOOT_MODE = EFI_BOOT_WITH_FULL_CONFIGURATION
STMM_MMRAM_REGION_STATE_DEFAULT = EFI_CACHEABLE | EFI_ALLOCATED
STMM_MMRAM_REGION_STATE_HEAP = EFI_CACHEABLE


# Helper for fdt node property parsing
def get_integer_property_value(fdt_node, name):
    if fdt_node.exist_property(name):
        p = fdt_node.get_property(name)

        # <u32> Device Tree value
        if len(p) == 1:
            return p.value
        # <u64> Device Tree value represented as two 32-bit values
        if len(p) == 2:
            msb = p[0]
            lsb = p[1]
            return lsb | (msb << 32)
    return None


class EfiGuid:
    """Class representing EFI GUID (Globally Unique Identifier) as described by
    the UEFI Specification v2.10"""

    def __init__(self, time_low, time_mid, time_hi_and_version, clock_seq_and_node):
        self.time_low = time_low
        self.time_mid = time_mid
        self.time_hi_and_version = time_hi_and_version
        self.clock_seq_and_node = clock_seq_and_node
        self.format_str = "IHH8B"

    def pack(self):
        return struct.pack(
            self.format_str,
            self.time_low,
            self.time_mid,
            self.time_hi_and_version,
            *self.clock_seq_and_node,
        )

    def __str__(self):
        return f"{hex(self.time_low)}, {hex(self.time_mid)}, \
    {hex(self.time_hi_and_version)}, {[hex(i) for i in self.clock_seq_and_node]}"


class HobGenericHeader:
    """Class representing the Hob Generic Header data type as described
    in the UEFI Platform Initialization Specification version 1.8.

    Each HOB is required to contain this header specifying the type and length
    of the HOB.
    """

    def __init__(self, hob_type, hob_length):
        self.format_str = "HHI"
        self.hob_type = hob_type
        self.hob_length = struct.calcsize(self.format_str) + hob_length
        self.reserved = 0

    def pack(self):
        return struct.pack(
            self.format_str, self.hob_type, self.hob_length, self.reserved
        )

    def __str__(self):
        return f"Hob Type: {self.hob_type} Hob Length: {self.hob_length}"


class HobGuid:
    """Class representing the Guid Extension HOB as described in the UEFI
    Platform Initialization Specification version 1.8.

    Allows the production of HOBs whose types are not defined by the
    specification by generating a GUID for the HOB entry."""

    def __init__(self, name: EfiGuid, data_format_str, data):
        hob_length = struct.calcsize(name.format_str) + struct.calcsize(data_format_str)
        self.header = HobGenericHeader(EFI_HOB_TYPE_GUID_EXTENSION, hob_length)
        self.name = name
        self.data = data
        self.data_format_str = data_format_str
        self.format_str = (
            self.header.format_str + self.name.format_str + data_format_str
        )

    def pack(self):
        return (
            self.header.pack()
            + self.name.pack()
            + struct.pack(self.data_format_str, *self.data)
        )

    def __str__(self):
        return f"Header: {self.header}\n Name: {self.name}\n Data: {self.data}"


class HandoffInfoTable:
    """Class representing the Handoff Info Table HOB (also known as PHIT HOB)
    as described in the UEFI Platform Initialization Specification version 1.8.

    Must be the first HOB in the HOB list. Contains general state
    information.

    For an SP, the range `memory_bottom` to `memory_top` will be the memory
    range for the SP starting at the load address. `free_memory_bottom` to
    `free_memory_top` indicates space where more HOB's could be added to the
    HOB List."""

    def __init__(self, memory_base, memory_size, free_memory_base, free_memory_size):
        # header,uint32t,uint32t, uint64_t * 5
        self.format_str = "II5Q"
        hob_length = struct.calcsize(self.format_str)
        self.header = HobGenericHeader(EFI_HOB_TYPE_HANDOFF, hob_length)
        self.version = EFI_HOB_HANDOFF_TABLE_VERSION
        self.boot_mode = STMM_BOOT_MODE
        self.memory_top = memory_base + memory_size
        self.memory_bottom = memory_base
        self.free_memory_top = free_memory_base + free_memory_size
        self.free_memory_bottom = free_memory_base + self.header.hob_length
        self.hob_end = None

    def set_hob_end_addr(self, hob_end_addr):
        self.hob_end = hob_end_addr

    def set_free_memory_bottom_addr(self, addr):
        self.free_memory_bottom = addr

    def pack(self):
        return self.header.pack() + struct.pack(
            self.format_str,
            self.version,
            self.boot_mode,
            self.memory_top,
            self.memory_bottom,
            self.free_memory_top,
            self.free_memory_bottom,
            self.hob_end,
        )


class FirmwareVolumeHob:
    """Class representing the Firmware Volume HOB type as described in the
    UEFI Platform Initialization Specification version 1.8.

    For an SP this will detail where the SP binary is located.
    """

    def __init__(self, base_address, img_offset, img_size):
        # header, uint64_t, uint64_t
        self.data_format_str = "2Q"
        hob_length = struct.calcsize(self.data_format_str)
        self.header = HobGenericHeader(EFI_HOB_TYPE_FV, hob_length)
        self.format_str = self.header.format_str + self.data_format_str
        self.base_address = base_address + img_offset
        self.length = img_size - img_offset

    def pack(self):
        return self.header.pack() + struct.pack(
            self.data_format_str, self.base_address, self.length
        )


class EndOfHobListHob:
    """Class representing the End of HOB List HOB type as described in the
    UEFI Platform Initialization Specification version 1.8.

    Must be the last entry in a HOB list.
    """

    def __init__(self):
        self.header = HobGenericHeader(EFI_HOB_TYPE_END_OF_HOB_LIST, 0)
        self.format_str = ""

    def pack(self):
        return self.header.pack()


class HobList:
    """Class representing a HOB (Handoff Block list) based on the UEFI Platform
    Initialization Sepcification version 1.8"""

    def __init__(self, phit: HandoffInfoTable):
        if phit is None:
            raise Exception("HobList must be initialized with valid PHIT HOB")
        final_hob = EndOfHobListHob()
        phit.hob_end = phit.free_memory_bottom
        phit.free_memory_bottom += final_hob.header.hob_length
        self.hob_list = [phit, final_hob]

    def add(self, hob):
        if hob is not None:
            if hob.header.hob_length > (
                self.get_phit().free_memory_top - self.get_phit().free_memory_bottom
            ):
                raise MemoryError(
                    f"Cannot add HOB of length {hob.header.hob_length}. \
                    Resulting table size would exceed max table size of \
                    {self.max_size}. Current table size: {self.size}."
                )
            self.hob_list.insert(-1, hob)
            self.get_phit().hob_end += hob.header.hob_length
            self.get_phit().free_memory_bottom += hob.header.hob_length

    def get_list(self):
        return self.hob_list

    def get_phit(self):
        if self.hob_list is not None:
            if type(self.hob_list[0]) is not HandoffInfoTable:
                raise Exception("First hob in list must be of type PHIT")
            return self.hob_list[0]


def generate_mmram_desc(base_addr, page_count, granule, region_state):
    physical_size = page_count << (PAGE_SIZE_SHIFT + (granule << 1))
    physical_start = base_addr
    cpu_start = base_addr

    return ("4Q", (physical_start, cpu_start, physical_size, region_state))


def generate_ns_buffer_guid(mmram_desc):
    return HobGuid(EfiGuid(*MM_NS_BUFFER_GUID), *mmram_desc)


def generate_pei_mmram_memory_reserve_guid(regions):
    # uint32t n_reserved regions, array of mmram descriptors
    format_str = "I"
    data = [len(regions)]
    for desc_format_str, mmram_desc in regions:
        format_str += desc_format_str
        data.extend(mmram_desc)
    guid_data = (format_str, data)
    return HobGuid(EfiGuid(*MM_PEI_MMRAM_MEMORY_RESERVE_GUID), *guid_data)


def generate_hob_from_fdt_node(sp_fdt, hob_offset, hob_size=None):
    """Create a HOB list binary from an SP FDT."""
    fv_hob = None
    ns_buffer_hob = None
    mmram_reserve_hob = None
    shared_buf_hob = None

    load_address = get_integer_property_value(sp_fdt, "load-address")
    img_size = get_integer_property_value(sp_fdt, "image-size")
    entrypoint_offset = get_integer_property_value(sp_fdt, "entrypoint-offset")

    if entrypoint_offset is None:
        entrypoint_offset = 0x0
    if hob_offset is None:
        hob_offset = 0x0
    if img_size is None:
        img_size = 0x0

    if sp_fdt.exist_node("memory-regions"):
        if sp_fdt.exist_property("xlat-granule"):
            granule = int(sp_fdt.get_property("xlat-granule").value)
        else:
            # Default granule to 4K
            granule = 0
        memory_regions = sp_fdt.get_node("memory-regions")
        regions = []
        for node in memory_regions.nodes:
            base_addr = get_integer_property_value(node, "base-address")
            page_count = get_integer_property_value(node, "pages-count")

            if base_addr is None:
                offset = get_integer_property_value(
                    node, "load-address-relative-offset"
                )
                if offset is None:
                    # Cannot create memory descriptor without base address, so skip
                    # node if base address cannot be defined
                    continue
                else:
                    base_addr = load_address + offset

            if node.name.strip() == "heap":
                region_state = STMM_MMRAM_REGION_STATE_HEAP
            else:
                region_state = STMM_MMRAM_REGION_STATE_DEFAULT

            mmram_desc = generate_mmram_desc(
                base_addr, page_count, granule, region_state
            )

            if node.name.strip() == "ns_comm_buffer":
                ns_buffer_hob = generate_ns_buffer_guid(mmram_desc)

            regions.append(mmram_desc)

        mmram_reserve_hob = generate_pei_mmram_memory_reserve_guid(regions)

    fv_hob = FirmwareVolumeHob(load_address, entrypoint_offset, img_size)
    hob_list_base = load_address + hob_offset

    # TODO assuming default of 1 page allocated for HOB List
    if hob_size is not None:
        max_table_size = hob_size
    else:
        max_table_size = 1 << PAGE_SIZE_SHIFT
    phit = HandoffInfoTable(
        load_address, entrypoint_offset + img_size, hob_list_base, max_table_size
    )

    # Create a HobList containing only PHIT and EndofHobList HOBs.
    hob_list = HobList(phit)

    # Add HOBs to HOB list
    if fv_hob is not None:
        hob_list.add(fv_hob)
    if ns_buffer_hob is not None:
        hob_list.add(ns_buffer_hob)
    if mmram_reserve_hob is not None:
        hob_list.add(mmram_reserve_hob)
    if shared_buf_hob is not None:
        hob_list.add(shared_buf_hob)

    return hob_list
