// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019 MediaTek Inc. */ /* * GenieZone (hypervisor-based seucrity platform) enables hardware protected * and isolated security execution environment, includes * 1. GZ hypervisor * 2. Hypervisor-TEE OS (built-in Trusty OS) * 3. Drivers (ex: debug, communication and interrupt) for GZ and * hypervisor-TEE OS * 4. GZ and hypervisor-TEE and GZ framework (supporting multiple TEE * ecosystem, ex: M-TEE, Trusty, GlobalPlatform, ...) */ #include #include #define SMC_UNDEFINED 0xFFFFFFFF /* gz_smcnr_table: * Select SMC number by looking up gz_smcnr_table. * This table is introduced to support more TEEs and drive them with the same * code. */ static const uint32_t gz_smcnr_table[SMCF_END][TEE_ID_END] = { [SMCF_FC_RESERVED] = { SMC_FC_GZ_RESERVED, SMC_FC_GZ_RESERVED }, [SMCF_FC_FIQ_EXIT] = { SMC_FC_GZ_FIQ_EXIT, SMC_FC_GZ_FIQ_EXIT }, [SMCF_FC_REQUEST_FIQ] = { SMC_FC_GZ_REQUEST_FIQ, SMC_FC_GZ_REQUEST_FIQ}, [SMCF_FC_GET_NEXT_IRQ] = { SMC_FC_GZ_GET_NEXT_IRQ, SMC_FC_GZ_GET_NEXT_IRQ }, [SMCF_FC_FIQ_ENTER] = { SMC_FC_GZ_FIQ_ENTER, SMC_FC_GZ_FIQ_ENTER }, [SMCF_FC64_SET_FIQ_HANDLER] = { SMC_FC64_GZ_SET_FIQ_HANDLER, SMC_FC64_GZ_SET_FIQ_HANDLER }, [SMCF_FC64_GET_FIQ_REGS] = { SMC_FC64_GZ_GET_FIQ_REGS, SMC_FC64_GZ_GET_FIQ_REGS }, [SMCF_FC_CPU_SUSPEND] = { SMC_FC_GZ_CPU_SUSPEND, SMC_FC_GZ_CPU_SUSPEND }, [SMCF_FC_CPU_RESUME] = { SMC_FC_GZ_CPU_RESUME, SMC_FC_GZ_CPU_RESUME }, [SMCF_FC_AARCH_SWITCH] = { SMC_FC_GZ_AARCH_SWITCH, SMC_FC_GZ_AARCH_SWITCH }, [SMCF_FC_GET_VERSION_STR] = { SMC_FC_GZ_GET_VERSION_STR, SMC_FC_GZ_GET_VERSION_STR }, [SMCF_FC_API_VERSION] = { SMC_FC_GZ_API_VERSION, SMC_FC_GZ_API_VERSION }, [SMCF_FC_GET_CMASK] = { SMC_FC_GZ_GET_CMASK, SMC_FC_GZ_GET_CMASK }, [SMCF_FC_GET_CPU_REQUEST] = { SMC_FC_GZ_GET_CPU_REQUEST, SMC_FC_GZ_GET_CPU_REQUEST }, [SMCF_SC_NS_RETURN] = { SMC_SC_GZ_NS_RETURN, SMC_SC_GZ_NS_RETURN }, [MT_SMCF_SC_ADD] = { MT_SMC_SC_GZ_ADD, SMC_UNDEFINED }, [MT_SMCF_SC_MDELAY] = { MT_SMC_SC_GZ_MDELAY, SMC_UNDEFINED }, [MT_SMCF_SC_IRQ_LATENCY] = { MT_SMC_SC_GZ_IRQ_LATENCY, SMC_UNDEFINED }, [MT_SMCF_SC_INTERCEPT_MMIO] = { MT_SMC_SC_GZ_INTERCEPT_MMIO, SMC_UNDEFINED }, [MT_SMCF_FC_THREADS] = { MT_SMC_FC_GZ_THREADS, SMC_UNDEFINED }, [MT_SMCF_FC_THREADSTATS] = { MT_SMC_FC_GZ_THREADSTATS, SMC_UNDEFINED }, [MT_SMCF_FC_THREADLOAD] = { MT_SMC_FC_GZ_THREADLOAD, SMC_UNDEFINED }, [MT_SMCF_FC_HEAP_DUMP] = { MT_SMC_FC_GZ_HEAP_DUMP, SMC_UNDEFINED }, [MT_SMCF_FC_APPS] = { MT_SMC_FC_GZ_APPS, SMC_UNDEFINED }, [MT_SMCF_FC_MEM_USAGE] = { MT_SMC_FC_GZ_MEM_USAGE, SMC_UNDEFINED }, [MT_SMCF_FC_DEVAPC_VIO] = { MT_SMC_FC_GZ_DEVAPC_VIO, SMC_UNDEFINED }, [MT_SMCF_SC_SET_RAMCONSOLE] = { MT_SMC_SC_GZ_SET_RAMCONSOLE, SMC_UNDEFINED }, [MT_SMCF_SC_VPU] = { MT_SMC_SC_GZ_VPU, SMC_UNDEFINED }, [MT_SMCF_FC_KTIME_ALIGN] = { MT_SMC_FC_GZ_KTIME, SMC_UNDEFINED }, [SMCF_FC_TEST_ADD] = { SMC_UNDEFINED, SMC_FC_NBL_TEST_ADD }, [SMCF_FC_TEST_MULTIPLY] = { SMC_UNDEFINED, SMC_FC_NBL_TEST_MULTIPLY }, [SMCF_SC_TEST_ADD] = { SMC_UNDEFINED, SMC_SC_NBL_TEST_ADD }, [SMCF_SC_TEST_MULTIPLY] = { SMC_UNDEFINED, SMC_SC_NBL_TEST_MULTIPLY }, [SMCF_SC_RESTART_LAST] = { SMC_SC_TRU_RESTART_LAST, SMC_SC_NBL_RESTART_LAST }, [SMCF_SC_LOCKED_NOP] = { SMC_SC_TRU_LOCKED_NOP, SMC_SC_NBL_LOCKED_NOP }, [SMCF_SC_RESTART_FIQ] = { SMC_SC_TRU_RESTART_FIQ, SMC_SC_GZ_RESTART_FIQ }, [SMCF_SC_NOP] = { SMC_SC_TRU_NOP, SMC_SC_NBL_NOP }, [SMCF_SC_SHARED_LOG_VERSION] = { SMC_SC_GZ_SHARED_LOG_VERSION, SMC_SC_GZ_SHARED_LOG_VERSION }, [SMCF_SC_SHARED_LOG_ADD] = { SMC_SC_GZ_SHARED_LOG_ADD, SMC_SC_GZ_SHARED_LOG_ADD }, [SMCF_SC_SHARED_LOG_RM] = { SMC_SC_GZ_SHARED_LOG_RM, SMC_SC_GZ_SHARED_LOG_RM }, [SMCF_SC_VIRTIO_GET_DESCR] = { SMC_SC_GZ_VIRTIO_GET_DESCR, SMC_SC_NBL_VIRTIO_GET_DESCR }, [SMCF_SC_VIRTIO_START] = { SMC_SC_GZ_VIRTIO_START, SMC_SC_NBL_VIRTIO_START }, [SMCF_SC_VIRTIO_STOP] = { SMC_SC_GZ_VIRTIO_STOP, SMC_SC_NBL_VIRTIO_STOP }, [SMCF_SC_VDEV_RESET] = { SMC_SC_GZ_VDEV_RESET, SMC_SC_NBL_VDEV_RESET }, [SMCF_SC_VDEV_KICK_VQ] = { SMC_SC_GZ_VDEV_KICK_VQ, SMC_SC_NBL_VDEV_KICK_VQ }, [SMCF_NC_VDEV_KICK_VQ] = { SMC_NC_GZ_VDEV_KICK_VQ, SMC_NC_NBL_VDEV_KICK_VQ } }; int init_smcnr_table(struct device *dev, enum tee_id_t tee_id) { int ver = 0; if (!dev || !is_tee_id(tee_id)) { WARN(1, "Error parameters %p, %d\n", dev, tee_id); return -EINVAL; } ver = trusty_fast_call32(dev, SMC_FC_GZ_API_VERSION, TRUSTY_API_VERSION_CURRENT, tee_id, 0); if (ver == SMC_UNDEFINED) ver = 0; if (ver < TRUSTY_API_VERSION_SMCNR_TABLE) { pr_info("GZ SMC version(%u) is not supported for MTEE %d, %s\n", ver, tee_id, "please update"); return -ENODEV; } pr_info("New smcall table ver %d support for MTEE %d\n", ver, tee_id); return ver; } inline uint32_t get_smcnr_teeid(enum smc_functions fid, enum tee_id_t tee_id) { uint32_t smcnr; if (unlikely(fid >= SMCF_END || !is_tee_id(tee_id))) { WARN(1, "ERROR parameters %d, %d\n", fid, tee_id); return SMC_UNDEFINED; } smcnr = gz_smcnr_table[fid][tee_id]; if (unlikely(smcnr == SMC_UNDEFINED)) pr_info("ERROR smcnr retrieving failed %d, %d\n", fid, tee_id); return smcnr; } inline uint32_t get_smcnr_dev(enum smc_functions fid, struct device *dev) { struct trusty_state *s = platform_get_drvdata(to_platform_device(dev)); return get_smcnr_teeid(fid, s->tee_id); } EXPORT_SYMBOL(get_smcnr_dev);