Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*
switches 0:5c4d7b2438d3 2 * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved
switches 0:5c4d7b2438d3 3 * SPDX-License-Identifier: Apache-2.0
switches 0:5c4d7b2438d3 4 *
switches 0:5c4d7b2438d3 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
switches 0:5c4d7b2438d3 6 * not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 7 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 8 *
switches 0:5c4d7b2438d3 9 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 10 *
switches 0:5c4d7b2438d3 11 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
switches 0:5c4d7b2438d3 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 14 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 15 * limitations under the License.
switches 0:5c4d7b2438d3 16 */
switches 0:5c4d7b2438d3 17
switches 0:5c4d7b2438d3 18 #ifndef __FLASH_JOURNAL_PRIVATE_H__
switches 0:5c4d7b2438d3 19 #define __FLASH_JOURNAL_PRIVATE_H__
switches 0:5c4d7b2438d3 20
switches 0:5c4d7b2438d3 21 #ifdef __cplusplus
switches 0:5c4d7b2438d3 22 extern "C" {
switches 0:5c4d7b2438d3 23 #endif // __cplusplus
switches 0:5c4d7b2438d3 24
switches 0:5c4d7b2438d3 25 #include "flash-journal/flash_journal.h"
switches 0:5c4d7b2438d3 26
switches 0:5c4d7b2438d3 27 static inline uint32_t roundUp_uint32(uint32_t N, uint32_t BOUNDARY) {
switches 0:5c4d7b2438d3 28 return ((((N) + (BOUNDARY) - 1) / (BOUNDARY)) * (BOUNDARY));
switches 0:5c4d7b2438d3 29 }
switches 0:5c4d7b2438d3 30 static inline uint32_t roundDown_uint32(uint32_t N, uint32_t BOUNDARY) {
switches 0:5c4d7b2438d3 31 return (((N) / (BOUNDARY)) * (BOUNDARY));
switches 0:5c4d7b2438d3 32 }
switches 0:5c4d7b2438d3 33
switches 0:5c4d7b2438d3 34 #define LCM_OF_ALL_ERASE_UNITS 4096 /* Assume an LCM of erase_units for now. This will be generalized later. */
switches 0:5c4d7b2438d3 35
switches 0:5c4d7b2438d3 36 static const uint32_t SEQUENTIAL_FLASH_JOURNAL_INVALD_NEXT_SEQUENCE_NUMBER = 0xFFFFFFFFUL;
switches 0:5c4d7b2438d3 37 static const uint32_t SEQUENTIAL_FLASH_JOURNAL_MAGIC = 0xCE02102AUL;
switches 0:5c4d7b2438d3 38 static const uint32_t SEQUENTIAL_FLASH_JOURNAL_VERSION = 1;
switches 0:5c4d7b2438d3 39 static const uint32_t SEQUENTIAL_FLASH_JOURNAL_HEADER_MAGIC = 0xCEA00AEEUL;
switches 0:5c4d7b2438d3 40 static const uint32_t SEQUENTIAL_FLASH_JOURNAL_HEADER_VERSION = 1;
switches 0:5c4d7b2438d3 41
switches 0:5c4d7b2438d3 42
switches 0:5c4d7b2438d3 43 typedef enum {
switches 0:5c4d7b2438d3 44 SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED,
switches 0:5c4d7b2438d3 45 SEQUENTIAL_JOURNAL_STATE_INIT_SCANNING_LOG_HEADERS,
switches 0:5c4d7b2438d3 46 SEQUENTIAL_JOURNAL_STATE_INITIALIZED,
switches 0:5c4d7b2438d3 47 SEQUENTIAL_JOURNAL_STATE_RESETING,
switches 0:5c4d7b2438d3 48 SEQUENTIAL_JOURNAL_STATE_LOGGING_ERASE,
switches 0:5c4d7b2438d3 49 SEQUENTIAL_JOURNAL_STATE_LOGGING_HEAD,
switches 0:5c4d7b2438d3 50 SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY,
switches 0:5c4d7b2438d3 51 SEQUENTIAL_JOURNAL_STATE_LOGGING_TAIL,
switches 0:5c4d7b2438d3 52 SEQUENTIAL_JOURNAL_STATE_READING,
switches 0:5c4d7b2438d3 53 } SequentialFlashJournalState_t;
switches 0:5c4d7b2438d3 54
switches 0:5c4d7b2438d3 55 /**
switches 0:5c4d7b2438d3 56 * Meta-data placed at the head of a Journal. The actual header would be an
switches 0:5c4d7b2438d3 57 * extension of this generic header, and would depend on the implementation
switches 0:5c4d7b2438d3 58 * strategy. Initialization algorithms can expect to find this generic header at
switches 0:5c4d7b2438d3 59 * the start of every Journal.
switches 0:5c4d7b2438d3 60 */
switches 0:5c4d7b2438d3 61 typedef struct _SequentialFlashJournalHeader {
switches 0:5c4d7b2438d3 62 FlashJournalHeader_t genericHeader; /** Generic meta-data placed at the head of a Journal; common to all journal types. */
switches 0:5c4d7b2438d3 63 uint32_t magic; /** Sequential journal header specific magic code. */
switches 0:5c4d7b2438d3 64 uint32_t version; /** Revision number for this sequential journal header. */
switches 0:5c4d7b2438d3 65 uint32_t numSlots; /** Maximum number of logged blobs; i.e. maximum number of versions of the journaled payload. */
switches 0:5c4d7b2438d3 66 uint32_t sizeofSlot; /** Slot size. Each slot holds a header, blob-payload, and a tail. */
switches 0:5c4d7b2438d3 67 } SequentialFlashJournalHeader_t;
switches 0:5c4d7b2438d3 68
switches 0:5c4d7b2438d3 69 /**
switches 0:5c4d7b2438d3 70 * Meta-data placed at the head of a sequential-log entry.
switches 0:5c4d7b2438d3 71 */
switches 0:5c4d7b2438d3 72 typedef struct _SequentialFlashJournalLogHead {
switches 0:5c4d7b2438d3 73 uint32_t version;
switches 0:5c4d7b2438d3 74 uint32_t magic;
switches 0:5c4d7b2438d3 75 uint32_t sequenceNumber;
switches 0:5c4d7b2438d3 76 uint32_t reserved;
switches 0:5c4d7b2438d3 77 } SequentialFlashJournalLogHead_t;
switches 0:5c4d7b2438d3 78
switches 0:5c4d7b2438d3 79 #define SEQUENTIAL_JOURNAL_VALID_HEAD(PTR) \
switches 0:5c4d7b2438d3 80 (((PTR)->version == SEQUENTIAL_FLASH_JOURNAL_VERSION) && ((PTR)->magic == SEQUENTIAL_FLASH_JOURNAL_MAGIC))
switches 0:5c4d7b2438d3 81
switches 0:5c4d7b2438d3 82 /**
switches 0:5c4d7b2438d3 83 * Meta-data placed at the tail of a sequential-log entry.
switches 0:5c4d7b2438d3 84 *
switches 0:5c4d7b2438d3 85 * @note the most crucial items (the ones which play a role in the validation of
switches 0:5c4d7b2438d3 86 * the log-entry) are placed at the end of this structure; this ensures that
switches 0:5c4d7b2438d3 87 * a partially written log-entry-tail won't be accepted as valid.
switches 0:5c4d7b2438d3 88 */
switches 0:5c4d7b2438d3 89 typedef struct _SequentialFlashJournalLogTail {
switches 0:5c4d7b2438d3 90 uint32_t sizeofBlob; /**< the size of the payload in this blob. */
switches 0:5c4d7b2438d3 91 uint32_t magic;
switches 0:5c4d7b2438d3 92 uint32_t sequenceNumber;
switches 0:5c4d7b2438d3 93 uint32_t crc32; /**< This field contains the CRC of the header, body (only including logged data),
switches 0:5c4d7b2438d3 94 * and the tail. The 'CRC32' field is assumed to hold 0x0 for the purpose of
switches 0:5c4d7b2438d3 95 * computing the CRC */
switches 0:5c4d7b2438d3 96 } SequentialFlashJournalLogTail_t;
switches 0:5c4d7b2438d3 97
switches 0:5c4d7b2438d3 98 #define SEQUENTIAL_JOURNAL_VALID_TAIL(TAIL_PTR) ((TAIL_PTR)->magic == SEQUENTIAL_FLASH_JOURNAL_MAGIC)
switches 0:5c4d7b2438d3 99
switches 0:5c4d7b2438d3 100 typedef struct _SequentialFlashJournal_t {
switches 0:5c4d7b2438d3 101 FlashJournal_Ops_t ops; /**< the mandatory OPS table defining the strategy. */
switches 0:5c4d7b2438d3 102 FlashJournal_Callback_t callback; /**< command completion callback. */
switches 0:5c4d7b2438d3 103 FlashJournal_Info_t info; /**< the info structure returned from GetInfo(). */
switches 0:5c4d7b2438d3 104 ARM_DRIVER_STORAGE *mtd; /**< The underlying Memory-Technology-Device. */
switches 0:5c4d7b2438d3 105 ARM_STORAGE_CAPABILITIES mtdCapabilities; /**< the return from mtd->GetCapabilities(); held for quick reference. */
switches 0:5c4d7b2438d3 106 uint64_t mtdStartOffset; /**< the start of the address range maintained by the underlying MTD. */
switches 0:5c4d7b2438d3 107 uint32_t firstSlotOffset; /** Offset from the start of the journal header to the actual logged journal. */
switches 0:5c4d7b2438d3 108 uint32_t numSlots; /** Maximum number of logged blobs; i.e. maximum number of versions of the journaled payload. */
switches 0:5c4d7b2438d3 109 uint32_t sizeofSlot; /**< size of the log stride. */
switches 0:5c4d7b2438d3 110 uint32_t nextSequenceNumber; /**< the next valid sequence number to be used when logging the next blob. */
switches 0:5c4d7b2438d3 111 uint32_t currentBlobIndex; /**< index of the most recently written blob. */
switches 0:5c4d7b2438d3 112 SequentialFlashJournalState_t state; /**< state of the journal. SEQUENTIAL_JOURNAL_STATE_INITIALIZED being the default. */
switches 0:5c4d7b2438d3 113 FlashJournal_OpCode_t prevCommand; /**< the last command issued to the journal. */
switches 0:5c4d7b2438d3 114
switches 0:5c4d7b2438d3 115 /**
switches 0:5c4d7b2438d3 116 * The following is a union of sub-structures meant to keep state relevant
switches 0:5c4d7b2438d3 117 * to the commands during their execution.
switches 0:5c4d7b2438d3 118 */
switches 0:5c4d7b2438d3 119 union {
switches 0:5c4d7b2438d3 120 /** state relevant to initialization. */
switches 0:5c4d7b2438d3 121 struct {
switches 0:5c4d7b2438d3 122 uint64_t currentOffset;
switches 0:5c4d7b2438d3 123 struct {
switches 0:5c4d7b2438d3 124 uint32_t headSequenceNumber;
switches 0:5c4d7b2438d3 125 SequentialFlashJournalLogTail_t tail;
switches 0:5c4d7b2438d3 126 };
switches 0:5c4d7b2438d3 127 } initScan;
switches 0:5c4d7b2438d3 128
switches 0:5c4d7b2438d3 129 /** state relevant to logging of data. */
switches 0:5c4d7b2438d3 130 struct {
switches 0:5c4d7b2438d3 131 const uint8_t *blob; /**< the original buffer holding source data. */
switches 0:5c4d7b2438d3 132 size_t sizeofBlob;
switches 0:5c4d7b2438d3 133 union {
switches 0:5c4d7b2438d3 134 struct {
switches 0:5c4d7b2438d3 135 uint64_t mtdEraseOffset;
switches 0:5c4d7b2438d3 136 };
switches 0:5c4d7b2438d3 137 struct {
switches 0:5c4d7b2438d3 138 uint64_t mtdOffset; /**< the current Storage offset at which data will be written. */
switches 0:5c4d7b2438d3 139 uint64_t mtdTailOffset; /**< Storage offset at which the SequentialFlashJournalLogTail_t will be logged for this log-entry. */
switches 0:5c4d7b2438d3 140 const uint8_t *dataBeingLogged; /**< temporary pointer aimed at the next data to be logged. */
switches 0:5c4d7b2438d3 141 size_t amountLeftToLog;
switches 0:5c4d7b2438d3 142 union {
switches 0:5c4d7b2438d3 143 SequentialFlashJournalLogHead_t head;
switches 0:5c4d7b2438d3 144 SequentialFlashJournalLogTail_t tail;
switches 0:5c4d7b2438d3 145 };
switches 0:5c4d7b2438d3 146 };
switches 0:5c4d7b2438d3 147 };
switches 0:5c4d7b2438d3 148 } log;
switches 0:5c4d7b2438d3 149
switches 0:5c4d7b2438d3 150 /** state relevant to read-back of data. */
switches 0:5c4d7b2438d3 151 struct {
switches 0:5c4d7b2438d3 152 const uint8_t *blob; /**< the original buffer holding source data. */
switches 0:5c4d7b2438d3 153 size_t sizeofBlob;
switches 0:5c4d7b2438d3 154 uint64_t mtdOffset; /**< the current Storage offset from which data is being read. */
switches 0:5c4d7b2438d3 155 uint8_t *dataBeingRead; /**< temporary pointer aimed at the next data to be read-into. */
switches 0:5c4d7b2438d3 156 size_t amountLeftToRead;
switches 0:5c4d7b2438d3 157 size_t logicalOffset; /**< the logical offset within the blob at which the next read will occur. */
switches 0:5c4d7b2438d3 158 } read;
switches 0:5c4d7b2438d3 159 };
switches 0:5c4d7b2438d3 160 } SequentialFlashJournal_t;
switches 0:5c4d7b2438d3 161
switches 0:5c4d7b2438d3 162 /**<
switches 0:5c4d7b2438d3 163 * A static assert to ensure that the size of SequentialJournal is smaller than
switches 0:5c4d7b2438d3 164 * FlashJournal_t. The caller will only allocate a FlashJournal_t and expect the
switches 0:5c4d7b2438d3 165 * Sequential Strategy to reuse that space for a SequentialFlashJournal_t.
switches 0:5c4d7b2438d3 166 */
switches 0:5c4d7b2438d3 167 typedef char AssertSequentialJournalSizeLessThanOrEqualToGenericJournal[sizeof(SequentialFlashJournal_t)<=sizeof(FlashJournal_t)?1:-1];
switches 0:5c4d7b2438d3 168
switches 0:5c4d7b2438d3 169 #define SLOT_ADDRESS(JOURNAL, INDEX) ((JOURNAL)->mtdStartOffset + (JOURNAL)->firstSlotOffset + ((INDEX) * (JOURNAL)->sizeofSlot))
switches 0:5c4d7b2438d3 170
switches 0:5c4d7b2438d3 171 #ifdef __cplusplus
switches 0:5c4d7b2438d3 172 }
switches 0:5c4d7b2438d3 173 #endif // __cplusplus
switches 0:5c4d7b2438d3 174
switches 0:5c4d7b2438d3 175 #endif /* __FLASH_JOURNAL_PRIVATE_H__ */