OP-TEE: Misc

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca Base addresses: U-Boot SPL: 0x80000000 OpenSBI: 0x80100000 OP-TEE: 0xf1000000 U-Boot proper: 0x81200000 / Relocated to: 0x17f76f000, relocate offset = 0xfe558000 E.g. 0x81217b66 → 0x17f76fb66; 0x81232884 → 0x17f78a884 Linux Kernel: 0x80200000 / 0xffffffff80000000 1 2 3 (gdb) add-symbol-file u-boot-spl 0x80000000 (gdb) add-symbol-file fw_dynamic.elf 0x80100000 (gdb) add-symbol-file tee.elf 0xf1000000 1 2 # For the relocated U-Boot (gdb) add-symbol-file u-boot -o 0xfe558000 When traps, mscratch/sscratch: If 0: Trap from kernel. If !0: Trap from user. See thread_init_per_cpu(), thread_trap_vect(). thread_init_per_cpu() sets mscratch/sscratch to 0 to indicate that the trap is from kernel. Fast Calls and Yielding Calls Fast Calls execute atomic operations. The call appears to be atomic from the perspective of the calling PE, and returns when the requested operation has completed. Yielding Calls start operations that can be pre-empted by a Non-secure interrupt. The call can return before the requested operation has completed.

2024/12/20 · 1 分鐘 · 151 字 · Frank Chang

OP-TEE: libteec

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca TEEC_InitializeContext() teec_open_dev() Open /dev/teeX device. TEEC_OpenSession() Call ioctl() with TEE_IOC_OPEN_SESSION command. This will eventually trap to Linux Kernel’s tee_ioctl(). TEEC_InvokeCommand() Call ioctl() with TEE_IOC_INVOKE command. The command ID for TA is passed through arg->func. TEEC_CloseSession() Call ioctl() with TEE_IOC_CLOSE_SESSION command. TEEC_FinalizeContext() Close /dev/teeX device.

2024/12/18 · 1 分鐘 · 54 字 · Frank Chang

OP-TEE: ABI

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca std_abi_entry() If args->a0: OPTEE_ABI_CALL_WITH_ARG or OPTEE_ABI_CALL_WITH_RPC_ARG: std_entry_with_parg() call_entry_std() tee_entry_std() __tee_entry_std() OPTEE_ABI_CALL_WITH_REGD_ARG: std_entry_with_regd_arg() __tee_entry_std() Call thread_set_foreign_intr() to enable all foreign interrupts. If arg->cmd: OPTEE_MSG_CMD_OPEN_SESSION: entry_open_session() OPTEE_MSG_CMD_CLOSE_SESSION: entry_close_session() OPTEE_MSG_CMD_INVOKE_COMMAND: entry_invoke_command() OPTEE_MSG_CMD_CANCEL: entry_cancel() OPTEE_MSG_CMD_REGISTER_SHM: register_shm() OPTEE_MSG_CMD_UNREGISTER_SHM: unregister_shm() …

2024/12/15 · 1 分鐘 · 45 字 · Frank Chang

