xref: /qemu/hw/arm/smmuv3-internal.h (revision 8deba2f3)
110a83cb9SPrem Mallappa /*
210a83cb9SPrem Mallappa  * ARM SMMUv3 support - Internal API
310a83cb9SPrem Mallappa  *
410a83cb9SPrem Mallappa  * Copyright (C) 2014-2016 Broadcom Corporation
510a83cb9SPrem Mallappa  * Copyright (c) 2017 Red Hat, Inc.
610a83cb9SPrem Mallappa  * Written by Prem Mallappa, Eric Auger
710a83cb9SPrem Mallappa  *
810a83cb9SPrem Mallappa  * This program is free software; you can redistribute it and/or modify
910a83cb9SPrem Mallappa  * it under the terms of the GNU General Public License version 2 as
1010a83cb9SPrem Mallappa  * published by the Free Software Foundation.
1110a83cb9SPrem Mallappa  *
1210a83cb9SPrem Mallappa  * This program is distributed in the hope that it will be useful,
1310a83cb9SPrem Mallappa  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1410a83cb9SPrem Mallappa  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1510a83cb9SPrem Mallappa  * GNU General Public License for more details.
1610a83cb9SPrem Mallappa  *
1710a83cb9SPrem Mallappa  * You should have received a copy of the GNU General Public License along
1810a83cb9SPrem Mallappa  * with this program; if not, see <http://www.gnu.org/licenses/>.
1910a83cb9SPrem Mallappa  */
2010a83cb9SPrem Mallappa 
2158ea30f5SMarkus Armbruster #ifndef HW_ARM_SMMUV3_INTERNAL_H
2258ea30f5SMarkus Armbruster #define HW_ARM_SMMUV3_INTERNAL_H
2310a83cb9SPrem Mallappa 
247b31c2dbSPhilippe Mathieu-Daudé #include "hw/registerfields.h"
2510a83cb9SPrem Mallappa #include "hw/arm/smmu-common.h"
2610a83cb9SPrem Mallappa 
279122bea9SJia He typedef enum SMMUTranslationStatus {
289122bea9SJia He     SMMU_TRANS_DISABLE,
299122bea9SJia He     SMMU_TRANS_ABORT,
309122bea9SJia He     SMMU_TRANS_BYPASS,
319122bea9SJia He     SMMU_TRANS_ERROR,
329122bea9SJia He     SMMU_TRANS_SUCCESS,
339122bea9SJia He } SMMUTranslationStatus;
349122bea9SJia He 
352731ea04SMostafa Saleh typedef enum SMMUTranslationClass {
362731ea04SMostafa Saleh     SMMU_CLASS_CD,
372731ea04SMostafa Saleh     SMMU_CLASS_TT,
382731ea04SMostafa Saleh     SMMU_CLASS_IN,
392731ea04SMostafa Saleh } SMMUTranslationClass;
402731ea04SMostafa Saleh 
4110a83cb9SPrem Mallappa /* MMIO Registers */
4210a83cb9SPrem Mallappa 
4310a83cb9SPrem Mallappa REG32(IDR0,                0x0)
44263d0e48SMostafa Saleh     FIELD(IDR0, S2P,         0 , 1)
4510a83cb9SPrem Mallappa     FIELD(IDR0, S1P,         1 , 1)
4610a83cb9SPrem Mallappa     FIELD(IDR0, TTF,         2 , 2)
4710a83cb9SPrem Mallappa     FIELD(IDR0, COHACC,      4 , 1)
48cbaf9404SPeter Maydell     FIELD(IDR0, BTM,         5 , 1)
49cbaf9404SPeter Maydell     FIELD(IDR0, HTTU,        6 , 2)
50cbaf9404SPeter Maydell     FIELD(IDR0, DORMHINT,    8 , 1)
51cbaf9404SPeter Maydell     FIELD(IDR0, HYP,         9 , 1)
52cbaf9404SPeter Maydell     FIELD(IDR0, ATS,         10, 1)
53cbaf9404SPeter Maydell     FIELD(IDR0, NS1ATS,      11, 1)
5410a83cb9SPrem Mallappa     FIELD(IDR0, ASID16,      12, 1)
55cbaf9404SPeter Maydell     FIELD(IDR0, MSI,         13, 1)
56cbaf9404SPeter Maydell     FIELD(IDR0, SEV,         14, 1)
57cbaf9404SPeter Maydell     FIELD(IDR0, ATOS,        15, 1)
58cbaf9404SPeter Maydell     FIELD(IDR0, PRI,         16, 1)
59cbaf9404SPeter Maydell     FIELD(IDR0, VMW,         17, 1)
60263d0e48SMostafa Saleh     FIELD(IDR0, VMID16,      18, 1)
61cbaf9404SPeter Maydell     FIELD(IDR0, CD2L,        19, 1)
62cbaf9404SPeter Maydell     FIELD(IDR0, VATOS,       20, 1)
6310a83cb9SPrem Mallappa     FIELD(IDR0, TTENDIAN,    21, 2)
64cbaf9404SPeter Maydell     FIELD(IDR0, ATSRECERR,   23, 1)
6510a83cb9SPrem Mallappa     FIELD(IDR0, STALL_MODEL, 24, 2)
6610a83cb9SPrem Mallappa     FIELD(IDR0, TERM_MODEL,  26, 1)
6710a83cb9SPrem Mallappa     FIELD(IDR0, STLEVEL,     27, 2)
68cbaf9404SPeter Maydell     FIELD(IDR0, RME_IMPL,    30, 1)
6910a83cb9SPrem Mallappa 
7010a83cb9SPrem Mallappa REG32(IDR1,                0x4)
7110a83cb9SPrem Mallappa     FIELD(IDR1, SIDSIZE,      0 , 6)
72cbaf9404SPeter Maydell     FIELD(IDR1, SSIDSIZE,     6 , 5)
73cbaf9404SPeter Maydell     FIELD(IDR1, PRIQS,        11, 5)
7410a83cb9SPrem Mallappa     FIELD(IDR1, EVENTQS,      16, 5)
7510a83cb9SPrem Mallappa     FIELD(IDR1, CMDQS,        21, 5)
76cbaf9404SPeter Maydell     FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
77cbaf9404SPeter Maydell     FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
78cbaf9404SPeter Maydell     FIELD(IDR1, REL,          28, 1)
79cbaf9404SPeter Maydell     FIELD(IDR1, QUEUES_PRESET, 29, 1)
80cbaf9404SPeter Maydell     FIELD(IDR1, TABLES_PRESET, 30, 1)
81cbaf9404SPeter Maydell     FIELD(IDR1, ECMDQ,        31, 1)
8210a83cb9SPrem Mallappa 
8310a83cb9SPrem Mallappa #define SMMU_IDR1_SIDSIZE 16
8410a83cb9SPrem Mallappa #define SMMU_CMDQS   19
8510a83cb9SPrem Mallappa #define SMMU_EVENTQS 19
8610a83cb9SPrem Mallappa 
8710a83cb9SPrem Mallappa REG32(IDR2,                0x8)
88cbaf9404SPeter Maydell      FIELD(IDR2, BA_VATOS, 0, 10)
89cbaf9404SPeter Maydell 
9010a83cb9SPrem Mallappa REG32(IDR3,                0xc)
91e7c3b9d9SEric Auger      FIELD(IDR3, HAD,         2, 1);
92cbaf9404SPeter Maydell      FIELD(IDR3, PBHA,        3, 1);
93cbaf9404SPeter Maydell      FIELD(IDR3, XNX,         4, 1);
94cbaf9404SPeter Maydell      FIELD(IDR3, PPS,         5, 1);
95cbaf9404SPeter Maydell      FIELD(IDR3, MPAM,        7, 1);
96cbaf9404SPeter Maydell      FIELD(IDR3, FWB,         8, 1);
97cbaf9404SPeter Maydell      FIELD(IDR3, STT,         9, 1);
98de206dfdSEric Auger      FIELD(IDR3, RIL,        10, 1);
99f8e7163dSPeter Maydell      FIELD(IDR3, BBML,       11, 2);
100cbaf9404SPeter Maydell      FIELD(IDR3, E0PD,       13, 1);
101cbaf9404SPeter Maydell      FIELD(IDR3, PTWNNC,     14, 1);
102cbaf9404SPeter Maydell      FIELD(IDR3, DPT,        15, 1);
103cbaf9404SPeter Maydell 
10410a83cb9SPrem Mallappa REG32(IDR4,                0x10)
105cbaf9404SPeter Maydell 
10610a83cb9SPrem Mallappa REG32(IDR5,                0x14)
10710a83cb9SPrem Mallappa      FIELD(IDR5, OAS,         0, 3);
10810a83cb9SPrem Mallappa      FIELD(IDR5, GRAN4K,      4, 1);
10910a83cb9SPrem Mallappa      FIELD(IDR5, GRAN16K,     5, 1);
11010a83cb9SPrem Mallappa      FIELD(IDR5, GRAN64K,     6, 1);
111cbaf9404SPeter Maydell      FIELD(IDR5, VAX,        10, 2);
112cbaf9404SPeter Maydell      FIELD(IDR5, STALL_MAX,  16, 16);
11310a83cb9SPrem Mallappa 
11410a83cb9SPrem Mallappa #define SMMU_IDR5_OAS 4
11510a83cb9SPrem Mallappa 
116f0ec277cSEric Auger REG32(IIDR,                0x18)
1175888f0adSEric Auger REG32(AIDR,                0x1c)
11810a83cb9SPrem Mallappa REG32(CR0,                 0x20)
11910a83cb9SPrem Mallappa     FIELD(CR0, SMMU_ENABLE,   0, 1)
12010a83cb9SPrem Mallappa     FIELD(CR0, EVENTQEN,      2, 1)
12110a83cb9SPrem Mallappa     FIELD(CR0, CMDQEN,        3, 1)
12210a83cb9SPrem Mallappa 
123fae4be38SEric Auger #define SMMU_CR0_RESERVED 0xFFFFFC20
124fae4be38SEric Auger 
12510a83cb9SPrem Mallappa REG32(CR0ACK,              0x24)
12610a83cb9SPrem Mallappa REG32(CR1,                 0x28)
12710a83cb9SPrem Mallappa REG32(CR2,                 0x2c)
12810a83cb9SPrem Mallappa REG32(STATUSR,             0x40)
129c2ecb424SMostafa Saleh REG32(GBPA,                0x44)
130c2ecb424SMostafa Saleh     FIELD(GBPA, ABORT,        20, 1)
131c2ecb424SMostafa Saleh     FIELD(GBPA, UPDATE,       31, 1)
132c2ecb424SMostafa Saleh 
133c2ecb424SMostafa Saleh /* Use incoming. */
134c2ecb424SMostafa Saleh #define SMMU_GBPA_RESET_VAL 0x1000
135c2ecb424SMostafa Saleh 
13610a83cb9SPrem Mallappa REG32(IRQ_CTRL,            0x50)
13710a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, GERROR_IRQEN,        0, 1)
13810a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, PRI_IRQEN,           1, 1)
13910a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, EVENTQ_IRQEN,        2, 1)
14010a83cb9SPrem Mallappa 
14110a83cb9SPrem Mallappa REG32(IRQ_CTRL_ACK,        0x54)
14210a83cb9SPrem Mallappa REG32(GERROR,              0x60)
14310a83cb9SPrem Mallappa     FIELD(GERROR, CMDQ_ERR,           0, 1)
14410a83cb9SPrem Mallappa     FIELD(GERROR, EVENTQ_ABT_ERR,     2, 1)
14510a83cb9SPrem Mallappa     FIELD(GERROR, PRIQ_ABT_ERR,       3, 1)
14610a83cb9SPrem Mallappa     FIELD(GERROR, MSI_CMDQ_ABT_ERR,   4, 1)
14710a83cb9SPrem Mallappa     FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
14810a83cb9SPrem Mallappa     FIELD(GERROR, MSI_PRIQ_ABT_ERR,   6, 1)
14910a83cb9SPrem Mallappa     FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
15010a83cb9SPrem Mallappa     FIELD(GERROR, MSI_SFM_ERR,        8, 1)
15110a83cb9SPrem Mallappa 
15210a83cb9SPrem Mallappa REG32(GERRORN,             0x64)
15310a83cb9SPrem Mallappa 
15410a83cb9SPrem Mallappa #define A_GERROR_IRQ_CFG0  0x68 /* 64b */
15510a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG1, 0x70)
15610a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG2, 0x74)
15710a83cb9SPrem Mallappa 
15810a83cb9SPrem Mallappa #define A_STRTAB_BASE      0x80 /* 64b */
15910a83cb9SPrem Mallappa 
1603293b9f5SSimon Veith #define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
16110a83cb9SPrem Mallappa 
16210a83cb9SPrem Mallappa REG32(STRTAB_BASE_CFG,     0x88)
16310a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, FMT,      16, 2)
16410a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, SPLIT,    6 , 5)
16510a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
16610a83cb9SPrem Mallappa 
16710a83cb9SPrem Mallappa #define A_CMDQ_BASE        0x90 /* 64b */
16810a83cb9SPrem Mallappa REG32(CMDQ_PROD,           0x98)
16910a83cb9SPrem Mallappa REG32(CMDQ_CONS,           0x9c)
17010a83cb9SPrem Mallappa     FIELD(CMDQ_CONS, ERR, 24, 7)
17110a83cb9SPrem Mallappa 
17210a83cb9SPrem Mallappa #define A_EVENTQ_BASE      0xa0 /* 64b */
17310a83cb9SPrem Mallappa REG32(EVENTQ_PROD,         0xa8)
17410a83cb9SPrem Mallappa REG32(EVENTQ_CONS,         0xac)
17510a83cb9SPrem Mallappa 
17610a83cb9SPrem Mallappa #define A_EVENTQ_IRQ_CFG0  0xb0 /* 64b */
17710a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG1,     0xb8)
17810a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG2,     0xbc)
17910a83cb9SPrem Mallappa 
18010a83cb9SPrem Mallappa #define A_IDREGS           0xfd0
18110a83cb9SPrem Mallappa 
smmu_enabled(SMMUv3State * s)18210a83cb9SPrem Mallappa static inline int smmu_enabled(SMMUv3State *s)
18310a83cb9SPrem Mallappa {
18410a83cb9SPrem Mallappa     return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
18510a83cb9SPrem Mallappa }
18610a83cb9SPrem Mallappa 
18710a83cb9SPrem Mallappa /* Command Queue Entry */
18810a83cb9SPrem Mallappa typedef struct Cmd {
18910a83cb9SPrem Mallappa     uint32_t word[4];
19010a83cb9SPrem Mallappa } Cmd;
19110a83cb9SPrem Mallappa 
19210a83cb9SPrem Mallappa /* Event Queue Entry */
19310a83cb9SPrem Mallappa typedef struct Evt  {
19410a83cb9SPrem Mallappa     uint32_t word[8];
19510a83cb9SPrem Mallappa } Evt;
19610a83cb9SPrem Mallappa 
smmuv3_idreg(int regoffset)19710a83cb9SPrem Mallappa static inline uint32_t smmuv3_idreg(int regoffset)
19810a83cb9SPrem Mallappa {
19910a83cb9SPrem Mallappa     /*
20010a83cb9SPrem Mallappa      * Return the value of the Primecell/Corelink ID registers at the
20110a83cb9SPrem Mallappa      * specified offset from the first ID register.
20210a83cb9SPrem Mallappa      * These value indicate an ARM implementation of MMU600 p1
20310a83cb9SPrem Mallappa      */
20410a83cb9SPrem Mallappa     static const uint8_t smmuv3_ids[] = {
20510a83cb9SPrem Mallappa         0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
20610a83cb9SPrem Mallappa     };
20710a83cb9SPrem Mallappa     return smmuv3_ids[regoffset / 4];
20810a83cb9SPrem Mallappa }
20910a83cb9SPrem Mallappa 
smmuv3_eventq_irq_enabled(SMMUv3State * s)2106a736033SEric Auger static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
2116a736033SEric Auger {
2126a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
2136a736033SEric Auger }
2146a736033SEric Auger 
smmuv3_gerror_irq_enabled(SMMUv3State * s)2156a736033SEric Auger static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
2166a736033SEric Auger {
2176a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
2186a736033SEric Auger }
2196a736033SEric Auger 
220dadd1a08SEric Auger /* Queue Handling */
221dadd1a08SEric Auger 
222dadd1a08SEric Auger #define Q_BASE(q)          ((q)->base & SMMU_BASE_ADDR_MASK)
223dadd1a08SEric Auger #define WRAP_MASK(q)       (1 << (q)->log2size)
224dadd1a08SEric Auger #define INDEX_MASK(q)      (((1 << (q)->log2size)) - 1)
225dadd1a08SEric Auger #define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
226dadd1a08SEric Auger 
227dadd1a08SEric Auger #define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
228dadd1a08SEric Auger #define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
229dadd1a08SEric Auger 
230dadd1a08SEric Auger #define Q_CONS_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
231dadd1a08SEric Auger #define Q_PROD_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
232dadd1a08SEric Auger 
233dadd1a08SEric Auger #define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
234dadd1a08SEric Auger #define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
235dadd1a08SEric Auger 
smmuv3_q_full(SMMUQueue * q)236dadd1a08SEric Auger static inline bool smmuv3_q_full(SMMUQueue *q)
237dadd1a08SEric Auger {
238dadd1a08SEric Auger     return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
239dadd1a08SEric Auger }
240dadd1a08SEric Auger 
smmuv3_q_empty(SMMUQueue * q)241dadd1a08SEric Auger static inline bool smmuv3_q_empty(SMMUQueue *q)
242dadd1a08SEric Auger {
243dadd1a08SEric Auger     return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
244dadd1a08SEric Auger }
245dadd1a08SEric Auger 
queue_prod_incr(SMMUQueue * q)246dadd1a08SEric Auger static inline void queue_prod_incr(SMMUQueue *q)
247dadd1a08SEric Auger {
248dadd1a08SEric Auger     q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
249dadd1a08SEric Auger }
250dadd1a08SEric Auger 
queue_cons_incr(SMMUQueue * q)251dadd1a08SEric Auger static inline void queue_cons_incr(SMMUQueue *q)
252dadd1a08SEric Auger {
253dadd1a08SEric Auger     /*
254dadd1a08SEric Auger      * We have to use deposit for the CONS registers to preserve
255dadd1a08SEric Auger      * the ERR field in the high bits.
256dadd1a08SEric Auger      */
257dadd1a08SEric Auger     q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
258dadd1a08SEric Auger }
259dadd1a08SEric Auger 
smmuv3_cmdq_enabled(SMMUv3State * s)260dadd1a08SEric Auger static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
261dadd1a08SEric Auger {
262dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, CMDQEN);
263dadd1a08SEric Auger }
264dadd1a08SEric Auger 
smmuv3_eventq_enabled(SMMUv3State * s)265dadd1a08SEric Auger static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
266dadd1a08SEric Auger {
267dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
268dadd1a08SEric Auger }
269dadd1a08SEric Auger 
smmu_write_cmdq_err(SMMUv3State * s,uint32_t err_type)270dadd1a08SEric Auger static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
271dadd1a08SEric Auger {
272dadd1a08SEric Auger     s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
273dadd1a08SEric Auger }
274dadd1a08SEric Auger 
275dadd1a08SEric Auger /* Commands */
276dadd1a08SEric Auger 
277dadd1a08SEric Auger typedef enum SMMUCommandType {
278dadd1a08SEric Auger     SMMU_CMD_NONE            = 0x00,
279dadd1a08SEric Auger     SMMU_CMD_PREFETCH_CONFIG       ,
280dadd1a08SEric Auger     SMMU_CMD_PREFETCH_ADDR,
281dadd1a08SEric Auger     SMMU_CMD_CFGI_STE,
282dadd1a08SEric Auger     SMMU_CMD_CFGI_STE_RANGE,
283dadd1a08SEric Auger     SMMU_CMD_CFGI_CD,
284dadd1a08SEric Auger     SMMU_CMD_CFGI_CD_ALL,
285dadd1a08SEric Auger     SMMU_CMD_CFGI_ALL,
286dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ALL     = 0x10,
287dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ASID,
288dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VA,
289dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VAA,
290dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_ALL    = 0x18,
291dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_VA     = 0x1a,
292dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ALL    = 0x20,
293dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ASID,
294dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VA,
295dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VAA,
296dadd1a08SEric Auger     SMMU_CMD_TLBI_S12_VMALL  = 0x28,
297dadd1a08SEric Auger     SMMU_CMD_TLBI_S2_IPA     = 0x2a,
298dadd1a08SEric Auger     SMMU_CMD_TLBI_NSNH_ALL   = 0x30,
299dadd1a08SEric Auger     SMMU_CMD_ATC_INV         = 0x40,
300dadd1a08SEric Auger     SMMU_CMD_PRI_RESP,
301dadd1a08SEric Auger     SMMU_CMD_RESUME          = 0x44,
302dadd1a08SEric Auger     SMMU_CMD_STALL_TERM,
303dadd1a08SEric Auger     SMMU_CMD_SYNC,
304dadd1a08SEric Auger } SMMUCommandType;
305dadd1a08SEric Auger 
306dadd1a08SEric Auger static const char *cmd_stringify[] = {
307dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
308dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_ADDR]   = "SMMU_CMD_PREFETCH_ADDR",
309dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE]        = "SMMU_CMD_CFGI_STE",
310dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE_RANGE]  = "SMMU_CMD_CFGI_STE_RANGE",
311dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD]         = "SMMU_CMD_CFGI_CD",
312dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD_ALL]     = "SMMU_CMD_CFGI_CD_ALL",
313dadd1a08SEric Auger     [SMMU_CMD_CFGI_ALL]        = "SMMU_CMD_CFGI_ALL",
314dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ALL]     = "SMMU_CMD_TLBI_NH_ALL",
315dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ASID]    = "SMMU_CMD_TLBI_NH_ASID",
316dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VA]      = "SMMU_CMD_TLBI_NH_VA",
317dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VAA]     = "SMMU_CMD_TLBI_NH_VAA",
318dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_ALL]    = "SMMU_CMD_TLBI_EL3_ALL",
319dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_VA]     = "SMMU_CMD_TLBI_EL3_VA",
320dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ALL]    = "SMMU_CMD_TLBI_EL2_ALL",
321dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ASID]   = "SMMU_CMD_TLBI_EL2_ASID",
322dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VA]     = "SMMU_CMD_TLBI_EL2_VA",
323dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VAA]    = "SMMU_CMD_TLBI_EL2_VAA",
324dadd1a08SEric Auger     [SMMU_CMD_TLBI_S12_VMALL]  = "SMMU_CMD_TLBI_S12_VMALL",
325dadd1a08SEric Auger     [SMMU_CMD_TLBI_S2_IPA]     = "SMMU_CMD_TLBI_S2_IPA",
326dadd1a08SEric Auger     [SMMU_CMD_TLBI_NSNH_ALL]   = "SMMU_CMD_TLBI_NSNH_ALL",
327dadd1a08SEric Auger     [SMMU_CMD_ATC_INV]         = "SMMU_CMD_ATC_INV",
328dadd1a08SEric Auger     [SMMU_CMD_PRI_RESP]        = "SMMU_CMD_PRI_RESP",
329dadd1a08SEric Auger     [SMMU_CMD_RESUME]          = "SMMU_CMD_RESUME",
330dadd1a08SEric Auger     [SMMU_CMD_STALL_TERM]      = "SMMU_CMD_STALL_TERM",
331dadd1a08SEric Auger     [SMMU_CMD_SYNC]            = "SMMU_CMD_SYNC",
332dadd1a08SEric Auger };
333dadd1a08SEric Auger 
smmu_cmd_string(SMMUCommandType type)334dadd1a08SEric Auger static inline const char *smmu_cmd_string(SMMUCommandType type)
335dadd1a08SEric Auger {
336dadd1a08SEric Auger     if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
337dadd1a08SEric Auger         return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
338dadd1a08SEric Auger     } else {
339dadd1a08SEric Auger         return "INVALID";
340dadd1a08SEric Auger     }
341dadd1a08SEric Auger }
342dadd1a08SEric Auger 
343dadd1a08SEric Auger /* CMDQ fields */
344dadd1a08SEric Auger 
345dadd1a08SEric Auger typedef enum {
346dadd1a08SEric Auger     SMMU_CERROR_NONE = 0,
347dadd1a08SEric Auger     SMMU_CERROR_ILL,
348dadd1a08SEric Auger     SMMU_CERROR_ABT,
349dadd1a08SEric Auger     SMMU_CERROR_ATC_INV_SYNC,
350dadd1a08SEric Auger } SMMUCmdError;
351dadd1a08SEric Auger 
352dadd1a08SEric Auger enum { /* Command completion notification */
353dadd1a08SEric Auger     CMD_SYNC_SIG_NONE,
354dadd1a08SEric Auger     CMD_SYNC_SIG_IRQ,
355dadd1a08SEric Auger     CMD_SYNC_SIG_SEV,
356dadd1a08SEric Auger };
357dadd1a08SEric Auger 
358dadd1a08SEric Auger #define CMD_TYPE(x)         extract32((x)->word[0], 0 , 8)
359d5291561SEric Auger #define CMD_NUM(x)          extract32((x)->word[0], 12 , 5)
360d5291561SEric Auger #define CMD_SCALE(x)        extract32((x)->word[0], 20 , 5)
361dadd1a08SEric Auger #define CMD_SSEC(x)         extract32((x)->word[0], 10, 1)
362dadd1a08SEric Auger #define CMD_SSV(x)          extract32((x)->word[0], 11, 1)
363dadd1a08SEric Auger #define CMD_RESUME_AC(x)    extract32((x)->word[0], 12, 1)
364dadd1a08SEric Auger #define CMD_RESUME_AB(x)    extract32((x)->word[0], 13, 1)
365dadd1a08SEric Auger #define CMD_SYNC_CS(x)      extract32((x)->word[0], 12, 2)
366dadd1a08SEric Auger #define CMD_SSID(x)         extract32((x)->word[0], 12, 20)
367dadd1a08SEric Auger #define CMD_SID(x)          ((x)->word[1])
368dadd1a08SEric Auger #define CMD_VMID(x)         extract32((x)->word[1], 0 , 16)
369dadd1a08SEric Auger #define CMD_ASID(x)         extract32((x)->word[1], 16, 16)
370dadd1a08SEric Auger #define CMD_RESUME_STAG(x)  extract32((x)->word[2], 0 , 16)
371dadd1a08SEric Auger #define CMD_RESP(x)         extract32((x)->word[2], 11, 2)
372dadd1a08SEric Auger #define CMD_LEAF(x)         extract32((x)->word[2], 0 , 1)
373d5291561SEric Auger #define CMD_TTL(x)          extract32((x)->word[2], 8 , 2)
374d5291561SEric Auger #define CMD_TG(x)           extract32((x)->word[2], 10, 2)
375dadd1a08SEric Auger #define CMD_STE_RANGE(x)    extract32((x)->word[2], 0 , 5)
37684abccddSPeter Maydell #define CMD_ADDR(x)                             \
37784abccddSPeter Maydell     (((uint64_t)((x)->word[3]) << 32) |         \
37884abccddSPeter Maydell      ((extract64((x)->word[2], 12, 20)) << 12))
379dadd1a08SEric Auger 
380fae4be38SEric Auger #define SMMU_FEATURE_2LVL_STE (1 << 0)
381dadd1a08SEric Auger 
382bb981004SEric Auger /* Events */
383bb981004SEric Auger 
384bb981004SEric Auger typedef enum SMMUEventType {
3859122bea9SJia He     SMMU_EVT_NONE               = 0x00,
386bb981004SEric Auger     SMMU_EVT_F_UUT                    ,
387bb981004SEric Auger     SMMU_EVT_C_BAD_STREAMID           ,
388bb981004SEric Auger     SMMU_EVT_F_STE_FETCH              ,
389bb981004SEric Auger     SMMU_EVT_C_BAD_STE                ,
390bb981004SEric Auger     SMMU_EVT_F_BAD_ATS_TREQ           ,
391bb981004SEric Auger     SMMU_EVT_F_STREAM_DISABLED        ,
392bb981004SEric Auger     SMMU_EVT_F_TRANS_FORBIDDEN        ,
393bb981004SEric Auger     SMMU_EVT_C_BAD_SUBSTREAMID        ,
394bb981004SEric Auger     SMMU_EVT_F_CD_FETCH               ,
395bb981004SEric Auger     SMMU_EVT_C_BAD_CD                 ,
396bb981004SEric Auger     SMMU_EVT_F_WALK_EABT              ,
397bb981004SEric Auger     SMMU_EVT_F_TRANSLATION      = 0x10,
398bb981004SEric Auger     SMMU_EVT_F_ADDR_SIZE              ,
399bb981004SEric Auger     SMMU_EVT_F_ACCESS                 ,
400bb981004SEric Auger     SMMU_EVT_F_PERMISSION             ,
401bb981004SEric Auger     SMMU_EVT_F_TLB_CONFLICT     = 0x20,
402bb981004SEric Auger     SMMU_EVT_F_CFG_CONFLICT           ,
403bb981004SEric Auger     SMMU_EVT_E_PAGE_REQ         = 0x24,
404bb981004SEric Auger } SMMUEventType;
405bb981004SEric Auger 
406bb981004SEric Auger static const char *event_stringify[] = {
4079122bea9SJia He     [SMMU_EVT_NONE]                     = "no recorded event",
408bb981004SEric Auger     [SMMU_EVT_F_UUT]                    = "SMMU_EVT_F_UUT",
409bb981004SEric Auger     [SMMU_EVT_C_BAD_STREAMID]           = "SMMU_EVT_C_BAD_STREAMID",
410bb981004SEric Auger     [SMMU_EVT_F_STE_FETCH]              = "SMMU_EVT_F_STE_FETCH",
411bb981004SEric Auger     [SMMU_EVT_C_BAD_STE]                = "SMMU_EVT_C_BAD_STE",
412bb981004SEric Auger     [SMMU_EVT_F_BAD_ATS_TREQ]           = "SMMU_EVT_F_BAD_ATS_TREQ",
413bb981004SEric Auger     [SMMU_EVT_F_STREAM_DISABLED]        = "SMMU_EVT_F_STREAM_DISABLED",
414bb981004SEric Auger     [SMMU_EVT_F_TRANS_FORBIDDEN]        = "SMMU_EVT_F_TRANS_FORBIDDEN",
415bb981004SEric Auger     [SMMU_EVT_C_BAD_SUBSTREAMID]        = "SMMU_EVT_C_BAD_SUBSTREAMID",
416bb981004SEric Auger     [SMMU_EVT_F_CD_FETCH]               = "SMMU_EVT_F_CD_FETCH",
417bb981004SEric Auger     [SMMU_EVT_C_BAD_CD]                 = "SMMU_EVT_C_BAD_CD",
418bb981004SEric Auger     [SMMU_EVT_F_WALK_EABT]              = "SMMU_EVT_F_WALK_EABT",
419bb981004SEric Auger     [SMMU_EVT_F_TRANSLATION]            = "SMMU_EVT_F_TRANSLATION",
420bb981004SEric Auger     [SMMU_EVT_F_ADDR_SIZE]              = "SMMU_EVT_F_ADDR_SIZE",
421bb981004SEric Auger     [SMMU_EVT_F_ACCESS]                 = "SMMU_EVT_F_ACCESS",
422bb981004SEric Auger     [SMMU_EVT_F_PERMISSION]             = "SMMU_EVT_F_PERMISSION",
423bb981004SEric Auger     [SMMU_EVT_F_TLB_CONFLICT]           = "SMMU_EVT_F_TLB_CONFLICT",
424bb981004SEric Auger     [SMMU_EVT_F_CFG_CONFLICT]           = "SMMU_EVT_F_CFG_CONFLICT",
425bb981004SEric Auger     [SMMU_EVT_E_PAGE_REQ]               = "SMMU_EVT_E_PAGE_REQ",
426bb981004SEric Auger };
427bb981004SEric Auger 
smmu_event_string(SMMUEventType type)428bb981004SEric Auger static inline const char *smmu_event_string(SMMUEventType type)
429bb981004SEric Auger {
430bb981004SEric Auger     if (type < ARRAY_SIZE(event_stringify)) {
431bb981004SEric Auger         return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
432bb981004SEric Auger     } else {
433bb981004SEric Auger         return "INVALID";
434bb981004SEric Auger     }
435bb981004SEric Auger }
436bb981004SEric Auger 
437bb981004SEric Auger /*  Encode an event record */
438bb981004SEric Auger typedef struct SMMUEventInfo {
439bb981004SEric Auger     SMMUEventType type;
440bb981004SEric Auger     uint32_t sid;
441bb981004SEric Auger     bool recorded;
4423499ec08SEric Auger     bool inval_ste_allowed;
443bb981004SEric Auger     union {
444bb981004SEric Auger         struct {
445bb981004SEric Auger             uint32_t ssid;
446bb981004SEric Auger             bool ssv;
447bb981004SEric Auger             dma_addr_t addr;
448bb981004SEric Auger             bool rnw;
449bb981004SEric Auger             bool pnu;
450bb981004SEric Auger             bool ind;
451bb981004SEric Auger        } f_uut;
452bb981004SEric Auger        struct SSIDInfo {
453bb981004SEric Auger             uint32_t ssid;
454bb981004SEric Auger             bool ssv;
455bb981004SEric Auger        } c_bad_streamid;
456bb981004SEric Auger        struct SSIDAddrInfo {
457bb981004SEric Auger             uint32_t ssid;
458bb981004SEric Auger             bool ssv;
459bb981004SEric Auger             dma_addr_t addr;
460bb981004SEric Auger        } f_ste_fetch;
461bb981004SEric Auger        struct SSIDInfo c_bad_ste;
462bb981004SEric Auger        struct {
463bb981004SEric Auger             dma_addr_t addr;
464bb981004SEric Auger             bool rnw;
465bb981004SEric Auger        } f_transl_forbidden;
466bb981004SEric Auger        struct {
467bb981004SEric Auger             uint32_t ssid;
468bb981004SEric Auger        } c_bad_substream;
469bb981004SEric Auger        struct SSIDAddrInfo f_cd_fetch;
470bb981004SEric Auger        struct SSIDInfo c_bad_cd;
471bb981004SEric Auger        struct FullInfo {
472bb981004SEric Auger             bool stall;
473bb981004SEric Auger             uint16_t stag;
474bb981004SEric Auger             uint32_t ssid;
475bb981004SEric Auger             bool ssv;
476bb981004SEric Auger             bool s2;
477bb981004SEric Auger             dma_addr_t addr;
478bb981004SEric Auger             bool rnw;
479bb981004SEric Auger             bool pnu;
480bb981004SEric Auger             bool ind;
481bb981004SEric Auger             uint8_t class;
482bb981004SEric Auger             dma_addr_t addr2;
483bb981004SEric Auger        } f_walk_eabt;
484bb981004SEric Auger        struct FullInfo f_translation;
485bb981004SEric Auger        struct FullInfo f_addr_size;
486bb981004SEric Auger        struct FullInfo f_access;
487bb981004SEric Auger        struct FullInfo f_permission;
488bb981004SEric Auger        struct SSIDInfo f_cfg_conflict;
489bb981004SEric Auger        /**
490bb981004SEric Auger         * not supported yet:
491bb981004SEric Auger         * F_BAD_ATS_TREQ
492bb981004SEric Auger         * F_BAD_ATS_TREQ
493bb981004SEric Auger         * F_TLB_CONFLICT
494bb981004SEric Auger         * E_PAGE_REQUEST
495bb981004SEric Auger         * IMPDEF_EVENTn
496bb981004SEric Auger         */
497bb981004SEric Auger     } u;
498bb981004SEric Auger } SMMUEventInfo;
499bb981004SEric Auger 
500bb981004SEric Auger /* EVTQ fields */
501bb981004SEric Auger 
502bb981004SEric Auger #define EVT_Q_OVERFLOW        (1 << 31)
503bb981004SEric Auger 
5049f4d2a13SEric Auger #define EVT_SET_TYPE(x, v)  ((x)->word[0] = deposit32((x)->word[0], 0 , 8 , v))
5059f4d2a13SEric Auger #define EVT_SET_SSV(x, v)   ((x)->word[0] = deposit32((x)->word[0], 11, 1 , v))
5069f4d2a13SEric Auger #define EVT_SET_SSID(x, v)  ((x)->word[0] = deposit32((x)->word[0], 12, 20, v))
507bb981004SEric Auger #define EVT_SET_SID(x, v)   ((x)->word[1] = v)
5089f4d2a13SEric Auger #define EVT_SET_STAG(x, v)  ((x)->word[2] = deposit32((x)->word[2], 0 , 16, v))
5099f4d2a13SEric Auger #define EVT_SET_STALL(x, v) ((x)->word[2] = deposit32((x)->word[2], 31, 1 , v))
5109f4d2a13SEric Auger #define EVT_SET_PNU(x, v)   ((x)->word[3] = deposit32((x)->word[3], 1 , 1 , v))
5119f4d2a13SEric Auger #define EVT_SET_IND(x, v)   ((x)->word[3] = deposit32((x)->word[3], 2 , 1 , v))
5129f4d2a13SEric Auger #define EVT_SET_RNW(x, v)   ((x)->word[3] = deposit32((x)->word[3], 3 , 1 , v))
5139f4d2a13SEric Auger #define EVT_SET_S2(x, v)    ((x)->word[3] = deposit32((x)->word[3], 7 , 1 , v))
5149f4d2a13SEric Auger #define EVT_SET_CLASS(x, v) ((x)->word[3] = deposit32((x)->word[3], 8 , 2 , v))
515bb981004SEric Auger #define EVT_SET_ADDR(x, addr)                             \
516bb981004SEric Auger     do {                                                  \
517bb981004SEric Auger             (x)->word[5] = (uint32_t)(addr >> 32);        \
518bb981004SEric Auger             (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
519bb981004SEric Auger     } while (0)
520bb981004SEric Auger #define EVT_SET_ADDR2(x, addr)                            \
521bb981004SEric Auger     do {                                                  \
522a7f65cebSSimon Veith             (x)->word[7] = (uint32_t)(addr >> 32);        \
523a7f65cebSSimon Veith             (x)->word[6] = (uint32_t)(addr & 0xffffffff); \
524bb981004SEric Auger     } while (0)
525bb981004SEric Auger 
526bb981004SEric Auger void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
527bb981004SEric Auger 
5289bde7f06SEric Auger /* Configuration Data */
5299bde7f06SEric Auger 
5309bde7f06SEric Auger /* STE Level 1 Descriptor */
5319bde7f06SEric Auger typedef struct STEDesc {
5329bde7f06SEric Auger     uint32_t word[2];
5339bde7f06SEric Auger } STEDesc;
5349bde7f06SEric Auger 
5359bde7f06SEric Auger /* CD Level 1 Descriptor */
5369bde7f06SEric Auger typedef struct CDDesc {
5379bde7f06SEric Auger     uint32_t word[2];
5389bde7f06SEric Auger } CDDesc;
5399bde7f06SEric Auger 
5409bde7f06SEric Auger /* Stream Table Entry(STE) */
5419bde7f06SEric Auger typedef struct STE {
5429bde7f06SEric Auger     uint32_t word[16];
5439bde7f06SEric Auger } STE;
5449bde7f06SEric Auger 
5459bde7f06SEric Auger /* Context Descriptor(CD) */
5469bde7f06SEric Auger typedef struct CD {
5479bde7f06SEric Auger     uint32_t word[16];
5489bde7f06SEric Auger } CD;
5499bde7f06SEric Auger 
5509bde7f06SEric Auger /* STE fields */
5519bde7f06SEric Auger 
5529bde7f06SEric Auger #define STE_VALID(x)   extract32((x)->word[0], 0, 1)
5539bde7f06SEric Auger 
5549bde7f06SEric Auger #define STE_CONFIG(x)  extract32((x)->word[0], 1, 3)
5559bde7f06SEric Auger #define STE_CFG_S1_ENABLED(config) (config & 0x1)
5569bde7f06SEric Auger #define STE_CFG_S2_ENABLED(config) (config & 0x2)
5579bde7f06SEric Auger #define STE_CFG_ABORT(config)      (!(config & 0x4))
5589bde7f06SEric Auger #define STE_CFG_BYPASS(config)     (config == 0x4)
5599bde7f06SEric Auger 
5609bde7f06SEric Auger #define STE_S1FMT(x)       extract32((x)->word[0], 4 , 2)
5619bde7f06SEric Auger #define STE_S1CDMAX(x)     extract32((x)->word[1], 27, 5)
5629bde7f06SEric Auger #define STE_S1STALLD(x)    extract32((x)->word[2], 27, 1)
5639bde7f06SEric Auger #define STE_EATS(x)        extract32((x)->word[2], 28, 2)
5649bde7f06SEric Auger #define STE_STRW(x)        extract32((x)->word[2], 30, 2)
5659bde7f06SEric Auger #define STE_S2VMID(x)      extract32((x)->word[4], 0 , 16)
5669bde7f06SEric Auger #define STE_S2T0SZ(x)      extract32((x)->word[5], 0 , 6)
5679bde7f06SEric Auger #define STE_S2SL0(x)       extract32((x)->word[5], 6 , 2)
5689bde7f06SEric Auger #define STE_S2TG(x)        extract32((x)->word[5], 14, 2)
5699bde7f06SEric Auger #define STE_S2PS(x)        extract32((x)->word[5], 16, 3)
5709bde7f06SEric Auger #define STE_S2AA64(x)      extract32((x)->word[5], 19, 1)
57121eb5b5cSMostafa Saleh #define STE_S2ENDI(x)      extract32((x)->word[5], 20, 1)
57221eb5b5cSMostafa Saleh #define STE_S2AFFD(x)      extract32((x)->word[5], 21, 1)
57321eb5b5cSMostafa Saleh #define STE_S2HD(x)        extract32((x)->word[5], 23, 1)
57421eb5b5cSMostafa Saleh #define STE_S2HA(x)        extract32((x)->word[5], 24, 1)
57521eb5b5cSMostafa Saleh #define STE_S2S(x)         extract32((x)->word[5], 25, 1)
57621eb5b5cSMostafa Saleh #define STE_S2R(x)         extract32((x)->word[5], 26, 1)
57721eb5b5cSMostafa Saleh 
5789bde7f06SEric Auger #define STE_CTXPTR(x)                                   \
57984abccddSPeter Maydell     ((extract64((x)->word[1], 0, 16) << 32) |           \
58084abccddSPeter Maydell      ((x)->word[0] & 0xffffffc0))
5819bde7f06SEric Auger 
5829bde7f06SEric Auger #define STE_S2TTB(x)                                    \
58384abccddSPeter Maydell     ((extract64((x)->word[7], 0, 16) << 32) |           \
58484abccddSPeter Maydell      ((x)->word[6] & 0xfffffff0))
5859bde7f06SEric Auger 
oas2bits(int oas_field)5869bde7f06SEric Auger static inline int oas2bits(int oas_field)
5879bde7f06SEric Auger {
5889bde7f06SEric Auger     switch (oas_field) {
5899bde7f06SEric Auger     case 0:
5909bde7f06SEric Auger         return 32;
5919bde7f06SEric Auger     case 1:
5929bde7f06SEric Auger         return 36;
5939bde7f06SEric Auger     case 2:
5949bde7f06SEric Auger         return 40;
5959bde7f06SEric Auger     case 3:
5969bde7f06SEric Auger         return 42;
5979bde7f06SEric Auger     case 4:
5989bde7f06SEric Auger         return 44;
5999bde7f06SEric Auger     case 5:
6009bde7f06SEric Auger         return 48;
6019bde7f06SEric Auger     }
602*8deba2f3SMostafa Saleh 
603*8deba2f3SMostafa Saleh     g_assert_not_reached();
6049bde7f06SEric Auger }
6059bde7f06SEric Auger 
6069bde7f06SEric Auger /* CD fields */
6079bde7f06SEric Auger 
6081b41847aSJoe Komlodi #define CD_VALID(x)   extract32((x)->word[0], 31, 1)
6099bde7f06SEric Auger #define CD_ASID(x)    extract32((x)->word[1], 16, 16)
6109bde7f06SEric Auger #define CD_TTB(x, sel)                                          \
61184abccddSPeter Maydell     ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) |       \
61284abccddSPeter Maydell      ((x)->word[(sel) * 2 + 2] & ~0xfULL))
61384abccddSPeter Maydell 
614e7c3b9d9SEric Auger #define CD_HAD(x, sel)   extract32((x)->word[(sel) * 2 + 2], 1, 1)
6159bde7f06SEric Auger 
6169bde7f06SEric Auger #define CD_TSZ(x, sel)   extract32((x)->word[0], (16 * (sel)) + 0, 6)
6179bde7f06SEric Auger #define CD_TG(x, sel)    extract32((x)->word[0], (16 * (sel)) + 6, 2)
6189bde7f06SEric Auger #define CD_EPD(x, sel)   extract32((x)->word[0], (16 * (sel)) + 14, 1)
6199bde7f06SEric Auger #define CD_ENDI(x)       extract32((x)->word[0], 15, 1)
6209bde7f06SEric Auger #define CD_IPS(x)        extract32((x)->word[1], 0 , 3)
62115f6c16eSLuc Michel #define CD_AFFD(x)       extract32((x)->word[1], 3 , 1)
6229bde7f06SEric Auger #define CD_TBI(x)        extract32((x)->word[1], 6 , 2)
6239bde7f06SEric Auger #define CD_HD(x)         extract32((x)->word[1], 10 , 1)
6249bde7f06SEric Auger #define CD_HA(x)         extract32((x)->word[1], 11 , 1)
6259bde7f06SEric Auger #define CD_S(x)          extract32((x)->word[1], 12, 1)
6269bde7f06SEric Auger #define CD_R(x)          extract32((x)->word[1], 13, 1)
6279bde7f06SEric Auger #define CD_A(x)          extract32((x)->word[1], 14, 1)
6289bde7f06SEric Auger #define CD_AARCH64(x)    extract32((x)->word[1], 9 , 1)
6299bde7f06SEric Auger 
6309bde7f06SEric Auger /**
6319bde7f06SEric Auger  * tg2granule - Decodes the CD translation granule size field according
6329bde7f06SEric Auger  * to the ttbr in use
6339bde7f06SEric Auger  * @bits: TG0/1 fields
6349bde7f06SEric Auger  * @ttbr: ttbr index in use
6359bde7f06SEric Auger  */
tg2granule(int bits,int ttbr)6369bde7f06SEric Auger static inline int tg2granule(int bits, int ttbr)
6379bde7f06SEric Auger {
6389bde7f06SEric Auger     switch (bits) {
6399bde7f06SEric Auger     case 0:
6409bde7f06SEric Auger         return ttbr ? 0  : 12;
6419bde7f06SEric Auger     case 1:
6429bde7f06SEric Auger         return ttbr ? 14 : 16;
6439bde7f06SEric Auger     case 2:
6449bde7f06SEric Auger         return ttbr ? 12 : 14;
6459bde7f06SEric Auger     case 3:
6469bde7f06SEric Auger         return ttbr ? 16 :  0;
6479bde7f06SEric Auger     default:
6489bde7f06SEric Auger         return 0;
6499bde7f06SEric Auger     }
6509bde7f06SEric Auger }
6519bde7f06SEric Auger 
l1std_l2ptr(STEDesc * desc)6529bde7f06SEric Auger static inline uint64_t l1std_l2ptr(STEDesc *desc)
6539bde7f06SEric Auger {
6549bde7f06SEric Auger     uint64_t hi, lo;
6559bde7f06SEric Auger 
6569bde7f06SEric Auger     hi = desc->word[1];
6579bde7f06SEric Auger     lo = desc->word[0] & ~0x1fULL;
6589bde7f06SEric Auger     return hi << 32 | lo;
6599bde7f06SEric Auger }
6609bde7f06SEric Auger 
661d9aad887SKunkun Jiang #define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
6629bde7f06SEric Auger 
66310a83cb9SPrem Mallappa #endif
664