efi_boottime.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /*
  2. * EFI application boot time services
  3. *
  4. * Copyright (c) 2016 Alexander Graf
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <efi_loader.h>
  10. #include <malloc.h>
  11. #include <asm/global_data.h>
  12. #include <libfdt_env.h>
  13. #include <u-boot/crc.h>
  14. #include <bootm.h>
  15. #include <inttypes.h>
  16. #include <watchdog.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. /* This list contains all the EFI objects our payload has access to */
  19. LIST_HEAD(efi_obj_list);
  20. /*
  21. * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
  22. * we need to do trickery with caches. Since we don't want to break the EFI
  23. * aware boot path, only apply hacks when loading exiting directly (breaking
  24. * direct Linux EFI booting along the way - oh well).
  25. */
  26. static bool efi_is_direct_boot = true;
  27. /*
  28. * EFI can pass arbitrary additional "tables" containing vendor specific
  29. * information to the payload. One such table is the FDT table which contains
  30. * a pointer to a flattened device tree blob.
  31. *
  32. * In most cases we want to pass an FDT to the payload, so reserve one slot of
  33. * config table space for it. The pointer gets populated by do_bootefi_exec().
  34. */
  35. static struct efi_configuration_table __efi_runtime_data efi_conf_table[2];
  36. #ifdef CONFIG_ARM
  37. /*
  38. * The "gd" pointer lives in a register on ARM and AArch64 that we declare
  39. * fixed when compiling U-Boot. However, the payload does not know about that
  40. * restriction so we need to manually swap its and our view of that register on
  41. * EFI callback entry/exit.
  42. */
  43. static volatile void *efi_gd, *app_gd;
  44. #endif
  45. /* Called from do_bootefi_exec() */
  46. void efi_save_gd(void)
  47. {
  48. #ifdef CONFIG_ARM
  49. efi_gd = gd;
  50. #endif
  51. }
  52. /* Called on every callback entry */
  53. void efi_restore_gd(void)
  54. {
  55. #ifdef CONFIG_ARM
  56. /* Only restore if we're already in EFI context */
  57. if (!efi_gd)
  58. return;
  59. if (gd != efi_gd)
  60. app_gd = gd;
  61. gd = efi_gd;
  62. #endif
  63. }
  64. /* Called on every callback exit */
  65. efi_status_t efi_exit_func(efi_status_t ret)
  66. {
  67. #ifdef CONFIG_ARM
  68. gd = app_gd;
  69. #endif
  70. return ret;
  71. }
  72. static efi_status_t efi_unsupported(const char *funcname)
  73. {
  74. debug("EFI: App called into unimplemented function %s\n", funcname);
  75. return EFI_EXIT(EFI_UNSUPPORTED);
  76. }
  77. static int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
  78. {
  79. return memcmp(g1, g2, sizeof(efi_guid_t));
  80. }
  81. static unsigned long EFIAPI efi_raise_tpl(unsigned long new_tpl)
  82. {
  83. EFI_ENTRY("0x%lx", new_tpl);
  84. return EFI_EXIT(0);
  85. }
  86. static void EFIAPI efi_restore_tpl(unsigned long old_tpl)
  87. {
  88. EFI_ENTRY("0x%lx", old_tpl);
  89. EFI_EXIT(efi_unsupported(__func__));
  90. }
  91. static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
  92. unsigned long pages,
  93. uint64_t *memory)
  94. {
  95. efi_status_t r;
  96. EFI_ENTRY("%d, %d, 0x%lx, %p", type, memory_type, pages, memory);
  97. r = efi_allocate_pages(type, memory_type, pages, memory);
  98. return EFI_EXIT(r);
  99. }
  100. static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
  101. unsigned long pages)
  102. {
  103. efi_status_t r;
  104. EFI_ENTRY("%"PRIx64", 0x%lx", memory, pages);
  105. r = efi_free_pages(memory, pages);
  106. return EFI_EXIT(r);
  107. }
  108. static efi_status_t EFIAPI efi_get_memory_map_ext(
  109. unsigned long *memory_map_size,
  110. struct efi_mem_desc *memory_map,
  111. unsigned long *map_key,
  112. unsigned long *descriptor_size,
  113. uint32_t *descriptor_version)
  114. {
  115. efi_status_t r;
  116. EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size, memory_map,
  117. map_key, descriptor_size, descriptor_version);
  118. r = efi_get_memory_map(memory_map_size, memory_map, map_key,
  119. descriptor_size, descriptor_version);
  120. return EFI_EXIT(r);
  121. }
  122. static efi_status_t EFIAPI efi_allocate_pool_ext(int pool_type,
  123. unsigned long size,
  124. void **buffer)
  125. {
  126. efi_status_t r;
  127. EFI_ENTRY("%d, %ld, %p", pool_type, size, buffer);
  128. r = efi_allocate_pool(pool_type, size, buffer);
  129. return EFI_EXIT(r);
  130. }
  131. static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
  132. {
  133. efi_status_t r;
  134. EFI_ENTRY("%p", buffer);
  135. r = efi_free_pool(buffer);
  136. return EFI_EXIT(r);
  137. }
  138. /*
  139. * Our event capabilities are very limited. Only support a single
  140. * event to exist, so we don't need to maintain lists.
  141. */
  142. static struct {
  143. enum efi_event_type type;
  144. u32 trigger_type;
  145. u32 trigger_time;
  146. u64 trigger_next;
  147. unsigned long notify_tpl;
  148. void (EFIAPI *notify_function) (void *event, void *context);
  149. void *notify_context;
  150. } efi_event = {
  151. /* Disable timers on bootup */
  152. .trigger_next = -1ULL,
  153. };
  154. static efi_status_t EFIAPI efi_create_event(
  155. enum efi_event_type type, ulong notify_tpl,
  156. void (EFIAPI *notify_function) (void *event,
  157. void *context),
  158. void *notify_context, void **event)
  159. {
  160. EFI_ENTRY("%d, 0x%lx, %p, %p", type, notify_tpl, notify_function,
  161. notify_context);
  162. if (efi_event.notify_function) {
  163. /* We only support one event at a time */
  164. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  165. }
  166. if (event == NULL)
  167. return EFI_EXIT(EFI_INVALID_PARAMETER);
  168. if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
  169. return EFI_EXIT(EFI_INVALID_PARAMETER);
  170. if ((type & (EVT_NOTIFY_SIGNAL|EVT_NOTIFY_WAIT)) &&
  171. notify_function == NULL)
  172. return EFI_EXIT(EFI_INVALID_PARAMETER);
  173. efi_event.type = type;
  174. efi_event.notify_tpl = notify_tpl;
  175. efi_event.notify_function = notify_function;
  176. efi_event.notify_context = notify_context;
  177. *event = &efi_event;
  178. return EFI_EXIT(EFI_SUCCESS);
  179. }
  180. /*
  181. * Our timers have to work without interrupts, so we check whenever keyboard
  182. * input or disk accesses happen if enough time elapsed for it to fire.
  183. */
  184. void efi_timer_check(void)
  185. {
  186. u64 now = timer_get_us();
  187. if (now >= efi_event.trigger_next) {
  188. /* Triggering! */
  189. if (efi_event.trigger_type == EFI_TIMER_PERIODIC)
  190. efi_event.trigger_next += efi_event.trigger_time / 10;
  191. if (efi_event.type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL))
  192. efi_event.notify_function(&efi_event,
  193. efi_event.notify_context);
  194. }
  195. WATCHDOG_RESET();
  196. }
  197. static efi_status_t EFIAPI efi_set_timer(void *event, int type,
  198. uint64_t trigger_time)
  199. {
  200. /* We don't have 64bit division available everywhere, so limit timer
  201. * distances to 32bit bits. */
  202. u32 trigger32 = trigger_time;
  203. EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time);
  204. if (trigger32 < trigger_time) {
  205. printf("WARNING: Truncating timer from %"PRIx64" to %x\n",
  206. trigger_time, trigger32);
  207. }
  208. if (event != &efi_event) {
  209. /* We only support one event at a time */
  210. return EFI_EXIT(EFI_INVALID_PARAMETER);
  211. }
  212. switch (type) {
  213. case EFI_TIMER_STOP:
  214. efi_event.trigger_next = -1ULL;
  215. break;
  216. case EFI_TIMER_PERIODIC:
  217. case EFI_TIMER_RELATIVE:
  218. efi_event.trigger_next = timer_get_us() + (trigger32 / 10);
  219. break;
  220. default:
  221. return EFI_EXIT(EFI_INVALID_PARAMETER);
  222. }
  223. efi_event.trigger_type = type;
  224. efi_event.trigger_time = trigger_time;
  225. return EFI_EXIT(EFI_SUCCESS);
  226. }
  227. static efi_status_t EFIAPI efi_wait_for_event(unsigned long num_events,
  228. void *event, unsigned long *index)
  229. {
  230. u64 now;
  231. EFI_ENTRY("%ld, %p, %p", num_events, event, index);
  232. now = timer_get_us();
  233. while (now < efi_event.trigger_next) { }
  234. efi_timer_check();
  235. return EFI_EXIT(EFI_SUCCESS);
  236. }
  237. static efi_status_t EFIAPI efi_signal_event(void *event)
  238. {
  239. EFI_ENTRY("%p", event);
  240. return EFI_EXIT(EFI_SUCCESS);
  241. }
  242. static efi_status_t EFIAPI efi_close_event(void *event)
  243. {
  244. EFI_ENTRY("%p", event);
  245. efi_event.trigger_next = -1ULL;
  246. return EFI_EXIT(EFI_SUCCESS);
  247. }
  248. static efi_status_t EFIAPI efi_check_event(void *event)
  249. {
  250. EFI_ENTRY("%p", event);
  251. return EFI_EXIT(EFI_NOT_READY);
  252. }
  253. static efi_status_t EFIAPI efi_install_protocol_interface(void **handle,
  254. efi_guid_t *protocol, int protocol_interface_type,
  255. void *protocol_interface)
  256. {
  257. EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type,
  258. protocol_interface);
  259. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  260. }
  261. static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
  262. efi_guid_t *protocol, void *old_interface,
  263. void *new_interface)
  264. {
  265. EFI_ENTRY("%p, %p, %p, %p", handle, protocol, old_interface,
  266. new_interface);
  267. return EFI_EXIT(EFI_ACCESS_DENIED);
  268. }
  269. static efi_status_t EFIAPI efi_uninstall_protocol_interface(void *handle,
  270. efi_guid_t *protocol, void *protocol_interface)
  271. {
  272. EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface);
  273. return EFI_EXIT(EFI_NOT_FOUND);
  274. }
  275. static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol,
  276. void *event,
  277. void **registration)
  278. {
  279. EFI_ENTRY("%p, %p, %p", protocol, event, registration);
  280. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  281. }
  282. static int efi_search(enum efi_locate_search_type search_type,
  283. efi_guid_t *protocol, void *search_key,
  284. struct efi_object *efiobj)
  285. {
  286. int i;
  287. switch (search_type) {
  288. case all_handles:
  289. return 0;
  290. case by_register_notify:
  291. return -1;
  292. case by_protocol:
  293. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  294. const efi_guid_t *guid = efiobj->protocols[i].guid;
  295. if (guid && !guidcmp(guid, protocol))
  296. return 0;
  297. }
  298. return -1;
  299. }
  300. return -1;
  301. }
  302. static efi_status_t EFIAPI efi_locate_handle(
  303. enum efi_locate_search_type search_type,
  304. efi_guid_t *protocol, void *search_key,
  305. unsigned long *buffer_size, efi_handle_t *buffer)
  306. {
  307. struct list_head *lhandle;
  308. unsigned long size = 0;
  309. EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key,
  310. buffer_size, buffer);
  311. /* Count how much space we need */
  312. list_for_each(lhandle, &efi_obj_list) {
  313. struct efi_object *efiobj;
  314. efiobj = list_entry(lhandle, struct efi_object, link);
  315. if (!efi_search(search_type, protocol, search_key, efiobj)) {
  316. size += sizeof(void*);
  317. }
  318. }
  319. if (*buffer_size < size) {
  320. *buffer_size = size;
  321. return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
  322. }
  323. /* Then fill the array */
  324. list_for_each(lhandle, &efi_obj_list) {
  325. struct efi_object *efiobj;
  326. efiobj = list_entry(lhandle, struct efi_object, link);
  327. if (!efi_search(search_type, protocol, search_key, efiobj)) {
  328. *(buffer++) = efiobj->handle;
  329. }
  330. }
  331. *buffer_size = size;
  332. return EFI_EXIT(EFI_SUCCESS);
  333. }
  334. static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol,
  335. struct efi_device_path **device_path,
  336. efi_handle_t *device)
  337. {
  338. EFI_ENTRY("%p, %p, %p", protocol, device_path, device);
  339. return EFI_EXIT(EFI_NOT_FOUND);
  340. }
  341. efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table)
  342. {
  343. int i;
  344. /* Check for guid override */
  345. for (i = 0; i < systab.nr_tables; i++) {
  346. if (!guidcmp(guid, &efi_conf_table[i].guid)) {
  347. efi_conf_table[i].table = table;
  348. return EFI_SUCCESS;
  349. }
  350. }
  351. /* No override, check for overflow */
  352. if (i >= ARRAY_SIZE(efi_conf_table))
  353. return EFI_OUT_OF_RESOURCES;
  354. /* Add a new entry */
  355. memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
  356. efi_conf_table[i].table = table;
  357. systab.nr_tables = i + 1;
  358. return EFI_SUCCESS;
  359. }
  360. static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
  361. void *table)
  362. {
  363. EFI_ENTRY("%p, %p", guid, table);
  364. return EFI_EXIT(efi_install_configuration_table(guid, table));
  365. }
  366. static efi_status_t EFIAPI efi_load_image(bool boot_policy,
  367. efi_handle_t parent_image,
  368. struct efi_device_path *file_path,
  369. void *source_buffer,
  370. unsigned long source_size,
  371. efi_handle_t *image_handle)
  372. {
  373. static struct efi_object loaded_image_info_obj = {
  374. .protocols = {
  375. {
  376. .guid = &efi_guid_loaded_image,
  377. },
  378. },
  379. };
  380. struct efi_loaded_image *info;
  381. struct efi_object *obj;
  382. EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
  383. file_path, source_buffer, source_size, image_handle);
  384. info = malloc(sizeof(*info));
  385. loaded_image_info_obj.protocols[0].protocol_interface = info;
  386. obj = malloc(sizeof(loaded_image_info_obj));
  387. memset(info, 0, sizeof(*info));
  388. memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj));
  389. obj->handle = info;
  390. info->file_path = file_path;
  391. info->reserved = efi_load_pe(source_buffer, info);
  392. if (!info->reserved) {
  393. free(info);
  394. free(obj);
  395. return EFI_EXIT(EFI_UNSUPPORTED);
  396. }
  397. *image_handle = info;
  398. list_add_tail(&obj->link, &efi_obj_list);
  399. return EFI_EXIT(EFI_SUCCESS);
  400. }
  401. static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
  402. unsigned long *exit_data_size,
  403. s16 **exit_data)
  404. {
  405. ulong (*entry)(void *image_handle, struct efi_system_table *st);
  406. struct efi_loaded_image *info = image_handle;
  407. EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
  408. entry = info->reserved;
  409. efi_is_direct_boot = false;
  410. /* call the image! */
  411. if (setjmp(&info->exit_jmp)) {
  412. /* We returned from the child image */
  413. return EFI_EXIT(info->exit_status);
  414. }
  415. entry(image_handle, &systab);
  416. /* Should usually never get here */
  417. return EFI_EXIT(EFI_SUCCESS);
  418. }
  419. static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
  420. efi_status_t exit_status, unsigned long exit_data_size,
  421. int16_t *exit_data)
  422. {
  423. struct efi_loaded_image *loaded_image_info = (void*)image_handle;
  424. EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
  425. exit_data_size, exit_data);
  426. loaded_image_info->exit_status = exit_status;
  427. longjmp(&loaded_image_info->exit_jmp, 1);
  428. panic("EFI application exited");
  429. }
  430. static struct efi_object *efi_search_obj(void *handle)
  431. {
  432. struct list_head *lhandle;
  433. list_for_each(lhandle, &efi_obj_list) {
  434. struct efi_object *efiobj;
  435. efiobj = list_entry(lhandle, struct efi_object, link);
  436. if (efiobj->handle == handle)
  437. return efiobj;
  438. }
  439. return NULL;
  440. }
  441. static efi_status_t EFIAPI efi_unload_image(void *image_handle)
  442. {
  443. struct efi_object *efiobj;
  444. EFI_ENTRY("%p", image_handle);
  445. efiobj = efi_search_obj(image_handle);
  446. if (efiobj)
  447. list_del(&efiobj->link);
  448. return EFI_EXIT(EFI_SUCCESS);
  449. }
  450. static void efi_exit_caches(void)
  451. {
  452. #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
  453. /*
  454. * Grub on 32bit ARM needs to have caches disabled before jumping into
  455. * a zImage, but does not know of all cache layers. Give it a hand.
  456. */
  457. if (efi_is_direct_boot)
  458. cleanup_before_linux();
  459. #endif
  460. }
  461. static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
  462. unsigned long map_key)
  463. {
  464. EFI_ENTRY("%p, %ld", image_handle, map_key);
  465. board_quiesce_devices();
  466. /* Fix up caches for EFI payloads if necessary */
  467. efi_exit_caches();
  468. /* This stops all lingering devices */
  469. bootm_disable_interrupts();
  470. /* Give the payload some time to boot */
  471. WATCHDOG_RESET();
  472. return EFI_EXIT(EFI_SUCCESS);
  473. }
  474. static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
  475. {
  476. static uint64_t mono = 0;
  477. EFI_ENTRY("%p", count);
  478. *count = mono++;
  479. return EFI_EXIT(EFI_SUCCESS);
  480. }
  481. static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
  482. {
  483. EFI_ENTRY("%ld", microseconds);
  484. udelay(microseconds);
  485. return EFI_EXIT(EFI_SUCCESS);
  486. }
  487. static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
  488. uint64_t watchdog_code,
  489. unsigned long data_size,
  490. uint16_t *watchdog_data)
  491. {
  492. EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code,
  493. data_size, watchdog_data);
  494. return EFI_EXIT(efi_unsupported(__func__));
  495. }
  496. static efi_status_t EFIAPI efi_connect_controller(
  497. efi_handle_t controller_handle,
  498. efi_handle_t *driver_image_handle,
  499. struct efi_device_path *remain_device_path,
  500. bool recursive)
  501. {
  502. EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
  503. remain_device_path, recursive);
  504. return EFI_EXIT(EFI_NOT_FOUND);
  505. }
  506. static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
  507. void *driver_image_handle,
  508. void *child_handle)
  509. {
  510. EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
  511. child_handle);
  512. return EFI_EXIT(EFI_INVALID_PARAMETER);
  513. }
  514. static efi_status_t EFIAPI efi_close_protocol(void *handle,
  515. efi_guid_t *protocol,
  516. void *agent_handle,
  517. void *controller_handle)
  518. {
  519. EFI_ENTRY("%p, %p, %p, %p", handle, protocol, agent_handle,
  520. controller_handle);
  521. return EFI_EXIT(EFI_NOT_FOUND);
  522. }
  523. static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
  524. efi_guid_t *protocol,
  525. struct efi_open_protocol_info_entry **entry_buffer,
  526. unsigned long *entry_count)
  527. {
  528. EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer,
  529. entry_count);
  530. return EFI_EXIT(EFI_NOT_FOUND);
  531. }
  532. static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,
  533. efi_guid_t ***protocol_buffer,
  534. unsigned long *protocol_buffer_count)
  535. {
  536. EFI_ENTRY("%p, %p, %p", handle, protocol_buffer,
  537. protocol_buffer_count);
  538. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  539. }
  540. static efi_status_t EFIAPI efi_locate_handle_buffer(
  541. enum efi_locate_search_type search_type,
  542. efi_guid_t *protocol, void *search_key,
  543. unsigned long *no_handles, efi_handle_t **buffer)
  544. {
  545. EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key,
  546. no_handles, buffer);
  547. return EFI_EXIT(EFI_NOT_FOUND);
  548. }
  549. static struct efi_class_map efi_class_maps[] = {
  550. {
  551. .guid = &efi_guid_console_control,
  552. .interface = &efi_console_control
  553. },
  554. };
  555. static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol,
  556. void *registration,
  557. void **protocol_interface)
  558. {
  559. int i;
  560. EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface);
  561. for (i = 0; i < ARRAY_SIZE(efi_class_maps); i++) {
  562. struct efi_class_map *curmap = &efi_class_maps[i];
  563. if (!guidcmp(protocol, curmap->guid)) {
  564. *protocol_interface = (void*)curmap->interface;
  565. return EFI_EXIT(EFI_SUCCESS);
  566. }
  567. }
  568. return EFI_EXIT(EFI_NOT_FOUND);
  569. }
  570. static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
  571. void **handle, ...)
  572. {
  573. EFI_ENTRY("%p", handle);
  574. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  575. }
  576. static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
  577. void *handle, ...)
  578. {
  579. EFI_ENTRY("%p", handle);
  580. return EFI_EXIT(EFI_INVALID_PARAMETER);
  581. }
  582. static efi_status_t EFIAPI efi_calculate_crc32(void *data,
  583. unsigned long data_size,
  584. uint32_t *crc32_p)
  585. {
  586. EFI_ENTRY("%p, %ld", data, data_size);
  587. *crc32_p = crc32(0, data, data_size);
  588. return EFI_EXIT(EFI_SUCCESS);
  589. }
  590. static void EFIAPI efi_copy_mem(void *destination, void *source,
  591. unsigned long length)
  592. {
  593. EFI_ENTRY("%p, %p, %ld", destination, source, length);
  594. memcpy(destination, source, length);
  595. }
  596. static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value)
  597. {
  598. EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value);
  599. memset(buffer, value, size);
  600. }
  601. static efi_status_t EFIAPI efi_open_protocol(
  602. void *handle, efi_guid_t *protocol,
  603. void **protocol_interface, void *agent_handle,
  604. void *controller_handle, uint32_t attributes)
  605. {
  606. struct list_head *lhandle;
  607. int i;
  608. efi_status_t r = EFI_UNSUPPORTED;
  609. EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
  610. protocol_interface, agent_handle, controller_handle,
  611. attributes);
  612. if (!protocol_interface && attributes !=
  613. EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
  614. r = EFI_INVALID_PARAMETER;
  615. goto out;
  616. }
  617. list_for_each(lhandle, &efi_obj_list) {
  618. struct efi_object *efiobj;
  619. efiobj = list_entry(lhandle, struct efi_object, link);
  620. if (efiobj->handle != handle)
  621. continue;
  622. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  623. struct efi_handler *handler = &efiobj->protocols[i];
  624. const efi_guid_t *hprotocol = handler->guid;
  625. if (!hprotocol)
  626. break;
  627. if (!guidcmp(hprotocol, protocol)) {
  628. if (attributes !=
  629. EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
  630. *protocol_interface =
  631. handler->protocol_interface;
  632. }
  633. r = EFI_SUCCESS;
  634. goto out;
  635. }
  636. }
  637. }
  638. out:
  639. return EFI_EXIT(r);
  640. }
  641. static efi_status_t EFIAPI efi_handle_protocol(void *handle,
  642. efi_guid_t *protocol,
  643. void **protocol_interface)
  644. {
  645. return efi_open_protocol(handle, protocol, protocol_interface, NULL,
  646. NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
  647. }
  648. static const struct efi_boot_services efi_boot_services = {
  649. .hdr = {
  650. .headersize = sizeof(struct efi_table_hdr),
  651. },
  652. .raise_tpl = efi_raise_tpl,
  653. .restore_tpl = efi_restore_tpl,
  654. .allocate_pages = efi_allocate_pages_ext,
  655. .free_pages = efi_free_pages_ext,
  656. .get_memory_map = efi_get_memory_map_ext,
  657. .allocate_pool = efi_allocate_pool_ext,
  658. .free_pool = efi_free_pool_ext,
  659. .create_event = efi_create_event,
  660. .set_timer = efi_set_timer,
  661. .wait_for_event = efi_wait_for_event,
  662. .signal_event = efi_signal_event,
  663. .close_event = efi_close_event,
  664. .check_event = efi_check_event,
  665. .install_protocol_interface = efi_install_protocol_interface,
  666. .reinstall_protocol_interface = efi_reinstall_protocol_interface,
  667. .uninstall_protocol_interface = efi_uninstall_protocol_interface,
  668. .handle_protocol = efi_handle_protocol,
  669. .reserved = NULL,
  670. .register_protocol_notify = efi_register_protocol_notify,
  671. .locate_handle = efi_locate_handle,
  672. .locate_device_path = efi_locate_device_path,
  673. .install_configuration_table = efi_install_configuration_table_ext,
  674. .load_image = efi_load_image,
  675. .start_image = efi_start_image,
  676. .exit = efi_exit,
  677. .unload_image = efi_unload_image,
  678. .exit_boot_services = efi_exit_boot_services,
  679. .get_next_monotonic_count = efi_get_next_monotonic_count,
  680. .stall = efi_stall,
  681. .set_watchdog_timer = efi_set_watchdog_timer,
  682. .connect_controller = efi_connect_controller,
  683. .disconnect_controller = efi_disconnect_controller,
  684. .open_protocol = efi_open_protocol,
  685. .close_protocol = efi_close_protocol,
  686. .open_protocol_information = efi_open_protocol_information,
  687. .protocols_per_handle = efi_protocols_per_handle,
  688. .locate_handle_buffer = efi_locate_handle_buffer,
  689. .locate_protocol = efi_locate_protocol,
  690. .install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
  691. .uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
  692. .calculate_crc32 = efi_calculate_crc32,
  693. .copy_mem = efi_copy_mem,
  694. .set_mem = efi_set_mem,
  695. };
  696. static uint16_t __efi_runtime_data firmware_vendor[] =
  697. { 'D','a','s',' ','U','-','b','o','o','t',0 };
  698. struct efi_system_table __efi_runtime_data systab = {
  699. .hdr = {
  700. .signature = EFI_SYSTEM_TABLE_SIGNATURE,
  701. .revision = 0x20005, /* 2.5 */
  702. .headersize = sizeof(struct efi_table_hdr),
  703. },
  704. .fw_vendor = (long)firmware_vendor,
  705. .con_in = (void*)&efi_con_in,
  706. .con_out = (void*)&efi_con_out,
  707. .std_err = (void*)&efi_con_out,
  708. .runtime = (void*)&efi_runtime_services,
  709. .boottime = (void*)&efi_boot_services,
  710. .nr_tables = 0,
  711. .tables = (void*)efi_conf_table,
  712. };