1 /*
2 * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef STM32MP_SHRES_HELPERS_H
8 #define STM32MP_SHRES_HELPERS_H
9
10 #include <stdint.h>
11
12 #include <common/debug.h>
13
14 /*
15 * Shared reference counter: increments by 2 on secure increment
16 * request, decrements by 2 on secure decrement request. Bit #0
17 * is set to 1 on non-secure increment request and reset to 0 on
18 * non-secure decrement request. The counter initializes to
19 * either 0, 1 or 2 upon their expect default state.
20 * Counters saturates once above UINT_MAX / 2.
21 */
22 #define SHREFCNT_NONSECURE_FLAG 0x1UL
23 #define SHREFCNT_SECURE_STEP 0x2UL
24 #define SHREFCNT_MAX (UINT32_MAX / 2)
25
26 /* Return 1 if refcnt increments from 0, else return 0 */
stm32mp_incr_shrefcnt(unsigned int * refcnt,bool secure)27 static inline int stm32mp_incr_shrefcnt(unsigned int *refcnt, bool secure)
28 {
29 int rc = !*refcnt;
30
31 if (secure) {
32 *refcnt += SHREFCNT_SECURE_STEP;
33 if (*refcnt >= SHREFCNT_MAX) {
34 panic();
35 }
36 } else {
37 *refcnt |= SHREFCNT_NONSECURE_FLAG;
38 }
39
40 return rc;
41 }
42
43 /* Return 1 if refcnt decrements to 0, else return 0 */
stm32mp_decr_shrefcnt(unsigned int * refcnt,bool secure)44 static inline int stm32mp_decr_shrefcnt(unsigned int *refcnt, bool secure)
45 {
46 int rc = 0;
47
48 if (secure) {
49 if (*refcnt < SHREFCNT_MAX) {
50 if (*refcnt < SHREFCNT_SECURE_STEP) {
51 panic();
52 }
53 *refcnt -= SHREFCNT_SECURE_STEP;
54 rc = !*refcnt;
55 }
56 } else {
57 rc = (*refcnt == SHREFCNT_NONSECURE_FLAG) ? 1 : 0;
58 *refcnt &= ~SHREFCNT_NONSECURE_FLAG;
59 }
60
61 return rc;
62 }
63
stm32mp_incr_refcnt(unsigned int * refcnt)64 static inline int stm32mp_incr_refcnt(unsigned int *refcnt)
65 {
66 return stm32mp_incr_shrefcnt(refcnt, true);
67 }
68
stm32mp_decr_refcnt(unsigned int * refcnt)69 static inline int stm32mp_decr_refcnt(unsigned int *refcnt)
70 {
71 return stm32mp_decr_shrefcnt(refcnt, true);
72 }
73
74 #endif /* STM32MP_SHRES_HELPERS_H */
75