efi_boottime.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  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 <environment.h>
  11. #include <malloc.h>
  12. #include <asm/global_data.h>
  13. #include <libfdt_env.h>
  14. #include <u-boot/crc.h>
  15. #include <bootm.h>
  16. #include <inttypes.h>
  17. #include <watchdog.h>
  18. DECLARE_GLOBAL_DATA_PTR;
  19. /* Task priority level */
  20. static UINTN efi_tpl = TPL_APPLICATION;
  21. /* This list contains all the EFI objects our payload has access to */
  22. LIST_HEAD(efi_obj_list);
  23. /*
  24. * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
  25. * we need to do trickery with caches. Since we don't want to break the EFI
  26. * aware boot path, only apply hacks when loading exiting directly (breaking
  27. * direct Linux EFI booting along the way - oh well).
  28. */
  29. static bool efi_is_direct_boot = true;
  30. /*
  31. * EFI can pass arbitrary additional "tables" containing vendor specific
  32. * information to the payload. One such table is the FDT table which contains
  33. * a pointer to a flattened device tree blob.
  34. *
  35. * In most cases we want to pass an FDT to the payload, so reserve one slot of
  36. * config table space for it. The pointer gets populated by do_bootefi_exec().
  37. */
  38. static struct efi_configuration_table __efi_runtime_data efi_conf_table[2];
  39. #ifdef CONFIG_ARM
  40. /*
  41. * The "gd" pointer lives in a register on ARM and AArch64 that we declare
  42. * fixed when compiling U-Boot. However, the payload does not know about that
  43. * restriction so we need to manually swap its and our view of that register on
  44. * EFI callback entry/exit.
  45. */
  46. static volatile void *efi_gd, *app_gd;
  47. #endif
  48. static int entry_count;
  49. static int nesting_level;
  50. /* Called on every callback entry */
  51. int __efi_entry_check(void)
  52. {
  53. int ret = entry_count++ == 0;
  54. #ifdef CONFIG_ARM
  55. assert(efi_gd);
  56. app_gd = gd;
  57. gd = efi_gd;
  58. #endif
  59. return ret;
  60. }
  61. /* Called on every callback exit */
  62. int __efi_exit_check(void)
  63. {
  64. int ret = --entry_count == 0;
  65. #ifdef CONFIG_ARM
  66. gd = app_gd;
  67. #endif
  68. return ret;
  69. }
  70. /* Called from do_bootefi_exec() */
  71. void efi_save_gd(void)
  72. {
  73. #ifdef CONFIG_ARM
  74. efi_gd = gd;
  75. #endif
  76. }
  77. /*
  78. * Special case handler for error/abort that just forces things back
  79. * to u-boot world so we can dump out an abort msg, without any care
  80. * about returning back to UEFI world.
  81. */
  82. void efi_restore_gd(void)
  83. {
  84. #ifdef CONFIG_ARM
  85. /* Only restore if we're already in EFI context */
  86. if (!efi_gd)
  87. return;
  88. gd = efi_gd;
  89. #endif
  90. }
  91. /*
  92. * Two spaces per indent level, maxing out at 10.. which ought to be
  93. * enough for anyone ;-)
  94. */
  95. static const char *indent_string(int level)
  96. {
  97. const char *indent = " ";
  98. const int max = strlen(indent);
  99. level = min(max, level * 2);
  100. return &indent[max - level];
  101. }
  102. const char *__efi_nesting(void)
  103. {
  104. return indent_string(nesting_level);
  105. }
  106. const char *__efi_nesting_inc(void)
  107. {
  108. return indent_string(nesting_level++);
  109. }
  110. const char *__efi_nesting_dec(void)
  111. {
  112. return indent_string(--nesting_level);
  113. }
  114. /* Low 32 bit */
  115. #define EFI_LOW32(a) (a & 0xFFFFFFFFULL)
  116. /* High 32 bit */
  117. #define EFI_HIGH32(a) (a >> 32)
  118. /*
  119. * 64bit division by 10 implemented as multiplication by 1 / 10
  120. *
  121. * Decimals of one tenth: 0x1 / 0xA = 0x0.19999...
  122. */
  123. #define EFI_TENTH 0x199999999999999A
  124. static u64 efi_div10(u64 a)
  125. {
  126. u64 prod;
  127. u64 rem;
  128. u64 ret;
  129. ret = EFI_HIGH32(a) * EFI_HIGH32(EFI_TENTH);
  130. prod = EFI_HIGH32(a) * EFI_LOW32(EFI_TENTH);
  131. rem = EFI_LOW32(prod);
  132. ret += EFI_HIGH32(prod);
  133. prod = EFI_LOW32(a) * EFI_HIGH32(EFI_TENTH);
  134. rem += EFI_LOW32(prod);
  135. ret += EFI_HIGH32(prod);
  136. prod = EFI_LOW32(a) * EFI_LOW32(EFI_TENTH);
  137. rem += EFI_HIGH32(prod);
  138. ret += EFI_HIGH32(rem);
  139. /* Round to nearest integer */
  140. if (rem >= (1 << 31))
  141. ++ret;
  142. return ret;
  143. }
  144. void efi_signal_event(struct efi_event *event)
  145. {
  146. if (event->notify_function) {
  147. event->queued = 1;
  148. /* Check TPL */
  149. if (efi_tpl >= event->notify_tpl)
  150. return;
  151. EFI_CALL_VOID(event->notify_function(event,
  152. event->notify_context));
  153. }
  154. event->queued = 0;
  155. }
  156. static efi_status_t efi_unsupported(const char *funcname)
  157. {
  158. debug("EFI: App called into unimplemented function %s\n", funcname);
  159. return EFI_EXIT(EFI_UNSUPPORTED);
  160. }
  161. static unsigned long EFIAPI efi_raise_tpl(UINTN new_tpl)
  162. {
  163. UINTN old_tpl = efi_tpl;
  164. EFI_ENTRY("0x%zx", new_tpl);
  165. if (new_tpl < efi_tpl)
  166. debug("WARNING: new_tpl < current_tpl in %s\n", __func__);
  167. efi_tpl = new_tpl;
  168. if (efi_tpl > TPL_HIGH_LEVEL)
  169. efi_tpl = TPL_HIGH_LEVEL;
  170. EFI_EXIT(EFI_SUCCESS);
  171. return old_tpl;
  172. }
  173. static void EFIAPI efi_restore_tpl(UINTN old_tpl)
  174. {
  175. EFI_ENTRY("0x%zx", old_tpl);
  176. if (old_tpl > efi_tpl)
  177. debug("WARNING: old_tpl > current_tpl in %s\n", __func__);
  178. efi_tpl = old_tpl;
  179. if (efi_tpl > TPL_HIGH_LEVEL)
  180. efi_tpl = TPL_HIGH_LEVEL;
  181. EFI_EXIT(EFI_SUCCESS);
  182. }
  183. static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
  184. unsigned long pages,
  185. uint64_t *memory)
  186. {
  187. efi_status_t r;
  188. EFI_ENTRY("%d, %d, 0x%lx, %p", type, memory_type, pages, memory);
  189. r = efi_allocate_pages(type, memory_type, pages, memory);
  190. return EFI_EXIT(r);
  191. }
  192. static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
  193. unsigned long pages)
  194. {
  195. efi_status_t r;
  196. EFI_ENTRY("%"PRIx64", 0x%lx", memory, pages);
  197. r = efi_free_pages(memory, pages);
  198. return EFI_EXIT(r);
  199. }
  200. static efi_status_t EFIAPI efi_get_memory_map_ext(
  201. unsigned long *memory_map_size,
  202. struct efi_mem_desc *memory_map,
  203. unsigned long *map_key,
  204. unsigned long *descriptor_size,
  205. uint32_t *descriptor_version)
  206. {
  207. efi_status_t r;
  208. EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size, memory_map,
  209. map_key, descriptor_size, descriptor_version);
  210. r = efi_get_memory_map(memory_map_size, memory_map, map_key,
  211. descriptor_size, descriptor_version);
  212. return EFI_EXIT(r);
  213. }
  214. static efi_status_t EFIAPI efi_allocate_pool_ext(int pool_type,
  215. unsigned long size,
  216. void **buffer)
  217. {
  218. efi_status_t r;
  219. EFI_ENTRY("%d, %ld, %p", pool_type, size, buffer);
  220. r = efi_allocate_pool(pool_type, size, buffer);
  221. return EFI_EXIT(r);
  222. }
  223. static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
  224. {
  225. efi_status_t r;
  226. EFI_ENTRY("%p", buffer);
  227. r = efi_free_pool(buffer);
  228. return EFI_EXIT(r);
  229. }
  230. /*
  231. * Our event capabilities are very limited. Only a small limited
  232. * number of events is allowed to coexist.
  233. */
  234. static struct efi_event efi_events[16];
  235. efi_status_t efi_create_event(uint32_t type, UINTN notify_tpl,
  236. void (EFIAPI *notify_function) (
  237. struct efi_event *event,
  238. void *context),
  239. void *notify_context, struct efi_event **event)
  240. {
  241. int i;
  242. if (event == NULL)
  243. return EFI_INVALID_PARAMETER;
  244. if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
  245. return EFI_INVALID_PARAMETER;
  246. if ((type & (EVT_NOTIFY_SIGNAL|EVT_NOTIFY_WAIT)) &&
  247. notify_function == NULL)
  248. return EFI_INVALID_PARAMETER;
  249. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  250. if (efi_events[i].type)
  251. continue;
  252. efi_events[i].type = type;
  253. efi_events[i].notify_tpl = notify_tpl;
  254. efi_events[i].notify_function = notify_function;
  255. efi_events[i].notify_context = notify_context;
  256. /* Disable timers on bootup */
  257. efi_events[i].trigger_next = -1ULL;
  258. efi_events[i].queued = 0;
  259. efi_events[i].signaled = 0;
  260. *event = &efi_events[i];
  261. return EFI_SUCCESS;
  262. }
  263. return EFI_OUT_OF_RESOURCES;
  264. }
  265. static efi_status_t EFIAPI efi_create_event_ext(
  266. uint32_t type, UINTN notify_tpl,
  267. void (EFIAPI *notify_function) (
  268. struct efi_event *event,
  269. void *context),
  270. void *notify_context, struct efi_event **event)
  271. {
  272. EFI_ENTRY("%d, 0x%zx, %p, %p", type, notify_tpl, notify_function,
  273. notify_context);
  274. return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
  275. notify_context, event));
  276. }
  277. /*
  278. * Our timers have to work without interrupts, so we check whenever keyboard
  279. * input or disk accesses happen if enough time elapsed for it to fire.
  280. */
  281. void efi_timer_check(void)
  282. {
  283. int i;
  284. u64 now = timer_get_us();
  285. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  286. if (!efi_events[i].type)
  287. continue;
  288. if (efi_events[i].queued)
  289. efi_signal_event(&efi_events[i]);
  290. if (!(efi_events[i].type & EVT_TIMER) ||
  291. now < efi_events[i].trigger_next)
  292. continue;
  293. switch (efi_events[i].trigger_type) {
  294. case EFI_TIMER_RELATIVE:
  295. efi_events[i].trigger_type = EFI_TIMER_STOP;
  296. break;
  297. case EFI_TIMER_PERIODIC:
  298. efi_events[i].trigger_next +=
  299. efi_events[i].trigger_time;
  300. break;
  301. default:
  302. continue;
  303. }
  304. efi_events[i].signaled = 1;
  305. efi_signal_event(&efi_events[i]);
  306. }
  307. WATCHDOG_RESET();
  308. }
  309. efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
  310. uint64_t trigger_time)
  311. {
  312. int i;
  313. /*
  314. * The parameter defines a multiple of 100ns.
  315. * We use multiples of 1000ns. So divide by 10.
  316. */
  317. trigger_time = efi_div10(trigger_time);
  318. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  319. if (event != &efi_events[i])
  320. continue;
  321. if (!(event->type & EVT_TIMER))
  322. break;
  323. switch (type) {
  324. case EFI_TIMER_STOP:
  325. event->trigger_next = -1ULL;
  326. break;
  327. case EFI_TIMER_PERIODIC:
  328. case EFI_TIMER_RELATIVE:
  329. event->trigger_next =
  330. timer_get_us() + trigger_time;
  331. break;
  332. default:
  333. return EFI_INVALID_PARAMETER;
  334. }
  335. event->trigger_type = type;
  336. event->trigger_time = trigger_time;
  337. event->signaled = 0;
  338. return EFI_SUCCESS;
  339. }
  340. return EFI_INVALID_PARAMETER;
  341. }
  342. static efi_status_t EFIAPI efi_set_timer_ext(struct efi_event *event,
  343. enum efi_timer_delay type,
  344. uint64_t trigger_time)
  345. {
  346. EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time);
  347. return EFI_EXIT(efi_set_timer(event, type, trigger_time));
  348. }
  349. static efi_status_t EFIAPI efi_wait_for_event(unsigned long num_events,
  350. struct efi_event **event,
  351. unsigned long *index)
  352. {
  353. int i, j;
  354. EFI_ENTRY("%ld, %p, %p", num_events, event, index);
  355. /* Check parameters */
  356. if (!num_events || !event)
  357. return EFI_EXIT(EFI_INVALID_PARAMETER);
  358. /* Check TPL */
  359. if (efi_tpl != TPL_APPLICATION)
  360. return EFI_EXIT(EFI_UNSUPPORTED);
  361. for (i = 0; i < num_events; ++i) {
  362. for (j = 0; j < ARRAY_SIZE(efi_events); ++j) {
  363. if (event[i] == &efi_events[j])
  364. goto known_event;
  365. }
  366. return EFI_EXIT(EFI_INVALID_PARAMETER);
  367. known_event:
  368. if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
  369. return EFI_EXIT(EFI_INVALID_PARAMETER);
  370. if (!event[i]->signaled)
  371. efi_signal_event(event[i]);
  372. }
  373. /* Wait for signal */
  374. for (;;) {
  375. for (i = 0; i < num_events; ++i) {
  376. if (event[i]->signaled)
  377. goto out;
  378. }
  379. /* Allow events to occur. */
  380. efi_timer_check();
  381. }
  382. out:
  383. /*
  384. * Reset the signal which is passed to the caller to allow periodic
  385. * events to occur.
  386. */
  387. event[i]->signaled = 0;
  388. if (index)
  389. *index = i;
  390. return EFI_EXIT(EFI_SUCCESS);
  391. }
  392. static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
  393. {
  394. int i;
  395. EFI_ENTRY("%p", event);
  396. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  397. if (event != &efi_events[i])
  398. continue;
  399. if (event->signaled)
  400. break;
  401. event->signaled = 1;
  402. if (event->type & EVT_NOTIFY_SIGNAL)
  403. efi_signal_event(event);
  404. break;
  405. }
  406. return EFI_EXIT(EFI_SUCCESS);
  407. }
  408. static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
  409. {
  410. int i;
  411. EFI_ENTRY("%p", event);
  412. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  413. if (event == &efi_events[i]) {
  414. event->type = 0;
  415. event->trigger_next = -1ULL;
  416. event->queued = 0;
  417. event->signaled = 0;
  418. return EFI_EXIT(EFI_SUCCESS);
  419. }
  420. }
  421. return EFI_EXIT(EFI_INVALID_PARAMETER);
  422. }
  423. static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
  424. {
  425. int i;
  426. EFI_ENTRY("%p", event);
  427. efi_timer_check();
  428. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  429. if (event != &efi_events[i])
  430. continue;
  431. if (!event->type || event->type & EVT_NOTIFY_SIGNAL)
  432. break;
  433. if (!event->signaled)
  434. efi_signal_event(event);
  435. if (event->signaled)
  436. return EFI_EXIT(EFI_SUCCESS);
  437. return EFI_EXIT(EFI_NOT_READY);
  438. }
  439. return EFI_EXIT(EFI_INVALID_PARAMETER);
  440. }
  441. static efi_status_t EFIAPI efi_install_protocol_interface(void **handle,
  442. efi_guid_t *protocol, int protocol_interface_type,
  443. void *protocol_interface)
  444. {
  445. struct list_head *lhandle;
  446. int i;
  447. efi_status_t r;
  448. if (!handle || !protocol ||
  449. protocol_interface_type != EFI_NATIVE_INTERFACE) {
  450. r = EFI_INVALID_PARAMETER;
  451. goto out;
  452. }
  453. /* Create new handle if requested. */
  454. if (!*handle) {
  455. r = EFI_OUT_OF_RESOURCES;
  456. goto out;
  457. }
  458. /* Find object. */
  459. list_for_each(lhandle, &efi_obj_list) {
  460. struct efi_object *efiobj;
  461. efiobj = list_entry(lhandle, struct efi_object, link);
  462. if (efiobj->handle != *handle)
  463. continue;
  464. /* Check if protocol is already installed on the handle. */
  465. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  466. struct efi_handler *handler = &efiobj->protocols[i];
  467. if (!handler->guid)
  468. continue;
  469. if (!guidcmp(handler->guid, protocol)) {
  470. r = EFI_INVALID_PARAMETER;
  471. goto out;
  472. }
  473. }
  474. /* Install protocol in first empty slot. */
  475. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  476. struct efi_handler *handler = &efiobj->protocols[i];
  477. if (handler->guid)
  478. continue;
  479. handler->guid = protocol;
  480. handler->protocol_interface = protocol_interface;
  481. r = EFI_SUCCESS;
  482. goto out;
  483. }
  484. r = EFI_OUT_OF_RESOURCES;
  485. goto out;
  486. }
  487. r = EFI_INVALID_PARAMETER;
  488. out:
  489. return r;
  490. }
  491. static efi_status_t EFIAPI efi_install_protocol_interface_ext(void **handle,
  492. efi_guid_t *protocol, int protocol_interface_type,
  493. void *protocol_interface)
  494. {
  495. EFI_ENTRY("%p, %pUl, %d, %p", handle, protocol, protocol_interface_type,
  496. protocol_interface);
  497. return EFI_EXIT(efi_install_protocol_interface(handle, protocol,
  498. protocol_interface_type,
  499. protocol_interface));
  500. }
  501. static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
  502. efi_guid_t *protocol, void *old_interface,
  503. void *new_interface)
  504. {
  505. EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
  506. new_interface);
  507. return EFI_EXIT(EFI_ACCESS_DENIED);
  508. }
  509. static efi_status_t EFIAPI efi_uninstall_protocol_interface(void *handle,
  510. efi_guid_t *protocol, void *protocol_interface)
  511. {
  512. struct list_head *lhandle;
  513. int i;
  514. efi_status_t r = EFI_NOT_FOUND;
  515. if (!handle || !protocol) {
  516. r = EFI_INVALID_PARAMETER;
  517. goto out;
  518. }
  519. list_for_each(lhandle, &efi_obj_list) {
  520. struct efi_object *efiobj;
  521. efiobj = list_entry(lhandle, struct efi_object, link);
  522. if (efiobj->handle != handle)
  523. continue;
  524. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  525. struct efi_handler *handler = &efiobj->protocols[i];
  526. const efi_guid_t *hprotocol = handler->guid;
  527. if (!hprotocol)
  528. continue;
  529. if (!guidcmp(hprotocol, protocol)) {
  530. if (handler->protocol_interface) {
  531. r = EFI_ACCESS_DENIED;
  532. } else {
  533. handler->guid = 0;
  534. r = EFI_SUCCESS;
  535. }
  536. goto out;
  537. }
  538. }
  539. }
  540. out:
  541. return r;
  542. }
  543. static efi_status_t EFIAPI efi_uninstall_protocol_interface_ext(void *handle,
  544. efi_guid_t *protocol, void *protocol_interface)
  545. {
  546. EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
  547. return EFI_EXIT(efi_uninstall_protocol_interface(handle, protocol,
  548. protocol_interface));
  549. }
  550. static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol,
  551. struct efi_event *event,
  552. void **registration)
  553. {
  554. EFI_ENTRY("%pUl, %p, %p", protocol, event, registration);
  555. return EFI_EXIT(EFI_OUT_OF_RESOURCES);
  556. }
  557. static int efi_search(enum efi_locate_search_type search_type,
  558. efi_guid_t *protocol, void *search_key,
  559. struct efi_object *efiobj)
  560. {
  561. int i;
  562. switch (search_type) {
  563. case all_handles:
  564. return 0;
  565. case by_register_notify:
  566. return -1;
  567. case by_protocol:
  568. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  569. const efi_guid_t *guid = efiobj->protocols[i].guid;
  570. if (guid && !guidcmp(guid, protocol))
  571. return 0;
  572. }
  573. return -1;
  574. }
  575. return -1;
  576. }
  577. static efi_status_t efi_locate_handle(
  578. enum efi_locate_search_type search_type,
  579. efi_guid_t *protocol, void *search_key,
  580. unsigned long *buffer_size, efi_handle_t *buffer)
  581. {
  582. struct list_head *lhandle;
  583. unsigned long size = 0;
  584. /* Count how much space we need */
  585. list_for_each(lhandle, &efi_obj_list) {
  586. struct efi_object *efiobj;
  587. efiobj = list_entry(lhandle, struct efi_object, link);
  588. if (!efi_search(search_type, protocol, search_key, efiobj)) {
  589. size += sizeof(void*);
  590. }
  591. }
  592. if (*buffer_size < size) {
  593. *buffer_size = size;
  594. return EFI_BUFFER_TOO_SMALL;
  595. }
  596. *buffer_size = size;
  597. if (size == 0)
  598. return EFI_NOT_FOUND;
  599. /* Then fill the array */
  600. list_for_each(lhandle, &efi_obj_list) {
  601. struct efi_object *efiobj;
  602. efiobj = list_entry(lhandle, struct efi_object, link);
  603. if (!efi_search(search_type, protocol, search_key, efiobj)) {
  604. *(buffer++) = efiobj->handle;
  605. }
  606. }
  607. return EFI_SUCCESS;
  608. }
  609. static efi_status_t EFIAPI efi_locate_handle_ext(
  610. enum efi_locate_search_type search_type,
  611. efi_guid_t *protocol, void *search_key,
  612. unsigned long *buffer_size, efi_handle_t *buffer)
  613. {
  614. EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key,
  615. buffer_size, buffer);
  616. return EFI_EXIT(efi_locate_handle(search_type, protocol, search_key,
  617. buffer_size, buffer));
  618. }
  619. static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol,
  620. struct efi_device_path **device_path,
  621. efi_handle_t *device)
  622. {
  623. struct efi_object *efiobj;
  624. EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device);
  625. efiobj = efi_dp_find_obj(*device_path, device_path);
  626. if (!efiobj)
  627. return EFI_EXIT(EFI_NOT_FOUND);
  628. *device = efiobj->handle;
  629. return EFI_EXIT(EFI_SUCCESS);
  630. }
  631. /* Collapses configuration table entries, removing index i */
  632. static void efi_remove_configuration_table(int i)
  633. {
  634. struct efi_configuration_table *this = &efi_conf_table[i];
  635. struct efi_configuration_table *next = &efi_conf_table[i+1];
  636. struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
  637. memmove(this, next, (ulong)end - (ulong)next);
  638. systab.nr_tables--;
  639. }
  640. efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table)
  641. {
  642. int i;
  643. /* Check for guid override */
  644. for (i = 0; i < systab.nr_tables; i++) {
  645. if (!guidcmp(guid, &efi_conf_table[i].guid)) {
  646. if (table)
  647. efi_conf_table[i].table = table;
  648. else
  649. efi_remove_configuration_table(i);
  650. return EFI_SUCCESS;
  651. }
  652. }
  653. if (!table)
  654. return EFI_NOT_FOUND;
  655. /* No override, check for overflow */
  656. if (i >= ARRAY_SIZE(efi_conf_table))
  657. return EFI_OUT_OF_RESOURCES;
  658. /* Add a new entry */
  659. memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
  660. efi_conf_table[i].table = table;
  661. systab.nr_tables = i + 1;
  662. return EFI_SUCCESS;
  663. }
  664. static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
  665. void *table)
  666. {
  667. EFI_ENTRY("%pUl, %p", guid, table);
  668. return EFI_EXIT(efi_install_configuration_table(guid, table));
  669. }
  670. /* Initialize a loaded_image_info + loaded_image_info object with correct
  671. * protocols, boot-device, etc.
  672. */
  673. void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj,
  674. struct efi_device_path *device_path,
  675. struct efi_device_path *file_path)
  676. {
  677. obj->handle = info;
  678. /*
  679. * When asking for the device path interface, return
  680. * bootefi_device_path
  681. */
  682. obj->protocols[0].guid = &efi_guid_device_path;
  683. obj->protocols[0].protocol_interface = device_path;
  684. /*
  685. * When asking for the loaded_image interface, just
  686. * return handle which points to loaded_image_info
  687. */
  688. obj->protocols[1].guid = &efi_guid_loaded_image;
  689. obj->protocols[1].protocol_interface = info;
  690. obj->protocols[2].guid = &efi_guid_console_control;
  691. obj->protocols[2].protocol_interface = (void *)&efi_console_control;
  692. obj->protocols[3].guid = &efi_guid_device_path_to_text_protocol;
  693. obj->protocols[3].protocol_interface =
  694. (void *)&efi_device_path_to_text;
  695. info->file_path = file_path;
  696. info->device_handle = efi_dp_find_obj(device_path, NULL);
  697. list_add_tail(&obj->link, &efi_obj_list);
  698. }
  699. efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
  700. void **buffer)
  701. {
  702. struct efi_file_info *info = NULL;
  703. struct efi_file_handle *f;
  704. static efi_status_t ret;
  705. uint64_t bs;
  706. f = efi_file_from_path(file_path);
  707. if (!f)
  708. return EFI_DEVICE_ERROR;
  709. bs = 0;
  710. EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid,
  711. &bs, info));
  712. if (ret == EFI_BUFFER_TOO_SMALL) {
  713. info = malloc(bs);
  714. EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid,
  715. &bs, info));
  716. }
  717. if (ret != EFI_SUCCESS)
  718. goto error;
  719. ret = efi_allocate_pool(EFI_LOADER_DATA, info->file_size, buffer);
  720. if (ret)
  721. goto error;
  722. EFI_CALL(ret = f->read(f, &info->file_size, *buffer));
  723. error:
  724. free(info);
  725. EFI_CALL(f->close(f));
  726. if (ret != EFI_SUCCESS) {
  727. efi_free_pool(*buffer);
  728. *buffer = NULL;
  729. }
  730. return ret;
  731. }
  732. static efi_status_t EFIAPI efi_load_image(bool boot_policy,
  733. efi_handle_t parent_image,
  734. struct efi_device_path *file_path,
  735. void *source_buffer,
  736. unsigned long source_size,
  737. efi_handle_t *image_handle)
  738. {
  739. struct efi_loaded_image *info;
  740. struct efi_object *obj;
  741. EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
  742. file_path, source_buffer, source_size, image_handle);
  743. info = calloc(1, sizeof(*info));
  744. obj = calloc(1, sizeof(*obj));
  745. if (!source_buffer) {
  746. struct efi_device_path *dp, *fp;
  747. efi_status_t ret;
  748. ret = efi_load_image_from_path(file_path, &source_buffer);
  749. if (ret != EFI_SUCCESS) {
  750. free(info);
  751. free(obj);
  752. return EFI_EXIT(ret);
  753. }
  754. /*
  755. * split file_path which contains both the device and
  756. * file parts:
  757. */
  758. efi_dp_split_file_path(file_path, &dp, &fp);
  759. efi_setup_loaded_image(info, obj, dp, fp);
  760. } else {
  761. /* In this case, file_path is the "device" path, ie.
  762. * something like a HARDWARE_DEVICE:MEMORY_MAPPED
  763. */
  764. efi_setup_loaded_image(info, obj, file_path, NULL);
  765. }
  766. info->reserved = efi_load_pe(source_buffer, info);
  767. if (!info->reserved) {
  768. free(info);
  769. free(obj);
  770. return EFI_EXIT(EFI_UNSUPPORTED);
  771. }
  772. *image_handle = info;
  773. return EFI_EXIT(EFI_SUCCESS);
  774. }
  775. static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
  776. unsigned long *exit_data_size,
  777. s16 **exit_data)
  778. {
  779. ulong (*entry)(void *image_handle, struct efi_system_table *st);
  780. struct efi_loaded_image *info = image_handle;
  781. EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
  782. entry = info->reserved;
  783. efi_is_direct_boot = false;
  784. /* call the image! */
  785. if (setjmp(&info->exit_jmp)) {
  786. /* We returned from the child image */
  787. return EFI_EXIT(info->exit_status);
  788. }
  789. __efi_nesting_dec();
  790. __efi_exit_check();
  791. entry(image_handle, &systab);
  792. __efi_entry_check();
  793. __efi_nesting_inc();
  794. /* Should usually never get here */
  795. return EFI_EXIT(EFI_SUCCESS);
  796. }
  797. static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
  798. efi_status_t exit_status, unsigned long exit_data_size,
  799. int16_t *exit_data)
  800. {
  801. struct efi_loaded_image *loaded_image_info = (void*)image_handle;
  802. EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
  803. exit_data_size, exit_data);
  804. /* Make sure entry/exit counts for EFI world cross-overs match */
  805. __efi_exit_check();
  806. /*
  807. * But longjmp out with the U-Boot gd, not the application's, as
  808. * the other end is a setjmp call inside EFI context.
  809. */
  810. efi_restore_gd();
  811. loaded_image_info->exit_status = exit_status;
  812. longjmp(&loaded_image_info->exit_jmp, 1);
  813. panic("EFI application exited");
  814. }
  815. static struct efi_object *efi_search_obj(void *handle)
  816. {
  817. struct list_head *lhandle;
  818. list_for_each(lhandle, &efi_obj_list) {
  819. struct efi_object *efiobj;
  820. efiobj = list_entry(lhandle, struct efi_object, link);
  821. if (efiobj->handle == handle)
  822. return efiobj;
  823. }
  824. return NULL;
  825. }
  826. static efi_status_t EFIAPI efi_unload_image(void *image_handle)
  827. {
  828. struct efi_object *efiobj;
  829. EFI_ENTRY("%p", image_handle);
  830. efiobj = efi_search_obj(image_handle);
  831. if (efiobj)
  832. list_del(&efiobj->link);
  833. return EFI_EXIT(EFI_SUCCESS);
  834. }
  835. static void efi_exit_caches(void)
  836. {
  837. #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
  838. /*
  839. * Grub on 32bit ARM needs to have caches disabled before jumping into
  840. * a zImage, but does not know of all cache layers. Give it a hand.
  841. */
  842. if (efi_is_direct_boot)
  843. cleanup_before_linux();
  844. #endif
  845. }
  846. static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
  847. unsigned long map_key)
  848. {
  849. int i;
  850. EFI_ENTRY("%p, %ld", image_handle, map_key);
  851. /* Notify that ExitBootServices is invoked. */
  852. for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
  853. if (efi_events[i].type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
  854. continue;
  855. efi_signal_event(&efi_events[i]);
  856. }
  857. /* Make sure that notification functions are not called anymore */
  858. efi_tpl = TPL_HIGH_LEVEL;
  859. #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
  860. /* save any EFI variables that have been written: */
  861. env_save();
  862. #endif
  863. board_quiesce_devices();
  864. /* Fix up caches for EFI payloads if necessary */
  865. efi_exit_caches();
  866. /* This stops all lingering devices */
  867. bootm_disable_interrupts();
  868. /* Give the payload some time to boot */
  869. WATCHDOG_RESET();
  870. return EFI_EXIT(EFI_SUCCESS);
  871. }
  872. static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
  873. {
  874. static uint64_t mono = 0;
  875. EFI_ENTRY("%p", count);
  876. *count = mono++;
  877. return EFI_EXIT(EFI_SUCCESS);
  878. }
  879. static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
  880. {
  881. EFI_ENTRY("%ld", microseconds);
  882. udelay(microseconds);
  883. return EFI_EXIT(EFI_SUCCESS);
  884. }
  885. static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
  886. uint64_t watchdog_code,
  887. unsigned long data_size,
  888. uint16_t *watchdog_data)
  889. {
  890. EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code,
  891. data_size, watchdog_data);
  892. return efi_unsupported(__func__);
  893. }
  894. static efi_status_t EFIAPI efi_connect_controller(
  895. efi_handle_t controller_handle,
  896. efi_handle_t *driver_image_handle,
  897. struct efi_device_path *remain_device_path,
  898. bool recursive)
  899. {
  900. EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
  901. remain_device_path, recursive);
  902. return EFI_EXIT(EFI_NOT_FOUND);
  903. }
  904. static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
  905. void *driver_image_handle,
  906. void *child_handle)
  907. {
  908. EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
  909. child_handle);
  910. return EFI_EXIT(EFI_INVALID_PARAMETER);
  911. }
  912. static efi_status_t EFIAPI efi_close_protocol(void *handle,
  913. efi_guid_t *protocol,
  914. void *agent_handle,
  915. void *controller_handle)
  916. {
  917. EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, agent_handle,
  918. controller_handle);
  919. return EFI_EXIT(EFI_NOT_FOUND);
  920. }
  921. static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
  922. efi_guid_t *protocol,
  923. struct efi_open_protocol_info_entry **entry_buffer,
  924. unsigned long *entry_count)
  925. {
  926. EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer,
  927. entry_count);
  928. return EFI_EXIT(EFI_NOT_FOUND);
  929. }
  930. static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,
  931. efi_guid_t ***protocol_buffer,
  932. unsigned long *protocol_buffer_count)
  933. {
  934. unsigned long buffer_size;
  935. struct efi_object *efiobj;
  936. unsigned long i, j;
  937. struct list_head *lhandle;
  938. efi_status_t r;
  939. EFI_ENTRY("%p, %p, %p", handle, protocol_buffer,
  940. protocol_buffer_count);
  941. if (!handle || !protocol_buffer || !protocol_buffer_count)
  942. return EFI_EXIT(EFI_INVALID_PARAMETER);
  943. *protocol_buffer = NULL;
  944. *protocol_buffer_count = 0;
  945. list_for_each(lhandle, &efi_obj_list) {
  946. efiobj = list_entry(lhandle, struct efi_object, link);
  947. if (efiobj->handle != handle)
  948. continue;
  949. /* Count protocols */
  950. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  951. if (efiobj->protocols[i].guid)
  952. ++*protocol_buffer_count;
  953. }
  954. /* Copy guids */
  955. if (*protocol_buffer_count) {
  956. buffer_size = sizeof(efi_guid_t *) *
  957. *protocol_buffer_count;
  958. r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
  959. buffer_size,
  960. (void **)protocol_buffer);
  961. if (r != EFI_SUCCESS)
  962. return EFI_EXIT(r);
  963. j = 0;
  964. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); ++i) {
  965. if (efiobj->protocols[i].guid) {
  966. (*protocol_buffer)[j] = (void *)
  967. efiobj->protocols[i].guid;
  968. ++j;
  969. }
  970. }
  971. }
  972. break;
  973. }
  974. return EFI_EXIT(EFI_SUCCESS);
  975. }
  976. static efi_status_t EFIAPI efi_locate_handle_buffer(
  977. enum efi_locate_search_type search_type,
  978. efi_guid_t *protocol, void *search_key,
  979. unsigned long *no_handles, efi_handle_t **buffer)
  980. {
  981. efi_status_t r;
  982. unsigned long buffer_size = 0;
  983. EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key,
  984. no_handles, buffer);
  985. if (!no_handles || !buffer) {
  986. r = EFI_INVALID_PARAMETER;
  987. goto out;
  988. }
  989. *no_handles = 0;
  990. *buffer = NULL;
  991. r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
  992. *buffer);
  993. if (r != EFI_BUFFER_TOO_SMALL)
  994. goto out;
  995. r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
  996. (void **)buffer);
  997. if (r != EFI_SUCCESS)
  998. goto out;
  999. r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
  1000. *buffer);
  1001. if (r == EFI_SUCCESS)
  1002. *no_handles = buffer_size / sizeof(void *);
  1003. out:
  1004. return EFI_EXIT(r);
  1005. }
  1006. static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol,
  1007. void *registration,
  1008. void **protocol_interface)
  1009. {
  1010. struct list_head *lhandle;
  1011. int i;
  1012. EFI_ENTRY("%pUl, %p, %p", protocol, registration, protocol_interface);
  1013. if (!protocol || !protocol_interface)
  1014. return EFI_EXIT(EFI_INVALID_PARAMETER);
  1015. EFI_PRINT_GUID("protocol", protocol);
  1016. list_for_each(lhandle, &efi_obj_list) {
  1017. struct efi_object *efiobj;
  1018. efiobj = list_entry(lhandle, struct efi_object, link);
  1019. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  1020. struct efi_handler *handler = &efiobj->protocols[i];
  1021. if (!handler->guid)
  1022. continue;
  1023. if (!guidcmp(handler->guid, protocol)) {
  1024. *protocol_interface =
  1025. handler->protocol_interface;
  1026. return EFI_EXIT(EFI_SUCCESS);
  1027. }
  1028. }
  1029. }
  1030. *protocol_interface = NULL;
  1031. return EFI_EXIT(EFI_NOT_FOUND);
  1032. }
  1033. static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
  1034. void **handle, ...)
  1035. {
  1036. EFI_ENTRY("%p", handle);
  1037. va_list argptr;
  1038. efi_guid_t *protocol;
  1039. void *protocol_interface;
  1040. efi_status_t r = EFI_SUCCESS;
  1041. int i = 0;
  1042. if (!handle)
  1043. return EFI_EXIT(EFI_INVALID_PARAMETER);
  1044. va_start(argptr, handle);
  1045. for (;;) {
  1046. protocol = va_arg(argptr, efi_guid_t*);
  1047. if (!protocol)
  1048. break;
  1049. protocol_interface = va_arg(argptr, void*);
  1050. r = efi_install_protocol_interface(handle, protocol,
  1051. EFI_NATIVE_INTERFACE,
  1052. protocol_interface);
  1053. if (r != EFI_SUCCESS)
  1054. break;
  1055. i++;
  1056. }
  1057. va_end(argptr);
  1058. if (r == EFI_SUCCESS)
  1059. return EFI_EXIT(r);
  1060. /* If an error occured undo all changes. */
  1061. va_start(argptr, handle);
  1062. for (; i; --i) {
  1063. protocol = va_arg(argptr, efi_guid_t*);
  1064. protocol_interface = va_arg(argptr, void*);
  1065. efi_uninstall_protocol_interface(handle, protocol,
  1066. protocol_interface);
  1067. }
  1068. va_end(argptr);
  1069. return EFI_EXIT(r);
  1070. }
  1071. static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
  1072. void *handle, ...)
  1073. {
  1074. EFI_ENTRY("%p", handle);
  1075. return EFI_EXIT(EFI_INVALID_PARAMETER);
  1076. }
  1077. static efi_status_t EFIAPI efi_calculate_crc32(void *data,
  1078. unsigned long data_size,
  1079. uint32_t *crc32_p)
  1080. {
  1081. EFI_ENTRY("%p, %ld", data, data_size);
  1082. *crc32_p = crc32(0, data, data_size);
  1083. return EFI_EXIT(EFI_SUCCESS);
  1084. }
  1085. static void EFIAPI efi_copy_mem(void *destination, void *source,
  1086. unsigned long length)
  1087. {
  1088. EFI_ENTRY("%p, %p, %ld", destination, source, length);
  1089. memcpy(destination, source, length);
  1090. }
  1091. static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value)
  1092. {
  1093. EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value);
  1094. memset(buffer, value, size);
  1095. }
  1096. static efi_status_t EFIAPI efi_open_protocol(
  1097. void *handle, efi_guid_t *protocol,
  1098. void **protocol_interface, void *agent_handle,
  1099. void *controller_handle, uint32_t attributes)
  1100. {
  1101. struct list_head *lhandle;
  1102. int i;
  1103. efi_status_t r = EFI_INVALID_PARAMETER;
  1104. EFI_ENTRY("%p, %pUl, %p, %p, %p, 0x%x", handle, protocol,
  1105. protocol_interface, agent_handle, controller_handle,
  1106. attributes);
  1107. if (!handle || !protocol ||
  1108. (!protocol_interface && attributes !=
  1109. EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
  1110. goto out;
  1111. }
  1112. EFI_PRINT_GUID("protocol", protocol);
  1113. switch (attributes) {
  1114. case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
  1115. case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
  1116. case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
  1117. break;
  1118. case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
  1119. if (controller_handle == handle)
  1120. goto out;
  1121. case EFI_OPEN_PROTOCOL_BY_DRIVER:
  1122. case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
  1123. if (controller_handle == NULL)
  1124. goto out;
  1125. case EFI_OPEN_PROTOCOL_EXCLUSIVE:
  1126. if (agent_handle == NULL)
  1127. goto out;
  1128. break;
  1129. default:
  1130. goto out;
  1131. }
  1132. list_for_each(lhandle, &efi_obj_list) {
  1133. struct efi_object *efiobj;
  1134. efiobj = list_entry(lhandle, struct efi_object, link);
  1135. if (efiobj->handle != handle)
  1136. continue;
  1137. for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
  1138. struct efi_handler *handler = &efiobj->protocols[i];
  1139. const efi_guid_t *hprotocol = handler->guid;
  1140. if (!hprotocol)
  1141. continue;
  1142. if (!guidcmp(hprotocol, protocol)) {
  1143. if (attributes !=
  1144. EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
  1145. *protocol_interface =
  1146. handler->protocol_interface;
  1147. }
  1148. r = EFI_SUCCESS;
  1149. goto out;
  1150. }
  1151. }
  1152. goto unsupported;
  1153. }
  1154. unsupported:
  1155. r = EFI_UNSUPPORTED;
  1156. out:
  1157. return EFI_EXIT(r);
  1158. }
  1159. static efi_status_t EFIAPI efi_handle_protocol(void *handle,
  1160. efi_guid_t *protocol,
  1161. void **protocol_interface)
  1162. {
  1163. return efi_open_protocol(handle, protocol, protocol_interface, NULL,
  1164. NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
  1165. }
  1166. static const struct efi_boot_services efi_boot_services = {
  1167. .hdr = {
  1168. .headersize = sizeof(struct efi_table_hdr),
  1169. },
  1170. .raise_tpl = efi_raise_tpl,
  1171. .restore_tpl = efi_restore_tpl,
  1172. .allocate_pages = efi_allocate_pages_ext,
  1173. .free_pages = efi_free_pages_ext,
  1174. .get_memory_map = efi_get_memory_map_ext,
  1175. .allocate_pool = efi_allocate_pool_ext,
  1176. .free_pool = efi_free_pool_ext,
  1177. .create_event = efi_create_event_ext,
  1178. .set_timer = efi_set_timer_ext,
  1179. .wait_for_event = efi_wait_for_event,
  1180. .signal_event = efi_signal_event_ext,
  1181. .close_event = efi_close_event,
  1182. .check_event = efi_check_event,
  1183. .install_protocol_interface = efi_install_protocol_interface_ext,
  1184. .reinstall_protocol_interface = efi_reinstall_protocol_interface,
  1185. .uninstall_protocol_interface = efi_uninstall_protocol_interface_ext,
  1186. .handle_protocol = efi_handle_protocol,
  1187. .reserved = NULL,
  1188. .register_protocol_notify = efi_register_protocol_notify,
  1189. .locate_handle = efi_locate_handle_ext,
  1190. .locate_device_path = efi_locate_device_path,
  1191. .install_configuration_table = efi_install_configuration_table_ext,
  1192. .load_image = efi_load_image,
  1193. .start_image = efi_start_image,
  1194. .exit = efi_exit,
  1195. .unload_image = efi_unload_image,
  1196. .exit_boot_services = efi_exit_boot_services,
  1197. .get_next_monotonic_count = efi_get_next_monotonic_count,
  1198. .stall = efi_stall,
  1199. .set_watchdog_timer = efi_set_watchdog_timer,
  1200. .connect_controller = efi_connect_controller,
  1201. .disconnect_controller = efi_disconnect_controller,
  1202. .open_protocol = efi_open_protocol,
  1203. .close_protocol = efi_close_protocol,
  1204. .open_protocol_information = efi_open_protocol_information,
  1205. .protocols_per_handle = efi_protocols_per_handle,
  1206. .locate_handle_buffer = efi_locate_handle_buffer,
  1207. .locate_protocol = efi_locate_protocol,
  1208. .install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
  1209. .uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
  1210. .calculate_crc32 = efi_calculate_crc32,
  1211. .copy_mem = efi_copy_mem,
  1212. .set_mem = efi_set_mem,
  1213. };
  1214. static uint16_t __efi_runtime_data firmware_vendor[] =
  1215. { 'D','a','s',' ','U','-','b','o','o','t',0 };
  1216. struct efi_system_table __efi_runtime_data systab = {
  1217. .hdr = {
  1218. .signature = EFI_SYSTEM_TABLE_SIGNATURE,
  1219. .revision = 0x20005, /* 2.5 */
  1220. .headersize = sizeof(struct efi_table_hdr),
  1221. },
  1222. .fw_vendor = (long)firmware_vendor,
  1223. .con_in = (void*)&efi_con_in,
  1224. .con_out = (void*)&efi_con_out,
  1225. .std_err = (void*)&efi_con_out,
  1226. .runtime = (void*)&efi_runtime_services,
  1227. .boottime = (void*)&efi_boot_services,
  1228. .nr_tables = 0,
  1229. .tables = (void*)efi_conf_table,
  1230. };