OP-TEE: RPC

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca thread_rpc_cmd() Call thread_rpc() with rpc_args (rv[THREAD_RPC_NUM_ARGS]). rpc_args’s first element is set to OPTEE_ABI_RETURN_RPC_CMD function. thread_rpc() Call __thread_rpc() __thread_rpc() Call xstatus_for_xret() to get xstatus with xstatus.PIE set to 0, xstatus.PP set to S-mode. The returned xstatus is passed to thread_rpc_xstatus(). Call thread_rpc_xstatus(). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 // core/arch/riscv/kernel/thread_optee_abi_rv.S /* * void thread_rpc_xstatus(uint32_t rv[THREAD_RPC_NUM_ARGS], * unsigned long status); */ FUNC thread_rpc_xstatus , : // Allocate stack space for 8 registers. /* Use stack for temporary storage */ addi sp, sp, -REGOFF(8) /* Read xSTATUS */ csrr a2, CSR_XSTATUS /* Mask all maskable exceptions before switching to temporary stack */ csrw CSR_XIE, x0 /* Save return address xSTATUS and pointer to rv */ // $a0: rv[THREAD_RPC_NUM_ARGS] // $a1: xstatus to restore // $a2: current xstatus STR a0, REGOFF(0)(sp) STR a1, REGOFF(1)(sp) STR s0, REGOFF(2)(sp) STR ra, REGOFF(3)(sp) STR a2, REGOFF(4)(sp) #ifdef CFG_UNWIND addi s0, sp, REGOFF(8) #endif /* Save thread state */ jal thread_get_ctx_regs // $a0 = current thread's struct thread_ctx. // Restore $ra. LDR ra, REGOFF(3)(sp) /* Save ra, sp, gp, tp, and s0~s11 */ store_xregs a0, THREAD_CTX_REG_RA, REG_RA, REG_TP store_xregs a0, THREAD_CTX_REG_S0, REG_S0, REG_S1 store_xregs a0, THREAD_CTX_REG_S2, REG_S2, REG_S11 /* Get to tmp stack */ jal thread_get_tmp_sp // $a0 = tmp stack. /* Get pointer to rv */ LDR s1, REGOFF(0)(sp) // $s1 = rv[THREAD_RPC_NUM_ARGS] /* xSTATUS to restore */ LDR a1, REGOFF(1)(sp) // $a1 = xstatus to restore /* Switch to tmp stack */ mv sp, a0 /* Early load rv[] into s2-s4 */ lw s2, 0(s1) lw s3, 4(s1) lw s4, 8(s1) li a0, THREAD_FLAGS_COPY_ARGS_ON_RETURN la a2, .thread_rpc_return // We are about to return to untrusted domain for RPC, // suspend the current thread. jal [thread_state_suspend](/posts/optee-threads/) // $a0 = thread index before suspend. mv a4, a0 /* thread index */ mv a1, s2 /* rv[0] */ mv a2, s3 /* rv[1] */ mv a3, s4 /* rv[2] */ li a0, TEEABI_OPTEED_RETURN_CALL_DONE mv a5, zero /* Return to untrusted domain */ // $a0: TEEABI_OPTEED_RETURN_CALL_DONE // $a1: rv[0], e.g. OPTEE_ABI_RETURN_RPC_CMD // $a2: rv[1] // $a3: rv[2] // $a4: thread index before suspend. jal [thread_return_to_udomain](/posts/optee-threads/) .thread_rpc_return: /* * Jumps here from thread_resume() above when RPC has returned. * At this point has the stack pointer been restored to the value * stored in THREAD_CTX above. */ /* Get pointer to rv[] */ LDR a4, REGOFF(0)(sp) /* Store a0-a3 into rv[] */ sw a0, 0(a4) sw a1, 4(a4) sw a2, 8(a4) sw a3, 12(a4) /* Pop saved XSTATUS from stack */ LDR s0, REGOFF(4)(sp) csrw CSR_XSTATUS, s0 /* Pop s0 from stack */ LDR s0, REGOFF(2)(sp) addi sp, sp, REGOFF(8) ret END_FUNC thread_rpc_xstatus DECLARE_KEEP_PAGER thread_rpc_xstatus

2024/12/09 · 3 分鐘 · 548 字 · Frank Chang

