xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/agx_va.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "agx_bo.h"
7 #include "agx_device.h"
8 
9 static struct util_vma_heap *
agx_vma_heap(struct agx_device * dev,enum agx_va_flags flags)10 agx_vma_heap(struct agx_device *dev, enum agx_va_flags flags)
11 {
12    return (flags & AGX_VA_USC) ? &dev->usc_heap : &dev->main_heap;
13 }
14 
15 struct agx_va *
agx_va_alloc(struct agx_device * dev,uint32_t size_B,uint32_t align_B,enum agx_va_flags flags,uint64_t fixed_va)16 agx_va_alloc(struct agx_device *dev, uint32_t size_B, uint32_t align_B,
17              enum agx_va_flags flags, uint64_t fixed_va)
18 {
19    assert((fixed_va != 0) == !!(flags & AGX_VA_FIXED));
20    assert((fixed_va % align_B) == 0);
21 
22    /* All allocations need a guard at the end to prevent overreads.
23     *
24     * TODO: Even with soft fault?
25     */
26    size_B += dev->guard_size;
27 
28    struct util_vma_heap *heap = agx_vma_heap(dev, flags);
29    uint64_t addr = 0;
30 
31    simple_mtx_lock(&dev->vma_lock);
32    if (flags & AGX_VA_FIXED) {
33       if (util_vma_heap_alloc_addr(heap, fixed_va, size_B))
34          addr = fixed_va;
35    } else {
36       addr = util_vma_heap_alloc(heap, size_B, align_B);
37    }
38    simple_mtx_unlock(&dev->vma_lock);
39 
40    if (addr == 0)
41       return NULL;
42 
43    struct agx_va *va = malloc(sizeof(struct agx_va));
44    *va = (struct agx_va){
45       .flags = flags,
46       .size_B = size_B,
47       .addr = addr,
48    };
49    return va;
50 }
51 
52 void
agx_va_free(struct agx_device * dev,struct agx_va * va)53 agx_va_free(struct agx_device *dev, struct agx_va *va)
54 {
55    if (!va)
56       return;
57 
58    struct util_vma_heap *heap = agx_vma_heap(dev, va->flags);
59 
60    simple_mtx_lock(&dev->vma_lock);
61    util_vma_heap_free(heap, va->addr, va->size_B);
62    simple_mtx_unlock(&dev->vma_lock);
63    free(va);
64 }
65