blob: bc3d6a01516c960d13936bec83f046dccd82d076 [file] [log] [blame]
Antonio Nino Diaz840627f2018-11-27 08:36:02 +00001/*
Ambroise Vincentb237bca2019-02-13 15:58:00 +00002 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
Antonio Nino Diaz840627f2018-11-27 08:36:02 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
Antonio Nino Diaz840627f2018-11-27 08:36:02 +00009#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <common/debug.h>
Ambroise Vincentb237bca2019-02-13 15:58:00 +000012#include <plat/common/platform.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <tools_share/sptool.h>
Antonio Nino Diaz840627f2018-11-27 08:36:02 +000014
15static unsigned int sp_next;
16
17/*******************************************************************************
18 * Platform handler get the address of a Secure Partition and its resource
19 * description blob. It iterates through all SPs detected by the platform. If
20 * there is information for another SP, it returns 0. If there are no more SPs,
21 * it returns -1.
22 ******************************************************************************/
23int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
24 void **rd_base, size_t *rd_size)
25{
26 assert((sp_base != NULL) && (sp_size != NULL));
27 assert((rd_base != NULL) && (rd_base != NULL));
28
29 const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE;
30
31 struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base;
32
33 if (sp_next == 0) {
34 if (pkg_header->version != 0x1) {
35 ERROR("SP package has an unsupported version 0x%llx\n",
36 pkg_header->version);
37 panic();
38 }
39 }
40
41 if (sp_next >= pkg_header->number_of_sp) {
42 /* No more partitions in the package */
43 return -1;
44 }
45
46 const struct sp_pkg_entry *entry_list =
47 (const struct sp_pkg_entry *)((uintptr_t)pkg_base
48 + sizeof(struct sp_pkg_header));
49
50 const struct sp_pkg_entry *entry = &(entry_list[sp_next]);
51
52 uint64_t sp_offset = entry->sp_offset;
53 uint64_t rd_offset = entry->rd_offset;
54
55 uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset);
56 uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset);
57
58 uint64_t pkg_sp_size = entry->sp_size;
59 uint64_t pkg_rd_size = entry->rd_size;
60
61 uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE
62 + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U;
63
64 /*
65 * Check for overflows. The package header isn't trusted, so assert()
66 * can't be used here.
67 */
68
69 uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U;
70 uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U;
71
72 if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) {
73 ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size);
74 panic();
75 }
76
77 if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) {
78 ERROR("Invalid Resource Description blob size (0x%llx)\n",
79 pkg_rd_size);
80 panic();
81 }
82
83 /* Return location of the binaries. */
84
85 *sp_base = (void *)pkg_sp_base;
86 *sp_size = pkg_sp_size;
87 *rd_base = (void *)pkg_rd_base;
88 *rd_size = pkg_rd_size;
89
90 sp_next++;
91
92 return 0;
93}