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 --- |