blob: 64c30b32b1cde0fcfc365b2493599b61930659dd [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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 */
21static 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 */
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 */
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}