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