blob: e080832af084659b515bb038b8a57e67a64f106f [file] [log] [blame]
Marc Bonnici9a297042022-02-14 17:06:09 +00001/*
2 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <string.h>
10
11#include <common/debug.h>
12#include <services/el3_spmc_logical_sp.h>
13#include <services/ffa_svc.h>
14#include "spmc.h"
15
16/*******************************************************************************
17 * Validate any logical partition descriptors before we initialise.
18 * Initialization of said partitions will be taken care of during SPMC boot.
19 ******************************************************************************/
20int el3_sp_desc_validate(void)
21{
22 struct el3_lp_desc *lp_array;
23
24 /*
25 * Assert the number of descriptors is less than maximum allowed.
26 * This constant should be define on a per platform basis.
27 */
28 assert(EL3_LP_DESCS_COUNT <= MAX_EL3_LP_DESCS_COUNT);
29
30 /* Check the array bounds are valid. */
31 assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START);
32
33 /* If no logical partitions are implemented then simply bail out. */
34 if (EL3_LP_DESCS_COUNT == 0U) {
35 return 0;
36 }
37
38 lp_array = get_el3_lp_array();
39
40 for (unsigned int index = 0; index < EL3_LP_DESCS_COUNT; index++) {
41 struct el3_lp_desc *lp_desc = &lp_array[index];
42
43 /* Validate our logical partition descriptors. */
44 if (lp_desc == NULL) {
45 ERROR("Invalid Logical SP Descriptor\n");
46 return -EINVAL;
47 }
48
49 /*
50 * Ensure the ID follows the convention to indidate it resides
51 * in the secure world.
52 */
53 if (!ffa_is_secure_world_id(lp_desc->sp_id)) {
54 ERROR("Invalid Logical SP ID (0x%x)\n",
55 lp_desc->sp_id);
56 return -EINVAL;
57 }
58
59 /* Ensure we don't conflict with the SPMC partition ID. */
60 if (lp_desc->sp_id == FFA_SPMC_ID) {
61 ERROR("Logical SP ID clashes with SPMC ID(0x%x)\n",
62 lp_desc->sp_id);
63 return -EINVAL;
64 }
65
66 /* Ensure the UUID is not the NULL UUID. */
67 if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 &&
68 lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) {
69 ERROR("Invalid UUID for Logical SP (0x%x)\n",
70 lp_desc->sp_id);
71 return -EINVAL;
72 }
73
74 /* Ensure init function callback is registered. */
75 if (lp_desc->init == NULL) {
76 ERROR("Missing init function for Logical SP(0x%x)\n",
77 lp_desc->sp_id);
78 return -EINVAL;
79 }
80
81 /* Ensure that LP only supports receiving direct requests. */
82 if (lp_desc->properties &
83 ~(FFA_PARTITION_DIRECT_REQ_RECV)) {
84 ERROR("Invalid partition properties (0x%x)\n",
85 lp_desc->properties);
86 return -EINVAL;
87 }
88
89 /* Ensure direct request function callback is registered. */
90 if (lp_desc->direct_req == NULL) {
91 ERROR("No Direct Req handler for Logical SP (0x%x)\n",
92 lp_desc->sp_id);
93 return -EINVAL;
94 }
95
96 /* Ensure that all partition IDs are unique. */
97 for (unsigned int inner_idx = index + 1;
98 inner_idx < EL3_LP_DESCS_COUNT; inner_idx++) {
99 if (lp_desc->sp_id == lp_array[inner_idx].sp_id) {
100 ERROR("Duplicate SP ID Detected (0x%x)\n",
101 lp_desc->sp_id);
102 return -EINVAL;
103 }
104 }
105 }
106 return 0;
107}