The Pedigree Project 0.1
IntelIommu.h
1/* Copyright (c) 2026, Pedigree Developers. SPDX-License-Identifier: ISC */
2#ifndef PEDIGREE_PC_INTEL_IOMMU_H
3#define PEDIGREE_PC_INTEL_IOMMU_H
4
5#include "pedigree/kernel/process/Mutex.h"
6#include "pedigree/kernel/processor/MemoryMappedIo.h"
7#include "pedigree/kernel/processor/MemoryRegion.h"
8#include "pedigree/kernel/processor/types.h"
9
10class Device;
11
13 public:
14 static IntelIommu& instance();
15
16 bool attach(Device* device, bool isolated = false);
17 bool detachIsolated(Device* device, bool requesterDisabled = false);
18 bool isolatedIdle(Device* device) const;
19 bool attached(const Device* device) const;
20 bool isolated(const Device* device) const;
21 bool mapPage(Device* device, physical_uintptr_t physical, uint32_t& dmaAddress, uint16_t& token);
22 void unmapPage(Device* device, uint16_t token);
23
24 private:
25 static constexpr size_t MaxDomains = 8;
26 static_assert(MaxDomains + 2 <= 16, "VT-d ND=0 supports only 16 domain IDs");
27 static constexpr size_t TokenPages = 32;
28 static constexpr size_t IsolatedTokenPages = 1024;
29 static constexpr uint32_t IsolatedTokenBase = 0x10000000U;
30
31 struct Domain {
32 Device* device = nullptr;
33 uint16_t id = 0;
34 physical_uintptr_t root = 0;
35 physical_uintptr_t pages[8] = {};
36 size_t pageCount = 0;
37 uint64_t tokenBase = 0;
38 uint16_t tokenCount = 0;
39 uint64_t* tokenTables[2] = {};
40 uint32_t tokenUsed[IsolatedTokenPages / 32] = {};
41 bool isolated = false;
42 bool loggedHighMapping = false;
43 };
44
45 IntelIommu();
46 bool initialise();
47 bool allocateTable(physical_uintptr_t& page);
48 bool makeDomain(Domain& domain);
49 void freeDomain(Domain& domain);
50 bool invalidateContext();
51 bool invalidateIotlb();
52 bool command(uint32_t bit, bool set);
53 bool waitForStatus(uint32_t bit, bool set);
54 void flushLines(const void* address, size_t bytes) const;
55 void logFault();
56 static uint64_t* tokenEntry(const Domain& domain, size_t slot);
57 Domain* findDomain(const Device* device);
58 const Domain* findDomain(const Device* device) const;
59
60 mutable Mutex m_Lock;
61 MemoryMappedIo m_Registers;
62 MemoryRegion m_ReservedTokens;
63 physical_uintptr_t m_Root = 0;
64 physical_uintptr_t m_DefaultContext = 0;
65 physical_uintptr_t m_BusContexts[256] = {};
66 Domain m_Domains[MaxDomains];
67 size_t m_IotlbOffset = 0;
68 uint64_t m_MaxPhysical = 0;
69 uint8_t m_Aw = 0;
70 uint8_t m_PassThroughAw = 0;
71 size_t m_CacheLine = 64;
72 bool m_Coherent = false;
73 bool m_Enabled = false;
74 bool m_Failed = false;
75};
76
77#endif
Memory mapped I/O range.
Special memory entity in the kernel's virtual address space.
Definition Mutex.h:56