Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers storage_volume_manager.h Source File

storage_volume_manager.h

00001 /*
00002  * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef __STORAGE_VOLUME_MANAGER_H__
00019 #define __STORAGE_VOLUME_MANAGER_H__
00020 
00021 #ifndef __cplusplus
00022 #error "This abstraction requires a C++ toolchain"
00023 #endif // __cplusplus
00024 
00025 #include "storage_abstraction/Driver_Storage.h"
00026 
00027 #if !defined(YOTTA_CFG_STORAGE_VOLUME_MANAGER_MAX_VOLUMES)
00028 #define MAX_VOLUMES 4
00029 #else
00030 #define MAX_VOLUMES YOTTA_CFG_STORAGE_VOLUME_MANAGER_MAX_VOLUMES
00031 #endif
00032 /**<
00033  * A static assert to ensure that the size of SequentialJournal is smaller than
00034  * FlashJournal_t. The caller will only allocate a FlashJournal_t and expect the
00035  * Sequential Strategy to reuse that space for a SequentialFlashJournal_t.
00036  */
00037 #ifndef TOOLCHAIN_IAR
00038 typedef char AssertStorageVolumeManagerMaxVolumesIsSane[(((MAX_VOLUMES) > 0) && ((MAX_VOLUMES) <= 8)) ? 0:-1];
00039 #endif
00040 
00041 #define CONCATENATE(A, B) A ## B
00042 #define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */
00043 
00044 #define STORAGE_API_EXTERN_C_DECLARATIONS_FOR_VOLUME(N)                                                               \
00045     extern "C" ARM_DRIVER_VERSION       GetVersion_ ## N(void);                                                       \
00046     extern "C" ARM_STORAGE_CAPABILITIES GetCapabilities_ ## N(void);                                                  \
00047     extern "C" int32_t                  Initialize_ ## N(ARM_Storage_Callback_t callback);                            \
00048     extern "C" int32_t                  Uninitialize_ ## N(void);                                                     \
00049     extern "C" int32_t                  PowerControl_ ## N(ARM_POWER_STATE state);                                    \
00050     extern "C" int32_t                  ReadData_ ## N(uint64_t addr, void *data, uint32_t size);                     \
00051     extern "C" int32_t                  ProgramData_ ## N(uint64_t addr, const void *data, uint32_t size);            \
00052     extern "C" int32_t                  Erase_ ## N(uint64_t addr, uint32_t size);                                    \
00053     extern "C" int32_t                  EraseAll_ ## N(void);                                                         \
00054     extern "C" ARM_STORAGE_STATUS       GetStatus_ ## N(void);                                                        \
00055     extern "C" int32_t                  GetInfo_ ## N(ARM_STORAGE_INFO *infoP);                                       \
00056     extern "C" uint32_t                 ResolveAddress_ ## N(uint64_t addr);                                          \
00057     extern "C" int32_t                  GetNextBlock_ ## N(const ARM_STORAGE_BLOCK* prevP, ARM_STORAGE_BLOCK *nextP); \
00058     extern "C" int32_t                  GetBlock_ ## N(uint64_t addr, ARM_STORAGE_BLOCK *blockP);
00059 
00060 #define STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_1 STORAGE_API_EXTERN_C_DECLARATIONS_FOR_VOLUME(0)
00061 #define STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_2 STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_1 STORAGE_API_EXTERN_C_DECLARATIONS_FOR_VOLUME(1)
00062 #define STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_3 STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_2 STORAGE_API_EXTERN_C_DECLARATIONS_FOR_VOLUME(2)
00063 #define STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_4 STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_3 STORAGE_API_EXTERN_C_DECLARATIONS_FOR_VOLUME(3)
00064 /* ... add more of the above if ever needed */
00065 
00066 #define STORAGE_API_EXTERN_C_DECLARATIONS_LIST(N) EXPAND(CONCATENATE(STORAGE_API_EXTERN_C_DECLARATIONS_LIST_FOR_, N))
00067 
00068 STORAGE_API_EXTERN_C_DECLARATIONS_LIST(MAX_VOLUMES);
00069 
00070 /**
00071  * Error return codes specific to the Storage volume manager. These extend the
00072  * common error codes from ARM_DRIVER_STORAGE. All Volume-manager APIs return an
00073  * int32_t to allow for both error and success status returns. This enumeration
00074  * contains all possible error status values.
00075  */
00076 typedef enum _StorageVolumeManager_Status
00077 {
00078     STORAGE_VOLUME_MANAGER_STATUS_ERROR_EXHASTED_VOLUMES     = -7,  ///< exhausted the supply of available volumes
00079     STORAGE_VOLUME_MANAGER_STATUS_ERROR_NOT_ERASABLE         = -8,  ///< Part (or all) of the range provided to Erase() isn't erasable.
00080     STORAGE_VOLUME_MANAGER_STATUS_ERROR_NOT_PROGRAMMABLE     = -9,  ///< Part (or all) of the range provided to ProgramData() isn't programmable.
00081     STORAGE_VOLUME_MANAGER_STATUS_ERROR_PROTECTED            = -10, ///< Part (or all) of the range to Erase() or ProgramData() is protected.
00082     STORAGE_VOLUME_MANAGER_STATUS_ERROR_NOT_INITIALIZED      = -11, ///< underlying storage not initialized
00083     STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED = -12, ///< attempt to operate on an unallocated volume
00084 } StorageVolumeManager_Status_t;
00085 
00086 typedef void (*InitializeCallback_t)(int32_t status);
00087 class StorageVolumeManager; /* forward declaration */
00088 
00089 class StorageVolume {
00090 public:
00091     StorageVolume() : allocated(false) { /* empty */ }
00092 
00093 public:
00094     void setup(uint64_t addr, uint64_t size, StorageVolumeManager *volumeManager);
00095 
00096     /*
00097      * Mimic the API of ARM_DRIVER_STORAGE
00098      */
00099 public:
00100     ARM_DRIVER_VERSION       GetVersion(void);
00101     ARM_STORAGE_CAPABILITIES GetCapabilities(void);
00102     int32_t                  Initialize(ARM_Storage_Callback_t callback);
00103     int32_t                  Uninitialize(void);
00104     int32_t                  PowerControl(ARM_POWER_STATE state);
00105     int32_t                  ReadData(uint64_t addr, void *data, uint32_t size);
00106     int32_t                  ProgramData(uint64_t addr, const void *data, uint32_t size);
00107     int32_t                  Erase(uint64_t addr, uint32_t size);
00108     int32_t                  EraseAll(void);
00109     ARM_STORAGE_STATUS       GetStatus(void);
00110     int32_t                  GetInfo(ARM_STORAGE_INFO *infoP);
00111     uint32_t                 ResolveAddress(uint64_t addr);
00112     int32_t                  GetNextBlock(const ARM_STORAGE_BLOCK* prevP, ARM_STORAGE_BLOCK *nextP);
00113     int32_t                  GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *blockP);
00114 
00115 public:
00116     bool isAllocated(void) const {
00117         return allocated;
00118     }
00119 
00120     void deallocate(void) {
00121         allocated = false;
00122     }
00123 
00124     /*
00125      * Accessor methods.
00126      */
00127 
00128     uint64_t getVolumeOffset(void) const {
00129         return volumeOffset;
00130     }
00131     uint64_t getVolumeSize(void) const {
00132         return volumeSize;
00133     }
00134     const ARM_Storage_Callback_t &getCallback(void) const {
00135         return callback;
00136     }
00137 
00138 private:
00139     bool overlapsWithBlock(const ARM_STORAGE_BLOCK* blockP) const {
00140         return (((blockP->addr + blockP->size) <= volumeOffset) || ((volumeOffset + volumeSize) <= blockP->addr)) ? false : true;
00141     }
00142 
00143     void transformBlockToVolume(ARM_STORAGE_BLOCK *blockP) const {
00144         if (blockP->addr < volumeOffset) {
00145             blockP->addr = volumeOffset;
00146         }
00147         if ((blockP->addr + blockP->size) > (volumeOffset + volumeSize)) {
00148             blockP->size = (volumeOffset + volumeSize) - blockP->addr;
00149         }
00150 
00151         blockP->addr -= volumeOffset;
00152     }
00153 
00154 private:
00155     bool                    allocated;
00156     uint64_t                volumeOffset;
00157     uint64_t                volumeSize;
00158     ARM_Storage_Callback_t  callback;
00159     StorageVolumeManager   *volumeManager;
00160 };
00161 
00162 class StorageVolumeManager {
00163 public:
00164     StorageVolumeManager()  { /* empty */ }
00165     ~StorageVolumeManager() { /* empty */ }
00166 
00167     /**
00168      * Initialize the storage MTD and prepare it for operation within the context of the volume manager.
00169      *
00170      * @param[in] storage
00171      *              The underlying MTD.
00172      * @param[in] callback
00173      *              A callback to be invoked upon completion of initialization.
00174      *
00175      * @return If asynchronous activity is launched, an invocation returns
00176      *     ARM_DRIVER_OK, and the caller can expect to receive a
00177      *     callback in the future with a status value of ARM_DRIVER_OK or an error-
00178      *     code. In the case of synchronous execution, control returns after
00179      *     completion with a value of 1. Return values less than
00180      *     ARM_DRIVER_OK (0) signify errors.
00181      */
00182     int32_t initialize(ARM_DRIVER_STORAGE *mtd, InitializeCallback_t callback);
00183 
00184     int32_t addVolume(uint64_t addr, uint64_t size, StorageVolume **volumePP);
00185     int32_t addVolume_C(uint64_t addr, uint64_t size, _ARM_DRIVER_STORAGE *mtd);
00186     int32_t lookupVolume(uint64_t addr, StorageVolume **volumePP);
00187 
00188     /*
00189      * Accessor methods.
00190      */
00191 
00192     bool isInitialized() const {
00193         return initialized;
00194     }
00195     ARM_DRIVER_STORAGE *getStorage(void) const {
00196         return storage;
00197     }
00198     const ARM_STORAGE_INFO &getStorageInfo(void) const {
00199         return storageInfo;
00200     }
00201     const ARM_STORAGE_CAPABILITIES &getStorageCapabilities(void) const {
00202         return storageCapabilities;
00203     }
00204     StorageVolume *volumeAtIndex(size_t index) {
00205         return &volumes[index];
00206     }
00207 
00208 public:
00209     static void storageCallback(int32_t status, ARM_STORAGE_OPERATION operation);
00210 
00211 private:
00212     friend int32_t StorageVolume::PowerControl(ARM_POWER_STATE state);
00213     friend int32_t StorageVolume::ReadData(uint64_t addr, void *data, uint32_t size);
00214     friend int32_t StorageVolume::ProgramData(uint64_t addr, const void *data, uint32_t size);
00215     friend int32_t StorageVolume::Erase(uint64_t addr, uint32_t size);
00216     friend int32_t StorageVolume::EraseAll(void);
00217     friend ARM_STORAGE_STATUS StorageVolume::GetStatus(void);
00218     StorageVolume *activeVolume; /* This state-variable is set to point to a volume
00219                                   * while there is pending activity. It tracks
00220                                   * the volume which is at the source of the
00221                                   * activity. Once the activity finishes, this
00222                                   * variable is reset. Having this variable set
00223                                   * might be used as an indication that the
00224                                   * underlying storage is busy. */
00225 
00226 #define FRIEND_DECLARATIONS_FOR_VOLUME(N) \
00227   friend ARM_DRIVER_VERSION       GetVersion_ ## N(void);                                                       \
00228   friend ARM_STORAGE_CAPABILITIES GetCapabilities_ ## N(void);                                                  \
00229   friend int32_t                  Initialize_ ## N(ARM_Storage_Callback_t callback);                            \
00230   friend int32_t                  Uninitialize_ ## N(void);                                                     \
00231   friend int32_t                  PowerControl_ ## N(ARM_POWER_STATE state);                                    \
00232   friend int32_t                  ReadData_ ## N(uint64_t addr, void *data, uint32_t size);                     \
00233   friend int32_t                  ProgramData_ ## N(uint64_t addr, const void *data, uint32_t size);            \
00234   friend int32_t                  Erase_ ## N(uint64_t addr, uint32_t size);                                    \
00235   friend int32_t                  EraseAll_ ## N(void);                                                         \
00236   friend ARM_STORAGE_STATUS       GetStatus_ ## N(void);                                                        \
00237   friend int32_t                  GetInfo_ ## N(ARM_STORAGE_INFO *infoP);                                       \
00238   friend uint32_t                 ResolveAddress_ ## N(uint64_t addr);                                          \
00239   friend int32_t                  GetNextBlock_ ## N(const ARM_STORAGE_BLOCK* prevP, ARM_STORAGE_BLOCK *nextP); \
00240   friend int32_t                  GetBlock_ ## N(uint64_t addr, ARM_STORAGE_BLOCK *blockP);
00241 
00242 #define FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_1 FRIEND_DECLARATIONS_FOR_VOLUME(0)
00243 #define FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_2 FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_1 FRIEND_DECLARATIONS_FOR_VOLUME(1)
00244 #define FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_3 FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_2 FRIEND_DECLARATIONS_FOR_VOLUME(2)
00245 #define FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_4 FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_3 FRIEND_DECLARATIONS_FOR_VOLUME(3)
00246 /* ... add more of the above if ever needed */
00247 
00248 #define FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES(N) EXPAND(CONCATENATE(FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES_FOR_, N))
00249 
00250     //todo: remove FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES(MAX_VOLUMES);
00251     FRIEND_DECLARATIONS_FOR_STORAGE_API_INSTANCES(MAX_VOLUMES)
00252 
00253 private:
00254     size_t findIndexOfUnusedVolume(void) const;
00255 
00256 private:
00257     bool                      initialized;
00258     ARM_DRIVER_STORAGE       *storage;
00259     ARM_STORAGE_INFO          storageInfo;
00260     ARM_STORAGE_CAPABILITIES  storageCapabilities;
00261     StorageVolume             volumes[MAX_VOLUMES];
00262 };
00263 
00264 #endif /* __STORAGE_VOLUME_MANAGER_H__ */