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