1/* 2 * Copyright (c) 2013, 2018-2019 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 369 unchanged lines hidden (view full) --- 378 } else { 379 panic("Not in timing or atomic mode!"); 380 } 381} 382 383void 384SMMUv3::processCommand(const SMMUCommand &cmd) 385{ |
386 switch (cmd.dw0.type) { |
387 case CMD_PRF_CONFIG: 388 DPRINTF(SMMUv3, "CMD_PREFETCH_CONFIG - ignored\n"); 389 break; 390 391 case CMD_PRF_ADDR: 392 DPRINTF(SMMUv3, "CMD_PREFETCH_ADDR - ignored\n"); 393 break; 394 |
395 case CMD_CFGI_STE: { 396 DPRINTF(SMMUv3, "CMD_CFGI_STE sid=%#x\n", cmd.dw0.sid); 397 configCache.invalidateSID(cmd.dw0.sid); |
398 break; |
399 } |
400 |
401 case CMD_CFGI_STE_RANGE: { 402 const auto range = cmd.dw1.range; 403 if (range == 31) { 404 // CMD_CFGI_ALL is an alias of CMD_CFGI_STE_RANGE with 405 // range = 31 406 DPRINTF(SMMUv3, "CMD_CFGI_ALL\n"); 407 configCache.invalidateAll(); 408 } else { 409 DPRINTF(SMMUv3, "CMD_CFGI_STE_RANGE\n"); 410 const auto start_sid = cmd.dw0.sid & ~((1 << (range + 1)) - 1); 411 const auto end_sid = start_sid + (1 << (range + 1)) - 1; 412 for (auto sid = start_sid; sid <= end_sid; sid++) 413 configCache.invalidateSID(sid); 414 } |
415 break; |
416 } |
417 |
418 case CMD_CFGI_CD: { 419 DPRINTF(SMMUv3, "CMD_CFGI_CD sid=%#x ssid=%#x\n", 420 cmd.dw0.sid, cmd.dw0.ssid); 421 configCache.invalidateSSID(cmd.dw0.sid, cmd.dw0.ssid); |
422 break; |
423 } |
424 |
425 case CMD_CFGI_CD_ALL: { 426 DPRINTF(SMMUv3, "CMD_CFGI_CD_ALL sid=%#x\n", cmd.dw0.sid); 427 configCache.invalidateSID(cmd.dw0.sid); |
428 break; |
429 } |
430 |
431 case CMD_TLBI_NH_ALL: { 432 DPRINTF(SMMUv3, "CMD_TLBI_NH_ALL vmid=%#x\n", cmd.dw0.vmid); |
433 for (auto slave_interface : slaveInterfaces) { |
434 slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid); 435 slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid); |
436 } |
437 tlb.invalidateVMID(cmd.dw0.vmid); 438 walkCache.invalidateVMID(cmd.dw0.vmid); |
439 break; |
440 } |
441 |
442 case CMD_TLBI_NH_ASID: { 443 DPRINTF(SMMUv3, "CMD_TLBI_NH_ASID asid=%#x vmid=%#x\n", 444 cmd.dw0.asid, cmd.dw0.vmid); |
445 for (auto slave_interface : slaveInterfaces) { 446 slave_interface->microTLB->invalidateASID( |
447 cmd.dw0.asid, cmd.dw0.vmid); |
448 slave_interface->mainTLB->invalidateASID( |
449 cmd.dw0.asid, cmd.dw0.vmid); |
450 } |
451 tlb.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid); 452 walkCache.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid); |
453 break; |
454 } |
455 |
456 case CMD_TLBI_NH_VAA: { 457 const Addr addr = cmd.addr(); 458 DPRINTF(SMMUv3, "CMD_TLBI_NH_VAA va=%#08x vmid=%#x\n", 459 addr, cmd.dw0.vmid); |
460 for (auto slave_interface : slaveInterfaces) { 461 slave_interface->microTLB->invalidateVAA( |
462 addr, cmd.dw0.vmid); |
463 slave_interface->mainTLB->invalidateVAA( |
464 addr, cmd.dw0.vmid); |
465 } |
466 tlb.invalidateVAA(addr, cmd.dw0.vmid); |
467 |
468 if (!cmd.dw1.leaf) 469 walkCache.invalidateVAA(addr, cmd.dw0.vmid); |
470 break; |
471 } |
472 |
473 case CMD_TLBI_NH_VA: { 474 const Addr addr = cmd.addr(); 475 DPRINTF(SMMUv3, "CMD_TLBI_NH_VA va=%#08x asid=%#x vmid=%#x\n", 476 addr, cmd.dw0.asid, cmd.dw0.vmid); |
477 for (auto slave_interface : slaveInterfaces) { 478 slave_interface->microTLB->invalidateVA( |
479 addr, cmd.dw0.asid, cmd.dw0.vmid); |
480 slave_interface->mainTLB->invalidateVA( |
481 addr, cmd.dw0.asid, cmd.dw0.vmid); |
482 } |
483 tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid); |
484 |
485 if (!cmd.dw1.leaf) 486 walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid); |
487 break; |
488 } |
489 |
490 case CMD_TLBI_S2_IPA: { 491 const Addr addr = cmd.addr(); 492 DPRINTF(SMMUv3, "CMD_TLBI_S2_IPA ipa=%#08x vmid=%#x\n", 493 addr, cmd.dw0.vmid); |
494 // This does not invalidate TLBs containing 495 // combined Stage1 + Stage2 translations, as per the spec. |
496 ipaCache.invalidateIPA(addr, cmd.dw0.vmid); 497 498 if (!cmd.dw1.leaf) 499 walkCache.invalidateVMID(cmd.dw0.vmid); |
500 break; |
501 } |
502 |
503 case CMD_TLBI_S12_VMALL: { 504 DPRINTF(SMMUv3, "CMD_TLBI_S12_VMALL vmid=%#x\n", cmd.dw0.vmid); 505 for (auto slave_interface : slaveInterfaces) { 506 slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid); 507 slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid); 508 } 509 tlb.invalidateVMID(cmd.dw0.vmid); 510 ipaCache.invalidateVMID(cmd.dw0.vmid); 511 walkCache.invalidateVMID(cmd.dw0.vmid); |
512 break; |
513 } |
514 |
515 case CMD_TLBI_NSNH_ALL: { 516 DPRINTF(SMMUv3, "CMD_TLBI_NSNH_ALL\n"); |
517 for (auto slave_interface : slaveInterfaces) { |
518 slave_interface->microTLB->invalidateAll(); 519 slave_interface->mainTLB->invalidateAll(); |
520 } |
521 tlb.invalidateAll(); 522 ipaCache.invalidateAll(); 523 walkCache.invalidateAll(); |
524 break; |
525 } |
526 |
527 case CMD_RESUME: 528 DPRINTF(SMMUv3, "CMD_RESUME\n"); |
529 panic("resume unimplemented"); 530 break; 531 532 default: |
533 warn("Unimplemented command %#x\n", cmd.dw0.type); |
534 break; 535 } 536} 537 538const PageTableOps* 539SMMUv3::getPageTableOps(uint8_t trans_granule) 540{ 541 static V8PageTableOps4k ptOps4k; --- 267 unchanged lines hidden --- |