xref: /qemu/hw/arm/smmuv3-internal.h (revision 263d0e48672c552c97cdbdbe2105d7b9fd0b133c)
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)
37*263d0e48SMostafa 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)
4110a83cb9SPrem Mallappa     FIELD(IDR0, ASID16,      12, 1)
42*263d0e48SMostafa Saleh     FIELD(IDR0, VMID16,      18, 1)
4310a83cb9SPrem Mallappa     FIELD(IDR0, TTENDIAN,    21, 2)
4410a83cb9SPrem Mallappa     FIELD(IDR0, STALL_MODEL, 24, 2)
4510a83cb9SPrem Mallappa     FIELD(IDR0, TERM_MODEL,  26, 1)
4610a83cb9SPrem Mallappa     FIELD(IDR0, STLEVEL,     27, 2)
4710a83cb9SPrem Mallappa 
4810a83cb9SPrem Mallappa REG32(IDR1,                0x4)
4910a83cb9SPrem Mallappa     FIELD(IDR1, SIDSIZE,      0 , 6)
5010a83cb9SPrem Mallappa     FIELD(IDR1, EVENTQS,      16, 5)
5110a83cb9SPrem Mallappa     FIELD(IDR1, CMDQS,        21, 5)
5210a83cb9SPrem Mallappa 
5310a83cb9SPrem Mallappa #define SMMU_IDR1_SIDSIZE 16
5410a83cb9SPrem Mallappa #define SMMU_CMDQS   19
5510a83cb9SPrem Mallappa #define SMMU_EVENTQS 19
5610a83cb9SPrem Mallappa 
5710a83cb9SPrem Mallappa REG32(IDR2,                0x8)
5810a83cb9SPrem Mallappa REG32(IDR3,                0xc)
59e7c3b9d9SEric Auger      FIELD(IDR3, HAD,         2, 1);
60de206dfdSEric Auger      FIELD(IDR3, RIL,        10, 1);
61f8e7163dSPeter Maydell      FIELD(IDR3, BBML,       11, 2);
6210a83cb9SPrem Mallappa REG32(IDR4,                0x10)
6310a83cb9SPrem Mallappa REG32(IDR5,                0x14)
6410a83cb9SPrem Mallappa      FIELD(IDR5, OAS,         0, 3);
6510a83cb9SPrem Mallappa      FIELD(IDR5, GRAN4K,      4, 1);
6610a83cb9SPrem Mallappa      FIELD(IDR5, GRAN16K,     5, 1);
6710a83cb9SPrem Mallappa      FIELD(IDR5, GRAN64K,     6, 1);
6810a83cb9SPrem Mallappa 
6910a83cb9SPrem Mallappa #define SMMU_IDR5_OAS 4
7010a83cb9SPrem Mallappa 
71f0ec277cSEric Auger REG32(IIDR,                0x18)
725888f0adSEric Auger REG32(AIDR,                0x1c)
7310a83cb9SPrem Mallappa REG32(CR0,                 0x20)
7410a83cb9SPrem Mallappa     FIELD(CR0, SMMU_ENABLE,   0, 1)
7510a83cb9SPrem Mallappa     FIELD(CR0, EVENTQEN,      2, 1)
7610a83cb9SPrem Mallappa     FIELD(CR0, CMDQEN,        3, 1)
7710a83cb9SPrem Mallappa 
78fae4be38SEric Auger #define SMMU_CR0_RESERVED 0xFFFFFC20
79fae4be38SEric Auger 
8010a83cb9SPrem Mallappa REG32(CR0ACK,              0x24)
8110a83cb9SPrem Mallappa REG32(CR1,                 0x28)
8210a83cb9SPrem Mallappa REG32(CR2,                 0x2c)
8310a83cb9SPrem Mallappa REG32(STATUSR,             0x40)
84c2ecb424SMostafa Saleh REG32(GBPA,                0x44)
85c2ecb424SMostafa Saleh     FIELD(GBPA, ABORT,        20, 1)
86c2ecb424SMostafa Saleh     FIELD(GBPA, UPDATE,       31, 1)
87c2ecb424SMostafa Saleh 
88c2ecb424SMostafa Saleh /* Use incoming. */
89c2ecb424SMostafa Saleh #define SMMU_GBPA_RESET_VAL 0x1000
90c2ecb424SMostafa Saleh 
9110a83cb9SPrem Mallappa REG32(IRQ_CTRL,            0x50)
9210a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, GERROR_IRQEN,        0, 1)
9310a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, PRI_IRQEN,           1, 1)
9410a83cb9SPrem Mallappa     FIELD(IRQ_CTRL, EVENTQ_IRQEN,        2, 1)
9510a83cb9SPrem Mallappa 
9610a83cb9SPrem Mallappa REG32(IRQ_CTRL_ACK,        0x54)
9710a83cb9SPrem Mallappa REG32(GERROR,              0x60)
9810a83cb9SPrem Mallappa     FIELD(GERROR, CMDQ_ERR,           0, 1)
9910a83cb9SPrem Mallappa     FIELD(GERROR, EVENTQ_ABT_ERR,     2, 1)
10010a83cb9SPrem Mallappa     FIELD(GERROR, PRIQ_ABT_ERR,       3, 1)
10110a83cb9SPrem Mallappa     FIELD(GERROR, MSI_CMDQ_ABT_ERR,   4, 1)
10210a83cb9SPrem Mallappa     FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
10310a83cb9SPrem Mallappa     FIELD(GERROR, MSI_PRIQ_ABT_ERR,   6, 1)
10410a83cb9SPrem Mallappa     FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
10510a83cb9SPrem Mallappa     FIELD(GERROR, MSI_SFM_ERR,        8, 1)
10610a83cb9SPrem Mallappa 
10710a83cb9SPrem Mallappa REG32(GERRORN,             0x64)
10810a83cb9SPrem Mallappa 
10910a83cb9SPrem Mallappa #define A_GERROR_IRQ_CFG0  0x68 /* 64b */
11010a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG1, 0x70)
11110a83cb9SPrem Mallappa REG32(GERROR_IRQ_CFG2, 0x74)
11210a83cb9SPrem Mallappa 
11310a83cb9SPrem Mallappa #define A_STRTAB_BASE      0x80 /* 64b */
11410a83cb9SPrem Mallappa 
1153293b9f5SSimon Veith #define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
11610a83cb9SPrem Mallappa 
11710a83cb9SPrem Mallappa REG32(STRTAB_BASE_CFG,     0x88)
11810a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, FMT,      16, 2)
11910a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, SPLIT,    6 , 5)
12010a83cb9SPrem Mallappa     FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
12110a83cb9SPrem Mallappa 
12210a83cb9SPrem Mallappa #define A_CMDQ_BASE        0x90 /* 64b */
12310a83cb9SPrem Mallappa REG32(CMDQ_PROD,           0x98)
12410a83cb9SPrem Mallappa REG32(CMDQ_CONS,           0x9c)
12510a83cb9SPrem Mallappa     FIELD(CMDQ_CONS, ERR, 24, 7)
12610a83cb9SPrem Mallappa 
12710a83cb9SPrem Mallappa #define A_EVENTQ_BASE      0xa0 /* 64b */
12810a83cb9SPrem Mallappa REG32(EVENTQ_PROD,         0xa8)
12910a83cb9SPrem Mallappa REG32(EVENTQ_CONS,         0xac)
13010a83cb9SPrem Mallappa 
13110a83cb9SPrem Mallappa #define A_EVENTQ_IRQ_CFG0  0xb0 /* 64b */
13210a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG1,     0xb8)
13310a83cb9SPrem Mallappa REG32(EVENTQ_IRQ_CFG2,     0xbc)
13410a83cb9SPrem Mallappa 
13510a83cb9SPrem Mallappa #define A_IDREGS           0xfd0
13610a83cb9SPrem Mallappa 
13710a83cb9SPrem Mallappa static inline int smmu_enabled(SMMUv3State *s)
13810a83cb9SPrem Mallappa {
13910a83cb9SPrem Mallappa     return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
14010a83cb9SPrem Mallappa }
14110a83cb9SPrem Mallappa 
14210a83cb9SPrem Mallappa /* Command Queue Entry */
14310a83cb9SPrem Mallappa typedef struct Cmd {
14410a83cb9SPrem Mallappa     uint32_t word[4];
14510a83cb9SPrem Mallappa } Cmd;
14610a83cb9SPrem Mallappa 
14710a83cb9SPrem Mallappa /* Event Queue Entry */
14810a83cb9SPrem Mallappa typedef struct Evt  {
14910a83cb9SPrem Mallappa     uint32_t word[8];
15010a83cb9SPrem Mallappa } Evt;
15110a83cb9SPrem Mallappa 
15210a83cb9SPrem Mallappa static inline uint32_t smmuv3_idreg(int regoffset)
15310a83cb9SPrem Mallappa {
15410a83cb9SPrem Mallappa     /*
15510a83cb9SPrem Mallappa      * Return the value of the Primecell/Corelink ID registers at the
15610a83cb9SPrem Mallappa      * specified offset from the first ID register.
15710a83cb9SPrem Mallappa      * These value indicate an ARM implementation of MMU600 p1
15810a83cb9SPrem Mallappa      */
15910a83cb9SPrem Mallappa     static const uint8_t smmuv3_ids[] = {
16010a83cb9SPrem Mallappa         0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
16110a83cb9SPrem Mallappa     };
16210a83cb9SPrem Mallappa     return smmuv3_ids[regoffset / 4];
16310a83cb9SPrem Mallappa }
16410a83cb9SPrem Mallappa 
1656a736033SEric Auger static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
1666a736033SEric Auger {
1676a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
1686a736033SEric Auger }
1696a736033SEric Auger 
1706a736033SEric Auger static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
1716a736033SEric Auger {
1726a736033SEric Auger     return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
1736a736033SEric Auger }
1746a736033SEric Auger 
175dadd1a08SEric Auger /* Queue Handling */
176dadd1a08SEric Auger 
177dadd1a08SEric Auger #define Q_BASE(q)          ((q)->base & SMMU_BASE_ADDR_MASK)
178dadd1a08SEric Auger #define WRAP_MASK(q)       (1 << (q)->log2size)
179dadd1a08SEric Auger #define INDEX_MASK(q)      (((1 << (q)->log2size)) - 1)
180dadd1a08SEric Auger #define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
181dadd1a08SEric Auger 
182dadd1a08SEric Auger #define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
183dadd1a08SEric Auger #define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
184dadd1a08SEric Auger 
185dadd1a08SEric Auger #define Q_CONS_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
186dadd1a08SEric Auger #define Q_PROD_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
187dadd1a08SEric Auger 
188dadd1a08SEric Auger #define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
189dadd1a08SEric Auger #define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
190dadd1a08SEric Auger 
191dadd1a08SEric Auger static inline bool smmuv3_q_full(SMMUQueue *q)
192dadd1a08SEric Auger {
193dadd1a08SEric Auger     return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
194dadd1a08SEric Auger }
195dadd1a08SEric Auger 
196dadd1a08SEric Auger static inline bool smmuv3_q_empty(SMMUQueue *q)
197dadd1a08SEric Auger {
198dadd1a08SEric Auger     return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
199dadd1a08SEric Auger }
200dadd1a08SEric Auger 
201dadd1a08SEric Auger static inline void queue_prod_incr(SMMUQueue *q)
202dadd1a08SEric Auger {
203dadd1a08SEric Auger     q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
204dadd1a08SEric Auger }
205dadd1a08SEric Auger 
206dadd1a08SEric Auger static inline void queue_cons_incr(SMMUQueue *q)
207dadd1a08SEric Auger {
208dadd1a08SEric Auger     /*
209dadd1a08SEric Auger      * We have to use deposit for the CONS registers to preserve
210dadd1a08SEric Auger      * the ERR field in the high bits.
211dadd1a08SEric Auger      */
212dadd1a08SEric Auger     q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
213dadd1a08SEric Auger }
214dadd1a08SEric Auger 
215dadd1a08SEric Auger static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
216dadd1a08SEric Auger {
217dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, CMDQEN);
218dadd1a08SEric Auger }
219dadd1a08SEric Auger 
220dadd1a08SEric Auger static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
221dadd1a08SEric Auger {
222dadd1a08SEric Auger     return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
223dadd1a08SEric Auger }
224dadd1a08SEric Auger 
225dadd1a08SEric Auger static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
226dadd1a08SEric Auger {
227dadd1a08SEric Auger     s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
228dadd1a08SEric Auger }
229dadd1a08SEric Auger 
230dadd1a08SEric Auger /* Commands */
231dadd1a08SEric Auger 
232dadd1a08SEric Auger typedef enum SMMUCommandType {
233dadd1a08SEric Auger     SMMU_CMD_NONE            = 0x00,
234dadd1a08SEric Auger     SMMU_CMD_PREFETCH_CONFIG       ,
235dadd1a08SEric Auger     SMMU_CMD_PREFETCH_ADDR,
236dadd1a08SEric Auger     SMMU_CMD_CFGI_STE,
237dadd1a08SEric Auger     SMMU_CMD_CFGI_STE_RANGE,
238dadd1a08SEric Auger     SMMU_CMD_CFGI_CD,
239dadd1a08SEric Auger     SMMU_CMD_CFGI_CD_ALL,
240dadd1a08SEric Auger     SMMU_CMD_CFGI_ALL,
241dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ALL     = 0x10,
242dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_ASID,
243dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VA,
244dadd1a08SEric Auger     SMMU_CMD_TLBI_NH_VAA,
245dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_ALL    = 0x18,
246dadd1a08SEric Auger     SMMU_CMD_TLBI_EL3_VA     = 0x1a,
247dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ALL    = 0x20,
248dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_ASID,
249dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VA,
250dadd1a08SEric Auger     SMMU_CMD_TLBI_EL2_VAA,
251dadd1a08SEric Auger     SMMU_CMD_TLBI_S12_VMALL  = 0x28,
252dadd1a08SEric Auger     SMMU_CMD_TLBI_S2_IPA     = 0x2a,
253dadd1a08SEric Auger     SMMU_CMD_TLBI_NSNH_ALL   = 0x30,
254dadd1a08SEric Auger     SMMU_CMD_ATC_INV         = 0x40,
255dadd1a08SEric Auger     SMMU_CMD_PRI_RESP,
256dadd1a08SEric Auger     SMMU_CMD_RESUME          = 0x44,
257dadd1a08SEric Auger     SMMU_CMD_STALL_TERM,
258dadd1a08SEric Auger     SMMU_CMD_SYNC,
259dadd1a08SEric Auger } SMMUCommandType;
260dadd1a08SEric Auger 
261dadd1a08SEric Auger static const char *cmd_stringify[] = {
262dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
263dadd1a08SEric Auger     [SMMU_CMD_PREFETCH_ADDR]   = "SMMU_CMD_PREFETCH_ADDR",
264dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE]        = "SMMU_CMD_CFGI_STE",
265dadd1a08SEric Auger     [SMMU_CMD_CFGI_STE_RANGE]  = "SMMU_CMD_CFGI_STE_RANGE",
266dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD]         = "SMMU_CMD_CFGI_CD",
267dadd1a08SEric Auger     [SMMU_CMD_CFGI_CD_ALL]     = "SMMU_CMD_CFGI_CD_ALL",
268dadd1a08SEric Auger     [SMMU_CMD_CFGI_ALL]        = "SMMU_CMD_CFGI_ALL",
269dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ALL]     = "SMMU_CMD_TLBI_NH_ALL",
270dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_ASID]    = "SMMU_CMD_TLBI_NH_ASID",
271dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VA]      = "SMMU_CMD_TLBI_NH_VA",
272dadd1a08SEric Auger     [SMMU_CMD_TLBI_NH_VAA]     = "SMMU_CMD_TLBI_NH_VAA",
273dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_ALL]    = "SMMU_CMD_TLBI_EL3_ALL",
274dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL3_VA]     = "SMMU_CMD_TLBI_EL3_VA",
275dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ALL]    = "SMMU_CMD_TLBI_EL2_ALL",
276dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_ASID]   = "SMMU_CMD_TLBI_EL2_ASID",
277dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VA]     = "SMMU_CMD_TLBI_EL2_VA",
278dadd1a08SEric Auger     [SMMU_CMD_TLBI_EL2_VAA]    = "SMMU_CMD_TLBI_EL2_VAA",
279dadd1a08SEric Auger     [SMMU_CMD_TLBI_S12_VMALL]  = "SMMU_CMD_TLBI_S12_VMALL",
280dadd1a08SEric Auger     [SMMU_CMD_TLBI_S2_IPA]     = "SMMU_CMD_TLBI_S2_IPA",
281dadd1a08SEric Auger     [SMMU_CMD_TLBI_NSNH_ALL]   = "SMMU_CMD_TLBI_NSNH_ALL",
282dadd1a08SEric Auger     [SMMU_CMD_ATC_INV]         = "SMMU_CMD_ATC_INV",
283dadd1a08SEric Auger     [SMMU_CMD_PRI_RESP]        = "SMMU_CMD_PRI_RESP",
284dadd1a08SEric Auger     [SMMU_CMD_RESUME]          = "SMMU_CMD_RESUME",
285dadd1a08SEric Auger     [SMMU_CMD_STALL_TERM]      = "SMMU_CMD_STALL_TERM",
286dadd1a08SEric Auger     [SMMU_CMD_SYNC]            = "SMMU_CMD_SYNC",
287dadd1a08SEric Auger };
288dadd1a08SEric Auger 
289dadd1a08SEric Auger static inline const char *smmu_cmd_string(SMMUCommandType type)
290dadd1a08SEric Auger {
291dadd1a08SEric Auger     if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
292dadd1a08SEric Auger         return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
293dadd1a08SEric Auger     } else {
294dadd1a08SEric Auger         return "INVALID";
295dadd1a08SEric Auger     }
296dadd1a08SEric Auger }
297dadd1a08SEric Auger 
298dadd1a08SEric Auger /* CMDQ fields */
299dadd1a08SEric Auger 
300dadd1a08SEric Auger typedef enum {
301dadd1a08SEric Auger     SMMU_CERROR_NONE = 0,
302dadd1a08SEric Auger     SMMU_CERROR_ILL,
303dadd1a08SEric Auger     SMMU_CERROR_ABT,
304dadd1a08SEric Auger     SMMU_CERROR_ATC_INV_SYNC,
305dadd1a08SEric Auger } SMMUCmdError;
306dadd1a08SEric Auger 
307dadd1a08SEric Auger enum { /* Command completion notification */
308dadd1a08SEric Auger     CMD_SYNC_SIG_NONE,
309dadd1a08SEric Auger     CMD_SYNC_SIG_IRQ,
310dadd1a08SEric Auger     CMD_SYNC_SIG_SEV,
311dadd1a08SEric Auger };
312dadd1a08SEric Auger 
313dadd1a08SEric Auger #define CMD_TYPE(x)         extract32((x)->word[0], 0 , 8)
314d5291561SEric Auger #define CMD_NUM(x)          extract32((x)->word[0], 12 , 5)
315d5291561SEric Auger #define CMD_SCALE(x)        extract32((x)->word[0], 20 , 5)
316dadd1a08SEric Auger #define CMD_SSEC(x)         extract32((x)->word[0], 10, 1)
317dadd1a08SEric Auger #define CMD_SSV(x)          extract32((x)->word[0], 11, 1)
318dadd1a08SEric Auger #define CMD_RESUME_AC(x)    extract32((x)->word[0], 12, 1)
319dadd1a08SEric Auger #define CMD_RESUME_AB(x)    extract32((x)->word[0], 13, 1)
320dadd1a08SEric Auger #define CMD_SYNC_CS(x)      extract32((x)->word[0], 12, 2)
321dadd1a08SEric Auger #define CMD_SSID(x)         extract32((x)->word[0], 12, 20)
322dadd1a08SEric Auger #define CMD_SID(x)          ((x)->word[1])
323dadd1a08SEric Auger #define CMD_VMID(x)         extract32((x)->word[1], 0 , 16)
324dadd1a08SEric Auger #define CMD_ASID(x)         extract32((x)->word[1], 16, 16)
325dadd1a08SEric Auger #define CMD_RESUME_STAG(x)  extract32((x)->word[2], 0 , 16)
326dadd1a08SEric Auger #define CMD_RESP(x)         extract32((x)->word[2], 11, 2)
327dadd1a08SEric Auger #define CMD_LEAF(x)         extract32((x)->word[2], 0 , 1)
328d5291561SEric Auger #define CMD_TTL(x)          extract32((x)->word[2], 8 , 2)
329d5291561SEric Auger #define CMD_TG(x)           extract32((x)->word[2], 10, 2)
330dadd1a08SEric Auger #define CMD_STE_RANGE(x)    extract32((x)->word[2], 0 , 5)
331dadd1a08SEric Auger #define CMD_ADDR(x) ({                                        \
332dadd1a08SEric Auger             uint64_t high = (uint64_t)(x)->word[3];           \
333dadd1a08SEric Auger             uint64_t low = extract32((x)->word[2], 12, 20);    \
334dadd1a08SEric Auger             uint64_t addr = high << 32 | (low << 12);         \
335dadd1a08SEric Auger             addr;                                             \
336dadd1a08SEric Auger         })
337dadd1a08SEric Auger 
338fae4be38SEric Auger #define SMMU_FEATURE_2LVL_STE (1 << 0)
339dadd1a08SEric Auger 
340bb981004SEric Auger /* Events */
341bb981004SEric Auger 
342bb981004SEric Auger typedef enum SMMUEventType {
3439122bea9SJia He     SMMU_EVT_NONE               = 0x00,
344bb981004SEric Auger     SMMU_EVT_F_UUT                    ,
345bb981004SEric Auger     SMMU_EVT_C_BAD_STREAMID           ,
346bb981004SEric Auger     SMMU_EVT_F_STE_FETCH              ,
347bb981004SEric Auger     SMMU_EVT_C_BAD_STE                ,
348bb981004SEric Auger     SMMU_EVT_F_BAD_ATS_TREQ           ,
349bb981004SEric Auger     SMMU_EVT_F_STREAM_DISABLED        ,
350bb981004SEric Auger     SMMU_EVT_F_TRANS_FORBIDDEN        ,
351bb981004SEric Auger     SMMU_EVT_C_BAD_SUBSTREAMID        ,
352bb981004SEric Auger     SMMU_EVT_F_CD_FETCH               ,
353bb981004SEric Auger     SMMU_EVT_C_BAD_CD                 ,
354bb981004SEric Auger     SMMU_EVT_F_WALK_EABT              ,
355bb981004SEric Auger     SMMU_EVT_F_TRANSLATION      = 0x10,
356bb981004SEric Auger     SMMU_EVT_F_ADDR_SIZE              ,
357bb981004SEric Auger     SMMU_EVT_F_ACCESS                 ,
358bb981004SEric Auger     SMMU_EVT_F_PERMISSION             ,
359bb981004SEric Auger     SMMU_EVT_F_TLB_CONFLICT     = 0x20,
360bb981004SEric Auger     SMMU_EVT_F_CFG_CONFLICT           ,
361bb981004SEric Auger     SMMU_EVT_E_PAGE_REQ         = 0x24,
362bb981004SEric Auger } SMMUEventType;
363bb981004SEric Auger 
364bb981004SEric Auger static const char *event_stringify[] = {
3659122bea9SJia He     [SMMU_EVT_NONE]                     = "no recorded event",
366bb981004SEric Auger     [SMMU_EVT_F_UUT]                    = "SMMU_EVT_F_UUT",
367bb981004SEric Auger     [SMMU_EVT_C_BAD_STREAMID]           = "SMMU_EVT_C_BAD_STREAMID",
368bb981004SEric Auger     [SMMU_EVT_F_STE_FETCH]              = "SMMU_EVT_F_STE_FETCH",
369bb981004SEric Auger     [SMMU_EVT_C_BAD_STE]                = "SMMU_EVT_C_BAD_STE",
370bb981004SEric Auger     [SMMU_EVT_F_BAD_ATS_TREQ]           = "SMMU_EVT_F_BAD_ATS_TREQ",
371bb981004SEric Auger     [SMMU_EVT_F_STREAM_DISABLED]        = "SMMU_EVT_F_STREAM_DISABLED",
372bb981004SEric Auger     [SMMU_EVT_F_TRANS_FORBIDDEN]        = "SMMU_EVT_F_TRANS_FORBIDDEN",
373bb981004SEric Auger     [SMMU_EVT_C_BAD_SUBSTREAMID]        = "SMMU_EVT_C_BAD_SUBSTREAMID",
374bb981004SEric Auger     [SMMU_EVT_F_CD_FETCH]               = "SMMU_EVT_F_CD_FETCH",
375bb981004SEric Auger     [SMMU_EVT_C_BAD_CD]                 = "SMMU_EVT_C_BAD_CD",
376bb981004SEric Auger     [SMMU_EVT_F_WALK_EABT]              = "SMMU_EVT_F_WALK_EABT",
377bb981004SEric Auger     [SMMU_EVT_F_TRANSLATION]            = "SMMU_EVT_F_TRANSLATION",
378bb981004SEric Auger     [SMMU_EVT_F_ADDR_SIZE]              = "SMMU_EVT_F_ADDR_SIZE",
379bb981004SEric Auger     [SMMU_EVT_F_ACCESS]                 = "SMMU_EVT_F_ACCESS",
380bb981004SEric Auger     [SMMU_EVT_F_PERMISSION]             = "SMMU_EVT_F_PERMISSION",
381bb981004SEric Auger     [SMMU_EVT_F_TLB_CONFLICT]           = "SMMU_EVT_F_TLB_CONFLICT",
382bb981004SEric Auger     [SMMU_EVT_F_CFG_CONFLICT]           = "SMMU_EVT_F_CFG_CONFLICT",
383bb981004SEric Auger     [SMMU_EVT_E_PAGE_REQ]               = "SMMU_EVT_E_PAGE_REQ",
384bb981004SEric Auger };
385bb981004SEric Auger 
386bb981004SEric Auger static inline const char *smmu_event_string(SMMUEventType type)
387bb981004SEric Auger {
388bb981004SEric Auger     if (type < ARRAY_SIZE(event_stringify)) {
389bb981004SEric Auger         return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
390bb981004SEric Auger     } else {
391bb981004SEric Auger         return "INVALID";
392bb981004SEric Auger     }
393bb981004SEric Auger }
394bb981004SEric Auger 
395bb981004SEric Auger /*  Encode an event record */
396bb981004SEric Auger typedef struct SMMUEventInfo {
397bb981004SEric Auger     SMMUEventType type;
398bb981004SEric Auger     uint32_t sid;
399bb981004SEric Auger     bool recorded;
4003499ec08SEric Auger     bool inval_ste_allowed;
401bb981004SEric Auger     union {
402bb981004SEric Auger         struct {
403bb981004SEric Auger             uint32_t ssid;
404bb981004SEric Auger             bool ssv;
405bb981004SEric Auger             dma_addr_t addr;
406bb981004SEric Auger             bool rnw;
407bb981004SEric Auger             bool pnu;
408bb981004SEric Auger             bool ind;
409bb981004SEric Auger        } f_uut;
410bb981004SEric Auger        struct SSIDInfo {
411bb981004SEric Auger             uint32_t ssid;
412bb981004SEric Auger             bool ssv;
413bb981004SEric Auger        } c_bad_streamid;
414bb981004SEric Auger        struct SSIDAddrInfo {
415bb981004SEric Auger             uint32_t ssid;
416bb981004SEric Auger             bool ssv;
417bb981004SEric Auger             dma_addr_t addr;
418bb981004SEric Auger        } f_ste_fetch;
419bb981004SEric Auger        struct SSIDInfo c_bad_ste;
420bb981004SEric Auger        struct {
421bb981004SEric Auger             dma_addr_t addr;
422bb981004SEric Auger             bool rnw;
423bb981004SEric Auger        } f_transl_forbidden;
424bb981004SEric Auger        struct {
425bb981004SEric Auger             uint32_t ssid;
426bb981004SEric Auger        } c_bad_substream;
427bb981004SEric Auger        struct SSIDAddrInfo f_cd_fetch;
428bb981004SEric Auger        struct SSIDInfo c_bad_cd;
429bb981004SEric Auger        struct FullInfo {
430bb981004SEric Auger             bool stall;
431bb981004SEric Auger             uint16_t stag;
432bb981004SEric Auger             uint32_t ssid;
433bb981004SEric Auger             bool ssv;
434bb981004SEric Auger             bool s2;
435bb981004SEric Auger             dma_addr_t addr;
436bb981004SEric Auger             bool rnw;
437bb981004SEric Auger             bool pnu;
438bb981004SEric Auger             bool ind;
439bb981004SEric Auger             uint8_t class;
440bb981004SEric Auger             dma_addr_t addr2;
441bb981004SEric Auger        } f_walk_eabt;
442bb981004SEric Auger        struct FullInfo f_translation;
443bb981004SEric Auger        struct FullInfo f_addr_size;
444bb981004SEric Auger        struct FullInfo f_access;
445bb981004SEric Auger        struct FullInfo f_permission;
446bb981004SEric Auger        struct SSIDInfo f_cfg_conflict;
447bb981004SEric Auger        /**
448bb981004SEric Auger         * not supported yet:
449bb981004SEric Auger         * F_BAD_ATS_TREQ
450bb981004SEric Auger         * F_BAD_ATS_TREQ
451bb981004SEric Auger         * F_TLB_CONFLICT
452bb981004SEric Auger         * E_PAGE_REQUEST
453bb981004SEric Auger         * IMPDEF_EVENTn
454bb981004SEric Auger         */
455bb981004SEric Auger     } u;
456bb981004SEric Auger } SMMUEventInfo;
457bb981004SEric Auger 
458bb981004SEric Auger /* EVTQ fields */
459bb981004SEric Auger 
460bb981004SEric Auger #define EVT_Q_OVERFLOW        (1 << 31)
461bb981004SEric Auger 
4629f4d2a13SEric Auger #define EVT_SET_TYPE(x, v)  ((x)->word[0] = deposit32((x)->word[0], 0 , 8 , v))
4639f4d2a13SEric Auger #define EVT_SET_SSV(x, v)   ((x)->word[0] = deposit32((x)->word[0], 11, 1 , v))
4649f4d2a13SEric Auger #define EVT_SET_SSID(x, v)  ((x)->word[0] = deposit32((x)->word[0], 12, 20, v))
465bb981004SEric Auger #define EVT_SET_SID(x, v)   ((x)->word[1] = v)
4669f4d2a13SEric Auger #define EVT_SET_STAG(x, v)  ((x)->word[2] = deposit32((x)->word[2], 0 , 16, v))
4679f4d2a13SEric Auger #define EVT_SET_STALL(x, v) ((x)->word[2] = deposit32((x)->word[2], 31, 1 , v))
4689f4d2a13SEric Auger #define EVT_SET_PNU(x, v)   ((x)->word[3] = deposit32((x)->word[3], 1 , 1 , v))
4699f4d2a13SEric Auger #define EVT_SET_IND(x, v)   ((x)->word[3] = deposit32((x)->word[3], 2 , 1 , v))
4709f4d2a13SEric Auger #define EVT_SET_RNW(x, v)   ((x)->word[3] = deposit32((x)->word[3], 3 , 1 , v))
4719f4d2a13SEric Auger #define EVT_SET_S2(x, v)    ((x)->word[3] = deposit32((x)->word[3], 7 , 1 , v))
4729f4d2a13SEric Auger #define EVT_SET_CLASS(x, v) ((x)->word[3] = deposit32((x)->word[3], 8 , 2 , v))
473bb981004SEric Auger #define EVT_SET_ADDR(x, addr)                             \
474bb981004SEric Auger     do {                                                  \
475bb981004SEric Auger             (x)->word[5] = (uint32_t)(addr >> 32);        \
476bb981004SEric Auger             (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
477bb981004SEric Auger     } while (0)
478bb981004SEric Auger #define EVT_SET_ADDR2(x, addr)                            \
479bb981004SEric Auger     do {                                                  \
480a7f65cebSSimon Veith             (x)->word[7] = (uint32_t)(addr >> 32);        \
481a7f65cebSSimon Veith             (x)->word[6] = (uint32_t)(addr & 0xffffffff); \
482bb981004SEric Auger     } while (0)
483bb981004SEric Auger 
484bb981004SEric Auger void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
485bb981004SEric Auger 
4869bde7f06SEric Auger /* Configuration Data */
4879bde7f06SEric Auger 
4889bde7f06SEric Auger /* STE Level 1 Descriptor */
4899bde7f06SEric Auger typedef struct STEDesc {
4909bde7f06SEric Auger     uint32_t word[2];
4919bde7f06SEric Auger } STEDesc;
4929bde7f06SEric Auger 
4939bde7f06SEric Auger /* CD Level 1 Descriptor */
4949bde7f06SEric Auger typedef struct CDDesc {
4959bde7f06SEric Auger     uint32_t word[2];
4969bde7f06SEric Auger } CDDesc;
4979bde7f06SEric Auger 
4989bde7f06SEric Auger /* Stream Table Entry(STE) */
4999bde7f06SEric Auger typedef struct STE {
5009bde7f06SEric Auger     uint32_t word[16];
5019bde7f06SEric Auger } STE;
5029bde7f06SEric Auger 
5039bde7f06SEric Auger /* Context Descriptor(CD) */
5049bde7f06SEric Auger typedef struct CD {
5059bde7f06SEric Auger     uint32_t word[16];
5069bde7f06SEric Auger } CD;
5079bde7f06SEric Auger 
5089bde7f06SEric Auger /* STE fields */
5099bde7f06SEric Auger 
5109bde7f06SEric Auger #define STE_VALID(x)   extract32((x)->word[0], 0, 1)
5119bde7f06SEric Auger 
5129bde7f06SEric Auger #define STE_CONFIG(x)  extract32((x)->word[0], 1, 3)
5139bde7f06SEric Auger #define STE_CFG_S1_ENABLED(config) (config & 0x1)
5149bde7f06SEric Auger #define STE_CFG_S2_ENABLED(config) (config & 0x2)
5159bde7f06SEric Auger #define STE_CFG_ABORT(config)      (!(config & 0x4))
5169bde7f06SEric Auger #define STE_CFG_BYPASS(config)     (config == 0x4)
5179bde7f06SEric Auger 
5189bde7f06SEric Auger #define STE_S1FMT(x)       extract32((x)->word[0], 4 , 2)
5199bde7f06SEric Auger #define STE_S1CDMAX(x)     extract32((x)->word[1], 27, 5)
5209bde7f06SEric Auger #define STE_S1STALLD(x)    extract32((x)->word[2], 27, 1)
5219bde7f06SEric Auger #define STE_EATS(x)        extract32((x)->word[2], 28, 2)
5229bde7f06SEric Auger #define STE_STRW(x)        extract32((x)->word[2], 30, 2)
5239bde7f06SEric Auger #define STE_S2VMID(x)      extract32((x)->word[4], 0 , 16)
5249bde7f06SEric Auger #define STE_S2T0SZ(x)      extract32((x)->word[5], 0 , 6)
5259bde7f06SEric Auger #define STE_S2SL0(x)       extract32((x)->word[5], 6 , 2)
5269bde7f06SEric Auger #define STE_S2TG(x)        extract32((x)->word[5], 14, 2)
5279bde7f06SEric Auger #define STE_S2PS(x)        extract32((x)->word[5], 16, 3)
5289bde7f06SEric Auger #define STE_S2AA64(x)      extract32((x)->word[5], 19, 1)
5299bde7f06SEric Auger #define STE_S2HD(x)        extract32((x)->word[5], 24, 1)
5309bde7f06SEric Auger #define STE_S2HA(x)        extract32((x)->word[5], 25, 1)
5319bde7f06SEric Auger #define STE_S2S(x)         extract32((x)->word[5], 26, 1)
5329bde7f06SEric Auger #define STE_CTXPTR(x)                                           \
5339bde7f06SEric Auger     ({                                                          \
5349bde7f06SEric Auger         unsigned long addr;                                     \
5359bde7f06SEric Auger         addr = (uint64_t)extract32((x)->word[1], 0, 16) << 32;  \
5369bde7f06SEric Auger         addr |= (uint64_t)((x)->word[0] & 0xffffffc0);          \
5379bde7f06SEric Auger         addr;                                                   \
5389bde7f06SEric Auger     })
5399bde7f06SEric Auger 
5409bde7f06SEric Auger #define STE_S2TTB(x)                                            \
5419bde7f06SEric Auger     ({                                                          \
5429bde7f06SEric Auger         unsigned long addr;                                     \
5439bde7f06SEric Auger         addr = (uint64_t)extract32((x)->word[7], 0, 16) << 32;  \
5449bde7f06SEric Auger         addr |= (uint64_t)((x)->word[6] & 0xfffffff0);          \
5459bde7f06SEric Auger         addr;                                                   \
5469bde7f06SEric Auger     })
5479bde7f06SEric Auger 
5489bde7f06SEric Auger static inline int oas2bits(int oas_field)
5499bde7f06SEric Auger {
5509bde7f06SEric Auger     switch (oas_field) {
5519bde7f06SEric Auger     case 0:
5529bde7f06SEric Auger         return 32;
5539bde7f06SEric Auger     case 1:
5549bde7f06SEric Auger         return 36;
5559bde7f06SEric Auger     case 2:
5569bde7f06SEric Auger         return 40;
5579bde7f06SEric Auger     case 3:
5589bde7f06SEric Auger         return 42;
5599bde7f06SEric Auger     case 4:
5609bde7f06SEric Auger         return 44;
5619bde7f06SEric Auger     case 5:
5629bde7f06SEric Auger         return 48;
5639bde7f06SEric Auger     }
5649bde7f06SEric Auger     return -1;
5659bde7f06SEric Auger }
5669bde7f06SEric Auger 
5679bde7f06SEric Auger static inline int pa_range(STE *ste)
5689bde7f06SEric Auger {
5699bde7f06SEric Auger     int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
5709bde7f06SEric Auger 
5719bde7f06SEric Auger     if (!STE_S2AA64(ste)) {
5729bde7f06SEric Auger         return 40;
5739bde7f06SEric Auger     }
5749bde7f06SEric Auger 
5759bde7f06SEric Auger     return oas2bits(oas_field);
5769bde7f06SEric Auger }
5779bde7f06SEric Auger 
5789bde7f06SEric Auger #define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
5799bde7f06SEric Auger 
5809bde7f06SEric Auger /* CD fields */
5819bde7f06SEric Auger 
5821b41847aSJoe Komlodi #define CD_VALID(x)   extract32((x)->word[0], 31, 1)
5839bde7f06SEric Auger #define CD_ASID(x)    extract32((x)->word[1], 16, 16)
5849bde7f06SEric Auger #define CD_TTB(x, sel)                                      \
5859bde7f06SEric Auger     ({                                                      \
5869bde7f06SEric Auger         uint64_t hi, lo;                                    \
5879bde7f06SEric Auger         hi = extract32((x)->word[(sel) * 2 + 3], 0, 19);    \
5889bde7f06SEric Auger         hi <<= 32;                                          \
5899bde7f06SEric Auger         lo = (x)->word[(sel) * 2 + 2] & ~0xfULL;            \
5909bde7f06SEric Auger         hi | lo;                                            \
5919bde7f06SEric Auger     })
592e7c3b9d9SEric Auger #define CD_HAD(x, sel)   extract32((x)->word[(sel) * 2 + 2], 1, 1)
5939bde7f06SEric Auger 
5949bde7f06SEric Auger #define CD_TSZ(x, sel)   extract32((x)->word[0], (16 * (sel)) + 0, 6)
5959bde7f06SEric Auger #define CD_TG(x, sel)    extract32((x)->word[0], (16 * (sel)) + 6, 2)
5969bde7f06SEric Auger #define CD_EPD(x, sel)   extract32((x)->word[0], (16 * (sel)) + 14, 1)
5979bde7f06SEric Auger #define CD_ENDI(x)       extract32((x)->word[0], 15, 1)
5989bde7f06SEric Auger #define CD_IPS(x)        extract32((x)->word[1], 0 , 3)
5999bde7f06SEric Auger #define CD_TBI(x)        extract32((x)->word[1], 6 , 2)
6009bde7f06SEric Auger #define CD_HD(x)         extract32((x)->word[1], 10 , 1)
6019bde7f06SEric Auger #define CD_HA(x)         extract32((x)->word[1], 11 , 1)
6029bde7f06SEric Auger #define CD_S(x)          extract32((x)->word[1], 12, 1)
6039bde7f06SEric Auger #define CD_R(x)          extract32((x)->word[1], 13, 1)
6049bde7f06SEric Auger #define CD_A(x)          extract32((x)->word[1], 14, 1)
6059bde7f06SEric Auger #define CD_AARCH64(x)    extract32((x)->word[1], 9 , 1)
6069bde7f06SEric Auger 
6079bde7f06SEric Auger /**
6089bde7f06SEric Auger  * tg2granule - Decodes the CD translation granule size field according
6099bde7f06SEric Auger  * to the ttbr in use
6109bde7f06SEric Auger  * @bits: TG0/1 fields
6119bde7f06SEric Auger  * @ttbr: ttbr index in use
6129bde7f06SEric Auger  */
6139bde7f06SEric Auger static inline int tg2granule(int bits, int ttbr)
6149bde7f06SEric Auger {
6159bde7f06SEric Auger     switch (bits) {
6169bde7f06SEric Auger     case 0:
6179bde7f06SEric Auger         return ttbr ? 0  : 12;
6189bde7f06SEric Auger     case 1:
6199bde7f06SEric Auger         return ttbr ? 14 : 16;
6209bde7f06SEric Auger     case 2:
6219bde7f06SEric Auger         return ttbr ? 12 : 14;
6229bde7f06SEric Auger     case 3:
6239bde7f06SEric Auger         return ttbr ? 16 :  0;
6249bde7f06SEric Auger     default:
6259bde7f06SEric Auger         return 0;
6269bde7f06SEric Auger     }
6279bde7f06SEric Auger }
6289bde7f06SEric Auger 
6299bde7f06SEric Auger static inline uint64_t l1std_l2ptr(STEDesc *desc)
6309bde7f06SEric Auger {
6319bde7f06SEric Auger     uint64_t hi, lo;
6329bde7f06SEric Auger 
6339bde7f06SEric Auger     hi = desc->word[1];
6349bde7f06SEric Auger     lo = desc->word[0] & ~0x1fULL;
6359bde7f06SEric Auger     return hi << 32 | lo;
6369bde7f06SEric Auger }
6379bde7f06SEric Auger 
638d9aad887SKunkun Jiang #define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
6399bde7f06SEric Auger 
64010a83cb9SPrem Mallappa #endif
641