dev-arm: SMMUv3 Table walks using TnSZ

TnSZ is needed when selecting the starting level of a table
walk, since it directly affects the number of IA bits.
This has been implemented by adding T0SZ and S2T0SZ to the
translation context.
T1SZ is not used at the moment since the current model doesn't
support TTB1.

Change-Id: I75663475c4dc01e5986cd93f8deafcdf7b1ece82
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Michiel Van Tol <michiel.vantol@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19630
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2019-07-22 16:08:26 +01:00
parent 36da743e0b
commit e71e2d6a35
4 changed files with 38 additions and 17 deletions

View File

@@ -122,7 +122,7 @@ V7LPageTableOps::walkMask(unsigned level) const
}
unsigned
V7LPageTableOps::firstLevel() const
V7LPageTableOps::firstLevel(uint8_t tsz) const
{
return 1;
}
@@ -216,9 +216,13 @@ V8PageTableOps4k::walkMask(unsigned level) const
}
unsigned
V8PageTableOps4k::firstLevel() const
V8PageTableOps4k::firstLevel(uint8_t tsz) const
{
return 0;
if (tsz >= 16 && tsz <= 24) return 0;
if (tsz >= 25 && tsz <= 33) return 1;
if (tsz >= 34 && tsz <= 39) return 2;
panic("Unsupported TnSZ: %d\n", tsz);
}
unsigned
@@ -312,9 +316,14 @@ V8PageTableOps16k::walkMask(unsigned level) const
}
unsigned
V8PageTableOps16k::firstLevel() const
V8PageTableOps16k::firstLevel(uint8_t tsz) const
{
return 0;
if (tsz == 16) return 0;
if (tsz >= 17 && tsz <= 27) return 1;
if (tsz >= 28 && tsz <= 38) return 2;
if (tsz == 39) return 3;
panic("Unsupported TnSZ: %d\n", tsz);
}
unsigned
@@ -400,9 +409,13 @@ V8PageTableOps64k::walkMask(unsigned level) const
}
unsigned
V8PageTableOps64k::firstLevel() const
V8PageTableOps64k::firstLevel(uint8_t tsz) const
{
return 1;
if (tsz >= 12 && tsz <= 21) return 1;
if (tsz >= 22 && tsz <= 34) return 2;
if (tsz >= 35 && tsz <= 39) return 3;
panic("Unsupported TnSZ: %d\n", tsz);
}
unsigned

View File

@@ -55,7 +55,7 @@ struct PageTableOps
virtual Addr index(Addr va, unsigned level) const = 0;
virtual Addr pageMask(pte_t pte, unsigned level) const = 0;
virtual Addr walkMask(unsigned level) const = 0;
virtual unsigned firstLevel() const = 0;
virtual unsigned firstLevel(uint8_t tsz) const = 0;
virtual unsigned lastLevel() const = 0;
};
@@ -68,7 +68,7 @@ struct V7LPageTableOps : public PageTableOps
Addr index(Addr va, unsigned level) const override;
Addr pageMask(pte_t pte, unsigned level) const override;
Addr walkMask(unsigned level) const override;
unsigned firstLevel() const override;
unsigned firstLevel(uint8_t tsz) const override;
unsigned lastLevel() const override;
};
@@ -81,7 +81,7 @@ struct V8PageTableOps4k : public PageTableOps
Addr index(Addr va, unsigned level) const override;
Addr pageMask(pte_t pte, unsigned level) const override;
Addr walkMask(unsigned level) const override;
unsigned firstLevel() const override;
unsigned firstLevel(uint8_t tsz) const override;
unsigned lastLevel() const override;
};
@@ -94,7 +94,7 @@ struct V8PageTableOps16k : public PageTableOps
Addr index(Addr va, unsigned level) const override;
Addr pageMask(pte_t pte, unsigned level) const override;
Addr walkMask(unsigned level) const override;
unsigned firstLevel() const override;
unsigned firstLevel(uint8_t tsz) const override;
unsigned lastLevel() const override;
};
@@ -107,7 +107,7 @@ struct V8PageTableOps64k : public PageTableOps
Addr index(Addr va, unsigned level) const override;
Addr pageMask(pte_t pte, unsigned level) const override;
Addr walkMask(unsigned level) const override;
unsigned firstLevel() const override;
unsigned firstLevel(uint8_t tsz) const override;
unsigned lastLevel() const override;
};