OP-TEE: ldelf

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca ldelf_hex.c is generated by scripts/gen_ldelf_hex.py from the input file: ldelf.elf and is included by OP-TEE, i.e. ldelf_data[], ldelf_code_size, ldelf_data_size, and ldelf_entry. ldelf sources: <optee-src>/ldelf/ ldelf is running in U-mode. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 // core/kernel/ldelf_loader.c /* * This function may leave a few mappings behind on error, but that's taken * care of by tee_ta_init_user_ta_session() since the entire context is * removed then. */ TEE_Result ldelf_load_ldelf(struct user_mode_ctx *uctx) { TEE_Result res = TEE_SUCCESS; vaddr_t stack_addr = 0; vaddr_t code_addr = 0; vaddr_t rw_addr = 0; vaddr_t bb_addr = 0; uint32_t prot = 0; uctx->is_32bit = is_32bit; // Allocate memory for bounce buffer. res = alloc_and_map_fobj(uctx, BOUNCE_BUFFER_SIZE, TEE_MATTR_PRW, 0, &bb_addr); if (res) return res; uctx->bbuf = (void *)bb_addr; uctx->bbuf_size = BOUNCE_BUFFER_SIZE; // Allocate stack memory for ldelf. res = alloc_and_map_fobj(uctx, LDELF_STACK_SIZE, TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF, &stack_addr); if (res) return res; uctx->ldelf_stack_ptr = stack_addr + LDELF_STACK_SIZE; // Allocate code section memory for ldelf. res = alloc_and_map_fobj(uctx, ldelf_code_size, TEE_MATTR_PRW, VM_FLAG_LDELF, &code_addr); if (res) return res; // Assign uctx->entry_func to ldelf's entry point, i.e. [_ldelf_start()](/posts/optee-ldelf/). uctx->entry_func = code_addr + ldelf_entry; // Allocate data section memory for ldelf. rw_addr = ROUNDUP(code_addr + ldelf_code_size, SMALL_PAGE_SIZE); res = alloc_and_map_fobj(uctx, ldelf_data_size, TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF, &rw_addr); if (res) return res; vm_set_ctx(uctx->ts_ctx); // Copy ldelf codes. // ldelf_data[] includes both ldelf's codes and data. // ldelf_data[] is generated by script/gen_ldelf_hex.py. memcpy((void *)code_addr, ldelf_data, ldelf_code_size); // Copy ldelf data. res = copy_to_user((void *)rw_addr, ldelf_data + ldelf_code_size, ldelf_data_size); if (res) return res; prot = TEE_MATTR_URX; if (IS_ENABLED(CFG_CORE_BTI)) prot |= TEE_MATTR_GUARDED; res = vm_set_prot(uctx, code_addr, ROUNDUP(ldelf_code_size, SMALL_PAGE_SIZE), prot); if (res) return res; DMSG("ldelf load address %#"PRIxVA, code_addr); return TEE_SUCCESS; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 // core/kernel/ldelf_loader.c TEE_Result ldelf_init_with_ldelf(struct ts_session *sess, struct user_mode_ctx *uctx) { TEE_Result res = TEE_SUCCESS; struct ldelf_arg *arg = NULL; uint32_t panic_code = 0; uint32_t panicked = 0; uaddr_t usr_stack = 0; struct ldelf_arg *arg_bbuf = NULL; // Set user stack. usr_stack = uctx->ldelf_stack_ptr; usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); arg = (struct ldelf_arg *)usr_stack; // Temporay overwrites handle_scall() with [scall_handle_ldelf()](/posts/optee-ldelf/). sess->handle_scall = scall_handle_ldelf; res = clear_user(arg, sizeof(*arg)); if (res) return res; // Copy UUID to &arg->uuid. res = PUT_USER_SCALAR(uctx->ts_ctx->uuid, &arg->uuid); if (res) return res; // uctx->entry_func is set to ldelf's entry point, i.e. [_ldelf_start()](/posts/optee-ldelf/), // in [ldelf_load_ldelf()](/posts/optee-ldelf/). // Switch to U-mode to execute ldelf. // ldelf will fill in arg parameter of the TA ELF. // E.g. arg->is_32bit, arg->entry_func, arg->load_addr, arg->stack_ptr... etc. res = [thread_enter_user_mode](/posts/optee-threads/)((vaddr_t)arg, 0, 0, 0, usr_stack, uctx->entry_func, is_32bit, &panicked, &panic_code); // Restore handle_scall(). sess->handle_scall = sess->ctx->ops->handle_scall; thread_user_clear_vfp(uctx); ldelf_sess_cleanup(sess); if (panicked) { abort_print_current_ts(); EMSG("ldelf panicked"); return TEE_ERROR_GENERIC; } if (res) { EMSG("ldelf failed with res: %#"PRIx32, res); return res; } res = BB_MEMDUP_USER(arg, sizeof(*arg), &arg_bbuf); if (res) return res; if (is_user_ta_ctx(uctx->ts_ctx)) { /* * This is already checked by the elf loader, but since it runs * in user mode we're not trusting it entirely. */ if (arg_bbuf->flags & ~TA_FLAGS_MASK) return TEE_ERROR_BAD_FORMAT; to_user_ta_ctx(uctx->ts_ctx)->ta_ctx.flags = arg_bbuf->flags; } // Copy TA ELF's information to struct user_mode_ctx. uctx->is_32bit = arg_bbuf->is_32bit; uctx->entry_func = arg_bbuf->entry_func; uctx->load_addr = arg_bbuf->load_addr; uctx->stack_ptr = arg_bbuf->stack_ptr; uctx->dump_entry_func = arg_bbuf->dump_entry; #ifdef CFG_FTRACE_SUPPORT uctx->ftrace_entry_func = arg_bbuf->ftrace_entry; sess->fbuf = arg_bbuf->fbuf; #endif uctx->dl_entry_func = arg_bbuf->dl_entry; bb_free(arg_bbuf, sizeof(*arg)); return TEE_SUCCESS; } scall_handle_ldelf() ...

2024/12/06 · 5 分鐘 · 1007 字 · Frank Chang

