• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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