blob: 5f39cf22da79bce64f9dfca4d00cc48453a0248f [file] [log] [blame]
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
4 *
5 * dtbdump.efi saves the device tree provided as a configuration table
6 * to a file.
7 */
8
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +01009#include <efi_api.h>
Heinrich Schuchardt45910792020-12-13 19:13:57 +010010#include <efi_dt_fixup.h>
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +010011#include <part.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060012#include <linux/libfdt.h>
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +010013
14#define BUFFER_SIZE 64
15#define ESC 0x17
Heinrich Schuchardt45910792020-12-13 19:13:57 +010016
17#define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +010018
19static struct efi_simple_text_output_protocol *cerr;
20static struct efi_simple_text_output_protocol *cout;
21static struct efi_simple_text_input_protocol *cin;
22static struct efi_boot_services *bs;
23static const efi_guid_t fdt_guid = EFI_FDT_GUID;
24static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
25static const efi_guid_t guid_simple_file_system_protocol =
26 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
Heinrich Schuchardt45910792020-12-13 19:13:57 +010027static efi_handle_t handle;
28static struct efi_system_table *systable;
29static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID;
30static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +010031static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
Heinrich Schuchardt45910792020-12-13 19:13:57 +010032
33/**
Heinrich Schuchardt9d4c19e2021-01-19 10:06:00 +010034 * print() - print string
35 *
36 * @string: text
37 */
38static void print(u16 *string)
39{
40 cout->output_string(cout, string);
41}
42
43/**
Heinrich Schuchardt45910792020-12-13 19:13:57 +010044 * error() - print error string
45 *
46 * @string: error text
47 */
48static void error(u16 *string)
49{
50 cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
Heinrich Schuchardt9d4c19e2021-01-19 10:06:00 +010051 print(string);
Heinrich Schuchardt45910792020-12-13 19:13:57 +010052 cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
53}
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +010054
55/**
Heinrich Schuchardt2e88aad2021-01-17 05:13:21 +010056 * efi_input_yn() - get answer to yes/no question
57 *
58 * Return:
59 * y or Y
60 * EFI_SUCCESS
61 * n or N
62 * EFI_ACCESS_DENIED
63 * ESC
64 * EFI_ABORTED
65 */
66static efi_status_t efi_input_yn(void)
67{
68 struct efi_input_key key = {0};
69 efi_uintn_t index;
70 efi_status_t ret;
71
72 /* Drain the console input */
73 ret = cin->reset(cin, true);
74 for (;;) {
75 ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
76 if (ret != EFI_SUCCESS)
77 continue;
78 ret = cin->read_key_stroke(cin, &key);
79 if (ret != EFI_SUCCESS)
80 continue;
81 switch (key.scan_code) {
82 case 0x17: /* Escape */
83 return EFI_ABORTED;
84 default:
85 break;
86 }
87 /* Convert to lower case */
88 switch (key.unicode_char | 0x20) {
89 case 'y':
90 return EFI_SUCCESS;
91 case 'n':
92 return EFI_ACCESS_DENIED;
93 default:
94 break;
95 }
96 }
97}
98
99/**
100 * efi_input() - read string from console
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100101 *
102 * @buffer: input buffer
103 * @buffer_size: buffer size
104 * Return: status code
105 */
106static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
107{
108 struct efi_input_key key = {0};
109 efi_uintn_t index;
110 efi_uintn_t pos = 0;
Simon Glass90975372022-01-23 12:55:12 -0700111 u16 outbuf[2] = u" ";
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100112 efi_status_t ret;
113
114 /* Drain the console input */
115 ret = cin->reset(cin, true);
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100116 *buffer = 0;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100117 for (;;) {
118 ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
119 if (ret != EFI_SUCCESS)
120 continue;
121 ret = cin->read_key_stroke(cin, &key);
122 if (ret != EFI_SUCCESS)
123 continue;
124 switch (key.scan_code) {
125 case 0x17: /* Escape */
Simon Glass90975372022-01-23 12:55:12 -0700126 print(u"\r\nAborted\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100127 return EFI_ABORTED;
128 default:
129 break;
130 }
131 switch (key.unicode_char) {
132 case 0x08: /* Backspace */
133 if (pos) {
134 buffer[pos--] = 0;
Simon Glass90975372022-01-23 12:55:12 -0700135 print(u"\b \b");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100136 }
137 break;
138 case 0x0a: /* Linefeed */
139 case 0x0d: /* Carriage return */
Simon Glass90975372022-01-23 12:55:12 -0700140 print(u"\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100141 return EFI_SUCCESS;
142 default:
143 break;
144 }
145 /* Ignore surrogate codes */
146 if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
147 continue;
148 if (key.unicode_char >= 0x20 &&
149 pos < buffer_size - 1) {
150 *outbuf = key.unicode_char;
151 buffer[pos++] = key.unicode_char;
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100152 buffer[pos] = 0;
Heinrich Schuchardt9d4c19e2021-01-19 10:06:00 +0100153 print(outbuf);
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100154 }
155 }
156}
157
158/*
159 * Convert FDT value to host endianness.
160 *
161 * @val FDT value
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100162 * Return: converted value
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100163 */
164static u32 f2h(fdt32_t val)
165{
166 char *buf = (char *)&val;
167 char i;
168
169 /* Swap the bytes */
170 i = buf[0]; buf[0] = buf[3]; buf[3] = i;
171 i = buf[1]; buf[1] = buf[2]; buf[2] = i;
172 return *(u32 *)buf;
173}
174
175/**
176 * get_dtb() - get device tree
177 *
178 * @systable: system table
179 * Return: device tree or NULL
180 */
181void *get_dtb(struct efi_system_table *systable)
182{
183 void *dtb = NULL;
184 efi_uintn_t i;
185
186 for (i = 0; i < systable->nr_tables; ++i) {
187 if (!memcmp(&systable->tables[i].guid, &fdt_guid,
188 sizeof(efi_guid_t))) {
189 dtb = systable->tables[i].table;
190 break;
191 }
192 }
193 return dtb;
194}
195
196/**
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100197 * skip_whitespace() - skip over leading whitespace
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100198 *
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100199 * @pos: UTF-16 string
200 * Return: pointer to first non-whitespace
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100201 */
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100202u16 *skip_whitespace(u16 *pos)
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100203{
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100204 for (; *pos && *pos <= 0x20; ++pos)
205 ;
206 return pos;
207}
208
209/**
210 * starts_with() - check if @string starts with @keyword
211 *
212 * @string: string to search for keyword
213 * @keyword: keyword to be searched
214 * Return: true fi @string starts with the keyword
215 */
216bool starts_with(u16 *string, u16 *keyword)
217{
218 for (; *keyword; ++string, ++keyword) {
219 if (*string != *keyword)
220 return false;
221 }
222 return true;
223}
224
225/**
226 * do_help() - print help
227 */
228void do_help(void)
229{
Simon Glass90975372022-01-23 12:55:12 -0700230 error(u"load <dtb> - load device-tree from file\r\n");
231 error(u"save <dtb> - save device-tree to file\r\n");
232 error(u"exit - exit the shell\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100233}
234
235/**
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +0100236 * open_file_system() - open simple file system protocol
237 *
238 * file_system: interface of the simple file system protocol
239 * Return: status code
240 */
241static efi_status_t
242open_file_system(struct efi_simple_file_system_protocol **file_system)
243{
244 struct efi_loaded_image *loaded_image;
245 efi_status_t ret;
246 efi_handle_t *handle_buffer = NULL;
247 efi_uintn_t count;
248
249 ret = bs->open_protocol(handle, &loaded_image_guid,
250 (void **)&loaded_image, NULL, NULL,
251 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
252 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700253 error(u"Loaded image protocol not found\r\n");
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +0100254 return ret;
255 }
256
257 /* Open the simple file system protocol on the same partition */
258 ret = bs->open_protocol(loaded_image->device_handle,
259 &guid_simple_file_system_protocol,
260 (void **)file_system, NULL, NULL,
261 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
262 if (ret == EFI_SUCCESS)
263 return ret;
264
265 /* Open the simple file system protocol on the UEFI system partition */
266 ret = bs->locate_handle_buffer(BY_PROTOCOL, &efi_system_partition_guid,
267 NULL, &count, &handle_buffer);
268 if (ret == EFI_SUCCESS && handle_buffer)
269 ret = bs->open_protocol(handle_buffer[0],
270 &guid_simple_file_system_protocol,
271 (void **)file_system, NULL, NULL,
272 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
273 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700274 error(u"Failed to open simple file system protocol\r\n");
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +0100275 if (handle)
276 bs->free_pool(handle_buffer);
277
278 return ret;
279}
280
281/**
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100282 * do_load() - load and install device-tree
283 *
284 * @filename: file name
285 * Return: status code
286 */
287efi_status_t do_load(u16 *filename)
288{
289 struct efi_dt_fixup_protocol *dt_fixup_prot;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100290 struct efi_simple_file_system_protocol *file_system;
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100291 struct efi_file_handle *root = NULL, *file = NULL;
292 u64 addr = 0;
293 struct efi_file_info *info;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100294 struct fdt_header *dtb;
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100295 efi_uintn_t buffer_size;
296 efi_uintn_t pages;
297 efi_status_t ret, ret2;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100298
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100299 ret = bs->locate_protocol(&efi_dt_fixup_protocol_guid, NULL,
300 (void **)&dt_fixup_prot);
301 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700302 error(u"Device-tree fix-up protocol not found\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100303 return ret;
304 }
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100305
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100306 filename = skip_whitespace(filename);
307
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +0100308 ret = open_file_system(&file_system);
309 if (ret != EFI_SUCCESS)
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100310 goto out;
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100311
312 /* Open volume */
313 ret = file_system->open_volume(file_system, &root);
314 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700315 error(u"Failed to open volume\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100316 goto out;
317 }
318
319 /* Open file */
320 ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0);
321 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700322 error(u"File not found\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100323 goto out;
324 }
325 /* Get file size */
326 buffer_size = 0;
327 ret = file->getinfo(file, &efi_file_info_guid, &buffer_size, NULL);
328 if (ret != EFI_BUFFER_TOO_SMALL) {
Simon Glass90975372022-01-23 12:55:12 -0700329 error(u"Can't get file info size\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100330 goto out;
331 }
332 ret = bs->allocate_pool(EFI_LOADER_DATA, buffer_size, (void **)&info);
333 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700334 error(u"Out of memory\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100335 goto out;
336 }
337 ret = file->getinfo(file, &efi_file_info_guid, &buffer_size, info);
338 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700339 error(u"Can't get file info\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100340 goto out;
341 }
342 buffer_size = info->file_size;
343 pages = efi_size_in_pages(buffer_size);
344 ret = bs->free_pool(info);
345 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700346 error(u"Can't free memory pool\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100347 /* Read file */
348 ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
349 EFI_ACPI_RECLAIM_MEMORY,
350 pages, &addr);
351 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700352 error(u"Out of memory\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100353 goto out;
354 }
355 dtb = (struct fdt_header *)(uintptr_t)addr;
356 ret = file->read(file, &buffer_size, dtb);
357 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700358 error(u"Can't read file\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100359 goto out;
360 }
361 /* Fixup file, expecting EFI_BUFFER_TOO_SMALL */
362 ret = dt_fixup_prot->fixup(dt_fixup_prot, dtb, &buffer_size,
363 EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY |
364 EFI_DT_INSTALL_TABLE);
365 if (ret == EFI_BUFFER_TOO_SMALL) {
366 /* Read file into larger buffer */
367 ret = bs->free_pages(addr, pages);
368 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700369 error(u"Can't free memory pages\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100370 pages = efi_size_in_pages(buffer_size);
371 ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
372 EFI_ACPI_RECLAIM_MEMORY,
373 pages, &addr);
374 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700375 error(u"Out of memory\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100376 goto out;
377 }
378 dtb = (struct fdt_header *)(uintptr_t)addr;
379 ret = file->setpos(file, 0);
380 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700381 error(u"Can't position file\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100382 goto out;
383 }
384 ret = file->read(file, &buffer_size, dtb);
385 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700386 error(u"Can't read file\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100387 goto out;
388 }
389 buffer_size = pages << EFI_PAGE_SHIFT;
390 ret = dt_fixup_prot->fixup(
391 dt_fixup_prot, dtb, &buffer_size,
392 EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY |
393 EFI_DT_INSTALL_TABLE);
394 }
395 if (ret == EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700396 print(u"device-tree installed\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100397 else
Simon Glass90975372022-01-23 12:55:12 -0700398 error(u"Device-tree fix-up failed\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100399out:
400 if (addr) {
401 ret2 = bs->free_pages(addr, pages);
402 if (ret2 != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700403 error(u"Can't free memory pages\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100404 }
405 if (file) {
406 ret2 = file->close(file);
407 if (ret2 != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700408 error(u"Can't close file\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100409 }
410 if (root) {
411 ret2 = root->close(root);
412 if (ret2 != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700413 error(u"Can't close volume\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100414 }
415 return ret;
416}
417
418/**
419 * do_save() - save current device-tree
420 *
421 * @filename: file name
422 * Return: status code
423 */
424efi_status_t do_save(u16 *filename)
425{
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100426 struct efi_simple_file_system_protocol *file_system;
427 efi_uintn_t dtb_size;
428 struct efi_file_handle *root, *file;
429 struct fdt_header *dtb;
430 efi_uintn_t ret;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100431
432 dtb = get_dtb(systable);
433 if (!dtb) {
Simon Glass90975372022-01-23 12:55:12 -0700434 error(u"DTB not found\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100435 return EFI_NOT_FOUND;
436 }
437 if (f2h(dtb->magic) != FDT_MAGIC) {
Simon Glass90975372022-01-23 12:55:12 -0700438 error(u"Wrong device tree magic\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100439 return EFI_NOT_FOUND;
440 }
441 dtb_size = f2h(dtb->totalsize);
442
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100443 filename = skip_whitespace(filename);
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100444
Heinrich Schuchardtfd20d8a2021-02-02 18:02:19 +0100445 ret = open_file_system(&file_system);
446 if (ret != EFI_SUCCESS)
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100447 return ret;
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100448
449 /* Open volume */
450 ret = file_system->open_volume(file_system, &root);
451 if (ret != EFI_SUCCESS) {
Simon Glass90975372022-01-23 12:55:12 -0700452 error(u"Failed to open volume\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100453 return ret;
454 }
Heinrich Schuchardt2e88aad2021-01-17 05:13:21 +0100455 /* Check if file already exists */
456 ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0);
457 if (ret == EFI_SUCCESS) {
458 file->close(file);
Simon Glass90975372022-01-23 12:55:12 -0700459 print(u"Overwrite existing file (y/n)? ");
Heinrich Schuchardt2e88aad2021-01-17 05:13:21 +0100460 ret = efi_input_yn();
Simon Glass90975372022-01-23 12:55:12 -0700461 print(u"\r\n");
Heinrich Schuchardt2e88aad2021-01-17 05:13:21 +0100462 if (ret != EFI_SUCCESS) {
463 root->close(root);
Simon Glass90975372022-01-23 12:55:12 -0700464 error(u"Aborted by user\r\n");
Heinrich Schuchardt2e88aad2021-01-17 05:13:21 +0100465 return ret;
466 }
467 }
468
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100469 /* Create file */
470 ret = root->open(root, &file, filename,
471 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
472 EFI_FILE_MODE_CREATE, EFI_FILE_ARCHIVE);
473 if (ret == EFI_SUCCESS) {
474 /* Write file */
475 ret = file->write(file, &dtb_size, dtb);
476 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700477 error(u"Failed to write file\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100478 file->close(file);
479 } else {
Simon Glass90975372022-01-23 12:55:12 -0700480 error(u"Failed to open file\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100481 }
482 root->close(root);
483
484 if (ret == EFI_SUCCESS) {
Heinrich Schuchardt9d4c19e2021-01-19 10:06:00 +0100485 print(filename);
Simon Glass90975372022-01-23 12:55:12 -0700486 print(u" written\r\n");
Heinrich Schuchardt12083ba2020-11-04 22:00:48 +0100487 }
488
489 return ret;
490}
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100491
492/**
493 * efi_main() - entry point of the EFI application.
494 *
495 * @handle: handle of the loaded image
496 * @systab: system table
Heinrich Schuchardtfbe90212022-01-20 19:48:20 +0100497 * Return: status code
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100498 */
499efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
500 struct efi_system_table *systab)
501{
502 handle = image_handle;
503 systable = systab;
504 cerr = systable->std_err;
505 cout = systable->con_out;
506 cin = systable->con_in;
507 bs = systable->boottime;
508
509 cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
510 cout->clear_screen(cout);
511 cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK);
Simon Glass90975372022-01-23 12:55:12 -0700512 print(u"DTB Dump\r\n========\r\n\r\n");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100513 cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
514
515 for (;;) {
516 u16 command[BUFFER_SIZE];
517 u16 *pos;
518 efi_uintn_t ret;
519
Simon Glass90975372022-01-23 12:55:12 -0700520 print(u"=> ");
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100521 ret = efi_input(command, sizeof(command));
522 if (ret == EFI_ABORTED)
523 break;
524 pos = skip_whitespace(command);
Simon Glass90975372022-01-23 12:55:12 -0700525 if (starts_with(pos, u"exit"))
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100526 break;
Simon Glass90975372022-01-23 12:55:12 -0700527 else if (starts_with(pos, u"load "))
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100528 do_load(pos + 5);
Simon Glass90975372022-01-23 12:55:12 -0700529 else if (starts_with(pos, u"save "))
Heinrich Schuchardt45910792020-12-13 19:13:57 +0100530 do_save(pos + 5);
531 else
532 do_help();
533 }
534
535 cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
536 cout->clear_screen(cout);
537 return EFI_SUCCESS;
538}