1*14c0df4eSMarouene Boubakri // SPDX-License-Identifier: BSD-2-Clause 2*14c0df4eSMarouene Boubakri /* 3*14c0df4eSMarouene Boubakri * Copyright (c) 2016-2020, Linaro Limited 4*14c0df4eSMarouene Boubakri * Copyright (c) 2014, STMicroelectronics International N.V. 5*14c0df4eSMarouene Boubakri */ 6*14c0df4eSMarouene Boubakri 7*14c0df4eSMarouene Boubakri #include <compiler.h> 8*14c0df4eSMarouene Boubakri #include <initcall.h> 9*14c0df4eSMarouene Boubakri #include <kernel/tee_time.h> 10*14c0df4eSMarouene Boubakri #include <kernel/thread.h> 11*14c0df4eSMarouene Boubakri #include <kernel/time_source.h> 12*14c0df4eSMarouene Boubakri #include <mm/core_mmu.h> 13*14c0df4eSMarouene Boubakri #include <optee_rpc_cmd.h> 14*14c0df4eSMarouene Boubakri #include <stdlib.h> 15*14c0df4eSMarouene Boubakri #include <string.h> 16*14c0df4eSMarouene Boubakri 17*14c0df4eSMarouene Boubakri struct time_source _time_source; 18*14c0df4eSMarouene Boubakri 19*14c0df4eSMarouene Boubakri static TEE_Result register_time_source(void) 20*14c0df4eSMarouene Boubakri { 21*14c0df4eSMarouene Boubakri time_source_init(); 22*14c0df4eSMarouene Boubakri 23*14c0df4eSMarouene Boubakri return TEE_SUCCESS; 24*14c0df4eSMarouene Boubakri } 25*14c0df4eSMarouene Boubakri early_init(register_time_source); 26*14c0df4eSMarouene Boubakri 27*14c0df4eSMarouene Boubakri TEE_Result tee_time_get_sys_time(TEE_Time *time) 28*14c0df4eSMarouene Boubakri { 29*14c0df4eSMarouene Boubakri return _time_source.get_sys_time(time); 30*14c0df4eSMarouene Boubakri } 31*14c0df4eSMarouene Boubakri 32*14c0df4eSMarouene Boubakri uint32_t tee_time_get_sys_time_protection_level(void) 33*14c0df4eSMarouene Boubakri { 34*14c0df4eSMarouene Boubakri return _time_source.protection_level; 35*14c0df4eSMarouene Boubakri } 36*14c0df4eSMarouene Boubakri 37*14c0df4eSMarouene Boubakri void tee_time_wait(uint32_t milliseconds_delay) 38*14c0df4eSMarouene Boubakri { 39*14c0df4eSMarouene Boubakri struct thread_param params = 40*14c0df4eSMarouene Boubakri THREAD_PARAM_VALUE(IN, milliseconds_delay, 0, 0); 41*14c0df4eSMarouene Boubakri 42*14c0df4eSMarouene Boubakri thread_rpc_cmd(OPTEE_RPC_CMD_SUSPEND, 1, ¶ms); 43*14c0df4eSMarouene Boubakri } 44*14c0df4eSMarouene Boubakri 45*14c0df4eSMarouene Boubakri /* 46*14c0df4eSMarouene Boubakri * tee_time_get_ree_time(): this function implements the GP Internal API 47*14c0df4eSMarouene Boubakri * function TEE_GetREETime() 48*14c0df4eSMarouene Boubakri * Goal is to get the time of the Rich Execution Environment 49*14c0df4eSMarouene Boubakri * This is why this time is provided through the supplicant 50*14c0df4eSMarouene Boubakri */ 51*14c0df4eSMarouene Boubakri TEE_Result tee_time_get_ree_time(TEE_Time *time) 52*14c0df4eSMarouene Boubakri { 53*14c0df4eSMarouene Boubakri struct thread_param params = THREAD_PARAM_VALUE(OUT, 0, 0, 0); 54*14c0df4eSMarouene Boubakri TEE_Result res = TEE_SUCCESS; 55*14c0df4eSMarouene Boubakri 56*14c0df4eSMarouene Boubakri if (!time) 57*14c0df4eSMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 58*14c0df4eSMarouene Boubakri 59*14c0df4eSMarouene Boubakri res = thread_rpc_cmd(OPTEE_RPC_CMD_GET_TIME, 1, ¶ms); 60*14c0df4eSMarouene Boubakri if (res == TEE_SUCCESS) { 61*14c0df4eSMarouene Boubakri time->seconds = params.u.value.a; 62*14c0df4eSMarouene Boubakri time->millis = params.u.value.b / 1000000; 63*14c0df4eSMarouene Boubakri } 64*14c0df4eSMarouene Boubakri 65*14c0df4eSMarouene Boubakri return res; 66*14c0df4eSMarouene Boubakri } 67