opteed_main.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. /*******************************************************************************
  7. * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a
  8. * plug-in component to the Secure Monitor, registered as a runtime service. The
  9. * SPD is expected to be a functional extension of the Secure Payload (SP) that
  10. * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting
  11. * the Trusted OS/Applications range to the dispatcher. The SPD will either
  12. * handle the request locally or delegate it to the Secure Payload. It is also
  13. * responsible for initialising and maintaining communication with the SP.
  14. ******************************************************************************/
  15. #include <assert.h>
  16. #include <errno.h>
  17. #include <inttypes.h>
  18. #include <stddef.h>
  19. #include <arch_helpers.h>
  20. #include <bl31/bl31.h>
  21. #include <common/bl_common.h>
  22. #include <common/debug.h>
  23. #include <common/runtime_svc.h>
  24. #include <lib/coreboot.h>
  25. #include <lib/el3_runtime/context_mgmt.h>
  26. #include <lib/optee_utils.h>
  27. #include <lib/transfer_list.h>
  28. #include <lib/xlat_tables/xlat_tables_v2.h>
  29. #if OPTEE_ALLOW_SMC_LOAD
  30. #include <libfdt.h>
  31. #endif /* OPTEE_ALLOW_SMC_LOAD */
  32. #include <plat/common/platform.h>
  33. #include <services/oem/chromeos/widevine_smc_handlers.h>
  34. #include <tools_share/uuid.h>
  35. #include "opteed_private.h"
  36. #include "teesmc_opteed.h"
  37. #if OPTEE_ALLOW_SMC_LOAD
  38. static struct transfer_list_header *bl31_tl;
  39. #endif
  40. /*******************************************************************************
  41. * Address of the entrypoint vector table in OPTEE. It is
  42. * initialised once on the primary core after a cold boot.
  43. ******************************************************************************/
  44. struct optee_vectors *optee_vector_table;
  45. /*******************************************************************************
  46. * Array to keep track of per-cpu OPTEE state
  47. ******************************************************************************/
  48. optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
  49. uint32_t opteed_rw;
  50. #if OPTEE_ALLOW_SMC_LOAD
  51. static bool opteed_allow_load;
  52. /* OP-TEE image loading service UUID */
  53. DEFINE_SVC_UUID2(optee_image_load_uuid,
  54. 0xb1eafba3, 0x5d31, 0x4612, 0xb9, 0x06,
  55. 0xc4, 0xc7, 0xa4, 0xbe, 0x3c, 0xc0);
  56. #define OPTEED_FDT_SIZE 1024
  57. static uint8_t fdt_buf[OPTEED_FDT_SIZE] __aligned(CACHE_WRITEBACK_GRANULE);
  58. #else
  59. static int32_t opteed_init(void);
  60. #endif
  61. uint64_t dual32to64(uint32_t high, uint32_t low)
  62. {
  63. return ((uint64_t)high << 32) | low;
  64. }
  65. /*******************************************************************************
  66. * This function is the handler registered for S-EL1 interrupts by the
  67. * OPTEED. It validates the interrupt and upon success arranges entry into
  68. * the OPTEE at 'optee_fiq_entry()' for handling the interrupt.
  69. ******************************************************************************/
  70. static uint64_t opteed_sel1_interrupt_handler(uint32_t id,
  71. uint32_t flags,
  72. void *handle,
  73. void *cookie)
  74. {
  75. uint32_t linear_id;
  76. optee_context_t *optee_ctx;
  77. #if OPTEE_ALLOW_SMC_LOAD
  78. if (optee_vector_table == NULL) {
  79. /* OPTEE is not loaded yet, ignore this interrupt */
  80. SMC_RET0(handle);
  81. }
  82. #endif
  83. /* Check the security state when the exception was generated */
  84. assert(get_interrupt_src_ss(flags) == NON_SECURE);
  85. /* Sanity check the pointer to this cpu's context */
  86. assert(handle == cm_get_context(NON_SECURE));
  87. /* Save the non-secure context before entering the OPTEE */
  88. cm_el1_sysregs_context_save(NON_SECURE);
  89. /* Get a reference to this cpu's OPTEE context */
  90. linear_id = plat_my_core_pos();
  91. optee_ctx = &opteed_sp_context[linear_id];
  92. assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE));
  93. cm_set_elr_el3(SECURE, (uint64_t)&optee_vector_table->fiq_entry);
  94. cm_el1_sysregs_context_restore(SECURE);
  95. cm_set_next_eret_context(SECURE);
  96. /*
  97. * Tell the OPTEE that it has to handle an FIQ (synchronously).
  98. * Also the instruction in normal world where the interrupt was
  99. * generated is passed for debugging purposes. It is safe to
  100. * retrieve this address from ELR_EL3 as the secure context will
  101. * not take effect until el3_exit().
  102. */
  103. SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3());
  104. }
  105. /*
  106. * Registers an interrupt handler for S-EL1 interrupts when generated during
  107. * code executing in the non-secure state. Panics if it fails to do so.
  108. */
  109. static void register_opteed_interrupt_handler(void)
  110. {
  111. u_register_t flags;
  112. uint64_t rc;
  113. flags = 0;
  114. set_interrupt_rm_flag(flags, NON_SECURE);
  115. rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
  116. opteed_sel1_interrupt_handler,
  117. flags);
  118. if (rc)
  119. panic();
  120. }
  121. /*******************************************************************************
  122. * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type
  123. * (aarch32/aarch64) if not already known and initialises the context for entry
  124. * into OPTEE for its initialization.
  125. ******************************************************************************/
  126. static int32_t opteed_setup(void)
  127. {
  128. #if OPTEE_ALLOW_SMC_LOAD
  129. opteed_allow_load = true;
  130. INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
  131. /*
  132. * We must register the interrupt handler now so that the interrupt
  133. * priorities are not changed after starting the linux kernel.
  134. */
  135. register_opteed_interrupt_handler();
  136. return 0;
  137. #else
  138. entry_point_info_t *optee_ep_info;
  139. uint32_t linear_id;
  140. uint64_t arg0;
  141. uint64_t arg1;
  142. uint64_t arg2;
  143. uint64_t arg3;
  144. struct transfer_list_header *tl = NULL;
  145. struct transfer_list_entry *te = NULL;
  146. void *dt = NULL;
  147. linear_id = plat_my_core_pos();
  148. /*
  149. * Get information about the Secure Payload (BL32) image. Its
  150. * absence is a critical failure. TODO: Add support to
  151. * conditionally include the SPD service
  152. */
  153. optee_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
  154. if (!optee_ep_info) {
  155. WARN("No OPTEE provided by BL2 boot loader, Booting device"
  156. " without OPTEE initialization. SMC`s destined for OPTEE"
  157. " will return SMC_UNK\n");
  158. return 1;
  159. }
  160. /*
  161. * If there's no valid entry point for SP, we return a non-zero value
  162. * signalling failure initializing the service. We bail out without
  163. * registering any handlers
  164. */
  165. if (!optee_ep_info->pc)
  166. return 1;
  167. if (TRANSFER_LIST &&
  168. optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
  169. REGISTER_CONVENTION_VERSION_MASK)) {
  170. tl = (void *)optee_ep_info->args.arg3;
  171. if (transfer_list_check_header(tl) == TL_OPS_NON) {
  172. return 1;
  173. }
  174. opteed_rw = GET_RW(optee_ep_info->spsr);
  175. te = transfer_list_find(tl, TL_TAG_FDT);
  176. dt = transfer_list_entry_data(te);
  177. if (opteed_rw == OPTEE_AARCH64) {
  178. arg0 = (uint64_t)dt;
  179. arg2 = 0;
  180. } else {
  181. arg2 = (uint64_t)dt;
  182. arg0 = 0;
  183. }
  184. arg1 = optee_ep_info->args.arg1;
  185. arg3 = optee_ep_info->args.arg3;
  186. } else {
  187. /* Default handoff arguments */
  188. opteed_rw = optee_ep_info->args.arg0;
  189. arg0 = optee_ep_info->args.arg1; /* opteed_pageable_part */
  190. arg1 = optee_ep_info->args.arg2; /* opteed_mem_limit */
  191. arg2 = optee_ep_info->args.arg3; /* dt_addr */
  192. arg3 = 0;
  193. }
  194. opteed_init_optee_ep_state(optee_ep_info, opteed_rw, optee_ep_info->pc,
  195. arg0, arg1, arg2, arg3,
  196. &opteed_sp_context[linear_id]);
  197. /*
  198. * All OPTEED initialization done. Now register our init function with
  199. * BL31 for deferred invocation
  200. */
  201. bl31_register_bl32_init(&opteed_init);
  202. return 0;
  203. #endif /* OPTEE_ALLOW_SMC_LOAD */
  204. }
  205. /*******************************************************************************
  206. * This function passes control to the OPTEE image (BL32) for the first time
  207. * on the primary cpu after a cold boot. It assumes that a valid secure
  208. * context has already been created by opteed_setup() which can be directly
  209. * used. It also assumes that a valid non-secure context has been
  210. * initialised by PSCI so it does not need to save and restore any
  211. * non-secure state. This function performs a synchronous entry into
  212. * OPTEE. OPTEE passes control back to this routine through a SMC. This returns
  213. * a non-zero value on success and zero on failure.
  214. ******************************************************************************/
  215. static int32_t
  216. opteed_init_with_entry_point(entry_point_info_t *optee_entry_point)
  217. {
  218. uint32_t linear_id = plat_my_core_pos();
  219. optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
  220. uint64_t rc;
  221. assert(optee_entry_point);
  222. cm_init_my_context(optee_entry_point);
  223. /*
  224. * Arrange for an entry into OPTEE. It will be returned via
  225. * OPTEE_ENTRY_DONE case
  226. */
  227. rc = opteed_synchronous_sp_entry(optee_ctx);
  228. assert(rc != 0);
  229. return rc;
  230. }
  231. #if !OPTEE_ALLOW_SMC_LOAD
  232. static int32_t opteed_init(void)
  233. {
  234. entry_point_info_t *optee_entry_point;
  235. /*
  236. * Get information about the OP-TEE (BL32) image. Its
  237. * absence is a critical failure.
  238. */
  239. optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
  240. return opteed_init_with_entry_point(optee_entry_point);
  241. }
  242. #endif /* !OPTEE_ALLOW_SMC_LOAD */
  243. #if OPTEE_ALLOW_SMC_LOAD
  244. #if COREBOOT
  245. /*
  246. * Adds a firmware/coreboot node with the coreboot table information to a device
  247. * tree. Returns zero on success or if there is no coreboot table information;
  248. * failure code otherwise.
  249. */
  250. static int add_coreboot_node(void *fdt)
  251. {
  252. int ret;
  253. uint64_t coreboot_table_addr;
  254. uint32_t coreboot_table_size;
  255. struct {
  256. uint64_t addr;
  257. uint32_t size;
  258. } reg_node;
  259. coreboot_get_table_location(&coreboot_table_addr, &coreboot_table_size);
  260. if (!coreboot_table_addr || !coreboot_table_size) {
  261. WARN("Unable to get coreboot table location for device tree");
  262. return 0;
  263. }
  264. ret = fdt_begin_node(fdt, "firmware");
  265. if (ret)
  266. return ret;
  267. ret = fdt_property(fdt, "ranges", NULL, 0);
  268. if (ret)
  269. return ret;
  270. ret = fdt_begin_node(fdt, "coreboot");
  271. if (ret)
  272. return ret;
  273. ret = fdt_property_string(fdt, "compatible", "coreboot");
  274. if (ret)
  275. return ret;
  276. reg_node.addr = cpu_to_fdt64(coreboot_table_addr);
  277. reg_node.size = cpu_to_fdt32(coreboot_table_size);
  278. ret = fdt_property(fdt, "reg", &reg_node,
  279. sizeof(uint64_t) + sizeof(uint32_t));
  280. if (ret)
  281. return ret;
  282. ret = fdt_end_node(fdt);
  283. if (ret)
  284. return ret;
  285. return fdt_end_node(fdt);
  286. }
  287. #endif /* COREBOOT */
  288. #if CROS_WIDEVINE_SMC
  289. /*
  290. * Adds a options/widevine node with the widevine table information to a device
  291. * tree. Returns zero on success or if there is no widevine table information;
  292. * failure code otherwise.
  293. */
  294. static int add_options_widevine_node(void *fdt)
  295. {
  296. int ret;
  297. ret = fdt_begin_node(fdt, "options");
  298. if (ret)
  299. return ret;
  300. ret = fdt_begin_node(fdt, "op-tee");
  301. if (ret)
  302. return ret;
  303. ret = fdt_begin_node(fdt, "widevine");
  304. if (ret)
  305. return ret;
  306. if (cros_oem_tpm_auth_pk.length) {
  307. ret = fdt_property(fdt, "tcg,tpm-auth-public-key",
  308. cros_oem_tpm_auth_pk.buffer,
  309. cros_oem_tpm_auth_pk.length);
  310. if (ret)
  311. return ret;
  312. }
  313. if (cros_oem_huk.length) {
  314. ret = fdt_property(fdt, "op-tee,hardware-unique-key",
  315. cros_oem_huk.buffer, cros_oem_huk.length);
  316. if (ret)
  317. return ret;
  318. }
  319. if (cros_oem_rot.length) {
  320. ret = fdt_property(fdt, "google,widevine-root-of-trust-ecc-p256",
  321. cros_oem_rot.buffer, cros_oem_rot.length);
  322. if (ret)
  323. return ret;
  324. }
  325. ret = fdt_end_node(fdt);
  326. if (ret)
  327. return ret;
  328. ret = fdt_end_node(fdt);
  329. if (ret)
  330. return ret;
  331. return fdt_end_node(fdt);
  332. }
  333. #endif /* CROS_WIDEVINE_SMC */
  334. /*
  335. * Creates a device tree for passing into OP-TEE. Currently is populated with
  336. * the coreboot table address.
  337. * Returns 0 on success, error code otherwise.
  338. */
  339. static int create_opteed_dt(void)
  340. {
  341. int ret;
  342. ret = fdt_create(fdt_buf, OPTEED_FDT_SIZE);
  343. if (ret)
  344. return ret;
  345. ret = fdt_finish_reservemap(fdt_buf);
  346. if (ret)
  347. return ret;
  348. ret = fdt_begin_node(fdt_buf, "");
  349. if (ret)
  350. return ret;
  351. #if COREBOOT
  352. ret = add_coreboot_node(fdt_buf);
  353. if (ret)
  354. return ret;
  355. #endif /* COREBOOT */
  356. #if CROS_WIDEVINE_SMC
  357. ret = add_options_widevine_node(fdt_buf);
  358. if (ret)
  359. return ret;
  360. #endif /* CROS_WIDEVINE_SMC */
  361. ret = fdt_end_node(fdt_buf);
  362. if (ret)
  363. return ret;
  364. return fdt_finish(fdt_buf);
  365. }
  366. static int32_t create_smc_tl(const void *fdt, uint32_t fdt_sz)
  367. {
  368. #if TRANSFER_LIST
  369. bl31_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
  370. FW_HANDOFF_SIZE);
  371. if (!bl31_tl) {
  372. ERROR("Failed to initialize Transfer List at 0x%lx\n",
  373. (unsigned long)FW_HANDOFF_BASE);
  374. return -1;
  375. }
  376. if (!transfer_list_add(bl31_tl, TL_TAG_FDT, fdt_sz, fdt)) {
  377. return -1;
  378. }
  379. return 0;
  380. #else
  381. return -1;
  382. #endif
  383. }
  384. /*******************************************************************************
  385. * This function is responsible for handling the SMC that loads the OP-TEE
  386. * binary image via a non-secure SMC call. It takes the size and physical
  387. * address of the payload as parameters.
  388. ******************************************************************************/
  389. static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
  390. {
  391. uintptr_t data_va = data_pa;
  392. uint64_t mapped_data_pa;
  393. uintptr_t mapped_data_va;
  394. uint64_t data_map_size;
  395. int32_t rc;
  396. optee_header_t *image_header;
  397. uint8_t *image_ptr;
  398. uint64_t target_pa;
  399. uint64_t target_end_pa;
  400. uint64_t image_pa;
  401. uintptr_t image_va;
  402. optee_image_t *curr_image;
  403. uintptr_t target_va;
  404. uint64_t target_size;
  405. entry_point_info_t optee_ep_info;
  406. uint32_t linear_id = plat_my_core_pos();
  407. uint64_t dt_addr = 0;
  408. uint64_t arg0 = 0;
  409. uint64_t arg1 = 0;
  410. uint64_t arg2 = 0;
  411. uint64_t arg3 = 0;
  412. mapped_data_pa = page_align(data_pa, DOWN);
  413. mapped_data_va = mapped_data_pa;
  414. data_map_size = page_align(data_size + (mapped_data_pa - data_pa), UP);
  415. /*
  416. * We do not validate the passed in address because we are trusting the
  417. * non-secure world at this point still.
  418. */
  419. rc = mmap_add_dynamic_region(mapped_data_pa, mapped_data_va,
  420. data_map_size, MT_MEMORY | MT_RO | MT_NS);
  421. if (rc != 0) {
  422. return rc;
  423. }
  424. image_header = (optee_header_t *)data_va;
  425. if (image_header->magic != TEE_MAGIC_NUM_OPTEE ||
  426. image_header->version != 2 || image_header->nb_images != 1) {
  427. mmap_remove_dynamic_region(mapped_data_va, data_map_size);
  428. return -EINVAL;
  429. }
  430. image_ptr = (uint8_t *)data_va + sizeof(optee_header_t) +
  431. sizeof(optee_image_t);
  432. if (image_header->arch == 1) {
  433. opteed_rw = OPTEE_AARCH64;
  434. } else {
  435. opteed_rw = OPTEE_AARCH32;
  436. }
  437. curr_image = &image_header->optee_image_list[0];
  438. image_pa = dual32to64(curr_image->load_addr_hi,
  439. curr_image->load_addr_lo);
  440. image_va = image_pa;
  441. target_end_pa = image_pa + curr_image->size;
  442. /* Now also map the memory we want to copy it to. */
  443. target_pa = page_align(image_pa, DOWN);
  444. target_va = target_pa;
  445. target_size = page_align(target_end_pa, UP) - target_pa;
  446. rc = mmap_add_dynamic_region(target_pa, target_va, target_size,
  447. MT_MEMORY | MT_RW | MT_SECURE);
  448. if (rc != 0) {
  449. mmap_remove_dynamic_region(mapped_data_va, data_map_size);
  450. return rc;
  451. }
  452. INFO("Loaded OP-TEE via SMC: size %d addr 0x%" PRIx64 "\n",
  453. curr_image->size, image_va);
  454. memcpy((void *)image_va, image_ptr, curr_image->size);
  455. flush_dcache_range(target_pa, target_size);
  456. mmap_remove_dynamic_region(mapped_data_va, data_map_size);
  457. mmap_remove_dynamic_region(target_va, target_size);
  458. /* Save the non-secure state */
  459. cm_el1_sysregs_context_save(NON_SECURE);
  460. rc = create_opteed_dt();
  461. if (rc) {
  462. ERROR("Failed device tree creation %d\n", rc);
  463. return rc;
  464. }
  465. dt_addr = (uint64_t)fdt_buf;
  466. flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
  467. if (TRANSFER_LIST &&
  468. !create_smc_tl((void *)dt_addr, OPTEED_FDT_SIZE)) {
  469. struct transfer_list_entry *te = NULL;
  470. void *dt = NULL;
  471. te = transfer_list_find(bl31_tl, TL_TAG_FDT);
  472. dt = transfer_list_entry_data(te);
  473. if (opteed_rw == OPTEE_AARCH64) {
  474. arg0 = (uint64_t)dt;
  475. arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
  476. arg2 = 0;
  477. } else {
  478. arg0 = 0;
  479. arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
  480. arg2 = (uint64_t)dt;
  481. }
  482. arg3 = (uint64_t)bl31_tl;
  483. } else {
  484. /* Default handoff arguments */
  485. arg2 = dt_addr;
  486. }
  487. opteed_init_optee_ep_state(&optee_ep_info,
  488. opteed_rw,
  489. image_pa,
  490. arg0,
  491. arg1,
  492. arg2,
  493. arg3,
  494. &opteed_sp_context[linear_id]);
  495. if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
  496. rc = -EFAULT;
  497. }
  498. /* Restore non-secure state */
  499. cm_el1_sysregs_context_restore(NON_SECURE);
  500. cm_set_next_eret_context(NON_SECURE);
  501. return rc;
  502. }
  503. #endif /* OPTEE_ALLOW_SMC_LOAD */
  504. /*******************************************************************************
  505. * This function is responsible for handling all SMCs in the Trusted OS/App
  506. * range from the non-secure state as defined in the SMC Calling Convention
  507. * Document. It is also responsible for communicating with the Secure
  508. * payload to delegate work and return results back to the non-secure
  509. * state. Lastly it will also return any information that OPTEE needs to do
  510. * the work assigned to it.
  511. ******************************************************************************/
  512. static uintptr_t opteed_smc_handler(uint32_t smc_fid,
  513. u_register_t x1,
  514. u_register_t x2,
  515. u_register_t x3,
  516. u_register_t x4,
  517. void *cookie,
  518. void *handle,
  519. u_register_t flags)
  520. {
  521. cpu_context_t *ns_cpu_context;
  522. uint32_t linear_id = plat_my_core_pos();
  523. optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
  524. /*
  525. * Determine which security state this SMC originated from
  526. */
  527. if (is_caller_non_secure(flags)) {
  528. #if OPTEE_ALLOW_SMC_LOAD
  529. if (opteed_allow_load && smc_fid == NSSMC_OPTEED_CALL_UID) {
  530. /* Provide the UUID of the image loading service. */
  531. SMC_UUID_RET(handle, optee_image_load_uuid);
  532. }
  533. if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
  534. /*
  535. * TODO: Consider wiping the code for SMC loading from
  536. * memory after it has been invoked similar to what is
  537. * done under RECLAIM_INIT, but extended to happen
  538. * later.
  539. */
  540. if (!opteed_allow_load) {
  541. SMC_RET1(handle, -EPERM);
  542. }
  543. opteed_allow_load = false;
  544. uint64_t data_size = dual32to64(x1, x2);
  545. uint64_t data_pa = dual32to64(x3, x4);
  546. if (!data_size || !data_pa) {
  547. /*
  548. * This is invoked when the OP-TEE image didn't
  549. * load correctly in the kernel but we want to
  550. * block off loading of it later for security
  551. * reasons.
  552. */
  553. SMC_RET1(handle, -EINVAL);
  554. }
  555. SMC_RET1(handle, opteed_handle_smc_load(
  556. data_size, data_pa));
  557. }
  558. #endif /* OPTEE_ALLOW_SMC_LOAD */
  559. /*
  560. * This is a fresh request from the non-secure client.
  561. * The parameters are in x1 and x2. Figure out which
  562. * registers need to be preserved, save the non-secure
  563. * state and send the request to the secure payload.
  564. */
  565. assert(handle == cm_get_context(NON_SECURE));
  566. cm_el1_sysregs_context_save(NON_SECURE);
  567. /*
  568. * We are done stashing the non-secure context. Ask the
  569. * OP-TEE to do the work now. If we are loading vi an SMC,
  570. * then we also need to init this CPU context if not done
  571. * already.
  572. */
  573. if (optee_vector_table == NULL) {
  574. SMC_RET1(handle, -EINVAL);
  575. }
  576. if (get_optee_pstate(optee_ctx->state) ==
  577. OPTEE_PSTATE_UNKNOWN) {
  578. opteed_cpu_on_finish_handler(0);
  579. }
  580. /*
  581. * Verify if there is a valid context to use, copy the
  582. * operation type and parameters to the secure context
  583. * and jump to the fast smc entry point in the secure
  584. * payload. Entry into S-EL1 will take place upon exit
  585. * from this function.
  586. */
  587. assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE));
  588. /* Set appropriate entry for SMC.
  589. * We expect OPTEE to manage the PSTATE.I and PSTATE.F
  590. * flags as appropriate.
  591. */
  592. if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
  593. cm_set_elr_el3(SECURE, (uint64_t)
  594. &optee_vector_table->fast_smc_entry);
  595. } else {
  596. cm_set_elr_el3(SECURE, (uint64_t)
  597. &optee_vector_table->yield_smc_entry);
  598. }
  599. cm_el1_sysregs_context_restore(SECURE);
  600. cm_set_next_eret_context(SECURE);
  601. write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
  602. CTX_GPREG_X4,
  603. read_ctx_reg(get_gpregs_ctx(handle),
  604. CTX_GPREG_X4));
  605. write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
  606. CTX_GPREG_X5,
  607. read_ctx_reg(get_gpregs_ctx(handle),
  608. CTX_GPREG_X5));
  609. write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
  610. CTX_GPREG_X6,
  611. read_ctx_reg(get_gpregs_ctx(handle),
  612. CTX_GPREG_X6));
  613. /* Propagate hypervisor client ID */
  614. write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
  615. CTX_GPREG_X7,
  616. read_ctx_reg(get_gpregs_ctx(handle),
  617. CTX_GPREG_X7));
  618. SMC_RET4(&optee_ctx->cpu_ctx, smc_fid, x1, x2, x3);
  619. }
  620. /*
  621. * Returning from OPTEE
  622. */
  623. switch (smc_fid) {
  624. /*
  625. * OPTEE has finished initialising itself after a cold boot
  626. */
  627. case TEESMC_OPTEED_RETURN_ENTRY_DONE:
  628. /*
  629. * Stash the OPTEE entry points information. This is done
  630. * only once on the primary cpu
  631. */
  632. assert(optee_vector_table == NULL);
  633. optee_vector_table = (optee_vectors_t *) x1;
  634. if (optee_vector_table) {
  635. set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);
  636. /*
  637. * OPTEE has been successfully initialized.
  638. * Register power management hooks with PSCI
  639. */
  640. psci_register_spd_pm_hook(&opteed_pm);
  641. #if !OPTEE_ALLOW_SMC_LOAD
  642. register_opteed_interrupt_handler();
  643. #endif
  644. }
  645. /*
  646. * OPTEE reports completion. The OPTEED must have initiated
  647. * the original request through a synchronous entry into
  648. * OPTEE. Jump back to the original C runtime context.
  649. */
  650. opteed_synchronous_sp_exit(optee_ctx, x1);
  651. break;
  652. /*
  653. * These function IDs is used only by OP-TEE to indicate it has
  654. * finished:
  655. * 1. turning itself on in response to an earlier psci
  656. * cpu_on request
  657. * 2. resuming itself after an earlier psci cpu_suspend
  658. * request.
  659. */
  660. case TEESMC_OPTEED_RETURN_ON_DONE:
  661. case TEESMC_OPTEED_RETURN_RESUME_DONE:
  662. /*
  663. * These function IDs is used only by the SP to indicate it has
  664. * finished:
  665. * 1. suspending itself after an earlier psci cpu_suspend
  666. * request.
  667. * 2. turning itself off in response to an earlier psci
  668. * cpu_off request.
  669. */
  670. case TEESMC_OPTEED_RETURN_OFF_DONE:
  671. case TEESMC_OPTEED_RETURN_SUSPEND_DONE:
  672. case TEESMC_OPTEED_RETURN_SYSTEM_OFF_DONE:
  673. case TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE:
  674. /*
  675. * OPTEE reports completion. The OPTEED must have initiated the
  676. * original request through a synchronous entry into OPTEE.
  677. * Jump back to the original C runtime context, and pass x1 as
  678. * return value to the caller
  679. */
  680. opteed_synchronous_sp_exit(optee_ctx, x1);
  681. break;
  682. /*
  683. * OPTEE is returning from a call or being preempted from a call, in
  684. * either case execution should resume in the normal world.
  685. */
  686. case TEESMC_OPTEED_RETURN_CALL_DONE:
  687. /*
  688. * This is the result from the secure client of an
  689. * earlier request. The results are in x0-x3. Copy it
  690. * into the non-secure context, save the secure state
  691. * and return to the non-secure state.
  692. */
  693. assert(handle == cm_get_context(SECURE));
  694. cm_el1_sysregs_context_save(SECURE);
  695. /* Get a reference to the non-secure context */
  696. ns_cpu_context = cm_get_context(NON_SECURE);
  697. assert(ns_cpu_context);
  698. /* Restore non-secure state */
  699. cm_el1_sysregs_context_restore(NON_SECURE);
  700. cm_set_next_eret_context(NON_SECURE);
  701. SMC_RET4(ns_cpu_context, x1, x2, x3, x4);
  702. /*
  703. * OPTEE has finished handling a S-EL1 FIQ interrupt. Execution
  704. * should resume in the normal world.
  705. */
  706. case TEESMC_OPTEED_RETURN_FIQ_DONE:
  707. /* Get a reference to the non-secure context */
  708. ns_cpu_context = cm_get_context(NON_SECURE);
  709. assert(ns_cpu_context);
  710. /*
  711. * Restore non-secure state. There is no need to save the
  712. * secure system register context since OPTEE was supposed
  713. * to preserve it during S-EL1 interrupt handling.
  714. */
  715. cm_el1_sysregs_context_restore(NON_SECURE);
  716. cm_set_next_eret_context(NON_SECURE);
  717. SMC_RET0((uint64_t) ns_cpu_context);
  718. default:
  719. panic();
  720. }
  721. }
  722. /* Define an OPTEED runtime service descriptor for fast SMC calls */
  723. DECLARE_RT_SVC(
  724. opteed_fast,
  725. OEN_TOS_START,
  726. OEN_TOS_END,
  727. SMC_TYPE_FAST,
  728. opteed_setup,
  729. opteed_smc_handler
  730. );
  731. /* Define an OPTEED runtime service descriptor for yielding SMC calls */
  732. DECLARE_RT_SVC(
  733. opteed_std,
  734. OEN_TOS_START,
  735. OEN_TOS_END,
  736. SMC_TYPE_YIELD,
  737. NULL,
  738. opteed_smc_handler
  739. );