| /* |
| * Copyright (c) 2018-2019, Arm Limited. All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include <assert.h> |
| |
| #include <platform_def.h> |
| |
| #include <common/debug.h> |
| #include <plat/common/platform.h> |
| #include <tools_share/sptool.h> |
| |
| static unsigned int sp_next; |
| |
| /******************************************************************************* |
| * Platform handler get the address of a Secure Partition and its resource |
| * description blob. It iterates through all SPs detected by the platform. If |
| * there is information for another SP, it returns 0. If there are no more SPs, |
| * it returns -1. |
| ******************************************************************************/ |
| int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, |
| void **rd_base, size_t *rd_size) |
| { |
| assert((sp_base != NULL) && (sp_size != NULL)); |
| assert((rd_base != NULL) && (rd_base != NULL)); |
| |
| const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE; |
| |
| struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base; |
| |
| if (sp_next == 0) { |
| if (pkg_header->version != 0x1) { |
| ERROR("SP package has an unsupported version 0x%llx\n", |
| pkg_header->version); |
| panic(); |
| } |
| } |
| |
| if (sp_next >= pkg_header->number_of_sp) { |
| /* No more partitions in the package */ |
| return -1; |
| } |
| |
| const struct sp_pkg_entry *entry_list = |
| (const struct sp_pkg_entry *)((uintptr_t)pkg_base |
| + sizeof(struct sp_pkg_header)); |
| |
| const struct sp_pkg_entry *entry = &(entry_list[sp_next]); |
| |
| uint64_t sp_offset = entry->sp_offset; |
| uint64_t rd_offset = entry->rd_offset; |
| |
| uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset); |
| uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset); |
| |
| uint64_t pkg_sp_size = entry->sp_size; |
| uint64_t pkg_rd_size = entry->rd_size; |
| |
| uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE |
| + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U; |
| |
| /* |
| * Check for overflows. The package header isn't trusted, so assert() |
| * can't be used here. |
| */ |
| |
| uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U; |
| uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U; |
| |
| if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) { |
| ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size); |
| panic(); |
| } |
| |
| if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) { |
| ERROR("Invalid Resource Description blob size (0x%llx)\n", |
| pkg_rd_size); |
| panic(); |
| } |
| |
| /* Return location of the binaries. */ |
| |
| *sp_base = (void *)pkg_sp_base; |
| *sp_size = pkg_sp_size; |
| *rd_base = (void *)pkg_rd_base; |
| *rd_size = pkg_rd_size; |
| |
| sp_next++; |
| |
| return 0; |
| } |