-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #679 from LedgerHQ/app-storage-backup-restore
Persistent application storage
- Loading branch information
Showing
3 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/***************************************************************************** | ||
* (c) 2024 Ledger SAS. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*****************************************************************************/ | ||
|
||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#ifndef HAVE_BOLOS | ||
/* "app_storage_data.h" needs to be created in all apps including this file */ | ||
#include "app_storage_data.h" | ||
#endif // HAVE_BOLOS | ||
|
||
///< bit to indicate in properties that the application storage contains settings | ||
#define APP_STORAGE_PROP_SETTINGS (1 << 0) | ||
///< bit to indicate in properties that the application contains data | ||
#define APP_STORAGE_PROP_DATA (1 << 1) | ||
|
||
/** | ||
* @brief Structure defining the header of application storage header | ||
* | ||
*/ | ||
typedef struct app_storage_header_s { | ||
char tag[4]; ///< ['N','V','R','A'] array, when properly initialized | ||
uint32_t size; ///< size in bytes of the data (app_storage_data_t structure) | ||
uint16_t struct_version; ///< version of the structure of data (to be set once at first | ||
///< application start-up) | ||
uint16_t properties; ///< used as a bitfield to set properties, like: contains settings, | ||
///< contains sensitive data | ||
uint32_t data_version; ///< version of the content of data (to be updated every time data are | ||
///< updated) | ||
} app_storage_header_t; | ||
|
||
/** | ||
* @brief Structure defining the application storage | ||
* | ||
*/ | ||
typedef struct app_storage_s { | ||
app_storage_header_t header; ///< header describing the data | ||
#ifndef HAVE_BOLOS | ||
app_storage_data_t data; ///< application data, app_storage_data_t must be defined in | ||
///< "app_storage_data.h" file | ||
#endif // HAVE_BOLOS | ||
} app_storage_t; | ||
|
||
#ifndef HAVE_BOLOS | ||
/** | ||
* @brief This variable must be defined in Application code, and never used directly, | ||
* except by @ref N_nvram | ||
* | ||
*/ | ||
extern const app_storage_t N_app_storage_real; | ||
|
||
/** | ||
* @brief To be used by function accessing application storage data (not N_storage_real) | ||
* | ||
*/ | ||
#define N_app_storage (*(volatile app_storage_t *) PIC(&N_app_storage_real)) | ||
|
||
void app_storage_init(uint32_t data_version); | ||
uint32_t app_storage_get_size(void); | ||
uint16_t app_storage_get_struct_version(void); | ||
uint16_t app_storage_get_properties(void); | ||
uint32_t app_storage_get_data_version(void); | ||
bool app_storage_is_initalized(void); | ||
void app_storage_set_data_version(uint32_t data_version); | ||
|
||
#endif // HAVE_BOLOS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/***************************************************************************** | ||
* (c) 2024 Ledger SAS. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*****************************************************************************/ | ||
|
||
#ifdef HAVE_APP_STORAGE | ||
#include <string.h> | ||
#include "app_storage.h" | ||
#include "os_nvm.h" | ||
#include "os_pic.h" | ||
|
||
// TODO: Create new section for the linker script | ||
/*app_storage app_storage_real __attribute__((section(".bss.app_storage")));*/ | ||
const app_storage_t N_app_storage_real; | ||
|
||
/** | ||
* @brief init header of application storage structure : | ||
* - set "NVRA" tag | ||
* - set size | ||
* - set struct and data versions | ||
* - set properties | ||
* @param data_version Version of the data | ||
*/ | ||
void app_storage_init(uint32_t data_version) | ||
{ | ||
app_storage_header_t header = {0}; | ||
|
||
memcpy(header.tag, (void *) "NVRA", 4); | ||
// APP_STORAGE_DATA_STRUCT_VERSION and APP_STORAGE_PROPERTIES must be defined in | ||
// app_storage_data.h | ||
header.struct_version = APP_STORAGE_DATA_STRUCT_VERSION; | ||
header.data_version = data_version; | ||
header.properties = APP_STORAGE_PROPERTIES; | ||
// TODO: Doing this lead to have app storage bigger than needed | ||
header.size = sizeof(app_storage_data_t); | ||
nvm_write((void *) &N_app_storage.header, &header, sizeof(header)); | ||
} | ||
|
||
/** | ||
* @brief get the size of app data | ||
*/ | ||
uint32_t app_storage_get_size(void) | ||
{ | ||
return N_app_storage.header.size; | ||
} | ||
|
||
/** | ||
* @brief get the version of app data structure | ||
*/ | ||
uint16_t app_storage_get_struct_version(void) | ||
{ | ||
return N_app_storage.header.struct_version; | ||
} | ||
|
||
/** | ||
* @brief get the version of app data | ||
*/ | ||
uint32_t app_storage_get_data_version(void) | ||
{ | ||
return N_app_storage.header.data_version; | ||
} | ||
|
||
/** | ||
* @brief get the properties of app data | ||
*/ | ||
uint16_t app_storage_get_properties(void) | ||
{ | ||
return N_app_storage.header.properties; | ||
} | ||
|
||
/** | ||
* @brief ensure app storage struct is initialized | ||
*/ | ||
bool app_storage_is_initalized(void) | ||
{ | ||
if (memcmp((void *) N_app_storage.header.tag, "NVRA", 4)) { | ||
return false; | ||
} | ||
if (N_app_storage.header.size == 0) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* @brief set data version of app data | ||
*/ | ||
void app_storage_set_data_version(uint32_t data_version) | ||
{ | ||
nvm_write((void *) &N_app_storage.header.data_version, | ||
(void *) &data_version, | ||
sizeof(N_app_storage.header.data_version)); | ||
} | ||
|
||
#endif // HAVE_APP_STORAGE |