View File

@@ -605,10 +605,12 @@ SMMUTranslationProcess::findConfig(Yield &yield,
tc.httb = ste.dw3.s2ttb << STE_S2TTB_SHIFT;
tc.vmid = ste.dw2.s2vmid;
tc.stage2TranslGranule = ste.dw2.s2tg;
tc.s2t0sz = ste.dw2.s2t0sz;
} else {
tc.httb = 0xdeadbeef;
tc.vmid = 0;
tc.stage2TranslGranule = TRANS_GRANULE_INVALID;
tc.s2t0sz = 0;
}
@@ -621,11 +623,13 @@ SMMUTranslationProcess::findConfig(Yield &yield,
tc.ttb1 = cd.dw2.ttb1 << CD_TTB_SHIFT;
tc.asid = cd.dw0.asid;
tc.stage1TranslGranule = cd.dw0.tg0;
tc.t0sz = cd.dw0.t0sz;
} else {
tc.ttb0 = 0xcafebabe;
tc.ttb1 = 0xcafed00d;
tc.asid = 0;
tc.stage1TranslGranule = TRANS_GRANULE_INVALID;
tc.t0sz = 0;
}
return true;
@@ -875,7 +879,7 @@ SMMUTranslationProcess::translateStage1And2(Yield &yield, Addr addr)
// Level here is actually (level+1) so we can count down
// to 0 using unsigned int.
for (level = pt_ops->lastLevel() + 1;
level > pt_ops->firstLevel();
level > pt_ops->firstLevel(context.t0sz);
level--)
{
walkCacheLookup(yield, walk_ep, addr,
@@ -908,7 +912,8 @@ SMMUTranslationProcess::translateStage1And2(Yield &yield, Addr addr)
table_addr = s2tr.addr;
}
tr = walkStage1And2(yield, addr, pt_ops, pt_ops->firstLevel(),
tr = walkStage1And2(yield, addr, pt_ops,
pt_ops->firstLevel(context.t0sz),
table_addr);
}
@@ -949,13 +954,13 @@ SMMUTranslationProcess::translateStage2(Yield &yield, Addr addr, bool final_tr)
}
const WalkCache::Entry *walk_ep = NULL;
unsigned level = pt_ops->firstLevel();
unsigned level = pt_ops->firstLevel(context.s2t0sz);
if (final_tr || smmu.walkCacheNonfinalEnable) {
// Level here is actually (level+1) so we can count down
// to 0 using unsigned int.
for (level = pt_ops->lastLevel() + 1;
level > pt_ops->firstLevel();
level > pt_ops->firstLevel(context.s2t0sz);
level--)
{
walkCacheLookup(yield, walk_ep, addr,
@@ -981,7 +986,8 @@ SMMUTranslationProcess::translateStage2(Yield &yield, Addr addr, bool final_tr)
level + 1, walk_ep->pa);
}
} else {
tr = walkStage2(yield, addr, final_tr, pt_ops, pt_ops->firstLevel(),
tr = walkStage2(yield, addr, final_tr, pt_ops,
pt_ops->firstLevel(context.s2t0sz),
context.httb);
}

View File

@@ -73,6 +73,8 @@ class SMMUTranslationProcess : public SMMUProcess
uint16_t vmid;
uint8_t stage1TranslGranule;
uint8_t stage2TranslGranule;
uint8_t t0sz;
uint8_t s2t0sz;
};
enum FaultType