00
hal/storage_abstraction/Driver_Storage.h@0:13413ea9a877, 2022-06-12 (annotated)
- Committer:
- ganlikun
- Date:
- Sun Jun 12 14:02:44 2022 +0000
- Revision:
- 0:13413ea9a877
00
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ganlikun | 0:13413ea9a877 | 1 | |
ganlikun | 0:13413ea9a877 | 2 | /** \addtogroup hal */ |
ganlikun | 0:13413ea9a877 | 3 | /** @{*/ |
ganlikun | 0:13413ea9a877 | 4 | /* |
ganlikun | 0:13413ea9a877 | 5 | * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved |
ganlikun | 0:13413ea9a877 | 6 | * SPDX-License-Identifier: Apache-2.0 |
ganlikun | 0:13413ea9a877 | 7 | * |
ganlikun | 0:13413ea9a877 | 8 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
ganlikun | 0:13413ea9a877 | 9 | * not use this file except in compliance with the License. |
ganlikun | 0:13413ea9a877 | 10 | * You may obtain a copy of the License at |
ganlikun | 0:13413ea9a877 | 11 | * |
ganlikun | 0:13413ea9a877 | 12 | * http://www.apache.org/licenses/LICENSE-2.0 |
ganlikun | 0:13413ea9a877 | 13 | * |
ganlikun | 0:13413ea9a877 | 14 | * Unless required by applicable law or agreed to in writing, software |
ganlikun | 0:13413ea9a877 | 15 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
ganlikun | 0:13413ea9a877 | 16 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ganlikun | 0:13413ea9a877 | 17 | * See the License for the specific language governing permissions and |
ganlikun | 0:13413ea9a877 | 18 | * limitations under the License. |
ganlikun | 0:13413ea9a877 | 19 | */ |
ganlikun | 0:13413ea9a877 | 20 | |
ganlikun | 0:13413ea9a877 | 21 | #ifndef __DRIVER_STORAGE_H |
ganlikun | 0:13413ea9a877 | 22 | #define __DRIVER_STORAGE_H |
ganlikun | 0:13413ea9a877 | 23 | |
ganlikun | 0:13413ea9a877 | 24 | #include <stdint.h> |
ganlikun | 0:13413ea9a877 | 25 | |
ganlikun | 0:13413ea9a877 | 26 | /****** This file has been deprecated since mbed-os-5.5 *****/ |
ganlikun | 0:13413ea9a877 | 27 | |
ganlikun | 0:13413ea9a877 | 28 | #ifdef __cplusplus |
ganlikun | 0:13413ea9a877 | 29 | extern "C" { |
ganlikun | 0:13413ea9a877 | 30 | #endif // __cplusplus |
ganlikun | 0:13413ea9a877 | 31 | |
ganlikun | 0:13413ea9a877 | 32 | #include "Driver_Common.h" |
ganlikun | 0:13413ea9a877 | 33 | |
ganlikun | 0:13413ea9a877 | 34 | #define ARM_STORAGE_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,00) /* API version */ |
ganlikun | 0:13413ea9a877 | 35 | |
ganlikun | 0:13413ea9a877 | 36 | |
ganlikun | 0:13413ea9a877 | 37 | #define _ARM_Driver_Storage_(n) Driver_Storage##n |
ganlikun | 0:13413ea9a877 | 38 | #define ARM_Driver_Storage_(n) _ARM_Driver_Storage_(n) |
ganlikun | 0:13413ea9a877 | 39 | |
ganlikun | 0:13413ea9a877 | 40 | #define ARM_STORAGE_INVALID_OFFSET (0xFFFFFFFFFFFFFFFFULL) ///< Invalid address (relative to a storage controller's |
ganlikun | 0:13413ea9a877 | 41 | ///< address space). A storage block may never start at this address. |
ganlikun | 0:13413ea9a877 | 42 | |
ganlikun | 0:13413ea9a877 | 43 | #define ARM_STORAGE_INVALID_ADDRESS (0xFFFFFFFFUL) ///< Invalid address within the processor's memory address space. |
ganlikun | 0:13413ea9a877 | 44 | ///< Refer to memory-mapped storage, i.e. < \ref ARM_DRIVER_STORAGE::ResolveAddress(). |
ganlikun | 0:13413ea9a877 | 45 | |
ganlikun | 0:13413ea9a877 | 46 | /****** Storage specific error codes *****/ |
ganlikun | 0:13413ea9a877 | 47 | #define ARM_STORAGE_ERROR_NOT_ERASABLE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Part (or all) of the range provided to Erase() isn't erasable. |
ganlikun | 0:13413ea9a877 | 48 | #define ARM_STORAGE_ERROR_NOT_PROGRAMMABLE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Part (or all) of the range provided to ProgramData() isn't programmable. |
ganlikun | 0:13413ea9a877 | 49 | #define ARM_STORAGE_ERROR_PROTECTED (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Part (or all) of the range to Erase() or ProgramData() is protected. |
ganlikun | 0:13413ea9a877 | 50 | #define ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Runtime or sanity-check failure. |
ganlikun | 0:13413ea9a877 | 51 | |
ganlikun | 0:13413ea9a877 | 52 | /** |
ganlikun | 0:13413ea9a877 | 53 | * \brief Attributes of the storage range within a storage block. |
ganlikun | 0:13413ea9a877 | 54 | */ |
ganlikun | 0:13413ea9a877 | 55 | typedef struct _ARM_STORAGE_BLOCK_ATTRIBUTES { |
ganlikun | 0:13413ea9a877 | 56 | uint32_t erasable : 1; ///< Erasing blocks is permitted with a minimum granularity of 'erase_unit'. |
ganlikun | 0:13413ea9a877 | 57 | ///< @note: if 'erasable' is 0--i.e. the 'erase' operation isn't available--then |
ganlikun | 0:13413ea9a877 | 58 | ///< 'erase_unit' (see below) is immaterial and should be 0. |
ganlikun | 0:13413ea9a877 | 59 | uint32_t programmable : 1; ///< Writing to ranges is permitted with a minimum granularity of 'program_unit'. |
ganlikun | 0:13413ea9a877 | 60 | ///< Writes are typically achieved through the ProgramData operation (following an erase); |
ganlikun | 0:13413ea9a877 | 61 | ///< if storage isn't erasable (see 'erasable' above) but is memory-mapped |
ganlikun | 0:13413ea9a877 | 62 | ///< (i.e. 'memory_mapped'), it can be written directly using memory-store operations. |
ganlikun | 0:13413ea9a877 | 63 | uint32_t executable : 1; ///< This storage block can hold program data; the processor can fetch and execute code |
ganlikun | 0:13413ea9a877 | 64 | ///< sourced from it. Often this is accompanied with the device being 'memory_mapped' (see \ref ARM_STORAGE_INFO). |
ganlikun | 0:13413ea9a877 | 65 | uint32_t protectable : 1; ///< The entire block can be protected from program and erase operations. Once protection |
ganlikun | 0:13413ea9a877 | 66 | ///< is enabled for a block, its 'erasable' and 'programmable' bits are turned off. |
ganlikun | 0:13413ea9a877 | 67 | uint32_t reserved : 28; |
ganlikun | 0:13413ea9a877 | 68 | uint32_t erase_unit; ///< Minimum erase size in bytes. |
ganlikun | 0:13413ea9a877 | 69 | ///< The offset of the start of the erase-range should also be aligned with this value. |
ganlikun | 0:13413ea9a877 | 70 | ///< Applicable if the 'erasable' attribute is set for the block. |
ganlikun | 0:13413ea9a877 | 71 | ///< @note: if 'erasable' (see above) is 0--i.e. the 'erase' operation isn't available--then |
ganlikun | 0:13413ea9a877 | 72 | ///< 'erase_unit' is immaterial and should be 0. |
ganlikun | 0:13413ea9a877 | 73 | uint32_t protection_unit; ///< Minimum protectable size in bytes. Applicable if the 'protectable' |
ganlikun | 0:13413ea9a877 | 74 | ///< attribute is set for the block. This should be a divisor of the block's size. A |
ganlikun | 0:13413ea9a877 | 75 | ///< block can be considered to be made up of consecutive, individually-protectable fragments. |
ganlikun | 0:13413ea9a877 | 76 | } ARM_STORAGE_BLOCK_ATTRIBUTES; |
ganlikun | 0:13413ea9a877 | 77 | |
ganlikun | 0:13413ea9a877 | 78 | /** |
ganlikun | 0:13413ea9a877 | 79 | * \brief A storage block is a range of memory with uniform attributes. Storage blocks |
ganlikun | 0:13413ea9a877 | 80 | * combine to make up the address map of a storage controller. |
ganlikun | 0:13413ea9a877 | 81 | */ |
ganlikun | 0:13413ea9a877 | 82 | typedef struct _ARM_STORAGE_BLOCK { |
ganlikun | 0:13413ea9a877 | 83 | uint64_t addr; ///< This is the start address of the storage block. It is |
ganlikun | 0:13413ea9a877 | 84 | ///< expressed as an offset from the start of the storage map |
ganlikun | 0:13413ea9a877 | 85 | ///< maintained by the owning storage controller. |
ganlikun | 0:13413ea9a877 | 86 | uint64_t size; ///< This is the size of the storage block, in units of bytes. |
ganlikun | 0:13413ea9a877 | 87 | ///< Together with addr, it describes a range [addr, addr+size). |
ganlikun | 0:13413ea9a877 | 88 | ARM_STORAGE_BLOCK_ATTRIBUTES attributes; ///< Attributes for this block. |
ganlikun | 0:13413ea9a877 | 89 | } ARM_STORAGE_BLOCK; |
ganlikun | 0:13413ea9a877 | 90 | |
ganlikun | 0:13413ea9a877 | 91 | /** |
ganlikun | 0:13413ea9a877 | 92 | * The check for a valid ARM_STORAGE_BLOCK. |
ganlikun | 0:13413ea9a877 | 93 | */ |
ganlikun | 0:13413ea9a877 | 94 | #define ARM_STORAGE_VALID_BLOCK(BLK) (((BLK)->addr != ARM_STORAGE_INVALID_OFFSET) && ((BLK)->size != 0)) |
ganlikun | 0:13413ea9a877 | 95 | |
ganlikun | 0:13413ea9a877 | 96 | /** |
ganlikun | 0:13413ea9a877 | 97 | * \brief Values for encoding storage memory-types with respect to programmability. |
ganlikun | 0:13413ea9a877 | 98 | * |
ganlikun | 0:13413ea9a877 | 99 | * Please ensure that the maximum of the following memory types doesn't exceed 16; we |
ganlikun | 0:13413ea9a877 | 100 | * encode this in a 4-bit field within ARM_STORAGE_INFO::programmability. |
ganlikun | 0:13413ea9a877 | 101 | */ |
ganlikun | 0:13413ea9a877 | 102 | #define ARM_STORAGE_PROGRAMMABILITY_RAM (0x0) |
ganlikun | 0:13413ea9a877 | 103 | #define ARM_STORAGE_PROGRAMMABILITY_ROM (0x1) ///< Read-only memory. |
ganlikun | 0:13413ea9a877 | 104 | #define ARM_STORAGE_PROGRAMMABILITY_WORM (0x2) ///< write-once-read-only-memory (WORM). |
ganlikun | 0:13413ea9a877 | 105 | #define ARM_STORAGE_PROGRAMMABILITY_ERASABLE (0x3) ///< re-programmable based on erase. Supports multiple writes. |
ganlikun | 0:13413ea9a877 | 106 | |
ganlikun | 0:13413ea9a877 | 107 | /** |
ganlikun | 0:13413ea9a877 | 108 | * Values for encoding data-retention levels for storage blocks. |
ganlikun | 0:13413ea9a877 | 109 | * |
ganlikun | 0:13413ea9a877 | 110 | * Please ensure that the maximum of the following retention types doesn't exceed 16; we |
ganlikun | 0:13413ea9a877 | 111 | * encode this in a 4-bit field within ARM_STORAGE_INFO::retention_level. |
ganlikun | 0:13413ea9a877 | 112 | */ |
ganlikun | 0:13413ea9a877 | 113 | #define ARM_RETENTION_WHILE_DEVICE_ACTIVE (0x0) ///< Data is retained only during device activity. |
ganlikun | 0:13413ea9a877 | 114 | #define ARM_RETENTION_ACROSS_SLEEP (0x1) ///< Data is retained across processor sleep. |
ganlikun | 0:13413ea9a877 | 115 | #define ARM_RETENTION_ACROSS_DEEP_SLEEP (0x2) ///< Data is retained across processor deep-sleep. |
ganlikun | 0:13413ea9a877 | 116 | #define ARM_RETENTION_BATTERY_BACKED (0x3) ///< Data is battery-backed. Device can be powered off. |
ganlikun | 0:13413ea9a877 | 117 | #define ARM_RETENTION_NVM (0x4) ///< Data is retained in non-volatile memory. |
ganlikun | 0:13413ea9a877 | 118 | |
ganlikun | 0:13413ea9a877 | 119 | /** |
ganlikun | 0:13413ea9a877 | 120 | * Device Data Security Protection Features. Applicable mostly to EXTERNAL_NVM. |
ganlikun | 0:13413ea9a877 | 121 | */ |
ganlikun | 0:13413ea9a877 | 122 | typedef struct _ARM_STORAGE_SECURITY_FEATURES { |
ganlikun | 0:13413ea9a877 | 123 | uint32_t acls : 1; ///< Protection against internal software attacks using ACLs. |
ganlikun | 0:13413ea9a877 | 124 | uint32_t rollback_protection : 1; ///< Roll-back protection. Set to true if the creator of the storage |
ganlikun | 0:13413ea9a877 | 125 | ///< can ensure that an external attacker can't force an |
ganlikun | 0:13413ea9a877 | 126 | ///< older firmware to run or to revert back to a previous state. |
ganlikun | 0:13413ea9a877 | 127 | uint32_t tamper_proof : 1; ///< Tamper-proof memory (will be deleted on tamper-attempts using board level or chip level sensors). |
ganlikun | 0:13413ea9a877 | 128 | uint32_t internal_flash : 1; ///< Internal flash. |
ganlikun | 0:13413ea9a877 | 129 | uint32_t reserved1 : 12; |
ganlikun | 0:13413ea9a877 | 130 | |
ganlikun | 0:13413ea9a877 | 131 | /** |
ganlikun | 0:13413ea9a877 | 132 | * Encode support for hardening against various classes of attacks. |
ganlikun | 0:13413ea9a877 | 133 | */ |
ganlikun | 0:13413ea9a877 | 134 | uint32_t software_attacks : 1; ///< device software (malware running on the device). |
ganlikun | 0:13413ea9a877 | 135 | uint32_t board_level_attacks : 1; ///< board level attacks (debug probes, copy protection fuses.) |
ganlikun | 0:13413ea9a877 | 136 | uint32_t chip_level_attacks : 1; ///< chip level attacks (tamper-protection). |
ganlikun | 0:13413ea9a877 | 137 | uint32_t side_channel_attacks : 1; ///< side channel attacks. |
ganlikun | 0:13413ea9a877 | 138 | uint32_t reserved2 : 12; |
ganlikun | 0:13413ea9a877 | 139 | } ARM_STORAGE_SECURITY_FEATURES; |
ganlikun | 0:13413ea9a877 | 140 | |
ganlikun | 0:13413ea9a877 | 141 | #define ARM_STORAGE_PROGRAM_CYCLES_INFINITE (0UL) /**< Infinite or unknown endurance for reprogramming. */ |
ganlikun | 0:13413ea9a877 | 142 | |
ganlikun | 0:13413ea9a877 | 143 | /** |
ganlikun | 0:13413ea9a877 | 144 | * \brief Storage information. This contains device-metadata. It is the return |
ganlikun | 0:13413ea9a877 | 145 | * value from calling GetInfo() on the storage driver. |
ganlikun | 0:13413ea9a877 | 146 | * |
ganlikun | 0:13413ea9a877 | 147 | * \details These fields serve a different purpose than the ones contained in |
ganlikun | 0:13413ea9a877 | 148 | * \ref ARM_STORAGE_CAPABILITIES, which is another structure containing |
ganlikun | 0:13413ea9a877 | 149 | * device-level metadata. ARM_STORAGE_CAPABILITIES describes the API |
ganlikun | 0:13413ea9a877 | 150 | * capabilities, whereas ARM_STORAGE_INFO describes the device. Furthermore |
ganlikun | 0:13413ea9a877 | 151 | * ARM_STORAGE_CAPABILITIES fits within a single word, and is designed to be |
ganlikun | 0:13413ea9a877 | 152 | * passed around by value; ARM_STORAGE_INFO, on the other hand, contains |
ganlikun | 0:13413ea9a877 | 153 | * metadata which doesn't fit into a single word and requires the use of |
ganlikun | 0:13413ea9a877 | 154 | * pointers to be moved around. |
ganlikun | 0:13413ea9a877 | 155 | */ |
ganlikun | 0:13413ea9a877 | 156 | typedef struct _ARM_STORAGE_INFO { |
ganlikun | 0:13413ea9a877 | 157 | uint64_t total_storage; ///< Total available storage, in bytes. |
ganlikun | 0:13413ea9a877 | 158 | uint32_t program_unit; ///< Minimum programming size in bytes. |
ganlikun | 0:13413ea9a877 | 159 | ///< The offset of the start of the program-range should also be aligned with this value. |
ganlikun | 0:13413ea9a877 | 160 | ///< Applicable only if the 'programmable' attribute is set for a block. |
ganlikun | 0:13413ea9a877 | 161 | ///< @note: setting program_unit to 0 has the effect of disabling the size and alignment |
ganlikun | 0:13413ea9a877 | 162 | ///< restrictions (setting it to 1 also has the same effect). |
ganlikun | 0:13413ea9a877 | 163 | uint32_t optimal_program_unit; ///< Optimal programming page-size in bytes. Some storage controllers |
ganlikun | 0:13413ea9a877 | 164 | ///< have internal buffers into which to receive data. Writing in chunks of |
ganlikun | 0:13413ea9a877 | 165 | ///< 'optimal_program_unit' would achieve maximum programming speed. |
ganlikun | 0:13413ea9a877 | 166 | ///< Applicable only if the 'programmable' attribute is set for the underlying block(s). |
ganlikun | 0:13413ea9a877 | 167 | uint32_t program_cycles; ///< A measure of endurance for reprogramming. |
ganlikun | 0:13413ea9a877 | 168 | ///< Use ARM_STORAGE_PROGRAM_CYCLES_INFINITE for infinite or unknown endurance. |
ganlikun | 0:13413ea9a877 | 169 | uint32_t erased_value : 1; ///< Contents of erased memory (usually 1 to indicate erased bytes with state 0xFF). |
ganlikun | 0:13413ea9a877 | 170 | uint32_t memory_mapped : 1; ///< This storage device has a mapping onto the processor's memory address space. |
ganlikun | 0:13413ea9a877 | 171 | ///< @note: For a memory-mapped block which isn't erasable but is programmable (i.e. if |
ganlikun | 0:13413ea9a877 | 172 | ///< 'erasable' is set to 0, but 'programmable' is 1), writes should be possible directly to |
ganlikun | 0:13413ea9a877 | 173 | ///< the memory-mapped storage without going through the ProgramData operation. |
ganlikun | 0:13413ea9a877 | 174 | uint32_t programmability : 4; ///< A value to indicate storage programmability. |
ganlikun | 0:13413ea9a877 | 175 | uint32_t retention_level : 4; |
ganlikun | 0:13413ea9a877 | 176 | uint32_t reserved : 22; |
ganlikun | 0:13413ea9a877 | 177 | ARM_STORAGE_SECURITY_FEATURES security; ///< \ref ARM_STORAGE_SECURITY_FEATURES |
ganlikun | 0:13413ea9a877 | 178 | } ARM_STORAGE_INFO; |
ganlikun | 0:13413ea9a877 | 179 | |
ganlikun | 0:13413ea9a877 | 180 | /** |
ganlikun | 0:13413ea9a877 | 181 | \brief Operating status of the storage controller. |
ganlikun | 0:13413ea9a877 | 182 | */ |
ganlikun | 0:13413ea9a877 | 183 | typedef struct _ARM_STORAGE_STATUS { |
ganlikun | 0:13413ea9a877 | 184 | uint32_t busy : 1; ///< Controller busy flag |
ganlikun | 0:13413ea9a877 | 185 | uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) |
ganlikun | 0:13413ea9a877 | 186 | } ARM_STORAGE_STATUS; |
ganlikun | 0:13413ea9a877 | 187 | |
ganlikun | 0:13413ea9a877 | 188 | /** |
ganlikun | 0:13413ea9a877 | 189 | * \brief Storage Driver API Capabilities. |
ganlikun | 0:13413ea9a877 | 190 | * |
ganlikun | 0:13413ea9a877 | 191 | * This data structure is designed to fit within a single word so that it can be |
ganlikun | 0:13413ea9a877 | 192 | * fetched cheaply using a call to driver->GetCapabilities(). |
ganlikun | 0:13413ea9a877 | 193 | */ |
ganlikun | 0:13413ea9a877 | 194 | typedef struct _ARM_STORAGE_CAPABILITIES { |
ganlikun | 0:13413ea9a877 | 195 | uint32_t asynchronous_ops : 1; ///< Used to indicate if APIs like initialize, |
ganlikun | 0:13413ea9a877 | 196 | ///< read, erase, program, etc. can operate in asynchronous mode. |
ganlikun | 0:13413ea9a877 | 197 | ///< Setting this bit to 1 means that the driver is capable |
ganlikun | 0:13413ea9a877 | 198 | ///< of launching asynchronous operations; command completion is |
ganlikun | 0:13413ea9a877 | 199 | ///< signaled by the invocation of a completion callback. If |
ganlikun | 0:13413ea9a877 | 200 | ///< set to 1, drivers may still complete asynchronous |
ganlikun | 0:13413ea9a877 | 201 | ///< operations synchronously as necessary--in which case they |
ganlikun | 0:13413ea9a877 | 202 | ///< return a positive error code to indicate synchronous completion. |
ganlikun | 0:13413ea9a877 | 203 | uint32_t erase_all : 1; ///< Supports EraseAll operation. |
ganlikun | 0:13413ea9a877 | 204 | uint32_t reserved : 30; |
ganlikun | 0:13413ea9a877 | 205 | } ARM_STORAGE_CAPABILITIES; |
ganlikun | 0:13413ea9a877 | 206 | |
ganlikun | 0:13413ea9a877 | 207 | /** |
ganlikun | 0:13413ea9a877 | 208 | * Command opcodes for Storage. Completion callbacks use these codes to refer to |
ganlikun | 0:13413ea9a877 | 209 | * completing commands. Refer to \ref ARM_Storage_Callback_t. |
ganlikun | 0:13413ea9a877 | 210 | */ |
ganlikun | 0:13413ea9a877 | 211 | typedef enum _ARM_STORAGE_OPERATION { |
ganlikun | 0:13413ea9a877 | 212 | ARM_STORAGE_OPERATION_GET_VERSION, |
ganlikun | 0:13413ea9a877 | 213 | ARM_STORAGE_OPERATION_GET_CAPABILITIES, |
ganlikun | 0:13413ea9a877 | 214 | ARM_STORAGE_OPERATION_INITIALIZE, |
ganlikun | 0:13413ea9a877 | 215 | ARM_STORAGE_OPERATION_UNINITIALIZE, |
ganlikun | 0:13413ea9a877 | 216 | ARM_STORAGE_OPERATION_POWER_CONTROL, |
ganlikun | 0:13413ea9a877 | 217 | ARM_STORAGE_OPERATION_READ_DATA, |
ganlikun | 0:13413ea9a877 | 218 | ARM_STORAGE_OPERATION_PROGRAM_DATA, |
ganlikun | 0:13413ea9a877 | 219 | ARM_STORAGE_OPERATION_ERASE, |
ganlikun | 0:13413ea9a877 | 220 | ARM_STORAGE_OPERATION_ERASE_ALL, |
ganlikun | 0:13413ea9a877 | 221 | ARM_STORAGE_OPERATION_GET_STATUS, |
ganlikun | 0:13413ea9a877 | 222 | ARM_STORAGE_OPERATION_GET_INFO, |
ganlikun | 0:13413ea9a877 | 223 | ARM_STORAGE_OPERATION_RESOLVE_ADDRESS, |
ganlikun | 0:13413ea9a877 | 224 | ARM_STORAGE_OPERATION_GET_NEXT_BLOCK, |
ganlikun | 0:13413ea9a877 | 225 | ARM_STORAGE_OPERATION_GET_BLOCK |
ganlikun | 0:13413ea9a877 | 226 | } ARM_STORAGE_OPERATION; |
ganlikun | 0:13413ea9a877 | 227 | |
ganlikun | 0:13413ea9a877 | 228 | /** |
ganlikun | 0:13413ea9a877 | 229 | * Declaration of the callback-type for command completion. |
ganlikun | 0:13413ea9a877 | 230 | * |
ganlikun | 0:13413ea9a877 | 231 | * @param [in] status |
ganlikun | 0:13413ea9a877 | 232 | * A code to indicate the status of the completed operation. For data |
ganlikun | 0:13413ea9a877 | 233 | * transfer operations, the status field is overloaded in case of |
ganlikun | 0:13413ea9a877 | 234 | * success to return the count of items successfully transferred; this |
ganlikun | 0:13413ea9a877 | 235 | * can be done safely because error codes are negative values. |
ganlikun | 0:13413ea9a877 | 236 | * |
ganlikun | 0:13413ea9a877 | 237 | * @param [in] operation |
ganlikun | 0:13413ea9a877 | 238 | * The command op-code. This value isn't essential for the callback in |
ganlikun | 0:13413ea9a877 | 239 | * the presence of the command instance-id, but it is expected that |
ganlikun | 0:13413ea9a877 | 240 | * this information could be a quick and useful filter. |
ganlikun | 0:13413ea9a877 | 241 | */ |
ganlikun | 0:13413ea9a877 | 242 | typedef void (*ARM_Storage_Callback_t)(int32_t status, ARM_STORAGE_OPERATION operation); |
ganlikun | 0:13413ea9a877 | 243 | |
ganlikun | 0:13413ea9a877 | 244 | /** |
ganlikun | 0:13413ea9a877 | 245 | * This is the set of operations constituting the Storage driver. Their |
ganlikun | 0:13413ea9a877 | 246 | * implementation is platform-specific, and needs to be supplied by the |
ganlikun | 0:13413ea9a877 | 247 | * porting effort. |
ganlikun | 0:13413ea9a877 | 248 | * |
ganlikun | 0:13413ea9a877 | 249 | * Some APIs within `ARM_DRIVER_STORAGE` will always operate synchronously: |
ganlikun | 0:13413ea9a877 | 250 | * GetVersion, GetCapabilities, GetStatus, GetInfo, ResolveAddress, |
ganlikun | 0:13413ea9a877 | 251 | * GetNextBlock, and GetBlock. This means that control returns to the caller |
ganlikun | 0:13413ea9a877 | 252 | * with a relevant status code only after the completion of the operation (or |
ganlikun | 0:13413ea9a877 | 253 | * the discovery of a failure condition). |
ganlikun | 0:13413ea9a877 | 254 | * |
ganlikun | 0:13413ea9a877 | 255 | * The remainder of the APIs: Initialize, Uninitialize, PowerControl, ReadData, |
ganlikun | 0:13413ea9a877 | 256 | * ProgramData, Erase, EraseAll, can function asynchronously if the underlying |
ganlikun | 0:13413ea9a877 | 257 | * controller supports it--i.e. if ARM_STORAGE_CAPABILITIES::asynchronous_ops is |
ganlikun | 0:13413ea9a877 | 258 | * set. In the case of asynchronous operation, the invocation returns early |
ganlikun | 0:13413ea9a877 | 259 | * (with ARM_DRIVER_OK) and results in a completion callback later. If |
ganlikun | 0:13413ea9a877 | 260 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is not set, then all such APIs |
ganlikun | 0:13413ea9a877 | 261 | * execute synchronously, and control returns to the caller with a status code |
ganlikun | 0:13413ea9a877 | 262 | * only after the completion of the operation (or the discovery of a failure |
ganlikun | 0:13413ea9a877 | 263 | * condition). |
ganlikun | 0:13413ea9a877 | 264 | * |
ganlikun | 0:13413ea9a877 | 265 | * If ARM_STORAGE_CAPABILITIES::asynchronous_ops is set, a storage driver may |
ganlikun | 0:13413ea9a877 | 266 | * still choose to execute asynchronous operations in a synchronous manner. If |
ganlikun | 0:13413ea9a877 | 267 | * so, the driver returns a positive value to indicate successful synchronous |
ganlikun | 0:13413ea9a877 | 268 | * completion (or an error code in case of failure) and no further invocation of |
ganlikun | 0:13413ea9a877 | 269 | * completion callback should be expected. The expected return value for |
ganlikun | 0:13413ea9a877 | 270 | * synchronous completion of such asynchronous operations varies depending on |
ganlikun | 0:13413ea9a877 | 271 | * the operation. For operations involving data access, it often equals the |
ganlikun | 0:13413ea9a877 | 272 | * amount of data transferred or affected. For non data-transfer operations, |
ganlikun | 0:13413ea9a877 | 273 | * such as EraseAll or Initialize, it is usually 1. |
ganlikun | 0:13413ea9a877 | 274 | * |
ganlikun | 0:13413ea9a877 | 275 | * Here's a code snippet to suggest how asynchronous APIs might be used by |
ganlikun | 0:13413ea9a877 | 276 | * callers to handle both synchronous and asynchronous execution by the |
ganlikun | 0:13413ea9a877 | 277 | * underlying storage driver: |
ganlikun | 0:13413ea9a877 | 278 | * \code |
ganlikun | 0:13413ea9a877 | 279 | * ASSERT(ARM_DRIVER_OK == 0); // this is a precondition; it doesn't need to be put in code |
ganlikun | 0:13413ea9a877 | 280 | * int32_t returnValue = drv->asynchronousAPI(...); |
ganlikun | 0:13413ea9a877 | 281 | * if (returnValue < ARM_DRIVER_OK) { |
ganlikun | 0:13413ea9a877 | 282 | * // handle error. |
ganlikun | 0:13413ea9a877 | 283 | * } else if (returnValue == ARM_DRIVER_OK) { |
ganlikun | 0:13413ea9a877 | 284 | * ASSERT(drv->GetCapabilities().asynchronous_ops == 1); |
ganlikun | 0:13413ea9a877 | 285 | * // handle early return from asynchronous execution; remainder of the work is done in the callback handler. |
ganlikun | 0:13413ea9a877 | 286 | * } else { |
ganlikun | 0:13413ea9a877 | 287 | * ASSERT(returnValue == EXPECTED_RETURN_VALUE_FOR_SYNCHRONOUS_COMPLETION); |
ganlikun | 0:13413ea9a877 | 288 | * // handle synchronous completion. |
ganlikun | 0:13413ea9a877 | 289 | * } |
ganlikun | 0:13413ea9a877 | 290 | * \endcode |
ganlikun | 0:13413ea9a877 | 291 | */ |
ganlikun | 0:13413ea9a877 | 292 | typedef struct _ARM_DRIVER_STORAGE { |
ganlikun | 0:13413ea9a877 | 293 | /** |
ganlikun | 0:13413ea9a877 | 294 | * \brief Get driver version. |
ganlikun | 0:13413ea9a877 | 295 | * |
ganlikun | 0:13413ea9a877 | 296 | * The function GetVersion() returns version information of the driver implementation in ARM_DRIVER_VERSION. |
ganlikun | 0:13413ea9a877 | 297 | * |
ganlikun | 0:13413ea9a877 | 298 | * - API version is the version of the CMSIS-Driver specification used to implement this driver. |
ganlikun | 0:13413ea9a877 | 299 | * - Driver version is source code version of the actual driver implementation. |
ganlikun | 0:13413ea9a877 | 300 | * |
ganlikun | 0:13413ea9a877 | 301 | * Example: |
ganlikun | 0:13413ea9a877 | 302 | * \code |
ganlikun | 0:13413ea9a877 | 303 | * extern ARM_DRIVER_STORAGE *drv_info; |
ganlikun | 0:13413ea9a877 | 304 | * |
ganlikun | 0:13413ea9a877 | 305 | * void read_version (void) { |
ganlikun | 0:13413ea9a877 | 306 | * ARM_DRIVER_VERSION version; |
ganlikun | 0:13413ea9a877 | 307 | * |
ganlikun | 0:13413ea9a877 | 308 | * version = drv_info->GetVersion (); |
ganlikun | 0:13413ea9a877 | 309 | * if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher |
ganlikun | 0:13413ea9a877 | 310 | * // error handling |
ganlikun | 0:13413ea9a877 | 311 | * return; |
ganlikun | 0:13413ea9a877 | 312 | * } |
ganlikun | 0:13413ea9a877 | 313 | * } |
ganlikun | 0:13413ea9a877 | 314 | * \endcode |
ganlikun | 0:13413ea9a877 | 315 | * |
ganlikun | 0:13413ea9a877 | 316 | * @return \ref ARM_DRIVER_VERSION. |
ganlikun | 0:13413ea9a877 | 317 | * |
ganlikun | 0:13413ea9a877 | 318 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 319 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 320 | * |
ganlikun | 0:13413ea9a877 | 321 | * @note The function GetVersion() can be called any time to obtain the |
ganlikun | 0:13413ea9a877 | 322 | * required information from the driver (even before initialization). It |
ganlikun | 0:13413ea9a877 | 323 | * always returns the same information. |
ganlikun | 0:13413ea9a877 | 324 | */ |
ganlikun | 0:13413ea9a877 | 325 | ARM_DRIVER_VERSION (*GetVersion)(void); |
ganlikun | 0:13413ea9a877 | 326 | |
ganlikun | 0:13413ea9a877 | 327 | /** |
ganlikun | 0:13413ea9a877 | 328 | * \brief Get driver capabilities. |
ganlikun | 0:13413ea9a877 | 329 | * |
ganlikun | 0:13413ea9a877 | 330 | * \details The function GetCapabilities() returns information about |
ganlikun | 0:13413ea9a877 | 331 | * capabilities in this driver implementation. The data fields of the struct |
ganlikun | 0:13413ea9a877 | 332 | * ARM_STORAGE_CAPABILITIES encode various capabilities, for example if the device |
ganlikun | 0:13413ea9a877 | 333 | * is able to execute operations asynchronously. |
ganlikun | 0:13413ea9a877 | 334 | * |
ganlikun | 0:13413ea9a877 | 335 | * Example: |
ganlikun | 0:13413ea9a877 | 336 | * \code |
ganlikun | 0:13413ea9a877 | 337 | * extern ARM_DRIVER_STORAGE *drv_info; |
ganlikun | 0:13413ea9a877 | 338 | * |
ganlikun | 0:13413ea9a877 | 339 | * void read_capabilities (void) { |
ganlikun | 0:13413ea9a877 | 340 | * ARM_STORAGE_CAPABILITIES drv_capabilities; |
ganlikun | 0:13413ea9a877 | 341 | * |
ganlikun | 0:13413ea9a877 | 342 | * drv_capabilities = drv_info->GetCapabilities (); |
ganlikun | 0:13413ea9a877 | 343 | * // interrogate capabilities |
ganlikun | 0:13413ea9a877 | 344 | * |
ganlikun | 0:13413ea9a877 | 345 | * } |
ganlikun | 0:13413ea9a877 | 346 | * \endcode |
ganlikun | 0:13413ea9a877 | 347 | * |
ganlikun | 0:13413ea9a877 | 348 | * @return \ref ARM_STORAGE_CAPABILITIES. |
ganlikun | 0:13413ea9a877 | 349 | * |
ganlikun | 0:13413ea9a877 | 350 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 351 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 352 | * |
ganlikun | 0:13413ea9a877 | 353 | * @note The function GetCapabilities() can be called any time to obtain the |
ganlikun | 0:13413ea9a877 | 354 | * required information from the driver (even before initialization). It |
ganlikun | 0:13413ea9a877 | 355 | * always returns the same information. |
ganlikun | 0:13413ea9a877 | 356 | */ |
ganlikun | 0:13413ea9a877 | 357 | ARM_STORAGE_CAPABILITIES (*GetCapabilities)(void); |
ganlikun | 0:13413ea9a877 | 358 | |
ganlikun | 0:13413ea9a877 | 359 | /** |
ganlikun | 0:13413ea9a877 | 360 | * \brief Initialize the Storage Interface. |
ganlikun | 0:13413ea9a877 | 361 | * |
ganlikun | 0:13413ea9a877 | 362 | * The function Initialize is called when the middleware component starts |
ganlikun | 0:13413ea9a877 | 363 | * operation. In addition to bringing the controller to a ready state, |
ganlikun | 0:13413ea9a877 | 364 | * Initialize() receives a callback handler to be invoked upon completion of |
ganlikun | 0:13413ea9a877 | 365 | * asynchronous operations. |
ganlikun | 0:13413ea9a877 | 366 | * |
ganlikun | 0:13413ea9a877 | 367 | * Initialize() needs to be called explicitly before |
ganlikun | 0:13413ea9a877 | 368 | * powering the peripheral using PowerControl(), and before initiating other |
ganlikun | 0:13413ea9a877 | 369 | * accesses to the storage controller. |
ganlikun | 0:13413ea9a877 | 370 | * |
ganlikun | 0:13413ea9a877 | 371 | * The function performs the following operations: |
ganlikun | 0:13413ea9a877 | 372 | * - Initializes the resources needed for the Storage interface. |
ganlikun | 0:13413ea9a877 | 373 | * - Registers the \ref ARM_Storage_Callback_t callback function. |
ganlikun | 0:13413ea9a877 | 374 | * |
ganlikun | 0:13413ea9a877 | 375 | * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: |
ganlikun | 0:13413ea9a877 | 376 | * drv->Initialize (...); // Allocate I/O pins |
ganlikun | 0:13413ea9a877 | 377 | * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA |
ganlikun | 0:13413ea9a877 | 378 | * |
ganlikun | 0:13413ea9a877 | 379 | * - Initialize() typically allocates the I/O resources (pins) for the |
ganlikun | 0:13413ea9a877 | 380 | * peripheral. The function can be called multiple times; if the I/O resources |
ganlikun | 0:13413ea9a877 | 381 | * are already initialized it performs no operation and just returns with |
ganlikun | 0:13413ea9a877 | 382 | * ARM_DRIVER_OK. |
ganlikun | 0:13413ea9a877 | 383 | * |
ganlikun | 0:13413ea9a877 | 384 | * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including |
ganlikun | 0:13413ea9a877 | 385 | * interrupt (NVIC) and optionally DMA. The function can be called multiple |
ganlikun | 0:13413ea9a877 | 386 | * times; if the registers are already set it performs no operation and just |
ganlikun | 0:13413ea9a877 | 387 | * returns with ARM_DRIVER_OK. |
ganlikun | 0:13413ea9a877 | 388 | * |
ganlikun | 0:13413ea9a877 | 389 | * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: |
ganlikun | 0:13413ea9a877 | 390 | * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral |
ganlikun | 0:13413ea9a877 | 391 | * drv->Uninitialize (...); // Release I/O pins |
ganlikun | 0:13413ea9a877 | 392 | * |
ganlikun | 0:13413ea9a877 | 393 | * The functions PowerControl and Uninitialize always execute and can be used |
ganlikun | 0:13413ea9a877 | 394 | * to put the peripheral into a Safe State, for example after any data |
ganlikun | 0:13413ea9a877 | 395 | * transmission errors. To restart the peripheral in an error condition, |
ganlikun | 0:13413ea9a877 | 396 | * you should first execute the Stop Sequence and then the Start Sequence. |
ganlikun | 0:13413ea9a877 | 397 | * |
ganlikun | 0:13413ea9a877 | 398 | * @param [in] callback |
ganlikun | 0:13413ea9a877 | 399 | * Caller-defined callback to be invoked upon command completion |
ganlikun | 0:13413ea9a877 | 400 | * for asynchronous APIs (including the completion of |
ganlikun | 0:13413ea9a877 | 401 | * initialization). Use a NULL pointer when no callback |
ganlikun | 0:13413ea9a877 | 402 | * signals are required. |
ganlikun | 0:13413ea9a877 | 403 | * |
ganlikun | 0:13413ea9a877 | 404 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 405 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 406 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 407 | * |
ganlikun | 0:13413ea9a877 | 408 | * @return If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 409 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 410 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
ganlikun | 0:13413ea9a877 | 411 | * case of synchronous execution, control returns after completion with a |
ganlikun | 0:13413ea9a877 | 412 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 413 | */ |
ganlikun | 0:13413ea9a877 | 414 | int32_t (*Initialize)(ARM_Storage_Callback_t callback); |
ganlikun | 0:13413ea9a877 | 415 | |
ganlikun | 0:13413ea9a877 | 416 | /** |
ganlikun | 0:13413ea9a877 | 417 | * \brief De-initialize the Storage Interface. |
ganlikun | 0:13413ea9a877 | 418 | * |
ganlikun | 0:13413ea9a877 | 419 | * The function Uninitialize() de-initializes the resources of Storage interface. |
ganlikun | 0:13413ea9a877 | 420 | * |
ganlikun | 0:13413ea9a877 | 421 | * It is called when the middleware component stops operation, and wishes to |
ganlikun | 0:13413ea9a877 | 422 | * release the software resources used by the interface. |
ganlikun | 0:13413ea9a877 | 423 | * |
ganlikun | 0:13413ea9a877 | 424 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 425 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 426 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 427 | * |
ganlikun | 0:13413ea9a877 | 428 | * @return If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 429 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 430 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
ganlikun | 0:13413ea9a877 | 431 | * case of synchronous execution, control returns after completion with a |
ganlikun | 0:13413ea9a877 | 432 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 433 | */ |
ganlikun | 0:13413ea9a877 | 434 | int32_t (*Uninitialize)(void); |
ganlikun | 0:13413ea9a877 | 435 | |
ganlikun | 0:13413ea9a877 | 436 | /** |
ganlikun | 0:13413ea9a877 | 437 | * \brief Control the Storage interface power. |
ganlikun | 0:13413ea9a877 | 438 | * |
ganlikun | 0:13413ea9a877 | 439 | * The function \b ARM_Storage_PowerControl operates the power modes of the Storage interface. |
ganlikun | 0:13413ea9a877 | 440 | * |
ganlikun | 0:13413ea9a877 | 441 | * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: |
ganlikun | 0:13413ea9a877 | 442 | * drv->Initialize (...); // Allocate I/O pins |
ganlikun | 0:13413ea9a877 | 443 | * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA |
ganlikun | 0:13413ea9a877 | 444 | * |
ganlikun | 0:13413ea9a877 | 445 | * - Initialize() typically allocates the I/O resources (pins) for the |
ganlikun | 0:13413ea9a877 | 446 | * peripheral. The function can be called multiple times; if the I/O resources |
ganlikun | 0:13413ea9a877 | 447 | * are already initialized it performs no operation and just returns with |
ganlikun | 0:13413ea9a877 | 448 | * ARM_DRIVER_OK. |
ganlikun | 0:13413ea9a877 | 449 | * |
ganlikun | 0:13413ea9a877 | 450 | * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including |
ganlikun | 0:13413ea9a877 | 451 | * interrupt (NVIC) and optionally DMA. The function can be called multiple |
ganlikun | 0:13413ea9a877 | 452 | * times; if the registers are already set it performs no operation and just |
ganlikun | 0:13413ea9a877 | 453 | * returns with ARM_DRIVER_OK. |
ganlikun | 0:13413ea9a877 | 454 | * |
ganlikun | 0:13413ea9a877 | 455 | * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: |
ganlikun | 0:13413ea9a877 | 456 | * |
ganlikun | 0:13413ea9a877 | 457 | * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral |
ganlikun | 0:13413ea9a877 | 458 | * drv->Uninitialize (...); // Release I/O pins |
ganlikun | 0:13413ea9a877 | 459 | * |
ganlikun | 0:13413ea9a877 | 460 | * The functions PowerControl and Uninitialize always execute and can be used |
ganlikun | 0:13413ea9a877 | 461 | * to put the peripheral into a Safe State, for example after any data |
ganlikun | 0:13413ea9a877 | 462 | * transmission errors. To restart the peripheral in an error condition, |
ganlikun | 0:13413ea9a877 | 463 | * you should first execute the Stop Sequence and then the Start Sequence. |
ganlikun | 0:13413ea9a877 | 464 | * |
ganlikun | 0:13413ea9a877 | 465 | * @param state |
ganlikun | 0:13413ea9a877 | 466 | * \ref ARM_POWER_STATE. The target power-state for the storage controller. |
ganlikun | 0:13413ea9a877 | 467 | * The parameter state can have the following values: |
ganlikun | 0:13413ea9a877 | 468 | * - ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts |
ganlikun | 0:13413ea9a877 | 469 | * (NVIC) and optionally DMA. Can be called multiple times. If the peripheral |
ganlikun | 0:13413ea9a877 | 470 | * is already in this mode, then the function performs no operation and returns |
ganlikun | 0:13413ea9a877 | 471 | * with ARM_DRIVER_OK. |
ganlikun | 0:13413ea9a877 | 472 | * - ARM_POWER_LOW : may use power saving. Returns ARM_DRIVER_ERROR_UNSUPPORTED when not implemented. |
ganlikun | 0:13413ea9a877 | 473 | * - ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA. |
ganlikun | 0:13413ea9a877 | 474 | * |
ganlikun | 0:13413ea9a877 | 475 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 476 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 477 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 478 | * |
ganlikun | 0:13413ea9a877 | 479 | * @return If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 480 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 481 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
ganlikun | 0:13413ea9a877 | 482 | * case of synchronous execution, control returns after completion with a |
ganlikun | 0:13413ea9a877 | 483 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 484 | */ |
ganlikun | 0:13413ea9a877 | 485 | int32_t (*PowerControl)(ARM_POWER_STATE state); |
ganlikun | 0:13413ea9a877 | 486 | |
ganlikun | 0:13413ea9a877 | 487 | /** |
ganlikun | 0:13413ea9a877 | 488 | * \brief read the contents of a given address range from the storage device. |
ganlikun | 0:13413ea9a877 | 489 | * |
ganlikun | 0:13413ea9a877 | 490 | * \details Read the contents of a range of storage memory into a buffer |
ganlikun | 0:13413ea9a877 | 491 | * supplied by the caller. The buffer is owned by the caller and should |
ganlikun | 0:13413ea9a877 | 492 | * remain accessible for the lifetime of this command. |
ganlikun | 0:13413ea9a877 | 493 | * |
ganlikun | 0:13413ea9a877 | 494 | * @param [in] addr |
ganlikun | 0:13413ea9a877 | 495 | * This specifies the address from where to read data. |
ganlikun | 0:13413ea9a877 | 496 | * |
ganlikun | 0:13413ea9a877 | 497 | * @param [out] data |
ganlikun | 0:13413ea9a877 | 498 | * The destination of the read operation. The buffer |
ganlikun | 0:13413ea9a877 | 499 | * is owned by the caller and should remain accessible for the |
ganlikun | 0:13413ea9a877 | 500 | * lifetime of this command. |
ganlikun | 0:13413ea9a877 | 501 | * |
ganlikun | 0:13413ea9a877 | 502 | * @param [in] size |
ganlikun | 0:13413ea9a877 | 503 | * The number of bytes requested to read. The data buffer |
ganlikun | 0:13413ea9a877 | 504 | * should be at least as large as this size. |
ganlikun | 0:13413ea9a877 | 505 | * |
ganlikun | 0:13413ea9a877 | 506 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 507 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 508 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 509 | * |
ganlikun | 0:13413ea9a877 | 510 | * @return If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 511 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 512 | * future with the number of successfully transferred bytes passed in as |
ganlikun | 0:13413ea9a877 | 513 | * the 'status' parameter. In the case of synchronous execution, control |
ganlikun | 0:13413ea9a877 | 514 | * returns after completion with a positive transfer-count. Return values |
ganlikun | 0:13413ea9a877 | 515 | * less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 516 | */ |
ganlikun | 0:13413ea9a877 | 517 | int32_t (*ReadData)(uint64_t addr, void *data, uint32_t size); |
ganlikun | 0:13413ea9a877 | 518 | |
ganlikun | 0:13413ea9a877 | 519 | /** |
ganlikun | 0:13413ea9a877 | 520 | * \brief program (write into) the contents of a given address range of the storage device. |
ganlikun | 0:13413ea9a877 | 521 | * |
ganlikun | 0:13413ea9a877 | 522 | * \details Write the contents of a given memory buffer into a range of |
ganlikun | 0:13413ea9a877 | 523 | * storage memory. In the case of flash memory, the destination range in |
ganlikun | 0:13413ea9a877 | 524 | * storage memory typically has its contents in an erased state from a |
ganlikun | 0:13413ea9a877 | 525 | * preceding erase operation. The source memory buffer is owned by the |
ganlikun | 0:13413ea9a877 | 526 | * caller and should remain accessible for the lifetime of this command. |
ganlikun | 0:13413ea9a877 | 527 | * |
ganlikun | 0:13413ea9a877 | 528 | * @param [in] addr |
ganlikun | 0:13413ea9a877 | 529 | * This is the start address of the range to be written into. It |
ganlikun | 0:13413ea9a877 | 530 | * needs to be aligned to the device's \em program_unit |
ganlikun | 0:13413ea9a877 | 531 | * specified in \ref ARM_STORAGE_INFO. |
ganlikun | 0:13413ea9a877 | 532 | * |
ganlikun | 0:13413ea9a877 | 533 | * @param [in] data |
ganlikun | 0:13413ea9a877 | 534 | * The source of the write operation. The buffer is owned by the |
ganlikun | 0:13413ea9a877 | 535 | * caller and should remain accessible for the lifetime of this |
ganlikun | 0:13413ea9a877 | 536 | * command. |
ganlikun | 0:13413ea9a877 | 537 | * |
ganlikun | 0:13413ea9a877 | 538 | * @param [in] size |
ganlikun | 0:13413ea9a877 | 539 | * The number of bytes requested to be written. The buffer |
ganlikun | 0:13413ea9a877 | 540 | * should be at least as large as this size. \note 'size' should |
ganlikun | 0:13413ea9a877 | 541 | * be a multiple of the device's 'program_unit' (see \ref |
ganlikun | 0:13413ea9a877 | 542 | * ARM_STORAGE_INFO). |
ganlikun | 0:13413ea9a877 | 543 | * |
ganlikun | 0:13413ea9a877 | 544 | * @note It is best for the middleware to write in units of |
ganlikun | 0:13413ea9a877 | 545 | * 'optimal_program_unit' (\ref ARM_STORAGE_INFO) of the device. |
ganlikun | 0:13413ea9a877 | 546 | * |
ganlikun | 0:13413ea9a877 | 547 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 548 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 549 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 550 | * |
ganlikun | 0:13413ea9a877 | 551 | * @return If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 552 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 553 | * future with the number of successfully transferred bytes passed in as |
ganlikun | 0:13413ea9a877 | 554 | * the 'status' parameter. In the case of synchronous execution, control |
ganlikun | 0:13413ea9a877 | 555 | * returns after completion with a positive transfer-count. Return values |
ganlikun | 0:13413ea9a877 | 556 | * less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 557 | */ |
ganlikun | 0:13413ea9a877 | 558 | int32_t (*ProgramData)(uint64_t addr, const void *data, uint32_t size); |
ganlikun | 0:13413ea9a877 | 559 | |
ganlikun | 0:13413ea9a877 | 560 | /** |
ganlikun | 0:13413ea9a877 | 561 | * @brief Erase Storage range. |
ganlikun | 0:13413ea9a877 | 562 | * |
ganlikun | 0:13413ea9a877 | 563 | * @details This function erases a range of storage specified by [addr, addr + |
ganlikun | 0:13413ea9a877 | 564 | * size). Both 'addr' and 'addr + size' should align with the |
ganlikun | 0:13413ea9a877 | 565 | * 'erase_unit'(s) of the respective owning storage block(s) (see \ref |
ganlikun | 0:13413ea9a877 | 566 | * ARM_STORAGE_BLOCK and \ref ARM_STORAGE_BLOCK_ATTRIBUTES). The range to |
ganlikun | 0:13413ea9a877 | 567 | * be erased will have its contents returned to the un-programmed state-- |
ganlikun | 0:13413ea9a877 | 568 | * i.e. to 'erased_value' (see \ref ARM_STORAGE_BLOCK_ATTRIBUTES), which |
ganlikun | 0:13413ea9a877 | 569 | * is usually 1 to indicate the pattern of all ones: 0xFF. |
ganlikun | 0:13413ea9a877 | 570 | * |
ganlikun | 0:13413ea9a877 | 571 | * @param [in] addr |
ganlikun | 0:13413ea9a877 | 572 | * This is the start-address of the range to be erased. It must |
ganlikun | 0:13413ea9a877 | 573 | * start at an 'erase_unit' boundary of the underlying block. |
ganlikun | 0:13413ea9a877 | 574 | * |
ganlikun | 0:13413ea9a877 | 575 | * @param [in] size |
ganlikun | 0:13413ea9a877 | 576 | * Size (in bytes) of the range to be erased. 'addr + size' |
ganlikun | 0:13413ea9a877 | 577 | * must be aligned with the 'erase_unit' of the underlying |
ganlikun | 0:13413ea9a877 | 578 | * block. |
ganlikun | 0:13413ea9a877 | 579 | * |
ganlikun | 0:13413ea9a877 | 580 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 581 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 582 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 583 | * |
ganlikun | 0:13413ea9a877 | 584 | * @return |
ganlikun | 0:13413ea9a877 | 585 | * If the range to be erased doesn't align with the erase_units of the |
ganlikun | 0:13413ea9a877 | 586 | * respective start and end blocks, ARM_DRIVER_ERROR_PARAMETER is returned. |
ganlikun | 0:13413ea9a877 | 587 | * If any part of the range is protected, ARM_STORAGE_ERROR_PROTECTED is |
ganlikun | 0:13413ea9a877 | 588 | * returned. If any part of the range is not erasable, |
ganlikun | 0:13413ea9a877 | 589 | * ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All such sanity-check |
ganlikun | 0:13413ea9a877 | 590 | * failures result in the error code being returned synchronously and the |
ganlikun | 0:13413ea9a877 | 591 | * storage bytes within the range remain unaffected. |
ganlikun | 0:13413ea9a877 | 592 | * Otherwise the function executes in the following ways: |
ganlikun | 0:13413ea9a877 | 593 | * If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 594 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 595 | * future with the number of successfully erased bytes passed in as |
ganlikun | 0:13413ea9a877 | 596 | * the 'status' parameter. In the case of synchronous execution, control |
ganlikun | 0:13413ea9a877 | 597 | * returns after completion with a positive erase-count. Return values |
ganlikun | 0:13413ea9a877 | 598 | * less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 599 | * |
ganlikun | 0:13413ea9a877 | 600 | * @note Erase() may return a smaller (positive) value than the size of the |
ganlikun | 0:13413ea9a877 | 601 | * requested range. The returned value indicates the actual number of bytes |
ganlikun | 0:13413ea9a877 | 602 | * erased. It is the caller's responsibility to follow up with an appropriate |
ganlikun | 0:13413ea9a877 | 603 | * request to complete the operation. |
ganlikun | 0:13413ea9a877 | 604 | * |
ganlikun | 0:13413ea9a877 | 605 | * @note in the case of a failed erase (except when |
ganlikun | 0:13413ea9a877 | 606 | * ARM_DRIVER_ERROR_PARAMETER, ARM_STORAGE_ERROR_PROTECTED, or |
ganlikun | 0:13413ea9a877 | 607 | * ARM_STORAGE_ERROR_NOT_ERASABLE is returned synchronously), the |
ganlikun | 0:13413ea9a877 | 608 | * requested range should be assumed to be in an unknown state. The |
ganlikun | 0:13413ea9a877 | 609 | * previous contents may not be retained. |
ganlikun | 0:13413ea9a877 | 610 | */ |
ganlikun | 0:13413ea9a877 | 611 | int32_t (*Erase)(uint64_t addr, uint32_t size); |
ganlikun | 0:13413ea9a877 | 612 | |
ganlikun | 0:13413ea9a877 | 613 | /** |
ganlikun | 0:13413ea9a877 | 614 | * @brief Erase complete storage. Optional function for faster erase of the complete device. |
ganlikun | 0:13413ea9a877 | 615 | * |
ganlikun | 0:13413ea9a877 | 616 | * This optional function erases the complete device. If the device does not |
ganlikun | 0:13413ea9a877 | 617 | * support global erase then the function returns the error value \ref |
ganlikun | 0:13413ea9a877 | 618 | * ARM_DRIVER_ERROR_UNSUPPORTED. The data field \em 'erase_all' = 1 |
ganlikun | 0:13413ea9a877 | 619 | * of the structure \ref ARM_STORAGE_CAPABILITIES encodes that |
ganlikun | 0:13413ea9a877 | 620 | * ARM_STORAGE_EraseAll is supported. |
ganlikun | 0:13413ea9a877 | 621 | * |
ganlikun | 0:13413ea9a877 | 622 | * @note This API may execute asynchronously if |
ganlikun | 0:13413ea9a877 | 623 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
ganlikun | 0:13413ea9a877 | 624 | * execution is optional even if 'asynchronous_ops' is set. |
ganlikun | 0:13413ea9a877 | 625 | * |
ganlikun | 0:13413ea9a877 | 626 | * @return |
ganlikun | 0:13413ea9a877 | 627 | * If any part of the storage range is protected, |
ganlikun | 0:13413ea9a877 | 628 | * ARM_STORAGE_ERROR_PROTECTED is returned. If any part of the storage |
ganlikun | 0:13413ea9a877 | 629 | * range is not erasable, ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All |
ganlikun | 0:13413ea9a877 | 630 | * such sanity-check failures result in the error code being returned |
ganlikun | 0:13413ea9a877 | 631 | * synchronously and the storage bytes within the range remain unaffected. |
ganlikun | 0:13413ea9a877 | 632 | * Otherwise the function executes in the following ways: |
ganlikun | 0:13413ea9a877 | 633 | * If asynchronous activity is launched, an invocation returns |
ganlikun | 0:13413ea9a877 | 634 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
ganlikun | 0:13413ea9a877 | 635 | * future with ARM_DRIVER_OK passed in as the 'status' parameter. In the |
ganlikun | 0:13413ea9a877 | 636 | * case of synchronous execution, control returns after completion with a |
ganlikun | 0:13413ea9a877 | 637 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
ganlikun | 0:13413ea9a877 | 638 | */ |
ganlikun | 0:13413ea9a877 | 639 | int32_t (*EraseAll)(void); |
ganlikun | 0:13413ea9a877 | 640 | |
ganlikun | 0:13413ea9a877 | 641 | /** |
ganlikun | 0:13413ea9a877 | 642 | * @brief Get the status of the current (or previous) command executed by the |
ganlikun | 0:13413ea9a877 | 643 | * storage controller; stored in the structure \ref ARM_STORAGE_STATUS. |
ganlikun | 0:13413ea9a877 | 644 | * |
ganlikun | 0:13413ea9a877 | 645 | * @return |
ganlikun | 0:13413ea9a877 | 646 | * The status of the underlying controller. |
ganlikun | 0:13413ea9a877 | 647 | * |
ganlikun | 0:13413ea9a877 | 648 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 649 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 650 | */ |
ganlikun | 0:13413ea9a877 | 651 | ARM_STORAGE_STATUS (*GetStatus)(void); |
ganlikun | 0:13413ea9a877 | 652 | |
ganlikun | 0:13413ea9a877 | 653 | /** |
ganlikun | 0:13413ea9a877 | 654 | * @brief Get information about the Storage device; stored in the structure \ref ARM_STORAGE_INFO. |
ganlikun | 0:13413ea9a877 | 655 | * |
ganlikun | 0:13413ea9a877 | 656 | * @param [out] info |
ganlikun | 0:13413ea9a877 | 657 | * A caller-supplied buffer capable of being filled in with an |
ganlikun | 0:13413ea9a877 | 658 | * \ref ARM_STORAGE_INFO. |
ganlikun | 0:13413ea9a877 | 659 | * |
ganlikun | 0:13413ea9a877 | 660 | * @return ARM_DRIVER_OK if a ARM_STORAGE_INFO structure containing top level |
ganlikun | 0:13413ea9a877 | 661 | * metadata about the storage controller is filled into the supplied |
ganlikun | 0:13413ea9a877 | 662 | * buffer, else an appropriate error value. |
ganlikun | 0:13413ea9a877 | 663 | * |
ganlikun | 0:13413ea9a877 | 664 | * @note It is the caller's responsibility to ensure that the buffer passed in |
ganlikun | 0:13413ea9a877 | 665 | * is able to be initialized with a \ref ARM_STORAGE_INFO. |
ganlikun | 0:13413ea9a877 | 666 | * |
ganlikun | 0:13413ea9a877 | 667 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 668 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 669 | */ |
ganlikun | 0:13413ea9a877 | 670 | int32_t (*GetInfo)(ARM_STORAGE_INFO *info); |
ganlikun | 0:13413ea9a877 | 671 | |
ganlikun | 0:13413ea9a877 | 672 | /** |
ganlikun | 0:13413ea9a877 | 673 | * \brief For memory-mapped storage, resolve an address relative to |
ganlikun | 0:13413ea9a877 | 674 | * the storage controller into a memory address. |
ganlikun | 0:13413ea9a877 | 675 | * |
ganlikun | 0:13413ea9a877 | 676 | * @param addr |
ganlikun | 0:13413ea9a877 | 677 | * This is the address for which we want a resolution to the |
ganlikun | 0:13413ea9a877 | 678 | * processor's physical address space. It is an offset from the |
ganlikun | 0:13413ea9a877 | 679 | * start of the storage map maintained by the owning storage |
ganlikun | 0:13413ea9a877 | 680 | * controller. |
ganlikun | 0:13413ea9a877 | 681 | * |
ganlikun | 0:13413ea9a877 | 682 | * @return |
ganlikun | 0:13413ea9a877 | 683 | * The resolved address in the processor's address space; else |
ganlikun | 0:13413ea9a877 | 684 | * ARM_STORAGE_INVALID_ADDRESS, if no resolution is possible. |
ganlikun | 0:13413ea9a877 | 685 | * |
ganlikun | 0:13413ea9a877 | 686 | * @note This API returns synchronously. The invocation should return quickly, |
ganlikun | 0:13413ea9a877 | 687 | * and result in a resolved address. |
ganlikun | 0:13413ea9a877 | 688 | */ |
ganlikun | 0:13413ea9a877 | 689 | uint32_t (*ResolveAddress)(uint64_t addr); |
ganlikun | 0:13413ea9a877 | 690 | |
ganlikun | 0:13413ea9a877 | 691 | /** |
ganlikun | 0:13413ea9a877 | 692 | * @brief Advance to the successor of the current block (iterator), or fetch |
ganlikun | 0:13413ea9a877 | 693 | * the first block (if 'prev_block' is passed in as NULL). |
ganlikun | 0:13413ea9a877 | 694 | * |
ganlikun | 0:13413ea9a877 | 695 | * @details This helper function fetches (an iterator to) the next block (or |
ganlikun | 0:13413ea9a877 | 696 | * the first block if 'prev_block' is passed in as NULL). In the failure |
ganlikun | 0:13413ea9a877 | 697 | * case, a terminating, invalid block iterator is filled into the out |
ganlikun | 0:13413ea9a877 | 698 | * parameter: 'next_block'. In combination with \ref |
ganlikun | 0:13413ea9a877 | 699 | * ARM_STORAGE_VALID_BLOCK(), it can be used to iterate over the sequence |
ganlikun | 0:13413ea9a877 | 700 | * of blocks within the storage map: |
ganlikun | 0:13413ea9a877 | 701 | * |
ganlikun | 0:13413ea9a877 | 702 | * \code |
ganlikun | 0:13413ea9a877 | 703 | * ARM_STORAGE_BLOCK block; |
ganlikun | 0:13413ea9a877 | 704 | * for (drv->GetNextBlock(NULL, &block); ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) { |
ganlikun | 0:13413ea9a877 | 705 | * // make use of block |
ganlikun | 0:13413ea9a877 | 706 | * } |
ganlikun | 0:13413ea9a877 | 707 | * \endcode |
ganlikun | 0:13413ea9a877 | 708 | * |
ganlikun | 0:13413ea9a877 | 709 | * @param[in] prev_block |
ganlikun | 0:13413ea9a877 | 710 | * An existing block (iterator) within the same storage |
ganlikun | 0:13413ea9a877 | 711 | * controller. The memory buffer holding this block is owned |
ganlikun | 0:13413ea9a877 | 712 | * by the caller. This pointer may be NULL; if so, the |
ganlikun | 0:13413ea9a877 | 713 | * invocation fills in the first block into the out parameter: |
ganlikun | 0:13413ea9a877 | 714 | * 'next_block'. |
ganlikun | 0:13413ea9a877 | 715 | * |
ganlikun | 0:13413ea9a877 | 716 | * @param[out] next_block |
ganlikun | 0:13413ea9a877 | 717 | * A caller-owned buffer large enough to be filled in with |
ganlikun | 0:13413ea9a877 | 718 | * the following ARM_STORAGE_BLOCK. It is legal to provide the |
ganlikun | 0:13413ea9a877 | 719 | * same buffer using 'next_block' as was passed in with 'prev_block'. It |
ganlikun | 0:13413ea9a877 | 720 | * is also legal to pass a NULL into this parameter if the |
ganlikun | 0:13413ea9a877 | 721 | * caller isn't interested in populating a buffer with the next |
ganlikun | 0:13413ea9a877 | 722 | * block--i.e. if the caller only wishes to establish the |
ganlikun | 0:13413ea9a877 | 723 | * presence of a next block. |
ganlikun | 0:13413ea9a877 | 724 | * |
ganlikun | 0:13413ea9a877 | 725 | * @return ARM_DRIVER_OK if a valid next block is found (or first block, if |
ganlikun | 0:13413ea9a877 | 726 | * prev_block is passed as NULL); upon successful operation, the contents |
ganlikun | 0:13413ea9a877 | 727 | * of the next (or first) block are filled into the buffer pointed to by |
ganlikun | 0:13413ea9a877 | 728 | * the parameter 'next_block' and ARM_STORAGE_VALID_BLOCK(next_block) is |
ganlikun | 0:13413ea9a877 | 729 | * guaranteed to be true. Upon reaching the end of the sequence of blocks |
ganlikun | 0:13413ea9a877 | 730 | * (iterators), or in case the driver is unable to fetch information about |
ganlikun | 0:13413ea9a877 | 731 | * the next (or first) block, an error (negative) value is returned and an |
ganlikun | 0:13413ea9a877 | 732 | * invalid StorageBlock is populated into the supplied buffer. If |
ganlikun | 0:13413ea9a877 | 733 | * prev_block is NULL, the first block is returned. |
ganlikun | 0:13413ea9a877 | 734 | * |
ganlikun | 0:13413ea9a877 | 735 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 736 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 737 | */ |
ganlikun | 0:13413ea9a877 | 738 | int32_t (*GetNextBlock)(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block); |
ganlikun | 0:13413ea9a877 | 739 | |
ganlikun | 0:13413ea9a877 | 740 | /** |
ganlikun | 0:13413ea9a877 | 741 | * @brief Find the storage block (iterator) encompassing a given storage address. |
ganlikun | 0:13413ea9a877 | 742 | * |
ganlikun | 0:13413ea9a877 | 743 | * @param[in] addr |
ganlikun | 0:13413ea9a877 | 744 | * Storage address in bytes. |
ganlikun | 0:13413ea9a877 | 745 | * |
ganlikun | 0:13413ea9a877 | 746 | * @param[out] block |
ganlikun | 0:13413ea9a877 | 747 | * A caller-owned buffer large enough to be filled in with the |
ganlikun | 0:13413ea9a877 | 748 | * ARM_STORAGE_BLOCK encapsulating the given address. This value |
ganlikun | 0:13413ea9a877 | 749 | * can also be passed in as NULL if the caller isn't interested |
ganlikun | 0:13413ea9a877 | 750 | * in populating a buffer with the block--if the caller only |
ganlikun | 0:13413ea9a877 | 751 | * wishes to establish the presence of a containing storage |
ganlikun | 0:13413ea9a877 | 752 | * block. |
ganlikun | 0:13413ea9a877 | 753 | * |
ganlikun | 0:13413ea9a877 | 754 | * @return ARM_DRIVER_OK if a containing storage-block is found. In this case, |
ganlikun | 0:13413ea9a877 | 755 | * if block is non-NULL, the buffer pointed to by it is populated with |
ganlikun | 0:13413ea9a877 | 756 | * the contents of the storage block--i.e. if block is valid and a block is |
ganlikun | 0:13413ea9a877 | 757 | * found, ARM_STORAGE_VALID_BLOCK(block) would return true following this |
ganlikun | 0:13413ea9a877 | 758 | * call. If there is no storage block containing the given offset, or in |
ganlikun | 0:13413ea9a877 | 759 | * case the driver is unable to resolve an address to a storage-block, an |
ganlikun | 0:13413ea9a877 | 760 | * error (negative) value is returned and an invalid StorageBlock is |
ganlikun | 0:13413ea9a877 | 761 | * populated into the supplied buffer. |
ganlikun | 0:13413ea9a877 | 762 | * |
ganlikun | 0:13413ea9a877 | 763 | * @note This API returns synchronously--it does not result in an invocation |
ganlikun | 0:13413ea9a877 | 764 | * of a completion callback. |
ganlikun | 0:13413ea9a877 | 765 | */ |
ganlikun | 0:13413ea9a877 | 766 | int32_t (*GetBlock)(uint64_t addr, ARM_STORAGE_BLOCK *block); |
ganlikun | 0:13413ea9a877 | 767 | } const ARM_DRIVER_STORAGE; |
ganlikun | 0:13413ea9a877 | 768 | |
ganlikun | 0:13413ea9a877 | 769 | #ifdef __cplusplus |
ganlikun | 0:13413ea9a877 | 770 | } |
ganlikun | 0:13413ea9a877 | 771 | #endif // __cplusplus |
ganlikun | 0:13413ea9a877 | 772 | |
ganlikun | 0:13413ea9a877 | 773 | #endif /* __DRIVER_STORAGE_H */ |
ganlikun | 0:13413ea9a877 | 774 | |
ganlikun | 0:13413ea9a877 | 775 | /** @}*/ |
ganlikun | 0:13413ea9a877 | 776 |