Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
DirectAccessDevicekey.cpp
00001 /* 00002 * Copyright (c) 2018 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 // ----------------------------------------------------------- Includes ----------------------------------------------------------- 00018 #if DEVICE_FLASH 00019 #include "DirectAccessDevicekey.h" 00020 #include "drivers/FlashIAP.h" 00021 #include <string.h> 00022 #include <stdio.h> 00023 #include "mbed_error.h" 00024 #include "MbedCRC.h" 00025 #include "mbed_trace.h" 00026 #define TRACE_GROUP "DADK" 00027 00028 using namespace mbed; 00029 00030 // --------------------------------------------------------- Definitions ---------------------------------------------------------- 00031 typedef struct { 00032 uint32_t address; 00033 size_t size; 00034 } tdbstore_area_data_t; 00035 00036 typedef struct { 00037 uint16_t trailer_size; 00038 uint16_t data_size; 00039 uint32_t crc; 00040 } reserved_trailer_t; 00041 00042 #define TDBSTORE_NUMBER_OF_AREAS 2 00043 #define MAX_DEVICEKEY_DATA_SIZE 64 00044 #define RESERVED_AREA_SIZE (MAX_DEVICEKEY_DATA_SIZE+sizeof(reserved_trailer_t)) /* DeviceKey Max Data size + metadata trailer */ 00045 00046 #define STR_EXPAND(tok) #tok 00047 #define STR(tok) STR_EXPAND(tok) 00048 00049 // -------------------------------------------------- Local Functions Declaration ---------------------------------------------------- 00050 static int calc_area_params(FlashIAP *flash, uint32_t out_tdb_start_offset, uint32_t tdb_end_offset, 00051 tdbstore_area_data_t *area_params); 00052 static int reserved_data_get(FlashIAP *flash, tdbstore_area_data_t *area_params, void *reserved_data_buf, 00053 size_t reserved_data_buf_size, size_t *actual_data_size_ptr); 00054 static inline uint32_t align_up(uint64_t val, uint64_t size); 00055 static inline uint32_t align_down(uint64_t val, uint64_t size); 00056 static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data_buf); 00057 00058 // -------------------------------------------------- API Functions Implementation ---------------------------------------------------- 00059 int direct_access_to_devicekey(uint32_t tdb_start_offset, uint32_t tdb_end_offset, void *data_buf, 00060 size_t data_buf_size, size_t *actual_data_size_ptr) 00061 { 00062 int status = MBED_ERROR_INVALID_ARGUMENT; 00063 FlashIAP flash; 00064 uint8_t active_area = 0; 00065 tdbstore_area_data_t area_params[TDBSTORE_NUMBER_OF_AREAS]; 00066 memset(area_params, 0, sizeof(area_params)); 00067 bool is_flash_init = false; 00068 00069 if (NULL == data_buf) { 00070 tr_error("Invalid Data Buf Argument"); 00071 goto exit_point; 00072 } 00073 00074 status = flash.init(); 00075 if (status != 0) { 00076 tr_error("FlashIAP init failed - err: %d", status); 00077 status = MBED_ERROR_FAILED_OPERATION; 00078 goto exit_point; 00079 } 00080 00081 is_flash_init = true; 00082 00083 status = calc_area_params(&flash, tdb_start_offset, tdb_end_offset, area_params); 00084 if (status != MBED_SUCCESS) { 00085 tr_error("Couldn't calulate Area Params - err: %d", status); 00086 goto exit_point; 00087 } 00088 00089 /* DeviceKey data can be found either in first or second Flash Area */ 00090 /* Loop through Areas to find valid DeviceKey data */ 00091 for (active_area = 0; active_area < TDBSTORE_NUMBER_OF_AREAS; active_area++) { 00092 status = reserved_data_get(&flash, &area_params[active_area], data_buf, data_buf_size, actual_data_size_ptr); 00093 if (status == MBED_SUCCESS) { 00094 break; 00095 } 00096 } 00097 00098 if (status != MBED_SUCCESS) { 00099 status = MBED_ERROR_ITEM_NOT_FOUND; 00100 tr_error("Couldn't find valid DeviceKey - err: %d", status); 00101 } 00102 00103 exit_point: 00104 if (true == is_flash_init) { 00105 flash.deinit(); 00106 } 00107 00108 return status; 00109 } 00110 00111 int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uint32_t *out_tdb_end_offset) 00112 { 00113 uint32_t flash_end_address; 00114 uint32_t flash_start_address; 00115 uint32_t aligned_start_address; 00116 uint32_t aligned_end_address; 00117 FlashIAP flash; 00118 bool is_default_configuration = false; 00119 uint32_t tdb_size; 00120 00121 if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "FILESYSTEM") == 0) { 00122 #ifndef MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS 00123 return MBED_ERROR_ITEM_NOT_FOUND; 00124 #else 00125 *out_tdb_start_offset = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS; 00126 tdb_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE; 00127 #endif 00128 00129 } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) { 00130 #ifndef MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS 00131 return MBED_ERROR_ITEM_NOT_FOUND; 00132 #else 00133 *out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS; 00134 tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE; 00135 #endif 00136 00137 } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_INTERNAL") == 0) { 00138 #ifndef MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS 00139 return MBED_ERROR_ITEM_NOT_FOUND; 00140 #else 00141 *out_tdb_start_offset = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS; 00142 tdb_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE; 00143 #endif 00144 00145 } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "default") == 0) { 00146 #ifndef MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS 00147 return MBED_ERROR_ITEM_NOT_FOUND; 00148 #else 00149 #if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH 00150 *out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS; 00151 tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE; 00152 #elif COMPONENT_SD 00153 tdb_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE; 00154 #else 00155 return MBED_ERROR_UNSUPPORTED; 00156 #endif // COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH 00157 #endif // MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS 00158 } else { 00159 return MBED_ERROR_UNSUPPORTED; 00160 } 00161 00162 *out_tdb_end_offset = (*out_tdb_start_offset) + tdb_size; 00163 00164 if ((*out_tdb_start_offset == 0) && (tdb_size == 0)) { 00165 is_default_configuration = true; 00166 } else if ((*out_tdb_start_offset == 0) || (tdb_size == 0)) { 00167 return MBED_ERROR_UNSUPPORTED; 00168 } 00169 00170 int ret = flash.init(); 00171 if (ret != 0) { 00172 return MBED_ERROR_FAILED_OPERATION; 00173 } 00174 00175 uint32_t flash_first_writable_sector_address = (uint32_t)(align_up(FLASHIAP_APP_ROM_END_ADDR, 00176 flash.get_sector_size(FLASHIAP_APP_ROM_END_ADDR))); 00177 00178 //Get flash parameters before starting 00179 flash_start_address = flash.get_flash_start(); 00180 flash_end_address = flash_start_address + flash.get_flash_size(); 00181 00182 if (!is_default_configuration) { 00183 aligned_start_address = align_down(*out_tdb_start_offset, flash.get_sector_size(*out_tdb_start_offset)); 00184 aligned_end_address = align_up(*out_tdb_end_offset, flash.get_sector_size(*out_tdb_end_offset - 1)); 00185 if ((*out_tdb_start_offset != aligned_start_address) || (*out_tdb_end_offset != aligned_end_address) 00186 || (*out_tdb_end_offset > flash_end_address)) { 00187 flash.deinit(); 00188 return MBED_ERROR_INVALID_OPERATION; 00189 } 00190 } else { 00191 aligned_start_address = flash_end_address - (flash.get_sector_size(flash_end_address - 1) * 2); 00192 if (aligned_start_address < flash_first_writable_sector_address) { 00193 flash.deinit(); 00194 return MBED_ERROR_INVALID_OPERATION; 00195 } 00196 *out_tdb_start_offset = aligned_start_address; 00197 *out_tdb_end_offset = flash_end_address; 00198 } 00199 00200 flash.deinit(); 00201 00202 return MBED_SUCCESS; 00203 } 00204 00205 // -------------------------------------------------- Local Functions Implementation ---------------------------------------------------- 00206 static int calc_area_params(FlashIAP *flash, uint32_t out_tdb_start_offset, uint32_t tdb_end_offset, 00207 tdbstore_area_data_t *area_params) 00208 { 00209 uint32_t bd_size = 0; 00210 uint32_t initial_erase_size = flash->get_sector_size(out_tdb_start_offset); 00211 uint32_t erase_unit_size = initial_erase_size; 00212 size_t cur_area_size = 0; 00213 00214 if ((tdb_end_offset < (out_tdb_start_offset + 2 * RESERVED_AREA_SIZE - 1)) || 00215 (tdb_end_offset > (flash->get_flash_start() + flash->get_flash_size()))) { 00216 tr_error("calc_area_params failed - Invalid input addresses"); 00217 return MBED_ERROR_INVALID_ARGUMENT; 00218 } 00219 00220 // Entire TDBStore can't exceed 32 bits 00221 bd_size = (tdb_end_offset - out_tdb_start_offset + 1); 00222 00223 while (cur_area_size < bd_size / 2) { 00224 erase_unit_size = flash->get_sector_size(out_tdb_start_offset + cur_area_size); 00225 cur_area_size += erase_unit_size; 00226 } 00227 00228 area_params[0].address = out_tdb_start_offset; 00229 area_params[0].size = cur_area_size; 00230 area_params[1].address = out_tdb_start_offset + cur_area_size; 00231 area_params[1].size = bd_size - cur_area_size; 00232 00233 return MBED_SUCCESS; 00234 } 00235 00236 static int reserved_data_get(FlashIAP *flash, tdbstore_area_data_t *area_params, void *reserved_data_buf, 00237 size_t reserved_data_buf_size, size_t *actual_data_size_ptr) 00238 { 00239 int status = MBED_SUCCESS; 00240 reserved_trailer_t trailer; 00241 uint8_t *buf; 00242 int ret = MBED_SUCCESS; 00243 bool erased = true; 00244 size_t actual_size = 0; 00245 uint32_t initial_crc = 0xFFFFFFFF; 00246 uint32_t crc = initial_crc; 00247 uint8_t blank = flash->get_erase_value(); 00248 00249 /* Read Into trailer deviceKey metadata */ 00250 ret = flash->read(&trailer, area_params->address + MAX_DEVICEKEY_DATA_SIZE, sizeof(trailer)); 00251 if (ret != MBED_SUCCESS) { 00252 status = MBED_ERROR_READ_FAILED; 00253 goto exit_point; 00254 } 00255 00256 buf = reinterpret_cast <uint8_t *>(&trailer); 00257 for (uint32_t i = 0; i < sizeof(trailer); i++) { 00258 if (buf[i] != blank) { 00259 erased = false; 00260 break; 00261 } 00262 } 00263 00264 if (true == erased) { 00265 /* Metadata is erased , DeviceKey Data is NOT in this Area */ 00266 status = MBED_ERROR_ITEM_NOT_FOUND; 00267 goto exit_point; 00268 } 00269 00270 actual_size = trailer.data_size; 00271 if (actual_data_size_ptr != NULL) { 00272 *actual_data_size_ptr = actual_size; 00273 } 00274 if (reserved_data_buf_size < actual_size) { 00275 status = MBED_ERROR_INVALID_SIZE; 00276 goto exit_point; 00277 } 00278 00279 buf = reinterpret_cast <uint8_t *>(reserved_data_buf); 00280 00281 /* Read DeviceKey Data */ 00282 ret = flash->read(buf, area_params->address, (uint32_t)actual_size); 00283 if (ret != MBED_SUCCESS) { 00284 status = MBED_ERROR_READ_FAILED; 00285 goto exit_point; 00286 } 00287 00288 crc = calc_crc(crc, (uint32_t)actual_size, buf); 00289 if (crc != trailer.crc) { 00290 status = MBED_ERROR_INVALID_DATA_DETECTED; 00291 } 00292 00293 exit_point: 00294 00295 return status; 00296 } 00297 00298 static inline uint32_t align_up(uint64_t val, uint64_t size) 00299 { 00300 return (((val - 1) / size) + 1) * size; 00301 } 00302 00303 static inline uint32_t align_down(uint64_t val, uint64_t size) 00304 { 00305 return (((val) / size)) * size; 00306 } 00307 00308 static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data_buf) 00309 { 00310 uint32_t crc; 00311 MbedCRC<POLY_32BIT_ANSI, 32> ct(init_crc, 0x0, true, false); 00312 ct.compute(data_buf, data_size, &crc); 00313 return crc; 00314 } 00315 #endif // DEVICE_FLASH
Generated on Tue Jul 12 2022 13:54:16 by
