1 /*
2  * Copyright (C) 2007 Advanced Micro Devices, Inc.
3  * Author: Leo Duran <leo.duran@amd.com>
4  * Author: Wei Wang <wei.wang2@amd.com> - adapted to xen
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef _ASM_X86_64_AMD_IOMMU_H
20 #define _ASM_X86_64_AMD_IOMMU_H
21 
22 #include <xen/init.h>
23 #include <xen/types.h>
24 #include <xen/list.h>
25 #include <xen/spinlock.h>
26 #include <xen/tasklet.h>
27 #include <asm/msi.h>
28 #include <asm/hvm/svm/amd-iommu-defs.h>
29 
30 #define iommu_found()           (!list_empty(&amd_iommu_head))
31 
32 extern struct list_head amd_iommu_head;
33 
34 #pragma pack(1)
35 typedef struct event_entry
36 {
37     uint32_t data[4];
38 } event_entry_t;
39 
40 typedef struct ppr_entry
41 {
42     uint32_t data[4];
43 } ppr_entry_t;
44 
45 typedef struct cmd_entry
46 {
47     uint32_t data[4];
48 } cmd_entry_t;
49 
50 typedef struct dev_entry
51 {
52     uint32_t data[8];
53 } dev_entry_t;
54 #pragma pack()
55 
56 struct table_struct {
57     void *buffer;
58     unsigned long entries;
59     unsigned long alloc_size;
60 };
61 
62 struct ring_buffer {
63     void *buffer;
64     unsigned long entries;
65     unsigned long alloc_size;
66     uint32_t tail;
67     uint32_t head;
68     spinlock_t lock;    /* protect buffer pointers */
69 };
70 
71 typedef struct iommu_cap {
72     uint32_t header;                    /* offset 00h */
73     uint32_t base_low;                  /* offset 04h */
74     uint32_t base_hi;                   /* offset 08h */
75     uint32_t range;                     /* offset 0Ch */
76     uint32_t misc;                      /* offset 10h */
77 } iommu_cap_t;
78 
79 struct amd_iommu {
80     struct list_head list;
81     spinlock_t lock; /* protect iommu */
82 
83     u16 seg;
84     u16 bdf;
85     struct msi_desc msi;
86 
87     u16 cap_offset;
88     iommu_cap_t cap;
89 
90     u8 ht_flags;
91     u64 features;
92 
93     void *mmio_base;
94     unsigned long mmio_base_phys;
95 
96     struct table_struct dev_table;
97     struct ring_buffer cmd_buffer;
98     struct ring_buffer event_log;
99     struct ring_buffer ppr_log;
100 
101     int exclusion_enable;
102     int exclusion_allow_all;
103     uint64_t exclusion_base;
104     uint64_t exclusion_limit;
105 
106     int enabled;
107 
108     struct list_head ats_devices;
109 };
110 
111 struct ivrs_mappings {
112     u16 dte_requestor_id;
113     u8 dte_allow_exclusion;
114     u8 unity_map_enable;
115     u8 write_permission;
116     u8 read_permission;
117     unsigned long addr_range_start;
118     unsigned long addr_range_length;
119     struct amd_iommu *iommu;
120 
121     /* per device interrupt remapping table */
122     void *intremap_table;
123     unsigned long *intremap_inuse;
124     spinlock_t intremap_lock;
125 
126     /* ivhd device data settings */
127     u8 device_flags;
128 };
129 
130 extern unsigned int ivrs_bdf_entries;
131 extern u8 ivhd_type;
132 
133 struct ivrs_mappings *get_ivrs_mappings(u16 seg);
134 int iterate_ivrs_mappings(int (*)(u16 seg, struct ivrs_mappings *));
135 int iterate_ivrs_entries(int (*)(u16 seg, struct ivrs_mappings *));
136 
137 /* iommu tables in guest space */
138 struct mmio_reg {
139     uint32_t    lo;
140     uint32_t    hi;
141 };
142 
143 struct guest_dev_table {
144     struct mmio_reg         reg_base;
145     uint32_t                size;
146 };
147 
148 struct guest_buffer {
149     struct mmio_reg         reg_base;
150     struct mmio_reg         reg_tail;
151     struct mmio_reg         reg_head;
152     uint32_t                entries;
153 };
154 
155 struct guest_iommu_msi {
156     uint8_t                 vector;
157     uint8_t                 dest;
158     uint8_t                 dest_mode;
159     uint8_t                 delivery_mode;
160     uint8_t                 trig_mode;
161 };
162 
163 /* virtual IOMMU structure */
164 struct guest_iommu {
165 
166     struct domain          *domain;
167     spinlock_t              lock;
168     bool_t                  enabled;
169 
170     struct guest_dev_table  dev_table;
171     struct guest_buffer     cmd_buffer;
172     struct guest_buffer     event_log;
173     struct guest_buffer     ppr_log;
174 
175     struct tasklet          cmd_buffer_tasklet;
176 
177     uint64_t                mmio_base;             /* MMIO base address */
178 
179     /* MMIO regs */
180     struct mmio_reg         reg_ctrl;              /* MMIO offset 0018h */
181     struct mmio_reg         reg_status;            /* MMIO offset 2020h */
182     struct mmio_reg         reg_ext_feature;       /* MMIO offset 0030h */
183 
184     /* guest interrupt settings */
185     struct guest_iommu_msi  msi;
186 };
187 
188 extern bool_t iommuv2_enabled;
189 
190 #endif /* _ASM_X86_64_AMD_IOMMU_H */
191