xref: /openbmc/qemu/hw/arm/smmuv3-internal.h (revision da4f7b8561e69112171f52279d23b9014902a398)
1  /*
2   * ARM SMMUv3 support - Internal API
3   *
4   * Copyright (C) 2014-2016 Broadcom Corporation
5   * Copyright (c) 2017 Red Hat, Inc.
6   * Written by Prem Mallappa, Eric Auger
7   *
8   * This program is free software; you can redistribute it and/or modify
9   * it under the terms of the GNU General Public License version 2 as
10   * published by the Free Software Foundation.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License along
18   * with this program; if not, see <http://www.gnu.org/licenses/>.
19   */
20  
21  #ifndef HW_ARM_SMMUV3_INTERNAL_H
22  #define HW_ARM_SMMUV3_INTERNAL_H
23  
24  #include "hw/registerfields.h"
25  #include "hw/arm/smmu-common.h"
26  
27  typedef enum SMMUTranslationStatus {
28      SMMU_TRANS_DISABLE,
29      SMMU_TRANS_ABORT,
30      SMMU_TRANS_BYPASS,
31      SMMU_TRANS_ERROR,
32      SMMU_TRANS_SUCCESS,
33  } SMMUTranslationStatus;
34  
35  typedef enum SMMUTranslationClass {
36      SMMU_CLASS_CD,
37      SMMU_CLASS_TT,
38      SMMU_CLASS_IN,
39  } SMMUTranslationClass;
40  
41  /* MMIO Registers */
42  
43  REG32(IDR0,                0x0)
44      FIELD(IDR0, S2P,         0 , 1)
45      FIELD(IDR0, S1P,         1 , 1)
46      FIELD(IDR0, TTF,         2 , 2)
47      FIELD(IDR0, COHACC,      4 , 1)
48      FIELD(IDR0, BTM,         5 , 1)
49      FIELD(IDR0, HTTU,        6 , 2)
50      FIELD(IDR0, DORMHINT,    8 , 1)
51      FIELD(IDR0, HYP,         9 , 1)
52      FIELD(IDR0, ATS,         10, 1)
53      FIELD(IDR0, NS1ATS,      11, 1)
54      FIELD(IDR0, ASID16,      12, 1)
55      FIELD(IDR0, MSI,         13, 1)
56      FIELD(IDR0, SEV,         14, 1)
57      FIELD(IDR0, ATOS,        15, 1)
58      FIELD(IDR0, PRI,         16, 1)
59      FIELD(IDR0, VMW,         17, 1)
60      FIELD(IDR0, VMID16,      18, 1)
61      FIELD(IDR0, CD2L,        19, 1)
62      FIELD(IDR0, VATOS,       20, 1)
63      FIELD(IDR0, TTENDIAN,    21, 2)
64      FIELD(IDR0, ATSRECERR,   23, 1)
65      FIELD(IDR0, STALL_MODEL, 24, 2)
66      FIELD(IDR0, TERM_MODEL,  26, 1)
67      FIELD(IDR0, STLEVEL,     27, 2)
68      FIELD(IDR0, RME_IMPL,    30, 1)
69  
70  REG32(IDR1,                0x4)
71      FIELD(IDR1, SIDSIZE,      0 , 6)
72      FIELD(IDR1, SSIDSIZE,     6 , 5)
73      FIELD(IDR1, PRIQS,        11, 5)
74      FIELD(IDR1, EVENTQS,      16, 5)
75      FIELD(IDR1, CMDQS,        21, 5)
76      FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
77      FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
78      FIELD(IDR1, REL,          28, 1)
79      FIELD(IDR1, QUEUES_PRESET, 29, 1)
80      FIELD(IDR1, TABLES_PRESET, 30, 1)
81      FIELD(IDR1, ECMDQ,        31, 1)
82  
83  #define SMMU_IDR1_SIDSIZE 16
84  #define SMMU_CMDQS   19
85  #define SMMU_EVENTQS 19
86  
87  REG32(IDR2,                0x8)
88       FIELD(IDR2, BA_VATOS, 0, 10)
89  
90  REG32(IDR3,                0xc)
91       FIELD(IDR3, HAD,         2, 1);
92       FIELD(IDR3, PBHA,        3, 1);
93       FIELD(IDR3, XNX,         4, 1);
94       FIELD(IDR3, PPS,         5, 1);
95       FIELD(IDR3, MPAM,        7, 1);
96       FIELD(IDR3, FWB,         8, 1);
97       FIELD(IDR3, STT,         9, 1);
98       FIELD(IDR3, RIL,        10, 1);
99       FIELD(IDR3, BBML,       11, 2);
100       FIELD(IDR3, E0PD,       13, 1);
101       FIELD(IDR3, PTWNNC,     14, 1);
102       FIELD(IDR3, DPT,        15, 1);
103  
104  REG32(IDR4,                0x10)
105  
106  REG32(IDR5,                0x14)
107       FIELD(IDR5, OAS,         0, 3);
108       FIELD(IDR5, GRAN4K,      4, 1);
109       FIELD(IDR5, GRAN16K,     5, 1);
110       FIELD(IDR5, GRAN64K,     6, 1);
111       FIELD(IDR5, VAX,        10, 2);
112       FIELD(IDR5, STALL_MAX,  16, 16);
113  
114  #define SMMU_IDR5_OAS 4
115  
116  REG32(IIDR,                0x18)
117  REG32(AIDR,                0x1c)
118  REG32(CR0,                 0x20)
119      FIELD(CR0, SMMU_ENABLE,   0, 1)
120      FIELD(CR0, EVENTQEN,      2, 1)
121      FIELD(CR0, CMDQEN,        3, 1)
122  
123  #define SMMU_CR0_RESERVED 0xFFFFFC20
124  
125  REG32(CR0ACK,              0x24)
126  REG32(CR1,                 0x28)
127  REG32(CR2,                 0x2c)
128  REG32(STATUSR,             0x40)
129  REG32(GBPA,                0x44)
130      FIELD(GBPA, ABORT,        20, 1)
131      FIELD(GBPA, UPDATE,       31, 1)
132  
133  /* Use incoming. */
134  #define SMMU_GBPA_RESET_VAL 0x1000
135  
136  REG32(IRQ_CTRL,            0x50)
137      FIELD(IRQ_CTRL, GERROR_IRQEN,        0, 1)
138      FIELD(IRQ_CTRL, PRI_IRQEN,           1, 1)
139      FIELD(IRQ_CTRL, EVENTQ_IRQEN,        2, 1)
140  
141  REG32(IRQ_CTRL_ACK,        0x54)
142  REG32(GERROR,              0x60)
143      FIELD(GERROR, CMDQ_ERR,           0, 1)
144      FIELD(GERROR, EVENTQ_ABT_ERR,     2, 1)
145      FIELD(GERROR, PRIQ_ABT_ERR,       3, 1)
146      FIELD(GERROR, MSI_CMDQ_ABT_ERR,   4, 1)
147      FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
148      FIELD(GERROR, MSI_PRIQ_ABT_ERR,   6, 1)
149      FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
150      FIELD(GERROR, MSI_SFM_ERR,        8, 1)
151  
152  REG32(GERRORN,             0x64)
153  
154  #define A_GERROR_IRQ_CFG0  0x68 /* 64b */
155  REG32(GERROR_IRQ_CFG1, 0x70)
156  REG32(GERROR_IRQ_CFG2, 0x74)
157  
158  #define A_STRTAB_BASE      0x80 /* 64b */
159  
160  #define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
161  
162  REG32(STRTAB_BASE_CFG,     0x88)
163      FIELD(STRTAB_BASE_CFG, FMT,      16, 2)
164      FIELD(STRTAB_BASE_CFG, SPLIT,    6 , 5)
165      FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
166  
167  #define A_CMDQ_BASE        0x90 /* 64b */
168  REG32(CMDQ_PROD,           0x98)
169  REG32(CMDQ_CONS,           0x9c)
170      FIELD(CMDQ_CONS, ERR, 24, 7)
171  
172  #define A_EVENTQ_BASE      0xa0 /* 64b */
173  REG32(EVENTQ_PROD,         0xa8)
174  REG32(EVENTQ_CONS,         0xac)
175  
176  #define A_EVENTQ_IRQ_CFG0  0xb0 /* 64b */
177  REG32(EVENTQ_IRQ_CFG1,     0xb8)
178  REG32(EVENTQ_IRQ_CFG2,     0xbc)
179  
180  #define A_IDREGS           0xfd0
181  
smmu_enabled(SMMUv3State * s)182  static inline int smmu_enabled(SMMUv3State *s)
183  {
184      return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
185  }
186  
187  /* Command Queue Entry */
188  typedef struct Cmd {
189      uint32_t word[4];
190  } Cmd;
191  
192  /* Event Queue Entry */
193  typedef struct Evt  {
194      uint32_t word[8];
195  } Evt;
196  
smmuv3_idreg(int regoffset)197  static inline uint32_t smmuv3_idreg(int regoffset)
198  {
199      /*
200       * Return the value of the Primecell/Corelink ID registers at the
201       * specified offset from the first ID register.
202       * These value indicate an ARM implementation of MMU600 p1
203       */
204      static const uint8_t smmuv3_ids[] = {
205          0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
206      };
207      return smmuv3_ids[regoffset / 4];
208  }
209  
smmuv3_eventq_irq_enabled(SMMUv3State * s)210  static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
211  {
212      return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
213  }
214  
smmuv3_gerror_irq_enabled(SMMUv3State * s)215  static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
216  {
217      return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
218  }
219  
220  /* Queue Handling */
221  
222  #define Q_BASE(q)          ((q)->base & SMMU_BASE_ADDR_MASK)
223  #define WRAP_MASK(q)       (1 << (q)->log2size)
224  #define INDEX_MASK(q)      (((1 << (q)->log2size)) - 1)
225  #define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
226  
227  #define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
228  #define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
229  
230  #define Q_CONS_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
231  #define Q_PROD_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
232  
233  #define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
234  #define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
235  
smmuv3_q_full(SMMUQueue * q)236  static inline bool smmuv3_q_full(SMMUQueue *q)
237  {
238      return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
239  }
240  
smmuv3_q_empty(SMMUQueue * q)241  static inline bool smmuv3_q_empty(SMMUQueue *q)
242  {
243      return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
244  }
245  
queue_prod_incr(SMMUQueue * q)246  static inline void queue_prod_incr(SMMUQueue *q)
247  {
248      q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
249  }
250  
queue_cons_incr(SMMUQueue * q)251  static inline void queue_cons_incr(SMMUQueue *q)
252  {
253      /*
254       * We have to use deposit for the CONS registers to preserve
255       * the ERR field in the high bits.
256       */
257      q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
258  }
259  
smmuv3_cmdq_enabled(SMMUv3State * s)260  static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
261  {
262      return FIELD_EX32(s->cr[0], CR0, CMDQEN);
263  }
264  
smmuv3_eventq_enabled(SMMUv3State * s)265  static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
266  {
267      return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
268  }
269  
smmu_write_cmdq_err(SMMUv3State * s,uint32_t err_type)270  static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
271  {
272      s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
273  }
274  
275  /* Commands */
276  
277  typedef enum SMMUCommandType {
278      SMMU_CMD_NONE            = 0x00,
279      SMMU_CMD_PREFETCH_CONFIG       ,
280      SMMU_CMD_PREFETCH_ADDR,
281      SMMU_CMD_CFGI_STE,
282      SMMU_CMD_CFGI_STE_RANGE,
283      SMMU_CMD_CFGI_CD,
284      SMMU_CMD_CFGI_CD_ALL,
285      SMMU_CMD_CFGI_ALL,
286      SMMU_CMD_TLBI_NH_ALL     = 0x10,
287      SMMU_CMD_TLBI_NH_ASID,
288      SMMU_CMD_TLBI_NH_VA,
289      SMMU_CMD_TLBI_NH_VAA,
290      SMMU_CMD_TLBI_EL3_ALL    = 0x18,
291      SMMU_CMD_TLBI_EL3_VA     = 0x1a,
292      SMMU_CMD_TLBI_EL2_ALL    = 0x20,
293      SMMU_CMD_TLBI_EL2_ASID,
294      SMMU_CMD_TLBI_EL2_VA,
295      SMMU_CMD_TLBI_EL2_VAA,
296      SMMU_CMD_TLBI_S12_VMALL  = 0x28,
297      SMMU_CMD_TLBI_S2_IPA     = 0x2a,
298      SMMU_CMD_TLBI_NSNH_ALL   = 0x30,
299      SMMU_CMD_ATC_INV         = 0x40,
300      SMMU_CMD_PRI_RESP,
301      SMMU_CMD_RESUME          = 0x44,
302      SMMU_CMD_STALL_TERM,
303      SMMU_CMD_SYNC,
304  } SMMUCommandType;
305  
306  static const char *cmd_stringify[] = {
307      [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
308      [SMMU_CMD_PREFETCH_ADDR]   = "SMMU_CMD_PREFETCH_ADDR",
309      [SMMU_CMD_CFGI_STE]        = "SMMU_CMD_CFGI_STE",
310      [SMMU_CMD_CFGI_STE_RANGE]  = "SMMU_CMD_CFGI_STE_RANGE",
311      [SMMU_CMD_CFGI_CD]         = "SMMU_CMD_CFGI_CD",
312      [SMMU_CMD_CFGI_CD_ALL]     = "SMMU_CMD_CFGI_CD_ALL",
313      [SMMU_CMD_CFGI_ALL]        = "SMMU_CMD_CFGI_ALL",
314      [SMMU_CMD_TLBI_NH_ALL]     = "SMMU_CMD_TLBI_NH_ALL",
315      [SMMU_CMD_TLBI_NH_ASID]    = "SMMU_CMD_TLBI_NH_ASID",
316      [SMMU_CMD_TLBI_NH_VA]      = "SMMU_CMD_TLBI_NH_VA",
317      [SMMU_CMD_TLBI_NH_VAA]     = "SMMU_CMD_TLBI_NH_VAA",
318      [SMMU_CMD_TLBI_EL3_ALL]    = "SMMU_CMD_TLBI_EL3_ALL",
319      [SMMU_CMD_TLBI_EL3_VA]     = "SMMU_CMD_TLBI_EL3_VA",
320      [SMMU_CMD_TLBI_EL2_ALL]    = "SMMU_CMD_TLBI_EL2_ALL",
321      [SMMU_CMD_TLBI_EL2_ASID]   = "SMMU_CMD_TLBI_EL2_ASID",
322      [SMMU_CMD_TLBI_EL2_VA]     = "SMMU_CMD_TLBI_EL2_VA",
323      [SMMU_CMD_TLBI_EL2_VAA]    = "SMMU_CMD_TLBI_EL2_VAA",
324      [SMMU_CMD_TLBI_S12_VMALL]  = "SMMU_CMD_TLBI_S12_VMALL",
325      [SMMU_CMD_TLBI_S2_IPA]     = "SMMU_CMD_TLBI_S2_IPA",
326      [SMMU_CMD_TLBI_NSNH_ALL]   = "SMMU_CMD_TLBI_NSNH_ALL",
327      [SMMU_CMD_ATC_INV]         = "SMMU_CMD_ATC_INV",
328      [SMMU_CMD_PRI_RESP]        = "SMMU_CMD_PRI_RESP",
329      [SMMU_CMD_RESUME]          = "SMMU_CMD_RESUME",
330      [SMMU_CMD_STALL_TERM]      = "SMMU_CMD_STALL_TERM",
331      [SMMU_CMD_SYNC]            = "SMMU_CMD_SYNC",
332  };
333  
smmu_cmd_string(SMMUCommandType type)334  static inline const char *smmu_cmd_string(SMMUCommandType type)
335  {
336      if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
337          return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
338      } else {
339          return "INVALID";
340      }
341  }
342  
343  /* CMDQ fields */
344  
345  typedef enum {
346      SMMU_CERROR_NONE = 0,
347      SMMU_CERROR_ILL,
348      SMMU_CERROR_ABT,
349      SMMU_CERROR_ATC_INV_SYNC,
350  } SMMUCmdError;
351  
352  enum { /* Command completion notification */
353      CMD_SYNC_SIG_NONE,
354      CMD_SYNC_SIG_IRQ,
355      CMD_SYNC_SIG_SEV,
356  };
357  
358  #define CMD_TYPE(x)         extract32((x)->word[0], 0 , 8)
359  #define CMD_NUM(x)          extract32((x)->word[0], 12 , 5)
360  #define CMD_SCALE(x)        extract32((x)->word[0], 20 , 5)
361  #define CMD_SSEC(x)         extract32((x)->word[0], 10, 1)
362  #define CMD_SSV(x)          extract32((x)->word[0], 11, 1)
363  #define CMD_RESUME_AC(x)    extract32((x)->word[0], 12, 1)
364  #define CMD_RESUME_AB(x)    extract32((x)->word[0], 13, 1)
365  #define CMD_SYNC_CS(x)      extract32((x)->word[0], 12, 2)
366  #define CMD_SSID(x)         extract32((x)->word[0], 12, 20)
367  #define CMD_SID(x)          ((x)->word[1])
368  #define CMD_VMID(x)         extract32((x)->word[1], 0 , 16)
369  #define CMD_ASID(x)         extract32((x)->word[1], 16, 16)
370  #define CMD_RESUME_STAG(x)  extract32((x)->word[2], 0 , 16)
371  #define CMD_RESP(x)         extract32((x)->word[2], 11, 2)
372  #define CMD_LEAF(x)         extract32((x)->word[2], 0 , 1)
373  #define CMD_TTL(x)          extract32((x)->word[2], 8 , 2)
374  #define CMD_TG(x)           extract32((x)->word[2], 10, 2)
375  #define CMD_STE_RANGE(x)    extract32((x)->word[2], 0 , 5)
376  #define CMD_ADDR(x)                             \
377      (((uint64_t)((x)->word[3]) << 32) |         \
378       ((extract64((x)->word[2], 12, 20)) << 12))
379  
380  #define SMMU_FEATURE_2LVL_STE (1 << 0)
381  
382  /* Events */
383  
384  typedef enum SMMUEventType {
385      SMMU_EVT_NONE               = 0x00,
386      SMMU_EVT_F_UUT                    ,
387      SMMU_EVT_C_BAD_STREAMID           ,
388      SMMU_EVT_F_STE_FETCH              ,
389      SMMU_EVT_C_BAD_STE                ,
390      SMMU_EVT_F_BAD_ATS_TREQ           ,
391      SMMU_EVT_F_STREAM_DISABLED        ,
392      SMMU_EVT_F_TRANS_FORBIDDEN        ,
393      SMMU_EVT_C_BAD_SUBSTREAMID        ,
394      SMMU_EVT_F_CD_FETCH               ,
395      SMMU_EVT_C_BAD_CD                 ,
396      SMMU_EVT_F_WALK_EABT              ,
397      SMMU_EVT_F_TRANSLATION      = 0x10,
398      SMMU_EVT_F_ADDR_SIZE              ,
399      SMMU_EVT_F_ACCESS                 ,
400      SMMU_EVT_F_PERMISSION             ,
401      SMMU_EVT_F_TLB_CONFLICT     = 0x20,
402      SMMU_EVT_F_CFG_CONFLICT           ,
403      SMMU_EVT_E_PAGE_REQ         = 0x24,
404  } SMMUEventType;
405  
406  static const char *event_stringify[] = {
407      [SMMU_EVT_NONE]                     = "no recorded event",
408      [SMMU_EVT_F_UUT]                    = "SMMU_EVT_F_UUT",
409      [SMMU_EVT_C_BAD_STREAMID]           = "SMMU_EVT_C_BAD_STREAMID",
410      [SMMU_EVT_F_STE_FETCH]              = "SMMU_EVT_F_STE_FETCH",
411      [SMMU_EVT_C_BAD_STE]                = "SMMU_EVT_C_BAD_STE",
412      [SMMU_EVT_F_BAD_ATS_TREQ]           = "SMMU_EVT_F_BAD_ATS_TREQ",
413      [SMMU_EVT_F_STREAM_DISABLED]        = "SMMU_EVT_F_STREAM_DISABLED",
414      [SMMU_EVT_F_TRANS_FORBIDDEN]        = "SMMU_EVT_F_TRANS_FORBIDDEN",
415      [SMMU_EVT_C_BAD_SUBSTREAMID]        = "SMMU_EVT_C_BAD_SUBSTREAMID",
416      [SMMU_EVT_F_CD_FETCH]               = "SMMU_EVT_F_CD_FETCH",
417      [SMMU_EVT_C_BAD_CD]                 = "SMMU_EVT_C_BAD_CD",
418      [SMMU_EVT_F_WALK_EABT]              = "SMMU_EVT_F_WALK_EABT",
419      [SMMU_EVT_F_TRANSLATION]            = "SMMU_EVT_F_TRANSLATION",
420      [SMMU_EVT_F_ADDR_SIZE]              = "SMMU_EVT_F_ADDR_SIZE",
421      [SMMU_EVT_F_ACCESS]                 = "SMMU_EVT_F_ACCESS",
422      [SMMU_EVT_F_PERMISSION]             = "SMMU_EVT_F_PERMISSION",
423      [SMMU_EVT_F_TLB_CONFLICT]           = "SMMU_EVT_F_TLB_CONFLICT",
424      [SMMU_EVT_F_CFG_CONFLICT]           = "SMMU_EVT_F_CFG_CONFLICT",
425      [SMMU_EVT_E_PAGE_REQ]               = "SMMU_EVT_E_PAGE_REQ",
426  };
427  
smmu_event_string(SMMUEventType type)428  static inline const char *smmu_event_string(SMMUEventType type)
429  {
430      if (type < ARRAY_SIZE(event_stringify)) {
431          return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
432      } else {
433          return "INVALID";
434      }
435  }
436  
437  /*  Encode an event record */
438  typedef struct SMMUEventInfo {
439      SMMUEventType type;
440      uint32_t sid;
441      bool recorded;
442      bool inval_ste_allowed;
443      union {
444          struct {
445              uint32_t ssid;
446              bool ssv;
447              dma_addr_t addr;
448              bool rnw;
449              bool pnu;
450              bool ind;
451         } f_uut;
452         struct SSIDInfo {
453              uint32_t ssid;
454              bool ssv;
455         } c_bad_streamid;
456         struct SSIDAddrInfo {
457              uint32_t ssid;
458              bool ssv;
459              dma_addr_t addr;
460         } f_ste_fetch;
461         struct SSIDInfo c_bad_ste;
462         struct {
463              dma_addr_t addr;
464              bool rnw;
465         } f_transl_forbidden;
466         struct {
467              uint32_t ssid;
468         } c_bad_substream;
469         struct SSIDAddrInfo f_cd_fetch;
470         struct SSIDInfo c_bad_cd;
471         struct FullInfo {
472              bool stall;
473              uint16_t stag;
474              uint32_t ssid;
475              bool ssv;
476              bool s2;
477              dma_addr_t addr;
478              bool rnw;
479              bool pnu;
480              bool ind;
481              uint8_t class;
482              dma_addr_t addr2;
483         } f_walk_eabt;
484         struct FullInfo f_translation;
485         struct FullInfo f_addr_size;
486         struct FullInfo f_access;
487         struct FullInfo f_permission;
488         struct SSIDInfo f_cfg_conflict;
489         /**
490          * not supported yet:
491          * F_BAD_ATS_TREQ
492          * F_BAD_ATS_TREQ
493          * F_TLB_CONFLICT
494          * E_PAGE_REQUEST
495          * IMPDEF_EVENTn
496          */
497      } u;
498  } SMMUEventInfo;
499  
500  /* EVTQ fields */
501  
502  #define EVT_Q_OVERFLOW        (1 << 31)
503  
504  #define EVT_SET_TYPE(x, v)  ((x)->word[0] = deposit32((x)->word[0], 0 , 8 , v))
505  #define EVT_SET_SSV(x, v)   ((x)->word[0] = deposit32((x)->word[0], 11, 1 , v))
506  #define EVT_SET_SSID(x, v)  ((x)->word[0] = deposit32((x)->word[0], 12, 20, v))
507  #define EVT_SET_SID(x, v)   ((x)->word[1] = v)
508  #define EVT_SET_STAG(x, v)  ((x)->word[2] = deposit32((x)->word[2], 0 , 16, v))
509  #define EVT_SET_STALL(x, v) ((x)->word[2] = deposit32((x)->word[2], 31, 1 , v))
510  #define EVT_SET_PNU(x, v)   ((x)->word[3] = deposit32((x)->word[3], 1 , 1 , v))
511  #define EVT_SET_IND(x, v)   ((x)->word[3] = deposit32((x)->word[3], 2 , 1 , v))
512  #define EVT_SET_RNW(x, v)   ((x)->word[3] = deposit32((x)->word[3], 3 , 1 , v))
513  #define EVT_SET_S2(x, v)    ((x)->word[3] = deposit32((x)->word[3], 7 , 1 , v))
514  #define EVT_SET_CLASS(x, v) ((x)->word[3] = deposit32((x)->word[3], 8 , 2 , v))
515  #define EVT_SET_ADDR(x, addr)                             \
516      do {                                                  \
517              (x)->word[5] = (uint32_t)(addr >> 32);        \
518              (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
519      } while (0)
520  #define EVT_SET_ADDR2(x, addr)                            \
521      do {                                                  \
522              (x)->word[7] = (uint32_t)(addr >> 32);        \
523              (x)->word[6] = (uint32_t)(addr & 0xffffffff); \
524      } while (0)
525  
526  void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
527  
528  /* Configuration Data */
529  
530  /* STE Level 1 Descriptor */
531  typedef struct STEDesc {
532      uint32_t word[2];
533  } STEDesc;
534  
535  /* CD Level 1 Descriptor */
536  typedef struct CDDesc {
537      uint32_t word[2];
538  } CDDesc;
539  
540  /* Stream Table Entry(STE) */
541  typedef struct STE {
542      uint32_t word[16];
543  } STE;
544  
545  /* Context Descriptor(CD) */
546  typedef struct CD {
547      uint32_t word[16];
548  } CD;
549  
550  /* STE fields */
551  
552  #define STE_VALID(x)   extract32((x)->word[0], 0, 1)
553  
554  #define STE_CONFIG(x)  extract32((x)->word[0], 1, 3)
555  #define STE_CFG_S1_ENABLED(config) (config & 0x1)
556  #define STE_CFG_S2_ENABLED(config) (config & 0x2)
557  #define STE_CFG_ABORT(config)      (!(config & 0x4))
558  #define STE_CFG_BYPASS(config)     (config == 0x4)
559  
560  #define STE_S1FMT(x)       extract32((x)->word[0], 4 , 2)
561  #define STE_S1CDMAX(x)     extract32((x)->word[1], 27, 5)
562  #define STE_S1STALLD(x)    extract32((x)->word[2], 27, 1)
563  #define STE_EATS(x)        extract32((x)->word[2], 28, 2)
564  #define STE_STRW(x)        extract32((x)->word[2], 30, 2)
565  #define STE_S2VMID(x)      extract32((x)->word[4], 0 , 16)
566  #define STE_S2T0SZ(x)      extract32((x)->word[5], 0 , 6)
567  #define STE_S2SL0(x)       extract32((x)->word[5], 6 , 2)
568  #define STE_S2TG(x)        extract32((x)->word[5], 14, 2)
569  #define STE_S2PS(x)        extract32((x)->word[5], 16, 3)
570  #define STE_S2AA64(x)      extract32((x)->word[5], 19, 1)
571  #define STE_S2ENDI(x)      extract32((x)->word[5], 20, 1)
572  #define STE_S2AFFD(x)      extract32((x)->word[5], 21, 1)
573  #define STE_S2HD(x)        extract32((x)->word[5], 23, 1)
574  #define STE_S2HA(x)        extract32((x)->word[5], 24, 1)
575  #define STE_S2S(x)         extract32((x)->word[5], 25, 1)
576  #define STE_S2R(x)         extract32((x)->word[5], 26, 1)
577  
578  #define STE_CTXPTR(x)                                   \
579      ((extract64((x)->word[1], 0, 16) << 32) |           \
580       ((x)->word[0] & 0xffffffc0))
581  
582  #define STE_S2TTB(x)                                    \
583      ((extract64((x)->word[7], 0, 16) << 32) |           \
584       ((x)->word[6] & 0xfffffff0))
585  
oas2bits(int oas_field)586  static inline int oas2bits(int oas_field)
587  {
588      switch (oas_field) {
589      case 0:
590          return 32;
591      case 1:
592          return 36;
593      case 2:
594          return 40;
595      case 3:
596          return 42;
597      case 4:
598          return 44;
599      case 5:
600          return 48;
601      }
602  
603      g_assert_not_reached();
604  }
605  
606  /* CD fields */
607  
608  #define CD_VALID(x)   extract32((x)->word[0], 31, 1)
609  #define CD_ASID(x)    extract32((x)->word[1], 16, 16)
610  #define CD_TTB(x, sel)                                          \
611      ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) |       \
612       ((x)->word[(sel) * 2 + 2] & ~0xfULL))
613  
614  #define CD_HAD(x, sel)   extract32((x)->word[(sel) * 2 + 2], 1, 1)
615  
616  #define CD_TSZ(x, sel)   extract32((x)->word[0], (16 * (sel)) + 0, 6)
617  #define CD_TG(x, sel)    extract32((x)->word[0], (16 * (sel)) + 6, 2)
618  #define CD_EPD(x, sel)   extract32((x)->word[0], (16 * (sel)) + 14, 1)
619  #define CD_ENDI(x)       extract32((x)->word[0], 15, 1)
620  #define CD_IPS(x)        extract32((x)->word[1], 0 , 3)
621  #define CD_AFFD(x)       extract32((x)->word[1], 3 , 1)
622  #define CD_TBI(x)        extract32((x)->word[1], 6 , 2)
623  #define CD_HD(x)         extract32((x)->word[1], 10 , 1)
624  #define CD_HA(x)         extract32((x)->word[1], 11 , 1)
625  #define CD_S(x)          extract32((x)->word[1], 12, 1)
626  #define CD_R(x)          extract32((x)->word[1], 13, 1)
627  #define CD_A(x)          extract32((x)->word[1], 14, 1)
628  #define CD_AARCH64(x)    extract32((x)->word[1], 9 , 1)
629  
630  /**
631   * tg2granule - Decodes the CD translation granule size field according
632   * to the ttbr in use
633   * @bits: TG0/1 fields
634   * @ttbr: ttbr index in use
635   */
tg2granule(int bits,int ttbr)636  static inline int tg2granule(int bits, int ttbr)
637  {
638      switch (bits) {
639      case 0:
640          return ttbr ? 0  : 12;
641      case 1:
642          return ttbr ? 14 : 16;
643      case 2:
644          return ttbr ? 12 : 14;
645      case 3:
646          return ttbr ? 16 :  0;
647      default:
648          return 0;
649      }
650  }
651  
l1std_l2ptr(STEDesc * desc)652  static inline uint64_t l1std_l2ptr(STEDesc *desc)
653  {
654      uint64_t hi, lo;
655  
656      hi = desc->word[1];
657      lo = desc->word[0] & ~0x1fULL;
658      return hi << 32 | lo;
659  }
660  
661  #define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
662  
663  #endif
664