xref: /openbmc/qemu/hw/i386/tdvf-hob.c (revision 98721058d6d50ef218e0c26e4f67c8ef96965859)
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 
tdvf_current_guest_addr(const TdvfHob * hob)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 
tdvf_align(TdvfHob * hob,size_t align)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 
tdvf_get_area(TdvfHob * hob,uint64_t size)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 
tdvf_hob_add_memory_resources(TdxGuest * tdx,TdvfHob * hob)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 
tdvf_hob_create(TdxGuest * tdx,TdxFirmwareEntry * td_hob)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