1 /* 2 * Copyright (c) 2022, 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 lcm_drv.h 19 * \brief Driver for Arm LCM. 20 */ 21 22 #ifndef __LCM_DRV_H__ 23 #define __LCM_DRV_H__ 24 25 #include <stdint.h> 26 #include <stdbool.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #define LCM_DCU_WIDTH_IN_BYTES (16) 33 34 struct lcm_otp_layout_t { 35 volatile uint32_t huk[8]; 36 volatile uint32_t guk[8]; 37 volatile uint32_t kp_cm[8]; 38 volatile uint32_t kce_cm[8]; 39 volatile uint32_t kp_dm[8]; 40 volatile uint32_t kce_dm[8]; 41 volatile uint32_t rotpk[8]; 42 volatile uint32_t tp_mode_config; 43 volatile uint32_t cm_config_1; 44 volatile uint32_t cm_config_2; 45 volatile uint32_t dm_config; 46 volatile uint32_t cm_rma_flag; 47 volatile uint32_t dm_rma_flag; 48 volatile uint32_t user_data[]; 49 }; 50 51 /** 52 * \brief ARM LCM LCS enumeration types 53 * 54 * \note These high hamming-weight constants are required by the hardware. 55 */ 56 enum lcm_lcs_t { 57 LCM_LCS_CM = (0xCCCC3C3Cu), 58 LCM_LCS_DM = (0xDDDD5A5Au), 59 LCM_LCS_SE = (0xEEEEA5A5u), 60 LCM_LCS_RMA = (0xFFFFC3C3u), 61 LCM_LCS_INVALID = (0xDEADBEEFu), 62 }; 63 64 /** 65 * \brief ARM LCM TP mode enumeration types 66 * 67 * \note These high hamming-weight constants are required by the hardware. 68 */ 69 enum lcm_tp_mode_t { 70 LCM_TP_MODE_VIRGIN = (0x000033CCu), 71 LCM_TP_MODE_TCI = (0x111155AAu), 72 LCM_TP_MODE_PCI = (0x2222AA55u), 73 LCM_TP_MODE_INVALID = (0xDEADBEEFu), 74 }; 75 76 /** 77 * \brief ARM LCM SP mode enumeration types 78 * 79 * \note These high hamming-weight constants are required by the hardware. 80 */ 81 enum lcm_bool_t { 82 LCM_FALSE = (0x00000000u), 83 LCM_TRUE = (0xFFFFFFFFu), 84 }; 85 86 /** 87 * \brief ARM LCM error enumeration types 88 */ 89 enum lcm_error_t { 90 LCM_ERROR_NONE = (0x0u), 91 LCM_ERROR_INVALID_KEY, 92 LCM_ERROR_INVALID_ALIGNMENT, 93 LCM_ERROR_INVALID_LENGTH, 94 LCM_ERROR_INVALID_OFFSET, 95 LCM_ERROR_INVALID_WRITE, 96 LCM_ERROR_INVALID_TRANSITION, 97 LCM_ERROR_INVALID_LCS, 98 LCM_ERROR_INVALID_TP_MODE, 99 LCM_ERROR_INVALID_POINTER, 100 LCM_ERROR_INTERNAL_ERROR, 101 LCM_ERROR_WRITE_VERIFY_FAIL, 102 LCM_ERROR_FATAL_ERR, 103 }; 104 105 /** 106 * \brief ARM LCM device configuration structure 107 */ 108 struct lcm_dev_cfg_t { 109 const uint32_t base; /*!< LCM base address */ 110 }; 111 112 /** 113 * \brief ARM LCM device structure 114 */ 115 struct lcm_dev_t { 116 const struct lcm_dev_cfg_t* const cfg; /*!< LCM configuration */ 117 }; 118 119 120 /** 121 * \brief This function initializes the LCM 122 * 123 * \param[in] dev The LCM device structure. 124 * 125 * \return Returns error code as specified in \ref lcm_error_t 126 */ 127 enum lcm_error_t lcm_init(struct lcm_dev_t *dev); 128 129 /** 130 * \brief This function gets the TP mode 131 * 132 * \param[in] dev The LCM device structure. 133 * \param[out] mode The TP mode the device is currently in. 134 * 135 * \return Returns error code as specified in \ref lcm_error_t 136 */ 137 enum lcm_error_t lcm_get_tp_mode(struct lcm_dev_t *dev, enum lcm_tp_mode_t *mode); 138 /** 139 * \brief This function sets the TP mode 140 * 141 * \param[in] dev The LCM device structure. 142 * \param[in] mode The TP mode to transition the device to. 143 * 144 * \return Returns error code as specified in \ref lcm_error_t 145 */ 146 enum lcm_error_t lcm_set_tp_mode(struct lcm_dev_t *dev, enum lcm_tp_mode_t mode); 147 148 /** 149 * \brief This function checks if secure provisioning mode is enabled 150 * 151 * \param[in] dev The LCM device structure. 152 * \param[out] enabled Whether secure provisioning mode is enabled. 153 * 154 * \return Returns error code as specified in \ref lcm_error_t 155 */ 156 enum lcm_error_t lcm_get_sp_enabled(struct lcm_dev_t *dev, enum lcm_bool_t *enabled); 157 /** 158 * \brief This function enables secure provisioning mode. 159 * 160 * \param[in] dev The LCM device structure. 161 * 162 * \note This function may cause some or all device components to be reset, and 163 * may begin executing code from the reset vector. 164 * 165 * \return Returns error code as specified in \ref lcm_error_t 166 */ 167 enum lcm_error_t lcm_set_sp_enabled(struct lcm_dev_t *dev); 168 169 /** 170 * \brief This function checks if fatal error mode is enabled 171 * 172 * \param[in] dev The LCM device structure. 173 * \param[out] error Whether fatal error mode is enabled. 174 * 175 * \return Returns error code as specified in \ref lcm_error_t 176 */ 177 enum lcm_error_t lcm_get_fatal_error(struct lcm_dev_t *dev, enum lcm_bool_t *error); 178 /** 179 * \brief This function enables fatal error mode. 180 * 181 * \param[in] dev The LCM device structure. 182 * 183 * \note This function will cause the LCM to be inoperable until the device is 184 * reset. 185 * 186 * \return Returns error code as specified in \ref lcm_error_t 187 */ 188 enum lcm_error_t lcm_set_fatal_error(struct lcm_dev_t *dev); 189 190 /** 191 * \brief This function gets the General purpose persistent configuration. 192 * 193 * \param[in] dev The LCM device structure. 194 * \param[out] gppc The value of the gppc. 195 * 196 * \return Returns error code as specified in \ref lcm_error_t 197 */ 198 enum lcm_error_t lcm_get_gppc(struct lcm_dev_t *dev, uint32_t *gppc); 199 200 /** 201 * \brief This function gets the size of the OTP managed by the LCM. 202 * 203 * \param[in] dev The LCM device structure. 204 * \param[out] size The size (in bytes) of the OTP. 205 * 206 * \return Returns error code as specified in \ref lcm_error_t 207 */ 208 enum lcm_error_t lcm_get_otp_size(struct lcm_dev_t *dev, uint32_t *size); 209 210 /** 211 * \brief This function gets Lifecycle State the LCM is currently in. 212 * 213 * \param[in] dev The LCM device structure. 214 * \param[out] lcs The LCS the device is currently in. 215 * 216 * \return Returns error code as specified in \ref lcm_error_t 217 */ 218 enum lcm_error_t lcm_get_lcs(struct lcm_dev_t *dev, enum lcm_lcs_t *lcs); 219 /** 220 * \brief This function gets Lifecycle State the LCM is currently in. 221 * 222 * \param[in] dev The LCM device structure. 223 * \param[in] lcs The LCS to transition to. 224 * \param[in] gppc_val The value that the General Purpose Persistent 225 * Configuration should be set to. Mandatory when lcs 226 * parameter == LCM_LCS_DM, unused otherwise. 227 * 228 * \note Some LCS transitions are illegal 229 * \note A cold system reset is required after this function returns for the new 230 * LCS to be entered. 231 * 232 * \return Returns error code as specified in \ref lcm_error_t 233 */ 234 enum lcm_error_t lcm_set_lcs(struct lcm_dev_t *dev, enum lcm_lcs_t lcs, 235 uint16_t gppc_val); 236 237 /** 238 * \brief This function writes the OTP managed by the LCM. 239 * 240 * \param[in] dev The LCM device structure. 241 * \param[in] offset The offset into the OTP to write. Must be 4 byte aligned 242 * \param[in] len The length of the OTP region to write. Must be 4 byte 243 * aligned. 244 * \param[in] buf The buffer containing the data to write into OTP. Must 245 * be 4 byte aligned and of a multiple of 4 bytes in length 246 * 247 * \note This function does not allow writes into OTP words that have already 248 * been written. 249 * 250 * \return Returns error code as specified in \ref lcm_error_t 251 */ 252 enum lcm_error_t lcm_otp_write(struct lcm_dev_t *dev, uint32_t offset, uint32_t len, 253 const uint8_t *buf); 254 255 /** 256 * \brief This function reads the OTP managed by the LCM. 257 * 258 * \param[in] dev The LCM device structure. 259 * \param[in] offset The offset into the OTP to write. Must be 4 byte aligned 260 * \param[in] len The length of the OTP region to write. Must be 4 byte 261 * aligned. 262 * \param[out] buf The buffer that will be filled with the OTP content. 263 * Must be 4 byte aligned and of a multiple of 4 bytes in 264 * length. 265 * 266 * \return Returns error code as specified in \ref lcm_error_t 267 */ 268 enum lcm_error_t lcm_otp_read(struct lcm_dev_t *dev, uint32_t offset, uint32_t len, 269 uint8_t *buf); 270 271 /** 272 * \brief This function gets the state of the Debug Control Unit. 273 * 274 * \param[in] dev The LCM device structure. 275 * \param[out] val The buffer into which to write the value of the DCU. Must 276 * be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned. 277 * 278 * \return Returns error code as specified in \ref lcm_error_t 279 */ 280 enum lcm_error_t lcm_dcu_get_enabled(struct lcm_dev_t *dev, uint8_t *val); 281 /** 282 * \brief This function sets the state of the Debug Control Unit. 283 * 284 * \param[in] dev The LCM device structure. 285 * \param[in] val The buffer whose value the DCU will be set to. Must 286 * be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned. 287 * 288 * \return Returns error code as specified in \ref lcm_error_t 289 */ 290 enum lcm_error_t lcm_dcu_set_enabled(struct lcm_dev_t *dev, uint8_t *val); 291 292 /** 293 * \brief This function gets the state of the Debug Control Unit Lock. 294 * 295 * \param[in] dev The LCM device structure. 296 * \param[out] val The buffer into which to write the value of the DCU Lock. 297 * Must be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned 298 * 299 * \return Returns error code as specified in \ref lcm_error_t 300 */ 301 enum lcm_error_t lcm_dcu_get_locked(struct lcm_dev_t *dev, uint8_t *val); 302 /** 303 * \brief This function sets the state of the Debug Control Unit Lock. 304 * 305 * \param[in] dev The LCM device structure. 306 * \param[in] val The buffer whose value the DCU lock will be set to. Must 307 * be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned. 308 * 309 * \return Returns error code as specified in \ref lcm_error_t 310 */ 311 enum lcm_error_t lcm_dcu_set_locked(struct lcm_dev_t *dev, uint8_t *val); 312 313 /** 314 * \brief This function gets the state of the Debug Control Unit Secure 315 * Provisioning Disable Mask. This mask controls which DCU bits cannot be 316 * enabled in secure provisioning mode. This mask is set in hardware. 317 * 318 * \param[in] dev The LCM device structure. 319 * \param[out] val The buffer into which to write the value of the DCU Lock. 320 * Must be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned 321 * 322 * \return Returns error code as specified in \ref lcm_error_t 323 */ 324 enum lcm_error_t lcm_dcu_get_sp_disable_mask(struct lcm_dev_t *dev, uint8_t *val); 325 /** 326 * \brief This function gets the state of the Debug Control Unit Disable Mask. 327 * This mask controls which DCU bits cannot be enabled. This mask is set 328 * in hardware 329 * 330 * \param[in] dev The LCM device structure. 331 * \param[out] val The buffer into which to write the value of the DCU Lock. 332 * Must be LCM_DCU_WIDTH_IN_BYTES in size, and 4 byte aligned 333 * 334 * \return Returns error code as specified in \ref lcm_error_t 335 */ 336 enum lcm_error_t lcm_dcu_get_disable_mask(struct lcm_dev_t *dev, uint8_t *val); 337 338 #ifdef __cplusplus 339 } 340 #endif 341 #endif /* __LCM_DRV_H__ */ 342