OP-TEE: REE filesystem TA

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca Reference: Trusted Applications — OP-TEE documentation documentation ree_fs_ta_open() Call rpc_load() to request TA from tee-supplicant. Validate the loaded TA. rpc_load() Call thread_rpc_cmd() with OPTEE_RPC_CMD_LOAD_TA RPC command without struct thread_param_memref parameter to request the size of TA. OPTEE_RPC_CMD_LOAD_TA RPC command is saved to struct optee_msg_arg.cmd. struct optee_msg_arg is stored in the shared memory shared with the untrusted domain. Call thread_rpc_alloc_payload() to allocate data for TA. Call thread_rpc_alloc() to allocate shared memory for TA. Call thread_rpc() with rpc_args (rv[THREAD_RPC_NUM_ARGS]). rpc_args’s first element is set to OPTEE_ABI_RETURN_RPC_CMD function. The RPC command is set to OPTEE_RPC_CMD_SHM_ALLOC to allocate the shared memory for TA. Call thread_rpc_cmd() with OPTEE_RPC_CMD_LOAD_TA RPC command again with struct thread_param_memref parameter to load TA.

2024/12/03 · 1 分鐘 · 123 字 · Frank Chang

OP-TEE: User TAs

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca tee_ta_init_user_ta_session() Initialize user TA for the UUID, assign ctx->ts_ctx.ops to user_ta_ops by calling set_ta_ctx_ops(). user_ta_ops will be the global callbacks for the user TAs; assign tee_ta_session->ts_sess.handle_scall to scall_handle_user_ta(). scall_handle_user_ta() will be the default callback to handle the syscall from user TA: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // core/kernel/user_ta.c TEE_Result tee_ta_init_user_ta_session(const TEE_UUID *uuid, struct tee_ta_session *s) { TEE_Result res = TEE_SUCCESS; struct user_ta_ctx *utc = NULL; ..... // Initialize lists. TAILQ_INIT(&utc->open_sessions); TAILQ_INIT(&utc->cryp_states); TAILQ_INIT(&utc->objects); TAILQ_INIT(&utc->storage_enums); condvar_init(&utc->ta_ctx.busy_cv); utc->ta_ctx.ref_count = 1; /* * Set context TA operation structure. It is required by generic * implementation to identify userland TA versus pseudo TA contexts. */ // utc->ta_ctx->ts_ctx.ops = [user_ta_ops](/posts/optee-user-tas/). set_ta_ctx_ops(&utc->ta_ctx); utc->ta_ctx.ts_ctx.uuid = *uuid; // vm_info_init() will set: utc->uctx->ts_ctx = &utc->ta_ctx.ts_ctx. res = vm_info_init(&utc->uctx, &utc->ta_ctx.ts_ctx); if (res) { condvar_destroy(&utc->ta_ctx.busy_cv); free_utc(utc); return res; } ..... utc->ta_ctx.is_initializing = true; ..... s->ts_sess.ctx = &utc->ta_ctx.ts_ctx; s->ts_sess.handle_scall = s->ts_sess.ctx->ops->handle_scall; /* * Another thread trying to load this same TA may need to wait * until this context is fully initialized. This is needed to * handle single instance TAs. */ TAILQ_INSERT_TAIL(&tee_ctxes, &utc->ta_ctx, link); return TEE_SUCCESS; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // core/kernel/user_ta.c /* * Note: this variable is weak just to ease breaking its dependency chain * when added to the unpaged area. */ const struct ts_ops user_ta_ops __weak __relrodata_unpaged("user_ta_ops") = { .enter_open_session = user_ta_enter_open_session, .enter_invoke_cmd = user_ta_enter_invoke_cmd, .enter_close_session = user_ta_enter_close_session, #if defined(CFG_TA_STATS) .dump_mem_stats = user_ta_enter_dump_memstats, #endif .dump_state = user_ta_dump_state, #ifdef CFG_FTRACE_SUPPORT .dump_ftrace = user_ta_dump_ftrace, #endif .release_state = user_ta_release_state, .destroy = user_ta_ctx_destroy, .get_instance_id = user_ta_get_instance_id, .handle_scall = scall_handle_user_ta, #ifdef CFG_TA_GPROF_SUPPORT .gprof_set_status = user_ta_gprof_set_status, #endif }; tee_ta_complete_user_ta_session() Call ldelf_load_ldelf() to load ldelf program to the memory for this User TA. ldelf is responsible for loading the user TA ELF image residing in REE to the memory. If ldelf_load_ldelf() returns TEE_SUCCESS, call ldelf_init_with_ldelf() ldelf_load_ldelf() loads user TA ELF and fill in user TA ELF’s information to struct user_mode_ctx. user_ta_enter_open_session() Call user_ta_enter() with function ID: UTEE_ENTRY_FUNC_OPEN_SESSION. user_ta_enter_invoke_cmd() Call user_ta_enter() with function ID: UTEE_ENTRY_FUNC_INVOKE_COMMAND. user_ta_enter() Call thread_enter_user_mode() to switch to U-mode. utc->utcx.entry_func (user TA’s entry function address, filled by ldelf) will be called after switching to U-mode. E.g. For optee_example_hello_world, i.e. 8aaaf200-2450-11e4-abe2-0002a5d5c51b.elf, the entry_func is 0x400405f8 => __ta_entry(). __ta_entry() is the first user TA API called from TEE core (defined in ta/user_ta_header.c). It’s assigned in TA’s Makefile: ...

