1*54fd6939SJiyong Park /* 2*54fd6939SJiyong Park * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park #include <platform_def.h> 8*54fd6939SJiyong Park 9*54fd6939SJiyong Park #include <arch.h> 10*54fd6939SJiyong Park #include <plat/arm/common/plat_arm.h> 11*54fd6939SJiyong Park 12*54fd6939SJiyong Park /******************************************************************************* 13*54fd6939SJiyong Park * This function validates an MPIDR by checking whether it falls within the 14*54fd6939SJiyong Park * acceptable bounds. An error code (-1) is returned if an incorrect mpidr 15*54fd6939SJiyong Park * is passed. 16*54fd6939SJiyong Park ******************************************************************************/ arm_check_mpidr(u_register_t mpidr)17*54fd6939SJiyong Parkint arm_check_mpidr(u_register_t mpidr) 18*54fd6939SJiyong Park { 19*54fd6939SJiyong Park unsigned int cluster_id, cpu_id; 20*54fd6939SJiyong Park uint64_t valid_mask; 21*54fd6939SJiyong Park 22*54fd6939SJiyong Park #if ARM_PLAT_MT 23*54fd6939SJiyong Park unsigned int pe_id; 24*54fd6939SJiyong Park 25*54fd6939SJiyong Park valid_mask = ~(MPIDR_AFFLVL_MASK | 26*54fd6939SJiyong Park (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | 27*54fd6939SJiyong Park (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) | 28*54fd6939SJiyong Park (MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)); 29*54fd6939SJiyong Park cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; 30*54fd6939SJiyong Park cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; 31*54fd6939SJiyong Park pe_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; 32*54fd6939SJiyong Park #else 33*54fd6939SJiyong Park valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK); 34*54fd6939SJiyong Park cluster_id = (unsigned int) ((mpidr >> MPIDR_AFF1_SHIFT) & 35*54fd6939SJiyong Park MPIDR_AFFLVL_MASK); 36*54fd6939SJiyong Park cpu_id = (unsigned int) ((mpidr >> MPIDR_AFF0_SHIFT) & 37*54fd6939SJiyong Park MPIDR_AFFLVL_MASK); 38*54fd6939SJiyong Park #endif /* ARM_PLAT_MT */ 39*54fd6939SJiyong Park 40*54fd6939SJiyong Park mpidr &= MPIDR_AFFINITY_MASK; 41*54fd6939SJiyong Park if ((mpidr & valid_mask) != 0U) 42*54fd6939SJiyong Park return -1; 43*54fd6939SJiyong Park 44*54fd6939SJiyong Park if (cluster_id >= PLAT_ARM_CLUSTER_COUNT) 45*54fd6939SJiyong Park return -1; 46*54fd6939SJiyong Park 47*54fd6939SJiyong Park /* Validate cpu_id by checking whether it represents a CPU in 48*54fd6939SJiyong Park one of the two clusters present on the platform. */ 49*54fd6939SJiyong Park if (cpu_id >= plat_arm_get_cluster_core_count(mpidr)) 50*54fd6939SJiyong Park return -1; 51*54fd6939SJiyong Park 52*54fd6939SJiyong Park #if ARM_PLAT_MT 53*54fd6939SJiyong Park if (pe_id >= plat_arm_get_cpu_pe_count(mpidr)) 54*54fd6939SJiyong Park return -1; 55*54fd6939SJiyong Park #endif /* ARM_PLAT_MT */ 56*54fd6939SJiyong Park 57*54fd6939SJiyong Park return 0; 58*54fd6939SJiyong Park } 59