Skip to content

Instantly share code, notes, and snippets.

@veprbl
Last active August 29, 2015 14:20
Show Gist options
  • Save veprbl/02804e0df8685d1e8cbe to your computer and use it in GitHub Desktop.
Save veprbl/02804e0df8685d1e8cbe to your computer and use it in GitHub Desktop.
VME_A16 = 0x1
VME_A24 = 0x2
VME_A32 = 0x4
VME_A64 = 0x8
VME_CRCSR = 0x10
VME_SUPER = 0x1000
VME_USER = 0x2000
VME_PROG = 0x4000
VME_DATA = 0x8000
VME_SCT = 0x1
VME_BLT = 0x2
VME_MBLT = 0x4
VME_2eVME = 0x8
VME_2eSST = 0x10
VME_2eSSTB = 0x20
VME_D8 = 0x1
VME_D16 = 0x2
VME_D32 = 0x4
VME_D64 = 0x8
VME_A16_MAX = 0x10000
VME_A24_MAX = 0x1000000
VME_A32_MAX = 0x100000000
VME_A64_MAX = 0x10000000000000000
VME_CRCSR_MAX = 0x1000000
VME_DMA_VME_TO_MEM = 1 << 0
VME_DMA_MEM_TO_VME = 1 << 1
VME_DMA_VME_TO_VME = 1 << 2
VME_DMA_MEM_TO_MEM = 1 << 3
VME_DMA_PATTERN_TO_VME = 1 << 4
VME_DMA_PATTERN_TO_MEM = 1 << 5
VME_DMA_OP = 0x4024ae07
import ctypes
import fcntl
import os
import time
def pp(s): return map(lambda c: "0x%02x" % (ord(c)), s)
urandom = open("/dev/urandom", "r")
vals = urandom.read(0x1000000)
urandom.close()
WFD64_BASE = 0xAAAAAA0200000000
class vme_dma_op(ctypes.Structure):
_fields_ = [
("vme_addr", ctypes.c_ulonglong),
("buf_vaddr", ctypes.c_ulonglong),
("count", ctypes.c_uint),
("aspace", ctypes.c_uint),
("cycle", ctypes.c_uint),
("dwidth", ctypes.c_uint),
("dir", ctypes.c_uint),
]
def __str__(self):
return "vme_dma<%x,%x,%x>" % (self.aspace, self.cycle, self.dwidth)
dma = open("/dev/bus/vme/dma0", "wb+", False)
def pread(fp, count, offset):
buf = ctypes.create_string_buffer(max(count, 0) + 1024)
assert all(map(lambda b: ord(b)==0, buf.raw[-1024:]))
dma_op = vme_dma_op()
dma_op.vme_addr = WFD64_BASE + offset
dma_op.buf_vaddr = ctypes.addressof(buf)
dma_op.count = count
dma_op.aspace = VME_A64
dma_op.cycle = VME_USER | VME_DATA | VME_BLT
dma_op.dwidth = VME_D32
dma_op.dir = VME_DMA_VME_TO_MEM
start = time.time()
fcntl.ioctl(dma, VME_DMA_OP, dma_op)
end = time.time()
assert all(map(lambda b: ord(b)==0, buf.raw[-1024:]))
print "Read speed: %.1f kb/s" % (dma_op.count / 1024.0 / (end - start))
return buf.raw[:-1024]
def pwrite(fp, buf, offset):
_buf = ctypes.create_string_buffer(buf)
dma_op = vme_dma_op()
dma_op.vme_addr = WFD64_BASE + offset
dma_op.buf_vaddr = ctypes.addressof(_buf)
dma_op.count = len(buf)
dma_op.aspace = VME_A64
dma_op.cycle = VME_USER | VME_DATA | VME_BLT
dma_op.dwidth = VME_D32
dma_op.dir = VME_DMA_MEM_TO_VME
start = time.time()
fcntl.ioctl(dma, VME_DMA_OP, dma_op)
end = time.time()
print "Write speed: %.1f kb/s" % (dma_op.count / 1024.0 / (end - start))
for offset in range(0x1000, 0x10001, 0x1000):
errno = None
try:
pread(dma, -offset, 0) # rogue read
except IOError as e:
errno = e.errno
assert errno == 14 or errno == 22 # Inval or Bad addr
assert errno is not None
assert len(pread(dma, 0, 0)) == 0
pwrite(dma, vals, 0)
readsize = 0x1000000
read_vals = pread(dma, readsize, 0)
pwrite(dma, vals, 0)
print len(vals)
print len(read_vals)
assert len(read_vals) == len(vals[:readsize])
assert read_vals == vals[:readsize]
def check_read(length, offset=None):
read_vals = pread(dma, length, offset)
assert read_vals == vals[offset:offset+length]
for i in range(1024):
check_read(i*4, offset=128)
for i in range(1024):
check_read(i*4, offset=64*4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment