1 /*
2  * Copyright 2019 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include "hf/addr.h"
12 #include "hf/fdt.h"
13 #include "hf/manifest.h"
14 #include "hf/vm.h"
15 
16 /**
17  * Initializes the platform IOMMU driver. The root node of the FDT is provided
18  * so that the driver can read from it. This can be used to map IOMMU devices
19  * into the hypervisor's address space so they are accessible by the driver.
20  */
21 bool plat_iommu_init(const struct fdt *fdt,
22 		     struct mm_stage1_locked stage1_locked,
23 		     struct mpool *ppool);
24 
25 /**
26  * Unmaps the address space used by the platform IOMMU driver from the VM so
27  * that VM cannot program these devices.
28  *
29  * Note that any calls to unmap an address range will result in
30  * `plat_iommu_identity_map` being invoked to apply the change to the IOMMU
31  * mapping as well. The module must ensure it can handle this reentrancy.
32  */
33 bool plat_iommu_unmap_iommus(struct vm_locked vm_locked, struct mpool *ppool);
34 
35 /**
36  * Maps the address range with the given mode for the given VM in the IOMMU.
37  *
38  * Assumes the identity map cannot fail. This may not always be true and if it
39  * isn't it will require careful thought on how to safely handle error cases
40  * when intermingled with MMU updates but it gives a starting point for drivers
41  * until those problems are understood.
42  *
43  * The modes are the same as the memory management modes but it is only required
44  * that read and write modes are enforced by the IOMMU driver.
45  */
46 void plat_iommu_identity_map(struct vm_locked vm_locked, paddr_t begin,
47 			     paddr_t end, uint32_t mode);
48 
49 /**
50  * Configure IOMMU to perform address translation of memory transactions on the
51  * bus generated by each upstream peripheral device associated with a VM.
52 
53  * mm_stage1_locked and mpool structure are provided so that the driver can
54  * allocate memory dynamically if needed (such as for configuring IOMMU using
55  * in-memory data structures.
56 
57  * vm_locked is needed for retrieving information related to the translation
58  * settings of the VM associated with a peripheral.
59 
60  * manifest_vm serves as a descriptor of various upstream peripherals that are
61  * associated with a VM.
62 
63  * Note: Not all these arguments may be needed for a certain implementation.
64  * This interface is designed to be agnostic of any particular implementation
65  * of IOMMU driver.
66  */
67 bool plat_iommu_attach_peripheral(struct mm_stage1_locked stage1_locked,
68 				  struct vm_locked vm_locked,
69 				  const struct manifest_vm *manifest_vm,
70 				  struct mpool *ppool);
71