1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. 4 */ 5 6 #include <arch_features.h> 7 #include <assert.h> 8 #include <atomics.h> 9 #include <sizes.h> 10 #include <spinlock.h> 11 #include <vmid.h> 12 13 #define VMID8_COUNT (1U << 8) 14 #define VMID16_COUNT (1U << 16) 15 #define MAX_VMID_COUNT VMID16_COUNT 16 #define VMID_ARRAY_LONG_SIZE (MAX_VMID_COUNT / BITS_PER_UL) 17 18 /* 19 * The bitmap for the reserved/used VMID values. 20 */ 21 static unsigned long vmids[VMID_ARRAY_LONG_SIZE]; 22 23 /* 24 * Marks the VMID value to be in use. It returns: 25 * - True, on success 26 * - False, if the vmid is out of range, 27 * or if it was already reserved (in use). 28 */ vmid_reserve(unsigned int vmid)29bool vmid_reserve(unsigned int vmid) 30 { 31 unsigned int offset; 32 unsigned int vmid_count; 33 34 /* Number of supported VMID values */ 35 vmid_count = is_feat_vmid16_present() ? VMID16_COUNT : VMID8_COUNT; 36 /* 37 * The input from NS as part of RMI_REALM_CREATE is 'short int' type, 38 * so this check will not fail on systems with FEAT_VMID16 implemented. 39 */ 40 if (vmid >= vmid_count) { 41 return false; 42 } 43 44 offset = vmid / BITS_PER_UL; 45 46 return !atomic_bit_set_acquire_release_64(&vmids[offset], vmid); 47 } 48 49 /* 50 * Marks the VMID value to be not in use. 51 */ vmid_free(unsigned int vmid)52void vmid_free(unsigned int vmid) 53 { 54 unsigned int offset; 55 unsigned int __unused vmid_count; 56 57 /* Number of supported VMID values */ 58 vmid_count = is_feat_vmid16_present() ? VMID16_COUNT : VMID8_COUNT; 59 60 /* Check the number of supported VMID values */ 61 assert(vmid < vmid_count); 62 offset = vmid / BITS_PER_UL; 63 64 atomic_bit_clear_release_64(&vmids[offset], vmid); 65 } 66