1 /* 2 * Copyright (c) 2018-2023, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef __TFM_PLAT_NV_COUNTERS_H__ 9 #define __TFM_PLAT_NV_COUNTERS_H__ 10 11 /** 12 * \file tfm_plat_nv_counters.h 13 * 14 * \note The interfaces defined in this file must be implemented for each 15 * SoC. 16 * \note The interface must be implemented in a fail-safe way that is 17 * resistant to asynchronous power failures or it can use hardware 18 * counters that have this capability, if supported by the platform. 19 * When a counter incrementation was interrupted it must be able to 20 * continue the incrementation process or recover the previous consistent 21 * status of the counters. If the counters have reached a stable status 22 * (every counter incrementation operation has finished), from that point 23 * their value cannot decrease due to any kind of power failure. 24 */ 25 26 #include <stdint.h> 27 #include "tfm_plat_defs.h" 28 29 #ifndef PLATFORM_NS_NV_COUNTERS 30 #define PLATFORM_NS_NV_COUNTERS 0 31 #endif 32 33 #ifdef PLATFORM_DEFAULT_NV_COUNTERS 34 enum tfm_nv_counter_t { 35 PLAT_NV_COUNTER_PS_0 = 0, /* Used by PS service */ 36 PLAT_NV_COUNTER_PS_1, /* Used by PS service */ 37 PLAT_NV_COUNTER_PS_2, /* Used by PS service */ 38 39 /* BL2 NV counters must be contiguous */ 40 PLAT_NV_COUNTER_BL2_0, /* Used by bootloader */ 41 PLAT_NV_COUNTER_BL2_1, /* Used by bootloader */ 42 PLAT_NV_COUNTER_BL2_2, /* Used by bootloader */ 43 PLAT_NV_COUNTER_BL2_3, /* Used by bootloader */ 44 45 PLAT_NV_COUNTER_BL1_0, /* Used by bootloader */ 46 47 /* NS counters must be contiguous */ 48 PLAT_NV_COUNTER_NS_0, /* Used by NS */ 49 PLAT_NV_COUNTER_NS_1, /* Used by NS */ 50 PLAT_NV_COUNTER_NS_2, /* Used by NS */ 51 52 PLAT_NV_COUNTER_MAX, 53 PLAT_NV_COUNTER_BOUNDARY = UINT32_MAX /* Fix tfm_nv_counter_t size 54 to 4 bytes */ 55 }; 56 #else 57 #include "platform_nv_counters_ids.h" 58 #endif 59 60 #ifdef __cplusplus 61 extern "C" { 62 #endif 63 64 /** 65 * \brief Initialises all non-volatile (NV) counters. 66 * 67 * \return TFM_PLAT_ERR_SUCCESS if the initialization succeeds, otherwise 68 * TFM_PLAT_ERR_SYSTEM_ERR 69 */ 70 enum tfm_plat_err_t tfm_plat_init_nv_counter(void); 71 72 /** 73 * \brief Reads the given non-volatile (NV) counter. 74 * 75 * \param[in] counter_id NV counter ID. 76 * \param[in] size Size of the buffer to store NV counter value 77 * in bytes. 78 * \param[out] val Pointer to store the current NV counter value. 79 * 80 * \return TFM_PLAT_ERR_SUCCESS if the value is read correctly. Otherwise, 81 * it returns TFM_PLAT_ERR_SYSTEM_ERR. 82 */ 83 enum tfm_plat_err_t tfm_plat_read_nv_counter(enum tfm_nv_counter_t counter_id, 84 uint32_t size, uint8_t *val); 85 86 /** 87 * \brief Increments the given non-volatile (NV) counter. 88 * 89 * \param[in] counter_id NV counter ID. 90 * 91 * \return When the NV counter reaches its maximum value, the 92 * TFM_PLAT_ERR_MAX_VALUE error is returned to indicate the value 93 * cannot be incremented. Otherwise, it returns TFM_PLAT_ERR_SUCCESS. 94 */ 95 enum tfm_plat_err_t tfm_plat_increment_nv_counter( 96 enum tfm_nv_counter_t counter_id); 97 98 /** 99 * \brief Sets the given non-volatile (NV) counter to the specified value. 100 * 101 * \param[in] counter_id NV counter ID. 102 * \param[in] value New value of the NV counter. The maximum value that 103 * can be set depends on the constraints of the 104 * underlying implementation, but it always must be 105 * greater than or equal to the current NV counter value. 106 * 107 * \retval TFM_PLAT_ERR_SUCCESS The NV counter is set successfully 108 * \retval TFM_PLAT_ERR_INVALID_INPUT The new value is less than the current 109 * counter value 110 * \retval TFM_PLAT_ERR_MAX_VALUE The new value is greater than the 111 * maximum value of the NV counter 112 * \retval TFM_PLAT_ERR_UNSUPPORTED The function is not implemented for 113 * the given platform or the new value is 114 * not representable on the underlying 115 * counter implementation 116 * \retval TFM_PLAT_ERR_SYSTEM_ERR An unspecified error occurred 117 * (none of the other standard error codes 118 * are applicable) 119 */ 120 enum tfm_plat_err_t tfm_plat_set_nv_counter(enum tfm_nv_counter_t counter_id, 121 uint32_t value); 122 123 #ifdef __cplusplus 124 } 125 #endif 126 127 #endif /* __TFM_PLAT_NV_COUNTERS_H__ */ 128