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