1/* @title: IOMMU */
2#pragma once
3#include <stdbool.h>
4#include <stddef.h>
5#include <stdint.h>
6#include <types/types.h>
7
8struct iommu_domain;
9struct iommu;
10struct device;
11
12enum iommu_perms {
13 IOMMU_READ = 1u << 0,
14 IOMMU_WRITE = 1u << 1,
15 IOMMU_NOEXEC = 1u << 2,
16};
17
18enum iommu_error {
19 IOMMU_ERR_OK,
20 IOMMU_ERR_NO_MEM,
21 IOMMU_ERR_UNSUPPORTED,
22 IOMMU_ERR_INVALID,
23};
24
25enum iommu_status { IOMMU_STATUS_INACTIVE, IOMMU_STATUS_ACTIVE };
26
27struct iommu_ops {
28 enum iommu_error (*unit_init)(struct iommu *unit);
29 void (*unit_destroy)(struct iommu *unit);
30
31 struct iommu_domain *(*domain_alloc)(struct iommu *unit);
32 void (*domain_free)(struct iommu_domain *domain);
33
34 enum iommu_error (*attach_device)(struct iommu_domain *domain, uint16_t seg,
35 uint8_t bus, uint8_t dev, uint8_t fn);
36 void (*detach_device)(struct iommu_domain *domain, uint16_t seg,
37 uint8_t bus, uint8_t dev, uint8_t fn);
38
39 enum iommu_error (*map)(struct iommu_domain *domain, iova_t iova,
40 paddr_t paddr, size_t size, enum iommu_perms perm);
41 void (*unmap)(struct iommu_domain *domain, iova_t iova, size_t size);
42
43 void (*flush_iotlb_domain)(struct iommu_domain *domain);
44 void (*flush_iotlb_range)(struct iommu_domain *domain, iova_t iova,
45 size_t size);
46
47 enum iommu_error (*enable)(struct iommu *unit);
48 void (*disable)(struct iommu *unit);
49
50 const char *name;
51};
52
53struct iommu {
54 const struct iommu_ops *ops;
55 void *private;
56 enum iommu_status status;
57};
58
59struct iommu_domain {
60 struct iommu *unit;
61 void *priv;
62 iova_t iova_base;
63 iova_t iova_limit;
64 struct vas *vas;
65};
66
67void iommu_init();
68
69enum iommu_error iommu_unit_init(struct iommu *unit);
70void iommu_unit_destroy(struct iommu *unit);
71
72struct iommu_domain *iommu_domain_alloc(struct iommu *unit);
73void iommu_domain_free(struct iommu_domain *domain);
74
75enum iommu_error iommu_attach_device(struct iommu_domain *domain,
76 struct device *dev);
77void iommu_detach_device(struct iommu_domain *domain, struct device *dev);
78
79enum iommu_error iommu_map(struct iommu_domain *domain, iova_t iova,
80 uint64_t pa, size_t size, enum iommu_perms perm);
81void iommu_unmap(struct iommu_domain *domain, iova_t iova, size_t size);
82