1*1da12ec4SLe Tan /* 2*1da12ec4SLe Tan * QEMU emulation of an Intel IOMMU (VT-d) 3*1da12ec4SLe Tan * (DMA Remapping device) 4*1da12ec4SLe Tan * 5*1da12ec4SLe Tan * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com> 6*1da12ec4SLe Tan * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com> 7*1da12ec4SLe Tan * 8*1da12ec4SLe Tan * This program is free software; you can redistribute it and/or modify 9*1da12ec4SLe Tan * it under the terms of the GNU General Public License as published by 10*1da12ec4SLe Tan * the Free Software Foundation; either version 2 of the License, or 11*1da12ec4SLe Tan * (at your option) any later version. 12*1da12ec4SLe Tan 13*1da12ec4SLe Tan * This program is distributed in the hope that it will be useful, 14*1da12ec4SLe Tan * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*1da12ec4SLe Tan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*1da12ec4SLe Tan * GNU General Public License for more details. 17*1da12ec4SLe Tan 18*1da12ec4SLe Tan * You should have received a copy of the GNU General Public License along 19*1da12ec4SLe Tan * with this program; if not, see <http://www.gnu.org/licenses/>. 20*1da12ec4SLe Tan */ 21*1da12ec4SLe Tan 22*1da12ec4SLe Tan #ifndef INTEL_IOMMU_H 23*1da12ec4SLe Tan #define INTEL_IOMMU_H 24*1da12ec4SLe Tan #include "hw/qdev.h" 25*1da12ec4SLe Tan #include "sysemu/dma.h" 26*1da12ec4SLe Tan 27*1da12ec4SLe Tan #define TYPE_INTEL_IOMMU_DEVICE "intel-iommu" 28*1da12ec4SLe Tan #define INTEL_IOMMU_DEVICE(obj) \ 29*1da12ec4SLe Tan OBJECT_CHECK(IntelIOMMUState, (obj), TYPE_INTEL_IOMMU_DEVICE) 30*1da12ec4SLe Tan 31*1da12ec4SLe Tan /* DMAR Hardware Unit Definition address (IOMMU unit) */ 32*1da12ec4SLe Tan #define Q35_HOST_BRIDGE_IOMMU_ADDR 0xfed90000ULL 33*1da12ec4SLe Tan 34*1da12ec4SLe Tan #define VTD_PCI_BUS_MAX 256 35*1da12ec4SLe Tan #define VTD_PCI_SLOT_MAX 32 36*1da12ec4SLe Tan #define VTD_PCI_FUNC_MAX 8 37*1da12ec4SLe Tan #define VTD_PCI_DEVFN_MAX 256 38*1da12ec4SLe Tan #define VTD_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) 39*1da12ec4SLe Tan #define VTD_PCI_FUNC(devfn) ((devfn) & 0x07) 40*1da12ec4SLe Tan 41*1da12ec4SLe Tan #define DMAR_REG_SIZE 0x230 42*1da12ec4SLe Tan #define VTD_HOST_ADDRESS_WIDTH 39 43*1da12ec4SLe Tan #define VTD_HAW_MASK ((1ULL << VTD_HOST_ADDRESS_WIDTH) - 1) 44*1da12ec4SLe Tan 45*1da12ec4SLe Tan typedef struct IntelIOMMUState IntelIOMMUState; 46*1da12ec4SLe Tan typedef struct VTDAddressSpace VTDAddressSpace; 47*1da12ec4SLe Tan 48*1da12ec4SLe Tan struct VTDAddressSpace { 49*1da12ec4SLe Tan uint8_t bus_num; 50*1da12ec4SLe Tan uint8_t devfn; 51*1da12ec4SLe Tan AddressSpace as; 52*1da12ec4SLe Tan MemoryRegion iommu; 53*1da12ec4SLe Tan IntelIOMMUState *iommu_state; 54*1da12ec4SLe Tan }; 55*1da12ec4SLe Tan 56*1da12ec4SLe Tan /* The iommu (DMAR) device state struct */ 57*1da12ec4SLe Tan struct IntelIOMMUState { 58*1da12ec4SLe Tan SysBusDevice busdev; 59*1da12ec4SLe Tan MemoryRegion csrmem; 60*1da12ec4SLe Tan uint8_t csr[DMAR_REG_SIZE]; /* register values */ 61*1da12ec4SLe Tan uint8_t wmask[DMAR_REG_SIZE]; /* R/W bytes */ 62*1da12ec4SLe Tan uint8_t w1cmask[DMAR_REG_SIZE]; /* RW1C(Write 1 to Clear) bytes */ 63*1da12ec4SLe Tan uint8_t womask[DMAR_REG_SIZE]; /* WO (write only - read returns 0) */ 64*1da12ec4SLe Tan uint32_t version; 65*1da12ec4SLe Tan 66*1da12ec4SLe Tan dma_addr_t root; /* Current root table pointer */ 67*1da12ec4SLe Tan bool root_extended; /* Type of root table (extended or not) */ 68*1da12ec4SLe Tan bool dmar_enabled; /* Set if DMA remapping is enabled */ 69*1da12ec4SLe Tan 70*1da12ec4SLe Tan uint16_t iq_head; /* Current invalidation queue head */ 71*1da12ec4SLe Tan uint16_t iq_tail; /* Current invalidation queue tail */ 72*1da12ec4SLe Tan dma_addr_t iq; /* Current invalidation queue pointer */ 73*1da12ec4SLe Tan uint16_t iq_size; /* IQ Size in number of entries */ 74*1da12ec4SLe Tan bool qi_enabled; /* Set if the QI is enabled */ 75*1da12ec4SLe Tan uint8_t iq_last_desc_type; /* The type of last completed descriptor */ 76*1da12ec4SLe Tan 77*1da12ec4SLe Tan /* The index of the Fault Recording Register to be used next. 78*1da12ec4SLe Tan * Wraps around from N-1 to 0, where N is the number of FRCD_REG. 79*1da12ec4SLe Tan */ 80*1da12ec4SLe Tan uint16_t next_frcd_reg; 81*1da12ec4SLe Tan 82*1da12ec4SLe Tan uint64_t cap; /* The value of capability reg */ 83*1da12ec4SLe Tan uint64_t ecap; /* The value of extended capability reg */ 84*1da12ec4SLe Tan 85*1da12ec4SLe Tan MemoryRegionIOMMUOps iommu_ops; 86*1da12ec4SLe Tan VTDAddressSpace **address_spaces[VTD_PCI_BUS_MAX]; 87*1da12ec4SLe Tan }; 88*1da12ec4SLe Tan 89*1da12ec4SLe Tan #endif 90