1
2
3
4
5
6
7
8
9
10
11
12
13#include <efi_selftest.h>
14
15#define EFI_ST_NUM_PAGES 8
16
17static const efi_guid_t fdt_guid = EFI_FDT_GUID;
18static struct efi_boot_services *boottime;
19static u64 fdt_addr;
20
21
22
23
24
25
26
27
28static int setup(const efi_handle_t handle,
29 const struct efi_system_table *systable)
30{
31 size_t i;
32
33 boottime = systable->boottime;
34
35 for (i = 0; i < systable->nr_tables; ++i) {
36 if (!memcmp(&systable->tables[i].guid, &fdt_guid,
37 sizeof(efi_guid_t))) {
38 if (fdt_addr) {
39 efi_st_error("Duplicate device tree\n");
40 return EFI_ST_FAILURE;
41 }
42 fdt_addr = (uintptr_t)systable->tables[i].table;
43 }
44 }
45 return EFI_ST_SUCCESS;
46}
47
48
49
50
51
52
53
54
55
56
57static int find_in_memory_map(efi_uintn_t map_size,
58 struct efi_mem_desc *memory_map,
59 efi_uintn_t desc_size,
60 u64 addr, int memory_type)
61{
62 efi_uintn_t i;
63 bool found = false;
64
65 for (i = 0; map_size; ++i, map_size -= desc_size) {
66 struct efi_mem_desc *entry = &memory_map[i];
67
68 if (entry->physical_start != entry->virtual_start) {
69 efi_st_error("Physical and virtual addresses do not match\n");
70 return EFI_ST_FAILURE;
71 }
72
73 if (addr >= entry->physical_start &&
74 addr < entry->physical_start +
75 (entry->num_pages << EFI_PAGE_SHIFT)) {
76 if (found) {
77 efi_st_error("Duplicate memory map entry\n");
78 return EFI_ST_FAILURE;
79 }
80 found = true;
81 if (memory_type != entry->type) {
82 efi_st_error
83 ("Wrong memory type %d, expected %d\n",
84 entry->type, memory_type);
85 return EFI_ST_FAILURE;
86 }
87 }
88 }
89 if (!found) {
90 efi_st_error("Missing memory map entry\n");
91 return EFI_ST_FAILURE;
92 }
93 return EFI_ST_SUCCESS;
94}
95
96
97
98
99
100
101static int execute(void)
102{
103 u64 p1;
104 u64 p2;
105 efi_uintn_t map_size = 0;
106 efi_uintn_t map_key;
107 efi_uintn_t desc_size;
108 u32 desc_version;
109 struct efi_mem_desc *memory_map;
110 efi_status_t ret;
111
112
113 ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
114 EFI_RUNTIME_SERVICES_CODE,
115 EFI_ST_NUM_PAGES, &p1);
116 if (ret != EFI_SUCCESS) {
117 efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
118 return EFI_ST_FAILURE;
119 }
120 ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
121 EFI_RUNTIME_SERVICES_DATA,
122 EFI_ST_NUM_PAGES, &p2);
123 if (ret != EFI_SUCCESS) {
124 efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
125 return EFI_ST_FAILURE;
126 }
127
128
129 ret = boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size,
130 &desc_version);
131 if (ret != EFI_BUFFER_TOO_SMALL) {
132 efi_st_error
133 ("GetMemoryMap did not return EFI_BUFFER_TOO_SMALL\n");
134 return EFI_ST_FAILURE;
135 }
136
137 map_size += sizeof(struct efi_mem_desc);
138 ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size,
139 (void **)&memory_map);
140 if (ret != EFI_SUCCESS) {
141 efi_st_error("AllocatePool did not return EFI_SUCCESS\n");
142 return EFI_ST_FAILURE;
143 }
144 ret = boottime->get_memory_map(&map_size, memory_map, &map_key,
145 &desc_size, &desc_version);
146 if (ret != EFI_SUCCESS) {
147 efi_st_error("GetMemoryMap did not return EFI_SUCCESS\n");
148 return EFI_ST_FAILURE;
149 }
150
151
152 if (find_in_memory_map(map_size, memory_map, desc_size, p1,
153 EFI_RUNTIME_SERVICES_CODE) != EFI_ST_SUCCESS)
154 return EFI_ST_FAILURE;
155 if (find_in_memory_map(map_size, memory_map, desc_size, p2,
156 EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS)
157 return EFI_ST_FAILURE;
158
159
160 ret = boottime->free_pages(p1, EFI_ST_NUM_PAGES);
161 if (ret != EFI_SUCCESS) {
162 efi_st_error("FreePages did not return EFI_SUCCESS\n");
163 return EFI_ST_FAILURE;
164 }
165 ret = boottime->free_pages(p2, EFI_ST_NUM_PAGES);
166 if (ret != EFI_SUCCESS) {
167 efi_st_error("FreePages did not return EFI_SUCCESS\n");
168 return EFI_ST_FAILURE;
169 }
170 ret = boottime->free_pool(memory_map);
171 if (ret != EFI_SUCCESS) {
172 efi_st_error("FreePool did not return EFI_SUCCESS\n");
173 return EFI_ST_FAILURE;
174 }
175
176
177 if (fdt_addr &&
178 find_in_memory_map(map_size, memory_map, desc_size, fdt_addr,
179 EFI_BOOT_SERVICES_DATA) != EFI_ST_SUCCESS) {
180 efi_st_error
181 ("Device tree not marked as boot services data\n");
182 return EFI_ST_FAILURE;
183 }
184 return EFI_ST_SUCCESS;
185}
186
187EFI_UNIT_TEST(memory) = {
188 .name = "memory",
189 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
190 .setup = setup,
191 .execute = execute,
192};
193