immu.h revision 9e986f0e5fb5e5ac09af90cd3b63f7836d983f9d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* All rights reserved.
*/
/*
* Copyright (c) 2008, Intel Corporation.
* All rights reserved.
*/
#ifndef _SYS_INTEL_IOMMU_H
#define _SYS_INTEL_IOMMU_H
/*
* Intel IOMMU implementation specific state
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Some ON drivers have bugs. Keep this define until all such drivers
* have been fixed
*/
#define BUGGY_DRIVERS 1
/* PD(T)E entries */
#define IMMU_MAXNAMELEN (64)
#define IMMU_MAXSEG (1)
#define IMMU_PAGESIZE (4096)
#define IMMU_PAGESHIFT (12)
#define IMMU_PAGEMASK (~IMMU_PAGEOFFSET)
#define IMMU_PGTABLE_MAX_LEVELS (6)
#define IMMU_PGTABLE_LEVEL_STRIDE (9)
/*
* DMAR global defines
*/
#define DMAR_TABLE "dmar-table"
#define DMAR_INTRMAP_SUPPORT (0x01)
/* DMAR unit types */
#define DMAR_DRHD 0
#define DMAR_RMRR 1
#define DMAR_ATSR 2
#define DMAR_RHSA 3
/* DRHD flag values */
#define DMAR_INCLUDE_ALL (0x01)
/* Device scope types */
#define DMAR_ENDPOINT 1
#define DMAR_SUBTREE 2
#define DMAR_IOAPIC 3
#define DMAR_HPET 4
/* Forward declarations for IOMMU state structure and DVMA domain struct */
struct immu;
struct domain;
/*
* The following structure describes the formate of DMAR ACPI table format.
* They are used to parse DMAR ACPI table. Read the spec for the meaning
* of each member.
*/
/* lengths of various strings */
typedef struct dmar_table {
char *tbl_oem_id;
char *tbl_oem_tblid;
int tbl_rawlen;
} dmar_table_t;
typedef struct drhd {
} drhd_t;
typedef struct rmrr {
} rmrr_t;
/*
* Macros based on PCI spec
*/
typedef struct scope {
} scope_t;
/*
* interrupt source id and drhd info for ioapic
*/
typedef struct ioapic_drhd {
typedef struct memrng {
} memrng_t;
typedef enum immu_flags {
IMMU_FLAGS_NONE = 0x1,
IMMU_FLAGS_SLEEP = 0x1,
IMMU_FLAGS_NOSLEEP = 0x2,
IMMU_FLAGS_READ = 0x4,
IMMU_FLAGS_WRITE = 0x8,
IMMU_FLAGS_DONTPASS = 0x10,
IMMU_FLAGS_ALLOC = 0x20,
IMMU_FLAGS_MUST_MATCH = 0x40,
IMMU_FLAGS_PAGE1 = 0x80,
IMMU_FLAGS_UNITY = 0x100,
IMMU_FLAGS_DMAHDL = 0x200,
IMMU_FLAGS_MEMRNG = 0x400
} immu_flags_t;
typedef enum cont_avail {
IMMU_CONT_BAD = 0x0,
IMMU_CONT_UNINITED = 0x1,
IMMU_CONT_INITED = 0x2
} cont_avail_t;
/* Size of root and context tables and their entries */
#define IMMU_ROOT_TBLSZ (4096)
#define IMMU_CONT_TBLSZ (4096)
#define IMMU_ROOT_NUM (256)
#define IMMU_CONT_NUM (256)
/* register offset */
/* ioapic memory region */
#define IOAPIC_REGION_START (0xfee00000)
#define IOAPIC_REGION_END (0xfeefffff)
/* fault register */
#define IMMU_FAULT_STS_PPF (2)
#define IMMU_FAULT_STS_PFO (1)
#define IMMU_FRR_GET_SID(x) ((x) & 0xffff)
/* (ex)capability register */
#define IMMU_ECAP_GET_SC(x) ((x) & 0x80)
#define IMMU_ECAP_GET_PT(x) ((x) & 0x40)
#define IMMU_ECAP_GET_CH(x) ((x) & 0x20)
#define IMMU_ECAP_GET_EIM(x) ((x) & 0x10)
#define IMMU_ECAP_GET_IR(x) ((x) & 0x8)
#define IMMU_ECAP_GET_DI(x) ((x) & 0x4)
#define IMMU_ECAP_GET_QI(x) ((x) & 0x2)
#define IMMU_ECAP_GET_C(x) ((x) & 0x1)
/* iotlb invalidation */
#define TLB_IVA_LEAF 1
#define TLB_IVA_WHOLE 0
/* dont use value 0 for enums - to catch unit 8 */
typedef enum iotlb_inv {
IOTLB_PSI = 1,
typedef enum context_inv {
CONTEXT_FSI = 1,
/* context invalidation */
/* global command register */
/* global status register */
/* psi address mask */
/* dmar fault event */
#define IMMU_INTR_IPL (4)
#define IMMU_REG_FEVNT_CON_IM_SHIFT (31)
/* max value of Size field of Interrupt Remapping Table Address Register */
#define INTRMAP_MAX_IRTA_SIZE 0xf
/* interrupt remapping table entry size */
#define INTRMAP_RTE_SIZE 0x10
/* ioapic redirection table entry related shift of remappable interrupt */
#define INTRMAP_IOAPIC_IDX_SHIFT 17
#define INTRMAP_IOAPIC_FORMAT_SHIFT 16
#define INTRMAP_IOAPIC_TM_SHIFT 15
#define INTRMAP_IOAPIC_POL_SHIFT 13
#define INTRMAP_IOAPIC_IDX15_SHIFT 11
/* msi intr entry related shift of remappable interrupt */
#define INTRMAP_MSI_IDX_SHIFT 5
#define INTRMAP_MSI_FORMAT_SHIFT 4
#define INTRMAP_MSI_SHV_SHIFT 3
#define INTRMAP_MSI_IDX15_SHIFT 2
#define INTRMAP_DISABLE (void *)-1
/*
* invalidation granularity
*/
typedef enum {
TLB_INV_G_GLOBAL = 1,
} tlb_inv_g_t;
typedef enum {
CTT_INV_G_GLOBAL = 1,
} ctt_inv_g_t;
typedef enum {
IEC_INV_GLOBAL = 0,
} iec_inv_g_t;
struct inv_queue_state;
struct intrmap_tbl_state;
/* A software page table structure */
typedef struct pgtable {
struct pgtable **swpg_next_array;
} pgtable_t;
/* interrupt remapping table state info */
typedef struct intrmap {
} intrmap_t;
typedef struct hw_rce {
} hw_rce_t;
#define TTYPE_XLATE_ONLY (0x0)
#define TTYPE_XLATE_IOTLB (0x1)
#define TTYPE_PASSTHRU (0x2)
#define TTYPE_RESERVED (0x3)
#define CONT_GET_AW(hcent) \
/* we use the bit 63 (available for system SW) as a present bit */
#define PDTE_SW3_OVERFLOW(hw_pdte) \
#define PDTE_CLEAR_SW3(hw_pdte) \
#define PDTE_CLEAR_PADDR(hw_pdte) \
typedef struct immu {
char *immu_name;
/* lock grabbed by interrupt handler */
void *immu_dmar_unit;
struct domain *immu_unity_domain;
/* IOMMU register related */
/* DVMA related */
int immu_dvma_gaw;
int immu_dvma_agaw;
int immu_dvma_nlevels;
/* DVMA context related */
/* DVMA domain related */
int immu_max_domains;
/* DVMA special devices */
/* interrupt remapping related */
/* queued invalidation related */
void *immu_qinv;
/* list_node for system-wide list of DMAR units */
} immu_t;
/* properties that control DVMA */
#define DDI_DVMA_MAPTYPE_ROOTNEX_PROP "immu-dvma-mapping"
#define DDI_DVMA_MAPTYPE_UNITY "unity"
#define DDI_DVMA_MAPTYPE_XLATE "xlate"
typedef enum immu_maptype {
IMMU_MAPTYPE_BAD = 0, /* 0 is always bad */
IMMU_MAPTYPE_UNITY = 1,
#define IMMU_COOKIE_HASHSZ (512)
/*
* domain_t
*
*/
typedef struct domain {
/* the basics */
/* mapping related */
/* pgtables */
/* list node for list of domains (unity or xlate) */
/* list node for list of domains off immu */
} domain_t;
typedef enum immu_pcib {
IMMU_PCIB_BAD = 0,
} immu_pcib_t;
/*
* immu_devi_t
* Intel IOMMU in devinfo node
*/
typedef struct immu_devi {
/* pci seg, bus, dev, func */
int imd_seg;
int imd_bus;
int imd_devfunc;
/* ppb information */
int imd_sec;
int imd_sub;
/* identifier for special devices */
/* dmar unit to which this dip belongs */
/* domain ptr */
/* my devinfo */
/*
* if we are a "special" devinfo
* the node for the special linked list
* off the DMAR unit structure
*/
} immu_devi_t;
/*
* struct dmar_arg
*/
typedef struct immu_arg {
int ima_seg;
int ima_bus;
int ima_devfunc;
} immu_arg_t;
/*
* Globals used by IOMMU code
*/
/* shared between IOMMU files */
extern dev_info_t *root_devinfo;
extern void *immu_pgtable_cache;
extern boolean_t immu_setup;
extern boolean_t immu_running;
extern kmutex_t ioapic_drhd_lock;
extern list_t ioapic_drhd_list;
/* switches */
/* Various features */
extern boolean_t immu_enable;
extern boolean_t immu_gfxdvma_enable;
extern boolean_t immu_intrmap_enable;
extern boolean_t immu_qinv_enable;
/* various quirks that need working around */
extern boolean_t immu_quirk_usbpage0;
extern boolean_t immu_quirk_usbfullpa;
extern boolean_t immu_quirk_usbrmrr;
extern boolean_t immu_quirk_mobile4;
/* debug messages */
extern boolean_t immu_dmar_print;
/* tunables */
extern int64_t immu_flush_gran;
extern immu_flags_t immu_global_dvma_flags;
/* ################### Interfaces exported outside IOMMU code ############## */
void immu_init(void);
void immu_startup(void);
void immu_shutdown(void);
void immu_destroy(void);
void immu_device_tree_changed(void);
int immu_quiesce(void);
int immu_unquiesce(void);
/* ######################################################################### */
/* ################# Interfaces used within IOMMU code #################### */
/* functions in rootnex.c */
/* immu_dmar.c interfaces */
int immu_dmar_setup(void);
int immu_dmar_parse(void);
void immu_dmar_startup(void);
void immu_dmar_shutdown(void);
void immu_dmar_destroy(void);
char *immu_dmar_unit_name(void *dmar_unit);
void immu_dmar_rmrr_map(void);
/* immu.c interfaces */
/* immu_regs.c interfaces */
/* immu_dvma.c interfaces */
/* immu_intrmap.c interfaces */
/* registers interrupt handler for IOMMU unit */
/* immu_qinv.c interfaces */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_INTEL_IOMMU_H */