blob: 8b786cc04000c6239881e12629e56b60225f90ba [file] [log] [blame]
Yann Gautiere4a3c352019-02-14 10:53:33 +01001/*
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 */
27static 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 */
44static 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
64static inline int stm32mp_incr_refcnt(unsigned int *refcnt)
65{
66 return stm32mp_incr_shrefcnt(refcnt, true);
67}
68
69static inline int stm32mp_decr_refcnt(unsigned int *refcnt)
70{
71 return stm32mp_decr_shrefcnt(refcnt, true);
72}
73
74#endif /* STM32MP_SHRES_HELPERS_H */