| 1 | /* @title: IOMMU */ |
| 2 | #pragma once |
| 3 | #include <stdbool.h> |
| 4 | #include <stddef.h> |
| 5 | #include <stdint.h> |
| 6 | #include <types/types.h> |
| 7 | |
| 8 | struct iommu_domain; |
| 9 | struct iommu; |
| 10 | struct device; |
| 11 | |
| 12 | enum iommu_perms { |
| 13 | IOMMU_READ = 1u << 0, |
| 14 | IOMMU_WRITE = 1u << 1, |
| 15 | IOMMU_NOEXEC = 1u << 2, |
| 16 | }; |
| 17 | |
| 18 | enum iommu_error { |
| 19 | IOMMU_ERR_OK, |
| 20 | IOMMU_ERR_NO_MEM, |
| 21 | IOMMU_ERR_UNSUPPORTED, |
| 22 | IOMMU_ERR_INVALID, |
| 23 | }; |
| 24 | |
| 25 | enum iommu_status { IOMMU_STATUS_INACTIVE, IOMMU_STATUS_ACTIVE }; |
| 26 | |
| 27 | struct 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 | |
| 53 | struct iommu { |
| 54 | const struct iommu_ops *ops; |
| 55 | void *private; |
| 56 | enum iommu_status status; |
| 57 | }; |
| 58 | |
| 59 | struct 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 | |
| 67 | void iommu_init(); |
| 68 | |
| 69 | enum iommu_error iommu_unit_init(struct iommu *unit); |
| 70 | void iommu_unit_destroy(struct iommu *unit); |
| 71 | |
| 72 | struct iommu_domain *iommu_domain_alloc(struct iommu *unit); |
| 73 | void iommu_domain_free(struct iommu_domain *domain); |
| 74 | |
| 75 | enum iommu_error iommu_attach_device(struct iommu_domain *domain, |
| 76 | struct device *dev); |
| 77 | void iommu_detach_device(struct iommu_domain *domain, struct device *dev); |
| 78 | |
| 79 | enum iommu_error iommu_map(struct iommu_domain *domain, iova_t iova, |
| 80 | uint64_t pa, size_t size, enum iommu_perms perm); |
| 81 | void iommu_unmap(struct iommu_domain *domain, iova_t iova, size_t size); |
| 82 | |