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_SMMU_V3_INTERNAL_H 22 #define HW_ARM_SMMU_V3_INTERNAL_H 23 24 #include "hw/arm/smmu-common.h" 25 26 /* MMIO Registers */ 27 28 REG32(IDR0, 0x0) 29 FIELD(IDR0, S1P, 1 , 1) 30 FIELD(IDR0, TTF, 2 , 2) 31 FIELD(IDR0, COHACC, 4 , 1) 32 FIELD(IDR0, ASID16, 12, 1) 33 FIELD(IDR0, TTENDIAN, 21, 2) 34 FIELD(IDR0, STALL_MODEL, 24, 2) 35 FIELD(IDR0, TERM_MODEL, 26, 1) 36 FIELD(IDR0, STLEVEL, 27, 2) 37 38 REG32(IDR1, 0x4) 39 FIELD(IDR1, SIDSIZE, 0 , 6) 40 FIELD(IDR1, EVENTQS, 16, 5) 41 FIELD(IDR1, CMDQS, 21, 5) 42 43 #define SMMU_IDR1_SIDSIZE 16 44 #define SMMU_CMDQS 19 45 #define SMMU_EVENTQS 19 46 47 REG32(IDR2, 0x8) 48 REG32(IDR3, 0xc) 49 REG32(IDR4, 0x10) 50 REG32(IDR5, 0x14) 51 FIELD(IDR5, OAS, 0, 3); 52 FIELD(IDR5, GRAN4K, 4, 1); 53 FIELD(IDR5, GRAN16K, 5, 1); 54 FIELD(IDR5, GRAN64K, 6, 1); 55 56 #define SMMU_IDR5_OAS 4 57 58 REG32(IIDR, 0x1c) 59 REG32(CR0, 0x20) 60 FIELD(CR0, SMMU_ENABLE, 0, 1) 61 FIELD(CR0, EVENTQEN, 2, 1) 62 FIELD(CR0, CMDQEN, 3, 1) 63 64 REG32(CR0ACK, 0x24) 65 REG32(CR1, 0x28) 66 REG32(CR2, 0x2c) 67 REG32(STATUSR, 0x40) 68 REG32(IRQ_CTRL, 0x50) 69 FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1) 70 FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1) 71 FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1) 72 73 REG32(IRQ_CTRL_ACK, 0x54) 74 REG32(GERROR, 0x60) 75 FIELD(GERROR, CMDQ_ERR, 0, 1) 76 FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1) 77 FIELD(GERROR, PRIQ_ABT_ERR, 3, 1) 78 FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1) 79 FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1) 80 FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1) 81 FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1) 82 FIELD(GERROR, MSI_SFM_ERR, 8, 1) 83 84 REG32(GERRORN, 0x64) 85 86 #define A_GERROR_IRQ_CFG0 0x68 /* 64b */ 87 REG32(GERROR_IRQ_CFG1, 0x70) 88 REG32(GERROR_IRQ_CFG2, 0x74) 89 90 #define A_STRTAB_BASE 0x80 /* 64b */ 91 92 #define SMMU_BASE_ADDR_MASK 0xffffffffffe0 93 94 REG32(STRTAB_BASE_CFG, 0x88) 95 FIELD(STRTAB_BASE_CFG, FMT, 16, 2) 96 FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5) 97 FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6) 98 99 #define A_CMDQ_BASE 0x90 /* 64b */ 100 REG32(CMDQ_PROD, 0x98) 101 REG32(CMDQ_CONS, 0x9c) 102 FIELD(CMDQ_CONS, ERR, 24, 7) 103 104 #define A_EVENTQ_BASE 0xa0 /* 64b */ 105 REG32(EVENTQ_PROD, 0xa8) 106 REG32(EVENTQ_CONS, 0xac) 107 108 #define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */ 109 REG32(EVENTQ_IRQ_CFG1, 0xb8) 110 REG32(EVENTQ_IRQ_CFG2, 0xbc) 111 112 #define A_IDREGS 0xfd0 113 114 static inline int smmu_enabled(SMMUv3State *s) 115 { 116 return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE); 117 } 118 119 /* Command Queue Entry */ 120 typedef struct Cmd { 121 uint32_t word[4]; 122 } Cmd; 123 124 /* Event Queue Entry */ 125 typedef struct Evt { 126 uint32_t word[8]; 127 } Evt; 128 129 static inline uint32_t smmuv3_idreg(int regoffset) 130 { 131 /* 132 * Return the value of the Primecell/Corelink ID registers at the 133 * specified offset from the first ID register. 134 * These value indicate an ARM implementation of MMU600 p1 135 */ 136 static const uint8_t smmuv3_ids[] = { 137 0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1 138 }; 139 return smmuv3_ids[regoffset / 4]; 140 } 141 142 static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s) 143 { 144 return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); 145 } 146 147 static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s) 148 { 149 return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); 150 } 151 152 /* public until callers get introduced */ 153 void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask); 154 void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn); 155 156 #endif 157