amd_iommu_impl.h revision 7d87efa8fdfb9453670f2832df666fdae8291a84
/*
* 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
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _AMD_IOMMU_IMPL_H
#define _AMD_IOMMU_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _KERNEL
#define AMD_IOMMU_PCI_PROG_IF (0x0)
#define AMD_IOMMU_CAP (0x3)
#define AMD_IOMMU_REG_SIZE (0x2028)
#define AMD_IOMMU_DEVTBL_SZ (16)
#define AMD_IOMMU_CMDBUF_SZ (15)
#define AMD_IOMMU_EVENTLOG_SZ (15)
#define AMD_IOMMU_DEVENT_SZ (32)
#define AMD_IOMMU_CMD_SZ (16)
#define AMD_IOMMU_EVENT_SZ (16)
/* Capability Register offsets */
#define AMD_IOMMU_CAP_HDR_OFF (0x00)
#define AMD_IOMMU_CAP_ADDR_LOW_OFF (0x04)
#define AMD_IOMMU_CAP_ADDR_HI_OFF (0x08)
#define AMD_IOMMU_CAP_RANGE_OFF (0x0C)
#define AMD_IOMMU_CAP_MISC_OFF (0x10)
/* ControL Registers offsets */
#define AMD_IOMMU_DEVTBL_REG_OFF (0x00)
#define AMD_IOMMU_CMDBUF_REG_OFF (0x08)
#define AMD_IOMMU_EVENTLOG_REG_OFF (0x10)
#define AMD_IOMMU_CTRL_REG_OFF (0x18)
#define AMD_IOMMU_EXCL_BASE_REG_OFF (0x20)
#define AMD_IOMMU_EXCL_LIM_REG_OFF (0x28)
#define AMD_IOMMU_CMDBUF_HEAD_REG_OFF (0x2000)
#define AMD_IOMMU_CMDBUF_TAIL_REG_OFF (0x2008)
#define AMD_IOMMU_EVENTLOG_HEAD_REG_OFF (0x2010)
#define AMD_IOMMU_EVENTLOG_TAIL_REG_OFF (0x2018)
#define AMD_IOMMU_STATUS_REG_OFF (0x2020)
/* Capability Header Register Bits */
/* Capability Range Register bits */
/* Capability Misc Register bits */
/* Device Table Base Address register bits */
/* Command Buffer Base Address register bits */
#define AMD_IOMMU_CMDBUF_MINSZ (8)
#define AMD_IOMMU_CMDBUF_MAXSZ (15)
/* Event Log Base Address register bits */
#define AMD_IOMMU_EVENTLOG_MINSZ (8)
#define AMD_IOMMU_EVENTLOG_MAXSZ (15)
/* Control register bits */
#define AMD_IOMMU_ENABLE (0 << 16 | 0)
/* Exclusion Base Register bits */
#define AMD_IOMMU_EXCL_BASE_EXEN (0 << 16 | 0)
/* Exclusion Limit Register bits */
/* Command Buffer Head Pointer Register bits */
/* Command Buffer Tail Pointer Register bits */
/* Event Log Head Pointer Register bits */
/* Event Log Tail Pointer Register bits */
/* Status Register bits */
#define AMD_IOMMU_EVENT_OVERFLOW_INT (0 << 16 | 0)
/* Device Table Bits */
/* size in bytes of each device table entry */
#define AMD_IOMMU_DEVTBL_ENTRY_SZ (32)
/* Interrupt Remapping related Device Table bits */
/* DMA Remapping related Device Table Bits */
#define AMD_IOMMU_DEVTBL_V (0 << 16 | 0)
#define AMD_IOMMU_ALIAS_HASH_SZ (256)
#define AMD_IOMMU_REG_ADDR_LOCKED (0x1)
/*
* IOMMU Command bits
*/
typedef enum {
AMD_IOMMU_CMD_INVAL = 0,
typedef enum {
/* Common command bits */
/* Completion Wait command bits */
#define AMD_IOMMU_CMD_COMPL_WAIT_S (0 << 16 | 0)
/* Invalidate Device Table entry command bits */
/* Invalidate IOMMU Pages command bits */
#define AMD_IOMMU_CMD_INVAL_PAGES_S (0 << 16 | 0)
/* Invalidate IOTLB command bits */
#define AMD_IOMMU_CMD_INVAL_IOTLB_S (0 << 16 | 0)
#define AMD_IOMMU_DEFAULT_MAXPEND (10)
/* Invalidate Interrupt Table bits */
#if defined(__amd64)
#define dmac_cookie_addr dmac_laddress
#else
#define dmac_cookie_addr dmac_address
#endif
#define AMD_IOMMU_MAX_DEVICEID (0xFFFF)
/*
* DMA sync macros
* TODO: optimize sync only small ranges
*/
#define CMD2OFF(c) ((c) << 4)
#define OFF2CMD(o) ((o) >> 4)
typedef union split {
} split_t;
#define BITPOS_START(b) ((b) >> 16)
#define BITPOS_END(b) ((b) & 0xFFFF)
#define AMD_IOMMU_REG_GET64_IMPL(rp, b) \
#define AMD_IOMMU_REG_GET64(rp, b) \
#define AMD_IOMMU_REG_GET32(rp, b) \
#define AMD_IOMMU_REG_GET16(rp, b) \
#define AMD_IOMMU_REG_GET8(rp, b) \
#define AMD_IOMMU_REG_SET64_IMPL(rp, b, v) \
((*(rp)) = \
| ((uint64_t)(v) << BITPOS_END(b))))
#define AMD_IOMMU_REG_SET64(rp, b, v) \
(void) ((amd_iommu_64bit_bug) ? \
amd_iommu_reg_set64_workaround(rp, b, v) : \
AMD_IOMMU_REG_SET64_IMPL(rp, b, v))
#define AMD_IOMMU_REG_SET32(rp, b, v) \
((*(rp)) = \
| ((uint32_t)(v) << BITPOS_END(b))))
#define AMD_IOMMU_REG_SET16(rp, b, v) \
((*(rp)) = \
| ((uint16_t)(v) << BITPOS_END(b))))
#define AMD_IOMMU_REG_SET8(rp, b, v) \
((*(rp)) = \
| ((uint8_t)(v) << BITPOS_END(b))))
/*
* Cast a 64 bit pointer to a uint64_t *
*/
typedef enum {
typedef struct amd_iommu {
int aiomt_idx;
void *aiomt_dma_bufva;
struct amd_iommu *aiomt_next;
} amd_iommu_t;
typedef struct amd_iommu_dma_devtbl_ent {
typedef struct amd_iommu_alias {
struct amd_iommu_alias *al_next;
typedef struct amd_iommu_cmdargs {
struct amd_iommu_page_table;
typedef struct amd_iommu_page_table_hash {
struct amd_iommu_page_table **ampt_hash;
typedef enum {
typedef enum {
AMD_IOMMU_DEBUG_NONE = 0,
AMD_IOMMU_DEBUG_ALLOCHDL = 0x1,
AMD_IOMMU_DEBUG_FREEHDL = 0x2,
AMD_IOMMU_DEBUG_BIND = 0x4,
AMD_IOMMU_DEBUG_UNBIND = 0x8,
AMD_IOMMU_DEBUG_WIN = 0x10,
AMD_IOMMU_DEBUG_PAGE_TABLES = 0x20,
AMD_IOMMU_DEBUG_DEVTBL = 0x40,
AMD_IOMMU_DEBUG_CMDBUF = 0x80,
AMD_IOMMU_DEBUG_EVENTLOG = 0x100,
AMD_IOMMU_DEBUG_ACPI = 0x200,
AMD_IOMMU_DEBUG_PA2VA = 0x400,
AMD_IOMMU_DEBUG_TABLES = 0x800,
AMD_IOMMU_DEBUG_EXCL = 0x1000,
AMD_IOMMU_DEBUG_INTR = 0x2000
extern const char *amd_iommu_modname;
extern kmutex_t amd_iommu_global_lock;
extern amd_iommu_alias_t **amd_iommu_alias;
extern amd_iommu_debug_t amd_iommu_debug;
extern uint8_t amd_iommu_htatsresv;
extern uint8_t amd_iommu_vasize;
extern uint8_t amd_iommu_pasize;
extern int amd_iommu_64bit_bug;
extern int amd_iommu_unity_map;
extern int amd_iommu_no_RW_perms;
extern int amd_iommu_no_unmap;
extern int amd_iommu_pageva_inval_all;
extern int amd_iommu_disable;
extern char *amd_iommu_disable_list;
void amd_iommu_read_boot_props(void);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _AMD_IOMMU_IMPL_H */