14f6ad66aSAchin Gupta /* 21b70db06SDan Handley * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. 34f6ad66aSAchin Gupta * 44f6ad66aSAchin Gupta * Redistribution and use in source and binary forms, with or without 54f6ad66aSAchin Gupta * modification, are permitted provided that the following conditions are met: 64f6ad66aSAchin Gupta * 74f6ad66aSAchin Gupta * Redistributions of source code must retain the above copyright notice, this 84f6ad66aSAchin Gupta * list of conditions and the following disclaimer. 94f6ad66aSAchin Gupta * 104f6ad66aSAchin Gupta * Redistributions in binary form must reproduce the above copyright notice, 114f6ad66aSAchin Gupta * this list of conditions and the following disclaimer in the documentation 124f6ad66aSAchin Gupta * and/or other materials provided with the distribution. 134f6ad66aSAchin Gupta * 144f6ad66aSAchin Gupta * Neither the name of ARM nor the names of its contributors may be used 154f6ad66aSAchin Gupta * to endorse or promote products derived from this software without specific 164f6ad66aSAchin Gupta * prior written permission. 174f6ad66aSAchin Gupta * 184f6ad66aSAchin Gupta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 194f6ad66aSAchin Gupta * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 204f6ad66aSAchin Gupta * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 214f6ad66aSAchin Gupta * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 224f6ad66aSAchin Gupta * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 234f6ad66aSAchin Gupta * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 244f6ad66aSAchin Gupta * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 254f6ad66aSAchin Gupta * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 264f6ad66aSAchin Gupta * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 274f6ad66aSAchin Gupta * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 284f6ad66aSAchin Gupta * POSSIBILITY OF SUCH DAMAGE. 294f6ad66aSAchin Gupta */ 304f6ad66aSAchin Gupta 3197043ac9SDan Handley #include <arch.h> 324f6ad66aSAchin Gupta #include <arch_helpers.h> 3397043ac9SDan Handley #include <assert.h> 341779ba6bSJuan Castillo #include <auth_mod.h> 354f6ad66aSAchin Gupta #include <bl_common.h> 3635e98e55SDan Handley #include <debug.h> 378f55dfb4SSandrine Bailleux #include <errno.h> 3897043ac9SDan Handley #include <io_storage.h> 3997043ac9SDan Handley #include <platform.h> 40fedbc049SJuan Castillo #include <string.h> 414f6ad66aSAchin Gupta 424f6ad66aSAchin Gupta unsigned long page_align(unsigned long value, unsigned dir) 434f6ad66aSAchin Gupta { 444f6ad66aSAchin Gupta unsigned long page_size = 1 << FOUR_KB_SHIFT; 454f6ad66aSAchin Gupta 464f6ad66aSAchin Gupta /* Round up the limit to the next page boundary */ 474f6ad66aSAchin Gupta if (value & (page_size - 1)) { 484f6ad66aSAchin Gupta value &= ~(page_size - 1); 494f6ad66aSAchin Gupta if (dir == UP) 504f6ad66aSAchin Gupta value += page_size; 514f6ad66aSAchin Gupta } 524f6ad66aSAchin Gupta 534f6ad66aSAchin Gupta return value; 544f6ad66aSAchin Gupta } 554f6ad66aSAchin Gupta 564f6ad66aSAchin Gupta static inline unsigned int is_page_aligned (unsigned long addr) { 574f6ad66aSAchin Gupta const unsigned long page_size = 1 << FOUR_KB_SHIFT; 584f6ad66aSAchin Gupta 594f6ad66aSAchin Gupta return (addr & (page_size - 1)) == 0; 604f6ad66aSAchin Gupta } 614f6ad66aSAchin Gupta 628f55dfb4SSandrine Bailleux /****************************************************************************** 638f55dfb4SSandrine Bailleux * Determine whether the memory region delimited by 'addr' and 'size' is free, 648f55dfb4SSandrine Bailleux * given the extents of free memory. 658f55dfb4SSandrine Bailleux * Return 1 if it is free, 0 otherwise. 668f55dfb4SSandrine Bailleux *****************************************************************************/ 678f55dfb4SSandrine Bailleux static int is_mem_free(uint64_t free_base, size_t free_size, 688f55dfb4SSandrine Bailleux uint64_t addr, size_t size) 694f6ad66aSAchin Gupta { 708f55dfb4SSandrine Bailleux return (addr >= free_base) && (addr + size <= free_base + free_size); 714f6ad66aSAchin Gupta } 724f6ad66aSAchin Gupta 738f55dfb4SSandrine Bailleux /****************************************************************************** 748f55dfb4SSandrine Bailleux * Inside a given memory region, determine whether a sub-region of memory is 758f55dfb4SSandrine Bailleux * closer from the top or the bottom of the encompassing region. Return the 768f55dfb4SSandrine Bailleux * size of the smallest chunk of free memory surrounding the sub-region in 778f55dfb4SSandrine Bailleux * 'small_chunk_size'. 788f55dfb4SSandrine Bailleux *****************************************************************************/ 798f55dfb4SSandrine Bailleux static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end, 808f55dfb4SSandrine Bailleux uint64_t submem_start, uint64_t submem_end, 818f55dfb4SSandrine Bailleux size_t *small_chunk_size) 828f55dfb4SSandrine Bailleux { 838f55dfb4SSandrine Bailleux size_t top_chunk_size, bottom_chunk_size; 844f6ad66aSAchin Gupta 858f55dfb4SSandrine Bailleux assert(mem_start <= submem_start); 868f55dfb4SSandrine Bailleux assert(submem_start <= submem_end); 878f55dfb4SSandrine Bailleux assert(submem_end <= mem_end); 888f55dfb4SSandrine Bailleux assert(small_chunk_size != NULL); 898f55dfb4SSandrine Bailleux 908f55dfb4SSandrine Bailleux top_chunk_size = mem_end - submem_end; 918f55dfb4SSandrine Bailleux bottom_chunk_size = submem_start - mem_start; 928f55dfb4SSandrine Bailleux 938f55dfb4SSandrine Bailleux if (top_chunk_size < bottom_chunk_size) { 948f55dfb4SSandrine Bailleux *small_chunk_size = top_chunk_size; 958f55dfb4SSandrine Bailleux return TOP; 968f55dfb4SSandrine Bailleux } else { 978f55dfb4SSandrine Bailleux *small_chunk_size = bottom_chunk_size; 988f55dfb4SSandrine Bailleux return BOTTOM; 998f55dfb4SSandrine Bailleux } 1008f55dfb4SSandrine Bailleux } 1018f55dfb4SSandrine Bailleux 1028f55dfb4SSandrine Bailleux /****************************************************************************** 1038f55dfb4SSandrine Bailleux * Reserve the memory region delimited by 'addr' and 'size'. The extents of free 1048f55dfb4SSandrine Bailleux * memory are passed in 'free_base' and 'free_size' and they will be updated to 1058f55dfb4SSandrine Bailleux * reflect the memory usage. 1068f55dfb4SSandrine Bailleux * The caller must ensure the memory to reserve is free. 1078f55dfb4SSandrine Bailleux *****************************************************************************/ 1088f55dfb4SSandrine Bailleux void reserve_mem(uint64_t *free_base, size_t *free_size, 1098f55dfb4SSandrine Bailleux uint64_t addr, size_t size) 1108f55dfb4SSandrine Bailleux { 1118f55dfb4SSandrine Bailleux size_t discard_size; 1128f55dfb4SSandrine Bailleux size_t reserved_size; 1138f55dfb4SSandrine Bailleux unsigned int pos; 1148f55dfb4SSandrine Bailleux 1158f55dfb4SSandrine Bailleux assert(free_base != NULL); 1168f55dfb4SSandrine Bailleux assert(free_size != NULL); 1178f55dfb4SSandrine Bailleux assert(is_mem_free(*free_base, *free_size, addr, size)); 1188f55dfb4SSandrine Bailleux 1198f55dfb4SSandrine Bailleux pos = choose_mem_pos(*free_base, *free_base + *free_size, 1208f55dfb4SSandrine Bailleux addr, addr + size, 1218f55dfb4SSandrine Bailleux &discard_size); 1228f55dfb4SSandrine Bailleux 1238f55dfb4SSandrine Bailleux reserved_size = size + discard_size; 1248f55dfb4SSandrine Bailleux *free_size -= reserved_size; 1258f55dfb4SSandrine Bailleux 1268f55dfb4SSandrine Bailleux if (pos == BOTTOM) 1278f55dfb4SSandrine Bailleux *free_base = addr + size; 1288f55dfb4SSandrine Bailleux 1291b70db06SDan Handley VERBOSE("Reserved 0x%lx bytes (discarded 0x%lx bytes %s)\n", 1308f55dfb4SSandrine Bailleux reserved_size, discard_size, 1318f55dfb4SSandrine Bailleux pos == TOP ? "above" : "below"); 1324f6ad66aSAchin Gupta } 1334f6ad66aSAchin Gupta 1344f6ad66aSAchin Gupta static void dump_load_info(unsigned long image_load_addr, 1354f6ad66aSAchin Gupta unsigned long image_size, 136fb037bfbSDan Handley const meminfo_t *mem_layout) 1374f6ad66aSAchin Gupta { 1386ad2e461SDan Handley INFO("Trying to load image at address 0x%lx, size = 0x%lx\n", 1394f6ad66aSAchin Gupta image_load_addr, image_size); 1406ad2e461SDan Handley INFO("Current memory layout:\n"); 1416ad2e461SDan Handley INFO(" total region = [0x%lx, 0x%lx]\n", mem_layout->total_base, 1424f6ad66aSAchin Gupta mem_layout->total_base + mem_layout->total_size); 1436ad2e461SDan Handley INFO(" free region = [0x%lx, 0x%lx]\n", mem_layout->free_base, 1444f6ad66aSAchin Gupta mem_layout->free_base + mem_layout->free_size); 1454f6ad66aSAchin Gupta } 1464f6ad66aSAchin Gupta 147ee9ad785SRyan Harkin /* Generic function to return the size of an image */ 14816948ae1SJuan Castillo unsigned long image_size(unsigned int image_id) 149ee9ad785SRyan Harkin { 150625de1d4SDan Handley uintptr_t dev_handle; 151625de1d4SDan Handley uintptr_t image_handle; 152625de1d4SDan Handley uintptr_t image_spec; 153ee9ad785SRyan Harkin size_t image_size = 0; 154*e098e244SJuan Castillo int io_result; 155ee9ad785SRyan Harkin 156ee9ad785SRyan Harkin /* Obtain a reference to the image by querying the platform layer */ 15716948ae1SJuan Castillo io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 158*e098e244SJuan Castillo if (io_result != 0) { 15916948ae1SJuan Castillo WARN("Failed to obtain reference to image id=%u (%i)\n", 16016948ae1SJuan Castillo image_id, io_result); 161ee9ad785SRyan Harkin return 0; 162ee9ad785SRyan Harkin } 163ee9ad785SRyan Harkin 164ee9ad785SRyan Harkin /* Attempt to access the image */ 165ee9ad785SRyan Harkin io_result = io_open(dev_handle, image_spec, &image_handle); 166*e098e244SJuan Castillo if (io_result != 0) { 16716948ae1SJuan Castillo WARN("Failed to access image id=%u (%i)\n", 16816948ae1SJuan Castillo image_id, io_result); 169ee9ad785SRyan Harkin return 0; 170ee9ad785SRyan Harkin } 171ee9ad785SRyan Harkin 172ee9ad785SRyan Harkin /* Find the size of the image */ 173ee9ad785SRyan Harkin io_result = io_size(image_handle, &image_size); 174*e098e244SJuan Castillo if ((io_result != 0) || (image_size == 0)) { 17516948ae1SJuan Castillo WARN("Failed to determine the size of the image id=%u (%i)\n", 17616948ae1SJuan Castillo image_id, io_result); 177ee9ad785SRyan Harkin } 178ee9ad785SRyan Harkin io_result = io_close(image_handle); 179ee9ad785SRyan Harkin /* Ignore improbable/unrecoverable error in 'close' */ 180ee9ad785SRyan Harkin 181ee9ad785SRyan Harkin /* TODO: Consider maintaining open device connection from this 182ee9ad785SRyan Harkin * bootloader stage 183ee9ad785SRyan Harkin */ 184ee9ad785SRyan Harkin io_result = io_dev_close(dev_handle); 185ee9ad785SRyan Harkin /* Ignore improbable/unrecoverable error in 'dev_close' */ 186ee9ad785SRyan Harkin 187ee9ad785SRyan Harkin return image_size; 188ee9ad785SRyan Harkin } 1898f55dfb4SSandrine Bailleux 1904f6ad66aSAchin Gupta /******************************************************************************* 1918f55dfb4SSandrine Bailleux * Generic function to load an image at a specific address given a name and 1928f55dfb4SSandrine Bailleux * extents of free memory. It updates the memory layout if the load is 1938f55dfb4SSandrine Bailleux * successful, as well as the image information and the entry point information. 1948f55dfb4SSandrine Bailleux * The caller might pass a NULL pointer for the entry point if it is not 1958f55dfb4SSandrine Bailleux * interested in this information, e.g. because the image just needs to be 1968f55dfb4SSandrine Bailleux * loaded in memory but won't ever be executed. 1978f55dfb4SSandrine Bailleux * Returns 0 on success, a negative error code otherwise. 1984f6ad66aSAchin Gupta ******************************************************************************/ 1994112bfa0SVikram Kanigiri int load_image(meminfo_t *mem_layout, 20016948ae1SJuan Castillo unsigned int image_id, 2011779ba6bSJuan Castillo uintptr_t image_base, 2024112bfa0SVikram Kanigiri image_info_t *image_data, 2034112bfa0SVikram Kanigiri entry_point_info_t *entry_point_info) 2044f6ad66aSAchin Gupta { 205625de1d4SDan Handley uintptr_t dev_handle; 206625de1d4SDan Handley uintptr_t image_handle; 207625de1d4SDan Handley uintptr_t image_spec; 2088f55dfb4SSandrine Bailleux size_t image_size; 2098f55dfb4SSandrine Bailleux size_t bytes_read; 21078460a05SJuan Castillo int io_result; 2114f6ad66aSAchin Gupta 2129d72b4eaSJames Morrissey assert(mem_layout != NULL); 2138f55dfb4SSandrine Bailleux assert(image_data != NULL); 2144112bfa0SVikram Kanigiri assert(image_data->h.version >= VERSION_1); 2159d72b4eaSJames Morrissey 2169d72b4eaSJames Morrissey /* Obtain a reference to the image by querying the platform layer */ 21716948ae1SJuan Castillo io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); 21878460a05SJuan Castillo if (io_result != 0) { 21916948ae1SJuan Castillo WARN("Failed to obtain reference to image id=%u (%i)\n", 22016948ae1SJuan Castillo image_id, io_result); 2214112bfa0SVikram Kanigiri return io_result; 2224f6ad66aSAchin Gupta } 2234f6ad66aSAchin Gupta 2249d72b4eaSJames Morrissey /* Attempt to access the image */ 2259d72b4eaSJames Morrissey io_result = io_open(dev_handle, image_spec, &image_handle); 22678460a05SJuan Castillo if (io_result != 0) { 22716948ae1SJuan Castillo WARN("Failed to access image id=%u (%i)\n", 22816948ae1SJuan Castillo image_id, io_result); 2294112bfa0SVikram Kanigiri return io_result; 2304f6ad66aSAchin Gupta } 2314f6ad66aSAchin Gupta 23216948ae1SJuan Castillo INFO("Loading image id=%u at address 0x%lx\n", image_id, image_base); 2338f55dfb4SSandrine Bailleux 2349d72b4eaSJames Morrissey /* Find the size of the image */ 2359d72b4eaSJames Morrissey io_result = io_size(image_handle, &image_size); 23678460a05SJuan Castillo if ((io_result != 0) || (image_size == 0)) { 23716948ae1SJuan Castillo WARN("Failed to determine the size of the image id=%u (%i)\n", 23816948ae1SJuan Castillo image_id, io_result); 2394112bfa0SVikram Kanigiri goto exit; 2409d72b4eaSJames Morrissey } 2419d72b4eaSJames Morrissey 2428f55dfb4SSandrine Bailleux /* Check that the memory where the image will be loaded is free */ 2438f55dfb4SSandrine Bailleux if (!is_mem_free(mem_layout->free_base, mem_layout->free_size, 2448f55dfb4SSandrine Bailleux image_base, image_size)) { 2458f55dfb4SSandrine Bailleux WARN("Failed to reserve memory: 0x%lx - 0x%lx\n", 2468f55dfb4SSandrine Bailleux image_base, image_base + image_size); 2479d72b4eaSJames Morrissey dump_load_info(image_base, image_size, mem_layout); 2484112bfa0SVikram Kanigiri io_result = -ENOMEM; 2494112bfa0SVikram Kanigiri goto exit; 2504f6ad66aSAchin Gupta } 2514f6ad66aSAchin Gupta 2524f6ad66aSAchin Gupta /* We have enough space so load the image now */ 2539d72b4eaSJames Morrissey /* TODO: Consider whether to try to recover/retry a partially successful read */ 254625de1d4SDan Handley io_result = io_read(image_handle, image_base, image_size, &bytes_read); 25578460a05SJuan Castillo if ((io_result != 0) || (bytes_read < image_size)) { 25616948ae1SJuan Castillo WARN("Failed to load image id=%u (%i)\n", image_id, io_result); 2574112bfa0SVikram Kanigiri goto exit; 2584f6ad66aSAchin Gupta } 2594f6ad66aSAchin Gupta 2608f55dfb4SSandrine Bailleux /* 2618f55dfb4SSandrine Bailleux * Update the memory usage info. 2628f55dfb4SSandrine Bailleux * This is done after the actual loading so that it is not updated when 2638f55dfb4SSandrine Bailleux * the load is unsuccessful. 264c5fb47c3SJuan Castillo * If the caller does not provide an entry point, bypass the memory 265c5fb47c3SJuan Castillo * reservation. 2668f55dfb4SSandrine Bailleux */ 267c5fb47c3SJuan Castillo if (entry_point_info != NULL) { 2688f55dfb4SSandrine Bailleux reserve_mem(&mem_layout->free_base, &mem_layout->free_size, 2698f55dfb4SSandrine Bailleux image_base, image_size); 270c5fb47c3SJuan Castillo } else { 271c5fb47c3SJuan Castillo INFO("Skip reserving memory: 0x%lx - 0x%lx\n", 272c5fb47c3SJuan Castillo image_base, image_base + image_size); 273c5fb47c3SJuan Castillo } 2748f55dfb4SSandrine Bailleux 2754112bfa0SVikram Kanigiri image_data->image_base = image_base; 2764112bfa0SVikram Kanigiri image_data->image_size = image_size; 2774112bfa0SVikram Kanigiri 27863db7ba2SSandrine Bailleux if (entry_point_info != NULL) 2794112bfa0SVikram Kanigiri entry_point_info->pc = image_base; 2804112bfa0SVikram Kanigiri 2814f6ad66aSAchin Gupta /* 2828f55dfb4SSandrine Bailleux * File has been successfully loaded. 2838f55dfb4SSandrine Bailleux * Flush the image in TZRAM so that the next EL can see it. 2844f6ad66aSAchin Gupta */ 2859d72b4eaSJames Morrissey flush_dcache_range(image_base, image_size); 2864f6ad66aSAchin Gupta 28716948ae1SJuan Castillo INFO("Image id=%u loaded: 0x%lx - 0x%lx\n", image_id, image_base, 2888f55dfb4SSandrine Bailleux image_base + image_size); 2899d72b4eaSJames Morrissey 2909d72b4eaSJames Morrissey exit: 2914112bfa0SVikram Kanigiri io_close(image_handle); 2929d72b4eaSJames Morrissey /* Ignore improbable/unrecoverable error in 'close' */ 2939d72b4eaSJames Morrissey 2949d72b4eaSJames Morrissey /* TODO: Consider maintaining open device connection from this bootloader stage */ 2954112bfa0SVikram Kanigiri io_dev_close(dev_handle); 2969d72b4eaSJames Morrissey /* Ignore improbable/unrecoverable error in 'dev_close' */ 2974f6ad66aSAchin Gupta 2984112bfa0SVikram Kanigiri return io_result; 2994f6ad66aSAchin Gupta } 3001779ba6bSJuan Castillo 3011779ba6bSJuan Castillo /******************************************************************************* 3021779ba6bSJuan Castillo * Generic function to load and authenticate an image. The image is actually 3031779ba6bSJuan Castillo * loaded by calling the 'load_image()' function. In addition, this function 3041779ba6bSJuan Castillo * uses recursion to authenticate the parent images up to the root of trust. 3051779ba6bSJuan Castillo ******************************************************************************/ 3061779ba6bSJuan Castillo int load_auth_image(meminfo_t *mem_layout, 3071779ba6bSJuan Castillo unsigned int image_id, 3081779ba6bSJuan Castillo uintptr_t image_base, 3091779ba6bSJuan Castillo image_info_t *image_data, 3101779ba6bSJuan Castillo entry_point_info_t *entry_point_info) 3111779ba6bSJuan Castillo { 3121779ba6bSJuan Castillo int rc; 3131779ba6bSJuan Castillo 3141779ba6bSJuan Castillo #if TRUSTED_BOARD_BOOT 3151779ba6bSJuan Castillo unsigned int parent_id; 3161779ba6bSJuan Castillo 3171779ba6bSJuan Castillo /* Use recursion to authenticate parent images */ 3181779ba6bSJuan Castillo rc = auth_mod_get_parent_id(image_id, &parent_id); 3191779ba6bSJuan Castillo if (rc == 0) { 3201779ba6bSJuan Castillo rc = load_auth_image(mem_layout, parent_id, image_base, 3211779ba6bSJuan Castillo image_data, NULL); 32278460a05SJuan Castillo if (rc != 0) { 3231779ba6bSJuan Castillo return rc; 3241779ba6bSJuan Castillo } 3251779ba6bSJuan Castillo } 3261779ba6bSJuan Castillo #endif /* TRUSTED_BOARD_BOOT */ 3271779ba6bSJuan Castillo 3281779ba6bSJuan Castillo /* Load the image */ 3291779ba6bSJuan Castillo rc = load_image(mem_layout, image_id, image_base, image_data, 3301779ba6bSJuan Castillo entry_point_info); 33178460a05SJuan Castillo if (rc != 0) { 33278460a05SJuan Castillo return rc; 3331779ba6bSJuan Castillo } 3341779ba6bSJuan Castillo 3351779ba6bSJuan Castillo #if TRUSTED_BOARD_BOOT 3361779ba6bSJuan Castillo /* Authenticate it */ 3371779ba6bSJuan Castillo rc = auth_mod_verify_img(image_id, 3381779ba6bSJuan Castillo (void *)image_data->image_base, 3391779ba6bSJuan Castillo image_data->image_size); 3401779ba6bSJuan Castillo if (rc != 0) { 341fedbc049SJuan Castillo memset((void *)image_data->image_base, 0x00, 342fedbc049SJuan Castillo image_data->image_size); 343fedbc049SJuan Castillo flush_dcache_range(image_data->image_base, 344fedbc049SJuan Castillo image_data->image_size); 34578460a05SJuan Castillo return -EAUTH; 3461779ba6bSJuan Castillo } 3471779ba6bSJuan Castillo 3481779ba6bSJuan Castillo /* After working with data, invalidate the data cache */ 3491779ba6bSJuan Castillo inv_dcache_range(image_data->image_base, 3501779ba6bSJuan Castillo (size_t)image_data->image_size); 3511779ba6bSJuan Castillo #endif /* TRUSTED_BOARD_BOOT */ 3521779ba6bSJuan Castillo 35378460a05SJuan Castillo return 0; 3541779ba6bSJuan Castillo } 355