`PhysMemoryMap` stores `PhysMemoryRange` entries. RAM ranges carry `phys_mem` and optional dirty bits; device ranges carry read/write function pointers and an opaque state pointer.
get_phys_mem_range(map, paddr)
for each range:
if paddr in [addr, addr + size):
return range
range.is_ram ? use range.phys_mem : call range.read_func/write_func