diff options
Diffstat (limited to 'mpm/python')
| -rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/magnesium.py | 15 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/n310.py | 10 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/udev.py | 24 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/uio.py | 108 | 
4 files changed, 106 insertions, 51 deletions
| diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py index 45a19ded6..cee2f0915 100644 --- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py +++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py @@ -23,7 +23,7 @@ import time  from . import lib # Pulls in everything from C++-land  from .base import DboardManagerBase  from .. import nijesdcore -from ..uio import uio +from ..uio import UIO  class magnesium(DboardManagerBase):      """ @@ -60,7 +60,7 @@ class magnesium(DboardManagerBase):          Execute necessary init dance to bring up dboard          """          self.log.debug("initialize hardware") -        self._device = lib.dboards.magnesium_periph_manager( +        self._device = lib.dboards.magnesium_manager(              # self.lmk.encode('ascii'), self.mykonos.encode('ascii')              '/dev/spidev0.0',              '/dev/spidev0.1', @@ -69,13 +69,10 @@ class magnesium(DboardManagerBase):          self.mykonos = self._device.get_radio_ctrl()          # uio_path, uio_size = get_uio_node("misc-enet-regs0") -        self.log.debug("getting Mg A uio") -        uio_path = "/dev/uio2" # TODO use labels -        uio_size = 0x4000 -        self.log.debug("got uio_path and size") -        self.uio = uio(uio_path, uio_size, read_only=False) -        self.log.info("got my uio") -        self.init_jesd(self.uio) +        self.log.debug("Getting Mg A uio...") +        self.radio_regs = UIO(label="jesd204b-regs", read_only=False) +        self.log.info("Radio-register UIO object successfully generated!") +        self.init_jesd(self.radio_regs)      def init_jesd(self, uio):          """ diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py index 364d50908..172aec35b 100644 --- a/mpm/python/usrp_mpm/periph_manager/n310.py +++ b/mpm/python/usrp_mpm/periph_manager/n310.py @@ -23,9 +23,8 @@ from .base import PeriphManagerBase  from .net import get_iface_addrs  from .net import byte_to_mac  from .net import get_mac_addr -from .udev import get_uio_node  from ..types import SID -from ..uio import uio +from ..uio import UIO  from .. import libpyusrp_periphs as lib  from logging import getLogger  import netaddr @@ -118,11 +117,8 @@ class n310(PeriphManagerBase):              sid.set_src_ep(new_ep)              my_xbar = lib.xbar.xbar.make("/dev/crossbar0") # TODO              my_xbar.set_route(xbar_src_addr, 0) # TODO -            # uio_path, uio_size = get_uio_node("misc-enet-regs0") -            uio_path = "/dev/uio0" -            uio_size = 0x2000 -            self.log.debug("got uio_path and size") -            uio_obj = uio(uio_path, uio_size, read_only=False) +            self.log.debug("Getting UIO device for Ethernet configuration...") +            uio_obj = UIO(label="misc-enet-regs0", read_only=False)              self.log.info("got my uio")              self.log.info("ip_addr: %s", sender_addr)              # self.log.info("mac_addr: %s", mac_addr) diff --git a/mpm/python/usrp_mpm/periph_manager/udev.py b/mpm/python/usrp_mpm/periph_manager/udev.py index 73601e85c..6801d2163 100644 --- a/mpm/python/usrp_mpm/periph_manager/udev.py +++ b/mpm/python/usrp_mpm/periph_manager/udev.py @@ -42,27 +42,3 @@ def get_spidev_nodes(spi_master):               for device in context.list_devices(parent=parent, subsystem="spidev")]      return paths -def get_uio_node(uio_name): -    """ -    Return found uio device path for a give parent name -    """ -    context = pyudev.Context() -    paths = [device.sys_path -             for device in context.list_devices(subsystem="uio")] -    log = get_logger('get_uio_node') -    log.debug("get_uio_node") -    log.debug("got paths: %s", paths) -    for path in paths: -        with open(os.path.join(path, "maps", "map0", "name"), "r") as uio_file: -            name = uio_file.read() -        log.debug("uio_node name: %s", name.strip()) -        if name.strip() == uio_name: -            with open(os.path.join(path, "maps", "map0", "size"), "r") as uio_file: -                size = uio_file.read() -            log.debug("uio_node size: %s", size.strip()) -            log.debug("uio_node syspath: %s", path) -            # device = pyudev.Device.from_sys_path(context, path) -            log.debug("got udev device") -            log.debug("device_node: %s size: %s", "/dev/uio0", size.strip()) -            return ("/dev/uio0", int(size.strip())) -    return ("", 0) diff --git a/mpm/python/usrp_mpm/uio.py b/mpm/python/usrp_mpm/uio.py index 18a894e9c..a3441a7d7 100644 --- a/mpm/python/usrp_mpm/uio.py +++ b/mpm/python/usrp_mpm/uio.py @@ -21,25 +21,111 @@ Access to UIO mapped memory.  import struct  import os  import mmap +import pyudev +from .mpmlog import get_logger -class uio(object): +UIO_SYSFS_BASE_DIR = '/sys/class/uio' +UIO_DEV_BASE_DIR = '/dev' + +def get_all_uio_devs(): +    """ +    Return a list of all uio devices. Will look something like +    ['uio0', 'uio1', ...]. +    """ +    try: +        context = pyudev.Context() +        paths = [os.path.split(device.device_node)[-1] +                 for device in context.list_devices(subsystem="uio")] +        return paths +    except OSError: +        # Typically means UIO devices +        return [] + +def get_uio_map_info(uio_dev, map_num): +    """ +    Returns all the map info for a given UIO device and map number. +    Example: If uio_dev is 'uio0', and map_num is 0, it will list all files +    in /sys/class/uio/uio0/maps/map0/ and create a dictionary with filenames +    as keys and content as value. + +    Numbers are casted to numbers automatically. Strings remain strings. +    """ +    map_info = {} +    map_info_path = os.path.join( +        UIO_SYSFS_BASE_DIR, uio_dev, 'maps', 'map{0}'.format(map_num) +    ) +    for info_file in os.listdir(map_info_path): +        map_info_value = open(os.path.join(map_info_path, info_file), 'r').read().strip() +        try: +            map_info[info_file] = int(map_info_value, 0) +        except ValueError: +            map_info[info_file] = map_info_value +    return map_info + +def find_uio_device(label, logger=None): +    """ +    Given a label, returns a tuple (uio_device, map_info). +    uio_device is something like '/dev/uio0'. map_info is a dictionary with +    information regarding the UIO device read from the map info sysfs dir. +    Note: We assume a single map (map0) for all UIO devices here. +    """ +    uio_devices = get_all_uio_devs() +    if logger: +        logger.trace("Found the following UIO devices: `{0}'".format(','.join(uio_devices))) +    for uio_device in uio_devices: +        map0_info = get_uio_map_info(uio_device, 0) +        logger.trace("{0} has map info: {1}".format(uio_device, map0_info)) +        if map0_info.get('name') == label: +            if logger: +                logger.trace("Device matches label: `{0}'".format(uio_device)) +            return os.path.join(UIO_DEV_BASE_DIR, uio_device), map0_info +    if logger: +        logger.warning("Found no matching UIO device for label `{0}'".format(label)) +    return None, None + +class UIO(object):      """      Provides peek/poke interfaces for uio-mapped memory.      Arguments: -    path -- Path to UIO device, e.g. '/dev/uio0' +    label -- Label of the UIO device. The label is set in the device tree +             overlay +    path -- Path to UIO device, e.g. '/dev/uio0'. This is ignored if 'label' is +            provided.      length -- Number of bytes in the address space (is passed to mmap.mmap). -              Must be at least one page size -    read_only -- Boolean, True == ro, False == rw -    offset -- Passed to mmap.mmap +              This is usually automatically determined. No need to set it. +              Unless you really know what you're doing. +    read_only -- Boolean; True == ro, False == rw +    offset -- Passed to mmap.mmap. +              This is usually automatically determined. No need to set it. +              Unless you really know what you're doing.      """ -    def __init__(self, path, length, read_only=True, offset=None): -        # Python can't tell the size of a uio device -        assert length >= mmap.PAGESIZE -        offset = offset or 0 -        self._path = path +    def __init__(self, label=None, path=None, length=None, read_only=True, offset=None): +        self.log = get_logger('UIO') +        if label is None: +            self._path = path +            self.log.trace("Using UIO device `{0}'".format(path)) +            uio_device = os.path.split(path)[-1] +            self.log.trace("Getting map info for UIO device `{0}'".format(uio_device)) +            map_info = get_uio_map_info(uio_device, 0) +            # Python can't tell the size of a uio device by itself +            assert length is not None +        else: +            self.log.trace("Using UIO device by label `{0}'".format(label)) +            self._path, map_info = find_uio_device(label, self.log) +        offset = offset or map_info['offset'] # If we ever support multiple maps, check if this is correct... +        assert offset == 0 # ...and then remove this line +        length = length or map_info['size'] +        self.log.trace("UIO device is being opened read-{0}.".format("only" if read_only else "write")) +        if self._path is None: +            self.log.error("Could not find a UIO device for label {0}".format(label)) +            raise RuntimeError("Could not find a UIO device for label {0}".format(label))          self._read_only = read_only -        self._fd = os.open(path, os.O_RDONLY if read_only else os.O_RDWR) +        self.log.trace("Opening UIO device file {}...".format(self._path)) +        self._fd = os.open(self._path, os.O_RDONLY if read_only else os.O_RDWR) +        self.log.trace("Calling mmap({fd}, length={length}, offset={offset})".format( +            fd=self._fd, length=hex(length), offset=hex(offset) +        ))          self._mm = mmap.mmap(              self._fd,              length, | 
