1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, Broadcom 4 */ 5 6 #include <drivers/gic.h> 7 #include <drivers/sp805_wdt.h> 8 #include <io.h> 9 #include <kernel/interrupt.h> 10 #include <kernel/misc.h> 11 #include <kernel/pseudo_ta.h> 12 #include <trace.h> 13 14 #define SEC_WD_SERVICE_UUID \ 15 { 0x6272636D, 0x2019, 0x0801, \ 16 { 0x42, 0x43, 0x4D, 0x5F, 0x57, 0x44, 0x54, 0x30 } } 17 18 #define PTA_BCM_SEC_WD_CMD_CONFIG 0 19 #define PTA_BCM_SEC_WD_CMD_START 1 20 #define PTA_BCM_SEC_WD_CMD_PING 2 21 #define PTA_BCM_SEC_WD_CMD_STOP 3 22 #define PTA_BCM_SEC_WD_CMD_SET_TIMEOUT 4 23 24 #define SEC_WD_TA_NAME "pta_bcm_sec_wd.ta" 25 26 static struct sp805_wdt_data wd_pd; 27 28 static void wd_isr_handler(struct wdt_chip *chip __unused) 29 { 30 /* Do nothing */ 31 DMSG("Watchdog ISR handler !!!"); 32 } 33 34 static TEE_Result pta_wd_config(uint32_t param_types, 35 TEE_Param params[TEE_NUM_PARAMS]) 36 { 37 uint32_t timeout = 0; 38 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 39 TEE_PARAM_TYPE_NONE, 40 TEE_PARAM_TYPE_NONE, 41 TEE_PARAM_TYPE_NONE); 42 43 if (exp_param_types != param_types) { 44 EMSG("Invalid Param types"); 45 return TEE_ERROR_BAD_PARAMETERS; 46 } 47 48 timeout = params[0].value.a; 49 50 sp805_wdt_init(&wd_pd, SEC_WDT_BASE, SEC_WDT_CLK_HZ, timeout); 51 52 sp805_register_itr_handler(&wd_pd, GIC_SPI_TO_ITNUM(SEC_WDT_INTR), 53 ITRF_TRIGGER_LEVEL, wd_isr_handler); 54 wd_pd.chip.ops->start(&wd_pd.chip); 55 56 return TEE_SUCCESS; 57 } 58 59 static TEE_Result pta_wd_start(uint32_t param_types, 60 TEE_Param params[TEE_NUM_PARAMS] __unused) 61 { 62 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, 63 TEE_PARAM_TYPE_NONE, 64 TEE_PARAM_TYPE_NONE, 65 TEE_PARAM_TYPE_NONE); 66 67 if (exp_param_types != param_types) { 68 EMSG("Invalid Param types"); 69 return TEE_ERROR_BAD_PARAMETERS; 70 } 71 72 wd_pd.chip.ops->start(&wd_pd.chip); 73 74 return TEE_SUCCESS; 75 } 76 77 static TEE_Result pta_wd_ping(uint32_t param_types, 78 TEE_Param params[TEE_NUM_PARAMS] __unused) 79 { 80 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, 81 TEE_PARAM_TYPE_NONE, 82 TEE_PARAM_TYPE_NONE, 83 TEE_PARAM_TYPE_NONE); 84 85 if (exp_param_types != param_types) { 86 EMSG("Invalid Param types"); 87 return TEE_ERROR_BAD_PARAMETERS; 88 } 89 90 wd_pd.chip.ops->ping(&wd_pd.chip); 91 92 return TEE_SUCCESS; 93 } 94 95 static TEE_Result pta_wd_stop(uint32_t param_types, 96 TEE_Param params[TEE_NUM_PARAMS] __unused) 97 { 98 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, 99 TEE_PARAM_TYPE_NONE, 100 TEE_PARAM_TYPE_NONE, 101 TEE_PARAM_TYPE_NONE); 102 103 if (exp_param_types != param_types) { 104 EMSG("Invalid Param types"); 105 return TEE_ERROR_BAD_PARAMETERS; 106 } 107 108 wd_pd.chip.ops->stop(&wd_pd.chip); 109 110 return TEE_SUCCESS; 111 } 112 113 static TEE_Result pta_wd_set_timeout(uint32_t param_types, 114 TEE_Param params[TEE_NUM_PARAMS]) 115 { 116 uint32_t timeout = 0; 117 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 118 TEE_PARAM_TYPE_NONE, 119 TEE_PARAM_TYPE_NONE, 120 TEE_PARAM_TYPE_NONE); 121 122 if (exp_param_types != param_types) { 123 EMSG("Invalid Param types"); 124 return TEE_ERROR_BAD_PARAMETERS; 125 } 126 127 timeout = params[0].value.a; 128 129 wd_pd.chip.ops->set_timeout(&wd_pd.chip, timeout); 130 131 return TEE_SUCCESS; 132 } 133 134 static TEE_Result invoke_command(void *session_context __unused, 135 uint32_t cmd_id, 136 uint32_t param_types, 137 TEE_Param params[TEE_NUM_PARAMS]) 138 { 139 TEE_Result res = TEE_SUCCESS; 140 141 DMSG("command entry point[%d] for \"%s\"", cmd_id, SEC_WD_TA_NAME); 142 143 switch (cmd_id) { 144 case PTA_BCM_SEC_WD_CMD_CONFIG: 145 res = pta_wd_config(param_types, params); 146 break; 147 case PTA_BCM_SEC_WD_CMD_START: 148 res = pta_wd_start(param_types, params); 149 break; 150 case PTA_BCM_SEC_WD_CMD_PING: 151 res = pta_wd_ping(param_types, params); 152 break; 153 case PTA_BCM_SEC_WD_CMD_STOP: 154 res = pta_wd_stop(param_types, params); 155 break; 156 case PTA_BCM_SEC_WD_CMD_SET_TIMEOUT: 157 res = pta_wd_set_timeout(param_types, params); 158 break; 159 default: 160 EMSG("cmd: %d Not supported %s", cmd_id, SEC_WD_TA_NAME); 161 res = TEE_ERROR_NOT_SUPPORTED; 162 break; 163 } 164 165 return res; 166 } 167 168 pseudo_ta_register(.uuid = SEC_WD_SERVICE_UUID, 169 .name = SEC_WD_TA_NAME, 170 .flags = PTA_DEFAULT_FLAGS, 171 .invoke_command_entry_point = invoke_command); 172