}
unsigned
-V7LPageTableOps::firstLevel() const
+V7LPageTableOps::firstLevel(uint8_t tsz) const
{
return 1;
}
}
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
}
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
}
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
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;
};
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;
};
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;
};
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;
};
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;
};
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;
}
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;
// 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,
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);
}
}
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,
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);
}
uint16_t vmid;
uint8_t stage1TranslGranule;
uint8_t stage2TranslGranule;
+ uint8_t t0sz;
+ uint8_t s2t0sz;
};
enum FaultType