1 /* 2 * QEMU PowerPC PowerNV (POWER8) PHB3 model 3 * 4 * Copyright (c) 2014-2020, IBM Corporation. 5 * 6 * This code is licensed under the GPL version 2 or later. See the 7 * COPYING file in the top-level directory. 8 */ 9 #include "qemu/osdep.h" 10 #include "qemu/log.h" 11 #include "qapi/error.h" 12 #include "hw/pci-host/pnv_phb3_regs.h" 13 #include "hw/pci-host/pnv_phb3.h" 14 #include "hw/ppc/pnv.h" 15 #include "hw/pci/msi.h" 16 #include "hw/irq.h" 17 #include "hw/qdev-properties.h" 18 #include "sysemu/reset.h" 19 20 static uint64_t phb3_msi_ive_addr(PnvPHB3 *phb, int srcno) 21 { 22 uint64_t ivtbar = phb->regs[PHB_IVT_BAR >> 3]; 23 uint64_t phbctl = phb->regs[PHB_CONTROL >> 3]; 24 25 if (!(ivtbar & PHB_IVT_BAR_ENABLE)) { 26 qemu_log_mask(LOG_GUEST_ERROR, "Failed access to disable IVT BAR !"); 27 return 0; 28 } 29 30 if (srcno >= (ivtbar & PHB_IVT_LENGTH_MASK)) { 31 qemu_log_mask(LOG_GUEST_ERROR, "MSI out of bounds (%d vs 0x%"PRIx64")", 32 srcno, (uint64_t) (ivtbar & PHB_IVT_LENGTH_MASK)); 33 return 0; 34 } 35 36 ivtbar &= PHB_IVT_BASE_ADDRESS_MASK; 37 38 if (phbctl & PHB_CTRL_IVE_128_BYTES) { 39 return ivtbar + 128 * srcno; 40 } else { 41 return ivtbar + 16 * srcno; 42 } 43 } 44 45 static bool phb3_msi_read_ive(PnvPHB3 *phb, int srcno, uint64_t *out_ive) 46 { 47 uint64_t ive_addr, ive; 48 49 ive_addr = phb3_msi_ive_addr(phb, srcno); 50 if (!ive_addr) { 51 return false; 52 } 53 54 if (dma_memory_read(&address_space_memory, ive_addr, 55 &ive, sizeof(ive), MEMTXATTRS_UNSPECIFIED)) { 56 qemu_log_mask(LOG_GUEST_ERROR, "Failed to read IVE at 0x%" PRIx64, 57 ive_addr); 58 return false; 59 } 60 *out_ive = be64_to_cpu(ive); 61 62 return true; 63 } 64 65 static void phb3_msi_set_p(Phb3MsiState *msi, int srcno, uint8_t gen) 66 { 67 uint64_t ive_addr; 68 uint8_t p = 0x01 | (gen << 1); 69 70 ive_addr = phb3_msi_ive_addr(msi->phb, srcno); 71 if (!ive_addr) { 72 return; 73 } 74 75 if (dma_memory_write(&address_space_memory, ive_addr + 4, 76 &p, 1, MEMTXATTRS_UNSPECIFIED)) { 77 qemu_log_mask(LOG_GUEST_ERROR, 78 "Failed to write IVE (set P) at 0x%" PRIx64, ive_addr); 79 } 80 } 81 82 static void phb3_msi_set_q(Phb3MsiState *msi, int srcno) 83 { 84 uint64_t ive_addr; 85 uint8_t q = 0x01; 86 87 ive_addr = phb3_msi_ive_addr(msi->phb, srcno); 88 if (!ive_addr) { 89 return; 90 } 91 92 if (dma_memory_write(&address_space_memory, ive_addr + 5, 93 &q, 1, MEMTXATTRS_UNSPECIFIED)) { 94 qemu_log_mask(LOG_GUEST_ERROR, 95 "Failed to write IVE (set Q) at 0x%" PRIx64, ive_addr); 96 } 97 } 98 99 static void phb3_msi_try_send(Phb3MsiState *msi, int srcno, bool force) 100 { 101 ICSState *ics = ICS(msi); 102 uint64_t ive; 103 uint64_t server, prio, pq, gen; 104 105 if (!phb3_msi_read_ive(msi->phb, srcno, &ive)) { 106 return; 107 } 108 109 server = GETFIELD(IODA2_IVT_SERVER, ive); 110 prio = GETFIELD(IODA2_IVT_PRIORITY, ive); 111 if (!force) { 112 pq = GETFIELD(IODA2_IVT_Q, ive) | (GETFIELD(IODA2_IVT_P, ive) << 1); 113 } else { 114 pq = 0; 115 } 116 gen = GETFIELD(IODA2_IVT_GEN, ive); 117 118 /* 119 * The low order 2 bits are the link pointer (Type II interrupts). 120 * Shift back to get a valid IRQ server. 121 */ 122 server >>= 2; 123 124 switch (pq) { 125 case 0: /* 00 */ 126 if (prio == 0xff) { 127 /* Masked, set Q */ 128 phb3_msi_set_q(msi, srcno); 129 } else { 130 /* Enabled, set P and send */ 131 phb3_msi_set_p(msi, srcno, gen); 132 icp_irq(ics, server, srcno + ics->offset, prio); 133 } 134 break; 135 case 2: /* 10 */ 136 /* Already pending, set Q */ 137 phb3_msi_set_q(msi, srcno); 138 break; 139 case 1: /* 01 */ 140 case 3: /* 11 */ 141 default: 142 /* Just drop stuff if Q already set */ 143 break; 144 } 145 } 146 147 static void phb3_msi_set_irq(void *opaque, int srcno, int val) 148 { 149 Phb3MsiState *msi = PHB3_MSI(opaque); 150 151 if (val) { 152 phb3_msi_try_send(msi, srcno, false); 153 } 154 } 155 156 157 void pnv_phb3_msi_send(Phb3MsiState *msi, uint64_t addr, uint16_t data, 158 int32_t dev_pe) 159 { 160 ICSState *ics = ICS(msi); 161 uint64_t ive; 162 uint16_t pe; 163 uint32_t src = ((addr >> 4) & 0xffff) | (data & 0x1f); 164 165 if (src >= ics->nr_irqs) { 166 qemu_log_mask(LOG_GUEST_ERROR, "MSI %d out of bounds", src); 167 return; 168 } 169 if (dev_pe >= 0) { 170 if (!phb3_msi_read_ive(msi->phb, src, &ive)) { 171 return; 172 } 173 pe = GETFIELD(IODA2_IVT_PE, ive); 174 if (pe != dev_pe) { 175 qemu_log_mask(LOG_GUEST_ERROR, 176 "MSI %d send by PE#%d but assigned to PE#%d", 177 src, dev_pe, pe); 178 return; 179 } 180 } 181 qemu_irq_pulse(msi->qirqs[src]); 182 } 183 184 void pnv_phb3_msi_ffi(Phb3MsiState *msi, uint64_t val) 185 { 186 /* Emit interrupt */ 187 pnv_phb3_msi_send(msi, val, 0, -1); 188 189 /* Clear FFI lock */ 190 msi->phb->regs[PHB_FFI_LOCK >> 3] = 0; 191 } 192 193 static void phb3_msi_reject(ICSState *ics, uint32_t nr) 194 { 195 Phb3MsiState *msi = PHB3_MSI(ics); 196 unsigned int srcno = nr - ics->offset; 197 unsigned int idx = srcno >> 6; 198 unsigned int bit = 1ull << (srcno & 0x3f); 199 200 assert(srcno < PHB3_MAX_MSI); 201 202 msi->rba[idx] |= bit; 203 msi->rba_sum |= (1u << idx); 204 } 205 206 static void phb3_msi_resend(ICSState *ics) 207 { 208 Phb3MsiState *msi = PHB3_MSI(ics); 209 unsigned int i, j; 210 211 if (msi->rba_sum == 0) { 212 return; 213 } 214 215 for (i = 0; i < 32; i++) { 216 if ((msi->rba_sum & (1u << i)) == 0) { 217 continue; 218 } 219 msi->rba_sum &= ~(1u << i); 220 for (j = 0; j < 64; j++) { 221 if ((msi->rba[i] & (1ull << j)) == 0) { 222 continue; 223 } 224 msi->rba[i] &= ~(1ull << j); 225 phb3_msi_try_send(msi, i * 64 + j, true); 226 } 227 } 228 } 229 230 static void phb3_msi_reset_hold(Object *obj, ResetType type) 231 { 232 Phb3MsiState *msi = PHB3_MSI(obj); 233 ICSStateClass *icsc = ICS_GET_CLASS(obj); 234 235 if (icsc->parent_phases.hold) { 236 icsc->parent_phases.hold(obj, type); 237 } 238 239 memset(msi->rba, 0, sizeof(msi->rba)); 240 msi->rba_sum = 0; 241 } 242 243 void pnv_phb3_msi_update_config(Phb3MsiState *msi, uint32_t base, 244 uint32_t count) 245 { 246 ICSState *ics = ICS(msi); 247 248 if (count > PHB3_MAX_MSI) { 249 count = PHB3_MAX_MSI; 250 } 251 ics->nr_irqs = count; 252 ics->offset = base; 253 } 254 255 static void phb3_msi_realize(DeviceState *dev, Error **errp) 256 { 257 Phb3MsiState *msi = PHB3_MSI(dev); 258 ICSState *ics = ICS(msi); 259 ICSStateClass *icsc = ICS_GET_CLASS(ics); 260 Error *local_err = NULL; 261 262 assert(msi->phb); 263 264 icsc->parent_realize(dev, &local_err); 265 if (local_err) { 266 error_propagate(errp, local_err); 267 return; 268 } 269 270 msi->qirqs = qemu_allocate_irqs(phb3_msi_set_irq, msi, ics->nr_irqs); 271 } 272 273 static void phb3_msi_instance_init(Object *obj) 274 { 275 Phb3MsiState *msi = PHB3_MSI(obj); 276 ICSState *ics = ICS(obj); 277 278 object_property_add_link(obj, "phb", TYPE_PNV_PHB3, 279 (Object **)&msi->phb, 280 object_property_allow_set_link, 281 OBJ_PROP_LINK_STRONG); 282 283 /* Will be overridden later */ 284 ics->offset = 0; 285 } 286 287 static void phb3_msi_class_init(ObjectClass *klass, void *data) 288 { 289 DeviceClass *dc = DEVICE_CLASS(klass); 290 ICSStateClass *isc = ICS_CLASS(klass); 291 ResettableClass *rc = RESETTABLE_CLASS(klass); 292 293 device_class_set_parent_realize(dc, phb3_msi_realize, 294 &isc->parent_realize); 295 resettable_class_set_parent_phases(rc, NULL, phb3_msi_reset_hold, NULL, 296 &isc->parent_phases); 297 298 isc->reject = phb3_msi_reject; 299 isc->resend = phb3_msi_resend; 300 } 301 302 static const TypeInfo phb3_msi_info = { 303 .name = TYPE_PHB3_MSI, 304 .parent = TYPE_ICS, 305 .instance_size = sizeof(Phb3MsiState), 306 .class_init = phb3_msi_class_init, 307 .class_size = sizeof(ICSStateClass), 308 .instance_init = phb3_msi_instance_init, 309 }; 310 311 static void pnv_phb3_msi_register_types(void) 312 { 313 type_register_static(&phb3_msi_info); 314 } 315 316 type_init(pnv_phb3_msi_register_types); 317 318 void pnv_phb3_msi_pic_print_info(Phb3MsiState *msi, GString *buf) 319 { 320 ICSState *ics = ICS(msi); 321 int i; 322 323 g_string_append_printf(buf, "ICS %4x..%4x %p\n", 324 ics->offset, ics->offset + ics->nr_irqs - 1, ics); 325 326 for (i = 0; i < ics->nr_irqs; i++) { 327 uint64_t ive; 328 329 if (!phb3_msi_read_ive(msi->phb, i, &ive)) { 330 return; 331 } 332 333 if (GETFIELD(IODA2_IVT_PRIORITY, ive) == 0xff) { 334 continue; 335 } 336 337 g_string_append_printf(buf, " %4x %c%c server=%04x prio=%02x gen=%d\n", 338 ics->offset + i, 339 GETFIELD(IODA2_IVT_P, ive) ? 'P' : '-', 340 GETFIELD(IODA2_IVT_Q, ive) ? 'Q' : '-', 341 (uint32_t) GETFIELD(IODA2_IVT_SERVER, ive) >> 2, 342 (uint32_t) GETFIELD(IODA2_IVT_PRIORITY, ive), 343 (uint32_t) GETFIELD(IODA2_IVT_GEN, ive)); 344 } 345 } 346