smmu_v3.cc (14103:1a8ac5412832) smmu_v3.cc (14116:3868b8bdb52b)
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{
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.type) {
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
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_INV_STE:
396 DPRINTF(SMMUv3, "CMD_INV_STE sid=%#x\n", cmd.data[0]);
397 configCache.invalidateSID(cmd.data[0]);
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;
398 break;
399 }
399
400
400 case CMD_INV_CD:
401 DPRINTF(SMMUv3, "CMD_INV_CD sid=%#x ssid=%#x\n",
402 cmd.data[0], cmd.data[1]);
403 configCache.invalidateSSID(cmd.data[0], cmd.data[1]);
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 }
404 break;
415 break;
416 }
405
417
406 case CMD_INV_CD_ALL:
407 DPRINTF(SMMUv3, "CMD_INV_CD_ALL sid=%#x\n", cmd.data[0]);
408 configCache.invalidateSID(cmd.data[0]);
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);
409 break;
422 break;
423 }
410
424
411 case CMD_INV_ALL:
412 DPRINTF(SMMUv3, "CMD_INV_ALL\n");
413 configCache.invalidateAll();
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);
414 break;
428 break;
429 }
415
430
416 case CMD_TLBI_ALL:
417 DPRINTF(SMMUv3, "CMD_TLBI_ALL\n");
431 case CMD_TLBI_NH_ALL: {
432 DPRINTF(SMMUv3, "CMD_TLBI_NH_ALL vmid=%#x\n", cmd.dw0.vmid);
418 for (auto slave_interface : slaveInterfaces) {
433 for (auto slave_interface : slaveInterfaces) {
419 slave_interface->microTLB->invalidateAll();
420 slave_interface->mainTLB->invalidateAll();
434 slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
435 slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
421 }
436 }
422 tlb.invalidateAll();
423 ipaCache.invalidateAll();
424 walkCache.invalidateAll();
437 tlb.invalidateVMID(cmd.dw0.vmid);
438 walkCache.invalidateVMID(cmd.dw0.vmid);
425 break;
439 break;
440 }
426
441
427 case CMD_TLBI_ASID:
428 DPRINTF(SMMUv3, "CMD_TLBI_ASID asid=%#x vmid=%#x\n",
429 cmd.data[0], cmd.data[1]);
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);
430 for (auto slave_interface : slaveInterfaces) {
431 slave_interface->microTLB->invalidateASID(
445 for (auto slave_interface : slaveInterfaces) {
446 slave_interface->microTLB->invalidateASID(
432 cmd.data[0], cmd.data[1]);
447 cmd.dw0.asid, cmd.dw0.vmid);
433 slave_interface->mainTLB->invalidateASID(
448 slave_interface->mainTLB->invalidateASID(
434 cmd.data[0], cmd.data[1]);
449 cmd.dw0.asid, cmd.dw0.vmid);
435 }
450 }
436 tlb.invalidateASID(cmd.data[0], cmd.data[1]);
437 walkCache.invalidateASID(cmd.data[0], cmd.data[1]);
451 tlb.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid);
452 walkCache.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid);
438 break;
453 break;
454 }
439
455
440 case CMD_TLBI_VAAL:
441 DPRINTF(SMMUv3, "CMD_TLBI_VAAL va=%#08x vmid=%#x\n",
442 cmd.data[0], cmd.data[1]);
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);
443 for (auto slave_interface : slaveInterfaces) {
444 slave_interface->microTLB->invalidateVAA(
460 for (auto slave_interface : slaveInterfaces) {
461 slave_interface->microTLB->invalidateVAA(
445 cmd.data[0], cmd.data[1]);
462 addr, cmd.dw0.vmid);
446 slave_interface->mainTLB->invalidateVAA(
463 slave_interface->mainTLB->invalidateVAA(
447 cmd.data[0], cmd.data[1]);
464 addr, cmd.dw0.vmid);
448 }
465 }
449 tlb.invalidateVAA(cmd.data[0], cmd.data[1]);
450 break;
466 tlb.invalidateVAA(addr, cmd.dw0.vmid);
451
467
452 case CMD_TLBI_VAA:
453 DPRINTF(SMMUv3, "CMD_TLBI_VAA va=%#08x vmid=%#x\n",
454 cmd.data[0], cmd.data[1]);
455 for (auto slave_interface : slaveInterfaces) {
456 slave_interface->microTLB->invalidateVAA(
457 cmd.data[0], cmd.data[1]);
458 slave_interface->mainTLB->invalidateVAA(
459 cmd.data[0], cmd.data[1]);
460 }
461 tlb.invalidateVAA(cmd.data[0], cmd.data[1]);
462 walkCache.invalidateVAA(cmd.data[0], cmd.data[1]);
468 if (!cmd.dw1.leaf)
469 walkCache.invalidateVAA(addr, cmd.dw0.vmid);
463 break;
470 break;
471 }
464
472
465 case CMD_TLBI_VAL:
466 DPRINTF(SMMUv3, "CMD_TLBI_VAL va=%#08x asid=%#x vmid=%#x\n",
467 cmd.data[0], cmd.data[1], cmd.data[2]);
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);
468 for (auto slave_interface : slaveInterfaces) {
469 slave_interface->microTLB->invalidateVA(
477 for (auto slave_interface : slaveInterfaces) {
478 slave_interface->microTLB->invalidateVA(
470 cmd.data[0], cmd.data[1], cmd.data[2]);
479 addr, cmd.dw0.asid, cmd.dw0.vmid);
471 slave_interface->mainTLB->invalidateVA(
480 slave_interface->mainTLB->invalidateVA(
472 cmd.data[0], cmd.data[1], cmd.data[2]);
481 addr, cmd.dw0.asid, cmd.dw0.vmid);
473 }
482 }
474 tlb.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]);
475 break;
483 tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
476
484
477 case CMD_TLBI_VA:
478 DPRINTF(SMMUv3, "CMD_TLBI_VA va=%#08x asid=%#x vmid=%#x\n",
479 cmd.data[0], cmd.data[1], cmd.data[2]);
480 for (auto slave_interface : slaveInterfaces) {
481 slave_interface->microTLB->invalidateVA(
482 cmd.data[0], cmd.data[1], cmd.data[2]);
483 slave_interface->mainTLB->invalidateVA(
484 cmd.data[0], cmd.data[1], cmd.data[2]);
485 }
486 tlb.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]);
487 walkCache.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]);
485 if (!cmd.dw1.leaf)
486 walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
488 break;
487 break;
488 }
489
489
490 case CMD_TLBI_VM_IPAL:
491 DPRINTF(SMMUv3, "CMD_TLBI_VM_IPAL ipa=%#08x vmid=%#x\n",
492 cmd.data[0], cmd.data[1]);
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);
493 // This does not invalidate TLBs containing
494 // combined Stage1 + Stage2 translations, as per the spec.
494 // This does not invalidate TLBs containing
495 // combined Stage1 + Stage2 translations, as per the spec.
495 ipaCache.invalidateIPA(cmd.data[0], cmd.data[1]);
496 walkCache.invalidateVMID(cmd.data[1]);
496 ipaCache.invalidateIPA(addr, cmd.dw0.vmid);
497
498 if (!cmd.dw1.leaf)
499 walkCache.invalidateVMID(cmd.dw0.vmid);
497 break;
500 break;
501 }
498
502
499 case CMD_TLBI_VM_IPA:
500 DPRINTF(SMMUv3, "CMD_TLBI_VM_IPA ipa=%#08x vmid=%#x\n",
501 cmd.data[0], cmd.data[1]);
502 // This does not invalidate TLBs containing
503 // combined Stage1 + Stage2 translations, as per the spec.
504 ipaCache.invalidateIPA(cmd.data[0], cmd.data[1]);
505 walkCache.invalidateVMID(cmd.data[1]);
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);
506 break;
512 break;
513 }
507
514
508 case CMD_TLBI_VM_S12:
509 DPRINTF(SMMUv3, "CMD_TLBI_VM_S12 vmid=%#x\n", cmd.data[0]);
515 case CMD_TLBI_NSNH_ALL: {
516 DPRINTF(SMMUv3, "CMD_TLBI_NSNH_ALL\n");
510 for (auto slave_interface : slaveInterfaces) {
517 for (auto slave_interface : slaveInterfaces) {
511 slave_interface->microTLB->invalidateVMID(cmd.data[0]);
512 slave_interface->mainTLB->invalidateVMID(cmd.data[0]);
518 slave_interface->microTLB->invalidateAll();
519 slave_interface->mainTLB->invalidateAll();
513 }
520 }
514 tlb.invalidateVMID(cmd.data[0]);
515 ipaCache.invalidateVMID(cmd.data[0]);
516 walkCache.invalidateVMID(cmd.data[0]);
521 tlb.invalidateAll();
522 ipaCache.invalidateAll();
523 walkCache.invalidateAll();
517 break;
524 break;
525 }
518
526
519 case CMD_RESUME_S:
520 DPRINTF(SMMUv3, "CMD_RESUME_S\n");
527 case CMD_RESUME:
528 DPRINTF(SMMUv3, "CMD_RESUME\n");
521 panic("resume unimplemented");
522 break;
523
524 default:
529 panic("resume unimplemented");
530 break;
531
532 default:
525 warn("Unimplemented command %#x\n", cmd.type);
533 warn("Unimplemented command %#x\n", cmd.dw0.type);
526 break;
527 }
528}
529
530const PageTableOps*
531SMMUv3::getPageTableOps(uint8_t trans_granule)
532{
533 static V8PageTableOps4k ptOps4k;

--- 267 unchanged lines hidden ---
534 break;
535 }
536}
537
538const PageTableOps*
539SMMUv3::getPageTableOps(uint8_t trans_granule)
540{
541 static V8PageTableOps4k ptOps4k;

--- 267 unchanged lines hidden ---