efi_setup.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * EFI setup code
  4. *
  5. * Copyright (c) 2016-2018 Alexander Graf et al.
  6. */
  7. #define LOG_CATEGORY LOGC_EFI
  8. #include <common.h>
  9. #include <efi_loader.h>
  10. #include <efi_variable.h>
  11. #include <log.h>
  12. #define OBJ_LIST_NOT_INITIALIZED 1
  13. efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
  14. /*
  15. * Allow unaligned memory access.
  16. *
  17. * This routine is overridden by architectures providing this feature.
  18. */
  19. void __weak allow_unaligned(void)
  20. {
  21. }
  22. /**
  23. * efi_init_platform_lang() - define supported languages
  24. *
  25. * Set the PlatformLangCodes and PlatformLang variables.
  26. *
  27. * Return: status code
  28. */
  29. static efi_status_t efi_init_platform_lang(void)
  30. {
  31. efi_status_t ret;
  32. efi_uintn_t data_size = 0;
  33. char *lang = CONFIG_EFI_PLATFORM_LANG_CODES;
  34. char *pos;
  35. /*
  36. * Variable PlatformLangCodes defines the language codes that the
  37. * machine can support.
  38. */
  39. ret = efi_set_variable_int(L"PlatformLangCodes",
  40. &efi_global_variable_guid,
  41. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  42. EFI_VARIABLE_RUNTIME_ACCESS |
  43. EFI_VARIABLE_READ_ONLY,
  44. sizeof(CONFIG_EFI_PLATFORM_LANG_CODES),
  45. CONFIG_EFI_PLATFORM_LANG_CODES, false);
  46. if (ret != EFI_SUCCESS)
  47. goto out;
  48. /*
  49. * Variable PlatformLang defines the language that the machine has been
  50. * configured for.
  51. */
  52. ret = efi_get_variable_int(L"PlatformLang",
  53. &efi_global_variable_guid,
  54. NULL, &data_size, &pos, NULL);
  55. if (ret == EFI_BUFFER_TOO_SMALL) {
  56. /* The variable is already set. Do not change it. */
  57. ret = EFI_SUCCESS;
  58. goto out;
  59. }
  60. /*
  61. * The list of supported languages is semicolon separated. Use the first
  62. * language to initialize PlatformLang.
  63. */
  64. pos = strchr(lang, ';');
  65. if (pos)
  66. *pos = 0;
  67. ret = efi_set_variable_int(L"PlatformLang",
  68. &efi_global_variable_guid,
  69. EFI_VARIABLE_NON_VOLATILE |
  70. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  71. EFI_VARIABLE_RUNTIME_ACCESS,
  72. 1 + strlen(lang), lang, false);
  73. out:
  74. if (ret != EFI_SUCCESS)
  75. printf("EFI: cannot initialize platform language settings\n");
  76. return ret;
  77. }
  78. #ifdef CONFIG_EFI_SECURE_BOOT
  79. /**
  80. * efi_init_secure_boot - initialize secure boot state
  81. *
  82. * Return: status code
  83. */
  84. static efi_status_t efi_init_secure_boot(void)
  85. {
  86. efi_guid_t signature_types[] = {
  87. EFI_CERT_SHA256_GUID,
  88. EFI_CERT_X509_GUID,
  89. };
  90. efi_status_t ret;
  91. ret = efi_set_variable_int(L"SignatureSupport",
  92. &efi_global_variable_guid,
  93. EFI_VARIABLE_READ_ONLY |
  94. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  95. EFI_VARIABLE_RUNTIME_ACCESS,
  96. sizeof(signature_types),
  97. &signature_types, false);
  98. if (ret != EFI_SUCCESS)
  99. printf("EFI: cannot initialize SignatureSupport variable\n");
  100. return ret;
  101. }
  102. #else
  103. static efi_status_t efi_init_secure_boot(void)
  104. {
  105. return EFI_SUCCESS;
  106. }
  107. #endif /* CONFIG_EFI_SECURE_BOOT */
  108. /**
  109. * efi_init_capsule - initialize capsule update state
  110. *
  111. * Return: status code
  112. */
  113. static efi_status_t efi_init_capsule(void)
  114. {
  115. efi_status_t ret = EFI_SUCCESS;
  116. if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_UPDATE)) {
  117. ret = efi_set_variable_int(L"CapsuleMax",
  118. &efi_guid_capsule_report,
  119. EFI_VARIABLE_READ_ONLY |
  120. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  121. EFI_VARIABLE_RUNTIME_ACCESS,
  122. 22, L"CapsuleFFFF", false);
  123. if (ret != EFI_SUCCESS)
  124. printf("EFI: cannot initialize CapsuleMax variable\n");
  125. }
  126. return ret;
  127. }
  128. /**
  129. * efi_init_os_indications() - indicate supported features for OS requests
  130. *
  131. * Set the OsIndicationsSupported variable.
  132. *
  133. * Return: status code
  134. */
  135. static efi_status_t efi_init_os_indications(void)
  136. {
  137. u64 os_indications_supported = 0;
  138. if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
  139. os_indications_supported |=
  140. EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED;
  141. if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK))
  142. os_indications_supported |=
  143. EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
  144. if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT))
  145. os_indications_supported |=
  146. EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;
  147. return efi_set_variable_int(L"OsIndicationsSupported",
  148. &efi_global_variable_guid,
  149. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  150. EFI_VARIABLE_RUNTIME_ACCESS |
  151. EFI_VARIABLE_READ_ONLY,
  152. sizeof(os_indications_supported),
  153. &os_indications_supported, false);
  154. }
  155. /**
  156. * efi_clear_os_indications() - clear OsIndications
  157. *
  158. * Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
  159. */
  160. static efi_status_t efi_clear_os_indications(void)
  161. {
  162. efi_uintn_t size;
  163. u64 os_indications;
  164. efi_status_t ret;
  165. size = sizeof(os_indications);
  166. ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
  167. NULL, &size, &os_indications, NULL);
  168. if (ret != EFI_SUCCESS)
  169. os_indications = 0;
  170. else
  171. os_indications &=
  172. ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
  173. ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid,
  174. EFI_VARIABLE_NON_VOLATILE |
  175. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  176. EFI_VARIABLE_RUNTIME_ACCESS,
  177. sizeof(os_indications), &os_indications,
  178. false);
  179. if (ret != EFI_SUCCESS)
  180. log_err("Setting %ls failed\n", L"OsIndications");
  181. return ret;
  182. }
  183. /**
  184. * efi_init_obj_list() - Initialize and populate EFI object list
  185. *
  186. * Return: status code
  187. */
  188. efi_status_t efi_init_obj_list(void)
  189. {
  190. efi_status_t r, ret = EFI_SUCCESS;
  191. /* Initialize once only */
  192. if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
  193. return efi_obj_list_initialized;
  194. /* Allow unaligned memory access */
  195. allow_unaligned();
  196. /* Initialize root node */
  197. ret = efi_root_node_register();
  198. if (ret != EFI_SUCCESS)
  199. goto out;
  200. ret = efi_console_register();
  201. if (ret != EFI_SUCCESS)
  202. goto out;
  203. #ifdef CONFIG_PARTITIONS
  204. ret = efi_disk_register();
  205. if (ret != EFI_SUCCESS)
  206. goto out;
  207. #endif
  208. if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) {
  209. ret = efi_rng_register();
  210. if (ret != EFI_SUCCESS)
  211. goto out;
  212. }
  213. /* Initialize variable services */
  214. ret = efi_init_variables();
  215. if (ret != EFI_SUCCESS)
  216. goto out;
  217. /* Define supported languages */
  218. ret = efi_init_platform_lang();
  219. if (ret != EFI_SUCCESS)
  220. goto out;
  221. /* Indicate supported features */
  222. ret = efi_init_os_indications();
  223. if (ret != EFI_SUCCESS)
  224. goto out;
  225. /* Initialize system table */
  226. ret = efi_initialize_system_table();
  227. if (ret != EFI_SUCCESS)
  228. goto out;
  229. if (IS_ENABLED(CONFIG_EFI_ESRT)) {
  230. ret = efi_esrt_register();
  231. if (ret != EFI_SUCCESS)
  232. goto out;
  233. }
  234. if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
  235. ret = efi_tcg2_register();
  236. if (ret != EFI_SUCCESS)
  237. goto out;
  238. }
  239. if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) {
  240. ret = efi_riscv_register();
  241. if (ret != EFI_SUCCESS)
  242. goto out;
  243. }
  244. /* Secure boot */
  245. ret = efi_init_secure_boot();
  246. if (ret != EFI_SUCCESS)
  247. goto out;
  248. /* Indicate supported runtime services */
  249. ret = efi_init_runtime_supported();
  250. if (ret != EFI_SUCCESS)
  251. goto out;
  252. /* Initialize EFI driver uclass */
  253. ret = efi_driver_init();
  254. if (ret != EFI_SUCCESS)
  255. goto out;
  256. if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
  257. ret = efi_load_capsule_drivers();
  258. if (ret != EFI_SUCCESS)
  259. goto out;
  260. }
  261. #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
  262. ret = efi_gop_register();
  263. if (ret != EFI_SUCCESS)
  264. goto out;
  265. #endif
  266. #ifdef CONFIG_NET
  267. ret = efi_net_register();
  268. if (ret != EFI_SUCCESS)
  269. goto out;
  270. #endif
  271. #ifdef CONFIG_GENERATE_ACPI_TABLE
  272. ret = efi_acpi_register();
  273. if (ret != EFI_SUCCESS)
  274. goto out;
  275. #endif
  276. #ifdef CONFIG_GENERATE_SMBIOS_TABLE
  277. ret = efi_smbios_register();
  278. if (ret != EFI_SUCCESS)
  279. goto out;
  280. #endif
  281. ret = efi_watchdog_register();
  282. if (ret != EFI_SUCCESS)
  283. goto out;
  284. ret = efi_init_capsule();
  285. if (ret != EFI_SUCCESS)
  286. goto out;
  287. /* Initialize EFI runtime services */
  288. ret = efi_reset_system_init();
  289. if (ret != EFI_SUCCESS)
  290. goto out;
  291. /* Execute capsules after reboot */
  292. if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
  293. !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
  294. ret = efi_launch_capsules();
  295. out:
  296. r = efi_clear_os_indications();
  297. if (ret == EFI_SUCCESS)
  298. ret = r;
  299. efi_obj_list_initialized = ret;
  300. return ret;
  301. }