diff options
author | Le Tan <tamlokveer@gmail.com> | 2014-08-16 13:55:38 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2014-08-28 23:10:22 +0200 |
commit | 1da12ec4c81330eb1ed1f29a78854bea87a23595 (patch) | |
tree | 25ff4496e3366f3892b6bb96d4b1d6a4abce5fe0 /include/hw/i386/intel_iommu.h | |
parent | 8d7b8cb9c22b7aa809050800a62e89f869054b35 (diff) |
intel-iommu: introduce Intel IOMMU (VT-d) emulation
Add support for emulating Intel IOMMU according to the VT-d specification for
the q35 chipset machine. Implement the logics for DMAR (DMA remapping) without
PASID support. The emulation supports register-based invalidation and primary
fault logging.
Signed-off-by: Le Tan <tamlokveer@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'include/hw/i386/intel_iommu.h')
-rw-r--r-- | include/hw/i386/intel_iommu.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h new file mode 100644 index 0000000000..fe1f1e987c --- /dev/null +++ b/include/hw/i386/intel_iommu.h @@ -0,0 +1,89 @@ +/* + * QEMU emulation of an Intel IOMMU (VT-d) + * (DMA Remapping device) + * + * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com> + * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INTEL_IOMMU_H +#define INTEL_IOMMU_H +#include "hw/qdev.h" +#include "sysemu/dma.h" + +#define TYPE_INTEL_IOMMU_DEVICE "intel-iommu" +#define INTEL_IOMMU_DEVICE(obj) \ + OBJECT_CHECK(IntelIOMMUState, (obj), TYPE_INTEL_IOMMU_DEVICE) + +/* DMAR Hardware Unit Definition address (IOMMU unit) */ +#define Q35_HOST_BRIDGE_IOMMU_ADDR 0xfed90000ULL + +#define VTD_PCI_BUS_MAX 256 +#define VTD_PCI_SLOT_MAX 32 +#define VTD_PCI_FUNC_MAX 8 +#define VTD_PCI_DEVFN_MAX 256 +#define VTD_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define VTD_PCI_FUNC(devfn) ((devfn) & 0x07) + +#define DMAR_REG_SIZE 0x230 +#define VTD_HOST_ADDRESS_WIDTH 39 +#define VTD_HAW_MASK ((1ULL << VTD_HOST_ADDRESS_WIDTH) - 1) + +typedef struct IntelIOMMUState IntelIOMMUState; +typedef struct VTDAddressSpace VTDAddressSpace; + +struct VTDAddressSpace { + uint8_t bus_num; + uint8_t devfn; + AddressSpace as; + MemoryRegion iommu; + IntelIOMMUState *iommu_state; +}; + +/* The iommu (DMAR) device state struct */ +struct IntelIOMMUState { + SysBusDevice busdev; + MemoryRegion csrmem; + uint8_t csr[DMAR_REG_SIZE]; /* register values */ + uint8_t wmask[DMAR_REG_SIZE]; /* R/W bytes */ + uint8_t w1cmask[DMAR_REG_SIZE]; /* RW1C(Write 1 to Clear) bytes */ + uint8_t womask[DMAR_REG_SIZE]; /* WO (write only - read returns 0) */ + uint32_t version; + + dma_addr_t root; /* Current root table pointer */ + bool root_extended; /* Type of root table (extended or not) */ + bool dmar_enabled; /* Set if DMA remapping is enabled */ + + uint16_t iq_head; /* Current invalidation queue head */ + uint16_t iq_tail; /* Current invalidation queue tail */ + dma_addr_t iq; /* Current invalidation queue pointer */ + uint16_t iq_size; /* IQ Size in number of entries */ + bool qi_enabled; /* Set if the QI is enabled */ + uint8_t iq_last_desc_type; /* The type of last completed descriptor */ + + /* The index of the Fault Recording Register to be used next. + * Wraps around from N-1 to 0, where N is the number of FRCD_REG. + */ + uint16_t next_frcd_reg; + + uint64_t cap; /* The value of capability reg */ + uint64_t ecap; /* The value of extended capability reg */ + + MemoryRegionIOMMUOps iommu_ops; + VTDAddressSpace **address_spaces[VTD_PCI_BUS_MAX]; +}; + +#endif |