1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _AMD_IOMMU_PAGE_TABLES_H 27 #define _AMD_IOMMU_PAGE_TABLES_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifdef _KERNEL 34 35 /* Common to PTEs and PDEs */ 36 #define AMD_IOMMU_PTDE_IW (62 << 16 | 62) 37 #define AMD_IOMMU_PTDE_IR (61 << 16 | 61) 38 #define AMD_IOMMU_PTDE_ADDR (51 << 16 | 12) 39 #define AMD_IOMMU_PTDE_NXT_LVL (11 << 16 | 9) 40 #define AMD_IOMMU_PTDE_PR (0 << 16 | 0) 41 42 #define AMD_IOMMU_PTE_FC (60 << 16 | 60) 43 #define AMD_IOMMU_PTE_U (59 << 16 | 59) 44 45 #define AMD_IOMMU_VA_NBITS(l) ((l) == 6 ? 7 : 9) 46 #define AMD_IOMMU_VA_BITMASK(l) ((1 << AMD_IOMMU_VA_NBITS(l)) - 1) 47 #define AMD_IOMMU_VA_SHIFT(v, l) \ 48 ((v) >> (MMU_PAGESHIFT + (AMD_IOMMU_VA_NBITS(l - 1) * (l - 1)))) 49 #define AMD_IOMMU_VA_BITS(v, l) \ 50 (AMD_IOMMU_VA_SHIFT(v, l) & AMD_IOMMU_VA_BITMASK(l)) 51 #define AMD_IOMMU_VA_TOTBITS(l) \ 52 (((l) == 6 ? 7 + (l - 1) * 9: l*9) + MMU_PAGESHIFT) 53 #define AMD_IOMMU_VA_TOTMASK(l) ((1 << AMD_IOMMU_VA_TOTBITS(l)) - 1) 54 #define AMD_IOMMU_VA_INVAL_SETMASK(l) \ 55 (((1 << AMD_IOMMU_VA_TOTBITS(l)) - 1) >> 1) 56 #define AMD_IOMMU_VA_INVAL_CLRMASK(l) \ 57 (~(1 << (AMD_IOMMU_VA_TOTBITS(l) - 1))) 58 #define AMD_IOMMU_VA_INVAL(v, l) \ 59 (((v) & AMD_IOMMU_VA_INVAL_CLRMASK(l)) | AMD_IOMMU_VA_INVAL_SETMASK(l)) 60 61 #define AMD_IOMMU_PGTABLE_SZ (4096) 62 #define AMD_IOMMU_PGTABLE_MAXLEVEL (6) 63 #define AMD_IOMMU_PGTABLE_HASH_SZ (256) 64 65 #define AMD_IOMMU_PGTABLE_ALIGN ((1ULL << 12) - 1) 66 #define AMD_IOMMU_PGTABLE_SIZE (1ULL << 12) 67 68 #define AMD_IOMMU_MAX_PDTE (1ULL << AMD_IOMMU_VA_NBITS(1)) 69 #define PT_REF_VALID(p) ((p)->pt_ref >= 0 && \ 70 (p)->pt_ref <= AMD_IOMMU_MAX_PDTE) 71 72 #define AMD_IOMMU_DOMAIN_HASH_SZ (256) 73 #define AMD_IOMMU_PGTABLE_FREELIST_MAX (256) 74 #define AMD_IOMMU_PA2VA_HASH_SZ (256) 75 76 #define AMD_IOMMU_SIZE_4G ((uint64_t)1 << 32) 77 #define AMD_IOMMU_VMEM_NAMELEN (30) 78 79 typedef enum { 80 AMD_IOMMU_INVALID_DOMAIN = 0, 81 AMD_IOMMU_IDENTITY_DOMAIN = 0xFFFD, 82 AMD_IOMMU_PASSTHRU_DOMAIN = 0xFFFE, 83 AMD_IOMMU_SYS_DOMAIN = 0xFFFF 84 } domain_id_t; 85 86 typedef enum { 87 AMD_IOMMU_INVALID_MAP = 0, 88 AMD_IOMMU_UNITY_MAP, 89 AMD_IOMMU_VMEM_MAP 90 } map_type_t; 91 92 typedef struct amd_iommu_page_table { 93 domain_id_t pt_domainid; 94 int pt_level; 95 ddi_dma_handle_t pt_dma_hdl; 96 ddi_acc_handle_t pt_mem_hdl; 97 uint64_t pt_mem_reqsz; 98 uint64_t pt_mem_realsz; 99 uint64_t *pt_pgtblva; 100 uint64_t pt_pte_ref[AMD_IOMMU_MAX_PDTE]; 101 uint16_t pt_index; 102 int pt_ref; 103 ddi_dma_cookie_t pt_cookie; 104 struct amd_iommu_page_table *pt_next; 105 struct amd_iommu_page_table *pt_prev; 106 struct amd_iommu_page_table *pt_parent; 107 } amd_iommu_page_table_t; 108 109 typedef struct amd_iommu_domain { 110 domain_id_t d_domainid; 111 uint64_t d_pgtable_root_4K; 112 int64_t d_ref; 113 vmem_t *d_vmem; 114 struct amd_iommu_domain *d_prev; 115 struct amd_iommu_domain *d_next; 116 } amd_iommu_domain_t; 117 118 int amd_iommu_map_pa2va(amd_iommu_t *iommu, dev_info_t *rdip, 119 ddi_dma_attr_t *attrp, struct ddi_dma_req *dmareq, 120 uint64_t pa, uint64_t pa_sz, map_type_t type, 121 uint64_t *start_vap, int km_flags); 122 int amd_iommu_unmap_va(amd_iommu_t *iommu, dev_info_t *rdip, 123 uint64_t va, uint64_t va_sz, map_type_t type); 124 void amd_iommu_init_page_tables(amd_iommu_t *iommu); 125 void amd_iommu_fini_page_tables(amd_iommu_t *iommu); 126 void amd_iommu_set_passthru(amd_iommu_t *iommu, dev_info_t *rdip); 127 128 #endif /* _KERNEL */ 129 130 #ifdef __cplusplus 131 } 132 #endif 133 134 #endif /* _AMD_IOMMU_PAGE_TABLES_H */ 135