1 /*
2  * Copyright (c) 2018-2022, 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 enum tfm_nv_counter_t {
34     PLAT_NV_COUNTER_PS_0 = 0,  /* Used by PS service */
35     PLAT_NV_COUNTER_PS_1,      /* Used by PS service */
36     PLAT_NV_COUNTER_PS_2,      /* Used by PS service */
37 
38     PLAT_NV_COUNTER_BL2_0,     /* Used by bootloader */
39     PLAT_NV_COUNTER_BL2_1,     /* Used by bootloader */
40     PLAT_NV_COUNTER_BL2_2,     /* Used by bootloader */
41     PLAT_NV_COUNTER_BL2_3,     /* Used by bootloader */
42 
43     PLAT_NV_COUNTER_BL1_0,     /* Used by bootloader */
44 
45     /* NS counters must be contiguous */
46     PLAT_NV_COUNTER_NS_0,      /* Used by NS */
47     PLAT_NV_COUNTER_NS_1,      /* Used by NS */
48     PLAT_NV_COUNTER_NS_2,      /* Used by NS */
49 
50     PLAT_NV_COUNTER_MAX,
51     PLAT_NV_COUNTER_BOUNDARY = UINT32_MAX  /* Fix  tfm_nv_counter_t size
52                                               to 4 bytes */
53 };
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /**
60  * \brief Initialises all non-volatile (NV) counters.
61  *
62  * \return  TFM_PLAT_ERR_SUCCESS if the initialization succeeds, otherwise
63  *          TFM_PLAT_ERR_SYSTEM_ERR
64  */
65 enum tfm_plat_err_t tfm_plat_init_nv_counter(void);
66 
67 /**
68  * \brief Reads the given non-volatile (NV) counter.
69  *
70  * \param[in]  counter_id  NV counter ID.
71  * \param[in]  size        Size of the buffer to store NV counter value
72  *                         in bytes.
73  * \param[out] val         Pointer to store the current NV counter value.
74  *
75  * \return  TFM_PLAT_ERR_SUCCESS if the value is read correctly. Otherwise,
76  *          it returns TFM_PLAT_ERR_SYSTEM_ERR.
77  */
78 enum tfm_plat_err_t tfm_plat_read_nv_counter(enum tfm_nv_counter_t counter_id,
79                                              uint32_t size, uint8_t *val);
80 
81 /**
82  * \brief Increments the given non-volatile (NV) counter.
83  *
84  * \param[in] counter_id  NV counter ID.
85  *
86  * \return  When the NV counter reaches its maximum value, the
87  *          TFM_PLAT_ERR_MAX_VALUE error is returned to indicate the value
88  *          cannot be incremented. Otherwise, it returns TFM_PLAT_ERR_SUCCESS.
89  */
90 enum tfm_plat_err_t tfm_plat_increment_nv_counter(
91                                               enum tfm_nv_counter_t counter_id);
92 
93 /**
94  * \brief Sets the given non-volatile (NV) counter to the specified value.
95  *
96  * \param[in] counter_id  NV counter ID.
97  * \param[in] value       New value of the NV counter. The maximum value that
98  *                        can be set depends on the constraints of the
99  *                        underlying implementation, but it always must be
100  *                        greater than or equal to the current NV counter value.
101  *
102  * \retval TFM_PLAT_ERR_SUCCESS         The NV counter is set successfully
103  * \retval TFM_PLAT_ERR_INVALID_INPUT   The new value is less than the current
104  *                                      counter value
105  * \retval TFM_PLAT_ERR_MAX_VALUE       The new value is greater than the
106  *                                      maximum value of the NV counter
107  * \retval TFM_PLAT_ERR_UNSUPPORTED     The function is not implemented for
108  *                                      the given platform or the new value is
109  *                                      not representable on the underlying
110  *                                      counter implementation
111  * \retval TFM_PLAT_ERR_SYSTEM_ERR      An unspecified error occurred
112  *                                      (none of the other standard error codes
113  *                                      are applicable)
114  */
115 enum tfm_plat_err_t tfm_plat_set_nv_counter(enum tfm_nv_counter_t counter_id,
116                                             uint32_t value);
117 
118 #ifdef __cplusplus
119 }
120 #endif
121 
122 #endif /* __TFM_PLAT_NV_COUNTERS_H__ */
123