mirror of
https://github.com/tinygrad/tinygrad.git
synced 2026-02-04 03:35:16 -05:00
* connect to gpu
* rlc init?
* gfx comp start init
* early init is hardoded, some progress with fw
* gart
* progress, next mqd
* ring setup, still does not execute anything
* ugh write correct reg
* pci2: vm
* pci2: start psp
* vm seems to work
* pci2: gfx start
* pci2: fix psp ring resp
* pci2: try ring
* pci2: mes and some fixes
* pci2: some progress
* pci2: progress
* pci2: mm
* pci2: discovery
* pci2: correct apertures
* pci2: b
* pci2: i
* pci2: l
* pci2: o
* pci2: cmu
* pci2: mes_kiq works
* pci2: mes
* pci2: kcq does not work(
* pci2: unhalt gfx
* ops_am
* minor
* check if amdgpu is there, or we will crash
* bring back graph, it just works
* less prints
* do not init mes (not used)
* remove unused files
* ops_am: start move into core
* ops_am: works
* clcks, but still slower
* faster + no mes_kiq
* vm frags + remove mes
* cleanup fw
* gmc tiny cleanup
* move to ops_amd
* comment out what we dont really need
* driverless
* close in speed
* am clean most of ips
* gmc to ips
* cleaner
* new vm walker
* comment old one
* remove unsued autogens
* last write ups
* remove psp hardcoded values
* more
* add logs
* ih
* p2p and sdma
* vfio hal and interrupts
* smth
* amd dev iface
* minor after rebase
* bind for sdma
* Revert "bind for sdma"
This reverts commit a90766514d.
* tmp
* debug new mm
* ugh, allreduce hangs fixed
* p1
* works
* no pci.py
* cleaner a bit
* smth
* tiny cleanups
* cleaner a bit
* pciiface
* linter
* linter 2
* linter 3
* linter
* pylint
* reverted unrelated changes
* unrelated
* cmp tool
* ugh wrong fw
* clockgating
* unrelated
* alloc smaller chunks
* this
* opt sigs
* collect stat
* ops
* upd
* proclogs
* proclogs2
* vfio
* ruff
* linter pylint
* oops
* mypy p1
* mem fix
* mypy p2
* mypy p3
* mypy p4
* correct
* minor
* more tests
* linter in tests
* pci_regs header
* minor write up
* setup
* do not require libs
---------
Co-authored-by: George Hotz <72895+geohot@users.noreply.github.com>
163 lines
6.2 KiB
Python
163 lines
6.2 KiB
Python
import unittest
|
|
from tinygrad.runtime.support.am.amdev import AMMemoryManager
|
|
|
|
class FakeGMC:
|
|
def flush_tlb(self, *args, **kwargs): pass
|
|
|
|
class FakePCIRegion:
|
|
def __init__(self): self.base_addr = 0xc12300000000
|
|
|
|
class FakePCIDev:
|
|
def __init__(self): self.regions = [FakePCIRegion()]
|
|
|
|
class FakeAM:
|
|
def __init__(self):
|
|
self.pcidev = FakePCIDev()
|
|
self.vram = memoryview(bytearray(4 << 30))
|
|
self.gmc = FakeGMC()
|
|
self.mm = AMMemoryManager(self, vram_size=4 << 30)
|
|
|
|
# * PTE format:
|
|
# * 63:59 reserved
|
|
# * 58:57 reserved
|
|
# * 56 F
|
|
# * 55 L
|
|
# * 54 reserved
|
|
# * 53:52 SW
|
|
# * 51 T
|
|
# * 50:48 mtype
|
|
# * 47:12 4k physical page base address
|
|
# * 11:7 fragment
|
|
# * 6 write
|
|
# * 5 read
|
|
# * 4 exe
|
|
# * 3 Z
|
|
# * 2 snooped
|
|
# * 1 system
|
|
# * 0 valid
|
|
def helper_read_entry_components(entry_val):
|
|
return {"paddr": entry_val & 0x0000FFFFFFFFF000, "fragment":(entry_val >> 7) & 0x1f, "valid": entry_val & 0x1,
|
|
"read": (entry_val >> 5) & 0x1, "write": (entry_val >> 6) & 0x1, "exec": (entry_val >> 4) & 0x1,
|
|
"mtype": (entry_val >> 48) & 0x7, "T": (entry_val >> 51) & 0x1, "L": (entry_val >> 55) & 0x1, "F": (entry_val >> 56) & 0x1}
|
|
|
|
class TestAMPageTable(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.d = [FakeAM() for _ in range(2)]
|
|
|
|
def test_page_table_walkers(self):
|
|
mm = self.d[0].mm
|
|
|
|
for va,sz in [(0x10000, 0x3000), (0x11000, 0x300000), (0x10000, 0x2000), (0x11000, 0x5000),
|
|
(0x2000000, 0x2000), (0x4000000, 0x4000000), (0x38000, 0x303000), (0x8000, 0x1000)]:
|
|
exteranl_va = va + AMMemoryManager.va_allocator.base
|
|
mm.map_range(vaddr=exteranl_va, size=sz, paddr=va)
|
|
|
|
results = list(mm.page_table_walker(mm.root_page_table, vaddr=va, size=sz))
|
|
|
|
total_covered = 0
|
|
for tup in results:
|
|
_vaddr, _offset, _pte_idx, _n_ptes, _pte_covers, _pt = tup
|
|
total_covered += _n_ptes * _pte_covers
|
|
|
|
assert total_covered == sz, f"Expected total coverage {total_covered} to be {sz}"
|
|
|
|
for tup in results:
|
|
_vaddr, _offset, pte_idx, n_ptes, pte_covers, pt = tup
|
|
for i in range(n_ptes):
|
|
pte = helper_read_entry_components(pt.get_entry(pte_idx + i))
|
|
assert pte['paddr'] == va + _offset + i * pte_covers, f"Expected paddr {pte['paddr']:#x} to be {va + _offset + i * pte_covers:#x}"
|
|
assert pte['valid'] == 1
|
|
|
|
mm.unmap_range(va, sz, free_paddrs=False)
|
|
|
|
for tup in results:
|
|
_vaddr, _offset, pte_idx, n_ptes, pte_covers, pt = tup
|
|
for i in range(n_ptes):
|
|
pte = helper_read_entry_components(pt.get_entry(pte_idx + i))
|
|
assert pte['paddr'] == 0
|
|
assert pte['valid'] == 0
|
|
|
|
def test_double_map(self):
|
|
mm0 = self.d[0].mm
|
|
|
|
for va,sz in [(0x10000, 0x3000), (0x1000000, 0x1000000), (0x12000, 0x4000)]:
|
|
exteranl_va = va + AMMemoryManager.va_allocator.base
|
|
mm0.map_range(vaddr=exteranl_va, size=sz, paddr=va)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_range(vaddr=exteranl_va, size=0x1000, paddr=va)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_range(vaddr=exteranl_va, size=0x100000, paddr=va)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_range(vaddr=exteranl_va + 0x1000, size=0x1000, paddr=va)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_range(vaddr=exteranl_va + 0x2000, size=0x100000, paddr=va)
|
|
|
|
mm0.unmap_range(vaddr=exteranl_va, size=sz, free_paddrs=False)
|
|
|
|
# Finally can map and check paddrs
|
|
mm0.map_range(vaddr=exteranl_va + 0x2000, size=0x100000, paddr=0xdead0000)
|
|
for tup in mm0.page_table_walker(mm0.root_page_table, vaddr=va + 0x2000, size=0x100000):
|
|
_vaddr, _offset, pte_idx, n_ptes, pte_covers, pt = tup
|
|
for i in range(n_ptes):
|
|
pte = helper_read_entry_components(pt.get_entry(pte_idx + i))
|
|
assert pte['paddr'] == 0xdead0000 + _offset + i * pte_covers, f"paddr {pte['paddr']:#x} not {0xdead0000 + _offset + i * pte_covers:#x}"
|
|
assert pte['valid'] == 1
|
|
|
|
mm0.unmap_range(vaddr=exteranl_va + 0x2000, size=0x100000, free_paddrs=False)
|
|
|
|
def test_map_from(self):
|
|
mm0 = self.d[0].mm
|
|
mm1 = self.d[1].mm
|
|
|
|
for va,sz in [(0x10000, 0x3000), (0x11000, 0x300000), (0x10000, 0x2000), (0x11000, 0x5000),
|
|
(0x2000000, 0x2000), (0x4000000, 0x4000000), (0x38000, 0x303000), (0x8000, 0x1000)]:
|
|
exteranl_va = va + AMMemoryManager.va_allocator.base
|
|
mm0.map_range(vaddr=exteranl_va, size=sz, paddr=va)
|
|
mm1.map_range(vaddr=exteranl_va, size=sz, paddr=va)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_from(vaddr=exteranl_va, size=sz, from_adev=mm0.adev) # self mapping -- bad
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.map_from(vaddr=exteranl_va, size=sz, from_adev=mm1.adev) # mapping from mm1 to same addrs -- bad
|
|
|
|
mm0.unmap_range(vaddr=exteranl_va, size=sz, free_paddrs=False) # unmap from mm0
|
|
mm0.map_from(vaddr=exteranl_va, size=sz, from_adev=mm1.adev) # mapping from mm1 to same addrs -- ok
|
|
|
|
d1_pci_base = self.d[1].pcidev.regions[0].base_addr
|
|
for tup in mm0.page_table_walker(mm0.root_page_table, vaddr=va, size=sz):
|
|
_vaddr, _offset, pte_idx, n_ptes, pte_covers, pt = tup
|
|
for i in range(n_ptes):
|
|
pte = helper_read_entry_components(pt.get_entry(pte_idx + i))
|
|
assert pte['paddr'] == d1_pci_base + va + _offset + i * pte_covers, f"paddr {pte['paddr']:#x} not {d1_pci_base+va+_offset+i*pte_covers:#x}"
|
|
assert pte['valid'] == 1
|
|
|
|
mm0.unmap_range(vaddr=exteranl_va, size=sz, free_paddrs=False)
|
|
mm1.unmap_range(vaddr=exteranl_va, size=sz, free_paddrs=False)
|
|
|
|
def test_try_bad_unmap(self):
|
|
mm0 = self.d[0].mm
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.unmap_range(0x10000, 0x3000, free_paddrs=False)
|
|
|
|
mm0.map_range(0x10000, 0x3000, 0x10000)
|
|
mm0.unmap_range(0x10000, 0x3000, free_paddrs=False)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.unmap_range(0x10000, 0x3000, free_paddrs=False)
|
|
|
|
mm0.map_range(0x10000, 0x3000, 0x10000)
|
|
mm0.unmap_range(0x10000, 0x3000, free_paddrs=False)
|
|
|
|
with self.assertRaises(AssertionError):
|
|
mm0.unmap_range(0x10000, 0x3000, free_paddrs=False)
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|