1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 // Allocate memory from a partition
6 //
7 // This allocates memory of least the requested size and minimum alignment
8 // specified and returns a pointer to the start of the allocation.
9 //
10 // Note that the memory allocated is uninitialized and it is the caller's
11 // responsibility to initialize or zero it.
12 void_ptr_result_t
13 partition_alloc(partition_t *partition, size_t bytes, size_t min_alignment);
14 
15 // Free memory back to a partition
16 //
17 // The memory must have been allocated from the partition that is it is freed
18 // back to.
19 error_t
20 partition_free(partition_t *partition, void *mem, size_t bytes);
21 
22 // Free memory by physical address back to a partition
23 //
24 // The memory must have been allocated from the partition that is it is freed
25 // back to.
26 error_t
27 partition_free_phys(partition_t *partition, paddr_t phys, size_t bytes);
28 
29 // Get the hypervisor's private partition.
30 //
31 // This is used for allocating objects that are owned by the hypervisor itself
32 // and used internally, such as the idle threads.
33 partition_t *
34 partition_get_private(void);
35 
36 // Get the physical address of an object owned by this partition.
37 //
38 // This is used by a limited set of internal hypervisor functions that need to
39 // allocate physical memory for their own use, e.g. for page table levels.
40 //
41 // The specified address must have been returned by a partition_alloc() call
42 // for the specified partition, and not subsequently freed; the result is not
43 // guaranteed to be meaningful otherwise. The caller must not assume that
44 // hypervisor memory is physically contiguous beyond the range allocated by that
45 // partition_alloc() call.
46 paddr_t
47 partition_virt_to_phys(partition_t *partition, uintptr_t virt);
48 
49 // Check whether the physical address range is valid, i.e. associated to any
50 // partition.
51 //
52 // The physical address must be normal memory owned by a partition, but it is
53 // not necessary to specify the partition.
54 bool
55 partition_phys_valid(paddr_t paddr, size_t size);
56 
57 // Obtain a virtual address that may be used to access a specified physical
58 // address.
59 //
60 // The physical address must be normal memory owned by a partition, but it is
61 // not necessary to specify the partition.
62 //
63 // The returned virtual address must only be accessed between calls to
64 // partition_phys_access_enable() and partition_phys_access_disable().
65 //
66 // This function must be paired with a call to partition_phys_unmap(). Pairs of
67 // calls to these functions may be nested; there may be a limit on the number of
68 // levels of nesting, but it shall be large enough to simultaneously access
69 // every level of the largest page table supported by the platform.
70 //
71 // Some implementations of this function may need to construct mappings at
72 // runtime (and unmap them afterwards), and therefore may be relatively slow.
73 // Where possible, multiple accesses to one memory region should be batched to
74 // minimise calls to this function.
75 void *
76 partition_phys_map(paddr_t paddr, size_t size);
77 
78 // Enable accesses to a physical address mapped with partition_phys_map().
79 //
80 // The pointer should point to the specific object that will be accessed.
81 //
82 // This function must be paired with a call to partition_phys_access_disable()
83 // with the same address argument. Pairs of calls to these functions must not be
84 // nested.
85 //
86 // This function should be fast enough to call before each individual access. If
87 // this is not possible, it must be a no-op, and all work necessary to enable
88 // access to the mapping must be performed by partition_phys_map().
89 void
90 partition_phys_access_enable(const void *ptr);
91 
92 // Disable accesses to a physical address mapped with partition_phys_map().
93 //
94 // The pointer should point to the specific object that was accessed.
95 //
96 // This function should be fast enough to call after each individual access. If
97 // this is not possible, it should be a no-op.
98 void
99 partition_phys_access_disable(const void *ptr);
100 
101 // Release a virtual address returned by partition_phys_unmap().
102 //
103 // The virtual address must not be accessed after calling this function.
104 void
105 partition_phys_unmap(const void *vaddr, paddr_t paddr, size_t size);
106 
107 // Donate memory from partition
108 //
109 // Update address range ownership in the memory database from src_partition to
110 // dst_partition.
111 //
112 // If from_heap is false, the specified range must be unused memory owned by the
113 // source partition.
114 //
115 // If from_heap is true, the specified range must have been returned by a call
116 // to partition_alloc() with the specified source partition. This is useful when
117 // allocating a new partition during bootstrap, from within the hypervisor.
118 error_t
119 partition_mem_donate(partition_t *src_partition, paddr_t base, size_t size,
120 		     partition_t *dst_partition, bool from_heap);
121 
122 // Add memory to the partition's allocators
123 //
124 // The memory must have been allocated from the partition that is it is freed
125 // back to.
126 error_t
127 partition_add_heap(partition_t *partition, paddr_t base, size_t size);
128 
129 // Map range and add memory to the partition's allocator
130 //
131 // The memory must have been allocated from the partition that is it is freed
132 // back to.
133 error_t
134 partition_map_and_add_heap(partition_t *partition, paddr_t base, size_t size);
135 
136 #if defined(PLATFORM_TRACE_STANDALONE_REGION)
137 // Map range and add memory to the partition's trace area
138 //
139 // The memory must have been allocated from the partition that is it is freed
140 // back to.
141 uintptr_result_t
142 partition_map_and_add_trace(partition_t *partition, paddr_t base, size_t size);
143 #endif
144