1 /* 2 * ITS emulation for a GICv3-based system 3 * 4 * Copyright Linaro.org 2021 5 * 6 * Authors: 7 * Shashi Mallela <shashi.mallela@linaro.org> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or (at your 10 * option) any later version. See the COPYING file in the top-level directory. 11 * 12 */ 13 14 #include "qemu/osdep.h" 15 #include "qemu/log.h" 16 #include "trace.h" 17 #include "hw/qdev-properties.h" 18 #include "hw/intc/arm_gicv3_its_common.h" 19 #include "gicv3_internal.h" 20 #include "qom/object.h" 21 #include "qapi/error.h" 22 23 typedef struct GICv3ITSClass GICv3ITSClass; 24 /* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */ 25 DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, 26 ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) 27 28 struct GICv3ITSClass { 29 GICv3ITSCommonClass parent_class; 30 void (*parent_reset)(DeviceState *dev); 31 }; 32 33 /* 34 * This is an internal enum used to distinguish between LPI triggered 35 * via command queue and LPI triggered via gits_translater write. 36 */ 37 typedef enum ItsCmdType { 38 NONE = 0, /* internal indication for GITS_TRANSLATER write */ 39 CLEAR = 1, 40 DISCARD = 2, 41 INTERRUPT = 3, 42 } ItsCmdType; 43 44 typedef struct DTEntry { 45 bool valid; 46 unsigned size; 47 uint64_t ittaddr; 48 } DTEntry; 49 50 typedef struct CTEntry { 51 bool valid; 52 uint32_t rdbase; 53 } CTEntry; 54 55 typedef struct ITEntry { 56 bool valid; 57 int inttype; 58 uint32_t intid; 59 uint32_t doorbell; 60 uint32_t icid; 61 uint32_t vpeid; 62 } ITEntry; 63 64 65 /* 66 * The ITS spec permits a range of CONSTRAINED UNPREDICTABLE options 67 * if a command parameter is not correct. These include both "stall 68 * processing of the command queue" and "ignore this command, and 69 * keep processing the queue". In our implementation we choose that 70 * memory transaction errors reading the command packet provoke a 71 * stall, but errors in parameters cause us to ignore the command 72 * and continue processing. 73 * The process_* functions which handle individual ITS commands all 74 * return an ItsCmdResult which tells process_cmdq() whether it should 75 * stall or keep going. 76 */ 77 typedef enum ItsCmdResult { 78 CMD_STALL = 0, 79 CMD_CONTINUE = 1, 80 } ItsCmdResult; 81 82 static inline bool intid_in_lpi_range(uint32_t id) 83 { 84 return id >= GICV3_LPI_INTID_START && 85 id < (1 << (GICD_TYPER_IDBITS + 1)); 86 } 87 88 static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) 89 { 90 uint64_t result = 0; 91 92 switch (page_sz) { 93 case GITS_PAGE_SIZE_4K: 94 case GITS_PAGE_SIZE_16K: 95 result = FIELD_EX64(value, GITS_BASER, PHYADDR) << 12; 96 break; 97 98 case GITS_PAGE_SIZE_64K: 99 result = FIELD_EX64(value, GITS_BASER, PHYADDRL_64K) << 16; 100 result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48; 101 break; 102 103 default: 104 break; 105 } 106 return result; 107 } 108 109 static uint64_t table_entry_addr(GICv3ITSState *s, TableDesc *td, 110 uint32_t idx, MemTxResult *res) 111 { 112 /* 113 * Given a TableDesc describing one of the ITS in-guest-memory 114 * tables and an index into it, return the guest address 115 * corresponding to that table entry. 116 * If there was a memory error reading the L1 table of an 117 * indirect table, *res is set accordingly, and we return -1. 118 * If the L1 table entry is marked not valid, we return -1 with 119 * *res set to MEMTX_OK. 120 * 121 * The specification defines the format of level 1 entries of a 122 * 2-level table, but the format of level 2 entries and the format 123 * of flat-mapped tables is IMPDEF. 124 */ 125 AddressSpace *as = &s->gicv3->dma_as; 126 uint32_t l2idx; 127 uint64_t l2; 128 uint32_t num_l2_entries; 129 130 *res = MEMTX_OK; 131 132 if (!td->indirect) { 133 /* Single level table */ 134 return td->base_addr + idx * td->entry_sz; 135 } 136 137 /* Two level table */ 138 l2idx = idx / (td->page_sz / L1TABLE_ENTRY_SIZE); 139 140 l2 = address_space_ldq_le(as, 141 td->base_addr + (l2idx * L1TABLE_ENTRY_SIZE), 142 MEMTXATTRS_UNSPECIFIED, res); 143 if (*res != MEMTX_OK) { 144 return -1; 145 } 146 if (!(l2 & L2_TABLE_VALID_MASK)) { 147 return -1; 148 } 149 150 num_l2_entries = td->page_sz / td->entry_sz; 151 return (l2 & ((1ULL << 51) - 1)) + (idx % num_l2_entries) * td->entry_sz; 152 } 153 154 /* 155 * Read the Collection Table entry at index @icid. On success (including 156 * successfully determining that there is no valid CTE for this index), 157 * we return MEMTX_OK and populate the CTEntry struct @cte accordingly. 158 * If there is an error reading memory then we return the error code. 159 */ 160 static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte) 161 { 162 AddressSpace *as = &s->gicv3->dma_as; 163 MemTxResult res = MEMTX_OK; 164 uint64_t entry_addr = table_entry_addr(s, &s->ct, icid, &res); 165 uint64_t cteval; 166 167 if (entry_addr == -1) { 168 /* No L2 table entry, i.e. no valid CTE, or a memory error */ 169 cte->valid = false; 170 goto out; 171 } 172 173 cteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res); 174 if (res != MEMTX_OK) { 175 goto out; 176 } 177 cte->valid = FIELD_EX64(cteval, CTE, VALID); 178 cte->rdbase = FIELD_EX64(cteval, CTE, RDBASE); 179 out: 180 if (res != MEMTX_OK) { 181 trace_gicv3_its_cte_read_fault(icid); 182 } else { 183 trace_gicv3_its_cte_read(icid, cte->valid, cte->rdbase); 184 } 185 return res; 186 } 187 188 /* 189 * Update the Interrupt Table entry at index @evinted in the table specified 190 * by the dte @dte. Returns true on success, false if there was a memory 191 * access error. 192 */ 193 static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte, 194 const ITEntry *ite) 195 { 196 AddressSpace *as = &s->gicv3->dma_as; 197 MemTxResult res = MEMTX_OK; 198 hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE; 199 uint64_t itel = 0; 200 uint32_t iteh = 0; 201 202 trace_gicv3_its_ite_write(dte->ittaddr, eventid, ite->valid, 203 ite->inttype, ite->intid, ite->icid, 204 ite->vpeid, ite->doorbell); 205 206 if (ite->valid) { 207 itel = FIELD_DP64(itel, ITE_L, VALID, 1); 208 itel = FIELD_DP64(itel, ITE_L, INTTYPE, ite->inttype); 209 itel = FIELD_DP64(itel, ITE_L, INTID, ite->intid); 210 itel = FIELD_DP64(itel, ITE_L, ICID, ite->icid); 211 itel = FIELD_DP64(itel, ITE_L, VPEID, ite->vpeid); 212 iteh = FIELD_DP32(iteh, ITE_H, DOORBELL, ite->doorbell); 213 } 214 215 address_space_stq_le(as, iteaddr, itel, MEMTXATTRS_UNSPECIFIED, &res); 216 if (res != MEMTX_OK) { 217 return false; 218 } 219 address_space_stl_le(as, iteaddr + 8, iteh, MEMTXATTRS_UNSPECIFIED, &res); 220 return res == MEMTX_OK; 221 } 222 223 /* 224 * Read the Interrupt Table entry at index @eventid from the table specified 225 * by the DTE @dte. On success, we return MEMTX_OK and populate the ITEntry 226 * struct @ite accordingly. If there is an error reading memory then we return 227 * the error code. 228 */ 229 static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid, 230 const DTEntry *dte, ITEntry *ite) 231 { 232 AddressSpace *as = &s->gicv3->dma_as; 233 MemTxResult res = MEMTX_OK; 234 uint64_t itel; 235 uint32_t iteh; 236 hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE; 237 238 itel = address_space_ldq_le(as, iteaddr, MEMTXATTRS_UNSPECIFIED, &res); 239 if (res != MEMTX_OK) { 240 trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid); 241 return res; 242 } 243 244 iteh = address_space_ldl_le(as, iteaddr + 8, MEMTXATTRS_UNSPECIFIED, &res); 245 if (res != MEMTX_OK) { 246 trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid); 247 return res; 248 } 249 250 ite->valid = FIELD_EX64(itel, ITE_L, VALID); 251 ite->inttype = FIELD_EX64(itel, ITE_L, INTTYPE); 252 ite->intid = FIELD_EX64(itel, ITE_L, INTID); 253 ite->icid = FIELD_EX64(itel, ITE_L, ICID); 254 ite->vpeid = FIELD_EX64(itel, ITE_L, VPEID); 255 ite->doorbell = FIELD_EX64(iteh, ITE_H, DOORBELL); 256 trace_gicv3_its_ite_read(dte->ittaddr, eventid, ite->valid, 257 ite->inttype, ite->intid, ite->icid, 258 ite->vpeid, ite->doorbell); 259 return MEMTX_OK; 260 } 261 262 /* 263 * Read the Device Table entry at index @devid. On success (including 264 * successfully determining that there is no valid DTE for this index), 265 * we return MEMTX_OK and populate the DTEntry struct accordingly. 266 * If there is an error reading memory then we return the error code. 267 */ 268 static MemTxResult get_dte(GICv3ITSState *s, uint32_t devid, DTEntry *dte) 269 { 270 MemTxResult res = MEMTX_OK; 271 AddressSpace *as = &s->gicv3->dma_as; 272 uint64_t entry_addr = table_entry_addr(s, &s->dt, devid, &res); 273 uint64_t dteval; 274 275 if (entry_addr == -1) { 276 /* No L2 table entry, i.e. no valid DTE, or a memory error */ 277 dte->valid = false; 278 goto out; 279 } 280 dteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res); 281 if (res != MEMTX_OK) { 282 goto out; 283 } 284 dte->valid = FIELD_EX64(dteval, DTE, VALID); 285 dte->size = FIELD_EX64(dteval, DTE, SIZE); 286 /* DTE word field stores bits [51:8] of the ITT address */ 287 dte->ittaddr = FIELD_EX64(dteval, DTE, ITTADDR) << ITTADDR_SHIFT; 288 out: 289 if (res != MEMTX_OK) { 290 trace_gicv3_its_dte_read_fault(devid); 291 } else { 292 trace_gicv3_its_dte_read(devid, dte->valid, dte->size, dte->ittaddr); 293 } 294 return res; 295 } 296 297 /* 298 * This function handles the processing of following commands based on 299 * the ItsCmdType parameter passed:- 300 * 1. triggering of lpi interrupt translation via ITS INT command 301 * 2. triggering of lpi interrupt translation via gits_translater register 302 * 3. handling of ITS CLEAR command 303 * 4. handling of ITS DISCARD command 304 */ 305 static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid, 306 uint32_t eventid, ItsCmdType cmd) 307 { 308 uint64_t num_eventids; 309 DTEntry dte; 310 CTEntry cte; 311 ITEntry ite; 312 313 if (devid >= s->dt.num_entries) { 314 qemu_log_mask(LOG_GUEST_ERROR, 315 "%s: invalid command attributes: devid %d>=%d", 316 __func__, devid, s->dt.num_entries); 317 return CMD_CONTINUE; 318 } 319 320 if (get_dte(s, devid, &dte) != MEMTX_OK) { 321 return CMD_STALL; 322 } 323 if (!dte.valid) { 324 qemu_log_mask(LOG_GUEST_ERROR, 325 "%s: invalid command attributes: " 326 "invalid dte for %d\n", __func__, devid); 327 return CMD_CONTINUE; 328 } 329 330 num_eventids = 1ULL << (dte.size + 1); 331 if (eventid >= num_eventids) { 332 qemu_log_mask(LOG_GUEST_ERROR, 333 "%s: invalid command attributes: eventid %d >= %" 334 PRId64 "\n", 335 __func__, eventid, num_eventids); 336 return CMD_CONTINUE; 337 } 338 339 if (get_ite(s, eventid, &dte, &ite) != MEMTX_OK) { 340 return CMD_STALL; 341 } 342 343 if (!ite.valid || ite.inttype != ITE_INTTYPE_PHYSICAL) { 344 qemu_log_mask(LOG_GUEST_ERROR, 345 "%s: invalid command attributes: invalid ITE\n", 346 __func__); 347 return CMD_CONTINUE; 348 } 349 350 if (ite.icid >= s->ct.num_entries) { 351 qemu_log_mask(LOG_GUEST_ERROR, 352 "%s: invalid ICID 0x%x in ITE (table corrupted?)\n", 353 __func__, ite.icid); 354 return CMD_CONTINUE; 355 } 356 357 if (get_cte(s, ite.icid, &cte) != MEMTX_OK) { 358 return CMD_STALL; 359 } 360 if (!cte.valid) { 361 qemu_log_mask(LOG_GUEST_ERROR, 362 "%s: invalid command attributes: invalid CTE\n", 363 __func__); 364 return CMD_CONTINUE; 365 } 366 367 /* 368 * Current implementation only supports rdbase == procnum 369 * Hence rdbase physical address is ignored 370 */ 371 if (cte.rdbase >= s->gicv3->num_cpu) { 372 return CMD_CONTINUE; 373 } 374 375 if ((cmd == CLEAR) || (cmd == DISCARD)) { 376 gicv3_redist_process_lpi(&s->gicv3->cpu[cte.rdbase], ite.intid, 0); 377 } else { 378 gicv3_redist_process_lpi(&s->gicv3->cpu[cte.rdbase], ite.intid, 1); 379 } 380 381 if (cmd == DISCARD) { 382 ITEntry ite = {}; 383 /* remove mapping from interrupt translation table */ 384 ite.valid = false; 385 return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE : CMD_STALL; 386 } 387 return CMD_CONTINUE; 388 } 389 390 static ItsCmdResult process_its_cmd(GICv3ITSState *s, const uint64_t *cmdpkt, 391 ItsCmdType cmd) 392 { 393 uint32_t devid, eventid; 394 395 devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; 396 eventid = cmdpkt[1] & EVENTID_MASK; 397 switch (cmd) { 398 case INTERRUPT: 399 trace_gicv3_its_cmd_int(devid, eventid); 400 break; 401 case CLEAR: 402 trace_gicv3_its_cmd_clear(devid, eventid); 403 break; 404 case DISCARD: 405 trace_gicv3_its_cmd_discard(devid, eventid); 406 break; 407 default: 408 g_assert_not_reached(); 409 } 410 return do_process_its_cmd(s, devid, eventid, cmd); 411 } 412 413 static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt, 414 bool ignore_pInt) 415 { 416 uint32_t devid, eventid; 417 uint32_t pIntid = 0; 418 uint64_t num_eventids; 419 uint16_t icid = 0; 420 DTEntry dte; 421 ITEntry ite; 422 423 devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; 424 eventid = cmdpkt[1] & EVENTID_MASK; 425 icid = cmdpkt[2] & ICID_MASK; 426 427 if (ignore_pInt) { 428 pIntid = eventid; 429 trace_gicv3_its_cmd_mapi(devid, eventid, icid); 430 } else { 431 pIntid = (cmdpkt[1] & pINTID_MASK) >> pINTID_SHIFT; 432 trace_gicv3_its_cmd_mapti(devid, eventid, icid, pIntid); 433 } 434 435 if (devid >= s->dt.num_entries) { 436 qemu_log_mask(LOG_GUEST_ERROR, 437 "%s: invalid command attributes: devid %d>=%d", 438 __func__, devid, s->dt.num_entries); 439 return CMD_CONTINUE; 440 } 441 442 if (get_dte(s, devid, &dte) != MEMTX_OK) { 443 return CMD_STALL; 444 } 445 num_eventids = 1ULL << (dte.size + 1); 446 447 if (icid >= s->ct.num_entries) { 448 qemu_log_mask(LOG_GUEST_ERROR, 449 "%s: invalid ICID 0x%x >= 0x%x\n", 450 __func__, icid, s->ct.num_entries); 451 return CMD_CONTINUE; 452 } 453 454 if (!dte.valid) { 455 qemu_log_mask(LOG_GUEST_ERROR, 456 "%s: no valid DTE for devid 0x%x\n", __func__, devid); 457 return CMD_CONTINUE; 458 } 459 460 if (eventid >= num_eventids) { 461 qemu_log_mask(LOG_GUEST_ERROR, 462 "%s: invalid event ID 0x%x >= 0x%" PRIx64 "\n", 463 __func__, eventid, num_eventids); 464 return CMD_CONTINUE; 465 } 466 467 if (!intid_in_lpi_range(pIntid)) { 468 qemu_log_mask(LOG_GUEST_ERROR, 469 "%s: invalid interrupt ID 0x%x\n", __func__, pIntid); 470 return CMD_CONTINUE; 471 } 472 473 /* add ite entry to interrupt translation table */ 474 ite.valid = true; 475 ite.inttype = ITE_INTTYPE_PHYSICAL; 476 ite.intid = pIntid; 477 ite.icid = icid; 478 ite.doorbell = INTID_SPURIOUS; 479 ite.vpeid = 0; 480 return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE : CMD_STALL; 481 } 482 483 /* 484 * Update the Collection Table entry for @icid to @cte. Returns true 485 * on success, false if there was a memory access error. 486 */ 487 static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte) 488 { 489 AddressSpace *as = &s->gicv3->dma_as; 490 uint64_t entry_addr; 491 uint64_t cteval = 0; 492 MemTxResult res = MEMTX_OK; 493 494 trace_gicv3_its_cte_write(icid, cte->valid, cte->rdbase); 495 496 if (cte->valid) { 497 /* add mapping entry to collection table */ 498 cteval = FIELD_DP64(cteval, CTE, VALID, 1); 499 cteval = FIELD_DP64(cteval, CTE, RDBASE, cte->rdbase); 500 } 501 502 entry_addr = table_entry_addr(s, &s->ct, icid, &res); 503 if (res != MEMTX_OK) { 504 /* memory access error: stall */ 505 return false; 506 } 507 if (entry_addr == -1) { 508 /* No L2 table for this index: discard write and continue */ 509 return true; 510 } 511 512 address_space_stq_le(as, entry_addr, cteval, MEMTXATTRS_UNSPECIFIED, &res); 513 return res == MEMTX_OK; 514 } 515 516 static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt) 517 { 518 uint16_t icid; 519 CTEntry cte; 520 521 icid = cmdpkt[2] & ICID_MASK; 522 cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK; 523 if (cte.valid) { 524 cte.rdbase = (cmdpkt[2] & R_MAPC_RDBASE_MASK) >> R_MAPC_RDBASE_SHIFT; 525 cte.rdbase &= RDBASE_PROCNUM_MASK; 526 } else { 527 cte.rdbase = 0; 528 } 529 trace_gicv3_its_cmd_mapc(icid, cte.rdbase, cte.valid); 530 531 if (icid >= s->ct.num_entries) { 532 qemu_log_mask(LOG_GUEST_ERROR, "ITS MAPC: invalid ICID 0x%x\n", icid); 533 return CMD_CONTINUE; 534 } 535 if (cte.valid && cte.rdbase >= s->gicv3->num_cpu) { 536 qemu_log_mask(LOG_GUEST_ERROR, 537 "ITS MAPC: invalid RDBASE %u\n", cte.rdbase); 538 return CMD_CONTINUE; 539 } 540 541 return update_cte(s, icid, &cte) ? CMD_CONTINUE : CMD_STALL; 542 } 543 544 /* 545 * Update the Device Table entry for @devid to @dte. Returns true 546 * on success, false if there was a memory access error. 547 */ 548 static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte) 549 { 550 AddressSpace *as = &s->gicv3->dma_as; 551 uint64_t entry_addr; 552 uint64_t dteval = 0; 553 MemTxResult res = MEMTX_OK; 554 555 trace_gicv3_its_dte_write(devid, dte->valid, dte->size, dte->ittaddr); 556 557 if (dte->valid) { 558 /* add mapping entry to device table */ 559 dteval = FIELD_DP64(dteval, DTE, VALID, 1); 560 dteval = FIELD_DP64(dteval, DTE, SIZE, dte->size); 561 dteval = FIELD_DP64(dteval, DTE, ITTADDR, dte->ittaddr); 562 } 563 564 entry_addr = table_entry_addr(s, &s->dt, devid, &res); 565 if (res != MEMTX_OK) { 566 /* memory access error: stall */ 567 return false; 568 } 569 if (entry_addr == -1) { 570 /* No L2 table for this index: discard write and continue */ 571 return true; 572 } 573 address_space_stq_le(as, entry_addr, dteval, MEMTXATTRS_UNSPECIFIED, &res); 574 return res == MEMTX_OK; 575 } 576 577 static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt) 578 { 579 uint32_t devid; 580 DTEntry dte; 581 582 devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; 583 dte.size = cmdpkt[1] & SIZE_MASK; 584 dte.ittaddr = (cmdpkt[2] & ITTADDR_MASK) >> ITTADDR_SHIFT; 585 dte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK; 586 587 trace_gicv3_its_cmd_mapd(devid, dte.size, dte.ittaddr, dte.valid); 588 589 if (devid >= s->dt.num_entries) { 590 qemu_log_mask(LOG_GUEST_ERROR, 591 "ITS MAPD: invalid device ID field 0x%x >= 0x%x\n", 592 devid, s->dt.num_entries); 593 return CMD_CONTINUE; 594 } 595 596 if (dte.size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS)) { 597 qemu_log_mask(LOG_GUEST_ERROR, 598 "ITS MAPD: invalid size %d\n", dte.size); 599 return CMD_CONTINUE; 600 } 601 602 return update_dte(s, devid, &dte) ? CMD_CONTINUE : CMD_STALL; 603 } 604 605 static ItsCmdResult process_movall(GICv3ITSState *s, const uint64_t *cmdpkt) 606 { 607 uint64_t rd1, rd2; 608 609 rd1 = FIELD_EX64(cmdpkt[2], MOVALL_2, RDBASE1); 610 rd2 = FIELD_EX64(cmdpkt[3], MOVALL_3, RDBASE2); 611 612 trace_gicv3_its_cmd_movall(rd1, rd2); 613 614 if (rd1 >= s->gicv3->num_cpu) { 615 qemu_log_mask(LOG_GUEST_ERROR, 616 "%s: RDBASE1 %" PRId64 617 " out of range (must be less than %d)\n", 618 __func__, rd1, s->gicv3->num_cpu); 619 return CMD_CONTINUE; 620 } 621 if (rd2 >= s->gicv3->num_cpu) { 622 qemu_log_mask(LOG_GUEST_ERROR, 623 "%s: RDBASE2 %" PRId64 624 " out of range (must be less than %d)\n", 625 __func__, rd2, s->gicv3->num_cpu); 626 return CMD_CONTINUE; 627 } 628 629 if (rd1 == rd2) { 630 /* Move to same target must succeed as a no-op */ 631 return CMD_CONTINUE; 632 } 633 634 /* Move all pending LPIs from redistributor 1 to redistributor 2 */ 635 gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]); 636 637 return CMD_CONTINUE; 638 } 639 640 static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt) 641 { 642 uint32_t devid, eventid; 643 uint16_t new_icid; 644 uint64_t num_eventids; 645 DTEntry dte; 646 CTEntry old_cte, new_cte; 647 ITEntry old_ite; 648 649 devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID); 650 eventid = FIELD_EX64(cmdpkt[1], MOVI_1, EVENTID); 651 new_icid = FIELD_EX64(cmdpkt[2], MOVI_2, ICID); 652 653 trace_gicv3_its_cmd_movi(devid, eventid, new_icid); 654 655 if (devid >= s->dt.num_entries) { 656 qemu_log_mask(LOG_GUEST_ERROR, 657 "%s: invalid command attributes: devid %d>=%d", 658 __func__, devid, s->dt.num_entries); 659 return CMD_CONTINUE; 660 } 661 if (get_dte(s, devid, &dte) != MEMTX_OK) { 662 return CMD_STALL; 663 } 664 665 if (!dte.valid) { 666 qemu_log_mask(LOG_GUEST_ERROR, 667 "%s: invalid command attributes: " 668 "invalid dte for %d\n", __func__, devid); 669 return CMD_CONTINUE; 670 } 671 672 num_eventids = 1ULL << (dte.size + 1); 673 if (eventid >= num_eventids) { 674 qemu_log_mask(LOG_GUEST_ERROR, 675 "%s: invalid command attributes: eventid %d >= %" 676 PRId64 "\n", 677 __func__, eventid, num_eventids); 678 return CMD_CONTINUE; 679 } 680 681 if (get_ite(s, eventid, &dte, &old_ite) != MEMTX_OK) { 682 return CMD_STALL; 683 } 684 685 if (!old_ite.valid || old_ite.inttype != ITE_INTTYPE_PHYSICAL) { 686 qemu_log_mask(LOG_GUEST_ERROR, 687 "%s: invalid command attributes: invalid ITE\n", 688 __func__); 689 return CMD_CONTINUE; 690 } 691 692 if (old_ite.icid >= s->ct.num_entries) { 693 qemu_log_mask(LOG_GUEST_ERROR, 694 "%s: invalid ICID 0x%x in ITE (table corrupted?)\n", 695 __func__, old_ite.icid); 696 return CMD_CONTINUE; 697 } 698 699 if (new_icid >= s->ct.num_entries) { 700 qemu_log_mask(LOG_GUEST_ERROR, 701 "%s: invalid command attributes: ICID 0x%x\n", 702 __func__, new_icid); 703 return CMD_CONTINUE; 704 } 705 706 if (get_cte(s, old_ite.icid, &old_cte) != MEMTX_OK) { 707 return CMD_STALL; 708 } 709 if (!old_cte.valid) { 710 qemu_log_mask(LOG_GUEST_ERROR, 711 "%s: invalid command attributes: " 712 "invalid CTE for old ICID 0x%x\n", 713 __func__, old_ite.icid); 714 return CMD_CONTINUE; 715 } 716 717 if (get_cte(s, new_icid, &new_cte) != MEMTX_OK) { 718 return CMD_STALL; 719 } 720 if (!new_cte.valid) { 721 qemu_log_mask(LOG_GUEST_ERROR, 722 "%s: invalid command attributes: " 723 "invalid CTE for new ICID 0x%x\n", 724 __func__, new_icid); 725 return CMD_CONTINUE; 726 } 727 728 if (old_cte.rdbase >= s->gicv3->num_cpu) { 729 qemu_log_mask(LOG_GUEST_ERROR, 730 "%s: CTE has invalid rdbase 0x%x\n", 731 __func__, old_cte.rdbase); 732 return CMD_CONTINUE; 733 } 734 735 if (new_cte.rdbase >= s->gicv3->num_cpu) { 736 qemu_log_mask(LOG_GUEST_ERROR, 737 "%s: CTE has invalid rdbase 0x%x\n", 738 __func__, new_cte.rdbase); 739 return CMD_CONTINUE; 740 } 741 742 if (old_cte.rdbase != new_cte.rdbase) { 743 /* Move the LPI from the old redistributor to the new one */ 744 gicv3_redist_mov_lpi(&s->gicv3->cpu[old_cte.rdbase], 745 &s->gicv3->cpu[new_cte.rdbase], 746 old_ite.intid); 747 } 748 749 /* Update the ICID field in the interrupt translation table entry */ 750 old_ite.icid = new_icid; 751 return update_ite(s, eventid, &dte, &old_ite) ? CMD_CONTINUE : CMD_STALL; 752 } 753 754 /* 755 * Current implementation blocks until all 756 * commands are processed 757 */ 758 static void process_cmdq(GICv3ITSState *s) 759 { 760 uint32_t wr_offset = 0; 761 uint32_t rd_offset = 0; 762 uint32_t cq_offset = 0; 763 AddressSpace *as = &s->gicv3->dma_as; 764 uint8_t cmd; 765 int i; 766 767 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 768 return; 769 } 770 771 wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET); 772 773 if (wr_offset >= s->cq.num_entries) { 774 qemu_log_mask(LOG_GUEST_ERROR, 775 "%s: invalid write offset " 776 "%d\n", __func__, wr_offset); 777 return; 778 } 779 780 rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET); 781 782 if (rd_offset >= s->cq.num_entries) { 783 qemu_log_mask(LOG_GUEST_ERROR, 784 "%s: invalid read offset " 785 "%d\n", __func__, rd_offset); 786 return; 787 } 788 789 while (wr_offset != rd_offset) { 790 ItsCmdResult result = CMD_CONTINUE; 791 void *hostmem; 792 hwaddr buflen; 793 uint64_t cmdpkt[GITS_CMDQ_ENTRY_WORDS]; 794 795 cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE); 796 797 buflen = GITS_CMDQ_ENTRY_SIZE; 798 hostmem = address_space_map(as, s->cq.base_addr + cq_offset, 799 &buflen, false, MEMTXATTRS_UNSPECIFIED); 800 if (!hostmem || buflen != GITS_CMDQ_ENTRY_SIZE) { 801 if (hostmem) { 802 address_space_unmap(as, hostmem, buflen, false, 0); 803 } 804 s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1); 805 qemu_log_mask(LOG_GUEST_ERROR, 806 "%s: could not read command at 0x%" PRIx64 "\n", 807 __func__, s->cq.base_addr + cq_offset); 808 break; 809 } 810 for (i = 0; i < ARRAY_SIZE(cmdpkt); i++) { 811 cmdpkt[i] = ldq_le_p(hostmem + i * sizeof(uint64_t)); 812 } 813 address_space_unmap(as, hostmem, buflen, false, 0); 814 815 cmd = cmdpkt[0] & CMD_MASK; 816 817 trace_gicv3_its_process_command(rd_offset, cmd); 818 819 switch (cmd) { 820 case GITS_CMD_INT: 821 result = process_its_cmd(s, cmdpkt, INTERRUPT); 822 break; 823 case GITS_CMD_CLEAR: 824 result = process_its_cmd(s, cmdpkt, CLEAR); 825 break; 826 case GITS_CMD_SYNC: 827 /* 828 * Current implementation makes a blocking synchronous call 829 * for every command issued earlier, hence the internal state 830 * is already consistent by the time SYNC command is executed. 831 * Hence no further processing is required for SYNC command. 832 */ 833 trace_gicv3_its_cmd_sync(); 834 break; 835 case GITS_CMD_MAPD: 836 result = process_mapd(s, cmdpkt); 837 break; 838 case GITS_CMD_MAPC: 839 result = process_mapc(s, cmdpkt); 840 break; 841 case GITS_CMD_MAPTI: 842 result = process_mapti(s, cmdpkt, false); 843 break; 844 case GITS_CMD_MAPI: 845 result = process_mapti(s, cmdpkt, true); 846 break; 847 case GITS_CMD_DISCARD: 848 result = process_its_cmd(s, cmdpkt, DISCARD); 849 break; 850 case GITS_CMD_INV: 851 case GITS_CMD_INVALL: 852 /* 853 * Current implementation doesn't cache any ITS tables, 854 * but the calculated lpi priority information. We only 855 * need to trigger lpi priority re-calculation to be in 856 * sync with LPI config table or pending table changes. 857 */ 858 trace_gicv3_its_cmd_inv(); 859 for (i = 0; i < s->gicv3->num_cpu; i++) { 860 gicv3_redist_update_lpi(&s->gicv3->cpu[i]); 861 } 862 break; 863 case GITS_CMD_MOVI: 864 result = process_movi(s, cmdpkt); 865 break; 866 case GITS_CMD_MOVALL: 867 result = process_movall(s, cmdpkt); 868 break; 869 default: 870 trace_gicv3_its_cmd_unknown(cmd); 871 break; 872 } 873 if (result == CMD_CONTINUE) { 874 rd_offset++; 875 rd_offset %= s->cq.num_entries; 876 s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset); 877 } else { 878 /* CMD_STALL */ 879 s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1); 880 qemu_log_mask(LOG_GUEST_ERROR, 881 "%s: 0x%x cmd processing failed, stalling\n", 882 __func__, cmd); 883 break; 884 } 885 } 886 } 887 888 /* 889 * This function extracts the ITS Device and Collection table specific 890 * parameters (like base_addr, size etc) from GITS_BASER register. 891 * It is called during ITS enable and also during post_load migration 892 */ 893 static void extract_table_params(GICv3ITSState *s) 894 { 895 uint16_t num_pages = 0; 896 uint8_t page_sz_type; 897 uint8_t type; 898 uint32_t page_sz = 0; 899 uint64_t value; 900 901 for (int i = 0; i < 8; i++) { 902 TableDesc *td; 903 int idbits; 904 905 value = s->baser[i]; 906 907 if (!value) { 908 continue; 909 } 910 911 page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE); 912 913 switch (page_sz_type) { 914 case 0: 915 page_sz = GITS_PAGE_SIZE_4K; 916 break; 917 918 case 1: 919 page_sz = GITS_PAGE_SIZE_16K; 920 break; 921 922 case 2: 923 case 3: 924 page_sz = GITS_PAGE_SIZE_64K; 925 break; 926 927 default: 928 g_assert_not_reached(); 929 } 930 931 num_pages = FIELD_EX64(value, GITS_BASER, SIZE) + 1; 932 933 type = FIELD_EX64(value, GITS_BASER, TYPE); 934 935 switch (type) { 936 case GITS_BASER_TYPE_DEVICE: 937 td = &s->dt; 938 idbits = FIELD_EX64(s->typer, GITS_TYPER, DEVBITS) + 1; 939 break; 940 case GITS_BASER_TYPE_COLLECTION: 941 td = &s->ct; 942 if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) { 943 idbits = FIELD_EX64(s->typer, GITS_TYPER, CIDBITS) + 1; 944 } else { 945 /* 16-bit CollectionId supported when CIL == 0 */ 946 idbits = 16; 947 } 948 break; 949 default: 950 /* 951 * GITS_BASER<n>.TYPE is read-only, so GITS_BASER_RO_MASK 952 * ensures we will only see type values corresponding to 953 * the values set up in gicv3_its_reset(). 954 */ 955 g_assert_not_reached(); 956 } 957 958 memset(td, 0, sizeof(*td)); 959 /* 960 * If GITS_BASER<n>.Valid is 0 for any <n> then we will not process 961 * interrupts. (GITS_TYPER.HCC is 0 for this implementation, so we 962 * do not have a special case where the GITS_BASER<n>.Valid bit is 0 963 * for the register corresponding to the Collection table but we 964 * still have to process interrupts using non-memory-backed 965 * Collection table entries.) 966 * The specification makes it UNPREDICTABLE to enable the ITS without 967 * marking each BASER<n> as valid. We choose to handle these as if 968 * the table was zero-sized, so commands using the table will fail 969 * and interrupts requested via GITS_TRANSLATER writes will be ignored. 970 * This happens automatically by leaving the num_entries field at 971 * zero, which will be caught by the bounds checks we have before 972 * every table lookup anyway. 973 */ 974 if (!FIELD_EX64(value, GITS_BASER, VALID)) { 975 continue; 976 } 977 td->page_sz = page_sz; 978 td->indirect = FIELD_EX64(value, GITS_BASER, INDIRECT); 979 td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE) + 1; 980 td->base_addr = baser_base_addr(value, page_sz); 981 if (!td->indirect) { 982 td->num_entries = (num_pages * page_sz) / td->entry_sz; 983 } else { 984 td->num_entries = (((num_pages * page_sz) / 985 L1TABLE_ENTRY_SIZE) * 986 (page_sz / td->entry_sz)); 987 } 988 td->num_entries = MIN(td->num_entries, 1ULL << idbits); 989 } 990 } 991 992 static void extract_cmdq_params(GICv3ITSState *s) 993 { 994 uint16_t num_pages = 0; 995 uint64_t value = s->cbaser; 996 997 num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1; 998 999 memset(&s->cq, 0 , sizeof(s->cq)); 1000 1001 if (FIELD_EX64(value, GITS_CBASER, VALID)) { 1002 s->cq.num_entries = (num_pages * GITS_PAGE_SIZE_4K) / 1003 GITS_CMDQ_ENTRY_SIZE; 1004 s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR); 1005 s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT; 1006 } 1007 } 1008 1009 static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset, 1010 uint64_t *data, unsigned size, 1011 MemTxAttrs attrs) 1012 { 1013 /* 1014 * GITS_TRANSLATER is write-only, and all other addresses 1015 * in the interrupt translation space frame are RES0. 1016 */ 1017 *data = 0; 1018 return MEMTX_OK; 1019 } 1020 1021 static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset, 1022 uint64_t data, unsigned size, 1023 MemTxAttrs attrs) 1024 { 1025 GICv3ITSState *s = (GICv3ITSState *)opaque; 1026 bool result = true; 1027 1028 trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id); 1029 1030 switch (offset) { 1031 case GITS_TRANSLATER: 1032 if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) { 1033 result = do_process_its_cmd(s, attrs.requester_id, data, NONE); 1034 } 1035 break; 1036 default: 1037 break; 1038 } 1039 1040 if (result) { 1041 return MEMTX_OK; 1042 } else { 1043 return MEMTX_ERROR; 1044 } 1045 } 1046 1047 static bool its_writel(GICv3ITSState *s, hwaddr offset, 1048 uint64_t value, MemTxAttrs attrs) 1049 { 1050 bool result = true; 1051 int index; 1052 1053 switch (offset) { 1054 case GITS_CTLR: 1055 if (value & R_GITS_CTLR_ENABLED_MASK) { 1056 s->ctlr |= R_GITS_CTLR_ENABLED_MASK; 1057 extract_table_params(s); 1058 extract_cmdq_params(s); 1059 process_cmdq(s); 1060 } else { 1061 s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK; 1062 } 1063 break; 1064 case GITS_CBASER: 1065 /* 1066 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 1067 * already enabled 1068 */ 1069 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 1070 s->cbaser = deposit64(s->cbaser, 0, 32, value); 1071 s->creadr = 0; 1072 } 1073 break; 1074 case GITS_CBASER + 4: 1075 /* 1076 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 1077 * already enabled 1078 */ 1079 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 1080 s->cbaser = deposit64(s->cbaser, 32, 32, value); 1081 s->creadr = 0; 1082 } 1083 break; 1084 case GITS_CWRITER: 1085 s->cwriter = deposit64(s->cwriter, 0, 32, 1086 (value & ~R_GITS_CWRITER_RETRY_MASK)); 1087 if (s->cwriter != s->creadr) { 1088 process_cmdq(s); 1089 } 1090 break; 1091 case GITS_CWRITER + 4: 1092 s->cwriter = deposit64(s->cwriter, 32, 32, value); 1093 break; 1094 case GITS_CREADR: 1095 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 1096 s->creadr = deposit64(s->creadr, 0, 32, 1097 (value & ~R_GITS_CREADR_STALLED_MASK)); 1098 } else { 1099 /* RO register, ignore the write */ 1100 qemu_log_mask(LOG_GUEST_ERROR, 1101 "%s: invalid guest write to RO register at offset " 1102 TARGET_FMT_plx "\n", __func__, offset); 1103 } 1104 break; 1105 case GITS_CREADR + 4: 1106 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 1107 s->creadr = deposit64(s->creadr, 32, 32, value); 1108 } else { 1109 /* RO register, ignore the write */ 1110 qemu_log_mask(LOG_GUEST_ERROR, 1111 "%s: invalid guest write to RO register at offset " 1112 TARGET_FMT_plx "\n", __func__, offset); 1113 } 1114 break; 1115 case GITS_BASER ... GITS_BASER + 0x3f: 1116 /* 1117 * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is 1118 * already enabled 1119 */ 1120 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 1121 index = (offset - GITS_BASER) / 8; 1122 1123 if (s->baser[index] == 0) { 1124 /* Unimplemented GITS_BASERn: RAZ/WI */ 1125 break; 1126 } 1127 if (offset & 7) { 1128 value <<= 32; 1129 value &= ~GITS_BASER_RO_MASK; 1130 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(0, 32); 1131 s->baser[index] |= value; 1132 } else { 1133 value &= ~GITS_BASER_RO_MASK; 1134 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(32, 32); 1135 s->baser[index] |= value; 1136 } 1137 } 1138 break; 1139 case GITS_IIDR: 1140 case GITS_IDREGS ... GITS_IDREGS + 0x2f: 1141 /* RO registers, ignore the write */ 1142 qemu_log_mask(LOG_GUEST_ERROR, 1143 "%s: invalid guest write to RO register at offset " 1144 TARGET_FMT_plx "\n", __func__, offset); 1145 break; 1146 default: 1147 result = false; 1148 break; 1149 } 1150 return result; 1151 } 1152 1153 static bool its_readl(GICv3ITSState *s, hwaddr offset, 1154 uint64_t *data, MemTxAttrs attrs) 1155 { 1156 bool result = true; 1157 int index; 1158 1159 switch (offset) { 1160 case GITS_CTLR: 1161 *data = s->ctlr; 1162 break; 1163 case GITS_IIDR: 1164 *data = gicv3_iidr(); 1165 break; 1166 case GITS_IDREGS ... GITS_IDREGS + 0x2f: 1167 /* ID registers */ 1168 *data = gicv3_idreg(offset - GITS_IDREGS, GICV3_PIDR0_ITS); 1169 break; 1170 case GITS_TYPER: 1171 *data = extract64(s->typer, 0, 32); 1172 break; 1173 case GITS_TYPER + 4: 1174 *data = extract64(s->typer, 32, 32); 1175 break; 1176 case GITS_CBASER: 1177 *data = extract64(s->cbaser, 0, 32); 1178 break; 1179 case GITS_CBASER + 4: 1180 *data = extract64(s->cbaser, 32, 32); 1181 break; 1182 case GITS_CREADR: 1183 *data = extract64(s->creadr, 0, 32); 1184 break; 1185 case GITS_CREADR + 4: 1186 *data = extract64(s->creadr, 32, 32); 1187 break; 1188 case GITS_CWRITER: 1189 *data = extract64(s->cwriter, 0, 32); 1190 break; 1191 case GITS_CWRITER + 4: 1192 *data = extract64(s->cwriter, 32, 32); 1193 break; 1194 case GITS_BASER ... GITS_BASER + 0x3f: 1195 index = (offset - GITS_BASER) / 8; 1196 if (offset & 7) { 1197 *data = extract64(s->baser[index], 32, 32); 1198 } else { 1199 *data = extract64(s->baser[index], 0, 32); 1200 } 1201 break; 1202 default: 1203 result = false; 1204 break; 1205 } 1206 return result; 1207 } 1208 1209 static bool its_writell(GICv3ITSState *s, hwaddr offset, 1210 uint64_t value, MemTxAttrs attrs) 1211 { 1212 bool result = true; 1213 int index; 1214 1215 switch (offset) { 1216 case GITS_BASER ... GITS_BASER + 0x3f: 1217 /* 1218 * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is 1219 * already enabled 1220 */ 1221 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 1222 index = (offset - GITS_BASER) / 8; 1223 if (s->baser[index] == 0) { 1224 /* Unimplemented GITS_BASERn: RAZ/WI */ 1225 break; 1226 } 1227 s->baser[index] &= GITS_BASER_RO_MASK; 1228 s->baser[index] |= (value & ~GITS_BASER_RO_MASK); 1229 } 1230 break; 1231 case GITS_CBASER: 1232 /* 1233 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 1234 * already enabled 1235 */ 1236 if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) { 1237 s->cbaser = value; 1238 s->creadr = 0; 1239 } 1240 break; 1241 case GITS_CWRITER: 1242 s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK; 1243 if (s->cwriter != s->creadr) { 1244 process_cmdq(s); 1245 } 1246 break; 1247 case GITS_CREADR: 1248 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 1249 s->creadr = value & ~R_GITS_CREADR_STALLED_MASK; 1250 } else { 1251 /* RO register, ignore the write */ 1252 qemu_log_mask(LOG_GUEST_ERROR, 1253 "%s: invalid guest write to RO register at offset " 1254 TARGET_FMT_plx "\n", __func__, offset); 1255 } 1256 break; 1257 case GITS_TYPER: 1258 /* RO registers, ignore the write */ 1259 qemu_log_mask(LOG_GUEST_ERROR, 1260 "%s: invalid guest write to RO register at offset " 1261 TARGET_FMT_plx "\n", __func__, offset); 1262 break; 1263 default: 1264 result = false; 1265 break; 1266 } 1267 return result; 1268 } 1269 1270 static bool its_readll(GICv3ITSState *s, hwaddr offset, 1271 uint64_t *data, MemTxAttrs attrs) 1272 { 1273 bool result = true; 1274 int index; 1275 1276 switch (offset) { 1277 case GITS_TYPER: 1278 *data = s->typer; 1279 break; 1280 case GITS_BASER ... GITS_BASER + 0x3f: 1281 index = (offset - GITS_BASER) / 8; 1282 *data = s->baser[index]; 1283 break; 1284 case GITS_CBASER: 1285 *data = s->cbaser; 1286 break; 1287 case GITS_CREADR: 1288 *data = s->creadr; 1289 break; 1290 case GITS_CWRITER: 1291 *data = s->cwriter; 1292 break; 1293 default: 1294 result = false; 1295 break; 1296 } 1297 return result; 1298 } 1299 1300 static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data, 1301 unsigned size, MemTxAttrs attrs) 1302 { 1303 GICv3ITSState *s = (GICv3ITSState *)opaque; 1304 bool result; 1305 1306 switch (size) { 1307 case 4: 1308 result = its_readl(s, offset, data, attrs); 1309 break; 1310 case 8: 1311 result = its_readll(s, offset, data, attrs); 1312 break; 1313 default: 1314 result = false; 1315 break; 1316 } 1317 1318 if (!result) { 1319 qemu_log_mask(LOG_GUEST_ERROR, 1320 "%s: invalid guest read at offset " TARGET_FMT_plx 1321 " size %u\n", __func__, offset, size); 1322 trace_gicv3_its_badread(offset, size); 1323 /* 1324 * The spec requires that reserved registers are RAZ/WI; 1325 * so use false returns from leaf functions as a way to 1326 * trigger the guest-error logging but don't return it to 1327 * the caller, or we'll cause a spurious guest data abort. 1328 */ 1329 *data = 0; 1330 } else { 1331 trace_gicv3_its_read(offset, *data, size); 1332 } 1333 return MEMTX_OK; 1334 } 1335 1336 static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data, 1337 unsigned size, MemTxAttrs attrs) 1338 { 1339 GICv3ITSState *s = (GICv3ITSState *)opaque; 1340 bool result; 1341 1342 switch (size) { 1343 case 4: 1344 result = its_writel(s, offset, data, attrs); 1345 break; 1346 case 8: 1347 result = its_writell(s, offset, data, attrs); 1348 break; 1349 default: 1350 result = false; 1351 break; 1352 } 1353 1354 if (!result) { 1355 qemu_log_mask(LOG_GUEST_ERROR, 1356 "%s: invalid guest write at offset " TARGET_FMT_plx 1357 " size %u\n", __func__, offset, size); 1358 trace_gicv3_its_badwrite(offset, data, size); 1359 /* 1360 * The spec requires that reserved registers are RAZ/WI; 1361 * so use false returns from leaf functions as a way to 1362 * trigger the guest-error logging but don't return it to 1363 * the caller, or we'll cause a spurious guest data abort. 1364 */ 1365 } else { 1366 trace_gicv3_its_write(offset, data, size); 1367 } 1368 return MEMTX_OK; 1369 } 1370 1371 static const MemoryRegionOps gicv3_its_control_ops = { 1372 .read_with_attrs = gicv3_its_read, 1373 .write_with_attrs = gicv3_its_write, 1374 .valid.min_access_size = 4, 1375 .valid.max_access_size = 8, 1376 .impl.min_access_size = 4, 1377 .impl.max_access_size = 8, 1378 .endianness = DEVICE_NATIVE_ENDIAN, 1379 }; 1380 1381 static const MemoryRegionOps gicv3_its_translation_ops = { 1382 .read_with_attrs = gicv3_its_translation_read, 1383 .write_with_attrs = gicv3_its_translation_write, 1384 .valid.min_access_size = 2, 1385 .valid.max_access_size = 4, 1386 .impl.min_access_size = 2, 1387 .impl.max_access_size = 4, 1388 .endianness = DEVICE_NATIVE_ENDIAN, 1389 }; 1390 1391 static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) 1392 { 1393 GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); 1394 int i; 1395 1396 for (i = 0; i < s->gicv3->num_cpu; i++) { 1397 if (!(s->gicv3->cpu[i].gicr_typer & GICR_TYPER_PLPIS)) { 1398 error_setg(errp, "Physical LPI not supported by CPU %d", i); 1399 return; 1400 } 1401 } 1402 1403 gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops); 1404 1405 /* set the ITS default features supported */ 1406 s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1); 1407 s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE, 1408 ITS_ITT_ENTRY_SIZE - 1); 1409 s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS); 1410 s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS); 1411 s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1); 1412 s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS); 1413 } 1414 1415 static void gicv3_its_reset(DeviceState *dev) 1416 { 1417 GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); 1418 GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); 1419 1420 c->parent_reset(dev); 1421 1422 /* Quiescent bit reset to 1 */ 1423 s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1); 1424 1425 /* 1426 * setting GITS_BASER0.Type = 0b001 (Device) 1427 * GITS_BASER1.Type = 0b100 (Collection Table) 1428 * GITS_BASER<n>.Type,where n = 3 to 7 are 0b00 (Unimplemented) 1429 * GITS_BASER<0,1>.Page_Size = 64KB 1430 * and default translation table entry size to 16 bytes 1431 */ 1432 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE, 1433 GITS_BASER_TYPE_DEVICE); 1434 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE, 1435 GITS_BASER_PAGESIZE_64K); 1436 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE, 1437 GITS_DTE_SIZE - 1); 1438 1439 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE, 1440 GITS_BASER_TYPE_COLLECTION); 1441 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE, 1442 GITS_BASER_PAGESIZE_64K); 1443 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE, 1444 GITS_CTE_SIZE - 1); 1445 } 1446 1447 static void gicv3_its_post_load(GICv3ITSState *s) 1448 { 1449 if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) { 1450 extract_table_params(s); 1451 extract_cmdq_params(s); 1452 } 1453 } 1454 1455 static Property gicv3_its_props[] = { 1456 DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3", 1457 GICv3State *), 1458 DEFINE_PROP_END_OF_LIST(), 1459 }; 1460 1461 static void gicv3_its_class_init(ObjectClass *klass, void *data) 1462 { 1463 DeviceClass *dc = DEVICE_CLASS(klass); 1464 GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass); 1465 GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass); 1466 1467 dc->realize = gicv3_arm_its_realize; 1468 device_class_set_props(dc, gicv3_its_props); 1469 device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset); 1470 icc->post_load = gicv3_its_post_load; 1471 } 1472 1473 static const TypeInfo gicv3_its_info = { 1474 .name = TYPE_ARM_GICV3_ITS, 1475 .parent = TYPE_ARM_GICV3_ITS_COMMON, 1476 .instance_size = sizeof(GICv3ITSState), 1477 .class_init = gicv3_its_class_init, 1478 .class_size = sizeof(GICv3ITSClass), 1479 }; 1480 1481 static void gicv3_its_register_types(void) 1482 { 1483 type_register_static(&gicv3_its_info); 1484 } 1485 1486 type_init(gicv3_its_register_types) 1487