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