dev-arm: Add 16K granule support to SMMUv3 model
authorMichiel Van Tol <michiel.vantol@arm.com>
Mon, 22 Jul 2019 15:51:48 +0000 (16:51 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 25 Jul 2019 12:49:12 +0000 (12:49 +0000)
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>
src/dev/arm/smmu_v3.cc
src/dev/arm/smmu_v3_ptops.cc
src/dev/arm/smmu_v3_ptops.hh

index d913d55a0a43fefe56e13262952eb4681743d9b1..7c4bd36733ae21cb01d2d6ba6632cb06ce223906 100644 (file)
@@ -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);
index 6490b34c7d7e2d094263b8863ae1def42e0d6617..c57c16a3a3076ace449d78e0b9b57d576be87dc4 100644 (file)
@@ -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
 {
index ef9ef0409a75b7ce77454f44eb7c9d2e217d8809..1b8c22c4d8c2bc4d4dad349681ac0181eb8b9b92 100644 (file)
@@ -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;