[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Implement Armv8.2-LVA
Jordi Vaquero has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/35955 ) Change subject: arch-arm: Implement Armv8.2-LVA .. arch-arm: Implement Armv8.2-LVA Change-Id: I1b489a3629b2376e03e79b158631cb1d0cacc17e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35955 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- M src/arch/arm/ArmISA.py M src/arch/arm/table_walker.cc M src/arch/arm/table_walker.hh M src/arch/arm/utility.cc M src/arch/arm/utility.hh 5 files changed, 93 insertions(+), 48 deletions(-) Approvals: Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py index a709894..02f24d3 100644 --- a/src/arch/arm/ArmISA.py +++ b/src/arch/arm/ArmISA.py @@ -112,7 +112,8 @@ # PAN | HPDS | VHE id_aa64mmfr1_el1 = Param.UInt64(0x00101100, "AArch64 Memory Model Feature Register 1") -id_aa64mmfr2_el1 = Param.UInt64(0x, +# |VARANGE +id_aa64mmfr2_el1 = Param.UInt64(0x0001, "AArch64 Memory Model Feature Register 2") # Any access (read/write) to an unimplemented diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 9462e27..d5027cf 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -746,14 +746,21 @@ return f; } -unsigned -TableWalker::adjustTableSizeAArch64(unsigned tsz) +bool +TableWalker::checkVAddrSizeFaultAArch64(Addr addr, int top_bit, +GrainSize tg, int tsz, bool low_range) { -if (tsz < 25) -return 25; -if (tsz > 48) -return 48; -return tsz; +// The effective maximum input size is 48 if ARMv8.2-LVA is not +// supported or if the translation granule that is in use is 4KB or +// 16KB in size. When ARMv8.2-LVA is supported, for the 64KB +// translation granule size only, the effective minimum value of +// 52. +int in_max = (HaveLVA(currState->tc) && tg == Grain64KB) ? 52 : 48; +int in_min = 64 - (tg == Grain64KB ? 47 : 48); + +return tsz > in_max || tsz < in_min || (low_range ? +bits(currState->vaddr, top_bit, tsz) != 0x0 : +bits(currState->vaddr, top_bit, tsz) != mask(top_bit - tsz + 1)); } bool @@ -784,8 +791,14 @@ GrainSize tg = Grain4KB; // grain size computed from tg* field bool fault = false; -LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; +int top_bit = computeAddrTop(currState->tc, +bits(currState->vaddr, 55), +currState->mode==TLB::Execute, +currState->tcr, +currState->el); +LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; +bool vaddr_fault = false; switch (currState->el) { case EL0: { @@ -804,24 +817,28 @@ case 0: DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); ttbr = ttbr0; -tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); +tsz = 64 - currState->tcr.t0sz; tg = GrainMap_tg0[currState->tcr.tg0]; currState->hpd = currState->tcr.hpd0; currState->isUncacheable = currState->tcr.irgn0 == 0; -if (bits(currState->vaddr, 63, tsz) != 0x0 || -currState->tcr.epd0) - fault = true; +vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, +top_bit, tg, tsz, true); + +if (vaddr_fault || currState->tcr.epd0) +fault = true; break; case 0x: DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n"); ttbr = ttbr1; -tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz); +tsz = 64 - currState->tcr.t1sz; tg = GrainMap_tg1[currState->tcr.tg1]; currState->hpd = currState->tcr.hpd1; currState->isUncacheable = currState->tcr.irgn1 == 0; -if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) || -currState->tcr.epd1) - fault = true; +vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, +top_bit, tg, tsz, false); + +if (vaddr_fault || currState->tcr.epd1) +fault = true; break; default: // top two bytes must be all 0s or all 1s, else invalid addr @@ -858,28 +875,32 @@ ps = currState->vtcr.ps; currState->isUncacheable = currState->vtcr.irgn0 == 0; } else { -switch (bits(currState->vaddr, 63,48)) { +switch (bits(currState->vaddr, top_bit)) { case 0: -DPRINTF(TLB, " - Selecting TTBR0
[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Implement Armv8.2-LVA
Jordi Vaquero has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/35955 ) Change subject: arch-arm: Implement Armv8.2-LVA .. arch-arm: Implement Armv8.2-LVA Change-Id: I1b489a3629b2376e03e79b158631cb1d0cacc17e --- M src/arch/arm/ArmISA.py M src/arch/arm/table_walker.cc M src/arch/arm/table_walker.hh M src/arch/arm/utility.cc M src/arch/arm/utility.hh 5 files changed, 93 insertions(+), 48 deletions(-) diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py index a709894..02f24d3 100644 --- a/src/arch/arm/ArmISA.py +++ b/src/arch/arm/ArmISA.py @@ -112,7 +112,8 @@ # PAN | HPDS | VHE id_aa64mmfr1_el1 = Param.UInt64(0x00101100, "AArch64 Memory Model Feature Register 1") -id_aa64mmfr2_el1 = Param.UInt64(0x, +# |VARANGE +id_aa64mmfr2_el1 = Param.UInt64(0x0001, "AArch64 Memory Model Feature Register 2") # Any access (read/write) to an unimplemented diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 9462e27..d5027cf 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -746,14 +746,21 @@ return f; } -unsigned -TableWalker::adjustTableSizeAArch64(unsigned tsz) +bool +TableWalker::checkVAddrSizeFaultAArch64(Addr addr, int top_bit, +GrainSize tg, int tsz, bool low_range) { -if (tsz < 25) -return 25; -if (tsz > 48) -return 48; -return tsz; +// The effective maximum input size is 48 if ARMv8.2-LVA is not +// supported or if the translation granule that is in use is 4KB or +// 16KB in size. When ARMv8.2-LVA is supported, for the 64KB +// translation granule size only, the effective minimum value of +// 52. +int in_max = (HaveLVA(currState->tc) && tg == Grain64KB) ? 52 : 48; +int in_min = 64 - (tg == Grain64KB ? 47 : 48); + +return tsz > in_max || tsz < in_min || (low_range ? +bits(currState->vaddr, top_bit, tsz) != 0x0 : +bits(currState->vaddr, top_bit, tsz) != mask(top_bit - tsz + 1)); } bool @@ -784,8 +791,14 @@ GrainSize tg = Grain4KB; // grain size computed from tg* field bool fault = false; -LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; +int top_bit = computeAddrTop(currState->tc, +bits(currState->vaddr, 55), +currState->mode==TLB::Execute, +currState->tcr, +currState->el); +LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; +bool vaddr_fault = false; switch (currState->el) { case EL0: { @@ -804,24 +817,28 @@ case 0: DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); ttbr = ttbr0; -tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); +tsz = 64 - currState->tcr.t0sz; tg = GrainMap_tg0[currState->tcr.tg0]; currState->hpd = currState->tcr.hpd0; currState->isUncacheable = currState->tcr.irgn0 == 0; -if (bits(currState->vaddr, 63, tsz) != 0x0 || -currState->tcr.epd0) - fault = true; +vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, +top_bit, tg, tsz, true); + +if (vaddr_fault || currState->tcr.epd0) +fault = true; break; case 0x: DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n"); ttbr = ttbr1; -tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz); +tsz = 64 - currState->tcr.t1sz; tg = GrainMap_tg1[currState->tcr.tg1]; currState->hpd = currState->tcr.hpd1; currState->isUncacheable = currState->tcr.irgn1 == 0; -if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) || -currState->tcr.epd1) - fault = true; +vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, +top_bit, tg, tsz, false); + +if (vaddr_fault || currState->tcr.epd1) +fault = true; break; default: // top two bytes must be all 0s or all 1s, else invalid addr @@ -858,28 +875,32 @@ ps = currState->vtcr.ps; currState->isUncacheable = currState->vtcr.irgn0 == 0; } else { -switch (bits(currState->vaddr, 63,48)) { +switch (bits(currState->vaddr, top_bit)) { case 0: -DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); +DPRINTF(TLB, " - Selecting TTBR0_EL1 (AArch64)\n"); ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1); -tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); +tsz = 64 -