m1n1.hw.dart: Add support for T6000 DARTs

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-11-01 18:54:11 +09:00
parent 9fab740a77
commit bc82dbea4e

View file

@ -14,6 +14,8 @@ class R_ERROR(Register32):
CODE = 23, 0
NO_DAPF_MATCH = 11
WRITE = 10
SUBPAGE_PROT = 7
PTE_READ_FAULT = 6
READ_FAULT = 4
WRITE_FAULT = 3
NO_PTE = 2
@ -39,8 +41,17 @@ class R_REMAP(Register32):
MAP1 = 15, 8
MAP0 = 7, 0
class PTE(Register64):
OFFSET = 36, 14
class PTE_T8103(Register64):
SP_START = 63, 52
SP_END = 51, 40
OFFSET = 39, 14
VALID2 = 1
VALID = 0
class PTE_T6000(Register64):
SP_START = 63, 52
SP_END = 51, 40
OFFSET = 39, 10
VALID2 = 1
VALID = 0
@ -87,6 +98,7 @@ class DART(Reloadable):
self.enabled_streams = regs.ENABLED_STREAMS.val
self.iova_allocator = [Heap(iova_range[0], iova_range[1], self.PAGE_SIZE)
for i in range(16)]
self.ptecls = PTE_T6000
def ioread(self, stream, base, size):
if size == 0:
@ -168,11 +180,11 @@ class DART(Reloadable):
cached, l1 = self.get_pt(ttbr.ADDR << 12)
l1idx = (page >> self.L1_OFF) & self.IDX_MASK
l1pte = PTE(l1[l1idx])
l1pte = self.ptecls(l1[l1idx])
if not l1pte.VALID:
l2addr = self.u.memalign(self.PAGE_SIZE, self.PAGE_SIZE)
self.pt_cache[l2addr] = [0] * self.Lx_SIZE
l1pte = PTE(
l1pte = self.ptecls(
OFFSET=l2addr >> self.PAGE_BITS, VALID=1, VALID2=1)
l1[l1idx] = l1pte.value
dirty.add(ttbr.ADDR << 12)
@ -182,7 +194,8 @@ class DART(Reloadable):
dirty.add(l1pte.OFFSET << self.PAGE_BITS)
cached, l2 = self.get_pt(l2addr)
l2idx = (page >> self.L2_OFF) & self.IDX_MASK
self.pt_cache[l2addr][l2idx] = PTE(
self.pt_cache[l2addr][l2idx] = self.ptecls(
SP_START=0, SP_END=0xfff,
OFFSET=paddr >> self.PAGE_BITS, VALID=1, VALID2=1).value
for page in dirty:
@ -217,19 +230,19 @@ class DART(Reloadable):
continue
cached, l1 = self.get_pt(ttbr.ADDR << 12)
l1pte = PTE(l1[(page >> self.L1_OFF) & self.IDX_MASK])
l1pte = self.pteclsf(l1[(page >> self.L1_OFF) & self.IDX_MASK])
if not l1pte.VALID and cached:
cached, l1 = self.get_pt(ttbr.ADDR << 12, uncached=True)
l1pte = PTE(l1[(page >> self.L1_OFF) & self.IDX_MASK])
l1pte = self.ptecls(l1[(page >> self.L1_OFF) & self.IDX_MASK])
if not l1pte.VALID:
pages.append(None)
continue
cached, l2 = self.get_pt(l1pte.OFFSET << self.PAGE_BITS)
l2pte = PTE(l2[(page >> self.L2_OFF) & self.IDX_MASK])
l2pte = self.ptecls(l2[(page >> self.L2_OFF) & self.IDX_MASK])
if not l2pte.VALID and cached:
cached, l2 = self.get_pt(l1pte.OFFSET << self.PAGE_BITS, uncached=True)
l2pte = PTE(l2[(page >> self.L2_OFF) & self.IDX_MASK])
l2pte = self.ptecls(l2[(page >> self.L2_OFF) & self.IDX_MASK])
if not l2pte.VALID:
pages.append(None)
continue
@ -304,7 +317,8 @@ class DART(Reloadable):
unmapped = False
for i, pte in enumerate(tbl):
if not (pte & 0b01):
pte = self.ptecls(pte)
if not pte.VALID:
if not unmapped:
print(" ...")
unmapped = True
@ -312,14 +326,18 @@ class DART(Reloadable):
unmapped = False
print(" page (%d): %08x ... %08x -> %016x [%s]" % (i, base + i*0x4000, base + (i+1)*0x4000, pte&~0b11, bin(pte&0b11)))
print(" page (%d): %08x ... %08x -> %016x [%d%d]" % (
i, base + i*0x4000, base + (i+1)*0x4000,
pte.OFFSET << self.PAGE_BITS, pte.VALID2, pte.VALID))
print(hex(pte.value))
def dump_table(self, base, l1_addr):
cached, tbl = self.get_pt(l1_addr)
unmapped = False
for i, pte in enumerate(tbl):
if not (pte & 0b01):
pte = self.ptecls(pte)
if not pte.VALID:
if not unmapped:
print(" ...")
unmapped = True
@ -327,8 +345,10 @@ class DART(Reloadable):
unmapped = False
print(" table (%d): %08x ... %08x -> %016x [%s]" % (i, base + i*0x2000000, base + (i+1)*0x2000000, pte&~0b11, bin(pte&0b11)))
self.dump_table2(base + i*0x2000000, pte & ~0b11)
print(" table (%d): %08x ... %08x -> %016x [%d%d]" % (
i, base + i*0x2000000, base + (i+1)*0x2000000,
pte.OFFSET << self.PAGE_BITS, pte.VALID2, pte.VALID))
self.dump_table2(base + i*0x2000000, pte.OFFSET << self.PAGE_BITS)
def dump_ttbr(self, idx, ttbr):
if not ttbr.VALID: