dev-arm: Add 16K granule support to SMMUv3 model
Added the necessary PageTableOps that match the 16K granule translation regime. Change-Id: I46ef07939cb4bdc8c0bbbeeeb6a50a9ab0d64de0 Reviewed-by: Michiel Van Tol <michiel.vantol@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19628 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:
committed by
Giacomo Travaglini
parent
6f45523ed7
commit
3ed50acb1e
@@ -531,10 +531,12 @@ const PageTableOps*
|
||||
SMMUv3::getPageTableOps(uint8_t trans_granule)
|
||||
{
|
||||
static V8PageTableOps4k ptOps4k;
|
||||
static V8PageTableOps16k ptOps16k;
|
||||
static V8PageTableOps64k ptOps64k;
|
||||
|
||||
switch (trans_granule) {
|
||||
case TRANS_GRANULE_4K: return &ptOps4k;
|
||||
case TRANS_GRANULE_16K: return &ptOps16k;
|
||||
case TRANS_GRANULE_64K: return &ptOps64k;
|
||||
default:
|
||||
panic("Unknown translation granule size %d", trans_granule);
|
||||
|
||||
@@ -227,6 +227,102 @@ V8PageTableOps4k::lastLevel() const
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool
|
||||
V8PageTableOps16k::isValid(pte_t pte, unsigned level) const
|
||||
{
|
||||
switch (level) {
|
||||
case 0: return pte & 0x1;
|
||||
case 1: return pte & 0x1;
|
||||
case 2: return pte & 0x1;
|
||||
case 3: return (pte & 0x1) && (pte & 0x2);
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
V8PageTableOps16k::isLeaf(pte_t pte, unsigned level) const
|
||||
{
|
||||
switch (level) {
|
||||
case 0: return false;
|
||||
case 1: return false;
|
||||
case 2: return !(pte & 0x2);
|
||||
case 3: return true;
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
V8PageTableOps16k::isWritable(pte_t pte, unsigned level, bool stage2) const
|
||||
{
|
||||
return stage2 ? bits(pte, 7, 6) == 3 : bits(pte, 7) == 0;
|
||||
}
|
||||
|
||||
Addr
|
||||
V8PageTableOps16k::nextLevelPointer(pte_t pte, unsigned level) const
|
||||
{
|
||||
if (isLeaf(pte, level)) {
|
||||
switch (level) {
|
||||
// no level 0 here
|
||||
case 1: return mbits(pte, 47, 36);
|
||||
case 2: return mbits(pte, 47, 25);
|
||||
case 3: return mbits(pte, 47, 14);
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
} else {
|
||||
return mbits(pte, 47, 12);
|
||||
}
|
||||
}
|
||||
|
||||
Addr
|
||||
V8PageTableOps16k::index(Addr va, unsigned level) const
|
||||
{
|
||||
switch (level) {
|
||||
case 0: return bits(va, 47, 47) << 3; break;
|
||||
case 1: return bits(va, 46, 36) << 3; break;
|
||||
case 2: return bits(va, 35, 25) << 3; break;
|
||||
case 3: return bits(va, 24, 14) << 3; break;
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
}
|
||||
|
||||
Addr
|
||||
V8PageTableOps16k::pageMask(pte_t pte, unsigned level) const
|
||||
{
|
||||
switch (level) {
|
||||
// no level 0 here
|
||||
case 1: return ~mask(36);
|
||||
// 16K granule supports contiguous entries also at L2; - 1G
|
||||
case 2: return bits(pte, 52) ? ~mask(30) : ~mask(25);
|
||||
// as well as at L3; - 2M
|
||||
case 3: return bits(pte, 52) ? ~mask(21) : ~mask(14);
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
}
|
||||
|
||||
Addr
|
||||
V8PageTableOps16k::walkMask(unsigned level) const
|
||||
{
|
||||
switch (level) {
|
||||
case 0: return ~mask(47);
|
||||
case 1: return ~mask(36);
|
||||
case 2: return ~mask(25);
|
||||
case 3: return ~mask(14);
|
||||
default: panic("bad level %d", level);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
V8PageTableOps16k::firstLevel() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
V8PageTableOps16k::lastLevel() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool
|
||||
V8PageTableOps64k::isValid(pte_t pte, unsigned level) const
|
||||
{
|
||||
|
||||
@@ -85,6 +85,19 @@ struct V8PageTableOps4k : public PageTableOps
|
||||
virtual unsigned lastLevel() const;
|
||||
};
|
||||
|
||||
struct V8PageTableOps16k : public PageTableOps
|
||||
{
|
||||
virtual bool isValid(pte_t pte, unsigned level) const;
|
||||
virtual bool isLeaf(pte_t pte, unsigned level) const;
|
||||
virtual bool isWritable(pte_t pte, unsigned level, bool stage2) const;
|
||||
virtual Addr nextLevelPointer(pte_t pte, unsigned level) const;
|
||||
virtual Addr index(Addr va, unsigned level) const;
|
||||
virtual Addr pageMask(pte_t pte, unsigned level) const;
|
||||
virtual Addr walkMask(unsigned level) const;
|
||||
virtual unsigned firstLevel() const;
|
||||
virtual unsigned lastLevel() const;
|
||||
};
|
||||
|
||||
struct V8PageTableOps64k : public PageTableOps
|
||||
{
|
||||
virtual bool isValid(pte_t pte, unsigned level) const;
|
||||
|
||||
Reference in New Issue
Block a user