1 /* 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * Description: KV Storage Library flash updating module interface 15 */ 16 17 #ifndef NV_UPDATE_H_ 18 #define NV_UPDATE_H_ 19 20 #ifdef CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM 21 #include "nv_task_adapt.h" 22 #else 23 #include "flash_task_types.h" 24 #endif 25 #include "nv_store.h" 26 #include "errcode.h" 27 #include "nv_porting.h" 28 29 #ifdef __cplusplus 30 #if __cplusplus 31 extern "C" { 32 #endif /* __cplusplus */ 33 #endif /* __cplusplus */ 34 35 /* Unused states and events should be removed */ 36 typedef enum { 37 STATE_INVALID, 38 39 /* erase_all_keys, erase_old_keys, copy_all_keys */ 40 STATE_SELECT_FIRST_PAGE, 41 STATE_SELECT_NEXT_PAGE, 42 STATE_FIND_FIRST_KEY, 43 STATE_FIND_NEXT_KEY, 44 STATE_FIND_EXISTING_KEY, 45 STATE_PREP_COPY_KEY, 46 STATE_PREP_DELETE_KEY, 47 STATE_PREP_MODIFY_KEY, 48 STATE_UPDATE_MAP_FOR_OLD, 49 50 /* prep_defrag_page, defrag_page */ 51 STATE_FIND_DEFRAG, 52 STATE_ERASE_DEFRAG, 53 STATE_PREP_DEFRAG, 54 STATE_COPY_ALL_KEYS, 55 STATE_PREP_PAGE_HEADER, 56 STATE_WRITE_PAGE_HEADER, 57 STATE_UPDATE_NVREGION_MAP, 58 59 /* prepare_write */ 60 STATE_FIND_WRITE_POS, 61 STATE_DEFRAG_PAGE, 62 63 /* write_key */ 64 STATE_PREP_STORE, 65 STATE_PREP_KEY_DATA, 66 STATE_CLAIM_CRYPTO, 67 STATE_ERASE_OLD_KEYS, 68 69 STATE_PRIME_WRITE, 70 STATE_PERFORM_WRITE, 71 STATE_UPDATE_MAP_FOR_NEW, 72 73 STATE_SUSPENDED = 0x1E, 74 STATE_EXIT = 0x1F 75 } kv_update_state_t; 76 77 typedef enum { 78 EVENT_NONE, 79 EVENT_SUSPEND, 80 81 EVENT_WRITE_DATA_EXHAUSTED, 82 EVENT_WRITE_BUFFER_PRIMED, 83 EVENT_WRITE_BUFFER_STORED, 84 85 /* erase_all_keys, erase_old_keys, copy_all_keys, modify_key */ 86 EVENT_PAGE_SELECTED, 87 EVENT_PAGE_NOT_SELECTED, 88 EVENT_KEY_FOUND, 89 EVENT_KEY_NOT_FOUND, 90 EVENT_COPY_KEY_READY, 91 92 /* erase_all_keys */ 93 EVENT_KEYS_ERASED, 94 95 /* modify_key */ 96 EVENT_KEY_UPDATE_REQUIRED, 97 EVENT_KEY_UPDATE_NOT_NEEDED, 98 99 /* prep_defrag_page */ 100 EVENT_DEFRAG_FOUND, 101 EVENT_DEFRAG_ERASED, 102 103 /* defrag_page */ 104 EVENT_DEFRAG_PREPARED, 105 EVENT_ALL_KEYS_COPIED, 106 EVENT_PAGE_HEADER_READY, 107 EVENT_NVREGION_MAP_UPDATED, 108 109 /* prepare_write */ 110 EVENT_DEFRAG_REQUIRED, 111 EVENT_DEFRAG_COMPLETE, 112 EVENT_WRITE_POS_FOUND, 113 114 /* write_key */ 115 EVENT_STORE_READY, 116 EVENT_KEY_DATA_READY, 117 EVENT_CRYPTO_CLAIMED, 118 EVENT_WRITE_COMPLETE, 119 EVENT_PAGE_MAP_UPDATED, 120 121 EVENT_ERROR = 0x1F 122 } kv_update_event_t; 123 124 /* State machine action function */ 125 typedef kv_update_event_t (*kv_state_action)(void); 126 127 /* Data to be written to flash can be scattered across a chain of one or more source buffers */ 128 typedef struct managed_source_buffer { 129 struct managed_source_buffer *next; /* Pointer to next source buffer in chain */ 130 uint8_t *data; /* Pointer to data in RAM/Flash */ 131 uint16_t data_length; /* Length of the data */ 132 uint16_t data_consumed; /* How much of the data has been read so far */ 133 bool release_data : 1; /* Data pointer is a temporary buffer that needs freeing */ 134 bool receive_hash : 1; /* Data buffer should receive a hash/CRC calculation */ 135 bool hash_data : 1; /* Indicates that the data needs hashing */ 136 bool crc_data : 1; /* Indicates that the data needs CRC calculation */ 137 bool encrypt_data : 1; /* Indicates that the data need encrypting */ 138 bool gcm_tag_data : 1; /* Indicates that the data needs AES GCM tag */ 139 } kv_managed_source_buffer_t; 140 141 /* Write buffer, used to gather chunks of data from one or more source buffers */ 142 typedef struct { 143 uint8_t *data; /* RAM buffer used to hold chunks of data to be written to flash */ 144 uint32_t write_location; /* Current location in flash to write to */ 145 uint32_t resume_location; /* Write location reached when state machine was suspended */ 146 uint32_t crypto_handle; /* AES crypo handle */ 147 uint16_t size; /* Size of the RAM buffer */ 148 uint16_t data_length; /* Length of data written to RAM buffer */ 149 uint32_t crc_ret; /* crc_ret counter */ 150 uint16_t data_consumed; /* How much of the data has been written to flash */ 151 bool hash_claimed : 1; /* Hash function (SHA256) has been claimed */ 152 bool encrypt_claimed : 1; /* Encryption function (AES) has been claimed */ 153 bool crc_claimed : 1; /* CRC function has been claimed */ 154 bool gcm_tag_claimed : 1; /* AES GCM tag has been claimed */ 155 } kv_managed_write_buffer_t; 156 157 /* State machine state transition table entry */ 158 typedef struct { 159 kv_update_state_t state : 5; /* Current state */ 160 kv_update_state_t next_state : 5; /* State after the transition has occurred */ 161 kv_update_event_t event : 5; /* Event required to cause the transition (raised by an action function) */ 162 } kv_update_transition_t; 163 164 /* State machine state action table entry */ 165 typedef struct { 166 kv_update_state_t state; /* Applicable state */ 167 kv_state_action action; /* Action function to be called */ 168 } kv_update_action_t; 169 170 /* Structure used to describe a state machine */ 171 typedef struct { 172 const kv_update_transition_t *transition_table; /* State Transition table for this state machine */ 173 const kv_update_action_t *action_table; /* State Action table for this state machine */ 174 uint16_t write_buffer_size; /* Size of the write buffer needed for this state machine */ 175 kv_update_state_t initial_state; /* State to set on initial entry to this state machine */ 176 kv_update_state_t resume_state; /* State to set on resuming this state machine */ 177 kv_update_event_t exit_event; /* Event to send to previous state machine, if no exit action function defined */ 178 } kv_state_machine_t; 179 180 /* Used to hold run-time details of a state machine being processed */ 181 /* Individual state machines will often invoke a sub state machine. 182 * These data structures will be used to form a linked list of currently active state machines, although only one 183 * state machine is ever being processed at any one time. 184 * The tail of the list will be the initial state machine, started by one of the four kv_update_xxx() functions at the 185 * end of this file. 186 * The head of the list will be the current state machine being actively processed. 187 * The 'prev' field provides a path back to the initial state machine 188 */ 189 typedef struct kv_active_state_machine_t { 190 struct kv_active_state_machine_t *prev; /* Previous state machine. Will be NULL if this is a root machine */ 191 const kv_state_machine_t *machine; /* State machine being processed */ 192 kv_managed_write_buffer_t *write_buffer; /* Holds chunk of data to be written to flash */ 193 kv_managed_source_buffer_t *source_buffer; /* Linked list of source data buffers used to populate write buffer */ 194 kv_managed_source_buffer_t *current_source; /* Current source buffer being used */ 195 kv_update_state_t state; /* Current state machine state */ 196 kv_update_event_t event; /* Last event raised (will have caused transition to current state) */ 197 errcode_t error_code; /* Records the error code produced when raising an error event */ 198 } kv_active_state_machine_t; 199 200 errcode_t kv_update_init(cores_t core); 201 errcode_t kv_update_erase_key(kv_store_t core, flash_task_node *sanitised_tasks); 202 errcode_t kv_update_write_key(kv_store_t core, flash_task_node *sanitised_task); 203 errcode_t kv_update_modify_attribute(kv_store_t core, flash_task_node *sanitised_task); 204 errcode_t kv_update_backup_init(void); 205 206 #ifdef __cplusplus 207 #if __cplusplus 208 } 209 #endif /* __cplusplus */ 210 #endif /* __cplusplus */ 211 212 #endif 213