2024/11/30 · 4 分鐘 · 696 字 · Frank Chang

OP-TEE: Pseudo TAs

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca tee_ta_init_pseudo_ta_session() Look up the pseudo TA based on UUID. Create pseudo TA context for the UUID, assign ctx->ts_ctx.ops to pseudo_ta_ops. pseudo_ta_ops will be the global callbacks for the pseudo TAs: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // core/kernel/pseudo_ta.c TEE_Result tee_ta_init_pseudo_ta_session(const TEE_UUID *uuid, struct tee_ta_session *s) { ..... ctx->ref_count = 1; ctx->flags = ta->flags; stc->pseudo_ta = ta; ctx->ts_ctx.uuid = ta->uuid; ctx->ts_ctx.ops = &pseudo_ta_ops; ..... } 1 2 3 4 5 6 7 8 // core/kernel/pseudo_ta.c static const struct ts_ops pseudo_ta_ops = { .enter_open_session = pseudo_ta_enter_open_session, .enter_invoke_cmd = pseudo_ta_enter_invoke_cmd, .enter_close_session = pseudo_ta_enter_close_session, .destroy = pseudo_ta_destroy, }; pseudo_ta_enter_open_session() Call stc->pseudo_ta->open_session_entry_point() callback, if defined. E.g. If the opened session is for pseudo TA: rtc.pta, open_session_entry_point() callback is: open_session(): ...

2024/11/21 · 1 分鐘 · 211 字 · Frank Chang

OP-TEE: TAs

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca entry_open_session() Open the session based on the UUID. tee_ta_open_session() tee_ta_open_session() tee_ta_init_session() Call ts_ctx->ops->enter_open_session() callback, For pseudo TAs, the callback is: pseudo_ta_enter_open_session() For user TAs, the callback is user_ta_enter_open_session() tee_ta_init_session() Look for already loaded TA tee_ta_init_session_with_context() If the TA for this UUID is not loaded yet: Look for secure partition stmm_init_session() Look for pseudo TA tee_ta_init_pseudo_ta_session() Look for user TA tee_ta_init_user_ta_session() If tee_ta_init_user_ta_session() returns TEE_SUCCESS, call tee_ta_complete_user_ta_session() entry_invoke_command() Call tee_ta_get_session() to get the opened session from arg->session. Call tee_ta_invoke_command() on the opened session. Call ts_ctx->ops->enter_invoke_cmd(): For pseudo TAs, the callback is: pseudo_ta_enter_invoke_cmd() For user TAs, the call back is: user_ta_enter_invoke_cmd()

2024/11/17 · 1 分鐘 · 109 字 · Frank Chang

OP-TEE: SBI MPXY

⚠️ The code is based on: https://gitlab.com/riseproject/riscv-optee/optee_os/-/tree/dev-optee-mpxy Commit ID: 75df9ba41a404aec897399ead0ff0aebcbff48ca mpxy_opteed_channel_init() Check if MPXY extension is supported by OpenSBI. Extract MPXY channel ID from DT: compatible = “riscv,sbi-mpxy-opteed"; riscv,sbi-mpxy-channel-id ← Defines MPXY channel ID. Save MPXY channel ID to mpxy_opteed_ctx.channel_id. opensbi-domain-instance ← Defines the OpenSBI domain used by OP-TEE (not used by OP-TEE). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 chosen { opensbi-domains { trusted-domain { compatible = "opensbi,domain,instance"; regions = <0x04 0x3f>; possible-harts = <0x03 0x01>; next-addr = <0x00 0xf1000000>; next-mode = <0x01>; phandle = <0x02>; }; }; sbi-mpxy-opteed { opensbi-domain-instance = <0x02>; riscv,sbi-mpxy-channel-id = <0x02>; compatible = "riscv,sbi-mpxy-opteed"; }; sbi_mpxy_setup_shmem() ...

2024/10/18 · 2 分鐘 · 226 字 · Frank Chang