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