Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

Committer:
MACRUM
Date:
Mon Jul 02 06:30:39 2018 +0000
Revision:
0:276e7a263c35
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:276e7a263c35 1 // ----------------------------------------------------------------------------
MACRUM 0:276e7a263c35 2 // Copyright 2016-2017 ARM Ltd.
MACRUM 0:276e7a263c35 3 //
MACRUM 0:276e7a263c35 4 // SPDX-License-Identifier: Apache-2.0
MACRUM 0:276e7a263c35 5 //
MACRUM 0:276e7a263c35 6 // Licensed under the Apache License, Version 2.0 (the "License");
MACRUM 0:276e7a263c35 7 // you may not use this file except in compliance with the License.
MACRUM 0:276e7a263c35 8 // You may obtain a copy of the License at
MACRUM 0:276e7a263c35 9 //
MACRUM 0:276e7a263c35 10 // http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:276e7a263c35 11 //
MACRUM 0:276e7a263c35 12 // Unless required by applicable law or agreed to in writing, software
MACRUM 0:276e7a263c35 13 // distributed under the License is distributed on an "AS IS" BASIS,
MACRUM 0:276e7a263c35 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:276e7a263c35 15 // See the License for the specific language governing permissions and
MACRUM 0:276e7a263c35 16 // limitations under the License.
MACRUM 0:276e7a263c35 17 // ----------------------------------------------------------------------------
MACRUM 0:276e7a263c35 18
MACRUM 0:276e7a263c35 19 #if defined(TARGET_REALTEK_RTL8195AM)
MACRUM 0:276e7a263c35 20
MACRUM 0:276e7a263c35 21 #include "update-client-paal/arm_uc_paal_update_api.h"
MACRUM 0:276e7a263c35 22 #include "update-client-pal-flashiap/arm_uc_pal_flashiap_platform.h"
MACRUM 0:276e7a263c35 23
MACRUM 0:276e7a263c35 24 #include "update-client-common/arm_uc_metadata_header_v2.h"
MACRUM 0:276e7a263c35 25 #include "update-client-common/arm_uc_common.h"
MACRUM 0:276e7a263c35 26
MACRUM 0:276e7a263c35 27 #include "ota_api.h"
MACRUM 0:276e7a263c35 28 #include "flash_ext.h"
MACRUM 0:276e7a263c35 29
MACRUM 0:276e7a263c35 30 #define HEADER_SIZE (OTA_CRC32_OFS + 4)
MACRUM 0:276e7a263c35 31
MACRUM 0:276e7a263c35 32 typedef enum {
MACRUM 0:276e7a263c35 33 BASE_ADDRESS_RUNNING,
MACRUM 0:276e7a263c35 34 BASE_ADDRESS_SPARE
MACRUM 0:276e7a263c35 35 } base_address_t;
MACRUM 0:276e7a263c35 36
MACRUM 0:276e7a263c35 37 /**
MACRUM 0:276e7a263c35 38 * Base address, for caching between operations.
MACRUM 0:276e7a263c35 39 */
MACRUM 0:276e7a263c35 40 static size_t arm_uc_base_address = 0;
MACRUM 0:276e7a263c35 41
MACRUM 0:276e7a263c35 42 /**
MACRUM 0:276e7a263c35 43 * Callback handler.
MACRUM 0:276e7a263c35 44 */
MACRUM 0:276e7a263c35 45 static void (*arm_uc_pal_rtl8195am_callback)(uint32_t) = NULL;
MACRUM 0:276e7a263c35 46
MACRUM 0:276e7a263c35 47 /**
MACRUM 0:276e7a263c35 48 * @brief Signal external event handler with NULL pointer check.
MACRUM 0:276e7a263c35 49 *
MACRUM 0:276e7a263c35 50 * @param[in] event The event
MACRUM 0:276e7a263c35 51 */
MACRUM 0:276e7a263c35 52 static void arm_uc_pal_rtl8195am_signal_internal(uint32_t event)
MACRUM 0:276e7a263c35 53 {
MACRUM 0:276e7a263c35 54 if (arm_uc_pal_rtl8195am_callback)
MACRUM 0:276e7a263c35 55 {
MACRUM 0:276e7a263c35 56 arm_uc_pal_rtl8195am_callback(event);
MACRUM 0:276e7a263c35 57 }
MACRUM 0:276e7a263c35 58 }
MACRUM 0:276e7a263c35 59
MACRUM 0:276e7a263c35 60 /**
MACRUM 0:276e7a263c35 61 * @brief Create header compatible with the RTL8195AM bootloader
MACRUM 0:276e7a263c35 62 *
MACRUM 0:276e7a263c35 63 * @param[in] details Update client firmware details struct.
MACRUM 0:276e7a263c35 64 * @param buffer Scratch buffer for creating the header.
MACRUM 0:276e7a263c35 65 *
MACRUM 0:276e7a263c35 66 * @return ERR_NONE on success. ERR_INVALID_PARAMETER on failure.
MACRUM 0:276e7a263c35 67 */
MACRUM 0:276e7a263c35 68 static arm_uc_error_t arm_uc_pal_create_realtek_header(const arm_uc_firmware_details_t* details, arm_uc_buffer_t* buffer)
MACRUM 0:276e7a263c35 69 {
MACRUM 0:276e7a263c35 70 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 71
MACRUM 0:276e7a263c35 72 if (details && buffer && buffer->ptr && (buffer->size_max >= HEADER_SIZE))
MACRUM 0:276e7a263c35 73 {
MACRUM 0:276e7a263c35 74 /* set tag */
MACRUM 0:276e7a263c35 75 buffer->ptr[OTA_TAG_OFS ] = OTA_TAG_ID & 0xFF;
MACRUM 0:276e7a263c35 76 buffer->ptr[OTA_TAG_OFS + 1] = (OTA_TAG_ID >> 8) & 0xFF;
MACRUM 0:276e7a263c35 77 buffer->ptr[OTA_TAG_OFS + 2] = (OTA_TAG_ID >> 16) & 0xFF;
MACRUM 0:276e7a263c35 78 buffer->ptr[OTA_TAG_OFS + 3] = (OTA_TAG_ID >> 24) & 0xFF;
MACRUM 0:276e7a263c35 79
MACRUM 0:276e7a263c35 80 /* set version tag */
MACRUM 0:276e7a263c35 81 buffer->ptr[OTA_VER_OFS ] = OTA_VER_ID & 0xFF;
MACRUM 0:276e7a263c35 82 buffer->ptr[OTA_VER_OFS + 1] = (OTA_VER_ID >> 8) & 0xFF;
MACRUM 0:276e7a263c35 83 buffer->ptr[OTA_VER_OFS + 2] = (OTA_VER_ID >> 16) & 0xFF;
MACRUM 0:276e7a263c35 84 buffer->ptr[OTA_VER_OFS + 3] = (OTA_VER_ID >> 24) & 0xFF;
MACRUM 0:276e7a263c35 85
MACRUM 0:276e7a263c35 86 /* set timestamp */
MACRUM 0:276e7a263c35 87 buffer->ptr[OTA_EPOCH_OFS ] = details->version & 0xFF;
MACRUM 0:276e7a263c35 88 buffer->ptr[OTA_EPOCH_OFS + 1] = (details->version >> 8) & 0xFF;
MACRUM 0:276e7a263c35 89 buffer->ptr[OTA_EPOCH_OFS + 2] = (details->version >> 16) & 0xFF;
MACRUM 0:276e7a263c35 90 buffer->ptr[OTA_EPOCH_OFS + 3] = (details->version >> 24) & 0xFF;
MACRUM 0:276e7a263c35 91 buffer->ptr[OTA_EPOCH_OFS + 4] = (details->version >> 32) & 0xFF;
MACRUM 0:276e7a263c35 92 buffer->ptr[OTA_EPOCH_OFS + 5] = (details->version >> 40) & 0xFF;
MACRUM 0:276e7a263c35 93 buffer->ptr[OTA_EPOCH_OFS + 6] = (details->version >> 48) & 0xFF;
MACRUM 0:276e7a263c35 94 buffer->ptr[OTA_EPOCH_OFS + 7] = (details->version >> 56) & 0xFF;
MACRUM 0:276e7a263c35 95
MACRUM 0:276e7a263c35 96 /* set size */
MACRUM 0:276e7a263c35 97 uint32_t size_with_header = details->size + HEADER_SIZE;
MACRUM 0:276e7a263c35 98
MACRUM 0:276e7a263c35 99 buffer->ptr[OTA_SIZE_OFS ] = size_with_header & 0xFF;
MACRUM 0:276e7a263c35 100 buffer->ptr[OTA_SIZE_OFS + 1] = (size_with_header >> 8) & 0xFF;
MACRUM 0:276e7a263c35 101 buffer->ptr[OTA_SIZE_OFS + 2] = (size_with_header >> 16) & 0xFF;
MACRUM 0:276e7a263c35 102 buffer->ptr[OTA_SIZE_OFS + 3] = (size_with_header >> 24) & 0xFF;
MACRUM 0:276e7a263c35 103
MACRUM 0:276e7a263c35 104 /* copy hash */
MACRUM 0:276e7a263c35 105 for (size_t index = 0; index < ARM_UC_SHA256_SIZE; index++)
MACRUM 0:276e7a263c35 106 {
MACRUM 0:276e7a263c35 107 buffer->ptr[OTA_HASH_OFS + index] = details->hash[index];
MACRUM 0:276e7a263c35 108 }
MACRUM 0:276e7a263c35 109
MACRUM 0:276e7a263c35 110 /* copy campaign */
MACRUM 0:276e7a263c35 111 for (size_t index = 0; index < ARM_UC_GUID_SIZE; index++)
MACRUM 0:276e7a263c35 112 {
MACRUM 0:276e7a263c35 113 buffer->ptr[OTA_CAMPAIGN_OFS + index] = details->campaign[index];
MACRUM 0:276e7a263c35 114 }
MACRUM 0:276e7a263c35 115
MACRUM 0:276e7a263c35 116 /* set buffer size minus CRC */
MACRUM 0:276e7a263c35 117 buffer->size = HEADER_SIZE - 4;
MACRUM 0:276e7a263c35 118
MACRUM 0:276e7a263c35 119 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 120 }
MACRUM 0:276e7a263c35 121
MACRUM 0:276e7a263c35 122 return result;
MACRUM 0:276e7a263c35 123 }
MACRUM 0:276e7a263c35 124
MACRUM 0:276e7a263c35 125 /**
MACRUM 0:276e7a263c35 126 * @brief Read header for the image located at the base address.
MACRUM 0:276e7a263c35 127 *
MACRUM 0:276e7a263c35 128 * @param[in] base_address Start address for firmware slot.
MACRUM 0:276e7a263c35 129 * @param details Update client details struct.
MACRUM 0:276e7a263c35 130 *
MACRUM 0:276e7a263c35 131 * @return ERR_NONE on success, ERR_INVALID_PARAMETER on failure.
MACRUM 0:276e7a263c35 132 */
MACRUM 0:276e7a263c35 133 static arm_uc_error_t arm_uc_pal_get_realtek_header(uint32_t base_address,
MACRUM 0:276e7a263c35 134 arm_uc_firmware_details_t* details)
MACRUM 0:276e7a263c35 135 {
MACRUM 0:276e7a263c35 136 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 137
MACRUM 0:276e7a263c35 138 if (details)
MACRUM 0:276e7a263c35 139 {
MACRUM 0:276e7a263c35 140 uint8_t buffer[HEADER_SIZE] = { 0 };
MACRUM 0:276e7a263c35 141
MACRUM 0:276e7a263c35 142 int rc = arm_uc_flashiap_read(buffer, base_address, sizeof(buffer));
MACRUM 0:276e7a263c35 143
MACRUM 0:276e7a263c35 144 if (rc == 0)
MACRUM 0:276e7a263c35 145 {
MACRUM 0:276e7a263c35 146 #if 0
MACRUM 0:276e7a263c35 147 printf("debug: \r\n");
MACRUM 0:276e7a263c35 148 for (size_t index = 0; index < sizeof(buffer); index++)
MACRUM 0:276e7a263c35 149 {
MACRUM 0:276e7a263c35 150 printf("%02X", buffer[index]);
MACRUM 0:276e7a263c35 151 }
MACRUM 0:276e7a263c35 152 printf("\r\n");
MACRUM 0:276e7a263c35 153 #endif
MACRUM 0:276e7a263c35 154
MACRUM 0:276e7a263c35 155 /* parse tag */
MACRUM 0:276e7a263c35 156 uint32_t tag = buffer[OTA_TAG_OFS + 3];
MACRUM 0:276e7a263c35 157 tag = (tag << 8) | buffer[OTA_TAG_OFS + 2];
MACRUM 0:276e7a263c35 158 tag = (tag << 8) | buffer[OTA_TAG_OFS + 1];
MACRUM 0:276e7a263c35 159 tag = (tag << 8) | buffer[OTA_TAG_OFS + 0];
MACRUM 0:276e7a263c35 160
MACRUM 0:276e7a263c35 161 /* parse version tag */
MACRUM 0:276e7a263c35 162 uint32_t version_tag = buffer[OTA_VER_OFS + 3];
MACRUM 0:276e7a263c35 163 version_tag = (version_tag << 8) | buffer[OTA_VER_OFS + 2];
MACRUM 0:276e7a263c35 164 version_tag = (version_tag << 8) | buffer[OTA_VER_OFS + 1];
MACRUM 0:276e7a263c35 165 version_tag = (version_tag << 8) | buffer[OTA_VER_OFS + 0];
MACRUM 0:276e7a263c35 166
MACRUM 0:276e7a263c35 167 UC_PAAL_TRACE("tag: %" PRIX32, tag);
MACRUM 0:276e7a263c35 168 UC_PAAL_TRACE("version_tag: %" PRIX32, version_tag);
MACRUM 0:276e7a263c35 169
MACRUM 0:276e7a263c35 170 /* check tags */
MACRUM 0:276e7a263c35 171 if ((tag == OTA_TAG_ID) && (version_tag == OTA_VER_ID))
MACRUM 0:276e7a263c35 172 {
MACRUM 0:276e7a263c35 173 /* parse CRC */
MACRUM 0:276e7a263c35 174 uint32_t crc_header = buffer[OTA_CRC32_OFS + 3];
MACRUM 0:276e7a263c35 175 crc_header = (crc_header << 8) | buffer[OTA_CRC32_OFS + 2];
MACRUM 0:276e7a263c35 176 crc_header = (crc_header << 8) | buffer[OTA_CRC32_OFS + 1];
MACRUM 0:276e7a263c35 177 crc_header = (crc_header << 8) | buffer[OTA_CRC32_OFS + 0];
MACRUM 0:276e7a263c35 178
MACRUM 0:276e7a263c35 179 /* calculate crc */
MACRUM 0:276e7a263c35 180 uint32_t crc_calculated = arm_uc_crc32(buffer, OTA_CRC32_OFS);
MACRUM 0:276e7a263c35 181
MACRUM 0:276e7a263c35 182 UC_PAAL_TRACE("CRC header: %" PRIX32, crc_header);
MACRUM 0:276e7a263c35 183 UC_PAAL_TRACE("CRC calculated: %" PRIX32, crc_calculated);
MACRUM 0:276e7a263c35 184
MACRUM 0:276e7a263c35 185 /* check crc before proceeding */
MACRUM 0:276e7a263c35 186 if (crc_header == crc_calculated)
MACRUM 0:276e7a263c35 187 {
MACRUM 0:276e7a263c35 188 /* parse size */
MACRUM 0:276e7a263c35 189 uint32_t size = buffer[OTA_SIZE_OFS + 3];
MACRUM 0:276e7a263c35 190 size = (size << 8) | buffer[OTA_SIZE_OFS + 2];
MACRUM 0:276e7a263c35 191 size = (size << 8) | buffer[OTA_SIZE_OFS + 1];
MACRUM 0:276e7a263c35 192 size = (size << 8) | buffer[OTA_SIZE_OFS + 0];
MACRUM 0:276e7a263c35 193
MACRUM 0:276e7a263c35 194 /* parse version */
MACRUM 0:276e7a263c35 195 uint64_t version = buffer[OTA_EPOCH_OFS + 7];
MACRUM 0:276e7a263c35 196 version = (version << 8) | buffer[OTA_EPOCH_OFS + 6];
MACRUM 0:276e7a263c35 197 version = (version << 8) | buffer[OTA_EPOCH_OFS + 5];
MACRUM 0:276e7a263c35 198 version = (version << 8) | buffer[OTA_EPOCH_OFS + 4];
MACRUM 0:276e7a263c35 199 version = (version << 8) | buffer[OTA_EPOCH_OFS + 3];
MACRUM 0:276e7a263c35 200 version = (version << 8) | buffer[OTA_EPOCH_OFS + 2];
MACRUM 0:276e7a263c35 201 version = (version << 8) | buffer[OTA_EPOCH_OFS + 1];
MACRUM 0:276e7a263c35 202 version = (version << 8) | buffer[OTA_EPOCH_OFS + 0];
MACRUM 0:276e7a263c35 203
MACRUM 0:276e7a263c35 204 /* copy hash */
MACRUM 0:276e7a263c35 205 for (size_t index = 0; index < ARM_UC_SHA256_SIZE; index++)
MACRUM 0:276e7a263c35 206 {
MACRUM 0:276e7a263c35 207 details->hash[index] = buffer[OTA_HASH_OFS + index];
MACRUM 0:276e7a263c35 208 }
MACRUM 0:276e7a263c35 209
MACRUM 0:276e7a263c35 210 details->size = size - HEADER_SIZE;
MACRUM 0:276e7a263c35 211 details->version = version;
MACRUM 0:276e7a263c35 212
MACRUM 0:276e7a263c35 213 UC_PAAL_TRACE("size: %" PRIu64, details->size);
MACRUM 0:276e7a263c35 214 UC_PAAL_TRACE("version: %" PRIu64, details->version);
MACRUM 0:276e7a263c35 215
MACRUM 0:276e7a263c35 216 #if 0
MACRUM 0:276e7a263c35 217 printf("hash: ");
MACRUM 0:276e7a263c35 218 for (size_t index = 0; index < ARM_UC_SHA256_SIZE; index++)
MACRUM 0:276e7a263c35 219 {
MACRUM 0:276e7a263c35 220 printf("%02X", details->hash[index]);
MACRUM 0:276e7a263c35 221 }
MACRUM 0:276e7a263c35 222 printf("\r\n");
MACRUM 0:276e7a263c35 223 #endif
MACRUM 0:276e7a263c35 224
MACRUM 0:276e7a263c35 225 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 226 }
MACRUM 0:276e7a263c35 227 else
MACRUM 0:276e7a263c35 228 {
MACRUM 0:276e7a263c35 229 UC_PAAL_ERR_MSG("header crc check failed");
MACRUM 0:276e7a263c35 230 }
MACRUM 0:276e7a263c35 231 }
MACRUM 0:276e7a263c35 232 else
MACRUM 0:276e7a263c35 233 {
MACRUM 0:276e7a263c35 234 UC_PAAL_ERR_MSG("invalid header");
MACRUM 0:276e7a263c35 235 }
MACRUM 0:276e7a263c35 236 }
MACRUM 0:276e7a263c35 237 else
MACRUM 0:276e7a263c35 238 {
MACRUM 0:276e7a263c35 239 UC_PAAL_ERR_MSG("error reading from flash");
MACRUM 0:276e7a263c35 240 }
MACRUM 0:276e7a263c35 241 }
MACRUM 0:276e7a263c35 242
MACRUM 0:276e7a263c35 243 return result;
MACRUM 0:276e7a263c35 244 }
MACRUM 0:276e7a263c35 245
MACRUM 0:276e7a263c35 246 /**
MACRUM 0:276e7a263c35 247 * @brief Find base address of either running or spare firmare slot.
MACRUM 0:276e7a263c35 248 *
MACRUM 0:276e7a263c35 249 * @param[in] find Enum specifying what to find (running or spare slot).
MACRUM 0:276e7a263c35 250 *
MACRUM 0:276e7a263c35 251 * @return Base address.
MACRUM 0:276e7a263c35 252 */
MACRUM 0:276e7a263c35 253 static uint32_t arm_uc_pal_find_base_address(base_address_t find)
MACRUM 0:276e7a263c35 254 {
MACRUM 0:276e7a263c35 255 uint32_t base_address = 0;
MACRUM 0:276e7a263c35 256
MACRUM 0:276e7a263c35 257 arm_uc_firmware_details_t slot_0 = { 0 };
MACRUM 0:276e7a263c35 258 arm_uc_firmware_details_t slot_1 = { 0 };
MACRUM 0:276e7a263c35 259
MACRUM 0:276e7a263c35 260 /* read header from both slots */
MACRUM 0:276e7a263c35 261 arm_uc_error_t result_0 = arm_uc_pal_get_realtek_header(OTA_REGION1_BASE, &slot_0);
MACRUM 0:276e7a263c35 262 arm_uc_error_t result_1 = arm_uc_pal_get_realtek_header(OTA_REGION2_BASE, &slot_1);
MACRUM 0:276e7a263c35 263
MACRUM 0:276e7a263c35 264 /* both headers are valid */
MACRUM 0:276e7a263c35 265 if ((result_0.error == ERR_NONE) && (result_1.error == ERR_NONE))
MACRUM 0:276e7a263c35 266 {
MACRUM 0:276e7a263c35 267 /* running firmware has the highest version number */
MACRUM 0:276e7a263c35 268 if (find == BASE_ADDRESS_RUNNING)
MACRUM 0:276e7a263c35 269 {
MACRUM 0:276e7a263c35 270 base_address = (slot_0.version >= slot_1.version) ? OTA_REGION1_BASE : OTA_REGION2_BASE;
MACRUM 0:276e7a263c35 271 }
MACRUM 0:276e7a263c35 272 /* spare firmware has the lowest version number */
MACRUM 0:276e7a263c35 273 else
MACRUM 0:276e7a263c35 274 {
MACRUM 0:276e7a263c35 275 /* same test, swap result */
MACRUM 0:276e7a263c35 276 base_address = (slot_0.version >= slot_1.version) ? OTA_REGION2_BASE : OTA_REGION1_BASE;
MACRUM 0:276e7a263c35 277 }
MACRUM 0:276e7a263c35 278 }
MACRUM 0:276e7a263c35 279 /* only slot0 has a valid header */
MACRUM 0:276e7a263c35 280 else if (result_0.error == ERR_NONE)
MACRUM 0:276e7a263c35 281 {
MACRUM 0:276e7a263c35 282 if (find == BASE_ADDRESS_RUNNING)
MACRUM 0:276e7a263c35 283 {
MACRUM 0:276e7a263c35 284 /* only valid header must be the running one */
MACRUM 0:276e7a263c35 285 base_address = OTA_REGION1_BASE;
MACRUM 0:276e7a263c35 286 }
MACRUM 0:276e7a263c35 287 else
MACRUM 0:276e7a263c35 288 {
MACRUM 0:276e7a263c35 289 /* slot with invalid header can be used as spare */
MACRUM 0:276e7a263c35 290 base_address = OTA_REGION2_BASE;
MACRUM 0:276e7a263c35 291 }
MACRUM 0:276e7a263c35 292 }
MACRUM 0:276e7a263c35 293 /* only slot1 has a valid header */
MACRUM 0:276e7a263c35 294 else if (result_1.error == ERR_NONE)
MACRUM 0:276e7a263c35 295 {
MACRUM 0:276e7a263c35 296 if (find == BASE_ADDRESS_RUNNING)
MACRUM 0:276e7a263c35 297 {
MACRUM 0:276e7a263c35 298 /* only valid header must be the running one */
MACRUM 0:276e7a263c35 299 base_address = OTA_REGION2_BASE;
MACRUM 0:276e7a263c35 300 }
MACRUM 0:276e7a263c35 301 else
MACRUM 0:276e7a263c35 302 {
MACRUM 0:276e7a263c35 303 /* slot with invalid header can be used as spare */
MACRUM 0:276e7a263c35 304 base_address = OTA_REGION1_BASE;
MACRUM 0:276e7a263c35 305 }
MACRUM 0:276e7a263c35 306 }
MACRUM 0:276e7a263c35 307
MACRUM 0:276e7a263c35 308 /* if both headers are invalid return 0 */
MACRUM 0:276e7a263c35 309
MACRUM 0:276e7a263c35 310 return base_address;
MACRUM 0:276e7a263c35 311 }
MACRUM 0:276e7a263c35 312
MACRUM 0:276e7a263c35 313 /*****************************************************************************/
MACRUM 0:276e7a263c35 314
MACRUM 0:276e7a263c35 315 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Initialize(void (*callback)(uint32_t))
MACRUM 0:276e7a263c35 316 {
MACRUM 0:276e7a263c35 317 arm_uc_error_t result = { .code = ERR_NONE };
MACRUM 0:276e7a263c35 318
MACRUM 0:276e7a263c35 319 arm_uc_pal_rtl8195am_callback = callback;
MACRUM 0:276e7a263c35 320
MACRUM 0:276e7a263c35 321 return result;
MACRUM 0:276e7a263c35 322 }
MACRUM 0:276e7a263c35 323
MACRUM 0:276e7a263c35 324 /**
MACRUM 0:276e7a263c35 325 * @brief Get maximum number of supported storage locations.
MACRUM 0:276e7a263c35 326 *
MACRUM 0:276e7a263c35 327 * @return Number of storage locations.
MACRUM 0:276e7a263c35 328 */
MACRUM 0:276e7a263c35 329 uint32_t ARM_UC_PAL_RTL8195AM_GetMaxID(void)
MACRUM 0:276e7a263c35 330 {
MACRUM 0:276e7a263c35 331 return 2;
MACRUM 0:276e7a263c35 332 }
MACRUM 0:276e7a263c35 333
MACRUM 0:276e7a263c35 334 /**
MACRUM 0:276e7a263c35 335 * @brief Prepare the storage layer for a new firmware image.
MACRUM 0:276e7a263c35 336 * @details The storage location is set up to receive an image with
MACRUM 0:276e7a263c35 337 * the details passed in the details struct.
MACRUM 0:276e7a263c35 338 *
MACRUM 0:276e7a263c35 339 * @param location Storage location ID.
MACRUM 0:276e7a263c35 340 * @param details Pointer to a struct with firmware details.
MACRUM 0:276e7a263c35 341 * @param buffer Temporary buffer for formatting and storing metadata.
MACRUM 0:276e7a263c35 342 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 343 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 344 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 345 */
MACRUM 0:276e7a263c35 346 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Prepare(uint32_t location,
MACRUM 0:276e7a263c35 347 const arm_uc_firmware_details_t* details,
MACRUM 0:276e7a263c35 348 arm_uc_buffer_t* buffer)
MACRUM 0:276e7a263c35 349 {
MACRUM 0:276e7a263c35 350 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 351
MACRUM 0:276e7a263c35 352 if (details && buffer && buffer->ptr)
MACRUM 0:276e7a263c35 353 {
MACRUM 0:276e7a263c35 354 UC_PAAL_TRACE("Prepare: %" PRIX32 " %" PRIX64 " %" PRIu64,
MACRUM 0:276e7a263c35 355 location,
MACRUM 0:276e7a263c35 356 details->size,
MACRUM 0:276e7a263c35 357 details->version);
MACRUM 0:276e7a263c35 358
MACRUM 0:276e7a263c35 359 /* find location for the spare slot */
MACRUM 0:276e7a263c35 360 arm_uc_base_address = arm_uc_pal_find_base_address(BASE_ADDRESS_SPARE);
MACRUM 0:276e7a263c35 361
MACRUM 0:276e7a263c35 362 UC_PAAL_TRACE("spare base: %" PRIX32, arm_uc_base_address);
MACRUM 0:276e7a263c35 363
MACRUM 0:276e7a263c35 364 /* check that the firmware can fit the spare slot */
MACRUM 0:276e7a263c35 365 if (((arm_uc_base_address == OTA_REGION1_BASE) && (details->size < OTA_REGION1_SIZE)) ||
MACRUM 0:276e7a263c35 366 ((arm_uc_base_address == OTA_REGION2_BASE) && (details->size < OTA_REGION2_SIZE)))
MACRUM 0:276e7a263c35 367 {
MACRUM 0:276e7a263c35 368 /* encode firmware details in buffer */
MACRUM 0:276e7a263c35 369 result = arm_uc_pal_create_realtek_header(details, buffer);
MACRUM 0:276e7a263c35 370
MACRUM 0:276e7a263c35 371 /* make space for new firmware */
MACRUM 0:276e7a263c35 372 if (result.error == ERR_NONE)
MACRUM 0:276e7a263c35 373 {
MACRUM 0:276e7a263c35 374 /* find end address */
MACRUM 0:276e7a263c35 375 uint32_t end_address = arm_uc_base_address + HEADER_SIZE + details->size;
MACRUM 0:276e7a263c35 376
MACRUM 0:276e7a263c35 377 /* erase */
MACRUM 0:276e7a263c35 378 uint32_t erase_address = arm_uc_base_address;
MACRUM 0:276e7a263c35 379
MACRUM 0:276e7a263c35 380 while (erase_address < end_address)
MACRUM 0:276e7a263c35 381 {
MACRUM 0:276e7a263c35 382 uint32_t sector_size = arm_uc_flashiap_get_sector_size(erase_address);
MACRUM 0:276e7a263c35 383
MACRUM 0:276e7a263c35 384 int status = arm_uc_flashiap_erase(erase_address, sector_size);
MACRUM 0:276e7a263c35 385
MACRUM 0:276e7a263c35 386 UC_PAAL_TRACE("erase: %" PRIX32 " %" PRIX32 " %d",
MACRUM 0:276e7a263c35 387 erase_address,
MACRUM 0:276e7a263c35 388 sector_size,
MACRUM 0:276e7a263c35 389 status);
MACRUM 0:276e7a263c35 390
MACRUM 0:276e7a263c35 391 if (status == 0)
MACRUM 0:276e7a263c35 392 {
MACRUM 0:276e7a263c35 393 erase_address += sector_size;
MACRUM 0:276e7a263c35 394 }
MACRUM 0:276e7a263c35 395 else
MACRUM 0:276e7a263c35 396 {
MACRUM 0:276e7a263c35 397 result.code = ERR_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 398 break;
MACRUM 0:276e7a263c35 399 }
MACRUM 0:276e7a263c35 400 }
MACRUM 0:276e7a263c35 401
MACRUM 0:276e7a263c35 402 /* write header */
MACRUM 0:276e7a263c35 403 if (result.error == ERR_NONE)
MACRUM 0:276e7a263c35 404 {
MACRUM 0:276e7a263c35 405 UC_PAAL_TRACE("program: %u %" PRIu32,
MACRUM 0:276e7a263c35 406 arm_uc_base_address,
MACRUM 0:276e7a263c35 407 buffer->size);
MACRUM 0:276e7a263c35 408
MACRUM 0:276e7a263c35 409 /* set default return code */
MACRUM 0:276e7a263c35 410 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 411
MACRUM 0:276e7a263c35 412 /* write header without CRC */
MACRUM 0:276e7a263c35 413 int status = arm_uc_flashiap_program(buffer->ptr,
MACRUM 0:276e7a263c35 414 arm_uc_base_address,
MACRUM 0:276e7a263c35 415 buffer->size);
MACRUM 0:276e7a263c35 416
MACRUM 0:276e7a263c35 417 if (status != 0)
MACRUM 0:276e7a263c35 418 {
MACRUM 0:276e7a263c35 419 /* set return code */
MACRUM 0:276e7a263c35 420 result.code = ERR_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 421 }
MACRUM 0:276e7a263c35 422
MACRUM 0:276e7a263c35 423 if (result.error == ERR_NONE)
MACRUM 0:276e7a263c35 424 {
MACRUM 0:276e7a263c35 425 /* signal done */
MACRUM 0:276e7a263c35 426 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_PREPARE_DONE);
MACRUM 0:276e7a263c35 427 }
MACRUM 0:276e7a263c35 428 else
MACRUM 0:276e7a263c35 429 {
MACRUM 0:276e7a263c35 430 UC_PAAL_ERR_MSG("flash program failed");
MACRUM 0:276e7a263c35 431 }
MACRUM 0:276e7a263c35 432 }
MACRUM 0:276e7a263c35 433 else
MACRUM 0:276e7a263c35 434 {
MACRUM 0:276e7a263c35 435 UC_PAAL_ERR_MSG("flash erase failed");
MACRUM 0:276e7a263c35 436 }
MACRUM 0:276e7a263c35 437 }
MACRUM 0:276e7a263c35 438 else
MACRUM 0:276e7a263c35 439 {
MACRUM 0:276e7a263c35 440 UC_PAAL_ERR_MSG("create header failed");
MACRUM 0:276e7a263c35 441 }
MACRUM 0:276e7a263c35 442 }
MACRUM 0:276e7a263c35 443 else
MACRUM 0:276e7a263c35 444 {
MACRUM 0:276e7a263c35 445 UC_PAAL_ERR_MSG("firmware larger than slot");
MACRUM 0:276e7a263c35 446 }
MACRUM 0:276e7a263c35 447 }
MACRUM 0:276e7a263c35 448
MACRUM 0:276e7a263c35 449 return result;
MACRUM 0:276e7a263c35 450 }
MACRUM 0:276e7a263c35 451
MACRUM 0:276e7a263c35 452 /**
MACRUM 0:276e7a263c35 453 * @brief Write a fragment to the indicated storage location.
MACRUM 0:276e7a263c35 454 * @details The storage location must have been allocated using the Prepare
MACRUM 0:276e7a263c35 455 * call. The call is expected to write the entire fragment before
MACRUM 0:276e7a263c35 456 * signaling completion.
MACRUM 0:276e7a263c35 457 *
MACRUM 0:276e7a263c35 458 * @param location Storage location ID.
MACRUM 0:276e7a263c35 459 * @param offset Offset in bytes to where the fragment should be written.
MACRUM 0:276e7a263c35 460 * @param buffer Pointer to buffer struct with fragment.
MACRUM 0:276e7a263c35 461 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 462 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 463 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 464 */
MACRUM 0:276e7a263c35 465 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Write(uint32_t location,
MACRUM 0:276e7a263c35 466 uint32_t offset,
MACRUM 0:276e7a263c35 467 const arm_uc_buffer_t* buffer)
MACRUM 0:276e7a263c35 468 {
MACRUM 0:276e7a263c35 469 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 470
MACRUM 0:276e7a263c35 471 if (buffer && buffer->ptr)
MACRUM 0:276e7a263c35 472 {
MACRUM 0:276e7a263c35 473 /* find location address */
MACRUM 0:276e7a263c35 474 uint32_t physical_address = arm_uc_base_address + HEADER_SIZE + offset;
MACRUM 0:276e7a263c35 475
MACRUM 0:276e7a263c35 476 UC_PAAL_TRACE("Write: %p %" PRIX32 " %" PRIX32 " %" PRIX32,
MACRUM 0:276e7a263c35 477 buffer->ptr,
MACRUM 0:276e7a263c35 478 buffer->size,
MACRUM 0:276e7a263c35 479 offset,
MACRUM 0:276e7a263c35 480 physical_address);
MACRUM 0:276e7a263c35 481
MACRUM 0:276e7a263c35 482 /* set default return code */
MACRUM 0:276e7a263c35 483 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 484
MACRUM 0:276e7a263c35 485 for (size_t index = 0; index < buffer->size; )
MACRUM 0:276e7a263c35 486 {
MACRUM 0:276e7a263c35 487 /* write aligned */
MACRUM 0:276e7a263c35 488 size_t modulo = (physical_address + index) % FLASH_PAGE_SIZE;
MACRUM 0:276e7a263c35 489 size_t remaining = buffer->size - index;
MACRUM 0:276e7a263c35 490 size_t write_size = 0;
MACRUM 0:276e7a263c35 491
MACRUM 0:276e7a263c35 492 /* fill remaining flash page */
MACRUM 0:276e7a263c35 493 if (modulo > 0)
MACRUM 0:276e7a263c35 494 {
MACRUM 0:276e7a263c35 495 write_size = modulo;
MACRUM 0:276e7a263c35 496 }
MACRUM 0:276e7a263c35 497 /* write last page */
MACRUM 0:276e7a263c35 498 else if (remaining < FLASH_PAGE_SIZE)
MACRUM 0:276e7a263c35 499 {
MACRUM 0:276e7a263c35 500 write_size = remaining;
MACRUM 0:276e7a263c35 501 }
MACRUM 0:276e7a263c35 502 /* write full page */
MACRUM 0:276e7a263c35 503 else
MACRUM 0:276e7a263c35 504 {
MACRUM 0:276e7a263c35 505 write_size = FLASH_PAGE_SIZE;
MACRUM 0:276e7a263c35 506 }
MACRUM 0:276e7a263c35 507
MACRUM 0:276e7a263c35 508 int status = arm_uc_flashiap_program(&buffer->ptr[index],
MACRUM 0:276e7a263c35 509 physical_address + index,
MACRUM 0:276e7a263c35 510 write_size);
MACRUM 0:276e7a263c35 511
MACRUM 0:276e7a263c35 512 if (status != 0)
MACRUM 0:276e7a263c35 513 {
MACRUM 0:276e7a263c35 514 /* set return code */
MACRUM 0:276e7a263c35 515 result.code = ERR_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 516 break;
MACRUM 0:276e7a263c35 517 }
MACRUM 0:276e7a263c35 518
MACRUM 0:276e7a263c35 519 index += write_size;
MACRUM 0:276e7a263c35 520 }
MACRUM 0:276e7a263c35 521
MACRUM 0:276e7a263c35 522 if (result.error == ERR_NONE)
MACRUM 0:276e7a263c35 523 {
MACRUM 0:276e7a263c35 524 /* signal done */
MACRUM 0:276e7a263c35 525 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_WRITE_DONE);
MACRUM 0:276e7a263c35 526 }
MACRUM 0:276e7a263c35 527 else
MACRUM 0:276e7a263c35 528 {
MACRUM 0:276e7a263c35 529 UC_PAAL_ERR_MSG("flash program failed");
MACRUM 0:276e7a263c35 530 }
MACRUM 0:276e7a263c35 531 }
MACRUM 0:276e7a263c35 532
MACRUM 0:276e7a263c35 533 return result;
MACRUM 0:276e7a263c35 534 }
MACRUM 0:276e7a263c35 535
MACRUM 0:276e7a263c35 536 /**
MACRUM 0:276e7a263c35 537 * @brief Close storage location for writing and flush pending data.
MACRUM 0:276e7a263c35 538 *
MACRUM 0:276e7a263c35 539 * @param location Storage location ID.
MACRUM 0:276e7a263c35 540 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 541 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 542 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 543 */
MACRUM 0:276e7a263c35 544 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Finalize(uint32_t location)
MACRUM 0:276e7a263c35 545 {
MACRUM 0:276e7a263c35 546 arm_uc_error_t result = { .code = ERR_NONE };
MACRUM 0:276e7a263c35 547
MACRUM 0:276e7a263c35 548 UC_PAAL_TRACE("Finalize");
MACRUM 0:276e7a263c35 549
MACRUM 0:276e7a263c35 550 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_FINALIZE_DONE);
MACRUM 0:276e7a263c35 551
MACRUM 0:276e7a263c35 552 return result;
MACRUM 0:276e7a263c35 553 }
MACRUM 0:276e7a263c35 554
MACRUM 0:276e7a263c35 555 /**
MACRUM 0:276e7a263c35 556 * @brief Read a fragment from the indicated storage location.
MACRUM 0:276e7a263c35 557 * @details The function will read until the buffer is full or the end of
MACRUM 0:276e7a263c35 558 * the storage location has been reached. The actual amount of
MACRUM 0:276e7a263c35 559 * bytes read is set in the buffer struct.
MACRUM 0:276e7a263c35 560 *
MACRUM 0:276e7a263c35 561 * @param location Storage location ID.
MACRUM 0:276e7a263c35 562 * @param offset Offset in bytes to read from.
MACRUM 0:276e7a263c35 563 * @param buffer Pointer to buffer struct to store fragment. buffer->size
MACRUM 0:276e7a263c35 564 * contains the intended read size.
MACRUM 0:276e7a263c35 565 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 566 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 567 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 568 * buffer->size contains actual bytes read on return.
MACRUM 0:276e7a263c35 569 */
MACRUM 0:276e7a263c35 570 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Read(uint32_t location,
MACRUM 0:276e7a263c35 571 uint32_t offset,
MACRUM 0:276e7a263c35 572 arm_uc_buffer_t* buffer)
MACRUM 0:276e7a263c35 573 {
MACRUM 0:276e7a263c35 574 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 575
MACRUM 0:276e7a263c35 576 if (buffer && buffer->ptr)
MACRUM 0:276e7a263c35 577 {
MACRUM 0:276e7a263c35 578 /* find the base address for the spare slot if not already set */
MACRUM 0:276e7a263c35 579 if (arm_uc_base_address == 0)
MACRUM 0:276e7a263c35 580 {
MACRUM 0:276e7a263c35 581 arm_uc_base_address = arm_uc_pal_find_base_address(BASE_ADDRESS_SPARE);
MACRUM 0:276e7a263c35 582 }
MACRUM 0:276e7a263c35 583
MACRUM 0:276e7a263c35 584 /* calculate actual physical address */
MACRUM 0:276e7a263c35 585 uint32_t physical_address = arm_uc_base_address + HEADER_SIZE + offset;
MACRUM 0:276e7a263c35 586
MACRUM 0:276e7a263c35 587 UC_PAAL_TRACE("Read: %" PRIX32 " %" PRIX32 " %" PRIX32,
MACRUM 0:276e7a263c35 588 physical_address,
MACRUM 0:276e7a263c35 589 offset,
MACRUM 0:276e7a263c35 590 buffer->size);
MACRUM 0:276e7a263c35 591
MACRUM 0:276e7a263c35 592 uint32_t read_size = buffer->size;
MACRUM 0:276e7a263c35 593
MACRUM 0:276e7a263c35 594 int status = arm_uc_flashiap_read(buffer->ptr, physical_address, read_size);
MACRUM 0:276e7a263c35 595
MACRUM 0:276e7a263c35 596 if (status == 0)
MACRUM 0:276e7a263c35 597 {
MACRUM 0:276e7a263c35 598 /* set buffer size */
MACRUM 0:276e7a263c35 599 buffer->size = read_size;
MACRUM 0:276e7a263c35 600
MACRUM 0:276e7a263c35 601 /* set return code */
MACRUM 0:276e7a263c35 602 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 603
MACRUM 0:276e7a263c35 604 /* signal done */
MACRUM 0:276e7a263c35 605 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_READ_DONE);
MACRUM 0:276e7a263c35 606 }
MACRUM 0:276e7a263c35 607 else
MACRUM 0:276e7a263c35 608 {
MACRUM 0:276e7a263c35 609 UC_PAAL_ERR_MSG("flash read failed");
MACRUM 0:276e7a263c35 610 }
MACRUM 0:276e7a263c35 611 }
MACRUM 0:276e7a263c35 612
MACRUM 0:276e7a263c35 613 return result;
MACRUM 0:276e7a263c35 614 }
MACRUM 0:276e7a263c35 615
MACRUM 0:276e7a263c35 616 /**
MACRUM 0:276e7a263c35 617 * @brief Set the firmware image in the slot to be the new active image.
MACRUM 0:276e7a263c35 618 * @details This call is responsible for initiating the process for
MACRUM 0:276e7a263c35 619 * applying a new/different image. Depending on the platform this
MACRUM 0:276e7a263c35 620 * could be:
MACRUM 0:276e7a263c35 621 * * An empty call, if the installer can deduce which slot to
MACRUM 0:276e7a263c35 622 * choose from based on the firmware details.
MACRUM 0:276e7a263c35 623 * * Setting a flag to indicate which slot to use next.
MACRUM 0:276e7a263c35 624 * * Decompressing/decrypting/installing the firmware image on
MACRUM 0:276e7a263c35 625 * top of another.
MACRUM 0:276e7a263c35 626 *
MACRUM 0:276e7a263c35 627 * @param location Storage location ID.
MACRUM 0:276e7a263c35 628 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 629 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 630 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 631 */
MACRUM 0:276e7a263c35 632 arm_uc_error_t ARM_UC_PAL_RTL8195AM_Activate(uint32_t location)
MACRUM 0:276e7a263c35 633 {
MACRUM 0:276e7a263c35 634 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 635
MACRUM 0:276e7a263c35 636 UC_PAAL_TRACE("Activate");
MACRUM 0:276e7a263c35 637
MACRUM 0:276e7a263c35 638 uint8_t buffer[HEADER_SIZE] = { 0 };
MACRUM 0:276e7a263c35 639
MACRUM 0:276e7a263c35 640 int status = arm_uc_flashiap_read(buffer, arm_uc_base_address, sizeof(buffer));
MACRUM 0:276e7a263c35 641
MACRUM 0:276e7a263c35 642 if (status == 0)
MACRUM 0:276e7a263c35 643 {
MACRUM 0:276e7a263c35 644 /* calculate CRC */
MACRUM 0:276e7a263c35 645 uint32_t crc = arm_uc_crc32(buffer, OTA_CRC32_OFS);
MACRUM 0:276e7a263c35 646
MACRUM 0:276e7a263c35 647 buffer[0] = crc & 0xFF;
MACRUM 0:276e7a263c35 648 buffer[1] = (crc >> 8) & 0xFF;
MACRUM 0:276e7a263c35 649 buffer[2] = (crc >> 16) & 0xFF;
MACRUM 0:276e7a263c35 650 buffer[3] = (crc >> 24) & 0xFF;
MACRUM 0:276e7a263c35 651
MACRUM 0:276e7a263c35 652 /* set crc in header to signal the bootloader that the image is ready */
MACRUM 0:276e7a263c35 653 status = arm_uc_flashiap_program(buffer, arm_uc_base_address + OTA_CRC32_OFS, 4);
MACRUM 0:276e7a263c35 654
MACRUM 0:276e7a263c35 655 if (status == 0)
MACRUM 0:276e7a263c35 656 {
MACRUM 0:276e7a263c35 657 /* set return code */
MACRUM 0:276e7a263c35 658 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 659
MACRUM 0:276e7a263c35 660 /* signal done */
MACRUM 0:276e7a263c35 661 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_ACTIVATE_DONE);
MACRUM 0:276e7a263c35 662 }
MACRUM 0:276e7a263c35 663 }
MACRUM 0:276e7a263c35 664
MACRUM 0:276e7a263c35 665 return result;
MACRUM 0:276e7a263c35 666 }
MACRUM 0:276e7a263c35 667
MACRUM 0:276e7a263c35 668 /**
MACRUM 0:276e7a263c35 669 * @brief Get firmware details for the firmware image in the slot passed.
MACRUM 0:276e7a263c35 670 * @details This call populates the passed details struct with information
MACRUM 0:276e7a263c35 671 * about the firmware image in the slot passed. Only the fields
MACRUM 0:276e7a263c35 672 * marked as supported in the capabilities bitmap will have valid
MACRUM 0:276e7a263c35 673 * values.
MACRUM 0:276e7a263c35 674 *
MACRUM 0:276e7a263c35 675 * @param details Pointer to firmware details struct to be populated.
MACRUM 0:276e7a263c35 676 * @return Returns ERR_NONE on accept, and signals the event handler with
MACRUM 0:276e7a263c35 677 * either DONE or ERROR when complete.
MACRUM 0:276e7a263c35 678 * Returns ERR_INVALID_PARAMETER on reject, and no signal is sent.
MACRUM 0:276e7a263c35 679 */
MACRUM 0:276e7a263c35 680 arm_uc_error_t ARM_UC_PAL_RTL8195AM_GetFirmwareDetails(
MACRUM 0:276e7a263c35 681 uint32_t location,
MACRUM 0:276e7a263c35 682 arm_uc_firmware_details_t* details)
MACRUM 0:276e7a263c35 683 {
MACRUM 0:276e7a263c35 684 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 685
MACRUM 0:276e7a263c35 686 /* this function is only used by the mbed Bootloader */
MACRUM 0:276e7a263c35 687
MACRUM 0:276e7a263c35 688 return result;
MACRUM 0:276e7a263c35 689 }
MACRUM 0:276e7a263c35 690
MACRUM 0:276e7a263c35 691 /*****************************************************************************/
MACRUM 0:276e7a263c35 692
MACRUM 0:276e7a263c35 693 arm_uc_error_t ARM_UC_PAL_RTL8195AM_GetActiveDetails(arm_uc_firmware_details_t* details)
MACRUM 0:276e7a263c35 694 {
MACRUM 0:276e7a263c35 695 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 696
MACRUM 0:276e7a263c35 697 if (details)
MACRUM 0:276e7a263c35 698 {
MACRUM 0:276e7a263c35 699 UC_PAAL_TRACE("GetActiveDetails");
MACRUM 0:276e7a263c35 700
MACRUM 0:276e7a263c35 701 /* find running slot */
MACRUM 0:276e7a263c35 702 uint32_t base_address = arm_uc_pal_find_base_address(BASE_ADDRESS_RUNNING);
MACRUM 0:276e7a263c35 703
MACRUM 0:276e7a263c35 704 UC_PAAL_TRACE("active base: %" PRIX32, base_address);
MACRUM 0:276e7a263c35 705
MACRUM 0:276e7a263c35 706 result = arm_uc_pal_get_realtek_header(base_address, details);
MACRUM 0:276e7a263c35 707
MACRUM 0:276e7a263c35 708 /* signal event if operation was successful */
MACRUM 0:276e7a263c35 709 if (result.error == ERR_NONE)
MACRUM 0:276e7a263c35 710 {
MACRUM 0:276e7a263c35 711 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_GET_ACTIVE_FIRMWARE_DETAILS_DONE);
MACRUM 0:276e7a263c35 712 }
MACRUM 0:276e7a263c35 713 }
MACRUM 0:276e7a263c35 714
MACRUM 0:276e7a263c35 715 return result;
MACRUM 0:276e7a263c35 716 }
MACRUM 0:276e7a263c35 717
MACRUM 0:276e7a263c35 718 arm_uc_error_t ARM_UC_PAL_RTL8195AM_GetInstallerDetails(arm_uc_installer_details_t* details)
MACRUM 0:276e7a263c35 719 {
MACRUM 0:276e7a263c35 720 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
MACRUM 0:276e7a263c35 721
MACRUM 0:276e7a263c35 722 if (details)
MACRUM 0:276e7a263c35 723 {
MACRUM 0:276e7a263c35 724 /* reset installer details struct */
MACRUM 0:276e7a263c35 725 memset(&details->arm_hash, 0, ARM_UC_SHA256_SIZE);
MACRUM 0:276e7a263c35 726 memset(&details->oem_hash, 0, ARM_UC_SHA256_SIZE);
MACRUM 0:276e7a263c35 727 details->layout = 0;
MACRUM 0:276e7a263c35 728
MACRUM 0:276e7a263c35 729 /* the magic tag identifies the bootloader it is compatible with */
MACRUM 0:276e7a263c35 730 details->oem_hash[0] = (OTA_TAG_ID >> 24) & 0xFF;
MACRUM 0:276e7a263c35 731 details->oem_hash[1] = (OTA_TAG_ID >> 16) & 0xFF;
MACRUM 0:276e7a263c35 732 details->oem_hash[2] = (OTA_TAG_ID >> 8) & 0xFF;
MACRUM 0:276e7a263c35 733 details->oem_hash[3] = OTA_TAG_ID & 0xFF;
MACRUM 0:276e7a263c35 734
MACRUM 0:276e7a263c35 735 details->oem_hash[4] = (OTA_VER_ID >> 24) & 0xFF;
MACRUM 0:276e7a263c35 736 details->oem_hash[5] = (OTA_VER_ID >> 16) & 0xFF;
MACRUM 0:276e7a263c35 737 details->oem_hash[6] = (OTA_VER_ID >> 8) & 0xFF;
MACRUM 0:276e7a263c35 738 details->oem_hash[7] = OTA_VER_ID & 0xFF;
MACRUM 0:276e7a263c35 739
MACRUM 0:276e7a263c35 740 result.code = ERR_NONE;
MACRUM 0:276e7a263c35 741
MACRUM 0:276e7a263c35 742 arm_uc_pal_rtl8195am_signal_internal(ARM_UC_PAAL_EVENT_GET_INSTALLER_DETAILS_DONE);
MACRUM 0:276e7a263c35 743 }
MACRUM 0:276e7a263c35 744
MACRUM 0:276e7a263c35 745 return result;
MACRUM 0:276e7a263c35 746 }
MACRUM 0:276e7a263c35 747
MACRUM 0:276e7a263c35 748 ARM_UC_PAAL_UPDATE_CAPABILITIES ARM_UC_PAL_RTL8195AM_GetCapabilities(void)
MACRUM 0:276e7a263c35 749 {
MACRUM 0:276e7a263c35 750 ARM_UC_PAAL_UPDATE_CAPABILITIES result = {
MACRUM 0:276e7a263c35 751 .installer_arm_hash = 0,
MACRUM 0:276e7a263c35 752 .installer_oem_hash = 0,
MACRUM 0:276e7a263c35 753 .installer_layout = 0,
MACRUM 0:276e7a263c35 754 .firmware_hash = 1,
MACRUM 0:276e7a263c35 755 .firmware_hmac = 0,
MACRUM 0:276e7a263c35 756 .firmware_campaign = 0,
MACRUM 0:276e7a263c35 757 .firmware_version = 1,
MACRUM 0:276e7a263c35 758 .firmware_size = 1
MACRUM 0:276e7a263c35 759 };
MACRUM 0:276e7a263c35 760
MACRUM 0:276e7a263c35 761 return result;
MACRUM 0:276e7a263c35 762 }
MACRUM 0:276e7a263c35 763
MACRUM 0:276e7a263c35 764 const ARM_UC_PAAL_UPDATE ARM_UCP_REALTEK_RTL8195AM =
MACRUM 0:276e7a263c35 765 {
MACRUM 0:276e7a263c35 766 .Initialize = ARM_UC_PAL_RTL8195AM_Initialize,
MACRUM 0:276e7a263c35 767 .GetCapabilities = ARM_UC_PAL_RTL8195AM_GetCapabilities,
MACRUM 0:276e7a263c35 768 .GetMaxID = ARM_UC_PAL_RTL8195AM_GetMaxID,
MACRUM 0:276e7a263c35 769 .Prepare = ARM_UC_PAL_RTL8195AM_Prepare,
MACRUM 0:276e7a263c35 770 .Write = ARM_UC_PAL_RTL8195AM_Write,
MACRUM 0:276e7a263c35 771 .Finalize = ARM_UC_PAL_RTL8195AM_Finalize,
MACRUM 0:276e7a263c35 772 .Read = ARM_UC_PAL_RTL8195AM_Read,
MACRUM 0:276e7a263c35 773 .Activate = ARM_UC_PAL_RTL8195AM_Activate,
MACRUM 0:276e7a263c35 774 .GetActiveFirmwareDetails = ARM_UC_PAL_RTL8195AM_GetActiveDetails,
MACRUM 0:276e7a263c35 775 .GetFirmwareDetails = ARM_UC_PAL_RTL8195AM_GetFirmwareDetails,
MACRUM 0:276e7a263c35 776 .GetInstallerDetails = ARM_UC_PAL_RTL8195AM_GetInstallerDetails
MACRUM 0:276e7a263c35 777 };
MACRUM 0:276e7a263c35 778
MACRUM 0:276e7a263c35 779 #endif