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