1 /*
2  * Copyright (c) 2013-2019, 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/uuid.h>
12 #include <common/debug.h>
13 #include <common/runtime_svc.h>
14 
15 #include <services/logical_sp.h>
16 
17 /*******************************************************************************
18  * The 'logical_partition' array holds the logical partition descriptors exported by
19  * SPs by placing them in the 'logical_partition' linker section.
20  ******************************************************************************/
21 
22 
23 
24 /*******************************************************************************
25  * Simple routine to sanity check a logical partition descriptor before using it
26  ******************************************************************************/
validate_logical_partition_struct(const el3_lp_desc_t * desc)27 static int32_t validate_logical_partition_struct(const el3_lp_desc_t *desc)
28 {
29 	if (desc == NULL)
30 		return -EINVAL;
31 
32 	/* Ensue we have setup and direct messaging callback registered */
33 	if ((desc->init == NULL) || (desc->direct_req == NULL))
34 		return -EINVAL;
35 
36 	return 0;
37 }
38 
39 /*******************************************************************************
40  * This function validates any logical partition descriptors.
41  * Initalistaion of said partitions will be taken care of during SPMC boot.
42  ******************************************************************************/
el3_sp_desc_init(void)43 void __init el3_sp_desc_init(void)
44 {
45 	int rc = 0;
46 	uint8_t index, inner_idx;
47 	el3_lp_desc_t *logical_partition;
48 
49 	/* Assert the number of descriptors detected are less than maximum indices */
50 	assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START);
51 
52 	assert(EL3_LP_DESCS_NUM <= MAX_EL3_LP_DESCS_COUNT);
53 
54 	/* If no logical partitions are implemented then simply bail out */
55 	if (EL3_LP_DESCS_NUM == 0U)
56 		return;
57 
58 	/* Initialise internal variables to invalid state */
59 	/* TODO: Do we want to reused indexing mechanism here or just loop as arrary is small? */
60 	// (void)memset(logical_partition_indices, -1, sizeof(logical_partition_indices));
61 
62 	logical_partition = (el3_lp_desc_t *) EL3_LP_DESCS_START;
63 	for (index = 0U; index < EL3_LP_DESCS_NUM; index++) {
64 		el3_lp_desc_t *lp_descriptor = &logical_partition[index];
65 
66 		/*
67 		 * Validate our logical partition descriptors.
68 		 */
69 		rc = validate_logical_partition_struct(lp_descriptor);
70 		if (rc != 0) {
71 			ERROR("Invalid logical partition descriptor %p\n",
72 				(void *) lp_descriptor);
73 			panic(); // TODO: Should we just continue to load without that partition?
74 		}
75 
76 		/* Check we have a UUID Specified. */
77 		if (lp_descriptor->uuid == NULL) {
78 			ERROR("Invalid UUID Specified\n");
79 		}
80 
81 		/* Ensure that all partition IDs are unique. */
82 		for (inner_idx = index  + 1; inner_idx < EL3_LP_DESCS_NUM; inner_idx++) {
83 			el3_lp_desc_t *lp_descriptor_other = &logical_partition[index];
84 			if (lp_descriptor->sp_id == lp_descriptor_other->sp_id) {
85 				ERROR("Duplicate Partition ID Detected 0x%x\n", lp_descriptor->sp_id);
86 				panic();
87 			}
88 		}
89 	}
90 }
91