1*a7314259SXiaoyao Li /* 2*a7314259SXiaoyao Li * Copyright (c) 2025 Intel Corporation 3*a7314259SXiaoyao Li * Author: Isaku Yamahata <isaku.yamahata at gmail.com> 4*a7314259SXiaoyao Li * <isaku.yamahata at intel.com> 5*a7314259SXiaoyao Li * Xiaoyao Li <xiaoyao.li@intel.com> 6*a7314259SXiaoyao Li * 7*a7314259SXiaoyao Li * SPDX-License-Identifier: GPL-2.0-or-later 8*a7314259SXiaoyao Li */ 9*a7314259SXiaoyao Li 10*a7314259SXiaoyao Li #include "qemu/osdep.h" 11*a7314259SXiaoyao Li #include "qemu/error-report.h" 12*a7314259SXiaoyao Li #include "standard-headers/uefi/uefi.h" 13*a7314259SXiaoyao Li #include "hw/pci/pcie_host.h" 14*a7314259SXiaoyao Li #include "tdvf-hob.h" 15*a7314259SXiaoyao Li 16*a7314259SXiaoyao Li typedef struct TdvfHob { 17*a7314259SXiaoyao Li hwaddr hob_addr; 18*a7314259SXiaoyao Li void *ptr; 19*a7314259SXiaoyao Li int size; 20*a7314259SXiaoyao Li 21*a7314259SXiaoyao Li /* working area */ 22*a7314259SXiaoyao Li void *current; 23*a7314259SXiaoyao Li void *end; 24*a7314259SXiaoyao Li } TdvfHob; 25*a7314259SXiaoyao Li 26*a7314259SXiaoyao Li static uint64_t tdvf_current_guest_addr(const TdvfHob *hob) 27*a7314259SXiaoyao Li { 28*a7314259SXiaoyao Li return hob->hob_addr + (hob->current - hob->ptr); 29*a7314259SXiaoyao Li } 30*a7314259SXiaoyao Li 31*a7314259SXiaoyao Li static void tdvf_align(TdvfHob *hob, size_t align) 32*a7314259SXiaoyao Li { 33*a7314259SXiaoyao Li hob->current = QEMU_ALIGN_PTR_UP(hob->current, align); 34*a7314259SXiaoyao Li } 35*a7314259SXiaoyao Li 36*a7314259SXiaoyao Li static void *tdvf_get_area(TdvfHob *hob, uint64_t size) 37*a7314259SXiaoyao Li { 38*a7314259SXiaoyao Li void *ret; 39*a7314259SXiaoyao Li 40*a7314259SXiaoyao Li if (hob->current + size > hob->end) { 41*a7314259SXiaoyao Li error_report("TD_HOB overrun, size = 0x%" PRIx64, size); 42*a7314259SXiaoyao Li exit(1); 43*a7314259SXiaoyao Li } 44*a7314259SXiaoyao Li 45*a7314259SXiaoyao Li ret = hob->current; 46*a7314259SXiaoyao Li hob->current += size; 47*a7314259SXiaoyao Li tdvf_align(hob, 8); 48*a7314259SXiaoyao Li return ret; 49*a7314259SXiaoyao Li } 50*a7314259SXiaoyao Li 51*a7314259SXiaoyao Li static void tdvf_hob_add_memory_resources(TdxGuest *tdx, TdvfHob *hob) 52*a7314259SXiaoyao Li { 53*a7314259SXiaoyao Li EFI_HOB_RESOURCE_DESCRIPTOR *region; 54*a7314259SXiaoyao Li EFI_RESOURCE_ATTRIBUTE_TYPE attr; 55*a7314259SXiaoyao Li EFI_RESOURCE_TYPE resource_type; 56*a7314259SXiaoyao Li 57*a7314259SXiaoyao Li TdxRamEntry *e; 58*a7314259SXiaoyao Li int i; 59*a7314259SXiaoyao Li 60*a7314259SXiaoyao Li for (i = 0; i < tdx->nr_ram_entries; i++) { 61*a7314259SXiaoyao Li e = &tdx->ram_entries[i]; 62*a7314259SXiaoyao Li 63*a7314259SXiaoyao Li if (e->type == TDX_RAM_UNACCEPTED) { 64*a7314259SXiaoyao Li resource_type = EFI_RESOURCE_MEMORY_UNACCEPTED; 65*a7314259SXiaoyao Li attr = EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED; 66*a7314259SXiaoyao Li } else if (e->type == TDX_RAM_ADDED) { 67*a7314259SXiaoyao Li resource_type = EFI_RESOURCE_SYSTEM_MEMORY; 68*a7314259SXiaoyao Li attr = EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE; 69*a7314259SXiaoyao Li } else { 70*a7314259SXiaoyao Li error_report("unknown TDX_RAM_ENTRY type %d", e->type); 71*a7314259SXiaoyao Li exit(1); 72*a7314259SXiaoyao Li } 73*a7314259SXiaoyao Li 74*a7314259SXiaoyao Li region = tdvf_get_area(hob, sizeof(*region)); 75*a7314259SXiaoyao Li *region = (EFI_HOB_RESOURCE_DESCRIPTOR) { 76*a7314259SXiaoyao Li .Header = { 77*a7314259SXiaoyao Li .HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, 78*a7314259SXiaoyao Li .HobLength = cpu_to_le16(sizeof(*region)), 79*a7314259SXiaoyao Li .Reserved = cpu_to_le32(0), 80*a7314259SXiaoyao Li }, 81*a7314259SXiaoyao Li .Owner = EFI_HOB_OWNER_ZERO, 82*a7314259SXiaoyao Li .ResourceType = cpu_to_le32(resource_type), 83*a7314259SXiaoyao Li .ResourceAttribute = cpu_to_le32(attr), 84*a7314259SXiaoyao Li .PhysicalStart = cpu_to_le64(e->address), 85*a7314259SXiaoyao Li .ResourceLength = cpu_to_le64(e->length), 86*a7314259SXiaoyao Li }; 87*a7314259SXiaoyao Li } 88*a7314259SXiaoyao Li } 89*a7314259SXiaoyao Li 90*a7314259SXiaoyao Li void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob) 91*a7314259SXiaoyao Li { 92*a7314259SXiaoyao Li TdvfHob hob = { 93*a7314259SXiaoyao Li .hob_addr = td_hob->address, 94*a7314259SXiaoyao Li .size = td_hob->size, 95*a7314259SXiaoyao Li .ptr = td_hob->mem_ptr, 96*a7314259SXiaoyao Li 97*a7314259SXiaoyao Li .current = td_hob->mem_ptr, 98*a7314259SXiaoyao Li .end = td_hob->mem_ptr + td_hob->size, 99*a7314259SXiaoyao Li }; 100*a7314259SXiaoyao Li 101*a7314259SXiaoyao Li EFI_HOB_GENERIC_HEADER *last_hob; 102*a7314259SXiaoyao Li EFI_HOB_HANDOFF_INFO_TABLE *hit; 103*a7314259SXiaoyao Li 104*a7314259SXiaoyao Li /* Note, Efi{Free}Memory{Bottom,Top} are ignored, leave 'em zeroed. */ 105*a7314259SXiaoyao Li hit = tdvf_get_area(&hob, sizeof(*hit)); 106*a7314259SXiaoyao Li *hit = (EFI_HOB_HANDOFF_INFO_TABLE) { 107*a7314259SXiaoyao Li .Header = { 108*a7314259SXiaoyao Li .HobType = EFI_HOB_TYPE_HANDOFF, 109*a7314259SXiaoyao Li .HobLength = cpu_to_le16(sizeof(*hit)), 110*a7314259SXiaoyao Li .Reserved = cpu_to_le32(0), 111*a7314259SXiaoyao Li }, 112*a7314259SXiaoyao Li .Version = cpu_to_le32(EFI_HOB_HANDOFF_TABLE_VERSION), 113*a7314259SXiaoyao Li .BootMode = cpu_to_le32(0), 114*a7314259SXiaoyao Li .EfiMemoryTop = cpu_to_le64(0), 115*a7314259SXiaoyao Li .EfiMemoryBottom = cpu_to_le64(0), 116*a7314259SXiaoyao Li .EfiFreeMemoryTop = cpu_to_le64(0), 117*a7314259SXiaoyao Li .EfiFreeMemoryBottom = cpu_to_le64(0), 118*a7314259SXiaoyao Li .EfiEndOfHobList = cpu_to_le64(0), /* initialized later */ 119*a7314259SXiaoyao Li }; 120*a7314259SXiaoyao Li 121*a7314259SXiaoyao Li tdvf_hob_add_memory_resources(tdx, &hob); 122*a7314259SXiaoyao Li 123*a7314259SXiaoyao Li last_hob = tdvf_get_area(&hob, sizeof(*last_hob)); 124*a7314259SXiaoyao Li *last_hob = (EFI_HOB_GENERIC_HEADER) { 125*a7314259SXiaoyao Li .HobType = EFI_HOB_TYPE_END_OF_HOB_LIST, 126*a7314259SXiaoyao Li .HobLength = cpu_to_le16(sizeof(*last_hob)), 127*a7314259SXiaoyao Li .Reserved = cpu_to_le32(0), 128*a7314259SXiaoyao Li }; 129*a7314259SXiaoyao Li hit->EfiEndOfHobList = tdvf_current_guest_addr(&hob); 130*a7314259SXiaoyao Li } 131