1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef MOD_SDS_H 9 #define MOD_SDS_H 10 11 #include <fwk_element.h> 12 #include <fwk_id.h> 13 #include <fwk_module_idx.h> 14 15 #include <stdbool.h> 16 #include <stddef.h> 17 #include <stdint.h> 18 19 /*! 20 * \addtogroup GroupModules Modules 21 * \{ 22 */ 23 24 /*! 25 * \defgroup GroupSDS Shared Data Storage 26 * 27 * \details Provides a framework for the structured storage of data that is 28 * shared between the SCP Firmware and application processor firmware. 29 * 30 * \{ 31 */ 32 33 /* 34 * Bit positions for the fields that make up a structure's unique, 35 * 32-bit identifier. This value consists of the 16-bit ID, an 8-bit major 36 * version number and an 8-bit minor version number. 37 */ 38 39 /*! Position of the identifier field. */ 40 #define MOD_SDS_ID_IDENTIFIER_POS 0 41 /*! Position of the minor version field. */ 42 #define MOD_SDS_ID_VERSION_MINOR_POS 16 43 /*! Position of the major version field. */ 44 #define MOD_SDS_ID_VERSION_MAJOR_POS 24 45 46 /* 47 * Masks for the structure identifier fields. 48 */ 49 50 /*! Mask for the identifier field. */ 51 #define MOD_SDS_ID_IDENTIFIER_MASK 0x0000FFFF 52 /*! Mask for the minor version field. */ 53 #define MOD_SDS_ID_VERSION_MINOR_MASK 0x00FF0000 54 /*! Mask for the major version field. */ 55 #define MOD_SDS_ID_VERSION_MAJOR_MASK 0xFF000000 56 57 /*! 58 * \brief Element descriptor that describes an SDS region that will be 59 * automatically created during module initialization. 60 */ 61 struct mod_sds_region_desc { 62 /*! 63 * \brief Base address of the SDS region. 64 */ 65 void *base; 66 67 /*! 68 * \brief Size in bytes of the SDS Memory Region. 69 * 70 * \note If the SDS module is initialized and a region already exists then 71 * the region will be resized to match the size given here. The 72 * existing region may be increased or shrunk, as required. In the 73 * latter case the new size must be sufficient to hold the existing 74 * contents and if it is not then the initialization process will 75 * fail. 76 */ 77 size_t size; 78 }; 79 80 /*! 81 * \brief Element descriptor that describes an SDS structure that will be 82 * automatically created during element initialization. 83 */ 84 struct mod_sds_structure_desc { 85 /*! Identifier of the structure to be created. */ 86 uint32_t id; 87 88 /*! Identifier of the SDS region containing the structure. */ 89 uint32_t region_id; 90 91 /*! Size, in bytes, of the structure. */ 92 size_t size; 93 94 /*! 95 * Payload of the structure. If not equal to NULL, as part of the 96 * initialization of the module's elements, the payload of the structure 97 * identified by 'id' is initalized/updated to the value pointed to by 98 * 'payload'. 99 */ 100 const void *payload; 101 102 /*! Set the valid flag in the structure if true. */ 103 bool finalize; 104 }; 105 106 /*! 107 * \brief Module configuration. 108 */ 109 struct mod_sds_config { 110 /*! 111 * Descriptors of all the SDS regions the module will use. 112 */ 113 const struct mod_sds_region_desc *regions; 114 115 /*! 116 * Number of SDS regions managed by the module. 117 */ 118 unsigned int region_count; 119 120 #ifdef BUILD_HAS_MOD_CLOCK 121 /*! Identifier of the clock that this module depends on */ 122 fwk_id_t clock_id; 123 #endif 124 }; 125 126 /*! 127 * \brief SDS notification indices. 128 */ 129 enum mod_sds_notification_idx { 130 /*! The SDS region has been initialized */ 131 MOD_SDS_NOTIFICATION_IDX_INITIALIZED, 132 133 /*! Number of defined notifications */ 134 MOD_SDS_NOTIFICATION_IDX_COUNT 135 }; 136 137 /*! 138 * \brief Identifier for the ::MOD_SDS_NOTIFICATION_IDX_INITIALIZED 139 * notification. 140 */ 141 static const fwk_id_t mod_sds_notification_id_initialized = 142 FWK_ID_NOTIFICATION_INIT( 143 FWK_MODULE_IDX_SDS, 144 MOD_SDS_NOTIFICATION_IDX_INITIALIZED); 145 146 /*! 147 * \brief Module interface. 148 */ 149 struct mod_sds_api { 150 /*! 151 * \brief Write data within a Shared Data Structure. 152 * 153 * \details Write data to a given offset within a Shared Data Structure. The 154 * SDS module ensures that the data being written is properly 155 * contained within the structure but it is the caller's responsibility 156 * to ensure that the correct field or fields are being updated. 157 * 158 * \note A single write may update a portion of a field, a complete 159 * field, or multiple fields, depending on the definition of the 160 * structure and the size of the data being written. 161 * 162 * \param structure_id The identifier of the Shared Data Structure into 163 * which data will be written. 164 * 165 * \param offset The offset, in bytes, of the field within the Shared Data 166 * Structure. 167 * 168 * \param data Pointer to the data that will be written into the Shared Data 169 * Structure's field. 170 * 171 * \param size Size, in bytes, of the data to be written. 172 * 173 * \retval ::FWK_SUCCESS Data was successfully written to the structure. 174 * \retval ::FWK_E_PARAM An invalid parameter was encountered: 175 * - The `data` parameter was a null pointer value. 176 * - An invalid structure identifier was provided. 177 * \retval ::FWK_E_RANGE The field extends outside of the structure bounds. 178 */ 179 int (*struct_write)(uint32_t structure_id, unsigned int offset, 180 const void *data, size_t size); 181 182 /*! 183 * \brief Read data from within a Shared Data Structure. 184 * 185 * \details Read data from a given offset within a Shared Data Structure. 186 * The SDS module ensures that the data being read is contained 187 * completely within the structure but it is the caller's 188 * responsibility to ensure that the correct field(s) are being read. 189 * 190 * A single read may return only a portion of a field, a complete 191 * field, or multiple fields, depending on the definition of the 192 * structure and the value of the size parameter. 193 * 194 * \note Reading from a structure that has not been finalized is permitted 195 * but discouraged. 196 * 197 * \param structure_id The identifier of the Shared Data Structure from 198 * which data will be read. 199 * 200 * \param offset The offset, in bytes, of the field within the Shared Data 201 * Structure. 202 * 203 * \param[out] data The field data that will be read. 204 * 205 * \param size Size, in bytes, of the storage pointed to by the data 206 * parameter. 207 * 208 * \retval ::FWK_SUCCESS Data was successfully read from the structure. 209 * \retval ::FWK_E_PARAM An invalid parameter was encountered: 210 * - The `data` parameter was a null pointer value. 211 * - An invalid structure identifier was provided. 212 * \retval ::FWK_E_RANGE The field extends outside of the structure bounds. 213 */ 214 int (*struct_read)(uint32_t structure_id, unsigned int offset, void *data, 215 size_t size); 216 217 /*! 218 * \brief Mark a Shared Data Structure as valid and ready for use by 219 * application processor firmware. 220 * 221 * \param structure_id The identifier of the Shared Data Structure to 222 * finalize. 223 * 224 * \retval ::FWK_SUCCESS The structure was successfully finalized. 225 * \retval ::FWK_E_PARAM An invalid structure identifier was provided. 226 * \retval ::FWK_E_STATE The structure has already been finalized. 227 */ 228 int (*struct_finalize)(uint32_t structure_id); 229 }; 230 231 /*! 232 * \} 233 */ 234 235 /*! 236 * \} 237 */ 238 239 #endif /* MOD_SDS_H */ 240