xref: /qemu/hw/arm/smmuv3-internal.h (revision cbaf9404f031a39342dee4d3183488a763f149e4)
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 
2410a83cb9SPrem Mallappa #include "hw/arm/smmu-common.h"
2510a83cb9SPrem Mallappa 
269122bea9SJia He typedef enum SMMUTranslationStatus {
279122bea9SJia He     SMMU_TRANS_DISABLE,
289122bea9SJia He     SMMU_TRANS_ABORT,
299122bea9SJia He     SMMU_TRANS_BYPASS,
309122bea9SJia He     SMMU_TRANS_ERROR,
319122bea9SJia He     SMMU_TRANS_SUCCESS,
329122bea9SJia He } SMMUTranslationStatus;
339122bea9SJia He 
3410a83cb9SPrem Mallappa /* MMIO Registers */
3510a83cb9SPrem Mallappa 
3610a83cb9SPrem Mallappa REG32(IDR0,                0x0)
37263d0e48SMostafa Saleh     FIELD(IDR0, S2P,         0 , 1)
3810a83cb9SPrem Mallappa     FIELD(IDR0, S1P,         1 , 1)
3910a83cb9SPrem Mallappa     FIELD(IDR0, TTF,         2 , 2)
4010a83cb9SPrem Mallappa     FIELD(IDR0, COHACC,      4 , 1)
41*cbaf9404SPeter Maydell     FIELD(IDR0, BTM,         5 , 1)
42*cbaf9404SPeter Maydell     FIELD(IDR0, HTTU,        6 , 2)
43*cbaf9404SPeter Maydell     FIELD(IDR0, DORMHINT,    8 , 1)
44*cbaf9404SPeter Maydell     FIELD(IDR0, HYP,         9 , 1)
45*cbaf9404SPeter Maydell     FIELD(IDR0, ATS,         10, 1)
46*cbaf9404SPeter Maydell     FIELD(IDR0, NS1ATS,      11, 1)
4710a83cb9SPrem Mallappa     FIELD(IDR0, ASID16,      12, 1)
48*cbaf9404SPeter Maydell     FIELD(IDR0, MSI,         13, 1)
49*cbaf9404SPeter Maydell     FIELD(IDR0, SEV,         14, 1)
50*cbaf9404SPeter Maydell     FIELD(IDR0, ATOS,        15, 1)
51*cbaf9404SPeter Maydell     FIELD(IDR0, PRI,         16, 1)
52*cbaf9404SPeter Maydell     FIELD(IDR0, VMW,         17, 1)
53263d0e48SMostafa Saleh     FIELD(IDR0, VMID16,      18, 1)
54*cbaf9404SPeter Maydell     FIELD(IDR0, CD2L,        19, 1)
55*cbaf9404SPeter Maydell     FIELD(IDR0, VATOS,       20, 1)
5610a83cb9SPrem Mallappa     FIELD(IDR0, TTENDIAN,    21, 2)
57*cbaf9404SPeter Maydell     FIELD(IDR0, ATSRECERR,   23, 1)
5810a83cb9SPrem Mallappa     FIELD(IDR0, STALL_MODEL, 24, 2)
5910a83cb9SPrem Mallappa     FIELD(IDR0, TERM_MODEL,  26, 1)
6010a83cb9SPrem Mallappa     FIELD(IDR0, STLEVEL,     27, 2)
61*cbaf9404SPeter Maydell     FIELD(IDR0, RME_IMPL,    30, 1)
6210a83cb9SPrem Mallappa 
6310a83cb9SPrem Mallappa REG32(IDR1,                0x4)
6410a83cb9SPrem Mallappa     FIELD(IDR1, SIDSIZE,      0 , 6)
65*cbaf9404SPeter Maydell     FIELD(IDR1, SSIDSIZE,     6 , 5)
66*cbaf9404SPeter Maydell     FIELD(IDR1, PRIQS,        11, 5)
6710a83cb9SPrem Mallappa     FIELD(IDR1, EVENTQS,      16, 5)
6810a83cb9SPrem Mallappa     FIELD(IDR1, CMDQS,        21, 5)
69*cbaf9404SPeter Maydell     FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
70*cbaf9404SPeter Maydell     FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
71*cbaf9404SPeter Maydell     FIELD(IDR1, REL,          28, 1)
72*cbaf9404SPeter Maydell     FIELD(IDR1, QUEUES_PRESET, 29, 1)
73*cbaf9404SPeter Maydell     FIELD(IDR1, TABLES_PRESET, 30, 1)
74*cbaf9404SPeter Maydell     FIELD(IDR1, ECMDQ,        31, 1)
7510a83cb9SPrem Mallappa 
7610a83cb9SPrem Mallappa #define SMMU_IDR1_SIDSIZE 16
7710a83cb9SPrem Mallappa #define SMMU_CMDQS   19
7810a83cb9SPrem Mallappa #define SMMU_EVENTQS 19
7910a83cb9SPrem Mallappa 
8010a83cb9SPrem Mallappa REG32(IDR2,                0x8)
81*cbaf9404SPeter Maydell      FIELD(IDR2, BA_VATOS, 0, 10)
82*cbaf9404SPeter Maydell 
8310a83cb9SPrem Mallappa REG32(IDR3,                0xc)
84e7c3b9d9SEric Auger      FIELD(IDR3, HAD,         2, 1);
85*cbaf9404SPeter Maydell      FIELD(IDR3, PBHA,        3, 1);
86*cbaf9404SPeter Maydell      FIELD(IDR3, XNX,         4, 1);
87*cbaf9404SPeter Maydell      FIELD(IDR3, PPS,         5, 1);
88*cbaf9404SPeter Maydell      FIELD(IDR3, MPAM,        7, 1);
89*cbaf9404SPeter Maydell      FIELD(IDR3, FWB,         8, 1);
90*cbaf9404SPeter Maydell      FIELD(IDR3, STT,         9, 1);
91de206dfdSEric Auger      FIELD(IDR3, RIL,        10, 1);
92f8e7163dSPeter Maydell      FIELD(IDR3, BBML,       11, 2);
93*cbaf9404SPeter Maydell      FIELD(IDR3, E0PD,       13, 1);
94*cbaf9404SPeter Maydell      FIELD(IDR3, PTWNNC,     14, 1);
95*cbaf9404SPeter Maydell      FIELD(IDR3, DPT,        15, 1);
96*cbaf9404SPeter Maydell 
9710a83cb9SPrem Mallappa REG32(IDR4,                0x10)
98*cbaf9404SPeter Maydell 
9910a83cb9SPrem Mallappa REG32(IDR5,                0x14)
10010a83cb9SPrem Mallappa      FIELD(IDR5, OAS,         0, 3);
10110a83cb9SPrem Mallappa      FIELD(IDR5, GRAN4K,      4, 1);
10210a83cb9SPrem Mallappa      FIELD(IDR5, GRAN16K,     5, 1);
10310a83cb9SPrem Mallappa      FIELD(IDR5, GRAN64K,     6, 1);
104*cbaf9404SPeter Maydell      FIELD(IDR5, VAX,        10, 2);
105*cbaf9404SPeter Maydell      FIELD(IDR5, STALL_MAX,  16, 16);
10610a83cb9SPrem Mallappa 
10710a83cb9SPrem Mallappa #define SMMU_IDR5_OAS 4
10810a83cb9SPrem Mallappa 
109f0ec277cSEric Auger REG32(IIDR,                0x18)
1105888f0adSEric Auger REG32(AIDR,                0x1c)
11110a83cb9SPrem Mallappa REG32(CR0,                 0x20)
11210a83cb9SPrem Mallappa     FIELD(CR0, SMMU_ENABLE,   0, 1)
11310a83cb9SPrem Mallappa     FIELD(CR0, EVENTQEN,      2, 1)
11410a83cb9SPrem Mallappa     FIELD(CR0, CMDQEN,        3, 1)
11510a83cb9SPrem Mallappa 
116fae4be38SEric Auger #define SMMU_CR0_RESERVED 0xFFFFFC20
117fae4be38SEric Auger 
11810a83cb9SPrem Mallappa REG32(CR0ACK,              0x24)
11910a83cb9SPrem Mallappa REG32(CR1,                 0x28)
12010a83cb9SPrem Mallappa REG32(CR2,                 0x2c)
12110a83cb9SPrem Mallappa REG32(STATUSR,             0x40)
122c2ecb424SMostafa Saleh REG32(GBPA,                0x44)
123c2ecb424SMostafa Saleh     FIELD(GBPA, ABORT,        20, 1)
124c2ecb424SMostafa Saleh     FIELD(GBPA, UPDATE,       31, 1)
125c2ecb424SMostafa Saleh 
126c2ecb424SMostafa Saleh /* Use incoming. */
127c2ecb424SMostafa Saleh #define SMMU_GBPA_RESET_VAL 0x1000
128c2ecb424SMostafa Saleh 
12910a83cb9SPrem Mallappa REG32(IRQ_CTRL,            0x50)
13010a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, GERROR_IRQEN,        0, 1)
13110a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, PRI_IRQEN,           1, 1)
13210a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, EVENTQ_IRQEN,        2, 1)
13310a83cb9SPrem Mallappa 
13410a83cb9SPrem Mallappa REG32(IRQ_CTRL_ACK,        0x54)
13510a83cb9SPrem Mallappa REG32(GERROR,              0x60)
13610a83cb9SPrem Mallappa     FIELD(GERROR, CMDQ_ERR,           0, 1)
13710a83cb9SPrem Mallappa     FIELD(GERROR, EVENTQ_ABT_ERR,     2, 1)
13810a83cb9SPrem Mallappa     FIELD(GERROR, PRIQ_ABT_ERR,       3, 1)
13910a83cb9SPrem Mallappa     FIELD(GERROR, MSI_CMDQ_ABT_ERR,   4, 1)
14010a83cb9SPrem Mallappa     FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
14110a83cb9SPrem Mallappa     FIELD(GERROR, MSI_PRIQ_ABT_ERR,   6, 1)
14210a83cb9SPrem Mallappa     FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
14310a83cb9SPrem Mallappa     FIELD(GERROR, MSI_SFM_ERR,        8, 1)
14410a83cb9SPrem Mallappa 
14510a83cb9SPrem Mallappa REG32(GERRORN,             0x64)
14610a83cb9SPrem Mallappa 
14710a83cb9SPrem Mallappa #define A_GERROR_IRQ_CFG0  0x68 /* 64b */
14810a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG1, 0x70)
14910a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG2, 0x74)
15010a83cb9SPrem Mallappa 
15110a83cb9SPrem Mallappa #define A_STRTAB_BASE      0x80 /* 64b */
15210a83cb9SPrem Mallappa 
1533293b9f5SSimon Veith #define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
15410a83cb9SPrem Mallappa 
15510a83cb9SPrem Mallappa REG32(STRTAB_BASE_CFG,     0x88)
15610a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, FMT,      16, 2)
15710a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, SPLIT,    6 , 5)
15810a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
15910a83cb9SPrem Mallappa 
16010a83cb9SPrem Mallappa #define A_CMDQ_BASE        0x90 /* 64b */
16110a83cb9SPrem Mallappa REG32(CMDQ_PROD,           0x98)
16210a83cb9SPrem Mallappa REG32(CMDQ_CONS,           0x9c)
16310a83cb9SPrem Mallappa     FIELD(CMDQ_CONS, ERR, 24, 7)
16410a83cb9SPrem Mallappa 
16510a83cb9SPrem Mallappa #define A_EVENTQ_BASE      0xa0 /* 64b */
16610a83cb9SPrem Mallappa REG32(EVENTQ_PROD,         0xa8)
16710a83cb9SPrem Mallappa REG32(EVENTQ_CONS,         0xac)
16810a83cb9SPrem Mallappa 
16910a83cb9SPrem Mallappa #define A_EVENTQ_IRQ_CFG0  0xb0 /* 64b */
17010a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG1,     0xb8)
17110a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG2,     0xbc)
17210a83cb9SPrem Mallappa 
17310a83cb9SPrem Mallappa #define A_IDREGS           0xfd0
17410a83cb9SPrem Mallappa 
17510a83cb9SPrem Mallappa static inline int smmu_enabled(SMMUv3State *s)
17610a83cb9SPrem Mallappa {
17710a83cb9SPrem Mallappa     return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
17810a83cb9SPrem Mallappa }
17910a83cb9SPrem Mallappa 
18010a83cb9SPrem Mallappa /* Command Queue Entry */
18110a83cb9SPrem Mallappa typedef struct Cmd {
18210a83cb9SPrem Mallappa     uint32_t word[4];
18310a83cb9SPrem Mallappa } Cmd;
18410a83cb9SPrem Mallappa 
18510a83cb9SPrem Mallappa /* Event Queue Entry */
18610a83cb9SPrem Mallappa typedef struct Evt  {
18710a83cb9SPrem Mallappa     uint32_t word[8];
18810a83cb9SPrem Mallappa } Evt;
18910a83cb9SPrem Mallappa 
19010a83cb9SPrem Mallappa static inline uint32_t smmuv3_idreg(int regoffset)
19110a83cb9SPrem Mallappa {
19210a83cb9SPrem Mallappa     /*
19310a83cb9SPrem Mallappa      * Return the value of the Primecell/Corelink ID registers at the
19410a83cb9SPrem Mallappa      * specified offset from the first ID register.
19510a83cb9SPrem Mallappa      * These value indicate an ARM implementation of MMU600 p1
19610a83cb9SPrem Mallappa      */
19710a83cb9SPrem Mallappa     static const uint8_t smmuv3_ids[] = {
19810a83cb9SPrem Mallappa         0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
19910a83cb9SPrem Mallappa     };
20010a83cb9SPrem Mallappa     return smmuv3_ids[regoffset / 4];
20110a83cb9SPrem Mallappa }
20210a83cb9SPrem Mallappa 
2036a736033SEric Auger static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
2046a736033SEric Auger {
2056a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
2066a736033SEric Auger }
2076a736033SEric Auger 
2086a736033SEric Auger static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
2096a736033SEric Auger {
2106a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
2116a736033SEric Auger }
2126a736033SEric Auger 
213dadd1a08SEric Auger /* Queue Handling */
214dadd1a08SEric Auger 
215dadd1a08SEric Auger #define Q_BASE(q)          ((q)->base & SMMU_BASE_ADDR_MASK)
216dadd1a08SEric Auger #define WRAP_MASK(q)       (1 << (q)->log2size)
217dadd1a08SEric Auger #define INDEX_MASK(q)      (((1 << (q)->log2size)) - 1)
218dadd1a08SEric Auger #define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
219dadd1a08SEric Auger 
220dadd1a08SEric Auger #define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
221dadd1a08SEric Auger #define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
222dadd1a08SEric Auger 
223dadd1a08SEric Auger #define Q_CONS_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
224dadd1a08SEric Auger #define Q_PROD_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
225dadd1a08SEric Auger 
226dadd1a08SEric Auger #define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
227dadd1a08SEric Auger #define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
228dadd1a08SEric Auger 
229dadd1a08SEric Auger static inline bool smmuv3_q_full(SMMUQueue *q)
230dadd1a08SEric Auger {
231dadd1a08SEric Auger     return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
232dadd1a08SEric Auger }
233dadd1a08SEric Auger 
234dadd1a08SEric Auger static inline bool smmuv3_q_empty(SMMUQueue *q)
235dadd1a08SEric Auger {
236dadd1a08SEric Auger     return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
237dadd1a08SEric Auger }
238dadd1a08SEric Auger 
239dadd1a08SEric Auger static inline void queue_prod_incr(SMMUQueue *q)
240dadd1a08SEric Auger {
241dadd1a08SEric Auger     q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
242dadd1a08SEric Auger }
243dadd1a08SEric Auger 
244dadd1a08SEric Auger static inline void queue_cons_incr(SMMUQueue *q)
245dadd1a08SEric Auger {
246dadd1a08SEric Auger     /*
247dadd1a08SEric Auger      * We have to use deposit for the CONS registers to preserve
248dadd1a08SEric Auger      * the ERR field in the high bits.
249dadd1a08SEric Auger      */
250dadd1a08SEric Auger     q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
251dadd1a08SEric Auger }
252dadd1a08SEric Auger 
253dadd1a08SEric Auger static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
254dadd1a08SEric Auger {
255dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, CMDQEN);
256dadd1a08SEric Auger }
257dadd1a08SEric Auger 
258dadd1a08SEric Auger static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
259dadd1a08SEric Auger {
260dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
261dadd1a08SEric Auger }
262dadd1a08SEric Auger 
263dadd1a08SEric Auger static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
264dadd1a08SEric Auger {
265dadd1a08SEric Auger     s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
266dadd1a08SEric Auger }
267dadd1a08SEric Auger 
268dadd1a08SEric Auger /* Commands */
269dadd1a08SEric Auger 
270dadd1a08SEric Auger typedef enum SMMUCommandType {
271dadd1a08SEric Auger     SMMU_CMD_NONE            = 0x00,
272dadd1a08SEric Auger     SMMU_CMD_PREFETCH_CONFIG       ,
273dadd1a08SEric Auger     SMMU_CMD_PREFETCH_ADDR,
274dadd1a08SEric Auger     SMMU_CMD_CFGI_STE,
275dadd1a08SEric Auger     SMMU_CMD_CFGI_STE_RANGE,
276dadd1a08SEric Auger     SMMU_CMD_CFGI_CD,
277dadd1a08SEric Auger     SMMU_CMD_CFGI_CD_ALL,
278dadd1a08SEric Auger     SMMU_CMD_CFGI_ALL,
279dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ALL     = 0x10,
280dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ASID,
281dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VA,
282dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VAA,
283dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_ALL    = 0x18,
284dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_VA     = 0x1a,
285dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ALL    = 0x20,
286dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ASID,
287dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VA,
288dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VAA,
289dadd1a08SEric Auger     SMMU_CMD_TLBI_S12_VMALL  = 0x28,
290dadd1a08SEric Auger     SMMU_CMD_TLBI_S2_IPA     = 0x2a,
291dadd1a08SEric Auger     SMMU_CMD_TLBI_NSNH_ALL   = 0x30,
292dadd1a08SEric Auger     SMMU_CMD_ATC_INV         = 0x40,
293dadd1a08SEric Auger     SMMU_CMD_PRI_RESP,
294dadd1a08SEric Auger     SMMU_CMD_RESUME          = 0x44,
295dadd1a08SEric Auger     SMMU_CMD_STALL_TERM,
296dadd1a08SEric Auger     SMMU_CMD_SYNC,
297dadd1a08SEric Auger } SMMUCommandType;
298dadd1a08SEric Auger 
299dadd1a08SEric Auger static const char *cmd_stringify[] = {
300dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
301dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_ADDR]   = "SMMU_CMD_PREFETCH_ADDR",
302dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE]        = "SMMU_CMD_CFGI_STE",
303dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE_RANGE]  = "SMMU_CMD_CFGI_STE_RANGE",
304dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD]         = "SMMU_CMD_CFGI_CD",
305dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD_ALL]     = "SMMU_CMD_CFGI_CD_ALL",
306dadd1a08SEric Auger     [SMMU_CMD_CFGI_ALL]        = "SMMU_CMD_CFGI_ALL",
307dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ALL]     = "SMMU_CMD_TLBI_NH_ALL",
308dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ASID]    = "SMMU_CMD_TLBI_NH_ASID",
309dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VA]      = "SMMU_CMD_TLBI_NH_VA",
310dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VAA]     = "SMMU_CMD_TLBI_NH_VAA",
311dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_ALL]    = "SMMU_CMD_TLBI_EL3_ALL",
312dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_VA]     = "SMMU_CMD_TLBI_EL3_VA",
313dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ALL]    = "SMMU_CMD_TLBI_EL2_ALL",
314dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ASID]   = "SMMU_CMD_TLBI_EL2_ASID",
315dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VA]     = "SMMU_CMD_TLBI_EL2_VA",
316dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VAA]    = "SMMU_CMD_TLBI_EL2_VAA",
317dadd1a08SEric Auger     [SMMU_CMD_TLBI_S12_VMALL]  = "SMMU_CMD_TLBI_S12_VMALL",
318dadd1a08SEric Auger     [SMMU_CMD_TLBI_S2_IPA]     = "SMMU_CMD_TLBI_S2_IPA",
319dadd1a08SEric Auger     [SMMU_CMD_TLBI_NSNH_ALL]   = "SMMU_CMD_TLBI_NSNH_ALL",
320dadd1a08SEric Auger     [SMMU_CMD_ATC_INV]         = "SMMU_CMD_ATC_INV",
321dadd1a08SEric Auger     [SMMU_CMD_PRI_RESP]        = "SMMU_CMD_PRI_RESP",
322dadd1a08SEric Auger     [SMMU_CMD_RESUME]          = "SMMU_CMD_RESUME",
323dadd1a08SEric Auger     [SMMU_CMD_STALL_TERM]      = "SMMU_CMD_STALL_TERM",
324dadd1a08SEric Auger     [SMMU_CMD_SYNC]            = "SMMU_CMD_SYNC",
325dadd1a08SEric Auger };
326dadd1a08SEric Auger 
327dadd1a08SEric Auger static inline const char *smmu_cmd_string(SMMUCommandType type)
328dadd1a08SEric Auger {
329dadd1a08SEric Auger     if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
330dadd1a08SEric Auger         return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
331dadd1a08SEric Auger     } else {
332dadd1a08SEric Auger         return "INVALID";
333dadd1a08SEric Auger     }
334dadd1a08SEric Auger }
335dadd1a08SEric Auger 
336dadd1a08SEric Auger /* CMDQ fields */
337dadd1a08SEric Auger 
338dadd1a08SEric Auger typedef enum {
339dadd1a08SEric Auger     SMMU_CERROR_NONE = 0,
340dadd1a08SEric Auger     SMMU_CERROR_ILL,
341dadd1a08SEric Auger     SMMU_CERROR_ABT,
342dadd1a08SEric Auger     SMMU_CERROR_ATC_INV_SYNC,
343dadd1a08SEric Auger } SMMUCmdError;
344dadd1a08SEric Auger 
345dadd1a08SEric Auger enum { /* Command completion notification */
346dadd1a08SEric Auger     CMD_SYNC_SIG_NONE,
347dadd1a08SEric Auger     CMD_SYNC_SIG_IRQ,
348dadd1a08SEric Auger     CMD_SYNC_SIG_SEV,
349dadd1a08SEric Auger };
350dadd1a08SEric Auger 
351dadd1a08SEric Auger #define CMD_TYPE(x)         extract32((x)->word[0], 0 , 8)
352d5291561SEric Auger #define CMD_NUM(x)          extract32((x)->word[0], 12 , 5)
353d5291561SEric Auger #define CMD_SCALE(x)        extract32((x)->word[0], 20 , 5)
354dadd1a08SEric Auger #define CMD_SSEC(x)         extract32((x)->word[0], 10, 1)
355dadd1a08SEric Auger #define CMD_SSV(x)          extract32((x)->word[0], 11, 1)
356dadd1a08SEric Auger #define CMD_RESUME_AC(x)    extract32((x)->word[0], 12, 1)
357dadd1a08SEric Auger #define CMD_RESUME_AB(x)    extract32((x)->word[0], 13, 1)
358dadd1a08SEric Auger #define CMD_SYNC_CS(x)      extract32((x)->word[0], 12, 2)
359dadd1a08SEric Auger #define CMD_SSID(x)         extract32((x)->word[0], 12, 20)
360dadd1a08SEric Auger #define CMD_SID(x)          ((x)->word[1])
361dadd1a08SEric Auger #define CMD_VMID(x)         extract32((x)->word[1], 0 , 16)
362dadd1a08SEric Auger #define CMD_ASID(x)         extract32((x)->word[1], 16, 16)
363dadd1a08SEric Auger #define CMD_RESUME_STAG(x)  extract32((x)->word[2], 0 , 16)
364dadd1a08SEric Auger #define CMD_RESP(x)         extract32((x)->word[2], 11, 2)
365dadd1a08SEric Auger #define CMD_LEAF(x)         extract32((x)->word[2], 0 , 1)
366d5291561SEric Auger #define CMD_TTL(x)          extract32((x)->word[2], 8 , 2)
367d5291561SEric Auger #define CMD_TG(x)           extract32((x)->word[2], 10, 2)
368dadd1a08SEric Auger #define CMD_STE_RANGE(x)    extract32((x)->word[2], 0 , 5)
36984abccddSPeter Maydell #define CMD_ADDR(x)                             \
37084abccddSPeter Maydell     (((uint64_t)((x)->word[3]) << 32) |         \
37184abccddSPeter Maydell      ((extract64((x)->word[2], 12, 20)) << 12))
372dadd1a08SEric Auger 
373fae4be38SEric Auger #define SMMU_FEATURE_2LVL_STE (1 << 0)
374dadd1a08SEric Auger 
375bb981004SEric Auger /* Events */
376bb981004SEric Auger 
377bb981004SEric Auger typedef enum SMMUEventType {
3789122bea9SJia He     SMMU_EVT_NONE               = 0x00,
379bb981004SEric Auger     SMMU_EVT_F_UUT                    ,
380bb981004SEric Auger     SMMU_EVT_C_BAD_STREAMID           ,
381bb981004SEric Auger     SMMU_EVT_F_STE_FETCH              ,
382bb981004SEric Auger     SMMU_EVT_C_BAD_STE                ,
383bb981004SEric Auger     SMMU_EVT_F_BAD_ATS_TREQ           ,
384bb981004SEric Auger     SMMU_EVT_F_STREAM_DISABLED        ,
385bb981004SEric Auger     SMMU_EVT_F_TRANS_FORBIDDEN        ,
386bb981004SEric Auger     SMMU_EVT_C_BAD_SUBSTREAMID        ,
387bb981004SEric Auger     SMMU_EVT_F_CD_FETCH               ,
388bb981004SEric Auger     SMMU_EVT_C_BAD_CD                 ,
389bb981004SEric Auger     SMMU_EVT_F_WALK_EABT              ,
390bb981004SEric Auger     SMMU_EVT_F_TRANSLATION      = 0x10,
391bb981004SEric Auger     SMMU_EVT_F_ADDR_SIZE              ,
392bb981004SEric Auger     SMMU_EVT_F_ACCESS                 ,
393bb981004SEric Auger     SMMU_EVT_F_PERMISSION             ,
394bb981004SEric Auger     SMMU_EVT_F_TLB_CONFLICT     = 0x20,
395bb981004SEric Auger     SMMU_EVT_F_CFG_CONFLICT           ,
396bb981004SEric Auger     SMMU_EVT_E_PAGE_REQ         = 0x24,
397bb981004SEric Auger } SMMUEventType;
398bb981004SEric Auger 
399bb981004SEric Auger static const char *event_stringify[] = {
4009122bea9SJia He     [SMMU_EVT_NONE]                     = "no recorded event",
401bb981004SEric Auger     [SMMU_EVT_F_UUT]                    = "SMMU_EVT_F_UUT",
402bb981004SEric Auger     [SMMU_EVT_C_BAD_STREAMID]           = "SMMU_EVT_C_BAD_STREAMID",
403bb981004SEric Auger     [SMMU_EVT_F_STE_FETCH]              = "SMMU_EVT_F_STE_FETCH",
404bb981004SEric Auger     [SMMU_EVT_C_BAD_STE]                = "SMMU_EVT_C_BAD_STE",
405bb981004SEric Auger     [SMMU_EVT_F_BAD_ATS_TREQ]           = "SMMU_EVT_F_BAD_ATS_TREQ",
406bb981004SEric Auger     [SMMU_EVT_F_STREAM_DISABLED]        = "SMMU_EVT_F_STREAM_DISABLED",
407bb981004SEric Auger     [SMMU_EVT_F_TRANS_FORBIDDEN]        = "SMMU_EVT_F_TRANS_FORBIDDEN",
408bb981004SEric Auger     [SMMU_EVT_C_BAD_SUBSTREAMID]        = "SMMU_EVT_C_BAD_SUBSTREAMID",
409bb981004SEric Auger     [SMMU_EVT_F_CD_FETCH]               = "SMMU_EVT_F_CD_FETCH",
410bb981004SEric Auger     [SMMU_EVT_C_BAD_CD]                 = "SMMU_EVT_C_BAD_CD",
411bb981004SEric Auger     [SMMU_EVT_F_WALK_EABT]              = "SMMU_EVT_F_WALK_EABT",
412bb981004SEric Auger     [SMMU_EVT_F_TRANSLATION]            = "SMMU_EVT_F_TRANSLATION",
413bb981004SEric Auger     [SMMU_EVT_F_ADDR_SIZE]              = "SMMU_EVT_F_ADDR_SIZE",
414bb981004SEric Auger     [SMMU_EVT_F_ACCESS]                 = "SMMU_EVT_F_ACCESS",
415bb981004SEric Auger     [SMMU_EVT_F_PERMISSION]             = "SMMU_EVT_F_PERMISSION",
416bb981004SEric Auger     [SMMU_EVT_F_TLB_CONFLICT]           = "SMMU_EVT_F_TLB_CONFLICT",
417bb981004SEric Auger     [SMMU_EVT_F_CFG_CONFLICT]           = "SMMU_EVT_F_CFG_CONFLICT",
418bb981004SEric Auger     [SMMU_EVT_E_PAGE_REQ]               = "SMMU_EVT_E_PAGE_REQ",
419bb981004SEric Auger };
420bb981004SEric Auger 
421bb981004SEric Auger static inline const char *smmu_event_string(SMMUEventType type)
422bb981004SEric Auger {
423bb981004SEric Auger     if (type < ARRAY_SIZE(event_stringify)) {
424bb981004SEric Auger         return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
425bb981004SEric Auger     } else {
426bb981004SEric Auger         return "INVALID";
427bb981004SEric Auger     }
428bb981004SEric Auger }
429bb981004SEric Auger 
430bb981004SEric Auger /*  Encode an event record */
431bb981004SEric Auger typedef struct SMMUEventInfo {
432bb981004SEric Auger     SMMUEventType type;
433bb981004SEric Auger     uint32_t sid;
434bb981004SEric Auger     bool recorded;
4353499ec08SEric Auger     bool inval_ste_allowed;
436bb981004SEric Auger     union {
437bb981004SEric Auger         struct {
438bb981004SEric Auger             uint32_t ssid;
439bb981004SEric Auger             bool ssv;
440bb981004SEric Auger             dma_addr_t addr;
441bb981004SEric Auger             bool rnw;
442bb981004SEric Auger             bool pnu;
443bb981004SEric Auger             bool ind;
444bb981004SEric Auger        } f_uut;
445bb981004SEric Auger        struct SSIDInfo {
446bb981004SEric Auger             uint32_t ssid;
447bb981004SEric Auger             bool ssv;
448bb981004SEric Auger        } c_bad_streamid;
449bb981004SEric Auger        struct SSIDAddrInfo {
450bb981004SEric Auger             uint32_t ssid;
451bb981004SEric Auger             bool ssv;
452bb981004SEric Auger             dma_addr_t addr;
453bb981004SEric Auger        } f_ste_fetch;
454bb981004SEric Auger        struct SSIDInfo c_bad_ste;
455bb981004SEric Auger        struct {
456bb981004SEric Auger             dma_addr_t addr;
457bb981004SEric Auger             bool rnw;
458bb981004SEric Auger        } f_transl_forbidden;
459bb981004SEric Auger        struct {
460bb981004SEric Auger             uint32_t ssid;
461bb981004SEric Auger        } c_bad_substream;
462bb981004SEric Auger        struct SSIDAddrInfo f_cd_fetch;
463bb981004SEric Auger        struct SSIDInfo c_bad_cd;
464bb981004SEric Auger        struct FullInfo {
465bb981004SEric Auger             bool stall;
466bb981004SEric Auger             uint16_t stag;
467bb981004SEric Auger             uint32_t ssid;
468bb981004SEric Auger             bool ssv;
469bb981004SEric Auger             bool s2;
470bb981004SEric Auger             dma_addr_t addr;
471bb981004SEric Auger             bool rnw;
472bb981004SEric Auger             bool pnu;
473bb981004SEric Auger             bool ind;
474bb981004SEric Auger             uint8_t class;
475bb981004SEric Auger             dma_addr_t addr2;
476bb981004SEric Auger        } f_walk_eabt;
477bb981004SEric Auger        struct FullInfo f_translation;
478bb981004SEric Auger        struct FullInfo f_addr_size;
479bb981004SEric Auger        struct FullInfo f_access;
480bb981004SEric Auger        struct FullInfo f_permission;
481bb981004SEric Auger        struct SSIDInfo f_cfg_conflict;
482bb981004SEric Auger        /**
483bb981004SEric Auger         * not supported yet:
484bb981004SEric Auger         * F_BAD_ATS_TREQ
485bb981004SEric Auger         * F_BAD_ATS_TREQ
486bb981004SEric Auger         * F_TLB_CONFLICT
487bb981004SEric Auger         * E_PAGE_REQUEST
488bb981004SEric Auger         * IMPDEF_EVENTn
489bb981004SEric Auger         */
490bb981004SEric Auger     } u;
491bb981004SEric Auger } SMMUEventInfo;
492bb981004SEric Auger 
493bb981004SEric Auger /* EVTQ fields */
494bb981004SEric Auger 
495bb981004SEric Auger #define EVT_Q_OVERFLOW        (1 << 31)
496bb981004SEric Auger 
4979f4d2a13SEric Auger #define EVT_SET_TYPE(x, v)  ((x)->word[0] = deposit32((x)->word[0], 0 , 8 , v))
4989f4d2a13SEric Auger #define EVT_SET_SSV(x, v)   ((x)->word[0] = deposit32((x)->word[0], 11, 1 , v))
4999f4d2a13SEric Auger #define EVT_SET_SSID(x, v)  ((x)->word[0] = deposit32((x)->word[0], 12, 20, v))
500bb981004SEric Auger #define EVT_SET_SID(x, v)   ((x)->word[1] = v)
5019f4d2a13SEric Auger #define EVT_SET_STAG(x, v)  ((x)->word[2] = deposit32((x)->word[2], 0 , 16, v))
5029f4d2a13SEric Auger #define EVT_SET_STALL(x, v) ((x)->word[2] = deposit32((x)->word[2], 31, 1 , v))
5039f4d2a13SEric Auger #define EVT_SET_PNU(x, v)   ((x)->word[3] = deposit32((x)->word[3], 1 , 1 , v))
5049f4d2a13SEric Auger #define EVT_SET_IND(x, v)   ((x)->word[3] = deposit32((x)->word[3], 2 , 1 , v))
5059f4d2a13SEric Auger #define EVT_SET_RNW(x, v)   ((x)->word[3] = deposit32((x)->word[3], 3 , 1 , v))
5069f4d2a13SEric Auger #define EVT_SET_S2(x, v)    ((x)->word[3] = deposit32((x)->word[3], 7 , 1 , v))
5079f4d2a13SEric Auger #define EVT_SET_CLASS(x, v) ((x)->word[3] = deposit32((x)->word[3], 8 , 2 , v))
508bb981004SEric Auger #define EVT_SET_ADDR(x, addr)                             \
509bb981004SEric Auger     do {                                                  \
510bb981004SEric Auger             (x)->word[5] = (uint32_t)(addr >> 32);        \
511bb981004SEric Auger             (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
512bb981004SEric Auger     } while (0)
513bb981004SEric Auger #define EVT_SET_ADDR2(x, addr)                            \
514bb981004SEric Auger     do {                                                  \
515a7f65cebSSimon Veith             (x)->word[7] = (uint32_t)(addr >> 32);        \
516a7f65cebSSimon Veith             (x)->word[6] = (uint32_t)(addr & 0xffffffff); \
517bb981004SEric Auger     } while (0)
518bb981004SEric Auger 
519bb981004SEric Auger void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
520bb981004SEric Auger 
5219bde7f06SEric Auger /* Configuration Data */
5229bde7f06SEric Auger 
5239bde7f06SEric Auger /* STE Level 1 Descriptor */
5249bde7f06SEric Auger typedef struct STEDesc {
5259bde7f06SEric Auger     uint32_t word[2];
5269bde7f06SEric Auger } STEDesc;
5279bde7f06SEric Auger 
5289bde7f06SEric Auger /* CD Level 1 Descriptor */
5299bde7f06SEric Auger typedef struct CDDesc {
5309bde7f06SEric Auger     uint32_t word[2];
5319bde7f06SEric Auger } CDDesc;
5329bde7f06SEric Auger 
5339bde7f06SEric Auger /* Stream Table Entry(STE) */
5349bde7f06SEric Auger typedef struct STE {
5359bde7f06SEric Auger     uint32_t word[16];
5369bde7f06SEric Auger } STE;
5379bde7f06SEric Auger 
5389bde7f06SEric Auger /* Context Descriptor(CD) */
5399bde7f06SEric Auger typedef struct CD {
5409bde7f06SEric Auger     uint32_t word[16];
5419bde7f06SEric Auger } CD;
5429bde7f06SEric Auger 
5439bde7f06SEric Auger /* STE fields */
5449bde7f06SEric Auger 
5459bde7f06SEric Auger #define STE_VALID(x)   extract32((x)->word[0], 0, 1)
5469bde7f06SEric Auger 
5479bde7f06SEric Auger #define STE_CONFIG(x)  extract32((x)->word[0], 1, 3)
5489bde7f06SEric Auger #define STE_CFG_S1_ENABLED(config) (config & 0x1)
5499bde7f06SEric Auger #define STE_CFG_S2_ENABLED(config) (config & 0x2)
5509bde7f06SEric Auger #define STE_CFG_ABORT(config)      (!(config & 0x4))
5519bde7f06SEric Auger #define STE_CFG_BYPASS(config)     (config == 0x4)
5529bde7f06SEric Auger 
5539bde7f06SEric Auger #define STE_S1FMT(x)       extract32((x)->word[0], 4 , 2)
5549bde7f06SEric Auger #define STE_S1CDMAX(x)     extract32((x)->word[1], 27, 5)
5559bde7f06SEric Auger #define STE_S1STALLD(x)    extract32((x)->word[2], 27, 1)
5569bde7f06SEric Auger #define STE_EATS(x)        extract32((x)->word[2], 28, 2)
5579bde7f06SEric Auger #define STE_STRW(x)        extract32((x)->word[2], 30, 2)
5589bde7f06SEric Auger #define STE_S2VMID(x)      extract32((x)->word[4], 0 , 16)
5599bde7f06SEric Auger #define STE_S2T0SZ(x)      extract32((x)->word[5], 0 , 6)
5609bde7f06SEric Auger #define STE_S2SL0(x)       extract32((x)->word[5], 6 , 2)
5619bde7f06SEric Auger #define STE_S2TG(x)        extract32((x)->word[5], 14, 2)
5629bde7f06SEric Auger #define STE_S2PS(x)        extract32((x)->word[5], 16, 3)
5639bde7f06SEric Auger #define STE_S2AA64(x)      extract32((x)->word[5], 19, 1)
56421eb5b5cSMostafa Saleh #define STE_S2ENDI(x)      extract32((x)->word[5], 20, 1)
56521eb5b5cSMostafa Saleh #define STE_S2AFFD(x)      extract32((x)->word[5], 21, 1)
56621eb5b5cSMostafa Saleh #define STE_S2HD(x)        extract32((x)->word[5], 23, 1)
56721eb5b5cSMostafa Saleh #define STE_S2HA(x)        extract32((x)->word[5], 24, 1)
56821eb5b5cSMostafa Saleh #define STE_S2S(x)         extract32((x)->word[5], 25, 1)
56921eb5b5cSMostafa Saleh #define STE_S2R(x)         extract32((x)->word[5], 26, 1)
57021eb5b5cSMostafa Saleh 
5719bde7f06SEric Auger #define STE_CTXPTR(x)                                   \
57284abccddSPeter Maydell     ((extract64((x)->word[1], 0, 16) << 32) |           \
57384abccddSPeter Maydell      ((x)->word[0] & 0xffffffc0))
5749bde7f06SEric Auger 
5759bde7f06SEric Auger #define STE_S2TTB(x)                                    \
57684abccddSPeter Maydell     ((extract64((x)->word[7], 0, 16) << 32) |           \
57784abccddSPeter Maydell      ((x)->word[6] & 0xfffffff0))
5789bde7f06SEric Auger 
5799bde7f06SEric Auger static inline int oas2bits(int oas_field)
5809bde7f06SEric Auger {
5819bde7f06SEric Auger     switch (oas_field) {
5829bde7f06SEric Auger     case 0:
5839bde7f06SEric Auger         return 32;
5849bde7f06SEric Auger     case 1:
5859bde7f06SEric Auger         return 36;
5869bde7f06SEric Auger     case 2:
5879bde7f06SEric Auger         return 40;
5889bde7f06SEric Auger     case 3:
5899bde7f06SEric Auger         return 42;
5909bde7f06SEric Auger     case 4:
5919bde7f06SEric Auger         return 44;
5929bde7f06SEric Auger     case 5:
5939bde7f06SEric Auger         return 48;
5949bde7f06SEric Auger     }
5959bde7f06SEric Auger     return -1;
5969bde7f06SEric Auger }
5979bde7f06SEric Auger 
5989bde7f06SEric Auger static inline int pa_range(STE *ste)
5999bde7f06SEric Auger {
6009bde7f06SEric Auger     int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
6019bde7f06SEric Auger 
6029bde7f06SEric Auger     if (!STE_S2AA64(ste)) {
6039bde7f06SEric Auger         return 40;
6049bde7f06SEric Auger     }
6059bde7f06SEric Auger 
6069bde7f06SEric Auger     return oas2bits(oas_field);
6079bde7f06SEric Auger }
6089bde7f06SEric Auger 
6099bde7f06SEric Auger #define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
6109bde7f06SEric Auger 
6119bde7f06SEric Auger /* CD fields */
6129bde7f06SEric Auger 
6131b41847aSJoe Komlodi #define CD_VALID(x)   extract32((x)->word[0], 31, 1)
6149bde7f06SEric Auger #define CD_ASID(x)    extract32((x)->word[1], 16, 16)
6159bde7f06SEric Auger #define CD_TTB(x, sel)                                          \
61684abccddSPeter Maydell     ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) |       \
61784abccddSPeter Maydell      ((x)->word[(sel) * 2 + 2] & ~0xfULL))
61884abccddSPeter Maydell 
619e7c3b9d9SEric Auger #define CD_HAD(x, sel)   extract32((x)->word[(sel) * 2 + 2], 1, 1)
6209bde7f06SEric Auger 
6219bde7f06SEric Auger #define CD_TSZ(x, sel)   extract32((x)->word[0], (16 * (sel)) + 0, 6)
6229bde7f06SEric Auger #define CD_TG(x, sel)    extract32((x)->word[0], (16 * (sel)) + 6, 2)
6239bde7f06SEric Auger #define CD_EPD(x, sel)   extract32((x)->word[0], (16 * (sel)) + 14, 1)
6249bde7f06SEric Auger #define CD_ENDI(x)       extract32((x)->word[0], 15, 1)
6259bde7f06SEric Auger #define CD_IPS(x)        extract32((x)->word[1], 0 , 3)
6269bde7f06SEric Auger #define CD_TBI(x)        extract32((x)->word[1], 6 , 2)
6279bde7f06SEric Auger #define CD_HD(x)         extract32((x)->word[1], 10 , 1)
6289bde7f06SEric Auger #define CD_HA(x)         extract32((x)->word[1], 11 , 1)
6299bde7f06SEric Auger #define CD_S(x)          extract32((x)->word[1], 12, 1)
6309bde7f06SEric Auger #define CD_R(x)          extract32((x)->word[1], 13, 1)
6319bde7f06SEric Auger #define CD_A(x)          extract32((x)->word[1], 14, 1)
6329bde7f06SEric Auger #define CD_AARCH64(x)    extract32((x)->word[1], 9 , 1)
6339bde7f06SEric Auger 
6349bde7f06SEric Auger /**
6359bde7f06SEric Auger  * tg2granule - Decodes the CD translation granule size field according
6369bde7f06SEric Auger  * to the ttbr in use
6379bde7f06SEric Auger  * @bits: TG0/1 fields
6389bde7f06SEric Auger  * @ttbr: ttbr index in use
6399bde7f06SEric Auger  */
6409bde7f06SEric Auger static inline int tg2granule(int bits, int ttbr)
6419bde7f06SEric Auger {
6429bde7f06SEric Auger     switch (bits) {
6439bde7f06SEric Auger     case 0:
6449bde7f06SEric Auger         return ttbr ? 0  : 12;
6459bde7f06SEric Auger     case 1:
6469bde7f06SEric Auger         return ttbr ? 14 : 16;
6479bde7f06SEric Auger     case 2:
6489bde7f06SEric Auger         return ttbr ? 12 : 14;
6499bde7f06SEric Auger     case 3:
6509bde7f06SEric Auger         return ttbr ? 16 :  0;
6519bde7f06SEric Auger     default:
6529bde7f06SEric Auger         return 0;
6539bde7f06SEric Auger     }
6549bde7f06SEric Auger }
6559bde7f06SEric Auger 
6569bde7f06SEric Auger static inline uint64_t l1std_l2ptr(STEDesc *desc)
6579bde7f06SEric Auger {
6589bde7f06SEric Auger     uint64_t hi, lo;
6599bde7f06SEric Auger 
6609bde7f06SEric Auger     hi = desc->word[1];
6619bde7f06SEric Auger     lo = desc->word[0] & ~0x1fULL;
6629bde7f06SEric Auger     return hi << 32 | lo;
6639bde7f06SEric Auger }
6649bde7f06SEric Auger 
665d9aad887SKunkun Jiang #define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
6669bde7f06SEric Auger 
66710a83cb9SPrem Mallappa #endif
668