Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code
Marc Gonzalez
mgonzalez at freebox.fr
Wed Feb 21 08:58:49 PST 2024
On 21/02/2024 08:40, Sumit Garg wrote:
> Hi Marc,
>
> On Tue, 20 Feb 2024 at 22:59, Marc Gonzalez wrote:
>>
>> Hello,
>>
>> The driver code I'm working on hard-codes
>>
>> #define TEE_SMC_FAST_CALL_VAL(func_num) \
>> ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>> ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
>>
>> #define TEE_SMC_FUNCID_CALLS_UID 0xFF01
>> #define TEE_SMC_CALLS_UID \
>> ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>> ARM_SMCCC_OWNER_TRUSTED_OS_END, \
>> TEE_SMC_FUNCID_CALLS_UID)
>>
>> arm_smccc_smc(TEE_SMC_CALLS_UID,
>> 0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
>> dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);
>>
>>
>> but it seems I would be required to somehow use
>> OPTEE_SMC_CALL_GET_OS_UUID
>>
>> But it's not exported, and no code seems to use it...?
>
> Can you describe your use-case to require direct
> OPTEE_SMC_CALL_GET_OS_UUID invocation?
Turns out the GET_OS_UUID call was just debug code to make sure
we were getting the expected reply.
I have removed it from the production code.
Below is the current code.
diff --git a/drivers/staging/media/meson/vdec/vdec_1.c b/drivers/staging/media/meson/vdec/vdec_1.c
index 3fe2de0c9331f..120bb1847aa38 100644
--- a/drivers/staging/media/meson/vdec/vdec_1.c
+++ b/drivers/staging/media/meson/vdec/vdec_1.c
@@ -8,7 +8,10 @@
*/
#include <linux/firmware.h>
+#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/arm-smccc.h>
+#include <soc/amlogic/socinfo.h>
#include "vdec_1.h"
#include "vdec_helpers.h"
@@ -22,6 +25,45 @@
#define MC_SIZE (4096 * 4)
+static int
+vdec_1_load_firmware_optee(struct amvdec_session *sess)
+{
+ struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
+ struct amvdec_core *core = sess->core;
+ struct device *dev = core->dev_dec;
+ struct arm_smccc_res res;
+ u32 pixfmt = sess->fmt_out->pixfmt;
+ int fw_id = -1;
+
+#define TEE_SMC_FAST_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
+
+#define TEE_SMC_FUNCID_LOAD_VIDEO_FW 15
+#define TEE_SMC_LOAD_VIDEO_FW TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_LOAD_VIDEO_FW)
+#define OPTEE_VDEC_LEGACY 0
+#define VIDEO_DEC_MPEG12 0
+#define VIDEO_DEC_H264 11
+
+ // Load wrong firmware, so that TA will reset hw component for us
+ arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, 1, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+
+ if (pixfmt == V4L2_PIX_FMT_H264)
+ fw_id = 11;
+
+ if (pixfmt == V4L2_PIX_FMT_MPEG1 || pixfmt == V4L2_PIX_FMT_MPEG2)
+ fw_id = 0;
+
+ arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, fw_id, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+ dev_info(dev, "Load firmware %d: ret=%d\n", fw_id, res.a0);
+
+ msleep(100);
+
+ if (codec_ops->load_extended_firmware)
+ codec_ops->load_extended_firmware(sess, 0, 0);
+
+ return 0;
+}
+
static int
vdec_1_load_firmware(struct amvdec_session *sess, const char *fwname)
{
@@ -209,7 +251,11 @@ static int vdec_1_start(struct amvdec_session *sess)
vdec_1_stbuf_power_up(sess);
- ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+ if (meson_get_secure_boot_state() == 1)
+ ret = vdec_1_load_firmware_optee(sess);
+ else
+ ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+
if (ret)
goto stop;
@@ -232,6 +278,13 @@ static int vdec_1_start(struct amvdec_session *sess)
/* Let the firmware settle */
usleep_range(10, 20);
+ /*
+ * When running secure boot, it looks like the codec needs
+ * more time to settle (perhaps to authenticate the image?)
+ */
+ if (meson_get_secure_boot_state() == 1)
+ msleep(100);
+
return 0;
stop:
>> $ git grep OPTEE_SMC_CALL_GET_OS_UUID
>> Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
>> drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \
>>
>> How do I make calls to OP-TEE from driver code?
>
> The TEE driver API documentation is here [1] and you can refer to the
> existing OP-TEE RNG driver here for reference.
>
> [1] https://docs.kernel.org/driver-api/tee.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/hw_random/optee-rng.c
Wow, this looks very different from our code.
Are we not supposed to call arm_smccc_smc() from driver code?
Looks like no one else is calling arm_smccc_smc with an owner
equal to ARM_SMCCC_OWNER_TRUSTED_OS...
Regards
More information about the linux-arm-kernel
mailing list