📄 iommu.h
字号:
do {(c).lo &= 0xfff; (c).lo |= (val) & PAGE_MASK_4K ;} while(0)#define context_set_address_width(c, val) \ do {(c).hi &= 0xfffffff8; (c).hi |= (val) & 7;} while(0)#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while(0)/* page table handling */#define LEVEL_STRIDE (9)#define LEVEL_MASK ((1 << LEVEL_STRIDE) - 1)#define PTE_NUM (1 << LEVEL_STRIDE)#define level_to_agaw(val) ((val) - 2)#define agaw_to_level(val) ((val) + 2)#define agaw_to_width(val) (30 + val * LEVEL_STRIDE)#define width_to_agaw(w) ((w - 30)/LEVEL_STRIDE)#define level_to_offset_bits(l) (12 + (l - 1) * LEVEL_STRIDE)#define address_level_offset(addr, level) \ ((addr >> level_to_offset_bits(level)) & LEVEL_MASK)#define level_mask(l) (((u64)(-1)) << level_to_offset_bits(l))#define level_size(l) (1 << level_to_offset_bits(l))#define align_to_level(addr, l) ((addr + level_size(l) - 1) & level_mask(l))/* * 0: readable * 1: writable * 2-6: reserved * 7: super page * 8-11: available * 12-63: Host physcial address */struct dma_pte { u64 val;};#define dma_clear_pte(p) do {(p).val = 0;} while(0)#define dma_set_pte_readable(p) do {(p).val |= 1;} while(0)#define dma_set_pte_writable(p) do {(p).val |= 2;} while(0)#define dma_set_pte_superpage(p) do {(p).val |= 8;} while(0)#define dma_set_pte_prot(p, prot) do { (p).val = (((p).val >> 2) << 2) | ((prot) & 3);} while (0)#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)#define dma_set_pte_addr(p, addr) do {(p).val |= ((addr) >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;} while(0)#define DMA_PTE_READ (1)#define DMA_PTE_WRITE (2)#define dma_pte_present(p) (((p).val & 3) != 0)/* interrupt remap entry */struct iremap_entry { union { u64 lo_val; struct { u64 p : 1, fpd : 1, dm : 1, rh : 1, tm : 1, dlm : 3, avail : 4, res_1 : 4, vector : 8, res_2 : 8, dst : 32; }lo; }; union { u64 hi_val; struct { u64 sid : 16, sq : 2, svt : 2, res_1 : 44; }hi; };};#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry))#define iremap_present(v) ((v).lo & 1)#define iremap_fault_disable(v) (((v).lo >> 1) & 1)#define iremap_set_present(v) do {(v).lo |= 1;} while(0)#define iremap_clear_present(v) do {(v).lo &= ~1;} while(0)/* queue invalidation entry */struct qinval_entry { union { struct { struct { u64 type : 4, granu : 2, res_1 : 10, did : 16, sid : 16, fm : 2, res_2 : 14; }lo; struct { u64 res; }hi; }cc_inv_dsc; struct { struct { u64 type : 4, granu : 2, dw : 1, dr : 1, res_1 : 8, did : 16, res_2 : 32; }lo; struct { u64 am : 6, ih : 1, res_1 : 5, addr : 52; }hi; }iotlb_inv_dsc; struct { struct { u64 type : 4, res_1 : 12, max_invs_pend: 5, res_2 : 11, sid : 16, res_3 : 16; }lo; struct { u64 size : 1, res_1 : 11, addr : 52; }hi; }dev_iotlb_inv_dsc; struct { struct { u64 type : 4, granu : 1, res_1 : 22, im : 5, iidx : 16, res_2 : 16; }lo; struct { u64 res; }hi; }iec_inv_dsc; struct { struct { u64 type : 4, iflag : 1, sw : 1, fn : 1, res_1 : 25, sdata : 32; }lo; struct { u64 res_1 : 2, saddr : 62; }hi; }inv_wait_dsc; }q;};struct poll_info { u64 saddr; u32 udata;};#define QINVAL_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct qinval_entry))#define qinval_present(v) ((v).lo & 1)#define qinval_fault_disable(v) (((v).lo >> 1) & 1)#define qinval_set_present(v) do {(v).lo |= 1;} while(0)#define qinval_clear_present(v) do {(v).lo &= ~1;} while(0)#define RESERVED_VAL 0#define TYPE_INVAL_CONTEXT 0x1#define TYPE_INVAL_IOTLB 0x2#define TYPE_INVAL_DEVICE_IOTLB 0x3#define TYPE_INVAL_IEC 0x4#define TYPE_INVAL_WAIT 0x5#define NOTIFY_TYPE_POLL 1#define NOTIFY_TYPE_INTR 1#define INTERRUTP_FLAG 1#define STATUS_WRITE 1#define FENCE_FLAG 1#define IEC_GLOBAL_INVL 0#define IEC_INDEX_INVL 1#define IRTA_REG_EIME_SHIFT 11#define IRTA_REG_TABLE_SIZE 7 // 4k page = 256 * 16 byte entries // 2^^(IRTA_REG_TABLE_SIZE + 1) = 256 // IRTA_REG_TABLE_SIZE = 7#define VTD_PAGE_TABLE_LEVEL_3 3#define VTD_PAGE_TABLE_LEVEL_4 4#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48#define MAX_IOMMU_REGS 0xc0extern struct list_head acpi_drhd_units;extern struct list_head acpi_rmrr_units;extern struct list_head acpi_ioapic_units;struct qi_ctrl { u64 qinval_maddr; /* queue invalidation page machine address */ int qinval_index; /* queue invalidation index */ spinlock_t qinval_lock; /* lock for queue invalidation page */ spinlock_t qinval_poll_lock; /* lock for queue invalidation poll addr */ volatile u32 qinval_poll_status; /* used by poll methord to sync */};struct ir_ctrl { u64 iremap_maddr; /* interrupt remap table machine address */ int iremap_index; /* interrupt remap index */ spinlock_t iremap_lock; /* lock for irq remappping table */};struct iommu_flush { int (*context)(void *iommu, u16 did, u16 source_id, u8 function_mask, u64 type, int non_present_entry_flush); int (*iotlb)(void *iommu, u16 did, u64 addr, unsigned int size_order, u64 type, int non_present_entry_flush);};struct intel_iommu { struct qi_ctrl qi_ctrl; struct ir_ctrl ir_ctrl; struct iommu_flush flush;};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -