1*cc594af6SKathleen Capella#!/usr/bin/python3 2*cc594af6SKathleen Capella# Copyright (c) 2025, Arm Limited. All rights reserved. 3*cc594af6SKathleen Capella# 4*cc594af6SKathleen Capella# SPDX-License-Identifier: BSD-3-Clause 5*cc594af6SKathleen Capella 6*cc594af6SKathleen Capellaimport struct 7*cc594af6SKathleen Capella 8*cc594af6SKathleen CapellaEFI_HOB_HANDOFF_TABLE_VERSION = 0x000A 9*cc594af6SKathleen Capella 10*cc594af6SKathleen CapellaPAGE_SIZE_SHIFT = 12 # TODO assuming 4K page size 11*cc594af6SKathleen Capella 12*cc594af6SKathleen Capella# HobType values of EFI_HOB_GENERIC_HEADER. 13*cc594af6SKathleen Capella 14*cc594af6SKathleen CapellaEFI_HOB_TYPE_HANDOFF = 0x0001 15*cc594af6SKathleen CapellaEFI_HOB_TYPE_MEMORY_ALLOCATION = 0x0002 16*cc594af6SKathleen CapellaEFI_HOB_TYPE_RESOURCE_DESCRIPTOR = 0x0003 17*cc594af6SKathleen CapellaEFI_HOB_TYPE_GUID_EXTENSION = 0x0004 18*cc594af6SKathleen CapellaEFI_HOB_TYPE_FV = 0x0005 19*cc594af6SKathleen CapellaEFI_HOB_TYPE_CPU = 0x0006 20*cc594af6SKathleen CapellaEFI_HOB_TYPE_MEMORY_POOL = 0x0007 21*cc594af6SKathleen CapellaEFI_HOB_TYPE_FV2 = 0x0009 22*cc594af6SKathleen CapellaEFI_HOB_TYPE_LOAD_PEIM_UNUSED = 0x000A 23*cc594af6SKathleen CapellaEFI_HOB_TYPE_UEFI_CAPSULE = 0x000B 24*cc594af6SKathleen CapellaEFI_HOB_TYPE_FV3 = 0x000C 25*cc594af6SKathleen CapellaEFI_HOB_TYPE_UNUSED = 0xFFFE 26*cc594af6SKathleen CapellaEFI_HOB_TYPE_END_OF_HOB_LIST = 0xFFFF 27*cc594af6SKathleen Capella 28*cc594af6SKathleen Capella# GUID values 29*cc594af6SKathleen Capella"""struct efi_guid { 30*cc594af6SKathleen Capella uint32_t time_low; 31*cc594af6SKathleen Capella uint16_t time_mid; 32*cc594af6SKathleen Capella uint16_t time_hi_and_version; 33*cc594af6SKathleen Capella uint8_t clock_seq_and_node[8]; 34*cc594af6SKathleen Capella}""" 35*cc594af6SKathleen Capella 36*cc594af6SKathleen CapellaMM_PEI_MMRAM_MEMORY_RESERVE_GUID = ( 37*cc594af6SKathleen Capella 0x0703F912, 38*cc594af6SKathleen Capella 0xBF8D, 39*cc594af6SKathleen Capella 0x4E2A, 40*cc594af6SKathleen Capella (0xBE, 0x07, 0xAB, 0x27, 0x25, 0x25, 0xC5, 0x92), 41*cc594af6SKathleen Capella) 42*cc594af6SKathleen CapellaMM_NS_BUFFER_GUID = ( 43*cc594af6SKathleen Capella 0xF00497E3, 44*cc594af6SKathleen Capella 0xBFA2, 45*cc594af6SKathleen Capella 0x41A1, 46*cc594af6SKathleen Capella (0x9D, 0x29, 0x54, 0xC2, 0xE9, 0x37, 0x21, 0xC5), 47*cc594af6SKathleen Capella) 48*cc594af6SKathleen Capella 49*cc594af6SKathleen Capella# MMRAM states and capabilities 50*cc594af6SKathleen Capella# See UEFI Platform Initialization Specification Version 1.8, IV-5.3.5 51*cc594af6SKathleen CapellaEFI_MMRAM_OPEN = 0x00000001 52*cc594af6SKathleen CapellaEFI_MMRAM_CLOSED = 0x00000002 53*cc594af6SKathleen CapellaEFI_MMRAM_LOCKED = 0x00000004 54*cc594af6SKathleen CapellaEFI_CACHEABLE = 0x00000008 55*cc594af6SKathleen CapellaEFI_ALLOCATED = 0x00000010 56*cc594af6SKathleen CapellaEFI_NEEDS_TESTING = 0x00000020 57*cc594af6SKathleen CapellaEFI_NEEDS_ECC_INITIALIZATION = 0x00000040 58*cc594af6SKathleen Capella 59*cc594af6SKathleen CapellaEFI_SMRAM_OPEN = EFI_MMRAM_OPEN 60*cc594af6SKathleen CapellaEFI_SMRAM_CLOSED = EFI_MMRAM_CLOSED 61*cc594af6SKathleen CapellaEFI_SMRAM_LOCKED = EFI_MMRAM_LOCKED 62*cc594af6SKathleen Capella 63*cc594af6SKathleen Capella# EFI boot mode. 64*cc594af6SKathleen CapellaEFI_BOOT_WITH_FULL_CONFIGURATION = 0x00 65*cc594af6SKathleen CapellaEFI_BOOT_WITH_MINIMAL_CONFIGURATION = 0x01 66*cc594af6SKathleen CapellaEFI_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES = 0x02 67*cc594af6SKathleen CapellaEFI_BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS = 0x03 68*cc594af6SKathleen CapellaEFI_BOOT_WITH_DEFAULT_SETTINGS = 0x04 69*cc594af6SKathleen CapellaEFI_BOOT_ON_S4_RESUME = 0x05 70*cc594af6SKathleen CapellaEFI_BOOT_ON_S5_RESUME = 0x06 71*cc594af6SKathleen CapellaEFI_BOOT_WITH_MFG_MODE_SETTINGS = 0x07 72*cc594af6SKathleen CapellaEFI_BOOT_ON_S2_RESUME = 0x10 73*cc594af6SKathleen CapellaEFI_BOOT_ON_S3_RESUME = 0x11 74*cc594af6SKathleen CapellaEFI_BOOT_ON_FLASH_UPDATE = 0x12 75*cc594af6SKathleen CapellaEFI_BOOT_IN_RECOVERY_MODE = 0x20 76*cc594af6SKathleen Capella 77*cc594af6SKathleen CapellaSTMM_BOOT_MODE = EFI_BOOT_WITH_FULL_CONFIGURATION 78*cc594af6SKathleen CapellaSTMM_MMRAM_REGION_STATE_DEFAULT = EFI_CACHEABLE | EFI_ALLOCATED 79*cc594af6SKathleen CapellaSTMM_MMRAM_REGION_STATE_HEAP = EFI_CACHEABLE 80*cc594af6SKathleen Capella 81*cc594af6SKathleen Capella 82*cc594af6SKathleen Capella# Helper for fdt node property parsing 83*cc594af6SKathleen Capelladef get_integer_property_value(fdt_node, name): 84*cc594af6SKathleen Capella if fdt_node.exist_property(name): 85*cc594af6SKathleen Capella p = fdt_node.get_property(name) 86*cc594af6SKathleen Capella 87*cc594af6SKathleen Capella # <u32> Device Tree value 88*cc594af6SKathleen Capella if len(p) == 1: 89*cc594af6SKathleen Capella return p.value 90*cc594af6SKathleen Capella # <u64> Device Tree value represented as two 32-bit values 91*cc594af6SKathleen Capella if len(p) == 2: 92*cc594af6SKathleen Capella msb = p[0] 93*cc594af6SKathleen Capella lsb = p[1] 94*cc594af6SKathleen Capella return lsb | (msb << 32) 95*cc594af6SKathleen Capella return None 96*cc594af6SKathleen Capella 97*cc594af6SKathleen Capella 98*cc594af6SKathleen Capellaclass EfiGuid: 99*cc594af6SKathleen Capella """Class representing EFI GUID (Globally Unique Identifier) as described by 100*cc594af6SKathleen Capella the UEFI Specification v2.10""" 101*cc594af6SKathleen Capella 102*cc594af6SKathleen Capella def __init__(self, time_low, time_mid, time_hi_and_version, clock_seq_and_node): 103*cc594af6SKathleen Capella self.time_low = time_low 104*cc594af6SKathleen Capella self.time_mid = time_mid 105*cc594af6SKathleen Capella self.time_hi_and_version = time_hi_and_version 106*cc594af6SKathleen Capella self.clock_seq_and_node = clock_seq_and_node 107*cc594af6SKathleen Capella self.format_str = "IHH8B" 108*cc594af6SKathleen Capella 109*cc594af6SKathleen Capella def pack(self): 110*cc594af6SKathleen Capella return struct.pack( 111*cc594af6SKathleen Capella self.format_str, 112*cc594af6SKathleen Capella self.time_low, 113*cc594af6SKathleen Capella self.time_mid, 114*cc594af6SKathleen Capella self.time_hi_and_version, 115*cc594af6SKathleen Capella *self.clock_seq_and_node, 116*cc594af6SKathleen Capella ) 117*cc594af6SKathleen Capella 118*cc594af6SKathleen Capella def __str__(self): 119*cc594af6SKathleen Capella return f"{hex(self.time_low)}, {hex(self.time_mid)}, \ 120*cc594af6SKathleen Capella {hex(self.time_hi_and_version)}, {[hex(i) for i in self.clock_seq_and_node]}" 121*cc594af6SKathleen Capella 122*cc594af6SKathleen Capella 123*cc594af6SKathleen Capellaclass HobGenericHeader: 124*cc594af6SKathleen Capella """Class representing the Hob Generic Header data type as described 125*cc594af6SKathleen Capella in the UEFI Platform Initialization Specification version 1.8. 126*cc594af6SKathleen Capella 127*cc594af6SKathleen Capella Each HOB is required to contain this header specifying the type and length 128*cc594af6SKathleen Capella of the HOB. 129*cc594af6SKathleen Capella """ 130*cc594af6SKathleen Capella 131*cc594af6SKathleen Capella def __init__(self, hob_type, hob_length): 132*cc594af6SKathleen Capella self.format_str = "HHI" 133*cc594af6SKathleen Capella self.hob_type = hob_type 134*cc594af6SKathleen Capella self.hob_length = struct.calcsize(self.format_str) + hob_length 135*cc594af6SKathleen Capella self.reserved = 0 136*cc594af6SKathleen Capella 137*cc594af6SKathleen Capella def pack(self): 138*cc594af6SKathleen Capella return struct.pack( 139*cc594af6SKathleen Capella self.format_str, self.hob_type, self.hob_length, self.reserved 140*cc594af6SKathleen Capella ) 141*cc594af6SKathleen Capella 142*cc594af6SKathleen Capella def __str__(self): 143*cc594af6SKathleen Capella return f"Hob Type: {self.hob_type} Hob Length: {self.hob_length}" 144*cc594af6SKathleen Capella 145*cc594af6SKathleen Capella 146*cc594af6SKathleen Capellaclass HobGuid: 147*cc594af6SKathleen Capella """Class representing the Guid Extension HOB as described in the UEFI 148*cc594af6SKathleen Capella Platform Initialization Specification version 1.8. 149*cc594af6SKathleen Capella 150*cc594af6SKathleen Capella Allows the production of HOBs whose types are not defined by the 151*cc594af6SKathleen Capella specification by generating a GUID for the HOB entry.""" 152*cc594af6SKathleen Capella 153*cc594af6SKathleen Capella def __init__(self, name: EfiGuid, data_format_str, data): 154*cc594af6SKathleen Capella hob_length = struct.calcsize(name.format_str) + struct.calcsize(data_format_str) 155*cc594af6SKathleen Capella self.header = HobGenericHeader(EFI_HOB_TYPE_GUID_EXTENSION, hob_length) 156*cc594af6SKathleen Capella self.name = name 157*cc594af6SKathleen Capella self.data = data 158*cc594af6SKathleen Capella self.data_format_str = data_format_str 159*cc594af6SKathleen Capella self.format_str = ( 160*cc594af6SKathleen Capella self.header.format_str + self.name.format_str + data_format_str 161*cc594af6SKathleen Capella ) 162*cc594af6SKathleen Capella 163*cc594af6SKathleen Capella def pack(self): 164*cc594af6SKathleen Capella return ( 165*cc594af6SKathleen Capella self.header.pack() 166*cc594af6SKathleen Capella + self.name.pack() 167*cc594af6SKathleen Capella + struct.pack(self.data_format_str, *self.data) 168*cc594af6SKathleen Capella ) 169*cc594af6SKathleen Capella 170*cc594af6SKathleen Capella def __str__(self): 171*cc594af6SKathleen Capella return f"Header: {self.header}\n Name: {self.name}\n Data: {self.data}" 172*cc594af6SKathleen Capella 173*cc594af6SKathleen Capella 174*cc594af6SKathleen Capellaclass HandoffInfoTable: 175*cc594af6SKathleen Capella """Class representing the Handoff Info Table HOB (also known as PHIT HOB) 176*cc594af6SKathleen Capella as described in the UEFI Platform Initialization Specification version 1.8. 177*cc594af6SKathleen Capella 178*cc594af6SKathleen Capella Must be the first HOB in the HOB list. Contains general state 179*cc594af6SKathleen Capella information. 180*cc594af6SKathleen Capella 181*cc594af6SKathleen Capella For an SP, the range `memory_bottom` to `memory_top` will be the memory 182*cc594af6SKathleen Capella range for the SP starting at the load address. `free_memory_bottom` to 183*cc594af6SKathleen Capella `free_memory_top` indicates space where more HOB's could be added to the 184*cc594af6SKathleen Capella HOB List.""" 185*cc594af6SKathleen Capella 186*cc594af6SKathleen Capella def __init__(self, memory_base, memory_size, free_memory_base, free_memory_size): 187*cc594af6SKathleen Capella # header,uint32t,uint32t, uint64_t * 5 188*cc594af6SKathleen Capella self.format_str = "II5Q" 189*cc594af6SKathleen Capella hob_length = struct.calcsize(self.format_str) 190*cc594af6SKathleen Capella self.header = HobGenericHeader(EFI_HOB_TYPE_HANDOFF, hob_length) 191*cc594af6SKathleen Capella self.version = EFI_HOB_HANDOFF_TABLE_VERSION 192*cc594af6SKathleen Capella self.boot_mode = STMM_BOOT_MODE 193*cc594af6SKathleen Capella self.memory_top = memory_base + memory_size 194*cc594af6SKathleen Capella self.memory_bottom = memory_base 195*cc594af6SKathleen Capella self.free_memory_top = free_memory_base + free_memory_size 196*cc594af6SKathleen Capella self.free_memory_bottom = free_memory_base + self.header.hob_length 197*cc594af6SKathleen Capella self.hob_end = None 198*cc594af6SKathleen Capella 199*cc594af6SKathleen Capella def set_hob_end_addr(self, hob_end_addr): 200*cc594af6SKathleen Capella self.hob_end = hob_end_addr 201*cc594af6SKathleen Capella 202*cc594af6SKathleen Capella def set_free_memory_bottom_addr(self, addr): 203*cc594af6SKathleen Capella self.free_memory_bottom = addr 204*cc594af6SKathleen Capella 205*cc594af6SKathleen Capella def pack(self): 206*cc594af6SKathleen Capella return self.header.pack() + struct.pack( 207*cc594af6SKathleen Capella self.format_str, 208*cc594af6SKathleen Capella self.version, 209*cc594af6SKathleen Capella self.boot_mode, 210*cc594af6SKathleen Capella self.memory_top, 211*cc594af6SKathleen Capella self.memory_bottom, 212*cc594af6SKathleen Capella self.free_memory_top, 213*cc594af6SKathleen Capella self.free_memory_bottom, 214*cc594af6SKathleen Capella self.hob_end, 215*cc594af6SKathleen Capella ) 216*cc594af6SKathleen Capella 217*cc594af6SKathleen Capella 218*cc594af6SKathleen Capellaclass FirmwareVolumeHob: 219*cc594af6SKathleen Capella """Class representing the Firmware Volume HOB type as described in the 220*cc594af6SKathleen Capella UEFI Platform Initialization Specification version 1.8. 221*cc594af6SKathleen Capella 222*cc594af6SKathleen Capella For an SP this will detail where the SP binary is located. 223*cc594af6SKathleen Capella """ 224*cc594af6SKathleen Capella 225*cc594af6SKathleen Capella def __init__(self, base_address, img_offset, img_size): 226*cc594af6SKathleen Capella # header, uint64_t, uint64_t 227*cc594af6SKathleen Capella self.data_format_str = "2Q" 228*cc594af6SKathleen Capella hob_length = struct.calcsize(self.data_format_str) 229*cc594af6SKathleen Capella self.header = HobGenericHeader(EFI_HOB_TYPE_FV, hob_length) 230*cc594af6SKathleen Capella self.format_str = self.header.format_str + self.data_format_str 231*cc594af6SKathleen Capella self.base_address = base_address + img_offset 232*cc594af6SKathleen Capella self.length = img_size - img_offset 233*cc594af6SKathleen Capella 234*cc594af6SKathleen Capella def pack(self): 235*cc594af6SKathleen Capella return self.header.pack() + struct.pack( 236*cc594af6SKathleen Capella self.data_format_str, self.base_address, self.length 237*cc594af6SKathleen Capella ) 238*cc594af6SKathleen Capella 239*cc594af6SKathleen Capella 240*cc594af6SKathleen Capellaclass EndOfHobListHob: 241*cc594af6SKathleen Capella """Class representing the End of HOB List HOB type as described in the 242*cc594af6SKathleen Capella UEFI Platform Initialization Specification version 1.8. 243*cc594af6SKathleen Capella 244*cc594af6SKathleen Capella Must be the last entry in a HOB list. 245*cc594af6SKathleen Capella """ 246*cc594af6SKathleen Capella 247*cc594af6SKathleen Capella def __init__(self): 248*cc594af6SKathleen Capella self.header = HobGenericHeader(EFI_HOB_TYPE_END_OF_HOB_LIST, 0) 249*cc594af6SKathleen Capella self.format_str = "" 250*cc594af6SKathleen Capella 251*cc594af6SKathleen Capella def pack(self): 252*cc594af6SKathleen Capella return self.header.pack() 253*cc594af6SKathleen Capella 254*cc594af6SKathleen Capella 255*cc594af6SKathleen Capellaclass HobList: 256*cc594af6SKathleen Capella """Class representing a HOB (Handoff Block list) based on the UEFI Platform 257*cc594af6SKathleen Capella Initialization Sepcification version 1.8""" 258*cc594af6SKathleen Capella 259*cc594af6SKathleen Capella def __init__(self, phit: HandoffInfoTable): 260*cc594af6SKathleen Capella if phit is None: 261*cc594af6SKathleen Capella raise Exception("HobList must be initialized with valid PHIT HOB") 262*cc594af6SKathleen Capella final_hob = EndOfHobListHob() 263*cc594af6SKathleen Capella phit.hob_end = phit.free_memory_bottom 264*cc594af6SKathleen Capella phit.free_memory_bottom += final_hob.header.hob_length 265*cc594af6SKathleen Capella self.hob_list = [phit, final_hob] 266*cc594af6SKathleen Capella 267*cc594af6SKathleen Capella def add(self, hob): 268*cc594af6SKathleen Capella if hob is not None: 269*cc594af6SKathleen Capella if hob.header.hob_length > ( 270*cc594af6SKathleen Capella self.get_phit().free_memory_top - self.get_phit().free_memory_bottom 271*cc594af6SKathleen Capella ): 272*cc594af6SKathleen Capella raise MemoryError( 273*cc594af6SKathleen Capella f"Cannot add HOB of length {hob.header.hob_length}. \ 274*cc594af6SKathleen Capella Resulting table size would exceed max table size of \ 275*cc594af6SKathleen Capella {self.max_size}. Current table size: {self.size}." 276*cc594af6SKathleen Capella ) 277*cc594af6SKathleen Capella self.hob_list.insert(-1, hob) 278*cc594af6SKathleen Capella self.get_phit().hob_end += hob.header.hob_length 279*cc594af6SKathleen Capella self.get_phit().free_memory_bottom += hob.header.hob_length 280*cc594af6SKathleen Capella 281*cc594af6SKathleen Capella def get_list(self): 282*cc594af6SKathleen Capella return self.hob_list 283*cc594af6SKathleen Capella 284*cc594af6SKathleen Capella def get_phit(self): 285*cc594af6SKathleen Capella if self.hob_list is not None: 286*cc594af6SKathleen Capella if type(self.hob_list[0]) is not HandoffInfoTable: 287*cc594af6SKathleen Capella raise Exception("First hob in list must be of type PHIT") 288*cc594af6SKathleen Capella return self.hob_list[0] 289*cc594af6SKathleen Capella 290*cc594af6SKathleen Capella 291*cc594af6SKathleen Capelladef generate_mmram_desc(base_addr, page_count, granule, region_state): 292*cc594af6SKathleen Capella physical_size = page_count << (PAGE_SIZE_SHIFT + (granule << 1)) 293*cc594af6SKathleen Capella physical_start = base_addr 294*cc594af6SKathleen Capella cpu_start = base_addr 295*cc594af6SKathleen Capella 296*cc594af6SKathleen Capella return ("4Q", (physical_start, cpu_start, physical_size, region_state)) 297*cc594af6SKathleen Capella 298*cc594af6SKathleen Capella 299*cc594af6SKathleen Capelladef generate_ns_buffer_guid(mmram_desc): 300*cc594af6SKathleen Capella return HobGuid(EfiGuid(*MM_NS_BUFFER_GUID), *mmram_desc) 301*cc594af6SKathleen Capella 302*cc594af6SKathleen Capella 303*cc594af6SKathleen Capelladef generate_pei_mmram_memory_reserve_guid(regions): 304*cc594af6SKathleen Capella # uint32t n_reserved regions, array of mmram descriptors 305*cc594af6SKathleen Capella format_str = "I" 306*cc594af6SKathleen Capella data = [len(regions)] 307*cc594af6SKathleen Capella for desc_format_str, mmram_desc in regions: 308*cc594af6SKathleen Capella format_str += desc_format_str 309*cc594af6SKathleen Capella data.extend(mmram_desc) 310*cc594af6SKathleen Capella guid_data = (format_str, data) 311*cc594af6SKathleen Capella return HobGuid(EfiGuid(*MM_PEI_MMRAM_MEMORY_RESERVE_GUID), *guid_data) 312*cc594af6SKathleen Capella 313*cc594af6SKathleen Capella 314*cc594af6SKathleen Capelladef generate_hob_from_fdt_node(sp_fdt, hob_offset, hob_size=None): 315*cc594af6SKathleen Capella """Create a HOB list binary from an SP FDT.""" 316*cc594af6SKathleen Capella fv_hob = None 317*cc594af6SKathleen Capella ns_buffer_hob = None 318*cc594af6SKathleen Capella mmram_reserve_hob = None 319*cc594af6SKathleen Capella shared_buf_hob = None 320*cc594af6SKathleen Capella 321*cc594af6SKathleen Capella load_address = get_integer_property_value(sp_fdt, "load-address") 322*cc594af6SKathleen Capella img_size = get_integer_property_value(sp_fdt, "image-size") 323*cc594af6SKathleen Capella entrypoint_offset = get_integer_property_value(sp_fdt, "entrypoint-offset") 324*cc594af6SKathleen Capella 325*cc594af6SKathleen Capella if entrypoint_offset is None: 326*cc594af6SKathleen Capella entrypoint_offset = 0x0 327*cc594af6SKathleen Capella if hob_offset is None: 328*cc594af6SKathleen Capella hob_offset = 0x0 329*cc594af6SKathleen Capella if img_size is None: 330*cc594af6SKathleen Capella img_size = 0x0 331*cc594af6SKathleen Capella 332*cc594af6SKathleen Capella if sp_fdt.exist_node("memory-regions"): 333*cc594af6SKathleen Capella if sp_fdt.exist_property("xlat-granule"): 334*cc594af6SKathleen Capella granule = int(sp_fdt.get_property("xlat-granule").value) 335*cc594af6SKathleen Capella else: 336*cc594af6SKathleen Capella # Default granule to 4K 337*cc594af6SKathleen Capella granule = 0 338*cc594af6SKathleen Capella memory_regions = sp_fdt.get_node("memory-regions") 339*cc594af6SKathleen Capella regions = [] 340*cc594af6SKathleen Capella for node in memory_regions.nodes: 341*cc594af6SKathleen Capella base_addr = get_integer_property_value(node, "base-address") 342*cc594af6SKathleen Capella page_count = get_integer_property_value(node, "pages-count") 343*cc594af6SKathleen Capella 344*cc594af6SKathleen Capella if base_addr is None: 345*cc594af6SKathleen Capella offset = get_integer_property_value( 346*cc594af6SKathleen Capella node, "load-address-relative-offset" 347*cc594af6SKathleen Capella ) 348*cc594af6SKathleen Capella if offset is None: 349*cc594af6SKathleen Capella # Cannot create memory descriptor without base address, so skip 350*cc594af6SKathleen Capella # node if base address cannot be defined 351*cc594af6SKathleen Capella continue 352*cc594af6SKathleen Capella else: 353*cc594af6SKathleen Capella base_addr = load_address + offset 354*cc594af6SKathleen Capella 355*cc594af6SKathleen Capella if node.name.strip() == "heap": 356*cc594af6SKathleen Capella region_state = STMM_MMRAM_REGION_STATE_HEAP 357*cc594af6SKathleen Capella else: 358*cc594af6SKathleen Capella region_state = STMM_MMRAM_REGION_STATE_DEFAULT 359*cc594af6SKathleen Capella 360*cc594af6SKathleen Capella mmram_desc = generate_mmram_desc( 361*cc594af6SKathleen Capella base_addr, page_count, granule, region_state 362*cc594af6SKathleen Capella ) 363*cc594af6SKathleen Capella 364*cc594af6SKathleen Capella if node.name.strip() == "ns_comm_buffer": 365*cc594af6SKathleen Capella ns_buffer_hob = generate_ns_buffer_guid(mmram_desc) 366*cc594af6SKathleen Capella 367*cc594af6SKathleen Capella regions.append(mmram_desc) 368*cc594af6SKathleen Capella 369*cc594af6SKathleen Capella mmram_reserve_hob = generate_pei_mmram_memory_reserve_guid(regions) 370*cc594af6SKathleen Capella 371*cc594af6SKathleen Capella fv_hob = FirmwareVolumeHob(load_address, entrypoint_offset, img_size) 372*cc594af6SKathleen Capella hob_list_base = load_address + hob_offset 373*cc594af6SKathleen Capella 374*cc594af6SKathleen Capella # TODO assuming default of 1 page allocated for HOB List 375*cc594af6SKathleen Capella if hob_size is not None: 376*cc594af6SKathleen Capella max_table_size = hob_size 377*cc594af6SKathleen Capella else: 378*cc594af6SKathleen Capella max_table_size = 1 << PAGE_SIZE_SHIFT 379*cc594af6SKathleen Capella phit = HandoffInfoTable( 380*cc594af6SKathleen Capella load_address, entrypoint_offset + img_size, hob_list_base, max_table_size 381*cc594af6SKathleen Capella ) 382*cc594af6SKathleen Capella 383*cc594af6SKathleen Capella # Create a HobList containing only PHIT and EndofHobList HOBs. 384*cc594af6SKathleen Capella hob_list = HobList(phit) 385*cc594af6SKathleen Capella 386*cc594af6SKathleen Capella # Add HOBs to HOB list 387*cc594af6SKathleen Capella if fv_hob is not None: 388*cc594af6SKathleen Capella hob_list.add(fv_hob) 389*cc594af6SKathleen Capella if ns_buffer_hob is not None: 390*cc594af6SKathleen Capella hob_list.add(ns_buffer_hob) 391*cc594af6SKathleen Capella if mmram_reserve_hob is not None: 392*cc594af6SKathleen Capella hob_list.add(mmram_reserve_hob) 393*cc594af6SKathleen Capella if shared_buf_hob is not None: 394*cc594af6SKathleen Capella hob_list.add(shared_buf_hob) 395*cc594af6SKathleen Capella 396*cc594af6SKathleen Capella return hob_list 397