// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2019, Broadcom */ #include #include #include #include #include #include #include #define SEC_WD_SERVICE_UUID \ { 0x6272636D, 0x2019, 0x0801, \ { 0x42, 0x43, 0x4D, 0x5F, 0x57, 0x44, 0x54, 0x30 } } #define PTA_BCM_SEC_WD_CMD_CONFIG 0 #define PTA_BCM_SEC_WD_CMD_START 1 #define PTA_BCM_SEC_WD_CMD_PING 2 #define PTA_BCM_SEC_WD_CMD_STOP 3 #define PTA_BCM_SEC_WD_CMD_SET_TIMEOUT 4 #define SEC_WD_TA_NAME "pta_bcm_sec_wd.ta" static struct sp805_wdt_data wd_pd; static void wd_isr_handler(struct wdt_chip *chip __unused) { /* Do nothing */ DMSG("Watchdog ISR handler !!!"); } static TEE_Result pta_wd_config(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { uint32_t timeout = 0; uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_param_types != param_types) { EMSG("Invalid Param types"); return TEE_ERROR_BAD_PARAMETERS; } timeout = params[0].value.a; sp805_wdt_init(&wd_pd, SEC_WDT_BASE, SEC_WDT_CLK_HZ, timeout); sp805_register_itr_handler(&wd_pd, GIC_SPI(SEC_WDT_INTR), ITRF_TRIGGER_LEVEL, wd_isr_handler); wd_pd.chip.ops->start(&wd_pd.chip); return TEE_SUCCESS; } static TEE_Result pta_wd_start(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS] __unused) { uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_param_types != param_types) { EMSG("Invalid Param types"); return TEE_ERROR_BAD_PARAMETERS; } wd_pd.chip.ops->start(&wd_pd.chip); return TEE_SUCCESS; } static TEE_Result pta_wd_ping(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS] __unused) { uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_param_types != param_types) { EMSG("Invalid Param types"); return TEE_ERROR_BAD_PARAMETERS; } wd_pd.chip.ops->ping(&wd_pd.chip); return TEE_SUCCESS; } static TEE_Result pta_wd_stop(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS] __unused) { uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_param_types != param_types) { EMSG("Invalid Param types"); return TEE_ERROR_BAD_PARAMETERS; } wd_pd.chip.ops->stop(&wd_pd.chip); return TEE_SUCCESS; } static TEE_Result pta_wd_set_timeout(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { uint32_t timeout = 0; uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_param_types != param_types) { EMSG("Invalid Param types"); return TEE_ERROR_BAD_PARAMETERS; } timeout = params[0].value.a; wd_pd.chip.ops->set_timeout(&wd_pd.chip, timeout); return TEE_SUCCESS; } static TEE_Result invoke_command(void *session_context __unused, uint32_t cmd_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { TEE_Result res = TEE_SUCCESS; DMSG("command entry point[%d] for \"%s\"", cmd_id, SEC_WD_TA_NAME); switch (cmd_id) { case PTA_BCM_SEC_WD_CMD_CONFIG: res = pta_wd_config(param_types, params); break; case PTA_BCM_SEC_WD_CMD_START: res = pta_wd_start(param_types, params); break; case PTA_BCM_SEC_WD_CMD_PING: res = pta_wd_ping(param_types, params); break; case PTA_BCM_SEC_WD_CMD_STOP: res = pta_wd_stop(param_types, params); break; case PTA_BCM_SEC_WD_CMD_SET_TIMEOUT: res = pta_wd_set_timeout(param_types, params); break; default: EMSG("cmd: %d Not supported %s", cmd_id, SEC_WD_TA_NAME); res = TEE_ERROR_NOT_SUPPORTED; break; } return res; } pseudo_ta_register(.uuid = SEC_WD_SERVICE_UUID, .name = SEC_WD_TA_NAME, .flags = PTA_DEFAULT_FLAGS, .invoke_command_entry_point = invoke_command);