1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FWK_INTERNAL_ID_H
9 #define FWK_INTERNAL_ID_H
10 
11 #include <stdint.h>
12 
13 /* Identifier type */
14 enum __fwk_id_type {
15     /*
16      * Invalid variant.
17      *
18      * This type is used to catch some classes of missing-initialization errors,
19      * and should not be used to initialize new identifiers.
20      */
21     __FWK_ID_TYPE_INVALID,
22 
23     /*
24      * None variant.
25      *
26      * This type is used when an id needs to be explicitly initialized to not
27      * refer to any entity.
28      */
29     __FWK_ID_TYPE_NONE,
30 
31     /* Module */
32     __FWK_ID_TYPE_MODULE,
33 
34     /* Element */
35     __FWK_ID_TYPE_ELEMENT,
36 
37     /* Sub-element */
38     __FWK_ID_TYPE_SUB_ELEMENT,
39 
40     /* API */
41     __FWK_ID_TYPE_API,
42 
43     /* Event */
44     __FWK_ID_TYPE_EVENT,
45 
46     /* Notification */
47     __FWK_ID_TYPE_NOTIFICATION,
48 
49     /* Number of defined types */
50     __FWK_ID_TYPE_COUNT,
51 };
52 
53 /*
54  * Generic identifier.
55  *
56  * This type should be treated as though it is a variant, but where the type
57  * switches on all the fields _after_ module_idx. The `type` and `module_idx`
58  * fields use the same mask in both variants, but prefer to access them through
59  * the \c common field in agnostic code.
60  *
61  * This identifier fits within the `uint32_t` type, and so should generally be
62  * passed by value.
63  */
64 union __fwk_id {
65     uint32_t value; /* Integer value */
66 
67     struct {
68         uint32_t type : 4; /* Identifier type */
69         uint32_t module_idx : 8; /* Module index */
70         uint32_t reserved : 20; /* Reserved */
71     } common; /* Common fields */
72 
73     struct {
74         uint32_t type : 4; /* Identifier type */
75         uint32_t module_idx : 8; /* Module index */
76         uint32_t element_idx : 12; /* Element index */
77         uint32_t reserved : 8; /* Reserved */
78     } element; /* Element variant */
79 
80     struct {
81         uint32_t type : 4; /* Identifier type */
82         uint32_t module_idx : 8; /* Module index */
83         uint32_t element_idx : 12; /* Element index */
84         uint32_t sub_element_idx : 8; /* Sub-element index */
85     } sub_element; /* Sub-element variant */
86 
87     struct {
88         uint32_t type : 4; /* Identifier type */
89         uint32_t module_idx : 8; /* Module index */
90         uint32_t api_idx : 4; /* API index */
91         uint32_t reserved : 16; /* Reserved */
92     } api; /* API variant */
93 
94     struct {
95         uint32_t type : 4; /* Identifier type */
96         uint32_t module_idx : 8; /* Module index */
97         uint32_t event_idx : 6; /* Event index */
98         uint32_t reserved : 14; /* Reserved */
99     } event; /* Event variant */
100 
101     struct {
102         uint32_t type : 4; /* Identifier type */
103         uint32_t module_idx : 8; /* Module index */
104         uint32_t notification_idx : 6; /* Notification index */
105         uint32_t reserved : 14; /* Reserved */
106     } notification; /* Notification variant */
107 };
108 
109 /*
110  * Print format helper structure.
111  *
112  * This structure is necessary to prevent the string buffer from decaying to
113  * a pointer when returned from __fwk_id_str(). This ensures the string
114  * buffer is kept in scope for the entire expression, as opposed to going out of
115  * scope once __fwk_id_str() returns.
116  */
117 struct __fwk_id_fmt {
118     char str[20]; /* Identifier string representation */
119 };
120 
121 /*
122  * Build the string representation of an identifier.
123  *
124  * \param id Identifier.
125  *
126  * \return Buffer structure containing the string representation of the
127  *      identifier.
128  */
129 struct __fwk_id_fmt __fwk_id_str(union __fwk_id id);
130 
131 #endif /* FWK_INTERNAL_ID_H */
132