arm_gicv3_its.c (40205B)
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 "hw/qdev-properties.h" 17#include "hw/intc/arm_gicv3_its_common.h" 18#include "gicv3_internal.h" 19#include "qom/object.h" 20#include "qapi/error.h" 21 22typedef struct GICv3ITSClass GICv3ITSClass; 23/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */ 24DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, 25 ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) 26 27struct GICv3ITSClass { 28 GICv3ITSCommonClass parent_class; 29 void (*parent_reset)(DeviceState *dev); 30}; 31 32/* 33 * This is an internal enum used to distinguish between LPI triggered 34 * via command queue and LPI triggered via gits_translater write. 35 */ 36typedef enum ItsCmdType { 37 NONE = 0, /* internal indication for GITS_TRANSLATER write */ 38 CLEAR = 1, 39 DISCARD = 2, 40 INTERRUPT = 3, 41} ItsCmdType; 42 43typedef struct { 44 uint32_t iteh; 45 uint64_t itel; 46} IteEntry; 47 48static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) 49{ 50 uint64_t result = 0; 51 52 switch (page_sz) { 53 case GITS_PAGE_SIZE_4K: 54 case GITS_PAGE_SIZE_16K: 55 result = FIELD_EX64(value, GITS_BASER, PHYADDR) << 12; 56 break; 57 58 case GITS_PAGE_SIZE_64K: 59 result = FIELD_EX64(value, GITS_BASER, PHYADDRL_64K) << 16; 60 result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48; 61 break; 62 63 default: 64 break; 65 } 66 return result; 67} 68 69static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte, 70 MemTxResult *res) 71{ 72 AddressSpace *as = &s->gicv3->dma_as; 73 uint64_t l2t_addr; 74 uint64_t value; 75 bool valid_l2t; 76 uint32_t l2t_id; 77 uint32_t max_l2_entries; 78 79 if (s->ct.indirect) { 80 l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE); 81 82 value = address_space_ldq_le(as, 83 s->ct.base_addr + 84 (l2t_id * L1TABLE_ENTRY_SIZE), 85 MEMTXATTRS_UNSPECIFIED, res); 86 87 if (*res == MEMTX_OK) { 88 valid_l2t = (value & L2_TABLE_VALID_MASK) != 0; 89 90 if (valid_l2t) { 91 max_l2_entries = s->ct.page_sz / s->ct.entry_sz; 92 93 l2t_addr = value & ((1ULL << 51) - 1); 94 95 *cte = address_space_ldq_le(as, l2t_addr + 96 ((icid % max_l2_entries) * GITS_CTE_SIZE), 97 MEMTXATTRS_UNSPECIFIED, res); 98 } 99 } 100 } else { 101 /* Flat level table */ 102 *cte = address_space_ldq_le(as, s->ct.base_addr + 103 (icid * GITS_CTE_SIZE), 104 MEMTXATTRS_UNSPECIFIED, res); 105 } 106 107 return (*cte & TABLE_ENTRY_VALID_MASK) != 0; 108} 109 110static bool update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte, 111 IteEntry ite) 112{ 113 AddressSpace *as = &s->gicv3->dma_as; 114 uint64_t itt_addr; 115 MemTxResult res = MEMTX_OK; 116 117 itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT; 118 itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */ 119 120 address_space_stq_le(as, itt_addr + (eventid * (sizeof(uint64_t) + 121 sizeof(uint32_t))), ite.itel, MEMTXATTRS_UNSPECIFIED, 122 &res); 123 124 if (res == MEMTX_OK) { 125 address_space_stl_le(as, itt_addr + (eventid * (sizeof(uint64_t) + 126 sizeof(uint32_t))) + sizeof(uint32_t), ite.iteh, 127 MEMTXATTRS_UNSPECIFIED, &res); 128 } 129 if (res != MEMTX_OK) { 130 return false; 131 } else { 132 return true; 133 } 134} 135 136static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte, 137 uint16_t *icid, uint32_t *pIntid, MemTxResult *res) 138{ 139 AddressSpace *as = &s->gicv3->dma_as; 140 uint64_t itt_addr; 141 bool status = false; 142 IteEntry ite = {}; 143 144 itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT; 145 itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */ 146 147 ite.itel = address_space_ldq_le(as, itt_addr + 148 (eventid * (sizeof(uint64_t) + 149 sizeof(uint32_t))), MEMTXATTRS_UNSPECIFIED, 150 res); 151 152 if (*res == MEMTX_OK) { 153 ite.iteh = address_space_ldl_le(as, itt_addr + 154 (eventid * (sizeof(uint64_t) + 155 sizeof(uint32_t))) + sizeof(uint32_t), 156 MEMTXATTRS_UNSPECIFIED, res); 157 158 if (*res == MEMTX_OK) { 159 if (ite.itel & TABLE_ENTRY_VALID_MASK) { 160 if ((ite.itel >> ITE_ENTRY_INTTYPE_SHIFT) & 161 GITS_TYPE_PHYSICAL) { 162 *pIntid = (ite.itel & ITE_ENTRY_INTID_MASK) >> 163 ITE_ENTRY_INTID_SHIFT; 164 *icid = ite.iteh & ITE_ENTRY_ICID_MASK; 165 status = true; 166 } 167 } 168 } 169 } 170 return status; 171} 172 173static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res) 174{ 175 AddressSpace *as = &s->gicv3->dma_as; 176 uint64_t l2t_addr; 177 uint64_t value; 178 bool valid_l2t; 179 uint32_t l2t_id; 180 uint32_t max_l2_entries; 181 182 if (s->dt.indirect) { 183 l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE); 184 185 value = address_space_ldq_le(as, 186 s->dt.base_addr + 187 (l2t_id * L1TABLE_ENTRY_SIZE), 188 MEMTXATTRS_UNSPECIFIED, res); 189 190 if (*res == MEMTX_OK) { 191 valid_l2t = (value & L2_TABLE_VALID_MASK) != 0; 192 193 if (valid_l2t) { 194 max_l2_entries = s->dt.page_sz / s->dt.entry_sz; 195 196 l2t_addr = value & ((1ULL << 51) - 1); 197 198 value = address_space_ldq_le(as, l2t_addr + 199 ((devid % max_l2_entries) * GITS_DTE_SIZE), 200 MEMTXATTRS_UNSPECIFIED, res); 201 } 202 } 203 } else { 204 /* Flat level table */ 205 value = address_space_ldq_le(as, s->dt.base_addr + 206 (devid * GITS_DTE_SIZE), 207 MEMTXATTRS_UNSPECIFIED, res); 208 } 209 210 return value; 211} 212 213/* 214 * This function handles the processing of following commands based on 215 * the ItsCmdType parameter passed:- 216 * 1. triggering of lpi interrupt translation via ITS INT command 217 * 2. triggering of lpi interrupt translation via gits_translater register 218 * 3. handling of ITS CLEAR command 219 * 4. handling of ITS DISCARD command 220 */ 221static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset, 222 ItsCmdType cmd) 223{ 224 AddressSpace *as = &s->gicv3->dma_as; 225 uint32_t devid, eventid; 226 MemTxResult res = MEMTX_OK; 227 bool dte_valid; 228 uint64_t dte = 0; 229 uint32_t max_eventid; 230 uint16_t icid = 0; 231 uint32_t pIntid = 0; 232 bool ite_valid = false; 233 uint64_t cte = 0; 234 bool cte_valid = false; 235 bool result = false; 236 uint64_t rdbase; 237 238 if (cmd == NONE) { 239 devid = offset; 240 } else { 241 devid = ((value & DEVID_MASK) >> DEVID_SHIFT); 242 243 offset += NUM_BYTES_IN_DW; 244 value = address_space_ldq_le(as, s->cq.base_addr + offset, 245 MEMTXATTRS_UNSPECIFIED, &res); 246 } 247 248 if (res != MEMTX_OK) { 249 return result; 250 } 251 252 eventid = (value & EVENTID_MASK); 253 254 dte = get_dte(s, devid, &res); 255 256 if (res != MEMTX_OK) { 257 return result; 258 } 259 dte_valid = dte & TABLE_ENTRY_VALID_MASK; 260 261 if (dte_valid) { 262 max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); 263 264 ite_valid = get_ite(s, eventid, dte, &icid, &pIntid, &res); 265 266 if (res != MEMTX_OK) { 267 return result; 268 } 269 270 if (ite_valid) { 271 cte_valid = get_cte(s, icid, &cte, &res); 272 } 273 274 if (res != MEMTX_OK) { 275 return result; 276 } 277 } 278 279 if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid || 280 !cte_valid || (eventid > max_eventid)) { 281 qemu_log_mask(LOG_GUEST_ERROR, 282 "%s: invalid command attributes " 283 "devid %d or eventid %d or invalid dte %d or" 284 "invalid cte %d or invalid ite %d\n", 285 __func__, devid, eventid, dte_valid, cte_valid, 286 ite_valid); 287 /* 288 * in this implementation, in case of error 289 * we ignore this command and move onto the next 290 * command in the queue 291 */ 292 } else { 293 /* 294 * Current implementation only supports rdbase == procnum 295 * Hence rdbase physical address is ignored 296 */ 297 rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U; 298 299 if (rdbase > s->gicv3->num_cpu) { 300 return result; 301 } 302 303 if ((cmd == CLEAR) || (cmd == DISCARD)) { 304 gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0); 305 } else { 306 gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1); 307 } 308 309 if (cmd == DISCARD) { 310 IteEntry ite = {}; 311 /* remove mapping from interrupt translation table */ 312 result = update_ite(s, eventid, dte, ite); 313 } 314 } 315 316 return result; 317} 318 319static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset, 320 bool ignore_pInt) 321{ 322 AddressSpace *as = &s->gicv3->dma_as; 323 uint32_t devid, eventid; 324 uint32_t pIntid = 0; 325 uint32_t max_eventid, max_Intid; 326 bool dte_valid; 327 MemTxResult res = MEMTX_OK; 328 uint16_t icid = 0; 329 uint64_t dte = 0; 330 IteEntry ite; 331 uint32_t int_spurious = INTID_SPURIOUS; 332 bool result = false; 333 334 devid = ((value & DEVID_MASK) >> DEVID_SHIFT); 335 offset += NUM_BYTES_IN_DW; 336 value = address_space_ldq_le(as, s->cq.base_addr + offset, 337 MEMTXATTRS_UNSPECIFIED, &res); 338 339 if (res != MEMTX_OK) { 340 return result; 341 } 342 343 eventid = (value & EVENTID_MASK); 344 345 if (!ignore_pInt) { 346 pIntid = ((value & pINTID_MASK) >> pINTID_SHIFT); 347 } 348 349 offset += NUM_BYTES_IN_DW; 350 value = address_space_ldq_le(as, s->cq.base_addr + offset, 351 MEMTXATTRS_UNSPECIFIED, &res); 352 353 if (res != MEMTX_OK) { 354 return result; 355 } 356 357 icid = value & ICID_MASK; 358 359 dte = get_dte(s, devid, &res); 360 361 if (res != MEMTX_OK) { 362 return result; 363 } 364 dte_valid = dte & TABLE_ENTRY_VALID_MASK; 365 366 max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); 367 368 if (!ignore_pInt) { 369 max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1; 370 } 371 372 if ((devid > s->dt.maxids.max_devids) || (icid > s->ct.maxids.max_collids) 373 || !dte_valid || (eventid > max_eventid) || 374 (!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) || 375 (pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) { 376 qemu_log_mask(LOG_GUEST_ERROR, 377 "%s: invalid command attributes " 378 "devid %d or icid %d or eventid %d or pIntid %d or" 379 "unmapped dte %d\n", __func__, devid, icid, eventid, 380 pIntid, dte_valid); 381 /* 382 * in this implementation, in case of error 383 * we ignore this command and move onto the next 384 * command in the queue 385 */ 386 } else { 387 /* add ite entry to interrupt translation table */ 388 ite.itel = (dte_valid & TABLE_ENTRY_VALID_MASK) | 389 (GITS_TYPE_PHYSICAL << ITE_ENTRY_INTTYPE_SHIFT); 390 391 if (ignore_pInt) { 392 ite.itel |= (eventid << ITE_ENTRY_INTID_SHIFT); 393 } else { 394 ite.itel |= (pIntid << ITE_ENTRY_INTID_SHIFT); 395 } 396 ite.itel |= (int_spurious << ITE_ENTRY_INTSP_SHIFT); 397 ite.iteh = icid; 398 399 result = update_ite(s, eventid, dte, ite); 400 } 401 402 return result; 403} 404 405static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid, 406 uint64_t rdbase) 407{ 408 AddressSpace *as = &s->gicv3->dma_as; 409 uint64_t value; 410 uint64_t l2t_addr; 411 bool valid_l2t; 412 uint32_t l2t_id; 413 uint32_t max_l2_entries; 414 uint64_t cte = 0; 415 MemTxResult res = MEMTX_OK; 416 417 if (!s->ct.valid) { 418 return true; 419 } 420 421 if (valid) { 422 /* add mapping entry to collection table */ 423 cte = (valid & TABLE_ENTRY_VALID_MASK) | (rdbase << 1ULL); 424 } 425 426 /* 427 * The specification defines the format of level 1 entries of a 428 * 2-level table, but the format of level 2 entries and the format 429 * of flat-mapped tables is IMPDEF. 430 */ 431 if (s->ct.indirect) { 432 l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE); 433 434 value = address_space_ldq_le(as, 435 s->ct.base_addr + 436 (l2t_id * L1TABLE_ENTRY_SIZE), 437 MEMTXATTRS_UNSPECIFIED, &res); 438 439 if (res != MEMTX_OK) { 440 return false; 441 } 442 443 valid_l2t = (value & L2_TABLE_VALID_MASK) != 0; 444 445 if (valid_l2t) { 446 max_l2_entries = s->ct.page_sz / s->ct.entry_sz; 447 448 l2t_addr = value & ((1ULL << 51) - 1); 449 450 address_space_stq_le(as, l2t_addr + 451 ((icid % max_l2_entries) * GITS_CTE_SIZE), 452 cte, MEMTXATTRS_UNSPECIFIED, &res); 453 } 454 } else { 455 /* Flat level table */ 456 address_space_stq_le(as, s->ct.base_addr + (icid * GITS_CTE_SIZE), 457 cte, MEMTXATTRS_UNSPECIFIED, &res); 458 } 459 if (res != MEMTX_OK) { 460 return false; 461 } else { 462 return true; 463 } 464} 465 466static bool process_mapc(GICv3ITSState *s, uint32_t offset) 467{ 468 AddressSpace *as = &s->gicv3->dma_as; 469 uint16_t icid; 470 uint64_t rdbase; 471 bool valid; 472 MemTxResult res = MEMTX_OK; 473 bool result = false; 474 uint64_t value; 475 476 offset += NUM_BYTES_IN_DW; 477 offset += NUM_BYTES_IN_DW; 478 479 value = address_space_ldq_le(as, s->cq.base_addr + offset, 480 MEMTXATTRS_UNSPECIFIED, &res); 481 482 if (res != MEMTX_OK) { 483 return result; 484 } 485 486 icid = value & ICID_MASK; 487 488 rdbase = (value & R_MAPC_RDBASE_MASK) >> R_MAPC_RDBASE_SHIFT; 489 rdbase &= RDBASE_PROCNUM_MASK; 490 491 valid = (value & CMD_FIELD_VALID_MASK); 492 493 if ((icid > s->ct.maxids.max_collids) || (rdbase > s->gicv3->num_cpu)) { 494 qemu_log_mask(LOG_GUEST_ERROR, 495 "ITS MAPC: invalid collection table attributes " 496 "icid %d rdbase %" PRIu64 "\n", icid, rdbase); 497 /* 498 * in this implementation, in case of error 499 * we ignore this command and move onto the next 500 * command in the queue 501 */ 502 } else { 503 result = update_cte(s, icid, valid, rdbase); 504 } 505 506 return result; 507} 508 509static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid, 510 uint8_t size, uint64_t itt_addr) 511{ 512 AddressSpace *as = &s->gicv3->dma_as; 513 uint64_t value; 514 uint64_t l2t_addr; 515 bool valid_l2t; 516 uint32_t l2t_id; 517 uint32_t max_l2_entries; 518 uint64_t dte = 0; 519 MemTxResult res = MEMTX_OK; 520 521 if (s->dt.valid) { 522 if (valid) { 523 /* add mapping entry to device table */ 524 dte = (valid & TABLE_ENTRY_VALID_MASK) | 525 ((size & SIZE_MASK) << 1U) | 526 (itt_addr << GITS_DTE_ITTADDR_SHIFT); 527 } 528 } else { 529 return true; 530 } 531 532 /* 533 * The specification defines the format of level 1 entries of a 534 * 2-level table, but the format of level 2 entries and the format 535 * of flat-mapped tables is IMPDEF. 536 */ 537 if (s->dt.indirect) { 538 l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE); 539 540 value = address_space_ldq_le(as, 541 s->dt.base_addr + 542 (l2t_id * L1TABLE_ENTRY_SIZE), 543 MEMTXATTRS_UNSPECIFIED, &res); 544 545 if (res != MEMTX_OK) { 546 return false; 547 } 548 549 valid_l2t = (value & L2_TABLE_VALID_MASK) != 0; 550 551 if (valid_l2t) { 552 max_l2_entries = s->dt.page_sz / s->dt.entry_sz; 553 554 l2t_addr = value & ((1ULL << 51) - 1); 555 556 address_space_stq_le(as, l2t_addr + 557 ((devid % max_l2_entries) * GITS_DTE_SIZE), 558 dte, MEMTXATTRS_UNSPECIFIED, &res); 559 } 560 } else { 561 /* Flat level table */ 562 address_space_stq_le(as, s->dt.base_addr + (devid * GITS_DTE_SIZE), 563 dte, MEMTXATTRS_UNSPECIFIED, &res); 564 } 565 if (res != MEMTX_OK) { 566 return false; 567 } else { 568 return true; 569 } 570} 571 572static bool process_mapd(GICv3ITSState *s, uint64_t value, uint32_t offset) 573{ 574 AddressSpace *as = &s->gicv3->dma_as; 575 uint32_t devid; 576 uint8_t size; 577 uint64_t itt_addr; 578 bool valid; 579 MemTxResult res = MEMTX_OK; 580 bool result = false; 581 582 devid = ((value & DEVID_MASK) >> DEVID_SHIFT); 583 584 offset += NUM_BYTES_IN_DW; 585 value = address_space_ldq_le(as, s->cq.base_addr + offset, 586 MEMTXATTRS_UNSPECIFIED, &res); 587 588 if (res != MEMTX_OK) { 589 return result; 590 } 591 592 size = (value & SIZE_MASK); 593 594 offset += NUM_BYTES_IN_DW; 595 value = address_space_ldq_le(as, s->cq.base_addr + offset, 596 MEMTXATTRS_UNSPECIFIED, &res); 597 598 if (res != MEMTX_OK) { 599 return result; 600 } 601 602 itt_addr = (value & ITTADDR_MASK) >> ITTADDR_SHIFT; 603 604 valid = (value & CMD_FIELD_VALID_MASK); 605 606 if ((devid > s->dt.maxids.max_devids) || 607 (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) { 608 qemu_log_mask(LOG_GUEST_ERROR, 609 "ITS MAPD: invalid device table attributes " 610 "devid %d or size %d\n", devid, size); 611 /* 612 * in this implementation, in case of error 613 * we ignore this command and move onto the next 614 * command in the queue 615 */ 616 } else { 617 result = update_dte(s, devid, valid, size, itt_addr); 618 } 619 620 return result; 621} 622 623/* 624 * Current implementation blocks until all 625 * commands are processed 626 */ 627static void process_cmdq(GICv3ITSState *s) 628{ 629 uint32_t wr_offset = 0; 630 uint32_t rd_offset = 0; 631 uint32_t cq_offset = 0; 632 uint64_t data; 633 AddressSpace *as = &s->gicv3->dma_as; 634 MemTxResult res = MEMTX_OK; 635 bool result = true; 636 uint8_t cmd; 637 int i; 638 639 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 640 return; 641 } 642 643 wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET); 644 645 if (wr_offset > s->cq.max_entries) { 646 qemu_log_mask(LOG_GUEST_ERROR, 647 "%s: invalid write offset " 648 "%d\n", __func__, wr_offset); 649 return; 650 } 651 652 rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET); 653 654 if (rd_offset > s->cq.max_entries) { 655 qemu_log_mask(LOG_GUEST_ERROR, 656 "%s: invalid read offset " 657 "%d\n", __func__, rd_offset); 658 return; 659 } 660 661 while (wr_offset != rd_offset) { 662 cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE); 663 data = address_space_ldq_le(as, s->cq.base_addr + cq_offset, 664 MEMTXATTRS_UNSPECIFIED, &res); 665 if (res != MEMTX_OK) { 666 result = false; 667 } 668 cmd = (data & CMD_MASK); 669 670 switch (cmd) { 671 case GITS_CMD_INT: 672 res = process_its_cmd(s, data, cq_offset, INTERRUPT); 673 break; 674 case GITS_CMD_CLEAR: 675 res = process_its_cmd(s, data, cq_offset, CLEAR); 676 break; 677 case GITS_CMD_SYNC: 678 /* 679 * Current implementation makes a blocking synchronous call 680 * for every command issued earlier, hence the internal state 681 * is already consistent by the time SYNC command is executed. 682 * Hence no further processing is required for SYNC command. 683 */ 684 break; 685 case GITS_CMD_MAPD: 686 result = process_mapd(s, data, cq_offset); 687 break; 688 case GITS_CMD_MAPC: 689 result = process_mapc(s, cq_offset); 690 break; 691 case GITS_CMD_MAPTI: 692 result = process_mapti(s, data, cq_offset, false); 693 break; 694 case GITS_CMD_MAPI: 695 result = process_mapti(s, data, cq_offset, true); 696 break; 697 case GITS_CMD_DISCARD: 698 result = process_its_cmd(s, data, cq_offset, DISCARD); 699 break; 700 case GITS_CMD_INV: 701 case GITS_CMD_INVALL: 702 /* 703 * Current implementation doesn't cache any ITS tables, 704 * but the calculated lpi priority information. We only 705 * need to trigger lpi priority re-calculation to be in 706 * sync with LPI config table or pending table changes. 707 */ 708 for (i = 0; i < s->gicv3->num_cpu; i++) { 709 gicv3_redist_update_lpi(&s->gicv3->cpu[i]); 710 } 711 break; 712 default: 713 break; 714 } 715 if (result) { 716 rd_offset++; 717 rd_offset %= s->cq.max_entries; 718 s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset); 719 } else { 720 /* 721 * in this implementation, in case of dma read/write error 722 * we stall the command processing 723 */ 724 s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1); 725 qemu_log_mask(LOG_GUEST_ERROR, 726 "%s: %x cmd processing failed\n", __func__, cmd); 727 break; 728 } 729 } 730} 731 732/* 733 * This function extracts the ITS Device and Collection table specific 734 * parameters (like base_addr, size etc) from GITS_BASER register. 735 * It is called during ITS enable and also during post_load migration 736 */ 737static void extract_table_params(GICv3ITSState *s) 738{ 739 uint16_t num_pages = 0; 740 uint8_t page_sz_type; 741 uint8_t type; 742 uint32_t page_sz = 0; 743 uint64_t value; 744 745 for (int i = 0; i < 8; i++) { 746 value = s->baser[i]; 747 748 if (!value) { 749 continue; 750 } 751 752 page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE); 753 754 switch (page_sz_type) { 755 case 0: 756 page_sz = GITS_PAGE_SIZE_4K; 757 break; 758 759 case 1: 760 page_sz = GITS_PAGE_SIZE_16K; 761 break; 762 763 case 2: 764 case 3: 765 page_sz = GITS_PAGE_SIZE_64K; 766 break; 767 768 default: 769 g_assert_not_reached(); 770 } 771 772 num_pages = FIELD_EX64(value, GITS_BASER, SIZE) + 1; 773 774 type = FIELD_EX64(value, GITS_BASER, TYPE); 775 776 switch (type) { 777 778 case GITS_BASER_TYPE_DEVICE: 779 memset(&s->dt, 0 , sizeof(s->dt)); 780 s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID); 781 782 if (!s->dt.valid) { 783 return; 784 } 785 786 s->dt.page_sz = page_sz; 787 s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT); 788 s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE); 789 790 if (!s->dt.indirect) { 791 s->dt.max_entries = (num_pages * page_sz) / s->dt.entry_sz; 792 } else { 793 s->dt.max_entries = (((num_pages * page_sz) / 794 L1TABLE_ENTRY_SIZE) * 795 (page_sz / s->dt.entry_sz)); 796 } 797 798 s->dt.maxids.max_devids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER, 799 DEVBITS) + 1)); 800 801 s->dt.base_addr = baser_base_addr(value, page_sz); 802 803 break; 804 805 case GITS_BASER_TYPE_COLLECTION: 806 memset(&s->ct, 0 , sizeof(s->ct)); 807 s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID); 808 809 /* 810 * GITS_TYPER.HCC is 0 for this implementation 811 * hence writes are discarded if ct.valid is 0 812 */ 813 if (!s->ct.valid) { 814 return; 815 } 816 817 s->ct.page_sz = page_sz; 818 s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT); 819 s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE); 820 821 if (!s->ct.indirect) { 822 s->ct.max_entries = (num_pages * page_sz) / s->ct.entry_sz; 823 } else { 824 s->ct.max_entries = (((num_pages * page_sz) / 825 L1TABLE_ENTRY_SIZE) * 826 (page_sz / s->ct.entry_sz)); 827 } 828 829 if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) { 830 s->ct.maxids.max_collids = (1UL << (FIELD_EX64(s->typer, 831 GITS_TYPER, CIDBITS) + 1)); 832 } else { 833 /* 16-bit CollectionId supported when CIL == 0 */ 834 s->ct.maxids.max_collids = (1UL << 16); 835 } 836 837 s->ct.base_addr = baser_base_addr(value, page_sz); 838 839 break; 840 841 default: 842 break; 843 } 844 } 845} 846 847static void extract_cmdq_params(GICv3ITSState *s) 848{ 849 uint16_t num_pages = 0; 850 uint64_t value = s->cbaser; 851 852 num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1; 853 854 memset(&s->cq, 0 , sizeof(s->cq)); 855 s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID); 856 857 if (s->cq.valid) { 858 s->cq.max_entries = (num_pages * GITS_PAGE_SIZE_4K) / 859 GITS_CMDQ_ENTRY_SIZE; 860 s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR); 861 s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT; 862 } 863} 864 865static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset, 866 uint64_t data, unsigned size, 867 MemTxAttrs attrs) 868{ 869 GICv3ITSState *s = (GICv3ITSState *)opaque; 870 bool result = true; 871 uint32_t devid = 0; 872 873 switch (offset) { 874 case GITS_TRANSLATER: 875 if (s->ctlr & ITS_CTLR_ENABLED) { 876 devid = attrs.requester_id; 877 result = process_its_cmd(s, data, devid, NONE); 878 } 879 break; 880 default: 881 break; 882 } 883 884 if (result) { 885 return MEMTX_OK; 886 } else { 887 return MEMTX_ERROR; 888 } 889} 890 891static bool its_writel(GICv3ITSState *s, hwaddr offset, 892 uint64_t value, MemTxAttrs attrs) 893{ 894 bool result = true; 895 int index; 896 897 switch (offset) { 898 case GITS_CTLR: 899 s->ctlr |= (value & ~(s->ctlr)); 900 901 if (s->ctlr & ITS_CTLR_ENABLED) { 902 extract_table_params(s); 903 extract_cmdq_params(s); 904 s->creadr = 0; 905 process_cmdq(s); 906 } 907 break; 908 case GITS_CBASER: 909 /* 910 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 911 * already enabled 912 */ 913 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 914 s->cbaser = deposit64(s->cbaser, 0, 32, value); 915 s->creadr = 0; 916 s->cwriter = s->creadr; 917 } 918 break; 919 case GITS_CBASER + 4: 920 /* 921 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 922 * already enabled 923 */ 924 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 925 s->cbaser = deposit64(s->cbaser, 32, 32, value); 926 s->creadr = 0; 927 s->cwriter = s->creadr; 928 } 929 break; 930 case GITS_CWRITER: 931 s->cwriter = deposit64(s->cwriter, 0, 32, 932 (value & ~R_GITS_CWRITER_RETRY_MASK)); 933 if (s->cwriter != s->creadr) { 934 process_cmdq(s); 935 } 936 break; 937 case GITS_CWRITER + 4: 938 s->cwriter = deposit64(s->cwriter, 32, 32, value); 939 break; 940 case GITS_CREADR: 941 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 942 s->creadr = deposit64(s->creadr, 0, 32, 943 (value & ~R_GITS_CREADR_STALLED_MASK)); 944 } else { 945 /* RO register, ignore the write */ 946 qemu_log_mask(LOG_GUEST_ERROR, 947 "%s: invalid guest write to RO register at offset " 948 TARGET_FMT_plx "\n", __func__, offset); 949 } 950 break; 951 case GITS_CREADR + 4: 952 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 953 s->creadr = deposit64(s->creadr, 32, 32, value); 954 } else { 955 /* RO register, ignore the write */ 956 qemu_log_mask(LOG_GUEST_ERROR, 957 "%s: invalid guest write to RO register at offset " 958 TARGET_FMT_plx "\n", __func__, offset); 959 } 960 break; 961 case GITS_BASER ... GITS_BASER + 0x3f: 962 /* 963 * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is 964 * already enabled 965 */ 966 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 967 index = (offset - GITS_BASER) / 8; 968 969 if (offset & 7) { 970 value <<= 32; 971 value &= ~GITS_BASER_RO_MASK; 972 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(0, 32); 973 s->baser[index] |= value; 974 } else { 975 value &= ~GITS_BASER_RO_MASK; 976 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(32, 32); 977 s->baser[index] |= value; 978 } 979 } 980 break; 981 case GITS_IIDR: 982 case GITS_IDREGS ... GITS_IDREGS + 0x2f: 983 /* RO registers, ignore the write */ 984 qemu_log_mask(LOG_GUEST_ERROR, 985 "%s: invalid guest write to RO register at offset " 986 TARGET_FMT_plx "\n", __func__, offset); 987 break; 988 default: 989 result = false; 990 break; 991 } 992 return result; 993} 994 995static bool its_readl(GICv3ITSState *s, hwaddr offset, 996 uint64_t *data, MemTxAttrs attrs) 997{ 998 bool result = true; 999 int index; 1000 1001 switch (offset) { 1002 case GITS_CTLR: 1003 *data = s->ctlr; 1004 break; 1005 case GITS_IIDR: 1006 *data = gicv3_iidr(); 1007 break; 1008 case GITS_IDREGS ... GITS_IDREGS + 0x2f: 1009 /* ID registers */ 1010 *data = gicv3_idreg(offset - GITS_IDREGS); 1011 break; 1012 case GITS_TYPER: 1013 *data = extract64(s->typer, 0, 32); 1014 break; 1015 case GITS_TYPER + 4: 1016 *data = extract64(s->typer, 32, 32); 1017 break; 1018 case GITS_CBASER: 1019 *data = extract64(s->cbaser, 0, 32); 1020 break; 1021 case GITS_CBASER + 4: 1022 *data = extract64(s->cbaser, 32, 32); 1023 break; 1024 case GITS_CREADR: 1025 *data = extract64(s->creadr, 0, 32); 1026 break; 1027 case GITS_CREADR + 4: 1028 *data = extract64(s->creadr, 32, 32); 1029 break; 1030 case GITS_CWRITER: 1031 *data = extract64(s->cwriter, 0, 32); 1032 break; 1033 case GITS_CWRITER + 4: 1034 *data = extract64(s->cwriter, 32, 32); 1035 break; 1036 case GITS_BASER ... GITS_BASER + 0x3f: 1037 index = (offset - GITS_BASER) / 8; 1038 if (offset & 7) { 1039 *data = extract64(s->baser[index], 32, 32); 1040 } else { 1041 *data = extract64(s->baser[index], 0, 32); 1042 } 1043 break; 1044 default: 1045 result = false; 1046 break; 1047 } 1048 return result; 1049} 1050 1051static bool its_writell(GICv3ITSState *s, hwaddr offset, 1052 uint64_t value, MemTxAttrs attrs) 1053{ 1054 bool result = true; 1055 int index; 1056 1057 switch (offset) { 1058 case GITS_BASER ... GITS_BASER + 0x3f: 1059 /* 1060 * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is 1061 * already enabled 1062 */ 1063 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 1064 index = (offset - GITS_BASER) / 8; 1065 s->baser[index] &= GITS_BASER_RO_MASK; 1066 s->baser[index] |= (value & ~GITS_BASER_RO_MASK); 1067 } 1068 break; 1069 case GITS_CBASER: 1070 /* 1071 * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is 1072 * already enabled 1073 */ 1074 if (!(s->ctlr & ITS_CTLR_ENABLED)) { 1075 s->cbaser = value; 1076 s->creadr = 0; 1077 s->cwriter = s->creadr; 1078 } 1079 break; 1080 case GITS_CWRITER: 1081 s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK; 1082 if (s->cwriter != s->creadr) { 1083 process_cmdq(s); 1084 } 1085 break; 1086 case GITS_CREADR: 1087 if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) { 1088 s->creadr = value & ~R_GITS_CREADR_STALLED_MASK; 1089 } else { 1090 /* RO register, ignore the write */ 1091 qemu_log_mask(LOG_GUEST_ERROR, 1092 "%s: invalid guest write to RO register at offset " 1093 TARGET_FMT_plx "\n", __func__, offset); 1094 } 1095 break; 1096 case GITS_TYPER: 1097 /* RO registers, ignore the write */ 1098 qemu_log_mask(LOG_GUEST_ERROR, 1099 "%s: invalid guest write to RO register at offset " 1100 TARGET_FMT_plx "\n", __func__, offset); 1101 break; 1102 default: 1103 result = false; 1104 break; 1105 } 1106 return result; 1107} 1108 1109static bool its_readll(GICv3ITSState *s, hwaddr offset, 1110 uint64_t *data, MemTxAttrs attrs) 1111{ 1112 bool result = true; 1113 int index; 1114 1115 switch (offset) { 1116 case GITS_TYPER: 1117 *data = s->typer; 1118 break; 1119 case GITS_BASER ... GITS_BASER + 0x3f: 1120 index = (offset - GITS_BASER) / 8; 1121 *data = s->baser[index]; 1122 break; 1123 case GITS_CBASER: 1124 *data = s->cbaser; 1125 break; 1126 case GITS_CREADR: 1127 *data = s->creadr; 1128 break; 1129 case GITS_CWRITER: 1130 *data = s->cwriter; 1131 break; 1132 default: 1133 result = false; 1134 break; 1135 } 1136 return result; 1137} 1138 1139static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data, 1140 unsigned size, MemTxAttrs attrs) 1141{ 1142 GICv3ITSState *s = (GICv3ITSState *)opaque; 1143 bool result; 1144 1145 switch (size) { 1146 case 4: 1147 result = its_readl(s, offset, data, attrs); 1148 break; 1149 case 8: 1150 result = its_readll(s, offset, data, attrs); 1151 break; 1152 default: 1153 result = false; 1154 break; 1155 } 1156 1157 if (!result) { 1158 qemu_log_mask(LOG_GUEST_ERROR, 1159 "%s: invalid guest read at offset " TARGET_FMT_plx 1160 "size %u\n", __func__, offset, size); 1161 /* 1162 * The spec requires that reserved registers are RAZ/WI; 1163 * so use false returns from leaf functions as a way to 1164 * trigger the guest-error logging but don't return it to 1165 * the caller, or we'll cause a spurious guest data abort. 1166 */ 1167 *data = 0; 1168 } 1169 return MEMTX_OK; 1170} 1171 1172static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data, 1173 unsigned size, MemTxAttrs attrs) 1174{ 1175 GICv3ITSState *s = (GICv3ITSState *)opaque; 1176 bool result; 1177 1178 switch (size) { 1179 case 4: 1180 result = its_writel(s, offset, data, attrs); 1181 break; 1182 case 8: 1183 result = its_writell(s, offset, data, attrs); 1184 break; 1185 default: 1186 result = false; 1187 break; 1188 } 1189 1190 if (!result) { 1191 qemu_log_mask(LOG_GUEST_ERROR, 1192 "%s: invalid guest write at offset " TARGET_FMT_plx 1193 "size %u\n", __func__, offset, size); 1194 /* 1195 * The spec requires that reserved registers are RAZ/WI; 1196 * so use false returns from leaf functions as a way to 1197 * trigger the guest-error logging but don't return it to 1198 * the caller, or we'll cause a spurious guest data abort. 1199 */ 1200 } 1201 return MEMTX_OK; 1202} 1203 1204static const MemoryRegionOps gicv3_its_control_ops = { 1205 .read_with_attrs = gicv3_its_read, 1206 .write_with_attrs = gicv3_its_write, 1207 .valid.min_access_size = 4, 1208 .valid.max_access_size = 8, 1209 .impl.min_access_size = 4, 1210 .impl.max_access_size = 8, 1211 .endianness = DEVICE_NATIVE_ENDIAN, 1212}; 1213 1214static const MemoryRegionOps gicv3_its_translation_ops = { 1215 .write_with_attrs = gicv3_its_translation_write, 1216 .valid.min_access_size = 2, 1217 .valid.max_access_size = 4, 1218 .impl.min_access_size = 2, 1219 .impl.max_access_size = 4, 1220 .endianness = DEVICE_NATIVE_ENDIAN, 1221}; 1222 1223static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) 1224{ 1225 GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); 1226 int i; 1227 1228 for (i = 0; i < s->gicv3->num_cpu; i++) { 1229 if (!(s->gicv3->cpu[i].gicr_typer & GICR_TYPER_PLPIS)) { 1230 error_setg(errp, "Physical LPI not supported by CPU %d", i); 1231 return; 1232 } 1233 } 1234 1235 gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops); 1236 1237 address_space_init(&s->gicv3->dma_as, s->gicv3->dma, 1238 "gicv3-its-sysmem"); 1239 1240 /* set the ITS default features supported */ 1241 s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1242 GITS_TYPE_PHYSICAL); 1243 s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE, 1244 ITS_ITT_ENTRY_SIZE - 1); 1245 s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS); 1246 s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS); 1247 s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1); 1248 s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS); 1249} 1250 1251static void gicv3_its_reset(DeviceState *dev) 1252{ 1253 GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); 1254 GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); 1255 1256 c->parent_reset(dev); 1257 1258 /* Quiescent bit reset to 1 */ 1259 s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1); 1260 1261 /* 1262 * setting GITS_BASER0.Type = 0b001 (Device) 1263 * GITS_BASER1.Type = 0b100 (Collection Table) 1264 * GITS_BASER<n>.Type,where n = 3 to 7 are 0b00 (Unimplemented) 1265 * GITS_BASER<0,1>.Page_Size = 64KB 1266 * and default translation table entry size to 16 bytes 1267 */ 1268 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE, 1269 GITS_BASER_TYPE_DEVICE); 1270 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE, 1271 GITS_BASER_PAGESIZE_64K); 1272 s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE, 1273 GITS_DTE_SIZE - 1); 1274 1275 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE, 1276 GITS_BASER_TYPE_COLLECTION); 1277 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE, 1278 GITS_BASER_PAGESIZE_64K); 1279 s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE, 1280 GITS_CTE_SIZE - 1); 1281} 1282 1283static void gicv3_its_post_load(GICv3ITSState *s) 1284{ 1285 if (s->ctlr & ITS_CTLR_ENABLED) { 1286 extract_table_params(s); 1287 extract_cmdq_params(s); 1288 } 1289} 1290 1291static Property gicv3_its_props[] = { 1292 DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3", 1293 GICv3State *), 1294 DEFINE_PROP_END_OF_LIST(), 1295}; 1296 1297static void gicv3_its_class_init(ObjectClass *klass, void *data) 1298{ 1299 DeviceClass *dc = DEVICE_CLASS(klass); 1300 GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass); 1301 GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass); 1302 1303 dc->realize = gicv3_arm_its_realize; 1304 device_class_set_props(dc, gicv3_its_props); 1305 device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset); 1306 icc->post_load = gicv3_its_post_load; 1307} 1308 1309static const TypeInfo gicv3_its_info = { 1310 .name = TYPE_ARM_GICV3_ITS, 1311 .parent = TYPE_ARM_GICV3_ITS_COMMON, 1312 .instance_size = sizeof(GICv3ITSState), 1313 .class_init = gicv3_its_class_init, 1314 .class_size = sizeof(GICv3ITSClass), 1315}; 1316 1317static void gicv3_its_register_types(void) 1318{ 1319 type_register_static(&gicv3_its_info); 1320} 1321 1322type_init(gicv3_its_register_types)