1 /* 2 * Copyright (c) 2023-2024, Arm Limited. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * \file sam_drv.h 19 * \brief Driver for Arm Security Alarm Manager (SAM). 20 */ 21 22 #ifndef __SAM_DRV_H__ 23 #define __SAM_DRV_H__ 24 25 #include <stdbool.h> 26 #include <stddef.h> 27 #include <stdint.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /** 34 * \brief SAM Event IDs. 35 */ 36 enum sam_event_id_t { 37 SAM_EVENT_CONFIG_INTEGRITY_ERROR = 0UL, 38 SAM_EVENT_WATCHDOG_TIMER, 39 SAM_EVENT_DUPLICATION_ERROR, 40 SAM_EVENT_LCM_FATAL_ERROR, 41 SAM_EVENT_CPU_LOCKUP, 42 SAM_EVENT_ATU_ERROR, 43 SAM_EVENT_KMU_PARITY_ERROR, 44 SAM_EVENT_CRYPTO_PARITY_ERROR, 45 SAM_EVENT_SIC_PARITY_ERROR, 46 SAM_EVENT_AES_DFA_ERROR, 47 SAM_EVENT_AES_PARITY_ERROR, 48 SAM_EVENT_DMA_DCLS_ERROR, 49 SAM_EVENT_PSI_PARITY_ERROR, 50 SAM_EVENT_BUS_PARITY_ERROR, 51 SAM_EVENT_PROCESSOR_DCLS_ERROR, 52 SAM_EVENT_PROCESSOR_RAS_SET_0, 53 SAM_EVENT_PROCESSOR_RAS_SET_1, 54 SAM_EVENT_PROCESSOR_RAS_SET_2, 55 SAM_EVENT_SRAM_PARTIAL_WRITE, 56 SAM_EVENT_VM0_SINGLE_ECC_ERROR, 57 SAM_EVENT_VM1_SINGLE_ECC_ERROR, 58 SAM_EVENT_VM2_SINGLE_ECC_ERROR, 59 SAM_EVENT_VM3_SINGLE_ECC_ERROR, 60 SAM_EVENT_VM0_DOUBLE_ECC_ERROR, 61 SAM_EVENT_VM1_DOUBLE_ECC_ERROR, 62 SAM_EVENT_VM2_DOUBLE_ECC_ERROR, 63 SAM_EVENT_VM3_DOUBLE_ECC_ERROR, 64 SAM_EVENT_SRAM_MPC_PARITY_ERROR, 65 SAM_EVENT_SIC_MPC_PARITY_ERROR, 66 SAM_EVENT_ATU_PARITY_ERROR, 67 SAM_EVENT_PPR_PARITY_ERROR, 68 SAM_EVENT_SYSCTRL_PARITY_ERROR, 69 SAM_EVENT_CPU_PPB_PARITY_ERROR, 70 SAM_EVENT_SACFG_PARITY_ERROR, 71 SAM_EVENT_NSACFG_PARITY_ERROR, 72 SAM_EVENT_INTEGRITY_CHECKER_ALARM, 73 SAM_EVENT_TRAM_PARITY_ERROR, 74 /* Reserved 37-47 */ 75 SAM_EVENT_EXTERNAL_SENSOR_0 = 48UL, 76 SAM_EVENT_EXTERNAL_SENSOR_1, 77 SAM_EVENT_EXTERNAL_SENSOR_2, 78 SAM_EVENT_EXTERNAL_SENSOR_3, 79 SAM_EVENT_EXTERNAL_SENSOR_4, 80 SAM_EVENT_EXTERNAL_SENSOR_5, 81 SAM_EVENT_EXTERNAL_SENSOR_6, 82 SAM_EVENT_EXTERNAL_SENSOR_7, 83 SAM_EVENT_EXTERNAL_SENSOR_8, 84 SAM_EVENT_EXTERNAL_SENSOR_9, 85 SAM_EVENT_EXTERNAL_SENSOR_10, 86 SAM_EVENT_EXTERNAL_SENSOR_11, 87 SAM_EVENT_EXTERNAL_SENSOR_12, 88 SAM_EVENT_EXTERNAL_SENSOR_13, 89 SAM_EVENT_EXTERNAL_SENSOR_14, 90 SAM_EVENT_EXTERNAL_SENSOR_15, 91 92 /* Maximum permitted event ID */ 93 SAM_MAX_EVENT_ID = SAM_EVENT_EXTERNAL_SENSOR_15, 94 }; 95 96 /** 97 * \brief SAM response action IDs. 98 */ 99 enum sam_response_t { 100 SAM_RESPONSE_NONE = 0UL, 101 SAM_RESPONSE_COLD_RESET = 1UL, 102 SAM_RESPONSE_WARM_RESET = 1UL << 1, 103 SAM_RESPONSE_NMI = 1UL << 2, 104 SAM_RESPONSE_CRITICAL_FAULT_INTERRUPT = 1UL << 3, 105 SAM_RESPONSE_FAULT_INTERRUPT = 1UL << 4, 106 SAM_RESPONSE_ACTION_5 = 1UL << 5, 107 SAM_RESPONSE_ACTION_6 = 1UL << 6, 108 SAM_RESPONSE_ACTION_7 = 1UL << 7, 109 110 SAM_MAX_RESPONSE_ACTION = SAM_RESPONSE_ACTION_7, 111 }; 112 113 /** 114 * \brief SAM error type. 115 */ 116 enum sam_error_t { 117 SAM_ERROR_NONE = 0, 118 SAM_ERROR_INVALID_ARGUMENT, 119 }; 120 121 /** 122 * \brief SAM event handler function type. 123 */ 124 typedef void (*sam_event_handler_t)(void); 125 126 /* SAM config covers 24 registers: samem to samicv */ 127 #define SAM_CONFIG_LEN 24 128 129 /** 130 * \brief SAM device configuration structure. 131 */ 132 struct sam_dev_cfg_t { 133 const uintptr_t base; /**< SAM base address */ 134 const uint32_t default_config[SAM_CONFIG_LEN]; /**< Default SAM config */ 135 }; 136 137 /** 138 * \brief SAM device structure. 139 */ 140 struct sam_dev_t { 141 const struct sam_dev_cfg_t *const cfg; /**< SAM configuration */ 142 sam_event_handler_t event_handlers[SAM_MAX_EVENT_ID + 1]; /**< SAM event handlers */ 143 }; 144 145 /** 146 * \brief Initialize SAM device. 147 * 148 * \param[in] dev Pointer to SAM device struct. 149 * 150 * \return Error code of enum sam_error_t type. 151 */ 152 enum sam_error_t sam_init(const struct sam_dev_t *dev); 153 154 /** 155 * \brief Enable a SAM event. 156 * 157 * \param[in] dev Pointer to SAM device struct. 158 * \param[in] event_id Event ID to enable. 159 * 160 * \return Error code of enum sam_error_t type. 161 */ 162 enum sam_error_t sam_enable_event(const struct sam_dev_t *dev, 163 enum sam_event_id_t event_id); 164 165 /** 166 * \brief Disable a SAM event. 167 * 168 * \param[in] dev Pointer to SAM device struct. 169 * \param[in] event_id Event ID to disable. 170 * 171 * \return Error code of enum sam_error_t type. 172 */ 173 enum sam_error_t sam_disable_event(const struct sam_dev_t *dev, 174 enum sam_event_id_t event_id); 175 176 /** 177 * \brief Set the response action for a SAM event. 178 * 179 * \param[in] dev Pointer to SAM device struct. 180 * \param[in] event_id Event ID for which to set response. 181 * \param[in] response Response action to set. 182 * \param[in] enable_response Enable or disable the response. 183 * 184 * \return Error code of enum sam_error_t type. 185 */ 186 enum sam_error_t sam_set_event_response(const struct sam_dev_t *dev, 187 enum sam_event_id_t event_id, 188 enum sam_response_t response, 189 bool enable_response); 190 191 /** 192 * \brief Set the SAM watchdog counter initial value. 193 * 194 * \param[in] dev Pointer to SAM device struct. 195 * \param[in] count_value Number of cycles to count after a SAM event before 196 * asserting the watchdog event: 197 * 0: watchdog count down disabled, 198 * 1 to (2^26)-1: valid initial count values. 199 * \param[in] responses Bitwise OR of response actions that trigger the 200 * watchdog counter. SAM_RESPONSE_COLD_RESET and 201 * SAM_RESPONSE_WARM_RESET are ignored. 202 */ 203 void sam_set_watchdog_counter_initial_value(const struct sam_dev_t *dev, 204 uint32_t count_value, 205 enum sam_response_t responses); 206 207 /** 208 * \brief Register a handler function for a SAM event. 209 * 210 * \param[in] dev Pointer to SAM device struct. 211 * \param[in] event_id Event ID to handle. 212 * \param[in] event_handler Pointer to event handler function. 213 * 214 * \return Error code of enum sam_error_t type. 215 */ 216 enum sam_error_t sam_register_event_handler(struct sam_dev_t *dev, 217 enum sam_event_id_t event_id, 218 sam_event_handler_t event_handler); 219 220 /** 221 * \brief Handle any outstanding SAM events by calling the corresponding 222 * registered event handler functions. 223 * 224 * \note This function is intended to be called from an interrupt handler. 225 * 226 * \param[in] dev Pointer to SAM device struct. 227 */ 228 void sam_handle_event(const struct sam_dev_t *dev); 229 230 /** 231 * \brief Handle an SRAM partial write event. 232 * 233 * \note This function is intended to be called from an interrupt handler. 234 * 235 * \param[in] dev Pointer to SAM device struct. 236 */ 237 void sam_handle_partial_write(const struct sam_dev_t *dev); 238 239 /** 240 * \brief Handle an SRAM single ECC error event. 241 * 242 * \note This function is intended to be called from an interrupt handler. 243 * 244 * \param[in] dev Pointer to SAM device struct. 245 */ 246 void sam_handle_single_ecc_error(const struct sam_dev_t *dev); 247 248 #ifdef __cplusplus 249 } 250 #endif 251 252 #endif /* __SAM_DRV_H__ */ 253