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