diff --git a/tools/sptool/hob.py b/tools/sptool/hob.py
new file mode 100644
index 0000000..372ec68
--- /dev/null
+++ b/tools/sptool/hob.py
@@ -0,0 +1,396 @@
+#!/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
