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)27static 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)43void __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